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#define LOG_TAG "Surface" 18#define ATRACE_TAG ATRACE_TAG_GRAPHICS 19//#define LOG_NDEBUG 0 20 21#include <android/native_window.h> 22 23#include <binder/Parcel.h> 24 25#include <utils/Log.h> 26#include <utils/Trace.h> 27#include <utils/NativeHandle.h> 28 29#include <ui/Fence.h> 30#include <ui/Region.h> 31 32#include <gui/IProducerListener.h> 33#include <gui/ISurfaceComposer.h> 34#include <gui/SurfaceComposerClient.h> 35#include <gui/GLConsumer.h> 36#include <gui/Surface.h> 37 38#include <private/gui/ComposerService.h> 39 40namespace android { 41 42Surface::Surface( 43 const sp<IGraphicBufferProducer>& bufferProducer, 44 bool controlledByApp) 45 : mGraphicBufferProducer(bufferProducer), 46 mCrop(Rect::EMPTY_RECT), 47 mGenerationNumber(0), 48 mSharedBufferMode(false), 49 mAutoRefresh(false), 50 mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), 51 mSharedBufferHasBeenQueued(false) 52{ 53 // Initialize the ANativeWindow function pointers. 54 ANativeWindow::setSwapInterval = hook_setSwapInterval; 55 ANativeWindow::dequeueBuffer = hook_dequeueBuffer; 56 ANativeWindow::cancelBuffer = hook_cancelBuffer; 57 ANativeWindow::queueBuffer = hook_queueBuffer; 58 ANativeWindow::query = hook_query; 59 ANativeWindow::perform = hook_perform; 60 61 ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED; 62 ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED; 63 ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED; 64 ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED; 65 66 const_cast<int&>(ANativeWindow::minSwapInterval) = 0; 67 const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; 68 69 mReqWidth = 0; 70 mReqHeight = 0; 71 mReqFormat = 0; 72 mReqUsage = 0; 73 mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; 74 mDataSpace = HAL_DATASPACE_UNKNOWN; 75 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 76 mTransform = 0; 77 mStickyTransform = 0; 78 mDefaultWidth = 0; 79 mDefaultHeight = 0; 80 mUserWidth = 0; 81 mUserHeight = 0; 82 mTransformHint = 0; 83 mConsumerRunningBehind = false; 84 mConnectedToCpu = false; 85 mProducerControlledByApp = controlledByApp; 86 mSwapIntervalZero = false; 87} 88 89Surface::~Surface() { 90 if (mConnectedToCpu) { 91 Surface::disconnect(NATIVE_WINDOW_API_CPU); 92 } 93} 94 95sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const { 96 return mGraphicBufferProducer; 97} 98 99void Surface::setSidebandStream(const sp<NativeHandle>& stream) { 100 mGraphicBufferProducer->setSidebandStream(stream); 101} 102 103void Surface::allocateBuffers() { 104 uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth; 105 uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight; 106 mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight, 107 mReqFormat, mReqUsage); 108} 109 110status_t Surface::setGenerationNumber(uint32_t generation) { 111 status_t result = mGraphicBufferProducer->setGenerationNumber(generation); 112 if (result == NO_ERROR) { 113 mGenerationNumber = generation; 114 } 115 return result; 116} 117 118uint64_t Surface::getNextFrameNumber() const { 119 return mGraphicBufferProducer->getNextFrameNumber(); 120} 121 122String8 Surface::getConsumerName() const { 123 return mGraphicBufferProducer->getConsumerName(); 124} 125 126status_t Surface::setDequeueTimeout(nsecs_t timeout) { 127 return mGraphicBufferProducer->setDequeueTimeout(timeout); 128} 129 130status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, 131 sp<Fence>* outFence, float outTransformMatrix[16]) { 132 return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence, 133 outTransformMatrix); 134} 135 136int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { 137 Surface* c = getSelf(window); 138 return c->setSwapInterval(interval); 139} 140 141int Surface::hook_dequeueBuffer(ANativeWindow* window, 142 ANativeWindowBuffer** buffer, int* fenceFd) { 143 Surface* c = getSelf(window); 144 return c->dequeueBuffer(buffer, fenceFd); 145} 146 147int Surface::hook_cancelBuffer(ANativeWindow* window, 148 ANativeWindowBuffer* buffer, int fenceFd) { 149 Surface* c = getSelf(window); 150 return c->cancelBuffer(buffer, fenceFd); 151} 152 153int Surface::hook_queueBuffer(ANativeWindow* window, 154 ANativeWindowBuffer* buffer, int fenceFd) { 155 Surface* c = getSelf(window); 156 return c->queueBuffer(buffer, fenceFd); 157} 158 159int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, 160 ANativeWindowBuffer** buffer) { 161 Surface* c = getSelf(window); 162 ANativeWindowBuffer* buf; 163 int fenceFd = -1; 164 int result = c->dequeueBuffer(&buf, &fenceFd); 165 if (result != OK) { 166 return result; 167 } 168 sp<Fence> fence(new Fence(fenceFd)); 169 int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED"); 170 if (waitResult != OK) { 171 ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d", 172 waitResult); 173 c->cancelBuffer(buf, -1); 174 return waitResult; 175 } 176 *buffer = buf; 177 return result; 178} 179 180int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window, 181 ANativeWindowBuffer* buffer) { 182 Surface* c = getSelf(window); 183 return c->cancelBuffer(buffer, -1); 184} 185 186int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window, 187 ANativeWindowBuffer* buffer) { 188 Surface* c = getSelf(window); 189 return c->lockBuffer_DEPRECATED(buffer); 190} 191 192int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window, 193 ANativeWindowBuffer* buffer) { 194 Surface* c = getSelf(window); 195 return c->queueBuffer(buffer, -1); 196} 197 198int Surface::hook_query(const ANativeWindow* window, 199 int what, int* value) { 200 const Surface* c = getSelf(window); 201 return c->query(what, value); 202} 203 204int Surface::hook_perform(ANativeWindow* window, int operation, ...) { 205 va_list args; 206 va_start(args, operation); 207 Surface* c = getSelf(window); 208 int result = c->perform(operation, args); 209 va_end(args); 210 return result; 211} 212 213int Surface::setSwapInterval(int interval) { 214 ATRACE_CALL(); 215 // EGL specification states: 216 // interval is silently clamped to minimum and maximum implementation 217 // dependent values before being stored. 218 219 if (interval < minSwapInterval) 220 interval = minSwapInterval; 221 222 if (interval > maxSwapInterval) 223 interval = maxSwapInterval; 224 225 mSwapIntervalZero = (interval == 0); 226 mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero); 227 228 return NO_ERROR; 229} 230 231int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { 232 ATRACE_CALL(); 233 ALOGV("Surface::dequeueBuffer"); 234 235 uint32_t reqWidth; 236 uint32_t reqHeight; 237 PixelFormat reqFormat; 238 uint32_t reqUsage; 239 240 { 241 Mutex::Autolock lock(mMutex); 242 243 reqWidth = mReqWidth ? mReqWidth : mUserWidth; 244 reqHeight = mReqHeight ? mReqHeight : mUserHeight; 245 246 reqFormat = mReqFormat; 247 reqUsage = mReqUsage; 248 249 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot != 250 BufferItem::INVALID_BUFFER_SLOT) { 251 sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer); 252 if (gbuf != NULL) { 253 *buffer = gbuf.get(); 254 *fenceFd = -1; 255 return OK; 256 } 257 } 258 } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer 259 260 int buf = -1; 261 sp<Fence> fence; 262 status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, 263 reqWidth, reqHeight, reqFormat, reqUsage); 264 265 if (result < 0) { 266 ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer" 267 "(%d, %d, %d, %d) failed: %d", reqWidth, reqHeight, reqFormat, 268 reqUsage, result); 269 return result; 270 } 271 272 Mutex::Autolock lock(mMutex); 273 274 sp<GraphicBuffer>& gbuf(mSlots[buf].buffer); 275 276 // this should never happen 277 ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); 278 279 if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { 280 freeAllBuffers(); 281 } 282 283 if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { 284 result = mGraphicBufferProducer->requestBuffer(buf, &gbuf); 285 if (result != NO_ERROR) { 286 ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result); 287 mGraphicBufferProducer->cancelBuffer(buf, fence); 288 return result; 289 } 290 } 291 292 if (fence->isValid()) { 293 *fenceFd = fence->dup(); 294 if (*fenceFd == -1) { 295 ALOGE("dequeueBuffer: error duping fence: %d", errno); 296 // dup() should never fail; something is badly wrong. Soldier on 297 // and hope for the best; the worst that should happen is some 298 // visible corruption that lasts until the next frame. 299 } 300 } else { 301 *fenceFd = -1; 302 } 303 304 *buffer = gbuf.get(); 305 306 if (mSharedBufferMode && mAutoRefresh) { 307 mSharedBufferSlot = buf; 308 mSharedBufferHasBeenQueued = false; 309 } else if (mSharedBufferSlot == buf) { 310 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 311 mSharedBufferHasBeenQueued = false; 312 } 313 314 return OK; 315} 316 317int Surface::cancelBuffer(android_native_buffer_t* buffer, 318 int fenceFd) { 319 ATRACE_CALL(); 320 ALOGV("Surface::cancelBuffer"); 321 Mutex::Autolock lock(mMutex); 322 int i = getSlotFromBufferLocked(buffer); 323 if (i < 0) { 324 if (fenceFd >= 0) { 325 close(fenceFd); 326 } 327 return i; 328 } 329 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) { 330 if (fenceFd >= 0) { 331 close(fenceFd); 332 } 333 return OK; 334 } 335 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); 336 mGraphicBufferProducer->cancelBuffer(i, fence); 337 338 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { 339 mSharedBufferHasBeenQueued = true; 340 } 341 342 return OK; 343} 344 345int Surface::getSlotFromBufferLocked( 346 android_native_buffer_t* buffer) const { 347 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 348 if (mSlots[i].buffer != NULL && 349 mSlots[i].buffer->handle == buffer->handle) { 350 return i; 351 } 352 } 353 ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle); 354 return BAD_VALUE; 355} 356 357int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) { 358 ALOGV("Surface::lockBuffer"); 359 Mutex::Autolock lock(mMutex); 360 return OK; 361} 362 363int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { 364 ATRACE_CALL(); 365 ALOGV("Surface::queueBuffer"); 366 Mutex::Autolock lock(mMutex); 367 int64_t timestamp; 368 bool isAutoTimestamp = false; 369 370 if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) { 371 timestamp = systemTime(SYSTEM_TIME_MONOTONIC); 372 isAutoTimestamp = true; 373 ALOGV("Surface::queueBuffer making up timestamp: %.2f ms", 374 timestamp / 1000000.f); 375 } else { 376 timestamp = mTimestamp; 377 } 378 int i = getSlotFromBufferLocked(buffer); 379 if (i < 0) { 380 if (fenceFd >= 0) { 381 close(fenceFd); 382 } 383 return i; 384 } 385 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) { 386 if (fenceFd >= 0) { 387 close(fenceFd); 388 } 389 return OK; 390 } 391 392 393 // Make sure the crop rectangle is entirely inside the buffer. 394 Rect crop(Rect::EMPTY_RECT); 395 mCrop.intersect(Rect(buffer->width, buffer->height), &crop); 396 397 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); 398 IGraphicBufferProducer::QueueBufferOutput output; 399 IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, 400 mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform, 401 fence, mStickyTransform); 402 403 if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) { 404 input.setSurfaceDamage(Region::INVALID_REGION); 405 } else { 406 // Here we do two things: 407 // 1) The surface damage was specified using the OpenGL ES convention of 408 // the origin being in the bottom-left corner. Here we flip to the 409 // convention that the rest of the system uses (top-left corner) by 410 // subtracting all top/bottom coordinates from the buffer height. 411 // 2) If the buffer is coming in rotated (for example, because the EGL 412 // implementation is reacting to the transform hint coming back from 413 // SurfaceFlinger), the surface damage needs to be rotated the 414 // opposite direction, since it was generated assuming an unrotated 415 // buffer (the app doesn't know that the EGL implementation is 416 // reacting to the transform hint behind its back). The 417 // transformations in the switch statement below apply those 418 // complementary rotations (e.g., if 90 degrees, rotate 270 degrees). 419 420 int width = buffer->width; 421 int height = buffer->height; 422 bool rotated90 = (mTransform ^ mStickyTransform) & 423 NATIVE_WINDOW_TRANSFORM_ROT_90; 424 if (rotated90) { 425 std::swap(width, height); 426 } 427 428 Region flippedRegion; 429 for (auto rect : mDirtyRegion) { 430 int left = rect.left; 431 int right = rect.right; 432 int top = height - rect.bottom; // Flip from OpenGL convention 433 int bottom = height - rect.top; // Flip from OpenGL convention 434 switch (mTransform ^ mStickyTransform) { 435 case NATIVE_WINDOW_TRANSFORM_ROT_90: { 436 // Rotate 270 degrees 437 Rect flippedRect{top, width - right, bottom, width - left}; 438 flippedRegion.orSelf(flippedRect); 439 break; 440 } 441 case NATIVE_WINDOW_TRANSFORM_ROT_180: { 442 // Rotate 180 degrees 443 Rect flippedRect{width - right, height - bottom, 444 width - left, height - top}; 445 flippedRegion.orSelf(flippedRect); 446 break; 447 } 448 case NATIVE_WINDOW_TRANSFORM_ROT_270: { 449 // Rotate 90 degrees 450 Rect flippedRect{height - bottom, left, 451 height - top, right}; 452 flippedRegion.orSelf(flippedRect); 453 break; 454 } 455 default: { 456 Rect flippedRect{left, top, right, bottom}; 457 flippedRegion.orSelf(flippedRect); 458 break; 459 } 460 } 461 } 462 463 input.setSurfaceDamage(flippedRegion); 464 } 465 466 status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); 467 if (err != OK) { 468 ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); 469 } 470 471 uint32_t numPendingBuffers = 0; 472 uint32_t hint = 0; 473 output.deflate(&mDefaultWidth, &mDefaultHeight, &hint, 474 &numPendingBuffers); 475 476 // Disable transform hint if sticky transform is set. 477 if (mStickyTransform == 0) { 478 mTransformHint = hint; 479 } 480 481 mConsumerRunningBehind = (numPendingBuffers >= 2); 482 483 if (!mConnectedToCpu) { 484 // Clear surface damage back to full-buffer 485 mDirtyRegion = Region::INVALID_REGION; 486 } 487 488 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { 489 mSharedBufferHasBeenQueued = true; 490 } 491 492 mQueueBufferCondition.broadcast(); 493 494 return err; 495} 496 497int Surface::query(int what, int* value) const { 498 ATRACE_CALL(); 499 ALOGV("Surface::query"); 500 { // scope for the lock 501 Mutex::Autolock lock(mMutex); 502 switch (what) { 503 case NATIVE_WINDOW_FORMAT: 504 if (mReqFormat) { 505 *value = static_cast<int>(mReqFormat); 506 return NO_ERROR; 507 } 508 break; 509 case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: { 510 sp<ISurfaceComposer> composer( 511 ComposerService::getComposerService()); 512 if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) { 513 *value = 1; 514 } else { 515 *value = 0; 516 } 517 return NO_ERROR; 518 } 519 case NATIVE_WINDOW_CONCRETE_TYPE: 520 *value = NATIVE_WINDOW_SURFACE; 521 return NO_ERROR; 522 case NATIVE_WINDOW_DEFAULT_WIDTH: 523 *value = static_cast<int>( 524 mUserWidth ? mUserWidth : mDefaultWidth); 525 return NO_ERROR; 526 case NATIVE_WINDOW_DEFAULT_HEIGHT: 527 *value = static_cast<int>( 528 mUserHeight ? mUserHeight : mDefaultHeight); 529 return NO_ERROR; 530 case NATIVE_WINDOW_TRANSFORM_HINT: 531 *value = static_cast<int>(mTransformHint); 532 return NO_ERROR; 533 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: { 534 status_t err = NO_ERROR; 535 if (!mConsumerRunningBehind) { 536 *value = 0; 537 } else { 538 err = mGraphicBufferProducer->query(what, value); 539 if (err == NO_ERROR) { 540 mConsumerRunningBehind = *value; 541 } 542 } 543 return err; 544 } 545 } 546 } 547 return mGraphicBufferProducer->query(what, value); 548} 549 550int Surface::perform(int operation, va_list args) 551{ 552 int res = NO_ERROR; 553 switch (operation) { 554 case NATIVE_WINDOW_CONNECT: 555 // deprecated. must return NO_ERROR. 556 break; 557 case NATIVE_WINDOW_DISCONNECT: 558 // deprecated. must return NO_ERROR. 559 break; 560 case NATIVE_WINDOW_SET_USAGE: 561 res = dispatchSetUsage(args); 562 break; 563 case NATIVE_WINDOW_SET_CROP: 564 res = dispatchSetCrop(args); 565 break; 566 case NATIVE_WINDOW_SET_BUFFER_COUNT: 567 res = dispatchSetBufferCount(args); 568 break; 569 case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: 570 res = dispatchSetBuffersGeometry(args); 571 break; 572 case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: 573 res = dispatchSetBuffersTransform(args); 574 break; 575 case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM: 576 res = dispatchSetBuffersStickyTransform(args); 577 break; 578 case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: 579 res = dispatchSetBuffersTimestamp(args); 580 break; 581 case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: 582 res = dispatchSetBuffersDimensions(args); 583 break; 584 case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS: 585 res = dispatchSetBuffersUserDimensions(args); 586 break; 587 case NATIVE_WINDOW_SET_BUFFERS_FORMAT: 588 res = dispatchSetBuffersFormat(args); 589 break; 590 case NATIVE_WINDOW_LOCK: 591 res = dispatchLock(args); 592 break; 593 case NATIVE_WINDOW_UNLOCK_AND_POST: 594 res = dispatchUnlockAndPost(args); 595 break; 596 case NATIVE_WINDOW_SET_SCALING_MODE: 597 res = dispatchSetScalingMode(args); 598 break; 599 case NATIVE_WINDOW_API_CONNECT: 600 res = dispatchConnect(args); 601 break; 602 case NATIVE_WINDOW_API_DISCONNECT: 603 res = dispatchDisconnect(args); 604 break; 605 case NATIVE_WINDOW_SET_SIDEBAND_STREAM: 606 res = dispatchSetSidebandStream(args); 607 break; 608 case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: 609 res = dispatchSetBuffersDataSpace(args); 610 break; 611 case NATIVE_WINDOW_SET_SURFACE_DAMAGE: 612 res = dispatchSetSurfaceDamage(args); 613 break; 614 case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE: 615 res = dispatchSetSharedBufferMode(args); 616 break; 617 case NATIVE_WINDOW_SET_AUTO_REFRESH: 618 res = dispatchSetAutoRefresh(args); 619 break; 620 default: 621 res = NAME_NOT_FOUND; 622 break; 623 } 624 return res; 625} 626 627int Surface::dispatchConnect(va_list args) { 628 int api = va_arg(args, int); 629 return connect(api); 630} 631 632int Surface::dispatchDisconnect(va_list args) { 633 int api = va_arg(args, int); 634 return disconnect(api); 635} 636 637int Surface::dispatchSetUsage(va_list args) { 638 int usage = va_arg(args, int); 639 return setUsage(static_cast<uint32_t>(usage)); 640} 641 642int Surface::dispatchSetCrop(va_list args) { 643 android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); 644 return setCrop(reinterpret_cast<Rect const*>(rect)); 645} 646 647int Surface::dispatchSetBufferCount(va_list args) { 648 size_t bufferCount = va_arg(args, size_t); 649 return setBufferCount(static_cast<int32_t>(bufferCount)); 650} 651 652int Surface::dispatchSetBuffersGeometry(va_list args) { 653 uint32_t width = va_arg(args, uint32_t); 654 uint32_t height = va_arg(args, uint32_t); 655 PixelFormat format = va_arg(args, PixelFormat); 656 int err = setBuffersDimensions(width, height); 657 if (err != 0) { 658 return err; 659 } 660 return setBuffersFormat(format); 661} 662 663int Surface::dispatchSetBuffersDimensions(va_list args) { 664 uint32_t width = va_arg(args, uint32_t); 665 uint32_t height = va_arg(args, uint32_t); 666 return setBuffersDimensions(width, height); 667} 668 669int Surface::dispatchSetBuffersUserDimensions(va_list args) { 670 uint32_t width = va_arg(args, uint32_t); 671 uint32_t height = va_arg(args, uint32_t); 672 return setBuffersUserDimensions(width, height); 673} 674 675int Surface::dispatchSetBuffersFormat(va_list args) { 676 PixelFormat format = va_arg(args, PixelFormat); 677 return setBuffersFormat(format); 678} 679 680int Surface::dispatchSetScalingMode(va_list args) { 681 int mode = va_arg(args, int); 682 return setScalingMode(mode); 683} 684 685int Surface::dispatchSetBuffersTransform(va_list args) { 686 uint32_t transform = va_arg(args, uint32_t); 687 return setBuffersTransform(transform); 688} 689 690int Surface::dispatchSetBuffersStickyTransform(va_list args) { 691 uint32_t transform = va_arg(args, uint32_t); 692 return setBuffersStickyTransform(transform); 693} 694 695int Surface::dispatchSetBuffersTimestamp(va_list args) { 696 int64_t timestamp = va_arg(args, int64_t); 697 return setBuffersTimestamp(timestamp); 698} 699 700int Surface::dispatchLock(va_list args) { 701 ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*); 702 ARect* inOutDirtyBounds = va_arg(args, ARect*); 703 return lock(outBuffer, inOutDirtyBounds); 704} 705 706int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) { 707 return unlockAndPost(); 708} 709 710int Surface::dispatchSetSidebandStream(va_list args) { 711 native_handle_t* sH = va_arg(args, native_handle_t*); 712 sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false); 713 setSidebandStream(sidebandHandle); 714 return OK; 715} 716 717int Surface::dispatchSetBuffersDataSpace(va_list args) { 718 android_dataspace dataspace = 719 static_cast<android_dataspace>(va_arg(args, int)); 720 return setBuffersDataSpace(dataspace); 721} 722 723int Surface::dispatchSetSurfaceDamage(va_list args) { 724 android_native_rect_t* rects = va_arg(args, android_native_rect_t*); 725 size_t numRects = va_arg(args, size_t); 726 setSurfaceDamage(rects, numRects); 727 return NO_ERROR; 728} 729 730int Surface::dispatchSetSharedBufferMode(va_list args) { 731 bool sharedBufferMode = va_arg(args, int); 732 return setSharedBufferMode(sharedBufferMode); 733} 734 735int Surface::dispatchSetAutoRefresh(va_list args) { 736 bool autoRefresh = va_arg(args, int); 737 return setAutoRefresh(autoRefresh); 738} 739 740int Surface::connect(int api) { 741 static sp<IProducerListener> listener = new DummyProducerListener(); 742 return connect(api, listener); 743} 744 745int Surface::connect(int api, const sp<IProducerListener>& listener) { 746 ATRACE_CALL(); 747 ALOGV("Surface::connect"); 748 Mutex::Autolock lock(mMutex); 749 IGraphicBufferProducer::QueueBufferOutput output; 750 int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); 751 if (err == NO_ERROR) { 752 uint32_t numPendingBuffers = 0; 753 uint32_t hint = 0; 754 output.deflate(&mDefaultWidth, &mDefaultHeight, &hint, 755 &numPendingBuffers); 756 757 // Disable transform hint if sticky transform is set. 758 if (mStickyTransform == 0) { 759 mTransformHint = hint; 760 } 761 762 mConsumerRunningBehind = (numPendingBuffers >= 2); 763 } 764 if (!err && api == NATIVE_WINDOW_API_CPU) { 765 mConnectedToCpu = true; 766 // Clear the dirty region in case we're switching from a non-CPU API 767 mDirtyRegion.clear(); 768 } else if (!err) { 769 // Initialize the dirty region for tracking surface damage 770 mDirtyRegion = Region::INVALID_REGION; 771 } 772 773 return err; 774} 775 776 777int Surface::disconnect(int api) { 778 ATRACE_CALL(); 779 ALOGV("Surface::disconnect"); 780 Mutex::Autolock lock(mMutex); 781 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 782 mSharedBufferHasBeenQueued = false; 783 freeAllBuffers(); 784 int err = mGraphicBufferProducer->disconnect(api); 785 if (!err) { 786 mReqFormat = 0; 787 mReqWidth = 0; 788 mReqHeight = 0; 789 mReqUsage = 0; 790 mCrop.clear(); 791 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 792 mTransform = 0; 793 mStickyTransform = 0; 794 795 if (api == NATIVE_WINDOW_API_CPU) { 796 mConnectedToCpu = false; 797 } 798 } 799 return err; 800} 801 802int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer, 803 sp<Fence>* outFence) { 804 ATRACE_CALL(); 805 ALOGV("Surface::detachNextBuffer"); 806 807 if (outBuffer == NULL || outFence == NULL) { 808 return BAD_VALUE; 809 } 810 811 Mutex::Autolock lock(mMutex); 812 813 sp<GraphicBuffer> buffer(NULL); 814 sp<Fence> fence(NULL); 815 status_t result = mGraphicBufferProducer->detachNextBuffer( 816 &buffer, &fence); 817 if (result != NO_ERROR) { 818 return result; 819 } 820 821 *outBuffer = buffer; 822 if (fence != NULL && fence->isValid()) { 823 *outFence = fence; 824 } else { 825 *outFence = Fence::NO_FENCE; 826 } 827 828 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 829 if (mSlots[i].buffer != NULL && 830 mSlots[i].buffer->handle == buffer->handle) { 831 mSlots[i].buffer = NULL; 832 } 833 } 834 835 return NO_ERROR; 836} 837 838int Surface::attachBuffer(ANativeWindowBuffer* buffer) 839{ 840 ATRACE_CALL(); 841 ALOGV("Surface::attachBuffer"); 842 843 Mutex::Autolock lock(mMutex); 844 845 sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer)); 846 uint32_t priorGeneration = graphicBuffer->mGenerationNumber; 847 graphicBuffer->mGenerationNumber = mGenerationNumber; 848 int32_t attachedSlot = -1; 849 status_t result = mGraphicBufferProducer->attachBuffer( 850 &attachedSlot, graphicBuffer); 851 if (result != NO_ERROR) { 852 ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result); 853 graphicBuffer->mGenerationNumber = priorGeneration; 854 return result; 855 } 856 mSlots[attachedSlot].buffer = graphicBuffer; 857 858 return NO_ERROR; 859} 860 861int Surface::setUsage(uint32_t reqUsage) 862{ 863 ALOGV("Surface::setUsage"); 864 Mutex::Autolock lock(mMutex); 865 if (reqUsage != mReqUsage) { 866 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 867 } 868 mReqUsage = reqUsage; 869 return OK; 870} 871 872int Surface::setCrop(Rect const* rect) 873{ 874 ATRACE_CALL(); 875 876 Rect realRect(Rect::EMPTY_RECT); 877 if (rect == NULL || rect->isEmpty()) { 878 realRect.clear(); 879 } else { 880 realRect = *rect; 881 } 882 883 ALOGV("Surface::setCrop rect=[%d %d %d %d]", 884 realRect.left, realRect.top, realRect.right, realRect.bottom); 885 886 Mutex::Autolock lock(mMutex); 887 mCrop = realRect; 888 return NO_ERROR; 889} 890 891int Surface::setBufferCount(int bufferCount) 892{ 893 ATRACE_CALL(); 894 ALOGV("Surface::setBufferCount"); 895 Mutex::Autolock lock(mMutex); 896 897 status_t err = NO_ERROR; 898 if (bufferCount == 0) { 899 err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1); 900 } else { 901 int minUndequeuedBuffers = 0; 902 err = mGraphicBufferProducer->query( 903 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); 904 if (err == NO_ERROR) { 905 err = mGraphicBufferProducer->setMaxDequeuedBufferCount( 906 bufferCount - minUndequeuedBuffers); 907 } 908 } 909 910 ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s", 911 bufferCount, strerror(-err)); 912 913 return err; 914} 915 916int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) { 917 ATRACE_CALL(); 918 ALOGV("Surface::setMaxDequeuedBufferCount"); 919 Mutex::Autolock lock(mMutex); 920 921 status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount( 922 maxDequeuedBuffers); 923 ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) " 924 "returned %s", maxDequeuedBuffers, strerror(-err)); 925 926 return err; 927} 928 929int Surface::setAsyncMode(bool async) { 930 ATRACE_CALL(); 931 ALOGV("Surface::setAsyncMode"); 932 Mutex::Autolock lock(mMutex); 933 934 status_t err = mGraphicBufferProducer->setAsyncMode(async); 935 ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s", 936 async, strerror(-err)); 937 938 return err; 939} 940 941int Surface::setSharedBufferMode(bool sharedBufferMode) { 942 ATRACE_CALL(); 943 ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode); 944 Mutex::Autolock lock(mMutex); 945 946 status_t err = mGraphicBufferProducer->setSharedBufferMode( 947 sharedBufferMode); 948 if (err == NO_ERROR) { 949 mSharedBufferMode = sharedBufferMode; 950 } 951 ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned" 952 "%s", sharedBufferMode, strerror(-err)); 953 954 return err; 955} 956 957int Surface::setAutoRefresh(bool autoRefresh) { 958 ATRACE_CALL(); 959 ALOGV("Surface::setAutoRefresh (%d)", autoRefresh); 960 Mutex::Autolock lock(mMutex); 961 962 status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh); 963 if (err == NO_ERROR) { 964 mAutoRefresh = autoRefresh; 965 } 966 ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s", 967 autoRefresh, strerror(-err)); 968 return err; 969} 970 971int Surface::setBuffersDimensions(uint32_t width, uint32_t height) 972{ 973 ATRACE_CALL(); 974 ALOGV("Surface::setBuffersDimensions"); 975 976 if ((width && !height) || (!width && height)) 977 return BAD_VALUE; 978 979 Mutex::Autolock lock(mMutex); 980 if (width != mReqWidth || height != mReqHeight) { 981 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 982 } 983 mReqWidth = width; 984 mReqHeight = height; 985 return NO_ERROR; 986} 987 988int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height) 989{ 990 ATRACE_CALL(); 991 ALOGV("Surface::setBuffersUserDimensions"); 992 993 if ((width && !height) || (!width && height)) 994 return BAD_VALUE; 995 996 Mutex::Autolock lock(mMutex); 997 if (width != mUserWidth || height != mUserHeight) { 998 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 999 } 1000 mUserWidth = width; 1001 mUserHeight = height; 1002 return NO_ERROR; 1003} 1004 1005int Surface::setBuffersFormat(PixelFormat format) 1006{ 1007 ALOGV("Surface::setBuffersFormat"); 1008 1009 Mutex::Autolock lock(mMutex); 1010 if (format != mReqFormat) { 1011 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 1012 } 1013 mReqFormat = format; 1014 return NO_ERROR; 1015} 1016 1017int Surface::setScalingMode(int mode) 1018{ 1019 ATRACE_CALL(); 1020 ALOGV("Surface::setScalingMode(%d)", mode); 1021 1022 switch (mode) { 1023 case NATIVE_WINDOW_SCALING_MODE_FREEZE: 1024 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 1025 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 1026 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 1027 break; 1028 default: 1029 ALOGE("unknown scaling mode: %d", mode); 1030 return BAD_VALUE; 1031 } 1032 1033 Mutex::Autolock lock(mMutex); 1034 mScalingMode = mode; 1035 return NO_ERROR; 1036} 1037 1038int Surface::setBuffersTransform(uint32_t transform) 1039{ 1040 ATRACE_CALL(); 1041 ALOGV("Surface::setBuffersTransform"); 1042 Mutex::Autolock lock(mMutex); 1043 mTransform = transform; 1044 return NO_ERROR; 1045} 1046 1047int Surface::setBuffersStickyTransform(uint32_t transform) 1048{ 1049 ATRACE_CALL(); 1050 ALOGV("Surface::setBuffersStickyTransform"); 1051 Mutex::Autolock lock(mMutex); 1052 mStickyTransform = transform; 1053 return NO_ERROR; 1054} 1055 1056int Surface::setBuffersTimestamp(int64_t timestamp) 1057{ 1058 ALOGV("Surface::setBuffersTimestamp"); 1059 Mutex::Autolock lock(mMutex); 1060 mTimestamp = timestamp; 1061 return NO_ERROR; 1062} 1063 1064int Surface::setBuffersDataSpace(android_dataspace dataSpace) 1065{ 1066 ALOGV("Surface::setBuffersDataSpace"); 1067 Mutex::Autolock lock(mMutex); 1068 mDataSpace = dataSpace; 1069 return NO_ERROR; 1070} 1071 1072void Surface::freeAllBuffers() { 1073 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 1074 mSlots[i].buffer = 0; 1075 } 1076} 1077 1078void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { 1079 ATRACE_CALL(); 1080 ALOGV("Surface::setSurfaceDamage"); 1081 Mutex::Autolock lock(mMutex); 1082 1083 if (mConnectedToCpu || numRects == 0) { 1084 mDirtyRegion = Region::INVALID_REGION; 1085 return; 1086 } 1087 1088 mDirtyRegion.clear(); 1089 for (size_t r = 0; r < numRects; ++r) { 1090 // We intentionally flip top and bottom here, since because they're 1091 // specified with a bottom-left origin, top > bottom, which fails 1092 // validation in the Region class. We will fix this up when we flip to a 1093 // top-left origin in queueBuffer. 1094 Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top); 1095 mDirtyRegion.orSelf(rect); 1096 } 1097} 1098 1099// ---------------------------------------------------------------------- 1100// the lock/unlock APIs must be used from the same thread 1101 1102static status_t copyBlt( 1103 const sp<GraphicBuffer>& dst, 1104 const sp<GraphicBuffer>& src, 1105 const Region& reg) 1106{ 1107 // src and dst with, height and format must be identical. no verification 1108 // is done here. 1109 status_t err; 1110 uint8_t* src_bits = NULL; 1111 err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), 1112 reinterpret_cast<void**>(&src_bits)); 1113 ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); 1114 1115 uint8_t* dst_bits = NULL; 1116 err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), 1117 reinterpret_cast<void**>(&dst_bits)); 1118 ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); 1119 1120 Region::const_iterator head(reg.begin()); 1121 Region::const_iterator tail(reg.end()); 1122 if (head != tail && src_bits && dst_bits) { 1123 const size_t bpp = bytesPerPixel(src->format); 1124 const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp; 1125 const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp; 1126 1127 while (head != tail) { 1128 const Rect& r(*head++); 1129 int32_t h = r.height(); 1130 if (h <= 0) continue; 1131 size_t size = static_cast<uint32_t>(r.width()) * bpp; 1132 uint8_t const * s = src_bits + 1133 static_cast<uint32_t>(r.left + src->stride * r.top) * bpp; 1134 uint8_t * d = dst_bits + 1135 static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp; 1136 if (dbpr==sbpr && size==sbpr) { 1137 size *= static_cast<size_t>(h); 1138 h = 1; 1139 } 1140 do { 1141 memcpy(d, s, size); 1142 d += dbpr; 1143 s += sbpr; 1144 } while (--h > 0); 1145 } 1146 } 1147 1148 if (src_bits) 1149 src->unlock(); 1150 1151 if (dst_bits) 1152 dst->unlock(); 1153 1154 return err; 1155} 1156 1157// ---------------------------------------------------------------------------- 1158 1159status_t Surface::lock( 1160 ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) 1161{ 1162 if (mLockedBuffer != 0) { 1163 ALOGE("Surface::lock failed, already locked"); 1164 return INVALID_OPERATION; 1165 } 1166 1167 if (!mConnectedToCpu) { 1168 int err = Surface::connect(NATIVE_WINDOW_API_CPU); 1169 if (err) { 1170 return err; 1171 } 1172 // we're intending to do software rendering from this point 1173 setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); 1174 } 1175 1176 ANativeWindowBuffer* out; 1177 int fenceFd = -1; 1178 status_t err = dequeueBuffer(&out, &fenceFd); 1179 ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); 1180 if (err == NO_ERROR) { 1181 sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); 1182 const Rect bounds(backBuffer->width, backBuffer->height); 1183 1184 Region newDirtyRegion; 1185 if (inOutDirtyBounds) { 1186 newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds)); 1187 newDirtyRegion.andSelf(bounds); 1188 } else { 1189 newDirtyRegion.set(bounds); 1190 } 1191 1192 // figure out if we can copy the frontbuffer back 1193 const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); 1194 const bool canCopyBack = (frontBuffer != 0 && 1195 backBuffer->width == frontBuffer->width && 1196 backBuffer->height == frontBuffer->height && 1197 backBuffer->format == frontBuffer->format); 1198 1199 if (canCopyBack) { 1200 // copy the area that is invalid and not repainted this round 1201 const Region copyback(mDirtyRegion.subtract(newDirtyRegion)); 1202 if (!copyback.isEmpty()) 1203 copyBlt(backBuffer, frontBuffer, copyback); 1204 } else { 1205 // if we can't copy-back anything, modify the user's dirty 1206 // region to make sure they redraw the whole buffer 1207 newDirtyRegion.set(bounds); 1208 mDirtyRegion.clear(); 1209 Mutex::Autolock lock(mMutex); 1210 for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) { 1211 mSlots[i].dirtyRegion.clear(); 1212 } 1213 } 1214 1215 1216 { // scope for the lock 1217 Mutex::Autolock lock(mMutex); 1218 int backBufferSlot(getSlotFromBufferLocked(backBuffer.get())); 1219 if (backBufferSlot >= 0) { 1220 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion); 1221 mDirtyRegion.subtract(dirtyRegion); 1222 dirtyRegion = newDirtyRegion; 1223 } 1224 } 1225 1226 mDirtyRegion.orSelf(newDirtyRegion); 1227 if (inOutDirtyBounds) { 1228 *inOutDirtyBounds = newDirtyRegion.getBounds(); 1229 } 1230 1231 void* vaddr; 1232 status_t res = backBuffer->lockAsync( 1233 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, 1234 newDirtyRegion.bounds(), &vaddr, fenceFd); 1235 1236 ALOGW_IF(res, "failed locking buffer (handle = %p)", 1237 backBuffer->handle); 1238 1239 if (res != 0) { 1240 err = INVALID_OPERATION; 1241 } else { 1242 mLockedBuffer = backBuffer; 1243 outBuffer->width = backBuffer->width; 1244 outBuffer->height = backBuffer->height; 1245 outBuffer->stride = backBuffer->stride; 1246 outBuffer->format = backBuffer->format; 1247 outBuffer->bits = vaddr; 1248 } 1249 } 1250 return err; 1251} 1252 1253status_t Surface::unlockAndPost() 1254{ 1255 if (mLockedBuffer == 0) { 1256 ALOGE("Surface::unlockAndPost failed, no locked buffer"); 1257 return INVALID_OPERATION; 1258 } 1259 1260 int fd = -1; 1261 status_t err = mLockedBuffer->unlockAsync(&fd); 1262 ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); 1263 1264 err = queueBuffer(mLockedBuffer.get(), fd); 1265 ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", 1266 mLockedBuffer->handle, strerror(-err)); 1267 1268 mPostedBuffer = mLockedBuffer; 1269 mLockedBuffer = 0; 1270 return err; 1271} 1272 1273bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) { 1274 Mutex::Autolock lock(mMutex); 1275 uint64_t currentFrame = mGraphicBufferProducer->getNextFrameNumber(); 1276 if (currentFrame > lastFrame) { 1277 return true; 1278 } 1279 return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK; 1280} 1281 1282status_t Surface::getUniqueId(uint64_t* outId) const { 1283 Mutex::Autolock lock(mMutex); 1284 return mGraphicBufferProducer->getUniqueId(outId); 1285} 1286 1287namespace view { 1288 1289status_t Surface::writeToParcel(Parcel* parcel) const { 1290 return writeToParcel(parcel, false); 1291} 1292 1293status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const { 1294 if (parcel == nullptr) return BAD_VALUE; 1295 1296 status_t res = OK; 1297 1298 if (!nameAlreadyWritten) res = parcel->writeString16(name); 1299 1300 if (res == OK) { 1301 res = parcel->writeStrongBinder( 1302 IGraphicBufferProducer::asBinder(graphicBufferProducer)); 1303 } 1304 return res; 1305} 1306 1307status_t Surface::readFromParcel(const Parcel* parcel) { 1308 return readFromParcel(parcel, false); 1309} 1310 1311status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) { 1312 if (parcel == nullptr) return BAD_VALUE; 1313 1314 if (!nameAlreadyRead) { 1315 name = readMaybeEmptyString16(parcel); 1316 } 1317 1318 sp<IBinder> binder; 1319 1320 status_t res = parcel->readStrongBinder(&binder); 1321 if (res != OK) return res; 1322 1323 graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder); 1324 1325 return OK; 1326} 1327 1328String16 Surface::readMaybeEmptyString16(const Parcel* parcel) { 1329 size_t len; 1330 const char16_t* str = parcel->readString16Inplace(&len); 1331 if (str != nullptr) { 1332 return String16(str, len); 1333 } else { 1334 return String16(); 1335 } 1336} 1337 1338} // namespace view 1339 1340}; // namespace android 1341