For vertices/patches with a shader and no texCoords, use positions
This was another surprising (to me) inconsistency. Just because these geometric primitives allow for explicit local coords, doesn't mean we should require them (vs. all others that implicitly sample using local position). Change-Id: If3e7f6077bd15891b06cd2ffc969f1a649305d42 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/290130 Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
1040e38363
commit
8219e91468
@ -9,6 +9,11 @@ Milestone 85
|
||||
|
||||
* <insert new release notes here>
|
||||
|
||||
* SkCanvas::drawVertices and drawPatch now support mapping an SkShader without explicit
|
||||
texture coordinates. If they're not supplied, the local positions (vertex position or
|
||||
patch cubic positions) will be directly used to sample the SkShader.
|
||||
https://review.skia.org/290130
|
||||
|
||||
* * *
|
||||
|
||||
Milestone 84
|
||||
|
@ -2164,8 +2164,11 @@ public:
|
||||
}
|
||||
|
||||
/** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
|
||||
If vertices texs and vertices colors are defined in vertices, and SkPaint paint
|
||||
contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
|
||||
If paint contains an SkShader and vertices does not contain texCoords, the shader
|
||||
is mapped using the vertices' positions.
|
||||
|
||||
If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
|
||||
SkBlendMode mode combines vertices colors with SkShader.
|
||||
|
||||
@param vertices triangle mesh to draw
|
||||
@param mode combines vertices colors with SkShader, if both are present
|
||||
@ -2183,8 +2186,11 @@ public:
|
||||
}
|
||||
|
||||
/** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
|
||||
If vertices texs and vertices colors are defined in vertices, and SkPaint paint
|
||||
contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
|
||||
If paint contains an SkShader and vertices does not contain texCoords, the shader
|
||||
is mapped using the vertices' positions.
|
||||
|
||||
If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
|
||||
SkBlendMode mode combines vertices colors with SkShader.
|
||||
|
||||
@param vertices triangle mesh to draw
|
||||
@param mode combines vertices colors with SkShader, if both are present
|
||||
@ -2217,7 +2223,8 @@ public:
|
||||
bottom-right, bottom-left order.
|
||||
|
||||
If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
|
||||
corners in top-left, top-right, bottom-right, bottom-left order.
|
||||
corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is
|
||||
nullptr, SkShader is mapped using positions (derived from cubics).
|
||||
|
||||
@param cubics SkPath cubic array, sharing common points
|
||||
@param colors color array, one for each corner
|
||||
@ -2245,7 +2252,8 @@ public:
|
||||
bottom-right, bottom-left order.
|
||||
|
||||
If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
|
||||
corners in top-left, top-right, bottom-right, bottom-left order.
|
||||
corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is
|
||||
nullptr, SkShader is mapped using positions (derived from cubics).
|
||||
|
||||
@param cubics SkPath cubic array, sharing common points
|
||||
@param colors color array, one for each corner
|
||||
|
@ -1967,6 +1967,17 @@ void SkCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
||||
// Preserve legacy behavior for Android: ignore the SkShader if there are no texCoords present
|
||||
if (paint.getShader() &&
|
||||
!(vertices->priv().hasTexCoords() || vertices->priv().hasCustomData())) {
|
||||
SkPaint noShaderPaint(paint);
|
||||
noShaderPaint.setShader(nullptr);
|
||||
this->onDrawVerticesObject(vertices, mode, noShaderPaint);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
this->onDrawVerticesObject(vertices, mode, paint);
|
||||
}
|
||||
|
||||
|
@ -268,11 +268,13 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
const uint16_t* indices = info.indices();
|
||||
const SkColor* colors = info.colors();
|
||||
|
||||
// make textures and shader mutually consistent
|
||||
// No need for texCoords without shader. If shader is present without explicit texCoords,
|
||||
// use positions instead.
|
||||
SkShader* shader = paint.getShader();
|
||||
if (!(shader && textures)) {
|
||||
shader = nullptr;
|
||||
if (!shader) {
|
||||
textures = nullptr;
|
||||
} else if (!textures) {
|
||||
textures = positions;
|
||||
}
|
||||
|
||||
// We can simplify things for certain blendmodes. This is for speed, and SkComposeShader
|
||||
@ -351,6 +353,14 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
// all opaque (and the blendmode will keep them that way
|
||||
}
|
||||
|
||||
// Positions as texCoords? The local matrix is always identity, so update once
|
||||
if (textures == positions) {
|
||||
SkMatrix localM;
|
||||
if (!updater->update(ctm, &localM)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, outerAlloc,
|
||||
fRC->clipShader());
|
||||
while (vertProc(&state)) {
|
||||
@ -360,9 +370,9 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
}
|
||||
|
||||
SkMatrix localM;
|
||||
if (texture_to_matrix(state, positions, textures, &localM) &&
|
||||
updater->update(ctm, &localM))
|
||||
{
|
||||
if ((textures == positions) ||
|
||||
(texture_to_matrix(state, positions, textures, &localM) &&
|
||||
updater->update(ctm, &localM))) {
|
||||
fill_triangle(state, blitter, *fRC, dev2, dev3);
|
||||
}
|
||||
}
|
||||
@ -378,7 +388,7 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
|
||||
const SkMatrixProvider* matrixProvider = fMatrixProvider;
|
||||
SkTLazy<SkPreConcatMatrixProvider> preConcatMatrixProvider;
|
||||
if (textures) {
|
||||
if (textures && (textures != positions)) {
|
||||
SkMatrix localM;
|
||||
if (!texture_to_matrix(state, positions, textures, &localM)) {
|
||||
continue;
|
||||
|
@ -940,12 +940,11 @@ static bool init_vertices_paint(GrContext* context,
|
||||
const SkPaint& skPaint,
|
||||
const SkMatrixProvider& matrixProvider,
|
||||
SkBlendMode bmode,
|
||||
bool hasTexs,
|
||||
bool hasColors,
|
||||
GrPaint* grPaint) {
|
||||
if (hasTexs && skPaint.getShader()) {
|
||||
if (skPaint.getShader()) {
|
||||
if (hasColors) {
|
||||
// When there are texs and colors the shader and colors are combined using bmode.
|
||||
// When there are colors and a shader, the shader and colors are combined using bmode.
|
||||
return SkPaintToGrPaintWithXfermode(context, colorInfo, skPaint, matrixProvider, bmode,
|
||||
grPaint);
|
||||
} else {
|
||||
@ -954,12 +953,11 @@ static bool init_vertices_paint(GrContext* context,
|
||||
}
|
||||
} else {
|
||||
if (hasColors) {
|
||||
// We have colors, but either have no shader or no texture coords (which implies that
|
||||
// we should ignore the shader).
|
||||
// We have colors, but no shader.
|
||||
return SkPaintToGrPaintWithPrimitiveColor(context, colorInfo, skPaint, matrixProvider,
|
||||
grPaint);
|
||||
} else {
|
||||
// No colors and no shaders. Just draw with the paint color.
|
||||
// No colors and no shader. Just draw with the paint color.
|
||||
return SkPaintToGrPaintNoShader(context, colorInfo, skPaint, matrixProvider, grPaint);
|
||||
}
|
||||
}
|
||||
@ -975,13 +973,9 @@ void SkGpuDevice::drawVertices(const SkVertices* vertices, SkBlendMode mode, con
|
||||
const SkRuntimeEffect* effect =
|
||||
paint.getShader() ? as_SB(paint.getShader())->asRuntimeEffect() : nullptr;
|
||||
|
||||
// Pretend that we have tex coords when using custom per-vertex data. The shader is going to
|
||||
// use those (rather than local coords), but our paint conversion remains the same.
|
||||
GrPaint grPaint;
|
||||
bool hasColors = info.hasColors();
|
||||
bool hasTexs = info.hasTexCoords() || info.hasCustomData();
|
||||
if (!init_vertices_paint(fContext.get(), fRenderTargetContext->colorInfo(), paint,
|
||||
this->asMatrixProvider(), mode, hasTexs, hasColors, &grPaint)) {
|
||||
this->asMatrixProvider(), mode, info.hasColors(), &grPaint)) {
|
||||
return;
|
||||
}
|
||||
fRenderTargetContext->drawVertices(this->clip(), std::move(grPaint), this->asMatrixProvider(),
|
||||
|
Loading…
Reference in New Issue
Block a user