FLTK logo

STR #3206

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 Home  |  Articles & FAQs  |  Bugs & Features  |  Documentation  |  Download  |  Screenshots  ]
 

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:

Receive EMails Don't Receive EMails

Trouble Report Files:


Name/Time/Date Filename/Size  
 
#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:


Name/Time/Date Text  
 
#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 ]

 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.