Index: gm/bigrrectaaeffect.cpp |
diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp |
index 18a0c6ef7d32180f7db1df40684742e956b9a622..c3f47f932d1ca06c85c50d58d635fb090b50805b 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 |