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