1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <unordered_map> 17 #include <string> 18 19 static std::unordered_map<std::string, std::string> extModuleData = { 20 {"sksl_frag.sksl", R"( 21 // defines built-in interfaces supported by SkiaSL fragment shaders 22 23 // See "enum SpvBuiltIn_" in ./spirv.h 24 layout(builtin=15) in float4 sk_FragCoord; 25 layout(builtin=17) in bool sk_Clockwise; // Similar to gl_FrontFacing, but defined in device space. 26 27 layout(location=0,index=0,builtin=10001) out half4 sk_FragColor; 28 layout(builtin=10008) half4 sk_LastFragColor; 29 layout(builtin=10012) out half4 sk_SecondaryFragColor; 30 )"}, 31 {"sksl_vert.sksl", R"( 32 // defines built-in interfaces supported by SkiaSL vertex shaders 33 34 out sk_PerVertex { 35 layout(builtin=0) float4 sk_Position; 36 layout(builtin=1) float sk_PointSize; 37 }; 38 39 layout(builtin=42) in int sk_VertexID; 40 layout(builtin=43) in int sk_InstanceID; 41 )"}, 42 {"sksl_gpu.sksl", R"( 43 // defines built-in functions supported by SkSL when running on a GPU 44 45 $genType radians($genType degrees); 46 $genType degrees($genType radians); 47 $genType sin($genType angle); 48 $genType cos($genType angle); 49 $genType tan($genType angle); 50 $genType asin($genType x); 51 $genType acos($genType x); 52 $genType atan($genType y, $genType x); 53 $genType atan($genType y_over_x); 54 $genType sinh($genType x); 55 $genType cosh($genType x); 56 $genType tanh($genType x); 57 $genType asinh($genType x); 58 $genType acosh($genType x); 59 $genType atanh($genType x); 60 $genType pow($genType x, $genType y); 61 $genType exp($genType x); 62 $genType log($genType x); 63 $genType exp2($genType x); 64 $genType log2($genType x); 65 $genType sqrt($genType x); 66 $genHType radians($genHType degrees); 67 $genHType degrees($genHType radians); 68 $genHType sin($genHType angle); 69 $genHType cos($genHType angle); 70 $genHType tan($genHType angle); 71 $genHType asin($genHType x); 72 $genHType acos($genHType x); 73 $genHType atan($genHType y, $genHType x); 74 $genHType atan($genHType y_over_x); 75 $genHType sinh($genHType x); 76 $genHType cosh($genHType x); 77 $genHType tanh($genHType x); 78 $genHType asinh($genHType x); 79 $genHType acosh($genHType x); 80 $genHType atanh($genHType x); 81 $genHType pow($genHType x, $genHType y); 82 $genHType exp($genHType x); 83 $genHType log($genHType x); 84 $genHType exp2($genHType x); 85 $genHType log2($genHType x); 86 $genHType sqrt($genHType x); 87 $genType inversesqrt($genType x); 88 $genHType inversesqrt($genHType x); 89 $genType abs($genType x); 90 $genHType abs($genHType x); 91 $genIType abs($genIType x); 92 $genType sign($genType x); 93 $genHType sign($genHType x); 94 $genIType sign($genIType x); 95 $genType floor($genType x); 96 $genHType floor($genHType x); 97 $genType trunc($genType x); 98 $genHType trunc($genHType x); 99 $genType round($genType x); 100 $genHType round($genHType x); 101 $genType roundEven($genType x); 102 $genHType roundEven($genHType x); 103 $genType ceil($genType x); 104 $genHType ceil($genHType x); 105 $genType fract($genType x); 106 $genHType fract($genHType x); 107 $genType mod($genType x, float y); 108 $genType mod($genType x, $genType y); 109 $genHType mod($genHType x, half y); 110 $genHType mod($genHType x, $genHType y); 111 $genType modf($genType x, out $genType i); 112 $genHType modf($genHType x, out $genHType i); 113 $genType min($genType x, $genType y); 114 $genType min($genType x, float y); 115 $genHType min($genHType x, $genHType y); 116 $genHType min($genHType x, half y); 117 $genIType min($genIType x, $genIType y); 118 $genIType min($genIType x, int y); 119 $genType max($genType x, $genType y); 120 $genType max($genType x, float y); 121 $genHType max($genHType x, $genHType y); 122 $genHType max($genHType x, half y); 123 $genIType max($genIType x, $genIType y); 124 $genIType max($genIType x, int y); 125 $genType clamp($genType x, $genType minVal, $genType maxVal); 126 $genType clamp($genType x, float minVal, float maxVal); 127 $genHType clamp($genHType x, $genHType minVal, $genHType maxVal); 128 $genHType clamp($genHType x, half minVal, half maxVal); 129 $genIType clamp($genIType x, $genIType minVal, $genIType maxVal); 130 $genIType clamp($genIType x, int minVal, int maxVal); 131 $genUType clamp($genUType x, $genUType minVal, $genUType maxVal); 132 $genUType clamp($genUType x, uint minVal, uint maxVal); 133 $genType saturate($genType x); 134 $genHType saturate($genHType x); 135 $genType mix($genType x, $genType y, $genType a); 136 $genType mix($genType x, $genType y, float a); 137 $genHType mix($genHType x, $genHType y, $genHType a); 138 $genHType mix($genHType x, $genHType y, half a); 139 $genType mix($genType x, $genType y, $genBType a); 140 $genHType mix($genHType x, $genHType y, $genBType a); 141 $genIType mix($genIType x, $genIType y, $genBType a); 142 $genBType mix($genBType x, $genBType y, $genBType a); 143 $genType step($genType edge, $genType x); 144 $genType step(float edge, $genType x); 145 $genHType step($genHType edge, $genHType x); 146 $genHType step(half edge, $genHType x); 147 $genType smoothstep($genType edge0, $genType edge1, $genType x); 148 $genType smoothstep(float edge0, float edge1, $genType x); 149 $genHType smoothstep($genHType edge0, $genHType edge1, $genHType x); 150 $genHType smoothstep(half edge0, half edge1, $genHType x); 151 $genBType isnan($genType x); 152 $genBType isinf($genType x); 153 $genIType floatBitsToInt($genType value); 154 $genUType floatBitsToUint($genType value); 155 $genType intBitsToFloat($genIType value); 156 $genType uintBitsToFloat($genUType value); 157 $genType fma($genType a, $genType b, $genType c); 158 $genHType fma($genHType a, $genHType b, $genHType c); 159 sk_has_side_effects $genType frexp($genType x, out $genIType exp); 160 sk_has_side_effects $genHType frexp($genHType x, out $genIType exp); 161 $genType ldexp($genType x, in $genIType exp); 162 $genHType ldexp($genHType x, in $genIType exp); 163 uint packUnorm2x16(float2 v); 164 uint packSnorm2x16(float2 v); 165 uint packUnorm4x8(float4 v); 166 uint packSnorm4x8(float4 v); 167 float2 unpackUnorm2x16(uint p); 168 float2 unpackSnorm2x16(uint p); 169 float4 unpackUnorm4x8(uint p); 170 float4 unpackSnorm4x8(uint p); 171 uint packHalf2x16(float2 v); 172 float2 unpackHalf2x16(uint v); 173 float length($genType x); 174 half length($genHType x); 175 float distance($genType p0, $genType p1); 176 half distance($genHType p0, $genHType p1); 177 float dot($genType x, $genType y); 178 half dot($genHType x, $genHType y); 179 float3 cross(float3 x, float3 y); 180 half3 cross(half3 x, half3 y); 181 $genType normalize($genType x); 182 $genHType normalize($genHType x); 183 $genType faceforward($genType N, $genType I, $genType Nref); 184 $genHType faceforward($genHType N, $genHType I, $genHType Nref); 185 $genType reflect($genType I, $genType N); 186 $genHType reflect($genHType I, $genHType N); 187 $genType refract($genType I, $genType N, float eta); 188 $genHType refract($genHType I, $genHType N, half eta); 189 $mat matrixCompMult($mat x, $mat y); 190 $hmat matrixCompMult($hmat x, $hmat y); 191 $squareMat outerProduct($vec c, $vec r); 192 float2x3 outerProduct(float3 c, float2 r); 193 float3x2 outerProduct(float2 c, float3 r); 194 float2x4 outerProduct(float4 c, float2 r); 195 float4x2 outerProduct(float2 c, float4 r); 196 float3x4 outerProduct(float4 c, float3 r); 197 float4x3 outerProduct(float3 c, float4 r); 198 $squareHMat outerProduct($hvec c, $hvec r); 199 half2x3 outerProduct(half3 c, half2 r); 200 half3x2 outerProduct(half2 c, half3 r); 201 half2x4 outerProduct(half4 c, half2 r); 202 half4x2 outerProduct(half2 c, half4 r); 203 half3x4 outerProduct(half4 c, half3 r); 204 half4x3 outerProduct(half3 c, half4 r); 205 $squareMat transpose($squareMat m); 206 float2x3 transpose(float3x2 m); 207 float3x2 transpose(float2x3 m); 208 float2x4 transpose(float4x2 m); 209 float4x2 transpose(float2x4 m); 210 float3x4 transpose(float4x3 m); 211 float4x3 transpose(float3x4 m); 212 $squareHMat transpose($squareHMat m); 213 half2x3 transpose(half3x2 m); 214 half3x2 transpose(half2x3 m); 215 half2x4 transpose(half4x2 m); 216 half4x2 transpose(half2x4 m); 217 half3x4 transpose(half4x3 m); 218 half4x3 transpose(half3x4 m); 219 float determinant($squareMat m); 220 half determinant($squareHMat m); 221 $squareMat inverse($squareMat m); 222 $squareHMat inverse($squareHMat m); 223 $bvec lessThan($vec x, $vec y); 224 $bvec lessThan($hvec x, $hvec y); 225 $bvec lessThan($ivec x, $ivec y); 226 $bvec lessThan($svec x, $svec y); 227 $bvec lessThan($usvec x, $usvec y); 228 $bvec lessThan($uvec x, $uvec y); 229 $bvec lessThanEqual($vec x, $vec y); 230 $bvec lessThanEqual($hvec x, $hvec y); 231 $bvec lessThanEqual($ivec x, $ivec y); 232 $bvec lessThanEqual($uvec x, $uvec y); 233 $bvec lessThanEqual($svec x, $svec y); 234 $bvec lessThanEqual($usvec x, $usvec y); 235 $bvec greaterThan($vec x, $vec y); 236 $bvec greaterThan($hvec x, $hvec y); 237 $bvec greaterThan($ivec x, $ivec y); 238 $bvec greaterThan($uvec x, $uvec y); 239 $bvec greaterThan($svec x, $svec y); 240 $bvec greaterThan($usvec x, $usvec y); 241 $bvec greaterThanEqual($vec x, $vec y); 242 $bvec greaterThanEqual($hvec x, $hvec y); 243 $bvec greaterThanEqual($ivec x, $ivec y); 244 $bvec greaterThanEqual($uvec x, $uvec y); 245 $bvec greaterThanEqual($svec x, $svec y); 246 $bvec greaterThanEqual($usvec x, $usvec y); 247 $bvec equal($vec x, $vec y); 248 $bvec equal($hvec x, $hvec y); 249 $bvec equal($ivec x, $ivec y); 250 $bvec equal($uvec x, $uvec y); 251 $bvec equal($svec x, $svec y); 252 $bvec equal($usvec x, $usvec y); 253 $bvec equal($bvec x, $bvec y); 254 $bvec notEqual($vec x, $vec y); 255 $bvec notEqual($hvec x, $hvec y); 256 $bvec notEqual($ivec x, $ivec y); 257 $bvec notEqual($uvec x, $uvec y); 258 $bvec notEqual($svec x, $svec y); 259 $bvec notEqual($usvec x, $usvec y); 260 $bvec notEqual($bvec x, $bvec y); 261 bool any($bvec x); 262 bool all($bvec x); 263 $bvec not($bvec x); 264 265 $genIType bitCount($genIType value); 266 $genIType bitCount($genUType value); 267 $genIType findLSB($genIType value); 268 $genIType findLSB($genUType value); 269 $genIType findMSB($genIType value); 270 $genIType findMSB($genUType value); 271 272 sampler2D makeSampler2D(texture2D texture, sampler s); 273 int2 textureSize(sampler2DRect s); 274 275 half4 sample(sampler1D s, float P); 276 half4 sample(sampler1D s, float P, float bias); 277 half4 sample(sampler2D s, float2 P); 278 int4 sample(isampler2D s, float2 P); 279 half4 sample(samplerExternalOES s, float2 P, float bias); 280 half4 sample(samplerExternalOES s, float2 P); 281 282 half4 sample(sampler2DRect s, float2 P); 283 half4 sample(sampler2DRect s, float3 P); 284 285 // Currently we do not support the generic types of loading subpassInput so we have some explicit 286 // versions that we currently use 287 half4 subpassLoad(subpassInput subpass); 288 half4 subpassLoad(subpassInputMS subpass, int sample); 289 290 half4 sample(sampler1D s, float2 P); 291 half4 sample(sampler1D s, float2 P, float bias); 292 half4 sample(sampler2D s, float3 P); 293 half4 sample(sampler2D s, float3 P, float bias); 294 295 $genType dFdx($genType p); 296 $genType dFdy($genType p); 297 $genHType dFdx($genHType p); 298 $genHType dFdy($genHType p); 299 $genType fwidth($genType p); 300 $genHType fwidth($genHType p); 301 float interpolateAtSample(float interpolant, int sample); 302 float2 interpolateAtSample(float2 interpolant, int sample); 303 float3 interpolateAtSample(float3 interpolant, int sample); 304 float4 interpolateAtSample(float4 interpolant, int sample); 305 float interpolateAtOffset(float interpolant, float2 offset); 306 float2 interpolateAtOffset(float2 interpolant, float2 offset); 307 float3 interpolateAtOffset(float3 interpolant, float2 offset); 308 float4 interpolateAtOffset(float4 interpolant, float2 offset); 309 310 // Definitions of functions implementing all of the SkBlendMode blends. 311 312 half4 blend_clear(half4 src, half4 dst) { return half4(0); } 313 314 half4 blend_src(half4 src, half4 dst) { return src; } 315 316 half4 blend_dst(half4 src, half4 dst) { return dst; } 317 318 half4 blend_src_over(half4 src, half4 dst) { return src + (1 - src.a)*dst; } 319 320 half4 blend_dst_over(half4 src, half4 dst) { return (1 - dst.a)*src + dst; } 321 322 half4 blend_src_in(half4 src, half4 dst) { return src*dst.a; } 323 324 half4 blend_dst_in(half4 src, half4 dst) { return dst*src.a; } 325 326 half4 blend_src_out(half4 src, half4 dst) { return (1 - dst.a)*src; } 327 328 half4 blend_dst_out(half4 src, half4 dst) { return (1 - src.a)*dst; } 329 330 half4 blend_src_atop(half4 src, half4 dst) { return dst.a*src + (1 - src.a)*dst; } 331 332 half4 blend_dst_atop(half4 src, half4 dst) { return (1 - dst.a) * src + src.a*dst; } 333 334 half4 blend_xor(half4 src, half4 dst) { return (1 - dst.a)*src + (1 - src.a)*dst; } 335 336 half4 blend_plus(half4 src, half4 dst) { return min(src + dst, 1); } 337 338 half4 blend_modulate(half4 src, half4 dst) { return src*dst; } 339 340 half4 blend_screen(half4 src, half4 dst) { return src + (1 - src)*dst; } 341 342 half _blend_overlay_component(half2 s, half2 d) { 343 return (2*d.x <= d.y) 344 ? 2*s.x*d.x 345 : s.y*d.y - 2*(d.y - d.x)*(s.y - s.x); 346 } 347 348 half4 blend_overlay(half4 src, half4 dst) { 349 half4 result = half4(_blend_overlay_component(src.ra, dst.ra), 350 _blend_overlay_component(src.ga, dst.ga), 351 _blend_overlay_component(src.ba, dst.ba), 352 src.a + (1 - src.a)*dst.a); 353 result.rgb += dst.rgb*(1 - src.a) + src.rgb*(1 - dst.a); 354 return result; 355 } 356 357 half4 blend_darken(half4 src, half4 dst) { 358 half4 result = blend_src_over(src, dst); 359 result.rgb = min(result.rgb, (1 - dst.a)*src.rgb + dst.rgb); 360 return result; 361 } 362 363 half4 blend_lighten(half4 src, half4 dst) { 364 half4 result = blend_src_over(src, dst); 365 result.rgb = max(result.rgb, (1 - dst.a)*src.rgb + dst.rgb); 366 return result; 367 } 368 369 half _guarded_divide(half n, half d) { 370 return sk_Caps.mustGuardDivisionEvenAfterExplicitZeroCheck 371 ? n/(d + 0.00000001) 372 : n/d; 373 } 374 375 half3 _guarded_divide(half3 n, half d) { 376 return sk_Caps.mustGuardDivisionEvenAfterExplicitZeroCheck 377 ? n/(d + 0.00000001) 378 : n/d; 379 } 380 381 half _color_dodge_component(half2 s, half2 d) { 382 if (d.x == 0) { 383 return s.x*(1 - d.y); 384 } else { 385 half delta = s.y - s.x; 386 if (delta == 0) { 387 return s.y*d.y + s.x*(1 - d.y) + d.x*(1 - s.y); 388 } else { 389 delta = min(d.y, _guarded_divide(d.x*s.y, delta)); 390 return delta*s.y + s.x*(1 - d.y) + d.x*(1 - s.y); 391 } 392 } 393 } 394 395 half4 blend_color_dodge(half4 src, half4 dst) { 396 return half4(_color_dodge_component(src.ra, dst.ra), 397 _color_dodge_component(src.ga, dst.ga), 398 _color_dodge_component(src.ba, dst.ba), 399 src.a + (1 - src.a)*dst.a); 400 } 401 402 half _color_burn_component(half2 s, half2 d) { 403 if (d.y == d.x) { 404 return s.y*d.y + s.x*(1 - d.y) + d.x*(1 - s.y); 405 } else if (s.x == 0) { 406 return d.x*(1 - s.y); 407 } else { 408 half delta = max(0, d.y - _guarded_divide((d.y - d.x)*s.y, s.x)); 409 return delta*s.y + s.x*(1 - d.y) + d.x*(1 - s.y); 410 } 411 } 412 413 half4 blend_color_burn(half4 src, half4 dst) { 414 return half4(_color_burn_component(src.ra, dst.ra), 415 _color_burn_component(src.ga, dst.ga), 416 _color_burn_component(src.ba, dst.ba), 417 src.a + (1 - src.a)*dst.a); 418 } 419 420 half4 blend_hard_light(half4 src, half4 dst) { return blend_overlay(dst, src); } 421 422 half _soft_light_component(half2 s, half2 d) { 423 if (2*s.x <= s.y) { 424 return _guarded_divide(d.x*d.x*(s.y - 2*s.x), d.y) + (1 - d.y)*s.x + d.x*(-s.y + 2*s.x + 1); 425 } else if (4.0 * d.x <= d.y) { 426 half DSqd = d.x*d.x; 427 half DCub = DSqd*d.x; 428 half DaSqd = d.y*d.y; 429 half DaCub = DaSqd*d.y; 430 return _guarded_divide(DaSqd*(s.x - d.x*(3*s.y - 6*s.x - 1)) + 12*d.y*DSqd*(s.y - 2*s.x) 431 - 16*DCub * (s.y - 2*s.x) - DaCub*s.x, DaSqd); 432 } else { 433 return d.x*(s.y - 2*s.x + 1) + s.x - sqrt(d.y*d.x)*(s.y - 2*s.x) - d.y*s.x; 434 } 435 } 436 437 half4 blend_soft_light(half4 src, half4 dst) { 438 return (dst.a == 0) ? src : half4(_soft_light_component(src.ra, dst.ra), 439 _soft_light_component(src.ga, dst.ga), 440 _soft_light_component(src.ba, dst.ba), 441 src.a + (1 - src.a)*dst.a); 442 } 443 444 half4 blend_difference(half4 src, half4 dst) { 445 return half4(src.rgb + dst.rgb - 2*min(src.rgb*dst.a, dst.rgb*src.a), 446 src.a + (1 - src.a)*dst.a); 447 } 448 449 half4 blend_exclusion(half4 src, half4 dst) { 450 return half4(dst.rgb + src.rgb - 2*dst.rgb*src.rgb, src.a + (1 - src.a)*dst.a); 451 } 452 453 half4 blend_multiply(half4 src, half4 dst) { 454 return half4((1 - src.a)*dst.rgb + (1 - dst.a)*src.rgb + src.rgb*dst.rgb, 455 src.a + (1 - src.a)*dst.a); 456 } 457 458 half _blend_color_luminance(half3 color) { return dot(half3(0.3, 0.59, 0.11), color); } 459 460 half3 _blend_set_color_luminance(half3 hueSatColor, half alpha, half3 lumColor) { 461 half lum = _blend_color_luminance(lumColor); 462 half3 result = lum - _blend_color_luminance(hueSatColor) + hueSatColor; 463 half minComp = min(min(result.r, result.g), result.b); 464 half maxComp = max(max(result.r, result.g), result.b); 465 if (minComp < 0 && lum != minComp) { 466 result = lum + (result - lum) * _guarded_divide(lum, (lum - minComp)); 467 } 468 if (maxComp > alpha && maxComp != lum) { 469 return lum + _guarded_divide((result - lum) * (alpha - lum), (maxComp - lum)); 470 } else { 471 return result; 472 } 473 } 474 475 half _blend_color_saturation(half3 color) { 476 return max(max(color.r, color.g), color.b) - min(min(color.r, color.g), color.b); 477 } 478 479 half3 _blend_set_color_saturation_helper(half3 minMidMax, half sat) { 480 if (minMidMax.r < minMidMax.b) { 481 return half3(0, 482 _guarded_divide(sat*(minMidMax.g - minMidMax.r), (minMidMax.b - minMidMax.r)), 483 sat); 484 } else { 485 return half3(0); 486 } 487 } 488 489 half3 _blend_set_color_saturation(half3 hueLumColor, half3 satColor) { 490 half sat = _blend_color_saturation(satColor); 491 if (hueLumColor.r <= hueLumColor.g) { 492 if (hueLumColor.g <= hueLumColor.b) { 493 return _blend_set_color_saturation_helper(hueLumColor.rgb, sat); 494 } else if (hueLumColor.r <= hueLumColor.b) { 495 return _blend_set_color_saturation_helper(hueLumColor.rbg, sat).rbg; 496 } else { 497 return _blend_set_color_saturation_helper(hueLumColor.brg, sat).gbr; 498 } 499 } else if (hueLumColor.r <= hueLumColor.b) { 500 return _blend_set_color_saturation_helper(hueLumColor.grb, sat).grb; 501 } else if (hueLumColor.g <= hueLumColor.b) { 502 return _blend_set_color_saturation_helper(hueLumColor.gbr, sat).brg; 503 } else { 504 return _blend_set_color_saturation_helper(hueLumColor.bgr, sat).bgr; 505 } 506 } 507 508 half4 blend_hue(half4 src, half4 dst) { 509 half alpha = dst.a*src.a; 510 half3 sda = src.rgb*dst.a; 511 half3 dsa = dst.rgb*src.a; 512 return half4(_blend_set_color_luminance(_blend_set_color_saturation(sda, dsa), alpha, dsa) + 513 dst.rgb - dsa + src.rgb - sda, 514 src.a + dst.a - alpha); 515 } 516 517 half4 blend_saturation(half4 src, half4 dst) { 518 half alpha = dst.a*src.a; 519 half3 sda = src.rgb*dst.a; 520 half3 dsa = dst.rgb*src.a; 521 return half4(_blend_set_color_luminance(_blend_set_color_saturation(dsa, sda), alpha, dsa) + 522 dst.rgb - dsa + src.rgb - sda, 523 src.a + dst.a - alpha); 524 } 525 526 half4 blend_color(half4 src, half4 dst) { 527 half alpha = dst.a*src.a; 528 half3 sda = src.rgb*dst.a; 529 half3 dsa = dst.rgb*src.a; 530 return half4(_blend_set_color_luminance(sda, alpha, dsa) + dst.rgb - dsa + src.rgb - sda, 531 src.a + dst.a - alpha); 532 } 533 534 half4 blend_luminosity(half4 src, half4 dst) { 535 half alpha = dst.a*src.a; 536 half3 sda = src.rgb*dst.a; 537 half3 dsa = dst.rgb*src.a; 538 return half4(_blend_set_color_luminance(dsa, alpha, sda) + dst.rgb - dsa + src.rgb - sda, 539 src.a + dst.a - alpha); 540 } 541 542 // The max() guards against division by zero when the incoming color is transparent black 543 half4 unpremul(half4 color) { return half4(color.rgb / max(color.a, 0.0001), color.a); } 544 float4 unpremul(float4 color) { return float4(color.rgb / max(color.a, 0.0001), color.a); } 545 546 float2 proj(float3 p) { return p.xy / p.z; } 547 548 // Implement cross() as a determinant to communicate our intent more clearly to the compiler. 549 // NOTE: Due to precision issues, it might be the case that cross(a, a) != 0. 550 float cross(float2 a, float2 b) { 551 return sk_Caps.builtinDeterminantSupport ? determinant(float2x2(a, b)) 552 : a.x*b.y - a.y*b.x; 553 } 554 555 half cross(half2 a, half2 b) { 556 return sk_Caps.builtinDeterminantSupport ? determinant(half2x2(a, b)) 557 : a.x*b.y - a.y*b.x; 558 } 559 560 // add the support of textureSize 561 int2 textureSize(sampler2D x, int y); 562 563 // add the support of nonuniformEXT 564 uint nonuniformEXT(uint x); 565 )"} 566 };