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

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

Issue 23480056: Create a child window as part of GLX surfaces. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix comment typo Created 7 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 | 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/lazy_instance.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h" 16 #include "base/memory/weak_ptr.h"
16 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
17 #include "base/synchronization/cancellation_flag.h" 18 #include "base/synchronization/cancellation_flag.h"
18 #include "base/synchronization/lock.h" 19 #include "base/synchronization/lock.h"
19 #include "base/threading/non_thread_safe.h" 20 #include "base/threading/non_thread_safe.h"
20 #include "base/threading/thread.h" 21 #include "base/threading/thread.h"
21 #include "base/time/time.h" 22 #include "base/time/time.h"
22 #include "third_party/mesa/src/include/GL/osmesa.h" 23 #include "third_party/mesa/src/include/GL/osmesa.h"
23 #include "ui/base/x/x11_util.h" 24 #include "ui/base/x/x11_util.h"
24 #include "ui/gl/gl_bindings.h" 25 #include "ui/gl/gl_bindings.h"
25 #include "ui/gl/gl_implementation.h" 26 #include "ui/gl/gl_implementation.h"
26 #include "ui/gl/vsync_provider.h" 27 #include "ui/gl/vsync_provider.h"
27 28
28 namespace gfx { 29 namespace gfx {
29 30
30 namespace { 31 namespace {
31 32
32 // scoped_ptr functor for XFree(). Use as follows: 33 // scoped_ptr functor for XFree(). Use as follows:
33 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...); 34 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...);
34 // where "XVisualInfo" is any X type that is freed with XFree. 35 // where "XVisualInfo" is any X type that is freed with XFree.
35 class ScopedPtrXFree { 36 class ScopedPtrXFree {
36 public: 37 public:
37 void operator()(void* x) const { 38 void operator()(void* x) const {
38 ::XFree(x); 39 ::XFree(x);
39 } 40 }
40 }; 41 };
41 42
42 Display* g_display; 43 Display* g_display = NULL;
43 const char* g_glx_extensions = NULL; 44 const char* g_glx_extensions = NULL;
44 bool g_glx_context_create = false; 45 bool g_glx_context_create = false;
45 bool g_glx_create_context_robustness_supported = false; 46 bool g_glx_create_context_robustness_supported = false;
46 bool g_glx_texture_from_pixmap_supported = false; 47 bool g_glx_texture_from_pixmap_supported = false;
47 bool g_glx_oml_sync_control_supported = false; 48 bool g_glx_oml_sync_control_supported = false;
48 49
49 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a 50 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a
50 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML 51 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML
51 // always fails even though GLX_OML_sync_control is reported as being supported. 52 // always fails even though GLX_OML_sync_control is reported as being supported.
52 bool g_glx_get_msc_rate_oml_supported = false; 53 bool g_glx_get_msc_rate_oml_supported = false;
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 if (initialized) 309 if (initialized)
309 return true; 310 return true;
310 311
311 // http://crbug.com/245466 312 // http://crbug.com/245466
312 setenv("force_s3tc_enable", "true", 1); 313 setenv("force_s3tc_enable", "true", 1);
313 314
314 // SGIVideoSyncProviderShim (if instantiated) will issue X commands on 315 // SGIVideoSyncProviderShim (if instantiated) will issue X commands on
315 // it's own thread. 316 // it's own thread.
316 XInitThreads(); 317 XInitThreads();
317 318
319 #if defined(TOOLKIT_GTK)
320 // Be sure to use the X display handle and not the GTK display handle if this
321 // is the GPU process.
322 if (base::MessageLoop::current()->type() == base::MessageLoop::TYPE_GPU)
323 g_display = base::MessagePumpX11::GetDefaultXDisplay();
324 else
325 g_display = base::MessagePumpForUI::GetDefaultXDisplay();
326 #else
318 g_display = base::MessagePumpForUI::GetDefaultXDisplay(); 327 g_display = base::MessagePumpForUI::GetDefaultXDisplay();
328 #endif
329
319 if (!g_display) { 330 if (!g_display) {
320 LOG(ERROR) << "XOpenDisplay failed."; 331 LOG(ERROR) << "XOpenDisplay failed.";
321 return false; 332 return false;
322 } 333 }
323 334
324 int major, minor; 335 int major, minor;
325 if (!glXQueryVersion(g_display, &major, &minor)) { 336 if (!glXQueryVersion(g_display, &major, &minor)) {
326 LOG(ERROR) << "glxQueryVersion failed"; 337 LOG(ERROR) << "glxQueryVersion failed";
327 return false; 338 return false;
328 } 339 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 bool GLSurfaceGLX::IsOMLSyncControlSupported() { 392 bool GLSurfaceGLX::IsOMLSyncControlSupported() {
382 return g_glx_oml_sync_control_supported; 393 return g_glx_oml_sync_control_supported;
383 } 394 }
384 395
385 void* GLSurfaceGLX::GetDisplay() { 396 void* GLSurfaceGLX::GetDisplay() {
386 return g_display; 397 return g_display;
387 } 398 }
388 399
389 GLSurfaceGLX::~GLSurfaceGLX() {} 400 GLSurfaceGLX::~GLSurfaceGLX() {}
390 401
402 class XExposeEventForwarder : public base::MessagePumpObserver {
403 public:
404 XExposeEventForwarder() {
405 base::MessagePumpX11::Current()->AddObserver(this);
406 }
407 ~XExposeEventForwarder() {
408 base::MessagePumpX11::Current()->RemoveObserver(this);
409 }
410
411 void AddParentChildPair(gfx::AcceleratedWidget parent_window,
412 gfx::AcceleratedWidget child_window) {
413 DCHECK(child_to_parent_map_.find(child_window) ==
414 child_to_parent_map_.end());
415 child_to_parent_map_.insert(std::make_pair(
416 child_window, parent_window));
417 }
418 void RemoveParentChildPair(gfx::AcceleratedWidget parent_window,
419 gfx::AcceleratedWidget child_window) {
420 DCHECK(child_to_parent_map_.find(child_window) !=
421 child_to_parent_map_.end());
422 child_to_parent_map_.erase(child_window);
423 }
424
425 private:
426 virtual base::EventStatus WillProcessEvent(
427 const base::NativeEvent& xevent) OVERRIDE {
428 if (xevent->type != Expose)
429 return base::EVENT_CONTINUE;
430
431 WindowMap::const_iterator found = child_to_parent_map_.find(
432 xevent->xexpose.window);
433 if (found == child_to_parent_map_.end())
434 return base::EVENT_CONTINUE;
435
436 gfx::AcceleratedWidget target_window = found->second;
437 XEvent forwarded_event = *xevent;
438 forwarded_event.xexpose.window = target_window;
439 XSendEvent(g_display, target_window, False, ExposureMask,
440 &forwarded_event);
441 return base::EVENT_CONTINUE;
442 }
443 virtual void DidProcessEvent(const base::NativeEvent& xevent) {
444 }
445
446 typedef std::map<gfx::AcceleratedWidget, gfx::AcceleratedWidget> WindowMap;
447 WindowMap child_to_parent_map_;
448 };
449
450 static base::LazyInstance<XExposeEventForwarder> g_xexpose_event_forwarder =
451 LAZY_INSTANCE_INITIALIZER;
452
391 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) 453 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window)
392 : window_(window), 454 : parent_window_(window),
455 child_window_(0),
393 config_(NULL) { 456 config_(NULL) {
394 } 457 }
395 458
396 bool NativeViewGLSurfaceGLX::Initialize() { 459 bool NativeViewGLSurfaceGLX::Initialize() {
397 XWindowAttributes attributes; 460 XWindowAttributes attributes;
398 if (!XGetWindowAttributes(g_display, window_, &attributes)) { 461 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) {
399 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; 462 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_
463 << ".";
400 return false; 464 return false;
401 } 465 }
402 size_ = gfx::Size(attributes.width, attributes.height); 466 size_ = gfx::Size(attributes.width, attributes.height);
403 467
468 // Workaround for http://crbug.com/145600:
469 // Some NVIDIA drivers don't allow deleting GLX windows separately from their
470 // parent X windows. Work around this by creating a child X window to the
471 // window passed in, creating the GLX window against the child window, and
472 // then destroying the child window to destroy the GLX window.
473 XSetWindowAttributes set_window_attributes;
474 set_window_attributes.event_mask = ExposureMask;
475 child_window_ = XCreateWindow(
476 g_display, parent_window_, 0, 0, attributes.width, attributes.height, 0,
477 attributes.depth, InputOutput, attributes.visual, CWEventMask,
478 &set_window_attributes);
479 // Because the child window covers the parent window, it will receive all
480 // expose events instead of the parent. Set up an explicit forwarding of
481 // these events from the child window to the parent window.
482 g_xexpose_event_forwarder.Pointer()->AddParentChildPair(
483 parent_window_, child_window_);
484 XMapWindow(g_display, child_window_);
485 XFlush(g_display);
486
404 if (g_glx_oml_sync_control_supported) 487 if (g_glx_oml_sync_control_supported)
405 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_)); 488 vsync_provider_.reset(new OMLSyncControlVSyncProvider(parent_window_));
406 else if (g_glx_sgi_video_sync_supported) 489 else if (g_glx_sgi_video_sync_supported)
407 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_)); 490 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(parent_window_));
408 491
409 return true; 492 return true;
410 } 493 }
411 494
412 void NativeViewGLSurfaceGLX::Destroy() { 495 void NativeViewGLSurfaceGLX::Destroy() {
496 g_xexpose_event_forwarder.Pointer()->RemoveParentChildPair(
497 parent_window_, child_window_);
498 XDestroyWindow(g_display, child_window_);
499 XFlush(g_display);
500 child_window_ = 0;
413 } 501 }
414 502
415 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { 503 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) {
504 XResizeWindow(g_display, child_window_, size.width(), size.height());
505 XFlush(g_display);
416 size_ = size; 506 size_ = size;
417 return true; 507 return true;
418 } 508 }
419 509
420 bool NativeViewGLSurfaceGLX::IsOffscreen() { 510 bool NativeViewGLSurfaceGLX::IsOffscreen() {
421 return false; 511 return false;
422 } 512 }
423 513
424 bool NativeViewGLSurfaceGLX::SwapBuffers() { 514 bool NativeViewGLSurfaceGLX::SwapBuffers() {
425 glXSwapBuffers(g_display, window_); 515 glXSwapBuffers(g_display, child_window_);
426 return true; 516 return true;
427 } 517 }
428 518
429 gfx::Size NativeViewGLSurfaceGLX::GetSize() { 519 gfx::Size NativeViewGLSurfaceGLX::GetSize() {
430 return size_; 520 return size_;
431 } 521 }
432 522
433 void* NativeViewGLSurfaceGLX::GetHandle() { 523 void* NativeViewGLSurfaceGLX::GetHandle() {
434 return reinterpret_cast<void*>(window_); 524 return reinterpret_cast<void*>(child_window_);
435 } 525 }
436 526
437 std::string NativeViewGLSurfaceGLX::GetExtensions() { 527 std::string NativeViewGLSurfaceGLX::GetExtensions() {
438 std::string extensions = GLSurface::GetExtensions(); 528 std::string extensions = GLSurface::GetExtensions();
439 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) { 529 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) {
440 extensions += extensions.empty() ? "" : " "; 530 extensions += extensions.empty() ? "" : " ";
441 extensions += "GL_CHROMIUM_post_sub_buffer"; 531 extensions += "GL_CHROMIUM_post_sub_buffer";
442 } 532 }
443 return extensions; 533 return extensions;
444 } 534 }
445 535
446 void* NativeViewGLSurfaceGLX::GetConfig() { 536 void* NativeViewGLSurfaceGLX::GetConfig() {
447 if (!config_) { 537 if (!config_) {
448 // This code path is expensive, but we only take it when 538 // This code path is expensive, but we only take it when
449 // attempting to use GLX_ARB_create_context_robustness, in which 539 // attempting to use GLX_ARB_create_context_robustness, in which
450 // case we need a GLXFBConfig for the window in order to create a 540 // case we need a GLXFBConfig for the window in order to create a
451 // context for it. 541 // context for it.
452 // 542 //
453 // TODO(kbr): this is not a reliable code path. On platforms which 543 // TODO(kbr): this is not a reliable code path. On platforms which
454 // support it, we should use glXChooseFBConfig in the browser 544 // support it, we should use glXChooseFBConfig in the browser
455 // process to choose the FBConfig and from there the X Visual to 545 // process to choose the FBConfig and from there the X Visual to
456 // use when creating the window in the first place. Then we can 546 // use when creating the window in the first place. Then we can
457 // pass that FBConfig down rather than attempting to reconstitute 547 // pass that FBConfig down rather than attempting to reconstitute
458 // it. 548 // it.
459 549
460 XWindowAttributes attributes; 550 XWindowAttributes attributes;
461 if (!XGetWindowAttributes( 551 if (!XGetWindowAttributes(
462 g_display, 552 g_display,
463 window_, 553 parent_window_,
464 &attributes)) { 554 &attributes)) {
465 LOG(ERROR) << "XGetWindowAttributes failed for window " << 555 LOG(ERROR) << "XGetWindowAttributes failed for window " <<
466 window_ << "."; 556 parent_window_ << ".";
467 return NULL; 557 return NULL;
468 } 558 }
469 559
470 int visual_id = XVisualIDFromVisual(attributes.visual); 560 int visual_id = XVisualIDFromVisual(attributes.visual);
471 561
472 int num_elements = 0; 562 int num_elements = 0;
473 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( 563 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs(
474 glXGetFBConfigs(g_display, 564 glXGetFBConfigs(g_display,
475 DefaultScreen(g_display), 565 DefaultScreen(g_display),
476 &num_elements)); 566 &num_elements));
(...skipping 23 matching lines...) Expand all
500 config_ = configs.get()[i]; 590 config_ = configs.get()[i];
501 } 591 }
502 } 592 }
503 593
504 return config_; 594 return config_;
505 } 595 }
506 596
507 bool NativeViewGLSurfaceGLX::PostSubBuffer( 597 bool NativeViewGLSurfaceGLX::PostSubBuffer(
508 int x, int y, int width, int height) { 598 int x, int y, int width, int height) {
509 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); 599 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer);
510 glXCopySubBufferMESA(g_display, window_, x, y, width, height); 600 glXCopySubBufferMESA(g_display, child_window_, x, y, width, height);
511 return true; 601 return true;
512 } 602 }
513 603
514 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { 604 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() {
515 return vsync_provider_.get(); 605 return vsync_provider_.get();
516 } 606 }
517 607
518 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() 608 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX()
519 : window_(0), 609 : parent_window_(0),
610 child_window_(0),
520 config_(NULL) { 611 config_(NULL) {
521 } 612 }
522 613
523 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { 614 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() {
524 Destroy(); 615 Destroy();
525 } 616 }
526 617
527 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) 618 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size)
528 : size_(size), 619 : size_(size),
529 config_(NULL), 620 config_(NULL),
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 698
608 void* PbufferGLSurfaceGLX::GetConfig() { 699 void* PbufferGLSurfaceGLX::GetConfig() {
609 return config_; 700 return config_;
610 } 701 }
611 702
612 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { 703 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() {
613 Destroy(); 704 Destroy();
614 } 705 }
615 706
616 } // namespace gfx 707 } // 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