summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-07 23:19:16 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-07 23:19:16 +0000
commit1c0585d585bc9f88ee177553b66e0025d7fe3aa0 (patch)
treedcce9c6dcbe4634483104b236a87e42d694bbeb1
parentfd3a7df6c4caaeceb8402daa2c1b357c7f78331f (diff)
downloadchromium_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.cc3
-rw-r--r--app/app_switches.h1
-rw-r--r--app/gfx/gl/generate_bindings.py3
-rw-r--r--app/gfx/gl/gl_context.cc17
-rw-r--r--app/gfx/gl/gl_context.h10
-rw-r--r--app/gfx/gl/gl_context_egl.cc18
-rw-r--r--app/gfx/gl/gl_context_egl.h5
-rw-r--r--app/gfx/gl/gl_context_linux.cc43
-rw-r--r--app/gfx/gl/gl_context_mac.cc6
-rw-r--r--app/gfx/gl/gl_context_osmesa.cc5
-rw-r--r--app/gfx/gl/gl_context_osmesa.h1
-rw-r--r--app/gfx/gl/gl_context_stub.h3
-rw-r--r--app/gfx/gl/gl_context_win.cc56
-rw-r--r--chrome/browser/gpu_process_host.cc1
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm7
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.