diff options
author | 2015-12-09 10:17:35 -0800 | |
---|---|---|
committer | 2015-12-09 10:17:35 -0800 | |
commit | 4a4f14ba3f93cc6bb9146be0f029a9badb1b95d9 (patch) | |
tree | 1554bb754ff7e3663467ac4512da09b9c1e5727b /gm/bigrrectaaeffect.cpp | |
parent | db64af3b178a19ecb47d2b9a373113687d8921fd (diff) |
Split big rrect aa effect up into separate images
Needed to enlarge radii to surface bugs without exceeding max texture size on low end devices.
BUG=chromium:477684
Review URL: https://codereview.chromium.org/1508003008
Diffstat (limited to 'gm/bigrrectaaeffect.cpp')
-rw-r--r-- | gm/bigrrectaaeffect.cpp | 156 |
1 files changed, 79 insertions, 77 deletions
diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp index 18a0c6ef7d..c3f47f932d 100644 --- a/gm/bigrrectaaeffect.cpp +++ b/gm/bigrrectaaeffect.cpp @@ -18,17 +18,32 @@ namespace skiagm { class BigRRectAAEffectGM : public GM { public: - BigRRectAAEffectGM() { - this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD)); - this->setUpRRects(); + BigRRectAAEffectGM(const SkRRect& rrect, const char* name) + : fRRect(rrect) + , fName(name) { + this->setBGColor(sk_tool_utils::color_to_565(SK_ColorBLUE)); + // Each test case draws the rrect with gaps around it. + fTestWidth = SkScalarCeilToInt(rrect.width()) + 2 * kGap; + fTestHeight = SkScalarCeilToInt(rrect.height()) + 2 * kGap; + + // Add a pad between test cases. + fTestOffsetX = fTestWidth + kPad; + fTestOffsetY = fTestHeight + kPad; + + // We draw two tests in x (fill and inv-fill) and pad around + // all four sides of the image. + fWidth = 2 * fTestOffsetX + kPad; + fHeight = fTestOffsetY + kPad; } protected: SkString onShortName() override { - return SkString("big_rrect_aa_effect"); + SkString name; + name.printf("big_rrect_%s_aa_effect", fName); + return name; } - SkISize onISize() override { return SkISize::Make(kImageWidth, kImageHeight); } + SkISize onISize() override { return SkISize::Make(fWidth, fHeight); } void onDraw(SkCanvas* canvas) override { GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); @@ -40,95 +55,82 @@ protected: SkPaint paint; -#ifdef SK_DEBUG - static const SkRect kMaxRRectBound = SkRect::MakeWH(SkIntToScalar(kMaxSize), - SkIntToScalar(kMaxSize)); - static const SkRect kMaxImageBound = SkRect::MakeWH(SkIntToScalar(kImageWidth), - SkIntToScalar(kImageHeight)); -#endif - int y = kPad; int x = kPad; static const GrPrimitiveEdgeType kEdgeTypes[] = { kFillAA_GrProcessorEdgeType, kInverseFillAA_GrProcessorEdgeType, }; + SkRect testBounds = SkRect::MakeIWH(fTestWidth, fTestHeight); for (size_t et = 0; et < SK_ARRAY_COUNT(kEdgeTypes); ++et) { GrPrimitiveEdgeType edgeType = kEdgeTypes[et]; - for (int curRRect = 0; curRRect < fRRects.count(); ++curRRect) { -#ifdef SK_DEBUG - SkASSERT(kMaxRRectBound.contains(fRRects[curRRect].getBounds())); - SkRect imageSpaceBounds = fRRects[curRRect].getBounds(); - imageSpaceBounds.offset(SkIntToScalar(x), SkIntToScalar(y)); - SkASSERT(kMaxImageBound.contains(imageSpaceBounds)); -#endif - canvas->save(); - canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); - GrTestTarget tt; - context->getTestTarget(&tt, rt); - if (nullptr == tt.target()) { - SkDEBUGFAIL("Couldn't get Gr test target."); - return; - } - GrPipelineBuilder pipelineBuilder; - pipelineBuilder.setXPFactory( - GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref(); - - SkRRect rrect = fRRects[curRRect]; - rrect.offset(SkIntToScalar(x), SkIntToScalar(y)); - SkAutoTUnref<GrFragmentProcessor> fp(GrRRectEffect::Create(edgeType, rrect)); - SkASSERT(fp); - if (fp) { - pipelineBuilder.addCoverageFragmentProcessor(fp); - pipelineBuilder.setRenderTarget(rt); - - SkRect bounds = SkRect::MakeWH(SkIntToScalar(kMaxSize), - SkIntToScalar(kMaxSize)); - bounds.outset(2.f, 2.f); - bounds.offset(SkIntToScalar(x), SkIntToScalar(y)); - - tt.target()->drawNonAARect(pipelineBuilder, - 0xff000000, - SkMatrix::I(), - bounds); - } - canvas->restore(); - x = x + kDrawOffset; - if (x + kMaxSize> kImageWidth) { - x = kPad; - y += kDrawOffset; + canvas->save(); + canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); + + // Draw a background for the test case + SkPaint paint; + paint.setColor(SK_ColorWHITE); + canvas->drawRect(testBounds, paint); + + GrTestTarget tt; + context->getTestTarget(&tt, rt); + if (!tt.target()) { + SkDEBUGFAIL("Couldn't get Gr test target."); + return; } - } + GrPipelineBuilder pipelineBuilder; + pipelineBuilder.setXPFactory( + GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref(); + + SkRRect rrect = fRRect; + rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap)); + SkAutoTUnref<GrFragmentProcessor> fp(GrRRectEffect::Create(edgeType, rrect)); + SkASSERT(fp); + if (fp) { + pipelineBuilder.addCoverageFragmentProcessor(fp); + pipelineBuilder.setRenderTarget(rt); + + SkRect bounds = testBounds; + bounds.offset(SkIntToScalar(x), SkIntToScalar(y)); + + tt.target()->drawNonAARect(pipelineBuilder, + 0xff000000, + SkMatrix::I(), + bounds); + } + canvas->restore(); + x = x + fTestOffsetX; } } - void setUpRRects() { - SkScalar maxSize = SkIntToScalar(kMaxSize); - fRRects.push()->setRect(SkRect::MakeWH(maxSize, maxSize)); - fRRects.push()->setOval(SkRect::MakeWH(maxSize, maxSize)); - fRRects.push()->setOval(SkRect::MakeWH(maxSize - 1.f, maxSize - 10.f)); - fRRects.push()->setRectXY(SkRect::MakeWH(maxSize - 1.f, maxSize - 10.f), - maxSize/2.f - 10.f, maxSize/2.f - 10.f); - fRRects.push()->setRectXY(SkRect::MakeWH(maxSize - 1.f, maxSize - 10), - maxSize/2.f - 10.f, maxSize/2.f - 20.f); - } - private: - static const int kPad = 5; - static const int kMaxSize = 300; - static const int kDrawOffset = kMaxSize + kPad; - - static const int kImageWidth = 4 * kDrawOffset + kPad; - static const int kImageHeight = 3 * kDrawOffset + kPad; - - - SkTDArray<SkRRect> fRRects; + // pad between test cases + static const int kPad = 7; + // gap between rect for each case that is rendered and exterior of rrect + static const int kGap = 3; + + SkRRect fRRect; + int fWidth; + int fHeight; + int fTestWidth; + int fTestHeight; + int fTestOffsetX; + int fTestOffsetY; + const char* fName; typedef GM INHERITED; }; /////////////////////////////////////////////////////////////////////////////// - -DEF_GM( return new BigRRectAAEffectGM (); ) +// This value is motivated by bug chromium:477684. It has to be large to cause overflow in +// the shader +static const int kSize = 700; + +DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRect(SkRect::MakeIWH(kSize, kSize)), "rect"); ) +DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize, kSize)), "circle"); ) +DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize - 1, kSize - 10)), "ellipse"); ) +// The next two have small linear segments between the corners +DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 10.f), "circular_corner"); ) +DEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 15.f), "elliptical_corner"); ) } #endif |