IGraphicBufferConsumer.cpp revision febd4f4f462444bfcb3f0618d07ac77e3fc1f6ad
1/*
2 * Copyright (C) 2013 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#define EGL_EGLEXT_PROTOTYPES
18
19#include <EGL/egl.h>
20#include <EGL/eglext.h>
21
22
23#include <stdint.h>
24#include <sys/types.h>
25
26#include <utils/Errors.h>
27#include <utils/NativeHandle.h>
28
29#include <binder/Parcel.h>
30#include <binder/IInterface.h>
31
32#include <gui/IConsumerListener.h>
33#include <gui/IGraphicBufferConsumer.h>
34
35#include <ui/GraphicBuffer.h>
36#include <ui/Fence.h>
37
38#include <system/window.h>
39
40namespace android {
41// ---------------------------------------------------------------------------
42
43IGraphicBufferConsumer::BufferItem::BufferItem() :
44    mTransform(0),
45    mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
46    mTimestamp(0),
47    mIsAutoTimestamp(false),
48    mFrameNumber(0),
49    mBuf(INVALID_BUFFER_SLOT),
50    mIsDroppable(false),
51    mAcquireCalled(false),
52    mTransformToDisplayInverse(false) {
53    mCrop.makeInvalid();
54}
55
56size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
57    size_t c =  sizeof(mCrop) +
58            sizeof(mTransform) +
59            sizeof(mScalingMode) +
60            sizeof(mTimestamp) +
61            sizeof(mIsAutoTimestamp) +
62            sizeof(mFrameNumber) +
63            sizeof(mBuf) +
64            sizeof(mIsDroppable) +
65            sizeof(mAcquireCalled) +
66            sizeof(mTransformToDisplayInverse);
67    return c;
68}
69
70size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
71    size_t c = 0;
72    if (mGraphicBuffer != 0) {
73        c += mGraphicBuffer->getFlattenedSize();
74        c = FlattenableUtils::align<4>(c);
75    }
76    if (mFence != 0) {
77        c += mFence->getFlattenedSize();
78        c = FlattenableUtils::align<4>(c);
79    }
80    return sizeof(int32_t) + c + getPodSize();
81}
82
83size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
84    size_t c = 0;
85    if (mGraphicBuffer != 0) {
86        c += mGraphicBuffer->getFdCount();
87    }
88    if (mFence != 0) {
89        c += mFence->getFdCount();
90    }
91    return c;
92}
93
94static void writeBoolAsInt(void*& buffer, size_t& size, bool b) {
95    FlattenableUtils::write(buffer, size, static_cast<int32_t>(b));
96}
97
98static bool readBoolFromInt(void const*& buffer, size_t& size) {
99    int32_t i;
100    FlattenableUtils::read(buffer, size, i);
101    return static_cast<bool>(i);
102}
103
104status_t IGraphicBufferConsumer::BufferItem::flatten(
105        void*& buffer, size_t& size, int*& fds, size_t& count) const {
106
107    // make sure we have enough space
108    if (size < BufferItem::getFlattenedSize()) {
109        return NO_MEMORY;
110    }
111
112    // content flags are stored first
113    uint32_t& flags = *static_cast<uint32_t*>(buffer);
114
115    // advance the pointer
116    FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
117
118    flags = 0;
119    if (mGraphicBuffer != 0) {
120        status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
121        if (err) return err;
122        size -= FlattenableUtils::align<4>(buffer);
123        flags |= 1;
124    }
125    if (mFence != 0) {
126        status_t err = mFence->flatten(buffer, size, fds, count);
127        if (err) return err;
128        size -= FlattenableUtils::align<4>(buffer);
129        flags |= 2;
130    }
131
132    // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
133    if (size < getPodSize()) {
134        return NO_MEMORY;
135    }
136
137    FlattenableUtils::write(buffer, size, mCrop);
138    FlattenableUtils::write(buffer, size, mTransform);
139    FlattenableUtils::write(buffer, size, mScalingMode);
140    FlattenableUtils::write(buffer, size, mTimestamp);
141    writeBoolAsInt(buffer, size, mIsAutoTimestamp);
142    FlattenableUtils::write(buffer, size, mFrameNumber);
143    FlattenableUtils::write(buffer, size, mBuf);
144    writeBoolAsInt(buffer, size, mIsDroppable);
145    writeBoolAsInt(buffer, size, mAcquireCalled);
146    writeBoolAsInt(buffer, size, mTransformToDisplayInverse);
147
148    return NO_ERROR;
149}
150
151status_t IGraphicBufferConsumer::BufferItem::unflatten(
152        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
153
154    if (size < sizeof(uint32_t))
155        return NO_MEMORY;
156
157    uint32_t flags = 0;
158    FlattenableUtils::read(buffer, size, flags);
159
160    if (flags & 1) {
161        mGraphicBuffer = new GraphicBuffer();
162        status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
163        if (err) return err;
164        size -= FlattenableUtils::align<4>(buffer);
165    }
166
167    if (flags & 2) {
168        mFence = new Fence();
169        status_t err = mFence->unflatten(buffer, size, fds, count);
170        if (err) return err;
171        size -= FlattenableUtils::align<4>(buffer);
172    }
173
174    // check we have enough space
175    if (size < getPodSize()) {
176        return NO_MEMORY;
177    }
178
179    FlattenableUtils::read(buffer, size, mCrop);
180    FlattenableUtils::read(buffer, size, mTransform);
181    FlattenableUtils::read(buffer, size, mScalingMode);
182    FlattenableUtils::read(buffer, size, mTimestamp);
183    mIsAutoTimestamp = readBoolFromInt(buffer, size);
184    FlattenableUtils::read(buffer, size, mFrameNumber);
185    FlattenableUtils::read(buffer, size, mBuf);
186    mIsDroppable = readBoolFromInt(buffer, size);
187    mAcquireCalled = readBoolFromInt(buffer, size);
188    mTransformToDisplayInverse = readBoolFromInt(buffer, size);
189
190    return NO_ERROR;
191}
192
193// ---------------------------------------------------------------------------
194
195enum {
196    ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
197    DETACH_BUFFER,
198    ATTACH_BUFFER,
199    RELEASE_BUFFER,
200    CONSUMER_CONNECT,
201    CONSUMER_DISCONNECT,
202    GET_RELEASED_BUFFERS,
203    SET_DEFAULT_BUFFER_SIZE,
204    SET_DEFAULT_MAX_BUFFER_COUNT,
205    DISABLE_ASYNC_BUFFER,
206    SET_MAX_ACQUIRED_BUFFER_COUNT,
207    SET_CONSUMER_NAME,
208    SET_DEFAULT_BUFFER_FORMAT,
209    SET_CONSUMER_USAGE_BITS,
210    SET_TRANSFORM_HINT,
211    GET_SIDEBAND_STREAM,
212    DUMP,
213};
214
215
216class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
217{
218public:
219    BpGraphicBufferConsumer(const sp<IBinder>& impl)
220        : BpInterface<IGraphicBufferConsumer>(impl)
221    {
222    }
223
224    virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
225        Parcel data, reply;
226        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
227        data.writeInt64(presentWhen);
228        status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
229        if (result != NO_ERROR) {
230            return result;
231        }
232        result = reply.read(*buffer);
233        if (result != NO_ERROR) {
234            return result;
235        }
236        return reply.readInt32();
237    }
238
239    virtual status_t detachBuffer(int slot) {
240        Parcel data, reply;
241        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
242        data.writeInt32(slot);
243        status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
244        if (result != NO_ERROR) {
245            return result;
246        }
247        result = reply.readInt32();
248        return result;
249    }
250
251    virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
252        Parcel data, reply;
253        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
254        data.write(*buffer.get());
255        status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
256        if (result != NO_ERROR) {
257            return result;
258        }
259        *slot = reply.readInt32();
260        result = reply.readInt32();
261        return result;
262    }
263
264    virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
265            EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
266            const sp<Fence>& releaseFence) {
267        Parcel data, reply;
268        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
269        data.writeInt32(buf);
270        data.writeInt64(frameNumber);
271        data.write(*releaseFence);
272        status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
273        if (result != NO_ERROR) {
274            return result;
275        }
276        return reply.readInt32();
277    }
278
279    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
280        Parcel data, reply;
281        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
282        data.writeStrongBinder(consumer->asBinder());
283        data.writeInt32(controlledByApp);
284        status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
285        if (result != NO_ERROR) {
286            return result;
287        }
288        return reply.readInt32();
289    }
290
291    virtual status_t consumerDisconnect() {
292        Parcel data, reply;
293        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
294        status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
295        if (result != NO_ERROR) {
296            return result;
297        }
298        return reply.readInt32();
299    }
300
301    virtual status_t getReleasedBuffers(uint64_t* slotMask) {
302        Parcel data, reply;
303        if (slotMask == NULL) {
304            ALOGE("getReleasedBuffers: slotMask must not be NULL");
305            return BAD_VALUE;
306        }
307        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
308        status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
309        if (result != NO_ERROR) {
310            return result;
311        }
312        *slotMask = reply.readInt64();
313        return reply.readInt32();
314    }
315
316    virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) {
317        Parcel data, reply;
318        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
319        data.writeInt32(w);
320        data.writeInt32(h);
321        status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
322        if (result != NO_ERROR) {
323            return result;
324        }
325        return reply.readInt32();
326    }
327
328    virtual status_t setDefaultMaxBufferCount(int bufferCount) {
329        Parcel data, reply;
330        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
331        data.writeInt32(bufferCount);
332        status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
333        if (result != NO_ERROR) {
334            return result;
335        }
336        return reply.readInt32();
337    }
338
339    virtual status_t disableAsyncBuffer() {
340        Parcel data, reply;
341        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
342        status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
343        if (result != NO_ERROR) {
344            return result;
345        }
346        return reply.readInt32();
347    }
348
349    virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
350        Parcel data, reply;
351        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
352        data.writeInt32(maxAcquiredBuffers);
353        status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
354        if (result != NO_ERROR) {
355            return result;
356        }
357        return reply.readInt32();
358    }
359
360    virtual void setConsumerName(const String8& name) {
361        Parcel data, reply;
362        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
363        data.writeString8(name);
364        remote()->transact(SET_CONSUMER_NAME, data, &reply);
365    }
366
367    virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) {
368        Parcel data, reply;
369        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
370        data.writeInt32(defaultFormat);
371        status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
372        if (result != NO_ERROR) {
373            return result;
374        }
375        return reply.readInt32();
376    }
377
378    virtual status_t setConsumerUsageBits(uint32_t usage) {
379        Parcel data, reply;
380        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
381        data.writeInt32(usage);
382        status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
383        if (result != NO_ERROR) {
384            return result;
385        }
386        return reply.readInt32();
387    }
388
389    virtual status_t setTransformHint(uint32_t hint) {
390        Parcel data, reply;
391        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
392        data.writeInt32(hint);
393        status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
394        if (result != NO_ERROR) {
395            return result;
396        }
397        return reply.readInt32();
398    }
399
400    virtual sp<NativeHandle> getSidebandStream() const {
401        Parcel data, reply;
402        status_t err;
403        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
404        if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
405            return NULL;
406        }
407        sp<NativeHandle> stream;
408        if (reply.readInt32()) {
409            stream = NativeHandle::create(reply.readNativeHandle(), true);
410        }
411        return stream;
412    }
413
414    virtual void dump(String8& result, const char* prefix) const {
415        Parcel data, reply;
416        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
417        data.writeString8(result);
418        data.writeString8(String8(prefix ? prefix : ""));
419        remote()->transact(DUMP, data, &reply);
420        reply.readString8();
421    }
422};
423
424IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
425
426// ----------------------------------------------------------------------
427
428status_t BnGraphicBufferConsumer::onTransact(
429        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
430{
431    switch(code) {
432        case ACQUIRE_BUFFER: {
433            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
434            BufferItem item;
435            int64_t presentWhen = data.readInt64();
436            status_t result = acquireBuffer(&item, presentWhen);
437            status_t err = reply->write(item);
438            if (err) return err;
439            reply->writeInt32(result);
440            return NO_ERROR;
441        } break;
442        case DETACH_BUFFER: {
443            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
444            int slot = data.readInt32();
445            int result = detachBuffer(slot);
446            reply->writeInt32(result);
447            return NO_ERROR;
448        } break;
449        case ATTACH_BUFFER: {
450            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
451            sp<GraphicBuffer> buffer = new GraphicBuffer();
452            data.read(*buffer.get());
453            int slot;
454            int result = attachBuffer(&slot, buffer);
455            reply->writeInt32(slot);
456            reply->writeInt32(result);
457            return NO_ERROR;
458        } break;
459        case RELEASE_BUFFER: {
460            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
461            int buf = data.readInt32();
462            uint64_t frameNumber = data.readInt64();
463            sp<Fence> releaseFence = new Fence();
464            status_t err = data.read(*releaseFence);
465            if (err) return err;
466            status_t result = releaseBuffer(buf, frameNumber,
467                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
468            reply->writeInt32(result);
469            return NO_ERROR;
470        } break;
471        case CONSUMER_CONNECT: {
472            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
473            sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
474            bool controlledByApp = data.readInt32();
475            status_t result = consumerConnect(consumer, controlledByApp);
476            reply->writeInt32(result);
477            return NO_ERROR;
478        } break;
479        case CONSUMER_DISCONNECT: {
480            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
481            status_t result = consumerDisconnect();
482            reply->writeInt32(result);
483            return NO_ERROR;
484        } break;
485        case GET_RELEASED_BUFFERS: {
486            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
487            uint64_t slotMask;
488            status_t result = getReleasedBuffers(&slotMask);
489            reply->writeInt64(slotMask);
490            reply->writeInt32(result);
491            return NO_ERROR;
492        } break;
493        case SET_DEFAULT_BUFFER_SIZE: {
494            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
495            uint32_t w = data.readInt32();
496            uint32_t h = data.readInt32();
497            status_t result = setDefaultBufferSize(w, h);
498            reply->writeInt32(result);
499            return NO_ERROR;
500        } break;
501        case SET_DEFAULT_MAX_BUFFER_COUNT: {
502            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
503            uint32_t bufferCount = data.readInt32();
504            status_t result = setDefaultMaxBufferCount(bufferCount);
505            reply->writeInt32(result);
506            return NO_ERROR;
507        } break;
508        case DISABLE_ASYNC_BUFFER: {
509            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
510            status_t result = disableAsyncBuffer();
511            reply->writeInt32(result);
512            return NO_ERROR;
513        } break;
514        case SET_MAX_ACQUIRED_BUFFER_COUNT: {
515            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
516            uint32_t maxAcquiredBuffers = data.readInt32();
517            status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
518            reply->writeInt32(result);
519            return NO_ERROR;
520        } break;
521        case SET_CONSUMER_NAME: {
522            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
523            setConsumerName( data.readString8() );
524            return NO_ERROR;
525        } break;
526        case SET_DEFAULT_BUFFER_FORMAT: {
527            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
528            uint32_t defaultFormat = data.readInt32();
529            status_t result = setDefaultBufferFormat(defaultFormat);
530            reply->writeInt32(result);
531            return NO_ERROR;
532        } break;
533        case SET_CONSUMER_USAGE_BITS: {
534            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
535            uint32_t usage = data.readInt32();
536            status_t result = setConsumerUsageBits(usage);
537            reply->writeInt32(result);
538            return NO_ERROR;
539        } break;
540        case SET_TRANSFORM_HINT: {
541            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
542            uint32_t hint = data.readInt32();
543            status_t result = setTransformHint(hint);
544            reply->writeInt32(result);
545            return NO_ERROR;
546        } break;
547        case DUMP: {
548            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
549            String8 result = data.readString8();
550            String8 prefix = data.readString8();
551            static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
552            reply->writeString8(result);
553            return NO_ERROR;
554        }
555    }
556    return BBinder::onTransact(code, data, reply, flags);
557}
558
559}; // namespace android
560