| 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 "GrAtlasTextBlob.h" | 8 #include "GrAtlasTextBlob.h" | 
| 9 | 9 | 
| 10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" | 
| 11 #include "GrTextUtils.h" | 11 #include "GrTextUtils.h" | 
| 12 | 12 | 
| 13 #include "SkDistanceFieldGen.h" | 13 #include "SkDistanceFieldGen.h" | 
| 14 #include "SkGlyphCache.h" | 14 #include "SkGlyphCache.h" | 
| 15 | 15 | 
| 16 #include "batches/GrAtlasTextBatch.h" | 16 #include "batches/GrAtlasTextBatch.h" | 
| 17 | 17 | 
| 18 ////////////////////////////////////////////////////////////////////////////////
     //////////////////// | 18 ////////////////////////////////////////////////////////////////////////////////
     //////////////////// | 
| 19 // A large template to handle regenerating the vertices of a textblob with as fe
     w branches as | 19 // A large template to handle regenerating the vertices of a textblob with as fe
     w branches as | 
| 20 // possible | 20 // possible | 
| 21 template <bool regenPos, bool regenCol, bool regenTexCoords> | 21 template <bool regenPos, bool regenCol, bool regenTexCoords> | 
| 22 inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS
     tride, | 22 inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS
     tride, | 
| 23                            bool useDistanceFields, SkScalar transX, SkScalar tra
     nsY, | 23                            bool useDistanceFields, SkScalar transX, SkScalar tra
     nsY, | 
| 24                            int32_t log2Width, int32_t log2Height, |  | 
| 25                            GrColor color) { | 24                            GrColor color) { | 
| 26     int u0, v0, u1, v1; | 25     int u0, v0, u1, v1; | 
| 27     if (regenTexCoords) { | 26     if (regenTexCoords) { | 
| 28         SkASSERT(glyph); | 27         SkASSERT(glyph); | 
| 29         int width = glyph->fBounds.width(); | 28         int width = glyph->fBounds.width(); | 
| 30         int height = glyph->fBounds.height(); | 29         int height = glyph->fBounds.height(); | 
| 31 | 30 | 
| 32         if (useDistanceFields) { | 31         if (useDistanceFields) { | 
| 33             u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset; | 32             u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset; | 
| 34             v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset; | 33             v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset; | 
| 35             u1 = u0 + width - 2 * SK_DistanceFieldInset; | 34             u1 = u0 + width - 2 * SK_DistanceFieldInset; | 
| 36             v1 = v0 + height - 2 * SK_DistanceFieldInset; | 35             v1 = v0 + height - 2 * SK_DistanceFieldInset; | 
| 37         } else { | 36         } else { | 
| 38             u0 = glyph->fAtlasLocation.fX; | 37             u0 = glyph->fAtlasLocation.fX; | 
| 39             v0 = glyph->fAtlasLocation.fY; | 38             v0 = glyph->fAtlasLocation.fY; | 
| 40             u1 = u0 + width; | 39             u1 = u0 + width; | 
| 41             v1 = v0 + height; | 40             v1 = v0 + height; | 
| 42         } | 41         } | 
| 43 |  | 
| 44         // normalize |  | 
| 45         u0 *= 65535; |  | 
| 46         u0 >>= log2Width; |  | 
| 47         u1 *= 65535; |  | 
| 48         u1 >>= log2Width; |  | 
| 49         v0 *= 65535; |  | 
| 50         v0 >>= log2Height; |  | 
| 51         v1 *= 65535; |  | 
| 52         v1 >>= log2Height; |  | 
| 53         SkASSERT(u0 >= 0 && u0 <= 65535); |  | 
| 54         SkASSERT(u1 >= 0 && u1 <= 65535); |  | 
| 55         SkASSERT(v0 >= 0 && v0 <= 65535); |  | 
| 56         SkASSERT(v1 >= 0 && v1 <= 65535); |  | 
| 57     } | 42     } | 
| 58 | 43 | 
| 59     // This is a bit wonky, but sometimes we have LCD text, in which case we won
     't have color | 44     // This is a bit wonky, but sometimes we have LCD text, in which case we won
     't have color | 
| 60     // vertices, hence vertexStride - sizeof(SkIPoint16) | 45     // vertices, hence vertexStride - sizeof(SkIPoint16) | 
| 61     intptr_t colorOffset = sizeof(SkPoint); | 46     intptr_t colorOffset = sizeof(SkPoint); | 
| 62     intptr_t texCoordOffset = vertexStride - sizeof(SkIPoint16); | 47     intptr_t texCoordOffset = vertexStride - sizeof(SkIPoint16); | 
| 63 | 48 | 
| 64     // V0 | 49     // V0 | 
| 65     if (regenPos) { | 50     if (regenPos) { | 
| 66         SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 51         SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 
| 67         point->fX += transX; | 52         point->fX += transX; | 
| 68         point->fY += transY; | 53         point->fY += transY; | 
| 69     } | 54     } | 
| 70 | 55 | 
| 71     if (regenCol) { | 56     if (regenCol) { | 
| 72         SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); | 57         SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); | 
| 73         *vcolor = color; | 58         *vcolor = color; | 
| 74     } | 59     } | 
| 75 | 60 | 
| 76     if (regenTexCoords) { | 61     if (regenTexCoords) { | 
| 77         uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordO
     ffset); | 62         SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCo
     ordOffset); | 
| 78         textureCoords[0] = (uint16_t) u0; | 63         textureCoords->set(u0, v0); | 
| 79         textureCoords[1] = (uint16_t) v0; |  | 
| 80     } | 64     } | 
| 81     vertex += vertexStride; | 65     vertex += vertexStride; | 
| 82 | 66 | 
| 83     // V1 | 67     // V1 | 
| 84     if (regenPos) { | 68     if (regenPos) { | 
| 85         SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 69         SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 
| 86         point->fX += transX; | 70         point->fX += transX; | 
| 87         point->fY += transY; | 71         point->fY += transY; | 
| 88     } | 72     } | 
| 89 | 73 | 
| 90     if (regenCol) { | 74     if (regenCol) { | 
| 91         SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); | 75         SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); | 
| 92         *vcolor = color; | 76         *vcolor = color; | 
| 93     } | 77     } | 
| 94 | 78 | 
| 95     if (regenTexCoords) { | 79     if (regenTexCoords) { | 
| 96         uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordO
     ffset); | 80         SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCo
     ordOffset); | 
| 97         textureCoords[0] = (uint16_t)u0; | 81         textureCoords->set(u0, v1); | 
| 98         textureCoords[1] = (uint16_t)v1; |  | 
| 99     } | 82     } | 
| 100     vertex += vertexStride; | 83     vertex += vertexStride; | 
| 101 | 84 | 
| 102     // V2 | 85     // V2 | 
| 103     if (regenPos) { | 86     if (regenPos) { | 
| 104         SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 87         SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 
| 105         point->fX += transX; | 88         point->fX += transX; | 
| 106         point->fY += transY; | 89         point->fY += transY; | 
| 107     } | 90     } | 
| 108 | 91 | 
| 109     if (regenCol) { | 92     if (regenCol) { | 
| 110         SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); | 93         SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); | 
| 111         *vcolor = color; | 94         *vcolor = color; | 
| 112     } | 95     } | 
| 113 | 96 | 
| 114     if (regenTexCoords) { | 97     if (regenTexCoords) { | 
| 115         uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordO
     ffset); | 98         SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCo
     ordOffset); | 
| 116         textureCoords[0] = (uint16_t)u1; | 99         textureCoords->set(u1, v1); | 
| 117         textureCoords[1] = (uint16_t)v1; |  | 
| 118     } | 100     } | 
| 119     vertex += vertexStride; | 101     vertex += vertexStride; | 
| 120 | 102 | 
| 121     // V3 | 103     // V3 | 
| 122     if (regenPos) { | 104     if (regenPos) { | 
| 123         SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 105         SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 
| 124         point->fX += transX; | 106         point->fX += transX; | 
| 125         point->fY += transY; | 107         point->fY += transY; | 
| 126     } | 108     } | 
| 127 | 109 | 
| 128     if (regenCol) { | 110     if (regenCol) { | 
| 129         SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); | 111         SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); | 
| 130         *vcolor = color; | 112         *vcolor = color; | 
| 131     } | 113     } | 
| 132 | 114 | 
| 133     if (regenTexCoords) { | 115     if (regenTexCoords) { | 
| 134         uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordO
     ffset); | 116         SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCo
     ordOffset); | 
| 135         textureCoords[0] = (uint16_t)u1; | 117         textureCoords->set(u1, v0); | 
| 136         textureCoords[1] = (uint16_t)v0; |  | 
| 137     } | 118     } | 
| 138 } | 119 } | 
| 139 | 120 | 
| 140 template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> | 121 template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> | 
| 141 void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, | 122 void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, | 
| 142                                    GrBatchFontCache* fontCache, | 123                                    GrBatchFontCache* fontCache, | 
| 143                                    GrBlobRegenHelper *helper, | 124                                    GrBlobRegenHelper *helper, | 
| 144                                    Run* run, | 125                                    Run* run, | 
| 145                                    Run::SubRunInfo* info, SkGlyphCache** cache, | 126                                    Run::SubRunInfo* info, SkGlyphCache** cache, | 
| 146                                    SkTypeface** typeface, GrFontScaler** scaler, | 127                                    SkTypeface** typeface, GrFontScaler** scaler, | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 173         if (regenGlyphs) { | 154         if (regenGlyphs) { | 
| 174             strike = fontCache->getStrike(*scaler); | 155             strike = fontCache->getStrike(*scaler); | 
| 175         } else { | 156         } else { | 
| 176             strike = info->strike(); | 157             strike = info->strike(); | 
| 177         } | 158         } | 
| 178     } | 159     } | 
| 179 | 160 | 
| 180     bool brokenRun = false; | 161     bool brokenRun = false; | 
| 181     for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { | 162     for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { | 
| 182         GrGlyph* glyph = nullptr; | 163         GrGlyph* glyph = nullptr; | 
| 183         int log2Width = 0, log2Height = 0; |  | 
| 184         if (regenTexCoords) { | 164         if (regenTexCoords) { | 
| 185             size_t glyphOffset = glyphIdx + info->glyphStartIndex(); | 165             size_t glyphOffset = glyphIdx + info->glyphStartIndex(); | 
| 186 | 166 | 
| 187             if (regenGlyphs) { | 167             if (regenGlyphs) { | 
| 188                 // Get the id from the old glyph, and use the new strike to look
     up | 168                 // Get the id from the old glyph, and use the new strike to look
     up | 
| 189                 // the glyph. | 169                 // the glyph. | 
| 190                 GrGlyph::PackedID id = fGlyphs[glyphOffset]->fPackedID; | 170                 GrGlyph::PackedID id = fGlyphs[glyphOffset]->fPackedID; | 
| 191                 fGlyphs[glyphOffset] = strike->getGlyph(id, info->maskFormat(), 
     *scaler); | 171                 fGlyphs[glyphOffset] = strike->getGlyph(id, info->maskFormat(), 
     *scaler); | 
| 192                 SkASSERT(id == fGlyphs[glyphOffset]->fPackedID); | 172                 SkASSERT(id == fGlyphs[glyphOffset]->fPackedID); | 
| 193             } | 173             } | 
| 194             glyph = fGlyphs[glyphOffset]; | 174             glyph = fGlyphs[glyphOffset]; | 
| 195             SkASSERT(glyph && glyph->fMaskFormat == info->maskFormat()); | 175             SkASSERT(glyph && glyph->fMaskFormat == info->maskFormat()); | 
| 196 | 176 | 
| 197             if (!fontCache->hasGlyph(glyph) && | 177             if (!fontCache->hasGlyph(glyph) && | 
| 198                 !strike->addGlyphToAtlas(target, glyph, *scaler, info->maskForma
     t())) { | 178                 !strike->addGlyphToAtlas(target, glyph, *scaler, info->maskForma
     t())) { | 
| 199                 helper->flush(); | 179                 helper->flush(); | 
| 200                 brokenRun = glyphIdx > 0; | 180                 brokenRun = glyphIdx > 0; | 
| 201 | 181 | 
| 202                 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target, | 182                 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target, | 
| 203                                                                     glyph, | 183                                                                     glyph, | 
| 204                                                                     *scaler, | 184                                                                     *scaler, | 
| 205                                                                     info->maskFo
     rmat()); | 185                                                                     info->maskFo
     rmat()); | 
| 206                 SkASSERT(success); | 186                 SkASSERT(success); | 
| 207             } | 187             } | 
| 208             fontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph, | 188             fontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph, | 
| 209                                                     target->currentToken()); | 189                                                     target->currentToken()); | 
| 210             log2Width = fontCache->log2Width(info->maskFormat()); |  | 
| 211             log2Height = fontCache->log2Height(info->maskFormat()); |  | 
| 212         } | 190         } | 
| 213 | 191 | 
| 214         intptr_t vertex = reinterpret_cast<intptr_t>(fVertices); | 192         intptr_t vertex = reinterpret_cast<intptr_t>(fVertices); | 
| 215         vertex += info->vertexStartIndex(); | 193         vertex += info->vertexStartIndex(); | 
| 216         vertex += vertexStride * glyphIdx * GrAtlasTextBatch::kVerticesPerGlyph; | 194         vertex += vertexStride * glyphIdx * GrAtlasTextBatch::kVerticesPerGlyph; | 
| 217         regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertex
     Stride, | 195         regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertex
     Stride, | 
| 218                                                            info->drawAsDistanceF
     ields(), transX, | 196                                                            info->drawAsDistanceF
     ields(), transX, | 
| 219                                                            transY, log2Width, lo
     g2Height, color); | 197                                                            transY, color); | 
| 220         helper->incGlyphCount(); | 198         helper->incGlyphCount(); | 
| 221     } | 199     } | 
| 222 | 200 | 
| 223     // We may have changed the color so update it here | 201     // We may have changed the color so update it here | 
| 224     info->setColor(color); | 202     info->setColor(color); | 
| 225     if (regenTexCoords) { | 203     if (regenTexCoords) { | 
| 226         if (regenGlyphs) { | 204         if (regenGlyphs) { | 
| 227             info->setStrike(strike); | 205             info->setStrike(strike); | 
| 228         } | 206         } | 
| 229         info->setAtlasGeneration(brokenRun ? GrBatchAtlas::kInvalidAtlasGenerati
     on : | 207         info->setAtlasGeneration(brokenRun ? GrBatchAtlas::kInvalidAtlasGenerati
     on : | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 308             // set use tokens for all of the glyphs in our subrun.  This is only
      valid if we | 286             // set use tokens for all of the glyphs in our subrun.  This is only
      valid if we | 
| 309             // have a valid atlas generation | 287             // have a valid atlas generation | 
| 310             fontCache->setUseTokenBulk(*info.bulkUseToken(), target->currentToke
     n(), | 288             fontCache->setUseTokenBulk(*info.bulkUseToken(), target->currentToke
     n(), | 
| 311                                         info.maskFormat()); | 289                                         info.maskFormat()); | 
| 312             break; | 290             break; | 
| 313     } | 291     } | 
| 314 | 292 | 
| 315     *byteCount = info.byteCount(); | 293     *byteCount = info.byteCount(); | 
| 316     *vertices = fVertices + info.vertexStartIndex(); | 294     *vertices = fVertices + info.vertexStartIndex(); | 
| 317 } | 295 } | 
| OLD | NEW | 
|---|