blob: 137a54bcfb3214ba19d9fce08b19bb7bd4ac2fc7 [file] [log] [blame]
Jamie Gennis8ba32fa2010-12-20 11:27:26 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdint.h>
18#include <sys/types.h>
19
20#include <utils/Errors.h>
Jesse Hall399184a2014-03-03 15:42:54 -080021#include <utils/NativeHandle.h>
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080022#include <utils/RefBase.h>
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080023#include <utils/Timers.h>
Jesse Hall399184a2014-03-03 15:42:54 -080024#include <utils/Vector.h>
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080025
26#include <binder/Parcel.h>
27#include <binder/IInterface.h>
28
Andy McFadden2adaf042012-12-18 09:49:45 -080029#include <gui/IGraphicBufferProducer.h>
Dan Stozaf0eaf252014-03-21 13:05:51 -070030#include <gui/IProducerListener.h>
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080031
32namespace android {
33// ----------------------------------------------------------------------------
34
35enum {
36 REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080037 DEQUEUE_BUFFER,
Dan Stoza9f3053d2014-03-06 15:14:33 -080038 DETACH_BUFFER,
Dan Stozad9822a32014-03-28 15:25:31 -070039 DETACH_NEXT_BUFFER,
Dan Stoza9f3053d2014-03-06 15:14:33 -080040 ATTACH_BUFFER,
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080041 QUEUE_BUFFER,
42 CANCEL_BUFFER,
Mathias Agopianeafabcd2011-04-20 14:20:59 -070043 QUERY,
Jamie Gennisfe0a87b2011-07-13 19:12:20 -070044 CONNECT,
45 DISCONNECT,
Jesse Hall399184a2014-03-03 15:42:54 -080046 SET_SIDEBAND_STREAM,
Dan Stoza29a3e902014-06-20 13:13:57 -070047 ALLOCATE_BUFFERS,
Dan Stoza9de72932015-04-16 17:28:43 -070048 ALLOW_ALLOCATION,
Dan Stoza812ed062015-06-02 15:45:22 -070049 SET_GENERATION_NUMBER,
Dan Stozac6f30bd2015-06-08 09:32:50 -070050 GET_CONSUMER_NAME,
Pablo Ceballosfa455352015-08-12 17:47:47 -070051 SET_MAX_DEQUEUED_BUFFER_COUNT,
Dan Stoza7dde5992015-05-22 09:51:44 -070052 SET_ASYNC_MODE,
Pablo Ceballosccdfd602015-10-07 15:05:45 -070053 GET_NEXT_FRAME_NUMBER,
Pablo Ceballos3559fbf2016-03-17 15:50:23 -070054 SET_SHARED_BUFFER_MODE,
Pablo Ceballosff95aab2016-01-13 17:09:58 -080055 SET_AUTO_REFRESH,
Dan Stoza127fc632015-06-30 13:43:32 -070056 SET_DEQUEUE_TIMEOUT,
Dan Stoza50101d02016-04-07 16:53:23 -070057 GET_LAST_QUEUED_BUFFER,
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080058};
59
Andy McFadden2adaf042012-12-18 09:49:45 -080060class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080061{
62public:
Andy McFadden2adaf042012-12-18 09:49:45 -080063 BpGraphicBufferProducer(const sp<IBinder>& impl)
64 : BpInterface<IGraphicBufferProducer>(impl)
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080065 {
66 }
67
Dan Stoza3be1c6b2014-11-18 10:24:03 -080068 virtual ~BpGraphicBufferProducer();
69
Jamie Gennis7b305ff2011-07-19 12:08:33 -070070 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080071 Parcel data, reply;
Andy McFadden2adaf042012-12-18 09:49:45 -080072 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080073 data.writeInt32(bufferIdx);
Jamie Gennis8a29ff22011-10-14 15:03:17 -070074 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
75 if (result != NO_ERROR) {
76 return result;
77 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080078 bool nonNull = reply.readInt32();
79 if (nonNull) {
Jamie Gennis7b305ff2011-07-19 12:08:33 -070080 *buf = new GraphicBuffer();
Lingyun Zhu2aff7022012-11-20 19:24:35 +080081 result = reply.read(**buf);
82 if(result != NO_ERROR) {
83 (*buf).clear();
84 return result;
85 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080086 }
Jamie Gennis8a29ff22011-10-14 15:03:17 -070087 result = reply.readInt32();
Jamie Gennis7b305ff2011-07-19 12:08:33 -070088 return result;
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080089 }
90
Pablo Ceballosfa455352015-08-12 17:47:47 -070091 virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
92 Parcel data, reply;
93 data.writeInterfaceToken(
94 IGraphicBufferProducer::getInterfaceDescriptor());
95 data.writeInt32(maxDequeuedBuffers);
96 status_t result = remote()->transact(SET_MAX_DEQUEUED_BUFFER_COUNT,
97 data, &reply);
98 if (result != NO_ERROR) {
99 return result;
100 }
101 result = reply.readInt32();
102 return result;
103 }
104
105 virtual status_t setAsyncMode(bool async) {
106 Parcel data, reply;
107 data.writeInterfaceToken(
108 IGraphicBufferProducer::getInterfaceDescriptor());
109 data.writeInt32(async);
110 status_t result = remote()->transact(SET_ASYNC_MODE,
111 data, &reply);
112 if (result != NO_ERROR) {
113 return result;
114 }
115 result = reply.readInt32();
116 return result;
117 }
118
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700119 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, uint32_t width,
120 uint32_t height, PixelFormat format, uint32_t usage) {
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800121 Parcel data, reply;
Andy McFadden2adaf042012-12-18 09:49:45 -0800122 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800123 data.writeUint32(width);
124 data.writeUint32(height);
125 data.writeInt32(static_cast<int32_t>(format));
126 data.writeUint32(usage);
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700127 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
128 if (result != NO_ERROR) {
129 return result;
130 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800131 *buf = reply.readInt32();
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700132 bool nonNull = reply.readInt32();
133 if (nonNull) {
Jesse Hall4c00cc12013-03-15 21:34:30 -0700134 *fence = new Fence();
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700135 reply.read(**fence);
Jesse Hallf7857542012-06-14 15:26:33 -0700136 }
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700137 result = reply.readInt32();
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800138 return result;
139 }
140
Dan Stoza9f3053d2014-03-06 15:14:33 -0800141 virtual status_t detachBuffer(int slot) {
142 Parcel data, reply;
143 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
144 data.writeInt32(slot);
145 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
146 if (result != NO_ERROR) {
147 return result;
148 }
149 result = reply.readInt32();
150 return result;
151 }
152
Dan Stozad9822a32014-03-28 15:25:31 -0700153 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
154 sp<Fence>* outFence) {
155 if (outBuffer == NULL) {
156 ALOGE("detachNextBuffer: outBuffer must not be NULL");
157 return BAD_VALUE;
158 } else if (outFence == NULL) {
159 ALOGE("detachNextBuffer: outFence must not be NULL");
160 return BAD_VALUE;
161 }
162 Parcel data, reply;
163 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
164 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply);
165 if (result != NO_ERROR) {
166 return result;
167 }
168 result = reply.readInt32();
169 if (result == NO_ERROR) {
170 bool nonNull = reply.readInt32();
171 if (nonNull) {
172 *outBuffer = new GraphicBuffer;
173 reply.read(**outBuffer);
174 }
175 nonNull = reply.readInt32();
176 if (nonNull) {
177 *outFence = new Fence;
178 reply.read(**outFence);
179 }
180 }
181 return result;
182 }
183
Dan Stoza9f3053d2014-03-06 15:14:33 -0800184 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
185 Parcel data, reply;
186 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
187 data.write(*buffer.get());
188 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
189 if (result != NO_ERROR) {
190 return result;
191 }
192 *slot = reply.readInt32();
193 result = reply.readInt32();
194 return result;
195 }
196
Mathias Agopianf0bc2f12012-04-09 16:14:01 -0700197 virtual status_t queueBuffer(int buf,
198 const QueueBufferInput& input, QueueBufferOutput* output) {
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800199 Parcel data, reply;
Andy McFadden2adaf042012-12-18 09:49:45 -0800200 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800201 data.writeInt32(buf);
Jesse Hallc777b0b2012-06-28 12:52:05 -0700202 data.write(input);
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700203 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
204 if (result != NO_ERROR) {
205 return result;
206 }
Mathias Agopianf0bc2f12012-04-09 16:14:01 -0700207 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700208 result = reply.readInt32();
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800209 return result;
210 }
211
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700212 virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) {
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800213 Parcel data, reply;
Andy McFadden2adaf042012-12-18 09:49:45 -0800214 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800215 data.writeInt32(buf);
Jamie Gennis1df8c342012-12-20 14:05:45 -0800216 data.write(*fence.get());
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700217 status_t result = remote()->transact(CANCEL_BUFFER, data, &reply);
218 if (result != NO_ERROR) {
219 return result;
220 }
221 result = reply.readInt32();
222 return result;
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800223 }
224
Mathias Agopianeafabcd2011-04-20 14:20:59 -0700225 virtual int query(int what, int* value) {
226 Parcel data, reply;
Andy McFadden2adaf042012-12-18 09:49:45 -0800227 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
Mathias Agopianeafabcd2011-04-20 14:20:59 -0700228 data.writeInt32(what);
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700229 status_t result = remote()->transact(QUERY, data, &reply);
230 if (result != NO_ERROR) {
231 return result;
232 }
Mathias Agopianeafabcd2011-04-20 14:20:59 -0700233 value[0] = reply.readInt32();
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700234 result = reply.readInt32();
Mathias Agopianeafabcd2011-04-20 14:20:59 -0700235 return result;
236 }
237
Dan Stozaf0eaf252014-03-21 13:05:51 -0700238 virtual status_t connect(const sp<IProducerListener>& listener,
Mathias Agopian365857d2013-09-11 19:35:45 -0700239 int api, bool producerControlledByApp, QueueBufferOutput* output) {
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700240 Parcel data, reply;
Andy McFadden2adaf042012-12-18 09:49:45 -0800241 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
Dan Stozaf0eaf252014-03-21 13:05:51 -0700242 if (listener != NULL) {
243 data.writeInt32(1);
Marco Nelissen097ca272014-11-14 08:01:01 -0800244 data.writeStrongBinder(IInterface::asBinder(listener));
Dan Stozaf0eaf252014-03-21 13:05:51 -0700245 } else {
246 data.writeInt32(0);
247 }
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700248 data.writeInt32(api);
Mathias Agopian595264f2013-07-16 22:56:09 -0700249 data.writeInt32(producerControlledByApp);
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700250 status_t result = remote()->transact(CONNECT, data, &reply);
251 if (result != NO_ERROR) {
252 return result;
253 }
Mathias Agopian24202f52012-04-23 14:28:58 -0700254 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700255 result = reply.readInt32();
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700256 return result;
257 }
Mathias Agopian80727112011-05-02 19:51:12 -0700258
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700259 virtual status_t disconnect(int api) {
260 Parcel data, reply;
Andy McFadden2adaf042012-12-18 09:49:45 -0800261 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700262 data.writeInt32(api);
Jamie Gennis8a29ff22011-10-14 15:03:17 -0700263 status_t result =remote()->transact(DISCONNECT, data, &reply);
264 if (result != NO_ERROR) {
265 return result;
266 }
267 result = reply.readInt32();
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700268 return result;
269 }
Jesse Hall399184a2014-03-03 15:42:54 -0800270
271 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
272 Parcel data, reply;
273 status_t result;
274 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
275 if (stream.get()) {
276 data.writeInt32(true);
277 data.writeNativeHandle(stream->handle());
278 } else {
279 data.writeInt32(false);
280 }
281 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
282 result = reply.readInt32();
283 }
284 return result;
285 }
Dan Stoza29a3e902014-06-20 13:13:57 -0700286
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700287 virtual void allocateBuffers(uint32_t width, uint32_t height,
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800288 PixelFormat format, uint32_t usage) {
Dan Stoza29a3e902014-06-20 13:13:57 -0700289 Parcel data, reply;
290 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800291 data.writeUint32(width);
292 data.writeUint32(height);
Dan Stoza29a3e902014-06-20 13:13:57 -0700293 data.writeInt32(static_cast<int32_t>(format));
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800294 data.writeUint32(usage);
Dan Stoza29a3e902014-06-20 13:13:57 -0700295 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
296 if (result != NO_ERROR) {
297 ALOGE("allocateBuffers failed to transact: %d", result);
298 }
299 }
Dan Stoza9de72932015-04-16 17:28:43 -0700300
301 virtual status_t allowAllocation(bool allow) {
302 Parcel data, reply;
303 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
304 data.writeInt32(static_cast<int32_t>(allow));
305 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
306 if (result != NO_ERROR) {
307 return result;
308 }
309 result = reply.readInt32();
310 return result;
311 }
Dan Stoza812ed062015-06-02 15:45:22 -0700312
313 virtual status_t setGenerationNumber(uint32_t generationNumber) {
314 Parcel data, reply;
315 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
316 data.writeUint32(generationNumber);
317 status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply);
318 if (result == NO_ERROR) {
319 result = reply.readInt32();
320 }
321 return result;
322 }
Dan Stozac6f30bd2015-06-08 09:32:50 -0700323
324 virtual String8 getConsumerName() const {
325 Parcel data, reply;
326 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
327 status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply);
328 if (result != NO_ERROR) {
329 ALOGE("getConsumerName failed to transact: %d", result);
330 return String8("TransactFailed");
331 }
332 return reply.readString8();
333 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700334
335 virtual uint64_t getNextFrameNumber() const {
336 Parcel data, reply;
337 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
338 status_t result = remote()->transact(GET_NEXT_FRAME_NUMBER, data, &reply);
339 if (result != NO_ERROR) {
340 ALOGE("getNextFrameNumber failed to transact: %d", result);
341 return 0;
342 }
343 uint64_t frameNumber = reply.readUint64();
344 return frameNumber;
345 }
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700346
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700347 virtual status_t setSharedBufferMode(bool sharedBufferMode) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700348 Parcel data, reply;
349 data.writeInterfaceToken(
350 IGraphicBufferProducer::getInterfaceDescriptor());
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700351 data.writeInt32(sharedBufferMode);
352 status_t result = remote()->transact(SET_SHARED_BUFFER_MODE, data,
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700353 &reply);
354 if (result == NO_ERROR) {
355 result = reply.readInt32();
356 }
357 return result;
358 }
Dan Stoza127fc632015-06-30 13:43:32 -0700359
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800360 virtual status_t setAutoRefresh(bool autoRefresh) {
361 Parcel data, reply;
362 data.writeInterfaceToken(
363 IGraphicBufferProducer::getInterfaceDescriptor());
364 data.writeInt32(autoRefresh);
365 status_t result = remote()->transact(SET_AUTO_REFRESH, data, &reply);
366 if (result == NO_ERROR) {
367 result = reply.readInt32();
368 }
369 return result;
370 }
371
Dan Stoza127fc632015-06-30 13:43:32 -0700372 virtual status_t setDequeueTimeout(nsecs_t timeout) {
373 Parcel data, reply;
374 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
375 data.writeInt64(timeout);
376 status_t result = remote()->transact(SET_DEQUEUE_TIMEOUT, data, &reply);
377 if (result != NO_ERROR) {
378 ALOGE("setDequeueTimeout failed to transact: %d", result);
379 return result;
380 }
381 return reply.readInt32();
382 }
Dan Stoza50101d02016-04-07 16:53:23 -0700383
384 virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
385 sp<Fence>* outFence) override {
386 Parcel data, reply;
387 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
388 status_t result = remote()->transact(GET_LAST_QUEUED_BUFFER, data,
389 &reply);
390 if (result != NO_ERROR) {
391 ALOGE("getLastQueuedBuffer failed to transact: %d", result);
392 return result;
393 }
394 result = reply.readInt32();
395 if (result != NO_ERROR) {
396 return result;
397 }
John Reckce8e5df2016-04-28 10:12:47 -0700398 bool hasBuffer = reply.readBool();
399 sp<GraphicBuffer> buffer;
400 if (hasBuffer) {
401 buffer = new GraphicBuffer();
402 result = reply.read(*buffer);
403 }
Dan Stoza50101d02016-04-07 16:53:23 -0700404 if (result != NO_ERROR) {
405 ALOGE("getLastQueuedBuffer failed to read buffer: %d", result);
406 return result;
407 }
408 sp<Fence> fence(new Fence);
409 result = reply.read(*fence);
410 if (result != NO_ERROR) {
411 ALOGE("getLastQueuedBuffer failed to read fence: %d", result);
412 return result;
413 }
414 *outBuffer = buffer;
415 *outFence = fence;
416 return result;
417 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800418};
419
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800420// Out-of-line virtual method definition to trigger vtable emission in this
421// translation unit (see clang warning -Wweak-vtables)
422BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
423
Andy McFadden466a1922013-01-08 11:25:51 -0800424IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800425
426// ----------------------------------------------------------------------
427
Andy McFadden2adaf042012-12-18 09:49:45 -0800428status_t BnGraphicBufferProducer::onTransact(
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800429 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
430{
431 switch(code) {
432 case REQUEST_BUFFER: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800433 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800434 int bufferIdx = data.readInt32();
Jamie Gennis7b305ff2011-07-19 12:08:33 -0700435 sp<GraphicBuffer> buffer;
436 int result = requestBuffer(bufferIdx, &buffer);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800437 reply->writeInt32(buffer != 0);
438 if (buffer != 0) {
439 reply->write(*buffer);
440 }
Jamie Gennis7b305ff2011-07-19 12:08:33 -0700441 reply->writeInt32(result);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800442 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800443 }
Pablo Ceballosfa455352015-08-12 17:47:47 -0700444 case SET_MAX_DEQUEUED_BUFFER_COUNT: {
445 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
446 int maxDequeuedBuffers = data.readInt32();
447 int result = setMaxDequeuedBufferCount(maxDequeuedBuffers);
448 reply->writeInt32(result);
449 return NO_ERROR;
450 }
451 case SET_ASYNC_MODE: {
452 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
453 bool async = data.readInt32();
454 int result = setAsyncMode(async);
455 reply->writeInt32(result);
456 return NO_ERROR;
457 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800458 case DEQUEUE_BUFFER: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800459 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800460 uint32_t width = data.readUint32();
461 uint32_t height = data.readUint32();
462 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
463 uint32_t usage = data.readUint32();
Naveen Leekha12ba0f52015-09-21 17:28:04 -0700464 int buf = 0;
Jesse Hallf7857542012-06-14 15:26:33 -0700465 sp<Fence> fence;
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700466 int result = dequeueBuffer(&buf, &fence, width, height, format,
467 usage);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800468 reply->writeInt32(buf);
Jamie Gennis1df8c342012-12-20 14:05:45 -0800469 reply->writeInt32(fence != NULL);
470 if (fence != NULL) {
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700471 reply->write(*fence);
Jesse Hallf7857542012-06-14 15:26:33 -0700472 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800473 reply->writeInt32(result);
474 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800475 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800476 case DETACH_BUFFER: {
477 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
478 int slot = data.readInt32();
479 int result = detachBuffer(slot);
480 reply->writeInt32(result);
481 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800482 }
Dan Stozad9822a32014-03-28 15:25:31 -0700483 case DETACH_NEXT_BUFFER: {
484 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
485 sp<GraphicBuffer> buffer;
486 sp<Fence> fence;
487 int32_t result = detachNextBuffer(&buffer, &fence);
488 reply->writeInt32(result);
489 if (result == NO_ERROR) {
490 reply->writeInt32(buffer != NULL);
491 if (buffer != NULL) {
492 reply->write(*buffer);
493 }
494 reply->writeInt32(fence != NULL);
495 if (fence != NULL) {
496 reply->write(*fence);
497 }
498 }
499 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800500 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800501 case ATTACH_BUFFER: {
502 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
503 sp<GraphicBuffer> buffer = new GraphicBuffer();
504 data.read(*buffer.get());
Naveen Leekha12ba0f52015-09-21 17:28:04 -0700505 int slot = 0;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800506 int result = attachBuffer(&slot, buffer);
507 reply->writeInt32(slot);
508 reply->writeInt32(result);
509 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800510 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800511 case QUEUE_BUFFER: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800512 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800513 int buf = data.readInt32();
Jesse Hallc777b0b2012-06-28 12:52:05 -0700514 QueueBufferInput input(data);
Mathias Agopianf0bc2f12012-04-09 16:14:01 -0700515 QueueBufferOutput* const output =
516 reinterpret_cast<QueueBufferOutput *>(
517 reply->writeInplace(sizeof(QueueBufferOutput)));
Robert Shihd06421f2016-01-11 15:02:12 -0800518 memset(output, 0, sizeof(QueueBufferOutput));
Jesse Hallc777b0b2012-06-28 12:52:05 -0700519 status_t result = queueBuffer(buf, input, output);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800520 reply->writeInt32(result);
521 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800522 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800523 case CANCEL_BUFFER: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800524 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800525 int buf = data.readInt32();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800526 sp<Fence> fence = new Fence();
527 data.read(*fence.get());
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700528 status_t result = cancelBuffer(buf, fence);
529 reply->writeInt32(result);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800530 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800531 }
Mathias Agopianeafabcd2011-04-20 14:20:59 -0700532 case QUERY: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800533 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Naveen Leekha12ba0f52015-09-21 17:28:04 -0700534 int value = 0;
Mathias Agopianeafabcd2011-04-20 14:20:59 -0700535 int what = data.readInt32();
536 int res = query(what, &value);
537 reply->writeInt32(value);
538 reply->writeInt32(res);
539 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800540 }
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700541 case CONNECT: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800542 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Dan Stozaf0eaf252014-03-21 13:05:51 -0700543 sp<IProducerListener> listener;
544 if (data.readInt32() == 1) {
545 listener = IProducerListener::asInterface(data.readStrongBinder());
546 }
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700547 int api = data.readInt32();
Mathias Agopian595264f2013-07-16 22:56:09 -0700548 bool producerControlledByApp = data.readInt32();
Mathias Agopian24202f52012-04-23 14:28:58 -0700549 QueueBufferOutput* const output =
550 reinterpret_cast<QueueBufferOutput *>(
551 reply->writeInplace(sizeof(QueueBufferOutput)));
Pablo Ceballos93c617f2016-03-15 18:10:49 -0700552 memset(output, 0, sizeof(QueueBufferOutput));
Dan Stozaf0eaf252014-03-21 13:05:51 -0700553 status_t res = connect(listener, api, producerControlledByApp, output);
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700554 reply->writeInt32(res);
555 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800556 }
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700557 case DISCONNECT: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800558 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700559 int api = data.readInt32();
Mathias Agopian27730042011-07-14 20:20:58 -0700560 status_t res = disconnect(api);
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700561 reply->writeInt32(res);
562 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800563 }
Jesse Hall399184a2014-03-03 15:42:54 -0800564 case SET_SIDEBAND_STREAM: {
565 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
566 sp<NativeHandle> stream;
567 if (data.readInt32()) {
Wonsik Kim0ec54e12014-03-21 10:46:24 +0900568 stream = NativeHandle::create(data.readNativeHandle(), true);
Jesse Hall399184a2014-03-03 15:42:54 -0800569 }
570 status_t result = setSidebandStream(stream);
571 reply->writeInt32(result);
572 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800573 }
Dan Stoza9de72932015-04-16 17:28:43 -0700574 case ALLOCATE_BUFFERS: {
Dan Stoza29a3e902014-06-20 13:13:57 -0700575 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800576 uint32_t width = data.readUint32();
577 uint32_t height = data.readUint32();
578 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
579 uint32_t usage = data.readUint32();
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700580 allocateBuffers(width, height, format, usage);
Dan Stoza29a3e902014-06-20 13:13:57 -0700581 return NO_ERROR;
Dan Stoza9de72932015-04-16 17:28:43 -0700582 }
583 case ALLOW_ALLOCATION: {
584 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
585 bool allow = static_cast<bool>(data.readInt32());
586 status_t result = allowAllocation(allow);
587 reply->writeInt32(result);
588 return NO_ERROR;
589 }
Dan Stoza812ed062015-06-02 15:45:22 -0700590 case SET_GENERATION_NUMBER: {
591 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
592 uint32_t generationNumber = data.readUint32();
593 status_t result = setGenerationNumber(generationNumber);
594 reply->writeInt32(result);
595 return NO_ERROR;
596 }
Dan Stozac6f30bd2015-06-08 09:32:50 -0700597 case GET_CONSUMER_NAME: {
598 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
599 reply->writeString8(getConsumerName());
600 return NO_ERROR;
601 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700602 case GET_NEXT_FRAME_NUMBER: {
603 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
604 uint64_t frameNumber = getNextFrameNumber();
605 reply->writeUint64(frameNumber);
606 return NO_ERROR;
607 }
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700608 case SET_SHARED_BUFFER_MODE: {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700609 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700610 bool sharedBufferMode = data.readInt32();
611 status_t result = setSharedBufferMode(sharedBufferMode);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700612 reply->writeInt32(result);
613 return NO_ERROR;
614 }
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800615 case SET_AUTO_REFRESH: {
616 CHECK_INTERFACE(IGraphicBuffer, data, reply);
617 bool autoRefresh = data.readInt32();
618 status_t result = setAutoRefresh(autoRefresh);
619 reply->writeInt32(result);
620 return NO_ERROR;
621 }
Dan Stoza127fc632015-06-30 13:43:32 -0700622 case SET_DEQUEUE_TIMEOUT: {
623 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
624 nsecs_t timeout = data.readInt64();
625 status_t result = setDequeueTimeout(timeout);
626 reply->writeInt32(result);
627 return NO_ERROR;
628 }
Dan Stoza50101d02016-04-07 16:53:23 -0700629 case GET_LAST_QUEUED_BUFFER: {
630 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
631 sp<GraphicBuffer> buffer(nullptr);
632 sp<Fence> fence(Fence::NO_FENCE);
633 status_t result = getLastQueuedBuffer(&buffer, &fence);
634 reply->writeInt32(result);
635 if (result != NO_ERROR) {
636 return result;
637 }
John Reckce8e5df2016-04-28 10:12:47 -0700638 if (!buffer.get()) {
639 reply->writeBool(false);
640 } else {
641 reply->writeBool(true);
642 result = reply->write(*buffer);
643 }
Dan Stoza50101d02016-04-07 16:53:23 -0700644 if (result != NO_ERROR) {
645 ALOGE("getLastQueuedBuffer failed to write buffer: %d", result);
646 return result;
647 }
648 result = reply->write(*fence);
649 if (result != NO_ERROR) {
650 ALOGE("getLastQueuedBuffer failed to write fence: %d", result);
651 return result;
652 }
653 return NO_ERROR;
654 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800655 }
656 return BBinder::onTransact(code, data, reply, flags);
657}
658
659// ----------------------------------------------------------------------------
660
Andy McFadden2adaf042012-12-18 09:49:45 -0800661IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
Jesse Hallc777b0b2012-06-28 12:52:05 -0700662 parcel.read(*this);
663}
664
Mathias Agopiane1424282013-07-29 21:24:40 -0700665size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
Jesse Hallc777b0b2012-06-28 12:52:05 -0700666 return sizeof(timestamp)
Andy McFadden3c256212013-08-16 14:55:39 -0700667 + sizeof(isAutoTimestamp)
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800668 + sizeof(dataSpace)
Jesse Hallc777b0b2012-06-28 12:52:05 -0700669 + sizeof(crop)
670 + sizeof(scalingMode)
671 + sizeof(transform)
Ruben Brunk1681d952014-06-27 15:51:55 -0700672 + sizeof(stickyTransform)
Dan Stoza5065a552015-03-17 16:23:42 -0700673 + fence->getFlattenedSize()
674 + surfaceDamage.getFlattenedSize();
Jesse Hallc777b0b2012-06-28 12:52:05 -0700675}
676
Mathias Agopiane1424282013-07-29 21:24:40 -0700677size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
Jamie Gennis1df8c342012-12-20 14:05:45 -0800678 return fence->getFdCount();
Jesse Hallc777b0b2012-06-28 12:52:05 -0700679}
680
Mathias Agopiane1424282013-07-29 21:24:40 -0700681status_t IGraphicBufferProducer::QueueBufferInput::flatten(
682 void*& buffer, size_t& size, int*& fds, size_t& count) const
Jesse Hallc777b0b2012-06-28 12:52:05 -0700683{
Mathias Agopiane1424282013-07-29 21:24:40 -0700684 if (size < getFlattenedSize()) {
685 return NO_MEMORY;
686 }
687 FlattenableUtils::write(buffer, size, timestamp);
Andy McFadden3c256212013-08-16 14:55:39 -0700688 FlattenableUtils::write(buffer, size, isAutoTimestamp);
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800689 FlattenableUtils::write(buffer, size, dataSpace);
Mathias Agopiane1424282013-07-29 21:24:40 -0700690 FlattenableUtils::write(buffer, size, crop);
691 FlattenableUtils::write(buffer, size, scalingMode);
692 FlattenableUtils::write(buffer, size, transform);
Ruben Brunk1681d952014-06-27 15:51:55 -0700693 FlattenableUtils::write(buffer, size, stickyTransform);
Dan Stoza5065a552015-03-17 16:23:42 -0700694 status_t result = fence->flatten(buffer, size, fds, count);
695 if (result != NO_ERROR) {
696 return result;
697 }
698 return surfaceDamage.flatten(buffer, size);
Jesse Hallc777b0b2012-06-28 12:52:05 -0700699}
700
Mathias Agopiane1424282013-07-29 21:24:40 -0700701status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
702 void const*& buffer, size_t& size, int const*& fds, size_t& count)
Jesse Hallc777b0b2012-06-28 12:52:05 -0700703{
Mathias Agopiane1424282013-07-29 21:24:40 -0700704 size_t minNeeded =
705 sizeof(timestamp)
Andy McFadden3c256212013-08-16 14:55:39 -0700706 + sizeof(isAutoTimestamp)
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800707 + sizeof(dataSpace)
Mathias Agopiane1424282013-07-29 21:24:40 -0700708 + sizeof(crop)
709 + sizeof(scalingMode)
710 + sizeof(transform)
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700711 + sizeof(stickyTransform);
Mathias Agopiane1424282013-07-29 21:24:40 -0700712
713 if (size < minNeeded) {
714 return NO_MEMORY;
715 }
716
717 FlattenableUtils::read(buffer, size, timestamp);
Andy McFadden3c256212013-08-16 14:55:39 -0700718 FlattenableUtils::read(buffer, size, isAutoTimestamp);
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800719 FlattenableUtils::read(buffer, size, dataSpace);
Mathias Agopiane1424282013-07-29 21:24:40 -0700720 FlattenableUtils::read(buffer, size, crop);
721 FlattenableUtils::read(buffer, size, scalingMode);
722 FlattenableUtils::read(buffer, size, transform);
Ruben Brunk1681d952014-06-27 15:51:55 -0700723 FlattenableUtils::read(buffer, size, stickyTransform);
Mathias Agopiane1424282013-07-29 21:24:40 -0700724
Jamie Gennis1df8c342012-12-20 14:05:45 -0800725 fence = new Fence();
Dan Stoza5065a552015-03-17 16:23:42 -0700726 status_t result = fence->unflatten(buffer, size, fds, count);
727 if (result != NO_ERROR) {
728 return result;
729 }
730 return surfaceDamage.unflatten(buffer, size);
Jesse Hallc777b0b2012-06-28 12:52:05 -0700731}
732
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800733}; // namespace android