Index: tests/RecordOptsTest.cpp |
diff --git a/tests/RecordOptsTest.cpp b/tests/RecordOptsTest.cpp |
index b6bfba4cae0985872e7aaa43677399b9316fa096..e55024400479ea01d0c0bb32513aecc53a02dab3 100644 |
--- a/tests/RecordOptsTest.cpp |
+++ b/tests/RecordOptsTest.cpp |
@@ -8,11 +8,14 @@ |
#include "Test.h" |
#include "RecordTestUtils.h" |
+#include "SkColorFilter.h" |
#include "SkRecord.h" |
#include "SkRecordOpts.h" |
#include "SkRecorder.h" |
#include "SkRecords.h" |
#include "SkXfermode.h" |
+#include "SkPictureRecorder.h" |
+#include "SkPictureImageFilter.h" |
static const int W = 1920, H = 1080; |
@@ -169,3 +172,139 @@ DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) { |
REPORTER_ASSERT(r, drawRect != NULL); |
REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202); |
} |
+ |
+static void assert_merge_svg_opacity_and_filter_layers(skiatest::Reporter* r, |
+ SkRecord* record, |
+ unsigned i, |
+ bool shouldBeNoOped) { |
+ SkRecordMergeSvgOpacityAndFilterLayers(record); |
+ if (shouldBeNoOped) { |
+ assert_type<SkRecords::NoOp>(r, *record, i); |
+ assert_type<SkRecords::NoOp>(r, *record, i + 6); |
+ } else { |
+ assert_type<SkRecords::SaveLayer>(r, *record, i); |
+ assert_type<SkRecords::Restore>(r, *record, i + 6); |
+ } |
+} |
+ |
+DEF_TEST(RecordOpts_MergeSvgOpacityAndFilterLayers, r) { |
+ SkRecord record; |
+ SkRecorder recorder(&record, W, H); |
+ |
+ SkRect bounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(200)); |
+ SkRect clip = SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(60)); |
+ |
+ SkPaint alphaOnlyLayerPaint; |
+ alphaOnlyLayerPaint.setColor(0x03000000); // Only alpha. |
+ SkPaint translucentLayerPaint; |
+ translucentLayerPaint.setColor(0x03040506); // Not only alpha. |
+ SkPaint xfermodePaint; |
+ xfermodePaint.setXfermodeMode(SkXfermode::kDstIn_Mode); |
+ SkPaint colorFilterPaint; |
+ colorFilterPaint.setColorFilter( |
+ SkColorFilter::CreateModeFilter(SK_ColorLTGRAY, SkXfermode::kSrcIn_Mode))->unref(); |
+ |
+ SkPaint opaqueFilterLayerPaint; |
+ opaqueFilterLayerPaint.setColor(0xFF020202); // Opaque. |
+ SkPaint translucentFilterLayerPaint; |
+ translucentFilterLayerPaint.setColor(0x0F020202); // Not opaque. |
+ SkAutoTUnref<SkPicture> shape; |
+ { |
+ SkPictureRecorder recorder; |
+ SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(100), SkIntToScalar(100)); |
+ SkPaint shapePaint; |
+ shapePaint.setColor(SK_ColorWHITE); |
+ canvas->drawRect(SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(50)), shapePaint); |
+ shape.reset(recorder.endRecordingAsPicture()); |
+ } |
+ translucentFilterLayerPaint.setImageFilter(SkPictureImageFilter::Create(shape))->unref(); |
+ |
+ int index = 0; |
+ |
+ { |
+ // Any combination of these should cause the pattern to be optimized. |
+ SkRect* firstBounds[] = { NULL, &bounds }; |
+ SkPaint* firstPaints[] = { NULL, &alphaOnlyLayerPaint }; |
+ SkRect* secondBounds[] = { NULL, &bounds }; |
+ SkPaint* secondPaints[] = { &opaqueFilterLayerPaint, &translucentFilterLayerPaint }; |
+ |
+ for (size_t i = 0; i < SK_ARRAY_COUNT(firstBounds); ++ i) { |
+ for (size_t j = 0; j < SK_ARRAY_COUNT(firstPaints); ++j) { |
+ for (size_t k = 0; k < SK_ARRAY_COUNT(secondBounds); ++k) { |
+ for (size_t m = 0; m < SK_ARRAY_COUNT(secondPaints); ++m) { |
+ recorder.saveLayer(firstBounds[i], firstPaints[j]); |
+ recorder.save(); |
+ recorder.clipRect(clip); |
+ recorder.saveLayer(secondBounds[k], secondPaints[m]); |
+ recorder.restore(); |
+ recorder.restore(); |
+ recorder.restore(); |
+ assert_merge_svg_opacity_and_filter_layers(r, &record, index, true); |
+ index += 7; |
+ } |
+ } |
+ } |
+ } |
+ } |
+ |
+ // These should cause the pattern to stay unoptimized: |
+ struct { |
+ SkPaint* firstPaint; |
+ SkPaint* secondPaint; |
+ } noChangeTests[] = { |
+ // No change: NULL filter layer paint not implemented. |
+ { &alphaOnlyLayerPaint, NULL }, |
+ // No change: layer paint is not alpha-only. |
+ { &translucentLayerPaint, &opaqueFilterLayerPaint }, |
+ // No change: layer paint has an xfereffect. |
+ { &xfermodePaint, &opaqueFilterLayerPaint }, |
+ // No change: filter layer paint has an xfereffect. |
+ { &alphaOnlyLayerPaint, &xfermodePaint }, |
+ // No change: layer paint has a color filter. |
+ { &colorFilterPaint, &opaqueFilterLayerPaint }, |
+ // No change: filter layer paint has a color filter (until the optimization accounts for |
+ // constant color draws that can filter the color). |
+ { &alphaOnlyLayerPaint, &colorFilterPaint } |
+ }; |
+ |
+ for (size_t i = 0; i < SK_ARRAY_COUNT(noChangeTests); ++i) { |
+ recorder.saveLayer(NULL, noChangeTests[i].firstPaint); |
+ recorder.save(); |
+ recorder.clipRect(clip); |
+ recorder.saveLayer(NULL, noChangeTests[i].secondPaint); |
+ recorder.restore(); |
+ recorder.restore(); |
+ recorder.restore(); |
+ assert_merge_svg_opacity_and_filter_layers(r, &record, index, false); |
+ index += 7; |
+ } |
+ |
+ // Test the folded alpha value. |
+ recorder.saveLayer(NULL, &alphaOnlyLayerPaint); |
+ recorder.save(); |
+ recorder.clipRect(clip); |
+ recorder.saveLayer(NULL, &opaqueFilterLayerPaint); |
+ recorder.restore(); |
+ recorder.restore(); |
+ recorder.restore(); |
+ assert_merge_svg_opacity_and_filter_layers(r, &record, index, true); |
+ |
+ const SkRecords::SaveLayer* saveLayer = assert_type<SkRecords::SaveLayer>(r, record, index + 3); |
+ REPORTER_ASSERT(r, saveLayer != NULL); |
+ REPORTER_ASSERT(r, saveLayer->paint->getColor() == 0x03020202); |
+ |
+ index += 7; |
+ |
+ // Test that currently we do not fold alphas for patterns without the clip. This is just not |
+ // implemented. |
+ recorder.saveLayer(NULL, &alphaOnlyLayerPaint); |
+ recorder.saveLayer(NULL, &opaqueFilterLayerPaint); |
+ recorder.restore(); |
+ recorder.restore(); |
+ SkRecordMergeSvgOpacityAndFilterLayers(&record); |
+ assert_type<SkRecords::SaveLayer>(r, record, index); |
+ assert_type<SkRecords::SaveLayer>(r, record, index + 1); |
+ assert_type<SkRecords::Restore>(r, record, index + 2); |
+ assert_type<SkRecords::Restore>(r, record, index + 3); |
+ index += 4; |
+} |