make producing GrTextBlob sub runs thread safe
Change-Id: Ie16e41fa6cef2d06d1e6e82036524dd5ad06b1ed
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375036
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/gpu/GrSurfaceDrawContext.cpp b/src/gpu/GrSurfaceDrawContext.cpp
index dff2642..3803946 100644
--- a/src/gpu/GrSurfaceDrawContext.cpp
+++ b/src/gpu/GrSurfaceDrawContext.cpp
@@ -429,18 +429,15 @@
textBlobCache->add(glyphRunList, blob);
}
- // TODO(herb): redo processGlyphRunList to handle shifted draw matrix.
bool supportsSDFT = fContext->priv().caps()->shaderCaps()->supportsDistanceFieldText();
- for (auto& glyphRun : glyphRunList) {
- fGlyphPainter.processGlyphRun(glyphRun,
- viewMatrix.localToDevice(),
- drawOrigin,
- drawPaint,
- fSurfaceProps,
- supportsSDFT,
- options,
- blob.get());
- }
+ blob->makeSubRuns(&fGlyphPainter,
+ glyphRunList,
+ viewMatrix.localToDevice(),
+ drawOrigin,
+ drawPaint,
+ fSurfaceProps,
+ supportsSDFT,
+ options);
}
for (const GrSubRun& subRun : blob->subRunList()) {
diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp
index 29f2fc3..f662da1 100644
--- a/src/gpu/text/GrTextBlob.cpp
+++ b/src/gpu/text/GrTextBlob.cpp
@@ -1480,6 +1480,30 @@
, fInitialMatrix{drawMatrix}
, fInitialLuminance{initialLuminance} { }
+void GrTextBlob::makeSubRuns(SkGlyphRunListPainter* painter,
+ const SkGlyphRunList& glyphRunList,
+ const SkMatrix& drawMatrix,
+ SkPoint drawOrigin,
+ const SkPaint& runPaint,
+ const SkSurfaceProps& props,
+ bool contextSupportsDistanceFieldText,
+ const GrSDFTOptions& options) {
+ SkAutoSpinlock lock{fSpinLock};
+ if (!fSubRunsCreated) {
+ for (auto& glyphRun : glyphRunList) {
+ painter->processGlyphRun(glyphRun,
+ drawMatrix,
+ drawOrigin,
+ runPaint,
+ props,
+ contextSupportsDistanceFieldText,
+ options,
+ this);
+ }
+ fSubRunsCreated = true;
+ }
+}
+
void GrTextBlob::processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
const SkStrikeSpec& strikeSpec) {
diff --git a/src/gpu/text/GrTextBlob.h b/src/gpu/text/GrTextBlob.h
index 0e8431e..28aa46f 100644
--- a/src/gpu/text/GrTextBlob.h
+++ b/src/gpu/text/GrTextBlob.h
@@ -399,6 +399,16 @@
void* operator new(size_t);
void* operator new(size_t, void* p);
+ void makeSubRuns(
+ SkGlyphRunListPainter* painter,
+ const SkGlyphRunList& glyphRunList,
+ const SkMatrix& drawMatrix,
+ SkPoint drawOrigin,
+ const SkPaint& runPaint,
+ const SkSurfaceProps& props,
+ bool contextSupportsDistanceFieldText,
+ const GrSDFTOptions& options) SK_EXCLUDES(fSpinLock);
+
static const Key& GetKey(const GrTextBlob& blob);
static uint32_t Hash(const Key& key);
@@ -442,6 +452,14 @@
void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
const SkStrikeSpec& strikeSpec) override;
+ // The run must be created only once.
+ bool fSubRunsCreated SK_GUARDED_BY(fSpinLock) {false};
+
+ // This lock guards makeSubRuns, but also guards addMultiMaskFormat, processDeviceMasks,
+ // processSourcePaths, processSourceSDFT, and processSourceMasks. These are callbacks, and
+ // there is no way for the annotation system to track the lock through processGlyphRun.
+ mutable SkSpinlock fSpinLock;
+
// The allocator must come first because it needs to be destroyed last. Other fields of this
// structure may have pointers into it.
GrSubRunAllocator fAlloc;