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

Commit ee44edd0 authored by Dan Stoza's avatar Dan Stoza
Browse files

SurfaceFlinger: Pass surface damage to HWC

Passes the surface damage from the incoming SurfaceFlingerConsumer
BufferQueue down to the hardware composer HAL interface, if the
HWC version number is 1.5 or greater.

Bug: 11239309
Change-Id: Ic4305210593874a8d6deba3319055b2b8c57e926
parent 5065a552
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -1020,6 +1020,21 @@ public:
        SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects);
        visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
    }
    virtual void setSurfaceDamage(const Region& reg) {
        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
            return;
        }
        hwc_region_t& surfaceDamage = getLayer()->surfaceDamage;
        // We encode default full-screen damage as INVALID_RECT upstream, but as
        // 0 rects for HWComposer
        if (reg.isRect() && reg.getBounds() == Rect::INVALID_RECT) {
            surfaceDamage.numRects = 0;
            surfaceDamage.rects = NULL;
            return;
        }
        SharedBuffer const* sb = reg.getSharedBuffer(&surfaceDamage.numRects);
        surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
    }
    virtual void setSidebandStream(const sp<NativeHandle>& stream) {
        ALOG_ASSERT(stream->handle() != NULL);
        getLayer()->compositionType = HWC_SIDEBAND;
@@ -1050,6 +1065,18 @@ public:
        }

        getLayer()->acquireFenceFd = -1;

        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
            return;
        }

        hwc_region_t& surfaceDamage = getLayer()->surfaceDamage;
        sb = SharedBuffer::bufferFromData(surfaceDamage.rects);
        if (sb) {
            sb->release();
            surfaceDamage.numRects = 0;
            surfaceDamage.rects = NULL;
        }
    }
};

+1 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ public:
        virtual void setFrame(const Rect& frame) = 0;
        virtual void setCrop(const FloatRect& crop) = 0;
        virtual void setVisibleRegionScreen(const Region& reg) = 0;
        virtual void setSurfaceDamage(const Region& reg) = 0;
        virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
        virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
        virtual void setAcquireFenceFd(int fenceFd) = 0;
+23 −0
Original line number Diff line number Diff line
@@ -513,6 +513,16 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
    layer.setVisibleRegionScreen(visible);

    // Pass full-surface damage down untouched
    if (surfaceDamageRegion.isRect() &&
            surfaceDamageRegion.getBounds() == Rect::INVALID_RECT) {
        layer.setSurfaceDamage(surfaceDamageRegion);
    } else {
        Region surfaceDamage =
            tr.transform(surfaceDamageRegion.intersect(hw->getViewport()));
        layer.setSurfaceDamage(surfaceDamage);
    }

    if (mSidebandStream.get()) {
        layer.setSidebandStream(mSidebandStream);
    } else {
@@ -1034,6 +1044,18 @@ bool Layer::setLayerStack(uint32_t layerStack) {
    return true;
}

void Layer::useSurfaceDamage() {
    if (mFlinger->mForceFullDamage) {
        surfaceDamageRegion = Region::INVALID_REGION;
    } else {
        surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
    }
}

void Layer::useEmptyDamage() {
    surfaceDamageRegion.clear();
}

// ----------------------------------------------------------------------------
// pageflip handling...
// ----------------------------------------------------------------------------
@@ -1349,6 +1371,7 @@ void Layer::dump(String8& result, Colorizer& colorizer) const

    s.activeTransparentRegion.dump(result, "transparentRegion");
    visibleRegion.dump(result, "visibleRegion");
    surfaceDamageRegion.dump(result, "surfaceDamageRegion");
    sp<Client> client(mClientRef.promote());

    result.appendFormat(            "      "
+7 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ public:
    Region visibleRegion;
    Region coveredRegion;
    Region visibleNonTransparentRegion;
    Region surfaceDamageRegion;

    // Layer serial number.  This gives layers an explicit ordering, so we
    // have a stable sort order when their layer stack and Z-order are
@@ -137,6 +138,12 @@ public:
    bool setCrop(const Rect& crop);
    bool setLayerStack(uint32_t layerStack);

    // If we have received a new buffer this frame, we will pass its surface
    // damage down to hardware composer. Otherwise, we must send a region with
    // one empty rect.
    void useSurfaceDamage();
    void useEmptyDamage();

    uint32_t getTransactionFlags(uint32_t flags);
    uint32_t setTransactionFlags(uint32_t flags);

+11 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ SurfaceFlinger::SurfaceFlinger()
        mDebugInTransaction(0),
        mLastTransactionTime(0),
        mBootFinished(false),
        mForceFullDamage(false),
        mPrimaryHWVsyncEnabled(false),
        mHWVsyncAvailable(false),
        mDaltonize(false),
@@ -1725,12 +1726,17 @@ bool SurfaceFlinger::handlePageFlip()
            frameQueued = true;
            if (layer->shouldPresentNow(mPrimaryDispSync)) {
                layersWithQueuedFrames.push_back(layer.get());
            } else {
                layer->useEmptyDamage();
            }
        } else {
            layer->useEmptyDamage();
        }
    }
    for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
        Layer* layer = layersWithQueuedFrames[i];
        const Region dirty(layer->latchBuffer(visibleRegions));
        layer->useSurfaceDamage();
        const Layer::State& s(layer->getDrawingState());
        invalidateLayerStack(s.layerStack, dirty);
    }
@@ -2876,6 +2882,11 @@ status_t SurfaceFlinger::onTransact(
                mPrimaryDispSync.setRefreshSkipCount(n);
                return NO_ERROR;
            }
            case 1017: {
                n = data.readInt32();
                mForceFullDamage = static_cast<bool>(n);
                return NO_ERROR;
            }
        }
    }
    return err;
Loading