Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(438)

Side by Side Diff: tests/GrShapeTest.cpp

Issue 1970003003: Add bounds to GrShape (Closed) Base URL: https://chromium.googlesource.com/skia.git@grshapeisempty
Patch Set: minor Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/gpu/GrStyle.h ('K') | « src/gpu/GrStyle.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include <initializer_list> 8 #include <initializer_list>
9 #include <functional> 9 #include <functional>
10 #include "Test.h" 10 #include "Test.h"
11 #if SK_SUPPORT_GPU 11 #if SK_SUPPORT_GPU
12 #include "GrShape.h" 12 #include "GrShape.h"
13 #include "SkCanvas.h"
14 #include "SkDashPathEffect.h"
13 #include "SkPath.h" 15 #include "SkPath.h"
14 #include "SkDashPathEffect.h" 16 #include "SkSurface.h"
15 17
16 using Key = SkTArray<uint32_t>; 18 using Key = SkTArray<uint32_t>;
17 19
18 static bool make_key(Key* key, const GrShape& shape) { 20 static bool make_key(Key* key, const GrShape& shape) {
19 int size = shape.unstyledKeySize(); 21 int size = shape.unstyledKeySize();
20 if (size <= 0) { 22 if (size <= 0) {
21 key->reset(0); 23 key->reset(0);
22 return false; 24 return false;
23 } 25 }
24 SkASSERT(size); 26 SkASSERT(size);
25 key->reset(size); 27 key->reset(size);
26 shape.writeUnstyledKey(key->begin()); 28 shape.writeUnstyledKey(key->begin());
27 return true; 29 return true;
28 } 30 }
29 31
30 namespace { 32 namespace {
33 static bool test_bounds_by_rasterizing(const SkPath& path, const SkRect& bounds) {
34 static constexpr int kRes = 2000;
35 static constexpr int kTol = 1;
36 GR_STATIC_ASSERT(kRes % 4 == 0);
37 SkImageInfo info = SkImageInfo::MakeA8(kRes, kRes);
38 sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
39 surface->getCanvas()->clear(0x0);
40 SkRect clip = SkRect::MakeXYWH(kRes/4, kRes/4, kRes/2, kRes/2);
41 SkMatrix matrix;
42 matrix.setRectToRect(bounds, clip, SkMatrix::kFill_ScaleToFit);
robertphillips 2016/05/12 17:18:47 Is this outset really kosher? If we're going to us
bsalomon 2016/05/12 18:37:58 For the current set of test cases it works at 0 (a
43 clip.outset(SkIntToScalar(kTol), SkIntToScalar(kTol));
44 surface->getCanvas()->clipRect(clip, SkRegion::kDifference_Op);
45 surface->getCanvas()->concat(matrix);
46 SkPaint whitePaint;
47 whitePaint.setColor(SK_ColorWHITE);
48 surface->getCanvas()->drawPath(path, whitePaint);
49 SkPixmap pixmap;
50 surface->getCanvas()->peekPixels(&pixmap);
51 static constexpr uint8_t kZeros[kRes] = {0};
52 for (int y = 0; y < kRes; ++y) {
53 const uint8_t* row = pixmap.addr8(0, y);
54 if (0 != memcmp(kZeros, row, kRes)) {
55 return false;
56 }
57 }
58 return true;
59 }
31 60
32 class TestCase { 61 class TestCase {
33 public: 62 public:
34 template <typename GEO> 63 template <typename GEO>
35 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r, 64 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r,
36 SkScalar scale = SK_Scalar1) : fBase(geo, paint) { 65 SkScalar scale = SK_Scalar1) : fBase(geo, paint) {
37 this->init(r, scale); 66 this->init(r, scale);
38 } 67 }
39 68
40 struct SelfExpectations { 69 struct SelfExpectations {
(...skipping 17 matching lines...) Expand all
58 const GrShape& appliedPathEffectShape() const { return fAppliedPE; } 87 const GrShape& appliedPathEffectShape() const { return fAppliedPE; }
59 const GrShape& appliedFullStyleShape() const { return fAppliedFull; } 88 const GrShape& appliedFullStyleShape() const { return fAppliedFull; }
60 89
61 // The returned array's count will be 0 if the key shape has no key. 90 // The returned array's count will be 0 if the key shape has no key.
62 const Key& baseKey() const { return fBaseKey; } 91 const Key& baseKey() const { return fBaseKey; }
63 const Key& appliedPathEffectKey() const { return fAppliedPEKey; } 92 const Key& appliedPathEffectKey() const { return fAppliedPEKey; }
64 const Key& appliedFullStyleKey() const { return fAppliedFullKey; } 93 const Key& appliedFullStyleKey() const { return fAppliedFullKey; }
65 const Key& appliedPathEffectThenStrokeKey() const { return fAppliedPEThenStr okeKey; } 94 const Key& appliedPathEffectThenStrokeKey() const { return fAppliedPEThenStr okeKey; }
66 95
67 private: 96 private:
97 static void CheckBounds(skiatest::Reporter* r, const GrShape& shape, const S kRect& bounds) {
98 SkPath path;
99 shape.asPath(&path);
100 // If the bounds are empty, the path ought to be as well.
101 if (bounds.isEmpty()) {
102 REPORTER_ASSERT(r, path.isEmpty());
103 return;
104 }
105 if (path.isEmpty()) {
106 return;
107 }
108 REPORTER_ASSERT(r, test_bounds_by_rasterizing(path, bounds));
109 }
110
68 void init(skiatest::Reporter* r, SkScalar scale) { 111 void init(skiatest::Reporter* r, SkScalar scale) {
69 fAppliedPE = fBase.applyStyle(GrStyle::Apply::kPathEffectOnly, scale); 112 fAppliedPE = fBase.applyStyle(GrStyle::Apply::kPathEffectOnly, scale);
70 fAppliedPEThenStroke = fAppliedPE.applyStyle(GrStyle::Apply::kPathEffect AndStrokeRec, 113 fAppliedPEThenStroke = fAppliedPE.applyStyle(GrStyle::Apply::kPathEffect AndStrokeRec,
71 scale); 114 scale);
72 fAppliedFull = fBase.applyStyle(GrStyle::Apply::kPathEffectAndSt rokeRec, scale); 115 fAppliedFull = fBase.applyStyle(GrStyle::Apply::kPathEffectAndSt rokeRec, scale);
73 116
74 make_key(&fBaseKey, fBase); 117 make_key(&fBaseKey, fBase);
75 make_key(&fAppliedPEKey, fAppliedPE); 118 make_key(&fAppliedPEKey, fAppliedPE);
76 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke); 119 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke);
77 make_key(&fAppliedFullKey, fAppliedFull); 120 make_key(&fAppliedFullKey, fAppliedFull);
78 121
79 // Applying the path effect and then the stroke should always be the sam e as applying 122 // Applying the path effect and then the stroke should always be the sam e as applying
80 // both in one go. 123 // both in one go.
81 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey); 124 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey);
82 SkPath a, b; 125 SkPath a, b;
83 fAppliedPEThenStroke.asPath(&a); 126 fAppliedPEThenStroke.asPath(&a);
84 fAppliedFull.asPath(&b); 127 fAppliedFull.asPath(&b);
85 REPORTER_ASSERT(r, a == b); 128 REPORTER_ASSERT(r, a == b);
86 REPORTER_ASSERT(r, fAppliedFull.isEmpty() == fAppliedPEThenStroke.isEmpt y()); 129 REPORTER_ASSERT(r, fAppliedFull.isEmpty() == fAppliedPEThenStroke.isEmpt y());
87 130
88 SkPath path; 131 SkPath path;
89 fBase.asPath(&path); 132 fBase.asPath(&path);
90 REPORTER_ASSERT(r, path.isEmpty() == fBase.isEmpty()); 133 REPORTER_ASSERT(r, path.isEmpty() == fBase.isEmpty());
91 fAppliedPE.asPath(&path); 134 fAppliedPE.asPath(&path);
92 REPORTER_ASSERT(r, path.isEmpty() == fAppliedPE.isEmpty()); 135 REPORTER_ASSERT(r, path.isEmpty() == fAppliedPE.isEmpty());
93 fAppliedFull.asPath(&path); 136 fAppliedFull.asPath(&path);
94 REPORTER_ASSERT(r, path.isEmpty() == fAppliedFull.isEmpty()); 137 REPORTER_ASSERT(r, path.isEmpty() == fAppliedFull.isEmpty());
95 138
139 CheckBounds(r, fBase, fBase.bounds());
140 CheckBounds(r, fAppliedPE, fAppliedPE.bounds());
141 CheckBounds(r, fAppliedPEThenStroke, fAppliedPEThenStroke.bounds());
142 CheckBounds(r, fAppliedFull, fAppliedFull.bounds());
143 SkRect styledBounds;
144 fBase.styledBounds(&styledBounds);
145 CheckBounds(r, fAppliedFull, styledBounds);
146 fAppliedPE.styledBounds(&styledBounds);
147 CheckBounds(r, fAppliedFull, styledBounds);
148
96 // Check that the same path is produced when style is applied by GrShape and GrStyle. 149 // Check that the same path is produced when style is applied by GrShape and GrStyle.
97 SkPath preStyle; 150 SkPath preStyle;
98 SkPath postPathEffect; 151 SkPath postPathEffect;
99 SkPath postAllStyle; 152 SkPath postAllStyle;
100 153
101 fBase.asPath(&preStyle); 154 fBase.asPath(&preStyle);
102 SkStrokeRec postPEStrokeRec(SkStrokeRec::kFill_InitStyle); 155 SkStrokeRec postPEStrokeRec(SkStrokeRec::kFill_InitStyle);
103 if (fBase.style().applyPathEffectToPath(&postPathEffect, &postPEStrokeRe c, preStyle, 156 if (fBase.style().applyPathEffectToPath(&postPathEffect, &postPEStrokeRe c, preStyle,
104 scale)) { 157 scale)) {
105 // run postPathEffect through GrShape to get any geometry reductions that would have 158 // run postPathEffect through GrShape to get any geometry reductions that would have
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 } 996 }
944 } 997 }
945 998
946 // Test a volatile empty path. 999 // Test a volatile empty path.
947 test_volatile_path(reporter, SkPath(), true); 1000 test_volatile_path(reporter, SkPath(), true);
948 1001
949 test_empty_shape(reporter); 1002 test_empty_shape(reporter);
950 } 1003 }
951 1004
952 #endif 1005 #endif
OLDNEW
« src/gpu/GrStyle.h ('K') | « src/gpu/GrStyle.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698