OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "chrome/browser/android/blimp/chrome_compositor_dependencies.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/command_line.h" | |
9 #include "cc/output/context_provider.h" | |
10 #include "content/public/common/content_switches.h" | |
11 #include "gpu/command_buffer/client/gles2_interface.h" | |
12 #include "gpu/command_buffer/client/shared_memory_limits.h" | |
13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | |
14 #include "ui/android/context_provider_factory.h" | |
15 | |
16 namespace { | |
17 | |
18 void OnCompositorContextCreated( | |
19 const blimp::client::CompositorDependencies::ContextProviderCallback& | |
20 callback, | |
21 const scoped_refptr<cc::ContextProvider>& worker_context, | |
22 const scoped_refptr<cc::ContextProvider>& compositor_context) { | |
23 blimp::client::CompositorDependencies::ContextProviders context_providers; | |
24 context_providers.compositor_context_provider = std::move(compositor_context); | |
25 context_providers.worker_context_provider = std::move(worker_context); | |
26 callback.Run(context_providers); | |
27 } | |
28 | |
29 gpu::gles2::ContextCreationAttribHelper | |
30 GetOffscreenContextCreationAttributes() { | |
31 gpu::gles2::ContextCreationAttribHelper attributes; | |
32 attributes.alpha_size = -1; | |
33 attributes.depth_size = 0; | |
34 attributes.stencil_size = 0; | |
35 attributes.samples = 0; | |
36 attributes.sample_buffers = 0; | |
37 attributes.bind_generates_resource = false; | |
38 attributes.lose_context_when_out_of_memory = true; | |
39 return attributes; | |
40 } | |
41 | |
42 bool IsAsyncWorkerContextEnabled() { | |
43 const base::CommandLine& command_line = | |
44 *base::CommandLine::ForCurrentProcess(); | |
45 | |
46 if (command_line.HasSwitch(switches::kDisableGpuAsyncWorkerContext)) | |
47 return false; | |
48 else if (command_line.HasSwitch(switches::kEnableGpuAsyncWorkerContext)) | |
49 return true; | |
50 | |
51 return false; | |
52 } | |
53 | |
54 } // namespace | |
55 | |
56 ChromeCompositorDependencies::ChromeCompositorDependencies( | |
57 ui::ContextProviderFactory* context_provider_factory) | |
58 : context_provider_factory_(context_provider_factory), | |
59 worker_context_request_pending_(false), | |
60 weak_factory_(this) { | |
61 DCHECK(context_provider_factory_); | |
62 } | |
63 | |
64 ChromeCompositorDependencies::~ChromeCompositorDependencies() = default; | |
65 | |
66 cc::LayerTreeSettings* ChromeCompositorDependencies::GetLayerTreeSettings() { | |
67 // MAKE THE SETTINGS!!!!! | |
David Trainor- moved to gerrit
2016/08/31 00:28:58
yes plz! In another patch maybe pull out the Comp
Khushal
2016/08/31 21:22:51
Done. I just moved it to internal for now, when Ch
| |
68 return nullptr; | |
69 } | |
70 | |
71 gpu::GpuMemoryBufferManager* | |
72 ChromeCompositorDependencies::GetGpuMemoryBufferManager() { | |
73 return context_provider_factory_->GetGpuMemoryBufferManager(); | |
74 } | |
75 | |
76 cc::SurfaceManager* ChromeCompositorDependencies::GetSurfaceManager() { | |
77 return context_provider_factory_->GetSurfaceManager(); | |
78 } | |
79 | |
80 uint32_t ChromeCompositorDependencies::AllocateSurfaceClientId() { | |
81 return context_provider_factory_->AllocateSurfaceClientId(); | |
82 } | |
83 | |
84 void ChromeCompositorDependencies::GetContextProviders( | |
85 const ContextProviderCallback& callback) { | |
86 bool worker_context_is_valid = false; | |
87 if (shared_main_thread_worker_context_) { | |
88 // Note: If context is lost, delete reference after releasing the lock. | |
89 cc::ContextProvider::ScopedContextLock lock( | |
90 shared_main_thread_worker_context_.get()); | |
91 if (shared_main_thread_worker_context_->ContextGL() | |
92 ->GetGraphicsResetStatusKHR() == GL_NO_ERROR) | |
93 worker_context_is_valid = true; | |
94 } | |
95 if (!worker_context_is_valid) | |
96 shared_main_thread_worker_context_ = nullptr; | |
David Trainor- moved to gerrit
2016/08/31 00:28:58
What happens to any outstanding requests if this d
Khushal
2016/08/31 21:22:50
Good call. I think the compositor expects the work
| |
97 | |
98 // Request a compositor context if the worker context is still valid. | |
99 if (shared_main_thread_worker_context_) { | |
100 HandleCompositorContextRequest(callback); | |
101 return; | |
102 } | |
103 | |
104 // Add the request to the list of pending requests first, if the result | |
105 // comes back synchronously, the callback should get triggered. | |
106 pending_requests_.push_back(callback); | |
107 | |
108 // If the request for a worker context is already pending, don't make | |
109 // another one. We'll handle all the pending requests together once the | |
110 // worker context is available. | |
111 if (worker_context_request_pending_) | |
112 return; | |
113 | |
114 worker_context_request_pending_ = true; | |
115 context_provider_factory_->CreateOffscreenContextProvider( | |
116 ui::ContextProviderFactory::ContextType::BLIMP_RENDER_WORKER_CONTEXT, | |
117 gpu::SharedMemoryLimits(), GetOffscreenContextCreationAttributes(), | |
118 true /* support_locking */, false /* automatic_flushes */, nullptr, | |
119 base::Bind(&ChromeCompositorDependencies::OnWorkerContextCreated, | |
120 weak_factory_.GetWeakPtr())); | |
121 } | |
122 | |
123 void ChromeCompositorDependencies::OnWorkerContextCreated( | |
124 const scoped_refptr<cc::ContextProvider>& worker_context) { | |
125 DCHECK(worker_context_request_pending_); | |
126 DCHECK(!shared_main_thread_worker_context_); | |
127 | |
128 worker_context_request_pending_ = false; | |
129 if (worker_context->BindToCurrentThread()) { | |
130 shared_main_thread_worker_context_ = worker_context; | |
131 } | |
David Trainor- moved to gerrit
2016/08/31 00:28:58
What if this returns false?
Khushal
2016/08/31 21:22:50
If the bind fails, then we just report the failure
| |
132 | |
133 // Copy the requests first since we can get more requests as we run these | |
134 // callbacks. | |
135 std::list<ContextProviderCallback> context_requests = pending_requests_; | |
136 pending_requests_.clear(); | |
137 | |
138 for (ContextProviderCallback& context_request : context_requests) { | |
139 HandleCompositorContextRequest(context_request); | |
140 } | |
141 } | |
142 | |
143 void ChromeCompositorDependencies::HandleCompositorContextRequest( | |
144 const ContextProviderCallback& callback) { | |
145 // Respond with null contexts if the worker context could not be created. | |
146 if (!shared_main_thread_worker_context_) { | |
147 callback.Run(ContextProviders()); | |
148 return; | |
149 } | |
150 | |
151 ui::ContextProviderFactory::ContextProviderCallback result_callback = | |
152 base::Bind(&OnCompositorContextCreated, callback, | |
153 shared_main_thread_worker_context_); | |
154 | |
155 // The compositor context shares resources with the worker context unless | |
156 // the worker is async. | |
157 cc::ContextProvider* shared_context = | |
158 IsAsyncWorkerContextEnabled() ? nullptr | |
159 : shared_main_thread_worker_context_.get(); | |
160 | |
161 context_provider_factory_->CreateOffscreenContextProvider( | |
162 ui::ContextProviderFactory::ContextType::BLIMP_RENDER_COMPOSITOR_CONTEXT, | |
163 gpu::SharedMemoryLimits::ForMailboxContext(), | |
164 GetOffscreenContextCreationAttributes(), false /* support_locking */, | |
165 false /* automatic_flushes */, shared_context, result_callback); | |
166 } | |
OLD | NEW |