1/* 2 * Copyright 2019 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8in fragmentProcessor inputFP; 9layout(ctype=SkM44, tracked) in uniform half4x4 m; 10layout(ctype=SkV4, tracked) in uniform half4 v; 11layout(key) in bool unpremulInput; 12layout(key) in bool clampRGBOutput; 13layout(key) in bool premulOutput; 14 15@optimizationFlags { 16 ProcessorOptimizationFlags(inputFP.get()) & kConstantOutputForConstantInput_OptimizationFlag 17} 18 19half4 main() { 20 half4 color = sample(inputFP); 21 @if (unpremulInput) { 22 color = unpremul(color); 23 } 24 color = m * color + v; 25 @if (clampRGBOutput) { 26 color = saturate(color); 27 } else { 28 color.a = saturate(color.a); 29 } 30 @if (premulOutput) { 31 color.rgb *= color.a; 32 } 33 return color; 34} 35 36@class { 37 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override { 38 SkPMColor4f input = ConstantOutputForConstantInput(this->childProcessor(0), inColor); 39 SkColor4f color; 40 if (unpremulInput) { 41 color = input.unpremul(); 42 } else { 43 color.fR = input.fR; 44 color.fG = input.fG; 45 color.fB = input.fB; 46 color.fA = input.fA; 47 } 48 auto v4 = m.map(color.fR, color.fG, color.fB, color.fA) + v; 49 color = {v4.x, v4.y, v4.z, v4.w}; 50 color.fA = SkTPin(color.fA, 0.f, 1.f); 51 if (clampRGBOutput) { 52 color.fR = SkTPin(color.fR, 0.f, 1.f); 53 color.fG = SkTPin(color.fG, 0.f, 1.f); 54 color.fB = SkTPin(color.fB, 0.f, 1.f); 55 } 56 if (premulOutput) { 57 return color.premul(); 58 } else { 59 return {color.fR, color.fG, color.fB, color.fA}; 60 } 61 } 62} 63 64@make { 65 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP, 66 const float matrix[20], bool unpremulInput, 67 bool clampRGBOutput, bool premulOutput) { 68 SkM44 m44( 69 matrix[ 0], matrix[ 1], matrix[ 2], matrix[ 3], 70 matrix[ 5], matrix[ 6], matrix[ 7], matrix[ 8], 71 matrix[10], matrix[11], matrix[12], matrix[13], 72 matrix[15], matrix[16], matrix[17], matrix[18] 73 ); 74 SkV4 v4 = {matrix[4], matrix[9], matrix[14], matrix[19]}; 75 return std::unique_ptr<GrFragmentProcessor>(new GrColorMatrixFragmentProcessor( 76 std::move(inputFP), m44, v4, unpremulInput, clampRGBOutput, premulOutput)); 77 } 78} 79 80@test(d) { 81 float m[20]; 82 for (int i = 0; i < 20; ++i) { 83 m[i] = d->fRandom->nextRangeScalar(-10.f, 10.f); 84 } 85 bool unpremul = d->fRandom->nextBool(); 86 bool clampRGB = d->fRandom->nextBool(); 87 bool premul = d->fRandom->nextBool(); 88 return Make(d->inputFP(), m, unpremul, clampRGB, premul); 89} 90