SkShader color input params

129 views
Skip to first unread message

Clark Kent

unread,
Sep 7, 2022, 9:43:27 AM9/7/22
to skia-discuss
in regards to the params specified here

is the color obtained from the current paint object?
or from the canvas object's current layer pixels?

    // Color filter SkSL requires an entry point that looks like:
    //     vec4 main(vec4 inColor) { ... }
    static Result MakeForColorFilter(SkString sksl, const Options&);
    static Result MakeForColorFilter(SkString sksl) {
        return MakeForColorFilter(std::move(sksl), Options{});
    }

    // Shader SkSL requires an entry point that looks like:
    //     vec4 main(vec2 inCoords) { ... }
    //   -or-
    //     vec4 main(vec2 inCoords, vec4 inColor) { ... }
    //
    // Most shaders don't use the input color, so that parameter is optional.
    static Result MakeForShader(SkString sksl, const Options&);
    static Result MakeForShader(SkString sksl) {
        return MakeForShader(std::move(sksl), Options{});
    }

    // Blend SkSL requires an entry point that looks like:
    //     vec4 main(vec4 srcColor, vec4 dstColor) { ... }
    static Result MakeForBlender(SkString sksl, const Options&);
    static Result MakeForBlender(SkString sksl) {
        return MakeForBlender(std::move(sksl), Options{});
    }

Brian Osman

unread,
Sep 7, 2022, 10:04:10 AM9/7/22
to skia-d...@googlegroups.com
It depends on which skia object (each one represents a different stage in Skia's pipeline). For an SkShader, the (optional) inColor is generally the paint color. (It will be the opaque paint color, because paint alpha is handled separately). For a color filter, the input color will be the output of the paint's SkShader (which will be the paint color if there's no SkShader, or the image color for something like drawImage). For the SkBlender, srcColor will be the output of the color filter (again, this might be the SkShader if there's no color filter, etc...). dstColor for the blender will be the existing color on the surface. It is worth mentioning that using a custom blender can be slow (at least slower than not doing it). On some mobile hardware, we can get access to the existing destination color cheaply (using certain GL extensions, etc), but on desktop hardware that's not normally an option. In that case, we have to make a copy of the surface, and read from that. (This all happens automatically behind the scenes, but the make-a-copy step tends to be one of the slower operations you might encounter, so I just wanted to bring it up).

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/122f42db-ce52-4fd2-a19b-0347f74794c3n%40googlegroups.com.

Clark Kent

unread,
Sep 7, 2022, 10:09:36 AM9/7/22
to skia-discuss
alright, thanks :)

also is there such a way to operate on the surface/canvas pixels directly instead of having to read/copy into CPU and then pass that in as a shader?

Brian Osman

unread,
Sep 7, 2022, 10:17:02 AM9/7/22
to skia-d...@googlegroups.com
Skia will always try to use the most efficient technique to get access to those pixels, so if you use a custom blender, there's not really anything else you can do. However: Skia won't actually pull those pixels all the way back to the CPU. The copy we make will be to a temporary texture that's still on the GPU.

Clark Kent

unread,
Sep 7, 2022, 10:21:37 AM9/7/22
to skia-discuss
and that is for a Blender, right?

eg if a Shader or ColorFilter is used instead then the canvas pixels are never sent to the inColor unless manually grabbed as a shader and sampled from in the sksl itself?

Brian Osman

unread,
Sep 7, 2022, 10:35:05 AM9/7/22
to skia-d...@googlegroups.com
Yes, that's correct.

Clark Kent

unread,
Sep 7, 2022, 10:41:13 AM9/7/22
to skia-discuss
so if the intent is to transform the current canvas's pixels, would using a blender be faster than other methods?

Clark Kent

unread,
Sep 7, 2022, 10:43:44 AM9/7/22
to skia-discuss
eg

for surface backed canvas

  grab surface
  obtain image snapshot
  convert image to shader

for bitmap backed canvas

  somehow find original bitmap object the surface is associated with
  convert bitmap to shader

Brian Osman

unread,
Sep 7, 2022, 10:44:06 AM9/7/22
to skia-d...@googlegroups.com
Yes - depending on the exact situation, some other methods might be as fast, but not in general. Using a blender should always be at least as fast as any other technique, and will often be faster.

Clark Kent

unread,
Sep 7, 2022, 10:49:17 AM9/7/22
to skia-discuss
nice :)

also for a bitmap backed canvas, does the blender have direct access to the canvas's associated bitmap?

eg, the blender can internally obtain the canvas bitmap device and know how to interact with such



also is it currently possible in the public API to obtain the currently backed bitmap from a canvas without having to pass the bitmap itself along with the canvas)

Clark Kent

unread,
Sep 7, 2022, 10:52:02 AM9/7/22
to skia-discuss
eg, instead of

(SkCanvas* canvas, SkBitmap* bitmap) {
// ...
}

we can do

(SkCanvas * canvas) {
// ...
SkBitmap * bitmap = canvas->SOMEHOW_OBTAIN_BITMAP();

Brian Osman

unread,
Sep 7, 2022, 11:09:11 AM9/7/22
to skia-d...@googlegroups.com
Yes (sort of). If you make a blender and use it with a CPU (bitmap) canvas/surface - the blender's dstColor will come directly from the destination pixels while the draw is being processed. The blender doesn't really get access to "the bitmap", just because that's not how Skia works internally - all the parts of the SkPaint are combined together to create a single optimized routine that does everything (read any textures, include the paint color, run the SkShader, run the SkColorFilter, read the destination, do blending, write out the new color, ...). If you write a custom blender, it just ends up inserting the code into that "do blending" part of the pipeline - the code to read the destination color remains like it would even if you were doing normal (kSrcOver) blending on the CPU.

Clark Kent

unread,
Sep 7, 2022, 11:27:27 AM9/7/22
to skia-discuss
so as part of the pipeline, the blender's dstcolor comes directly from the "output" of the "previous canvas draw operation"

eg if we clear to blue, the "dstcolor" of the next op would be "blue"

if we draw an image, the "dstcolor" of the next op would be that image as if converted to a shader and passed to dstcolor via sample

if we draw a path, the "dstcolor" of the next op would be whatever the path drew in regards to the current pixel being blended

Clark Kent

unread,
Sep 7, 2022, 11:30:22 AM9/7/22
to skia-discuss
or rather, it would be the current canvas output as it would appear if flushed to the screen/image

eg if we clear blue then draw path, the next op "dstcolor" would recieve blue and the drawn path, as if the canvas had drew to a bitmap and then sampled the bitmap's output as an image for the next op's dstcolor

Brian Osman

unread,
Sep 7, 2022, 11:34:11 AM9/7/22
to skia-d...@googlegroups.com
Right - the second thing you said. The dstColor is whatever the total color of the surface is up to that point (the blended result of all previous operations). It's exactly the same as whatever the destination color would be if you just did normal blending (src-over or any other SkBlendMode). From Skia's standpoint, the blender is EXACTLY like letting you replace the "standard" blend equation with whatever math/logic you want.

Clark Kent

unread,
Sep 7, 2022, 11:41:40 AM9/7/22
to skia-discuss
:)

Clark Kent

unread,
Sep 14, 2022, 9:20:37 PM9/14/22
to skia-d...@googlegroups.com
How would this affect the recently removed color input on shaders?

Clark Kent

unread,
Sep 15, 2022, 7:56:18 AM9/15/22
to skia-discuss
mainly https://groups.google.com/a/skia.org/g/bugs/c/Hb4NSwjkTqI - Deprecate two-argument RuntimeShader main(float2 coords, half4 color)

Brian Osman

unread,
Sep 15, 2022, 8:29:52 AM9/15/22
to skia-d...@googlegroups.com
Good catch. That change removed the optional paintColor input to shaders. It was almost never used, and you can get the same effect by declaring a `uniform shader`, leaving it as `nullptr` on the SkRuntimeShaderBuilder, and then calling eval() on it. Note that the color inputs to other stages (blender and colorFilter) still work exactly like they did before (and we have no intention of changing or removing those).

Clark Kent

unread,
Sep 15, 2022, 9:14:11 AM9/15/22
to skia-discuss
to clarify, would that be the same as doing this?

AsRuntimeEffectBuilder(builder)->child(name) = nullptr;

and

AsRuntimeEffectBuilder(builder)->child(name) = sk_ref_sp<SkShader>(AsShader(nullptr));

?
Reply all
Reply to author
Forward
0 new messages