Bug 405418 - GLCanvas flickers during repaints although its SWT.NO_BACKGROUND style bit is set
Summary: GLCanvas flickers during repaints although its SWT.NO_BACKGROUND style bit is...
Status: RESOLVED WORKSFORME
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.8.1   Edit
Hardware: PC Linux-GTK
: P3 major with 5 votes (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: needinfo, triaged
Depends on:
Blocks:
 
Reported: 2013-04-10 19:30 EDT by Chester Kollschen CLA
Modified: 2018-06-13 10:35 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chester Kollschen CLA 2013-04-10 19:30:52 EDT
The described problem occurs on a 32 bit machine running Debian GNU/Linux Wheezy.

I use the SWT as a stand-alone library in a JavaSE project that displays OpenGL graphics in a GLCanvas using LWJGL.

The GLCanvas is constructed once and then drawn to repeatedly.

The GLCanvas is constructed with the SWT.NO_BACKGROUND style bit so that SWT won't clear/fill the widget's background in the drawing process.

In the GLCanvas' PaintListener, OpenGL calls are used to draw the scene, followed by a call to GLCanvas.swapBuffers to make it visible.

Up to SWT 3.8.0, everything works fine. Starting with SWT 3.8.1, the scene flickers as if the SWT.NO_BACKGROUND style bit was not set.

I have diff'ed the source code folders of SWT 3.8.0 and SWT 3.8.1 and stumbled upon one change that may have something to do with this.

In the file <swt-sources>/org/eclipse/swt/widgets/Composite.java, method checkStyle(int):

    static int checkStyle (int style) {
        style &= ~SWT.TRANSPARENT;
        return style;
    }

In SWT 3.8.1, this was changed to:

    static int checkStyle (int style) {
        if (OS.INIT_CAIRO) {
            style &= ~SWT.NO_BACKGROUND;
	}
        style &= ~SWT.TRANSPARENT;
        return style;
    }

Both OS.INIT_CAIRO and OS.USE_CAIRO are initialize to true on my system. Since this method is called in the constructor of Canvas (and thus GLCanvas), this might be the cause of the troubles as well as a good starting point for investigation.

As a workaround, the system property "org.eclipse.swt.internal.gtk.useCairo" can be set to "false", which initializes OS.INIT_CAIRO to false, leaving the SWT.NO_BACKGROUND style bit intact and thus prevents flickering.
Comment 1 Chester Kollschen CLA 2013-05-01 09:18:28 EDT
The commited patch that I am suspecting of making GLCanvas flicker in SWT-GTK beginning with 3.8.1/4.2.1 (library version 3.834) is this one:

http://git.eclipse.org/c/platform/eclipse.platform.swt.git/patch/bundles/org.eclipse.swt/Eclipse%20SWT/gtk/org/eclipse/swt/widgets/Composite.java?id=091e36b96050b89d4e91c682d15c94c651865f88

The subject suggests that this patch was commited to fix display issues with WindowBuilder. The patch masks out the SWT.NO_BACKGROUND style flag from any Composite widget in the hierarchy if Cairo is present.

However, since this patch affects every widget derived from Composite, it also affects GLCanvas.

Rendering to a GLCanvas is typically done using OpenGL calls followed by a call to GLCanvas.swapBuffers(void). In order to use GLCanvas in a flicker-free way, the SWT.NO_BACKGROUND style flag is crucial to prevent SWT from interfering with the widget's client area.

Maybe the mentioned patch can be refined so that the SWT.NO_BACKGROUND style flag will NOT be masked out if the widget in construction IS instanceof GLCanvas?
Comment 2 Eric Williams CLA 2018-05-11 14:02:35 EDT
Is there a snippet for this issue? Is it still reproducible on 4.8 M7?
Comment 3 Eric Williams CLA 2018-06-13 10:35:42 EDT
Closing this ticket now, please re-open the bug if you see the issue on 4.8 with GTK3.22.