Kaydet (Commit) 344dc693 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

opengl: batch drawing of pixel, line, rect draw calls

Change-Id: Ib1619fa476f488c5315411b1ad4d1b7464c70c69
üst d0ec6c7b
......@@ -621,6 +621,7 @@ else
vcl/opengl/texture \
vcl/opengl/FixedTextureAtlas \
vcl/opengl/PackedTextureAtlas \
vcl/opengl/RenderList \
vcl/source/opengl/OpenGLContext \
vcl/source/opengl/OpenGLHelper \
vcl/source/window/openglwin \
......
/* -*- 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/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
#define INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
#include <glm/glm.hpp>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <vcl/salgtype.hxx>
#include <basegfx/range/b2drange.hxx>
struct RenderParameters
{
std::vector<GLfloat> maVertices;
std::vector<GLfloat> maExtrusionVectors;
std::vector<glm::vec4> maColors;
};
struct RenderEntry
{
RenderParameters maTriangleParameters;
RenderParameters maLineParameters;
RenderParameters maLineAAParameters;
bool hasTriangles()
{
return !maTriangleParameters.maVertices.empty();
}
bool hasLines()
{
return !maLineParameters.maVertices.empty();
}
bool hasLinesAA()
{
return !maLineAAParameters.maVertices.empty();
}
};
class RenderList
{
private:
basegfx::B2DRange maOverlapTrackingRectangle;
std::vector<RenderEntry> maRenderEntries;
void checkOverlapping(const basegfx::B2DRange& rDrawRectangle)
{
if (maRenderEntries.empty() || maOverlapTrackingRectangle.overlaps(rDrawRectangle))
{
maRenderEntries.resize(maRenderEntries.size() + 1);
maOverlapTrackingRectangle = rDrawRectangle;
}
else
{
maOverlapTrackingRectangle.expand(rDrawRectangle);
}
}
public:
RenderList() = default;
bool empty()
{
return maRenderEntries.empty();
}
void clear()
{
maRenderEntries.clear();
maOverlapTrackingRectangle.reset();
}
std::vector<RenderEntry>& getEntries()
{
return maRenderEntries;
}
void addDrawPixel(long nX, long nY, const SalColor& rColor);
void addDrawRectangle(long nX, long nY, long nWidth, long nHeight,
const SalColor& rLineColor, const SalColor& rFillColor);
void addDrawLine(long nX1, long nY1, long nX2, long nY2, const SalColor& rLineColor, bool bUseAA);
};
#endif // INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -39,6 +39,44 @@ inline void addRectangle<GL_TRIANGLE_FAN>(std::vector<GLfloat>& rVertices, GLflo
});
}
inline glm::vec4 createGLColor(const SalColor& rColor, GLfloat rTransparency)
{
return glm::vec4(SALCOLOR_RED(rColor) / 255.0f,
SALCOLOR_GREEN(rColor) / 255.0f,
SALCOLOR_BLUE(rColor) / 255.0f,
1.0f - rTransparency);
}
template<GLenum TYPE>
inline void addQuadColors(std::vector<glm::vec4>& rColors, const SalColor& rColor, GLfloat rTransparency);
template<>
inline void addQuadColors<GL_TRIANGLES>(std::vector<glm::vec4>& rColors, const SalColor& rColor, GLfloat rTransparency)
{
glm::vec4 color = createGLColor(rColor, rTransparency);
rColors.insert(rColors.end(), {
color, color, color,
color, color, color
});
}
template<GLenum TYPE>
inline void addQuadEmptyExtrusionVectors(std::vector<GLfloat>& rExtrusions);
template<>
inline void addQuadEmptyExtrusionVectors<GL_TRIANGLES>(std::vector<GLfloat>& rExtrusions)
{
rExtrusions.insert(rExtrusions.end(), {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
});
}
inline void addLineVertex(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors, glm::vec2 point, glm::vec2 extrusionVector, float length)
{
rVertices.push_back(point.x);
......
......@@ -22,6 +22,7 @@
#include <tools/color.hxx>
#include <opengl/texture.hxx>
#include <glm/glm.hpp>
#include <unordered_map>
typedef std::unordered_map< OString, GLuint, OStringHash > UniformCache;
......@@ -52,7 +53,9 @@ private:
GLuint mnTexCoordAttrib;
GLuint mnAlphaCoordAttrib;
GLuint mnMaskCoordAttrib;
GLuint mnNormalAttrib;
GLuint mnExtrusionVectorsAttrib;
GLuint mnVertexColorsAttrib;
TextureList maTextures;
bool mbBlending;
......@@ -79,6 +82,7 @@ public:
void SetAlphaCoord( const GLvoid* pData );
void SetMaskCoord(const GLvoid* pData);
void SetExtrusionVectors(const GLvoid* pData);
void SetVertexColors(std::vector<glm::vec4>& rColorVector);
void SetUniform1f( const OString& rName, GLfloat v1 );
void SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 );
......
......@@ -78,6 +78,8 @@ private:
ImplOpenGLTexture* mpImpl;
int mnSlotNumber;
inline bool GetTextureRect(const SalTwoRect& rPosAry, bool bInverted, GLfloat& x1, GLfloat& x2, GLfloat& y1, GLfloat& y2) const;
public:
OpenGLTexture();
OpenGLTexture(ImplOpenGLTexture* pImpl, Rectangle aRectangle, int nSlotNumber);
......@@ -124,6 +126,10 @@ template<> void OpenGLTexture::FillCoords<GL_TRIANGLES>(
std::vector<GLfloat>& aCoord, const SalTwoRect& rPosAry, bool bInverted)
const;
template<> void OpenGLTexture::FillCoords<GL_TRIANGLE_FAN>(
std::vector<GLfloat>& aCoord, const SalTwoRect& rPosAry, bool bInverted)
const;
#endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -30,6 +30,7 @@
#include "opengl/program.hxx"
#include "opengl/texture.hxx"
#include "opengl/AccumulatedTextures.hxx"
#include "opengl/RenderList.hxx"
#include <memory>
......@@ -100,7 +101,8 @@ protected:
SalColor mProgramSolidColor;
double mProgramSolidTransparency;
std::unique_ptr<AccumulatedTextures> mpAccumulatedTextures;
std::unique_ptr<AccumulatedTextures> mpAccumulatedTextures;
std::unique_ptr<RenderList> mpRenderList;
void ImplInitClipRegion();
void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
......@@ -114,12 +116,12 @@ public:
bool UseSolid( SalColor nColor, sal_uInt8 nTransparency );
bool UseSolid( SalColor nColor, double fTransparency );
bool UseSolid( SalColor nColor );
bool UseSolid();
bool UseLine(SalColor nColor, double fTransparency, GLfloat fLineWidth, bool bUseAA);
bool UseLine(GLfloat fLineWidth, bool bUseAA);
bool UseInvert50();
bool UseInvert(SalInvert nFlags);
void DrawPoint( long nX, long nY );
void DrawLine( double nX1, double nY1, double nX2, double nY2 );
void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, bool blockAA = false );
void DrawConvexPolygon( const tools::Polygon& rPolygon, bool blockAA = false );
void DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid, bool blockAA = false );
......
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include "opengl/RenderList.hxx"
#include "opengl/VertexUtils.hxx"
namespace
{
inline void lclAddLineSegmentVertices(RenderParameters& rRenderParameter, GLfloat fX1, GLfloat fY1, GLfloat fX2, GLfloat fY2,
const SalColor& rColor, double fTransparency)
{
glm::vec2 aPoint1(fX1, fY1);
glm::vec2 aPoint2(fX2, fY2);
glm::vec2 aLineVector = vcl::vertex::normalize(aPoint2 - aPoint1);
glm::vec2 aNormal = glm::vec2(-aLineVector.y, aLineVector.x);
vcl::vertex::addLinePointFirst(rRenderParameter.maVertices, rRenderParameter.maExtrusionVectors,
aPoint1, aNormal, 1.0f);
vcl::vertex::addLinePointNext (rRenderParameter.maVertices, rRenderParameter.maExtrusionVectors,
aPoint1, aNormal, 1.0f,
aPoint2, aNormal, 1.0f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rColor, fTransparency);
}
} // end anonymous namespace
void RenderList::addDrawPixel(long nX, long nY, const SalColor& rColor)
{
if (rColor == SALCOLOR_NONE)
return;
checkOverlapping(basegfx::B2DRange(nX, nY, nX, nY));
RenderParameters& rRenderParameter = maRenderEntries.back().maTriangleParameters;
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, nX - 0.5f, nY - 0.5f, nX + 0.5f, nY + 0.5f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rColor, 0.0f);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
}
void RenderList::addDrawRectangle(long nX, long nY, long nWidth, long nHeight, const SalColor& rLineColor, const SalColor& rFillColor)
{
if (rLineColor == SALCOLOR_NONE && rFillColor == SALCOLOR_NONE)
return;
GLfloat fX1(nX);
GLfloat fY1(nY);
GLfloat fX2(nX + nWidth - 1);
GLfloat fY2(nY + nHeight - 1);
checkOverlapping(basegfx::B2DRange(fX1, fY1, fX2, fY2));
RenderParameters& rRenderParameter = maRenderEntries.back().maTriangleParameters;
// Draw rectangle stroke with line color
if (rLineColor != SALCOLOR_NONE)
{
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY1 - 0.5f, fX1 + 0.5f, fY2 + 0.5f);
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY1 + 0.5f);
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX2 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY2 + 0.5f);
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY2 - 0.5f, fX2 + 0.5f, fY2 + 0.5f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rLineColor, 0.0f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rLineColor, 0.0f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rLineColor, 0.0f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rLineColor, 0.0f);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
}
if (rFillColor != SALCOLOR_NONE)
{
if (rLineColor == SALCOLOR_NONE)
{
// Draw rectangle stroke with fill color
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY1 - 0.5f, fX1 + 0.5f, fY2 + 0.5f);
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY1 + 0.5f);
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX2 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY2 + 0.5f);
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 - 0.5f, fY2 - 0.5f, fX2 + 0.5f, fY2 + 0.5f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
}
// Draw rectangle fill with fill color
vcl::vertex::addRectangle<GL_TRIANGLES>(rRenderParameter.maVertices, fX1 + 0.5f, fY1 + 0.5f, fX2 - 0.5f, fY2 - 0.5f);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rRenderParameter.maColors, rFillColor, 0.0f);
vcl::vertex::addQuadEmptyExtrusionVectors<GL_TRIANGLES>(rRenderParameter.maExtrusionVectors);
}
}
void RenderList::addDrawLine(long nX1, long nY1, long nX2, long nY2, const SalColor& rLineColor, bool bUseAA)
{
if (rLineColor == SALCOLOR_NONE)
return;
checkOverlapping(basegfx::B2DRange(nX1, nY1, nX2, nY2));
RenderParameters& rRenderParameter = bUseAA ? maRenderEntries.back().maLineAAParameters :
maRenderEntries.back().maLineParameters;
lclAddLineSegmentVertices(rRenderParameter, nX1, nY1, nX2, nY2, rLineColor, 0.0f);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -8,8 +8,12 @@
*/
varying float fade_factor; // 0->1 fade factor used for AA
uniform vec4 color;
#ifdef USE_VERTEX_COLORS
varying vec4 vertex_color;
#endif
uniform vec4 color;
uniform float line_width;
uniform float feather;
......@@ -22,6 +26,12 @@ void main()
{
float alpha = 1.0;
#ifdef USE_VERTEX_COLORS
vec4 result = vertex_color;
#else
vec4 result = color;
#endif
if (type == TYPE_LINE)
{
float start = (line_width / 2.0) - feather; // where we start to apply alpha
......@@ -36,10 +46,9 @@ void main()
alpha = clamp(dist, 0.0, 1.0);
}
vec4 result_color = color;
result_color.a = result_color.a * alpha;
result.a = result.a * alpha;
gl_FragColor = result_color;
gl_FragColor = result;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -9,8 +9,14 @@
attribute vec2 position;
attribute vec4 extrusion_vectors;
#ifdef USE_VERTEX_COLORS
attribute vec4 vertex_color_in;
#endif
varying float fade_factor; // fade factor for anti-aliasing
#ifdef USE_VERTEX_COLORS
varying vec4 vertex_color;
#endif
uniform float line_width;
uniform float feather; // width where we fade the line
......@@ -42,6 +48,9 @@ void main()
}
gl_Position = mvp * final_position;
#ifdef USE_VERTEX_COLORS
vertex_color = vertex_color_in;
#endif
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
This diff is collapsed.
......@@ -24,8 +24,9 @@ OpenGLProgram::OpenGLProgram() :
mnTexCoordAttrib( SAL_MAX_UINT32 ),
mnAlphaCoordAttrib( SAL_MAX_UINT32 ),
mnMaskCoordAttrib( SAL_MAX_UINT32 ),
mnNormalAttrib( SAL_MAX_UINT32 ),
mbBlending( false ),
mnExtrusionVectorsAttrib( SAL_MAX_UINT32 ),
mnVertexColorsAttrib( SAL_MAX_UINT32 ),
mbBlending(false),
mfLastWidth(0.0),
mfLastHeight(0.0),
mfLastPixelOffset(0.0)
......@@ -147,7 +148,12 @@ void OpenGLProgram::SetMaskCoord(const GLvoid* pData)
void OpenGLProgram::SetExtrusionVectors(const GLvoid* pData)
{
SetVertexAttrib(mnNormalAttrib, "extrusion_vectors", pData, 3);
SetVertexAttrib(mnExtrusionVectorsAttrib, "extrusion_vectors", pData, 3);
}
void OpenGLProgram::SetVertexColors(std::vector<glm::vec4>& rColorVector)
{
SetVertexAttrib(mnVertexColorsAttrib, "vertex_color_in", glm::value_ptr(rColorVector[0]), 4);
}
void OpenGLProgram::SetShaderType(TextureShaderType eTextureShaderType)
......
......@@ -386,18 +386,8 @@ void OpenGLTexture::GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool b
}
}
template <>
void OpenGLTexture::FillCoords<GL_TRIANGLES>(std::vector<GLfloat>& aCoord, const SalTwoRect& rPosAry, bool bInverted) const
bool OpenGLTexture::GetTextureRect(const SalTwoRect& rPosAry, bool bInverted, GLfloat& x1, GLfloat& x2, GLfloat& y1, GLfloat& y2) const
{
VCL_GL_INFO("Add coord " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() );
VCL_GL_INFO(" With 2Rect Src [" << rPosAry.mnSrcX << ", " << rPosAry.mnSrcY << "] wh (" << rPosAry.mnSrcWidth << ", " << rPosAry.mnSrcHeight << ")");
VCL_GL_INFO(" With 2Rect Dest [" << rPosAry.mnDestX << ", " << rPosAry.mnDestY << "] wh (" << rPosAry.mnDestWidth << ", " << rPosAry.mnDestHeight << ")");
GLfloat x1 = 0.0f;
GLfloat x2 = 0.0f;
GLfloat y1 = 0.0f;
GLfloat y2 = 0.0f;
if (mpImpl)
{
double fTextureWidth(mpImpl->mnWidth);
......@@ -416,25 +406,41 @@ void OpenGLTexture::FillCoords<GL_TRIANGLES>(std::vector<GLfloat>& aCoord, const
y1 = 1.0f - (maRect.Top() + rPosAry.mnSrcY) / fTextureHeight;
y2 = 1.0f - (maRect.Top() + rPosAry.mnSrcY + rPosAry.mnSrcHeight) / fTextureHeight;
}
return true;
}
return false;
}
aCoord.push_back(x1);
aCoord.push_back(y1);
template <>
void OpenGLTexture::FillCoords<GL_TRIANGLE_FAN>(std::vector<GLfloat>& rCoords, const SalTwoRect& rPosAry, bool bInverted) const
{
GLfloat x1 = 0.0f;
GLfloat x2 = 0.0f;
GLfloat y1 = 0.0f;
GLfloat y2 = 0.0f;
aCoord.push_back(x2);
aCoord.push_back(y1);
GetTextureRect(rPosAry, bInverted, x1, x2, y1, y2);
aCoord.push_back(x1);
aCoord.push_back(y2);
rCoords.insert(rCoords.end(), {
x1, y2, x1, y1,
x2, y1, x2, y2
});
}
aCoord.push_back(x1);
aCoord.push_back(y2);
template <>
void OpenGLTexture::FillCoords<GL_TRIANGLES>(std::vector<GLfloat>& rCoords, const SalTwoRect& rPosAry, bool bInverted) const
{
GLfloat x1 = 0.0f;
GLfloat x2 = 0.0f;
GLfloat y1 = 0.0f;
GLfloat y2 = 0.0f;
aCoord.push_back(x2);
aCoord.push_back(y1);
GetTextureRect(rPosAry, bInverted, x1, x2, y1, y2);
aCoord.push_back(x2);
aCoord.push_back(y2);
rCoords.insert(rCoords.end(), {
x1, y1, x2, y1, x1, y2,
x1, y2, x2, y1, x2, y2
});
}
void OpenGLTexture::GetWholeCoord( GLfloat* pCoord ) const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment