SkASSERT(kernelWidth <= kMaxBlurSamples); // The SkSL structure performs two kernel taps; if the kernel has an odd width the last // sample will be skipped with the current loop limit calculation.
SkASSERT(kernelWidth % 2 == 0); return SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
SkStringPrintf( // The coefficients are always stored for the max radius to keep the // uniform block consistent across all effects. "const int kMaxUniformKernelSize = %d / 2;" // But we generate an exact loop over the kernel size. Note that this // program can be used for kernels smaller than the constructed max as long // as the kernel weights for excess entries are set to 0. "const int kMaxLoopLimit = %d / 2;"
SkASSERT(maxKernelSize % 4 == 0); return SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
SkStringPrintf( // The coefficients are always stored for the max radius to keep the // uniform block consistent across all effects. "const int kMaxUniformKernelSize = %d / 4;" "const int kMaxUniformOffsetsSize = 2*kMaxUniformKernelSize;" // But we generate an exact loop over the kernel size. Note that this // program can be used for kernels smaller than the constructed max as long // as the kernel weights for excess entries are set to 0. "const int kMaxLoopLimit = %d / 4;"
// Pack scalar coefficients into half4 for better packing on std140, and // upload offsets to avoid having to transform the 1D index into a 2D coord "uniform half4 kernel[kMaxUniformKernelSize];" "uniform half4 offsets[kMaxUniformOffsetsSize];"
"uniform shader child;"
"half4 main(float2 coord) {" "half4 sum = half4(0);"
// There are three shader variants: // a smaller kernel version that stores the matrix in uniforms and iterates in 1D // a larger kernel version that stores the matrix in a 1D texture. The texture version has small // and large variants w/ the actual kernel size uploaded as a uniform.
SkRuntimeEffect* make_matrix_conv_shader(MatrixConvolutionImpl impl, StableKey stableKey) {
SkRuntimeEffect::Options options = get_options(stableKey);
// While the uniforms and kernel access are different, pieces of the algorithm are common and // defined statically for re-use in the two shaders: staticconstchar* kHeaderAndBeginLoopSkSL = "uniform int2 size;" "uniform int2 offset;" "uniform half2 gainAndBias;" "uniform int convolveAlpha;"// FIXME not a full int? Put in a half3 w/ gainAndBias?
// Used in the inner loop to accumulate convolution sum and increment the kernel position staticconstchar* kAccumulateAndIncrementSkSL = "half4 c = child.eval(coord + half2(kernelPos) - half2(offset));" "if (convolveAlpha == 0) {" // When not convolving alpha, remember the original alpha for actual sample // coord, and perform accumulation on unpremul colors. "if (kernelPos == offset) {" "origAlpha = c.a;" "}" "c = unpremul(c);" "}" "sum += c*k;" "kernelPos.x += 1;" "if (kernelPos.x >= size.x) {" "kernelPos.x = 0;" "kernelPos.y += 1;" "}";
// Closes the loop and calculates final color staticconstchar* kCloseLoopAndFooterSkSL = "}" "half4 color = sum*gainAndBias.x + gainAndBias.y;" "if (convolveAlpha == 0) {" // Reset the alpha to the original and convert to premul RGB "color = half4(color.rgb*origAlpha, origAlpha);" "} else {" // Ensure convolved alpha is within [0, 1] "color.a = saturate(color.a);" "}" // Make RGB valid premul w/ respect to the alpha (either original or convolved) "color.rgb = clamp(color.rgb, 0, color.a);" "return color;" "}";
// NOTE: This uses dot product selection to work on all GLES2 hardware (enforced by // public runtime effect restrictions). Otherwise, this would use a "uniform ivec2" // and component indexing to convert the displacement color into a vector. static constexpr char kDisplacementShaderCode[] = "uniform shader displMap;" "uniform shader colorMap;" "uniform half2 scale;" "uniform half4 xSelect;"// Only one of RGBA will be 1, the rest are 0 "uniform half4 ySelect;"
// Packs surface depth, shininess, material type (0 == diffuse) and light type // (< 0 = distant, 0 = point, > 0 = spot) "uniform half4 materialAndLightType;"
"uniform half4 lightPosAndSpotFalloff;"// (x,y,z) are lightPos, w is spot falloff // exponent "uniform half4 lightDirAndSpotCutoff;"// (x,y,z) are lightDir, // w is spot cos(cutoffAngle) "uniform half3 lightColor;"// Material's k has already been multiplied in
// Color Filters case StableKey::kHighContrast: { staticconst SkRuntimeEffect* sHighContrastEffect = make_high_contrast_color_filter(); return sHighContrastEffect;
} case StableKey::kLuma: { staticconst SkRuntimeEffect* sLumaEffect = make_luma_color_filter(); return sLumaEffect;
} case StableKey::kOverdraw: { staticconst SkRuntimeEffect* sOverdrawEffect = make_overdraw_color_filter(); return sOverdrawEffect;
}
}
SkUNREACHABLE;
}
} // namespace SkKnownRuntimeEffects
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.14Bemerkung:
(vorverarbeitet am 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.