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