Commit 70c908ca authored by danakj@chromium.org's avatar danakj@chromium.org

Allow tests to stub out GL draw calls.

This allows us to use real GL bindings but without drawing when we
don't care about pixel output, allowing for faster execution. In
particular this will allow us to use OSMesa instead of a completely
fake GL implementation in the compositor for browser tests.

We add a new kDisableGLDrawingForTests command line flag that can
be set to prevent the GL draw calls from doing any work. We will be
able to set this flag in the browser test environment for any tests
that don't require real pixel output.

R=piman, sievers
BUG=270918

Review URL: https://codereview.chromium.org/132473009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244405 0039d316-1c4b-4281-b951-d872f2087c98
parent 6396b297
......@@ -1119,6 +1119,7 @@ bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) {
static const char* const kSwitchNames[] = {
switches::kDisableAcceleratedVideoDecode,
switches::kDisableBreakpad,
switches::kDisableGLDrawingForTests,
switches::kDisableGLMultisampling,
switches::kDisableGpuSandbox,
switches::kDisableGpuWatchdog,
......
......@@ -761,6 +761,19 @@ GL_FUNCTIONS = [
'const GLenum* attachments' },
]
GL_NULLDRAW_FUNCTIONS = [
{ 'return_type': 'void',
'names': ['glClear'],
'arguments': 'GLbitfield mask', },
{ 'return_type': 'void',
'names': ['glDrawArrays'],
'arguments': 'GLenum mode, GLint first, GLsizei count', },
{ 'return_type': 'void',
'names': ['glDrawElements'],
'arguments':
'GLenum mode, GLsizei count, GLenum type, const void* indices', },
]
OSMESA_FUNCTIONS = [
{ 'return_type': 'OSMesaContext',
'names': ['OSMesaCreateContext'],
......@@ -1191,7 +1204,7 @@ GLX_FUNCTIONS = [
]
FUNCTION_SETS = [
[GL_FUNCTIONS, 'gl', [
[GL_FUNCTIONS, GL_NULLDRAW_FUNCTIONS, 'gl', [
'GL/glext.h',
'GLES2/gl2ext.h',
# Files below are Chromium-specific and shipped with Chromium sources.
......@@ -1199,8 +1212,8 @@ FUNCTION_SETS = [
'GLES2/gl2chromium.h',
'GLES2/gl2extchromium.h'
], []],
[OSMESA_FUNCTIONS, 'osmesa', [], []],
[EGL_FUNCTIONS, 'egl', [
[OSMESA_FUNCTIONS, [], 'osmesa', [], []],
[EGL_FUNCTIONS, [], 'egl', [
'EGL/eglext.h',
# Files below are Chromium-specific and shipped with Chromium sources.
'EGL/eglextchromium.h',
......@@ -1210,8 +1223,8 @@ FUNCTION_SETS = [
'EGL_ANGLE_surface_d3d_texture_2d_share_handle',
],
],
[WGL_FUNCTIONS, 'wgl', ['GL/wglext.h'], []],
[GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'GL/glxext.h'], []],
[WGL_FUNCTIONS, [], 'wgl', ['GL/wglext.h'], []],
[GLX_FUNCTIONS, [], 'glx', ['GL/glx.h', 'GL/glxext.h'], []],
]
def GenerateHeader(file, functions, set_name, used_extension_functions):
......@@ -1357,7 +1370,8 @@ def GenerateInterfaceHeader(
file.write('\n')
def GenerateSource(file, functions, set_name, used_extension_functions):
def GenerateSource(
file, functions, nulldraw_functions, set_name, used_extension_functions):
"""Generates gl_bindings_autogen_x.cc"""
# Write file header.
......@@ -1433,6 +1447,17 @@ namespace gfx {
file.write('}\n')
file.write('\n')
# Write empty stubs for functions that want one.
file.write('extern "C" {\n')
for func in nulldraw_functions:
names = func['names']
return_type = func['return_type']
arguments = func['arguments']
file.write('\n')
file.write('static %s GL_BINDING_CALL Stub_%s(%s) {}\n' %
(return_type, names[0], arguments))
file.write('} // extern "C"\n')
# Write logging wrappers for each function.
file.write('extern "C" {\n')
for func in functions:
......@@ -1512,6 +1537,17 @@ namespace gfx {
file.write(' g_debugBindingsInitialized = true;\n')
file.write('}\n')
# Write function to initialize the nulldraw function pointers.
if nulldraw_functions:
file.write('\n')
file.write('void Driver%s::InitializeNullDrawBindings() {\n' %
set_name.upper())
for func in nulldraw_functions:
first_name = func['names'][0]
file.write(' fn.%sFn = Stub_%s;\n' % (first_name, first_name))
file.write('}\n')
# Write function to update the debug function pointers to extension functions
# after the extensions have been initialized.
file.write('\n')
......@@ -1796,7 +1832,7 @@ def main(argv):
options, args = parser.parse_args(argv)
if options.inputs:
for [_, _, headers, _] in FUNCTION_SETS:
for [_, _, _, headers, _] in FUNCTION_SETS:
for header in headers:
print ResolveHeader(header, options.header_paths)
return 0
......@@ -1806,7 +1842,11 @@ def main(argv):
else:
dir = '.'
for [functions, set_name, extension_headers, extensions] in FUNCTION_SETS:
for [functions,
nulldraw_functions,
set_name,
extension_headers,
extensions] in FUNCTION_SETS:
extension_headers = [ResolveHeader(h, options.header_paths)
for h in extension_headers]
used_extension_functions = GetUsedExtensionFunctions(
......@@ -1825,7 +1865,11 @@ def main(argv):
source_file = open(
os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
GenerateSource(source_file, functions, set_name, used_extension_functions)
GenerateSource(source_file,
functions,
nulldraw_functions,
set_name,
used_extension_functions)
source_file.close()
header_file = open(
......
......@@ -228,6 +228,7 @@ struct GL_EXPORT DriverGL {
void Initialize();
void InitializeExtensions(GLContext* context);
void InitializeDebugBindings();
void InitializeNullDrawBindings();
void ClearBindings();
void UpdateDebugExtensionBindings();
......
......@@ -203,6 +203,10 @@ void InitializeDebugGLBindingsGL() {
g_driver_gl.InitializeDebugBindings();
}
void InitializeNullDrawGLBindingsGL() {
g_driver_gl.InitializeNullDrawBindings();
}
void ClearGLBindingsGL() {
if (g_real_gl) {
delete g_real_gl;
......
......@@ -22,6 +22,7 @@ class GLSurface;
void InitializeGLBindingsGL();
void InitializeGLExtensionBindingsGL(GLContext* context);
void InitializeDebugGLBindingsGL();
void InitializeNullDrawGLBindingsGL();
void ClearGLBindingsGL();
void SetGLToRealGLApi();
void SetGLApi(GLApi* api);
......
......@@ -11,6 +11,7 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_gl_api_implementation.h"
namespace gfx {
......@@ -171,4 +172,10 @@ void* GetGLProcAddress(const char* name) {
return proc;
}
void InitializeNullDrawGLBindings() {
// This is platform independent, so it does not need to live in a platform
// specific implementation file.
InitializeNullDrawGLBindingsGL();
}
} // namespace gfx
......@@ -51,6 +51,9 @@ GL_EXPORT bool InitializeGLExtensionBindings(GLImplementation implementation,
// Initialize Debug logging wrappers for GL bindings.
void InitializeDebugGLBindings();
// Initialize stub methods for drawing operations in the GL bindings.
void InitializeNullDrawGLBindings();
GL_EXPORT void ClearGLBindings();
// Set the current GL implementation.
......
......@@ -69,6 +69,9 @@ bool GLSurface::InitializeOneOff() {
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableGPUServiceLogging))
InitializeDebugGLBindings();
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGLDrawingForTests))
InitializeNullDrawGLBindings();
}
return initialized;
}
......
......@@ -67,6 +67,10 @@ const char kGpuSwitchingOptionNameForceDiscrete[] = "force_discrete";
// library first, but fall back to regular library if loading fails.
const char kTestGLLib[] = "test-gl-lib";
// Disables GL drawing operations which produce pixel output. With this
// the GL output will not be correct but tests will run faster.
const char kDisableGLDrawingForTests[] = "disable-gl-drawing-for-tests";
// This is the list of switches passed from this file that are passed from the
// GpuProcessHost to the GPU Process. Add your switch to this list if you need
// to read it in the GPU process, else don't add it.
......
......@@ -44,6 +44,7 @@ GL_EXPORT extern const char kGpuSwitchingOptionNameAutomatic[];
GL_EXPORT extern const char kUseGL[];
GL_EXPORT extern const char kSwiftShaderPath[];
GL_EXPORT extern const char kTestGLLib[];
GL_EXPORT extern const char kDisableGLDrawingForTests[];
GL_EXPORT extern const char* kGLSwitchesCopiedFromGpuProcessHost[];
GL_EXPORT extern const int kGLSwitchesCopiedFromGpuProcessHostNumSwitches;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment