IGraphicBufferConsumer.cpp revision febd4f4f462444bfcb3f0618d07ac77e3fc1f6ad
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(uint64_t* slotMask) { 302 Parcel data, reply; 303 if (slotMask == NULL) { 304 ALOGE("getReleasedBuffers: slotMask must not be NULL"); 305 return BAD_VALUE; 306 } 307 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 308 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply); 309 if (result != NO_ERROR) { 310 return result; 311 } 312 *slotMask = reply.readInt64(); 313 return reply.readInt32(); 314 } 315 316 virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) { 317 Parcel data, reply; 318 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 319 data.writeInt32(w); 320 data.writeInt32(h); 321 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply); 322 if (result != NO_ERROR) { 323 return result; 324 } 325 return reply.readInt32(); 326 } 327 328 virtual status_t setDefaultMaxBufferCount(int bufferCount) { 329 Parcel data, reply; 330 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 331 data.writeInt32(bufferCount); 332 status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply); 333 if (result != NO_ERROR) { 334 return result; 335 } 336 return reply.readInt32(); 337 } 338 339 virtual status_t disableAsyncBuffer() { 340 Parcel data, reply; 341 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 342 status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply); 343 if (result != NO_ERROR) { 344 return result; 345 } 346 return reply.readInt32(); 347 } 348 349 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 350 Parcel data, reply; 351 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 352 data.writeInt32(maxAcquiredBuffers); 353 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply); 354 if (result != NO_ERROR) { 355 return result; 356 } 357 return reply.readInt32(); 358 } 359 360 virtual void setConsumerName(const String8& name) { 361 Parcel data, reply; 362 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 363 data.writeString8(name); 364 remote()->transact(SET_CONSUMER_NAME, data, &reply); 365 } 366 367 virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) { 368 Parcel data, reply; 369 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 370 data.writeInt32(defaultFormat); 371 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply); 372 if (result != NO_ERROR) { 373 return result; 374 } 375 return reply.readInt32(); 376 } 377 378 virtual status_t setConsumerUsageBits(uint32_t usage) { 379 Parcel data, reply; 380 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 381 data.writeInt32(usage); 382 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply); 383 if (result != NO_ERROR) { 384 return result; 385 } 386 return reply.readInt32(); 387 } 388 389 virtual status_t setTransformHint(uint32_t hint) { 390 Parcel data, reply; 391 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 392 data.writeInt32(hint); 393 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply); 394 if (result != NO_ERROR) { 395 return result; 396 } 397 return reply.readInt32(); 398 } 399 400 virtual sp<NativeHandle> getSidebandStream() const { 401 Parcel data, reply; 402 status_t err; 403 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 404 if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) { 405 return NULL; 406 } 407 sp<NativeHandle> stream; 408 if (reply.readInt32()) { 409 stream = NativeHandle::create(reply.readNativeHandle(), true); 410 } 411 return stream; 412 } 413 414 virtual void dump(String8& result, const char* prefix) const { 415 Parcel data, reply; 416 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 417 data.writeString8(result); 418 data.writeString8(String8(prefix ? prefix : "")); 419 remote()->transact(DUMP, data, &reply); 420 reply.readString8(); 421 } 422}; 423 424IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer"); 425 426// ---------------------------------------------------------------------- 427 428status_t BnGraphicBufferConsumer::onTransact( 429 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 430{ 431 switch(code) { 432 case ACQUIRE_BUFFER: { 433 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 434 BufferItem item; 435 int64_t presentWhen = data.readInt64(); 436 status_t result = acquireBuffer(&item, presentWhen); 437 status_t err = reply->write(item); 438 if (err) return err; 439 reply->writeInt32(result); 440 return NO_ERROR; 441 } break; 442 case DETACH_BUFFER: { 443 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 444 int slot = data.readInt32(); 445 int result = detachBuffer(slot); 446 reply->writeInt32(result); 447 return NO_ERROR; 448 } break; 449 case ATTACH_BUFFER: { 450 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 451 sp<GraphicBuffer> buffer = new GraphicBuffer(); 452 data.read(*buffer.get()); 453 int slot; 454 int result = attachBuffer(&slot, buffer); 455 reply->writeInt32(slot); 456 reply->writeInt32(result); 457 return NO_ERROR; 458 } break; 459 case RELEASE_BUFFER: { 460 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 461 int buf = data.readInt32(); 462 uint64_t frameNumber = data.readInt64(); 463 sp<Fence> releaseFence = new Fence(); 464 status_t err = data.read(*releaseFence); 465 if (err) return err; 466 status_t result = releaseBuffer(buf, frameNumber, 467 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); 468 reply->writeInt32(result); 469 return NO_ERROR; 470 } break; 471 case CONSUMER_CONNECT: { 472 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 473 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() ); 474 bool controlledByApp = data.readInt32(); 475 status_t result = consumerConnect(consumer, controlledByApp); 476 reply->writeInt32(result); 477 return NO_ERROR; 478 } break; 479 case CONSUMER_DISCONNECT: { 480 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 481 status_t result = consumerDisconnect(); 482 reply->writeInt32(result); 483 return NO_ERROR; 484 } break; 485 case GET_RELEASED_BUFFERS: { 486 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 487 uint64_t slotMask; 488 status_t result = getReleasedBuffers(&slotMask); 489 reply->writeInt64(slotMask); 490 reply->writeInt32(result); 491 return NO_ERROR; 492 } break; 493 case SET_DEFAULT_BUFFER_SIZE: { 494 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 495 uint32_t w = data.readInt32(); 496 uint32_t h = data.readInt32(); 497 status_t result = setDefaultBufferSize(w, h); 498 reply->writeInt32(result); 499 return NO_ERROR; 500 } break; 501 case SET_DEFAULT_MAX_BUFFER_COUNT: { 502 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 503 uint32_t bufferCount = data.readInt32(); 504 status_t result = setDefaultMaxBufferCount(bufferCount); 505 reply->writeInt32(result); 506 return NO_ERROR; 507 } break; 508 case DISABLE_ASYNC_BUFFER: { 509 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 510 status_t result = disableAsyncBuffer(); 511 reply->writeInt32(result); 512 return NO_ERROR; 513 } break; 514 case SET_MAX_ACQUIRED_BUFFER_COUNT: { 515 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 516 uint32_t maxAcquiredBuffers = data.readInt32(); 517 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers); 518 reply->writeInt32(result); 519 return NO_ERROR; 520 } break; 521 case SET_CONSUMER_NAME: { 522 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 523 setConsumerName( data.readString8() ); 524 return NO_ERROR; 525 } break; 526 case SET_DEFAULT_BUFFER_FORMAT: { 527 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 528 uint32_t defaultFormat = data.readInt32(); 529 status_t result = setDefaultBufferFormat(defaultFormat); 530 reply->writeInt32(result); 531 return NO_ERROR; 532 } break; 533 case SET_CONSUMER_USAGE_BITS: { 534 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 535 uint32_t usage = data.readInt32(); 536 status_t result = setConsumerUsageBits(usage); 537 reply->writeInt32(result); 538 return NO_ERROR; 539 } break; 540 case SET_TRANSFORM_HINT: { 541 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 542 uint32_t hint = data.readInt32(); 543 status_t result = setTransformHint(hint); 544 reply->writeInt32(result); 545 return NO_ERROR; 546 } break; 547 case DUMP: { 548 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 549 String8 result = data.readString8(); 550 String8 prefix = data.readString8(); 551 static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix); 552 reply->writeString8(result); 553 return NO_ERROR; 554 } 555 } 556 return BBinder::onTransact(code, data, reply, flags); 557} 558 559}; // namespace android 560