Use layers properly in Slug drawing

When drawing the Slug, aboutToDraw was never called resulting
in strange drawing matrices and broken image filters. Call
aboutToDraw in Slug drawing needs to use the initial paint from
the convert call. Store this in the Slug instead of the paint
resulting from aboutToDraw. Plumb the initialPaint and the
paint from aboutToDraw to where they need to go.

Bug: chromium:1302290
Change-Id: Id921aa37bf8ff2ecd21cdcdaad0012a7b90f5322
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/533759
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2022-04-25 15:19:41 -06:00 committed by SkCQ
parent fd9804f9a3
commit 74666f4b8c
21 changed files with 170 additions and 97 deletions

View File

@ -61,7 +61,11 @@ public:
void draw(SkCanvas* canvas) const; void draw(SkCanvas* canvas) const;
virtual SkRect sourceBounds() const = 0; virtual SkRect sourceBounds() const = 0;
virtual const SkPaint& paint() const = 0;
// The paint passed into ConvertBlob; this paint is used instead of the paint resulting from
// the call to aboutToDraw because when we call draw(), the initial paint is needed to call
// aboutToDraw again to get the layer right.
virtual const SkPaint& initialPaint() const = 0;
virtual void doFlatten(SkWriteBuffer&) const = 0; virtual void doFlatten(SkWriteBuffer&) const = 0;

View File

@ -523,9 +523,10 @@ void SkBitmapDevice::drawImageRect(const SkImage* image, const SkRect* src, cons
void SkBitmapDevice::onDrawGlyphRunList(SkCanvas* canvas, void SkBitmapDevice::onDrawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
SkASSERT(!glyphRunList.hasRSXForm()); SkASSERT(!glyphRunList.hasRSXForm());
LOOP_TILER( drawGlyphRunList(canvas, &fGlyphPainter, glyphRunList, paint), nullptr ) LOOP_TILER( drawGlyphRunList(canvas, &fGlyphPainter, glyphRunList, drawingPaint), nullptr )
} }
void SkBitmapDevice::drawVertices(const SkVertices* vertices, void SkBitmapDevice::drawVertices(const SkVertices* vertices,

View File

@ -107,7 +107,10 @@ protected:
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override; void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
bool onReadPixels(const SkPixmap&, int x, int y) override; bool onReadPixels(const SkPixmap&, int x, int y) override;
bool onWritePixels(const SkPixmap&, int, int) override; bool onWritePixels(const SkPixmap&, int, int) override;
bool onPeekPixels(SkPixmap*) override; bool onPeekPixels(SkPixmap*) override;

View File

@ -2338,7 +2338,7 @@ void SkCanvas::onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPa
} }
auto layer = this->aboutToDraw(this, paint, &bounds); auto layer = this->aboutToDraw(this, paint, &bounds);
if (layer) { if (layer) {
this->topDevice()->drawGlyphRunList(this, glyphRunList, layer->paint()); this->topDevice()->drawGlyphRunList(this, glyphRunList, paint, layer->paint());
} }
} }
@ -2358,7 +2358,7 @@ SkCanvas::onConvertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList, const
} }
auto layer = this->aboutToDraw(this, paint, &bounds); auto layer = this->aboutToDraw(this, paint, &bounds);
if (layer) { if (layer) {
return this->topDevice()->convertGlyphRunListToSlug(glyphRunList, layer->paint()); return this->topDevice()->convertGlyphRunListToSlug(glyphRunList, paint, layer->paint());
} }
return nullptr; return nullptr;
} }
@ -2372,11 +2372,14 @@ void SkCanvas::drawSlug(const GrSlug* slug) {
void SkCanvas::onDrawSlug(const GrSlug* slug) { void SkCanvas::onDrawSlug(const GrSlug* slug) {
SkRect bounds = slug->sourceBounds(); SkRect bounds = slug->sourceBounds();
if (this->internalQuickReject(bounds, slug->paint())) { if (this->internalQuickReject(bounds, slug->initialPaint())) {
return; return;
} }
this->topDevice()->drawSlug(this, slug); auto layer = this->aboutToDraw(this, slug->initialPaint(), &bounds);
if (layer) {
this->topDevice()->drawSlug(this, slug, layer->paint());
}
} }
#endif #endif

View File

@ -814,7 +814,8 @@ protected:
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
void onDrawGlyphRunList(SkCanvas*, void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override { const SkPaint& initialPaint,
const SkPaint& drawingPaint) override {
GrContextOptions ctxOptions; GrContextOptions ctxOptions;
GrSDFTControl control = GrSDFTControl control =
GrSDFTControl{fDFTSupport, GrSDFTControl{fDFTSupport,
@ -829,7 +830,7 @@ protected:
fPainter.processGlyphRun(nullptr, fPainter.processGlyphRun(nullptr,
glyphRun, glyphRun,
drawMatrix, drawMatrix,
paint, drawingPaint,
control, control,
"Cache Diff", "Cache Diff",
uniqueID); uniqueID);
@ -837,7 +838,8 @@ protected:
} }
sk_sp<GrSlug> convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList, sk_sp<GrSlug> convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override { const SkPaint& initialPaint,
const SkPaint& drawingPaint) override {
GrContextOptions ctxOptions; GrContextOptions ctxOptions;
GrSDFTControl control = GrSDFTControl control =
GrSDFTControl{fDFTSupport, GrSDFTControl{fDFTSupport,
@ -858,14 +860,18 @@ protected:
fPainter.processGlyphRun(nullptr, fPainter.processGlyphRun(nullptr,
glyphRun, glyphRun,
positionMatrix, positionMatrix,
paint, drawingPaint,
control, control,
"Convert Slug Analysis"); "Convert Slug Analysis");
} }
// Use the glyph strike cache to get actual glyph information. // Use the glyph strike cache to get actual glyph information.
return skgpu::v1::MakeSlug( return skgpu::v1::MakeSlug(this->localToDevice(),
this->localToDevice(), glyphRunList, paint, control, &fConvertPainter); glyphRunList,
initialPaint,
drawingPaint,
control,
&fConvertPainter);
} }
#endif // SK_SUPPORT_GPU #endif // SK_SUPPORT_GPU

View File

@ -428,25 +428,27 @@ static sk_sp<SkShader> make_post_inverse_lm(const SkShader* shader, const SkMatr
void SkBaseDevice::drawGlyphRunList(SkCanvas* canvas, void SkBaseDevice::drawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
if (!this->localToDevice().isFinite()) { if (!this->localToDevice().isFinite()) {
return; return;
} }
if (!glyphRunList.hasRSXForm()) { if (!glyphRunList.hasRSXForm()) {
this->onDrawGlyphRunList(canvas, glyphRunList, paint); this->onDrawGlyphRunList(canvas, glyphRunList, initialPaint, drawingPaint);
} else { } else {
this->simplifyGlyphRunRSXFormAndRedraw(canvas, glyphRunList, paint); this->simplifyGlyphRunRSXFormAndRedraw(canvas, glyphRunList, initialPaint, drawingPaint);
} }
} }
void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas, void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
for (const SkGlyphRun& run : glyphRunList) { for (const SkGlyphRun& run : glyphRunList) {
if (run.scaledRotations().empty()) { if (run.scaledRotations().empty()) {
SkGlyphRunList subList{run, run.sourceBounds(paint), {0, 0}}; SkGlyphRunList subList{run, run.sourceBounds(drawingPaint), {0, 0}};
this->drawGlyphRunList(canvas, subList, paint); this->drawGlyphRunList(canvas, subList, initialPaint, drawingPaint);
} else { } else {
SkPoint origin = glyphRunList.origin(); SkPoint origin = glyphRunList.origin();
SkPoint sharedPos{0, 0}; // we're at the origin SkPoint sharedPos{0, 0}; // we're at the origin
@ -471,12 +473,13 @@ void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
// (i.e. the shader that cares about the ctm) so we have to undo our little ctm // (i.e. the shader that cares about the ctm) so we have to undo our little ctm
// trick with a localmatrixshader so that the shader draws as if there was no // trick with a localmatrixshader so that the shader draws as if there was no
// change to the ctm. // change to the ctm.
SkPaint invertingPaint{paint}; SkPaint invertingPaint{drawingPaint};
invertingPaint.setShader(make_post_inverse_lm(paint.getShader(), glyphToLocal)); invertingPaint.setShader(
make_post_inverse_lm(drawingPaint.getShader(), glyphToLocal));
SkAutoCanvasRestore acr(canvas, true); SkAutoCanvasRestore acr(canvas, true);
canvas->concat(SkM44(glyphToLocal)); canvas->concat(SkM44(glyphToLocal));
SkGlyphRunList subList{glyphRun, glyphRun.sourceBounds(paint), {0, 0}}; SkGlyphRunList subList{glyphRun, glyphRun.sourceBounds(drawingPaint), {0, 0}};
this->drawGlyphRunList(canvas, subList, invertingPaint); this->drawGlyphRunList(canvas, subList, initialPaint, invertingPaint);
} }
} }
} }
@ -485,11 +488,12 @@ void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
sk_sp<GrSlug> SkBaseDevice::convertGlyphRunListToSlug( sk_sp<GrSlug> SkBaseDevice::convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
return nullptr; return nullptr;
} }
void SkBaseDevice::drawSlug(SkCanvas*, const GrSlug*) { void SkBaseDevice::drawSlug(SkCanvas*, const GrSlug*, const SkPaint&) {
SK_ABORT("GrSlug drawing not supported."); SK_ABORT("GrSlug drawing not supported.");
} }
#endif #endif

View File

@ -199,7 +199,10 @@ public:
virtual skgpu::graphite::Device* asGraphiteDevice() { return nullptr; } virtual skgpu::graphite::Device* asGraphiteDevice() { return nullptr; }
// Ensure that non-RSXForm runs are passed to onDrawGlyphRunList. // Ensure that non-RSXForm runs are passed to onDrawGlyphRunList.
void drawGlyphRunList(SkCanvas*, const SkGlyphRunList& glyphRunList, const SkPaint& paint); void drawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList,
const SkPaint& initialPaint,
const SkPaint& drawingPaint);
protected: protected:
enum TileUsage { enum TileUsage {
@ -311,14 +314,18 @@ protected:
virtual void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*); virtual void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*);
// Only called with glyphRunLists that do not contain RSXForm. // Only called with glyphRunLists that do not contain RSXForm.
virtual void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) = 0; virtual void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) = 0;
// GrSlug handling routines. // GrSlug handling routines.
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
virtual sk_sp<GrSlug> convertGlyphRunListToSlug( virtual sk_sp<GrSlug> convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint); const SkPaint& initialPaint,
virtual void drawSlug(SkCanvas*, const GrSlug* slug); const SkPaint& drawingPaint);
virtual void drawSlug(SkCanvas*, const GrSlug* slug, const SkPaint& drawingPaint);
#endif #endif
/** /**
@ -436,7 +443,10 @@ private:
friend class SkSurface_Raster; friend class SkSurface_Raster;
friend class DeviceTestingAccess; friend class DeviceTestingAccess;
void simplifyGlyphRunRSXFormAndRedraw(SkCanvas*, const SkGlyphRunList&, const SkPaint&); void simplifyGlyphRunRSXFormAndRedraw(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint);
// used to change the backend's pixels (and possibly config/rowbytes) // used to change the backend's pixels (and possibly config/rowbytes)
// but cannot change the width/height, so there should be no change to // but cannot change the width/height, so there should be no change to
@ -548,8 +558,8 @@ protected:
void drawFilteredImage(const skif::Mapping&, SkSpecialImage* src, const SkImageFilter*, void drawFilteredImage(const skif::Mapping&, SkSpecialImage* src, const SkImageFilter*,
const SkSamplingOptions&, const SkPaint&) override {} const SkSamplingOptions&, const SkPaint&) override {}
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override {} void onDrawGlyphRunList(
SkCanvas*, const SkGlyphRunList&, const SkPaint&, const SkPaint&) override {}
bool isNoPixelsDevice() const override { return true; } bool isNoPixelsDevice() const override { return true; }

View File

@ -62,10 +62,12 @@ public:
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull, void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
const SkSamplingOptions&, const SkPaint&) const override {} const SkSamplingOptions&, const SkPaint&) const override {}
void onDrawGlyphRunList(SkCanvas* canvas, const SkGlyphRunList& glyphRunList, void onDrawGlyphRunList(SkCanvas* canvas,
const SkPaint& paint) override { const SkGlyphRunList& glyphRunList,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override {
SkASSERT(!glyphRunList.hasRSXForm()); SkASSERT(!glyphRunList.hasRSXForm());
fPainter.drawForBitmapDevice(canvas, this, glyphRunList, paint, fPainter.drawForBitmapDevice(canvas, this, glyphRunList, drawingPaint,
fOverdrawCanvas->getTotalMatrix()); fOverdrawCanvas->getTotalMatrix());
} }
@ -83,12 +85,13 @@ void SkOverdrawCanvas::onDrawTextBlob(
} }
void SkOverdrawCanvas::onDrawGlyphRunList( void SkOverdrawCanvas::onDrawGlyphRunList(
const SkGlyphRunList& glyphRunList, const SkPaint& paint) { const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
SkSurfaceProps props{0, kUnknown_SkPixelGeometry}; SkSurfaceProps props{0, kUnknown_SkPixelGeometry};
this->getProps(&props); this->getProps(&props);
TextDevice device{this, props}; TextDevice device{this, props};
device.drawGlyphRunList(this, glyphRunList, paint); device.drawGlyphRunList(this, glyphRunList, paint, paint);
} }
void SkOverdrawCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], void SkOverdrawCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],

View File

@ -479,7 +479,7 @@ private:
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
Bounds bounds(const DrawSlug& op) const { Bounds bounds(const DrawSlug& op) const {
SkRect dst = op.slug->sourceBounds(); SkRect dst = op.slug->sourceBounds();
return this->adjustAndMap(dst, &op.slug->paint()); return this->adjustAndMap(dst, &op.slug->initialPaint());
} }
#else #else
Bounds bounds(const DrawSlug& op) const { Bounds bounds(const DrawSlug& op) const {

View File

@ -2211,7 +2211,8 @@ public:
static sk_sp<Slug> Make(const SkMatrixProvider& viewMatrix, static sk_sp<Slug> Make(const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint, const SkPaint& initialPaint,
const SkPaint& drawingPaint,
const GrSDFTControl& control, const GrSDFTControl& control,
SkGlyphRunListPainter* painter); SkGlyphRunListPainter* painter);
static sk_sp<GrSlug> MakeFromBuffer(SkReadBuffer& buffer, static sk_sp<GrSlug> MakeFromBuffer(SkReadBuffer& buffer,
@ -2220,11 +2221,12 @@ public:
void surfaceDraw(SkCanvas*, void surfaceDraw(SkCanvas*,
const GrClip* clip, const GrClip* clip,
const SkMatrixProvider& viewMatrix, const SkMatrixProvider& viewMatrix,
const SkPaint& paint,
skgpu::v1::SurfaceDrawContext* sdc) const; skgpu::v1::SurfaceDrawContext* sdc) const;
void doFlatten(SkWriteBuffer& buffer) const override; void doFlatten(SkWriteBuffer& buffer) const override;
SkRect sourceBounds() const override { return fSourceBounds; } SkRect sourceBounds() const override { return fSourceBounds; }
const SkPaint& paint() const override { return fPaint; } const SkPaint& initialPaint() const override { return fInitialPaint; }
// SkGlyphRunPainterInterface // SkGlyphRunPainterInterface
void processDeviceMasks( void processDeviceMasks(
@ -2268,33 +2270,33 @@ private:
// structure may have pointers into it. // structure may have pointers into it.
GrSubRunAllocator fAlloc; GrSubRunAllocator fAlloc;
const SkRect fSourceBounds; const SkRect fSourceBounds;
const SkPaint fPaint; const SkPaint fInitialPaint;
const SkMatrix fInitialPositionMatrix; const SkMatrix fInitialPositionMatrix;
const SkPoint fOrigin; const SkPoint fOrigin;
GrSubRunList fSubRuns; GrSubRunList fSubRuns;
}; };
Slug::Slug(SkRect sourceBounds, Slug::Slug(SkRect sourceBounds,
const SkPaint& paint, const SkPaint& initialPaint,
const SkMatrix& positionMatrix, const SkMatrix& positionMatrix,
SkPoint origin, SkPoint origin,
int allocSize) int allocSize)
: fAlloc {SkTAddOffset<char>(this, sizeof(Slug)), allocSize, allocSize/2} : fAlloc {SkTAddOffset<char>(this, sizeof(Slug)), allocSize, allocSize/2}
, fSourceBounds{sourceBounds} , fSourceBounds{sourceBounds}
, fPaint{paint} , fInitialPaint{initialPaint}
, fInitialPositionMatrix{positionMatrix} , fInitialPositionMatrix{positionMatrix}
, fOrigin{origin} { } , fOrigin{origin} { }
void Slug::surfaceDraw(SkCanvas* canvas, const GrClip* clip, const SkMatrixProvider& viewMatrix, void Slug::surfaceDraw(SkCanvas* canvas, const GrClip* clip, const SkMatrixProvider& viewMatrix,
skgpu::v1::SurfaceDrawContext* sdc) const { const SkPaint& drawingPaint, skgpu::v1::SurfaceDrawContext* sdc) const {
for (const GrSubRun& subRun : fSubRuns) { for (const GrSubRun& subRun : fSubRuns) {
subRun.draw(canvas, clip, viewMatrix, fOrigin, fPaint, sdc); subRun.draw(canvas, clip, viewMatrix, fOrigin, drawingPaint, sdc);
} }
} }
void Slug::doFlatten(SkWriteBuffer& buffer) const { void Slug::doFlatten(SkWriteBuffer& buffer) const {
buffer.writeRect(fSourceBounds); buffer.writeRect(fSourceBounds);
SkPaintPriv::Flatten(fPaint, buffer); SkPaintPriv::Flatten(fInitialPaint, buffer);
buffer.writeMatrix(fInitialPositionMatrix); buffer.writeMatrix(fInitialPositionMatrix);
buffer.writePoint(fOrigin); buffer.writePoint(fOrigin);
auto [subRunCount, subRunsUnflattenSizeHint] = this->subRunCountAndUnflattenSizeHint(); auto [subRunCount, subRunsUnflattenSizeHint] = this->subRunCountAndUnflattenSizeHint();
@ -2772,7 +2774,8 @@ void Slug::processDeviceMasks(
sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix, sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint, const SkPaint& initialPaint,
const SkPaint& drawingPaint,
const GrSDFTControl& control, const GrSDFTControl& control,
SkGlyphRunListPainter* painter) { SkGlyphRunListPainter* painter) {
// The difference in alignment from the per-glyph data to the SubRun; // The difference in alignment from the per-glyph data to the SubRun;
@ -2795,7 +2798,7 @@ sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
sk_sp<Slug> slug{new (::operator new (allocationSize)) sk_sp<Slug> slug{new (::operator new (allocationSize))
Slug(glyphRunList.sourceBounds(), Slug(glyphRunList.sourceBounds(),
paint, initialPaint,
positionMatrix, positionMatrix,
glyphRunList.origin(), glyphRunList.origin(),
bytesNeededForSubRun)}; bytesNeededForSubRun)};
@ -2805,7 +2808,7 @@ sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
painter->processGlyphRun(slug.get(), painter->processGlyphRun(slug.get(),
glyphRun, glyphRun,
positionMatrix, positionMatrix,
paint, drawingPaint,
control, control,
"Make Slug", "Make Slug",
uniqueID); uniqueID);
@ -2867,19 +2870,22 @@ void Slug::processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& accepted,
namespace skgpu::v1 { namespace skgpu::v1 {
sk_sp<GrSlug> sk_sp<GrSlug>
Device::convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList, const SkPaint& paint) { Device::convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
auto recordingContextPriv = this->recordingContext()->priv(); auto recordingContextPriv = this->recordingContext()->priv();
const GrSDFTControl control = recordingContextPriv.getSDFTControl( const GrSDFTControl control = recordingContextPriv.getSDFTControl(
this->surfaceProps().isUseDeviceIndependentFonts()); this->surfaceProps().isUseDeviceIndependentFonts());
return Slug::Make(this->asMatrixProvider(), return Slug::Make(this->asMatrixProvider(),
glyphRunList, glyphRunList,
paint, initialPaint,
drawingPaint,
control, control,
fSurfaceDrawContext->glyphRunPainter()); fSurfaceDrawContext->glyphRunPainter());
} }
void Device::drawSlug(SkCanvas* canvas, const GrSlug* grSlug) { void Device::drawSlug(SkCanvas* canvas, const GrSlug* grSlug, const SkPaint& drawingPaint) {
const Slug* slug = static_cast<const Slug*>(grSlug); const Slug* slug = static_cast<const Slug*>(grSlug);
auto matrixProvider = this->asMatrixProvider(); auto matrixProvider = this->asMatrixProvider();
#if defined(SK_DEBUG) #if defined(SK_DEBUG)
@ -2893,15 +2899,17 @@ void Device::drawSlug(SkCanvas* canvas, const GrSlug* grSlug) {
SkASSERT(slugMatrix == positionMatrix); SkASSERT(slugMatrix == positionMatrix);
} }
#endif #endif
slug->surfaceDraw(canvas, this->clip(), matrixProvider, fSurfaceDrawContext.get()); slug->surfaceDraw(
canvas, this->clip(), matrixProvider, drawingPaint, fSurfaceDrawContext.get());
} }
sk_sp<GrSlug> MakeSlug(const SkMatrixProvider& drawMatrix, sk_sp<GrSlug> MakeSlug(const SkMatrixProvider& drawMatrix,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint, const SkPaint& initialPaint,
const SkPaint& drawingPaint,
const GrSDFTControl& control, const GrSDFTControl& control,
SkGlyphRunListPainter* painter) { SkGlyphRunListPainter* painter) {
return Slug::Make(drawMatrix, glyphRunList, paint, control, painter); return Slug::Make(drawMatrix, glyphRunList, initialPaint, drawingPaint, control, painter);
} }
} // namespace skgpu::v1 } // namespace skgpu::v1

View File

@ -298,7 +298,8 @@ private:
namespace skgpu::v1 { namespace skgpu::v1 {
sk_sp<GrSlug> MakeSlug(const SkMatrixProvider& drawMatrix, sk_sp<GrSlug> MakeSlug(const SkMatrixProvider& drawMatrix,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint, const SkPaint& initialPaint,
const SkPaint& drawingPaint,
const GrSDFTControl& control, const GrSDFTControl& control,
SkGlyphRunListPainter* painter); SkGlyphRunListPainter* painter);
} // namespace skgpu::v1 } // namespace skgpu::v1

View File

@ -960,10 +960,11 @@ void Device::drawAtlas(const SkRSXform xform[],
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG) #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG)
void Device::testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas, void Device::testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
auto slug = this->convertGlyphRunListToSlug(glyphRunList, paint); const SkPaint& drawingPaint) {
auto slug = this->convertGlyphRunListToSlug(glyphRunList, initialPaint, drawingPaint);
if (slug != nullptr) { if (slug != nullptr) {
this->drawSlug(canvas, slug.get()); this->drawSlug(canvas, slug.get(), drawingPaint);
} }
} }
#endif #endif
@ -971,16 +972,18 @@ void Device::testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas,
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE) #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE)
void Device::testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas, void Device::testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
// This is not a text blob draw. Handle using glyphRunList conversion. // This is not a text blob draw. Handle using glyphRunList conversion.
if (glyphRunList.blob() == nullptr) { if (glyphRunList.blob() == nullptr) {
auto slug = this->convertGlyphRunListToSlug(glyphRunList, paint); auto slug = this->convertGlyphRunListToSlug(glyphRunList, initialPaint, drawingPaint);
if (slug != nullptr) { if (slug != nullptr) {
this->drawSlug(canvas, slug.get()); this->drawSlug(canvas, slug.get(), drawingPaint);
} }
return; return;
} }
auto srcSlug = GrSlug::ConvertBlob(canvas, *glyphRunList.blob(), glyphRunList.origin(), paint); auto srcSlug = GrSlug::ConvertBlob(
canvas, *glyphRunList.blob(), glyphRunList.origin(), initialPaint);
// There is nothing to draw. // There is nothing to draw.
if (srcSlug == nullptr) { if (srcSlug == nullptr) {
@ -992,7 +995,7 @@ void Device::testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas,
auto dstSlug = GrSlug::Deserialize(dstSlugData->data(), dstSlugData->size()); auto dstSlug = GrSlug::Deserialize(dstSlugData->data(), dstSlugData->size());
SkASSERT(dstSlug != nullptr); SkASSERT(dstSlug != nullptr);
if (dstSlug != nullptr) { if (dstSlug != nullptr) {
this->drawSlug(canvas, dstSlug.get()); this->drawSlug(canvas, dstSlug.get(), drawingPaint);
} }
} }
#endif #endif
@ -1052,10 +1055,15 @@ private:
} // namespace } // namespace
void Device::testingOnly_drawGlyphRunListWithSerializedSlugAndStrike( void Device::testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
SkCanvas* canvas, const SkGlyphRunList& glyphRunList, const SkPaint& paint) { SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
if (glyphRunList.blob() == nullptr) { if (glyphRunList.blob() == nullptr) {
fSurfaceDrawContext->drawGlyphRunList( auto slug = this->convertGlyphRunListToSlug(glyphRunList, initialPaint, drawingPaint);
canvas, this->clip(), this->asMatrixProvider(), glyphRunList, paint); if (slug != nullptr) {
this->drawSlug(canvas, slug.get(), drawingPaint);
}
return; return;
} }
@ -1080,7 +1088,7 @@ void Device::testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
auto srcSlug = GrSlug::ConvertBlob(analysisCanvas.get(), auto srcSlug = GrSlug::ConvertBlob(analysisCanvas.get(),
*glyphRunList.blob(), *glyphRunList.blob(),
glyphRunList.origin(), glyphRunList.origin(),
paint); initialPaint);
if (srcSlug == nullptr) { if (srcSlug == nullptr) {
return; return;
@ -1095,34 +1103,37 @@ void Device::testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
auto dstSlugData = srcSlug->serialize(); auto dstSlugData = srcSlug->serialize();
auto dstSlug = client.deserializeSlug(dstSlugData->data(), dstSlugData->size()); auto dstSlug = client.deserializeSlug(dstSlugData->data(), dstSlugData->size());
this->drawSlug(canvas, dstSlug.get()); this->drawSlug(canvas, dstSlug.get(), drawingPaint);
} }
#endif #endif
void Device::onDrawGlyphRunList(SkCanvas* canvas, void Device::onDrawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
ASSERT_SINGLE_OWNER ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v1::Device", "drawGlyphRunList", fContext.get()); GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v1::Device", "drawGlyphRunList", fContext.get());
SkASSERT(!glyphRunList.hasRSXForm()); SkASSERT(!glyphRunList.hasRSXForm());
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG) #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG)
this->testingOnly_drawGlyphRunListWithSlug(canvas, glyphRunList, paint); this->testingOnly_drawGlyphRunListWithSlug(canvas, glyphRunList, initialPaint, drawingPaint);
#elif defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE) #elif defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE)
this->testingOnly_drawGlyphRunListWithSerializedSlug(canvas, glyphRunList, paint); this->testingOnly_drawGlyphRunListWithSerializedSlug(
canvas, glyphRunList, initialPaint, drawingPaint);
#elif defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_STRIKE_SERIALIZE) #elif defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_STRIKE_SERIALIZE)
this->testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(canvas, glyphRunList, paint); this->testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
canvas, glyphRunList, initialPaint, drawingPaint);
#else #else
if (glyphRunList.blob() == nullptr) { if (glyphRunList.blob() == nullptr) {
// If the glyphRunList does not have an associated text blob, then it was created by one of // If the glyphRunList does not have an associated text blob, then it was created by one of
// the direct draw APIs (drawGlyphs, etc.). Use a Slug to draw the glyphs. // the direct draw APIs (drawGlyphs, etc.). Use a Slug to draw the glyphs.
auto slug = this->convertGlyphRunListToSlug(glyphRunList, paint); auto slug = this->convertGlyphRunListToSlug(glyphRunList, initialPaint, drawingPaint);
if (slug != nullptr) { if (slug != nullptr) {
this->drawSlug(canvas, slug.get()); this->drawSlug(canvas, slug.get(), drawingPaint);
} }
} else { } else {
fSurfaceDrawContext->drawGlyphRunList( fSurfaceDrawContext->drawGlyphRunList(
canvas, this->clip(), this->asMatrixProvider(), glyphRunList, paint); canvas, this->clip(), this->asMatrixProvider(), glyphRunList, drawingPaint);
} }
#endif #endif
} }

View File

@ -155,13 +155,17 @@ protected:
void onSave() override { fClip.save(); } void onSave() override { fClip.save(); }
void onRestore() override { fClip.restore(); } void onRestore() override { fClip.restore(); }
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override; void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
sk_sp<GrSlug> convertGlyphRunListToSlug( sk_sp<GrSlug> convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override; const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
void drawSlug(SkCanvas*, const GrSlug* slug) override; void drawSlug(SkCanvas*, const GrSlug* slug, const SkPaint& drawingPaint) override;
void onClipRect(const SkRect& rect, SkClipOp op, bool aa) override { void onClipRect(const SkRect& rect, SkClipOp op, bool aa) override {
SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference); SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);
@ -213,19 +217,22 @@ private:
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG) #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG)
void testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas, void testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint); const SkPaint& initialPaint,
const SkPaint& drawingPaint);
#endif #endif
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE) #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE)
void testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas, void testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint); const SkPaint& initialPaint,
const SkPaint& drawingPaint);
#endif #endif
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_STRIKE_SERIALIZE) #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_STRIKE_SERIALIZE)
void testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(SkCanvas* canvas, void testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint); const SkPaint& initialPaint,
const SkPaint& drawingPaint);
#endif #endif
// If not null, dstClip must be contained inside dst and will also respect the edge AA flags. // If not null, dstClip must be contained inside dst and will also respect the edge AA flags.

View File

@ -129,7 +129,8 @@ private:
void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override {} void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override {}
void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override {} void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override {}
void drawShadow(const SkPath&, const SkDrawShadowRec&) override {} void drawShadow(const SkPath&, const SkDrawShadowRec&) override {}
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override {} void onDrawGlyphRunList(
SkCanvas*, const SkGlyphRunList&, const SkPaint&, const SkPaint&) override {}
void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override {} void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override {}
void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice, void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice,

View File

@ -958,10 +958,11 @@ void SkPDFDevice::internalDrawGlyphRun(
void SkPDFDevice::onDrawGlyphRunList(SkCanvas*, void SkPDFDevice::onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
SkASSERT(!glyphRunList.hasRSXForm()); SkASSERT(!glyphRunList.hasRSXForm());
for (const SkGlyphRun& glyphRun : glyphRunList) { for (const SkGlyphRun& glyphRun : glyphRunList) {
this->internalDrawGlyphRun(glyphRun, glyphRunList.origin(), paint); this->internalDrawGlyphRun(glyphRun, glyphRunList.origin(), drawingPaint);
} }
} }

View File

@ -84,7 +84,10 @@ public:
const SkSamplingOptions&, const SkSamplingOptions&,
const SkPaint&, const SkPaint&,
SkCanvas::SrcRectConstraint) override; SkCanvas::SrcRectConstraint) override;
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override; void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override; void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override;
void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override; void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;

View File

@ -1106,10 +1106,11 @@ private:
void SkSVGDevice::onDrawGlyphRunList(SkCanvas* canvas, void SkSVGDevice::onDrawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
SkASSERT(!glyphRunList.hasRSXForm()); SkASSERT(!glyphRunList.hasRSXForm());
const auto draw_as_path = (fFlags & SkSVGCanvas::kConvertTextToPaths_Flag) || const auto draw_as_path = (fFlags & SkSVGCanvas::kConvertTextToPaths_Flag) ||
paint.getPathEffect(); drawingPaint.getPathEffect();
if (draw_as_path) { if (draw_as_path) {
// Emit a single <path> element. // Emit a single <path> element.
@ -1118,14 +1119,14 @@ void SkSVGDevice::onDrawGlyphRunList(SkCanvas* canvas,
AddPath(glyphRun, glyphRunList.origin(), &path); AddPath(glyphRun, glyphRunList.origin(), &path);
} }
this->drawPath(path, paint); this->drawPath(path, drawingPaint);
return; return;
} }
// Emit one <text> element for each run. // Emit one <text> element for each run.
for (auto& glyphRun : glyphRunList) { for (auto& glyphRun : glyphRunList) {
AutoElement elem("text", this, fResourceBucket.get(), MxCp(this), paint); AutoElement elem("text", this, fResourceBucket.get(), MxCp(this), drawingPaint);
elem.addTextAttributes(glyphRun.font()); elem.addTextAttributes(glyphRun.font());
SVGTextBuilder builder(glyphRunList.origin(), glyphRun); SVGTextBuilder builder(glyphRunList.origin(), glyphRun);

View File

@ -57,7 +57,10 @@ protected:
const SkPaint& paint, const SkPaint& paint,
bool pathIsMutable = false) override; bool pathIsMutable = false) override;
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override; void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override; void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override;
#ifdef SK_ENABLE_SKSL #ifdef SK_ENABLE_SKSL
void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override; void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;

View File

@ -284,7 +284,8 @@ void SkNWayCanvas::onDrawAtlas2(const SkImage* image, const SkRSXform xform[], c
} }
} }
void SkNWayCanvas::onDrawGlyphRunList(const SkGlyphRunList& list, const SkPaint &paint) { void SkNWayCanvas::onDrawGlyphRunList(const SkGlyphRunList& list,
const SkPaint &paint) {
Iter iter(fList); Iter iter(fList);
while (iter.next()) { while (iter.next()) {
iter->onDrawGlyphRunList(list, paint); iter->onDrawGlyphRunList(list, paint);

View File

@ -1898,7 +1898,8 @@ static bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) {
void SkXPSDevice::onDrawGlyphRunList(SkCanvas*, void SkXPSDevice::onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) { const SkPaint& initailPaint,
const SkPaint& drawingPaint) {
SkASSERT(!glyphRunList.hasRSXForm()); SkASSERT(!glyphRunList.hasRSXForm());
for (const auto& run : glyphRunList) { for (const auto& run : glyphRunList) {
@ -1912,7 +1913,7 @@ void SkXPSDevice::onDrawGlyphRunList(SkCanvas*,
TypefaceUse* typeface; TypefaceUse* typeface;
if (FAILED(CreateTypefaceUse(font, &typeface)) || if (FAILED(CreateTypefaceUse(font, &typeface)) ||
text_must_be_pathed(paint, this->localToDevice())) { text_must_be_pathed(drawingPaint, this->localToDevice())) {
SkPath path; SkPath path;
//TODO: make this work, Draw currently does not handle as well. //TODO: make this work, Draw currently does not handle as well.
//paint.getTextPath(text, byteLength, x, y, &path); //paint.getTextPath(text, byteLength, x, y, &path);
@ -1961,7 +1962,7 @@ void SkXPSDevice::onDrawGlyphRunList(SkCanvas*,
SkScalarToFLOAT(font.getSize()), SkScalarToFLOAT(font.getSize()),
XPS_STYLE_SIMULATION_NONE, XPS_STYLE_SIMULATION_NONE,
this->localToDevice(), this->localToDevice(),
paint)); drawingPaint));
} }
} }

View File

@ -92,7 +92,8 @@ protected:
const SkRect* srcOrNull, const SkRect& dst, const SkRect* srcOrNull, const SkRect& dst,
const SkSamplingOptions&, const SkPaint& paint, const SkSamplingOptions&, const SkPaint& paint,
SkCanvas::SrcRectConstraint) override; SkCanvas::SrcRectConstraint) override;
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override; void onDrawGlyphRunList(
SkCanvas*, const SkGlyphRunList&, const SkPaint&, const SkPaint&) override;
void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override; void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override;
void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override; void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;
void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override; void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override;