diff options
author | jbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-01 05:21:02 +0000 |
---|---|---|
committer | jbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-01 05:21:02 +0000 |
commit | c455148a05a8bf9e39bd47f0a9433d0a0b1f301c (patch) | |
tree | 982e0fe35adfcd368318b3d1d8f00c7693240996 /ui/gl | |
parent | 6f2240ded5a22b6e3f75437966ea632b90362448 (diff) | |
download | chromium_src-c455148a05a8bf9e39bd47f0a9433d0a0b1f301c.zip chromium_src-c455148a05a8bf9e39bd47f0a9433d0a0b1f301c.tar.gz chromium_src-c455148a05a8bf9e39bd47f0a9433d0a0b1f301c.tar.bz2 |
Use DwmGetCompositionTimingInfo to get vsync info on Vista+
DwmGetCompositionTimingInfo works to find out vsync info on Vista+. Luckily using a NULL HWND (required on Win 8.1+) avoids the issue where the window starts flickering.
BUG=291390
Review URL: https://codereview.chromium.org/25102004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226152 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gl')
-rw-r--r-- | ui/gl/gl_surface_egl.cc | 3 | ||||
-rw-r--r-- | ui/gl/gl_surface_egl.h | 1 | ||||
-rw-r--r-- | ui/gl/gl_surface_win.cc | 42 |
3 files changed, 43 insertions, 3 deletions
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index d93a945..0c1871e 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc @@ -225,6 +225,7 @@ bool NativeViewGLSurfaceEGL::Initialize() { bool NativeViewGLSurfaceEGL::Initialize(VSyncProvider* sync_provider) { DCHECK(!surface_); + scoped_ptr<VSyncProvider> vsync_provider(sync_provider); if (window_ == kNullAcceleratedWidget) { LOG(ERROR) << "Trying to create surface without window."; @@ -265,7 +266,7 @@ bool NativeViewGLSurfaceEGL::Initialize(VSyncProvider* sync_provider) { supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE; if (sync_provider) - vsync_provider_.reset(sync_provider); + vsync_provider_.swap(vsync_provider); else if (g_egl_sync_control_supported) vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_)); return true; diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h index fcac714..68a99af 100644 --- a/ui/gl/gl_surface_egl.h +++ b/ui/gl/gl_surface_egl.h @@ -67,6 +67,7 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL { virtual VSyncProvider* GetVSyncProvider() OVERRIDE; // Create a NativeViewGLSurfaceEGL with an externally provided VSyncProvider. + // Takes ownership of the VSyncProvider. virtual bool Initialize(VSyncProvider* sync_provider); protected: diff --git a/ui/gl/gl_surface_win.cc b/ui/gl/gl_surface_win.cc index 766e123..d535c06 100644 --- a/ui/gl/gl_surface_win.cc +++ b/ui/gl/gl_surface_win.cc @@ -4,9 +4,12 @@ #include "ui/gl/gl_surface.h" +#include <dwmapi.h> + #include "base/debug/trace_event.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/win/windows_version.h" #include "third_party/mesa/src/include/GL/osmesa.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_implementation.h" @@ -39,6 +42,37 @@ class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa { DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa); }; +class DWMVSyncProvider : public VSyncProvider { + public: + explicit DWMVSyncProvider() {} + + virtual ~DWMVSyncProvider() {} + + virtual void GetVSyncParameters(const UpdateVSyncCallback& callback) { + TRACE_EVENT0("gpu", "DWMVSyncProvider::GetVSyncParameters"); + DWM_TIMING_INFO timing_info; + timing_info.cbSize = sizeof(timing_info); + HRESULT result = DwmGetCompositionTimingInfo(NULL, &timing_info); + if (result != S_OK) + return; + + base::TimeTicks timebase = base::TimeTicks::FromQPCValue( + static_cast<LONGLONG>(timing_info.qpcVBlank)); + // Swap the numerator/denominator to convert frequency to period. + if (timing_info.rateRefresh.uiDenominator > 0 && + timing_info.rateRefresh.uiNumerator > 0) { + base::TimeDelta interval = base::TimeDelta::FromMicroseconds( + timing_info.rateRefresh.uiDenominator * + base::Time::kMicrosecondsPerSecond / + timing_info.rateRefresh.uiNumerator); + callback.Run(timebase, interval); + } + } + + private: + DISALLOW_COPY_AND_ASSIGN(DWMVSyncProvider); +}; + // Helper routine that does one-off initialization like determining the // pixel format and initializing the GL bindings. bool GLSurface::InitializeOneOffInternal() { @@ -185,8 +219,12 @@ scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( return surface; } case kGLImplementationEGLGLES2: { - scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceEGL(window)); - if (!surface->Initialize()) + scoped_refptr<NativeViewGLSurfaceEGL> surface( + new NativeViewGLSurfaceEGL(window)); + DWMVSyncProvider* sync_provider = NULL; + if (base::win::GetVersion() >= base::win::VERSION_VISTA) + sync_provider = new DWMVSyncProvider; + if (!surface->Initialize(sync_provider)) return NULL; return surface; |