Hi guys, I'd like your input on this very strange one.
I've come up with a fix for the blackOut issue on eglPostSubBuffer, but there's a glitch (read the FIXME: comment).

thanks.

P.S.  by the way, I am aware of what CompositeScreen::handlePaintTimeout (...) is doing when one issues a partial damage the size of the screen. it simply damages the whole screen by calling "damageScreen ()"... I really thought this could explain the weird behavior I explain in the FIXME: comment, but I have made several attempts to work this around, to bypass this, the most obvious one being :

if (!refreshSubBuffer)
	if (priv->damageMask & COMPOSITE_SCREEN_DAMAGE_REGION_MASK)
		{
		    if (priv->tmpRegion == screen->region ())
			damageScreen ();
		}
... but every time, the black screen reappeared ! 

please find the patch below :
++++++++++++++++++++++++++++++++

From d50d61a45dfaac1bfef1073139bdb033486ab787 Mon Sep 17 00:00:00 2001
From: Frederic Plourde <[email protected]>
Date: Thu, 17 Nov 2011 21:59:23 -0500
Subject: [PATCH] Fix the black screen issue when using eglPostSubBufferNV.

We had previously refactored painting the screen on GLES for
damage regions (see commit afbb0cd81bef44ad3239699a4856d7cd3ffcdfde).
What was done, is that instead of rendering damaged regions over
a preserved backBuffer, we now only render and blit the damaged
regions using the eglPostSubBufferNV extension.

However, when plugins trigger fullscreen repaints (using
eglSwapBuffers), this has the embarassing side-effect of completely
washing away backbuffer's content, thus, leading to the rendering
of a black frame immediately after getting back to mode
COMPOSITE_SCREEN_DAMAGE_REGION_MASK.

This patch fixes this issue by presenting (with eglPostSubBufferNV)
a fullscreen region to the frontbuffer in the specific cases where
(mask == COMPOSITE_SCREEN_DAMAGE_REGION_MASK)  &&
(lastMask == COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
---
 plugins/opengl/src/privates.h |    2 ++
 plugins/opengl/src/screen.cpp |   25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/plugins/opengl/src/privates.h b/plugins/opengl/src/privates.h
index 0faa5d5..423a10c 100644
--- a/plugins/opengl/src/privates.h
+++ b/plugins/opengl/src/privates.h
@@ -128,6 +128,8 @@ class PrivateGLScreen :
     bool pendingCommands;
 
     XRectangle lastViewport;
+    bool refreshSubBuffer;
+    unsigned int lastMask;
 
     std::vector<GLTexture::BindPixmapProc> bindPixmap;
     bool hasCompositing;
diff --git a/plugins/opengl/src/screen.cpp b/plugins/opengl/src/screen.cpp
index 4d2d3bc..fc67e84 100644
--- a/plugins/opengl/src/screen.cpp
+++ b/plugins/opengl/src/screen.cpp
@@ -877,6 +877,7 @@ PrivateGLScreen::PrivateGLScreen (GLScreen   *gs) :
     scratchFbo (NULL),
     outputRegion (),
     pendingCommands (false),
+    lastMask (0),
     bindPixmap (),
     hasCompositing (false),
     programCache (new GLProgramCache (30))
@@ -1391,6 +1392,23 @@ PrivateGLScreen::paintOutputs (CompOutput::ptrList &outputs,
     GLFramebufferObject *oldFbo = NULL;
     bool useFbo = false;
 
+#ifdef USE_GLES
+    refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
+              !(     mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
+               (     mask & COMPOSITE_SCREEN_DAMAGE_REGION_MASK));
+
+      if (refreshSubBuffer)
+      {
+    // FIXME: We shouldn't have to substract a 1X1 pixel region here !!
+    // This is an ugly workaround for what appears to be a bug in the SGX
+    // X11 driver (e.g. on Pandaboard OMAP4 platform).
+    // Posting a fullscreen damage region to the SGX seems to reset the
+    // framebuffer, causing the screen to blackout.
+      cScreen->damageRegion (CompRegion (screen->fullscreenOutput ()) -
+                   CompRegion (CompRect(0, 0, 1, 1)));
+      }
+#endif
+
     if (clearBuffers)
     {
     if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
@@ -1441,6 +1459,11 @@ PrivateGLScreen::paintOutputs (CompOutput::ptrList &outputs,
     {
         GLMatrix identity;
 
+#ifdef USE_GLES
+        if (refreshSubBuffer)
+        tmpRegion = CompRegion (*output);
+#endif
+
         outputRegion = tmpRegion & CompRegion (*output);
 
         if (!gScreen->glPaintOutput (defaultScreenPaintAttrib,
@@ -1578,6 +1601,8 @@ PrivateGLScreen::paintOutputs (CompOutput::ptrList &outputs,
     }
     #endif
     }
+
+    lastMask = mask;
 }
 
 bool
--
1.7.5.4


--
  Frédéric Plourde
Software engineering consultant
 T :: (450) 415-0855
@:: [email protected]

_______________________________________________
dev mailing list
[email protected]
http://lists.compiz.org/mailman/listinfo/dev

Reply via email to