1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2024 Google LLC 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef skgpu_graphite_precompile_PrecompileShader_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_precompile_PrecompileShader_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileBase.h" 12*c8dee2aaSAndroid Build Coastguard Worker 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlendMode.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker class SkColorSpace; 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite { 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker class PrecompileBlender; 20*c8dee2aaSAndroid Build Coastguard Worker class PrecompileColorFilter; 21*c8dee2aaSAndroid Build Coastguard Worker class PrecompileShaderPriv; 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker /** \class PrecompileShader 24*c8dee2aaSAndroid Build Coastguard Worker This class corresponds to the SkShader class in the main API. 25*c8dee2aaSAndroid Build Coastguard Worker */ 26*c8dee2aaSAndroid Build Coastguard Worker class SK_API PrecompileShader : public PrecompileBase { 27*c8dee2aaSAndroid Build Coastguard Worker public: 28*c8dee2aaSAndroid Build Coastguard Worker /** 29*c8dee2aaSAndroid Build Coastguard Worker * This is the Precompile correlate to SkShader::makeWithLocalMatrix. The actual matrix 30*c8dee2aaSAndroid Build Coastguard Worker * involved is abstracted away, except for whether or the not the matrix involves perspective 31*c8dee2aaSAndroid Build Coastguard Worker * so the correct generated shader variation is chosen. 32*c8dee2aaSAndroid Build Coastguard Worker * The PrecompileShaders::LocalMatrix factory can be used to generate a set of shaders 33*c8dee2aaSAndroid Build Coastguard Worker * that would've been generated via multiple makeWithLocalMatrix calls. That is, rather than 34*c8dee2aaSAndroid Build Coastguard Worker * performing: 35*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> option1 = source1->makeWithLocalMatrix(false); 36*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> option2 = source2->makeWithLocalMatrix(false); 37*c8dee2aaSAndroid Build Coastguard Worker * one could call: 38*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> combinedOptions = LocalMatrix({ source1, source2 }, false); 39*c8dee2aaSAndroid Build Coastguard Worker */ 40*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PrecompileShader> makeWithLocalMatrix(bool isPerspective) const; 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker /** 43*c8dee2aaSAndroid Build Coastguard Worker * This is the Precompile correlate to SkShader::makeWithColorFilter. 44*c8dee2aaSAndroid Build Coastguard Worker * The PrecompileShaders::ColorFilter factory can be used to generate a set of shaders that 45*c8dee2aaSAndroid Build Coastguard Worker * would've been generated via multiple makeWithColorFilter calls. That is, rather than 46*c8dee2aaSAndroid Build Coastguard Worker * performing: 47*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> option1 = source->makeWithColorFilter(colorFilter1); 48*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> option2 = source->makeWithColorFilter(colorFilter2); 49*c8dee2aaSAndroid Build Coastguard Worker * one could call: 50*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> combinedOptions = ColorFilter({ source }, 51*c8dee2aaSAndroid Build Coastguard Worker * { colorFilter1, colorFilter2 }); 52*c8dee2aaSAndroid Build Coastguard Worker * With an alternative use case one could also use the ColorFilter factory thusly: 53*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> combinedOptions = ColorFilter({ source1, source2 }, 54*c8dee2aaSAndroid Build Coastguard Worker * { colorFilter }); 55*c8dee2aaSAndroid Build Coastguard Worker */ 56*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PrecompileShader> makeWithColorFilter(sk_sp<PrecompileColorFilter>) const; 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker /** 59*c8dee2aaSAndroid Build Coastguard Worker * This is the Precompile correlate to SkShader::makeWithWorkingColorSpace. 60*c8dee2aaSAndroid Build Coastguard Worker * The PrecompileShaders::WorkingColorSpace factory can be used to generate a set of shaders 61*c8dee2aaSAndroid Build Coastguard Worker * that would've been generated via multiple makeWithWorkingColorSpace calls. That is, rather 62*c8dee2aaSAndroid Build Coastguard Worker * than performing: 63*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> option1 = source->makeWithWorkingColorSpace(colorSpace1); 64*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> option2 = source->makeWithWorkingColorSpace(colorSpace2); 65*c8dee2aaSAndroid Build Coastguard Worker * one could call: 66*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> combinedOptions = WorkingColorSpace({ source }, 67*c8dee2aaSAndroid Build Coastguard Worker * { colorSpace1, 68*c8dee2aaSAndroid Build Coastguard Worker * colorSpace2 }); 69*c8dee2aaSAndroid Build Coastguard Worker * With an alternative use case one could also use the WorkingColorSpace factory thusly: 70*c8dee2aaSAndroid Build Coastguard Worker * sk_sp<PrecompileShader> combinedOptions = WorkingColorSpace({ source1, source2 }, 71*c8dee2aaSAndroid Build Coastguard Worker * { colorSpace }); 72*c8dee2aaSAndroid Build Coastguard Worker */ 73*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PrecompileShader> makeWithWorkingColorSpace(sk_sp<SkColorSpace>) const; 74*c8dee2aaSAndroid Build Coastguard Worker 75*c8dee2aaSAndroid Build Coastguard Worker // Provides access to functions that aren't part of the public API. 76*c8dee2aaSAndroid Build Coastguard Worker PrecompileShaderPriv priv(); 77*c8dee2aaSAndroid Build Coastguard Worker const PrecompileShaderPriv priv() const; // NOLINT(readability-const-return-type) 78*c8dee2aaSAndroid Build Coastguard Worker 79*c8dee2aaSAndroid Build Coastguard Worker protected: 80*c8dee2aaSAndroid Build Coastguard Worker friend class PrecompileShaderPriv; 81*c8dee2aaSAndroid Build Coastguard Worker PrecompileShader()82*c8dee2aaSAndroid Build Coastguard Worker PrecompileShader() : PrecompileBase(Type::kShader) {} 83*c8dee2aaSAndroid Build Coastguard Worker ~PrecompileShader() override; 84*c8dee2aaSAndroid Build Coastguard Worker isConstant(int)85*c8dee2aaSAndroid Build Coastguard Worker virtual bool isConstant(int /* desiredCombination */) const { return false; } 86*c8dee2aaSAndroid Build Coastguard Worker isALocalMatrixShader()87*c8dee2aaSAndroid Build Coastguard Worker virtual bool isALocalMatrixShader() const { return false; } 88*c8dee2aaSAndroid Build Coastguard Worker }; 89*c8dee2aaSAndroid Build Coastguard Worker 90*c8dee2aaSAndroid Build Coastguard Worker //-------------------------------------------------------------------------------------------------- 91*c8dee2aaSAndroid Build Coastguard Worker // This is the Precompile correlate to the SkShaders namespace in the main API 92*c8dee2aaSAndroid Build Coastguard Worker namespace PrecompileShaders { 93*c8dee2aaSAndroid Build Coastguard Worker // --- This block of eight matches the SkShaders factories in SkShader.h 94*c8dee2aaSAndroid Build Coastguard Worker // Note that some of the details of the main API have been elided since they don't impact 95*c8dee2aaSAndroid Build Coastguard Worker // the generated shader (e.g., the color parameter to the Color() factories). 96*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> Empty(); 97*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> Color(); 98*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> Color(sk_sp<SkColorSpace>); 99*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> Blend(SkSpan<const SkBlendMode> blendModes, 100*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const sk_sp<PrecompileShader>> dsts, 101*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const sk_sp<PrecompileShader>> srcs); 102*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> Blend(SkSpan<const sk_sp<PrecompileBlender>> blenders, 103*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const sk_sp<PrecompileShader>> dsts, 104*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const sk_sp<PrecompileShader>> srcs); 105*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> CoordClamp(SkSpan<const sk_sp<PrecompileShader>>); 106*c8dee2aaSAndroid Build Coastguard Worker 107*c8dee2aaSAndroid Build Coastguard Worker // In the main Skia API ImageShaders are usually created via a SkImage::makeShader call. 108*c8dee2aaSAndroid Build Coastguard Worker // Since the SkImage used to create the ImageShader is unlikely to be present at precompilation 109*c8dee2aaSAndroid Build Coastguard Worker // time this entry point allows the equivalent precompilation program structure to be created. 110*c8dee2aaSAndroid Build Coastguard Worker // Note that this factory is for non-YUV SkImages, the YUVImage factory (below) should be used 111*c8dee2aaSAndroid Build Coastguard Worker // to represent the shading and sampling required for YUV images. 112*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> Image(); 113*c8dee2aaSAndroid Build Coastguard Worker // As with the above Image call, raw ImageShaders are usually created via an 114*c8dee2aaSAndroid Build Coastguard Worker // SkImage::makeRawShader call. The RawImage call allows the equivalent precompilation 115*c8dee2aaSAndroid Build Coastguard Worker // program structure to be created without needing the SkImage. 116*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> RawImage(); 117*c8dee2aaSAndroid Build Coastguard Worker 118*c8dee2aaSAndroid Build Coastguard Worker // In the main Skia API, the specifics of the SkImage used for the SkImage::makeShader call 119*c8dee2aaSAndroid Build Coastguard Worker // can determine whether normal or YUV sampling is required. This entry point allows clients 120*c8dee2aaSAndroid Build Coastguard Worker // to specify that the future image will be a YUV image. 121*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> YUVImage(); 122*c8dee2aaSAndroid Build Coastguard Worker 123*c8dee2aaSAndroid Build Coastguard Worker // --- This block of two matches the SkShaders factories in SkPerlinNoiseShader.h 124*c8dee2aaSAndroid Build Coastguard Worker // Again, most of the details have been elided. 125*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> MakeFractalNoise(); 126*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> MakeTurbulence(); 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker // --- This block of four matches all the factories in SkGradientShader (SkGradientShader.h) 129*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> LinearGradient(); 130*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> RadialGradient(); 131*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> TwoPointConicalGradient(); 132*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> SweepGradient(); 133*c8dee2aaSAndroid Build Coastguard Worker 134*c8dee2aaSAndroid Build Coastguard Worker // Normally, SkPicture shaders are only created via SkPicture::makeShader. Since the 135*c8dee2aaSAndroid Build Coastguard Worker // SkPicture to be drawn, most likely, won't be available at precompilation time, this 136*c8dee2aaSAndroid Build Coastguard Worker // entry point can be used to create a precompilation equivalent. 137*c8dee2aaSAndroid Build Coastguard Worker // Note: this will precompile the program that draws the SkPicture. It, obviously, won't 138*c8dee2aaSAndroid Build Coastguard Worker // precompile any SkPaints within the SkPicture. 139*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> Picture(); 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker // Normally, LocalMatrixShaders are only created via SkShader::makeWithLocalMatrix. 142*c8dee2aaSAndroid Build Coastguard Worker // However, in the combination API, clients may want to create a set of precompile 143*c8dee2aaSAndroid Build Coastguard Worker // LocalMatrixShaders (i.e., pass an SkSpan to the factory function vs just creating a 144*c8dee2aaSAndroid Build Coastguard Worker // single option). This entry point allows that use case. 145*c8dee2aaSAndroid Build Coastguard Worker // Note: PrecompileShader::makeWithLocalMatrix() can still be used and works as expected. 146*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> LocalMatrix(SkSpan<const sk_sp<PrecompileShader>> wrapped, 147*c8dee2aaSAndroid Build Coastguard Worker bool isPerspective = false); 148*c8dee2aaSAndroid Build Coastguard Worker 149*c8dee2aaSAndroid Build Coastguard Worker // Normally, ColorFilterShaders are only created via SkShader::makeWithColorFilter. 150*c8dee2aaSAndroid Build Coastguard Worker // However, in the combination API, clients may want to create a set of precompile 151*c8dee2aaSAndroid Build Coastguard Worker // ColorFilterShaders (i.e., pass SkSpans to the factory function vs just creating a 152*c8dee2aaSAndroid Build Coastguard Worker // single option). This entry point allows that use case. 153*c8dee2aaSAndroid Build Coastguard Worker // Note: PrecompileShader::makeWithColorFilter can still be used and works as expected. 154*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> ColorFilter( 155*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const sk_sp<PrecompileShader>> shaders, 156*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters); 157*c8dee2aaSAndroid Build Coastguard Worker 158*c8dee2aaSAndroid Build Coastguard Worker // Normally, WorkingColorSpaceShaders are only created via SkShader::makeWithWorkingColorSpace. 159*c8dee2aaSAndroid Build Coastguard Worker // However, in the combination API, clients may want to create a set of precompile 160*c8dee2aaSAndroid Build Coastguard Worker // WorkingColorSpaceShaders (i.e., pass SkSpans to the factory function vs just creating a 161*c8dee2aaSAndroid Build Coastguard Worker // single option). This entry point allows that use case. 162*c8dee2aaSAndroid Build Coastguard Worker // Note: PrecompileShader::makeWithWorkingColorSpace can still be used and works as expected. 163*c8dee2aaSAndroid Build Coastguard Worker SK_API sk_sp<PrecompileShader> WorkingColorSpace(SkSpan<const sk_sp<PrecompileShader>> shaders, 164*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const sk_sp<SkColorSpace>> colorSpaces); 165*c8dee2aaSAndroid Build Coastguard Worker 166*c8dee2aaSAndroid Build Coastguard Worker } // namespace PrecompileShaders 167*c8dee2aaSAndroid Build Coastguard Worker 168*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker #endif // skgpu_graphite_precompile_PrecompileShader_DEFINED 171