IGraphicBufferConsumer.cpp revision a4e19521ac4563f2ff6517bcfd63d9b8d33a6d0b
1/* 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, 189 SET_TRANSFORM_HINT 190}; 191 192 193class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer> 194{ 195public: 196 BpGraphicBufferConsumer(const sp<IBinder>& impl) 197 : BpInterface<IGraphicBufferConsumer>(impl) 198 { 199 } 200 201 virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) { 202 Parcel data, reply; 203 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 204 data.writeInt64(presentWhen); 205 status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply); 206 if (result != NO_ERROR) { 207 return result; 208 } 209 result = reply.read(*buffer); 210 if (result != NO_ERROR) { 211 return result; 212 } 213 return reply.readInt32(); 214 } 215 216 virtual status_t releaseBuffer(int buf, uint64_t frameNumber, 217 EGLDisplay display, EGLSyncKHR fence, 218 const sp<Fence>& releaseFence) { 219 Parcel data, reply; 220 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 221 data.writeInt32(buf); 222 data.writeInt64(frameNumber); 223 data.write(*releaseFence); 224 status_t result = remote()->transact(RELEASE_BUFFER, data, &reply); 225 if (result != NO_ERROR) { 226 return result; 227 } 228 return reply.readInt32(); 229 } 230 231 virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { 232 Parcel data, reply; 233 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 234 data.writeStrongBinder(consumer->asBinder()); 235 data.writeInt32(controlledByApp); 236 status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply); 237 if (result != NO_ERROR) { 238 return result; 239 } 240 return reply.readInt32(); 241 } 242 243 virtual status_t consumerDisconnect() { 244 Parcel data, reply; 245 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 246 status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply); 247 if (result != NO_ERROR) { 248 return result; 249 } 250 return reply.readInt32(); 251 } 252 253 virtual status_t getReleasedBuffers(uint32_t* slotMask) { 254 Parcel data, reply; 255 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 256 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply); 257 if (result != NO_ERROR) { 258 return result; 259 } 260 *slotMask = reply.readInt32(); 261 return reply.readInt32(); 262 } 263 264 virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) { 265 Parcel data, reply; 266 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 267 data.writeInt32(w); 268 data.writeInt32(h); 269 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply); 270 if (result != NO_ERROR) { 271 return result; 272 } 273 return reply.readInt32(); 274 } 275 276 virtual status_t setDefaultMaxBufferCount(int bufferCount) { 277 Parcel data, reply; 278 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 279 data.writeInt32(bufferCount); 280 status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply); 281 if (result != NO_ERROR) { 282 return result; 283 } 284 return reply.readInt32(); 285 } 286 287 virtual status_t disableAsyncBuffer() { 288 Parcel data, reply; 289 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 290 status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply); 291 if (result != NO_ERROR) { 292 return result; 293 } 294 return reply.readInt32(); 295 } 296 297 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 298 Parcel data, reply; 299 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 300 data.writeInt32(maxAcquiredBuffers); 301 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply); 302 if (result != NO_ERROR) { 303 return result; 304 } 305 return reply.readInt32(); 306 } 307 308 virtual void setConsumerName(const String8& name) { 309 Parcel data, reply; 310 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 311 data.writeString8(name); 312 remote()->transact(SET_CONSUMER_NAME, data, &reply); 313 } 314 315 virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) { 316 Parcel data, reply; 317 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 318 data.writeInt32(defaultFormat); 319 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply); 320 if (result != NO_ERROR) { 321 return result; 322 } 323 return reply.readInt32(); 324 } 325 326 virtual status_t setConsumerUsageBits(uint32_t usage) { 327 Parcel data, reply; 328 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 329 data.writeInt32(usage); 330 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply); 331 if (result != NO_ERROR) { 332 return result; 333 } 334 return reply.readInt32(); 335 } 336 337 virtual status_t setTransformHint(uint32_t hint) { 338 Parcel data, reply; 339 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 340 data.writeInt32(hint); 341 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply); 342 if (result != NO_ERROR) { 343 return result; 344 } 345 return reply.readInt32(); 346 } 347}; 348 349IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer"); 350 351// ---------------------------------------------------------------------- 352 353status_t BnGraphicBufferConsumer::onTransact( 354 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 355{ 356 switch(code) { 357 case ACQUIRE_BUFFER: { 358 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 359 BufferItem item; 360 int64_t presentWhen = data.readInt64(); 361 status_t result = acquireBuffer(&item, presentWhen); 362 status_t err = reply->write(item); 363 if (err) return err; 364 reply->writeInt32(result); 365 return NO_ERROR; 366 } break; 367 case RELEASE_BUFFER: { 368 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 369 int buf = data.readInt32(); 370 uint64_t frameNumber = data.readInt64(); 371 sp<Fence> releaseFence = new Fence(); 372 status_t err = data.read(*releaseFence); 373 if (err) return err; 374 status_t result = releaseBuffer(buf, frameNumber, 375 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); 376 reply->writeInt32(result); 377 return NO_ERROR; 378 } break; 379 case CONSUMER_CONNECT: { 380 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 381 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() ); 382 bool controlledByApp = data.readInt32(); 383 status_t result = consumerConnect(consumer, controlledByApp); 384 reply->writeInt32(result); 385 return NO_ERROR; 386 } break; 387 case CONSUMER_DISCONNECT: { 388 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 389 status_t result = consumerDisconnect(); 390 reply->writeInt32(result); 391 return NO_ERROR; 392 } break; 393 case GET_RELEASED_BUFFERS: { 394 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 395 uint32_t slotMask; 396 status_t result = getReleasedBuffers(&slotMask); 397 reply->writeInt32(slotMask); 398 reply->writeInt32(result); 399 return NO_ERROR; 400 } break; 401 case SET_DEFAULT_BUFFER_SIZE: { 402 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 403 uint32_t w = data.readInt32(); 404 uint32_t h = data.readInt32(); 405 status_t result = setDefaultBufferSize(w, h); 406 reply->writeInt32(result); 407 return NO_ERROR; 408 } break; 409 case SET_DEFAULT_MAX_BUFFER_COUNT: { 410 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 411 uint32_t bufferCount = data.readInt32(); 412 status_t result = setDefaultMaxBufferCount(bufferCount); 413 reply->writeInt32(result); 414 return NO_ERROR; 415 } break; 416 case DISABLE_ASYNC_BUFFER: { 417 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 418 status_t result = disableAsyncBuffer(); 419 reply->writeInt32(result); 420 return NO_ERROR; 421 } break; 422 case SET_MAX_ACQUIRED_BUFFER_COUNT: { 423 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 424 uint32_t maxAcquiredBuffers = data.readInt32(); 425 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers); 426 reply->writeInt32(result); 427 return NO_ERROR; 428 } break; 429 case SET_CONSUMER_NAME: { 430 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 431 setConsumerName( data.readString8() ); 432 return NO_ERROR; 433 } break; 434 case SET_DEFAULT_BUFFER_FORMAT: { 435 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 436 uint32_t defaultFormat = data.readInt32(); 437 status_t result = setDefaultBufferFormat(defaultFormat); 438 reply->writeInt32(result); 439 return NO_ERROR; 440 } break; 441 case SET_CONSUMER_USAGE_BITS: { 442 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 443 uint32_t usage = data.readInt32(); 444 status_t result = setConsumerUsageBits(usage); 445 reply->writeInt32(result); 446 return NO_ERROR; 447 } break; 448 case SET_TRANSFORM_HINT: { 449 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 450 uint32_t hint = data.readInt32(); 451 status_t result = setTransformHint(hint); 452 reply->writeInt32(result); 453 return NO_ERROR; 454 } break; 455 } 456 return BBinder::onTransact(code, data, reply, flags); 457} 458 459}; // namespace android 460