diff --git a/gfx/layers/opengl/OGLShaderProgram.cpp b/gfx/layers/opengl/OGLShaderProgram.cpp index 4abe986fb4e..faf49f3ebe3 100644 --- a/gfx/layers/opengl/OGLShaderProgram.cpp +++ b/gfx/layers/opengl/OGLShaderProgram.cpp @@ -49,6 +49,10 @@ AddUniforms(ProgramProfileOGL& aProfile) "uTexturePass2", "uColorMatrix", "uColorMatrixVector", + "uBlurRadius", + "uBlurOffset", + "uBlurAlpha", + "uBlurGaussianKernel", nullptr }; @@ -549,5 +553,25 @@ ShaderProgramOGL::Activate() mGL->fUseProgram(mProgram); } +void +ShaderProgramOGL::SetBlurRadius(float aRX, float aRY) +{ + float f[] = {aRX, aRY}; + SetUniform(KnownUniform::BlurRadius, 2, f); + + float gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH]; + float sum = 0.0f; + for (int i = 0; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) { + float x = i * GAUSSIAN_KERNEL_STEP; + float sigma = 1.0f; + gaussianKernel[i] = exp(-x * x / (2 * sigma * sigma)) / sqrt(2 * M_PI * sigma * sigma); + sum += gaussianKernel[i] * (i == 0 ? 1 : 2); + } + for (int i = 0; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) { + gaussianKernel[i] /= sum; + } + SetArrayUniform(KnownUniform::BlurGaussianKernel, GAUSSIAN_KERNEL_HALF_WIDTH, gaussianKernel); +} + } /* layers */ } /* mozilla */ diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h index 51ecaaeed36..a7305809fa2 100644 --- a/gfx/layers/opengl/OGLShaderProgram.h +++ b/gfx/layers/opengl/OGLShaderProgram.h @@ -70,6 +70,10 @@ public: TexturePass2, ColorMatrix, ColorMatrixVector, + BlurRadius, + BlurOffset, + BlurAlpha, + BlurGaussianKernel, KnownUniformCount }; @@ -147,6 +151,19 @@ public: return false; } + bool UpdateArrayUniform(int cnt, const float *fp) { + if (mLocation == -1) return false; + if (cnt > 16) { + return false; + } + + if (memcmp(mValue.f16v, fp, sizeof(float) * cnt) != 0) { + memcpy(mValue.f16v, fp, sizeof(float) * cnt); + return true; + } + return false; + } + KnownUniformName mName; const char *mNameString; int32_t mLocation; @@ -389,6 +406,17 @@ public: SetUniform(KnownUniform::TexturePass2, aFlag ? 1 : 0); } + void SetBlurRadius(float aRX, float aRY); + + void SetBlurAlpha(float aAlpha) { + SetUniform(KnownUniform::BlurAlpha, aAlpha); + } + + void SetBlurOffset(float aOffsetX, float aOffsetY) { + float f[] = {aOffsetX, aOffsetY}; + SetUniform(KnownUniform::BlurOffset, 2, f); + } + size_t GetTextureCount() const { return mProfile.mTextureCount; } @@ -459,6 +487,17 @@ protected: } } + void SetArrayUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, float *aFloatValues) + { + ASSERT_THIS_PROGRAM; + NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); + + KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); + if (ku.UpdateArrayUniform(aLength, aFloatValues)) { + mGL->fUniform1fv(ku.mLocation, aLength, ku.mValue.f16v); + } + } + void SetUniform(KnownUniform::KnownUniformName aKnownUniform, GLint aIntValue) { ASSERT_THIS_PROGRAM; NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");