| OLD | NEW |
| 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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 ? style.strokeRec().getMiter() | 149 ? style.strokeRec().getMiter() |
| 150 : -1.f; | 150 : -1.f; |
| 151 memcpy(&key[i++], &scalar, sizeof(scalar)); | 151 memcpy(&key[i++], &scalar, sizeof(scalar)); |
| 152 | 152 |
| 153 scalar = style.strokeRec().getWidth(); | 153 scalar = style.strokeRec().getWidth(); |
| 154 memcpy(&key[i++], &scalar, sizeof(scalar)); | 154 memcpy(&key[i++], &scalar, sizeof(scalar)); |
| 155 } | 155 } |
| 156 SkASSERT(StyleKeySize(style, stopAfterPE) == i); | 156 SkASSERT(StyleKeySize(style, stopAfterPE) == i); |
| 157 } | 157 } |
| 158 | 158 |
| 159 void GrShape::setInheritedKey(const GrShape &parent, bool stopAfterPE){ | 159 void GrShape::setInheritedKey(const GrShape &parent, bool stopAfterPE) { |
| 160 SkASSERT(!fInheritedKey.count()); | 160 SkASSERT(!fInheritedKey.count()); |
| 161 // If the output shape turns out to be simple, then we will just use its geo
metric key | 161 // If the output shape turns out to be simple, then we will just use its geo
metric key |
| 162 if (Type::kPath == fType) { | 162 if (Type::kPath == fType) { |
| 163 // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key a
s | 163 // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key a
s |
| 164 // ApplyFullStyle(shape). | 164 // ApplyFullStyle(shape). |
| 165 // The full key is structured as (geo,path_effect,stroke). | 165 // The full key is structured as (geo,path_effect,stroke). |
| 166 // If we do ApplyPathEffect we get get,path_effect as the inherited key.
If we then | 166 // If we do ApplyPathEffect we get get,path_effect as the inherited key.
If we then |
| 167 // do ApplyFullStyle we'll memcpy geo,path_effect into the new inherited
key | 167 // do ApplyFullStyle we'll memcpy geo,path_effect into the new inherited
key |
| 168 // and then append the style key (which should now be stroke only) at th
e end. | 168 // and then append the style key (which should now be stroke only) at th
e end. |
| 169 int parentCnt = parent.fInheritedKey.count(); | 169 int parentCnt = parent.fInheritedKey.count(); |
| 170 bool useParentGeoKey = !parentCnt; | 170 bool useParentGeoKey = !parentCnt; |
| 171 if (useParentGeoKey) { | 171 if (useParentGeoKey) { |
| 172 parentCnt = parent.unstyledKeySize(); | 172 parentCnt = parent.unstyledKeySize(); |
| 173 if (parentCnt < 0) { |
| 174 // The parent's geometry has no key so we will have no key. |
| 175 fPath.get()->setIsVolatile(true); |
| 176 return; |
| 177 } |
| 173 } | 178 } |
| 174 int styleCnt = StyleKeySize(parent.fStyle, stopAfterPE); | 179 int styleCnt = StyleKeySize(parent.fStyle, stopAfterPE); |
| 175 if (styleCnt < 0) { | 180 if (styleCnt < 0) { |
| 176 // The style doesn't allow a key, set the path to volatile so that w
e fail when | 181 // The style doesn't allow a key, set the path to volatile so that w
e fail when |
| 177 // we try to get a key for the shape. | 182 // we try to get a key for the shape. |
| 178 fPath.get()->setIsVolatile(true); | 183 fPath.get()->setIsVolatile(true); |
| 184 return; |
| 185 } |
| 186 fInheritedKey.reset(parentCnt + styleCnt); |
| 187 if (useParentGeoKey) { |
| 188 // This will be the geo key. |
| 189 parent.writeUnstyledKey(fInheritedKey.get()); |
| 179 } else { | 190 } else { |
| 180 fInheritedKey.reset(parentCnt + styleCnt); | 191 // This should be (geo,path_effect). |
| 181 if (useParentGeoKey) { | 192 memcpy(fInheritedKey.get(), parent.fInheritedKey.get(), |
| 182 // This will be the geo key. | 193 parentCnt * sizeof(uint32_t)); |
| 183 parent.writeUnstyledKey(fInheritedKey.get()); | |
| 184 } else { | |
| 185 // This should be geo,path_effect | |
| 186 memcpy(fInheritedKey.get(), parent.fInheritedKey.get(), | |
| 187 parentCnt * sizeof(uint32_t)); | |
| 188 } | |
| 189 // Now turn (geo,path_effect) or (geo) into (geo,path_effect,stroke) | |
| 190 StyleKey(fInheritedKey.get() + parentCnt, parent.fStyle, stopAfterPE
); | |
| 191 } | 194 } |
| 195 // Now turn (geo,path_effect) or (geo) into (geo,path_effect,stroke) |
| 196 StyleKey(fInheritedKey.get() + parentCnt, parent.fStyle, stopAfterPE); |
| 192 } | 197 } |
| 193 } | 198 } |
| 194 | 199 |
| 195 GrShape::GrShape(const GrShape& that) : fType(that.fType), fStyle(that.fStyle) { | 200 GrShape::GrShape(const GrShape& that) : fType(that.fType), fStyle(that.fStyle) { |
| 196 switch (fType) { | 201 switch (fType) { |
| 197 case Type::kEmpty: | 202 case Type::kEmpty: |
| 198 return; | 203 return; |
| 199 case Type::kRRect: | 204 case Type::kRRect: |
| 200 fRRect = that.fRRect; | 205 fRRect = that.fRRect; |
| 201 return; | 206 return; |
| 202 case Type::kPath: | 207 case Type::kPath: |
| 203 fPath.set(*that.fPath.get()); | 208 fPath.set(*that.fPath.get()); |
| 204 return; | 209 return; |
| 205 } | 210 } |
| 206 fInheritedKey.reset(that.fInheritedKey.count()); | 211 fInheritedKey.reset(that.fInheritedKey.count()); |
| 207 memcpy(fInheritedKey.get(), that.fInheritedKey.get(), | 212 memcpy(fInheritedKey.get(), that.fInheritedKey.get(), |
| 208 sizeof(uint32_t) * fInheritedKey.count()); | 213 sizeof(uint32_t) * fInheritedKey.count()); |
| 209 } | 214 } |
| 210 | 215 |
| 211 GrShape::GrShape(const GrShape& parent, bool stopAfterPE) { | 216 GrShape::GrShape(const GrShape& parent, bool stopAfterPE) { |
| 212 fType = Type::kEmpty; | 217 fType = Type::kEmpty; |
| 213 SkPathEffect* pe = parent.fStyle.pathEffect(); | 218 SkPathEffect* pe = parent.fStyle.pathEffect(); |
| 214 const SkPath* inPath; | 219 const SkPath* inPath; |
| 215 SkStrokeRec strokeRec = parent.fStyle.strokeRec(); | 220 SkStrokeRec strokeRec = parent.fStyle.strokeRec(); |
| 221 bool appliedPE = false; |
| 216 if (pe) { | 222 if (pe) { |
| 217 fType = Type::kPath; | 223 fType = Type::kPath; |
| 218 fPath.init(); | 224 fPath.init(); |
| 219 if (parent.fType == Type::kPath) { | 225 if (parent.fType == Type::kPath) { |
| 220 inPath = parent.fPath.get(); | 226 inPath = parent.fPath.get(); |
| 221 } else { | 227 } else { |
| 222 inPath = fPath.get(); | 228 inPath = fPath.get(); |
| 223 parent.asPath(fPath.get()); | 229 parent.asPath(fPath.get()); |
| 224 } | 230 } |
| 225 // Should we consider bounds? Would have to include in key, but it'd be
nice to know | 231 // Should we consider bounds? Would have to include in key, but it'd be
nice to know |
| 226 // if the bounds actually modified anything before including in key. | 232 // if the bounds actually modified anything before including in key. |
| 227 if (!pe->filterPath(fPath.get(), *inPath, &strokeRec, nullptr)) { | 233 if (!pe->filterPath(fPath.get(), *inPath, &strokeRec, nullptr)) { |
| 228 // Make an empty unstyled shape if filtering fails. | 234 // Make an empty unstyled shape if filtering fails. |
| 229 fType = Type::kEmpty; | 235 fType = Type::kEmpty; |
| 230 fStyle = GrStyle(); | 236 fStyle = GrStyle(); |
| 231 fPath.reset(); | 237 fPath.reset(); |
| 232 return; | 238 return; |
| 233 } | 239 } |
| 240 appliedPE = true; |
| 234 inPath = fPath.get(); | 241 inPath = fPath.get(); |
| 235 } else if (stopAfterPE || !strokeRec.needToApply()) { | 242 } else if (stopAfterPE || !strokeRec.needToApply()) { |
| 236 *this = parent; | 243 *this = parent; |
| 237 return; | 244 return; |
| 238 } else { | 245 } else { |
| 239 fType = Type::kPath; | 246 fType = Type::kPath; |
| 240 fPath.init(); | 247 fPath.init(); |
| 241 if (parent.fType == Type::kPath) { | 248 if (parent.fType == Type::kPath) { |
| 242 inPath = parent.fPath.get(); | 249 inPath = parent.fPath.get(); |
| 243 } else { | 250 } else { |
| 244 inPath = fPath.get(); | 251 inPath = fPath.get(); |
| 245 parent.asPath(fPath.get()); | 252 parent.asPath(fPath.get()); |
| 246 } | 253 } |
| 247 } | 254 } |
| 255 const GrShape* effectiveParent = &parent; |
| 256 SkTLazy<GrShape> tmpParent; |
| 248 if (!stopAfterPE) { | 257 if (!stopAfterPE) { |
| 258 if (appliedPE) { |
| 259 // If the intermediate shape from just the PE is not a path then we
capture that here |
| 260 // so that we can pass the non-path parent to setInheritedKey. |
| 261 SkRRect rrect; |
| 262 Type parentType = AttemptToReduceFromPathImpl(*fPath.get(), &rrect,
nullptr, strokeRec); |
| 263 switch (parentType) { |
| 264 case Type::kEmpty: |
| 265 tmpParent.init(); |
| 266 effectiveParent = tmpParent.get(); |
| 267 break; |
| 268 case Type::kRRect: |
| 269 tmpParent.init(rrect, GrStyle(strokeRec, nullptr)); |
| 270 effectiveParent = tmpParent.get(); |
| 271 case Type::kPath: |
| 272 break; |
| 273 } |
| 274 } |
| 249 strokeRec.applyToPath(fPath.get(), *inPath); | 275 strokeRec.applyToPath(fPath.get(), *inPath); |
| 250 } else { | 276 } else { |
| 251 fStyle = GrStyle(strokeRec, nullptr); | 277 fStyle = GrStyle(strokeRec, nullptr); |
| 252 } | 278 } |
| 253 this->setInheritedKey(parent, stopAfterPE); | 279 this->attemptToReduceFromPath(); |
| 280 this->setInheritedKey(*effectiveParent, stopAfterPE); |
| 254 } | 281 } |
| OLD | NEW |