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

Side by Side Diff: content/browser/renderer_host/image_transport_factory.cc

Issue 11195011: Send vsync timebase updates to the browser compositor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Work-in-progress Created 8 years, 1 month 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/renderer_host/image_transport_factory.h" 5 #include "content/browser/renderer_host/image_transport_factory.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
13 #include "base/observer_list.h" 13 #include "base/observer_list.h"
14 #include "base/threading/non_thread_safe.h"
14 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" 15 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
15 #include "content/browser/gpu/gpu_data_manager_impl.h" 16 #include "content/browser/gpu/gpu_data_manager_impl.h"
17 #include "content/browser/gpu/gpu_process_host.h"
16 #include "content/browser/gpu/gpu_surface_tracker.h" 18 #include "content/browser/gpu/gpu_surface_tracker.h"
17 #include "content/common/gpu/client/gl_helper.h" 19 #include "content/common/gpu/client/gl_helper.h"
18 #include "content/common/gpu/client/gpu_channel_host.h" 20 #include "content/common/gpu/client/gpu_channel_host.h"
19 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 21 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
22 #include "content/common/gpu/gpu_messages.h"
20 #include "content/common/gpu/gpu_process_launch_causes.h" 23 #include "content/common/gpu/gpu_process_launch_causes.h"
21 #include "content/common/webkitplatformsupport_impl.h" 24 #include "content/common/webkitplatformsupport_impl.h"
25 #include "content/public/browser/browser_thread.h"
jonathan.backer 2012/10/26 20:31:03 still need this?
ajuma 2012/10/29 17:02:26 No. Removed.
22 #include "content/public/common/content_switches.h" 26 #include "content/public/common/content_switches.h"
23 #include "gpu/ipc/command_buffer_proxy.h" 27 #include "gpu/ipc/command_buffer_proxy.h"
28 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutput Surface.h"
29 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutput SurfaceClient.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsC ontext3D.h" 30 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsC ontext3D.h"
25 #include "ui/compositor/compositor.h" 31 #include "ui/compositor/compositor.h"
26 #include "ui/compositor/compositor_setup.h" 32 #include "ui/compositor/compositor_setup.h"
27 #include "ui/compositor/test_web_graphics_context_3d.h" 33 #include "ui/compositor/test_web_graphics_context_3d.h"
28 #include "ui/gfx/native_widget_types.h" 34 #include "ui/gfx/native_widget_types.h"
29 #include "ui/gfx/size.h" 35 #include "ui/gfx/size.h"
30 36
31 #if defined(OS_WIN) 37 #if defined(OS_WIN)
32 #include "ui/surface/accelerated_surface_win.h" 38 #include "ui/surface/accelerated_surface_win.h"
33 #endif 39 #endif
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 219 }
214 220
215 private: 221 private:
216 void OnLostContext(); 222 void OnLostContext();
217 ui::Compositor* compositor_; 223 ui::Compositor* compositor_;
218 GpuProcessTransportFactory* factory_; 224 GpuProcessTransportFactory* factory_;
219 225
220 DISALLOW_COPY_AND_ASSIGN(CompositorSwapClient); 226 DISALLOW_COPY_AND_ASSIGN(CompositorSwapClient);
221 }; 227 };
222 228
229 class BrowserCompositorOutputSurfaceProxy;
230
231 // Adapts a WebGraphicsContext3DCommandBufferImpl into a
232 // WebCompositorOutputSurface that also handles vsync parameter updates
233 // arriving from the GPU process.
234 class BrowserCompositorOutputSurface :
235 public WebKit::WebCompositorOutputSurface,
236 public base::NonThreadSafe {
237 public:
238 explicit BrowserCompositorOutputSurface(
239 WebGraphicsContext3DCommandBufferImpl* context,
240 int surface_id)
241 : context3D_(context)
242 , surface_id_(surface_id)
243 , client_(NULL) {
244 DetachFromThread();
245 }
246
247 virtual ~BrowserCompositorOutputSurface() {
248 DCHECK(CalledOnValidThread());
249 if (!client_)
250 return;
251 BrowserCompositorOutputSurfaceProxy::GetInstance()->RemoveSurface(
252 surface_id_);
253 }
254
255 virtual bool bindToClient(
256 WebKit::WebCompositorOutputSurfaceClient* client) OVERRIDE {
257 DCHECK(CalledOnValidThread());
258 DCHECK(client);
259 DCHECK(!client_);
260 if (context3D_.get()) {
261 if (!context3D_->makeContextCurrent())
262 return false;
263 }
264
265 client_ = client;
266 BrowserCompositorOutputSurfaceProxy::GetInstance()->AddSurface(this,
267 surface_id_);
268 return true;
269 }
270
271 virtual const Capabilities& capabilities() const OVERRIDE {
272 DCHECK(CalledOnValidThread());
273 return capabilities_;
274 }
275
276 virtual WebKit::WebGraphicsContext3D* context3D() const OVERRIDE {
277 DCHECK(CalledOnValidThread());
278 return context3D_.get();
279 }
280
281 virtual void sendFrameToParentCompositor(
282 const WebKit::WebCompositorFrame&) OVERRIDE {
283 }
284
285 static void TerminateProxy() {
286 BrowserCompositorOutputSurfaceProxy::Terminate();
287 }
288
289 private:
290 // Directs vsync updates to the appropriate BrowserCompositorOutputSurface.
291 class BrowserCompositorOutputSurfaceProxy {
jonathan.backer 2012/10/26 20:31:03 Why an inner class? We're in an anon namespace no?
ajuma 2012/10/29 17:02:26 Yes. Made this a non-inner class now.
292 public:
293 static BrowserCompositorOutputSurfaceProxy* GetInstance() {
jonathan.backer 2012/10/26 20:31:03 Singletons are generally frowned upon (we do have
ajuma 2012/10/29 17:02:26 Done.
294 if (!instance_)
295 instance_ = new BrowserCompositorOutputSurfaceProxy();
296 return instance_;
297 }
298
299 static void Terminate() {
300 if (instance_) {
301 delete instance_;
302 instance_ = NULL;
303 }
304 }
305
306 void AddSurface(BrowserCompositorOutputSurface* surface, int surface_id) {
307 surface_map_.AddWithID(surface, surface_id);
308 }
309
310 void RemoveSurface(int surface_id) {
311 surface_map_.Remove(surface_id);
312 }
313
314 private:
315 BrowserCompositorOutputSurfaceProxy() {
316 uint32 messages_to_filter[] = {GpuHostMsg_UpdateVSyncParameters::ID};
317 BrowserGpuChannelHostFactory::instance()->SetHandlerForControlMessages(
318 messages_to_filter,
319 arraysize(messages_to_filter),
320 base::Bind(&BrowserCompositorOutputSurfaceProxy::
321 OnMessageReceivedStatic),
jonathan.backer 2012/10/26 20:31:03 Can we bind OnMessageReceived to this and eliminat
ajuma 2012/10/29 17:02:26 Done.
322 MessageLoop::current()->message_loop_proxy());
323 }
324
325 static void OnMessageReceivedStatic(const IPC::Message& message) {
326 if (instance_) {
327 instance_->OnMessageReceived(message);
328 }
329 }
330
331 void OnMessageReceived(const IPC::Message& message) {
332 IPC_BEGIN_MESSAGE_MAP(BrowserCompositorOutputSurfaceProxy, message)
333 IPC_MESSAGE_HANDLER(GpuHostMsg_UpdateVSyncParameters,
334 OnUpdateVSyncParameters);
335 IPC_END_MESSAGE_MAP()
336 }
337
338 void OnUpdateVSyncParameters(
339 int surface_id, base::TimeTicks timebase, base::TimeDelta interval) {
340 BrowserCompositorOutputSurface* surface = surface_map_.Lookup(surface_id);
341 if (surface)
342 surface->OnUpdateVSyncParameters(timebase, interval);
343 }
344
345 friend class
346 base::RefCountedThreadSafe<BrowserCompositorOutputSurfaceProxy>;
347 ~BrowserCompositorOutputSurfaceProxy() {}
348 IDMap<BrowserCompositorOutputSurface> surface_map_;
349
350 static BrowserCompositorOutputSurfaceProxy* instance_;
351
352 DISALLOW_COPY_AND_ASSIGN(BrowserCompositorOutputSurfaceProxy);
353 };
354
355 void OnUpdateVSyncParameters(
356 base::TimeTicks timebase, base::TimeDelta interval) {
357 DCHECK(CalledOnValidThread());
358 DCHECK(client_);
359 double monotonicTimebase = timebase.ToInternalValue() /
360 static_cast<double>(base::Time::kMicrosecondsPerSecond);
361 double intervalInSeconds = interval.ToInternalValue() /
362 static_cast<double>(base::Time::kMicrosecondsPerSecond);
363 client_->onVSyncParametersChanged(monotonicTimebase, intervalInSeconds);
364 }
365
366 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3D_;
367 int surface_id_;
368 Capabilities capabilities_;
369 WebKit::WebCompositorOutputSurfaceClient* client_;
370 };
371
372 // static
373 BrowserCompositorOutputSurface::BrowserCompositorOutputSurfaceProxy*
374 BrowserCompositorOutputSurface::BrowserCompositorOutputSurfaceProxy::
375 instance_ = NULL;
376
223 class GpuProcessTransportFactory : 377 class GpuProcessTransportFactory :
jonathan.backer 2012/10/26 20:31:03 Maybe this can own the BrowserCompositorOutputSurf
ajuma 2012/10/29 17:02:26 Done.
224 public ui::ContextFactory, 378 public ui::ContextFactory,
225 public ImageTransportFactory, 379 public ImageTransportFactory,
226 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { 380 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback {
227 public: 381 public:
228 GpuProcessTransportFactory() 382 GpuProcessTransportFactory()
229 : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { 383 : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) {
230 } 384 }
231 385
232 virtual ~GpuProcessTransportFactory() { 386 virtual ~GpuProcessTransportFactory() {
233 DCHECK(per_compositor_data_.empty()); 387 DCHECK(per_compositor_data_.empty());
234 } 388 }
235 389
236 virtual WebKit::WebGraphicsContext3D* CreateContext( 390 virtual WebGraphicsContext3DCommandBufferImpl* CreateContext(
237 ui::Compositor* compositor) OVERRIDE { 391 ui::Compositor* compositor) OVERRIDE {
238 PerCompositorData* data = per_compositor_data_[compositor]; 392 PerCompositorData* data = per_compositor_data_[compositor];
239 if (!data) 393 if (!data)
240 data = CreatePerCompositorData(compositor); 394 data = CreatePerCompositorData(compositor);
241 return CreateContextCommon(data->swap_client->AsWeakPtr(), 395 return CreateContextCommon(data->swap_client->AsWeakPtr(),
242 data->surface_id); 396 data->surface_id);
243 } 397 }
244 398
245 virtual WebGraphicsContext3DCommandBufferImpl* CreateOffscreenContext() 399 virtual WebGraphicsContext3DCommandBufferImpl* CreateOffscreenContext()
246 OVERRIDE { 400 OVERRIDE {
247 base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client; 401 base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client;
248 return CreateContextCommon(swap_client, 0); 402 return CreateContextCommon(swap_client, 0);
249 } 403 }
250 404
405 virtual WebKit::WebCompositorOutputSurface* CreateOutputSurface(
406 ui::Compositor* compositor) OVERRIDE {
407 WebGraphicsContext3DCommandBufferImpl* context = CreateContext(compositor);
408 return new BrowserCompositorOutputSurface(
409 context,
410 per_compositor_data_[compositor]->surface_id);
411 }
412
251 virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE { 413 virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE {
252 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 414 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
253 if (it == per_compositor_data_.end()) 415 if (it == per_compositor_data_.end())
254 return; 416 return;
255 PerCompositorData* data = it->second; 417 PerCompositorData* data = it->second;
256 DCHECK(data); 418 DCHECK(data);
257 GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id); 419 GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id);
258 delete data; 420 delete data;
259 per_compositor_data_.erase(it); 421 per_compositor_data_.erase(it);
260 if (per_compositor_data_.empty()) { 422 if (per_compositor_data_.empty()) {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 g_factory = new GpuProcessTransportFactory(); 662 g_factory = new GpuProcessTransportFactory();
501 } 663 }
502 ui::ContextFactory::SetInstance(g_factory->AsContextFactory()); 664 ui::ContextFactory::SetInstance(g_factory->AsContextFactory());
503 } 665 }
504 666
505 // static 667 // static
506 void ImageTransportFactory::Terminate() { 668 void ImageTransportFactory::Terminate() {
507 ui::ContextFactory::SetInstance(NULL); 669 ui::ContextFactory::SetInstance(NULL);
508 delete g_factory; 670 delete g_factory;
509 g_factory = NULL; 671 g_factory = NULL;
672 BrowserCompositorOutputSurface::TerminateProxy();
510 } 673 }
511 674
512 // static 675 // static
513 ImageTransportFactory* ImageTransportFactory::GetInstance() { 676 ImageTransportFactory* ImageTransportFactory::GetInstance() {
514 return g_factory; 677 return g_factory;
515 } 678 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698