blob: 8d6438008c05fec73b58d94aaaa4de696fd1cc34 [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),
Mathias Agopianc1c05de2013-09-17 23:45:22 -070050 mAcquireCalled(false),
51 mTransformToDisplayInverse(false) {
Mathias Agopiana4e19522013-07-31 20:09:53 -070052 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) +
Andy McFadden3c256212013-08-16 14:55:39 -070060 sizeof(mIsAutoTimestamp) +
Mathias Agopiana4e19522013-07-31 20:09:53 -070061 sizeof(mFrameNumber) +
62 sizeof(mBuf) +
63 sizeof(mIsDroppable) +
Mathias Agopianc1c05de2013-09-17 23:45:22 -070064 sizeof(mAcquireCalled) +
65 sizeof(mTransformToDisplayInverse);
Mathias Agopiana4e19522013-07-31 20:09:53 -070066 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);
Andy McFadden3c256212013-08-16 14:55:39 -0700130 FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700131 FlattenableUtils::write(buffer, size, mFrameNumber);
132 FlattenableUtils::write(buffer, size, mBuf);
133 FlattenableUtils::write(buffer, size, mIsDroppable);
134 FlattenableUtils::write(buffer, size, mAcquireCalled);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700135 FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700136
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);
Andy McFadden3c256212013-08-16 14:55:39 -0700172 FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700173 FlattenableUtils::read(buffer, size, mFrameNumber);
174 FlattenableUtils::read(buffer, size, mBuf);
175 FlattenableUtils::read(buffer, size, mIsDroppable);
176 FlattenableUtils::read(buffer, size, mAcquireCalled);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700177 FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700178
179 return NO_ERROR;
180}
181
182// ---------------------------------------------------------------------------
183
184enum {
185 ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
Dan Stoza9f3053d2014-03-06 15:14:33 -0800186 DETACH_BUFFER,
187 ATTACH_BUFFER,
Mathias Agopiana4e19522013-07-31 20:09:53 -0700188 RELEASE_BUFFER,
189 CONSUMER_CONNECT,
190 CONSUMER_DISCONNECT,
191 GET_RELEASED_BUFFERS,
192 SET_DEFAULT_BUFFER_SIZE,
193 SET_DEFAULT_MAX_BUFFER_COUNT,
194 DISABLE_ASYNC_BUFFER,
195 SET_MAX_ACQUIRED_BUFFER_COUNT,
196 SET_CONSUMER_NAME,
197 SET_DEFAULT_BUFFER_FORMAT,
198 SET_CONSUMER_USAGE_BITS,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700199 SET_TRANSFORM_HINT,
200 DUMP,
Mathias Agopiana4e19522013-07-31 20:09:53 -0700201};
202
203
204class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
205{
206public:
207 BpGraphicBufferConsumer(const sp<IBinder>& impl)
208 : BpInterface<IGraphicBufferConsumer>(impl)
209 {
210 }
211
212 virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
213 Parcel data, reply;
214 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
215 data.writeInt64(presentWhen);
216 status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
217 if (result != NO_ERROR) {
218 return result;
219 }
220 result = reply.read(*buffer);
221 if (result != NO_ERROR) {
222 return result;
223 }
224 return reply.readInt32();
225 }
226
Dan Stoza9f3053d2014-03-06 15:14:33 -0800227 virtual status_t detachBuffer(int slot) {
228 Parcel data, reply;
229 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
230 data.writeInt32(slot);
231 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
232 if (result != NO_ERROR) {
233 return result;
234 }
235 result = reply.readInt32();
236 return result;
237 }
238
239 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
240 Parcel data, reply;
241 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
242 data.write(*buffer.get());
243 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
244 if (result != NO_ERROR) {
245 return result;
246 }
247 *slot = reply.readInt32();
248 result = reply.readInt32();
249 return result;
250 }
251
Mathias Agopiana4e19522013-07-31 20:09:53 -0700252 virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
Igor Murashkin7d2d1602013-11-12 18:02:20 -0800253 EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
Mathias Agopiana4e19522013-07-31 20:09:53 -0700254 const sp<Fence>& releaseFence) {
255 Parcel data, reply;
256 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
257 data.writeInt32(buf);
258 data.writeInt64(frameNumber);
259 data.write(*releaseFence);
260 status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
261 if (result != NO_ERROR) {
262 return result;
263 }
264 return reply.readInt32();
265 }
266
267 virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
268 Parcel data, reply;
269 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
270 data.writeStrongBinder(consumer->asBinder());
271 data.writeInt32(controlledByApp);
272 status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
273 if (result != NO_ERROR) {
274 return result;
275 }
276 return reply.readInt32();
277 }
278
279 virtual status_t consumerDisconnect() {
280 Parcel data, reply;
281 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
282 status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
283 if (result != NO_ERROR) {
284 return result;
285 }
286 return reply.readInt32();
287 }
288
289 virtual status_t getReleasedBuffers(uint32_t* slotMask) {
290 Parcel data, reply;
291 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
292 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
293 if (result != NO_ERROR) {
294 return result;
295 }
296 *slotMask = reply.readInt32();
297 return reply.readInt32();
298 }
299
300 virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) {
301 Parcel data, reply;
302 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
303 data.writeInt32(w);
304 data.writeInt32(h);
305 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
306 if (result != NO_ERROR) {
307 return result;
308 }
309 return reply.readInt32();
310 }
311
312 virtual status_t setDefaultMaxBufferCount(int bufferCount) {
313 Parcel data, reply;
314 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
315 data.writeInt32(bufferCount);
316 status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
317 if (result != NO_ERROR) {
318 return result;
319 }
320 return reply.readInt32();
321 }
322
323 virtual status_t disableAsyncBuffer() {
324 Parcel data, reply;
325 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
326 status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
327 if (result != NO_ERROR) {
328 return result;
329 }
330 return reply.readInt32();
331 }
332
333 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
334 Parcel data, reply;
335 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
336 data.writeInt32(maxAcquiredBuffers);
337 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
338 if (result != NO_ERROR) {
339 return result;
340 }
341 return reply.readInt32();
342 }
343
344 virtual void setConsumerName(const String8& name) {
345 Parcel data, reply;
346 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
347 data.writeString8(name);
348 remote()->transact(SET_CONSUMER_NAME, data, &reply);
349 }
350
351 virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) {
352 Parcel data, reply;
353 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
354 data.writeInt32(defaultFormat);
355 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
356 if (result != NO_ERROR) {
357 return result;
358 }
359 return reply.readInt32();
360 }
361
362 virtual status_t setConsumerUsageBits(uint32_t usage) {
363 Parcel data, reply;
364 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
365 data.writeInt32(usage);
366 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
367 if (result != NO_ERROR) {
368 return result;
369 }
370 return reply.readInt32();
371 }
372
373 virtual status_t setTransformHint(uint32_t hint) {
374 Parcel data, reply;
375 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
376 data.writeInt32(hint);
377 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
378 if (result != NO_ERROR) {
379 return result;
380 }
381 return reply.readInt32();
382 }
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700383
384 virtual void dump(String8& result, const char* prefix) const {
385 Parcel data, reply;
386 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
387 data.writeString8(result);
388 data.writeString8(String8(prefix ? prefix : ""));
389 remote()->transact(DUMP, data, &reply);
390 reply.readString8();
391 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700392};
393
394IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
395
396// ----------------------------------------------------------------------
397
398status_t BnGraphicBufferConsumer::onTransact(
399 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
400{
401 switch(code) {
402 case ACQUIRE_BUFFER: {
403 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
404 BufferItem item;
405 int64_t presentWhen = data.readInt64();
406 status_t result = acquireBuffer(&item, presentWhen);
407 status_t err = reply->write(item);
408 if (err) return err;
409 reply->writeInt32(result);
410 return NO_ERROR;
411 } break;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800412 case DETACH_BUFFER: {
413 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
414 int slot = data.readInt32();
415 int result = detachBuffer(slot);
416 reply->writeInt32(result);
417 return NO_ERROR;
418 } break;
419 case ATTACH_BUFFER: {
420 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
421 sp<GraphicBuffer> buffer = new GraphicBuffer();
422 data.read(*buffer.get());
423 int slot;
424 int result = attachBuffer(&slot, buffer);
425 reply->writeInt32(slot);
426 reply->writeInt32(result);
427 return NO_ERROR;
428 } break;
Mathias Agopiana4e19522013-07-31 20:09:53 -0700429 case RELEASE_BUFFER: {
430 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
431 int buf = data.readInt32();
432 uint64_t frameNumber = data.readInt64();
433 sp<Fence> releaseFence = new Fence();
434 status_t err = data.read(*releaseFence);
435 if (err) return err;
436 status_t result = releaseBuffer(buf, frameNumber,
437 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
438 reply->writeInt32(result);
439 return NO_ERROR;
440 } break;
441 case CONSUMER_CONNECT: {
442 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
443 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
444 bool controlledByApp = data.readInt32();
445 status_t result = consumerConnect(consumer, controlledByApp);
446 reply->writeInt32(result);
447 return NO_ERROR;
448 } break;
449 case CONSUMER_DISCONNECT: {
450 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
451 status_t result = consumerDisconnect();
452 reply->writeInt32(result);
453 return NO_ERROR;
454 } break;
455 case GET_RELEASED_BUFFERS: {
456 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
457 uint32_t slotMask;
458 status_t result = getReleasedBuffers(&slotMask);
459 reply->writeInt32(slotMask);
460 reply->writeInt32(result);
461 return NO_ERROR;
462 } break;
463 case SET_DEFAULT_BUFFER_SIZE: {
464 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
465 uint32_t w = data.readInt32();
466 uint32_t h = data.readInt32();
467 status_t result = setDefaultBufferSize(w, h);
468 reply->writeInt32(result);
469 return NO_ERROR;
470 } break;
471 case SET_DEFAULT_MAX_BUFFER_COUNT: {
472 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
473 uint32_t bufferCount = data.readInt32();
474 status_t result = setDefaultMaxBufferCount(bufferCount);
475 reply->writeInt32(result);
476 return NO_ERROR;
477 } break;
478 case DISABLE_ASYNC_BUFFER: {
479 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
480 status_t result = disableAsyncBuffer();
481 reply->writeInt32(result);
482 return NO_ERROR;
483 } break;
484 case SET_MAX_ACQUIRED_BUFFER_COUNT: {
485 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
486 uint32_t maxAcquiredBuffers = data.readInt32();
487 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
488 reply->writeInt32(result);
489 return NO_ERROR;
490 } break;
491 case SET_CONSUMER_NAME: {
492 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
493 setConsumerName( data.readString8() );
494 return NO_ERROR;
495 } break;
496 case SET_DEFAULT_BUFFER_FORMAT: {
497 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
498 uint32_t defaultFormat = data.readInt32();
499 status_t result = setDefaultBufferFormat(defaultFormat);
500 reply->writeInt32(result);
501 return NO_ERROR;
502 } break;
503 case SET_CONSUMER_USAGE_BITS: {
504 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
505 uint32_t usage = data.readInt32();
506 status_t result = setConsumerUsageBits(usage);
507 reply->writeInt32(result);
508 return NO_ERROR;
509 } break;
510 case SET_TRANSFORM_HINT: {
511 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
512 uint32_t hint = data.readInt32();
513 status_t result = setTransformHint(hint);
514 reply->writeInt32(result);
515 return NO_ERROR;
516 } break;
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700517 case DUMP: {
518 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
519 String8 result = data.readString8();
520 String8 prefix = data.readString8();
521 static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
522 reply->writeString8(result);
523 return NO_ERROR;
524 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700525 }
526 return BBinder::onTransact(code, data, reply, flags);
527}
528
529}; // namespace android