• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
7 
8 #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"
16 #include "src/core/SkArenaAlloc.h"
17 #include "src/core/SkBitmapDevice.h"
18 #include "src/core/SkDraw.h"
19 #include "tests/Test.h"
20 
make_bm(int w,int h)21 static SkBitmap make_bm(int w, int h) {
22     SkBitmap bm;
23     bm.allocN32Pixels(w, h);
24     return bm;
25 }
26 
27 // TODO: can this be derived from SkBaseDevice?
28 class FakeDevice : public SkBitmapDevice {
29 public:
FakeDevice()30     FakeDevice() : INHERITED(make_bm(100, 100), SkSurfaceProps(0, kUnknown_SkPixelGeometry),
31                              nullptr, nullptr) {
32     }
33 
drawRect(const SkRect & r,const SkPaint & paint)34     void drawRect(const SkRect& r, const SkPaint& paint) override {
35         fLastMatrix = this->ctm();
36         this->INHERITED::drawRect(r, paint);
37     }
38 
39     SkMatrix fLastMatrix;
40 
41 private:
42     typedef SkBitmapDevice INHERITED;
43 };
44 
test_frontToBack(skiatest::Reporter * reporter)45 static void test_frontToBack(skiatest::Reporter* reporter) {
46     SkLayerDrawLooper::Builder looperBuilder;
47     SkLayerDrawLooper::LayerInfo layerInfo;
48 
49     // Add the front layer, with the defaults.
50     (void)looperBuilder.addLayer(layerInfo);
51 
52     // Add the back layer, with some layer info set.
53     layerInfo.fOffset.set(10.0f, 20.0f);
54     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
55     SkPaint* layerPaint = looperBuilder.addLayer(layerInfo);
56     layerPaint->setBlendMode(SkBlendMode::kSrc);
57 
58     SkPaint paint;
59     auto looper(looperBuilder.detach());
60     SkArenaAlloc alloc{48};
61     SkDrawLooper::Context* context = looper->makeContext(&alloc);
62     SkDrawLooper::Context::Info info;
63 
64     // The back layer should come first.
65     REPORTER_ASSERT(reporter, context->next(&info, &paint));
66     REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
67     REPORTER_ASSERT(reporter, 10.0f == info.fTranslate.fX);
68     REPORTER_ASSERT(reporter, 20.0f == info.fTranslate.fY);
69     paint.reset();
70 
71     // Then the front layer.
72     REPORTER_ASSERT(reporter, context->next(&info, &paint));
73     REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
74     REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fX);
75     REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fY);
76 
77     // Only two layers were added, so that should be the end.
78     REPORTER_ASSERT(reporter, !context->next(&info, &paint));
79 }
80 
test_backToFront(skiatest::Reporter * reporter)81 static void test_backToFront(skiatest::Reporter* reporter) {
82     SkLayerDrawLooper::Builder looperBuilder;
83     SkLayerDrawLooper::LayerInfo layerInfo;
84 
85     // Add the back layer, with the defaults.
86     (void)looperBuilder.addLayerOnTop(layerInfo);
87 
88     // Add the front layer, with some layer info set.
89     layerInfo.fOffset.set(10.0f, 20.0f);
90     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
91     SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
92     layerPaint->setBlendMode(SkBlendMode::kSrc);
93 
94     SkPaint paint;
95     auto looper(looperBuilder.detach());
96     SkArenaAlloc alloc{48};
97     SkDrawLooper::Context* context = looper->makeContext(&alloc);
98     SkDrawLooper::Context::Info info;
99 
100     // The back layer should come first.
101     REPORTER_ASSERT(reporter, context->next(&info, &paint));
102     REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
103     REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fX);
104     REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fY);
105     paint.reset();
106 
107     // Then the front layer.
108     REPORTER_ASSERT(reporter, context->next(&info, &paint));
109     REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
110     REPORTER_ASSERT(reporter, 10.0f == info.fTranslate.fX);
111     REPORTER_ASSERT(reporter, 20.0f == info.fTranslate.fY);
112 
113     // Only two layers were added, so that should be the end.
114     REPORTER_ASSERT(reporter, !context->next(&info, &paint));
115 }
116 
test_mixed(skiatest::Reporter * reporter)117 static void test_mixed(skiatest::Reporter* reporter) {
118     SkLayerDrawLooper::Builder looperBuilder;
119     SkLayerDrawLooper::LayerInfo layerInfo;
120 
121     // Add the back layer, with the defaults.
122     (void)looperBuilder.addLayer(layerInfo);
123 
124     // Add the front layer, with some layer info set.
125     layerInfo.fOffset.set(10.0f, 20.0f);
126     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
127     SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
128     layerPaint->setBlendMode(SkBlendMode::kSrc);
129 
130     SkPaint paint;
131     sk_sp<SkDrawLooper> looper(looperBuilder.detach());
132     SkArenaAlloc alloc{48};
133     SkDrawLooper::Context* context = looper->makeContext(&alloc);
134     SkDrawLooper::Context::Info info;
135 
136     // The back layer should come first.
137     REPORTER_ASSERT(reporter, context->next(&info, &paint));
138     REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver);
139     REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fX);
140     REPORTER_ASSERT(reporter, 0.0f == info.fTranslate.fY);
141     paint.reset();
142 
143     // Then the front layer.
144     REPORTER_ASSERT(reporter, context->next(&info, &paint));
145     REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc);
146     REPORTER_ASSERT(reporter, 10.0f == info.fTranslate.fX);
147     REPORTER_ASSERT(reporter, 20.0f == info.fTranslate.fY);
148 
149     // Only two layers were added, so that should be the end.
150     REPORTER_ASSERT(reporter, !context->next(&info, &paint));
151 }
152 
DEF_TEST(LayerDrawLooper,reporter)153 DEF_TEST(LayerDrawLooper, reporter) {
154     test_frontToBack(reporter);
155     test_backToFront(reporter);
156     test_mixed(reporter);
157 }
158