Lines Matching +full:- +full:- +full:hard
4 * Use of this source code is governed by a BSD-style license that can be
26 // Intervals smaller than this (that aren't hard stops) on low-precision-only devices force us to
35 // MakeColorizer to transparently take care of hard stops at the end points of the gradient.
43 if (GrColorTypeIsWiderThan(args.fDstColorInfo->colorType(), 8)) { in make_textured_colorizer()
44 auto f16Format = args.fContext->priv().caps()->getDefaultBackendFormat( in make_textured_colorizer()
117 const Vec4 scale[2] = {(vc1 - vc0) / threshold, in make_dual_interval_colorizer()
118 (vc3 - vc2) / (1 - threshold)}; in make_dual_interval_colorizer()
120 vc2 - threshold * scale[1]}; in make_dual_interval_colorizer()
128 // The "unrolled" colorizer contains hand-written nested ifs which perform a binary search.
129 // This works on ES2 hardware that doesn't support non-constant array indexes.
144 once[intervalCount - 1]([intervalCount] { in make_unrolled_colorizer()
152 // - thresholds1_7.x = boundary between (0,1) and (2,3) -> 1_2 in make_unrolled_colorizer()
153 // - .y = boundary between (2,3) and (4,5) -> 3_4 in make_unrolled_colorizer()
154 // - .z = boundary between (4,5) and (6,7) -> 5_6 in make_unrolled_colorizer()
155 // - .w = boundary between (6,7) and (8,9) -> 7_8 in make_unrolled_colorizer()
156 // - thresholds9_13.x = boundary between (8,9) and (10,11) -> 9_10 in make_unrolled_colorizer()
157 // - .y = boundary between (10,11) and (12,13) -> 11_12 in make_unrolled_colorizer()
158 // - .z = boundary between (12,13) and (14,15) -> 13_14 in make_unrolled_colorizer()
159 // - .w = unused in make_unrolled_colorizer()
231 effects[intervalCount - 1] = std::move(result.effect); in make_unrolled_colorizer()
234 return GrSkSLFP::Make(effects[intervalCount - 1], "UnrolledBinaryColorizer", in make_unrolled_colorizer()
242 // The "looping" colorizer uses a real loop to binary-search the array of gradient stops.
253 int cacheIndex = (size_t)intervalChunks - 1; in make_looping_colorizer()
264 cacheEntry->once([intervalCount, intervalChunks, cacheEntry] { in make_looping_colorizer()
272 // binary search are hand-unrolled to allow them to use swizzles. in make_looping_colorizer()
275 // single chunk). In this case, the binary search for-loop will optimize away entirely, as in make_looping_colorizer()
300 // Choose the final position via explicit 4-way binary search. in make_looping_colorizer()
315 /* high: */ intervalChunks - 1, in make_looping_colorizer()
316 /* chunk: */ (intervalChunks - 1) / 2, in make_looping_colorizer()
323 cacheEntry->effect = std::move(result.effect); in make_looping_colorizer()
326 return GrSkSLFP::Make(cacheEntry->effect, "LoopingBinaryColorizer", in make_looping_colorizer()
334 // The length of the result array may differ from the input due to hard-stops or empty intervals.
342 // Depending on how the positions resolve into hard stops or regular stops, the number of in build_intervals()
344 // 3 color gradient is two intervals, but a 4 color gradient with a hard stop is also in build_intervals()
345 // two intervals. At the most extreme end, an 8 interval gradient made entirely of hard in build_intervals()
348 for (int i = 0; i < inputLength - 1; i++) { in build_intervals()
357 SkScalar dt = t1 - t0; in build_intervals()
359 // distinct hard stop intervals as needed. It also protects against malformed gradients in build_intervals()
360 // that have repeated hard stops at the very beginning that are effectively unreachable. in build_intervals()
367 Vec4 scale = (c1 - c0) / dt; in build_intervals()
368 Vec4 bias = c0 - t0 * scale; in build_intervals()
423 thresholds[intervalCount] = thresholds[intervalCount - 1]; in make_looping_binary_colorizer()
424 scales[intervalCount] = scales[intervalCount - 1]; in make_looping_binary_colorizer()
425 biases[intervalCount] = biases[intervalCount - 1]; in make_looping_binary_colorizer()
438 // If there are hard stops at the beginning or end, the first and/or last color should be in make_colorizer()
446 bool topHardStop = SkScalarNearlyEqual(positions[count - 2], positions[count - 1]); in make_colorizer()
451 count--; in make_colorizer()
454 count--; in make_colorizer()
458 // (but it may have originally been a 3 or 4 color gradient with 1-2 hard stops at the ends) in make_colorizer()
463 const GrShaderCaps* caps = args.fContext->priv().caps()->shaderCaps(); in make_colorizer()
464 auto intervalsExceedPrecisionLimit = [&]() -> bool { in make_colorizer()
467 // isn't 32-bit, output can be incorrect if the thresholds are too close together. However, in make_colorizer()
469 // hardware when the thresholds are not ill-conditioned. in make_colorizer()
470 if (!caps->floatIs32Bits()) { in make_colorizer()
473 // 16-bit). in make_colorizer()
474 for (int i = 0; i < count - 1; i++) { in make_colorizer()
475 SkScalar dt = SkScalarAbs(positions[i] - positions[i + 1]); in make_colorizer()
484 auto makeDualIntervalColorizer = [&]() -> std::unique_ptr<GrFragmentProcessor> { in make_colorizer()
485 // The dual-interval colorizer uses the same principles as the binary-search colorizer, but in make_colorizer()
504 int binaryColorizerLimit = caps->nonconstantArrayIndexSupport() ? kMaxLoopingColorCount in make_colorizer()
507 // The dual-interval colorizer uses the same principles as the binary-search colorizer, but in make_colorizer()
513 // Attempt to create an analytic colorizer that uses a binary-search loop. in make_colorizer()
514 colorizer = caps->nonconstantArrayIndexSupport() in make_colorizer()
523 // arbitrary gradients. (This has limited sampling resolution, and always blurs hard-stops.) in make_colorizer()
527 // This top-level effect implements clamping on the layout coordinate and requires specifying the
531 // there is a hard stop.
569 // side-channel. in make_clamped_gradient()
582 bool layoutPreservesOpacity = gradLayout->preservesOpaqueInput(); in make_clamped_gradient()
623 half t_1 = t.x - 1; in make_tiled_gradient()
624 half tiled_t = t_1 - 2 * floor(t_1 * 0.5) - 1; in make_tiled_gradient()
626 // At this point the expected value of tiled_t should between -1 and 1, so in make_tiled_gradient()
629 tiled_t = clamp(tiled_t, -1, 1); in make_tiled_gradient()
638 // side-channel. in make_tiled_gradient()
651 bool layoutPreservesOpacity = gradLayout->preservesOpaqueInput(); in make_tiled_gradient()
657 args.fContext->priv().caps()->shaderCaps()->mustDoOpBetweenFloorAndAbs(); in make_tiled_gradient()
670 // Combines the colorizer and layout with an appropriately configured top-level effect based on the
677 // No shader is possible if a layout couldn't be created, e.g. a layout-specific Make() returned in make_gradient()
685 if (!shader.totalLocalMatrix(args.fPreLocalMatrix)->invert(&matrix)) { in make_gradient()
688 // Some two-point conical gradients use a custom matrix here in make_gradient()
698 shader.fColorSpace.get(), args.fDstColorInfo->colorSpace()); in make_gradient()
717 SkScalar posScale = SK_Scalar1 / (shader.fColorCount - 1); in make_gradient()
731 // The top-level effect has to export premul colors, but under certain conditions it doesn't in make_gradient()
735 // optimize away the make-premul op for two point conical gradients (which report false for in make_gradient()
753 // appropriate. If there is a hard stop, this grabs the expected outer colors for the in make_gradient()
756 colors[0], colors[shader.fColorCount - 1], in make_gradient()
775 // We add a tiny delta to t. When gradient stops are set up so that a hard stop in a vertically in MakeLinear()
778 // we will consistently get the color to the "right" of the stop. Of course if the hard stop in MakeLinear()
779 // falls at X.5 - delta then we still could get inconsistent results, but that is much less in MakeLinear()
814 args.fContext->priv().caps()->shaderCaps()->atan2ImplementedAsAtanYOverX(); in MakeSweep()
822 ? half(2 * atan(-coord.y, length(coord) - coord.x)) in MakeSweep()
823 : half(atan(-coord.y, -coord.x)); in MakeSweep()
825 // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi] in MakeSweep()
851 float t = r0_2 - p.y * p.y; in MakeConical()
855 v = -1; in MakeConical()
872 float t = length(p) * lengthScale - r0; in MakeConical()
882 "lengthScale", isRadiusIncreasing ? 1.0f : -1.0f); in MakeConical()
888 matrix.set(SkMatrix::Translate(-shader.getStartCenter().fX, in MakeConical()
889 -shader.getStartCenter().fY)); in MakeConical()
891 matrix->postScale(1 / dr, 1 / dr); in MakeConical()
904 uniform half fx; // focalX = r0/(r0-r1) in MakeConical()
907 float t = -1; in MakeConical()
910 float x_t = -1; in MakeConical()
914 x_t = length(p) - p.x * invR1; in MakeConical()
916 float temp = p.x * p.x - p.y * p.y; in MakeConical()
927 x_t = -sqrt(temp) - p.x * invR1; in MakeConical()
929 x_t = sqrt(temp) - p.x * invR1; in MakeConical()
941 v = -1; in MakeConical()
952 t = -x_t; in MakeConical()
954 t = -x_t + fx; in MakeConical()
959 t = 1 - t; in MakeConical()
967 bool isRadiusIncreasing = (1 - focalData.fFocalX) > 0, in MakeConical()
990 // a non-gradient processor. in RandomParams()
991 fColorCount = random->nextRangeU(2, kMaxRandomGradientColors); in RandomParams()
992 fUseColors4f = random->nextBool(); in RandomParams()
995 if (fColorCount == 1 || (fColorCount >= 2 && random->nextBool())) { in RandomParams()
1009 fColors4f[i].fR = random->nextUScalar1(); in RandomParams()
1010 fColors4f[i].fG = random->nextUScalar1(); in RandomParams()
1011 fColors4f[i].fB = random->nextUScalar1(); in RandomParams()
1012 fColors4f[i].fA = random->nextUScalar1(); in RandomParams()
1014 fColors[i] = random->nextU(); in RandomParams()
1018 stop = i < fColorCount - 1 ? stop + random->nextUScalar1() * (1.f - stop) : 1.f; in RandomParams()
1021 fTileMode = static_cast<SkTileMode>(random->nextULessThan(kSkTileModeCount)); in RandomParams()