SurfaceComposerClient.cpp revision 3ca76f416bc8665a97636ca8a2d0128b9da9d92c
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 43namespace android { 44// --------------------------------------------------------------------------- 45 46ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService); 47 48ComposerService::ComposerService() 49: Singleton<ComposerService>() { 50 Mutex::Autolock _l(mLock); 51 connectLocked(); 52} 53 54void 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 88void ComposerService::composerServiceDied() 89{ 90 Mutex::Autolock _l(mLock); 91 mComposerService = NULL; 92 mDeathObserver = NULL; 93} 94 95// --------------------------------------------------------------------------- 96 97static inline 98int 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 106static inline 107int compare_type(const DisplayState& lhs, const DisplayState& rhs) { 108 return compare_type(lhs.token, rhs.token); 109} 110 111class 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 136public: 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 182ANDROID_SINGLETON_STATIC_INSTANCE(Composer); 183 184// --------------------------------------------------------------------------- 185 186sp<IBinder> Composer::createDisplay(const String8& displayName, bool secure) { 187 return ComposerService::getComposerService()->createDisplay(displayName, 188 secure); 189} 190 191sp<IBinder> Composer::getBuiltInDisplay(int32_t id) { 192 return ComposerService::getComposerService()->getBuiltInDisplay(id); 193} 194 195void Composer::openGlobalTransactionImpl() { 196 { // scope for the lock 197 Mutex::Autolock _l(mLock); 198 mTransactionNestCount += 1; 199 } 200} 201 202void 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 239void Composer::setAnimationTransactionImpl() { 240 Mutex::Autolock _l(mLock); 241 mAnimation = true; 242} 243 244layer_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 261status_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 273status_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 289status_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 300status_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 314status_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 326status_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 337status_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 348status_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 365status_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 378DisplayState& 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 390void 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 398void 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 406void 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 421SurfaceComposerClient::SurfaceComposerClient() 422 : mStatus(NO_INIT), mComposer(Composer::getInstance()) 423{ 424} 425 426void 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 437SurfaceComposerClient::~SurfaceComposerClient() { 438 dispose(); 439} 440 441status_t SurfaceComposerClient::initCheck() const { 442 return mStatus; 443} 444 445sp<IBinder> SurfaceComposerClient::connection() const { 446 return (mClient != 0) ? mClient->asBinder() : 0; 447} 448 449status_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 456void 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 467sp<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 488sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, 489 bool secure) { 490 return Composer::getInstance().createDisplay(displayName, secure); 491} 492 493sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) { 494 return Composer::getInstance().getBuiltInDisplay(id); 495} 496 497status_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 504inline Composer& SurfaceComposerClient::getComposer() { 505 return mComposer; 506} 507 508// ---------------------------------------------------------------------------- 509 510void SurfaceComposerClient::openGlobalTransaction() { 511 Composer::openGlobalTransaction(); 512} 513 514void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { 515 Composer::closeGlobalTransaction(synchronous); 516} 517 518void SurfaceComposerClient::setAnimationTransaction() { 519 Composer::setAnimationTransaction(); 520} 521 522// ---------------------------------------------------------------------------- 523 524status_t SurfaceComposerClient::setCrop(const sp<IBinder>& id, const Rect& crop) { 525 return getComposer().setCrop(this, id, crop); 526} 527 528status_t SurfaceComposerClient::setPosition(const sp<IBinder>& id, float x, float y) { 529 return getComposer().setPosition(this, id, x, y); 530} 531 532status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint32_t h) { 533 return getComposer().setSize(this, id, w, h); 534} 535 536status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) { 537 return getComposer().setLayer(this, id, z); 538} 539 540status_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 546status_t SurfaceComposerClient::show(const sp<IBinder>& id) { 547 return getComposer().setFlags(this, id, 548 0, 549 layer_state_t::eLayerHidden); 550} 551 552status_t SurfaceComposerClient::setFlags(const sp<IBinder>& id, uint32_t flags, 553 uint32_t mask) { 554 return getComposer().setFlags(this, id, flags, mask); 555} 556 557status_t SurfaceComposerClient::setTransparentRegionHint(const sp<IBinder>& id, 558 const Region& transparentRegion) { 559 return getComposer().setTransparentRegionHint(this, id, transparentRegion); 560} 561 562status_t SurfaceComposerClient::setAlpha(const sp<IBinder>& id, float alpha) { 563 return getComposer().setAlpha(this, id, alpha); 564} 565 566status_t SurfaceComposerClient::setLayerStack(const sp<IBinder>& id, uint32_t layerStack) { 567 return getComposer().setLayerStack(this, id, layerStack); 568} 569 570status_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 577void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token, 578 const sp<IGraphicBufferProducer>& bufferProducer) { 579 Composer::getInstance().setDisplaySurface(token, bufferProducer); 580} 581 582void SurfaceComposerClient::setDisplayLayerStack(const sp<IBinder>& token, 583 uint32_t layerStack) { 584 Composer::getInstance().setDisplayLayerStack(token, layerStack); 585} 586 587void 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 597status_t SurfaceComposerClient::getDisplayInfo( 598 const sp<IBinder>& display, DisplayInfo* info) 599{ 600 return ComposerService::getComposerService()->getDisplayInfo(display, info); 601} 602 603void SurfaceComposerClient::blankDisplay(const sp<IBinder>& token) { 604 ComposerService::getComposerService()->blank(token); 605} 606 607void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) { 608 ComposerService::getComposerService()->unblank(token); 609} 610 611// ---------------------------------------------------------------------------- 612 613status_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} 623 624ScreenshotClient::ScreenshotClient() 625 : mHaveBuffer(false) { 626 memset(&mBuffer, 0, sizeof(mBuffer)); 627} 628 629ScreenshotClient::~ScreenshotClient() { 630 ScreenshotClient::release(); 631} 632 633sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const { 634 if (mCpuConsumer == NULL) { 635 mBufferQueue = new BufferQueue(); 636 mCpuConsumer = new CpuConsumer(mBufferQueue, 1); 637 mCpuConsumer->setName(String8("ScreenshotClient")); 638 } 639 return mCpuConsumer; 640} 641 642status_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, mBufferQueue, 656 reqWidth, reqHeight, minLayerZ, maxLayerZ); 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 667status_t ScreenshotClient::update(const sp<IBinder>& display) { 668 return ScreenshotClient::update(display, 0, 0, 0, -1UL); 669} 670 671status_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 676void ScreenshotClient::release() { 677 if (mHaveBuffer) { 678 mCpuConsumer->unlockBuffer(mBuffer); 679 memset(&mBuffer, 0, sizeof(mBuffer)); 680 mHaveBuffer = false; 681 } 682 mCpuConsumer.clear(); 683} 684 685void const* ScreenshotClient::getPixels() const { 686 return mBuffer.data; 687} 688 689uint32_t ScreenshotClient::getWidth() const { 690 return mBuffer.width; 691} 692 693uint32_t ScreenshotClient::getHeight() const { 694 return mBuffer.height; 695} 696 697PixelFormat ScreenshotClient::getFormat() const { 698 return mBuffer.format; 699} 700 701uint32_t ScreenshotClient::getStride() const { 702 return mBuffer.stride; 703} 704 705size_t ScreenshotClient::getSize() const { 706 return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format); 707} 708 709// ---------------------------------------------------------------------------- 710}; // namespace android 711