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