1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/test/test_context_provider.h"
6
7#include <set>
8#include <vector>
9
10#include "base/bind.h"
11#include "base/callback_helpers.h"
12#include "base/logging.h"
13#include "cc/test/test_gles2_interface.h"
14#include "cc/test/test_web_graphics_context_3d.h"
15
16namespace cc {
17
18// static
19scoped_refptr<TestContextProvider> TestContextProvider::Create() {
20  return Create(TestWebGraphicsContext3D::Create().Pass());
21}
22
23// static
24scoped_refptr<TestContextProvider> TestContextProvider::Create(
25    scoped_ptr<TestWebGraphicsContext3D> context) {
26  if (!context)
27    return NULL;
28  return new TestContextProvider(context.Pass());
29}
30
31TestContextProvider::TestContextProvider(
32    scoped_ptr<TestWebGraphicsContext3D> context)
33    : context3d_(context.Pass()),
34      context_gl_(new TestGLES2Interface(context3d_.get())),
35      bound_(false),
36      destroyed_(false),
37      weak_ptr_factory_(this) {
38  DCHECK(main_thread_checker_.CalledOnValidThread());
39  DCHECK(context3d_);
40  context_thread_checker_.DetachFromThread();
41  context3d_->set_test_support(&support_);
42}
43
44TestContextProvider::~TestContextProvider() {
45  DCHECK(main_thread_checker_.CalledOnValidThread() ||
46         context_thread_checker_.CalledOnValidThread());
47}
48
49bool TestContextProvider::BindToCurrentThread() {
50  // This is called on the thread the context will be used.
51  DCHECK(context_thread_checker_.CalledOnValidThread());
52
53  if (bound_)
54    return true;
55
56  if (context3d_->isContextLost()) {
57    base::AutoLock lock(destroyed_lock_);
58    destroyed_ = true;
59    return false;
60  }
61  bound_ = true;
62
63  context3d_->set_context_lost_callback(
64      base::Bind(&TestContextProvider::OnLostContext,
65                 base::Unretained(this)));
66
67  return true;
68}
69
70ContextProvider::Capabilities TestContextProvider::ContextCapabilities() {
71  DCHECK(bound_);
72  DCHECK(context_thread_checker_.CalledOnValidThread());
73
74  return context3d_->test_capabilities();
75}
76
77gpu::gles2::GLES2Interface* TestContextProvider::ContextGL() {
78  DCHECK(context3d_);
79  DCHECK(bound_);
80  DCHECK(context_thread_checker_.CalledOnValidThread());
81
82  return context_gl_.get();
83}
84
85gpu::ContextSupport* TestContextProvider::ContextSupport() {
86  return &support_;
87}
88
89class GrContext* TestContextProvider::GrContext() {
90  DCHECK(bound_);
91  DCHECK(context_thread_checker_.CalledOnValidThread());
92
93  // TODO(danakj): Make a test GrContext that works with a test Context3d.
94  return NULL;
95}
96
97bool TestContextProvider::IsContextLost() {
98  DCHECK(bound_);
99  DCHECK(context_thread_checker_.CalledOnValidThread());
100
101  return context3d_->isContextLost();
102}
103
104void TestContextProvider::VerifyContexts() {
105  DCHECK(bound_);
106  DCHECK(context_thread_checker_.CalledOnValidThread());
107
108  if (context3d_->isContextLost()) {
109    base::AutoLock lock(destroyed_lock_);
110    destroyed_ = true;
111  }
112}
113
114void TestContextProvider::DeleteCachedResources() {
115}
116
117bool TestContextProvider::DestroyedOnMainThread() {
118  DCHECK(main_thread_checker_.CalledOnValidThread());
119
120  base::AutoLock lock(destroyed_lock_);
121  return destroyed_;
122}
123
124void TestContextProvider::OnLostContext() {
125  DCHECK(context_thread_checker_.CalledOnValidThread());
126  {
127    base::AutoLock lock(destroyed_lock_);
128    if (destroyed_)
129      return;
130    destroyed_ = true;
131  }
132  if (!lost_context_callback_.is_null())
133    base::ResetAndReturn(&lost_context_callback_).Run();
134}
135
136TestWebGraphicsContext3D* TestContextProvider::TestContext3d() {
137  DCHECK(bound_);
138  DCHECK(context_thread_checker_.CalledOnValidThread());
139
140  return context3d_.get();
141}
142
143TestWebGraphicsContext3D* TestContextProvider::UnboundTestContext3d() {
144  return context3d_.get();
145}
146
147void TestContextProvider::SetMemoryAllocation(
148    const ManagedMemoryPolicy& policy) {
149  if (memory_policy_changed_callback_.is_null())
150    return;
151  memory_policy_changed_callback_.Run(policy);
152}
153
154void TestContextProvider::SetLostContextCallback(
155    const LostContextCallback& cb) {
156  DCHECK(context_thread_checker_.CalledOnValidThread());
157  DCHECK(lost_context_callback_.is_null() || cb.is_null());
158  lost_context_callback_ = cb;
159}
160
161void TestContextProvider::SetMemoryPolicyChangedCallback(
162    const MemoryPolicyChangedCallback& cb) {
163  DCHECK(context_thread_checker_.CalledOnValidThread());
164  DCHECK(memory_policy_changed_callback_.is_null() || cb.is_null());
165  memory_policy_changed_callback_ = cb;
166}
167
168void TestContextProvider::SetMaxTransferBufferUsageBytes(
169    size_t max_transfer_buffer_usage_bytes) {
170  context3d_->SetMaxTransferBufferUsageBytes(max_transfer_buffer_usage_bytes);
171}
172
173}  // namespace cc
174