Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 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 "ui/compositor/test/in_process_context_provider.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/callback_helpers.h" | |
| 9 #include "base/debug/trace_event.h" | |
| 10 #include "base/lazy_instance.h" | |
| 11 #include "base/strings/stringprintf.h" | |
| 12 #include "cc/output/managed_memory_policy.h" | |
| 13 #include "gpu/command_buffer/client/gl_in_process_context.h" | |
| 14 #include "gpu/command_buffer/client/gles2_implementation.h" | |
| 15 #include "gpu/command_buffer/client/gles2_lib.h" | |
| 16 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" | |
| 17 #include "third_party/skia/include/gpu/GrContext.h" | |
| 18 #include "third_party/skia/include/gpu/gl/GrGLInterface.h" | |
| 19 | |
| 20 namespace ui { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 //const int kNoLimit = 0; | |
|
jamesr
2015/01/21 21:39:05
delete
tfarina
2015/01/21 21:53:35
Done.
| |
| 25 | |
| 26 // Singleton used to initialize and terminate the gles2 library. | |
| 27 class GLES2Initializer { | |
| 28 public: | |
| 29 GLES2Initializer() { gles2::Initialize(); } | |
| 30 | |
| 31 ~GLES2Initializer() { gles2::Terminate(); } | |
| 32 | |
| 33 private: | |
| 34 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer); | |
| 35 }; | |
| 36 | |
| 37 void ConvertAttributes( | |
| 38 const blink::WebGraphicsContext3D::Attributes& attributes, | |
| 39 gpu::gles2::ContextCreationAttribHelper* output_attribs) { | |
| 40 output_attribs->alpha_size = attributes.alpha ? 8 : 0; | |
| 41 output_attribs->depth_size = attributes.depth ? 24 : 0; | |
| 42 output_attribs->stencil_size = attributes.stencil ? 8 : 0; | |
| 43 output_attribs->samples = attributes.antialias ? 4 : 0; | |
| 44 output_attribs->sample_buffers = attributes.antialias ? 1 : 0; | |
| 45 output_attribs->fail_if_major_perf_caveat = | |
| 46 attributes.failIfMajorPerformanceCaveat; | |
| 47 output_attribs->bind_generates_resource = false; | |
| 48 } | |
| 49 | |
| 50 base::LazyInstance<GLES2Initializer> g_gles2_initializer = | |
| 51 LAZY_INSTANCE_INITIALIZER; | |
| 52 | |
| 53 } // namespace | |
| 54 | |
| 55 class InProcessContextProvider::LostContextCallbackProxy | |
|
jamesr
2015/01/21 21:39:05
delete this class, you don't need it
tfarina
2015/01/21 21:53:35
Done.
| |
| 56 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback { | |
| 57 public: | |
| 58 explicit LostContextCallbackProxy(InProcessContextProvider* provider) | |
| 59 : provider_(provider) { | |
| 60 //provider_->context3d_->setContextLostCallback(this); | |
| 61 } | |
| 62 | |
| 63 virtual ~LostContextCallbackProxy() { | |
| 64 //provider_->context3d_->setContextLostCallback(NULL); | |
| 65 } | |
| 66 | |
| 67 virtual void onContextLost() { | |
| 68 provider_->OnLostContext(); | |
| 69 } | |
| 70 | |
| 71 private: | |
| 72 InProcessContextProvider* provider_; | |
| 73 }; | |
| 74 | |
| 75 // static | |
| 76 scoped_refptr<InProcessContextProvider> InProcessContextProvider::Create( | |
| 77 const blink::WebGraphicsContext3D::Attributes& attributes, | |
|
jamesr
2015/01/21 21:39:05
don't use this type. are there any attributes that
tfarina
2015/01/21 21:53:35
I don't know how to answer that yet. I'm thinking
| |
| 78 bool lose_context_when_out_of_memory, | |
| 79 gfx::AcceleratedWidget window, | |
| 80 const std::string& debug_name) { | |
| 81 return new InProcessContextProvider( | |
| 82 attributes, lose_context_when_out_of_memory, window, debug_name); | |
| 83 } | |
| 84 | |
| 85 // static | |
| 86 scoped_refptr<InProcessContextProvider> | |
| 87 InProcessContextProvider::CreateOffscreen( | |
| 88 bool lose_context_when_out_of_memory) { | |
| 89 blink::WebGraphicsContext3D::Attributes attributes; | |
| 90 attributes.depth = false; | |
| 91 attributes.stencil = true; | |
| 92 attributes.antialias = false; | |
| 93 attributes.shareResources = true; | |
| 94 attributes.noAutomaticFlushes = true; | |
| 95 | |
| 96 return InProcessContextProvider::Create( | |
| 97 attributes, lose_context_when_out_of_memory, gfx::kNullAcceleratedWidget, | |
| 98 "Offscreen"); | |
| 99 } | |
| 100 | |
| 101 InProcessContextProvider::InProcessContextProvider( | |
| 102 const blink::WebGraphicsContext3D::Attributes& attributes, | |
| 103 bool lose_context_when_out_of_memory, | |
| 104 gfx::AcceleratedWidget window, | |
| 105 const std::string& debug_name) | |
| 106 : lose_context_when_out_of_memory_(lose_context_when_out_of_memory), | |
| 107 share_resources_(attributes.shareResources), | |
| 108 window_(window), | |
| 109 destroyed_(false), | |
| 110 debug_name_(debug_name) { | |
| 111 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 112 context_thread_checker_.DetachFromThread(); | |
| 113 | |
| 114 ConvertAttributes(attributes, &attributes_); | |
| 115 } | |
| 116 | |
| 117 InProcessContextProvider::~InProcessContextProvider() { | |
| 118 DCHECK(main_thread_checker_.CalledOnValidThread() || | |
| 119 context_thread_checker_.CalledOnValidThread()); | |
| 120 } | |
| 121 | |
| 122 bool InProcessContextProvider::BindToCurrentThread() { | |
| 123 // This is called on the thread the context will be used. | |
| 124 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 125 | |
| 126 if (lost_context_callback_proxy_) | |
| 127 return true; | |
| 128 | |
| 129 if (!context_) { | |
| 130 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; | |
| 131 context_.reset(gpu::GLInProcessContext::Create( | |
| 132 nullptr, /* service */ | |
| 133 nullptr, /* surface */ | |
| 134 true, /* is_offscreen */ | |
| 135 window_, | |
| 136 gfx::Size(1, 1), | |
| 137 nullptr, /* share_context */ | |
| 138 share_resources_, | |
| 139 attributes_, | |
| 140 gpu_preference, | |
| 141 gpu::GLInProcessContextSharedMemoryLimits(), | |
| 142 nullptr, | |
| 143 nullptr)); | |
| 144 } | |
| 145 | |
| 146 InitializeCapabilities(); | |
| 147 | |
| 148 std::string unique_context_name = | |
| 149 base::StringPrintf("%s-%p", debug_name_.c_str(), context_.get()); | |
| 150 //context_->traceBeginCHROMIUM("gpu_toplevel", | |
|
jamesr
2015/01/21 21:39:05
do
context_->TraceBeginCHROMIUM(....)
tfarina
2015/01/21 21:53:35
../../../ui/compositor/test/in_process_context_pro
| |
| 151 // unique_context_name.c_str()); | |
| 152 | |
| 153 lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this)); | |
| 154 return true; | |
| 155 } | |
| 156 | |
| 157 void InProcessContextProvider::InitializeCapabilities() { | |
| 158 capabilities_.gpu = context_->GetImplementation()->capabilities(); | |
| 159 | |
| 160 // size_t mapped_memory_limit = context3d_->GetMappedMemoryLimit(); | |
|
jamesr
2015/01/21 21:39:05
you don't care about this, just delete the block
tfarina
2015/01/21 21:53:35
Done.
| |
| 161 // capabilities_.max_transfer_buffer_usage_bytes = | |
| 162 // mapped_memory_limit == kNoLimit ? std::numeric_limits<size_t>::max() | |
| 163 // : mapped_memory_limit; | |
| 164 } | |
| 165 | |
| 166 cc::ContextProvider::Capabilities | |
| 167 InProcessContextProvider::ContextCapabilities() { | |
| 168 DCHECK(lost_context_callback_proxy_); // Is bound to thread. | |
| 169 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 170 return capabilities_; | |
| 171 } | |
| 172 | |
| 173 ::gpu::gles2::GLES2Interface* InProcessContextProvider::ContextGL() { | |
| 174 DCHECK(lost_context_callback_proxy_); // Is bound to thread. | |
| 175 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 176 | |
| 177 return context_->GetImplementation(); | |
| 178 } | |
| 179 | |
| 180 ::gpu::ContextSupport* InProcessContextProvider::ContextSupport() { | |
| 181 if (!lost_context_callback_proxy_) | |
| 182 return NULL; // Not bound to anything. | |
| 183 | |
| 184 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 185 | |
| 186 return context_->GetImplementation(); | |
| 187 } | |
| 188 | |
| 189 static void BindGrContextCallback(const GrGLInterface* interface) { | |
| 190 cc::ContextProvider* context_provider = | |
| 191 reinterpret_cast<InProcessContextProvider*>(interface->fCallbackData); | |
| 192 | |
| 193 gles2::SetGLContext(context_provider->ContextGL()); | |
| 194 } | |
| 195 | |
| 196 class GrContext* InProcessContextProvider::GrContext() { | |
| 197 DCHECK(lost_context_callback_proxy_); // Is bound to thread. | |
| 198 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 199 | |
| 200 if (gr_context_) | |
| 201 return gr_context_.get(); | |
| 202 | |
| 203 // The GrGLInterface factory will make GL calls using the C GLES2 interface. | |
| 204 // Make sure the gles2 library is initialized first on exactly one thread. | |
| 205 g_gles2_initializer.Get(); | |
| 206 gles2::SetGLContext(ContextGL()); | |
| 207 | |
| 208 skia::RefPtr<GrGLInterface> interface = | |
| 209 skia::AdoptRef(skia_bindings::CreateCommandBufferSkiaGLBinding()); | |
| 210 interface->fCallback = BindGrContextCallback; | |
| 211 interface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this); | |
| 212 | |
| 213 gr_context_ = skia::AdoptRef(GrContext::Create( | |
| 214 kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get()))); | |
| 215 | |
| 216 return gr_context_.get(); | |
| 217 } | |
| 218 | |
| 219 bool InProcessContextProvider::IsContextLost() { | |
| 220 DCHECK(lost_context_callback_proxy_); // Is bound to thread. | |
| 221 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 222 | |
| 223 return true; | |
| 224 } | |
| 225 | |
| 226 void InProcessContextProvider::VerifyContexts() { | |
| 227 } | |
| 228 | |
| 229 void InProcessContextProvider::DeleteCachedResources() { | |
| 230 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 231 | |
| 232 if (gr_context_) { | |
| 233 TRACE_EVENT_INSTANT0("gpu", "GrContext::freeGpuResources", | |
| 234 TRACE_EVENT_SCOPE_THREAD); | |
| 235 gr_context_->freeGpuResources(); | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 void InProcessContextProvider::OnLostContext() { | |
| 240 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 241 { | |
| 242 base::AutoLock lock(destroyed_lock_); | |
| 243 if (destroyed_) | |
| 244 return; | |
| 245 destroyed_ = true; | |
| 246 } | |
| 247 if (!lost_context_callback_.is_null()) | |
| 248 base::ResetAndReturn(&lost_context_callback_).Run(); | |
| 249 if (gr_context_) | |
| 250 gr_context_->abandonContext(); | |
| 251 } | |
| 252 | |
| 253 bool InProcessContextProvider::DestroyedOnMainThread() { | |
| 254 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 255 | |
| 256 base::AutoLock lock(destroyed_lock_); | |
| 257 return destroyed_; | |
| 258 } | |
| 259 | |
| 260 void InProcessContextProvider::SetLostContextCallback( | |
| 261 const LostContextCallback& lost_context_callback) { | |
| 262 DCHECK(context_thread_checker_.CalledOnValidThread()); | |
| 263 DCHECK(lost_context_callback_.is_null() || | |
| 264 lost_context_callback.is_null()); | |
| 265 lost_context_callback_ = lost_context_callback; | |
| 266 } | |
| 267 | |
| 268 void InProcessContextProvider::SetMemoryPolicyChangedCallback( | |
| 269 const MemoryPolicyChangedCallback& memory_policy_changed_callback) { | |
| 270 // There's no memory manager for the in-process implementation. | |
| 271 } | |
| 272 | |
| 273 } // namespace ui | |
| OLD | NEW |