blob: ebd88cab6e86aa30d185a119773a00e5356c12aa [file] [log] [blame] [edit]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gl/gl_surface_android.h"
#include <EGL/egl.h>
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "ui/gl/android_native_window.h"
#include "ui/gl/egl_util.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_implementation.h"
namespace gfx {
bool GLSurface::InitializeOneOffInternal() {
static bool initialized = false;
if (initialized)
return true;
switch (GetGLImplementation()) {
case kGLImplementationEGLGLES2:
if (!GLSurfaceEGL::InitializeOneOff()) {
LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
return false;
}
break;
default:
NOTREACHED();
break;
}
initialized = true;
return true;
}
// static
scoped_refptr<GLSurface>
GLSurface::CreateViewGLSurface(bool software, gfx::AcceleratedWidget window) {
if (software)
return NULL;
switch (GetGLImplementation()) {
case kGLImplementationEGLGLES2: {
// window is unused
scoped_refptr<AndroidViewSurface> surface(new AndroidViewSurface());
if (!surface->Initialize())
return NULL;
return surface;
}
default:
NOTREACHED();
return NULL;
}
}
// static
scoped_refptr<GLSurface>
GLSurface::CreateOffscreenGLSurface(bool software, const gfx::Size& size) {
if (software)
return NULL;
switch (GetGLImplementation()) {
case kGLImplementationEGLGLES2: {
scoped_refptr<PbufferGLSurfaceEGL> surface(
new PbufferGLSurfaceEGL(false, size));
if (!surface->Initialize())
return NULL;
return surface;
}
default:
NOTREACHED();
return NULL;
}
}
AndroidViewSurface::AndroidViewSurface()
: NativeViewGLSurfaceEGL(false, 0),
pbuffer_surface_(new PbufferGLSurfaceEGL(false, Size(1, 1))),
window_(NULL) {
}
AndroidViewSurface::~AndroidViewSurface() {
}
bool AndroidViewSurface::Initialize() {
DCHECK(pbuffer_surface_.get());
return pbuffer_surface_->Initialize();
}
void AndroidViewSurface::Destroy() {
if (pbuffer_surface_.get()) {
pbuffer_surface_->Destroy();
} else {
window_ = NULL;
}
NativeViewGLSurfaceEGL::Destroy();
}
bool AndroidViewSurface::IsOffscreen() {
return false;
}
bool AndroidViewSurface::SwapBuffers() {
if (!pbuffer_surface_.get())
return NativeViewGLSurfaceEGL::SwapBuffers();
return true;
}
gfx::Size AndroidViewSurface::GetSize() {
if (pbuffer_surface_.get())
return pbuffer_surface_->GetSize();
else
return NativeViewGLSurfaceEGL::GetSize();
}
EGLSurface AndroidViewSurface::GetHandle() {
if (pbuffer_surface_.get())
return pbuffer_surface_->GetHandle();
else
return NativeViewGLSurfaceEGL::GetHandle();
}
bool AndroidViewSurface::Resize(const gfx::Size& size) {
if (pbuffer_surface_.get())
return pbuffer_surface_->Resize(size);
else if (GetHandle()) {
DCHECK(window_ && window_->GetNativeWindow());
// Deactivate and restore any currently active context.
EGLContext context = eglGetCurrentContext();
if (context != EGL_NO_CONTEXT) {
eglMakeCurrent(GetDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
}
NativeViewGLSurfaceEGL::Destroy();
if (CreateWindowSurface(window_)) {
if (context != EGL_NO_CONTEXT)
eglMakeCurrent(GetDisplay(), GetHandle(), GetHandle(), context);
}
}
return true;
}
bool AndroidViewSurface::CreateWindowSurface(AndroidNativeWindow* window) {
DCHECK(window->GetNativeWindow());
window_ = window;
EGLSurface surface = eglCreateWindowSurface(GetDisplay(),
GetConfig(),
window->GetNativeWindow(),
NULL);
if (surface == EGL_NO_SURFACE) {
LOG(ERROR) << "eglCreateWindowSurface failed with error "
<< GetLastEGLErrorString();
Destroy();
return false;
}
SetHandle(surface);
return true;
}
void AndroidViewSurface::SetNativeWindow(AndroidNativeWindow* window) {
if (window->GetNativeWindow()) {
DCHECK(pbuffer_surface_.get());
pbuffer_surface_->Destroy();
pbuffer_surface_ = NULL;
CreateWindowSurface(window);
} else {
DCHECK(GetHandle());
NativeViewGLSurfaceEGL::Destroy();
window_ = NULL;
pbuffer_surface_ = new PbufferGLSurfaceEGL(false, Size(1,1));
pbuffer_surface_->Initialize();
}
}
} // namespace gfx