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

Side by Side Diff: ui/gl/gl_surface_glx.cc

Issue 2291373002: Fix SGI_video_sync cpu usage and rendering issues with Nvidia driver. (Closed)
Patch Set: rebase Created 4 years, 3 months 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
« no previous file with comments | « content/common/sandbox_linux/bpf_gpu_policy_linux.cc ('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 #include "ui/gl/gl_surface_glx.h" 5 #include "ui/gl/gl_surface_glx.h"
6 6
7 extern "C" { 7 extern "C" {
8 #include <X11/Xlib.h> 8 #include <X11/Xlib.h>
9 } 9 }
10 #include <memory> 10 #include <memory>
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 bool g_glx_texture_from_pixmap_supported = false; 43 bool g_glx_texture_from_pixmap_supported = false;
44 bool g_glx_oml_sync_control_supported = false; 44 bool g_glx_oml_sync_control_supported = false;
45 45
46 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a 46 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a
47 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML 47 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML
48 // always fails even though GLX_OML_sync_control is reported as being supported. 48 // always fails even though GLX_OML_sync_control is reported as being supported.
49 bool g_glx_get_msc_rate_oml_supported = false; 49 bool g_glx_get_msc_rate_oml_supported = false;
50 50
51 bool g_glx_sgi_video_sync_supported = false; 51 bool g_glx_sgi_video_sync_supported = false;
52 52
53 static const int kGetVSyncParametersMinSeconds =
54 #if defined(OS_LINUX)
55 // See crbug.com/373489
56 // On Linux, querying the vsync parameters might burn CPU for up to an
57 // entire vsync, so we only query periodically to reduce CPU usage.
58 // 5 seconds is chosen somewhat abitrarily as a balance between:
59 // a) Drift in the phase of our signal.
60 // b) Potential janks from periodically pegging the CPU.
61 5;
62 #else
63 0;
64 #endif
65
66 GLXFBConfig GetConfigForWindow(Display* display, 53 GLXFBConfig GetConfigForWindow(Display* display,
67 gfx::AcceleratedWidget window) { 54 gfx::AcceleratedWidget window) {
68 DCHECK(window != 0); 55 DCHECK(window != 0);
69 56
70 // This code path is expensive, but we only take it when 57 // This code path is expensive, but we only take it when
71 // attempting to use GLX_ARB_create_context_robustness, in which 58 // attempting to use GLX_ARB_create_context_robustness, in which
72 // case we need a GLXFBConfig for the window in order to create a 59 // case we need a GLXFBConfig for the window in order to create a
73 // context for it. 60 // context for it.
74 // 61 //
75 // TODO(kbr): this is not a reliable code path. On platforms which 62 // TODO(kbr): this is not a reliable code path. On platforms which
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 found = true; 98 found = true;
112 break; 99 break;
113 } 100 }
114 } 101 }
115 if (found) { 102 if (found) {
116 return configs.get()[i]; 103 return configs.get()[i];
117 } 104 }
118 return nullptr; 105 return nullptr;
119 } 106 }
120 107
108 bool CreateDummyWindow(Display* display) {
109 DCHECK(display);
110 gfx::AcceleratedWidget parent_window =
111 RootWindow(display, DefaultScreen(display));
112 // We create a window with CopyFromParent visual so that we have the same
113 // visual as NativeViewGLSurfaceGLX (i.e. same GLXFBConfig), to ensure
114 // contexts are compatible and can be made current with either.
115 gfx::AcceleratedWidget window =
116 XCreateWindow(display, parent_window, 0, 0, 1, 1, 0, CopyFromParent,
117 InputOutput, CopyFromParent, 0, nullptr);
118 if (!window) {
119 LOG(ERROR) << "XCreateWindow failed";
120 return false;
121 }
122 GLXFBConfig config = GetConfigForWindow(display, window);
123 GLXWindow glx_window = glXCreateWindow(display, config, window, nullptr);
124 if (!glx_window) {
125 LOG(ERROR) << "glXCreateWindow failed";
126 XDestroyWindow(display, window);
127 return false;
128 }
129 glXDestroyWindow(display, glx_window);
130 XDestroyWindow(display, window);
131 return true;
132 }
133
121 class OMLSyncControlVSyncProvider : public SyncControlVSyncProvider { 134 class OMLSyncControlVSyncProvider : public SyncControlVSyncProvider {
122 public: 135 public:
123 explicit OMLSyncControlVSyncProvider(GLXWindow glx_window) 136 explicit OMLSyncControlVSyncProvider(GLXWindow glx_window)
124 : SyncControlVSyncProvider(), 137 : SyncControlVSyncProvider(), glx_window_(glx_window) {}
125 glx_window_(glx_window) {
126 }
127 138
128 ~OMLSyncControlVSyncProvider() override {} 139 ~OMLSyncControlVSyncProvider() override {}
129 140
130 protected: 141 protected:
131 bool GetSyncValues(int64_t* system_time, 142 bool GetSyncValues(int64_t* system_time,
132 int64_t* media_stream_counter, 143 int64_t* media_stream_counter,
133 int64_t* swap_buffer_counter) override { 144 int64_t* swap_buffer_counter) override {
134 return glXGetSyncValuesOML(g_display, glx_window_, system_time, 145 return glXGetSyncValuesOML(g_display, glx_window_, system_time,
135 media_stream_counter, swap_buffer_counter); 146 media_stream_counter, swap_buffer_counter);
136 } 147 }
(...skipping 11 matching lines...) Expand all
148 159
149 return true; 160 return true;
150 } 161 }
151 162
152 private: 163 private:
153 GLXWindow glx_window_; 164 GLXWindow glx_window_;
154 165
155 DISALLOW_COPY_AND_ASSIGN(OMLSyncControlVSyncProvider); 166 DISALLOW_COPY_AND_ASSIGN(OMLSyncControlVSyncProvider);
156 }; 167 };
157 168
158 class SGIVideoSyncThread 169 class SGIVideoSyncThread : public base::Thread,
159 : public base::Thread, 170 public base::NonThreadSafe,
160 public base::NonThreadSafe, 171 public base::RefCounted<SGIVideoSyncThread> {
161 public base::RefCounted<SGIVideoSyncThread> {
162 public: 172 public:
163 static scoped_refptr<SGIVideoSyncThread> Create() { 173 static scoped_refptr<SGIVideoSyncThread> Create() {
164 if (!g_video_sync_thread) { 174 if (!g_video_sync_thread) {
165 g_video_sync_thread = new SGIVideoSyncThread(); 175 g_video_sync_thread = new SGIVideoSyncThread();
166 g_video_sync_thread->Start(); 176 g_video_sync_thread->Start();
167 } 177 }
168 return g_video_sync_thread; 178 return g_video_sync_thread;
169 } 179 }
170 180
171 private: 181 private:
172 friend class base::RefCounted<SGIVideoSyncThread>; 182 friend class base::RefCounted<SGIVideoSyncThread>;
173 183
174 SGIVideoSyncThread() : base::Thread("SGI_video_sync") { 184 SGIVideoSyncThread() : base::Thread("SGI_video_sync") {
175 DCHECK(CalledOnValidThread()); 185 DCHECK(CalledOnValidThread());
176 } 186 }
177 187
178 ~SGIVideoSyncThread() override { 188 ~SGIVideoSyncThread() override {
179 DCHECK(CalledOnValidThread()); 189 DCHECK(CalledOnValidThread());
180 g_video_sync_thread = nullptr; 190 g_video_sync_thread = nullptr;
181 Stop(); 191 Stop();
182 } 192 }
183 193
184 static SGIVideoSyncThread* g_video_sync_thread; 194 static SGIVideoSyncThread* g_video_sync_thread;
185 195
186 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncThread); 196 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncThread);
187 }; 197 };
188 198
189 class SGIVideoSyncProviderThreadShim { 199 class SGIVideoSyncProviderThreadShim {
190 public: 200 public:
191 explicit SGIVideoSyncProviderThreadShim(GLXFBConfig config, 201 explicit SGIVideoSyncProviderThreadShim(gfx::AcceleratedWidget parent_window)
192 GLXWindow glx_window) 202 : parent_window_(parent_window),
193 : config_(config), 203 window_(0),
194 glx_window_(glx_window), 204 glx_window_(0),
195 context_(nullptr),
196 task_runner_(base::ThreadTaskRunnerHandle::Get()), 205 task_runner_(base::ThreadTaskRunnerHandle::Get()),
197 cancel_vsync_flag_(), 206 cancel_vsync_flag_(),
198 vsync_lock_() { 207 vsync_lock_() {
199 // This ensures that creation of |window_| has occured when this shim 208 // This ensures that creation of |parent_window_| has occured when this shim
200 // is executing in the same process as the call to create |window_|. 209 // is executing in the same thread as the call to create |parent_window_|.
201 XSync(g_display, False); 210 XSync(g_display, False);
202 } 211 }
203 212
204 virtual ~SGIVideoSyncProviderThreadShim() { 213 virtual ~SGIVideoSyncProviderThreadShim() {
205 if (context_) { 214 if (glx_window_)
206 glXDestroyContext(display_, context_); 215 glXDestroyWindow(display_, glx_window_);
207 context_ = nullptr; 216
208 } 217 if (window_)
218 XDestroyWindow(display_, window_);
209 } 219 }
210 220
211 base::CancellationFlag* cancel_vsync_flag() { 221 base::CancellationFlag* cancel_vsync_flag() { return &cancel_vsync_flag_; }
212 return &cancel_vsync_flag_;
213 }
214 222
215 base::Lock* vsync_lock() { 223 base::Lock* vsync_lock() { return &vsync_lock_; }
216 return &vsync_lock_;
217 }
218 224
219 void Initialize() { 225 void Initialize() {
220 DCHECK(display_); 226 DCHECK(display_);
221 227
222 context_ = 228 window_ =
223 glXCreateNewContext(display_, config_, GLX_RGBA_TYPE, nullptr, True); 229 XCreateWindow(display_, parent_window_, 0, 0, 1, 1, 0, CopyFromParent,
230 InputOutput, CopyFromParent, 0, nullptr);
231 if (!window_) {
232 LOG(ERROR) << "video_sync: XCreateWindow failed";
233 return;
234 }
224 235
225 DCHECK(nullptr != context_); 236 GLXFBConfig config = GetConfigForWindow(display_, window_);
237 DCHECK(config);
238
239 glx_window_ = glXCreateWindow(display_, config, window_, nullptr);
240 if (!glx_window_) {
241 LOG(ERROR) << "video_sync: glXCreateWindow failed";
242 return;
243 }
244
245 // Create the context only once for all vsync providers.
246 if (!context_) {
247 context_ =
248 glXCreateNewContext(display_, config, GLX_RGBA_TYPE, nullptr, True);
249 if (!context_)
250 LOG(ERROR) << "video_sync: glXCreateNewContext failed";
251 }
226 } 252 }
227 253
228 void GetVSyncParameters( 254 void GetVSyncParameters(
229 const gfx::VSyncProvider::UpdateVSyncCallback& callback) { 255 const gfx::VSyncProvider::UpdateVSyncCallback& callback) {
230 base::TimeTicks now; 256 base::TimeTicks now;
231 { 257 {
232 // Don't allow |window_| destruction while we're probing vsync. 258 // Don't allow |window_| destruction while we're probing vsync.
233 base::AutoLock locked(vsync_lock_); 259 base::AutoLock locked(vsync_lock_);
234 260
235 if (!context_ || cancel_vsync_flag_.IsSet()) 261 if (!context_ || cancel_vsync_flag_.IsSet())
236 return; 262 return;
237 263
238 glXMakeContextCurrent(display_, glx_window_, glx_window_, context_); 264 glXMakeContextCurrent(display_, glx_window_, glx_window_, context_);
239 265
240 unsigned int retrace_count = 0; 266 unsigned int retrace_count = 0;
241 if (glXWaitVideoSyncSGI(1, 0, &retrace_count) != 0) 267 if (glXWaitVideoSyncSGI(1, 0, &retrace_count) != 0)
242 return; 268 return;
243 269
244 TRACE_EVENT_INSTANT0("gpu", "vblank", TRACE_EVENT_SCOPE_THREAD); 270 TRACE_EVENT_INSTANT0("gpu", "vblank", TRACE_EVENT_SCOPE_THREAD);
245 now = base::TimeTicks::Now(); 271 now = base::TimeTicks::Now();
246 272
247 glXMakeContextCurrent(display_, 0, 0, nullptr); 273 glXMakeContextCurrent(display_, 0, 0, nullptr);
248 } 274 }
249 275
250 const base::TimeDelta kDefaultInterval = 276 const base::TimeDelta kDefaultInterval =
251 base::TimeDelta::FromSeconds(1) / 60; 277 base::TimeDelta::FromSeconds(1) / 60;
252 278
253 task_runner_->PostTask( 279 task_runner_->PostTask(FROM_HERE,
254 FROM_HERE, base::Bind(callback, now, kDefaultInterval)); 280 base::Bind(callback, now, kDefaultInterval));
255 } 281 }
256 282
257 private: 283 private:
258 // For initialization of display_ in GLSurface::InitializeOneOff before 284 // For initialization of display_ in GLSurface::InitializeOneOff before
259 // the sandbox goes up. 285 // the sandbox goes up.
260 friend class gl::GLSurfaceGLX; 286 friend class gl::GLSurfaceGLX;
261 287
288 // We only need one Display and GLXContext because we only use one thread for
289 // SGI_video_sync. The display is created in GLSurfaceGLX::InitializeOneOff
290 // and the context is created the first time a vsync provider is initialized.
262 static Display* display_; 291 static Display* display_;
292 static GLXContext context_;
263 293
264 GLXFBConfig config_; 294 gfx::AcceleratedWidget parent_window_;
295
296 gfx::AcceleratedWidget window_;
265 GLXWindow glx_window_; 297 GLXWindow glx_window_;
266 GLXContext context_;
267 298
268 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 299 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
269 300
270 base::CancellationFlag cancel_vsync_flag_; 301 base::CancellationFlag cancel_vsync_flag_;
271 base::Lock vsync_lock_; 302 base::Lock vsync_lock_;
272 303
273 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncProviderThreadShim); 304 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncProviderThreadShim);
274 }; 305 };
275 306
276 class SGIVideoSyncVSyncProvider 307 class SGIVideoSyncVSyncProvider
277 : public gfx::VSyncProvider, 308 : public gfx::VSyncProvider,
278 public base::SupportsWeakPtr<SGIVideoSyncVSyncProvider> { 309 public base::SupportsWeakPtr<SGIVideoSyncVSyncProvider> {
279 public: 310 public:
280 explicit SGIVideoSyncVSyncProvider(GLXFBConfig config, GLXWindow glx_window) 311 explicit SGIVideoSyncVSyncProvider(gfx::AcceleratedWidget parent_window)
281 : vsync_thread_(SGIVideoSyncThread::Create()), 312 : vsync_thread_(SGIVideoSyncThread::Create()),
282 shim_(new SGIVideoSyncProviderThreadShim(config, glx_window)), 313 shim_(new SGIVideoSyncProviderThreadShim(parent_window)),
283 cancel_vsync_flag_(shim_->cancel_vsync_flag()), 314 cancel_vsync_flag_(shim_->cancel_vsync_flag()),
284 vsync_lock_(shim_->vsync_lock()) { 315 vsync_lock_(shim_->vsync_lock()) {
285 vsync_thread_->task_runner()->PostTask( 316 vsync_thread_->task_runner()->PostTask(
286 FROM_HERE, base::Bind(&SGIVideoSyncProviderThreadShim::Initialize, 317 FROM_HERE, base::Bind(&SGIVideoSyncProviderThreadShim::Initialize,
287 base::Unretained(shim_.get()))); 318 base::Unretained(shim_.get())));
288 } 319 }
289 320
290 ~SGIVideoSyncVSyncProvider() override { 321 ~SGIVideoSyncVSyncProvider() override {
291 { 322 {
292 base::AutoLock locked(*vsync_lock_); 323 base::AutoLock locked(*vsync_lock_);
293 cancel_vsync_flag_->Set(); 324 cancel_vsync_flag_->Set();
294 } 325 }
295 326
296 // Hand-off |shim_| to be deleted on the |vsync_thread_|. 327 // Hand-off |shim_| to be deleted on the |vsync_thread_|.
297 vsync_thread_->task_runner()->DeleteSoon(FROM_HERE, shim_.release()); 328 vsync_thread_->task_runner()->DeleteSoon(FROM_HERE, shim_.release());
298 } 329 }
299 330
300 void GetVSyncParameters( 331 void GetVSyncParameters(
301 const gfx::VSyncProvider::UpdateVSyncCallback& callback) override { 332 const gfx::VSyncProvider::UpdateVSyncCallback& callback) override {
302 if (kGetVSyncParametersMinSeconds > 0) {
303 base::TimeTicks now = base::TimeTicks::Now();
304 base::TimeDelta delta = now - last_get_vsync_parameters_time_;
305 if (delta.InSeconds() < kGetVSyncParametersMinSeconds)
306 return;
307 last_get_vsync_parameters_time_ = now;
308 }
309
310 // Only one outstanding request per surface. 333 // Only one outstanding request per surface.
311 if (!pending_callback_) { 334 if (!pending_callback_) {
312 pending_callback_.reset( 335 pending_callback_.reset(
313 new gfx::VSyncProvider::UpdateVSyncCallback(callback)); 336 new gfx::VSyncProvider::UpdateVSyncCallback(callback));
314 vsync_thread_->task_runner()->PostTask( 337 vsync_thread_->task_runner()->PostTask(
315 FROM_HERE, 338 FROM_HERE,
316 base::Bind( 339 base::Bind(
317 &SGIVideoSyncProviderThreadShim::GetVSyncParameters, 340 &SGIVideoSyncProviderThreadShim::GetVSyncParameters,
318 base::Unretained(shim_.get()), 341 base::Unretained(shim_.get()),
319 base::Bind(&SGIVideoSyncVSyncProvider::PendingCallbackRunner, 342 base::Bind(&SGIVideoSyncVSyncProvider::PendingCallbackRunner,
(...skipping 15 matching lines...) Expand all
335 std::unique_ptr<SGIVideoSyncProviderThreadShim> shim_; 358 std::unique_ptr<SGIVideoSyncProviderThreadShim> shim_;
336 359
337 std::unique_ptr<gfx::VSyncProvider::UpdateVSyncCallback> pending_callback_; 360 std::unique_ptr<gfx::VSyncProvider::UpdateVSyncCallback> pending_callback_;
338 361
339 // Raw pointers to sync primitives owned by the shim_. 362 // Raw pointers to sync primitives owned by the shim_.
340 // These will only be referenced before we post a task to destroy 363 // These will only be referenced before we post a task to destroy
341 // the shim_, so they are safe to access. 364 // the shim_, so they are safe to access.
342 base::CancellationFlag* cancel_vsync_flag_; 365 base::CancellationFlag* cancel_vsync_flag_;
343 base::Lock* vsync_lock_; 366 base::Lock* vsync_lock_;
344 367
345 base::TimeTicks last_get_vsync_parameters_time_;
346
347 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider); 368 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider);
348 }; 369 };
349 370
350 SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = nullptr; 371 SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = nullptr;
351 372
352 // In order to take advantage of GLX_SGI_video_sync, we need a display 373 // In order to take advantage of GLX_SGI_video_sync, we need a display
353 // for use on a separate thread. We must allocate this before the sandbox 374 // for use on a separate thread. We must allocate this before the sandbox
354 // goes up (rather than on-demand when we start the thread). 375 // goes up (rather than on-demand when we start the thread).
355 Display* SGIVideoSyncProviderThreadShim::display_ = nullptr; 376 Display* SGIVideoSyncProviderThreadShim::display_ = nullptr;
377 GLXContext SGIVideoSyncProviderThreadShim::context_ = 0;
356 378
357 } // namespace 379 } // namespace
358 380
359 GLSurfaceGLX::GLSurfaceGLX() {} 381 GLSurfaceGLX::GLSurfaceGLX() {}
360 382
361 bool GLSurfaceGLX::InitializeOneOff() { 383 bool GLSurfaceGLX::InitializeOneOff() {
362 static bool initialized = false; 384 static bool initialized = false;
363 if (initialized) 385 if (initialized)
364 return true; 386 return true;
365 387
(...skipping 14 matching lines...) Expand all
380 if (!glXQueryVersion(g_display, &major, &minor)) { 402 if (!glXQueryVersion(g_display, &major, &minor)) {
381 LOG(ERROR) << "glxQueryVersion failed"; 403 LOG(ERROR) << "glxQueryVersion failed";
382 return false; 404 return false;
383 } 405 }
384 406
385 if (major == 1 && minor < 3) { 407 if (major == 1 && minor < 3) {
386 LOG(ERROR) << "GLX 1.3 or later is required."; 408 LOG(ERROR) << "GLX 1.3 or later is required.";
387 return false; 409 return false;
388 } 410 }
389 411
390 g_glx_context_create = 412 g_glx_context_create = HasGLXExtension("GLX_ARB_create_context");
391 HasGLXExtension("GLX_ARB_create_context");
392 g_glx_create_context_robustness_supported = 413 g_glx_create_context_robustness_supported =
393 HasGLXExtension("GLX_ARB_create_context_robustness"); 414 HasGLXExtension("GLX_ARB_create_context_robustness");
394 g_glx_create_context_profile_supported = 415 g_glx_create_context_profile_supported =
395 HasGLXExtension("GLX_ARB_create_context_profile"); 416 HasGLXExtension("GLX_ARB_create_context_profile");
396 g_glx_create_context_profile_es2_supported = 417 g_glx_create_context_profile_es2_supported =
397 HasGLXExtension("GLX_ARB_create_context_es2_profile"); 418 HasGLXExtension("GLX_ARB_create_context_es2_profile");
398 g_glx_texture_from_pixmap_supported = 419 g_glx_texture_from_pixmap_supported =
399 HasGLXExtension("GLX_EXT_texture_from_pixmap"); 420 HasGLXExtension("GLX_EXT_texture_from_pixmap");
400 g_glx_oml_sync_control_supported = 421 g_glx_oml_sync_control_supported = HasGLXExtension("GLX_OML_sync_control");
401 HasGLXExtension("GLX_OML_sync_control");
402 g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported; 422 g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported;
403 g_glx_sgi_video_sync_supported = 423 g_glx_sgi_video_sync_supported = HasGLXExtension("GLX_SGI_video_sync");
404 HasGLXExtension("GLX_SGI_video_sync") &&
405 base::CommandLine::ForCurrentProcess()->HasSwitch(
406 switches::kEnableSgiVideoSync);
407 424
408 if (!g_glx_get_msc_rate_oml_supported && g_glx_sgi_video_sync_supported) 425 // We create a dummy unmapped window for both the main Display and the video
409 SGIVideoSyncProviderThreadShim::display_ = gfx::OpenNewXDisplay(); 426 // sync Display so that the Nvidia driver can initialize itself before the
427 // sandbox is set up.
428 // Unfortunately some fds e.g. /dev/nvidia0 are cached per thread and because
429 // we can't start threads before the sandbox is set up, these are accessed
430 // through the broker process. See GpuProcessPolicy::InitGpuBrokerProcess.
431 if (!CreateDummyWindow(g_display)) {
432 LOG(ERROR) << "CreateDummyWindow(g_display) failed";
433 return false;
434 }
435
436 if (!g_glx_get_msc_rate_oml_supported && g_glx_sgi_video_sync_supported) {
437 Display* video_sync_display = gfx::OpenNewXDisplay();
438 if (!CreateDummyWindow(video_sync_display)) {
439 LOG(ERROR) << "CreateDummyWindow(video_sync_display) failed";
440 return false;
441 }
442 SGIVideoSyncProviderThreadShim::display_ = video_sync_display;
443 }
410 444
411 initialized = true; 445 initialized = true;
412 return true; 446 return true;
413 } 447 }
414 448
415 // static 449 // static
416 const char* GLSurfaceGLX::GetGLXExtensions() { 450 const char* GLSurfaceGLX::GetGLXExtensions() {
417 return glXQueryExtensionsString(g_display, 0); 451 return glXQueryExtensionsString(g_display, 0);
418 } 452 }
419 453
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 return g_glx_oml_sync_control_supported; 486 return g_glx_oml_sync_control_supported;
453 } 487 }
454 488
455 void* GLSurfaceGLX::GetDisplay() { 489 void* GLSurfaceGLX::GetDisplay() {
456 return g_display; 490 return g_display;
457 } 491 }
458 492
459 GLSurfaceGLX::~GLSurfaceGLX() {} 493 GLSurfaceGLX::~GLSurfaceGLX() {}
460 494
461 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) 495 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window)
462 : parent_window_(window), window_(0), glx_window_(0), config_(nullptr) { 496 : parent_window_(window), window_(0), glx_window_(0), config_(nullptr) {}
463 }
464 497
465 GLXDrawable NativeViewGLSurfaceGLX::GetDrawableHandle() const { 498 GLXDrawable NativeViewGLSurfaceGLX::GetDrawableHandle() const {
466 return glx_window_; 499 return glx_window_;
467 } 500 }
468 501
469 bool NativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { 502 bool NativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) {
470 XWindowAttributes attributes; 503 XWindowAttributes attributes;
471 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { 504 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) {
472 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ 505 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_
473 << "."; 506 << ".";
474 return false; 507 return false;
475 } 508 }
476 size_ = gfx::Size(attributes.width, attributes.height); 509 size_ = gfx::Size(attributes.width, attributes.height);
477 // Create a child window, with a CopyFromParent visual (to avoid inducing 510 // Create a child window, with a CopyFromParent visual (to avoid inducing
478 // extra blits in the driver), that we can resize exactly in Resize(), 511 // extra blits in the driver), that we can resize exactly in Resize(),
479 // correctly ordered with GL, so that we don't have invalid transient states. 512 // correctly ordered with GL, so that we don't have invalid transient states.
480 // See https://crbug.com/326995. 513 // See https://crbug.com/326995.
481 XSetWindowAttributes swa; 514 XSetWindowAttributes swa;
482 memset(&swa, 0, sizeof(swa)); 515 memset(&swa, 0, sizeof(swa));
483 swa.background_pixmap = 0; 516 swa.background_pixmap = 0;
(...skipping 12 matching lines...) Expand all
496 } 529 }
497 XFlush(g_display); 530 XFlush(g_display);
498 531
499 GetConfig(); 532 GetConfig();
500 DCHECK(config_); 533 DCHECK(config_);
501 glx_window_ = glXCreateWindow(g_display, config_, window_, NULL); 534 glx_window_ = glXCreateWindow(g_display, config_, window_, NULL);
502 535
503 if (g_glx_oml_sync_control_supported) { 536 if (g_glx_oml_sync_control_supported) {
504 vsync_provider_.reset(new OMLSyncControlVSyncProvider(glx_window_)); 537 vsync_provider_.reset(new OMLSyncControlVSyncProvider(glx_window_));
505 } else if (g_glx_sgi_video_sync_supported) { 538 } else if (g_glx_sgi_video_sync_supported) {
506 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(config_, glx_window_)); 539 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(parent_window_));
507 } else { 540 } else {
508 // Assume a refresh rate of 59.9 Hz, which will cause us to skip 541 // Assume a refresh rate of 59.9 Hz, which will cause us to skip
509 // 1 frame every 10 seconds on a 60Hz monitor, but will prevent us 542 // 1 frame every 10 seconds on a 60Hz monitor, but will prevent us
510 // from blocking the GPU service due to back pressure. This would still 543 // from blocking the GPU service due to back pressure. This would still
511 // encounter backpressure on a <60Hz monitor, but hopefully that is 544 // encounter backpressure on a <60Hz monitor, but hopefully that is
512 // not common. 545 // not common.
513 const base::TimeTicks kDefaultTimebase; 546 const base::TimeTicks kDefaultTimebase;
514 const base::TimeDelta kDefaultInterval = 547 const base::TimeDelta kDefaultInterval =
515 base::TimeDelta::FromSeconds(1) / 59.9; 548 base::TimeDelta::FromSeconds(1) / 59.9;
516 vsync_provider_.reset( 549 vsync_provider_.reset(
(...skipping 20 matching lines...) Expand all
537 } 570 }
538 } 571 }
539 572
540 bool NativeViewGLSurfaceGLX::CanDispatchEvent(const ui::PlatformEvent& event) { 573 bool NativeViewGLSurfaceGLX::CanDispatchEvent(const ui::PlatformEvent& event) {
541 return event->type == Expose && event->xexpose.window == window_; 574 return event->type == Expose && event->xexpose.window == window_;
542 } 575 }
543 576
544 uint32_t NativeViewGLSurfaceGLX::DispatchEvent(const ui::PlatformEvent& event) { 577 uint32_t NativeViewGLSurfaceGLX::DispatchEvent(const ui::PlatformEvent& event) {
545 XEvent forwarded_event = *event; 578 XEvent forwarded_event = *event;
546 forwarded_event.xexpose.window = parent_window_; 579 forwarded_event.xexpose.window = parent_window_;
547 XSendEvent(g_display, parent_window_, False, ExposureMask, 580 XSendEvent(g_display, parent_window_, False, ExposureMask, &forwarded_event);
548 &forwarded_event);
549 XFlush(g_display); 581 XFlush(g_display);
550 return ui::POST_DISPATCH_STOP_PROPAGATION; 582 return ui::POST_DISPATCH_STOP_PROPAGATION;
551 } 583 }
552 584
553 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size, 585 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size,
554 float scale_factor, 586 float scale_factor,
555 bool has_alpha) { 587 bool has_alpha) {
556 size_ = size; 588 size_ = size;
557 glXWaitGL(); 589 glXWaitGL();
558 XResizeWindow(g_display, window_, size.width(), size.height()); 590 XResizeWindow(g_display, window_, size.width(), size.height());
559 glXWaitX(); 591 glXWaitX();
560 return true; 592 return true;
561 } 593 }
562 594
563 bool NativeViewGLSurfaceGLX::IsOffscreen() { 595 bool NativeViewGLSurfaceGLX::IsOffscreen() {
564 return false; 596 return false;
565 } 597 }
566 598
567 gfx::SwapResult NativeViewGLSurfaceGLX::SwapBuffers() { 599 gfx::SwapResult NativeViewGLSurfaceGLX::SwapBuffers() {
568 TRACE_EVENT2("gpu", "NativeViewGLSurfaceGLX:RealSwapBuffers", 600 TRACE_EVENT2("gpu", "NativeViewGLSurfaceGLX:RealSwapBuffers", "width",
569 "width", GetSize().width(), 601 GetSize().width(), "height", GetSize().height());
570 "height", GetSize().height());
571 602
572 glXSwapBuffers(g_display, GetDrawableHandle()); 603 glXSwapBuffers(g_display, GetDrawableHandle());
573 return gfx::SwapResult::SWAP_ACK; 604 return gfx::SwapResult::SWAP_ACK;
574 } 605 }
575 606
576 gfx::Size NativeViewGLSurfaceGLX::GetSize() { 607 gfx::Size NativeViewGLSurfaceGLX::GetSize() {
577 return size_; 608 return size_;
578 } 609 }
579 610
580 void* NativeViewGLSurfaceGLX::GetHandle() { 611 void* NativeViewGLSurfaceGLX::GetHandle() {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 if (!config_) 698 if (!config_)
668 config_ = GetConfigForWindow(g_display, window_); 699 config_ = GetConfigForWindow(g_display, window_);
669 return config_; 700 return config_;
670 } 701 }
671 702
672 UnmappedNativeViewGLSurfaceGLX::~UnmappedNativeViewGLSurfaceGLX() { 703 UnmappedNativeViewGLSurfaceGLX::~UnmappedNativeViewGLSurfaceGLX() {
673 Destroy(); 704 Destroy();
674 } 705 }
675 706
676 } // namespace gl 707 } // namespace gl
OLDNEW
« no previous file with comments | « content/common/sandbox_linux/bpf_gpu_policy_linux.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698