SurfaceComposerClient.cpp revision 2c9b11f0291210c9b9513a1a0cce6afebd361b3b
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 void destroyDisplay(const sp<IBinder>& display); 139 sp<IBinder> getBuiltInDisplay(int32_t id); 140 141 status_t setPosition(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 142 float x, float y); 143 status_t setSize(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 144 uint32_t w, uint32_t h); 145 status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 146 int32_t z); 147 status_t setFlags(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 148 uint32_t flags, uint32_t mask); 149 status_t setTransparentRegionHint( 150 const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 151 const Region& transparentRegion); 152 status_t setAlpha(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 153 float alpha); 154 status_t setMatrix(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 155 float dsdx, float dtdx, float dsdy, float dtdy); 156 status_t setOrientation(int orientation); 157 status_t setCrop(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 158 const Rect& crop); 159 status_t setLayerStack(const sp<SurfaceComposerClient>& client, 160 const sp<IBinder>& id, uint32_t layerStack); 161 162 void setDisplaySurface(const sp<IBinder>& token, 163 const sp<IGraphicBufferProducer>& bufferProducer); 164 void setDisplayLayerStack(const sp<IBinder>& token, uint32_t layerStack); 165 void setDisplayProjection(const sp<IBinder>& token, 166 uint32_t orientation, 167 const Rect& layerStackRect, 168 const Rect& displayRect); 169 170 static void setAnimationTransaction() { 171 Composer::getInstance().setAnimationTransactionImpl(); 172 } 173 174 static void openGlobalTransaction() { 175 Composer::getInstance().openGlobalTransactionImpl(); 176 } 177 178 static void closeGlobalTransaction(bool synchronous) { 179 Composer::getInstance().closeGlobalTransactionImpl(synchronous); 180 } 181}; 182 183ANDROID_SINGLETON_STATIC_INSTANCE(Composer); 184 185// --------------------------------------------------------------------------- 186 187sp<IBinder> Composer::createDisplay(const String8& displayName, bool secure) { 188 return ComposerService::getComposerService()->createDisplay(displayName, 189 secure); 190} 191 192void Composer::destroyDisplay(const sp<IBinder>& display) { 193 return ComposerService::getComposerService()->destroyDisplay(display); 194} 195 196sp<IBinder> Composer::getBuiltInDisplay(int32_t id) { 197 return ComposerService::getComposerService()->getBuiltInDisplay(id); 198} 199 200void Composer::openGlobalTransactionImpl() { 201 { // scope for the lock 202 Mutex::Autolock _l(mLock); 203 mTransactionNestCount += 1; 204 } 205} 206 207void Composer::closeGlobalTransactionImpl(bool synchronous) { 208 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 209 210 Vector<ComposerState> transaction; 211 Vector<DisplayState> displayTransaction; 212 uint32_t flags = 0; 213 214 { // scope for the lock 215 Mutex::Autolock _l(mLock); 216 mForceSynchronous |= synchronous; 217 if (!mTransactionNestCount) { 218 ALOGW("At least one call to closeGlobalTransaction() was not matched by a prior " 219 "call to openGlobalTransaction()."); 220 } else if (--mTransactionNestCount) { 221 return; 222 } 223 224 transaction = mComposerStates; 225 mComposerStates.clear(); 226 227 displayTransaction = mDisplayStates; 228 mDisplayStates.clear(); 229 230 if (mForceSynchronous) { 231 flags |= ISurfaceComposer::eSynchronous; 232 } 233 if (mAnimation) { 234 flags |= ISurfaceComposer::eAnimation; 235 } 236 237 mForceSynchronous = false; 238 mAnimation = false; 239 } 240 241 sm->setTransactionState(transaction, displayTransaction, flags); 242} 243 244void Composer::setAnimationTransactionImpl() { 245 Mutex::Autolock _l(mLock); 246 mAnimation = true; 247} 248 249layer_state_t* Composer::getLayerStateLocked( 250 const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) { 251 252 ComposerState s; 253 s.client = client->mClient; 254 s.state.surface = id; 255 256 ssize_t index = mComposerStates.indexOf(s); 257 if (index < 0) { 258 // we don't have it, add an initialized layer_state to our list 259 index = mComposerStates.add(s); 260 } 261 262 ComposerState* const out = mComposerStates.editArray(); 263 return &(out[index].state); 264} 265 266status_t Composer::setPosition(const sp<SurfaceComposerClient>& client, 267 const sp<IBinder>& id, float x, float y) { 268 Mutex::Autolock _l(mLock); 269 layer_state_t* s = getLayerStateLocked(client, id); 270 if (!s) 271 return BAD_INDEX; 272 s->what |= layer_state_t::ePositionChanged; 273 s->x = x; 274 s->y = y; 275 return NO_ERROR; 276} 277 278status_t Composer::setSize(const sp<SurfaceComposerClient>& client, 279 const sp<IBinder>& id, uint32_t w, uint32_t h) { 280 Mutex::Autolock _l(mLock); 281 layer_state_t* s = getLayerStateLocked(client, id); 282 if (!s) 283 return BAD_INDEX; 284 s->what |= layer_state_t::eSizeChanged; 285 s->w = w; 286 s->h = h; 287 288 // Resizing a surface makes the transaction synchronous. 289 mForceSynchronous = true; 290 291 return NO_ERROR; 292} 293 294status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, 295 const sp<IBinder>& id, int32_t z) { 296 Mutex::Autolock _l(mLock); 297 layer_state_t* s = getLayerStateLocked(client, id); 298 if (!s) 299 return BAD_INDEX; 300 s->what |= layer_state_t::eLayerChanged; 301 s->z = z; 302 return NO_ERROR; 303} 304 305status_t Composer::setFlags(const sp<SurfaceComposerClient>& client, 306 const sp<IBinder>& id, uint32_t flags, 307 uint32_t mask) { 308 Mutex::Autolock _l(mLock); 309 layer_state_t* s = getLayerStateLocked(client, id); 310 if (!s) 311 return BAD_INDEX; 312 if (mask & layer_state_t::eLayerOpaque) { 313 s->what |= layer_state_t::eOpacityChanged; 314 } 315 if (mask & layer_state_t::eLayerHidden) { 316 s->what |= layer_state_t::eVisibilityChanged; 317 } 318 s->flags &= ~mask; 319 s->flags |= (flags & mask); 320 s->mask |= mask; 321 return NO_ERROR; 322} 323 324status_t Composer::setTransparentRegionHint( 325 const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, 326 const Region& transparentRegion) { 327 Mutex::Autolock _l(mLock); 328 layer_state_t* s = getLayerStateLocked(client, id); 329 if (!s) 330 return BAD_INDEX; 331 s->what |= layer_state_t::eTransparentRegionChanged; 332 s->transparentRegion = transparentRegion; 333 return NO_ERROR; 334} 335 336status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client, 337 const sp<IBinder>& id, float alpha) { 338 Mutex::Autolock _l(mLock); 339 layer_state_t* s = getLayerStateLocked(client, id); 340 if (!s) 341 return BAD_INDEX; 342 s->what |= layer_state_t::eAlphaChanged; 343 s->alpha = alpha; 344 return NO_ERROR; 345} 346 347status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client, 348 const sp<IBinder>& id, uint32_t layerStack) { 349 Mutex::Autolock _l(mLock); 350 layer_state_t* s = getLayerStateLocked(client, id); 351 if (!s) 352 return BAD_INDEX; 353 s->what |= layer_state_t::eLayerStackChanged; 354 s->layerStack = layerStack; 355 return NO_ERROR; 356} 357 358status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client, 359 const sp<IBinder>& id, float dsdx, float dtdx, 360 float dsdy, float dtdy) { 361 Mutex::Autolock _l(mLock); 362 layer_state_t* s = getLayerStateLocked(client, id); 363 if (!s) 364 return BAD_INDEX; 365 s->what |= layer_state_t::eMatrixChanged; 366 layer_state_t::matrix22_t matrix; 367 matrix.dsdx = dsdx; 368 matrix.dtdx = dtdx; 369 matrix.dsdy = dsdy; 370 matrix.dtdy = dtdy; 371 s->matrix = matrix; 372 return NO_ERROR; 373} 374 375status_t Composer::setCrop(const sp<SurfaceComposerClient>& client, 376 const sp<IBinder>& id, const Rect& crop) { 377 Mutex::Autolock _l(mLock); 378 layer_state_t* s = getLayerStateLocked(client, id); 379 if (!s) 380 return BAD_INDEX; 381 s->what |= layer_state_t::eCropChanged; 382 s->crop = crop; 383 return NO_ERROR; 384} 385 386// --------------------------------------------------------------------------- 387 388DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) { 389 DisplayState s; 390 s.token = token; 391 ssize_t index = mDisplayStates.indexOf(s); 392 if (index < 0) { 393 // we don't have it, add an initialized layer_state to our list 394 s.what = 0; 395 index = mDisplayStates.add(s); 396 } 397 return mDisplayStates.editItemAt(index); 398} 399 400void Composer::setDisplaySurface(const sp<IBinder>& token, 401 const sp<IGraphicBufferProducer>& bufferProducer) { 402 Mutex::Autolock _l(mLock); 403 DisplayState& s(getDisplayStateLocked(token)); 404 s.surface = bufferProducer; 405 s.what |= DisplayState::eSurfaceChanged; 406} 407 408void Composer::setDisplayLayerStack(const sp<IBinder>& token, 409 uint32_t layerStack) { 410 Mutex::Autolock _l(mLock); 411 DisplayState& s(getDisplayStateLocked(token)); 412 s.layerStack = layerStack; 413 s.what |= DisplayState::eLayerStackChanged; 414} 415 416void Composer::setDisplayProjection(const sp<IBinder>& token, 417 uint32_t orientation, 418 const Rect& layerStackRect, 419 const Rect& displayRect) { 420 Mutex::Autolock _l(mLock); 421 DisplayState& s(getDisplayStateLocked(token)); 422 s.orientation = orientation; 423 s.viewport = layerStackRect; 424 s.frame = displayRect; 425 s.what |= DisplayState::eDisplayProjectionChanged; 426 mForceSynchronous = true; // TODO: do we actually still need this? 427} 428 429// --------------------------------------------------------------------------- 430 431SurfaceComposerClient::SurfaceComposerClient() 432 : mStatus(NO_INIT), mComposer(Composer::getInstance()) 433{ 434} 435 436void SurfaceComposerClient::onFirstRef() { 437 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 438 if (sm != 0) { 439 sp<ISurfaceComposerClient> conn = sm->createConnection(); 440 if (conn != 0) { 441 mClient = conn; 442 mStatus = NO_ERROR; 443 } 444 } 445} 446 447SurfaceComposerClient::~SurfaceComposerClient() { 448 dispose(); 449} 450 451status_t SurfaceComposerClient::initCheck() const { 452 return mStatus; 453} 454 455sp<IBinder> SurfaceComposerClient::connection() const { 456 return (mClient != 0) ? mClient->asBinder() : 0; 457} 458 459status_t SurfaceComposerClient::linkToComposerDeath( 460 const sp<IBinder::DeathRecipient>& recipient, 461 void* cookie, uint32_t flags) { 462 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 463 return sm->asBinder()->linkToDeath(recipient, cookie, flags); 464} 465 466void SurfaceComposerClient::dispose() { 467 // this can be called more than once. 468 sp<ISurfaceComposerClient> client; 469 Mutex::Autolock _lm(mLock); 470 if (mClient != 0) { 471 client = mClient; // hold ref while lock is held 472 mClient.clear(); 473 } 474 mStatus = NO_INIT; 475} 476 477sp<SurfaceControl> SurfaceComposerClient::createSurface( 478 const String8& name, 479 uint32_t w, 480 uint32_t h, 481 PixelFormat format, 482 uint32_t flags) 483{ 484 sp<SurfaceControl> sur; 485 if (mStatus == NO_ERROR) { 486 sp<IBinder> handle; 487 sp<IGraphicBufferProducer> gbp; 488 status_t err = mClient->createSurface(name, w, h, format, flags, 489 &handle, &gbp); 490 ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); 491 if (err == NO_ERROR) { 492 sur = new SurfaceControl(this, handle, gbp); 493 } 494 } 495 return sur; 496} 497 498sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, 499 bool secure) { 500 return Composer::getInstance().createDisplay(displayName, secure); 501} 502 503void SurfaceComposerClient::destroyDisplay(const sp<IBinder>& display) { 504 Composer::getInstance().destroyDisplay(display); 505} 506 507sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) { 508 return Composer::getInstance().getBuiltInDisplay(id); 509} 510 511status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) { 512 if (mStatus != NO_ERROR) 513 return mStatus; 514 status_t err = mClient->destroySurface(sid); 515 return err; 516} 517 518status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) const { 519 if (mStatus != NO_ERROR) { 520 return mStatus; 521 } 522 return mClient->clearLayerFrameStats(token); 523} 524 525status_t SurfaceComposerClient::getLayerFrameStats(const sp<IBinder>& token, 526 FrameStats* outStats) const { 527 if (mStatus != NO_ERROR) { 528 return mStatus; 529 } 530 return mClient->getLayerFrameStats(token, outStats); 531} 532 533inline Composer& SurfaceComposerClient::getComposer() { 534 return mComposer; 535} 536 537// ---------------------------------------------------------------------------- 538 539void SurfaceComposerClient::openGlobalTransaction() { 540 Composer::openGlobalTransaction(); 541} 542 543void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { 544 Composer::closeGlobalTransaction(synchronous); 545} 546 547void SurfaceComposerClient::setAnimationTransaction() { 548 Composer::setAnimationTransaction(); 549} 550 551// ---------------------------------------------------------------------------- 552 553status_t SurfaceComposerClient::setCrop(const sp<IBinder>& id, const Rect& crop) { 554 return getComposer().setCrop(this, id, crop); 555} 556 557status_t SurfaceComposerClient::setPosition(const sp<IBinder>& id, float x, float y) { 558 return getComposer().setPosition(this, id, x, y); 559} 560 561status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint32_t h) { 562 return getComposer().setSize(this, id, w, h); 563} 564 565status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) { 566 return getComposer().setLayer(this, id, z); 567} 568 569status_t SurfaceComposerClient::hide(const sp<IBinder>& id) { 570 return getComposer().setFlags(this, id, 571 layer_state_t::eLayerHidden, 572 layer_state_t::eLayerHidden); 573} 574 575status_t SurfaceComposerClient::show(const sp<IBinder>& id) { 576 return getComposer().setFlags(this, id, 577 0, 578 layer_state_t::eLayerHidden); 579} 580 581status_t SurfaceComposerClient::setFlags(const sp<IBinder>& id, uint32_t flags, 582 uint32_t mask) { 583 return getComposer().setFlags(this, id, flags, mask); 584} 585 586status_t SurfaceComposerClient::setTransparentRegionHint(const sp<IBinder>& id, 587 const Region& transparentRegion) { 588 return getComposer().setTransparentRegionHint(this, id, transparentRegion); 589} 590 591status_t SurfaceComposerClient::setAlpha(const sp<IBinder>& id, float alpha) { 592 return getComposer().setAlpha(this, id, alpha); 593} 594 595status_t SurfaceComposerClient::setLayerStack(const sp<IBinder>& id, uint32_t layerStack) { 596 return getComposer().setLayerStack(this, id, layerStack); 597} 598 599status_t SurfaceComposerClient::setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, 600 float dsdy, float dtdy) { 601 return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy); 602} 603 604// ---------------------------------------------------------------------------- 605 606void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token, 607 const sp<IGraphicBufferProducer>& bufferProducer) { 608 Composer::getInstance().setDisplaySurface(token, bufferProducer); 609} 610 611void SurfaceComposerClient::setDisplayLayerStack(const sp<IBinder>& token, 612 uint32_t layerStack) { 613 Composer::getInstance().setDisplayLayerStack(token, layerStack); 614} 615 616void SurfaceComposerClient::setDisplayProjection(const sp<IBinder>& token, 617 uint32_t orientation, 618 const Rect& layerStackRect, 619 const Rect& displayRect) { 620 Composer::getInstance().setDisplayProjection(token, orientation, 621 layerStackRect, displayRect); 622} 623 624// ---------------------------------------------------------------------------- 625 626status_t SurfaceComposerClient::getDisplayConfigs( 627 const sp<IBinder>& display, Vector<DisplayInfo>* configs) 628{ 629 return ComposerService::getComposerService()->getDisplayConfigs(display, configs); 630} 631 632status_t SurfaceComposerClient::getDisplayInfo(const sp<IBinder>& display, 633 DisplayInfo* info) { 634 Vector<DisplayInfo> configs; 635 status_t result = getDisplayConfigs(display, &configs); 636 if (result != NO_ERROR) { 637 return result; 638 } 639 640 int activeId = getActiveConfig(display); 641 if (activeId < 0) { 642 ALOGE("No active configuration found"); 643 return NAME_NOT_FOUND; 644 } 645 646 *info = configs[activeId]; 647 return NO_ERROR; 648} 649 650int SurfaceComposerClient::getActiveConfig(const sp<IBinder>& display) { 651 return ComposerService::getComposerService()->getActiveConfig(display); 652} 653 654status_t SurfaceComposerClient::setActiveConfig(const sp<IBinder>& display, int id) { 655 return ComposerService::getComposerService()->setActiveConfig(display, id); 656} 657 658void SurfaceComposerClient::setDisplayPowerMode(const sp<IBinder>& token, 659 int mode) { 660 ComposerService::getComposerService()->setPowerMode(token, mode); 661} 662 663status_t SurfaceComposerClient::clearAnimationFrameStats() { 664 return ComposerService::getComposerService()->clearAnimationFrameStats(); 665} 666 667status_t SurfaceComposerClient::getAnimationFrameStats(FrameStats* outStats) { 668 return ComposerService::getComposerService()->getAnimationFrameStats(outStats); 669} 670 671// ---------------------------------------------------------------------------- 672 673status_t ScreenshotClient::capture( 674 const sp<IBinder>& display, 675 const sp<IGraphicBufferProducer>& producer, 676 Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 677 uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform) { 678 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 679 if (s == NULL) return NO_INIT; 680 return s->captureScreen(display, producer, sourceCrop, 681 reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform); 682} 683 684ScreenshotClient::ScreenshotClient() 685 : mHaveBuffer(false) { 686 memset(&mBuffer, 0, sizeof(mBuffer)); 687} 688 689ScreenshotClient::~ScreenshotClient() { 690 ScreenshotClient::release(); 691} 692 693sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const { 694 if (mCpuConsumer == NULL) { 695 sp<IGraphicBufferConsumer> consumer; 696 BufferQueue::createBufferQueue(&mProducer, &consumer); 697 mCpuConsumer = new CpuConsumer(consumer, 1); 698 mCpuConsumer->setName(String8("ScreenshotClient")); 699 } 700 return mCpuConsumer; 701} 702 703status_t ScreenshotClient::update(const sp<IBinder>& display, 704 Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 705 uint32_t minLayerZ, uint32_t maxLayerZ, 706 bool useIdentityTransform) { 707 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 708 if (s == NULL) return NO_INIT; 709 sp<CpuConsumer> cpuConsumer = getCpuConsumer(); 710 711 if (mHaveBuffer) { 712 mCpuConsumer->unlockBuffer(mBuffer); 713 memset(&mBuffer, 0, sizeof(mBuffer)); 714 mHaveBuffer = false; 715 } 716 717 status_t err = s->captureScreen(display, mProducer, sourceCrop, 718 reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform); 719 720 if (err == NO_ERROR) { 721 err = mCpuConsumer->lockNextBuffer(&mBuffer); 722 if (err == NO_ERROR) { 723 mHaveBuffer = true; 724 } 725 } 726 return err; 727} 728 729status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, 730 bool useIdentityTransform) { 731 return ScreenshotClient::update(display, sourceCrop, 0, 0, 0, -1UL, 732 useIdentityTransform); 733} 734 735status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, 736 uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) { 737 return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight, 738 0, -1UL, useIdentityTransform); 739} 740 741void ScreenshotClient::release() { 742 if (mHaveBuffer) { 743 mCpuConsumer->unlockBuffer(mBuffer); 744 memset(&mBuffer, 0, sizeof(mBuffer)); 745 mHaveBuffer = false; 746 } 747 mCpuConsumer.clear(); 748} 749 750void const* ScreenshotClient::getPixels() const { 751 return mBuffer.data; 752} 753 754uint32_t ScreenshotClient::getWidth() const { 755 return mBuffer.width; 756} 757 758uint32_t ScreenshotClient::getHeight() const { 759 return mBuffer.height; 760} 761 762PixelFormat ScreenshotClient::getFormat() const { 763 return mBuffer.format; 764} 765 766uint32_t ScreenshotClient::getStride() const { 767 return mBuffer.stride; 768} 769 770size_t ScreenshotClient::getSize() const { 771 return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format); 772} 773 774// ---------------------------------------------------------------------------- 775}; // namespace android 776