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 DEQUEUE_BUFFER, 38 DETACH_BUFFER, 39 DETACH_NEXT_BUFFER, 40 ATTACH_BUFFER, 41 QUEUE_BUFFER, 42 CANCEL_BUFFER, 43 QUERY, 44 CONNECT, 45 DISCONNECT, 46 SET_SIDEBAND_STREAM, 47 ALLOCATE_BUFFERS, 48 ALLOW_ALLOCATION, 49 SET_GENERATION_NUMBER, 50 GET_CONSUMER_NAME, 51 SET_MAX_DEQUEUED_BUFFER_COUNT, 52 SET_ASYNC_MODE, 53 GET_NEXT_FRAME_NUMBER, 54 SET_SHARED_BUFFER_MODE, 55 SET_AUTO_REFRESH, 56 SET_DEQUEUE_TIMEOUT, 57 GET_LAST_QUEUED_BUFFER, 58 GET_UNIQUE_ID, 59}; 60 61class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> 62{ 63public: 64 BpGraphicBufferProducer(const sp<IBinder>& impl) 65 : BpInterface<IGraphicBufferProducer>(impl) 66 { 67 } 68 69 virtual ~BpGraphicBufferProducer(); 70 71 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) { 72 Parcel data, reply; 73 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 74 data.writeInt32(bufferIdx); 75 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply); 76 if (result != NO_ERROR) { 77 return result; 78 } 79 bool nonNull = reply.readInt32(); 80 if (nonNull) { 81 *buf = new GraphicBuffer(); 82 result = reply.read(**buf); 83 if(result != NO_ERROR) { 84 (*buf).clear(); 85 return result; 86 } 87 } 88 result = reply.readInt32(); 89 return result; 90 } 91 92 virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) { 93 Parcel data, reply; 94 data.writeInterfaceToken( 95 IGraphicBufferProducer::getInterfaceDescriptor()); 96 data.writeInt32(maxDequeuedBuffers); 97 status_t result = remote()->transact(SET_MAX_DEQUEUED_BUFFER_COUNT, 98 data, &reply); 99 if (result != NO_ERROR) { 100 return result; 101 } 102 result = reply.readInt32(); 103 return result; 104 } 105 106 virtual status_t setAsyncMode(bool async) { 107 Parcel data, reply; 108 data.writeInterfaceToken( 109 IGraphicBufferProducer::getInterfaceDescriptor()); 110 data.writeInt32(async); 111 status_t result = remote()->transact(SET_ASYNC_MODE, 112 data, &reply); 113 if (result != NO_ERROR) { 114 return result; 115 } 116 result = reply.readInt32(); 117 return result; 118 } 119 120 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, uint32_t width, 121 uint32_t height, PixelFormat format, uint32_t usage) { 122 Parcel data, reply; 123 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 124 data.writeUint32(width); 125 data.writeUint32(height); 126 data.writeInt32(static_cast<int32_t>(format)); 127 data.writeUint32(usage); 128 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply); 129 if (result != NO_ERROR) { 130 return result; 131 } 132 *buf = reply.readInt32(); 133 bool nonNull = reply.readInt32(); 134 if (nonNull) { 135 *fence = new Fence(); 136 reply.read(**fence); 137 } 138 result = reply.readInt32(); 139 return result; 140 } 141 142 virtual status_t detachBuffer(int slot) { 143 Parcel data, reply; 144 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 145 data.writeInt32(slot); 146 status_t result = remote()->transact(DETACH_BUFFER, data, &reply); 147 if (result != NO_ERROR) { 148 return result; 149 } 150 result = reply.readInt32(); 151 return result; 152 } 153 154 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, 155 sp<Fence>* outFence) { 156 if (outBuffer == NULL) { 157 ALOGE("detachNextBuffer: outBuffer must not be NULL"); 158 return BAD_VALUE; 159 } else if (outFence == NULL) { 160 ALOGE("detachNextBuffer: outFence must not be NULL"); 161 return BAD_VALUE; 162 } 163 Parcel data, reply; 164 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 165 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply); 166 if (result != NO_ERROR) { 167 return result; 168 } 169 result = reply.readInt32(); 170 if (result == NO_ERROR) { 171 bool nonNull = reply.readInt32(); 172 if (nonNull) { 173 *outBuffer = new GraphicBuffer; 174 reply.read(**outBuffer); 175 } 176 nonNull = reply.readInt32(); 177 if (nonNull) { 178 *outFence = new Fence; 179 reply.read(**outFence); 180 } 181 } 182 return result; 183 } 184 185 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) { 186 Parcel data, reply; 187 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 188 data.write(*buffer.get()); 189 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply); 190 if (result != NO_ERROR) { 191 return result; 192 } 193 *slot = reply.readInt32(); 194 result = reply.readInt32(); 195 return result; 196 } 197 198 virtual status_t queueBuffer(int buf, 199 const QueueBufferInput& input, QueueBufferOutput* output) { 200 Parcel data, reply; 201 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 202 data.writeInt32(buf); 203 data.write(input); 204 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply); 205 if (result != NO_ERROR) { 206 return result; 207 } 208 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output)); 209 result = reply.readInt32(); 210 return result; 211 } 212 213 virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) { 214 Parcel data, reply; 215 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 216 data.writeInt32(buf); 217 data.write(*fence.get()); 218 status_t result = remote()->transact(CANCEL_BUFFER, data, &reply); 219 if (result != NO_ERROR) { 220 return result; 221 } 222 result = reply.readInt32(); 223 return result; 224 } 225 226 virtual int query(int what, int* value) { 227 Parcel data, reply; 228 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 229 data.writeInt32(what); 230 status_t result = remote()->transact(QUERY, data, &reply); 231 if (result != NO_ERROR) { 232 return result; 233 } 234 value[0] = reply.readInt32(); 235 result = reply.readInt32(); 236 return result; 237 } 238 239 virtual status_t connect(const sp<IProducerListener>& listener, 240 int api, bool producerControlledByApp, QueueBufferOutput* output) { 241 Parcel data, reply; 242 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 243 if (listener != NULL) { 244 data.writeInt32(1); 245 data.writeStrongBinder(IInterface::asBinder(listener)); 246 } else { 247 data.writeInt32(0); 248 } 249 data.writeInt32(api); 250 data.writeInt32(producerControlledByApp); 251 status_t result = remote()->transact(CONNECT, data, &reply); 252 if (result != NO_ERROR) { 253 return result; 254 } 255 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output)); 256 result = reply.readInt32(); 257 return result; 258 } 259 260 virtual status_t disconnect(int api) { 261 Parcel data, reply; 262 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 263 data.writeInt32(api); 264 status_t result =remote()->transact(DISCONNECT, data, &reply); 265 if (result != NO_ERROR) { 266 return result; 267 } 268 result = reply.readInt32(); 269 return result; 270 } 271 272 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) { 273 Parcel data, reply; 274 status_t result; 275 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 276 if (stream.get()) { 277 data.writeInt32(true); 278 data.writeNativeHandle(stream->handle()); 279 } else { 280 data.writeInt32(false); 281 } 282 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) { 283 result = reply.readInt32(); 284 } 285 return result; 286 } 287 288 virtual void allocateBuffers(uint32_t width, uint32_t height, 289 PixelFormat format, uint32_t usage) { 290 Parcel data, reply; 291 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 292 data.writeUint32(width); 293 data.writeUint32(height); 294 data.writeInt32(static_cast<int32_t>(format)); 295 data.writeUint32(usage); 296 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply); 297 if (result != NO_ERROR) { 298 ALOGE("allocateBuffers failed to transact: %d", result); 299 } 300 } 301 302 virtual status_t allowAllocation(bool allow) { 303 Parcel data, reply; 304 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 305 data.writeInt32(static_cast<int32_t>(allow)); 306 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply); 307 if (result != NO_ERROR) { 308 return result; 309 } 310 result = reply.readInt32(); 311 return result; 312 } 313 314 virtual status_t setGenerationNumber(uint32_t generationNumber) { 315 Parcel data, reply; 316 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 317 data.writeUint32(generationNumber); 318 status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply); 319 if (result == NO_ERROR) { 320 result = reply.readInt32(); 321 } 322 return result; 323 } 324 325 virtual String8 getConsumerName() const { 326 Parcel data, reply; 327 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 328 status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply); 329 if (result != NO_ERROR) { 330 ALOGE("getConsumerName failed to transact: %d", result); 331 return String8("TransactFailed"); 332 } 333 return reply.readString8(); 334 } 335 336 virtual uint64_t getNextFrameNumber() const { 337 Parcel data, reply; 338 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 339 status_t result = remote()->transact(GET_NEXT_FRAME_NUMBER, data, &reply); 340 if (result != NO_ERROR) { 341 ALOGE("getNextFrameNumber failed to transact: %d", result); 342 return 0; 343 } 344 uint64_t frameNumber = reply.readUint64(); 345 return frameNumber; 346 } 347 348 virtual status_t setSharedBufferMode(bool sharedBufferMode) { 349 Parcel data, reply; 350 data.writeInterfaceToken( 351 IGraphicBufferProducer::getInterfaceDescriptor()); 352 data.writeInt32(sharedBufferMode); 353 status_t result = remote()->transact(SET_SHARED_BUFFER_MODE, data, 354 &reply); 355 if (result == NO_ERROR) { 356 result = reply.readInt32(); 357 } 358 return result; 359 } 360 361 virtual status_t setAutoRefresh(bool autoRefresh) { 362 Parcel data, reply; 363 data.writeInterfaceToken( 364 IGraphicBufferProducer::getInterfaceDescriptor()); 365 data.writeInt32(autoRefresh); 366 status_t result = remote()->transact(SET_AUTO_REFRESH, data, &reply); 367 if (result == NO_ERROR) { 368 result = reply.readInt32(); 369 } 370 return result; 371 } 372 373 virtual status_t setDequeueTimeout(nsecs_t timeout) { 374 Parcel data, reply; 375 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 376 data.writeInt64(timeout); 377 status_t result = remote()->transact(SET_DEQUEUE_TIMEOUT, data, &reply); 378 if (result != NO_ERROR) { 379 ALOGE("setDequeueTimeout failed to transact: %d", result); 380 return result; 381 } 382 return reply.readInt32(); 383 } 384 385 virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, 386 sp<Fence>* outFence, float outTransformMatrix[16]) override { 387 Parcel data, reply; 388 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 389 status_t result = remote()->transact(GET_LAST_QUEUED_BUFFER, data, 390 &reply); 391 if (result != NO_ERROR) { 392 ALOGE("getLastQueuedBuffer failed to transact: %d", result); 393 return result; 394 } 395 result = reply.readInt32(); 396 if (result != NO_ERROR) { 397 return result; 398 } 399 bool hasBuffer = reply.readBool(); 400 sp<GraphicBuffer> buffer; 401 if (hasBuffer) { 402 buffer = new GraphicBuffer(); 403 result = reply.read(*buffer); 404 if (result == NO_ERROR) { 405 result = reply.read(outTransformMatrix, sizeof(float) * 16); 406 } 407 } 408 if (result != NO_ERROR) { 409 ALOGE("getLastQueuedBuffer failed to read buffer: %d", result); 410 return result; 411 } 412 sp<Fence> fence(new Fence); 413 result = reply.read(*fence); 414 if (result != NO_ERROR) { 415 ALOGE("getLastQueuedBuffer failed to read fence: %d", result); 416 return result; 417 } 418 *outBuffer = buffer; 419 *outFence = fence; 420 return result; 421 } 422 423 virtual status_t getUniqueId(uint64_t* outId) const { 424 Parcel data, reply; 425 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 426 status_t result = remote()->transact(GET_UNIQUE_ID, data, &reply); 427 if (result != NO_ERROR) { 428 ALOGE("getUniqueId failed to transact: %d", result); 429 } 430 status_t actualResult = NO_ERROR; 431 result = reply.readInt32(&actualResult); 432 if (result != NO_ERROR) { 433 return result; 434 } 435 result = reply.readUint64(outId); 436 if (result != NO_ERROR) { 437 return result; 438 } 439 return actualResult; 440 } 441}; 442 443// Out-of-line virtual method definition to trigger vtable emission in this 444// translation unit (see clang warning -Wweak-vtables) 445BpGraphicBufferProducer::~BpGraphicBufferProducer() {} 446 447IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer"); 448 449// ---------------------------------------------------------------------- 450 451status_t BnGraphicBufferProducer::onTransact( 452 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 453{ 454 switch(code) { 455 case REQUEST_BUFFER: { 456 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 457 int bufferIdx = data.readInt32(); 458 sp<GraphicBuffer> buffer; 459 int result = requestBuffer(bufferIdx, &buffer); 460 reply->writeInt32(buffer != 0); 461 if (buffer != 0) { 462 reply->write(*buffer); 463 } 464 reply->writeInt32(result); 465 return NO_ERROR; 466 } 467 case SET_MAX_DEQUEUED_BUFFER_COUNT: { 468 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 469 int maxDequeuedBuffers = data.readInt32(); 470 int result = setMaxDequeuedBufferCount(maxDequeuedBuffers); 471 reply->writeInt32(result); 472 return NO_ERROR; 473 } 474 case SET_ASYNC_MODE: { 475 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 476 bool async = data.readInt32(); 477 int result = setAsyncMode(async); 478 reply->writeInt32(result); 479 return NO_ERROR; 480 } 481 case DEQUEUE_BUFFER: { 482 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 483 uint32_t width = data.readUint32(); 484 uint32_t height = data.readUint32(); 485 PixelFormat format = static_cast<PixelFormat>(data.readInt32()); 486 uint32_t usage = data.readUint32(); 487 int buf = 0; 488 sp<Fence> fence; 489 int result = dequeueBuffer(&buf, &fence, width, height, format, 490 usage); 491 reply->writeInt32(buf); 492 reply->writeInt32(fence != NULL); 493 if (fence != NULL) { 494 reply->write(*fence); 495 } 496 reply->writeInt32(result); 497 return NO_ERROR; 498 } 499 case DETACH_BUFFER: { 500 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 501 int slot = data.readInt32(); 502 int result = detachBuffer(slot); 503 reply->writeInt32(result); 504 return NO_ERROR; 505 } 506 case DETACH_NEXT_BUFFER: { 507 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 508 sp<GraphicBuffer> buffer; 509 sp<Fence> fence; 510 int32_t result = detachNextBuffer(&buffer, &fence); 511 reply->writeInt32(result); 512 if (result == NO_ERROR) { 513 reply->writeInt32(buffer != NULL); 514 if (buffer != NULL) { 515 reply->write(*buffer); 516 } 517 reply->writeInt32(fence != NULL); 518 if (fence != NULL) { 519 reply->write(*fence); 520 } 521 } 522 return NO_ERROR; 523 } 524 case ATTACH_BUFFER: { 525 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 526 sp<GraphicBuffer> buffer = new GraphicBuffer(); 527 data.read(*buffer.get()); 528 int slot = 0; 529 int result = attachBuffer(&slot, buffer); 530 reply->writeInt32(slot); 531 reply->writeInt32(result); 532 return NO_ERROR; 533 } 534 case QUEUE_BUFFER: { 535 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 536 int buf = data.readInt32(); 537 QueueBufferInput input(data); 538 QueueBufferOutput* const output = 539 reinterpret_cast<QueueBufferOutput *>( 540 reply->writeInplace(sizeof(QueueBufferOutput))); 541 memset(output, 0, sizeof(QueueBufferOutput)); 542 status_t result = queueBuffer(buf, input, output); 543 reply->writeInt32(result); 544 return NO_ERROR; 545 } 546 case CANCEL_BUFFER: { 547 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 548 int buf = data.readInt32(); 549 sp<Fence> fence = new Fence(); 550 data.read(*fence.get()); 551 status_t result = cancelBuffer(buf, fence); 552 reply->writeInt32(result); 553 return NO_ERROR; 554 } 555 case QUERY: { 556 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 557 int value = 0; 558 int what = data.readInt32(); 559 int res = query(what, &value); 560 reply->writeInt32(value); 561 reply->writeInt32(res); 562 return NO_ERROR; 563 } 564 case CONNECT: { 565 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 566 sp<IProducerListener> listener; 567 if (data.readInt32() == 1) { 568 listener = IProducerListener::asInterface(data.readStrongBinder()); 569 } 570 int api = data.readInt32(); 571 bool producerControlledByApp = data.readInt32(); 572 QueueBufferOutput* const output = 573 reinterpret_cast<QueueBufferOutput *>( 574 reply->writeInplace(sizeof(QueueBufferOutput))); 575 memset(output, 0, sizeof(QueueBufferOutput)); 576 status_t res = connect(listener, api, producerControlledByApp, output); 577 reply->writeInt32(res); 578 return NO_ERROR; 579 } 580 case DISCONNECT: { 581 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 582 int api = data.readInt32(); 583 status_t res = disconnect(api); 584 reply->writeInt32(res); 585 return NO_ERROR; 586 } 587 case SET_SIDEBAND_STREAM: { 588 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 589 sp<NativeHandle> stream; 590 if (data.readInt32()) { 591 stream = NativeHandle::create(data.readNativeHandle(), true); 592 } 593 status_t result = setSidebandStream(stream); 594 reply->writeInt32(result); 595 return NO_ERROR; 596 } 597 case ALLOCATE_BUFFERS: { 598 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 599 uint32_t width = data.readUint32(); 600 uint32_t height = data.readUint32(); 601 PixelFormat format = static_cast<PixelFormat>(data.readInt32()); 602 uint32_t usage = data.readUint32(); 603 allocateBuffers(width, height, format, usage); 604 return NO_ERROR; 605 } 606 case ALLOW_ALLOCATION: { 607 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 608 bool allow = static_cast<bool>(data.readInt32()); 609 status_t result = allowAllocation(allow); 610 reply->writeInt32(result); 611 return NO_ERROR; 612 } 613 case SET_GENERATION_NUMBER: { 614 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 615 uint32_t generationNumber = data.readUint32(); 616 status_t result = setGenerationNumber(generationNumber); 617 reply->writeInt32(result); 618 return NO_ERROR; 619 } 620 case GET_CONSUMER_NAME: { 621 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 622 reply->writeString8(getConsumerName()); 623 return NO_ERROR; 624 } 625 case GET_NEXT_FRAME_NUMBER: { 626 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 627 uint64_t frameNumber = getNextFrameNumber(); 628 reply->writeUint64(frameNumber); 629 return NO_ERROR; 630 } 631 case SET_SHARED_BUFFER_MODE: { 632 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 633 bool sharedBufferMode = data.readInt32(); 634 status_t result = setSharedBufferMode(sharedBufferMode); 635 reply->writeInt32(result); 636 return NO_ERROR; 637 } 638 case SET_AUTO_REFRESH: { 639 CHECK_INTERFACE(IGraphicBuffer, data, reply); 640 bool autoRefresh = data.readInt32(); 641 status_t result = setAutoRefresh(autoRefresh); 642 reply->writeInt32(result); 643 return NO_ERROR; 644 } 645 case SET_DEQUEUE_TIMEOUT: { 646 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 647 nsecs_t timeout = data.readInt64(); 648 status_t result = setDequeueTimeout(timeout); 649 reply->writeInt32(result); 650 return NO_ERROR; 651 } 652 case GET_LAST_QUEUED_BUFFER: { 653 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 654 sp<GraphicBuffer> buffer(nullptr); 655 sp<Fence> fence(Fence::NO_FENCE); 656 float transform[16] = {}; 657 status_t result = getLastQueuedBuffer(&buffer, &fence, transform); 658 reply->writeInt32(result); 659 if (result != NO_ERROR) { 660 return result; 661 } 662 if (!buffer.get()) { 663 reply->writeBool(false); 664 } else { 665 reply->writeBool(true); 666 result = reply->write(*buffer); 667 if (result == NO_ERROR) { 668 reply->write(transform, sizeof(float) * 16); 669 } 670 } 671 if (result != NO_ERROR) { 672 ALOGE("getLastQueuedBuffer failed to write buffer: %d", result); 673 return result; 674 } 675 result = reply->write(*fence); 676 if (result != NO_ERROR) { 677 ALOGE("getLastQueuedBuffer failed to write fence: %d", result); 678 return result; 679 } 680 return NO_ERROR; 681 } 682 case GET_UNIQUE_ID: { 683 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 684 uint64_t outId = 0; 685 status_t actualResult = getUniqueId(&outId); 686 status_t result = reply->writeInt32(actualResult); 687 if (result != NO_ERROR) { 688 return result; 689 } 690 result = reply->writeUint64(outId); 691 if (result != NO_ERROR) { 692 return result; 693 } 694 return NO_ERROR; 695 } 696 } 697 return BBinder::onTransact(code, data, reply, flags); 698} 699 700// ---------------------------------------------------------------------------- 701 702IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) { 703 parcel.read(*this); 704} 705 706size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const { 707 return sizeof(timestamp) 708 + sizeof(isAutoTimestamp) 709 + sizeof(dataSpace) 710 + sizeof(crop) 711 + sizeof(scalingMode) 712 + sizeof(transform) 713 + sizeof(stickyTransform) 714 + fence->getFlattenedSize() 715 + surfaceDamage.getFlattenedSize(); 716} 717 718size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const { 719 return fence->getFdCount(); 720} 721 722status_t IGraphicBufferProducer::QueueBufferInput::flatten( 723 void*& buffer, size_t& size, int*& fds, size_t& count) const 724{ 725 if (size < getFlattenedSize()) { 726 return NO_MEMORY; 727 } 728 FlattenableUtils::write(buffer, size, timestamp); 729 FlattenableUtils::write(buffer, size, isAutoTimestamp); 730 FlattenableUtils::write(buffer, size, dataSpace); 731 FlattenableUtils::write(buffer, size, crop); 732 FlattenableUtils::write(buffer, size, scalingMode); 733 FlattenableUtils::write(buffer, size, transform); 734 FlattenableUtils::write(buffer, size, stickyTransform); 735 status_t result = fence->flatten(buffer, size, fds, count); 736 if (result != NO_ERROR) { 737 return result; 738 } 739 return surfaceDamage.flatten(buffer, size); 740} 741 742status_t IGraphicBufferProducer::QueueBufferInput::unflatten( 743 void const*& buffer, size_t& size, int const*& fds, size_t& count) 744{ 745 size_t minNeeded = 746 sizeof(timestamp) 747 + sizeof(isAutoTimestamp) 748 + sizeof(dataSpace) 749 + sizeof(crop) 750 + sizeof(scalingMode) 751 + sizeof(transform) 752 + sizeof(stickyTransform); 753 754 if (size < minNeeded) { 755 return NO_MEMORY; 756 } 757 758 FlattenableUtils::read(buffer, size, timestamp); 759 FlattenableUtils::read(buffer, size, isAutoTimestamp); 760 FlattenableUtils::read(buffer, size, dataSpace); 761 FlattenableUtils::read(buffer, size, crop); 762 FlattenableUtils::read(buffer, size, scalingMode); 763 FlattenableUtils::read(buffer, size, transform); 764 FlattenableUtils::read(buffer, size, stickyTransform); 765 766 fence = new Fence(); 767 status_t result = fence->unflatten(buffer, size, fds, count); 768 if (result != NO_ERROR) { 769 return result; 770 } 771 return surfaceDamage.unflatten(buffer, size); 772} 773 774}; // namespace android 775