vcl: Use the current OpenGL context for VirtualDevice and Bitmap if possible
Conflicts: include/vcl/opengl/OpenGLContext.hxx vcl/inc/openglgdiimpl.hxx vcl/opengl/gdiimpl.cxx vcl/opengl/x11/gdiimpl.cxx vcl/source/opengl/OpenGLContext.cxx Change-Id: I17f6ce66fb8b5bc027d35b4016ae56c24ee0a738
This commit is contained in:
committed by
Markus Mohrhard
parent
83c97b2a1c
commit
d6b51a87b4
@@ -65,10 +65,10 @@
|
||||
|
||||
OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
|
||||
: mpContext(0)
|
||||
, mpFramebuffer(NULL)
|
||||
, mbUseScissor(false)
|
||||
, mbUseStencil(false)
|
||||
, mbOffscreen(false)
|
||||
, mnFramebufferId(0)
|
||||
, mnLineColor(SALCOLOR_NONE)
|
||||
, mnFillColor(SALCOLOR_NONE)
|
||||
, mnSolidProgram(0)
|
||||
@@ -111,27 +111,30 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
|
||||
{
|
||||
}
|
||||
|
||||
bool OpenGLSalGraphicsImpl::AcquireContext( bool bOffscreen )
|
||||
OpenGLContext* OpenGLSalGraphicsImpl::GetOpenGLContext()
|
||||
{
|
||||
if( !mpContext )
|
||||
AcquireContext();
|
||||
return mpContext.get();
|
||||
}
|
||||
|
||||
bool OpenGLSalGraphicsImpl::AcquireContext( )
|
||||
{
|
||||
ImplSVData* pSVData = ImplGetSVData();
|
||||
|
||||
if( bOffscreen )
|
||||
{
|
||||
mpContext.reset(CreatePixmapContext());
|
||||
return (mpContext.get() != NULL);
|
||||
}
|
||||
mpContext.reset();
|
||||
|
||||
OpenGLContext* pContext = pSVData->maGDIData.mpLastContext;
|
||||
while( pContext )
|
||||
{
|
||||
// check if this context can be used by this SalGraphicsImpl instance
|
||||
if( CompareWinContext( pContext ) )
|
||||
if( UseContext( pContext ) )
|
||||
break;
|
||||
pContext = pContext->mpPrevContext;
|
||||
}
|
||||
|
||||
if (!pContext)
|
||||
pContext =CreateWinContext();
|
||||
pContext = mbOffscreen ? CreatePixmapContext() : CreateWinContext();
|
||||
|
||||
mpContext.reset(pContext);
|
||||
return (mpContext != nullptr);
|
||||
@@ -145,68 +148,41 @@ bool OpenGLSalGraphicsImpl::ReleaseContext()
|
||||
|
||||
void OpenGLSalGraphicsImpl::Init()
|
||||
{
|
||||
const bool bOffscreen = IsOffscreen();
|
||||
mbOffscreen = IsOffscreen();
|
||||
|
||||
// check if we can simply re-use the same context
|
||||
if( mpContext )
|
||||
{
|
||||
if( bOffscreen != mbOffscreen || ( !mbOffscreen && CompareWinContext( mpContext.get() ) ) )
|
||||
if( !UseContext( mpContext.get() ) )
|
||||
ReleaseContext();
|
||||
}
|
||||
|
||||
if( !mpContext && !AcquireContext( bOffscreen ) )
|
||||
// reset the offscreen texture
|
||||
if( !mbOffscreen ||
|
||||
maOffscreenTex.GetWidth() != GetWidth() ||
|
||||
maOffscreenTex.GetHeight() != GetHeight() )
|
||||
{
|
||||
SAL_WARN( "vcl.opengl", "Couldn't acquire context for SalGraphics" );
|
||||
return;
|
||||
}
|
||||
|
||||
mpContext->makeCurrent();
|
||||
|
||||
if( mbOffscreen == bOffscreen )
|
||||
{
|
||||
// Nothing more to do for onscreen case
|
||||
if( !mbOffscreen )
|
||||
return;
|
||||
|
||||
// Already enabled and same size
|
||||
if( maOffscreenTex.GetWidth() == GetWidth() &&
|
||||
maOffscreenTex.GetHeight() == GetHeight() )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mbOffscreen = bOffscreen;
|
||||
if( bOffscreen )
|
||||
glGenFramebuffers( 1, &mnFramebufferId );
|
||||
else
|
||||
glDeleteFramebuffers( 1, &mnFramebufferId );
|
||||
}
|
||||
|
||||
// Create/update attached offscreen texture
|
||||
if( mbOffscreen )
|
||||
{
|
||||
glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
|
||||
maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
|
||||
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, maOffscreenTex.Id(), 0 );
|
||||
GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
|
||||
if( nStatus != GL_FRAMEBUFFER_COMPLETE )
|
||||
SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
|
||||
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
|
||||
CHECK_GL_ERROR();
|
||||
maOffscreenTex = OpenGLTexture();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLSalGraphicsImpl::PreDraw()
|
||||
{
|
||||
assert( mpContext && mpContext->isInitialized() );
|
||||
if( !mpContext && !AcquireContext() )
|
||||
{
|
||||
SAL_WARN( "vcl.opengl", "Couldn't acquire context" );
|
||||
return;
|
||||
}
|
||||
|
||||
mpContext->makeCurrent();
|
||||
// TODO: lfrb: make sure the render target has the right size
|
||||
if( mbOffscreen )
|
||||
CheckOffscreenTexture();
|
||||
else
|
||||
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
if( !mbOffscreen )
|
||||
mpContext->AcquireDefaultFramebuffer();
|
||||
else
|
||||
CheckOffscreenTexture();
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
glViewport( 0, 0, GetWidth(), GetHeight() );
|
||||
ImplInitClipRegion();
|
||||
|
||||
@@ -215,15 +191,16 @@ void OpenGLSalGraphicsImpl::PreDraw()
|
||||
|
||||
void OpenGLSalGraphicsImpl::PostDraw()
|
||||
{
|
||||
if( mbOffscreen )
|
||||
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
|
||||
else if( mpContext->mnPainting == 0 )
|
||||
if( !mbOffscreen && mpContext->mnPainting == 0 )
|
||||
glFlush();
|
||||
if( mbUseScissor )
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
if( mbUseStencil )
|
||||
glDisable( GL_STENCIL_TEST );
|
||||
|
||||
mpContext->ReleaseFramebuffer( mpFramebuffer );
|
||||
mpFramebuffer = NULL;
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
@@ -279,6 +256,8 @@ void OpenGLSalGraphicsImpl::ImplInitClipRegion()
|
||||
glStencilFunc( GL_EQUAL, 1, 0x1 );
|
||||
glEnable( GL_STENCIL_TEST );
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
|
||||
@@ -371,26 +350,25 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
|
||||
|
||||
bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
|
||||
{
|
||||
glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
|
||||
if( !maOffscreenTex )
|
||||
maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
|
||||
|
||||
if( maOffscreenTex.IsUnique() )
|
||||
if( !maOffscreenTex.IsUnique() )
|
||||
{
|
||||
GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
|
||||
if( nStatus != GL_FRAMEBUFFER_COMPLETE )
|
||||
SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
|
||||
return true;
|
||||
GLfloat fWidth = GetWidth();
|
||||
GLfloat fHeight = GetHeight();
|
||||
SalTwoRect aPosAry(0, 0, fWidth, fHeight, 0,0, fWidth, fHeight);
|
||||
|
||||
// TODO: lfrb: User GL_ARB_copy_image?
|
||||
OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
|
||||
mpFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
|
||||
DrawTexture( maOffscreenTex, aPosAry );
|
||||
maOffscreenTex = aNewTex;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpFramebuffer = mpContext->AcquireFramebuffer( maOffscreenTex );
|
||||
}
|
||||
|
||||
GLfloat fWidth = GetWidth();
|
||||
GLfloat fHeight = GetHeight();
|
||||
SalTwoRect aPosAry(0, 0, fWidth, fHeight, 0,0, fWidth, fHeight);
|
||||
|
||||
// TODO: improve performance: lfrb: User GL_ARB_copy_image?
|
||||
OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
|
||||
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 );
|
||||
glViewport( 0, 0, GetWidth(), GetHeight() );
|
||||
DrawTexture( maOffscreenTex, aPosAry );
|
||||
maOffscreenTex = aNewTex;
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
return true;
|
||||
@@ -1895,13 +1873,17 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
|
||||
|
||||
void OpenGLSalGraphicsImpl::beginPaint()
|
||||
{
|
||||
SAL_INFO( "vcl.opengl", "BEGIN PAINT " << this );
|
||||
if( !mpContext && !AcquireContext() )
|
||||
return;
|
||||
|
||||
mpContext->mnPainting++;
|
||||
}
|
||||
|
||||
void OpenGLSalGraphicsImpl::endPaint()
|
||||
{
|
||||
SAL_INFO( "vcl.opengl", "END PAINT " << this );
|
||||
if( !mpContext && !AcquireContext() )
|
||||
return;
|
||||
|
||||
mpContext->mnPainting--;
|
||||
assert( mpContext->mnPainting >= 0 );
|
||||
if( mpContext->mnPainting == 0 && !mbOffscreen )
|
||||
|
Reference in New Issue
Block a user