IGraphicBufferConsumer.cpp revision 80640fca047bb5f4e792cd87138e24586a3a37c4
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#include <stdint.h>
18#include <sys/types.h>
19
20#include <utils/Errors.h>
21#include <utils/NativeHandle.h>
22
23#include <binder/Parcel.h>
24#include <binder/IInterface.h>
25
26#include <gui/BufferItem.h>
27#include <gui/IConsumerListener.h>
28#include <gui/IGraphicBufferConsumer.h>
29
30#include <ui/GraphicBuffer.h>
31#include <ui/Fence.h>
32
33#include <system/window.h>
34
35namespace android {
36
37enum {
38    ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
39    DETACH_BUFFER,
40    ATTACH_BUFFER,
41    RELEASE_BUFFER,
42    CONSUMER_CONNECT,
43    CONSUMER_DISCONNECT,
44    GET_RELEASED_BUFFERS,
45    SET_DEFAULT_BUFFER_SIZE,
46    SET_DEFAULT_MAX_BUFFER_COUNT,
47    DISABLE_ASYNC_BUFFER,
48    SET_MAX_ACQUIRED_BUFFER_COUNT,
49    SET_CONSUMER_NAME,
50    SET_DEFAULT_BUFFER_FORMAT,
51    SET_DEFAULT_BUFFER_DATA_SPACE,
52    SET_CONSUMER_USAGE_BITS,
53    SET_TRANSFORM_HINT,
54    GET_SIDEBAND_STREAM,
55    DUMP,
56};
57
58
59class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
60{
61public:
62    BpGraphicBufferConsumer(const sp<IBinder>& impl)
63        : BpInterface<IGraphicBufferConsumer>(impl)
64    {
65    }
66
67    virtual ~BpGraphicBufferConsumer();
68
69    virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
70        Parcel data, reply;
71        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
72        data.writeInt64(presentWhen);
73        status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
74        if (result != NO_ERROR) {
75            return result;
76        }
77        result = reply.read(*buffer);
78        if (result != NO_ERROR) {
79            return result;
80        }
81        return reply.readInt32();
82    }
83
84    virtual status_t detachBuffer(int slot) {
85        Parcel data, reply;
86        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
87        data.writeInt32(slot);
88        status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
89        if (result != NO_ERROR) {
90            return result;
91        }
92        result = reply.readInt32();
93        return result;
94    }
95
96    virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
97        Parcel data, reply;
98        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
99        data.write(*buffer.get());
100        status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
101        if (result != NO_ERROR) {
102            return result;
103        }
104        *slot = reply.readInt32();
105        result = reply.readInt32();
106        return result;
107    }
108
109    virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
110            EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
111            const sp<Fence>& releaseFence) {
112        Parcel data, reply;
113        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
114        data.writeInt32(buf);
115        data.writeInt64(static_cast<int64_t>(frameNumber));
116        data.write(*releaseFence);
117        status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
118        if (result != NO_ERROR) {
119            return result;
120        }
121        return reply.readInt32();
122    }
123
124    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
125        Parcel data, reply;
126        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
127        data.writeStrongBinder(IInterface::asBinder(consumer));
128        data.writeInt32(controlledByApp);
129        status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
130        if (result != NO_ERROR) {
131            return result;
132        }
133        return reply.readInt32();
134    }
135
136    virtual status_t consumerDisconnect() {
137        Parcel data, reply;
138        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
139        status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
140        if (result != NO_ERROR) {
141            return result;
142        }
143        return reply.readInt32();
144    }
145
146    virtual status_t getReleasedBuffers(uint64_t* slotMask) {
147        Parcel data, reply;
148        if (slotMask == NULL) {
149            ALOGE("getReleasedBuffers: slotMask must not be NULL");
150            return BAD_VALUE;
151        }
152        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
153        status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
154        if (result != NO_ERROR) {
155            return result;
156        }
157        *slotMask = static_cast<uint64_t>(reply.readInt64());
158        return reply.readInt32();
159    }
160
161    virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height) {
162        Parcel data, reply;
163        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
164        data.writeUint32(width);
165        data.writeUint32(height);
166        status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
167        if (result != NO_ERROR) {
168            return result;
169        }
170        return reply.readInt32();
171    }
172
173    virtual status_t setDefaultMaxBufferCount(int bufferCount) {
174        Parcel data, reply;
175        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
176        data.writeInt32(bufferCount);
177        status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
178        if (result != NO_ERROR) {
179            return result;
180        }
181        return reply.readInt32();
182    }
183
184    virtual status_t disableAsyncBuffer() {
185        Parcel data, reply;
186        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
187        status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
188        if (result != NO_ERROR) {
189            return result;
190        }
191        return reply.readInt32();
192    }
193
194    virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
195        Parcel data, reply;
196        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
197        data.writeInt32(maxAcquiredBuffers);
198        status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
199        if (result != NO_ERROR) {
200            return result;
201        }
202        return reply.readInt32();
203    }
204
205    virtual void setConsumerName(const String8& name) {
206        Parcel data, reply;
207        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
208        data.writeString8(name);
209        remote()->transact(SET_CONSUMER_NAME, data, &reply);
210    }
211
212    virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) {
213        Parcel data, reply;
214        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
215        data.writeInt32(static_cast<int32_t>(defaultFormat));
216        status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
217        if (result != NO_ERROR) {
218            return result;
219        }
220        return reply.readInt32();
221    }
222
223    virtual status_t setDefaultBufferDataSpace(
224            android_dataspace defaultDataSpace) {
225        Parcel data, reply;
226        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
227        data.writeInt32(static_cast<int32_t>(defaultDataSpace));
228        status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE,
229                data, &reply);
230        if (result != NO_ERROR) {
231            return result;
232        }
233        return reply.readInt32();
234    }
235
236    virtual status_t setConsumerUsageBits(uint32_t usage) {
237        Parcel data, reply;
238        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
239        data.writeUint32(usage);
240        status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
241        if (result != NO_ERROR) {
242            return result;
243        }
244        return reply.readInt32();
245    }
246
247    virtual status_t setTransformHint(uint32_t hint) {
248        Parcel data, reply;
249        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
250        data.writeUint32(hint);
251        status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
252        if (result != NO_ERROR) {
253            return result;
254        }
255        return reply.readInt32();
256    }
257
258    virtual sp<NativeHandle> getSidebandStream() const {
259        Parcel data, reply;
260        status_t err;
261        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
262        if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
263            return NULL;
264        }
265        sp<NativeHandle> stream;
266        if (reply.readInt32()) {
267            stream = NativeHandle::create(reply.readNativeHandle(), true);
268        }
269        return stream;
270    }
271
272    virtual void dump(String8& result, const char* prefix) const {
273        Parcel data, reply;
274        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
275        data.writeString8(result);
276        data.writeString8(String8(prefix ? prefix : ""));
277        remote()->transact(DUMP, data, &reply);
278        reply.readString8();
279    }
280};
281
282// Out-of-line virtual method definition to trigger vtable emission in this
283// translation unit (see clang warning -Wweak-vtables)
284BpGraphicBufferConsumer::~BpGraphicBufferConsumer() {}
285
286IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
287
288// ----------------------------------------------------------------------
289
290status_t BnGraphicBufferConsumer::onTransact(
291        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
292{
293    switch(code) {
294        case ACQUIRE_BUFFER: {
295            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
296            BufferItem item;
297            int64_t presentWhen = data.readInt64();
298            status_t result = acquireBuffer(&item, presentWhen);
299            status_t err = reply->write(item);
300            if (err) return err;
301            reply->writeInt32(result);
302            return NO_ERROR;
303        }
304        case DETACH_BUFFER: {
305            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
306            int slot = data.readInt32();
307            int result = detachBuffer(slot);
308            reply->writeInt32(result);
309            return NO_ERROR;
310        }
311        case ATTACH_BUFFER: {
312            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
313            sp<GraphicBuffer> buffer = new GraphicBuffer();
314            data.read(*buffer.get());
315            int slot;
316            int result = attachBuffer(&slot, buffer);
317            reply->writeInt32(slot);
318            reply->writeInt32(result);
319            return NO_ERROR;
320        }
321        case RELEASE_BUFFER: {
322            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
323            int buf = data.readInt32();
324            uint64_t frameNumber = static_cast<uint64_t>(data.readInt64());
325            sp<Fence> releaseFence = new Fence();
326            status_t err = data.read(*releaseFence);
327            if (err) return err;
328            status_t result = releaseBuffer(buf, frameNumber,
329                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
330            reply->writeInt32(result);
331            return NO_ERROR;
332        }
333        case CONSUMER_CONNECT: {
334            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
335            sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
336            bool controlledByApp = data.readInt32();
337            status_t result = consumerConnect(consumer, controlledByApp);
338            reply->writeInt32(result);
339            return NO_ERROR;
340        }
341        case CONSUMER_DISCONNECT: {
342            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
343            status_t result = consumerDisconnect();
344            reply->writeInt32(result);
345            return NO_ERROR;
346        }
347        case GET_RELEASED_BUFFERS: {
348            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
349            uint64_t slotMask;
350            status_t result = getReleasedBuffers(&slotMask);
351            reply->writeInt64(static_cast<int64_t>(slotMask));
352            reply->writeInt32(result);
353            return NO_ERROR;
354        }
355        case SET_DEFAULT_BUFFER_SIZE: {
356            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
357            uint32_t width = data.readUint32();
358            uint32_t height = data.readUint32();
359            status_t result = setDefaultBufferSize(width, height);
360            reply->writeInt32(result);
361            return NO_ERROR;
362        }
363        case SET_DEFAULT_MAX_BUFFER_COUNT: {
364            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
365            int bufferCount = data.readInt32();
366            status_t result = setDefaultMaxBufferCount(bufferCount);
367            reply->writeInt32(result);
368            return NO_ERROR;
369        }
370        case DISABLE_ASYNC_BUFFER: {
371            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
372            status_t result = disableAsyncBuffer();
373            reply->writeInt32(result);
374            return NO_ERROR;
375        }
376        case SET_MAX_ACQUIRED_BUFFER_COUNT: {
377            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
378            int maxAcquiredBuffers = data.readInt32();
379            status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
380            reply->writeInt32(result);
381            return NO_ERROR;
382        }
383        case SET_CONSUMER_NAME: {
384            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
385            setConsumerName( data.readString8() );
386            return NO_ERROR;
387        }
388        case SET_DEFAULT_BUFFER_FORMAT: {
389            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
390            PixelFormat defaultFormat = static_cast<PixelFormat>(data.readInt32());
391            status_t result = setDefaultBufferFormat(defaultFormat);
392            reply->writeInt32(result);
393            return NO_ERROR;
394        }
395        case SET_DEFAULT_BUFFER_DATA_SPACE: {
396            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
397            android_dataspace defaultDataSpace =
398                    static_cast<android_dataspace>(data.readInt32());
399            status_t result = setDefaultBufferDataSpace(defaultDataSpace);
400            reply->writeInt32(result);
401            return NO_ERROR;
402        }
403        case SET_CONSUMER_USAGE_BITS: {
404            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
405            uint32_t usage = data.readUint32();
406            status_t result = setConsumerUsageBits(usage);
407            reply->writeInt32(result);
408            return NO_ERROR;
409        }
410        case SET_TRANSFORM_HINT: {
411            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
412            uint32_t hint = data.readUint32();
413            status_t result = setTransformHint(hint);
414            reply->writeInt32(result);
415            return NO_ERROR;
416        }
417        case GET_SIDEBAND_STREAM: {
418            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
419            sp<NativeHandle> stream = getSidebandStream();
420            reply->writeInt32(static_cast<int32_t>(stream != NULL));
421            if (stream != NULL) {
422                reply->writeNativeHandle(stream->handle());
423            }
424            return NO_ERROR;
425        }
426        case DUMP: {
427            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
428            String8 result = data.readString8();
429            String8 prefix = data.readString8();
430            static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
431            reply->writeString8(result);
432            return NO_ERROR;
433        }
434    }
435    return BBinder::onTransact(code, data, reply, flags);
436}
437
438}; // namespace android
439