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,
49 SET_GENERATION_NUMBER,
51 SET_MAX_DEQUEUED_BUFFER_COUNT,
53 GET_NEXT_FRAME_NUMBER,
54 SET_SHARED_BUFFER_MODE,
57 GET_LAST_QUEUED_BUFFER,
60 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
63 BpGraphicBufferProducer(const sp<IBinder>& impl)
64 : BpInterface<IGraphicBufferProducer>(impl)
68 virtual ~BpGraphicBufferProducer();
70 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
72 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
73 data.writeInt32(bufferIdx);
74 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
75 if (result != NO_ERROR) {
78 bool nonNull = reply.readInt32();
80 *buf = new GraphicBuffer();
81 result = reply.read(**buf);
82 if(result != NO_ERROR) {
87 result = reply.readInt32();
91 virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
93 data.writeInterfaceToken(
94 IGraphicBufferProducer::getInterfaceDescriptor());
95 data.writeInt32(maxDequeuedBuffers);
96 status_t result = remote()->transact(SET_MAX_DEQUEUED_BUFFER_COUNT,
98 if (result != NO_ERROR) {
101 result = reply.readInt32();
105 virtual status_t setAsyncMode(bool async) {
107 data.writeInterfaceToken(
108 IGraphicBufferProducer::getInterfaceDescriptor());
109 data.writeInt32(async);
110 status_t result = remote()->transact(SET_ASYNC_MODE,
112 if (result != NO_ERROR) {
115 result = reply.readInt32();
119 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, uint32_t width,
120 uint32_t height, PixelFormat format, uint32_t usage) {
122 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
123 data.writeUint32(width);
124 data.writeUint32(height);
125 data.writeInt32(static_cast<int32_t>(format));
126 data.writeUint32(usage);
127 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
128 if (result != NO_ERROR) {
131 *buf = reply.readInt32();
132 bool nonNull = reply.readInt32();
134 *fence = new Fence();
137 result = reply.readInt32();
141 virtual status_t detachBuffer(int slot) {
143 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
144 data.writeInt32(slot);
145 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
146 if (result != NO_ERROR) {
149 result = reply.readInt32();
153 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
154 sp<Fence>* outFence) {
155 if (outBuffer == NULL) {
156 ALOGE("detachNextBuffer: outBuffer must not be NULL");
158 } else if (outFence == NULL) {
159 ALOGE("detachNextBuffer: outFence must not be NULL");
163 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
164 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply);
165 if (result != NO_ERROR) {
168 result = reply.readInt32();
169 if (result == NO_ERROR) {
170 bool nonNull = reply.readInt32();
172 *outBuffer = new GraphicBuffer;
173 reply.read(**outBuffer);
175 nonNull = reply.readInt32();
177 *outFence = new Fence;
178 reply.read(**outFence);
184 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
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) {
192 *slot = reply.readInt32();
193 result = reply.readInt32();
197 virtual status_t queueBuffer(int buf,
198 const QueueBufferInput& input, QueueBufferOutput* output) {
200 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
201 data.writeInt32(buf);
203 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
204 if (result != NO_ERROR) {
207 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
208 result = reply.readInt32();
212 virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) {
214 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
215 data.writeInt32(buf);
216 data.write(*fence.get());
217 status_t result = remote()->transact(CANCEL_BUFFER, data, &reply);
218 if (result != NO_ERROR) {
221 result = reply.readInt32();
225 virtual int query(int what, int* value) {
227 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
228 data.writeInt32(what);
229 status_t result = remote()->transact(QUERY, data, &reply);
230 if (result != NO_ERROR) {
233 value[0] = reply.readInt32();
234 result = reply.readInt32();
238 virtual status_t connect(const sp<IProducerListener>& listener,
239 int api, bool producerControlledByApp, QueueBufferOutput* output) {
241 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
242 if (listener != NULL) {
244 data.writeStrongBinder(IInterface::asBinder(listener));
248 data.writeInt32(api);
249 data.writeInt32(producerControlledByApp);
250 status_t result = remote()->transact(CONNECT, data, &reply);
251 if (result != NO_ERROR) {
254 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
255 result = reply.readInt32();
259 virtual status_t disconnect(int api) {
261 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
262 data.writeInt32(api);
263 status_t result =remote()->transact(DISCONNECT, data, &reply);
264 if (result != NO_ERROR) {
267 result = reply.readInt32();
271 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
274 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
276 data.writeInt32(true);
277 data.writeNativeHandle(stream->handle());
279 data.writeInt32(false);
281 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
282 result = reply.readInt32();
287 virtual void allocateBuffers(uint32_t width, uint32_t height,
288 PixelFormat format, uint32_t usage) {
290 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
291 data.writeUint32(width);
292 data.writeUint32(height);
293 data.writeInt32(static_cast<int32_t>(format));
294 data.writeUint32(usage);
295 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
296 if (result != NO_ERROR) {
297 ALOGE("allocateBuffers failed to transact: %d", result);
301 virtual status_t allowAllocation(bool allow) {
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) {
309 result = reply.readInt32();
313 virtual status_t setGenerationNumber(uint32_t generationNumber) {
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();
324 virtual String8 getConsumerName() const {
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");
332 return reply.readString8();
335 virtual uint64_t getNextFrameNumber() const {
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);
343 uint64_t frameNumber = reply.readUint64();
347 virtual status_t setSharedBufferMode(bool sharedBufferMode) {
349 data.writeInterfaceToken(
350 IGraphicBufferProducer::getInterfaceDescriptor());
351 data.writeInt32(sharedBufferMode);
352 status_t result = remote()->transact(SET_SHARED_BUFFER_MODE, data,
354 if (result == NO_ERROR) {
355 result = reply.readInt32();
360 virtual status_t setAutoRefresh(bool autoRefresh) {
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();
372 virtual status_t setDequeueTimeout(nsecs_t timeout) {
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);
381 return reply.readInt32();
384 virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
385 sp<Fence>* outFence) override {
387 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
388 status_t result = remote()->transact(GET_LAST_QUEUED_BUFFER, data,
390 if (result != NO_ERROR) {
391 ALOGE("getLastQueuedBuffer failed to transact: %d", result);
394 result = reply.readInt32();
395 if (result != NO_ERROR) {
398 bool hasBuffer = reply.readBool();
399 sp<GraphicBuffer> buffer;
401 buffer = new GraphicBuffer();
402 result = reply.read(*buffer);
404 if (result != NO_ERROR) {
405 ALOGE("getLastQueuedBuffer failed to read buffer: %d", result);
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);
420 // Out-of-line virtual method definition to trigger vtable emission in this
421 // translation unit (see clang warning -Wweak-vtables)
422 BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
424 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
426 // ----------------------------------------------------------------------
428 status_t BnGraphicBufferProducer::onTransact(
429 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
432 case REQUEST_BUFFER: {
433 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
434 int bufferIdx = data.readInt32();
435 sp<GraphicBuffer> buffer;
436 int result = requestBuffer(bufferIdx, &buffer);
437 reply->writeInt32(buffer != 0);
439 reply->write(*buffer);
441 reply->writeInt32(result);
444 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);
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);
458 case DEQUEUE_BUFFER: {
459 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
460 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();
466 int result = dequeueBuffer(&buf, &fence, width, height, format,
468 reply->writeInt32(buf);
469 reply->writeInt32(fence != NULL);
471 reply->write(*fence);
473 reply->writeInt32(result);
476 case DETACH_BUFFER: {
477 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
478 int slot = data.readInt32();
479 int result = detachBuffer(slot);
480 reply->writeInt32(result);
483 case DETACH_NEXT_BUFFER: {
484 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
485 sp<GraphicBuffer> buffer;
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);
494 reply->writeInt32(fence != NULL);
496 reply->write(*fence);
501 case ATTACH_BUFFER: {
502 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
503 sp<GraphicBuffer> buffer = new GraphicBuffer();
504 data.read(*buffer.get());
506 int result = attachBuffer(&slot, buffer);
507 reply->writeInt32(slot);
508 reply->writeInt32(result);
512 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
513 int buf = data.readInt32();
514 QueueBufferInput input(data);
515 QueueBufferOutput* const output =
516 reinterpret_cast<QueueBufferOutput *>(
517 reply->writeInplace(sizeof(QueueBufferOutput)));
518 memset(output, 0, sizeof(QueueBufferOutput));
519 status_t result = queueBuffer(buf, input, output);
520 reply->writeInt32(result);
523 case CANCEL_BUFFER: {
524 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
525 int buf = data.readInt32();
526 sp<Fence> fence = new Fence();
527 data.read(*fence.get());
528 status_t result = cancelBuffer(buf, fence);
529 reply->writeInt32(result);
533 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
535 int what = data.readInt32();
536 int res = query(what, &value);
537 reply->writeInt32(value);
538 reply->writeInt32(res);
542 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
543 sp<IProducerListener> listener;
544 if (data.readInt32() == 1) {
545 listener = IProducerListener::asInterface(data.readStrongBinder());
547 int api = data.readInt32();
548 bool producerControlledByApp = data.readInt32();
549 QueueBufferOutput* const output =
550 reinterpret_cast<QueueBufferOutput *>(
551 reply->writeInplace(sizeof(QueueBufferOutput)));
552 memset(output, 0, sizeof(QueueBufferOutput));
553 status_t res = connect(listener, api, producerControlledByApp, output);
554 reply->writeInt32(res);
558 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
559 int api = data.readInt32();
560 status_t res = disconnect(api);
561 reply->writeInt32(res);
564 case SET_SIDEBAND_STREAM: {
565 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
566 sp<NativeHandle> stream;
567 if (data.readInt32()) {
568 stream = NativeHandle::create(data.readNativeHandle(), true);
570 status_t result = setSidebandStream(stream);
571 reply->writeInt32(result);
574 case ALLOCATE_BUFFERS: {
575 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
576 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();
580 allocateBuffers(width, height, format, usage);
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);
590 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);
597 case GET_CONSUMER_NAME: {
598 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
599 reply->writeString8(getConsumerName());
602 case GET_NEXT_FRAME_NUMBER: {
603 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
604 uint64_t frameNumber = getNextFrameNumber();
605 reply->writeUint64(frameNumber);
608 case SET_SHARED_BUFFER_MODE: {
609 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
610 bool sharedBufferMode = data.readInt32();
611 status_t result = setSharedBufferMode(sharedBufferMode);
612 reply->writeInt32(result);
615 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);
622 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);
629 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) {
639 reply->writeBool(false);
641 reply->writeBool(true);
642 result = reply->write(*buffer);
644 if (result != NO_ERROR) {
645 ALOGE("getLastQueuedBuffer failed to write buffer: %d", result);
648 result = reply->write(*fence);
649 if (result != NO_ERROR) {
650 ALOGE("getLastQueuedBuffer failed to write fence: %d", result);
656 return BBinder::onTransact(code, data, reply, flags);
659 // ----------------------------------------------------------------------------
661 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
665 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
666 return sizeof(timestamp)
667 + sizeof(isAutoTimestamp)
670 + sizeof(scalingMode)
672 + sizeof(stickyTransform)
673 + fence->getFlattenedSize()
674 + surfaceDamage.getFlattenedSize();
677 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
678 return fence->getFdCount();
681 status_t IGraphicBufferProducer::QueueBufferInput::flatten(
682 void*& buffer, size_t& size, int*& fds, size_t& count) const
684 if (size < getFlattenedSize()) {
687 FlattenableUtils::write(buffer, size, timestamp);
688 FlattenableUtils::write(buffer, size, isAutoTimestamp);
689 FlattenableUtils::write(buffer, size, dataSpace);
690 FlattenableUtils::write(buffer, size, crop);
691 FlattenableUtils::write(buffer, size, scalingMode);
692 FlattenableUtils::write(buffer, size, transform);
693 FlattenableUtils::write(buffer, size, stickyTransform);
694 status_t result = fence->flatten(buffer, size, fds, count);
695 if (result != NO_ERROR) {
698 return surfaceDamage.flatten(buffer, size);
701 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
702 void const*& buffer, size_t& size, int const*& fds, size_t& count)
706 + sizeof(isAutoTimestamp)
709 + sizeof(scalingMode)
711 + sizeof(stickyTransform);
713 if (size < minNeeded) {
717 FlattenableUtils::read(buffer, size, timestamp);
718 FlattenableUtils::read(buffer, size, isAutoTimestamp);
719 FlattenableUtils::read(buffer, size, dataSpace);
720 FlattenableUtils::read(buffer, size, crop);
721 FlattenableUtils::read(buffer, size, scalingMode);
722 FlattenableUtils::read(buffer, size, transform);
723 FlattenableUtils::read(buffer, size, stickyTransform);
726 status_t result = fence->unflatten(buffer, size, fds, count);
727 if (result != NO_ERROR) {
730 return surfaceDamage.unflatten(buffer, size);
733 }; // namespace android