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

Side by Side Diff: ui/gl/gl_surface_glx.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
« ui/compositor/compositor.cc ('K') | « ui/gl/gl_surface_glx.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 extern "C" { 5 extern "C" {
6 #include <X11/Xlib.h> 6 #include <X11/Xlib.h>
7 } 7 }
8 8
9 #include "ui/gl/gl_surface_glx.h" 9 #include "ui/gl/gl_surface_glx.h"
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop.h" 15 #include "base/message_loop.h"
16 #include "base/process_util.h" 16 #include "base/process_util.h"
17 #include "base/time.h"
17 #include "third_party/mesa/MesaLib/include/GL/osmesa.h" 18 #include "third_party/mesa/MesaLib/include/GL/osmesa.h"
18 #include "ui/base/x/x11_util.h" 19 #include "ui/base/x/x11_util.h"
19 #include "ui/gl/gl_bindings.h" 20 #include "ui/gl/gl_bindings.h"
20 #include "ui/gl/gl_implementation.h" 21 #include "ui/gl/gl_implementation.h"
21 22
22 namespace gfx { 23 namespace gfx {
23 24
24 namespace { 25 namespace {
25 26
26 // scoped_ptr functor for XFree(). Use as follows: 27 // scoped_ptr functor for XFree(). Use as follows:
27 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...); 28 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...);
28 // where "XVisualInfo" is any X type that is freed with XFree. 29 // where "XVisualInfo" is any X type that is freed with XFree.
29 class ScopedPtrXFree { 30 class ScopedPtrXFree {
30 public: 31 public:
31 void operator()(void* x) const { 32 void operator()(void* x) const {
32 ::XFree(x); 33 ::XFree(x);
33 } 34 }
34 }; 35 };
35 36
36 Display* g_display; 37 Display* g_display;
37 const char* g_glx_extensions = NULL; 38 const char* g_glx_extensions = NULL;
38 bool g_glx_create_context_robustness_supported = false; 39 bool g_glx_create_context_robustness_supported = false;
39 bool g_glx_texture_from_pixmap_supported = false; 40 bool g_glx_texture_from_pixmap_supported = false;
41 bool g_glx_oml_sync_control_supported = false;
42
43 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a
44 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML
45 // always fails even though GLX_OML_sync_control is reported as being supported.
46 bool g_glx_get_msc_rate_oml_supported = false;
40 47
41 } // namespace 48 } // namespace
42 49
43 GLSurfaceGLX::GLSurfaceGLX() {} 50 GLSurfaceGLX::GLSurfaceGLX() {}
44 51
45 bool GLSurfaceGLX::InitializeOneOff() { 52 bool GLSurfaceGLX::InitializeOneOff() {
46 static bool initialized = false; 53 static bool initialized = false;
47 if (initialized) 54 if (initialized)
48 return true; 55 return true;
49 56
(...skipping 12 matching lines...) Expand all
62 if (major == 1 && minor < 3) { 69 if (major == 1 && minor < 3) {
63 LOG(ERROR) << "GLX 1.3 or later is required."; 70 LOG(ERROR) << "GLX 1.3 or later is required.";
64 return false; 71 return false;
65 } 72 }
66 73
67 g_glx_extensions = glXQueryExtensionsString(g_display, 0); 74 g_glx_extensions = glXQueryExtensionsString(g_display, 0);
68 g_glx_create_context_robustness_supported = 75 g_glx_create_context_robustness_supported =
69 HasGLXExtension("GLX_ARB_create_context_robustness"); 76 HasGLXExtension("GLX_ARB_create_context_robustness");
70 g_glx_texture_from_pixmap_supported = 77 g_glx_texture_from_pixmap_supported =
71 HasGLXExtension("GLX_EXT_texture_from_pixmap"); 78 HasGLXExtension("GLX_EXT_texture_from_pixmap");
79 g_glx_oml_sync_control_supported =
80 HasGLXExtension("GLX_OML_sync_control");
81 g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported;
82
72 83
73 initialized = true; 84 initialized = true;
74 return true; 85 return true;
75 } 86 }
76 87
77 // static 88 // static
78 const char* GLSurfaceGLX::GetGLXExtensions() { 89 const char* GLSurfaceGLX::GetGLXExtensions() {
79 return g_glx_extensions; 90 return g_glx_extensions;
80 } 91 }
81 92
82 // static 93 // static
83 bool GLSurfaceGLX::HasGLXExtension(const char* name) { 94 bool GLSurfaceGLX::HasGLXExtension(const char* name) {
84 return ExtensionsContain(GetGLXExtensions(), name); 95 return ExtensionsContain(GetGLXExtensions(), name);
85 } 96 }
86 97
87 // static 98 // static
88 bool GLSurfaceGLX::IsCreateContextRobustnessSupported() { 99 bool GLSurfaceGLX::IsCreateContextRobustnessSupported() {
89 return g_glx_create_context_robustness_supported; 100 return g_glx_create_context_robustness_supported;
90 } 101 }
91 102
92 // static 103 // static
93 bool GLSurfaceGLX::IsTextureFromPixmapSupported() { 104 bool GLSurfaceGLX::IsTextureFromPixmapSupported() {
94 return g_glx_texture_from_pixmap_supported; 105 return g_glx_texture_from_pixmap_supported;
95 } 106 }
96 107
108 // static
109 bool GLSurfaceGLX::IsOMLSyncControlSupported() {
110 return g_glx_oml_sync_control_supported;
111 }
112
97 void* GLSurfaceGLX::GetDisplay() { 113 void* GLSurfaceGLX::GetDisplay() {
98 return g_display; 114 return g_display;
99 } 115 }
100 116
101 GLSurfaceGLX::~GLSurfaceGLX() {} 117 GLSurfaceGLX::~GLSurfaceGLX() {}
102 118
103 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) 119 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window)
104 : window_(window), 120 : window_(window),
105 config_(NULL) { 121 config_(NULL) {
106 } 122 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 return config_; 233 return config_;
218 } 234 }
219 235
220 bool NativeViewGLSurfaceGLX::PostSubBuffer( 236 bool NativeViewGLSurfaceGLX::PostSubBuffer(
221 int x, int y, int width, int height) { 237 int x, int y, int width, int height) {
222 DCHECK(g_GLX_MESA_copy_sub_buffer); 238 DCHECK(g_GLX_MESA_copy_sub_buffer);
223 glXCopySubBufferMESA(g_display, window_, x, y, width, height); 239 glXCopySubBufferMESA(g_display, window_, x, y, width, height);
224 return true; 240 return true;
225 } 241 }
226 242
243 bool NativeViewGLSurfaceGLX::GetVSyncParameters(base::TimeTicks* timebase,
244 base::TimeDelta* interval) {
245 if (g_glx_oml_sync_control_supported) {
jonathan.backer 2012/10/26 20:31:03 I'm concerned that this may be per monitor (in the
ajuma 2012/10/29 17:02:26 AIUI, since we only XOpenDisplay() once, we're onl
246 // The actual clock used for the system time returned by glXGetSyncValuesOML
247 // is unspecified. In practice, the clock used is likely to be either
248 // CLOCK_REALTIME or CLOCK_MONOTONIC. We test if the returned time is
249 // "close" (within a minute) to the current time according to either of
250 // these clocks, and if so, we assume that the corresponding clock was used
251 // to produce this time.
252 int64 system_time;
253 int64 media_stream_counter;
254 int64 swap_buffer_counter;
255 if (glXGetSyncValuesOML(g_display, window_, &system_time,
256 &media_stream_counter, &swap_buffer_counter)) {
257 struct timespec real_time;
258 struct timespec monotonic_time;
259 clock_gettime(CLOCK_REALTIME, &real_time);
260 clock_gettime(CLOCK_MONOTONIC, &monotonic_time);
261
262 int64 real_time_in_microseconds =
263 real_time.tv_sec * base::Time::kMicrosecondsPerSecond +
264 real_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
265 int64 monotonic_time_in_microseconds =
266 monotonic_time.tv_sec * base::Time::kMicrosecondsPerSecond +
267 monotonic_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
268
269 if (real_time_in_microseconds - system_time <=
270 base::Time::kMicrosecondsPerMinute) {
271 // Convert from CLOCK_REALTIME to CLOCK_MONOTONIC.
272 int64 time_difference =
273 real_time_in_microseconds - monotonic_time_in_microseconds;
274 *timebase = base::TimeTicks::FromInternalValue(
275 system_time - time_difference);
276 } else if (monotonic_time_in_microseconds - system_time <=
277 base::Time::kMicrosecondsPerMinute) {
278 *timebase = base::TimeTicks::FromInternalValue(system_time);
279 } else {
280 // We don't know how to interpret system_time.
281 return false;
282 }
283
284 // On platforms where glXGetMscRateOML doesn't work, we fall back to the
285 // assumption that we're displaying 60 frames per second.
286 const int64 kDefaultIntervalTime =
287 base::Time::kMicrosecondsPerSecond / 60;
288 int64 interval_time = kDefaultIntervalTime;
289 int32 numerator;
290 int32 denominator;
291 if (g_glx_get_msc_rate_oml_supported) {
292 if (glXGetMscRateOML(g_display, window_, &numerator, &denominator)) {
293 interval_time =
294 (base::Time::kMicrosecondsPerSecond * denominator) / numerator;
295 } else {
296 // Once glXGetMscRateOML has been found to fail, don't try again,
297 // since each failing call may spew an error message.
298 g_glx_get_msc_rate_oml_supported = false;
299 }
300 }
301
302 *interval = base::TimeDelta::FromMicroseconds(interval_time);
303 return true;
304 }
305 }
306
307 return false;
308 }
309
227 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() 310 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX()
228 : window_(0), 311 : window_(0),
229 config_(NULL) { 312 config_(NULL) {
230 } 313 }
231 314
232 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { 315 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() {
233 Destroy(); 316 Destroy();
234 } 317 }
235 318
236 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) 319 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 399
317 void* PbufferGLSurfaceGLX::GetConfig() { 400 void* PbufferGLSurfaceGLX::GetConfig() {
318 return config_; 401 return config_;
319 } 402 }
320 403
321 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { 404 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() {
322 Destroy(); 405 Destroy();
323 } 406 }
324 407
325 } // namespace gfx 408 } // namespace gfx
OLDNEW
« ui/compositor/compositor.cc ('K') | « ui/gl/gl_surface_glx.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698