Commit 6d94f064 by Jamie Madill Committed by Commit Bot

Add more complete NULL driver for the GL back-end.

This implements a NULL driver in OpenGL by stubbing out most of the GL functions in FunctionsGL except a few static "Gets" that are needed for initialization with Chromium and the tests. It is intended to be used for performance testing ONLY and will not have correct behaviour. It also adds a define to enable conditionally excluding the null entry points for implementations that wish to save on a bit of binary size. Also fixes some of the typedefs in functionsgl_typesdefs.h that were turned up after implementing the direct assignment from NULL stub entry point, generated from gl.xml, to the function pointer with type defined from functionsgl_typedefs.h. BUG=angleproject:2188 Change-Id: Ifa1e4739cb471ab6b52a4bf24c16d9eb4b334ac5 Reviewed-on: https://chromium-review.googlesource.com/727530 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 29ddcc99
......@@ -396,6 +396,9 @@ config("libANGLE_config") {
if (use_x11) {
defines += [ "ANGLE_USE_X11" ]
}
if (angle_enable_gl_null) {
defines += [ "ANGLE_ENABLE_OPENGL_NULL" ]
}
}
if (angle_enable_vulkan) {
defines += [ "ANGLE_ENABLE_VULKAN" ]
......@@ -449,6 +452,9 @@ static_library("libANGLE") {
sources += rebase_path(gles_gypi.libangle_gl_sources, ".", "src")
include_dirs += [ "src/third_party/khronos" ]
if (angle_enable_gl_null) {
sources += rebase_path(gles_gypi.libangle_gl_null_sources, ".", "src")
}
if (is_win) {
sources += rebase_path(gles_gypi.libangle_gl_wgl_sources, ".", "src")
}
......
......@@ -20,6 +20,7 @@ if (build_with_chromium) {
angle_enable_d3d9 = false
angle_enable_d3d11 = false
angle_enable_gl = false
angle_enable_gl_null = false
angle_enable_vulkan = false
angle_enable_null = true
......@@ -27,16 +28,20 @@ if (is_win) {
angle_enable_d3d9 = true
angle_enable_d3d11 = true
angle_enable_gl = true
angle_enable_gl_null = true
angle_enable_vulkan = true
import("//build/config/win/visual_studio_version.gni")
} else if (is_linux && use_x11 && !is_chromeos) {
angle_enable_gl = true
angle_enable_gl_null = true
angle_enable_vulkan = true
} else if (is_mac || ozone_platform_gbm) {
angle_enable_gl = true
angle_enable_gl_null = true
} else if (is_android) {
angle_enable_gl = true
angle_enable_gl_null = true
}
angle_enable_essl = true
......
......@@ -15,6 +15,7 @@
'angle_enable_d3d9%': 0,
'angle_enable_d3d11%': 0,
'angle_enable_gl%': 0,
'angle_enable_gl_null%': 0,
'angle_enable_vulkan%': 0,
'angle_enable_essl%': 1, # Enable this for all configs by default
'angle_enable_glsl%': 1, # Enable this for all configs by default
......@@ -27,6 +28,7 @@
['OS=="win"',
{
'angle_enable_gl%': 1,
'angle_enable_gl_null%': 1,
'angle_enable_d3d9%': 1,
'angle_enable_d3d11%': 1,
'angle_enable_hlsl%': 1,
......@@ -35,15 +37,18 @@
['OS=="linux" and use_x11==1 and chromeos==0',
{
'angle_enable_gl%': 1,
'angle_enable_gl_null%': 1,
'angle_enable_vulkan%': 1,
}],
['OS=="mac"',
{
'angle_enable_gl%': 1,
'angle_enable_gl_null%': 1,
}],
['use_ozone==1',
{
'angle_enable_gl%': 1,
'angle_enable_gl_null%': 1,
}],
],
'angle_enable_null%': 1, # Available on all platforms
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -772,6 +772,13 @@ class DispatchTableGL : angle::NonCopyable
void initProcsDesktopGL(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsGLES(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsSharedExtensions(const std::set<std::string> &extensions);
#if defined(ANGLE_ENABLE_OPENGL_NULL)
void initProcsDesktopGLNULL(const gl::Version &version,
const std::set<std::string> &extensions);
void initProcsGLESNULL(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsSharedExtensionsNULL(const std::set<std::string> &extensions);
#endif // defined(ANGLE_ENABLE_OPENGL_NULL)
};
} // namespace rx
......
......@@ -11,6 +11,7 @@
#include <algorithm>
#include "common/string_utils.h"
#include "libANGLE/AttributeMap.h"
#include "libANGLE/renderer/gl/renderergl_utils.h"
namespace rx
......@@ -55,6 +56,40 @@ static std::vector<std::string> GetIndexedExtensions(PFNGLGETINTEGERVPROC getInt
return result;
}
#if defined(ANGLE_ENABLE_OPENGL_NULL)
static GLenum INTERNAL_GL_APIENTRY DummyCheckFramebufferStatus(GLenum)
{
return GL_FRAMEBUFFER_COMPLETE;
}
static void INTERNAL_GL_APIENTRY DummyGetProgramiv(GLuint program, GLenum pname, GLint *params)
{
switch (pname)
{
case GL_LINK_STATUS:
*params = GL_TRUE;
break;
case GL_VALIDATE_STATUS:
*params = GL_TRUE;
break;
default:
break;
}
}
static void INTERNAL_GL_APIENTRY DummyGetShaderiv(GLuint program, GLenum pname, GLint *params)
{
switch (pname)
{
case GL_COMPILE_STATUS:
*params = GL_TRUE;
break;
default:
break;
}
}
#endif // defined(ANGLE_ENABLE_OPENGL_NULL)
#define ASSIGN(NAME, FP) *reinterpret_cast<void **>(&FP) = loadProcAddress(NAME)
FunctionsGL::FunctionsGL() : version(), standard(), extensions()
......@@ -65,7 +100,7 @@ FunctionsGL::~FunctionsGL()
{
}
void FunctionsGL::initialize()
void FunctionsGL::initialize(const egl::AttributeMap &displayAttributes)
{
// Grab the version number
ASSIGN("glGetString", getString);
......@@ -90,12 +125,18 @@ void FunctionsGL::initialize()
extensionSet.insert(extension);
}
// Note:
// Even though extensions are written against specific versions of GL, many drivers expose the
// extensions in even older versions. Always try loading the extensions regardless of GL
// version.
// Note:
// Even though extensions are written against specific versions of GL, many drivers expose the
// extensions in even older versions. Always try loading the extensions regardless of GL
// version.
// Load the entry points
#if defined(ANGLE_ENABLE_OPENGL_NULL)
EGLint deviceType =
static_cast<EGLint>(displayAttributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE));
#endif // defined(ANGLE_ENABLE_GL_NULL)
// Load the entry points
switch (standard)
{
case STANDARD_GL_DESKTOP:
......@@ -107,23 +148,53 @@ void FunctionsGL::initialize()
getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
}
initProcsDesktopGL(version, extensionSet);
#if defined(ANGLE_ENABLE_OPENGL_NULL)
if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
{
initProcsDesktopGLNULL(version, extensionSet);
}
else
#endif // defined(ANGLE_ENABLE_GL_NULL)
{
initProcsDesktopGL(version, extensionSet);
}
break;
}
case STANDARD_GL_ES:
{
// No profiles in GLES
profile = 0;
initProcsGLES(version, extensionSet);
#if defined(ANGLE_ENABLE_OPENGL_NULL)
if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
{
initProcsGLESNULL(version, extensionSet);
}
else
#endif // defined(ANGLE_ENABLE_GL_NULL)
{
initProcsGLES(version, extensionSet);
}
break;
}
default:
UNREACHABLE();
break;
}
initProcsSharedExtensions(extensionSet);
#if defined(ANGLE_ENABLE_OPENGL_NULL)
if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
{
initProcsSharedExtensionsNULL(extensionSet);
initializeDummyFunctionsForNULLDriver(extensionSet);
}
else
#endif // defined(ANGLE_ENABLE_OPENGL_NULL)
{
initProcsSharedExtensions(extensionSet);
}
}
bool FunctionsGL::isAtLeastGL(const gl::Version &glVersion) const
......@@ -161,4 +232,39 @@ bool FunctionsGL::hasGLESExtension(const std::string &ext) const
return standard == STANDARD_GL_ES && hasExtension(ext);
}
#if defined(ANGLE_ENABLE_OPENGL_NULL)
void FunctionsGL::initializeDummyFunctionsForNULLDriver(const std::set<std::string> &extensionSet)
{
// This is a quick hack to get the NULL driver working, but we might want to implement a true
// NULL/stub driver that never calls into the OS. See Chromium's implementation in
// ui/gl/gl_stub_api.cc. This might be useful for testing things like perf scaling due to
// the caps returned by the drivers (i.e. number of texture units) or a true NULL back-end
// that could be used in a VM for things like fuzzing.
// TODO(jmadill): Implement true no-op/stub back-end.
ASSIGN("glGetString", getString);
ASSIGN("glGetStringi", getStringi);
ASSIGN("glGetIntegerv", getIntegerv);
getProgramiv = &DummyGetProgramiv;
getShaderiv = &DummyGetShaderiv;
checkFramebufferStatus = &DummyCheckFramebufferStatus;
if (isAtLeastGLES(gl::Version(3, 0)) || isAtLeastGL(gl::Version(4, 2)) ||
extensionSet.count("GL_ARB_internalformat_query") > 0)
{
ASSIGN("glGetInternalformativ", getInternalformativ);
}
if (isAtLeastGL(gl::Version(4, 3)))
{
ASSIGN("glGetInternalformati64v", getInternalformati64v);
}
if (extensionSet.count("GL_NV_internalformat_sample_query") > 0)
{
ASSIGN("glGetInternalformatSampleivNV", getInternalformatSampleivNV);
}
}
#endif // defined(ANGLE_ENABLE_OPENGL_NULL)
} // namespace gl
......@@ -15,6 +15,11 @@
#include "libANGLE/renderer/gl/functionsgl_enums.h"
#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
namespace egl
{
class AttributeMap;
} // namespace egl
namespace rx
{
......@@ -30,7 +35,7 @@ class FunctionsGL : public DispatchTableGL
FunctionsGL();
virtual ~FunctionsGL();
void initialize();
void initialize(const egl::AttributeMap &displayAttributes);
// Version information
gl::Version version;
......@@ -46,6 +51,10 @@ class FunctionsGL : public DispatchTableGL
bool hasExtension(const std::string &ext) const;
bool hasGLExtension(const std::string &ext) const;
bool hasGLESExtension(const std::string &ext) const;
private:
virtual void *loadProcAddress(const std::string &function) const = 0;
void initializeDummyFunctionsForNULLDriver(const std::set<std::string> &extensionSet);
};
} // namespace rx
......
......@@ -171,7 +171,6 @@ RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &at
mBlitter(nullptr),
mMultiviewClearer(nullptr),
mUseDebugOutput(false),
mSkipDrawCalls(false),
mCapsInitialized(false),
mMultiviewImplementationType(MultiviewImplementationTypeGL::UNSPECIFIED)
{
......@@ -203,13 +202,6 @@ RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &at
mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
}
EGLint deviceType =
static_cast<EGLint>(attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE));
if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
{
mSkipDrawCalls = true;
}
if (mWorkarounds.initializeCurrentVertexAttributes)
{
GLint maxVertexAttribs = 0;
......@@ -262,16 +254,13 @@ gl::Error RendererGL::drawArrays(const gl::Context *context,
const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, instanceCount));
if (!mSkipDrawCalls)
if (!usesMultiview)
{
if (!usesMultiview)
{
mFunctions->drawArrays(mode, first, count);
}
else
{
mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
}
mFunctions->drawArrays(mode, first, count);
}
else
{
mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
}
return gl::NoError();
}
......@@ -290,10 +279,7 @@ gl::Error RendererGL::drawArraysInstanced(const gl::Context *context,
}
ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, adjustedInstanceCount));
if (!mSkipDrawCalls)
{
mFunctions->drawArraysInstanced(mode, first, count, adjustedInstanceCount);
}
mFunctions->drawArraysInstanced(mode, first, count, adjustedInstanceCount);
return gl::NoError();
}
......@@ -310,16 +296,13 @@ gl::Error RendererGL::drawElements(const gl::Context *context,
ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount,
&drawIndexPtr));
if (!mSkipDrawCalls)
if (!usesMultiview)
{
if (!usesMultiview)
{
mFunctions->drawElements(mode, count, type, drawIndexPtr);
}
else
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPtr, instanceCount);
}
mFunctions->drawElements(mode, count, type, drawIndexPtr);
}
else
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPtr, instanceCount);
}
return gl::NoError();
}
......@@ -341,11 +324,7 @@ gl::Error RendererGL::drawElementsInstanced(const gl::Context *context,
ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices,
adjustedInstanceCount, &drawIndexPointer));
if (!mSkipDrawCalls)
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer,
adjustedInstanceCount);
}
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, adjustedInstanceCount);
return gl::NoError();
}
......@@ -364,16 +343,13 @@ gl::Error RendererGL::drawRangeElements(const gl::Context *context,
ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount,
&drawIndexPointer));
if (!mSkipDrawCalls)
if (!usesMultiview)
{
if (!usesMultiview)
{
mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer);
}
else
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instanceCount);
}
mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer);
}
else
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instanceCount);
}
return gl::NoError();
}
......@@ -383,11 +359,7 @@ gl::Error RendererGL::drawArraysIndirect(const gl::Context *context,
const void *indirect)
{
ANGLE_TRY(mStateManager->setDrawIndirectState(context, GL_NONE));
if (!mSkipDrawCalls)
{
mFunctions->drawArraysIndirect(mode, indirect);
}
mFunctions->drawArraysIndirect(mode, indirect);
return gl::NoError();
}
......@@ -397,11 +369,7 @@ gl::Error RendererGL::drawElementsIndirect(const gl::Context *context,
const void *indirect)
{
ANGLE_TRY(mStateManager->setDrawIndirectState(context, type));
if (!mSkipDrawCalls)
{
mFunctions->drawElementsIndirect(mode, type, indirect);
}
mFunctions->drawElementsIndirect(mode, type, indirect);
return gl::NoError();
}
......
......@@ -193,9 +193,6 @@ class RendererGL : angle::NonCopyable
bool mUseDebugOutput;
// For performance debugging
bool mSkipDrawCalls;
mutable bool mCapsInitialized;
mutable gl::Caps mNativeCaps;
mutable gl::TextureCapsMap mNativeTextureCaps;
......
......@@ -13,6 +13,7 @@
#include <EGL/eglext.h>
#include "common/debug.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h"
#include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h"
......@@ -91,7 +92,7 @@ egl::Error DisplayCGL::initialize(egl::Display *display)
}
mFunctions = new FunctionsGLCGL(handle);
mFunctions->initialize();
mFunctions->initialize(display->getAttributeMap());
return DisplayGL::initialize(display);
}
......
......@@ -117,7 +117,7 @@ egl::Error DisplayAndroid::initialize(egl::Display *display)
mCurrentSurface = mDummyPbuffer;
mFunctionsGL = mEGL->makeFunctionsGL();
mFunctionsGL->initialize();
mFunctionsGL->initialize(display->getAttributeMap());
return DisplayGL::initialize(display);
}
......
......@@ -511,7 +511,7 @@ egl::Error DisplayOzone::initialize(egl::Display *display)
}
mFunctionsGL = mEGL->makeFunctionsGL();
mFunctionsGL->initialize();
mFunctionsGL->initialize(display->getAttributeMap());
return DisplayGL::initialize(display);
}
......
......@@ -46,6 +46,8 @@ typedef khronos_int64_t GLint64;
typedef khronos_uint64_t GLuint64;
typedef struct __GLsync *GLsync;
// TODO(jmadill): It's likely we can auto-generate this file from gl.xml.
namespace rx
{
typedef void (INTERNAL_GL_APIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
......@@ -395,8 +397,19 @@ typedef GLboolean (INTERNAL_GL_APIENTRY *PFNGLISSYNCPROC)(GLsync);
typedef void (INTERNAL_GL_APIENTRY *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei, const GLint *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLPROVOKINGVERTEXPROC)(GLenum);
typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLEMASKIPROC)(GLuint, GLbitfield);
typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean);
typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean);
typedef void(INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum,
GLsizei,
GLenum,
GLsizei,
GLsizei,
GLboolean);
typedef void(INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum,
GLsizei,
GLenum,
GLsizei,
GLsizei,
GLsizei,
GLboolean);
typedef void (INTERNAL_GL_APIENTRY *PFNGLWAITSYNCPROC)(GLsync, GLbitfield, GLuint64);
// 3.3
......@@ -647,7 +660,8 @@ typedef void (INTERNAL_GL_APIENTRY *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint, GLuin
typedef GLenum (INTERNAL_GL_APIENTRY *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint, GLenum);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint, GLenum, GLenum, GLenum, const void *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint, GLenum, GLintptr, GLsizeiptr, GLenum, GLenum, const void *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint, GLenum, const GLfloat, GLint);
typedef void(
INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint, GLenum, GLint, GLfloat, GLint);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint, GLenum, GLint, const GLfloat *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint, GLenum, GLint, const GLint *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint, GLenum, GLint, const GLuint *);
......
......@@ -8,6 +8,7 @@
import sys
import os
import re
import xml.etree.ElementTree as etree
from datetime import date
......@@ -25,6 +26,8 @@ def safe_append(the_dict, key, element):
gl_xml_path = os.path.join('..', '..', '..', '..', 'scripts', 'gl.xml')
dispatch_header_path = 'DispatchTableGL_autogen.h'
dispatch_source_path = 'DispatchTableGL_autogen.cpp'
null_functions_header_path = 'null_functions.h'
null_functions_source_path = 'null_functions.cpp'
# Load the JSON and XML data.
data_source_name = 'gl_bindings_data.json'
......@@ -79,10 +82,15 @@ gl_extension_requirements = {}
gles2_extension_requirements = {}
both_extension_requirements = {}
# Used later in the NULL bindings.
all_entry_points = []
for comment, entry_points in json_data.iteritems():
for entry_point_no_prefix in entry_points:
entry_point = "gl" + entry_point_no_prefix
all_entry_points.append(entry_point)
gl_required = None
gles2_required = None
......@@ -176,6 +184,12 @@ class DispatchTableGL : angle::NonCopyable
void initProcsDesktopGL(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsGLES(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsSharedExtensions(const std::set<std::string> &extensions);
#if defined(ANGLE_ENABLE_OPENGL_NULL)
void initProcsDesktopGLNULL(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsGLESNULL(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsSharedExtensionsNULL(const std::set<std::string> &extensions);
#endif // defined(ANGLE_ENABLE_OPENGL_NULL)
}};
}} // namespace rx
......@@ -222,6 +236,10 @@ dispatch_table_source_template = """// GENERATED FILE - DO NOT EDIT.
#include "libANGLE/Version.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#if defined(ANGLE_ENABLE_OPENGL_NULL)
#include "libANGLE/renderer/gl/null_functions.h"
#endif // defined(ANGLE_ENABLE_OPENGL_NULL)
// Check for nullptr so extensions do not overwrite core imports.
#define ASSIGN(NAME, FP) if (!FP) *reinterpret_cast<void **>(&FP) = loadProcAddress(NAME)
......@@ -247,6 +265,27 @@ void DispatchTableGL::initProcsSharedExtensions(const std::set<std::string> &ext
{both_extensions_data}
}}
#if defined(ANGLE_ENABLE_OPENGL_NULL)
void DispatchTableGL::initProcsDesktopGLNULL(const gl::Version &version, const std::set<std::string> &extensions)
{{
{gl_null_data}
{gl_null_extensions_data}
}}
void DispatchTableGL::initProcsGLESNULL(const gl::Version &version, const std::set<std::string> &extensions)
{{
{gles2_null_data}
{gles2_null_extensions_data}
}}
void DispatchTableGL::initProcsSharedExtensionsNULL(const std::set<std::string> &extensions)
{{
{both_null_extensions_data}
}}
#endif // defined(ANGLE_ENABLE_OPENGL_NULL)
}} // namespace rx
"""
......@@ -286,6 +325,20 @@ both_extensions_data = []
for extension, entry_points in sorted(both_extension_requirements.iteritems()):
both_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gles2|gl"))
def assign_null_line(line):
m = re.match(r' ASSIGN\("gl.*", (.+)\);', line)
if m:
name = m.group(1)
return ' ' + name + ' = &gl' + name[0].upper() + name[1:] + 'NULL;'
else:
return line
def assign_null(entry):
return '\n'.join([assign_null_line(line) for line in entry.split('\n')])
def nullify(data):
return [assign_null(entry) for entry in data]
dispatch_table_source = dispatch_table_source_template.format(
script_name = os.path.basename(sys.argv[0]),
data_source_name = data_source_name,
......@@ -295,7 +348,104 @@ dispatch_table_source = dispatch_table_source_template.format(
gl_extensions_data = "\n\n".join(gl_extensions_data),
gles2_data = "\n\n".join(gles2_data),
gles2_extensions_data = "\n\n".join(gles2_extensions_data),
both_extensions_data = "\n\n".join(both_extensions_data))
both_extensions_data = "\n\n".join(both_extensions_data),
gl_null_data = "\n\n".join(nullify(gl_data)),
gl_null_extensions_data = "\n\n".join(nullify(gl_extensions_data)),
gles2_null_data = "\n\n".join(nullify(gles2_data)),
gles2_null_extensions_data = "\n\n".join(nullify(gles2_extensions_data)),
both_null_extensions_data = "\n\n".join(nullify(both_extensions_data)))
with open(dispatch_source_path, "w") as out:
out.write(dispatch_table_source)
# Generate the NULL/stub entry points.
# Process the whole set of commands
def format_param(param):
return "".join(param.itertext())
command_defs = {}
command_decls = {}
for command in xml_root.findall('commands/command'):
proto = command.find('proto')
command_name = proto.find('name').text
entry = ''.join(proto.itertext())
return_type = entry[:-len(command_name)]
entry = return_type + ' INTERNAL_GL_APIENTRY ' + entry[len(return_type):] + 'NULL('
param_text = [format_param(param) for param in command.findall('param')]
entry += ', '.join(param_text) + ')'
command_decls[command_name] = entry + ';'
entry += '\n{\n'
if return_type != 'void ':
entry += ' return static_cast<' + return_type + '>(0);\n'
entry += '}'
command_defs[command_name] = entry
null_decls = [command_decls[entry_point] for entry_point in sorted(all_entry_points)]
null_stubs = [command_defs[entry_point] for entry_point in sorted(all_entry_points)]
null_functions_header_template = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name} and gl.xml.
//
// Copyright {year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// {file_name}:
// Declares the NULL/Stub bindings for the OpenGL back-end.
#ifndef LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
#define LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
namespace rx
{{
{table_data}
}} // namespace rx
#endif // LIBGLESV2_RENDERER_GL_NULL_GL_FUNCTIONS_AUTOGEN_H_
"""
null_functions_header = null_functions_header_template.format(
script_name = os.path.basename(sys.argv[0]),
data_source_name = data_source_name,
year = date.today().year,
file_name = null_functions_header_path,
table_data = "\n".join(null_decls))
with open(null_functions_header_path, "w") as out:
out.write(null_functions_header)
null_functions_source_template = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name} and gl.xml.
//
// Copyright {year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// {file_name}:
// Defines the NULL/Stub bindings for the OpenGL back-end.
#include "libANGLE/renderer/gl/null_functions.h"
namespace rx
{{
{table_data}
}} // namespace rx
"""
null_functions_source = null_functions_source_template.format(
script_name = os.path.basename(sys.argv[0]),
data_source_name = data_source_name,
year = date.today().year,
file_name = null_functions_source_path,
table_data = "\n\n".join(null_stubs))
with open(null_functions_source_path, "w") as out:
out.write(null_functions_source)
......@@ -292,7 +292,7 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
}
mFunctionsGL = new FunctionsGLGLX(mGLX.getProc);
mFunctionsGL->initialize();
mFunctionsGL->initialize(eglAttributes);
// TODO(cwallez, angleproject:1303) Disable the OpenGL ES backend on Linux NVIDIA and Intel as
// it has problems on our automated testing. An OpenGL ES backend might not trigger this test if
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -277,7 +277,7 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
mCurrentDC = mDeviceContext;
mFunctionsGL = new FunctionsGLWindows(mOpenGLModule, mFunctionsWGL->getProcAddress);
mFunctionsGL->initialize();
mFunctionsGL->initialize(displayAttributes);
mHasRobustness = mFunctionsGL->getGraphicsResetStatus != nullptr;
if (mHasWGLCreateContextRobustness != mHasRobustness)
......
......@@ -620,6 +620,11 @@
'libANGLE/renderer/gl/renderergl_utils.cpp',
'libANGLE/renderer/gl/renderergl_utils.h',
],
'libangle_gl_null_sources':
[
'libANGLE/renderer/gl/null_functions.cpp',
'libANGLE/renderer/gl/null_functions.h',
],
'libangle_gl_wgl_sources':
[
'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp',
......@@ -910,6 +915,13 @@
'ANGLE_ENABLE_OPENGL',
],
}],
['angle_enable_gl_null==1',
{
'defines':
[
'ANGLE_ENABLE_OPENGL_NULL',
],
}],
['angle_enable_vulkan==1',
{
'defines':
......@@ -1071,6 +1083,13 @@
],
'conditions':
[
['angle_enable_gl_null==1',
{
'sources':
[
'<@(libangle_gl_null_sources)',
],
}],
['OS=="win"',
{
'sources':
......
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