IGraphicBufferProducer.cpp revision c6f30bdee1f634eb90d68cb76efe935b6535a1e8
1/* 2 * Copyright (C) 2010 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#include <utils/RefBase.h> 23#include <utils/Timers.h> 24#include <utils/Vector.h> 25 26#include <binder/Parcel.h> 27#include <binder/IInterface.h> 28 29#include <gui/IGraphicBufferProducer.h> 30#include <gui/IProducerListener.h> 31 32namespace android { 33// ---------------------------------------------------------------------------- 34 35enum { 36 REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION, 37 SET_BUFFER_COUNT, 38 DEQUEUE_BUFFER, 39 DETACH_BUFFER, 40 DETACH_NEXT_BUFFER, 41 ATTACH_BUFFER, 42 QUEUE_BUFFER, 43 CANCEL_BUFFER, 44 QUERY, 45 CONNECT, 46 DISCONNECT, 47 SET_SIDEBAND_STREAM, 48 ALLOCATE_BUFFERS, 49 ALLOW_ALLOCATION, 50 SET_GENERATION_NUMBER, 51 GET_CONSUMER_NAME, 52}; 53 54class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> 55{ 56public: 57 BpGraphicBufferProducer(const sp<IBinder>& impl) 58 : BpInterface<IGraphicBufferProducer>(impl) 59 { 60 } 61 62 virtual ~BpGraphicBufferProducer(); 63 64 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) { 65 Parcel data, reply; 66 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 67 data.writeInt32(bufferIdx); 68 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply); 69 if (result != NO_ERROR) { 70 return result; 71 } 72 bool nonNull = reply.readInt32(); 73 if (nonNull) { 74 *buf = new GraphicBuffer(); 75 result = reply.read(**buf); 76 if(result != NO_ERROR) { 77 (*buf).clear(); 78 return result; 79 } 80 } 81 result = reply.readInt32(); 82 return result; 83 } 84 85 virtual status_t setBufferCount(int bufferCount) 86 { 87 Parcel data, reply; 88 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 89 data.writeInt32(bufferCount); 90 status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply); 91 if (result != NO_ERROR) { 92 return result; 93 } 94 result = reply.readInt32(); 95 return result; 96 } 97 98 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async, 99 uint32_t width, uint32_t height, PixelFormat format, 100 uint32_t usage) { 101 Parcel data, reply; 102 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 103 data.writeInt32(static_cast<int32_t>(async)); 104 data.writeUint32(width); 105 data.writeUint32(height); 106 data.writeInt32(static_cast<int32_t>(format)); 107 data.writeUint32(usage); 108 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply); 109 if (result != NO_ERROR) { 110 return result; 111 } 112 *buf = reply.readInt32(); 113 bool nonNull = reply.readInt32(); 114 if (nonNull) { 115 *fence = new Fence(); 116 reply.read(**fence); 117 } 118 result = reply.readInt32(); 119 return result; 120 } 121 122 virtual status_t detachBuffer(int slot) { 123 Parcel data, reply; 124 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 125 data.writeInt32(slot); 126 status_t result = remote()->transact(DETACH_BUFFER, data, &reply); 127 if (result != NO_ERROR) { 128 return result; 129 } 130 result = reply.readInt32(); 131 return result; 132 } 133 134 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, 135 sp<Fence>* outFence) { 136 if (outBuffer == NULL) { 137 ALOGE("detachNextBuffer: outBuffer must not be NULL"); 138 return BAD_VALUE; 139 } else if (outFence == NULL) { 140 ALOGE("detachNextBuffer: outFence must not be NULL"); 141 return BAD_VALUE; 142 } 143 Parcel data, reply; 144 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 145 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply); 146 if (result != NO_ERROR) { 147 return result; 148 } 149 result = reply.readInt32(); 150 if (result == NO_ERROR) { 151 bool nonNull = reply.readInt32(); 152 if (nonNull) { 153 *outBuffer = new GraphicBuffer; 154 reply.read(**outBuffer); 155 } 156 nonNull = reply.readInt32(); 157 if (nonNull) { 158 *outFence = new Fence; 159 reply.read(**outFence); 160 } 161 } 162 return result; 163 } 164 165 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) { 166 Parcel data, reply; 167 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 168 data.write(*buffer.get()); 169 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply); 170 if (result != NO_ERROR) { 171 return result; 172 } 173 *slot = reply.readInt32(); 174 result = reply.readInt32(); 175 return result; 176 } 177 178 virtual status_t queueBuffer(int buf, 179 const QueueBufferInput& input, QueueBufferOutput* output) { 180 Parcel data, reply; 181 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 182 data.writeInt32(buf); 183 data.write(input); 184 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply); 185 if (result != NO_ERROR) { 186 return result; 187 } 188 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output)); 189 result = reply.readInt32(); 190 return result; 191 } 192 193 virtual void cancelBuffer(int buf, const sp<Fence>& fence) { 194 Parcel data, reply; 195 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 196 data.writeInt32(buf); 197 data.write(*fence.get()); 198 remote()->transact(CANCEL_BUFFER, data, &reply); 199 } 200 201 virtual int query(int what, int* value) { 202 Parcel data, reply; 203 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 204 data.writeInt32(what); 205 status_t result = remote()->transact(QUERY, data, &reply); 206 if (result != NO_ERROR) { 207 return result; 208 } 209 value[0] = reply.readInt32(); 210 result = reply.readInt32(); 211 return result; 212 } 213 214 virtual status_t connect(const sp<IProducerListener>& listener, 215 int api, bool producerControlledByApp, QueueBufferOutput* output) { 216 Parcel data, reply; 217 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 218 if (listener != NULL) { 219 data.writeInt32(1); 220 data.writeStrongBinder(IInterface::asBinder(listener)); 221 } else { 222 data.writeInt32(0); 223 } 224 data.writeInt32(api); 225 data.writeInt32(producerControlledByApp); 226 status_t result = remote()->transact(CONNECT, data, &reply); 227 if (result != NO_ERROR) { 228 return result; 229 } 230 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output)); 231 result = reply.readInt32(); 232 return result; 233 } 234 235 virtual status_t disconnect(int api) { 236 Parcel data, reply; 237 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 238 data.writeInt32(api); 239 status_t result =remote()->transact(DISCONNECT, data, &reply); 240 if (result != NO_ERROR) { 241 return result; 242 } 243 result = reply.readInt32(); 244 return result; 245 } 246 247 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) { 248 Parcel data, reply; 249 status_t result; 250 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 251 if (stream.get()) { 252 data.writeInt32(true); 253 data.writeNativeHandle(stream->handle()); 254 } else { 255 data.writeInt32(false); 256 } 257 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) { 258 result = reply.readInt32(); 259 } 260 return result; 261 } 262 263 virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, 264 PixelFormat format, uint32_t usage) { 265 Parcel data, reply; 266 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 267 data.writeInt32(static_cast<int32_t>(async)); 268 data.writeUint32(width); 269 data.writeUint32(height); 270 data.writeInt32(static_cast<int32_t>(format)); 271 data.writeUint32(usage); 272 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply); 273 if (result != NO_ERROR) { 274 ALOGE("allocateBuffers failed to transact: %d", result); 275 } 276 } 277 278 virtual status_t allowAllocation(bool allow) { 279 Parcel data, reply; 280 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 281 data.writeInt32(static_cast<int32_t>(allow)); 282 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply); 283 if (result != NO_ERROR) { 284 return result; 285 } 286 result = reply.readInt32(); 287 return result; 288 } 289 290 virtual status_t setGenerationNumber(uint32_t generationNumber) { 291 Parcel data, reply; 292 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 293 data.writeUint32(generationNumber); 294 status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply); 295 if (result == NO_ERROR) { 296 result = reply.readInt32(); 297 } 298 return result; 299 } 300 301 virtual String8 getConsumerName() const { 302 Parcel data, reply; 303 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 304 status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply); 305 if (result != NO_ERROR) { 306 ALOGE("getConsumerName failed to transact: %d", result); 307 return String8("TransactFailed"); 308 } 309 return reply.readString8(); 310 } 311}; 312 313// Out-of-line virtual method definition to trigger vtable emission in this 314// translation unit (see clang warning -Wweak-vtables) 315BpGraphicBufferProducer::~BpGraphicBufferProducer() {} 316 317IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer"); 318 319// ---------------------------------------------------------------------- 320 321status_t BnGraphicBufferProducer::onTransact( 322 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 323{ 324 switch(code) { 325 case REQUEST_BUFFER: { 326 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 327 int bufferIdx = data.readInt32(); 328 sp<GraphicBuffer> buffer; 329 int result = requestBuffer(bufferIdx, &buffer); 330 reply->writeInt32(buffer != 0); 331 if (buffer != 0) { 332 reply->write(*buffer); 333 } 334 reply->writeInt32(result); 335 return NO_ERROR; 336 } 337 case SET_BUFFER_COUNT: { 338 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 339 int bufferCount = data.readInt32(); 340 int result = setBufferCount(bufferCount); 341 reply->writeInt32(result); 342 return NO_ERROR; 343 } 344 case DEQUEUE_BUFFER: { 345 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 346 bool async = static_cast<bool>(data.readInt32()); 347 uint32_t width = data.readUint32(); 348 uint32_t height = data.readUint32(); 349 PixelFormat format = static_cast<PixelFormat>(data.readInt32()); 350 uint32_t usage = data.readUint32(); 351 int buf; 352 sp<Fence> fence; 353 int result = dequeueBuffer(&buf, &fence, async, width, height, 354 format, usage); 355 reply->writeInt32(buf); 356 reply->writeInt32(fence != NULL); 357 if (fence != NULL) { 358 reply->write(*fence); 359 } 360 reply->writeInt32(result); 361 return NO_ERROR; 362 } 363 case DETACH_BUFFER: { 364 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 365 int slot = data.readInt32(); 366 int result = detachBuffer(slot); 367 reply->writeInt32(result); 368 return NO_ERROR; 369 } 370 case DETACH_NEXT_BUFFER: { 371 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 372 sp<GraphicBuffer> buffer; 373 sp<Fence> fence; 374 int32_t result = detachNextBuffer(&buffer, &fence); 375 reply->writeInt32(result); 376 if (result == NO_ERROR) { 377 reply->writeInt32(buffer != NULL); 378 if (buffer != NULL) { 379 reply->write(*buffer); 380 } 381 reply->writeInt32(fence != NULL); 382 if (fence != NULL) { 383 reply->write(*fence); 384 } 385 } 386 return NO_ERROR; 387 } 388 case ATTACH_BUFFER: { 389 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 390 sp<GraphicBuffer> buffer = new GraphicBuffer(); 391 data.read(*buffer.get()); 392 int slot; 393 int result = attachBuffer(&slot, buffer); 394 reply->writeInt32(slot); 395 reply->writeInt32(result); 396 return NO_ERROR; 397 } 398 case QUEUE_BUFFER: { 399 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 400 int buf = data.readInt32(); 401 QueueBufferInput input(data); 402 QueueBufferOutput* const output = 403 reinterpret_cast<QueueBufferOutput *>( 404 reply->writeInplace(sizeof(QueueBufferOutput))); 405 status_t result = queueBuffer(buf, input, output); 406 reply->writeInt32(result); 407 return NO_ERROR; 408 } 409 case CANCEL_BUFFER: { 410 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 411 int buf = data.readInt32(); 412 sp<Fence> fence = new Fence(); 413 data.read(*fence.get()); 414 cancelBuffer(buf, fence); 415 return NO_ERROR; 416 } 417 case QUERY: { 418 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 419 int value; 420 int what = data.readInt32(); 421 int res = query(what, &value); 422 reply->writeInt32(value); 423 reply->writeInt32(res); 424 return NO_ERROR; 425 } 426 case CONNECT: { 427 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 428 sp<IProducerListener> listener; 429 if (data.readInt32() == 1) { 430 listener = IProducerListener::asInterface(data.readStrongBinder()); 431 } 432 int api = data.readInt32(); 433 bool producerControlledByApp = data.readInt32(); 434 QueueBufferOutput* const output = 435 reinterpret_cast<QueueBufferOutput *>( 436 reply->writeInplace(sizeof(QueueBufferOutput))); 437 status_t res = connect(listener, api, producerControlledByApp, output); 438 reply->writeInt32(res); 439 return NO_ERROR; 440 } 441 case DISCONNECT: { 442 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 443 int api = data.readInt32(); 444 status_t res = disconnect(api); 445 reply->writeInt32(res); 446 return NO_ERROR; 447 } 448 case SET_SIDEBAND_STREAM: { 449 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 450 sp<NativeHandle> stream; 451 if (data.readInt32()) { 452 stream = NativeHandle::create(data.readNativeHandle(), true); 453 } 454 status_t result = setSidebandStream(stream); 455 reply->writeInt32(result); 456 return NO_ERROR; 457 } 458 case ALLOCATE_BUFFERS: { 459 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 460 bool async = static_cast<bool>(data.readInt32()); 461 uint32_t width = data.readUint32(); 462 uint32_t height = data.readUint32(); 463 PixelFormat format = static_cast<PixelFormat>(data.readInt32()); 464 uint32_t usage = data.readUint32(); 465 allocateBuffers(async, width, height, format, usage); 466 return NO_ERROR; 467 } 468 case ALLOW_ALLOCATION: { 469 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 470 bool allow = static_cast<bool>(data.readInt32()); 471 status_t result = allowAllocation(allow); 472 reply->writeInt32(result); 473 return NO_ERROR; 474 } 475 case SET_GENERATION_NUMBER: { 476 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 477 uint32_t generationNumber = data.readUint32(); 478 status_t result = setGenerationNumber(generationNumber); 479 reply->writeInt32(result); 480 return NO_ERROR; 481 } 482 case GET_CONSUMER_NAME: { 483 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 484 reply->writeString8(getConsumerName()); 485 return NO_ERROR; 486 } 487 } 488 return BBinder::onTransact(code, data, reply, flags); 489} 490 491// ---------------------------------------------------------------------------- 492 493IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) { 494 parcel.read(*this); 495} 496 497size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const { 498 return sizeof(timestamp) 499 + sizeof(isAutoTimestamp) 500 + sizeof(dataSpace) 501 + sizeof(crop) 502 + sizeof(scalingMode) 503 + sizeof(transform) 504 + sizeof(stickyTransform) 505 + sizeof(async) 506 + fence->getFlattenedSize() 507 + surfaceDamage.getFlattenedSize(); 508} 509 510size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const { 511 return fence->getFdCount(); 512} 513 514status_t IGraphicBufferProducer::QueueBufferInput::flatten( 515 void*& buffer, size_t& size, int*& fds, size_t& count) const 516{ 517 if (size < getFlattenedSize()) { 518 return NO_MEMORY; 519 } 520 FlattenableUtils::write(buffer, size, timestamp); 521 FlattenableUtils::write(buffer, size, isAutoTimestamp); 522 FlattenableUtils::write(buffer, size, dataSpace); 523 FlattenableUtils::write(buffer, size, crop); 524 FlattenableUtils::write(buffer, size, scalingMode); 525 FlattenableUtils::write(buffer, size, transform); 526 FlattenableUtils::write(buffer, size, stickyTransform); 527 FlattenableUtils::write(buffer, size, async); 528 status_t result = fence->flatten(buffer, size, fds, count); 529 if (result != NO_ERROR) { 530 return result; 531 } 532 return surfaceDamage.flatten(buffer, size); 533} 534 535status_t IGraphicBufferProducer::QueueBufferInput::unflatten( 536 void const*& buffer, size_t& size, int const*& fds, size_t& count) 537{ 538 size_t minNeeded = 539 sizeof(timestamp) 540 + sizeof(isAutoTimestamp) 541 + sizeof(dataSpace) 542 + sizeof(crop) 543 + sizeof(scalingMode) 544 + sizeof(transform) 545 + sizeof(stickyTransform) 546 + sizeof(async); 547 548 if (size < minNeeded) { 549 return NO_MEMORY; 550 } 551 552 FlattenableUtils::read(buffer, size, timestamp); 553 FlattenableUtils::read(buffer, size, isAutoTimestamp); 554 FlattenableUtils::read(buffer, size, dataSpace); 555 FlattenableUtils::read(buffer, size, crop); 556 FlattenableUtils::read(buffer, size, scalingMode); 557 FlattenableUtils::read(buffer, size, transform); 558 FlattenableUtils::read(buffer, size, stickyTransform); 559 FlattenableUtils::read(buffer, size, async); 560 561 fence = new Fence(); 562 status_t result = fence->unflatten(buffer, size, fds, count); 563 if (result != NO_ERROR) { 564 return result; 565 } 566 return surfaceDamage.unflatten(buffer, size); 567} 568 569}; // namespace android 570