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 5import logging 6import os 7import re 8from autotest_lib.client.bin import test, utils 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.cros.graphics import graphics_utils 11 12 13class 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 version_major, version_minor = graphics_utils.get_gles_version() 138 if version_major: 139 version_info = ('GLES_VERSION = %d.%d' % 140 (version_major, version_minor)) 141 logging.info(version_info) 142 # GLES version has to be 2.0 or above. 143 if version_major < 2: 144 self.error_message = ' %s' % version_info 145 return False 146 version_major, version_minor = graphics_utils.get_egl_version() 147 if version_major: 148 version_info = ('EGL_VERSION = %d.%d' % 149 (version_major, version_minor)) 150 logging.info(version_info) 151 # EGL version has to be 1.3 or above. 152 if (version_major == 1 and version_minor >= 3 or 153 version_major > 1): 154 logging.warning('Please add missing extension check. ' 155 'Details crbug.com/413079') 156 # return self.__check_gles_extensions(wflinfo + eglinfo) 157 return True 158 else: 159 self.error_message = version_info 160 return False 161 # No EGL version info found. 162 self.error_message = ' missing EGL version info' 163 return False 164 # No GLES version info found. 165 self.error_message = ' missing GLES version info' 166 return False 167 168 def initialize(self): 169 self.GSC = graphics_utils.GraphicsStateChecker() 170 171 def cleanup(self): 172 if self.GSC: 173 self.GSC.finalize() 174 175 def run_once(self): 176 if utils.is_freon(): 177 if not self.__check_wflinfo(): 178 raise error.TestFail('Failed: GLES API insufficient:' + 179 self.error_message) 180 return 181 182 # TODO(ihf): Remove this once all boards are switched to freon. 183 cmd_gl = os.path.join(self.bindir, 'gl_APICheck') 184 cmd_gles = os.path.join(self.bindir, 'gles_APICheck') 185 exist_gl = os.path.isfile(cmd_gl) 186 exist_gles = os.path.isfile(cmd_gles) 187 if not exist_gl and not exist_gles: 188 raise error.TestFail( 189 'Failed: Found neither gl_APICheck nor gles_APICheck. ' 190 'Test setup error.') 191 elif exist_gl and exist_gles: 192 raise error.TestFail( 193 'Failed: Found both gl_APICheck and gles_APICheck. ' 194 'Test setup error.') 195 elif exist_gl: 196 self.error_message = '' 197 result = self.__run_x_cmd(cmd_gl) 198 errors = re.findall(r'ERROR: ', result) 199 run_through = re.findall(r'SUCCEED: run to the end', result) 200 if not errors and run_through: 201 check_result = self.__check_gl(result) 202 if not check_result: 203 raise error.TestFail('Failed: GL API insufficient:' + 204 self.error_message) 205 else: 206 raise error.TestFail('Failed: gl_APICheck error: ' + result) 207 else: 208 self.error_message = '' 209 # TODO(zmo@): smarter mechanism with GLES & EGL library names. 210 result = self.__run_x_cmd(cmd_gles + ' libGLESv2.so libEGL.so') 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_gles(result) 215 if not check_result: 216 raise error.TestFail('Failed: GLES API insufficient:' + 217 self.error_message) 218 else: 219 raise error.TestFail('Failed: gles_APICheck error: ' + result) 220 221 # Check X11 extensions. 222 self.error_message = '' 223 check_result = self.__check_x_extensions(result) 224 if not check_result: 225 raise error.TestFail('Failed: X extensions insufficient:' + 226 self.error_message) 227