| 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;
|
| +}
|
|
|