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") { ...@@ -396,6 +396,9 @@ config("libANGLE_config") {
if (use_x11) { if (use_x11) {
defines += [ "ANGLE_USE_X11" ] defines += [ "ANGLE_USE_X11" ]
} }
if (angle_enable_gl_null) {
defines += [ "ANGLE_ENABLE_OPENGL_NULL" ]
}
} }
if (angle_enable_vulkan) { if (angle_enable_vulkan) {
defines += [ "ANGLE_ENABLE_VULKAN" ] defines += [ "ANGLE_ENABLE_VULKAN" ]
...@@ -449,6 +452,9 @@ static_library("libANGLE") { ...@@ -449,6 +452,9 @@ static_library("libANGLE") {
sources += rebase_path(gles_gypi.libangle_gl_sources, ".", "src") sources += rebase_path(gles_gypi.libangle_gl_sources, ".", "src")
include_dirs += [ "src/third_party/khronos" ] include_dirs += [ "src/third_party/khronos" ]
if (angle_enable_gl_null) {
sources += rebase_path(gles_gypi.libangle_gl_null_sources, ".", "src")
}
if (is_win) { if (is_win) {
sources += rebase_path(gles_gypi.libangle_gl_wgl_sources, ".", "src") sources += rebase_path(gles_gypi.libangle_gl_wgl_sources, ".", "src")
} }
......
...@@ -20,6 +20,7 @@ if (build_with_chromium) { ...@@ -20,6 +20,7 @@ if (build_with_chromium) {
angle_enable_d3d9 = false angle_enable_d3d9 = false
angle_enable_d3d11 = false angle_enable_d3d11 = false
angle_enable_gl = false angle_enable_gl = false
angle_enable_gl_null = false
angle_enable_vulkan = false angle_enable_vulkan = false
angle_enable_null = true angle_enable_null = true
...@@ -27,16 +28,20 @@ if (is_win) { ...@@ -27,16 +28,20 @@ if (is_win) {
angle_enable_d3d9 = true angle_enable_d3d9 = true
angle_enable_d3d11 = true angle_enable_d3d11 = true
angle_enable_gl = true angle_enable_gl = true
angle_enable_gl_null = true
angle_enable_vulkan = true angle_enable_vulkan = true
import("//build/config/win/visual_studio_version.gni") import("//build/config/win/visual_studio_version.gni")
} else if (is_linux && use_x11 && !is_chromeos) { } else if (is_linux && use_x11 && !is_chromeos) {
angle_enable_gl = true angle_enable_gl = true
angle_enable_gl_null = true
angle_enable_vulkan = true angle_enable_vulkan = true
} else if (is_mac || ozone_platform_gbm) { } else if (is_mac || ozone_platform_gbm) {
angle_enable_gl = true angle_enable_gl = true
angle_enable_gl_null = true
} else if (is_android) { } else if (is_android) {
angle_enable_gl = true angle_enable_gl = true
angle_enable_gl_null = true
} }
angle_enable_essl = true angle_enable_essl = true
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
'angle_enable_d3d9%': 0, 'angle_enable_d3d9%': 0,
'angle_enable_d3d11%': 0, 'angle_enable_d3d11%': 0,
'angle_enable_gl%': 0, 'angle_enable_gl%': 0,
'angle_enable_gl_null%': 0,
'angle_enable_vulkan%': 0, 'angle_enable_vulkan%': 0,
'angle_enable_essl%': 1, # Enable this for all configs by default 'angle_enable_essl%': 1, # Enable this for all configs by default
'angle_enable_glsl%': 1, # Enable this for all configs by default 'angle_enable_glsl%': 1, # Enable this for all configs by default
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
['OS=="win"', ['OS=="win"',
{ {
'angle_enable_gl%': 1, 'angle_enable_gl%': 1,
'angle_enable_gl_null%': 1,
'angle_enable_d3d9%': 1, 'angle_enable_d3d9%': 1,
'angle_enable_d3d11%': 1, 'angle_enable_d3d11%': 1,
'angle_enable_hlsl%': 1, 'angle_enable_hlsl%': 1,
...@@ -35,15 +37,18 @@ ...@@ -35,15 +37,18 @@
['OS=="linux" and use_x11==1 and chromeos==0', ['OS=="linux" and use_x11==1 and chromeos==0',
{ {
'angle_enable_gl%': 1, 'angle_enable_gl%': 1,
'angle_enable_gl_null%': 1,
'angle_enable_vulkan%': 1, 'angle_enable_vulkan%': 1,
}], }],
['OS=="mac"', ['OS=="mac"',
{ {
'angle_enable_gl%': 1, 'angle_enable_gl%': 1,
'angle_enable_gl_null%': 1,
}], }],
['use_ozone==1', ['use_ozone==1',
{ {
'angle_enable_gl%': 1, 'angle_enable_gl%': 1,
'angle_enable_gl_null%': 1,
}], }],
], ],
'angle_enable_null%': 1, # Available on all platforms '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 ...@@ -772,6 +772,13 @@ class DispatchTableGL : angle::NonCopyable
void initProcsDesktopGL(const gl::Version &version, const std::set<std::string> &extensions); 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 initProcsGLES(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsSharedExtensions(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 } // namespace rx
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <algorithm> #include <algorithm>
#include "common/string_utils.h" #include "common/string_utils.h"
#include "libANGLE/AttributeMap.h"
#include "libANGLE/renderer/gl/renderergl_utils.h" #include "libANGLE/renderer/gl/renderergl_utils.h"
namespace rx namespace rx
...@@ -55,6 +56,40 @@ static std::vector<std::string> GetIndexedExtensions(PFNGLGETINTEGERVPROC getInt ...@@ -55,6 +56,40 @@ static std::vector<std::string> GetIndexedExtensions(PFNGLGETINTEGERVPROC getInt
return result; 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) #define ASSIGN(NAME, FP) *reinterpret_cast<void **>(&FP) = loadProcAddress(NAME)
FunctionsGL::FunctionsGL() : version(), standard(), extensions() FunctionsGL::FunctionsGL() : version(), standard(), extensions()
...@@ -65,7 +100,7 @@ FunctionsGL::~FunctionsGL() ...@@ -65,7 +100,7 @@ FunctionsGL::~FunctionsGL()
{ {
} }
void FunctionsGL::initialize() void FunctionsGL::initialize(const egl::AttributeMap &displayAttributes)
{ {
// Grab the version number // Grab the version number
ASSIGN("glGetString", getString); ASSIGN("glGetString", getString);
...@@ -90,12 +125,18 @@ void FunctionsGL::initialize() ...@@ -90,12 +125,18 @@ void FunctionsGL::initialize()
extensionSet.insert(extension); extensionSet.insert(extension);
} }
// Note: // Note:
// Even though extensions are written against specific versions of GL, many drivers expose the // 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 // extensions in even older versions. Always try loading the extensions regardless of GL
// version. // 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) switch (standard)
{ {
case STANDARD_GL_DESKTOP: case STANDARD_GL_DESKTOP:
...@@ -107,23 +148,53 @@ void FunctionsGL::initialize() ...@@ -107,23 +148,53 @@ void FunctionsGL::initialize()
getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile); 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; break;
} }
case STANDARD_GL_ES: case STANDARD_GL_ES:
{
// No profiles in GLES // No profiles in GLES
profile = 0; 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; break;
}
default: default:
UNREACHABLE(); UNREACHABLE();
break; 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 bool FunctionsGL::isAtLeastGL(const gl::Version &glVersion) const
...@@ -161,4 +232,39 @@ bool FunctionsGL::hasGLESExtension(const std::string &ext) const ...@@ -161,4 +232,39 @@ bool FunctionsGL::hasGLESExtension(const std::string &ext) const
return standard == STANDARD_GL_ES && hasExtension(ext); 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 } // namespace gl
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
#include "libANGLE/renderer/gl/functionsgl_enums.h" #include "libANGLE/renderer/gl/functionsgl_enums.h"
#include "libANGLE/renderer/gl/functionsgl_typedefs.h" #include "libANGLE/renderer/gl/functionsgl_typedefs.h"
namespace egl
{
class AttributeMap;
} // namespace egl
namespace rx namespace rx
{ {
...@@ -30,7 +35,7 @@ class FunctionsGL : public DispatchTableGL ...@@ -30,7 +35,7 @@ class FunctionsGL : public DispatchTableGL
FunctionsGL(); FunctionsGL();
virtual ~FunctionsGL(); virtual ~FunctionsGL();
void initialize(); void initialize(const egl::AttributeMap &displayAttributes);
// Version information // Version information
gl::Version version; gl::Version version;
...@@ -46,6 +51,10 @@ class FunctionsGL : public DispatchTableGL ...@@ -46,6 +51,10 @@ class FunctionsGL : public DispatchTableGL
bool hasExtension(const std::string &ext) const; bool hasExtension(const std::string &ext) const;
bool hasGLExtension(const std::string &ext) const; bool hasGLExtension(const std::string &ext) const;
bool hasGLESExtension(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 } // namespace rx
......
...@@ -171,7 +171,6 @@ RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &at ...@@ -171,7 +171,6 @@ RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &at
mBlitter(nullptr), mBlitter(nullptr),
mMultiviewClearer(nullptr), mMultiviewClearer(nullptr),
mUseDebugOutput(false), mUseDebugOutput(false),
mSkipDrawCalls(false),
mCapsInitialized(false), mCapsInitialized(false),
mMultiviewImplementationType(MultiviewImplementationTypeGL::UNSPECIFIED) mMultiviewImplementationType(MultiviewImplementationTypeGL::UNSPECIFIED)
{ {
...@@ -203,13 +202,6 @@ RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &at ...@@ -203,13 +202,6 @@ RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &at
mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr); 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) if (mWorkarounds.initializeCurrentVertexAttributes)
{ {
GLint maxVertexAttribs = 0; GLint maxVertexAttribs = 0;
...@@ -262,16 +254,13 @@ gl::Error RendererGL::drawArrays(const gl::Context *context, ...@@ -262,16 +254,13 @@ gl::Error RendererGL::drawArrays(const gl::Context *context,
const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0; const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, instanceCount)); ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, instanceCount));
if (!mSkipDrawCalls) if (!usesMultiview)
{ {
if (!usesMultiview) mFunctions->drawArrays(mode, first, count);
{ }
mFunctions->drawArrays(mode, first, count); else
} {
else mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
{
mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
}
} }
return gl::NoError(); return gl::NoError();
} }
...@@ -290,10 +279,7 @@ gl::Error RendererGL::drawArraysInstanced(const gl::Context *context, ...@@ -290,10 +279,7 @@ gl::Error RendererGL::drawArraysInstanced(const gl::Context *context,
} }
ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, adjustedInstanceCount)); 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(); return gl::NoError();
} }
...@@ -310,16 +296,13 @@ gl::Error RendererGL::drawElements(const gl::Context *context, ...@@ -310,16 +296,13 @@ gl::Error RendererGL::drawElements(const gl::Context *context,
ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount, ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount,
&drawIndexPtr)); &drawIndexPtr));
if (!mSkipDrawCalls) if (!usesMultiview)
{ {
if (!usesMultiview) mFunctions->drawElements(mode, count, type, drawIndexPtr);
{ }
mFunctions->drawElements(mode, count, type, drawIndexPtr); else
} {
else mFunctions->drawElementsInstanced(mode, count, type, drawIndexPtr, instanceCount);
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPtr, instanceCount);
}
} }
return gl::NoError(); return gl::NoError();
} }
...@@ -341,11 +324,7 @@ gl::Error RendererGL::drawElementsInstanced(const gl::Context *context, ...@@ -341,11 +324,7 @@ gl::Error RendererGL::drawElementsInstanced(const gl::Context *context,
ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices,
adjustedInstanceCount, &drawIndexPointer)); adjustedInstanceCount, &drawIndexPointer));
if (!mSkipDrawCalls) mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, adjustedInstanceCount);
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer,
adjustedInstanceCount);
}
return gl::NoError(); return gl::NoError();
} }
...@@ -364,16 +343,13 @@ gl::Error RendererGL::drawRangeElements(const gl::Context *context, ...@@ -364,16 +343,13 @@ gl::Error RendererGL::drawRangeElements(const gl::Context *context,
ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount, ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount,
&drawIndexPointer)); &drawIndexPointer));
if (!mSkipDrawCalls) if (!usesMultiview)
{ {
if (!usesMultiview) mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer);
{ }
mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer); else
} {
else mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instanceCount);
{
mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instanceCount);
}
} }
return gl::NoError(); return gl::NoError();
} }
...@@ -383,11 +359,7 @@ gl::Error RendererGL::drawArraysIndirect(const gl::Context *context, ...@@ -383,11 +359,7 @@ gl::Error RendererGL::drawArraysIndirect(const gl::Context *context,
const void *indirect) const void *indirect)
{ {
ANGLE_TRY(mStateManager->setDrawIndirectState(context, GL_NONE)); ANGLE_TRY(mStateManager->setDrawIndirectState(context, GL_NONE));
mFunctions->drawArraysIndirect(mode, indirect);
if (!mSkipDrawCalls)
{
mFunctions->drawArraysIndirect(mode, indirect);
}
return gl::NoError(); return gl::NoError();
} }
...@@ -397,11 +369,7 @@ gl::Error RendererGL::drawElementsIndirect(const gl::Context *context, ...@@ -397,11 +369,7 @@ gl::Error RendererGL::drawElementsIndirect(const gl::Context *context,
const void *indirect) const void *indirect)
{ {
ANGLE_TRY(mStateManager->setDrawIndirectState(context, type)); ANGLE_TRY(mStateManager->setDrawIndirectState(context, type));
mFunctions->drawElementsIndirect(mode, type, indirect);
if (!mSkipDrawCalls)
{
mFunctions->drawElementsIndirect(mode, type, indirect);
}
return gl::NoError(); return gl::NoError();
} }
......
...@@ -193,9 +193,6 @@ class RendererGL : angle::NonCopyable ...@@ -193,9 +193,6 @@ class RendererGL : angle::NonCopyable
bool mUseDebugOutput; bool mUseDebugOutput;
// For performance debugging
bool mSkipDrawCalls;
mutable bool mCapsInitialized; mutable bool mCapsInitialized;
mutable gl::Caps mNativeCaps; mutable gl::Caps mNativeCaps;
mutable gl::TextureCapsMap mNativeTextureCaps; mutable gl::TextureCapsMap mNativeTextureCaps;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h" #include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h"
#include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h" #include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h"
...@@ -91,7 +92,7 @@ egl::Error DisplayCGL::initialize(egl::Display *display) ...@@ -91,7 +92,7 @@ egl::Error DisplayCGL::initialize(egl::Display *display)
} }
mFunctions = new FunctionsGLCGL(handle); mFunctions = new FunctionsGLCGL(handle);
mFunctions->initialize(); mFunctions->initialize(display->getAttributeMap());
return DisplayGL::initialize(display); return DisplayGL::initialize(display);
} }
......
...@@ -117,7 +117,7 @@ egl::Error DisplayAndroid::initialize(egl::Display *display) ...@@ -117,7 +117,7 @@ egl::Error DisplayAndroid::initialize(egl::Display *display)
mCurrentSurface = mDummyPbuffer; mCurrentSurface = mDummyPbuffer;
mFunctionsGL = mEGL->makeFunctionsGL(); mFunctionsGL = mEGL->makeFunctionsGL();
mFunctionsGL->initialize(); mFunctionsGL->initialize(display->getAttributeMap());
return DisplayGL::initialize(display); return DisplayGL::initialize(display);
} }
......
...@@ -511,7 +511,7 @@ egl::Error DisplayOzone::initialize(egl::Display *display) ...@@ -511,7 +511,7 @@ egl::Error DisplayOzone::initialize(egl::Display *display)
} }
mFunctionsGL = mEGL->makeFunctionsGL(); mFunctionsGL = mEGL->makeFunctionsGL();
mFunctionsGL->initialize(); mFunctionsGL->initialize(display->getAttributeMap());
return DisplayGL::initialize(display); return DisplayGL::initialize(display);
} }
......
...@@ -46,6 +46,8 @@ typedef khronos_int64_t GLint64; ...@@ -46,6 +46,8 @@ typedef khronos_int64_t GLint64;
typedef khronos_uint64_t GLuint64; typedef khronos_uint64_t GLuint64;
typedef struct __GLsync *GLsync; typedef struct __GLsync *GLsync;
// TODO(jmadill): It's likely we can auto-generate this file from gl.xml.
namespace rx namespace rx
{ {
typedef void (INTERNAL_GL_APIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); 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); ...@@ -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 *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei, const GLint *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLPROVOKINGVERTEXPROC)(GLenum); typedef void (INTERNAL_GL_APIENTRY *PFNGLPROVOKINGVERTEXPROC)(GLenum);
typedef void (INTERNAL_GL_APIENTRY *PFNGLSAMPLEMASKIPROC)(GLuint, GLbitfield); 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 *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum,
typedef void (INTERNAL_GL_APIENTRY *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean); 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); typedef void (INTERNAL_GL_APIENTRY *PFNGLWAITSYNCPROC)(GLsync, GLbitfield, GLuint64);
// 3.3 // 3.3
...@@ -647,7 +660,8 @@ typedef void (INTERNAL_GL_APIENTRY *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint, GLuin ...@@ -647,7 +660,8 @@ typedef void (INTERNAL_GL_APIENTRY *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint, GLuin
typedef GLenum (INTERNAL_GL_APIENTRY *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint, GLenum); 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 *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 *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 *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint, GLenum, GLint, const GLfloat *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint, GLenum, GLint, const GLint *); typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint, GLenum, GLint, const GLint *);
typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint, GLenum, GLint, const GLuint *); typedef void (INTERNAL_GL_APIENTRY *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint, GLenum, GLint, const GLuint *);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
import sys import sys
import os import os
import re
import xml.etree.ElementTree as etree import xml.etree.ElementTree as etree
from datetime import date from datetime import date
...@@ -25,6 +26,8 @@ def safe_append(the_dict, key, element): ...@@ -25,6 +26,8 @@ def safe_append(the_dict, key, element):
gl_xml_path = os.path.join('..', '..', '..', '..', 'scripts', 'gl.xml') gl_xml_path = os.path.join('..', '..', '..', '..', 'scripts', 'gl.xml')
dispatch_header_path = 'DispatchTableGL_autogen.h' dispatch_header_path = 'DispatchTableGL_autogen.h'
dispatch_source_path = 'DispatchTableGL_autogen.cpp' 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. # Load the JSON and XML data.
data_source_name = 'gl_bindings_data.json' data_source_name = 'gl_bindings_data.json'
...@@ -79,10 +82,15 @@ gl_extension_requirements = {} ...@@ -79,10 +82,15 @@ gl_extension_requirements = {}
gles2_extension_requirements = {} gles2_extension_requirements = {}
both_extension_requirements = {} both_extension_requirements = {}
# Used later in the NULL bindings.
all_entry_points = []
for comment, entry_points in json_data.iteritems(): for comment, entry_points in json_data.iteritems():
for entry_point_no_prefix in entry_points: for entry_point_no_prefix in entry_points:
entry_point = "gl" + entry_point_no_prefix entry_point = "gl" + entry_point_no_prefix
all_entry_points.append(entry_point)
gl_required = None gl_required = None
gles2_required = None gles2_required = None
...@@ -176,6 +184,12 @@ class DispatchTableGL : angle::NonCopyable ...@@ -176,6 +184,12 @@ class DispatchTableGL : angle::NonCopyable
void initProcsDesktopGL(const gl::Version &version, const std::set<std::string> &extensions); 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 initProcsGLES(const gl::Version &version, const std::set<std::string> &extensions);
void initProcsSharedExtensions(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 }} // namespace rx
...@@ -222,6 +236,10 @@ dispatch_table_source_template = """// GENERATED FILE - DO NOT EDIT. ...@@ -222,6 +236,10 @@ dispatch_table_source_template = """// GENERATED FILE - DO NOT EDIT.
#include "libANGLE/Version.h" #include "libANGLE/Version.h"
#include "libANGLE/renderer/gl/FunctionsGL.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. // Check for nullptr so extensions do not overwrite core imports.
#define ASSIGN(NAME, FP) if (!FP) *reinterpret_cast<void **>(&FP) = loadProcAddress(NAME) #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 ...@@ -247,6 +265,27 @@ void DispatchTableGL::initProcsSharedExtensions(const std::set<std::string> &ext
{both_extensions_data} {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 }} // namespace rx
""" """
...@@ -286,6 +325,20 @@ both_extensions_data = [] ...@@ -286,6 +325,20 @@ both_extensions_data = []
for extension, entry_points in sorted(both_extension_requirements.iteritems()): for extension, entry_points in sorted(both_extension_requirements.iteritems()):
both_extensions_data.append(format_extension_requirements_lines(extension, entry_points, "gles2|gl")) 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( dispatch_table_source = dispatch_table_source_template.format(
script_name = os.path.basename(sys.argv[0]), script_name = os.path.basename(sys.argv[0]),
data_source_name = data_source_name, data_source_name = data_source_name,
...@@ -295,7 +348,104 @@ dispatch_table_source = dispatch_table_source_template.format( ...@@ -295,7 +348,104 @@ dispatch_table_source = dispatch_table_source_template.format(
gl_extensions_data = "\n\n".join(gl_extensions_data), gl_extensions_data = "\n\n".join(gl_extensions_data),
gles2_data = "\n\n".join(gles2_data), gles2_data = "\n\n".join(gles2_data),
gles2_extensions_data = "\n\n".join(gles2_extensions_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: with open(dispatch_source_path, "w") as out:
out.write(dispatch_table_source) 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) ...@@ -292,7 +292,7 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
} }
mFunctionsGL = new FunctionsGLGLX(mGLX.getProc); 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 // 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 // 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) ...@@ -277,7 +277,7 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
mCurrentDC = mDeviceContext; mCurrentDC = mDeviceContext;
mFunctionsGL = new FunctionsGLWindows(mOpenGLModule, mFunctionsWGL->getProcAddress); mFunctionsGL = new FunctionsGLWindows(mOpenGLModule, mFunctionsWGL->getProcAddress);
mFunctionsGL->initialize(); mFunctionsGL->initialize(displayAttributes);
mHasRobustness = mFunctionsGL->getGraphicsResetStatus != nullptr; mHasRobustness = mFunctionsGL->getGraphicsResetStatus != nullptr;
if (mHasWGLCreateContextRobustness != mHasRobustness) if (mHasWGLCreateContextRobustness != mHasRobustness)
......
...@@ -620,6 +620,11 @@ ...@@ -620,6 +620,11 @@
'libANGLE/renderer/gl/renderergl_utils.cpp', 'libANGLE/renderer/gl/renderergl_utils.cpp',
'libANGLE/renderer/gl/renderergl_utils.h', '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_gl_wgl_sources':
[ [
'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp', 'libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp',
...@@ -910,6 +915,13 @@ ...@@ -910,6 +915,13 @@
'ANGLE_ENABLE_OPENGL', 'ANGLE_ENABLE_OPENGL',
], ],
}], }],
['angle_enable_gl_null==1',
{
'defines':
[
'ANGLE_ENABLE_OPENGL_NULL',
],
}],
['angle_enable_vulkan==1', ['angle_enable_vulkan==1',
{ {
'defines': 'defines':
...@@ -1071,6 +1083,13 @@ ...@@ -1071,6 +1083,13 @@
], ],
'conditions': 'conditions':
[ [
['angle_enable_gl_null==1',
{
'sources':
[
'<@(libangle_gl_null_sources)',
],
}],
['OS=="win"', ['OS=="win"',
{ {
'sources': '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