blob: 05044a07be778c09799303a9b8b98ae0b866596c [file] [log] [blame]
commit-bot@chromium.org8f838252013-05-22 12:35:50 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
commit-bot@chromium.orgddf94cf2013-10-12 17:25:17 +00007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkBitmap.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkMatrix.h"
11#include "include/core/SkPaint.h"
12#include "include/core/SkRect.h"
13#include "include/core/SkRefCnt.h"
14#include "include/core/SkScalar.h"
15#include "include/effects/SkLayerDrawLooper.h"
Ben Wagner729a23f2019-05-17 16:29:34 -040016#include "src/core/SkArenaAlloc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/core/SkBitmapDevice.h"
18#include "src/core/SkDraw.h"
19#include "tests/Test.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000020
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000021static SkBitmap make_bm(int w, int h) {
22 SkBitmap bm;
23 bm.allocN32Pixels(w, h);
24 return bm;
25}
26
robertphillips9a53fd72015-06-22 09:46:59 -070027// TODO: can this be derived from SkBaseDevice?
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000028class FakeDevice : public SkBitmapDevice {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000029public:
Mike Reed910ca0f2018-04-25 13:04:05 -040030 FakeDevice() : INHERITED(make_bm(100, 100), SkSurfaceProps(0, kUnknown_SkPixelGeometry),
31 nullptr, nullptr) {
robertphillips9a53fd72015-06-22 09:46:59 -070032 }
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000033
Mike Reeda1361362017-03-07 09:37:29 -050034 void drawRect(const SkRect& r, const SkPaint& paint) override {
Michael Ludwigc89d1b52019-10-18 11:32:56 -040035 fLastMatrix = this->localToDevice();
Mike Reeda1361362017-03-07 09:37:29 -050036 this->INHERITED::drawRect(r, paint);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000037 }
38
39 SkMatrix fLastMatrix;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000040
41private:
42 typedef SkBitmapDevice INHERITED;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000043};
44
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000045static void test_frontToBack(skiatest::Reporter* reporter) {
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000046 SkLayerDrawLooper::Builder looperBuilder;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000047 SkLayerDrawLooper::LayerInfo layerInfo;
48
49 // Add the front layer, with the defaults.
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000050 (void)looperBuilder.addLayer(layerInfo);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000051
52 // Add the back layer, with some layer info set.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000053 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000054 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000055 SkPaint* layerPaint = looperBuilder.addLayer(layerInfo);
reed374772b2016-10-05 17:33:02 -070056 layerPaint->setBlendMode(SkBlendMode::kSrc);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000057
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000058 SkPaint paint;
reed7b380d02016-03-21 13:25:16 -070059 auto looper(looperBuilder.detach());
Herb Derby73fe7b02017-02-08 15:12:19 -050060 SkArenaAlloc alloc{48};
Mike Reed59f2e462019-07-25 14:33:59 -040061 SkDrawLooper::Context* context = looper->makeContext(&alloc);
62 SkDrawLooper::Context::Info info;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000063
64 // The back layer should come first.
Mike Reed59f2e462019-07-25 14:33:59 -040065 REPORTER_ASSERT(reporter, context->next(&info, &paint));
reed374772b2016-10-05 17:33:02 -070066 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
Mike Reed59f2e462019-07-25 14:33:59 -040067 REPORTER_ASSERT(reporter, 10.0f == info.fTranslate.fX);
68 REPORTER_ASSERT(reporter, 20.0f == info.fTranslate.fY);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000069 paint.reset();
70
71 // Then the front layer.
Mike Reed59f2e462019-07-25 14:33:59 -040072 REPORTER_ASSERT(reporter, context->next(&info, &paint));
reed374772b2016-10-05 17:33:02 -070073 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
Mike Reed59f2e462019-07-25 14:33:59 -040074 REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fX);
75 REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fY);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000076
77 // Only two layers were added, so that should be the end.
Mike Reed59f2e462019-07-25 14:33:59 -040078 REPORTER_ASSERT(reporter, !context->next(&info, &paint));
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000079}
80
81static void test_backToFront(skiatest::Reporter* reporter) {
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000082 SkLayerDrawLooper::Builder looperBuilder;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000083 SkLayerDrawLooper::LayerInfo layerInfo;
84
85 // Add the back layer, with the defaults.
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000086 (void)looperBuilder.addLayerOnTop(layerInfo);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000087
88 // Add the front layer, with some layer info set.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000089 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000090 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000091 SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
reed374772b2016-10-05 17:33:02 -070092 layerPaint->setBlendMode(SkBlendMode::kSrc);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000093
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000094 SkPaint paint;
reed7b380d02016-03-21 13:25:16 -070095 auto looper(looperBuilder.detach());
Herb Derby73fe7b02017-02-08 15:12:19 -050096 SkArenaAlloc alloc{48};
Mike Reed59f2e462019-07-25 14:33:59 -040097 SkDrawLooper::Context* context = looper->makeContext(&alloc);
98 SkDrawLooper::Context::Info info;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000099
100 // The back layer should come first.
Mike Reed59f2e462019-07-25 14:33:59 -0400101 REPORTER_ASSERT(reporter, context->next(&info, &paint));
reed374772b2016-10-05 17:33:02 -0700102 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
Mike Reed59f2e462019-07-25 14:33:59 -0400103 REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fX);
104 REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fY);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000105 paint.reset();
106
107 // Then the front layer.
Mike Reed59f2e462019-07-25 14:33:59 -0400108 REPORTER_ASSERT(reporter, context->next(&info, &paint));
reed374772b2016-10-05 17:33:02 -0700109 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
Mike Reed59f2e462019-07-25 14:33:59 -0400110 REPORTER_ASSERT(reporter, 10.0f == info.fTranslate.fX);
111 REPORTER_ASSERT(reporter, 20.0f == info.fTranslate.fY);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000112
113 // Only two layers were added, so that should be the end.
Mike Reed59f2e462019-07-25 14:33:59 -0400114 REPORTER_ASSERT(reporter, !context->next(&info, &paint));
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000115}
116
117static void test_mixed(skiatest::Reporter* reporter) {
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +0000118 SkLayerDrawLooper::Builder looperBuilder;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000119 SkLayerDrawLooper::LayerInfo layerInfo;
120
121 // Add the back layer, with the defaults.
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +0000122 (void)looperBuilder.addLayer(layerInfo);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000123
124 // Add the front layer, with some layer info set.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000125 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000126 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +0000127 SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
reed374772b2016-10-05 17:33:02 -0700128 layerPaint->setBlendMode(SkBlendMode::kSrc);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000129
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000130 SkPaint paint;
reed7b380d02016-03-21 13:25:16 -0700131 sk_sp<SkDrawLooper> looper(looperBuilder.detach());
Herb Derby73fe7b02017-02-08 15:12:19 -0500132 SkArenaAlloc alloc{48};
Mike Reed59f2e462019-07-25 14:33:59 -0400133 SkDrawLooper::Context* context = looper->makeContext(&alloc);
134 SkDrawLooper::Context::Info info;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000135
136 // The back layer should come first.
Mike Reed59f2e462019-07-25 14:33:59 -0400137 REPORTER_ASSERT(reporter, context->next(&info, &paint));
reed374772b2016-10-05 17:33:02 -0700138 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
Mike Reed59f2e462019-07-25 14:33:59 -0400139 REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fX);
140 REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fY);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000141 paint.reset();
142
143 // Then the front layer.
Mike Reed59f2e462019-07-25 14:33:59 -0400144 REPORTER_ASSERT(reporter, context->next(&info, &paint));
reed374772b2016-10-05 17:33:02 -0700145 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
Mike Reed59f2e462019-07-25 14:33:59 -0400146 REPORTER_ASSERT(reporter, 10.0f == info.fTranslate.fX);
147 REPORTER_ASSERT(reporter, 20.0f == info.fTranslate.fY);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000148
149 // Only two layers were added, so that should be the end.
Mike Reed59f2e462019-07-25 14:33:59 -0400150 REPORTER_ASSERT(reporter, !context->next(&info, &paint));
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000151}
152
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000153DEF_TEST(LayerDrawLooper, reporter) {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000154 test_frontToBack(reporter);
155 test_backToFront(reporter);
156 test_mixed(reporter);
157}