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

Commit 6b77231b authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "Fix an issue is SF that caused drawing artifacts when hwc changed mode"

parents 6c0d41a4 4bacc9dc
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -344,6 +344,14 @@ void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
    hwcl->handle = NULL;
    hwcl->handle = NULL;
}
}


void LayerBase::setOverlay(bool inOverlay) {
    mInOverlay = inOverlay;
}

bool LayerBase::isOverlay() const {
    return mInOverlay;
}

void LayerBase::setFiltering(bool filtering)
void LayerBase::setFiltering(bool filtering)
{
{
    mFiltering = filtering;
    mFiltering = filtering;
+8 −1
Original line number Original line Diff line number Diff line
@@ -109,8 +109,10 @@ public:
    virtual const char* getTypeId() const { return "LayerBase"; }
    virtual const char* getTypeId() const { return "LayerBase"; }


    virtual void setGeometry(hwc_layer_t* hwcl);
    virtual void setGeometry(hwc_layer_t* hwcl);

    virtual void setPerFrameData(hwc_layer_t* hwcl);
    virtual void setPerFrameData(hwc_layer_t* hwcl);
            void setOverlay(bool inOverlay);
            bool isOverlay() const;



    /**
    /**
     * draw - performs some global clipping optimizations
     * draw - performs some global clipping optimizations
@@ -242,6 +244,11 @@ private:
                // Whether filtering is needed b/c of the drawingstate
                // Whether filtering is needed b/c of the drawingstate
                bool            mNeedsFiltering;
                bool            mNeedsFiltering;


                // this layer is currently handled by the hwc. this is
                // updated at composition time, always frmo the composition
                // thread.
                bool            mInOverlay;

protected:
protected:
                // cached during validateVisibility()
                // cached during validateVisibility()
                int32_t         mOrientation;
                int32_t         mOrientation;
+68 −59
Original line number Original line Diff line number Diff line
@@ -817,20 +817,6 @@ void SurfaceFlinger::handleWorkList()
    mHwWorkListDirty = false;
    mHwWorkListDirty = false;
    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
    if (hwc.initCheck() == NO_ERROR) {
    if (hwc.initCheck() == NO_ERROR) {

        const DisplayHardware& hw(graphicPlane(0).displayHardware());
        uint32_t flags = hw.getFlags();
        if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
            (flags & DisplayHardware::BUFFER_PRESERVED))
        {
            // we need to redraw everything (the whole screen)
            // NOTE: we could be more subtle here and redraw only
            // the area which will end-up in an overlay. But since this
            // shouldn't happen often, we invalidate everything.
            mDirtyRegion.set(hw.bounds());
            mInvalidRegion = mDirtyRegion;
        }

        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
        const size_t count = currentLayers.size();
        const size_t count = currentLayers.size();
        hwc.createWorkList(count);
        hwc.createWorkList(count);
@@ -891,29 +877,26 @@ void SurfaceFlinger::handleRepaint()
    }
    }


    // compose all surfaces
    // compose all surfaces
    setupHardwareComposer(&mDirtyRegion);
    composeSurfaces(mDirtyRegion);
    composeSurfaces(mDirtyRegion);


    // clear the dirty regions
    // clear the dirty regions
    mDirtyRegion.clear();
    mDirtyRegion.clear();
}
}


void SurfaceFlinger::composeSurfaces(const Region& dirty)
void SurfaceFlinger::setupHardwareComposer(Region* dirtyInOut)
{
{
    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
        // should never happen unless the window manager has a bug
    HWComposer& hwc(hw.getHwComposer());
        // draw something...
    hwc_layer_t* const cur(hwc.getLayers());
        drawWormhole();
    if (!cur) {
        return;
    }
    }


    status_t err = NO_ERROR;
    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
    size_t count = layers.size();
    size_t count = layers.size();


    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    LOGE_IF(hwc.getNumLayers() != count,
    HWComposer& hwc(hw.getHwComposer());
    hwc_layer_t* const cur(hwc.getLayers());

    LOGE_IF(cur && hwc.getNumLayers() != count,
            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
            hwc.getNumLayers(), count);
            hwc.getNumLayers(), count);


@@ -927,28 +910,45 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
     *  and build the transparent region of the FB
     *  and build the transparent region of the FB
     */
     */
    Region transparent;
    Region transparent;
    if (cur) {
    for (size_t i=0 ; i<count ; i++) {
    for (size_t i=0 ; i<count ; i++) {
        const sp<LayerBase>& layer(layers[i]);
        const sp<LayerBase>& layer(layers[i]);
        layer->setPerFrameData(&cur[i]);
        layer->setPerFrameData(&cur[i]);
    }
    }
        err = hwc.prepare();
    status_t err = hwc.prepare();
    LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
    LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));


    if (err == NO_ERROR) {
    if (err == NO_ERROR) {
        Region transparentDirty(*dirtyInOut);
        for (size_t i=0 ; i<count ; i++) {
        for (size_t i=0 ; i<count ; i++) {
                if (cur[i].hints & HWC_HINT_CLEAR_FB) {
            // Calculate the new transparent region and dirty region
            // - the transparent region needs to always include the layers
            // that moved from FB to OVERLAY, regardless of the dirty region
            // - the dirty region needs to be expanded to include layers
            // that moved from OVERLAY to FB.

            const sp<LayerBase>& layer(layers[i]);
            const sp<LayerBase>& layer(layers[i]);
                    if (layer->isOpaque()) {
            if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
                transparent.orSelf(layer->visibleRegionScreen);
                transparent.orSelf(layer->visibleRegionScreen);
            }
            }

            bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER) &&
                !(cur[i].flags & HWC_SKIP_LAYER);

            if (!isOverlay && layer->isOverlay()) {
                dirtyInOut->orSelf(layer->visibleRegionScreen);
            }

            if (isOverlay && !layer->isOverlay()) {
                transparentDirty.orSelf(layer->visibleRegionScreen);
            }
            }

            layer->setOverlay(isOverlay);
        }
        }


        /*
        /*
         *  clear the area of the FB that need to be transparent
         *  clear the area of the FB that need to be transparent
         */
         */
            transparent.andSelf(dirty);
        transparent.andSelf(transparentDirty);
        if (!transparent.isEmpty()) {
        if (!transparent.isEmpty()) {
            glClearColor(0,0,0,0);
            glClearColor(0,0,0,0);
            Region::const_iterator it = transparent.begin();
            Region::const_iterator it = transparent.begin();
@@ -964,19 +964,28 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
    }
    }
}
}


void SurfaceFlinger::composeSurfaces(const Region& dirty)
{
    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
        // should never happen unless the window manager has a bug
        // draw something...
        drawWormhole();
    }

    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    HWComposer& hwc(hw.getHwComposer());
    hwc_layer_t* const cur(hwc.getLayers());


    /*
    /*
     * and then, render the layers targeted at the framebuffer
     * and then, render the layers targeted at the framebuffer
     */
     */
    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
    size_t count = layers.size();
    for (size_t i=0 ; i<count ; i++) {
    for (size_t i=0 ; i<count ; i++) {
        if (cur) {
        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) &&
            if ((cur[i].compositionType != HWC_FRAMEBUFFER) &&
                !(cur[i].flags & HWC_SKIP_LAYER)) {
                !(cur[i].flags & HWC_SKIP_LAYER)) {
                // skip layers handled by the HAL
            continue;
            continue;
        }
        }
        }

        const sp<LayerBase>& layer(layers[i]);
        const sp<LayerBase>& layer(layers[i]);
        const Region clip(dirty.intersect(layer->visibleRegionScreen));
        const Region clip(dirty.intersect(layer->visibleRegionScreen));
        if (!clip.isEmpty()) {
        if (!clip.isEmpty()) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -277,6 +277,7 @@ private:
            void        handleWorkList();
            void        handleWorkList();
            void        handleRepaint();
            void        handleRepaint();
            void        postFramebuffer();
            void        postFramebuffer();
            void        setupHardwareComposer(Region* dirtyInOut);
            void        composeSurfaces(const Region& dirty);
            void        composeSurfaces(const Region& dirty);
            void        repaintEverything();
            void        repaintEverything();