Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f588d1dc authored by Mathias Agopian's avatar Mathias Agopian Committed by Android Git Automerger
Browse files

am e7d3ee9d: Revert "merge various SF fixes from gingerbread to honeycomb-mr2" (DO NOT MERGE)

* commit 'e7d3ee9d81de13e992c7d063ca472d480956b0c6':
  Revert "merge various SF fixes from gingerbread to honeycomb-mr2" (DO NOT MERGE)
parents 0fcbbddf debc234c
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -145,6 +145,18 @@ sp<LayerBaseClient::Surface> Layer::createSurface() const
    return sur;
    return sur;
}
}


status_t Layer::ditch()
{
    // NOTE: Called from the main UI thread

    // the layer is not on screen anymore. free as much resources as possible
    mFreezeLock.clear();

    Mutex::Autolock _l(mLock);
    mWidth = mHeight = 0;
    return NO_ERROR;
}

status_t Layer::setBuffers( uint32_t w, uint32_t h,
status_t Layer::setBuffers( uint32_t w, uint32_t h,
                            PixelFormat format, uint32_t flags)
                            PixelFormat format, uint32_t flags)
{
{
+1 −0
Original line number Original line Diff line number Diff line
@@ -82,6 +82,7 @@ public:
    virtual bool isSecure() const           { return mSecure; }
    virtual bool isSecure() const           { return mSecure; }
    virtual bool isProtected() const;
    virtual bool isProtected() const;
    virtual sp<Surface> createSurface() const;
    virtual sp<Surface> createSurface() const;
    virtual status_t ditch();
    virtual void onRemoved();
    virtual void onRemoved();


    // only for debugging
    // only for debugging
+4 −1
Original line number Original line Diff line number Diff line
@@ -616,7 +616,10 @@ LayerBaseClient::Surface::~Surface()
     */
     */


    // destroy client resources
    // destroy client resources
    mFlinger->destroySurface(mOwner);
    sp<LayerBaseClient> layer = getOwner();
    if (layer != 0) {
        mFlinger->destroySurface(layer);
    }
}
}


sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
+5 −2
Original line number Original line Diff line number Diff line
@@ -202,6 +202,10 @@ public:
     */
     */
    virtual bool isProtected() const   { return false; }
    virtual bool isProtected() const   { return false; }


    /** Called from the main thread, when the surface is removed from the
     * draw list */
    virtual status_t ditch() { return NO_ERROR; }

    /** called with the state lock when the surface is removed from the
    /** called with the state lock when the surface is removed from the
     *  current list */
     *  current list */
    virtual void onRemoved() { };
    virtual void onRemoved() { };
@@ -267,8 +271,7 @@ protected:
    volatile    int32_t         mInvalidate;
    volatile    int32_t         mInvalidate;
                
                


public:
protected:
    // called from class SurfaceFlinger
    virtual ~LayerBase();
    virtual ~LayerBase();


private:
private:
+81 −51
Original line number Original line Diff line number Diff line
@@ -395,7 +395,7 @@ bool SurfaceFlinger::threadLoop()
    if (LIKELY(mTransactionCount == 0)) {
    if (LIKELY(mTransactionCount == 0)) {
        // if we're in a global transaction, don't do anything.
        // if we're in a global transaction, don't do anything.
        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
        uint32_t transactionFlags = peekTransactionFlags(mask);
        uint32_t transactionFlags = getTransactionFlags(mask);
        if (LIKELY(transactionFlags)) {
        if (LIKELY(transactionFlags)) {
            handleTransaction(transactionFlags);
            handleTransaction(transactionFlags);
        }
        }
@@ -480,26 +480,39 @@ void SurfaceFlinger::handleConsoleEvents()


void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{
{
    Vector< sp<LayerBase> > ditchedLayers;

    /*
     * Perform and commit the transaction
     */

    { // scope for the lock
        Mutex::Autolock _l(mStateLock);
        Mutex::Autolock _l(mStateLock);
        const nsecs_t now = systemTime();
        const nsecs_t now = systemTime();
        mDebugInTransaction = now;
        mDebugInTransaction = now;

        handleTransactionLocked(transactionFlags, ditchedLayers);
    // Here we're guaranteed that some transaction flags are set
    // so we can call handleTransactionLocked() unconditionally.
    // We call getTransactionFlags(), which will also clear the flags,
    // with mStateLock held to guarantee that mCurrentState won't change
    // until the transaction is committed.

    const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
    transactionFlags = getTransactionFlags(mask);
    handleTransactionLocked(transactionFlags);

        mLastTransactionTime = systemTime() - now;
        mLastTransactionTime = systemTime() - now;
        mDebugInTransaction = 0;
        mDebugInTransaction = 0;
        invalidateHwcGeometry();
        // here the transaction has been committed
        // here the transaction has been committed
    }
    }


void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
    /*
     * Clean-up all layers that went away
     * (do this without the lock held)
     */

    const size_t count = ditchedLayers.size();
    for (size_t i=0 ; i<count ; i++) {
        if (ditchedLayers[i] != 0) {
            //LOGD("ditching layer %p", ditchedLayers[i].get());
            ditchedLayers[i]->ditch();
        }
    }
}

void SurfaceFlinger::handleTransactionLocked(
        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
{
{
    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
    const size_t count = currentLayers.size();
    const size_t count = currentLayers.size();
@@ -571,6 +584,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                const sp<LayerBase>& layer(previousLayers[i]);
                const sp<LayerBase>& layer(previousLayers[i]);
                if (currentLayers.indexOf( layer ) < 0) {
                if (currentLayers.indexOf( layer ) < 0) {
                    // this layer is not visible anymore
                    // this layer is not visible anymore
                    ditchedLayers.add(layer);
                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
                }
                }
            }
            }
@@ -1082,15 +1096,15 @@ status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
        const sp<LayerBaseClient>& lbc)
        const sp<LayerBaseClient>& lbc)
{
{
    // attach this layer to the client
    size_t name = client->attachLayer(lbc);

    Mutex::Autolock _l(mStateLock);
    Mutex::Autolock _l(mStateLock);


    // attach this layer to the client
    ssize_t name = client->attachLayer(lbc);

    // add this layer to the current state list
    // add this layer to the current state list
    addLayer_l(lbc);
    addLayer_l(lbc);


    return ssize_t(name);
    return name;
}
}


status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
@@ -1141,11 +1155,6 @@ status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
    return NO_ERROR;
    return NO_ERROR;
}
}


uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
{
    return android_atomic_release_load(&mTransactionFlags);
}

uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
{
{
    return android_atomic_and(~flags, &mTransactionFlags) & flags;
    return android_atomic_and(~flags, &mTransactionFlags) & flags;
@@ -1353,26 +1362,51 @@ status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
    return err;
    return err;
}
}


status_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
{
{
    // called by ~ISurface() when all references are gone
    // called by ~ISurface() when all references are gone
    status_t err = NO_ERROR;

    sp<LayerBaseClient> l(layer.promote());
    class MessageDestroySurface : public MessageBase {
    if (l != NULL) {
        SurfaceFlinger* flinger;
        Mutex::Autolock _l(mStateLock);
        sp<LayerBaseClient> layer;
        err = removeLayer_l(l);
    public:
        MessageDestroySurface(
                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
            : flinger(flinger), layer(layer) { }
        virtual bool handler() {
            sp<LayerBaseClient> l(layer);
            layer.clear(); // clear it outside of the lock;
            Mutex::Autolock _l(flinger->mStateLock);
            /*
             * remove the layer from the current list -- chances are that it's
             * not in the list anyway, because it should have been removed
             * already upon request of the client (eg: window manager).
             * However, a buggy client could have not done that.
             * Since we know we don't have any more clients, we don't need
             * to use the purgatory.
             */
            status_t err = flinger->removeLayer_l(l);
            if (err == NAME_NOT_FOUND) {
            if (err == NAME_NOT_FOUND) {
                // The surface wasn't in the current list, which means it was
                // The surface wasn't in the current list, which means it was
                // removed already, which means it is in the purgatory,
                // removed already, which means it is in the purgatory,
                // and need to be removed from there.
                // and need to be removed from there.
            ssize_t idx = mLayerPurgatory.remove(l);
                // This needs to happen from the main thread since its dtor
                // must run from there (b/c of OpenGL ES). Additionally, we
                // can't really acquire our internal lock from
                // destroySurface() -- see postMessage() below.
                ssize_t idx = flinger->mLayerPurgatory.remove(l);
                LOGE_IF(idx < 0,
                LOGE_IF(idx < 0,
                        "layer=%p is not in the purgatory list", l.get());
                        "layer=%p is not in the purgatory list", l.get());
            }
            }

            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
                    "error removing layer=%p (%s)", l.get(), strerror(-err));
                    "error removing layer=%p (%s)", l.get(), strerror(-err));
            return true;
        }
        }
    return err;
    };

    postMessageAsync( new MessageDestroySurface(this, layer) );
    return NO_ERROR;
}
}


status_t SurfaceFlinger::setClientState(
status_t SurfaceFlinger::setClientState(
@@ -2347,17 +2381,15 @@ status_t Client::initCheck() const {
    return NO_ERROR;
    return NO_ERROR;
}
}


size_t Client::attachLayer(const sp<LayerBaseClient>& layer)
ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
{
{
    Mutex::Autolock _l(mLock);
    int32_t name = android_atomic_inc(&mNameGenerator);
    size_t name = mNameGenerator++;
    mLayers.add(name, layer);
    mLayers.add(name, layer);
    return name;
    return name;
}
}


void Client::detachLayer(const LayerBaseClient* layer)
void Client::detachLayer(const LayerBaseClient* layer)
{
{
    Mutex::Autolock _l(mLock);
    // we do a linear search here, because this doesn't happen often
    // we do a linear search here, because this doesn't happen often
    const size_t count = mLayers.size();
    const size_t count = mLayers.size();
    for (size_t i=0 ; i<count ; i++) {
    for (size_t i=0 ; i<count ; i++) {
@@ -2367,11 +2399,9 @@ void Client::detachLayer(const LayerBaseClient* layer)
        }
        }
    }
    }
}
}
sp<LayerBaseClient> Client::getLayerUser(int32_t i) const
sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
{
    Mutex::Autolock _l(mLock);
    sp<LayerBaseClient> lbc;
    sp<LayerBaseClient> lbc;
    wp<LayerBaseClient> layer(mLayers.valueFor(i));
    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
    if (layer != 0) {
    if (layer != 0) {
        lbc = layer.promote();
        lbc = layer.promote();
        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
Loading