// 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/win32/video_decoder.h"
#include "starboard/thread.h"
#include "starboard/time.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 SbTime kReleaseTimeout = kSbTimeSecond;

// 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.
// 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.
const uint64_t kFrameBuffersPoolMemorySize = 380 * 1024 * 1024;

bool IsExtendedResourceModeRequired() {
  if (!::starboard::xb1::shared::CanAcquire()) {
    return false;
  }
  bool is_erm_required =
      !shared::win32::VideoDecoder::IsHardwareVp9DecoderSupported();
  SB_LOG(INFO) << "Extended resources mode"
               << (is_erm_required ? " is required." : " isn't required.");
  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 SbTime kRetryDelay = kSbTimeSecond / 10;
  for (;;) {
    switch (retrying_acquire ? event_queue_.GetTimed(kRetryDelay)
                             : 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);
}

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_) {
    D3D12_HEAP_DESC heap_desc;
    heap_desc.SizeInBytes = kFrameBuffersPoolMemorySize;
    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 * kSbTimeSecond)) {
      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(kReleaseTimeout)) {
    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
