[Libreoffice-commits] core.git: Branch 'feature/opengl-vcl' - 10 commits - include/vcl vcl/inc vcl/Library_vcl.mk vcl/Module_vcl.mk vcl/opengl vcl/Package_opengl.mk vcl/source vcl/unx
Markus Mohrhard
markus.mohrhard at collabora.co.uk
Mon Nov 3 19:55:11 PST 2014
include/vcl/opengl/OpenGLContext.hxx | 2
vcl/Library_vcl.mk | 1
vcl/Module_vcl.mk | 1
vcl/Package_opengl.mk | 23
vcl/inc/opengl/salbmp.hxx | 90 +++
vcl/inc/openglgdiimpl.hxx | 51 ++
vcl/inc/salgdiimpl.hxx | 3
vcl/opengl/gdiimpl.cxx | 646 ++++++++++++++++++++++++++--
vcl/opengl/maskFragmentShader.glsl | 21
vcl/opengl/maskVertexShader.glsl | 19
vcl/opengl/maskedTextureFragmentShader.glsl | 22
vcl/opengl/maskedTextureVertexShader.glsl | 19
vcl/opengl/salbmp.cxx | 521 ++++++++++++++++++++++
vcl/opengl/solidFragmentShader.glsl | 17
vcl/opengl/solidVertexShader.glsl | 16
vcl/opengl/textureFragmentShader.glsl | 18
vcl/opengl/textureVertexShader.glsl | 19
vcl/source/opengl/OpenGLContext.cxx | 9
vcl/unx/generic/gdi/gdiimpl.cxx | 6
vcl/unx/generic/gdi/gdiimpl.hxx | 2
vcl/unx/generic/gdi/salbmp.cxx | 8
vcl/unx/generic/gdi/salgdi.cxx | 21
22 files changed, 1479 insertions(+), 56 deletions(-)
New commits:
commit 1931334a0f4ae604467c649eb7d0bcd5d4d85614
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date: Tue Nov 4 04:55:44 2014 +0100
fix signed/unsigned comparison warning
Change-Id: I0d1ce56514ff9dfff620f11cf987d6d53c4be5e4
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index 84ada34..5edeed8 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -190,7 +190,7 @@ bool OpenGLSalBitmap::AllocateUserData()
#ifdef DBG_UTIL
else
{
- for (size_t i = 0; i < mnBytesPerRow * mnHeight; i++)
+ for (size_t i = 0; i < size_t(mnBytesPerRow * mnHeight); i++)
maUserBuffer.get()[i] = (i & 0xFF);
}
#endif
commit a2c4dc3d0e4adf85ba1dcbfab68c318b6d637ead
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Mon Nov 3 11:10:14 2014 -0500
vcl: Fix the vertices calculations for some drawing operations
Change-Id: Ida92d77d7f828f5ff53e7cceaf4787beeef0022b
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 65cff6a..d79bce0 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -257,33 +257,32 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
{
- GLushort pPoints[4];
+ GLfloat pPoints[4];
- pPoints[0] = nX1;
- pPoints[1] = nY1;
- pPoints[2] = nX2;
- pPoints[3] = nY2;
+ pPoints[0] = (2 * nX1) / GetWidth() - 1.0;
+ pPoints[1] = (2 * nY1) / GetHeight() - 1.0;
+ pPoints[2] = (2 * nX2) / GetWidth() - 1.0;;
+ pPoints[3] = (2 * nY2) / GetHeight() - 1.0;
glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 4, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pPoints );
glDrawArrays( GL_LINES, 0, 2 );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
{
- GLushort *pPoints;
+ GLfloat pPoints[nPoints * 2];
sal_uInt32 i, j;
- pPoints = new GLushort[nPoints * 2];
- for( i = 0, j = 0; i < nPoints; i++, j += 2 )
+ for( i = 0, j = 0; i < nPoints; i++ )
{
- pPoints[j] = pPtAry[i].mnX;
- pPoints[j+1] = pPtAry[i].mnY;
+ pPoints[j++] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0;
+ pPoints[j++] = (2 * pPtAry[i].mnY) / GetHeight() - 1.0;
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints );
+ glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_FLOAT, GL_FALSE, 0, pPoints );
if( bClose )
glDrawArrays( GL_LINE_LOOP, 0, nPoints );
else
@@ -293,7 +292,7 @@ void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAr
void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
- GLushort pVertices[nPoints * 2];
+ GLfloat pVertices[nPoints * 2];
sal_uInt32 i, j;
for( i = 0, j = 0; i < nPoints; i++, j += 2 )
@@ -303,7 +302,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pVertices );
glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
@@ -312,8 +311,8 @@ void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeigh
{
long nX1( nX );
long nY1( nY );
- long nX2( nX + nWidth - 1 );
- long nY2( nY + nHeight - 1 );
+ long nX2( nX + nWidth );
+ long nY2( nY + nHeight );
const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
{ nX2, nY1 }, { nX2, nY2 }};
@@ -350,7 +349,7 @@ void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPt
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, aResult.count() * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices );
glDrawArrays( GL_TRIANGLES, 0, aResult.count() );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
@@ -367,16 +366,16 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPol
const ::basegfx::B2DPolygon& aResult(
::basegfx::triangulator::triangulate( pPolygon ) );
- for( j = 0; i < aResult.count(); j++ )
+ for( j = 0; j < aResult.count(); j++ )
{
- const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) );
+ const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint( j ) );
pVertices.push_back( rPt.getX() );
pVertices.push_back( rPt.getY() );
}
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.data() );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.data() );
glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
@@ -386,7 +385,7 @@ void OpenGLSalGraphicsImpl::DrawTextureRect( const SalTwoRect& pPosAry )
GLushort aTexCoord[8];
glEnableVertexAttribArray( GL_ATTRIB_TEX );
- glVertexAttribPointer( GL_ATTRIB_TEX, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord );
+ glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord );
DrawRect( pPosAry.mnDestX, pPosAry.mnDestY, pPosAry.mnDestWidth, pPosAry.mnDestHeight );
commit 1b057679da586254d3ec8960ea70ee3e101669e9
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Mon Nov 3 11:08:24 2014 -0500
vcl: Get the OpenGL window size from the frame
Change-Id: Id1b62d1982e56ef073ebb4ab800356d4dee3d742
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index cad2c4d..6643546 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -25,11 +25,14 @@
#include <vcl/opengl/OpenGLContext.hxx>
+class SalFrame;
+
class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
{
private:
OpenGLContext maContext;
+ SalFrame* mpFrame;
SalColor mnLineColor;
SalColor mnFillColor;
@@ -84,6 +87,8 @@ public:
virtual void freeResources() SAL_OVERRIDE;
+ virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE;
+
virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
//
// get the depth of the device
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index ed4f4ba..9802a7b 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -34,6 +34,7 @@
class SalGraphics;
class SalBitmap;
+class SalFrame;
class Gradient;
class VCL_PLUGIN_PUBLIC SalGraphicsImpl
@@ -42,6 +43,8 @@ public:
virtual ~SalGraphicsImpl();
+ virtual void Init( SalFrame* pFrame ) = 0;
+
virtual void freeResources() = 0;
virtual bool setClipRegion( const vcl::Region& ) = 0;
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 528b1d5..65cff6a 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -20,6 +20,7 @@
#include "openglgdiimpl.hxx"
#include <vcl/gradient.hxx>
+#include <salframe.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygontriangulator.hxx>
@@ -45,6 +46,11 @@ void OpenGLSalGraphicsImpl::freeResources()
// Delete shaders, programs and textures if not shared
}
+void OpenGLSalGraphicsImpl::Init( SalFrame* pFrame )
+{
+ mpFrame = pFrame;
+}
+
bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
{
const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() );
@@ -77,17 +83,21 @@ sal_uInt16 OpenGLSalGraphicsImpl::GetBitCount() const
// get the width of the device
long OpenGLSalGraphicsImpl::GetGraphicsWidth() const
{
- return maContext.getOpenGLWindow().Width;
+ return GetWidth();
}
inline GLfloat OpenGLSalGraphicsImpl::GetWidth() const
{
- return maContext.getOpenGLWindow().Width;
+ if( mpFrame )
+ return mpFrame->maGeometry.nWidth;
+ return 0;
}
inline GLfloat OpenGLSalGraphicsImpl::GetHeight() const
{
- return maContext.getOpenGLWindow().Height;
+ if( mpFrame )
+ return mpFrame->maGeometry.nHeight;
+ return 0;
}
// set the clip region to empty
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 508bf0b..f1686e3 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -540,10 +540,10 @@ bool OpenGLContext::init(HDC hDC, HWND hWnd)
bool OpenGLContext::ImplInit()
{
SAL_INFO("vcl.opengl", "OpenGLContext::ImplInit----start");
- if(m_pWindow)
+ /*if(m_pWindow)
m_pWindow->setPosSizePixel(0,0,0,0);
m_aGLWin.Width = 0;
- m_aGLWin.Height = 0;
+ m_aGLWin.Height = 0;*/
#if defined( WNT )
#elif defined( MACOSX )
@@ -683,6 +683,11 @@ bool OpenGLContext::ImplInit()
m_aGLWin.GLExtensions = glGetString( GL_EXTENSIONS );
SAL_INFO("vcl.opengl", "available GL extensions: " << m_aGLWin.GLExtensions);
+ XWindowAttributes xWinAttr;
+ XGetWindowAttributes( m_aGLWin.dpy, m_aGLWin.win, &xWinAttr );
+ m_aGLWin.Width = xWinAttr.width;
+ m_aGLWin.Height = xWinAttr.height;
+
if( m_aGLWin.HasGLXExtension("GLX_SGI_swap_control" ) )
{
// enable vsync
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
index 60ed793..6b90220 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -153,6 +153,12 @@ X11SalGraphicsImpl::~X11SalGraphicsImpl()
{
}
+void X11SalGraphicsImpl::Init( SalFrame* /*pFrame*/ )
+{
+ mnPenPixel = mrParent.GetPixel( mnPenColor );
+ mnBrushPixel = mrParent.GetPixel( mnBrushColor );
+}
+
XID X11SalGraphicsImpl::GetXRenderPicture()
{
XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx
index a6e12ec..e81d16e 100644
--- a/vcl/unx/generic/gdi/gdiimpl.hxx
+++ b/vcl/unx/generic/gdi/gdiimpl.hxx
@@ -108,6 +108,8 @@ public:
virtual ~X11SalGraphicsImpl();
+ virtual void Init( SalFrame* pFrame ) SAL_OVERRIDE;
+
virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
//
// get the depth of the device
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index c5dd0be..97e060e 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -148,22 +148,15 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
if( hDrawable_ )
{
- X11SalGraphicsImpl* pImpl = dynamic_cast<X11SalGraphicsImpl*>(mpImpl.get());
- if (pImpl)
+ OpenGLSalGraphicsImpl* pOpenGLImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get());
+ if (pOpenGLImpl && m_pFrame && dynamic_cast<X11WindowProvider*>(m_pFrame))
{
- pImpl->mnPenPixel = GetPixel( pImpl->mnPenColor );
- pImpl->mnBrushPixel = GetPixel( pImpl->mnBrushColor );
- }
- else
- {
- OpenGLSalGraphicsImpl* pOpenGLImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get());
- if (pOpenGLImpl && m_pFrame && dynamic_cast<X11WindowProvider*>(m_pFrame))
- {
- Window aWin = dynamic_cast<X11WindowProvider*>(m_pFrame)->GetX11Window();
- pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(),
- aWin, m_nXScreen.getXScreen());
- }
+ Window aWin = dynamic_cast<X11WindowProvider*>(m_pFrame)->GetX11Window();
+ pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(),
+ aWin, m_nXScreen.getXScreen());
}
+
+ mpImpl->Init( m_pFrame );
nTextPixel_ = GetPixel( nTextColor_ );
}
}
commit f5997bb5089a26fddb5556d487a75a31d39e0010
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Thu Oct 30 22:01:25 2014 -0400
vcl: Remove the extra colon at the end of shader
Change-Id: I0a1a2346176a9f2f4d62ca80a9485d720b522cef
diff --git a/vcl/opengl/solidVertexShader.glsl b/vcl/opengl/solidVertexShader.glsl
index c3de9c5..47061f6 100644
--- a/vcl/opengl/solidVertexShader.glsl
+++ b/vcl/opengl/solidVertexShader.glsl
@@ -10,7 +10,7 @@
attribute vec4 position;
void main() {
gl_Position = position;
-};
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 4c5b3d836b5fb71cc492a66643e6ac3151c2bf3c
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Thu Oct 30 22:00:37 2014 -0400
vcl: Add OpenGLSalBitmap implementation
Change-Id: I0deebaedf6fe5b23f50a448eea0d5d9e99ebd391
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 8580701..c085df8 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -123,6 +123,7 @@ $(eval $(call gb_Library_use_externals,vcl,\
$(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/opengl/gdiimpl \
+ vcl/opengl/salbmp \
vcl/source/opengl/OpenGLContext \
vcl/source/opengl/OpenGLHelper \
vcl/source/window/openglwin \
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
new file mode 100644
index 0000000..5661e56
--- /dev/null
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -0,0 +1,90 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_SALBMP_H
+#define INCLUDED_VCL_INC_OPENGL_SALBMP_H
+
+#include <basebmp/bitmapdevice.hxx>
+#include <vcl/opengl/OpenGLContext.hxx>
+
+#include "vcl/salbtype.hxx"
+
+#include <salbmp.hxx>
+
+// - SalBitmap -
+
+struct BitmapBuffer;
+class BitmapPalette;
+
+class VCL_PLUGIN_PUBLIC OpenGLSalBitmap : public SalBitmap
+{
+private:
+ OpenGLContext* mpContext;
+ GLuint mnTexture;
+ bool mbDirtyTexture;
+ BitmapPalette maPalette;
+ basebmp::RawMemorySharedArray maUserBuffer;
+ sal_uInt16 mnBits;
+ sal_uInt16 mnBytesPerRow;
+ int mnWidth;
+ int mnHeight;
+
+public:
+ OpenGLSalBitmap();
+ virtual ~OpenGLSalBitmap();
+
+public:
+
+ // SalBitmap methods
+ bool Create( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal ) SAL_OVERRIDE;
+ bool Create( const SalBitmap& rSalBmp ) SAL_OVERRIDE;
+ bool Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics ) SAL_OVERRIDE;
+ bool Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount ) SAL_OVERRIDE;
+ virtual bool Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
+ Size& rSize,
+ bool bMask = false ) SAL_OVERRIDE;
+
+ void Destroy() SAL_OVERRIDE;
+
+ Size GetSize() const SAL_OVERRIDE;
+ sal_uInt16 GetBitCount() const SAL_OVERRIDE;
+
+ BitmapBuffer *AcquireBuffer( bool bReadOnly ) SAL_OVERRIDE;
+ void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE;
+
+ bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE;
+
+public:
+
+ bool Create( OpenGLContext& rContext, long nX, long nY, long nWidth, long nHeight );
+ bool Draw( OpenGLContext& rContext, const SalTwoRect& rPosAry );
+ GLuint GetTexture( OpenGLContext& rContext ) const;
+
+private:
+
+ GLuint CreateTexture();
+ void DeleteTexture();
+ void DrawTexture( GLuint nTexture, const SalTwoRect& rPosAry );
+ bool AllocateUserData();
+ bool ReadTexture();
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_SALBMP_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 8bb31b0..528b1d5 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -24,6 +24,7 @@
#include <basegfx/polygon/b2dpolygontriangulator.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
+#include "opengl/salbmp.hxx"
#define GL_ATTRIB_POS 0
#define GL_ATTRIB_TEX 1
@@ -654,8 +655,9 @@ void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* /*
void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
{
const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
- GLuint nTexture = rBitmap.GetTexture();
+ GLuint nTexture = rBitmap.GetTexture( maContext );
+ SAL_INFO( "vcl.opengl", "::drawBitmap" );
maContext.makeCurrent();
DrawTexture( nTexture, rPosAry );
}
@@ -675,9 +677,10 @@ void OpenGLSalGraphicsImpl::drawBitmap(
{
const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
const OpenGLSalBitmap& rMask = static_cast<const OpenGLSalBitmap&>(rMaskBitmap);
- const GLuint nTexture( rBitmap.GetTexture() );
- const GLuint nMask( rMask.GetTexture() );
+ const GLuint nTexture( rBitmap.GetTexture( maContext ) );
+ const GLuint nMask( rMask.GetTexture( maContext ) );
+ SAL_INFO( "vcl.opengl", "::drawBitmap" );
maContext.makeCurrent();
DrawTextureWithMask( nTexture, nMask, rPosAry );
}
@@ -688,22 +691,16 @@ void OpenGLSalGraphicsImpl::drawMask(
SalColor nMaskColor )
{
const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
- const GLuint nTexture( rBitmap.GetTexture() );
+ const GLuint nTexture( rBitmap.GetTexture( maContext ) );
+ maContext.makeCurrent();
DrawMask( nTexture, nMaskColor, rPosAry );
}
SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long nHeight )
{
- GLuint nTexture;
-
- /*glGenTexture( 1, &nTexture );
- glBindTexture( GL_TEXTURE_2D, nTexture );
- glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, nX, nY, nWidth, nHeight, 0 );
- glBindTexture( GL_TEXTURE_2D, 0 );*/
-
OpenGLSalBitmap* pBitmap = new OpenGLSalBitmap;
- if( !pBitmap->Create( nX, nY, nWidth, nHeight ) )
+ if( !pBitmap->Create( maContext, nX, nY, nWidth, nHeight ) )
{
delete pBitmap;
pBitmap = NULL;
@@ -796,8 +793,8 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
{
const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
const OpenGLSalBitmap& rAlpha = static_cast<const OpenGLSalBitmap&>(rAlphaBitmap);
- const GLuint nTexture( rBitmap.GetTexture() );
- const GLuint nAlpha( rAlpha.GetTexture() );
+ const GLuint nTexture( rBitmap.GetTexture( maContext ) );
+ const GLuint nAlpha( rAlpha.GetTexture( maContext ) );
maContext.makeCurrent();
DrawTextureWithMask( nTexture, nAlpha, rPosAry );
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
new file mode 100644
index 0000000..84ada34
--- /dev/null
+++ b/vcl/opengl/salbmp.cxx
@@ -0,0 +1,521 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+#include "vcl/bitmap.hxx"
+#include "vcl/salbtype.hxx"
+#include "salgdi.hxx"
+
+#include "opengl/salbmp.hxx"
+#include "unx/salbmp.h"
+
+static bool isValidBitCount( sal_uInt16 nBitCount )
+{
+ return (nBitCount == 1) || (nBitCount == 4) || (nBitCount == 8) || (nBitCount == 16) || (nBitCount == 24) || (nBitCount == 32);
+}
+
+OpenGLSalBitmap::OpenGLSalBitmap()
+: mnTexture(0)
+, mbDirtyTexture(true)
+, mnBits(0)
+, mnBytesPerRow(0)
+, mnWidth(0)
+, mnHeight(0)
+{
+}
+
+OpenGLSalBitmap::~OpenGLSalBitmap()
+{
+ Destroy();
+}
+
+bool OpenGLSalBitmap::Create( OpenGLContext& rContext, long nX, long nY, long nWidth, long nHeight )
+{
+ static const BitmapPalette aEmptyPalette;
+
+ Destroy();
+
+ mpContext = &rContext;
+ mpContext->makeCurrent();
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+
+ // TODO Check the framebuffer configuration
+ mnBits = 32;
+ maPalette = aEmptyPalette;
+
+ glGenTextures( 1, &mnTexture );
+ glBindTexture( GL_TEXTURE_2D, mnTexture );
+ glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nX, nY, nWidth, nHeight, 0 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+
+ return true;
+}
+
+bool OpenGLSalBitmap::Create( const Size& rSize, sal_uInt16 nBits, const BitmapPalette& rBitmapPalette )
+{
+ Destroy();
+
+ if( !isValidBitCount( nBits ) )
+ return false;
+ maPalette = rBitmapPalette;
+ mnBits = nBits;
+ mnWidth = rSize.Width();
+ mnHeight = rSize.Height();
+ return false;
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp )
+{
+ return Create( rSalBmp, rSalBmp.GetBitCount() );
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+ return Create( rSalBmp, pGraphics ? pGraphics->GetBitCount() : rSalBmp.GetBitCount() );
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount )
+{
+ const OpenGLSalBitmap& rSourceBitmap = static_cast<const OpenGLSalBitmap&>(rSalBmp);
+
+ if( isValidBitCount( nNewBitCount ) )
+ {
+ mnBits = nNewBitCount;
+ mnWidth = rSourceBitmap.mnWidth;
+ mnHeight = rSourceBitmap.mnHeight;
+ maPalette = rSourceBitmap.maPalette;
+ mnTexture = rSourceBitmap.mnTexture;
+
+ // TODO Copy buffer data if the bitcount and palette are the same
+ return true;
+ }
+ return false;
+}
+
+bool OpenGLSalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
+{
+ // TODO Is this method needed?
+ return false;
+}
+
+bool OpenGLSalBitmap::Draw( OpenGLContext& rContext, const SalTwoRect& rPosAry )
+{
+ if( !mpContext )
+ mpContext = &rContext;
+
+ if( !mnTexture || 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( !mnTexture || mbDirtyTexture )
+ const_cast<OpenGLSalBitmap*>(this)->CreateTexture();
+ return mnTexture;
+}
+
+void OpenGLSalBitmap::Destroy()
+{
+ DeleteTexture();
+ maUserBuffer.reset();
+}
+
+bool OpenGLSalBitmap::AllocateUserData()
+{
+ Destroy();
+
+ if( mnWidth && mnHeight )
+ {
+ mnBytesPerRow = 0;
+
+ switch( mnBits )
+ {
+ case 1: mnBytesPerRow = (mnWidth + 7) >> 3; break;
+ case 4: mnBytesPerRow = (mnWidth + 1) >> 1; break;
+ case 8: mnBytesPerRow = mnWidth; break;
+ case 16: mnBytesPerRow = mnWidth << 1; break;
+ case 24: mnBytesPerRow = (mnWidth << 1) + mnWidth; break;
+ case 32: mnBytesPerRow = mnWidth << 2; break;
+ default:
+ OSL_FAIL("vcl::OpenGLSalBitmap::AllocateUserData(), illegal bitcount!");
+ }
+ }
+
+ bool alloc = false;
+ if (mnBytesPerRow != 0
+ && mnBytesPerRow <= std::numeric_limits<sal_uInt32>::max() / mnHeight)
+ {
+ try
+ {
+ maUserBuffer.reset( new sal_uInt8[mnBytesPerRow * mnHeight] );
+ alloc = true;
+ }
+ catch (std::bad_alloc &) {}
+ }
+ if (!alloc)
+ {
+ SAL_WARN(
+ "vcl.opengl", "bad alloc " << mnBytesPerRow << "x" << mnHeight);
+ maUserBuffer.reset( static_cast<sal_uInt8*>(NULL) );
+ mnBytesPerRow = 0;
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ for (size_t i = 0; i < mnBytesPerRow * mnHeight; i++)
+ maUserBuffer.get()[i] = (i & 0xFF);
+ }
+#endif
+
+ return maUserBuffer.get() != 0;
+}
+
+class ImplPixelFormat
+{
+protected:
+ sal_uInt8* mpData;
+public:
+ static ImplPixelFormat* GetFormat( sal_uInt16 nBits, const BitmapPalette& rPalette );
+
+ virtual void StartLine( sal_uInt8* pLine ) { mpData = pLine; }
+ virtual const BitmapColor& ReadPixel() = 0;
+ virtual ~ImplPixelFormat() { }
+};
+
+class ImplPixelFormat8 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+
+public:
+ ImplPixelFormat8( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+ {
+ return mrPalette[ *mpData++ ];
+ }
+};
+
+class ImplPixelFormat4 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+ sal_uInt32 mnX;
+ sal_uInt32 mnShift;
+
+public:
+ ImplPixelFormat4( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual void StartLine( sal_uInt8* pLine ) SAL_OVERRIDE
+ {
+ mpData = pLine;
+ mnX = 0;
+ mnShift = 4;
+ }
+ virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+ {
+ const BitmapColor& rColor = mrPalette[( mpData[mnX >> 1] >> mnShift) & 0x0f];
+ mnX++;
+ mnShift ^= 4;
+ return rColor;
+ }
+};
+
+class ImplPixelFormat1 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+ sal_uInt32 mnX;
+
+public:
+ ImplPixelFormat1( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual void StartLine( sal_uInt8* pLine ) SAL_OVERRIDE
+ {
+ mpData = pLine;
+ mnX = 0;
+ }
+ virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+ {
+ const BitmapColor& rColor = mrPalette[ (mpData[mnX >> 3 ] >> ( 7 - ( mnX & 7 ) )) & 1];
+ mnX++;
+ return rColor;
+ }
+};
+
+ImplPixelFormat* ImplPixelFormat::GetFormat( sal_uInt16 nBits, const BitmapPalette& rPalette )
+{
+ switch( nBits )
+ {
+ case 1: return new ImplPixelFormat1( rPalette );
+ case 4: return new ImplPixelFormat4( rPalette );
+ case 8: return new ImplPixelFormat8( rPalette );
+ }
+
+ return 0;
+}
+
+Size OpenGLSalBitmap::GetSize() const
+{
+ return Size( mnWidth, mnHeight );
+}
+
+GLuint OpenGLSalBitmap::CreateTexture()
+{
+ GLenum nFormat, nType;
+ sal_uInt8* pData( NULL );
+ bool bAllocated( false );
+
+ if( maUserBuffer.get() != 0 )
+ {
+ if( mnBits == 16 || mnBits == 24 || mnBits == 32 )
+ {
+ // no conversion needed for truecolor
+ pData = maUserBuffer.get();
+
+ switch( mnBits )
+ {
+ case 16: nFormat = GL_RGB;
+ nType = GL_UNSIGNED_SHORT_5_6_5;
+ break;
+ case 24: nFormat = GL_RGB;
+ nType = GL_UNSIGNED_BYTE;
+ break;
+ case 32: nFormat = GL_RGBA;
+ nType = GL_UNSIGNED_BYTE;
+ break;
+ }
+ }
+ else if( mnBits == 8 && maPalette.IsGreyPalette() )
+ {
+ // no conversion needed for grayscale
+ pData = maUserBuffer.get();
+ nFormat = GL_LUMINANCE;
+ nType = GL_UNSIGNED_BYTE;
+ }
+ else
+ {
+ // convert to 32 bits RGBA using palette
+ pData = new sal_uInt8[ mnHeight * (mnWidth << 2) ];
+ bAllocated = true;
+ nFormat = GL_RGBA;
+ nType = GL_UNSIGNED_BYTE;
+
+ ImplPixelFormat* pSrcFormat = ImplPixelFormat::GetFormat( mnBits, maPalette );
+ sal_uInt8* pSrcData = maUserBuffer.get();
+ sal_uInt8* pDstData = pData;
+
+ sal_uInt32 nY = mnHeight;
+ while( nY-- )
+ {
+ pSrcFormat->StartLine( pSrcData );
+
+ sal_uInt32 nX = mnWidth;
+ while( nX-- )
+ {
+ const BitmapColor& c = pSrcFormat->ReadPixel();
+
+ *pDstData++ = c.GetRed();
+ *pDstData++ = c.GetGreen();
+ *pDstData++ = c.GetBlue();
+ *pDstData++ = 255;
+ }
+
+ pSrcData += mnBytesPerRow;
+ }
+ }
+ }
+
+ mpContext->makeCurrent();
+ if( !mnTexture )
+ glGenTextures( 1, &mnTexture );
+ glBindTexture( GL_TEXTURE_2D, mnTexture );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, mnWidth, mnHeight, 0, nFormat, nType, pData );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+
+ if( bAllocated )
+ delete pData;
+
+ mbDirtyTexture = false;
+ return mnTexture;
+}
+
+void OpenGLSalBitmap::DeleteTexture()
+{
+ if( mnTexture )
+ {
+ mpContext->makeCurrent();
+ glDeleteTextures( 1, &mnTexture );
+ mnTexture = 0;
+ }
+}
+
+void OpenGLSalBitmap::DrawTexture( GLuint nTexture, const SalTwoRect& /*rPosAry*/ )
+{
+ GLushort aTexCoord[8];
+ GLushort aVertices[8];
+
+ /*if( mnTextureProgram == 0 )
+ {
+ if( !CreateTextureProgram() )
+ return;
+ }*/
+
+ //glUseProgram( mnTextureProgram );
+ //glUniform1i( mnSamplerUniform, 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, nTexture );
+ glEnableVertexAttribArray( 0 );
+ glVertexAttribPointer( 0, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord );
+ glEnableVertexAttribArray( 1 );
+ glVertexAttribPointer( 1, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aVertices );
+ glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+ glDisableVertexAttribArray( 0 );
+ glDisableVertexAttribArray( 1 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glUseProgram( 0 );
+}
+
+bool OpenGLSalBitmap::ReadTexture()
+{
+ SalTwoRect aPosAry;
+ GLuint nFramebufferId, nRenderbufferDepthId, nRenderbufferColorId;
+ sal_uInt8* pData = maUserBuffer.get();
+
+ mpContext->makeCurrent();
+ OpenGLHelper::createFramebuffer( mnWidth, mnHeight, nFramebufferId,
+ nRenderbufferDepthId, nRenderbufferColorId, true );
+ glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
+
+ aPosAry.mnSrcX = aPosAry.mnDestX = 0;
+ aPosAry.mnSrcY = aPosAry.mnDestY = 0;
+ aPosAry.mnSrcWidth = aPosAry.mnDestWidth = mnWidth;
+ aPosAry.mnSrcHeight = aPosAry.mnDestHeight = mnHeight;
+
+ DrawTexture( mnTexture, aPosAry );
+ glReadPixels( 0, 0, mnWidth, mnHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ glDeleteFramebuffers( 1, &nFramebufferId );
+ glDeleteRenderbuffers( 1, &nRenderbufferDepthId );
+ glDeleteRenderbuffers( 1, &nRenderbufferColorId );
+
+ return true;
+}
+
+sal_uInt16 OpenGLSalBitmap::GetBitCount() const
+{
+ return mnBits;
+}
+
+BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
+{
+ if( !maUserBuffer.get() )
+ {
+ if( !AllocateUserData() )
+ return NULL;
+ if( mnTexture && !ReadTexture() )
+ return NULL;
+ }
+
+ BitmapBuffer* pBuffer = new BitmapBuffer;
+ pBuffer->mnWidth = mnWidth;
+ pBuffer->mnHeight = mnHeight;
+ pBuffer->maPalette = maPalette;
+ pBuffer->mnScanlineSize = mnBytesPerRow;
+ pBuffer->mpBits = maUserBuffer.get();
+ pBuffer->mnBitCount = mnBits;
+ switch( mnBits )
+ {
+ case 1: pBuffer->mnFormat = BMP_FORMAT_1BIT_MSB_PAL; break;
+ case 4: pBuffer->mnFormat = BMP_FORMAT_4BIT_MSN_PAL; break;
+ case 8: pBuffer->mnFormat = BMP_FORMAT_8BIT_PAL; break;
+ case 16: pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
+ pBuffer->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
+ break;
+ case 24: pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_BGR; break;
+ case 32: pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_ARGB;
+ pBuffer->maColorMask = ColorMask( 0x00ff0000, 0x0000ff00, 0x000000ff );
+ break;
+ }
+ // FIXME pBuffer->mnFormat |= BMP_FORMAT_BOTTOM_UP;
+
+ return pBuffer;
+}
+
+void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
+{
+ if( !bReadOnly )
+ {
+ mbDirtyTexture = true;
+ }
+ delete pBuffer;
+}
+
+bool OpenGLSalBitmap::GetSystemData( BitmapSystemData& /*rData*/ )
+{
+#if 0
+ // TODO Implement for ANDROID/OSX/IOS/WIN32
+ X11SalBitmap rBitmap;
+ BitmapBuffer* pBuffer;
+
+ rBitmap.Create( GetSize(), mnBits, maPalette );
+ pBuffer = rBitmap.AcquireBuffer( false );
+ if( pBuffer == NULL )
+ return false;
+
+ if( !maUserBuffer.get() )
+ {
+ if( !AllocateUserData() || !ReadTexture() )
+ {
+ rBitmap.ReleaseBuffer( pBuffer, false );
+ return false;
+ }
+ }
+
+ // TODO Might be more efficient to add a static method to SalBitmap
+ // to get system data from a buffer
+ memcpy( pBuffer->mpBits, maUserBuffer.get(), mnBytesPerRow * mnHeight );
+
+ rBitmap.ReleaseBuffer( pBuffer, false );
+ return rBitmap.GetSystemData( rData );
+#else
+ return false;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salbmp.cxx b/vcl/unx/generic/gdi/salbmp.cxx
index e68078e..8468b4d 100644
--- a/vcl/unx/generic/gdi/salbmp.cxx
+++ b/vcl/unx/generic/gdi/salbmp.cxx
@@ -43,6 +43,8 @@
#include <unx/salinst.h>
#include <unx/x11/xlimits.hxx>
+#include <opengl/salbmp.hxx>
+
#if defined HAVE_VALGRIND_HEADERS
#include <valgrind/memcheck.h>
#endif
@@ -53,7 +55,11 @@
SalBitmap* X11SalInstance::CreateSalBitmap()
{
- return new X11SalBitmap();
+ static const char* pOpenGL = getenv("USE_OPENGL");
+ if (pOpenGL)
+ return new OpenGLSalBitmap();
+ else
+ return new X11SalBitmap();
}
ImplSalBitmapCache* X11SalBitmap::mpCache = NULL;
commit 8c5df61d2086dfd9ff321f88b293de568cc2ea2d
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Thu Oct 30 21:57:22 2014 -0400
vcl: Update OpenGL context before drawing
Change-Id: I7575881d8d9a2026a74692ca562a340231d946bd
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 9ada69a..8bb31b0 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -453,6 +453,7 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
{
if( mnLineColor != SALCOLOR_NONE )
{
+ maContext.makeCurrent();
BeginSolid( mnLineColor );
DrawPoint( nX, nY );
EndSolid();
@@ -463,6 +464,7 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
{
if( nSalColor != SALCOLOR_NONE )
{
+ maContext.makeCurrent();
BeginSolid( nSalColor );
DrawPoint( nX, nY );
EndSolid();
@@ -473,6 +475,7 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
{
if( mnLineColor != SALCOLOR_NONE )
{
+ maContext.makeCurrent();
BeginSolid( mnLineColor );
DrawLine( nX1, nY1, nX2, nY2 );
EndSolid();
@@ -481,6 +484,8 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeight )
{
+ maContext.makeCurrent();
+
if( mnFillColor != SALCOLOR_NONE )
{
BeginSolid( mnFillColor );
@@ -505,6 +510,8 @@ void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeigh
void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
+ maContext.makeCurrent();
+
if( mnLineColor != SALCOLOR_NONE && nPoints > 1 )
{
BeginSolid( mnLineColor );
@@ -529,6 +536,8 @@ void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPt
return;
}
+ maContext.makeCurrent();
+
if( mnFillColor != SALCOLOR_NONE )
{
BeginSolid( mnFillColor );
@@ -549,6 +558,8 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32*
if( nPoly <= 0 )
return;
+ maContext.makeCurrent();
+
if( mnFillColor != SALCOLOR_NONE )
{
BeginSolid( mnFillColor );
@@ -645,6 +656,7 @@ void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitm
const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
GLuint nTexture = rBitmap.GetTexture();
+ maContext.makeCurrent();
DrawTexture( nTexture, rPosAry );
}
@@ -666,6 +678,7 @@ void OpenGLSalGraphicsImpl::drawBitmap(
const GLuint nTexture( rBitmap.GetTexture() );
const GLuint nMask( rMask.GetTexture() );
+ maContext.makeCurrent();
DrawTextureWithMask( nTexture, nMask, rPosAry );
}
@@ -702,6 +715,7 @@ SalColor OpenGLSalGraphicsImpl::getPixel( long nX, long nY )
{
char pixel[3];
+ maContext.makeCurrent();
glReadPixels( nX, nY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
return MAKE_SALCOLOR( pixel[0], pixel[1], pixel[2] );
}
@@ -716,6 +730,8 @@ void OpenGLSalGraphicsImpl::invert(
// * SAL_INVERT_50 (50/50 pattern?)
// * SAL_INVERT_TRACKFRAME (dash-line rectangle?)
+ maContext.makeCurrent();
+
if( nFlags & SAL_INVERT_TRACKFRAME )
{
@@ -734,6 +750,8 @@ void OpenGLSalGraphicsImpl::invert(
void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags )
{
+ maContext.makeCurrent();
+
if( nFlags & SAL_INVERT_TRACKFRAME )
{
@@ -781,6 +799,7 @@ bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
const GLuint nTexture( rBitmap.GetTexture() );
const GLuint nAlpha( rAlpha.GetTexture() );
+ maContext.makeCurrent();
DrawTextureWithMask( nTexture, nAlpha, rPosAry );
return true;
}
diff --git a/vcl/opengl/solidFragmentShader.glsl b/vcl/opengl/solidFragmentShader.glsl
index 917cafc..94d0de0 100644
--- a/vcl/opengl/solidFragmentShader.glsl
+++ b/vcl/opengl/solidFragmentShader.glsl
@@ -7,7 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-precision mediump float;
+/*precision mediump float;*/
uniform vec4 color;
void main() {
commit 130b43d5c86fcf05d6feb09c54a1e0b275a4edbf
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Thu Oct 30 21:54:22 2014 -0400
vcl: Add methods to get size of OpenGLSalGraphicsImpl
Change-Id: I7eecbc236db12fb9453384985245eb5ca781e0f5
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index a8344d6..8e4c257 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -177,7 +177,7 @@ public:
void setWinPosAndSize(const Point &rPos, const Size& rSize);
void setWinSize(const Size& rSize);
- GLWindow& getOpenGLWindow() { return m_aGLWin;}
+ const GLWindow& getOpenGLWindow() const { return m_aGLWin;}
SystemChildWindow* getChildWindow();
const SystemChildWindow* getChildWindow() const;
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 6338ebe..cad2c4d 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -50,6 +50,9 @@ private:
GLuint mnMaskUniform;
GLuint mnMaskColorUniform;
+ inline GLfloat GetWidth() const;
+ inline GLfloat GetHeight() const;
+
bool CreateSolidProgram( void );
bool CreateTextureProgram( void );
bool CreateMaskedTextureProgram( void );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index d9e4865..9ada69a 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -76,7 +76,17 @@ sal_uInt16 OpenGLSalGraphicsImpl::GetBitCount() const
// get the width of the device
long OpenGLSalGraphicsImpl::GetGraphicsWidth() const
{
- return 0;
+ return maContext.getOpenGLWindow().Width;
+}
+
+inline GLfloat OpenGLSalGraphicsImpl::GetWidth() const
+{
+ return maContext.getOpenGLWindow().Width;
+}
+
+inline GLfloat OpenGLSalGraphicsImpl::GetHeight() const
+{
+ return maContext.getOpenGLWindow().Height;
}
// set the clip region to empty
@@ -277,8 +287,8 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
for( i = 0, j = 0; i < nPoints; i++, j += 2 )
{
- pVertices[j] = pPtAry[i].mnX;
- pVertices[j+1] = pPtAry[i].mnY;
+ pVertices[j] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0;
+ pVertices[j+1] = (2 * pPtAry[i].mnY) / GetHeight() - 1.0;
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
commit b92cca3a44c26b9d8a514860dc3d71d65f730e81
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Thu Oct 30 21:51:39 2014 -0400
vcl: Some fixes to the OpenGL impl
Change-Id: I58466142e0a47beb892e10113c1bc34d5ac3abcd
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index d6f35fd..6338ebe 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -65,7 +65,7 @@ private:
void DrawLine( long nX1, long nY1, long nX2, long nY2 );
void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
- void DrawRect( long nX, long nY, long nWidth, nHeight );
+ void DrawRect( long nX, long nY, long nWidth, long nHeight );
void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon );
void DrawTextureRect( const SalTwoRect& pPosAry );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index ef49d03..d9e4865 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -86,7 +86,6 @@ void OpenGLSalGraphicsImpl::ResetClipRegion()
}
// set the line color to transparent (= don't draw lines)
-
void OpenGLSalGraphicsImpl::SetLineColor()
{
if( mnLineColor != SALCOLOR_NONE )
@@ -151,9 +150,7 @@ bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
{
- static const char aFragShaderSrc[] =
-
- mnTextureProgram = OpenGLHelper::( "textureVertexShader", "textureFragmentShader" );
+ mnTextureProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "textureFragmentShader" );
if( mnTextureProgram == 0 )
return false;
@@ -358,7 +355,7 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPol
}
glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.size() );
+ glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.data() );
glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 );
glDisableVertexAttribArray( GL_ATTRIB_POS );
}
@@ -611,7 +608,7 @@ 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 );
@@ -720,7 +717,7 @@ void OpenGLSalGraphicsImpl::invert(
else // just invert
{
BeginInvert();
- DrawPolygon( 4, aPoints );
+ DrawRect( nX, nY, nWidth, nHeight );
EndInvert();
}
}
commit e4986c3348b9f3f2bcf60a35cd8f0895d8c5bbdc
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date: Wed Oct 29 22:30:55 2014 +0100
extract shaders from source code
Conflicts:
vcl/opengl/gdiimpl.cxx
Change-Id: Ifbb55e58e0854cc491703b8ca8d8e582741a9bd9
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 693c625..f61cc7b 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -22,6 +22,7 @@ $(eval $(call gb_Module_Module,vcl))
$(eval $(call gb_Module_add_targets,vcl,\
CustomTarget_afm_hash \
Library_vcl \
+ Package_opengl \
$(if $(filter DESKTOP,$(BUILD_TYPE)), \
StaticLibrary_vclmain \
Executable_ui-previewer \
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
new file mode 100644
index 0000000..9b8f745
--- /dev/null
+++ b/vcl/Package_opengl.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl))
+
+$(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
+ maskFragmentShader.glsl \
+ maskVertexShader.glsl \
+ maskedTextureFragmentShader.glsl \
+ maskedTextureVertexShader.glsl \
+ solidFragmentShader.glsl \
+ solidVertexShader.glsl \
+ textureFragmentShader.glsl \
+ textureVertexShader.glsl \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index d3ee9ef..d6f35fd 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -50,8 +50,6 @@ private:
GLuint mnMaskUniform;
GLuint mnMaskColorUniform;
- GLuint CompileShader( GLenum nType, const char *aSrc );
- GLuint CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc );
bool CreateSolidProgram( void );
bool CreateTextureProgram( void );
bool CreateMaskedTextureProgram( void );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index f59584a..ef49d03 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -23,6 +23,8 @@
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygontriangulator.hxx>
+#include <vcl/opengl/OpenGLHelper.hxx>
+
#define GL_ATTRIB_POS 0
#define GL_ATTRIB_TEX 1
@@ -136,99 +138,9 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
{
}
-GLuint OpenGLSalGraphicsImpl::CompileShader( GLenum nType, const char *aSrc )
-{
- GLint nStatus;
- GLuint nShader;
- GLint nLogLen( 0 );
- char *aLog( NULL );
-
- nShader = glCreateShader( nType );
- glShaderSource( nShader, 1, (const GLchar **) &aSrc, NULL );
- glCompileShader( nShader );
- glGetShaderiv( nShader, GL_COMPILE_STATUS, &nStatus );
- if( nStatus )
- return nShader;
-
- glGetShaderiv( nShader, GL_INFO_LOG_LENGTH, &nLogLen );
- if( nLogLen > 1 )
- aLog = new char[nLogLen];
- if( aLog )
- glGetShaderInfoLog( nShader, nLogLen, NULL, aLog );
-
- SAL_WARN( "vcl.opengl", "::CompileShader failed: " << aLog );
-
- delete aLog;
- glDeleteShader( nShader );
-
- return 0;
-}
-
-GLuint OpenGLSalGraphicsImpl::CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc )
-{
- GLuint nProgram;
- GLuint nVertShader, nFragShader;
- GLint nStatus;
-
- nVertShader = CompileShader( GL_VERTEX_SHADER, aVertShaderSrc );
- nFragShader = CompileShader( GL_FRAGMENT_SHADER, aFragShaderSrc );
- if( !nVertShader || !nFragShader )
- {
- SAL_WARN( "vcl.opengl", "::CreateProgram couldn't compile the shaders" );
- return 0;
- }
-
- nProgram = glCreateProgram();
- if( nProgram == 0 )
- {
- SAL_WARN( "vcl.opengl", "::CreateProgram couldn't create GL program" );
- return 0;
- }
-
- glAttachShader( nProgram, nVertShader );
- glAttachShader( nProgram, nFragShader );
- glLinkProgram( nProgram );
- glGetProgramiv( nProgram, GL_LINK_STATUS, &nStatus );
- if( !nStatus )
- {
- GLint nLogLen( 0 );
- char *aLog( NULL );
-
- glDeleteShader( nVertShader );
- glDeleteShader( nFragShader );
-
- glGetProgramiv( nProgram, GL_INFO_LOG_LENGTH, &nLogLen );
- if( nLogLen > 0 )
- aLog = new char[nLogLen];
- if( aLog )
- glGetProgramInfoLog( nProgram, nLogLen, NULL, aLog );
-
- SAL_WARN( "vcl.opengl", "::CreateSolidShader couldn't link program: " << aLog );
- delete aLog;
-
- return 0;
- }
-
- maShaders.push_back( nVertShader );
- maShaders.push_back( nFragShader );
- return nProgram;
-}
-
bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
{
- static const char aVertShaderSrc[] =
- "attribute vec4 position;\n"
- "void main() {\n"
- " gl_Position = position;\n"
- "}\n";
- static const char aFragShaderSrc[] =
- "precision mediump float;\n"
- "uniform vec4 color;\n"
- "void main() {\n"
- " gl_FragColor = color;\n"
- "}\n";
-
- mnSolidProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
+ mnSolidProgram = OpenGLHelper::LoadShaders( "solidVertexShader", "solidFragmentShader" );
if( mnSolidProgram == 0 )
return false;
@@ -239,23 +151,9 @@ bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
{
- static const char aVertShaderSrc[] =
- "attribute vec4 position;\n"
- "attribute vec2 tex_coord_in;\n"
- "varying vec2 tex_coord;\n"
- "void main() {\n"
- " gl_Position = position;\n"
- " tex_coord = tex_coord_in;\n"
- "}\n";
static const char aFragShaderSrc[] =
- "precision mediump float;\n"
- "varying vec2 tex_coord;\n"
- "uniform sampler2D sampler;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(sampler, tex_coord);\n"
- "}\n";
-
- mnTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
+
+ mnTextureProgram = OpenGLHelper::( "textureVertexShader", "textureFragmentShader" );
if( mnTextureProgram == 0 )
return false;
@@ -267,27 +165,7 @@ bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void )
{
- static const char aVertShaderSrc[] =
- "attribute vec4 position;\n"
- "attribute vec2 tex_coord_in;\n"
- "varying vec2 tex_coord;\n"
- "void main() {\n"
- " gl_Position = position;\n"
- " tex_coord = tex_coord_in;\n"
- "}\n";
- static const char aFragShaderSrc[] =
- "precision mediump float;\n"
- "varying vec2 tex_coord;\n"
- "uniform sampler2D sampler;\n"
- "uniform sampler2D mask;\n"
- "void main() {\n"
- " vec4 texel0, texel1;\n"
- " texel0 = texture2D(sampler, tex_coord);\n"
- " texel1 = texture2D(mask, tex_coord);\n"
- " gl_FragColor = texel0 * texel1.a;\n"
- "}\n";
-
- mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
+ mnMaskedTextureProgram = OpenGLHelper::LoadShaders( "maskedTextureVertexShader", "maskedTextureFragmentShader" );
if( mnMaskedTextureProgram == 0 )
return false;
@@ -300,26 +178,7 @@ bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void )
bool OpenGLSalGraphicsImpl::CreateMaskProgram( void )
{
- static const char aVertShaderSrc[] =
- "attribute vec4 position;\n"
- "attribute vec2 tex_coord_in;\n"
- "varying vec2 tex_coord;\n"
- "void main() {\n"
- " gl_Position = position;\n"
- " tex_coord = tex_coord_in;\n"
- "}\n";
- static const char aFragShaderSrc[] =
- "precision mediump float;\n"
- "varying vec2 tex_coord;\n"
- "uniform sampler2D sampler;\n"
- "uniform vec4 color;\n"
- "void main() {\n"
- " vec4 texel0;\n"
- " texel0 = texture2D(sampler, tex_coord);\n"
- " gl_FragColor = color * texel0.a;\n"
- "}\n";
-
- mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
+ mnMaskedTextureProgram = OpenGLHelper::LoadShaders( "maskVertexShader", "maskFragmentShader" );
if( mnMaskedTextureProgram == 0 )
return false;
diff --git a/vcl/opengl/maskFragmentShader.glsl b/vcl/opengl/maskFragmentShader.glsl
new file mode 100644
index 0000000..35ecbd0
--- /dev/null
+++ b/vcl/opengl/maskFragmentShader.glsl
@@ -0,0 +1,21 @@
+/* -*- 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/.
+ */
+
+precision mediump float;
+varying vec2 tex_coord;
+uniform sampler2D sampler;
+uniform vec4 color;"
+
+void main() {
+ vec4 texel0;
+ texel0 = texture2D(sampler, tex_coord);
+ gl_FragColor = color * texel0.a;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/maskVertexShader.glsl b/vcl/opengl/maskVertexShader.glsl
new file mode 100644
index 0000000..303ddec
--- /dev/null
+++ b/vcl/opengl/maskVertexShader.glsl
@@ -0,0 +1,19 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+varying vec2 tex_coord;
+
+void main() {
+ gl_Position = position;
+ tex_coord = tex_coord_in;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/maskedTextureFragmentShader.glsl b/vcl/opengl/maskedTextureFragmentShader.glsl
new file mode 100644
index 0000000..5353250
--- /dev/null
+++ b/vcl/opengl/maskedTextureFragmentShader.glsl
@@ -0,0 +1,22 @@
+/* -*- 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/.
+ */
+
+precision mediump float;
+varying vec2 tex_coord;
+uniform sampler2D sampler;
+uniform sampler2D mask;
+
+void main() {
+ vec4 texel0, texel1;
+ texel0 = texture2D(sampler, tex_coord);
+ texel1 = texture2D(mask, tex_coord);
+ gl_FragColor = texel0 * texel1.a;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/maskedTextureVertexShader.glsl b/vcl/opengl/maskedTextureVertexShader.glsl
new file mode 100644
index 0000000..303ddec
--- /dev/null
+++ b/vcl/opengl/maskedTextureVertexShader.glsl
@@ -0,0 +1,19 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+varying vec2 tex_coord;
+
+void main() {
+ gl_Position = position;
+ tex_coord = tex_coord_in;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/solidFragmentShader.glsl b/vcl/opengl/solidFragmentShader.glsl
new file mode 100644
index 0000000..917cafc
--- /dev/null
+++ b/vcl/opengl/solidFragmentShader.glsl
@@ -0,0 +1,17 @@
+/* -*- 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/.
+ */
+
+precision mediump float;
+
+uniform vec4 color;
+void main() {
+ gl_FragColor = color;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/solidVertexShader.glsl b/vcl/opengl/solidVertexShader.glsl
new file mode 100644
index 0000000..c3de9c5
--- /dev/null
+++ b/vcl/opengl/solidVertexShader.glsl
@@ -0,0 +1,16 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+void main() {
+ gl_Position = position;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/textureFragmentShader.glsl b/vcl/opengl/textureFragmentShader.glsl
new file mode 100644
index 0000000..eb510d8
--- /dev/null
+++ b/vcl/opengl/textureFragmentShader.glsl
@@ -0,0 +1,18 @@
+/* -*- 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/.
+ */
+
+precision mediump float;
+varying vec2 tex_coord;
+uniform sampler2D sampler;
+
+void main() {
+ gl_FragColor = texture2D(sampler, tex_coord);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/textureVertexShader.glsl b/vcl/opengl/textureVertexShader.glsl
new file mode 100644
index 0000000..303ddec
--- /dev/null
+++ b/vcl/opengl/textureVertexShader.glsl
@@ -0,0 +1,19 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+varying vec2 tex_coord;
+
+void main() {
+ gl_Position = position;
+ tex_coord = tex_coord_in;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 72ef9d08ba31689675381693aa49986555bc0139
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Wed Oct 29 13:05:02 2014 -0400
vcl: Implement basic SalGraphics methods for OpenGL backend
Change-Id: Iade3960c38f0de5594bc98e535450abcf88e9a6d
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 9ae84ca..d3ee9ef 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -31,6 +31,51 @@ private:
OpenGLContext maContext;
+ SalColor mnLineColor;
+ SalColor mnFillColor;
+
+ std::vector< GLuint > maShaders;
+
+ GLuint mnSolidProgram;
+ GLuint mnColorUniform;
+
+ GLuint mnTextureProgram;
+ GLuint mnSamplerUniform;
+
+ GLuint mnMaskedTextureProgram;
+ GLuint mnMaskedSamplerUniform;
+ GLuint mnMaskSamplerUniform;
+
+ GLuint mnMaskProgram;
+ GLuint mnMaskUniform;
+ GLuint mnMaskColorUniform;
+
+ GLuint CompileShader( GLenum nType, const char *aSrc );
+ GLuint CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc );
+ bool CreateSolidProgram( void );
+ bool CreateTextureProgram( void );
+ bool CreateMaskedTextureProgram( void );
+ bool CreateMaskProgram( void );
+
+ void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
+ void BeginSolid( SalColor nColor );
+ void EndSolid( void );
+ void BeginInvert( void );
+ void EndInvert( void );
+
+ void DrawPoint( long nX, long nY );
+ void DrawLine( long nX1, long nY1, long nX2, long nY2 );
+ void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
+ void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
+ void DrawRect( long nX, long nY, long nWidth, nHeight );
+ void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
+ void DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon );
+ void DrawTextureRect( const SalTwoRect& pPosAry );
+ void DrawTexture( GLuint nTexture, const SalTwoRect& pPosAry );
+ void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& pPosAry );
+ void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& pPosAry );
+
+
public:
virtual ~OpenGLSalGraphicsImpl ();
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 6e39d1e..f59584a 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -20,6 +20,18 @@
#include "openglgdiimpl.hxx"
#include <vcl/gradient.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontriangulator.hxx>
+
+#define GL_ATTRIB_POS 0
+#define GL_ATTRIB_TEX 1
+
+#define glUniformColor(nUniform, nColor, nTransparency) \
+ glUniform4f( nUniform, \
+ ((float) SALCOLOR_RED( nColor )) / 255, \
+ ((float) SALCOLOR_GREEN( nColor )) / 255, \
+ ((float) SALCOLOR_BLUE( nColor )) / 255, \
+ (100 - nTransparency) * (1.0 / 100) )
OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
{
@@ -27,11 +39,30 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
void OpenGLSalGraphicsImpl::freeResources()
{
+ // Delete shaders, programs and textures if not shared
}
-bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& )
+bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
{
- return false;
+ const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() );
+
+ glEnable(GL_STENCIL_TEST);
+
+ glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
+ glDepthMask( GL_FALSE );
+ glStencilMask( 0xFF );
+ glStencilFunc( GL_NEVER, 1, 0xFF );
+ glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP );
+
+ glClear( GL_STENCIL_BUFFER_BIT );
+ DrawPolyPolygon( aClip );
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glDepthMask( GL_TRUE );
+ glStencilMask( 0x00 );
+ glStencilFunc(GL_EQUAL, 1, 0xFF);
+
+ return true;
}
// get the depth of the device
@@ -49,28 +80,45 @@ long OpenGLSalGraphicsImpl::GetGraphicsWidth() const
// set the clip region to empty
void OpenGLSalGraphicsImpl::ResetClipRegion()
{
+ glDisable(GL_STENCIL_TEST);
}
// set the line color to transparent (= don't draw lines)
void OpenGLSalGraphicsImpl::SetLineColor()
{
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ mnLineColor = SALCOLOR_NONE;
+ }
}
// set the line color to a specific color
-void OpenGLSalGraphicsImpl::SetLineColor( SalColor /*nSalColor*/ )
+void OpenGLSalGraphicsImpl::SetLineColor( SalColor nSalColor )
{
+ if( mnLineColor != nSalColor )
+ {
+ mnLineColor = nSalColor;
+ }
}
// set the fill color to transparent (= don't fill)
void OpenGLSalGraphicsImpl::SetFillColor()
{
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ mnFillColor = SALCOLOR_NONE;
+ }
}
// set the fill color to a specific color, shapes will be
// filled accordingly
-void OpenGLSalGraphicsImpl::SetFillColor( SalColor /*nSalColor*/ )
+void OpenGLSalGraphicsImpl::SetFillColor( SalColor nSalColor )
{
+ if( mnFillColor != nSalColor )
+ {
+ mnFillColor = nSalColor;
+ }
}
// enable/disable XOR drawing
@@ -88,34 +136,571 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
{
}
-// draw --> LineColor and FillColor and RasterOp and ClipRegion
-void OpenGLSalGraphicsImpl::drawPixel( long /*nX*/, long /*nY*/ )
+GLuint OpenGLSalGraphicsImpl::CompileShader( GLenum nType, const char *aSrc )
+{
+ GLint nStatus;
+ GLuint nShader;
+ GLint nLogLen( 0 );
+ char *aLog( NULL );
+
+ nShader = glCreateShader( nType );
+ glShaderSource( nShader, 1, (const GLchar **) &aSrc, NULL );
+ glCompileShader( nShader );
+ glGetShaderiv( nShader, GL_COMPILE_STATUS, &nStatus );
+ if( nStatus )
+ return nShader;
+
+ glGetShaderiv( nShader, GL_INFO_LOG_LENGTH, &nLogLen );
+ if( nLogLen > 1 )
+ aLog = new char[nLogLen];
+ if( aLog )
+ glGetShaderInfoLog( nShader, nLogLen, NULL, aLog );
+
+ SAL_WARN( "vcl.opengl", "::CompileShader failed: " << aLog );
+
+ delete aLog;
+ glDeleteShader( nShader );
+
+ return 0;
+}
+
+GLuint OpenGLSalGraphicsImpl::CreateProgram( const char *aVertShaderSrc, const char *aFragShaderSrc )
+{
+ GLuint nProgram;
+ GLuint nVertShader, nFragShader;
+ GLint nStatus;
+
+ nVertShader = CompileShader( GL_VERTEX_SHADER, aVertShaderSrc );
+ nFragShader = CompileShader( GL_FRAGMENT_SHADER, aFragShaderSrc );
+ if( !nVertShader || !nFragShader )
+ {
+ SAL_WARN( "vcl.opengl", "::CreateProgram couldn't compile the shaders" );
+ return 0;
+ }
+
+ nProgram = glCreateProgram();
+ if( nProgram == 0 )
+ {
+ SAL_WARN( "vcl.opengl", "::CreateProgram couldn't create GL program" );
+ return 0;
+ }
+
+ glAttachShader( nProgram, nVertShader );
+ glAttachShader( nProgram, nFragShader );
+ glLinkProgram( nProgram );
+ glGetProgramiv( nProgram, GL_LINK_STATUS, &nStatus );
+ if( !nStatus )
+ {
+ GLint nLogLen( 0 );
+ char *aLog( NULL );
+
+ glDeleteShader( nVertShader );
+ glDeleteShader( nFragShader );
+
+ glGetProgramiv( nProgram, GL_INFO_LOG_LENGTH, &nLogLen );
+ if( nLogLen > 0 )
+ aLog = new char[nLogLen];
+ if( aLog )
+ glGetProgramInfoLog( nProgram, nLogLen, NULL, aLog );
+
+ SAL_WARN( "vcl.opengl", "::CreateSolidShader couldn't link program: " << aLog );
+ delete aLog;
+
+ return 0;
+ }
+
+ maShaders.push_back( nVertShader );
+ maShaders.push_back( nFragShader );
+ return nProgram;
+}
+
+bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
+{
+ static const char aVertShaderSrc[] =
+ "attribute vec4 position;\n"
+ "void main() {\n"
+ " gl_Position = position;\n"
+ "}\n";
+ static const char aFragShaderSrc[] =
+ "precision mediump float;\n"
+ "uniform vec4 color;\n"
+ "void main() {\n"
+ " gl_FragColor = color;\n"
+ "}\n";
+
+ mnSolidProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
+ if( mnSolidProgram == 0 )
+ return false;
+
+ glBindAttribLocation( mnSolidProgram, GL_ATTRIB_POS, "position" );
+ mnColorUniform = glGetUniformLocation( mnSolidProgram, "color" );
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
+{
+ static const char aVertShaderSrc[] =
+ "attribute vec4 position;\n"
+ "attribute vec2 tex_coord_in;\n"
+ "varying vec2 tex_coord;\n"
+ "void main() {\n"
+ " gl_Position = position;\n"
+ " tex_coord = tex_coord_in;\n"
+ "}\n";
+ static const char aFragShaderSrc[] =
+ "precision mediump float;\n"
+ "varying vec2 tex_coord;\n"
+ "uniform sampler2D sampler;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(sampler, tex_coord);\n"
+ "}\n";
+
+ mnTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
+ if( mnTextureProgram == 0 )
+ return false;
+
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+ mnSamplerUniform = glGetUniformLocation( mnTextureProgram, "sampler" );
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void )
+{
+ static const char aVertShaderSrc[] =
+ "attribute vec4 position;\n"
+ "attribute vec2 tex_coord_in;\n"
+ "varying vec2 tex_coord;\n"
+ "void main() {\n"
+ " gl_Position = position;\n"
+ " tex_coord = tex_coord_in;\n"
+ "}\n";
+ static const char aFragShaderSrc[] =
+ "precision mediump float;\n"
+ "varying vec2 tex_coord;\n"
+ "uniform sampler2D sampler;\n"
+ "uniform sampler2D mask;\n"
+ "void main() {\n"
+ " vec4 texel0, texel1;\n"
+ " texel0 = texture2D(sampler, tex_coord);\n"
+ " texel1 = texture2D(mask, tex_coord);\n"
+ " gl_FragColor = texel0 * texel1.a;\n"
+ "}\n";
+
+ mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
+ if( mnMaskedTextureProgram == 0 )
+ return false;
+
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+ mnMaskedSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "sampler" );
+ mnMaskSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "mask" );
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::CreateMaskProgram( void )
+{
+ static const char aVertShaderSrc[] =
+ "attribute vec4 position;\n"
+ "attribute vec2 tex_coord_in;\n"
+ "varying vec2 tex_coord;\n"
+ "void main() {\n"
+ " gl_Position = position;\n"
+ " tex_coord = tex_coord_in;\n"
+ "}\n";
+ static const char aFragShaderSrc[] =
+ "precision mediump float;\n"
+ "varying vec2 tex_coord;\n"
+ "uniform sampler2D sampler;\n"
+ "uniform vec4 color;\n"
+ "void main() {\n"
+ " vec4 texel0;\n"
+ " texel0 = texture2D(sampler, tex_coord);\n"
+ " gl_FragColor = color * texel0.a;\n"
+ "}\n";
+
+ mnMaskedTextureProgram = CreateProgram( aVertShaderSrc, aFragShaderSrc );
+ if( mnMaskedTextureProgram == 0 )
+ return false;
+
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+ mnMaskUniform = glGetUniformLocation( mnMaskProgram, "sampler" );
+ mnMaskColorUniform = glGetUniformLocation( mnMaskProgram, "mask" );
+ return true;
+}
+
+void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, sal_uInt8 nTransparency )
+{
+ if( mnSolidProgram == 0 )
+ {
+ if( !CreateSolidProgram() )
+ return;
+ }
+
+ glUseProgram( mnSolidProgram );
+ glUniformColor( mnColorUniform, nColor, nTransparency );
+}
+
+void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor )
+{
+ BeginSolid( nColor, 0 );
+}
+
+void OpenGLSalGraphicsImpl::EndSolid( void )
+{
+ glUseProgram( 0 );
+}
+
+void OpenGLSalGraphicsImpl::BeginInvert( void )
+{
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
+ BeginSolid( MAKE_SALCOLOR( 255, 255, 255 ) );
+}
+
+void OpenGLSalGraphicsImpl::EndInvert( void )
+{
+ EndSolid();
+ glDisable( GL_BLEND );
+}
+
+void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
+{
+ GLushort pPoint[2];
+
+ pPoint[0] = nX;
+ pPoint[1] = nY;
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoint );
+ glDrawArrays( GL_POINTS, 0, 1 );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+}
+
+void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ GLushort pPoints[4];
+
+ pPoints[0] = nX1;
+ pPoints[1] = nY1;
+ pPoints[2] = nX2;
+ pPoints[3] = nY2;
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, 4, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints );
+ glDrawArrays( GL_LINES, 0, 2 );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+}
+
+void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
+{
+ GLushort *pPoints;
+ sal_uInt32 i, j;
+
+ pPoints = new GLushort[nPoints * 2];
+ for( i = 0, j = 0; i < nPoints; i++, j += 2 )
+ {
+ pPoints[j] = pPtAry[i].mnX;
+ pPoints[j+1] = pPtAry[i].mnY;
+ }
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoints );
+ if( bClose )
+ glDrawArrays( GL_LINE_LOOP, 0, nPoints );
+ else
+ glDrawArrays( GL_LINE_STRIP, 0, nPoints );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+}
+
+void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
+ GLushort pVertices[nPoints * 2];
+ sal_uInt32 i, j;
+
+ for( i = 0, j = 0; i < nPoints; i++, j += 2 )
+ {
+ pVertices[j] = pPtAry[i].mnX;
+ pVertices[j+1] = pPtAry[i].mnY;
+ }
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, nPoints * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices );
+ glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
}
-void OpenGLSalGraphicsImpl::drawPixel( long /*nX*/, long /*nY*/, SalColor /*nSalColor*/ )
+void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeight )
{
+ long nX1( nX );
+ long nY1( nY );
+ long nX2( nX + nWidth - 1 );
+ long nY2( nY + nHeight - 1 );
+ const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
+ { nX2, nY1 }, { nX2, nY2 }};
+
+ DrawConvexPolygon( 4, aPoints );
}
-void OpenGLSalGraphicsImpl::drawLine( long /*nX1*/, long /*nY1*/, long /*nX2*/, long /*nY2*/ )
+void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
+ ::basegfx::B2DPolygon aPolygon;
+
+ for( sal_uInt32 i = 0; i < nPoints; i++ )
+ aPolygon.append( ::basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
+ aPolygon.setClosed( true );
+
+ if( ::basegfx::tools::isConvex( aPolygon ) )
+ {
+ if( nPoints > 2L )
+ {
+ DrawConvexPolygon( nPoints, pPtAry );
+ }
+ }
+ else
+ {
+ const ::basegfx::B2DPolygon& aResult(
+ ::basegfx::triangulator::triangulate( aPolygon ) );
+ GLushort pVertices[aResult.count() * 2];
+ sal_uInt32 j( 0 );
+
+ for( sal_uInt32 i = 0; i < aResult.count(); i++ )
+ {
+ const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) );
+ pVertices[j++] = rPt.getX();
+ pVertices[j++] = rPt.getY();
+ }
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, aResult.count() * 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices );
+ glDrawArrays( GL_TRIANGLES, 0, aResult.count() );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+ }
}
-void OpenGLSalGraphicsImpl::drawRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/ )
+void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& pPolyPolygon )
{
+ sal_uInt32 i, j;
+ ::std::vector< GLushort > pVertices;
+
+ for( i = 0; i < pPolyPolygon.count(); i++ )
+ {
+ const basegfx::B2DPolygon& pPolygon( pPolyPolygon.getB2DPolygon( i ) );
+ const ::basegfx::B2DPolygon& aResult(
+ ::basegfx::triangulator::triangulate( pPolygon ) );
+
+ for( j = 0; i < aResult.count(); j++ )
+ {
+ const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint(i) );
+ pVertices.push_back( rPt.getX() );
+ pVertices.push_back( rPt.getY() );
+ }
+ }
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, pVertices.size(), GL_UNSIGNED_SHORT, GL_FALSE, 0, pVertices.size() );
+ glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
}
-void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/ )
+void OpenGLSalGraphicsImpl::DrawTextureRect( const SalTwoRect& pPosAry )
{
+ GLushort aTexCoord[8];
+
+ glEnableVertexAttribArray( GL_ATTRIB_TEX );
+ glVertexAttribPointer( GL_ATTRIB_TEX, 8, GL_UNSIGNED_SHORT, GL_FALSE, 0, aTexCoord );
+
+ DrawRect( pPosAry.mnDestX, pPosAry.mnDestY, pPosAry.mnDestWidth, pPosAry.mnDestHeight );
+
+ glDisableVertexAttribArray( GL_ATTRIB_TEX );
}
-void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/ )
+void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const SalTwoRect& pPosAry )
{
+ if( mnTextureProgram == 0 )
+ {
+ if( !CreateTextureProgram() )
+ return;
+ }
+
+ glUseProgram( mnTextureProgram );
+ glUniform1i( mnSamplerUniform, 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, nTexture );
+
+ DrawTextureRect( pPosAry );
+
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glUseProgram( 0 );
+}
+
+void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, const SalTwoRect& pPosAry )
+{
+ if( mnMaskedTextureProgram == 0 )
+ {
+ if( !CreateMaskedTextureProgram() )
+ return;
+ }
+
+ glUseProgram( mnMaskedTextureProgram );
+ glUniform1i( mnMaskedSamplerUniform, 0 );
+ glUniform1i( mnMaskSamplerUniform, 1 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, nTexture );
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, nMask );
+
+ DrawTextureRect( pPosAry );
+
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glUseProgram( 0 );
}
-void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 /*nPoly*/, const sal_uInt32* /*pPoints*/, PCONSTSALPOINT* /*pPtAry*/ )
+void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& pPosAry )
{
+ if( mnMaskProgram == 0 )
+ {
+ if( !CreateMaskProgram() )
+ return;
+ }
+
+ glUseProgram( mnMaskProgram );
+ glUniformColor( mnMaskColorUniform, nMaskColor, 0 );
+ glUniform1i( mnMaskUniform, 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, nMask );
+
+ DrawTextureRect( pPosAry );
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glUseProgram( 0 );
}
+
+
+// draw --> LineColor and FillColor and RasterOp and ClipRegion
+void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
+{
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnLineColor );
+ DrawPoint( nX, nY );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
+{
+ if( nSalColor != SALCOLOR_NONE )
+ {
+ BeginSolid( nSalColor );
+ DrawPoint( nX, nY );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnLineColor );
+ DrawLine( nX1, nY1, nX2, nY2 );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnFillColor );
+ DrawRect( nX, nY, nWidth, nHeight );
+ EndSolid();
+ }
+
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ const long nX1( nX );
+ const long nY1( nY );
+ const long nX2( nX + nWidth - 1 );
+ const long nY2( nY + nHeight - 1 );
+ const SalPoint aPoints[] = { { nX1, nY1 }, { nX2, nY1 },
+ { nX2, nY2 }, { nX1, nY2 } };
+
+ BeginSolid( mnLineColor );
+ DrawLines( 4, aPoints, true );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ if( mnLineColor != SALCOLOR_NONE && nPoints > 1 )
+ {
+ BeginSolid( mnLineColor );
+ DrawLines( nPoints, pPtAry, false );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ if( nPoints == 0 )
+ return;
+ if( nPoints == 1 )
+ {
+ drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
+ return;
+ }
+ if( nPoints == 2 )
+ {
+ drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
+ pPtAry[1].mnX, pPtAry[1].mnY );
+ return;
+ }
+
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnFillColor );
+ DrawPolygon( nPoints, pPtAry );
+ EndSolid();
+ }
+
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnLineColor );
+ DrawLines( nPoints, pPtAry, true );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry )
+{
+ if( nPoly <= 0 )
+ return;
+
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnFillColor );
+ for( sal_uInt32 i = 0; i < nPoly; i++ )
+ DrawPolygon( pPoints[i], pPtAry[i] );
+ EndSolid();
+ }
+
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ // TODO Use glMultiDrawElements or primitive restart
+ BeginSolid( mnLineColor );
+ for( sal_uInt32 i = 0; i < nPoly; i++ )
+ DrawLines( pPoints[i], pPtAry[i], true );
+ EndSolid();
+ }
+}
+
bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
{
return false;
@@ -167,12 +752,34 @@ 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 );
+
+ if( bSameGraphics &&
+ (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
+ (rPosAry.mnSrcHeight == rPosAry.mnDestHeight))
+ {
+ // short circuit if there is nothing to do
+ if( (rPosAry.mnSrcX == rPosAry.mnDestX) &&
+ (rPosAry.mnSrcY == rPosAry.mnDestY))
+ return;
+ // use copyArea() if source and destination context are identical
+ copyArea( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, 0 );
+ return;
+ }
+
+ // TODO Copy from one FBO to the other (glBlitFramebuffer)
}
-void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& /*rPosAry*/, const SalBitmap& /*rSalBitmap*/ )
+void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
{
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ GLuint nTexture = rBitmap.GetTexture();
+
+ DrawTexture( nTexture, rPosAry );
}
void OpenGLSalGraphicsImpl::drawBitmap(
@@ -180,42 +787,101 @@ void OpenGLSalGraphicsImpl::drawBitmap(
const SalBitmap& /*rSalBitmap*/,
SalColor /*nTransparentColor*/ )
{
+ OSL_FAIL( "::DrawBitmap with transparent color not supported" );
}
void OpenGLSalGraphicsImpl::drawBitmap(
- const SalTwoRect& /*rPosAry*/,
- const SalBitmap& /*rSalBitmap*/,
- const SalBitmap& /*rMaskBitmap*/ )
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rMaskBitmap )
{
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ const OpenGLSalBitmap& rMask = static_cast<const OpenGLSalBitmap&>(rMaskBitmap);
+ const GLuint nTexture( rBitmap.GetTexture() );
+ const GLuint nMask( rMask.GetTexture() );
+
+ DrawTextureWithMask( nTexture, nMask, rPosAry );
}
void OpenGLSalGraphicsImpl::drawMask(
- const SalTwoRect& /*rPosAry*/,
- const SalBitmap& /*rSalBitmap*/,
- SalColor /*nMaskColor*/ )
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor )
{
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ const GLuint nTexture( rBitmap.GetTexture() );
+
+ DrawMask( nTexture, nMaskColor, rPosAry );
}
-SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/ )
+SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long nHeight )
{
- return NULL;
+ GLuint nTexture;
+
+ /*glGenTexture( 1, &nTexture );
+ glBindTexture( GL_TEXTURE_2D, nTexture );
+ glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, nX, nY, nWidth, nHeight, 0 );
+ glBindTexture( GL_TEXTURE_2D, 0 );*/
+
+ OpenGLSalBitmap* pBitmap = new OpenGLSalBitmap;
+ if( !pBitmap->Create( nX, nY, nWidth, nHeight ) )
+ {
+ delete pBitmap;
+ pBitmap = NULL;
+ }
+ return pBitmap;
}
-SalColor OpenGLSalGraphicsImpl::getPixel( long /*nX*/, long /*nY*/ )
+SalColor OpenGLSalGraphicsImpl::getPixel( long nX, long nY )
{
- return 0;
+ char pixel[3];
+
+ glReadPixels( nX, nY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
+ return MAKE_SALCOLOR( pixel[0], pixel[1], pixel[2] );
}
// invert --> ClipRegion (only Windows or VirDevs)
void OpenGLSalGraphicsImpl::invert(
- long /*nX*/, long /*nY*/,
- long /*nWidth*/, long /*nHeight*/,
- SalInvert /*nFlags*/)
+ long nX, long nY,
+ long nWidth, long nHeight,
+ SalInvert nFlags)
{
+ // TODO Figure out what are those:
+ // * SAL_INVERT_50 (50/50 pattern?)
+ // * SAL_INVERT_TRACKFRAME (dash-line rectangle?)
+
+ if( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+
+ }
+ else if( nFlags & SAL_INVERT_50 )
+ {
+
+ }
+ else // just invert
+ {
+ BeginInvert();
+ DrawPolygon( 4, aPoints );
+ EndInvert();
+ }
}
-void OpenGLSalGraphicsImpl::invert( sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/, SalInvert /*nFlags*/ )
+void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags )
{
+ if( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+
+ }
+ else if( nFlags & SAL_INVERT_50 )
+ {
+
+ }
+ else // just invert
+ {
+ BeginInvert();
+ DrawPolygon( nPoints, pPtAry );
+ EndInvert();
+ }
}
bool OpenGLSalGraphicsImpl::drawEPS(
@@ -240,11 +906,17 @@ bool OpenGLSalGraphicsImpl::drawEPS(
compositing themselves
*/
bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
- const SalTwoRect&,
- const SalBitmap& /*rSourceBitmap*/,
- const SalBitmap& /*rAlphaBitmap*/ )
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rAlphaBitmap )
{
- return false;
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ const OpenGLSalBitmap& rAlpha = static_cast<const OpenGLSalBitmap&>(rAlphaBitmap);
+ const GLuint nTexture( rBitmap.GetTexture() );
+ const GLuint nAlpha( rAlpha.GetTexture() );
+
+ DrawTextureWithMask( nTexture, nAlpha, rPosAry );
+ return true;
}
/** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
@@ -265,11 +937,18 @@ bool OpenGLSalGraphicsImpl::drawTransformedBitmap(
fully transparent rectangle
*/
bool OpenGLSalGraphicsImpl::drawAlphaRect(
- long /*nX*/, long /*nY*/,
- long /*nWidth*/, long /*nHeight*/,
- sal_uInt8 /*nTransparency*/ )
-{
- return false;
+ long nX, long nY,
+ long nWidth, long nHeight,
+ sal_uInt8 nTransparency )
+{
+ if( mnFillColor != SALCOLOR_NONE && nTransparency < 100 )
+ {
+ BeginSolid( mnFillColor, nTransparency );
+ DrawRect( nX, nY, nWidth, nHeight );
+ EndSolid();
+ }
+
+ return true;
}
bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/,
More information about the Libreoffice-commits
mailing list