summaryrefslogtreecommitdiffstats
path: root/chromium/ui/gl/gl_surface_egl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/gl/gl_surface_egl.cc')
-rw-r--r--chromium/ui/gl/gl_surface_egl.cc234
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