draw vertices: make shader invariants a little clearer

Make it clear that texture data and the paint shader
work in tandem.

Change-Id: Ifdb66632516eb2301c003de52aa678e450c61cc4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/425018
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2021-07-07 10:59:37 -04:00 committed by Skia Commit-Bot
parent cd947ac177
commit 55d339c348

View File

@ -276,18 +276,17 @@ void SkDraw::drawFixedVertices(const SkVertices* vertices, SkBlendMode blendMode
const uint16_t* indices = info.indices(); const uint16_t* indices = info.indices();
const SkColor* colors = info.colors(); const SkColor* colors = info.colors();
// No need for texCoords without shader. If shader is present without explicit texCoords,
// use positions instead.
SkShader* shader = paint.getShader(); SkShader* shader = paint.getShader();
if (!shader) { if (shader) {
if (!textures) {
textures = positions;
}
} else {
textures = nullptr; textures = nullptr;
} else if (!textures) {
textures = positions;
} }
// We can simplify things for certain blendmodes. This is for speed, and SkComposeShader // We can simplify things for certain blend modes. This is for speed, and SkComposeShader
// itself insists we don't pass kSrc or kDst to it. // itself insists we don't pass kSrc or kDst to it.
//
if (colors && textures) { if (colors && textures) {
switch (blendMode) { switch (blendMode) {
case SkBlendMode::kSrc: case SkBlendMode::kSrc:
@ -295,15 +294,14 @@ void SkDraw::drawFixedVertices(const SkVertices* vertices, SkBlendMode blendMode
break; break;
case SkBlendMode::kDst: case SkBlendMode::kDst:
textures = nullptr; textures = nullptr;
shader = nullptr;
break; break;
default: break; default: break;
} }
} }
// we don't use the shader if there are no textures // There is a paintShader iff there is texCoords.
if (!textures) { SkASSERT((textures != nullptr) == (shader != nullptr));
shader = nullptr;
}
/* We need to know if we have perspective or not, so we can know what stage(s) we will need, /* We need to know if we have perspective or not, so we can know what stage(s) we will need,
and how to prep our "uniforms" before each triangle in the tricolorshader. and how to prep our "uniforms" before each triangle in the tricolorshader.
@ -334,12 +332,12 @@ void SkDraw::drawFixedVertices(const SkVertices* vertices, SkBlendMode blendMode
} }
} }
SkPaint p(paint); SkPaint shaderPaint(paint);
p.setShader(sk_ref_sp(shader)); shaderPaint.setShader(sk_ref_sp(shader));
if (!textures) { // only tricolor shader if (!textures) { // only tricolor shader
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *fMatrixProvider, outerAlloc, if (auto blitter = SkCreateRasterPipelineBlitter(
this->fRC->clipShader())) { fDst, shaderPaint, *fMatrixProvider, outerAlloc, this->fRC->clipShader())) {
while (vertProc(&state)) { while (vertProc(&state)) {
if (triShader && if (triShader &&
!triShader->update(ctmInverse, positions, dstColors, !triShader->update(ctmInverse, positions, dstColors,
@ -354,13 +352,19 @@ void SkDraw::drawFixedVertices(const SkVertices* vertices, SkBlendMode blendMode
SkRasterPipeline pipeline(outerAlloc); SkRasterPipeline pipeline(outerAlloc);
SkStageRec rec = { SkStageRec rec = {
&pipeline, outerAlloc, fDst.colorType(), fDst.colorSpace(), p, nullptr, *fMatrixProvider &pipeline,
outerAlloc,
fDst.colorType(),
fDst.colorSpace(),
shaderPaint,
nullptr,
*fMatrixProvider
}; };
if (auto updater = as_SB(shader)->appendUpdatableStages(rec)) { if (auto updater = as_SB(shader)->appendUpdatableStages(rec)) {
bool isOpaque = shader->isOpaque(); bool isOpaque = shader->isOpaque();
if (triShader) { if (triShader) {
isOpaque = false; // unless we want to walk all the colors, and see if they are isOpaque = false; // unless we want to walk all the colors, and see if they are
// all opaque (and the blendmode will keep them that way // all opaque (and the blend mode will keep them that way
} }
// Positions as texCoords? The local matrix is always identity, so update once // Positions as texCoords? The local matrix is always identity, so update once
@ -371,8 +375,8 @@ void SkDraw::drawFixedVertices(const SkVertices* vertices, SkBlendMode blendMode
} }
} }
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, outerAlloc, if (auto blitter = SkCreateRasterPipelineBlitter(
fRC->clipShader())) { fDst, shaderPaint, pipeline, isOpaque, outerAlloc, fRC->clipShader())) {
while (vertProc(&state)) { while (vertProc(&state)) {
if (triShader && !triShader->update(ctmInverse, positions, dstColors, if (triShader && !triShader->update(ctmInverse, positions, dstColors,
state.f0, state.f1, state.f2)) { state.f0, state.f1, state.f2)) {
@ -407,8 +411,8 @@ void SkDraw::drawFixedVertices(const SkVertices* vertices, SkBlendMode blendMode
matrixProvider = preConcatMatrixProvider.init(*matrixProvider, localM); matrixProvider = preConcatMatrixProvider.init(*matrixProvider, localM);
} }
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, *matrixProvider, &innerAlloc, if (auto blitter = SkCreateRasterPipelineBlitter(
this->fRC->clipShader())) { fDst, shaderPaint, *matrixProvider, &innerAlloc, this->fRC->clipShader())) {
fill_triangle(state, blitter, *fRC, dev2, dev3); fill_triangle(state, blitter, *fRC, dev2, dev3);
} }
} }