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 ®ion)
{
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