IGraphicBufferConsumer.cpp revision 9cfa49c95445b968da3170b4fdb0b942af69569e
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#include <utils/NativeHandle.h> 28 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), 47 mIsAutoTimestamp(false), 48 mFrameNumber(0), 49 mBuf(INVALID_BUFFER_SLOT), 50 mIsDroppable(false), 51 mAcquireCalled(false), 52 mTransformToDisplayInverse(false) { 53 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) + 61 sizeof(mIsAutoTimestamp) + 62 sizeof(mFrameNumber) + 63 sizeof(mBuf) + 64 sizeof(mIsDroppable) + 65 sizeof(mAcquireCalled) + 66 sizeof(mTransformToDisplayInverse); 67 return c; 68} 69 70size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const { 71 size_t c = 0; 72 if (mGraphicBuffer != 0) { 73 c += mGraphicBuffer->getFlattenedSize(); 74 c = FlattenableUtils::align<4>(c); 75 } 76 if (mFence != 0) { 77 c += mFence->getFlattenedSize(); 78 c = 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 94static void writeBoolAsInt(void*& buffer, size_t& size, bool b) { 95 FlattenableUtils::write(buffer, size, static_cast<int32_t>(b)); 96} 97 98static bool readBoolFromInt(void const*& buffer, size_t& size) { 99 int32_t i; 100 FlattenableUtils::read(buffer, size, i); 101 return static_cast<bool>(i); 102} 103 104status_t IGraphicBufferConsumer::BufferItem::flatten( 105 void*& buffer, size_t& size, int*& fds, size_t& count) const { 106 107 // make sure we have enough space 108 if (size < BufferItem::getFlattenedSize()) { 109 return NO_MEMORY; 110 } 111 112 // content flags are stored first 113 uint32_t& flags = *static_cast<uint32_t*>(buffer); 114 115 // advance the pointer 116 FlattenableUtils::advance(buffer, size, sizeof(uint32_t)); 117 118 flags = 0; 119 if (mGraphicBuffer != 0) { 120 status_t err = mGraphicBuffer->flatten(buffer, size, fds, count); 121 if (err) return err; 122 size -= FlattenableUtils::align<4>(buffer); 123 flags |= 1; 124 } 125 if (mFence != 0) { 126 status_t err = mFence->flatten(buffer, size, fds, count); 127 if (err) return err; 128 size -= FlattenableUtils::align<4>(buffer); 129 flags |= 2; 130 } 131 132 // check we have enough space (in case flattening the fence/graphicbuffer lied to us) 133 if (size < getPodSize()) { 134 return NO_MEMORY; 135 } 136 137 FlattenableUtils::write(buffer, size, mCrop); 138 FlattenableUtils::write(buffer, size, mTransform); 139 FlattenableUtils::write(buffer, size, mScalingMode); 140 FlattenableUtils::write(buffer, size, mTimestamp); 141 writeBoolAsInt(buffer, size, mIsAutoTimestamp); 142 FlattenableUtils::write(buffer, size, mFrameNumber); 143 FlattenableUtils::write(buffer, size, mBuf); 144 writeBoolAsInt(buffer, size, mIsDroppable); 145 writeBoolAsInt(buffer, size, mAcquireCalled); 146 writeBoolAsInt(buffer, size, mTransformToDisplayInverse); 147 148 return NO_ERROR; 149} 150 151status_t IGraphicBufferConsumer::BufferItem::unflatten( 152 void const*& buffer, size_t& size, int const*& fds, size_t& count) { 153 154 if (size < sizeof(uint32_t)) 155 return NO_MEMORY; 156 157 uint32_t flags = 0; 158 FlattenableUtils::read(buffer, size, flags); 159 160 if (flags & 1) { 161 mGraphicBuffer = new GraphicBuffer(); 162 status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count); 163 if (err) return err; 164 size -= FlattenableUtils::align<4>(buffer); 165 } 166 167 if (flags & 2) { 168 mFence = new Fence(); 169 status_t err = mFence->unflatten(buffer, size, fds, count); 170 if (err) return err; 171 size -= FlattenableUtils::align<4>(buffer); 172 } 173 174 // check we have enough space 175 if (size < getPodSize()) { 176 return NO_MEMORY; 177 } 178 179 FlattenableUtils::read(buffer, size, mCrop); 180 FlattenableUtils::read(buffer, size, mTransform); 181 FlattenableUtils::read(buffer, size, mScalingMode); 182 FlattenableUtils::read(buffer, size, mTimestamp); 183 mIsAutoTimestamp = readBoolFromInt(buffer, size); 184 FlattenableUtils::read(buffer, size, mFrameNumber); 185 FlattenableUtils::read(buffer, size, mBuf); 186 mIsDroppable = readBoolFromInt(buffer, size); 187 mAcquireCalled = readBoolFromInt(buffer, size); 188 mTransformToDisplayInverse = readBoolFromInt(buffer, size); 189 190 return NO_ERROR; 191} 192 193// --------------------------------------------------------------------------- 194 195enum { 196 ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION, 197 DETACH_BUFFER, 198 ATTACH_BUFFER, 199 RELEASE_BUFFER, 200 CONSUMER_CONNECT, 201 CONSUMER_DISCONNECT, 202 GET_RELEASED_BUFFERS, 203 SET_DEFAULT_BUFFER_SIZE, 204 SET_DEFAULT_MAX_BUFFER_COUNT, 205 DISABLE_ASYNC_BUFFER, 206 SET_MAX_ACQUIRED_BUFFER_COUNT, 207 SET_CONSUMER_NAME, 208 SET_DEFAULT_BUFFER_FORMAT, 209 SET_CONSUMER_USAGE_BITS, 210 SET_TRANSFORM_HINT, 211 GET_SIDEBAND_STREAM, 212 DUMP, 213}; 214 215 216class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer> 217{ 218public: 219 BpGraphicBufferConsumer(const sp<IBinder>& impl) 220 : BpInterface<IGraphicBufferConsumer>(impl) 221 { 222 } 223 224 virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) { 225 Parcel data, reply; 226 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 227 data.writeInt64(presentWhen); 228 status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply); 229 if (result != NO_ERROR) { 230 return result; 231 } 232 result = reply.read(*buffer); 233 if (result != NO_ERROR) { 234 return result; 235 } 236 return reply.readInt32(); 237 } 238 239 virtual status_t detachBuffer(int slot) { 240 Parcel data, reply; 241 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 242 data.writeInt32(slot); 243 status_t result = remote()->transact(DETACH_BUFFER, data, &reply); 244 if (result != NO_ERROR) { 245 return result; 246 } 247 result = reply.readInt32(); 248 return result; 249 } 250 251 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) { 252 Parcel data, reply; 253 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 254 data.write(*buffer.get()); 255 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply); 256 if (result != NO_ERROR) { 257 return result; 258 } 259 *slot = reply.readInt32(); 260 result = reply.readInt32(); 261 return result; 262 } 263 264 virtual status_t releaseBuffer(int buf, uint64_t frameNumber, 265 EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)), 266 const sp<Fence>& releaseFence) { 267 Parcel data, reply; 268 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 269 data.writeInt32(buf); 270 data.writeInt64(frameNumber); 271 data.write(*releaseFence); 272 status_t result = remote()->transact(RELEASE_BUFFER, data, &reply); 273 if (result != NO_ERROR) { 274 return result; 275 } 276 return reply.readInt32(); 277 } 278 279 virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { 280 Parcel data, reply; 281 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 282 data.writeStrongBinder(consumer->asBinder()); 283 data.writeInt32(controlledByApp); 284 status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply); 285 if (result != NO_ERROR) { 286 return result; 287 } 288 return reply.readInt32(); 289 } 290 291 virtual status_t consumerDisconnect() { 292 Parcel data, reply; 293 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 294 status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply); 295 if (result != NO_ERROR) { 296 return result; 297 } 298 return reply.readInt32(); 299 } 300 301 virtual status_t getReleasedBuffers(uint32_t* slotMask) { 302 Parcel data, reply; 303 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 304 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply); 305 if (result != NO_ERROR) { 306 return result; 307 } 308 *slotMask = reply.readInt32(); 309 return reply.readInt32(); 310 } 311 312 virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) { 313 Parcel data, reply; 314 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 315 data.writeInt32(w); 316 data.writeInt32(h); 317 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply); 318 if (result != NO_ERROR) { 319 return result; 320 } 321 return reply.readInt32(); 322 } 323 324 virtual status_t setDefaultMaxBufferCount(int bufferCount) { 325 Parcel data, reply; 326 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 327 data.writeInt32(bufferCount); 328 status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply); 329 if (result != NO_ERROR) { 330 return result; 331 } 332 return reply.readInt32(); 333 } 334 335 virtual status_t disableAsyncBuffer() { 336 Parcel data, reply; 337 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 338 status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply); 339 if (result != NO_ERROR) { 340 return result; 341 } 342 return reply.readInt32(); 343 } 344 345 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 346 Parcel data, reply; 347 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 348 data.writeInt32(maxAcquiredBuffers); 349 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply); 350 if (result != NO_ERROR) { 351 return result; 352 } 353 return reply.readInt32(); 354 } 355 356 virtual void setConsumerName(const String8& name) { 357 Parcel data, reply; 358 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 359 data.writeString8(name); 360 remote()->transact(SET_CONSUMER_NAME, data, &reply); 361 } 362 363 virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) { 364 Parcel data, reply; 365 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 366 data.writeInt32(defaultFormat); 367 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply); 368 if (result != NO_ERROR) { 369 return result; 370 } 371 return reply.readInt32(); 372 } 373 374 virtual status_t setConsumerUsageBits(uint32_t usage) { 375 Parcel data, reply; 376 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 377 data.writeInt32(usage); 378 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply); 379 if (result != NO_ERROR) { 380 return result; 381 } 382 return reply.readInt32(); 383 } 384 385 virtual status_t setTransformHint(uint32_t hint) { 386 Parcel data, reply; 387 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 388 data.writeInt32(hint); 389 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply); 390 if (result != NO_ERROR) { 391 return result; 392 } 393 return reply.readInt32(); 394 } 395 396 virtual sp<NativeHandle> getSidebandStream() const { 397 Parcel data, reply; 398 status_t err; 399 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 400 if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) { 401 return NULL; 402 } 403 sp<NativeHandle> stream; 404 if (reply.readInt32()) { 405 stream = NativeHandle::create(reply.readNativeHandle(), true); 406 } 407 return stream; 408 } 409 410 virtual void dump(String8& result, const char* prefix) const { 411 Parcel data, reply; 412 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 413 data.writeString8(result); 414 data.writeString8(String8(prefix ? prefix : "")); 415 remote()->transact(DUMP, data, &reply); 416 reply.readString8(); 417 } 418}; 419 420IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer"); 421 422// ---------------------------------------------------------------------- 423 424status_t BnGraphicBufferConsumer::onTransact( 425 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 426{ 427 switch(code) { 428 case ACQUIRE_BUFFER: { 429 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 430 BufferItem item; 431 int64_t presentWhen = data.readInt64(); 432 status_t result = acquireBuffer(&item, presentWhen); 433 status_t err = reply->write(item); 434 if (err) return err; 435 reply->writeInt32(result); 436 return NO_ERROR; 437 } break; 438 case DETACH_BUFFER: { 439 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 440 int slot = data.readInt32(); 441 int result = detachBuffer(slot); 442 reply->writeInt32(result); 443 return NO_ERROR; 444 } break; 445 case ATTACH_BUFFER: { 446 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 447 sp<GraphicBuffer> buffer = new GraphicBuffer(); 448 data.read(*buffer.get()); 449 int slot; 450 int result = attachBuffer(&slot, buffer); 451 reply->writeInt32(slot); 452 reply->writeInt32(result); 453 return NO_ERROR; 454 } break; 455 case RELEASE_BUFFER: { 456 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 457 int buf = data.readInt32(); 458 uint64_t frameNumber = data.readInt64(); 459 sp<Fence> releaseFence = new Fence(); 460 status_t err = data.read(*releaseFence); 461 if (err) return err; 462 status_t result = releaseBuffer(buf, frameNumber, 463 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); 464 reply->writeInt32(result); 465 return NO_ERROR; 466 } break; 467 case CONSUMER_CONNECT: { 468 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 469 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() ); 470 bool controlledByApp = data.readInt32(); 471 status_t result = consumerConnect(consumer, controlledByApp); 472 reply->writeInt32(result); 473 return NO_ERROR; 474 } break; 475 case CONSUMER_DISCONNECT: { 476 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 477 status_t result = consumerDisconnect(); 478 reply->writeInt32(result); 479 return NO_ERROR; 480 } break; 481 case GET_RELEASED_BUFFERS: { 482 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 483 uint32_t slotMask; 484 status_t result = getReleasedBuffers(&slotMask); 485 reply->writeInt32(slotMask); 486 reply->writeInt32(result); 487 return NO_ERROR; 488 } break; 489 case SET_DEFAULT_BUFFER_SIZE: { 490 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 491 uint32_t w = data.readInt32(); 492 uint32_t h = data.readInt32(); 493 status_t result = setDefaultBufferSize(w, h); 494 reply->writeInt32(result); 495 return NO_ERROR; 496 } break; 497 case SET_DEFAULT_MAX_BUFFER_COUNT: { 498 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 499 uint32_t bufferCount = data.readInt32(); 500 status_t result = setDefaultMaxBufferCount(bufferCount); 501 reply->writeInt32(result); 502 return NO_ERROR; 503 } break; 504 case DISABLE_ASYNC_BUFFER: { 505 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 506 status_t result = disableAsyncBuffer(); 507 reply->writeInt32(result); 508 return NO_ERROR; 509 } break; 510 case SET_MAX_ACQUIRED_BUFFER_COUNT: { 511 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 512 uint32_t maxAcquiredBuffers = data.readInt32(); 513 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers); 514 reply->writeInt32(result); 515 return NO_ERROR; 516 } break; 517 case SET_CONSUMER_NAME: { 518 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 519 setConsumerName( data.readString8() ); 520 return NO_ERROR; 521 } break; 522 case SET_DEFAULT_BUFFER_FORMAT: { 523 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 524 uint32_t defaultFormat = data.readInt32(); 525 status_t result = setDefaultBufferFormat(defaultFormat); 526 reply->writeInt32(result); 527 return NO_ERROR; 528 } break; 529 case SET_CONSUMER_USAGE_BITS: { 530 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 531 uint32_t usage = data.readInt32(); 532 status_t result = setConsumerUsageBits(usage); 533 reply->writeInt32(result); 534 return NO_ERROR; 535 } break; 536 case SET_TRANSFORM_HINT: { 537 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 538 uint32_t hint = data.readInt32(); 539 status_t result = setTransformHint(hint); 540 reply->writeInt32(result); 541 return NO_ERROR; 542 } break; 543 case DUMP: { 544 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 545 String8 result = data.readString8(); 546 String8 prefix = data.readString8(); 547 static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix); 548 reply->writeString8(result); 549 return NO_ERROR; 550 } 551 } 552 return BBinder::onTransact(code, data, reply, flags); 553} 554 555}; // namespace android 556