Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursor transparency problem on Linux AMD #1777

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 4 comments
Closed

Cursor transparency problem on Linux AMD #1777

SDLBugzilla opened this issue Feb 10, 2021 · 4 comments
Assignees
Milestone

Comments

@SDLBugzilla
Copy link
Collaborator

SDLBugzilla commented Feb 10, 2021

This bug report was migrated from our old Bugzilla tracker.

Reported in version: 2.0.2
Reported for operating system, platform: Linux, x86

Comments on the original bug report:

On 2015-02-22 12:28:02 +0000, fabio wrote:

After 0ad started to offer sdl2 support I tried it on Linux, and while it mostly works fine, I noticed that the mouse cursor has a problem, showing a white box when it should be transparent, see this image: http://trac.wildfiregames.com/raw-attachment/ticket/2823/sdl2-cursor.png

I originally reported the bug here:
http://trac.wildfiregames.com/ticket/2823

According to these:
https://forums.libsdl.org/viewtopic.php?t=10422
http://www.grimrock.net/forum/viewtopic.php?f=12&t=4583
there are other users and games with a similar issue, that happens on Linux with AMD cards (both open and fglrx drivers).

On 2015-02-24 04:28:01 +0000, Ryan C. Gordon wrote:

Ok, I don't know if this is a driver bug or our bug, but the PNG for that buggy cursor does in fact have a full-white block (r,g,b are all == 255) exactly where it's showing in the screenshot, even though it has an alpha of 0.

The parts that appear to mask out correctly are closer to black. A few pieces are r,g,b == 2,3,2, and I can't tell from the screenshot, but those might be showing up but just too hard to see. The white block is pretty obvious though.

So the quick fix is to edit that PNG and make that white block on the right black and it'll work correctly.

The reason for this is likely a driver bug (maybe it ignores alpha unless the rgb value is zero, too?). But it could be that every other driver offers Xcursor support and the fglxr driver doesn't...I don't know if that's true. But if that's the case, it's possible it forces SDL to generate a pixmap cursor and we have a bug there.

But I'm leaning towards it being a driver bug. :)

If someone could try this with 0ad: get yourself an SDL2 with debug symbols, and set a breakpoint on X11_CreateCursor. Does it end up calling X11_CreateXCursorCursor or X11_CreatePixmapCursor?

(Feel free to copy/paste this reply into the Trac ticket, too.)

--ryan.

On 2015-02-25 08:11:08 +0000, fabio wrote:

(In reply to Ryan C. Gordon from comment # 1)

The reason for this is likely a driver bug (maybe it ignores alpha unless
the rgb value is zero, too?). But it could be that every other driver offers
Xcursor support and the fglxr driver doesn't...I don't know if that's true.

Note that I can reproduce this issues also with mesa drivers (gallium r300, gallium llvmpipe and classic swarst).

If someone could try this with 0ad: get yourself an SDL2 with debug symbols,
and set a breakpoint on X11_CreateCursor. Does it end up calling
X11_CreateXCursorCursor or X11_CreatePixmapCursor?

I got this:

(gdb) break X11_CreateCursor
Function "X11_CreateCursor" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (X11_CreateCursor) pending.
(gdb) r
[...]
Breakpoint 1, X11_CreateCursor (surface=0x94c6888, hot_x=0, hot_y=0)
    at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/x11/SDL_x11mouse.c:205
205     /build/buildd/libsdl2-2.0.2+dfsg1/src/video/x11/SDL_x11mouse.c: File o directory non esistente.
(gdb) bt
# 0  X11_CreateCursor (surface=0x94c6888, hot_x=0, hot_y=0)
    at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/x11/SDL_x11mouse.c:205
# 1  0xb7658f6c in SDL_CreateColorCursor_REAL (surface=<optimized out>, hot_x=0, hot_y=0)
    at /build/buildd/libsdl2-2.0.2+dfsg1/src/events/SDL_mouse.c:655
# 2  0xb7651adc in SDL_CreateColorCursor (a=0x94c6888, b=0, c=0)
    at /build/buildd/libsdl2-2.0.2+dfsg1/src/dynapi/SDL_dynapi_procs.h:287
# 3  0x084eacf7 in create (hotspoty_=0, hotspotx_=0, pathname=..., vfs=
    std::shared_ptr (count 4, weak 0) 0x86eb280, this=0xb3b7197c)
    at ../../../source/lib/res/graphics/cursor.cpp:105
# 4  Cursor_reload (c=0xb3b71974, vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, name=...)
    at ../../../source/lib/res/graphics/cursor.cpp:285
# 5  0x084e5497 in call_init_and_reload (type=<optimized out>, type=<optimized out>,
    init_args=<synthetic pointer>, pathname=..., vfs=std::shared_ptr (count 4, weak 0) 0x86eb280,
    hd=0xb3b71950, h=3014702) at ../../../source/lib/res/h_mgr.cpp:446
# 6  alloc_new_handle (init_args=<synthetic pointer>, flags=<optimized out>, key=<optimized out>,
    pathname=..., vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, type=0x86d7b08 <V_Cursor>)
    at ../../../source/lib/res/h_mgr.cpp:489
# 7  h_alloc (type=0x86d7b08 <V_Cursor>, vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, pathname=...,
    flags=0) at ../../../source/lib/res/h_mgr.cpp:536
# 8  0x084e9c6f in cursor_load (forceGL=false, name=..., vfs=std::shared_ptr (count 4, weak 0) 0x86eb280)
    at ../../../source/lib/res/graphics/cursor.cpp:379
# 9  cursor_draw (vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, name=0x86e53f4 L"test", x=362, y=461,
    forceGL=false) at ../../../source/lib/res/graphics/cursor.cpp:406
# 10 0x0824f0e5 in Render () at ../../../source/ps/GameSetup/GameSetup.cpp:295
# 11 0x080725cc in Frame () at ../../../source/main.cpp:367
# 12 RunGameOrAtlas (argc=argc@entry=1, argv=argv@entry=0xbffff084) at ../../../source/main.cpp:511
# 13 0x0806218a in main (argc=1, argv=0xbffff084) at ../../../source/main.cpp:555

(Feel free to copy/paste this reply into the Trac ticket, too.)

Will do once we gather some other info :)

On 2015-02-26 09:36:43 +0000, fabio wrote:

I also tried setting a break on X11_CreatePixmapCursor but this one never get reached:

(gdb) break X11_CreatePixmapCursor
Function "X11_CreatePixmapCursor" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (X11_CreatePixmapCursor) pending.
(gdb) r
[...]

never reached.

While I get this when setting a break on X11_CreateXCursorCursor:

(gdb) break X11_CreateXCursorCursor
Function "X11_CreateXCursorCursor" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (X11_CreateXCursorCursor) pending.
(gdb) r
[...]
Breakpoint 1, X11_CreateCursor (surface=0x94cd788, hot_x=0, hot_y=0)
    at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/x11/SDL_x11mouse.c:214
214	/build/buildd/libsdl2-2.0.2+dfsg1/src/video/x11/SDL_x11mouse.c: File o directory non esistente.
(gdb) bt
# 0  X11_CreateCursor (surface=0x94cd788, hot_x=0, hot_y=0)
    at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/x11/SDL_x11mouse.c:214
# 1  0xb7658f6c in SDL_CreateColorCursor_REAL (surface=<optimized out>, hot_x=0, hot_y=0)
    at /build/buildd/libsdl2-2.0.2+dfsg1/src/events/SDL_mouse.c:655
# 2  0xb7651adc in SDL_CreateColorCursor (a=0x94cd788, b=0, c=0)
    at /build/buildd/libsdl2-2.0.2+dfsg1/src/dynapi/SDL_dynapi_procs.h:287
# 3  0x084eacf7 in create (hotspoty_=0, hotspotx_=0, pathname=..., vfs=
    std::shared_ptr (count 4, weak 0) 0x86eb280, this=0xb3b7197c)
    at ../../../source/lib/res/graphics/cursor.cpp:105
# 4  Cursor_reload (c=0xb3b71974, vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, name=...)
    at ../../../source/lib/res/graphics/cursor.cpp:285
# 5  0x084e5497 in call_init_and_reload (type=<optimized out>, type=<optimized out>, 
    init_args=<synthetic pointer>, pathname=..., vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, 
    hd=0xb3b71950, h=3014702) at ../../../source/lib/res/h_mgr.cpp:446
# 6  alloc_new_handle (init_args=<synthetic pointer>, flags=<optimized out>, key=<optimized out>, 
    pathname=..., vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, type=0x86d7b08 <V_Cursor>)
    at ../../../source/lib/res/h_mgr.cpp:489
# 7  h_alloc (type=0x86d7b08 <V_Cursor>, vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, pathname=..., 
    flags=0) at ../../../source/lib/res/h_mgr.cpp:536
# 8  0x084e9c6f in cursor_load (forceGL=false, name=..., vfs=std::shared_ptr (count 4, weak 0) 0x86eb280)
    at ../../../source/lib/res/graphics/cursor.cpp:379
# 9  cursor_draw (vfs=std::shared_ptr (count 4, weak 0) 0x86eb280, name=0x86e53f4 L"test", x=167, y=731, 
    forceGL=false) at ../../../source/lib/res/graphics/cursor.cpp:406
# 10 0x0824f0e5 in Render () at ../../../source/ps/GameSetup/GameSetup.cpp:295
# 11 0x080725cc in Frame () at ../../../source/main.cpp:367
# 12 RunGameOrAtlas (argc=argc@entry=1, argv=argv@entry=0xbffff084) at ../../../source/main.cpp:511
# 13 0x0806218a in main (argc=1, argv=0xbffff084) at ../../../source/main.cpp:555

On 2015-02-28 00:30:52 +0000, Philip Taylor wrote:

Did a test with this image as a cursor:

http://trac.wildfiregames.com/attachment/ticket/2823/alpha-test.png

and some demo renderings on light/dark backgrounds:

http://trac.wildfiregames.com/attachment/ticket/2823/cursor-blending.png

The top pair matches what I see on the proprietary NVIDIA drivers on Linux, and is the expected behaviour.

The bottom pair apparently matches what is seen on the AMD drivers which had the bug reported here.

For that demo, I rendered the cursor in GL with

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

for the top pair, and

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

for the bottom pair.

So in the incorrect case, it seems the drivers are blending the cursor as if it were using premultiplied alpha. But the image data is non-premultiplied, so that gives the wrong output whenever alpha!=255 and rgb!=0. Either the hardware needs to use the non-premultiplied blending equation, or the image needs to be converted to premultiplied before the hardware gets it. (But I don't know whether SDL or the display driver is meant to be responsible for that.)

On 2015-03-05 20:59:15 +0000, Torbjörn Andersson wrote:

Could this be what I'm seeing in Another World - 20th Anniversary Edition (purchased from GOG), as well? I do have an AMD Radeon R7 260X graphics card, and the cursor there is an arrow in a translucent magenta square. I was going to file a bug report to that game's bug tracker, but if it's already known, and possibly a driver issue, that seems unnecessary.

(Unfortunately, I can't provide any screenshots because every way I've tried to make one either doesn't show the cursor at all, or shows it correctly without the magenta background.)

On 2015-10-01 11:25:53 +0000, Andreas Löf wrote:

I've also observed this on 2.0.3.

@icculus icculus added this to the 2.0.20 milestone Nov 30, 2021
@icculus icculus removed the bug label Nov 30, 2021
@icculus icculus self-assigned this Nov 30, 2021
@Patola
Copy link

Patola commented Feb 9, 2022

Saw the call on twitter... System:
AMD Ryzen 9 5900X + AMD GPU RX 6800 XT with a MSI MPG X570 Gaming Plus. 32 GB RAM 3200 MHz. Arch Linux, Mesa 21.3.5-1, sdl2 2.0.20-1. I am using the regular amdgpu (open-source) kernel driver, RADV. Using Xorg. Bug does not seem to happen with me.
nada

@eriktorbjorn
Copy link

I should still have the same computer and graphics card as when I commented about Another World back in 2015. (It must have been fairly new then). The lspci command lists the graphics card as "Radeon R7 260X/360", at least. Another World's cursor looks fine to me, both on GOG and Steam, i.e. almost like the one you see briefly in the intro.

I don't see any cursor problems with Debian's 0ad package either (0.0.25b-1).

@icculus
Copy link
Collaborator

icculus commented Feb 9, 2022

Okay, it seems like this was a driver bug that got fixed (I never fixed this in Another World, as far as I recall, even if 0AD worked around it).

@icculus icculus closed this as completed Feb 9, 2022
@icculus
Copy link
Collaborator

icculus commented Feb 9, 2022

(Thanks everyone that tested this!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants