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

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: Rebased again. 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
« no previous file with comments | « 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(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); 238 DCHECK(gfx::g_driver_glx.ext.b_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)
246 return false;
247
248 // The actual clock used for the system time returned by glXGetSyncValuesOML
249 // is unspecified. In practice, the clock used is likely to be either
250 // CLOCK_REALTIME or CLOCK_MONOTONIC, so we compare the returned time to the
251 // current time according to both clocks, and assume that the returned time
252 // was produced by the clock whose current time is closest to it, subject
253 // to the restriction that the returned time must not be in the future (since
254 // it is the time of a vblank that has already occurred).
255 int64 system_time;
256 int64 media_stream_counter;
257 int64 swap_buffer_counter;
258 if (!glXGetSyncValuesOML(g_display, window_, &system_time,
259 &media_stream_counter, &swap_buffer_counter))
260 return false;
261
262 struct timespec real_time;
263 struct timespec monotonic_time;
264 clock_gettime(CLOCK_REALTIME, &real_time);
265 clock_gettime(CLOCK_MONOTONIC, &monotonic_time);
266
267 int64 real_time_in_microseconds =
268 real_time.tv_sec * base::Time::kMicrosecondsPerSecond +
269 real_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
270 int64 monotonic_time_in_microseconds =
271 monotonic_time.tv_sec * base::Time::kMicrosecondsPerSecond +
272 monotonic_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
273
274 if ((system_time > real_time_in_microseconds) &&
275 (system_time > monotonic_time_in_microseconds))
276 return false;
277
278 // We need the time according to CLOCK_MONOTONIC, so if we've been given
279 // a time from CLOCK_REALTIME, we need to convert.
280 bool time_conversion_needed =
281 (system_time > monotonic_time_in_microseconds) ||
282 (real_time_in_microseconds - system_time <
283 monotonic_time_in_microseconds - system_time);
284
285 if (time_conversion_needed) {
286 int64 time_difference =
287 real_time_in_microseconds - monotonic_time_in_microseconds;
288 *timebase = base::TimeTicks::FromInternalValue(
289 system_time - time_difference);
290 } else {
291 *timebase = base::TimeTicks::FromInternalValue(system_time);
292 }
293
294 // On platforms where glXGetMscRateOML doesn't work, we fall back to the
295 // assumption that we're displaying 60 frames per second.
296 const int64 kDefaultIntervalTime =
297 base::Time::kMicrosecondsPerSecond / 60;
298 int64 interval_time = kDefaultIntervalTime;
299 int32 numerator;
300 int32 denominator;
301 if (g_glx_get_msc_rate_oml_supported) {
302 if (glXGetMscRateOML(g_display, window_, &numerator, &denominator)) {
303 interval_time =
304 (base::Time::kMicrosecondsPerSecond * denominator) / numerator;
305 } else {
306 // Once glXGetMscRateOML has been found to fail, don't try again,
307 // since each failing call may spew an error message.
308 g_glx_get_msc_rate_oml_supported = false;
309 }
310 }
311
312 *interval = base::TimeDelta::FromMicroseconds(interval_time);
313 return true;
314 }
315
227 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() 316 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX()
228 : window_(0), 317 : window_(0),
229 config_(NULL) { 318 config_(NULL) {
230 } 319 }
231 320
232 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { 321 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() {
233 Destroy(); 322 Destroy();
234 } 323 }
235 324
236 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) 325 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 405
317 void* PbufferGLSurfaceGLX::GetConfig() { 406 void* PbufferGLSurfaceGLX::GetConfig() {
318 return config_; 407 return config_;
319 } 408 }
320 409
321 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { 410 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() {
322 Destroy(); 411 Destroy();
323 } 412 }
324 413
325 } // namespace gfx 414 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/gl_surface_glx.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698