IGraphicBufferConsumer.cpp revision db89edc94bd2a78226b407f9f7261e202e7fa325
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 DUMP, 191}; 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 } 348 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 } 357}; 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; 465 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 } 473 } 474 return BBinder::onTransact(code, data, reply, flags); 475} 476 477}; // namespace android 478