// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/uwp/extended_resources_manager.h"

#include <ppltasks.h>

#include "starboard/common/condition_variable.h"
#include "starboard/common/semaphore.h"
#include "starboard/common/string.h"
#include "starboard/shared/starboard/application.h"
#include "starboard/shared/starboard/media/mime_supportability_cache.h"
#include "starboard/shared/uwp/xb1_get_type.h"
#include "starboard/shared/win32/video_decoder.h"
#include "starboard/thread.h"
#include "starboard/xb1/shared/internal_shims.h"
#if defined(INTERNAL_BUILD)
#include "internal/starboard/xb1/dav1d_video_decoder.h"
#include "internal/starboard/xb1/vpx_video_decoder.h"
#include "third_party/internal/libvpx_xb1/libvpx/d3dx12.h"
#endif  // defined(INTERNAL_BUILD)

namespace starboard {
namespace shared {
namespace uwp {

namespace {

using Microsoft::WRL::ComPtr;
using ::starboard::shared::starboard::media::MimeSupportabilityCache;
using Windows::Foundation::Metadata::ApiInformation;
#if defined(INTERNAL_BUILD)
using ::starboard::xb1::shared::Dav1dVideoDecoder;
using ::starboard::xb1::shared::GpuVideoDecoderBase;
using ::starboard::xb1::shared::VpxVideoDecoder;
#endif  // defined(INTERNAL_BUILD)

const int64_t kReleaseTimeoutUsec = 1'000'000;

// kFrameBuffersPoolMemorySize is the size of gpu memory heap for common use
// by vpx & av1 sw decoders.
// This value must be greater then max(av1_min_value, vpx_min_value), where
// av1_min_value & vpx_min_value are minimal required memory size for sw av1 &
// vpx decoders.
//
// Vpx sw decoder needs 13 internal frame buffers for work and at least
// 8 buffers for preroll.
// The size of fb is 13762560 for 4K SDR and 12976128 for 2K HDR
// So, vpx decoder needs minimum  13762560 * (13 + preroll_size) = 289013760
// bytes.
//
// Av1 sw decoder needs 13 internal buffers and 8 buffers for preroll.
// The size of fb is 5996544 for 2K SDR and 11993088 for 2K HDR
// av1 decoder needs minimum  11993088 * (13 + preroll_size) = 251854848 bytes.
//
// So, the value 289013760 is minimal for reliable decoders working.
//
// To make playback more smooth it is better to increase the output queue size
// up to 30-50 frames, but it should not exceed memory budgetd.
// Compromise value was found out experimentally.
// In XBOX ONE S/Base 400 Mb leaves enough memory for stable working of the rest
// system. Just in case to be more sure we reduce this value down to 380 Mb. In
// Sereies devices (if to use gpu based decoders) the max available frame size
// size is 4K instead of 2K. On the other hand the memory budget is greater than
// for Base/S. So we can use more memory for output queue.
const uint64_t kFrameBuffersPoolMemorySizeForXB1 = 380 * 1024 * 1024;
// +8 extra frames 4K HDR DXGI_FORMAT_R10G10B10A2_UNORM
const uint64_t kFrameBuffersPoolMemorySizeForXBSeries =
    kFrameBuffersPoolMemorySizeForXB1 + 8 * 16588800;

bool IsExtendedResourceModeRequired() {
  if (!::starboard::xb1::shared::CanAcquire()) {
    return false;
  }
  // erm is required for all xbox types except kXboxOneX;
  bool is_erm_required = ::starboard::shared::uwp::GetXboxType() !=
                         ::starboard::shared::uwp::kXboxOneX;
  return is_erm_required;
}

}  // namespace

// static
ExtendedResourcesManager* ExtendedResourcesManager::s_instance_;

ExtendedResourcesManager::ExtendedResourcesManager()
    : acquisition_condition_(mutex_) {
  SB_DCHECK(!s_instance_);
  s_instance_ = this;
}

ExtendedResourcesManager::~ExtendedResourcesManager() {
  SB_DCHECK(s_instance_ == this);
  s_instance_ = NULL;
}

// static
ExtendedResourcesManager* ExtendedResourcesManager::GetInstance() {
  return s_instance_;
}

void ExtendedResourcesManager::Run() {
  SB_DCHECK(thread_checker_.CalledOnValidThread());

  if (!IsExtendedResourceModeRequired()) {
    // Running a simplified loop that only cares about the kQuit event.
    while (event_queue_.Get() != kQuit) {
    }
    return;
  }

  bool retrying_acquire = false;
  // Delay before retry acquiring to avoid pinning a core.
  constexpr int64_t kRetryDelayUsec = 1'000'000 / 10;
  for (;;) {
    switch (retrying_acquire ? event_queue_.GetTimed(kRetryDelayUsec)
                             : event_queue_.Get()) {
      case kTimeout:
        SB_DCHECK(retrying_acquire);
      // Fall through to acquire extended resources.
      case kAcquireExtendedResources:
        retrying_acquire = !AcquireExtendedResourcesInternal();
        if (!retrying_acquire) {
          retrying_acquire = !StartCompileShaders();
        }
        break;
      case kCompileShaders:
        CompileShadersAsynchronously();
        break;
      case kReleaseExtendedResources:
        retrying_acquire = false;
        ReleaseExtendedResourcesInternal();
        break;
      case kQuit:
        retrying_acquire = false;
        ReleaseExtendedResourcesInternal();
        return;
    }
  }
}

void ExtendedResourcesManager::AcquireExtendedResources() {
  // This is expected to be called from another thread only.
  SB_DCHECK(!thread_checker_.CalledOnValidThread());
  event_queue_.Put(kAcquireExtendedResources);
}

void ExtendedResourcesManager::ReleaseExtendedResources() {
  // This is expected to be called from another thread only. If called from the
  // worker thread, it can deadlock on the mutex below.
  SB_DCHECK(!thread_checker_.CalledOnValidThread());
  event_queue_.Put(kReleaseExtendedResources);

  // Skip any pending extended resources acquisitions.
  pending_extended_resources_release_.store(true);
  {
    // Wait until we successfully release the extended resources or timeout.
    ScopedLock scoped_lock(mutex_);
    while (is_extended_resources_acquired_.load()) {
      acquisition_condition_.Wait();
    }
  }
}

void ExtendedResourcesManager::Quit() {
  SB_DCHECK(!thread_checker_.CalledOnValidThread());
  event_queue_.Put(kQuit);
  pending_extended_resources_release_.store(true);
}

void ExtendedResourcesManager::ReleaseBuffersHeap() {
  d3d12FrameBuffersHeap_.Reset();
}

bool ExtendedResourcesManager::GetD3D12Objects(
    Microsoft::WRL::ComPtr<ID3D12Device>* device,
    Microsoft::WRL::ComPtr<ID3D12Heap>* buffer_heap,
    void** command_queue) {
  if (HasNonrecoverableFailure()) {
    SB_LOG(WARNING) << "The D3D12 device has encountered a nonrecoverable "
                       "failure.";
    return false;
  }

  device->Reset();
  *command_queue = nullptr;

  ScopedTryLock scoped_lock(mutex_);
  if (!scoped_lock.is_locked()) {
    SB_LOG(INFO) << "GetD3D12Objects() failed"
                 << " because lock cannot be acquired.";
    return false;
  }
  if (!is_extended_resources_acquired_.load()) {
    SB_LOG(INFO) << "GetD3D12Objects() failed"
                 << " because extended resources mode is not acquired.";
    return false;
  }
  if (!GetD3D12ObjectsInternal()) {
    SB_LOG(INFO) << "GetD3D12Objects() failed"
                 << " because d3d12 objects can not be created.";
    return false;
  }

#if defined(INTERNAL_BUILD)
  // Verify that we can allocate one MB without getting an error. This should
  // detect a DXGI_ERROR_DEVICE_REMOVED failure mode.
  ComPtr<ID3D12Resource> res;
  D3D12_HEAP_PROPERTIES prop = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
  D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Buffer(1024 * 1024);
  HRESULT result = d3d12device_->CreateCommittedResource(
      &prop, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COMMON, nullptr,
      IID_PPV_ARGS(&res));
  if (result != S_OK) {
    SB_LOG(WARNING) << "The D3D12 device is not in a good state, can not use "
                       "GPU based decoders.";
    OnNonrecoverableFailure();
    return false;
  }
#endif  // defined(INTERNAL_BUILD)

  *device = d3d12device_;
  *command_queue = d3d12queue_.Get();
  *buffer_heap = d3d12FrameBuffersHeap_.Get();
  return true;
}

bool ExtendedResourcesManager::GetD3D12ObjectsInternal() {
  if (!d3d12device_) {
    UINT dxgiFactoryFlags = 0;
#if defined(_DEBUG)
    {
      // This can help to debug DX issues. If something goes wrong in DX,
      // Debug Layer outputs detailed log
      ComPtr<ID3D12Debug> debugController;
      HRESULT hr = D3D12GetDebugInterface(IID_PPV_ARGS(&debugController));
      if (SUCCEEDED(hr)) {
        debugController->EnableDebugLayer();
      }
    }
#endif

    if (FAILED(D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0,
                                 IID_PPV_ARGS(&d3d12device_)))) {
      // GPU based vp9 decoding will be temporarily disabled.
      SB_LOG(WARNING) << "Failed to create d3d12 device.";
      return false;
    }
    SB_DCHECK(d3d12device_);
  }

  if (!d3d12queue_) {
    D3D12_COMMAND_QUEUE_DESC desc = {};
    desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
    if (FAILED(d3d12device_->CreateCommandQueue(&desc,
                                                IID_PPV_ARGS(&d3d12queue_)))) {
      SB_LOG(WARNING) << "Failed to create d3d12 command queue.";
      return false;
    }
    SB_DCHECK(d3d12queue_);
  }
  if (!d3d12FrameBuffersHeap_) {
    const bool isSeries = ::starboard::shared::uwp::GetXboxType() ==
                              ::starboard::shared::uwp::kXboxSeriesS ||
                          ::starboard::shared::uwp::GetXboxType() ==
                              ::starboard::shared::uwp::kXboxSeriesX;
    D3D12_HEAP_DESC heap_desc;
    heap_desc.SizeInBytes = isSeries ? kFrameBuffersPoolMemorySizeForXBSeries
                                     : kFrameBuffersPoolMemorySizeForXB1;
    heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
    heap_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
    heap_desc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
    heap_desc.Properties.CreationNodeMask = 0;
    heap_desc.Properties.VisibleNodeMask = 0;
    heap_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
    heap_desc.Flags = D3D12_HEAP_FLAG_NONE;

    if (FAILED(d3d12device_->CreateHeap(
            &heap_desc, IID_PPV_ARGS(&d3d12FrameBuffersHeap_)))) {
      SB_LOG(WARNING) << "Failed to create d3d12 buffer.";
      return false;
    }
    SB_DCHECK(d3d12FrameBuffersHeap_);
  }

  return d3d12device_ && d3d12queue_ && d3d12FrameBuffersHeap_;
}

bool ExtendedResourcesManager::AcquireExtendedResourcesInternal() {
  SB_DCHECK(thread_checker_.CalledOnValidThread());

  ScopedLock scoped_lock(mutex_);

  if (HasNonrecoverableFailure()) {
    SB_LOG(WARNING)
        << "Encountered a nonrecoverable failure, ignoring acquire.";
    return false;
  }

  if (is_extended_resources_acquired_.load()) {
    SB_LOG(INFO) << "Skip acquiring extended resources, already acquired.";
  } else {
    if (pending_extended_resources_release_.load()) {
      SB_LOG(INFO) << "AcquireExtendedResourcesInternal() interrupted"
                      " by pending extended resources release.";
      return false;
    }
    auto extended_resources_mode_enable_task =
        concurrency::create_task(::starboard::xb1::shared::Acquire());

    Semaphore semaphore;
    extended_resources_mode_enable_task.then(
        [this, &semaphore](concurrency::task<bool> task) {
          try {
            if (task.get()) {
              is_extended_resources_acquired_.store(true);
              acquisition_condition_.Signal();
              SB_LOG(INFO) << "Successfully acquired extended resources.";
            } else {
              // TODO: Investigate if vp9 playback should be disabled.
              SB_LOG(INFO) << "Failed to acquire extended resources.";
            }
          } catch (const std::exception& e) {
            SB_LOG(ERROR) << "Exception on acquiring extended resources: "
                          << e.what();
          } catch (...) {
            SB_LOG(ERROR) << "Exception on acquiring extended resources.";
          }
          semaphore.Put();
        });
    if (semaphore.TakeWait(10'000'000)) {
      acquisition_condition_.Signal();
      // If extended resource acquisition was not successful after the wait
      // time, signal a nonrecoverable failure, unless a release of
      // extended resources has since been requested.
      if (!is_extended_resources_acquired_.load() &&
          !pending_extended_resources_release_.load()) {
        SB_LOG(WARNING) << "Extended resource mode acquisition timed out";
        OnNonrecoverableFailure();
      }
    }
  }

  if (!is_extended_resources_acquired_.load()) {
    SB_LOG(INFO) << "AcquireExtendedResourcesInternal() failed.";
    return false;
  }
  return is_extended_resources_acquired_.load();
}

bool ExtendedResourcesManager::StartCompileShaders() {
  {
    ScopedLock scoped_lock(mutex_);
    if (HasNonrecoverableFailure()) {
      SB_LOG(WARNING)
          << "Encountered a nonrecoverable failure, ignoring shader compile.";
      return false;
    }
    if (pending_extended_resources_release_.load()) {
      SB_LOG(INFO) << "StartCompileShaders() interrupted"
                      " by pending extended resources release.";
      return false;
    }
    if (!is_extended_resources_acquired_.load()) {
      SB_LOG(INFO) << "StartCompileShaders() failed"
                      " because extended resources are not acquired.";
      return false;
    }
    if (!GetD3D12ObjectsInternal()) {
      SB_LOG(INFO) << "StartCompileShaders() failed"
                   << " because d3d12 objects can not be created.";
      return false;
    }
  }
  // Everything is ready to give a command for shaders compilation.
  // Note: once we returned "true" execution will not go here anymore to queue
  // an event to compile shaders again.
  event_queue_.Put(kCompileShaders);
  return true;
}

void ExtendedResourcesManager::CompileShadersAsynchronously() {
  // Shaders compilation may take several seconds that is why it is good to run
  // it asynchronously. We may not wait until its compilation is completed and
  // synchronize decoding with it. If real playback will start earlier than this
  // compilation completed then the decoder will compile shaders before playback
  // and they will be placed in cache as binaries for further reusing.
  Concurrency::create_task([this] {
    ScopedLock scoped_lock(mutex_);
#if defined(INTERNAL_BUILD)
    SB_LOG(INFO) << "Start to compile AV1 decoder shaders.";
    SB_DCHECK(!is_av1_shader_compiled_)
        << "Unexpected attempt to recompile AV1 decoder shaders.";
    if (HasNonrecoverableFailure()) {
      SB_LOG(WARNING) << "Encountered a nonrecoverable failure, ignoring "
                         "shader compile.";
      return;
    }
    if (Dav1dVideoDecoder::CompileShaders(d3d12device_)) {
      is_av1_shader_compiled_ = true;
      SB_LOG(INFO) << "Gpu based AV1 decoder finished compiling its shaders.";
    } else {
      SB_LOG(WARNING) << "Failed to compile AV1 decoder shaders, next attempt "
                         "will happen right on the AV1 decoder instantiation.";
    }

    SB_LOG(INFO) << "Start to compile VP9 decoder shaders.";
    SB_DCHECK(!is_vp9_shader_compiled_)
        << "Unexpected attempt to recompile VP9 decoder shaders";
    if (HasNonrecoverableFailure()) {
      SB_LOG(WARNING) << "Encountered a nonrecoverable failure, ignoring "
                         "shader compile.";
      return;
    }

    if (VpxVideoDecoder::CompileShaders(d3d12device_, d3d12FrameBuffersHeap_,
                                        d3d12queue_.Get())) {
      is_vp9_shader_compiled_ = true;
      SB_LOG(INFO) << "Gpu based VP9 decoder finished compiling its shaders.";
    } else {
      // This warning means that not all the shaders has been compiled
      // successfully, It will try to compile the shaders again, right before
      // the start of playback, in function |VideoDecoder::InitializeCodec()|.
      SB_LOG(WARNING) << "Failed to compile VP9 decoder shaders, next attempt "
                         "will happen right on the VP9 decoder instantiation.";
    }
#endif  // defined(INTERNAL_BUILD)

    if (is_av1_shader_compiled_ && is_vp9_shader_compiled_) {
      MimeSupportabilityCache::GetInstance()->ClearCachedMimeSupportabilities();
    }
  });
}

void ExtendedResourcesManager::ReleaseExtendedResourcesInternal() {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  ScopedLock scoped_lock(mutex_);
  if (!is_extended_resources_acquired_.load()) {
    SB_LOG(INFO) << "Extended resources hasn't been acquired,"
                 << " no need to release.";
    return;
  }

  try {
    // Wait until all commands on the queue has been finished.
    if (d3d12device_ && d3d12queue_) {
      ComPtr<ID3D12Fence> fence;
      HRESULT hr = d3d12device_->CreateFence(0, D3D12_FENCE_FLAG_NONE,
                                             IID_PPV_ARGS(&fence));
      if (SUCCEEDED(hr)) {
        HANDLE event = CreateEvent(nullptr, false, false, nullptr);
        SB_DCHECK(event);

        // If createEvent() succeeds, we can use it to wait for the command
        // queue to complete.
        if (event) {
          fence->SetEventOnCompletion(1, event);
          d3d12queue_->Signal(fence.Get(), 1);

          DWORD result =
              WaitForSingleObject(event, 1000);  // Wait at most one second
          CloseHandle(event);
          if (result == WAIT_TIMEOUT) {
            SB_LOG(WARNING) << "Fence event completion timeout.";
            OnNonrecoverableFailure();
          }
        } else {
          SB_LOG(INFO) << "CreateEvent() failed with " << GetLastError();
        }
#if defined(INTERNAL_BUILD)
        Dav1dVideoDecoder::ReleaseShaders();
        VpxVideoDecoder::ReleaseShaders();
#endif  // #if defined(INTERNAL_BUILD)
        is_av1_shader_compiled_ = false;
        is_vp9_shader_compiled_ = false;
      } else {
        SB_LOG(INFO) << "CreateFence() failed with " << hr;
      }
#if defined(INTERNAL_BUILD)
      // Clear frame buffers used for rendering queue
      GpuVideoDecoderBase::ClearFrameBuffersPool();
#endif  // #if defined(INTERNAL_BUILD)
    }

    if (d3d12queue_) {
#if !defined(COBALT_BUILD_TYPE_GOLD)
      d3d12queue_->AddRef();
      ULONG reference_count = d3d12queue_->Release();
      SB_LOG(INFO) << "Reference count of |d3d12queue_| is " << reference_count;
#endif
      d3d12queue_.Reset();
    }

    if (d3d12FrameBuffersHeap_) {
#if !defined(COBALT_BUILD_TYPE_GOLD)
      d3d12FrameBuffersHeap_->AddRef();
      ULONG reference_count = d3d12FrameBuffersHeap_->Release();
      SB_LOG(INFO) << "Reference count of |d3d12FrameBuffersHeap_| is "
                   << reference_count;
#endif
      d3d12FrameBuffersHeap_.Reset();
    }

    if (d3d12device_) {
#if !defined(COBALT_BUILD_TYPE_GOLD)
      d3d12device_->AddRef();
      ULONG reference_count = d3d12device_->Release();
      SB_LOG(INFO) << "Reference count of |d3d12device_| is "
                   << reference_count;
#endif
      d3d12device_.Reset();
    }

  } catch (const std::exception& e) {
    SB_LOG(ERROR) << "Exception on releasing extended resources: " << e.what();
    OnNonrecoverableFailure();
  } catch (...) {
    SB_LOG(ERROR) << "Exception on releasing extended resources.";
    OnNonrecoverableFailure();
  }

  auto extended_resources_mode_disable_task =
      concurrency::create_task([] { ::starboard::xb1::shared::Release(); });

  Semaphore semaphore;
  extended_resources_mode_disable_task.then(
      [this, &semaphore](concurrency::task<void> task) {
        try {
          acquisition_condition_.Signal();
          // ReleaseExtendedResources has no return value but a call to get()
          // will bubble up any exceptions thrown during the task.
          task.get();
          SB_LOG(INFO) << "Released extended resources.";
        } catch (const std::exception& e) {
          SB_LOG(ERROR) << "Exception on releasing extended resources: "
                        << e.what();
          OnNonrecoverableFailure();
        } catch (...) {
          SB_LOG(ERROR) << "Exception on releasing extended resources.";
          OnNonrecoverableFailure();
        }
        is_extended_resources_acquired_.store(false);
        pending_extended_resources_release_.store(false);
        semaphore.Put();
      });
  if (!semaphore.TakeWait(kReleaseTimeoutUsec)) {
    acquisition_condition_.Signal();
    // If extended resources are still acquired or the release is still pending
    // after the wait time, signal a nonrecoverable failure.
    if (is_extended_resources_acquired_.load() ||
        pending_extended_resources_release_.load()) {
      SB_LOG(WARNING) << "Extended resource mode release timed out";
      OnNonrecoverableFailure();
    }
    is_extended_resources_acquired_.store(false);
    pending_extended_resources_release_.store(false);
  }
}

}  // namespace uwp
}  // namespace shared
}  // namespace starboard
