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

Commit dfe8976b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add more canvas ops 5"

parents 0c37dac1 da9248ce
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -50,7 +50,11 @@ enum class CanvasOpType : int8_t {
    DrawPath,
    DrawPath,
    DrawLine,
    DrawLine,
    DrawVertices,
    DrawVertices,

    DrawImage,
    DrawImageRect,
    // DrawImageLattice also used to draw 9 patches
    DrawImageLattice,
    DrawPicture,


    // TODO: Rest
    // TODO: Rest


+95 −0
Original line number Original line Diff line number Diff line
@@ -21,12 +21,16 @@
#include <SkPath.h>
#include <SkPath.h>
#include <SkRegion.h>
#include <SkRegion.h>
#include <SkVertices.h>
#include <SkVertices.h>
#include <SkImage.h>
#include <SkPicture.h>
#include <hwui/Bitmap.h>
#include <log/log.h>
#include <log/log.h>
#include "CanvasProperty.h"
#include "CanvasProperty.h"


#include "CanvasOpTypes.h"
#include "CanvasOpTypes.h"


#include <experimental/type_traits>
#include <experimental/type_traits>
#include <utility>


namespace android::uirenderer {
namespace android::uirenderer {


@@ -269,6 +273,97 @@ struct CanvasOp<CanvasOpType::DrawVertices> {
    ASSERT_DRAWABLE()
    ASSERT_DRAWABLE()
};
};


template<>
struct CanvasOp<CanvasOpType::DrawImage> {

    CanvasOp<CanvasOpType::DrawImageRect>(
        const sk_sp<Bitmap>& bitmap,
        float left,
        float top,
        SkPaint paint
    ) : left(left),
        top(top),
        paint(std::move(paint)),
        bitmap(bitmap),
        image(bitmap->makeImage()) { }

    float left;
    float top;
    SkPaint paint;
    sk_sp<Bitmap> bitmap;
    sk_sp<SkImage> image;

    void draw(SkCanvas* canvas) const {
        canvas->drawImage(image, left, top, &paint);
    }
    ASSERT_DRAWABLE()
};

template<>
struct CanvasOp<CanvasOpType::DrawImageRect> {

    CanvasOp<CanvasOpType::DrawImageRect>(
        const sk_sp<Bitmap>& bitmap,
        SkRect src,
        SkRect dst,
        SkPaint paint
    ) : src(src),
        dst(dst),
        paint(std::move(paint)),
        bitmap(bitmap),
        image(bitmap->makeImage()) { }

    SkRect src;
    SkRect dst;
    SkPaint paint;
    sk_sp<Bitmap> bitmap;
    sk_sp<SkImage> image;

    void draw(SkCanvas* canvas) const {
        canvas->drawImageRect(image,
                src,
                dst,
                &paint,
                SkCanvas::kFast_SrcRectConstraint
        );
    }
    ASSERT_DRAWABLE()
};

template<>
struct CanvasOp<CanvasOpType::DrawImageLattice> {

    CanvasOp<CanvasOpType::DrawImageLattice>(
        const sk_sp<Bitmap>& bitmap,
        SkRect dst,
        SkCanvas::Lattice lattice,
        SkPaint  paint
    ):  dst(dst),
        lattice(lattice),
        bitmap(bitmap),
        image(bitmap->makeImage()),
        paint(std::move(paint)) {}

    SkRect dst;
    SkCanvas::Lattice lattice;
    const sk_sp<Bitmap> bitmap;
    const sk_sp<SkImage> image;

    SkPaint paint;
    void draw(SkCanvas* canvas) const {
        canvas->drawImageLattice(image.get(), lattice, dst, &paint);
    }
    ASSERT_DRAWABLE()
};

template<>
struct CanvasOp<CanvasOpType::DrawPicture> {
    sk_sp<SkPicture> picture;
    void draw(SkCanvas* canvas) const {
        picture->playback(canvas);
    }
};

// cleanup our macros
// cleanup our macros
#undef ASSERT_DRAWABLE
#undef ASSERT_DRAWABLE


+121 −15
Original line number Original line Diff line number Diff line
@@ -22,7 +22,9 @@


#include <tests/common/CallCountingCanvas.h>
#include <tests/common/CallCountingCanvas.h>


#include "SkPictureRecorder.h"
#include "SkColor.h"
#include "SkColor.h"
#include "SkLatticeIter.h"
#include "pipeline/skia/AnimatedDrawables.h"
#include "pipeline/skia/AnimatedDrawables.h"


using namespace android;
using namespace android;
@@ -198,7 +200,7 @@ TEST(CanvasOp, simplePush) {
TEST(CanvasOp, simpleDrawPaint) {
TEST(CanvasOp, simpleDrawPaint) {
    CanvasOpBuffer buffer;
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    buffer.push(CanvasOp<Op::DrawColor> {
    buffer.push<Op::DrawColor> ({
        .color = SkColor4f{1, 1, 1, 1},
        .color = SkColor4f{1, 1, 1, 1},
        .mode = SkBlendMode::kSrcIn
        .mode = SkBlendMode::kSrcIn
    });
    });
@@ -213,7 +215,7 @@ TEST(CanvasOp, simpleDrawPaint) {
TEST(CanvasOp, simpleDrawPoint) {
TEST(CanvasOp, simpleDrawPoint) {
    CanvasOpBuffer buffer;
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    buffer.push(CanvasOp<Op::DrawPoint> {
    buffer.push<Op::DrawPoint> ({
        .x = 12,
        .x = 12,
        .y = 42,
        .y = 42,
        .paint = SkPaint{}
        .paint = SkPaint{}
@@ -229,7 +231,7 @@ TEST(CanvasOp, simpleDrawPoint) {
TEST(CanvasOp, simpleDrawLine) {
TEST(CanvasOp, simpleDrawLine) {
    CanvasOpBuffer buffer;
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    buffer.push(CanvasOp<Op::DrawLine> {
    buffer.push<Op::DrawLine> ({
        .startX = 16,
        .startX = 16,
        .startY = 28,
        .startY = 28,
        .endX = 12,
        .endX = 12,
@@ -247,7 +249,7 @@ TEST(CanvasOp, simpleDrawLine) {
TEST(CanvasOp, simpleDrawRect) {
TEST(CanvasOp, simpleDrawRect) {
    CanvasOpBuffer buffer;
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    buffer.push(CanvasOp<Op::DrawRect> {
    buffer.push<Op::DrawRect> ({
        .paint = SkPaint{},
        .paint = SkPaint{},
        .rect = SkRect::MakeEmpty()
        .rect = SkRect::MakeEmpty()
    });
    });
@@ -264,7 +266,7 @@ TEST(CanvasOp, simpleDrawRegionRect) {
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    SkRegion region;
    SkRegion region;
    region.setRect(SkIRect::MakeWH(12, 50));
    region.setRect(SkIRect::MakeWH(12, 50));
    buffer.push(CanvasOp<Op::DrawRegion> {
    buffer.push<Op::DrawRegion> ({
        .paint = SkPaint{},
        .paint = SkPaint{},
        .region = region
        .region = region
    });
    });
@@ -286,7 +288,7 @@ TEST(CanvasOp, simpleDrawRegionPath) {
    clip.setRect(SkIRect::MakeWH(100, 100));
    clip.setRect(SkIRect::MakeWH(100, 100));
    SkRegion region;
    SkRegion region;
    region.setPath(path, clip);
    region.setPath(path, clip);
    buffer.push(CanvasOp<Op::DrawRegion> {
    buffer.push<Op::DrawRegion> ({
        .paint = SkPaint{},
        .paint = SkPaint{},
        .region = region
        .region = region
    });
    });
@@ -301,7 +303,7 @@ TEST(CanvasOp, simpleDrawRegionPath) {
TEST(CanvasOp, simpleDrawRoundRect) {
TEST(CanvasOp, simpleDrawRoundRect) {
    CanvasOpBuffer buffer;
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    buffer.push(CanvasOp<Op::DrawRoundRect> {
    buffer.push<Op::DrawRoundRect> ({
        .paint = SkPaint{},
        .paint = SkPaint{},
        .rect = SkRect::MakeEmpty(),
        .rect = SkRect::MakeEmpty(),
        .rx = 10,
        .rx = 10,
@@ -340,7 +342,7 @@ TEST(CanvasOp, simpleDrawDoubleRoundRect) {
    innerPts[3].set(10, 10);
    innerPts[3].set(10, 10);
    innerRRect.setRectRadii(inner, innerPts.get());
    innerRRect.setRectRadii(inner, innerPts.get());


    buffer.push(CanvasOp<Op::DrawDoubleRoundRect> {
    buffer.push<Op::DrawDoubleRoundRect> ({
        .outer = outerRRect,
        .outer = outerRRect,
        .inner = innerRRect,
        .inner = innerRRect,
        .paint = SkPaint{}
        .paint = SkPaint{}
@@ -356,7 +358,7 @@ TEST(CanvasOp, simpleDrawDoubleRoundRect) {
TEST(CanvasOp, simpleDrawCircle) {
TEST(CanvasOp, simpleDrawCircle) {
    CanvasOpBuffer buffer;
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    buffer.push(CanvasOp<Op::DrawCircle> {
    buffer.push<Op::DrawCircle>({
        .cx = 5,
        .cx = 5,
        .cy = 7,
        .cy = 7,
        .radius = 10,
        .radius = 10,
@@ -373,7 +375,7 @@ TEST(CanvasOp, simpleDrawCircle) {
TEST(CanvasOp, simpleDrawOval) {
TEST(CanvasOp, simpleDrawOval) {
    CanvasOpBuffer buffer;
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    buffer.push(CanvasOp<Op::DrawOval> {
    buffer.push<Op::DrawOval> ({
        .oval = SkRect::MakeEmpty(),
        .oval = SkRect::MakeEmpty(),
        .paint = SkPaint{}
        .paint = SkPaint{}
    });
    });
@@ -388,7 +390,7 @@ TEST(CanvasOp, simpleDrawOval) {
TEST(CanvasOp, simpleDrawArc) {
TEST(CanvasOp, simpleDrawArc) {
    CanvasOpBuffer buffer;
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    buffer.push(CanvasOp<Op::DrawArc> {
    buffer.push<Op::DrawArc>({
        .oval = SkRect::MakeWH(100, 100),
        .oval = SkRect::MakeWH(100, 100),
        .startAngle = 120,
        .startAngle = 120,
        .sweepAngle = 70,
        .sweepAngle = 70,
@@ -408,7 +410,7 @@ TEST(CanvasOp, simpleDrawPath) {
    EXPECT_EQ(buffer.size(), 0);
    EXPECT_EQ(buffer.size(), 0);
    SkPath path;
    SkPath path;
    path.addCircle(50, 50, 30);
    path.addCircle(50, 50, 30);
    buffer.push(CanvasOp<Op::DrawPath> {
    buffer.push<Op::DrawPath> ({
        .path = path,
        .path = path,
        .paint = SkPaint{}
        .paint = SkPaint{}
    });
    });
@@ -433,7 +435,7 @@ TEST(CanvasOp, simpleDrawRoundRectProperty) {
    auto propertyPaint =
    auto propertyPaint =
            sp<uirenderer::CanvasPropertyPaint>(new uirenderer::CanvasPropertyPaint(SkPaint{}));
            sp<uirenderer::CanvasPropertyPaint>(new uirenderer::CanvasPropertyPaint(SkPaint{}));


    buffer.push(CanvasOp<Op::DrawRoundRectProperty> {
    buffer.push<Op::DrawRoundRectProperty> ({
        .left = left,
        .left = left,
        .top = top,
        .top = top,
        .right = right,
        .right = right,
@@ -460,7 +462,7 @@ TEST(CanvasOp, simpleDrawCircleProperty) {
    auto propertyPaint =
    auto propertyPaint =
            sp<uirenderer::CanvasPropertyPaint>(new uirenderer::CanvasPropertyPaint(SkPaint{}));
            sp<uirenderer::CanvasPropertyPaint>(new uirenderer::CanvasPropertyPaint(SkPaint{}));


    buffer.push(CanvasOp<Op::DrawCircleProperty> {
    buffer.push<Op::DrawCircleProperty> ({
        .x = x,
        .x = x,
        .y = y,
        .y = y,
        .radius = radius,
        .radius = radius,
@@ -482,7 +484,7 @@ TEST(CanvasOp, simpleDrawVertices) {
    SkColor colors[3] = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN};
    SkColor colors[3] = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN};
    sk_sp<SkVertices> vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts,
    sk_sp<SkVertices> vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts,
            nullptr, colors);
            nullptr, colors);
    buffer.push(CanvasOp<Op::DrawVertices> {
    buffer.push<Op::DrawVertices> ({
        .vertices = vertices,
        .vertices = vertices,
        .mode = SkBlendMode::kSrcOver,
        .mode = SkBlendMode::kSrcOver,
        .paint = SkPaint{}
        .paint = SkPaint{}
@@ -495,6 +497,110 @@ TEST(CanvasOp, simpleDrawVertices) {
    EXPECT_EQ(1, canvas.sumTotalDrawCalls());
    EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}
}


TEST(CanvasOp, simpleDrawImage) {
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);

    SkImageInfo info =SkImageInfo::Make(5, 1,
        kGray_8_SkColorType, kOpaque_SkAlphaType);
    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(info);
    buffer.push<Op::DrawImage> ({
            bitmap,
            7,
            19,
            SkPaint{}
        }
    );

    CallCountingCanvas canvas;
    EXPECT_EQ(0, canvas.sumTotalDrawCalls());
    rasterizeCanvasBuffer(buffer, &canvas);
    EXPECT_EQ(1, canvas.drawImageCount);
    EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}

TEST(CanvasOp, simpleDrawImageRect) {
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);

    SkImageInfo info = SkImageInfo::Make(5, 1,
        kGray_8_SkColorType, kOpaque_SkAlphaType);

    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(info);
    buffer.push<Op::DrawImageRect> ({
          bitmap, SkRect::MakeWH(100, 100),
          SkRect::MakeLTRB(120, 110, 220, 210),
          SkPaint{}
        }
    );

    CallCountingCanvas canvas;
    EXPECT_EQ(0, canvas.sumTotalDrawCalls());
    rasterizeCanvasBuffer(buffer, &canvas);
    EXPECT_EQ(1, canvas.drawImageRectCount);
    EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}

TEST(CanvasOp, simpleDrawImageLattice) {
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);

    SkBitmap skBitmap;
    skBitmap.allocPixels(SkImageInfo::MakeN32Premul(60, 60));

    const int xDivs[] = { 20, 50 };
    const int yDivs[] = { 10, 40 };
    SkCanvas::Lattice::RectType fillTypes[3][3];
    memset(fillTypes, 0, sizeof(fillTypes));
    fillTypes[1][1] = SkCanvas::Lattice::kTransparent;
    SkColor colors[9];
    SkCanvas::Lattice lattice = { xDivs, yDivs, fillTypes[0], 2,
         2, nullptr, colors };
    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(&skBitmap);
    buffer.push<Op::DrawImageLattice>(
        {
            bitmap,
            SkRect::MakeWH(5, 1),
            lattice,
            SkPaint{}
        }
    );

    CallCountingCanvas canvas;
    EXPECT_EQ(0, canvas.sumTotalDrawCalls());
    rasterizeCanvasBuffer(buffer, &canvas);
    EXPECT_EQ(1, canvas.drawImageLatticeCount);
    EXPECT_EQ(1, canvas.sumTotalDrawCalls());
}

TEST(CanvasOp, simpleDrawPicture) {
    CanvasOpBuffer buffer;
    EXPECT_EQ(buffer.size(), 0);

    SkPictureRecorder recorder;
    SkCanvas* pictureCanvas = recorder.beginRecording({64, 64, 192, 192});
    SkPaint paint;
    pictureCanvas->drawRect(SkRect::MakeWH(200, 200), paint);
    paint.setColor(SK_ColorWHITE);
    pictureCanvas->drawRect(SkRect::MakeLTRB(20, 20, 180, 180), paint);
    sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
    buffer.push<Op::DrawPicture> ({
        .picture = picture
    });

    CallCountingCanvas canvas;
    EXPECT_EQ(0, canvas.sumTotalDrawCalls());
    rasterizeCanvasBuffer(buffer, &canvas);
    // Note because we are explicitly issuing 2 drawRect calls
    // in the picture recorder above, when it is played back into
    // CallCountingCanvas we will see 2 calls to drawRect instead of 1
    // call to drawPicture.
    // This is because SkiaCanvas::drawPicture uses picture.playback(canvas)
    // instead of canvas->drawPicture.
    EXPECT_EQ(2, canvas.drawRectCount);
    EXPECT_EQ(2, canvas.sumTotalDrawCalls());
}

TEST(CanvasOp, immediateRendering) {
TEST(CanvasOp, immediateRendering) {
    auto canvas = std::make_shared<CallCountingCanvas>();
    auto canvas = std::make_shared<CallCountingCanvas>();