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