View Issue Details

IDProjectCategoryView StatusLast Update
0033864LazarusLCLpublic2018-09-27 15:05
ReporterChris RordenAssigned ToJuha Manninen 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformLinuxOSUbuntuOS Version16.04
Product Version1.9 (SVN)Product Build58283 
Target Version1.10Fixed in Version 
Summary0033864: TOpenGLControl regression: flicker using Linux GTK with NVidia graphics cards
DescriptionRecent changes to the TOpenGLControl provided in /components/lazarus/opengl cause flicker for every Lazarus OpenGL project I tried on my Linux Ubuntu 16.04 computer. The machine has a GTX 1080 Ti card and runs other OpenGL programs (including Lazarus programs compiled previously) without problem. The flicker is seen with every update, and setting features like GLBox.doublebuffered has no effect. This regression can be fixed by replacing the contents of /components/lazarus/opengl with that from prior releases of Lazarus (I used the 1.8) and rebuilding Lazarus and the projects. It returns if you put in the latest files. This is seen in every OpenGL project. I tested on two machines with identical results.

The flicker is the entire context, each time the scene changes.
Steps To ReproduceThe easiest way to demonstrate this is the OpenGL sample project included with Lazarus
  /components/lazarus/opengl/testopenglcontext1.lpr
This project autoupdates, so the flicker is severe and complete.
(the imgui.lpr project shows this effect the least, maybe since it rarely updates).

Compile your favorite OpenGL project. I replicated it with these projects, some of which are classic OpenGL 2.1 and others use OpenGL 3.3 core, the results are the same.
 
https://github.com/neurolabusc/OpenGLCoreTutorials
 https://github.com/neurolabusc/OpenGLCoreTutorials
 https://github.com/neurolabusc/vx
 https://github.com/neurolabusc/surf-ice
 https://github.com/neurolabusc/MRIcroGL
TagsNo tags attached.
Fixed in Revisionr59111
LazTarget1.10
WidgetsetGTK 2
Attached Files
  • issue-33864.diff (2,522 bytes)
    Index: components/opengl/openglcontext.pas
    ===================================================================
    --- components/opengl/openglcontext.pas	(revision 59106)
    +++ components/opengl/openglcontext.pas	(working copy)
    @@ -275,6 +275,7 @@
         class function CreateHandle(const AWinControl: TWinControl;
                                     const AParams: TCreateParams): HWND; override;
         class procedure DestroyHandle(const AWinControl: TWinControl); override;
    +    class function GetDoubleBuffered(const AWinControl: TWinControl): Boolean; override;
       end;
     
     
    @@ -723,6 +724,11 @@
       TWSWinControlClass(ClassParent).DestroyHandle(AWinControl);
     end;
     
    +class function TWSOpenGLControl.GetDoubleBuffered(const AWinControl: TWinControl): Boolean;
    +begin
    +  Result := False;
    +end;
    +
     initialization
       RegisterWSComponent(TCustomOpenGLControl,TWSOpenGLControl);
     
    Index: lcl/interfaces/gtk2/gtk2int.pas
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2int.pas	(revision 59106)
    +++ lcl/interfaces/gtk2/gtk2int.pas	(working copy)
    @@ -45,7 +45,7 @@
       LMessages, LCLProc, LCLIntf, LCLType, GraphType, GraphMath,
       Graphics, Menus, Themes, Buttons, StdCtrls, CheckLst, ComCtrls, Spin, ExtCtrls,
       LCLPlatformDef, InterfaceBase,
    -  WSLCLClasses,
    +  WSLCLClasses, WSControls,
       Gtk2WinApiWindow, Gtk2Globals, Gtk2Proc, Gtk2Def, Gtk2FontCache, Gtk2Extra,
       Gtk2MsgQueue;
     
    Index: lcl/interfaces/gtk2/gtk2winapi.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2winapi.inc	(revision 59106)
    +++ lcl/interfaces/gtk2/gtk2winapi.inc	(working copy)
    @@ -138,7 +138,7 @@
       else Control := nil;
     
       if (Control <> nil)
    -  and Control.DoubleBuffered
    +  and TWSWinControlClass(Control.WidgetSetClass).GetDoubleBuffered(Control)
       and not GTK_WIDGET_DOUBLE_BUFFERED({%H-}PGTKWidget(Handle))
       then begin
         //DebugLn(['TGtk2WidgetSet.BeginPaint ',DbgSName(Control)]);
    @@ -2837,8 +2837,10 @@
       then Control := TWinControl(GetLCLObject({%H-}Pointer(Handle)))
       else Control := nil;
     
    -  If (Control <> nil) and (not GTK_WIDGET_DOUBLE_BUFFERED(({%H-}PGTKWidget(Handle)))) and (Control.DoubleBuffered) then
    -  begin
    +  if (Control <> nil)
    +  and TWSWinControlClass(Control.WidgetSetClass).GetDoubleBuffered(Control)
    +  and not GTK_WIDGET_DOUBLE_BUFFERED({%H-}PGTKWidget(Handle))
    +  then begin
         gdk_window_thaw_updates(TGtkDeviceContext(PS.HDC).Drawable);
         gdk_window_end_paint (TGtkDeviceContext(PS.HDC).Drawable);
       end;
    
    issue-33864.diff (2,522 bytes)

Relationships

has duplicate 0034094 resolvedJuha Manninen OpenGLControl flickers 

Activities

Anton Kavalenka

2018-06-16 08:08

reporter   ~0108925

can confirm both on Intel built-in card and on nvidia bumblebee

Previous implementation was simulated double buffering.
OpenGL do it by design, so no need in Widgetset caching.

Juha Manninen

2018-09-20 23:46

developer   ~0110906

I set target for 1.10 (which should really be 2.0) because this is a regression.
Ondrej made the double buffering changes but he is having a pause now and will not fix this.
Somebody please provide a patch. I don't know the OpenGL code well but I can apply patches.

accorp

2018-09-21 06:01

reporter  

issue-33864.diff (2,522 bytes)
Index: components/opengl/openglcontext.pas
===================================================================
--- components/opengl/openglcontext.pas	(revision 59106)
+++ components/opengl/openglcontext.pas	(working copy)
@@ -275,6 +275,7 @@
     class function CreateHandle(const AWinControl: TWinControl;
                                 const AParams: TCreateParams): HWND; override;
     class procedure DestroyHandle(const AWinControl: TWinControl); override;
+    class function GetDoubleBuffered(const AWinControl: TWinControl): Boolean; override;
   end;
 
 
@@ -723,6 +724,11 @@
   TWSWinControlClass(ClassParent).DestroyHandle(AWinControl);
 end;
 
+class function TWSOpenGLControl.GetDoubleBuffered(const AWinControl: TWinControl): Boolean;
+begin
+  Result := False;
+end;
+
 initialization
   RegisterWSComponent(TCustomOpenGLControl,TWSOpenGLControl);
 
Index: lcl/interfaces/gtk2/gtk2int.pas
===================================================================
--- lcl/interfaces/gtk2/gtk2int.pas	(revision 59106)
+++ lcl/interfaces/gtk2/gtk2int.pas	(working copy)
@@ -45,7 +45,7 @@
   LMessages, LCLProc, LCLIntf, LCLType, GraphType, GraphMath,
   Graphics, Menus, Themes, Buttons, StdCtrls, CheckLst, ComCtrls, Spin, ExtCtrls,
   LCLPlatformDef, InterfaceBase,
-  WSLCLClasses,
+  WSLCLClasses, WSControls,
   Gtk2WinApiWindow, Gtk2Globals, Gtk2Proc, Gtk2Def, Gtk2FontCache, Gtk2Extra,
   Gtk2MsgQueue;
 
Index: lcl/interfaces/gtk2/gtk2winapi.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2winapi.inc	(revision 59106)
+++ lcl/interfaces/gtk2/gtk2winapi.inc	(working copy)
@@ -138,7 +138,7 @@
   else Control := nil;
 
   if (Control <> nil)
-  and Control.DoubleBuffered
+  and TWSWinControlClass(Control.WidgetSetClass).GetDoubleBuffered(Control)
   and not GTK_WIDGET_DOUBLE_BUFFERED({%H-}PGTKWidget(Handle))
   then begin
     //DebugLn(['TGtk2WidgetSet.BeginPaint ',DbgSName(Control)]);
@@ -2837,8 +2837,10 @@
   then Control := TWinControl(GetLCLObject({%H-}Pointer(Handle)))
   else Control := nil;
 
-  If (Control <> nil) and (not GTK_WIDGET_DOUBLE_BUFFERED(({%H-}PGTKWidget(Handle)))) and (Control.DoubleBuffered) then
-  begin
+  if (Control <> nil)
+  and TWSWinControlClass(Control.WidgetSetClass).GetDoubleBuffered(Control)
+  and not GTK_WIDGET_DOUBLE_BUFFERED({%H-}PGTKWidget(Handle))
+  then begin
     gdk_window_thaw_updates(TGtkDeviceContext(PS.HDC).Drawable);
     gdk_window_end_paint (TGtkDeviceContext(PS.HDC).Drawable);
   end;
issue-33864.diff (2,522 bytes)

accorp

2018-09-21 06:04

reporter   ~0110915

A patch uploaded.

Anton Kavalenka

2018-09-21 08:51

reporter   ~0110917

radical solution.

IMO GL control in its nature is csOpaque. So this control style has to be handled in such a way at widgetset level.

Also this fixes problem with spontaneous background paint (flicker) in other [csOpaque] controls.

Juha Manninen

2018-09-21 09:49

developer   ~0110918

> radical solution.

Radical? Is it good or bad? I am planning to apply the patch.

Juha Manninen

2018-09-21 11:15

developer   ~0110922

It works here and does not break anything. Applied. Please test everybody.
Thanks accorp for the patch.

Anton Kavalenka

2018-09-21 11:22

reporter   ~0110923

Radical because checking if the control of corresponding class (with high CPU for VMT lookup) instead of checking specific attribute of instance.

Good patch - it will work at the cost of little slowdown for all widgets.

m_burkhard@gmx.ch

2018-09-21 20:46

reporter   ~0110940

Thanks, run with the latest trunk again.

Linux Mint 19.0 64Bit

Issue History

Date Modified Username Field Change
2018-06-15 22:40 Chris Rorden New Issue
2018-06-16 08:08 Anton Kavalenka Note Added: 0108925
2018-06-16 09:00 Ondrej Pokorny Assigned To => Ondrej Pokorny
2018-06-16 09:00 Ondrej Pokorny Status new => assigned
2018-08-06 18:41 Mattias Gaertner Relationship added related to 0034094
2018-09-16 17:41 Juha Manninen LazTarget => -
2018-09-16 17:41 Juha Manninen Assigned To Ondrej Pokorny =>
2018-09-16 17:41 Juha Manninen Status assigned => new
2018-09-20 23:46 Juha Manninen LazTarget - => 1.10
2018-09-20 23:46 Juha Manninen Note Added: 0110906
2018-09-20 23:46 Juha Manninen Target Version => 1.10
2018-09-21 06:01 accorp File Added: issue-33864.diff
2018-09-21 06:04 accorp Note Added: 0110915
2018-09-21 08:51 Anton Kavalenka Note Added: 0110917
2018-09-21 09:49 Juha Manninen Note Added: 0110918
2018-09-21 11:10 Juha Manninen Assigned To => Juha Manninen
2018-09-21 11:10 Juha Manninen Status new => assigned
2018-09-21 11:12 Juha Manninen Relationship replaced has duplicate 0034094
2018-09-21 11:15 Juha Manninen Fixed in Revision => r59111
2018-09-21 11:15 Juha Manninen Note Added: 0110922
2018-09-21 11:15 Juha Manninen Status assigned => resolved
2018-09-21 11:15 Juha Manninen Resolution open => fixed
2018-09-21 11:22 Anton Kavalenka Note Added: 0110923
2018-09-21 20:46 m_burkhard@gmx.ch Note Added: 0110940
2018-09-27 15:05 Chris Rorden Status resolved => closed