sc/source/core/tool/interpr5.cxx | 9 vcl/Library_vclplug_gen.mk | 1 vcl/inc/generic/genpspgraphics.h | 1 vcl/inc/headless/svpgdi.hxx | 1 vcl/inc/opengl/salbmp.hxx | 7 vcl/inc/opengl/texture.hxx | 67 ++++-- vcl/inc/opengl/x11/gdiimpl.hxx | 2 vcl/inc/openglgdiimpl.hxx | 17 + vcl/inc/quartz/salgdi.h | 2 vcl/inc/salgdi.hxx | 3 vcl/inc/unx/pixmap.hxx | 24 +- vcl/inc/unx/salgdi.h | 5 vcl/inc/unx/x11/x11gdiimpl.h | 2 vcl/inc/win/salgdi.h | 1 vcl/opengl/gdiimpl.cxx | 206 ++++++++++++++----- vcl/opengl/linearGradientFragmentShader.glsl | 2 vcl/opengl/salbmp.cxx | 71 ++---- vcl/opengl/scale.cxx | 97 ++++----- vcl/opengl/texture.cxx | 243 +++++++++++++++++++---- vcl/opengl/x11/gdiimpl.cxx | 32 +-- vcl/quartz/salgdi.cxx | 5 vcl/source/opengl/OpenGLContext.cxx | 14 + vcl/source/outdev/gradient.cxx | 7 vcl/unx/generic/gdi/gdiimpl.cxx | 16 - vcl/unx/generic/gdi/gdiimpl.hxx | 2 vcl/unx/generic/gdi/openglx11cairotextrender.cxx | 45 +--- vcl/unx/generic/gdi/pixmap.cxx | 54 ----- vcl/unx/generic/gdi/salgdi.cxx | 5 vcl/unx/generic/gdi/salgdi2.cxx | 4 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx | 59 ++--- vcl/unx/kde/salnativewidgets-kde.cxx | 142 +++++++------ vcl/win/source/gdi/salgdi.cxx | 5 vcl/win/source/gdi/winlayout.cxx | 6 33 files changed, 688 insertions(+), 469 deletions(-)
New commits: commit 893d37c379ca053cf033bf1aa2e175053af6da28 Author: Markus Mohrhard <[email protected]> Date: Sat Nov 15 10:40:42 2014 +0100 blind fix for OSX Change-Id: I7050057e5fa6da5bb5517713f6cbbfa60e47984b diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 6cc4526..d25b093 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -217,6 +217,8 @@ public: // InvalidateContext does an UnsetState and sets mrContext to 0 void InvalidateContext(); + virtual SalGraphicsImpl* GetImpl() const SAL_OVERRIDE; + virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE; // draw --> LineColor and FillColor and RasterOp and ClipRegion diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index 2462ec0..f133dfd 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -315,6 +315,11 @@ AquaSalGraphics::~AquaSalGraphics() } } +SalGraphicsImpl* AquaSalGraphics::GetImpl() const +{ + return NULL; +} + void AquaSalGraphics::SetTextColor( SalColor nSalColor ) { maTextColor = RGBAColor( nSalColor ); commit 1577f53fa58378ec615ac3d00f96a6aff71c0c9e Author: Markus Mohrhard <[email protected]> Date: Sat Nov 15 10:38:06 2014 +0100 let us make the virtual explicit Change-Id: Iaa4f2ecb54d57c9badc27ec8c13033eba5be7fed diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index a09e026..6b0e2be 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -128,7 +128,7 @@ public: void Init( class ImplSalPrinterData *pPrinter ); void DeInit(); - SalGraphicsImpl* GetImpl() const SAL_OVERRIDE; + virtual SalGraphicsImpl* GetImpl() const SAL_OVERRIDE; inline const SalDisplay* GetDisplay() const; inline Display* GetXDisplay() const; inline const SalVisual& GetVisual() const; commit a1754292bbb3d83fa0e23cf3a84b903911734387 Author: Markus Mohrhard <[email protected]> Date: Sat Nov 15 10:16:02 2014 +0100 ialso support the ARB debug version Change-Id: I247d43805ce08db49b487079aecee2a7b50277f5 diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 2c6de41..0e760bc 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -857,10 +857,18 @@ bool OpenGLContext::InitGLEW() // only enable debug output in dbgutil build // somehow there are implementations where the feature is present and the function // pointer is still NULL - if( GLEW_ARB_debug_output && glDebugMessageCallback ) + if( GLEW_ARB_debug_output) { - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(&debug_callback, NULL); + if (glDebugMessageCallbackARB) + { + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallbackARB(&debug_callback, NULL); + } + else if ( glDebugMessageCallback ) + { + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(&debug_callback, NULL); + } } #endif commit 0e55b14db52031d809d6537272902aa5fd94158d Author: Markus Mohrhard <[email protected]> Date: Fri Nov 14 15:02:16 2014 +0100 fix building the KDE backend Change-Id: I03c8629bf27a43d6f4cc08bb8f64ed71b9055fdc diff --git a/vcl/unx/kde/salnativewidgets-kde.cxx b/vcl/unx/kde/salnativewidgets-kde.cxx index f234e49..b849c53 100644 --- a/vcl/unx/kde/salnativewidgets-kde.cxx +++ b/vcl/unx/kde/salnativewidgets-kde.cxx @@ -26,6 +26,7 @@ #include <unx/saldisp.hxx> #include <unx/salgdi.h> #include <unx/kde/kdedata.hxx> +#include "unx/pixmap.hxx" #include <vcl/settings.hxx> #include "fontmanager.hxx" @@ -313,7 +314,7 @@ class WidgetPainter */ bool drawStyledWidget( QWidget *pWidget, ControlState nState, const ImplControlValue& aValue, - KDESalGraphics* pGraphics, + X11SalGraphics* pGraphics, ControlPart nPart = PART_ENTIRE_CONTROL ); /** 'Get' method for push button. @@ -505,7 +506,7 @@ WidgetPainter::~WidgetPainter( void ) bool WidgetPainter::drawStyledWidget( QWidget *pWidget, ControlState nState, const ImplControlValue& aValue, - KDESalGraphics* pGraphics, ControlPart nPart ) + X11SalGraphics* pGraphics, ControlPart nPart ) { if ( !pWidget ) return false; @@ -852,7 +853,7 @@ bool WidgetPainter::drawStyledWidget( QWidget *pWidget, return false; // Bitblt it to the screen - pGraphics->RenderPixmapToScreen( xPixmap, qWidgetPos.x(), qWidgetPos.y() ); + pGraphics->RenderPixmapToScreen( &xPixmap, qWidgetPos.x(), qWidgetPos.y() ); // Restore widget's position pWidget->move( qWidgetPos ); commit 32bddc7cb2fe6f3f5d9b964b28fcda864aae5c66 Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Fri Nov 14 01:16:28 2014 -0500 vcl: Implement axial gradients in OpenGL backend Change-Id: I93b8c3c076c79d992d467b01ca5f5eca1ed626d3 diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 67c0c30..dd0b1e3 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -107,6 +107,7 @@ public: void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry ); void DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry ); void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ); + void DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect ); void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect ); public: diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index ef0c2bd..0423775 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -772,6 +772,68 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const CHECK_GL_ERROR(); } +void OpenGLSalGraphicsImpl::DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect ) +{ + if( mnLinearGradientProgram == 0 ) + { + if( !CreateLinearGradientProgram() ) + return; + } + + glUseProgram( mnLinearGradientProgram ); + + Color aStartCol = rGradient.GetStartColor(); + Color aEndCol = rGradient.GetEndColor(); + long nFactor = rGradient.GetStartIntensity(); + glUniformColorIntensity( mnLinearGradientStartColorUniform, aStartCol, nFactor ); + nFactor = rGradient.GetEndIntensity(); + glUniformColorIntensity( mnLinearGradientEndColorUniform, aEndCol, nFactor ); + + /** + * Draw two rectangles with linear gradient. + * + * 1 *---* 2 + * | /| + * | / | Points 0 and 3 have start color + * 0 |/__| 3 Points 1, 2, 4 and 5 have end color + * |\ | + * | \ | + * | \| + * 5 *---* 4 + * + */ + + Rectangle aRect; + Point aCenter; + rGradient.GetBoundRect( rRect, aRect, aCenter ); + + // determine points 0 and 3 + Point aPt0( aRect.Left(), (aRect.Top() + aRect.Bottom() + 1) / 2 ); + Point aPt3( aRect.Right(), (aRect.Top() + aRect.Bottom() + 1) / 2 ); + + Polygon aPoly( 7 ); + aPoly.SetPoint( aPt0, 0 ); + aPoly.SetPoint( aRect.TopLeft(), 1 ); + aPoly.SetPoint( aRect.TopRight(), 2 ); + aPoly.SetPoint( aPt3, 3 ); + aPoly.SetPoint( aRect.BottomRight(), 4 ); + aPoly.SetPoint( aRect.BottomLeft(), 5 ); + aPoly.SetPoint( aPt0, 6 ); + aPoly.Rotate( aCenter, rGradient.GetAngle() % 3600 ); + + GLfloat aTexCoord[12] = { 0, 1, 1, 0, 2, 0, 3, 1, 4, 0, 5, 0 }; + GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder()); + aTexCoord[3] = aTexCoord[5] = aTexCoord[9] = aTexCoord[11] = fMin; + glEnableVertexAttribArray( GL_ATTRIB_TEX ); + glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord ); + + DrawConvexPolygon( aPoly ); + + glDisableVertexAttribArray( GL_ATTRIB_TEX ); + glUseProgram( 0 ); + CHECK_GL_ERROR(); +} + void OpenGLSalGraphicsImpl::DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect ) { if( mnRadialGradientProgram == 0 ) @@ -1365,6 +1427,7 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, return true; if( rGradient.GetStyle() != GradientStyle_LINEAR && + rGradient.GetStyle() != GradientStyle_AXIAL && rGradient.GetStyle() != GradientStyle_RADIAL ) return false; @@ -1402,6 +1465,10 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, { DrawLinearGradient( rGradient, aBoundRect ); } + else if( rGradient.GetStyle() == GradientStyle_AXIAL ) + { + DrawAxialGradient( rGradient, aBoundRect ); + } else if( rGradient.GetStyle() == GradientStyle_RADIAL ) { DrawRadialGradient( rGradient, aBoundRect ); diff --git a/vcl/opengl/linearGradientFragmentShader.glsl b/vcl/opengl/linearGradientFragmentShader.glsl index 7b84c06..bd1137c 100644 --- a/vcl/opengl/linearGradientFragmentShader.glsl +++ b/vcl/opengl/linearGradientFragmentShader.glsl @@ -16,7 +16,7 @@ varying vec2 tex_coord; void main(void) { - gl_FragColor = mix(start_color, end_color, + gl_FragColor = mix(end_color, start_color, clamp(tex_coord.t, 0.0, 1.0)); } commit b190ffe58796875eceaf340501a8832e222514fb Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Thu Nov 13 22:24:35 2014 -0500 vcl: Add DrawAlphaTexture to directly render Cairo surface Change-Id: I7aa824578b14999d0ef667a5bcfccd731f1d3b64 diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index c6093b5..67c0c30 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -84,6 +84,7 @@ protected: bool CreateLinearGradientProgram( void ); bool CreateRadialGradientProgram( void ); +public: void BeginSolid( SalColor nColor, sal_uInt8 nTransparency ); void BeginSolid( SalColor nColor, double fTransparency ); void BeginSolid( SalColor nColor ); @@ -102,12 +103,13 @@ protected: void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon ); void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false ); void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false ); + void DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false, bool pPremultiplied = false ); void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry ); void DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry ); void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ); void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect ); -protected: +public: // get the width of the device virtual GLfloat GetWidth() const = 0; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 8f60489..ef0c2bd 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -670,6 +670,17 @@ void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRe CHECK_GL_ERROR(); } +void OpenGLSalGraphicsImpl::DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted, bool bPremultiplied ) +{ + glEnable( GL_BLEND ); + if( bPremultiplied ) + glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); + else + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + DrawTexture( rTexture, rPosAry, bInverted ); + glDisable( GL_BLEND ); +} + void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& pPosAry ) { if( mnMaskedTextureProgram == 0 ) @@ -1301,10 +1312,7 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap( SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" ); PreDraw(); - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - DrawTexture( rTexture, rPosAry ); - glDisable( GL_BLEND ); + DrawAlphaTexture( rTexture, rPosAry ); PostDraw(); CHECK_GL_ERROR(); diff --git a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx index 36a76b0..38a7213 100644 --- a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx +++ b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx @@ -9,6 +9,7 @@ #include "openglx11cairotextrender.hxx" +#include "openglgdiimpl.hxx" #include "salbmp.hxx" #include <vcl/salbtype.hxx> @@ -33,40 +34,8 @@ void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr) cairo_surface_t* pSurface = cairo_get_target(cr); int nWidth = cairo_image_surface_get_width( pSurface ); int nHeight = cairo_image_surface_get_height( pSurface ); - SalBitmap* pBitmap = ImplGetSVData()->mpDefInst->CreateSalBitmap(); - pBitmap->Create(Size(nWidth, nHeight), 32, BitmapPalette()); - cairo_surface_flush( pSurface ); - BitmapBuffer* pBuffer = pBitmap->AcquireBuffer(false); unsigned char *pSrc = cairo_image_surface_get_data( pSurface ); - unsigned int nSrcStride = cairo_image_surface_get_stride( pSurface ); - unsigned int nDestStride = pBuffer->mnScanlineSize; - for( unsigned long y = 0; y < (unsigned long) nHeight; y++ ) - { - // Cairo surface is y-inverse - sal_uInt32 *pSrcPix = (sal_uInt32 *)(pSrc + nSrcStride * (nHeight - y - 1)); - sal_uInt32 *pDestPix = (sal_uInt32 *)(pBuffer->mpBits + nDestStride * y); - for( unsigned long x = 0; x < (unsigned long) nWidth; x++ ) - { - sal_uInt8 nAlpha = (*pSrcPix >> 24); - sal_uInt8 nR = (*pSrcPix >> 16) & 0xff; - sal_uInt8 nG = (*pSrcPix >> 8) & 0xff; - sal_uInt8 nB = *pSrcPix & 0xff; - if( nAlpha != 0 && nAlpha != 255 ) - { - // Cairo uses pre-multiplied alpha - we do not => re-multiply - nR = (sal_uInt8) MinMax( ((sal_uInt32)nR * 255) / nAlpha, 0, 255 ); - nG = (sal_uInt8) MinMax( ((sal_uInt32)nG * 255) / nAlpha, 0, 255 ); - nB = (sal_uInt8) MinMax( ((sal_uInt32)nB * 255) / nAlpha, 0, 255 ); - } - - // FIXME: lfrb: depends on endianness (use BitmapWriteAccess) - *pDestPix = (nAlpha << 24) + (nB << 16) + (nG << 8) + nR; - pSrcPix++; - pDestPix++; - } - } - pBitmap->ReleaseBuffer(pBuffer, false); SalTwoRect aRect; aRect.mnSrcX = 0; @@ -78,8 +47,16 @@ void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr) aRect.mnDestWidth = nWidth; aRect.mnDestHeight = nHeight; - mrParent.drawAlphaBitmap(aRect, *pBitmap); - delete pBitmap; + // XXX: lfrb: GLES 2.0 doesn't support GL_UNSIGNED_INT_8_8_8_8_REV + OpenGLSalGraphicsImpl *pImpl = dynamic_cast< OpenGLSalGraphicsImpl* >(mrParent.GetImpl()); + if( pImpl ) + { + // Cairo surface data is ARGB with premultiplied alpha and is Y-inverted + OpenGLTexture aTexture( nWidth, nHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pSrc ); + pImpl->PreDraw(); + pImpl->DrawAlphaTexture( aTexture, aRect, true, true ); + pImpl->PostDraw(); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 0ec7566..30c62ef 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -202,9 +202,9 @@ void WinLayout::DrawText(SalGraphics& rGraphics) const aRects.mnDestWidth = width; aRects.mnDestHeight = height; - // FIXME We don't have a method that could paint a texture with - // transparency yet, use it when we have it - pImpl->DrawTexture(aTexture, aRects); + pImpl->PreDraw(); + pImpl->DrawAlphaTexture(aTexture, aRects); + pImpl->PostDraw(); } DeleteObject(hBitmap); commit fbe77f453cc9f6840b12d10982d972d6ef276549 Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Thu Nov 13 21:38:58 2014 -0500 vcl: Make sure the offscreen texture is unique before rendering to it Change-Id: I265ce62e983e6f44ba51675993c9ec1f071c160e diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 965365e..c6093b5 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -75,6 +75,8 @@ protected: void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask ); + bool CheckOffscreenTexture(); + bool CreateSolidProgram( void ); bool CreateTextureProgram( void ); bool CreateMaskedTextureProgram( void ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 6a4ee80..8f60489 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -97,7 +97,7 @@ void OpenGLSalGraphicsImpl::PreDraw() maContext.makeCurrent(); // TODO: lfrb: make sure the render target has the right size if( mbOffscreen ) - glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId ); + CheckOffscreenTexture(); glViewport( 0, 0, GetWidth(), GetHeight() ); if( mbUseScissor ) glEnable( GL_SCISSOR_TEST ); @@ -282,6 +282,28 @@ void OpenGLSalGraphicsImpl::SetOffscreen( bool bOffscreen ) CHECK_GL_ERROR(); } +bool OpenGLSalGraphicsImpl::CheckOffscreenTexture() +{ + glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId ); + + if( maOffscreenTex.IsUnique() ) + return true; + + SalTwoRect aPosAry; + aPosAry.mnSrcX = aPosAry.mnDestX = 0; + aPosAry.mnSrcY = aPosAry.mnDestY = 0; + aPosAry.mnSrcWidth = aPosAry.mnDestWidth = GetWidth(); + aPosAry.mnSrcHeight = aPosAry.mnDestHeight = GetHeight(); + + // TODO: lfrb: User GL_ARB_copy_image? + OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 ); + glViewport( 0, 0, GetWidth(), GetHeight() ); + DrawTexture( maOffscreenTex, aPosAry ); + + return true; +} + bool OpenGLSalGraphicsImpl::CreateSolidProgram( void ) { SAL_INFO( "vcl.opengl", "::CreateSolidProgram" ); commit dce9610afed674ecec23497a1a004193a6cf3bf1 Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Thu Nov 13 21:37:54 2014 -0500 vcl: Improve OpenGLTexture implementation by allowing implicit sharing Conflicts: vcl/opengl/gdiimpl.cxx Change-Id: I6421265325e72023d1affe671d75488185772786 diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx index c1f0cdb..dbb29d8 100644 --- a/vcl/inc/opengl/salbmp.hxx +++ b/vcl/inc/opengl/salbmp.hxx @@ -40,7 +40,7 @@ class VCL_PLUGIN_PUBLIC OpenGLSalBitmap : public SalBitmap { private: OpenGLContext* mpContext; - OpenGLTextureSharedPtr mpTexture; + OpenGLTexture maTexture; bool mbDirtyTexture; BitmapPalette maPalette; basebmp::RawMemorySharedArray maUserBuffer; @@ -81,9 +81,8 @@ public: public: - bool Create( OpenGLContext& rContext, OpenGLTextureSharedPtr pTex, long nX, long nY, long nWidth, long nHeight ); - bool Draw( OpenGLContext& rContext, const SalTwoRect& rPosAry ); - GLuint GetTexture( OpenGLContext& rContext ) const; + bool Create( OpenGLContext& rContext, const OpenGLTexture& rTex, long nX, long nY, long nWidth, long nHeight ); + OpenGLTexture& GetTexture( OpenGLContext& rContext ) const; private: diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx index c0b6541..eb003cf 100644 --- a/vcl/inc/opengl/texture.hxx +++ b/vcl/inc/opengl/texture.hxx @@ -20,37 +20,62 @@ #ifndef INCLUDED_VCL_INC_OPENGL_TEXTURE_H #define INCLUDED_VCL_INC_OPENGL_TEXTURE_H -#include <boost/shared_ptr.hpp> #include <GL/glew.h> +#include <vcl/dllapi.h> -class OpenGLTexture +class ImplOpenGLTexture { -private: +public: + int mnRefCount; GLuint mnTexture; int mnWidth; int mnHeight; GLenum mnFilter; -public: - OpenGLTexture(); - OpenGLTexture( int nWidth, int nHeight ); - OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData ); - OpenGLTexture( int nX, int nY, int nWidth, int nHeight ); - virtual ~OpenGLTexture(); - - GLuint Id() const; - int GetWidth() const; - int GetHeight() const; - - void Bind(); - void Unbind(); - bool Draw(); - - GLenum GetFilter() const; - void SetFilter( GLenum nFilter ); + ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate ); + ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData ); + ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight ); + ~ImplOpenGLTexture(); }; -typedef boost::shared_ptr< OpenGLTexture > OpenGLTextureSharedPtr; +class VCL_PLUGIN_PUBLIC OpenGLTexture +{ +private: + // if the rect size doesn't match the mpImpl one, this instance + // is a sub-area from the real OpenGL texture + Rectangle maRect; + + ImplOpenGLTexture* mpImpl; + +public: + OpenGLTexture(); + OpenGLTexture( int nWidth, int nHeight, bool bAllocate = true ); + OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData ); + OpenGLTexture( int nX, int nY, int nWidth, int nHeight ); + OpenGLTexture( const OpenGLTexture& rTexture ); + OpenGLTexture( const OpenGLTexture& rTexture, int nX, int nY, int nWidth, int nHeight ); + virtual ~OpenGLTexture(); + + bool IsUnique() const; + + GLuint Id() const; + int GetWidth() const; + int GetHeight() const; + void GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool bInverted=false ) const; + + void Bind(); + void Unbind(); + bool Draw(); + void Read( GLenum nFormat, GLenum nType, sal_uInt8* pData ); + + GLenum GetFilter() const; + void SetFilter( GLenum nFilter ); + + operator bool() const; + OpenGLTexture& operator=( const OpenGLTexture& rTexture ); + bool operator==( const OpenGLTexture& rTexture ) const; + bool operator!=( const OpenGLTexture& rTexture ) const; +}; #endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_H diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 1fb0d61..965365e 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -45,7 +45,7 @@ protected: bool mbOffscreen; GLuint mnFramebufferId; - OpenGLTextureSharedPtr mpOffscreenTex; + OpenGLTexture maOffscreenTex; SalColor mnLineColor; SalColor mnFillColor; @@ -98,10 +98,10 @@ protected: void DrawRect( const Rectangle& rRect ); void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon ); - void DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry, bool bInverted = false ); - void DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& rPosAry, bool bInverted = false ); - void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const Size& rSize, const SalTwoRect& rPosAry ); - void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& rPosAry ); + void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false ); + void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false ); + void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry ); + void DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry ); void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ); void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 801130f..6a4ee80 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -66,7 +66,6 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl() , mbUseStencil(false) , mbOffscreen(false) , mnFramebufferId(0) - , mpOffscreenTex(nullptr) , mnLineColor(SALCOLOR_NONE) , mnFillColor(SALCOLOR_NONE) , mnSolidProgram(0) @@ -260,8 +259,8 @@ void OpenGLSalGraphicsImpl::SetOffscreen( bool bOffscreen ) return; // Already enabled and same size - if( mpOffscreenTex->GetWidth() == GetWidth() && - mpOffscreenTex->GetHeight() == GetHeight() ) + if( maOffscreenTex.GetWidth() == GetWidth() && + maOffscreenTex.GetHeight() == GetHeight() ) return; } else @@ -276,8 +275,8 @@ void OpenGLSalGraphicsImpl::SetOffscreen( bool bOffscreen ) if( mbOffscreen ) { glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId ); - mpOffscreenTex.reset( new OpenGLTexture( GetWidth(), GetHeight() ) ); - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mpOffscreenTex->Id(), 0 ); + maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, maOffscreenTex.Id(), 0 ); } CHECK_GL_ERROR(); @@ -611,24 +610,11 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol CHECK_GL_ERROR(); } -void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry, bool bInverted ) +void OpenGLSalGraphicsImpl::DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted ) { GLfloat aTexCoord[8]; - aTexCoord[0] = aTexCoord[2] = rPosAry.mnSrcX / (double) rSize.Width(); - aTexCoord[4] = aTexCoord[6] = (rPosAry.mnSrcX + rPosAry.mnSrcWidth) / (double) rSize.Width(); - - if( !bInverted ) - { - aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height(); - aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height(); - } - else - { - aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height(); - aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height(); - } - + rTexture.GetCoord( aTexCoord, rPosAry, bInverted ); glEnableVertexAttribArray( GL_ATTRIB_TEX ); glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord ); @@ -639,7 +625,7 @@ void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect CHECK_GL_ERROR(); } -void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& pPosAry, bool bInverted ) +void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& pPosAry, bool bInverted ) { if( mnTextureProgram == 0 ) { @@ -651,18 +637,18 @@ void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, con glUniform1i( mnSamplerUniform, 0 ); glActiveTexture( GL_TEXTURE0 ); CHECK_GL_ERROR(); - glBindTexture( GL_TEXTURE_2D, nTexture ); - DrawTextureRect( rSize, pPosAry, bInverted ); + rTexture.Bind(); + DrawTextureRect( rTexture, pPosAry, bInverted ); + rTexture.Unbind(); CHECK_GL_ERROR(); - glBindTexture( GL_TEXTURE_2D, 0 ); glUseProgram( 0 ); CHECK_GL_ERROR(); } -void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, const Size& rSize, const SalTwoRect& pPosAry ) +void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& pPosAry ) { if( mnMaskedTextureProgram == 0 ) { @@ -674,25 +660,25 @@ void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, glUniform1i( mnMaskedSamplerUniform, 0 ); glUniform1i( mnMaskSamplerUniform, 1 ); glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, nTexture ); + rTexture.Bind(); glActiveTexture( GL_TEXTURE1 ); - glBindTexture( GL_TEXTURE_2D, nMask ); + rMask.Bind(); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - DrawTextureRect( rSize, pPosAry ); + DrawTextureRect( rTexture, pPosAry ); glDisable( GL_BLEND ); glActiveTexture( GL_TEXTURE1 ); - glBindTexture( GL_TEXTURE_2D, 0 ); + rMask.Unbind(); glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, 0 ); + rTexture.Unbind(); glUseProgram( 0 ); CHECK_GL_ERROR(); } -void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& /*pPosAry*/ ) +void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, SalColor nMaskColor, const SalTwoRect& /*pPosAry*/ ) { if( mnMaskProgram == 0 ) { @@ -704,12 +690,11 @@ void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const S glUniformColor( mnMaskColorUniform, nMaskColor, 0 ); glUniform1i( mnMaskUniform, 0 ); glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, nMask ); + rMask.Bind(); - //DrawTextureRect( pPosAry ); + //DrawTextureRect( rMask, pPosAry ); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, 0 ); + rMask.Unbind(); glUseProgram( 0 ); CHECK_GL_ERROR(); @@ -1122,12 +1107,11 @@ void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitm assert(dynamic_cast<const OpenGLSalBitmap*>(&rSalBitmap)); const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); - GLuint nTexture = rBitmap.GetTexture( maContext ); - const Size aSize = rSalBitmap.GetSize(); + OpenGLTexture& rTexture = rBitmap.GetTexture( maContext ); SAL_INFO( "vcl.opengl", "::drawBitmap" ); PreDraw(); - DrawTexture( nTexture, aSize, rPosAry ); + DrawTexture( rTexture, rPosAry ); PostDraw(); } @@ -1146,12 +1130,12 @@ void OpenGLSalGraphicsImpl::drawBitmap( { const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); const OpenGLSalBitmap& rMask = static_cast<const OpenGLSalBitmap&>(rMaskBitmap); - const GLuint nTexture( rBitmap.GetTexture( maContext ) ); - const GLuint nMask( rMask.GetTexture( maContext ) ); + OpenGLTexture& rTexture( rBitmap.GetTexture( maContext ) ); + OpenGLTexture& rMaskTex( rMask.GetTexture( maContext ) ); SAL_INFO( "vcl.opengl", "::drawBitmap with MASK" ); PreDraw(); - DrawTextureWithMask( nTexture, nMask, rBitmap.GetSize(), rPosAry ); + DrawTextureWithMask( rTexture, rMaskTex, rPosAry ); PostDraw(); } @@ -1161,11 +1145,11 @@ void OpenGLSalGraphicsImpl::drawMask( SalColor nMaskColor ) { const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); - const GLuint nTexture( rBitmap.GetTexture( maContext ) ); + OpenGLTexture& rTexture( rBitmap.GetTexture( maContext ) ); SAL_INFO( "vcl.opengl", "::drawMask" ); PreDraw(); - DrawMask( nTexture, nMaskColor, rPosAry ); + DrawMask( rTexture, nMaskColor, rPosAry ); PostDraw(); } @@ -1175,7 +1159,7 @@ SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long SAL_INFO( "vcl.opengl", "::getBitmap " << nX << "," << nY << " " << nWidth << "x" << nHeight ); PreDraw(); - if( !pBitmap->Create( maContext, mpOffscreenTex, nX, nY, nWidth, nHeight ) ) + if( !pBitmap->Create( maContext, maOffscreenTex, nX, nY, nWidth, nHeight ) ) { delete pBitmap; pBitmap = NULL; @@ -1276,12 +1260,12 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap( { const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); const OpenGLSalBitmap& rAlpha = static_cast<const OpenGLSalBitmap&>(rAlphaBitmap); - const GLuint nTexture( rBitmap.GetTexture( maContext ) ); - const GLuint nAlpha( rAlpha.GetTexture( maContext ) ); + OpenGLTexture& rTexture( rBitmap.GetTexture( maContext ) ); + OpenGLTexture& rAlphaTex( rAlpha.GetTexture( maContext ) ); SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" ); PreDraw(); - DrawTextureWithMask( nTexture, nAlpha, rBitmap.GetSize(), rPosAry ); + DrawTextureWithMask( rTexture, rAlphaTex, rPosAry ); PostDraw(); return true; } @@ -1291,13 +1275,13 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap( const SalBitmap& rSalBitmap ) { const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap); - const GLuint nTexture( rBitmap.GetTexture( maContext ) ); + OpenGLTexture& rTexture( rBitmap.GetTexture( maContext ) ); SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" ); PreDraw(); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - DrawTexture( nTexture, rBitmap.GetSize(), rPosAry ); + DrawTexture( rTexture, rPosAry ); glDisable( GL_BLEND ); PostDraw(); diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index d7e38b0..2e197d3 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -37,7 +37,6 @@ static bool isValidBitCount( sal_uInt16 nBitCount ) OpenGLSalBitmap::OpenGLSalBitmap() : mpContext(NULL) -, mpTexture() , mbDirtyTexture(true) , mnBits(0) , mnBytesPerRow(0) @@ -61,7 +60,7 @@ OpenGLSalBitmap::~OpenGLSalBitmap() SAL_INFO( "vcl.opengl", "~OpenGLSalBitmap" ); } -bool OpenGLSalBitmap::Create( OpenGLContext& rContext, OpenGLTextureSharedPtr pTex, long nX, long nY, long nWidth, long nHeight ) +bool OpenGLSalBitmap::Create( OpenGLContext& rContext, const OpenGLTexture& rTex, long nX, long nY, long nWidth, long nHeight ) { static const BitmapPalette aEmptyPalette; @@ -78,13 +77,12 @@ bool OpenGLSalBitmap::Create( OpenGLContext& rContext, OpenGLTextureSharedPtr pT mnBits = 32; maPalette = aEmptyPalette; - // TODO: lfrb: Crop texture if size doesn't match the texture one - if( pTex ) - mpTexture = pTex; + if( rTex ) + maTexture = OpenGLTexture( rTex, nX, nY, nWidth, nHeight ); else - mpTexture.reset( new OpenGLTexture( nX, nY, nWidth, nHeight ) ); + maTexture = OpenGLTexture( nX, nY, nWidth, nHeight ); mbDirtyTexture = false; - SAL_INFO( "vcl.opengl", "Created texture " << mpTexture->Id() ); + SAL_INFO( "vcl.opengl", "Created texture " << maTexture.Id() ); return true; } @@ -133,7 +131,7 @@ bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount mnBufHeight = rSourceBitmap.mnBufHeight; maPalette = rSourceBitmap.maPalette; mpContext = rSourceBitmap.mpContext; - mpTexture = rSourceBitmap.mpTexture; + maTexture = rSourceBitmap.maTexture; mbDirtyTexture = false; maUserBuffer = rSourceBitmap.maUserBuffer; @@ -149,36 +147,22 @@ bool OpenGLSalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun return false; } -bool OpenGLSalBitmap::Draw( OpenGLContext& rContext, const SalTwoRect& /*rPosAry*/ ) +OpenGLTexture& OpenGLSalBitmap::GetTexture( OpenGLContext& rContext ) const { + OpenGLSalBitmap* pThis = const_cast<OpenGLSalBitmap*>(this); if( !mpContext ) - mpContext = &rContext; - - if( !mpTexture || mbDirtyTexture ) - { - if( !CreateTexture() ) - return false; - } - - //DrawTexture( mnTexture, rPosAry ); - return true; -} - -GLuint OpenGLSalBitmap::GetTexture( OpenGLContext& rContext ) const -{ - if( !mpContext ) - const_cast<OpenGLSalBitmap*>(this)->mpContext = &rContext; - if( !mpTexture || mbDirtyTexture ) - const_cast<OpenGLSalBitmap*>(this)->CreateTexture(); - SAL_INFO( "vcl.opengl", "Got texture " << mpTexture->Id() ); - return mpTexture->Id(); + pThis->mpContext = &rContext; + if( !maTexture || mbDirtyTexture ) + pThis->CreateTexture(); + SAL_INFO( "vcl.opengl", "Got texture " << maTexture.Id() ); + return pThis->maTexture; } void OpenGLSalBitmap::Destroy() { SAL_INFO( "vcl.opengl", "Destroy OpenGLSalBitmap" ); maPendingOps.clear(); - mpTexture.reset(); + maTexture = OpenGLTexture(); maUserBuffer.reset(); } @@ -410,8 +394,8 @@ GLuint OpenGLSalBitmap::CreateTexture() } mpContext->makeCurrent(); - mpTexture.reset( new OpenGLTexture (mnBufWidth, mnBufHeight, nFormat, nType, pData ) ); - SAL_INFO( "vcl.opengl", "Created texture " << mpTexture->Id() ); + maTexture = OpenGLTexture (mnBufWidth, mnBufHeight, nFormat, nType, pData ); + SAL_INFO( "vcl.opengl", "Created texture " << maTexture.Id() ); if( bAllocated ) delete[] pData; @@ -426,12 +410,11 @@ GLuint OpenGLSalBitmap::CreateTexture() mbDirtyTexture = false; CHECK_GL_ERROR(); - return mpTexture->Id(); + return maTexture.Id(); } bool OpenGLSalBitmap::ReadTexture() { - GLuint nFramebufferId; sal_uInt8* pData = maUserBuffer.get(); GLenum nFormat = GL_RGBA; GLenum nType = GL_UNSIGNED_BYTE; @@ -459,18 +442,16 @@ bool OpenGLSalBitmap::ReadTexture() break; } } + else + { + return false; + } mpContext->makeCurrent(); - glGenFramebuffers( 1, &nFramebufferId ); - glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId ); - - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mpTexture->Id(), 0 ); - glReadPixels( 0, 0, mnWidth, mnHeight, nFormat, nType, pData ); + maTexture.Read( nFormat, nType, pData ); + mnBufWidth = mnWidth; + mnBufHeight = mnHeight; - glBindFramebuffer( GL_FRAMEBUFFER, 0 ); - glDeleteFramebuffers( 1, &nFramebufferId ); - - CHECK_GL_ERROR(); return true; } @@ -485,7 +466,7 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ ) { if( !AllocateUserData() ) return NULL; - if( mpTexture && !ReadTexture() ) + if( maTexture && !ReadTexture() ) return NULL; } @@ -533,6 +514,7 @@ void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) { if( !bReadOnly ) { + maTexture = OpenGLTexture(); mbDirtyTexture = true; } delete pBuffer; @@ -540,6 +522,7 @@ void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) bool OpenGLSalBitmap::GetSystemData( BitmapSystemData& /*rData*/ ) { + SAL_WARN( "vcl.opengl", "*** NOT IMPLEMENTED *** GetSystemData" ); #if 0 // TODO Implement for ANDROID/OSX/IOS/WIN32 X11SalBitmap rBitmap; diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx index d1b85a5..92fdd3f 100644 --- a/vcl/opengl/scale.cxx +++ b/vcl/opengl/scale.cxx @@ -86,7 +86,6 @@ bool OpenGLSalBitmap::ImplScaleFilter( const double& rScaleY, GLenum nFilter ) { - OpenGLTexture* pNewTex; GLuint nProgram; GLuint nFramebufferId; GLenum nOldFilter; @@ -102,15 +101,15 @@ bool OpenGLSalBitmap::ImplScaleFilter( glUseProgram( nProgram ); glUniform1i( mnTexSamplerUniform, 0 ); - pNewTex = new OpenGLTexture( nNewWidth, nNewHeight ); - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pNewTex->Id(), 0 ); + OpenGLTexture aNewTex = OpenGLTexture( nNewWidth, nNewHeight ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 ); - mpTexture->Bind(); - nOldFilter = mpTexture->GetFilter(); - mpTexture->SetFilter( nFilter ); - mpTexture->Draw(); - mpTexture->SetFilter( nOldFilter ); - mpTexture->Unbind(); + maTexture.Bind(); + nOldFilter = maTexture.GetFilter(); + maTexture.SetFilter( nFilter ); + maTexture.Draw(); + maTexture.SetFilter( nOldFilter ); + maTexture.Unbind(); glUseProgram( 0 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); @@ -118,7 +117,7 @@ bool OpenGLSalBitmap::ImplScaleFilter( mnWidth = nNewWidth; mnHeight = nNewHeight; - mpTexture.reset( pNewTex ); + maTexture = aNewTex; CHECK_GL_ERROR(); return true; @@ -167,8 +166,6 @@ bool OpenGLSalBitmap::ImplScaleConvolution( const double& rScaleY, const Kernel& aKernel ) { - OpenGLTexture* pScratchTex; - OpenGLTexture* pNewTex; GLfloat* pWeights( 0 ); GLuint nFramebufferId; GLuint nProgram; @@ -190,51 +187,59 @@ bool OpenGLSalBitmap::ImplScaleConvolution( CHECK_GL_ERROR(); // horizontal scaling in scratch texture - pScratchTex = new OpenGLTexture( nNewWidth, mnHeight ); - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pScratchTex->Id(), 0 ); - CHECK_GL_ERROR(); - - for( sal_uInt32 i = 0; i < 16; i++ ) + if( mnWidth != nNewWidth ) { - aOffsets[i * 2] = i / (double) mnWidth; - aOffsets[i * 2 + 1] = 0; - } - ImplCreateKernel( rScaleX, aKernel, pWeights, nKernelSize ); - glUniform1fv( mnConvKernelUniform, 16, pWeights ); - CHECK_GL_ERROR(); - glUniform2fv( mnConvOffsetsUniform, 16, aOffsets ); - CHECK_GL_ERROR(); + OpenGLTexture aScratchTex = OpenGLTexture( nNewWidth, mnHeight ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aScratchTex.Id(), 0 ); + CHECK_GL_ERROR(); - glViewport( 0, 0, nNewWidth, mnHeight ); - mpTexture->Bind(); - mpTexture->Draw(); - mpTexture->Unbind(); + for( sal_uInt32 i = 0; i < 16; i++ ) + { + aOffsets[i * 2] = i / (double) mnWidth; + aOffsets[i * 2 + 1] = 0; + } + ImplCreateKernel( rScaleX, aKernel, pWeights, nKernelSize ); + glUniform1fv( mnConvKernelUniform, 16, pWeights ); + CHECK_GL_ERROR(); + glUniform2fv( mnConvOffsetsUniform, 16, aOffsets ); + CHECK_GL_ERROR(); + + glViewport( 0, 0, nNewWidth, mnHeight ); + maTexture.Bind(); + maTexture.Draw(); + maTexture.Unbind(); + + maTexture = aScratchTex; + } // vertical scaling in final texture - pNewTex = new OpenGLTexture( nNewWidth, nNewHeight ); - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pNewTex->Id(), 0 ); - - for( sal_uInt32 i = 0; i < 16; i++ ) + if( mnHeight != nNewHeight ) { - aOffsets[i * 2] = 0; - aOffsets[i * 2 + 1] = i / (double) mnHeight; - } - ImplCreateKernel( rScaleY, aKernel, pWeights, nKernelSize ); - glUniform1fv( mnConvKernelUniform, 16, pWeights ); - glUniform2fv( mnConvOffsetsUniform, 16, aOffsets ); - CHECK_GL_ERROR(); + OpenGLTexture aScratchTex = OpenGLTexture( nNewWidth, nNewHeight ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aScratchTex.Id(), 0 ); + + for( sal_uInt32 i = 0; i < 16; i++ ) + { + aOffsets[i * 2] = 0; + aOffsets[i * 2 + 1] = i / (double) mnHeight; + } + ImplCreateKernel( rScaleY, aKernel, pWeights, nKernelSize ); + glUniform1fv( mnConvKernelUniform, 16, pWeights ); + glUniform2fv( mnConvOffsetsUniform, 16, aOffsets ); + CHECK_GL_ERROR(); - glViewport( 0, 0, nNewWidth, nNewHeight ); - pScratchTex->Bind(); - pScratchTex->Draw(); - pScratchTex->Unbind(); + glViewport( 0, 0, nNewWidth, nNewHeight ); + maTexture.Bind(); + maTexture.Draw(); + maTexture.Unbind(); + + maTexture = aScratchTex; + } glUseProgram( 0 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glDeleteFramebuffers( 1, &nFramebufferId ); - delete pScratchTex; - mpTexture.reset( pNewTex ); mnWidth = nNewWidth; mnHeight = nNewHeight; diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx index 0c8dc1d..005fb66 100644 --- a/vcl/opengl/texture.cxx +++ b/vcl/opengl/texture.cxx @@ -24,19 +24,12 @@ #include "opengl/texture.hxx" -OpenGLTexture::OpenGLTexture() -: mnTexture( 0 ) -, mnWidth( -1 ) -, mnHeight( -1 ) -, mnFilter( GL_NEAREST ) -{ -} - -OpenGLTexture::OpenGLTexture( int nWidth, int nHeight ) -: mnTexture( 0 ) -, mnWidth( nWidth ) -, mnHeight( nHeight ) -, mnFilter( GL_NEAREST ) +// texture with allocated size +ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate ) : + mnRefCount( 1 ), + mnWidth( nWidth ), + mnHeight( nHeight ), + mnFilter( GL_NEAREST ) { glGenTextures( 1, &mnTexture ); glBindTexture( GL_TEXTURE_2D, mnTexture ); @@ -44,15 +37,18 @@ OpenGLTexture::OpenGLTexture( int nWidth, int nHeight ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); + if( bAllocate ) + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); glBindTexture( GL_TEXTURE_2D, 0 ); } -OpenGLTexture::OpenGLTexture( int nX, int nY, int nWidth, int nHeight ) -: mnTexture( 0 ) -, mnWidth( nWidth ) -, mnHeight( nHeight ) -, mnFilter( GL_NEAREST ) +// texture with content retrieved from FBO +ImplOpenGLTexture::ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight ) : + mnRefCount( 1 ), + mnTexture( 0 ), + mnWidth( nWidth ), + mnHeight( nHeight ), + mnFilter( GL_NEAREST ) { glGenTextures( 1, &mnTexture ); glBindTexture( GL_TEXTURE_2D, mnTexture ); @@ -66,11 +62,13 @@ OpenGLTexture::OpenGLTexture( int nX, int nY, int nWidth, int nHeight ) CHECK_GL_ERROR(); } -OpenGLTexture::OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData ) -: mnTexture( 0 ) -, mnWidth( nWidth ) -, mnHeight( nHeight ) -, mnFilter( GL_NEAREST ) +// texture from buffer data +ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData ) : + mnRefCount( 1 ), + mnTexture( 0 ), + mnWidth( nWidth ), + mnHeight( nHeight ), + mnFilter( GL_NEAREST ) { if( !mnTexture ) glGenTextures( 1, &mnTexture ); @@ -84,37 +82,119 @@ OpenGLTexture::OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, s glBindTexture( GL_TEXTURE_2D, 0 ); } -OpenGLTexture::~OpenGLTexture() +ImplOpenGLTexture::~ImplOpenGLTexture() { + SAL_INFO( "vcl.opengl", "~OpenGLTexture " << mnTexture ); if( mnTexture != 0 ) glDeleteTextures( 1, &mnTexture ); } +OpenGLTexture::OpenGLTexture() : + maRect( 0, 0, 0, 0 ), + mpImpl( NULL ) +{ +} + +OpenGLTexture::OpenGLTexture( int nWidth, int nHeight, bool bAllocate ) : + maRect( Point( 0, 0 ), Size( nWidth, nHeight ) ) +{ + mpImpl = new ImplOpenGLTexture( nWidth, nHeight, bAllocate ); +} + +OpenGLTexture::OpenGLTexture( int nX, int nY, int nWidth, int nHeight ) : + maRect( Point( 0, 0 ), Size( nWidth, nHeight ) ) +{ + mpImpl = new ImplOpenGLTexture( nX, nY, nWidth, nHeight ); +} + +OpenGLTexture::OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData ) : + maRect( Point( 0, 0 ), Size( nWidth, nHeight ) ) +{ + mpImpl = new ImplOpenGLTexture( nWidth, nHeight, nFormat, nType, pData ); +} + +OpenGLTexture::OpenGLTexture( const OpenGLTexture& rTexture ) +{ + maRect = rTexture.maRect; + mpImpl = rTexture.mpImpl; + if( mpImpl ) + mpImpl->mnRefCount++; +} + +OpenGLTexture::OpenGLTexture( const OpenGLTexture& rTexture, + int nX, int nY, int nWidth, int nHeight ) +{ + maRect = Rectangle( Point( rTexture.maRect.Left() + nX, rTexture.maRect.Top() + nY ), + Size( nWidth, nHeight ) ); + mpImpl = rTexture.mpImpl; + if( mpImpl ) + mpImpl->mnRefCount++; + SAL_INFO( "vcl.opengl", "Copying texture " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() ); +} + +OpenGLTexture::~OpenGLTexture() +{ + if( mpImpl ) + { + if( mpImpl->mnRefCount == 1 ) + delete mpImpl; + else + mpImpl->mnRefCount--; + } +} + +bool OpenGLTexture::IsUnique() const +{ + return ( mpImpl == NULL || mpImpl->mnRefCount == 1 ); +} + GLuint OpenGLTexture::Id() const { - return mnTexture; + if( mpImpl ) + return mpImpl->mnTexture; + return 0; } int OpenGLTexture::GetWidth() const { - return mnWidth; + return maRect.GetWidth(); } int OpenGLTexture::GetHeight() const { - return mnHeight; + return maRect.GetHeight(); +} + +void OpenGLTexture::GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool bInverted ) const +{ + SAL_INFO( "vcl.opengl", "Getting coord " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() ); + pCoord[0] = pCoord[2] = (maRect.Left() + rPosAry.mnSrcX) / (double) mpImpl->mnWidth; + pCoord[4] = pCoord[6] = (maRect.Left() + rPosAry.mnSrcX + rPosAry.mnSrcWidth) / (double) mpImpl->mnWidth; + + if( !bInverted ) + { + pCoord[3] = pCoord[5] = 1.0f - (maRect.Top() + rPosAry.mnSrcY) / (double) mpImpl->mnHeight; + pCoord[1] = pCoord[7] = 1.0f - (maRect.Top() + rPosAry.mnSrcY + rPosAry.mnSrcHeight) / (double) mpImpl->mnHeight; + } + else + { + pCoord[1] = pCoord[7] = 1.0f - (maRect.Top() + rPosAry.mnSrcY) / (double) mpImpl->mnHeight; + pCoord[3] = pCoord[5] = 1.0f - (maRect.Top() + rPosAry.mnSrcY + rPosAry.mnSrcHeight) / (double) mpImpl->mnHeight; + } } GLenum OpenGLTexture::GetFilter() const { - return mnFilter; + if( mpImpl ) + return mpImpl->mnFilter; + return GL_NEAREST; } void OpenGLTexture::SetFilter( GLenum nFilter ) { - mnFilter = nFilter; - if( mnTexture ) + if( mpImpl ) { + mpImpl->mnFilter = nFilter; glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nFilter ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nFilter ); } @@ -122,23 +202,38 @@ void OpenGLTexture::SetFilter( GLenum nFilter ) void OpenGLTexture::Bind() { - glBindTexture( GL_TEXTURE_2D, mnTexture ); + if( mpImpl ) + glBindTexture( GL_TEXTURE_2D, mpImpl->mnTexture ); } void OpenGLTexture::Unbind() { - glBindTexture( GL_TEXTURE_2D, 0 ); + if( mpImpl ) + glBindTexture( GL_TEXTURE_2D, 0 ); } bool OpenGLTexture::Draw() { - const GLfloat aPosition[8] = { -1, -1, -1, 1, 1, 1, 1, -1 }; - const GLfloat aTexCoord[8] = { 0, 0, 0, 1, 1, 1, 1, 0 }; + GLfloat aPosition[8] = { -1, -1, -1, 1, 1, 1, 1, -1 }; + GLfloat aTexCoord[8] = { 0, 0, 0, 1, 1, 1, 1, 0 }; - if( mnTexture == 0 ) + if( mpImpl == NULL ) + { + SAL_WARN( "vcl.opengl", "Can't draw invalid texture" ); return false; + } - glBindTexture( GL_TEXTURE_2D, mnTexture ); + SAL_INFO( "vcl.opengl", "Drawing texture " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() ); + if( GetWidth() != mpImpl->mnWidth || GetHeight() != mpImpl->mnHeight ) + { + // FIXME: lfrb: check math + aTexCoord[0] = aTexCoord[2] = maRect.Left() / (double) mpImpl->mnWidth; + aTexCoord[4] = aTexCoord[6] = maRect.Right() / (double) mpImpl->mnWidth; + aTexCoord[1] = aTexCoord[7] = maRect.Top() / (double) mpImpl->mnHeight; + aTexCoord[3] = aTexCoord[5] = maRect.Bottom() / (double) mpImpl->mnHeight; + } + + glBindTexture( GL_TEXTURE_2D, mpImpl->mnTexture ); glEnableVertexAttribArray( 0 ); glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, aPosition ); glEnableVertexAttribArray( 1 ); @@ -151,4 +246,78 @@ bool OpenGLTexture::Draw() return true; } +void OpenGLTexture::Read( GLenum nFormat, GLenum nType, sal_uInt8* pData ) +{ + if( mpImpl == NULL ) + { + SAL_WARN( "vcl.opengl", "Can't read invalid texture" ); + return; + } + + Bind(); + glPixelStorei( GL_PACK_ALIGNMENT, 1 ); + + SAL_INFO( "vcl.opengl", "Reading texture " << Id() << " " << GetWidth() << "x" << GetHeight() ); + + if( GetWidth() == mpImpl->mnWidth && GetHeight() == mpImpl->mnHeight ) + { + // XXX: Call not available with GLES 2.0 + glGetTexImage( GL_TEXTURE_2D, 0, nFormat, nType, pData ); + } + else + { + GLuint nFramebufferId; + glGenFramebuffers( 1, &nFramebufferId ); + glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId ); + CHECK_GL_ERROR(); + + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Id(), 0 ); + CHECK_GL_ERROR(); + glReadPixels( maRect.Left(), mpImpl->mnHeight - maRect.Top(), GetWidth(), GetHeight(), nFormat, nType, pData ); + CHECK_GL_ERROR(); + + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + glDeleteFramebuffers( 1, &nFramebufferId ); + + int bpp = (nFormat == GL_RGB) ? 3 : 4; + memset( pData, 255, GetWidth() * GetHeight() * bpp ); + } + + Unbind(); + CHECK_GL_ERROR(); +} + +OpenGLTexture::operator bool() const +{ + return ( mpImpl != NULL ); +} + +OpenGLTexture& OpenGLTexture::operator=( const OpenGLTexture& rTexture ) +{ + if( rTexture.mpImpl ) + rTexture.mpImpl->mnRefCount++; + if( mpImpl ) + { + if( mpImpl->mnRefCount == 1 ) + delete mpImpl; + else + mpImpl->mnRefCount--; + } + + maRect = rTexture.maRect; + mpImpl = rTexture.mpImpl; + + return *this; +} + +bool OpenGLTexture::operator==( const OpenGLTexture& rTexture ) const +{ + return (mpImpl == rTexture.mpImpl && maRect == rTexture.maRect ); +} + +bool OpenGLTexture::operator!=( const OpenGLTexture& rTexture ) const +{ + return !( *this == rTexture ); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx index 3d242ac..3bbb3d3 100644 --- a/vcl/opengl/x11/gdiimpl.cxx +++ b/vcl/opengl/x11/gdiimpl.cxx @@ -15,6 +15,7 @@ #include "unx/salgdi.h" #include "unx/salvd.h" +#include "opengl/texture.hxx" #include "opengl/x11/gdiimpl.hxx" #include <vcl/opengl/OpenGLContext.hxx> @@ -125,7 +126,6 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, Display* pDisplay = mrParent.GetXDisplay(); GLXFBConfig pFbConfig; GLXPixmap pGlxPixmap; - GLuint nTexture; SalTwoRect aPosAry; bool bInverted; @@ -145,21 +145,18 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, PreDraw(); - glGenTextures( 1, &nTexture ); + OpenGLTexture aTexture( pPixmap->GetWidth(), pPixmap->GetHeight(), false ); glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, nTexture ); + aTexture.Bind(); //TODO: lfrb: glXGetProc to get the functions glXBindTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT, NULL ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - - DrawTexture( nTexture, pPixmap->GetSize(), aPosAry, !bInverted ); + DrawTexture( aTexture, aPosAry, !bInverted ); glXReleaseTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT ); - glDeleteTextures( 1, &nTexture ); glXDestroyPixmap( pDisplay, pGlxPixmap ); + aTexture.Unbind(); PostDraw(); diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index ca988bc..0ec7566 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -204,7 +204,7 @@ void WinLayout::DrawText(SalGraphics& rGraphics) const // FIXME We don't have a method that could paint a texture with // transparency yet, use it when we have it - pImpl->DrawTexture(aTexture.Id(), Size(width, height), aRects); + pImpl->DrawTexture(aTexture, aRects); } DeleteObject(hBitmap); commit 330b7b310193f3290cbd4c340659f72d12c352e1 Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Thu Nov 13 21:31:42 2014 -0500 vcl: Draw gradient in alpha device even when using native rendering Change-Id: Iead4ac3e97197f8f863242a2162907b32c3c5b2b diff --git a/vcl/source/outdev/gradient.cxx b/vcl/source/outdev/gradient.cxx index 50855e3..77be6a0 100644 --- a/vcl/source/outdev/gradient.cxx +++ b/vcl/source/outdev/gradient.cxx @@ -41,6 +41,8 @@ void OutputDevice::DrawGradient( const Rectangle& rRect, void OutputDevice::DrawGradient( const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient ) { + bool bDrawn = false; + if ( mnDrawMode & DRAWMODE_NOGRADIENT ) return; // nothing to draw! @@ -52,11 +54,10 @@ void OutputDevice::DrawGradient( const tools::PolyPolygon& rPolyPoly, if ( mpGraphics || AcquireGraphics() ) { - if ( mpGraphics->DrawGradient( rPolyPoly, rGradient, this ) ) - return; + bDrawn = mpGraphics->DrawGradient( rPolyPoly, rGradient, this ); } - if ( rPolyPoly.Count() && rPolyPoly[ 0 ].GetSize() ) + if ( !bDrawn && rPolyPoly.Count() && rPolyPoly[ 0 ].GetSize() ) { if ( mnDrawMode & ( DRAWMODE_BLACKGRADIENT | DRAWMODE_WHITEGRADIENT | DRAWMODE_SETTINGSGRADIENT) ) { commit aa9dfcee5039246874809f1235835415b8eaa1a9 Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Thu Nov 13 21:30:05 2014 -0500 vcl: Implement copyBits in the OpenGL backend Change-Id: I101afd11394d3d024d38519afd61d700114702ac diff --git a/vcl/inc/generic/genpspgraphics.h b/vcl/inc/generic/genpspgraphics.h index 882e475..382a693 100644 --- a/vcl/inc/generic/genpspgraphics.h +++ b/vcl/inc/generic/genpspgraphics.h @@ -71,6 +71,7 @@ public: const psp::FastPrintFontInfo& ); // overload all pure virtual methods + virtual SalGraphicsImpl*GetImpl() const SAL_OVERRIDE { return NULL; }; virtual void GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) SAL_OVERRIDE; virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE; virtual long GetGraphicsWidth() const SAL_OVERRIDE; diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 9f2604f..4da3ffa 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -137,6 +137,7 @@ public: SvpSalGraphics(); virtual ~SvpSalGraphics(); + virtual SalGraphicsImpl* GetImpl() const SAL_OVERRIDE { return NULL; }; virtual void GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) SAL_OVERRIDE; virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE; virtual long GetGraphicsWidth() const SAL_OVERRIDE; diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 2453450..4a567f5 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -29,6 +29,7 @@ #include <vcl/salnativewidgets.hxx> #include <vcl/metric.hxx> +#include "salgdiimpl.hxx" #include "salglyphid.hxx" #include "sallayout.hxx" @@ -82,6 +83,8 @@ public: SalGraphics(); virtual ~SalGraphics(); + virtual SalGraphicsImpl* GetImpl() const = 0; + void setAntiAliasB2DDraw(bool bNew) { m_bAntiAliasB2DDraw = bNew; } bool getAntiAliasB2DDraw() const { return m_bAntiAliasB2DDraw; } diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index f14eab6..a09e026 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -128,6 +128,7 @@ public: void Init( class ImplSalPrinterData *pPrinter ); void DeInit(); + SalGraphicsImpl* GetImpl() const SAL_OVERRIDE; inline const SalDisplay* GetDisplay() const; inline Display* GetXDisplay() const; inline const SalVisual& GetVisual() const; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 82cfb38..74e8fe0 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -203,6 +203,7 @@ public: explicit WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd); virtual ~WinSalGraphics(); + SalGraphicsImpl* GetImpl() const SAL_OVERRIDE; bool isPrinter() const; bool isVirtualDevice() const; bool isWindow() const; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 027d9ac..801130f 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -30,6 +30,7 @@ #include <basegfx/polygon/b2dtrapezoid.hxx> #include <vcl/opengl/OpenGLHelper.hxx> +#include "salgdi.hxx" #include "opengl/salbmp.hxx" #include <vector> @@ -1082,13 +1083,13 @@ void OpenGLSalGraphicsImpl::copyArea( // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics -void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* /*pSrcGraphics*/ ) +void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { - // TODO Check if SalGraphicsImpl is the same - const bool bSameGraphics( false ); + OpenGLSalGraphicsImpl *pImpl = pSrcGraphics ? dynamic_cast< OpenGLSalGraphicsImpl* >(pSrcGraphics->GetImpl()) : NULL; SAL_INFO( "vcl.opengl", "::copyBits" ); - if( bSameGraphics && + + if( pImpl == this && (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && (rPosAry.mnSrcHeight == rPosAry.mnDestHeight)) { @@ -1102,6 +1103,16 @@ void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* /* return; } + if( pImpl->mbOffscreen ) + { + Size aSize( pImpl->GetWidth(), pImpl->GetHeight() ); + PreDraw(); + DrawTexture( pImpl->maOffscreenTex, rPosAry ); + PostDraw(); + return; + } + + SAL_WARN( "vcl.opengl", "*** NOT IMPLEMENTED *** copyBits" ); // TODO Copy from one FBO to the other (glBlitFramebuffer) } diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index 50ffdc6..fc2ca50 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -121,6 +121,11 @@ void X11SalGraphics::freeResources() bFontGC_ = false; } +SalGraphicsImpl* X11SalGraphics::GetImpl() const +{ + return mpImpl.get(); +} + void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen ) { // shortcut if nothing changed diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index 195d14c..c5f848c 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -615,6 +615,11 @@ WinSalGraphics::~WinSalGraphics() delete [] mpFontKernPairs; } +SalGraphicsImpl* WinSalGraphics::GetImpl() const +{ + return mpImpl.get(); +} + bool WinSalGraphics::isPrinter() const { return mbPrinter; commit 9d2afa44fd783820c64d424632f4d96278382253 Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Thu Nov 13 09:33:22 2014 -0500 vcl: Use backend-independent functions to fill/render pixmap on KDE Conflicts: vcl/unx/kde/salnativewidgets-kde.cxx Change-Id: I662a05d988f5989fc2ac0d06003851c56105e184 diff --git a/vcl/unx/kde/salnativewidgets-kde.cxx b/vcl/unx/kde/salnativewidgets-kde.cxx index 4c48b88..f234e49 100644 --- a/vcl/unx/kde/salnativewidgets-kde.cxx +++ b/vcl/unx/kde/salnativewidgets-kde.cxx @@ -78,6 +78,54 @@ using namespace ::com::sun::star; + +/** Qt implementation of X11Pixmap + + Wrapper around a QPixmap. + */ + +class KDEX11Pixmap : public X11Pixmap +{ +public: + KDEX11Pixmap( int nWidth, int nHeight ); + virtual ~KDEX11Pixmap() {}; + + virtual int GetDepth() const SAL_OVERRIDE; + virtual SalX11Screen GetScreen() const SAL_OVERRIDE; + virtual Pixmap GetPixmap() const SAL_OVERRIDE; + QPixmap GetQPixmap() const; + +protected: + QPixmap mqPixmap; +}; + +KDEX11Pixmap::KDEX11Pixmap( int nWidth, int nHeight ) +: X11Pixmap( nWidth, nHeight ) +, mqPixmap( nWidth, nHeight ) +{ +} + +int KDEX11Pixmap::GetDepth() const +{ + return mqPixmap.x11Depth(); +} + +SalX11Screen KDEX11Pixmap::GetScreen() const +{ + return SalX11Screen( mqPixmap.x11Screen() ); +} + +Pixmap KDEX11Pixmap::GetPixmap() const +{ + return mqPixmap.handle(); +} + +QPixmap KDEX11Pixmap::GetQPixmap() const +{ + return mqPixmap; +} + + /** Cached native widgets. A class which caches and paints the native widgets. @@ -260,19 +308,12 @@ class WidgetPainter @param aValue The value (true/false, ...) - @param dpy - The display to be used by the X calls. - - @param drawable - The destination X window. - - @param gc - The graphics context. + @param pGraphics + The SalGraphics instance to read/write screen. */ bool drawStyledWidget( QWidget *pWidget, ControlState nState, const ImplControlValue& aValue, - Display *dpy, ::Window drawable, SalX11Screen nXScreen, - int nDepth, GC gc, + KDESalGraphics* pGraphics, ControlPart nPart = PART_ENTIRE_CONTROL ); /** 'Get' method for push button. @@ -464,8 +505,7 @@ WidgetPainter::~WidgetPainter( void ) bool WidgetPainter::drawStyledWidget( QWidget *pWidget, ControlState nState, const ImplControlValue& aValue, - Display *dpy, ::Window drawable, SalX11Screen nXScreen, - int nDepth, GC gc, ControlPart nPart ) + KDESalGraphics* pGraphics, ControlPart nPart ) { if ( !pWidget ) return false; @@ -478,9 +518,10 @@ bool WidgetPainter::drawStyledWidget( QWidget *pWidget, pWidget->setEnabled( nState & CTRL_STATE_ENABLED ); // Create pixmap to paint to - QPixmap qPixmap( pWidget->width(), pWidget->height() ); - QPainter qPainter( &qPixmap ); - QRect qRect( 0, 0, pWidget->width(), pWidget->height() ); + KDEX11Pixmap xPixmap( pWidget->width(), pWidget->height() ); + QPixmap qPixmap( xPixmap.GetQPixmap() ); + QPainter qPainter( &qPixmap ); + QRect qRect( 0, 0, pWidget->width(), pWidget->height() ); // Use the background of the widget qPixmap.fill( pWidget, QPoint(0, 0) ); @@ -512,15 +553,7 @@ bool WidgetPainter::drawStyledWidget( QWidget *pWidget, { // Bitblt from the screen, because the radio buttons are usually not // rectangular, and there could be a bitmap under them - GC aTmpGC = XCreateGC( dpy, qPixmap.handle(), 0, NULL ); - X11SalGraphics::CopyScreenArea( - dpy, - drawable, nXScreen, nDepth, - qPixmap.handle(), SalX11Screen( qPixmap.x11Screen() ), qPixmap.x11Depth(), - aTmpGC, - qWidgetPos.x(), qWidgetPos.y(), qRect.width(), qRect.height(), - 0, 0 ); - XFreeGC( dpy, aTmpGC ); + pGraphics->FillPixmapFromScreen( &xPixmap, qWidgetPos.x(), qWidgetPos.y() ); QApplication::style().drawControl( QStyle::CE_RadioButton, &qPainter, pWidget, qRect, @@ -819,12 +852,7 @@ bool WidgetPainter::drawStyledWidget( QWidget *pWidget, return false; // Bitblt it to the screen - X11SalGraphics::CopyScreenArea( - dpy, qPixmap.handle(), SalX11Screen( qPixmap.x11Screen() ), qPixmap.x11Depth(), - drawable, nXScreen, nDepth, - gc, - 0, 0, qRect.width(), qRect.height(), - qWidgetPos.x(), qWidgetPos.y() ); + pGraphics->RenderPixmapToScreen( xPixmap, qWidgetPos.x(), qWidgetPos.y() ); // Restore widget's position pWidget->move( qWidgetPos ); @@ -1381,122 +1409,101 @@ bool KDESalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, { bool bReturn = false; - Display *dpy = GetXDisplay(); - ::Window drawable = GetDrawable(); - // TODO: moggi: FIX that properly!! It was SelectPen() - GC gc = GetFontGC(); //SelectFont(); // GC with current clipping region set - if ( (nType == CTRL_PUSHBUTTON) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->pushButton( rControlRegion, (nState & CTRL_STATE_DEFAULT) ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_RADIOBUTTON) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->radioButton( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_CHECKBOX) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->checkBox( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_COMBOBOX) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->comboBox( rControlRegion, true ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_EDITBOX) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->lineEdit( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_LISTBOX) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->comboBox( rControlRegion, false ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_LISTBOX) && (nPart == PART_WINDOW) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->listView( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_SPINBOX) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->spinWidget( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType==CTRL_TAB_ITEM) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->tabBar( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType==CTRL_TAB_PANE) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->tabWidget( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_SCROLLBAR) && (nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->scrollBar( rControlRegion, nPart == PART_DRAW_BACKGROUND_HORZ, aValue ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_TOOLBAR) && (nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT || nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->toolBar( rControlRegion, nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_THUMB_VERT ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, nPart ); + nState, aValue, this, nPart ); } else if ( (nType == CTRL_TOOLBAR) && (nPart == PART_BUTTON) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->toolButton( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, nPart ); + nState, aValue, this, nPart ); } else if ( (nType == CTRL_MENUBAR) && (nPart == PART_ENTIRE_CONTROL || nPart == PART_MENU_ITEM) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->menuBar( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, nPart ); + nState, aValue, this, nPart ); } else if ( (nType == CTRL_MENU_POPUP) && (nPart == PART_ENTIRE_CONTROL || nPart == PART_MENU_ITEM) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->popupMenu( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } else if ( (nType == CTRL_PROGRESS) && (nPart == PART_ENTIRE_CONTROL) ) { bReturn = pWidgetPainter->drawStyledWidget( pWidgetPainter->progressBar( rControlRegion ), - nState, aValue, - dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); + nState, aValue, this ); } return bReturn; commit ec5fa3c9073db79489d8eba1eb8a09029b699e3f Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Thu Nov 13 09:32:41 2014 -0500 vcl: Replace GetPixmapFromScreen by FillPixmapFromScreen Conflicts: vcl/unx/generic/gdi/gdiimpl.cxx vcl/unx/generic/gdi/salgdi2.cxx Change-Id: I2cb960d194ee5bc38beece97e8b21cc6fa3b3fbc diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk index 73e5d01..76be2c1 100644 --- a/vcl/Library_vclplug_gen.mk +++ b/vcl/Library_vclplug_gen.mk @@ -94,7 +94,6 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\ vcl/unx/generic/gdi/x11cairotextrender \ vcl/unx/generic/gdi/gcach_xpeer \ vcl/unx/generic/gdi/gdiimpl \ - vcl/unx/generic/gdi/pixmap \ vcl/unx/generic/gdi/openglx11cairotextrender \ vcl/unx/generic/gdi/salbmp \ vcl/unx/generic/gdi/salgdi2 \ diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx index 878c7c2..00eaf8c 100644 --- a/vcl/inc/opengl/x11/gdiimpl.hxx +++ b/vcl/inc/opengl/x11/gdiimpl.hxx @@ -33,7 +33,7 @@ public: // implementation of X11GraphicsImpl void Init() SAL_OVERRIDE; - X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) SAL_OVERRIDE; + bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE; bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE; }; diff --git a/vcl/inc/unx/pixmap.hxx b/vcl/inc/unx/pixmap.hxx index b65170f..ec3c932 100644 --- a/vcl/inc/unx/pixmap.hxx +++ b/vcl/inc/unx/pixmap.hxx @@ -19,27 +19,25 @@ class VCLPLUG_GEN_PUBLIC X11Pixmap { public: - X11Pixmap(); - X11Pixmap( Display *pDisplay, SalX11Screen nScreen, int nWidth, int nHeight, int nDepth ); - X11Pixmap( X11Pixmap& rOther ); - virtual ~X11Pixmap(); + X11Pixmap( int nWidth, int nHeight ) + { + mnWidth = nWidth; + mnHeight = nHeight; + } - Pixmap GetPixmap() const { return mpPixmap; }; - Drawable GetDrawable() const { return mpPixmap; }; + virtual ~X11Pixmap() {}; + + virtual int GetDepth() const = 0; + virtual SalX11Screen GetScreen() const = 0; + virtual Pixmap GetPixmap() const = 0; + Drawable GetDrawable() const { return GetPixmap(); }; int GetWidth() const { return mnWidth; }; int GetHeight() const { return mnHeight; }; Size GetSize() const { return Size( mnWidth, mnHeight ); }; - int GetDepth() const { return mnDepth; }; - SalX11Screen GetScreen() const { return mnScreen; } protected: - Display* mpDisplay; - SalX11Screen mnScreen; - Pixmap mpPixmap; - bool mbDeletePixmap; int mnWidth; int mnHeight; - int mnDepth; }; #endif // INCLUDED_VCL_INC_UNX_PIXMAP_HXX diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index f693ed1..f14eab6 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -273,8 +273,8 @@ public: virtual void BeginPaint() SAL_OVERRIDE; virtual void EndPaint() SAL_OVERRIDE; - // create a pixmap from a screen region - X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ); + // fill a pixmap from a screen region + bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ); // render a pixmap to the screen bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ); diff --git a/vcl/inc/unx/x11/x11gdiimpl.h b/vcl/inc/unx/x11/x11gdiimpl.h index 911ea71..8cd130d 100644 --- a/vcl/inc/unx/x11/x11gdiimpl.h +++ b/vcl/inc/unx/x11/x11gdiimpl.h @@ -18,7 +18,7 @@ public: virtual ~X11GraphicsImpl() {}; virtual void Init() = 0; - virtual X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) = 0; + virtual bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) = 0; virtual bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) = 0; }; diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx index 6a16b9f..3d242ac 100644 --- a/vcl/opengl/x11/gdiimpl.cxx +++ b/vcl/opengl/x11/gdiimpl.cxx @@ -80,42 +80,39 @@ void X11OpenGLSalGraphicsImpl::Init() } } -X11Pixmap* X11OpenGLSalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect ) +bool X11OpenGLSalGraphicsImpl::FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) { Display* pDisplay = mrParent.GetXDisplay(); SalX11Screen nScreen = mrParent.GetScreenNumber(); XVisualInfo aVisualInfo; - X11Pixmap* pPixmap; XImage* pImage; char* pData; - SAL_INFO( "vcl.opengl", "GetPixmapFromScreen" ); - // TODO: lfrb: Use context depth - pPixmap = new X11Pixmap( pDisplay, nScreen, rRect.GetWidth(), rRect.GetHeight(), 24 ); + SAL_INFO( "vcl.opengl", "FillPixmapFromScreen" ); if( !OpenGLHelper::GetVisualInfo( pDisplay, nScreen.getXScreen(), aVisualInfo ) ) - return pPixmap; + return false; // make sure everything is synced up before reading back maContext.makeCurrent(); glXWaitX(); // TODO: lfrb: What if offscreen? - pData = (char*) malloc( rRect.GetWidth() * rRect.GetHeight() * 4 ); + pData = (char*) malloc( pPixmap->GetWidth() * pPixmap->GetHeight() * 4 ); glPixelStorei( GL_PACK_ALIGNMENT, 1 ); - glReadPixels( rRect.Left(), GetHeight() - rRect.Top(), rRect.GetWidth(), rRect.GetHeight(), + glReadPixels( nX, GetHeight() - nY, pPixmap->GetWidth(), pPixmap->GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pData ); pImage = XCreateImage( pDisplay, aVisualInfo.visual, 24, ZPixmap, 0, pData, - rRect.GetWidth(), rRect.GetHeight(), 8, 0 ); + pPixmap->GetWidth(), pPixmap->GetHeight(), 8, 0 ); XInitImage( pImage ); GC aGC = XCreateGC( pDisplay, pPixmap->GetPixmap(), 0, NULL ); XPutImage( pDisplay, pPixmap->GetDrawable(), aGC, pImage, - 0, 0, 0, 0, rRect.GetWidth(), rRect.GetHeight() ); + 0, 0, 0, 0, pPixmap->GetWidth(), pPixmap->GetHeight() ); XFreeGC( pDisplay, aGC ); XDestroyImage( pImage ); - return pPixmap; + return true; } bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index 0088028..ee7e596 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -159,19 +159,16 @@ void X11SalGraphicsImpl::Init() mnBrushPixel = mrParent.GetPixel( mnBrushColor ); } -X11Pixmap* X11SalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect ) +bool X11SalGraphicsImpl::FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) { //TODO lfrb: don't hardcode the depth Display* pDpy = mrParent.GetXDisplay(); - X11Pixmap* pPixmap = new X11Pixmap( pDpy, mrParent.GetScreenNumber(), - rRect.GetWidth(), rRect.GetHeight(), 24 ); GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL ); - if (!aTmpGC) + if( !aTmpGC ) { - delete pPixmap; - SAL_WARN( "vcl", "Could not get valid GC from screen" ); - return NULL; + SAL_WARN( "vcl", "Could not create GC from screen" ); + return false; } // Copy the background of the screen into a composite pixmap @@ -181,12 +178,11 @@ X11Pixmap* X11SalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect ) pPixmap->GetDrawable(), pPixmap->GetScreen(), pPixmap->GetDepth(), aTmpGC, - rRect.Left(), rRect.Top(), - rRect.GetWidth(), rRect.GetHeight(), + nX, nY, pPixmap->GetWidth(), pPixmap->GetHeight(), 0, 0 ); XFreeGC( pDpy, aTmpGC ); - return pPixmap; + return true; } bool X11SalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index fed9bc6..2d9294a 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -274,7 +274,7 @@ public: // implementation of X11GraphicsImpl void Init() SAL_OVERRIDE; - X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) SAL_OVERRIDE; + bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE; bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE; }; diff --git a/vcl/unx/generic/gdi/pixmap.cxx b/vcl/unx/generic/gdi/pixmap.cxx deleted file mode 100644 index 0440c46..0000000 --- a/vcl/unx/generic/gdi/pixmap.cxx +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "unx/pixmap.hxx" - -X11Pixmap::X11Pixmap() -: mpDisplay( NULL ) -, mnScreen( 0 ) -, mpPixmap( 0 ) -, mbDeletePixmap( false ) -, mnWidth( -1 ) -, mnHeight( -1 ) -, mnDepth( 0 ) -{ -} - -X11Pixmap::X11Pixmap( Display* pDisplay, SalX11Screen nScreen, int nWidth, int nHeight, int nDepth ) -: mpDisplay( pDisplay ) -, mnScreen( nScreen ) -, mbDeletePixmap( true ) -, mnWidth( nWidth ) -, mnHeight( nHeight ) -, mnDepth( nDepth ) -{ - Window root = RootWindow( pDisplay, 0 ); - mpPixmap = XCreatePixmap( pDisplay, root, nWidth, nHeight, nDepth ); -} - -X11Pixmap::X11Pixmap( X11Pixmap& rOther ) -: mpDisplay( rOther.mpDisplay ) -, mnScreen( rOther.mnScreen ) -, mbDeletePixmap( rOther.mbDeletePixmap ) -, mnWidth( rOther.mnWidth ) -, mnHeight( rOther.mnHeight ) -, mnDepth( rOther.mnDepth ) -{ - mpPixmap = rOther.mpPixmap; - rOther.mpPixmap = 0; - rOther.mbDeletePixmap = false; -} - -X11Pixmap::~X11Pixmap() -{ - if (mbDeletePixmap && mpPixmap) - XFreePixmap( mpDisplay, mpPixmap ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx index 768e596..9ef50b8 100644 --- a/vcl/unx/generic/gdi/salgdi2.cxx +++ b/vcl/unx/generic/gdi/salgdi2.cxx @@ -83,10 +83,10 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay, } } -X11Pixmap* X11SalGraphics::GetPixmapFromScreen( const Rectangle& rRect ) +bool X11SalGraphics::FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) { X11GraphicsImpl& rImpl = dynamic_cast<X11GraphicsImpl&>(*mpImpl.get()); - return rImpl.GetPixmapFromScreen( rRect ); + return rImpl.FillPixmapFromScreen( pPixmap, nX, nY ); } bool X11SalGraphics::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 9c11cd9..10cff10 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -269,49 +269,44 @@ class GdkX11Pixmap : public X11Pixmap { public: GdkX11Pixmap( int nWidth, int nHeight, int nDepth ); - GdkX11Pixmap( X11Pixmap& rOther, GdkWindow *pWindow ); virtual ~GdkX11Pixmap(); - GdkPixmap* GetGdkPixmap() const; - GdkDrawable* GetGdkDrawable() const; + virtual int GetDepth() const SAL_OVERRIDE; + virtual SalX11Screen GetScreen() const SAL_OVERRIDE; + virtual Pixmap GetPixmap() const SAL_OVERRIDE; + GdkPixmap* GetGdkPixmap() const; + GdkDrawable* GetGdkDrawable() const; protected: GdkPixmap* mpGdkPixmap; + int mnDepth; }; GdkX11Pixmap::GdkX11Pixmap( int nWidth, int nHeight, int nDepth ) +: X11Pixmap( nWidth, nHeight ) +, mnDepth( nDepth ) { mpGdkPixmap = gdk_pixmap_new( NULL, nWidth, nHeight, nDepth ); - - //mpDisplay = ? - mnScreen = SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(mpGdkPixmap) ) ) ); - mnWidth = nWidth; - mnHeight = nHeight; - mnDepth = nDepth; - mpPixmap = GDK_PIXMAP_XID( mpGdkPixmap ); } -GdkX11Pixmap::GdkX11Pixmap( X11Pixmap& rOther, GdkWindow *pWindow ) - : X11Pixmap(rOther) +GdkX11Pixmap::~GdkX11Pixmap() { - GdkColormap* pColormap; + g_object_unref( mpGdkPixmap ); +} -#if GTK_CHECK_VERSION(2,24,0) - GdkScreen *pScreen = gdk_window_get_screen( pWindow ); - mpGdkPixmap = gdk_pixmap_foreign_new_for_screen( pScreen, mpPixmap, - mnWidth, mnHeight, - mnDepth ); -#else - mpGdkPixmap = gdk_pixmap_foreign_new( mpPixmap ); -#endif +int GdkX11Pixmap::GetDepth() const +{ + return mnDepth; +} - pColormap = gdk_drawable_get_colormap( pWindow ); - gdk_drawable_set_colormap( GDK_DRAWABLE (mpGdkPixmap), pColormap ); +SalX11Screen GdkX11Pixmap::GetScreen() const +{ + return SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(mpGdkPixmap) ) ) ); } -GdkX11Pixmap::~GdkX11Pixmap() +Pixmap GdkX11Pixmap::GetPixmap() const { - g_object_unref( mpGdkPixmap ); + return GDK_PIXMAP_XID( mpGdkPixmap ); } GdkPixmap* GdkX11Pixmap::GetGdkPixmap() const @@ -4135,17 +4130,11 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) GdkX11Pixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect ) { - X11Pixmap* pPixmap; - GdkX11Pixmap* pResult; - - pPixmap = GetPixmapFromScreen( srcRect ); - if( pPixmap == NULL ) - return NULL; - - pResult = new GdkX11Pixmap( *pPixmap, GetGdkWindow() ); - delete pPixmap; + GdkX11Pixmap* pPixmap; - return pResult; + pPixmap = new GdkX11Pixmap( srcRect.GetWidth(), srcRect.GetHeight(), 24 ); + FillPixmapFromScreen( pPixmap, srcRect.Left(), srcRect.Top() ); + return pPixmap; } /************************************************************************ commit 7dc6fd3908f752c3552dfe34b1a3da6e485b5fd5 Author: Markus Mohrhard <[email protected]> Date: Sun Sep 7 20:31:21 2014 +0200 some formatting improvements Change-Id: I77f0fdea3c33fded1ed1a00d3a602a5902a6a0b3 diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index f873361..1f2e4a1 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -1282,16 +1282,17 @@ void ScInterpreter::CalculateAddSub(bool _bSub) pResMat->PutDouble( _bSub ? ::rtl::math::approxSub( fVal, pMat->GetDouble(i)) : ::rtl::math::approxAdd( pMat->GetDouble(i), fVal), i); else pResMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i); - } // for ( SCSIZE i = 0; i < nCount; i++ ) - } // if (bFlag || !_bSub ) + } + } else { for ( SCSIZE i = 0; i < nCount; i++ ) - { if (pMat->IsValue(i)) + { + if (pMat->IsValue(i)) pResMat->PutDouble( ::rtl::math::approxSub( pMat->GetDouble(i), fVal), i); else pResMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), i); - } // for ( SCSIZE i = 0; i < nCount; i++ ) + } } PushMatrix(pResMat); }
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
