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

Commit 33c1ea73 authored by Chet Haase's avatar Chet Haase
Browse files

Enable path clipping for View outlines

Clipping Views to Outlines has existed for several releases,
as has providing a Path for shaping Oulines. However, using
a Path-shaped Outline to clip a View against was specifically
disabled internally, due to historical functionality limitations
(prior to enabling Skia for HWUI rendering) as well as performance
concerns.

On current (even relatively low-end) hardware, path clipping is now
sufficiently performant that we are enabling this functionality.
This functionality will be used by AndroidX APIs that enable easier
shaping via paths.

Bug: 201807515
Test: Manual testing including hwui performance tests and CTS
OutlineTest

Change-Id: Ic61d9393cb72c6ad3517954177e5037a383a0c4d
parent 1544cd3c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -118,13 +118,13 @@ public final class Outline {
    /**
     * Returns whether the outline can be used to clip a View.
     * <p>
     * Currently, only Outlines that can be represented as a rectangle, circle,
     * or round rect support clipping.
     * As of API 33, all Outline shapes support clipping. Prior to API 33, only Outlines that
     * could be represented as a rectangle, circle, or round rect supported clipping.
     *
     * @see android.view.View#setClipToOutline(boolean)
     */
    public boolean canClip() {
        return mMode != MODE_PATH;
        return true;
    }

    /**
+3 −7
Original line number Diff line number Diff line
@@ -88,14 +88,10 @@ public:

    bool getShouldClip() const { return mShouldClip; }

    bool willClip() const {
        // only round rect outlines can be used for clipping
        return mShouldClip && (mType == Type::RoundRect);
    }
    bool willClip() const { return mShouldClip; }

    bool willRoundRectClip() const {
        // only round rect outlines can be used for clipping
        return willClip() && MathUtils::isPositive(mRadius);
    bool willComplexClip() const {
        return mShouldClip && (mType != Type::RoundRect || MathUtils::isPositive(mRadius));
    }

    bool getAsRoundRect(Rect* outRect, float* outRadius) const {
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ void ProfileData::dump(int fd) const {
    histogramGPUForEach([fd](HistogramEntry entry) {
        dprintf(fd, " %ums=%u", entry.renderTimeMs, entry.frameCount);
    });
    dprintf(fd, "\n");
}

uint32_t ProfileData::findPercentile(int percentile) const {
+3 −3
Original line number Diff line number Diff line
@@ -165,11 +165,11 @@ public:
    bool prepareForFunctorPresence(bool willHaveFunctor, bool ancestorDictatesFunctorsNeedLayer) {
        // parent may have already dictated that a descendant layer is needed
        bool functorsNeedLayer =
                ancestorDictatesFunctorsNeedLayer
                || CC_UNLIKELY(isClipMayBeComplex())
                ancestorDictatesFunctorsNeedLayer ||
                CC_UNLIKELY(isClipMayBeComplex())

                // Round rect clipping forces layer for functors
                || CC_UNLIKELY(getOutline().willRoundRectClip()) ||
                || CC_UNLIKELY(getOutline().willComplexClip()) ||
                CC_UNLIKELY(getRevealClip().willClip())

                // Complex matrices forces layer, due to stencil clipping
+4 −0
Original line number Diff line number Diff line
@@ -88,6 +88,10 @@ static void clipOutline(const Outline& outline, SkCanvas* canvas, const SkRect*
        if (pendingClip) {
            canvas->clipRect(*pendingClip);
        }
        const SkPath* path = outline.getPath();
        if (path) {
            canvas->clipPath(*path, SkClipOp::kIntersect, true);
        }
        return;
    }

Loading