// 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 "flutter/shell/common/shell_io_manager.h"

#include <utility>

#include "flutter/fml/message_loop.h"
#include "flutter/shell/common/context_options.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"

namespace flutter {

sk_sp<GrDirectContext> ShellIOManager::CreateCompatibleResourceLoadingContext(
    GrBackend backend,
    sk_sp<const GrGLInterface> gl_interface) {
#if SK_GL
  if (backend != GrBackend::kOpenGL_GrBackend) {
    return nullptr;
  }

  const auto options = MakeDefaultContextOptions(ContextType::kResource);

  if (auto context =
          GrDirectContext::MakeGL(std::move(gl_interface), options)) {
    // Do not cache textures created by the image decoder.  These textures
    // should be deleted when they are no longer referenced by an SkImage.
    context->setResourceCacheLimit(0);
    return context;
  }
#endif  // SK_GL

  return nullptr;
}

ShellIOManager::ShellIOManager(
    sk_sp<GrDirectContext> resource_context,
    std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
    fml::RefPtr<fml::TaskRunner> unref_queue_task_runner,
    std::shared_ptr<impeller::Context> impeller_context,
    fml::TimeDelta unref_queue_drain_delay)
    : resource_context_(std::move(resource_context)),
      resource_context_weak_factory_(
          resource_context_
              ? std::make_unique<fml::WeakPtrFactory<GrDirectContext>>(
                    resource_context_.get())
              : nullptr),
      unref_queue_(fml::MakeRefCounted<flutter::SkiaUnrefQueue>(
          std::move(unref_queue_task_runner),
          unref_queue_drain_delay,
          resource_context_)),
      is_gpu_disabled_sync_switch_(std::move(is_gpu_disabled_sync_switch)),
      impeller_context_(std::move(impeller_context)),
      weak_factory_(this) {
  if (!resource_context_) {
#ifndef OS_FUCHSIA
    FML_DLOG(WARNING) << "The IO manager was initialized without a resource "
                         "context. Async texture uploads will be disabled. "
                         "Expect performance degradation.";
#endif  // OS_FUCHSIA
  }
}

ShellIOManager::~ShellIOManager() {
  // Last chance to drain the IO queue as the platform side reference to the
  // underlying OpenGL context may be going away.
  is_gpu_disabled_sync_switch_->Execute(
      fml::SyncSwitch::Handlers().SetIfFalse([&] { unref_queue_->Drain(); }));
}

void ShellIOManager::NotifyResourceContextAvailable(
    sk_sp<GrDirectContext> resource_context) {
  // The resource context needs to survive as long as we have Dart objects
  // referencing. We shouldn't ever need to replace it if we have one - unless
  // we've somehow shut down the Dart VM and started a new one fresh.
  if (!resource_context_) {
    UpdateResourceContext(std::move(resource_context));
  }
}

void ShellIOManager::UpdateResourceContext(
    sk_sp<GrDirectContext> resource_context) {
  resource_context_ = std::move(resource_context);
  resource_context_weak_factory_ =
      resource_context_
          ? std::make_unique<fml::WeakPtrFactory<GrDirectContext>>(
                resource_context_.get())
          : nullptr;
  unref_queue_->UpdateResourceContext(resource_context_);
}

fml::WeakPtr<ShellIOManager> ShellIOManager::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

// |IOManager|
fml::WeakPtr<GrDirectContext> ShellIOManager::GetResourceContext() const {
  return resource_context_weak_factory_
             ? resource_context_weak_factory_->GetWeakPtr()
             : fml::WeakPtr<GrDirectContext>();
}

// |IOManager|
fml::RefPtr<flutter::SkiaUnrefQueue> ShellIOManager::GetSkiaUnrefQueue() const {
  return unref_queue_;
}

// |IOManager|
fml::WeakPtr<IOManager> ShellIOManager::GetWeakIOManager() const {
  return weak_factory_.GetWeakPtr();
}

// |IOManager|
std::shared_ptr<const fml::SyncSwitch>
ShellIOManager::GetIsGpuDisabledSyncSwitch() {
  return is_gpu_disabled_sync_switch_;
}

// |IOManager|
std::shared_ptr<impeller::Context> ShellIOManager::GetImpellerContext() const {
  return impeller_context_;
}

}  // namespace flutter
