1 // Copyright 2015 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.
5 #include "android_webview/browser/aw_render_thread_context_provider.h"
8 #include "base/callback_helpers.h"
9 #include "base/lazy_instance.h"
10 #include "base/trace_event/trace_event.h"
11 #include "cc/output/managed_memory_policy.h"
12 #include "gpu/blink/webgraphicscontext3d_impl.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"
20 namespace android_webview
{
24 // Singleton used to initialize and terminate the gles2 library.
25 class GLES2Initializer
{
27 GLES2Initializer() { gles2::Initialize(); }
29 ~GLES2Initializer() { gles2::Terminate(); }
32 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer
);
35 base::LazyInstance
<GLES2Initializer
> g_gles2_initializer
=
36 LAZY_INSTANCE_INITIALIZER
;
41 scoped_refptr
<AwRenderThreadContextProvider
>
42 AwRenderThreadContextProvider::Create(
43 scoped_refptr
<gfx::GLSurface
> surface
,
44 scoped_refptr
<gpu::InProcessCommandBuffer::Service
> service
) {
45 return new AwRenderThreadContextProvider(surface
, service
);
48 AwRenderThreadContextProvider::AwRenderThreadContextProvider(
49 scoped_refptr
<gfx::GLSurface
> surface
,
50 scoped_refptr
<gpu::InProcessCommandBuffer::Service
> service
)
52 DCHECK(main_thread_checker_
.CalledOnValidThread());
54 blink::WebGraphicsContext3D::Attributes attributes
;
55 attributes
.antialias
= false;
56 attributes
.depth
= false;
57 attributes
.stencil
= false;
58 attributes
.shareResources
= true;
59 attributes
.noAutomaticFlushes
= true;
60 gpu::gles2::ContextCreationAttribHelper attribs_for_gles2
;
61 gpu_blink::WebGraphicsContext3DImpl::ConvertAttributes(attributes
,
63 attribs_for_gles2
.lose_context_when_out_of_memory
= true;
65 context_
.reset(gpu::GLInProcessContext::Create(
68 surface
->IsOffscreen(),
69 gfx::kNullAcceleratedWidget
,
71 NULL
/* share_context */,
72 false /* share_resources */,
74 gfx::PreferDiscreteGpu
,
75 gpu::GLInProcessContextSharedMemoryLimits(),
79 context_
->SetContextLostCallback(base::Bind(
80 &AwRenderThreadContextProvider::OnLostContext
, base::Unretained(this)));
82 capabilities_
.gpu
= context_
->GetImplementation()->capabilities();
85 AwRenderThreadContextProvider::~AwRenderThreadContextProvider() {
86 DCHECK(main_thread_checker_
.CalledOnValidThread());
89 bool AwRenderThreadContextProvider::BindToCurrentThread() {
90 // This is called on the thread the context will be used.
91 DCHECK(main_thread_checker_
.CalledOnValidThread());
96 cc::ContextProvider::Capabilities
97 AwRenderThreadContextProvider::ContextCapabilities() {
98 DCHECK(main_thread_checker_
.CalledOnValidThread());
100 return capabilities_
;
103 gpu::gles2::GLES2Interface
* AwRenderThreadContextProvider::ContextGL() {
104 DCHECK(main_thread_checker_
.CalledOnValidThread());
106 return context_
->GetImplementation();
109 gpu::ContextSupport
* AwRenderThreadContextProvider::ContextSupport() {
110 DCHECK(main_thread_checker_
.CalledOnValidThread());
112 return context_
->GetImplementation();
115 static void BindGrContextCallback(const GrGLInterface
* interface
) {
116 cc::ContextProvider
* context_provider
=
117 reinterpret_cast<AwRenderThreadContextProvider
*>(
118 interface
->fCallbackData
);
120 gles2::SetGLContext(context_provider
->ContextGL());
123 class GrContext
* AwRenderThreadContextProvider::GrContext() {
124 DCHECK(main_thread_checker_
.CalledOnValidThread());
127 return gr_context_
.get();
129 // The GrGLInterface factory will make GL calls using the C GLES2 interface.
130 // Make sure the gles2 library is initialized first on exactly one thread.
131 g_gles2_initializer
.Get();
132 gles2::SetGLContext(ContextGL());
134 skia::RefPtr
<GrGLInterface
> interface
=
135 skia::AdoptRef(skia_bindings::CreateCommandBufferSkiaGLBinding());
136 interface
->fCallback
= BindGrContextCallback
;
137 interface
->fCallbackData
= reinterpret_cast<GrGLInterfaceCallbackData
>(this);
139 gr_context_
= skia::AdoptRef(GrContext::Create(
140 kOpenGL_GrBackend
, reinterpret_cast<GrBackendContext
>(interface
.get())));
142 return gr_context_
.get();
145 void AwRenderThreadContextProvider::InvalidateGrContext(uint32_t state
) {
146 DCHECK(main_thread_checker_
.CalledOnValidThread());
149 gr_context_
.get()->resetContext(state
);
152 void AwRenderThreadContextProvider::SetupLock() {
153 context_
->SetLock(&context_lock_
);
156 base::Lock
* AwRenderThreadContextProvider::GetLock() {
157 return &context_lock_
;
160 bool AwRenderThreadContextProvider::IsContextLost() {
161 DCHECK(main_thread_checker_
.CalledOnValidThread());
166 void AwRenderThreadContextProvider::VerifyContexts() {
169 void AwRenderThreadContextProvider::DeleteCachedResources() {
170 DCHECK(main_thread_checker_
.CalledOnValidThread());
173 TRACE_EVENT_INSTANT0("gpu", "GrContext::freeGpuResources",
174 TRACE_EVENT_SCOPE_THREAD
);
175 gr_context_
->freeGpuResources();
179 bool AwRenderThreadContextProvider::DestroyedOnMainThread() {
180 DCHECK(main_thread_checker_
.CalledOnValidThread());
185 void AwRenderThreadContextProvider::SetLostContextCallback(
186 const LostContextCallback
& lost_context_callback
) {
187 lost_context_callback_
= lost_context_callback
;
190 void AwRenderThreadContextProvider::SetMemoryPolicyChangedCallback(
191 const MemoryPolicyChangedCallback
& memory_policy_changed_callback
) {
192 // There's no memory manager for the in-process implementation.
195 void AwRenderThreadContextProvider::OnLostContext() {
196 DCHECK(main_thread_checker_
.CalledOnValidThread());
202 if (!lost_context_callback_
.is_null())
203 base::ResetAndReturn(&lost_context_callback_
).Run();
205 gr_context_
->abandonContext();
208 } // namespace android_webview