2014-11-08 13:14:14 -05:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "vcl/salbtype.hxx"
|
|
|
|
|
|
|
|
#include "unx/pixmap.hxx"
|
|
|
|
#include "unx/saldisp.hxx"
|
|
|
|
#include "unx/salframe.h"
|
|
|
|
#include "unx/salgdi.h"
|
|
|
|
#include "unx/salvd.h"
|
|
|
|
|
2014-11-13 21:37:54 -05:00
|
|
|
#include "opengl/texture.hxx"
|
2014-11-08 13:14:14 -05:00
|
|
|
#include "opengl/x11/gdiimpl.hxx"
|
|
|
|
|
|
|
|
#include <vcl/opengl/OpenGLContext.hxx>
|
|
|
|
#include <vcl/opengl/OpenGLHelper.hxx>
|
|
|
|
|
|
|
|
X11OpenGLSalGraphicsImpl::X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent ):
|
|
|
|
OpenGLSalGraphicsImpl(),
|
|
|
|
mrParent(rParent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
X11OpenGLSalGraphicsImpl::~X11OpenGLSalGraphicsImpl()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GLfloat X11OpenGLSalGraphicsImpl::GetWidth() const
|
|
|
|
{
|
|
|
|
if( mrParent.m_pFrame )
|
|
|
|
return mrParent.m_pFrame->maGeometry.nWidth;
|
|
|
|
else if( mrParent.m_pVDev )
|
|
|
|
{
|
|
|
|
long nWidth = 0;
|
|
|
|
long nHeight = 0;
|
|
|
|
mrParent.m_pVDev->GetSize( nWidth, nHeight );
|
|
|
|
return nWidth;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const
|
|
|
|
{
|
|
|
|
if( mrParent.m_pFrame )
|
|
|
|
return mrParent.m_pFrame->maGeometry.nHeight;
|
|
|
|
else if( mrParent.m_pVDev )
|
|
|
|
{
|
|
|
|
long nWidth = 0;
|
|
|
|
long nHeight = 0;
|
|
|
|
mrParent.m_pVDev->GetSize( nWidth, nHeight );
|
|
|
|
return nHeight;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void X11OpenGLSalGraphicsImpl::Init()
|
|
|
|
{
|
2014-11-13 21:05:30 +00:00
|
|
|
X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
|
|
|
|
if (pProvider)
|
2014-11-08 13:14:14 -05:00
|
|
|
{
|
2014-11-13 21:05:30 +00:00
|
|
|
Window aWin = pProvider->GetX11Window();
|
2014-11-08 13:14:14 -05:00
|
|
|
maContext.init( mrParent.GetXDisplay(), aWin, mrParent.m_nXScreen.getXScreen());
|
2014-11-10 13:46:12 -05:00
|
|
|
SetOffscreen( false );
|
2014-11-08 13:14:14 -05:00
|
|
|
}
|
|
|
|
else if( mrParent.m_pVDev )
|
|
|
|
{
|
|
|
|
maContext.init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
|
|
|
|
mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(),
|
|
|
|
mrParent.m_nXScreen.getXScreen() );
|
2014-11-10 13:46:12 -05:00
|
|
|
SetOffscreen( true );
|
2014-11-08 13:14:14 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SAL_WARN( "vcl.opengl", "what happened here?" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-13 09:32:41 -05:00
|
|
|
bool X11OpenGLSalGraphicsImpl::FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY )
|
2014-11-08 13:14:14 -05:00
|
|
|
{
|
|
|
|
Display* pDisplay = mrParent.GetXDisplay();
|
|
|
|
SalX11Screen nScreen = mrParent.GetScreenNumber();
|
2014-11-11 13:43:56 -05:00
|
|
|
XVisualInfo aVisualInfo;
|
|
|
|
XImage* pImage;
|
2014-11-12 12:51:03 -05:00
|
|
|
char* pData;
|
2014-11-08 13:14:14 -05:00
|
|
|
|
2014-11-13 09:32:41 -05:00
|
|
|
SAL_INFO( "vcl.opengl", "FillPixmapFromScreen" );
|
2014-11-11 13:43:56 -05:00
|
|
|
|
|
|
|
if( !OpenGLHelper::GetVisualInfo( pDisplay, nScreen.getXScreen(), aVisualInfo ) )
|
2014-11-13 09:32:41 -05:00
|
|
|
return false;
|
2014-11-11 13:43:56 -05:00
|
|
|
|
|
|
|
// make sure everything is synced up before reading back
|
|
|
|
maContext.makeCurrent();
|
|
|
|
glXWaitX();
|
|
|
|
|
|
|
|
// TODO: lfrb: What if offscreen?
|
2014-11-13 09:32:41 -05:00
|
|
|
pData = (char*) malloc( pPixmap->GetWidth() * pPixmap->GetHeight() * 4 );
|
2014-11-11 13:43:56 -05:00
|
|
|
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
|
2014-11-13 09:32:41 -05:00
|
|
|
glReadPixels( nX, GetHeight() - nY, pPixmap->GetWidth(), pPixmap->GetHeight(),
|
2014-11-11 13:43:56 -05:00
|
|
|
GL_RGBA, GL_UNSIGNED_BYTE, pData );
|
|
|
|
|
2014-11-12 12:51:03 -05:00
|
|
|
pImage = XCreateImage( pDisplay, aVisualInfo.visual, 24, ZPixmap, 0, pData,
|
2014-11-13 09:32:41 -05:00
|
|
|
pPixmap->GetWidth(), pPixmap->GetHeight(), 8, 0 );
|
2014-11-11 13:43:56 -05:00
|
|
|
XInitImage( pImage );
|
|
|
|
GC aGC = XCreateGC( pDisplay, pPixmap->GetPixmap(), 0, NULL );
|
|
|
|
XPutImage( pDisplay, pPixmap->GetDrawable(), aGC, pImage,
|
2014-11-13 09:32:41 -05:00
|
|
|
0, 0, 0, 0, pPixmap->GetWidth(), pPixmap->GetHeight() );
|
2014-11-11 13:43:56 -05:00
|
|
|
XFreeGC( pDisplay, aGC );
|
|
|
|
XDestroyImage( pImage );
|
|
|
|
|
2014-11-13 09:32:41 -05:00
|
|
|
return true;
|
2014-11-08 13:14:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
|
|
|
|
{
|
|
|
|
const int aAttribs[] = {
|
|
|
|
GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
|
|
|
|
GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
|
|
|
|
None
|
|
|
|
};
|
|
|
|
Display* pDisplay = mrParent.GetXDisplay();
|
|
|
|
GLXFBConfig pFbConfig;
|
|
|
|
GLXPixmap pGlxPixmap;
|
|
|
|
SalTwoRect aPosAry;
|
|
|
|
bool bInverted;
|
|
|
|
|
|
|
|
SAL_INFO( "vcl.opengl", "RenderPixmapToScreen (" << nX << " " << nY << ")" );
|
|
|
|
|
|
|
|
aPosAry.mnSrcX = 0;
|
|
|
|
aPosAry.mnSrcY = 0;
|
|
|
|
aPosAry.mnDestX = nX;
|
|
|
|
aPosAry.mnDestY = nY;
|
|
|
|
aPosAry.mnSrcWidth = aPosAry.mnDestWidth = pPixmap->GetWidth();
|
|
|
|
aPosAry.mnSrcHeight = aPosAry.mnDestHeight = pPixmap->GetHeight();
|
|
|
|
|
|
|
|
XSync( pDisplay, 0 );
|
|
|
|
pFbConfig = OpenGLHelper::GetPixmapFBConfig( pDisplay, bInverted );
|
|
|
|
pGlxPixmap = glXCreatePixmap( pDisplay, pFbConfig, pPixmap->GetPixmap(), aAttribs);
|
|
|
|
XSync( pDisplay, 0 );
|
|
|
|
|
2014-11-10 13:06:38 -05:00
|
|
|
PreDraw();
|
2014-11-08 13:14:14 -05:00
|
|
|
|
2014-11-13 21:37:54 -05:00
|
|
|
OpenGLTexture aTexture( pPixmap->GetWidth(), pPixmap->GetHeight(), false );
|
2014-11-08 13:14:14 -05:00
|
|
|
glActiveTexture( GL_TEXTURE0 );
|
2014-11-13 21:37:54 -05:00
|
|
|
aTexture.Bind();
|
2014-11-08 13:14:14 -05:00
|
|
|
|
|
|
|
//TODO: lfrb: glXGetProc to get the functions
|
|
|
|
glXBindTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT, NULL );
|
|
|
|
|
2014-11-13 21:37:54 -05:00
|
|
|
DrawTexture( aTexture, aPosAry, !bInverted );
|
2014-11-08 13:14:14 -05:00
|
|
|
|
|
|
|
glXReleaseTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT );
|
|
|
|
glXDestroyPixmap( pDisplay, pGlxPixmap );
|
2014-11-13 21:37:54 -05:00
|
|
|
aTexture.Unbind();
|
2014-11-08 13:14:14 -05:00
|
|
|
|
2014-11-10 13:06:38 -05:00
|
|
|
PostDraw();
|
|
|
|
|
2014-11-08 13:14:14 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|