LayerDrawLooperTest.cpp 6.1 KB

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