diff options
-rw-r--r-- | vcl/inc/opengl/RenderState.hxx | 27 | ||||
-rw-r--r-- | vcl/inc/opengl/program.hxx | 5 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 116 | ||||
-rw-r--r-- | vcl/opengl/program.cxx | 45 | ||||
-rw-r--r-- | vcl/source/opengl/OpenGLContext.cxx | 6 |
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; |