From ef087a7d5374088d10190cb9bc13f6348fa0c2e2 Mon Sep 17 00:00:00 2001
From: Frederic Plourde <[email protected]>
Date: Fri, 21 Oct 2011 12:23:20 -0400
Subject: [PATCH gles] Fix partial screen damage rendering to allow plugins to shade final
 composited screen.

Partial screen damage rendering, driven in GLPrivateGLScreen::
paintOutputs(), renders every GLwindows to an offscreen FBO
(scratchFbo) and then renders damaged parts of this FBO to the back
buffer. However, plugins needs a way to get access to scratchFbo
if they want to be able to add screen-based FX on it while shading.

This patch adds another GLScreen hookable called glPaintCompositedOutput.
The 'bool fullRepaint' argument tells the function to whether or not
perform a fullRepaint (useful in some situations, e.g. when
COMPOSITE_SCREEN_DAMAGE_ALL_MASK is defined) or not (partial repaint).

Plugins can benefit from hooking to glPaintCompositedOutput because
they can then access scratchFbo (which should be renamed, really)
before going to partial repaint. A plugin might then just decide to
use scratchFbo's color_attachment in an FX shader and render that
to the backbuffer, completely bypassing partial damage repaint.
---
 plugins/opengl/include/opengl/opengl.h |   17 ++++-
plugins/opengl/src/paint.cpp | 137 ++++++++++++++++++++++++++++++++
 plugins/opengl/src/screen.cpp          |  102 +++++-------------------
 3 files changed, 172 insertions(+), 84 deletions(-)

diff --git a/plugins/opengl/include/opengl/opengl.h b/plugins/opengl/include/opengl/opengl.h
index 4fc88c1..84505fb 100644
--- a/plugins/opengl/include/opengl/opengl.h
+++ b/plugins/opengl/include/opengl/opengl.h
@@ -44,6 +44,7 @@

 #include <opengl/matrix.h>
 #include <opengl/texture.h>
+#include <opengl/framebufferobject.h>
 #include <opengl/vertexbuffer.h>
 #include <opengl/program.h>
 #include <opengl/programcache.h>
@@ -377,6 +378,7 @@ struct GLShaderData
 extern GLScreenPaintAttrib defaultScreenPaintAttrib;

 class GLScreen;
+class GLFramebufferObject;

 class GLScreenInterface :
     public WrapableInterface<GLScreen, GLScreenInterface>
@@ -445,11 +447,22 @@ class GLScreenInterface :

     virtual GLMatrix *projectionMatrix ();

+    /**
+     * Hookable function used by plugins to shade the final composited
+     * Output.
+     *
+     * @param tmpRegion Describes the final composited output region
+     * @param scratchFbo Describes the final composited FBO that is
+     * to be rendered.
+     */
+    virtual void glPaintCompositedOutput (const CompRegion &tmpRegion,
+                          GLFramebufferObject *scratchFbo,
+                          bool fullRepaint);
 };


 class GLScreen :
-    public WrapableHandler<GLScreenInterface, 6>,
+    public WrapableHandler<GLScreenInterface, 7>,
     public PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>,
     public CompOption::Class
 {
@@ -546,6 +559,8 @@ class GLScreen :
     WRAPABLE_HND (4, GLScreenInterface, void, glDisableOutputClipping);

     WRAPABLE_HND (5, GLScreenInterface, GLMatrix *, projectionMatrix);
+    WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput,
+              const CompRegion &, GLFramebufferObject *, bool);

     friend class GLTexture;

diff --git a/plugins/opengl/src/paint.cpp b/plugins/opengl/src/paint.cpp
index 26361a7..fdd9a73 100644
--- a/plugins/opengl/src/paint.cpp
+++ b/plugins/opengl/src/paint.cpp
@@ -544,6 +544,143 @@ GLScreen::glPaintOutput (const GLScreenPaintAttrib &sAttrib,
     }
 }

+void
+GLScreen::glPaintCompositedOutput (const CompRegion &tmpRegion,
+                   GLFramebufferObject *scratchFbo,
+                   bool fullRepaint)
+{
+    WRAPABLE_HND_FUNC (6, glPaintCompositedOutput,
+               tmpRegion, scratchFbo, fullRepaint)
+
+    GLMatrix sTransform;
+    GLfloat vertexData[18];
+    GLfloat textureData[12];
+    const GLTexture::Matrix & texmatrix = scratchFbo->tex ()->matrix ();
+    GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
+
+    BoxPtr pBox = const_cast <Region> (tmpRegion.handle ())->rects;
+    int nBox    = const_cast <Region> (tmpRegion.handle ())->numRects;
+
+    streamingBuffer->begin (GL_TRIANGLES);
+
+    if (fullRepaint)
+    {
+    GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, 0.0f);
+    GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, screen->width ());
+    GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, 0.0f);
+    GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, screen->height ());
+
+    vertexData[0]  = 0.0f;
+    vertexData[1]  = 0.0f;
+    vertexData[2]  = 0.0f;
+
+    vertexData[3]  = 0.0f;
+    vertexData[4]  = screen->height ();
+    vertexData[5]  = 0.0f;
+
+    vertexData[6]  = screen->width ();
+    vertexData[7]  = 0.0f;
+    vertexData[8]  = 0.0f;
+
+    vertexData[9]  = 0.0f;
+    vertexData[10] = screen->height ();
+    vertexData[11] = 0.0f;
+
+    vertexData[12] = screen->width ();
+    vertexData[13] = screen->height ();
+    vertexData[14] = 0.0f;
+
+    vertexData[15] = screen->width ();
+    vertexData[16] = 0.0f;
+    vertexData[17] = 0.0f;
+
+    textureData[0]  = tx1;
+    textureData[1]  = ty1;
+
+    textureData[2]  = tx1;
+    textureData[3]  = ty2;
+
+    textureData[4]  = tx2;
+    textureData[5]  = ty1;
+
+    textureData[6]  = tx1;
+    textureData[7]  = ty2;
+
+    textureData[8]  = tx2;
+    textureData[9]  = ty2;
+
+    textureData[10] = tx2;
+    textureData[11] = ty1;
+
+    streamingBuffer->addVertices (6, vertexData);
+    streamingBuffer->addTexCoords (0, 6, textureData);
+    }
+    else
+    {
+    while (nBox--)
+    {
+        GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, pBox->x1);
+        GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, pBox->x2);
+        GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y1);
+        GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y2);
+
+        vertexData[0]  = pBox->x1;
+        vertexData[1]  = pBox->y1;
+        vertexData[2]  = 0.0f;
+
+        vertexData[3]  = pBox->x1;
+        vertexData[4]  = pBox->y2;
+        vertexData[5]  = 0.0f;
+
+        vertexData[6]  = pBox->x2;
+        vertexData[7]  = pBox->y1;
+        vertexData[8]  = 0.0f;
+
+        vertexData[9]  = pBox->x1;
+        vertexData[10] = pBox->y2;
+        vertexData[11] = 0.0f;
+
+        vertexData[12] = pBox->x2;
+        vertexData[13] = pBox->y2;
+        vertexData[14] = 0.0f;
+
+        vertexData[15] = pBox->x2;
+        vertexData[16] = pBox->y1;
+        vertexData[17] = 0.0f;
+
+        textureData[0]  = tx1;
+        textureData[1]  = ty1;
+
+        textureData[2]  = tx1;
+        textureData[3]  = ty2;
+
+        textureData[4]  = tx2;
+        textureData[5]  = ty1;
+
+        textureData[6]  = tx1;
+        textureData[7]  = ty2;
+
+        textureData[8]  = tx2;
+        textureData[9]  = ty2;
+
+        textureData[10] = tx2;
+        textureData[11] = ty1;
+
+        streamingBuffer->addVertices (6, vertexData);
+        streamingBuffer->addTexCoords (0, 6, textureData);
+
+        pBox++;
+    }
+    }
+
+    streamingBuffer->end ();
+
+    scratchFbo->tex ()-> enable (GLTexture::Fast);
+ sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
+    streamingBuffer->render (sTransform);
+    scratchFbo->tex ()-> disable ();
+}
+
 #define ADD_RECT(vertexBuffer, m, n, x1, y1, x2, y2) \
     GLfloat vertexData[18] = {                       \
     x1, y1, 0.0,                                 \
diff --git a/plugins/opengl/src/screen.cpp b/plugins/opengl/src/screen.cpp
index 3540f58..54df17b 100644
--- a/plugins/opengl/src/screen.cpp
+++ b/plugins/opengl/src/screen.cpp
@@ -339,7 +339,7 @@ GLScreen::GLScreen (CompScreen *s) :
     registerBindPixmap (EglTexture::bindPixmapToTexture);

     priv->scratchFbo = new GLFramebufferObject;
-    priv->scratchFbo->allocate (*screen);
+    priv->scratchFbo->allocate (*screen, NULL, GL_BGRA);

     #else

@@ -1239,6 +1239,12 @@ GLMatrix *
 GLScreenInterface::projectionMatrix ()
     WRAPABLE_DEF (projectionMatrix)

+void
+GLScreenInterface::glPaintCompositedOutput (const CompRegion &tmpRegion,
+                        GLFramebufferObject *scratchFbo,
+                        bool partialRepaint)
+ WRAPABLE_DEF (glPaintCompositedOutput, tmpRegion, scratchFbo, partialRepaint)
+

 GLMatrix *
 GLScreen::projectionMatrix ()
@@ -1379,18 +1385,16 @@ PrivateGLScreen::paintOutputs (CompOutput::ptrList &outputs,
                    const CompRegion &region)
 {
     XRectangle r;
+    GLint oldViewport[4];

 #ifdef USE_GLES
     GLFramebufferObject *oldFbo = NULL;
     bool useFbo = false;

-    // FIXME: does not work if screen dimensions exceed max texture size
-    if (!(mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK))
-    {
-    oldFbo = scratchFbo->bind ();
-    useFbo = scratchFbo->checkStatus () && scratchFbo->tex ();
-    if (!useFbo)
-        GLFramebufferObject::rebind (oldFbo);
+    oldFbo = scratchFbo->bind ();
+    useFbo = scratchFbo->checkStatus () && scratchFbo->tex ();
+    if (!useFbo) {
+    GLFramebufferObject::rebind (oldFbo);
     }
 #endif

@@ -1449,7 +1453,6 @@ PrivateGLScreen::paintOutputs (CompOutput::ptrList &outputs,
                     PAINT_SCREEN_FULL_MASK);

         tmpRegion += *output;
-
         }
     }
     }
@@ -1460,84 +1463,17 @@ PrivateGLScreen::paintOutputs (CompOutput::ptrList &outputs,

     #ifdef USE_GLES
     Display *xdpy = screen->dpy ();
+    GLFramebufferObject::rebind (oldFbo);

     if (useFbo)
     {
-    GLMatrix sTransform;
-    GLfloat vertexData[18];
-    GLfloat textureData[12];
-    const GLTexture::Matrix & texmatrix = scratchFbo->tex ()->matrix ();
-    GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
-
-    BoxPtr pBox = const_cast <Region> (tmpRegion.handle ())->rects;
-    int nBox    = const_cast <Region> (tmpRegion.handle ())->numRects;
-
-    streamingBuffer->begin (GL_TRIANGLES);
-
-    while (nBox--)
-    {
-        GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, pBox->x1);
-        GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, pBox->x2);
-        GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y1);
-        GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y2);
-
-        vertexData[0]  = pBox->x1;
-        vertexData[1]  = pBox->y1;
-        vertexData[2]  = 0.0f;
-
-        vertexData[3]  = pBox->x1;
-        vertexData[4]  = pBox->y2;
-        vertexData[5]  = 0.0f;
-
-        vertexData[6]  = pBox->x2;
-        vertexData[7]  = pBox->y1;
-        vertexData[8]  = 0.0f;
-
-        vertexData[9]  = pBox->x1;
-        vertexData[10] = pBox->y2;
-        vertexData[11] = 0.0f;
-
-        vertexData[12] = pBox->x2;
-        vertexData[13] = pBox->y2;
-        vertexData[14] = 0.0f;
-
-        vertexData[15] = pBox->x2;
-        vertexData[16] = pBox->y1;
-        vertexData[17] = 0.0f;
-
-        textureData[0]  = tx1;
-        textureData[1]  = ty1;
-
-        textureData[2]  = tx1;
-        textureData[3]  = ty2;
-
-        textureData[4]  = tx2;
-        textureData[5]  = ty1;
-
-        textureData[6]  = tx1;
-        textureData[7]  = ty2;
-
-        textureData[8]  = tx2;
-        textureData[9]  = ty2;
-
-        textureData[10] = tx2;
-        textureData[11] = ty1;
-
-        streamingBuffer->addVertices (6, vertexData);
-        streamingBuffer->addTexCoords (0, 6, textureData);
-
-        pBox++;
-    }
-
-    streamingBuffer->end ();
-
-    GLFramebufferObject::rebind (oldFbo);
-
-    scratchFbo->tex ()-> enable (GLTexture::Fast);
- sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
-    streamingBuffer->render (sTransform);
-    scratchFbo->tex ()-> disable ();
+    // Call this hookable to allow plugins to shade
+    // the final composited Fbo
+    // FIXME: does not work if screen dimensions exceed max texture size
+    gScreen->glPaintCompositedOutput (tmpRegion, scratchFbo,
+                      mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK);
     }
+
     eglSwapBuffers (eglGetDisplay (xdpy), surface);
     eglWaitGL ();
     XFlush (xdpy);
--
1.7.4.1

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

Reply via email to