1 # Copyright (c) 2012 The Chromium OS 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 import logging 6 import os 7 import re 8 from autotest_lib.client.bin import test, utils 9 from autotest_lib.client.common_lib import error 10 from autotest_lib.client.cros.graphics import graphics_utils 11 12 13 class graphics_GLAPICheck(test.test): 14 """ 15 Verify correctness of OpenGL/GLES and X11 versions/extensions. 16 """ 17 version = 1 18 preserve_srcdir = True 19 error_message = '' 20 GSC = None 21 22 def setup(self): 23 os.chdir(self.srcdir) 24 utils.make('clean') 25 utils.make('all') 26 27 def __check_extensions(self, info, ext_entries): 28 info_split = info.split() 29 comply = True 30 for extension in ext_entries: 31 match = extension in info_split 32 if not match: 33 self.error_message += ' ' + extension 34 comply = False 35 return comply 36 37 def __check_gl_extensions_1x(self, info): 38 extensions = [ 39 'GL_ARB_vertex_buffer_object', 40 'GL_ARB_shader_objects', 41 'GL_ARB_texture_non_power_of_two', 42 'GL_ARB_point_sprite', 43 'GL_EXT_framebuffer_object', 44 'GLX_EXT_texture_from_pixmap' 45 ] 46 return self.__check_extensions(info, extensions) 47 48 def __check_gl_extensions_2x(self, info): 49 extensions = [ 50 'GL_EXT_framebuffer_object', 51 'GLX_EXT_texture_from_pixmap' 52 ] 53 return self.__check_extensions(info, extensions) 54 55 def __check_gles_extensions(self, info): 56 extensions = [ 57 'GL_OES_EGL_image', 58 'EGL_KHR_image' 59 ] 60 extensions2 = [ 61 'GL_OES_EGL_image', 62 'EGL_KHR_image_base', 63 'EGL_KHR_image_pixmap' 64 ] 65 return (self.__check_extensions(info, extensions) or 66 self.__check_extensions(info, extensions2)) 67 68 def __check_gl(self, result): 69 version = re.findall(r'GL_VERSION = ([0-9]+).([0-9]+)', result) 70 if version: 71 version_major = int(version[0][0]) 72 version_minor = int(version[0][1]) 73 version_info = (' GL_VERSION = %d.%d' % 74 (version_major, version_minor)) 75 if version_major == 1: 76 if version_minor < 4: 77 self.error_message = version_info 78 return False 79 return self.__check_gl_extensions_1x(result) 80 elif version_major >= 2: 81 return self.__check_gl_extensions_2x(result) 82 else: 83 self.error_message = version_info 84 return False 85 # No GL version info found. 86 self.error_message = ' missing GL version info' 87 return False 88 89 def __check_gles(self, result): 90 version = re.findall(r'GLES_VERSION = OpenGL ES.* ([0-9]+).([0-9]+)', 91 result) 92 if version: 93 # GLES version has to be 2.0 or above. 94 version_major = int(version[0][0]) 95 version_minor = int(version[0][1]) 96 version_info = (' GLES_VERSION = %d.%d' % 97 (version_major, version_minor)) 98 if version_major < 2: 99 self.error_message = version_info 100 return False 101 # EGL version has to be 1.3 or above. 102 version = re.findall(r'EGL_VERSION = ([0-9]+).([0-9]+)', result) 103 if version: 104 version_major = int(version[0][0]) 105 version_minor = int(version[0][1]) 106 version_info = ('EGL_VERSION = %d.%d' % 107 (version_major, version_minor)) 108 if (version_major == 1 and version_minor >= 3 or 109 version_major > 1): 110 return self.__check_gles_extensions(result) 111 else: 112 self.error_message = version_info 113 return False 114 # No EGL version info found. 115 self.error_message = ' missing EGL version info' 116 return False 117 # No GLES version info found. 118 self.error_message = ' missing GLES version info' 119 return False 120 121 def __check_x_extensions(self, result): 122 extensions = [ 123 'DAMAGE', 124 'Composite' 125 ] 126 return self.__check_extensions(result, extensions) 127 128 def __run_x_cmd(self, cmd): 129 cmd = graphics_utils.xcommand(cmd) 130 result = utils.system_output(cmd, retain_output=True, 131 ignore_status=True) 132 return result 133 134 def __check_wflinfo(self): 135 # TODO(ihf): Extend this function once gl(es)_APICheck code has 136 # been upstreamed to waffle. 137 cmd = graphics_utils.wflinfo_cmd() 138 logging.info('Running %s', cmd) 139 wflinfo = utils.system_output(cmd, retain_output=True, 140 ignore_status=False) 141 # OpenGL version string: OpenGL ES 3.0 Mesa 10.5.0-devel 142 version = re.findall(r'OpenGL version string: ' 143 r'OpenGL ES ([0-9]+).([0-9]+)', wflinfo) 144 if version: 145 # GLES version has to be 2.0 or above. 146 version_major = int(version[0][0]) 147 version_minor = int(version[0][1]) 148 version_info = ('GLES_VERSION = %d.%d' % 149 (version_major, version_minor)) 150 logging.info(version_info) 151 if version_major < 2: 152 self.error_message = ' %s' % version_info 153 return False 154 cmd = 'eglinfo' 155 eglinfo = utils.system_output(cmd, retain_output=True, 156 ignore_status=False) 157 # EGL version string: 1.4 (DRI2) 158 version = re.findall(r'EGL version string: ([0-9]+).([0-9]+)', 159 eglinfo) 160 # EGL version has to be 1.3 or above. 161 if version: 162 version_major = int(version[0][0]) 163 version_minor = int(version[0][1]) 164 version_info = ('EGL_VERSION = %d.%d' % 165 (version_major, version_minor)) 166 logging.info(version_info) 167 if (version_major == 1 and version_minor >= 3 or 168 version_major > 1): 169 logging.warning('Please add missing extension check. ' 170 'Details crbug.com/413079') 171 # return self.__check_gles_extensions(wflinfo + eglinfo) 172 return True 173 else: 174 self.error_message = version_info 175 return False 176 # No EGL version info found. 177 self.error_message = ' missing EGL version info' 178 return False 179 # No GLES version info found. 180 self.error_message = ' missing GLES version info' 181 return False 182 183 def initialize(self): 184 self.GSC = graphics_utils.GraphicsStateChecker() 185 186 def cleanup(self): 187 if self.GSC: 188 self.GSC.finalize() 189 190 def run_once(self): 191 if utils.is_freon(): 192 if not self.__check_wflinfo(): 193 raise error.TestFail('GLES API insufficient:' + 194 self.error_message) 195 return 196 197 # TODO(ihf): Remove this once all boards are switched to freon. 198 cmd_gl = os.path.join(self.bindir, 'gl_APICheck') 199 cmd_gles = os.path.join(self.bindir, 'gles_APICheck') 200 exist_gl = os.path.isfile(cmd_gl) 201 exist_gles = os.path.isfile(cmd_gles) 202 if not exist_gl and not exist_gles: 203 raise error.TestFail('Found neither gl_APICheck nor gles_APICheck. ' 204 'Test setup error.') 205 elif exist_gl and exist_gles: 206 raise error.TestFail('Found both gl_APICheck and gles_APICheck. ' 207 'Test setup error.') 208 elif exist_gl: 209 self.error_message = '' 210 result = self.__run_x_cmd(cmd_gl) 211 errors = re.findall(r'ERROR: ', result) 212 run_through = re.findall(r'SUCCEED: run to the end', result) 213 if not errors and run_through: 214 check_result = self.__check_gl(result) 215 if not check_result: 216 raise error.TestFail('GL API insufficient:' + 217 self.error_message) 218 else: 219 raise error.TestFail('gl_APICheck error: ' + result) 220 else: 221 self.error_message = '' 222 # TODO(zmo@): smarter mechanism with GLES & EGL library names. 223 result = self.__run_x_cmd(cmd_gles + ' libGLESv2.so libEGL.so') 224 errors = re.findall(r'ERROR: ', result) 225 run_through = re.findall(r'SUCCEED: run to the end', result) 226 if not errors and run_through: 227 check_result = self.__check_gles(result) 228 if not check_result: 229 raise error.TestFail('GLES API insufficient:' + 230 self.error_message) 231 else: 232 raise error.TestFail('gles_APICheck error: ' + result) 233 234 # Check X11 extensions. 235 self.error_message = '' 236 check_result = self.__check_x_extensions(result) 237 if not check_result: 238 raise error.TestFail('X extensions insufficient:' + 239 self.error_message) 240