blob: 68dd5e06e7bbbafdd5bd6ddf637841a8a8401f8f [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
commit-bot@chromium.org8f838252013-05-22 12:35:50 +00008#include "SkBitmap.h"
robertphillips@google.com1f2f3382013-08-29 11:54:56 +00009#include "SkBitmapDevice.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000010#include "SkCanvas.h"
11#include "SkDraw.h"
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000012#include "SkLayerDrawLooper.h"
13#include "SkMatrix.h"
14#include "SkPaint.h"
15#include "SkRect.h"
16#include "SkRefCnt.h"
17#include "SkScalar.h"
18#include "SkXfermode.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000019#include "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
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000027class FakeDevice : public SkBitmapDevice {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000028public:
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000029 FakeDevice() : SkBitmapDevice(make_bm(100, 100)) { }
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000030
skia.committer@gmail.com7f1af502013-07-24 07:01:12 +000031 virtual void drawRect(const SkDraw& draw, const SkRect& r,
commit-bot@chromium.org3e2ea252013-07-23 11:28:45 +000032 const SkPaint& paint) SK_OVERRIDE {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000033 fLastMatrix = *draw.fMatrix;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000034 INHERITED::drawRect(draw, r, paint);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000035 }
36
37 SkMatrix fLastMatrix;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000038
39private:
40 typedef SkBitmapDevice INHERITED;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000041};
42
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000043static void test_frontToBack(skiatest::Reporter* reporter) {
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000044 SkLayerDrawLooper::Builder looperBuilder;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000045 SkLayerDrawLooper::LayerInfo layerInfo;
46
47 // Add the front layer, with the defaults.
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000048 (void)looperBuilder.addLayer(layerInfo);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000049
50 // Add the back layer, with some layer info set.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000051 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000052 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000053 SkPaint* layerPaint = looperBuilder.addLayer(layerInfo);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000054 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
55
56 FakeDevice device;
57 SkCanvas canvas(&device);
58 SkPaint paint;
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000059 SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000060 looper->init(&canvas);
61
62 // The back layer should come first.
63 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
64 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000065 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
66 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
67 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000068 paint.reset();
69
70 // Then the front layer.
71 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
72 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +000073 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
74 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
75 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000076
77 // Only two layers were added, so that should be the end.
78 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
79}
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);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000092 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
93
94 FakeDevice device;
95 SkCanvas canvas(&device);
96 SkPaint paint;
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +000097 SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +000098 looper->init(&canvas);
99
100 // The back layer should come first.
101 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
102 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000103 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
104 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
105 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000106 paint.reset();
107
108 // Then the front layer.
109 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
110 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000111 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
112 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
113 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000114
115 // Only two layers were added, so that should be the end.
116 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
117}
118
119static void test_mixed(skiatest::Reporter* reporter) {
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +0000120 SkLayerDrawLooper::Builder looperBuilder;
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000121 SkLayerDrawLooper::LayerInfo layerInfo;
122
123 // Add the back layer, with the defaults.
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +0000124 (void)looperBuilder.addLayer(layerInfo);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000125
126 // Add the front layer, with some layer info set.
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000127 layerInfo.fOffset.set(10.0f, 20.0f);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000128 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +0000129 SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo);
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000130 layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
131
132 FakeDevice device;
133 SkCanvas canvas(&device);
134 SkPaint paint;
commit-bot@chromium.org74ba2f62014-02-14 10:06:42 +0000135 SkAutoTUnref<SkLayerDrawLooper> looper(looperBuilder.detachLooper());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000136 looper->init(&canvas);
137
138 // The back layer should come first.
139 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
140 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000141 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
142 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
143 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000144 paint.reset();
145
146 // Then the front layer.
147 REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
148 REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000149 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
150 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
151 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000152
153 // Only two layers were added, so that should be the end.
154 REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
155}
156
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000157DEF_TEST(LayerDrawLooper, reporter) {
commit-bot@chromium.org8f838252013-05-22 12:35:50 +0000158 test_frontToBack(reporter);
159 test_backToFront(reporter);
160 test_mixed(reporter);
161}