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

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: put back const& 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
« no previous file with comments | « 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
32 static bool test_bounds_by_rasterizing(const SkPath& path, const SkRect& bounds) {
33 static constexpr int kRes = 2000;
34 // This tolerance is in units of 1/kRes fractions of the bounds width/height .
35 static constexpr int kTol = 0;
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);
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 #if defined(SK_BUILD_FOR_WIN)
52 // The static constexpr version in #else causes cl.exe to crash.
53 const uint8_t* kZeros = reinterpret_cast<uint8_t*>(calloc(kRes, 1));
54 #else
55 static constexpr uint8_t kZeros[kRes] = {0};
56 #endif
57 for (int y = 0; y < kRes/4; ++y) {
58 const uint8_t* row = pixmap.addr8(0, y);
59 if (0 != memcmp(kZeros, row, kRes)) {
60 return false;
61 }
62 }
63 #ifdef SK_BUILD_FOR_WIN
64 free(const_cast<uint8_t*>(kZeros));
65 #endif
66 return true;
67 }
68
30 namespace { 69 namespace {
31
32 class TestCase { 70 class TestCase {
33 public: 71 public:
34 template <typename GEO> 72 template <typename GEO>
35 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r, 73 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r,
36 SkScalar scale = SK_Scalar1) : fBase(geo, paint) { 74 SkScalar scale = SK_Scalar1) : fBase(geo, paint) {
37 this->init(r, scale); 75 this->init(r, scale);
38 } 76 }
39 77
40 struct SelfExpectations { 78 struct SelfExpectations {
41 bool fPEHasEffect; 79 bool fPEHasEffect;
(...skipping 16 matching lines...) Expand all
58 const GrShape& appliedPathEffectShape() const { return fAppliedPE; } 96 const GrShape& appliedPathEffectShape() const { return fAppliedPE; }
59 const GrShape& appliedFullStyleShape() const { return fAppliedFull; } 97 const GrShape& appliedFullStyleShape() const { return fAppliedFull; }
60 98
61 // The returned array's count will be 0 if the key shape has no key. 99 // The returned array's count will be 0 if the key shape has no key.
62 const Key& baseKey() const { return fBaseKey; } 100 const Key& baseKey() const { return fBaseKey; }
63 const Key& appliedPathEffectKey() const { return fAppliedPEKey; } 101 const Key& appliedPathEffectKey() const { return fAppliedPEKey; }
64 const Key& appliedFullStyleKey() const { return fAppliedFullKey; } 102 const Key& appliedFullStyleKey() const { return fAppliedFullKey; }
65 const Key& appliedPathEffectThenStrokeKey() const { return fAppliedPEThenStr okeKey; } 103 const Key& appliedPathEffectThenStrokeKey() const { return fAppliedPEThenStr okeKey; }
66 104
67 private: 105 private:
106 static void CheckBounds(skiatest::Reporter* r, const GrShape& shape, const S kRect& bounds) {
107 SkPath path;
108 shape.asPath(&path);
109 // If the bounds are empty, the path ought to be as well.
110 if (bounds.isEmpty()) {
111 REPORTER_ASSERT(r, path.isEmpty());
112 return;
113 }
114 if (path.isEmpty()) {
115 return;
116 }
117 REPORTER_ASSERT(r, test_bounds_by_rasterizing(path, bounds));
118 }
119
68 void init(skiatest::Reporter* r, SkScalar scale) { 120 void init(skiatest::Reporter* r, SkScalar scale) {
69 fAppliedPE = fBase.applyStyle(GrStyle::Apply::kPathEffectOnly, scale); 121 fAppliedPE = fBase.applyStyle(GrStyle::Apply::kPathEffectOnly, scale);
70 fAppliedPEThenStroke = fAppliedPE.applyStyle(GrStyle::Apply::kPathEffect AndStrokeRec, 122 fAppliedPEThenStroke = fAppliedPE.applyStyle(GrStyle::Apply::kPathEffect AndStrokeRec,
71 scale); 123 scale);
72 fAppliedFull = fBase.applyStyle(GrStyle::Apply::kPathEffectAndSt rokeRec, scale); 124 fAppliedFull = fBase.applyStyle(GrStyle::Apply::kPathEffectAndSt rokeRec, scale);
73 125
74 make_key(&fBaseKey, fBase); 126 make_key(&fBaseKey, fBase);
75 make_key(&fAppliedPEKey, fAppliedPE); 127 make_key(&fAppliedPEKey, fAppliedPE);
76 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke); 128 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke);
77 make_key(&fAppliedFullKey, fAppliedFull); 129 make_key(&fAppliedFullKey, fAppliedFull);
78 130
79 // Applying the path effect and then the stroke should always be the sam e as applying 131 // Applying the path effect and then the stroke should always be the sam e as applying
80 // both in one go. 132 // both in one go.
81 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey); 133 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey);
82 SkPath a, b; 134 SkPath a, b;
83 fAppliedPEThenStroke.asPath(&a); 135 fAppliedPEThenStroke.asPath(&a);
84 fAppliedFull.asPath(&b); 136 fAppliedFull.asPath(&b);
85 REPORTER_ASSERT(r, a == b); 137 REPORTER_ASSERT(r, a == b);
86 REPORTER_ASSERT(r, fAppliedFull.isEmpty() == fAppliedPEThenStroke.isEmpt y()); 138 REPORTER_ASSERT(r, fAppliedFull.isEmpty() == fAppliedPEThenStroke.isEmpt y());
87 139
88 SkPath path; 140 SkPath path;
89 fBase.asPath(&path); 141 fBase.asPath(&path);
90 REPORTER_ASSERT(r, path.isEmpty() == fBase.isEmpty()); 142 REPORTER_ASSERT(r, path.isEmpty() == fBase.isEmpty());
91 fAppliedPE.asPath(&path); 143 fAppliedPE.asPath(&path);
92 REPORTER_ASSERT(r, path.isEmpty() == fAppliedPE.isEmpty()); 144 REPORTER_ASSERT(r, path.isEmpty() == fAppliedPE.isEmpty());
93 fAppliedFull.asPath(&path); 145 fAppliedFull.asPath(&path);
94 REPORTER_ASSERT(r, path.isEmpty() == fAppliedFull.isEmpty()); 146 REPORTER_ASSERT(r, path.isEmpty() == fAppliedFull.isEmpty());
95 147
148 CheckBounds(r, fBase, fBase.bounds());
149 CheckBounds(r, fAppliedPE, fAppliedPE.bounds());
150 CheckBounds(r, fAppliedPEThenStroke, fAppliedPEThenStroke.bounds());
151 CheckBounds(r, fAppliedFull, fAppliedFull.bounds());
152 SkRect styledBounds;
153 fBase.styledBounds(&styledBounds);
154 CheckBounds(r, fAppliedFull, styledBounds);
155 fAppliedPE.styledBounds(&styledBounds);
156 CheckBounds(r, fAppliedFull, styledBounds);
157
96 // Check that the same path is produced when style is applied by GrShape and GrStyle. 158 // Check that the same path is produced when style is applied by GrShape and GrStyle.
97 SkPath preStyle; 159 SkPath preStyle;
98 SkPath postPathEffect; 160 SkPath postPathEffect;
99 SkPath postAllStyle; 161 SkPath postAllStyle;
100 162
101 fBase.asPath(&preStyle); 163 fBase.asPath(&preStyle);
102 SkStrokeRec postPEStrokeRec(SkStrokeRec::kFill_InitStyle); 164 SkStrokeRec postPEStrokeRec(SkStrokeRec::kFill_InitStyle);
103 if (fBase.style().applyPathEffectToPath(&postPathEffect, &postPEStrokeRe c, preStyle, 165 if (fBase.style().applyPathEffectToPath(&postPathEffect, &postPEStrokeRe c, preStyle,
104 scale)) { 166 scale)) {
105 // run postPathEffect through GrShape to get any geometry reductions that would have 167 // 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 } 1005 }
944 } 1006 }
945 1007
946 // Test a volatile empty path. 1008 // Test a volatile empty path.
947 test_volatile_path(reporter, SkPath(), true); 1009 test_volatile_path(reporter, SkPath(), true);
948 1010
949 test_empty_shape(reporter); 1011 test_empty_shape(reporter);
950 } 1012 }
951 1013
952 #endif 1014 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrStyle.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698