LibreOffice Module android (master) 1
GLController.java
Go to the documentation of this file.
1/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6package org.mozilla.gecko.gfx;
7
8import javax.microedition.khronos.egl.EGL10;
9import javax.microedition.khronos.egl.EGL11;
10import javax.microedition.khronos.egl.EGLConfig;
11import javax.microedition.khronos.egl.EGLContext;
12import javax.microedition.khronos.egl.EGLDisplay;
13import javax.microedition.khronos.egl.EGLSurface;
14import javax.microedition.khronos.opengles.GL;
15import javax.microedition.khronos.opengles.GL10;
16
17public class GLController {
18 private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
19 private static final String LOGTAG = "GeckoGLController";
20
22 private int mGLVersion;
23 private boolean mSurfaceValid;
24 private int mWidth, mHeight;
25
26 private EGL10 mEGL;
27 private EGLDisplay mEGLDisplay;
28 private EGLConfig mEGLConfig;
29 private EGLContext mEGLContext;
30 private EGLSurface mEGLSurface;
31
32 private GL mGL;
33
34 private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4;
35
36 private static final int[] CONFIG_SPEC = {
37 EGL10.EGL_RED_SIZE, 5,
38 EGL10.EGL_GREEN_SIZE, 6,
39 EGL10.EGL_BLUE_SIZE, 5,
40 EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
41 EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
42 EGL10.EGL_NONE
43 };
44
45 public GLController(LayerView view) {
46 mView = view;
47 mGLVersion = 2;
48 mSurfaceValid = false;
49 }
50
51 public void setGLVersion(int version) {
52 mGLVersion = version;
53 }
54
56 public void initGLContext() {
59 }
60
61 public void disposeGLContext() {
62 if (mEGL == null) {
63 return;
64 }
65
66 if (!mEGL.eglMakeCurrent(mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
67 EGL10.EGL_NO_CONTEXT)) {
68 throw new GLControllerException("EGL context could not be released! " +
69 getEGLError());
70 }
71
72 if (mEGLSurface != null) {
73 if (!mEGL.eglDestroySurface(mEGLDisplay, mEGLSurface)) {
74 throw new GLControllerException("EGL surface could not be destroyed! " +
75 getEGLError());
76 }
77
78 mEGLSurface = null;
79 }
80
81 if (mEGLContext != null) {
82 if (!mEGL.eglDestroyContext(mEGLDisplay, mEGLContext)) {
83 throw new GLControllerException("EGL context could not be destroyed! " +
84 getEGLError());
85 }
86
87 mGL = null;
88 mEGLContext = null;
89 }
90 }
91
92 public GL getGL() { return mEGLContext.getGL(); }
93 public EGLDisplay getEGLDisplay() { return mEGLDisplay; }
94 public EGLConfig getEGLConfig() { return mEGLConfig; }
95 public EGLContext getEGLContext() { return mEGLContext; }
96 public EGLSurface getEGLSurface() { return mEGLSurface; }
97 public LayerView getView() { return mView; }
98
99 public boolean hasSurface() {
100 return mEGLSurface != null;
101 }
102
103 public boolean swapBuffers() {
104 return mEGL.eglSwapBuffers(mEGLDisplay, mEGLSurface);
105 }
106
107 public boolean checkForLostContext() {
108 if (mEGL.eglGetError() != EGL11.EGL_CONTEXT_LOST) {
109 return false;
110 }
111
112 mEGLDisplay = null;
113 mEGLConfig = null;
114 mEGLContext = null;
115 mEGLSurface = null;
116 mGL = null;
117 return true;
118 }
119
120 // This function is invoked by JNI
121 public synchronized void resumeCompositorIfValid() {
122 if (mSurfaceValid) {
124 }
125 }
126
127 // Wait until we are allowed to use EGL functions on the Surface backing
128 // this window. This function is invoked by JNI
129 public synchronized void waitForValidSurface() {
130 while (!mSurfaceValid) {
131 try {
132 wait();
133 } catch (InterruptedException e) {
134 throw new RuntimeException(e);
135 }
136 }
137 }
138
139 public synchronized int getWidth() {
140 return mWidth;
141 }
142
143 public synchronized int getHeight() {
144 return mHeight;
145 }
146
147 synchronized void surfaceDestroyed() {
148 mSurfaceValid = false;
149 notifyAll();
150 }
151
152 synchronized void surfaceChanged(int newWidth, int newHeight) {
153 mWidth = newWidth;
154 mHeight = newHeight;
155 mSurfaceValid = true;
156 notifyAll();
157 }
158
159 private void initEGL() {
160 mEGL = (EGL10)EGLContext.getEGL();
161
162 mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
163 if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) {
164 throw new GLControllerException("eglGetDisplay() failed");
165 }
166
167 int[] version = new int[2];
168 if (!mEGL.eglInitialize(mEGLDisplay, version)) {
169 throw new GLControllerException("eglInitialize() failed " + getEGLError());
170 }
171
173 }
174
175 private void initEGLContext() {
176 initEGL();
177
178 int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, mGLVersion, EGL10.EGL_NONE };
179 mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT,
180 attribList);
181 if (mEGLContext == null || mEGLContext == EGL10.EGL_NO_CONTEXT) {
182 throw new GLControllerException("createContext() failed " +
183 getEGLError());
184 }
185
186 mGL = mEGLContext.getGL();
187
188 if (mView.getRenderer() != null) {
191 }
192 }
193
194 private EGLConfig chooseConfig() {
195 int[] numConfigs = new int[1];
196 if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, null, 0, numConfigs) ||
197 numConfigs[0] <= 0) {
198 throw new GLControllerException("No available EGL configurations " +
199 getEGLError());
200 }
201
202 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
203 if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, configs, numConfigs[0], numConfigs)) {
204 throw new GLControllerException("No EGL configuration for that specification " +
205 getEGLError());
206 }
207
208 // Select the first 565 RGB configuration.
209 int[] red = new int[1], green = new int[1], blue = new int[1];
210 for (EGLConfig config : configs) {
211 mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_RED_SIZE, red);
212 mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_GREEN_SIZE, green);
213 mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_BLUE_SIZE, blue);
214 if (red[0] == 5 && green[0] == 6 && blue[0] == 5) {
215 return config;
216 }
217 }
218
219 throw new GLControllerException("No suitable EGL configuration found");
220 }
221
222 private void createEGLSurface() {
223 Object window = mView.getNativeWindow();
224 mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, window, null);
225 if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) {
226 throw new GLControllerException("EGL window surface could not be created! " +
227 getEGLError());
228 }
229
230 if (!mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
231 throw new GLControllerException("EGL surface could not be made into the current " +
232 "surface! " + getEGLError());
233 }
234
235 mGL = mEGLContext.getGL();
236
237 if (mView.getRenderer() != null) {
239 mView.getRenderer().onSurfaceChanged((GL10)mGL, mView.getWidth(), mView.getHeight());
240 }
241 }
242
248 private EGLSurface provideEGLSurface() {
249 if (mEGL == null) {
250 initEGL();
251 }
252
253 Object window = mView.getNativeWindow();
254 EGLSurface surface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, window, null);
255 if (surface == null || surface == EGL10.EGL_NO_SURFACE) {
256 throw new GLControllerException("EGL window surface could not be created! " +
257 getEGLError());
258 }
259
260 return surface;
261 }
262
263 private String getEGLError() {
264 return "Error " + mEGL.eglGetError();
265 }
266
267 public static class GLControllerException extends RuntimeException {
268 public static final long serialVersionUID = 1L;
269
270 GLControllerException(String e) {
271 super(e);
272 }
273 }
274}
275
synchronized void resumeCompositorIfValid()
EGLSurface provideEGLSurface()
Provides an EGLSurface without assuming ownership of this surface.
static final int LOCAL_EGL_OPENGL_ES2_BIT
synchronized void waitForValidSurface()
static final int EGL_CONTEXT_CLIENT_VERSION
void initGLContext()
You must call this on the same thread you intend to use OpenGL on.
void onSurfaceCreated(GL10 gl, EGLConfig config)
void onSurfaceChanged(GL10 gl, final int width, final int height)
A view rendered by the layer compositor.
Definition: LayerView.java:41
void compositionResumeRequested(int width, int height)
config