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

Side by Side Diff: src/gpu/GrShape.cpp

Issue 2357643002: Make GrShape compute keys for short paths from path data instead of using the gen id. (Closed)
Patch Set: Address comments Created 4 years, 2 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/GrShape.h ('k') | tests/GrShapeTest.cpp » ('j') | 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 "GrShape.h" 8 #include "GrShape.h"
9 9
10 GrShape& GrShape::operator=(const GrShape& that) { 10 GrShape& GrShape::operator=(const GrShape& that) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 65
66 SkRect GrShape::styledBounds() const { 66 SkRect GrShape::styledBounds() const {
67 if (Type::kEmpty == fType && !fStyle.hasNonDashPathEffect()) { 67 if (Type::kEmpty == fType && !fStyle.hasNonDashPathEffect()) {
68 return SkRect::MakeEmpty(); 68 return SkRect::MakeEmpty();
69 } 69 }
70 SkRect bounds; 70 SkRect bounds;
71 fStyle.adjustBounds(&bounds, this->bounds()); 71 fStyle.adjustBounds(&bounds, this->bounds());
72 return bounds; 72 return bounds;
73 } 73 }
74 74
75 // If the path is small enough to be keyed from its data this returns key length , otherwise -1.
76 static int path_key_from_data_size(const SkPath& path) {
77 const int verbCnt = path.countVerbs();
78 if (verbCnt > GrShape::kMaxKeyFromDataVerbCnt) {
79 return -1;
80 }
81 const int pointCnt = path.countPoints();
82 const int conicWeightCnt = SkPathPriv::ConicWeightCnt(path);
83
84 GR_STATIC_ASSERT(sizeof(SkPoint) == 2 * sizeof(uint32_t));
85 GR_STATIC_ASSERT(sizeof(SkScalar) == sizeof(uint32_t));
86 // 2 is for the verb cnt and a fill type. Each verb is a byte but we'll pad the verb data out to
87 // a uint32_t length.
88 return 2 + (SkAlign4(verbCnt) >> 2) + 2 * pointCnt + conicWeightCnt;
89 }
90
91 // Writes the path data key into the passed pointer.
92 static void write_path_key_from(const SkPath& path, uint32_t* origKey) {
93 uint32_t* key = origKey;
94 // The check below should take care of negative values casted positive.
95 const int verbCnt = path.countVerbs();
96 const int pointCnt = path.countPoints();
97 const int conicWeightCnt = SkPathPriv::ConicWeightCnt(path);
98 SkASSERT(verbCnt <= GrShape::kMaxKeyFromDataVerbCnt);
99 SkASSERT(pointCnt && verbCnt);
100 *key++ = path.getFillType();
101 *key++ = verbCnt;
102 memcpy(key, SkPathPriv::VerbData(path), verbCnt * sizeof(uint8_t));
103 int verbKeySize = SkAlign4(verbCnt);
104 // pad out to uint32_t alignment using value that will stand out when debugg ing.
105 uint8_t* pad = reinterpret_cast<uint8_t*>(key)+ verbCnt;
106 memset(pad, 0xDE, verbKeySize - verbCnt);
107 key += verbKeySize >> 2;
108
109 memcpy(key, SkPathPriv::PointData(path), sizeof(SkPoint) * pointCnt);
110 GR_STATIC_ASSERT(sizeof(SkPoint) == 2 * sizeof(uint32_t));
111 key += 2 * pointCnt;
112 memcpy(key, SkPathPriv::ConicWeightData(path), sizeof(SkScalar) * conicWeigh tCnt);
113 GR_STATIC_ASSERT(sizeof(SkScalar) == sizeof(uint32_t));
114 SkDEBUGCODE(key += conicWeightCnt);
115 SkASSERT(key - origKey == path_key_from_data_size(path));
116 }
117
75 int GrShape::unstyledKeySize() const { 118 int GrShape::unstyledKeySize() const {
76 if (fInheritedKey.count()) { 119 if (fInheritedKey.count()) {
77 return fInheritedKey.count(); 120 return fInheritedKey.count();
78 } 121 }
79 switch (fType) { 122 switch (fType) {
80 case Type::kEmpty: 123 case Type::kEmpty:
81 return 1; 124 return 1;
82 case Type::kRRect: 125 case Type::kRRect:
83 SkASSERT(!fInheritedKey.count()); 126 SkASSERT(!fInheritedKey.count());
84 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t)); 127 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
85 // + 1 for the direction, start index, and inverseness. 128 // + 1 for the direction, start index, and inverseness.
86 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1; 129 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1;
87 case Type::kLine: 130 case Type::kLine:
88 GR_STATIC_ASSERT(2 * sizeof(uint32_t) == sizeof(SkPoint)); 131 GR_STATIC_ASSERT(2 * sizeof(uint32_t) == sizeof(SkPoint));
89 // 4 for the end points and 1 for the inverseness 132 // 4 for the end points and 1 for the inverseness
90 return 5; 133 return 5;
91 case Type::kPath: 134 case Type::kPath: {
135 int dataKeySize = path_key_from_data_size(fPathData.fPath);
136 if (dataKeySize >= 0) {
137 return dataKeySize;
138 }
92 if (0 == fPathData.fGenID) { 139 if (0 == fPathData.fGenID) {
93 return -1; 140 return -1;
94 } else {
95 // The key is the path ID and fill type.
96 return 2;
97 } 141 }
142 // The key is the path ID and fill type.
143 return 2;
144 }
98 } 145 }
99 SkFAIL("Should never get here."); 146 SkFAIL("Should never get here.");
100 return 0; 147 return 0;
101 } 148 }
102 149
103 void GrShape::writeUnstyledKey(uint32_t* key) const { 150 void GrShape::writeUnstyledKey(uint32_t* key) const {
104 SkASSERT(this->unstyledKeySize()); 151 SkASSERT(this->unstyledKeySize());
105 SkDEBUGCODE(uint32_t* origKey = key;) 152 SkDEBUGCODE(uint32_t* origKey = key;)
106 if (fInheritedKey.count()) { 153 if (fInheritedKey.count()) {
107 memcpy(key, fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count( )); 154 memcpy(key, fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count( ));
108 SkDEBUGCODE(key += fInheritedKey.count();) 155 SkDEBUGCODE(key += fInheritedKey.count();)
109 } else { 156 } else {
110 switch (fType) { 157 switch (fType) {
111 case Type::kEmpty: 158 case Type::kEmpty:
112 *key++ = 1; 159 *key++ = 1;
113 break; 160 break;
114 case Type::kRRect: 161 case Type::kRRect:
115 fRRectData.fRRect.writeToMemory(key); 162 fRRectData.fRRect.writeToMemory(key);
116 key += SkRRect::kSizeInMemory / sizeof(uint32_t); 163 key += SkRRect::kSizeInMemory / sizeof(uint32_t);
117 *key = (fRRectData.fDir == SkPath::kCCW_Direction) ? (1 << 31) : 0; 164 *key = (fRRectData.fDir == SkPath::kCCW_Direction) ? (1 << 31) : 0;
118 *key |= fRRectData.fInverted ? (1 << 30) : 0; 165 *key |= fRRectData.fInverted ? (1 << 30) : 0;
119 *key++ |= fRRectData.fStart; 166 *key++ |= fRRectData.fStart;
120 SkASSERT(fRRectData.fStart < 8); 167 SkASSERT(fRRectData.fStart < 8);
121 break; 168 break;
122 case Type::kLine: 169 case Type::kLine:
123 memcpy(key, fLineData.fPts, 2 * sizeof(SkPoint)); 170 memcpy(key, fLineData.fPts, 2 * sizeof(SkPoint));
124 key += 4; 171 key += 4;
125 *key++ = fLineData.fInverted ? 1 : 0; 172 *key++ = fLineData.fInverted ? 1 : 0;
126 break; 173 break;
127 case Type::kPath: 174 case Type::kPath: {
175 int dataKeySize = path_key_from_data_size(fPathData.fPath);
176 if (dataKeySize >= 0) {
177 write_path_key_from(fPathData.fPath, key);
178 return;
179 }
128 SkASSERT(fPathData.fGenID); 180 SkASSERT(fPathData.fGenID);
129 *key++ = fPathData.fGenID; 181 *key++ = fPathData.fGenID;
130 // We could canonicalize the fill rule for paths that don't diff erentiate between 182 // We could canonicalize the fill rule for paths that don't diff erentiate between
131 // even/odd or winding fill (e.g. convex). 183 // even/odd or winding fill (e.g. convex).
132 *key++ = this->path().getFillType(); 184 *key++ = this->path().getFillType();
133 break; 185 break;
186 }
134 } 187 }
135 } 188 }
136 SkASSERT(key - origKey == this->unstyledKeySize()); 189 SkASSERT(key - origKey == this->unstyledKeySize());
137 } 190 }
138 191
139 void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca lar scale) { 192 void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca lar scale) {
140 SkASSERT(!fInheritedKey.count()); 193 SkASSERT(!fInheritedKey.count());
141 // If the output shape turns out to be simple, then we will just use its geo metric key 194 // If the output shape turns out to be simple, then we will just use its geo metric key
142 if (Type::kPath == fType) { 195 if (Type::kPath == fType) {
143 // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key a s 196 // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key a s
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 fStyle = GrStyle::SimpleFill(); 531 fStyle = GrStyle::SimpleFill();
479 return; 532 return;
480 } 533 }
481 } 534 }
482 // Only path effects could care about the order of the points. Otherwise can onicalize 535 // Only path effects could care about the order of the points. Otherwise can onicalize
483 // the point order. 536 // the point order.
484 if (pts[1].fY < pts[0].fY || (pts[1].fY == pts[0].fY && pts[1].fX < pts[0].f X)) { 537 if (pts[1].fY < pts[0].fY || (pts[1].fY == pts[0].fY && pts[1].fX < pts[0].f X)) {
485 SkTSwap(pts[0], pts[1]); 538 SkTSwap(pts[0], pts[1]);
486 } 539 }
487 } 540 }
OLDNEW
« no previous file with comments | « src/gpu/GrShape.h ('k') | tests/GrShapeTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698