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

Commit d1f9aaa5 authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Fix various draw ops that may incorrectly not scissor"

parents e08d54b9 39a908c1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject cl

static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
    return renderer->quickReject(left, top, right, bottom);
    return renderer->quickRejectNoScissor(left, top, right, bottom);
}

static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
+11 −4
Original line number Diff line number Diff line
@@ -356,22 +356,26 @@ void DisplayList::outputViewProperties(const int level) {
                    level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix));
        }
    }

    bool clipToBoundsNeeded = mClipToBounds;
    if (mAlpha < 1) {
        if (mCaching) {
            ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mAlpha);
            clipToBoundsNeeded = false; // clipping done by layer
        } else if (!mHasOverlappingRendering) {
            ALOGD("%*sScaleAlpha %.2f", level * 2, "", mAlpha);
        } else {
            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
            if (mClipToBounds) {
            if (clipToBoundsNeeded) {
                flags |= SkCanvas::kClipToLayer_SaveFlag;
                clipToBoundsNeeded = false; // clipping done by save layer
            }
            ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
                    (int)(mAlpha * 255), flags);
        }
    }
    if (mClipToBounds && !mCaching) {
    if (clipToBoundsNeeded) {
        ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
                (float) mRight - mLeft, (float) mBottom - mTop);
    }
@@ -406,9 +410,11 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler,
            renderer.concatMatrix(mTransformMatrix);
        }
    }
    bool clipToBoundsNeeded = mClipToBounds;
    if (mAlpha < 1) {
        if (mCaching) {
            renderer.setOverrideLayerAlpha(mAlpha);
            clipToBoundsNeeded = false; // clipping done by layer
        } else if (!mHasOverlappingRendering) {
            renderer.scaleAlpha(mAlpha);
        } else {
@@ -416,15 +422,16 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler,
            // have to pass it into this call. In fact, this information might be in the
            // location/size info that we store with the new native transform data.
            int saveFlags = SkCanvas::kHasAlphaLayer_SaveFlag;
            if (mClipToBounds) {
            if (clipToBoundsNeeded) {
                saveFlags |= SkCanvas::kClipToLayer_SaveFlag;
                clipToBoundsNeeded = false; // clipping done by saveLayer
            }
            handler(mSaveLayerOp->reinit(0, 0, mRight - mLeft, mBottom - mTop,
                    mAlpha * 255, SkXfermode::kSrcOver_Mode, saveFlags), PROPERTY_SAVECOUNT,
                    mClipToBounds);
        }
    }
    if (mClipToBounds && !mCaching) {
    if (clipToBoundsNeeded) {
        handler(mClipRectOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op),
                PROPERTY_SAVECOUNT, mClipToBounds);
    }
+26 −35
Original line number Diff line number Diff line
@@ -993,6 +993,10 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
    const Rect& rect = layer->layer;
    const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer;

    bool clipRequired = false;
    quickRejectNoScissor(rect, &clipRequired); // safely ignore return, should never be rejected
    mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);

    if (fboLayer) {
        endTiling();

@@ -1568,8 +1572,9 @@ const Rect& OpenGLRenderer::getClipBounds() {
    return mSnapshot->getLocalClip();
}

bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom) {
    if (mSnapshot->isIgnored()) {
bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom,
        bool* clipRequired) {
    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
        return true;
    }

@@ -1580,23 +1585,10 @@ bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, fl
    Rect clipRect(*mSnapshot->clipRect);
    clipRect.snapToPixelBoundaries();

    return !clipRect.intersects(r);
}

bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom,
        Rect& transformed, Rect& clip) {
    if (mSnapshot->isIgnored()) {
        return true;
    }

    transformed.set(left, top, right, bottom);
    currentTransform().mapRect(transformed);
    transformed.snapToPixelBoundaries();

    clip.set(*mSnapshot->clipRect);
    clip.snapToPixelBoundaries();
    if (!clipRect.intersects(r)) return true;

    return !clip.intersects(transformed);
    if (clipRequired) *clipRequired = !clipRect.contains(r);
    return false;
}

bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, float bottom,
@@ -1610,23 +1602,15 @@ bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, fl
}

bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
    bool clipRequired = false;
    if (quickRejectNoScissor(left, top, right, bottom, &clipRequired)) {
        return true;
    }

    Rect r(left, top, right, bottom);
    currentTransform().mapRect(r);
    r.snapToPixelBoundaries();

    Rect clipRect(*mSnapshot->clipRect);
    clipRect.snapToPixelBoundaries();

    bool rejected = !clipRect.intersects(r);
    if (!isDeferred() && !rejected) {
        mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clipRect.contains(r));
    if (!isDeferred()) {
        mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
    }

    return rejected;
    return false;
}

void OpenGLRenderer::debugClip() {
@@ -2163,6 +2147,9 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes
        return DrawGlInfo::kStatusDone;
    }

    // TODO: use quickReject on bounds from vertices
    mCaches.enableScissor();

    float left = FLT_MAX;
    float top = FLT_MAX;
    float right = FLT_MIN;
@@ -2829,6 +2816,8 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count
        return DrawGlInfo::kStatusDone;
    }

    mCaches.enableScissor();

    float x = 0.0f;
    float y = 0.0f;
    const bool pureTranslate = currentTransform().isPureTranslate();
@@ -2984,6 +2973,9 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co
        return DrawGlInfo::kStatusDone;
    }

    // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics
    mCaches.enableScissor();

    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
    fontRenderer.setFont(paint, mat4::identity());
    fontRenderer.setTextureFiltering(true);
@@ -3059,10 +3051,9 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
        }
    }

    Rect transformed;
    Rect clip;
    bool clipRequired = false;
    const bool rejected = quickRejectNoScissor(x, y,
            x + layer->layer.getWidth(), y + layer->layer.getHeight(), transformed, clip);
            x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired);

    if (rejected) {
        if (transform && !transform->isIdentity()) {
@@ -3073,7 +3064,7 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {

    updateLayer(layer, true);

    mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clip.contains(transformed));
    mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
    mCaches.activeTexture(0);

    if (CC_LIKELY(!layer->region.isEmpty())) {
+22 −14
Original line number Diff line number Diff line
@@ -252,11 +252,31 @@ public:
    virtual void concatMatrix(SkMatrix* matrix);

    ANDROID_API const Rect& getClipBounds();
    ANDROID_API bool quickReject(float left, float top, float right, float bottom);

    /**
     * Performs a quick reject but adjust the bounds to account for stroke width if necessary
     */
    bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint);

    /**
     * Returns false and sets scissor based upon bounds if drawing won't be clipped out
     */
    bool quickReject(float left, float top, float right, float bottom);
    bool quickReject(const Rect& bounds) {
        return quickReject(bounds.left, bounds.top, bounds.right, bounds.bottom);
    }
    bool quickRejectNoScissor(float left, float top, float right, float bottom);

    /**
     * Same as quickReject, without the scissor, instead returning clipRequired through pointer.
     * clipRequired will be only set if not rejected
     */
    ANDROID_API bool quickRejectNoScissor(float left, float top, float right, float bottom,
            bool* clipRequired = NULL);
    bool quickRejectNoScissor(const Rect& bounds, bool* clipRequired = NULL) {
        return quickRejectNoScissor(bounds.left, bounds.top, bounds.right, bounds.bottom,
                clipRequired);
    }

    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
    virtual bool clipPath(SkPath* path, SkRegion::Op op);
    virtual bool clipRegion(SkRegion* region, SkRegion::Op op);
@@ -603,18 +623,6 @@ private:
     */
    void setStencilFromClip();

    /**
     * Performs a quick reject but does not affect the scissor. Returns
     * the transformed rect to test and the current clip.
     */
    bool quickRejectNoScissor(float left, float top, float right, float bottom,
            Rect& transformed, Rect& clip);

    /**
     * Performs a quick reject but adjust the bounds to account for stroke width if necessary
     */
    bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint);

    /**
     * Given the local bounds of the layer, calculates ...
     */
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
namespace android {
namespace uirenderer {

#define RECT_STRING "%4.2f %4.2f %4.2f %4.2f"
#define RECT_STRING "%7.2f %7.2f %7.2f %7.2f"
#define RECT_ARGS(r) \
    (r).left, (r).top, (r).right, (r).bottom