/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <VectorDrawable.h>
#include <gtest/gtest.h>

#include <SkClipStack.h>
#include <SkLiteRecorder.h>
#include <SkSurface_Base.h>
#include <string.h>
#include "AnimationContext.h"
#include "DamageAccumulator.h"
#include "FatalTestCanvas.h"
#include "IContextFactory.h"
#include "SkiaCanvas.h"
#include "pipeline/skia/SkiaDisplayList.h"
#include "pipeline/skia/SkiaOpenGLPipeline.h"
#include "pipeline/skia/SkiaPipeline.h"
#include "pipeline/skia/SkiaRecordingCanvas.h"
#include "renderthread/CanvasContext.h"
#include "tests/common/TestUtils.h"

using namespace android;
using namespace android::uirenderer;
using namespace android::uirenderer::renderthread;
using namespace android::uirenderer::skiapipeline;

TEST(RenderNodeDrawable, create) {
    auto rootNode =
            TestUtils::createNode(0, 0, 200, 400, [](RenderProperties& props, Canvas& canvas) {
                canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
            });

    SkLiteDL skLiteDL;
    SkLiteRecorder canvas;
    canvas.reset(&skLiteDL, SkIRect::MakeWH(1, 1));
    canvas.translate(100, 100);
    RenderNodeDrawable drawable(rootNode.get(), &canvas);

    ASSERT_EQ(drawable.getRenderNode(), rootNode.get());
    ASSERT_EQ(&drawable.getNodeProperties(), &rootNode->properties());
    ASSERT_EQ(drawable.getRecordedMatrix(), canvas.getTotalMatrix());
}

namespace {

static void drawOrderedRect(Canvas* canvas, uint8_t expectedDrawOrder) {
    SkPaint paint;
    // order put in blue channel, transparent so overlapped content doesn't get rejected
    paint.setColor(SkColorSetARGB(1, 0, 0, expectedDrawOrder));
    canvas->drawRect(0, 0, 100, 100, paint);
}

static void drawOrderedNode(Canvas* canvas, uint8_t expectedDrawOrder, float z) {
    auto node = TestUtils::createSkiaNode(
            0, 0, 100, 100,
            [expectedDrawOrder, z](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                drawOrderedRect(&canvas, expectedDrawOrder);
                props.setTranslationZ(z);
            });
    canvas->drawRenderNode(node.get());  // canvas takes reference/sole ownership
}

static void drawOrderedNode(
        Canvas* canvas, uint8_t expectedDrawOrder,
        std::function<void(RenderProperties& props, SkiaRecordingCanvas& canvas)> setup) {
    auto node = TestUtils::createSkiaNode(
            0, 0, 100, 100,
            [expectedDrawOrder, setup](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                drawOrderedRect(&canvas, expectedDrawOrder);
                if (setup) {
                    setup(props, canvas);
                }
            });
    canvas->drawRenderNode(node.get());  // canvas takes reference/sole ownership
}

class ZReorderCanvas : public SkCanvas {
public:
    ZReorderCanvas(int width, int height) : SkCanvas(width, height) {}
    void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
        int expectedOrder = SkColorGetB(paint.getColor());  // extract order from blue channel
        EXPECT_EQ(expectedOrder, mDrawCounter++) << "An op was drawn out of order";
    }
    int getIndex() { return mDrawCounter; }

protected:
    int mDrawCounter = 0;
};

}  // end anonymous namespace

TEST(RenderNodeDrawable, zReorder) {
    auto parent = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                               SkiaRecordingCanvas& canvas) {
        canvas.insertReorderBarrier(true);
        canvas.insertReorderBarrier(false);
        drawOrderedNode(&canvas, 0, 10.0f);  // in reorder=false at this point, so played inorder
        drawOrderedRect(&canvas, 1);
        canvas.insertReorderBarrier(true);
        drawOrderedNode(&canvas, 6, 2.0f);
        drawOrderedRect(&canvas, 3);
        drawOrderedNode(&canvas, 4, 0.0f);
        drawOrderedRect(&canvas, 5);
        drawOrderedNode(&canvas, 2, -2.0f);
        drawOrderedNode(&canvas, 7, 2.0f);
        canvas.insertReorderBarrier(false);
        drawOrderedRect(&canvas, 8);
        drawOrderedNode(&canvas, 9, -10.0f);  // in reorder=false at this point, so played inorder
        canvas.insertReorderBarrier(true);    // reorder a node ahead of drawrect op
        drawOrderedRect(&canvas, 11);
        drawOrderedNode(&canvas, 10, -1.0f);
        canvas.insertReorderBarrier(false);
        canvas.insertReorderBarrier(true);  // test with two empty reorder sections
        canvas.insertReorderBarrier(true);
        canvas.insertReorderBarrier(false);
        drawOrderedRect(&canvas, 12);
    });

    // create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
    ZReorderCanvas canvas(100, 100);
    RenderNodeDrawable drawable(parent.get(), &canvas, false);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(13, canvas.getIndex());
}

TEST(RenderNodeDrawable, composeOnLayer) {
    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
    SkCanvas& canvas = *surface->getCanvas();
    canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);

    auto rootNode = TestUtils::createSkiaNode(
            0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& recorder) {
                recorder.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
            });

    // attach a layer to the render node
    auto surfaceLayer = SkSurface::MakeRasterN32Premul(1, 1);
    auto canvas2 = surfaceLayer->getCanvas();
    canvas2->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
    rootNode->setLayerSurface(surfaceLayer);

    RenderNodeDrawable drawable1(rootNode.get(), &canvas, false);
    canvas.drawDrawable(&drawable1);
    ASSERT_EQ(SK_ColorRED, TestUtils::getColor(surface, 0, 0));

    RenderNodeDrawable drawable2(rootNode.get(), &canvas, true);
    canvas.drawDrawable(&drawable2);
    ASSERT_EQ(SK_ColorWHITE, TestUtils::getColor(surface, 0, 0));

    RenderNodeDrawable drawable3(rootNode.get(), &canvas, false);
    canvas.drawDrawable(&drawable3);
    ASSERT_EQ(SK_ColorRED, TestUtils::getColor(surface, 0, 0));

    rootNode->setLayerSurface(sk_sp<SkSurface>());
}

namespace {
static SkRect getRecorderClipBounds(const SkiaRecordingCanvas& recorder) {
    SkRect clipBounds;
    recorder.getClipBounds(&clipBounds);
    return clipBounds;
}

static SkMatrix getRecorderMatrix(const SkiaRecordingCanvas& recorder) {
    SkMatrix matrix;
    recorder.getMatrix(&matrix);
    return matrix;
}
}

TEST(RenderNodeDrawable, saveLayerClipAndMatrixRestore) {
    auto surface = SkSurface::MakeRasterN32Premul(400, 800);
    SkCanvas& canvas = *surface->getCanvas();
    canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);

    auto rootNode = TestUtils::createSkiaNode(
            0, 0, 400, 800, [](RenderProperties& props, SkiaRecordingCanvas& recorder) {
                SkPaint layerPaint;
                ASSERT_EQ(SkRect::MakeLTRB(0, 0, 400, 800), getRecorderClipBounds(recorder));
                EXPECT_TRUE(getRecorderMatrix(recorder).isIdentity());

                // note we don't pass SaveFlags::MatrixClip, but matrix and clip will be saved
                recorder.saveLayer(0, 0, 400, 400, &layerPaint, SaveFlags::ClipToLayer);
                ASSERT_EQ(SkRect::MakeLTRB(0, 0, 400, 400), getRecorderClipBounds(recorder));
                EXPECT_TRUE(getRecorderMatrix(recorder).isIdentity());

                recorder.clipRect(50, 50, 350, 350, SkClipOp::kIntersect);
                ASSERT_EQ(SkRect::MakeLTRB(50, 50, 350, 350), getRecorderClipBounds(recorder));

                recorder.translate(300.0f, 400.0f);
                EXPECT_EQ(SkMatrix::MakeTrans(300.0f, 400.0f), getRecorderMatrix(recorder));

                recorder.restore();
                ASSERT_EQ(SkRect::MakeLTRB(0, 0, 400, 800), getRecorderClipBounds(recorder));
                EXPECT_TRUE(getRecorderMatrix(recorder).isIdentity());

                SkPaint paint;
                paint.setAntiAlias(true);
                paint.setColor(SK_ColorGREEN);
                recorder.drawRect(0.0f, 400.0f, 400.0f, 800.0f, paint);
            });

    RenderNodeDrawable drawable(rootNode.get(), &canvas, true);
    canvas.drawDrawable(&drawable);
    ASSERT_EQ(SK_ColorGREEN, TestUtils::getColor(surface, 200, 600));
}

namespace {
class ContextFactory : public IContextFactory {
public:
    virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
        return new AnimationContext(clock);
    }
};
}  // end anonymous namespace

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorder) {
    static const int SCROLL_X = 5;
    static const int SCROLL_Y = 10;
    class ProjectionTestCanvas : public SkCanvas {
    public:
        ProjectionTestCanvas(int width, int height) : SkCanvas(width, height) {}
        void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
            const int index = mDrawCounter++;
            SkMatrix expectedMatrix;
            ;
            switch (index) {
                case 0:  // this is node "B"
                    EXPECT_EQ(SkRect::MakeWH(100, 100), rect);
                    EXPECT_EQ(SK_ColorWHITE, paint.getColor());
                    expectedMatrix.reset();
                    EXPECT_EQ(SkRect::MakeLTRB(0, 0, 100, 100), TestUtils::getClipBounds(this));
                    break;
                case 1:  // this is node "P"
                    EXPECT_EQ(SkRect::MakeLTRB(-10, -10, 60, 60), rect);
                    EXPECT_EQ(SK_ColorDKGRAY, paint.getColor());
                    expectedMatrix.setTranslate(50 - SCROLL_X, 50 - SCROLL_Y);
                    EXPECT_EQ(SkRect::MakeLTRB(-35, -30, 45, 50),
                              TestUtils::getLocalClipBounds(this));
                    break;
                case 2:  // this is node "C"
                    EXPECT_EQ(SkRect::MakeWH(100, 50), rect);
                    EXPECT_EQ(SK_ColorBLUE, paint.getColor());
                    expectedMatrix.setTranslate(-SCROLL_X, 50 - SCROLL_Y);
                    EXPECT_EQ(SkRect::MakeLTRB(0, 40, 95, 90), TestUtils::getClipBounds(this));
                    break;
                default:
                    ADD_FAILURE();
            }
            EXPECT_EQ(expectedMatrix, getTotalMatrix());
        }

        int getIndex() { return mDrawCounter; }

    protected:
        int mDrawCounter = 0;
    };

    /**
     * Construct a tree of nodes, where the root (A) has a receiver background (B), and a child (C)
     * with a projecting child (P) of its own. P would normally draw between B and C's "background"
     * draw, but because it is projected backwards, it's drawn in between B and C.
     *
     * The parent is scrolled by SCROLL_X/SCROLL_Y, but this does not affect the background
     * (which isn't affected by scroll).
     */
    auto receiverBackground = TestUtils::createSkiaNode(
            0, 0, 100, 100,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                properties.setProjectionReceiver(true);
                // scroll doesn't apply to background, so undone via translationX/Y
                // NOTE: translationX/Y only! no other transform properties may be set for a proj
                // receiver!
                properties.setTranslationX(SCROLL_X);
                properties.setTranslationY(SCROLL_Y);

                SkPaint paint;
                paint.setColor(SK_ColorWHITE);
                canvas.drawRect(0, 0, 100, 100, paint);
            },
            "B");

    auto projectingRipple = TestUtils::createSkiaNode(
            50, 0, 100, 50,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                properties.setProjectBackwards(true);
                properties.setClipToBounds(false);
                SkPaint paint;
                paint.setColor(SK_ColorDKGRAY);
                canvas.drawRect(-10, -10, 60, 60, paint);
            },
            "P");
    auto child = TestUtils::createSkiaNode(
            0, 50, 100, 100,
            [&projectingRipple](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                SkPaint paint;
                paint.setColor(SK_ColorBLUE);
                canvas.drawRect(0, 0, 100, 50, paint);
                canvas.drawRenderNode(projectingRipple.get());
            },
            "C");
    auto parent = TestUtils::createSkiaNode(
            0, 0, 100, 100,
            [&receiverBackground, &child](RenderProperties& properties,
                                          SkiaRecordingCanvas& canvas) {
                // Set a rect outline for the projecting ripple to be masked against.
                properties.mutableOutline().setRoundRect(10, 10, 90, 90, 5, 1.0f);

                canvas.save(SaveFlags::MatrixClip);
                canvas.translate(-SCROLL_X,
                                 -SCROLL_Y);  // Apply scroll (note: bg undoes this internally)
                canvas.drawRenderNode(receiverBackground.get());
                canvas.drawRenderNode(child.get());
                canvas.restore();
            },
            "A");
    ContextFactory contextFactory;
    std::unique_ptr<CanvasContext> canvasContext(
            CanvasContext::create(renderThread, false, parent.get(), &contextFactory));
    TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
    DamageAccumulator damageAccumulator;
    info.damageAccumulator = &damageAccumulator;
    parent->prepareTree(info);

    // parent(A)             -> (receiverBackground, child)
    // child(C)              -> (rect[0, 0, 100, 50], projectingRipple)
    // projectingRipple(P)   -> (rect[-10, -10, 60, 60]) -> projects backwards
    // receiverBackground(B) -> (rect[0, 0, 100, 100]) -> projection receiver

    // create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
    ProjectionTestCanvas canvas(100, 100);
    RenderNodeDrawable drawable(parent.get(), &canvas, true);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(3, canvas.getIndex());
}

RENDERTHREAD_SKIA_PIPELINE_TEST(RenderNodeDrawable, emptyReceiver) {
    class ProjectionTestCanvas : public SkCanvas {
    public:
        ProjectionTestCanvas(int width, int height) : SkCanvas(width, height) {}
        void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
            mDrawCounter++;
        }

        int getDrawCounter() { return mDrawCounter; }

    private:
        int mDrawCounter = 0;
    };

    auto receiverBackground = TestUtils::createSkiaNode(
            0, 0, 100, 100,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                properties.setProjectionReceiver(true);
            },
            "B"); // a receiver with an empty display list

    auto projectingRipple = TestUtils::createSkiaNode(
            0, 0, 100, 100,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                properties.setProjectBackwards(true);
                properties.setClipToBounds(false);
                SkPaint paint;
                canvas.drawRect(0, 0, 100, 100, paint);
            },
            "P");
    auto child = TestUtils::createSkiaNode(
            0, 0, 100, 100,
            [&projectingRipple](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                SkPaint paint;
                canvas.drawRect(0, 0, 100, 100, paint);
                canvas.drawRenderNode(projectingRipple.get());
            },
            "C");
    auto parent = TestUtils::createSkiaNode(
            0, 0, 100, 100,
            [&receiverBackground, &child](RenderProperties& properties,
                                          SkiaRecordingCanvas& canvas) {
                canvas.drawRenderNode(receiverBackground.get());
                canvas.drawRenderNode(child.get());
            },
            "A");
    ContextFactory contextFactory;
    std::unique_ptr<CanvasContext> canvasContext(
            CanvasContext::create(renderThread, false, parent.get(), &contextFactory));
    TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
    DamageAccumulator damageAccumulator;
    info.damageAccumulator = &damageAccumulator;
    parent->prepareTree(info);

    // parent(A)             -> (receiverBackground, child)
    // child(C)              -> (rect[0, 0, 100, 100], projectingRipple)
    // projectingRipple(P)   -> (rect[0, 0, 100, 100]) -> projects backwards
    // receiverBackground(B) -> (empty) -> projection receiver

    // create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
    ProjectionTestCanvas canvas(100, 100);
    RenderNodeDrawable drawable(parent.get(), &canvas, true);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(2, canvas.getDrawCounter());
}

RENDERTHREAD_SKIA_PIPELINE_TEST(RenderNodeDrawable, projectionHwLayer) {
    /* R is backward projected on B and C is a layer.
                A
               / \
              B   C
                  |
                  R
    */
    static const int SCROLL_X = 5;
    static const int SCROLL_Y = 10;
    static const int CANVAS_WIDTH = 400;
    static const int CANVAS_HEIGHT = 400;
    static const int LAYER_WIDTH = 200;
    static const int LAYER_HEIGHT = 200;
    class ProjectionTestCanvas : public SkCanvas {
    public:
        ProjectionTestCanvas(int* drawCounter)
                : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT), mDrawCounter(drawCounter) {}
        void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
                       const SkPaint&) override {
            EXPECT_EQ(0, (*mDrawCounter)++);  // part of painting the layer
            EXPECT_EQ(SkRect::MakeLTRB(0, 0, LAYER_WIDTH, LAYER_HEIGHT),
                      TestUtils::getClipBounds(this));
        }
        void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
            EXPECT_EQ(1, (*mDrawCounter)++);
            EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT),
                      TestUtils::getClipBounds(this));
        }
        void onDrawOval(const SkRect&, const SkPaint&) override {
            EXPECT_EQ(2, (*mDrawCounter)++);
            SkMatrix expectedMatrix;
            expectedMatrix.setTranslate(100 - SCROLL_X, 100 - SCROLL_Y);
            EXPECT_EQ(expectedMatrix, getTotalMatrix());
            EXPECT_EQ(SkRect::MakeLTRB(-85, -80, 295, 300), TestUtils::getLocalClipBounds(this));
        }
        int* mDrawCounter;
    };

    class ProjectionLayer : public SkSurface_Base {
    public:
        ProjectionLayer(int* drawCounter)
                : SkSurface_Base(SkImageInfo::MakeN32Premul(LAYER_WIDTH, LAYER_HEIGHT), nullptr)
                , mDrawCounter(drawCounter) {}
        virtual sk_sp<SkImage> onNewImageSnapshot() override {
            EXPECT_EQ(3, (*mDrawCounter)++);
            EXPECT_EQ(SkRect::MakeLTRB(100 - SCROLL_X, 100 - SCROLL_Y, 300 - SCROLL_X,
                                       300 - SCROLL_Y),
                      TestUtils::getClipBounds(this->getCanvas()));
            return nullptr;
        }
        SkCanvas* onNewCanvas() override { return new ProjectionTestCanvas(mDrawCounter); }
        sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override { return nullptr; }
        void onCopyOnWrite(ContentChangeMode) override {}
        int* mDrawCounter;
        void onWritePixels(const SkPixmap&, int x, int y) {}
    };

    auto receiverBackground = TestUtils::createSkiaNode(
            0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                properties.setProjectionReceiver(true);
                // scroll doesn't apply to background, so undone via translationX/Y
                // NOTE: translationX/Y only! no other transform properties may be set for a proj
                // receiver!
                properties.setTranslationX(SCROLL_X);
                properties.setTranslationY(SCROLL_Y);

                canvas.drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, SkPaint());
            },
            "B");  // B
    auto projectingRipple = TestUtils::createSkiaNode(
            0, 0, LAYER_WIDTH, LAYER_HEIGHT,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                properties.setProjectBackwards(true);
                properties.setClipToBounds(false);
                canvas.drawOval(100, 100, 300, 300, SkPaint());  // drawn mostly out of layer bounds
            },
            "R");  // R
    auto child = TestUtils::createSkiaNode(
            100, 100, 300, 300,
            [&projectingRipple](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                canvas.drawRenderNode(projectingRipple.get());
                canvas.drawArc(0, 0, LAYER_WIDTH, LAYER_HEIGHT, 0.0f, 280.0f, true, SkPaint());
            },
            "C");  // C
    auto parent = TestUtils::createSkiaNode(
            0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
            [&receiverBackground, &child](RenderProperties& properties,
                                          SkiaRecordingCanvas& canvas) {
                // Set a rect outline for the projecting ripple to be masked against.
                properties.mutableOutline().setRoundRect(10, 10, 390, 390, 0, 1.0f);
                canvas.translate(-SCROLL_X,
                                 -SCROLL_Y);  // Apply scroll (note: bg undoes this internally)
                canvas.drawRenderNode(receiverBackground.get());
                canvas.drawRenderNode(child.get());
            },
            "A");  // A

    // prepareTree is required to find, which receivers have backward projected nodes
    ContextFactory contextFactory;
    std::unique_ptr<CanvasContext> canvasContext(
            CanvasContext::create(renderThread, false, parent.get(), &contextFactory));
    TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
    DamageAccumulator damageAccumulator;
    info.damageAccumulator = &damageAccumulator;
    parent->prepareTree(info);

    int drawCounter = 0;
    // set a layer after prepareTree to avoid layer logic there
    child->animatorProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
    sk_sp<SkSurface> surfaceLayer1(new ProjectionLayer(&drawCounter));
    child->setLayerSurface(surfaceLayer1);
    Matrix4 windowTransform;
    windowTransform.loadTranslate(100, 100, 0);
    child->getSkiaLayer()->inverseTransformInWindow.loadInverse(windowTransform);

    LayerUpdateQueue layerUpdateQueue;
    layerUpdateQueue.enqueueLayerWithDamage(child.get(),
                                            android::uirenderer::Rect(LAYER_WIDTH, LAYER_HEIGHT));
    auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
    pipeline->renderLayersImpl(layerUpdateQueue, true, false);
    EXPECT_EQ(1, drawCounter);  // assert index 0 is drawn on the layer

    RenderNodeDrawable drawable(parent.get(), surfaceLayer1->getCanvas(), true);
    surfaceLayer1->getCanvas()->drawDrawable(&drawable);
    EXPECT_EQ(4, drawCounter);

    // clean up layer pointer, so we can safely destruct RenderNode
    child->setLayerSurface(nullptr);
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionChildScroll) {
    /* R is backward projected on B.
                A
               / \
              B   C
                  |
                  R
    */
    static const int SCROLL_X = 500000;
    static const int SCROLL_Y = 0;
    static const int CANVAS_WIDTH = 400;
    static const int CANVAS_HEIGHT = 400;
    class ProjectionChildScrollTestCanvas : public SkCanvas {
    public:
        ProjectionChildScrollTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
        void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
            EXPECT_EQ(0, mDrawCounter++);
            EXPECT_TRUE(getTotalMatrix().isIdentity());
        }
        void onDrawOval(const SkRect&, const SkPaint&) override {
            EXPECT_EQ(1, mDrawCounter++);
            EXPECT_EQ(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), TestUtils::getClipBounds(this));
            EXPECT_TRUE(getTotalMatrix().isIdentity());
        }
        int mDrawCounter = 0;
    };

    auto receiverBackground = TestUtils::createSkiaNode(
            0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                properties.setProjectionReceiver(true);
                canvas.drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, SkPaint());
            },
            "B");  // B
    auto projectingRipple = TestUtils::createSkiaNode(
            0, 0, 200, 200,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                // scroll doesn't apply to background, so undone via translationX/Y
                // NOTE: translationX/Y only! no other transform properties may be set for a proj
                // receiver!
                properties.setTranslationX(SCROLL_X);
                properties.setTranslationY(SCROLL_Y);
                properties.setProjectBackwards(true);
                properties.setClipToBounds(false);
                canvas.drawOval(0, 0, 200, 200, SkPaint());
            },
            "R");  // R
    auto child = TestUtils::createSkiaNode(
            0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
            [&projectingRipple](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                // Record time clip will be ignored by projectee
                canvas.clipRect(100, 100, 300, 300, SkClipOp::kIntersect);

                canvas.translate(-SCROLL_X,
                                 -SCROLL_Y);  // Apply scroll (note: bg undoes this internally)
                canvas.drawRenderNode(projectingRipple.get());
            },
            "C");  // C
    auto parent =
            TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
                                      [&receiverBackground, &child](RenderProperties& properties,
                                                                    SkiaRecordingCanvas& canvas) {
                                          canvas.drawRenderNode(receiverBackground.get());
                                          canvas.drawRenderNode(child.get());
                                      },
                                      "A");  // A

    // prepareTree is required to find, which receivers have backward projected nodes
    ContextFactory contextFactory;
    std::unique_ptr<CanvasContext> canvasContext(
            CanvasContext::create(renderThread, false, parent.get(), &contextFactory));
    TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
    DamageAccumulator damageAccumulator;
    info.damageAccumulator = &damageAccumulator;
    parent->prepareTree(info);

    std::unique_ptr<ProjectionChildScrollTestCanvas> canvas(new ProjectionChildScrollTestCanvas());
    RenderNodeDrawable drawable(parent.get(), canvas.get(), true);
    canvas->drawDrawable(&drawable);
    EXPECT_EQ(2, canvas->mDrawCounter);
}

namespace {
static int drawNode(RenderThread& renderThread, const sp<RenderNode>& renderNode) {
    ContextFactory contextFactory;
    std::unique_ptr<CanvasContext> canvasContext(
            CanvasContext::create(renderThread, false, renderNode.get(), &contextFactory));
    TreeInfo info(TreeInfo::MODE_RT_ONLY, *canvasContext.get());
    DamageAccumulator damageAccumulator;
    info.damageAccumulator = &damageAccumulator;
    renderNode->prepareTree(info);

    // create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
    ZReorderCanvas canvas(100, 100);
    RenderNodeDrawable drawable(renderNode.get(), &canvas, false);
    canvas.drawDrawable(&drawable);
    return canvas.getIndex();
}
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderProjectedInMiddle) {
    /* R is backward projected on B
                A
               / \
              B   C
                  |
                  R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            props.setProjectionReceiver(true);
        });  // nodeB
        drawOrderedNode(&canvas, 2, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            drawOrderedNode(&canvas, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                props.setProjectBackwards(true);
                props.setClipToBounds(false);
            });  // nodeR
        });      // nodeC
    });          // nodeA
    EXPECT_EQ(3, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderProjectLast) {
    /* R is backward projected on E
                  A
                / | \
               /  |  \
              B   C   E
                  |
                  R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, nullptr);  // nodeB
        drawOrderedNode(&canvas, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            drawOrderedNode(&canvas, 3, [](RenderProperties& props,
                                           SkiaRecordingCanvas& canvas) {  // drawn as 2
                props.setProjectBackwards(true);
                props.setClipToBounds(false);
            });  // nodeR
        });      // nodeC
        drawOrderedNode(&canvas, 2,
                        [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // drawn as 3
                            props.setProjectionReceiver(true);
                        });  // nodeE
    });                      // nodeA
    EXPECT_EQ(4, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderNoReceivable) {
    /* R is backward projected without receiver
                A
               / \
              B   C
                  |
                  R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, nullptr);  // nodeB
        drawOrderedNode(&canvas, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            drawOrderedNode(&canvas, 255, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                // not having a projection receiver is an undefined behavior
                props.setProjectBackwards(true);
                props.setClipToBounds(false);
            });  // nodeR
        });      // nodeC
    });          // nodeA
    EXPECT_EQ(2, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderParentReceivable) {
    /* R is backward projected on C
                A
               / \
              B   C
                  |
                  R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, nullptr);  // nodeB
        drawOrderedNode(&canvas, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            props.setProjectionReceiver(true);
            drawOrderedNode(&canvas, 2, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                props.setProjectBackwards(true);
                props.setClipToBounds(false);
            });  // nodeR
        });      // nodeC
    });          // nodeA
    EXPECT_EQ(3, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderSameNodeReceivable) {
    /* R is backward projected on R
                A
               / \
              B   C
                  |
                  R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, nullptr);  // nodeB
        drawOrderedNode(&canvas, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            drawOrderedNode(&canvas, 255, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                // having a node that is projected on itself is an undefined/unexpected behavior
                props.setProjectionReceiver(true);
                props.setProjectBackwards(true);
                props.setClipToBounds(false);
            });  // nodeR
        });      // nodeC
    });          // nodeA
    EXPECT_EQ(2, drawNode(renderThread, nodeA));
}

// Note: the outcome for this test is different in HWUI
RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderProjectedSibling) {
    /* R is set to project on B, but R is not drawn because projecting on a sibling is not allowed.
                A
               /|\
              / | \
             B  C  R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            props.setProjectionReceiver(true);
        });  // nodeB
        drawOrderedNode(&canvas, 1,
                        [](RenderProperties& props, SkiaRecordingCanvas& canvas) {});  // nodeC
        drawOrderedNode(&canvas, 255, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            props.setProjectBackwards(true);
            props.setClipToBounds(false);
        });  // nodeR
    });      // nodeA
    EXPECT_EQ(2, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderProjectedSibling2) {
    /* R is set to project on B, but R is not drawn because projecting on a sibling is not allowed.
                A
                |
                G
               /|\
              / | \
             B  C  R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            drawOrderedNode(&canvas, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                props.setProjectionReceiver(true);
            });  // nodeB
            drawOrderedNode(&canvas, 2,
                            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {});  // nodeC
            drawOrderedNode(&canvas, 255, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                props.setProjectBackwards(true);
                props.setClipToBounds(false);
            });  // nodeR
        });      // nodeG
    });          // nodeA
    EXPECT_EQ(3, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderGrandparentReceivable) {
    /* R is backward projected on B
                A
                |
                B
                |
                C
                |
                R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
            props.setProjectionReceiver(true);
            drawOrderedNode(&canvas, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                drawOrderedNode(&canvas, 2,
                                [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                                    props.setProjectBackwards(true);
                                    props.setClipToBounds(false);
                                });  // nodeR
            });                      // nodeC
        });                          // nodeB
    });                              // nodeA
    EXPECT_EQ(3, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderTwoReceivables) {
    /* B and G are receivables, R is backward projected
                A
               / \
              B   C
                 / \
                G   R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // B
            props.setProjectionReceiver(true);
        });  // nodeB
        drawOrderedNode(&canvas, 2, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // C
            drawOrderedNode(&canvas, 3,
                            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // G
                                props.setProjectionReceiver(true);
                            });  // nodeG
            drawOrderedNode(&canvas, 1,
                            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // R
                                props.setProjectBackwards(true);
                                props.setClipToBounds(false);
                            });  // nodeR
        });                      // nodeC
    });                          // nodeA
    EXPECT_EQ(4, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderTwoReceivablesLikelyScenario) {
    /* B and G are receivables, G is backward projected
                A
               / \
              B   C
                 / \
                G   R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // B
            props.setProjectionReceiver(true);
        });  // nodeB
        drawOrderedNode(&canvas, 2, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // C
            drawOrderedNode(&canvas, 1,
                            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // G
                                props.setProjectionReceiver(true);
                                props.setProjectBackwards(true);
                                props.setClipToBounds(false);
                            });  // nodeG
            drawOrderedNode(&canvas, 3,
                            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // R
                            });                                                         // nodeR
        });                                                                             // nodeC
    });                                                                                 // nodeA
    EXPECT_EQ(4, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorderTwoReceivablesDeeper) {
    /* B and G are receivables, R is backward projected
                A
               / \
              B   C
                 / \
                G   D
                    |
                    R
    */
    auto nodeA = TestUtils::createSkiaNode(0, 0, 100, 100, [](RenderProperties& props,
                                                              SkiaRecordingCanvas& canvas) {
        drawOrderedNode(&canvas, 0, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // B
            props.setProjectionReceiver(true);
        });  // nodeB
        drawOrderedNode(&canvas, 1, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // C
            drawOrderedNode(&canvas, 2,
                            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // G
                                props.setProjectionReceiver(true);
                            });  // nodeG
            drawOrderedNode(&canvas, 4,
                            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {  // D
                                drawOrderedNode(&canvas, 3, [](RenderProperties& props,
                                                               SkiaRecordingCanvas& canvas) {  // R
                                    props.setProjectBackwards(true);
                                    props.setClipToBounds(false);
                                });  // nodeR
                            });      // nodeD
        });                          // nodeC
    });                              // nodeA
    EXPECT_EQ(5, drawNode(renderThread, nodeA));
}

RENDERTHREAD_TEST(RenderNodeDrawable, simple) {
    static const int CANVAS_WIDTH = 100;
    static const int CANVAS_HEIGHT = 200;
    class SimpleTestCanvas : public TestCanvasBase {
    public:
        SimpleTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {}
        void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
            EXPECT_EQ(0, mDrawCounter++);
        }
        void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*) override {
            EXPECT_EQ(1, mDrawCounter++);
        }
    };

    auto node = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
                                          [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                                              sk_sp<Bitmap> bitmap(TestUtils::createBitmap(25, 25));
                                              canvas.drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
                                                              SkPaint());
                                              canvas.drawBitmap(*bitmap, 10, 10, nullptr);
                                          });

    SimpleTestCanvas canvas;
    RenderNodeDrawable drawable(node.get(), &canvas, true);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(2, canvas.mDrawCounter);
}

RENDERTHREAD_TEST(RenderNodeDrawable, colorOp_unbounded) {
    static const int CANVAS_WIDTH = 200;
    static const int CANVAS_HEIGHT = 200;
    class ColorTestCanvas : public TestCanvasBase {
    public:
        ColorTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {}
        void onDrawPaint(const SkPaint&) {
            switch (mDrawCounter++) {
                case 0:
                    EXPECT_EQ(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT),
                              TestUtils::getClipBounds(this));
                    break;
                case 1:
                    EXPECT_EQ(SkRect::MakeWH(10, 10), TestUtils::getClipBounds(this));
                    break;
                default:
                    ADD_FAILURE();
            }
        }
    };

    auto unclippedColorView = TestUtils::createSkiaNode(
            0, 0, 10, 10, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                props.setClipToBounds(false);
                canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
            });

    auto clippedColorView = TestUtils::createSkiaNode(
            0, 0, 10, 10, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
            });

    ColorTestCanvas canvas;
    RenderNodeDrawable drawable(unclippedColorView.get(), &canvas, true);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(1, canvas.mDrawCounter);
    RenderNodeDrawable drawable2(clippedColorView.get(), &canvas, true);
    canvas.drawDrawable(&drawable2);
    EXPECT_EQ(2, canvas.mDrawCounter);
}

TEST(RenderNodeDrawable, renderNode) {
    static const int CANVAS_WIDTH = 200;
    static const int CANVAS_HEIGHT = 200;
    class RenderNodeTestCanvas : public TestCanvasBase {
    public:
        RenderNodeTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {}
        void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
            switch (mDrawCounter++) {
                case 0:
                    EXPECT_EQ(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT),
                              TestUtils::getClipBounds(this));
                    EXPECT_EQ(SK_ColorDKGRAY, paint.getColor());
                    break;
                case 1:
                    EXPECT_EQ(SkRect::MakeLTRB(50, 50, 150, 150), TestUtils::getClipBounds(this));
                    EXPECT_EQ(SK_ColorWHITE, paint.getColor());
                    break;
                default:
                    ADD_FAILURE();
            }
        }
    };

    auto child = TestUtils::createSkiaNode(
            10, 10, 110, 110, [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                SkPaint paint;
                paint.setColor(SK_ColorWHITE);
                canvas.drawRect(0, 0, 100, 100, paint);
            });

    auto parent = TestUtils::createSkiaNode(
            0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
            [&child](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                SkPaint paint;
                paint.setColor(SK_ColorDKGRAY);
                canvas.drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, paint);

                canvas.save(SaveFlags::MatrixClip);
                canvas.translate(40, 40);
                canvas.drawRenderNode(child.get());
                canvas.restore();
            });

    RenderNodeTestCanvas canvas;
    RenderNodeDrawable drawable(parent.get(), &canvas, true);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(2, canvas.mDrawCounter);
}

// Verify that layers are composed with kLow_SkFilterQuality filter quality.
RENDERTHREAD_SKIA_PIPELINE_TEST(RenderNodeDrawable, layerComposeQuality) {
    static const int CANVAS_WIDTH = 1;
    static const int CANVAS_HEIGHT = 1;
    static const int LAYER_WIDTH = 1;
    static const int LAYER_HEIGHT = 1;
    class FrameTestCanvas : public TestCanvasBase {
    public:
        FrameTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {}
        void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
                const SkPaint* paint, SrcRectConstraint constraint) override {
            mDrawCounter++;
            EXPECT_EQ(kLow_SkFilterQuality, paint->getFilterQuality());
        }
    };

    auto layerNode = TestUtils::createSkiaNode(
            0, 0, LAYER_WIDTH, LAYER_HEIGHT,
            [](RenderProperties& properties, SkiaRecordingCanvas& canvas) {
                canvas.drawPaint(SkPaint());
            });

    layerNode->animatorProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
    layerNode->setLayerSurface(SkSurface::MakeRasterN32Premul(LAYER_WIDTH, LAYER_HEIGHT));

    FrameTestCanvas canvas;
    RenderNodeDrawable drawable(layerNode.get(), &canvas, true);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(1, canvas.mDrawCounter);  //make sure the layer was composed

    // clean up layer pointer, so we can safely destruct RenderNode
    layerNode->setLayerSurface(nullptr);
}

TEST(ReorderBarrierDrawable, testShadowMatrix) {
    static const int CANVAS_WIDTH = 100;
    static const int CANVAS_HEIGHT = 100;
    static const float TRANSLATE_X = 11.0f;
    static const float TRANSLATE_Y = 22.0f;
    static const float CASTER_X = 40.0f;
    static const float CASTER_Y = 40.0f;
    static const float CASTER_WIDTH = 20.0f;
    static const float CASTER_HEIGHT = 20.0f;

    class ShadowTestCanvas : public SkCanvas {
    public:
        ShadowTestCanvas(int width, int height) : SkCanvas(width, height) {}
        int getIndex() { return mDrawCounter; }

        virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
            // expect to draw 2 RenderNodeDrawable, 1 StartReorderBarrierDrawable,
            // 1 EndReorderBarrierDrawable
            mDrawCounter++;
            SkCanvas::onDrawDrawable(drawable, matrix);
        }

        virtual void didTranslate(SkScalar dx, SkScalar dy) override {
            mDrawCounter++;
            EXPECT_EQ(dx, TRANSLATE_X);
            EXPECT_EQ(dy, TRANSLATE_Y);
        }

        virtual void didConcat(const SkMatrix& matrix) override {
            // This function is invoked by EndReorderBarrierDrawable::drawShadow to apply shadow
            // matrix.
            mDrawCounter++;
            EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X, CASTER_Y), matrix);
            EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
                      getTotalMatrix());
        }

    protected:
        int mDrawCounter = 0;
    };

    auto parent = TestUtils::createSkiaNode(
            0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                canvas.translate(TRANSLATE_X, TRANSLATE_Y);
                canvas.insertReorderBarrier(true);

                auto node = TestUtils::createSkiaNode(
                        CASTER_X, CASTER_Y, CASTER_X + CASTER_WIDTH, CASTER_Y + CASTER_HEIGHT,
                        [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                            props.setElevation(42);
                            props.mutableOutline().setRoundRect(0, 0, 20, 20, 5, 1);
                            props.mutableOutline().setShouldClip(true);
                        });
                canvas.drawRenderNode(node.get());
                canvas.insertReorderBarrier(false);
            });

    // create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
    ShadowTestCanvas canvas(CANVAS_WIDTH, CANVAS_HEIGHT);
    RenderNodeDrawable drawable(parent.get(), &canvas, false);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(6, canvas.getIndex());
}

// Draw a vector drawable twice but with different bounds and verify correct bounds are used.
RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaRecordingCanvas, drawVectorDrawable) {
    static const int CANVAS_WIDTH = 100;
    static const int CANVAS_HEIGHT = 200;
    class VectorDrawableTestCanvas : public TestCanvasBase {
    public:
        VectorDrawableTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {}
        void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
                const SkPaint* paint, SrcRectConstraint constraint) override {
            const int index = mDrawCounter++;
            switch (index) {
                case 0:
                    EXPECT_EQ(dst, SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT));
                    break;
                case 1:
                    EXPECT_EQ(dst, SkRect::MakeWH(CANVAS_WIDTH/2, CANVAS_HEIGHT));
                    break;
                default:
                    ADD_FAILURE();
            }
        }
    };

    VectorDrawable::Group* group = new VectorDrawable::Group();
    sp<VectorDrawableRoot> vectorDrawable(new VectorDrawableRoot(group));
    vectorDrawable->mutateStagingProperties()->setScaledSize(CANVAS_WIDTH/10, CANVAS_HEIGHT/10);

    auto node = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
            [&](RenderProperties& props, SkiaRecordingCanvas& canvas) {
                vectorDrawable->mutateStagingProperties()->setBounds(SkRect::MakeWH(CANVAS_WIDTH,
                        CANVAS_HEIGHT));
                canvas.drawVectorDrawable(vectorDrawable.get());
                vectorDrawable->mutateStagingProperties()->setBounds(SkRect::MakeWH(CANVAS_WIDTH/2,
                        CANVAS_HEIGHT));
                canvas.drawVectorDrawable(vectorDrawable.get());
            });

    VectorDrawableTestCanvas canvas;
    RenderNodeDrawable drawable(node.get(), &canvas, true);
    canvas.drawDrawable(&drawable);
    EXPECT_EQ(2, canvas.mDrawCounter);
}
