/*
 * Copyright 2026 Rive
 */

#include "rive/renderer/triangulation_controller.hpp"

#include <algorithm>
#include <cassert>
#include <cmath>

namespace rive::gpu
{
bool TriangulationController::admits(float area, size_t verbCount)
{
  assert(isEligible(area, verbCount));
  if (std::isinf(m_thresholds.frameBudgetMs))
  {
    // The guards decide alone. There's no budget to spend down and
    // endFrame() won't tune, so there's no score or bracket worth tracking
    // either.
    return true;
  }
  if (budgetExhausted())
  {
    // Out of budget. That's no verdict on the path's score, so don't record
    // it as a rejection: it would tell endFrame() to loosen when the real
    // problem is that we already admitted too much.
    return false;
  }

  // Triangulate based on value density: the biggest wins are large-area /
  // low-verb fills, so score = area / cost, where cost models triangulation's
  // ~N-log-N verb complexity.
  assert(verbCount > 1);
  const float n = static_cast<float>(verbCount);
  const float score = area / (n * std::log2(n));
  if (score > m_scoreThreshold)
  {
    m_frameMinAdmittedScore = std::min(m_frameMinAdmittedScore, score);
    return true;
  }
  else
  {
    m_frameMaxRejectedScore = std::max(m_frameMaxRejectedScore, score);
    return false;
  }
}

void TriangulationController::endFrame()
{
  const double frameBudgetMs = m_thresholds.frameBudgetMs;
  if (frameBudgetMs <= 0 || std::isinf(frameBudgetMs))
  {
    // Nothing to tune: at 0 we never triangulate, and at infinity the
    // guards decide alone. Leave the threshold where it is so the decision
    // stays independent of measured time.
    return;
  }

  const double frameMs = m_frameSeconds * 1e3;
  // Low-pass (EWMA) the noisy per-frame signal so the controller tracks the
  // trend -- including slow thermal/DVFS drift -- rather than frame-to-frame
  // jitter in which paths happen to be onscreen.
  constexpr double Alpha = 0.1;
  m_timeEwmaMs += Alpha * (frameMs - m_timeEwmaMs);

  // Nudge the value-density threshold toward the budget, with a hysteresis
  // dead-band. Over budget -> raise it (admit fewer, shedding the
  // lowest-value paths first); under -> lower it.
  const double ratio = m_timeEwmaMs / frameBudgetMs;
  if (ratio > 1.05 || ratio < 0.95)
  {
    // Both sides aim at a score measured on this frame's bracket, betting
    // it recurs in the next one. Overshoot a little so the decision still
    // flips if it drifts.
    constexpr float BracketBackoff = .99f;
    // The sqrt makes the step large when far from budget and gentle near
    // it, so it converges in a handful of frames without oscillating.
    const double factor = std::clamp(std::sqrt(ratio), 0.5, 2.0);
    if (factor > 1)
    {
      // EWMA called for us to tighten (reject more triangulations).
      if (m_frameMinAdmittedScore !=
          std::numeric_limits<float>::infinity()) // If we admitted
                                                  // nothing, we already
                                                  // rejected everything,
                                                  // so tightening further
                                                  // does nothing.
      {
        // The multiplicative step is blind to the actual triangulations
        // being scored, operating solely on the time ratio to tighten
        // the heuristic. However, we do track the frame's min admitted
        // triangulation score, which lets us tighten enough to reject
        // at least one more path when the step alone wouldn't make a
        // difference.
        // NOTE: The EWMA would converge either way, but the bracket
        // gets us there in one frame instead of a geometric climb, and
        // doesn't overrun the budget along the way.
        m_scoreThreshold = std::max(
            m_scoreThreshold * static_cast<float>(factor),
            m_frameMinAdmittedScore / BracketBackoff);
      }
    }
    else
    {
      // EWMA called for us to loosen (admit more triangulations).
      if (m_frameMaxRejectedScore != 0) // If we rejected nothing, we
                                        // already admitted everything, so
                                        // loosening further does nothing.
      {
        // The multiplicative step is blind to the actual triangulations
        // being scored, operating solely on the time ratio to loosen
        // the heuristic. However, we do track the frame's max rejected
        // triangulation score, which lets us loosen enough to admit at
        // least one more path when the step alone wouldn't make a
        // difference.
        // NOTE: The EWMA would converge either way, but the bracket
        // gets us there in one frame instead of a geometric descent,
        // and doesn't leave triangulations on the table along the way.
        m_scoreThreshold = std::min(
            m_scoreThreshold * static_cast<float>(factor),
            m_frameMaxRejectedScore * BracketBackoff);
      }
    }
  }
  m_scoreThreshold = std::clamp(m_scoreThreshold, 1.f, 1e9f);
}
} // namespace rive::gpu
