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