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

Commit 4fec873a authored by Mathias Agopian's avatar Mathias Agopian
Browse files

one more step towards multiple display support

- remove dependency on cached state in validateVisibility
- get rid of mVertices and mTransformedBounds
- get rid of validateVisibility
- get rid of unlockPageFlip
- handleTransaction now returns a dirty region
- computevisibileregion now uses window-manager space
parent e7db724b
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -72,11 +72,11 @@ public:

    //! returns number of items in the vector
    inline  size_t          size() const                { return VectorImpl::size(); }
    //! returns wether or not the vector is empty
    //! returns whether or not the vector is empty
    inline  bool            isEmpty() const             { return VectorImpl::isEmpty(); }
    //! returns how many items can be stored without reallocating the backing store
    inline  size_t          capacity() const            { return VectorImpl::capacity(); }
    //! setst the capacity. capacity can never be reduced less than size()
    //! sets the capacity. capacity can never be reduced less than size()
    inline  ssize_t         setCapacity(size_t size)    { return VectorImpl::setCapacity(size); }

    /*! 
@@ -102,12 +102,12 @@ public:
            const TYPE&     mirrorItemAt(ssize_t index) const;

    /*!
     * modifing the array
     * modifying the array
     */

    //! copy-on write support, grants write access to an item
            TYPE&           editItemAt(size_t index);
    //! grants right acces to the top of the stack (last element)
    //! grants right access to the top of the stack (last element)
            TYPE&           editTop();

            /*! 
+31 −47
Original line number Diff line number Diff line
@@ -145,14 +145,6 @@ void Layer::setName(const String8& name) {
    mSurfaceTexture->setName(name);
}

void Layer::validateVisibility(const Transform& globalTransform, const DisplayHardware& hw) {
    LayerBase::validateVisibility(globalTransform, hw);

    // This optimization allows the SurfaceTexture to bake in
    // the rotation so hardware overlays can be used
    mSurfaceTexture->setTransformHint(getTransformHint());
}

sp<ISurface> Layer::createSurface()
{
    class BSurface : public BnSurface, public LayerCleaner {
@@ -225,7 +217,8 @@ Rect Layer::computeBufferCrop() const {
    } else  if (mActiveBuffer != NULL){
        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
    } else {
        crop = Rect(mTransformedBounds.width(), mTransformedBounds.height());
        crop.makeInvalid();
        return crop;
    }

    // ... then reduce that in the same proportions as the window crop reduces
@@ -258,9 +251,11 @@ Rect Layer::computeBufferCrop() const {
    return crop;
}

void Layer::setGeometry(HWComposer::HWCLayerInterface& layer)
void Layer::setGeometry(
        const DisplayHardware& hw,
        HWComposer::HWCLayerInterface& layer)
{
    LayerBaseClient::setGeometry(layer);
    LayerBaseClient::setGeometry(hw, layer);

    // enable this layer
    layer.setSkip(false);
@@ -276,12 +271,11 @@ void Layer::setGeometry(HWComposer::HWCLayerInterface& layer)
     * 1) buffer orientation/flip/mirror
     * 2) state transformation (window manager)
     * 3) layer orientation (screen orientation)
     * mTransform is already the composition of (2) and (3)
     * (NOTE: the matrices are multiplied in reverse order)
     */

    const Transform bufferOrientation(mCurrentTransform);
    const Transform tr(mTransform * bufferOrientation);
    const Transform tr(hw.getTransform() * s.transform * bufferOrientation);

    // this gives us only the "orientation" component of the transform
    const uint32_t finalTransform = tr.getOrientation();
@@ -339,7 +333,7 @@ void Layer::onDraw(const DisplayHardware& hw, const Region& clip) const
            const sp<LayerBase>& layer(drawingLayers[i]);
            if (layer.get() == static_cast<LayerBase const*>(this))
                break;
            under.orSelf(layer->visibleRegionScreen);
            under.orSelf( hw.getTransform().transform(layer->visibleRegion) );
        }
        // if not everything below us is covered, we plug the holes!
        Region holes(clip.subtract(under));
@@ -527,10 +521,11 @@ bool Layer::onPreComposition() {
    return mQueuedFrames > 0;
}

void Layer::lockPageFlip(bool& recomputeVisibleRegions)
Region Layer::latchBuffer(bool& recomputeVisibleRegions)
{
    ATRACE_CALL();

    Region outDirtyRegion;
    if (mQueuedFrames > 0) {

        // if we've already called updateTexImage() without going through
@@ -539,8 +534,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
        // compositionComplete() call.
        // we'll trigger an update in onPreComposition().
        if (mRefreshPending) {
            mPostedDirtyRegion.clear();
            return;
            return outDirtyRegion;
        }

        // Capture the old state of the layer for comparisons later
@@ -637,17 +631,21 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)

        Reject r(mDrawingState, currentState(), recomputeVisibleRegions);

        // XXX: not sure if setTransformHint belongs here
        // it should only be needed when the main screen orientation changes
        mSurfaceTexture->setTransformHint(getTransformHint());

        if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
            // something happened!
            recomputeVisibleRegions = true;
            return;
            return outDirtyRegion;
        }

        // update the active buffer
        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
        if (mActiveBuffer == NULL) {
            // this can only happen if the very first buffer was rejected.
            return;
            return outDirtyRegion;
        }

        mRefreshPending = true;
@@ -686,38 +684,17 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
            recomputeVisibleRegions = true;
        }

        // FIXME: mPostedDirtyRegion = dirty & bounds
        const Layer::State& front(drawingState());
        mPostedDirtyRegion.set(front.active.w, front.active.h);

        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    }
}

void Layer::unlockPageFlip(
        const Transform& planeTransform, Region& outDirtyRegion)
{
    ATRACE_CALL();

    Region postedRegion(mPostedDirtyRegion);
    if (!postedRegion.isEmpty()) {
        mPostedDirtyRegion.clear();
        if (!visibleRegionScreen.isEmpty()) {
            // The dirty region is given in the layer's coordinate space
            // transform the dirty region by the surface's transformation
            // and the global transformation.
            const Layer::State& s(drawingState());
            const Transform tr(planeTransform * s.transform);
            postedRegion = tr.transform(postedRegion);
        // FIXME: postedRegion should be dirty & bounds
        const Layer::State& front(drawingState());
        Region dirtyRegion(Rect(front.active.w, front.active.h));

            // At this point, the dirty region is in screen space.
            // Make sure it's constrained by the visible region (which
            // is in screen space as well).
            postedRegion.andSelf(visibleRegionScreen);
            outDirtyRegion.orSelf(postedRegion);
        }
        // transform the dirty region to window-manager space
        outDirtyRegion = (front.transform.transform(dirtyRegion));
    }
    return outDirtyRegion;
}

void Layer::dump(String8& result, char* buffer, size_t SIZE) const
@@ -786,7 +763,14 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const
uint32_t Layer::getTransformHint() const {
    uint32_t orientation = 0;
    if (!mFlinger->mDebugDisableTransformHint) {
        orientation = getPlaneOrientation();
        // The transform hint is used to improve performance on the main
        // display -- we can only have a single transform hint, it cannot
        // apply to all displays.
        // This is why we use the default display here. This is not an
        // oversight.
        const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
        const Transform& planeTransform(hw.getTransform());
        orientation = planeTransform.getOrientation();
        if (orientation & Transform::ROT_INVALID) {
            orientation = 0;
        }
+4 −5
Original line number Diff line number Diff line
@@ -64,20 +64,20 @@ public:
    bool isFixedSize() const;

    // LayerBase interface
    virtual void setGeometry(HWComposer::HWCLayerInterface& layer);
    virtual void setGeometry(const DisplayHardware& hw,
            HWComposer::HWCLayerInterface& layer);
    virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
    virtual void setAcquireFence(HWComposer::HWCLayerInterface& layer);

    virtual void onDraw(const DisplayHardware& hw, const Region& clip) const;
    virtual uint32_t doTransaction(uint32_t transactionFlags);
    virtual void lockPageFlip(bool& recomputeVisibleRegions);
    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
    virtual Region latchBuffer(bool& recomputeVisibleRegions);
    virtual bool isOpaque() const;
    virtual bool isSecure() const           { return mSecure; }
    virtual bool isProtected() const;
    virtual void onRemoved();
    virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
    virtual void setName(const String8& name);
    virtual void validateVisibility(const Transform& globalTransform, const DisplayHardware& hw);

    // LayerBaseClient interface
    virtual wp<IBinder> getSurfaceTextureBinder() const;
@@ -142,7 +142,6 @@ private:
    // page-flip thread (currently main thread)
    bool mSecure;         // no screenshots
    bool mProtectedByApp; // application requires protected path to external sink
    Region mPostedDirtyRegion;
};

// ---------------------------------------------------------------------------
+50 −57
Original line number Diff line number Diff line
@@ -45,8 +45,6 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
      sequence(uint32_t(android_atomic_inc(&sSequence))),
      mFlinger(flinger), mFiltering(false),
      mNeedsFiltering(false),
      mOrientation(0),
      mPlaneOrientation(0),
      mTransactionFlags(0),
      mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)
{
@@ -170,19 +168,14 @@ bool LayerBase::setCrop(const Rect& crop) {
    return true;
}

Rect LayerBase::visibleBounds() const
{
    return mTransformedBounds;
}      

void LayerBase::setVisibleRegion(const Region& visibleRegion) {
    // always called from main thread
    visibleRegionScreen = visibleRegion;
    this->visibleRegion = visibleRegion;
}

void LayerBase::setCoveredRegion(const Region& coveredRegion) {
    // always called from main thread
    coveredRegionScreen = coveredRegion;
    this->coveredRegion = coveredRegion;
}

uint32_t LayerBase::doTransaction(uint32_t flags)
@@ -219,57 +212,45 @@ uint32_t LayerBase::doTransaction(uint32_t flags)
    return flags;
}

void LayerBase::validateVisibility(const Transform& planeTransform, const DisplayHardware& hw)
void LayerBase::computeGeometry(const DisplayHardware& hw, LayerMesh* mesh) const
{
    const Layer::State& s(drawingState());
    const Transform tr(planeTransform * s.transform);
    const bool transformed = tr.transformed();
    const Transform tr(hw.getTransform() * s.transform);
    const uint32_t hw_h = hw.getHeight();
    const Rect& crop(s.active.crop);

    Rect win(s.active.w, s.active.h);
    if (!crop.isEmpty()) {
        win.intersect(crop, &win);
    }

    mNumVertices = 4;
    tr.transform(mVertices[0], win.left,  win.top);
    tr.transform(mVertices[1], win.left,  win.bottom);
    tr.transform(mVertices[2], win.right, win.bottom);
    tr.transform(mVertices[3], win.right, win.top);
    for (size_t i=0 ; i<4 ; i++)
        mVertices[i][1] = hw_h - mVertices[i][1];

    if (CC_UNLIKELY(transformed)) {
        // NOTE: here we could also punt if we have too many rectangles
        // in the transparent region
        if (tr.preserveRects()) {
            // transform the transparent region
            transparentRegionScreen = tr.transform(s.transparentRegion);
        } else {
            // transformation too complex, can't do the transparent region
            // optimization.
            transparentRegionScreen.clear();
    if (mesh) {
        tr.transform(mesh->mVertices[0], win.left,  win.top);
        tr.transform(mesh->mVertices[1], win.left,  win.bottom);
        tr.transform(mesh->mVertices[2], win.right, win.bottom);
        tr.transform(mesh->mVertices[3], win.right, win.top);
        for (size_t i=0 ; i<4 ; i++) {
            mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
        }
    } else {
        transparentRegionScreen = s.transparentRegion;
    }

    // cache a few things...
    mOrientation = tr.getOrientation();
    mPlaneOrientation = planeTransform.getOrientation();
    mTransform = tr;
    mTransformedBounds = tr.transform(win);
}

void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) {
Rect LayerBase::computeBounds() const {
    const Layer::State& s(drawingState());
    const Rect& crop(s.active.crop);
    Rect win(s.active.w, s.active.h);
    if (!crop.isEmpty()) {
        win.intersect(crop, &win);
    }
    return s.transform.transform(win);
}

void LayerBase::unlockPageFlip(
        const Transform& planeTransform, Region& outDirtyRegion) {
Region LayerBase::latchBuffer(bool& recomputeVisibleRegions) {
    Region result;
    return result;
}

void LayerBase::setGeometry(HWComposer::HWCLayerInterface& layer)
void LayerBase::setGeometry(
        const DisplayHardware& hw,
        HWComposer::HWCLayerInterface& layer)
{
    layer.setDefaultState();

@@ -289,10 +270,14 @@ void LayerBase::setGeometry(HWComposer::HWCLayerInterface& layer)
                HWC_BLENDING_COVERAGE);
    }

    // scaling is already applied in mTransformedBounds
    layer.setFrame(mTransformedBounds);
    layer.setVisibleRegionScreen(visibleRegionScreen);
    layer.setCrop(mTransformedBounds.getBounds());
    const Transform& tr = hw.getTransform();
    Rect transformedBounds(computeBounds());
    transformedBounds = tr.transform(transformedBounds);

    // scaling is already applied in transformedBounds
    layer.setFrame(transformedBounds);
    layer.setCrop(transformedBounds.getBounds());
    layer.setVisibleRegionScreen(tr.transform(visibleRegion));
}

void LayerBase::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
@@ -335,8 +320,11 @@ void LayerBase::clearWithOpenGL(const DisplayHardware& hw, const Region& clip,
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

    glVertexPointer(2, GL_FLOAT, 0, mVertices);
    glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
    LayerMesh mesh;
    computeGeometry(hw, &mesh);

    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
}

void LayerBase::clearWithOpenGL(const DisplayHardware& hw, const Region& clip) const
@@ -371,6 +359,12 @@ void LayerBase::drawWithOpenGL(const DisplayHardware& hw, const Region& clip) co
        }
    }

    LayerMesh mesh;
    computeGeometry(hw, &mesh);

    // TODO: we probably want to generate the texture coords with the mesh
    // here we assume that we only have 4 vertices

    struct TexCoords {
        GLfloat u;
        GLfloat v;
@@ -399,9 +393,9 @@ void LayerBase::drawWithOpenGL(const DisplayHardware& hw, const Region& clip) co
    }

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, mVertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());

    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_BLEND);
@@ -417,8 +411,7 @@ void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
    result.append(buffer);

    s.transparentRegion.dump(result, "transparentRegion");
    transparentRegionScreen.dump(result, "transparentRegionScreen");
    visibleRegionScreen.dump(result, "visibleRegionScreen");
    visibleRegion.dump(result, "visibleRegion");

    snprintf(buffer, SIZE,
            "      "
+26 −34
Original line number Diff line number Diff line
@@ -57,9 +57,9 @@ public:

    DisplayID           dpy;
    mutable bool        contentDirty;
            Region      visibleRegionScreen;
            Region      transparentRegionScreen;
            Region      coveredRegionScreen;
            // regions below are in window-manager space
            Region      visibleRegion;
            Region      coveredRegion;
            int32_t     sequence;
            
            struct Geometry {
@@ -86,6 +86,20 @@ public:
                Region          transparentRegion;
            };

            class LayerMesh {
                friend class LayerBase;
                GLfloat mVertices[4][2];
                size_t mNumVertices;
            public:
                LayerMesh() : mNumVertices(4) { }
                GLfloat const* getVertices() const {
                    return &mVertices[0][0];
                }
                size_t getVertexCount() const {
                    return mNumVertices;
                }
            };

    virtual void setName(const String8& name);
            String8 getName() const;

@@ -106,14 +120,17 @@ public:
            uint32_t getTransactionFlags(uint32_t flags);
            uint32_t setTransactionFlags(uint32_t flags);

            Rect visibleBounds() const;
            void computeGeometry(const DisplayHardware& hw, LayerMesh* mesh) const;
            Rect computeBounds() const;


    virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }
    virtual sp<Layer> getLayer() const { return 0; }

    virtual const char* getTypeId() const { return "LayerBase"; }

    virtual void setGeometry(HWComposer::HWCLayerInterface& layer);
    virtual void setGeometry(const DisplayHardware& hw,
            HWComposer::HWCLayerInterface& layer);
    virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
    virtual void setAcquireFence(HWComposer::HWCLayerInterface& layer);

@@ -156,25 +173,12 @@ public:
    virtual void setCoveredRegion(const Region& coveredRegion);

    /**
     * validateVisibility - cache a bunch of things
     */
    virtual void validateVisibility(const Transform& globalTransform, const DisplayHardware& hw);

    /**
     * lockPageFlip - called each time the screen is redrawn and returns whether
     * latchBuffer - called each time the screen is redrawn and returns whether
     * the visible regions need to be recomputed (this is a fairly heavy
     * operation, so this should be set only if needed). Typically this is used
     * to figure out if the content or size of a surface has changed.
     */
    virtual void lockPageFlip(bool& recomputeVisibleRegions);
    
    /**
     * unlockPageFlip - called each time the screen is redrawn. updates the
     * final dirty region wrt the planeTransform.
     * At this point, all visible regions, surface position and size, etc... are
     * correct.
     */
    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
    virtual Region latchBuffer(bool& recomputeVisibleRegions);

    /**
     * isOpaque - true if this surface is opaque
@@ -233,9 +237,6 @@ public:
    inline  const State&    currentState() const    { return mCurrentState; }
    inline  State&          currentState()          { return mCurrentState; }

    int32_t  getOrientation() const { return mOrientation; }
    int32_t  getPlaneOrientation() const { return mPlaneOrientation; }

    void clearWithOpenGL(const DisplayHardware& hw, const Region& clip) const;

protected:
@@ -253,19 +254,10 @@ private:
                // Whether filtering is forced on or not
                bool            mFiltering;

                // cached during validateVisibility()
                // Whether filtering is needed b/c of the drawingstate
                bool            mNeedsFiltering;

protected:
                // cached during validateVisibility()
                int32_t         mOrientation;
                int32_t         mPlaneOrientation;
                Transform       mTransform;
                GLfloat         mVertices[4][2];
                size_t          mNumVertices;
                Rect            mTransformedBounds;
            
                // these are protected by an external lock
                State           mCurrentState;
                State           mDrawingState;
Loading