OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "ui/gfx/gl/gl_context_egl.h" | |
6 | |
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/angle/include/EGL/egl.h" | |
12 #include "ui/gfx/gl/egl_util.h" | |
13 #include "ui/gfx/gl/gl_surface.h" | |
14 | |
15 // This header must come after the above third-party include, as | |
16 // it brings in #defines that cause conflicts. | |
17 #include "ui/gfx/gl/gl_bindings.h" | |
18 | |
19 #if defined(USE_X11) | |
20 extern "C" { | |
21 #include <X11/Xlib.h> | |
22 } | |
23 #endif | |
24 | |
25 namespace gfx { | |
26 | |
27 std::string GLContextEGL::GetExtensions() { | |
28 const char* extensions = eglQueryString(display_, | |
29 EGL_EXTENSIONS); | |
30 if (!extensions) | |
31 return GLContext::GetExtensions(); | |
32 | |
33 return GLContext::GetExtensions() + " " + extensions; | |
34 } | |
35 | |
36 GLContextEGL::GLContextEGL(GLShareGroup* share_group) | |
37 : GLContext(share_group), | |
38 context_(NULL), | |
39 display_(NULL), | |
40 config_(NULL) { | |
41 } | |
42 | |
43 GLContextEGL::~GLContextEGL() { | |
44 Destroy(); | |
45 } | |
46 | |
47 bool GLContextEGL::Initialize( | |
48 GLSurface* compatible_surface, GpuPreference gpu_preference) { | |
49 DCHECK(compatible_surface); | |
50 DCHECK(!context_); | |
51 | |
52 static const EGLint kContextAttributes[] = { | |
53 EGL_CONTEXT_CLIENT_VERSION, 2, | |
54 EGL_NONE | |
55 }; | |
56 | |
57 display_ = compatible_surface->GetDisplay(); | |
58 config_ = compatible_surface->GetConfig(); | |
59 | |
60 context_ = eglCreateContext( | |
61 display_, | |
62 config_, | |
63 share_group() ? share_group()->GetHandle() : NULL, | |
64 kContextAttributes); | |
65 if (!context_) { | |
66 LOG(ERROR) << "eglCreateContext failed with error " | |
67 << GetLastEGLErrorString(); | |
68 Destroy(); | |
69 return false; | |
70 } | |
71 | |
72 return true; | |
73 } | |
74 | |
75 void GLContextEGL::Destroy() { | |
76 if (context_) { | |
77 if (!eglDestroyContext(display_, context_)) { | |
78 LOG(ERROR) << "eglDestroyContext failed with error " | |
79 << GetLastEGLErrorString(); | |
80 } | |
81 | |
82 context_ = NULL; | |
83 } | |
84 } | |
85 | |
86 bool GLContextEGL::MakeCurrent(GLSurface* surface) { | |
87 DCHECK(context_); | |
88 if (IsCurrent(surface)) | |
89 return true; | |
90 | |
91 TRACE_EVENT0("gpu", "GLContextEGL::MakeCurrent"); | |
92 | |
93 if (!eglMakeCurrent(display_, | |
94 surface->GetHandle(), | |
95 surface->GetHandle(), | |
96 context_)) { | |
97 DVLOG(1) << "eglMakeCurrent failed with error " | |
98 << GetLastEGLErrorString(); | |
99 return false; | |
100 } | |
101 | |
102 SetCurrent(this, surface); | |
103 if (!InitializeExtensionBindings()) { | |
104 ReleaseCurrent(surface); | |
105 return false; | |
106 } | |
107 | |
108 if (!surface->OnMakeCurrent(this)) { | |
109 LOG(ERROR) << "Could not make current."; | |
110 return false; | |
111 } | |
112 | |
113 return true; | |
114 } | |
115 | |
116 void GLContextEGL::ReleaseCurrent(GLSurface* surface) { | |
117 if (!IsCurrent(surface)) | |
118 return; | |
119 | |
120 SetCurrent(NULL, NULL); | |
121 eglMakeCurrent(display_, | |
122 EGL_NO_SURFACE, | |
123 EGL_NO_SURFACE, | |
124 EGL_NO_CONTEXT); | |
125 } | |
126 | |
127 bool GLContextEGL::IsCurrent(GLSurface* surface) { | |
128 DCHECK(context_); | |
129 | |
130 bool native_context_is_current = context_ == eglGetCurrentContext(); | |
131 | |
132 // If our context is current then our notion of which GLContext is | |
133 // current must be correct. On the other hand, third-party code | |
134 // using OpenGL might change the current context. | |
135 DCHECK(!native_context_is_current || (GetCurrent() == this)); | |
136 | |
137 if (!native_context_is_current) | |
138 return false; | |
139 | |
140 if (surface) { | |
141 if (surface->GetHandle() != eglGetCurrentSurface(EGL_DRAW)) | |
142 return false; | |
143 } | |
144 | |
145 return true; | |
146 } | |
147 | |
148 void* GLContextEGL::GetHandle() { | |
149 return context_; | |
150 } | |
151 | |
152 void GLContextEGL::SetSwapInterval(int interval) { | |
153 DCHECK(IsCurrent(NULL)); | |
154 if (!eglSwapInterval(display_, interval)) { | |
155 LOG(ERROR) << "eglSwapInterval failed with error " | |
156 << GetLastEGLErrorString(); | |
157 } | |
158 } | |
159 | |
160 } // namespace gfx | |
OLD | NEW |