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

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

Issue 1275393003: Fix for 510931, merge to m44 (Closed) Base URL: https://skia.googlesource.com/skia.git@m44
Patch Set: Created 5 years, 4 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/GrAtlasTextContext.h ('k') | src/gpu/GrBatchAtlas.h » ('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 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 #include "GrAtlasTextContext.h" 7 #include "GrAtlasTextContext.h"
8 8
9 #include "GrBatch.h" 9 #include "GrBatch.h"
10 #include "GrBatchFontCache.h" 10 #include "GrBatchFontCache.h"
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 Sk48Dot16 fy = SkScalarTo48Dot16(y + halfSampleY); 868 Sk48Dot16 fy = SkScalarTo48Dot16(y + halfSampleY);
869 869
870 while (text < stop) { 870 while (text < stop) {
871 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy Mask); 871 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fy Mask);
872 872
873 fx += autokern.adjust(glyph); 873 fx += autokern.adjust(glyph);
874 874
875 if (glyph.fWidth) { 875 if (glyph.fWidth) {
876 this->bmpAppendGlyph(blob, 876 this->bmpAppendGlyph(blob,
877 runIndex, 877 runIndex,
878 GrGlyph::Pack(glyph.getGlyphID(), 878 glyph,
879 glyph.getSubXFixed(),
880 glyph.getSubYFixed(),
881 GrGlyph::kCoverage_MaskStyle),
882 Sk48Dot16FloorToInt(fx), 879 Sk48Dot16FloorToInt(fx),
883 Sk48Dot16FloorToInt(fy), 880 Sk48Dot16FloorToInt(fy),
884 color, 881 color,
885 fontScaler, 882 fontScaler,
886 clipRect); 883 clipRect);
887 } 884 }
888 885
889 fx += glyph.fAdvanceX; 886 fx += glyph.fAdvanceX;
890 fy += glyph.fAdvanceY; 887 fy += glyph.fAdvanceY;
891 } 888 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 tmsProc(pos, &tmsLoc); 935 tmsProc(pos, &tmsLoc);
939 Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + halfSampleX); 936 Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + halfSampleX);
940 Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + halfSampleY); 937 Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + halfSampleY);
941 938
942 const SkGlyph& glyph = glyphCacheProc(cache, &text, 939 const SkGlyph& glyph = glyphCacheProc(cache, &text,
943 fx & fxMask, fy & fyMask); 940 fx & fxMask, fy & fyMask);
944 941
945 if (glyph.fWidth) { 942 if (glyph.fWidth) {
946 this->bmpAppendGlyph(blob, 943 this->bmpAppendGlyph(blob,
947 runIndex, 944 runIndex,
948 GrGlyph::Pack(glyph.getGlyphID(), 945 glyph,
949 glyph.getSubXFixed(),
950 glyph.getSubYFixed(),
951 GrGlyph::kCoverage_MaskSt yle),
952 Sk48Dot16FloorToInt(fx), 946 Sk48Dot16FloorToInt(fx),
953 Sk48Dot16FloorToInt(fy), 947 Sk48Dot16FloorToInt(fy),
954 color, 948 color,
955 fontScaler, 949 fontScaler,
956 clipRect); 950 clipRect);
957 } 951 }
958 pos += scalarsPerPosition; 952 pos += scalarsPerPosition;
959 } 953 }
960 } else { 954 } else {
961 while (text < stop) { 955 while (text < stop) {
(...skipping 14 matching lines...) Expand all
976 // have to call again, now that we've been "aligned" 970 // have to call again, now that we've been "aligned"
977 const SkGlyph& glyph = glyphCacheProc(cache, &currentText, 971 const SkGlyph& glyph = glyphCacheProc(cache, &currentText,
978 fx & fxMask, fy & fyMa sk); 972 fx & fxMask, fy & fyMa sk);
979 // the assumption is that the metrics haven't changed 973 // the assumption is that the metrics haven't changed
980 SkASSERT(prevAdvX == glyph.fAdvanceX); 974 SkASSERT(prevAdvX == glyph.fAdvanceX);
981 SkASSERT(prevAdvY == glyph.fAdvanceY); 975 SkASSERT(prevAdvY == glyph.fAdvanceY);
982 SkASSERT(glyph.fWidth); 976 SkASSERT(glyph.fWidth);
983 977
984 this->bmpAppendGlyph(blob, 978 this->bmpAppendGlyph(blob,
985 runIndex, 979 runIndex,
986 GrGlyph::Pack(glyph.getGlyphID(), 980 glyph,
987 glyph.getSubXFixed(),
988 glyph.getSubYFixed(),
989 GrGlyph::kCoverage_MaskSt yle),
990 Sk48Dot16FloorToInt(fx), 981 Sk48Dot16FloorToInt(fx),
991 Sk48Dot16FloorToInt(fy), 982 Sk48Dot16FloorToInt(fy),
992 color, 983 color,
993 fontScaler, 984 fontScaler,
994 clipRect); 985 clipRect);
995 } 986 }
996 pos += scalarsPerPosition; 987 pos += scalarsPerPosition;
997 } 988 }
998 } 989 }
999 } else { // not subpixel 990 } else { // not subpixel
1000 991
1001 if (SkPaint::kLeft_Align == skPaint.getTextAlign()) { 992 if (SkPaint::kLeft_Align == skPaint.getTextAlign()) {
1002 while (text < stop) { 993 while (text < stop) {
1003 // the last 2 parameters are ignored 994 // the last 2 parameters are ignored
1004 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 995 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1005 996
1006 if (glyph.fWidth) { 997 if (glyph.fWidth) {
1007 SkPoint tmsLoc; 998 SkPoint tmsLoc;
1008 tmsProc(pos, &tmsLoc); 999 tmsProc(pos, &tmsLoc);
1009 1000
1010 Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf); //halfSampleX; 1001 Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf); //halfSampleX;
1011 Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf); //halfSampleY; 1002 Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf); //halfSampleY;
1012 this->bmpAppendGlyph(blob, 1003 this->bmpAppendGlyph(blob,
1013 runIndex, 1004 runIndex,
1014 GrGlyph::Pack(glyph.getGlyphID(), 1005 glyph,
1015 glyph.getSubXFixed(),
1016 glyph.getSubYFixed(),
1017 GrGlyph::kCoverage_MaskSt yle),
1018 Sk48Dot16FloorToInt(fx), 1006 Sk48Dot16FloorToInt(fx),
1019 Sk48Dot16FloorToInt(fy), 1007 Sk48Dot16FloorToInt(fy),
1020 color, 1008 color,
1021 fontScaler, 1009 fontScaler,
1022 clipRect); 1010 clipRect);
1023 } 1011 }
1024 pos += scalarsPerPosition; 1012 pos += scalarsPerPosition;
1025 } 1013 }
1026 } else { 1014 } else {
1027 while (text < stop) { 1015 while (text < stop) {
1028 // the last 2 parameters are ignored 1016 // the last 2 parameters are ignored
1029 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 1017 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1030 1018
1031 if (glyph.fWidth) { 1019 if (glyph.fWidth) {
1032 SkPoint tmsLoc; 1020 SkPoint tmsLoc;
1033 tmsProc(pos, &tmsLoc); 1021 tmsProc(pos, &tmsLoc);
1034 1022
1035 SkPoint alignLoc; 1023 SkPoint alignLoc;
1036 alignProc(tmsLoc, glyph, &alignLoc); 1024 alignProc(tmsLoc, glyph, &alignLoc);
1037 1025
1038 Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf ); //halfSampleX; 1026 Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf ); //halfSampleX;
1039 Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf ); //halfSampleY; 1027 Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf ); //halfSampleY;
1040 this->bmpAppendGlyph(blob, 1028 this->bmpAppendGlyph(blob,
1041 runIndex, 1029 runIndex,
1042 GrGlyph::Pack(glyph.getGlyphID(), 1030 glyph,
1043 glyph.getSubXFixed(),
1044 glyph.getSubYFixed(),
1045 GrGlyph::kCoverage_MaskSt yle),
1046 Sk48Dot16FloorToInt(fx), 1031 Sk48Dot16FloorToInt(fx),
1047 Sk48Dot16FloorToInt(fy), 1032 Sk48Dot16FloorToInt(fy),
1048 color, 1033 color,
1049 fontScaler, 1034 fontScaler,
1050 clipRect); 1035 clipRect);
1051 } 1036 }
1052 pos += scalarsPerPosition; 1037 pos += scalarsPerPosition;
1053 } 1038 }
1054 } 1039 }
1055 } 1040 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 const char* lastText = text; 1146 const char* lastText = text;
1162 // the last 2 parameters are ignored 1147 // the last 2 parameters are ignored
1163 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 1148 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1164 1149
1165 if (glyph.fWidth) { 1150 if (glyph.fWidth) {
1166 SkScalar x = offset.x() + pos[0]; 1151 SkScalar x = offset.x() + pos[0];
1167 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; 1152 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ;
1168 1153
1169 if (!this->dfAppendGlyph(blob, 1154 if (!this->dfAppendGlyph(blob,
1170 runIndex, 1155 runIndex,
1171 GrGlyph::Pack(glyph.getGlyphID(), 1156 glyph,
1172 glyph.getSubXFixed(),
1173 glyph.getSubYFixed(),
1174 GrGlyph::kDistance_MaskSt yle),
1175 x, y, color, fontScaler, clipRect, 1157 x, y, color, fontScaler, clipRect,
1176 textRatio, viewMatrix)) { 1158 textRatio, viewMatrix)) {
1177 // couldn't append, send to fallback 1159 // couldn't append, send to fallback
1178 fallbackTxt->append(SkToInt(text-lastText), lastText); 1160 fallbackTxt->append(SkToInt(text-lastText), lastText);
1179 *fallbackPos->append() = pos[0]; 1161 *fallbackPos->append() = pos[0];
1180 if (2 == scalarsPerPosition) { 1162 if (2 == scalarsPerPosition) {
1181 *fallbackPos->append() = pos[1]; 1163 *fallbackPos->append() = pos[1];
1182 } 1164 }
1183 } 1165 }
1184 } 1166 }
1185 pos += scalarsPerPosition; 1167 pos += scalarsPerPosition;
1186 } 1168 }
1187 } else { 1169 } else {
1188 SkScalar alignMul = SkPaint::kCenter_Align == skPaint.getTextAlign() ? S K_ScalarHalf 1170 SkScalar alignMul = SkPaint::kCenter_Align == skPaint.getTextAlign() ? S K_ScalarHalf
1189 : S K_Scalar1; 1171 : S K_Scalar1;
1190 while (text < stop) { 1172 while (text < stop) {
1191 const char* lastText = text; 1173 const char* lastText = text;
1192 // the last 2 parameters are ignored 1174 // the last 2 parameters are ignored
1193 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 1175 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1194 1176
1195 if (glyph.fWidth) { 1177 if (glyph.fWidth) {
1196 SkScalar x = offset.x() + pos[0]; 1178 SkScalar x = offset.x() + pos[0];
1197 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ; 1179 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0) ;
1198 1180
1199 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX) * alignMul * textRatio; 1181 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX) * alignMul * textRatio;
1200 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY) * alignMul * textRatio; 1182 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY) * alignMul * textRatio;
1201 1183
1202 if (!this->dfAppendGlyph(blob, 1184 if (!this->dfAppendGlyph(blob,
1203 runIndex, 1185 runIndex,
1204 GrGlyph::Pack(glyph.getGlyphID(), 1186 glyph,
1205 glyph.getSubXFixed(),
1206 glyph.getSubYFixed(),
1207 GrGlyph::kDistance_MaskSt yle),
1208 x - advanceX, y - advanceY, color, 1187 x - advanceX, y - advanceY, color,
1209 fontScaler, 1188 fontScaler,
1210 clipRect, 1189 clipRect,
1211 textRatio, 1190 textRatio,
1212 viewMatrix)) { 1191 viewMatrix)) {
1213 // couldn't append, send to fallback 1192 // couldn't append, send to fallback
1214 fallbackTxt->append(SkToInt(text-lastText), lastText); 1193 fallbackTxt->append(SkToInt(text-lastText), lastText);
1215 *fallbackPos->append() = pos[0]; 1194 *fallbackPos->append() = pos[0];
1216 if (2 == scalarsPerPosition) { 1195 if (2 == scalarsPerPosition) {
1217 *fallbackPos->append() = pos[1]; 1196 *fallbackPos->append() = pos[1];
1218 } 1197 }
1219 } 1198 }
1220 } 1199 }
1221 pos += scalarsPerPosition; 1200 pos += scalarsPerPosition;
1222 } 1201 }
1223 } 1202 }
1224 } 1203 }
1225 1204
1226 void GrAtlasTextContext::bmpAppendGlyph(BitmapTextBlob* blob, int runIndex, 1205 void GrAtlasTextContext::bmpAppendGlyph(BitmapTextBlob* blob, int runIndex,
1227 GrGlyph::PackedID packed, 1206 const SkGlyph& skGlyph,
1228 int vx, int vy, GrColor color, GrFontSca ler* scaler, 1207 int vx, int vy, GrColor color, GrFontSca ler* scaler,
1229 const SkIRect& clipRect) { 1208 const SkIRect& clipRect) {
1230 Run& run = blob->fRuns[runIndex]; 1209 Run& run = blob->fRuns[runIndex];
1231 if (!fCurrStrike) { 1210 if (!fCurrStrike) {
1232 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); 1211 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler);
1233 run.fStrike.reset(SkRef(fCurrStrike));
1234 } 1212 }
1235 1213
1236 GrGlyph* glyph = fCurrStrike->getGlyph(packed, scaler); 1214 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
1215 skGlyph.getSubXFixed(),
1216 skGlyph.getSubYFixed(),
1217 GrGlyph::kCoverage_MaskStyle);
1218 GrGlyph* glyph = fCurrStrike->getGlyph(skGlyph, id, scaler);
1237 if (!glyph) { 1219 if (!glyph) {
1238 return; 1220 return;
1239 } 1221 }
1240 1222
1241 int x = vx + glyph->fBounds.fLeft; 1223 int x = vx + glyph->fBounds.fLeft;
1242 int y = vy + glyph->fBounds.fTop; 1224 int y = vy + glyph->fBounds.fTop;
1243 1225
1244 // keep them as ints until we've done the clip-test 1226 // keep them as ints until we've done the clip-test
1245 int width = glyph->fBounds.width(); 1227 int width = glyph->fBounds.width();
1246 int height = glyph->fBounds.height(); 1228 int height = glyph->fBounds.height();
1247 1229
1248 #if 0 1230 #if 0
1249 // Not checking the clip bounds might introduce a performance regression. H owever, its not 1231 // Not checking the clip bounds might introduce a performance regression. H owever, its not
1250 // clear if this is still true today with the larger tiles we use in Chrome. For repositionable 1232 // clear if this is still true today with the larger tiles we use in Chrome. For repositionable
1251 // blobs, we want to make sure we have all of the glyphs, so clipping them o ut is not ideal. 1233 // blobs, we want to make sure we have all of the glyphs, so clipping them o ut is not ideal.
1252 // We could store the cliprect in the key, but then we'd lose the ability to do integer scrolls 1234 // We could store the cliprect in the key, but then we'd lose the ability to do integer scrolls
1253 // TODO verify this 1235 // TODO verify this
1254 // check if we clipped out 1236 // check if we clipped out
1255 if (clipRect.quickReject(x, y, x + width, y + height)) { 1237 if (clipRect.quickReject(x, y, x + width, y + height)) {
1256 return; 1238 return;
1257 } 1239 }
1258 #endif 1240 #endif
1259 1241
1260 // If the glyph is too large we fall back to paths 1242 // If the glyph is too large we fall back to paths
1261 if (glyph->fTooLargeForAtlas) { 1243 if (glyph->fTooLargeForAtlas) {
1262 this->appendGlyphPath(blob, glyph, scaler, SkIntToScalar(vx), SkIntToSca lar(vy)); 1244 this->appendGlyphPath(blob, glyph, scaler, skGlyph, SkIntToScalar(vx), S kIntToScalar(vy));
1263 return; 1245 return;
1264 } 1246 }
1265 1247
1266 GrMaskFormat format = glyph->fMaskFormat; 1248 GrMaskFormat format = glyph->fMaskFormat;
1267 1249
1268 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); 1250 PerSubRunInfo* subRun = &run.fSubRunInfo.back();
1269 if (run.fInitialized && subRun->fMaskFormat != format) { 1251 if (run.fInitialized && subRun->fMaskFormat != format) {
1270 subRun = &run.fSubRunInfo.push_back(); 1252 subRun = &run.push_back();
1253 subRun->fStrike.reset(SkRef(fCurrStrike));
1254 } else if (!run.fInitialized) {
1255 subRun->fStrike.reset(SkRef(fCurrStrike));
1271 } 1256 }
1272 1257
1273 run.fInitialized = true; 1258 run.fInitialized = true;
1274 1259
1275 size_t vertexStride = get_vertex_stride(format); 1260 size_t vertexStride = get_vertex_stride(format);
1276 1261
1277 SkRect r; 1262 SkRect r;
1278 r.fLeft = SkIntToScalar(x); 1263 r.fLeft = SkIntToScalar(x);
1279 r.fTop = SkIntToScalar(y); 1264 r.fTop = SkIntToScalar(y);
1280 r.fRight = r.fLeft + SkIntToScalar(width); 1265 r.fRight = r.fLeft + SkIntToScalar(width);
1281 r.fBottom = r.fTop + SkIntToScalar(height); 1266 r.fBottom = r.fTop + SkIntToScalar(height);
1282 subRun->fMaskFormat = format; 1267 subRun->fMaskFormat = format;
1283 this->appendGlyphCommon(blob, &run, subRun, r, color, vertexStride, kA8_GrMa skFormat == format, 1268 this->appendGlyphCommon(blob, &run, subRun, r, color, vertexStride, kA8_GrMa skFormat == format,
1284 glyph); 1269 glyph);
1285 } 1270 }
1286 1271
1287 bool GrAtlasTextContext::dfAppendGlyph(BitmapTextBlob* blob, int runIndex, 1272 bool GrAtlasTextContext::dfAppendGlyph(BitmapTextBlob* blob, int runIndex,
1288 GrGlyph::PackedID packed, 1273 const SkGlyph& skGlyph,
1289 SkScalar sx, SkScalar sy, GrColor color, 1274 SkScalar sx, SkScalar sy, GrColor color,
1290 GrFontScaler* scaler, 1275 GrFontScaler* scaler,
1291 const SkIRect& clipRect, 1276 const SkIRect& clipRect,
1292 SkScalar textRatio, const SkMatrix& viewM atrix) { 1277 SkScalar textRatio, const SkMatrix& viewM atrix) {
1293 Run& run = blob->fRuns[runIndex]; 1278 Run& run = blob->fRuns[runIndex];
1294 if (!fCurrStrike) { 1279 if (!fCurrStrike) {
1295 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler); 1280 fCurrStrike = fContext->getBatchFontCache()->getStrike(scaler);
1296 run.fStrike.reset(SkRef(fCurrStrike));
1297 } 1281 }
1298 1282
1299 GrGlyph* glyph = fCurrStrike->getGlyph(packed, scaler); 1283 GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
1284 skGlyph.getSubXFixed(),
1285 skGlyph.getSubYFixed(),
1286 GrGlyph::kDistance_MaskStyle);
1287 GrGlyph* glyph = fCurrStrike->getGlyph(skGlyph, id, scaler);
1300 if (!glyph) { 1288 if (!glyph) {
1301 return true; 1289 return true;
1302 } 1290 }
1303 1291
1304 // fallback to color glyph support 1292 // fallback to color glyph support
1305 if (kA8_GrMaskFormat != glyph->fMaskFormat) { 1293 if (kA8_GrMaskFormat != glyph->fMaskFormat) {
1306 return false; 1294 return false;
1307 } 1295 }
1308 1296
1309 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); 1297 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset);
(...skipping 18 matching lines...) Expand all
1328 SkScalarTruncToInt(dstRect.top()), 1316 SkScalarTruncToInt(dstRect.top()),
1329 SkScalarTruncToInt(dstRect.right()), 1317 SkScalarTruncToInt(dstRect.right()),
1330 SkScalarTruncToInt(dstRect.bottom()))) { 1318 SkScalarTruncToInt(dstRect.bottom()))) {
1331 return true; 1319 return true;
1332 } 1320 }
1333 #endif 1321 #endif
1334 1322
1335 // TODO combine with the above 1323 // TODO combine with the above
1336 // If the glyph is too large we fall back to paths 1324 // If the glyph is too large we fall back to paths
1337 if (glyph->fTooLargeForAtlas) { 1325 if (glyph->fTooLargeForAtlas) {
1338 this->appendGlyphPath(blob, glyph, scaler, sx - dx, sy - dy); 1326 this->appendGlyphPath(blob, glyph, scaler, skGlyph, sx - dx, sy - dy);
1339 return true; 1327 return true;
1340 } 1328 }
1341 1329
1342 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); 1330 PerSubRunInfo* subRun = &run.fSubRunInfo.back();
1331 if (!run.fInitialized) {
1332 subRun->fStrike.reset(SkRef(fCurrStrike));
1333 }
1334 run.fInitialized = true;
1343 SkASSERT(glyph->fMaskFormat == kA8_GrMaskFormat); 1335 SkASSERT(glyph->fMaskFormat == kA8_GrMaskFormat);
1344 subRun->fMaskFormat = kA8_GrMaskFormat; 1336 subRun->fMaskFormat = kA8_GrMaskFormat;
1345 1337
1346 size_t vertexStride = get_vertex_stride_df(kA8_GrMaskFormat, subRun->fUseLCD Text); 1338 size_t vertexStride = get_vertex_stride_df(kA8_GrMaskFormat, subRun->fUseLCD Text);
1347 1339
1348 bool useColorVerts = !subRun->fUseLCDText; 1340 bool useColorVerts = !subRun->fUseLCDText;
1349 this->appendGlyphCommon(blob, &run, subRun, glyphRect, color, vertexStride, useColorVerts, 1341 this->appendGlyphCommon(blob, &run, subRun, glyphRect, color, vertexStride, useColorVerts,
1350 glyph); 1342 glyph);
1351 return true; 1343 return true;
1352 } 1344 }
1353 1345
1354 inline void GrAtlasTextContext::appendGlyphPath(BitmapTextBlob* blob, GrGlyph* g lyph, 1346 inline void GrAtlasTextContext::appendGlyphPath(BitmapTextBlob* blob, GrGlyph* g lyph,
1355 GrFontScaler* scaler, SkScalar x , SkScalar y) { 1347 GrFontScaler* scaler, const SkGl yph& skGlyph,
1348 SkScalar x, SkScalar y) {
1356 if (NULL == glyph->fPath) { 1349 if (NULL == glyph->fPath) {
1357 SkPath* path = SkNEW(SkPath); 1350 const SkPath* glyphPath = scaler->getGlyphPath(skGlyph);
1358 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { 1351 if (!glyphPath) {
1359 // flag the glyph as being dead?
1360 SkDELETE(path);
1361 return; 1352 return;
1362 } 1353 }
1363 glyph->fPath = path; 1354
1355 glyph->fPath = SkNEW_ARGS(SkPath, (*glyphPath));
1364 } 1356 }
1365 SkASSERT(glyph->fPath);
1366 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, x, y)); 1357 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, x, y));
1367 } 1358 }
1368 1359
1369 inline void GrAtlasTextContext::appendGlyphCommon(BitmapTextBlob* blob, Run* run , 1360 inline void GrAtlasTextContext::appendGlyphCommon(BitmapTextBlob* blob, Run* run ,
1370 Run::SubRunInfo* subRun, 1361 Run::SubRunInfo* subRun,
1371 const SkRect& positions, GrCol or color, 1362 const SkRect& positions, GrCol or color,
1372 size_t vertexStride, bool useV ertexColor, 1363 size_t vertexStride, bool useV ertexColor,
1373 GrGlyph* glyph) { 1364 GrGlyph* glyph) {
1374 blob->fGlyphs[subRun->fGlyphEndIndex] = glyph; 1365 blob->fGlyphs[subRun->fGlyphEndIndex] = glyph;
1375 run->fVertexBounds.joinNonEmptyArg(positions); 1366 run->fVertexBounds.joinNonEmptyArg(positions);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 SkTypeface* typeface = NULL; 1569 SkTypeface* typeface = NULL;
1579 1570
1580 for (int i = 0; i < instanceCount; i++) { 1571 for (int i = 0; i < instanceCount; i++) {
1581 Geometry& args = fGeoData[i]; 1572 Geometry& args = fGeoData[i];
1582 Blob* blob = args.fBlob; 1573 Blob* blob = args.fBlob;
1583 Run& run = blob->fRuns[args.fRun]; 1574 Run& run = blob->fRuns[args.fRun];
1584 TextInfo& info = run.fSubRunInfo[args.fSubRun]; 1575 TextInfo& info = run.fSubRunInfo[args.fSubRun];
1585 1576
1586 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); 1577 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat);
1587 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen || 1578 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen ||
1588 run.fStrike->isAbandoned(); 1579 info.fStrike->isAbandoned();
1589 bool regenerateColors; 1580 bool regenerateColors;
1590 if (fUseDistanceFields) { 1581 if (fUseDistanceFields) {
1591 regenerateColors = !fUseLCDText && run.fColor != args.fColor; 1582 regenerateColors = !fUseLCDText && run.fColor != args.fColor;
1592 } else { 1583 } else {
1593 regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor; 1584 regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor;
1594 } 1585 }
1595 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0. f; 1586 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0. f;
1596 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; 1587 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
1597 1588
1598 // We regenerate both texture coords and colors in the blob itself, and update the 1589 // We regenerate both texture coords and colors in the blob itself, and update the
(...skipping 27 matching lines...) Expand all
1626 run.fOverrideDescriptor->getDe sc() : 1617 run.fOverrideDescriptor->getDe sc() :
1627 run.fDescriptor.getDesc(); 1618 run.fDescriptor.getDesc();
1628 if (!cache || !SkTypeface::Equal(typeface, run.fTypeface) || 1619 if (!cache || !SkTypeface::Equal(typeface, run.fTypeface) ||
1629 !(desc->equals(*newDesc))) { 1620 !(desc->equals(*newDesc))) {
1630 if (cache) { 1621 if (cache) {
1631 SkGlyphCache::AttachCache(cache); 1622 SkGlyphCache::AttachCache(cache);
1632 } 1623 }
1633 desc = newDesc; 1624 desc = newDesc;
1634 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); 1625 cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
1635 scaler = GrTextContext::GetGrFontScaler(cache); 1626 scaler = GrTextContext::GetGrFontScaler(cache);
1636 strike = run.fStrike; 1627 strike = info.fStrike;
1637 typeface = run.fTypeface; 1628 typeface = run.fTypeface;
1638 } 1629 }
1639 1630
1640 if (run.fStrike->isAbandoned()) { 1631 if (info.fStrike->isAbandoned()) {
1641 regenerateGlyphs = true; 1632 regenerateGlyphs = true;
1642 strike = fFontCache->getStrike(scaler); 1633 strike = fFontCache->getStrike(scaler);
1643 } else { 1634 } else {
1644 strike = run.fStrike; 1635 strike = info.fStrike;
1645 } 1636 }
1646 } 1637 }
1647 1638
1648 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { 1639 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
1649 if (regenerateTextureCoords) { 1640 if (regenerateTextureCoords) {
1650 size_t glyphOffset = glyphIdx + info.fGlyphStartIndex; 1641 size_t glyphOffset = glyphIdx + info.fGlyphStartIndex;
1651 GrGlyph* glyph; 1642
1643 GrGlyph* glyph = blob->fGlyphs[glyphOffset];
1644 GrGlyph::PackedID id = glyph->fPackedID;
1645 const SkGlyph& skGlyph = scaler->grToSkGlyph(id);
1652 if (regenerateGlyphs) { 1646 if (regenerateGlyphs) {
1653 // Get the id from the old glyph, and use the new st rike to lookup 1647 // Get the id from the old glyph, and use the new st rike to lookup
1654 // the glyph. 1648 // the glyph.
1655 glyph = blob->fGlyphs[glyphOffset]; 1649 blob->fGlyphs[glyphOffset] = strike->getGlyph(skGlyp h, id, fMaskFormat,
1656 blob->fGlyphs[glyphOffset] = strike->getGlyph(glyph- >fPackedID,
1657 scaler ); 1650 scaler );
1658 } 1651 }
1659 glyph = blob->fGlyphs[glyphOffset]; 1652 glyph = blob->fGlyphs[glyphOffset];
1660 SkASSERT(glyph); 1653 SkASSERT(glyph);
1661 1654
1662 if (!fFontCache->hasGlyph(glyph) && 1655 if (!fFontCache->hasGlyph(glyph) &&
1663 !strike->addGlyphToAtlas(batchTarget, glyph, scaler) ) { 1656 !strike->addGlyphToAtlas(batchTarget, glyph, scaler, skGlyph,
1657 fMaskFormat)) {
1664 this->flush(batchTarget, &flushInfo); 1658 this->flush(batchTarget, &flushInfo);
1665 this->initDraw(batchTarget, gp, pipeline); 1659 this->initDraw(batchTarget, gp, pipeline);
1666 brokenRun = glyphIdx > 0; 1660 brokenRun = glyphIdx > 0;
1667 1661
1668 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas( batchTarget, 1662 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas( batchTarget,
1669 glyph, 1663 glyph,
1670 scaler); 1664 scaler,
1665 skGlyph,
1666 fMaskFormat);
1671 SkASSERT(success); 1667 SkASSERT(success);
1672 } 1668 }
1673 fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseT oken, glyph, 1669 fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseT oken, glyph,
1674 batchTarget->cu rrentToken()); 1670 batchTarget->cu rrentToken());
1675 1671
1676 // Texture coords are the last vertex attribute so we ge t a pointer to the 1672 // Texture coords are the last vertex attribute so we ge t a pointer to the
1677 // first one and then map with stride in regenerateTextu reCoords 1673 // first one and then map with stride in regenerateTextu reCoords
1678 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices); 1674 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices);
1679 vertex += info.fVertexStartIndex; 1675 vertex += info.fVertexStartIndex;
1680 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; 1676 vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
(...skipping 17 matching lines...) Expand all
1698 SkScalar transY = args.fTransY; 1694 SkScalar transY = args.fTransY;
1699 this->regeneratePositions(vertex, vertexStride, transX, transY); 1695 this->regeneratePositions(vertex, vertexStride, transX, transY);
1700 } 1696 }
1701 flushInfo.fGlyphsToFlush++; 1697 flushInfo.fGlyphsToFlush++;
1702 } 1698 }
1703 1699
1704 // We my have changed the color so update it here 1700 // We my have changed the color so update it here
1705 run.fColor = args.fColor; 1701 run.fColor = args.fColor;
1706 if (regenerateTextureCoords) { 1702 if (regenerateTextureCoords) {
1707 if (regenerateGlyphs) { 1703 if (regenerateGlyphs) {
1708 run.fStrike.reset(SkRef(strike)); 1704 info.fStrike.reset(SkRef(strike));
1709 } 1705 }
1710 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration : 1706 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration :
1711 fFontCache->atlasGenerat ion(fMaskFormat); 1707 fFontCache->atlasGenerat ion(fMaskFormat);
1712 } 1708 }
1713 } else { 1709 } else {
1714 flushInfo.fGlyphsToFlush += glyphCount; 1710 flushInfo.fGlyphsToFlush += glyphCount;
1715 1711
1716 // set use tokens for all of the glyphs in our subrun. This is only valid if we 1712 // set use tokens for all of the glyphs in our subrun. This is only valid if we
1717 // have a valid atlas generation 1713 // have a valid atlas generation
1718 fFontCache->setUseTokenBulk(info.fBulkUseToken, 1714 fFontCache->setUseTokenBulk(info.fBulkUseToken,
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
2277 gTextContext->createDrawTextBlob(rt, clip, grPaint, skPaint, viewMat rix, text, 2273 gTextContext->createDrawTextBlob(rt, clip, grPaint, skPaint, viewMat rix, text,
2278 static_cast<size_t>(textLen), 0, 0, noClip)); 2274 static_cast<size_t>(textLen), 0, 0, noClip));
2279 2275
2280 SkScalar transX = static_cast<SkScalar>(random->nextU()); 2276 SkScalar transX = static_cast<SkScalar>(random->nextU());
2281 SkScalar transY = static_cast<SkScalar>(random->nextU()); 2277 SkScalar transY = static_cast<SkScalar>(random->nextU());
2282 const GrAtlasTextContext::BitmapTextBlob::Run::SubRunInfo& info = blob->fRun s[0].fSubRunInfo[0]; 2278 const GrAtlasTextContext::BitmapTextBlob::Run::SubRunInfo& info = blob->fRun s[0].fSubRunInfo[0];
2283 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t ransY, skPaint); 2279 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t ransY, skPaint);
2284 } 2280 }
2285 2281
2286 #endif 2282 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrAtlasTextContext.h ('k') | src/gpu/GrBatchAtlas.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698