/*
 * 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 <SkSurface_Base.h>
#include <string.h>
#include "AnimationContext.h"
#include "DamageAccumulator.h"
#include "FatalTestCanvas.h"
#include "IContextFactory.h"
#include "RecordingCanvas.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"
#include "utils/Color.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);
            });

    DisplayListData skLiteDL;
    RecordingCanvas 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(const SkIRect* bounds) 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);
    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 getDrawCounter() { 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 didSetMatrix(const SkMatrix& matrix) override {
            mDrawCounter++;
            // First invocation is EndReorderBarrierDrawable::drawShadow to apply shadow matrix.
            // Second invocation is preparing the matrix for an elevated RenderNodeDrawable.
            EXPECT_TRUE(matrix.isIdentity());
            EXPECT_TRUE(getTotalMatrix().isIdentity());
        }

        virtual void didConcat(const SkMatrix& matrix) override {
            mDrawCounter++;
            if (mFirstDidConcat) {
                // First invocation is EndReorderBarrierDrawable::drawShadow to apply shadow matrix.
                mFirstDidConcat = false;
                EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
                          matrix);
                EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y),
                          getTotalMatrix());
            } else {
                // Second invocation is preparing the matrix for an elevated RenderNodeDrawable.
                EXPECT_EQ(SkMatrix::MakeTrans(TRANSLATE_X, TRANSLATE_Y),
                          matrix);
                EXPECT_EQ(SkMatrix::MakeTrans(TRANSLATE_X, TRANSLATE_Y),
                          getTotalMatrix());
            }
        }

    protected:
        int mDrawCounter = 0;
    private:
        bool mFirstDidConcat = true;
    };

    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(9, canvas.getDrawCounter());
}

// 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);
}
