/*
 * Copyright 2020 Google LLC.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Initial import from
 * skia:src/gpu/ganesh/tessellate/GrStrokeTessellationShader.cpp
 *
 * Copyright 2022 Rive
 */

#define MAX_PARAMETRIC_SEGMENTS_LOG2 10 // Max 1024 segments.

#ifdef @VERTEX
ATTR_BLOCK_BEGIN(Attrs)
// RHI Version > 5.8 failes to parse this when it's multi line
// End in '_' because D3D interprets the '1' as a semantic index.
ATTR(0, float4, @a_p0p1_);
ATTR(1, float4, @a_p2p3_);
ATTR(2, float4, @a_joinTan_and_ys); // [joinTangent, y, reflectionY]
#ifdef SPLIT_UINT4_ATTRIBUTES
ATTR(3, uint, @a_x0x1);
ATTR(4, uint, @a_reflectionX0X1);
ATTR(5, uint, @a_segmentCounts);
ATTR(6, uint, @a_contourIDWithFlags);
#else
ATTR(3,
     uint4,
     @a_args); // [x0x1, reflectionX0X1, segmentCounts, contourIDWithFlags]
#endif
ATTR_BLOCK_END
#endif

VARYING_BLOCK_BEGIN
NO_PERSPECTIVE VARYING(0, float4, v_p0p1);
NO_PERSPECTIVE VARYING(1, float4, v_p2p3);
// [vertexIdx, totalVertexCount, joinSegmentCount,
//  parametricSegmentCount, radsPerPolarSegment]
NO_PERSPECTIVE VARYING(2, float4, v_args);
// [joinTangent, radsPerJoinSegment]
NO_PERSPECTIVE VARYING(3, float3, v_joinArgs);
FLAT VARYING(4, uint, v_contourIDWithFlags);
VARYING_BLOCK_END

#ifdef @VERTEX
VERTEX_TEXTURE_BLOCK_BEGIN
TEXTURE_R16F_1D_ARRAY(PER_FLUSH_BINDINGS_SET,
                      FEATHER_TEXTURE_IDX,
                      @featherTexture);
VERTEX_TEXTURE_BLOCK_END

SAMPLER_LINEAR(FEATHER_TEXTURE_IDX, featherSampler)

VERTEX_STORAGE_BUFFER_BLOCK_BEGIN
STORAGE_BUFFER_U32x4(PATH_BUFFER_IDX, PathBuffer, @pathBuffer);
STORAGE_BUFFER_U32x4(CONTOUR_BUFFER_IDX, ContourBuffer, @contourBuffer);
VERTEX_STORAGE_BUFFER_BLOCK_END

VERTEX_MAIN(@tessellateVertexMain, Attrs, attrs, _vertexID, _instanceID)
{
    // Each instance repeats twice. Once for normal patch(es) and once for
    // reflection(s).
    ATTR_UNPACK(_instanceID, attrs, @a_p0p1_, float4);
    ATTR_UNPACK(_instanceID, attrs, @a_p2p3_, float4);
    ATTR_UNPACK(_instanceID, attrs, @a_joinTan_and_ys, float4);
#ifdef SPLIT_UINT4_ATTRIBUTES
    ATTR_UNPACK(_instanceID, attrs, @a_x0x1, uint);
    ATTR_UNPACK(_instanceID, attrs, @a_reflectionX0X1, uint);
    ATTR_UNPACK(_instanceID, attrs, @a_segmentCounts, uint);
    ATTR_UNPACK(_instanceID, attrs, @a_contourIDWithFlags, uint);

    uint4 @a_args = uint4(@a_x0x1,
                          @a_reflectionX0X1,
                          @a_segmentCounts,
                          @a_contourIDWithFlags);
#else
    ATTR_UNPACK(_instanceID, attrs, @a_args, uint4);
#endif

    VARYING_INIT(v_p0p1, float4);
    VARYING_INIT(v_p2p3, float4);
    VARYING_INIT(v_args, float4);
    VARYING_INIT(v_joinArgs, float3);
    VARYING_INIT(v_contourIDWithFlags, uint);

    float2 p0 = @a_p0p1_.xy;
    float2 p1 = @a_p0p1_.zw;
    float2 p2 = @a_p2p3_.xy;
    float2 p3 = @a_p2p3_.zw;
    // Each instance has two spans, potentially for both a forward copy and and
    // reflection. (If the second span isn't needed, the client will have placed
    // it offscreen.)
    bool isFirstSpan = _vertexID < 4;
    float y = isFirstSpan ? @a_joinTan_and_ys.z : @a_joinTan_and_ys.w;
    int x0x1 = int(isFirstSpan ? @a_args.x : @a_args.y);
#ifdef GLSL
    int x1up = x0x1 << 16;
    if (@a_args.z == 0xffffffffu)
    {
        // Pixel 8 with ARM Mali-G715 throws away "x0x1 << 16 >> 16". We need
        // this in order to sign-extend the bottom 16 bits of x0x1. Create a
        // branch that we know won't be taken, in order to convince the compiler
        // not to throw this operation away. NOTE: we could use
        // bitfieldExtract(), but it isn't available on ES 3.0.
        --x1up;
    }
    float x0 = float(x1up >> 16);
#else
    float x0 = float(x0x1 << 16 >> 16);
#endif
    float x1 = float(x0x1 >> 16);
    float2 coord = float2((_vertexID & 1) == 0 ? x0 : x1,
                          (_vertexID & 2) == 0 ? y + 1. : y);
    if ((x1 - x0) * uniforms.tessInverseViewportY < .0)
    {
        // Make sure we always emit clockwise triangles. Swap the top and bottom
        // vertices.
        coord.y = 2. * y + 1. - coord.y;
    }

    // Unpack arguments.
    uint parametricSegmentCount = @a_args.z & 0x3ffu;
    uint polarSegmentCount = (@a_args.z >> 10) & 0x3ffu;
    uint joinSegmentCount = @a_args.z >> 20;
    uint contourIDWithFlags = @a_args.w;
    uint contourID = contourIDWithFlags & CONTOUR_ID_MASK;
    uint pathID =
        contourID > 0u
            // Clamp contourID at 1, even though this is the <true> expression
            // of "contourID > 0u", and even though GLSL specifies short-circuit
            // evaluation for the ternary operator.
            //
            // PowerVR (B-Series BXM-8-256, build 1.15) appears to evaluate this
            // expression unconditionally, leading to a load at buffer index
            // 0xffffffff when contourID == 0, which crashes the render pass.
            ? STORAGE_BUFFER_LOAD4(@contourBuffer, max(contourID, 1u) - 1u).z
            : 0u;
    uint4 pathData = pathID != 0u
                         ? STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 1u)
                         : uint4(0u, 0u, 0u, 0u);
    float strokeRadius = uintBitsToFloat(pathData.z);
    float featherRadius = uintBitsToFloat(pathData.w);

    if (featherRadius != .0 && strokeRadius == .0)
    {
        // We're a cubic from a feathered fill. To simulate the
        // feather-softening effect that happens with curvature, reduce the
        // height of the curve proportionally.
        // Start by finding the point of maximum height on the cubic.
        float maxHeightT;
        float height = find_cubic_max_height(p0, p1, p2, p3, maxHeightT);

        // Measure curvature across one standard deviation of the feather.
        float oneStddev = featherRadius * (1. / FEATHER_TEXTURE_STDDEVS);
        float curvature = measure_cubic_local_curvature(p0,
                                                        p1,
                                                        p2,
                                                        p3,
                                                        maxHeightT,
                                                        oneStddev);

        // The feather gets softer with curvature. Find a dimming factor based
        // on the strength of curvature at maximum height.
        float dimming = 1. - curvature * (1. / PI);

        // It gets hard to measure curvature on short segments. Also taper down
        // to completely flat as the distance between endpoints moves from 2
        // standard deviations to 1.
        float stddevsPow2 = dot(p3 - p0, p3 - p0) / (oneStddev * oneStddev);
        float dimmingByStddevs = (stddevsPow2 - 1.) * .5;
        dimming = min(dimming, dimmingByStddevs);

        // Unfortunately, the best method we have to get rid of some final
        // speckles on cusps is to dim everything by 1%.
        dimming = min(dimming, .99);

        // Soften the feather by reducing the curve height. Find a new height
        // such that the center of the feather (currently 50% opacity) is
        // reduced to "50% * dimming".
        float desiredOpacityOnCenter = .5 * dimming;
        float x = INVERSE_FEATHER(desiredOpacityOnCenter) * -2. + 1.;
        float softness = clamped_divide(x * featherRadius, height);

        // Flatten the curve down to "softenedHeight". (Height scales linearly
        // as we lerp the control points to "flatLinePoints".)
        float4 flatLinePoints =
            mix(p0.xyxy, p3.xyxy, float4(1. / 3., 1. / 3., 2. / 3., 2. / 3.));
        p1 = mix(p1, flatLinePoints.xy, softness);
        p2 = mix(p2, flatLinePoints.zw, softness);
    }

    if ((contourIDWithFlags & CULL_EXCESS_TESSELLATION_SEGMENTS_CONTOUR_FLAG) !=
        0u)
    {
        // This span may have more tessellation vertices allocated to it than
        // necessary (e.g., outerCurve patches all have a fixed patch size,
        // regardless of how many segments the curve actually needs). Re-run
        // Wang's formula to figure out how many segments we actually need, and
        // make any excess segments degenerate by co-locating their vertices at
        // T=0.
        float2x2 mat = make_float2x2(
            uintBitsToFloat(STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u)));
        float2 d0 = MUL(mat, -2. * p1 + p2 + p0);
        float2 d1 = MUL(mat, -2. * p2 + p3 + p1);
        float m = max(dot(d0, d0), dot(d1, d1));
        float n = max(ceil(sqrt(.75 * 4. * sqrt(m))), 1.);
        parametricSegmentCount = min(uint(n), parametricSegmentCount);
    }

    // Polar and parametric segments share the same beginning and ending
    // vertices, so the merged *vertex* count is equal to the sum of polar and
    // parametric *segment* counts.
    uint totalVertexCount =
        parametricSegmentCount + polarSegmentCount + joinSegmentCount - 1u;

    float2x2 tangents = find_cubic_tangents(p0, p1, p2, p3);
    float theta = acos(cosine_between_vectors(tangents[0], tangents[1]));
    float radsPerPolarSegment = theta / float(polarSegmentCount);
    // Adjust sign of radsPerPolarSegment to match the direction the curve
    // turns.
    // NOTE: Since the curve is not allowed to inflect, we can just check
    // F'(.5) x F''(.5).
    // NOTE: F'(.5) x F''(.5) has the same sign as (p2 - p0) x (p3 - p1).
    float turn = determinant(float2x2(p2 - p0, p3 - p1));
    // This is the case for joins and cusps where points are co-located.
    if (turn == .0)
        turn = determinant(tangents);
    if (turn < .0)
        radsPerPolarSegment = -radsPerPolarSegment;

    v_p0p1 = float4(p0, p1);
    v_p2p3 = float4(p2, p3);
    v_args = float4(float(totalVertexCount) - abs(x1 - coord.x), // vertexIdx
                    float(totalVertexCount), // totalVertexCount
                    (joinSegmentCount << 10) | parametricSegmentCount,
                    radsPerPolarSegment);
    if (joinSegmentCount > 1u)
    {
        float2x2 joinTangents = float2x2(tangents[1], @a_joinTan_and_ys.xy);
        float joinTheta =
            acos(cosine_between_vectors(joinTangents[0], joinTangents[1]));
        float joinSpan = float(joinSegmentCount);
        if ((contourIDWithFlags &
             (JOIN_TYPE_MASK | EMULATED_STROKE_CAP_CONTOUR_FLAG)) ==
            (ROUND_JOIN_CONTOUR_FLAG | EMULATED_STROKE_CAP_CONTOUR_FLAG))
        {
            // Round caps emulated as joins need to emit vertices at T=0 and
            // T=1, unlike normal round joins. The fragment shader will handle
            // most of this, but here we need to adjust radsPerJoinSegment to
            // account for the fact that this join will be rotating around two
            // more segments.
            joinSpan -= 2.;
        }
        float radsPerJoinSegment = joinTheta / joinSpan;
        if (determinant(joinTangents) < .0)
            radsPerJoinSegment = -radsPerJoinSegment;
        v_joinArgs.xy = @a_joinTan_and_ys.xy;
        v_joinArgs.z = radsPerJoinSegment;
    }

    if (x1 < x0) // Reflections are drawn right to left.
    {
        contourIDWithFlags |= MIRRORED_CONTOUR_CONTOUR_FLAG;
    }

    v_contourIDWithFlags = contourIDWithFlags;

    float4 pos = pixel_coord_to_clip_coord(coord,
                                           2. / TESS_TEXTURE_WIDTH,
                                           uniforms.tessInverseViewportY);
#ifdef @POST_INVERT_Y
    pos.y = -pos.y;
#endif

    VARYING_PACK(v_p0p1);
    VARYING_PACK(v_p2p3);
    VARYING_PACK(v_args);
    VARYING_PACK(v_joinArgs);
    VARYING_PACK(v_contourIDWithFlags);
    EMIT_VERTEX(pos);
}
#endif

#ifdef @FRAGMENT
FRAG_TEXTURE_BLOCK_BEGIN
FRAG_TEXTURE_BLOCK_END

FRAG_DATA_MAIN(TESSDATA4, @tessellateFragmentMain)
{
    VARYING_UNPACK(v_p0p1, float4);
    VARYING_UNPACK(v_p2p3, float4);
    VARYING_UNPACK(v_args, float4);
    VARYING_UNPACK(v_joinArgs, float3);
    VARYING_UNPACK(v_contourIDWithFlags, uint);

    float2 p0 = v_p0p1.xy;
    float2 p1 = v_p0p1.zw;
    float2 p2 = v_p2p3.xy;
    float2 p3 = v_p2p3.zw;
    float2x2 tangents = find_cubic_tangents(p0, p1, p2, p3);
    // Colocate any padding vertices at T=0.
    float vertexIdx = max(floor(v_args.x), .0);
    float totalVertexCount = v_args.y;
    uint joinSegmentCount_and_parametricSegmentCount = uint(v_args.z);
    float parametricSegmentCount =
        float(joinSegmentCount_and_parametricSegmentCount & 0x3ffu);
    float joinSegmentCount =
        float(joinSegmentCount_and_parametricSegmentCount >> 10);
    float radsPerPolarSegment = v_args.w;
    uint contourIDWithFlags = v_contourIDWithFlags;

    // mergedVertexID/mergedSegmentCount are relative to the sub-section of the
    // instance this vertex belongs to (either the curve section that consists
    // of merged polar and parametric segments, or the join section composed of
    // just polar segments).
    //
    // Begin with the assumption that we belong to the curve section.
    float mergedSegmentCount = totalVertexCount - joinSegmentCount;
    float mergedVertexID = vertexIdx;
    if (mergedVertexID <= mergedSegmentCount)
    {
        // We do belong to the curve section. Clear out any stroke join flags.
        contourIDWithFlags &= ~JOIN_TYPE_MASK;
    }
    else
    {
        // We actually belong to the join section following the curve. Construct
        // a point-cubic with rotation.
        p0 = p1 = p2 = p3;
        tangents = float2x2(tangents[1], v_joinArgs.xy /*joinTangent*/);
        parametricSegmentCount = 1.;
        mergedVertexID -= mergedSegmentCount;
        mergedSegmentCount = joinSegmentCount;
        radsPerPolarSegment = v_joinArgs.z; // radsPerJoinSegment.
        if ((contourIDWithFlags & JOIN_TYPE_MASK) > ROUND_JOIN_CONTOUR_FLAG)
        {
            // Miter or bevel join vertices snap to either tangents[0] or
            // tangents[1], and get adjusted in the shader that follows.
            if (mergedVertexID < 2.5) // With 5 join segments, this branch will
                                      // see IDs: 1, 2, 3, 4.
                contourIDWithFlags |= JOIN_TANGENT_0_CONTOUR_FLAG;
            if (mergedVertexID > 1.5 && mergedVertexID < 3.5)
                contourIDWithFlags |= JOIN_TANGENT_INNER_CONTOUR_FLAG;
        }
        else if ((contourIDWithFlags & EMULATED_STROKE_CAP_CONTOUR_FLAG) !=
                     0u ||
                 (contourIDWithFlags & JOIN_TYPE_MASK) ==
                     FEATHER_JOIN_CONTOUR_FLAG)
        {
            // Round caps emulated as joins and feather joins need to emit
            // vertices at T=0 and T=1, unlike normal round joins. Preserve
            // the same number of vertices, but adjust our stepping
            // parameters so we begin at T=0 and end at T=1. (The CPU should
            // have known we were going to add vertices here and increased our
            // count to make sure the tessellation would still be smooth).
            mergedSegmentCount -= 2.;
            --mergedVertexID;
        }
        contourIDWithFlags |= radsPerPolarSegment < .0
                                  ? LEFT_JOIN_CONTOUR_FLAG
                                  : RIGHT_JOIN_CONTOUR_FLAG;
    }

    float2 tessCoord;
    float theta = .0;
    if (mergedVertexID == .0 || mergedVertexID == mergedSegmentCount ||
        (contourIDWithFlags & JOIN_TYPE_MASK) > ROUND_JOIN_CONTOUR_FLAG)
    {
        // Tessellated vertices at the beginning and end of the strip use exact
        // endpoints and tangents. This ensures crack-free seaming between
        // instances.
        bool isTan0 = mergedVertexID < mergedSegmentCount * .5;
        tessCoord = isTan0 ? p0 : p3;
        theta = atan2(isTan0 ? tangents[0] : tangents[1]);
    }
    else if ((contourIDWithFlags & RETROFITTED_TRIANGLE_CONTOUR_FLAG) != 0u)
    {
        // This cubic should actually be drawn as the single, non-AA triangle:
        // [p0, p1, p3]. This is used to squeeze in more rare triangles, like
        // "grout" triangles from self intersections on interior triangulation,
        // where it wouldn't be worth it to put them in their own dedicated draw
        // call.
        tessCoord = p1;
    }
    else
    {
        float T, polarT;
        if (parametricSegmentCount == mergedSegmentCount)
        {
            // There are no polar vertices. This is (probably) a fill. Vertices
            // are spaced evenly in parametric space.
            T = mergedVertexID / parametricSegmentCount;
            polarT = .0; // Set polarT != T to ensure we calculate the
                         // parametric tangent later.
        }
        else
        {
            // Compute the location and tangent direction of the tessellated
            // stroke vertex with the integral id "mergedVertexID", where
            // mergedVertexID is the sorted-order index of parametric and polar
            // vertices. Start by finding the tangent function's power basis
            // coefficients. These define a tangent direction (scaled by some
            // uniform value) as:
            //
            //                                                 |T^2|
            //     Tangent_Direction(T) = dx,dy = |A  2B  C| * |T  |
            //                                    |.   .  .|   |1  |
            float2 A, B, C = p1 - p0;
            float2 D = p3 - p0;
            float2 E = p2 - p1;
            B = E - C;
            A = -3. * E + D;
            // FIXME(crbug.com/800804,skbug.com/11268): Consider normalizing the
            // exponents in A,B,C at this point in order to prevent fp32
            // overflow.

            // Now find the coefficients that give a tangent direction from a
            // parametric vertex ID:
            //
            //  Tangent_Direction(parametricVertexID) = dx,dy =
            //
            //                     |parametricVertexID^2|
            //      |A  B_  C_| *  |parametricVertexID  |
            //      |.   .   .|    |1                   |
            //
            float2 B_ = B * (parametricSegmentCount * 2.);
            float2 C_ = C * (parametricSegmentCount * parametricSegmentCount);

            // Run a binary search to determine the highest parametric vertex
            // that is located on or before the mergedVertexID. A merged ID is
            // determined by the sum of complete parametric and polar segments
            // behind it. i.e., find the highest parametric vertex where:
            //
            //    parametricVertexID + floor(numPolarSegmentsAtParametricT) <=
            //    mergedVertexID
            //
            float lastParametricVertexID = .0;
            float maxParametricVertexID =
                min(parametricSegmentCount - 1., mergedVertexID);
            // FIXME(crbug.com/800804,skbug.com/11268): This normalize() can
            // overflow.
            float2 tan0norm = normalize(tangents[0]);
            float negAbsRadsPerSegment = -abs(radsPerPolarSegment);
            float maxRotation0 =
                (1. + mergedVertexID) * abs(radsPerPolarSegment);
            for (int p = MAX_PARAMETRIC_SEGMENTS_LOG2 - 1; p >= 0; --p)
            {
                // Test the parametric vertex at lastParametricVertexID + 2^p.
                float testParametricID =
                    lastParametricVertexID + exp2(float(p));
                if (testParametricID <= maxParametricVertexID)
                {
                    float2 testTan = testParametricID * A + B_;
                    testTan = testParametricID * testTan + C_;
                    float cosRotation = dot(normalize(testTan), tan0norm);
                    float maxRotation =
                        testParametricID * negAbsRadsPerSegment + maxRotation0;
                    maxRotation = min(maxRotation, PI);
                    // Is rotation <= maxRotation? (i.e., is the number of
                    // complete polar segments behind testT, + testParametricID
                    // <= mergedVertexID?)
                    if (cosRotation >= cos(maxRotation))
                        lastParametricVertexID = testParametricID;
                }
            }

            // Find the T value of the parametric vertex at
            // lastParametricVertexID.
            float parametricT = lastParametricVertexID / parametricSegmentCount;

            // Now that we've identified the highest parametric vertex on or
            // before the mergedVertexID, the highest polar vertex is easy:
            float lastPolarVertexID = mergedVertexID - lastParametricVertexID;

            // Find the angle of tan0, or the angle between tan0norm and the
            // positive x axis.
            float theta0 = acos(clamp(tan0norm.x, -1., 1.));
            theta0 = tan0norm.y >= .0 ? theta0 : -theta0;

            // Find the tangent vector on the vertex at lastPolarVertexID.
            theta = lastPolarVertexID * radsPerPolarSegment + theta0;
            float2 norm = float2(sin(theta), -cos(theta));

            // Find the T value where the tangent is orthogonal to norm. This is
            // a quadratic:
            //
            //     dot(norm, Tangent_Direction(T)) == 0
            //
            //                         |T^2|
            //     norm * |A  2B  C| * |T  | == 0
            //            |.   .  .|   |1  |
            //
            float a = dot(norm, A), b_over_2 = dot(norm, B), c = dot(norm, C);
            float discr_over_4 = max(b_over_2 * b_over_2 - a * c, .0);
            float q = sqrt(discr_over_4);
            if (b_over_2 > .0)
                q = -q;
            q -= b_over_2;

            // Roots are q/a and c/q. Since each curve section does not inflect
            // or rotate more than 180 degrees, there can only be one tangent
            // orthogonal to "norm" inside 0..1. Pick the root nearest .5.
            float _5qa = -.5 * q * a;
            float2 root = (abs(q * q + _5qa) < abs(a * c + _5qa))
                              ? float2(q, a)
                              : float2(c, q);
            polarT = (root.t != .0) ? root.s / root.t : .0;
            polarT = clamp(polarT, .0, 1.);

            // The root finder above can become unstable when lastPolarVertexID
            // == 0 (e.g., if there are roots at exatly 0 and 1 both). polarT
            // should always == 0 in this case.
            if (lastPolarVertexID == .0)
                polarT = .0;

            // Now that we've identified the T values of the last parametric and
            // polar vertices, our final T value for mergedVertexID is whichever
            // is larger.
            T = max(parametricT, polarT);
        }

        // Evaluate the cubic at T. Use De Casteljau's for its accuracy and
        // stability.
        float2 ab = unchecked_mix(p0, p1, T);
        float2 bc = unchecked_mix(p1, p2, T);
        float2 cd = unchecked_mix(p2, p3, T);
        float2 abc = unchecked_mix(ab, bc, T);
        float2 bcd = unchecked_mix(bc, cd, T);
        tessCoord = unchecked_mix(abc, bcd, T);

        // If we went with T=parametricT, then update theta. Otherwise leave it
        // at the polar theta found previously. (In the event that
        // parametricT == polarT, we keep the polar theta.)
        if (T != polarT)
            theta = atan2(bcd - abc);
    }

    TESSDATA4 tessData;
    tessData.xy = FLOAT_AS_TESSDATA(tessCoord);
    if ((contourIDWithFlags & JOIN_TYPE_MASK) == FEATHER_JOIN_CONTOUR_FLAG)
    {
        // Feather joins work out their stepping in the vertex shader, so we
        // emit the original tessellation parameters instead of just the tangent
        // angle and let the vertex shader work it all out.
        // Pack these as integers instead of using packHalf2x16() because the
        // latter does not work on ARM Mali.
        tessData.z = UINT_AS_TESSDATA((uint(mergedSegmentCount) << 16) |
                                      uint(mergedVertexID));
    }
    else
    {
        tessData.z = FLOAT_AS_TESSDATA(mod(theta, _2PI));
    }
    tessData.w = UINT_AS_TESSDATA(contourIDWithFlags);
    EMIT_FRAG_DATA(tessData);
}
#endif
