After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 759287 - Canvas Tearing While in Rotated Canvas View
Canvas Tearing While in Rotated Canvas View
Status: RESOLVED FIXED
Product: GIMP
Classification: Other
Component: General
2.9.2
Other All
: High blocker
: 2.10
Assigned To: GIMP Bugs
GIMP Bugs
: 701415 (view as bug list)
Depends on:
Blocks: 701415
 
 
Reported: 2015-12-10 06:37 UTC by fullraidofblast
Modified: 2018-01-10 03:00 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Canvas looks tearing/destroyed/ruined/whatever (102.12 KB, image/jpeg)
2015-12-10 06:37 UTC, fullraidofblast
  Details
first attempt (6.65 KB, patch)
2015-12-14 09:15 UTC, Massimo
needs-work Details | Review
Alternative approach (5.06 KB, patch)
2015-12-15 07:28 UTC, Massimo
needs-work Details | Review
fixes artifacts moving brush outline on rotated canvas with transparency (2.57 KB, patch)
2016-10-15 05:40 UTC, Massimo
needs-work Details | Review
Left: unrotated - Right: rotated (163.96 KB, image/png)
2018-01-07 19:10 UTC, Jehan
  Details
screenshot showing zig-zag edges (64.75 KB, image/png)
2018-01-09 16:59 UTC, Elle Stone
  Details

Description fullraidofblast 2015-12-10 06:37:13 UTC
Created attachment 317089 [details]
Canvas looks tearing/destroyed/ruined/whatever

First sorry for bad English... :D

Canvas looks tearing/destroyed/ruined/whatever (look at attachment)

Steps to reproduce:
1. Open an image without alpha channel (.jpeg)
2. Lower its opacity, make it transparent <-- this is kinda important to being able to reproduce
3. Create a new layer
4. 'Rotate' the canvas (using shift+space or keyboard assigned to it)
5. Use paint tools on the new layer

Actual Result:
Canvas looks 'teared/destroyed/ruined/whatever', but only in rotated canvas view. If I reset the canvas rotation, it back to normal and don't show any problem. 

Expected Result:
Canvas act normally, just like when using Krita or MyPaint

Temporary solution:
Add an extra layer at the most back of the layer (layer without alpha channel or layer filled with color on 100% opacity) <-- this makes the 'canvas tearing' disappear

LinuxMint 17 XCFE

By the way, is it normal that the white grid appear?
Comment 1 Alexandre Prokoudine 2015-12-11 18:34:10 UTC
Thanks for reporting!

Trying to reproduce without luck so far... 

Made two layers:

1) bottom layer without alpha channel, any opacity between 0% and 100%.
2) top layer with solid color fill, opacity 100%.

Rotated canvas.

Tried painting.

Can't see either white grid or destroyed canvas: http://i.imgur.com/9YfACQJ.png.

I do vaguely recall seeing some sort of grid above rotated canvas about two years ago when canvas rotation was first introduced. But it'd be difficult for me to tell if that was original implementation in GIMP Painter or implementation in GIMP at the time.

LinuxMint 17 was released 1.5 years ago. This could be some bug in Cairo that has been fixed since then. Let's see if someone can clarify this.
Comment 2 Massimo 2015-12-12 10:56:20 UTC
(In reply to Alexandre Prokoudine from comment #1)
> Thanks for reporting!
> 
> Trying to reproduce without luck so far... 
> 
> Made two layers:
> 
> 1) bottom layer without alpha channel, any opacity between 0% and 100%.

add the alpha channel to a red bottom layer and set opacity to 50%

> 2) top layer with solid color fill, opacity 100%

and paint on a transparent top layer, for example, but
is enough to move the brush on it

> 
> Rotated canvas.
> 
> Tried painting.
> 
> Can't see either white grid or destroyed canvas:

Not always white, it depends on the image colors, but I
can reproduce it.

And I think it is a duplicate or related to 

https://bugzilla.gnome.org/show_bug.cgi?id=701415
Comment 3 Massimo 2015-12-14 09:15:09 UTC
Created attachment 317336 [details] [review]
first attempt

The attached patch is a first attempt to fix this
problem. When there is a rotation it renders the projection
over the checkers in a opaque group which is then painted
to the window using the ADD operator. It requires to clear
the window to black (0) because apparently the canvas padding
color is painted even inside the image bounds, at least in
some cases.

It seems to work, I did not test the foreground selection mask
and hi ppi screen scaling.

I suspect that there is a simpler way to fix this problem
chunking in transformed space, instead of image space, in
gimp_display_shell_draw_image (app/display/gimpdisplayshell-draw.c),
that way chunks would be always whole pixels wide/high and
there would be no transparency/coverage mixing.
Comment 4 Massimo 2015-12-15 07:28:30 UTC
Created attachment 317405 [details] [review]
Alternative approach

The attached patch is a proof of concept of the alternative
approach I had in mind.

It does not deal with different X/Y image resolutions and
when chunking is necessary it recursively splits the area in 4,
but it shows that it is possible to simplify the rendering
code without artifacts.
Comment 5 Michael Natterer 2016-10-14 23:04:28 UTC
In any case we must fix this for 2.10.

I still don't really understand what exactly is happening, but I haven't
looked at this in quite a while. Can you quickly summarize what exactly
the problem is?
Comment 6 Massimo 2016-10-15 05:40:26 UTC
Created attachment 337749 [details] [review]
fixes artifacts moving brush outline on rotated canvas with transparency

Here there are two problems: one is the 'grid'.

The second is that when rendering rotated content, the source
area required includes an excess that is currently painted more
times when the exposed area is split in many rectangles.

It works only when the content is fully transparent/opaque.

IOW there is one big clip for the exposed area, but rendering
in chunks requires one clip for chunk.

The attached patch fixes this second problem, clipping in
screen/canvas space each rectangle.

Besides that, I'm not sure the code deals properly with images and
displays both having resx != resy, it seems too simple, but I could be
wrong.
Comment 7 Michael Schumacher 2016-10-20 22:33:03 UTC
Does the third patch obsolete the previous two?
Comment 8 Massimo 2016-10-21 04:36:50 UTC
N0, but none of them is complete so I'm going to mark them all
needs-work
Comment 9 Jehan 2017-12-04 19:19:53 UTC
Adding a link to bug 701415 which is also about some canvas corruption when painting on a rotated canvas, though it doesn't look as bad in this other bug report.
Still it may be the same issue or related.
Comment 10 Jehan 2017-12-07 15:01:39 UTC
*** Bug 701415 has been marked as a duplicate of this bug. ***
Comment 11 Jehan 2017-12-09 02:47:28 UTC
Massimo, do you think you would have some time to review your patches and finish them? :-)
Comment 12 Ell 2017-12-09 10:04:33 UTC
You snooze, you lose, dude ;)

Pushed a fix to master, based on Massimo's screen-space chunking patch:

commit 8029508fbef8b2b5b3abd3be8a3fbb7d46654f86
Author: Ell <ell_se@yahoo.com>
Date:   Sat Dec 9 04:25:35 2017 -0500

    Bug 759287 - Canvas Tearing While in Rotated Canvas View
    
    Based on a patch by Massimo.
    
    Move the entire image-space/screen-space transformation logic from
    gimp_display_shell_render() to gimp_display_shell_draw_image(), so
    that the former works entirely in image space, and do the chunking
    and clipping in screen-space, making sure that image-space chunks
    are never larger than
    GIMP_DISPLAY_RENDER_BUF_WIDTH x GIMP_DISPLAY_RENDER_BUF_HEIGHT,
    even when the window's scale factor is greater than 1.
    
    Add a GIMP_BRICK_WALL environment variable, which, when set, shows
    the screen-space chunk bounds.

 app/display/gimpdisplayshell-callbacks.c |   4 +++
 app/display/gimpdisplayshell-draw.c      | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
 app/display/gimpdisplayshell-render.c    | 212 ++++++++++++++++++++++++++----------------------------------------------------------------------------------------------
 app/display/gimpdisplayshell-render.h    |   3 +-
 4 files changed, 140 insertions(+), 224 deletions(-)
Comment 13 Jehan 2018-01-07 19:10:49 UTC
Created attachment 366464 [details]
Left: unrotated - Right: rotated

Actually that's not fixed at all, unless there is another problem as well.
This is very easy to reproduce on current master:

- draw something
- start rotating the canvas

Result: you see the tearing happen even as you are rotating the canvas. It's like your lines are alive and spikes go and move on them while you rotate. ;p

See attached image.
Comment 14 Ell 2018-01-07 19:49:22 UTC
That would be commit 36258a671a04336260b1154128f8ff2cd9b85673 :)  It's a trade-off between quality and speed (and not related to this bug).
Comment 15 Jehan 2018-01-07 19:56:59 UTC
Hmmm… Can't there be a better compromise? I find the quality quite horrible.

But I am not drawing myself and Aryeom doesn't really use canvas rotation either, so maybe painters who do are ok with it (though I doubt it).
Comment 16 Elle Stone 2018-01-09 16:59:49 UTC
Created attachment 366565 [details]
screenshot showing zig-zag edges

(In reply to Jehan from comment #15)
> Hmmm… Can't there be a better compromise? I find the quality quite horrible.
>
> But I am not drawing myself and Aryeom doesn't really use canvas rotation
> either, so maybe painters who do are ok with it (though I doubt it).

I do draw/paint (just a beginner), and I do use canvas rotation. I agree, the quality is not good (understatement).

The attached screenshot shows black squiggly lines on a white background, single layer, no alpha channel, 100% opacity, 15-degree clockwise rotation, as displayed in default GIMP and also in my patched "CCE" version of GIMP.

The artifacts from rotating the view ("View/Flip and Rotate") are obvious in default GIMP, but not in my patched "CCE", which is up-to-date with babl updated through July 2017, and GEGL/GIMP through November 8, 2017. So I'm guessing that whatever is causing the zig-zags might have been added some time after November 8, 2016, or else after July 2017 if there's any slim chance it could be babl-related.
Comment 17 Jehan 2018-01-10 00:37:43 UTC
Elle: could you run:

> git revert 36258a671a04336260b1154128f8ff2cd9b85673 

And see if that improves things on your side? Also does that make drawing much more slower when canvas is rotated?
Comment 18 Elle Stone 2018-01-10 01:25:52 UTC
(In reply to Jehan from comment #17)
> Elle: could you run:
> 
> > git revert 36258a671a04336260b1154128f8ff2cd9b85673 
> 
> And see if that improves things on your side? Also does that make drawing
> much more slower when canvas is rotated?

Hi Jehan, I reverted the commit and recompiled, and that fixed the zig-zags. 

As far as "much more slower when canvas is rotated, no, the speed of painting seems about the same with or without canvas rotation, at least for the brush+settings that I tried.
Comment 19 Jehan 2018-01-10 03:00:06 UTC
Ok so I just took on myself to revert this commit. It was just too bad and really rotation of canvas was made useless.

Ell: was this commit done for a specific bug in particular? I think we will have to find something else. What is the default filter used on cairo? Reading the enum list, it looks like CAIRO_FILTER_GOOD may be the next one to test, but maybe that is already the default.
Or some other ways have to be found, which are less radical compromises.

In the meantime, I re-close this bug report because any canvas tearing is now gone at least.

commit 21cb905dad8e8ccb95a4a420293102a478b7638e (HEAD -> master, origin/master, origin/HEAD)
Author: Jehan <jehan@girinstud.io>
Date:   Wed Jan 10 03:38:25 2018 +0100

    Revert "app: use FAST filter when painting xfer surface"
    
    This reverts commit 36258a671a04336260b1154128f8ff2cd9b85673.
    This commit was making the rotated canvas rendering quite horrible to
    the point that I think it would make the canvas rotation feature barely
    usable. See bug 759287, comments 13 to 18.
    I think we will need to find other ways to accelerate rendering.
    Compromise on quality is possible, but I think that in this case, this
    was more than just a compromise. It was more like completely abandonning
    quality. We could even see the lines "spiking" while you were rotating!
    Like your drawing was alive!

 app/display/gimpdisplayshell-render.c | 1 -
 1 file changed, 1 deletion(-)