diff options
Diffstat (limited to 'libs/surfaceflinger_client/SurfaceComposerClient.cpp')
| -rw-r--r-- | libs/surfaceflinger_client/SurfaceComposerClient.cpp | 403 | 
1 files changed, 155 insertions, 248 deletions
| diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp index 3117495d3f41..4096ac6854c2 100644 --- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp +++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp @@ -17,98 +17,137 @@  #define LOG_TAG "SurfaceComposerClient"  #include <stdint.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h>  #include <sys/types.h> -#include <sys/stat.h> -#include <cutils/memory.h> - -#include <utils/Atomic.h>  #include <utils/Errors.h>  #include <utils/threads.h> -#include <utils/KeyedVector.h> +#include <utils/SortedVector.h>  #include <utils/Log.h> +#include <utils/Singleton.h>  #include <binder/IServiceManager.h>  #include <binder/IMemory.h>  #include <ui/DisplayInfo.h> -#include <ui/Rect.h>  #include <surfaceflinger/ISurfaceComposer.h> -#include <surfaceflinger/ISurfaceFlingerClient.h> +#include <surfaceflinger/ISurfaceComposerClient.h>  #include <surfaceflinger/ISurface.h>  #include <surfaceflinger/SurfaceComposerClient.h>  #include <private/surfaceflinger/LayerState.h>  #include <private/surfaceflinger/SharedBufferStack.h> -#define VERBOSE(...)	((void)0) -//#define VERBOSE			LOGD - -#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  )) -#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))  namespace android { +// --------------------------------------------------------------------------- + +ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService); + +ComposerService::ComposerService() +: Singleton<ComposerService>() { +    const String16 name("SurfaceFlinger"); +    while (getService(name, &mComposerService) != NO_ERROR) { +        usleep(250000); +    } +    mServerCblkMemory = mComposerService->getCblk(); +    mServerCblk = static_cast<surface_flinger_cblk_t volatile *>( +            mServerCblkMemory->getBase()); +} + +sp<ISurfaceComposer> ComposerService::getComposerService() { +    return ComposerService::getInstance().mComposerService; +} + +surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() { +    return ComposerService::getInstance().mServerCblk; +} + +static inline sp<ISurfaceComposer> getComposerService() { +    return ComposerService::getComposerService(); +} + +static inline surface_flinger_cblk_t const volatile * get_cblk() { +    return ComposerService::getControlBlock(); +}  // --------------------------------------------------------------------------- -// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here. -static Mutex                                                gLock; -static sp<ISurfaceComposer>                                 gSurfaceManager; -static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections; -static SortedVector<sp<SurfaceComposerClient> >             gOpenTransactions; -static sp<IMemoryHeap>                                      gServerCblkMemory; -static volatile surface_flinger_cblk_t*                     gServerCblk; - -static sp<ISurfaceComposer> getComposerService() -{ -    sp<ISurfaceComposer> sc; -    Mutex::Autolock _l(gLock); -    if (gSurfaceManager != 0) { -        sc = gSurfaceManager; -    } else { -        // release the lock while we're waiting... -        gLock.unlock(); - -        sp<IBinder> binder; -        sp<IServiceManager> sm = defaultServiceManager(); -        do { -            binder = sm->getService(String16("SurfaceFlinger")); -            if (binder == 0) { -                LOGW("SurfaceFlinger not published, waiting..."); -                usleep(500000); // 0.5 s +class Composer : public Singleton<Composer> +{ +    Mutex mLock; +    SortedVector< wp<SurfaceComposerClient> > mActiveConnections; +    SortedVector<sp<SurfaceComposerClient> > mOpenTransactions; + +    Composer() : Singleton<Composer>() { +    } + +    void addClientImpl(const sp<SurfaceComposerClient>& client) { +        Mutex::Autolock _l(mLock); +        mActiveConnections.add(client); +    } + +    void removeClientImpl(const sp<SurfaceComposerClient>& client) { +        Mutex::Autolock _l(mLock); +        mActiveConnections.remove(client); +    } + +    void openGlobalTransactionImpl() +    { +        Mutex::Autolock _l(mLock); +        if (mOpenTransactions.size()) { +            LOGE("openGlobalTransaction() called more than once. skipping."); +            return; +        } +        const size_t N = mActiveConnections.size(); +        for (size_t i=0; i<N; i++) { +            sp<SurfaceComposerClient> client(mActiveConnections[i].promote()); +            if (client != 0 && mOpenTransactions.indexOf(client) < 0) { +                if (client->openTransaction() == NO_ERROR) { +                    mOpenTransactions.add(client); +                } else { +                    LOGE("openTransaction on client %p failed", client.get()); +                    // let it go, it'll fail later when the user +                    // tries to do something with the transaction +                }              } -        } while(binder == 0); - -        // grab the lock again for updating gSurfaceManager -        gLock.lock(); -        if (gSurfaceManager == 0) { -            sc = interface_cast<ISurfaceComposer>(binder); -            gSurfaceManager = sc; -        } else { -            sc = gSurfaceManager;          }      } -    return sc; -} -static volatile surface_flinger_cblk_t const * get_cblk() -{ -    if (gServerCblk == 0) { +    void closeGlobalTransactionImpl() +    { +        mLock.lock(); +            SortedVector< sp<SurfaceComposerClient> > clients(mOpenTransactions); +            mOpenTransactions.clear(); +        mLock.unlock(); +          sp<ISurfaceComposer> sm(getComposerService()); -        Mutex::Autolock _l(gLock); -        if (gServerCblk == 0) { -            gServerCblkMemory = sm->getCblk(); -            LOGE_IF(gServerCblkMemory==0, "Can't get server control block"); -            gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase(); -            LOGE_IF(gServerCblk==0, "Can't get server control block address"); -        } +        sm->openGlobalTransaction(); +            const size_t N = clients.size(); +            for (size_t i=0; i<N; i++) { +                clients[i]->closeTransaction(); +            } +        sm->closeGlobalTransaction();      } -    return gServerCblk; -} + +    friend class Singleton<Composer>; + +public: +    static void addClient(const sp<SurfaceComposerClient>& client) { +        Composer::getInstance().addClientImpl(client); +    } +    static void removeClient(const sp<SurfaceComposerClient>& client) { +        Composer::getInstance().removeClientImpl(client); +    } +    static void openGlobalTransaction() { +        Composer::getInstance().openGlobalTransactionImpl(); +    } +    static void closeGlobalTransaction() { +        Composer::getInstance().closeGlobalTransactionImpl(); +    } +}; + +ANDROID_SINGLETON_STATIC_INSTANCE(Composer);  // --------------------------------------------------------------------------- @@ -120,61 +159,27 @@ static inline int compare_type( const layer_state_t& lhs,  }  SurfaceComposerClient::SurfaceComposerClient() +    : mTransactionOpen(0), mPrebuiltLayerState(0), mStatus(NO_INIT)  { -    sp<ISurfaceComposer> sm(getComposerService()); -    if (sm == 0) { -        _init(0, 0); -        return; -    } - -    _init(sm, sm->createConnection()); - -    if (mClient != 0) { -        Mutex::Autolock _l(gLock); -        VERBOSE("Adding client %p to map", this); -        gActiveConnections.add(mClient->asBinder(), this); -    }  } -SurfaceComposerClient::SurfaceComposerClient( -        const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn) -{ -    _init(sm, interface_cast<ISurfaceFlingerClient>(conn)); -} - - -status_t SurfaceComposerClient::linkToComposerDeath( -        const sp<IBinder::DeathRecipient>& recipient, -        void* cookie, uint32_t flags) +void SurfaceComposerClient::onFirstRef()  {      sp<ISurfaceComposer> sm(getComposerService()); -    return sm->asBinder()->linkToDeath(recipient, cookie, flags);     -} - -void SurfaceComposerClient::_init( -        const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn) -{ -    VERBOSE("Creating client %p, conn %p", this, conn.get()); - -    mPrebuiltLayerState = 0; -    mTransactionOpen = 0; -    mStatus = NO_ERROR; -    mControl = 0; - -    mClient = conn; -    if (mClient == 0) { -        mStatus = NO_INIT; -        return; +    if (sm != 0) { +        sp<ISurfaceComposerClient> conn = sm->createConnection(); +        if (conn != 0) { +            mClient = conn; +            Composer::addClient(this); +            mPrebuiltLayerState = new layer_state_t; +            mStatus = NO_ERROR; +        }      } - -    mControlMemory = mClient->getControlBlock(); -    mSignalServer = sm; -    mControl = static_cast<SharedClient *>(mControlMemory->getBase());  }  SurfaceComposerClient::~SurfaceComposerClient()  { -    VERBOSE("Destroying client %p, conn %p", this, mClient.get()); +    delete mPrebuiltLayerState;      dispose();  } @@ -188,69 +193,31 @@ sp<IBinder> SurfaceComposerClient::connection() const      return (mClient != 0) ? mClient->asBinder() : 0;  } -sp<SurfaceComposerClient> -SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn) +status_t SurfaceComposerClient::linkToComposerDeath( +        const sp<IBinder::DeathRecipient>& recipient, +        void* cookie, uint32_t flags)  { -    sp<SurfaceComposerClient> client; - -    { // scope for lock -        Mutex::Autolock _l(gLock); -        client = gActiveConnections.valueFor(conn); -    } - -    if (client == 0) { -        // Need to make a new client. -        sp<ISurfaceComposer> sm(getComposerService()); -        client = new SurfaceComposerClient(sm, conn); -        if (client != 0 && client->initCheck() == NO_ERROR) { -            Mutex::Autolock _l(gLock); -            gActiveConnections.add(conn, client); -            //LOGD("we have %d connections", gActiveConnections.size()); -        } else { -            client.clear(); -        } -    } - -    return client; +    sp<ISurfaceComposer> sm(getComposerService()); +    return sm->asBinder()->linkToDeath(recipient, cookie, flags);  }  void SurfaceComposerClient::dispose()  {      // this can be called more than once. - -    sp<IMemoryHeap>             controlMemory; -    sp<ISurfaceFlingerClient>   client; - -    { -        Mutex::Autolock _lg(gLock); -        Mutex::Autolock _lm(mLock); - -        mSignalServer = 0; - -        if (mClient != 0) { -            client = mClient; -            mClient.clear(); - -            ssize_t i = gActiveConnections.indexOfKey(client->asBinder()); -            if (i >= 0 && gActiveConnections.valueAt(i) == this) { -                VERBOSE("Removing client %p from map at %d", this, int(i)); -                gActiveConnections.removeItemsAt(i); -            } -        } - -        delete mPrebuiltLayerState; -        mPrebuiltLayerState = 0; -        controlMemory = mControlMemory; -        mControlMemory.clear(); -        mControl = 0; -        mStatus = NO_INIT; +    sp<ISurfaceComposerClient> client; +    Mutex::Autolock _lm(mLock); +    if (mClient != 0) { +        Composer::removeClient(this); +        client = mClient; // hold ref while lock is held +        mClient.clear();      } +    mStatus = NO_INIT;  }  status_t SurfaceComposerClient::getDisplayInfo(          DisplayID dpy, DisplayInfo* info)  { -    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) +    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)          return BAD_VALUE;      volatile surface_flinger_cblk_t const * cblk = get_cblk(); @@ -268,7 +235,7 @@ status_t SurfaceComposerClient::getDisplayInfo(  ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)  { -    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) +    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)          return BAD_VALUE;      volatile surface_flinger_cblk_t const * cblk = get_cblk();      volatile display_cblk_t const * dcblk = cblk->displays + dpy; @@ -277,7 +244,7 @@ ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)  ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)  { -    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) +    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)          return BAD_VALUE;      volatile surface_flinger_cblk_t const * cblk = get_cblk();      volatile display_cblk_t const * dcblk = cblk->displays + dpy; @@ -286,7 +253,7 @@ ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)  ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)  { -    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) +    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)          return BAD_VALUE;      volatile surface_flinger_cblk_t const * cblk = get_cblk();      volatile display_cblk_t const * dcblk = cblk->displays + dpy; @@ -305,12 +272,6 @@ ssize_t SurfaceComposerClient::getNumberOfDisplays()      return n;  } - -void SurfaceComposerClient::signalServer() -{ -    mSignalServer->signal(); -} -  sp<SurfaceControl> SurfaceComposerClient::createSurface(          int pid,          DisplayID display, @@ -327,7 +288,6 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(      return SurfaceComposerClient::createSurface(pid, name, display,              w, h, format, flags); -  }  sp<SurfaceControl> SurfaceComposerClient::createSurface( @@ -341,13 +301,11 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(  {      sp<SurfaceControl> result;      if (mStatus == NO_ERROR) { -        ISurfaceFlingerClient::surface_data_t data; +        ISurfaceComposerClient::surface_data_t data;          sp<ISurface> surface = mClient->createSurface(&data, pid, name,                  display, w, h, format, flags);          if (surface != 0) { -            if (uint32_t(data.token) < NUM_LAYERS_MAX) { -                result = new SurfaceControl(this, surface, data, w, h, format, flags); -            } +            result = new SurfaceControl(this, surface, data, w, h, format, flags);          }      }      return result; @@ -373,56 +331,14 @@ status_t SurfaceComposerClient::destroySurface(SurfaceID sid)  void SurfaceComposerClient::openGlobalTransaction()  { -    Mutex::Autolock _l(gLock); - -    if (gOpenTransactions.size()) { -        LOGE("openGlobalTransaction() called more than once. skipping."); -        return; -    } - -    const size_t N = gActiveConnections.size(); -    VERBOSE("openGlobalTransaction (%ld clients)", N); -    for (size_t i=0; i<N; i++) { -        sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i)); -        if (gOpenTransactions.indexOf(client) < 0) { -            if (client->openTransaction() == NO_ERROR) { -                if (gOpenTransactions.add(client) < 0) { -                    // Ooops! -                    LOGE(   "Unable to add a SurfaceComposerClient " -                            "to the global transaction set (out of memory?)"); -                    client->closeTransaction(); -                    // let it go, it'll fail later when the user -                    // tries to do something with the transaction -                } -            } else { -                LOGE("openTransaction on client %p failed", client.get()); -                // let it go, it'll fail later when the user -                // tries to do something with the transaction -            } -        } -    } +    Composer::openGlobalTransaction();  }  void SurfaceComposerClient::closeGlobalTransaction()  { -    gLock.lock(); -        SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions); -        gOpenTransactions.clear(); -    gLock.unlock(); - -    const size_t N = clients.size(); -    VERBOSE("closeGlobalTransaction (%ld clients)", N); - -    sp<ISurfaceComposer> sm(getComposerService()); -    sm->openGlobalTransaction(); -    for (size_t i=0; i<N; i++) { -        clients[i]->closeTransaction(); -    } -    sm->closeGlobalTransaction(); - +    Composer::closeGlobalTransaction();  } -  status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)  {      sp<ISurfaceComposer> sm(getComposerService()); @@ -447,26 +363,16 @@ status_t SurfaceComposerClient::openTransaction()      if (mStatus != NO_ERROR)          return mStatus;      Mutex::Autolock _l(mLock); -    VERBOSE(   "openTransaction (client %p, mTransactionOpen=%d)", -            this, mTransactionOpen);      mTransactionOpen++; -    if (mPrebuiltLayerState == 0) { -        mPrebuiltLayerState = new layer_state_t; -    }      return NO_ERROR;  } -  status_t SurfaceComposerClient::closeTransaction()  {      if (mStatus != NO_ERROR)          return mStatus;      Mutex::Autolock _l(mLock); - -    VERBOSE(   "closeTransaction (client %p, mTransactionOpen=%d)", -            this, mTransactionOpen); -      if (mTransactionOpen <= 0) {          LOGE(   "closeTransaction (client %p, mTransactionOpen=%d) "                  "called more times than openTransaction()", @@ -488,7 +394,7 @@ status_t SurfaceComposerClient::closeTransaction()      return NO_ERROR;  } -layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index) +layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index)  {      // API usage error, do nothing.      if (mTransactionOpen<=0) { @@ -498,7 +404,7 @@ layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index)      }      // use mPrebuiltLayerState just to find out if we already have it -    layer_state_t& dummy = *mPrebuiltLayerState; +    layer_state_t& dummy(*mPrebuiltLayerState);      dummy.surface = index;      ssize_t i = mStates.indexOf(dummy);      if (i < 0) { @@ -508,49 +414,49 @@ layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index)      return mStates.editArray() + i;  } -layer_state_t* SurfaceComposerClient::_lockLayerState(SurfaceID id) +layer_state_t* SurfaceComposerClient::lockLayerState(SurfaceID id)  {      layer_state_t* s;      mLock.lock(); -    s = _get_state_l(id); +    s = get_state_l(id);      if (!s) mLock.unlock();      return s;  } -void SurfaceComposerClient::_unlockLayerState() +void SurfaceComposerClient::unlockLayerState()  {      mLock.unlock();  }  status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)  { -    layer_state_t* s = _lockLayerState(id); +    layer_state_t* s = lockLayerState(id);      if (!s) return BAD_INDEX;      s->what |= ISurfaceComposer::ePositionChanged;      s->x = x;      s->y = y; -    _unlockLayerState(); +    unlockLayerState();      return NO_ERROR;  }  status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)  { -    layer_state_t* s = _lockLayerState(id); +    layer_state_t* s = lockLayerState(id);      if (!s) return BAD_INDEX;      s->what |= ISurfaceComposer::eSizeChanged;      s->w = w;      s->h = h; -    _unlockLayerState(); +    unlockLayerState();      return NO_ERROR;  }  status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)  { -    layer_state_t* s = _lockLayerState(id); +    layer_state_t* s = lockLayerState(id);      if (!s) return BAD_INDEX;      s->what |= ISurfaceComposer::eLayerChanged;      s->z = z; -    _unlockLayerState(); +    unlockLayerState();      return NO_ERROR;  } @@ -579,34 +485,34 @@ status_t SurfaceComposerClient::unfreeze(SurfaceID id)  status_t SurfaceComposerClient::setFlags(SurfaceID id,          uint32_t flags, uint32_t mask)  { -    layer_state_t* s = _lockLayerState(id); +    layer_state_t* s = lockLayerState(id);      if (!s) return BAD_INDEX;      s->what |= ISurfaceComposer::eVisibilityChanged;      s->flags &= ~mask;      s->flags |= (flags & mask);      s->mask |= mask; -    _unlockLayerState(); +    unlockLayerState();      return NO_ERROR;  }  status_t SurfaceComposerClient::setTransparentRegionHint(          SurfaceID id, const Region& transparentRegion)  { -    layer_state_t* s = _lockLayerState(id); +    layer_state_t* s = lockLayerState(id);      if (!s) return BAD_INDEX;      s->what |= ISurfaceComposer::eTransparentRegionChanged;      s->transparentRegion = transparentRegion; -    _unlockLayerState(); +    unlockLayerState();      return NO_ERROR;  }  status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)  { -    layer_state_t* s = _lockLayerState(id); +    layer_state_t* s = lockLayerState(id);      if (!s) return BAD_INDEX;      s->what |= ISurfaceComposer::eAlphaChanged;      s->alpha = alpha; -    _unlockLayerState(); +    unlockLayerState();      return NO_ERROR;  } @@ -615,7 +521,7 @@ status_t SurfaceComposerClient::setMatrix(          float dsdx, float dtdx,          float dsdy, float dtdy )  { -    layer_state_t* s = _lockLayerState(id); +    layer_state_t* s = lockLayerState(id);      if (!s) return BAD_INDEX;      s->what |= ISurfaceComposer::eMatrixChanged;      layer_state_t::matrix22_t matrix; @@ -624,19 +530,20 @@ status_t SurfaceComposerClient::setMatrix(      matrix.dsdy = dsdy;      matrix.dtdy = dtdy;      s->matrix = matrix; -    _unlockLayerState(); +    unlockLayerState();      return NO_ERROR;  }  status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)  { -    layer_state_t* s = _lockLayerState(id); +    layer_state_t* s = lockLayerState(id);      if (!s) return BAD_INDEX;      s->what |= ISurfaceComposer::eFreezeTintChanged;      s->tint = tint; -    _unlockLayerState(); +    unlockLayerState();      return NO_ERROR;  } +// ----------------------------------------------------------------------------  }; // namespace android | 
