summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/opengl/RenderState.hxx27
-rw-r--r--vcl/inc/opengl/program.hxx5
-rw-r--r--vcl/opengl/gdiimpl.cxx116
-rw-r--r--vcl/opengl/program.cxx45
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx6
5 files changed, 115 insertions, 84 deletions
diff --git a/vcl/inc/opengl/RenderState.hxx b/vcl/inc/opengl/RenderState.hxx
index 0a039a7a3d3a..f84dba70fea9 100644
--- a/vcl/inc/opengl/RenderState.hxx
+++ b/vcl/inc/opengl/RenderState.hxx
@@ -117,11 +117,36 @@ public:
static std::string className() { return std::string("StencilState"); }
};
+class BlendState : public GenericCapabilityState<GL_BLEND, BlendState>
+{
+ GLenum mnSourceMode;
+ GLenum mnDestinationMode;
+public:
+ BlendState()
+ : mnSourceMode(GL_ZERO)
+ , mnDestinationMode(GL_ZERO)
+ {}
+
+ static std::string className() { return std::string("BlendState"); }
+
+ void func(GLenum nSource, GLenum nDestination)
+ {
+ if (mnSourceMode != nSource || mnDestinationMode != nDestination)
+ {
+ glBlendFunc(nSource, nDestination);
+ CHECK_GL_ERROR();
+ mnSourceMode = nSource;
+ mnDestinationMode = nDestination;
+ }
+ }
+};
+
class RenderState
{
TextureState maTexture;
ScissorState maScissor;
StencilState maStencil;
+ BlendState maBlend;
Rectangle maCurrentViewport;
@@ -142,12 +167,14 @@ public:
TextureState& texture() { return maTexture; }
ScissorState& scissor() { return maScissor; }
StencilState& stencil() { return maStencil; }
+ BlendState& blend() { return maBlend; }
void sync()
{
VCL_GL_INFO("RenderState::sync");
maScissor.sync();
maStencil.sync();
+ maBlend.sync();
}
};
diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
index 780cba72380f..5944c72be127 100644
--- a/vcl/inc/opengl/program.hxx
+++ b/vcl/inc/opengl/program.hxx
@@ -51,9 +51,12 @@ public:
OpenGLProgram();
~OpenGLProgram();
+ GLuint Id() { return mnId; }
+
bool Load( const OUString& rVertexShader, const OUString& rFragmentShader,
const rtl::OString& preamble = "", const rtl::OString& rDigest = "" );
bool Use();
+ void Reuse();
bool Clean();
void SetVertices( const GLvoid* pData );
@@ -81,6 +84,8 @@ public:
bool DrawTexture( const OpenGLTexture& rTexture );
+ void DrawArrays(GLenum GLenum, std::vector<GLfloat>& aVertices);
+
protected:
void SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData, GLint nSize = 2 );
GLuint GetUniformLocation( const OString& rName );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index bba462f3cf72..efe51f92e3e9 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -628,14 +628,12 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
{
OpenGLZone aZone;
- GLfloat pPoint[2];
-
- pPoint[0] = GLfloat(nX);
- pPoint[1] = GLfloat(nY);
+ std::vector<GLfloat> pPoint {
+ GLfloat(nX), GLfloat(nY)
+ };
ApplyProgramMatrices(0.5f);
- mpProgram->SetVertices( pPoint );
- glDrawArrays( GL_POINTS, 0, 1 );
+ mpProgram->DrawArrays(GL_POINTS, pPoint);
CHECK_GL_ERROR();
}
@@ -643,16 +641,13 @@ void OpenGLSalGraphicsImpl::DrawLine( double nX1, double nY1, double nX2, double
{
OpenGLZone aZone;
- GLfloat pPoints[4];
-
- pPoints[0] = GLfloat(nX1);
- pPoints[1] = GLfloat(nY1);
- pPoints[2] = GLfloat(nX2);
- pPoints[3] = GLfloat(nY2);
+ std::vector<GLfloat> pPoint {
+ GLfloat(nX1), GLfloat(nY1),
+ GLfloat(nX2), GLfloat(nY2)
+ };
ApplyProgramMatrices(0.5f);
- mpProgram->SetVertices( pPoints );
- glDrawArrays( GL_LINES, 0, 2 );
+ mpProgram->DrawArrays(GL_LINES, pPoint);
CHECK_GL_ERROR();
}
@@ -722,8 +717,7 @@ void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2,
ApplyProgramMatrices(0.0f);
mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
- mpProgram->SetVertices(aVertices.data());
- glDrawArrays(GL_TRIANGLE_STRIP, 0, aVertices.size() / 2);
+ mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aVertices);
CHECK_GL_ERROR();
}
@@ -749,8 +743,7 @@ void OpenGLSalGraphicsImpl::DrawLineSegment(float x1, float y1, float x2, float
ApplyProgramMatrices(0.0f);
mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
- mpProgram->SetVertices(aPoints.data());
- glDrawArrays(GL_TRIANGLE_STRIP, 0, aPoints.size() / 2);
+ mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aPoints);
CHECK_GL_ERROR();
}
@@ -944,8 +937,7 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
ApplyProgramMatrices(0.0f);
mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
- mpProgram->SetVertices(aVertices.data());
- glDrawArrays(GL_TRIANGLE_STRIP, 0, aVertices.size() / 2);
+ mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aVertices);
CHECK_GL_ERROR();
}
@@ -1109,7 +1101,7 @@ void OpenGLSalGraphicsImpl::ImplDrawLineAA( double nX1, double nY1, double nX2,
tx = ty = 0;
}
- GLfloat vertices[]=
+ std::vector<GLfloat> vertices
{
GLfloat(x1-tx-Rx), GLfloat(y1-ty-Ry), //fading edge1
GLfloat(x2-tx-Rx), GLfloat(y2-ty-Ry),
@@ -1124,8 +1116,7 @@ void OpenGLSalGraphicsImpl::ImplDrawLineAA( double nX1, double nY1, double nX2,
ApplyProgramMatrices(0.0f);
GLfloat aTexCoord[16] = { 0, 0, 1, 0, 2, 1, 3, 1, 4, 1, 5, 1, 6, 0, 7, 0 };
mpProgram->SetTextureCoord( aTexCoord );
- mpProgram->SetVertices( vertices );
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
+ mpProgram->DrawArrays(GL_TRIANGLE_STRIP, vertices);
CHECK_GL_ERROR();
}
@@ -1160,8 +1151,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
}
ApplyProgramMatrices();
- mpProgram->SetVertices( &aVertices[0] );
- glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+ mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
CHECK_GL_ERROR();
if( !blockAA && mrParent.getAntiAliasB2DDraw())
@@ -1204,8 +1194,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const tools::Polygon& rPolygon, b
}
ApplyProgramMatrices();
- mpProgram->SetVertices( &aVertices[0] );
- glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+ mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
CHECK_GL_ERROR();
if( !blockAA && mrParent.getAntiAliasB2DDraw())
@@ -1255,8 +1244,7 @@ void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoi
}
ApplyProgramMatrices();
- mpProgram->SetVertices( &aVertices[0] );
- glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+ mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
CHECK_GL_ERROR();
if( !blockAA && mrParent.getAntiAliasB2DDraw())
@@ -1369,8 +1357,7 @@ void OpenGLSalGraphicsImpl::DrawRegionBand( const RegionBand& rRegion )
#undef ADD_VERTICE
ApplyProgramMatrices();
- mpProgram->SetVertices( &aVertices[0] );
- glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
+ mpProgram->DrawArrays(GL_TRIANGLES, aVertices);
CHECK_GL_ERROR();
}
@@ -1449,9 +1436,13 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
{
OpenGLZone aZone;
- GLfloat aVertices[8] = {
- 0, (float) rTexture.GetHeight(), 0, 0,
- (float) rTexture.GetWidth(), 0, (float) rTexture.GetWidth(), (float) rTexture.GetHeight() };
+ std::vector<GLfloat> aVertices = {
+ 0, GLfloat(rTexture.GetHeight()),
+ 0, 0,
+ GLfloat(rTexture.GetWidth()), 0,
+ GLfloat(rTexture.GetWidth()), GLfloat(rTexture.GetHeight())
+ };
+
GLfloat aTexCoord[8];
const long nDestWidth = basegfx::fround(basegfx::B2DVector(rX - rNull).getLength());
@@ -1587,8 +1578,7 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
mpProgram->SetTexture("sampler", aInTexture);
aInTexture.SetFilter(GL_LINEAR);
mpProgram->SetTextureCoord( aTexCoord );
- mpProgram->SetVertices( aVertices );
- glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+ mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
CHECK_GL_ERROR();
mpProgram->Clean();
@@ -1730,8 +1720,7 @@ void OpenGLSalGraphicsImpl::FlushDeferredDrawing()
TextureDrawParameters& rParameters = rColorTwoRectPair.second;
ApplyProgramMatrices();
mpProgram->SetTextureCoord(rParameters.maTextureCoords.data());
- mpProgram->SetVertices(rParameters.maVertices.data());
- glDrawArrays(GL_TRIANGLES, 0, rParameters.getNumberOfVertices());
+ mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
}
}
#endif
@@ -1751,8 +1740,7 @@ void OpenGLSalGraphicsImpl::FlushDeferredDrawing()
TextureDrawParameters& rParameters = rColorTwoRectPair.second;
ApplyProgramMatrices();
mpProgram->SetTextureCoord(rParameters.maTextureCoords.data());
- mpProgram->SetVertices(rParameters.maVertices.data());
- glDrawArrays(GL_TRIANGLES, 0, rParameters.getNumberOfVertices());
+ mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
}
}
mpProgram->Clean();
@@ -1920,20 +1908,15 @@ void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeigh
GLfloat fX2(nX + nWidth - 1);
GLfloat fY2(nY + nHeight - 1);
- GLfloat pPoints[8];
-
- pPoints[0] = fX1;
- pPoints[1] = fY1;
- pPoints[2] = fX2;
- pPoints[3] = fY1;
- pPoints[4] = fX2;
- pPoints[5] = fY2;
- pPoints[6] = fX1;
- pPoints[7] = fY2;
+ std::vector<GLfloat> pPoints {
+ fX1, fY1,
+ fX2, fY1,
+ fX2, fY2,
+ fX1, fY2
+ };
ApplyProgramMatrices(0.5f);
- mpProgram->SetVertices(pPoints);
- glDrawArrays(GL_LINE_LOOP, 0, 4);
+ mpProgram->DrawArrays(GL_LINE_LOOP, pPoints);
CHECK_GL_ERROR();
}
@@ -2294,13 +2277,15 @@ bool OpenGLSalGraphicsImpl::blendBitmap(
VCL_GL_INFO( "::blendBitmap" );
PreDraw();
- glEnable( GL_BLEND );
- CHECK_GL_ERROR();
- glBlendFunc( GL_ZERO, GL_SRC_COLOR );
- CHECK_GL_ERROR();
- DrawTexture( rTexture, rPosAry );
- glDisable( GL_BLEND );
- CHECK_GL_ERROR();
+
+ if (!UseProgram("textureVertexShader", "textureFragmentShader"))
+ return true;
+
+ mpProgram->SetBlendMode(GL_ZERO, GL_SRC_COLOR);
+ mpProgram->SetTexture("sampler", rTexture);
+ DrawTextureRect(rTexture, rPosAry, false);
+ mpProgram->Clean();
+
PostDraw();
return true;
}
@@ -2593,14 +2578,15 @@ void OpenGLSalGraphicsImpl::doFlush()
GLfloat fWidth( maOffscreenTex.GetWidth() );
GLfloat fHeight( maOffscreenTex.GetHeight() );
- const GLfloat aVertices[] = { 0, fHeight,
- 0, 0,
- fWidth, 0,
- fWidth, fHeight };
+ std::vector<GLfloat> aVertices {
+ 0, fHeight,
+ 0, 0,
+ fWidth, 0,
+ fWidth, fHeight
+ };
pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0);
- pProgram->SetVertices( &aVertices[0] );
- glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+ pProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
pProgram->Clean();
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index c4f5c0e5ec02..71530cbf75cb 100644
--- a/vcl/opengl/program.cxx
+++ b/vcl/opengl/program.cxx
@@ -51,13 +51,19 @@ bool OpenGLProgram::Load( const OUString& rVertexShader,
return ( mnId != 0 );
}
+void OpenGLProgram::Reuse()
+{
+ mbBlending = false;
+}
+
bool OpenGLProgram::Use()
{
- if( !mnId )
+ if (!mnId)
return false;
- glUseProgram( mnId );
+ glUseProgram(mnId);
CHECK_GL_ERROR();
+ Reuse();
return true;
}
@@ -84,14 +90,6 @@ bool OpenGLProgram::Clean()
mnEnabledAttribs = 0;
}
- // disable blending if enabled
- if( mbBlending )
- {
- mbBlending = false;
- glDisable( GL_BLEND );
- CHECK_GL_ERROR();
- }
-
return true;
}
@@ -151,6 +149,15 @@ GLuint OpenGLProgram::GetUniformLocation( const OString& rName )
return it->second;
}
+void OpenGLProgram::DrawArrays(GLenum aMode, std::vector<GLfloat>& aVertices)
+{
+ if (!mbBlending)
+ OpenGLContext::getVCLContext()->state()->blend().disable();
+
+ SetVertices(aVertices.data());
+ glDrawArrays(aMode, 0, aVertices.size() / 2);
+}
+
void OpenGLProgram::SetUniform1f( const OString& rName, GLfloat v1 )
{
GLuint nUniform = GetUniformLocation( rName );
@@ -301,12 +308,10 @@ void OpenGLProgram::ApplyMatrix(float fWidth, float fHeight, float fPixelOffset)
CHECK_GL_ERROR();
}
-void OpenGLProgram::SetBlendMode( GLenum nSFactor, GLenum nDFactor )
+void OpenGLProgram::SetBlendMode(GLenum nSFactor, GLenum nDFactor)
{
- glEnable( GL_BLEND );
- CHECK_GL_ERROR();
- glBlendFunc( nSFactor, nDFactor );
- CHECK_GL_ERROR();
+ OpenGLContext::getVCLContext()->state()->blend().enable();
+ OpenGLContext::getVCLContext()->state()->blend().func(nSFactor, nDFactor);
mbBlending = true;
}
@@ -323,14 +328,18 @@ bool OpenGLProgram::DrawTexture( const OpenGLTexture& rTexture )
float fMinY = 0.0f;
float fMaxY = fHeight;
- GLfloat aPosition[8] = { fMinX, fMaxY, fMinX, fMinY, fMaxX, fMinY, fMaxX, fMaxY };
+ std::vector<GLfloat> aPosition {
+ fMinX, fMaxY,
+ fMinX, fMinY,
+ fMaxX, fMinY,
+ fMaxX, fMaxY
+ };
GLfloat aTexCoord[8];
rTexture.GetWholeCoord( aTexCoord );
- SetVertices( aPosition );
SetTextureCoord( aTexCoord );
ApplyMatrix(fWidth, fHeight);
- glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+ DrawArrays(GL_TRIANGLE_FAN, aPosition);
CHECK_GL_ERROR();
return true;
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 5a8334cf27f4..de8c7099ca97 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -1806,8 +1806,12 @@ OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const O
OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader, preamble );
- if( pProgram == mpCurrentProgram )
+ if (pProgram == mpCurrentProgram)
+ {
+ VCL_GL_INFO("Context::UseProgram: Reusing existing program " << pProgram->Id());
+ pProgram->Reuse();
return pProgram;
+ }
mpCurrentProgram = pProgram;