OSDN Git Service

Merge "Don\'t flatten nullptrs" into nyc-dev
[android-x86/frameworks-native.git] / libs / gui / IGraphicBufferProducer.cpp
1 /*
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>
21 #include <utils/NativeHandle.h>
22 #include <utils/RefBase.h>
23 #include <utils/Timers.h>
24 #include <utils/Vector.h>
25
26 #include <binder/Parcel.h>
27 #include <binder/IInterface.h>
28
29 #include <gui/IGraphicBufferProducer.h>
30 #include <gui/IProducerListener.h>
31
32 namespace android {
33 // ----------------------------------------------------------------------------
34
35 enum {
36     REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
37     DEQUEUE_BUFFER,
38     DETACH_BUFFER,
39     DETACH_NEXT_BUFFER,
40     ATTACH_BUFFER,
41     QUEUE_BUFFER,
42     CANCEL_BUFFER,
43     QUERY,
44     CONNECT,
45     DISCONNECT,
46     SET_SIDEBAND_STREAM,
47     ALLOCATE_BUFFERS,
48     ALLOW_ALLOCATION,
49     SET_GENERATION_NUMBER,
50     GET_CONSUMER_NAME,
51     SET_MAX_DEQUEUED_BUFFER_COUNT,
52     SET_ASYNC_MODE,
53     GET_NEXT_FRAME_NUMBER,
54     SET_SHARED_BUFFER_MODE,
55     SET_AUTO_REFRESH,
56     SET_DEQUEUE_TIMEOUT,
57     GET_LAST_QUEUED_BUFFER,
58 };
59
60 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
61 {
62 public:
63     BpGraphicBufferProducer(const sp<IBinder>& impl)
64         : BpInterface<IGraphicBufferProducer>(impl)
65     {
66     }
67
68     virtual ~BpGraphicBufferProducer();
69
70     virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
71         Parcel data, reply;
72         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
73         data.writeInt32(bufferIdx);
74         status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
75         if (result != NO_ERROR) {
76             return result;
77         }
78         bool nonNull = reply.readInt32();
79         if (nonNull) {
80             *buf = new GraphicBuffer();
81             result = reply.read(**buf);
82             if(result != NO_ERROR) {
83                 (*buf).clear();
84                 return result;
85             }
86         }
87         result = reply.readInt32();
88         return result;
89     }
90
91     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
119     virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, uint32_t width,
120             uint32_t height, PixelFormat format, uint32_t usage) {
121         Parcel data, reply;
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) {
129             return result;
130         }
131         *buf = reply.readInt32();
132         bool nonNull = reply.readInt32();
133         if (nonNull) {
134             *fence = new Fence();
135             reply.read(**fence);
136         }
137         result = reply.readInt32();
138         return result;
139     }
140
141     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
153     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
184     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
197     virtual status_t queueBuffer(int buf,
198             const QueueBufferInput& input, QueueBufferOutput* output) {
199         Parcel data, reply;
200         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
201         data.writeInt32(buf);
202         data.write(input);
203         status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
204         if (result != NO_ERROR) {
205             return result;
206         }
207         memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
208         result = reply.readInt32();
209         return result;
210     }
211
212     virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) {
213         Parcel data, reply;
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) {
219             return result;
220         }
221         result = reply.readInt32();
222         return result;
223     }
224
225     virtual int query(int what, int* value) {
226         Parcel data, reply;
227         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
228         data.writeInt32(what);
229         status_t result = remote()->transact(QUERY, data, &reply);
230         if (result != NO_ERROR) {
231             return result;
232         }
233         value[0] = reply.readInt32();
234         result = reply.readInt32();
235         return result;
236     }
237
238     virtual status_t connect(const sp<IProducerListener>& listener,
239             int api, bool producerControlledByApp, QueueBufferOutput* output) {
240         Parcel data, reply;
241         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
242         if (listener != NULL) {
243             data.writeInt32(1);
244             data.writeStrongBinder(IInterface::asBinder(listener));
245         } else {
246             data.writeInt32(0);
247         }
248         data.writeInt32(api);
249         data.writeInt32(producerControlledByApp);
250         status_t result = remote()->transact(CONNECT, data, &reply);
251         if (result != NO_ERROR) {
252             return result;
253         }
254         memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
255         result = reply.readInt32();
256         return result;
257     }
258
259     virtual status_t disconnect(int api) {
260         Parcel data, reply;
261         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
262         data.writeInt32(api);
263         status_t result =remote()->transact(DISCONNECT, data, &reply);
264         if (result != NO_ERROR) {
265             return result;
266         }
267         result = reply.readInt32();
268         return result;
269     }
270
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     }
286
287     virtual void allocateBuffers(uint32_t width, uint32_t height,
288             PixelFormat format, uint32_t usage) {
289         Parcel data, reply;
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);
298         }
299     }
300
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     }
312
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     }
323
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     }
334
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     }
346
347     virtual status_t setSharedBufferMode(bool sharedBufferMode) {
348         Parcel data, reply;
349         data.writeInterfaceToken(
350                 IGraphicBufferProducer::getInterfaceDescriptor());
351         data.writeInt32(sharedBufferMode);
352         status_t result = remote()->transact(SET_SHARED_BUFFER_MODE, data,
353                 &reply);
354         if (result == NO_ERROR) {
355             result = reply.readInt32();
356         }
357         return result;
358     }
359
360     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
372     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     }
383
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         }
398         bool hasBuffer = reply.readBool();
399         sp<GraphicBuffer> buffer;
400         if (hasBuffer) {
401             buffer = new GraphicBuffer();
402             result = reply.read(*buffer);
403         }
404         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     }
418 };
419
420 // Out-of-line virtual method definition to trigger vtable emission in this
421 // translation unit (see clang warning -Wweak-vtables)
422 BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
423
424 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
425
426 // ----------------------------------------------------------------------
427
428 status_t BnGraphicBufferProducer::onTransact(
429     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
430 {
431     switch(code) {
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);
438             if (buffer != 0) {
439                 reply->write(*buffer);
440             }
441             reply->writeInt32(result);
442             return NO_ERROR;
443         }
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);
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         }
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();
464             int buf = 0;
465             sp<Fence> fence;
466             int result = dequeueBuffer(&buf, &fence, width, height, format,
467                     usage);
468             reply->writeInt32(buf);
469             reply->writeInt32(fence != NULL);
470             if (fence != NULL) {
471                 reply->write(*fence);
472             }
473             reply->writeInt32(result);
474             return NO_ERROR;
475         }
476         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;
482         }
483         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;
500         }
501         case ATTACH_BUFFER: {
502             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
503             sp<GraphicBuffer> buffer = new GraphicBuffer();
504             data.read(*buffer.get());
505             int slot = 0;
506             int result = attachBuffer(&slot, buffer);
507             reply->writeInt32(slot);
508             reply->writeInt32(result);
509             return NO_ERROR;
510         }
511         case QUEUE_BUFFER: {
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);
521             return NO_ERROR;
522         }
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);
530             return NO_ERROR;
531         }
532         case QUERY: {
533             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
534             int value = 0;
535             int what = data.readInt32();
536             int res = query(what, &value);
537             reply->writeInt32(value);
538             reply->writeInt32(res);
539             return NO_ERROR;
540         }
541         case CONNECT: {
542             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
543             sp<IProducerListener> listener;
544             if (data.readInt32() == 1) {
545                 listener = IProducerListener::asInterface(data.readStrongBinder());
546             }
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);
555             return NO_ERROR;
556         }
557         case DISCONNECT: {
558             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
559             int api = data.readInt32();
560             status_t res = disconnect(api);
561             reply->writeInt32(res);
562             return NO_ERROR;
563         }
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);
569             }
570             status_t result = setSidebandStream(stream);
571             reply->writeInt32(result);
572             return NO_ERROR;
573         }
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);
581             return NO_ERROR;
582         }
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         }
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);
595             return NO_ERROR;
596         }
597         case GET_CONSUMER_NAME: {
598             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
599             reply->writeString8(getConsumerName());
600             return NO_ERROR;
601         }
602         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         }
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);
613             return NO_ERROR;
614         }
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);
620             return NO_ERROR;
621         }
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);
627             return NO_ERROR;
628         }
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) {
636                 return result;
637             }
638             if (!buffer.get()) {
639                 reply->writeBool(false);
640             } else {
641                 reply->writeBool(true);
642                 result = reply->write(*buffer);
643             }
644             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         }
655     }
656     return BBinder::onTransact(code, data, reply, flags);
657 }
658
659 // ----------------------------------------------------------------------------
660
661 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
662     parcel.read(*this);
663 }
664
665 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
666     return sizeof(timestamp)
667          + sizeof(isAutoTimestamp)
668          + sizeof(dataSpace)
669          + sizeof(crop)
670          + sizeof(scalingMode)
671          + sizeof(transform)
672          + sizeof(stickyTransform)
673          + fence->getFlattenedSize()
674          + surfaceDamage.getFlattenedSize();
675 }
676
677 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
678     return fence->getFdCount();
679 }
680
681 status_t IGraphicBufferProducer::QueueBufferInput::flatten(
682         void*& buffer, size_t& size, int*& fds, size_t& count) const
683 {
684     if (size < getFlattenedSize()) {
685         return NO_MEMORY;
686     }
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) {
696         return result;
697     }
698     return surfaceDamage.flatten(buffer, size);
699 }
700
701 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
702         void const*& buffer, size_t& size, int const*& fds, size_t& count)
703 {
704     size_t minNeeded =
705               sizeof(timestamp)
706             + sizeof(isAutoTimestamp)
707             + sizeof(dataSpace)
708             + sizeof(crop)
709             + sizeof(scalingMode)
710             + sizeof(transform)
711             + sizeof(stickyTransform);
712
713     if (size < minNeeded) {
714         return NO_MEMORY;
715     }
716
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);
724
725     fence = new Fence();
726     status_t result = fence->unflatten(buffer, size, fds, count);
727     if (result != NO_ERROR) {
728         return result;
729     }
730     return surfaceDamage.unflatten(buffer, size);
731 }
732
733 }; // namespace android