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 3 // found in the LICENSE file. 4 5 // This include must be here so that the includes provided transitively 6 // by gl_surface_egl.h don't make it impossible to compile this code. 7 #include "third_party/mesa/src/include/GL/osmesa.h" 8 9 #include "ui/gl/gl_surface_egl.h" 10 11 #if defined(OS_ANDROID) 12 #include <android/native_window_jni.h> 13 #endif 14 15 #include "base/command_line.h" 16 #include "base/logging.h" 17 #include "base/memory/scoped_ptr.h" 18 #include "base/message_loop/message_loop.h" 19 #include "build/build_config.h" 20 #include "ui/gl/egl_util.h" 21 #include "ui/gl/gl_context.h" 22 #include "ui/gl/gl_implementation.h" 23 #include "ui/gl/gl_surface_osmesa.h" 24 #include "ui/gl/gl_surface_stub.h" 25 #include "ui/gl/gl_switches.h" 26 #include "ui/gl/scoped_make_current.h" 27 #include "ui/gl/sync_control_vsync_provider.h" 28 29 #if defined(USE_X11) 30 extern "C" { 31 #include <X11/Xlib.h> 32 } 33 #endif 34 35 #if defined (USE_OZONE) 36 #include "ui/gfx/ozone/surface_factory_ozone.h" 37 #endif 38 39 // From ANGLE's egl/eglext.h. 40 #if !defined(EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE) 41 #define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE \ 42 reinterpret_cast<EGLNativeDisplayType>(-2) 43 #endif 44 45 using ui::GetLastEGLErrorString; 46 47 namespace gfx { 48 49 namespace { 50 51 EGLConfig g_config; 52 EGLDisplay g_display; 53 EGLNativeDisplayType g_native_display; 54 55 const char* g_egl_extensions = NULL; 56 bool g_egl_create_context_robustness_supported = false; 57 bool g_egl_sync_control_supported = false; 58 bool g_egl_surfaceless_context_supported = false; 59 60 class EGLSyncControlVSyncProvider 61 : public gfx::SyncControlVSyncProvider { 62 public: 63 explicit EGLSyncControlVSyncProvider(EGLSurface surface) 64 : SyncControlVSyncProvider(), 65 surface_(surface) { 66 } 67 68 virtual ~EGLSyncControlVSyncProvider() { } 69 70 protected: 71 virtual bool GetSyncValues(int64* system_time, 72 int64* media_stream_counter, 73 int64* swap_buffer_counter) OVERRIDE { 74 uint64 u_system_time, u_media_stream_counter, u_swap_buffer_counter; 75 bool result = eglGetSyncValuesCHROMIUM( 76 g_display, surface_, &u_system_time, 77 &u_media_stream_counter, &u_swap_buffer_counter) == EGL_TRUE; 78 if (result) { 79 *system_time = static_cast<int64>(u_system_time); 80 *media_stream_counter = static_cast<int64>(u_media_stream_counter); 81 *swap_buffer_counter = static_cast<int64>(u_swap_buffer_counter); 82 } 83 return result; 84 } 85 86 virtual bool GetMscRate(int32* numerator, int32* denominator) OVERRIDE { 87 return false; 88 } 89 90 private: 91 EGLSurface surface_; 92 93 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); 94 }; 95 96 } // namespace 97 98 GLSurfaceEGL::GLSurfaceEGL() {} 99 100 bool GLSurfaceEGL::InitializeOneOff() { 101 static bool initialized = false; 102 if (initialized) 103 return true; 104 105 #if defined(USE_X11) 106 g_native_display = base::MessagePumpForUI::GetDefaultXDisplay(); 107 #elif defined(OS_WIN) 108 g_native_display = EGL_DEFAULT_DISPLAY; 109 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableD3D11) && 110 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableD3D11)) { 111 g_native_display = EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE; 112 } 113 #elif defined(USE_OZONE) 114 gfx::SurfaceFactoryOzone* surface_factory = 115 gfx::SurfaceFactoryOzone::GetInstance(); 116 if (surface_factory->InitializeHardware() != 117 gfx::SurfaceFactoryOzone::INITIALIZED) { 118 LOG(ERROR) << "OZONE failed to initialize hardware"; 119 return false; 120 } 121 g_native_display = reinterpret_cast<EGLNativeDisplayType>( 122 surface_factory->GetNativeDisplay()); 123 #else 124 g_native_display = EGL_DEFAULT_DISPLAY; 125 #endif 126 g_display = eglGetDisplay(g_native_display); 127 if (!g_display) { 128 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); 129 return false; 130 } 131 132 if (!eglInitialize(g_display, NULL, NULL)) { 133 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); 134 return false; 135 } 136 137 // Choose an EGL configuration. 138 // On X this is only used for PBuffer surfaces. 139 static const EGLint kConfigAttribs[] = { 140 EGL_BUFFER_SIZE, 32, 141 EGL_ALPHA_SIZE, 8, 142 EGL_BLUE_SIZE, 8, 143 EGL_GREEN_SIZE, 8, 144 EGL_RED_SIZE, 8, 145 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 146 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, 147 EGL_NONE 148 }; 149 150 #if defined(USE_OZONE) 151 const EGLint* config_attribs = 152 surface_factory->GetEGLSurfaceProperties(kConfigAttribs); 153 #else 154 const EGLint* config_attribs = kConfigAttribs; 155 #endif 156 157 EGLint num_configs; 158 if (!eglChooseConfig(g_display, 159 config_attribs, 160 NULL, 161 0, 162 &num_configs)) { 163 LOG(ERROR) << "eglChooseConfig failed with error " 164 << GetLastEGLErrorString(); 165 return false; 166 } 167 168 if (num_configs == 0) { 169 LOG(ERROR) << "No suitable EGL configs found."; 170 return false; 171 } 172 173 if (!eglChooseConfig(g_display, 174 config_attribs, 175 &g_config, 176 1, 177 &num_configs)) { 178 LOG(ERROR) << "eglChooseConfig failed with error " 179 << GetLastEGLErrorString(); 180 return false; 181 } 182 183 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); 184 g_egl_create_context_robustness_supported = 185 HasEGLExtension("EGL_EXT_create_context_robustness"); 186 g_egl_sync_control_supported = 187 HasEGLExtension("EGL_CHROMIUM_sync_control"); 188 189 // Check if SurfacelessEGL is supported. 190 g_egl_surfaceless_context_supported = 191 HasEGLExtension("EGL_KHR_surfaceless_context"); 192 if (g_egl_surfaceless_context_supported) { 193 // EGL_KHR_surfaceless_context is supported but ensure 194 // GL_OES_surfaceless_context is also supported. We need a current context 195 // to query for supported GL extensions. 196 scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1)); 197 scoped_refptr<GLContext> context = GLContext::CreateGLContext( 198 NULL, surface.get(), PreferIntegratedGpu); 199 if (!context->MakeCurrent(surface.get())) 200 g_egl_surfaceless_context_supported = false; 201 202 // Ensure context supports GL_OES_surfaceless_context. 203 if (g_egl_surfaceless_context_supported) { 204 g_egl_surfaceless_context_supported = context->HasExtension( 205 "GL_OES_surfaceless_context"); 206 context->ReleaseCurrent(surface.get()); 207 } 208 } 209 210 initialized = true; 211 212 return true; 213 } 214 215 EGLDisplay GLSurfaceEGL::GetDisplay() { 216 return g_display; 217 } 218 219 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { 220 return g_display; 221 } 222 223 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { 224 return g_native_display; 225 } 226 227 const char* GLSurfaceEGL::GetEGLExtensions() { 228 return g_egl_extensions; 229 } 230 231 bool GLSurfaceEGL::HasEGLExtension(const char* name) { 232 return ExtensionsContain(GetEGLExtensions(), name); 233 } 234 235 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { 236 return g_egl_create_context_robustness_supported; 237 } 238 239 GLSurfaceEGL::~GLSurfaceEGL() {} 240 241 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(gfx::AcceleratedWidget window) 242 : window_(window), 243 surface_(NULL), 244 supports_post_sub_buffer_(false), 245 config_(NULL) { 246 #if defined(OS_ANDROID) 247 if (window) 248 ANativeWindow_acquire(window); 249 #endif 250 } 251 252 bool NativeViewGLSurfaceEGL::Initialize() { 253 return Initialize(NULL); 254 } 255 256 bool NativeViewGLSurfaceEGL::Initialize(VSyncProvider* sync_provider) { 257 DCHECK(!surface_); 258 scoped_ptr<VSyncProvider> vsync_provider(sync_provider); 259 260 if (window_ == kNullAcceleratedWidget) { 261 LOG(ERROR) << "Trying to create surface without window."; 262 return false; 263 } 264 265 if (!GetDisplay()) { 266 LOG(ERROR) << "Trying to create surface with invalid display."; 267 return false; 268 } 269 270 static const EGLint egl_window_attributes_sub_buffer[] = { 271 EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_TRUE, 272 EGL_NONE 273 }; 274 275 // Create a surface for the native window. 276 surface_ = eglCreateWindowSurface( 277 GetDisplay(), 278 GetConfig(), 279 window_, 280 gfx::g_driver_egl.ext.b_EGL_NV_post_sub_buffer ? 281 egl_window_attributes_sub_buffer : 282 NULL); 283 284 if (!surface_) { 285 LOG(ERROR) << "eglCreateWindowSurface failed with error " 286 << GetLastEGLErrorString(); 287 Destroy(); 288 return false; 289 } 290 291 EGLint surfaceVal; 292 EGLBoolean retVal = eglQuerySurface(GetDisplay(), 293 surface_, 294 EGL_POST_SUB_BUFFER_SUPPORTED_NV, 295 &surfaceVal); 296 supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE; 297 298 if (sync_provider) 299 vsync_provider_.swap(vsync_provider); 300 else if (g_egl_sync_control_supported) 301 vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_)); 302 return true; 303 } 304 305 void NativeViewGLSurfaceEGL::Destroy() { 306 if (surface_) { 307 if (!eglDestroySurface(GetDisplay(), surface_)) { 308 LOG(ERROR) << "eglDestroySurface failed with error " 309 << GetLastEGLErrorString(); 310 } 311 surface_ = NULL; 312 } 313 } 314 315 EGLConfig NativeViewGLSurfaceEGL::GetConfig() { 316 #if !defined(USE_X11) 317 return g_config; 318 #else 319 if (!config_) { 320 // Get a config compatible with the window 321 DCHECK(window_); 322 XWindowAttributes win_attribs; 323 if (!XGetWindowAttributes(GetNativeDisplay(), window_, &win_attribs)) { 324 return NULL; 325 } 326 327 // Try matching the window depth with an alpha channel, 328 // because we're worried the destination alpha width could 329 // constrain blending precision. 330 const int kBufferSizeOffset = 1; 331 const int kAlphaSizeOffset = 3; 332 EGLint config_attribs[] = { 333 EGL_BUFFER_SIZE, ~0, 334 EGL_ALPHA_SIZE, 8, 335 EGL_BLUE_SIZE, 8, 336 EGL_GREEN_SIZE, 8, 337 EGL_RED_SIZE, 8, 338 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 339 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, 340 EGL_NONE 341 }; 342 config_attribs[kBufferSizeOffset] = win_attribs.depth; 343 344 EGLint num_configs; 345 if (!eglChooseConfig(g_display, 346 config_attribs, 347 &config_, 348 1, 349 &num_configs)) { 350 LOG(ERROR) << "eglChooseConfig failed with error " 351 << GetLastEGLErrorString(); 352 return NULL; 353 } 354 355 if (num_configs) { 356 EGLint config_depth; 357 if (!eglGetConfigAttrib(g_display, 358 config_, 359 EGL_BUFFER_SIZE, 360 &config_depth)) { 361 LOG(ERROR) << "eglGetConfigAttrib failed with error " 362 << GetLastEGLErrorString(); 363 return NULL; 364 } 365 366 if (config_depth == win_attribs.depth) { 367 return config_; 368 } 369 } 370 371 // Try without an alpha channel. 372 config_attribs[kAlphaSizeOffset] = 0; 373 if (!eglChooseConfig(g_display, 374 config_attribs, 375 &config_, 376 1, 377 &num_configs)) { 378 LOG(ERROR) << "eglChooseConfig failed with error " 379 << GetLastEGLErrorString(); 380 return NULL; 381 } 382 383 if (num_configs == 0) { 384 LOG(ERROR) << "No suitable EGL configs found."; 385 return NULL; 386 } 387 } 388 return config_; 389 #endif 390 } 391 392 bool NativeViewGLSurfaceEGL::IsOffscreen() { 393 return false; 394 } 395 396 bool NativeViewGLSurfaceEGL::SwapBuffers() { 397 if (!eglSwapBuffers(GetDisplay(), surface_)) { 398 DVLOG(1) << "eglSwapBuffers failed with error " 399 << GetLastEGLErrorString(); 400 return false; 401 } 402 403 return true; 404 } 405 406 gfx::Size NativeViewGLSurfaceEGL::GetSize() { 407 EGLint width; 408 EGLint height; 409 if (!eglQuerySurface(GetDisplay(), surface_, EGL_WIDTH, &width) || 410 !eglQuerySurface(GetDisplay(), surface_, EGL_HEIGHT, &height)) { 411 NOTREACHED() << "eglQuerySurface failed with error " 412 << GetLastEGLErrorString(); 413 return gfx::Size(); 414 } 415 416 return gfx::Size(width, height); 417 } 418 419 bool NativeViewGLSurfaceEGL::Resize(const gfx::Size& size) { 420 if (size == GetSize()) 421 return true; 422 423 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; 424 GLContext* current_context = GLContext::GetCurrent(); 425 bool was_current = 426 current_context && current_context->IsCurrent(this); 427 if (was_current) { 428 scoped_make_current.reset( 429 new ui::ScopedMakeCurrent(current_context, this)); 430 current_context->ReleaseCurrent(this); 431 } 432 433 Destroy(); 434 435 if (!Initialize()) { 436 LOG(ERROR) << "Failed to resize window."; 437 return false; 438 } 439 440 return true; 441 } 442 443 bool NativeViewGLSurfaceEGL::Recreate() { 444 Destroy(); 445 if (!Initialize()) { 446 LOG(ERROR) << "Failed to create surface."; 447 return false; 448 } 449 return true; 450 } 451 452 EGLSurface NativeViewGLSurfaceEGL::GetHandle() { 453 return surface_; 454 } 455 456 std::string NativeViewGLSurfaceEGL::GetExtensions() { 457 std::string extensions = GLSurface::GetExtensions(); 458 if (supports_post_sub_buffer_) { 459 extensions += extensions.empty() ? "" : " "; 460 extensions += "GL_CHROMIUM_post_sub_buffer"; 461 } 462 return extensions; 463 } 464 465 bool NativeViewGLSurfaceEGL::PostSubBuffer( 466 int x, int y, int width, int height) { 467 DCHECK(supports_post_sub_buffer_); 468 if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) { 469 DVLOG(1) << "eglPostSubBufferNV failed with error " 470 << GetLastEGLErrorString(); 471 return false; 472 } 473 return true; 474 } 475 476 VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() { 477 return vsync_provider_.get(); 478 } 479 480 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { 481 Destroy(); 482 #if defined(OS_ANDROID) 483 if (window_) 484 ANativeWindow_release(window_); 485 #endif 486 } 487 488 void NativeViewGLSurfaceEGL::SetHandle(EGLSurface surface) { 489 surface_ = surface; 490 } 491 492 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) 493 : size_(size), 494 surface_(NULL) { 495 } 496 497 bool PbufferGLSurfaceEGL::Initialize() { 498 EGLSurface old_surface = surface_; 499 500 EGLDisplay display = GetDisplay(); 501 if (!display) { 502 LOG(ERROR) << "Trying to create surface with invalid display."; 503 return false; 504 } 505 506 if (size_.GetArea() == 0) { 507 LOG(ERROR) << "Error: surface has zero area " 508 << size_.width() << " x " << size_.height(); 509 return false; 510 } 511 512 // Allocate the new pbuffer surface before freeing the old one to ensure 513 // they have different addresses. If they have the same address then a 514 // future call to MakeCurrent might early out because it appears the current 515 // context and surface have not changed. 516 const EGLint pbuffer_attribs[] = { 517 EGL_WIDTH, size_.width(), 518 EGL_HEIGHT, size_.height(), 519 EGL_NONE 520 }; 521 522 EGLSurface new_surface = eglCreatePbufferSurface(display, 523 GetConfig(), 524 pbuffer_attribs); 525 if (!new_surface) { 526 LOG(ERROR) << "eglCreatePbufferSurface failed with error " 527 << GetLastEGLErrorString(); 528 return false; 529 } 530 531 if (old_surface) 532 eglDestroySurface(display, old_surface); 533 534 surface_ = new_surface; 535 return true; 536 } 537 538 void PbufferGLSurfaceEGL::Destroy() { 539 if (surface_) { 540 if (!eglDestroySurface(GetDisplay(), surface_)) { 541 LOG(ERROR) << "eglDestroySurface failed with error " 542 << GetLastEGLErrorString(); 543 } 544 surface_ = NULL; 545 } 546 } 547 548 EGLConfig PbufferGLSurfaceEGL::GetConfig() { 549 return g_config; 550 } 551 552 bool PbufferGLSurfaceEGL::IsOffscreen() { 553 return true; 554 } 555 556 bool PbufferGLSurfaceEGL::SwapBuffers() { 557 NOTREACHED() << "Attempted to call SwapBuffers on a PbufferGLSurfaceEGL."; 558 return false; 559 } 560 561 gfx::Size PbufferGLSurfaceEGL::GetSize() { 562 return size_; 563 } 564 565 bool PbufferGLSurfaceEGL::Resize(const gfx::Size& size) { 566 if (size == size_) 567 return true; 568 569 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; 570 GLContext* current_context = GLContext::GetCurrent(); 571 bool was_current = 572 current_context && current_context->IsCurrent(this); 573 if (was_current) { 574 scoped_make_current.reset( 575 new ui::ScopedMakeCurrent(current_context, this)); 576 } 577 578 size_ = size; 579 580 if (!Initialize()) { 581 LOG(ERROR) << "Failed to resize pbuffer."; 582 return false; 583 } 584 585 return true; 586 } 587 588 EGLSurface PbufferGLSurfaceEGL::GetHandle() { 589 return surface_; 590 } 591 592 void* PbufferGLSurfaceEGL::GetShareHandle() { 593 #if defined(OS_ANDROID) 594 NOTREACHED(); 595 return NULL; 596 #else 597 if (!gfx::g_driver_egl.ext.b_EGL_ANGLE_query_surface_pointer) 598 return NULL; 599 600 if (!gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle) 601 return NULL; 602 603 void* handle; 604 if (!eglQuerySurfacePointerANGLE(g_display, 605 GetHandle(), 606 EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, 607 &handle)) { 608 return NULL; 609 } 610 611 return handle; 612 #endif 613 } 614 615 PbufferGLSurfaceEGL::~PbufferGLSurfaceEGL() { 616 Destroy(); 617 } 618 619 SurfacelessEGL::SurfacelessEGL(const gfx::Size& size) 620 : size_(size) { 621 } 622 623 bool SurfacelessEGL::Initialize() { 624 return true; 625 } 626 627 void SurfacelessEGL::Destroy() { 628 } 629 630 EGLConfig SurfacelessEGL::GetConfig() { 631 return g_config; 632 } 633 634 bool SurfacelessEGL::IsOffscreen() { 635 return true; 636 } 637 638 bool SurfacelessEGL::SwapBuffers() { 639 LOG(ERROR) << "Attempted to call SwapBuffers with SurfacelessEGL."; 640 return false; 641 } 642 643 gfx::Size SurfacelessEGL::GetSize() { 644 return size_; 645 } 646 647 bool SurfacelessEGL::Resize(const gfx::Size& size) { 648 size_ = size; 649 return true; 650 } 651 652 EGLSurface SurfacelessEGL::GetHandle() { 653 return EGL_NO_SURFACE; 654 } 655 656 void* SurfacelessEGL::GetShareHandle() { 657 return NULL; 658 } 659 660 SurfacelessEGL::~SurfacelessEGL() { 661 } 662 663 #if defined(ANDROID) || defined(USE_OZONE) 664 665 // A thin subclass of |GLSurfaceOSMesa| that can be used in place 666 // of a native hardware-provided surface when a native surface 667 // provider is not available. 668 class GLSurfaceOSMesaHeadless : public GLSurfaceOSMesa { 669 public: 670 explicit GLSurfaceOSMesaHeadless(gfx::AcceleratedWidget window); 671 672 virtual bool IsOffscreen() OVERRIDE; 673 virtual bool SwapBuffers() OVERRIDE; 674 675 protected: 676 virtual ~GLSurfaceOSMesaHeadless(); 677 678 private: 679 680 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOSMesaHeadless); 681 }; 682 683 bool GLSurfaceOSMesaHeadless::IsOffscreen() { return false; } 684 685 bool GLSurfaceOSMesaHeadless::SwapBuffers() { return true; } 686 687 GLSurfaceOSMesaHeadless::GLSurfaceOSMesaHeadless(gfx::AcceleratedWidget window) 688 : GLSurfaceOSMesa(OSMESA_BGRA, gfx::Size(1, 1)) { 689 DCHECK(window); 690 } 691 692 GLSurfaceOSMesaHeadless::~GLSurfaceOSMesaHeadless() { Destroy(); } 693 694 // static 695 bool GLSurface::InitializeOneOffInternal() { 696 if (GetGLImplementation() == kGLImplementationOSMesaGL) { 697 return true; 698 } 699 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); 700 701 if (!GLSurfaceEGL::InitializeOneOff()) { 702 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; 703 return false; 704 } 705 return true; 706 } 707 708 // static 709 scoped_refptr<GLSurface> 710 GLSurface::CreateViewGLSurface(gfx::AcceleratedWidget window) { 711 712 if (GetGLImplementation() == kGLImplementationOSMesaGL) { 713 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless(window)); 714 if (!surface->Initialize()) 715 return NULL; 716 return surface; 717 } 718 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); 719 if (window) { 720 scoped_refptr<NativeViewGLSurfaceEGL> surface; 721 VSyncProvider* sync_provider = NULL; 722 #if defined(USE_OZONE) 723 window = gfx::SurfaceFactoryOzone::GetInstance()->RealizeAcceleratedWidget( 724 window); 725 sync_provider = 726 gfx::SurfaceFactoryOzone::GetInstance()->GetVSyncProvider(window); 727 #endif 728 surface = new NativeViewGLSurfaceEGL(window); 729 if(surface->Initialize(sync_provider)) 730 return surface; 731 } else { 732 scoped_refptr<GLSurface> surface = new GLSurfaceStub(); 733 if (surface->Initialize()) 734 return surface; 735 } 736 return NULL; 737 } 738 739 // static 740 scoped_refptr<GLSurface> 741 GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) { 742 switch (GetGLImplementation()) { 743 case kGLImplementationOSMesaGL: { 744 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa(1, size)); 745 if (!surface->Initialize()) 746 return NULL; 747 748 return surface; 749 } 750 case kGLImplementationEGLGLES2: { 751 scoped_refptr<GLSurface> surface; 752 if (g_egl_surfaceless_context_supported && 753 (size.width() == 0 && size.height() == 0)) { 754 surface = new SurfacelessEGL(size); 755 } else 756 surface = new PbufferGLSurfaceEGL(size); 757 758 if (!surface->Initialize()) 759 return NULL; 760 return surface; 761 } 762 default: 763 NOTREACHED(); 764 return NULL; 765 } 766 } 767 768 #endif 769 770 } // namespace gfx 771