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 16 namespace cc { 17 18 class TestContextProvider::LostContextCallbackProxy 19 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback { 20 public: 21 explicit LostContextCallbackProxy(TestContextProvider* provider) 22 : provider_(provider) { 23 provider_->context3d_->setContextLostCallback(this); 24 } 25 26 virtual ~LostContextCallbackProxy() { 27 provider_->context3d_->setContextLostCallback(NULL); 28 } 29 30 virtual void onContextLost() { 31 provider_->OnLostContext(); 32 } 33 34 private: 35 TestContextProvider* provider_; 36 }; 37 38 // static 39 scoped_refptr<TestContextProvider> TestContextProvider::Create() { 40 return Create(TestWebGraphicsContext3D::Create().Pass()); 41 } 42 43 // static 44 scoped_refptr<TestContextProvider> TestContextProvider::Create( 45 scoped_ptr<TestWebGraphicsContext3D> context) { 46 if (!context) 47 return NULL; 48 return new TestContextProvider(context.Pass()); 49 } 50 51 TestContextProvider::TestContextProvider( 52 scoped_ptr<TestWebGraphicsContext3D> context) 53 : context3d_(context.Pass()), 54 context_gl_(new TestGLES2Interface(context3d_.get())), 55 bound_(false), 56 destroyed_(false), 57 weak_ptr_factory_(this) { 58 DCHECK(main_thread_checker_.CalledOnValidThread()); 59 DCHECK(context3d_); 60 context_thread_checker_.DetachFromThread(); 61 context3d_->set_test_support(&support_); 62 } 63 64 TestContextProvider::~TestContextProvider() { 65 DCHECK(main_thread_checker_.CalledOnValidThread() || 66 context_thread_checker_.CalledOnValidThread()); 67 } 68 69 bool TestContextProvider::BindToCurrentThread() { 70 // This is called on the thread the context will be used. 71 DCHECK(context_thread_checker_.CalledOnValidThread()); 72 73 if (bound_) 74 return true; 75 76 if (context3d_->isContextLost()) { 77 base::AutoLock lock(destroyed_lock_); 78 destroyed_ = true; 79 return false; 80 } 81 bound_ = true; 82 83 lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this)); 84 85 return true; 86 } 87 88 ContextProvider::Capabilities TestContextProvider::ContextCapabilities() { 89 DCHECK(bound_); 90 DCHECK(context_thread_checker_.CalledOnValidThread()); 91 92 return context3d_->test_capabilities(); 93 } 94 95 blink::WebGraphicsContext3D* TestContextProvider::Context3d() { 96 DCHECK(bound_); 97 DCHECK(context_thread_checker_.CalledOnValidThread()); 98 99 return context3d_.get(); 100 } 101 102 gpu::gles2::GLES2Interface* TestContextProvider::ContextGL() { 103 DCHECK(context3d_); 104 DCHECK(bound_); 105 DCHECK(context_thread_checker_.CalledOnValidThread()); 106 107 return context_gl_.get(); 108 } 109 110 gpu::ContextSupport* TestContextProvider::ContextSupport() { 111 return &support_; 112 } 113 114 class GrContext* TestContextProvider::GrContext() { 115 DCHECK(bound_); 116 DCHECK(context_thread_checker_.CalledOnValidThread()); 117 118 // TODO(danakj): Make a test GrContext that works with a test Context3d. 119 return NULL; 120 } 121 122 void TestContextProvider::MakeGrContextCurrent() {} 123 124 bool TestContextProvider::IsContextLost() { 125 DCHECK(bound_); 126 DCHECK(context_thread_checker_.CalledOnValidThread()); 127 128 return context3d_->isContextLost(); 129 } 130 131 void TestContextProvider::VerifyContexts() { 132 DCHECK(bound_); 133 DCHECK(context_thread_checker_.CalledOnValidThread()); 134 135 if (context3d_->isContextLost()) { 136 base::AutoLock lock(destroyed_lock_); 137 destroyed_ = true; 138 } 139 } 140 141 bool TestContextProvider::DestroyedOnMainThread() { 142 DCHECK(main_thread_checker_.CalledOnValidThread()); 143 144 base::AutoLock lock(destroyed_lock_); 145 return destroyed_; 146 } 147 148 void TestContextProvider::OnLostContext() { 149 DCHECK(context_thread_checker_.CalledOnValidThread()); 150 { 151 base::AutoLock lock(destroyed_lock_); 152 if (destroyed_) 153 return; 154 destroyed_ = true; 155 } 156 if (!lost_context_callback_.is_null()) 157 base::ResetAndReturn(&lost_context_callback_).Run(); 158 } 159 160 TestWebGraphicsContext3D* TestContextProvider::TestContext3d() { 161 DCHECK(bound_); 162 DCHECK(context_thread_checker_.CalledOnValidThread()); 163 164 return context3d_.get(); 165 } 166 167 TestWebGraphicsContext3D* TestContextProvider::UnboundTestContext3d() { 168 return context3d_.get(); 169 } 170 171 void TestContextProvider::SetMemoryAllocation( 172 const ManagedMemoryPolicy& policy) { 173 if (memory_policy_changed_callback_.is_null()) 174 return; 175 memory_policy_changed_callback_.Run(policy); 176 } 177 178 void TestContextProvider::SetLostContextCallback( 179 const LostContextCallback& cb) { 180 DCHECK(context_thread_checker_.CalledOnValidThread()); 181 DCHECK(lost_context_callback_.is_null() || cb.is_null()); 182 lost_context_callback_ = cb; 183 } 184 185 void TestContextProvider::SetMemoryPolicyChangedCallback( 186 const MemoryPolicyChangedCallback& cb) { 187 DCHECK(context_thread_checker_.CalledOnValidThread()); 188 DCHECK(memory_policy_changed_callback_.is_null() || cb.is_null()); 189 memory_policy_changed_callback_ = cb; 190 } 191 192 void TestContextProvider::SetMaxTransferBufferUsageBytes( 193 size_t max_transfer_buffer_usage_bytes) { 194 context3d_->SetMaxTransferBufferUsageBytes(max_transfer_buffer_usage_bytes); 195 } 196 197 } // namespace cc 198