1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <ui/GraphicTypes.h>
20 #include "../GLESRenderEngine.h"
21 #include "../GLFramebuffer.h"
22 #include "../GLVertexBuffer.h"
23 #include "GenericProgram.h"
24 
25 using namespace std;
26 
27 namespace android {
28 namespace renderengine {
29 namespace gl {
30 
31 /**
32  * This is an implementation of a Kawase blur, as described in here:
33  * https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/
34  * 00-00-00-20-66/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf
35  */
36 class BlurFilter {
37 public:
38     // Downsample FBO to improve performance
39     static constexpr float kFboScale = 0.25f;
40     // Maximum number of render passes
41     static constexpr uint32_t kMaxPasses = 4;
42     // To avoid downscaling artifacts, we interpolate the blurred fbo with the full composited
43     // image, up to this radius.
44     static constexpr float kMaxCrossFadeRadius = 30.0f;
45 
46     explicit BlurFilter(GLESRenderEngine& engine);
~BlurFilter()47     virtual ~BlurFilter(){};
48 
49     // Set up render targets, redirecting output to offscreen texture.
50     status_t setAsDrawTarget(const DisplaySettings&, uint32_t radius);
51     // Execute blur passes, rendering to offscreen texture.
52     status_t prepare();
53     // Render blur to the bound framebuffer (screen).
54     status_t render(bool multiPass);
55 
56 private:
57     uint32_t mRadius;
58     void drawMesh(GLuint uv, GLuint position);
59     string getVertexShader() const;
60     string getFragmentShader() const;
61     string getMixFragShader() const;
62 
63     GLESRenderEngine& mEngine;
64     // Frame buffer holding the composited background.
65     GLFramebuffer mCompositionFbo;
66     // Frame buffers holding the blur passes.
67     GLFramebuffer mPingFbo;
68     GLFramebuffer mPongFbo;
69     uint32_t mDisplayWidth = 0;
70     uint32_t mDisplayHeight = 0;
71     uint32_t mDisplayX = 0;
72     uint32_t mDisplayY = 0;
73     // Buffer holding the final blur pass.
74     GLFramebuffer* mLastDrawTarget;
75 
76     // VBO containing vertex and uv data of a fullscreen triangle.
77     GLVertexBuffer mMeshBuffer;
78 
79     GenericProgram mMixProgram;
80     GLuint mMPosLoc;
81     GLuint mMUvLoc;
82     GLuint mMMixLoc;
83     GLuint mMTextureLoc;
84     GLuint mMCompositionTextureLoc;
85 
86     GenericProgram mBlurProgram;
87     GLuint mBPosLoc;
88     GLuint mBUvLoc;
89     GLuint mBTextureLoc;
90     GLuint mBOffsetLoc;
91 };
92 
93 } // namespace gl
94 } // namespace renderengine
95 } // namespace android
96