1 /* 2 * Copyright (C) 2007 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 "SurfaceComposerClient" 18 19 #include <stdint.h> 20 #include <sys/types.h> 21 22 #include <utils/Errors.h> 23 #include <utils/Log.h> 24 #include <utils/Singleton.h> 25 #include <utils/SortedVector.h> 26 #include <utils/String8.h> 27 #include <utils/threads.h> 28 29 #include <binder/IMemory.h> 30 #include <binder/IServiceManager.h> 31 32 #include <ui/DisplayInfo.h> 33 34 #include <gui/CpuConsumer.h> 35 #include <gui/IGraphicBufferProducer.h> 36 #include <gui/ISurfaceComposer.h> 37 #include <gui/ISurfaceComposerClient.h> 38 #include <gui/SurfaceComposerClient.h> 39 40 #include <private/gui/ComposerService.h> 41 #include <private/gui/LayerState.h> 42 43 namespace android { 44 // --------------------------------------------------------------------------- 45 46 ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService); 47 48 ComposerService::ComposerService() 49 : Singleton<ComposerService>() { 50 Mutex::Autolock _l(mLock); 51 connectLocked(); 52 } 53 54 void ComposerService::connectLocked() { 55 const String16 name("SurfaceFlinger"); 56 while (getService(name, &mComposerService) != NO_ERROR) { 57 usleep(250000); 58 } 59 assert(mComposerService != NULL); 60 61 // Create the death listener. 62 class DeathObserver : public IBinder::DeathRecipient { 63 ComposerService& mComposerService; 64 virtual void binderDied(const wp<IBinder>& who) { 65 ALOGW("ComposerService remote (surfaceflinger) died [%p]", 66 who.unsafe_get()); 67 mComposerService.composerServiceDied(); 68 } 69 public: 70 DeathObserver(ComposerService& mgr) : mComposerService(mgr) { } 71 }; 72 73 mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this)); 74 mComposerService->asBinder()->linkToDeath(mDeathObserver); 75 } 76 77 /*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() { 78 ComposerService& instance = ComposerService::getInstance(); 79 Mutex::Autolock _l(instance.mLock); 80 if (instance.mComposerService == NULL) { 81 ComposerService::getInstance().connectLocked(); 82 assert(instance.mComposerService != NULL); 83 ALOGD("ComposerService reconnected"); 84 } 85 return instance.mComposerService; 86 } 87 88 void ComposerService::composerServiceDied() 89 { 90 Mutex::Autolock _l(mLock); 91 mComposerService = NULL; 92 mDeathObserver = NULL; 93 } 94 95 // --------------------------------------------------------------------------- 96 97 static inline 98 int compare_type(const ComposerState& lhs, const ComposerState& rhs) { 99 if (lhs.client < rhs.client) return -1; 100 if (lhs.client > rhs.client) return 1; 101 if (lhs.state.surface < rhs.state.surface) return -1; 102 if (lhs.state.surface > rhs.state.surface) return 1; 103 return 0; 104 } 105 106 static inline 107 int compare_type(const DisplayState& lhs, const DisplayState& rhs) { 108 return compare_type(lhs.token, rhs.token); 109 } 110 111 class Composer : public Singleton<Composer> 112 { 113 friend class Singleton<Composer>; 114 115 mutable Mutex mLock; 116 SortedVector<ComposerState> mComposerStates; 117 SortedVector<DisplayState > mDisplayStates; 118 uint32_t mForceSynchronous; 119 uint32_t mTransactionNestCount; 120 bool mAnimation; 121 122 Composer() : Singleton<Composer>(), 123 mForceSynchronous(0), mTransactionNestCount(0), 124 mAnimation(false) 125 { } 126 127 void openGlobalTransactionImpl(); 128 void closeGlobalTransactionImpl(bool synchronous); 129 void setAnimationTransactionImpl(); 130 131 layer_state_t* getLayerStateLocked( 132 const sp<SurfaceComposerClient>& client, const sp<IBinder>& id); 133 134 DisplayState& getDisplayStateLocked(const sp<IBinder>& token); 135 136 public: 137 sp<IBinder> createDisplay(const String8& displayName, bool secure); 138 sp<IBinder> getBuiltInDisplay(int32_t id); 139 140 status_t setPosition(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 141 float x, float y); 142 status_t setSize(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 143 uint32_t w, uint32_t h); 144 status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 145 int32_t z); 146 status_t setFlags(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 147 uint32_t flags, uint32_t mask); 148 status_t setTransparentRegionHint( 149 const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 150 const Region& transparentRegion); 151 status_t setAlpha(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 152 float alpha); 153 status_t setMatrix(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 154 float dsdx, float dtdx, float dsdy, float dtdy); 155 status_t setOrientation(int orientation); 156 status_t setCrop(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 157 const Rect& crop); 158 status_t setLayerStack(const sp<SurfaceComposerClient>& client, 159 const sp<IBinder>& id, uint32_t layerStack); 160 161 void setDisplaySurface(const sp<IBinder>& token, 162 const sp<IGraphicBufferProducer>& bufferProducer); 163 void setDisplayLayerStack(const sp<IBinder>& token, uint32_t layerStack); 164 void setDisplayProjection(const sp<IBinder>& token, 165 uint32_t orientation, 166 const Rect& layerStackRect, 167 const Rect& displayRect); 168 169 static void setAnimationTransaction() { 170 Composer::getInstance().setAnimationTransactionImpl(); 171 } 172 173 static void openGlobalTransaction() { 174 Composer::getInstance().openGlobalTransactionImpl(); 175 } 176 177 static void closeGlobalTransaction(bool synchronous) { 178 Composer::getInstance().closeGlobalTransactionImpl(synchronous); 179 } 180 }; 181 182 ANDROID_SINGLETON_STATIC_INSTANCE(Composer); 183 184 // --------------------------------------------------------------------------- 185 186 sp<IBinder> Composer::createDisplay(const String8& displayName, bool secure) { 187 return ComposerService::getComposerService()->createDisplay(displayName, 188 secure); 189 } 190 191 sp<IBinder> Composer::getBuiltInDisplay(int32_t id) { 192 return ComposerService::getComposerService()->getBuiltInDisplay(id); 193 } 194 195 void Composer::openGlobalTransactionImpl() { 196 { // scope for the lock 197 Mutex::Autolock _l(mLock); 198 mTransactionNestCount += 1; 199 } 200 } 201 202 void Composer::closeGlobalTransactionImpl(bool synchronous) { 203 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 204 205 Vector<ComposerState> transaction; 206 Vector<DisplayState> displayTransaction; 207 uint32_t flags = 0; 208 209 { // scope for the lock 210 Mutex::Autolock _l(mLock); 211 mForceSynchronous |= synchronous; 212 if (!mTransactionNestCount) { 213 ALOGW("At least one call to closeGlobalTransaction() was not matched by a prior " 214 "call to openGlobalTransaction()."); 215 } else if (--mTransactionNestCount) { 216 return; 217 } 218 219 transaction = mComposerStates; 220 mComposerStates.clear(); 221 222 displayTransaction = mDisplayStates; 223 mDisplayStates.clear(); 224 225 if (mForceSynchronous) { 226 flags |= ISurfaceComposer::eSynchronous; 227 } 228 if (mAnimation) { 229 flags |= ISurfaceComposer::eAnimation; 230 } 231 232 mForceSynchronous = false; 233 mAnimation = false; 234 } 235 236 sm->setTransactionState(transaction, displayTransaction, flags); 237 } 238 239 void Composer::setAnimationTransactionImpl() { 240 Mutex::Autolock _l(mLock); 241 mAnimation = true; 242 } 243 244 layer_state_t* Composer::getLayerStateLocked( 245 const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) { 246 247 ComposerState s; 248 s.client = client->mClient; 249 s.state.surface = id; 250 251 ssize_t index = mComposerStates.indexOf(s); 252 if (index < 0) { 253 // we don't have it, add an initialized layer_state to our list 254 index = mComposerStates.add(s); 255 } 256 257 ComposerState* const out = mComposerStates.editArray(); 258 return &(out[index].state); 259 } 260 261 status_t Composer::setPosition(const sp<SurfaceComposerClient>& client, 262 const sp<IBinder>& id, float x, float y) { 263 Mutex::Autolock _l(mLock); 264 layer_state_t* s = getLayerStateLocked(client, id); 265 if (!s) 266 return BAD_INDEX; 267 s->what |= layer_state_t::ePositionChanged; 268 s->x = x; 269 s->y = y; 270 return NO_ERROR; 271 } 272 273 status_t Composer::setSize(const sp<SurfaceComposerClient>& client, 274 const sp<IBinder>& id, uint32_t w, uint32_t h) { 275 Mutex::Autolock _l(mLock); 276 layer_state_t* s = getLayerStateLocked(client, id); 277 if (!s) 278 return BAD_INDEX; 279 s->what |= layer_state_t::eSizeChanged; 280 s->w = w; 281 s->h = h; 282 283 // Resizing a surface makes the transaction synchronous. 284 mForceSynchronous = true; 285 286 return NO_ERROR; 287 } 288 289 status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, 290 const sp<IBinder>& id, int32_t z) { 291 Mutex::Autolock _l(mLock); 292 layer_state_t* s = getLayerStateLocked(client, id); 293 if (!s) 294 return BAD_INDEX; 295 s->what |= layer_state_t::eLayerChanged; 296 s->z = z; 297 return NO_ERROR; 298 } 299 300 status_t Composer::setFlags(const sp<SurfaceComposerClient>& client, 301 const sp<IBinder>& id, uint32_t flags, 302 uint32_t mask) { 303 Mutex::Autolock _l(mLock); 304 layer_state_t* s = getLayerStateLocked(client, id); 305 if (!s) 306 return BAD_INDEX; 307 s->what |= layer_state_t::eVisibilityChanged; 308 s->flags &= ~mask; 309 s->flags |= (flags & mask); 310 s->mask |= mask; 311 return NO_ERROR; 312 } 313 314 status_t Composer::setTransparentRegionHint( 315 const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 316 const Region& transparentRegion) { 317 Mutex::Autolock _l(mLock); 318 layer_state_t* s = getLayerStateLocked(client, id); 319 if (!s) 320 return BAD_INDEX; 321 s->what |= layer_state_t::eTransparentRegionChanged; 322 s->transparentRegion = transparentRegion; 323 return NO_ERROR; 324 } 325 326 status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client, 327 const sp<IBinder>& id, float alpha) { 328 Mutex::Autolock _l(mLock); 329 layer_state_t* s = getLayerStateLocked(client, id); 330 if (!s) 331 return BAD_INDEX; 332 s->what |= layer_state_t::eAlphaChanged; 333 s->alpha = alpha; 334 return NO_ERROR; 335 } 336 337 status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client, 338 const sp<IBinder>& id, uint32_t layerStack) { 339 Mutex::Autolock _l(mLock); 340 layer_state_t* s = getLayerStateLocked(client, id); 341 if (!s) 342 return BAD_INDEX; 343 s->what |= layer_state_t::eLayerStackChanged; 344 s->layerStack = layerStack; 345 return NO_ERROR; 346 } 347 348 status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client, 349 const sp<IBinder>& id, float dsdx, float dtdx, 350 float dsdy, float dtdy) { 351 Mutex::Autolock _l(mLock); 352 layer_state_t* s = getLayerStateLocked(client, id); 353 if (!s) 354 return BAD_INDEX; 355 s->what |= layer_state_t::eMatrixChanged; 356 layer_state_t::matrix22_t matrix; 357 matrix.dsdx = dsdx; 358 matrix.dtdx = dtdx; 359 matrix.dsdy = dsdy; 360 matrix.dtdy = dtdy; 361 s->matrix = matrix; 362 return NO_ERROR; 363 } 364 365 status_t Composer::setCrop(const sp<SurfaceComposerClient>& client, 366 const sp<IBinder>& id, const Rect& crop) { 367 Mutex::Autolock _l(mLock); 368 layer_state_t* s = getLayerStateLocked(client, id); 369 if (!s) 370 return BAD_INDEX; 371 s->what |= layer_state_t::eCropChanged; 372 s->crop = crop; 373 return NO_ERROR; 374 } 375 376 // --------------------------------------------------------------------------- 377 378 DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) { 379 DisplayState s; 380 s.token = token; 381 ssize_t index = mDisplayStates.indexOf(s); 382 if (index < 0) { 383 // we don't have it, add an initialized layer_state to our list 384 s.what = 0; 385 index = mDisplayStates.add(s); 386 } 387 return mDisplayStates.editItemAt(index); 388 } 389 390 void Composer::setDisplaySurface(const sp<IBinder>& token, 391 const sp<IGraphicBufferProducer>& bufferProducer) { 392 Mutex::Autolock _l(mLock); 393 DisplayState& s(getDisplayStateLocked(token)); 394 s.surface = bufferProducer; 395 s.what |= DisplayState::eSurfaceChanged; 396 } 397 398 void Composer::setDisplayLayerStack(const sp<IBinder>& token, 399 uint32_t layerStack) { 400 Mutex::Autolock _l(mLock); 401 DisplayState& s(getDisplayStateLocked(token)); 402 s.layerStack = layerStack; 403 s.what |= DisplayState::eLayerStackChanged; 404 } 405 406 void Composer::setDisplayProjection(const sp<IBinder>& token, 407 uint32_t orientation, 408 const Rect& layerStackRect, 409 const Rect& displayRect) { 410 Mutex::Autolock _l(mLock); 411 DisplayState& s(getDisplayStateLocked(token)); 412 s.orientation = orientation; 413 s.viewport = layerStackRect; 414 s.frame = displayRect; 415 s.what |= DisplayState::eDisplayProjectionChanged; 416 mForceSynchronous = true; // TODO: do we actually still need this? 417 } 418 419 // --------------------------------------------------------------------------- 420 421 SurfaceComposerClient::SurfaceComposerClient() 422 : mStatus(NO_INIT), mComposer(Composer::getInstance()) 423 { 424 } 425 426 void SurfaceComposerClient::onFirstRef() { 427 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 428 if (sm != 0) { 429 sp<ISurfaceComposerClient> conn = sm->createConnection(); 430 if (conn != 0) { 431 mClient = conn; 432 mStatus = NO_ERROR; 433 } 434 } 435 } 436 437 SurfaceComposerClient::~SurfaceComposerClient() { 438 dispose(); 439 } 440 441 status_t SurfaceComposerClient::initCheck() const { 442 return mStatus; 443 } 444 445 sp<IBinder> SurfaceComposerClient::connection() const { 446 return (mClient != 0) ? mClient->asBinder() : 0; 447 } 448 449 status_t SurfaceComposerClient::linkToComposerDeath( 450 const sp<IBinder::DeathRecipient>& recipient, 451 void* cookie, uint32_t flags) { 452 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 453 return sm->asBinder()->linkToDeath(recipient, cookie, flags); 454 } 455 456 void SurfaceComposerClient::dispose() { 457 // this can be called more than once. 458 sp<ISurfaceComposerClient> client; 459 Mutex::Autolock _lm(mLock); 460 if (mClient != 0) { 461 client = mClient; // hold ref while lock is held 462 mClient.clear(); 463 } 464 mStatus = NO_INIT; 465 } 466 467 sp<SurfaceControl> SurfaceComposerClient::createSurface( 468 const String8& name, 469 uint32_t w, 470 uint32_t h, 471 PixelFormat format, 472 uint32_t flags) 473 { 474 sp<SurfaceControl> sur; 475 if (mStatus == NO_ERROR) { 476 sp<IBinder> handle; 477 sp<IGraphicBufferProducer> gbp; 478 status_t err = mClient->createSurface(name, w, h, format, flags, 479 &handle, &gbp); 480 ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); 481 if (err == NO_ERROR) { 482 sur = new SurfaceControl(this, handle, gbp); 483 } 484 } 485 return sur; 486 } 487 488 sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, 489 bool secure) { 490 return Composer::getInstance().createDisplay(displayName, secure); 491 } 492 493 sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) { 494 return Composer::getInstance().getBuiltInDisplay(id); 495 } 496 497 status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) { 498 if (mStatus != NO_ERROR) 499 return mStatus; 500 status_t err = mClient->destroySurface(sid); 501 return err; 502 } 503 504 inline Composer& SurfaceComposerClient::getComposer() { 505 return mComposer; 506 } 507 508 // ---------------------------------------------------------------------------- 509 510 void SurfaceComposerClient::openGlobalTransaction() { 511 Composer::openGlobalTransaction(); 512 } 513 514 void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { 515 Composer::closeGlobalTransaction(synchronous); 516 } 517 518 void SurfaceComposerClient::setAnimationTransaction() { 519 Composer::setAnimationTransaction(); 520 } 521 522 // ---------------------------------------------------------------------------- 523 524 status_t SurfaceComposerClient::setCrop(const sp<IBinder>& id, const Rect& crop) { 525 return getComposer().setCrop(this, id, crop); 526 } 527 528 status_t SurfaceComposerClient::setPosition(const sp<IBinder>& id, float x, float y) { 529 return getComposer().setPosition(this, id, x, y); 530 } 531 532 status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint32_t h) { 533 return getComposer().setSize(this, id, w, h); 534 } 535 536 status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) { 537 return getComposer().setLayer(this, id, z); 538 } 539 540 status_t SurfaceComposerClient::hide(const sp<IBinder>& id) { 541 return getComposer().setFlags(this, id, 542 layer_state_t::eLayerHidden, 543 layer_state_t::eLayerHidden); 544 } 545 546 status_t SurfaceComposerClient::show(const sp<IBinder>& id) { 547 return getComposer().setFlags(this, id, 548 0, 549 layer_state_t::eLayerHidden); 550 } 551 552 status_t SurfaceComposerClient::setFlags(const sp<IBinder>& id, uint32_t flags, 553 uint32_t mask) { 554 return getComposer().setFlags(this, id, flags, mask); 555 } 556 557 status_t SurfaceComposerClient::setTransparentRegionHint(const sp<IBinder>& id, 558 const Region& transparentRegion) { 559 return getComposer().setTransparentRegionHint(this, id, transparentRegion); 560 } 561 562 status_t SurfaceComposerClient::setAlpha(const sp<IBinder>& id, float alpha) { 563 return getComposer().setAlpha(this, id, alpha); 564 } 565 566 status_t SurfaceComposerClient::setLayerStack(const sp<IBinder>& id, uint32_t layerStack) { 567 return getComposer().setLayerStack(this, id, layerStack); 568 } 569 570 status_t SurfaceComposerClient::setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, 571 float dsdy, float dtdy) { 572 return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy); 573 } 574 575 // ---------------------------------------------------------------------------- 576 577 void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token, 578 const sp<IGraphicBufferProducer>& bufferProducer) { 579 Composer::getInstance().setDisplaySurface(token, bufferProducer); 580 } 581 582 void SurfaceComposerClient::setDisplayLayerStack(const sp<IBinder>& token, 583 uint32_t layerStack) { 584 Composer::getInstance().setDisplayLayerStack(token, layerStack); 585 } 586 587 void SurfaceComposerClient::setDisplayProjection(const sp<IBinder>& token, 588 uint32_t orientation, 589 const Rect& layerStackRect, 590 const Rect& displayRect) { 591 Composer::getInstance().setDisplayProjection(token, orientation, 592 layerStackRect, displayRect); 593 } 594 595 // ---------------------------------------------------------------------------- 596 597 status_t SurfaceComposerClient::getDisplayInfo( 598 const sp<IBinder>& display, DisplayInfo* info) 599 { 600 return ComposerService::getComposerService()->getDisplayInfo(display, info); 601 } 602 603 void SurfaceComposerClient::blankDisplay(const sp<IBinder>& token) { 604 ComposerService::getComposerService()->blank(token); 605 } 606 607 void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) { 608 ComposerService::getComposerService()->unblank(token); 609 } 610 611 // ---------------------------------------------------------------------------- 612 613 status_t ScreenshotClient::capture( 614 const sp<IBinder>& display, 615 const sp<IGraphicBufferProducer>& producer, 616 uint32_t reqWidth, uint32_t reqHeight, 617 uint32_t minLayerZ, uint32_t maxLayerZ) { 618 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 619 if (s == NULL) return NO_INIT; 620 return s->captureScreen(display, producer, 621 reqWidth, reqHeight, minLayerZ, maxLayerZ, 622 false); 623 } 624 625 ScreenshotClient::ScreenshotClient() 626 : mHaveBuffer(false) { 627 memset(&mBuffer, 0, sizeof(mBuffer)); 628 } 629 630 ScreenshotClient::~ScreenshotClient() { 631 ScreenshotClient::release(); 632 } 633 634 sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const { 635 if (mCpuConsumer == NULL) { 636 mCpuConsumer = new CpuConsumer(1); 637 mCpuConsumer->setName(String8("ScreenshotClient")); 638 } 639 return mCpuConsumer; 640 } 641 642 status_t ScreenshotClient::update(const sp<IBinder>& display, 643 uint32_t reqWidth, uint32_t reqHeight, 644 uint32_t minLayerZ, uint32_t maxLayerZ) { 645 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 646 if (s == NULL) return NO_INIT; 647 sp<CpuConsumer> cpuConsumer = getCpuConsumer(); 648 649 if (mHaveBuffer) { 650 mCpuConsumer->unlockBuffer(mBuffer); 651 memset(&mBuffer, 0, sizeof(mBuffer)); 652 mHaveBuffer = false; 653 } 654 655 status_t err = s->captureScreen(display,cpuConsumer->getBufferQueue(), 656 reqWidth, reqHeight, minLayerZ, maxLayerZ, true); 657 658 if (err == NO_ERROR) { 659 err = mCpuConsumer->lockNextBuffer(&mBuffer); 660 if (err == NO_ERROR) { 661 mHaveBuffer = true; 662 } 663 } 664 return err; 665 } 666 667 status_t ScreenshotClient::update(const sp<IBinder>& display) { 668 return ScreenshotClient::update(display, 0, 0, 0, -1UL); 669 } 670 671 status_t ScreenshotClient::update(const sp<IBinder>& display, 672 uint32_t reqWidth, uint32_t reqHeight) { 673 return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL); 674 } 675 676 void ScreenshotClient::release() { 677 if (mHaveBuffer) { 678 mCpuConsumer->unlockBuffer(mBuffer); 679 memset(&mBuffer, 0, sizeof(mBuffer)); 680 mHaveBuffer = false; 681 } 682 mCpuConsumer.clear(); 683 } 684 685 void const* ScreenshotClient::getPixels() const { 686 return mBuffer.data; 687 } 688 689 uint32_t ScreenshotClient::getWidth() const { 690 return mBuffer.width; 691 } 692 693 uint32_t ScreenshotClient::getHeight() const { 694 return mBuffer.height; 695 } 696 697 PixelFormat ScreenshotClient::getFormat() const { 698 return mBuffer.format; 699 } 700 701 uint32_t ScreenshotClient::getStride() const { 702 return mBuffer.stride; 703 } 704 705 size_t ScreenshotClient::getSize() const { 706 return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format); 707 } 708 709 // ---------------------------------------------------------------------------- 710 }; // namespace android 711