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 <surfaceflinger/ISurface.h>
     35 #include <surfaceflinger/ISurfaceComposer.h>
     36 #include <surfaceflinger/ISurfaceComposerClient.h>
     37 #include <surfaceflinger/SurfaceComposerClient.h>
     38 
     39 #include <private/surfaceflinger/LayerState.h>
     40 #include <private/surfaceflinger/SharedBufferStack.h>
     41 
     42 
     43 namespace android {
     44 // ---------------------------------------------------------------------------
     45 
     46 ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
     47 
     48 ComposerService::ComposerService()
     49 : Singleton<ComposerService>() {
     50     const String16 name("SurfaceFlinger");
     51     while (getService(name, &mComposerService) != NO_ERROR) {
     52         usleep(250000);
     53     }
     54     mServerCblkMemory = mComposerService->getCblk();
     55     mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
     56             mServerCblkMemory->getBase());
     57 }
     58 
     59 sp<ISurfaceComposer> ComposerService::getComposerService() {
     60     return ComposerService::getInstance().mComposerService;
     61 }
     62 
     63 surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() {
     64     return ComposerService::getInstance().mServerCblk;
     65 }
     66 
     67 static inline sp<ISurfaceComposer> getComposerService() {
     68     return ComposerService::getComposerService();
     69 }
     70 
     71 static inline surface_flinger_cblk_t const volatile * get_cblk() {
     72     return ComposerService::getControlBlock();
     73 }
     74 
     75 // ---------------------------------------------------------------------------
     76 
     77 // NOTE: this is NOT a member function (it's a friend defined with its
     78 // declaration).
     79 static inline
     80 int compare_type( const ComposerState& lhs, const ComposerState& rhs) {
     81     if (lhs.client < rhs.client)  return -1;
     82     if (lhs.client > rhs.client)  return 1;
     83     if (lhs.state.surface < rhs.state.surface)  return -1;
     84     if (lhs.state.surface > rhs.state.surface)  return 1;
     85     return 0;
     86 }
     87 
     88 class Composer : public Singleton<Composer>
     89 {
     90     friend class Singleton<Composer>;
     91 
     92     mutable Mutex               mLock;
     93     SortedVector<ComposerState> mStates;
     94     int                         mOrientation;
     95 
     96     Composer() : Singleton<Composer>(),
     97         mOrientation(ISurfaceComposer::eOrientationUnchanged) { }
     98 
     99     void closeGlobalTransactionImpl();
    100 
    101     layer_state_t* getLayerStateLocked(
    102             const sp<SurfaceComposerClient>& client, SurfaceID id);
    103 
    104 public:
    105 
    106     status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
    107             float x, float y);
    108     status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id,
    109             uint32_t w, uint32_t h);
    110     status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id,
    111             int32_t z);
    112     status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id,
    113             uint32_t flags, uint32_t mask);
    114     status_t setTransparentRegionHint(
    115             const sp<SurfaceComposerClient>& client, SurfaceID id,
    116             const Region& transparentRegion);
    117     status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id,
    118             float alpha);
    119     status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
    120             float dsdx, float dtdx, float dsdy, float dtdy);
    121     status_t setFreezeTint(
    122             const sp<SurfaceComposerClient>& client, SurfaceID id,
    123             uint32_t tint);
    124     status_t setOrientation(int orientation);
    125 
    126     static void closeGlobalTransaction() {
    127         Composer::getInstance().closeGlobalTransactionImpl();
    128     }
    129 };
    130 
    131 ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
    132 
    133 // ---------------------------------------------------------------------------
    134 
    135 void Composer::closeGlobalTransactionImpl() {
    136     sp<ISurfaceComposer> sm(getComposerService());
    137 
    138     Vector<ComposerState> transaction;
    139     int orientation;
    140 
    141     { // scope for the lock
    142         Mutex::Autolock _l(mLock);
    143         transaction = mStates;
    144         mStates.clear();
    145 
    146         orientation = mOrientation;
    147         mOrientation = ISurfaceComposer::eOrientationUnchanged;
    148     }
    149 
    150    sm->setTransactionState(transaction, orientation);
    151 }
    152 
    153 layer_state_t* Composer::getLayerStateLocked(
    154         const sp<SurfaceComposerClient>& client, SurfaceID id) {
    155 
    156     ComposerState s;
    157     s.client = client->mClient;
    158     s.state.surface = id;
    159 
    160     ssize_t index = mStates.indexOf(s);
    161     if (index < 0) {
    162         // we don't have it, add an initialized layer_state to our list
    163         index = mStates.add(s);
    164     }
    165 
    166     ComposerState* const out = mStates.editArray();
    167     return &(out[index].state);
    168 }
    169 
    170 status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
    171         SurfaceID id, float x, float y) {
    172     Mutex::Autolock _l(mLock);
    173     layer_state_t* s = getLayerStateLocked(client, id);
    174     if (!s)
    175         return BAD_INDEX;
    176     s->what |= ISurfaceComposer::ePositionChanged;
    177     s->x = x;
    178     s->y = y;
    179     return NO_ERROR;
    180 }
    181 
    182 status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
    183         SurfaceID id, uint32_t w, uint32_t h) {
    184     Mutex::Autolock _l(mLock);
    185     layer_state_t* s = getLayerStateLocked(client, id);
    186     if (!s)
    187         return BAD_INDEX;
    188     s->what |= ISurfaceComposer::eSizeChanged;
    189     s->w = w;
    190     s->h = h;
    191     return NO_ERROR;
    192 }
    193 
    194 status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
    195         SurfaceID id, int32_t z) {
    196     Mutex::Autolock _l(mLock);
    197     layer_state_t* s = getLayerStateLocked(client, id);
    198     if (!s)
    199         return BAD_INDEX;
    200     s->what |= ISurfaceComposer::eLayerChanged;
    201     s->z = z;
    202     return NO_ERROR;
    203 }
    204 
    205 status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
    206         SurfaceID id, uint32_t flags,
    207         uint32_t mask) {
    208     Mutex::Autolock _l(mLock);
    209     layer_state_t* s = getLayerStateLocked(client, id);
    210     if (!s)
    211         return BAD_INDEX;
    212     s->what |= ISurfaceComposer::eVisibilityChanged;
    213     s->flags &= ~mask;
    214     s->flags |= (flags & mask);
    215     s->mask |= mask;
    216     return NO_ERROR;
    217 }
    218 
    219 status_t Composer::setTransparentRegionHint(
    220         const sp<SurfaceComposerClient>& client, SurfaceID id,
    221         const Region& transparentRegion) {
    222     Mutex::Autolock _l(mLock);
    223     layer_state_t* s = getLayerStateLocked(client, id);
    224     if (!s)
    225         return BAD_INDEX;
    226     s->what |= ISurfaceComposer::eTransparentRegionChanged;
    227     s->transparentRegion = transparentRegion;
    228     return NO_ERROR;
    229 }
    230 
    231 status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
    232         SurfaceID id, float alpha) {
    233     Mutex::Autolock _l(mLock);
    234     layer_state_t* s = getLayerStateLocked(client, id);
    235     if (!s)
    236         return BAD_INDEX;
    237     s->what |= ISurfaceComposer::eAlphaChanged;
    238     s->alpha = alpha;
    239     return NO_ERROR;
    240 }
    241 
    242 status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
    243         SurfaceID id, float dsdx, float dtdx,
    244         float dsdy, float dtdy) {
    245     Mutex::Autolock _l(mLock);
    246     layer_state_t* s = getLayerStateLocked(client, id);
    247     if (!s)
    248         return BAD_INDEX;
    249     s->what |= ISurfaceComposer::eMatrixChanged;
    250     layer_state_t::matrix22_t matrix;
    251     matrix.dsdx = dsdx;
    252     matrix.dtdx = dtdx;
    253     matrix.dsdy = dsdy;
    254     matrix.dtdy = dtdy;
    255     s->matrix = matrix;
    256     return NO_ERROR;
    257 }
    258 
    259 status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client,
    260         SurfaceID id, uint32_t tint) {
    261     Mutex::Autolock _l(mLock);
    262     layer_state_t* s = getLayerStateLocked(client, id);
    263     if (!s)
    264         return BAD_INDEX;
    265     s->what |= ISurfaceComposer::eFreezeTintChanged;
    266     s->tint = tint;
    267     return NO_ERROR;
    268 }
    269 
    270 status_t Composer::setOrientation(int orientation) {
    271     Mutex::Autolock _l(mLock);
    272     mOrientation = orientation;
    273     return NO_ERROR;
    274 }
    275 
    276 // ---------------------------------------------------------------------------
    277 
    278 SurfaceComposerClient::SurfaceComposerClient()
    279     : mStatus(NO_INIT), mComposer(Composer::getInstance())
    280 {
    281 }
    282 
    283 void SurfaceComposerClient::onFirstRef() {
    284     sp<ISurfaceComposer> sm(getComposerService());
    285     if (sm != 0) {
    286         sp<ISurfaceComposerClient> conn = sm->createConnection();
    287         if (conn != 0) {
    288             mClient = conn;
    289             mStatus = NO_ERROR;
    290         }
    291     }
    292 }
    293 
    294 SurfaceComposerClient::~SurfaceComposerClient() {
    295     dispose();
    296 }
    297 
    298 status_t SurfaceComposerClient::initCheck() const {
    299     return mStatus;
    300 }
    301 
    302 sp<IBinder> SurfaceComposerClient::connection() const {
    303     return (mClient != 0) ? mClient->asBinder() : 0;
    304 }
    305 
    306 status_t SurfaceComposerClient::linkToComposerDeath(
    307         const sp<IBinder::DeathRecipient>& recipient,
    308         void* cookie, uint32_t flags) {
    309     sp<ISurfaceComposer> sm(getComposerService());
    310     return sm->asBinder()->linkToDeath(recipient, cookie, flags);
    311 }
    312 
    313 void SurfaceComposerClient::dispose() {
    314     // this can be called more than once.
    315     sp<ISurfaceComposerClient> client;
    316     Mutex::Autolock _lm(mLock);
    317     if (mClient != 0) {
    318         client = mClient; // hold ref while lock is held
    319         mClient.clear();
    320     }
    321     mStatus = NO_INIT;
    322 }
    323 
    324 sp<SurfaceControl> SurfaceComposerClient::createSurface(
    325         DisplayID display,
    326         uint32_t w,
    327         uint32_t h,
    328         PixelFormat format,
    329         uint32_t flags)
    330 {
    331     String8 name;
    332     const size_t SIZE = 128;
    333     char buffer[SIZE];
    334     snprintf(buffer, SIZE, "<pid_%d>", getpid());
    335     name.append(buffer);
    336 
    337     return SurfaceComposerClient::createSurface(name, display,
    338             w, h, format, flags);
    339 }
    340 
    341 sp<SurfaceControl> SurfaceComposerClient::createSurface(
    342         const String8& name,
    343         DisplayID display,
    344         uint32_t w,
    345         uint32_t h,
    346         PixelFormat format,
    347         uint32_t flags)
    348 {
    349     sp<SurfaceControl> result;
    350     if (mStatus == NO_ERROR) {
    351         ISurfaceComposerClient::surface_data_t data;
    352         sp<ISurface> surface = mClient->createSurface(&data, name,
    353                 display, w, h, format, flags);
    354         if (surface != 0) {
    355             result = new SurfaceControl(this, surface, data);
    356         }
    357     }
    358     return result;
    359 }
    360 
    361 status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
    362     if (mStatus != NO_ERROR)
    363         return mStatus;
    364     status_t err = mClient->destroySurface(sid);
    365     return err;
    366 }
    367 
    368 inline Composer& SurfaceComposerClient::getComposer() {
    369     return mComposer;
    370 }
    371 
    372 // ----------------------------------------------------------------------------
    373 
    374 void SurfaceComposerClient::openGlobalTransaction() {
    375     // Currently a no-op
    376 }
    377 
    378 void SurfaceComposerClient::closeGlobalTransaction() {
    379     Composer::closeGlobalTransaction();
    380 }
    381 
    382 // ----------------------------------------------------------------------------
    383 
    384 status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) {
    385     return getComposer().setFreezeTint(this, id, tint);
    386 }
    387 
    388 status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
    389     return getComposer().setPosition(this, id, x, y);
    390 }
    391 
    392 status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
    393     return getComposer().setSize(this, id, w, h);
    394 }
    395 
    396 status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) {
    397     return getComposer().setLayer(this, id, z);
    398 }
    399 
    400 status_t SurfaceComposerClient::hide(SurfaceID id) {
    401     return getComposer().setFlags(this, id,
    402             ISurfaceComposer::eLayerHidden,
    403             ISurfaceComposer::eLayerHidden);
    404 }
    405 
    406 status_t SurfaceComposerClient::show(SurfaceID id, int32_t) {
    407     return getComposer().setFlags(this, id,
    408             0,
    409             ISurfaceComposer::eLayerHidden);
    410 }
    411 
    412 status_t SurfaceComposerClient::freeze(SurfaceID id) {
    413     return getComposer().setFlags(this, id,
    414             ISurfaceComposer::eLayerFrozen,
    415             ISurfaceComposer::eLayerFrozen);
    416 }
    417 
    418 status_t SurfaceComposerClient::unfreeze(SurfaceID id) {
    419     return getComposer().setFlags(this, id,
    420             0,
    421             ISurfaceComposer::eLayerFrozen);
    422 }
    423 
    424 status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
    425         uint32_t mask) {
    426     return getComposer().setFlags(this, id, flags, mask);
    427 }
    428 
    429 status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id,
    430         const Region& transparentRegion) {
    431     return getComposer().setTransparentRegionHint(this, id, transparentRegion);
    432 }
    433 
    434 status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) {
    435     return getComposer().setAlpha(this, id, alpha);
    436 }
    437 
    438 status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
    439         float dsdy, float dtdy) {
    440     return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
    441 }
    442 
    443 status_t SurfaceComposerClient::setOrientation(DisplayID dpy,
    444         int orientation, uint32_t flags)
    445 {
    446     return Composer::getInstance().setOrientation(orientation);
    447 }
    448 
    449 // ----------------------------------------------------------------------------
    450 
    451 status_t SurfaceComposerClient::getDisplayInfo(
    452         DisplayID dpy, DisplayInfo* info)
    453 {
    454     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
    455         return BAD_VALUE;
    456 
    457     volatile surface_flinger_cblk_t const * cblk = get_cblk();
    458     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
    459 
    460     info->w              = dcblk->w;
    461     info->h              = dcblk->h;
    462     info->orientation    = dcblk->orientation;
    463     info->xdpi           = dcblk->xdpi;
    464     info->ydpi           = dcblk->ydpi;
    465     info->fps            = dcblk->fps;
    466     info->density        = dcblk->density;
    467     return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
    468 }
    469 
    470 ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
    471 {
    472     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
    473         return BAD_VALUE;
    474     volatile surface_flinger_cblk_t const * cblk = get_cblk();
    475     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
    476     return dcblk->w;
    477 }
    478 
    479 ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
    480 {
    481     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
    482         return BAD_VALUE;
    483     volatile surface_flinger_cblk_t const * cblk = get_cblk();
    484     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
    485     return dcblk->h;
    486 }
    487 
    488 ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
    489 {
    490     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
    491         return BAD_VALUE;
    492     volatile surface_flinger_cblk_t const * cblk = get_cblk();
    493     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
    494     return dcblk->orientation;
    495 }
    496 
    497 ssize_t SurfaceComposerClient::getNumberOfDisplays()
    498 {
    499     volatile surface_flinger_cblk_t const * cblk = get_cblk();
    500     uint32_t connected = cblk->connected;
    501     int n = 0;
    502     while (connected) {
    503         if (connected&1) n++;
    504         connected >>= 1;
    505     }
    506     return n;
    507 }
    508 
    509 // ----------------------------------------------------------------------------
    510 
    511 status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
    512 {
    513     // This has been made a no-op because it can cause Gralloc buffer deadlocks.
    514     return NO_ERROR;
    515 }
    516 
    517 status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
    518 {
    519     // This has been made a no-op because it can cause Gralloc buffer deadlocks.
    520     return NO_ERROR;
    521 }
    522 
    523 // ----------------------------------------------------------------------------
    524 
    525 ScreenshotClient::ScreenshotClient()
    526     : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
    527 }
    528 
    529 status_t ScreenshotClient::update() {
    530     sp<ISurfaceComposer> s(ComposerService::getComposerService());
    531     if (s == NULL) return NO_INIT;
    532     mHeap = 0;
    533     return s->captureScreen(0, &mHeap,
    534             &mWidth, &mHeight, &mFormat, 0, 0,
    535             0, -1UL);
    536 }
    537 
    538 status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) {
    539     sp<ISurfaceComposer> s(ComposerService::getComposerService());
    540     if (s == NULL) return NO_INIT;
    541     mHeap = 0;
    542     return s->captureScreen(0, &mHeap,
    543             &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
    544             0, -1UL);
    545 }
    546 
    547 status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight,
    548         uint32_t minLayerZ, uint32_t maxLayerZ) {
    549     sp<ISurfaceComposer> s(ComposerService::getComposerService());
    550     if (s == NULL) return NO_INIT;
    551     mHeap = 0;
    552     return s->captureScreen(0, &mHeap,
    553             &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
    554             minLayerZ, maxLayerZ);
    555 }
    556 
    557 void ScreenshotClient::release() {
    558     mHeap = 0;
    559 }
    560 
    561 void const* ScreenshotClient::getPixels() const {
    562     return mHeap->getBase();
    563 }
    564 
    565 uint32_t ScreenshotClient::getWidth() const {
    566     return mWidth;
    567 }
    568 
    569 uint32_t ScreenshotClient::getHeight() const {
    570     return mHeight;
    571 }
    572 
    573 PixelFormat ScreenshotClient::getFormat() const {
    574     return mFormat;
    575 }
    576 
    577 uint32_t ScreenshotClient::getStride() const {
    578     return mWidth;
    579 }
    580 
    581 size_t ScreenshotClient::getSize() const {
    582     return mHeap->getSize();
    583 }
    584 
    585 // ----------------------------------------------------------------------------
    586 }; // namespace android
    587