xref: /aosp_15_r20/frameworks/base/libs/hwui/ColorFilter.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1 /*
2  * Copyright (C) 2023 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 #ifndef COLORFILTER_H_
18 #define COLORFILTER_H_
19 
20 #include <stdint.h>
21 
22 #include <memory>
23 
24 #include "GraphicsJNI.h"
25 #include "RuntimeEffectUtils.h"
26 #include "SkColorFilter.h"
27 
28 namespace android {
29 namespace uirenderer {
30 
31 class ColorFilter : public VirtualLightRefBase {
32 public:
fromJava(jlong handle)33     static ColorFilter* fromJava(jlong handle) { return reinterpret_cast<ColorFilter*>(handle); }
34 
getInstance()35     sk_sp<SkColorFilter> getInstance() {
36         if (mInstance != nullptr && shouldDiscardInstance()) {
37             mInstance = nullptr;
38         }
39 
40         if (mInstance == nullptr) {
41             mInstance = createInstance();
42             if (mInstance) {
43                 mInstance = mInstance->makeWithWorkingColorSpace(SkColorSpace::MakeSRGB());
44             }
45             mGenerationId++;
46         }
47         return mInstance;
48     }
49 
shouldDiscardInstance()50     virtual bool shouldDiscardInstance() const { return false; }
51 
discardInstance()52     void discardInstance() { mInstance = nullptr; }
53 
getGenerationId()54     [[nodiscard]] int32_t getGenerationId() const { return mGenerationId; }
55 
56 protected:
57     ColorFilter() = default;
58     virtual sk_sp<SkColorFilter> createInstance() = 0;
59 
60 private:
61     sk_sp<SkColorFilter> mInstance = nullptr;
62     int32_t mGenerationId = 0;
63 };
64 
65 class BlendModeColorFilter : public ColorFilter {
66 public:
BlendModeColorFilter(SkColor color,SkBlendMode mode)67     BlendModeColorFilter(SkColor color, SkBlendMode mode) : mColor(color), mMode(mode) {}
68 
69 private:
createInstance()70     sk_sp<SkColorFilter> createInstance() override { return SkColorFilters::Blend(mColor, mMode); }
71 
72 private:
73     const SkColor mColor;
74     const SkBlendMode mMode;
75 };
76 
77 class LightingFilter : public ColorFilter {
78 public:
LightingFilter(SkColor mul,SkColor add)79     LightingFilter(SkColor mul, SkColor add) : mMul(mul), mAdd(add) {}
80 
setMul(SkColor mul)81     void setMul(SkColor mul) {
82         mMul = mul;
83         discardInstance();
84     }
85 
setAdd(SkColor add)86     void setAdd(SkColor add) {
87         mAdd = add;
88         discardInstance();
89     }
90 
91 private:
createInstance()92     sk_sp<SkColorFilter> createInstance() override { return SkColorFilters::Lighting(mMul, mAdd); }
93 
94 private:
95     SkColor mMul;
96     SkColor mAdd;
97 };
98 
99 class ColorMatrixColorFilter : public ColorFilter {
100 public:
ColorMatrixColorFilter(std::vector<float> && matrix)101     ColorMatrixColorFilter(std::vector<float>&& matrix) : mMatrix(std::move(matrix)) {}
102 
setMatrix(std::vector<float> && matrix)103     void setMatrix(std::vector<float>&& matrix) {
104         mMatrix = std::move(matrix);
105         discardInstance();
106     }
107 
108 private:
createInstance()109     sk_sp<SkColorFilter> createInstance() override {
110         return SkColorFilters::Matrix(mMatrix.data(), SkColorFilters::Clamp::kNo);
111     }
112 
113 private:
114     std::vector<float> mMatrix;
115 };
116 
117 class RuntimeColorFilter : public ColorFilter {
118 public:
RuntimeColorFilter(SkRuntimeEffectBuilder * builder)119     RuntimeColorFilter(SkRuntimeEffectBuilder* builder) : mBuilder(builder) {}
120 
updateUniforms(JNIEnv * env,const char * name,const float vals[],int count,bool isColor)121     void updateUniforms(JNIEnv* env, const char* name, const float vals[], int count,
122                         bool isColor) {
123         UpdateFloatUniforms(env, mBuilder, name, vals, count, isColor);
124         discardInstance();
125     }
126 
updateUniforms(JNIEnv * env,const char * name,const int vals[],int count)127     void updateUniforms(JNIEnv* env, const char* name, const int vals[], int count) {
128         UpdateIntUniforms(env, mBuilder, name, vals, count);
129         discardInstance();
130     }
131 
updateChild(JNIEnv * env,const char * name,SkFlattenable * childEffect)132     void updateChild(JNIEnv* env, const char* name, SkFlattenable* childEffect) {
133         UpdateChild(env, mBuilder, name, childEffect);
134         discardInstance();
135     }
136 
137 private:
createInstance()138     sk_sp<SkColorFilter> createInstance() override {
139         // TODO: throw error if null
140         return mBuilder->makeColorFilter();
141     }
142 
143 private:
144     SkRuntimeEffectBuilder* mBuilder;
145 };
146 
147 }  // namespace uirenderer
148 }  // namespace android
149 
150 #endif  // COLORFILTER_H_
151