Chromium Code Reviews| 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 |
| 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 Loading... | |
| 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 Loading... | |
| 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 #if defined(TOOLKIT_GTK) | |
| 403 // A mechanism for forwarding XExpose events from one window to another. | |
| 404 // Because in the workaround for http://crbug.com/145600 the child window | |
| 405 // is placed on top of the parent window, only the child window will receive | |
| 406 // all expose events. These need to be forwared to the parent window to inform | |
| 407 // it that it should paint. | |
| 408 class XExposeEventForwarder : public base::MessagePumpObserver { | |
|
piman
2013/09/11 23:05:09
nit: move this to an anonoymous namespace.
ccameron
2013/09/12 01:37:13
Done.
| |
| 409 public: | |
| 410 XExposeEventForwarder() { | |
| 411 base::MessagePumpX11::Current()->AddObserver(this); | |
| 412 } | |
| 413 ~XExposeEventForwarder() { | |
| 414 base::MessagePumpX11::Current()->RemoveObserver(this); | |
|
piman
2013/09/11 23:05:09
If this is a lazy instance, the destructor will ru
ccameron
2013/09/12 01:37:13
Good catch, thanks. Moved to the Add/RemoveParentC
| |
| 415 } | |
| 416 | |
| 417 void AddParentChildPair(gfx::AcceleratedWidget parent_window, | |
| 418 gfx::AcceleratedWidget child_window) { | |
| 419 DCHECK(child_to_parent_map_.find(child_window) == | |
| 420 child_to_parent_map_.end()); | |
| 421 child_to_parent_map_.insert(std::make_pair( | |
| 422 child_window, parent_window)); | |
| 423 } | |
| 424 void RemoveParentChildPair(gfx::AcceleratedWidget parent_window, | |
| 425 gfx::AcceleratedWidget child_window) { | |
| 426 DCHECK(child_to_parent_map_.find(child_window) != | |
| 427 child_to_parent_map_.end()); | |
| 428 child_to_parent_map_.erase(child_window); | |
| 429 } | |
| 430 | |
| 431 private: | |
| 432 virtual base::EventStatus WillProcessEvent( | |
| 433 const base::NativeEvent& xevent) OVERRIDE { | |
| 434 if (xevent->type != Expose) | |
| 435 return base::EVENT_CONTINUE; | |
| 436 | |
| 437 WindowMap::const_iterator found = child_to_parent_map_.find( | |
| 438 xevent->xexpose.window); | |
| 439 if (found == child_to_parent_map_.end()) | |
| 440 return base::EVENT_CONTINUE; | |
| 441 | |
| 442 gfx::AcceleratedWidget target_window = found->second; | |
| 443 XEvent forwarded_event = *xevent; | |
| 444 forwarded_event.xexpose.window = target_window; | |
| 445 XSendEvent(g_display, target_window, False, ExposureMask, | |
| 446 &forwarded_event); | |
| 447 return base::EVENT_CONTINUE; | |
| 448 } | |
| 449 virtual void DidProcessEvent(const base::NativeEvent& xevent) { | |
| 450 } | |
| 451 | |
| 452 typedef std::map<gfx::AcceleratedWidget, gfx::AcceleratedWidget> WindowMap; | |
| 453 WindowMap child_to_parent_map_; | |
| 454 }; | |
| 455 | |
| 456 static base::LazyInstance<XExposeEventForwarder> g_xexpose_event_forwarder = | |
| 457 LAZY_INSTANCE_INITIALIZER; | |
| 458 | |
| 459 bool NativeViewGLSurfaceGLX::SetBackbufferAllocation(bool allocated) { | |
| 460 if (allocated) | |
| 461 return CreateChildWindow(); | |
| 462 else | |
| 463 DestroyChildWindow(); | |
| 464 return true; | |
| 465 } | |
| 466 | |
| 467 bool NativeViewGLSurfaceGLX::CreateChildWindow() { | |
| 468 if (child_window_) | |
| 469 return true; | |
| 470 | |
| 471 XWindowAttributes attributes; | |
| 472 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { | |
|
piman
2013/09/11 23:05:09
Could we cache this? It requires a round trip to X
ccameron
2013/09/12 01:37:13
Actually, we can just use CopyFromParent and avoid
| |
| 473 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ | |
| 474 << "."; | |
| 475 return false; | |
| 476 } | |
| 477 | |
| 478 XSetWindowAttributes set_window_attributes; | |
| 479 set_window_attributes.event_mask = ExposureMask; | |
| 480 child_window_ = XCreateWindow( | |
| 481 g_display, parent_window_, 0, 0, attributes.width, attributes.height, 0, | |
| 482 attributes.depth, InputOutput, attributes.visual, CWEventMask, | |
| 483 &set_window_attributes); | |
| 484 g_xexpose_event_forwarder.Pointer()->AddParentChildPair( | |
| 485 parent_window_, child_window_); | |
| 486 | |
| 487 XMapWindow(g_display, child_window_); | |
| 488 XFlush(g_display); | |
| 489 | |
| 490 // If the dummy window was current, make the child window current now. | |
| 491 if (dummy_window_ == glXGetCurrentDrawable()) | |
| 492 glXMakeCurrent(g_display, child_window_, glXGetCurrentContext()); | |
| 493 | |
| 494 return true; | |
| 495 } | |
| 496 | |
| 497 void NativeViewGLSurfaceGLX::DestroyChildWindow() { | |
| 498 if (!child_window_) | |
| 499 return; | |
| 500 | |
|
piman
2013/09/11 23:05:09
Do we need to glXMakeCurrent the dummy_window_ her
ccameron
2013/09/12 01:37:13
Doesn't look like it. And I may make dummy_window_
| |
| 501 g_xexpose_event_forwarder.Pointer()->RemoveParentChildPair( | |
| 502 parent_window_, child_window_); | |
| 503 XDestroyWindow(g_display, child_window_); | |
| 504 XFlush(g_display); | |
| 505 child_window_ = 0; | |
| 506 } | |
| 507 #endif | |
| 508 | |
| 391 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) | 509 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) |
| 392 : window_(window), | 510 : parent_window_(window), |
| 511 #if defined(TOOLKIT_GTK) | |
| 512 child_window_(0), | |
| 513 dummy_window_(0), | |
| 514 #endif | |
| 393 config_(NULL) { | 515 config_(NULL) { |
| 394 } | 516 } |
| 395 | 517 |
| 518 gfx::AcceleratedWidget NativeViewGLSurfaceGLX::GetDrawableHandle() const { | |
| 519 #if defined(TOOLKIT_GTK) | |
| 520 if (child_window_) | |
| 521 return child_window_; | |
| 522 return dummy_window_; | |
| 523 #else | |
| 524 return parent_window_; | |
| 525 #endif | |
| 526 } | |
| 527 | |
| 396 bool NativeViewGLSurfaceGLX::Initialize() { | 528 bool NativeViewGLSurfaceGLX::Initialize() { |
| 397 XWindowAttributes attributes; | 529 XWindowAttributes attributes; |
| 398 if (!XGetWindowAttributes(g_display, window_, &attributes)) { | 530 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { |
| 399 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | 531 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ |
| 532 << "."; | |
| 400 return false; | 533 return false; |
| 401 } | 534 } |
| 402 size_ = gfx::Size(attributes.width, attributes.height); | 535 size_ = gfx::Size(attributes.width, attributes.height); |
| 403 | 536 |
| 537 gfx::AcceleratedWidget window_for_vsync = parent_window_; | |
| 538 | |
| 539 #if defined(TOOLKIT_GTK) | |
| 540 CreateChildWindow(); | |
| 541 dummy_window_ = XCreateWindow( | |
| 542 g_display, parent_window_, 0, 0, 1, 1, 0, attributes.depth, InputOutput, | |
| 543 attributes.visual, 0, NULL); | |
| 544 window_for_vsync = dummy_window_; | |
| 545 #endif | |
| 546 | |
| 404 if (g_glx_oml_sync_control_supported) | 547 if (g_glx_oml_sync_control_supported) |
| 405 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_)); | 548 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_for_vsync)); |
| 406 else if (g_glx_sgi_video_sync_supported) | 549 else if (g_glx_sgi_video_sync_supported) |
| 407 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_)); | 550 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_for_vsync)); |
| 408 | 551 |
| 409 return true; | 552 return true; |
| 410 } | 553 } |
| 411 | 554 |
| 412 void NativeViewGLSurfaceGLX::Destroy() { | 555 void NativeViewGLSurfaceGLX::Destroy() { |
| 556 #if defined(TOOLKIT_GTK) | |
| 557 if (dummy_window_) | |
| 558 XDestroyWindow(g_display, dummy_window_); | |
| 559 dummy_window_ = 0; | |
| 560 | |
| 561 DestroyChildWindow(); | |
| 562 #endif | |
| 413 } | 563 } |
| 414 | 564 |
| 415 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { | 565 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { |
| 566 #if defined(TOOLKIT_GTK) | |
| 567 if (child_window_) { | |
| 568 XResizeWindow(g_display, child_window_, size.width(), size.height()); | |
| 569 XFlush(g_display); | |
| 570 } | |
| 571 #endif | |
| 416 size_ = size; | 572 size_ = size; |
| 417 return true; | 573 return true; |
| 418 } | 574 } |
| 419 | 575 |
| 420 bool NativeViewGLSurfaceGLX::IsOffscreen() { | 576 bool NativeViewGLSurfaceGLX::IsOffscreen() { |
| 421 return false; | 577 return false; |
| 422 } | 578 } |
| 423 | 579 |
| 424 bool NativeViewGLSurfaceGLX::SwapBuffers() { | 580 bool NativeViewGLSurfaceGLX::SwapBuffers() { |
| 425 glXSwapBuffers(g_display, window_); | 581 glXSwapBuffers(g_display, GetDrawableHandle()); |
| 426 return true; | 582 return true; |
| 427 } | 583 } |
| 428 | 584 |
| 429 gfx::Size NativeViewGLSurfaceGLX::GetSize() { | 585 gfx::Size NativeViewGLSurfaceGLX::GetSize() { |
| 430 return size_; | 586 return size_; |
| 431 } | 587 } |
| 432 | 588 |
| 433 void* NativeViewGLSurfaceGLX::GetHandle() { | 589 void* NativeViewGLSurfaceGLX::GetHandle() { |
| 434 return reinterpret_cast<void*>(window_); | 590 return reinterpret_cast<void*>(GetDrawableHandle()); |
| 435 } | 591 } |
| 436 | 592 |
| 437 std::string NativeViewGLSurfaceGLX::GetExtensions() { | 593 std::string NativeViewGLSurfaceGLX::GetExtensions() { |
| 438 std::string extensions = GLSurface::GetExtensions(); | 594 std::string extensions = GLSurface::GetExtensions(); |
| 439 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) { | 595 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) { |
| 440 extensions += extensions.empty() ? "" : " "; | 596 extensions += extensions.empty() ? "" : " "; |
| 441 extensions += "GL_CHROMIUM_post_sub_buffer"; | 597 extensions += "GL_CHROMIUM_post_sub_buffer"; |
| 442 } | 598 } |
| 443 return extensions; | 599 return extensions; |
| 444 } | 600 } |
| 445 | 601 |
| 446 void* NativeViewGLSurfaceGLX::GetConfig() { | 602 void* NativeViewGLSurfaceGLX::GetConfig() { |
| 447 if (!config_) { | 603 if (!config_) { |
| 448 // This code path is expensive, but we only take it when | 604 // This code path is expensive, but we only take it when |
| 449 // attempting to use GLX_ARB_create_context_robustness, in which | 605 // attempting to use GLX_ARB_create_context_robustness, in which |
| 450 // case we need a GLXFBConfig for the window in order to create a | 606 // case we need a GLXFBConfig for the window in order to create a |
| 451 // context for it. | 607 // context for it. |
| 452 // | 608 // |
| 453 // TODO(kbr): this is not a reliable code path. On platforms which | 609 // TODO(kbr): this is not a reliable code path. On platforms which |
| 454 // support it, we should use glXChooseFBConfig in the browser | 610 // support it, we should use glXChooseFBConfig in the browser |
| 455 // process to choose the FBConfig and from there the X Visual to | 611 // 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 | 612 // use when creating the window in the first place. Then we can |
| 457 // pass that FBConfig down rather than attempting to reconstitute | 613 // pass that FBConfig down rather than attempting to reconstitute |
| 458 // it. | 614 // it. |
| 459 | 615 |
| 460 XWindowAttributes attributes; | 616 XWindowAttributes attributes; |
| 461 if (!XGetWindowAttributes( | 617 if (!XGetWindowAttributes( |
| 462 g_display, | 618 g_display, |
| 463 window_, | 619 parent_window_, |
| 464 &attributes)) { | 620 &attributes)) { |
| 465 LOG(ERROR) << "XGetWindowAttributes failed for window " << | 621 LOG(ERROR) << "XGetWindowAttributes failed for window " << |
| 466 window_ << "."; | 622 parent_window_ << "."; |
| 467 return NULL; | 623 return NULL; |
| 468 } | 624 } |
| 469 | 625 |
| 470 int visual_id = XVisualIDFromVisual(attributes.visual); | 626 int visual_id = XVisualIDFromVisual(attributes.visual); |
| 471 | 627 |
| 472 int num_elements = 0; | 628 int num_elements = 0; |
| 473 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( | 629 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( |
| 474 glXGetFBConfigs(g_display, | 630 glXGetFBConfigs(g_display, |
| 475 DefaultScreen(g_display), | 631 DefaultScreen(g_display), |
| 476 &num_elements)); | 632 &num_elements)); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 500 config_ = configs.get()[i]; | 656 config_ = configs.get()[i]; |
| 501 } | 657 } |
| 502 } | 658 } |
| 503 | 659 |
| 504 return config_; | 660 return config_; |
| 505 } | 661 } |
| 506 | 662 |
| 507 bool NativeViewGLSurfaceGLX::PostSubBuffer( | 663 bool NativeViewGLSurfaceGLX::PostSubBuffer( |
| 508 int x, int y, int width, int height) { | 664 int x, int y, int width, int height) { |
| 509 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); | 665 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); |
| 510 glXCopySubBufferMESA(g_display, window_, x, y, width, height); | 666 glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); |
| 511 return true; | 667 return true; |
| 512 } | 668 } |
| 513 | 669 |
| 514 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { | 670 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { |
| 515 return vsync_provider_.get(); | 671 return vsync_provider_.get(); |
| 516 } | 672 } |
| 517 | 673 |
| 518 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() | 674 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() |
| 519 : window_(0), | 675 : parent_window_(0), |
| 676 #if defined(TOOLKIT_GTK) | |
| 677 child_window_(0), | |
| 678 dummy_window_(0), | |
| 679 #endif | |
| 520 config_(NULL) { | 680 config_(NULL) { |
| 521 } | 681 } |
| 522 | 682 |
| 523 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { | 683 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { |
| 524 Destroy(); | 684 Destroy(); |
| 525 } | 685 } |
| 526 | 686 |
| 527 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) | 687 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) |
| 528 : size_(size), | 688 : size_(size), |
| 529 config_(NULL), | 689 config_(NULL), |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 607 | 767 |
| 608 void* PbufferGLSurfaceGLX::GetConfig() { | 768 void* PbufferGLSurfaceGLX::GetConfig() { |
| 609 return config_; | 769 return config_; |
| 610 } | 770 } |
| 611 | 771 |
| 612 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { | 772 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { |
| 613 Destroy(); | 773 Destroy(); |
| 614 } | 774 } |
| 615 | 775 |
| 616 } // namespace gfx | 776 } // namespace gfx |
| OLD | NEW |