Home | History | Annotate | Download | only in graphics_GLAPICheck
      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