// Copyright 2013 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/test/test_context_provider.h"

#include <set>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "cc/test/test_gles2_interface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/gl/SkNullGLContext.h"

namespace cc {

// static
scoped_refptr<TestContextProvider> TestContextProvider::Create() {
  return Create(TestWebGraphicsContext3D::Create().Pass());
}

// static
scoped_refptr<TestContextProvider> TestContextProvider::Create(
    scoped_ptr<TestWebGraphicsContext3D> context) {
  if (!context)
    return NULL;
  return new TestContextProvider(context.Pass());
}

TestContextProvider::TestContextProvider(
    scoped_ptr<TestWebGraphicsContext3D> context)
    : context3d_(context.Pass()),
      context_gl_(new TestGLES2Interface(context3d_.get())),
      bound_(false),
      destroyed_(false),
      weak_ptr_factory_(this) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DCHECK(context3d_);
  context_thread_checker_.DetachFromThread();
  context3d_->set_test_support(&support_);
}

TestContextProvider::~TestContextProvider() {
  DCHECK(main_thread_checker_.CalledOnValidThread() ||
         context_thread_checker_.CalledOnValidThread());
}

bool TestContextProvider::BindToCurrentThread() {
  // This is called on the thread the context will be used.
  DCHECK(context_thread_checker_.CalledOnValidThread());

  if (bound_)
    return true;

  if (context3d_->isContextLost()) {
    base::AutoLock lock(destroyed_lock_);
    destroyed_ = true;
    return false;
  }
  bound_ = true;

  context3d_->set_context_lost_callback(
      base::Bind(&TestContextProvider::OnLostContext,
                 base::Unretained(this)));

  return true;
}

void TestContextProvider::DetachFromThread() {
  context_thread_checker_.DetachFromThread();
}

ContextProvider::Capabilities TestContextProvider::ContextCapabilities() {
  DCHECK(bound_);
  DCHECK(context_thread_checker_.CalledOnValidThread());

  return context3d_->test_capabilities();
}

gpu::gles2::GLES2Interface* TestContextProvider::ContextGL() {
  DCHECK(context3d_);
  DCHECK(bound_);
  DCHECK(context_thread_checker_.CalledOnValidThread());

  return context_gl_.get();
}

gpu::ContextSupport* TestContextProvider::ContextSupport() {
  return &support_;
}

class GrContext* TestContextProvider::GrContext() {
  DCHECK(bound_);
  DCHECK(context_thread_checker_.CalledOnValidThread());

  if (gr_context_)
    return gr_context_.get();

  skia::RefPtr<class SkGLContext> gl_context =
      skia::AdoptRef(SkNullGLContext::Create(kNone_GrGLStandard));
  gl_context->makeCurrent();
  gr_context_ = skia::AdoptRef(GrContext::Create(
      kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(gl_context->gl())));

  // If GlContext is already lost, also abandon the new GrContext.
  if (IsContextLost())
    gr_context_->abandonContext();

  return gr_context_.get();
}

void TestContextProvider::SetupLock() {
}

base::Lock* TestContextProvider::GetLock() {
  return &context_lock_;
}

bool TestContextProvider::IsContextLost() {
  DCHECK(bound_);
  DCHECK(context_thread_checker_.CalledOnValidThread());

  return context3d_->isContextLost();
}

void TestContextProvider::VerifyContexts() {
  DCHECK(bound_);
  DCHECK(context_thread_checker_.CalledOnValidThread());

  if (context3d_->isContextLost()) {
    base::AutoLock lock(destroyed_lock_);
    destroyed_ = true;
  }
}

void TestContextProvider::DeleteCachedResources() {
}

bool TestContextProvider::DestroyedOnMainThread() {
  DCHECK(main_thread_checker_.CalledOnValidThread());

  base::AutoLock lock(destroyed_lock_);
  return destroyed_;
}

void TestContextProvider::OnLostContext() {
  DCHECK(context_thread_checker_.CalledOnValidThread());
  {
    base::AutoLock lock(destroyed_lock_);
    if (destroyed_)
      return;
    destroyed_ = true;
  }
  if (!lost_context_callback_.is_null())
    base::ResetAndReturn(&lost_context_callback_).Run();
  if (gr_context_)
    gr_context_->abandonContext();
}

TestWebGraphicsContext3D* TestContextProvider::TestContext3d() {
  DCHECK(bound_);
  DCHECK(context_thread_checker_.CalledOnValidThread());

  return context3d_.get();
}

TestWebGraphicsContext3D* TestContextProvider::UnboundTestContext3d() {
  return context3d_.get();
}

void TestContextProvider::SetMemoryAllocation(
    const ManagedMemoryPolicy& policy) {
  if (memory_policy_changed_callback_.is_null())
    return;
  memory_policy_changed_callback_.Run(policy);
}

void TestContextProvider::SetLostContextCallback(
    const LostContextCallback& cb) {
  DCHECK(context_thread_checker_.CalledOnValidThread());
  DCHECK(lost_context_callback_.is_null() || cb.is_null());
  lost_context_callback_ = cb;
}

void TestContextProvider::SetMemoryPolicyChangedCallback(
    const MemoryPolicyChangedCallback& cb) {
  DCHECK(context_thread_checker_.CalledOnValidThread());
  DCHECK(memory_policy_changed_callback_.is_null() || cb.is_null());
  memory_policy_changed_callback_ = cb;
}

void TestContextProvider::SetMaxTransferBufferUsageBytes(
    size_t max_transfer_buffer_usage_bytes) {
  context3d_->SetMaxTransferBufferUsageBytes(max_transfer_buffer_usage_bytes);
}

}  // namespace cc
