Avoid potential negative array index access to cached text.
[LibreOffice.git] / android / source / src / java / org / mozilla / gecko / gfx / GLController.java
blob6a43dd6a87db781d3f3a42fb0d1e22337d65fda1
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/. */
6 package org.mozilla.gecko.gfx;
8 import javax.microedition.khronos.egl.EGL10;
9 import javax.microedition.khronos.egl.EGL11;
10 import javax.microedition.khronos.egl.EGLConfig;
11 import javax.microedition.khronos.egl.EGLContext;
12 import javax.microedition.khronos.egl.EGLDisplay;
13 import javax.microedition.khronos.egl.EGLSurface;
14 import javax.microedition.khronos.opengles.GL;
15 import javax.microedition.khronos.opengles.GL10;
17 public class GLController {
18 private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
19 private static final String LOGTAG = "GeckoGLController";
21 private LayerView mView;
22 private int mGLVersion;
23 private int mWidth, mHeight;
25 private EGL10 mEGL;
26 private EGLDisplay mEGLDisplay;
27 private EGLConfig mEGLConfig;
28 private EGLContext mEGLContext;
29 private EGLSurface mEGLSurface;
31 private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4;
33 private static final int[] CONFIG_SPEC = {
34 EGL10.EGL_RED_SIZE, 5,
35 EGL10.EGL_GREEN_SIZE, 6,
36 EGL10.EGL_BLUE_SIZE, 5,
37 EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
38 EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
39 EGL10.EGL_NONE
42 public GLController(LayerView view) {
43 mView = view;
44 mGLVersion = 2;
47 public void setGLVersion(int version) {
48 mGLVersion = version;
51 /** You must call this on the same thread you intend to use OpenGL on. */
52 public void initGLContext() {
53 initEGLContext();
54 createEGLSurface();
57 public void disposeGLContext() {
58 if (mEGL == null) {
59 return;
62 if (!mEGL.eglMakeCurrent(mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
63 EGL10.EGL_NO_CONTEXT)) {
64 throw new GLControllerException("EGL context could not be released! " +
65 getEGLError());
68 if (mEGLSurface != null) {
69 if (!mEGL.eglDestroySurface(mEGLDisplay, mEGLSurface)) {
70 throw new GLControllerException("EGL surface could not be destroyed! " +
71 getEGLError());
74 mEGLSurface = null;
77 if (mEGLContext != null) {
78 if (!mEGL.eglDestroyContext(mEGLDisplay, mEGLContext)) {
79 throw new GLControllerException("EGL context could not be destroyed! " +
80 getEGLError());
83 mEGLContext = null;
87 public GL10 getGL() { return (GL10) mEGLContext.getGL(); }
88 public EGLDisplay getEGLDisplay() { return mEGLDisplay; }
89 public EGLConfig getEGLConfig() { return mEGLConfig; }
90 public EGLContext getEGLContext() { return mEGLContext; }
91 public EGLSurface getEGLSurface() { return mEGLSurface; }
92 public LayerView getView() { return mView; }
94 public boolean hasSurface() {
95 return mEGLSurface != null;
98 public boolean swapBuffers() {
99 return mEGL.eglSwapBuffers(mEGLDisplay, mEGLSurface);
102 public synchronized int getWidth() {
103 return mWidth;
106 public synchronized int getHeight() {
107 return mHeight;
110 synchronized void surfaceDestroyed() {
111 notifyAll();
114 synchronized void surfaceChanged(int newWidth, int newHeight) {
115 mWidth = newWidth;
116 mHeight = newHeight;
117 notifyAll();
120 private void initEGL() {
121 mEGL = (EGL10)EGLContext.getEGL();
123 mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
124 if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) {
125 throw new GLControllerException("eglGetDisplay() failed");
128 int[] version = new int[2];
129 if (!mEGL.eglInitialize(mEGLDisplay, version)) {
130 throw new GLControllerException("eglInitialize() failed " + getEGLError());
133 mEGLConfig = chooseConfig();
136 private void initEGLContext() {
137 initEGL();
139 int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, mGLVersion, EGL10.EGL_NONE };
140 mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT,
141 attribList);
142 if (mEGLContext == null || mEGLContext == EGL10.EGL_NO_CONTEXT) {
143 throw new GLControllerException("createContext() failed " +
144 getEGLError());
147 if (mView.getRenderer() != null) {
148 GL10 gl = (GL10) mEGLContext.getGL();
149 mView.getRenderer().onSurfaceCreated(gl, mEGLConfig);
150 mView.getRenderer().onSurfaceChanged(gl, mWidth, mHeight);
154 private EGLConfig chooseConfig() {
155 int[] numConfigs = new int[1];
156 if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, null, 0, numConfigs) ||
157 numConfigs[0] <= 0) {
158 throw new GLControllerException("No available EGL configurations " +
159 getEGLError());
162 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
163 if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, configs, numConfigs[0], numConfigs)) {
164 throw new GLControllerException("No EGL configuration for that specification " +
165 getEGLError());
168 // Select the first 565 RGB configuration.
169 int[] red = new int[1], green = new int[1], blue = new int[1];
170 for (EGLConfig config : configs) {
171 mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_RED_SIZE, red);
172 mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_GREEN_SIZE, green);
173 mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_BLUE_SIZE, blue);
174 if (red[0] == 5 && green[0] == 6 && blue[0] == 5) {
175 return config;
179 // if there's no 565 RGB configuration, select another one that fulfils the specification
180 return configs[0];
183 private void createEGLSurface() {
184 Object window = mView.getNativeWindow();
185 mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, window, null);
186 if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) {
187 throw new GLControllerException("EGL window surface could not be created! " +
188 getEGLError());
191 if (!mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
192 throw new GLControllerException("EGL surface could not be made into the current " +
193 "surface! " + getEGLError());
196 if (mView.getRenderer() != null) {
197 GL10 gl = (GL10) mEGLContext.getGL();
198 mView.getRenderer().onSurfaceCreated(gl, mEGLConfig);
199 mView.getRenderer().onSurfaceChanged(gl, mView.getWidth(), mView.getHeight());
203 private String getEGLError() {
204 return "Error " + mEGL.eglGetError();
207 public static class GLControllerException extends RuntimeException {
208 public static final long serialVersionUID = 1L;
210 GLControllerException(String e) {
211 super(e);