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,
62 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
65 BpGraphicBufferProducer(const sp<IBinder>& impl)
66 : BpInterface<IGraphicBufferProducer>(impl)
70 virtual ~BpGraphicBufferProducer();
72 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
74 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
75 data.writeInt32(bufferIdx);
76 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
77 if (result != NO_ERROR) {
80 bool nonNull = reply.readInt32();
82 *buf = new GraphicBuffer();
83 result = reply.read(**buf);
84 if(result != NO_ERROR) {
89 result = reply.readInt32();
93 virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
95 data.writeInterfaceToken(
96 IGraphicBufferProducer::getInterfaceDescriptor());
97 data.writeInt32(maxDequeuedBuffers);
98 status_t result = remote()->transact(SET_MAX_DEQUEUED_BUFFER_COUNT,
100 if (result != NO_ERROR) {
103 result = reply.readInt32();
107 virtual status_t setAsyncMode(bool async) {
109 data.writeInterfaceToken(
110 IGraphicBufferProducer::getInterfaceDescriptor());
111 data.writeInt32(async);
112 status_t result = remote()->transact(SET_ASYNC_MODE,
114 if (result != NO_ERROR) {
117 result = reply.readInt32();
121 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, uint32_t width,
122 uint32_t height, PixelFormat format, uint32_t usage) {
124 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
125 data.writeUint32(width);
126 data.writeUint32(height);
127 data.writeInt32(static_cast<int32_t>(format));
128 data.writeUint32(usage);
129 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
130 if (result != NO_ERROR) {
133 *buf = reply.readInt32();
134 bool nonNull = reply.readInt32();
136 *fence = new Fence();
137 result = reply.read(**fence);
138 if (result != NO_ERROR) {
143 result = reply.readInt32();
147 virtual status_t detachBuffer(int slot) {
149 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
150 data.writeInt32(slot);
151 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
152 if (result != NO_ERROR) {
155 result = reply.readInt32();
159 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
160 sp<Fence>* outFence) {
161 if (outBuffer == NULL) {
162 ALOGE("detachNextBuffer: outBuffer must not be NULL");
164 } else if (outFence == NULL) {
165 ALOGE("detachNextBuffer: outFence must not be NULL");
169 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
170 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply);
171 if (result != NO_ERROR) {
174 result = reply.readInt32();
175 if (result == NO_ERROR) {
176 bool nonNull = reply.readInt32();
178 *outBuffer = new GraphicBuffer;
179 result = reply.read(**outBuffer);
180 if (result != NO_ERROR) {
185 nonNull = reply.readInt32();
187 *outFence = new Fence;
188 result = reply.read(**outFence);
189 if (result != NO_ERROR) {
199 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
201 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
202 data.write(*buffer.get());
203 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
204 if (result != NO_ERROR) {
207 *slot = reply.readInt32();
208 result = reply.readInt32();
212 virtual status_t queueBuffer(int buf,
213 const QueueBufferInput& input, QueueBufferOutput* output) {
215 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
216 data.writeInt32(buf);
218 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
219 if (result != NO_ERROR) {
222 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
223 result = reply.readInt32();
227 virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) {
229 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
230 data.writeInt32(buf);
231 data.write(*fence.get());
232 status_t result = remote()->transact(CANCEL_BUFFER, data, &reply);
233 if (result != NO_ERROR) {
236 result = reply.readInt32();
240 virtual int query(int what, int* value) {
242 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
243 data.writeInt32(what);
244 status_t result = remote()->transact(QUERY, data, &reply);
245 if (result != NO_ERROR) {
248 value[0] = reply.readInt32();
249 result = reply.readInt32();
253 virtual status_t connect(const sp<IProducerListener>& listener,
254 int api, bool producerControlledByApp, QueueBufferOutput* output) {
256 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
257 if (listener != NULL) {
259 data.writeStrongBinder(IInterface::asBinder(listener));
263 data.writeInt32(api);
264 data.writeInt32(producerControlledByApp);
265 status_t result = remote()->transact(CONNECT, data, &reply);
266 if (result != NO_ERROR) {
269 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
270 result = reply.readInt32();
274 virtual status_t disconnect(int api) {
276 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
277 data.writeInt32(api);
278 status_t result =remote()->transact(DISCONNECT, data, &reply);
279 if (result != NO_ERROR) {
282 result = reply.readInt32();
286 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
289 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
291 data.writeInt32(true);
292 data.writeNativeHandle(stream->handle());
294 data.writeInt32(false);
296 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
297 result = reply.readInt32();
302 virtual void allocateBuffers(uint32_t width, uint32_t height,
303 PixelFormat format, uint32_t usage) {
305 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
306 data.writeUint32(width);
307 data.writeUint32(height);
308 data.writeInt32(static_cast<int32_t>(format));
309 data.writeUint32(usage);
310 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
311 if (result != NO_ERROR) {
312 ALOGE("allocateBuffers failed to transact: %d", result);
316 virtual status_t allowAllocation(bool allow) {
318 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
319 data.writeInt32(static_cast<int32_t>(allow));
320 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
321 if (result != NO_ERROR) {
324 result = reply.readInt32();
328 virtual status_t setGenerationNumber(uint32_t generationNumber) {
330 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
331 data.writeUint32(generationNumber);
332 status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply);
333 if (result == NO_ERROR) {
334 result = reply.readInt32();
339 virtual String8 getConsumerName() const {
341 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
342 status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply);
343 if (result != NO_ERROR) {
344 ALOGE("getConsumerName failed to transact: %d", result);
345 return String8("TransactFailed");
347 return reply.readString8();
350 virtual uint64_t getNextFrameNumber() const {
352 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
353 status_t result = remote()->transact(GET_NEXT_FRAME_NUMBER, data, &reply);
354 if (result != NO_ERROR) {
355 ALOGE("getNextFrameNumber failed to transact: %d", result);
358 uint64_t frameNumber = reply.readUint64();
362 virtual status_t setSharedBufferMode(bool sharedBufferMode) {
364 data.writeInterfaceToken(
365 IGraphicBufferProducer::getInterfaceDescriptor());
366 data.writeInt32(sharedBufferMode);
367 status_t result = remote()->transact(SET_SHARED_BUFFER_MODE, data,
369 if (result == NO_ERROR) {
370 result = reply.readInt32();
375 virtual status_t setAutoRefresh(bool autoRefresh) {
377 data.writeInterfaceToken(
378 IGraphicBufferProducer::getInterfaceDescriptor());
379 data.writeInt32(autoRefresh);
380 status_t result = remote()->transact(SET_AUTO_REFRESH, data, &reply);
381 if (result == NO_ERROR) {
382 result = reply.readInt32();
387 virtual status_t setDequeueTimeout(nsecs_t timeout) {
389 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
390 data.writeInt64(timeout);
391 status_t result = remote()->transact(SET_DEQUEUE_TIMEOUT, data, &reply);
392 if (result != NO_ERROR) {
393 ALOGE("setDequeueTimeout failed to transact: %d", result);
396 return reply.readInt32();
399 virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
400 sp<Fence>* outFence, float outTransformMatrix[16]) override {
402 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
403 status_t result = remote()->transact(GET_LAST_QUEUED_BUFFER, data,
405 if (result != NO_ERROR) {
406 ALOGE("getLastQueuedBuffer failed to transact: %d", result);
409 result = reply.readInt32();
410 if (result != NO_ERROR) {
413 bool hasBuffer = reply.readBool();
414 sp<GraphicBuffer> buffer;
416 buffer = new GraphicBuffer();
417 result = reply.read(*buffer);
418 if (result == NO_ERROR) {
419 result = reply.read(outTransformMatrix, sizeof(float) * 16);
422 if (result != NO_ERROR) {
423 ALOGE("getLastQueuedBuffer failed to read buffer: %d", result);
426 sp<Fence> fence(new Fence);
427 result = reply.read(*fence);
428 if (result != NO_ERROR) {
429 ALOGE("getLastQueuedBuffer failed to read fence: %d", result);
437 virtual bool getFrameTimestamps(uint64_t frameNumber,
438 FrameTimestamps* outTimestamps) const {
440 status_t result = data.writeInterfaceToken(
441 IGraphicBufferProducer::getInterfaceDescriptor());
442 if (result != NO_ERROR) {
443 ALOGE("getFrameTimestamps failed to write token: %d", result);
446 result = data.writeUint64(frameNumber);
447 if (result != NO_ERROR) {
448 ALOGE("getFrameTimestamps failed to write: %d", result);
451 result = remote()->transact(GET_FRAME_TIMESTAMPS, data, &reply);
452 if (result != NO_ERROR) {
453 ALOGE("getFrameTimestamps failed to transact: %d", result);
457 result = reply.readBool(&found);
458 if (result != NO_ERROR) {
459 ALOGE("getFrameTimestamps failed to read: %d", result);
463 result = reply.read(*outTimestamps);
464 if (result != NO_ERROR) {
465 ALOGE("getFrameTimestamps failed to read timestamps: %d",
473 virtual status_t getUniqueId(uint64_t* outId) const {
475 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
476 status_t result = remote()->transact(GET_UNIQUE_ID, data, &reply);
477 if (result != NO_ERROR) {
478 ALOGE("getUniqueId failed to transact: %d", result);
480 status_t actualResult = NO_ERROR;
481 result = reply.readInt32(&actualResult);
482 if (result != NO_ERROR) {
485 result = reply.readUint64(outId);
486 if (result != NO_ERROR) {
493 // Out-of-line virtual method definition to trigger vtable emission in this
494 // translation unit (see clang warning -Wweak-vtables)
495 BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
497 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
499 // ----------------------------------------------------------------------
501 status_t BnGraphicBufferProducer::onTransact(
502 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
505 case REQUEST_BUFFER: {
506 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
507 int bufferIdx = data.readInt32();
508 sp<GraphicBuffer> buffer;
509 int result = requestBuffer(bufferIdx, &buffer);
510 reply->writeInt32(buffer != 0);
512 reply->write(*buffer);
514 reply->writeInt32(result);
517 case SET_MAX_DEQUEUED_BUFFER_COUNT: {
518 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
519 int maxDequeuedBuffers = data.readInt32();
520 int result = setMaxDequeuedBufferCount(maxDequeuedBuffers);
521 reply->writeInt32(result);
524 case SET_ASYNC_MODE: {
525 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
526 bool async = data.readInt32();
527 int result = setAsyncMode(async);
528 reply->writeInt32(result);
531 case DEQUEUE_BUFFER: {
532 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
533 uint32_t width = data.readUint32();
534 uint32_t height = data.readUint32();
535 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
536 uint32_t usage = data.readUint32();
539 int result = dequeueBuffer(&buf, &fence, width, height, format,
541 reply->writeInt32(buf);
542 reply->writeInt32(fence != NULL);
544 reply->write(*fence);
546 reply->writeInt32(result);
549 case DETACH_BUFFER: {
550 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
551 int slot = data.readInt32();
552 int result = detachBuffer(slot);
553 reply->writeInt32(result);
556 case DETACH_NEXT_BUFFER: {
557 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
558 sp<GraphicBuffer> buffer;
560 int32_t result = detachNextBuffer(&buffer, &fence);
561 reply->writeInt32(result);
562 if (result == NO_ERROR) {
563 reply->writeInt32(buffer != NULL);
564 if (buffer != NULL) {
565 reply->write(*buffer);
567 reply->writeInt32(fence != NULL);
569 reply->write(*fence);
574 case ATTACH_BUFFER: {
575 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
576 sp<GraphicBuffer> buffer = new GraphicBuffer();
577 status_t result = data.read(*buffer.get());
579 if (result == NO_ERROR) {
580 result = attachBuffer(&slot, buffer);
582 reply->writeInt32(slot);
583 reply->writeInt32(result);
587 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
588 int buf = data.readInt32();
589 QueueBufferInput input(data);
590 QueueBufferOutput* const output =
591 reinterpret_cast<QueueBufferOutput *>(
592 reply->writeInplace(sizeof(QueueBufferOutput)));
593 memset(output, 0, sizeof(QueueBufferOutput));
594 status_t result = queueBuffer(buf, input, output);
595 reply->writeInt32(result);
598 case CANCEL_BUFFER: {
599 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
600 int buf = data.readInt32();
601 sp<Fence> fence = new Fence();
602 status_t result = data.read(*fence.get());
603 if (result == NO_ERROR) {
604 result = cancelBuffer(buf, fence);
606 reply->writeInt32(result);
610 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
612 int what = data.readInt32();
613 int res = query(what, &value);
614 reply->writeInt32(value);
615 reply->writeInt32(res);
619 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
620 sp<IProducerListener> listener;
621 if (data.readInt32() == 1) {
622 listener = IProducerListener::asInterface(data.readStrongBinder());
624 int api = data.readInt32();
625 bool producerControlledByApp = data.readInt32();
626 QueueBufferOutput* const output =
627 reinterpret_cast<QueueBufferOutput *>(
628 reply->writeInplace(sizeof(QueueBufferOutput)));
629 memset(output, 0, sizeof(QueueBufferOutput));
630 status_t res = connect(listener, api, producerControlledByApp, output);
631 reply->writeInt32(res);
635 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
636 int api = data.readInt32();
637 status_t res = disconnect(api);
638 reply->writeInt32(res);
641 case SET_SIDEBAND_STREAM: {
642 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
643 sp<NativeHandle> stream;
644 if (data.readInt32()) {
645 stream = NativeHandle::create(data.readNativeHandle(), true);
647 status_t result = setSidebandStream(stream);
648 reply->writeInt32(result);
651 case ALLOCATE_BUFFERS: {
652 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
653 uint32_t width = data.readUint32();
654 uint32_t height = data.readUint32();
655 PixelFormat format = static_cast<PixelFormat>(data.readInt32());
656 uint32_t usage = data.readUint32();
657 allocateBuffers(width, height, format, usage);
660 case ALLOW_ALLOCATION: {
661 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
662 bool allow = static_cast<bool>(data.readInt32());
663 status_t result = allowAllocation(allow);
664 reply->writeInt32(result);
667 case SET_GENERATION_NUMBER: {
668 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
669 uint32_t generationNumber = data.readUint32();
670 status_t result = setGenerationNumber(generationNumber);
671 reply->writeInt32(result);
674 case GET_CONSUMER_NAME: {
675 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
676 reply->writeString8(getConsumerName());
679 case GET_NEXT_FRAME_NUMBER: {
680 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
681 uint64_t frameNumber = getNextFrameNumber();
682 reply->writeUint64(frameNumber);
685 case SET_SHARED_BUFFER_MODE: {
686 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
687 bool sharedBufferMode = data.readInt32();
688 status_t result = setSharedBufferMode(sharedBufferMode);
689 reply->writeInt32(result);
692 case SET_AUTO_REFRESH: {
693 CHECK_INTERFACE(IGraphicBuffer, data, reply);
694 bool autoRefresh = data.readInt32();
695 status_t result = setAutoRefresh(autoRefresh);
696 reply->writeInt32(result);
699 case SET_DEQUEUE_TIMEOUT: {
700 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
701 nsecs_t timeout = data.readInt64();
702 status_t result = setDequeueTimeout(timeout);
703 reply->writeInt32(result);
706 case GET_LAST_QUEUED_BUFFER: {
707 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
708 sp<GraphicBuffer> buffer(nullptr);
709 sp<Fence> fence(Fence::NO_FENCE);
710 float transform[16] = {};
711 status_t result = getLastQueuedBuffer(&buffer, &fence, transform);
712 reply->writeInt32(result);
713 if (result != NO_ERROR) {
717 reply->writeBool(false);
719 reply->writeBool(true);
720 result = reply->write(*buffer);
721 if (result == NO_ERROR) {
722 reply->write(transform, sizeof(float) * 16);
725 if (result != NO_ERROR) {
726 ALOGE("getLastQueuedBuffer failed to write buffer: %d", result);
729 result = reply->write(*fence);
730 if (result != NO_ERROR) {
731 ALOGE("getLastQueuedBuffer failed to write fence: %d", result);
736 case GET_FRAME_TIMESTAMPS: {
737 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
738 uint64_t frameNumber = 0;
739 status_t result = data.readUint64(&frameNumber);
740 if (result != NO_ERROR) {
741 ALOGE("onTransact failed to read: %d", result);
744 FrameTimestamps timestamps;
745 bool found = getFrameTimestamps(frameNumber, ×tamps);
746 result = reply->writeBool(found);
747 if (result != NO_ERROR) {
748 ALOGE("onTransact failed to write: %d", result);
752 result = reply->write(timestamps);
753 if (result != NO_ERROR) {
754 ALOGE("onTransact failed to write timestamps: %d", result);
760 case GET_UNIQUE_ID: {
761 CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
763 status_t actualResult = getUniqueId(&outId);
764 status_t result = reply->writeInt32(actualResult);
765 if (result != NO_ERROR) {
768 result = reply->writeUint64(outId);
769 if (result != NO_ERROR) {
775 return BBinder::onTransact(code, data, reply, flags);
778 // ----------------------------------------------------------------------------
780 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
784 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
785 return sizeof(timestamp)
786 + sizeof(isAutoTimestamp)
789 + sizeof(scalingMode)
791 + sizeof(stickyTransform)
792 + fence->getFlattenedSize()
793 + surfaceDamage.getFlattenedSize();
796 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
797 return fence->getFdCount();
800 status_t IGraphicBufferProducer::QueueBufferInput::flatten(
801 void*& buffer, size_t& size, int*& fds, size_t& count) const
803 if (size < getFlattenedSize()) {
806 FlattenableUtils::write(buffer, size, timestamp);
807 FlattenableUtils::write(buffer, size, isAutoTimestamp);
808 FlattenableUtils::write(buffer, size, dataSpace);
809 FlattenableUtils::write(buffer, size, crop);
810 FlattenableUtils::write(buffer, size, scalingMode);
811 FlattenableUtils::write(buffer, size, transform);
812 FlattenableUtils::write(buffer, size, stickyTransform);
813 status_t result = fence->flatten(buffer, size, fds, count);
814 if (result != NO_ERROR) {
817 return surfaceDamage.flatten(buffer, size);
820 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
821 void const*& buffer, size_t& size, int const*& fds, size_t& count)
825 + sizeof(isAutoTimestamp)
828 + sizeof(scalingMode)
830 + sizeof(stickyTransform);
832 if (size < minNeeded) {
836 FlattenableUtils::read(buffer, size, timestamp);
837 FlattenableUtils::read(buffer, size, isAutoTimestamp);
838 FlattenableUtils::read(buffer, size, dataSpace);
839 FlattenableUtils::read(buffer, size, crop);
840 FlattenableUtils::read(buffer, size, scalingMode);
841 FlattenableUtils::read(buffer, size, transform);
842 FlattenableUtils::read(buffer, size, stickyTransform);
845 status_t result = fence->unflatten(buffer, size, fds, count);
846 if (result != NO_ERROR) {
849 return surfaceDamage.unflatten(buffer, size);
852 }; // namespace android