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