diff options
Diffstat (limited to 'chromium/ui/gl/gl_surface_egl.cc')
-rw-r--r-- | chromium/ui/gl/gl_surface_egl.cc | 234 |
1 files changed, 65 insertions, 169 deletions
diff --git a/chromium/ui/gl/gl_surface_egl.cc b/chromium/ui/gl/gl_surface_egl.cc index 3f8923ae895..6cf38160431 100644 --- a/chromium/ui/gl/gl_surface_egl.cc +++ b/chromium/ui/gl/gl_surface_egl.cc @@ -12,11 +12,12 @@ #include <android/native_window_jni.h> #endif -#include "base/command_line.h" +#include "base/debug/trace_event.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "build/build_config.h" +#include "ui/gfx/geometry/rect.h" #include "ui/gl/egl_util.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" @@ -33,13 +34,11 @@ extern "C" { #endif #if defined (USE_OZONE) -#include "ui/gfx/ozone/surface_factory_ozone.h" +#include "ui/ozone/public/surface_factory_ozone.h" #endif -// From ANGLE's egl/eglext.h. -#if !defined(EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE) -#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE \ - reinterpret_cast<EGLNativeDisplayType>(-2) +#if !defined(EGL_FIXED_SIZE_ANGLE) +#define EGL_FIXED_SIZE_ANGLE 0x3201 #endif using ui::GetLastEGLErrorString; @@ -55,6 +54,7 @@ EGLNativeDisplayType g_native_display; const char* g_egl_extensions = NULL; bool g_egl_create_context_robustness_supported = false; bool g_egl_sync_control_supported = false; +bool g_egl_window_fixed_size_supported = false; bool g_egl_surfaceless_context_supported = false; class EGLSyncControlVSyncProvider @@ -102,27 +102,7 @@ bool GLSurfaceEGL::InitializeOneOff() { if (initialized) return true; -#if defined(USE_X11) - g_native_display = base::MessagePumpForUI::GetDefaultXDisplay(); -#elif defined(OS_WIN) - g_native_display = EGL_DEFAULT_DISPLAY; - if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableD3D11) && - CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableD3D11)) { - g_native_display = EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE; - } -#elif defined(USE_OZONE) - gfx::SurfaceFactoryOzone* surface_factory = - gfx::SurfaceFactoryOzone::GetInstance(); - if (surface_factory->InitializeHardware() != - gfx::SurfaceFactoryOzone::INITIALIZED) { - LOG(ERROR) << "OZONE failed to initialize hardware"; - return false; - } - g_native_display = reinterpret_cast<EGLNativeDisplayType>( - surface_factory->GetNativeDisplay()); -#else - g_native_display = EGL_DEFAULT_DISPLAY; -#endif + g_native_display = GetPlatformDefaultEGLNativeDisplay(); g_display = eglGetDisplay(g_native_display); if (!g_display) { LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); @@ -149,7 +129,8 @@ bool GLSurfaceEGL::InitializeOneOff() { #if defined(USE_OZONE) const EGLint* config_attribs = - surface_factory->GetEGLSurfaceProperties(kConfigAttribs); + ui::SurfaceFactoryOzone::GetInstance()->GetEGLSurfaceProperties( + kConfigAttribs); #else const EGLint* config_attribs = kConfigAttribs; #endif @@ -185,7 +166,16 @@ bool GLSurfaceEGL::InitializeOneOff() { HasEGLExtension("EGL_EXT_create_context_robustness"); g_egl_sync_control_supported = HasEGLExtension("EGL_CHROMIUM_sync_control"); + g_egl_window_fixed_size_supported = + HasEGLExtension("EGL_ANGLE_window_fixed_size"); + // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary + // workaround, since code written for Android WebView takes different paths + // based on whether GL surface objects have underlying EGL surface handles, + // conflicting with the use of surfaceless. See https://crbug.com/382349 +#if defined(OS_ANDROID) + DCHECK(!g_egl_surfaceless_context_supported); +#else // Check if SurfacelessEGL is supported. g_egl_surfaceless_context_supported = HasEGLExtension("EGL_KHR_surfaceless_context"); @@ -206,6 +196,7 @@ bool GLSurfaceEGL::InitializeOneOff() { context->ReleaseCurrent(surface.get()); } } +#endif initialized = true; @@ -236,50 +227,63 @@ bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { return g_egl_create_context_robustness_supported; } +bool GLSurfaceEGL::IsEGLSurfacelessContextSupported() { + return g_egl_surfaceless_context_supported; +} + GLSurfaceEGL::~GLSurfaceEGL() {} -NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(gfx::AcceleratedWidget window) +NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) : window_(window), surface_(NULL), supports_post_sub_buffer_(false), - config_(NULL) { + config_(NULL), + size_(1, 1) { #if defined(OS_ANDROID) if (window) ANativeWindow_acquire(window); #endif + +#if defined(OS_WIN) + RECT windowRect; + if (GetClientRect(window_, &windowRect)) + size_ = gfx::Rect(windowRect).size(); +#endif } bool NativeViewGLSurfaceEGL::Initialize() { - return Initialize(NULL); + return Initialize(scoped_ptr<VSyncProvider>()); } -bool NativeViewGLSurfaceEGL::Initialize(VSyncProvider* sync_provider) { +bool NativeViewGLSurfaceEGL::Initialize( + scoped_ptr<VSyncProvider> sync_provider) { DCHECK(!surface_); - scoped_ptr<VSyncProvider> vsync_provider(sync_provider); - - if (window_ == kNullAcceleratedWidget) { - LOG(ERROR) << "Trying to create surface without window."; - return false; - } if (!GetDisplay()) { LOG(ERROR) << "Trying to create surface with invalid display."; return false; } - static const EGLint egl_window_attributes_sub_buffer[] = { - EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_TRUE, - EGL_NONE - }; + std::vector<EGLint> egl_window_attributes; + if (g_egl_window_fixed_size_supported) { + egl_window_attributes.push_back(EGL_FIXED_SIZE_ANGLE); + egl_window_attributes.push_back(EGL_TRUE); + egl_window_attributes.push_back(EGL_WIDTH); + egl_window_attributes.push_back(size_.width()); + egl_window_attributes.push_back(EGL_HEIGHT); + egl_window_attributes.push_back(size_.height()); + } + + if (gfx::g_driver_egl.ext.b_EGL_NV_post_sub_buffer) { + egl_window_attributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV); + egl_window_attributes.push_back(EGL_TRUE); + } + + egl_window_attributes.push_back(EGL_NONE); // Create a surface for the native window. surface_ = eglCreateWindowSurface( - GetDisplay(), - GetConfig(), - window_, - gfx::g_driver_egl.ext.b_EGL_NV_post_sub_buffer ? - egl_window_attributes_sub_buffer : - NULL); + GetDisplay(), GetConfig(), window_, &egl_window_attributes[0]); if (!surface_) { LOG(ERROR) << "eglCreateWindowSurface failed with error " @@ -296,7 +300,7 @@ bool NativeViewGLSurfaceEGL::Initialize(VSyncProvider* sync_provider) { supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE; if (sync_provider) - vsync_provider_.swap(vsync_provider); + vsync_provider_.reset(sync_provider.release()); else if (g_egl_sync_control_supported) vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_)); return true; @@ -394,6 +398,10 @@ bool NativeViewGLSurfaceEGL::IsOffscreen() { } bool NativeViewGLSurfaceEGL::SwapBuffers() { + TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers", + "width", GetSize().width(), + "height", GetSize().height()); + if (!eglSwapBuffers(GetDisplay(), surface_)) { DVLOG(1) << "eglSwapBuffers failed with error " << GetLastEGLErrorString(); @@ -420,6 +428,8 @@ bool NativeViewGLSurfaceEGL::Resize(const gfx::Size& size) { if (size == GetSize()) return true; + size_ = size; + scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; GLContext* current_context = GLContext::GetCurrent(); bool was_current = @@ -453,13 +463,8 @@ EGLSurface NativeViewGLSurfaceEGL::GetHandle() { return surface_; } -std::string NativeViewGLSurfaceEGL::GetExtensions() { - std::string extensions = GLSurface::GetExtensions(); - if (supports_post_sub_buffer_) { - extensions += extensions.empty() ? "" : " "; - extensions += "GL_CHROMIUM_post_sub_buffer"; - } - return extensions; +bool NativeViewGLSurfaceEGL::SupportsPostSubBuffer() { + return supports_post_sub_buffer_; } bool NativeViewGLSurfaceEGL::PostSubBuffer( @@ -492,6 +497,10 @@ void NativeViewGLSurfaceEGL::SetHandle(EGLSurface surface) { PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) : size_(size), surface_(NULL) { + // Some implementations of Pbuffer do not support having a 0 size. For such + // cases use a (1, 1) surface. + if (size_.GetArea() == 0) + size_.SetSize(1, 1); } bool PbufferGLSurfaceEGL::Initialize() { @@ -503,12 +512,6 @@ bool PbufferGLSurfaceEGL::Initialize() { return false; } - if (size_.GetArea() == 0) { - LOG(ERROR) << "Error: surface has zero area " - << size_.width() << " x " << size_.height(); - return false; - } - // Allocate the new pbuffer surface before freeing the old one to ensure // they have different addresses. If they have the same address then a // future call to MakeCurrent might early out because it appears the current @@ -660,111 +663,4 @@ void* SurfacelessEGL::GetShareHandle() { SurfacelessEGL::~SurfacelessEGL() { } -#if defined(ANDROID) || defined(USE_OZONE) - -// A thin subclass of |GLSurfaceOSMesa| that can be used in place -// of a native hardware-provided surface when a native surface -// provider is not available. -class GLSurfaceOSMesaHeadless : public GLSurfaceOSMesa { - public: - explicit GLSurfaceOSMesaHeadless(gfx::AcceleratedWidget window); - - virtual bool IsOffscreen() OVERRIDE; - virtual bool SwapBuffers() OVERRIDE; - - protected: - virtual ~GLSurfaceOSMesaHeadless(); - - private: - - DISALLOW_COPY_AND_ASSIGN(GLSurfaceOSMesaHeadless); -}; - -bool GLSurfaceOSMesaHeadless::IsOffscreen() { return false; } - -bool GLSurfaceOSMesaHeadless::SwapBuffers() { return true; } - -GLSurfaceOSMesaHeadless::GLSurfaceOSMesaHeadless(gfx::AcceleratedWidget window) - : GLSurfaceOSMesa(OSMESA_BGRA, gfx::Size(1, 1)) { - DCHECK(window); -} - -GLSurfaceOSMesaHeadless::~GLSurfaceOSMesaHeadless() { Destroy(); } - -// static -bool GLSurface::InitializeOneOffInternal() { - if (GetGLImplementation() == kGLImplementationOSMesaGL) { - return true; - } - DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); - - if (!GLSurfaceEGL::InitializeOneOff()) { - LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; - return false; - } - return true; -} - -// static -scoped_refptr<GLSurface> -GLSurface::CreateViewGLSurface(gfx::AcceleratedWidget window) { - - if (GetGLImplementation() == kGLImplementationOSMesaGL) { - scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless(window)); - if (!surface->Initialize()) - return NULL; - return surface; - } - DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); - if (window) { - scoped_refptr<NativeViewGLSurfaceEGL> surface; - VSyncProvider* sync_provider = NULL; -#if defined(USE_OZONE) - window = gfx::SurfaceFactoryOzone::GetInstance()->RealizeAcceleratedWidget( - window); - sync_provider = - gfx::SurfaceFactoryOzone::GetInstance()->GetVSyncProvider(window); -#endif - surface = new NativeViewGLSurfaceEGL(window); - if(surface->Initialize(sync_provider)) - return surface; - } else { - scoped_refptr<GLSurface> surface = new GLSurfaceStub(); - if (surface->Initialize()) - return surface; - } - return NULL; -} - -// static -scoped_refptr<GLSurface> -GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) { - switch (GetGLImplementation()) { - case kGLImplementationOSMesaGL: { - scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa(1, size)); - if (!surface->Initialize()) - return NULL; - - return surface; - } - case kGLImplementationEGLGLES2: { - scoped_refptr<GLSurface> surface; - if (g_egl_surfaceless_context_supported && - (size.width() == 0 && size.height() == 0)) { - surface = new SurfacelessEGL(size); - } else - surface = new PbufferGLSurfaceEGL(size); - - if (!surface->Initialize()) - return NULL; - return surface; - } - default: - NOTREACHED(); - return NULL; - } -} - -#endif - } // namespace gfx |