From a21bbb027a3eff72f94063e59c894020abd73c3c Mon Sep 17 00:00:00 2001 From: Nolan Scobie Date: Thu, 28 Jul 2022 16:37:25 +0000 Subject: [PATCH] Fix Canvas#drawVertices color blending when no shader is provided Since https://skia-review.googlesource.com/c/skia/+/473676, Skia will blend paint and vertex colors when no shader is provided. This fix mimics the old behavior of ignoring the paint and using the vertex colors directly when no shader is provided. Additionally, centralizes some legacy compatability logic of disabling the shader if no texs array is provided. I think this simplifies the logic/cognitive overhead of understanding what compatability tweaks are being made to the call. Tests added in Iddb4d2a3872b905684ec57c0e039d0bd0ca64a71 Test: atest ExactCanvasTests Fix: 239398877 Change-Id: Ie9a6389b422cc0c315485d8a8097314cb6706538 --- libs/hwui/jni/android_graphics_Canvas.cpp | 28 +++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp index 0ef80ee107082..132234b38003a 100644 --- a/libs/hwui/jni/android_graphics_Canvas.cpp +++ b/libs/hwui/jni/android_graphics_Canvas.cpp @@ -407,14 +407,28 @@ static void drawVertices(JNIEnv* env, jobject, jlong canvasHandle, indices = (const uint16_t*)(indexA.ptr() + indexIndex); } - SkVertices::VertexMode mode = static_cast(modeHandle); + SkVertices::VertexMode vertexMode = static_cast(modeHandle); const Paint* paint = reinterpret_cast(paintHandle); - get_canvas(canvasHandle)->drawVertices(SkVertices::MakeCopy(mode, vertexCount, - reinterpret_cast(verts), - reinterpret_cast(texs), - reinterpret_cast(colors), - indexCount, indices).get(), - SkBlendMode::kModulate, *paint); + + // Preserve legacy Skia behavior: ignore the shader if there are no texs set. + Paint noShaderPaint; + if (jtexs == NULL) { + noShaderPaint = Paint(*paint); + noShaderPaint.setShader(nullptr); + paint = &noShaderPaint; + } + // Since https://skia-review.googlesource.com/c/skia/+/473676, Skia will blend paint and vertex + // colors when no shader is provided. This ternary uses kDst to mimic the old behavior of + // ignoring the paint and using the vertex colors directly when no shader is provided. + SkBlendMode blendMode = paint->getShader() ? SkBlendMode::kModulate : SkBlendMode::kDst; + + get_canvas(canvasHandle) + ->drawVertices(SkVertices::MakeCopy( + vertexMode, vertexCount, reinterpret_cast(verts), + reinterpret_cast(texs), + reinterpret_cast(colors), indexCount, indices) + .get(), + blendMode, *paint); } static void drawNinePatch(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,