blob: 4db635ca1225b8ec9912b16b1e8a501b460e8dcc [file] [log] [blame]
Mathias Agopiana4e19522013-07-31 20:09:53 -07001/*
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),
Andy McFadden3c256212013-08-16 14:55:39 -070046 mIsAutoTimestamp(false),
Mathias Agopiana4e19522013-07-31 20:09:53 -070047 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) +
Andy McFadden3c256212013-08-16 14:55:39 -070059 sizeof(mIsAutoTimestamp) +
Mathias Agopiana4e19522013-07-31 20:09:53 -070060 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);
Andy McFadden3c256212013-08-16 14:55:39 -0700128 FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700129 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);
Andy McFadden3c256212013-08-16 14:55:39 -0700169 FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700170 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,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700193 SET_TRANSFORM_HINT,
194 DUMP,
Mathias Agopiana4e19522013-07-31 20:09:53 -0700195};
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 }
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700352
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 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700361};
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;
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700469 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 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700477 }
478 return BBinder::onTransact(code, data, reply, flags);
479}
480
481}; // namespace android