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