2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <sys/types.h>
20 #include <utils/Errors.h>
21 #include <utils/NativeHandle.h>
22 #include <utils/RefBase.h>
23 #include <utils/Timers.h>
24 #include <utils/Vector.h>
26 #include <binder/Parcel.h>
27 #include <binder/IInterface.h>
29 #include <gui/IGraphicBufferProducer.h>
30 #include <gui/IProducerListener.h>
33 // ----------------------------------------------------------------------------
36 REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
50 SET_GENERATION_NUMBER,
54 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
57 BpGraphicBufferProducer(const sp<IBinder>& impl)
58 : BpInterface<IGraphicBufferProducer>(impl)
62 virtual ~BpGraphicBufferProducer();
64 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
66 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
67 data.writeInt32(bufferIdx);
68 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
69 if (result != NO_ERROR) {
72 bool nonNull = reply.readInt32();
74 *buf = new GraphicBuffer();
75 result = reply.read(**buf);
76 if(result != NO_ERROR) {
81 result = reply.readInt32();
85 virtual status_t setBufferCount(int bufferCount)
88 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
89 data.writeInt32(bufferCount);
90 status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply);
91 if (result != NO_ERROR) {
94 result = reply.readInt32();
98 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async,
99 uint32_t width, uint32_t height, PixelFormat format,
102 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
103 data.writeInt32(static_cast<int32_t>(async));
104 data.writeUint32(width);
105 data.writeUint32(height);
106 data.writeInt32(static_cast<int32_t>(format));
107 data.writeUint32(usage);
108 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
109 if (result != NO_ERROR) {
112 *buf = reply.readInt32();
113 bool nonNull = reply.readInt32();
115 *fence = new Fence();
118 result = reply.readInt32();
122 virtual status_t detachBuffer(int slot) {
124 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
125 data.writeInt32(slot);
126 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
127 if (result != NO_ERROR) {
130 result = reply.readInt32();
134 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
135 sp<Fence>* outFence) {
136 if (outBuffer == NULL) {
137 ALOGE("detachNextBuffer: outBuffer must not be NULL");
139 } else if (outFence == NULL) {
140 ALOGE("detachNextBuffer: outFence must not be NULL");
144 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
145 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply);
146 if (result != NO_ERROR) {
149 result = reply.readInt32();
150 if (result == NO_ERROR) {
151 bool nonNull = reply.readInt32();
153 *outBuffer = new GraphicBuffer;
154 reply.read(**outBuffer);
156 nonNull = reply.readInt32();
158 *outFence = new Fence;
159 reply.read(**outFence);
165 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
167 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
168 data.write(*buffer.get());
169 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
170 if (result != NO_ERROR) {
173 *slot = reply.readInt32();
174 result = reply.readInt32();
178 virtual status_t queueBuffer(int buf,
179 const QueueBufferInput& input, QueueBufferOutput* output) {
181 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
182 data.writeInt32(buf);
184 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
185 if (result != NO_ERROR) {
188 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
189 result = reply.readInt32();
193 virtual void cancelBuffer(int buf, const sp<Fence>& fence) {
195 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
196 data.writeInt32(buf);
197 data.write(*fence.get());
198 remote()->transact(CANCEL_BUFFER, data, &reply);
201 virtual int query(int what, int* value) {
203 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
204 data.writeInt32(what);
205 status_t result = remote()->transact(QUERY, data, &reply);
206 if (result != NO_ERROR) {
209 value[0] = reply.readInt32();
210 result = reply.readInt32();
214 virtual status_t connect(const sp<IProducerListener>& listener,
215 int api, bool producerControlledByApp, QueueBufferOutput* output) {
217 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
218 if (listener != NULL) {
220 data.writeStrongBinder(IInterface::asBinder(listener));
224 data.writeInt32(api);
225 data.writeInt32(producerControlledByApp);
226 status_t result = remote()->transact(CONNECT, data, &reply);
227 if (result != NO_ERROR) {
230 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
231 result = reply.readInt32();
235 virtual status_t disconnect(int api) {
237 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
238 data.writeInt32(api);
239 status_t result =remote()->transact(DISCONNECT, data, &reply);
240 if (result != NO_ERROR) {
243 result = reply.readInt32();
247 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
250 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
252 data.writeInt32(true);
253 data.writeNativeHandle(stream->handle());
255 data.writeInt32(false);
257 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
258 result = reply.readInt32();
263 virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
264 PixelFormat format, uint32_t usage) {
266 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
267 data.writeInt32(static_cast<int32_t>(async));
268 data.writeUint32(width);
269 data.writeUint32(height);
270 data.writeInt32(static_cast<int32_t>(format));
271 data.writeUint32(usage);
272 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
273 if (result != NO_ERROR) {
274 ALOGE("allocateBuffers failed to transact: %d", result);
278 virtual status_t allowAllocation(bool allow) {
280 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
281 data.writeInt32(static_cast<int32_t>(allow));
282 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
283 if (result != NO_ERROR) {
286 result = reply.readInt32();
290 virtual status_t setGenerationNumber(uint32_t generationNumber) {
292 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
293 data.writeUint32(generationNumber);
294 status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply);
295 if (result == NO_ERROR) {
296 result = reply.readInt32();
301 virtual String8 getConsumerName() const {
303 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
304 status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply);
305 if (result != NO_ERROR) {
306 ALOGE("getConsumerName failed to transact: %d", result);
307 return String8("TransactFailed");
309 return reply.readString8();
313 // Out-of-line virtual method definition to trigger vtable emission in this
314 // translation unit (see clang warning -Wweak-vtables)
315 BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
317 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
319 // ----------------------------------------------------------------------
321 status_t BnGraphicBufferProducer::onTransact(
322 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
325 case REQUEST_BUFFER: {
326 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
327 int bufferIdx = data.readInt32();
328 sp<GraphicBuffer> buffer;
329 int result = requestBuffer(bufferIdx, &buffer);
330 reply->writeInt32(buffer != 0);
332 reply->write(*buffer);
334 reply->writeInt32(result);
337 case SET_BUFFER_COUNT: {
338 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
339 int bufferCount = data.readInt32();
340 int result = setBufferCount(bufferCount);
341 reply->writeInt32(result);
344 case DEQUEUE_BUFFER: {
345 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
346 bool async = static_cast<bool>(data.readInt32());
347 uint32_t width = data.readUint32();
348 uint32_t height = data.readUint32();
349 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
350 uint32_t usage = data.readUint32();
353 int result = dequeueBuffer(&buf, &fence, async, width, height,
355 reply->writeInt32(buf);
356 reply->writeInt32(fence != NULL);
358 reply->write(*fence);
360 reply->writeInt32(result);
363 case DETACH_BUFFER: {
364 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
365 int slot = data.readInt32();
366 int result = detachBuffer(slot);
367 reply->writeInt32(result);
370 case DETACH_NEXT_BUFFER: {
371 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
372 sp<GraphicBuffer> buffer;
374 int32_t result = detachNextBuffer(&buffer, &fence);
375 reply->writeInt32(result);
376 if (result == NO_ERROR) {
377 reply->writeInt32(buffer != NULL);
378 if (buffer != NULL) {
379 reply->write(*buffer);
381 reply->writeInt32(fence != NULL);
383 reply->write(*fence);
388 case ATTACH_BUFFER: {
389 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
390 sp<GraphicBuffer> buffer = new GraphicBuffer();
391 data.read(*buffer.get());
393 int result = attachBuffer(&slot, buffer);
394 reply->writeInt32(slot);
395 reply->writeInt32(result);
399 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
400 int buf = data.readInt32();
401 QueueBufferInput input(data);
402 QueueBufferOutput* const output =
403 reinterpret_cast<QueueBufferOutput *>(
404 reply->writeInplace(sizeof(QueueBufferOutput)));
405 memset(output, 0, sizeof(QueueBufferOutput));
406 status_t result = queueBuffer(buf, input, output);
407 reply->writeInt32(result);
410 case CANCEL_BUFFER: {
411 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
412 int buf = data.readInt32();
413 sp<Fence> fence = new Fence();
414 data.read(*fence.get());
415 cancelBuffer(buf, fence);
419 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
421 int what = data.readInt32();
422 int res = query(what, &value);
423 reply->writeInt32(value);
424 reply->writeInt32(res);
428 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
429 sp<IProducerListener> listener;
430 if (data.readInt32() == 1) {
431 listener = IProducerListener::asInterface(data.readStrongBinder());
433 int api = data.readInt32();
434 bool producerControlledByApp = data.readInt32();
435 QueueBufferOutput* const output =
436 reinterpret_cast<QueueBufferOutput *>(
437 reply->writeInplace(sizeof(QueueBufferOutput)));
438 memset(output, 0, sizeof(QueueBufferOutput));
439 status_t res = connect(listener, api, producerControlledByApp, output);
440 reply->writeInt32(res);
444 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
445 int api = data.readInt32();
446 status_t res = disconnect(api);
447 reply->writeInt32(res);
450 case SET_SIDEBAND_STREAM: {
451 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
452 sp<NativeHandle> stream;
453 if (data.readInt32()) {
454 stream = NativeHandle::create(data.readNativeHandle(), true);
456 status_t result = setSidebandStream(stream);
457 reply->writeInt32(result);
460 case ALLOCATE_BUFFERS: {
461 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
462 bool async = static_cast<bool>(data.readInt32());
463 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();
467 allocateBuffers(async, width, height, format, usage);
470 case ALLOW_ALLOCATION: {
471 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
472 bool allow = static_cast<bool>(data.readInt32());
473 status_t result = allowAllocation(allow);
474 reply->writeInt32(result);
477 case SET_GENERATION_NUMBER: {
478 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
479 uint32_t generationNumber = data.readUint32();
480 status_t result = setGenerationNumber(generationNumber);
481 reply->writeInt32(result);
484 case GET_CONSUMER_NAME: {
485 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
486 reply->writeString8(getConsumerName());
490 return BBinder::onTransact(code, data, reply, flags);
493 // ----------------------------------------------------------------------------
495 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
499 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
500 return sizeof(timestamp)
501 + sizeof(isAutoTimestamp)
504 + sizeof(scalingMode)
506 + sizeof(stickyTransform)
508 + fence->getFlattenedSize()
509 + surfaceDamage.getFlattenedSize();
512 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
513 return fence->getFdCount();
516 status_t IGraphicBufferProducer::QueueBufferInput::flatten(
517 void*& buffer, size_t& size, int*& fds, size_t& count) const
519 if (size < getFlattenedSize()) {
522 FlattenableUtils::write(buffer, size, timestamp);
523 FlattenableUtils::write(buffer, size, isAutoTimestamp);
524 FlattenableUtils::write(buffer, size, dataSpace);
525 FlattenableUtils::write(buffer, size, crop);
526 FlattenableUtils::write(buffer, size, scalingMode);
527 FlattenableUtils::write(buffer, size, transform);
528 FlattenableUtils::write(buffer, size, stickyTransform);
529 FlattenableUtils::write(buffer, size, async);
530 status_t result = fence->flatten(buffer, size, fds, count);
531 if (result != NO_ERROR) {
534 return surfaceDamage.flatten(buffer, size);
537 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
538 void const*& buffer, size_t& size, int const*& fds, size_t& count)
542 + sizeof(isAutoTimestamp)
545 + sizeof(scalingMode)
547 + sizeof(stickyTransform)
550 if (size < minNeeded) {
554 FlattenableUtils::read(buffer, size, timestamp);
555 FlattenableUtils::read(buffer, size, isAutoTimestamp);
556 FlattenableUtils::read(buffer, size, dataSpace);
557 FlattenableUtils::read(buffer, size, crop);
558 FlattenableUtils::read(buffer, size, scalingMode);
559 FlattenableUtils::read(buffer, size, transform);
560 FlattenableUtils::read(buffer, size, stickyTransform);
561 FlattenableUtils::read(buffer, size, async);
564 status_t result = fence->unflatten(buffer, size, fds, count);
565 if (result != NO_ERROR) {
568 return surfaceDamage.unflatten(buffer, size);
571 }; // namespace android