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