Rebased ref, commits from common ancestor: commit c6d3598f2fb9e5f46f5df2c997ac7c09813ee7b9 Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Nov 27 18:56:54 2015 +0000
vcl: move begin/end paint counting to SalGraphics where it fits nicely. Also elide dupliate swap / flushes - if no rendering occurred between times. diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index 36efe03..92d4d11 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -248,7 +248,6 @@ private: public: vcl::Region maClipRegion; - int mnPainting; // Don't hold references to ourselves: OpenGLContext *mpPrevContext; diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 2bf3f07..68a5170 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -612,8 +612,9 @@ public: */ class PaintScope { VclPtr<OutputDevice> mpDev; + void *mpDebug; public: - PaintScope(OutputDevice *); + explicit PaintScope(OutputDevice *); ~PaintScope(); void flush(); }; diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 87000c3..d280743 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -347,12 +347,8 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override; - virtual OpenGLContext *beginPaint() override; - virtual void endPaint() override; - /// flush contents of the back-buffer to the screen & swap. - void flushAndSwap(); -private: + virtual void flush() override; }; #endif diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx index 14fb2fa..c8ae6b2 100644 --- a/vcl/inc/salframe.hxx +++ b/vcl/inc/salframe.hxx @@ -253,6 +253,13 @@ public: { return m_pProc ? long(m_pProc( m_pWindow, const_cast<SalFrame*>(this), nEvent, pEvent )) : 0; } bool PaintsBlocked() const { return m_bPaintsBlocked; } + + // track painting, and flush when its done. + void BeginPaint(); + void EndPaint(); + sal_uInt32 GetPaintNesting() { return m_nPaintNesting; } +private: + sal_uInt32 m_nPaintNesting; }; #endif // INCLUDED_VCL_INC_SALFRAME_HXX diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 62f714f..045ae48 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -438,11 +438,11 @@ public: sal_uInt8 nTransparency, const OutputDevice *pOutDev ); - virtual OpenGLContext *BeginPaint() { return nullptr; } - virtual void EndPaint() { } - virtual SystemGraphicsData GetGraphicsData() const = 0; + /// Push any pending rendering to the screen. + virtual void Flush(); + #if ENABLE_CAIRO_CANVAS /// Check whether cairo will work diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index 1a1c3ef..7a6858f 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -212,8 +212,8 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0; - virtual OpenGLContext *beginPaint() { return nullptr; } - virtual void endPaint() { } + /// flush and hence render any pending rendering commands + virtual void flush() { } }; #endif diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index ea7da0b..9212a99 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -263,9 +263,6 @@ public: virtual css::uno::Any GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const override; virtual SystemFontData GetSysFontData( int nFallbackLevel ) const override; - virtual OpenGLContext *BeginPaint() override; - virtual void EndPaint() override; - bool TryRenderCachedNativeControl(ControlCacheKey& aControlCacheKey, int nX, int nY); diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 25a416b..4fb8414 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -436,9 +436,6 @@ public: virtual SystemGraphicsData GetGraphicsData() const override; - virtual OpenGLContext *BeginPaint() override; - virtual void EndPaint() override; - /// Update settings based on the platform values static void updateSettingsNative( AllSettings& rSettings ); }; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index a87c05c..b21eb12 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -154,6 +154,10 @@ void OpenGLSalGraphicsImpl::Init() mpContext->ReleaseFramebuffer( maOffscreenTex ); } maOffscreenTex = OpenGLTexture(); + SAL_DEBUG("paint: " << this << " size mismatch - delete texture " << + maOffscreenTex.GetWidth() << " x " << + maOffscreenTex.GetHeight() << " vs. " << + GetWidth() << " x " << GetHeight()); VCL_GL_INFO("::Init - re-size offscreen texture"); } @@ -232,10 +236,15 @@ void OpenGLSalGraphicsImpl::PostDraw() else assert( mpWindowContext.is() ); - if( mpContext->mnPainting == 0 ) + // FIXME: we should flush when something is drawn outside paint really. + if( !IsOffscreen() ) { - if (!IsOffscreen()) - flushAndSwap(); + SalFrame *pFrame = dynamic_cast< SalFrame * >(mpProvider); + if( pFrame && pFrame->GetPaintNesting() == 0 ) + { + VCL_GL_INFO( "uncontrolled rendering: catch and stop me." ); + flush(); + } } OpenGLZone::leave(); @@ -429,6 +438,7 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() mpContext->ReleaseFramebuffer( maOffscreenTex ); maOffscreenTex = OpenGLTexture(); VCL_GL_INFO( "re-size offscreen texture" ); + SAL_DEBUG( "paint: " << this << " re-size offscreen texture" ); } } @@ -436,6 +446,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() { VCL_GL_INFO( "create texture of size " << GetWidth() << " x " << GetHeight() ); + SAL_DEBUG( "paint: " << this << " create texture of size " + << GetWidth() << " x " << GetHeight() ); maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() ); bClearTexture = true; } @@ -1936,26 +1948,29 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, return true; } -OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() +void OpenGLSalGraphicsImpl::flush() { - AcquireContext(); - if( mpContext.is() ) - mpContext->mnPainting++; - return mpContext.get(); -} + if( IsOffscreen() ) + return; -void OpenGLSalGraphicsImpl::flushAndSwap() -{ - assert( !IsOffscreen() ); assert( mpWindowContext.is() ); - assert( mpContext.is() ); if( !maOffscreenTex ) { + SAL_DEBUG("paint: " << this << " flush and swap - no texture !"); VCL_GL_INFO( "flushAndSwap - odd no texture !" ); return; } + if (mnDrawCountAtFlush == mnDrawCount) + { + VCL_GL_INFO( "eliding redundant flushAndSwap, no drawing since last!" ); + SAL_DEBUG( "paint: " << this << " eliding redundant flushAndSwap, no drawing since last!" ); + return; + } + + SAL_DEBUG("paint: " << this << " flush and swap"); + mnDrawCountAtFlush = mnDrawCount; OpenGLZone aZone; @@ -2044,19 +2059,6 @@ void OpenGLSalGraphicsImpl::flushAndSwap() VCL_GL_INFO( "flushAndSwap - end." ); } -void OpenGLSalGraphicsImpl::endPaint() -{ - assert( !IsOffscreen() ); - - AcquireContext(); - if( mpContext.is() ) - { - mpContext->mnPainting--; - if( mpContext->mnPainting == 0 ) - flushAndSwap(); - } -} - bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext) { // so far a blunt heuristic: vcl uses shiny new contexts. diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index c540eef5..bc77397 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -33,6 +33,7 @@ SalFrame::SalFrame() : m_bPaintsBlocked(false) , m_pWindow(nullptr) , m_pProc(nullptr) + , m_nPaintNesting( 0 ) { } @@ -41,6 +42,8 @@ SalFrame::SalFrame() SalFrame::~SalFrame() { + // don't destroy graphics while mid-paint. + assert(m_nPaintNesting == 0); } void SalFrame::SetCallback( vcl::Window* pWindow, SALFRAMEPROC pProc ) @@ -56,6 +59,21 @@ void SalFrame::Flush( const Rectangle& ) Flush(); } +void SalFrame::BeginPaint() +{ + m_nPaintNesting++; + assert (m_nPaintNesting > 0); + SAL_DEBUG("paint: " << this << " begin " << m_nPaintNesting); +} + +void SalFrame::EndPaint() +{ + SAL_DEBUG("paint: " << this << " end " << m_nPaintNesting); + assert (m_nPaintNesting > 0); + if (--m_nPaintNesting == 0) + Flush(); +} + void SalFrame::SetRepresentedURL( const OUString& ) { // currently this is Mac only functionality diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 6d04c1e..7dcb3a7 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -65,7 +65,7 @@ SalFrameGeometry SalFrame::GetGeometry() SalGraphics::SalGraphics() : m_nLayout( SalLayoutFlags::NONE ), - m_bAntiAliasB2DDraw(false) + m_bAntiAliasB2DDraw( false ) { // read global RTL settings if( AllSettings::GetLayoutRTL() ) @@ -76,6 +76,13 @@ SalGraphics::~SalGraphics() { } +void SalGraphics::Flush() +{ + SalGraphicsImpl* pImpl = GetImpl(); + if (pImpl) + pImpl->flush(); +} + rtl::Reference<OpenGLContext> SalGraphics::GetOpenGLContext() const { OpenGLSalGraphicsImpl *pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(GetImpl()); diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 09fac7b..93f91bc 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -65,7 +65,6 @@ OpenGLContext::OpenGLContext(): mpFirstFramebuffer(nullptr), mpLastFramebuffer(nullptr), mpCurrentProgram(nullptr), - mnPainting(0), mpPrevContext(nullptr), mpNextContext(nullptr) { @@ -1199,9 +1198,6 @@ void OpenGLContext::reset() OpenGLZone aZone; - // don't reset a context in the middle of stack frames rendering to it - assert( mnPainting == 0 ); - // reset the clip region maClipRegion.SetEmpty(); diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx index 1779002..fc5418c 100644 --- a/vcl/source/outdev/outdev.cxx +++ b/vcl/source/outdev/outdev.cxx @@ -846,11 +846,23 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, } OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) - : mpDev( pDev ) { - SalGraphics *mpGraphics = mpDev->GetGraphics(); - if (mpGraphics) - mpGraphics->BeginPaint(); + vcl::Window *pWindow = dynamic_cast<vcl::Window *>(pDev); + + if (!pWindow) // no point on a non-window + { + mpDebug = NULL; + return; + } + + mpDev = pDev; + + SalFrame *pFrame = pWindow->ImplGetFrame(); + mpDebug = pFrame; + if (pFrame) + pFrame->BeginPaint(); + else + SAL_WARN("vcl.gdi", "paintscope: no frame for window " << pWindow); } OutputDevice::PaintScope::~PaintScope() @@ -861,10 +873,16 @@ OutputDevice::PaintScope::~PaintScope() /// Flush all the queued rendering commands to the screen for this context. void OutputDevice::PaintScope::flush() { - SalGraphics *mpGraphics = mpDev->GetGraphics(); - if (mpGraphics) - mpGraphics->EndPaint(); -} + /// SAL_DEBUG kill this method - why a separate flush ? -> fold me into ~PaintScope. + vcl::Window *pWindow = static_cast<vcl::Window *>(mpDev.get()); + SalFrame *pFrame = pWindow->ImplGetFrame(); + if (!pFrame || pWindow->isDisposed()) + SAL_WARN("vcl.gdi", "Very odd, window disposed while painting"); + else + assert (pFrame == mpDebug); + + pFrame->EndPaint(); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 8901512..254400e 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -788,6 +788,8 @@ bool Window::AcquireGraphics() const // try harder if no wingraphics was available directly if ( !mpGraphics ) { + assert ("this is utterly lame !" || false); + // find another output device in the same frame OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics; while ( pReleaseOutDev ) diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index 1241439..d98466a 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -557,16 +557,6 @@ bool X11SalGraphics::drawGradient(const tools::PolyPolygon& rPoly, const Gradien return mxImpl->drawGradient(rPoly, rGradient); } -OpenGLContext *X11SalGraphics::BeginPaint() -{ - return mxImpl->beginPaint(); -} - -void X11SalGraphics::EndPaint() -{ - return mxImpl->endPaint(); -} - SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const { if (m_pFrame) diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx index c0e3e75..6b1bbff 100644 --- a/vcl/unx/generic/window/salframe.cxx +++ b/vcl/unx/generic/window/salframe.cxx @@ -2286,6 +2286,11 @@ void X11SalFrame::SetTitle( const OUString& rTitle ) void X11SalFrame::Flush() { + SAL_DEBUG("flush " << this); + if( pGraphics_ ) + pGraphics_->Flush(); + if( pFreeGraphics_ ) + pFreeGraphics_->Flush(); XFlush( GetDisplay()->GetDisplay() ); } diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx index c5c01a4..c318db9 100644 --- a/vcl/unx/gtk/gtksalframe.cxx +++ b/vcl/unx/gtk/gtksalframe.cxx @@ -2623,6 +2623,9 @@ void GtkSalFrame::SetPointerPos( long nX, long nY ) void GtkSalFrame::Flush() { + if( m_pGraphics ) + m_pGraphics->Flush(); + #if GTK_CHECK_VERSION(3,0,0) gdk_display_flush( getGdkDisplay() ); #else diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index 1462f25..36ff322 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -1046,14 +1046,4 @@ SystemGraphicsData WinSalGraphics::GetGraphicsData() const return aRes; } -OpenGLContext *WinSalGraphics::BeginPaint() -{ - return mpImpl->beginPaint(); -} - -void WinSalGraphics::EndPaint() -{ - return mpImpl->endPaint(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 47a0142a831c5dc78b95e85e13aa6dba4ce267b9 Author: Michael Meeks <michael.me...@collabora.com> Date: Thu Nov 26 21:47:35 2015 +0000 More smoketest notes. Change-Id: I52bd1555e572c75feb0fc96368b6e61802d9d65c diff --git a/smoketest/README b/smoketest/README index b1d250d..30dceb6 100644 --- a/smoketest/README +++ b/smoketest/README @@ -12,4 +12,7 @@ data/Basic/Standard. macro and waits for a dispatchFinished from the macro's execution. To debug this best load workdir/Zip/smoketestdoc.sxw - and hit 'start smoketest' - this will launch a number of components and build a -suitable report in the form of a table. \ No newline at end of file +suitable report in the form of a table. + + The StarBasic smoketests also log their output, this ends up +in instdir/user/temp/smoketest.log. commit f1fd51628cd90864c6a4ea163261371432bde9c4 Author: Michael Meeks <michael.me...@collabora.com> Date: Sat Nov 21 16:19:08 2015 +0000 vcl rebase cleanup; also assertions on non-flushed SalGraphics. Change-Id: I41443640e00c69891e4a95ced84b97b8b4626cd8 diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index c391853..87000c3 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -89,6 +89,8 @@ protected: SalColor mnFillColor; #ifdef DBG_UTIL bool mProgramIsSolidColor; + sal_uInt32 mnDrawCount; + sal_uInt32 mnDrawCountAtFlush; #endif SalColor mProgramSolidColor; double mProgramSolidTransparency; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index bf7ab78..a87c05c 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -51,6 +51,8 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr , mnFillColor(SALCOLOR_NONE) #ifdef DBG_UTIL , mProgramIsSolidColor(false) + , mnDrawCount(0) + , mnDrawCountAtFlush(0) #endif , mProgramSolidColor(SALCOLOR_NONE) , mProgramSolidTransparency(0.0) @@ -59,6 +61,14 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl() { +#ifdef DBG_UTIL + if( !IsOffscreen() ) + { + // Check that all SalGraphics have flushed before being destroyed + assert( mnDrawCountAtFlush == mnDrawCount ); + } +#endif + ReleaseContext(); } @@ -144,7 +154,7 @@ void OpenGLSalGraphicsImpl::Init() mpContext->ReleaseFramebuffer( maOffscreenTex ); } maOffscreenTex = OpenGLTexture(); - VCL_GL_INFO("vcl.opengl", "::Init - re-size offscreen texture"); + VCL_GL_INFO("::Init - re-size offscreen texture"); } if( !IsOffscreen() ) @@ -173,6 +183,8 @@ void OpenGLSalGraphicsImpl::PreDraw() { OpenGLZone::enter(); + mnDrawCount++; + if( !AcquireContext() ) { SAL_WARN( "vcl.opengl", "Couldn't acquire context" ); @@ -239,7 +251,7 @@ void OpenGLSalGraphicsImpl::freeResources() // TODO Delete shaders, programs and textures if not shared if( mpContext.is() && mpContext->isInitialized() ) { - VCL_GL_INFO( "vcl.opengl", "freeResources" ); + VCL_GL_INFO( "freeResources" ); mpContext->makeCurrent(); mpContext->ReleaseFramebuffer( maOffscreenTex ); } @@ -406,7 +418,7 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() { bool bClearTexture = false; - VCL_GL_INFO( "vcl.opengl", "Check Offscreen texture" ); + VCL_GL_INFO( "Check Offscreen texture" ); // Always create the offscreen texture if( maOffscreenTex ) @@ -416,13 +428,13 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() { mpContext->ReleaseFramebuffer( maOffscreenTex ); maOffscreenTex = OpenGLTexture(); - VCL_GL_INFO( "vcl.opengl", "re-size offscreen texture" ); + VCL_GL_INFO( "re-size offscreen texture" ); } } if( !maOffscreenTex ) { - VCL_GL_INFO( "vcl.opengl", "create texture of size " + VCL_GL_INFO( "create texture of size " << GetWidth() << " x " << GetHeight() ); maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() ); bClearTexture = true; @@ -1940,25 +1952,27 @@ void OpenGLSalGraphicsImpl::flushAndSwap() if( !maOffscreenTex ) { - VCL_GL_INFO( "vcl.opengl", "flushAndSwap - odd no texture !" ); + VCL_GL_INFO( "flushAndSwap - odd no texture !" ); return; } + mnDrawCountAtFlush = mnDrawCount; + OpenGLZone aZone; - VCL_GL_INFO( "vcl.opengl", "flushAndSwap" ); + VCL_GL_INFO( "flushAndSwap" ); // Interesting ! -> this destroys a context [ somehow ] ... mpWindowContext->makeCurrent(); CHECK_GL_ERROR(); - VCL_GL_INFO( "vcl.opengl", "flushAndSwap - acquire default frame buffer" ); + VCL_GL_INFO( "flushAndSwap - acquire default frame buffer" ); mpWindowContext->AcquireDefaultFramebuffer(); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); // FIXME: paranoid double check. CHECK_GL_ERROR(); - VCL_GL_INFO( "vcl.opengl", "flushAndSwap - acquired default frame buffer" ); + VCL_GL_INFO( "flushAndSwap - acquired default frame buffer" ); glDisable( GL_SCISSOR_TEST ); // FIXME: paranoia ... CHECK_GL_ERROR(); @@ -1975,20 +1989,20 @@ void OpenGLSalGraphicsImpl::flushAndSwap() SalTwoRect aPosAry( 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(), 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight() ); - VCL_GL_INFO( "vcl.opengl", "Texture height " << maOffscreenTex.GetHeight() << " vs. window height " << GetHeight() ); + VCL_GL_INFO( "Texture height " << maOffscreenTex.GetHeight() << " vs. window height " << GetHeight() ); OpenGLProgram *pProgram = mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" ); if( !pProgram ) - VCL_GL_INFO( "vcl.opengl", "Can't compile simple copying shader !" ); + VCL_GL_INFO( "Can't compile simple copying shader !" ); else { pProgram->Use(); // FIXME: paranoia ... - VCL_GL_INFO( "vcl.opengl", "done paranoid re-use." ); + VCL_GL_INFO( "done paranoid re-use." ); pProgram->SetTexture( "sampler", maOffscreenTex ); maOffscreenTex.Bind(); // FIXME: paranoia ... - VCL_GL_INFO( "vcl.opengl", "bound bits etc." ); + VCL_GL_INFO( "bound bits etc." ); GLfloat aTexCoord[8]; maOffscreenTex.GetCoord( aTexCoord, aPosAry, false ); @@ -2027,7 +2041,7 @@ void OpenGLSalGraphicsImpl::flushAndSwap() usleep(500 * 1000); } } - VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." ); + VCL_GL_INFO( "flushAndSwap - end." ); } void OpenGLSalGraphicsImpl::endPaint() diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 5cb1aea..09fac7b 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -1372,7 +1372,7 @@ void OpenGLContext::prepareForYield() { ImplSVData* pSVData = ImplGetSVData(); - VCL_GL_INFO("vcl.opengl", "clearCurrent - detachframebuffers"); + VCL_GL_INFO("clearCurrent - detachframebuffers"); // release all framebuffers from the old context so we can re-attach the // texture in the new context @@ -1541,9 +1541,9 @@ bool OpenGLContext::BindFramebuffer( OpenGLFramebuffer* pFramebuffer ) else OpenGLFramebuffer::Unbind(); - VCL_GL_INFO( "vcl.opengl", "before assign pFramebuffer" ); + VCL_GL_INFO( "before assign pFramebuffer" ); mpCurrentFramebuffer = pFramebuffer; - VCL_GL_INFO( "vcl.opengl", "after assign pFramebuffer" ); + VCL_GL_INFO( "after assign pFramebuffer" ); } return true; commit adccc35fb6a3fb8f2644560de750e782c20d7748 Author: Michael Meeks <michael.me...@collabora.com> Date: Mon Nov 16 18:18:36 2015 +0000 Get Double-buffered context creation working on linux. Change-Id: I3db1d6792fcd51577f047b82029124ec825ea319 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index cd5c1a8..bf7ab78 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -166,6 +166,7 @@ void OpenGLSalGraphicsImpl::DeInit() // get a shiny new context in AcquireContext:: next PreDraw. if( mpContext.is() && !IsOffscreen() ) mpContext->reset(); + mpContext.clear(); } void OpenGLSalGraphicsImpl::PreDraw() @@ -1967,7 +1968,6 @@ void OpenGLSalGraphicsImpl::flushAndSwap() glViewport( 0, 0, GetWidth(), GetHeight() ); CHECK_GL_ERROR(); - glDrawBuffer(GL_BACK); glClearColor((float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, 1.0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); @@ -1979,50 +1979,54 @@ void OpenGLSalGraphicsImpl::flushAndSwap() OpenGLProgram *pProgram = mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" ); - pProgram->Use(); // FIXME: paranoia ... - VCL_GL_INFO( "vcl.opengl", "done paranoid re-use." ); - pProgram->SetTexture( "sampler", maOffscreenTex ); - maOffscreenTex.Bind(); // FIXME: paranoia ... + if( !pProgram ) + VCL_GL_INFO( "vcl.opengl", "Can't compile simple copying shader !" ); + else + { + pProgram->Use(); // FIXME: paranoia ... + VCL_GL_INFO( "vcl.opengl", "done paranoid re-use." ); + pProgram->SetTexture( "sampler", maOffscreenTex ); + maOffscreenTex.Bind(); // FIXME: paranoia ... - VCL_GL_INFO( "vcl.opengl", "bound bits etc." ); + VCL_GL_INFO( "vcl.opengl", "bound bits etc." ); - GLfloat aTexCoord[8]; - maOffscreenTex.GetCoord( aTexCoord, aPosAry, false ); - pProgram->SetTextureCoord( aTexCoord ); + GLfloat aTexCoord[8]; + maOffscreenTex.GetCoord( aTexCoord, aPosAry, false ); + pProgram->SetTextureCoord( aTexCoord ); - long nX1( aPosAry.mnDestX ); - long nY1( aPosAry.mnDestY ); - long nX2( nX1 + aPosAry.mnDestWidth ); - long nY2( nY1 + aPosAry.mnDestHeight ); - const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 }, - { nX2, nY1 }, { nX2, nY2 }}; + long nX1( aPosAry.mnDestX ); + long nY1( aPosAry.mnDestY ); + long nX2( nX1 + aPosAry.mnDestWidth ); + long nY2( nY1 + aPosAry.mnDestHeight ); + const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 }, + { nX2, nY1 }, { nX2, nY2 }}; - sal_uInt32 nPoints = 4; - std::vector<GLfloat> aVertices(nPoints * 2); - sal_uInt32 i, j; + sal_uInt32 nPoints = 4; + std::vector<GLfloat> aVertices(nPoints * 2); + sal_uInt32 i, j; - for( i = 0, j = 0; i < nPoints; i++, j += 2 ) - { - aVertices[j] = GLfloat(aPoints[i].mnX); - aVertices[j+1] = GLfloat(aPoints[i].mnY); - } + for( i = 0, j = 0; i < nPoints; i++, j += 2 ) + { + aVertices[j] = GLfloat(aPoints[i].mnX); + aVertices[j+1] = GLfloat(aPoints[i].mnY); + } - pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0); - pProgram->SetVertices( &aVertices[0] ); - if (!getenv("NO_COPY")) - glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); + pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0); + pProgram->SetVertices( &aVertices[0] ); + if (!getenv("NO_COPY")) + glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); - pProgram->Clean(); + pProgram->Clean(); - glBindTexture( GL_TEXTURE_2D, 0 ); + glBindTexture( GL_TEXTURE_2D, 0 ); - if (!getenv("NO_SWAP")) - { - mpWindowContext->swapBuffers(); - if (!getenv("NO_SLEEP")) - usleep(500 * 1000); + if (!getenv("NO_SWAP")) + { + mpWindowContext->swapBuffers(); + if (!getenv("NO_SLEEP")) + usleep(500 * 1000); + } } - VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." ); } diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index c3c505f..5cb1aea 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -700,9 +700,7 @@ bool GLWindow::HasGLXExtension( const char* name ) const bool OpenGLContext::ImplInit() { if (!m_aGLWin.dpy) - { return false; - } OpenGLZone aZone; @@ -716,11 +714,10 @@ bool OpenGLContext::ImplInit() if (!g_vShareList.empty()) pSharedCtx = g_vShareList.front(); -#ifdef DBG_UTIL if (glXCreateContextAttribsARB && !mbRequestLegacyContext) { int best_fbc = -1; - GLXFBConfig* pFBC = getFBConfig(m_aGLWin.dpy, m_aGLWin.win, best_fbc, mbUseDoubleBufferedRendering, true); + GLXFBConfig* pFBC = getFBConfig(m_aGLWin.dpy, m_aGLWin.win, best_fbc, mbUseDoubleBufferedRendering, false); if (!pFBC) return false; @@ -728,24 +725,28 @@ bool OpenGLContext::ImplInit() { int pContextAttribs[] = { +#if 0 // defined(DBG_UTIL) GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, +#endif None + }; m_aGLWin.ctx = glXCreateContextAttribsARB(m_aGLWin.dpy, pFBC[best_fbc], pSharedCtx, /* direct, not via X */ GL_TRUE, pContextAttribs); SAL_INFO_IF(m_aGLWin.ctx, "vcl.opengl", "created a 3.2 core context"); } else SAL_WARN("vcl.opengl", "unable to find correct FBC"); - } -#endif if (!m_aGLWin.ctx) { if (!m_aGLWin.vi) return false; + SAL_WARN("vcl.opengl", "attempting to create a non-double-buffered " + "visual matching the context"); + m_aGLWin.ctx = glXCreateContext(m_aGLWin.dpy, m_aGLWin.vi, pSharedCtx, commit d4b35c09d8ac20c19046142485b3507b845dbd62 Author: Michael Meeks <michael.me...@collabora.com> Date: Mon Nov 16 13:42:28 2015 +0000 Try to de-bong horrors around vdev creation. This used to create multiple GL Contexts' for the same drawable [!] And then release them again, etc. a flicker frenzy for vdevs. Change-Id: Ia2d79fea3db6ded75e278b8dda80da7d91186c8e diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index f95b98f..cd5c1a8 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -121,6 +121,11 @@ bool OpenGLSalGraphicsImpl::ReleaseContext() void OpenGLSalGraphicsImpl::Init() { + // Our init phase is strange ::Init is called twice for vdevs. + // the first time around with a NULL geometry provider. + if( !mpProvider ) + return; + // check if we can simply re-use the same context if( mpContext.is() ) { @@ -142,11 +147,12 @@ void OpenGLSalGraphicsImpl::Init() VCL_GL_INFO("vcl.opengl", "::Init - re-size offscreen texture"); } - if( mpWindowContext.is() ) - mpWindowContext->reset(); - if( !IsOffscreen() ) + { + if( mpWindowContext.is() ) + mpWindowContext->reset(); mpWindowContext = CreateWinContext(); + } } // Currently only used to get windows ordering right. @@ -208,6 +214,11 @@ void OpenGLSalGraphicsImpl::PostDraw() assert (maOffscreenTex); + if( IsOffscreen() ) + assert( !mpWindowContext.is() ); + else + assert( mpWindowContext.is() ); + if( mpContext->mnPainting == 0 ) { if (!IsOffscreen()) diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index abcf635..1241439 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -156,6 +156,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen ) // TODO: moggi: FIXME nTextPixel_ = GetPixel( nTextColor_ ); } +// Initialize the SalGraphics, if @pFrame is NULL - this is a vdev. void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, SalX11Screen nXScreen ) { @@ -165,8 +166,8 @@ void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, m_pFrame = pFrame; m_pVDev = nullptr; - bWindow_ = true; - bVirDev_ = false; + bWindow_ = pFrame; + bVirDev_ = !pFrame; SetDrawable( aTarget, nXScreen ); mxImpl->Init(); diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx index f7da84f..404f6eb 100644 --- a/vcl/unx/gtk/gtkinst.cxx +++ b/vcl/unx/gtk/gtkinst.cxx @@ -328,7 +328,7 @@ SalVirtualDevice* GtkInstance::CreateVirtualDevice( SalGraphics *pG, GtkSalGraphics *pGtkSalGraphics = dynamic_cast<GtkSalGraphics*>(pG); assert(pGtkSalGraphics); return CreateX11VirtualDevice(pG, nDX, nDY, eFormat, pGd, - new GtkSalGraphics(pGtkSalGraphics->GetGtkFrame(), pGtkSalGraphics->GetGtkWidget())); + new GtkSalGraphics(NULL, pGtkSalGraphics->GetGtkWidget())); #endif } commit 764fc9df049979c32638db53c6f097a21996fa2a Author: Michael Meeks <michael.me...@collabora.com> Date: Mon Nov 16 12:21:47 2015 +0000 More debugging work; potentially multiple contexts created for same window. Change-Id: Ibb785f87122980bbc259590c193bbf01e64a285b diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 6d745c1..f95b98f 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -144,7 +144,9 @@ void OpenGLSalGraphicsImpl::Init() if( mpWindowContext.is() ) mpWindowContext->reset(); - mpWindowContext = CreateWinContext(); + + if( !IsOffscreen() ) + mpWindowContext = CreateWinContext(); } // Currently only used to get windows ordering right. @@ -204,6 +206,8 @@ void OpenGLSalGraphicsImpl::PostDraw() #endif } + assert (maOffscreenTex); + if( mpContext->mnPainting == 0 ) { if (!IsOffscreen()) @@ -392,8 +396,22 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() VCL_GL_INFO( "vcl.opengl", "Check Offscreen texture" ); + // Always create the offscreen texture + if( maOffscreenTex ) + { + if( maOffscreenTex.GetWidth() != GetWidth() || + maOffscreenTex.GetHeight() != GetHeight() ) + { + mpContext->ReleaseFramebuffer( maOffscreenTex ); + maOffscreenTex = OpenGLTexture(); + VCL_GL_INFO( "vcl.opengl", "re-size offscreen texture" ); + } + } + if( !maOffscreenTex ) { + VCL_GL_INFO( "vcl.opengl", "create texture of size " + << GetWidth() << " x " << GetHeight() ); maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() ); bClearTexture = true; } @@ -418,8 +436,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() if( bClearTexture ) { glDrawBuffer( GL_COLOR_ATTACHMENT0 ); - GLuint clearColor[4] = { 0, 0, 0, 0 }; - glClearBufferuiv( GL_COLOR, 0, clearColor ); + GLfloat clearColor[4] = { 1.0, 0, 0, 0 }; + glClearBufferfv( GL_COLOR, 0, clearColor ); // FIXME: use glClearTexImage if we have it ? } } @@ -1905,6 +1923,7 @@ OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() void OpenGLSalGraphicsImpl::flushAndSwap() { assert( !IsOffscreen() ); + assert( mpWindowContext.is() ); assert( mpContext.is() ); if( !maOffscreenTex ) @@ -1917,7 +1936,6 @@ void OpenGLSalGraphicsImpl::flushAndSwap() VCL_GL_INFO( "vcl.opengl", "flushAndSwap" ); - glFlush(); // Interesting ! -> this destroys a context [ somehow ] ... mpWindowContext->makeCurrent(); CHECK_GL_ERROR(); @@ -1938,6 +1956,7 @@ void OpenGLSalGraphicsImpl::flushAndSwap() glViewport( 0, 0, GetWidth(), GetHeight() ); CHECK_GL_ERROR(); + glDrawBuffer(GL_BACK); glClearColor((float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, 1.0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); @@ -1945,6 +1964,7 @@ void OpenGLSalGraphicsImpl::flushAndSwap() SalTwoRect aPosAry( 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(), 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight() ); + VCL_GL_INFO( "vcl.opengl", "Texture height " << maOffscreenTex.GetHeight() << " vs. window height " << GetHeight() ); OpenGLProgram *pProgram = mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" ); @@ -1987,16 +2007,11 @@ void OpenGLSalGraphicsImpl::flushAndSwap() if (!getenv("NO_SWAP")) { - glFlush(); mpWindowContext->swapBuffers(); - glFlush(); if (!getenv("NO_SLEEP")) - usleep(500000); + usleep(500 * 1000); } - // Should get a more sensible context (this one) next time. - mpContext.clear(); - VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." ); } commit cdd413b987a6b7388d73cab18b27a429c5c61603 Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Nov 13 22:57:43 2015 +0000 More horrific debugging experience ... Change-Id: Iaf703f5297e20de24ca748571bb12b708b5a252a diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 3d1c50c..6d745c1 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -139,6 +139,7 @@ void OpenGLSalGraphicsImpl::Init() mpContext->ReleaseFramebuffer( maOffscreenTex ); } maOffscreenTex = OpenGLTexture(); + VCL_GL_INFO("vcl.opengl", "::Init - re-size offscreen texture"); } if( mpWindowContext.is() ) @@ -222,6 +223,7 @@ void OpenGLSalGraphicsImpl::freeResources() // TODO Delete shaders, programs and textures if not shared if( mpContext.is() && mpContext->isInitialized() ) { + VCL_GL_INFO( "vcl.opengl", "freeResources" ); mpContext->makeCurrent(); mpContext->ReleaseFramebuffer( maOffscreenTex ); } @@ -388,6 +390,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() { bool bClearTexture = false; + VCL_GL_INFO( "vcl.opengl", "Check Offscreen texture" ); + if( !maOffscreenTex ) { maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() ); @@ -409,6 +413,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() else { mpFramebuffer = mpContext->AcquireFramebuffer( maOffscreenTex ); + CHECK_GL_ERROR(); + if( bClearTexture ) { glDrawBuffer( GL_COLOR_ATTACHMENT0 ); @@ -418,6 +424,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() } } + assert( maOffscreenTex ); + CHECK_GL_ERROR(); return true; } @@ -1899,22 +1907,32 @@ void OpenGLSalGraphicsImpl::flushAndSwap() assert( !IsOffscreen() ); assert( mpContext.is() ); + if( !maOffscreenTex ) + { + VCL_GL_INFO( "vcl.opengl", "flushAndSwap - odd no texture !" ); + return; + } + OpenGLZone aZone; VCL_GL_INFO( "vcl.opengl", "flushAndSwap" ); - glBindTexture( GL_TEXTURE_2D, 0 ); - glFlush(); + // Interesting ! -> this destroys a context [ somehow ] ... mpWindowContext->makeCurrent(); CHECK_GL_ERROR(); + VCL_GL_INFO( "vcl.opengl", "flushAndSwap - acquire default frame buffer" ); + mpWindowContext->AcquireDefaultFramebuffer(); + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); // FIXME: paranoid double check. CHECK_GL_ERROR(); - glDisable( GL_SCISSOR_TEST ); + VCL_GL_INFO( "vcl.opengl", "flushAndSwap - acquired default frame buffer" ); + + glDisable( GL_SCISSOR_TEST ); // FIXME: paranoia ... CHECK_GL_ERROR(); - glDisable( GL_STENCIL_TEST ); + glDisable( GL_STENCIL_TEST ); // FIXME: paranoia ... CHECK_GL_ERROR(); glViewport( 0, 0, GetWidth(), GetHeight() ); @@ -1930,8 +1948,12 @@ void OpenGLSalGraphicsImpl::flushAndSwap() OpenGLProgram *pProgram = mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" ); - + pProgram->Use(); // FIXME: paranoia ... + VCL_GL_INFO( "vcl.opengl", "done paranoid re-use." ); pProgram->SetTexture( "sampler", maOffscreenTex ); + maOffscreenTex.Bind(); // FIXME: paranoia ... + + VCL_GL_INFO( "vcl.opengl", "bound bits etc." ); GLfloat aTexCoord[8]; maOffscreenTex.GetCoord( aTexCoord, aPosAry, false ); @@ -1961,6 +1983,8 @@ void OpenGLSalGraphicsImpl::flushAndSwap() pProgram->Clean(); + glBindTexture( GL_TEXTURE_2D, 0 ); + if (!getenv("NO_SWAP")) { glFlush(); @@ -1970,6 +1994,9 @@ void OpenGLSalGraphicsImpl::flushAndSwap() usleep(500000); } + // Should get a more sensible context (this one) next time. + mpContext.clear(); + VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." ); } diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx index 2d4cb40..b540e96 100644 --- a/vcl/opengl/texture.cxx +++ b/vcl/opengl/texture.cxx @@ -349,6 +349,10 @@ void OpenGLTexture::Bind() glBindTexture( GL_TEXTURE_2D, mpImpl->mnTexture ); CHECK_GL_ERROR(); } + else + VCL_GL_INFO( "OpenGLTexture::Binding invalid texture" ); + + CHECK_GL_ERROR(); } void OpenGLTexture::Unbind() diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index c3ad82c51..c3c505f 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -1371,6 +1371,8 @@ void OpenGLContext::prepareForYield() { ImplSVData* pSVData = ImplGetSVData(); + VCL_GL_INFO("vcl.opengl", "clearCurrent - detachframebuffers"); + // release all framebuffers from the old context so we can re-attach the // texture in the new context rtl::Reference<OpenGLContext> pCurrentCtx = pSVData->maGDIData.mpLastContext; @@ -1537,7 +1539,10 @@ bool OpenGLContext::BindFramebuffer( OpenGLFramebuffer* pFramebuffer ) pFramebuffer->Bind(); else OpenGLFramebuffer::Unbind(); + + VCL_GL_INFO( "vcl.opengl", "before assign pFramebuffer" ); mpCurrentFramebuffer = pFramebuffer; + VCL_GL_INFO( "vcl.opengl", "after assign pFramebuffer" ); } return true; commit c70f629be25702808cda62c712ffd5b7bf9995c9 Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Nov 13 21:25:44 2015 +0000 More tweakables ... no joy. Change-Id: I994023668a9251809ec10520829a3df5e6e3a819 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 8fcb3d6..3d1c50c 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -1889,6 +1889,8 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() { AcquireContext(); + if( mpContext.is() ) + mpContext->mnPainting++; return mpContext.get(); } @@ -1954,15 +1956,18 @@ void OpenGLSalGraphicsImpl::flushAndSwap() pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0); pProgram->SetVertices( &aVertices[0] ); - glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); + if (!getenv("NO_COPY")) + glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); pProgram->Clean(); if (!getenv("NO_SWAP")) { + glFlush(); mpWindowContext->swapBuffers(); glFlush(); - usleep(500000); + if (!getenv("NO_SLEEP")) + usleep(500000); } VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." ); @@ -1973,9 +1978,12 @@ void OpenGLSalGraphicsImpl::endPaint() assert( !IsOffscreen() ); AcquireContext(); - if( mpContext.is() && - mpContext->mnPainting == 0 ) - flushAndSwap(); + if( mpContext.is() ) + { + mpContext->mnPainting--; + if( mpContext->mnPainting == 0 ) + flushAndSwap(); + } } bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext) diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index 768e725..3538572 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -1105,10 +1105,17 @@ public: { mnStartTime = getTimeNow(); for (int i = 0; i < r->getTestRepeatCount(); i++) + { + OutputDevice::PaintScope aScope(&rDev); r->RenderRegion(rDev, aWholeWin, aCtx); + } addTime(mnSelectedRenderer, getTimeNow() - mnStartTime); - } else + } + else + { + OutputDevice::PaintScope aScope(&rDev); r->RenderRegion(rDev, aWholeWin, aCtx); + } } else { @@ -1128,11 +1135,20 @@ public: { mnStartTime = getTimeNow(); for (int j = 0; j < r->getTestRepeatCount() * THUMB_REPEAT_FACTOR; j++) + { + OutputDevice::PaintScope aScope(&rDev); r->RenderRegion(rDev, aRegions[i], aCtx); + } addTime(i, (getTimeNow() - mnStartTime) / THUMB_REPEAT_FACTOR); - } else + } + else + { for (int j = 0; j < r->getTestRepeatCount(); j++) + { + OutputDevice::PaintScope aScope(&rDev); r->RenderRegion(rDev, aRegions[i], aCtx); + } + } } else { commit 5e5eeeae5db72c774133bfca11a4f7ae88bcfd55 Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Nov 13 21:11:18 2015 +0000 STAGE <N> - starting to see something. Change-Id: Iee7261e724e7ec3f834ae246cdf94f6a46605fec diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index f1f19e1..8fcb3d6 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -37,6 +37,8 @@ #include <vector> +#include <stdlib.h> + OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryProvider *pProvider) : mpContext(nullptr) , mrParent(rParent) @@ -100,7 +102,12 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) pContext = pContext->mpPrevContext; } - mpContext = pContext ? pContext : GetDefaultContext(); + if( mpContext.is() ) + mpContext = pContext; + else if( mpWindowContext.is() ) + mpContext = mpWindowContext; + else + mpContext = GetDefaultContext(); return mpContext.is(); } @@ -199,10 +206,7 @@ void OpenGLSalGraphicsImpl::PostDraw() if( mpContext->mnPainting == 0 ) { if (!IsOffscreen()) - { - SAL_DEBUG("PostDraw flush ?"); flushAndSwap(); - } } OpenGLZone::leave(); @@ -382,8 +386,13 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ ) bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() { + bool bClearTexture = false; + if( !maOffscreenTex ) + { maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() ); + bClearTexture = true; + } if( !maOffscreenTex.IsUnique() ) { @@ -400,6 +409,13 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() else { mpFramebuffer = mpContext->AcquireFramebuffer( maOffscreenTex ); + if( bClearTexture ) + { + glDrawBuffer( GL_COLOR_ATTACHMENT0 ); + GLuint clearColor[4] = { 0, 0, 0, 0 }; + glClearBufferuiv( GL_COLOR, 0, clearColor ); + // FIXME: use glClearTexImage if we have it ? + } } CHECK_GL_ERROR(); @@ -1872,7 +1888,6 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() { - SAL_DEBUG( "want to rid ourselves of this method" ); AcquireContext(); return mpContext.get(); } @@ -1886,22 +1901,33 @@ void OpenGLSalGraphicsImpl::flushAndSwap() VCL_GL_INFO( "vcl.opengl", "flushAndSwap" ); -// glFlush(); - not needed + glBindTexture( GL_TEXTURE_2D, 0 ); + + glFlush(); mpWindowContext->makeCurrent(); CHECK_GL_ERROR(); mpWindowContext->AcquireDefaultFramebuffer(); CHECK_GL_ERROR(); + glDisable( GL_SCISSOR_TEST ); + CHECK_GL_ERROR(); + glDisable( GL_STENCIL_TEST ); + CHECK_GL_ERROR(); + glViewport( 0, 0, GetWidth(), GetHeight() ); - ImplInitClipRegion(); CHECK_GL_ERROR(); - SalTwoRect aPosAry(0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(), - 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight()); + glClearColor((float)rand()/RAND_MAX, (float)rand()/RAND_MAX, + (float)rand()/RAND_MAX, 1.0); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); + CHECK_GL_ERROR(); + + SalTwoRect aPosAry( 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(), + 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight() ); OpenGLProgram *pProgram = - mpContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" ); + mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" ); pProgram->SetTexture( "sampler", maOffscreenTex ); @@ -1932,7 +1958,14 @@ void OpenGLSalGraphicsImpl::flushAndSwap() pProgram->Clean(); - mpContext->swapBuffers(); + if (!getenv("NO_SWAP")) + { + mpWindowContext->swapBuffers(); + glFlush(); + usleep(500000); + } + + VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." ); } void OpenGLSalGraphicsImpl::endPaint() commit 61dcd416b539eb6582646e9403d2cbbb541ed0b4 Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Nov 13 15:50:39 2015 +0000 STEP #4 - paint guards & compilation. Change-Id: I57addc1d7d948f7e614526f24cf32181313bda1e diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index a146c86..2bf3f07 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -609,13 +609,9 @@ public: /** * Instantiate across a paint operation to defer flushing * to the end. - * - * NB. holding a handle avoids problems with - * the underlying SalGraphics and it's implementation - * changing. */ class PaintScope { - void *pHandle; + VclPtr<OutputDevice> mpDev; public: PaintScope(OutputDevice *); ~PaintScope(); diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 418850b..c391853 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -160,9 +160,6 @@ protected: /// retrieve the default context for offscreen rendering static rtl::Reference<OpenGLContext> GetDefaultContext(); - /// flush contents of the back-buffer to the screen & swap. - void FlushAndSwap(); - /// create a new context for rendering to the underlying window virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0; @@ -350,6 +347,9 @@ public: virtual OpenGLContext *beginPaint() override; virtual void endPaint() override; + + /// flush contents of the back-buffer to the screen & swap. + void flushAndSwap(); private: }; diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index 1bef26b..1a1c3ef 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -213,7 +213,7 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0; virtual OpenGLContext *beginPaint() { return nullptr; } - virtual OpenGLContext *endPaint() { } + virtual void endPaint() { } }; #endif diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index 04da6ed..ea7da0b 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -264,6 +264,7 @@ public: virtual SystemFontData GetSysFontData( int nFallbackLevel ) const override; virtual OpenGLContext *BeginPaint() override; + virtual void EndPaint() override; bool TryRenderCachedNativeControl(ControlCacheKey& aControlCacheKey, int nX, int nY); diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 4ff01fa..25a416b 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -437,6 +437,7 @@ public: virtual SystemGraphicsData GetGraphicsData() const override; virtual OpenGLContext *BeginPaint() override; + virtual void EndPaint() override; /// Update settings based on the platform values static void updateSettingsNative( AllSettings& rSettings ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index b1ee0ce..f1f19e1 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -135,7 +135,7 @@ void OpenGLSalGraphicsImpl::Init() } if( mpWindowContext.is() ) - mpWindowContext.reset(); + mpWindowContext->reset(); mpWindowContext = CreateWinContext(); } @@ -201,7 +201,7 @@ void OpenGLSalGraphicsImpl::PostDraw() if (!IsOffscreen()) { SAL_DEBUG("PostDraw flush ?"); - FlushAndSwap(); + flushAndSwap(); } } @@ -1877,13 +1877,15 @@ OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() return mpContext.get(); } -void OpenGLSalGraphicsImpl::FlushAndSwap() +void OpenGLSalGraphicsImpl::flushAndSwap() { assert( !IsOffscreen() ); assert( mpContext.is() ); OpenGLZone aZone; + VCL_GL_INFO( "vcl.opengl", "flushAndSwap" ); + // glFlush(); - not needed mpWindowContext->makeCurrent(); CHECK_GL_ERROR(); @@ -1904,20 +1906,21 @@ void OpenGLSalGraphicsImpl::FlushAndSwap() pProgram->SetTexture( "sampler", maOffscreenTex ); GLfloat aTexCoord[8]; - maOffscreenTex.GetCoord( aTexCoord, rPosAry, false ); + maOffscreenTex.GetCoord( aTexCoord, aPosAry, false ); pProgram->SetTextureCoord( aTexCoord ); - long nX1( rPosAry.mnDestX ); - long nY1( rPosAry.mnDestY ); - long nX2( nX1 + rPosAry.mnDestWidth ); - long nY2( nY1 + rPosAry.mnDestHeight ); + long nX1( aPosAry.mnDestX ); + long nY1( aPosAry.mnDestY ); + long nX2( nX1 + aPosAry.mnDestWidth ); + long nY2( nY1 + aPosAry.mnDestHeight ); const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 }, { nX2, nY1 }, { nX2, nY2 }}; + sal_uInt32 nPoints = 4; std::vector<GLfloat> aVertices(nPoints * 2); sal_uInt32 i, j; - for( i = 0, j = 0; i < 4; i++, j += 2 ) + for( i = 0, j = 0; i < nPoints; i++, j += 2 ) { aVertices[j] = GLfloat(aPoints[i].mnX); aVertices[j+1] = GLfloat(aPoints[i].mnY); @@ -1939,7 +1942,7 @@ void OpenGLSalGraphicsImpl::endPaint() AcquireContext(); if( mpContext.is() && mpContext->mnPainting == 0 ) - FlushAndSwap(); + flushAndSwap(); } bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext) diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index 10875ca..5a7fa28 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -1083,55 +1083,4 @@ GLXFBConfig OpenGLHelper::GetPixmapFBConfig( Display* pDisplay, bool& bInverted #endif -OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) - : pHandle( nullptr ) -{ - if( pDev->mpGraphics || pDev->AcquireGraphics() ) - { - OpenGLContext *pContext = pDev->mpGraphics->BeginPaint(); -/* - if( pContext ) - { - assert( pContext->mnPainting >= 0 ); - pContext->mnPainting++; - pContext->acquire(); - pHandle = static_cast<void *>( pContext ); - } -*/ - } -} - -/** - * Flush all the queued rendering commands to the screen for this context. - */ -void OutputDevice::PaintScope::flush() -{ - if( pDev->mpGraphics || pDev->AcquireGraphics() ) - pDev->mpGraphics->EndPaint(); - -#if 0 - if( pHandle ) - { - OpenGLContext *pContext = static_cast<OpenGLContext *>( pHandle ); - pHandle = nullptr; - pContext->mnPainting--; - assert( pContext->mnPainting >= 0 ); - if( pContext->mnPainting == 0 ) - { - pContext->makeCurrent(); - pContext->AcquireDefaultFramebuffer(); - glFlush(); - pContext->swapBuffers(); - CHECK_GL_ERROR(); - } - pContext->release(); - } -#endif -} - -OutputDevice::PaintScope::~PaintScope() -{ - flush(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx index b343f50..1779002 100644 --- a/vcl/source/outdev/outdev.cxx +++ b/vcl/source/outdev/outdev.cxx @@ -845,4 +845,26 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, return bDrawn; } +OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) + : mpDev( pDev ) +{ + SalGraphics *mpGraphics = mpDev->GetGraphics(); + if (mpGraphics) + mpGraphics->BeginPaint(); +} + +OutputDevice::PaintScope::~PaintScope() +{ + flush(); +} + +/// Flush all the queued rendering commands to the screen for this context. +void OutputDevice::PaintScope::flush() +{ + SalGraphics *mpGraphics = mpDev->GetGraphics(); + if (mpGraphics) + mpGraphics->EndPaint(); +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index 738d59b..abcf635 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -561,6 +561,11 @@ OpenGLContext *X11SalGraphics::BeginPaint() return mxImpl->beginPaint(); } +void X11SalGraphics::EndPaint() +{ + return mxImpl->endPaint(); +} + SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const { if (m_pFrame) diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index 366b81c..1462f25 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -1051,4 +1051,9 @@ OpenGLContext *WinSalGraphics::BeginPaint() return mpImpl->beginPaint(); } +void WinSalGraphics::EndPaint() +{ + return mpImpl->endPaint(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit e61d5564fcce97bdbb6dba898135926761a7a10a Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Nov 13 14:31:09 2015 +0000 Stage #3 - first cut at flushing the whole buffer across ... diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 7ac3496..418850b 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -160,6 +160,9 @@ protected: /// retrieve the default context for offscreen rendering static rtl::Reference<OpenGLContext> GetDefaultContext(); + /// flush contents of the back-buffer to the screen & swap. + void FlushAndSwap(); + /// create a new context for rendering to the underlying window virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0; @@ -346,6 +349,7 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override; virtual OpenGLContext *beginPaint() override; + virtual void endPaint() override; private: }; diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 98c3b8f..62f714f 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -439,6 +439,7 @@ public: const OutputDevice *pOutDev ); virtual OpenGLContext *BeginPaint() { return nullptr; } + virtual void EndPaint() { } virtual SystemGraphicsData GetGraphicsData() const = 0; diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index 3324012..1bef26b 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -213,6 +213,7 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0; virtual OpenGLContext *beginPaint() { return nullptr; } + virtual OpenGLContext *endPaint() { } }; #endif diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 25cb53a..b1ee0ce 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -133,6 +133,10 @@ void OpenGLSalGraphicsImpl::Init() } maOffscreenTex = OpenGLTexture(); } + + if( mpWindowContext.is() ) + mpWindowContext.reset(); + mpWindowContext = CreateWinContext(); } // Currently only used to get windows ordering right. @@ -173,19 +177,13 @@ void OpenGLSalGraphicsImpl::PreDraw() void OpenGLSalGraphicsImpl::PostDraw() { - if( mpContext->mnPainting == 0 ) - { - if (!IsOffscreen()) ... -#warning "Trigger re-rendering of the window if we have one" - glFlush(); - } if( mbUseScissor ) { glDisable( GL_SCISSOR_TEST ); CHECK_GL_ERROR(); } - if( mbUseStencil ) - { + if( mbUseStencil ) + { glDisable( GL_STENCIL_TEST ); CHECK_GL_ERROR(); } @@ -197,6 +195,16 @@ void OpenGLSalGraphicsImpl::PostDraw() mProgramIsSolidColor = false; #endif } + + if( mpContext->mnPainting == 0 ) + { + if (!IsOffscreen()) + { + SAL_DEBUG("PostDraw flush ?"); + FlushAndSwap(); + } + } + OpenGLZone::leave(); } @@ -1864,10 +1872,76 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() { + SAL_DEBUG( "want to rid ourselves of this method" ); AcquireContext(); return mpContext.get(); } +void OpenGLSalGraphicsImpl::FlushAndSwap() +{ + assert( !IsOffscreen() ); + assert( mpContext.is() ); + + OpenGLZone aZone; + +// glFlush(); - not needed + mpWindowContext->makeCurrent(); + CHECK_GL_ERROR(); + + mpWindowContext->AcquireDefaultFramebuffer(); + CHECK_GL_ERROR(); + + glViewport( 0, 0, GetWidth(), GetHeight() ); + ImplInitClipRegion(); + CHECK_GL_ERROR(); + + SalTwoRect aPosAry(0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(), + 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight()); + + OpenGLProgram *pProgram = + mpContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" ); + + pProgram->SetTexture( "sampler", maOffscreenTex ); + + GLfloat aTexCoord[8]; + maOffscreenTex.GetCoord( aTexCoord, rPosAry, false ); + pProgram->SetTextureCoord( aTexCoord ); + + long nX1( rPosAry.mnDestX ); + long nY1( rPosAry.mnDestY ); + long nX2( nX1 + rPosAry.mnDestWidth ); + long nY2( nY1 + rPosAry.mnDestHeight ); + const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 }, + { nX2, nY1 }, { nX2, nY2 }}; + + std::vector<GLfloat> aVertices(nPoints * 2); + sal_uInt32 i, j; + + for( i = 0, j = 0; i < 4; i++, j += 2 ) + { + aVertices[j] = GLfloat(aPoints[i].mnX); + aVertices[j+1] = GLfloat(aPoints[i].mnY); + } + + pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0); + pProgram->SetVertices( &aVertices[0] ); + glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); + + pProgram->Clean(); + + mpContext->swapBuffers(); +} + +void OpenGLSalGraphicsImpl::endPaint() +{ + assert( !IsOffscreen() ); + + AcquireContext(); + if( mpContext.is() && + mpContext->mnPainting == 0 ) + FlushAndSwap(); +} + bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext) { // so far a blunt heuristic: vcl uses shiny new contexts. diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index c7cbfa3..10875ca 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -1089,6 +1089,7 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) if( pDev->mpGraphics || pDev->AcquireGraphics() ) { OpenGLContext *pContext = pDev->mpGraphics->BeginPaint(); +/* if( pContext ) { assert( pContext->mnPainting >= 0 ); @@ -1096,6 +1097,7 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) pContext->acquire(); pHandle = static_cast<void *>( pContext ); } +*/ } } @@ -1104,6 +1106,10 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) */ void OutputDevice::PaintScope::flush() { + if( pDev->mpGraphics || pDev->AcquireGraphics() ) + pDev->mpGraphics->EndPaint(); + +#if 0 if( pHandle ) { OpenGLContext *pContext = static_cast<OpenGLContext *>( pHandle ); @@ -1120,6 +1126,7 @@ void OutputDevice::PaintScope::flush() } pContext->release(); } +#endif } OutputDevice::PaintScope::~PaintScope() commit cfdfe8f75794b87f1ee4eb754864d256c9ae2a9f Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Nov 13 12:26:52 2015 +0000 Step #2 - kill mbOffscreen. Change-Id: Ib844155cca41cd4a75bf0273c7b32a99dfb9870e diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 9eb4353..7ac3496 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -57,7 +57,13 @@ class VCL_DLLPUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl friend class OpenGLTests; protected: + /// This context is solely for blitting @maOffscreenTex + rtl::Reference<OpenGLContext> mpWindowContext; + + /// This context is whatever is most convenient to render + /// to @maOffscreenTex with. rtl::Reference<OpenGLContext> mpContext; + SalGraphics& mrParent; /// Pointer to the SalFrame or SalVirtualDevice SalGeometryProvider* mpProvider; @@ -72,7 +78,11 @@ protected: bool mbUseScissor; bool mbUseStencil; - bool mbOffscreen; + /** + * All rendering happens to this off-screen texture. For + * non-virtual devices, ie. windows - we will blit it and + * swapBuffers later. + */ OpenGLTexture maOffscreenTex; SalColor mnLineColor; @@ -131,8 +141,10 @@ public: // get the height of the device GLfloat GetHeight() const { return mpProvider ? mpProvider->GetHeight() : 1; } - // check whether this instance is used for offscreen (Virtual Device) - // rendering ie. does it need its own context. + /** + * check whether this instance is used for offscreen (Virtual Device) + * rendering ie. does it need its own context. + */ bool IsOffscreen() const { return mpProvider == nullptr || mpProvider->IsOffScreen(); } // operations to do before painting @@ -145,10 +157,10 @@ protected: bool AcquireContext(); bool ReleaseContext(); - // retrieve the default context for offscreen rendering + /// retrieve the default context for offscreen rendering static rtl::Reference<OpenGLContext> GetDefaultContext(); - /// create a new context for window rendering + /// create a new context for rendering to the underlying window virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0; /// check whether the given context can be used for off-screen rendering diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 452d064..25cb53a 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -45,7 +45,6 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr , mpProgram(nullptr) , mbUseScissor(false) , mbUseStencil(false) - , mbOffscreen(false) , mnLineColor(SALCOLOR_NONE) , mnFillColor(SALCOLOR_NONE) #ifdef DBG_UTIL @@ -79,10 +78,9 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) // We always prefer to bind our VirtualDevice / offscreen graphics // to the current OpenGLContext - to avoid switching contexts. - if (mpContext.is() && mbOffscreen) + if (mpContext.is() && OpenGLContext::hasCurrent() && !mpContext->isCurrent()) { - if (OpenGLContext::hasCurrent() && !mpContext->isCurrent()) - mpContext.clear(); + mpContext.clear(); } if( mpContext.is() ) @@ -116,8 +114,6 @@ bool OpenGLSalGraphicsImpl::ReleaseContext() void OpenGLSalGraphicsImpl::Init() { - mbOffscreen = IsOffscreen(); - // check if we can simply re-use the same context if( mpContext.is() ) { @@ -165,10 +161,7 @@ void OpenGLSalGraphicsImpl::PreDraw() mpContext->makeCurrent(); CHECK_GL_ERROR(); - if( !mbOffscreen ) - mpContext->AcquireDefaultFramebuffer(); - else - CheckOffscreenTexture(); + CheckOffscreenTexture(); CHECK_GL_ERROR(); glViewport( 0, 0, GetWidth(), GetHeight() ); @@ -180,8 +173,12 @@ void OpenGLSalGraphicsImpl::PreDraw() void OpenGLSalGraphicsImpl::PostDraw() { - if( !mbOffscreen && mpContext->mnPainting == 0 ) + if( mpContext->mnPainting == 0 ) + { + if (!IsOffscreen()) ... +#warning "Trigger re-rendering of the window if we have one" glFlush(); + } if( mbUseScissor ) { glDisable( GL_SCISSOR_TEST ); @@ -211,7 +208,7 @@ void OpenGLSalGraphicsImpl::ApplyProgramMatrices(float fPixelOffset) void OpenGLSalGraphicsImpl::freeResources() { // TODO Delete shaders, programs and textures if not shared - if( mbOffscreen && mpContext.is() && mpContext->isInitialized() ) + if( mpContext.is() && mpContext->isInitialized() ) { mpContext->makeCurrent(); mpContext->ReleaseFramebuffer( maOffscreenTex ); @@ -1536,17 +1533,9 @@ void OpenGLSalGraphicsImpl::DoCopyBits( const SalTwoRect& rPosAry, OpenGLSalGrap return; } - if( rImpl.mbOffscreen ) - { - PreDraw(); - DrawTexture( rImpl.maOffscreenTex, rPosAry ); - PostDraw(); - return; - } - - SAL_WARN( "vcl.opengl", "*** NOT IMPLEMENTED *** copyBits" ); - // TODO: Copy from one FBO to the other (glBlitFramebuffer) - // ie. copying from one visible window to another visible window + PreDraw(); + DrawTexture( rImpl.maOffscreenTex, rPosAry ); + PostDraw(); } void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) @@ -1875,10 +1864,8 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() { - if( mbOffscreen || !AcquireContext() ) - return nullptr; - else - return mpContext.get(); + AcquireContext(); + return mpContext.get(); } bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext) commit 87279c541ee2027155bf7381413b2e2e582367ba Author: Michael Meeks <michael.me...@collabora.com> Date: Fri Nov 13 12:00:59 2015 +0000 Step #1 - de-virtualize UseContext Change-Id: If343746b6544d77fec76ee89351cd7262d1bf350 diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx index ecefede..8102d2e 100644 --- a/vcl/inc/opengl/win/gdiimpl.hxx +++ b/vcl/inc/opengl/win/gdiimpl.hxx @@ -31,7 +31,6 @@ public: protected: virtual rtl::Reference<OpenGLContext> CreateWinContext() override; - virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) override; bool RenderTextureCombo(TextureCombo& rCombo, int nX, int nY); diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx index f07468d..eccd0ef 100644 --- a/vcl/inc/opengl/x11/gdiimpl.hxx +++ b/vcl/inc/opengl/x11/gdiimpl.hxx @@ -29,7 +29,6 @@ public: protected: virtual rtl::Reference<OpenGLContext> CreateWinContext() override; - virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) override; bool RenderPixmap(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY, TextureCombo& rCombo); diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 667b2ec..9eb4353 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -131,7 +131,8 @@ public: // get the height of the device GLfloat GetHeight() const { return mpProvider ? mpProvider->GetHeight() : 1; } - // check whether this instance is used for offscreen rendering + // check whether this instance is used for offscreen (Virtual Device) + // rendering ie. does it need its own context. bool IsOffscreen() const { return mpProvider == nullptr || mpProvider->IsOffScreen(); } // operations to do before painting @@ -147,11 +148,15 @@ protected: // retrieve the default context for offscreen rendering static rtl::Reference<OpenGLContext> GetDefaultContext(); - // create a new context for window rendering + /// create a new context for window rendering virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0; - // check whether the given context can be used by this instance - virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) = 0; + /// check whether the given context can be used for off-screen rendering + bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) + { + return pContext->isInitialized() && // not released by the OS etc. + IsForeignContext( pContext ); // a genuine VCL context. + } public: OpenGLSalGraphicsImpl(SalGraphics& pParent, SalGeometryProvider *pProvider); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 3771d3c..452d064 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -97,15 +97,12 @@ bool OpenGLSalGraphicsImpl::AcquireContext( ) while( pContext ) { // check if this context can be used by this SalGraphicsImpl instance - if( UseContext( pContext ) ) + if( UseContext( pContext ) ) break; pContext = pContext->mpPrevContext; } - if( pContext ) - mpContext = pContext; - else - mpContext = mbOffscreen ? GetDefaultContext() : CreateWinContext(); + mpContext = pContext ? pContext : GetDefaultContext(); return mpContext.is(); } @@ -124,14 +121,12 @@ void OpenGLSalGraphicsImpl::Init() // check if we can simply re-use the same context if( mpContext.is() ) { - if( !mpContext->isInitialized() || - !UseContext( mpContext ) ) + if( !UseContext( mpContext ) ) ReleaseContext(); } - // reset the offscreen texture - if( !mbOffscreen || - maOffscreenTex.GetWidth() != GetWidth() || + // Always create the offscreen texture + if( maOffscreenTex.GetWidth() != GetWidth() || maOffscreenTex.GetHeight() != GetHeight() ) { if( maOffscreenTex && // don't work to release empty textures diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx index f57c82d..666cdbf 100644 --- a/vcl/opengl/win/gdiimpl.cxx +++ b/vcl/opengl/win/gdiimpl.cxx @@ -29,21 +29,10 @@ void WinOpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* rtl::Reference<OpenGLContext> WinOpenGLSalGraphicsImpl::CreateWinContext() { rtl::Reference<OpenGLContext> pContext = OpenGLContext::Create(); - pContext->requestSingleBufferedRendering(); pContext->init( mrParent.mhLocalDC, mrParent.mhWnd ); return pContext; } -bool WinOpenGLSalGraphicsImpl::UseContext( const rtl::Reference<OpenGLContext> &pContext ) -{ - if( !pContext.is() || !pContext->isInitialized() || IsForeignContext( pContext ) ) - return false; - if( IsOffscreen() ) - return true; - return pContext->getOpenGLWindow().hWnd == mrParent.mhWnd && - pContext->getOpenGLWindow().hDC == mrParent.mhLocalDC; -} - void WinOpenGLSalGraphicsImpl::Init() { if ( !IsOffscreen() && mpContext.is() && mpContext->isInitialized() && diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx index 2418bc6..595ca45c 100644 --- a/vcl/opengl/x11/gdiimpl.cxx +++ b/vcl/opengl/x11/gdiimpl.cxx @@ -58,18 +58,6 @@ rtl::Reference<OpenGLContext> X11OpenGLSalGraphicsImpl::CreateWinContext() return pContext; } -bool X11OpenGLSalGraphicsImpl::UseContext( const rtl::Reference<OpenGLContext> &pContext ) -{ - X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame); - - if( !pContext->isInitialized() || IsForeignContext( pContext ) ) - return false; - if( !pProvider ) - return pContext->getOpenGLWindow().win != None; - else - return pContext->getOpenGLWindow().win == pProvider->GetX11Window(); -} - void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { OpenGLSalGraphicsImpl *pImpl = pSrcGraphics ? static_cast< OpenGLSalGraphicsImpl* >(pSrcGraphics->GetImpl()) : static_cast< OpenGLSalGraphicsImpl *>(mrParent.GetImpl()); diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 4a68ab8..c3ad82c51 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -124,11 +124,6 @@ void OpenGLContext::requestLegacyContext() mbRequestLegacyContext = true; } -void OpenGLContext::requestSingleBufferedRendering() -{ - mbUseDoubleBufferedRendering = false; -} - #if defined( _WIN32 ) static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { commit 2d49006f7cb04d7b3b71481f1f3aecf0f6d70dff Author: Caolán McNamara <caol...@redhat.com> Date: Mon Nov 30 12:01:07 2015 +0000 uninitialized m_pGraphics -> cppcanvas_emfplus kaboom Change-Id: I370f63ed12e187684332112b9510a9892a665129 diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx index 6da958d..c5c01a4 100644 --- a/vcl/unx/gtk/gtksalframe.cxx +++ b/vcl/unx/gtk/gtksalframe.cxx @@ -494,6 +494,7 @@ void GtkSalFrame::doKeyCallback( guint state, GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) : m_nXScreen( getDisplay()->GetDefaultXScreen() ) + , m_pGraphics(nullptr) { getDisplay()->registerFrame( this ); m_bDefaultPos = true; @@ -507,6 +508,7 @@ GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) GtkSalFrame::GtkSalFrame( SystemParentData* pSysData ) : m_nXScreen( getDisplay()->GetDefaultXScreen() ) + , m_pGraphics(nullptr) { getDisplay()->registerFrame( this ); // permanently ignore errors from our unruly children ... commit 367dc08f9a7e34fe108c289a59548716e9abdf54 Author: Tor Lillqvist <t...@collabora.com> Date: Mon Nov 30 13:52:34 2015 +0200 Use -ldl -pthread only on Linux Change-Id: I968449ac3c12011cb32bf9c29db66ad2ae4553f1 diff --git a/smoketest/Executable_libtest.mk b/smoketest/Executable_libtest.mk index 3b3bd16..4ba29ee 100644 --- a/smoketest/Executable_libtest.mk +++ b/smoketest/Executable_libtest.mk @@ -17,10 +17,12 @@ $(eval $(call gb_Executable_use_libraries,libtest,\ $(gb_UWINAPI) \ )) +ifeq ($(OS),LINUX) $(eval $(call gb_Executable_add_libs,libtest,\ -ldl \ -pthread \ )) +endif $(eval $(call gb_Executable_add_exception_objects,libtest,\ smoketest/libtest \ commit ac95a8b2e9e68111a24aa20c04eb18fba4a5c6e9 Author: Stephan Bergmann <sberg...@redhat.com> Date: Mon Nov 30 12:30:35 2015 +0100 Move uses of SwFrame pointer-to-member after definition of class SwFrame ...to avoid trouble with MSVC's pointer-to-member model, where the details of a pointer-to-member depend on details of the pointed-to class type. Change-Id: Id5b3be1696794d23fbad96f047d114e27395b134 diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 12bc2c6..e942315 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -94,98 +94,6 @@ typedef struct _xmlTextWriter *xmlTextWriterPtr; #define FRM_HEADFOOT 0x0018 #define FRM_BODYFTNC 0x00a0 -class SwFrame; -typedef long (SwFrame:: *SwFrameGet)() const; -typedef bool (SwFrame:: *SwFrameMax)( long ); -typedef void (SwFrame:: *SwFrameMakePos)( const SwFrame*, const SwFrame*, bool ); -typedef long (*SwOperator)( long, long ); -typedef void (SwFrame:: *SwFrameSet)( long, long ); - -struct SwRectFnCollection -{ - SwRectGet fnGetTop; - SwRectGet fnGetBottom; - SwRectGet fnGetLeft; - SwRectGet fnGetRight; - SwRectGet fnGetWidth; - SwRectGet fnGetHeight; - SwRectPoint fnGetPos; - - SwRectSet fnSetTop; - SwRectSet fnSetBottom; - SwRectSet fnSetLeft; - SwRectSet fnSetRight; - SwRectSet fnSetWidth; - SwRectSet fnSetHeight; - - SwRectSet fnSubTop; - SwRectSet fnAddBottom; - SwRectSet fnSubLeft; - SwRectSet fnAddRight; - SwRectSet fnAddWidth; - SwRectSet fnAddHeight; - - SwRectSet fnSetPosX; - SwRectSet fnSetPosY; - - SwFrameGet fnGetTopMargin; - SwFrameGet fnGetBottomMargin; - SwFrameGet fnGetLeftMargin; - SwFrameGet fnGetRightMargin; - SwFrameSet fnSetXMargins; - SwFrameSet fnSetYMargins; - SwFrameGet fnGetPrtTop; - SwFrameGet fnGetPrtBottom; - SwFrameGet fnGetPrtLeft; - SwFrameGet fnGetPrtRight; - SwRectDist fnTopDist; - SwRectDist fnBottomDist; - SwFrameMax fnSetLimit; - SwRectMax fnOverStep; - - SwRectSetPos fnSetPos; - SwFrameMakePos fnMakePos; - SwOperator fnXDiff; - SwOperator fnYDiff; - SwOperator fnYInc; - - SwRectSetTwice fnSetLeftAndWidth; - SwRectSetTwice fnSetTopAndHeight; -}; - -typedef SwRectFnCollection* SwRectFn; - -extern SwRectFn fnRectHori, fnRectVert, fnRectB2T, fnRectVL2R, fnRectVertL2R; -#define SWRECTFN( pFrame ) bool bVert = pFrame->IsVertical(); \ - bool bRev = pFrame->IsReverse(); \ - bool bVertL2R = pFrame->IsVertLR(); \ - SwRectFn fnRect = bVert ? \ - ( bRev ? fnRectVL2R : ( bVertL2R ? fnRectVertL2R : fnRectVert ) ): \ - ( bRev ? fnRectB2T : fnRectHori ); -#define SWRECTFNX( pFrame ) bool bVertX = pFrame->IsVertical(); \ - bool bRevX = pFrame->IsReverse(); \ - bool bVertL2RX = pFrame->IsVertLR(); \ - SwRectFn fnRectX = bVertX ? \ - ( bRevX ? fnRectVL2R : ( bVertL2RX ? fnRectVertL2R : fnRectVert ) ): \ - ( bRevX ? fnRectB2T : fnRectHori ); -#define SWREFRESHFN( pFrame ) { if( bVert != pFrame->IsVertical() || \ - bRev != pFrame->IsReverse() ) \ - bVert = pFrame->IsVertical(); \ - bRev = pFrame->IsReverse(); \ - bVertL2R = pFrame->IsVertLR(); \ - fnRect = bVert ? \ - ( bRev ? fnRectVL2R : ( bVertL2R ? fnRectVertL2R : fnRectVert ) ): \ - ( bRev ? fnRectB2T : fnRectHori ); } -#define SWRECTFN2( pFrame ) bool bVert = pFrame->IsVertical(); \ - bool bVertL2R = pFrame->IsVertLR(); \ - bool bNeighb = pFrame->IsNeighbourFrame(); \ - SwRectFn fnRect = bVert == bNeighb ? \ - fnRectHori : ( bVertL2R ? fnRectVertL2R : fnRectVert ); - -#define POS_DIFF( aFrame1, aFrame2 ) \ - ( (aFrame1.*fnRect->fnGetTop)() != (aFrame2.*fnRect->fnGetTop)() || \ - (aFrame1.*fnRect->fnGetLeft)() != (aFrame2.*fnRect->fnGetLeft)() ) - // for GetNextLeaf/GetPrevLeaf. enum MakePageType { @@ -1173,6 +1081,97 @@ public: } }; +typedef long (SwFrame:: *SwFrameGet)() const; +typedef bool (SwFrame:: *SwFrameMax)( long ); +typedef void (SwFrame:: *SwFrameMakePos)( const SwFrame*, const SwFrame*, bool ); +typedef long (*SwOperator)( long, long ); +typedef void (SwFrame:: *SwFrameSet)( long, long ); + +struct SwRectFnCollection +{ + SwRectGet fnGetTop; + SwRectGet fnGetBottom; + SwRectGet fnGetLeft; + SwRectGet fnGetRight; + SwRectGet fnGetWidth; + SwRectGet fnGetHeight; + SwRectPoint fnGetPos; + + SwRectSet fnSetTop; + SwRectSet fnSetBottom; + SwRectSet fnSetLeft; + SwRectSet fnSetRight; + SwRectSet fnSetWidth; + SwRectSet fnSetHeight; + + SwRectSet fnSubTop; + SwRectSet fnAddBottom; + SwRectSet fnSubLeft; + SwRectSet fnAddRight; + SwRectSet fnAddWidth; + SwRectSet fnAddHeight; + + SwRectSet fnSetPosX; + SwRectSet fnSetPosY; + + SwFrameGet fnGetTopMargin; + SwFrameGet fnGetBottomMargin; + SwFrameGet fnGetLeftMargin; + SwFrameGet fnGetRightMargin; + SwFrameSet fnSetXMargins; + SwFrameSet fnSetYMargins; + SwFrameGet fnGetPrtTop; + SwFrameGet fnGetPrtBottom; + SwFrameGet fnGetPrtLeft; + SwFrameGet fnGetPrtRight; + SwRectDist fnTopDist; + SwRectDist fnBottomDist; + SwFrameMax fnSetLimit; + SwRectMax fnOverStep; + + SwRectSetPos fnSetPos; + SwFrameMakePos fnMakePos; + SwOperator fnXDiff; + SwOperator fnYDiff; + SwOperator fnYInc; + + SwRectSetTwice fnSetLeftAndWidth; + SwRectSetTwice fnSetTopAndHeight; +}; + +typedef SwRectFnCollection* SwRectFn; + +extern SwRectFn fnRectHori, fnRectVert, fnRectB2T, fnRectVL2R, fnRectVertL2R; +#define SWRECTFN( pFrame ) bool bVert = pFrame->IsVertical(); \ + bool bRev = pFrame->IsReverse(); \ + bool bVertL2R = pFrame->IsVertLR(); \ + SwRectFn fnRect = bVert ? \ + ( bRev ? fnRectVL2R : ( bVertL2R ? fnRectVertL2R : fnRectVert ) ): \ + ( bRev ? fnRectB2T : fnRectHori ); +#define SWRECTFNX( pFrame ) bool bVertX = pFrame->IsVertical(); \ + bool bRevX = pFrame->IsReverse(); \ + bool bVertL2RX = pFrame->IsVertLR(); \ + SwRectFn fnRectX = bVertX ? \ + ( bRevX ? fnRectVL2R : ( bVertL2RX ? fnRectVertL2R : fnRectVert ) ): \ + ( bRevX ? fnRectB2T : fnRectHori ); +#define SWREFRESHFN( pFrame ) { if( bVert != pFrame->IsVertical() || \ + bRev != pFrame->IsReverse() ) \ + bVert = pFrame->IsVertical(); \ + bRev = pFrame->IsReverse(); \ + bVertL2R = pFrame->IsVertLR(); \ + fnRect = bVert ? \ + ( bRev ? fnRectVL2R : ( bVertL2R ? fnRectVertL2R : fnRectVert ) ): \ + ( bRev ? fnRectB2T : fnRectHori ); } +#define SWRECTFN2( pFrame ) bool bVert = pFrame->IsVertical(); \ + bool bVertL2R = pFrame->IsVertLR(); \ + bool bNeighb = pFrame->IsNeighbourFrame(); \ + SwRectFn fnRect = bVert == bNeighb ? \ + fnRectHori : ( bVertL2R ? fnRectVertL2R : fnRectVert ); + +#define POS_DIFF( aFrame1, aFrame2 ) \ + ( (aFrame1.*fnRect->fnGetTop)() != (aFrame2.*fnRect->fnGetTop)() || \ + (aFrame1.*fnRect->fnGetLeft)() != (aFrame2.*fnRect->fnGetLeft)() ) + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit ef242ae01047f6b8a0a9012e4e40509dd1c03145 Author: Michael Meeks <michael.me...@collabora.com> Date: Mon Nov 30 11:04:01 2015 +0000 vcl: move gtk+ to sharing the same SalGraphics per SalFrame. This makes the code consistent with other: Mac, Unx, Windows backends, and allows us to cache an OpenGL back-buffer on the SalGraphics - as per Mac. The lifecycle of a SalFrame and a SalGraphics should be consistent for real OS graphics now. Change-Id: I11fea2ce1c1386b1c6b0161a718e5c909c81612c Reviewed-on: https://gerrit.libreoffice.org/20283 Reviewed-by: Michael Meeks <michael.me...@collabora.com> Tested-by: Michael Meeks <michael.me...@collabora.com> diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index 472aae7..d1203a3 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -62,19 +62,6 @@ typedef ::Window GdkNativeWindow; class GtkSalFrame : public SalFrame, public X11WindowProvider { - static const int nMaxGraphics = 2; - - struct GraphicsHolder - { - GtkSalGraphics* pGraphics; - bool bInUse; - GraphicsHolder() - : pGraphics( nullptr ), - bInUse( false ) - {} - ~GraphicsHolder(); - }; - struct IMHandler { @@ -187,7 +174,8 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider std::list< GtkSalFrame* > m_aChildren; GdkWindowState m_nState; SystemEnvData m_aSystemData; - GraphicsHolder m_aGraphics[ nMaxGraphics ]; + GtkSalGraphics *m_pGraphics; + bool m_bGraphics; sal_uInt16 m_nKeyModifiers; GdkCursor *m_pCurrentCursor; GdkVisibilityState m_nVisibility; diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx index 923581d..6da958d 100644 --- a/vcl/unx/gtk/gtksalframe.cxx +++ b/vcl/unx/gtk/gtksalframe.cxx @@ -492,11 +492,6 @@ void GtkSalFrame::doKeyCallback( guint state, CallCallback( SALEVENT_KEYUP, &aEvent ); } -GtkSalFrame::GraphicsHolder::~GraphicsHolder() -{ - delete pGraphics; -} - GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) : m_nXScreen( getDisplay()->GetDefaultXScreen() ) { @@ -845,15 +840,13 @@ void GtkSalFrame::EnsureAppMenuWatch() void GtkSalFrame::InvalidateGraphics() { - for (unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); ++i) + if( m_pGraphics ) { - if( !m_aGraphics[i].pGraphics ) - continue; #if !GTK_CHECK_VERSION(3,0,0) - m_aGraphics[i].pGraphics->SetDrawable( None, m_nXScreen ); - m_aGraphics[i].pGraphics->SetWindow(nullptr); + m_pGraphics->SetDrawable( None, m_nXScreen ); + m_pGraphics->SetWindow(nullptr); #endif - m_aGraphics[i].bInUse = false; + m_bGraphics = false; } } @@ -926,6 +919,9 @@ GtkSalFrame::~GtkSalFrame() g_object_unref( G_OBJECT( m_pForeignParent ) ); if( m_pForeignTopLevel ) g_object_unref( G_OBJECT( m_pForeignTopLevel) ); + + delete m_pGraphics; + m_pGraphics = NULL; } void GtkSalFrame::moveWindow( long nX, long nY ) @@ -1172,6 +1168,9 @@ void GtkSalFrame::InitCommon() m_aSystemData.pAppContext = nullptr; m_aSystemData.pShellWidget = m_aSystemData.pWidget; + m_bGraphics = false; + m_pGraphics = NULL; + // fake an initial geometry, gets updated via configure event or SetPosSize if( m_bDefaultPos || m_bDefaultSize ) { @@ -1596,45 +1595,32 @@ void GtkSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) SalGraphics* GtkSalFrame::AcquireGraphics() { - if( m_pWindow ) + if( m_bGraphics ) + return nullptr; + + if( !m_pGraphics ) { - for( int i = 0; i < nMaxGraphics; i++ ) - { - if( ! m_aGraphics[i].bInUse ) - { - m_aGraphics[i].bInUse = true; - if( ! m_aGraphics[i].pGraphics ) - { #if GTK_CHECK_VERSION(3,0,0) - m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow ); - if( !m_aFrame.get() ) - { - AllocateFrame(); - TriggerPaintEvent(); - } - m_aGraphics[i].pGraphics->setDevice( m_aFrame ); + m_pGraphics = new GtkSalGraphics( this, m_pWindow ); + if( !m_aFrame.get() ) + { + AllocateFrame(); + TriggerPaintEvent(); + } + m_pGraphics->setDevice( m_aFrame ); #else // common case: - m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow, m_nXScreen ); + m_pGraphics = new GtkSalGraphics( this, m_pWindow, m_nXScreen ); #endif - } - return m_aGraphics[i].pGraphics; - } - } } - - return nullptr; + m_bGraphics = true; + return m_pGraphics; } void GtkSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) { - for( int i = 0; i < nMaxGraphics; i++ ) - { - if( m_aGraphics[i].pGraphics == pGraphics ) - { - m_aGraphics[i].bInUse = false; - break; - } - } + (void) pGraphics; + assert( pGraphics == m_pGraphics ); + m_bGraphics = false; } bool GtkSalFrame::PostEvent(ImplSVEvent* pData) @@ -1978,13 +1964,8 @@ void GtkSalFrame::AllocateFrame() m_aFrame->clear( basebmp::Color( 255, 127, 0 ) ); #endif - // update device in existing graphics - for( unsigned int i = 0; i < SAL_N_ELEMENTS( m_aGraphics ); ++i ) - { - if( !m_aGraphics[i].pGraphics ) - continue; - m_aGraphics[i].pGraphics->setDevice( m_aFrame ); - } + if( m_pGraphics ) + m_pGraphics->setDevice( m_aFrame ); } #endif } @@ -2835,7 +2816,7 @@ void GtkSalFrame::UpdateSettings( AllSettings& rSettings ) if( ! m_pWindow ) return; - GtkSalGraphics* pGraphics = static_cast<GtkSalGraphics*>(m_aGraphics[0].pGraphics); + GtkSalGraphics* pGraphics = m_pGraphics; bool bFreeGraphics = false; if( ! pGraphics ) { @@ -2914,9 +2895,8 @@ void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Scre } // free xrender resources - for( unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); i++ ) - if( m_aGraphics[i].bInUse ) - m_aGraphics[i].pGraphics->SetDrawable( None, m_nXScreen ); + if( m_pGraphics ) + m_pGraphics->SetDrawable( None, m_nXScreen ); // first deinit frame if( m_pIMHandler ) @@ -2957,13 +2937,10 @@ void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Scre } // update graphics - for( unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); i++ ) + if( m_pGraphics ) { - if( m_aGraphics[i].bInUse ) - { - m_aGraphics[i].pGraphics->SetDrawable( widget_get_xid(m_pWindow), m_nXScreen ); - m_aGraphics[i].pGraphics->SetWindow( m_pWindow ); - } + m_pGraphics->SetDrawable( widget_get_xid(m_pWindow), m_nXScreen ); + m_pGraphics->SetWindow( m_pWindow ); } if( ! m_aTitle.isEmpty() ) commit 268e4e90f9696998333026ac45b52c4f349d0069 Author: Noel Grandin <n...@peralex.com> Date: Mon Nov 30 13:03:32 2015 +0200 allocate and initialise FormatEntry table at compile-time no need to init this at runtime, it's purely static data Change-Id: I73ff5b0d8f273d7ee925f485f3ed712f117f5b40 diff --git a/dtrans/source/win32/ftransl/ftransl.cxx b/dtrans/source/win32/ftransl/ftransl.cxx index 968c2f6..6a17ca4 100644 --- a/dtrans/source/win32/ftransl/ftransl.cxx +++ b/dtrans/source/win32/ftransl/ftransl.cxx @@ -69,25 +69,35 @@ namespace MODULE_PRIVATE } } -FormatEntry::FormatEntry() +struct FormatEntry { -} + FormatEntry() {} + + FormatEntry( + const char *mime_content_type, + const char *human_presentable_name, + const char *native_format_name, + CLIPFORMAT std_clipboard_format_id, + css::uno::Type const & cppu_type + ); + + css::datatransfer::DataFlavor aDataFlavor; + OUString aNativeFormatName; + sal_Int32 aStandardFormatId; +}; FormatEntry::FormatEntry( - const char* mime_content_type, - const char* human_presentable_name, - const char* native_format_name, + const char *mime_content_type, + const char *human_presentable_name, + const char *native_format_name, CLIPFORMAT std_clipboard_format_id, css::uno::Type const & cppu_type) + : aDataFlavor( OUString::createFromAscii(mime_content_type), OUString::createFromAscii(human_presentable_name), cppu_type) { - aDataFlavor.MimeType = OUString::createFromAscii(mime_content_type); - aDataFlavor.HumanPresentableName = OUString::createFromAscii(human_presentable_name); - aDataFlavor.DataType = cppu_type; - if (native_format_name) - aNativeFormatName = OUString::createFromAscii(native_format_name); + aNativeFormatName = OUString::createFromAscii(native_format_name); else - aNativeFormatName = OUString::createFromAscii(human_presentable_name); + aNativeFormatName = OUString::createFromAscii(human_presentable_name); aStandardFormatId = std_clipboard_format_id; } @@ -97,7 +107,6 @@ FormatEntry::FormatEntry( CDataFormatTranslator::CDataFormatTranslator( const Reference< XComponentContext >& rxContext ) : m_xContext( rxContext ) { - initTranslationTable( ); } Any SAL_CALL CDataFormatTranslator::getSystemDataTypeFromDataFlavor( const DataFlavor& aDataFlavor ) @@ -212,258 +221,257 @@ Sequence< OUString > SAL_CALL CDataFormatTranslator::getSupportedServiceNames( ) // format number we can stop if we find the first // CF_INVALID -void SAL_CALL CDataFormatTranslator::initTranslationTable() -{ +static const std::vector< FormatEntry > g_TranslTable { //SotClipboardFormatId::DIF - m_TranslTable.push_back(FormatEntry("application/x-openoffice-dif;windows_formatname=\"DIF\"", "DIF", "DIF", CF_DIF, CPPUTYPE_DEFAULT)); + FormatEntry("application/x-openoffice-dif;windows_formatname=\"DIF\"", "DIF", "DIF", CF_DIF, CPPUTYPE_DEFAULT), // SotClipboardFormatId::BITMAP // #i124085# CF_DIBV5 disabled, leads to problems at export. To fully support, using // an own mime-type may be necessary. I have tried that, but saw no real advantages // with different apps when exchanging bitmap-based data. So, disabled for now. At // the same time increased png format exchange for better interoperability - //m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIBV5, CPPUTYPE_DEFAULT)); + // FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIBV5, CPPUTYPE_DEFAULT), - m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIB, CPPUTYPE_DEFAULT)); - m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_BITMAP, CPPUTYPE_DEFAULT)); + FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIB, CPPUTYPE_DEFAULT), + FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_BITMAP, CPPUTYPE_DEFAULT), // SotClipboardFormatId::STRING - m_TranslTable.push_back(FormatEntry("text/plain;charset=utf-16", "Unicode-Text", "", CF_UNICODETEXT, CppuType_String)); + FormatEntry("text/plain;charset=utf-16", "Unicode-Text", "", CF_UNICODETEXT, CppuType_String), // Format Locale - for internal use - m_TranslTable.push_back(FormatEntry("application/x-openoffice-locale;windows_formatname=\"Locale\"", "Locale", "Locale", CF_LOCALE, CPPUTYPE_DEFAULT)); + FormatEntry("application/x-openoffice-locale;windows_formatname=\"Locale\"", "Locale", "Locale", CF_LOCALE, CPPUTYPE_DEFAULT), // SOT_FORMAT_WMF - m_TranslTable.push_back(FormatEntry("application/x-openoffice-wmf;windows_formatname=\"Image WMF\"", "Windows MetaFile", "Image WMF", CF_METAFILEPICT, CPPUTYPE_DEFAULT)); + FormatEntry("application/x-openoffice-wmf;windows_formatname=\"Image WMF\"", "Windows MetaFile", "Image WMF", CF_METAFILEPICT, CPPUTYPE_DEFAULT), // SOT_FORMAT_EMF - m_TranslTable.push_back(FormatEntry("application/x-openoffice-emf;windows_formatname=\"Image EMF\"", "Windows Enhanced MetaFile", "Image EMF", CF_ENHMETAFILE, CPPUTYPE_DEFAULT)); + FormatEntry("application/x-openoffice-emf;windows_formatname=\"Image EMF\"", "Windows Enhanced MetaFile", "Image EMF", CF_ENHMETAFILE, CPPUTYPE_DEFAULT), // SotClipboardFormatId::FILE_LIST ... etc. - the rest is truncated
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits