blob: 3f23c2f6891bedc04374093c7f1363a5f675c682 [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
Mathias Agopiana4e19522013-07-31 20:09:53 -070017#include <stdint.h>
18#include <sys/types.h>
19
20#include <utils/Errors.h>
Jesse Hall399184a2014-03-03 15:42:54 -080021#include <utils/NativeHandle.h>
Mathias Agopiana4e19522013-07-31 20:09:53 -070022
23#include <binder/Parcel.h>
24#include <binder/IInterface.h>
25
Dan Stozade7100a2015-03-11 16:38:47 -070026#include <gui/BufferItem.h>
Mathias Agopiana4e19522013-07-31 20:09:53 -070027#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
35namespace android {
Mathias Agopiana4e19522013-07-31 20:09:53 -070036
37enum {
38 ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
Dan Stoza9f3053d2014-03-06 15:14:33 -080039 DETACH_BUFFER,
40 ATTACH_BUFFER,
Mathias Agopiana4e19522013-07-31 20:09:53 -070041 RELEASE_BUFFER,
42 CONSUMER_CONNECT,
43 CONSUMER_DISCONNECT,
44 GET_RELEASED_BUFFERS,
45 SET_DEFAULT_BUFFER_SIZE,
46 SET_DEFAULT_MAX_BUFFER_COUNT,
47 DISABLE_ASYNC_BUFFER,
48 SET_MAX_ACQUIRED_BUFFER_COUNT,
49 SET_CONSUMER_NAME,
50 SET_DEFAULT_BUFFER_FORMAT,
Eino-Ville Talvala5b75a512015-02-19 16:10:43 -080051 SET_DEFAULT_BUFFER_DATA_SPACE,
Mathias Agopiana4e19522013-07-31 20:09:53 -070052 SET_CONSUMER_USAGE_BITS,
Mathias Agopiandb89edc2013-08-02 01:40:18 -070053 SET_TRANSFORM_HINT,
Jesse Hall399184a2014-03-03 15:42:54 -080054 GET_SIDEBAND_STREAM,
Mathias Agopiandb89edc2013-08-02 01:40:18 -070055 DUMP,
Mathias Agopiana4e19522013-07-31 20:09:53 -070056};
57
58
59class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
60{
61public:
62 BpGraphicBufferConsumer(const sp<IBinder>& impl)
63 : BpInterface<IGraphicBufferConsumer>(impl)
64 {
65 }
66
Dan Stozad723bd72014-11-18 10:24:03 -080067 virtual ~BpGraphicBufferConsumer();
68
Mathias Agopiana4e19522013-07-31 20:09:53 -070069 virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
70 Parcel data, reply;
71 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
72 data.writeInt64(presentWhen);
73 status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
74 if (result != NO_ERROR) {
75 return result;
76 }
77 result = reply.read(*buffer);
78 if (result != NO_ERROR) {
79 return result;
80 }
81 return reply.readInt32();
82 }
83
Dan Stoza9f3053d2014-03-06 15:14:33 -080084 virtual status_t detachBuffer(int slot) {
85 Parcel data, reply;
86 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
87 data.writeInt32(slot);
88 status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
89 if (result != NO_ERROR) {
90 return result;
91 }
92 result = reply.readInt32();
93 return result;
94 }
95
96 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
97 Parcel data, reply;
98 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
99 data.write(*buffer.get());
100 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
101 if (result != NO_ERROR) {
102 return result;
103 }
104 *slot = reply.readInt32();
105 result = reply.readInt32();
106 return result;
107 }
108
Mathias Agopiana4e19522013-07-31 20:09:53 -0700109 virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
Igor Murashkin7d2d1602013-11-12 18:02:20 -0800110 EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
Mathias Agopiana4e19522013-07-31 20:09:53 -0700111 const sp<Fence>& releaseFence) {
112 Parcel data, reply;
113 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
114 data.writeInt32(buf);
Dan Stozad723bd72014-11-18 10:24:03 -0800115 data.writeInt64(static_cast<int64_t>(frameNumber));
Mathias Agopiana4e19522013-07-31 20:09:53 -0700116 data.write(*releaseFence);
117 status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
118 if (result != NO_ERROR) {
119 return result;
120 }
121 return reply.readInt32();
122 }
123
124 virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
125 Parcel data, reply;
126 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
Marco Nelissen2ea926b2014-11-14 08:01:01 -0800127 data.writeStrongBinder(IInterface::asBinder(consumer));
Mathias Agopiana4e19522013-07-31 20:09:53 -0700128 data.writeInt32(controlledByApp);
129 status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
130 if (result != NO_ERROR) {
131 return result;
132 }
133 return reply.readInt32();
134 }
135
136 virtual status_t consumerDisconnect() {
137 Parcel data, reply;
138 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
139 status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
140 if (result != NO_ERROR) {
141 return result;
142 }
143 return reply.readInt32();
144 }
145
Dan Stozafebd4f42014-04-09 16:14:51 -0700146 virtual status_t getReleasedBuffers(uint64_t* slotMask) {
Mathias Agopiana4e19522013-07-31 20:09:53 -0700147 Parcel data, reply;
Dan Stozafebd4f42014-04-09 16:14:51 -0700148 if (slotMask == NULL) {
149 ALOGE("getReleasedBuffers: slotMask must not be NULL");
150 return BAD_VALUE;
151 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700152 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
153 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
154 if (result != NO_ERROR) {
155 return result;
156 }
Dan Stozad723bd72014-11-18 10:24:03 -0800157 *slotMask = static_cast<uint64_t>(reply.readInt64());
Mathias Agopiana4e19522013-07-31 20:09:53 -0700158 return reply.readInt32();
159 }
160
Dan Stozad723bd72014-11-18 10:24:03 -0800161 virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height) {
Mathias Agopiana4e19522013-07-31 20:09:53 -0700162 Parcel data, reply;
163 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
Dan Stozad723bd72014-11-18 10:24:03 -0800164 data.writeUint32(width);
165 data.writeUint32(height);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700166 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
167 if (result != NO_ERROR) {
168 return result;
169 }
170 return reply.readInt32();
171 }
172
173 virtual status_t setDefaultMaxBufferCount(int bufferCount) {
174 Parcel data, reply;
175 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
176 data.writeInt32(bufferCount);
177 status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
178 if (result != NO_ERROR) {
179 return result;
180 }
181 return reply.readInt32();
182 }
183
184 virtual status_t disableAsyncBuffer() {
185 Parcel data, reply;
186 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
187 status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
188 if (result != NO_ERROR) {
189 return result;
190 }
191 return reply.readInt32();
192 }
193
194 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
195 Parcel data, reply;
196 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
197 data.writeInt32(maxAcquiredBuffers);
198 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
199 if (result != NO_ERROR) {
200 return result;
201 }
202 return reply.readInt32();
203 }
204
205 virtual void setConsumerName(const String8& name) {
206 Parcel data, reply;
207 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
208 data.writeString8(name);
209 remote()->transact(SET_CONSUMER_NAME, data, &reply);
210 }
211
Dan Stozad723bd72014-11-18 10:24:03 -0800212 virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) {
Mathias Agopiana4e19522013-07-31 20:09:53 -0700213 Parcel data, reply;
214 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
Dan Stozad723bd72014-11-18 10:24:03 -0800215 data.writeInt32(static_cast<int32_t>(defaultFormat));
Mathias Agopiana4e19522013-07-31 20:09:53 -0700216 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
217 if (result != NO_ERROR) {
218 return result;
219 }
220 return reply.readInt32();
221 }
222
Eino-Ville Talvala5b75a512015-02-19 16:10:43 -0800223 virtual status_t setDefaultBufferDataSpace(
224 android_dataspace defaultDataSpace) {
225 Parcel data, reply;
226 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
227 data.writeInt32(static_cast<int32_t>(defaultDataSpace));
228 status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE,
229 data, &reply);
230 if (result != NO_ERROR) {
231 return result;
232 }
233 return reply.readInt32();
234 }
235
Mathias Agopiana4e19522013-07-31 20:09:53 -0700236 virtual status_t setConsumerUsageBits(uint32_t usage) {
237 Parcel data, reply;
238 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
Dan Stozad723bd72014-11-18 10:24:03 -0800239 data.writeUint32(usage);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700240 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
241 if (result != NO_ERROR) {
242 return result;
243 }
244 return reply.readInt32();
245 }
246
247 virtual status_t setTransformHint(uint32_t hint) {
248 Parcel data, reply;
249 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
Dan Stozad723bd72014-11-18 10:24:03 -0800250 data.writeUint32(hint);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700251 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
252 if (result != NO_ERROR) {
253 return result;
254 }
255 return reply.readInt32();
256 }
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700257
Jesse Hall399184a2014-03-03 15:42:54 -0800258 virtual sp<NativeHandle> getSidebandStream() const {
259 Parcel data, reply;
260 status_t err;
261 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
262 if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
263 return NULL;
264 }
265 sp<NativeHandle> stream;
266 if (reply.readInt32()) {
Wonsik Kim0ec54e12014-03-21 10:46:24 +0900267 stream = NativeHandle::create(reply.readNativeHandle(), true);
Jesse Hall399184a2014-03-03 15:42:54 -0800268 }
269 return stream;
270 }
271
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700272 virtual void dump(String8& result, const char* prefix) const {
273 Parcel data, reply;
274 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
275 data.writeString8(result);
276 data.writeString8(String8(prefix ? prefix : ""));
277 remote()->transact(DUMP, data, &reply);
278 reply.readString8();
279 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700280};
281
Dan Stozad723bd72014-11-18 10:24:03 -0800282// Out-of-line virtual method definition to trigger vtable emission in this
283// translation unit (see clang warning -Wweak-vtables)
284BpGraphicBufferConsumer::~BpGraphicBufferConsumer() {}
285
Mathias Agopiana4e19522013-07-31 20:09:53 -0700286IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
287
288// ----------------------------------------------------------------------
289
290status_t BnGraphicBufferConsumer::onTransact(
291 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
292{
293 switch(code) {
294 case ACQUIRE_BUFFER: {
295 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
296 BufferItem item;
297 int64_t presentWhen = data.readInt64();
298 status_t result = acquireBuffer(&item, presentWhen);
299 status_t err = reply->write(item);
300 if (err) return err;
301 reply->writeInt32(result);
302 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800303 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800304 case DETACH_BUFFER: {
305 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
306 int slot = data.readInt32();
307 int result = detachBuffer(slot);
308 reply->writeInt32(result);
309 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800310 }
Dan Stoza9f3053d2014-03-06 15:14:33 -0800311 case ATTACH_BUFFER: {
312 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
313 sp<GraphicBuffer> buffer = new GraphicBuffer();
314 data.read(*buffer.get());
315 int slot;
316 int result = attachBuffer(&slot, buffer);
317 reply->writeInt32(slot);
318 reply->writeInt32(result);
319 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800320 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700321 case RELEASE_BUFFER: {
322 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
323 int buf = data.readInt32();
Dan Stozad723bd72014-11-18 10:24:03 -0800324 uint64_t frameNumber = static_cast<uint64_t>(data.readInt64());
Mathias Agopiana4e19522013-07-31 20:09:53 -0700325 sp<Fence> releaseFence = new Fence();
326 status_t err = data.read(*releaseFence);
327 if (err) return err;
328 status_t result = releaseBuffer(buf, frameNumber,
329 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
330 reply->writeInt32(result);
331 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800332 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700333 case CONSUMER_CONNECT: {
334 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
335 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
336 bool controlledByApp = data.readInt32();
337 status_t result = consumerConnect(consumer, controlledByApp);
338 reply->writeInt32(result);
339 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800340 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700341 case CONSUMER_DISCONNECT: {
342 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
343 status_t result = consumerDisconnect();
344 reply->writeInt32(result);
345 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800346 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700347 case GET_RELEASED_BUFFERS: {
348 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
Dan Stozafebd4f42014-04-09 16:14:51 -0700349 uint64_t slotMask;
Mathias Agopiana4e19522013-07-31 20:09:53 -0700350 status_t result = getReleasedBuffers(&slotMask);
Dan Stozad723bd72014-11-18 10:24:03 -0800351 reply->writeInt64(static_cast<int64_t>(slotMask));
Mathias Agopiana4e19522013-07-31 20:09:53 -0700352 reply->writeInt32(result);
353 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800354 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700355 case SET_DEFAULT_BUFFER_SIZE: {
356 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
Dan Stozad723bd72014-11-18 10:24:03 -0800357 uint32_t width = data.readUint32();
358 uint32_t height = data.readUint32();
359 status_t result = setDefaultBufferSize(width, height);
Mathias Agopiana4e19522013-07-31 20:09:53 -0700360 reply->writeInt32(result);
361 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800362 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700363 case SET_DEFAULT_MAX_BUFFER_COUNT: {
364 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
Dan Stozad723bd72014-11-18 10:24:03 -0800365 int bufferCount = data.readInt32();
Mathias Agopiana4e19522013-07-31 20:09:53 -0700366 status_t result = setDefaultMaxBufferCount(bufferCount);
367 reply->writeInt32(result);
368 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800369 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700370 case DISABLE_ASYNC_BUFFER: {
371 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
372 status_t result = disableAsyncBuffer();
373 reply->writeInt32(result);
374 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800375 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700376 case SET_MAX_ACQUIRED_BUFFER_COUNT: {
377 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
Dan Stozad723bd72014-11-18 10:24:03 -0800378 int maxAcquiredBuffers = data.readInt32();
Mathias Agopiana4e19522013-07-31 20:09:53 -0700379 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
380 reply->writeInt32(result);
381 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800382 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700383 case SET_CONSUMER_NAME: {
384 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
385 setConsumerName( data.readString8() );
386 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800387 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700388 case SET_DEFAULT_BUFFER_FORMAT: {
389 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
Dan Stozad723bd72014-11-18 10:24:03 -0800390 PixelFormat defaultFormat = static_cast<PixelFormat>(data.readInt32());
Mathias Agopiana4e19522013-07-31 20:09:53 -0700391 status_t result = setDefaultBufferFormat(defaultFormat);
392 reply->writeInt32(result);
393 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800394 }
Eino-Ville Talvala5b75a512015-02-19 16:10:43 -0800395 case SET_DEFAULT_BUFFER_DATA_SPACE: {
396 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
397 android_dataspace defaultDataSpace =
398 static_cast<android_dataspace>(data.readInt32());
399 status_t result = setDefaultBufferDataSpace(defaultDataSpace);
400 reply->writeInt32(result);
401 return NO_ERROR;
402 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700403 case SET_CONSUMER_USAGE_BITS: {
404 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
Dan Stozad723bd72014-11-18 10:24:03 -0800405 uint32_t usage = data.readUint32();
Mathias Agopiana4e19522013-07-31 20:09:53 -0700406 status_t result = setConsumerUsageBits(usage);
407 reply->writeInt32(result);
408 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800409 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700410 case SET_TRANSFORM_HINT: {
411 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
Dan Stozad723bd72014-11-18 10:24:03 -0800412 uint32_t hint = data.readUint32();
Mathias Agopiana4e19522013-07-31 20:09:53 -0700413 status_t result = setTransformHint(hint);
414 reply->writeInt32(result);
415 return NO_ERROR;
Dan Stozad723bd72014-11-18 10:24:03 -0800416 }
Mathias Agopiandb89edc2013-08-02 01:40:18 -0700417 case DUMP: {
418 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
419 String8 result = data.readString8();
420 String8 prefix = data.readString8();
421 static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
422 reply->writeString8(result);
423 return NO_ERROR;
424 }
Mathias Agopiana4e19522013-07-31 20:09:53 -0700425 }
426 return BBinder::onTransact(code, data, reply, flags);
427}
428
429}; // namespace android