remove OpenGL VCL backend code

It is by now practically unmaintained, even bugreports in bugzilla
have been already closed for it. AFAICT this used to be really
used only on Windows, where it's no longer the default.

There's still some OpenGL code left, because there are still two
other places that use OpenGL. One is OpenGL slideshows, which
reuse some of the base OpenGL code (and I've checked they
still work even after this removal). Second one is OpenGL canvas,
which it seems has never been finished or enabled (or so it
most probably should be dumped too).

Change-Id: I7ea5aef77ec252eb8e712d167db591209be84a13
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107290
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
This commit is contained in:
Luboš Luňák
2020-12-07 20:46:49 +01:00
parent 6265cfca9d
commit db89f53c31
101 changed files with 35 additions and 9990 deletions
-2
View File
@@ -48,8 +48,6 @@ namespace cairocanvas
if( !maArguments.hasElements() )
return;
// tdf#93870 - force VCL canvas in OpenGL mode for now.
assert( !OpenGLWrapper::isVCLOpenGLEnabled() );
assert( !SkiaHelper::isVCLSkiaEnabled() );
/* maArguments:
-2
View File
@@ -77,8 +77,6 @@ namespace dxcanvas
if( maArguments.getLength() == 0 )
return;
// tdf#93870 - force VCL canvas in OpenGL mode for now.
assert( !OpenGLWrapper::isVCLOpenGLEnabled() );
assert( !SkiaHelper::isVCLSkiaEnabled() );
SAL_INFO("canvas.directx", "Canvas::initialize called" );
-6
View File
@@ -299,12 +299,6 @@ Reference<XInterface> CanvasFactory::lookupAndUse(
m_bCacheHasForcedLastImpl,
"ForceSafeServiceImpl" );
// tdf#93870 - force VCL canvas in OpenGL mode for now.
#if HAVE_FEATURE_OPENGL
if( OpenGLWrapper::isVCLOpenGLEnabled() )
bForceLastEntry = true;
#endif
// use anti-aliasing canvas, if config flag set (or not existing)
bool bUseAAEntry(true);
checkConfigFlag( bUseAAEntry,
-10
View File
@@ -78,9 +78,6 @@
#include <vcl/settings.hxx>
#include <vcl/window.hxx>
#include <vcl/IconThemeInfo.hxx>
#if HAVE_FEATURE_OPENGL
#include <vcl/opengl/OpenGLWrapper.hxx>
#endif
#include <vcl/skia/SkiaHelper.hxx>
#include "optgdlg.hxx"
#include <svtools/apearcfg.hxx>
@@ -467,13 +464,6 @@ CanvasSettings::CanvasSettings() :
bool CanvasSettings::IsHardwareAccelerationAvailable() const
{
#if HAVE_FEATURE_OPENGL
if (OpenGLWrapper::isVCLOpenGLEnabled() && Application::GetToolkitName() != "gtk3")
{
mbHWAccelAvailable = false;
return false;
}
#endif
if( !mbHWAccelChecked )
{
mbHWAccelChecked = true;
@@ -37,7 +37,6 @@
#include <rtl/ustrbuf.hxx>
#include <osl/mutex.hxx>
#include <tools/urlobj.hxx>
#include <vcl/opengl/OpenGLWrapper.hxx>
#include <vcl/skia/SkiaHelper.hxx>
#include <vcl/svapp.hxx>
@@ -600,10 +599,6 @@ void TitleHelper::impl_appendDebugVersion (OUStringBuffer& sTitle)
OUString sVersion = ::utl::Bootstrap::getBuildIdData("development");
sTitle.append(" [");
sTitle.append(sVersion);
#if HAVE_FEATURE_UI
if (OpenGLWrapper::isVCLOpenGLEnabled() && !SkiaHelper::isVCLSkiaEnabled())
sTitle.append("-GL");
#endif
sTitle.append("]");
}
#else
-39
View File
@@ -19,11 +19,6 @@
#include <memory>
#include <unordered_map>
class OpenGLFramebuffer;
class OpenGLProgram;
class OpenGLTexture;
class RenderState;
/// Holds the information of our new child window
struct VCL_DLLPUBLIC GLWindow
{
@@ -72,25 +67,12 @@ public:
// use these methods right after setting a context to make sure drawing happens
// in the right FBO (default one is for onscreen painting)
void BindFramebuffer( OpenGLFramebuffer* pFramebuffer );
void AcquireDefaultFramebuffer();
OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture );
static void ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer );
void UnbindTextureFromFramebuffers( GLuint nTexture );
static bool IsTextureAttachedAnywhere( GLuint nTexture );
void ReleaseFramebuffer( const OpenGLTexture& rTexture );
void ReleaseFramebuffers();
// retrieve a program from the cache or compile/link it
OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
RenderState& state()
{
return *mpRenderState;
}
OpenGLCapabilitySwitch& getOpenGLCapabilitySwitch()
{
return maOpenGLCapabilitySwitch;
@@ -107,10 +89,6 @@ public:
/// Is there a current GL context ?
static bool hasCurrent();
/// make a VCL context (any context) current, create it if necessary.
static void makeVCLCurrent();
/// fetch any VCL context, creating one if bMakeIfNecessary is set.
static rtl::Reference<OpenGLContext> getVCLContext(bool bMakeIfNecessary = true);
/// make this GL context current - so it is implicit in subsequent GL calls
virtual void makeCurrent();
/// Put this GL context to the end of the context list.
@@ -134,10 +112,6 @@ public:
return mbInitialized;
}
/// VCL promiscuously re-uses its own contexts:
void setVCLOnly() { mbVCLOnly = true; }
bool isVCLOnly() const { return mbVCLOnly; }
virtual SystemWindowData generateWinData(vcl::Window* pParent, bool bRequestLegacyContext);
private:
@@ -159,22 +133,9 @@ protected:
bool mbInitialized;
int mnRefCount;
bool mbRequestLegacyContext;
bool mbVCLOnly;
int mnFramebufferCount;
OpenGLFramebuffer* mpCurrentFramebuffer;
OpenGLFramebuffer* mpFirstFramebuffer;
OpenGLFramebuffer* mpLastFramebuffer;
OpenGLCapabilitySwitch maOpenGLCapabilitySwitch;
private:
typedef std::unordered_map< OString, std::shared_ptr<OpenGLProgram> > ProgramCollection;
ProgramCollection maPrograms;
OpenGLProgram* mpCurrentProgram;
std::unique_ptr<RenderState> mpRenderState;
public:
vcl::Region maClipRegion;
+1 -3
View File
@@ -51,7 +51,6 @@
#include <unotools/transliterationwrapper.hxx>
#include <comphelper/lok.hxx>
#include <vcl/opengl/OpenGLWrapper.hxx>
#include <global.hxx>
#include <scresid.hxx>
@@ -460,10 +459,9 @@ void ScGlobal::InitPPT()
{
OutputDevice* pDev = Application::GetDefaultDevice();
if (comphelper::LibreOfficeKit::isActive() || OpenGLWrapper::isVCLOpenGLEnabled())
if (comphelper::LibreOfficeKit::isActive())
{
// LOK: the below limited precision is not enough for RowColumnHeader.
// OpenGL: limited precision breaks AA of text in charts.
nScreenPPTX = double(pDev->GetDPIX()) / double(TWIPS_PER_INCH);
nScreenPPTY = double(pDev->GetDPIY()) / double(TWIPS_PER_INCH);
}
-12
View File
@@ -20,11 +20,6 @@
#include <unotools/mediadescriptor.hxx>
#include <rtl/ustring.hxx>
#ifdef _WIN32
#include <vcl/opengl/OpenGLWrapper.hxx>
#include <vcl/skia/SkiaHelper.hxx>
#endif
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
@@ -295,13 +290,6 @@ void SdExportTest::testTransparentBackground()
void SdExportTest::testMediaEmbedding()
{
#ifdef _WIN32
// This seems broken. This test should not be disabled for all cases except when OpenGL
// is found to be working, just because in some OpenGL setups this breaks (per the commit log message).
if (!OpenGLWrapper::isVCLOpenGLEnabled() && !SkiaHelper::isVCLSkiaEnabled())
return;
#endif
::sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/media_embedding.odp"), ODP);
const SdrPage *pPage = GetPage( 1, xDocShRef );
-12
View File
@@ -592,16 +592,6 @@ else # ! DISABLE_GUI
$(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/opengl/DeviceInfo \
vcl/opengl/gdiimpl \
vcl/opengl/salbmp \
vcl/opengl/scale \
vcl/opengl/framebuffer \
vcl/opengl/program \
vcl/opengl/texture \
vcl/opengl/FixedTextureAtlas \
vcl/opengl/PackedTextureAtlas \
vcl/opengl/RenderList \
vcl/opengl/LineRenderUtils \
vcl/source/opengl/OpenGLContext \
vcl/source/opengl/OpenGLHelper \
vcl/skia/SkiaHelper \
@@ -612,8 +602,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
) \
))
# runtime dependency
$(eval $(call gb_Library_use_package,vcl,vcl_opengl_shader))
ifeq ($(OS),WNT)
$(eval $(call gb_Library_use_package,vcl,vcl_opengl_denylist))
endif
-2
View File
@@ -108,9 +108,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
vcl/unx/generic/window/salobj \
vcl/unx/x11/x11sys \
vcl/unx/x11/xlimits \
vcl/opengl/x11/cairotextrender \
vcl/opengl/x11/gdiimpl \
vcl/opengl/x11/salvd \
$(if $(filter SKIA,$(BUILD_TYPE)), \
vcl/skia/x11/gdiimpl \
vcl/skia/x11/salvd \
-1
View File
@@ -65,7 +65,6 @@ $(eval $(call gb_Library_use_externals,vclplug_win,\
$(eval $(call gb_Library_add_exception_objects,vclplug_win,\
vcl/opengl/win/gdiimpl \
vcl/opengl/win/winlayout \
vcl/win/app/saldata \
vcl/win/app/salinfo \
vcl/win/app/salinst \
-1
View File
@@ -21,7 +21,6 @@ $(eval $(call gb_Module_Module,vcl))
$(eval $(call gb_Module_add_targets,vcl,\
Library_vcl \
Package_opengl_shader \
Package_theme_definitions \
Package_tipoftheday \
Package_toolbarmode \
-41
View File
@@ -1,41 +0,0 @@
# -*- 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/shaders))
$(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
areaHashCRC64TFragmentShader.glsl \
areaScaleFastFragmentShader.glsl \
areaScaleFragmentShader.glsl \
blendedTextureFragmentShader.glsl \
blendedTextureVertexShader.glsl \
dumbVertexShader.glsl \
diffTextureFragmentShader.glsl \
greyscaleFragmentShader.glsl \
invert50FragmentShader.glsl \
convolutionFragmentShader.glsl \
linearGradientFragmentShader.glsl \
combinedTextureFragmentShader.glsl \
combinedTextureVertexShader.glsl \
combinedFragmentShader.glsl \
combinedVertexShader.glsl \
lineFragmentShader.glsl \
lineVertexShader.glsl \
maskFragmentShader.glsl \
maskedTextureVertexShader.glsl \
maskedTextureFragmentShader.glsl \
radialGradientFragmentShader.glsl \
replaceColorFragmentShader.glsl \
solidFragmentShader.glsl \
textureFragmentShader.glsl \
textureVertexShader.glsl \
transformedTextureVertexShader.glsl \
))
# vim: set noet sw=4 ts=4:
-80
View File
@@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_BUFFEROBJECT_H
#define INCLUDED_VCL_INC_OPENGL_BUFFEROBJECT_H
namespace vcl
{
template <typename TYPE, GLenum BUFFER_TYPE> class BufferObject
{
private:
GLuint mId;
public:
BufferObject()
: mId(0)
{
glGenBuffers(1, &mId);
CHECK_GL_ERROR();
}
virtual ~BufferObject()
{
if (mId)
{
glDeleteBuffers(1, &mId);
CHECK_GL_ERROR();
mId = 0;
}
}
void bind()
{
if (mId)
{
glBindBuffer(BUFFER_TYPE, mId);
CHECK_GL_ERROR();
}
}
void unbind()
{
if (mId)
{
glBindBuffer(BUFFER_TYPE, 0);
CHECK_GL_ERROR();
}
}
void upload(const std::vector<TYPE>& rData)
{
if (mId)
{
bind();
glBufferData(BUFFER_TYPE, sizeof(TYPE) * rData.size(), rData.data(), GL_STATIC_DRAW);
CHECK_GL_ERROR();
}
}
};
template <typename TYPE> class VertexBufferObject final : public BufferObject<TYPE, GL_ARRAY_BUFFER>
{
};
class IndexBufferObject final : public BufferObject<GLuint, GL_ELEMENT_ARRAY_BUFFER>
{
};
} // end vcl
#endif // INCLUDED_VCL_INC_OPENGL_BUFFEROBJECT_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-47
View File
@@ -1,47 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_FIXEDTEXTUREATLAS_HXX
#define INCLUDED_VCL_INC_OPENGL_FIXEDTEXTUREATLAS_HXX
#include <memory>
#include <opengl/texture.hxx>
struct FixedTexture;
class FixedTextureAtlasManager final
{
std::vector<std::unique_ptr<FixedTexture>> maFixedTextures;
int mWidthFactor;
int mHeightFactor;
int mSubTextureSize;
void CreateNewTexture();
FixedTextureAtlasManager( const FixedTextureAtlasManager& ) = delete;
FixedTextureAtlasManager& operator=( const FixedTextureAtlasManager& ) = delete;
public:
FixedTextureAtlasManager(int nWidthFactor, int nHeightFactor, int nTextureSize);
~FixedTextureAtlasManager();
OpenGLTexture InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8 const * pData);
OpenGLTexture Reserve(int nWidth, int nHeight);
int GetSubtextureSize() const
{
return mSubTextureSize;
}
};
#endif // INCLUDED_VCL_INC_OPENGL_FIXEDTEXTUREATLAS_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-55
View File
@@ -1,55 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_LINERENDERUTILS_H
#define INCLUDED_VCL_INC_OPENGL_LINERENDERUTILS_H
#include <opengl/RenderList.hxx>
namespace vcl
{
class LineBuilder
{
private:
std::vector<Vertex>& mrVertices;
std::vector<GLuint>& mrIndices;
GLubyte mR, mG, mB, mA;
GLfloat mfLineWidth;
GLfloat mfLineWidthAndAA;
size_t mnInitialIndexSize;
bool mbIncomplete;
public:
LineBuilder(std::vector<Vertex>& rVertices, std::vector<GLuint>& rIndices,
Color nColor, GLfloat fTransparency,
GLfloat fLineWidth, bool bUseAA);
void appendLineSegment(const glm::vec2& rPoint1, const glm::vec2& rNormal1, GLfloat aExtrusion1,
const glm::vec2& rPoint2, const glm::vec2& rNormal2, GLfloat aExtrusion2);
void appendLine(const glm::vec2& rPoint1, const glm::vec2& rPoint2);
void appendAndConnectLinePoint(const glm::vec2& rPoint, const glm::vec2& aNormal, GLfloat aExtrusion);
void appendMiterJoint(glm::vec2 const& point, const glm::vec2& prevLineVector,
glm::vec2 const& nextLineVector);
void appendBevelJoint(glm::vec2 const& point, const glm::vec2& prevLineVector,
const glm::vec2& nextLineVector);
void appendRoundJoint(glm::vec2 const& point, const glm::vec2& prevLineVector,
const glm::vec2& nextLineVector);
void appendRoundLineCapVertices(const glm::vec2& rPoint1, const glm::vec2& rPoint2);
void appendSquareLineCapVertices(const glm::vec2& rPoint1, const glm::vec2& rPoint2);
};
} // end vcl
#endif // INCLUDED_VCL_INC_OPENGL_LINERENDERUTILS_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-57
View File
@@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_PACKEDTEXTUREATLAS_HXX
#define INCLUDED_VCL_INC_OPENGL_PACKEDTEXTUREATLAS_HXX
#include <memory>
#include <opengl/texture.hxx>
struct PackedTexture;
/**
* Pack textures into one texture atlas.
*
* This is based on algorithm described in [1] and is an
* adaptation of "texture atlas generator" from [2].
*
* [1]: http://www.blackpawn.com/texts/lightmaps/
* [2]: https://github.com/lukaszdk/texture-atlas-generator
*
*/
class VCL_DLLPUBLIC PackedTextureAtlasManager final
{
std::vector<std::unique_ptr<PackedTexture>> maPackedTextures;
int mnTextureWidth;
int mnTextureHeight;
void CreateNewTexture();
PackedTextureAtlasManager( const PackedTextureAtlasManager& ) = delete;
PackedTextureAtlasManager& operator=( const PackedTextureAtlasManager& ) = delete;
public:
/**
* nTextureWidth and nTextureHeight are the dimensions of the common texture(s)
* nTextureLimit is the maximum limit of that a texture atlas can have (0 or less - unlimited)
*/
PackedTextureAtlasManager(int nTextureWidth, int nTextureHeight);
~PackedTextureAtlasManager();
OpenGLTexture InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8 const * pData);
OpenGLTexture Reserve(int nWidth, int nHeight);
std::vector<GLuint> ReduceTextureNumber(int nMaxNumberOfTextures);
};
#endif // INCLUDED_VCL_INC_OPENGL_PACKEDTEXTUREATLAS_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-173
View File
@@ -1,173 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
#define INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
#include <unordered_map>
#include <glm/glm.hpp>
#include <vcl/salgtype.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <opengl/texture.hxx>
#include <com/sun/star/drawing/LineCap.hpp>
struct Vertex
{
glm::vec2 position;
glm::vec4 color;
glm::vec4 lineData;
};
static_assert(sizeof(Vertex) == (2*4 + 4*4 + 4*4), "Vertex struct has wrong size/alignment");
struct RenderParameters
{
std::vector<Vertex> maVertices;
std::vector<GLuint> maIndices;
};
struct RenderTextureParameters
{
std::vector<GLfloat> maVertices;
std::vector<GLfloat> maTextureCoords;
std::vector<GLubyte> maColors;
OpenGLTexture maTexture;
};
struct RenderEntry
{
basegfx::B2DRange maOverlapTrackingRectangle;
RenderParameters maTriangleParameters;
RenderParameters maLineParameters;
std::unordered_map<GLuint, RenderTextureParameters> maTextureParametersMap;
bool hasTriangles() const
{
return !maTriangleParameters.maVertices.empty();
}
bool hasLines() const
{
return !maLineParameters.maVertices.empty();
}
bool hasTextures() const
{
return !maTextureParametersMap.empty();
}
};
class RenderList
{
private:
std::vector<RenderEntry> maRenderEntries;
std::vector<basegfx::B2DRange> maRectangles;
bool doesOverlap(const basegfx::B2DRange& rDrawRectangle)
{
if (!maRenderEntries.back().maOverlapTrackingRectangle.overlaps(rDrawRectangle))
return false;
for (const basegfx::B2DRange& rRectangle : maRectangles)
{
if (rRectangle.overlaps(rDrawRectangle))
return true;
}
return false;
}
void checkOverlapping(const basegfx::B2DRange& rDrawRectangle)
{
if (maRenderEntries.empty() || doesOverlap(rDrawRectangle))
{
maRenderEntries.emplace_back();
maRenderEntries.back().maOverlapTrackingRectangle = rDrawRectangle;
maRectangles.clear();
maRectangles.reserve(30);
maRectangles.push_back(rDrawRectangle);
}
else
{
maRenderEntries.back().maOverlapTrackingRectangle.expand(rDrawRectangle);
if (maRectangles.size() < 30)
{
maRectangles.push_back(rDrawRectangle);
}
else
{
basegfx::B2DRange aTempRectangle(maRectangles[0]);
aTempRectangle.expand(rDrawRectangle);
double minArea = aTempRectangle.getWidth() * aTempRectangle.getHeight();
size_t index = 0;
double area;
for (size_t i = 1; i < maRectangles.size(); ++i)
{
aTempRectangle = maRectangles[i];
aTempRectangle.expand(rDrawRectangle);
area = aTempRectangle.getWidth() * aTempRectangle.getHeight();
if (area < minArea)
index = i;
}
maRectangles[index].expand(rDrawRectangle);
}
}
}
public:
RenderList() = default;
bool empty()
{
return maRenderEntries.empty();
}
void clear()
{
maRenderEntries.clear();
}
std::vector<RenderEntry>& getEntries()
{
return maRenderEntries;
}
VCL_DLLPUBLIC void addDrawTextureWithMaskColor(OpenGLTexture const & rTexture, Color nColor, const SalTwoRect& r2Rect);
void addDrawPixel(tools::Long nX, tools::Long nY, Color nColor);
void addDrawRectangle(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, double fTransparency,
Color nLineColor, Color nFillColor);
void addDrawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2, Color nLineColor, bool bUseAA);
void addDrawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency,
Color nLineColor, Color nFillColor, bool bUseAA);
void addDrawPolyLine(const basegfx::B2DPolygon& rPolygon, double fTransparency,
double fLineWidth, basegfx::B2DLineJoin eLineJoin,
css::drawing::LineCap eLineCap, double fMiterMinimumAngle,
Color nLineColor, bool bUseAA);
};
#endif // INCLUDED_VCL_INC_OPENGL_RENDERLIST_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-188
View File
@@ -1,188 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_RENDER_STATE_H
#define INCLUDED_VCL_INC_OPENGL_RENDER_STATE_H
#include <opengl/TextureState.hxx>
template<GLenum ENUM_TYPE, typename TYPE>
class GenericCapabilityState
{
protected:
bool mbTest;
GenericCapabilityState()
: mbTest(false)
{
}
static bool readState()
{
return glIsEnabled(ENUM_TYPE);
}
public:
void sync()
{
mbTest = readState();
}
void enable()
{
if (!mbTest)
{
glEnable(ENUM_TYPE);
CHECK_GL_ERROR();
mbTest = true;
}
else
{
VCL_GL_INFO(TYPE::className() << ": enable called but already enabled");
}
#ifdef DBG_UTIL
checkState();
#endif
}
void disable()
{
if (mbTest)
{
glDisable(ENUM_TYPE);
CHECK_GL_ERROR();
mbTest = false;
}
else
{
VCL_GL_INFO(TYPE::className() << ": disable called but already disabled");
}
#ifdef DBG_UTIL
checkState();
#endif
}
#ifdef DBG_UTIL
void checkState()
{
bool bRealState = readState();
if (mbTest != bRealState)
{
VCL_GL_INFO(TYPE::className() << " mismatch! "
<< "Expected: " << (mbTest ? "enabled" : "disabled")
<< " but is: " << (bRealState ? "enabled" : "disabled"));
}
}
#endif
};
class ScissorState : public GenericCapabilityState<GL_SCISSOR_TEST, ScissorState>
{
private:
int mX;
int mY;
int mWidth;
int mHeight;
public:
static std::string className() { return std::string("ScissorState"); }
ScissorState()
: mX(0)
, mY(0)
, mWidth(0)
, mHeight(0)
{}
void set(int x, int y, int width, int height)
{
if (x != mX || y != mY || width != mWidth || height != mHeight)
{
glScissor(x, y, width, height);
CHECK_GL_ERROR();
mX = x;
mY = y;
mWidth = width;
mHeight = height;
}
}
};
class StencilState : public GenericCapabilityState<GL_STENCIL_TEST, StencilState>
{
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;
tools::Rectangle maCurrentViewport;
public:
RenderState()
{}
void viewport(tools::Rectangle aViewPort)
{
if (aViewPort != maCurrentViewport)
{
glViewport(aViewPort.Left(), aViewPort.Top(), aViewPort.GetWidth(), aViewPort.GetHeight());
CHECK_GL_ERROR();
maCurrentViewport = aViewPort;
}
}
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();
}
};
#endif // INCLUDED_VCL_INC_OPENGL_RENDER_STATE_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-73
View File
@@ -1,73 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_TEXTURE_STATE_H
#define INCLUDED_VCL_INC_OPENGL_TEXTURE_STATE_H
#include <vcl/opengl/OpenGLHelper.hxx>
class TextureState
{
private:
GLuint mnCurrentTextureUnit;
std::vector<GLuint> maBoundTextures;
public:
TextureState()
: mnCurrentTextureUnit(0)
, maBoundTextures(4, 0)
{
}
static void generate(GLuint& nTexture)
{
glGenTextures(1, &nTexture);
CHECK_GL_ERROR();
}
void active(GLuint nTextureUnit)
{
if (mnCurrentTextureUnit != nTextureUnit)
{
glActiveTexture(GL_TEXTURE0 + nTextureUnit);
CHECK_GL_ERROR();
mnCurrentTextureUnit = nTextureUnit;
}
}
void bind(GLuint nTexture)
{
if (maBoundTextures[mnCurrentTextureUnit] != nTexture)
{
glBindTexture(GL_TEXTURE_2D, nTexture);
CHECK_GL_ERROR();
maBoundTextures[mnCurrentTextureUnit] = nTexture;
}
}
void unbindAndDelete(GLuint nTexture)
{
unbind(nTexture);
glDeleteTextures(1, &nTexture);
}
void unbind(GLuint nTexture)
{
for (size_t i = 0; i < maBoundTextures.size(); i++)
{
if (nTexture == maBoundTextures[i])
maBoundTextures[i] = 0;
}
}
};
#endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_STATE_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-118
View File
@@ -1,118 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#ifndef INCLUDED_VCL_INC_OPENGL_VERTEXUTILS_H
#define INCLUDED_VCL_INC_OPENGL_VERTEXUTILS_H
#include <basegfx/numeric/ftools.hxx>
#include <epoxy/gl.h>
#include <glm/gtx/norm.hpp>
#include <tools/color.hxx>
#include <vector>
namespace vcl::vertex
{
template<GLenum TYPE>
inline void addRectangle(std::vector<GLfloat>& rVertices, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
template<>
inline void addRectangle<GL_TRIANGLES>(std::vector<GLfloat>& rVertices, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
rVertices.insert(rVertices.end(), {
x1, y1, x2, y1, x1, y2,
x1, y2, x2, y1, x2, y2
});
}
template<>
inline void addRectangle<GL_TRIANGLE_FAN>(std::vector<GLfloat>& rVertices, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
rVertices.insert(rVertices.end(), {
x1, y2, x1, y1,
x2, y1, x2, y2
});
}
inline void createColor(Color nColor, GLfloat fTransparency, GLubyte& nR, GLubyte& nG, GLubyte& nB, GLubyte& nA)
{
nR = nColor.GetRed();
nG = nColor.GetGreen();
nB = nColor.GetBlue();
nA = (1.0f - fTransparency) * 255.0f;
}
template<GLenum TYPE>
inline void addQuadColors(std::vector<GLubyte>& rColors, Color nColor, GLfloat fTransparency);
template<>
inline void addQuadColors<GL_TRIANGLES>(std::vector<GLubyte>& rColors, Color nColor, GLfloat fTransparency)
{
GLubyte nR, nG, nB, nA;
createColor(nColor, fTransparency, nR, nG, nB, nA);
rColors.insert(rColors.end(), {
nR, nG, nB, nA,
nR, nG, nB, nA,
nR, nG, nB, nA,
nR, nG, nB, nA,
nR, nG, nB, nA,
nR, nG, nB, nA,
});
}
inline void addLineSegmentVertices(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors,
glm::vec2 prevPoint, glm::vec2 prevExtrusionVector, GLfloat prevLength,
glm::vec2 currPoint, glm::vec2 currExtrusionVector, GLfloat currLength)
{
rVertices.insert(rVertices.end(), {
prevPoint.x, prevPoint.y,
prevPoint.x, prevPoint.y,
currPoint.x, currPoint.y,
currPoint.x, currPoint.y,
prevPoint.x, prevPoint.y,
currPoint.x, currPoint.y,
});
rExtrusionVectors.insert(rExtrusionVectors.end(), {
-prevExtrusionVector.x, -prevExtrusionVector.y, -prevLength,
prevExtrusionVector.x, prevExtrusionVector.y, prevLength,
-currExtrusionVector.x, -currExtrusionVector.y, -currLength,
-currExtrusionVector.x, -currExtrusionVector.y, -currLength,
prevExtrusionVector.x, prevExtrusionVector.y, prevLength,
currExtrusionVector.x, currExtrusionVector.y, currLength,
});
}
inline glm::vec2 normalize(const glm::vec2& vector)
{
if (glm::length(vector) > 0.0)
return glm::normalize(vector);
return vector;
}
inline glm::vec2 perpendicular(const glm::vec2& vector)
{
return glm::vec2(-vector.y, vector.x);
}
inline float lineVectorAngle(const glm::vec2& previous, const glm::vec2& next)
{
float angle = std::atan2(previous.x * next.y - previous.y * next.x,
previous.x * next.x + previous.y * next.y);
return F_PI - std::fabs(angle);
}
} // end vcl::vertex
#endif // INCLUDED_VCL_INC_OPENGL_VERTEXUTILS_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-48
View File
@@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
#define INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
#include <vcl/dllapi.h>
#include <opengl/texture.hxx>
class OpenGLFramebuffer final
{
private:
GLuint mnId;
int mnWidth;
int mnHeight;
GLuint mnAttachedTexture;
public:
OpenGLFramebuffer();
~OpenGLFramebuffer();
int GetWidth() const { return mnWidth; };
int GetHeight() const { return mnHeight; };
void Bind(GLenum eTarget = GL_FRAMEBUFFER);
static void Unbind(GLenum eTarget = GL_FRAMEBUFFER);
VCL_DLLPUBLIC bool IsFree() const;
bool IsAttached( GLuint nTexture ) const;
bool IsAttached( const OpenGLTexture& rTexture ) const;
void AttachTexture( const OpenGLTexture& rTexture );
void DetachTexture();
public:
OpenGLFramebuffer* mpPrevFramebuffer;
};
#endif // INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-396
View File
@@ -1,396 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* 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_OPENGLGDIIMPL_HXX
#define INCLUDED_VCL_OPENGLGDIIMPL_HXX
#include <vcl/dllapi.h>
#include <vcl/opengl/OpenGLContext.hxx>
#include <regionband.hxx>
#include <salgeom.hxx>
#include <salgdiimpl.hxx>
#include <opengl/program.hxx>
#include <opengl/texture.hxx>
#include <opengl/RenderList.hxx>
#include <memory>
class SalFrame;
class SalVirtualDevice;
class OpenGLTests;
namespace basegfx
{
class B2DTrapezoid;
};
namespace tools
{
class Polygon;
class PolyPolygon;
}
struct TextureCombo
{
std::unique_ptr<OpenGLTexture> mpTexture;
std::unique_ptr<OpenGLTexture> mpMask;
};
class OpenGLFlushIdle;
class VCL_DLLPUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
{
friend class OpenGLTests;
protected:
/// This context is solely for blitting maOffscreenTex
rtl::Reference<OpenGLContext> mpWindowContext;
/// This context is whatever is most convenient to render
/// to maOffscreenTex with.
rtl::Reference<OpenGLContext> mpContext;
SalGraphics& mrParent;
/// Pointer to the SalFrame or SalVirtualDevice
SalGeometryProvider* mpProvider;
OpenGLProgram* mpProgram;
/// This idle handler is used to swap buffers after rendering.
std::unique_ptr<OpenGLFlushIdle> mpFlush;
// clipping
vcl::Region maClipRegion;
bool mbUseScissor;
bool mbUseStencil;
bool mbXORMode;
bool mbAcquiringOpenGLContext;
/**
* All rendering happens to this off-screen texture. For
* non-virtual devices, ie. windows - we will blit it and
* swapBuffers later.
*/
OpenGLTexture maOffscreenTex;
Color mnLineColor;
Color mnFillColor;
#ifdef DBG_UTIL
bool mProgramIsSolidColor;
#endif
sal_uInt32 mnDrawCount;
sal_uInt32 mnDrawCountAtFlush;
Color mProgramSolidColor;
double mProgramSolidTransparency;
std::unique_ptr<RenderList> mpRenderList;
void ImplInitClipRegion();
void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
void ImplDrawLineAA( double nX1, double nY1, double nX2, double nY2, bool edge );
void CheckOffscreenTexture();
void ApplyProgramMatrices(float fPixelOffset = 0.0);
public:
bool UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
bool UseSolid( Color nColor, sal_uInt8 nTransparency );
bool UseSolid( Color nColor, double fTransparency );
bool UseSolid( Color nColor );
void UseSolid();
bool UseLine(Color nColor, double fTransparency, GLfloat fLineWidth, bool bUseAA);
void UseLine(GLfloat fLineWidth, bool bUseAA);
bool UseInvert50();
bool UseInvert(SalInvert nFlags);
void DrawConvexPolygon( sal_uInt32 nPoints, const Point* pPtAry, bool blockAA = false );
void DrawConvexPolygon( const tools::Polygon& rPolygon, bool blockAA );
void DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid, bool blockAA );
void DrawRect( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight );
void DrawRect( const tools::Rectangle& rRect );
void DrawPolygon( sal_uInt32 nPoints, const Point* pPtAry );
void DrawLineSegment(float x1, float y1, float x2, float y2);
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool blockAA = false );
void DrawRegionBand( const RegionBand& rRegion );
void DrawTextureRect( const SalTwoRect& rPosAry );
void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
void DrawTransformedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY );
void DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted, bool pPremultiplied );
void DrawTextureDiff( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry, bool bInverted );
void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry );
void DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, OpenGLTexture& rAlpha, const SalTwoRect& rPosAry );
void DrawMask( OpenGLTexture& rTexture, Color nMaskColor, const SalTwoRect& rPosAry );
void DrawLinearGradient( const Gradient& rGradient, const tools::Rectangle& rRect );
void DrawAxialGradient( const Gradient& rGradient, const tools::Rectangle& rRect );
void DrawRadialGradient( const Gradient& rGradient, const tools::Rectangle& rRect );
void FlushDeferredDrawing();
void FlushLinesOrTriangles(DrawShaderType eType, RenderParameters const & rParameters);
public:
// get the width of the device
GLfloat GetWidth() const { return mpProvider ? mpProvider->GetWidth() : 1; }
// get the height of the device
GLfloat GetHeight() const { return mpProvider ? mpProvider->GetHeight() : 1; }
/**
* check whether this instance is used for offscreen (Virtual Device)
* rendering ie. does it need its own context.
*/
bool IsOffscreen() const { return mpProvider == nullptr || mpProvider->IsOffScreen(); }
/// Oddly not all operations obey the XOR option.
enum XOROption { IGNORE_XOR, IMPLEMENT_XOR };
// initialize pre-draw state
void InitializePreDrawState(XOROption eOpt);
// operations to do before painting
void PreDraw(XOROption eOpt = IGNORE_XOR);
// operations to do after painting
void PostDraw();
void PostBatchDraw();
protected:
bool AcquireContext(bool bForceCreate = false);
void ReleaseContext();
/// create a new context for rendering to the underlying window
virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0;
/// check whether the given context can be used for off-screen rendering
static bool UseContext( const rtl::Reference<OpenGLContext> &pContext )
{
return pContext->isInitialized() && // not released by the OS etc.
pContext->isVCLOnly();
}
public:
OpenGLSalGraphicsImpl(SalGraphics& pParent, SalGeometryProvider *pProvider);
virtual ~OpenGLSalGraphicsImpl () override;
rtl::Reference<OpenGLContext> GetOpenGLContext();
virtual void Init() override;
virtual void DeInit() override;
virtual void freeResources() override;
virtual OUString getRenderBackendName() const override { return "opengl"; }
const vcl::Region& getClipRegion() const;
virtual bool setClipRegion( const vcl::Region& ) override;
//
// get the depth of the device
virtual sal_uInt16 GetBitCount() const override;
// get the width of the device
virtual tools::Long GetGraphicsWidth() const override;
// set the clip region to empty
virtual void ResetClipRegion() override;
// set the line color to transparent (= don't draw lines)
virtual void SetLineColor() override;
// set the line color to a specific color
virtual void SetLineColor( Color nColor ) override;
// set the fill color to transparent (= don't fill)
virtual void SetFillColor() override;
// set the fill color to a specific color, shapes will be
// filled accordingly
virtual void SetFillColor( Color nColor ) override;
// enable/disable XOR drawing
virtual void SetXORMode( bool bSet, bool bInvertOnly ) override;
// set line color for raster operations
virtual void SetROPLineColor( SalROPColor nROPColor ) override;
// set fill color for raster operations
virtual void SetROPFillColor( SalROPColor nROPColor ) override;
// draw --> LineColor and FillColor and RasterOp and ClipRegion
virtual void drawPixel( tools::Long nX, tools::Long nY ) override;
virtual void drawPixel( tools::Long nX, tools::Long nY, Color nColor ) override;
virtual void drawLine( tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2 ) override;
virtual void drawRect( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight ) override;
virtual void drawPolyLine( sal_uInt32 nPoints, const Point* pPtAry ) override;
virtual void drawPolygon( sal_uInt32 nPoints, const Point* pPtAry ) override;
virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, const Point** pPtAry ) override;
virtual bool drawPolyPolygon(
const basegfx::B2DHomMatrix& rObjectToDevice,
const basegfx::B2DPolyPolygon&,
double fTransparency) override;
virtual bool drawPolyLine(
const basegfx::B2DHomMatrix& rObjectToDevice,
const basegfx::B2DPolygon&,
double fTransparency,
double fLineWidth,
const std::vector< double >* pStroke, // MM01
basegfx::B2DLineJoin,
css::drawing::LineCap,
double fMiterMinimumAngle,
bool bPixelSnapHairline) override;
virtual bool drawPolyLineBezier(
sal_uInt32 nPoints,
const Point* pPtAry,
const PolyFlags* pFlgAry ) override;
virtual bool drawPolygonBezier(
sal_uInt32 nPoints,
const Point* pPtAry,
const PolyFlags* pFlgAry ) override;
virtual bool drawPolyPolygonBezier(
sal_uInt32 nPoly,
const sal_uInt32* pPoints,
const Point* const* pPtAry,
const PolyFlags* const* pFlgAry ) override;
// CopyArea --> No RasterOp, but ClipRegion
virtual void copyArea(
tools::Long nDestX, tools::Long nDestY,
tools::Long nSrcX, tools::Long nSrcY,
tools::Long nSrcWidth, tools::Long nSrcHeight,
bool bWindowInvalidate ) override;
// CopyBits and DrawBitmap --> RasterOp and ClipRegion
// CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
void DoCopyBits(const SalTwoRect& rPosAry, OpenGLSalGraphicsImpl &rSrcImpl);
virtual bool blendBitmap(
const SalTwoRect&,
const SalBitmap& rBitmap ) override;
virtual bool blendAlphaBitmap(
const SalTwoRect&,
const SalBitmap& rSrcBitmap,
const SalBitmap& rMaskBitmap,
const SalBitmap& rAlphaBitmap ) override;
virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) override;
virtual void drawBitmap(
const SalTwoRect& rPosAry,
const SalBitmap& rSalBitmap,
const SalBitmap& rMaskBitmap ) override;
virtual void drawMask(
const SalTwoRect& rPosAry,
const SalBitmap& rSalBitmap,
Color nMaskColor ) override;
virtual std::shared_ptr<SalBitmap> getBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight ) override;
virtual Color getPixel( tools::Long nX, tools::Long nY ) override;
// invert --> ClipRegion (only Windows or VirDevs)
virtual void invert(
tools::Long nX, tools::Long nY,
tools::Long nWidth, tools::Long nHeight,
SalInvert nFlags) override;
virtual void invert( sal_uInt32 nPoints, const Point* pPtAry, SalInvert nFlags ) override;
virtual bool drawEPS(
tools::Long nX, tools::Long nY,
tools::Long nWidth, tools::Long nHeight,
void* pPtr,
sal_uInt32 nSize ) override;
/** Render bitmap with alpha channel
@param rSourceBitmap
Source bitmap to blit
@param rAlphaBitmap
Alpha channel to use for blitting
@return true, if the operation succeeded, and false
otherwise. In this case, clients should try to emulate alpha
compositing themselves
*/
virtual bool drawAlphaBitmap(
const SalTwoRect&,
const SalBitmap& rSourceBitmap,
const SalBitmap& rAlphaBitmap ) override;
/** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
virtual bool drawTransformedBitmap(
const basegfx::B2DPoint& rNull,
const basegfx::B2DPoint& rX,
const basegfx::B2DPoint& rY,
const SalBitmap& rSourceBitmap,
const SalBitmap* pAlphaBitmap) override;
/** Render solid rectangle with given transparency
@param nX Top left coordinate of rectangle
@param nY Bottom right coordinate of rectangle
@param nWidth Width of rectangle
@param nHeight Height of rectangle
@param nTransparency Transparency value (0-255) to use. 0 blits and opaque, 255 a
fully transparent rectangle
@returns true if successfully drawn, false if not able to draw rectangle
*/
virtual bool drawAlphaRect(
tools::Long nX, tools::Long nY,
tools::Long nWidth, tools::Long nHeight,
sal_uInt8 nTransparency ) override;
virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override;
virtual bool implDrawGradient(basegfx::B2DPolyPolygon const & rPolyPolygon, SalGradient const & rGradient) override;
virtual bool supportsOperation(OutDevSupportType eType) const override;
/// queue an idle flush of contents of the back-buffer to the screen
void flush();
public:
/// do flush of contents of the back-buffer to the screen & swap.
void doFlush();
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-122
View File
@@ -1,122 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_VCL_INC_OPENGL_PROGRAM_H
#define INCLUDED_VCL_INC_OPENGL_PROGRAM_H
#include <sal/config.h>
#include <vector>
#include <vcl/dllapi.h>
#include <basegfx/point/b2dpoint.hxx>
#include <rtl/ustring.hxx>
#include <opengl/texture.hxx>
#include <unordered_map>
class Color;
enum class TextureShaderType
{
Normal = 0,
Blend,
Masked,
Diff,
MaskedColor
};
enum class DrawShaderType
{
Normal = 0,
Line
};
class OpenGLProgram
{
private:
GLuint mnId;
std::unordered_map< OString, GLuint >
maUniformLocations;
sal_uInt32 mnEnabledAttribs;
GLuint mnPositionAttrib;
GLuint mnTexCoordAttrib;
GLuint mnAlphaCoordAttrib;
GLuint mnMaskCoordAttrib;
GLuint mnExtrusionVectorsAttrib;
GLuint mnVertexColorsAttrib;
std::vector< OpenGLTexture > maTextures;
bool mbBlending;
float mfLastWidth;
float mfLastHeight;
float mfLastPixelOffset;
OpenGLProgram(const OpenGLProgram &) = delete;
public:
OpenGLProgram();
~OpenGLProgram();
GLuint Id() { return mnId; }
bool Load( const OUString& rVertexShader, const OUString& rFragmentShader,
const OString& preamble, const OString& rDigest );
void Use();
void Reuse();
void Clean();
void SetVertices( const GLvoid* pData );
void SetTextureCoord( const GLvoid* pData );
void SetAlphaCoord( const GLvoid* pData );
void SetMaskCoord(const GLvoid* pData);
void SetExtrusionVectors(const GLvoid* pData);
void SetVertexColors(std::vector<GLubyte>& rColorVector);
void SetUniform1f( const OString& rName, GLfloat v1 );
void SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 );
void SetUniform1fv( const OString& rName, GLsizei nCount, GLfloat const * aValues );
void SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat const * aValues );
void SetUniform1i( const OString& rName, GLint v1 );
void SetColor( const OString& rName, const Color& rColor );
void SetColor( const OString& rName, Color nColor, sal_uInt8 nTransparency );
void SetColorf( const OString& rName, Color nColor, double fTransparency );
void SetColorWithIntensity( const OString& rName, const Color& rColor, tools::Long nFactor );
void SetTexture( const OString& rName, OpenGLTexture& rTexture );
void SetTransform( const OString& rName, const OpenGLTexture& rTexture,
const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX,
const basegfx::B2DPoint& rY );
void SetIdentityTransform(const OString& rName);
void SetShaderType(TextureShaderType eTextureShaderType);
void SetShaderType(DrawShaderType eDrawShaderType);
void SetBlendMode( GLenum nSFactor, GLenum nDFactor );
void ApplyMatrix(float fWidth, float fHeight, float fPixelOffset = 0.0f);
void DrawTexture( const OpenGLTexture& rTexture );
void DrawArrays(GLenum aMode, std::vector<GLfloat>& aVertices);
void DrawElements(GLenum aMode, GLuint nNumberOfVertices);
bool EnableVertexAttrib(GLuint& rAttrib, const OString& rName);
void SetVertexAttrib(GLuint& rAttrib, const OString& rName, GLint nSize,
GLenum eType, GLboolean bNormalized, GLsizei aStride,
const GLvoid* pPointer);
private:
GLuint GetUniformLocation( const OString& rName );
};
#endif // INCLUDED_VCL_INC_OPENGL_PROGRAM_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-113
View File
@@ -1,113 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* 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 <vcl/opengl/OpenGLContext.hxx>
#include <opengl/texture.hxx>
#include <salbmp.hxx>
#include <memory>
struct BitmapBuffer;
class BitmapPalette;
namespace vcl
{
class Kernel;
}
class VCL_PLUGIN_PUBLIC OpenGLSalBitmap final : public SalBitmap
{
private:
OpenGLTexture maTexture;
bool mbDirtyTexture;
BitmapPalette maPalette;
std::shared_ptr<sal_uInt8> mpUserBuffer;
sal_uInt16 mnBits;
sal_uInt32 mnBytesPerRow;
int mnWidth;
int mnHeight;
virtual void updateChecksum() const override;
bool calcChecksumGL(OpenGLTexture& rInputTexture, BitmapChecksum& rChecksum) const;
public:
OpenGLSalBitmap();
virtual ~OpenGLSalBitmap() override;
public:
// SalBitmap methods
bool Create( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal ) override;
bool Create( const SalBitmap& rSalBmp ) override;
bool Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics ) override;
bool Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount ) override;
virtual bool Create( const css::uno::Reference< css::rendering::XBitmapCanvas >& rBitmapCanvas,
Size& rSize,
bool bMask = false ) override;
void Destroy() final override;
Size GetSize() const override;
sal_uInt16 GetBitCount() const override;
BitmapBuffer* AcquireBuffer( BitmapAccessMode nMode ) override;
void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) override;
bool GetSystemData( BitmapSystemData& rData ) override;
bool ScalingSupported() const override;
bool Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag ) override;
bool Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uInt8 nTol ) override;
bool ConvertToGreyscale() override;
bool InterpretAs8Bit() override;
public:
void Create( const OpenGLTexture& rTex, tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight );
OpenGLTexture& GetTexture() const;
const BitmapPalette& GetBitmapPalette() const { return maPalette; }
private:
GLuint CreateTexture();
bool AllocateUserData();
void DeallocateUserData();
bool ReadTexture();
private:
bool ImplScaleFilter( const rtl::Reference< OpenGLContext > &xContext, const double& rScaleX, const double& rScaleY, GLenum nFilter );
static void ImplCreateKernel( const double& fScale, const vcl::Kernel& rKernel, GLfloat*& pWeights, sal_uInt32& aKernelSize );
bool ImplScaleConvolution(const rtl::Reference< OpenGLContext > &xContext, const double& rScaleX, const double& rScaleY, const vcl::Kernel& rKernel);
bool ImplScaleArea( const rtl::Reference< OpenGLContext > &xContext,
double rScaleX, double rScaleY );
public:
void ImplScale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag );
};
#endif // INCLUDED_VCL_INC_OPENGL_SALBMP_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-139
View File
@@ -1,139 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* 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_TEXTURE_H
#define INCLUDED_VCL_INC_OPENGL_TEXTURE_H
#include <epoxy/gl.h>
#include <vcl/dllapi.h>
#include <vcl/salgtype.hxx>
#include <rtl/ustring.hxx>
#include <tools/gen.hxx>
#include <functional>
#include <memory>
#include <vector>
class ImplOpenGLTexture
{
public:
GLuint mnTexture;
int mnWidth;
int mnHeight;
GLenum mnFilter;
GLuint mnOptStencil;
std::unique_ptr<std::vector<int>> mpSlotReferences;
std::function<void(int)> mFunctSlotDeallocateCallback;
ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate );
ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, void const * pData );
ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight );
~ImplOpenGLTexture();
bool InsertBuffer(int nX, int nY, int nWidth, int nHeight, int nFormat, int nType, sal_uInt8 const * pData);
void IncreaseRefCount(int nSlotNumber);
void DecreaseRefCount(int nSlotNumber);
void InitializeSlotMechanism(int nInitialSlotSize);
void SetSlotDeallocateCallback(std::function<void(int)> aCallback)
{
mFunctSlotDeallocateCallback = aCallback;
}
void ResetSlotDeallocateCallback()
{
mFunctSlotDeallocateCallback = std::function<void(int)>();
}
GLuint AddStencil();
};
class VCL_DLLPUBLIC OpenGLTexture final
{
private:
// if the rect size doesn't match the mpImpl one, this instance
// is a sub-area from the real OpenGL texture
tools::Rectangle maRect;
std::shared_ptr<ImplOpenGLTexture> mpImpl;
int mnSlotNumber;
inline void GetTextureRect(const SalTwoRect& rPosAry, GLfloat& x1, GLfloat& x2, GLfloat& y1, GLfloat& y2) const;
bool IsValid() const
{
return (mpImpl && mpImpl->mnTexture != 0);
}
public:
OpenGLTexture();
OpenGLTexture(const std::shared_ptr<ImplOpenGLTexture>& pImpl, tools::Rectangle aRectangle, int nSlotNumber);
OpenGLTexture( int nWidth, int nHeight, bool bAllocate = true );
OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, void const * pData );
OpenGLTexture( int nX, int nY, int nWidth, int nHeight );
OpenGLTexture( const OpenGLTexture& rTexture );
OpenGLTexture( OpenGLTexture&& rTexture ) noexcept;
OpenGLTexture( const OpenGLTexture& rTexture, int nX, int nY, int nWidth, int nHeight );
~OpenGLTexture();
bool IsUnique() const;
GLuint Id() const;
int GetWidth() const;
int GetHeight() const;
void GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool bInverted=false ) const;
void GetWholeCoord( GLfloat* pCoord ) const;
void Bind();
void Unbind();
void Read( GLenum nFormat, GLenum nType, sal_uInt8* pData );
GLuint AddStencil();
GLuint StencilId() const;
bool CopyData(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8 const * pData);
void SaveToFile(const OUString& rFileName);
GLenum GetFilter() const;
void SetFilter( GLenum nFilter );
operator bool() const;
OpenGLTexture& operator=( const OpenGLTexture& rTexture );
OpenGLTexture& operator=( OpenGLTexture&& rTexture );
bool operator==( const OpenGLTexture& rTexture ) const;
bool operator!=( const OpenGLTexture& rTexture ) const;
template<GLenum type>
void FillCoords(std::vector<GLfloat>& aCoordVector, const SalTwoRect& rPosAry) const;
};
template<> void OpenGLTexture::FillCoords<GL_TRIANGLES>(
std::vector<GLfloat>& aCoord, const SalTwoRect& rPosAry)
const;
template<> void OpenGLTexture::FillCoords<GL_TRIANGLE_FAN>(
std::vector<GLfloat>& aCoord, const SalTwoRect& rPosAry)
const;
#endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-97
View File
@@ -1,97 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_VCL_INC_OPENGL_WIN_GDIIMPL_HXX
#define INCLUDED_VCL_INC_OPENGL_WIN_GDIIMPL_HXX
#include <memory>
#include <vcl/dllapi.h>
#include <opengl/gdiimpl.hxx>
#include <svdata.hxx>
#include <win/salgdi.h>
#include <win/wingdiimpl.hxx>
#include <o3tl/lru_map.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
#include <ControlCacheKey.hxx>
class OpenGLCompatibleDC : public CompatibleDC
{
public:
OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height);
virtual std::unique_ptr<Texture> getAsMaskTexture() const override;
// caller must delete
OpenGLTexture* getOpenGLTexture() const;
/// Copy bitmap data to the texture. Texture must be initialized and the correct size to hold the bitmap.
bool copyToTexture(Texture& aTexture) const;
struct Texture;
};
struct OpenGLCompatibleDC::Texture : public CompatibleDC::Texture
{
OpenGLTexture texture;
virtual bool isValid() const { return !!texture; }
virtual int GetWidth() const { return texture.GetWidth(); }
virtual int GetHeight() const { return texture.GetHeight(); }
};
class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl, public WinSalGraphicsImplBase
{
friend class WinLayout;
private:
WinSalGraphics& mrWinParent;
bool RenderCompatibleDC(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack,
int nX, int nY, TextureCombo& rCombo);
public:
WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics,
SalGeometryProvider *mpProvider);
protected:
virtual rtl::Reference<OpenGLContext> CreateWinContext() override;
bool RenderTextureCombo(TextureCombo const & rCombo, int nX, int nY);
public:
virtual void Init() override;
virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) override;
virtual bool UseTextDraw() const override { return true; }
virtual void PreDrawText() override;
virtual void PostDrawText() override;
virtual void DrawTextMask( CompatibleDC::Texture* rTexture, Color nMaskColor, const SalTwoRect& rPosAry ) override;
using OpenGLSalGraphicsImpl::DrawMask;
virtual void DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry) override;
virtual bool UseRenderNativeControl() const override { return true; }
virtual bool TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY) override;
virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack,
int nX, int nY , ControlCacheKey& aControlCacheKey) override;
};
typedef std::pair<ControlCacheKey, std::unique_ptr<TextureCombo>> OpenGLControlCachePair;
typedef o3tl::lru_map<ControlCacheKey, std::unique_ptr<TextureCombo>, ControlCacheHashFunction> OpenGLControlCacheType;
class OpenGLControlsCache {
OpenGLControlCacheType cache;
OpenGLControlsCache();
public:
static OpenGLControlCacheType & get();
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-51
View File
@@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* 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_WIN_WINLAYOUT_HXX
#define INCLUDED_VCL_INC_OPENGL_WIN_WINLAYOUT_HXX
#include <win/winlayout.hxx>
#include <opengl/PackedTextureAtlas.hxx>
struct OpenGLGlobalWinGlyphCache : public GlobalWinGlyphCache
{
OpenGLGlobalWinGlyphCache()
: maPackedTextureAtlas(2048, 2048)
{
}
PackedTextureAtlasManager maPackedTextureAtlas;
virtual bool AllocateTexture(WinGlyphDrawElement& rElement, CompatibleDC* dc) override;
virtual void Prune() override;
};
class OpenGLWinGlyphCache : public WinGlyphCache
{
public:
void RemoveTextures(std::vector<GLuint>& rTextureIDs);
private:
// This class just "adds" RemoveTextures() to the base class, it's never instantiated.
OpenGLWinGlyphCache() = delete;
};
#endif // INCLUDED_VCL_INC_OPENGL_WIN_WINLAYOUT_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-27
View File
@@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_VCL_UNX_GENERIC_GDI_OPENGLX11CAIROTEXTRENDER_HXX
#define INCLUDED_VCL_UNX_GENERIC_GDI_OPENGLX11CAIROTEXTRENDER_HXX
#include <unx/x11/x11cairotextrender.hxx>
class OpenGLX11CairoTextRender final : public X11CairoTextRender
{
public:
explicit OpenGLX11CairoTextRender(X11SalGraphics& rParent);
virtual cairo_t* getCairoContext() override;
virtual void getSurfaceOffset(double& nDX, double& nDY) override;
virtual void releaseCairoContext(cairo_t* cr) override;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-42
View File
@@ -1,42 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
#define INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
#include <vcl/dllapi.h>
#include <unx/salgdi.h>
#include <unx/x11/x11gdiimpl.h>
#include <opengl/gdiimpl.hxx>
#include <ControlCacheKey.hxx>
struct TextureCombo;
class X11OpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl, public X11GraphicsImpl
{
private:
X11SalGraphics& mrX11Parent;
public:
X11OpenGLSalGraphicsImpl(X11SalGraphics& rParent);
virtual ~X11OpenGLSalGraphicsImpl() override;
protected:
virtual rtl::Reference<OpenGLContext> CreateWinContext() override;
public:
virtual void copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics) override;
virtual void Init() override;
};
#endif // INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-57
View File
@@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
#define INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
#include <memory>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <unx/saltype.h>
#include <salvd.hxx>
class SalDisplay;
class X11OpenGLSalGraphics;
class X11SalGraphics;
class X11OpenGLSalVirtualDevice : public SalVirtualDevice
{
SalDisplay *mpDisplay;
std::unique_ptr<X11SalGraphics>
mpGraphics;
bool mbGraphics; // is Graphics used
SalX11Screen mnXScreen;
int mnWidth;
int mnHeight;
public:
X11OpenGLSalVirtualDevice( SalGraphics const *pGraphics,
tools::Long nDX, tools::Long nDY,
const SystemGraphicsData *pData,
std::unique_ptr<X11SalGraphics> pNewGraphics);
virtual ~X11OpenGLSalVirtualDevice() override;
// SalGeometryProvider
virtual tools::Long GetWidth() const override { return mnWidth; }
virtual tools::Long GetHeight() const override { return mnHeight; }
SalDisplay * GetDisplay() const { return mpDisplay; }
const SalX11Screen& GetXScreenNumber() const { return mnXScreen; }
virtual SalGraphics* AcquireGraphics() override;
virtual void ReleaseGraphics( SalGraphics* pGraphics ) override;
// Set new size, without saving the old contents
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY ) override;
};
#endif // INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-16
View File
@@ -29,22 +29,6 @@ public:
static const char* name() { return "OpenGL"; }
};
/// Create this to not only enter the zone, but set VCL context.
class OpenGLVCLContextZone
{
OpenGLZone aZone;
public:
OpenGLVCLContextZone();
};
class VCL_DLLPUBLIC PreDefaultWinNoOpenGLZone
{
public:
PreDefaultWinNoOpenGLZone();
~PreDefaultWinNoOpenGLZone();
};
#endif // INCLUDED_VCL_INC_OPENGL_ZONE_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-3
View File
@@ -81,9 +81,6 @@ public:
virtual SalGraphicsImpl* GetImpl() const = 0;
/// Check that our mpImpl is OpenGL and return the context, otherwise NULL.
rtl::Reference<OpenGLContext> GetOpenGLContext() const;
void setAntiAlias(bool bNew) { m_bAntiAlias = bNew; }
bool getAntiAlias() const { return m_bAntiAlias; }
-5
View File
@@ -51,8 +51,6 @@ class SalFrame;
class X11Pixmap;
class X11SalVirtualDevice;
class X11SalGraphicsImpl;
class X11OpenGLSalGraphicsImpl;
class X11OpenGLSalVirtualDevice;
class X11SkiaSalVirtualDevice;
class FreetypeFont;
class ImplLayoutArgs;
@@ -68,7 +66,6 @@ namespace basegfx {
class X11SalGraphics final : public SalGraphics
{
friend class X11SalGraphicsImpl;
friend class X11OpenGLSalGraphicsImpl;
friend class X11CairoTextRender;
public:
@@ -78,7 +75,6 @@ public:
void Init( SalFrame *pFrame, Drawable aDrawable, SalX11Screen nXScreen );
void Init( X11SalVirtualDevice *pVirtualDevice, cairo_surface_t* pPreExistingTarget = nullptr,
SalColormap* pColormap = nullptr, bool bDeleteColormap = false );
void Init( X11OpenGLSalVirtualDevice *pVirtualDevice );
void Init( X11SkiaSalVirtualDevice *pVirtualDevice );
void DeInit();
@@ -317,7 +313,6 @@ private:
bool bWindow_ : 1; // is Window
bool bVirDev_ : 1; // is VirDev
bool m_bOpenGL : 1;
bool m_bSkia : 1;
private:
-2
View File
@@ -46,7 +46,6 @@ struct GlobalWinGlyphCache;
struct HDCCache;
struct TempFontItem;
class TextOutRenderer;
class OpenGLControlsCache;
#if HAVE_FEATURE_SKIA
class SkiaControlsCache;
#endif
@@ -130,7 +129,6 @@ public:
// tdf#107205 need 2 instances because D2DWrite can't rotate text
std::unique_ptr<TextOutRenderer> m_pExTextOutRenderer;
std::unique_ptr<GlobalWinGlyphCache> m_pGlobalWinGlyphCache;
std::unique_ptr<OpenGLControlsCache> m_pOpenGLControlsCache;
#if HAVE_FEATURE_SKIA
std::unique_ptr<SkiaControlsCache> m_pSkiaControlsCache;
#endif
-1
View File
@@ -154,7 +154,6 @@ struct CompatibleDC::Texture
class WinSalGraphics : public SalGraphics
{
friend class WinSalGraphicsImpl;
friend class WinOpenGLSalGraphicsImpl;
friend class ScopedFont;
protected:
-137
View File
@@ -1,137 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include <memory>
#include <sal/config.h>
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <opengl/framebuffer.hxx>
#include <opengl/texture.hxx>
#include <opengl/FixedTextureAtlas.hxx>
struct FixedTexture
{
std::shared_ptr<ImplOpenGLTexture> mpTexture;
int mnFreeSlots;
std::vector<bool> maAllocatedSlots;
FixedTexture(int nTextureWidth, int nTextureHeight, int nNumberOfSlots)
: mpTexture(std::make_shared<ImplOpenGLTexture>(nTextureWidth, nTextureHeight, true))
, mnFreeSlots(nNumberOfSlots)
, maAllocatedSlots(nNumberOfSlots, false)
{
auto aDeallocateFunction = [this] (int nSlotNumber)
{
deallocateSlot(nSlotNumber);
};
mpTexture->SetSlotDeallocateCallback(aDeallocateFunction);
mpTexture->InitializeSlotMechanism(nNumberOfSlots);
}
~FixedTexture()
{
mpTexture->ResetSlotDeallocateCallback();
}
void allocateSlot(int nSlot)
{
maAllocatedSlots[nSlot] = true;
mnFreeSlots--;
}
void deallocateSlot(int nSlot)
{
maAllocatedSlots[nSlot] = false;
mnFreeSlots++;
}
int findAndAllocateFreeSlot()
{
for (size_t i = 0; i < maAllocatedSlots.size(); ++i)
{
if (!maAllocatedSlots[i])
{
allocateSlot(i);
return i;
}
}
return -1;
}
private:
FixedTexture(const FixedTexture&) = delete;
FixedTexture& operator=(const FixedTexture&) = delete;
};
FixedTextureAtlasManager::FixedTextureAtlasManager(int nWidthFactor, int nHeightFactor, int nSubTextureSize)
: mWidthFactor(nWidthFactor)
, mHeightFactor(nHeightFactor)
, mSubTextureSize(nSubTextureSize)
{
}
FixedTextureAtlasManager::~FixedTextureAtlasManager()
{
}
void FixedTextureAtlasManager::CreateNewTexture()
{
int nTextureWidth = mWidthFactor * mSubTextureSize;
int nTextureHeight = mHeightFactor * mSubTextureSize;
maFixedTextures.push_back(std::make_unique<FixedTexture>(nTextureWidth, nTextureHeight, mWidthFactor * mHeightFactor));
}
OpenGLTexture FixedTextureAtlasManager::Reserve(int nWidth, int nHeight)
{
FixedTexture* pFixedTexture = nullptr;
auto funFreeSlot = [] (std::unique_ptr<FixedTexture>& inFixedTexture)
{
return inFixedTexture->mnFreeSlots > 0;
};
auto it = std::find_if(maFixedTextures.begin(), maFixedTextures.end(), funFreeSlot);
if (it != maFixedTextures.end())
{
pFixedTexture = (*it).get();
}
else
{
CreateNewTexture();
pFixedTexture = maFixedTextures.back().get();
}
int nSlot = pFixedTexture->findAndAllocateFreeSlot();
// Calculate coordinates in texture
int nX = (nSlot % mWidthFactor) * mSubTextureSize;
int nY = (nSlot / mWidthFactor) * mSubTextureSize;
tools::Rectangle aRectangle(Point(nX, nY), Size(nWidth, nHeight));
return OpenGLTexture(pFixedTexture->mpTexture, aRectangle, nSlot);
}
OpenGLTexture FixedTextureAtlasManager::InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8 const * pData)
{
OpenGLTexture aTexture = Reserve(nWidth, nHeight);
if (pData == nullptr)
return aTexture;
aTexture.CopyData(nWidth, nHeight, nFormat, nType, pData);
return aTexture;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-189
View File
@@ -1,189 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include <opengl/LineRenderUtils.hxx>
#include <opengl/VertexUtils.hxx>
namespace vcl
{
LineBuilder::LineBuilder(std::vector<Vertex>& rVertices, std::vector<GLuint>& rIndices,
Color nColor, GLfloat fTransparency,
GLfloat fLineWidth, bool bUseAA)
: mrVertices(rVertices)
, mrIndices(rIndices)
, mR(nColor.GetRed())
, mG(nColor.GetGreen())
, mB(nColor.GetBlue())
, mA((1.0f - fTransparency) * 255.0f)
, mfLineWidth(fLineWidth)
, mfLineWidthAndAA(bUseAA ? fLineWidth : -fLineWidth)
, mnInitialIndexSize(rIndices.size())
, mbIncomplete(false)
{
}
void LineBuilder::appendLineSegment(const glm::vec2& rPoint1, const glm::vec2& rNormal1, GLfloat aExtrusion1,
const glm::vec2& rPoint2, const glm::vec2& rNormal2, GLfloat aExtrusion2)
{
GLuint zero = mrVertices.size();
mrVertices.insert(mrVertices.end(), {
{rPoint1, glm::vec4{mR, mG, mB, mA}, glm::vec4{-rNormal1.x, -rNormal1.y, -aExtrusion1, mfLineWidthAndAA}},
{rPoint1, glm::vec4{mR, mG, mB, mA}, glm::vec4{ rNormal1.x, rNormal1.y, aExtrusion1, mfLineWidthAndAA}},
{rPoint2, glm::vec4{mR, mG, mB, mA}, glm::vec4{-rNormal2.x, -rNormal2.y, -aExtrusion2, mfLineWidthAndAA}},
{rPoint2, glm::vec4{mR, mG, mB, mA}, glm::vec4{ rNormal2.x, rNormal2.y, aExtrusion2, mfLineWidthAndAA}},
});
mrIndices.insert(mrIndices.end(), {
zero + 0, zero + 1, zero + 2,
zero + 2, zero + 1, zero + 3
});
}
void LineBuilder::appendLine(const glm::vec2& rPoint1, const glm::vec2& rPoint2)
{
glm::vec2 aLineVector = vcl::vertex::normalize(rPoint2 - rPoint1);
glm::vec2 aNormal = vcl::vertex::perpendicular(aLineVector);
appendLineSegment(rPoint1, aNormal, 1.0f,
rPoint2, aNormal, 1.0f);
}
void LineBuilder::appendAndConnectLinePoint(const glm::vec2& rPoint, const glm::vec2& aNormal, GLfloat aExtrusion)
{
GLuint zero = mrVertices.size();
mrVertices.insert(mrVertices.end(), {
{rPoint, glm::vec4{mR, mG, mB, mA}, glm::vec4{-aNormal.x, -aNormal.y, -aExtrusion, mfLineWidthAndAA}},
{rPoint, glm::vec4{mR, mG, mB, mA}, glm::vec4{ aNormal.x, aNormal.y, aExtrusion, mfLineWidthAndAA}},
});
if (mnInitialIndexSize == mrIndices.size())
{
mrIndices.insert(mrIndices.end(), {
zero + 0, zero + 1
});
mbIncomplete = true;
}
else
{
if (mbIncomplete)
{
mrIndices.insert(mrIndices.end(), {
zero + 0,
zero + 0, zero - 1, zero + 1
});
mbIncomplete = false;
}
else
{
mrIndices.insert(mrIndices.end(), {
zero - 2, zero - 1, zero + 0,
zero + 0, zero - 1, zero + 1
});
}
}
}
void LineBuilder::appendMiterJoint(glm::vec2 const& point, const glm::vec2& prevLineVector,
glm::vec2 const& nextLineVector)
{
// With miter join we calculate the extrusion vector by adding normals of
// previous and next line segment. The vector shows the way but we also
// need the length (otherwise the line will be deformed). Length factor is
// calculated as dot product of extrusion vector and one of the normals.
// The value we get is the inverse length (used in the shader):
// length = line_width / dot(extrusionVector, normal)
glm::vec2 normal(-prevLineVector.y, prevLineVector.x);
glm::vec2 tangent = vcl::vertex::normalize(nextLineVector + prevLineVector);
glm::vec2 extrusionVector(-tangent.y, tangent.x);
GLfloat length = glm::dot(extrusionVector, normal);
appendAndConnectLinePoint(point, extrusionVector, length);
}
void LineBuilder::appendBevelJoint(glm::vec2 const& point, const glm::vec2& prevLineVector,
const glm::vec2& nextLineVector)
{
// For bevel join we just add 2 additional vertices and use previous
// line segment normal and next line segment normal as extrusion vector.
// All the magic is done by the fact that we draw triangle strips, so we
// cover the joins correctly.
glm::vec2 prevNormal(-prevLineVector.y, prevLineVector.x);
glm::vec2 nextNormal(-nextLineVector.y, nextLineVector.x);
appendAndConnectLinePoint(point, prevNormal, 1.0f);
appendAndConnectLinePoint(point, nextNormal, 1.0f);
}
void LineBuilder::appendRoundJoint(glm::vec2 const& point, const glm::vec2& prevLineVector,
const glm::vec2& nextLineVector)
{
// For round join we do a similar thing as in bevel, we add more intermediate
// vertices and add normals to get extrusion vectors in the between the
// both normals.
// 3 additional extrusion vectors + normals are enough to make most
// line joins look round. Ideally the number of vectors could be
// calculated.
glm::vec2 prevNormal(-prevLineVector.y, prevLineVector.x);
glm::vec2 nextNormal(-nextLineVector.y, nextLineVector.x);
glm::vec2 middle = vcl::vertex::normalize(prevNormal + nextNormal);
glm::vec2 middleLeft = vcl::vertex::normalize(prevNormal + middle);
glm::vec2 middleRight = vcl::vertex::normalize(middle + nextNormal);
appendAndConnectLinePoint(point, prevNormal, 1.0f);
appendAndConnectLinePoint(point, middleLeft, 1.0f);
appendAndConnectLinePoint(point, middle, 1.0f);
appendAndConnectLinePoint(point, middleRight, 1.0f);
appendAndConnectLinePoint(point, nextNormal, 1.0f);
}
void LineBuilder::appendRoundLineCapVertices(const glm::vec2& rPoint1, const glm::vec2& rPoint2)
{
constexpr int nRoundCapIteration = 12;
glm::vec2 lineVector = vcl::vertex::normalize(rPoint2 - rPoint1);
glm::vec2 normal(-lineVector.y, lineVector.x);
glm::vec2 previousRoundNormal = normal;
for (int nFactor = 1; nFactor <= nRoundCapIteration; nFactor++)
{
float angle = float(nFactor) * (M_PI / float(nRoundCapIteration));
glm::vec2 roundNormal(normal.x * glm::cos(angle) - normal.y * glm::sin(angle),
normal.x * glm::sin(angle) + normal.y * glm::cos(angle));
appendLineSegment(rPoint1, previousRoundNormal, 1.0f,
rPoint1, roundNormal, 1.0f);
previousRoundNormal = roundNormal;
}
}
void LineBuilder::appendSquareLineCapVertices(const glm::vec2& rPoint1, const glm::vec2& rPoint2)
{
glm::vec2 lineVector = vcl::vertex::normalize(rPoint2 - rPoint1);
glm::vec2 normal(-lineVector.y, lineVector.x);
glm::vec2 extrudedPoint = rPoint1 + -lineVector * (mfLineWidth / 2.0f);
appendLineSegment(extrudedPoint, normal, 1.0f,
rPoint1, normal, 1.0f);
}
} // end vcl
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-192
View File
@@ -1,192 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include <memory>
#include <sal/config.h>
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <opengl/framebuffer.hxx>
#include <opengl/texture.hxx>
#include <opengl/PackedTextureAtlas.hxx>
namespace {
struct Node
{
tools::Rectangle mRectangle;
std::unique_ptr<Node> mLeftNode;
std::unique_ptr<Node> mRightNode;
bool mOccupied;
explicit Node(int nWidth, int nHeight);
explicit Node(tools::Rectangle const & aRectangle);
bool isLeaf() const;
Node* insert(int nWidth, int nHeight, int nPadding);
};
}
Node::Node(int nWidth, int nHeight)
: mRectangle(tools::Rectangle(Point(), Size(nWidth, nHeight)))
, mLeftNode()
, mRightNode()
, mOccupied(false)
{}
Node::Node(tools::Rectangle const & aRectangle)
: mRectangle(aRectangle)
, mLeftNode()
, mRightNode()
, mOccupied(false)
{}
bool Node::isLeaf() const { return mLeftNode == nullptr && mRightNode == nullptr; }
Node* Node::insert(int nWidth, int nHeight, int nPadding)
{
if (!isLeaf())
{
Node* pNewNode = mLeftNode->insert(nWidth, nHeight, nPadding);
if (pNewNode != nullptr)
return pNewNode;
return mRightNode->insert(nWidth, nHeight, nPadding);
}
else
{
if (mOccupied)
{
return nullptr;
}
if (nWidth > mRectangle.GetWidth() || nHeight > mRectangle.GetHeight())
{ // does not fit
return nullptr;
}
if (nWidth == mRectangle.GetWidth() && nHeight == mRectangle.GetHeight())
{ // perfect fit
mOccupied = true;
return this;
}
int dw = mRectangle.GetWidth() - nWidth;
int dh = mRectangle.GetHeight() - nHeight;
tools::Rectangle aLeftRect;
tools::Rectangle aRightRect;
if (dw > dh)
{
aLeftRect = tools::Rectangle(Point(mRectangle.Left(), mRectangle.Top()),
Size(nWidth, mRectangle.GetHeight()));
aRightRect = tools::Rectangle(Point(nPadding + mRectangle.Left() + nWidth, mRectangle.Top()),
Size(mRectangle.GetWidth() - nWidth - nPadding, mRectangle.GetHeight()));
}
else
{
aLeftRect = tools::Rectangle(Point(mRectangle.Left(), mRectangle.Top()),
Size(mRectangle.GetWidth(), nHeight));
aRightRect = tools::Rectangle(Point(mRectangle.Left(), nPadding + mRectangle.Top() + nHeight),
Size(mRectangle.GetWidth(), mRectangle.GetHeight() - nHeight - nPadding));
}
mLeftNode.reset(new Node(aLeftRect));
mRightNode.reset(new Node(aRightRect));
return mLeftNode->insert(nWidth, nHeight, nPadding);
}
}
struct PackedTexture
{
std::shared_ptr<ImplOpenGLTexture> mpTexture;
std::unique_ptr<Node> mpRootNode;
PackedTexture(int nWidth, int nHeight)
: mpTexture(std::make_shared<ImplOpenGLTexture>(nWidth, nHeight, true))
, mpRootNode(new Node(nWidth, nHeight))
{}
};
PackedTextureAtlasManager::PackedTextureAtlasManager(int nTextureWidth, int nTextureHeight)
: mnTextureWidth(nTextureWidth)
, mnTextureHeight(nTextureHeight)
{
}
PackedTextureAtlasManager::~PackedTextureAtlasManager()
{
for (std::unique_ptr<PackedTexture>& pPackedTexture : maPackedTextures)
{
// Free texture early in VCL shutdown while we have a context.
pPackedTexture->mpTexture.reset();
}
}
void PackedTextureAtlasManager::CreateNewTexture()
{
std::unique_ptr<PackedTexture> pPackedTexture(new PackedTexture(mnTextureWidth, mnTextureHeight));
GLuint nTextureID = pPackedTexture->mpTexture->mnTexture;
maPackedTextures.push_back(std::move(pPackedTexture));
VCL_GL_INFO("PackedTextureAtlas::CreateNewTexture adding texture: " << nTextureID <<
" atlases: " << maPackedTextures.size());
}
OpenGLTexture PackedTextureAtlasManager::Reserve(int nWidth, int nHeight)
{
for (std::unique_ptr<PackedTexture>& pPackedTexture : maPackedTextures)
{
Node* pNode = pPackedTexture->mpRootNode->insert(nWidth, nHeight, 1);
if (pNode != nullptr)
{
return OpenGLTexture(pPackedTexture->mpTexture, pNode->mRectangle, -1);
}
}
CreateNewTexture();
std::unique_ptr<PackedTexture>& pPackedTexture = maPackedTextures.back();
Node* pNode = pPackedTexture->mpRootNode->insert(nWidth, nHeight, 1);
if (pNode != nullptr)
{
return OpenGLTexture(pPackedTexture->mpTexture, pNode->mRectangle, -1);
}
return OpenGLTexture();
}
OpenGLTexture PackedTextureAtlasManager::InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8 const * pData)
{
OpenGLTexture aTexture = Reserve(nWidth, nHeight);
if (aTexture && pData == nullptr)
return aTexture;
aTexture.CopyData(nWidth, nHeight, nFormat, nType, pData);
return aTexture;
}
std::vector<GLuint> PackedTextureAtlasManager::ReduceTextureNumber(int nMaxNumberOfTextures)
{
std::vector<GLuint> aTextureIDs;
while (int(maPackedTextures.size()) > nMaxNumberOfTextures)
{
// Remove oldest created texture
GLuint nTextureID = maPackedTextures[0]->mpTexture->mnTexture;
aTextureIDs.push_back(nTextureID);
maPackedTextures.erase(maPackedTextures.begin());
VCL_GL_INFO("PackedTextureAtlas::ReduceTextureNumber removing texture: " << nTextureID <<
" atlases: " << maPackedTextures.size());
}
return aTextureIDs;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-404
View File
@@ -1,404 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include <opengl/RenderList.hxx>
#include <opengl/VertexUtils.hxx>
#include <opengl/LineRenderUtils.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygontriangulator.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
#include <basegfx/polygon/b2dtrapezoid.hxx>
namespace
{
/** Append vertices for the polyline
*
* OpenGL polyline drawing algorithm inspired by:
* - http://mattdesl.svbtle.com/drawing-lines-is-hard
* - https://www.mapbox.com/blog/drawing-antialiased-lines/
* - https://cesiumjs.org/2013/04/22/Robust-Polyline-Rendering-with-WebGL/
* - http://artgrammer.blogspot.si/2011/05/drawing-nearly-perfect-2d-line-segments.html
* - http://artgrammer.blogspot.si/2011/07/drawing-polylines-by-tessellation.html
*
*/
void appendPolyLine(vcl::LineBuilder& rBuilder, const basegfx::B2DPolygon& rPolygon,
basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap,
double fMiterMinimumAngle)
{
sal_uInt32 nPoints = rPolygon.count();
bool bClosed = rPolygon.isClosed();
if (nPoints == 2 || eLineJoin == basegfx::B2DLineJoin::NONE)
{
// If line joint is NONE or a simple line with 2 points, draw the polyline
// each line segment separately.
for (sal_uInt32 i = 0; i < (bClosed ? nPoints : nPoints - 1); ++i)
{
sal_uInt32 index1 = (i + 0) % nPoints; // loop indices - important when polyline is closed
sal_uInt32 index2 = (i + 1) % nPoints;
glm::vec2 aPoint1(rPolygon.getB2DPoint(index1).getX(), rPolygon.getB2DPoint(index1).getY());
glm::vec2 aPoint2(rPolygon.getB2DPoint(index2).getX(), rPolygon.getB2DPoint(index2).getY());
rBuilder.appendLine(aPoint1, aPoint2);
}
}
else if (nPoints > 2)
{
int i = 0;
int lastPoint = int(nPoints);
glm::vec2 p0(rPolygon.getB2DPoint(nPoints - 1).getX(), rPolygon.getB2DPoint(nPoints - 1).getY());
glm::vec2 p1(rPolygon.getB2DPoint(0).getX(), rPolygon.getB2DPoint(0).getY());
glm::vec2 p2(rPolygon.getB2DPoint(1).getX(), rPolygon.getB2DPoint(1).getY());
glm::vec2 nextLineVector;
glm::vec2 previousLineVector;
glm::vec2 normal; // perpendicular to the line vector
nextLineVector = vcl::vertex::normalize(p2 - p1);
if (!bClosed)
{
normal = glm::vec2(-nextLineVector.y, nextLineVector.x); // make perpendicular
rBuilder.appendAndConnectLinePoint(p1, normal, 1.0f);
i++; // first point done already
lastPoint--; // last point will be calculated separately from the loop
p0 = p1;
previousLineVector = nextLineVector;
}
else
{
lastPoint++; // we need to connect last point to first point so one more line segment to calculate
previousLineVector = vcl::vertex::normalize(p1 - p0);
}
for (; i < lastPoint; ++i)
{
int index1 = (i + 0) % nPoints; // loop indices - important when polyline is closed
int index2 = (i + 1) % nPoints;
p1 = glm::vec2(rPolygon.getB2DPoint(index1).getX(), rPolygon.getB2DPoint(index1).getY());
p2 = glm::vec2(rPolygon.getB2DPoint(index2).getX(), rPolygon.getB2DPoint(index2).getY());
if (p1 == p2) // skip equal points, normals could div-by-0
continue;
nextLineVector = vcl::vertex::normalize(p2 - p1);
if (eLineJoin == basegfx::B2DLineJoin::Miter)
{
if (vcl::vertex::lineVectorAngle(previousLineVector, nextLineVector) < fMiterMinimumAngle)
rBuilder.appendBevelJoint(p1, previousLineVector, nextLineVector);
else
rBuilder.appendMiterJoint(p1, previousLineVector, nextLineVector);
}
else if (eLineJoin == basegfx::B2DLineJoin::Bevel)
{
rBuilder.appendBevelJoint(p1, previousLineVector, nextLineVector);
}
else if (eLineJoin == basegfx::B2DLineJoin::Round)
{
rBuilder.appendRoundJoint(p1, previousLineVector, nextLineVector);
}
p0 = p1;
previousLineVector = nextLineVector;
}
if (!bClosed)
{
// Create vertices for the last point. There is no line join so just
// use the last line segment normal as the extrusion vector.
p1 = glm::vec2(rPolygon.getB2DPoint(nPoints - 1).getX(), rPolygon.getB2DPoint(nPoints - 1).getY());
normal = glm::vec2(-previousLineVector.y, previousLineVector.x);
rBuilder.appendAndConnectLinePoint(p1, normal, 1.0f);
}
}
if (bClosed || nPoints < 2 || (eLineCap != css::drawing::LineCap_ROUND && eLineCap != css::drawing::LineCap_SQUARE))
return;
glm::vec2 aBeginCapPoint1(rPolygon.getB2DPoint(0).getX(), rPolygon.getB2DPoint(0).getY());
glm::vec2 aBeginCapPoint2(rPolygon.getB2DPoint(1).getX(), rPolygon.getB2DPoint(1).getY());
glm::vec2 aEndCapPoint1(rPolygon.getB2DPoint(nPoints - 1).getX(), rPolygon.getB2DPoint(nPoints - 1).getY());
glm::vec2 aEndCapPoint2(rPolygon.getB2DPoint(nPoints - 2).getX(), rPolygon.getB2DPoint(nPoints - 2).getY());
if (eLineCap == css::drawing::LineCap_ROUND)
{
rBuilder.appendRoundLineCapVertices(aBeginCapPoint1, aBeginCapPoint2);
rBuilder.appendRoundLineCapVertices(aEndCapPoint1, aEndCapPoint2);
}
else if (eLineCap == css::drawing::LineCap_SQUARE)
{
rBuilder.appendSquareLineCapVertices(aBeginCapPoint1, aBeginCapPoint2);
rBuilder.appendSquareLineCapVertices(aEndCapPoint1, aEndCapPoint2);
}
}
void appendTrapezoid(std::vector<Vertex>& rVertices, std::vector<GLuint>& rIndices,
GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4,
Color nColor, GLfloat fTransparency)
{
GLubyte nR, nG, nB, nA;
vcl::vertex::createColor(nColor, fTransparency, nR, nG, nB, nA);
GLuint zero = rVertices.size();
rVertices.insert(rVertices.end(), {
{glm::vec2{x1, y1}, glm::vec4{nR, nG, nB, nA}, glm::vec4{0.0f, 0.0f, 0.0f, 0.0f}},
{glm::vec2{x2, y2}, glm::vec4{nR, nG, nB, nA}, glm::vec4{0.0f, 0.0f, 0.0f, 0.0f}},
{glm::vec2{x3, y3}, glm::vec4{nR, nG, nB, nA}, glm::vec4{0.0f, 0.0f, 0.0f, 0.0f}},
{glm::vec2{x4, y4}, glm::vec4{nR, nG, nB, nA}, glm::vec4{0.0f, 0.0f, 0.0f, 0.0f}},
});
rIndices.insert(rIndices.end(), {
zero + 0, zero + 1, zero + 2,
zero + 2, zero + 1, zero + 3
});
}
void appendRectangle(std::vector<Vertex>& rVertices, std::vector<GLuint>& rIndices,
GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
Color nColor, GLfloat fTransparency)
{
GLubyte nR, nG, nB, nA;
vcl::vertex::createColor(nColor, fTransparency, nR, nG, nB, nA);
GLuint zero = rVertices.size();
rVertices.insert(rVertices.end(), {
{glm::vec2{x1, y1}, glm::vec4{nR, nG, nB, nA}, glm::vec4{0.0f, 0.0f, 0.0f, 0.0f}},
{glm::vec2{x2, y1}, glm::vec4{nR, nG, nB, nA}, glm::vec4{0.0f, 0.0f, 0.0f, 0.0f}},
{glm::vec2{x1, y2}, glm::vec4{nR, nG, nB, nA}, glm::vec4{0.0f, 0.0f, 0.0f, 0.0f}},
{glm::vec2{x2, y2}, glm::vec4{nR, nG, nB, nA}, glm::vec4{0.0f, 0.0f, 0.0f, 0.0f}},
});
rIndices.insert(rIndices.end(), {
zero + 0, zero + 1, zero + 2,
zero + 2, zero + 1, zero + 3
});
}
} // end anonymous namespace
void RenderList::addDrawPixel(tools::Long nX, tools::Long nY, Color nColor)
{
if (nColor == SALCOLOR_NONE)
return;
checkOverlapping(basegfx::B2DRange(nX, nY, nX, nY));
RenderParameters& rRenderParameter = maRenderEntries.back().maTriangleParameters;
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
nX - 0.5f, nY - 0.5f, nX + 0.5f, nY + 0.5f, nColor, 0.0f);
}
void RenderList::addDrawRectangle(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, double fTransparency,
Color nLineColor, Color nFillColor)
{
if (nLineColor == SALCOLOR_NONE && nFillColor == SALCOLOR_NONE)
return;
if (fTransparency == 1.0f)
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 (nLineColor != SALCOLOR_NONE)
{
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX1 - 0.5f, fY1 - 0.5f, fX1 + 0.5f, fY2 + 0.5f, nLineColor, fTransparency);
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX1 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY1 + 0.5f, nLineColor, fTransparency);
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX2 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY2 + 0.5f, nLineColor, fTransparency);
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX1 - 0.5f, fY2 - 0.5f, fX2 + 0.5f, fY2 + 0.5f, nLineColor, fTransparency);
}
if (nFillColor == SALCOLOR_NONE)
return;
// coverity[copy_paste_error : FALSE] - this is correct nLineColor not nFillColor
if (nLineColor == SALCOLOR_NONE)
{
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX1 - 0.5f, fY1 - 0.5f, fX1 + 0.5f, fY2 + 0.5f, nFillColor, fTransparency);
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX1 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY1 + 0.5f, nFillColor, fTransparency);
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX2 - 0.5f, fY1 - 0.5f, fX2 + 0.5f, fY2 + 0.5f, nFillColor, fTransparency);
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX1 - 0.5f, fY2 - 0.5f, fX2 + 0.5f, fY2 + 0.5f, nFillColor, fTransparency);
}
// Draw rectangle fill with fill color
appendRectangle(rRenderParameter.maVertices, rRenderParameter.maIndices,
fX1 + 0.5f, fY1 + 0.5f, fX2 - 0.5f, fY2 - 0.5f, nFillColor, fTransparency);
}
void RenderList::addDrawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2, Color nLineColor, bool bUseAA)
{
if (nLineColor == SALCOLOR_NONE)
return;
checkOverlapping(basegfx::B2DRange(nX1, nY1, nX2, nY2));
RenderParameters& rRenderParameter = maRenderEntries.back().maLineParameters;
glm::vec2 aPoint1(nX1, nY1);
glm::vec2 aPoint2(nX2, nY2);
vcl::LineBuilder aBuilder(rRenderParameter.maVertices, rRenderParameter.maIndices, nLineColor, 0.0f, 1.0f, bUseAA);
aBuilder.appendLine(aPoint1, aPoint2);
}
void RenderList::addDrawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency,
Color nLineColor, Color nFillColor, bool bUseAA)
{
if (rPolyPolygon.count() <= 0)
return;
if (nLineColor == SALCOLOR_NONE && nFillColor == SALCOLOR_NONE)
return;
if (fTransparency == 1.0)
return;
checkOverlapping(rPolyPolygon.getB2DRange());
if (nFillColor != SALCOLOR_NONE)
{
basegfx::B2DTrapezoidVector aTrapezoidVector;
basegfx::utils::trapezoidSubdivide(aTrapezoidVector, rPolyPolygon);
if (!aTrapezoidVector.empty())
{
RenderParameters& rTriangleRenderParameter = maRenderEntries.back().maTriangleParameters;
for (const basegfx::B2DTrapezoid & rTrapezoid : aTrapezoidVector)
{
GLfloat topX1 = rTrapezoid.getTopXLeft();
GLfloat topX2 = rTrapezoid.getTopXRight();
GLfloat topY = rTrapezoid.getTopY();
GLfloat bottomX1 = rTrapezoid.getBottomXLeft();
GLfloat bottomX2 = rTrapezoid.getBottomXRight();
GLfloat bottomY = rTrapezoid.getBottomY();
appendTrapezoid(rTriangleRenderParameter.maVertices, rTriangleRenderParameter.maIndices,
topX1, topY, topX2, topY,
bottomX1, bottomY, bottomX2, bottomY,
nFillColor, fTransparency);
}
}
}
if (nLineColor == SALCOLOR_NONE && !bUseAA)
return;
RenderParameters& rLineRenderParameter = maRenderEntries.back().maLineParameters;
Color nColor = (nLineColor == SALCOLOR_NONE) ? nFillColor : nLineColor;
vcl::LineBuilder aBuilder(rLineRenderParameter.maVertices, rLineRenderParameter.maIndices,
nColor, fTransparency, 1.0f, bUseAA);
for (const basegfx::B2DPolygon& rPolygon : rPolyPolygon)
{
basegfx::B2DPolygon aPolygon(rPolygon);
if (rPolygon.areControlPointsUsed())
aPolygon = rPolygon.getDefaultAdaptiveSubdivision();
sal_uInt32 nPoints = aPolygon.count();
if (nPoints <= 1)
continue;
GLfloat x1, y1, x2, y2;
sal_uInt32 index1, index2;
for (sal_uInt32 i = 0; i <= nPoints; ++i)
{
index1 = i % nPoints;
index2 = (i + 1) % nPoints;
x1 = aPolygon.getB2DPoint(index1).getX();
y1 = aPolygon.getB2DPoint(index1).getY();
x2 = aPolygon.getB2DPoint(index2).getX();
y2 = aPolygon.getB2DPoint(index2).getY();
aBuilder.appendLine(glm::vec2(x1, y1), glm::vec2(x2, y2));
}
}
}
void RenderList::addDrawTextureWithMaskColor(OpenGLTexture const & rTexture, Color nColor, const SalTwoRect& r2Rect)
{
if (!rTexture)
return;
GLfloat fX1 = r2Rect.mnDestX;
GLfloat fY1 = r2Rect.mnDestY;
GLfloat fX2 = fX1 + r2Rect.mnDestWidth;
GLfloat fY2 = fY1 + r2Rect.mnDestHeight;
checkOverlapping(basegfx::B2DRange(fX1, fY1, fX2, fY2));
GLuint nTextureId = rTexture.Id();
RenderTextureParameters& rTextureParameter = maRenderEntries.back().maTextureParametersMap[nTextureId];
rTextureParameter.maTexture = rTexture;
rTexture.FillCoords<GL_TRIANGLES>(rTextureParameter.maTextureCoords, r2Rect);
vcl::vertex::addRectangle<GL_TRIANGLES>(rTextureParameter.maVertices, fX1, fY1, fX2, fY2);
vcl::vertex::addQuadColors<GL_TRIANGLES>(rTextureParameter.maColors, nColor, 0.0f);
}
void RenderList::addDrawPolyLine(const basegfx::B2DPolygon& rPolygon, double fTransparency,
double fLineWidth, basegfx::B2DLineJoin eLineJoin,
css::drawing::LineCap eLineCap, double fMiterMinimumAngle,
Color nLineColor, bool bUseAA)
{
if (rPolygon.count() <= 1)
return;
if (nLineColor == SALCOLOR_NONE)
return;
if (fTransparency == 1.0)
return;
const bool bIsHairline = fLineWidth <= 1.2;
fLineWidth = bIsHairline ? 1.0f : fLineWidth;
basegfx::B2DPolygon aPolygon(rPolygon);
if (rPolygon.areControlPointsUsed())
aPolygon = rPolygon.getDefaultAdaptiveSubdivision();
checkOverlapping(aPolygon.getB2DRange());
RenderParameters& rParameter = maRenderEntries.back().maLineParameters;
vcl::LineBuilder aBuilder(rParameter.maVertices, rParameter.maIndices,
nLineColor, fTransparency, fLineWidth, bUseAA);
appendPolyLine(aBuilder, aPolygon, eLineJoin, eLineCap, fMiterMinimumAngle);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-108
View File
@@ -1,108 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <sal/log.hxx>
#include <opengl/framebuffer.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
OpenGLFramebuffer::OpenGLFramebuffer() :
mnId( 0 ),
mnWidth( 0 ),
mnHeight( 0 ),
mnAttachedTexture( 0 ),
mpPrevFramebuffer( nullptr )
{
glGenFramebuffers( 1, &mnId );
CHECK_GL_ERROR();
VCL_GL_INFO( "Created framebuffer " << static_cast<int>(mnId) );
}
OpenGLFramebuffer::~OpenGLFramebuffer()
{
glDeleteFramebuffers( 1, &mnId );
VCL_GL_INFO( "Deleted framebuffer " << static_cast<int>(mnId) );
CHECK_GL_ERROR();
}
void OpenGLFramebuffer::Bind(GLenum eTarget)
{
VCL_GL_INFO( "Binding framebuffer " << static_cast<int>(mnId) );
glBindFramebuffer(eTarget, mnId);
CHECK_GL_ERROR();
}
void OpenGLFramebuffer::Unbind(GLenum eTarget)
{
glBindFramebuffer(eTarget, 0);
CHECK_GL_ERROR();
VCL_GL_INFO( "Binding default framebuffer" );
}
bool OpenGLFramebuffer::IsFree() const
{
return !mnAttachedTexture;
}
bool OpenGLFramebuffer::IsAttached( GLuint nTexture ) const
{
return mnAttachedTexture == nTexture;
}
bool OpenGLFramebuffer::IsAttached( const OpenGLTexture& rTexture ) const
{
return mnAttachedTexture == rTexture.Id();
}
void OpenGLFramebuffer::AttachTexture( const OpenGLTexture& rTexture )
{
if( rTexture.Id() == mnAttachedTexture )
return;
VCL_GL_INFO( "Attaching texture " << rTexture.Id() << " to framebuffer " << static_cast<int>(mnId) );
mnAttachedTexture = rTexture.Id();
mnWidth = rTexture.GetWidth();
mnHeight = rTexture.GetHeight();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mnAttachedTexture, 0);
CHECK_GL_ERROR();
GLuint nStencil = rTexture.StencilId();
if( nStencil )
{
VCL_GL_INFO( "Attaching stencil " << nStencil << " to framebuffer " << static_cast<int>(mnId) );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, nStencil );
CHECK_GL_ERROR();
}
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
CHECK_GL_ERROR();
if (status != GL_FRAMEBUFFER_COMPLETE)
{
SAL_WARN("vcl.opengl", "Framebuffer incomplete");
}
}
void OpenGLFramebuffer::DetachTexture()
{
if( mnAttachedTexture != 0 )
{
mnAttachedTexture = 0;
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 );
CHECK_GL_ERROR();
// FIXME: we could make this conditional on having a stencil ?
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, 0 );
CHECK_GL_ERROR();
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
File diff suppressed because it is too large Load Diff
-390
View File
@@ -1,390 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <opengl/program.hxx>
#include <opengl/RenderState.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
OpenGLProgram::OpenGLProgram() :
mnId( 0 ),
mnEnabledAttribs( 0 ),
mnPositionAttrib( SAL_MAX_UINT32 ),
mnTexCoordAttrib( SAL_MAX_UINT32 ),
mnAlphaCoordAttrib( SAL_MAX_UINT32 ),
mnMaskCoordAttrib( SAL_MAX_UINT32 ),
mnExtrusionVectorsAttrib( SAL_MAX_UINT32 ),
mnVertexColorsAttrib( SAL_MAX_UINT32 ),
mbBlending(false),
mfLastWidth(0.0),
mfLastHeight(0.0),
mfLastPixelOffset(0.0)
{
}
OpenGLProgram::~OpenGLProgram()
{
maUniformLocations.clear();
if( mnId != 0 )
{
glDeleteProgram( mnId );
CHECK_GL_ERROR();
}
}
bool OpenGLProgram::Load( const OUString& rVertexShader,
const OUString& rFragmentShader,
const OString& preamble,
const OString& rDigest )
{
mnId = OpenGLHelper::LoadShaders( rVertexShader, rFragmentShader, preamble, rDigest );
return ( mnId != 0 );
}
void OpenGLProgram::Reuse()
{
mbBlending = false;
}
void OpenGLProgram::Use()
{
if (!mnId)
return;
glUseProgram(mnId);
CHECK_GL_ERROR();
Reuse();
}
void OpenGLProgram::Clean()
{
// unbind all textures
for (OpenGLTexture& rTexture : maTextures)
{
rTexture.Unbind();
}
maTextures.clear();
// disable any enabled vertex attrib array
if( mnEnabledAttribs )
{
for( int i = 0; i < 32; i++ )
{
if( mnEnabledAttribs & ( 1 << i ) )
{
glDisableVertexAttribArray( i );
CHECK_GL_ERROR();
}
}
mnEnabledAttribs = 0;
}
}
bool OpenGLProgram::EnableVertexAttrib(GLuint& rAttrib, const OString& rName)
{
if( rAttrib == SAL_MAX_UINT32 )
{
GLint aLocation = glGetAttribLocation(mnId, rName.getStr());
CHECK_GL_ERROR();
if (aLocation < 0)
return false;
rAttrib = GLuint(aLocation);
}
if( (mnEnabledAttribs & ( 1 << rAttrib )) == 0 )
{
glEnableVertexAttribArray( rAttrib );
CHECK_GL_ERROR();
mnEnabledAttribs |= ( 1 << rAttrib );
}
return true;
}
void OpenGLProgram::SetVertexAttrib(GLuint& rAttrib, const OString& rName, GLint nSize,
GLenum eType, GLboolean bNormalized, GLsizei aStride,
const GLvoid* pPointer)
{
if (EnableVertexAttrib(rAttrib, rName))
{
glVertexAttribPointer(rAttrib, nSize, eType, bNormalized, aStride, pPointer);
CHECK_GL_ERROR();
}
else
{
VCL_GL_INFO("Vertex attribute '" << rName << "' doesn't exist in this program (" << mnId << ")");
}
}
void OpenGLProgram::SetVertices( const GLvoid* pData )
{
SetVertexAttrib(mnPositionAttrib, "position", 2, GL_FLOAT, GL_FALSE, 0, pData);
}
void OpenGLProgram::SetTextureCoord( const GLvoid* pData )
{
SetVertexAttrib(mnTexCoordAttrib, "tex_coord_in", 2, GL_FLOAT, GL_FALSE, 0, pData);
}
void OpenGLProgram::SetAlphaCoord( const GLvoid* pData )
{
SetVertexAttrib(mnAlphaCoordAttrib, "alpha_coord_in", 2, GL_FLOAT, GL_FALSE, 0, pData);
}
void OpenGLProgram::SetMaskCoord(const GLvoid* pData)
{
SetVertexAttrib(mnMaskCoordAttrib, "mask_coord_in", 2, GL_FLOAT, GL_FALSE, 0, pData);
}
void OpenGLProgram::SetExtrusionVectors(const GLvoid* pData)
{
SetVertexAttrib(mnExtrusionVectorsAttrib, "extrusion_vectors", 3, GL_FLOAT, GL_FALSE, 0, pData);
}
void OpenGLProgram::SetVertexColors(std::vector<GLubyte>& rColorVector)
{
SetVertexAttrib(mnVertexColorsAttrib, "vertex_color_in", 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, rColorVector.data());
}
void OpenGLProgram::SetShaderType(TextureShaderType eTextureShaderType)
{
SetUniform1i("type", GLint(eTextureShaderType));
}
void OpenGLProgram::SetShaderType(DrawShaderType eDrawShaderType)
{
SetUniform1i("type", GLint(eDrawShaderType));
}
GLuint OpenGLProgram::GetUniformLocation( const OString& rName )
{
auto it = maUniformLocations.find( rName );
if( it == maUniformLocations.end() )
{
GLuint nLocation = glGetUniformLocation( mnId, rName.getStr() );
CHECK_GL_ERROR();
maUniformLocations[rName] = nLocation;
return nLocation;
}
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::DrawElements(GLenum aMode, GLuint nNumberOfVertices)
{
if (!mbBlending)
OpenGLContext::getVCLContext()->state().blend().disable();
glDrawElements(aMode, nNumberOfVertices, GL_UNSIGNED_INT, nullptr);
}
void OpenGLProgram::SetUniform1f( const OString& rName, GLfloat v1 )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform1f( nUniform, v1 );
CHECK_GL_ERROR();
}
void OpenGLProgram::SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform2f( nUniform, v1, v2 );
CHECK_GL_ERROR();
}
void OpenGLProgram::SetUniform1fv( const OString& rName, GLsizei nCount, GLfloat const * aValues )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform1fv( nUniform, nCount, aValues );
CHECK_GL_ERROR();
}
void OpenGLProgram::SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat const * aValues )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform2fv( nUniform, nCount, aValues );
CHECK_GL_ERROR();
}
void OpenGLProgram::SetUniform1i( const OString& rName, GLint v1 )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform1i( nUniform, v1 );
CHECK_GL_ERROR();
}
void OpenGLProgram::SetColor( const OString& rName, Color nColor, sal_uInt8 nTransparency )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform4f( nUniform,
nColor.GetRed() / 255.0f,
nColor.GetGreen() / 255.0f,
nColor.GetBlue() / 255.0f,
(100 - nTransparency) * (1.0 / 100) );
CHECK_GL_ERROR();
if( nTransparency > 0 )
SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
void OpenGLProgram::SetColorf( const OString& rName, Color nColor, double fTransparency )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform4f( nUniform,
nColor.GetRed() / 255.0f,
nColor.GetGreen() / 255.0f,
nColor.GetBlue() / 255.0f,
(1.0f - fTransparency) );
CHECK_GL_ERROR();
if( fTransparency > 0.0 )
SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
void OpenGLProgram::SetColor( const OString& rName, const Color& rColor )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform4f( nUniform,
static_cast<float>(rColor.GetRed()) / 255,
static_cast<float>(rColor.GetGreen()) / 255,
static_cast<float>(rColor.GetBlue()) / 255,
1.0f - static_cast<float>(rColor.GetTransparency()) / 255 );
CHECK_GL_ERROR();
if( rColor.GetTransparency() > 0 )
SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
void OpenGLProgram::SetColorWithIntensity( const OString& rName, const Color& rColor, tools::Long nFactor )
{
GLuint nUniform = GetUniformLocation( rName );
glUniform4f( nUniform,
static_cast<float>(rColor.GetRed()) * nFactor / 25500.0,
static_cast<float>(rColor.GetGreen()) * nFactor / 25500.0,
static_cast<float>(rColor.GetBlue()) * nFactor / 25500.0,
1.0f );
CHECK_GL_ERROR();
}
void OpenGLProgram::SetTexture( const OString& rName, OpenGLTexture& rTexture )
{
GLuint nUniform = GetUniformLocation( rName );
int nIndex = maTextures.size();
glUniform1i( nUniform, nIndex );
CHECK_GL_ERROR();
OpenGLContext::getVCLContext()->state().texture().active(nIndex);
rTexture.Bind();
maTextures.push_back(rTexture);
}
void OpenGLProgram::SetTransform(
const OString& rName,
const OpenGLTexture& rTexture,
const basegfx::B2DPoint& rNull,
const basegfx::B2DPoint& rX,
const basegfx::B2DPoint& rY )
{
auto nTexWidth = rTexture.GetWidth();
auto nTexHeight = rTexture.GetHeight();
if (nTexWidth == 0 || nTexHeight == 0)
return;
GLuint nUniform = GetUniformLocation( rName );
const basegfx::B2DVector aXRel = rX - rNull;
const basegfx::B2DVector aYRel = rY - rNull;
const float aValues[] = {
static_cast<float>(aXRel.getX())/nTexWidth, static_cast<float>(aXRel.getY())/nTexWidth, 0, 0,
static_cast<float>(aYRel.getX())/nTexHeight, static_cast<float>(aYRel.getY())/nTexHeight, 0, 0,
0, 0, 1, 0,
static_cast<float>(rNull.getX()), static_cast<float>(rNull.getY()), 0, 1 };
glm::mat4 aMatrix = glm::make_mat4( aValues );
glUniformMatrix4fv( nUniform, 1, GL_FALSE, glm::value_ptr( aMatrix ) );
CHECK_GL_ERROR();
}
void OpenGLProgram::SetIdentityTransform(const OString& rName)
{
GLuint nUniform = GetUniformLocation(rName);
glm::mat4 aMatrix {};
glUniformMatrix4fv(nUniform, 1, GL_FALSE, glm::value_ptr( aMatrix ) );
CHECK_GL_ERROR();
}
void OpenGLProgram::ApplyMatrix(float fWidth, float fHeight, float fPixelOffset)
{
if (mfLastWidth == fWidth && mfLastHeight == fHeight && mfLastPixelOffset == fPixelOffset)
return;
mfLastWidth = fWidth;
mfLastHeight = fHeight;
mfLastPixelOffset = fPixelOffset;
GLuint nUniform = GetUniformLocation("mvp");
glm::mat4 aMVP = glm::ortho(0.0f, fWidth, fHeight, 0.0f, 0.0f, 1.0f);
if (fPixelOffset != 0.0f)
aMVP = glm::translate(aMVP, glm::vec3(fPixelOffset, fPixelOffset, 0.0f));
glUniformMatrix4fv(nUniform, 1, GL_FALSE, glm::value_ptr(aMVP));
CHECK_GL_ERROR();
}
void OpenGLProgram::SetBlendMode(GLenum nSFactor, GLenum nDFactor)
{
OpenGLContext::getVCLContext()->state().blend().enable();
OpenGLContext::getVCLContext()->state().blend().func(nSFactor, nDFactor);
mbBlending = true;
}
void OpenGLProgram::DrawTexture( const OpenGLTexture& rTexture )
{
if (!rTexture)
return;
float fWidth = rTexture.GetWidth();
float fHeight = rTexture.GetHeight();
float fMinX = 0.0f;
float fMaxX = fWidth;
float fMinY = 0.0f;
float fMaxY = fHeight;
std::vector<GLfloat> aPosition {
fMinX, fMaxY,
fMinX, fMinY,
fMaxX, fMinY,
fMaxX, fMaxY
};
GLfloat aTexCoord[8];
rTexture.GetWholeCoord( aTexCoord );
SetTextureCoord( aTexCoord );
ApplyMatrix(fWidth, fHeight);
DrawArrays(GL_TRIANGLE_FAN, aPosition);
CHECK_GL_ERROR();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-783
View File
@@ -1,783 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* 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 <memory>
#include <sal/config.h>
#include <sal/log.hxx>
#include <osl/diagnose.h>
#include <tools/debug.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <vcl/bitmap.hxx>
#include <vcl/checksum.hxx>
#include <vcl/outdev.hxx>
#include <svdata.hxx>
#include <salgdi.hxx>
#include <vcleventlisteners.hxx>
#include <vcl/lazydelete.hxx>
#include <scanlinewriter.hxx>
#include <o3tl/make_shared.hxx>
#include <opengl/zone.hxx>
#include <opengl/program.hxx>
#include <opengl/salbmp.hxx>
#include <opengl/RenderState.hxx>
#include <opengl/FixedTextureAtlas.hxx>
#if OSL_DEBUG_LEVEL > 0
# define CANARY "tex-canary"
#endif
namespace
{
bool determineTextureFormat(sal_uInt16 nBits, GLenum& nFormat, GLenum& nType)
{
switch(nBits)
{
case 8:
nFormat = GL_LUMINANCE;
nType = GL_UNSIGNED_BYTE;
return true;
case 24:
nFormat = GL_RGB;
nType = GL_UNSIGNED_BYTE;
return true;
case 32:
nFormat = GL_RGBA;
nType = GL_UNSIGNED_BYTE;
return true;
default:
break;
}
SAL_WARN("vcl.opengl", "Could not determine the appropriate texture format for input bits '" << nBits << "'");
return false;
}
bool isValidBitCount( sal_uInt16 nBitCount )
{
return (nBitCount == 1) || (nBitCount == 4) || (nBitCount == 8) || (nBitCount == 24) || (nBitCount == 32);
}
sal_uInt32 lclBytesPerRow(sal_uInt16 nBits, int nWidth)
{
switch(nBits)
{
case 1: return (nWidth + 7) >> 3;
case 4: return (nWidth + 1) >> 1;
case 8: return nWidth;
case 24: return nWidth * 3;
case 32: return nWidth * 4;
default:
OSL_FAIL("vcl::OpenGLSalBitmap::AllocateUserData(), illegal bitcount!");
}
return 0;
}
}
OpenGLSalBitmap::OpenGLSalBitmap()
: mbDirtyTexture(true)
, mnBits(0)
, mnBytesPerRow(0)
, mnWidth(0)
, mnHeight(0)
{
}
OpenGLSalBitmap::~OpenGLSalBitmap()
{
Destroy();
VCL_GL_INFO( "~OpenGLSalBitmap" );
}
void OpenGLSalBitmap::Create( const OpenGLTexture& rTex, tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight )
{
DBG_TESTSOLARMUTEX();
static const BitmapPalette aEmptyPalette;
OpenGLVCLContextZone aContextZone;
Destroy();
VCL_GL_INFO( "OpenGLSalBitmap::Create from FBO: ["
<< nX << ", " << nY << "] " << nWidth << "x" << nHeight );
GLint nMaxTextureSize;
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &nMaxTextureSize );
if ( nWidth > nMaxTextureSize )
{
nWidth = nMaxTextureSize;
VCL_GL_INFO( "Width limited to " << nMaxTextureSize );
}
if ( nHeight > nMaxTextureSize )
{
nHeight = nMaxTextureSize;
VCL_GL_INFO( "Height limited to " << nMaxTextureSize );
}
mnWidth = nWidth;
mnHeight = nHeight;
// TODO Check the framebuffer configuration
mnBits = 32;
maPalette = aEmptyPalette;
if( rTex )
maTexture = OpenGLTexture( rTex, nX, nY, nWidth, nHeight );
else
maTexture = OpenGLTexture( nX, nY, nWidth, nHeight );
mbDirtyTexture = false;
VCL_GL_INFO( "Created texture " << maTexture.Id() );
assert(mnWidth == maTexture.GetWidth() &&
mnHeight == maTexture.GetHeight());
}
bool OpenGLSalBitmap::Create( const Size& rSize, sal_uInt16 nBits, const BitmapPalette& rBitmapPalette )
{
DBG_TESTSOLARMUTEX();
OpenGLVCLContextZone aContextZone;
Destroy();
VCL_GL_INFO( "OpenGLSalBitmap::Create with size: " << rSize );
if( !isValidBitCount( nBits ) )
return false;
maPalette = rBitmapPalette;
mnBits = nBits;
mnWidth = rSize.Width();
mnHeight = rSize.Height();
// Limit size to what GL allows, so later glTexImage2D() won't fail.
GLint nMaxTextureSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &nMaxTextureSize);
if (mnWidth > nMaxTextureSize)
mnWidth = nMaxTextureSize;
if (mnHeight > nMaxTextureSize)
mnHeight = nMaxTextureSize;
return false;
}
bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp )
{
DBG_TESTSOLARMUTEX();
return Create( rSalBmp, rSalBmp.GetBitCount() );
}
bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
{
DBG_TESTSOLARMUTEX();
return Create( rSalBmp, pGraphics ? pGraphics->GetBitCount() : rSalBmp.GetBitCount() );
}
bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount )
{
DBG_TESTSOLARMUTEX();
OpenGLZone aZone;
// check that carefully only in the debug mode
assert(dynamic_cast<const OpenGLSalBitmap*>(&rSalBmp));
const OpenGLSalBitmap& rSourceBitmap = static_cast<const OpenGLSalBitmap&>(rSalBmp);
VCL_GL_INFO("OpenGLSalBitmap::Create from BMP: "
<< rSourceBitmap.mnWidth << "x" << rSourceBitmap.mnHeight
<< " Bits old: " << mnBits << " new:" << nNewBitCount );
if( isValidBitCount( nNewBitCount ) )
{
// TODO: lfrb: What about the pending operations?!
mnBits = nNewBitCount;
mnBytesPerRow = rSourceBitmap.mnBytesPerRow;
mnWidth = rSourceBitmap.mnWidth;
mnHeight = rSourceBitmap.mnHeight;
maPalette = rSourceBitmap.maPalette;
// execute any pending operations on the source bitmap
maTexture = rSourceBitmap.GetTexture();
mbDirtyTexture = false;
// be careful here, we are share & reference-count the
// mpUserBuffer, BUT this Create() is called from
// Bitmap::ImplMakeUnique().
// Consequently, there might be cases when this needs to be made
// unique later (when we don't do that right away here), like when
// using the BitmapWriteAccess.
mpUserBuffer = rSourceBitmap.mpUserBuffer;
return true;
}
return false;
}
bool OpenGLSalBitmap::Create( const css::uno::Reference< css::rendering::XBitmapCanvas >& /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
{
DBG_TESTSOLARMUTEX();
// TODO Is this method needed?
return false;
}
OpenGLTexture& OpenGLSalBitmap::GetTexture() const
{
OpenGLSalBitmap* pThis = const_cast<OpenGLSalBitmap*>(this);
if( !maTexture || mbDirtyTexture )
pThis->CreateTexture();
VCL_GL_INFO( "Got texture " << maTexture.Id() );
return pThis->maTexture;
}
void OpenGLSalBitmap::Destroy()
{
OpenGLZone aZone;
VCL_GL_INFO("Destroy OpenGLSalBitmap texture:" << maTexture.Id());
maTexture = OpenGLTexture();
DeallocateUserData();
}
bool OpenGLSalBitmap::AllocateUserData()
{
VCL_GL_INFO( "OpenGLSalBitmap::AllocateUserData" );
if( mnWidth && mnHeight )
{
mnBytesPerRow = lclBytesPerRow(mnBits, mnWidth);
}
bool alloc = false;
if (mnBytesPerRow != 0 && mnHeight &&
mnBytesPerRow <= std::numeric_limits<sal_uInt32>::max() / mnHeight)
{
try
{
size_t nToAllocate = mnBytesPerRow * mnHeight;
#if OSL_DEBUG_LEVEL > 0
nToAllocate += sizeof(CANARY);
#endif
mpUserBuffer = o3tl::make_shared_array<sal_uInt8>(nToAllocate);
#if OSL_DEBUG_LEVEL > 0
memcpy(mpUserBuffer.get() + nToAllocate - sizeof(CANARY),
CANARY, sizeof(CANARY));
#endif
alloc = true;
}
catch (const std::bad_alloc &) {}
}
if (!alloc)
{
SAL_WARN("vcl.opengl", "bad alloc " << mnBytesPerRow << "x" << mnHeight);
DeallocateUserData();
}
#ifdef DBG_UTIL
else
{
for (size_t i = 0; i < size_t(mnBytesPerRow * mnHeight); i++)
mpUserBuffer.get()[i] = (i & 0xFF);
}
#endif
return mpUserBuffer != nullptr;
}
void OpenGLSalBitmap::DeallocateUserData()
{
mpUserBuffer.reset();
mnBytesPerRow = 0;
}
namespace {
void lclInstantiateTexture(OpenGLTexture& rTexture, const int nWidth, const int nHeight,
const GLenum nFormat, const GLenum nType, sal_uInt8 const * pData)
{
if (nWidth == nHeight)
{
typedef std::vector<std::unique_ptr<FixedTextureAtlasManager>> TextureAtlasVector;
static vcl::DeleteOnDeinit<TextureAtlasVector> aTextureAtlases([]() {
TextureAtlasVector* p = new TextureAtlasVector;
p->reserve(5);
p->push_back(std::make_unique<FixedTextureAtlasManager>(8, 8, 16));
p->push_back(std::make_unique<FixedTextureAtlasManager>(8, 8, 24));
p->push_back(std::make_unique<FixedTextureAtlasManager>(8, 8, 32));
p->push_back(std::make_unique<FixedTextureAtlasManager>(8, 8, 48));
p->push_back(std::make_unique<FixedTextureAtlasManager>(8, 8, 64));
return p;
}());
for (std::unique_ptr<FixedTextureAtlasManager>& pTextureAtlas : *aTextureAtlases.get())
{
if (nWidth == pTextureAtlas->GetSubtextureSize())
{
rTexture = pTextureAtlas->InsertBuffer(nWidth, nHeight, nFormat, nType, pData);
return;
}
}
}
rTexture = OpenGLTexture (nWidth, nHeight, nFormat, nType, pData);
}
} // end anonymous namespace
Size OpenGLSalBitmap::GetSize() const
{
return Size(mnWidth, mnHeight);
}
GLuint OpenGLSalBitmap::CreateTexture()
{
VCL_GL_INFO( "::CreateTexture bits: " << mnBits);
GLenum nFormat = GL_RGBA;
GLenum nType = GL_UNSIGNED_BYTE;
sal_uInt8* pData( nullptr );
bool bAllocated( false );
if (mpUserBuffer != nullptr)
{
if( mnBits == 24 || mnBits == 32 )
{
// no conversion needed for truecolor
pData = mpUserBuffer.get();
determineTextureFormat(mnBits, nFormat, nType);
}
else if( mnBits == 8 && maPalette.IsGreyPalette8Bit() )
{
// no conversion needed for 8bit grayscale
pData = mpUserBuffer.get();
nFormat = GL_LUMINANCE;
nType = GL_UNSIGNED_BYTE;
}
else
{
VCL_GL_INFO( "::CreateTexture - convert from " << mnBits << " to 24 bits" );
// convert to 24 bits RGB using palette
determineTextureFormat(24, nFormat, nType);
pData = convertDataBitCount( mpUserBuffer.get(), mnWidth, mnHeight,
mnBits, mnBytesPerRow, maPalette,
nFormat == GL_BGR ? BitConvert::BGR : BitConvert::RGB ).release();
bAllocated = true;
}
}
OpenGLVCLContextZone aContextZone;
lclInstantiateTexture(maTexture, mnWidth, mnHeight, nFormat, nType, pData);
VCL_GL_INFO("Created texture " << maTexture.Id() << " bits: " << mnBits);
if( bAllocated )
delete[] pData;
mbDirtyTexture = false;
CHECK_GL_ERROR();
return maTexture.Id();
}
bool OpenGLSalBitmap::ReadTexture()
{
sal_uInt8* pData = mpUserBuffer.get();
GLenum nFormat = GL_RGBA;
GLenum nType = GL_UNSIGNED_BYTE;
VCL_GL_INFO( "::ReadTexture " << mnWidth << "x" << mnHeight << " bits: " << mnBits);
if( pData == nullptr )
return false;
OpenGLVCLContextZone aContextZone;
rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
xContext->state().scissor().disable();
xContext->state().stencil().disable();
if ((mnBits == 8 && maPalette.IsGreyPalette8Bit()) || mnBits == 24 || mnBits == 32)
{
determineTextureFormat(mnBits, nFormat, nType);
#if OSL_DEBUG_LEVEL > 0
// help valgrind & drmemory rescue us - touch last and first bits.
pData[0] = 0;
pData[mnBits/8*mnWidth*mnHeight-1] = 0;
// if this fails we can read too much into pData
assert(mnWidth == maTexture.GetWidth() &&
mnHeight == maTexture.GetHeight());
#endif
maTexture.Read(nFormat, nType, pData);
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
// If we read over the end of pData we have a real hidden memory
// corruption problem !
size_t nCanary = mnBytesPerRow * mnHeight;
assert(!memcmp(pData + nCanary, CANARY, sizeof (CANARY)));
#endif
return true;
}
else if (mnBits == 1 || mnBits == 4 || mnBits == 8)
{ // convert buffers from 24-bit RGB to 1,4 or 8-bit buffer
std::vector<sal_uInt8> aBuffer(mnWidth * mnHeight * 3);
sal_uInt8* pBuffer = aBuffer.data();
determineTextureFormat(24, nFormat, nType);
maTexture.Read(nFormat, nType, pBuffer);
sal_uInt32 nSourceBytesPerRow = lclBytesPerRow(24, mnWidth);
std::unique_ptr<vcl::ScanlineWriter> pWriter = vcl::ScanlineWriter::Create(mnBits, maPalette);
for (int y = 0; y < mnHeight; ++y)
{
sal_uInt8* pSource = &pBuffer[y * nSourceBytesPerRow];
sal_uInt8* pDestination = &pData[y * mnBytesPerRow];
pWriter->nextLine(pDestination);
for (int x = 0; x < mnWidth; ++x)
{
// read source
sal_uInt8 nR = *pSource++;
sal_uInt8 nG = *pSource++;
sal_uInt8 nB = *pSource++;
pWriter->writeRGB(nR, nG, nB);
}
}
return true;
}
SAL_WARN("vcl.opengl", "::ReadTexture - tx:" << maTexture.Id() << " @ "
<< mnWidth << "x" << mnHeight << "- unimplemented bit depth: "
<< mnBits);
return false;
}
sal_uInt16 OpenGLSalBitmap::GetBitCount() const
{
return mnBits;
}
bool OpenGLSalBitmap::calcChecksumGL(OpenGLTexture& rInputTexture, BitmapChecksum& rChecksum) const
{
OUString FragShader("areaHashCRC64TFragmentShader");
rtl::Reference< OpenGLContext > xContext = OpenGLContext::getVCLContext();
xContext->state().scissor().disable();
xContext->state().stencil().disable();
static vcl::DeleteOnDeinit<OpenGLTexture> gCRCTableTexture(
new OpenGLTexture(512, 1, GL_RGBA, GL_UNSIGNED_BYTE,
vcl_get_crc64_table()));
OpenGLTexture &rCRCTableTexture = *gCRCTableTexture.get();
// First Pass
int nWidth = rInputTexture.GetWidth();
int nHeight = rInputTexture.GetHeight();
OpenGLProgram* pProgram = xContext->UseProgram("textureVertexShader", FragShader);
if (pProgram == nullptr)
return false;
int nNewWidth = ceil( nWidth / 4.0 );
int nNewHeight = ceil( nHeight / 4.0 );
OpenGLTexture aFirstPassTexture(nNewWidth, nNewHeight);
OpenGLFramebuffer* pFramebuffer = xContext->AcquireFramebuffer(aFirstPassTexture);
pProgram->SetUniform1f( "xstep", 1.0 / mnWidth );
pProgram->SetUniform1f( "ystep", 1.0 / mnHeight );
pProgram->SetTexture("crc_table", rCRCTableTexture);
pProgram->SetTexture("sampler", rInputTexture);
pProgram->DrawTexture(rInputTexture);
pProgram->Clean();
OpenGLContext::ReleaseFramebuffer(pFramebuffer);
CHECK_GL_ERROR();
// Second Pass
nWidth = aFirstPassTexture.GetWidth();
nHeight = aFirstPassTexture.GetHeight();
pProgram = xContext->UseProgram("textureVertexShader", FragShader);
if (pProgram == nullptr)
return false;
nNewWidth = ceil( nWidth / 4.0 );
nNewHeight = ceil( nHeight / 4.0 );
OpenGLTexture aSecondPassTexture(nNewWidth, nNewHeight);
pFramebuffer = xContext->AcquireFramebuffer(aSecondPassTexture);
pProgram->SetUniform1f( "xstep", 1.0 / mnWidth );
pProgram->SetUniform1f( "ystep", 1.0 / mnHeight );
pProgram->SetTexture("crc_table", rCRCTableTexture);
pProgram->SetTexture("sampler", aFirstPassTexture);
pProgram->DrawTexture(aFirstPassTexture);
pProgram->Clean();
OpenGLContext::ReleaseFramebuffer(pFramebuffer);
CHECK_GL_ERROR();
// Final CRC on CPU
OpenGLTexture& aFinalTexture = aSecondPassTexture;
std::vector<sal_uInt8> aBuf( aFinalTexture.GetWidth() * aFinalTexture.GetHeight() * 4 );
aFinalTexture.Read(GL_RGBA, GL_UNSIGNED_BYTE, aBuf.data());
BitmapChecksum nCrc = vcl_get_checksum(0, aBuf.data(), aBuf.size());
rChecksum = nCrc;
return true;
}
void OpenGLSalBitmap::updateChecksum() const
{
if (mbChecksumValid)
return;
if( (mnWidth * mnHeight) < (1024*768) || mnWidth < 128 || mnHeight < 128 )
{
SalBitmap::updateChecksum();
return;
}
OpenGLSalBitmap* pThis = const_cast<OpenGLSalBitmap*>(this);
OpenGLVCLContextZone aContextZone;
OpenGLTexture& rInputTexture = GetTexture();
pThis->mbChecksumValid = calcChecksumGL(rInputTexture, pThis->mnChecksum);
if (!pThis->mbChecksumValid)
SalBitmap::updateChecksum();
}
BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( BitmapAccessMode nMode )
{
OpenGLVCLContextZone aContextZone;
if( nMode != BitmapAccessMode::Info )
{
if (!mpUserBuffer)
{
if( !AllocateUserData() )
return nullptr;
if( maTexture && !ReadTexture() )
{
DeallocateUserData();
return nullptr;
}
}
}
// mpUserBuffer must be unique when we are doing the write access
if (nMode == BitmapAccessMode::Write && mpUserBuffer && mpUserBuffer.use_count() > 1)
{
std::shared_ptr<sal_uInt8> aBuffer(mpUserBuffer);
mpUserBuffer.reset();
AllocateUserData();
memcpy(mpUserBuffer.get(), aBuffer.get(), mnBytesPerRow * mnHeight);
}
BitmapBuffer* pBuffer = new BitmapBuffer;
pBuffer->mnWidth = mnWidth;
pBuffer->mnHeight = mnHeight;
pBuffer->maPalette = maPalette;
pBuffer->mnScanlineSize = mnBytesPerRow;
pBuffer->mpBits = mpUserBuffer.get();
pBuffer->mnBitCount = mnBits;
switch (mnBits)
{
case 1:
pBuffer->mnFormat = ScanlineFormat::N1BitMsbPal;
break;
case 4:
pBuffer->mnFormat = ScanlineFormat::N4BitMsnPal;
break;
case 8:
pBuffer->mnFormat = ScanlineFormat::N8BitPal;
break;
case 24:
{
pBuffer->mnFormat = ScanlineFormat::N24BitTcRgb;
break;
}
case 32:
{
pBuffer->mnFormat = ScanlineFormat::N32BitTcRgba;
ColorMaskElement aRedMask(0xff000000);
aRedMask.CalcMaskShift();
ColorMaskElement aGreenMask(0x00ff0000);
aGreenMask.CalcMaskShift();
ColorMaskElement aBlueMask(0x0000ff00);
aBlueMask.CalcMaskShift();
pBuffer->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask);
break;
}
default: assert(false);
}
return pBuffer;
}
void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode )
{
OpenGLVCLContextZone aContextZone;
if( nMode == BitmapAccessMode::Write )
{
maTexture = OpenGLTexture();
mbDirtyTexture = true;
mbChecksumValid = false;
}
// The palette is modified on read during the BitmapWriteAccess,
// but of course, often it is not modified; interesting.
maPalette = pBuffer->maPalette;
// Are there any more ground movements underneath us ?
assert( pBuffer->mnWidth == mnWidth );
assert( pBuffer->mnHeight == mnHeight );
assert( pBuffer->mnBitCount == mnBits );
delete pBuffer;
}
bool OpenGLSalBitmap::GetSystemData( BitmapSystemData& /*rData*/ )
{
SAL_WARN( "vcl.opengl", "*** NOT IMPLEMENTED *** GetSystemData" );
#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 (!mpUserBuffer.get())
{
if( !AllocateUserData() || !ReadTexture() )
{
rBitmap.ReleaseBuffer( pBuffer, false );
DeallocateUserData();
return false;
}
}
// TODO Might be more efficient to add a static method to SalBitmap
// to get system data from a buffer
memcpy( pBuffer->mpBits, mpUserBuffer.get(), mnBytesPerRow * mnHeight );
rBitmap.ReleaseBuffer( pBuffer, false );
return rBitmap.GetSystemData( rData );
#else
return false;
#endif
}
bool OpenGLSalBitmap::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uInt8 nTol )
{
VCL_GL_INFO("::Replace");
OpenGLZone aZone;
rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
xContext->state().scissor().disable();
xContext->state().stencil().disable();
OpenGLFramebuffer* pFramebuffer;
OpenGLProgram* pProgram;
GetTexture();
pProgram = xContext->UseProgram( "textureVertexShader",
"replaceColorFragmentShader" );
if( !pProgram )
return false;
OpenGLTexture aNewTex( mnWidth, mnHeight );
pFramebuffer = xContext->AcquireFramebuffer( aNewTex );
pProgram->SetTexture( "sampler", maTexture );
pProgram->SetColor( "search_color", rSearchColor );
pProgram->SetColor( "replace_color", rReplaceColor );
pProgram->SetUniform1f( "epsilon", nTol / 255.0f );
pProgram->DrawTexture( maTexture );
pProgram->Clean();
OpenGLContext::ReleaseFramebuffer( pFramebuffer );
maTexture = aNewTex;
CHECK_GL_ERROR();
return true;
}
// Convert texture to greyscale and adjust bitmap metadata
bool OpenGLSalBitmap::ConvertToGreyscale()
{
VCL_GL_INFO("::ConvertToGreyscale");
// avoid re-converting to 8bits.
if ( mnBits == 8 && maPalette.IsGreyPalette8Bit())
return true;
OpenGLZone aZone;
rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
xContext->state().scissor().disable();
xContext->state().stencil().disable();
OpenGLFramebuffer* pFramebuffer;
OpenGLProgram* pProgram;
GetTexture();
pProgram = xContext->UseProgram("textureVertexShader", "greyscaleFragmentShader");
if (!pProgram)
return false;
OpenGLTexture aNewTex(mnWidth, mnHeight);
pFramebuffer = xContext->AcquireFramebuffer(aNewTex);
pProgram->SetTexture("sampler", maTexture);
pProgram->DrawTexture(maTexture);
pProgram->Clean();
OpenGLContext::ReleaseFramebuffer( pFramebuffer );
maTexture = aNewTex;
mnBits = 8;
maPalette = Bitmap::GetGreyPalette(256);
// AllocateUserData will handle the rest.
DeallocateUserData();
mbDirtyTexture = false;
CHECK_GL_ERROR();
return true;
}
// This is needed to just make the bitmap usable as an alpha channel.
// Converting to 8bit grey will do.
bool OpenGLSalBitmap::InterpretAs8Bit()
{
return ConvertToGreyscale();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-423
View File
@@ -1,423 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* 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 <sal/log.hxx>
#include <cmath>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <vcl/bitmap.hxx>
#include <opengl/zone.hxx>
#include <opengl/salbmp.hxx>
#include <opengl/program.hxx>
#include <opengl/texture.hxx>
#include <opengl/RenderState.hxx>
#include <ResampleKernel.hxx>
using vcl::Kernel;
using vcl::Lanczos3Kernel;
bool OpenGLSalBitmap::ImplScaleFilter(
const rtl::Reference< OpenGLContext > &xContext,
const double& rScaleX,
const double& rScaleY,
GLenum nFilter )
{
OpenGLFramebuffer* pFramebuffer;
OpenGLProgram* pProgram;
GLenum nOldFilter;
int nNewWidth( mnWidth * rScaleX );
int nNewHeight( mnHeight * rScaleY );
pProgram = xContext->UseProgram( "textureVertexShader",
"textureFragmentShader" );
if( !pProgram )
return false;
OpenGLTexture aNewTex(nNewWidth, nNewHeight);
pFramebuffer = xContext->AcquireFramebuffer( aNewTex );
pProgram->SetTexture( "sampler", maTexture );
nOldFilter = maTexture.GetFilter();
maTexture.SetFilter( nFilter );
pProgram->ApplyMatrix(mnWidth, mnHeight);
pProgram->DrawTexture( maTexture );
maTexture.SetFilter( nOldFilter );
pProgram->Clean();
OpenGLContext::ReleaseFramebuffer( pFramebuffer );
mnWidth = nNewWidth;
mnHeight = nNewHeight;
maTexture = aNewTex;
CHECK_GL_ERROR();
return true;
}
void OpenGLSalBitmap::ImplCreateKernel(
const double& fScale,
const Kernel& rKernel,
GLfloat*& pWeights,
sal_uInt32& aKernelSize )
{
const double fSamplingRadius(rKernel.GetWidth());
const double fScaledRadius((fScale < 1.0) ? fSamplingRadius / fScale : fSamplingRadius);
const double fFilterFactor(std::min(fScale, 1.0));
int aNumberOfContributions;
double aSum( 0 );
aNumberOfContributions = (static_cast< sal_uInt32 >(fabs(ceil(fScaledRadius))) * 2) + 1 - 6;
aKernelSize = aNumberOfContributions / 2 + 1;
// avoid a crash for now; re-think me.
if (aKernelSize > 16)
aKernelSize = 16;
pWeights = new GLfloat[16];
memset( pWeights, 0, 16 * sizeof( GLfloat ) );
for( sal_uInt32 i(0); i < aKernelSize; i++ )
{
const GLfloat aWeight( rKernel.Calculate( fFilterFactor * i ) );
if( fabs( aWeight ) >= 0.0001 )
{
pWeights[i] = aWeight;
aSum += i > 0 ? aWeight * 2 : aWeight;
}
}
for( sal_uInt32 i(0); i < aKernelSize; i++ )
{
pWeights[i] /= aSum;
}
}
bool OpenGLSalBitmap::ImplScaleConvolution(
const rtl::Reference< OpenGLContext > &xContext,
const double& rScaleX,
const double& rScaleY,
const Kernel& aKernel )
{
OpenGLFramebuffer* pFramebuffer;
OpenGLProgram* pProgram;
GLfloat* pWeights( nullptr );
sal_uInt32 nKernelSize;
GLfloat aOffsets[32];
int nNewWidth( mnWidth * rScaleX );
int nNewHeight( mnHeight * rScaleY );
// TODO Make sure the framebuffer is alright
pProgram = xContext->UseProgram( "textureVertexShader",
"convolutionFragmentShader" );
if( pProgram == nullptr )
return false;
// horizontal scaling in scratch texture
if( mnWidth != nNewWidth )
{
OpenGLTexture aScratchTex(nNewWidth, nNewHeight);
pFramebuffer = xContext->AcquireFramebuffer( aScratchTex );
for( sal_uInt32 i = 0; i < 16; i++ )
{
aOffsets[i * 2] = i / static_cast<double>(mnWidth);
aOffsets[i * 2 + 1] = 0;
}
ImplCreateKernel( rScaleX, aKernel, pWeights, nKernelSize );
pProgram->SetUniform1fv( "kernel", 16, pWeights );
pProgram->SetUniform2fv( "offsets", 16, aOffsets );
pProgram->SetTexture( "sampler", maTexture );
pProgram->DrawTexture( maTexture );
pProgram->Clean();
maTexture = aScratchTex;
OpenGLContext::ReleaseFramebuffer( pFramebuffer );
}
// vertical scaling in final texture
if( mnHeight != nNewHeight )
{
OpenGLTexture aScratchTex(nNewWidth, nNewHeight);
pFramebuffer = xContext->AcquireFramebuffer( aScratchTex );
for( sal_uInt32 i = 0; i < 16; i++ )
{
aOffsets[i * 2] = 0;
aOffsets[i * 2 + 1] = i / static_cast<double>(mnHeight);
}
ImplCreateKernel( rScaleY, aKernel, pWeights, nKernelSize );
pProgram->SetUniform1fv( "kernel", 16, pWeights );
pProgram->SetUniform2fv( "offsets", 16, aOffsets );
pProgram->SetTexture( "sampler", maTexture );
pProgram->DrawTexture( maTexture );
pProgram->Clean();
maTexture = aScratchTex;
OpenGLContext::ReleaseFramebuffer( pFramebuffer );
}
mnWidth = nNewWidth;
mnHeight = nNewHeight;
CHECK_GL_ERROR();
return true;
}
/*
"Area" scaling algorithm, which seems to give better results for downscaling
than other algorithms. The principle (taken from opencv, see resize.cl)
is that each resulting pixel is the average of all the source pixel values
it represents. Which is trivial in the case of exact multiples for downscaling,
the generic case needs to also consider that some source pixels contribute
only partially to their resulting pixels (because of non-integer multiples).
*/
bool OpenGLSalBitmap::ImplScaleArea( const rtl::Reference< OpenGLContext > &xContext,
double rScaleX, double rScaleY )
{
int nNewWidth( mnWidth * rScaleX );
int nNewHeight( mnHeight * rScaleY );
if( nNewWidth == mnWidth && nNewHeight == mnHeight )
return true;
double ixscale = 1 / rScaleX;
double iyscale = 1 / rScaleY;
bool fast = ( ixscale == std::trunc( ixscale ) && iyscale == std::trunc( iyscale )
&& int( nNewWidth * ixscale ) == mnWidth && int( nNewHeight * iyscale ) == mnHeight );
bool bTwoPasses = false;
// The generic case has arrays only up to 100 ratio downscaling, which is hopefully enough
// in practice, but protect against buffer overflows in case such an extreme case happens
// (and in such case the precision of the generic algorithm probably doesn't matter anyway).
if( ixscale > 100 || iyscale > 100 )
{
fast = true;
}
else
{
if (ixscale > 16 || iyscale > 16)
{
ixscale = std::floor(std::sqrt(ixscale));
iyscale = std::floor(std::sqrt(iyscale));
nNewWidth = int(mnWidth / ixscale);
rScaleX *= ixscale; // second pass x-scale factor
nNewHeight = int(mnHeight / iyscale);
rScaleY *= iyscale; // second pass y-scale factor
bTwoPasses = true;
}
}
// TODO Make sure the framebuffer is alright
OString sUseReducedRegisterVariantDefine;
if (xContext->getOpenGLCapabilitySwitch().mbLimitedShaderRegisters)
sUseReducedRegisterVariantDefine = OString("#define USE_REDUCED_REGISTER_VARIANT\n");
OpenGLProgram* pProgram = xContext->UseProgram( "textureVertexShader",
fast ? OUString( "areaScaleFastFragmentShader" ) : OUString( "areaScaleFragmentShader" ),
sUseReducedRegisterVariantDefine);
if( pProgram == nullptr )
return false;
OpenGLTexture aScratchTex(nNewWidth, nNewHeight);
OpenGLFramebuffer* pFramebuffer = xContext->AcquireFramebuffer( aScratchTex );
// NOTE: This setup is also done in OpenGLSalGraphicsImpl::DrawTransformedTexture().
if( fast )
{
pProgram->SetUniform1i( "xscale", ixscale );
pProgram->SetUniform1i( "yscale", iyscale );
// The shader operates on pixels in the surrounding area, so it's necessary
// to know the step in texture coordinates to get to the next pixel.
// With a texture atlas the "texture" is just a subtexture of a larger texture,
// so while with a normal texture we'd map between <0.0,1.0> and <0,mnWidth>,
// with a subtexture the texture coordinates range is smaller.
GLfloat srcCoords[ 8 ];
maTexture.GetWholeCoord( srcCoords );
pProgram->SetUniform1f( "xstep", ( srcCoords[ 4 ] - srcCoords[ 0 ] ) / mnWidth );
pProgram->SetUniform1f( "ystep", ( srcCoords[ 5 ] - srcCoords[ 1 ] ) / mnHeight );
pProgram->SetUniform1f( "ratio", 1.0 / ( ixscale * iyscale ));
}
else
{
pProgram->SetUniform1f( "xscale", ixscale );
pProgram->SetUniform1f( "yscale", iyscale );
pProgram->SetUniform1i( "swidth", mnWidth );
pProgram->SetUniform1i( "sheight", mnHeight );
// The shader internally actually operates on pixel coordinates,
// so it needs to know how to convert to those from the texture coordinates.
// With a simple texture that would mean converting e.g. between
// <0,mnWidth-1> and <0.0,1.0> coordinates.
// However with a texture atlas the "texture" is just a subtexture
// of a larger texture, so the texture coordinates need offset and ratio
// conversion too.
GLfloat srcCoords[ 8 ];
maTexture.GetWholeCoord( srcCoords );
pProgram->SetUniform1f( "xoffset", srcCoords[ 0 ] );
pProgram->SetUniform1f( "yoffset", srcCoords[ 1 ] );
pProgram->SetUniform1f( "xtopixelratio", nNewWidth / ( srcCoords[ 4 ] - srcCoords[ 0 ] ));
pProgram->SetUniform1f( "ytopixelratio", nNewHeight / ( srcCoords[ 5 ] - srcCoords[ 1 ] ));
pProgram->SetUniform1f( "xfrompixelratio", ( srcCoords[ 4 ] - srcCoords[ 0 ] ) / mnWidth );
pProgram->SetUniform1f( "yfrompixelratio", ( srcCoords[ 5 ] - srcCoords[ 1 ] ) / mnHeight );
}
pProgram->SetTexture( "sampler", maTexture );
pProgram->DrawTexture( maTexture );
pProgram->Clean();
OpenGLContext::ReleaseFramebuffer(pFramebuffer);
CHECK_GL_ERROR();
if (bTwoPasses)
{
mnWidth = nNewWidth;
mnHeight = nNewHeight;
nNewWidth = round(mnWidth * rScaleX);
nNewHeight = round(mnHeight * rScaleY);
ixscale = 1 / rScaleX;
iyscale = 1 / rScaleY;
pProgram = xContext->UseProgram("textureVertexShader", "areaScaleFragmentShader", sUseReducedRegisterVariantDefine);
if (pProgram == nullptr)
return false;
OpenGLTexture aScratchTex2(nNewWidth, nNewHeight);
pFramebuffer = xContext->AcquireFramebuffer(aScratchTex2);
pProgram->SetUniform1f("xscale", ixscale);
pProgram->SetUniform1f("yscale", iyscale);
pProgram->SetUniform1i("swidth", mnWidth);
pProgram->SetUniform1i("sheight", mnHeight);
GLfloat srcCoords[ 8 ];
aScratchTex.GetWholeCoord( srcCoords );
pProgram->SetUniform1f( "xoffset", srcCoords[ 0 ] );
pProgram->SetUniform1f( "yoffset", srcCoords[ 1 ] );
pProgram->SetUniform1f( "xtopixelratio", nNewWidth / ( srcCoords[ 4 ] - srcCoords[ 0 ] ));
pProgram->SetUniform1f( "ytopixelratio", nNewHeight / ( srcCoords[ 5 ] - srcCoords[ 1 ] ));
pProgram->SetUniform1f( "xfrompixelratio", ( srcCoords[ 4 ] - srcCoords[ 0 ] ) / mnWidth );
pProgram->SetUniform1f( "yfrompixelratio", ( srcCoords[ 5 ] - srcCoords[ 1 ] ) / mnHeight );
pProgram->SetTexture("sampler", aScratchTex);
pProgram->DrawTexture(aScratchTex);
pProgram->Clean();
OpenGLContext::ReleaseFramebuffer(pFramebuffer);
CHECK_GL_ERROR();
maTexture = aScratchTex2;
mnWidth = nNewWidth;
mnHeight = nNewHeight;
}
else
{
maTexture = aScratchTex;
mnWidth = nNewWidth;
mnHeight = nNewHeight;
}
return true;
}
void OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag )
{
VCL_GL_INFO( "::ImplScale" );
mpUserBuffer.reset();
OpenGLVCLContextZone aContextZone;
rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
xContext->state().scissor().disable();
xContext->state().stencil().disable();
if (rScaleX <= 1 && rScaleY <= 1)
{
nScaleFlag = BmpScaleFlag::BestQuality;
}
if( nScaleFlag == BmpScaleFlag::Fast )
{
ImplScaleFilter( xContext, rScaleX, rScaleY, GL_NEAREST );
}
else if( nScaleFlag == BmpScaleFlag::BiLinear )
{
ImplScaleFilter( xContext, rScaleX, rScaleY, GL_LINEAR );
}
else if( nScaleFlag == BmpScaleFlag::Default )
{
const Lanczos3Kernel aKernel;
ImplScaleConvolution( xContext, rScaleX, rScaleY, aKernel );
}
else if( nScaleFlag == BmpScaleFlag::BestQuality && rScaleX <= 1 && rScaleY <= 1 )
{ // Use area scaling for best quality, but only if downscaling.
ImplScaleArea( xContext, rScaleX, rScaleY );
}
else if( nScaleFlag == BmpScaleFlag::Lanczos || nScaleFlag == BmpScaleFlag::BestQuality )
{
const Lanczos3Kernel aKernel;
ImplScaleConvolution( xContext, rScaleX, rScaleY, aKernel );
}
else
SAL_WARN( "vcl.opengl", "Invalid flag for scaling operation" );
}
bool OpenGLSalBitmap::ScalingSupported() const
{
return true;
}
bool OpenGLSalBitmap::Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag )
{
OpenGLVCLContextZone aContextZone;
VCL_GL_INFO("::Scale " << int(nScaleFlag)
<< " from " << mnWidth << "x" << mnHeight
<< " to " << (mnWidth * rScaleX) << "x" << (mnHeight * rScaleY) );
if( nScaleFlag == BmpScaleFlag::Fast ||
nScaleFlag == BmpScaleFlag::BiLinear ||
nScaleFlag == BmpScaleFlag::Lanczos ||
nScaleFlag == BmpScaleFlag::Default ||
nScaleFlag == BmpScaleFlag::BestQuality )
{
ImplScale( rScaleX, rScaleY, nScaleFlag );
return true;
}
return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,87 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* TODO Use textureOffset for newest version of GLSL */
#version 130
uniform sampler2D crc_table;
uniform sampler2D sampler;
uniform float xstep;
uniform float ystep;
varying vec2 tex_coord;
const int scale = 4;
const float ratio = 16.0;
ivec2 crc64( ivec2 hval, int color )
{
int dx = 2 * ((hval[0] ^ color) & 0xff);
float s = dx / 255.0;
vec4 table_value_lo = round(texture2D( crc_table, vec2( s, 0.0 ) ) * 255.0);
s = (dx+1) / 255.0;
vec4 table_value_hi = round(texture2D( crc_table, vec2( s, 0.0 ) ) * 255.0);
int tvalue_lo = int(table_value_lo[0]) | (int(table_value_lo[1]) << 8) | (int(table_value_lo[2]) << 16) | (int(table_value_lo[3]) << 24);
int tvalue_hi = int(table_value_hi[0]) | (int(table_value_hi[1]) << 8) | (int(table_value_hi[2]) << 16) | (int(table_value_hi[3]) << 24);
hval[1] = tvalue_hi ^ (hval[1] >> 8);
hval[0] = tvalue_lo ^ ( (hval[1] << 24) | (hval[0] >> 8) );
return hval;
}
void main(void)
{
ivec2 Crc = ivec2( 0xffffffff, 0xffffffff );
vec2 offset = vec2( 0.0, 0.0 );
vec2 next_coord = tex_coord.st;
for( int y = 0; y < scale && next_coord.y <= 1.0; ++y )
{
for( int x = 0; x < scale && next_coord.x <= 1.0; ++x )
{
vec4 pixel = round(texture2D( sampler, next_coord ) * 255.0);
int r = int(pixel.r); // 0..255
int g = int(pixel.g); // 0..255
int b = int(pixel.b); // 0..255
int a = int(pixel.a); // 0..255
Crc = crc64( Crc, r );
Crc = crc64( Crc, g );
Crc = crc64( Crc, b );
Crc = crc64( Crc, a );
offset.x += xstep;
next_coord = tex_coord.st + offset;
}
offset.y += ystep;
offset.x = 0.0;
next_coord = tex_coord.st + offset;
}
Crc[0] = ~Crc[0];
Crc[1] = ~Crc[1];
int Hash = Crc[0] ^ Crc[1];
float fr = ( Hash & 0xff) / 255.0;
float fg = ((Hash >> 8) & 0xff) / 255.0;
float fb = ((Hash >> 16) & 0xff) / 255.0;
float fa = ((Hash >> 24) & 0xff) / 255.0;
gl_FragColor = vec4(fr, fg, fb, fa);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* TODO Use textureOffset for newest version of GLSL */
#version 130
uniform sampler2D sampler;
uniform int xscale;
uniform int yscale;
uniform float xstep;
uniform float ystep;
uniform float ratio; // = 1.0/(xscale*yscale)
varying vec2 tex_coord;
// This mode makes the scaling work like maskedTextureFragmentShader.glsl
// (instead of like plain textureVertexShader.glsl).
#ifdef MASKED
varying vec2 mask_coord;
uniform sampler2D mask;
#endif
/*
Just make the resulting color the average of all the source pixels
(which is an area (xscale)x(yscale) ).
*/
void main(void)
{
vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
vec2 offset = vec2( 0.0, 0.0 );
for( int y = 0; y < yscale; ++y )
{
for( int x = 0; x < xscale; ++x )
{
#ifndef MASKED
sum += texture2D( sampler, tex_coord.st + offset );
#else
vec4 texel;
texel = texture2D( sampler, tex_coord.st + offset );
texel.a = 1.0 - texture2D( mask, mask_coord.st + offset ).r;
sum += texel;
#endif
offset.x += xstep;
}
offset.y += ystep;
offset.x = 0.0;
}
sum *= ratio;
gl_FragColor = sum;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,239 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
uniform sampler2D sampler;
uniform int swidth;
uniform int sheight;
uniform float xscale;
uniform float yscale;
uniform float xoffset;
uniform float yoffset;
uniform float xfrompixelratio;
uniform float yfrompixelratio;
uniform float xtopixelratio;
uniform float ytopixelratio;
varying vec2 tex_coord;
// This mode makes the scaling work like maskedTextureFragmentShader.glsl
// (instead of like plain textureVertexShader.glsl).
#ifdef MASKED
varying vec2 mask_coord;
uniform sampler2D mask;
#endif
#ifdef USE_REDUCED_REGISTER_VARIANT
vec4 getTexel(int x, int y)
{
vec2 pos = vec2( x * xfrompixelratio + xoffset, y * yfrompixelratio + yoffset );
vec4 texel = texture2D(sampler, pos);
#ifdef MASKED
texel.a = 1.0 - texture2D(mask, pos - tex_coord.st + mask_coord.st).r;
#endif
return texel;
}
void main(void)
{
// Convert to pixel coordinates again.
int dx = int(( tex_coord.s - xoffset ) * xtopixelratio );
int dy = int(( tex_coord.t - yoffset ) * ytopixelratio );
// Compute the range of source pixels which will make up this destination pixel.
float fsx1 = min(dx * xscale, float(swidth - 1));
float fsx2 = min(fsx1 + xscale, float(swidth - 1));
float fsy1 = min(dy * yscale, float(sheight - 1));
float fsy2 = min(fsy1 + yscale, float(sheight - 1));
// To whole pixel coordinates.
int xstart = int(floor(fsx1));
int xend = int(floor(fsx2));
int ystart = int(floor(fsy1));
int yend = int(floor(fsy2));
float xlength = fsx2 - fsx1;
float ylength = fsy2 - fsy1;
float xContribution[3];
xContribution[0] = (1.0 - max(0.0, fsx1 - xstart)) / xlength;
xContribution[1] = 1.0 / xlength;
xContribution[2] = (1.0 - max(0.0, (xend + 1) - fsx2)) / xlength;
float yContribution[3];
yContribution[0] = (1.0 - max(0.0, fsy1 - ystart)) / ylength;
yContribution[1] = 1.0 / ylength;
yContribution[2] = (1.0 - max(0.0, (yend + 1) - fsy2)) / ylength;
vec4 sumAll = vec4(0.0, 0.0, 0.0, 0.0);
vec4 texel;
// First Y pass
{
vec4 sumX = vec4(0.0, 0.0, 0.0, 0.0);
sumX += getTexel(xstart, ystart) * xContribution[0];
for (int x = xstart + 1; x < xend; ++x)
{
sumX += getTexel(x, ystart) * xContribution[1];
}
sumX += getTexel(xend, ystart) * xContribution[2];
sumAll += sumX * yContribution[0];
}
// Middle Y Passes
for (int y = ystart + 1; y < yend; ++y)
{
vec4 sumX = vec4(0.0, 0.0, 0.0, 0.0);
sumX += getTexel(xstart, y) * xContribution[0];
for (int x = xstart + 1; x < xend; ++x)
{
sumX += getTexel(x, y) * xContribution[1];
}
sumX += getTexel(xend, y) * xContribution[2];
sumAll += sumX * yContribution[1];
}
// Last Y pass
{
vec4 sumX = vec4(0.0, 0.0, 0.0, 0.0);
sumX += getTexel(xstart, yend) * xContribution[0];
for (int x = xstart + 1; x < xend; ++x)
{
sumX += getTexel(x, yend) * xContribution[1];
}
sumX += getTexel(xend, yend) * xContribution[2];
sumAll += sumX * yContribution[2];
}
gl_FragColor = sumAll;
}
#else
void main(void)
{
// Convert to pixel coordinates again.
int dx = int(( tex_coord.s - xoffset ) * xtopixelratio );
int dy = int(( tex_coord.t - yoffset ) * ytopixelratio );
// How much each column/row will contribute to the resulting pixel.
// Note: These values are always the same for the same X (or Y),
// so they could be precalculated in C++ and passed to the shader,
// but GLSL has limits on the size of uniforms passed to it,
// so it'd need something like texture buffer objects from newer
// GLSL versions, and it seems the hassle is not really worth it.
float xratio[ 16 + 2 ];
float yratio[ 16 + 2 ];
// For finding the first and last source pixel.
int xpixel[ 16 + 2 ];
int ypixel[ 16 + 2 ];
int xpos = 0;
int ypos = 0;
// Compute the range of source pixels which will make up this destination pixel.
float fsx1 = dx * xscale;
float fsx2 = fsx1 + xscale;
// To whole pixel coordinates.
int sx1 = int( ceil( fsx1 ) );
int sx2 = int( floor( fsx2 ) );
// Range checking.
sx2 = min( sx2, swidth - 1 );
sx1 = min( sx1, sx2 );
// How much one full column contributes to the resulting pixel.
float width = min( xscale, swidth - fsx1 );
if( sx1 - fsx1 > 0.001 )
{ // The first column contributes only partially.
xpixel[ xpos ] = sx1 - 1;
xratio[ xpos ] = ( sx1 - fsx1 ) / width;
++xpos;
}
for( int sx = sx1; sx < sx2; ++sx )
{ // Columns that fully contribute to the resulting pixel.
xpixel[ xpos ] = sx;
xratio[ xpos ] = 1.0 / width;
++xpos;
}
if( fsx2 - sx2 > 0.001 )
{ // The last column contributes only partially.
xpixel[ xpos ] = sx2;
xratio[ xpos ] = min( min( fsx2 - sx2, 1.0 ) / width, 1.0 );
++xpos;
}
// The same for Y.
float fsy1 = dy * yscale;
float fsy2 = fsy1 + yscale;
int sy1 = int( ceil( fsy1 ) );
int sy2 = int( floor( fsy2 ) );
sy2 = min( sy2, sheight - 1 );
sy1 = min( sy1, sy2 );
float height = min( yscale, sheight - fsy1 );
if( sy1 - fsy1 > 0.001 )
{
ypixel[ ypos ] = sy1 - 1;
yratio[ ypos ] = ( sy1 - fsy1 ) / height;
++ypos;
}
for( int sy = sy1; sy < sy2; ++sy )
{
ypixel[ ypos ] = sy;
yratio[ ypos ] = 1.0 / height;
++ypos;
}
if( fsy2 - sy2 > 0.001 )
{
ypixel[ ypos ] = sy2;
yratio[ ypos ] = min( min( fsy2 - sy2, 1.0 ) / height, 1.0 );
++ypos;
}
int xstart = xpixel[ 0 ];
int xend = xpixel[ xpos - 1 ];
int ystart = ypixel[ 0 ];
int yend = ypixel[ ypos - 1 ];
vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
ypos = 0;
for( int y = ystart; y <= yend; ++y, ++ypos )
{
vec4 tmp = vec4( 0.0, 0.0, 0.0, 0.0 );
xpos = 0;
for( int x = xstart; x <= xend; ++x, ++xpos )
{
vec2 pos = vec2( x * xfrompixelratio + xoffset, y * yfrompixelratio + yoffset );
#ifndef MASKED
tmp += texture2D( sampler, pos ) * xratio[ xpos ];
#else
vec4 texel;
texel = texture2D( sampler, pos );
texel.a = 1.0 - texture2D( mask, pos - tex_coord.st + mask_coord.st ).r;
tmp += texel * xratio[ xpos ];
#endif
}
sum += tmp * yratio[ ypos ];
}
gl_FragColor = sum;
}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,33 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
varying vec2 tex_coord;
varying vec2 alpha_coord;
varying vec2 mask_coord;
uniform sampler2D sampler;
uniform sampler2D mask;
uniform sampler2D alpha;
void main()
{
vec4 texel0, texel1, texel2;
texel0 = texture2D(sampler, tex_coord);
texel1 = texture2D(mask, mask_coord);
texel2 = texture2D(alpha, alpha_coord);
gl_FragColor = texel0;
/* Only blend if the alpha texture wasn't fully transparent */
gl_FragColor.a = 1.0 - (1.0 - floor(texel2.r)) * texel1.r;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,28 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
attribute vec4 position;
attribute vec2 tex_coord_in;
attribute vec2 alpha_coord_in;
attribute vec2 mask_coord_in;
varying vec2 tex_coord;
varying vec2 alpha_coord;
varying vec2 mask_coord;
uniform mat4 mvp;
void main() {
gl_Position = mvp * position;
tex_coord = tex_coord_in;
alpha_coord = alpha_coord_in;
mask_coord = mask_coord_in;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
varying float fade_factor; // 0->1 fade factor used for AA
varying float multiply;
#ifdef USE_VERTEX_COLORS
varying vec4 vertex_color;
#endif
uniform vec4 color;
#define TYPE_NORMAL 0
#define TYPE_LINE 1
uniform int type;
void main()
{
#ifdef USE_VERTEX_COLORS
vec4 result = vertex_color;
#else
vec4 result = color;
#endif
if (type == TYPE_LINE)
{
float dist = (1.0 - abs(fade_factor)) * multiply;
float alpha = clamp(dist, 0.0, 1.0);
result.a = result.a * alpha;
}
gl_FragColor = result;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,73 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
varying vec2 tex_coord;
varying vec2 alpha_coord;
varying vec2 mask_coord;
#ifdef USE_VERTEX_COLORS
varying vec4 vertex_color;
#endif
uniform sampler2D texture;
uniform sampler2D mask;
uniform sampler2D alpha;
uniform vec4 color;
uniform int type;
#define TYPE_NORMAL 0
#define TYPE_BLEND 1
#define TYPE_MASKED 2
#define TYPE_DIFF 3
#define TYPE_MASKED_COLOR 4
void main()
{
vec4 texelTexture = texture2D(texture, tex_coord);
if (type == TYPE_NORMAL)
{
gl_FragColor = texelTexture;
}
else if (type == TYPE_BLEND)
{
vec4 texelMask = texture2D(mask, mask_coord);
vec4 texelAlpha = texture2D(alpha, alpha_coord);
gl_FragColor = texelTexture;
gl_FragColor.a = 1.0 - (1.0 - floor(texelAlpha.r)) * texelMask.r;
}
else if (type == TYPE_MASKED)
{
vec4 texelMask = texture2D(mask, mask_coord);
gl_FragColor = texelTexture;
gl_FragColor.a = 1.0 - texelMask.r;
}
else if (type == TYPE_DIFF)
{
vec4 texelMask = texture2D(mask, mask_coord);
float alpha = 1.0 - abs(texelTexture.r - texelMask.r);
if (alpha > 0.0)
gl_FragColor = texelMask / alpha;
gl_FragColor.a = alpha;
}
else if (type == TYPE_MASKED_COLOR)
{
#ifdef USE_VERTEX_COLORS
gl_FragColor = vertex_color;
#else
gl_FragColor = color;
#endif
gl_FragColor.a = 1.0 - texelTexture.r;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
attribute vec4 position;
attribute vec2 tex_coord_in;
attribute vec2 mask_coord_in;
attribute vec2 alpha_coord_in;
#ifdef USE_VERTEX_COLORS
attribute vec4 vertex_color_in;
#endif
varying vec2 tex_coord;
varying vec2 mask_coord;
varying vec2 alpha_coord;
#ifdef USE_VERTEX_COLORS
varying vec4 vertex_color;
#endif
uniform mat4 mvp;
uniform mat4 transform;
uniform int type;
void main()
{
gl_Position = mvp * transform * position;
tex_coord = tex_coord_in;
mask_coord = mask_coord_in;
alpha_coord = alpha_coord_in;
#ifdef USE_VERTEX_COLORS
vertex_color = vertex_color_in / 255.0;
#endif
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,76 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
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
varying float multiply;
#ifdef USE_VERTEX_COLORS
varying vec4 vertex_color;
#endif
uniform float line_width;
uniform float feather; // width where we fade the line
uniform mat4 mvp;
#define TYPE_NORMAL 0
#define TYPE_LINE 1
uniform int type;
void main()
{
vec2 extrusion_vector = extrusion_vectors.xy;
float render_thickness = 0.0;
if (type == TYPE_LINE)
{
// miter factor to additionally lengthen the distance of vertex (needed for miter)
// if 1.0 - miter_factor has no effect
float miter_factor = 1.0 / abs(extrusion_vectors.z);
// fade factor is always -1.0 or 1.0 -> we transport that info together with length
fade_factor = sign(extrusion_vectors.z);
#ifdef USE_VERTEX_COLORS
float the_feather = (1.0 + sign(extrusion_vectors.w)) / 4.0;
float the_line_width = abs(extrusion_vectors.w);
#else
float the_feather = feather;
float the_line_width = line_width;
#endif
render_thickness = (the_line_width * miter_factor + the_feather * 2.0 * miter_factor);
// Calculate the multiplier so we can transform the 0->1 fade factor
// to take feather and line width into account.
float start = mix(0.0, (the_line_width / 2.0) - the_feather, the_feather * 2.0);
float end = mix(1.0, (the_line_width / 2.0) + the_feather, the_feather * 2.0);
multiply = 1.0 / (1.0 - (start / end));
}
// lengthen the vertex in direction of the extrusion vector by line width.
vec4 final_position = vec4(position + (extrusion_vector * (render_thickness / 2.0) ), 0.0, 1.0);
gl_Position = mvp * final_position;
#ifdef USE_VERTEX_COLORS
vertex_color = vertex_color_in / 255.0;
#endif
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,30 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* TODO Use textureOffset for newest version of GLSL */
#version 130
uniform sampler2D sampler;
uniform vec2 offsets[16];
uniform float kernel[16];
varying vec2 tex_coord;
void main(void)
{
vec4 sum = texture2D(sampler, tex_coord.st) * kernel[0];
for (int i = 1; i < 16; i++) {
sum += texture2D(sampler, tex_coord.st - offsets[i]) * kernel[i];
sum += texture2D(sampler, tex_coord.st + offsets[i]) * kernel[i];
}
gl_FragColor = sum;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,30 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
/*precision mediump float;*/
varying vec2 tex_coord;
varying vec2 mask_coord;
uniform sampler2D texture; /* white background */
uniform sampler2D mask; /* black background */
void main()
{
float alpha;
vec4 texel0, texel1;
texel0 = texture2D(texture, tex_coord);
texel1 = texture2D(mask, mask_coord);
alpha = 1.0 - abs(texel0.r - texel1.r);
if(alpha > 0.0)
gl_FragColor = texel1 / alpha;
gl_FragColor.a = alpha;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-20
View File
@@ -1,20 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
attribute vec4 position;
uniform mat4 mvp;
void main() {
gl_Position = mvp * position;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,20 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
varying vec2 tex_coord;
uniform sampler2D sampler;
void main() {
vec4 texel = texture2D(sampler, tex_coord);
gl_FragColor = vec4(vec3(dot(texel.rgb, vec3(0.301, 0.591, 0.108))), 1.0);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,25 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
/*precision mediump float;*/
void main() {
vec2 tex_mod = mod(gl_FragCoord, 2).xy;
bool bLeft = (tex_mod.x > 0.0) && (tex_mod.x < 1.0);
bool bTop = (tex_mod.y > 0.0) && (tex_mod.y < 1.0);
// horrors - where is the XOR operator ?
if ((bTop && bLeft) || (!bTop && !bLeft))
gl_FragColor = vec4(255,255,255,0);
else
gl_FragColor = vec4(0,0,0,0);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
varying float fade_factor; // 0->1 fade factor used for AA
uniform vec4 color;
uniform float line_width;
uniform float feather;
void main()
{
float start = (line_width / 2.0) - feather; // where we start to apply alpha
float end = (line_width / 2.0) + feather; // where we end to apply alpha
// Calculate the multiplier so we can transform the 0->1 fade factor
// to take feather and line width into account.
float multiplied = 1.0 / (1.0 - (start / end));
float dist = (1.0 - abs(fade_factor)) * multiplied;
float alpha = clamp(dist, 0.0, 1.0);
// modify the alpha channel only
vec4 result_color = color;
result_color.a = result_color.a * alpha;
gl_FragColor = result_color;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-37
View File
@@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
attribute vec2 position;
attribute vec4 extrusion_vectors;
varying float fade_factor; // fade factor for anti-aliasing
uniform float line_width;
uniform float feather; // width where we fade the line
uniform mat4 mvp;
void main()
{
vec2 extrusion_vector = extrusion_vectors.xy;
// miter factor to additionally lengthen the distance of vertex (needed for miter)
// if 1.0 - miter_factor has no effect
float miter_factor = 1.0f / abs(extrusion_vectors.z);
// fade factor is always -1.0 or 1.0 -> we transport that info together with length
fade_factor = sign(extrusion_vectors.z);
float rendered_thickness = (line_width + feather * 2.0) * miter_factor;
// lengthen the vertex in direction of the extrusion vector by line width.
vec4 position = vec4(position + (extrusion_vector * (rendered_thickness / 2.0) ), 0.0, 1.0);
gl_Position = mvp * position;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,23 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 120
uniform vec4 start_color;
uniform vec4 end_color;
uniform mat3x3 transform;
varying vec2 tex_coord;
void main(void)
{
gl_FragColor = mix(end_color, start_color,
clamp(tex_coord.t, 0.0, 1.0));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,23 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
varying vec2 tex_coord;
uniform sampler2D sampler;
uniform vec4 color;
void main() {
vec4 texel0;
texel0 = texture2D(sampler, tex_coord);
gl_FragColor = color;
gl_FragColor.a = 1.0 - texel0.r;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
/*precision mediump float;*/
varying vec2 tex_coord;
varying vec2 mask_coord;
uniform sampler2D sampler;
uniform sampler2D mask;
void main()
{
vec4 texel0, texel1;
texel0 = texture2D(sampler, tex_coord);
texel1 = texture2D(mask, mask_coord);
gl_FragColor = texel0;
gl_FragColor.a = 1.0 - texel1.r;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,26 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
attribute vec4 position;
attribute vec2 tex_coord_in;
attribute vec2 mask_coord_in;
varying vec2 tex_coord;
varying vec2 mask_coord;
uniform mat4 mvp;
void main()
{
gl_Position = mvp * position;
tex_coord = tex_coord_in;
mask_coord = mask_coord_in;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,23 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 120
uniform vec4 start_color;
uniform vec4 end_color;
uniform vec2 center;
varying vec2 tex_coord;
void main(void)
{
gl_FragColor = mix(end_color, start_color,
clamp(distance(tex_coord, center), 0.0, 1.0));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,25 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
varying vec2 tex_coord;
uniform sampler2D sampler;
uniform vec4 search_color;
uniform vec4 replace_color;
uniform float epsilon;
void main() {
vec4 texel = texture2D(sampler, tex_coord);
vec4 diff = clamp(abs(texel - search_color) - epsilon, 0.0, 1.0);
float bump = max(0.0, 1.0 - ceil(diff.x + diff.y + diff.z));
gl_FragColor = texel + bump * (replace_color - search_color);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,19 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
/*precision mediump float;*/
uniform vec4 color;
void main() {
gl_FragColor = color;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,20 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
/* 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: */
@@ -1,22 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
attribute vec4 position;
attribute vec2 tex_coord_in;
varying vec2 tex_coord;
uniform mat4 mvp;
void main() {
gl_Position = mvp * position;
tex_coord = tex_coord_in;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@@ -1,28 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#version 130
attribute vec4 position;
attribute vec2 tex_coord_in;
attribute vec2 mask_coord_in;
uniform vec2 viewport;
uniform mat4 transform;
uniform mat4 mvp;
varying vec2 tex_coord;
varying vec2 mask_coord;
void main() {
vec4 pos = mvp * transform * position;
gl_Position = pos;
tex_coord = tex_coord_in;
mask_coord = mask_coord_in;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-606
View File
@@ -1,606 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* 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 <sal/log.hxx>
#include <tools/stream.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <svdata.hxx>
#include <vcl/pngwrite.hxx>
#include <opengl/framebuffer.hxx>
#include <opengl/texture.hxx>
#include <opengl/zone.hxx>
#include <opengl/RenderState.hxx>
namespace
{
constexpr GLenum constInternalFormat = GL_RGBA8;
} // end anonymous namespace
// texture with allocated size
ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate ) :
mnTexture( 0 ),
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
mnOptStencil( 0 )
{
OpenGLVCLContextZone aContextZone;
auto& rState = OpenGLContext::getVCLContext()->state();
TextureState::generate(mnTexture);
rState.texture().active(0);
rState.texture().bind(mnTexture);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
CHECK_GL_ERROR();
if( bAllocate )
{
#ifdef DBG_UTIL
std::vector< sal_uInt8 > buffer;
buffer.resize( nWidth * nHeight * 4 );
for( int i = 0; i < nWidth * nHeight; ++i )
{ // pre-fill the texture with deterministic garbage
bool odd = (i & 0x01);
buffer[ i * 4 ] = odd ? 0x40 : 0xBF;
buffer[ i * 4 + 1 ] = 0x80;
buffer[ i * 4 + 2 ] = odd ? 0xBF : 0x40;
buffer[ i * 4 + 3 ] = 0xFF;
}
glTexImage2D( GL_TEXTURE_2D, 0, constInternalFormat, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
#else
glTexImage2D( GL_TEXTURE_2D, 0, constInternalFormat, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr );
#endif
CHECK_GL_ERROR();
}
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " allocate" );
}
// texture with content retrieved from FBO
ImplOpenGLTexture::ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight ) :
mnTexture( 0 ),
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
mnOptStencil( 0 )
{
OpenGLVCLContextZone aContextZone;
// FIXME We need the window height here
// nY = GetHeight() - nHeight - nY;
auto& rState = OpenGLContext::getVCLContext()->state();
TextureState::generate(mnTexture);
rState.texture().active(0);
rState.texture().bind(mnTexture);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
CHECK_GL_ERROR();
glCopyTexImage2D( GL_TEXTURE_2D, 0, constInternalFormat, nX, nY, nWidth, nHeight, 0 );
CHECK_GL_ERROR();
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " from x" << nX << ", y" << nY );
}
// texture from buffer data
ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, void const * pData ) :
mnTexture( 0 ),
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
mnOptStencil( 0 )
{
OpenGLVCLContextZone aContextZone;
auto& rState = OpenGLContext::getVCLContext()->state();
TextureState::generate(mnTexture);
rState.texture().active(0);
rState.texture().bind(mnTexture);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
CHECK_GL_ERROR();
glTexImage2D( GL_TEXTURE_2D, 0, constInternalFormat, mnWidth, mnHeight, 0, nFormat, nType, pData );
CHECK_GL_ERROR();
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " from data" );
}
GLuint ImplOpenGLTexture::AddStencil()
{
assert( mnOptStencil == 0 );
glGenRenderbuffers( 1, &mnOptStencil );
CHECK_GL_ERROR();
glBindRenderbuffer( GL_RENDERBUFFER, mnOptStencil );
CHECK_GL_ERROR();
VCL_GL_INFO( "Allocate stencil " << mnWidth << " x " << mnHeight );
glRenderbufferStorage( GL_RENDERBUFFER, GL_STENCIL_INDEX,
mnWidth, mnHeight );
CHECK_GL_ERROR();
glBindRenderbuffer(GL_RENDERBUFFER, 0);
CHECK_GL_ERROR();
return mnOptStencil;
}
ImplOpenGLTexture::~ImplOpenGLTexture()
{
VCL_GL_INFO( "~OpenGLTexture " << mnTexture );
if( mnTexture == 0 )
return;
// During shutdown GL is already de-initialized, so we should not try to create a new context.
OpenGLZone aZone;
rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext(false);
if( xContext.is() )
{
// FIXME: this is really not optimal performance-wise.
// Check we have been correctly un-bound from all framebuffers.
ImplSVData* pSVData = ImplGetSVData();
rtl::Reference<OpenGLContext> pContext = pSVData->maGDIData.mpLastContext;
if( pContext.is() )
{
pContext->makeCurrent();
pContext->UnbindTextureFromFramebuffers( mnTexture );
}
if( mnOptStencil != 0 )
{
glDeleteRenderbuffers( 1, &mnOptStencil );
mnOptStencil = 0;
}
auto& rState = pContext->state();
rState.texture().unbindAndDelete(mnTexture);
mnTexture = 0;
}
else
{
mnOptStencil = 0;
mnTexture = 0;
}
}
bool ImplOpenGLTexture::InsertBuffer(int nX, int nY, int nWidth, int nHeight, int nFormat, int nType, sal_uInt8 const * pData)
{
if (!pData || mnTexture == 0)
return false;
rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
xContext->state().texture().active(0);
xContext->state().texture().bind(mnTexture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
CHECK_GL_ERROR();
glTexSubImage2D(GL_TEXTURE_2D, 0, nX, mnHeight - nY - nHeight, nWidth, nHeight, nFormat, nType, pData);
CHECK_GL_ERROR();
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " Insert buff. to " << nX << " " << nY
<< " size " << nWidth << "x" << nHeight << " from data" );
return true;
}
void ImplOpenGLTexture::InitializeSlotMechanism(int nInitialSlotSize)
{
if (mpSlotReferences)
return;
mpSlotReferences.reset(new std::vector<int>(nInitialSlotSize, 0));
}
void ImplOpenGLTexture::IncreaseRefCount(int nSlotNumber)
{
if (mpSlotReferences && nSlotNumber >= 0)
{
if (nSlotNumber >= int(mpSlotReferences->size()))
mpSlotReferences->resize(nSlotNumber + 1, 0);
mpSlotReferences->at(nSlotNumber)++;
}
}
void ImplOpenGLTexture::DecreaseRefCount(int nSlotNumber)
{
if (mpSlotReferences && nSlotNumber >= 0)
{
if (nSlotNumber >= int(mpSlotReferences->size()))
mpSlotReferences->resize(nSlotNumber, 0);
mpSlotReferences->at(nSlotNumber)--;
if (mpSlotReferences->at(nSlotNumber) == 0 && mFunctSlotDeallocateCallback)
{
mFunctSlotDeallocateCallback(nSlotNumber);
}
}
}
OpenGLTexture::OpenGLTexture() :
maRect( 0, 0, 0, 0 ),
mpImpl(),
mnSlotNumber(-1)
{
}
OpenGLTexture::OpenGLTexture(const std::shared_ptr<ImplOpenGLTexture>& rpImpl, tools::Rectangle aRectangle, int nSlotNumber)
: maRect(aRectangle)
, mpImpl(rpImpl)
, mnSlotNumber(nSlotNumber)
{
if (mpImpl)
mpImpl->IncreaseRefCount(nSlotNumber);
}
OpenGLTexture::OpenGLTexture( int nWidth, int nHeight, bool bAllocate )
: maRect( Point( 0, 0 ), Size( nWidth, nHeight ) )
, mpImpl(std::make_shared<ImplOpenGLTexture>(nWidth, nHeight, bAllocate))
, mnSlotNumber(-1)
{
}
OpenGLTexture::OpenGLTexture( int nX, int nY, int nWidth, int nHeight )
: maRect( Point( 0, 0 ), Size( nWidth, nHeight ) )
, mpImpl(std::make_shared<ImplOpenGLTexture>(nX, nY, nWidth, nHeight))
, mnSlotNumber(-1)
{
}
OpenGLTexture::OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, void const * pData )
: maRect( Point( 0, 0 ), Size( nWidth, nHeight ) )
, mpImpl(std::make_shared<ImplOpenGLTexture>(nWidth, nHeight, nFormat, nType, pData))
, mnSlotNumber(-1)
{
}
OpenGLTexture::OpenGLTexture(const OpenGLTexture& rTexture)
: maRect(rTexture.maRect)
, mpImpl(rTexture.mpImpl)
, mnSlotNumber(rTexture.mnSlotNumber)
{
if (mpImpl)
mpImpl->IncreaseRefCount(mnSlotNumber);
}
OpenGLTexture::OpenGLTexture(OpenGLTexture&& rTexture) noexcept
: maRect(rTexture.maRect)
, mpImpl(std::move(rTexture.mpImpl))
, mnSlotNumber(rTexture.mnSlotNumber)
{
}
OpenGLTexture::OpenGLTexture( const OpenGLTexture& rTexture,
int nX, int nY, int nWidth, int nHeight )
{
maRect = tools::Rectangle( Point( rTexture.maRect.Left() + nX, rTexture.maRect.Top() + nY ),
Size( nWidth, nHeight ) );
mpImpl = rTexture.mpImpl;
mnSlotNumber = rTexture.mnSlotNumber;
if (mpImpl)
mpImpl->IncreaseRefCount(mnSlotNumber);
VCL_GL_INFO( "Copying texture " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() );
}
OpenGLTexture::~OpenGLTexture()
{
if (mpImpl)
mpImpl->DecreaseRefCount(mnSlotNumber);
}
bool OpenGLTexture::IsUnique() const
{
return !mpImpl || (mpImpl.use_count() == 1);
}
GLuint OpenGLTexture::Id() const
{
if (mpImpl)
return mpImpl->mnTexture;
return 0;
}
int OpenGLTexture::GetWidth() const
{
return maRect.GetWidth();
}
int OpenGLTexture::GetHeight() const
{
return maRect.GetHeight();
}
GLuint OpenGLTexture::StencilId() const
{
return mpImpl ? mpImpl->mnOptStencil : 0;
}
GLuint OpenGLTexture::AddStencil()
{
if (mpImpl)
return mpImpl->AddStencil();
else
return 0;
}
void OpenGLTexture::GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool bInverted ) const
{
VCL_GL_INFO( "Getting coord " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() );
if (!IsValid())
{
pCoord[0] = pCoord[1] = pCoord[2] = pCoord[3] = 0.0f;
pCoord[4] = pCoord[5] = pCoord[6] = pCoord[7] = 0.0f;
return;
}
pCoord[0] = pCoord[2] = (maRect.Left() + rPosAry.mnSrcX) / static_cast<double>(mpImpl->mnWidth);
pCoord[4] = pCoord[6] = (maRect.Left() + rPosAry.mnSrcX + rPosAry.mnSrcWidth) / static_cast<double>(mpImpl->mnWidth);
if( !bInverted )
{
pCoord[3] = pCoord[5] = 1.0f - (maRect.Top() + rPosAry.mnSrcY) / static_cast<double>(mpImpl->mnHeight);
pCoord[1] = pCoord[7] = 1.0f - (maRect.Top() + rPosAry.mnSrcY + rPosAry.mnSrcHeight) / static_cast<double>(mpImpl->mnHeight);
}
else
{
pCoord[1] = pCoord[7] = 1.0f - (maRect.Top() + rPosAry.mnSrcY) / static_cast<double>(mpImpl->mnHeight);
pCoord[3] = pCoord[5] = 1.0f - (maRect.Top() + rPosAry.mnSrcY + rPosAry.mnSrcHeight) / static_cast<double>(mpImpl->mnHeight);
}
}
void OpenGLTexture::GetTextureRect(const SalTwoRect& rPosAry, GLfloat& x1, GLfloat& x2, GLfloat& y1, GLfloat& y2) const
{
if (IsValid())
{
double fTextureWidth(mpImpl->mnWidth);
double fTextureHeight(mpImpl->mnHeight);
x1 = (maRect.Left() + rPosAry.mnSrcX) / fTextureWidth;
x2 = (maRect.Left() + rPosAry.mnSrcX + rPosAry.mnSrcWidth) / fTextureWidth;
y1 = 1.0f - (maRect.Top() + rPosAry.mnSrcY) / fTextureHeight;
y2 = 1.0f - (maRect.Top() + rPosAry.mnSrcY + rPosAry.mnSrcHeight) / fTextureHeight;
}
}
template <>
void OpenGLTexture::FillCoords<GL_TRIANGLE_FAN>(std::vector<GLfloat>& rCoords, const SalTwoRect& rPosAry) const
{
GLfloat x1 = 0.0f;
GLfloat x2 = 0.0f;
GLfloat y1 = 0.0f;
GLfloat y2 = 0.0f;
GetTextureRect(rPosAry, x1, x2, y1, y2);
rCoords.insert(rCoords.end(), {
x1, y2, x1, y1,
x2, y1, x2, y2
});
}
template <>
void OpenGLTexture::FillCoords<GL_TRIANGLES>(std::vector<GLfloat>& rCoords, const SalTwoRect& rPosAry) const
{
GLfloat x1 = 0.0f;
GLfloat x2 = 0.0f;
GLfloat y1 = 0.0f;
GLfloat y2 = 0.0f;
GetTextureRect(rPosAry, x1, x2, y1, y2);
rCoords.insert(rCoords.end(), {
x1, y1, x2, y1, x1, y2,
x1, y2, x2, y1, x2, y2
});
}
void OpenGLTexture::GetWholeCoord( GLfloat* pCoord ) const
{
if( GetWidth() != mpImpl->mnWidth || GetHeight() != mpImpl->mnHeight )
{
pCoord[0] = pCoord[2] = maRect.Left() / static_cast<double>(mpImpl->mnWidth);
pCoord[4] = pCoord[6] = maRect.Right() / static_cast<double>(mpImpl->mnWidth);
pCoord[3] = pCoord[5] = 1.0f - maRect.Top() / static_cast<double>(mpImpl->mnHeight);
pCoord[1] = pCoord[7] = 1.0f - maRect.Bottom() / static_cast<double>(mpImpl->mnHeight);
}
else
{
pCoord[0] = pCoord[2] = 0;
pCoord[4] = pCoord[6] = 1;
pCoord[1] = pCoord[7] = 0;
pCoord[3] = pCoord[5] = 1;
}
}
GLenum OpenGLTexture::GetFilter() const
{
if( mpImpl )
return mpImpl->mnFilter;
return GL_NEAREST;
}
bool OpenGLTexture::CopyData(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8 const * pData)
{
if (!pData || !IsValid())
return false;
int nX = maRect.Left();
int nY = maRect.Top();
return mpImpl->InsertBuffer(nX, nY, nWidth, nHeight, nFormat, nType, pData);
}
void OpenGLTexture::SetFilter( GLenum nFilter )
{
if( mpImpl )
{
mpImpl->mnFilter = nFilter;
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nFilter );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nFilter );
CHECK_GL_ERROR();
}
}
void OpenGLTexture::Bind()
{
if (IsValid())
{
OpenGLContext::getVCLContext()->state().texture().bind(mpImpl->mnTexture);
}
else
VCL_GL_INFO( "OpenGLTexture::Binding invalid texture" );
CHECK_GL_ERROR();
}
void OpenGLTexture::Unbind()
{
if (IsValid())
{
OpenGLContext::getVCLContext()->state().texture().unbind(mpImpl->mnTexture);
}
}
void OpenGLTexture::SaveToFile(const OUString& rFileName)
{
std::vector<sal_uInt8> aBuffer(GetWidth() * GetHeight() * 4);
Read(OpenGLHelper::OptimalBufferFormat(), GL_UNSIGNED_BYTE, aBuffer.data());
BitmapEx aBitmap = OpenGLHelper::ConvertBufferToBitmapEx(aBuffer.data(), GetWidth(), GetHeight());
try
{
vcl::PNGWriter aWriter(aBitmap);
SvFileStream sOutput(rFileName, StreamMode::WRITE);
aWriter.Write(sOutput);
sOutput.Close();
}
catch (...)
{
SAL_WARN("vcl.opengl", "Error writing png to " << rFileName);
}
}
void OpenGLTexture::Read( GLenum nFormat, GLenum nType, sal_uInt8* pData )
{
if (!IsValid())
{
SAL_WARN( "vcl.opengl", "Can't read invalid texture" );
return;
}
OpenGLVCLContextZone aContextZone;
VCL_GL_INFO( "Reading texture " << Id() << " " << GetWidth() << "x" << GetHeight() );
if( GetWidth() == mpImpl->mnWidth && GetHeight() == mpImpl->mnHeight )
{
Bind();
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
CHECK_GL_ERROR();
// XXX: Call not available with GLES 2.0
glGetTexImage( GL_TEXTURE_2D, 0, nFormat, nType, pData );
CHECK_GL_ERROR();
Unbind();
}
else
{
tools::Long nWidth = maRect.GetWidth();
tools::Long nHeight = maRect.GetHeight();
tools::Long nX = maRect.Left();
tools::Long nY = mpImpl->mnHeight - maRect.Top() - nHeight;
// Retrieve current context
ImplSVData* pSVData = ImplGetSVData();
rtl::Reference<OpenGLContext> pContext = pSVData->maGDIData.mpLastContext;
OpenGLFramebuffer* pFramebuffer = pContext->AcquireFramebuffer(*this);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
CHECK_GL_ERROR();
glReadPixels(nX, nY, nWidth, nHeight, nFormat, nType, pData);
CHECK_GL_ERROR();
OpenGLContext::ReleaseFramebuffer(pFramebuffer);
}
}
OpenGLTexture::operator bool() const
{
return IsValid();
}
OpenGLTexture& OpenGLTexture::operator=(const OpenGLTexture& rTexture)
{
OpenGLTexture aTemp(rTexture);
*this = std::move(aTemp);
return *this;
}
OpenGLTexture& OpenGLTexture::operator=(OpenGLTexture&& rTexture)
{
if (mpImpl)
mpImpl->DecreaseRefCount(mnSlotNumber);
maRect = rTexture.maRect;
mpImpl = std::move(rTexture.mpImpl);
mnSlotNumber = rTexture.mnSlotNumber;
return *this;
}
bool OpenGLTexture::operator==( const OpenGLTexture& rTexture ) const
{
return (mpImpl == rTexture.mpImpl
&& maRect == rTexture.maRect
&& mnSlotNumber == rTexture.mnSlotNumber);
}
bool OpenGLTexture::operator!=( const OpenGLTexture& rTexture ) const
{
return !( *this == rTexture );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+5 -226
View File
@@ -9,7 +9,7 @@
#include <memory>
#include <thread>
#include <opengl/win/gdiimpl.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <sal/log.hxx>
@@ -453,7 +453,7 @@ bool compiledShaderBinariesWork()
bResult =
(
#if 0 // Only look at shaders used by vcl for now
#if 0 // Only look at shaders used by slideshow for now
// canvas
tryShaders("dummyVertexShader", "linearMultiColorGradientFragmentShader") &&
tryShaders("dummyVertexShader", "linearTwoColorGradientFragmentShader") &&
@@ -461,48 +461,14 @@ bool compiledShaderBinariesWork()
tryShaders("dummyVertexShader", "radialTwoColorGradientFragmentShader") &&
tryShaders("dummyVertexShader", "rectangularMultiColorGradientFragmentShader") &&
tryShaders("dummyVertexShader", "rectangularTwoColorGradientFragmentShader") &&
// chart2
(GLEW_VERSION_3_3 ?
(tryShaders("shape3DVertexShader", "shape3DFragmentShader") &&
tryShaders("shape3DVertexShaderBatchScroll", "shape3DFragmentShaderBatchScroll") &&
tryShaders("shape3DVertexShaderBatch", "shape3DFragmentShaderBatch") &&
tryShaders("textVertexShaderBatch", "textFragmentShaderBatch")) :
(tryShaders("shape3DVertexShaderV300", "shape3DFragmentShaderV300"))) &&
tryShaders("textVertexShader", "textFragmentShader") &&
tryShaders("screenTextVertexShader", "screenTextFragmentShader") &&
tryShaders("commonVertexShader", "commonFragmentShader") &&
tryShaders("pickingVertexShader", "pickingFragmentShader") &&
tryShaders("backgroundVertexShader", "backgroundFragmentShader") &&
tryShaders("symbolVertexShader", "symbolFragmentShader") &&
tryShaders("symbolVertexShader", "symbolFragmentShader") &&
#endif
// slideshow
tryShaders("reflectionVertexShader", "reflectionFragmentShader") &&
tryShaders("basicVertexShader", "basicFragmentShader") &&
tryShaders("vortexVertexShader", "vortexFragmentShader", "vortexGeometryShader") &&
tryShaders("basicVertexShader", "rippleFragmentShader") &&
tryShaders("glitterVertexShader", "glitterFragmentShader") &&
tryShaders("honeycombVertexShader", "honeycombFragmentShader", "honeycombGeometryShader") &&
#endif
// vcl
tryShaders("combinedVertexShader", "combinedFragmentShader") &&
tryShaders("dumbVertexShader", "invert50FragmentShader") &&
tryShaders("textureVertexShader", "areaScaleFragmentShader") &&
tryShaders("transformedTextureVertexShader", "maskedTextureFragmentShader") &&
tryShaders("transformedTextureVertexShader", "areaScaleFastFragmentShader") &&
tryShaders("transformedTextureVertexShader", "areaScaleFastFragmentShader", "", "#define MASKED") &&
tryShaders("transformedTextureVertexShader", "areaScaleFragmentShader") &&
tryShaders("transformedTextureVertexShader", "areaScaleFragmentShader", "", "#define MASKED") &&
tryShaders("transformedTextureVertexShader", "textureFragmentShader") &&
tryShaders("combinedTextureVertexShader", "combinedTextureFragmentShader") &&
tryShaders("combinedTextureVertexShader", "combinedTextureFragmentShader", "", "// flush shader\n") &&
tryShaders("textureVertexShader", "linearGradientFragmentShader") &&
tryShaders("textureVertexShader", "radialGradientFragmentShader") &&
tryShaders("textureVertexShader", "areaHashCRC64TFragmentShader") &&
tryShaders("textureVertexShader", "replaceColorFragmentShader") &&
tryShaders("textureVertexShader", "greyscaleFragmentShader") &&
tryShaders("textureVertexShader", "textureFragmentShader") &&
tryShaders("textureVertexShader", "convolutionFragmentShader") &&
tryShaders("textureVertexShader", "areaScaleFastFragmentShader"));
tryShaders("honeycombVertexShader", "honeycombFragmentShader", "honeycombGeometryShader"));
return bResult;
}
@@ -544,10 +510,7 @@ bool WinOpenGLContext::ImplInit()
int WindowPix = 0;
bool bMultiSampleSupport = false;
if (!mbVCLOnly)
bMultiSampleSupport = InitMultisample(PixelFormatFront, WindowPix, /*bUseDoubleBufferedRendering*/true, false);
else
VCL_GL_INFO("Skipping multisample detection for VCL.");
bMultiSampleSupport = InitMultisample(PixelFormatFront, WindowPix, /*bUseDoubleBufferedRendering*/true, false);
if (bMultiSampleSupport && WindowPix != 0)
{
@@ -711,188 +674,4 @@ OpenGLContext* WinSalInstance::CreateOpenGLContext()
return new WinOpenGLContext;
}
WinOpenGLSalGraphicsImpl::WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics,
SalGeometryProvider *mpProvider):
OpenGLSalGraphicsImpl(rGraphics,mpProvider),
mrWinParent(rGraphics)
{
}
void WinOpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
{
OpenGLSalGraphicsImpl *pImpl = pSrcGraphics ? static_cast< OpenGLSalGraphicsImpl* >(pSrcGraphics->GetImpl()) : static_cast< OpenGLSalGraphicsImpl *>(mrParent.GetImpl());
OpenGLSalGraphicsImpl::DoCopyBits( rPosAry, *pImpl );
}
rtl::Reference<OpenGLContext> WinOpenGLSalGraphicsImpl::CreateWinContext()
{
rtl::Reference<WinOpenGLContext> xContext(new WinOpenGLContext);
xContext->setVCLOnly();
if (!xContext->init(mrWinParent.mhLocalDC, mrWinParent.mhWnd))
{
SAL_WARN("vcl.opengl", "Context could not be created.");
return rtl::Reference<OpenGLContext>();
}
return rtl::Reference<OpenGLContext>(xContext.get());
}
void WinOpenGLSalGraphicsImpl::Init()
{
if (!IsOffscreen() && mpContext.is() && mpContext->isInitialized())
{
const GLWinWindow& rGLWindow = static_cast<const GLWinWindow&>(mpContext->getOpenGLWindow());
if (rGLWindow.hWnd != mrWinParent.mhWnd || rGLWindow.hDC == mrWinParent.mhLocalDC)
{
// This can legitimately happen, SalFrame keeps 2x
// SalGraphics which share the same hWnd and hDC.
// The shape 'Area' dialog does reparenting to trigger this.
SAL_WARN("vcl.opengl", "Unusual: Windows handle / DC changed without DeInit");
DeInit();
}
}
OpenGLSalGraphicsImpl::Init();
}
OpenGLControlsCache::OpenGLControlsCache(): cache(200) {}
OpenGLControlCacheType & OpenGLControlsCache::get() {
SalData * data = GetSalData();
if (!data->m_pOpenGLControlsCache) {
data->m_pOpenGLControlsCache.reset(new OpenGLControlsCache);
}
return data->m_pOpenGLControlsCache->cache;
}
OpenGLCompatibleDC::OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height)
: CompatibleDC( rGraphics, x, y, width, height, false )
{
}
OpenGLTexture* OpenGLCompatibleDC::getOpenGLTexture() const
{
if (!mpImpl)
return nullptr;
// turn what's in the mpData into a texture
return new OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData);
}
std::unique_ptr<CompatibleDC::Texture> OpenGLCompatibleDC::getAsMaskTexture() const
{
auto ret = std::make_unique<OpenGLCompatibleDC::Texture>();
ret->texture = OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData);
return ret;
}
bool OpenGLCompatibleDC::copyToTexture(CompatibleDC::Texture& aTexture) const
{
if (!mpImpl)
return false;
assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(&aTexture));
return static_cast<OpenGLCompatibleDC::Texture&>(aTexture).texture.CopyData(
maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, reinterpret_cast<sal_uInt8*>(mpData));
}
bool WinOpenGLSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY)
{
static bool gbCacheEnabled = !getenv("SAL_WITHOUT_WIDGET_CACHE");
if (!gbCacheEnabled)
return false;
auto & gTextureCache = OpenGLControlsCache::get();
OpenGLControlCacheType::const_iterator iterator = gTextureCache.find(rControlCacheKey);
if (iterator == gTextureCache.end())
return false;
const std::unique_ptr<TextureCombo>& pCombo = iterator->second;
bool bRet = false;
PreDraw();
bRet = RenderTextureCombo(*pCombo, nX, nY);
PostDraw();
return bRet;
}
bool WinOpenGLSalGraphicsImpl::RenderTextureCombo(TextureCombo const & rCombo, int nX, int nY)
{
OpenGLTexture& rTexture = *rCombo.mpTexture;
SalTwoRect aPosAry(0, 0, rTexture.GetWidth(), rTexture.GetHeight(),
nX, nY, rTexture.GetWidth(), rTexture.GetHeight());
DrawTextureDiff(rTexture, *rCombo.mpMask, aPosAry, false);
return true;
}
bool WinOpenGLSalGraphicsImpl::RenderCompatibleDC(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack,
int nX, int nY, TextureCombo& rCombo)
{
bool bRet = false;
PreDraw();
rCombo.mpTexture.reset(rWhite.getOpenGLTexture());
rCombo.mpMask.reset(rBlack.getOpenGLTexture());
bRet = RenderTextureCombo(rCombo, nX, nY);
PostDraw();
return bRet;
}
bool WinOpenGLSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack,
int nX, int nY , ControlCacheKey& aControlCacheKey)
{
assert(dynamic_cast<OpenGLCompatibleDC*>(&rWhite));
assert(dynamic_cast<OpenGLCompatibleDC*>(&rBlack));
std::unique_ptr<TextureCombo> pCombo(new TextureCombo);
bool bResult = RenderCompatibleDC(static_cast<OpenGLCompatibleDC&>(rWhite),
static_cast<OpenGLCompatibleDC&>(rBlack), nX, nY, *pCombo);
if (!bResult)
return false;
if (!aControlCacheKey.canCacheControl())
return true;
OpenGLControlCachePair pair(aControlCacheKey, std::move(pCombo));
OpenGLControlsCache::get().insert(std::move(pair));
return bResult;
}
void WinOpenGLSalGraphicsImpl::PreDrawText()
{
PreDraw();
}
void WinOpenGLSalGraphicsImpl::PostDrawText()
{
PostDraw();
}
void WinOpenGLSalGraphicsImpl::DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color aMaskColor, const SalTwoRect& rPosAry)
{
assert(dynamic_cast<const OpenGLCompatibleDC::Texture*>(pTexture));
mpRenderList->addDrawTextureWithMaskColor(
static_cast<const OpenGLCompatibleDC::Texture*>(pTexture)->texture, aMaskColor, rPosAry);
PostBatchDraw();
}
void WinOpenGLSalGraphicsImpl::DrawTextMask( CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry )
{
assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(pTexture));
DrawMask( static_cast<OpenGLCompatibleDC::Texture*>(pTexture)->texture, nMaskColor, rPosAry );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-60
View File
@@ -1,60 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <opengl/win/winlayout.hxx>
#include <opengl/win/gdiimpl.hxx>
bool OpenGLGlobalWinGlyphCache::AllocateTexture(WinGlyphDrawElement& rElement, CompatibleDC* dc)
{
assert(!rElement.maTexture);
assert(dynamic_cast<OpenGLCompatibleDC*>(dc));
OpenGLCompatibleDC* odc = static_cast<OpenGLCompatibleDC*>(dc);
OpenGLCompatibleDC::Texture* texture = new OpenGLCompatibleDC::Texture;
rElement.maTexture.reset(texture);
texture->texture = maPackedTextureAtlas.Reserve(dc->getBitmapWidth(), dc->getBitmapHeight());
if (!texture->texture)
return false;
if (!odc->copyToTexture(*rElement.maTexture))
return false;
return true;
}
void OpenGLGlobalWinGlyphCache::Prune()
{
std::vector<GLuint> aTextureIDs = maPackedTextureAtlas.ReduceTextureNumber(8);
if (!aTextureIDs.empty())
{
for (auto& pWinGlyphCache : maWinGlyphCaches)
static_cast<OpenGLWinGlyphCache*>(pWinGlyphCache)->RemoveTextures(aTextureIDs);
}
}
void OpenGLWinGlyphCache::RemoveTextures(std::vector<GLuint>& rTextureIDs)
{
auto it = maWinTextureCache.begin();
while (it != maWinTextureCache.end())
{
assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(it->second.maTexture.get()));
GLuint nTextureID
= static_cast<OpenGLCompatibleDC::Texture*>(it->second.maTexture.get())->texture.Id();
if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end())
{
it = maWinTextureCache.erase(it);
}
else
{
++it;
}
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-84
View File
@@ -1,84 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <opengl/x11/cairotextrender.hxx>
#include <opengl/gdiimpl.hxx>
#include <cairo.h>
OpenGLX11CairoTextRender::OpenGLX11CairoTextRender(X11SalGraphics& rParent)
: X11CairoTextRender(rParent)
{
}
cairo_t* OpenGLX11CairoTextRender::getCairoContext()
{
cairo_surface_t* surface = nullptr;
OpenGLSalGraphicsImpl *pImpl = dynamic_cast< OpenGLSalGraphicsImpl* >(mrParent.GetImpl());
if( pImpl )
{
tools::Rectangle aClipRect = pImpl->getClipRegion().GetBoundRect();
if( aClipRect.GetWidth() == 0 || aClipRect.GetHeight() == 0 )
{
aClipRect.setWidth( GetWidth() );
aClipRect.setHeight( GetHeight() );
}
surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, aClipRect.GetWidth(), aClipRect.GetHeight() );
}
if (!surface)
return nullptr;
cairo_t *cr = cairo_create(surface);
cairo_surface_destroy(surface);
return cr;
}
void OpenGLX11CairoTextRender::getSurfaceOffset( double& nDX, double& nDY )
{
OpenGLSalGraphicsImpl *pImpl = dynamic_cast< OpenGLSalGraphicsImpl* >(mrParent.GetImpl());
if( pImpl )
{
tools::Rectangle aClipRect = pImpl->getClipRegion().GetBoundRect();
nDX = -aClipRect.Left();
nDY = -aClipRect.Top();
}
}
void OpenGLX11CairoTextRender::releaseCairoContext(cairo_t* cr)
{
// XXX: lfrb: GLES 2.0 doesn't support GL_UNSIGNED_INT_8_8_8_8_REV
OpenGLSalGraphicsImpl *pImpl = dynamic_cast< OpenGLSalGraphicsImpl* >(mrParent.GetImpl());
if(!pImpl)
{
cairo_destroy(cr);
return;
}
cairo_surface_t* pSurface = cairo_get_target(cr);
int nWidth = cairo_image_surface_get_width( pSurface );
int nHeight = cairo_image_surface_get_height( pSurface );
cairo_surface_flush(pSurface);
unsigned char *pSrc = cairo_image_surface_get_data( pSurface );
// XXX: lfrb: GLES 2.0 doesn't support GL_UNSIGNED_INT_8_8_8_8_REV
tools::Rectangle aClipRect = pImpl->getClipRegion().GetBoundRect();
SalTwoRect aRect(0, 0, nWidth, nHeight,
aClipRect.Left(), aClipRect.Top(), nWidth, nHeight);
// Cairo surface data is ARGB with premultiplied alpha and is Y-inverted
OpenGLTexture aTexture( nWidth, nHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pSrc );
pImpl->PreDraw();
pImpl->DrawAlphaTexture( aTexture, aRect, true, true );
pImpl->PostDraw();
cairo_destroy(cr);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-81
View File
@@ -19,19 +19,12 @@
#include <unx/salvd.h>
#include <unx/x11/xlimits.hxx>
#include <opengl/texture.hxx>
#include <opengl/zone.hxx>
#include <opengl/RenderState.hxx>
#include <opengl/x11/gdiimpl.hxx>
#include <opengl/x11/salvd.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <sal/log.hxx>
#include <o3tl/lru_map.hxx>
#include <ControlCacheKey.hxx>
static std::vector<GLXContext> g_vShareList;
static bool g_bAnyCurrent;
@@ -40,7 +33,6 @@ namespace {
class X11OpenGLContext : public OpenGLContext
{
public:
void init(Display* dpy, Window win, int screen);
virtual void initWindow() override;
private:
GLX11Window m_aGLWin;
@@ -181,20 +173,6 @@ private:
return pFBC;
}
Visual* getVisual(Display* dpy, Window win)
{
OpenGLZone aZone;
XWindowAttributes xattr;
if( !XGetWindowAttributes( dpy, win, &xattr ) )
{
SAL_WARN("vcl.opengl", "Failed to get window attributes for getVisual " << win);
xattr.visual = nullptr;
}
VCL_GL_INFO("using VisualID " << xattr.visual);
return xattr.visual;
}
}
void X11OpenGLContext::sync()
@@ -448,27 +426,6 @@ void X11OpenGLContext::destroyCurrentContext()
m_aGLWin.ctx = nullptr;
}
void X11OpenGLContext::init(Display* dpy, Window win, int screen)
{
if (isInitialized())
return;
if (!dpy)
return;
OpenGLZone aZone;
m_aGLWin.dpy = dpy;
m_aGLWin.win = win;
m_aGLWin.screen = screen;
Visual* pVisual = getVisual(dpy, win);
initGLWindow(pVisual);
ImplInit();
}
void X11OpenGLContext::initGLWindow(Visual* pVisual)
{
OpenGLZone aZone;
@@ -557,42 +514,4 @@ OpenGLContext* X11SalInstance::CreateOpenGLContext()
return new X11OpenGLContext;
}
X11OpenGLSalGraphicsImpl::X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent ):
OpenGLSalGraphicsImpl(rParent,rParent.GetGeometryProvider()),
mrX11Parent(rParent)
{
}
X11OpenGLSalGraphicsImpl::~X11OpenGLSalGraphicsImpl()
{
}
void X11OpenGLSalGraphicsImpl::Init()
{
// The m_pFrame and m_pVDev pointers are updated late in X11
mpProvider = mrX11Parent.GetGeometryProvider();
OpenGLSalGraphicsImpl::Init();
}
rtl::Reference<OpenGLContext> X11OpenGLSalGraphicsImpl::CreateWinContext()
{
NativeWindowHandleProvider *pProvider = dynamic_cast<NativeWindowHandleProvider*>(mrX11Parent.m_pFrame);
if( !pProvider )
return nullptr;
sal_uIntPtr aWin = pProvider->GetNativeWindowHandle();
rtl::Reference<X11OpenGLContext> xContext = new X11OpenGLContext;
xContext->setVCLOnly();
xContext->init( mrX11Parent.GetXDisplay(), aWin,
mrX11Parent.m_nXScreen.getXScreen() );
return rtl::Reference<OpenGLContext>(xContext.get());
}
void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
{
OpenGLSalGraphicsImpl *pImpl = pSrcGraphics ? static_cast< OpenGLSalGraphicsImpl* >(pSrcGraphics->GetImpl()) : static_cast< OpenGLSalGraphicsImpl *>(mrX11Parent.GetImpl());
OpenGLSalGraphicsImpl::DoCopyBits( rPosAry, *pImpl );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-90
View File
@@ -1,90 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <vcl/sysdata.hxx>
#include <unx/salunx.h>
#include <unx/saldisp.hxx>
#include <unx/salgdi.h>
#include <unx/salvd.h>
#include <opengl/x11/salvd.hxx>
void X11SalGraphics::Init( X11OpenGLSalVirtualDevice *pDevice )
{
SalDisplay *pDisplay = pDevice->GetDisplay();
m_nXScreen = pDevice->GetXScreenNumber();
m_pColormap = &pDisplay->GetColormap( m_nXScreen );
m_pVDev = pDevice;
m_pFrame = nullptr;
bWindow_ = pDisplay->IsDisplay();
bVirDev_ = true;
mxImpl->Init();
}
X11OpenGLSalVirtualDevice::X11OpenGLSalVirtualDevice( SalGraphics const * pGraphics,
tools::Long nDX, tools::Long nDY,
const SystemGraphicsData *pData,
std::unique_ptr<X11SalGraphics> pNewGraphics) :
mpGraphics(std::move(pNewGraphics)),
mbGraphics( false ),
mnXScreen( 0 )
{
assert(mpGraphics);
// TODO Check where a VirtualDevice is created from SystemGraphicsData
assert( pData == nullptr ); (void)pData;
mpDisplay = vcl_sal::getSalDisplay(GetGenericUnixSalData());
mnXScreen = pGraphics ? static_cast<X11SalGraphics const *>(pGraphics)->GetScreenNumber() :
vcl_sal::getSalDisplay(GetGenericUnixSalData())->GetDefaultXScreen();
mnWidth = nDX;
mnHeight = nDY;
mpGraphics->Init( this );
}
X11OpenGLSalVirtualDevice::~X11OpenGLSalVirtualDevice()
{
}
SalGraphics* X11OpenGLSalVirtualDevice::AcquireGraphics()
{
if( mbGraphics )
return nullptr;
if( mpGraphics )
mbGraphics = true;
return mpGraphics.get();
}
void X11OpenGLSalVirtualDevice::ReleaseGraphics( SalGraphics* )
{
mbGraphics = false;
}
bool X11OpenGLSalVirtualDevice::SetSize( tools::Long nDX, tools::Long nDY )
{
if( !nDX ) nDX = 1;
if( !nDY ) nDY = 1;
mnWidth = nDX;
mnHeight = nDY;
if( mpGraphics )
mpGraphics->Init( this );
return true;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+1 -9
View File
@@ -360,10 +360,7 @@ void BitmapTest::testConvert()
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(10), pReadAccess->GetScanlineSize());
#else
if (!SkiaHelper::isVCLSkiaEnabled())
#if HAVE_FEATURE_OPENGL
if (!OpenGLHelper::isVCLOpenGLEnabled())
#endif
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(12), pReadAccess->GetScanlineSize());
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(12), pReadAccess->GetScanlineSize());
#endif
CPPUNIT_ASSERT(pReadAccess->HasPalette());
const BitmapColor& rColor = pReadAccess->GetPaletteColor(pReadAccess->GetPixelIndex(1, 1));
@@ -383,11 +380,6 @@ void BitmapTest::testConvert()
if (SkiaHelper::isVCLSkiaEnabled()) // aligned to 4 bytes
CPPUNIT_ASSERT_EQUAL(sal_uInt32(32), pReadAccess->GetScanlineSize());
else
#if HAVE_FEATURE_OPENGL
if (OpenGLHelper::isVCLOpenGLEnabled())
CPPUNIT_ASSERT_EQUAL(sal_uInt32(30), pReadAccess->GetScanlineSize());
else
#endif
#if defined LINUX || defined FREEBSD
{
CPPUNIT_ASSERT_EQUAL(sal_uInt32(32), pReadAccess->GetScanlineSize());
+10 -39
View File
@@ -922,15 +922,6 @@ void SvmTest::checkBitmaps(const GDIMetaFile& rMetaFile)
OUString crc1 = "b8dee5da";
OUString crc2 = "281fc589";
OUString crc3 = "5e01ddcc";
#if HAVE_FEATURE_OPENGL
if (OpenGLHelper::isVCLOpenGLEnabled())
{
// OpenGL uses a different scaling algorithm and also a different RGB order.
crc1 = "5e01ddcc";
crc2 = "281fc589";
crc3 = "b8dee5da";
}
#endif
assertXPathAttrs(pDoc, "/metafile/bmp[1]", {{"x", "1"}, {"y", "2"}, {"crc", crc1}});
assertXPathAttrs(pDoc, "/metafile/bmpscale[1]", {
@@ -988,37 +979,17 @@ void SvmTest::checkBitmapExs(const GDIMetaFile& rMetaFile)
return; // TODO SKIA using CRCs is broken (the idea of it)
std::vector<OUString> aExpectedCRC;
#if HAVE_FEATURE_OPENGL
if (OpenGLHelper::isVCLOpenGLEnabled())
aExpectedCRC.insert(aExpectedCRC.end(),
{
aExpectedCRC.insert(aExpectedCRC.end(),
{
"08feb5d3",
"281fc589",
"b8dee5da",
"4df0e464",
"4322ee3a",
"1426653b",
"4fd547df",
"71efc447",
});
}
else
#endif
{
aExpectedCRC.insert(aExpectedCRC.end(),
{
"d8377d4f",
"281fc589",
"5e01ddcc",
"4df0e464",
"4322ee3a",
"794c92a9",
"3c80d829",
"71efc447",
});
}
"d8377d4f",
"281fc589",
"5e01ddcc",
"4df0e464",
"4322ee3a",
"794c92a9",
"3c80d829",
"71efc447",
});
assertXPathAttrs(pDoc, "/metafile/bmpex[1]", {
{"x", "1"}, {"y", "1"}, {"crc", aExpectedCRC[0]}, {"transparenttype", "bitmap"}
-5
View File
@@ -1170,11 +1170,6 @@ OUString Application::GetHWOSConfInfo(const int bSelection, const bool bLocalize
}
}
else
#endif
#if HAVE_FEATURE_OPENGL
if ( OpenGLWrapper::isVCLOpenGLEnabled() )
appendDetails(u"", Localize(SV_APP_GL, bLocalize));
else
#endif
appendDetails(u"", Localize(SV_APP_DEFAULT, bLocalize));
-7
View File
@@ -235,13 +235,6 @@ vcl::Window *ImplGetDefaultContextWindow()
pSVData->mpDefaultWin = VclPtr<WorkWindow>::Create( nullptr, WB_DEFAULTWIN );
pSVData->mpDefaultWin->SetText( "VCL ImplGetDefaultWindow" );
#if HAVE_FEATURE_OPENGL
// Add a reference to the default context so it never gets deleted
rtl::Reference<OpenGLContext> pContext = pSVData->mpDefaultWin->GetGraphics()->GetOpenGLContext();
if( pContext.is() )
pContext->acquire();
#endif
}
catch (const css::uno::Exception&)
{
-4
View File
@@ -783,10 +783,6 @@ bool Bitmap::HasFastScale()
#if HAVE_FEATURE_SKIA
if( SkiaHelper::isVCLSkiaEnabled() && SkiaHelper::renderMethodToUse() != SkiaHelper::RenderRaster)
return true;
#endif
#if HAVE_FEATURE_OPENGL
if( OpenGLHelper::isVCLOpenGLEnabled())
return true;
#endif
return false;
}
-43
View File
@@ -20,14 +20,6 @@
#include <memory>
#include <config_features.h>
#include <sal/log.hxx>
#if HAVE_FEATURE_OPENGL
#include <opengl/gdiimpl.hxx>
#include <opengl/zone.hxx>
#include <desktop/exithelper.h>
#ifdef _WIN32
#include <svsys.h>
#endif
#endif
#include <PhysicalFontFace.hxx>
#include <fontsubset.hxx>
#include <salgdi.hxx>
@@ -90,41 +82,6 @@ SalGraphics::~SalGraphics() COVERITY_NOEXCEPT_FALSE
// can't call ReleaseFonts here, as the destructor just calls this classes SetFont (pure virtual)!
}
#if HAVE_FEATURE_OPENGL
namespace
{
void disableOpenGLAndTerminateForRestart()
{
OpenGLZone::hardDisable();
#ifdef _WIN32
TerminateProcess(GetCurrentProcess(), EXITHELPER_NORMAL_RESTART);
#endif
}
}
rtl::Reference<OpenGLContext> SalGraphics::GetOpenGLContext() const
{
OpenGLSalGraphicsImpl *pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(GetImpl());
if (pImpl)
{
// If we notice that OpenGL is broken the first time being called, it is not too late to call
// disableOpenGLAndTerminateForRestart(). The first time this will be called is from displaying
// the splash screen, so if OpenGL is broken, it is "early enough" for us to be able to disable
// OpenGL and terminate bluntly with EXITHELPER_NORMAL_RESTART, thus causing the wrapper process
// to restart us, then without using OpenGL.
static bool bFirstCall = true;
rtl::Reference<OpenGLContext> xRet(pImpl->GetOpenGLContext());
if (!xRet.is() && bFirstCall)
disableOpenGLAndTerminateForRestart();
bFirstCall = false;
return xRet;
}
return nullptr;
}
#endif
bool SalGraphics::drawTransformedBitmap(
const basegfx::B2DPoint& /* rNull */,
const basegfx::B2DPoint& /* rX */,
-311
View File
@@ -22,19 +22,12 @@
#include <salgdi.hxx>
#include <salinst.hxx>
#include <opengl/framebuffer.hxx>
#include <opengl/program.hxx>
#include <opengl/texture.hxx>
#include <opengl/zone.hxx>
#include <opengl/RenderState.hxx>
#include <config_features.h>
using namespace com::sun::star;
#define MAX_FRAMEBUFFER_COUNT 30
static sal_Int64 nBufferSwapCounter = 0;
GLWindow::~GLWindow()
@@ -52,13 +45,6 @@ OpenGLContext::OpenGLContext():
mbInitialized(false),
mnRefCount(0),
mbRequestLegacyContext(false),
mbVCLOnly(false),
mnFramebufferCount(0),
mpCurrentFramebuffer(nullptr),
mpFirstFramebuffer(nullptr),
mpLastFramebuffer(nullptr),
mpCurrentProgram(nullptr),
mpRenderState(new RenderState),
mpPrevContext(nullptr),
mpNextContext(nullptr)
{
@@ -354,31 +340,6 @@ void OpenGLContext::reset()
// reset the clip region
maClipRegion.SetEmpty();
mpRenderState.reset(new RenderState);
// destroy all framebuffers
if( mpLastFramebuffer )
{
OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer;
makeCurrent();
while( pFramebuffer )
{
OpenGLFramebuffer* pPrevFramebuffer = pFramebuffer->mpPrevFramebuffer;
delete pFramebuffer;
pFramebuffer = pPrevFramebuffer;
}
mnFramebufferCount = 0;
mpFirstFramebuffer = nullptr;
mpLastFramebuffer = nullptr;
}
// destroy all programs
if( !maPrograms.empty() )
{
makeCurrent();
maPrograms.clear();
}
if( isCurrent() )
resetCurrent();
@@ -428,13 +389,6 @@ bool OpenGLContext::hasCurrent()
void OpenGLContext::clearCurrent()
{
ImplSVData* pSVData = ImplGetSVData();
// release all framebuffers from the old context so we can re-attach the
// texture in the new context
rtl::Reference<OpenGLContext> pCurrentCtx = pSVData->maGDIData.mpLastContext;
if( pCurrentCtx.is() && pCurrentCtx->isCurrent() )
pCurrentCtx->ReleaseFramebuffers();
}
void OpenGLContext::prepareForYield()
@@ -467,46 +421,6 @@ void OpenGLContext::prepareForYield()
assert (!hasCurrent());
}
rtl::Reference<OpenGLContext> OpenGLContext::getVCLContext(bool bMakeIfNecessary)
{
ImplSVData* pSVData = ImplGetSVData();
OpenGLContext *pContext = pSVData->maGDIData.mpLastContext;
while( pContext )
{
// check if this context is usable
if( pContext->isInitialized() && pContext->isVCLOnly() )
break;
pContext = pContext->mpPrevContext;
}
rtl::Reference<OpenGLContext> xContext;
vcl::Window* pDefWindow = !pContext && bMakeIfNecessary ? ImplGetDefaultWindow() : nullptr;
if (pDefWindow)
{
// create our magic fallback window context.
#if HAVE_FEATURE_OPENGL
xContext = pDefWindow->GetGraphics()->GetOpenGLContext();
assert(xContext.is());
#endif
}
else
xContext = pContext;
if( xContext.is() )
xContext->makeCurrent();
return xContext;
}
/*
* We don't care what context we have, but we want one that is live,
* ie. not reset underneath us, and is setup for VCL usage - ideally
* not swapping context at all.
*/
void OpenGLContext::makeVCLCurrent()
{
getVCLContext();
}
void OpenGLContext::registerAsCurrent()
{
ImplSVData* pSVData = ImplGetSVData();
@@ -525,9 +439,6 @@ void OpenGLContext::registerAsCurrent()
pSVData->maGDIData.mpLastContext->mpNextContext = this;
pSVData->maGDIData.mpLastContext = this;
}
// sync the render state with the current context
mpRenderState->sync();
}
void OpenGLContext::resetCurrent()
@@ -584,226 +495,4 @@ const SystemChildWindow* OpenGLContext::getChildWindow() const
return m_pChildWindow;
}
void OpenGLContext::BindFramebuffer( OpenGLFramebuffer* pFramebuffer )
{
OpenGLZone aZone;
if( pFramebuffer != mpCurrentFramebuffer )
{
if( pFramebuffer )
pFramebuffer->Bind();
else
OpenGLFramebuffer::Unbind();
mpCurrentFramebuffer = pFramebuffer;
}
}
void OpenGLContext::AcquireDefaultFramebuffer()
{
BindFramebuffer( nullptr );
}
OpenGLFramebuffer* OpenGLContext::AcquireFramebuffer( const OpenGLTexture& rTexture )
{
OpenGLZone aZone;
OpenGLFramebuffer* pFramebuffer = nullptr;
OpenGLFramebuffer* pFreeFbo = nullptr;
OpenGLFramebuffer* pSameSizeFbo = nullptr;
// check if there is already a framebuffer attached to that texture
pFramebuffer = mpLastFramebuffer;
while( pFramebuffer )
{
if( pFramebuffer->IsAttached( rTexture ) )
break;
if( !pFreeFbo && pFramebuffer->IsFree() )
pFreeFbo = pFramebuffer;
if( !pSameSizeFbo &&
pFramebuffer->GetWidth() == rTexture.GetWidth() &&
pFramebuffer->GetHeight() == rTexture.GetHeight() )
pSameSizeFbo = pFramebuffer;
pFramebuffer = pFramebuffer->mpPrevFramebuffer;
}
// else use any framebuffer having the same size
if( !pFramebuffer && pSameSizeFbo )
pFramebuffer = pSameSizeFbo;
// else use the first free framebuffer
if( !pFramebuffer && pFreeFbo )
pFramebuffer = pFreeFbo;
// if there isn't any free one, create a new one if the limit isn't reached
if( !pFramebuffer && mnFramebufferCount < MAX_FRAMEBUFFER_COUNT )
{
mnFramebufferCount++;
pFramebuffer = new OpenGLFramebuffer();
if( mpLastFramebuffer )
{
pFramebuffer->mpPrevFramebuffer = mpLastFramebuffer;
mpLastFramebuffer = pFramebuffer;
}
else
{
mpFirstFramebuffer = pFramebuffer;
mpLastFramebuffer = pFramebuffer;
}
}
// last try, use any framebuffer
// TODO order the list of framebuffers as a LRU
if( !pFramebuffer )
pFramebuffer = mpFirstFramebuffer;
assert( pFramebuffer );
BindFramebuffer( pFramebuffer );
pFramebuffer->AttachTexture( rTexture );
state().viewport(tools::Rectangle(Point(), Size(rTexture.GetWidth(), rTexture.GetHeight())));
return pFramebuffer;
}
// FIXME: this method is rather grim from a perf. perspective.
// We should instead (eventually) use pointers to associate the
// framebuffer and texture cleanly.
void OpenGLContext::UnbindTextureFromFramebuffers( GLuint nTexture )
{
OpenGLFramebuffer* pFramebuffer;
// see if there is a framebuffer attached to that texture
pFramebuffer = mpLastFramebuffer;
while( pFramebuffer )
{
if (pFramebuffer->IsAttached(nTexture))
{
BindFramebuffer(pFramebuffer);
pFramebuffer->DetachTexture();
}
pFramebuffer = pFramebuffer->mpPrevFramebuffer;
}
// Lets just check that no other context has a framebuffer
// with this texture - that would be bad ...
assert( !IsTextureAttachedAnywhere( nTexture ) );
}
/// Method for debugging; check texture is not already attached.
bool OpenGLContext::IsTextureAttachedAnywhere( GLuint nTexture )
{
ImplSVData* pSVData = ImplGetSVData();
for( auto *pCheck = pSVData->maGDIData.mpLastContext; pCheck;
pCheck = pCheck->mpPrevContext )
{
for( auto pBuffer = pCheck->mpLastFramebuffer; pBuffer;
pBuffer = pBuffer->mpPrevFramebuffer )
{
if( pBuffer->IsAttached( nTexture ) )
return true;
}
}
return false;
}
void OpenGLContext::ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer )
{
if( pFramebuffer )
pFramebuffer->DetachTexture();
}
void OpenGLContext::ReleaseFramebuffer( const OpenGLTexture& rTexture )
{
OpenGLZone aZone;
if (!rTexture) // no texture to release.
return;
OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer;
while( pFramebuffer )
{
if( pFramebuffer->IsAttached( rTexture ) )
{
BindFramebuffer( pFramebuffer );
pFramebuffer->DetachTexture();
if (mpCurrentFramebuffer == pFramebuffer)
BindFramebuffer( nullptr );
}
pFramebuffer = pFramebuffer->mpPrevFramebuffer;
}
}
void OpenGLContext::ReleaseFramebuffers()
{
OpenGLZone aZone;
OpenGLFramebuffer* pFramebuffer = mpLastFramebuffer;
while( pFramebuffer )
{
if (!pFramebuffer->IsFree())
{
BindFramebuffer( pFramebuffer );
pFramebuffer->DetachTexture();
}
pFramebuffer = pFramebuffer->mpPrevFramebuffer;
}
BindFramebuffer( nullptr );
}
OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
{
OpenGLZone aZone;
// We cache the shader programs in a per-process run-time cache
// based on only the names and the preamble. We don't expect
// shader source files to change during the lifetime of a
// LibreOffice process.
OString aNameBasedKey = OUStringToOString(rVertexShader + "+" + rFragmentShader, RTL_TEXTENCODING_UTF8) + "+" + preamble;
if( !aNameBasedKey.isEmpty() )
{
ProgramCollection::iterator it = maPrograms.find( aNameBasedKey );
if( it != maPrograms.end() )
return it->second.get();
}
// Binary shader programs are cached persistently (between
// LibreOffice process instances) based on a hash of their source
// code, as the source code can and will change between
// LibreOffice versions even if the shader names don't change.
OString aPersistentKey = OpenGLHelper::GetDigest( rVertexShader, rFragmentShader, preamble );
std::shared_ptr<OpenGLProgram> pProgram = std::make_shared<OpenGLProgram>();
if( !pProgram->Load( rVertexShader, rFragmentShader, preamble, aPersistentKey ) )
return nullptr;
maPrograms.insert(std::make_pair(aNameBasedKey, pProgram));
return pProgram.get();
}
OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
{
OpenGLZone aZone;
OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader, preamble );
if (pProgram && pProgram == mpCurrentProgram)
{
VCL_GL_INFO("Context::UseProgram: Reusing existing program " << pProgram->Id());
pProgram->Reuse();
return pProgram;
}
mpCurrentProgram = pProgram;
if (!mpCurrentProgram)
{
SAL_WARN("vcl.opengl", "OpenGLContext::UseProgram: mpCurrentProgram is 0");
return nullptr;
}
mpCurrentProgram->Use();
return mpCurrentProgram;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-25
View File
@@ -884,26 +884,6 @@ const CrashWatchdogTimingsValues& OpenGLZone::getCrashWatchdogTimingsValues()
return gWatchdogTimings.getWatchdogTimingsValues(eMode);
}
OpenGLVCLContextZone::OpenGLVCLContextZone()
{
OpenGLContext::makeVCLCurrent();
}
namespace
{
bool bTempOpenGLDisabled = false;
}
PreDefaultWinNoOpenGLZone::PreDefaultWinNoOpenGLZone()
{
bTempOpenGLDisabled = true;
}
PreDefaultWinNoOpenGLZone::~PreDefaultWinNoOpenGLZone()
{
bTempOpenGLDisabled = false;
}
static void reapGlxTest()
{
// Reap the glxtest child, or it'll stay around as a zombie,
@@ -938,11 +918,6 @@ bool OpenGLHelper::isVCLOpenGLEnabled()
if (Application::IsBitmapRendering())
return false;
//tdf#106155, disable GL while loading certain bitmaps needed for the initial toplevel windows
//under raw X (kde) vclplug
if (bTempOpenGLDisabled)
return false;
if (bSet)
{
return bForceOpenGL || bEnable;
+1 -4
View File
@@ -697,10 +697,7 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
return;
}
// we need to make sure OpenGL never reaches this slow code path
#if HAVE_FEATURE_OPENGL
assert(!OpenGLHelper::isVCLOpenGLEnabled());
#endif
// we need to make sure Skia never reaches this slow code path
assert(!SkiaHelper::isVCLSkiaEnabled());
}
-8
View File
@@ -871,14 +871,6 @@ void OutputDevice::DrawText( const Point& rStartPt, const OUString& rStr,
if(mpFontInstance->mpConversion)
pLayoutCache = nullptr;
#ifdef MACOSX
// FIXME: tdf#112990
// Cache text layout crashes on mac with OpenGL enabled
// Force it to not use the cache
if(OpenGLHelper::isVCLOpenGLEnabled())
pLayoutCache = nullptr;
#endif
std::unique_ptr<SalLayout> pSalLayout = ImplLayout(rStr, nIndex, nLen, rStartPt, 0, nullptr, eDefaultLayout, nullptr, pLayoutCache);
if(pSalLayout)
{
+1 -10
View File
@@ -516,17 +516,8 @@ void Window::ImplCallResize()
{
mpWindowImpl->mbCallResize = false;
// OpenGL has a charming feature of black clearing the whole window
// some legacy code eg. the app-menu has the beautiful feature of
// avoiding re-paints when width doesn't change => invalidate all.
#if HAVE_FEATURE_OPENGL
if( OpenGLWrapper::isVCLOpenGLEnabled() )
Invalidate();
// Normally we avoid blanking on re-size unless people might notice:
else
#endif
if( GetBackground().IsGradient() )
if( GetBackground().IsGradient() )
Invalidate();
Resize();
-7
View File
@@ -721,13 +721,6 @@ void StatusBar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle
// Do offscreen only when we are not recording layout...
bool bOffscreen = !rRenderContext.ImplIsRecordLayout();
// tdf#94213 - un-necessary virtual-device in GL mode
// causes context switch & hence flicker during sizing.
#if HAVE_FEATURE_OPENGL
if( OpenGLWrapper::isVCLOpenGLEnabled() )
bOffscreen = false;
#endif
if (!bOffscreen)
rRenderContext.Erase(rRect);
-5
View File
@@ -40,8 +40,6 @@
#include <unx/x11/xlimits.hxx>
#include <o3tl/safeint.hxx>
#include <opengl/salbmp.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <config_features.h>
#if HAVE_FEATURE_SKIA
@@ -63,9 +61,6 @@ std::shared_ptr<SalBitmap> X11SalInstance::CreateSalBitmap()
return std::make_shared<SkiaSalBitmap>();
else
#endif
if (OpenGLHelper::isVCLOpenGLEnabled())
return std::make_shared<OpenGLSalBitmap>();
else
return std::make_shared<X11SalBitmap>();
}
+3 -14
View File
@@ -44,16 +44,12 @@
#include <textrender.hxx>
#include <salvd.hxx>
#include "gdiimpl.hxx"
#include <opengl/x11/gdiimpl.hxx>
#include <unx/x11/x11cairotextrender.hxx>
#include <opengl/x11/cairotextrender.hxx>
#include <unx/x11/x11cairotextrender.hxx>
#include <unx/x11/xrender_peer.hxx>
#include "cairo_xlib_cairo.hxx"
#include <cairo-xlib.h>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <config_features.h>
#include <vcl/skia/SkiaHelper.hxx>
#if HAVE_FEATURE_SKIA
@@ -79,7 +75,6 @@ X11SalGraphics::X11SalGraphics():
hBrush_(None),
bWindow_(false),
bVirDev_(false),
m_bOpenGL(OpenGLHelper::isVCLOpenGLEnabled()),
m_bSkia(SkiaHelper::isVCLSkiaEnabled())
{
#if HAVE_FEATURE_SKIA
@@ -90,12 +85,6 @@ X11SalGraphics::X11SalGraphics():
}
else
#endif
if (m_bOpenGL)
{
mxImpl.reset(new X11OpenGLSalGraphicsImpl(*this));
mxTextRenderImpl.reset(new OpenGLX11CairoTextRender(*this));
}
else
{
mxTextRenderImpl.reset(new X11CairoTextRender(*this));
mxImpl.reset(new X11SalGraphicsImpl(*this));
@@ -608,7 +597,7 @@ bool X11SalGraphics::drawPolyPolygon(
// enable by setting to something
static const char* pUseCairoForPolygons(getenv("SAL_ENABLE_USE_CAIRO_FOR_POLYGONS"));
if (!m_bOpenGL && !m_bSkia && nullptr != pUseCairoForPolygons && SupportsCairo())
if (!m_bSkia && nullptr != pUseCairoForPolygons && SupportsCairo())
{
// snap to raster if requested
const bool bSnapPoints(!getAntiAlias());
@@ -729,7 +718,7 @@ bool X11SalGraphics::drawPolyLine(
// disable by setting to something
static const char* pUseCairoForFatLines(getenv("SAL_DISABLE_USE_CAIRO_FOR_FATLINES"));
if (!m_bOpenGL && !m_bSkia && nullptr == pUseCairoForFatLines && SupportsCairo())
if (!m_bSkia && nullptr == pUseCairoForFatLines && SupportsCairo())
{
cairo_t* cr = getCairoContext();
clipRegion(cr);
-4
View File
@@ -29,7 +29,6 @@
#include <unx/x11/xlimits.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <opengl/x11/salvd.hxx>
#include <config_features.h>
#include <vcl/skia/SkiaHelper.hxx>
@@ -47,9 +46,6 @@ std::unique_ptr<SalVirtualDevice> X11SalInstance::CreateX11VirtualDevice(SalGrap
return std::unique_ptr<SalVirtualDevice>(new X11SkiaSalVirtualDevice( pGraphics, nDX, nDY, pData, std::move(pNewGraphics) ));
else
#endif
if (OpenGLHelper::isVCLOpenGLEnabled())
return std::unique_ptr<SalVirtualDevice>(new X11OpenGLSalVirtualDevice( pGraphics, nDX, nDY, pData, std::move(pNewGraphics) ));
else
return std::unique_ptr<SalVirtualDevice>(new X11SalVirtualDevice(pGraphics, nDX, nDY, eFormat, pData, std::move(pNewGraphics)));
}
-2
View File
@@ -301,8 +301,6 @@ static bool lcl_SelectAppIconPixmap( SalDisplay const *pDisplay, SalX11Screen nX
sal_uInt16 nIcon, sal_uInt16 iconSize,
Pixmap& icon_pixmap, Pixmap& icon_mask, NetWmIconData& netwm_icon)
{
PreDefaultWinNoOpenGLZone aGuard;
CreateNetWmAppIcon( nIcon, netwm_icon );
OUString sIcon;
-6
View File
@@ -31,13 +31,10 @@
#include <o3tl/char16_t2wchar_t.hxx>
#include <vcl/inputtypes.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/timer.hxx>
#include <vclpluginapi.h>
#include <opengl/salbmp.hxx>
#include <opengl/win/gdiimpl.hxx>
#include <win/wincomp.hxx>
#include <win/salids.hrc>
#include <win/saldata.hxx>
@@ -991,9 +988,6 @@ std::shared_ptr<SalBitmap> WinSalInstance::CreateSalBitmap()
return std::make_shared<SkiaSalBitmap>();
else
#endif
if (OpenGLHelper::isVCLOpenGLEnabled())
return std::make_shared<OpenGLSalBitmap>();
else
return std::make_shared<WinSalBitmap>();
}
+1 -10
View File
@@ -790,15 +790,6 @@ void ImplGetLogFontFromFontSelect( HDC hDC,
| ImplFamilyToWin( rFont.GetFamilyType() );
}
static BYTE nDefaultQuality = NONANTIALIASED_QUALITY;
if (nDefaultQuality == NONANTIALIASED_QUALITY)
{
if (OpenGLWrapper::isVCLOpenGLEnabled())
nDefaultQuality = ANTIALIASED_QUALITY;
else
nDefaultQuality = DEFAULT_QUALITY;
}
rLogFont.lfWeight = ImplWeightToWin( rFont.GetWeight() );
rLogFont.lfHeight = static_cast<LONG>(-rFont.mnHeight);
rLogFont.lfWidth = static_cast<LONG>(rFont.mnWidth);
@@ -808,7 +799,7 @@ void ImplGetLogFontFromFontSelect( HDC hDC,
rLogFont.lfEscapement = rFont.mnOrientation.get();
rLogFont.lfOrientation = rLogFont.lfEscapement;
rLogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
rLogFont.lfQuality = nDefaultQuality;
rLogFont.lfQuality = DEFAULT_QUALITY;
rLogFont.lfOutPrecision = OUT_TT_PRECIS;
if ( rFont.mnOrientation )
rLogFont.lfClipPrecision |= CLIP_LH_ANGLES;
-8
View File
@@ -34,9 +34,6 @@
#include <salgdiimpl.hxx>
#include "gdiimpl.hxx"
#include <opengl/win/gdiimpl.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <config_features.h>
#include <vcl/skia/SkiaHelper.hxx>
@@ -553,8 +550,6 @@ std::unique_ptr< CompatibleDC > CompatibleDC::create(SalGraphics &rGraphics, int
if (SkiaHelper::isVCLSkiaEnabled())
return std::make_unique< SkiaCompatibleDC >( rGraphics, x, y, width, height );
#endif
if (OpenGLHelper::isVCLOpenGLEnabled())
return std::make_unique< OpenGLCompatibleDC >( rGraphics, x, y, width, height );
return std::unique_ptr< CompatibleDC >( new CompatibleDC( rGraphics, x, y, width, height ));
}
@@ -626,9 +621,6 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hW
mpImpl.reset(new WinSkiaSalGraphicsImpl(*this, pProvider));
else
#endif
if (OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter)
mpImpl.reset(new WinOpenGLSalGraphicsImpl(*this, pProvider));
else
mpImpl.reset(new WinSalGraphicsImpl(*this));
}
+6 -13
View File
@@ -29,7 +29,6 @@
#include <win/salids.hrc>
#include <win/salgdi.h>
#include <win/salframe.h>
#include <opengl/salbmp.hxx>
#include <vcl/BitmapAccessMode.hxx>
#include <vcl/BitmapBuffer.hxx>
@@ -38,7 +37,6 @@
#include <vcl/bitmapaccess.hxx>
#include <outdata.hxx>
#include <salgdiimpl.hxx>
#include <opengl/win/gdiimpl.hxx>
#include <config_features.h>
#if HAVE_FEATURE_SKIA
@@ -109,11 +107,6 @@ public:
void convertToWinSalBitmap(SalBitmap& rSalBitmap, WinSalBitmap& rWinSalBitmap)
{
BitmapPalette aBitmapPalette;
OpenGLSalBitmap* pGLSalBitmap = dynamic_cast<OpenGLSalBitmap*>(&rSalBitmap);
if (pGLSalBitmap != nullptr)
{
aBitmapPalette = pGLSalBitmap->GetBitmapPalette();
}
#if HAVE_FEATURE_SKIA
if(SkiaSalBitmap* pSkiaSalBitmap = dynamic_cast<SkiaSalBitmap*>(&rSalBitmap))
aBitmapPalette = pSkiaSalBitmap->Palette();
@@ -168,11 +161,11 @@ void convertToWinSalBitmap(SalBitmap& rSalBitmap, WinSalBitmap& rWinSalBitmap)
void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap)
{
if (dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()) == nullptr &&
if (dynamic_cast<const WinSalBitmap*>(&rSalBitmap) == nullptr
#if HAVE_FEATURE_SKIA
dynamic_cast<WinSkiaSalGraphicsImpl*>(mpImpl.get()) == nullptr &&
&& dynamic_cast<WinSkiaSalGraphicsImpl*>(mpImpl.get()) == nullptr
#endif
dynamic_cast<const WinSalBitmap*>(&rSalBitmap) == nullptr)
)
{
std::unique_ptr<WinSalBitmap> pWinSalBitmap(new WinSalBitmap());
SalBitmap& rConstBitmap = const_cast<SalBitmap&>(rSalBitmap);
@@ -189,11 +182,11 @@ void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
const SalBitmap& rSSalBitmap,
const SalBitmap& rSTransparentBitmap )
{
if (dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()) == nullptr &&
if (dynamic_cast<const WinSalBitmap*>(&rSSalBitmap) == nullptr
#if HAVE_FEATURE_SKIA
dynamic_cast<WinSkiaSalGraphicsImpl*>(mpImpl.get()) == nullptr &&
&& dynamic_cast<WinSkiaSalGraphicsImpl*>(mpImpl.get()) == nullptr
#endif
dynamic_cast<const WinSalBitmap*>(&rSSalBitmap) == nullptr)
)
{
std::unique_ptr<WinSalBitmap> pWinSalBitmap(new WinSalBitmap());
SalBitmap& rConstBitmap = const_cast<SalBitmap&>(rSSalBitmap);
+1 -1
View File
@@ -37,7 +37,6 @@
#include <osl/module.h>
#include <o3tl/char16_t2wchar_t.hxx>
#include <opengl/win/gdiimpl.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
@@ -45,6 +44,7 @@
#include <win/salgdi.h>
#include <win/saldata.hxx>
#include <win/scoped_gdi.hxx>
#include <win/wingdiimpl.hxx>
#include <uxtheme.h>
#include <vssym32.h>
-1
View File
@@ -28,7 +28,6 @@
#include <win/salinst.h>
#include <win/salgdi.h>
#include <win/salvd.h>
#include <opengl/win/gdiimpl.hxx>
#include <sal/log.hxx>
#include <o3tl/temporary.hxx>
-5
View File
@@ -30,9 +30,6 @@
#include <comphelper/windowserrorstring.hxx>
#include <comphelper/scopeguard.hxx>
#include <opengl/win/gdiimpl.hxx>
#include <opengl/win/winlayout.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <win/salgdi.h>
#include <win/saldata.hxx>
@@ -61,8 +58,6 @@ GlobalWinGlyphCache* GlobalWinGlyphCache::get()
SalData* data = GetSalData();
if (!data->m_pGlobalWinGlyphCache)
{
if (OpenGLHelper::isVCLOpenGLEnabled())
data->m_pGlobalWinGlyphCache.reset(new OpenGLGlobalWinGlyphCache);
}
return data->m_pGlobalWinGlyphCache.get();
}

Some files were not shown because too many files have changed in this diff Show More