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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider); | 293 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider); |
293 }; | 294 }; |
294 | 295 |
295 SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = NULL; | 296 SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = NULL; |
296 | 297 |
297 // In order to take advantage of GLX_SGI_video_sync, we need a display | 298 // 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 | 299 // 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). | 300 // goes up (rather than on-demand when we start the thread). |
300 Display* SGIVideoSyncProviderThreadShim::display_ = NULL; | 301 Display* SGIVideoSyncProviderThreadShim::display_ = NULL; |
301 | 302 |
| 303 #if defined(TOOLKIT_GTK) |
| 304 // A mechanism for forwarding XExpose events from one window to another. |
| 305 // Because in the workaround for http://crbug.com/145600 the child window |
| 306 // is placed on top of the parent window, only the child window will receive |
| 307 // all expose events. These need to be forwared to the parent window to inform |
| 308 // it that it should paint. |
| 309 class XExposeEventForwarder : public base::MessagePumpObserver { |
| 310 public: |
| 311 XExposeEventForwarder() {} |
| 312 virtual ~XExposeEventForwarder() { |
| 313 DCHECK(child_to_parent_map_.empty()); |
| 314 } |
| 315 void AddParentChildPair(gfx::AcceleratedWidget parent_window, |
| 316 gfx::AcceleratedWidget child_window) { |
| 317 if (child_to_parent_map_.empty()) |
| 318 base::MessagePumpX11::Current()->AddObserver(this); |
| 319 |
| 320 DCHECK(child_to_parent_map_.find(child_window) == |
| 321 child_to_parent_map_.end()); |
| 322 child_to_parent_map_.insert(std::make_pair( |
| 323 child_window, parent_window)); |
| 324 } |
| 325 void RemoveParentChildPair(gfx::AcceleratedWidget parent_window, |
| 326 gfx::AcceleratedWidget child_window) { |
| 327 DCHECK(child_to_parent_map_.find(child_window) != |
| 328 child_to_parent_map_.end()); |
| 329 child_to_parent_map_.erase(child_window); |
| 330 |
| 331 if (child_to_parent_map_.empty()) |
| 332 base::MessagePumpX11::Current()->RemoveObserver(this); |
| 333 } |
| 334 |
| 335 private: |
| 336 virtual base::EventStatus WillProcessEvent ( |
| 337 const base::NativeEvent& xevent) OVERRIDE { |
| 338 if (xevent->type != Expose) |
| 339 return base::EVENT_CONTINUE; |
| 340 |
| 341 WindowMap::const_iterator found = child_to_parent_map_.find( |
| 342 xevent->xexpose.window); |
| 343 if (found == child_to_parent_map_.end()) |
| 344 return base::EVENT_CONTINUE; |
| 345 |
| 346 gfx::AcceleratedWidget target_window = found->second; |
| 347 XEvent forwarded_event = *xevent; |
| 348 forwarded_event.xexpose.window = target_window; |
| 349 XSendEvent(g_display, target_window, False, ExposureMask, |
| 350 &forwarded_event); |
| 351 return base::EVENT_CONTINUE; |
| 352 } |
| 353 virtual void DidProcessEvent(const base::NativeEvent& xevent) OVERRIDE { |
| 354 } |
| 355 |
| 356 typedef std::map<gfx::AcceleratedWidget, gfx::AcceleratedWidget> WindowMap; |
| 357 WindowMap child_to_parent_map_; |
| 358 |
| 359 DISALLOW_COPY_AND_ASSIGN(XExposeEventForwarder); |
| 360 }; |
| 361 |
| 362 static base::LazyInstance<XExposeEventForwarder> g_xexpose_event_forwarder = |
| 363 LAZY_INSTANCE_INITIALIZER; |
| 364 #endif |
| 365 |
302 } // namespace | 366 } // namespace |
303 | 367 |
304 GLSurfaceGLX::GLSurfaceGLX() {} | 368 GLSurfaceGLX::GLSurfaceGLX() {} |
305 | 369 |
306 bool GLSurfaceGLX::InitializeOneOff() { | 370 bool GLSurfaceGLX::InitializeOneOff() { |
307 static bool initialized = false; | 371 static bool initialized = false; |
308 if (initialized) | 372 if (initialized) |
309 return true; | 373 return true; |
310 | 374 |
311 // http://crbug.com/245466 | 375 // http://crbug.com/245466 |
312 setenv("force_s3tc_enable", "true", 1); | 376 setenv("force_s3tc_enable", "true", 1); |
313 | 377 |
314 // SGIVideoSyncProviderShim (if instantiated) will issue X commands on | 378 // SGIVideoSyncProviderShim (if instantiated) will issue X commands on |
315 // it's own thread. | 379 // it's own thread. |
316 XInitThreads(); | 380 XInitThreads(); |
317 | 381 |
| 382 #if defined(TOOLKIT_GTK) |
| 383 // Be sure to use the X display handle and not the GTK display handle if this |
| 384 // is the GPU process. |
| 385 if (base::MessageLoop::current()->type() == base::MessageLoop::TYPE_GPU) |
| 386 g_display = base::MessagePumpX11::GetDefaultXDisplay(); |
| 387 else |
| 388 g_display = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 389 #else |
318 g_display = base::MessagePumpForUI::GetDefaultXDisplay(); | 390 g_display = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 391 #endif |
| 392 |
319 if (!g_display) { | 393 if (!g_display) { |
320 LOG(ERROR) << "XOpenDisplay failed."; | 394 LOG(ERROR) << "XOpenDisplay failed."; |
321 return false; | 395 return false; |
322 } | 396 } |
323 | 397 |
324 int major, minor; | 398 int major, minor; |
325 if (!glXQueryVersion(g_display, &major, &minor)) { | 399 if (!glXQueryVersion(g_display, &major, &minor)) { |
326 LOG(ERROR) << "glxQueryVersion failed"; | 400 LOG(ERROR) << "glxQueryVersion failed"; |
327 return false; | 401 return false; |
328 } | 402 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 bool GLSurfaceGLX::IsOMLSyncControlSupported() { | 455 bool GLSurfaceGLX::IsOMLSyncControlSupported() { |
382 return g_glx_oml_sync_control_supported; | 456 return g_glx_oml_sync_control_supported; |
383 } | 457 } |
384 | 458 |
385 void* GLSurfaceGLX::GetDisplay() { | 459 void* GLSurfaceGLX::GetDisplay() { |
386 return g_display; | 460 return g_display; |
387 } | 461 } |
388 | 462 |
389 GLSurfaceGLX::~GLSurfaceGLX() {} | 463 GLSurfaceGLX::~GLSurfaceGLX() {} |
390 | 464 |
| 465 #if defined(TOOLKIT_GTK) |
| 466 bool NativeViewGLSurfaceGLX::SetBackbufferAllocation(bool allocated) { |
| 467 backbuffer_allocated_ = allocated; |
| 468 AdjustBufferAllocation(); |
| 469 return true; |
| 470 } |
| 471 |
| 472 void NativeViewGLSurfaceGLX::SetFrontbufferAllocation(bool allocated) { |
| 473 frontbuffer_allocated_ = allocated; |
| 474 AdjustBufferAllocation(); |
| 475 } |
| 476 |
| 477 void NativeViewGLSurfaceGLX::AdjustBufferAllocation() { |
| 478 if (frontbuffer_allocated_ || backbuffer_allocated_) |
| 479 CreateChildWindow(); |
| 480 else |
| 481 DestroyChildWindow(); |
| 482 } |
| 483 |
| 484 void NativeViewGLSurfaceGLX::CreateChildWindow() { |
| 485 if (child_window_) |
| 486 return; |
| 487 |
| 488 XSetWindowAttributes set_window_attributes; |
| 489 set_window_attributes.event_mask = ExposureMask; |
| 490 child_window_ = XCreateWindow( |
| 491 g_display, parent_window_, 0, 0, size_.width(), size_.height(), 0, |
| 492 CopyFromParent, InputOutput, CopyFromParent, CWEventMask, |
| 493 &set_window_attributes); |
| 494 g_xexpose_event_forwarder.Pointer()->AddParentChildPair( |
| 495 parent_window_, child_window_); |
| 496 |
| 497 XMapWindow(g_display, child_window_); |
| 498 XFlush(g_display); |
| 499 } |
| 500 |
| 501 void NativeViewGLSurfaceGLX::DestroyChildWindow() { |
| 502 if (!child_window_) |
| 503 return; |
| 504 |
| 505 g_xexpose_event_forwarder.Pointer()->RemoveParentChildPair( |
| 506 parent_window_, child_window_); |
| 507 XDestroyWindow(g_display, child_window_); |
| 508 XFlush(g_display); |
| 509 child_window_ = 0; |
| 510 } |
| 511 #endif |
| 512 |
391 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) | 513 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) |
392 : window_(window), | 514 : parent_window_(window), |
| 515 #if defined(TOOLKIT_GTK) |
| 516 child_window_(0), |
| 517 dummy_window_(0), |
| 518 backbuffer_allocated_(true), |
| 519 frontbuffer_allocated_(true), |
| 520 #endif |
393 config_(NULL) { | 521 config_(NULL) { |
394 } | 522 } |
395 | 523 |
| 524 gfx::AcceleratedWidget NativeViewGLSurfaceGLX::GetDrawableHandle() const { |
| 525 #if defined(TOOLKIT_GTK) |
| 526 if (child_window_) |
| 527 return child_window_; |
| 528 return dummy_window_; |
| 529 #else |
| 530 return parent_window_; |
| 531 #endif |
| 532 } |
| 533 |
396 bool NativeViewGLSurfaceGLX::Initialize() { | 534 bool NativeViewGLSurfaceGLX::Initialize() { |
397 XWindowAttributes attributes; | 535 XWindowAttributes attributes; |
398 if (!XGetWindowAttributes(g_display, window_, &attributes)) { | 536 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { |
399 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | 537 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ |
| 538 << "."; |
400 return false; | 539 return false; |
401 } | 540 } |
402 size_ = gfx::Size(attributes.width, attributes.height); | 541 size_ = gfx::Size(attributes.width, attributes.height); |
403 | 542 |
| 543 gfx::AcceleratedWidget window_for_vsync = parent_window_; |
| 544 |
| 545 #if defined(TOOLKIT_GTK) |
| 546 dummy_window_ = XCreateWindow( |
| 547 g_display, |
| 548 RootWindow(g_display, XScreenNumberOfScreen(attributes.screen)), |
| 549 0, 0, 1, 1, 0, CopyFromParent, InputOutput, attributes.visual, 0, NULL); |
| 550 window_for_vsync = dummy_window_; |
| 551 CreateChildWindow(); |
| 552 #endif |
| 553 |
404 if (g_glx_oml_sync_control_supported) | 554 if (g_glx_oml_sync_control_supported) |
405 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_)); | 555 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_for_vsync)); |
406 else if (g_glx_sgi_video_sync_supported) | 556 else if (g_glx_sgi_video_sync_supported) |
407 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_)); | 557 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_for_vsync)); |
408 | 558 |
409 return true; | 559 return true; |
410 } | 560 } |
411 | 561 |
412 void NativeViewGLSurfaceGLX::Destroy() { | 562 void NativeViewGLSurfaceGLX::Destroy() { |
| 563 #if defined(TOOLKIT_GTK) |
| 564 DestroyChildWindow(); |
| 565 if (dummy_window_) |
| 566 XDestroyWindow(g_display, dummy_window_); |
| 567 dummy_window_ = 0; |
| 568 #endif |
413 } | 569 } |
414 | 570 |
415 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { | 571 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { |
| 572 #if defined(TOOLKIT_GTK) |
| 573 if (child_window_) { |
| 574 XResizeWindow(g_display, child_window_, size.width(), size.height()); |
| 575 XFlush(g_display); |
| 576 } |
| 577 #endif |
416 size_ = size; | 578 size_ = size; |
417 return true; | 579 return true; |
418 } | 580 } |
419 | 581 |
420 bool NativeViewGLSurfaceGLX::IsOffscreen() { | 582 bool NativeViewGLSurfaceGLX::IsOffscreen() { |
421 return false; | 583 return false; |
422 } | 584 } |
423 | 585 |
424 bool NativeViewGLSurfaceGLX::SwapBuffers() { | 586 bool NativeViewGLSurfaceGLX::SwapBuffers() { |
425 glXSwapBuffers(g_display, window_); | 587 glXSwapBuffers(g_display, GetDrawableHandle()); |
426 return true; | 588 return true; |
427 } | 589 } |
428 | 590 |
429 gfx::Size NativeViewGLSurfaceGLX::GetSize() { | 591 gfx::Size NativeViewGLSurfaceGLX::GetSize() { |
430 return size_; | 592 return size_; |
431 } | 593 } |
432 | 594 |
433 void* NativeViewGLSurfaceGLX::GetHandle() { | 595 void* NativeViewGLSurfaceGLX::GetHandle() { |
434 return reinterpret_cast<void*>(window_); | 596 return reinterpret_cast<void*>(GetDrawableHandle()); |
435 } | 597 } |
436 | 598 |
437 std::string NativeViewGLSurfaceGLX::GetExtensions() { | 599 std::string NativeViewGLSurfaceGLX::GetExtensions() { |
438 std::string extensions = GLSurface::GetExtensions(); | 600 std::string extensions = GLSurface::GetExtensions(); |
439 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) { | 601 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) { |
440 extensions += extensions.empty() ? "" : " "; | 602 extensions += extensions.empty() ? "" : " "; |
441 extensions += "GL_CHROMIUM_post_sub_buffer"; | 603 extensions += "GL_CHROMIUM_post_sub_buffer"; |
442 } | 604 } |
443 return extensions; | 605 return extensions; |
444 } | 606 } |
445 | 607 |
446 void* NativeViewGLSurfaceGLX::GetConfig() { | 608 void* NativeViewGLSurfaceGLX::GetConfig() { |
447 if (!config_) { | 609 if (!config_) { |
448 // This code path is expensive, but we only take it when | 610 // This code path is expensive, but we only take it when |
449 // attempting to use GLX_ARB_create_context_robustness, in which | 611 // attempting to use GLX_ARB_create_context_robustness, in which |
450 // case we need a GLXFBConfig for the window in order to create a | 612 // case we need a GLXFBConfig for the window in order to create a |
451 // context for it. | 613 // context for it. |
452 // | 614 // |
453 // TODO(kbr): this is not a reliable code path. On platforms which | 615 // TODO(kbr): this is not a reliable code path. On platforms which |
454 // support it, we should use glXChooseFBConfig in the browser | 616 // support it, we should use glXChooseFBConfig in the browser |
455 // process to choose the FBConfig and from there the X Visual to | 617 // 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 | 618 // use when creating the window in the first place. Then we can |
457 // pass that FBConfig down rather than attempting to reconstitute | 619 // pass that FBConfig down rather than attempting to reconstitute |
458 // it. | 620 // it. |
459 | 621 |
460 XWindowAttributes attributes; | 622 XWindowAttributes attributes; |
461 if (!XGetWindowAttributes( | 623 if (!XGetWindowAttributes( |
462 g_display, | 624 g_display, |
463 window_, | 625 parent_window_, |
464 &attributes)) { | 626 &attributes)) { |
465 LOG(ERROR) << "XGetWindowAttributes failed for window " << | 627 LOG(ERROR) << "XGetWindowAttributes failed for window " << |
466 window_ << "."; | 628 parent_window_ << "."; |
467 return NULL; | 629 return NULL; |
468 } | 630 } |
469 | 631 |
470 int visual_id = XVisualIDFromVisual(attributes.visual); | 632 int visual_id = XVisualIDFromVisual(attributes.visual); |
471 | 633 |
472 int num_elements = 0; | 634 int num_elements = 0; |
473 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( | 635 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( |
474 glXGetFBConfigs(g_display, | 636 glXGetFBConfigs(g_display, |
475 DefaultScreen(g_display), | 637 DefaultScreen(g_display), |
476 &num_elements)); | 638 &num_elements)); |
(...skipping 23 matching lines...) Expand all Loading... |
500 config_ = configs.get()[i]; | 662 config_ = configs.get()[i]; |
501 } | 663 } |
502 } | 664 } |
503 | 665 |
504 return config_; | 666 return config_; |
505 } | 667 } |
506 | 668 |
507 bool NativeViewGLSurfaceGLX::PostSubBuffer( | 669 bool NativeViewGLSurfaceGLX::PostSubBuffer( |
508 int x, int y, int width, int height) { | 670 int x, int y, int width, int height) { |
509 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); | 671 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); |
510 glXCopySubBufferMESA(g_display, window_, x, y, width, height); | 672 glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); |
511 return true; | 673 return true; |
512 } | 674 } |
513 | 675 |
514 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { | 676 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { |
515 return vsync_provider_.get(); | 677 return vsync_provider_.get(); |
516 } | 678 } |
517 | 679 |
518 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() | 680 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() |
519 : window_(0), | 681 : parent_window_(0), |
| 682 #if defined(TOOLKIT_GTK) |
| 683 child_window_(0), |
| 684 dummy_window_(0), |
| 685 backbuffer_allocated_(true), |
| 686 frontbuffer_allocated_(true), |
| 687 #endif |
520 config_(NULL) { | 688 config_(NULL) { |
521 } | 689 } |
522 | 690 |
523 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { | 691 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { |
524 Destroy(); | 692 Destroy(); |
525 } | 693 } |
526 | 694 |
527 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) | 695 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) |
528 : size_(size), | 696 : size_(size), |
529 config_(NULL), | 697 config_(NULL), |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 | 775 |
608 void* PbufferGLSurfaceGLX::GetConfig() { | 776 void* PbufferGLSurfaceGLX::GetConfig() { |
609 return config_; | 777 return config_; |
610 } | 778 } |
611 | 779 |
612 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { | 780 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { |
613 Destroy(); | 781 Destroy(); |
614 } | 782 } |
615 | 783 |
616 } // namespace gfx | 784 } // namespace gfx |
OLD | NEW |