move GrAtlasTextOp creation to GrRenderTargetContext
The op creation is no self contained, which means that it handles taking the clip. For random op testing, this means that some times no op is created for blobs that are entirely off screen. This results in a nullptr op. The random op test has been adjust accordingly. Change-Id: I619ffb315b7ad7c834b3e85d7120fe2cdb90c56a Reviewed-on: https://skia-review.googlesource.com/c/skia/+/301583 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
54867de4bf
commit
411e7aa8b1
@ -47,6 +47,7 @@
|
||||
#include "src/gpu/GrTracing.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#include "src/gpu/effects/GrBicubicEffect.h"
|
||||
#include "src/gpu/effects/GrDistanceFieldGeoProc.h"
|
||||
#include "src/gpu/effects/GrRRectEffect.h"
|
||||
#include "src/gpu/geometry/GrQuad.h"
|
||||
#include "src/gpu/geometry/GrQuadUtils.h"
|
||||
@ -479,8 +480,139 @@ void GrRenderTargetContext::drawTextPaths(const GrClip* clip,
|
||||
}
|
||||
}
|
||||
|
||||
static SkPMColor4f generate_filtered_color(const SkPaint& paint, const GrColorInfo& colorInfo) {
|
||||
SkColor4f c = paint.getColor4f();
|
||||
if (auto* xform = colorInfo.colorSpaceXformFromSRGB()) {
|
||||
c = xform->apply(c);
|
||||
}
|
||||
if (auto* cf = paint.getColorFilter()) {
|
||||
c = cf->filterColor4f(c, colorInfo.colorSpace(), colorInfo.colorSpace());
|
||||
}
|
||||
return c.premul();
|
||||
}
|
||||
|
||||
std::tuple<const GrClip*, std::unique_ptr<GrDrawOp>>
|
||||
GrRenderTargetContext::makeAtlasTextOp(const GrClip* clip,
|
||||
const SkMatrixProvider& viewMatrix,
|
||||
const SkGlyphRunList& glyphRunList,
|
||||
GrTextBlob::SubRun* subRun) {
|
||||
SkASSERT(subRun->glyphCount() != 0);
|
||||
|
||||
SkPoint drawOrigin = glyphRunList.origin();
|
||||
const SkPaint& drawPaint = glyphRunList.paint();
|
||||
const SkMatrix& drawMatrix = viewMatrix.localToDevice();
|
||||
GrRecordingContext* context = this->fContext;
|
||||
GrOpMemoryPool* pool = context->priv().opMemoryPool();
|
||||
const GrColorInfo& colorInfo = this->colorInfo();
|
||||
|
||||
// We can clip geometrically using clipRect and ignore clip if we're not using SDFs or
|
||||
// transformed glyphs, and we have an axis-aligned rectangular non-AA clip.
|
||||
std::unique_ptr<GrDrawOp> op;
|
||||
if (!subRun->drawAsDistanceFields()) {
|
||||
SkIRect clipRect = SkIRect::MakeEmpty();
|
||||
if (!subRun->needsTransform()) {
|
||||
// We only need to do clipping work if the SubRun isn't contained by the clip
|
||||
SkRect subRunBounds = subRun->deviceRect(drawMatrix, drawOrigin);
|
||||
SkRect renderTargetBounds = SkRect::MakeWH(this->width(), this->height());
|
||||
if (clip == nullptr && !renderTargetBounds.intersects(subRunBounds)) {
|
||||
// If the SubRun is completely outside, don't add an op for it.
|
||||
return {nullptr, nullptr};
|
||||
} else if (clip != nullptr) {
|
||||
GrClip::PreClipResult result = clip->preApply(subRunBounds);
|
||||
if (result.fEffect == GrClip::Effect::kClipped) {
|
||||
if (result.fIsRRect && result.fRRect.isRect() &&
|
||||
result.fAA == GrAA::kNo) {
|
||||
// Clip geometrically during onPrepare using clipRect.
|
||||
result.fRRect.getBounds().round(&clipRect);
|
||||
clip = nullptr;
|
||||
}
|
||||
} else if (result.fEffect == GrClip::Effect::kClippedOut) {
|
||||
return {nullptr, nullptr};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!clipRect.isEmpty()) { SkASSERT(clip == nullptr); }
|
||||
|
||||
// Produce the Bitmap Op.
|
||||
GrPaint grPaint;
|
||||
if (kARGB_GrMaskFormat == subRun->maskFormat()) {
|
||||
SkPaintToGrPaintWithPrimitiveColor(
|
||||
context, colorInfo, drawPaint, viewMatrix, &grPaint);
|
||||
} else {
|
||||
SkPaintToGrPaint(context, colorInfo, drawPaint, viewMatrix, &grPaint);
|
||||
}
|
||||
|
||||
// This is the color the op will use to draw.
|
||||
SkPMColor4f drawingColor = generate_filtered_color(drawPaint, colorInfo);
|
||||
|
||||
GrAtlasTextOp::MaskType maskType = [&]() {
|
||||
switch (subRun->maskFormat()) {
|
||||
case kA8_GrMaskFormat: return GrAtlasTextOp::kGrayscaleCoverageMask_MaskType;
|
||||
case kA565_GrMaskFormat: return GrAtlasTextOp::kLCDCoverageMask_MaskType;
|
||||
case kARGB_GrMaskFormat: return GrAtlasTextOp::kColorBitmapMask_MaskType;
|
||||
// Needed to placate some compilers.
|
||||
default: return GrAtlasTextOp::kGrayscaleCoverageMask_MaskType;
|
||||
}
|
||||
}();
|
||||
|
||||
op = pool->allocate<GrAtlasTextOp>(maskType,
|
||||
std::move(grPaint),
|
||||
subRun,
|
||||
drawMatrix,
|
||||
drawOrigin,
|
||||
clipRect,
|
||||
drawingColor,
|
||||
0,
|
||||
false,
|
||||
0);
|
||||
} else {
|
||||
GrPaint grPaint;
|
||||
SkPaintToGrPaint(context, colorInfo, drawPaint, viewMatrix, &grPaint);
|
||||
|
||||
// This is the color the op will use to draw.
|
||||
SkPMColor4f drawingColor = generate_filtered_color(drawPaint, colorInfo);
|
||||
|
||||
const SkSurfaceProps& props = this->surfaceProps();
|
||||
bool isBGR = SkPixelGeometryIsBGR(props.pixelGeometry());
|
||||
bool isLCD = subRun->hasUseLCDText() && SkPixelGeometryIsH(props.pixelGeometry());
|
||||
using MT = GrAtlasTextOp::MaskType;
|
||||
MT maskType = !subRun->isAntiAliased() ? MT::kAliasedDistanceField_MaskType
|
||||
: isLCD ? (isBGR ? MT::kLCDBGRDistanceField_MaskType
|
||||
: MT::kLCDDistanceField_MaskType)
|
||||
: MT::kGrayscaleDistanceField_MaskType;
|
||||
|
||||
bool useGammaCorrectDistanceTable = colorInfo.isLinearlyBlended();
|
||||
uint32_t DFGPFlags = drawMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
|
||||
DFGPFlags |= drawMatrix.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0;
|
||||
DFGPFlags |= drawMatrix.hasPerspective() ? kPerspective_DistanceFieldEffectFlag : 0;
|
||||
DFGPFlags |= useGammaCorrectDistanceTable ? kGammaCorrect_DistanceFieldEffectFlag : 0;
|
||||
DFGPFlags |= MT::kAliasedDistanceField_MaskType == maskType ?
|
||||
kAliased_DistanceFieldEffectFlag : 0;
|
||||
|
||||
if (isLCD) {
|
||||
DFGPFlags |= kUseLCD_DistanceFieldEffectFlag;
|
||||
DFGPFlags |= MT::kLCDBGRDistanceField_MaskType == maskType ?
|
||||
kBGR_DistanceFieldEffectFlag : 0;
|
||||
}
|
||||
|
||||
op = pool->allocate<GrAtlasTextOp>(maskType,
|
||||
std::move(grPaint),
|
||||
subRun,
|
||||
drawMatrix,
|
||||
drawOrigin,
|
||||
SkIRect::MakeEmpty(),
|
||||
drawingColor,
|
||||
SkPaintPriv::ComputeLuminanceColor(drawPaint),
|
||||
useGammaCorrectDistanceTable,
|
||||
DFGPFlags);
|
||||
}
|
||||
|
||||
return {clip, std::move(op)};
|
||||
}
|
||||
|
||||
void GrRenderTargetContext::drawGlyphRunList(const GrClip* clip,
|
||||
const SkMatrixProvider& matrixProvider,
|
||||
const SkMatrixProvider& viewMatrix,
|
||||
const SkGlyphRunList& glyphRunList) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
RETURN_IF_ABANDONED
|
||||
@ -536,7 +668,7 @@ void GrRenderTargetContext::drawGlyphRunList(const GrClip* clip,
|
||||
blob = textBlobCache->find(key);
|
||||
}
|
||||
|
||||
const SkMatrix& drawMatrix(matrixProvider.localToDevice());
|
||||
const SkMatrix& drawMatrix(viewMatrix.localToDevice());
|
||||
if (blob != nullptr && blob->canReuse(blobPaint, blurRec, drawMatrix, drawOrigin)) {
|
||||
// Reusing the blob. Move it to the front of LRU cache.
|
||||
textBlobCache->makeMRU(blob.get());
|
||||
@ -560,58 +692,11 @@ void GrRenderTargetContext::drawGlyphRunList(const GrClip* clip,
|
||||
|
||||
for (GrTextBlob::SubRun* subRun : blob->subRunList()) {
|
||||
if (subRun->drawAsPaths()) {
|
||||
this->drawTextPaths(clip, matrixProvider, glyphRunList, subRun);
|
||||
this->drawTextPaths(clip, viewMatrix, glyphRunList, subRun);
|
||||
} else {
|
||||
// Handle the mask and distance field cases.
|
||||
SkASSERT(subRun->glyphCount() != 0);
|
||||
|
||||
// We can clip geometrically using clipRect and ignore clip if we're not using SDFs or
|
||||
// transformed glyphs, and we have an axis-aligned rectangular non-AA clip.
|
||||
std::unique_ptr<GrAtlasTextOp> op;
|
||||
const GrClip* subRunClip = clip;
|
||||
if (!subRun->drawAsDistanceFields()) {
|
||||
SkIRect clipRect = SkIRect::MakeEmpty();
|
||||
if (!subRun->needsTransform()) {
|
||||
// We only need to do clipping work if the SubRun isn't contained by the clip
|
||||
SkRect subRunBounds = subRun->deviceRect(
|
||||
matrixProvider.localToDevice(), drawOrigin);
|
||||
SkRect renderTargetBounds = SkRect::MakeWH(this->width(), this->height());
|
||||
if (subRunClip == nullptr && !renderTargetBounds.intersects(subRunBounds)) {
|
||||
// If the SubRun is completely outside, don't add an op for it.
|
||||
continue;
|
||||
} else if (subRunClip != nullptr) {
|
||||
GrClip::PreClipResult result = subRunClip->preApply(subRunBounds);
|
||||
if (result.fEffect == GrClip::Effect::kClipped) {
|
||||
if (result.fIsRRect && result.fRRect.isRect() &&
|
||||
result.fAA == GrAA::kNo) {
|
||||
// Clip geometrically during onPrepare using clipRect.
|
||||
result.fRRect.getBounds().round(&clipRect);
|
||||
subRunClip = nullptr;
|
||||
}
|
||||
} else if (result.fEffect == GrClip::Effect::kClippedOut) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!clipRect.isEmpty()) { SkASSERT(subRunClip == nullptr); }
|
||||
|
||||
op = GrAtlasTextOp::MakeBitmap(this,
|
||||
blobPaint,
|
||||
subRun,
|
||||
matrixProvider,
|
||||
drawOrigin,
|
||||
clipRect);
|
||||
} else {
|
||||
op = GrAtlasTextOp::MakeDistanceField(this,
|
||||
blobPaint,
|
||||
subRun,
|
||||
matrixProvider,
|
||||
drawOrigin);
|
||||
}
|
||||
|
||||
auto [drawingClip, op] = this->makeAtlasTextOp(clip, viewMatrix, glyphRunList, subRun);
|
||||
if (op != nullptr) {
|
||||
this->addDrawOp(subRunClip, std::move(op));
|
||||
this->addDrawOp(drawingClip, std::move(op));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "src/gpu/geometry/GrQuad.h"
|
||||
#include "src/gpu/text/GrTextBlob.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
class GrBackendSemaphore;
|
||||
class GrClip;
|
||||
class GrColorSpaceXform;
|
||||
@ -140,8 +142,6 @@ public:
|
||||
|
||||
~GrRenderTargetContext() override;
|
||||
|
||||
virtual void drawGlyphRunList(const GrClip*, const SkMatrixProvider&, const SkGlyphRunList&);
|
||||
|
||||
/**
|
||||
* Provides a perfomance hint that the render target's contents are allowed
|
||||
* to become undefined.
|
||||
@ -518,6 +518,26 @@ public:
|
||||
const SkGlyphRunList& glyphRunList,
|
||||
GrTextBlob::SubRun* subRun);
|
||||
|
||||
/**
|
||||
* Make the AtlasTextOp - returns the op and the original clip or nullptr for the clip if the
|
||||
* op is going to clip geometrically.
|
||||
*/
|
||||
std::tuple<const GrClip*, std::unique_ptr<GrDrawOp>>
|
||||
makeAtlasTextOp(const GrClip*,
|
||||
const SkMatrixProvider& viewMatrix,
|
||||
const SkGlyphRunList& glyphRunList,
|
||||
GrTextBlob::SubRun* subRun);
|
||||
|
||||
/**
|
||||
* Draw the text specified by the SkGlyphRunList.
|
||||
*
|
||||
* @param viewMatrix transformationMatrix
|
||||
* @param glyphRunList text, text positions, and paint.
|
||||
*/
|
||||
void drawGlyphRunList(const GrClip*,
|
||||
const SkMatrixProvider& viewMatrix,
|
||||
const SkGlyphRunList& glyphRunList);
|
||||
|
||||
/**
|
||||
* Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
|
||||
* of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
|
||||
@ -590,7 +610,6 @@ private:
|
||||
friend class GrFillRectOp; // for access to addDrawOp
|
||||
friend class GrTessellationPathRenderer; // for access to addDrawOp
|
||||
friend class GrTextureOp; // for access to addDrawOp
|
||||
friend class GrAtlasTextOp; // for access to addDrawOp
|
||||
|
||||
SkDEBUGCODE(void onValidate() const override;)
|
||||
|
||||
|
@ -102,6 +102,10 @@ public:
|
||||
void testingOnly_addDrawOp(const GrClip*, std::unique_ptr<GrDrawOp>,
|
||||
const std::function<WillAddOpFn>& = std::function<WillAddOpFn>());
|
||||
|
||||
SkGlyphRunListPainter* testingOnly_glyphRunPainter() {
|
||||
return &fRenderTargetContext->fGlyphPainter;
|
||||
}
|
||||
|
||||
bool refsWrappedObjects() const {
|
||||
return fRenderTargetContext->asRenderTargetProxy()->refsWrappedObjects();
|
||||
}
|
||||
|
@ -75,107 +75,6 @@ void GrAtlasTextOp::Geometry::fillVertexData(void *dst, int offset, int count) c
|
||||
fDrawMatrix, fDrawOrigin, fClipRect);
|
||||
}
|
||||
|
||||
static SkPMColor4f generate_filtered_color(const SkPaint& paint, const GrColorInfo& colorInfo) {
|
||||
SkColor4f c = paint.getColor4f();
|
||||
if (auto* xform = colorInfo.colorSpaceXformFromSRGB()) {
|
||||
c = xform->apply(c);
|
||||
}
|
||||
if (auto* cf = paint.getColorFilter()) {
|
||||
c = cf->filterColor4f(c, colorInfo.colorSpace(), colorInfo.colorSpace());
|
||||
}
|
||||
return c.premul();
|
||||
}
|
||||
|
||||
std::unique_ptr<GrAtlasTextOp> GrAtlasTextOp::MakeBitmap(GrRenderTargetContext* rtc,
|
||||
const SkPaint& paint,
|
||||
GrTextBlob::SubRun* subrun,
|
||||
const SkMatrixProvider& matrixProvider,
|
||||
SkPoint drawOrigin,
|
||||
const SkIRect& clipRect) {
|
||||
GrPaint grPaint;
|
||||
GrRecordingContext* context = rtc->priv().getContext();
|
||||
const GrColorInfo& colorInfo = rtc->colorInfo();
|
||||
if (kARGB_GrMaskFormat == subrun->maskFormat()) {
|
||||
SkPaintToGrPaintWithPrimitiveColor(context, colorInfo, paint, matrixProvider, &grPaint);
|
||||
} else {
|
||||
SkPaintToGrPaint(context, colorInfo, paint, matrixProvider, &grPaint);
|
||||
}
|
||||
|
||||
// This is the color the op will use to draw.
|
||||
SkPMColor4f drawingColor = generate_filtered_color(paint, colorInfo);
|
||||
|
||||
GrOpMemoryPool* pool = context->priv().opMemoryPool();
|
||||
|
||||
MaskType maskType = [&]() {
|
||||
switch (subrun->maskFormat()) {
|
||||
case kA8_GrMaskFormat: return kGrayscaleCoverageMask_MaskType;
|
||||
case kA565_GrMaskFormat: return kLCDCoverageMask_MaskType;
|
||||
case kARGB_GrMaskFormat: return kColorBitmapMask_MaskType;
|
||||
// Needed to placate some compilers.
|
||||
default: return kGrayscaleCoverageMask_MaskType;
|
||||
}
|
||||
}();
|
||||
|
||||
return pool->allocate<GrAtlasTextOp>(maskType,
|
||||
std::move(grPaint),
|
||||
subrun,
|
||||
matrixProvider.localToDevice(),
|
||||
drawOrigin,
|
||||
clipRect,
|
||||
drawingColor,
|
||||
0,
|
||||
false,
|
||||
0);
|
||||
}
|
||||
|
||||
std::unique_ptr<GrAtlasTextOp> GrAtlasTextOp::MakeDistanceField(
|
||||
GrRenderTargetContext* rtc,
|
||||
const SkPaint& paint,
|
||||
GrTextBlob::SubRun* subrun,
|
||||
const SkMatrixProvider& matrixProvider,
|
||||
SkPoint drawOrigin) {
|
||||
GrPaint grPaint;
|
||||
GrRecordingContext* context = rtc->priv().getContext();
|
||||
const GrColorInfo& colorInfo = rtc->colorInfo();
|
||||
SkPaintToGrPaint(context, colorInfo, paint, matrixProvider, &grPaint);
|
||||
|
||||
// This is the color the op will use to draw.
|
||||
SkPMColor4f drawingColor = generate_filtered_color(paint, colorInfo);
|
||||
|
||||
const SkSurfaceProps& props = rtc->surfaceProps();
|
||||
GrOpMemoryPool* pool = context->priv().opMemoryPool();
|
||||
bool isBGR = SkPixelGeometryIsBGR(props.pixelGeometry());
|
||||
bool isLCD = subrun->hasUseLCDText() && SkPixelGeometryIsH(props.pixelGeometry());
|
||||
MaskType maskType = !subrun->isAntiAliased() ? kAliasedDistanceField_MaskType
|
||||
: isLCD ? (isBGR ? kLCDBGRDistanceField_MaskType
|
||||
: kLCDDistanceField_MaskType)
|
||||
: kGrayscaleDistanceField_MaskType;
|
||||
|
||||
const SkMatrix& drawMatrix = matrixProvider.localToDevice();
|
||||
bool useGammaCorrectDistanceTable = colorInfo.isLinearlyBlended();
|
||||
uint32_t DFGPFlags = drawMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
|
||||
DFGPFlags |= drawMatrix.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0;
|
||||
DFGPFlags |= drawMatrix.hasPerspective() ? kPerspective_DistanceFieldEffectFlag : 0;
|
||||
DFGPFlags |= useGammaCorrectDistanceTable ? kGammaCorrect_DistanceFieldEffectFlag : 0;
|
||||
DFGPFlags |= kAliasedDistanceField_MaskType == maskType ? kAliased_DistanceFieldEffectFlag : 0;
|
||||
|
||||
if (isLCD) {
|
||||
DFGPFlags |= kUseLCD_DistanceFieldEffectFlag;
|
||||
DFGPFlags |= kLCDBGRDistanceField_MaskType == maskType ? kBGR_DistanceFieldEffectFlag : 0;
|
||||
}
|
||||
|
||||
return pool->allocate<GrAtlasTextOp>(maskType,
|
||||
std::move(grPaint),
|
||||
subrun,
|
||||
drawMatrix,
|
||||
drawOrigin,
|
||||
SkIRect::MakeEmpty(),
|
||||
drawingColor,
|
||||
SkPaintPriv::ComputeLuminanceColor(paint),
|
||||
useGammaCorrectDistanceTable,
|
||||
DFGPFlags);
|
||||
}
|
||||
|
||||
void GrAtlasTextOp::visitProxies(const VisitProxyFunc& func) const {
|
||||
fProcessors.visitProxies(func);
|
||||
}
|
||||
@ -595,11 +494,11 @@ std::unique_ptr<GrDrawOp> GrAtlasTextOp::CreateOpTestingOnly(GrRenderTargetConte
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GrRecordingContextPriv& contextPriv = rtc->fContext->priv();
|
||||
GrSDFTOptions SDFOptions = rtc->fContext->priv().SDFTOptions();
|
||||
const GrRecordingContextPriv& contextPriv = rtc->priv().getContext()->priv();
|
||||
GrSDFTOptions SDFOptions = contextPriv.SDFTOptions();
|
||||
|
||||
sk_sp<GrTextBlob> blob = GrTextBlob::Make(glyphRunList, drawMatrix);
|
||||
SkGlyphRunListPainter* painter = &rtc->fGlyphPainter;
|
||||
SkGlyphRunListPainter* painter = rtc->priv().testingOnly_glyphRunPainter();
|
||||
painter->processGlyphRunList(
|
||||
glyphRunList, drawMatrix, rtc->surfaceProps(),
|
||||
contextPriv.caps()->shaderCaps()->supportsDistanceFieldText(),
|
||||
@ -608,12 +507,10 @@ std::unique_ptr<GrDrawOp> GrAtlasTextOp::CreateOpTestingOnly(GrRenderTargetConte
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return GrAtlasTextOp::MakeBitmap(rtc,
|
||||
skPaint,
|
||||
blob->firstSubRun(),
|
||||
mtxProvider,
|
||||
drawOrigin,
|
||||
SkIRect::MakeEmpty());
|
||||
std::unique_ptr<GrDrawOp> op;
|
||||
std::tie(std::ignore, op) =
|
||||
rtc->makeAtlasTextOp(nullptr, mtxProvider, glyphRunList, blob->firstSubRun());
|
||||
return op;
|
||||
}
|
||||
|
||||
GR_DRAW_OP_TEST_DEFINE(GrAtlasTextOp) {
|
||||
|
@ -37,20 +37,6 @@ public:
|
||||
void fillVertexData(void* dst, int offset, int count) const;
|
||||
};
|
||||
|
||||
static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrRenderTargetContext*,
|
||||
const SkPaint&,
|
||||
GrTextBlob::SubRun*,
|
||||
const SkMatrixProvider&,
|
||||
SkPoint drawOrigin,
|
||||
const SkIRect& clipRect);
|
||||
|
||||
static std::unique_ptr<GrAtlasTextOp> MakeDistanceField(
|
||||
GrRenderTargetContext*,
|
||||
const SkPaint&,
|
||||
GrTextBlob::SubRun*,
|
||||
const SkMatrixProvider&,
|
||||
SkPoint drawOrigin);
|
||||
|
||||
const char* name() const override { return "AtlasTextOp"; }
|
||||
|
||||
void visitProxies(const VisitProxyFunc& func) const override;
|
||||
|
@ -200,6 +200,9 @@ void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext
|
||||
uint32_t index = random->nextULessThan(static_cast<uint32_t>(kTotal));
|
||||
auto op = gFactories[index](
|
||||
std::move(paint), random, context, renderTargetContext->numSamples());
|
||||
|
||||
// Creating a GrAtlasTextOp my not produce an op if for example, it is totally outside the
|
||||
// render target context.
|
||||
if (op) {
|
||||
renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user