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