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