blob: 3598a8610b906a7b42b48d2ea171c3bfe4973e0b [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>
Jesse Hall399184a2014-03-03 15:42:54 -080027#include <utils/NativeHandle.h>
Mathias Agopiana4e19522013-07-31 20:09:53 -070028
29#include <binder/Parcel.h>
30#include <binder/IInterface.h>
31
32#include <gui/IConsumerListener.h>
33#include <gui/IGraphicBufferConsumer.h>
34
35#include <ui/GraphicBuffer.h>
36#include <ui/Fence.h>
37
38#include <system/window.h>
39
40namespace android {
41// ---------------------------------------------------------------------------
42
43IGraphicBufferConsumer::BufferItem::BufferItem() :
44 mTransform(0),
45 mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
46 mTimestamp(0),
Andy McFadden3c256212013-08-16 14:55:39 -070047 mIsAutoTimestamp(false),
Mathias Agopiana4e19522013-07-31 20:09:53 -070048 mFrameNumber(0),
49 mBuf(INVALID_BUFFER_SLOT),
50 mIsDroppable(false),
Mathias Agopianc1c05de2013-09-17 23:45:22 -070051 mAcquireCalled(false),
52 mTransformToDisplayInverse(false) {
Mathias Agopiana4e19522013-07-31 20:09:53 -070053 mCrop.makeInvalid();
54}
55
56size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
57 size_t c = sizeof(mCrop) +
58 sizeof(mTransform) +
59 sizeof(mScalingMode) +
60 sizeof(mTimestamp) +
Andy McFadden3c256212013-08-16 14:55:39 -070061 sizeof(mIsAutoTimestamp) +
Mathias Agopiana4e19522013-07-31 20:09:53 -070062 sizeof(mFrameNumber) +
63 sizeof(mBuf) +
64 sizeof(mIsDroppable) +
Mathias Agopianc1c05de2013-09-17 23:45:22 -070065 sizeof(mAcquireCalled) +
66 sizeof(mTransformToDisplayInverse);
Mathias Agopiana4e19522013-07-31 20:09:53 -070067 return c;
68}
69
70size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
71 size_t c = 0;
72 if (mGraphicBuffer != 0) {
73 c += mGraphicBuffer->getFlattenedSize();
74 FlattenableUtils::align<4>(c);
75 }
76 if (mFence != 0) {
77 c += mFence->getFlattenedSize();
78 FlattenableUtils::align<4>(c);
79 }
80 return sizeof(int32_t) + c + getPodSize();
81}
82
83size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
84 size_t c = 0;
85 if (mGraphicBuffer != 0) {
86 c += mGraphicBuffer->getFdCount();
87 }
88 if (mFence != 0) {
89 c += mFence->getFdCount();
90 }
91 return c;
92}
93
94status_t IGraphicBufferConsumer::BufferItem::flatten(
95 void*& buffer, size_t& size, int*& fds, size_t& count) const {
96
97 // make sure we have enough space
98 if (count < BufferItem::getFlattenedSize()) {
99 return NO_MEMORY;
100 }
101
102 // content flags are stored first
103 uint32_t& flags = *static_cast<uint32_t*>(buffer);
104
105 // advance the pointer
106 FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
107
108 flags = 0;
109 if (mGraphicBuffer != 0) {
110 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
111 if (err) return err;
112 size -= FlattenableUtils::align<4>(buffer);
113 flags |= 1;
114 }
115 if (mFence != 0) {
116 status_t err = mFence->flatten(buffer, size, fds, count);
117 if (err) return err;
118 size -= FlattenableUtils::align<4>(buffer);
119 flags |= 2;
120 }
121
122 // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
123 if (size < getPodSize()) {
124 return NO_MEMORY;
125 }
126
127 FlattenableUtils::write(buffer, size, mCrop);
128 FlattenableUtils::write(buffer, size, mTransform);
129 FlattenableUtils::write(buffer, size, mScalingMode);
130 FlattenableUtils::write(buffer, size, mTimestamp);
Andy McFadden3c256212013-08-16 14:55:39 -0700131 FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700132 FlattenableUtils::write(buffer, size, mFrameNumber);
133 FlattenableUtils::write(buffer, size, mBuf);
134 FlattenableUtils::write(buffer, size, mIsDroppable);
135 FlattenableUtils::write(buffer, size, mAcquireCalled);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700136 FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700137
138 return NO_ERROR;
139}
140
141status_t IGraphicBufferConsumer::BufferItem::unflatten(
142 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
143
144 if (size < sizeof(uint32_t))
145 return NO_MEMORY;
146
147 uint32_t flags = 0;
148 FlattenableUtils::read(buffer, size, flags);
149
150 if (flags & 1) {
151 mGraphicBuffer = new GraphicBuffer();
152 status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
153 if (err) return err;
154 size -= FlattenableUtils::align<4>(buffer);
155 }
156
157 if (flags & 2) {
158 mFence = new Fence();
159 status_t err = mFence->unflatten(buffer, size, fds, count);
160 if (err) return err;
161 size -= FlattenableUtils::align<4>(buffer);
162 }
163
164 // check we have enough space
165 if (size < getPodSize()) {
166 return NO_MEMORY;
167 }
168
169 FlattenableUtils::read(buffer, size, mCrop);
170 FlattenableUtils::read(buffer, size, mTransform);
171 FlattenableUtils::read(buffer, size, mScalingMode);
172 FlattenableUtils::read(buffer, size, mTimestamp);
Andy McFadden3c256212013-08-16 14:55:39 -0700173 FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700174 FlattenableUtils::read(buffer, size, mFrameNumber);
175 FlattenableUtils::read(buffer, size, mBuf);
176 FlattenableUtils::read(buffer, size, mIsDroppable);
177 FlattenableUtils::read(buffer, size, mAcquireCalled);
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700178 FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700179
180 return NO_ERROR;
181}
182
183// ---------------------------------------------------------------------------
184
185enum {
186 ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
Dan Stoza9f3053d2014-03-06 15:14:33 -0800187 DETACH_BUFFER,
188 ATTACH_BUFFER,
Mathias Agopiana4e19522013-07-31 20:09:53 -0700189 RELEASE_BUFFER,
190 CONSUMER_CONNECT,
191 CONSUMER_DISCONNECT,
192 GET_RELEASED_BUFFERS,
193 SET_DEFAULT_BUFFER_SIZE,
194 SET_DEFAULT_MAX_BUFFER_COUNT,
195 DISABLE_ASYNC_BUFFER,
196 SET_MAX_ACQUIRED_BUFFER_COUNT,
197 SET_CONSUMER_NAME,
198 SET_DEFAULT_BUFFER_FORMAT,
199 SET_CONSUMER_USAGE_BITS,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700200 SET_TRANSFORM_HINT,
Jesse Hall399184a2014-03-03 15:42:54 -0800201 GET_SIDEBAND_STREAM,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700202 DUMP,
Mathias Agopiana4e19522013-07-31 20:09:53 -0700203};
204
205
206class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
207{
208public:
209 BpGraphicBufferConsumer(const sp<IBinder>& impl)
210 : BpInterface<IGraphicBufferConsumer>(impl)
211 {
212 }
213
214 virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
215 Parcel data, reply;
216 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
217 data.writeInt64(presentWhen);
218 status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
219 if (result != NO_ERROR) {
220 return result;
221 }
222 result = reply.read(*buffer);
223 if (result != NO_ERROR) {
224 return result;
225 }
226 return reply.readInt32();
227 }
228
Dan Stoza9f3053d2014-03-06 15:14:33 -0800229 virtual status_t detachBuffer(int slot) {
230 Parcel data, reply;
231 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
232 data.writeInt32(slot);
233 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
234 if (result != NO_ERROR) {
235 return result;
236 }
237 result = reply.readInt32();
238 return result;
239 }
240
241 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
242 Parcel data, reply;
243 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
244 data.write(*buffer.get());
245 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
246 if (result != NO_ERROR) {
247 return result;
248 }
249 *slot = reply.readInt32();
250 result = reply.readInt32();
251 return result;
252 }
253
Mathias Agopiana4e19522013-07-31 20:09:53 -0700254 virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
Igor Murashkin7d2d1602013-11-12 18:02:20 -0800255 EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
Mathias Agopiana4e19522013-07-31 20:09:53 -0700256 const sp<Fence>& releaseFence) {
257 Parcel data, reply;
258 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
259 data.writeInt32(buf);
260 data.writeInt64(frameNumber);
261 data.write(*releaseFence);
262 status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
263 if (result != NO_ERROR) {
264 return result;
265 }
266 return reply.readInt32();
267 }
268
269 virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
270 Parcel data, reply;
271 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
272 data.writeStrongBinder(consumer->asBinder());
273 data.writeInt32(controlledByApp);
274 status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
275 if (result != NO_ERROR) {
276 return result;
277 }
278 return reply.readInt32();
279 }
280
281 virtual status_t consumerDisconnect() {
282 Parcel data, reply;
283 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
284 status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
285 if (result != NO_ERROR) {
286 return result;
287 }
288 return reply.readInt32();
289 }
290
291 virtual status_t getReleasedBuffers(uint32_t* slotMask) {
292 Parcel data, reply;
293 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
294 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
295 if (result != NO_ERROR) {
296 return result;
297 }
298 *slotMask = reply.readInt32();
299 return reply.readInt32();
300 }
301
302 virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) {
303 Parcel data, reply;
304 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
305 data.writeInt32(w);
306 data.writeInt32(h);
307 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
308 if (result != NO_ERROR) {
309 return result;
310 }
311 return reply.readInt32();
312 }
313
314 virtual status_t setDefaultMaxBufferCount(int bufferCount) {
315 Parcel data, reply;
316 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
317 data.writeInt32(bufferCount);
318 status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
319 if (result != NO_ERROR) {
320 return result;
321 }
322 return reply.readInt32();
323 }
324
325 virtual status_t disableAsyncBuffer() {
326 Parcel data, reply;
327 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
328 status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
329 if (result != NO_ERROR) {
330 return result;
331 }
332 return reply.readInt32();
333 }
334
335 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
336 Parcel data, reply;
337 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
338 data.writeInt32(maxAcquiredBuffers);
339 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
340 if (result != NO_ERROR) {
341 return result;
342 }
343 return reply.readInt32();
344 }
345
346 virtual void setConsumerName(const String8& name) {
347 Parcel data, reply;
348 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
349 data.writeString8(name);
350 remote()->transact(SET_CONSUMER_NAME, data, &reply);
351 }
352
353 virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) {
354 Parcel data, reply;
355 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
356 data.writeInt32(defaultFormat);
357 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
358 if (result != NO_ERROR) {
359 return result;
360 }
361 return reply.readInt32();
362 }
363
364 virtual status_t setConsumerUsageBits(uint32_t usage) {
365 Parcel data, reply;
366 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
367 data.writeInt32(usage);
368 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
369 if (result != NO_ERROR) {
370 return result;
371 }
372 return reply.readInt32();
373 }
374
375 virtual status_t setTransformHint(uint32_t hint) {
376 Parcel data, reply;
377 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
378 data.writeInt32(hint);
379 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
380 if (result != NO_ERROR) {
381 return result;
382 }
383 return reply.readInt32();
384 }
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700385
Jesse Hall399184a2014-03-03 15:42:54 -0800386 virtual sp<NativeHandle> getSidebandStream() const {
387 Parcel data, reply;
388 status_t err;
389 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
390 if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
391 return NULL;
392 }
393 sp<NativeHandle> stream;
394 if (reply.readInt32()) {
395 stream = NativeHandle::create(reply.readNativeHandle());
396 }
397 return stream;
398 }
399
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700400 virtual void dump(String8& result, const char* prefix) const {
401 Parcel data, reply;
402 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
403 data.writeString8(result);
404 data.writeString8(String8(prefix ? prefix : ""));
405 remote()->transact(DUMP, data, &reply);
406 reply.readString8();
407 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700408};
409
410IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
411
412// ----------------------------------------------------------------------
413
414status_t BnGraphicBufferConsumer::onTransact(
415 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
416{
417 switch(code) {
418 case ACQUIRE_BUFFER: {
419 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
420 BufferItem item;
421 int64_t presentWhen = data.readInt64();
422 status_t result = acquireBuffer(&item, presentWhen);
423 status_t err = reply->write(item);
424 if (err) return err;
425 reply->writeInt32(result);
426 return NO_ERROR;
427 } break;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800428 case DETACH_BUFFER: {
429 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
430 int slot = data.readInt32();
431 int result = detachBuffer(slot);
432 reply->writeInt32(result);
433 return NO_ERROR;
434 } break;
435 case ATTACH_BUFFER: {
436 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
437 sp<GraphicBuffer> buffer = new GraphicBuffer();
438 data.read(*buffer.get());
439 int slot;
440 int result = attachBuffer(&slot, buffer);
441 reply->writeInt32(slot);
442 reply->writeInt32(result);
443 return NO_ERROR;
444 } break;
Mathias Agopiana4e19522013-07-31 20:09:53 -0700445 case RELEASE_BUFFER: {
446 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
447 int buf = data.readInt32();
448 uint64_t frameNumber = data.readInt64();
449 sp<Fence> releaseFence = new Fence();
450 status_t err = data.read(*releaseFence);
451 if (err) return err;
452 status_t result = releaseBuffer(buf, frameNumber,
453 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
454 reply->writeInt32(result);
455 return NO_ERROR;
456 } break;
457 case CONSUMER_CONNECT: {
458 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
459 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
460 bool controlledByApp = data.readInt32();
461 status_t result = consumerConnect(consumer, controlledByApp);
462 reply->writeInt32(result);
463 return NO_ERROR;
464 } break;
465 case CONSUMER_DISCONNECT: {
466 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
467 status_t result = consumerDisconnect();
468 reply->writeInt32(result);
469 return NO_ERROR;
470 } break;
471 case GET_RELEASED_BUFFERS: {
472 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
473 uint32_t slotMask;
474 status_t result = getReleasedBuffers(&slotMask);
475 reply->writeInt32(slotMask);
476 reply->writeInt32(result);
477 return NO_ERROR;
478 } break;
479 case SET_DEFAULT_BUFFER_SIZE: {
480 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
481 uint32_t w = data.readInt32();
482 uint32_t h = data.readInt32();
483 status_t result = setDefaultBufferSize(w, h);
484 reply->writeInt32(result);
485 return NO_ERROR;
486 } break;
487 case SET_DEFAULT_MAX_BUFFER_COUNT: {
488 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
489 uint32_t bufferCount = data.readInt32();
490 status_t result = setDefaultMaxBufferCount(bufferCount);
491 reply->writeInt32(result);
492 return NO_ERROR;
493 } break;
494 case DISABLE_ASYNC_BUFFER: {
495 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
496 status_t result = disableAsyncBuffer();
497 reply->writeInt32(result);
498 return NO_ERROR;
499 } break;
500 case SET_MAX_ACQUIRED_BUFFER_COUNT: {
501 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
502 uint32_t maxAcquiredBuffers = data.readInt32();
503 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
504 reply->writeInt32(result);
505 return NO_ERROR;
506 } break;
507 case SET_CONSUMER_NAME: {
508 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
509 setConsumerName( data.readString8() );
510 return NO_ERROR;
511 } break;
512 case SET_DEFAULT_BUFFER_FORMAT: {
513 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
514 uint32_t defaultFormat = data.readInt32();
515 status_t result = setDefaultBufferFormat(defaultFormat);
516 reply->writeInt32(result);
517 return NO_ERROR;
518 } break;
519 case SET_CONSUMER_USAGE_BITS: {
520 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
521 uint32_t usage = data.readInt32();
522 status_t result = setConsumerUsageBits(usage);
523 reply->writeInt32(result);
524 return NO_ERROR;
525 } break;
526 case SET_TRANSFORM_HINT: {
527 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
528 uint32_t hint = data.readInt32();
529 status_t result = setTransformHint(hint);
530 reply->writeInt32(result);
531 return NO_ERROR;
532 } break;
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700533 case DUMP: {
534 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
535 String8 result = data.readString8();
536 String8 prefix = data.readString8();
537 static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
538 reply->writeString8(result);
539 return NO_ERROR;
540 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700541 }
542 return BBinder::onTransact(code, data, reply, flags);
543}
544
545}; // namespace android