From 0b04e1608add515919e2987f34b679be1b46e75a Mon Sep 17 00:00:00 2001 From: domrjchen Date: Fri, 6 Oct 2023 23:25:01 +0800 Subject: [PATCH] Merge GLFragmentProcessor into FragmentProcessor. --- tgfx/src/gpu/AARectEffect.cpp | 9 - tgfx/src/gpu/AARectEffect.h | 6 +- tgfx/src/gpu/ColorMatrixFragmentProcessor.cpp | 10 - tgfx/src/gpu/ColorMatrixFragmentProcessor.h | 6 +- tgfx/src/gpu/ConstColorProcessor.cpp | 9 - tgfx/src/gpu/ConstColorProcessor.h | 6 +- tgfx/src/gpu/DeviceSpaceTextureEffect.cpp | 14 -- tgfx/src/gpu/DeviceSpaceTextureEffect.h | 6 +- tgfx/src/gpu/DualBlurFragmentProcessor.cpp | 15 -- tgfx/src/gpu/DualBlurFragmentProcessor.h | 6 +- tgfx/src/gpu/EllipseGeometryProcessor.cpp | 1 - tgfx/src/gpu/EmptyXferProcessor.cpp | 1 - tgfx/src/gpu/FragmentProcessor.cpp | 78 ++++++-- tgfx/src/gpu/FragmentProcessor.h | 119 +++++++++++- tgfx/src/gpu/GLFragmentProcessor.cpp | 102 ---------- tgfx/src/gpu/GLFragmentProcessor.h | 183 ------------------ tgfx/src/gpu/GeometryProcessor.h | 7 - tgfx/src/gpu/LumaColorFilterEffect.cpp | 26 --- tgfx/src/gpu/LumaColorFilterEffect.h | 11 +- tgfx/src/gpu/PorterDuffXferProcessor.cpp | 1 - tgfx/src/gpu/ProgramBuilder.cpp | 24 +-- tgfx/src/gpu/ProgramBuilder.h | 6 +- .../gpu/QuadPerEdgeAAGeometryProcessor.cpp | 1 - tgfx/src/gpu/SeriesFragmentProcessor.cpp | 16 -- tgfx/src/gpu/SeriesFragmentProcessor.h | 6 +- tgfx/src/gpu/TextureEffect.cpp | 28 --- tgfx/src/gpu/TextureEffect.h | 6 +- tgfx/src/gpu/TiledTextureEffect.cpp | 29 --- tgfx/src/gpu/TiledTextureEffect.h | 19 +- tgfx/src/gpu/XferProcessor.h | 2 - tgfx/src/gpu/XfermodeFragmentProcessor.cpp | 24 --- tgfx/src/gpu/XfermodeFragmentProcessor.h | 6 +- tgfx/src/gpu/YUVTextureEffect.cpp | 5 - tgfx/src/gpu/YUVTextureEffect.h | 6 +- .../gpu/gradients/ClampedGradientEffect.cpp | 13 -- .../src/gpu/gradients/ClampedGradientEffect.h | 6 +- .../DualIntervalGradientColorizer.cpp | 29 --- .../gradients/DualIntervalGradientColorizer.h | 6 +- .../gpu/gradients/LinearGradientLayout.cpp | 9 - tgfx/src/gpu/gradients/LinearGradientLayout.h | 4 +- .../gpu/gradients/RadialGradientLayout.cpp | 9 - tgfx/src/gpu/gradients/RadialGradientLayout.h | 4 +- .../SingleIntervalGradientColorizer.cpp | 11 -- .../SingleIntervalGradientColorizer.h | 6 +- .../src/gpu/gradients/SweepGradientLayout.cpp | 10 - tgfx/src/gpu/gradients/SweepGradientLayout.h | 6 +- .../gradients/TextureGradientColorizer.cpp | 11 -- .../gpu/gradients/TextureGradientColorizer.h | 6 +- .../UnrolledBinaryGradientColorizer.cpp | 70 ------- .../UnrolledBinaryGradientColorizer.h | 6 +- tgfx/src/opengl/GLAARectEffect.cpp | 17 +- tgfx/src/opengl/GLAARectEffect.h | 10 +- tgfx/src/opengl/GLClampedGradientEffect.cpp | 33 +++- tgfx/src/opengl/GLClampedGradientEffect.h | 12 +- .../opengl/GLColorMatrixFragmentProcessor.cpp | 32 +-- .../opengl/GLColorMatrixFragmentProcessor.h | 10 +- tgfx/src/opengl/GLConstColorProcessor.cpp | 19 +- tgfx/src/opengl/GLConstColorProcessor.h | 10 +- .../src/opengl/GLDeviceSpaceTextureEffect.cpp | 26 ++- tgfx/src/opengl/GLDeviceSpaceTextureEffect.h | 10 +- .../opengl/GLDualBlurFragmentProcessor.cpp | 29 ++- tgfx/src/opengl/GLDualBlurFragmentProcessor.h | 12 +- .../GLDualIntervalGradientColorizer.cpp | 46 ++++- .../opengl/GLDualIntervalGradientColorizer.h | 11 +- .../src/opengl/GLEllipseGeometryProcessor.cpp | 1 - tgfx/src/opengl/GLLinearGradientLayout.cpp | 9 +- tgfx/src/opengl/GLLinearGradientLayout.h | 8 +- tgfx/src/opengl/GLLumaColorFilterEffect.cpp | 6 +- tgfx/src/opengl/GLLumaColorFilterEffect.h | 6 +- tgfx/src/opengl/GLProgram.cpp | 10 +- tgfx/src/opengl/GLProgram.h | 4 +- tgfx/src/opengl/GLProgramBuilder.cpp | 4 +- tgfx/src/opengl/GLRadialGradientLayout.cpp | 9 +- tgfx/src/opengl/GLRadialGradientLayout.h | 8 +- tgfx/src/opengl/GLSeriesFragmentProcessor.cpp | 18 +- tgfx/src/opengl/GLSeriesFragmentProcessor.h | 8 +- .../GLSingleIntervalGradientColorizer.cpp | 20 +- .../GLSingleIntervalGradientColorizer.h | 10 +- tgfx/src/opengl/GLSweepGradientLayout.cpp | 19 +- tgfx/src/opengl/GLSweepGradientLayout.h | 10 +- tgfx/src/opengl/GLTextureEffect.cpp | 44 ++++- tgfx/src/opengl/GLTextureEffect.h | 11 +- .../src/opengl/GLTextureGradientColorizer.cpp | 12 +- tgfx/src/opengl/GLTextureGradientColorizer.h | 8 +- tgfx/src/opengl/GLTiledTextureEffect.cpp | 130 +++++++------ tgfx/src/opengl/GLTiledTextureEffect.h | 20 +- .../GLUnrolledBinaryGradientColorizer.cpp | 161 ++++++++++----- .../GLUnrolledBinaryGradientColorizer.h | 11 +- .../opengl/GLXfermodeFragmentProcessor.cpp | 43 +++- tgfx/src/opengl/GLXfermodeFragmentProcessor.h | 9 +- tgfx/src/opengl/GLYUVTextureEffect.cpp | 31 +-- tgfx/src/opengl/GLYUVTextureEffect.h | 11 +- 92 files changed, 835 insertions(+), 1083 deletions(-) delete mode 100644 tgfx/src/gpu/GLFragmentProcessor.cpp delete mode 100644 tgfx/src/gpu/GLFragmentProcessor.h delete mode 100644 tgfx/src/gpu/LumaColorFilterEffect.cpp diff --git a/tgfx/src/gpu/AARectEffect.cpp b/tgfx/src/gpu/AARectEffect.cpp index cc2053e950..5c6ca8d402 100644 --- a/tgfx/src/gpu/AARectEffect.cpp +++ b/tgfx/src/gpu/AARectEffect.cpp @@ -17,18 +17,9 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "AARectEffect.h" -#include "opengl/GLAARectEffect.h" namespace tgfx { -std::unique_ptr AARectEffect::Make(const Rect& rect) { - return std::unique_ptr(new AARectEffect(rect)); -} - bool AARectEffect::onIsEqual(const FragmentProcessor& processor) const { return rect == static_cast(processor).rect; } - -std::unique_ptr AARectEffect::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/AARectEffect.h b/tgfx/src/gpu/AARectEffect.h index d62a1e4d0e..564f25f07d 100644 --- a/tgfx/src/gpu/AARectEffect.h +++ b/tgfx/src/gpu/AARectEffect.h @@ -29,7 +29,7 @@ class AARectEffect : public FragmentProcessor { return "AARectEffect"; } - private: + protected: DEFINE_PROCESSOR_CLASS_ID explicit AARectEffect(const Rect& rect) : FragmentProcessor(ClassID()), rect(rect) { @@ -37,10 +37,6 @@ class AARectEffect : public FragmentProcessor { bool onIsEqual(const FragmentProcessor& processor) const override; - std::unique_ptr onCreateGLInstance() const override; - Rect rect = Rect::MakeEmpty(); - - friend class GLAARectEffect; }; } // namespace tgfx diff --git a/tgfx/src/gpu/ColorMatrixFragmentProcessor.cpp b/tgfx/src/gpu/ColorMatrixFragmentProcessor.cpp index 550489e5dc..67d2f547fd 100644 --- a/tgfx/src/gpu/ColorMatrixFragmentProcessor.cpp +++ b/tgfx/src/gpu/ColorMatrixFragmentProcessor.cpp @@ -17,19 +17,9 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/ColorMatrixFragmentProcessor.h" -#include "opengl/GLColorMatrixFragmentProcessor.h" namespace tgfx { -std::unique_ptr ColorMatrixFragmentProcessor::Make( - const std::array& matrix) { - return std::unique_ptr(new ColorMatrixFragmentProcessor(matrix)); -} - bool ColorMatrixFragmentProcessor::onIsEqual(const FragmentProcessor& processor) const { return matrix == static_cast(processor).matrix; } - -std::unique_ptr ColorMatrixFragmentProcessor::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/ColorMatrixFragmentProcessor.h b/tgfx/src/gpu/ColorMatrixFragmentProcessor.h index 702aad3b18..dfa0332b98 100644 --- a/tgfx/src/gpu/ColorMatrixFragmentProcessor.h +++ b/tgfx/src/gpu/ColorMatrixFragmentProcessor.h @@ -30,9 +30,7 @@ class ColorMatrixFragmentProcessor : public FragmentProcessor { return "ColorMatrixFragmentProcessor"; } - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID explicit ColorMatrixFragmentProcessor(const std::array& matrix) @@ -42,7 +40,5 @@ class ColorMatrixFragmentProcessor : public FragmentProcessor { bool onIsEqual(const FragmentProcessor& processor) const override; std::array matrix; - - friend class GLColorMatrixFragmentProcessor; }; } // namespace tgfx diff --git a/tgfx/src/gpu/ConstColorProcessor.cpp b/tgfx/src/gpu/ConstColorProcessor.cpp index d65403bead..241e6176b3 100644 --- a/tgfx/src/gpu/ConstColorProcessor.cpp +++ b/tgfx/src/gpu/ConstColorProcessor.cpp @@ -17,13 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/ConstColorProcessor.h" -#include "opengl/GLConstColorProcessor.h" namespace tgfx { -std::unique_ptr ConstColorProcessor::Make(Color color, InputMode mode) { - return std::unique_ptr(new ConstColorProcessor(color, mode)); -} - void ConstColorProcessor::onComputeProcessorKey(BytesKey* bytesKey) const { bytesKey->write(static_cast(inputMode)); } @@ -32,8 +27,4 @@ bool ConstColorProcessor::onIsEqual(const FragmentProcessor& processor) const { const auto& that = static_cast(processor); return inputMode == that.inputMode && color == that.color; } - -std::unique_ptr ConstColorProcessor::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/ConstColorProcessor.h b/tgfx/src/gpu/ConstColorProcessor.h index c8ad5b8bdb..62bd2f0958 100644 --- a/tgfx/src/gpu/ConstColorProcessor.h +++ b/tgfx/src/gpu/ConstColorProcessor.h @@ -34,9 +34,7 @@ class ConstColorProcessor : public FragmentProcessor { void onComputeProcessorKey(BytesKey* bytesKey) const override; - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID ConstColorProcessor(Color color, InputMode mode) @@ -47,7 +45,5 @@ class ConstColorProcessor : public FragmentProcessor { Color color; InputMode inputMode; - - friend class GLConstColorProcessor; }; } // namespace tgfx diff --git a/tgfx/src/gpu/DeviceSpaceTextureEffect.cpp b/tgfx/src/gpu/DeviceSpaceTextureEffect.cpp index 08e8d6d145..6180a80206 100644 --- a/tgfx/src/gpu/DeviceSpaceTextureEffect.cpp +++ b/tgfx/src/gpu/DeviceSpaceTextureEffect.cpp @@ -17,18 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "DeviceSpaceTextureEffect.h" -#include "opengl/GLDeviceSpaceTextureEffect.h" namespace tgfx { -std::unique_ptr DeviceSpaceTextureEffect::Make( - std::shared_ptr texture, ImageOrigin deviceOrigin) { - if (texture == nullptr) { - return nullptr; - } - return std::unique_ptr( - new DeviceSpaceTextureEffect(std::move(texture), deviceOrigin)); -} - DeviceSpaceTextureEffect::DeviceSpaceTextureEffect(std::shared_ptr texture, ImageOrigin deviceOrigin) : FragmentProcessor(ClassID()), texture(std::move(texture)) { @@ -46,8 +36,4 @@ bool DeviceSpaceTextureEffect::onIsEqual(const FragmentProcessor& processor) con const auto& that = static_cast(processor); return texture == that.texture && deviceCoordMatrix == that.deviceCoordMatrix; } - -std::unique_ptr DeviceSpaceTextureEffect::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/DeviceSpaceTextureEffect.h b/tgfx/src/gpu/DeviceSpaceTextureEffect.h index 7550b9e5b2..881a36b0e5 100644 --- a/tgfx/src/gpu/DeviceSpaceTextureEffect.h +++ b/tgfx/src/gpu/DeviceSpaceTextureEffect.h @@ -30,22 +30,18 @@ class DeviceSpaceTextureEffect : public FragmentProcessor { return "DeviceSpaceTextureEffect"; } - private: + protected: DEFINE_PROCESSOR_CLASS_ID DeviceSpaceTextureEffect(std::shared_ptr texture, ImageOrigin deviceOrigin); bool onIsEqual(const FragmentProcessor& processor) const override; - std::unique_ptr onCreateGLInstance() const override; - const TextureSampler* onTextureSampler(size_t) const override { return texture->getSampler(); } std::shared_ptr texture; Matrix deviceCoordMatrix = Matrix::I(); - - friend class GLDeviceSpaceTextureEffect; }; } // namespace tgfx diff --git a/tgfx/src/gpu/DualBlurFragmentProcessor.cpp b/tgfx/src/gpu/DualBlurFragmentProcessor.cpp index f5318f4f25..0b44e4f1c7 100644 --- a/tgfx/src/gpu/DualBlurFragmentProcessor.cpp +++ b/tgfx/src/gpu/DualBlurFragmentProcessor.cpp @@ -17,19 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/DualBlurFragmentProcessor.h" -#include "opengl/GLDualBlurFragmentProcessor.h" namespace tgfx { -std::unique_ptr DualBlurFragmentProcessor::Make( - DualBlurPassMode passMode, std::unique_ptr processor, Point blurOffset, - Point texelSize) { - if (processor == nullptr) { - return nullptr; - } - return std::unique_ptr( - new DualBlurFragmentProcessor(passMode, std::move(processor), blurOffset, texelSize)); -} - DualBlurFragmentProcessor::DualBlurFragmentProcessor(DualBlurPassMode passMode, std::unique_ptr processor, Point blurOffset, Point texelSize) @@ -48,8 +37,4 @@ bool DualBlurFragmentProcessor::onIsEqual(const FragmentProcessor& processor) co const auto& that = static_cast(processor); return passMode == that.passMode && blurOffset == that.blurOffset && texelSize == that.texelSize; } - -std::unique_ptr DualBlurFragmentProcessor::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/DualBlurFragmentProcessor.h b/tgfx/src/gpu/DualBlurFragmentProcessor.h index d2e32d7f99..242f03a043 100644 --- a/tgfx/src/gpu/DualBlurFragmentProcessor.h +++ b/tgfx/src/gpu/DualBlurFragmentProcessor.h @@ -35,9 +35,7 @@ class DualBlurFragmentProcessor : public FragmentProcessor { void onComputeProcessorKey(BytesKey* bytesKey) const override; - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID DualBlurFragmentProcessor(DualBlurPassMode passMode, std::unique_ptr processor, @@ -48,7 +46,5 @@ class DualBlurFragmentProcessor : public FragmentProcessor { DualBlurPassMode passMode; Point blurOffset; Point texelSize; - - friend class GLDualBlurFragmentProcessor; }; } // namespace tgfx diff --git a/tgfx/src/gpu/EllipseGeometryProcessor.cpp b/tgfx/src/gpu/EllipseGeometryProcessor.cpp index 5f539e2604..582d8c92db 100644 --- a/tgfx/src/gpu/EllipseGeometryProcessor.cpp +++ b/tgfx/src/gpu/EllipseGeometryProcessor.cpp @@ -17,7 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "EllipseGeometryProcessor.h" -#include "opengl/GLEllipseGeometryProcessor.h" namespace tgfx { EllipseGeometryProcessor::EllipseGeometryProcessor(int width, int height, bool stroke, diff --git a/tgfx/src/gpu/EmptyXferProcessor.cpp b/tgfx/src/gpu/EmptyXferProcessor.cpp index efcc0e1914..c9da02662f 100644 --- a/tgfx/src/gpu/EmptyXferProcessor.cpp +++ b/tgfx/src/gpu/EmptyXferProcessor.cpp @@ -17,7 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "EmptyXferProcessor.h" -#include "opengl/GLEmptyXferProcessor.h" namespace tgfx { void EmptyXferProcessor::computeProcessorKey(Context*, BytesKey* bytesKey) const { diff --git a/tgfx/src/gpu/FragmentProcessor.cpp b/tgfx/src/gpu/FragmentProcessor.cpp index 6baa4d8269..62c710d49c 100644 --- a/tgfx/src/gpu/FragmentProcessor.cpp +++ b/tgfx/src/gpu/FragmentProcessor.cpp @@ -17,7 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/FragmentProcessor.h" -#include "GLFragmentProcessor.h" #include "Pipeline.h" #include "SeriesFragmentProcessor.h" #include "gpu/XfermodeFragmentProcessor.h" @@ -70,14 +69,6 @@ void FragmentProcessor::computeProcessorKey(Context* context, BytesKey* bytesKey } } -std::unique_ptr FragmentProcessor::createGLInstance() const { - auto glFragProc = onCreateGLInstance(); - for (const auto& fChildProcessor : childProcessors) { - glFragProc->childProcessors.push_back(fChildProcessor->createGLInstance()); - } - return glFragProc; -} - size_t FragmentProcessor::registerChildProcessor(std::unique_ptr child) { auto index = childProcessors.size(); childProcessors.push_back(std::move(child)); @@ -171,7 +162,72 @@ std::unique_ptr FragmentProcessor::instantiate() { return nullptr; } -std::unique_ptr FragmentProcessorProxy::onCreateGLInstance() const { - return nullptr; +void FragmentProcessor::setData(UniformBuffer* uniformBuffer) const { + onSetData(uniformBuffer); +} + +void FragmentProcessor::emitChild(size_t childIndex, const std::string& inputColor, + std::string* outputColor, EmitArgs& args, + std::function coordFunc) const { + auto* fragBuilder = args.fragBuilder; + outputColor->append(fragBuilder->mangleString()); + fragBuilder->codeAppendf("vec4 %s;", outputColor->c_str()); + internalEmitChild(childIndex, inputColor, *outputColor, args, std::move(coordFunc)); +} + +void FragmentProcessor::emitChild(size_t childIndex, const std::string& inputColor, + EmitArgs& parentArgs) const { + internalEmitChild(childIndex, inputColor, parentArgs.outputColor, parentArgs); } + +void FragmentProcessor::internalEmitChild( + size_t childIndex, const std::string& inputColor, const std::string& outputColor, + EmitArgs& args, std::function coordFunc) const { + auto* fragBuilder = args.fragBuilder; + fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is updated + // Prepare a mangled input color variable if the default is not used, + // inputName remains the empty string if no variable is needed. + std::string inputName; + if (!inputColor.empty() && inputColor != "vec4(1.0)" && inputColor != "vec4(1)") { + // The input name is based off of the current mangle string, and + // since this is called after onBeforeChildProcEmitCode(), it will be + // unique to the child processor (exactly what we want for its input). + inputName += "_childInput"; + inputName += fragBuilder->mangleString(); + fragBuilder->codeAppendf("vec4 %s = %s;", inputName.c_str(), inputColor.c_str()); + } + + const auto* childProc = childProcessor(childIndex); + + // emit the code for the child in its own scope + fragBuilder->codeAppend("{\n"); + fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex, + fragBuilder->mangleString().c_str(), childProc->name().c_str()); + TransformedCoordVars coordVars = args.transformedCoords->childInputs(childIndex); + TextureSamplers textureSamplers = args.textureSamplers->childInputs(childIndex); + + EmitArgs childArgs(fragBuilder, args.uniformHandler, outputColor, + inputName.empty() ? "vec4(1.0)" : inputName, &coordVars, &textureSamplers, + std::move(coordFunc)); + childProcessor(childIndex)->emitCode(childArgs); + fragBuilder->codeAppend("}\n"); + + fragBuilder->onAfterChildProcEmitCode(); +} + +template +FragmentProcessor::BuilderInputProvider +FragmentProcessor::BuilderInputProvider::childInputs(size_t childIndex) const { + const FragmentProcessor* child = fragmentProcessor->childProcessor(childIndex); + FragmentProcessor::Iter iter(fragmentProcessor); + int numToSkip = 0; + while (true) { + const FragmentProcessor* processor = iter.next(); + if (processor == child) { + return BuilderInputProvider(child, t + numToSkip); + } + numToSkip += (processor->*COUNT)(); + } +} + } // namespace tgfx diff --git a/tgfx/src/gpu/FragmentProcessor.h b/tgfx/src/gpu/FragmentProcessor.h index 9640a2750c..3fb34c2fff 100644 --- a/tgfx/src/gpu/FragmentProcessor.h +++ b/tgfx/src/gpu/FragmentProcessor.h @@ -20,10 +20,13 @@ #include #include "CoordTransform.h" +#include "FragmentShaderBuilder.h" #include "Processor.h" #include "SamplerState.h" #include "TextureProxy.h" +#include "UniformHandler.h" #include "gpu/Texture.h" +#include "gpu/UniformBuffer.h" namespace tgfx { struct FPArgs { @@ -39,7 +42,6 @@ struct FPArgs { bool ComputeTotalInverse(const FPArgs& args, Matrix* totalInverse); class Pipeline; -class GLFragmentProcessor; class FragmentProcessor : public Processor { public: @@ -74,8 +76,6 @@ class FragmentProcessor : public Processor { static std::unique_ptr RunInSeries(std::unique_ptr* series, int count); - std::unique_ptr createGLInstance() const; - size_t numTextureSamplers() const { return textureSamplerCount; } @@ -151,6 +151,105 @@ class FragmentProcessor : public Processor { FragmentProcessor::Iter fpIter; }; + template + class BuilderInputProvider { + public: + BuilderInputProvider(const FragmentProcessor* fp, const T* t) : fragmentProcessor(fp), t(t) { + } + + const T& operator[](size_t i) const { + return t[i]; + } + + size_t count() const { + return (fragmentProcessor->*COUNT)(); + } + + BuilderInputProvider childInputs(size_t childIndex) const; + + private: + const FragmentProcessor* fragmentProcessor; + const T* t; + }; + + using TransformedCoordVars = + BuilderInputProvider; + using TextureSamplers = + BuilderInputProvider; + + struct EmitArgs { + EmitArgs(FragmentShaderBuilder* fragBuilder, UniformHandler* uniformHandler, + std::string outputColor, std::string inputColor, + const TransformedCoordVars* transformedCoords, const TextureSamplers* textureSamplers, + std::function coordFunc = {}) + : fragBuilder(fragBuilder), + uniformHandler(uniformHandler), + outputColor(std::move(outputColor)), + inputColor(std::move(inputColor)), + transformedCoords(transformedCoords), + textureSamplers(textureSamplers), + coordFunc(std::move(coordFunc)) { + } + /** + * Interface used to emit code in the shaders. + */ + FragmentShaderBuilder* fragBuilder; + UniformHandler* uniformHandler; + /** + * A predefined vec4 in the FS in which the stage should place its output color (or coverage). + */ + const std::string outputColor; + /** + * A vec4 that holds the input color to the stage in the FS. + */ + const std::string inputColor; + /** + * Fragment shader variables containing the coords computed using each of the + * FragmentProcessor's CoordTransforms. + */ + const TransformedCoordVars* transformedCoords; + /** + * Contains one entry for each TextureSampler of the Processor. These can be passed to the + * builder to emit texture reads in the generated code. + */ + const TextureSamplers* textureSamplers; + const std::function coordFunc; + }; + + /** + * Called when the program stage should insert its code into the shaders. The code in each shader + * will be in its own block ({}) and so locally scoped names will not collide across stages. + */ + virtual void emitCode(EmitArgs& args) const = 0; + + void setData(UniformBuffer* uniformBuffer) const; + + /** + * Emit the child with the default input color (solid white) + */ + void emitChild(size_t childIndex, std::string* outputColor, EmitArgs& parentArgs, + std::function coordFunc = {}) const { + emitChild(childIndex, "", outputColor, parentArgs, std::move(coordFunc)); + } + + /** + * Will emit the code of a child proc in its own scope. Pass in the parent's EmitArgs and + * emitChild will automatically extract the coords and samplers of that child and pass them + * on to the child's emitCode(). Also, any uniforms or functions emitted by the child will + * have their names mangled to prevent redefinitions. The output color name is also mangled + * therefore in an in/out param. It will be declared in mangled form by emitChild(). It is + * legal to pass empty string as inputColor, since all fragment processors are required to work + * without an input color. + */ + void emitChild(size_t childIndex, const std::string& inputColor, std::string* outputColor, + EmitArgs& parentArgs, + std::function coordFunc = {}) const; + + /** + * Variation that uses the parent's output color variable to hold the child's output. + */ + void emitChild(size_t childIndex, const std::string& inputColor, EmitArgs& parentArgs) const; + protected: explicit FragmentProcessor(uint32_t classID) : Processor(classID) { } @@ -187,12 +286,13 @@ class FragmentProcessor : public Processor { textureSamplerCount = count; } + virtual void onSetData(UniformBuffer*) const { + } + private: virtual void onComputeProcessorKey(BytesKey*) const { } - virtual std::unique_ptr onCreateGLInstance() const = 0; - virtual const TextureSampler* onTextureSampler(size_t) const { return nullptr; } @@ -208,10 +308,11 @@ class FragmentProcessor : public Processor { virtual void onVisitProxies(const std::function&) const { } - size_t textureSamplerCount = 0; + void internalEmitChild(size_t, const std::string&, const std::string&, EmitArgs&, + std::function = {}) const; + size_t textureSamplerCount = 0; std::vector coordTransforms; - std::vector> childProcessors; }; @@ -220,7 +321,7 @@ class FragmentProcessorProxy : public FragmentProcessor { explicit FragmentProcessorProxy(uint32_t classID) : FragmentProcessor(classID) { } - private: - std::unique_ptr onCreateGLInstance() const override; + void emitCode(EmitArgs&) const override { + } }; } // namespace tgfx diff --git a/tgfx/src/gpu/GLFragmentProcessor.cpp b/tgfx/src/gpu/GLFragmentProcessor.cpp deleted file mode 100644 index 2728cc772d..0000000000 --- a/tgfx/src/gpu/GLFragmentProcessor.cpp +++ /dev/null @@ -1,102 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////////////////////// -// -// Tencent is pleased to support the open source community by making libpag available. -// -// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. -// -// Licensed 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 -// -// unless required by applicable law or agreed to in writing, software distributed under the -// license is distributed on an "as is" basis, without warranties or conditions of any kind, -// either express or implied. see the license for the specific language governing permissions -// and limitations under the license. -// -///////////////////////////////////////////////////////////////////////////////////////////////// - -#include "GLFragmentProcessor.h" - -namespace tgfx { -void GLFragmentProcessor::setData(UniformBuffer* uniformBuffer, - const FragmentProcessor& processor) { - onSetData(uniformBuffer, processor); -} - -void GLFragmentProcessor::emitChild(size_t childIndex, const std::string& inputColor, - std::string* outputColor, EmitArgs& args, - std::function coordFunc) { - auto* fragBuilder = args.fragBuilder; - outputColor->append(fragBuilder->mangleString()); - fragBuilder->codeAppendf("vec4 %s;", outputColor->c_str()); - internalEmitChild(childIndex, inputColor, *outputColor, args, std::move(coordFunc)); -} - -void GLFragmentProcessor::emitChild(size_t childIndex, const std::string& inputColor, - EmitArgs& parentArgs) { - internalEmitChild(childIndex, inputColor, parentArgs.outputColor, parentArgs); -} - -void GLFragmentProcessor::internalEmitChild( - size_t childIndex, const std::string& inputColor, const std::string& outputColor, - EmitArgs& args, std::function coordFunc) { - auto* fragBuilder = args.fragBuilder; - fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is updated - // Prepare a mangled input color variable if the default is not used, - // inputName remains the empty string if no variable is needed. - std::string inputName; - if (!inputColor.empty() && inputColor != "vec4(1.0)" && inputColor != "vec4(1)") { - // The input name is based off of the current mangle string, and - // since this is called after onBeforeChildProcEmitCode(), it will be - // unique to the child processor (exactly what we want for its input). - inputName += "_childInput"; - inputName += fragBuilder->mangleString(); - fragBuilder->codeAppendf("vec4 %s = %s;", inputName.c_str(), inputColor.c_str()); - } - - const auto* childProc = args.fragmentProcessor->childProcessor(childIndex); - - // emit the code for the child in its own scope - fragBuilder->codeAppend("{\n"); - fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex, - fragBuilder->mangleString().c_str(), childProc->name().c_str()); - TransformedCoordVars coordVars = args.transformedCoords->childInputs(childIndex); - TextureSamplers textureSamplers = args.textureSamplers->childInputs(childIndex); - - EmitArgs childArgs(fragBuilder, args.uniformHandler, childProc, outputColor, - inputName.empty() ? "vec4(1.0)" : inputName, &coordVars, &textureSamplers, - std::move(coordFunc)); - childProcessor(childIndex)->emitCode(childArgs); - fragBuilder->codeAppend("}\n"); - - fragBuilder->onAfterChildProcEmitCode(); -} - -GLFragmentProcessor* GLFragmentProcessor::Iter::next() { - if (fpStack.empty()) { - return nullptr; - } - GLFragmentProcessor* back = fpStack.back(); - fpStack.pop_back(); - for (size_t i = 0; i < back->numChildProcessors(); ++i) { - fpStack.push_back(back->childProcessor(back->numChildProcessors() - 1 - i)); - } - return back; -} - -template -GLFragmentProcessor::BuilderInputProvider -GLFragmentProcessor::BuilderInputProvider::childInputs(size_t childIndex) const { - const FragmentProcessor* child = fragmentProcessor->childProcessor(childIndex); - FragmentProcessor::Iter iter(fragmentProcessor); - int numToSkip = 0; - while (true) { - const FragmentProcessor* processor = iter.next(); - if (processor == child) { - return BuilderInputProvider(child, t + numToSkip); - } - numToSkip += (processor->*COUNT)(); - } -} -} // namespace tgfx diff --git a/tgfx/src/gpu/GLFragmentProcessor.h b/tgfx/src/gpu/GLFragmentProcessor.h deleted file mode 100644 index 2e429b0075..0000000000 --- a/tgfx/src/gpu/GLFragmentProcessor.h +++ /dev/null @@ -1,183 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////////////////////// -// -// Tencent is pleased to support the open source community by making libpag available. -// -// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. -// -// Licensed 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 -// -// unless required by applicable law or agreed to in writing, software distributed under the -// license is distributed on an "as is" basis, without warranties or conditions of any kind, -// either express or implied. see the license for the specific language governing permissions -// and limitations under the license. -// -///////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include -#include "FragmentShaderBuilder.h" -#include "UniformHandler.h" -#include "gpu/FragmentProcessor.h" -#include "gpu/UniformBuffer.h" - -namespace tgfx { -class GLFragmentProcessor { - public: - virtual ~GLFragmentProcessor() = default; - - /** - * This class allows the shader builder to provide each GLFragmentProcessor with an array of - * generated variables where each generated variable corresponds to an element of an array on - * the FragmentProcessor that generated the GLFragmentProcessor. - */ - template - class BuilderInputProvider { - public: - BuilderInputProvider(const FragmentProcessor* fp, const T* t) : fragmentProcessor(fp), t(t) { - } - - const T& operator[](size_t i) const { - return t[i]; - } - - size_t count() const { - return (fragmentProcessor->*COUNT)(); - } - - BuilderInputProvider childInputs(size_t childIndex) const; - - private: - const FragmentProcessor* fragmentProcessor; - const T* t; - }; - - using TransformedCoordVars = - BuilderInputProvider; - using TextureSamplers = - BuilderInputProvider; - - struct EmitArgs { - EmitArgs(FragmentShaderBuilder* fragBuilder, UniformHandler* uniformHandler, - const FragmentProcessor* fp, std::string outputColor, std::string inputColor, - const TransformedCoordVars* transformedCoords, const TextureSamplers* textureSamplers, - std::function coordFunc = {}) - : fragBuilder(fragBuilder), - uniformHandler(uniformHandler), - fragmentProcessor(fp), - outputColor(std::move(outputColor)), - inputColor(std::move(inputColor)), - transformedCoords(transformedCoords), - textureSamplers(textureSamplers), - coordFunc(std::move(coordFunc)) { - } - /** - * Interface used to emit code in the shaders. - */ - FragmentShaderBuilder* fragBuilder; - UniformHandler* uniformHandler; - /** - * The processor that generated this program stage. - */ - const FragmentProcessor* fragmentProcessor; - /** - * A predefined vec4 in the FS in which the stage should place its output color (or coverage). - */ - const std::string outputColor; - /** - * A vec4 that holds the input color to the stage in the FS. - */ - const std::string inputColor; - /** - * Fragment shader variables containing the coords computed using each of the - * FragmentProcessor's CoordTransforms. - */ - const TransformedCoordVars* transformedCoords; - /** - * Contains one entry for each TextureSampler of the Processor. These can be passed to the - * builder to emit texture reads in the generated code. - */ - const TextureSamplers* textureSamplers; - const std::function coordFunc; - }; - - /** - * Called when the program stage should insert its code into the shaders. The code in each shader - * will be in its own block ({}) and so locally scoped names will not collide across stages. - */ - virtual void emitCode(EmitArgs&) = 0; - - void setData(UniformBuffer* uniformBuffer, const FragmentProcessor& processor); - - size_t numChildProcessors() const { - return childProcessors.size(); - } - - GLFragmentProcessor* childProcessor(size_t index) { - return childProcessors[index].get(); - } - - /** - * Emit the child with the default input color (solid white) - */ - void emitChild(size_t childIndex, std::string* outputColor, EmitArgs& parentArgs, - std::function coordFunc = {}) { - emitChild(childIndex, "", outputColor, parentArgs, std::move(coordFunc)); - } - - /** - * Will emit the code of a child proc in its own scope. Pass in the parent's EmitArgs and - * emitChild will automatically extract the coords and samplers of that child and pass them - * on to the child's emitCode(). Also, any uniforms or functions emitted by the child will - * have their names mangled to prevent redefinitions. The output color name is also mangled - * therefore in an in/out param. It will be declared in mangled form by emitChild(). It is - * legal to pass empty string as inputColor, since all fragment processors are required to work - * without an input color. - */ - void emitChild(size_t childIndex, const std::string& inputColor, std::string* outputColor, - EmitArgs& parentArgs, std::function coordFunc = {}); - - /** - * Variation that uses the parent's output color variable to hold the child's output. - */ - void emitChild(size_t childIndex, const std::string& inputColor, EmitArgs& parentArgs); - - /** - * Pre-order traversal of a GLFP hierarchy, or of multiple trees with roots in an array of - * GLFPs. This agrees with the traversal order of FragmentProcessor::Iter - */ - class Iter { - public: - explicit Iter(GLFragmentProcessor* fp) { - fpStack.push_back(fp); - } - - GLFragmentProcessor* next(); - - private: - std::vector fpStack; - }; - - protected: - /** - * A GLFragmentProcessor instance can be reused with any FragmentProcessor that produces - * the same stage key; this function reads data from a FragmentProcessor and uploads any - * uniform variables required by the shaders created in emitCode(). The FragmentProcessor - * parameter is guaranteed to be of the same type that created this GLFragmentProcessor and - * to have an identical processor key as the one that created this GLFragmentProcessor. - */ - virtual void onSetData(UniformBuffer*, const FragmentProcessor&) { - } - - private: - void internalEmitChild(size_t, const std::string&, const std::string&, EmitArgs&, - std::function = {}); - - std::vector> childProcessors; - - friend class FragmentProcessor; -}; -} // namespace tgfx diff --git a/tgfx/src/gpu/GeometryProcessor.h b/tgfx/src/gpu/GeometryProcessor.h index 4903aa7e4d..24f55e1011 100644 --- a/tgfx/src/gpu/GeometryProcessor.h +++ b/tgfx/src/gpu/GeometryProcessor.h @@ -77,13 +77,6 @@ class GeometryProcessor : public Processor { void computeProcessorKey(Context* context, BytesKey* bytesKey) const override; - /** - * This class provides access to the CoordTransforms across all FragmentProcessors in a - * Pipeline. It is also used by the primitive processor to specify the fragment shader - * variable that will hold the transformed coords for each CoordTransform. It is required that - * the primitive processor iterate over each coord transform and insert a shader var result for - * each. The GLFragmentProcessors will reference these variables in their fragment code. - */ class FPCoordTransformHandler { public: FPCoordTransformHandler(const Pipeline* pipeline, std::vector* transformedCoordVars) diff --git a/tgfx/src/gpu/LumaColorFilterEffect.cpp b/tgfx/src/gpu/LumaColorFilterEffect.cpp deleted file mode 100644 index 9a642fcc3a..0000000000 --- a/tgfx/src/gpu/LumaColorFilterEffect.cpp +++ /dev/null @@ -1,26 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////////////////////// -// -// Tencent is pleased to support the open source community by making libpag available. -// -// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. -// -// Licensed 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 -// -// unless required by applicable law or agreed to in writing, software distributed under the -// license is distributed on an "as is" basis, without warranties or conditions of any kind, -// either express or implied. see the license for the specific language governing permissions -// and limitations under the license. -// -///////////////////////////////////////////////////////////////////////////////////////////////// - -#include "gpu/LumaColorFilterEffect.h" -#include "opengl/GLLumaColorFilterEffect.h" - -namespace tgfx { -std::unique_ptr LumaColorFilterEffect::onCreateGLInstance() const { - return std::make_unique(); -} -} // namespace tgfx diff --git a/tgfx/src/gpu/LumaColorFilterEffect.h b/tgfx/src/gpu/LumaColorFilterEffect.h index 0145f6f64b..1c65f8d4de 100644 --- a/tgfx/src/gpu/LumaColorFilterEffect.h +++ b/tgfx/src/gpu/LumaColorFilterEffect.h @@ -23,18 +23,15 @@ namespace tgfx { class LumaColorFilterEffect : public FragmentProcessor { public: - static std::unique_ptr Make() { - return std::make_unique(); - } - - LumaColorFilterEffect() : FragmentProcessor(ClassID()) { - } + static std::unique_ptr Make(); std::string name() const override { return "LumaColorFilterEffect"; } - std::unique_ptr onCreateGLInstance() const override; + protected: + LumaColorFilterEffect() : FragmentProcessor(ClassID()) { + } private: DEFINE_PROCESSOR_CLASS_ID diff --git a/tgfx/src/gpu/PorterDuffXferProcessor.cpp b/tgfx/src/gpu/PorterDuffXferProcessor.cpp index 9aae766dcf..8bee8bfeed 100644 --- a/tgfx/src/gpu/PorterDuffXferProcessor.cpp +++ b/tgfx/src/gpu/PorterDuffXferProcessor.cpp @@ -17,7 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "PorterDuffXferProcessor.h" -#include "opengl/GLPorterDuffXferProcessor.h" namespace tgfx { void PorterDuffXferProcessor::computeProcessorKey(Context*, BytesKey* bytesKey) const { diff --git a/tgfx/src/gpu/ProgramBuilder.cpp b/tgfx/src/gpu/ProgramBuilder.cpp index 88b8d4c0bf..12b767ef58 100644 --- a/tgfx/src/gpu/ProgramBuilder.cpp +++ b/tgfx/src/gpu/ProgramBuilder.cpp @@ -17,7 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "ProgramBuilder.h" -#include "GLFragmentProcessor.h" +#include "FragmentProcessor.h" namespace tgfx { ProgramBuilder::ProgramBuilder(Context* context, const Pipeline* pipeline) @@ -70,7 +70,7 @@ void ProgramBuilder::emitAndInstallFragProcessors(std::string* color, std::strin inOut = &coverage; } const auto* fp = pipeline->getFragmentProcessor(i); - auto output = emitAndInstallFragProc(fp, transformedCoordVarsIdx, **inOut, &fragmentProcessors); + auto output = emitAndInstallFragProc(fp, transformedCoordVarsIdx, **inOut); FragmentProcessor::Iter iter(fp); while (const FragmentProcessor* tempFP = iter.next()) { transformedCoordVarsIdx += tempFP->numCoordTransforms(); @@ -87,9 +87,9 @@ static const T* GetPointer(const std::vector& vector, size_t atIndex) { return &vector[atIndex]; } -std::string ProgramBuilder::emitAndInstallFragProc( - const FragmentProcessor* processor, size_t transformedCoordVarsIdx, const std::string& input, - std::vector>* glslFragmentProcessors) { +std::string ProgramBuilder::emitAndInstallFragProc(const FragmentProcessor* processor, + size_t transformedCoordVarsIdx, + const std::string& input) { advanceStage(); std::string output; nameExpression(&output, "output"); @@ -98,8 +98,6 @@ std::string ProgramBuilder::emitAndInstallFragProc( fragmentShaderBuilder()->codeAppendf("{ // Stage %d %s\n", _stageIndex, processor->name().c_str()); - auto fragProc = processor->createGLInstance(); - std::vector texSamplers; FragmentProcessor::Iter fpIter(processor); int samplerIndex = 0; @@ -111,15 +109,13 @@ std::string ProgramBuilder::emitAndInstallFragProc( texSamplers.emplace_back(emitSampler(sampler, name)); } } - GLFragmentProcessor::TransformedCoordVars coords( + FragmentProcessor::TransformedCoordVars coords( processor, GetPointer(transformedCoordVars, transformedCoordVarsIdx)); - GLFragmentProcessor::TextureSamplers textureSamplers(processor, GetPointer(texSamplers, 0)); - GLFragmentProcessor::EmitArgs args(fragmentShaderBuilder(), uniformHandler(), processor, output, - input, &coords, &textureSamplers); - - fragProc->emitCode(args); + FragmentProcessor::TextureSamplers textureSamplers(processor, GetPointer(texSamplers, 0)); + FragmentProcessor::EmitArgs args(fragmentShaderBuilder(), uniformHandler(), output, input, + &coords, &textureSamplers); - glslFragmentProcessors->push_back(std::move(fragProc)); + processor->emitCode(args); fragmentShaderBuilder()->codeAppend("}"); return output; diff --git a/tgfx/src/gpu/ProgramBuilder.h b/tgfx/src/gpu/ProgramBuilder.h index 8e8052cfbb..7426133697 100644 --- a/tgfx/src/gpu/ProgramBuilder.h +++ b/tgfx/src/gpu/ProgramBuilder.h @@ -83,7 +83,6 @@ class ProgramBuilder { virtual bool checkSamplerCounts() = 0; - std::vector> fragmentProcessors; int numFragmentSamplers = 0; private: @@ -103,9 +102,8 @@ class ProgramBuilder { void emitAndInstallFragProcessors(std::string* color, std::string* coverage); - std::string emitAndInstallFragProc( - const FragmentProcessor* processor, size_t transformedCoordVarsIdx, const std::string& input, - std::vector>* glslFragmentProcessors); + std::string emitAndInstallFragProc(const FragmentProcessor* processor, + size_t transformedCoordVarsIdx, const std::string& input); void emitAndInstallXferProc(const std::string& colorIn, const std::string& coverageIn); diff --git a/tgfx/src/gpu/QuadPerEdgeAAGeometryProcessor.cpp b/tgfx/src/gpu/QuadPerEdgeAAGeometryProcessor.cpp index 9f84602dbb..9bf32aaefa 100644 --- a/tgfx/src/gpu/QuadPerEdgeAAGeometryProcessor.cpp +++ b/tgfx/src/gpu/QuadPerEdgeAAGeometryProcessor.cpp @@ -18,7 +18,6 @@ #include "QuadPerEdgeAAGeometryProcessor.h" #include "gpu/YUVTexture.h" -#include "opengl/GLQuadPerEdgeAAGeometryProcessor.h" namespace tgfx { QuadPerEdgeAAGeometryProcessor::QuadPerEdgeAAGeometryProcessor(int width, int height, AAType aa, diff --git a/tgfx/src/gpu/SeriesFragmentProcessor.cpp b/tgfx/src/gpu/SeriesFragmentProcessor.cpp index 87455de087..d8e7ee1a3e 100644 --- a/tgfx/src/gpu/SeriesFragmentProcessor.cpp +++ b/tgfx/src/gpu/SeriesFragmentProcessor.cpp @@ -17,20 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "SeriesFragmentProcessor.h" -#include "opengl/GLSeriesFragmentProcessor.h" namespace tgfx { -std::unique_ptr SeriesFragmentProcessor::Make( - std::unique_ptr* children, int count) { - if (!count) { - return nullptr; - } - if (1 == count) { - return std::move(children[0]); - } - return std::unique_ptr(new SeriesFragmentProcessor(children, count)); -} - SeriesFragmentProcessor::SeriesFragmentProcessor(std::unique_ptr* children, int count) : FragmentProcessor(ClassID()) { @@ -38,8 +26,4 @@ SeriesFragmentProcessor::SeriesFragmentProcessor(std::unique_ptr SeriesFragmentProcessor::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/SeriesFragmentProcessor.h b/tgfx/src/gpu/SeriesFragmentProcessor.h index d4e732f421..61e933bc56 100644 --- a/tgfx/src/gpu/SeriesFragmentProcessor.h +++ b/tgfx/src/gpu/SeriesFragmentProcessor.h @@ -30,13 +30,9 @@ class SeriesFragmentProcessor : public FragmentProcessor { return "SeriesFragmentProcessor"; } - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID SeriesFragmentProcessor(std::unique_ptr* children, int count); - - friend class GLSeriesFragmentProcessor; }; } // namespace tgfx diff --git a/tgfx/src/gpu/TextureEffect.cpp b/tgfx/src/gpu/TextureEffect.cpp index 0a464ec0b8..eb4b3e7d3b 100644 --- a/tgfx/src/gpu/TextureEffect.cpp +++ b/tgfx/src/gpu/TextureEffect.cpp @@ -18,8 +18,6 @@ #include "TextureEffect.h" #include "ConstColorProcessor.h" -#include "YUVTextureEffect.h" -#include "opengl/GLTextureEffect.h" namespace tgfx { class TextureEffectProxy : public FragmentProcessorProxy { @@ -84,28 +82,6 @@ std::unique_ptr TextureEffect::MakeRGBAAA( localMatrix); } -std::unique_ptr TextureEffect::Make(std::shared_ptr texture, - const SamplingOptions& sampling, - const Matrix* localMatrix) { - return MakeRGBAAA(std::move(texture), sampling, Point::Zero(), localMatrix); -} - -std::unique_ptr TextureEffect::MakeRGBAAA(std::shared_ptr texture, - const SamplingOptions& sampling, - const Point& alphaStart, - const Matrix* localMatrix) { - if (texture == nullptr) { - return nullptr; - } - auto matrix = localMatrix ? *localMatrix : Matrix::I(); - if (texture->isYUV()) { - return std::unique_ptr(new YUVTextureEffect( - std::static_pointer_cast(texture), sampling, alphaStart, matrix)); - } - return std::unique_ptr( - new TextureEffect(std::move(texture), sampling, alphaStart, matrix)); -} - TextureEffect::TextureEffect(std::shared_ptr texture, SamplingOptions sampling, const Point& alphaStart, const Matrix& localMatrix) : FragmentProcessor(ClassID()), @@ -127,8 +103,4 @@ void TextureEffect::onComputeProcessorKey(BytesKey* bytesKey) const { uint32_t flags = alphaStart == Point::Zero() ? 1 : 0; bytesKey->write(flags); } - -std::unique_ptr TextureEffect::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/TextureEffect.h b/tgfx/src/gpu/TextureEffect.h index bd535e3622..78d4064b6f 100644 --- a/tgfx/src/gpu/TextureEffect.h +++ b/tgfx/src/gpu/TextureEffect.h @@ -47,7 +47,7 @@ class TextureEffect : public FragmentProcessor { return "TextureEffect"; } - private: + protected: DEFINE_PROCESSOR_CLASS_ID TextureEffect(std::shared_ptr texture, SamplingOptions sampling, const Point& alphaStart, @@ -57,8 +57,6 @@ class TextureEffect : public FragmentProcessor { void onComputeProcessorKey(BytesKey* bytesKey) const override; - std::unique_ptr onCreateGLInstance() const override; - const TextureSampler* onTextureSampler(size_t) const override { return texture->getSampler(); } @@ -71,7 +69,5 @@ class TextureEffect : public FragmentProcessor { SamplerState samplerState; Point alphaStart = Point::Zero(); CoordTransform coordTransform; - - friend class GLTextureEffect; }; } // namespace tgfx diff --git a/tgfx/src/gpu/TiledTextureEffect.cpp b/tgfx/src/gpu/TiledTextureEffect.cpp index ded0f76103..bf4648d028 100644 --- a/tgfx/src/gpu/TiledTextureEffect.cpp +++ b/tgfx/src/gpu/TiledTextureEffect.cpp @@ -19,8 +19,6 @@ #include "gpu/TiledTextureEffect.h" #include "ConstColorProcessor.h" #include "TextureEffect.h" -#include "opengl/GLTiledTextureEffect.h" -#include "utils/Log.h" #include "utils/MathExtra.h" namespace tgfx { @@ -89,16 +87,6 @@ std::unique_ptr TiledTextureEffect::Make( using Wrap = SamplerState::WrapMode; -struct TiledTextureEffect::Sampling { - Sampling(const Texture* texture, SamplerState samplerState, const Rect& subset, const Caps* caps); - - SamplerState hwSampler; - ShaderMode shaderModeX = ShaderMode::None; - ShaderMode shaderModeY = ShaderMode::None; - Rect shaderSubset = Rect::MakeEmpty(); - Rect shaderClamp = Rect::MakeEmpty(); -}; - TiledTextureEffect::ShaderMode TiledTextureEffect::GetShaderMode(Wrap wrap, FilterMode filter, MipMapMode mm) { switch (wrap) { @@ -191,19 +179,6 @@ TiledTextureEffect::Sampling::Sampling(const Texture* texture, SamplerState samp shaderClamp = {x.shaderClamp.a, y.shaderClamp.a, x.shaderClamp.b, y.shaderClamp.b}; } -std::unique_ptr TiledTextureEffect::Make(std::shared_ptr texture, - SamplerState samplerState, - const Matrix* localMatrix) { - if (texture == nullptr) { - return nullptr; - } - auto matrix = localMatrix ? *localMatrix : Matrix::I(); - auto subset = Rect::MakeWH(texture->width(), texture->height()); - Sampling sampling(texture.get(), samplerState, subset, texture->getContext()->caps()); - return std::unique_ptr( - new TiledTextureEffect(std::move(texture), sampling, matrix)); -} - TiledTextureEffect::TiledTextureEffect(std::shared_ptr texture, const Sampling& sampling, const Matrix& localMatrix) : FragmentProcessor(ClassID()), @@ -230,8 +205,4 @@ bool TiledTextureEffect::onIsEqual(const FragmentProcessor& processor) const { clamp == that.clamp && shaderModeX == that.shaderModeX && shaderModeY == that.shaderModeY && coordTransform.matrix == that.coordTransform.matrix; } - -std::unique_ptr TiledTextureEffect::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/TiledTextureEffect.h b/tgfx/src/gpu/TiledTextureEffect.h index 16902ebbf4..fa3ccfc720 100644 --- a/tgfx/src/gpu/TiledTextureEffect.h +++ b/tgfx/src/gpu/TiledTextureEffect.h @@ -38,11 +38,9 @@ class TiledTextureEffect : public FragmentProcessor { return "TiledTextureEffect"; } - private: + protected: DEFINE_PROCESSOR_CLASS_ID - struct Sampling; - enum class ShaderMode { None, // Using HW mode Clamp, // Shader based clamp, no filter specialization @@ -55,13 +53,22 @@ class TiledTextureEffect : public FragmentProcessor { ClampToBorderLinear }; + struct Sampling { + Sampling(const Texture* texture, SamplerState samplerState, const Rect& subset, + const Caps* caps); + + SamplerState hwSampler; + ShaderMode shaderModeX = ShaderMode::None; + ShaderMode shaderModeY = ShaderMode::None; + Rect shaderSubset = Rect::MakeEmpty(); + Rect shaderClamp = Rect::MakeEmpty(); + }; + TiledTextureEffect(std::shared_ptr texture, const Sampling& sampling, const Matrix& localMatrix); void onComputeProcessorKey(BytesKey* bytesKey) const override; - std::unique_ptr onCreateGLInstance() const override; - bool onIsEqual(const FragmentProcessor& processor) const override; const TextureSampler* onTextureSampler(size_t) const override { @@ -81,7 +88,5 @@ class TiledTextureEffect : public FragmentProcessor { ShaderMode shaderModeX; ShaderMode shaderModeY; CoordTransform coordTransform; - - friend class GLTiledTextureEffect; }; } // namespace tgfx diff --git a/tgfx/src/gpu/XferProcessor.h b/tgfx/src/gpu/XferProcessor.h index ef3790147f..321841c49f 100644 --- a/tgfx/src/gpu/XferProcessor.h +++ b/tgfx/src/gpu/XferProcessor.h @@ -27,8 +27,6 @@ #include "tgfx/utils/BytesKey.h" namespace tgfx { -class GLXferProcessor; - class XferProcessor : public Processor { public: struct EmitArgs { diff --git a/tgfx/src/gpu/XfermodeFragmentProcessor.cpp b/tgfx/src/gpu/XfermodeFragmentProcessor.cpp index 4f243a8e62..1581532949 100644 --- a/tgfx/src/gpu/XfermodeFragmentProcessor.cpp +++ b/tgfx/src/gpu/XfermodeFragmentProcessor.cpp @@ -18,7 +18,6 @@ #include "gpu/XfermodeFragmentProcessor.h" #include "gpu/ConstColorProcessor.h" -#include "opengl/GLXfermodeFragmentProcessor.h" namespace tgfx { std::unique_ptr XfermodeFragmentProcessor::MakeFromSrcProcessor( @@ -31,25 +30,6 @@ std::unique_ptr XfermodeFragmentProcessor::MakeFromDstProcess return XfermodeFragmentProcessor::MakeFromTwoProcessors(nullptr, std::move(dst), mode); } -std::unique_ptr XfermodeFragmentProcessor::MakeFromTwoProcessors( - std::unique_ptr src, std::unique_ptr dst, - BlendMode mode) { - if (src == nullptr && dst == nullptr) { - return nullptr; - } - switch (mode) { - case BlendMode::Clear: - return ConstColorProcessor::Make(Color::Transparent(), InputMode::Ignore); - case BlendMode::Src: - return src; - case BlendMode::Dst: - return dst; - default: - return std::unique_ptr( - new XfermodeFragmentProcessor(std::move(src), std::move(dst), mode)); - } -} - std::string XfermodeFragmentProcessor::name() const { switch (child) { case Child::TwoChild: @@ -86,8 +66,4 @@ bool XfermodeFragmentProcessor::onIsEqual(const FragmentProcessor& processor) co const auto& that = static_cast(processor); return mode == that.mode && child == that.child; } - -std::unique_ptr XfermodeFragmentProcessor::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/XfermodeFragmentProcessor.h b/tgfx/src/gpu/XfermodeFragmentProcessor.h index 2a51c8a90f..ced954f5d7 100644 --- a/tgfx/src/gpu/XfermodeFragmentProcessor.h +++ b/tgfx/src/gpu/XfermodeFragmentProcessor.h @@ -51,9 +51,7 @@ class XfermodeFragmentProcessor : public FragmentProcessor { void onComputeProcessorKey(BytesKey* bytesKey) const override; - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID enum class Child { DstChild, SrcChild, TwoChild }; @@ -65,7 +63,5 @@ class XfermodeFragmentProcessor : public FragmentProcessor { Child child; BlendMode mode; - - friend class GLXfermodeFragmentProcessor; }; } // namespace tgfx diff --git a/tgfx/src/gpu/YUVTextureEffect.cpp b/tgfx/src/gpu/YUVTextureEffect.cpp index d043e7aa49..f9a483f18e 100644 --- a/tgfx/src/gpu/YUVTextureEffect.cpp +++ b/tgfx/src/gpu/YUVTextureEffect.cpp @@ -17,7 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "YUVTextureEffect.h" -#include "opengl/GLYUVTextureEffect.h" namespace tgfx { YUVTextureEffect::YUVTextureEffect(std::shared_ptr texture, SamplingOptions sampling, @@ -43,8 +42,4 @@ bool YUVTextureEffect::onIsEqual(const FragmentProcessor& processor) const { return texture == that.texture && alphaStart == that.alphaStart && coordTransform.matrix == that.coordTransform.matrix && samplerState == that.samplerState; } - -std::unique_ptr YUVTextureEffect::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/YUVTextureEffect.h b/tgfx/src/gpu/YUVTextureEffect.h index bbb2e1baed..a83d20404c 100644 --- a/tgfx/src/gpu/YUVTextureEffect.h +++ b/tgfx/src/gpu/YUVTextureEffect.h @@ -28,7 +28,7 @@ class YUVTextureEffect : public FragmentProcessor { return "YUVTextureEffect"; } - private: + protected: DEFINE_PROCESSOR_CLASS_ID YUVTextureEffect(std::shared_ptr texture, SamplingOptions sampling, @@ -36,8 +36,6 @@ class YUVTextureEffect : public FragmentProcessor { void onComputeProcessorKey(BytesKey* bytesKey) const override; - std::unique_ptr onCreateGLInstance() const override; - const TextureSampler* onTextureSampler(size_t index) const override { return texture->getSamplerAt(index); } @@ -54,7 +52,5 @@ class YUVTextureEffect : public FragmentProcessor { CoordTransform coordTransform; friend class TextureEffect; - - friend class GLYUVTextureEffect; }; } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/ClampedGradientEffect.cpp b/tgfx/src/gpu/gradients/ClampedGradientEffect.cpp index 85c30e7a02..657f33a0e8 100644 --- a/tgfx/src/gpu/gradients/ClampedGradientEffect.cpp +++ b/tgfx/src/gpu/gradients/ClampedGradientEffect.cpp @@ -17,26 +17,13 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "ClampedGradientEffect.h" -#include "opengl/GLClampedGradientEffect.h" namespace tgfx { -std::unique_ptr ClampedGradientEffect::Make( - std::unique_ptr colorizer, std::unique_ptr gradLayout, - Color leftBorderColor, Color rightBorderColor, bool makePremultiply) { - return std::unique_ptr( - new ClampedGradientEffect(std::move(colorizer), std::move(gradLayout), leftBorderColor, - rightBorderColor, makePremultiply)); -} - void ClampedGradientEffect::onComputeProcessorKey(BytesKey* bytesKey) const { uint32_t flag = makePremultiply ? 1 : 0; bytesKey->write(flag); } -std::unique_ptr ClampedGradientEffect::onCreateGLInstance() const { - return std::make_unique(); -} - bool ClampedGradientEffect::onIsEqual(const FragmentProcessor& processor) const { const auto& that = static_cast(processor); return makePremultiply == that.makePremultiply && leftBorderColor == that.leftBorderColor && diff --git a/tgfx/src/gpu/gradients/ClampedGradientEffect.h b/tgfx/src/gpu/gradients/ClampedGradientEffect.h index 85efb20fc9..07077b7d72 100644 --- a/tgfx/src/gpu/gradients/ClampedGradientEffect.h +++ b/tgfx/src/gpu/gradients/ClampedGradientEffect.h @@ -36,9 +36,7 @@ class ClampedGradientEffect : public FragmentProcessor { void onComputeProcessorKey(BytesKey* bytesKey) const override; - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID ClampedGradientEffect(std::unique_ptr colorizer, @@ -52,7 +50,5 @@ class ClampedGradientEffect : public FragmentProcessor { Color leftBorderColor; Color rightBorderColor; bool makePremultiply; - - friend class GLClampedGradientEffect; }; } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.cpp b/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.cpp index 7069232346..3725707c60 100644 --- a/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.cpp +++ b/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.cpp @@ -17,40 +17,11 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "DualIntervalGradientColorizer.h" -#include "opengl/GLDualIntervalGradientColorizer.h" namespace tgfx { -std::unique_ptr DualIntervalGradientColorizer::Make( - Color c0, Color c1, Color c2, Color c3, float threshold) { - Color scale01; - // Derive scale and biases from the 4 colors and threshold - for (int i = 0; i < 4; ++i) { - auto vc0 = c0[i]; - auto vc1 = c1[i]; - scale01[i] = (vc1 - vc0) / threshold; - } - // bias01 = c0 - - Color scale23; - Color bias23; - for (int i = 0; i < 4; ++i) { - auto vc2 = c2[i]; - auto vc3 = c3[i]; - scale23[i] = (vc3 - vc2) / (1 - threshold); - bias23[i] = vc2 - threshold * scale23[i]; - } - - return std::unique_ptr( - new DualIntervalGradientColorizer(scale01, c0, scale23, bias23, threshold)); -} - bool DualIntervalGradientColorizer::onIsEqual(const FragmentProcessor& processor) const { const auto& that = static_cast(processor); return scale01 == that.scale01 && bias01 == that.bias01 && scale23 == that.scale23 && bias23 == that.bias23 && threshold == that.threshold; } - -std::unique_ptr DualIntervalGradientColorizer::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.h b/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.h index b7447a20cb..d9e63174b1 100644 --- a/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.h +++ b/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.h @@ -31,9 +31,7 @@ class DualIntervalGradientColorizer : public FragmentProcessor { return "DualIntervalGradientColorizer"; } - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID DualIntervalGradientColorizer(Color scale01, Color bias01, Color scale23, Color bias23, @@ -53,7 +51,5 @@ class DualIntervalGradientColorizer : public FragmentProcessor { Color scale23; Color bias23; float threshold; - - friend class GLDualIntervalGradientColorizer; }; } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/LinearGradientLayout.cpp b/tgfx/src/gpu/gradients/LinearGradientLayout.cpp index 66b1602f5b..d765e342b9 100644 --- a/tgfx/src/gpu/gradients/LinearGradientLayout.cpp +++ b/tgfx/src/gpu/gradients/LinearGradientLayout.cpp @@ -17,13 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "LinearGradientLayout.h" -#include "opengl/GLLinearGradientLayout.h" namespace tgfx { -std::unique_ptr LinearGradientLayout::Make(Matrix matrix) { - return std::unique_ptr(new LinearGradientLayout(matrix)); -} - LinearGradientLayout::LinearGradientLayout(Matrix matrix) : FragmentProcessor(ClassID()), coordTransform(matrix) { addCoordTransform(&coordTransform); @@ -33,8 +28,4 @@ bool LinearGradientLayout::onIsEqual(const FragmentProcessor& processor) const { return coordTransform.matrix == static_cast(processor).coordTransform.matrix; } - -std::unique_ptr LinearGradientLayout::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/LinearGradientLayout.h b/tgfx/src/gpu/gradients/LinearGradientLayout.h index bac44f76a1..2445c3afb2 100644 --- a/tgfx/src/gpu/gradients/LinearGradientLayout.h +++ b/tgfx/src/gpu/gradients/LinearGradientLayout.h @@ -29,9 +29,7 @@ class LinearGradientLayout : public FragmentProcessor { return "LinearGradientLayout"; } - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID explicit LinearGradientLayout(Matrix matrix); diff --git a/tgfx/src/gpu/gradients/RadialGradientLayout.cpp b/tgfx/src/gpu/gradients/RadialGradientLayout.cpp index ae0cc4fbdf..02180e6833 100644 --- a/tgfx/src/gpu/gradients/RadialGradientLayout.cpp +++ b/tgfx/src/gpu/gradients/RadialGradientLayout.cpp @@ -17,13 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "RadialGradientLayout.h" -#include "opengl/GLRadialGradientLayout.h" namespace tgfx { -std::unique_ptr RadialGradientLayout::Make(Matrix matrix) { - return std::unique_ptr(new RadialGradientLayout(matrix)); -} - RadialGradientLayout::RadialGradientLayout(Matrix matrix) : FragmentProcessor(ClassID()), coordTransform(matrix) { addCoordTransform(&coordTransform); @@ -33,8 +28,4 @@ bool RadialGradientLayout::onIsEqual(const FragmentProcessor& processor) const { return coordTransform.matrix == static_cast(processor).coordTransform.matrix; } - -std::unique_ptr RadialGradientLayout::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/RadialGradientLayout.h b/tgfx/src/gpu/gradients/RadialGradientLayout.h index 502f99ef64..56c145af08 100644 --- a/tgfx/src/gpu/gradients/RadialGradientLayout.h +++ b/tgfx/src/gpu/gradients/RadialGradientLayout.h @@ -29,9 +29,7 @@ class RadialGradientLayout : public FragmentProcessor { return "RadialGradientLayout"; } - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID explicit RadialGradientLayout(Matrix matrix); diff --git a/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.cpp b/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.cpp index b72a2d5836..9476ac2057 100644 --- a/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.cpp +++ b/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.cpp @@ -17,21 +17,10 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "SingleIntervalGradientColorizer.h" -#include "opengl/GLSingleIntervalGradientColorizer.h" namespace tgfx { -std::unique_ptr SingleIntervalGradientColorizer::Make(Color start, - Color end) { - return std::unique_ptr( - new SingleIntervalGradientColorizer(start, end)); -} - bool SingleIntervalGradientColorizer::onIsEqual(const FragmentProcessor& processor) const { const auto& that = static_cast(processor); return start == that.start && end == that.end; } - -std::unique_ptr SingleIntervalGradientColorizer::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.h b/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.h index f30541afc5..2cceafa935 100644 --- a/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.h +++ b/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.h @@ -30,9 +30,7 @@ class SingleIntervalGradientColorizer : public FragmentProcessor { return "SingleIntervalGradientColorizer"; } - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID SingleIntervalGradientColorizer(Color start, Color end) @@ -43,7 +41,5 @@ class SingleIntervalGradientColorizer : public FragmentProcessor { Color start; Color end; - - friend class GLSingleIntervalGradientColorizer; }; } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/SweepGradientLayout.cpp b/tgfx/src/gpu/gradients/SweepGradientLayout.cpp index a6f5985ea4..57bacfa4a5 100644 --- a/tgfx/src/gpu/gradients/SweepGradientLayout.cpp +++ b/tgfx/src/gpu/gradients/SweepGradientLayout.cpp @@ -17,14 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/gradients/SweepGradientLayout.h" -#include "opengl/GLSweepGradientLayout.h" namespace tgfx { -std::unique_ptr SweepGradientLayout::Make(Matrix matrix, float bias, - float scale) { - return std::unique_ptr(new SweepGradientLayout(matrix, bias, scale)); -} - SweepGradientLayout::SweepGradientLayout(Matrix matrix, float bias, float scale) : FragmentProcessor(ClassID()), coordTransform(matrix), bias(bias), scale(scale) { addCoordTransform(&coordTransform); @@ -35,8 +29,4 @@ bool SweepGradientLayout::onIsEqual(const FragmentProcessor& processor) const { return coordTransform.matrix == that.coordTransform.matrix && bias == that.bias && scale == that.scale; } - -std::unique_ptr SweepGradientLayout::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/SweepGradientLayout.h b/tgfx/src/gpu/gradients/SweepGradientLayout.h index ee05e62995..f91561e166 100644 --- a/tgfx/src/gpu/gradients/SweepGradientLayout.h +++ b/tgfx/src/gpu/gradients/SweepGradientLayout.h @@ -29,9 +29,7 @@ class SweepGradientLayout : public FragmentProcessor { return "SweepGradientLayout"; } - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID SweepGradientLayout(Matrix matrix, float bias, float scale); @@ -41,7 +39,5 @@ class SweepGradientLayout : public FragmentProcessor { CoordTransform coordTransform; float bias; float scale; - - friend class GLSweepGradientLayout; }; } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/TextureGradientColorizer.cpp b/tgfx/src/gpu/gradients/TextureGradientColorizer.cpp index eef0de5b45..c56fb9c67f 100644 --- a/tgfx/src/gpu/gradients/TextureGradientColorizer.cpp +++ b/tgfx/src/gpu/gradients/TextureGradientColorizer.cpp @@ -17,20 +17,9 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "TextureGradientColorizer.h" -#include "opengl/GLTextureGradientColorizer.h" namespace tgfx { -std::unique_ptr TextureGradientColorizer::Make( - std::shared_ptr gradient) { - return std::unique_ptr( - new TextureGradientColorizer(std::move(gradient))); -} - bool TextureGradientColorizer::onIsEqual(const FragmentProcessor& processor) const { return gradient == static_cast(processor).gradient; } - -std::unique_ptr TextureGradientColorizer::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/TextureGradientColorizer.h b/tgfx/src/gpu/gradients/TextureGradientColorizer.h index a1d346674b..287885bccc 100644 --- a/tgfx/src/gpu/gradients/TextureGradientColorizer.h +++ b/tgfx/src/gpu/gradients/TextureGradientColorizer.h @@ -31,9 +31,7 @@ class TextureGradientColorizer : public FragmentProcessor { return "TextureGradientColorizer"; } - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID explicit TextureGradientColorizer(std::shared_ptr gradient) @@ -48,7 +46,5 @@ class TextureGradientColorizer : public FragmentProcessor { bool onIsEqual(const FragmentProcessor& processor) const override; std::shared_ptr gradient; - - friend class GLTextureGradientColorizer; }; } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.cpp b/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.cpp index 5af85f7b87..874b458c7b 100644 --- a/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.cpp +++ b/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.cpp @@ -17,74 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "UnrolledBinaryGradientColorizer.h" -#include "opengl/GLUnrolledBinaryGradientColorizer.h" -#include "utils/MathExtra.h" namespace tgfx { -static constexpr int kMaxIntervals = 8; -std::unique_ptr UnrolledBinaryGradientColorizer::Make( - const Color* colors, const float* positions, int count) { - // Depending on how the positions resolve into hard stops or regular stops, the number of - // intervals specified by the number of colors/positions can change. For instance, a plain - // 3 color gradient is two intervals, but a 4 color gradient with a hard stop is also - // two intervals. At the most extreme end, an 8 interval gradient made entirely of hard - // stops has 16 colors. - - if (count > kMaxColorCount) { - // Definitely cannot represent this gradient configuration - return nullptr; - } - - // The raster implementation also uses scales and biases, but since they must be calculated - // after the dst color space is applied, it limits our ability to cache their values. - Color scales[kMaxIntervals]; - Color biases[kMaxIntervals]; - float thresholds[kMaxIntervals]; - - int intervalCount = 0; - - for (int i = 0; i < count - 1; i++) { - if (intervalCount >= kMaxIntervals) { - // Already reached kMaxIntervals, and haven't run out of color stops so this - // gradient cannot be represented by this shader. - return nullptr; - } - - auto t0 = positions[i]; - auto t1 = positions[i + 1]; - auto dt = t1 - t0; - // If the interval is empty, skip to the next interval. This will automatically create - // distinct hard stop intervals as needed. It also protects against malformed gradients - // that have repeated hard stops at the very beginning that are effectively unreachable. - if (FloatNearlyZero(dt)) { - continue; - } - - for (int j = 0; j < 4; ++j) { - auto c0 = colors[i][j]; - auto c1 = colors[i + 1][j]; - auto scale = (c1 - c0) / dt; - auto bias = c0 - t0 * scale; - scales[intervalCount][j] = scale; - biases[intervalCount][j] = bias; - } - thresholds[intervalCount] = t1; - intervalCount++; - } - - // set the unused values to something consistent - for (int i = intervalCount; i < kMaxIntervals; i++) { - scales[i] = Color::Transparent(); - biases[i] = Color::Transparent(); - thresholds[i] = 0.0; - } - - return std::unique_ptr(new UnrolledBinaryGradientColorizer( - intervalCount, scales, biases, - Rect::MakeLTRB(thresholds[0], thresholds[1], thresholds[2], thresholds[3]), - Rect::MakeLTRB(thresholds[4], thresholds[5], thresholds[6], 0.0))); -} - void UnrolledBinaryGradientColorizer::onComputeProcessorKey(BytesKey* bytesKey) const { bytesKey->write(static_cast(intervalCount)); } @@ -100,8 +34,4 @@ bool UnrolledBinaryGradientColorizer::onIsEqual(const FragmentProcessor& process bias12_13 == that.bias12_13 && bias14_15 == that.bias14_15 && thresholds1_7 == that.thresholds1_7 && thresholds9_13 == that.thresholds9_13; } - -std::unique_ptr UnrolledBinaryGradientColorizer::onCreateGLInstance() const { - return std::make_unique(); -} } // namespace tgfx diff --git a/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.h b/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.h index 6244c165eb..13c8f2cebf 100644 --- a/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.h +++ b/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.h @@ -34,9 +34,7 @@ class UnrolledBinaryGradientColorizer : public FragmentProcessor { void onComputeProcessorKey(BytesKey* bytesKey) const override; - std::unique_ptr onCreateGLInstance() const override; - - private: + protected: DEFINE_PROCESSOR_CLASS_ID UnrolledBinaryGradientColorizer(int intervalCount, Color* scales, Color* biases, @@ -84,7 +82,5 @@ class UnrolledBinaryGradientColorizer : public FragmentProcessor { Color bias14_15; Rect thresholds1_7; Rect thresholds9_13; - - friend class GLUnrolledBinaryGradientColorizer; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLAARectEffect.cpp b/tgfx/src/opengl/GLAARectEffect.cpp index cb0a511076..d88207c632 100644 --- a/tgfx/src/opengl/GLAARectEffect.cpp +++ b/tgfx/src/opengl/GLAARectEffect.cpp @@ -20,7 +20,14 @@ #include "gpu/AARectEffect.h" namespace tgfx { -void GLAARectEffect::emitCode(EmitArgs& args) { +std::unique_ptr AARectEffect::Make(const Rect& rect) { + return std::unique_ptr(new GLAARectEffect(rect)); +} + +GLAARectEffect::GLAARectEffect(const Rect& rect) : AARectEffect(rect) { +} + +void GLAARectEffect::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto* uniformHandler = args.uniformHandler; @@ -35,12 +42,10 @@ void GLAARectEffect::emitCode(EmitArgs& args) { args.inputColor.c_str()); } -void GLAARectEffect::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& rectEffect = static_cast(fragmentProcessor); +void GLAARectEffect::onSetData(UniformBuffer* uniformBuffer) const { // The AA math in the shader evaluates to 0 at the uploaded coordinates, so outset by 0.5 // to interpolate from 0 at a half pixel inset and 1 at a half pixel outset of rect. - auto rect = rectEffect.rect.makeOutset(0.5f, 0.5f); - uniformBuffer->setData("Rect", &rect); + auto outRect = rect.makeOutset(0.5f, 0.5f); + uniformBuffer->setData("Rect", &outRect); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLAARectEffect.h b/tgfx/src/opengl/GLAARectEffect.h index 774e6c8be3..c36695787f 100644 --- a/tgfx/src/opengl/GLAARectEffect.h +++ b/tgfx/src/opengl/GLAARectEffect.h @@ -19,14 +19,16 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/AARectEffect.h" namespace tgfx { -class GLAARectEffect : public GLFragmentProcessor { +class GLAARectEffect : public AARectEffect { public: - void emitCode(EmitArgs& args) override; + explicit GLAARectEffect(const Rect& rect); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLClampedGradientEffect.cpp b/tgfx/src/opengl/GLClampedGradientEffect.cpp index 063e63a0ce..a78103bcd4 100644 --- a/tgfx/src/opengl/GLClampedGradientEffect.cpp +++ b/tgfx/src/opengl/GLClampedGradientEffect.cpp @@ -20,15 +20,30 @@ #include "gpu/gradients/ClampedGradientEffect.h" namespace tgfx { -void GLClampedGradientEffect::emitCode(EmitArgs& args) { +std::unique_ptr ClampedGradientEffect::Make( + std::unique_ptr colorizer, std::unique_ptr gradLayout, + Color leftBorderColor, Color rightBorderColor, bool makePremultiply) { + return std::unique_ptr( + new GLClampedGradientEffect(std::move(colorizer), std::move(gradLayout), leftBorderColor, + rightBorderColor, makePremultiply)); +} + +GLClampedGradientEffect::GLClampedGradientEffect(std::unique_ptr colorizer, + std::unique_ptr gradLayout, + tgfx::Color leftBorderColor, + tgfx::Color rightBorderColor, bool makePremultiply) + : ClampedGradientEffect(std::move(colorizer), std::move(gradLayout), leftBorderColor, + rightBorderColor, makePremultiply) { +} + +void GLClampedGradientEffect::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; - const auto* fp = static_cast(args.fragmentProcessor); auto leftBorderColorName = args.uniformHandler->addUniform( ShaderFlags::Fragment, ShaderVar::Type::Float4, "leftBorderColor"); auto rightBorderColorName = args.uniformHandler->addUniform( ShaderFlags::Fragment, ShaderVar::Type::Float4, "rightBorderColor"); std::string _child1 = "_child1"; - emitChild(fp->gradLayoutIndex, &_child1, args); + emitChild(gradLayoutIndex, &_child1, args); fragBuilder->codeAppendf("vec4 t = %s;", _child1.c_str()); fragBuilder->codeAppend("if (t.y < 0.0) {"); fragBuilder->codeAppendf("%s = vec4(0.0);", args.outputColor.c_str()); @@ -39,20 +54,18 @@ void GLClampedGradientEffect::emitCode(EmitArgs& args) { fragBuilder->codeAppend("} else {"); std::string _input0 = "t"; std::string _child0 = "_child0"; - emitChild(fp->colorizerIndex, _input0, &_child0, args); + emitChild(colorizerIndex, _input0, &_child0, args); fragBuilder->codeAppendf("%s = %s;", args.outputColor.c_str(), _child0.c_str()); fragBuilder->codeAppend("}"); - if (fp->makePremultiply) { + if (makePremultiply) { fragBuilder->codeAppend("{"); fragBuilder->codeAppendf("%s.rgb *= %s.a;", args.outputColor.c_str(), args.outputColor.c_str()); fragBuilder->codeAppend("}"); } } -void GLClampedGradientEffect::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& fp = static_cast(fragmentProcessor); - uniformBuffer->setData("leftBorderColor", fp.leftBorderColor.array()); - uniformBuffer->setData("rightBorderColor", fp.rightBorderColor.array()); +void GLClampedGradientEffect::onSetData(UniformBuffer* uniformBuffer) const { + uniformBuffer->setData("leftBorderColor", leftBorderColor.array()); + uniformBuffer->setData("rightBorderColor", rightBorderColor.array()); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLClampedGradientEffect.h b/tgfx/src/opengl/GLClampedGradientEffect.h index 83afd94f08..7fed4b9df8 100644 --- a/tgfx/src/opengl/GLClampedGradientEffect.h +++ b/tgfx/src/opengl/GLClampedGradientEffect.h @@ -19,15 +19,19 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/gradients/ClampedGradientEffect.h" #include "tgfx/core/Color.h" namespace tgfx { -class GLClampedGradientEffect : public GLFragmentProcessor { +class GLClampedGradientEffect : public ClampedGradientEffect { public: - void emitCode(EmitArgs& args) override; + GLClampedGradientEffect(std::unique_ptr colorizer, + std::unique_ptr gradLayout, Color leftBorderColor, + Color rightBorderColor, bool makePremultiply); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLColorMatrixFragmentProcessor.cpp b/tgfx/src/opengl/GLColorMatrixFragmentProcessor.cpp index 8c72137f16..1a1bd0b780 100644 --- a/tgfx/src/opengl/GLColorMatrixFragmentProcessor.cpp +++ b/tgfx/src/opengl/GLColorMatrixFragmentProcessor.cpp @@ -20,7 +20,16 @@ #include "gpu/ColorMatrixFragmentProcessor.h" namespace tgfx { -void GLColorMatrixFragmentProcessor::emitCode(EmitArgs& args) { +std::unique_ptr ColorMatrixFragmentProcessor::Make( + const std::array& matrix) { + return std::unique_ptr(new GLColorMatrixFragmentProcessor(matrix)); +} + +GLColorMatrixFragmentProcessor::GLColorMatrixFragmentProcessor(const std::array& matrix) + : ColorMatrixFragmentProcessor(matrix) { +} + +void GLColorMatrixFragmentProcessor::emitCode(EmitArgs& args) const { auto* uniformHandler = args.uniformHandler; auto matrixUniformName = uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float4x4, "Matrix"); @@ -39,21 +48,18 @@ void GLColorMatrixFragmentProcessor::emitCode(EmitArgs& args) { fragBuilder->codeAppendf("%s.rgb *= %s.a;", args.outputColor.c_str(), args.outputColor.c_str()); } -void GLColorMatrixFragmentProcessor::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& fp = static_cast(fragmentProcessor); - float matrix[] = { - fp.matrix[0], fp.matrix[5], fp.matrix[10], fp.matrix[15], fp.matrix[1], fp.matrix[6], - fp.matrix[11], fp.matrix[16], fp.matrix[2], fp.matrix[7], fp.matrix[12], fp.matrix[17], - fp.matrix[3], fp.matrix[8], fp.matrix[13], fp.matrix[18], +void GLColorMatrixFragmentProcessor::onSetData(UniformBuffer* uniformBuffer) const { + float m[] = { + matrix[0], matrix[5], matrix[10], matrix[15], matrix[1], matrix[6], matrix[11], matrix[16], + matrix[2], matrix[7], matrix[12], matrix[17], matrix[3], matrix[8], matrix[13], matrix[18], }; float vec[] = { - fp.matrix[4], - fp.matrix[9], - fp.matrix[14], - fp.matrix[19], + matrix[4], + matrix[9], + matrix[14], + matrix[19], }; - uniformBuffer->setData("Matrix", matrix); + uniformBuffer->setData("Matrix", m); uniformBuffer->setData("Vector", vec); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLColorMatrixFragmentProcessor.h b/tgfx/src/opengl/GLColorMatrixFragmentProcessor.h index f6110f5f28..9a67c93cd2 100644 --- a/tgfx/src/opengl/GLColorMatrixFragmentProcessor.h +++ b/tgfx/src/opengl/GLColorMatrixFragmentProcessor.h @@ -20,14 +20,16 @@ #include #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/ColorMatrixFragmentProcessor.h" namespace tgfx { -class GLColorMatrixFragmentProcessor : public GLFragmentProcessor { +class GLColorMatrixFragmentProcessor : public ColorMatrixFragmentProcessor { public: - void emitCode(EmitArgs& args) override; + explicit GLColorMatrixFragmentProcessor(const std::array& matrix); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLConstColorProcessor.cpp b/tgfx/src/opengl/GLConstColorProcessor.cpp index 9a75a27188..7f852917f2 100644 --- a/tgfx/src/opengl/GLConstColorProcessor.cpp +++ b/tgfx/src/opengl/GLConstColorProcessor.cpp @@ -20,13 +20,20 @@ #include "gpu/ConstColorProcessor.h" namespace tgfx { -void GLConstColorProcessor::emitCode(EmitArgs& args) { +std::unique_ptr ConstColorProcessor::Make(Color color, InputMode mode) { + return std::unique_ptr(new GLConstColorProcessor(color, mode)); +} + +GLConstColorProcessor::GLConstColorProcessor(Color color, InputMode mode) + : ConstColorProcessor(color, mode) { +} + +void GLConstColorProcessor::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto colorName = args.uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float4, "Color"); fragBuilder->codeAppendf("%s = %s;", args.outputColor.c_str(), colorName.c_str()); - const auto* fp = static_cast(args.fragmentProcessor); - switch (fp->inputMode) { + switch (inputMode) { case InputMode::Ignore: break; case InputMode::ModulateRGBA: @@ -38,9 +45,7 @@ void GLConstColorProcessor::emitCode(EmitArgs& args) { } } -void GLConstColorProcessor::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& fp = static_cast(fragmentProcessor); - uniformBuffer->setData("Color", fp.color.array()); +void GLConstColorProcessor::onSetData(UniformBuffer* uniformBuffer) const { + uniformBuffer->setData("Color", color.array()); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLConstColorProcessor.h b/tgfx/src/opengl/GLConstColorProcessor.h index 618908eaef..d2c296fa9f 100644 --- a/tgfx/src/opengl/GLConstColorProcessor.h +++ b/tgfx/src/opengl/GLConstColorProcessor.h @@ -19,15 +19,17 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/ConstColorProcessor.h" #include "tgfx/core/Color.h" namespace tgfx { -class GLConstColorProcessor : public GLFragmentProcessor { +class GLConstColorProcessor : public ConstColorProcessor { public: - void emitCode(EmitArgs& args) override; + GLConstColorProcessor(Color color, InputMode mode); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLDeviceSpaceTextureEffect.cpp b/tgfx/src/opengl/GLDeviceSpaceTextureEffect.cpp index d33678db2c..ed670af04a 100644 --- a/tgfx/src/opengl/GLDeviceSpaceTextureEffect.cpp +++ b/tgfx/src/opengl/GLDeviceSpaceTextureEffect.cpp @@ -20,7 +20,21 @@ #include "gpu/DeviceSpaceTextureEffect.h" namespace tgfx { -void GLDeviceSpaceTextureEffect::emitCode(EmitArgs& args) { +std::unique_ptr DeviceSpaceTextureEffect::Make( + std::shared_ptr texture, ImageOrigin deviceOrigin) { + if (texture == nullptr) { + return nullptr; + } + return std::unique_ptr( + new GLDeviceSpaceTextureEffect(std::move(texture), deviceOrigin)); +} + +GLDeviceSpaceTextureEffect::GLDeviceSpaceTextureEffect(std::shared_ptr texture, + ImageOrigin deviceOrigin) + : DeviceSpaceTextureEffect(std::move(texture), deviceOrigin) { +} + +void GLDeviceSpaceTextureEffect::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto* uniformHandler = args.uniformHandler; auto deviceCoordMatrixName = uniformHandler->addUniform( @@ -35,12 +49,10 @@ void GLDeviceSpaceTextureEffect::emitCode(EmitArgs& args) { fragBuilder->codeAppend(";"); } -void GLDeviceSpaceTextureEffect::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& textureFP = static_cast(fragmentProcessor); - float scales[] = {1.f / static_cast(textureFP.texture->width()), - 1.f / static_cast(textureFP.texture->height())}; +void GLDeviceSpaceTextureEffect::onSetData(UniformBuffer* uniformBuffer) const { + float scales[] = {1.f / static_cast(texture->width()), + 1.f / static_cast(texture->height())}; uniformBuffer->setData("CoordScale", scales); - uniformBuffer->setMatrix("DeviceCoordMatrix", textureFP.deviceCoordMatrix); + uniformBuffer->setMatrix("DeviceCoordMatrix", deviceCoordMatrix); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLDeviceSpaceTextureEffect.h b/tgfx/src/opengl/GLDeviceSpaceTextureEffect.h index 1bcf347ed1..0cb020bf08 100644 --- a/tgfx/src/opengl/GLDeviceSpaceTextureEffect.h +++ b/tgfx/src/opengl/GLDeviceSpaceTextureEffect.h @@ -19,14 +19,16 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/DeviceSpaceTextureEffect.h" namespace tgfx { -class GLDeviceSpaceTextureEffect : public GLFragmentProcessor { +class GLDeviceSpaceTextureEffect : public DeviceSpaceTextureEffect { public: - void emitCode(EmitArgs& args) override; + GLDeviceSpaceTextureEffect(std::shared_ptr texture, ImageOrigin deviceOrigin); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLDualBlurFragmentProcessor.cpp b/tgfx/src/opengl/GLDualBlurFragmentProcessor.cpp index a8b6d0bbef..6b8bff512e 100644 --- a/tgfx/src/opengl/GLDualBlurFragmentProcessor.cpp +++ b/tgfx/src/opengl/GLDualBlurFragmentProcessor.cpp @@ -20,15 +20,30 @@ #include "gpu/DualBlurFragmentProcessor.h" namespace tgfx { -void GLDualBlurFragmentProcessor::emitCode(EmitArgs& args) { +std::unique_ptr DualBlurFragmentProcessor::Make( + DualBlurPassMode passMode, std::unique_ptr processor, Point blurOffset, + Point texelSize) { + if (processor == nullptr) { + return nullptr; + } + return std::unique_ptr( + new GLDualBlurFragmentProcessor(passMode, std::move(processor), blurOffset, texelSize)); +} + +GLDualBlurFragmentProcessor::GLDualBlurFragmentProcessor( + DualBlurPassMode passMode, std::unique_ptr processor, Point blurOffset, + Point texelSize) + : DualBlurFragmentProcessor(passMode, std::move(processor), blurOffset, texelSize) { +} + +void GLDualBlurFragmentProcessor::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto blurOffsetName = args.uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float2, "Blur"); auto texelSizeName = args.uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float2, "TexelSize"); std::string tempColor = "tempColor"; - const auto* fp = static_cast(args.fragmentProcessor); - if (fp->passMode == DualBlurPassMode::Down) { + if (passMode == DualBlurPassMode::Down) { fragBuilder->codeAppend("const int size = 5;"); fragBuilder->codeAppendf("vec2 coords[size];"); fragBuilder->codeAppend("coords[0] = vec2(0.0, 0.0);"); @@ -82,10 +97,8 @@ void GLDualBlurFragmentProcessor::emitCode(EmitArgs& args) { } } -void GLDualBlurFragmentProcessor::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& fp = static_cast(fragmentProcessor); - uniformBuffer->setData("Blur", &fp.blurOffset); - uniformBuffer->setData("TexelSize", &fp.texelSize); +void GLDualBlurFragmentProcessor::onSetData(UniformBuffer* uniformBuffer) const { + uniformBuffer->setData("Blur", &blurOffset); + uniformBuffer->setData("TexelSize", &texelSize); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLDualBlurFragmentProcessor.h b/tgfx/src/opengl/GLDualBlurFragmentProcessor.h index 9fc0bc33c0..7174d21909 100644 --- a/tgfx/src/opengl/GLDualBlurFragmentProcessor.h +++ b/tgfx/src/opengl/GLDualBlurFragmentProcessor.h @@ -19,14 +19,18 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/DualBlurFragmentProcessor.h" namespace tgfx { -class GLDualBlurFragmentProcessor : public GLFragmentProcessor { +class GLDualBlurFragmentProcessor : public DualBlurFragmentProcessor { public: - void emitCode(EmitArgs& args) override; + GLDualBlurFragmentProcessor(DualBlurPassMode passMode, + std::unique_ptr processor, Point blurOffset, + Point texelSize); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLDualIntervalGradientColorizer.cpp b/tgfx/src/opengl/GLDualIntervalGradientColorizer.cpp index 0def927a88..76db2439e6 100644 --- a/tgfx/src/opengl/GLDualIntervalGradientColorizer.cpp +++ b/tgfx/src/opengl/GLDualIntervalGradientColorizer.cpp @@ -20,7 +20,37 @@ #include "gpu/gradients/DualIntervalGradientColorizer.h" namespace tgfx { -void GLDualIntervalGradientColorizer::emitCode(EmitArgs& args) { +std::unique_ptr DualIntervalGradientColorizer::Make( + Color c0, Color c1, Color c2, Color c3, float threshold) { + Color scale01; + // Derive scale and biases from the 4 colors and threshold + for (int i = 0; i < 4; ++i) { + auto vc0 = c0[i]; + auto vc1 = c1[i]; + scale01[i] = (vc1 - vc0) / threshold; + } + // bias01 = c0 + + Color scale23; + Color bias23; + for (int i = 0; i < 4; ++i) { + auto vc2 = c2[i]; + auto vc3 = c3[i]; + scale23[i] = (vc3 - vc2) / (1 - threshold); + bias23[i] = vc2 - threshold * scale23[i]; + } + + return std::unique_ptr( + new GLDualIntervalGradientColorizer(scale01, c0, scale23, bias23, threshold)); +} + +GLDualIntervalGradientColorizer::GLDualIntervalGradientColorizer(Color scale01, Color bias01, + Color scale23, Color bias23, + float threshold) + : DualIntervalGradientColorizer(scale01, bias01, scale23, bias23, threshold) { +} + +void GLDualIntervalGradientColorizer::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto scale01Name = args.uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float4, "scale01"); @@ -44,13 +74,11 @@ void GLDualIntervalGradientColorizer::emitCode(EmitArgs& args) { fragBuilder->codeAppendf("%s = vec4(t * scale + bias);", args.outputColor.c_str()); } -void GLDualIntervalGradientColorizer::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& fp = static_cast(fragmentProcessor); - uniformBuffer->setData("scale01", fp.scale01.array()); - uniformBuffer->setData("bias01", fp.bias01.array()); - uniformBuffer->setData("scale23", fp.scale23.array()); - uniformBuffer->setData("bias23", fp.bias23.array()); - uniformBuffer->setData("threshold", &fp.threshold); +void GLDualIntervalGradientColorizer::onSetData(UniformBuffer* uniformBuffer) const { + uniformBuffer->setData("scale01", scale01.array()); + uniformBuffer->setData("bias01", bias01.array()); + uniformBuffer->setData("scale23", scale23.array()); + uniformBuffer->setData("bias23", bias23.array()); + uniformBuffer->setData("threshold", &threshold); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLDualIntervalGradientColorizer.h b/tgfx/src/opengl/GLDualIntervalGradientColorizer.h index d2cb01dc65..4d6cfd72ed 100644 --- a/tgfx/src/opengl/GLDualIntervalGradientColorizer.h +++ b/tgfx/src/opengl/GLDualIntervalGradientColorizer.h @@ -19,15 +19,18 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/gradients/DualIntervalGradientColorizer.h" #include "tgfx/core/Color.h" namespace tgfx { -class GLDualIntervalGradientColorizer : public GLFragmentProcessor { +class GLDualIntervalGradientColorizer : public DualIntervalGradientColorizer { public: - void emitCode(EmitArgs& args) override; + GLDualIntervalGradientColorizer(Color scale01, Color bias01, Color scale23, Color bias23, + float threshold); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer*, const FragmentProcessor&) override; + void onSetData(UniformBuffer*) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLEllipseGeometryProcessor.cpp b/tgfx/src/opengl/GLEllipseGeometryProcessor.cpp index 01de5583b1..72e1c4b5e2 100644 --- a/tgfx/src/opengl/GLEllipseGeometryProcessor.cpp +++ b/tgfx/src/opengl/GLEllipseGeometryProcessor.cpp @@ -18,7 +18,6 @@ #include "GLEllipseGeometryProcessor.h" #include "gpu/EllipseGeometryProcessor.h" -#include "tgfx/gpu/Caps.h" namespace tgfx { std::unique_ptr EllipseGeometryProcessor::Make( diff --git a/tgfx/src/opengl/GLLinearGradientLayout.cpp b/tgfx/src/opengl/GLLinearGradientLayout.cpp index af604407d3..4164d7ec6f 100644 --- a/tgfx/src/opengl/GLLinearGradientLayout.cpp +++ b/tgfx/src/opengl/GLLinearGradientLayout.cpp @@ -19,7 +19,14 @@ #include "GLLinearGradientLayout.h" namespace tgfx { -void GLLinearGradientLayout::emitCode(EmitArgs& args) { +std::unique_ptr LinearGradientLayout::Make(Matrix matrix) { + return std::unique_ptr(new GLLinearGradientLayout(matrix)); +} + +GLLinearGradientLayout::GLLinearGradientLayout(Matrix matrix) : LinearGradientLayout(matrix) { +} + +void GLLinearGradientLayout::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; fragBuilder->codeAppendf("float t = %s.x + 1.0000000000000001e-05;", (*args.transformedCoords)[0].name().c_str()); diff --git a/tgfx/src/opengl/GLLinearGradientLayout.h b/tgfx/src/opengl/GLLinearGradientLayout.h index 7f985a383d..f796aaf860 100644 --- a/tgfx/src/opengl/GLLinearGradientLayout.h +++ b/tgfx/src/opengl/GLLinearGradientLayout.h @@ -18,11 +18,13 @@ #pragma once -#include "gpu/GLFragmentProcessor.h" +#include "gpu/gradients/LinearGradientLayout.h" namespace tgfx { -class GLLinearGradientLayout : public GLFragmentProcessor { +class GLLinearGradientLayout : public LinearGradientLayout { public: - void emitCode(EmitArgs& args) override; + explicit GLLinearGradientLayout(Matrix matrix); + + void emitCode(EmitArgs& args) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLLumaColorFilterEffect.cpp b/tgfx/src/opengl/GLLumaColorFilterEffect.cpp index 0f38487a98..ffb0f3aef6 100644 --- a/tgfx/src/opengl/GLLumaColorFilterEffect.cpp +++ b/tgfx/src/opengl/GLLumaColorFilterEffect.cpp @@ -19,7 +19,11 @@ #include "GLLumaColorFilterEffect.h" namespace tgfx { -void GLLumaColorFilterEffect::emitCode(EmitArgs& args) { +std::unique_ptr LumaColorFilterEffect::Make() { + return std::make_unique(); +} + +void GLLumaColorFilterEffect::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; fragBuilder->codeAppendf( "%s = vec4(0.0, 0.0, 0.0, clamp(dot(vec3(0.21260000000000001, 0.71519999999999995, 0.0722), " diff --git a/tgfx/src/opengl/GLLumaColorFilterEffect.h b/tgfx/src/opengl/GLLumaColorFilterEffect.h index 4910d217d0..6ebd2e50d3 100644 --- a/tgfx/src/opengl/GLLumaColorFilterEffect.h +++ b/tgfx/src/opengl/GLLumaColorFilterEffect.h @@ -18,11 +18,11 @@ #pragma once -#include "gpu/GLFragmentProcessor.h" +#include "gpu/LumaColorFilterEffect.h" namespace tgfx { -class GLLumaColorFilterEffect : public GLFragmentProcessor { +class GLLumaColorFilterEffect : public LumaColorFilterEffect { public: - void emitCode(EmitArgs& args) override; + void emitCode(EmitArgs& args) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLProgram.cpp b/tgfx/src/opengl/GLProgram.cpp index 232e2df6e3..a7561a52e8 100644 --- a/tgfx/src/opengl/GLProgram.cpp +++ b/tgfx/src/opengl/GLProgram.cpp @@ -24,12 +24,10 @@ namespace tgfx { GLProgram::GLProgram(Context* context, unsigned programID, std::unique_ptr uniformBuffer, - std::vector> fragmentProcessors, std::vector attributes, int vertexStride) : Program(context), programId(programID), uniformBuffer(std::move(uniformBuffer)), - glFragmentProcessors(std::move(fragmentProcessors)), attributes(std::move(attributes)), _vertexStride(vertexStride) { } @@ -84,19 +82,15 @@ void GLProgram::setFragmentData(const Pipeline* pipeline, int* nextTexSamplerIdx for (size_t index = 0; index < pipeline->numFragmentProcessors(); ++index) { uniformBuffer->advanceStage(); const auto* currentFP = pipeline->getFragmentProcessor(index); - auto currentGLFP = glFragmentProcessors.at(index).get(); FragmentProcessor::Iter iter(currentFP); - GLFragmentProcessor::Iter glIter(currentGLFP); const FragmentProcessor* fp = iter.next(); - GLFragmentProcessor* glslFP = glIter.next(); - while (fp && glslFP) { - glslFP->setData(uniformBuffer.get(), *fp); + while (fp) { + fp->setData(uniformBuffer.get()); for (size_t i = 0; i < fp->numTextureSamplers(); ++i) { static_cast(context->gpu()) ->bindTexture((*nextTexSamplerIdx)++, fp->textureSampler(i), fp->samplerState(i)); } fp = iter.next(); - glslFP = glIter.next(); } } } diff --git a/tgfx/src/opengl/GLProgram.h b/tgfx/src/opengl/GLProgram.h index 792241c941..644ab3c71b 100644 --- a/tgfx/src/opengl/GLProgram.h +++ b/tgfx/src/opengl/GLProgram.h @@ -21,7 +21,7 @@ #include #include "GLContext.h" #include "GLUniformHandler.h" -#include "gpu/GLFragmentProcessor.h" +#include "gpu/Pipeline.h" #include "gpu/Program.h" #include "opengl/GLRenderTarget.h" @@ -35,7 +35,6 @@ class GLProgram : public Program { }; GLProgram(Context* context, unsigned programID, std::unique_ptr uniformBuffer, - std::vector> fragmentProcessors, std::vector attributes, int vertexStride); void setupSamplerUniforms(const std::vector& textureSamplers) const; @@ -82,7 +81,6 @@ class GLProgram : public Program { unsigned programId = 0; std::unique_ptr uniformBuffer = nullptr; - std::vector> glFragmentProcessors; std::vector attributes; int _vertexStride = 0; }; diff --git a/tgfx/src/opengl/GLProgramBuilder.cpp b/tgfx/src/opengl/GLProgramBuilder.cpp index 77749d909a..4135bc0b76 100644 --- a/tgfx/src/opengl/GLProgramBuilder.cpp +++ b/tgfx/src/opengl/GLProgramBuilder.cpp @@ -150,8 +150,8 @@ bool GLProgramBuilder::checkSamplerCounts() { std::unique_ptr GLProgramBuilder::createProgram(unsigned programID) { auto uniformBuffer = _uniformHandler.makeUniformBuffer(); - auto program = new GLProgram(context, programID, std::move(uniformBuffer), - std::move(fragmentProcessors), attributes, vertexStride); + auto program = + new GLProgram(context, programID, std::move(uniformBuffer), attributes, vertexStride); program->setupSamplerUniforms(_uniformHandler.samplers); return std::unique_ptr(program); } diff --git a/tgfx/src/opengl/GLRadialGradientLayout.cpp b/tgfx/src/opengl/GLRadialGradientLayout.cpp index 70005be30d..afb3bc4e81 100644 --- a/tgfx/src/opengl/GLRadialGradientLayout.cpp +++ b/tgfx/src/opengl/GLRadialGradientLayout.cpp @@ -19,7 +19,14 @@ #include "GLRadialGradientLayout.h" namespace tgfx { -void GLRadialGradientLayout::emitCode(EmitArgs& args) { +std::unique_ptr RadialGradientLayout::Make(Matrix matrix) { + return std::unique_ptr(new GLRadialGradientLayout(matrix)); +} + +GLRadialGradientLayout::GLRadialGradientLayout(Matrix matrix) : RadialGradientLayout(matrix) { +} + +void GLRadialGradientLayout::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; fragBuilder->codeAppendf("float t = length(%s);", (*args.transformedCoords)[0].name().c_str()); fragBuilder->codeAppendf("%s = vec4(t, 1.0, 0.0, 0.0);", args.outputColor.c_str()); diff --git a/tgfx/src/opengl/GLRadialGradientLayout.h b/tgfx/src/opengl/GLRadialGradientLayout.h index a99949e3db..f7adaac46f 100644 --- a/tgfx/src/opengl/GLRadialGradientLayout.h +++ b/tgfx/src/opengl/GLRadialGradientLayout.h @@ -18,11 +18,13 @@ #pragma once -#include "gpu/GLFragmentProcessor.h" +#include "gpu/gradients/RadialGradientLayout.h" namespace tgfx { -class GLRadialGradientLayout : public GLFragmentProcessor { +class GLRadialGradientLayout : public RadialGradientLayout { public: - void emitCode(EmitArgs& args) override; + explicit GLRadialGradientLayout(Matrix matrix); + + void emitCode(EmitArgs& args) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLSeriesFragmentProcessor.cpp b/tgfx/src/opengl/GLSeriesFragmentProcessor.cpp index 1b0ac0bf3f..5daaeb2098 100644 --- a/tgfx/src/opengl/GLSeriesFragmentProcessor.cpp +++ b/tgfx/src/opengl/GLSeriesFragmentProcessor.cpp @@ -19,7 +19,23 @@ #include "GLSeriesFragmentProcessor.h" namespace tgfx { -void GLSeriesFragmentProcessor::emitCode(EmitArgs& args) { +std::unique_ptr SeriesFragmentProcessor::Make( + std::unique_ptr* children, int count) { + if (!count) { + return nullptr; + } + if (1 == count) { + return std::move(children[0]); + } + return std::unique_ptr(new GLSeriesFragmentProcessor(children, count)); +} + +GLSeriesFragmentProcessor::GLSeriesFragmentProcessor(std::unique_ptr* children, + int count) + : SeriesFragmentProcessor(children, count) { +} + +void GLSeriesFragmentProcessor::emitCode(EmitArgs& args) const { // First guy's input might be nil. std::string temp = "out0"; emitChild(0, args.inputColor, &temp, args); diff --git a/tgfx/src/opengl/GLSeriesFragmentProcessor.h b/tgfx/src/opengl/GLSeriesFragmentProcessor.h index 8b6fa98b9b..0cc5d0002a 100644 --- a/tgfx/src/opengl/GLSeriesFragmentProcessor.h +++ b/tgfx/src/opengl/GLSeriesFragmentProcessor.h @@ -18,11 +18,13 @@ #pragma once -#include "gpu/GLFragmentProcessor.h" +#include "gpu/SeriesFragmentProcessor.h" namespace tgfx { -class GLSeriesFragmentProcessor : public GLFragmentProcessor { +class GLSeriesFragmentProcessor : public SeriesFragmentProcessor { public: - void emitCode(EmitArgs& args) override; + GLSeriesFragmentProcessor(std::unique_ptr* children, int count); + + void emitCode(EmitArgs& args) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLSingleIntervalGradientColorizer.cpp b/tgfx/src/opengl/GLSingleIntervalGradientColorizer.cpp index 2bcada7c23..f20e24a328 100644 --- a/tgfx/src/opengl/GLSingleIntervalGradientColorizer.cpp +++ b/tgfx/src/opengl/GLSingleIntervalGradientColorizer.cpp @@ -20,7 +20,17 @@ #include "gpu/gradients/SingleIntervalGradientColorizer.h" namespace tgfx { -void GLSingleIntervalGradientColorizer::emitCode(EmitArgs& args) { +std::unique_ptr SingleIntervalGradientColorizer::Make(Color start, + Color end) { + return std::unique_ptr( + new GLSingleIntervalGradientColorizer(start, end)); +} + +GLSingleIntervalGradientColorizer::GLSingleIntervalGradientColorizer(Color start, Color end) + : SingleIntervalGradientColorizer(start, end) { +} + +void GLSingleIntervalGradientColorizer::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto startName = args.uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float4, "start"); @@ -31,10 +41,8 @@ void GLSingleIntervalGradientColorizer::emitCode(EmitArgs& args) { startName.c_str(), endName.c_str()); } -void GLSingleIntervalGradientColorizer::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& fp = static_cast(fragmentProcessor); - uniformBuffer->setData("start", fp.start.array()); - uniformBuffer->setData("end", fp.end.array()); +void GLSingleIntervalGradientColorizer::onSetData(UniformBuffer* uniformBuffer) const { + uniformBuffer->setData("start", start.array()); + uniformBuffer->setData("end", end.array()); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLSingleIntervalGradientColorizer.h b/tgfx/src/opengl/GLSingleIntervalGradientColorizer.h index 2d7cd89a80..86f8bd569c 100644 --- a/tgfx/src/opengl/GLSingleIntervalGradientColorizer.h +++ b/tgfx/src/opengl/GLSingleIntervalGradientColorizer.h @@ -19,15 +19,17 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/gradients/SingleIntervalGradientColorizer.h" #include "tgfx/core/Color.h" namespace tgfx { -class GLSingleIntervalGradientColorizer : public GLFragmentProcessor { +class GLSingleIntervalGradientColorizer : public SingleIntervalGradientColorizer { public: - void emitCode(EmitArgs& args) override; + GLSingleIntervalGradientColorizer(Color start, Color end); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer*, const FragmentProcessor&) override; + void onSetData(UniformBuffer*) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLSweepGradientLayout.cpp b/tgfx/src/opengl/GLSweepGradientLayout.cpp index fc28ba1f33..c3644eb354 100644 --- a/tgfx/src/opengl/GLSweepGradientLayout.cpp +++ b/tgfx/src/opengl/GLSweepGradientLayout.cpp @@ -20,7 +20,16 @@ #include "gpu/gradients/SweepGradientLayout.h" namespace tgfx { -void GLSweepGradientLayout::emitCode(EmitArgs& args) { +std::unique_ptr SweepGradientLayout::Make(Matrix matrix, float bias, + float scale) { + return std::unique_ptr(new GLSweepGradientLayout(matrix, bias, scale)); +} + +GLSweepGradientLayout::GLSweepGradientLayout(Matrix matrix, float bias, float scale) + : SweepGradientLayout(matrix, bias, scale) { +} + +void GLSweepGradientLayout::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto* uniformHandler = args.uniformHandler; auto biasName = uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float, "Bias"); @@ -34,10 +43,8 @@ void GLSweepGradientLayout::emitCode(EmitArgs& args) { fragBuilder->codeAppendf("%s = vec4(t, 1.0, 0.0, 0.0);", args.outputColor.c_str()); } -void GLSweepGradientLayout::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& fp = static_cast(fragmentProcessor); - uniformBuffer->setData("Bias", &fp.bias); - uniformBuffer->setData("Scale", &fp.scale); +void GLSweepGradientLayout::onSetData(UniformBuffer* uniformBuffer) const { + uniformBuffer->setData("Bias", &bias); + uniformBuffer->setData("Scale", &scale); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLSweepGradientLayout.h b/tgfx/src/opengl/GLSweepGradientLayout.h index 9f11b1d5c8..46fa7b76c5 100644 --- a/tgfx/src/opengl/GLSweepGradientLayout.h +++ b/tgfx/src/opengl/GLSweepGradientLayout.h @@ -19,14 +19,16 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/gradients/SweepGradientLayout.h" namespace tgfx { -class GLSweepGradientLayout : public GLFragmentProcessor { +class GLSweepGradientLayout : public SweepGradientLayout { public: - void emitCode(EmitArgs& args) override; + GLSweepGradientLayout(Matrix matrix, float bias, float scale); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer*, const FragmentProcessor&) override; + void onSetData(UniformBuffer*) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLTextureEffect.cpp b/tgfx/src/opengl/GLTextureEffect.cpp index cd24bce26b..37a109424f 100644 --- a/tgfx/src/opengl/GLTextureEffect.cpp +++ b/tgfx/src/opengl/GLTextureEffect.cpp @@ -18,10 +18,37 @@ #include "GLTextureEffect.h" #include "gpu/TextureEffect.h" +#include "opengl/GLYUVTextureEffect.h" namespace tgfx { -void GLTextureEffect::emitCode(EmitArgs& args) { - const auto* textureFP = static_cast(args.fragmentProcessor); +std::unique_ptr TextureEffect::Make(std::shared_ptr texture, + const SamplingOptions& sampling, + const Matrix* localMatrix) { + return MakeRGBAAA(std::move(texture), sampling, Point::Zero(), localMatrix); +} + +std::unique_ptr TextureEffect::MakeRGBAAA(std::shared_ptr texture, + const SamplingOptions& sampling, + const Point& alphaStart, + const Matrix* localMatrix) { + if (texture == nullptr) { + return nullptr; + } + auto matrix = localMatrix ? *localMatrix : Matrix::I(); + if (texture->isYUV()) { + return std::unique_ptr(new GLYUVTextureEffect( + std::static_pointer_cast(texture), sampling, alphaStart, matrix)); + } + return std::unique_ptr( + new GLTextureEffect(std::move(texture), sampling, alphaStart, matrix)); +} + +GLTextureEffect::GLTextureEffect(std::shared_ptr texture, SamplingOptions sampling, + const Point& alphaStart, const Matrix& localMatrix) + : TextureEffect(std::move(texture), sampling, alphaStart, localMatrix) { +} + +void GLTextureEffect::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto* uniformHandler = args.uniformHandler; @@ -32,7 +59,7 @@ void GLTextureEffect::emitCode(EmitArgs& args) { fragBuilder->codeAppend("vec4 color = "); fragBuilder->appendTextureLookup((*args.textureSamplers)[0], vertexColor); fragBuilder->codeAppend(";"); - if (textureFP->alphaStart != Point::Zero()) { + if (alphaStart != Point::Zero()) { fragBuilder->codeAppend("color = clamp(color, 0.0, 1.0);"); auto alphaStartName = uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float2, "alphaStart"); @@ -48,13 +75,10 @@ void GLTextureEffect::emitCode(EmitArgs& args) { fragBuilder->codeAppendf("%s = color * %s;", args.outputColor.c_str(), args.inputColor.c_str()); } -void GLTextureEffect::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& textureFP = static_cast(fragmentProcessor); - if (textureFP.alphaStart != Point::Zero()) { - auto alphaStart = - textureFP.texture->getTextureCoord(textureFP.alphaStart.x, textureFP.alphaStart.y); - uniformBuffer->setData("alphaStart", &alphaStart); +void GLTextureEffect::onSetData(UniformBuffer* uniformBuffer) const { + if (alphaStart != Point::Zero()) { + auto alphaStartValue = texture->getTextureCoord(alphaStart.x, alphaStart.y); + uniformBuffer->setData("alphaStart", &alphaStartValue); } } } // namespace tgfx diff --git a/tgfx/src/opengl/GLTextureEffect.h b/tgfx/src/opengl/GLTextureEffect.h index f4ba6a4701..f29d12355e 100644 --- a/tgfx/src/opengl/GLTextureEffect.h +++ b/tgfx/src/opengl/GLTextureEffect.h @@ -19,14 +19,17 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/TextureEffect.h" namespace tgfx { -class GLTextureEffect : public GLFragmentProcessor { +class GLTextureEffect : public TextureEffect { public: - void emitCode(EmitArgs& args) override; + GLTextureEffect(std::shared_ptr texture, SamplingOptions sampling, + const Point& alphaStart, const Matrix& localMatrix); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLTextureGradientColorizer.cpp b/tgfx/src/opengl/GLTextureGradientColorizer.cpp index 1a46fe684a..77cc16006d 100644 --- a/tgfx/src/opengl/GLTextureGradientColorizer.cpp +++ b/tgfx/src/opengl/GLTextureGradientColorizer.cpp @@ -19,7 +19,17 @@ #include "GLTextureGradientColorizer.h" namespace tgfx { -void GLTextureGradientColorizer::emitCode(EmitArgs& args) { +std::unique_ptr TextureGradientColorizer::Make( + std::shared_ptr gradient) { + return std::unique_ptr( + new GLTextureGradientColorizer(std::move(gradient))); +} + +GLTextureGradientColorizer::GLTextureGradientColorizer(std::shared_ptr gradient) + : TextureGradientColorizer(std::move(gradient)) { +} + +void GLTextureGradientColorizer::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; fragBuilder->codeAppendf("vec2 coord = vec2(%s.x, 0.5);", args.inputColor.c_str()); fragBuilder->codeAppendf("%s = ", args.outputColor.c_str()); diff --git a/tgfx/src/opengl/GLTextureGradientColorizer.h b/tgfx/src/opengl/GLTextureGradientColorizer.h index dde7f38bed..530d8b40fa 100644 --- a/tgfx/src/opengl/GLTextureGradientColorizer.h +++ b/tgfx/src/opengl/GLTextureGradientColorizer.h @@ -18,11 +18,13 @@ #pragma once -#include "gpu/GLFragmentProcessor.h" +#include "gpu/gradients/TextureGradientColorizer.h" namespace tgfx { -class GLTextureGradientColorizer : public GLFragmentProcessor { +class GLTextureGradientColorizer : public TextureGradientColorizer { public: - void emitCode(EmitArgs& args) override; + explicit GLTextureGradientColorizer(std::shared_ptr gradient); + + void emitCode(EmitArgs& args) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLTiledTextureEffect.cpp b/tgfx/src/opengl/GLTiledTextureEffect.cpp index cdeb911b15..cfcddcc45c 100644 --- a/tgfx/src/opengl/GLTiledTextureEffect.cpp +++ b/tgfx/src/opengl/GLTiledTextureEffect.cpp @@ -17,9 +17,29 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "GLTiledTextureEffect.h" +#include "gpu/SamplerState.h" #include "gpu/TiledTextureEffect.h" namespace tgfx { +std::unique_ptr TiledTextureEffect::Make(std::shared_ptr texture, + SamplerState samplerState, + const Matrix* localMatrix) { + if (texture == nullptr) { + return nullptr; + } + auto matrix = localMatrix ? *localMatrix : Matrix::I(); + auto subset = Rect::MakeWH(texture->width(), texture->height()); + Sampling sampling(texture.get(), samplerState, subset, texture->getContext()->caps()); + return std::unique_ptr( + new GLTiledTextureEffect(std::move(texture), sampling, matrix)); +} + +GLTiledTextureEffect::GLTiledTextureEffect(std::shared_ptr texture, + const TiledTextureEffect::Sampling& sampling, + const Matrix& localMatrix) + : TiledTextureEffect(std::move(texture), sampling, localMatrix) { +} + bool GLTiledTextureEffect::ShaderModeRequiresUnormCoord(TiledTextureEffect::ShaderMode mode) { switch (mode) { case TiledTextureEffect::ShaderMode::None: @@ -69,7 +89,7 @@ bool GLTiledTextureEffect::ShaderModeUsesClamp(TiledTextureEffect::ShaderMode m) } void GLTiledTextureEffect::readColor(EmitArgs& args, const std::string& dimensionsName, - const std::string& coord, const char* out) { + const std::string& coord, const char* out) const { std::string normCoord; if (!dimensionsName.empty()) { normCoord = "(" + coord + ") * " + dimensionsName + ""; @@ -82,12 +102,11 @@ void GLTiledTextureEffect::readColor(EmitArgs& args, const std::string& dimensio fragBuilder->codeAppend(";"); } -void GLTiledTextureEffect::subsetCoord(GLFragmentProcessor::EmitArgs& args, - TiledTextureEffect::ShaderMode mode, +void GLTiledTextureEffect::subsetCoord(EmitArgs& args, TiledTextureEffect::ShaderMode mode, const std::string& subsetName, const char* coordSwizzle, const char* subsetStartSwizzle, const char* subsetStopSwizzle, const char* extraCoord, - const char* coordWeight) { + const char* coordWeight) const { auto* fragBuilder = args.fragBuilder; switch (mode) { case TiledTextureEffect::ShaderMode::None: @@ -139,9 +158,9 @@ void GLTiledTextureEffect::subsetCoord(GLFragmentProcessor::EmitArgs& args, } } -void GLTiledTextureEffect::clampCoord(GLFragmentProcessor::EmitArgs& args, bool clamp, - const std::string& clampName, const char* coordSwizzle, - const char* clampStartSwizzle, const char* clampStopSwizzle) { +void GLTiledTextureEffect::clampCoord(EmitArgs& args, bool clamp, const std::string& clampName, + const char* coordSwizzle, const char* clampStartSwizzle, + const char* clampStopSwizzle) const { auto* fragBuilder = args.fragBuilder; if (clamp) { fragBuilder->codeAppendf("clampedCoord%s = clamp(subsetCoord%s, %s%s, %s%s);", coordSwizzle, @@ -152,8 +171,8 @@ void GLTiledTextureEffect::clampCoord(GLFragmentProcessor::EmitArgs& args, bool } } -void GLTiledTextureEffect::clampCoord(GLFragmentProcessor::EmitArgs& args, const bool useClamp[2], - const std::string& clampName) { +void GLTiledTextureEffect::clampCoord(EmitArgs& args, const bool useClamp[2], + const std::string& clampName) const { if (useClamp[0] == useClamp[1]) { clampCoord(args, useClamp[0], clampName, "", ".xy", ".zw"); } else { @@ -162,8 +181,9 @@ void GLTiledTextureEffect::clampCoord(GLFragmentProcessor::EmitArgs& args, const } } -GLTiledTextureEffect::UniformNames GLTiledTextureEffect::initUniform( - GLFragmentProcessor::EmitArgs& args, const bool useSubset[2], const bool useClamp[2]) { +GLTiledTextureEffect::UniformNames GLTiledTextureEffect::initUniform(EmitArgs& args, + const bool useSubset[2], + const bool useClamp[2]) const { UniformNames names = {}; auto* uniformHandler = args.uniformHandler; if (useSubset[0] || useSubset[1]) { @@ -174,11 +194,9 @@ GLTiledTextureEffect::UniformNames GLTiledTextureEffect::initUniform( names.clampName = uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float4, "Clamp"); } - const auto* textureFP = static_cast(args.fragmentProcessor); - bool unormCoordsRequiredForShaderMode = ShaderModeRequiresUnormCoord(textureFP->shaderModeX) || - ShaderModeRequiresUnormCoord(textureFP->shaderModeY); - bool sampleCoordsMustBeNormalized = - textureFP->texture->getSampler()->type() != TextureType::Rectangle; + bool unormCoordsRequiredForShaderMode = + ShaderModeRequiresUnormCoord(shaderModeX) || ShaderModeRequiresUnormCoord(shaderModeY); + bool sampleCoordsMustBeNormalized = texture->getSampler()->type() != TextureType::Rectangle; if (unormCoordsRequiredForShaderMode && sampleCoordsMustBeNormalized) { names.dimensionsName = uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float2, "Dimension"); @@ -186,25 +204,21 @@ GLTiledTextureEffect::UniformNames GLTiledTextureEffect::initUniform( return names; } -void GLTiledTextureEffect::emitCode(EmitArgs& args) { - const auto* textureFP = static_cast(args.fragmentProcessor); +void GLTiledTextureEffect::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; - auto vertexColor = (*args.transformedCoords)[0].name(); if (args.coordFunc) { vertexColor = args.coordFunc(vertexColor); } - if (textureFP->shaderModeX == TiledTextureEffect::ShaderMode::None && - textureFP->shaderModeY == TiledTextureEffect::ShaderMode::None) { + if (shaderModeX == TiledTextureEffect::ShaderMode::None && + shaderModeY == TiledTextureEffect::ShaderMode::None) { fragBuilder->codeAppendf("%s = ", args.outputColor.c_str()); fragBuilder->appendTextureLookup((*args.textureSamplers)[0], vertexColor); fragBuilder->codeAppendf(" * %s;", args.inputColor.c_str()); } else { fragBuilder->codeAppendf("vec2 inCoord = %s;", vertexColor.c_str()); - bool useSubset[2] = {ShaderModeUsesSubset(textureFP->shaderModeX), - ShaderModeUsesSubset(textureFP->shaderModeY)}; - bool useClamp[2] = {ShaderModeUsesClamp(textureFP->shaderModeX), - ShaderModeUsesClamp(textureFP->shaderModeY)}; + bool useSubset[2] = {ShaderModeUsesSubset(shaderModeX), ShaderModeUsesSubset(shaderModeY)}; + bool useClamp[2] = {ShaderModeUsesClamp(shaderModeX), ShaderModeUsesClamp(shaderModeY)}; auto names = initUniform(args, useSubset, useClamp); if (!names.dimensionsName.empty()) { fragBuilder->codeAppendf("inCoord /= %s;", names.dimensionsName.c_str()); @@ -215,12 +229,10 @@ void GLTiledTextureEffect::emitCode(EmitArgs& args) { const char* extraRepeatCoordY = nullptr; const char* repeatCoordWeightY = nullptr; - bool mipMapRepeatX = - textureFP->shaderModeX == TiledTextureEffect::ShaderMode::RepeatNearestMipmap || - textureFP->shaderModeX == TiledTextureEffect::ShaderMode::RepeatLinearMipmap; - bool mipMapRepeatY = - textureFP->shaderModeY == TiledTextureEffect::ShaderMode::RepeatNearestMipmap || - textureFP->shaderModeY == TiledTextureEffect::ShaderMode::RepeatLinearMipmap; + bool mipMapRepeatX = shaderModeX == TiledTextureEffect::ShaderMode::RepeatNearestMipmap || + shaderModeX == TiledTextureEffect::ShaderMode::RepeatLinearMipmap; + bool mipMapRepeatY = shaderModeY == TiledTextureEffect::ShaderMode::RepeatNearestMipmap || + shaderModeY == TiledTextureEffect::ShaderMode::RepeatLinearMipmap; if (mipMapRepeatX || mipMapRepeatY) { fragBuilder->codeAppend("vec2 extraRepeatCoord;"); @@ -237,9 +249,9 @@ void GLTiledTextureEffect::emitCode(EmitArgs& args) { } fragBuilder->codeAppend("highp vec2 subsetCoord;"); - subsetCoord(args, textureFP->shaderModeX, names.subsetName, "x", "x", "z", extraRepeatCoordX, + subsetCoord(args, shaderModeX, names.subsetName, "x", "x", "z", extraRepeatCoordX, repeatCoordWeightX); - subsetCoord(args, textureFP->shaderModeY, names.subsetName, "y", "y", "w", extraRepeatCoordY, + subsetCoord(args, shaderModeY, names.subsetName, "y", "y", "w", extraRepeatCoordY, repeatCoordWeightY); fragBuilder->codeAppend("vec2 clampedCoord;"); @@ -294,18 +306,18 @@ void GLTiledTextureEffect::emitCode(EmitArgs& args) { static const char* repeatReadX = "repeatReadX"; static const char* repeatReadY = "repeatReadY"; - bool repeatX = textureFP->shaderModeX == TiledTextureEffect::ShaderMode::RepeatLinearNone || - textureFP->shaderModeX == TiledTextureEffect::ShaderMode::RepeatLinearMipmap; - bool repeatY = textureFP->shaderModeY == TiledTextureEffect::ShaderMode::RepeatLinearNone || - textureFP->shaderModeY == TiledTextureEffect::ShaderMode::RepeatLinearMipmap; - if (repeatX || textureFP->shaderModeX == TiledTextureEffect::ShaderMode::ClampToBorderLinear) { + bool repeatX = shaderModeX == TiledTextureEffect::ShaderMode::RepeatLinearNone || + shaderModeX == TiledTextureEffect::ShaderMode::RepeatLinearMipmap; + bool repeatY = shaderModeY == TiledTextureEffect::ShaderMode::RepeatLinearNone || + shaderModeY == TiledTextureEffect::ShaderMode::RepeatLinearMipmap; + if (repeatX || shaderModeX == TiledTextureEffect::ShaderMode::ClampToBorderLinear) { fragBuilder->codeAppend("float errX = subsetCoord.x - clampedCoord.x;"); if (repeatX) { fragBuilder->codeAppendf("float repeatCoordX = errX > 0.0 ? %s.x : %s.z;", names.clampName.c_str(), names.clampName.c_str()); } } - if (repeatY || textureFP->shaderModeY == TiledTextureEffect::ShaderMode::ClampToBorderLinear) { + if (repeatY || shaderModeY == TiledTextureEffect::ShaderMode::ClampToBorderLinear) { fragBuilder->codeAppend("float errY = subsetCoord.y - clampedCoord.y;"); if (repeatY) { fragBuilder->codeAppendf("float repeatCoordY = errY > 0.0 ? %s.y : %s.w;", @@ -340,20 +352,20 @@ void GLTiledTextureEffect::emitCode(EmitArgs& args) { fragBuilder->codeAppend("}"); } - if (textureFP->shaderModeX == TiledTextureEffect::ShaderMode::ClampToBorderLinear) { + if (shaderModeX == TiledTextureEffect::ShaderMode::ClampToBorderLinear) { fragBuilder->codeAppend("textureColor = mix(textureColor, vec4(0.0), min(abs(errX), 1.0));"); } - if (textureFP->shaderModeY == TiledTextureEffect::ShaderMode::ClampToBorderLinear) { + if (shaderModeY == TiledTextureEffect::ShaderMode::ClampToBorderLinear) { fragBuilder->codeAppendf("textureColor = mix(textureColor, vec4(0.0), min(abs(errY), 1.0));"); } - if (textureFP->shaderModeX == TiledTextureEffect::ShaderMode::ClampToBorderNearest) { + if (shaderModeX == TiledTextureEffect::ShaderMode::ClampToBorderNearest) { fragBuilder->codeAppend("float snappedX = floor(inCoord.x + 0.001) + 0.5;"); fragBuilder->codeAppendf("if (snappedX < %s.x || snappedX > %s.z) {", names.subsetName.c_str(), names.subsetName.c_str()); fragBuilder->codeAppend("textureColor = vec4(0.0);"); // border color fragBuilder->codeAppend("}"); } - if (textureFP->shaderModeY == TiledTextureEffect::ShaderMode::ClampToBorderNearest) { + if (shaderModeY == TiledTextureEffect::ShaderMode::ClampToBorderNearest) { fragBuilder->codeAppend("float snappedY = floor(inCoord.y + 0.001) + 0.5;"); fragBuilder->codeAppendf("if (snappedY < %s.y || snappedY > %s.w) {", names.subsetName.c_str(), names.subsetName.c_str()); @@ -365,30 +377,26 @@ void GLTiledTextureEffect::emitCode(EmitArgs& args) { } } -void GLTiledTextureEffect::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& textureFP = static_cast(fragmentProcessor); - auto hasDimensionUniform = (ShaderModeRequiresUnormCoord(textureFP.shaderModeX) || - ShaderModeRequiresUnormCoord(textureFP.shaderModeY)) && - textureFP.texture->getSampler()->type() != TextureType::Rectangle; +void GLTiledTextureEffect::onSetData(UniformBuffer* uniformBuffer) const { + auto hasDimensionUniform = + (ShaderModeRequiresUnormCoord(shaderModeX) || ShaderModeRequiresUnormCoord(shaderModeY)) && + texture->getSampler()->type() != TextureType::Rectangle; if (hasDimensionUniform) { - auto dimensions = textureFP.texture->getTextureCoord(1.f, 1.f); + auto dimensions = texture->getTextureCoord(1.f, 1.f); uniformBuffer->setData("Dimension", &dimensions); } auto pushRect = [&](Rect subset, const std::string& uni) { float rect[4] = {subset.left, subset.top, subset.right, subset.bottom}; - if (textureFP.texture->origin() == ImageOrigin::BottomLeft) { - auto h = static_cast(textureFP.texture->height()); + if (texture->origin() == ImageOrigin::BottomLeft) { + auto h = static_cast(texture->height()); rect[1] = h - rect[1]; rect[3] = h - rect[3]; std::swap(rect[1], rect[3]); } - auto type = textureFP.texture->getSampler()->type(); + auto type = texture->getSampler()->type(); if (!hasDimensionUniform && type != TextureType::Rectangle) { - auto lt = textureFP.texture->getTextureCoord(static_cast(rect[0]), - static_cast(rect[1])); - auto rb = textureFP.texture->getTextureCoord(static_cast(rect[2]), - static_cast(rect[3])); + auto lt = texture->getTextureCoord(static_cast(rect[0]), static_cast(rect[1])); + auto rb = texture->getTextureCoord(static_cast(rect[2]), static_cast(rect[3])); rect[0] = lt.x; rect[1] = lt.y; rect[2] = rb.x; @@ -396,11 +404,11 @@ void GLTiledTextureEffect::onSetData(UniformBuffer* uniformBuffer, } uniformBuffer->setData(uni, &rect); }; - if (ShaderModeUsesSubset(textureFP.shaderModeX) || ShaderModeUsesSubset(textureFP.shaderModeY)) { - pushRect(textureFP.subset, "Subset"); + if (ShaderModeUsesSubset(shaderModeX) || ShaderModeUsesSubset(shaderModeY)) { + pushRect(subset, "Subset"); } - if (ShaderModeUsesClamp(textureFP.shaderModeX) || ShaderModeUsesClamp(textureFP.shaderModeY)) { - pushRect(textureFP.clamp, "Clamp"); + if (ShaderModeUsesClamp(shaderModeX) || ShaderModeUsesClamp(shaderModeY)) { + pushRect(clamp, "Clamp"); } } } // namespace tgfx diff --git a/tgfx/src/opengl/GLTiledTextureEffect.h b/tgfx/src/opengl/GLTiledTextureEffect.h index fd68414446..0ab622c8c4 100644 --- a/tgfx/src/opengl/GLTiledTextureEffect.h +++ b/tgfx/src/opengl/GLTiledTextureEffect.h @@ -19,13 +19,15 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" #include "gpu/TiledTextureEffect.h" namespace tgfx { -class GLTiledTextureEffect : public GLFragmentProcessor { +class GLTiledTextureEffect : public TiledTextureEffect { public: - void emitCode(EmitArgs& args) override; + GLTiledTextureEffect(std::shared_ptr texture, + const TiledTextureEffect::Sampling& sampling, const Matrix& localMatrix); + + void emitCode(EmitArgs& args) const override; private: struct UniformNames { @@ -34,7 +36,7 @@ class GLTiledTextureEffect : public GLFragmentProcessor { std::string dimensionsName; }; - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; static bool ShaderModeRequiresUnormCoord(TiledTextureEffect::ShaderMode m); @@ -43,19 +45,19 @@ class GLTiledTextureEffect : public GLFragmentProcessor { static bool ShaderModeUsesClamp(TiledTextureEffect::ShaderMode m); void readColor(EmitArgs& args, const std::string& dimensionsName, const std::string& coord, - const char* out); + const char* out) const; void subsetCoord(EmitArgs& args, TiledTextureEffect::ShaderMode mode, const std::string& subsetName, const char* coordSwizzle, const char* subsetStartSwizzle, const char* subsetStopSwizzle, - const char* extraCoord, const char* coordWeight); + const char* extraCoord, const char* coordWeight) const; void clampCoord(EmitArgs& args, bool clamp, const std::string& clampName, const char* coordSwizzle, const char* clampStartSwizzle, - const char* clampStopSwizzle); + const char* clampStopSwizzle) const; - void clampCoord(EmitArgs& args, const bool useClamp[2], const std::string& clampName); + void clampCoord(EmitArgs& args, const bool useClamp[2], const std::string& clampName) const; - UniformNames initUniform(EmitArgs& args, const bool useSubset[2], const bool useClamp[2]); + UniformNames initUniform(EmitArgs& args, const bool useSubset[2], const bool useClamp[2]) const; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLUnrolledBinaryGradientColorizer.cpp b/tgfx/src/opengl/GLUnrolledBinaryGradientColorizer.cpp index 6b25ca8499..d45a9d8fc1 100644 --- a/tgfx/src/opengl/GLUnrolledBinaryGradientColorizer.cpp +++ b/tgfx/src/opengl/GLUnrolledBinaryGradientColorizer.cpp @@ -18,6 +18,7 @@ #include "GLUnrolledBinaryGradientColorizer.h" #include "gpu/gradients/UnrolledBinaryGradientColorizer.h" +#include "utils/MathExtra.h" namespace tgfx { struct UnrolledBinaryUniformName { @@ -41,6 +42,79 @@ struct UnrolledBinaryUniformName { std::string thresholds9_13; }; +static constexpr int kMaxIntervals = 8; + +std::unique_ptr UnrolledBinaryGradientColorizer::Make( + const Color* colors, const float* positions, int count) { + // Depending on how the positions resolve into hard stops or regular stops, the number of + // intervals specified by the number of colors/positions can change. For instance, a plain + // 3 color gradient is two intervals, but a 4 color gradient with a hard stop is also + // two intervals. At the most extreme end, an 8 interval gradient made entirely of hard + // stops has 16 colors. + + if (count > kMaxColorCount) { + // Definitely cannot represent this gradient configuration + return nullptr; + } + + // The raster implementation also uses scales and biases, but since they must be calculated + // after the dst color space is applied, it limits our ability to cache their values. + Color scales[kMaxIntervals]; + Color biases[kMaxIntervals]; + float thresholds[kMaxIntervals]; + + int intervalCount = 0; + + for (int i = 0; i < count - 1; i++) { + if (intervalCount >= kMaxIntervals) { + // Already reached kMaxIntervals, and haven't run out of color stops so this + // gradient cannot be represented by this shader. + return nullptr; + } + + auto t0 = positions[i]; + auto t1 = positions[i + 1]; + auto dt = t1 - t0; + // If the interval is empty, skip to the next interval. This will automatically create + // distinct hard stop intervals as needed. It also protects against malformed gradients + // that have repeated hard stops at the very beginning that are effectively unreachable. + if (FloatNearlyZero(dt)) { + continue; + } + + for (int j = 0; j < 4; ++j) { + auto c0 = colors[i][j]; + auto c1 = colors[i + 1][j]; + auto scale = (c1 - c0) / dt; + auto bias = c0 - t0 * scale; + scales[intervalCount][j] = scale; + biases[intervalCount][j] = bias; + } + thresholds[intervalCount] = t1; + intervalCount++; + } + + // set the unused values to something consistent + for (int i = intervalCount; i < kMaxIntervals; i++) { + scales[i] = Color::Transparent(); + biases[i] = Color::Transparent(); + thresholds[i] = 0.0; + } + + return std::unique_ptr(new GLUnrolledBinaryGradientColorizer( + intervalCount, scales, biases, + Rect::MakeLTRB(thresholds[0], thresholds[1], thresholds[2], thresholds[3]), + Rect::MakeLTRB(thresholds[4], thresholds[5], thresholds[6], 0.0))); +} + +GLUnrolledBinaryGradientColorizer::GLUnrolledBinaryGradientColorizer(int intervalCount, + Color* scales, Color* biases, + Rect thresholds1_7, + Rect thresholds9_13) + : UnrolledBinaryGradientColorizer(intervalCount, scales, biases, thresholds1_7, + thresholds9_13) { +} + std::string AddUniform(UniformHandler* uniformHandler, const std::string& name, int intervalCount, int limit) { if (intervalCount > limit) { @@ -144,27 +218,26 @@ void AppendCode2(FragmentShaderBuilder* fragBuilder, int intervalCount, } } -void GLUnrolledBinaryGradientColorizer::emitCode(EmitArgs& args) { +void GLUnrolledBinaryGradientColorizer::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto* uniformHandler = args.uniformHandler; - const auto* fp = static_cast(args.fragmentProcessor); UnrolledBinaryUniformName uniformNames = {}; - uniformNames.scale0_1 = AddUniform(uniformHandler, "scale0_1", fp->intervalCount, 0); - uniformNames.scale2_3 = AddUniform(uniformHandler, "scale2_3", fp->intervalCount, 1); - uniformNames.scale4_5 = AddUniform(uniformHandler, "scale4_5", fp->intervalCount, 2); - uniformNames.scale6_7 = AddUniform(uniformHandler, "scale6_7", fp->intervalCount, 3); - uniformNames.scale8_9 = AddUniform(uniformHandler, "scale8_9", fp->intervalCount, 4); - uniformNames.scale10_11 = AddUniform(uniformHandler, "scale10_11", fp->intervalCount, 5); - uniformNames.scale12_13 = AddUniform(uniformHandler, "scale12_13", fp->intervalCount, 6); - uniformNames.scale14_15 = AddUniform(uniformHandler, "scale14_15", fp->intervalCount, 7); - uniformNames.bias0_1 = AddUniform(uniformHandler, "bias0_1", fp->intervalCount, 0); - uniformNames.bias2_3 = AddUniform(uniformHandler, "bias2_3", fp->intervalCount, 1); - uniformNames.bias4_5 = AddUniform(uniformHandler, "bias4_5", fp->intervalCount, 2); - uniformNames.bias6_7 = AddUniform(uniformHandler, "bias6_7", fp->intervalCount, 3); - uniformNames.bias8_9 = AddUniform(uniformHandler, "bias8_9", fp->intervalCount, 4); - uniformNames.bias10_11 = AddUniform(uniformHandler, "bias10_11", fp->intervalCount, 5); - uniformNames.bias12_13 = AddUniform(uniformHandler, "bias12_13", fp->intervalCount, 6); - uniformNames.bias14_15 = AddUniform(uniformHandler, "bias14_15", fp->intervalCount, 7); + uniformNames.scale0_1 = AddUniform(uniformHandler, "scale0_1", intervalCount, 0); + uniformNames.scale2_3 = AddUniform(uniformHandler, "scale2_3", intervalCount, 1); + uniformNames.scale4_5 = AddUniform(uniformHandler, "scale4_5", intervalCount, 2); + uniformNames.scale6_7 = AddUniform(uniformHandler, "scale6_7", intervalCount, 3); + uniformNames.scale8_9 = AddUniform(uniformHandler, "scale8_9", intervalCount, 4); + uniformNames.scale10_11 = AddUniform(uniformHandler, "scale10_11", intervalCount, 5); + uniformNames.scale12_13 = AddUniform(uniformHandler, "scale12_13", intervalCount, 6); + uniformNames.scale14_15 = AddUniform(uniformHandler, "scale14_15", intervalCount, 7); + uniformNames.bias0_1 = AddUniform(uniformHandler, "bias0_1", intervalCount, 0); + uniformNames.bias2_3 = AddUniform(uniformHandler, "bias2_3", intervalCount, 1); + uniformNames.bias4_5 = AddUniform(uniformHandler, "bias4_5", intervalCount, 2); + uniformNames.bias6_7 = AddUniform(uniformHandler, "bias6_7", intervalCount, 3); + uniformNames.bias8_9 = AddUniform(uniformHandler, "bias8_9", intervalCount, 4); + uniformNames.bias10_11 = AddUniform(uniformHandler, "bias10_11", intervalCount, 5); + uniformNames.bias12_13 = AddUniform(uniformHandler, "bias12_13", intervalCount, 6); + uniformNames.bias14_15 = AddUniform(uniformHandler, "bias14_15", intervalCount, 7); uniformNames.thresholds1_7 = args.uniformHandler->addUniform( ShaderFlags::Fragment, ShaderVar::Type::Float4, "thresholds1_7"); uniformNames.thresholds9_13 = args.uniformHandler->addUniform( @@ -172,18 +245,18 @@ void GLUnrolledBinaryGradientColorizer::emitCode(EmitArgs& args) { fragBuilder->codeAppendf("float t = %s.x;", args.inputColor.c_str()); fragBuilder->codeAppend("vec4 scale, bias;"); - fragBuilder->codeAppendf("// interval count: %d\n", fp->intervalCount); + fragBuilder->codeAppendf("// interval count: %d\n", intervalCount); - if (fp->intervalCount >= 4) { + if (intervalCount >= 4) { fragBuilder->codeAppend("// thresholds1_7.w is mid-point for intervals (0,7) and (8,15)\n"); fragBuilder->codeAppendf("if (t < %s.w) {", uniformNames.thresholds1_7.c_str()); } - AppendCode1(fragBuilder, fp->intervalCount, uniformNames); - if (fp->intervalCount > 4) { + AppendCode1(fragBuilder, intervalCount, uniformNames); + if (intervalCount > 4) { fragBuilder->codeAppend("} else {"); } - AppendCode2(fragBuilder, fp->intervalCount, uniformNames); - if (fp->intervalCount >= 4) { + AppendCode2(fragBuilder, intervalCount, uniformNames); + if (intervalCount >= 4) { fragBuilder->codeAppend("}"); } @@ -197,26 +270,24 @@ void SetUniformData(UniformBuffer* uniformBuffer, const std::string& name, int i } } -void GLUnrolledBinaryGradientColorizer::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& fp = static_cast(fragmentProcessor); - uniformBuffer->setData("scale0_1", fp.scale0_1.array()); - SetUniformData(uniformBuffer, "scale2_3", fp.intervalCount, 0, fp.scale2_3); - SetUniformData(uniformBuffer, "scale4_5", fp.intervalCount, 1, fp.scale4_5); - SetUniformData(uniformBuffer, "scale6_7", fp.intervalCount, 2, fp.scale6_7); - SetUniformData(uniformBuffer, "scale8_9", fp.intervalCount, 3, fp.scale8_9); - SetUniformData(uniformBuffer, "scale10_11", fp.intervalCount, 5, fp.scale10_11); - SetUniformData(uniformBuffer, "scale12_13", fp.intervalCount, 6, fp.scale12_13); - SetUniformData(uniformBuffer, "scale14_15", fp.intervalCount, 7, fp.scale14_15); - uniformBuffer->setData("bias0_1", fp.bias0_1.array()); - SetUniformData(uniformBuffer, "bias2_3", fp.intervalCount, 0, fp.bias2_3); - SetUniformData(uniformBuffer, "bias4_5", fp.intervalCount, 1, fp.bias4_5); - SetUniformData(uniformBuffer, "bias6_7", fp.intervalCount, 2, fp.bias6_7); - SetUniformData(uniformBuffer, "bias8_9", fp.intervalCount, 3, fp.bias8_9); - SetUniformData(uniformBuffer, "bias10_11", fp.intervalCount, 5, fp.bias10_11); - SetUniformData(uniformBuffer, "bias12_13", fp.intervalCount, 6, fp.bias12_13); - SetUniformData(uniformBuffer, "bias14_15", fp.intervalCount, 7, fp.bias14_15); - uniformBuffer->setData("thresholds1_7", reinterpret_cast(&(fp.thresholds1_7))); - uniformBuffer->setData("thresholds9_13", reinterpret_cast(&(fp.thresholds9_13))); +void GLUnrolledBinaryGradientColorizer::onSetData(UniformBuffer* uniformBuffer) const { + uniformBuffer->setData("scale0_1", scale0_1.array()); + SetUniformData(uniformBuffer, "scale2_3", intervalCount, 0, scale2_3); + SetUniformData(uniformBuffer, "scale4_5", intervalCount, 1, scale4_5); + SetUniformData(uniformBuffer, "scale6_7", intervalCount, 2, scale6_7); + SetUniformData(uniformBuffer, "scale8_9", intervalCount, 3, scale8_9); + SetUniformData(uniformBuffer, "scale10_11", intervalCount, 5, scale10_11); + SetUniformData(uniformBuffer, "scale12_13", intervalCount, 6, scale12_13); + SetUniformData(uniformBuffer, "scale14_15", intervalCount, 7, scale14_15); + uniformBuffer->setData("bias0_1", bias0_1.array()); + SetUniformData(uniformBuffer, "bias2_3", intervalCount, 0, bias2_3); + SetUniformData(uniformBuffer, "bias4_5", intervalCount, 1, bias4_5); + SetUniformData(uniformBuffer, "bias6_7", intervalCount, 2, bias6_7); + SetUniformData(uniformBuffer, "bias8_9", intervalCount, 3, bias8_9); + SetUniformData(uniformBuffer, "bias10_11", intervalCount, 5, bias10_11); + SetUniformData(uniformBuffer, "bias12_13", intervalCount, 6, bias12_13); + SetUniformData(uniformBuffer, "bias14_15", intervalCount, 7, bias14_15); + uniformBuffer->setData("thresholds1_7", reinterpret_cast(&(thresholds1_7))); + uniformBuffer->setData("thresholds9_13", reinterpret_cast(&(thresholds9_13))); } } // namespace tgfx diff --git a/tgfx/src/opengl/GLUnrolledBinaryGradientColorizer.h b/tgfx/src/opengl/GLUnrolledBinaryGradientColorizer.h index 9837e521e4..25230ce13f 100644 --- a/tgfx/src/opengl/GLUnrolledBinaryGradientColorizer.h +++ b/tgfx/src/opengl/GLUnrolledBinaryGradientColorizer.h @@ -19,7 +19,7 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" +#include "gpu/gradients/UnrolledBinaryGradientColorizer.h" namespace tgfx { /** @@ -36,11 +36,14 @@ namespace tgfx { * - .z = boundary between (12,13) and (14,15) -> 13_14 * - .w = unused */ -class GLUnrolledBinaryGradientColorizer : public GLFragmentProcessor { +class GLUnrolledBinaryGradientColorizer : public UnrolledBinaryGradientColorizer { public: - void emitCode(EmitArgs& args) override; + GLUnrolledBinaryGradientColorizer(int intervalCount, Color* scales, Color* biases, + Rect thresholds1_7, Rect thresholds9_13); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer*, const FragmentProcessor&) override; + void onSetData(UniformBuffer*) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLXfermodeFragmentProcessor.cpp b/tgfx/src/opengl/GLXfermodeFragmentProcessor.cpp index 7c4a4f6967..29d68373ab 100644 --- a/tgfx/src/opengl/GLXfermodeFragmentProcessor.cpp +++ b/tgfx/src/opengl/GLXfermodeFragmentProcessor.cpp @@ -18,13 +18,38 @@ #include "GLXfermodeFragmentProcessor.h" #include "GLBlend.h" +#include "gpu/ConstColorProcessor.h" #include "gpu/XfermodeFragmentProcessor.h" namespace tgfx { -void GLXfermodeFragmentProcessor::emitCode(EmitArgs& args) { +std::unique_ptr XfermodeFragmentProcessor::MakeFromTwoProcessors( + std::unique_ptr src, std::unique_ptr dst, + BlendMode mode) { + if (src == nullptr && dst == nullptr) { + return nullptr; + } + switch (mode) { + case BlendMode::Clear: + return ConstColorProcessor::Make(Color::Transparent(), InputMode::Ignore); + case BlendMode::Src: + return src; + case BlendMode::Dst: + return dst; + default: + return std::unique_ptr( + new GLXfermodeFragmentProcessor(std::move(src), std::move(dst), mode)); + } +} + +GLXfermodeFragmentProcessor::GLXfermodeFragmentProcessor(std::unique_ptr src, + std::unique_ptr dst, + BlendMode mode) + : XfermodeFragmentProcessor(std::move(src), std::move(dst), mode) { +} + +void GLXfermodeFragmentProcessor::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; - const auto* fp = static_cast(args.fragmentProcessor); - if (fp->child == XfermodeFragmentProcessor::Child::TwoChild) { + if (child == XfermodeFragmentProcessor::Child::TwoChild) { std::string inputColor; if (!args.inputColor.empty()) { inputColor = "inputColor"; @@ -34,8 +59,8 @@ void GLXfermodeFragmentProcessor::emitCode(EmitArgs& args) { emitChild(0, inputColor, &srcColor, args); std::string dstColor = "xfer_dst"; emitChild(1, inputColor, &dstColor, args); - fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", BlendModeName(fp->mode)); - AppendMode(fragBuilder, srcColor, dstColor, args.outputColor, fp->mode); + fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", BlendModeName(mode)); + AppendMode(fragBuilder, srcColor, dstColor, args.outputColor, mode); // re-multiply the output color by the input color's alpha if (!args.inputColor.empty()) { fragBuilder->codeAppendf("%s *= %s.a;", args.outputColor.c_str(), args.inputColor.c_str()); @@ -44,11 +69,11 @@ void GLXfermodeFragmentProcessor::emitCode(EmitArgs& args) { std::string childColor = "child"; emitChild(0, &childColor, args); // emit blend code - fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", BlendModeName(fp->mode)); - if (fp->child == XfermodeFragmentProcessor::Child::DstChild) { - AppendMode(fragBuilder, args.inputColor, childColor, args.outputColor, fp->mode); + fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", BlendModeName(mode)); + if (child == XfermodeFragmentProcessor::Child::DstChild) { + AppendMode(fragBuilder, args.inputColor, childColor, args.outputColor, mode); } else { - AppendMode(fragBuilder, childColor, args.inputColor, args.outputColor, fp->mode); + AppendMode(fragBuilder, childColor, args.inputColor, args.outputColor, mode); } } } diff --git a/tgfx/src/opengl/GLXfermodeFragmentProcessor.h b/tgfx/src/opengl/GLXfermodeFragmentProcessor.h index fb3e13eac6..b4f19aefbe 100644 --- a/tgfx/src/opengl/GLXfermodeFragmentProcessor.h +++ b/tgfx/src/opengl/GLXfermodeFragmentProcessor.h @@ -18,11 +18,14 @@ #pragma once -#include "gpu/GLFragmentProcessor.h" +#include "gpu/XfermodeFragmentProcessor.h" namespace tgfx { -class GLXfermodeFragmentProcessor : public GLFragmentProcessor { +class GLXfermodeFragmentProcessor : public XfermodeFragmentProcessor { public: - void emitCode(EmitArgs& args) override; + GLXfermodeFragmentProcessor(std::unique_ptr src, + std::unique_ptr dst, BlendMode mode); + + void emitCode(EmitArgs& args) const override; }; } // namespace tgfx diff --git a/tgfx/src/opengl/GLYUVTextureEffect.cpp b/tgfx/src/opengl/GLYUVTextureEffect.cpp index ed1a4e869f..3703f2f64f 100644 --- a/tgfx/src/opengl/GLYUVTextureEffect.cpp +++ b/tgfx/src/opengl/GLYUVTextureEffect.cpp @@ -20,17 +20,22 @@ #include "gpu/YUVTextureEffect.h" namespace tgfx { -void GLYUVTextureEffect::emitCode(EmitArgs& args) { - const auto* yuvFP = static_cast(args.fragmentProcessor); +GLYUVTextureEffect::GLYUVTextureEffect(std::shared_ptr texture, + tgfx::SamplingOptions sampling, + const tgfx::Point& alphaStart, + const tgfx::Matrix& localMatrix) + : YUVTextureEffect(std::move(texture), sampling, alphaStart, localMatrix) { +} + +void GLYUVTextureEffect::emitCode(EmitArgs& args) const { auto* fragBuilder = args.fragBuilder; auto* uniformHandler = args.uniformHandler; - auto yuvTexture = yuvFP->texture; fragBuilder->codeAppend("vec3 yuv;"); fragBuilder->codeAppend("yuv.x = "); fragBuilder->appendTextureLookup((*args.textureSamplers)[0], (*args.transformedCoords)[0].name()); fragBuilder->codeAppend(".r;"); - if (yuvTexture->pixelFormat() == YUVPixelFormat::I420) { + if (texture->pixelFormat() == YUVPixelFormat::I420) { fragBuilder->codeAppend("yuv.y = "); fragBuilder->appendTextureLookup((*args.textureSamplers)[1], (*args.transformedCoords)[0].name()); @@ -39,20 +44,20 @@ void GLYUVTextureEffect::emitCode(EmitArgs& args) { fragBuilder->appendTextureLookup((*args.textureSamplers)[2], (*args.transformedCoords)[0].name()); fragBuilder->codeAppend(".r;"); - } else if (yuvTexture->pixelFormat() == YUVPixelFormat::NV12) { + } else if (texture->pixelFormat() == YUVPixelFormat::NV12) { fragBuilder->codeAppend("yuv.yz = "); fragBuilder->appendTextureLookup((*args.textureSamplers)[1], (*args.transformedCoords)[0].name()); fragBuilder->codeAppend(".ra;"); } - if (IsLimitedYUVColorRange(yuvFP->texture->colorSpace())) { + if (IsLimitedYUVColorRange(texture->colorSpace())) { fragBuilder->codeAppend("yuv.x -= (16.0 / 255.0);"); } fragBuilder->codeAppend("yuv.yz -= vec2(0.5, 0.5);"); auto mat3Name = uniformHandler->addUniform(ShaderFlags::Fragment, ShaderVar::Type::Float3x3, "Mat3ColorConversion"); fragBuilder->codeAppendf("vec3 rgb = clamp(%s * yuv, 0.0, 1.0);", mat3Name.c_str()); - if (yuvFP->alphaStart == Point::Zero()) { + if (alphaStart == Point::Zero()) { fragBuilder->codeAppendf("%s = vec4(rgb, 1.0) * %s;", args.outputColor.c_str(), args.inputColor.c_str()); } else { @@ -102,15 +107,13 @@ static const float ColorConversionJPEGFullRange[] = { 1.0f, 1.0f, 1.0f, 0.0f, -0.344136f, 1.772000f, 1.402f, -0.714136f, 0.0f, }; -void GLYUVTextureEffect::onSetData(UniformBuffer* uniformBuffer, - const FragmentProcessor& fragmentProcessor) { - const auto& yuvFP = static_cast(fragmentProcessor); - if (yuvFP.alphaStart != Point::Zero()) { - auto alphaStart = yuvFP.texture->getTextureCoord(yuvFP.alphaStart.x, yuvFP.alphaStart.y); - uniformBuffer->setData("AlphaStart", &alphaStart); +void GLYUVTextureEffect::onSetData(UniformBuffer* uniformBuffer) const { + if (alphaStart != Point::Zero()) { + auto alphaStartValue = texture->getTextureCoord(alphaStart.x, alphaStart.y); + uniformBuffer->setData("AlphaStart", &alphaStartValue); } std::string mat3ColorConversion = "Mat3ColorConversion"; - switch (yuvFP.texture->colorSpace()) { + switch (texture->colorSpace()) { case YUVColorSpace::BT601_LIMITED: uniformBuffer->setData(mat3ColorConversion, ColorConversion601LimitRange); break; diff --git a/tgfx/src/opengl/GLYUVTextureEffect.h b/tgfx/src/opengl/GLYUVTextureEffect.h index ed03618a28..1e7ff82c44 100644 --- a/tgfx/src/opengl/GLYUVTextureEffect.h +++ b/tgfx/src/opengl/GLYUVTextureEffect.h @@ -19,15 +19,18 @@ #pragma once #include -#include "gpu/GLFragmentProcessor.h" #include "gpu/YUVTexture.h" +#include "gpu/YUVTextureEffect.h" namespace tgfx { -class GLYUVTextureEffect : public GLFragmentProcessor { +class GLYUVTextureEffect : public YUVTextureEffect { public: - void emitCode(EmitArgs& args) override; + GLYUVTextureEffect(std::shared_ptr texture, SamplingOptions sampling, + const Point& alphaStart, const Matrix& localMatrix); + + void emitCode(EmitArgs& args) const override; private: - void onSetData(UniformBuffer* uniformBuffer, const FragmentProcessor& fragmentProcessor) override; + void onSetData(UniformBuffer* uniformBuffer) const override; }; } // namespace tgfx