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