11d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt/* 21d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * Copyright 2015 Google Inc. 31d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * 41d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * Use of this source code is governed by a BSD-style license that can be 51d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * found in the LICENSE file. 61d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt */ 71d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 81d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt#ifndef GrAtlasTextContext_DEFINED 91d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt#define GrAtlasTextContext_DEFINED 101d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 111d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt#include "GrTextContext.h" 121d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 13b4c507e03386f2105e33f0c4c09b4a9d0a23196djoshualitt#include "GrBatchAtlas.h" 14ae32c102e70577bff1432ef4b4b63ca6835012f6joshualitt#include "GrBatchFontCache.h" 151d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt#include "GrGeometryProcessor.h" 161d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt#include "SkDescriptor.h" 17b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt#include "GrMemoryPool.h" 1853b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt#include "SkMaskFilter.h" 199a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt#include "SkTextBlob.h" 20b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt#include "SkTInternalLList.h" 211d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 2279dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt#ifdef GR_TEST_UTILS 2379dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt#include "GrBatchTest.h" 2479dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt#endif 2579dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt 2679dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualittclass BitmapTextBatch; 271d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualittclass GrPipelineBuilder; 28b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualittclass GrTextBlobCache; 291d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 301d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt/* 311d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * This class implements GrTextContext using standard bitmap fonts, and can also process textblobs. 321d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * TODO replace GrBitmapTextContext 331d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt */ 34dbd3593e0b0cfb04f23b9d7bce623e6e32364b3fjoshualittclass GrAtlasTextContext : public GrTextContext { 351d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualittpublic: 369bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt static GrAtlasTextContext* Create(GrContext*, SkGpuDevice*, const SkDeviceProperties&, 379bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt bool enableDistanceFields); 381d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 391d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualittprivate: 409bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt GrAtlasTextContext(GrContext*, SkGpuDevice*, const SkDeviceProperties&, 419bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt bool enableDistanceFields); 429bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt ~GrAtlasTextContext() override {} 431d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 441d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&, 451d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const SkPaint&, const SkMatrix& viewMatrix) override; 461d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 471d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, 481d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const SkMatrix& viewMatrix, const char text[], size_t byteLength, 491d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override; 501d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, 511d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const SkMatrix& viewMatrix, 521d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const char text[], size_t byteLength, 531d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const SkScalar pos[], int scalarsPerPosition, 541d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const SkPoint& offset, const SkIRect& regionClipBounds) override; 551d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&, 561d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y, 571d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt SkDrawFilter*, const SkIRect& clipBounds) override; 581d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 591d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt /* 601d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * A BitmapTextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing 611d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * on the GPU. These are initially created with valid positions and colors, but invalid 621d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * texture coordinates. The BitmapTextBlob itself has a few Blob-wide properties, and also 631d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * consists of a number of runs. Runs inside a blob are flushed individually so they can be 641d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * reordered. 651d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * 661d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * The only thing(aside from a memcopy) required to flush a BitmapTextBlob is to ensure that 671d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt * the GrAtlas will not evict anything the Blob needs. 681d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt */ 691d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt struct BitmapTextBlob : public SkRefCnt { 70b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt SK_DECLARE_INTERNAL_LLIST_INTERFACE(BitmapTextBlob); 71b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt 729a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt /* 739a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * Each Run inside of the blob can have its texture coordinates regenerated if required. 749a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * To determine if regeneration is necessary, fAtlasGeneration is used. If there have been 759a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * any evictions inside of the atlas, then we will simply regenerate Runs. We could track 769a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * this at a more fine grained level, but its not clear if this is worth it, as evictions 779a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * should be fairly rare. 789a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * 799a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * One additional point, each run can contain glyphs with any of the three mask formats. 809a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * We call these SubRuns. Because a subrun must be a contiguous range, we have to create 819a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * a new subrun each time the mask format changes in a run. In theory, a run can have as 829a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * many SubRuns as it has glyphs, ie if a run alternates between color emoji and A8. In 839a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * practice, the vast majority of runs have only a single subrun. 849a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * 859a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * Finally, for runs where the entire thing is too large for the GrAtlasTextContext to 869a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * handle, we have a bit to mark the run as flusahable via rendering as paths. It is worth 879a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * pointing. It would be a bit expensive to figure out ahead of time whether or not a run 889a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * can flush in this manner, so we always allocate vertices for the run, regardless of 899a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * whether or not it is too large. The benefit of this strategy is that we can always reuse 909a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * a blob allocation regardless of viewmatrix changes. We could store positions for these 919a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * glyphs. However, its not clear if this is a win because we'd still have to either go the 929a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * glyph cache to get the path at flush time, or hold onto the path in the cache, which 939a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt * would greatly increase the memory of these cached items. 949a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt */ 951d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt struct Run { 96c3c5990ac0f1063eb92a98b98a71314b5b5ef7e8joshualitt Run() 97c3c5990ac0f1063eb92a98b98a71314b5b5ef7e8joshualitt : fColor(GrColor_ILLEGAL) 98c3c5990ac0f1063eb92a98b98a71314b5b5ef7e8joshualitt , fInitialized(false) 99c3c5990ac0f1063eb92a98b98a71314b5b5ef7e8joshualitt , fDrawAsPaths(false) { 1001d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt fVertexBounds.setLargestInverted(); 10197202d2821c2b9e997d36146ecb9711e02fd7734joshualitt // To ensure we always have one subrun, we push back a fresh run here 10297202d2821c2b9e997d36146ecb9711e02fd7734joshualitt fSubRunInfo.push_back(); 1031d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt } 1041d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt struct SubRunInfo { 1051d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt SubRunInfo() 1061d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) 1071d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt , fVertexStartIndex(0) 1089bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt , fVertexEndIndex(0) 1098672f4dffa4b298d4cabee6151590ae885d47263joshualitt , fGlyphStartIndex(0) 1108672f4dffa4b298d4cabee6151590ae885d47263joshualitt , fGlyphEndIndex(0) 1119bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt , fDrawAsDistanceFields(false) {} 112fec19e1751d1a20748e9beaf0a948c01ffe89f04joshualitt // Distance field text cannot draw coloremoji, and so has to fall back. However, 113fec19e1751d1a20748e9beaf0a948c01ffe89f04joshualitt // though the distance field text and the coloremoji may share the same run, they 114fec19e1751d1a20748e9beaf0a948c01ffe89f04joshualitt // will have different descriptors. If fOverrideDescriptor is non-NULL, then it 115fec19e1751d1a20748e9beaf0a948c01ffe89f04joshualitt // will be used in place of the run's descriptor to regen texture coords 116fec19e1751d1a20748e9beaf0a948c01ffe89f04joshualitt // TODO we could have a descriptor cache, it would reduce the size of these blobs 117fec19e1751d1a20748e9beaf0a948c01ffe89f04joshualitt // significantly, and then the subrun could just have a refed pointer to the 118fec19e1751d1a20748e9beaf0a948c01ffe89f04joshualitt // correct descriptor. 1198672f4dffa4b298d4cabee6151590ae885d47263joshualitt GrBatchAtlas::BulkUseTokenUpdater fBulkUseToken; 1208672f4dffa4b298d4cabee6151590ae885d47263joshualitt uint64_t fAtlasGeneration; 1218672f4dffa4b298d4cabee6151590ae885d47263joshualitt size_t fVertexStartIndex; 1228672f4dffa4b298d4cabee6151590ae885d47263joshualitt size_t fVertexEndIndex; 1238672f4dffa4b298d4cabee6151590ae885d47263joshualitt uint32_t fGlyphStartIndex; 1248672f4dffa4b298d4cabee6151590ae885d47263joshualitt uint32_t fGlyphEndIndex; 1258672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkScalar fTextRatio; // df property 1268672f4dffa4b298d4cabee6151590ae885d47263joshualitt GrMaskFormat fMaskFormat; 1278672f4dffa4b298d4cabee6151590ae885d47263joshualitt bool fDrawAsDistanceFields; // df property 1288672f4dffa4b298d4cabee6151590ae885d47263joshualitt bool fUseLCDText; // df property 1291d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt }; 130c3c5990ac0f1063eb92a98b98a71314b5b5ef7e8joshualitt 13197202d2821c2b9e997d36146ecb9711e02fd7734joshualitt SubRunInfo& push_back() { 13297202d2821c2b9e997d36146ecb9711e02fd7734joshualitt // Forward glyph / vertex information to seed the new sub run 13397202d2821c2b9e997d36146ecb9711e02fd7734joshualitt SubRunInfo& prevSubRun = fSubRunInfo.back(); 13497202d2821c2b9e997d36146ecb9711e02fd7734joshualitt SubRunInfo& newSubRun = fSubRunInfo.push_back(); 13597202d2821c2b9e997d36146ecb9711e02fd7734joshualitt newSubRun.fGlyphStartIndex = prevSubRun.fGlyphEndIndex; 13697202d2821c2b9e997d36146ecb9711e02fd7734joshualitt newSubRun.fGlyphEndIndex = prevSubRun.fGlyphEndIndex; 137c3c5990ac0f1063eb92a98b98a71314b5b5ef7e8joshualitt 13897202d2821c2b9e997d36146ecb9711e02fd7734joshualitt newSubRun.fVertexStartIndex = prevSubRun.fVertexEndIndex; 13997202d2821c2b9e997d36146ecb9711e02fd7734joshualitt newSubRun.fVertexEndIndex = prevSubRun.fVertexEndIndex; 14097202d2821c2b9e997d36146ecb9711e02fd7734joshualitt return newSubRun; 14197202d2821c2b9e997d36146ecb9711e02fd7734joshualitt } 14297202d2821c2b9e997d36146ecb9711e02fd7734joshualitt static const int kMinSubRuns = 1; 143ae32c102e70577bff1432ef4b4b63ca6835012f6joshualitt SkAutoTUnref<GrBatchTextStrike> fStrike; 1441d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt SkAutoTUnref<SkTypeface> fTypeface; 1451d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt SkRect fVertexBounds; 14697202d2821c2b9e997d36146ecb9711e02fd7734joshualitt SkSTArray<kMinSubRuns, SubRunInfo> fSubRunInfo; 1478672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkAutoDescriptor fDescriptor; 14897202d2821c2b9e997d36146ecb9711e02fd7734joshualitt SkAutoTDelete<SkAutoDescriptor> fOverrideDescriptor; // df properties 1491d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt GrColor fColor; 1501d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt bool fInitialized; 1519a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt bool fDrawAsPaths; 1521d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt }; 1531d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 1541d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt struct BigGlyph { 15519e4c02a4112f9a9c63247613c201dbba84110b4joshualitt BigGlyph(const SkPath& path, SkScalar vx, SkScalar vy) 15619e4c02a4112f9a9c63247613c201dbba84110b4joshualitt : fPath(path) 15719e4c02a4112f9a9c63247613c201dbba84110b4joshualitt , fVx(vx) 15819e4c02a4112f9a9c63247613c201dbba84110b4joshualitt , fVy(vy) {} 1591d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt SkPath fPath; 16019e4c02a4112f9a9c63247613c201dbba84110b4joshualitt SkScalar fVx; 16119e4c02a4112f9a9c63247613c201dbba84110b4joshualitt SkScalar fVy; 1621d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt }; 1631d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 16453b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt struct Key { 16553b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt Key() { 1669e36c1a9306f052331550dab4728b9875127bfb5joshualitt sk_bzero(this, sizeof(Key)); 16753b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt } 16853b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt uint32_t fUniqueID; 1699e36c1a9306f052331550dab4728b9875127bfb5joshualitt // Color may affect the gamma of the mask we generate, but in a fairly limited way. 1709e36c1a9306f052331550dab4728b9875127bfb5joshualitt // Each color is assigned to on of a fixed number of buckets based on its 1719e36c1a9306f052331550dab4728b9875127bfb5joshualitt // luminance. For each luminance bucket there is a "canonical color" that 1729e36c1a9306f052331550dab4728b9875127bfb5joshualitt // represents the bucket. This functionality is currently only supported for A8 1739e36c1a9306f052331550dab4728b9875127bfb5joshualitt SkColor fCanonicalColor; 174e4cee1f283c435618343f0c7b298207d5a9a3e1cjoshualitt SkPaint::Style fStyle; 175e4cee1f283c435618343f0c7b298207d5a9a3e1cjoshualitt SkPixelGeometry fPixelGeometry; 17653b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt bool fHasBlur; 17753b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt 17853b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt bool operator==(const Key& other) const { 17953b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt return 0 == memcmp(this, &other, sizeof(Key)); 18053b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt } 18153b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt }; 1828672f4dffa4b298d4cabee6151590ae885d47263joshualitt 1838672f4dffa4b298d4cabee6151590ae885d47263joshualitt struct StrokeInfo { 1848672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkScalar fFrameWidth; 1858672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkScalar fMiterLimit; 1868672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkPaint::Join fJoin; 1878672f4dffa4b298d4cabee6151590ae885d47263joshualitt }; 1888672f4dffa4b298d4cabee6151590ae885d47263joshualitt 1898672f4dffa4b298d4cabee6151590ae885d47263joshualitt enum TextType { 1908672f4dffa4b298d4cabee6151590ae885d47263joshualitt kHasDistanceField_TextType = 0x1, 1918672f4dffa4b298d4cabee6151590ae885d47263joshualitt kHasBitmap_TextType = 0x2, 1928672f4dffa4b298d4cabee6151590ae885d47263joshualitt }; 1938672f4dffa4b298d4cabee6151590ae885d47263joshualitt 1948672f4dffa4b298d4cabee6151590ae885d47263joshualitt // all glyph / vertex offsets are into these pools. 1958672f4dffa4b298d4cabee6151590ae885d47263joshualitt unsigned char* fVertices; 196ae32c102e70577bff1432ef4b4b63ca6835012f6joshualitt GrGlyph** fGlyphs; 1978672f4dffa4b298d4cabee6151590ae885d47263joshualitt Run* fRuns; 1988672f4dffa4b298d4cabee6151590ae885d47263joshualitt GrMemoryPool* fPool; 1998672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkMaskFilter::BlurRec fBlurRec; 2008672f4dffa4b298d4cabee6151590ae885d47263joshualitt StrokeInfo fStrokeInfo; 2018672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkTArray<BigGlyph> fBigGlyphs; 20253b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt Key fKey; 2038672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkMatrix fViewMatrix; 20464c99cc90e678feba473d38db420d31883cc53e6joshualitt SkColor fPaintColor; 2058672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkScalar fX; 2068672f4dffa4b298d4cabee6151590ae885d47263joshualitt SkScalar fY; 20764c99cc90e678feba473d38db420d31883cc53e6joshualitt 20864c99cc90e678feba473d38db420d31883cc53e6joshualitt // We can reuse distance field text, but only if the new viewmatrix would not result in 20964c99cc90e678feba473d38db420d31883cc53e6joshualitt // a mip change. Because there can be multiple runs in a blob, we track the overall 21064c99cc90e678feba473d38db420d31883cc53e6joshualitt // maximum minimum scale, and minimum maximum scale, we can support before we need to regen 21164c99cc90e678feba473d38db420d31883cc53e6joshualitt SkScalar fMaxMinScale; 21264c99cc90e678feba473d38db420d31883cc53e6joshualitt SkScalar fMinMaxScale; 2138672f4dffa4b298d4cabee6151590ae885d47263joshualitt int fRunCount; 2148672f4dffa4b298d4cabee6151590ae885d47263joshualitt uint8_t fTextType; 2158672f4dffa4b298d4cabee6151590ae885d47263joshualitt 21664c99cc90e678feba473d38db420d31883cc53e6joshualitt BitmapTextBlob() 217a7c6389ebf19cf58926f7a1616f0e5554c56aa84joshualitt : fMaxMinScale(-SK_ScalarMax) 21864c99cc90e678feba473d38db420d31883cc53e6joshualitt , fMinMaxScale(SK_ScalarMax) 21964c99cc90e678feba473d38db420d31883cc53e6joshualitt , fTextType(0) {} 22053b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt 22112c20e40a47a454049cda8240a9b3d8918ac06efjoshualitt ~BitmapTextBlob() override { 22212c20e40a47a454049cda8240a9b3d8918ac06efjoshualitt for (int i = 0; i < fRunCount; i++) { 22312c20e40a47a454049cda8240a9b3d8918ac06efjoshualitt fRuns[i].~Run(); 22412c20e40a47a454049cda8240a9b3d8918ac06efjoshualitt } 22512c20e40a47a454049cda8240a9b3d8918ac06efjoshualitt } 22612c20e40a47a454049cda8240a9b3d8918ac06efjoshualitt 22753b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt static const Key& GetKey(const BitmapTextBlob& blob) { 22853b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt return blob.fKey; 229b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt } 230b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt 23153b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt static uint32_t Hash(const Key& key) { 23253b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt return SkChecksum::Murmur3(&key, sizeof(Key)); 2331d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt } 2341d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 235b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt void operator delete(void* p) { 236b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt BitmapTextBlob* blob = reinterpret_cast<BitmapTextBlob*>(p); 237b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt blob->fPool->release(p); 238b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt } 2391d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt void* operator new(size_t) { 2401d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt SkFAIL("All blobs are created by placement new."); 2411d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt return sk_malloc_throw(0); 2421d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt } 2431d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 2441d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt void* operator new(size_t, void* p) { return p; } 2451d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt void operator delete(void* target, void* placement) { 2461d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt ::operator delete(target, placement); 2471d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt } 248fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt 249fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt bool hasDistanceField() const { return SkToBool(fTextType & kHasDistanceField_TextType); } 250fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt bool hasBitmap() const { return SkToBool(fTextType & kHasBitmap_TextType); } 251fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; } 252fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt void setHasBitmap() { fTextType |= kHasBitmap_TextType; } 2531d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt }; 2541d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 2551d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt typedef BitmapTextBlob::Run Run; 2561d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt typedef Run::SubRunInfo PerSubRunInfo; 2571d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 2589bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt inline bool canDrawAsDistanceFields(const SkPaint&, const SkMatrix& viewMatrix); 2599bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt BitmapTextBlob* setupDFBlob(int glyphCount, const SkPaint& origPaint, 2609bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkMatrix& viewMatrix, SkGlyphCache** cache, 2619bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkPaint* dfPaint, SkScalar* textRatio); 2629bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt void bmpAppendGlyph(BitmapTextBlob*, int runIndex, GrGlyph::PackedID, int left, int top, 2639bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt GrColor color, GrFontScaler*, const SkIRect& clipRect); 2649bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt bool dfAppendGlyph(BitmapTextBlob*, int runIndex, GrGlyph::PackedID, SkScalar sx, SkScalar sy, 2659bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt GrColor color, GrFontScaler*, const SkIRect& clipRect, SkScalar textRatio, 2669bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkMatrix& viewMatrix); 2679bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt inline void appendGlyphPath(BitmapTextBlob* blob, GrGlyph* glyph, 26819e4c02a4112f9a9c63247613c201dbba84110b4joshualitt GrFontScaler* scaler, SkScalar x, SkScalar y); 2699bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt inline void appendGlyphCommon(BitmapTextBlob*, Run*, Run::SubRunInfo*, 2709bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkRect& positions, GrColor color, 2719bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt size_t vertexStride, bool useVertexColor, 272ae32c102e70577bff1432ef4b4b63ca6835012f6joshualitt GrGlyph*); 2739a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt 2749a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt inline void flushRunAsPaths(const SkTextBlob::RunIterator&, const SkPaint&, SkDrawFilter*, 2759a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, 2769a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt SkScalar y); 27779dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt inline BitmapTextBatch* createBatch(BitmapTextBlob*, const PerSubRunInfo&, 27879dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt int glyphCount, int run, int subRun, 27979dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt GrColor, SkScalar transX, SkScalar transY, 28079dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const SkPaint&); 2819a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt inline void flushRun(GrDrawTarget*, GrPipelineBuilder*, BitmapTextBlob*, int run, GrColor, 2829bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkScalar transX, SkScalar transY, const SkPaint&); 2839a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt inline void flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRenderTarget* rt, 2841107e901c9dac3098e2915213f171ff62d007aa7joshualitt const SkPaint& skPaint, 2851107e901c9dac3098e2915213f171ff62d007aa7joshualitt SkScalar transX, SkScalar transY, const SkIRect& clipBounds); 2869a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt 2879a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt // We have to flush SkTextBlobs differently from drawText / drawPosText 2889a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt void flush(GrDrawTarget*, const SkTextBlob*, BitmapTextBlob*, GrRenderTarget*, const SkPaint&, 2899a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt const GrPaint&, SkDrawFilter*, const GrClip&, const SkMatrix& viewMatrix, 2902a0e9f36c6e823d2c0472ef23b4c5a247427807fjoshualitt const SkIRect& clipBounds, SkScalar x, SkScalar y, SkScalar transX, SkScalar transY); 2919a27e639481882b59a8ef123e0b69a9a719f08b9joshualitt void flush(GrDrawTarget*, BitmapTextBlob*, GrRenderTarget*, const SkPaint&, 2921107e901c9dac3098e2915213f171ff62d007aa7joshualitt const GrPaint&, const GrClip&, const SkIRect& clipBounds); 2939bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt 2949bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt // A helper for drawing BitmapText in a run of distance fields 295fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt inline void fallbackDrawPosText(BitmapTextBlob*, int runIndex, 296fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt GrRenderTarget*, const GrClip&, 2979bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const GrPaint&, 2989bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkPaint&, const SkMatrix& viewMatrix, 2999bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkTDArray<char>& fallbackTxt, 3009bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkTDArray<SkScalar>& fallbackPos, 3019bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt int scalarsPerPosition, 3029bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkPoint& offset, 3039bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkIRect& clipRect); 3041d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 3059bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt void internalDrawBMPText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&, 3069e36c1a9306f052331550dab4728b9875127bfb5joshualitt GrColor color, const SkMatrix& viewMatrix, 3071d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const char text[], size_t byteLength, 3089bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkScalar x, SkScalar y, const SkIRect& clipRect); 3099bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt void internalDrawBMPPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&, 3109bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt GrColor color, const SkMatrix& viewMatrix, 3119bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const char text[], size_t byteLength, 3129bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkScalar pos[], int scalarsPerPosition, 3139bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkPoint& offset, const SkIRect& clipRect); 3149bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt 3159bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt void internalDrawDFText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&, 3169bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt GrColor color, const SkMatrix& viewMatrix, 3179bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const char text[], size_t byteLength, 3189bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkScalar x, SkScalar y, const SkIRect& clipRect, 3199bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkScalar textRatio, 3209bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkTDArray<char>* fallbackTxt, 3219bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkTDArray<SkScalar>* fallbackPos, 3229bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkPoint* offset, const SkPaint& origPaint); 3239bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt void internalDrawDFPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&, 3249bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt GrColor color, const SkMatrix& viewMatrix, 3259bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const char text[], size_t byteLength, 3269bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkScalar pos[], int scalarsPerPosition, 3279bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkPoint& offset, const SkIRect& clipRect, 3289bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkScalar textRatio, 3299bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkTDArray<char>* fallbackTxt, 3309bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkTDArray<SkScalar>* fallbackPos); 3311d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 3321d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt // sets up the descriptor on the blob and returns a detached cache. Client must attach 3339e36c1a9306f052331550dab4728b9875127bfb5joshualitt inline static GrColor ComputeCanonicalColor(const SkPaint&, bool lcd); 3349bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt inline SkGlyphCache* setupCache(Run*, const SkPaint&, const SkMatrix* viewMatrix, bool noGamma); 3352a0e9f36c6e823d2c0472ef23b4c5a247427807fjoshualitt static inline bool MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY, 3362a0e9f36c6e823d2c0472ef23b4c5a247427807fjoshualitt const BitmapTextBlob&, const SkPaint&, 33753b5f4488b05c40254b24c718c2df9724a13c54ajoshualitt const SkMaskFilter::BlurRec&, 3381d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const SkMatrix& viewMatrix, SkScalar x, SkScalar y); 3399e36c1a9306f052331550dab4728b9875127bfb5joshualitt void regenerateTextBlob(BitmapTextBlob* bmp, const SkPaint& skPaint, GrColor, 3409e36c1a9306f052331550dab4728b9875127bfb5joshualitt const SkMatrix& viewMatrix, 3411d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt const SkTextBlob* blob, SkScalar x, SkScalar y, 342fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt SkDrawFilter* drawFilter, const SkIRect& clipRect, GrRenderTarget*, 343fcfb9fc4bde43fd375ce8e0d6583282dad4a1226joshualitt const GrClip&, const GrPaint&); 3449e36c1a9306f052331550dab4728b9875127bfb5joshualitt inline static bool HasLCD(const SkTextBlob*); 34564c99cc90e678feba473d38db420d31883cc53e6joshualitt inline void initDistanceFieldPaint(BitmapTextBlob*, SkPaint*, SkScalar* textRatio, 34664c99cc90e678feba473d38db420d31883cc53e6joshualitt const SkMatrix&); 3479bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt 34879dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt // Test methods 34979dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt // TODO this is really ugly. It'd be much nicer if positioning could be moved to batch 35079dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt inline BitmapTextBlob* createDrawTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&, 35179dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const SkPaint&, const SkMatrix& viewMatrix, 35279dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const char text[], size_t byteLength, 35379dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt SkScalar x, SkScalar y, 35479dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const SkIRect& regionClipBounds); 35579dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt inline BitmapTextBlob* createDrawPosTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&, 35679dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const SkPaint&, const SkMatrix& viewMatrix, 35779dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const char text[], size_t byteLength, 35879dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const SkScalar pos[], int scalarsPerPosition, 35979dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const SkPoint& offset, 36079dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt const SkIRect& regionClipBounds); 36179dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt 3629bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt // Distance field text needs this table to compute a value for use in the fragment shader. 3639bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt // Because the GrAtlasTextContext can go out of scope before the final flush, this needs to be 3649bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt // refcnted and malloced 3659bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt struct DistanceAdjustTable : public SkNVRefCnt<DistanceAdjustTable> { 3669bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt DistanceAdjustTable(float gamma) { this->buildDistanceAdjustTable(gamma); } 3679bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt ~DistanceAdjustTable() { SkDELETE_ARRAY(fTable); } 3689bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt 3699bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt void buildDistanceAdjustTable(float gamma); 3709bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt 3719bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkScalar& operator[] (int i) { 3729bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt return fTable[i]; 3739bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt } 3749bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt 3759bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt const SkScalar& operator[] (int i) const { 3769bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt return fTable[i]; 3779bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt } 3789bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt 3799bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkScalar* fTable; 3809bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt }; 3811d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 3821d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt GrBatchTextStrike* fCurrStrike; 383b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt GrTextBlobCache* fCache; 3849bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt bool fEnableDFRendering; 3859bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt SkAutoTUnref<DistanceAdjustTable> fDistanceAdjustTable; 3861d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 387b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt friend class GrTextBlobCache; 3881d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt friend class BitmapTextBatch; 3891d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 39079dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt#ifdef GR_TEST_UTILS 3916c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt BATCH_TEST_FRIEND(TextBlobBatch); 39279dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt#endif 39379dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt 3941d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt typedef GrTextContext INHERITED; 3951d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt}; 3961d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt 3971d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt#endif 398