blob: 2c48d83d96da7f24f551ff2a0cdacaefa42bf51e [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,
John Reck1a61da52016-04-28 13:18:15 -0700385 sp<Fence>* outFence, float outTransformMatrix[16]) override {
Dan Stoza50101d02016-04-07 16:53:23 -0700386 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);
John Reck1a61da52016-04-28 13:18:15 -0700403 if (result == NO_ERROR) {
404 result = reply.read(outTransformMatrix, sizeof(float) * 16);
405 }
John Reckce8e5df2016-04-28 10:12:47 -0700406 }
Dan Stoza50101d02016-04-07 16:53:23 -0700407 if (result != NO_ERROR) {
408 ALOGE("getLastQueuedBuffer failed to read buffer: %d", result);
409 return result;
410 }
411 sp<Fence> fence(new Fence);
412 result = reply.read(*fence);
413 if (result != NO_ERROR) {
414 ALOGE("getLastQueuedBuffer failed to read fence: %d", result);
415 return result;
416 }
417 *outBuffer = buffer;
418 *outFence = fence;
419 return result;
420 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800421};
422
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800423// Out-of-line virtual method definition to trigger vtable emission in this
424// translation unit (see clang warning -Wweak-vtables)
425BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
426
Andy McFadden466a1922013-01-08 11:25:51 -0800427IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800428
429// ----------------------------------------------------------------------
430
Andy McFadden2adaf042012-12-18 09:49:45 -0800431status_t BnGraphicBufferProducer::onTransact(
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800432 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
433{
434 switch(code) {
435 case REQUEST_BUFFER: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800436 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800437 int bufferIdx = data.readInt32();
Jamie Gennis7b305ff2011-07-19 12:08:33 -0700438 sp<GraphicBuffer> buffer;
439 int result = requestBuffer(bufferIdx, &buffer);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800440 reply->writeInt32(buffer != 0);
441 if (buffer != 0) {
442 reply->write(*buffer);
443 }
Jamie Gennis7b305ff2011-07-19 12:08:33 -0700444 reply->writeInt32(result);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800445 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800446 }
Pablo Ceballosfa455352015-08-12 17:47:47 -0700447 case SET_MAX_DEQUEUED_BUFFER_COUNT: {
448 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
449 int maxDequeuedBuffers = data.readInt32();
450 int result = setMaxDequeuedBufferCount(maxDequeuedBuffers);
451 reply->writeInt32(result);
452 return NO_ERROR;
453 }
454 case SET_ASYNC_MODE: {
455 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
456 bool async = data.readInt32();
457 int result = setAsyncMode(async);
458 reply->writeInt32(result);
459 return NO_ERROR;
460 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800461 case DEQUEUE_BUFFER: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800462 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800463 uint32_t width = data.readUint32();
464 uint32_t height = data.readUint32();
465 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
466 uint32_t usage = data.readUint32();
Naveen Leekha12ba0f52015-09-21 17:28:04 -0700467 int buf = 0;
Jesse Hallf7857542012-06-14 15:26:33 -0700468 sp<Fence> fence;
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700469 int result = dequeueBuffer(&buf, &fence, width, height, format,
470 usage);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800471 reply->writeInt32(buf);
Jamie Gennis1df8c342012-12-20 14:05:45 -0800472 reply->writeInt32(fence != NULL);
473 if (fence != NULL) {
Mathias Agopianba93b3f2013-08-01 15:48:40 -0700474 reply->write(*fence);
Jesse Hallf7857542012-06-14 15:26:33 -0700475 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800476 reply->writeInt32(result);
477 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800478 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800479 case DETACH_BUFFER: {
480 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
481 int slot = data.readInt32();
482 int result = detachBuffer(slot);
483 reply->writeInt32(result);
484 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800485 }
Dan Stozad9822a32014-03-28 15:25:31 -0700486 case DETACH_NEXT_BUFFER: {
487 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
488 sp<GraphicBuffer> buffer;
489 sp<Fence> fence;
490 int32_t result = detachNextBuffer(&buffer, &fence);
491 reply->writeInt32(result);
492 if (result == NO_ERROR) {
493 reply->writeInt32(buffer != NULL);
494 if (buffer != NULL) {
495 reply->write(*buffer);
496 }
497 reply->writeInt32(fence != NULL);
498 if (fence != NULL) {
499 reply->write(*fence);
500 }
501 }
502 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800503 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800504 case ATTACH_BUFFER: {
505 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
506 sp<GraphicBuffer> buffer = new GraphicBuffer();
507 data.read(*buffer.get());
Naveen Leekha12ba0f52015-09-21 17:28:04 -0700508 int slot = 0;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800509 int result = attachBuffer(&slot, buffer);
510 reply->writeInt32(slot);
511 reply->writeInt32(result);
512 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800513 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800514 case QUEUE_BUFFER: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800515 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800516 int buf = data.readInt32();
Jesse Hallc777b0b2012-06-28 12:52:05 -0700517 QueueBufferInput input(data);
Mathias Agopianf0bc2f12012-04-09 16:14:01 -0700518 QueueBufferOutput* const output =
519 reinterpret_cast<QueueBufferOutput *>(
520 reply->writeInplace(sizeof(QueueBufferOutput)));
Robert Shihd06421f2016-01-11 15:02:12 -0800521 memset(output, 0, sizeof(QueueBufferOutput));
Jesse Hallc777b0b2012-06-28 12:52:05 -0700522 status_t result = queueBuffer(buf, input, output);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800523 reply->writeInt32(result);
524 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800525 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800526 case CANCEL_BUFFER: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800527 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800528 int buf = data.readInt32();
Jamie Gennis1df8c342012-12-20 14:05:45 -0800529 sp<Fence> fence = new Fence();
530 data.read(*fence.get());
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700531 status_t result = cancelBuffer(buf, fence);
532 reply->writeInt32(result);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800533 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800534 }
Mathias Agopianeafabcd2011-04-20 14:20:59 -0700535 case QUERY: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800536 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Naveen Leekha12ba0f52015-09-21 17:28:04 -0700537 int value = 0;
Mathias Agopianeafabcd2011-04-20 14:20:59 -0700538 int what = data.readInt32();
539 int res = query(what, &value);
540 reply->writeInt32(value);
541 reply->writeInt32(res);
542 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800543 }
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700544 case CONNECT: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800545 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Dan Stozaf0eaf252014-03-21 13:05:51 -0700546 sp<IProducerListener> listener;
547 if (data.readInt32() == 1) {
548 listener = IProducerListener::asInterface(data.readStrongBinder());
549 }
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700550 int api = data.readInt32();
Mathias Agopian595264f2013-07-16 22:56:09 -0700551 bool producerControlledByApp = data.readInt32();
Mathias Agopian24202f52012-04-23 14:28:58 -0700552 QueueBufferOutput* const output =
553 reinterpret_cast<QueueBufferOutput *>(
554 reply->writeInplace(sizeof(QueueBufferOutput)));
Pablo Ceballos93c617f2016-03-15 18:10:49 -0700555 memset(output, 0, sizeof(QueueBufferOutput));
Dan Stozaf0eaf252014-03-21 13:05:51 -0700556 status_t res = connect(listener, api, producerControlledByApp, output);
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700557 reply->writeInt32(res);
558 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800559 }
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700560 case DISCONNECT: {
Andy McFadden2adaf042012-12-18 09:49:45 -0800561 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700562 int api = data.readInt32();
Mathias Agopian27730042011-07-14 20:20:58 -0700563 status_t res = disconnect(api);
Jamie Gennisfe0a87b2011-07-13 19:12:20 -0700564 reply->writeInt32(res);
565 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800566 }
Jesse Hall399184a2014-03-03 15:42:54 -0800567 case SET_SIDEBAND_STREAM: {
568 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
569 sp<NativeHandle> stream;
570 if (data.readInt32()) {
Wonsik Kim0ec54e12014-03-21 10:46:24 +0900571 stream = NativeHandle::create(data.readNativeHandle(), true);
Jesse Hall399184a2014-03-03 15:42:54 -0800572 }
573 status_t result = setSidebandStream(stream);
574 reply->writeInt32(result);
575 return NO_ERROR;
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800576 }
Dan Stoza9de72932015-04-16 17:28:43 -0700577 case ALLOCATE_BUFFERS: {
Dan Stoza29a3e902014-06-20 13:13:57 -0700578 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Dan Stoza3be1c6b2014-11-18 10:24:03 -0800579 uint32_t width = data.readUint32();
580 uint32_t height = data.readUint32();
581 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
582 uint32_t usage = data.readUint32();
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700583 allocateBuffers(width, height, format, usage);
Dan Stoza29a3e902014-06-20 13:13:57 -0700584 return NO_ERROR;
Dan Stoza9de72932015-04-16 17:28:43 -0700585 }
586 case ALLOW_ALLOCATION: {
587 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
588 bool allow = static_cast<bool>(data.readInt32());
589 status_t result = allowAllocation(allow);
590 reply->writeInt32(result);
591 return NO_ERROR;
592 }
Dan Stoza812ed062015-06-02 15:45:22 -0700593 case SET_GENERATION_NUMBER: {
594 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
595 uint32_t generationNumber = data.readUint32();
596 status_t result = setGenerationNumber(generationNumber);
597 reply->writeInt32(result);
598 return NO_ERROR;
599 }
Dan Stozac6f30bd2015-06-08 09:32:50 -0700600 case GET_CONSUMER_NAME: {
601 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
602 reply->writeString8(getConsumerName());
603 return NO_ERROR;
604 }
Dan Stoza7dde5992015-05-22 09:51:44 -0700605 case GET_NEXT_FRAME_NUMBER: {
606 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
607 uint64_t frameNumber = getNextFrameNumber();
608 reply->writeUint64(frameNumber);
609 return NO_ERROR;
610 }
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700611 case SET_SHARED_BUFFER_MODE: {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700612 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700613 bool sharedBufferMode = data.readInt32();
614 status_t result = setSharedBufferMode(sharedBufferMode);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700615 reply->writeInt32(result);
616 return NO_ERROR;
617 }
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800618 case SET_AUTO_REFRESH: {
619 CHECK_INTERFACE(IGraphicBuffer, data, reply);
620 bool autoRefresh = data.readInt32();
621 status_t result = setAutoRefresh(autoRefresh);
622 reply->writeInt32(result);
623 return NO_ERROR;
624 }
Dan Stoza127fc632015-06-30 13:43:32 -0700625 case SET_DEQUEUE_TIMEOUT: {
626 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
627 nsecs_t timeout = data.readInt64();
628 status_t result = setDequeueTimeout(timeout);
629 reply->writeInt32(result);
630 return NO_ERROR;
631 }
Dan Stoza50101d02016-04-07 16:53:23 -0700632 case GET_LAST_QUEUED_BUFFER: {
633 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
634 sp<GraphicBuffer> buffer(nullptr);
635 sp<Fence> fence(Fence::NO_FENCE);
John Reck1a61da52016-04-28 13:18:15 -0700636 float transform[16] = {};
637 status_t result = getLastQueuedBuffer(&buffer, &fence, transform);
Dan Stoza50101d02016-04-07 16:53:23 -0700638 reply->writeInt32(result);
639 if (result != NO_ERROR) {
640 return result;
641 }
John Reckce8e5df2016-04-28 10:12:47 -0700642 if (!buffer.get()) {
643 reply->writeBool(false);
644 } else {
645 reply->writeBool(true);
646 result = reply->write(*buffer);
John Reck1a61da52016-04-28 13:18:15 -0700647 if (result == NO_ERROR) {
648 reply->write(transform, sizeof(float) * 16);
649 }
John Reckce8e5df2016-04-28 10:12:47 -0700650 }
Dan Stoza50101d02016-04-07 16:53:23 -0700651 if (result != NO_ERROR) {
652 ALOGE("getLastQueuedBuffer failed to write buffer: %d", result);
653 return result;
654 }
655 result = reply->write(*fence);
656 if (result != NO_ERROR) {
657 ALOGE("getLastQueuedBuffer failed to write fence: %d", result);
658 return result;
659 }
660 return NO_ERROR;
661 }
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800662 }
663 return BBinder::onTransact(code, data, reply, flags);
664}
665
666// ----------------------------------------------------------------------------
667
Andy McFadden2adaf042012-12-18 09:49:45 -0800668IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
Jesse Hallc777b0b2012-06-28 12:52:05 -0700669 parcel.read(*this);
670}
671
Mathias Agopiane1424282013-07-29 21:24:40 -0700672size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
Jesse Hallc777b0b2012-06-28 12:52:05 -0700673 return sizeof(timestamp)
Andy McFadden3c256212013-08-16 14:55:39 -0700674 + sizeof(isAutoTimestamp)
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800675 + sizeof(dataSpace)
Jesse Hallc777b0b2012-06-28 12:52:05 -0700676 + sizeof(crop)
677 + sizeof(scalingMode)
678 + sizeof(transform)
Ruben Brunk1681d952014-06-27 15:51:55 -0700679 + sizeof(stickyTransform)
Dan Stoza5065a552015-03-17 16:23:42 -0700680 + fence->getFlattenedSize()
681 + surfaceDamage.getFlattenedSize();
Jesse Hallc777b0b2012-06-28 12:52:05 -0700682}
683
Mathias Agopiane1424282013-07-29 21:24:40 -0700684size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
Jamie Gennis1df8c342012-12-20 14:05:45 -0800685 return fence->getFdCount();
Jesse Hallc777b0b2012-06-28 12:52:05 -0700686}
687
Mathias Agopiane1424282013-07-29 21:24:40 -0700688status_t IGraphicBufferProducer::QueueBufferInput::flatten(
689 void*& buffer, size_t& size, int*& fds, size_t& count) const
Jesse Hallc777b0b2012-06-28 12:52:05 -0700690{
Mathias Agopiane1424282013-07-29 21:24:40 -0700691 if (size < getFlattenedSize()) {
692 return NO_MEMORY;
693 }
694 FlattenableUtils::write(buffer, size, timestamp);
Andy McFadden3c256212013-08-16 14:55:39 -0700695 FlattenableUtils::write(buffer, size, isAutoTimestamp);
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800696 FlattenableUtils::write(buffer, size, dataSpace);
Mathias Agopiane1424282013-07-29 21:24:40 -0700697 FlattenableUtils::write(buffer, size, crop);
698 FlattenableUtils::write(buffer, size, scalingMode);
699 FlattenableUtils::write(buffer, size, transform);
Ruben Brunk1681d952014-06-27 15:51:55 -0700700 FlattenableUtils::write(buffer, size, stickyTransform);
Dan Stoza5065a552015-03-17 16:23:42 -0700701 status_t result = fence->flatten(buffer, size, fds, count);
702 if (result != NO_ERROR) {
703 return result;
704 }
705 return surfaceDamage.flatten(buffer, size);
Jesse Hallc777b0b2012-06-28 12:52:05 -0700706}
707
Mathias Agopiane1424282013-07-29 21:24:40 -0700708status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
709 void const*& buffer, size_t& size, int const*& fds, size_t& count)
Jesse Hallc777b0b2012-06-28 12:52:05 -0700710{
Mathias Agopiane1424282013-07-29 21:24:40 -0700711 size_t minNeeded =
712 sizeof(timestamp)
Andy McFadden3c256212013-08-16 14:55:39 -0700713 + sizeof(isAutoTimestamp)
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800714 + sizeof(dataSpace)
Mathias Agopiane1424282013-07-29 21:24:40 -0700715 + sizeof(crop)
716 + sizeof(scalingMode)
717 + sizeof(transform)
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700718 + sizeof(stickyTransform);
Mathias Agopiane1424282013-07-29 21:24:40 -0700719
720 if (size < minNeeded) {
721 return NO_MEMORY;
722 }
723
724 FlattenableUtils::read(buffer, size, timestamp);
Andy McFadden3c256212013-08-16 14:55:39 -0700725 FlattenableUtils::read(buffer, size, isAutoTimestamp);
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800726 FlattenableUtils::read(buffer, size, dataSpace);
Mathias Agopiane1424282013-07-29 21:24:40 -0700727 FlattenableUtils::read(buffer, size, crop);
728 FlattenableUtils::read(buffer, size, scalingMode);
729 FlattenableUtils::read(buffer, size, transform);
Ruben Brunk1681d952014-06-27 15:51:55 -0700730 FlattenableUtils::read(buffer, size, stickyTransform);
Mathias Agopiane1424282013-07-29 21:24:40 -0700731
Jamie Gennis1df8c342012-12-20 14:05:45 -0800732 fence = new Fence();
Dan Stoza5065a552015-03-17 16:23:42 -0700733 status_t result = fence->unflatten(buffer, size, fds, count);
734 if (result != NO_ERROR) {
735 return result;
736 }
737 return surfaceDamage.unflatten(buffer, size);
Jesse Hallc777b0b2012-06-28 12:52:05 -0700738}
739
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800740}; // namespace android