Kaydet (Commit) 56900a44 authored tarafından Michael Meeks's avatar Michael Meeks

tdf#94006 - fix OpenGLContext mis-use in several places.

gltf rendering, OpenGL canvas, GL transitions & GL capable (charts)
Avoid GLX operations on un-initialized contexts.

Change-Id: I7f523640f66ab656896181e5c865879234f6640e
üst 2456cf83
......@@ -28,6 +28,7 @@ namespace avmedia { namespace ogl {
OGLPlayer::OGLPlayer()
: Player_BASE(m_aMutex)
, m_pHandle(NULL)
, m_xContext(OpenGLContext::Create())
, m_pOGLWindow(NULL)
, m_bIsRendering(false)
{
......@@ -38,7 +39,7 @@ OGLPlayer::~OGLPlayer()
osl::MutexGuard aGuard(m_aMutex);
if( m_pHandle )
{
m_aContext.makeCurrent();
m_xContext->makeCurrent();
gltf_renderer_release(m_pHandle);
}
releaseInputFiles();
......@@ -258,13 +259,13 @@ uno::Reference< media::XPlayerWindow > SAL_CALL OGLPlayer::createPlayerWindow( c
}
assert(pChildWindow->GetParent());
if( !m_aContext.init(pChildWindow) )
if( !m_xContext->init(pChildWindow) )
{
SAL_WARN("avmedia.opengl", "Context initialization failed");
return uno::Reference< media::XPlayerWindow >();
}
if( !m_aContext.supportMultiSampling() )
if( !m_xContext->supportMultiSampling() )
{
SAL_WARN("avmedia.opengl", "Context does not support multisampling!");
return uno::Reference< media::XPlayerWindow >();
......@@ -277,7 +278,7 @@ uno::Reference< media::XPlayerWindow > SAL_CALL OGLPlayer::createPlayerWindow( c
}
Size aSize = pChildWindow->GetSizePixel();
m_aContext.setWinSize(aSize);
m_xContext->setWinSize(aSize);
m_pHandle->viewport.x = 0;
m_pHandle->viewport.y = 0;
m_pHandle->viewport.width = aSize.Width();
......@@ -294,7 +295,7 @@ uno::Reference< media::XPlayerWindow > SAL_CALL OGLPlayer::createPlayerWindow( c
// The background color is white by default, but we need to separate the
// OpenGL window from the main window so set background color to grey
glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
m_pOGLWindow = new OGLWindow(*m_pHandle, m_aContext, *pChildWindow->GetParent());
m_pOGLWindow = new OGLWindow(*m_pHandle, m_xContext, *pChildWindow->GetParent());
return uno::Reference< media::XPlayerWindow >( m_pOGLWindow );
}
......@@ -304,13 +305,13 @@ uno::Reference< media::XFrameGrabber > SAL_CALL OGLPlayer::createFrameGrabber()
osl::MutexGuard aGuard(m_aMutex);
assert(m_pHandle);
if( !m_aContext.init() )
if( !m_xContext->init() )
{
SAL_WARN("avmedia.opengl", "Offscreen context initialization failed");
return uno::Reference< media::XFrameGrabber >();
}
if( !m_aContext.supportMultiSampling() )
if( !m_xContext->supportMultiSampling() )
{
SAL_WARN("avmedia.opengl", "Context does not support multisampling!");
return uno::Reference< media::XFrameGrabber >();
......
......@@ -68,7 +68,7 @@ private:
libgltf::glTFHandle* m_pHandle;
std::vector<libgltf::glTFFile> m_vInputFiles;
OpenGLContext m_aContext;
rtl::Reference<OpenGLContext> m_xContext;
AutoTimer m_aTimer;
OGLWindow* m_pOGLWindow;
bool m_bIsRendering;
......
......@@ -15,9 +15,9 @@ using namespace libgltf;
namespace avmedia { namespace ogl {
OGLWindow::OGLWindow( glTFHandle& rHandle, OpenGLContext& rContext, vcl::Window& rEventHandlerParent )
OGLWindow::OGLWindow( glTFHandle& rHandle, const rtl::Reference<OpenGLContext> &rContext, vcl::Window& rEventHandlerParent )
: m_rHandle( rHandle )
, m_rContext( rContext )
, m_xContext( rContext )
, m_rEventHandler( rEventHandlerParent )
, m_bVisible ( false )
, m_aLastMousePos(Point(0,0))
......@@ -32,7 +32,7 @@ OGLWindow::~OGLWindow()
void SAL_CALL OGLWindow::update() throw (css::uno::RuntimeException, std::exception)
{
m_rContext.makeCurrent();
m_xContext->makeCurrent();
int nRet = gltf_prepare_renderer(&m_rHandle);
if( nRet != 0 )
{
......@@ -41,7 +41,7 @@ void SAL_CALL OGLWindow::update() throw (css::uno::RuntimeException, std::except
}
gltf_renderer(&m_rHandle);
gltf_complete_renderer(&m_rHandle);
m_rContext.swapBuffers();
m_xContext->swapBuffers();
}
sal_Bool SAL_CALL OGLWindow::setZoomLevel( css::media::ZoomLevel /*eZoomLevel*/ ) throw (css::uno::RuntimeException, std::exception)
......@@ -98,7 +98,7 @@ void SAL_CALL OGLWindow::setPosSize( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidt
if( m_rHandle.viewport.x != nX || m_rHandle.viewport.x != nY ||
m_rHandle.viewport.width != nWidth || m_rHandle.viewport.height != nHeight )
{
m_rContext.setWinSize(Size(nWidth,nHeight));
m_xContext->setWinSize(Size(nWidth,nHeight));
m_rHandle.viewport.x = nX;
m_rHandle.viewport.y = nY;
m_rHandle.viewport.width = nWidth;
......
......@@ -27,7 +27,7 @@ namespace avmedia { namespace ogl {
class OGLWindow : public ::cppu::WeakImplHelper< css::media::XPlayerWindow, css::lang::XServiceInfo >
{
public:
OGLWindow( libgltf::glTFHandle& rHandle, OpenGLContext& rContext, vcl::Window& rEventHandlerParent );
OGLWindow( libgltf::glTFHandle& rHandle, const rtl::Reference<OpenGLContext> & rContext, vcl::Window& rEventHandlerParent );
virtual ~OGLWindow();
virtual void SAL_CALL update() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
......@@ -66,7 +66,7 @@ private:
DECL_LINK( CameraHandler, VclWindowEvent* );
libgltf::glTFHandle& m_rHandle;
OpenGLContext& m_rContext;
rtl::Reference<OpenGLContext> m_xContext;
vcl::Window& m_rEventHandler;
bool m_bVisible;
......
......@@ -85,7 +85,8 @@ namespace oglcanvas
mnRadialTwoColorGradientProgram(0),
mnRadialMultiColorGradientProgram(0),
mnRectangularTwoColorGradientProgram(0),
mnRectangularMultiColorGradientProgram(0)
mnRectangularMultiColorGradientProgram(0),
mxContext(OpenGLContext::Create())
{}
SpriteDeviceHelper::~SpriteDeviceHelper()
......@@ -102,8 +103,8 @@ namespace oglcanvas
VCLUnoHelper::GetInterface(&rWindow),
uno::UNO_QUERY_THROW) );
maContext.requestLegacyContext();
maContext.init(&rWindow);
mxContext->requestLegacyContext();
mxContext->init(&rWindow);
// init window context
initContext();
......@@ -125,7 +126,7 @@ namespace oglcanvas
mnRectangularTwoColorGradientProgram =
OpenGLHelper::LoadShaders("dummyVertexShader", "rectangularTwoColorGradientFragmentShader");
maContext.makeCurrent();
mxContext->makeCurrent();
notifySizeUpdate(rViewArea);
// TODO(E3): check for GL_ARB_imaging extension
......@@ -138,7 +139,7 @@ namespace oglcanvas
mpDevice = NULL;
mpTextureCache.reset();
if( maContext.isInitialized() )
if( mxContext->isInitialized() )
{
glDeleteProgram( mnRectangularTwoColorGradientProgram );
glDeleteProgram( mnRectangularMultiColorGradientProgram );
......@@ -151,11 +152,11 @@ namespace oglcanvas
geometry::RealSize2D SpriteDeviceHelper::getPhysicalResolution()
{
if( !maContext.isInitialized() )
if( !mxContext->isInitialized() )
return ::canvas::tools::createInfiniteSize2D(); // we're disposed
// Map a one-by-one millimeter box to pixel
SystemChildWindow* pChildWindow = maContext.getChildWindow();
SystemChildWindow* pChildWindow = mxContext->getChildWindow();
const MapMode aOldMapMode( pChildWindow->GetMapMode() );
pChildWindow->SetMapMode( MapMode(MAP_MM) );
const Size aPixelSize( pChildWindow->LogicToPixel(Size(1,1)) );
......@@ -166,11 +167,11 @@ namespace oglcanvas
geometry::RealSize2D SpriteDeviceHelper::getPhysicalSize()
{
if( !maContext.isInitialized() )
if( !mxContext->isInitialized() )
return ::canvas::tools::createInfiniteSize2D(); // we're disposed
// Map the pixel dimensions of the output window to millimeter
SystemChildWindow* pChildWindow = maContext.getChildWindow();
SystemChildWindow* pChildWindow = mxContext->getChildWindow();
const MapMode aOldMapMode( pChildWindow->GetMapMode() );
pChildWindow->SetMapMode( MapMode(MAP_MM) );
const Size aLogSize( pChildWindow->PixelToLogic(pChildWindow->GetOutputSizePixel()) );
......@@ -271,13 +272,13 @@ namespace oglcanvas
bool SpriteDeviceHelper::showBuffer( bool bIsVisible, bool /*bUpdateAll*/ )
{
// hidden or disposed?
if( !bIsVisible || !maContext.isInitialized() || !mpSpriteCanvas )
if( !bIsVisible || !mxContext->isInitialized() || !mpSpriteCanvas )
return false;
if( !activateWindowContext() )
return false;
SystemChildWindow* pChildWindow = maContext.getChildWindow();
SystemChildWindow* pChildWindow = mxContext->getChildWindow();
const ::Size& rOutputSize = pChildWindow->GetSizePixel();
initTransformation(rOutputSize);
......@@ -326,7 +327,7 @@ namespace oglcanvas
unx::glXWaitGL();
XSync( reinterpret_cast<unx::Display*>(mpDisplay), false );
*/
maContext.swapBuffers();
mxContext->swapBuffers();
// flush texture cache, such that it does not build up
// indefinitely.
......@@ -350,7 +351,7 @@ namespace oglcanvas
uno::Any SpriteDeviceHelper::getDeviceHandle() const
{
const SystemChildWindow* pChildWindow = maContext.getChildWindow();
const SystemChildWindow* pChildWindow = mxContext->getChildWindow();
return uno::makeAny( reinterpret_cast< sal_Int64 >(pChildWindow) );
}
......@@ -369,9 +370,9 @@ namespace oglcanvas
void SpriteDeviceHelper::notifySizeUpdate( const awt::Rectangle& rBounds )
{
if( maContext.isInitialized() )
if( mxContext->isInitialized() )
{
SystemChildWindow* pChildWindow = maContext.getChildWindow();
SystemChildWindow* pChildWindow = mxContext->getChildWindow();
pChildWindow->setPosSizePixel(
0,0,rBounds.Width,rBounds.Height);
}
......@@ -506,7 +507,7 @@ namespace oglcanvas
bool SpriteDeviceHelper::activateWindowContext()
{
maContext.makeCurrent();
mxContext->makeCurrent();
return true;
}
......
......@@ -140,7 +140,7 @@ namespace oglcanvas
unsigned int mnRectangularTwoColorGradientProgram;
unsigned int mnRectangularMultiColorGradientProgram;
OpenGLContext maContext;
rtl::Reference<OpenGLContext> mxContext;
};
}
......
......@@ -169,8 +169,8 @@ struct GLWindow
class VCL_DLLPUBLIC OpenGLContext
{
friend class OpenGLTests;
public:
OpenGLContext();
public:
static rtl::Reference<OpenGLContext> Create();
~OpenGLContext();
void acquire() { mnRefCount++; }
......
......@@ -228,7 +228,7 @@ private:
void impl_finishTransition();
private:
boost::shared_ptr<OpenGLContext> mpContext;
rtl::Reference<OpenGLContext> mpContext;
/** OpenGL handle to the leaving slide's texture
*/
......@@ -368,7 +368,7 @@ bool OGLTransitionerImpl::initWindowFromSlideShowView( const Reference< presenta
sal_Int64 aVal = 0;
aDeviceParams[1] >>= aVal;
mpContext = boost::make_shared<OpenGLContext>();
mpContext = OpenGLContext::Create();
mpContext->requestLegacyContext();
if( !mpContext->init( reinterpret_cast< vcl::Window* >( aVal ) ) )
......@@ -1323,7 +1323,7 @@ void OGLTransitionerImpl::impl_dispose()
{
impl_finishTransition();
disposeTextures();
mpContext.reset();
mpContext.clear();
}
// we are about to be disposed (someone call dispose() on us)
......@@ -1350,7 +1350,7 @@ void OGLTransitionerImpl::disposing()
#endif
#if defined( UNX ) && !defined( MACOSX )
if( mbRestoreSync && bool(mpContext) ) {
if( mbRestoreSync && bool(mpContext.is()) ) {
// try to reestablish synchronize state
char* sal_synchronize = getenv("SAL_SYNCHRONIZE");
XSynchronize( mpContext->getOpenGLWindow().dpy, sal_synchronize && *sal_synchronize == '1' );
......
......@@ -1362,11 +1362,14 @@ void OpenGLContext::makeCurrent()
TempErrorHandler aErrorHandler(m_aGLWin.dpy, unxErrorHandler);
#endif
GLXDrawable nDrawable = mbPixmap ? m_aGLWin.glPix : m_aGLWin.win;
if (!glXMakeCurrent( m_aGLWin.dpy, nDrawable, m_aGLWin.ctx ))
if (m_aGLWin.dpy)
{
SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent failed on drawable " << nDrawable << " pixmap? " << mbPixmap);
return;
GLXDrawable nDrawable = mbPixmap ? m_aGLWin.glPix : m_aGLWin.win;
if (!glXMakeCurrent( m_aGLWin.dpy, nDrawable, m_aGLWin.ctx ))
{
SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent failed on drawable " << nDrawable << " pixmap? " << mbPixmap);
return;
}
}
#endif
......
......@@ -17,18 +17,19 @@ class OpenGLWindowImpl
public:
explicit OpenGLWindowImpl(vcl::Window* pWindow);
~OpenGLWindowImpl() { mxChildWindow.disposeAndClear(); }
OpenGLContext& getContext() { return maContext;}
OpenGLContext& getContext() { return *mxContext.get(); }
private:
OpenGLContext maContext;
rtl::Reference<OpenGLContext> mxContext;
VclPtr<SystemChildWindow> mxChildWindow;
};
OpenGLWindowImpl::OpenGLWindowImpl(vcl::Window* pWindow)
: mxContext(OpenGLContext::Create())
{
SystemWindowData aData = OpenGLContext::generateWinData(pWindow, false);
mxChildWindow.reset(VclPtr<SystemChildWindow>::Create(pWindow, 0, &aData));
mxChildWindow->Show();
maContext.init(mxChildWindow.get());
mxContext->init(mxChildWindow.get());
pWindow->SetMouseTransparent(false);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment