/*
 * Copyright 2019 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/private/SkTPin.h"
#include "src/gpu/ccpr/GrOctoBounds.h"
#include <algorithm>

bool GrOctoBounds::clip(const SkIRect& clipRect) {
    // Intersect dev bounds with the clip rect.
    float l = std::max(fBounds.left(), (float)clipRect.left());
    float t = std::max(fBounds.top(), (float)clipRect.top());
    float r = std::min(fBounds.right(), (float)clipRect.right());
    float b = std::min(fBounds.bottom(), (float)clipRect.bottom());

    float l45 = fBounds45.left();
    float t45 = fBounds45.top();
    float r45 = fBounds45.right();
    float b45 = fBounds45.bottom();

    // Check if either the bounds or 45-degree bounds are empty. We write this check as the NOT of
    // non-empty rects, so we will return false if any values are NaN.
    if (!(l < r && t < b && l45 < r45 && t45 < b45)) {
        return false;
    }

    // Tighten dev bounds around the new (octagonal) intersection that results after clipping. This
    // may be tighter now even than the clipped bounds, depending on the diagonals. Shader code that
    // emits octagons expects both bounding boxes to circumcribe the inner octagon, and will fail if
    // they do not.
    if (l45 > Get_x45(r,b)) {
        // Slide the bottom upward until it crosses the l45 diagonal at x=r.
        //     y = x + (y0 - x0)
        // Substitute: l45 = x0 - y0
        //     y = x - l45
        b = SkTPin(r - l45, t, b);
    } else if (r45 < Get_x45(r,b)) {
        // Slide the right side leftward until it crosses the r45 diagonal at y=b.
        //     x = y + (x0 - y0)
        // Substitute: r45 = x0 - y0
        //     x = y + r45
        r = SkTPin(b + r45, l, r);
    }
    if (l45 > Get_x45(l,t)) {
        // Slide the left side rightward until it crosses the l45 diagonal at y=t.
        //     x = y + (x0 - y0)
        // Substitute: l45 = x0 - y0
        //     x = y + l45
        l = SkTPin(t + l45, l, r);
    } else if (r45 < Get_x45(l,t)) {
        // Slide the top downward until it crosses the r45 diagonal at x=l.
        //     y = x + (y0 - x0)
        // Substitute: r45 = x0 - y0
        //     y = x - r45
        t = SkTPin(l - r45, t, b);
    }
    if (t45 > Get_y45(l,b)) {
        // Slide the left side rightward until it crosses the t45 diagonal at y=b.
        //     x = -y + (x0 + y0)
        // Substitute: t45 = x0 + y0
        //     x = -y + t45
        l = SkTPin(t45 - b, l, r);
    } else if (b45 < Get_y45(l,b)) {
        // Slide the bottom upward until it crosses the b45 diagonal at x=l.
        //     y = -x + (y0 + x0)
        // Substitute: b45 = x0 + y0
        //     y = -x + b45
        b = SkTPin(b45 - l, t, b);
    }
    if (t45 > Get_y45(r,t)) {
        // Slide the top downward until it crosses the t45 diagonal at x=r.
        //     y = -x + (y0 + x0)
        // Substitute: t45 = x0 + y0
        //     y = -x + t45
        t = SkTPin(t45 - r, t, b);
    } else if (b45 < Get_y45(r,t)) {
        // Slide the right side leftward until it crosses the b45 diagonal at y=t.
        //     x = -y + (x0 + y0)
        // Substitute: b45 = x0 + y0
        //     x = -y + b45
        r = SkTPin(b45 - t, l, r);
    }

    // Tighten the 45-degree bounding box. Since the dev bounds are now fully tightened, we only
    // have to clamp the diagonals to outer corners.
    // NOTE: This will not cause l,t,r,b to need more insetting. We only ever change a diagonal by
    // pinning it to a FAR corner, which, by definition, is still outside the other corners.
    l45 = SkTPin(Get_x45(l,b), l45, r45);
    t45 = SkTPin(Get_y45(l,t), t45, b45);
    r45 = SkTPin(Get_x45(r,t), l45, r45);
    b45 = SkTPin(Get_y45(r,b), t45, b45);

    // Make one final check for empty or NaN bounds. If the dev bounds were clipped completely
    // outside one of the diagonals, they will have been pinned to empty. It's also possible that
    // some Infs crept in and turned into NaNs.
    if (!(l < r && t < b && l45 < r45 && t45 < b45)) {
        return false;
    }

    fBounds.setLTRB(l, t, r, b);
    fBounds45.setLTRB(l45, t45, r45, b45);

#ifdef SK_DEBUG
    // Verify dev bounds are inside the clip rect.
    SkASSERT(l >= (float)clipRect.left());
    SkASSERT(t >= (float)clipRect.top());
    SkASSERT(r <= (float)clipRect.right());
    SkASSERT(b <= (float)clipRect.bottom());
    this->validateBoundsAreTight();
#endif

    return true;
}

#if defined(SK_DEBUG) || GR_TEST_UTILS
void GrOctoBounds::validateBoundsAreTight() const {
    this->validateBoundsAreTight([](bool cond, const char* file, int line, const char* code) {
        SkASSERTF(cond, "%s(%d): assertion failure: \"assert(%s)\"", file, line, code);
    });
}

void GrOctoBounds::validateBoundsAreTight(const std::function<void(
        bool cond, const char* file, int line, const char* code)>& validateFn) const {
    // The octobounds calculated in GrCCPerFlushResources::renderShapeInAtlas use FMAs to compute
    // M * (x,y) and T45 * M * (x,y) in parallel. This leads to a not-insignificant floating point
    // difference between (T45 * M * (x,y)) stored in fBounds45, and T45 * (M * (x,y)) calculated
    // here from fBounds with the Get_xy45 functions.
    constexpr static float epsilon = 1e-2f;

    float l=fBounds.left(), l45=fBounds45.left();
    float t=fBounds.top(), t45=fBounds45.top();
    float r=fBounds.right(), r45=fBounds45.right();
    float b=fBounds.bottom(), b45=fBounds45.bottom();

#define VALIDATE(CODE) validateFn(CODE, __FILE__, __LINE__, #CODE)
    // Verify diagonals are inside far corners of the dev bounds.
    VALIDATE(l45 >= Get_x45(l,b) - epsilon);
    VALIDATE(t45 >= Get_y45(l,t) - epsilon);
    VALIDATE(r45 <= Get_x45(r,t) + epsilon);
    VALIDATE(b45 <= Get_y45(r,b) + epsilon);
    // Verify verticals and horizontals are inside far corners of the 45-degree dev bounds.
    VALIDATE(l >= Get_x(l45,t45) - epsilon);
    VALIDATE(t >= Get_y(r45,t45) - epsilon);
    VALIDATE(r <= Get_x(r45,b45) + epsilon);
    VALIDATE(b <= Get_y(l45,b45) + epsilon);
    // Verify diagonals are outside middle corners of the dev bounds.
    VALIDATE(l45 <= Get_x45(r,b) + epsilon);
    VALIDATE(l45 <= Get_x45(l,t) + epsilon);
    VALIDATE(t45 <= Get_y45(l,b) + epsilon);
    VALIDATE(t45 <= Get_y45(r,t) + epsilon);
    VALIDATE(r45 >= Get_x45(l,t) - epsilon);
    VALIDATE(r45 >= Get_x45(r,b) - epsilon);
    VALIDATE(b45 >= Get_y45(r,t) - epsilon);
    VALIDATE(b45 >= Get_y45(l,b) - epsilon);
    // Verify verticals and horizontals are outside middle corners of the 45-degree dev bounds.
    VALIDATE(l <= Get_x(l45,b45) + epsilon);
    VALIDATE(l <= Get_x(r45,t45) + epsilon);
    VALIDATE(t <= Get_y(r45,b45) + epsilon);
    VALIDATE(t <= Get_y(l45,t45) + epsilon);
    VALIDATE(r >= Get_x(r45,t45) - epsilon);
    VALIDATE(r >= Get_x(l45,b45) - epsilon);
    VALIDATE(b >= Get_y(l45,t45) - epsilon);
    VALIDATE(b >= Get_y(r45,b45) - epsilon);
#undef VALIDATE
}
#endif
