// 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 #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::CreateViewGLSurface(bool software, gfx::AcceleratedWidget window) { if (software) return NULL; switch (GetGLImplementation()) { case kGLImplementationEGLGLES2: { // window is unused scoped_refptr surface(new AndroidViewSurface()); if (!surface->Initialize()) return NULL; return surface; } default: NOTREACHED(); return NULL; } } // static scoped_refptr GLSurface::CreateOffscreenGLSurface(bool software, const gfx::Size& size) { if (software) return NULL; switch (GetGLImplementation()) { case kGLImplementationEGLGLES2: { scoped_refptr 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