diff options
| author | 2011-06-28 19:09:31 -0700 | |
|---|---|---|
| committer | 2011-06-29 15:05:41 -0700 | |
| commit | 698c0873cf2e07bdc7fd1e72169aee2a19fa40d7 (patch) | |
| tree | cf1a8a26a6568ad5dd1fa30d238b9651e09d3800 /libs/gui/SurfaceComposerClient.cpp | |
| parent | 0748907d6a9a052fe54541cd7f6ec66b998fec3b (diff) | |
SF transactions are now O(1) wrt IPC instead of O(N).
Change-Id: I57669852cbf6aabae244ea86940a08a5a27ffc43
Diffstat (limited to 'libs/gui/SurfaceComposerClient.cpp')
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 593 | 
1 files changed, 279 insertions, 314 deletions
| diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 1678711aaf..8cead808a1 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -74,75 +74,52 @@ static inline surface_flinger_cblk_t const volatile * get_cblk() {  // --------------------------------------------------------------------------- +// NOTE: this is NOT a member function (it's a friend defined with its +// declaration). +static inline +int compare_type( const ComposerState& lhs, const ComposerState& rhs) { +    if (lhs.client < rhs.client)  return -1; +    if (lhs.client > rhs.client)  return 1; +    if (lhs.state.surface < rhs.state.surface)  return -1; +    if (lhs.state.surface > rhs.state.surface)  return 1; +    return 0; +} +  class Composer : public Singleton<Composer>  { -    Mutex mLock; -    SortedVector< wp<SurfaceComposerClient> > mActiveConnections; -    SortedVector<sp<SurfaceComposerClient> > mOpenTransactions; +    friend class Singleton<Composer>; -    Composer() : Singleton<Composer>() { -    } +    mutable Mutex               mLock; +    SortedVector<ComposerState> mStates; -    void addClientImpl(const sp<SurfaceComposerClient>& client) { -        Mutex::Autolock _l(mLock); -        mActiveConnections.add(client); -    } +    Composer() : Singleton<Composer>() { } -    void removeClientImpl(const sp<SurfaceComposerClient>& client) { -        Mutex::Autolock _l(mLock); -        mActiveConnections.remove(client); -    } +    void closeGlobalTransactionImpl(); -    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 -                } -            } -        } -    } +    layer_state_t* getLayerStateLocked( +            const sp<SurfaceComposerClient>& client, SurfaceID id); -    void closeGlobalTransactionImpl() -    { -        mLock.lock(); -            SortedVector< sp<SurfaceComposerClient> > clients(mOpenTransactions); -            mOpenTransactions.clear(); -        mLock.unlock(); - -        sp<ISurfaceComposer> sm(getComposerService()); -        sm->openGlobalTransaction(); -            const size_t N = clients.size(); -            for (size_t i=0; i<N; i++) { -                clients[i]->closeTransaction(); -            } -        sm->closeGlobalTransaction(); -    } +public: -    friend class Singleton<Composer>; +    status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id, +            int32_t x, int32_t y); +    status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id, +            uint32_t w, uint32_t h); +    status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id, +            int32_t z); +    status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id, +            uint32_t flags, uint32_t mask); +    status_t setTransparentRegionHint( +            const sp<SurfaceComposerClient>& client, SurfaceID id, +            const Region& transparentRegion); +    status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id, +            float alpha); +    status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id, +            float dsdx, float dtdx, float dsdy, float dtdy); +    status_t setFreezeTint( +            const sp<SurfaceComposerClient>& client, SurfaceID id, +            uint32_t tint); -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();      } @@ -152,127 +129,185 @@ ANDROID_SINGLETON_STATIC_INSTANCE(Composer);  // --------------------------------------------------------------------------- -static inline int compare_type( const layer_state_t& lhs, -                                const layer_state_t& rhs) { -    if (lhs.surface < rhs.surface)  return -1; -    if (lhs.surface > rhs.surface)  return 1; -    return 0; +void Composer::closeGlobalTransactionImpl() { +    sp<ISurfaceComposer> sm(getComposerService()); + +    Vector<ComposerState> transaction; + +    { // scope for the lock +        Mutex::Autolock _l(mLock); +        transaction = mStates; +        mStates.clear(); +    } + +   sm->setTransactionState(transaction); +} + +layer_state_t* Composer::getLayerStateLocked( +        const sp<SurfaceComposerClient>& client, SurfaceID id) { + +    ComposerState s; +    s.client = client->mClient; +    s.state.surface = id; + +    ssize_t index = mStates.indexOf(s); +    if (index < 0) { +        // we don't have it, add an initialized layer_state to our list +        index = mStates.add(s); +    } + +    ComposerState* const out = mStates.editArray(); +    return &(out[index].state); +} + +status_t Composer::setPosition(const sp<SurfaceComposerClient>& client, +        SurfaceID id, int32_t x, int32_t y) { +    Mutex::Autolock _l(mLock); +    layer_state_t* s = getLayerStateLocked(client, id); +    if (!s) +        return BAD_INDEX; +    s->what |= ISurfaceComposer::ePositionChanged; +    s->x = x; +    s->y = y; +    return NO_ERROR; +} + +status_t Composer::setSize(const sp<SurfaceComposerClient>& client, +        SurfaceID id, uint32_t w, uint32_t h) { +    Mutex::Autolock _l(mLock); +    layer_state_t* s = getLayerStateLocked(client, id); +    if (!s) +        return BAD_INDEX; +    s->what |= ISurfaceComposer::eSizeChanged; +    s->w = w; +    s->h = h; +    return NO_ERROR; +} + +status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, +        SurfaceID id, int32_t z) { +    Mutex::Autolock _l(mLock); +    layer_state_t* s = getLayerStateLocked(client, id); +    if (!s) +        return BAD_INDEX; +    s->what |= ISurfaceComposer::eLayerChanged; +    s->z = z; +    return NO_ERROR; +} + +status_t Composer::setFlags(const sp<SurfaceComposerClient>& client, +        SurfaceID id, uint32_t flags, +        uint32_t mask) { +    Mutex::Autolock _l(mLock); +    layer_state_t* s = getLayerStateLocked(client, id); +    if (!s) +        return BAD_INDEX; +    s->what |= ISurfaceComposer::eVisibilityChanged; +    s->flags &= ~mask; +    s->flags |= (flags & mask); +    s->mask |= mask; +    return NO_ERROR; +} + +status_t Composer::setTransparentRegionHint( +        const sp<SurfaceComposerClient>& client, SurfaceID id, +        const Region& transparentRegion) { +    Mutex::Autolock _l(mLock); +    layer_state_t* s = getLayerStateLocked(client, id); +    if (!s) +        return BAD_INDEX; +    s->what |= ISurfaceComposer::eTransparentRegionChanged; +    s->transparentRegion = transparentRegion; +    return NO_ERROR; +} + +status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client, +        SurfaceID id, float alpha) { +    Mutex::Autolock _l(mLock); +    layer_state_t* s = getLayerStateLocked(client, id); +    if (!s) +        return BAD_INDEX; +    s->what |= ISurfaceComposer::eAlphaChanged; +    s->alpha = alpha; +    return NO_ERROR; +} + +status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client, +        SurfaceID id, float dsdx, float dtdx, +        float dsdy, float dtdy) { +    Mutex::Autolock _l(mLock); +    layer_state_t* s = getLayerStateLocked(client, id); +    if (!s) +        return BAD_INDEX; +    s->what |= ISurfaceComposer::eMatrixChanged; +    layer_state_t::matrix22_t matrix; +    matrix.dsdx = dsdx; +    matrix.dtdx = dtdx; +    matrix.dsdy = dsdy; +    matrix.dtdy = dtdy; +    s->matrix = matrix; +    return NO_ERROR;  } +status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client, +        SurfaceID id, uint32_t tint) { +    Mutex::Autolock _l(mLock); +    layer_state_t* s = getLayerStateLocked(client, id); +    if (!s) +        return BAD_INDEX; +    s->what |= ISurfaceComposer::eFreezeTintChanged; +    s->tint = tint; +    return NO_ERROR; +} + +// --------------------------------------------------------------------------- +  SurfaceComposerClient::SurfaceComposerClient() -    : mTransactionOpen(0), mPrebuiltLayerState(0), mStatus(NO_INIT) +    : mStatus(NO_INIT), mComposer(Composer::getInstance())  {  } -void SurfaceComposerClient::onFirstRef() -{ +void SurfaceComposerClient::onFirstRef() {      sp<ISurfaceComposer> sm(getComposerService());      if (sm != 0) {          sp<ISurfaceComposerClient> conn = sm->createConnection();          if (conn != 0) {              mClient = conn; -            Composer::addClient(this); -            mPrebuiltLayerState = new layer_state_t;              mStatus = NO_ERROR;          }      }  } -SurfaceComposerClient::~SurfaceComposerClient() -{ -    delete mPrebuiltLayerState; +SurfaceComposerClient::~SurfaceComposerClient() {      dispose();  } -status_t SurfaceComposerClient::initCheck() const -{ +status_t SurfaceComposerClient::initCheck() const {      return mStatus;  } -sp<IBinder> SurfaceComposerClient::connection() const -{ +sp<IBinder> SurfaceComposerClient::connection() const {      return (mClient != 0) ? mClient->asBinder() : 0;  }  status_t SurfaceComposerClient::linkToComposerDeath(          const sp<IBinder::DeathRecipient>& recipient, -        void* cookie, uint32_t flags) -{ +        void* cookie, uint32_t flags) {      sp<ISurfaceComposer> sm(getComposerService());      return sm->asBinder()->linkToDeath(recipient, cookie, flags);  } -void SurfaceComposerClient::dispose() -{ +void SurfaceComposerClient::dispose() {      // this can be called more than once.      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) -        return BAD_VALUE; - -    volatile surface_flinger_cblk_t const * cblk = get_cblk(); -    volatile display_cblk_t const * dcblk = cblk->displays + dpy; - -    info->w              = dcblk->w; -    info->h              = dcblk->h; -    info->orientation    = dcblk->orientation; -    info->xdpi           = dcblk->xdpi; -    info->ydpi           = dcblk->ydpi; -    info->fps            = dcblk->fps; -    info->density        = dcblk->density; -    return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo)); -} - -ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy) -{ -    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) -        return BAD_VALUE; -    volatile surface_flinger_cblk_t const * cblk = get_cblk(); -    volatile display_cblk_t const * dcblk = cblk->displays + dpy; -    return dcblk->w; -} - -ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy) -{ -    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) -        return BAD_VALUE; -    volatile surface_flinger_cblk_t const * cblk = get_cblk(); -    volatile display_cblk_t const * dcblk = cblk->displays + dpy; -    return dcblk->h; -} - -ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy) -{ -    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) -        return BAD_VALUE; -    volatile surface_flinger_cblk_t const * cblk = get_cblk(); -    volatile display_cblk_t const * dcblk = cblk->displays + dpy; -    return dcblk->orientation; -} - -ssize_t SurfaceComposerClient::getNumberOfDisplays() -{ -    volatile surface_flinger_cblk_t const * cblk = get_cblk(); -    uint32_t connected = cblk->connected; -    int n = 0; -    while (connected) { -        if (connected&1) n++; -        connected >>= 1; -    } -    return n; -} -  sp<SurfaceControl> SurfaceComposerClient::createSurface(          DisplayID display,          uint32_t w, @@ -310,237 +345,167 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(      return result;  } -status_t SurfaceComposerClient::destroySurface(SurfaceID sid) -{ +status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {      if (mStatus != NO_ERROR)          return mStatus; - -    // it's okay to destroy a surface while a transaction is open, -    // (transactions really are a client-side concept) -    // however, this indicates probably a misuse of the API or a bug -    // in the client code. -    LOGW_IF(mTransactionOpen, -         "Destroying surface while a transaction is open. " -         "Client %p: destroying surface %d, mTransactionOpen=%d", -         this, sid, mTransactionOpen); -      status_t err = mClient->destroySurface(sid);      return err;  } -void SurfaceComposerClient::openGlobalTransaction() -{ -    Composer::openGlobalTransaction(); +inline Composer& SurfaceComposerClient::getComposer() { +    return mComposer;  } -void SurfaceComposerClient::closeGlobalTransaction() -{ -    Composer::closeGlobalTransaction(); -} +// ---------------------------------------------------------------------------- -status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags) -{ -    sp<ISurfaceComposer> sm(getComposerService()); -    return sm->freezeDisplay(dpy, flags); +void SurfaceComposerClient::openGlobalTransaction() { +    // Currently a no-op  } -status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags) -{ -    sp<ISurfaceComposer> sm(getComposerService()); -    return sm->unfreezeDisplay(dpy, flags); +void SurfaceComposerClient::closeGlobalTransaction() { +    Composer::closeGlobalTransaction();  } -int SurfaceComposerClient::setOrientation(DisplayID dpy,  -        int orientation, uint32_t flags) -{ -    sp<ISurfaceComposer> sm(getComposerService()); -    return sm->setOrientation(dpy, orientation, flags); -} +// ---------------------------------------------------------------------------- -status_t SurfaceComposerClient::openTransaction() -{ -    if (mStatus != NO_ERROR) -        return mStatus; -    Mutex::Autolock _l(mLock); -    mTransactionOpen++; -    return NO_ERROR; +status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) { +    return getComposer().setFreezeTint(this, id, tint);  } -status_t SurfaceComposerClient::closeTransaction() -{ -    if (mStatus != NO_ERROR) -        return mStatus; - -    Mutex::Autolock _l(mLock); -    if (mTransactionOpen <= 0) { -        LOGE(   "closeTransaction (client %p, mTransactionOpen=%d) " -                "called more times than openTransaction()", -                this, mTransactionOpen); -        return INVALID_OPERATION; -    } +status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y) { +    return getComposer().setPosition(this, id, x, y); +} -    if (mTransactionOpen >= 2) { -        mTransactionOpen--; -        return NO_ERROR; -    } +status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) { +    return getComposer().setSize(this, id, w, h); +} -    mTransactionOpen = 0; -    const ssize_t count = mStates.size(); -    if (count) { -        mClient->setState(count, mStates.array()); -        mStates.clear(); -    } -    return NO_ERROR; +status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) { +    return getComposer().setLayer(this, id, z);  } -layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index) -{ -    // API usage error, do nothing. -    if (mTransactionOpen<=0) { -        LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d", -                this, int(index), mTransactionOpen); -        return 0; -    } +status_t SurfaceComposerClient::hide(SurfaceID id) { +    return getComposer().setFlags(this, id, +            ISurfaceComposer::eLayerHidden, +            ISurfaceComposer::eLayerHidden); +} -    // use mPrebuiltLayerState just to find out if we already have it -    layer_state_t& dummy(*mPrebuiltLayerState); -    dummy.surface = index; -    ssize_t i = mStates.indexOf(dummy); -    if (i < 0) { -        // we don't have it, add an initialized layer_state to our list -        i = mStates.add(dummy); -    } -    return mStates.editArray() + i; +status_t SurfaceComposerClient::show(SurfaceID id, int32_t) { +    return getComposer().setFlags(this, id, +            0, +            ISurfaceComposer::eLayerHidden);  } -layer_state_t* SurfaceComposerClient::lockLayerState(SurfaceID id) -{ -    layer_state_t* s; -    mLock.lock(); -    s = get_state_l(id); -    if (!s) mLock.unlock(); -    return s; +status_t SurfaceComposerClient::freeze(SurfaceID id) { +    return getComposer().setFlags(this, id, +            ISurfaceComposer::eLayerFrozen, +            ISurfaceComposer::eLayerFrozen);  } -void SurfaceComposerClient::unlockLayerState() -{ -    mLock.unlock(); +status_t SurfaceComposerClient::unfreeze(SurfaceID id) { +    return getComposer().setFlags(this, id, +            0, +            ISurfaceComposer::eLayerFrozen);  } -status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y) -{ -    layer_state_t* s = lockLayerState(id); -    if (!s) return BAD_INDEX; -    s->what |= ISurfaceComposer::ePositionChanged; -    s->x = x; -    s->y = y; -    unlockLayerState(); -    return NO_ERROR; +status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags, +        uint32_t mask) { +    return getComposer().setFlags(this, id, flags, mask);  } -status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) -{ -    layer_state_t* s = lockLayerState(id); -    if (!s) return BAD_INDEX; -    s->what |= ISurfaceComposer::eSizeChanged; -    s->w = w; -    s->h = h; -    unlockLayerState(); -    return NO_ERROR; +status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id, +        const Region& transparentRegion) { +    return getComposer().setTransparentRegionHint(this, id, transparentRegion);  } -status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) -{ -    layer_state_t* s = lockLayerState(id); -    if (!s) return BAD_INDEX; -    s->what |= ISurfaceComposer::eLayerChanged; -    s->z = z; -    unlockLayerState(); -    return NO_ERROR; +status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) { +    return getComposer().setAlpha(this, id, alpha);  } -status_t SurfaceComposerClient::hide(SurfaceID id) -{ -    return setFlags(id, ISurfaceComposer::eLayerHidden, -            ISurfaceComposer::eLayerHidden); +status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx, +        float dsdy, float dtdy) { +    return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);  } -status_t SurfaceComposerClient::show(SurfaceID id, int32_t) +// ---------------------------------------------------------------------------- + +status_t SurfaceComposerClient::getDisplayInfo( +        DisplayID dpy, DisplayInfo* info)  { -    return setFlags(id, 0, ISurfaceComposer::eLayerHidden); +    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) +        return BAD_VALUE; + +    volatile surface_flinger_cblk_t const * cblk = get_cblk(); +    volatile display_cblk_t const * dcblk = cblk->displays + dpy; + +    info->w              = dcblk->w; +    info->h              = dcblk->h; +    info->orientation    = dcblk->orientation; +    info->xdpi           = dcblk->xdpi; +    info->ydpi           = dcblk->ydpi; +    info->fps            = dcblk->fps; +    info->density        = dcblk->density; +    return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));  } -status_t SurfaceComposerClient::freeze(SurfaceID id) +ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)  { -    return setFlags(id, ISurfaceComposer::eLayerFrozen, -            ISurfaceComposer::eLayerFrozen); +    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) +        return BAD_VALUE; +    volatile surface_flinger_cblk_t const * cblk = get_cblk(); +    volatile display_cblk_t const * dcblk = cblk->displays + dpy; +    return dcblk->w;  } -status_t SurfaceComposerClient::unfreeze(SurfaceID id) +ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)  { -    return setFlags(id, 0, ISurfaceComposer::eLayerFrozen); +    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) +        return BAD_VALUE; +    volatile surface_flinger_cblk_t const * cblk = get_cblk(); +    volatile display_cblk_t const * dcblk = cblk->displays + dpy; +    return dcblk->h;  } -status_t SurfaceComposerClient::setFlags(SurfaceID id, -        uint32_t flags, uint32_t mask) +ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)  { -    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(); -    return NO_ERROR; +    if (uint32_t(dpy)>=NUM_DISPLAY_MAX) +        return BAD_VALUE; +    volatile surface_flinger_cblk_t const * cblk = get_cblk(); +    volatile display_cblk_t const * dcblk = cblk->displays + dpy; +    return dcblk->orientation;  } -status_t SurfaceComposerClient::setTransparentRegionHint( -        SurfaceID id, const Region& transparentRegion) +ssize_t SurfaceComposerClient::getNumberOfDisplays()  { -    layer_state_t* s = lockLayerState(id); -    if (!s) return BAD_INDEX; -    s->what |= ISurfaceComposer::eTransparentRegionChanged; -    s->transparentRegion = transparentRegion; -    unlockLayerState(); -    return NO_ERROR; +    volatile surface_flinger_cblk_t const * cblk = get_cblk(); +    uint32_t connected = cblk->connected; +    int n = 0; +    while (connected) { +        if (connected&1) n++; +        connected >>= 1; +    } +    return n;  } -status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) +// ---------------------------------------------------------------------------- + +status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)  { -    layer_state_t* s = lockLayerState(id); -    if (!s) return BAD_INDEX; -    s->what |= ISurfaceComposer::eAlphaChanged; -    s->alpha = alpha; -    unlockLayerState(); -    return NO_ERROR; +    sp<ISurfaceComposer> sm(getComposerService()); +    return sm->freezeDisplay(dpy, flags);  } -status_t SurfaceComposerClient::setMatrix( -        SurfaceID id, -        float dsdx, float dtdx, -        float dsdy, float dtdy ) +status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)  { -    layer_state_t* s = lockLayerState(id); -    if (!s) return BAD_INDEX; -    s->what |= ISurfaceComposer::eMatrixChanged; -    layer_state_t::matrix22_t matrix; -    matrix.dsdx = dsdx; -    matrix.dtdx = dtdx; -    matrix.dsdy = dsdy; -    matrix.dtdy = dtdy; -    s->matrix = matrix; -    unlockLayerState(); -    return NO_ERROR; +    sp<ISurfaceComposer> sm(getComposerService()); +    return sm->unfreezeDisplay(dpy, flags);  } -status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) +int SurfaceComposerClient::setOrientation(DisplayID dpy, +        int orientation, uint32_t flags)  { -    layer_state_t* s = lockLayerState(id); -    if (!s) return BAD_INDEX; -    s->what |= ISurfaceComposer::eFreezeTintChanged; -    s->tint = tint; -    unlockLayerState(); -    return NO_ERROR; +    sp<ISurfaceComposer> sm(getComposerService()); +    return sm->setOrientation(dpy, orientation, flags);  }  // ---------------------------------------------------------------------------- |