// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/renderer/backend/gles/sampler_gles.h"

#include "impeller/base/validation.h"
#include "impeller/core/formats.h"
#include "impeller/renderer/backend/gles/formats_gles.h"
#include "impeller/renderer/backend/gles/proc_table_gles.h"
#include "impeller/renderer/backend/gles/texture_gles.h"

namespace impeller {

SamplerGLES::SamplerGLES(SamplerDescriptor desc) : Sampler(std::move(desc)) {}

SamplerGLES::~SamplerGLES() = default;

static GLint ToParam(MinMagFilter minmag_filter,
                     std::optional<MipFilter> mip_filter = std::nullopt) {
  if (!mip_filter.has_value()) {
    switch (minmag_filter) {
      case MinMagFilter::kNearest:
        return GL_NEAREST;
      case MinMagFilter::kLinear:
        return GL_LINEAR;
    }
    FML_UNREACHABLE();
  }

  switch (mip_filter.value()) {
    case MipFilter::kNearest:
      switch (minmag_filter) {
        case MinMagFilter::kNearest:
          return GL_NEAREST_MIPMAP_NEAREST;
        case MinMagFilter::kLinear:
          return GL_LINEAR_MIPMAP_NEAREST;
      }
    case MipFilter::kLinear:
      switch (minmag_filter) {
        case MinMagFilter::kNearest:
          return GL_NEAREST_MIPMAP_LINEAR;
        case MinMagFilter::kLinear:
          return GL_LINEAR_MIPMAP_LINEAR;
      }
  }
  FML_UNREACHABLE();
}

static GLint ToAddressMode(SamplerAddressMode mode,
                           bool supports_decal_sampler_address_mode) {
  switch (mode) {
    case SamplerAddressMode::kClampToEdge:
      return GL_CLAMP_TO_EDGE;
    case SamplerAddressMode::kRepeat:
      return GL_REPEAT;
    case SamplerAddressMode::kMirror:
      return GL_MIRRORED_REPEAT;
    case SamplerAddressMode::kDecal:
      if (supports_decal_sampler_address_mode) {
        return IMPELLER_GL_CLAMP_TO_BORDER;
      } else {
        return GL_CLAMP_TO_EDGE;
      }
  }
  FML_UNREACHABLE();
}

bool SamplerGLES::ConfigureBoundTexture(const TextureGLES& texture,
                                        const ProcTableGLES& gl) const {
  if (texture.NeedsMipmapGeneration()) {
    VALIDATION_LOG
        << "Texture mip count is > 1, but the mipmap has not been generated. "
           "Texture can not be sampled safely.";
    return false;
  }

  auto target = ToTextureTarget(texture.GetTextureDescriptor().type);

  if (!target.has_value()) {
    return false;
  }
  const auto& desc = GetDescriptor();

  std::optional<MipFilter> mip_filter = std::nullopt;
  if (texture.GetTextureDescriptor().mip_count > 1) {
    mip_filter = desc.mip_filter;
  }

  gl.TexParameteri(*target, GL_TEXTURE_MIN_FILTER,
                   ToParam(desc.min_filter, mip_filter));
  gl.TexParameteri(*target, GL_TEXTURE_MAG_FILTER, ToParam(desc.mag_filter));

  const auto supports_decal_mode =
      gl.GetCapabilities()->SupportsDecalSamplerAddressMode();

  const auto wrap_s =
      ToAddressMode(desc.width_address_mode, supports_decal_mode);
  const auto wrap_t =
      ToAddressMode(desc.height_address_mode, supports_decal_mode);

  gl.TexParameteri(*target, GL_TEXTURE_WRAP_S, wrap_s);
  gl.TexParameteri(*target, GL_TEXTURE_WRAP_T, wrap_t);

  if (wrap_s == IMPELLER_GL_CLAMP_TO_BORDER ||
      wrap_t == IMPELLER_GL_CLAMP_TO_BORDER) {
    // Transparent black.
    const GLfloat border_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    gl.TexParameterfv(*target, IMPELLER_GL_TEXTURE_BORDER_COLOR, border_color);
  }

  return true;
}

}  // namespace impeller
