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

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

Merge "Clean up clipping and deferral logic"

parents 14bd8359 5d116764
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -937,6 +937,8 @@ class GLES20Canvas extends HardwareCanvas {

    @Override
    public void drawLines(float[] pts, int offset, int count, Paint paint) {
        if (count < 4) return;

        if ((offset | count) < 0 || offset + count > pts.length) {
            throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
        }
@@ -1060,6 +1062,8 @@ class GLES20Canvas extends HardwareCanvas {

    @Override
    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
        if (count < 2) return;

        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
        try {
            nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
+2 −2
Original line number Diff line number Diff line
@@ -1199,7 +1199,7 @@ public class Canvas {
     * meshHeight+1 vertices down. The verts array is accessed in row-major
     * order, so that the first meshWidth+1 vertices are distributed across the
     * top of the bitmap from left to right. A more general version of this
     * methid is drawVertices().
     * method is drawVertices().
     *
     * @param bitmap The bitmap to draw using the mesh
     * @param meshWidth The number of columns in the mesh. Nothing is drawn if
@@ -1208,7 +1208,7 @@ public class Canvas {
     *                   this is 0
     * @param verts Array of x,y pairs, specifying where the mesh should be
     *              drawn. There must be at least
     *              (meshWidth+1) * (meshHeight+1) * 2 + meshOffset values
     *              (meshWidth+1) * (meshHeight+1) * 2 + vertOffset values
     *              in the array
     * @param vertOffset Number of verts elements to skip before drawing
     * @param colors May be null. Specifies a color at each vertex, which is
+2 −7
Original line number Diff line number Diff line
@@ -436,13 +436,8 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag
        Caches::getInstance().eventMark(strlen(op->name()), op->name());
#endif

        if (deferredList) {
        drawGlStatus |= op->replay(renderer, dirty, flags,
                    saveCount, level, mCaching, mMultipliedAlpha, *deferredList);
        } else {
            drawGlStatus |= op->replay(renderer, dirty, flags,
                    saveCount, level, mCaching, mMultipliedAlpha);
        }
                saveCount, level, mCaching, mMultipliedAlpha, deferredList);
        logBuffer.writeCommand(level, op->name());
    }

+38 −50
Original line number Diff line number Diff line
@@ -74,14 +74,11 @@ public:
        kOpLogFlag_JSON = 0x2 // TODO: add?
    };

    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
            uint32_t level, bool caching, int multipliedAlpha) = 0;

    // same as replay above, but draw operations will defer into the deferredList if possible
    // NOTE: colorfilters, paintfilters, shaders, shadow, and complex clips prevent deferral
    // If a DeferredDisplayList is supplied, DrawOps will be stored until the list is flushed
    // NOTE: complex clips and layers prevent deferral
    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
            uint32_t level, bool caching, int multipliedAlpha,
            DeferredDisplayList& deferredList) = 0;
            DeferredDisplayList* deferredList) = 0;

    virtual void output(int level, uint32_t flags = 0) = 0;

@@ -96,22 +93,16 @@ public:

    virtual ~StateOp() {}

    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
            uint32_t level, bool caching, int multipliedAlpha) {
        applyState(renderer, saveCount);
        return DrawGlInfo::kStatusDone;
    }

    /**
     * State operations are applied directly to the renderer, but can cause the deferred drawing op
     * list to flush
     */
    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
            uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList& deferredList) {
            uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) {
        status_t status = DrawGlInfo::kStatusDone;
        if (requiresDrawOpFlush()) {
        if (deferredList && requiresDrawOpFlush()) {
            // will be setting renderer state that affects ops in deferredList, so flush list first
            status |= deferredList.flush(renderer, dirty, flags, level);
            status |= deferredList->flush(renderer, dirty, flags, level);
        }
        applyState(renderer, saveCount);
        return status;
@@ -131,23 +122,14 @@ public:
    DrawOp(SkPaint* paint)
            : mPaint(paint), mQuickRejected(false) {}

    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
            uint32_t level, bool caching, int multipliedAlpha) {
        if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) {
            return DrawGlInfo::kStatusDone;
        }

        return applyDraw(renderer, dirty, level, caching, multipliedAlpha);
    }

    /** Draw operations are stored in the deferredList with information necessary for playback */
    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
            uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList& deferredList) {
            uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) {
        if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) {
            return DrawGlInfo::kStatusDone;
        }

        if (renderer.disallowDeferral()) {
        if (!deferredList || renderer.disallowDeferral()) {
            // dispatch draw immediately, since the renderer's state is too complex for deferral
            return applyDraw(renderer, dirty, level, caching, multipliedAlpha);
        }
@@ -161,7 +143,7 @@ public:

        if (!renderer.storeDisplayState(state)) {
            // op wasn't quick-rejected, so defer
            deferredList.add(this, renderer.disallowReorder());
            deferredList->add(this, renderer.disallowReorder());
        }

        return DrawGlInfo::kStatusDone;
@@ -184,7 +166,6 @@ public:

    float strokeWidthOutset() { return mPaint->getStrokeWidth() * 0.5f; }

public:
    /**
     * Stores the relevant canvas state of the object between deferral and replay (if the canvas
     * state supports being stored) See OpenGLRenderer::simpleClipAndState()
@@ -204,7 +185,20 @@ public:
    DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
            : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}

    // default constructor for area, to be overridden in child constructor body
    // Calculates bounds as smallest rect encompassing all points
    // NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in
    // subclass' constructor)
    DrawBoundedOp(const float* points, int count, SkPaint* paint)
            : DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) {
        for (int i = 2; i < count; i += 2) {
            mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
            mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]);
            mLocalBounds.top = fminf(mLocalBounds.top, points[i + 1]);
            mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i + 1]);
        }
    }

    // default empty constructor for bounds, to be overridden in child constructor body
    DrawBoundedOp(SkPaint* paint)
            : DrawOp(paint) {}

@@ -740,11 +734,12 @@ public:
    }
};

class DrawBitmapMeshOp : public DrawOp {
class DrawBitmapMeshOp : public DrawBoundedOp {
public:
    DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight,
            float* vertices, int* colors, SkPaint* paint)
            : DrawOp(paint), mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
            : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint),
            mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
            mVertices(vertices), mColors(colors) {}

    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
@@ -873,10 +868,11 @@ public:
    virtual const char* name() { return "DrawRect"; }
};

class DrawRectsOp : public DrawOp {
class DrawRectsOp : public DrawBoundedOp {
public:
    DrawRectsOp(const float* rects, int count, SkPaint* paint)
            : DrawOp(paint), mRects(rects), mCount(count) {}
            : DrawBoundedOp(rects, count, paint),
            mRects(rects), mCount(count) {}

    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
            bool caching, int multipliedAlpha) {
@@ -1022,13 +1018,8 @@ private:
class DrawLinesOp : public DrawBoundedOp {
public:
    DrawLinesOp(float* points, int count, SkPaint* paint)
            : DrawBoundedOp(paint), mPoints(points), mCount(count) {
        for (int i = 0; i < count; i += 2) {
            mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
            mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]);
            mLocalBounds.top = fminf(mLocalBounds.top, points[i+1]);
            mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i+1]);
        }
            : DrawBoundedOp(points, count, paint),
            mPoints(points), mCount(count) {
        mLocalBounds.outset(strokeWidthOutset());
    }

@@ -1199,26 +1190,23 @@ private:
    Functor* mFunctor;
};

class DrawDisplayListOp : public DrawOp {
class DrawDisplayListOp : public DrawBoundedOp {
public:
    DrawDisplayListOp(DisplayList* displayList, int flags)
            : DrawOp(0), mDisplayList(displayList), mFlags(flags) {}
            : DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0),
            mDisplayList(displayList), mFlags(flags) {}

    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
            uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList& deferredList) {
            uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) {
        if (mDisplayList && mDisplayList->isRenderable()) {
            return mDisplayList->replay(renderer, dirty, mFlags, level + 1, &deferredList);
            return mDisplayList->replay(renderer, dirty, mFlags, level + 1, deferredList);
        }
        return DrawGlInfo::kStatusDone;
    }

    // NOT USED, since replay is overridden
    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
            bool caching, int multipliedAlpha) {
        if (mDisplayList && mDisplayList->isRenderable()) {
            return mDisplayList->replay(renderer, dirty, mFlags, level + 1);
        }
        return DrawGlInfo::kStatusDone;
    }
            bool caching, int multipliedAlpha) { return DrawGlInfo::kStatusDone; }

    virtual void output(int level, uint32_t flags) {
        OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags);
+2 −0
Original line number Diff line number Diff line
@@ -1235,6 +1235,8 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state) {
            // quick rejected
            return true;
        }
    } else {
        state.mBounds.set(currentClip);
    }

    state.mClip.set(currentClip);