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