diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-07 23:19:16 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-07 23:19:16 +0000 |
commit | 1c0585d585bc9f88ee177553b66e0025d7fe3aa0 (patch) | |
tree | dcce9c6dcbe4634483104b236a87e42d694bbeb1 | |
parent | fd3a7df6c4caaeceb8402daa2c1b357c7f78331f (diff) | |
download | chromium_src-1c0585d585bc9f88ee177553b66e0025d7fe3aa0.zip chromium_src-1c0585d585bc9f88ee177553b66e0025d7fe3aa0.tar.gz chromium_src-1c0585d585bc9f88ee177553b66e0025d7fe3aa0.tar.bz2 |
Added switch to disable GPU vsync.
This is useful for GPU performance testing because the vsync caps the frame rate.
TEST=try
BUG=none
Review URL: http://codereview.chromium.org/3380011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61877 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | app/app_switches.cc | 3 | ||||
-rw-r--r-- | app/app_switches.h | 1 | ||||
-rw-r--r-- | app/gfx/gl/generate_bindings.py | 3 | ||||
-rw-r--r-- | app/gfx/gl/gl_context.cc | 17 | ||||
-rw-r--r-- | app/gfx/gl/gl_context.h | 10 | ||||
-rw-r--r-- | app/gfx/gl/gl_context_egl.cc | 18 | ||||
-rw-r--r-- | app/gfx/gl/gl_context_egl.h | 5 | ||||
-rw-r--r-- | app/gfx/gl/gl_context_linux.cc | 43 | ||||
-rw-r--r-- | app/gfx/gl/gl_context_mac.cc | 6 | ||||
-rw-r--r-- | app/gfx/gl/gl_context_osmesa.cc | 5 | ||||
-rw-r--r-- | app/gfx/gl/gl_context_osmesa.h | 1 | ||||
-rw-r--r-- | app/gfx/gl/gl_context_stub.h | 3 | ||||
-rw-r--r-- | app/gfx/gl/gl_context_win.cc | 56 | ||||
-rw-r--r-- | chrome/browser/gpu_process_host.cc | 1 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_mac.mm | 7 |
15 files changed, 171 insertions, 8 deletions
diff --git a/app/app_switches.cc b/app/app_switches.cc index 8527a45..258b148 100644 --- a/app/app_switches.cc +++ b/app/app_switches.cc @@ -6,6 +6,9 @@ namespace switches { +// Stop the GPU from synchronizing on the vsync before presenting. +const char kDisableGpuVsync[] = "disable-gpu-vsync"; + // The language file that we want to try to open. Of the form // language[-country] where language is the 2 letter code from ISO-639. const char kLang[] = "lang"; diff --git a/app/app_switches.h b/app/app_switches.h index dda5b84..dc5ea8f 100644 --- a/app/app_switches.h +++ b/app/app_switches.h @@ -10,6 +10,7 @@ namespace switches { +extern const char kDisableGpuVsync[]; extern const char kLang[]; extern const char kUseGL[]; diff --git a/app/gfx/gl/generate_bindings.py b/app/gfx/gl/generate_bindings.py index 21a8137..dc07c8e 100644 --- a/app/gfx/gl/generate_bindings.py +++ b/app/gfx/gl/generate_bindings.py @@ -332,6 +332,7 @@ WGL_FUNCTIONS = [ ['HDC', ['wglGetCurrentDC'], ''], ['BOOL', ['wglMakeCurrent'], 'HDC hdc, HGLRC hglrc'], ['BOOL', ['wglShareLists'], 'HGLRC hglrc1, HGLRC hglrc2'], +['BOOL', ['wglSwapIntervalEXT'], 'int interval'], ['BOOL', ['wglSwapLayerBuffers'], 'HDC hdc, UINT fuPlanes'], ['const char*', ['wglGetExtensionsStringARB', 'wglGetExtensionsStringEXT'], 'HDC hDC'], @@ -407,6 +408,8 @@ GLX_FUNCTIONS = [ 'Display* dpy, GLXDrawable drawable, unsigned long mask'], ['void', ['glXGetSelectedEvent'], 'Display* dpy, GLXDrawable drawable, unsigned long* mask'], +['void', ['glXSwapIntervalEXT'], + 'Display* dpy, GLXDrawable drawable, int interval'], ] FUNCTION_SETS = [ diff --git a/app/gfx/gl/gl_context.cc b/app/gfx/gl/gl_context.cc index 7e58027..a07d30a 100644 --- a/app/gfx/gl/gl_context.cc +++ b/app/gfx/gl/gl_context.cc @@ -4,18 +4,22 @@ #include <string> +#include "app/app_switches.h" #include "app/gfx/gl/gl_context.h" #include "app/gfx/gl/gl_bindings.h" #include "app/gfx/gl/gl_implementation.h" +#include "base/command_line.h" #include "base/logging.h" namespace gfx { -bool GLContext::HasExtension(const char* name) { +std::string GLContext::GetExtensions() { DCHECK(IsCurrent()); + return std::string(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); +} - std::string extensions(reinterpret_cast<const char*>( - glGetString(GL_EXTENSIONS))); +bool GLContext::HasExtension(const char* name) { + std::string extensions = GetExtensions(); extensions += " "; std::string delimited_name(name); @@ -30,6 +34,13 @@ bool GLContext::InitializeCommon() { return false; } + if (!IsOffscreen()) { + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) + SetSwapInterval(0); + else + SetSwapInterval(1); + } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); if (glGetError() != GL_NO_ERROR) { LOG(ERROR) << "glClear failed."; diff --git a/app/gfx/gl/gl_context.h b/app/gfx/gl/gl_context.h index 3c1dfe0..5264c4a 100644 --- a/app/gfx/gl/gl_context.h +++ b/app/gfx/gl/gl_context.h @@ -6,6 +6,8 @@ #define APP_GFX_GL_GL_CONTEXT_H_ #pragma once +#include <string> + #include "build/build_config.h" #include "gfx/native_widget_types.h" #include "gfx/size.h" @@ -40,9 +42,15 @@ class GLContext { // Get the underlying platform specific GL context "handle". virtual void* GetHandle() = 0; + // Set swap interval. This context must be current. + virtual void SetSwapInterval(int interval) = 0; + + // Returns space separated list of extensions. The context must be current. + virtual std::string GetExtensions(); + // Returns whether the current context supports the named extension. The // context must be current. - virtual bool HasExtension(const char* name); + bool HasExtension(const char* name); static bool InitializeOneOff(); diff --git a/app/gfx/gl/gl_context_egl.cc b/app/gfx/gl/gl_context_egl.cc index 910a22e..4cceb56 100644 --- a/app/gfx/gl/gl_context_egl.cc +++ b/app/gfx/gl/gl_context_egl.cc @@ -97,6 +97,14 @@ EGLDisplay BaseEGLContext::GetDisplay() { return g_display; } +std::string BaseEGLContext::GetExtensions() { + const char* extensions = eglQueryString(g_display, EGL_EXTENSIONS); + if (!extensions) + return GLContext::GetExtensions(); + + return GLContext::GetExtensions() + " " + extensions; +} + NativeViewEGLContext::NativeViewEGLContext(void* window) : window_(window), surface_(NULL), @@ -200,6 +208,11 @@ void* NativeViewEGLContext::GetHandle() { return context_; } +void NativeViewEGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + eglSwapInterval(g_display, interval); +} + EGLSurface NativeViewEGLContext::GetSurface() { return surface_; } @@ -307,6 +320,11 @@ void* SecondaryEGLContext::GetHandle() { return context_; } +void SecondaryEGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + NOTREACHED() << "Attempt to call SetSwapInterval on a SecondaryEGLContext."; +} + EGLSurface SecondaryEGLContext::GetSurface() { return surface_; } diff --git a/app/gfx/gl/gl_context_egl.h b/app/gfx/gl/gl_context_egl.h index 76e34d6..9cbdba1 100644 --- a/app/gfx/gl/gl_context_egl.h +++ b/app/gfx/gl/gl_context_egl.h @@ -23,6 +23,9 @@ class BaseEGLContext : public GLContext { virtual ~BaseEGLContext() {} // Implement GLContext. + virtual std::string GetExtensions(); + + // Get the associated EGL surface. virtual EGLSurface GetSurface() = 0; static bool InitializeOneOff(); @@ -50,6 +53,7 @@ class NativeViewEGLContext : public BaseEGLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); // Implement BaseEGLContext. virtual EGLSurface GetSurface(); @@ -82,6 +86,7 @@ class SecondaryEGLContext : public BaseEGLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); // Implement BaseEGLContext. virtual EGLSurface GetSurface(); diff --git a/app/gfx/gl/gl_context_linux.cc b/app/gfx/gl/gl_context_linux.cc index 48f0368..2301e9e 100644 --- a/app/gfx/gl/gl_context_linux.cc +++ b/app/gfx/gl/gl_context_linux.cc @@ -23,6 +23,11 @@ namespace gfx { typedef GLXContext GLContextHandle; typedef GLXPbuffer PbufferHandle; +class BaseLinuxGLContext : public GLContext { + public: + virtual std::string GetExtensions(); +}; + // This class is a wrapper around a GL context that renders directly to a // window. class ViewGLContext : public GLContext { @@ -43,6 +48,7 @@ class ViewGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); private: gfx::PluginWindowHandle window_; @@ -73,6 +79,7 @@ class OSMesaViewGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); private: bool UpdateSize(); @@ -106,6 +113,7 @@ class PbufferGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); private: GLContextHandle context_; @@ -133,6 +141,7 @@ class PixmapGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); private: GLContextHandle context_; @@ -201,6 +210,16 @@ bool GLContext::InitializeOneOff() { return true; } +std::string BaseLinuxGLContext::GetExtensions() { + Display* display = x11_util::GetXDisplay(); + const char* extensions = glXQueryExtensionsString(display, 0); + if (extensions) { + return GLContext::GetExtensions() + " " + extensions; + } + + return GLContext::GetExtensions(); +} + bool ViewGLContext::Initialize(bool multisampled) { if (multisampled) { LOG(WARNING) << "Multisampling not implemented."; @@ -300,6 +319,14 @@ void* ViewGLContext::GetHandle() { return context_; } +void ViewGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + if (HasExtension("GLX_EXT_swap_control") && glXSwapIntervalEXT) { + Display* display = x11_util::GetXDisplay(); + glXSwapIntervalEXT(display, window_, interval); + } +} + bool OSMesaViewGLContext::Initialize() { if (!osmesa_context_.Initialize(OSMESA_BGRA, NULL)) { LOG(ERROR) << "OSMesaGLContext::Initialize failed."; @@ -403,6 +430,12 @@ void* OSMesaViewGLContext::GetHandle() { return osmesa_context_.GetHandle(); } +void OSMesaViewGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + // Fail silently. It is legitimate to set the swap interval on a view context + // but XLib does not have those semantics. +} + bool OSMesaViewGLContext::UpdateSize() { // Get the window size. XWindowAttributes attributes; @@ -610,6 +643,11 @@ void* PbufferGLContext::GetHandle() { return context_; } +void PbufferGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + NOTREACHED(); +} + bool PixmapGLContext::Initialize(GLContext* shared_context) { LOG(INFO) << "GL context: using pixmaps."; @@ -728,6 +766,11 @@ void* PixmapGLContext::GetHandle() { return context_; } +void PixmapGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + NOTREACHED(); +} + GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) { switch (GetGLImplementation()) { case kGLImplementationDesktopGL: { diff --git a/app/gfx/gl/gl_context_mac.cc b/app/gfx/gl/gl_context_mac.cc index 36fc089..841d1a6 100644 --- a/app/gfx/gl/gl_context_mac.cc +++ b/app/gfx/gl/gl_context_mac.cc @@ -42,6 +42,7 @@ class PbufferGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); private: GLContextHandle context_; @@ -175,6 +176,11 @@ void* PbufferGLContext::GetHandle() { return context_; } +void PbufferGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + NOTREACHED() << "Attempt to call SetSwapInterval on a PbufferGLContext."; +} + GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) { switch (GetGLImplementation()) { case kGLImplementationDesktopGL: { diff --git a/app/gfx/gl/gl_context_osmesa.cc b/app/gfx/gl/gl_context_osmesa.cc index 9eb5549..d9cbe4f 100644 --- a/app/gfx/gl/gl_context_osmesa.cc +++ b/app/gfx/gl/gl_context_osmesa.cc @@ -97,6 +97,11 @@ void* OSMesaGLContext::GetHandle() { return context_; } +void OSMesaGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + NOTREACHED() << "Attempt to call SetSwapInterval on an OSMesaGLContext."; +} + void OSMesaGLContext::Resize(const gfx::Size& new_size) { if (new_size == size_) return; diff --git a/app/gfx/gl/gl_context_osmesa.h b/app/gfx/gl/gl_context_osmesa.h index caa0895..31a2ff7 100644 --- a/app/gfx/gl/gl_context_osmesa.h +++ b/app/gfx/gl/gl_context_osmesa.h @@ -31,6 +31,7 @@ class OSMesaGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); // Resize the back buffer, preserving the old content. Does nothing if the // size is unchanged. diff --git a/app/gfx/gl/gl_context_stub.h b/app/gfx/gl/gl_context_stub.h index 034a04d..0037044 100644 --- a/app/gfx/gl/gl_context_stub.h +++ b/app/gfx/gl/gl_context_stub.h @@ -23,7 +23,8 @@ class StubGLContext : public gfx::GLContext { virtual bool SwapBuffers() { return true; } virtual gfx::Size GetSize() { return size_; } virtual void* GetHandle() { return NULL; } - virtual bool HasExtension(const char* name) { return false; } + virtual void SetSwapInterval(int interval) {} + virtual std::string GetExtensions() { return std::string(); } void SetSize(const gfx::Size& size) { size_ = size; } diff --git a/app/gfx/gl/gl_context_win.cc b/app/gfx/gl/gl_context_win.cc index 508355f..f264b93 100644 --- a/app/gfx/gl/gl_context_win.cc +++ b/app/gfx/gl/gl_context_win.cc @@ -24,9 +24,16 @@ namespace gfx { typedef HGLRC GLContextHandle; typedef HPBUFFERARB PbufferHandle; +class BaseWinGLContext : public GLContext { + public: + virtual std::string GetExtensions(); + + virtual HDC GetDC() = 0; +}; + // This class is a wrapper around a GL context that renders directly to a // window. -class NativeViewGLContext : public GLContext { +class NativeViewGLContext : public BaseWinGLContext { public: explicit NativeViewGLContext(gfx::PluginWindowHandle window) : window_(window), @@ -45,6 +52,9 @@ class NativeViewGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); + + virtual HDC GetDC(); private: gfx::PluginWindowHandle window_; @@ -74,6 +84,7 @@ class OSMesaViewGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); private: void UpdateSize(); @@ -106,6 +117,9 @@ class PbufferGLContext : public GLContext { virtual bool SwapBuffers(); virtual gfx::Size GetSize(); virtual void* GetHandle(); + virtual void SetSwapInterval(int interval); + + virtual HDC GetDC(); private: GLContextHandle context_; @@ -310,9 +324,21 @@ bool GLContext::InitializeOneOff() { return true; } + +std::string BaseWinGLContext::GetExtensions() { + if (wglGetExtensionsStringARB) { + const char* extensions = wglGetExtensionsStringARB(GetDC()); + if (extensions) { + return GLContext::GetExtensions() + " " + extensions; + } + } + + return GetExtensions(); +} + bool NativeViewGLContext::Initialize(bool multisampled) { // The GL context will render to this window. - device_context_ = GetDC(window_); + device_context_ = ::GetDC(window_); int pixel_format = multisampled ? g_multisampled_pixel_format : g_regular_pixel_format; @@ -395,6 +421,17 @@ void* NativeViewGLContext::GetHandle() { return context_; } +void NativeViewGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + if (HasExtension("WGL_EXT_swap_control") && wglSwapIntervalEXT) { + wglSwapIntervalEXT(interval); + } +} + +HDC NativeViewGLContext::GetDC() { + return device_context_; +} + bool OSMesaViewGLContext::Initialize() { // The GL context will render to this window. device_context_ = GetDC(window_); @@ -476,6 +513,12 @@ void* OSMesaViewGLContext::GetHandle() { return osmesa_context_.GetHandle(); } +void OSMesaViewGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + // Fail silently. It is legitimate to set the swap interval on a view context + // but GDI does not have those semantics. +} + void OSMesaViewGLContext::UpdateSize() { // Change back buffer size to that of window. RECT rect; @@ -628,6 +671,15 @@ void* PbufferGLContext::GetHandle() { return context_; } +void PbufferGLContext::SetSwapInterval(int interval) { + DCHECK(IsCurrent()); + NOTREACHED() << "Attempt to call SetSwapInterval on a PbufferGLContext."; +} + +HDC PbufferGLContext::GetDC() { + return device_context_; +} + GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) { switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc index 8e2242e..6bd5b87 100644 --- a/chrome/browser/gpu_process_host.cc +++ b/chrome/browser/gpu_process_host.cc @@ -91,6 +91,7 @@ bool GpuProcessHost::Init() { // Propagate relevant command line switches. static const char* const kSwitchNames[] = { switches::kUseGL, + switches::kDisableGpuVsync, switches::kDisableLogging, switches::kEnableLogging, switches::kGpuStartupDialog, diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm index 3f4ff41..bd84427 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -7,6 +7,7 @@ #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" #include "chrome/browser/chrome_thread.h" +#include "app/app_switches.h" #include "app/surface/io_surface_support_mac.h" #import "base/chrome_application_mac.h" #include "base/command_line.h" @@ -242,7 +243,11 @@ static CVReturn DrawOneAcceleratedPluginCallback( cglPixelFormat_ = (CGLPixelFormatObj)[glPixelFormat_ CGLPixelFormatObj]; // Draw at beam vsync. - GLint swapInterval = 1; + GLint swapInterval; + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) + swapInterval = 0; + else + swapInterval = 1; [glContext_ setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; // Set up a display link to do OpenGL rendering on a background thread. |