Skip to content
This repository
Browse code

[EGL] Fix the non-trivial dirty rectangle modes

EGL is typically double or triple buffered, and the previous buffer contents are not preserved.
This means the non-trivial dirty rectangle modes display a flickery mess.

EGL does provide a means for requesting the EGL buffer is preserved across calls.
It seems appropriate to request that when using dirty rectangle modes.

This PR makes algorithmdirtyregions 1 and 2 work on the Raspberry Pi.
It needs testing on other EGL platforms.
  • Loading branch information...
commit 5c89074b7bdce305c2ff4a0d2d83b02c51393d3f 1 parent 6edea14
popcornmix authored July 22, 2013
7  xbmc/windowing/egl/EGLWrapper.cpp
@@ -390,5 +390,12 @@ void* CEGLWrapper::GetProcAddress(const char* function)
390 390
   
391 391
   return ext;
392 392
 }
  393
+
  394
+bool CEGLWrapper::SurfaceAttrib(EGLDisplay display, EGLSurface surface, EGLint attribute, EGLint value)
  395
+{
  396
+  if ((display == EGL_NO_DISPLAY) || (surface == EGL_NO_SURFACE))
  397
+    return false;
  398
+  return eglSurfaceAttrib(display, surface, attribute, value);
  399
+}
393 400
 #endif
394 401
 
1  xbmc/windowing/egl/EGLWrapper.h
@@ -62,6 +62,7 @@ class CEGLWrapper
62 62
   bool SetVSync(EGLDisplay display, bool enable);
63 63
   bool IsExtSupported(const char* extension);
64 64
   bool GetConfigAttrib(EGLDisplay display, EGLConfig config, EGLint attribute, EGLint *value);
  65
+  bool SurfaceAttrib(EGLDisplay display, EGLSurface surface, EGLint  attribute, EGLint  value);
65 66
 
66 67
   static void* GetProcAddress(const char* function);
67 68
   
18  xbmc/windowing/egl/WinSystemEGL.cpp
@@ -25,6 +25,8 @@
25 25
 #include "filesystem/SpecialProtocol.h"
26 26
 #include "guilib/GraphicContext.h"
27 27
 #include "settings/DisplaySettings.h"
  28
+#include "guilib/IDirtyRegionSolver.h"
  29
+#include "settings/AdvancedSettings.h"
28 30
 #include "settings/Settings.h"
29 31
 #include "settings/DisplaySettings.h"
30 32
 #include "utils/log.h"
@@ -95,6 +97,12 @@ bool CWinSystemEGL::InitWindowSystem()
95 97
     return false;
96 98
   }
97 99
 
  100
+  EGLint surface_type = EGL_WINDOW_BIT;
  101
+  // for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates
  102
+  if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION ||
  103
+      g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION)
  104
+    surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
  105
+
98 106
   EGLint configAttrs [] = {
99 107
         EGL_RED_SIZE,        8,
100 108
         EGL_GREEN_SIZE,      8,
@@ -104,7 +112,7 @@ bool CWinSystemEGL::InitWindowSystem()
104 112
         EGL_STENCIL_SIZE,    0,
105 113
         EGL_SAMPLE_BUFFERS,  0,
106 114
         EGL_SAMPLES,         0,
107  
-        EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
  115
+        EGL_SURFACE_TYPE,    surface_type,
108 116
         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
109 117
         EGL_NONE
110 118
   };
@@ -192,6 +200,14 @@ bool CWinSystemEGL::CreateWindow(RESOLUTION_INFO &res)
192 200
     return false;
193 201
   }
194 202
 
  203
+  // for the non-trivial dirty region modes, we need the EGL buffer to be preserved across updates
  204
+  if (g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_COST_REDUCTION ||
  205
+      g_advancedSettings.m_guiAlgorithmDirtyRegions == DIRTYREGION_SOLVER_UNION)
  206
+  {
  207
+    if (!m_egl->SurfaceAttrib(m_display, m_surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED))
  208
+      CLog::Log(LOGDEBUG, "%s: Could not set EGL_SWAP_BEHAVIOR",__FUNCTION__);
  209
+  }
  210
+
195 211
   m_bWindowCreated = true;
196 212
 
197 213
   return true;

0 notes on commit 5c89074

Please sign in to comment.
Something went wrong with that request. Please try again.