// Copyright 2017 The Fuchsia 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 "garnet/lib/ui/gfx/resources/material.h"

#include "garnet/lib/ui/gfx/engine/session.h"
#include "garnet/lib/ui/gfx/resources/image.h"
#include "garnet/lib/ui/gfx/resources/image_base.h"
#include "garnet/lib/ui/gfx/resources/image_pipe.h"

namespace {

// TODO(SCN-1380): This is a hack that temporarily avoids memory and performance
// issues involving immutable samplers. It relies on the fact that Scenic is
// currently a singleton service with a single vk::Device, with no user-provided
// parameters that affect sampler construction other than image format. SCN-1380
// covers the real task to solve this problem, which involves design work both
// at the Scenic and Escher levels.
escher::SamplerPtr CreateNV12Sampler(escher::ResourceRecycler* recycler) {
  static vk::Device last_device;
  static escher::SamplerPtr last_sampler;

  if (recycler->vulkan_context().device == last_device && last_sampler)
    return last_sampler;

  if (last_sampler) {
    FXL_LOG(WARNING) << "YUV Sampler was not successfully cached, memory "
                        "footprint will increase.";
  }

  last_device = recycler->vulkan_context().device;
  last_sampler = fxl::MakeRefCounted<escher::Sampler>(
      recycler, vk::Format::eG8B8R82Plane420Unorm, vk::Filter::eLinear);
  return last_sampler;
}

}  // namespace

namespace scenic_impl {
namespace gfx {

const ResourceTypeInfo Material::kTypeInfo = {ResourceType::kMaterial,
                                              "Material"};

Material::Material(Session* session, ResourceId id)
    : Resource(session, id, Material::kTypeInfo),
      escher_material_(fxl::MakeRefCounted<escher::Material>()) {}

void Material::SetColor(float red, float green, float blue, float alpha) {
  escher_material_->set_color(escher::vec4(red, green, blue, alpha));
  // TODO(rosswang): This and related affordances are not enough to allow
  // transparent textures to work on opaque materials. It may be worthwhile to
  // surface the |opaque| flag on the Scenic client API to support this.
  escher_material_->set_opaque(alpha == 1);
}

void Material::SetTexture(ImageBasePtr texture_image) {
  texture_ = std::move(texture_image);
}

void Material::UpdateEscherMaterial(escher::BatchGpuUploader* gpu_uploader) {
  // Update our escher::Material if our texture's presented image changed.
  escher::ImagePtr escher_image;
  if (texture_) {
    texture_->UpdateEscherImage(gpu_uploader);
    escher_image = texture_->GetEscherImage();
  }
  const escher::TexturePtr& escher_texture = escher_material_->texture();

  if (!escher_texture || escher_image != escher_texture->image()) {
    escher::TexturePtr texture;
    if (escher_image) {
      auto recycler = session()->resource_context().escher_resource_recycler;
      // TODO(SCN-1403): Technically, eG8B8R82Plane420Unorm is not enough to
      // assume NV12, but it's currently the only format we support at the
      // sampler level.
      if (escher_image->format() == vk::Format::eG8B8R82Plane420Unorm) {
        texture = fxl::MakeRefCounted<escher::Texture>(
            recycler, CreateNV12Sampler(recycler), escher_image);
      } else {
        texture =
            escher::Texture::New(recycler, escher_image, vk::Filter::eLinear);
        // TODO(ES-199, ES-200): Reusing samplers is just good policy, but it is
        // required for immutable samplers because, until these bugs are fixed,
        // Escher will keep these samplers around forever.
        FXL_DCHECK(!texture->sampler()->is_immutable())
            << "Immutable samplers need to be cached to avoid unbounded memory "
               "consumption";
      }
    }
    escher_material_->SetTexture(std::move(texture));
  }
}

}  // namespace gfx
}  // namespace scenic_impl
