1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.opengl.cts; 18 19 import static android.opengl.EGL14.EGL_HEIGHT; 20 import static android.opengl.EGL14.EGL_NONE; 21 import static android.opengl.EGL14.EGL_WIDTH; 22 import static android.opengl.EGL14.eglCreatePbufferSurface; 23 import static android.opengl.EGL14.eglMakeCurrent; 24 import static android.opengl.GLES20.GL_MAX_TEXTURE_SIZE; 25 import static android.opengl.GLES20.glGetIntegerv; 26 27 import android.opengl.EGL14; 28 import android.opengl.EGLConfig; 29 import android.opengl.EGLContext; 30 import android.opengl.EGLDisplay; 31 import android.opengl.EGLExt; 32 import android.opengl.EGLSurface; 33 import android.opengl.GLES20; 34 import android.os.SystemProperties; 35 36 import java.util.regex.Matcher; 37 import java.util.regex.Pattern; 38 39 /** 40 * Utilities to test EGL APIs in CTS test suites 41 */ 42 public final class Egl14Utils { Egl14Utils()43 private Egl14Utils() { 44 } 45 getMajorVersion()46 static int getMajorVersion() { 47 // Section 6.1.5 of the OpenGL ES specification indicates the GL version 48 // string strictly follows this format: 49 // 50 // OpenGL<space>ES<space><version number><space><vendor-specific information> 51 // 52 // In addition section 6.1.5 describes the version number thusly: 53 // 54 // "The version number is either of the form major number.minor number or 55 // major number.minor number.release number, where the numbers all have one 56 // or more digits. The release number and vendor specific information are 57 // optional." 58 String version = GLES20.glGetString(GLES20.GL_VERSION); 59 Pattern pattern = Pattern.compile("OpenGL ES ([0-9]+)\\.([0-9]+)"); 60 Matcher matcher = pattern.matcher(version); 61 if (matcher.find()) { 62 return Integer.parseInt(matcher.group(1)); 63 } 64 return 2; 65 } 66 67 /** 68 * Returns an initialized default display. 69 */ createEglDisplay()70 static EGLDisplay createEglDisplay() { 71 EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); 72 if (eglDisplay == EGL14.EGL_NO_DISPLAY) { 73 throw new IllegalStateException("no EGL display"); 74 } 75 76 int[] major = new int[1]; 77 int[] minor = new int[1]; 78 if (!EGL14.eglInitialize(eglDisplay, major, 0, minor, 0)) { 79 throw new IllegalStateException("error in eglInitialize"); 80 } 81 82 return eglDisplay; 83 } 84 85 /** 86 * Returns a new GL ES 2.0 context for the specified {@code eglDisplay}. 87 */ createEglContext(EGLDisplay eglDisplay)88 static EGLContext createEglContext(EGLDisplay eglDisplay) { 89 return createEglContext(eglDisplay, getEglConfig(eglDisplay, 2), 2); 90 } 91 92 /** 93 * Returns a new GL ES context for the specified display, config and version. 94 */ createEglContext(EGLDisplay eglDisplay, EGLConfig eglConfig, int version)95 static EGLContext createEglContext(EGLDisplay eglDisplay, EGLConfig eglConfig, int version) { 96 int[] contextAttributes = { EGL14.EGL_CONTEXT_CLIENT_VERSION, version, EGL14.EGL_NONE }; 97 return EGL14.eglCreateContext(eglDisplay, eglConfig, 98 EGL14.EGL_NO_CONTEXT, contextAttributes, 0); 99 } 100 101 /** 102 * Destroys the GL context identified by {@code eglDisplay} and {@code eglContext}. 103 */ destroyEglContext(EGLDisplay eglDisplay, EGLContext eglContext)104 static void destroyEglContext(EGLDisplay eglDisplay, EGLContext eglContext) { 105 EGL14.eglMakeCurrent(eglDisplay, 106 EGL14.EGL_NO_SURFACE, 107 EGL14.EGL_NO_SURFACE, 108 EGL14.EGL_NO_CONTEXT); 109 int error = EGL14.eglGetError(); 110 if (error != EGL14.EGL_SUCCESS) { 111 throw new RuntimeException("error releasing context: " + error); 112 } 113 114 EGL14.eglDestroyContext(eglDisplay, eglContext); 115 error = EGL14.eglGetError(); 116 if (error != EGL14.EGL_SUCCESS) { 117 throw new RuntimeException("error destroying context: " + error); 118 } 119 } 120 releaseAndTerminate(EGLDisplay eglDisplay)121 static void releaseAndTerminate(EGLDisplay eglDisplay) { 122 int error; 123 EGL14.eglReleaseThread(); 124 error = EGL14.eglGetError(); 125 if (error != EGL14.EGL_SUCCESS) { 126 throw new RuntimeException("error releasing thread: " + error); 127 } 128 129 EGL14.eglTerminate(eglDisplay); 130 error = EGL14.eglGetError(); 131 if (error != EGL14.EGL_SUCCESS) { 132 throw new RuntimeException("error terminating display: " + error); 133 } 134 } 135 getEglConfig(EGLDisplay eglDisplay, int version)136 static EGLConfig getEglConfig(EGLDisplay eglDisplay, int version) { 137 // Get an EGLConfig. 138 int renderableType = EGL14.EGL_OPENGL_ES2_BIT; 139 if (version == 3) { 140 renderableType = EGLExt.EGL_OPENGL_ES3_BIT_KHR; 141 } 142 final int RED_SIZE = 8; 143 final int GREEN_SIZE = 8; 144 final int BLUE_SIZE = 8; 145 final int ALPHA_SIZE = 8; 146 final int DEPTH_SIZE = 0; 147 final int STENCIL_SIZE = 0; 148 final int[] DEFAULT_CONFIGURATION = new int[] { 149 EGL14.EGL_RENDERABLE_TYPE, renderableType, 150 EGL14.EGL_RED_SIZE, RED_SIZE, 151 EGL14.EGL_GREEN_SIZE, GREEN_SIZE, 152 EGL14.EGL_BLUE_SIZE, BLUE_SIZE, 153 EGL14.EGL_ALPHA_SIZE, ALPHA_SIZE, 154 EGL14.EGL_DEPTH_SIZE, DEPTH_SIZE, 155 EGL14.EGL_STENCIL_SIZE, STENCIL_SIZE, 156 EGL14.EGL_NONE}; 157 158 int[] configsCount = new int[1]; 159 EGLConfig[] eglConfigs = new EGLConfig[1]; 160 if (!EGL14.eglChooseConfig( 161 eglDisplay, DEFAULT_CONFIGURATION, 0, eglConfigs, 0, 1, configsCount, 0)) { 162 throw new RuntimeException("eglChooseConfig failed"); 163 } 164 return eglConfigs[0]; 165 } 166 167 /** 168 * Checks for a GL error using {@link GLES20#glGetError()}. 169 * 170 * @throws RuntimeException if there is a GL error 171 */ checkGlError()172 static void checkGlError() { 173 int errorCode; 174 if ((errorCode = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 175 throw new RuntimeException("gl error: " + Integer.toHexString(errorCode)); 176 } 177 } 178 retrieveCapableTextureSize()179 static int retrieveCapableTextureSize() { 180 int error; 181 EGL14.eglReleaseThread(); 182 error = EGL14.eglGetError(); 183 184 final int[] attrs = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; 185 final int[] maxSize = new int[1]; 186 187 EGLDisplay eglDisplay = createEglDisplay(); 188 EGLContext eglContext = createEglContext(eglDisplay); 189 EGLSurface eglSurface = 190 eglCreatePbufferSurface(eglDisplay, getEglConfig(eglDisplay, 2), attrs, 191 0 /* offset */); 192 eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); 193 glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxSize, 0 /* offset */); 194 195 destroyEglContext(eglDisplay, eglContext); 196 releaseAndTerminate(eglDisplay); 197 198 if (error != EGL14.EGL_SUCCESS) { 199 throw new RuntimeException("error retrieveTextureSizeFromGL: " + error); 200 } 201 return maxSize[0]; 202 } 203 204 /** 205 * Retrieve the max of capable texture size that GPU can support, and the value used in 206 * WallpaperManagerTest.suggestDesiredDimensionsTest() to validate assertion 207 * 208 * @return maxTextureSize the max texture size from OpenGL GL_MAX_TEXTURE_SIZE 209 */ getMaxTextureSize()210 public static int getMaxTextureSize() { 211 int maxTextureSize = SystemProperties.getInt("sys.max_texture_size", 0); 212 maxTextureSize = maxTextureSize > 0 ? maxTextureSize : retrieveCapableTextureSize(); 213 return maxTextureSize; 214 } 215 } 216