summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-11 13:43:56 -0500
committerMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-11-12 04:07:21 +0100
commit74c3dbe87e7256f8f8b3eac3a34415780035f465 (patch)
tree1271e6355a0a47850435be794581c1bfc9a4c17f
parentc7a5ce27e6d27af4d868dedcde1f650fa129e6f8 (diff)
vcl: Read back OpenGL FBO to create offscreen X11 pixmap
Change-Id: I330e7d62bf31b4a90b5866d9531f073f7c69c92a
-rw-r--r--vcl/inc/openglgdiimpl.hxx4
-rw-r--r--vcl/opengl/gdiimpl.cxx19
-rw-r--r--vcl/opengl/x11/gdiimpl.cxx33
3 files changed, 47 insertions, 9 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index c9e8b6888b71..535bc722a364 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -86,8 +86,8 @@ protected:
void DrawRect( long nX, long nY, long nWidth, long nHeight );
void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
- void DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry );
- void DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& rPosAry );
+ void DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry, bool bInverted = false );
+ void DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& rPosAry, bool bInverted = false );
void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const Size& rSize, const SalTwoRect& rPosAry );
void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& rPosAry );
void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 72387e22cbc1..65c4f3089017 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -503,14 +503,23 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
-void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry )
+void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry, bool bInverted )
{
GLfloat aTexCoord[8];
aTexCoord[0] = aTexCoord[2] = rPosAry.mnSrcX / (double) rSize.Width();
aTexCoord[4] = aTexCoord[6] = (rPosAry.mnSrcX + rPosAry.mnSrcWidth) / (double) rSize.Width();
- aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height();
- aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height();
+
+ if( !bInverted )
+ {
+ aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height();
+ aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height();
+ }
+ else
+ {
+ aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height();
+ aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height();
+ }
glEnableVertexAttribArray( GL_ATTRIB_TEX );
glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
@@ -520,7 +529,7 @@ void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect
glDisableVertexAttribArray( GL_ATTRIB_TEX );
}
-void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& pPosAry )
+void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& pPosAry, bool bInverted )
{
if( mnTextureProgram == 0 )
{
@@ -534,7 +543,7 @@ void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, con
CHECK_GL_ERROR();
glBindTexture( GL_TEXTURE_2D, nTexture );
- DrawTextureRect( rSize, pPosAry );
+ DrawTextureRect( rSize, pPosAry, bInverted );
CHECK_GL_ERROR();
glBindTexture( GL_TEXTURE_2D, 0 );
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 6e803bd21acd..13b70495341a 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -83,9 +83,38 @@ X11Pixmap* X11OpenGLSalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect
{
Display* pDisplay = mrParent.GetXDisplay();
SalX11Screen nScreen = mrParent.GetScreenNumber();
+ XVisualInfo aVisualInfo;
+ X11Pixmap* pPixmap;
+ XImage* pImage;
+ sal_uInt8* pData;
SAL_INFO( "vcl.opengl", "GetPixmapFromScreen" );
- return new X11Pixmap( pDisplay, nScreen, rRect.GetWidth(), rRect.GetHeight(), 24 );
+ // TODO: lfrb: Use context depth
+ pPixmap = new X11Pixmap( pDisplay, nScreen, rRect.GetWidth(), rRect.GetHeight(), 24 );
+
+ if( !OpenGLHelper::GetVisualInfo( pDisplay, nScreen.getXScreen(), aVisualInfo ) )
+ return pPixmap;
+
+ // make sure everything is synced up before reading back
+ maContext.makeCurrent();
+ glXWaitX();
+
+ // TODO: lfrb: What if offscreen?
+ pData = new sal_uInt8[rRect.GetWidth() * rRect.GetHeight() * 4];
+ glPixelStorei( GL_PACK_ALIGNMENT, 1 );
+ glReadPixels( rRect.Left(), GetHeight() - rRect.Top(), rRect.GetWidth(), rRect.GetHeight(),
+ GL_RGBA, GL_UNSIGNED_BYTE, pData );
+
+ pImage = XCreateImage( pDisplay, aVisualInfo.visual, 24, ZPixmap, 0, (char*) pData,
+ rRect.GetWidth(), rRect.GetHeight(), 8, 0 );
+ XInitImage( pImage );
+ GC aGC = XCreateGC( pDisplay, pPixmap->GetPixmap(), 0, NULL );
+ XPutImage( pDisplay, pPixmap->GetDrawable(), aGC, pImage,
+ 0, 0, 0, 0, rRect.GetWidth(), rRect.GetHeight() );
+ XFreeGC( pDisplay, aGC );
+ XDestroyImage( pImage );
+
+ return pPixmap;
}
bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
@@ -128,7 +157,7 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX,
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- DrawTexture( nTexture, pPixmap->GetSize(), aPosAry );
+ DrawTexture( nTexture, pPixmap->GetSize(), aPosAry, !bInverted );
glXReleaseTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT );
glDeleteTextures( 1, &nTexture );