Home | History | Annotate | Download | only in gui
      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     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 
    183 ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
    184 
    185 // ---------------------------------------------------------------------------
    186 
    187 sp<IBinder> Composer::createDisplay(const String8& displayName, bool secure) {
    188     return ComposerService::getComposerService()->createDisplay(displayName,
    189             secure);
    190 }
    191 
    192 void Composer::destroyDisplay(const sp<IBinder>& display) {
    193     return ComposerService::getComposerService()->destroyDisplay(display);
    194 }
    195 
    196 sp<IBinder> Composer::getBuiltInDisplay(int32_t id) {
    197     return ComposerService::getComposerService()->getBuiltInDisplay(id);
    198 }
    199 
    200 void Composer::openGlobalTransactionImpl() {
    201     { // scope for the lock
    202         Mutex::Autolock _l(mLock);
    203         mTransactionNestCount += 1;
    204     }
    205 }
    206 
    207 void 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 
    244 void Composer::setAnimationTransactionImpl() {
    245     Mutex::Autolock _l(mLock);
    246     mAnimation = true;
    247 }
    248 
    249 layer_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 
    266 status_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 
    278 status_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 
    294 status_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 
    305 status_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     s->what |= layer_state_t::eVisibilityChanged;
    313     s->flags &= ~mask;
    314     s->flags |= (flags & mask);
    315     s->mask |= mask;
    316     return NO_ERROR;
    317 }
    318 
    319 status_t Composer::setTransparentRegionHint(
    320         const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
    321         const Region& transparentRegion) {
    322     Mutex::Autolock _l(mLock);
    323     layer_state_t* s = getLayerStateLocked(client, id);
    324     if (!s)
    325         return BAD_INDEX;
    326     s->what |= layer_state_t::eTransparentRegionChanged;
    327     s->transparentRegion = transparentRegion;
    328     return NO_ERROR;
    329 }
    330 
    331 status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
    332         const sp<IBinder>& id, float alpha) {
    333     Mutex::Autolock _l(mLock);
    334     layer_state_t* s = getLayerStateLocked(client, id);
    335     if (!s)
    336         return BAD_INDEX;
    337     s->what |= layer_state_t::eAlphaChanged;
    338     s->alpha = alpha;
    339     return NO_ERROR;
    340 }
    341 
    342 status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client,
    343         const sp<IBinder>& id, uint32_t layerStack) {
    344     Mutex::Autolock _l(mLock);
    345     layer_state_t* s = getLayerStateLocked(client, id);
    346     if (!s)
    347         return BAD_INDEX;
    348     s->what |= layer_state_t::eLayerStackChanged;
    349     s->layerStack = layerStack;
    350     return NO_ERROR;
    351 }
    352 
    353 status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
    354         const sp<IBinder>& id, float dsdx, float dtdx,
    355         float dsdy, float dtdy) {
    356     Mutex::Autolock _l(mLock);
    357     layer_state_t* s = getLayerStateLocked(client, id);
    358     if (!s)
    359         return BAD_INDEX;
    360     s->what |= layer_state_t::eMatrixChanged;
    361     layer_state_t::matrix22_t matrix;
    362     matrix.dsdx = dsdx;
    363     matrix.dtdx = dtdx;
    364     matrix.dsdy = dsdy;
    365     matrix.dtdy = dtdy;
    366     s->matrix = matrix;
    367     return NO_ERROR;
    368 }
    369 
    370 status_t Composer::setCrop(const sp<SurfaceComposerClient>& client,
    371         const sp<IBinder>& id, const Rect& crop) {
    372     Mutex::Autolock _l(mLock);
    373     layer_state_t* s = getLayerStateLocked(client, id);
    374     if (!s)
    375         return BAD_INDEX;
    376     s->what |= layer_state_t::eCropChanged;
    377     s->crop = crop;
    378     return NO_ERROR;
    379 }
    380 
    381 // ---------------------------------------------------------------------------
    382 
    383 DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) {
    384     DisplayState s;
    385     s.token = token;
    386     ssize_t index = mDisplayStates.indexOf(s);
    387     if (index < 0) {
    388         // we don't have it, add an initialized layer_state to our list
    389         s.what = 0;
    390         index = mDisplayStates.add(s);
    391     }
    392     return mDisplayStates.editItemAt(index);
    393 }
    394 
    395 void Composer::setDisplaySurface(const sp<IBinder>& token,
    396         const sp<IGraphicBufferProducer>& bufferProducer) {
    397     Mutex::Autolock _l(mLock);
    398     DisplayState& s(getDisplayStateLocked(token));
    399     s.surface = bufferProducer;
    400     s.what |= DisplayState::eSurfaceChanged;
    401 }
    402 
    403 void Composer::setDisplayLayerStack(const sp<IBinder>& token,
    404         uint32_t layerStack) {
    405     Mutex::Autolock _l(mLock);
    406     DisplayState& s(getDisplayStateLocked(token));
    407     s.layerStack = layerStack;
    408     s.what |= DisplayState::eLayerStackChanged;
    409 }
    410 
    411 void Composer::setDisplayProjection(const sp<IBinder>& token,
    412         uint32_t orientation,
    413         const Rect& layerStackRect,
    414         const Rect& displayRect) {
    415     Mutex::Autolock _l(mLock);
    416     DisplayState& s(getDisplayStateLocked(token));
    417     s.orientation = orientation;
    418     s.viewport = layerStackRect;
    419     s.frame = displayRect;
    420     s.what |= DisplayState::eDisplayProjectionChanged;
    421     mForceSynchronous = true; // TODO: do we actually still need this?
    422 }
    423 
    424 // ---------------------------------------------------------------------------
    425 
    426 SurfaceComposerClient::SurfaceComposerClient()
    427     : mStatus(NO_INIT), mComposer(Composer::getInstance())
    428 {
    429 }
    430 
    431 void SurfaceComposerClient::onFirstRef() {
    432     sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    433     if (sm != 0) {
    434         sp<ISurfaceComposerClient> conn = sm->createConnection();
    435         if (conn != 0) {
    436             mClient = conn;
    437             mStatus = NO_ERROR;
    438         }
    439     }
    440 }
    441 
    442 SurfaceComposerClient::~SurfaceComposerClient() {
    443     dispose();
    444 }
    445 
    446 status_t SurfaceComposerClient::initCheck() const {
    447     return mStatus;
    448 }
    449 
    450 sp<IBinder> SurfaceComposerClient::connection() const {
    451     return (mClient != 0) ? mClient->asBinder() : 0;
    452 }
    453 
    454 status_t SurfaceComposerClient::linkToComposerDeath(
    455         const sp<IBinder::DeathRecipient>& recipient,
    456         void* cookie, uint32_t flags) {
    457     sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    458     return sm->asBinder()->linkToDeath(recipient, cookie, flags);
    459 }
    460 
    461 void SurfaceComposerClient::dispose() {
    462     // this can be called more than once.
    463     sp<ISurfaceComposerClient> client;
    464     Mutex::Autolock _lm(mLock);
    465     if (mClient != 0) {
    466         client = mClient; // hold ref while lock is held
    467         mClient.clear();
    468     }
    469     mStatus = NO_INIT;
    470 }
    471 
    472 sp<SurfaceControl> SurfaceComposerClient::createSurface(
    473         const String8& name,
    474         uint32_t w,
    475         uint32_t h,
    476         PixelFormat format,
    477         uint32_t flags)
    478 {
    479     sp<SurfaceControl> sur;
    480     if (mStatus == NO_ERROR) {
    481         sp<IBinder> handle;
    482         sp<IGraphicBufferProducer> gbp;
    483         status_t err = mClient->createSurface(name, w, h, format, flags,
    484                 &handle, &gbp);
    485         ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
    486         if (err == NO_ERROR) {
    487             sur = new SurfaceControl(this, handle, gbp);
    488         }
    489     }
    490     return sur;
    491 }
    492 
    493 sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName,
    494         bool secure) {
    495     return Composer::getInstance().createDisplay(displayName, secure);
    496 }
    497 
    498 void SurfaceComposerClient::destroyDisplay(const sp<IBinder>& display) {
    499     Composer::getInstance().destroyDisplay(display);
    500 }
    501 
    502 sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) {
    503     return Composer::getInstance().getBuiltInDisplay(id);
    504 }
    505 
    506 status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) {
    507     if (mStatus != NO_ERROR)
    508         return mStatus;
    509     status_t err = mClient->destroySurface(sid);
    510     return err;
    511 }
    512 
    513 inline Composer& SurfaceComposerClient::getComposer() {
    514     return mComposer;
    515 }
    516 
    517 // ----------------------------------------------------------------------------
    518 
    519 void SurfaceComposerClient::openGlobalTransaction() {
    520     Composer::openGlobalTransaction();
    521 }
    522 
    523 void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
    524     Composer::closeGlobalTransaction(synchronous);
    525 }
    526 
    527 void SurfaceComposerClient::setAnimationTransaction() {
    528     Composer::setAnimationTransaction();
    529 }
    530 
    531 // ----------------------------------------------------------------------------
    532 
    533 status_t SurfaceComposerClient::setCrop(const sp<IBinder>& id, const Rect& crop) {
    534     return getComposer().setCrop(this, id, crop);
    535 }
    536 
    537 status_t SurfaceComposerClient::setPosition(const sp<IBinder>& id, float x, float y) {
    538     return getComposer().setPosition(this, id, x, y);
    539 }
    540 
    541 status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint32_t h) {
    542     return getComposer().setSize(this, id, w, h);
    543 }
    544 
    545 status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) {
    546     return getComposer().setLayer(this, id, z);
    547 }
    548 
    549 status_t SurfaceComposerClient::hide(const sp<IBinder>& id) {
    550     return getComposer().setFlags(this, id,
    551             layer_state_t::eLayerHidden,
    552             layer_state_t::eLayerHidden);
    553 }
    554 
    555 status_t SurfaceComposerClient::show(const sp<IBinder>& id) {
    556     return getComposer().setFlags(this, id,
    557             0,
    558             layer_state_t::eLayerHidden);
    559 }
    560 
    561 status_t SurfaceComposerClient::setFlags(const sp<IBinder>& id, uint32_t flags,
    562         uint32_t mask) {
    563     return getComposer().setFlags(this, id, flags, mask);
    564 }
    565 
    566 status_t SurfaceComposerClient::setTransparentRegionHint(const sp<IBinder>& id,
    567         const Region& transparentRegion) {
    568     return getComposer().setTransparentRegionHint(this, id, transparentRegion);
    569 }
    570 
    571 status_t SurfaceComposerClient::setAlpha(const sp<IBinder>& id, float alpha) {
    572     return getComposer().setAlpha(this, id, alpha);
    573 }
    574 
    575 status_t SurfaceComposerClient::setLayerStack(const sp<IBinder>& id, uint32_t layerStack) {
    576     return getComposer().setLayerStack(this, id, layerStack);
    577 }
    578 
    579 status_t SurfaceComposerClient::setMatrix(const sp<IBinder>& id, float dsdx, float dtdx,
    580         float dsdy, float dtdy) {
    581     return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
    582 }
    583 
    584 // ----------------------------------------------------------------------------
    585 
    586 void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token,
    587         const sp<IGraphicBufferProducer>& bufferProducer) {
    588     Composer::getInstance().setDisplaySurface(token, bufferProducer);
    589 }
    590 
    591 void SurfaceComposerClient::setDisplayLayerStack(const sp<IBinder>& token,
    592         uint32_t layerStack) {
    593     Composer::getInstance().setDisplayLayerStack(token, layerStack);
    594 }
    595 
    596 void SurfaceComposerClient::setDisplayProjection(const sp<IBinder>& token,
    597         uint32_t orientation,
    598         const Rect& layerStackRect,
    599         const Rect& displayRect) {
    600     Composer::getInstance().setDisplayProjection(token, orientation,
    601             layerStackRect, displayRect);
    602 }
    603 
    604 // ----------------------------------------------------------------------------
    605 
    606 status_t SurfaceComposerClient::getDisplayInfo(
    607         const sp<IBinder>& display, DisplayInfo* info)
    608 {
    609     return ComposerService::getComposerService()->getDisplayInfo(display, info);
    610 }
    611 
    612 void SurfaceComposerClient::blankDisplay(const sp<IBinder>& token) {
    613     ComposerService::getComposerService()->blank(token);
    614 }
    615 
    616 void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) {
    617     ComposerService::getComposerService()->unblank(token);
    618 }
    619 
    620 // ----------------------------------------------------------------------------
    621 
    622 status_t ScreenshotClient::capture(
    623         const sp<IBinder>& display,
    624         const sp<IGraphicBufferProducer>& producer,
    625         uint32_t reqWidth, uint32_t reqHeight,
    626         uint32_t minLayerZ, uint32_t maxLayerZ) {
    627     sp<ISurfaceComposer> s(ComposerService::getComposerService());
    628     if (s == NULL) return NO_INIT;
    629     return s->captureScreen(display, producer,
    630             reqWidth, reqHeight, minLayerZ, maxLayerZ);
    631 }
    632 
    633 ScreenshotClient::ScreenshotClient()
    634     : mHaveBuffer(false) {
    635     memset(&mBuffer, 0, sizeof(mBuffer));
    636 }
    637 
    638 ScreenshotClient::~ScreenshotClient() {
    639     ScreenshotClient::release();
    640 }
    641 
    642 sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const {
    643     if (mCpuConsumer == NULL) {
    644         mBufferQueue = new BufferQueue();
    645         mCpuConsumer = new CpuConsumer(mBufferQueue, 1);
    646         mCpuConsumer->setName(String8("ScreenshotClient"));
    647     }
    648     return mCpuConsumer;
    649 }
    650 
    651 status_t ScreenshotClient::update(const sp<IBinder>& display,
    652         uint32_t reqWidth, uint32_t reqHeight,
    653         uint32_t minLayerZ, uint32_t maxLayerZ) {
    654     sp<ISurfaceComposer> s(ComposerService::getComposerService());
    655     if (s == NULL) return NO_INIT;
    656     sp<CpuConsumer> cpuConsumer = getCpuConsumer();
    657 
    658     if (mHaveBuffer) {
    659         mCpuConsumer->unlockBuffer(mBuffer);
    660         memset(&mBuffer, 0, sizeof(mBuffer));
    661         mHaveBuffer = false;
    662     }
    663 
    664     status_t err = s->captureScreen(display, mBufferQueue,
    665             reqWidth, reqHeight, minLayerZ, maxLayerZ);
    666 
    667     if (err == NO_ERROR) {
    668         err = mCpuConsumer->lockNextBuffer(&mBuffer);
    669         if (err == NO_ERROR) {
    670             mHaveBuffer = true;
    671         }
    672     }
    673     return err;
    674 }
    675 
    676 status_t ScreenshotClient::update(const sp<IBinder>& display) {
    677     return ScreenshotClient::update(display, 0, 0, 0, -1UL);
    678 }
    679 
    680 status_t ScreenshotClient::update(const sp<IBinder>& display,
    681         uint32_t reqWidth, uint32_t reqHeight) {
    682     return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL);
    683 }
    684 
    685 void ScreenshotClient::release() {
    686     if (mHaveBuffer) {
    687         mCpuConsumer->unlockBuffer(mBuffer);
    688         memset(&mBuffer, 0, sizeof(mBuffer));
    689         mHaveBuffer = false;
    690     }
    691     mCpuConsumer.clear();
    692 }
    693 
    694 void const* ScreenshotClient::getPixels() const {
    695     return mBuffer.data;
    696 }
    697 
    698 uint32_t ScreenshotClient::getWidth() const {
    699     return mBuffer.width;
    700 }
    701 
    702 uint32_t ScreenshotClient::getHeight() const {
    703     return mBuffer.height;
    704 }
    705 
    706 PixelFormat ScreenshotClient::getFormat() const {
    707     return mBuffer.format;
    708 }
    709 
    710 uint32_t ScreenshotClient::getStride() const {
    711     return mBuffer.stride;
    712 }
    713 
    714 size_t ScreenshotClient::getSize() const {
    715     return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format);
    716 }
    717 
    718 // ----------------------------------------------------------------------------
    719 }; // namespace android
    720