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:
@@ -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:
|
||||
|
||||
@@ -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" );
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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:
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -154,7 +154,6 @@ struct CompatibleDC::Texture
|
||||
class WinSalGraphics : public SalGraphics
|
||||
{
|
||||
friend class WinSalGraphicsImpl;
|
||||
friend class WinOpenGLSalGraphicsImpl;
|
||||
friend class ScopedFont;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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
@@ -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: */
|
||||
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
@@ -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: */
|
||||
|
||||
@@ -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: */
|
||||
@@ -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());
|
||||
|
||||
@@ -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"}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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&)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */,
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user