OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrAtlasTextBlob.h" | 8 #include "GrAtlasTextBlob.h" |
9 | 9 |
10 void GrAtlasTextBlob::appendGlyph(int runIndex, | 10 void GrAtlasTextBlob::appendGlyph(int runIndex, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 | 79 |
80 // V3 | 80 // V3 |
81 position = reinterpret_cast<SkPoint*>(vertex); | 81 position = reinterpret_cast<SkPoint*>(vertex); |
82 position->set(positions.fRight, positions.fTop); | 82 position->set(positions.fRight, positions.fTop); |
83 } | 83 } |
84 subRun->appendVertices(vertexStride); | 84 subRun->appendVertices(vertexStride); |
85 fGlyphs[subRun->glyphEndIndex()] = glyph; | 85 fGlyphs[subRun->glyphEndIndex()] = glyph; |
86 subRun->glyphAppended(); | 86 subRun->glyphAppended(); |
87 } | 87 } |
88 | 88 |
| 89 bool GrAtlasTextBlob::mustRegenerate(SkScalar* outTransX, SkScalar* outTransY, |
| 90 const SkPaint& paint, |
| 91 GrColor color, const SkMaskFilter::BlurRec&
blurRec, |
| 92 const SkMatrix& viewMatrix, SkScalar x, SkS
calar y) { |
| 93 // If we have LCD text then our canonical color will be set to transparent,
in this case we have |
| 94 // to regenerate the blob on any color change |
| 95 // We use the grPaint to get any color filter effects |
| 96 if (fKey.fCanonicalColor == SK_ColorTRANSPARENT && |
| 97 fPaintColor != color) { |
| 98 return true; |
| 99 } |
| 100 |
| 101 if (fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { |
| 102 return true; |
| 103 } |
| 104 |
| 105 if (fViewMatrix.hasPerspective() && !fViewMatrix.cheapEqualTo(viewMatrix)) { |
| 106 return true; |
| 107 } |
| 108 |
| 109 // We only cache one masked version |
| 110 if (fKey.fHasBlur && |
| 111 (fBlurRec.fSigma != blurRec.fSigma || |
| 112 fBlurRec.fStyle != blurRec.fStyle || |
| 113 fBlurRec.fQuality != blurRec.fQuality)) { |
| 114 return true; |
| 115 } |
| 116 |
| 117 // Similarly, we only cache one version for each style |
| 118 if (fKey.fStyle != SkPaint::kFill_Style && |
| 119 (fStrokeInfo.fFrameWidth != paint.getStrokeWidth() || |
| 120 fStrokeInfo.fMiterLimit != paint.getStrokeMiter() || |
| 121 fStrokeInfo.fJoin != paint.getStrokeJoin())) { |
| 122 return true; |
| 123 } |
| 124 |
| 125 // Mixed blobs must be regenerated. We could probably figure out a way to d
o integer scrolls |
| 126 // for mixed blobs if this becomes an issue. |
| 127 if (this->hasBitmap() && this->hasDistanceField()) { |
| 128 // Identical viewmatrices and we can reuse in all cases |
| 129 if (fViewMatrix.cheapEqualTo(viewMatrix) && x == fX && y == fY) { |
| 130 return false; |
| 131 } |
| 132 return true; |
| 133 } |
| 134 |
| 135 if (this->hasBitmap()) { |
| 136 if (fViewMatrix.getScaleX() != viewMatrix.getScaleX() || |
| 137 fViewMatrix.getScaleY() != viewMatrix.getScaleY() || |
| 138 fViewMatrix.getSkewX() != viewMatrix.getSkewX() || |
| 139 fViewMatrix.getSkewY() != viewMatrix.getSkewY()) { |
| 140 return true; |
| 141 } |
| 142 |
| 143 // We can update the positions in the cachedtextblobs without regenerati
ng the whole blob, |
| 144 // but only for integer translations. |
| 145 // This cool bit of math will determine the necessary translation to app
ly to the already |
| 146 // generated vertex coordinates to move them to the correct position |
| 147 SkScalar transX = viewMatrix.getTranslateX() + |
| 148 viewMatrix.getScaleX() * (x - fX) + |
| 149 viewMatrix.getSkewX() * (y - fY) - |
| 150 fViewMatrix.getTranslateX(); |
| 151 SkScalar transY = viewMatrix.getTranslateY() + |
| 152 viewMatrix.getSkewY() * (x - fX) + |
| 153 viewMatrix.getScaleY() * (y - fY) - |
| 154 fViewMatrix.getTranslateY(); |
| 155 if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY) ) { |
| 156 return true; |
| 157 } |
| 158 |
| 159 (*outTransX) = transX; |
| 160 (*outTransY) = transY; |
| 161 } else if (this->hasDistanceField()) { |
| 162 // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would resul
t in a different |
| 163 // distance field being generated, so we have to regenerate in those cas
es |
| 164 SkScalar newMaxScale = viewMatrix.getMaxScale(); |
| 165 SkScalar oldMaxScale = fViewMatrix.getMaxScale(); |
| 166 SkScalar scaleAdjust = newMaxScale / oldMaxScale; |
| 167 if (scaleAdjust < fMaxMinScale || scaleAdjust > fMinMaxScale) { |
| 168 return true; |
| 169 } |
| 170 |
| 171 (*outTransX) = x - fX; |
| 172 (*outTransY) = y - fY; |
| 173 } |
| 174 |
| 175 |
| 176 // If we can reuse the blob, then make sure we update the blob's viewmatrix,
and x/y |
| 177 // offsets. Note, we offset the vertex bounds right before flushing |
| 178 fViewMatrix = viewMatrix; |
| 179 fX = x; |
| 180 fY = y; |
| 181 |
| 182 // It is possible that a blob has neither distanceField nor bitmaptext. Thi
s is in the case |
| 183 // when all of the runs inside the blob are drawn as paths. In this case, w
e always regenerate |
| 184 // the blob anyways at flush time, so no need to regenerate explicitly |
| 185 return false; |
| 186 } |
| 187 |
89 // TODO get this code building again | 188 // TODO get this code building again |
90 #ifdef CACHE_SANITY_CHECK | 189 #ifdef CACHE_SANITY_CHECK |
91 void GrAtlasTextBlob::AssertEqual(const GrAtlasTextBlob& l, const GrAtlasTextBlo
b& r) { | 190 void GrAtlasTextBlob::AssertEqual(const GrAtlasTextBlob& l, const GrAtlasTextBlo
b& r) { |
92 SkASSERT(l.fSize == r.fSize); | 191 SkASSERT(l.fSize == r.fSize); |
93 SkASSERT(l.fPool == r.fPool); | 192 SkASSERT(l.fPool == r.fPool); |
94 | 193 |
95 SkASSERT(l.fBlurRec.fSigma == r.fBlurRec.fSigma); | 194 SkASSERT(l.fBlurRec.fSigma == r.fBlurRec.fSigma); |
96 SkASSERT(l.fBlurRec.fStyle == r.fBlurRec.fStyle); | 195 SkASSERT(l.fBlurRec.fStyle == r.fBlurRec.fStyle); |
97 SkASSERT(l.fBlurRec.fQuality == r.fBlurRec.fQuality); | 196 SkASSERT(l.fBlurRec.fQuality == r.fBlurRec.fQuality); |
98 | 197 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 rSubRun.fBulkUseToken.fPlotAlreadyUpdated); | 279 rSubRun.fBulkUseToken.fPlotAlreadyUpdated); |
181 for (int k = 0; k < lSubRun.fBulkUseToken.fPlotsToUpdate.count(); k+
+) { | 280 for (int k = 0; k < lSubRun.fBulkUseToken.fPlotsToUpdate.count(); k+
+) { |
182 SkASSERT(lSubRun.fBulkUseToken.fPlotsToUpdate[k] == | 281 SkASSERT(lSubRun.fBulkUseToken.fPlotsToUpdate[k] == |
183 rSubRun.fBulkUseToken.fPlotsToUpdate[k]); | 282 rSubRun.fBulkUseToken.fPlotsToUpdate[k]); |
184 }*/ | 283 }*/ |
185 } | 284 } |
186 } | 285 } |
187 } | 286 } |
188 | 287 |
189 #endif | 288 #endif |
OLD | NEW |