| [ Return to Bugs & Features | Roadmap 1.3 | SVN ⇄ GIT ]
STR #3206
Application: | FLTK Library |
Status: | 1 - Closed w/Resolution |
Priority: | 4 - High, e.g. key functionality not working |
Scope: | 2 - Specific to an operating system |
Subsystem: | X11 |
Summary: | (Re-)drawing artefacts with scheme plastic after STR 3059 |
Version: | 1.3-current |
Created By: | chris |
Assigned To: | AlbrechtS |
Fix Version: | 1.3.4 (SVN: v10771) |
Update Notification: | |
Trouble Report Files:
|
#1 | chris 09:54 Mar 09, 2015 |
| STR_3059.png 18k | |
|
#2 | AlbrechtS 07:13 Mar 12, 2015 |
| clip_box.patch 3k | |
|
#3 | AlbrechtS 07:20 Mar 12, 2015 |
| metacity_01_events.txt 2k | |
|
#4 | AlbrechtS 07:22 Mar 12, 2015 |
| metacity_01a.png 40k | |
|
#5 | AlbrechtS 07:26 Mar 12, 2015 |
| metacity_01b.png 42k | |
|
#6 | AlbrechtS 07:31 Mar 12, 2015 |
| unity_01_events.txt 2k | |
|
#7 | AlbrechtS 07:34 Mar 12, 2015 |
| hello.cxx 1k | |
|
#8 | AlbrechtS 06:15 Jun 15, 2015 |
| Fl_Pixmap_r10751.patch 3k | |
|
#9 | AlbrechtS 06:55 Jun 15, 2015 |
| Fl_Pixmap_r10753.patch 3k | |
|
#10 | manolo 04:25 Jun 18, 2015 |
| Fl_Pixmap2.patch 2k | |
|
#11 | manolo 01:51 Jun 19, 2015 |
| Fl_Pixmap3.patch 3k | |
|
#12 | manolo 10:00 Jun 19, 2015 |
| Fl_Pixmap4.patch 3k | |
|
#13 | AlbrechtS 14:15 Jun 19, 2015 |
| Fl_Pixmap5.patch 3k | |
|
#14 | AlbrechtS 14:32 Jun 19, 2015 |
| Fl_Pixmap5a.patch 3k | |
|
#15 | manolo 23:18 Jun 19, 2015 |
| Fl_Pixmap6.patch 2k | |
|
#16 | AlbrechtS 03:29 Jun 20, 2015 |
| Fl_Pixmap6a.patch 3k | |
|
#17 | AlbrechtS 14:54 Jun 20, 2015 |
| Fl_Pixmap7.patch 3k | |
|
#18 | AlbrechtS 05:11 Jun 21, 2015 |
| big_artefact.png 4k | |
|
#19 | AlbrechtS 05:29 Jun 21, 2015 |
| big_artefact_zoom.png 1k | |
Trouble Report Comments:
|
#1 | chris 09:54 Mar 09, 2015 |
| As STR 3059 is already closed, I had to create a new one.
Observing some redrawing issues with scheme "plastic" under Ubuntu 14.04 with svn rev 10610.
It seems that the rounded corners of the window title produce artefacts when moving them over a window with "plastic" background.
This can be seen with the demo program.
Attached is a screenshot, where the Fl_Input demo has been moved over the demo base window. | |
|
#2 | AlbrechtS 08:39 Mar 10, 2015 |
| Thanks for the report. I can't reproduce this though on the systems available to me, hence I need some more info and help.
It looks very much like a graphics driver or WM issue rather than a FLTK issue. It could be that FLTK does not get the appropriate expose events needed to draw the background and/or widgets. Unfortunately I have no concrete idea of what may be happening.
Looking at the posted image it seems that the artefacts are caused by the occluding window's title bar (top left corner) where something is drawn over the window below it or not redrawn as needed. Can you confirm that the artefacts are "caused" by the title bar's top left corner (or maybe also the top right corner)? Are there also artefacts at the bottom corners if you drag the window such that the bottom corners overlap?
More questions (sorry for the long list):
(1) General info: which WM etc. ? (I tested also on Ubuntu 14.04: no issue)
(2) Usage on local system or remote X server? If the latter, which X server?
(3) Maybe important: graphics card, driver, etc.
(4) Configuration options, particularly --enable-xdbe / --disable-xdbe
Please try different options. With --enable-xdbe make sure that the libs are available/installed/used (probably libXext?)
(5) Are you sure this issue appears after the fix of STR #3059)?
There are several svn revisions with updates, as noted in STR #3059:
r10584: Fixes background image drawing (incomplete). r10598: Fixes excessive image drawing of clipped areas. r10607: Fixes label drawing artefacts.
Please test all of these and at least on prior version if the issue occurs and report back here.
(6) Is it really only visible with the plastic scheme? If yes, is there a difference if only one of the programs is set to plastic, but the other is not? If yes, which one must have the plastic scheme: the program with the window that shows the artefacts, or the one you are dragging over the former? If there is a difference, what happens if you drag a non-FLTK program window over the FLTK window?
Last, but not least: for better testing you may try this:
test/demo -bg "#ee8844" -s plastic & test/input -bg "#4488ee" -s plastic
This should give your tests a colored background (orange and blue, resp.) and make it easier to identify where the artefacts are coming from (if they are still gray that may be caused by the WM itself).
Thanks for your help in advance. | |
|
#3 | AlbrechtS 08:42 Mar 10, 2015 |
| I should have added: if you use svn you can run
$ svn up -r nnnnn
to test one particular svn revision (nnnnn). | |
|
#4 | chris 10:56 Mar 10, 2015 |
| First the answers to your questions, but also see my new comments afterwards!
(1) I use Ubuntu 14.04 with gnome-session-flashback / Metacity.
(2) local
(3) Some Intel 4thGen Integrated...
(4) xdbe is enabled
(5) Appears with r10584
(6) Only with plastic theme, and it also happens with both top corners and also when dragging non-FLTK windows over the FLTK window. The color of the artefacts is the color of the background e.g. when using orange, it has the color of the lighter orange, which the buttons get (not the darker orange from the containing group).
New information: It's WM-specific. I don't get it with Unity But I have no such problems with any other application on my system.
Now it's clear: It comes from the Buttons. Only dragging over buttons with plastic theme leave such artefacts behind (tested with several other demo programs that have buttons).
I tested revision 10583: No problems.
HTH | |
|
#5 | chris 11:54 Mar 10, 2015 |
| I have to take back the statement, that it's with buttons only. It happens by dragging over all other widgets too (except image tiles). | |
|
#6 | AlbrechtS 04:11 Mar 11, 2015 |
| Thanks for your feedback and all the testing you did.
I can see the effect now after switching to Metacity. That's fine, now I can try to debug it.
Don't hold your breath though. I don't know yet when I will find the time to debug, and I don't know if we can fix it if the WM doesn't send the "right" events. Let's see... | |
|
#7 | AlbrechtS 08:14 Mar 11, 2015 |
| A short test with xev shows that Metacity sends lots of expose events (many different "slices") that do not contain the corner area that is responsible for the artefacts. My current theory is that FLTK draws the background (in a somewhat larger rectangular area) but misses to draw the widget afterwards. At least that is what it looks like now. This needs more debugging, but as I wrote before I'll have to do that later.
In case of Unity there are no expose events at all. Obviously Unity saves the window contents and restores it w/o the app's intervention. I assume this is so because Unity is a compositing window manager.
http://en.wikipedia.org/wiki/Compositing_window_manager
This makes me suspect that the issue can be visible with many other window managers as well. More to come... | |
|
#8 | AlbrechtS 07:13 Mar 12, 2015 |
| I made some progress. I found the culprit and a working solution, but maybe this is not the best solution we can have since it _can_ result in more drawing than necessary.
As documented in the patch file the problem was that the background drawing code in Fl_Xlib_Graphics_Driver::draw(Fl_Pixmap *pxm, ...) uses a slightly larger _rectangular_ clip region than the code drawing the widgets (the "clip box"). The delta area (the rectangular part around the rounded corners) was not drawn by the widget drawing code because it was clipped as intended (by the original clipping region).
The fix in clip_box.patch does the same as the Fl_Pixmap drawing code and makes sure that the widgets are (re)drawn over the background image.
Please test the attached file clip_box.patch and report if this patch works for you (use patch -p1 to patch the sources).
Does the patched software feel slower than the original version in the test, i.e. when dragging a window over the other one in your configuration (Metacity)? | |
|
#9 | AlbrechtS 07:20 Mar 12, 2015 |
| More info:
See attached file metacity_01_events.txt for events sent when the a part of the window that has been occluded by another window is exposed. The different areas result from the "rounded corner" of the occluding window. | |
|
#10 | AlbrechtS 07:22 Mar 12, 2015 |
| The image metacity_01a.png shows the correspondig artefacts after activating the partly occluded window. The previously occluding window can be seen in the bottom right corner. | |
|
#11 | AlbrechtS 07:26 Mar 12, 2015 |
| metacity_01b.png shows the situation after reactivating the previously occluding window. You can see the orange artefacts around the top left corner of the occluding window.
I used this test to generate exactly one artefact around the corner to see what happens in one case as opposed to dragging another window over the FLTK window which would leave a trace of artefacts as shown in the original window posted by Chris. | |
|
#12 | AlbrechtS 07:31 Mar 12, 2015 |
| Attached file unity_01_events.txt shows the events sent by Unity: no expose events at all. This is the reason why it worked with this WM. | |
|
#13 | AlbrechtS 07:34 Mar 12, 2015 |
| For completeness: the modified hello.cxx file used in the tests.
PS: I'm posting these files for review and easier testing by others in case someone might have a better idea (to prevent excessive drawing). | |
|
#14 | chris 11:26 Mar 12, 2015 |
| I can confirm, that with this patch most artefacts are gone, but there are still some left:
'tiled_image' demo (with all schemes!): dragging a window edge over the single button leaves artefacts.
'blocks' demo (also with all schemes): when in paused mode dragging over the blocks leaves artefacts.
I did not notice any speed penalties with the patch, but I have a rather fast machine... | |
|
#15 | AlbrechtS 05:45 Mar 13, 2015 |
| Thanks for confirmation and the new tests.
The new observations are not caused by the fix in r 10584 though. Both effects are visible in svn r 10583.
The artefacts shown in tiled_image are even visible in FLTK 1.1 (svn) and probably in all FLTK versions since 1.0.0 because the Fl_Pixmap drawing code did not change in that respect (using its own rectangular clipping).
I can't see the artefacts in blocks though in FLTK 1.1, but they are definitely visible in r 10583.
Conclusion: the artefacts can appear whenever a widget (Fl_Window, Fl_Group, or any other, e.g. Fl_Box) uses an Fl_Pixmap as its image, no matter if it's a full background or only an image displayed somewhere inside or outside the widget's box. The only requirement seems to be that something is drawn "over" the image - another widget in case of Fl_Group or anything else in a draw() method.
The posted patch can't fix this. The only way for a correct fix seems to be to fix the Fl_Pixmap drawing code. This is particularly important since we can't change draw() methods of custom (derived) widgets. | |
|
#16 | AlbrechtS 05:57 Mar 13, 2015 |
| Asking for help:
I'll take another look at the pixmap drawing code later (I don't know when this will be though), but contributions of everybody with X11 knowledge would be appreciated. The questionable code is in src/Fl_Pixmap.cxx (shown with line numbers as of svn r 10620):
184 #else // Xlib 185 void Fl_Xlib_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { 186 int X, Y, W, H; 187 if (pxm->prepare(XP, YP, WP, HP, cx, cy, X, Y, W, H)) return; 188 if (pxm->mask_) { 189 // I can't figure out how to combine a mask with existing region, 190 // so cut the image down to a clipped rectangle: 191 int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); 192 cx += nx-X; X = nx; 193 cy += ny-Y; Y = ny; 194 // make X use the bitmap as a mask: 195 XSetClipMask(fl_display, fl_gc, pxm->mask_); 196 int ox = X-cx; if (ox < 0) ox += pxm->w(); 197 int oy = Y-cy; if (oy < 0) oy += pxm->h(); 198 XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); 199 } 200 copy_offscreen(X, Y, W, H, pxm->id_, cx, cy);
See the comment in line #189/190 and line #195/198. This disables the active clip region and draws the image in the rectangular area surrounding the clip region (i.e. the "clip box", line #191).
Thinking loud ...
One way to fix this would be to modify the image mask (make the pixels outside the active clip regions transparent), but this would obviously mean to create another pixmap, which contradicts the idea to have the pixmap cached in the X server (see comment in line #28/29):
28 // Draws X pixmap data, keeping it stashed in a server pixmap so it 29 // redraws fast.
We could use XPointInRegion() to find out if any point is in the clip region (should be drawn) or not (should be transparent). At least that is how I read the docs. http://linux.die.net/man/3/xpointinregion http://www.x.org/archive/X11R7.5/doc/man/man3/XEmptyRegion.3.html
Ideas, anybody? | |
|
#17 | AlbrechtS 06:15 Jun 15, 2015 |
| Okay, I think I got it! Hopefully.
See attached file Fl_Pixmap_r10751.patch against svn r 10751. Please use `patch -p0' to apply to svn r 10751 (do not use the previous patch).
The chosen solution was to fix the pixmap drawing code. If the pixmap overlaps the non-rectangular clip region (as it was shown in the examples) we need to modify the pixmap's mask to account for the clip region. As the comment in the original source said, I also couldn't find a way to combine an existing clip region and an arbitrary bit mask of a pixmap directly, so I modified the pixmap's bitmask by drawing (copying) it into another offscreen pixmap with the original clip region applied. The resulting (clipped) bitmap is then used as the mask to draw the original Fl_Pixmap's data.
With this patch I couldn't see any artefacts. This also fixes the old (FLTK 1.0.0) drawing artefacts in the tiled_image and blocks demo programs.
Please test and report if this fixes the issue for you or if you can find any other side effects or speed issues. TIA. | |
|
#18 | AlbrechtS 06:55 Jun 15, 2015 |
| Uploaded slightly modified patch against svn r 10753.
Fl_Pixmap_r10753.patch. | |
|
#19 | manolo 05:47 Jun 18, 2015 |
| @Albrecht: I have seen (item #16 above) that you were willing to consider alternative ideas.
I confirm that Fl_Pixmap_r10753.patch does fix the issue that occurs when a pixmap is overdrawn by other graphics, and when the rounded corner of a window is moved over all of that.
After much headscratching, I finally understood what's going on in this issue, and doing that, an alternative solution came to my mind (Fl_Pixmap2.patch, attached). But I now see that it does not work if the clipping region is popped before more graphics gets drawn over the pixmap.
So, I withdraw Fl_Pixmap2.patch, and support that Fl_Pixmap_r10753.patch should be committed. | |
|
#20 | manolo 01:55 Jun 19, 2015 |
| Attached file Fl_Pixmap3.patch is a proposal to fix this issue differently.
It is simple because no new Pixmap needs construction. It accesses the rectangles that compose the clipping region, and draw each in turn. | |
|
#21 | AlbrechtS 03:31 Jun 19, 2015 |
| @Manolo: Thanks for your support. This issue is really a tricky one.
I read your patches and comments, and I agree with you that Fl_Pixmap3.patch is simple and looks good.
On a first glance:
- No additional pixmap is certainly an advantage. - Potentially more drawing calls may be a downside (more [network] traffic?). - Wouldn't it be better to use '#if(def) USE_X11' for '#include <X11/Xregion.h>' ?
We should also test performance. Background: I first tried a solution with fl_read_image to do the pixmap drawing in an offscreen and then copy the result using the normal clip region. I new that fl_read_image can be slow, and I could really see a "trail of window shadows" when dragging another window over a FLTK window with scheme 'plastic' on a fast intel i7 processor. Besides that something didn't work anyway, so I tried another solution which eventually became Fl_Pixmap_r10753.patch.
I'll try to test your patch on my system over the weekend. If it turns out to be fast enough, I think that I'd prefer your patch over mine. | |
|
#22 | manolo 10:01 Jun 19, 2015 |
| @Albrecht: see Fl_Pixmap4.patch (attached) following your suggested changes. | |
|
#23 | AlbrechtS 14:15 Jun 19, 2015 |
| Okay, I see that you used config.h and #if defined(USE_X11).
However I don't understand the other changes between Fl_Pixmap3.patch and Fl_Pixmap4.patch. Was there a reason why you changed it?
AFAICT ...
- Fl_Pixmap3.patch does the "complex drawing" only if we have a mask (pxm->mask_) and therefore have to set a clip mask (and hence destroy/overwrite the clip region).
- Fl_Pixmap4.patch does the "complex drawing" always, which is not really wrong, but certainly not as fast as just one copy_offscreen with the existing clip region.
My intention was to do it the simple way when we don't have a mask in the pixmap [1], so I tried to restore the behavior and merged Fl_Pixmap3.patch and Fl_Pixmap4.patch. As in Fl_Pixmap4.patch I removed the extra boolean variable, but used two else cases (see comments). That's a matter of taste, I wouldn't mind to have the boolean variable if you think this is better.
Anyway, I hope that Fl_Pixmap5.patch has "the best of both" Fl_Pixmap3.patch and Fl_Pixmap4.patch.
I did a few short tests (only Fl_Pixmap5.patch), and it seemed to work as expected. I'll do more tests later - it's too late now...
[1] The issue arises only if there is a Pixmap mask (transparency), so I think that Fl_Pixmap5.patch is a better choice. Or did I miss anything? | |
|
#24 | AlbrechtS 14:32 Jun 19, 2015 |
| Uploaded a simplified version: Fl_Pixmap5a.patch. | |
|
#25 | manolo 23:23 Jun 19, 2015 |
| Right. It was confusing not to process separately when there's no mask.
I suggest we simplify one last step removing this test: !(XRectInRegion(r, X, Y, W, H) == RectangleIn) We always draw in a loop, even if there's a single rectangle (see Fl_Pixmap6.patch attached). | |
|
#26 | AlbrechtS 03:29 Jun 20, 2015 |
| Awesome!
However we need to test clip_region() for 0 - otherwise we could crash with a segfault, for instance in test/pixmap(.cxx).
See attached Fl_Pixmap6a.patch.
This patch also restores the usage of USE_X11 and removes trailing spaces, but basically I added only the clip_region() test.
Some statistics: now we have 14 more lines of code, comprised of:
+5 lines for platform test and inclusion of <X11/Xregion.h> +6 lines for comments (+8, -2) +3 lines (net) for code (including removal of 5 lines of obsolete code)
And it works! | |
|
#27 | AlbrechtS 06:31 Jun 20, 2015 |
| Another optimization: instead of testing clip_region() inside the if().. block we could do:
if (pxm->mask_ && clip_region()) { // ...
This would be a tiny bit faster at runtime and make the intention more obvious.
Sorry, no time to create another patch right now... | |
|
#28 | manolo 09:21 Jun 20, 2015 |
| Agreed.
I see I removed in Fl_Pixmap6.patch the use of USE_X11. My mistake.
Also, there's a typo in comments: XHWH (instead of XYWH). | |
|
#29 | AlbrechtS 14:54 Jun 20, 2015 |
| Unfortunately my proposal (#27) doesn't work - we would not set the pixmap's clip mask if there is no clip region. The very first display of test/pixmap shows the effect (a black background).
Fl_Pixmap7.patch fixes this issue.
For performance reasons I wanted to avoid to allocate and destroy a (simple rectangular) region if it is not necessary, so I had to re-introduce another else case with the "standard" copy_offscreen() call. I decided to do it this way because I prefer runtime optimization over code size in this case.
I also renamed (X2, Y2) to (X1, Y1) and added W1 and H1 to avoid reusing W and H and make the code clearer to read, although I'm pretty sure the compiler won't generate much different code (if at all).
I hope that Fl_Pixmap7.patch is the last iteration. I believe that we can't do it any better than that. Thanks for the great team work.
Ready to commit? | |
|
#30 | manolo 00:03 Jun 21, 2015 |
| Yes, please, do commit.
I would like to improve the wording of the comment lines as follows:
// At this point, XYWH is the bounding box of the intersection between // the current clip region and the (portion of the) pixmap we have to draw. // The current clip region is often a rectangle. But, when a window with rounded // corners is moved above another window, expose events may create a complex clip // region made of several (e.g., 10) rectangles. We have to draw only in the clip // region, and also to mask out the transparent pixels of the image. This can't // be done in a single Xlib call for a multi-rectangle clip region. Thus, we // process each rectangle of the intersection between the clip region and XYWH. | |
|
#31 | AlbrechtS 05:11 Jun 21, 2015 |
| Fixed in Subversion repository.
Done and done - svn r 10771.
I committed the Fl_Pixmap7.patch and changed the comment as suggested. I also added a reference to this STR. | |
|
#32 | AlbrechtS 05:29 Jun 21, 2015 |
| Summary:
It turned out that drawing a pixmap could enlarge the clip region if the intersection of the clip region and the pixmap was not a single rectangle. Hence drawing the background pixmap would draw outside the clip region and leave artefacts when a widget was drawn on top of it.
This issue can only be seen when a non-compositing window manager like Metacity is used. This may generate multiple expose events that are combined in a multi-rectangle clip region. Compositing window managers like Unity keep the window contents in a cache and don't generate expose events in such cases.
The artefacts could be seen when a window with non-rectangular shape (for instance one with rounded corners, but also examples/shapedwindow.cxx) was dragged around and occluded another FLTK window with scheme 'plastic' and in many more cases, e.g. when a window was occluded partially by two or more other windows and then brought to the foreground by clicking on it.
To show this case I uploaded two more images: big_artefact.png and big_artefact_zoom.png. They have been "produced" by occluding the hello test program window with two other windows and then clicking on the test window. The artefact is generated by the top left corners of two windows. | |
|
#33 | AlbrechtS 06:02 Jun 30, 2015 |
| @OP (Chris): Can you confirm that the commit in svn r 10771 (included in the latest snapshot) fixes the issue for you? | |
|
#34 | chris 08:57 Jun 30, 2015 |
| Yes. No more artefacts with r10779 on my Ubuntu 14.04 with Metacity. | |
|
#35 | AlbrechtS 00:25 Jul 01, 2015 |
| Thanks for confirmation. | |
[ Return to Bugs & Features ]
|
| |