-
Notifications
You must be signed in to change notification settings - Fork 166
[GTK] Fix GC#copyArea() for overlapping source and target areas #1756 #1757
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
Conversation
@iloveeclipse can you please have a look at this? You were involved in the development of the workaround for the copyArea() issue (eclipse-platform/eclipse.platform.ui#2754), which this PR replaces with an actual solution of the underlying problem, as well as in the discussion on the regression we had because of that in the line number ruler this week. So would be great to have your opinion and/or testing of this (in the best case together with the removal of the Platform UI workaround eclipse-platform/eclipse.platform.ui#2754). |
I'm by no means a Cairo expert, so if I'm completely off here just say so and ignore my input :-) Drawing into a temporary surface: isn't this what |
Me too :-) I've tested this patch alone and also with reverted the UI workaround for line number ruler, everything seem to work |
@sravanlakkimsetti : I believe you were involved in earlier fixes in this area, do you have time to look into this PR? @HeikoKlare : if you want merge this, best before M3. |
Thank you for the pointer! I saw code using these methods in other cases of
Thank you for testing! If we agree that this change (or an improvement incorporating the above mentioned pointer) is fine and has low risk of regression, I would be in favor of merging as soon as possible to have some testing of this in daily use until M3/release. |
0ccebf5
to
e89afc8
Compare
Just implemented it that way (e89afc8) and it works perfectly fine for me (tested with line number ruler on X11, Wayland and by executing the added regression test). Much simpler and proper usage of Cairo API provided for this use case, so to me this now seems to be the right fix for the issue. Thank you, @tomaswolf! |
Last patch seem to work too. Please rebase on master. |
e89afc8
to
8b4543b
Compare
Glad to see my idea wasn't misleading at all. And thanks for using it; the code is much cleaner now! |
…se-platform#1756 The GC provides a #copyArea() method that copies an area inside the surface of the GC to another area in the same surface. When using a surface directly created via the Cairo API (or with the GDK API on Wayland), this operation is broken. When the source and target area are overlapping and the source is above-left of the target area, the source area will appear replicated in the target area, as Cairo does not perform any buffering but does a linewise/chunkwise write from the source area to the target area by default. This change fixes the behavior of GC#copyArea() by explicitly making Cairo first pipe the copied area into an intermediate surface to be painted into the actual target area afterwards. It also removes the existing workaround in images that avoids the instantiation of a surface via the Cairo API, as the reason for that workaround was the issue fixed by this change. It improves the behavior of consumers of that functionality on GTK4 and Wayland. An according regression test is added. Fixes eclipse-platform#1756
8b4543b
to
094abb8
Compare
Tested again after updating to I20250124-1800 on Ubuntu 24.04: With X11 everything is working as before. Using Wayland the previous glitches with the line number ruler are fixed. |
We seem to be facing a test failure in GEF, ever since the M3 went live (or to be more precise, starting with I20250124-1800, so I'm fairly certain this commit is responsible for this behavior. The test in question is checking whether anti-aliasing is working correctly, as shown below. The first line is how it currently looks like, the second line is what it's supposed to look like. Note that the second line is also what's shown on e.g. Windows. Weirdly enough, this issue only happens on the Jenkins/GitHub builds which are using Xvnc, but not when executed locally. Reason seems to be that Xvnc only supports up to 24 bit.
So my question: @HeikoKlare is there a technical reason for going from 24 to 32 bit? Because if I understand it correctly, Windows creates at most a 24bit handle: eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java Lines 1480 to 1487 in 857ac0b
The same for MacOS: eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java Line 1441 in 857ac0b
Would it make sense to go back to 24 bit for Linux as well, rather than being the odd one out? Especially if it risks causing visual glitches on systems that only support True Color? |
Thank you for the catch, @ptziegler!
I do not remember any technical reason for doing that. Actually, if I remember correctly, the intended change was to simply remove the Since both previous cases (if/else, GTK4/3) used a 24 bit color type for the created surface, it should be safe to revert that change. Thus I proposed: Maybe you want to check whether that PR fixes your test? |
The GC provides a #copyArea() method that copies an area inside the surface of the GC to another area in the same surface. When using a surface directly created via the Cairo API (or with the GDK API on Wayland), this operation is broken.
When the source and target area are overlapping and the source is above-left of the target area, the source area will appear replicated in the target area, as Cairo does not perform any buffering but does a linewise/chunkwise write from the source area to the target area.
This change fixes the behavior of GC#copyArea() by explicitly making Cairo first pipe the copied area into an intermediate surface to be painted into the actual target area afterwards. It also removes the existing workaround in images that avoids the instantiation of a surface via the Cairo API, as the reason for that workaround was the issue fixed by this change. The effect can be seen in the description of #1756. The operation now produces the result shown as the expected one in that issue, also on GTK4 and when using Wayland. An according regression test is added.
Fixes #1756
Can be tested in the line number ruler, which has also proper behavior on GTK4 and when using Wayland with this fix. Can also be tested together with eclipse-platform/eclipse.platform.ui#2754 resolving the workaround that was implemented to deal with the bug in SWT.
There might be better solutions than this (e.g., methods directly provided by Cairo that perform the buffering), but I did not find them yet and actually any solution will have to do something like the solution proposed here (buffering the area to be copied).