LayerDrawLooperTest.cpp revision 84b18c7e3e042bf206e1ace3d1b6ea5bb929fe51
18f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org/*
28f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org * Copyright 2013 Google Inc.
38f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org *
48f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
58f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org * found in the LICENSE file.
68f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org */
7ddf94cf108ae430877f009bd67b9070341426947commit-bot@chromium.org
88f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkBitmap.h"
91f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com#include "SkBitmapDevice.h"
108f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkCanvas.h"
118f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkDraw.h"
128f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkLayerDrawLooper.h"
138f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkMatrix.h"
148f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkPaint.h"
158f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkRect.h"
168f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkRefCnt.h"
178f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkScalar.h"
1879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h"
198f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org#include "SkXfermode.h"
208f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
218f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
2215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgstatic SkBitmap make_bm(int w, int h) {
2315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    SkBitmap bm;
2415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    bm.allocN32Pixels(w, h);
2515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    return bm;
2615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org}
2715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org
281f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comclass FakeDevice : public SkBitmapDevice {
298f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgpublic:
3015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org    FakeDevice() : SkBitmapDevice(make_bm(100, 100)) { }
318f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
327f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com    virtual void drawRect(const SkDraw& draw, const SkRect& r,
333e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                          const SkPaint& paint) SK_OVERRIDE {
348f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org        fLastMatrix = *draw.fMatrix;
3584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com        this->INHERITED::drawRect(draw, r, paint);
368f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    }
378f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
388f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkMatrix fLastMatrix;
391f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com
401f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comprivate:
411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    typedef SkBitmapDevice INHERITED;
428f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org};
438f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
448f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgstatic void test_frontToBack(skiatest::Reporter* reporter) {
4574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkLayerDrawLooper::Builder looperBuilder;
468f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkLayerDrawLooper::LayerInfo layerInfo;
478f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
488f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Add the front layer, with the defaults.
4974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    (void)looperBuilder.addLayer(layerInfo);
508f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
518f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Add the back layer, with some layer info set.
524b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    layerInfo.fOffset.set(10.0f, 20.0f);
538f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
5474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkPaint* layerPaint = looperBuilder.addLayer(layerInfo);
558f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
568f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
578f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    FakeDevice device;
588f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkCanvas canvas(&device);
598f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkPaint paint;
6074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
6179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkSmallAllocator<1, 32> allocator;
6279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize());
6379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkDrawLooper::Context* context = looper->createContext(&canvas, buffer);
648f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
658f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // The back layer should come first.
6679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
678f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
684b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
694b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
704b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
718f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    paint.reset();
728f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
738f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Then the front layer.
7479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
758f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
764b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
774b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
784b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
798f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
808f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Only two layers were added, so that should be the end.
8179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, !context->next(&canvas, &paint));
828f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org}
838f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
848f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgstatic void test_backToFront(skiatest::Reporter* reporter) {
8574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkLayerDrawLooper::Builder looperBuilder;
868f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkLayerDrawLooper::LayerInfo layerInfo;
878f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
888f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Add the back layer, with the defaults.
8974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    (void)looperBuilder.addLayerOnTop(layerInfo);
908f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
918f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Add the front layer, with some layer info set.
924b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    layerInfo.fOffset.set(10.0f, 20.0f);
938f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
9474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
958f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
968f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
978f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    FakeDevice device;
988f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkCanvas canvas(&device);
998f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkPaint paint;
10074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
10179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkSmallAllocator<1, 32> allocator;
10279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize());
10379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkDrawLooper::Context* context = looper->createContext(&canvas, buffer);
1048f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1058f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // The back layer should come first.
10679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
1078f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
1084b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
1094b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
1104b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
1118f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    paint.reset();
1128f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1138f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Then the front layer.
11479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
1158f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
1164b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
1174b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
1184b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
1198f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1208f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Only two layers were added, so that should be the end.
12179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, !context->next(&canvas, &paint));
1228f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org}
1238f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1248f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.orgstatic void test_mixed(skiatest::Reporter* reporter) {
12574ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkLayerDrawLooper::Builder looperBuilder;
1268f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkLayerDrawLooper::LayerInfo layerInfo;
1278f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1288f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Add the back layer, with the defaults.
12974ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    (void)looperBuilder.addLayer(layerInfo);
1308f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1318f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Add the front layer, with some layer info set.
1324b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    layerInfo.fOffset.set(10.0f, 20.0f);
1338f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
13474ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
1358f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
1368f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1378f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    FakeDevice device;
1388f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkCanvas canvas(&device);
1398f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    SkPaint paint;
14074ba2f62dce1998bd6555291ab0a5330c276301dcommit-bot@chromium.org    SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
14179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkSmallAllocator<1, 32> allocator;
14279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    void* buffer = allocator.reserveT<SkDrawLooper::Context>(looper->contextSize());
14379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    SkDrawLooper::Context* context = looper->createContext(&canvas, buffer);
1448f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1458f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // The back layer should come first.
14679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
1478f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
1484b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
1494b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
1504b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
1518f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    paint.reset();
1528f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1538f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Then the front layer.
15479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, context->next(&canvas, &paint));
1558f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
1564b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
1574b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
1584b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
1598f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
1608f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    // Only two layers were added, so that should be the end.
16179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org    REPORTER_ASSERT(reporter, !context->next(&canvas, &paint));
1628f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org}
1638f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org
164e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(LayerDrawLooper, reporter) {
1658f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    test_frontToBack(reporter);
1668f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    test_backToFront(reporter);
1678f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org    test_mixed(reporter);
1688f838259ab65e44562902679fa88cb00575b99cecommit-bot@chromium.org}
169