• 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