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 "SkArenaAlloc.h" 9 #include "SkBitmap.h" 10 #include "SkBitmapDevice.h" 11 #include "SkCanvas.h" 12 #include "SkDraw.h" 13 #include "SkLayerDrawLooper.h" 14 #include "SkMatrix.h" 15 #include "SkPaint.h" 16 #include "SkRect.h" 17 #include "SkRefCnt.h" 18 #include "SkScalar.h" 19 #include "Test.h" 20 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: 30 FakeDevice() : INHERITED(make_bm(100, 100), SkSurfaceProps(0, kUnknown_SkPixelGeometry)) { 31 } 32 33 void drawRect(const SkRect& r, const SkPaint& paint) override { 34 fLastMatrix = this->ctm(); 35 this->INHERITED::drawRect(r, paint); 36 } 37 38 SkMatrix fLastMatrix; 39 40 private: 41 typedef SkBitmapDevice INHERITED; 42 }; 43 44 static void test_frontToBack(skiatest::Reporter* reporter) { 45 SkLayerDrawLooper::Builder looperBuilder; 46 SkLayerDrawLooper::LayerInfo layerInfo; 47 48 // Add the front layer, with the defaults. 49 (void)looperBuilder.addLayer(layerInfo); 50 51 // Add the back layer, with some layer info set. 52 layerInfo.fOffset.set(10.0f, 20.0f); 53 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 54 SkPaint* layerPaint = looperBuilder.addLayer(layerInfo); 55 layerPaint->setBlendMode(SkBlendMode::kSrc); 56 57 FakeDevice device; 58 SkCanvas canvas(&device); 59 SkPaint paint; 60 auto looper(looperBuilder.detach()); 61 SkArenaAlloc alloc{48}; 62 SkDrawLooper::Context* context = looper->makeContext(&canvas, &alloc); 63 64 // The back layer should come first. 65 REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 66 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc); 67 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 68 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 69 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 70 paint.reset(); 71 72 // Then the front layer. 73 REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 74 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver); 75 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 76 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 77 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 78 79 // Only two layers were added, so that should be the end. 80 REPORTER_ASSERT(reporter, !context->next(&canvas, &paint)); 81 } 82 83 static void test_backToFront(skiatest::Reporter* reporter) { 84 SkLayerDrawLooper::Builder looperBuilder; 85 SkLayerDrawLooper::LayerInfo layerInfo; 86 87 // Add the back layer, with the defaults. 88 (void)looperBuilder.addLayerOnTop(layerInfo); 89 90 // Add the front layer, with some layer info set. 91 layerInfo.fOffset.set(10.0f, 20.0f); 92 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 93 SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo); 94 layerPaint->setBlendMode(SkBlendMode::kSrc); 95 96 FakeDevice device; 97 SkCanvas canvas(&device); 98 SkPaint paint; 99 auto looper(looperBuilder.detach()); 100 SkArenaAlloc alloc{48}; 101 SkDrawLooper::Context* context = looper->makeContext(&canvas, &alloc); 102 103 // The back layer should come first. 104 REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 105 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver); 106 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 107 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 108 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 109 paint.reset(); 110 111 // Then the front layer. 112 REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 113 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc); 114 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 115 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 116 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 117 118 // Only two layers were added, so that should be the end. 119 REPORTER_ASSERT(reporter, !context->next(&canvas, &paint)); 120 } 121 122 static void test_mixed(skiatest::Reporter* reporter) { 123 SkLayerDrawLooper::Builder looperBuilder; 124 SkLayerDrawLooper::LayerInfo layerInfo; 125 126 // Add the back layer, with the defaults. 127 (void)looperBuilder.addLayer(layerInfo); 128 129 // Add the front layer, with some layer info set. 130 layerInfo.fOffset.set(10.0f, 20.0f); 131 layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; 132 SkPaint* layerPaint = looperBuilder.addLayerOnTop(layerInfo); 133 layerPaint->setBlendMode(SkBlendMode::kSrc); 134 135 FakeDevice device; 136 SkCanvas canvas(&device); 137 SkPaint paint; 138 sk_sp<SkDrawLooper> looper(looperBuilder.detach()); 139 SkArenaAlloc alloc{48}; 140 SkDrawLooper::Context* context = looper->makeContext(&canvas, &alloc); 141 142 // The back layer should come first. 143 REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 144 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrcOver); 145 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 146 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX()); 147 REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY()); 148 paint.reset(); 149 150 // Then the front layer. 151 REPORTER_ASSERT(reporter, context->next(&canvas, &paint)); 152 REPORTER_ASSERT(reporter, paint.getBlendMode() == SkBlendMode::kSrc); 153 canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint); 154 REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX()); 155 REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY()); 156 157 // Only two layers were added, so that should be the end. 158 REPORTER_ASSERT(reporter, !context->next(&canvas, &paint)); 159 } 160 161 DEF_TEST(LayerDrawLooper, reporter) { 162 test_frontToBack(reporter); 163 test_backToFront(reporter); 164 test_mixed(reporter); 165 } 166