IGraphicBufferConsumer.cpp revision 399184a4cd728ea1421fb0bc1722274a29e38f4a
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        FlattenableUtils::align<4>(c);
75    }
76    if (mFence != 0) {
77        c += mFence->getFlattenedSize();
78        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
94status_t IGraphicBufferConsumer::BufferItem::flatten(
95        void*& buffer, size_t& size, int*& fds, size_t& count) const {
96
97    // make sure we have enough space
98    if (count < BufferItem::getFlattenedSize()) {
99        return NO_MEMORY;
100    }
101
102    // content flags are stored first
103    uint32_t& flags = *static_cast<uint32_t*>(buffer);
104
105    // advance the pointer
106    FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
107
108    flags = 0;
109    if (mGraphicBuffer != 0) {
110        status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
111        if (err) return err;
112        size -= FlattenableUtils::align<4>(buffer);
113        flags |= 1;
114    }
115    if (mFence != 0) {
116        status_t err = mFence->flatten(buffer, size, fds, count);
117        if (err) return err;
118        size -= FlattenableUtils::align<4>(buffer);
119        flags |= 2;
120    }
121
122    // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
123    if (size < getPodSize()) {
124        return NO_MEMORY;
125    }
126
127    FlattenableUtils::write(buffer, size, mCrop);
128    FlattenableUtils::write(buffer, size, mTransform);
129    FlattenableUtils::write(buffer, size, mScalingMode);
130    FlattenableUtils::write(buffer, size, mTimestamp);
131    FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
132    FlattenableUtils::write(buffer, size, mFrameNumber);
133    FlattenableUtils::write(buffer, size, mBuf);
134    FlattenableUtils::write(buffer, size, mIsDroppable);
135    FlattenableUtils::write(buffer, size, mAcquireCalled);
136    FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
137
138    return NO_ERROR;
139}
140
141status_t IGraphicBufferConsumer::BufferItem::unflatten(
142        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
143
144    if (size < sizeof(uint32_t))
145        return NO_MEMORY;
146
147    uint32_t flags = 0;
148    FlattenableUtils::read(buffer, size, flags);
149
150    if (flags & 1) {
151        mGraphicBuffer = new GraphicBuffer();
152        status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
153        if (err) return err;
154        size -= FlattenableUtils::align<4>(buffer);
155    }
156
157    if (flags & 2) {
158        mFence = new Fence();
159        status_t err = mFence->unflatten(buffer, size, fds, count);
160        if (err) return err;
161        size -= FlattenableUtils::align<4>(buffer);
162    }
163
164    // check we have enough space
165    if (size < getPodSize()) {
166        return NO_MEMORY;
167    }
168
169    FlattenableUtils::read(buffer, size, mCrop);
170    FlattenableUtils::read(buffer, size, mTransform);
171    FlattenableUtils::read(buffer, size, mScalingMode);
172    FlattenableUtils::read(buffer, size, mTimestamp);
173    FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
174    FlattenableUtils::read(buffer, size, mFrameNumber);
175    FlattenableUtils::read(buffer, size, mBuf);
176    FlattenableUtils::read(buffer, size, mIsDroppable);
177    FlattenableUtils::read(buffer, size, mAcquireCalled);
178    FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
179
180    return NO_ERROR;
181}
182
183// ---------------------------------------------------------------------------
184
185enum {
186    ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
187    RELEASE_BUFFER,
188    CONSUMER_CONNECT,
189    CONSUMER_DISCONNECT,
190    GET_RELEASED_BUFFERS,
191    SET_DEFAULT_BUFFER_SIZE,
192    SET_DEFAULT_MAX_BUFFER_COUNT,
193    DISABLE_ASYNC_BUFFER,
194    SET_MAX_ACQUIRED_BUFFER_COUNT,
195    SET_CONSUMER_NAME,
196    SET_DEFAULT_BUFFER_FORMAT,
197    SET_CONSUMER_USAGE_BITS,
198    SET_TRANSFORM_HINT,
199    GET_SIDEBAND_STREAM,
200    DUMP,
201};
202
203
204class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
205{
206public:
207    BpGraphicBufferConsumer(const sp<IBinder>& impl)
208        : BpInterface<IGraphicBufferConsumer>(impl)
209    {
210    }
211
212    virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
213        Parcel data, reply;
214        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
215        data.writeInt64(presentWhen);
216        status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
217        if (result != NO_ERROR) {
218            return result;
219        }
220        result = reply.read(*buffer);
221        if (result != NO_ERROR) {
222            return result;
223        }
224        return reply.readInt32();
225    }
226
227    virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
228            EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
229            const sp<Fence>& releaseFence) {
230        Parcel data, reply;
231        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
232        data.writeInt32(buf);
233        data.writeInt64(frameNumber);
234        data.write(*releaseFence);
235        status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
236        if (result != NO_ERROR) {
237            return result;
238        }
239        return reply.readInt32();
240    }
241
242    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
243        Parcel data, reply;
244        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
245        data.writeStrongBinder(consumer->asBinder());
246        data.writeInt32(controlledByApp);
247        status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
248        if (result != NO_ERROR) {
249            return result;
250        }
251        return reply.readInt32();
252    }
253
254    virtual status_t consumerDisconnect() {
255        Parcel data, reply;
256        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
257        status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
258        if (result != NO_ERROR) {
259            return result;
260        }
261        return reply.readInt32();
262    }
263
264    virtual status_t getReleasedBuffers(uint32_t* slotMask) {
265        Parcel data, reply;
266        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
267        status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
268        if (result != NO_ERROR) {
269            return result;
270        }
271        *slotMask = reply.readInt32();
272        return reply.readInt32();
273    }
274
275    virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) {
276        Parcel data, reply;
277        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
278        data.writeInt32(w);
279        data.writeInt32(h);
280        status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
281        if (result != NO_ERROR) {
282            return result;
283        }
284        return reply.readInt32();
285    }
286
287    virtual status_t setDefaultMaxBufferCount(int bufferCount) {
288        Parcel data, reply;
289        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
290        data.writeInt32(bufferCount);
291        status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
292        if (result != NO_ERROR) {
293            return result;
294        }
295        return reply.readInt32();
296    }
297
298    virtual status_t disableAsyncBuffer() {
299        Parcel data, reply;
300        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
301        status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
302        if (result != NO_ERROR) {
303            return result;
304        }
305        return reply.readInt32();
306    }
307
308    virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
309        Parcel data, reply;
310        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
311        data.writeInt32(maxAcquiredBuffers);
312        status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
313        if (result != NO_ERROR) {
314            return result;
315        }
316        return reply.readInt32();
317    }
318
319    virtual void setConsumerName(const String8& name) {
320        Parcel data, reply;
321        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
322        data.writeString8(name);
323        remote()->transact(SET_CONSUMER_NAME, data, &reply);
324    }
325
326    virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) {
327        Parcel data, reply;
328        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
329        data.writeInt32(defaultFormat);
330        status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
331        if (result != NO_ERROR) {
332            return result;
333        }
334        return reply.readInt32();
335    }
336
337    virtual status_t setConsumerUsageBits(uint32_t usage) {
338        Parcel data, reply;
339        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
340        data.writeInt32(usage);
341        status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
342        if (result != NO_ERROR) {
343            return result;
344        }
345        return reply.readInt32();
346    }
347
348    virtual status_t setTransformHint(uint32_t hint) {
349        Parcel data, reply;
350        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
351        data.writeInt32(hint);
352        status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
353        if (result != NO_ERROR) {
354            return result;
355        }
356        return reply.readInt32();
357    }
358
359    virtual sp<NativeHandle> getSidebandStream() const {
360        Parcel data, reply;
361        status_t err;
362        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
363        if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
364            return NULL;
365        }
366        sp<NativeHandle> stream;
367        if (reply.readInt32()) {
368            stream = NativeHandle::create(reply.readNativeHandle());
369        }
370        return stream;
371    }
372
373    virtual void dump(String8& result, const char* prefix) const {
374        Parcel data, reply;
375        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
376        data.writeString8(result);
377        data.writeString8(String8(prefix ? prefix : ""));
378        remote()->transact(DUMP, data, &reply);
379        reply.readString8();
380    }
381};
382
383IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
384
385// ----------------------------------------------------------------------
386
387status_t BnGraphicBufferConsumer::onTransact(
388        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
389{
390    switch(code) {
391        case ACQUIRE_BUFFER: {
392            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
393            BufferItem item;
394            int64_t presentWhen = data.readInt64();
395            status_t result = acquireBuffer(&item, presentWhen);
396            status_t err = reply->write(item);
397            if (err) return err;
398            reply->writeInt32(result);
399            return NO_ERROR;
400        } break;
401        case RELEASE_BUFFER: {
402            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
403            int buf = data.readInt32();
404            uint64_t frameNumber = data.readInt64();
405            sp<Fence> releaseFence = new Fence();
406            status_t err = data.read(*releaseFence);
407            if (err) return err;
408            status_t result = releaseBuffer(buf, frameNumber,
409                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
410            reply->writeInt32(result);
411            return NO_ERROR;
412        } break;
413        case CONSUMER_CONNECT: {
414            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
415            sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
416            bool controlledByApp = data.readInt32();
417            status_t result = consumerConnect(consumer, controlledByApp);
418            reply->writeInt32(result);
419            return NO_ERROR;
420        } break;
421        case CONSUMER_DISCONNECT: {
422            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
423            status_t result = consumerDisconnect();
424            reply->writeInt32(result);
425            return NO_ERROR;
426        } break;
427        case GET_RELEASED_BUFFERS: {
428            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
429            uint32_t slotMask;
430            status_t result = getReleasedBuffers(&slotMask);
431            reply->writeInt32(slotMask);
432            reply->writeInt32(result);
433            return NO_ERROR;
434        } break;
435        case SET_DEFAULT_BUFFER_SIZE: {
436            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
437            uint32_t w = data.readInt32();
438            uint32_t h = data.readInt32();
439            status_t result = setDefaultBufferSize(w, h);
440            reply->writeInt32(result);
441            return NO_ERROR;
442        } break;
443        case SET_DEFAULT_MAX_BUFFER_COUNT: {
444            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
445            uint32_t bufferCount = data.readInt32();
446            status_t result = setDefaultMaxBufferCount(bufferCount);
447            reply->writeInt32(result);
448            return NO_ERROR;
449        } break;
450        case DISABLE_ASYNC_BUFFER: {
451            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
452            status_t result = disableAsyncBuffer();
453            reply->writeInt32(result);
454            return NO_ERROR;
455        } break;
456        case SET_MAX_ACQUIRED_BUFFER_COUNT: {
457            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
458            uint32_t maxAcquiredBuffers = data.readInt32();
459            status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
460            reply->writeInt32(result);
461            return NO_ERROR;
462        } break;
463        case SET_CONSUMER_NAME: {
464            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
465            setConsumerName( data.readString8() );
466            return NO_ERROR;
467        } break;
468        case SET_DEFAULT_BUFFER_FORMAT: {
469            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
470            uint32_t defaultFormat = data.readInt32();
471            status_t result = setDefaultBufferFormat(defaultFormat);
472            reply->writeInt32(result);
473            return NO_ERROR;
474        } break;
475        case SET_CONSUMER_USAGE_BITS: {
476            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
477            uint32_t usage = data.readInt32();
478            status_t result = setConsumerUsageBits(usage);
479            reply->writeInt32(result);
480            return NO_ERROR;
481        } break;
482        case SET_TRANSFORM_HINT: {
483            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
484            uint32_t hint = data.readInt32();
485            status_t result = setTransformHint(hint);
486            reply->writeInt32(result);
487            return NO_ERROR;
488        } break;
489        case DUMP: {
490            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
491            String8 result = data.readString8();
492            String8 prefix = data.readString8();
493            static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
494            reply->writeString8(result);
495            return NO_ERROR;
496        }
497    }
498    return BBinder::onTransact(code, data, reply, flags);
499}
500
501}; // namespace android
502