Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(493)

Side by Side Diff: content/browser/android/in_process/synchronous_compositor_impl.cc

Issue 102963010: Move SynchronousCompositorFactoryImpl into separate h/cc files (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: style Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/android/in_process/synchronous_compositor_impl.h" 5 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/synchronization/lock.h"
10 #include "cc/input/input_handler.h" 9 #include "cc/input/input_handler.h"
11 #include "cc/input/layer_scroll_offset_delegate.h" 10 #include "cc/input/layer_scroll_offset_delegate.h"
11 #include "content/browser/android/in_process/synchronous_compositor_factory_impl .h"
12 #include "content/browser/android/in_process/synchronous_input_event_filter.h" 12 #include "content/browser/android/in_process/synchronous_input_event_filter.h"
13 #include "content/browser/renderer_host/render_widget_host_view_android.h" 13 #include "content/browser/renderer_host/render_widget_host_view_android.h"
14 #include "content/public/browser/android/synchronous_compositor_client.h" 14 #include "content/public/browser/android/synchronous_compositor_client.h"
15 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/render_process_host.h" 16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_view_host.h" 17 #include "content/public/browser/render_view_host.h"
18 #include "content/renderer/android/synchronous_compositor_factory.h"
19 #include "content/renderer/media/android/stream_texture_factory_android_synchron ous_impl.h"
20 #include "gpu/command_buffer/client/gl_in_process_context.h"
21 #include "gpu/command_buffer/service/stream_texture_manager_in_process_android.h "
22 #include "ui/gl/android/surface_texture.h"
23 #include "ui/gl/gl_surface.h" 18 #include "ui/gl/gl_surface.h"
24 #include "webkit/common/gpu/context_provider_in_process.h"
25 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl. h"
26 19
27 namespace content { 20 namespace content {
28 21
29 namespace { 22 namespace {
30 23
31 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
32
33 int GetInProcessRendererId() { 24 int GetInProcessRendererId() {
34 content::RenderProcessHost::iterator it = 25 content::RenderProcessHost::iterator it =
35 content::RenderProcessHost::AllHostsIterator(); 26 content::RenderProcessHost::AllHostsIterator();
36 if (it.IsAtEnd()) { 27 if (it.IsAtEnd()) {
37 // There should always be one RPH in single process mode. 28 // There should always be one RPH in single process mode.
38 NOTREACHED(); 29 NOTREACHED();
39 return 0; 30 return 0;
40 } 31 }
41 32
42 int id = it.GetCurrentValue()->GetID(); 33 int id = it.GetCurrentValue()->GetID();
43 it.Advance(); 34 it.Advance();
44 DCHECK(it.IsAtEnd()); // Not multiprocess compatible. 35 DCHECK(it.IsAtEnd()); // Not multiprocess compatible.
45 return id; 36 return id;
46 } 37 }
47 38
48 class VideoContextProvider
49 : public StreamTextureFactorySynchronousImpl::ContextProvider {
50 public:
51 VideoContextProvider(
52 const scoped_refptr<cc::ContextProvider>& context_provider,
53 gpu::GLInProcessContext* gl_in_process_context)
54 : context_provider_(context_provider),
55 gl_in_process_context_(gl_in_process_context) {}
56
57 virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture(
58 uint32 stream_id) OVERRIDE {
59 return gl_in_process_context_->GetSurfaceTexture(stream_id);
60 }
61
62 virtual blink::WebGraphicsContext3D* Context3d() OVERRIDE {
63 return context_provider_->Context3d();
64 }
65
66 private:
67 friend class base::RefCountedThreadSafe<VideoContextProvider>;
68 virtual ~VideoContextProvider() {}
69
70 scoped_refptr<cc::ContextProvider> context_provider_;
71 gpu::GLInProcessContext* gl_in_process_context_;
72
73 DISALLOW_COPY_AND_ASSIGN(VideoContextProvider);
74 };
75
76 class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
77 public:
78 SynchronousCompositorFactoryImpl()
79 : wrapped_gl_context_for_main_thread_(NULL),
80 num_hardware_compositors_(0) {
81 SynchronousCompositorFactory::SetInstance(this);
82 }
83
84 // SynchronousCompositorFactory
85 virtual scoped_refptr<base::MessageLoopProxy>
86 GetCompositorMessageLoop() OVERRIDE {
87 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
88 }
89
90 virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(
91 int routing_id) OVERRIDE {
92 scoped_ptr<SynchronousCompositorOutputSurface> output_surface(
93 new SynchronousCompositorOutputSurface(routing_id));
94 return output_surface.PassAs<cc::OutputSurface>();
95 }
96
97 virtual InputHandlerManagerClient* GetInputHandlerManagerClient() OVERRIDE {
98 return synchronous_input_event_filter();
99 }
100
101 SynchronousInputEventFilter* synchronous_input_event_filter() {
102 return &synchronous_input_event_filter_;
103 }
104
105 scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>
106 CreateOffscreenContext() {
107 if (!gfx::GLSurface::InitializeOneOff())
108 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>();
109
110 const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
111
112 blink::WebGraphicsContext3D::Attributes attributes;
113 attributes.antialias = false;
114 attributes.shareResources = true;
115 attributes.noAutomaticFlushes = true;
116
117 gpu::GLInProcessContextAttribs in_process_attribs;
118 WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes(
119 attributes, &in_process_attribs);
120 scoped_ptr<gpu::GLInProcessContext> context(
121 gpu::GLInProcessContext::CreateContext(true,
122 NULL,
123 gfx::Size(1, 1),
124 attributes.shareResources,
125 in_process_attribs,
126 gpu_preference));
127
128 wrapped_gl_context_for_main_thread_ = context.get();
129 if (!context.get())
130 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>();
131
132 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(
133 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
134 context.Pass(), attributes));
135 }
136
137 virtual scoped_refptr<cc::ContextProvider>
138 GetOffscreenContextProviderForMainThread() OVERRIDE {
139 // This check only guarantees the main thread context is created after
140 // a compositor did successfully initialize hardware draw in the past.
141 // In particular this does not guarantee that the main thread context
142 // will fail creation when all compositors release hardware draw.
143 bool failed = !CanCreateMainThreadContext();
144 if (!failed &&
145 (!offscreen_context_for_main_thread_.get() ||
146 offscreen_context_for_main_thread_->DestroyedOnMainThread())) {
147 offscreen_context_for_main_thread_ =
148 webkit::gpu::ContextProviderInProcess::Create(
149 CreateOffscreenContext(),
150 "Compositor-Offscreen");
151 failed = !offscreen_context_for_main_thread_.get() ||
152 !offscreen_context_for_main_thread_->BindToCurrentThread();
153 }
154
155 if (failed) {
156 offscreen_context_for_main_thread_ = NULL;
157 wrapped_gl_context_for_main_thread_ = NULL;
158 }
159 return offscreen_context_for_main_thread_;
160 }
161
162 // This is called on both renderer main thread (offscreen context creation
163 // path shared between cross-process and in-process platforms) and renderer
164 // compositor impl thread (InitializeHwDraw) in order to support Android
165 // WebView synchronously enable and disable hardware mode multiple times in
166 // the same task. This is ok because in-process WGC3D creation may happen on
167 // any thread and is lightweight.
168 virtual scoped_refptr<cc::ContextProvider>
169 GetOffscreenContextProviderForCompositorThread() OVERRIDE {
170 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_);
171 if (!offscreen_context_for_compositor_thread_.get() ||
172 offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) {
173 offscreen_context_for_compositor_thread_ =
174 webkit::gpu::ContextProviderInProcess::CreateOffscreen();
175 }
176 return offscreen_context_for_compositor_thread_;
177 }
178
179 virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory(
180 int view_id) OVERRIDE {
181 scoped_ptr<StreamTextureFactorySynchronousImpl> factory(
182 new StreamTextureFactorySynchronousImpl(
183 base::Bind(&SynchronousCompositorFactoryImpl::
184 TryCreateStreamTextureFactory,
185 base::Unretained(this)),
186 view_id));
187 return factory.PassAs<StreamTextureFactory>();
188 }
189
190 void CompositorInitializedHardwareDraw(SynchronousCompositorImpl* compositor);
191 void CompositorReleasedHardwareDraw(SynchronousCompositorImpl* compositor);
192
193 private:
194 void ReleaseGlobalHardwareResources();
195 bool CanCreateMainThreadContext();
196 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider>
197 TryCreateStreamTextureFactory();
198
199 SynchronousInputEventFilter synchronous_input_event_filter_;
200
201 // Only guards construction and destruction of
202 // |offscreen_context_for_compositor_thread_|, not usage.
203 base::Lock offscreen_context_for_compositor_thread_lock_;
204 scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_;
205 // This is a pointer to the context owned by
206 // |offscreen_context_for_main_thread_|.
207 gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_;
208 scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_;
209
210 // |num_hardware_compositor_lock_| is updated on UI thread only but can be
211 // read on renderer main thread.
212 base::Lock num_hardware_compositor_lock_;
213 unsigned int num_hardware_compositors_;
214 };
215
216 void SynchronousCompositorFactoryImpl::CompositorInitializedHardwareDraw(
217 SynchronousCompositorImpl* compositor) {
218 base::AutoLock lock(num_hardware_compositor_lock_);
219 num_hardware_compositors_++;
220 }
221
222 void SynchronousCompositorFactoryImpl::CompositorReleasedHardwareDraw(
223 SynchronousCompositorImpl* compositor) {
224 bool should_release_resources = false;
225 {
226 base::AutoLock lock(num_hardware_compositor_lock_);
227 DCHECK_GT(num_hardware_compositors_, 0u);
228 num_hardware_compositors_--;
229 should_release_resources = num_hardware_compositors_ == 0u;
230 }
231 if (should_release_resources)
232 ReleaseGlobalHardwareResources();
233 }
234
235 void SynchronousCompositorFactoryImpl::ReleaseGlobalHardwareResources() {
236 {
237 base::AutoLock lock(offscreen_context_for_compositor_thread_lock_);
238 offscreen_context_for_compositor_thread_ = NULL;
239 }
240
241 // TODO(boliu): Properly clean up command buffer server of main thread
242 // context here.
243 }
244
245 bool SynchronousCompositorFactoryImpl::CanCreateMainThreadContext() {
246 base::AutoLock lock(num_hardware_compositor_lock_);
247 return num_hardware_compositors_ > 0;
248 }
249
250 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider>
251 SynchronousCompositorFactoryImpl::TryCreateStreamTextureFactory() {
252 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider>
253 context_provider;
254 if (CanCreateMainThreadContext() &&
255 GetOffscreenContextProviderForMainThread()) {
256 DCHECK(offscreen_context_for_main_thread_);
257 DCHECK(wrapped_gl_context_for_main_thread_);
258 context_provider =
259 new VideoContextProvider(offscreen_context_for_main_thread_,
260 wrapped_gl_context_for_main_thread_);
261 }
262 return context_provider;
263 }
264
265 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory = 39 base::LazyInstance<SynchronousCompositorFactoryImpl>::Leaky g_factory =
266 LAZY_INSTANCE_INITIALIZER; 40 LAZY_INSTANCE_INITIALIZER;
267 41
268 } // namespace 42 } // namespace
269 43
270 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl); 44 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SynchronousCompositorImpl);
271 45
272 // static 46 // static
273 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id, 47 SynchronousCompositorImpl* SynchronousCompositorImpl::FromID(int process_id,
274 int routing_id) { 48 int routing_id) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 } 83 }
310 84
311 bool SynchronousCompositorImpl::InitializeHwDraw( 85 bool SynchronousCompositorImpl::InitializeHwDraw(
312 scoped_refptr<gfx::GLSurface> surface) { 86 scoped_refptr<gfx::GLSurface> surface) {
313 DCHECK(CalledOnValidThread()); 87 DCHECK(CalledOnValidThread());
314 DCHECK(output_surface_); 88 DCHECK(output_surface_);
315 bool success = output_surface_->InitializeHwDraw( 89 bool success = output_surface_->InitializeHwDraw(
316 surface, 90 surface,
317 g_factory.Get().GetOffscreenContextProviderForCompositorThread()); 91 g_factory.Get().GetOffscreenContextProviderForCompositorThread());
318 if (success) 92 if (success)
319 g_factory.Get().CompositorInitializedHardwareDraw(this); 93 g_factory.Get().CompositorInitializedHardwareDraw();
320 return success; 94 return success;
321 } 95 }
322 96
323 void SynchronousCompositorImpl::ReleaseHwDraw() { 97 void SynchronousCompositorImpl::ReleaseHwDraw() {
324 DCHECK(CalledOnValidThread()); 98 DCHECK(CalledOnValidThread());
325 DCHECK(output_surface_); 99 DCHECK(output_surface_);
326 output_surface_->ReleaseHwDraw(); 100 output_surface_->ReleaseHwDraw();
327 g_factory.Get().CompositorReleasedHardwareDraw(this); 101 g_factory.Get().CompositorReleasedHardwareDraw();
328 } 102 }
329 103
330 bool SynchronousCompositorImpl::DemandDrawHw( 104 bool SynchronousCompositorImpl::DemandDrawHw(
331 gfx::Size surface_size, 105 gfx::Size surface_size,
332 const gfx::Transform& transform, 106 const gfx::Transform& transform,
333 gfx::Rect viewport, 107 gfx::Rect viewport,
334 gfx::Rect clip, 108 gfx::Rect clip,
335 bool stencil_enabled) { 109 bool stencil_enabled) {
336 DCHECK(CalledOnValidThread()); 110 DCHECK(CalledOnValidThread());
337 DCHECK(output_surface_); 111 DCHECK(output_surface_);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 g_factory.Get(); // Ensure it's initialized. 259 g_factory.Get(); // Ensure it's initialized.
486 SynchronousCompositorImpl::CreateForWebContents(contents); 260 SynchronousCompositorImpl::CreateForWebContents(contents);
487 } 261 }
488 if (SynchronousCompositorImpl* instance = 262 if (SynchronousCompositorImpl* instance =
489 SynchronousCompositorImpl::FromWebContents(contents)) { 263 SynchronousCompositorImpl::FromWebContents(contents)) {
490 instance->SetClient(client); 264 instance->SetClient(client);
491 } 265 }
492 } 266 }
493 267
494 } // namespace content 268 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/android/in_process/synchronous_compositor_factory_impl.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698