Apply paint color to alpha-only textures in drawEdgeAAImageSet

This makes batch texture ops consistent with singleton texture ops, and
images drawn through a texture producer.

Bug: chromium:1102578
Change-Id: I490b20940ef6f1899396b786369271ce7130e8a9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/301540
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Michael Ludwig 2020-07-10 08:59:44 -04:00 committed by Skia Commit-Bot
parent d9eb219e80
commit 1c66ad940e
7 changed files with 104 additions and 38 deletions

View File

@ -34,12 +34,12 @@
// Makes a set of m x n tiled images to be drawn with SkCanvas::experimental_drawImageSetV1().
static void make_image_tiles(int tileW, int tileH, int m, int n, const SkColor colors[4],
SkCanvas::ImageSetEntry set[]) {
SkCanvas::ImageSetEntry set[], const SkColor bgColor=SK_ColorLTGRAY) {
const int w = tileW * m;
const int h = tileH * n;
auto surf = SkSurface::MakeRaster(
SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
surf->getCanvas()->clear(SK_ColorLTGRAY);
surf->getCanvas()->clear(bgColor);
static constexpr SkScalar kStripeW = 10;
static constexpr SkScalar kStripeSpacing = 30;
@ -288,7 +288,68 @@ private:
SkCanvas::ImageSetEntry fSet[kM * kN];
};
// This GM exercises alpha-only and color textures being combined correctly with the paint's color.
class DrawImageSetAlphaOnlyGM : public GM {
private:
SkString onShortName() override { return SkString("draw_image_set_alpha_only"); }
SkISize onISize() override { return {kM*kTileW, 2*kN*kTileH}; }
void onOnceBeforeDraw() override {
static constexpr SkColor kColors[] = {SK_ColorBLUE, SK_ColorTRANSPARENT,
SK_ColorRED, SK_ColorTRANSPARENT};
static constexpr SkColor kBGColor = SkColorSetARGB(128, 128, 128, 128);
make_image_tiles(kTileW, kTileH, kM, kN, kColors, fSet, kBGColor);
// Modify the alpha of the entries, decreasing by column, and convert even rows to
// alpha-only textures.
sk_sp<SkColorSpace> alphaSpace = SkColorSpace::MakeSRGB();
for (int y = 0; y < kN; ++y) {
for (int x = 0; x < kM; ++x) {
int i = y * kM + x;
fSet[i].fAlpha = (kM - x) / (float) kM;
if (y % 2 == 0) {
fSet[i].fImage = fSet[i].fImage->makeColorTypeAndColorSpace(
kAlpha_8_SkColorType, alphaSpace);
}
}
}
}
void onDraw(SkCanvas* canvas) override {
ToolUtils::draw_checkerboard(canvas, SK_ColorGRAY, SK_ColorDKGRAY, 25);
SkPaint paint;
paint.setFilterQuality(kLow_SkFilterQuality);
paint.setBlendMode(SkBlendMode::kSrcOver);
paint.setColor4f({0.2f, 0.8f, 0.4f, 1.f}); // colorizes even rows, no effect on odd rows
// Top rows use experimental edge set API
canvas->experimental_DrawEdgeAAImageSet(fSet, kM * kN, nullptr, nullptr, &paint,
SkCanvas::kFast_SrcRectConstraint);
canvas->translate(0.f, kN * kTileH);
// Bottom rows draw each image from the set using the regular API
for (int y = 0; y < kN; ++y) {
for (int x = 0; x < kM; ++x) {
int i = y * kM + x;
SkPaint entryPaint = paint;
entryPaint.setAlphaf(fSet[i].fAlpha * paint.getAlphaf());
canvas->drawImageRect(fSet[i].fImage.get(), fSet[i].fSrcRect, fSet[i].fDstRect,
&entryPaint, SkCanvas::kFast_SrcRectConstraint);
}
}
}
static constexpr int kM = 4;
static constexpr int kN = 4;
static constexpr int kTileW = 50;
static constexpr int kTileH = 50;
SkCanvas::ImageSetEntry fSet[kM * kN];
};
DEF_GM(return new DrawImageSetGM();)
DEF_GM(return new DrawImageSetRectToRectGM();)
DEF_GM(return new DrawImageSetAlphaOnlyGM();)
} // namespace skiagm

View File

@ -760,6 +760,7 @@ func (b *taskBuilder) dmFlags(internalHardwareLabel string) {
badSerializeGMs = append(badSerializeGMs, "makecolorspace")
badSerializeGMs = append(badSerializeGMs, "readpixels")
badSerializeGMs = append(badSerializeGMs, "draw_image_set_rect_to_rect")
badSerializeGMs = append(badSerializeGMs, "draw_image_set_alpha_only")
badSerializeGMs = append(badSerializeGMs, "compositor_quads_shader")
badSerializeGMs = append(badSerializeGMs, "wacky_yuv_formats_qtr")

File diff suppressed because one or more lines are too long

View File

@ -308,7 +308,7 @@ public:
SkRect fDstRect;
const SkPoint* fDstClipQuad; // Must be null, or point to an array of 4 points
const SkMatrix* fPreViewMatrix; // If not null, entry's CTM is 'viewMatrix' * fPreViewMatrix
float fAlpha;
SkPMColor4f fColor; // {a,a,a,a} for rgb textures, {r,g,b,a} for alpha-only textures
GrQuadAAFlags fAAFlags;
};
/**

View File

@ -323,6 +323,17 @@ static bool can_use_draw_texture(const SkPaint& paint) {
!paint.getImageFilter() && paint.getFilterQuality() < kMedium_SkFilterQuality);
}
static SkPMColor4f texture_color(SkColor4f paintColor, float entryAlpha, GrColorType srcColorType,
const GrColorInfo& dstColorInfo) {
paintColor.fA *= entryAlpha;
if (GrColorTypeIsAlphaOnly(srcColorType)) {
return SkColor4fPrepForDst(paintColor, dstColorInfo).premul();
} else {
float paintAlpha = SkTPin(paintColor.fA, 0.f, 1.f);
return { paintAlpha, paintAlpha, paintAlpha, paintAlpha };
}
}
// Assumes srcRect and dstRect have already been optimized to fit the proxy
static void draw_texture(GrRenderTargetContext* rtc, const GrClip* clip, const SkMatrix& ctm,
const SkPaint& paint, const SkRect& srcRect, const SkRect& dstRect,
@ -359,14 +370,8 @@ static void draw_texture(GrRenderTargetContext* rtc, const GrClip* clip, const S
constraint = SkCanvas::kStrict_SrcRectConstraint;
}
}
SkPMColor4f color;
if (GrColorTypeIsAlphaOnly(srcColorInfo.colorType())) {
color = SkColor4fPrepForDst(paint.getColor4f(), dstInfo).premul();
} else {
float paintAlpha = paint.getColor4f().fA;
color = { paintAlpha, paintAlpha, paintAlpha, paintAlpha };
}
SkPMColor4f color = texture_color(paint.getColor4f(), 1.f, srcColorInfo.colorType(), dstInfo);
if (dstClip) {
// Get source coords corresponding to dstClip
SkPoint srcQuad[4];
@ -851,7 +856,9 @@ void SkGpuDevice::drawEdgeAAImageSet(const SkCanvas::ImageSetEntry set[], int co
textures[i].fDstClipQuad = clip;
textures[i].fPreViewMatrix =
set[i].fMatrixIndex < 0 ? nullptr : preViewMatrices + set[i].fMatrixIndex;
textures[i].fAlpha = set[i].fAlpha * paint.getAlphaf();
textures[i].fColor = texture_color(paint.getColor4f(), set[i].fAlpha,
SkColorTypeToGrColorType(image->colorType()),
fRenderTargetContext->colorInfo());
textures[i].fAAFlags = SkToGrQuadAAFlags(set[i].fAAFlags);
if (n > 0 &&

View File

@ -607,9 +607,7 @@ private:
// Always append a quad (or 2 if perspective clipped), it just may refer back to a prior
// ViewCountPair (this frequently happens when Chrome draws 9-patches).
float alpha = SkTPin(set[q].fAlpha, 0.f, 1.f);
fViewCountPairs[p].fQuadCnt += this->appendQuad(
&quad, {alpha, alpha, alpha, alpha}, subset);
fViewCountPairs[p].fQuadCnt += this->appendQuad(&quad, set[q].fColor, subset);
}
// The # of proxy switches should match what was provided (+1 because we incremented p
// when a new proxy was encountered).
@ -1157,7 +1155,6 @@ void GrTextureOp::AddTextureSetOps(GrRenderTargetContext* rtc,
// automatically creates the appropriate GrFillRectOp to emulate GrTextureOp.
SkMatrix ctm;
for (int i = 0; i < cnt; ++i) {
float alpha = set[i].fAlpha;
ctm = viewMatrix;
if (set[i].fPreViewMatrix) {
ctm.preConcat(*set[i].fPreViewMatrix);
@ -1180,7 +1177,7 @@ void GrTextureOp::AddTextureSetOps(GrRenderTargetContext* rtc,
? &set[i].fSrcRect : nullptr;
auto op = Make(context, set[i].fProxyView, set[i].fSrcAlphaType, textureColorSpaceXform,
filter, {alpha, alpha, alpha, alpha}, saturate, blendMode, aaType,
filter, set[i].fColor, saturate, blendMode, aaType,
&quad, subset);
rtc->addDrawOp(clip, std::move(op));
}

View File

@ -102,7 +102,7 @@ static void bulk_texture_rect_create_test(skiatest::Reporter* reporter, GrContex
set[i].fDstRect = SkRect::MakeWH(100.5f, 100.5f); // prevent the int non-AA optimization
set[i].fDstClipQuad = nullptr;
set[i].fPreViewMatrix = nullptr;
set[i].fAlpha = 1.0f;
set[i].fColor = {1.f, 1.f, 1.f, 1.f};
set[i].fAAFlags = perQuadAA(i);
}