HumbleUI/Skija

Force no antialiasing when painting / set texture filter quality?

Closed this issue · 4 comments

I recently switched from SkiaSharp to Skija and so far, Skija is doing a fantastic job.
But I encountered two dissimilarities, I could not resolve:

  1. How do i "force" no antialiasing when painting. The function description states: paint.setAntiAlias() "requests" antialiasing being enabled or disabled. But in my case, it does not disable it, when I want it to. In SkiaSharp I was able to enable/disable antialiasing from one draw call to another (which was quite uesful in some scenarios) is this not possible in Skija?

  2. In SkiaSharp I had the option to set a "filterQuality" state when painting a texture/image. (Which gave me the option to set nearest neighbour, bilinear, trilienar filtering) but I simply cannot find this feature in Skija. Is texture filtering handled differently in Skija? [Solved!]

tonsky commented
  1. Seems to work for me. See
    var watchStroke = new Paint().setColor(0xFF000000).setMode(PaintMode.STROKE).setStrokeWidth(1f).setAntiAlias(false);
    var watchStrokeAA = new Paint().setColor(0xFF000000).setMode(PaintMode.STROKE).setStrokeWidth(1f);
    and the output it produces (left half no AA, right half AA):

Screenshot 2023-04-10 at 21 54 56

I also remember it working even for stuff like clip boundaries. Maybe it depends on what and how are you drawing?

  1. Take a look at
    for (var pair: Pair.arrayOf("None/None", SamplingMode.DEFAULT,
    "Linear/None", SamplingMode.LINEAR,
    "Linear/Nearest", new FilterMipmap(FilterMode.LINEAR, MipmapMode.NEAREST),
    "Linear/Linear", new FilterMipmap(FilterMode.LINEAR, MipmapMode.LINEAR),
    "Mitchell", SamplingMode.MITCHELL,
    "Catmull-Rom", SamplingMode.CATMULL_ROM,
    "Anisotropic(10)", new SamplingModeAnisotropic(10)))
    . This is what it gives me:

Screenshot 2023-04-10 at 21 58 12

Overall I’m trying to follow Skia API as close as possible. I think if something was possible in SkiaSharp, it should be possible in Skija, too. Might be a question of convenience, though (e.g. if SkiaSharp has some composite APIs that do not directly exist in Skia)

Thank you very much for your reply and for pointing me to the right Skija samples!
I managed to get texture filtering working. (Skija's implementaion is even more self explanatory than SkiaSharp, which is nice) So question 2 is solved.

But antialiasing in Skija still behaves kinda weird. For some reason, I can only disable antialiasing via paint.setAntiAlias() if I create the backend rendertarget with either 0 or 1 msaa samples... Any value higher that that, and antialiasing seems to be forced enabled. Which kinda sucks:

Because if I want to be able to switch aa on or off, depending on what I want to draw, I can only have "somewhat okay" aa. But if I want good aa (8 or 16 samples), I cannot turn it off anymore.

Backend rendertarget creation:

renderTarget = BackendRenderTarget.makeGL(
    getRenderResolution().getX(),
    getRenderResolution().getY(),
    /*msaaSamples*/1,
    /*stencil*/8,
    /*fbId*/0,
    FramebufferFormat.GR_GL_RGBA8);

surface = Surface.makeFromBackendRenderTarget(
    context,
    renderTarget,
    SurfaceOrigin.BOTTOM_LEFT,
    SurfaceColorFormat.RGBA_8888,
    ColorSpace.getSRGB(),
    new SurfaceProps(PixelGeometry.RGB_H));

Debug Drawing:

surface.getCanvas().clear(0x00000000);

Paint noaa = new Paint();
noaa.setColor(0xFFFFFFFF);
noaa.setAntiAlias(false);
surface.getCanvas().drawCircle(200, 200, 180, noaa);
if (noaa.isAntiAlias())
{
    //This does not trigger... so antialiasing should be disabled?
}

Paint aa = new Paint();
aa.setColor(0xFFFFFFFF);
aa.setAntiAlias(true);
surface.getCanvas().drawCircle(600, 200, 180, aa);

Backend rendertarget msaa samples set to [1]
1_msaa

Backend rendertarget msaa samples set to [16]
16_msaa

Maybe I'm missing something, but that is the only option I found, to be able to disable antialiasing on a per drawcall basis...

tonsky commented

Try asking at https://groups.google.com/g/skia-discuss/? Folks there are much more familiar with Skia itself, and devs are answering questions too

Ok, after reading through some of the discussions around AA on the skia forum, this behaviour seems to be more of a feature, than a bug...

The gist of it seems to be: If I want really good AA and be able to switch it on and off, just set the msaa samples to 0.
By doing so, Skia is applying its own AA method, which on closer inspection looks even better than native 16x MSAA.
If I set any value higher than 0, GPU based MSAA gets used instead. (Which might be faster, but for whatever reason, can't be disabled by setting paint.setAntiAlias())

So for now, I'm just gonna stick to 0 and hope for the best. Once I encounter performance issues with skias AA implemantaion I might have to take another look at the issue.

By the way, thank you again for your support!

aa