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

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

Issue 1081533003: ui: Enable virtual contexts for linux (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change comment Created 5 years, 8 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
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
(...skipping 15 matching lines...) Expand all
26 #include "ui/gfx/x/x11_connection.h" 26 #include "ui/gfx/x/x11_connection.h"
27 #include "ui/gfx/x/x11_types.h" 27 #include "ui/gfx/x/x11_types.h"
28 #include "ui/gl/gl_bindings.h" 28 #include "ui/gl/gl_bindings.h"
29 #include "ui/gl/gl_implementation.h" 29 #include "ui/gl/gl_implementation.h"
30 #include "ui/gl/sync_control_vsync_provider.h" 30 #include "ui/gl/sync_control_vsync_provider.h"
31 31
32 namespace gfx { 32 namespace gfx {
33 33
34 namespace { 34 namespace {
35 35
36 Display* g_display = NULL; 36 Display* g_display = nullptr;
37 const char* g_glx_extensions = NULL; 37 const char* g_glx_extensions = nullptr;
38 bool g_glx_context_create = false; 38 bool g_glx_context_create = false;
39 bool g_glx_create_context_robustness_supported = false; 39 bool g_glx_create_context_robustness_supported = false;
40 bool g_glx_texture_from_pixmap_supported = false; 40 bool g_glx_texture_from_pixmap_supported = false;
41 bool g_glx_oml_sync_control_supported = false; 41 bool g_glx_oml_sync_control_supported = false;
42 42
43 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a 43 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a
44 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML 44 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML
45 // always fails even though GLX_OML_sync_control is reported as being supported. 45 // always fails even though GLX_OML_sync_control is reported as being supported.
46 bool g_glx_get_msc_rate_oml_supported = false; 46 bool g_glx_get_msc_rate_oml_supported = false;
47 47
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 113
114 private: 114 private:
115 friend class base::RefCounted<SGIVideoSyncThread>; 115 friend class base::RefCounted<SGIVideoSyncThread>;
116 116
117 SGIVideoSyncThread() : base::Thread("SGI_video_sync") { 117 SGIVideoSyncThread() : base::Thread("SGI_video_sync") {
118 DCHECK(CalledOnValidThread()); 118 DCHECK(CalledOnValidThread());
119 } 119 }
120 120
121 ~SGIVideoSyncThread() override { 121 ~SGIVideoSyncThread() override {
122 DCHECK(CalledOnValidThread()); 122 DCHECK(CalledOnValidThread());
123 g_video_sync_thread = NULL; 123 g_video_sync_thread = nullptr;
124 Stop(); 124 Stop();
125 } 125 }
126 126
127 static SGIVideoSyncThread* g_video_sync_thread; 127 static SGIVideoSyncThread* g_video_sync_thread;
128 128
129 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncThread); 129 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncThread);
130 }; 130 };
131 131
132 class SGIVideoSyncProviderThreadShim { 132 class SGIVideoSyncProviderThreadShim {
133 public: 133 public:
134 explicit SGIVideoSyncProviderThreadShim(XID window) 134 explicit SGIVideoSyncProviderThreadShim(XID window)
135 : window_(window), 135 : window_(window),
136 context_(NULL), 136 context_(nullptr),
137 task_runner_(base::ThreadTaskRunnerHandle::Get()), 137 task_runner_(base::ThreadTaskRunnerHandle::Get()),
138 cancel_vsync_flag_(), 138 cancel_vsync_flag_(),
139 vsync_lock_() { 139 vsync_lock_() {
140 // This ensures that creation of |window_| has occured when this shim 140 // This ensures that creation of |window_| has occured when this shim
141 // is executing in the same process as the call to create |window_|. 141 // is executing in the same process as the call to create |window_|.
142 XSync(g_display, False); 142 XSync(g_display, False);
143 } 143 }
144 144
145 virtual ~SGIVideoSyncProviderThreadShim() { 145 virtual ~SGIVideoSyncProviderThreadShim() {
146 if (context_) { 146 if (context_) {
147 glXDestroyContext(display_, context_); 147 glXDestroyContext(display_, context_);
148 context_ = NULL; 148 context_ = nullptr;
149 } 149 }
150 } 150 }
151 151
152 base::CancellationFlag* cancel_vsync_flag() { 152 base::CancellationFlag* cancel_vsync_flag() {
153 return &cancel_vsync_flag_; 153 return &cancel_vsync_flag_;
154 } 154 }
155 155
156 base::Lock* vsync_lock() { 156 base::Lock* vsync_lock() {
157 return &vsync_lock_; 157 return &vsync_lock_;
158 } 158 }
(...skipping 14 matching lines...) Expand all
173 int visual_info_count = 0; 173 int visual_info_count = 0;
174 gfx::XScopedPtr<XVisualInfo> visual_info_list(XGetVisualInfo( 174 gfx::XScopedPtr<XVisualInfo> visual_info_list(XGetVisualInfo(
175 display_, VisualIDMask, &visual_info_template, &visual_info_count)); 175 display_, VisualIDMask, &visual_info_template, &visual_info_count));
176 176
177 DCHECK(visual_info_list.get()); 177 DCHECK(visual_info_list.get());
178 if (visual_info_count == 0) { 178 if (visual_info_count == 0) {
179 LOG(ERROR) << "No visual info for visual ID."; 179 LOG(ERROR) << "No visual info for visual ID.";
180 return; 180 return;
181 } 181 }
182 182
183 context_ = glXCreateContext(display_, visual_info_list.get(), NULL, True); 183 context_ =
184 glXCreateContext(display_, visual_info_list.get(), nullptr, True);
184 185
185 DCHECK(NULL != context_); 186 DCHECK(nullptr != context_);
186 } 187 }
187 188
188 void GetVSyncParameters(const VSyncProvider::UpdateVSyncCallback& callback) { 189 void GetVSyncParameters(const VSyncProvider::UpdateVSyncCallback& callback) {
189 base::TimeTicks now; 190 base::TimeTicks now;
190 { 191 {
191 // Don't allow |window_| destruction while we're probing vsync. 192 // Don't allow |window_| destruction while we're probing vsync.
192 base::AutoLock locked(vsync_lock_); 193 base::AutoLock locked(vsync_lock_);
193 194
194 if (!context_ || cancel_vsync_flag_.IsSet()) 195 if (!context_ || cancel_vsync_flag_.IsSet())
195 return; 196 return;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 // These will only be referenced before we post a task to destroy 302 // These will only be referenced before we post a task to destroy
302 // the shim_, so they are safe to access. 303 // the shim_, so they are safe to access.
303 base::CancellationFlag* cancel_vsync_flag_; 304 base::CancellationFlag* cancel_vsync_flag_;
304 base::Lock* vsync_lock_; 305 base::Lock* vsync_lock_;
305 306
306 base::TimeTicks last_get_vsync_parameters_time_; 307 base::TimeTicks last_get_vsync_parameters_time_;
307 308
308 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider); 309 DISALLOW_COPY_AND_ASSIGN(SGIVideoSyncVSyncProvider);
309 }; 310 };
310 311
311 SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = NULL; 312 SGIVideoSyncThread* SGIVideoSyncThread::g_video_sync_thread = nullptr;
312 313
313 // In order to take advantage of GLX_SGI_video_sync, we need a display 314 // In order to take advantage of GLX_SGI_video_sync, we need a display
314 // for use on a separate thread. We must allocate this before the sandbox 315 // for use on a separate thread. We must allocate this before the sandbox
315 // goes up (rather than on-demand when we start the thread). 316 // goes up (rather than on-demand when we start the thread).
316 Display* SGIVideoSyncProviderThreadShim::display_ = NULL; 317 Display* SGIVideoSyncProviderThreadShim::display_ = nullptr;
317 318
318 } // namespace 319 } // namespace
319 320
320 GLSurfaceGLX::GLSurfaceGLX() {} 321 GLSurfaceGLX::GLSurfaceGLX() {}
321 322
322 bool GLSurfaceGLX::InitializeOneOff() { 323 bool GLSurfaceGLX::InitializeOneOff() {
323 static bool initialized = false; 324 static bool initialized = false;
324 if (initialized) 325 if (initialized)
325 return true; 326 return true;
326 327
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 bool GLSurfaceGLX::IsOMLSyncControlSupported() { 398 bool GLSurfaceGLX::IsOMLSyncControlSupported() {
398 return g_glx_oml_sync_control_supported; 399 return g_glx_oml_sync_control_supported;
399 } 400 }
400 401
401 void* GLSurfaceGLX::GetDisplay() { 402 void* GLSurfaceGLX::GetDisplay() {
402 return g_display; 403 return g_display;
403 } 404 }
404 405
405 GLSurfaceGLX::~GLSurfaceGLX() {} 406 GLSurfaceGLX::~GLSurfaceGLX() {}
406 407
408 void* GLSurfaceGLX::GetConfig(gfx::AcceleratedWidget window) {
409 DCHECK(window != 0);
410
411 // This code path is expensive, but we only take it when
412 // attempting to use GLX_ARB_create_context_robustness, in which
413 // case we need a GLXFBConfig for the window in order to create a
414 // context for it.
415 //
416 // TODO(kbr): this is not a reliable code path. On platforms which
417 // support it, we should use glXChooseFBConfig in the browser
418 // process to choose the FBConfig and from there the X Visual to
419 // use when creating the window in the first place. Then we can
420 // pass that FBConfig down rather than attempting to reconstitute
421 // it.
422
423 XWindowAttributes attributes;
424 if (!XGetWindowAttributes(g_display, window, &attributes)) {
425 LOG(ERROR) << "XGetWindowAttributes failed for window " << window << ".";
426 return nullptr;
427 }
428
429 int visual_id = XVisualIDFromVisual(attributes.visual);
430
431 int num_elements = 0;
432 gfx::XScopedPtr<GLXFBConfig> configs(
433 glXGetFBConfigs(g_display, DefaultScreen(g_display), &num_elements));
434 if (!configs.get()) {
435 LOG(ERROR) << "glXGetFBConfigs failed.";
436 return nullptr;
437 }
438 if (!num_elements) {
439 LOG(ERROR) << "glXGetFBConfigs returned 0 elements.";
440 return nullptr;
441 }
442 bool found = false;
443 int i;
444 for (i = 0; i < num_elements; ++i) {
445 int value;
446 if (glXGetFBConfigAttrib(g_display, configs.get()[i], GLX_VISUAL_ID,
447 &value)) {
448 LOG(ERROR) << "glXGetFBConfigAttrib failed.";
449 return nullptr;
450 }
451 if (value == visual_id) {
452 found = true;
453 break;
454 }
455 }
456 if (found) {
457 return configs.get()[i];
458 }
459 return nullptr;
460 }
461
407 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) 462 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window)
408 : parent_window_(window), 463 : parent_window_(window), window_(0), config_(nullptr) {
409 window_(0),
410 config_(NULL) {
411 } 464 }
412 465
413 gfx::AcceleratedWidget NativeViewGLSurfaceGLX::GetDrawableHandle() const { 466 gfx::AcceleratedWidget NativeViewGLSurfaceGLX::GetDrawableHandle() const {
414 return window_; 467 return window_;
415 } 468 }
416 469
417 bool NativeViewGLSurfaceGLX::Initialize() { 470 bool NativeViewGLSurfaceGLX::Initialize() {
418 XWindowAttributes attributes; 471 XWindowAttributes attributes;
419 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { 472 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) {
420 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ 473 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_
421 << "."; 474 << ".";
422 return false; 475 return false;
423 } 476 }
424 size_ = gfx::Size(attributes.width, attributes.height); 477 size_ = gfx::Size(attributes.width, attributes.height);
425 // Create a child window, with a CopyFromParent visual (to avoid inducing 478 // Create a child window, with a CopyFromParent visual (to avoid inducing
426 // extra blits in the driver), that we can resize exactly in Resize(), 479 // extra blits in the driver), that we can resize exactly in Resize(),
427 // correctly ordered with GL, so that we don't have invalid transient states. 480 // correctly ordered with GL, so that we don't have invalid transient states.
428 // See https://crbug.com/326995. 481 // See https://crbug.com/326995.
429 window_ = XCreateWindow(g_display, 482 window_ = XCreateWindow(g_display, parent_window_, 0, 0, size_.width(),
430 parent_window_, 483 size_.height(), 0, CopyFromParent, InputOutput,
431 0, 484 CopyFromParent, 0, nullptr);
432 0,
433 size_.width(),
434 size_.height(),
435 0,
436 CopyFromParent,
437 InputOutput,
438 CopyFromParent,
439 0,
440 NULL);
441 XMapWindow(g_display, window_); 485 XMapWindow(g_display, window_);
442 486
443 ui::PlatformEventSource* event_source = 487 ui::PlatformEventSource* event_source =
444 ui::PlatformEventSource::GetInstance(); 488 ui::PlatformEventSource::GetInstance();
445 // Can be NULL in tests, when we don't care about Exposes. 489 // Can be nullptr in tests, when we don't care about Exposes.
446 if (event_source) { 490 if (event_source) {
447 XSelectInput(g_display, window_, ExposureMask); 491 XSelectInput(g_display, window_, ExposureMask);
448 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); 492 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
449 } 493 }
450 XFlush(g_display); 494 XFlush(g_display);
451 495
452 gfx::AcceleratedWidget window_for_vsync = window_; 496 gfx::AcceleratedWidget window_for_vsync = window_;
453 497
454 if (g_glx_oml_sync_control_supported) 498 if (g_glx_oml_sync_control_supported)
455 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_for_vsync)); 499 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_for_vsync));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 555
512 void* NativeViewGLSurfaceGLX::GetHandle() { 556 void* NativeViewGLSurfaceGLX::GetHandle() {
513 return reinterpret_cast<void*>(GetDrawableHandle()); 557 return reinterpret_cast<void*>(GetDrawableHandle());
514 } 558 }
515 559
516 bool NativeViewGLSurfaceGLX::SupportsPostSubBuffer() { 560 bool NativeViewGLSurfaceGLX::SupportsPostSubBuffer() {
517 return gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer; 561 return gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer;
518 } 562 }
519 563
520 void* NativeViewGLSurfaceGLX::GetConfig() { 564 void* NativeViewGLSurfaceGLX::GetConfig() {
521 if (!config_) { 565 if (!config_)
522 // This code path is expensive, but we only take it when 566 config_ = GLSurfaceGLX::GetConfig(window_);
523 // attempting to use GLX_ARB_create_context_robustness, in which
524 // case we need a GLXFBConfig for the window in order to create a
525 // context for it.
526 //
527 // TODO(kbr): this is not a reliable code path. On platforms which
528 // support it, we should use glXChooseFBConfig in the browser
529 // process to choose the FBConfig and from there the X Visual to
530 // use when creating the window in the first place. Then we can
531 // pass that FBConfig down rather than attempting to reconstitute
532 // it.
533
534 XWindowAttributes attributes;
535 if (!XGetWindowAttributes(
536 g_display,
537 window_,
538 &attributes)) {
539 LOG(ERROR) << "XGetWindowAttributes failed for window " <<
540 window_ << ".";
541 return NULL;
542 }
543
544 int visual_id = XVisualIDFromVisual(attributes.visual);
545
546 int num_elements = 0;
547 gfx::XScopedPtr<GLXFBConfig> configs(
548 glXGetFBConfigs(g_display, DefaultScreen(g_display), &num_elements));
549 if (!configs.get()) {
550 LOG(ERROR) << "glXGetFBConfigs failed.";
551 return NULL;
552 }
553 if (!num_elements) {
554 LOG(ERROR) << "glXGetFBConfigs returned 0 elements.";
555 return NULL;
556 }
557 bool found = false;
558 int i;
559 for (i = 0; i < num_elements; ++i) {
560 int value;
561 if (glXGetFBConfigAttrib(
562 g_display, configs.get()[i], GLX_VISUAL_ID, &value)) {
563 LOG(ERROR) << "glXGetFBConfigAttrib failed.";
564 return NULL;
565 }
566 if (value == visual_id) {
567 found = true;
568 break;
569 }
570 }
571 if (found) {
572 config_ = configs.get()[i];
573 }
574 }
575
576 return config_; 567 return config_;
577 } 568 }
578 569
579 bool NativeViewGLSurfaceGLX::PostSubBuffer( 570 bool NativeViewGLSurfaceGLX::PostSubBuffer(
580 int x, int y, int width, int height) { 571 int x, int y, int width, int height) {
581 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); 572 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer);
582 glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); 573 glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height);
583 return true; 574 return true;
584 } 575 }
585 576
586 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { 577 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() {
587 return vsync_provider_.get(); 578 return vsync_provider_.get();
588 } 579 }
589 580
590 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { 581 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() {
591 Destroy(); 582 Destroy();
592 } 583 }
593 584
594 PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) 585 UnmappedNativeViewGLSurfaceGLX::UnmappedNativeViewGLSurfaceGLX(
595 : size_(size), 586 const gfx::Size& size)
596 config_(NULL), 587 : size_(size), config_(nullptr), window_(0) {
597 pbuffer_(0) { 588 // Ensure that we don't create a window with zero size.
598 // Some implementations of Pbuffer do not support having a 0 size. For such
599 // cases use a (1, 1) surface.
600 if (size_.GetArea() == 0) 589 if (size_.GetArea() == 0)
hendrikw 2015/04/17 18:59:46 I think it's safer to leave this in, but it would
piman 2015/04/17 19:37:29 AIUI yes it's needed. XCreatWindow(3) isn't clear
601 size_.SetSize(1, 1); 590 size_.SetSize(1, 1);
602 } 591 }
603 592
604 bool PbufferGLSurfaceGLX::Initialize() { 593 bool UnmappedNativeViewGLSurfaceGLX::Initialize() {
605 DCHECK(!pbuffer_); 594 DCHECK(!window_);
606 595
607 static const int config_attributes[] = { 596 gfx::AcceleratedWidget parent_window =
608 GLX_BUFFER_SIZE, 32, 597 RootWindow(g_display, DefaultScreen(g_display));
609 GLX_ALPHA_SIZE, 8,
610 GLX_BLUE_SIZE, 8,
611 GLX_GREEN_SIZE, 8,
612 GLX_RED_SIZE, 8,
613 GLX_RENDER_TYPE, GLX_RGBA_BIT,
614 GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
615 GLX_DOUBLEBUFFER, False,
616 0
617 };
618 598
619 int num_elements = 0; 599 // We create a window with CopyFromParent visual so that we have the same
620 gfx::XScopedPtr<GLXFBConfig> configs(glXChooseFBConfig( 600 // visual as NativeViewGLSurfaceGLX (i.e. same GLXFBConfig), to ensure
621 g_display, DefaultScreen(g_display), config_attributes, &num_elements)); 601 // contexts are compatible and can be made current with either.
622 if (!configs.get()) { 602 window_ = XCreateWindow(g_display, parent_window, 0, 0, size_.width(),
623 LOG(ERROR) << "glXChooseFBConfig failed."; 603 size_.height(), 0, CopyFromParent, InputOutput,
624 return false; 604 CopyFromParent, 0, nullptr);
605 return window_ != 0;
606 }
607
608 void UnmappedNativeViewGLSurfaceGLX::Destroy() {
609 config_ = nullptr;
610 if (window_) {
611 XDestroyWindow(g_display, window_);
612 window_ = 0;
625 } 613 }
626 if (!num_elements) { 614 }
627 LOG(ERROR) << "glXChooseFBConfig returned 0 elements.";
628 return false;
629 }
630 615
631 config_ = configs.get()[0]; 616 bool UnmappedNativeViewGLSurfaceGLX::IsOffscreen() {
632
633 const int pbuffer_attributes[] = {
634 GLX_PBUFFER_WIDTH, size_.width(),
635 GLX_PBUFFER_HEIGHT, size_.height(),
636 0
637 };
638 pbuffer_ = glXCreatePbuffer(g_display,
639 static_cast<GLXFBConfig>(config_),
640 pbuffer_attributes);
641 if (!pbuffer_) {
642 Destroy();
643 LOG(ERROR) << "glXCreatePbuffer failed.";
644 return false;
645 }
646
647 return true; 617 return true;
648 } 618 }
649 619
650 void PbufferGLSurfaceGLX::Destroy() { 620 bool UnmappedNativeViewGLSurfaceGLX::SwapBuffers() {
651 if (pbuffer_) { 621 NOTREACHED() << "Attempted to call SwapBuffers on an unmapped window.";
652 glXDestroyPbuffer(g_display, pbuffer_);
653 pbuffer_ = 0;
654 }
655
656 config_ = NULL;
657 }
658
659 bool PbufferGLSurfaceGLX::IsOffscreen() {
660 return true;
661 }
662
663 bool PbufferGLSurfaceGLX::SwapBuffers() {
664 NOTREACHED() << "Attempted to call SwapBuffers on a pbuffer.";
665 return false; 622 return false;
666 } 623 }
667 624
668 gfx::Size PbufferGLSurfaceGLX::GetSize() { 625 gfx::Size UnmappedNativeViewGLSurfaceGLX::GetSize() {
669 return size_; 626 return size_;
670 } 627 }
671 628
672 void* PbufferGLSurfaceGLX::GetHandle() { 629 void* UnmappedNativeViewGLSurfaceGLX::GetHandle() {
673 return reinterpret_cast<void*>(pbuffer_); 630 return reinterpret_cast<void*>(window_);
674 } 631 }
675 632
676 void* PbufferGLSurfaceGLX::GetConfig() { 633 void* UnmappedNativeViewGLSurfaceGLX::GetConfig() {
634 if (!config_)
635 config_ = GLSurfaceGLX::GetConfig(window_);
677 return config_; 636 return config_;
678 } 637 }
679 638
680 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { 639 UnmappedNativeViewGLSurfaceGLX::~UnmappedNativeViewGLSurfaceGLX() {
681 Destroy(); 640 Destroy();
682 } 641 }
683 642
684 } // namespace gfx 643 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698