Have a single blur implementation

After experimenting with both Gaussian and Kawase, we concluded
that Kawase has similar visuals and better performance.

This CL removes GaussianBlurFilter and promotes KawaseBlurFilter
to just BlurFilter.

Bug: 149792636
Test: librenderengine_test
Test: visual
Change-Id: I6d5790b2735754b5a39dd7367280871ab43f723c
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index 3d77059..1075f16 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -59,8 +59,6 @@
         "gl/Program.cpp",
         "gl/ProgramCache.cpp",
         "gl/filters/BlurFilter.cpp",
-        "gl/filters/KawaseBlurFilter.cpp",
-        "gl/filters/GaussianBlurFilter.cpp",
         "gl/filters/GenericProgram.cpp",
     ],
 }
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index e11b59f..daf7d72 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -50,8 +50,6 @@
 #include "Program.h"
 #include "ProgramCache.h"
 #include "filters/BlurFilter.h"
-#include "filters/GaussianBlurFilter.h"
-#include "filters/KawaseBlurFilter.h"
 
 extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 
@@ -430,13 +428,7 @@
     }
 
     if (args.supportsBackgroundBlur) {
-        char isGaussian[PROPERTY_VALUE_MAX];
-        property_get("debug.sf.gaussianBlur", isGaussian, "0");
-        if (atoi(isGaussian)) {
-            mBlurFilter = new GaussianBlurFilter(*this);
-        } else {
-            mBlurFilter = new KawaseBlurFilter(*this);
-        }
+        mBlurFilter = new BlurFilter(*this);
         checkErrors("BlurFilter creation");
     }
 
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index ebf78fe..4cd0b3d 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -261,8 +261,6 @@
     friend class ImageManager;
     friend class GLFramebuffer;
     friend class BlurFilter;
-    friend class GaussianBlurFilter;
-    friend class KawaseBlurFilter;
     friend class GenericProgram;
     std::unique_ptr<FlushTracer> mFlushTracer;
     std::unique_ptr<ImageManager> mImageManager = std::make_unique<ImageManager>(this);
diff --git a/libs/renderengine/gl/filters/BlurFilter.cpp b/libs/renderengine/gl/filters/BlurFilter.cpp
index eb66c8f..4d6694a 100644
--- a/libs/renderengine/gl/filters/BlurFilter.cpp
+++ b/libs/renderengine/gl/filters/BlurFilter.cpp
@@ -31,13 +31,24 @@
 namespace gl {
 
 BlurFilter::BlurFilter(GLESRenderEngine& engine)
-      : mEngine(engine), mCompositionFbo(engine), mBlurredFbo(engine), mMixProgram(engine) {
+      : mEngine(engine),
+        mCompositionFbo(engine),
+        mBlurredFbo(engine),
+        mPingPongFbo(engine),
+        mMixProgram(engine),
+        mBlurProgram(engine) {
     mMixProgram.compile(getVertexShader(), getMixFragShader());
     mMPosLoc = mMixProgram.getAttributeLocation("aPosition");
     mMUvLoc = mMixProgram.getAttributeLocation("aUV");
     mMTextureLoc = mMixProgram.getUniformLocation("uTexture");
     mMCompositionTextureLoc = mMixProgram.getUniformLocation("uCompositionTexture");
     mMMixLoc = mMixProgram.getUniformLocation("uMix");
+
+    mBlurProgram.compile(getVertexShader(), getFragmentShader());
+    mBPosLoc = mBlurProgram.getAttributeLocation("aPosition");
+    mBUvLoc = mBlurProgram.getAttributeLocation("aUV");
+    mBTextureLoc = mBlurProgram.getUniformLocation("uTexture");
+    mBOffsetLoc = mBlurProgram.getUniformLocation("uOffset");
 }
 
 status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display, uint32_t radius) {
@@ -52,7 +63,7 @@
         const uint32_t fboWidth = floorf(mDisplayWidth * kFboScale);
         const uint32_t fboHeight = floorf(mDisplayHeight * kFboScale);
         mBlurredFbo.allocateBuffers(fboWidth, fboHeight);
-        allocateTextures();
+        mPingPongFbo.allocateBuffers(fboWidth, fboHeight);
         mTexturesAllocated = true;
     }
 
@@ -96,6 +107,65 @@
     mEngine.checkErrors("Drawing blur mesh");
 }
 
+status_t BlurFilter::prepare() {
+    ATRACE_NAME("BlurFilter::prepare");
+
+    if (mPingPongFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) {
+        ALOGE("Invalid FBO");
+        return mPingPongFbo.getStatus();
+    }
+    if (!mBlurProgram.isValid()) {
+        ALOGE("Invalid shader");
+        return GL_INVALID_OPERATION;
+    }
+
+    blit(mCompositionFbo, mBlurredFbo);
+
+    // Kawase is an approximation of Gaussian, but it behaves differently from it.
+    // A radius transformation is required for approximating them, and also to introduce
+    // non-integer steps, necessary to smoothly interpolate large radii.
+    auto radius = mRadius / 6.0f;
+
+    // Calculate how many passes we'll do, based on the radius.
+    // Too many passes will make the operation expensive.
+    auto passes = min(kMaxPasses, (uint32_t)ceil(radius));
+
+    // We'll ping pong between our textures, to accumulate the result of various offsets.
+    mBlurProgram.useProgram();
+    GLFramebuffer* draw = &mPingPongFbo;
+    GLFramebuffer* read = &mBlurredFbo;
+    float stepX = radius / (float)mCompositionFbo.getBufferWidth() / (float)passes;
+    float stepY = radius / (float)mCompositionFbo.getBufferHeight() / (float)passes;
+    glActiveTexture(GL_TEXTURE0);
+    glUniform1i(mBTextureLoc, 0);
+    for (auto i = 0; i < passes; i++) {
+        ATRACE_NAME("BlurFilter::renderPass");
+        draw->bind();
+
+        glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight());
+        glBindTexture(GL_TEXTURE_2D, read->getTextureName());
+        glUniform2f(mBOffsetLoc, stepX * i, stepY * i);
+        mEngine.checkErrors("Setting uniforms");
+
+        drawMesh(mBUvLoc, mBPosLoc);
+
+        // Swap buffers for next iteration
+        auto tmp = draw;
+        draw = read;
+        read = tmp;
+    }
+
+    // Copy texture, given that we're expected to end on mBlurredFbo.
+    if (draw == &mBlurredFbo) {
+        blit(mPingPongFbo, mBlurredFbo);
+    }
+
+    // Cleanup
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    return NO_ERROR;
+}
+
 status_t BlurFilter::render(bool multiPass) {
     ATRACE_NAME("BlurFilter::render");
 
@@ -145,6 +215,28 @@
     )SHADER";
 }
 
+string BlurFilter::getFragmentShader() const {
+    return R"SHADER(#version 310 es
+        precision mediump float;
+
+        uniform sampler2D uTexture;
+        uniform vec2 uOffset;
+
+        highp in vec2 vUV;
+        out vec4 fragColor;
+
+        void main() {
+            fragColor  = texture(uTexture, vUV, 0.0);
+            fragColor += texture(uTexture, vUV + vec2( uOffset.x,  uOffset.y), 0.0);
+            fragColor += texture(uTexture, vUV + vec2( uOffset.x, -uOffset.y), 0.0);
+            fragColor += texture(uTexture, vUV + vec2(-uOffset.x,  uOffset.y), 0.0);
+            fragColor += texture(uTexture, vUV + vec2(-uOffset.x, -uOffset.y), 0.0);
+
+            fragColor = vec4(fragColor.rgb * 0.2, 1.0);
+        }
+    )SHADER";
+}
+
 string BlurFilter::getMixFragShader() const {
     string shader = R"SHADER(#version 310 es
         precision mediump float;
@@ -165,6 +257,15 @@
     return shader;
 }
 
+void BlurFilter::blit(GLFramebuffer& read, GLFramebuffer& draw) const {
+    read.bindAsReadBuffer();
+    draw.bindAsDrawBuffer();
+    glBlitFramebuffer(0, 0, read.getBufferWidth(), read.getBufferHeight(), 0, 0,
+                      draw.getBufferWidth(), draw.getBufferHeight(), GL_COLOR_BUFFER_BIT,
+                      GL_LINEAR);
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
 } // namespace gl
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/gl/filters/BlurFilter.h b/libs/renderengine/gl/filters/BlurFilter.h
index 52dc8aa..32af8b0 100644
--- a/libs/renderengine/gl/filters/BlurFilter.h
+++ b/libs/renderengine/gl/filters/BlurFilter.h
@@ -27,10 +27,17 @@
 namespace renderengine {
 namespace gl {
 
+/**
+ * This is an implementation of a Kawase blur, as described in here:
+ * https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/
+ * 00-00-00-20-66/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf
+ */
 class BlurFilter {
 public:
     // Downsample FBO to improve performance
     static constexpr float kFboScale = 0.25f;
+    // Maximum number of render passes
+    static constexpr uint32_t kMaxPasses = 6;
     // To avoid downscaling artifacts, we interpolate the blurred fbo with the full composited
     // image, up to this radius.
     static constexpr float kMaxCrossFadeRadius = 30.0f;
@@ -40,17 +47,18 @@
 
     // Set up render targets, redirecting output to offscreen texture.
     status_t setAsDrawTarget(const DisplaySettings&, uint32_t radius);
-    // Allocate any textures needed for the filter.
-    virtual void allocateTextures() = 0;
     // Execute blur passes, rendering to offscreen texture.
-    virtual status_t prepare() = 0;
+    status_t prepare();
     // Render blur to the bound framebuffer (screen).
     status_t render(bool multiPass);
 
-protected:
+private:
     uint32_t mRadius;
     void drawMesh(GLuint uv, GLuint position);
+    void blit(GLFramebuffer& read, GLFramebuffer& draw) const;
     string getVertexShader() const;
+    string getFragmentShader() const;
+    string getMixFragShader() const;
 
     GLESRenderEngine& mEngine;
     // Frame buffer holding the composited background.
@@ -59,9 +67,7 @@
     GLFramebuffer mBlurredFbo;
     uint32_t mDisplayWidth;
     uint32_t mDisplayHeight;
-
-private:
-    string getMixFragShader() const;
+    GLFramebuffer mPingPongFbo;
     bool mTexturesAllocated = false;
 
     GenericProgram mMixProgram;
@@ -70,6 +76,12 @@
     GLuint mMMixLoc;
     GLuint mMTextureLoc;
     GLuint mMCompositionTextureLoc;
+
+    GenericProgram mBlurProgram;
+    GLuint mBPosLoc;
+    GLuint mBUvLoc;
+    GLuint mBTextureLoc;
+    GLuint mBOffsetLoc;
 };
 
 } // namespace gl
diff --git a/libs/renderengine/gl/filters/GaussianBlurFilter.cpp b/libs/renderengine/gl/filters/GaussianBlurFilter.cpp
deleted file mode 100644
index a0d7af8..0000000
--- a/libs/renderengine/gl/filters/GaussianBlurFilter.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * 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.
- */
-
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#include "GaussianBlurFilter.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <ui/GraphicTypes.h>
-#include <cstdint>
-
-#include <utils/Trace.h>
-
-#define PI 3.14159265359
-#define THETA 0.352
-#define K 1.0 / (2.0 * THETA * THETA)
-
-namespace android {
-namespace renderengine {
-namespace gl {
-
-GaussianBlurFilter::GaussianBlurFilter(GLESRenderEngine& engine)
-      : BlurFilter(engine),
-        mVerticalPassFbo(engine),
-        mVerticalProgram(engine),
-        mHorizontalProgram(engine) {
-    mVerticalProgram.compile(getVertexShader(), getFragmentShader(false));
-    mVPosLoc = mVerticalProgram.getAttributeLocation("aPosition");
-    mVUvLoc = mVerticalProgram.getAttributeLocation("aUV");
-    mVTextureLoc = mVerticalProgram.getUniformLocation("uTexture");
-    mVGaussianOffsetLoc = mVerticalProgram.getUniformLocation("uGaussianOffsets");
-    mVNumSamplesLoc = mVerticalProgram.getUniformLocation("uSamples");
-    mVGaussianWeightLoc = mVerticalProgram.getUniformLocation("uGaussianWeights");
-
-    mHorizontalProgram.compile(getVertexShader(), getFragmentShader(true));
-    mHPosLoc = mHorizontalProgram.getAttributeLocation("aPosition");
-    mHUvLoc = mHorizontalProgram.getAttributeLocation("aUV");
-    mHTextureLoc = mHorizontalProgram.getUniformLocation("uTexture");
-    mHGaussianOffsetLoc = mHorizontalProgram.getUniformLocation("uGaussianOffsets");
-    mHNumSamplesLoc = mHorizontalProgram.getUniformLocation("uSamples");
-    mHGaussianWeightLoc = mHorizontalProgram.getUniformLocation("uGaussianWeights");
-}
-
-void GaussianBlurFilter::allocateTextures() {
-    mVerticalPassFbo.allocateBuffers(mBlurredFbo.getBufferWidth(), mBlurredFbo.getBufferHeight());
-}
-
-static void calculateLinearGaussian(uint32_t samples, double dimension,
-                                    GLfloat* gaussianLinearOffsets, GLfloat* gaussianWeights,
-                                    GLfloat* gaussianLinearWeights) {
-    // The central point in the symmetric bell curve is not offset.
-    // This decision allows one less sampling in the GPU.
-    gaussianLinearWeights[0] = gaussianWeights[0];
-    gaussianLinearOffsets[0] = 0.0;
-
-    // Calculate the linear weights.
-    // This is a vector reduction where an element of the packed reduced array
-    // contains the sum of two adjacent members of the original packed array.
-    // We start preserving the element 1 of the array and then perform sum for
-    // every other (i+=2) element of the gaussianWeights array.
-    gaussianLinearWeights[1] = gaussianWeights[1];
-    const auto start = 1 + ((samples - 1) & 0x1);
-    for (size_t i = start; i < samples; i += 2) {
-        gaussianLinearWeights[start + i / 2] = gaussianWeights[i] + gaussianWeights[i + 1];
-    }
-
-    // Calculate the texture coordinates offsets as an average of the initial offsets,
-    // weighted by the Gaussian weights as described in the original article.
-    gaussianLinearOffsets[1] = 1.0 / dimension;
-    for (size_t i = start; i < samples; i += 2) {
-        GLfloat offset_1 = float(i) / dimension;
-        GLfloat offset_2 = float(i + 1) / dimension;
-        gaussianLinearOffsets[start + i / 2] =
-                (offset_1 * gaussianWeights[i] + offset_2 * gaussianWeights[i + 1]) /
-                gaussianLinearWeights[start + i / 2];
-    }
-}
-status_t GaussianBlurFilter::prepare() {
-    ATRACE_NAME("GaussianBlurFilter::prepare");
-
-    if (mVerticalPassFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) {
-        ALOGE("Invalid vertical FBO");
-        return mVerticalPassFbo.getStatus();
-    }
-    if (!mVerticalProgram.isValid()) {
-        ALOGE("Invalid vertical shader");
-        return GL_INVALID_OPERATION;
-    }
-    if (!mHorizontalProgram.isValid()) {
-        ALOGE("Invalid horizontal shader");
-        return GL_INVALID_OPERATION;
-    }
-
-    mCompositionFbo.bindAsReadBuffer();
-    mBlurredFbo.bindAsDrawBuffer();
-    glBlitFramebuffer(0, 0, mCompositionFbo.getBufferWidth(), mCompositionFbo.getBufferHeight(), 0,
-                      0, mBlurredFbo.getBufferWidth(), mBlurredFbo.getBufferHeight(),
-                      GL_COLOR_BUFFER_BIT, GL_LINEAR);
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
-    // First, we'll apply the vertical pass, that receives the flattened background layers.
-    mVerticalPassFbo.bind();
-    mVerticalProgram.useProgram();
-
-    // Precompute gaussian bell curve, and send it to the shader to avoid unnecessary computations.
-    double radiusD = fmax(1.0, mRadius * kFboScale);
-    auto samples = int(fmin(radiusD, kNumSamples));
-    GLfloat gaussianWeights[kNumSamples] = {};
-
-    gaussianWeights[0] = 1.0f;
-    auto totalWeight = gaussianWeights[0];
-
-    // Gaussian weights calculation.
-    for (size_t i = 1; i < samples; i++) {
-        const double normalized = i / radiusD;
-        gaussianWeights[i] = (float)exp(-K * normalized * normalized);
-        totalWeight += 2.0 * gaussianWeights[i];
-    }
-
-    // Gaussian weights normalization to avoid work in the GPU.
-    for (size_t i = 0; i < samples; i++) {
-        gaussianWeights[i] /= totalWeight;
-    }
-
-    auto width = mVerticalPassFbo.getBufferWidth();
-    auto height = mVerticalPassFbo.getBufferHeight();
-    glViewport(0, 0, width, height);
-
-    // Allocate space for the corrected Gaussian weights and offsets.
-    // We could use less space, but let's keep the code simple.
-    GLfloat gaussianLinearWeights[kNumSamples] = {};
-    GLfloat gaussianLinearOffsets[kNumSamples] = {};
-
-    // Calculate the weights and offsets for the vertical pass.
-    // This only need to be called every time mRadius or height changes, so it could be optimized.
-    calculateLinearGaussian(samples, double(height), gaussianLinearOffsets, gaussianWeights,
-                            gaussianLinearWeights);
-    // set uniforms
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, mBlurredFbo.getTextureName());
-    glUniform1i(mVTextureLoc, 0);
-    glUniform1i(mVNumSamplesLoc, 1 + (samples + 1) / 2);
-    glUniform1fv(mVGaussianWeightLoc, kNumSamples, gaussianLinearWeights);
-    glUniform1fv(mVGaussianOffsetLoc, kNumSamples, gaussianLinearOffsets);
-    mEngine.checkErrors("Setting vertical pass uniforms");
-
-    drawMesh(mVUvLoc, mVPosLoc);
-
-    // Blur vertically on a secondary pass
-    mBlurredFbo.bind();
-    mHorizontalProgram.useProgram();
-
-    // Calculate the weights and offsets for the horizontal pass.
-    // This only needs to be called every time mRadius or width change, so it could be optimized.
-    calculateLinearGaussian(samples, double(width), gaussianLinearOffsets, gaussianWeights,
-                            gaussianLinearWeights);
-    // set uniforms
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, mVerticalPassFbo.getTextureName());
-    glUniform1i(mHTextureLoc, 0);
-    glUniform1i(mHNumSamplesLoc, 1 + (samples + 1) / 2);
-    glUniform1fv(mHGaussianWeightLoc, kNumSamples, gaussianLinearWeights);
-    glUniform1fv(mHGaussianOffsetLoc, kNumSamples, gaussianLinearOffsets);
-    mEngine.checkErrors("Setting horizontal pass uniforms");
-
-    drawMesh(mHUvLoc, mHPosLoc);
-
-    // reset active texture
-    mBlurredFbo.unbind();
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, 0);
-
-    // unbind program
-    glUseProgram(0);
-
-    return NO_ERROR;
-}
-
-string GaussianBlurFilter::getFragmentShader(bool horizontal) const {
-    stringstream shader;
-    shader << "#version 310 es\n"
-           << "#define DIRECTION " << (horizontal ? "1" : "0") << "\n"
-           << "#define NUM_SAMPLES " << 1 + (kNumSamples + 1) / 2 <<
-            R"SHADER(
-        precision mediump float;
-
-        uniform sampler2D uTexture;
-        uniform float[NUM_SAMPLES] uGaussianWeights;
-        uniform float[NUM_SAMPLES] uGaussianOffsets;
-        uniform int uSamples;
-
-        highp in vec2 vUV;
-        out vec4 fragColor;
-
-        void main() {
-            #if DIRECTION == 1
-            const vec2 direction = vec2(1.0, 0.0);
-            #else
-            const vec2 direction = vec2(0.0, 1.0);
-            #endif
-
-            // Iteration zero outside loop to avoid sampling the central point twice.
-            vec4 blurred = uGaussianWeights[0] * (texture(uTexture, vUV, 0.0));
-
-            // Iterate one side of the bell to halve the loop iterations.
-            for (int i = 1; i <= uSamples; i++) {
-                vec2 offset = uGaussianOffsets[i] * direction;
-                blurred += uGaussianWeights[i] * (texture(uTexture, vUV + offset, 0.0));
-                blurred += uGaussianWeights[i] * (texture(uTexture, vUV - offset, 0.0));
-            }
-
-            fragColor = vec4(blurred.rgb, 1.0);
-        }
-    )SHADER";
-    return shader.str();
-}
-
-} // namespace gl
-} // namespace renderengine
-} // namespace android
diff --git a/libs/renderengine/gl/filters/GaussianBlurFilter.h b/libs/renderengine/gl/filters/GaussianBlurFilter.h
deleted file mode 100644
index 44f5fde..0000000
--- a/libs/renderengine/gl/filters/GaussianBlurFilter.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * 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 <ui/GraphicTypes.h>
-#include "../GLESRenderEngine.h"
-#include "../GLFramebuffer.h"
-#include "BlurFilter.h"
-#include "GenericProgram.h"
-
-using namespace std;
-
-namespace android {
-namespace renderengine {
-namespace gl {
-
-// Class that implements a Gaussian Filter that uses Linear Sampling
-// to halve the number of samples and reduce runtime by 40% as described in:
-// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling
-class GaussianBlurFilter : public BlurFilter {
-public:
-    static constexpr uint32_t kNumSamples = 22;
-
-    explicit GaussianBlurFilter(GLESRenderEngine& engine);
-    status_t prepare() override;
-    void allocateTextures() override;
-
-private:
-    string getFragmentShader(bool horizontal) const;
-
-    // Initial, vertical render pass
-    GLFramebuffer mVerticalPassFbo;
-
-    // Vertical pass and its uniforms
-    GenericProgram mVerticalProgram;
-    GLuint mVPosLoc;
-    GLuint mVUvLoc;
-    GLuint mVTextureLoc;
-    GLuint mVGaussianOffsetLoc;
-    GLuint mVNumSamplesLoc;
-    GLuint mVGaussianWeightLoc;
-
-    // Horizontal pass and its uniforms
-    GenericProgram mHorizontalProgram;
-    GLuint mHPosLoc;
-    GLuint mHUvLoc;
-    GLuint mHTextureLoc;
-    GLuint mHGaussianOffsetLoc;
-    GLuint mHNumSamplesLoc;
-    GLuint mHGaussianWeightLoc;
-};
-
-} // namespace gl
-} // namespace renderengine
-} // namespace android
\ No newline at end of file
diff --git a/libs/renderengine/gl/filters/KawaseBlurFilter.cpp b/libs/renderengine/gl/filters/KawaseBlurFilter.cpp
deleted file mode 100644
index 7524c6d..0000000
--- a/libs/renderengine/gl/filters/KawaseBlurFilter.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * 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.
- */
-
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#include "KawaseBlurFilter.h"
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES3/gl3.h>
-#include <GLES3/gl3ext.h>
-#include <ui/GraphicTypes.h>
-
-#include <utils/Trace.h>
-
-namespace android {
-namespace renderengine {
-namespace gl {
-
-KawaseBlurFilter::KawaseBlurFilter(GLESRenderEngine& engine)
-      : BlurFilter(engine), mFbo(engine), mProgram(engine) {
-    mProgram.compile(getVertexShader(), getFragmentShader());
-    mPosLoc = mProgram.getAttributeLocation("aPosition");
-    mUvLoc = mProgram.getAttributeLocation("aUV");
-    mTextureLoc = mProgram.getUniformLocation("uTexture");
-    mOffsetLoc = mProgram.getUniformLocation("uOffset");
-}
-
-void KawaseBlurFilter::allocateTextures() {
-    mFbo.allocateBuffers(mBlurredFbo.getBufferWidth(), mBlurredFbo.getBufferHeight());
-}
-
-status_t KawaseBlurFilter::prepare() {
-    ATRACE_NAME("KawaseBlurFilter::prepare");
-
-    if (mFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) {
-        ALOGE("Invalid FBO");
-        return mFbo.getStatus();
-    }
-    if (!mProgram.isValid()) {
-        ALOGE("Invalid shader");
-        return GL_INVALID_OPERATION;
-    }
-
-    blit(mCompositionFbo, mBlurredFbo);
-
-    // Kawase is an approximation of Gaussian, but it behaves differently from it.
-    // A radius transformation is required for approximating them, and also to introduce
-    // non-integer steps, necessary to smoothly interpolate large radii.
-    auto radius = mRadius / 6.0f;
-
-    // Calculate how many passes we'll do, based on the radius.
-    // Too many passes will make the operation expensive.
-    auto passes = min(kMaxPasses, (uint32_t)ceil(radius));
-
-    // We'll ping pong between our textures, to accumulate the result of various offsets.
-    mProgram.useProgram();
-    GLFramebuffer* draw = &mFbo;
-    GLFramebuffer* read = &mBlurredFbo;
-    float stepX = radius / (float)mCompositionFbo.getBufferWidth() / (float)passes;
-    float stepY = radius / (float)mCompositionFbo.getBufferHeight() / (float)passes;
-    glActiveTexture(GL_TEXTURE0);
-    glUniform1i(mTextureLoc, 0);
-    for (auto i = 0; i < passes; i++) {
-        ATRACE_NAME("KawaseBlurFilter::renderPass");
-        draw->bind();
-
-        glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight());
-        glBindTexture(GL_TEXTURE_2D, read->getTextureName());
-        glUniform2f(mOffsetLoc, stepX * i, stepY * i);
-        mEngine.checkErrors("Setting uniforms");
-
-        drawMesh(mUvLoc, mPosLoc);
-
-        // Swap buffers for next iteration
-        auto tmp = draw;
-        draw = read;
-        read = tmp;
-    }
-
-    // Copy texture, given that we're expected to end on mBlurredFbo.
-    if (draw == &mBlurredFbo) {
-        blit(mFbo, mBlurredFbo);
-    }
-
-    // Cleanup
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
-    return NO_ERROR;
-}
-
-string KawaseBlurFilter::getFragmentShader() const {
-    return R"SHADER(#version 310 es
-        precision mediump float;
-
-        uniform sampler2D uTexture;
-        uniform vec2 uOffset;
-
-        highp in vec2 vUV;
-        out vec4 fragColor;
-
-        void main() {
-            fragColor  = texture(uTexture, vUV, 0.0);
-            fragColor += texture(uTexture, vUV + vec2( uOffset.x,  uOffset.y), 0.0);
-            fragColor += texture(uTexture, vUV + vec2( uOffset.x, -uOffset.y), 0.0);
-            fragColor += texture(uTexture, vUV + vec2(-uOffset.x,  uOffset.y), 0.0);
-            fragColor += texture(uTexture, vUV + vec2(-uOffset.x, -uOffset.y), 0.0);
-
-            fragColor = vec4(fragColor.rgb * 0.2, 1.0);
-        }
-    )SHADER";
-}
-
-void KawaseBlurFilter::blit(GLFramebuffer& read, GLFramebuffer& draw) const {
-    read.bindAsReadBuffer();
-    draw.bindAsDrawBuffer();
-    glBlitFramebuffer(0, 0, read.getBufferWidth(), read.getBufferHeight(), 0, 0,
-                      draw.getBufferWidth(), draw.getBufferHeight(), GL_COLOR_BUFFER_BIT,
-                      GL_LINEAR);
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
-}
-
-} // namespace gl
-} // namespace renderengine
-} // namespace android
diff --git a/libs/renderengine/gl/filters/KawaseBlurFilter.h b/libs/renderengine/gl/filters/KawaseBlurFilter.h
deleted file mode 100644
index 20009cf..0000000
--- a/libs/renderengine/gl/filters/KawaseBlurFilter.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * 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 <ui/GraphicTypes.h>
-#include "../GLESRenderEngine.h"
-#include "../GLFramebuffer.h"
-#include "BlurFilter.h"
-#include "GenericProgram.h"
-
-using namespace std;
-
-namespace android {
-namespace renderengine {
-namespace gl {
-
-class KawaseBlurFilter : public BlurFilter {
-public:
-    static constexpr uint32_t kMaxPasses = 6;
-
-    explicit KawaseBlurFilter(GLESRenderEngine& engine);
-    status_t prepare() override;
-    void allocateTextures() override;
-
-private:
-    string getFragmentShader() const;
-    void blit(GLFramebuffer& read, GLFramebuffer& draw) const;
-
-    GLFramebuffer mFbo;
-
-    GenericProgram mProgram;
-    GLuint mPosLoc;
-    GLuint mUvLoc;
-    GLuint mTextureLoc;
-    GLuint mOffsetLoc;
-};
-
-} // namespace gl
-} // namespace renderengine
-} // namespace android