1 /*
2  * Copyright 2020 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 <SkCanvas.h>
20 #include <SkImage.h>
21 #include <SkRuntimeEffect.h>
22 #include <SkSurface.h>
23 
24 #include "../compat/SkiaGpuContext.h"
25 
26 using namespace std;
27 
28 namespace android {
29 namespace renderengine {
30 namespace skia {
31 
32 class BlurFilter {
33 public:
34     // Downsample FBO to improve performance
35     static constexpr float kInputScale = 0.25f;
36     // Downsample scale factor used to improve performance
37     static constexpr float kInverseInputScale = 1.0f / kInputScale;
38 
39     explicit BlurFilter(float maxCrossFadeRadius = 10.0f);
~BlurFilter()40     virtual ~BlurFilter(){}
41 
42     // Execute blur, saving it to a texture
43     virtual sk_sp<SkImage> generate(SkiaGpuContext* context, const uint32_t radius,
44                                     const sk_sp<SkImage> blurInput,
45                                     const SkRect& blurRect) const = 0;
46 
47     /**
48      * Draw the blurred content (from the generate method) into the canvas.
49      * @param canvas is the destination/output for the blur
50      * @param effectRegion the RoundRect in canvas coordinates that determines the blur coverage
51      * @param blurRadius radius of the blur used to determine the intensity of the crossfade effect
52      * @param blurAlpha alpha value applied to the effectRegion when the blur is drawn
53      * @param blurRect bounds of the blurredImage translated into canvas coordinates
54      * @param blurredImage down-sampled blurred content that was produced by the generate() method
55      * @param input original unblurred input that is used to crossfade with the blurredImage
56      */
57     void drawBlurRegion(SkCanvas* canvas, const SkRRect& effectRegion,
58                                 const uint32_t blurRadius, const float blurAlpha,
59                                 const SkRect& blurRect, sk_sp<SkImage> blurredImage,
60                                 sk_sp<SkImage> input);
61 
62     float getMaxCrossFadeRadius() const;
63 
64 private:
65     // To avoid downscaling artifacts, we interpolate the blurred fbo with the full composited
66     // image, up to this radius.
67     const float mMaxCrossFadeRadius;
68 
69     // Optional blend used for crossfade only if mMaxCrossFadeRadius > 0
70     const sk_sp<SkRuntimeEffect> mMixEffect;
71 };
72 
73 } // namespace skia
74 } // namespace renderengine
75 } // namespace android
76