blob: 6d65016cf0624626d860561ef772ae87de865f1b [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),
46 mFrameNumber(0),
47 mBuf(INVALID_BUFFER_SLOT),
48 mIsDroppable(false),
49 mAcquireCalled(false) {
50 mCrop.makeInvalid();
51}
52
53size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
54 size_t c = sizeof(mCrop) +
55 sizeof(mTransform) +
56 sizeof(mScalingMode) +
57 sizeof(mTimestamp) +
58 sizeof(mFrameNumber) +
59 sizeof(mBuf) +
60 sizeof(mIsDroppable) +
61 sizeof(mAcquireCalled);
62 return c;
63}
64
65size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
66 size_t c = 0;
67 if (mGraphicBuffer != 0) {
68 c += mGraphicBuffer->getFlattenedSize();
69 FlattenableUtils::align<4>(c);
70 }
71 if (mFence != 0) {
72 c += mFence->getFlattenedSize();
73 FlattenableUtils::align<4>(c);
74 }
75 return sizeof(int32_t) + c + getPodSize();
76}
77
78size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
79 size_t c = 0;
80 if (mGraphicBuffer != 0) {
81 c += mGraphicBuffer->getFdCount();
82 }
83 if (mFence != 0) {
84 c += mFence->getFdCount();
85 }
86 return c;
87}
88
89status_t IGraphicBufferConsumer::BufferItem::flatten(
90 void*& buffer, size_t& size, int*& fds, size_t& count) const {
91
92 // make sure we have enough space
93 if (count < BufferItem::getFlattenedSize()) {
94 return NO_MEMORY;
95 }
96
97 // content flags are stored first
98 uint32_t& flags = *static_cast<uint32_t*>(buffer);
99
100 // advance the pointer
101 FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
102
103 flags = 0;
104 if (mGraphicBuffer != 0) {
105 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
106 if (err) return err;
107 size -= FlattenableUtils::align<4>(buffer);
108 flags |= 1;
109 }
110 if (mFence != 0) {
111 status_t err = mFence->flatten(buffer, size, fds, count);
112 if (err) return err;
113 size -= FlattenableUtils::align<4>(buffer);
114 flags |= 2;
115 }
116
117 // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
118 if (size < getPodSize()) {
119 return NO_MEMORY;
120 }
121
122 FlattenableUtils::write(buffer, size, mCrop);
123 FlattenableUtils::write(buffer, size, mTransform);
124 FlattenableUtils::write(buffer, size, mScalingMode);
125 FlattenableUtils::write(buffer, size, mTimestamp);
126 FlattenableUtils::write(buffer, size, mFrameNumber);
127 FlattenableUtils::write(buffer, size, mBuf);
128 FlattenableUtils::write(buffer, size, mIsDroppable);
129 FlattenableUtils::write(buffer, size, mAcquireCalled);
130
131 return NO_ERROR;
132}
133
134status_t IGraphicBufferConsumer::BufferItem::unflatten(
135 void const*& buffer, size_t& size, int const*& fds, size_t& count) {
136
137 if (size < sizeof(uint32_t))
138 return NO_MEMORY;
139
140 uint32_t flags = 0;
141 FlattenableUtils::read(buffer, size, flags);
142
143 if (flags & 1) {
144 mGraphicBuffer = new GraphicBuffer();
145 status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
146 if (err) return err;
147 size -= FlattenableUtils::align<4>(buffer);
148 }
149
150 if (flags & 2) {
151 mFence = new Fence();
152 status_t err = mFence->unflatten(buffer, size, fds, count);
153 if (err) return err;
154 size -= FlattenableUtils::align<4>(buffer);
155 }
156
157 // check we have enough space
158 if (size < getPodSize()) {
159 return NO_MEMORY;
160 }
161
162 FlattenableUtils::read(buffer, size, mCrop);
163 FlattenableUtils::read(buffer, size, mTransform);
164 FlattenableUtils::read(buffer, size, mScalingMode);
165 FlattenableUtils::read(buffer, size, mTimestamp);
166 FlattenableUtils::read(buffer, size, mFrameNumber);
167 FlattenableUtils::read(buffer, size, mBuf);
168 FlattenableUtils::read(buffer, size, mIsDroppable);
169 FlattenableUtils::read(buffer, size, mAcquireCalled);
170
171 return NO_ERROR;
172}
173
174// ---------------------------------------------------------------------------
175
176enum {
177 ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
178 RELEASE_BUFFER,
179 CONSUMER_CONNECT,
180 CONSUMER_DISCONNECT,
181 GET_RELEASED_BUFFERS,
182 SET_DEFAULT_BUFFER_SIZE,
183 SET_DEFAULT_MAX_BUFFER_COUNT,
184 DISABLE_ASYNC_BUFFER,
185 SET_MAX_ACQUIRED_BUFFER_COUNT,
186 SET_CONSUMER_NAME,
187 SET_DEFAULT_BUFFER_FORMAT,
188 SET_CONSUMER_USAGE_BITS,
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700189 SET_TRANSFORM_HINT,
190 DUMP,
Mathias Agopiana4e19522013-07-31 20:09:53 -0700191};
192
193
194class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
195{
196public:
197 BpGraphicBufferConsumer(const sp<IBinder>& impl)
198 : BpInterface<IGraphicBufferConsumer>(impl)
199 {
200 }
201
202 virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
203 Parcel data, reply;
204 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
205 data.writeInt64(presentWhen);
206 status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
207 if (result != NO_ERROR) {
208 return result;
209 }
210 result = reply.read(*buffer);
211 if (result != NO_ERROR) {
212 return result;
213 }
214 return reply.readInt32();
215 }
216
217 virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
218 EGLDisplay display, EGLSyncKHR fence,
219 const sp<Fence>& releaseFence) {
220 Parcel data, reply;
221 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
222 data.writeInt32(buf);
223 data.writeInt64(frameNumber);
224 data.write(*releaseFence);
225 status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
226 if (result != NO_ERROR) {
227 return result;
228 }
229 return reply.readInt32();
230 }
231
232 virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
233 Parcel data, reply;
234 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
235 data.writeStrongBinder(consumer->asBinder());
236 data.writeInt32(controlledByApp);
237 status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
238 if (result != NO_ERROR) {
239 return result;
240 }
241 return reply.readInt32();
242 }
243
244 virtual status_t consumerDisconnect() {
245 Parcel data, reply;
246 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
247 status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
248 if (result != NO_ERROR) {
249 return result;
250 }
251 return reply.readInt32();
252 }
253
254 virtual status_t getReleasedBuffers(uint32_t* slotMask) {
255 Parcel data, reply;
256 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
257 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
258 if (result != NO_ERROR) {
259 return result;
260 }
261 *slotMask = reply.readInt32();
262 return reply.readInt32();
263 }
264
265 virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) {
266 Parcel data, reply;
267 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
268 data.writeInt32(w);
269 data.writeInt32(h);
270 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
271 if (result != NO_ERROR) {
272 return result;
273 }
274 return reply.readInt32();
275 }
276
277 virtual status_t setDefaultMaxBufferCount(int bufferCount) {
278 Parcel data, reply;
279 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
280 data.writeInt32(bufferCount);
281 status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
282 if (result != NO_ERROR) {
283 return result;
284 }
285 return reply.readInt32();
286 }
287
288 virtual status_t disableAsyncBuffer() {
289 Parcel data, reply;
290 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
291 status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
292 if (result != NO_ERROR) {
293 return result;
294 }
295 return reply.readInt32();
296 }
297
298 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
299 Parcel data, reply;
300 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
301 data.writeInt32(maxAcquiredBuffers);
302 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
303 if (result != NO_ERROR) {
304 return result;
305 }
306 return reply.readInt32();
307 }
308
309 virtual void setConsumerName(const String8& name) {
310 Parcel data, reply;
311 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
312 data.writeString8(name);
313 remote()->transact(SET_CONSUMER_NAME, data, &reply);
314 }
315
316 virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) {
317 Parcel data, reply;
318 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
319 data.writeInt32(defaultFormat);
320 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
321 if (result != NO_ERROR) {
322 return result;
323 }
324 return reply.readInt32();
325 }
326
327 virtual status_t setConsumerUsageBits(uint32_t usage) {
328 Parcel data, reply;
329 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
330 data.writeInt32(usage);
331 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
332 if (result != NO_ERROR) {
333 return result;
334 }
335 return reply.readInt32();
336 }
337
338 virtual status_t setTransformHint(uint32_t hint) {
339 Parcel data, reply;
340 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
341 data.writeInt32(hint);
342 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
343 if (result != NO_ERROR) {
344 return result;
345 }
346 return reply.readInt32();
347 }
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700348
349 virtual void dump(String8& result, const char* prefix) const {
350 Parcel data, reply;
351 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
352 data.writeString8(result);
353 data.writeString8(String8(prefix ? prefix : ""));
354 remote()->transact(DUMP, data, &reply);
355 reply.readString8();
356 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700357};
358
359IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
360
361// ----------------------------------------------------------------------
362
363status_t BnGraphicBufferConsumer::onTransact(
364 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
365{
366 switch(code) {
367 case ACQUIRE_BUFFER: {
368 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
369 BufferItem item;
370 int64_t presentWhen = data.readInt64();
371 status_t result = acquireBuffer(&item, presentWhen);
372 status_t err = reply->write(item);
373 if (err) return err;
374 reply->writeInt32(result);
375 return NO_ERROR;
376 } break;
377 case RELEASE_BUFFER: {
378 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
379 int buf = data.readInt32();
380 uint64_t frameNumber = data.readInt64();
381 sp<Fence> releaseFence = new Fence();
382 status_t err = data.read(*releaseFence);
383 if (err) return err;
384 status_t result = releaseBuffer(buf, frameNumber,
385 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
386 reply->writeInt32(result);
387 return NO_ERROR;
388 } break;
389 case CONSUMER_CONNECT: {
390 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
391 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
392 bool controlledByApp = data.readInt32();
393 status_t result = consumerConnect(consumer, controlledByApp);
394 reply->writeInt32(result);
395 return NO_ERROR;
396 } break;
397 case CONSUMER_DISCONNECT: {
398 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
399 status_t result = consumerDisconnect();
400 reply->writeInt32(result);
401 return NO_ERROR;
402 } break;
403 case GET_RELEASED_BUFFERS: {
404 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
405 uint32_t slotMask;
406 status_t result = getReleasedBuffers(&slotMask);
407 reply->writeInt32(slotMask);
408 reply->writeInt32(result);
409 return NO_ERROR;
410 } break;
411 case SET_DEFAULT_BUFFER_SIZE: {
412 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
413 uint32_t w = data.readInt32();
414 uint32_t h = data.readInt32();
415 status_t result = setDefaultBufferSize(w, h);
416 reply->writeInt32(result);
417 return NO_ERROR;
418 } break;
419 case SET_DEFAULT_MAX_BUFFER_COUNT: {
420 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
421 uint32_t bufferCount = data.readInt32();
422 status_t result = setDefaultMaxBufferCount(bufferCount);
423 reply->writeInt32(result);
424 return NO_ERROR;
425 } break;
426 case DISABLE_ASYNC_BUFFER: {
427 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
428 status_t result = disableAsyncBuffer();
429 reply->writeInt32(result);
430 return NO_ERROR;
431 } break;
432 case SET_MAX_ACQUIRED_BUFFER_COUNT: {
433 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
434 uint32_t maxAcquiredBuffers = data.readInt32();
435 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
436 reply->writeInt32(result);
437 return NO_ERROR;
438 } break;
439 case SET_CONSUMER_NAME: {
440 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
441 setConsumerName( data.readString8() );
442 return NO_ERROR;
443 } break;
444 case SET_DEFAULT_BUFFER_FORMAT: {
445 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
446 uint32_t defaultFormat = data.readInt32();
447 status_t result = setDefaultBufferFormat(defaultFormat);
448 reply->writeInt32(result);
449 return NO_ERROR;
450 } break;
451 case SET_CONSUMER_USAGE_BITS: {
452 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
453 uint32_t usage = data.readInt32();
454 status_t result = setConsumerUsageBits(usage);
455 reply->writeInt32(result);
456 return NO_ERROR;
457 } break;
458 case SET_TRANSFORM_HINT: {
459 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
460 uint32_t hint = data.readInt32();
461 status_t result = setTransformHint(hint);
462 reply->writeInt32(result);
463 return NO_ERROR;
464 } break;
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700465 case DUMP: {
466 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
467 String8 result = data.readString8();
468 String8 prefix = data.readString8();
469 static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
470 reply->writeString8(result);
471 return NO_ERROR;
472 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700473 }
474 return BBinder::onTransact(code, data, reply, flags);
475}
476
477}; // namespace android