| OLD | NEW |
| 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 |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider); | 292 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider); |
| 293 }; | 293 }; |
| 294 | 294 |
| 295 SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = NULL; | 295 SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = NULL; |
| 296 | 296 |
| 297 // In order to take advantage of GLX_SGI_video_sync, we need a display | 297 // In order to take advantage of GLX_SGI_video_sync, we need a display |
| 298 // for use on a separate thread. We must allocate this before the sandbox | 298 // for use on a separate thread. We must allocate this before the sandbox |
| 299 // goes up (rather than on-demand when we start the thread). | 299 // goes up (rather than on-demand when we start the thread). |
| 300 Display* SGIVideoSyncProviderThreadShim::display_ = NULL; | 300 Display* SGIVideoSyncProviderThreadShim::display_ = NULL; |
| 301 | 301 |
| 302 #if defined(TOOLKIT_GTK) | |
| 303 // A mechanism for forwarding XExpose events from one window to another. | |
| 304 // Because in the workaround for http://crbug.com/145600 the child window | |
| 305 // is placed on top of the parent window, only the child window will receive | |
| 306 // all expose events. These need to be forwared to the parent window to inform | |
| 307 // it that it should paint. | |
| 308 class XExposeEventForwarder : public base::MessagePumpObserver { | |
| 309 public: | |
| 310 XExposeEventForwarder() {} | |
| 311 virtual ~XExposeEventForwarder() { | |
| 312 DCHECK(child_to_parent_map_.empty()); | |
| 313 } | |
| 314 void AddParentChildPair(gfx::AcceleratedWidget parent_window, | |
| 315 gfx::AcceleratedWidget child_window) { | |
| 316 if (child_to_parent_map_.empty()) | |
| 317 base::MessagePumpX11::Current()->AddObserver(this); | |
| 318 | |
| 319 DCHECK(child_to_parent_map_.find(child_window) == | |
| 320 child_to_parent_map_.end()); | |
| 321 child_to_parent_map_.insert(std::make_pair( | |
| 322 child_window, parent_window)); | |
| 323 } | |
| 324 void RemoveParentChildPair(gfx::AcceleratedWidget parent_window, | |
| 325 gfx::AcceleratedWidget child_window) { | |
| 326 DCHECK(child_to_parent_map_.find(child_window) != | |
| 327 child_to_parent_map_.end()); | |
| 328 child_to_parent_map_.erase(child_window); | |
| 329 | |
| 330 if (child_to_parent_map_.empty()) | |
| 331 base::MessagePumpX11::Current()->RemoveObserver(this); | |
| 332 } | |
| 333 | |
| 334 private: | |
| 335 virtual void WillProcessEvent(const base::NativeEvent& xevent) OVERRIDE { | |
| 336 if (xevent->type != Expose) | |
| 337 return; | |
| 338 | |
| 339 WindowMap::const_iterator found = child_to_parent_map_.find( | |
| 340 xevent->xexpose.window); | |
| 341 if (found == child_to_parent_map_.end()) | |
| 342 return; | |
| 343 | |
| 344 gfx::AcceleratedWidget target_window = found->second; | |
| 345 XEvent forwarded_event = *xevent; | |
| 346 forwarded_event.xexpose.window = target_window; | |
| 347 XSendEvent(g_display, target_window, False, ExposureMask, | |
| 348 &forwarded_event); | |
| 349 } | |
| 350 virtual void DidProcessEvent(const base::NativeEvent& xevent) OVERRIDE { | |
| 351 } | |
| 352 | |
| 353 typedef std::map<gfx::AcceleratedWidget, gfx::AcceleratedWidget> WindowMap; | |
| 354 WindowMap child_to_parent_map_; | |
| 355 | |
| 356 DISALLOW_COPY_AND_ASSIGN(XExposeEventForwarder); | |
| 357 }; | |
| 358 | |
| 359 static base::LazyInstance<XExposeEventForwarder> g_xexpose_event_forwarder = | |
| 360 LAZY_INSTANCE_INITIALIZER; | |
| 361 | |
| 362 // Do not use this workaround when running in test harnesses that do not have | |
| 363 // a message loop or do not have a TYPE_GPU message loop. | |
| 364 bool g_create_child_windows = false; | |
| 365 #endif | |
| 366 | |
| 367 } // namespace | 302 } // namespace |
| 368 | 303 |
| 369 GLSurfaceGLX::GLSurfaceGLX() {} | 304 GLSurfaceGLX::GLSurfaceGLX() {} |
| 370 | 305 |
| 371 bool GLSurfaceGLX::InitializeOneOff() { | 306 bool GLSurfaceGLX::InitializeOneOff() { |
| 372 static bool initialized = false; | 307 static bool initialized = false; |
| 373 if (initialized) | 308 if (initialized) |
| 374 return true; | 309 return true; |
| 375 | 310 |
| 376 // http://crbug.com/245466 | 311 // http://crbug.com/245466 |
| 377 setenv("force_s3tc_enable", "true", 1); | 312 setenv("force_s3tc_enable", "true", 1); |
| 378 | 313 |
| 379 // SGIVideoSyncProviderShim (if instantiated) will issue X commands on | 314 // SGIVideoSyncProviderShim (if instantiated) will issue X commands on |
| 380 // it's own thread. | 315 // it's own thread. |
| 381 XInitThreads(); | 316 XInitThreads(); |
| 382 | 317 |
| 383 #if defined(TOOLKIT_GTK) | |
| 384 // Be sure to use the X display handle and not the GTK display handle if this | |
| 385 // is the GPU process. | |
| 386 g_create_child_windows = | |
| 387 base::MessageLoop::current() && | |
| 388 base::MessageLoop::current()->type() == base::MessageLoop::TYPE_GPU; | |
| 389 | |
| 390 if (g_create_child_windows) | |
| 391 g_display = base::MessagePumpX11::GetDefaultXDisplay(); | |
| 392 else | |
| 393 g_display = base::MessagePumpForUI::GetDefaultXDisplay(); | |
| 394 #else | |
| 395 g_display = base::MessagePumpForUI::GetDefaultXDisplay(); | 318 g_display = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 396 #endif | |
| 397 | 319 |
| 398 if (!g_display) { | 320 if (!g_display) { |
| 399 LOG(ERROR) << "XOpenDisplay failed."; | 321 LOG(ERROR) << "XOpenDisplay failed."; |
| 400 return false; | 322 return false; |
| 401 } | 323 } |
| 402 | 324 |
| 403 int major, minor; | 325 int major, minor; |
| 404 if (!glXQueryVersion(g_display, &major, &minor)) { | 326 if (!glXQueryVersion(g_display, &major, &minor)) { |
| 405 LOG(ERROR) << "glxQueryVersion failed"; | 327 LOG(ERROR) << "glxQueryVersion failed"; |
| 406 return false; | 328 return false; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 bool GLSurfaceGLX::IsOMLSyncControlSupported() { | 382 bool GLSurfaceGLX::IsOMLSyncControlSupported() { |
| 461 return g_glx_oml_sync_control_supported; | 383 return g_glx_oml_sync_control_supported; |
| 462 } | 384 } |
| 463 | 385 |
| 464 void* GLSurfaceGLX::GetDisplay() { | 386 void* GLSurfaceGLX::GetDisplay() { |
| 465 return g_display; | 387 return g_display; |
| 466 } | 388 } |
| 467 | 389 |
| 468 GLSurfaceGLX::~GLSurfaceGLX() {} | 390 GLSurfaceGLX::~GLSurfaceGLX() {} |
| 469 | 391 |
| 470 #if defined(TOOLKIT_GTK) | |
| 471 bool NativeViewGLSurfaceGLX::SetBackbufferAllocation(bool allocated) { | |
| 472 backbuffer_allocated_ = allocated; | |
| 473 AdjustBufferAllocation(); | |
| 474 return true; | |
| 475 } | |
| 476 | |
| 477 void NativeViewGLSurfaceGLX::SetFrontbufferAllocation(bool allocated) { | |
| 478 frontbuffer_allocated_ = allocated; | |
| 479 AdjustBufferAllocation(); | |
| 480 } | |
| 481 | |
| 482 void NativeViewGLSurfaceGLX::AdjustBufferAllocation() { | |
| 483 if (!g_create_child_windows) | |
| 484 return; | |
| 485 | |
| 486 if (frontbuffer_allocated_ || backbuffer_allocated_) | |
| 487 CreateChildWindow(); | |
| 488 else | |
| 489 DestroyChildWindow(); | |
| 490 } | |
| 491 | |
| 492 void NativeViewGLSurfaceGLX::CreateChildWindow() { | |
| 493 DCHECK(g_create_child_windows); | |
| 494 | |
| 495 if (child_window_) | |
| 496 return; | |
| 497 | |
| 498 XSetWindowAttributes set_window_attributes; | |
| 499 set_window_attributes.event_mask = ExposureMask; | |
| 500 child_window_ = XCreateWindow( | |
| 501 g_display, parent_window_, 0, 0, size_.width(), size_.height(), 0, | |
| 502 CopyFromParent, InputOutput, CopyFromParent, CWEventMask, | |
| 503 &set_window_attributes); | |
| 504 g_xexpose_event_forwarder.Pointer()->AddParentChildPair( | |
| 505 parent_window_, child_window_); | |
| 506 | |
| 507 XMapWindow(g_display, child_window_); | |
| 508 XFlush(g_display); | |
| 509 } | |
| 510 | |
| 511 void NativeViewGLSurfaceGLX::DestroyChildWindow() { | |
| 512 if (!child_window_) | |
| 513 return; | |
| 514 | |
| 515 g_xexpose_event_forwarder.Pointer()->RemoveParentChildPair( | |
| 516 parent_window_, child_window_); | |
| 517 XDestroyWindow(g_display, child_window_); | |
| 518 XFlush(g_display); | |
| 519 child_window_ = 0; | |
| 520 } | |
| 521 #endif | |
| 522 | |
| 523 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) | 392 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) |
| 524 : parent_window_(window), | 393 : parent_window_(window), |
| 525 #if defined(TOOLKIT_GTK) | |
| 526 child_window_(0), | |
| 527 dummy_window_(0), | |
| 528 backbuffer_allocated_(true), | |
| 529 frontbuffer_allocated_(true), | |
| 530 #endif | |
| 531 config_(NULL) { | 394 config_(NULL) { |
| 532 } | 395 } |
| 533 | 396 |
| 534 gfx::AcceleratedWidget NativeViewGLSurfaceGLX::GetDrawableHandle() const { | 397 gfx::AcceleratedWidget NativeViewGLSurfaceGLX::GetDrawableHandle() const { |
| 535 #if defined(TOOLKIT_GTK) | |
| 536 if (g_create_child_windows) { | |
| 537 if (child_window_) | |
| 538 return child_window_; | |
| 539 return dummy_window_; | |
| 540 } | |
| 541 #endif | |
| 542 return parent_window_; | 398 return parent_window_; |
| 543 } | 399 } |
| 544 | 400 |
| 545 bool NativeViewGLSurfaceGLX::Initialize() { | 401 bool NativeViewGLSurfaceGLX::Initialize() { |
| 546 XWindowAttributes attributes; | 402 XWindowAttributes attributes; |
| 547 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { | 403 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { |
| 548 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ | 404 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ |
| 549 << "."; | 405 << "."; |
| 550 return false; | 406 return false; |
| 551 } | 407 } |
| 552 size_ = gfx::Size(attributes.width, attributes.height); | 408 size_ = gfx::Size(attributes.width, attributes.height); |
| 553 | 409 |
| 554 gfx::AcceleratedWidget window_for_vsync = parent_window_; | 410 gfx::AcceleratedWidget window_for_vsync = parent_window_; |
| 555 | 411 |
| 556 #if defined(TOOLKIT_GTK) | |
| 557 if (g_create_child_windows) { | |
| 558 dummy_window_ = XCreateWindow( | |
| 559 g_display, | |
| 560 RootWindow(g_display, XScreenNumberOfScreen(attributes.screen)), | |
| 561 0, 0, 1, 1, 0, CopyFromParent, InputOutput, attributes.visual, 0, NULL); | |
| 562 window_for_vsync = dummy_window_; | |
| 563 CreateChildWindow(); | |
| 564 } | |
| 565 #endif | |
| 566 | |
| 567 if (g_glx_oml_sync_control_supported) | 412 if (g_glx_oml_sync_control_supported) |
| 568 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_for_vsync)); | 413 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_for_vsync)); |
| 569 else if (g_glx_sgi_video_sync_supported) | 414 else if (g_glx_sgi_video_sync_supported) |
| 570 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_for_vsync)); | 415 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_for_vsync)); |
| 571 | 416 |
| 572 return true; | 417 return true; |
| 573 } | 418 } |
| 574 | 419 |
| 575 void NativeViewGLSurfaceGLX::Destroy() { | 420 void NativeViewGLSurfaceGLX::Destroy() { |
| 576 #if defined(TOOLKIT_GTK) | |
| 577 DestroyChildWindow(); | |
| 578 if (dummy_window_) | |
| 579 XDestroyWindow(g_display, dummy_window_); | |
| 580 dummy_window_ = 0; | |
| 581 #endif | |
| 582 } | 421 } |
| 583 | 422 |
| 584 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { | 423 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { |
| 585 #if defined(TOOLKIT_GTK) | |
| 586 if (child_window_) { | |
| 587 XResizeWindow(g_display, child_window_, size.width(), size.height()); | |
| 588 XFlush(g_display); | |
| 589 } | |
| 590 #endif | |
| 591 size_ = size; | 424 size_ = size; |
| 592 return true; | 425 return true; |
| 593 } | 426 } |
| 594 | 427 |
| 595 bool NativeViewGLSurfaceGLX::IsOffscreen() { | 428 bool NativeViewGLSurfaceGLX::IsOffscreen() { |
| 596 return false; | 429 return false; |
| 597 } | 430 } |
| 598 | 431 |
| 599 bool NativeViewGLSurfaceGLX::SwapBuffers() { | 432 bool NativeViewGLSurfaceGLX::SwapBuffers() { |
| 600 TRACE_EVENT2("gpu", "NativeViewGLSurfaceGLX:RealSwapBuffers", | 433 TRACE_EVENT2("gpu", "NativeViewGLSurfaceGLX:RealSwapBuffers", |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); | 517 glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); |
| 685 return true; | 518 return true; |
| 686 } | 519 } |
| 687 | 520 |
| 688 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { | 521 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { |
| 689 return vsync_provider_.get(); | 522 return vsync_provider_.get(); |
| 690 } | 523 } |
| 691 | 524 |
| 692 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() | 525 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() |
| 693 : parent_window_(0), | 526 : parent_window_(0), |
| 694 #if defined(TOOLKIT_GTK) | |
| 695 child_window_(0), | |
| 696 dummy_window_(0), | |
| 697 backbuffer_allocated_(true), | |
| 698 frontbuffer_allocated_(true), | |
| 699 #endif | |
| 700 config_(NULL) { | 527 config_(NULL) { |
| 701 } | 528 } |
| 702 | 529 |
| 703 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { | 530 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { |
| 704 Destroy(); | 531 Destroy(); |
| 705 } | 532 } |
| 706 | 533 |
| 707 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) | 534 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) |
| 708 : size_(size), | 535 : size_(size), |
| 709 config_(NULL), | 536 config_(NULL), |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 | 614 |
| 788 void* PbufferGLSurfaceGLX::GetConfig() { | 615 void* PbufferGLSurfaceGLX::GetConfig() { |
| 789 return config_; | 616 return config_; |
| 790 } | 617 } |
| 791 | 618 |
| 792 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { | 619 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { |
| 793 Destroy(); | 620 Destroy(); |
| 794 } | 621 } |
| 795 | 622 |
| 796 } // namespace gfx | 623 } // namespace gfx |
| OLD | NEW |