// Copyright (c) 2016 The Chromium 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 "cc/output/context_cache_controller.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/synchronization/lock.h"
#include "gpu/command_buffer/client/context_support.h"
#include "third_party/skia/include/gpu/GrContext.h"

namespace cc {
namespace {
static const int kIdleCleanupDelaySeconds = 1;
}  // namespace

ContextCacheController::ScopedToken::ScopedToken() = default;

ContextCacheController::ScopedToken::~ScopedToken() {
  DCHECK(released_);
}

void ContextCacheController::ScopedToken::Release() {
  DCHECK(!released_);
  released_ = true;
}

ContextCacheController::ContextCacheController(
    gpu::ContextSupport* context_support,
    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
    : context_support_(context_support),
      task_runner_(std::move(task_runner)),
      weak_factory_(this) {
  // The |weak_factory_| can only be used from a single thread. We
  // create/destroy this class and run callbacks on a single thread, but we
  // want to be able to post callbacks from multiple threads. We need a weak
  // ptr to post callbacks, so acquire one here, while we're on the right
  // thread.
  weak_ptr_ = weak_factory_.GetWeakPtr();
}

ContextCacheController::~ContextCacheController() = default;

void ContextCacheController::SetGrContext(GrContext* gr_context) {
  gr_context_ = gr_context;
}

void ContextCacheController::SetLock(base::Lock* lock) {
  context_lock_ = lock;
}

std::unique_ptr<ContextCacheController::ScopedVisibility>
ContextCacheController::ClientBecameVisible() {
  if (context_lock_)
    context_lock_->AssertAcquired();

  bool became_visible = num_clients_visible_ == 0;
  ++num_clients_visible_;

  if (became_visible)
    context_support_->SetAggressivelyFreeResources(false);

  return base::WrapUnique(new ScopedVisibility());
}

void ContextCacheController::ClientBecameNotVisible(
    std::unique_ptr<ScopedVisibility> scoped_visibility) {
  DCHECK(scoped_visibility);
  scoped_visibility->Release();

  if (context_lock_)
    context_lock_->AssertAcquired();

  DCHECK_GT(num_clients_visible_, 0u);
  --num_clients_visible_;

  if (num_clients_visible_ == 0) {
    // We are freeing resources now - cancel any pending idle callbacks.
    InvalidatePendingIdleCallbacks();

    if (gr_context_)
      gr_context_->freeGpuResources();
    context_support_->SetAggressivelyFreeResources(true);
  }
}

std::unique_ptr<ContextCacheController::ScopedBusy>
ContextCacheController::ClientBecameBusy() {
  if (context_lock_)
    context_lock_->AssertAcquired();

  ++num_clients_busy_;
  // We are busy, cancel any pending idle callbacks.
  InvalidatePendingIdleCallbacks();

  return base::WrapUnique(new ScopedBusy());
}

void ContextCacheController::ClientBecameNotBusy(
    std::unique_ptr<ScopedBusy> scoped_busy) {
  DCHECK(scoped_busy);
  scoped_busy->Release();

  if (context_lock_)
    context_lock_->AssertAcquired();

  DCHECK_GT(num_clients_busy_, 0u);
  --num_clients_busy_;

  // If we have become idle and we are visible, queue a task to drop resources
  // after a delay. If are not visible, we have already dropped resources.
  if (num_clients_busy_ == 0 && num_clients_visible_ > 0 && task_runner_) {
    // If we already have a callback pending, don't post a new one. The pending
    // callback will handle posting a new callback itself. This prevents us from
    // flooding the system with tasks.
    if (!callback_pending_) {
      {
        base::AutoLock hold(current_idle_generation_lock_);
        PostIdleCallback(current_idle_generation_);
      }
      callback_pending_ = true;
    }
  }
}

void ContextCacheController::PostIdleCallback(
    uint32_t current_idle_generation) const {
  task_runner_->PostDelayedTask(
      FROM_HERE, base::Bind(&ContextCacheController::OnIdle, weak_ptr_,
                            current_idle_generation),
      base::TimeDelta::FromSeconds(kIdleCleanupDelaySeconds));
}

void ContextCacheController::InvalidatePendingIdleCallbacks() {
  base::AutoLock hold(current_idle_generation_lock_);
  ++current_idle_generation_;
}

void ContextCacheController::OnIdle(uint32_t idle_generation) {
  // First check if we should run our idle callback at all. If we have become
  // busy since scheduling, just schedule another idle callback and return.
  {
    base::AutoLock hold(current_idle_generation_lock_);
    if (current_idle_generation_ != idle_generation) {
      PostIdleCallback(current_idle_generation_);
      return;
    }
  }

  // Try to acquire the context lock - if we can't acquire it then we've become
  // busy since checking |current_idle_generation_| above. In this case, just
  // re-post our idle callback and return.
  if (context_lock_ && !context_lock_->Try()) {
    base::AutoLock hold(current_idle_generation_lock_);
    PostIdleCallback(current_idle_generation_);
    return;
  }

  if (gr_context_)
    gr_context_->freeGpuResources();

  // Toggle SetAggressivelyFreeResources to drop command buffer data.
  context_support_->SetAggressivelyFreeResources(true);
  context_support_->SetAggressivelyFreeResources(false);

  callback_pending_ = false;

  if (context_lock_)
    context_lock_->Release();
}

}  // namespace cc
