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.
5 #include "ui/gl/gl_context_egl.h"
7 #include "base/debug/trace_event.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "build/build_config.h"
11 #include "third_party/khronos/EGL/egl.h"
12 #include "third_party/khronos/EGL/eglext.h"
13 #include "ui/gl/egl_util.h"
14 #include "ui/gl/gl_bindings.h"
15 #include "ui/gl/gl_surface_egl.h"
23 using ui::GetLastEGLErrorString
;
27 GLContextEGL::GLContextEGL(GLShareGroup
* share_group
)
28 : GLContextReal(share_group
),
32 unbind_fbo_on_makecurrent_(false) {
35 bool GLContextEGL::Initialize(
36 GLSurface
* compatible_surface
, GpuPreference gpu_preference
) {
37 DCHECK(compatible_surface
);
40 static const EGLint kContextAttributes
[] = {
41 EGL_CONTEXT_CLIENT_VERSION
, 2,
44 static const EGLint kContextRobustnessAttributes
[] = {
45 EGL_CONTEXT_CLIENT_VERSION
, 2,
46 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT
,
47 EGL_LOSE_CONTEXT_ON_RESET_EXT
,
51 display_
= compatible_surface
->GetDisplay();
52 config_
= compatible_surface
->GetConfig();
54 const EGLint
* context_attributes
= NULL
;
55 if (GLSurfaceEGL::IsCreateContextRobustnessSupported()) {
56 DVLOG(1) << "EGL_EXT_create_context_robustness supported.";
57 context_attributes
= kContextRobustnessAttributes
;
59 // At some point we should require the presence of the robustness
60 // extension and remove this code path.
61 DVLOG(1) << "EGL_EXT_create_context_robustness NOT supported.";
62 context_attributes
= kContextAttributes
;
65 context_
= eglCreateContext(
68 share_group() ? share_group()->GetHandle() : NULL
,
72 LOG(ERROR
) << "eglCreateContext failed with error "
73 << GetLastEGLErrorString();
81 void GLContextEGL::Destroy() {
83 if (!eglDestroyContext(display_
, context_
)) {
84 LOG(ERROR
) << "eglDestroyContext failed with error "
85 << GetLastEGLErrorString();
92 bool GLContextEGL::MakeCurrent(GLSurface
* surface
) {
94 if (IsCurrent(surface
))
97 TRACE_EVENT2("gpu", "GLContextEGL::MakeCurrent",
101 if (unbind_fbo_on_makecurrent_
&&
102 eglGetCurrentContext() != EGL_NO_CONTEXT
) {
103 glBindFramebufferEXT(GL_FRAMEBUFFER
, 0);
106 if (!eglMakeCurrent(display_
,
107 surface
->GetHandle(),
108 surface
->GetHandle(),
110 DVLOG(1) << "eglMakeCurrent failed with error "
111 << GetLastEGLErrorString();
115 // Set this as soon as the context is current, since we might call into GL.
119 if (!InitializeExtensionBindings()) {
120 ReleaseCurrent(surface
);
124 if (!surface
->OnMakeCurrent(this)) {
125 LOG(ERROR
) << "Could not make current.";
132 void GLContextEGL::SetUnbindFboOnMakeCurrent() {
133 unbind_fbo_on_makecurrent_
= true;
136 void GLContextEGL::ReleaseCurrent(GLSurface
* surface
) {
137 if (!IsCurrent(surface
))
140 if (unbind_fbo_on_makecurrent_
)
141 glBindFramebufferEXT(GL_FRAMEBUFFER
, 0);
144 eglMakeCurrent(display_
,
150 bool GLContextEGL::IsCurrent(GLSurface
* surface
) {
153 bool native_context_is_current
= context_
== eglGetCurrentContext();
155 // If our context is current then our notion of which GLContext is
156 // current must be correct. On the other hand, third-party code
157 // using OpenGL might change the current context.
158 DCHECK(!native_context_is_current
|| (GetRealCurrent() == this));
160 if (!native_context_is_current
)
164 if (surface
->GetHandle() != eglGetCurrentSurface(EGL_DRAW
))
171 void* GLContextEGL::GetHandle() {
175 void GLContextEGL::SetSwapInterval(int interval
) {
176 DCHECK(IsCurrent(NULL
));
177 if (!eglSwapInterval(display_
, interval
)) {
178 LOG(ERROR
) << "eglSwapInterval failed with error "
179 << GetLastEGLErrorString();
183 std::string
GLContextEGL::GetExtensions() {
184 const char* extensions
= eglQueryString(display_
,
187 return GLContext::GetExtensions();
189 return GLContext::GetExtensions() + " " + extensions
;
192 bool GLContextEGL::WasAllocatedUsingRobustnessExtension() {
193 return GLSurfaceEGL::IsCreateContextRobustnessSupported();
196 GLContextEGL::~GLContextEGL() {
200 #if !defined(OS_ANDROID)
201 bool GLContextEGL::GetTotalGpuMemory(size_t* bytes
) {