bug 900101 - GLContext let extension group queries XXX_* use mVersion and mProfile - r=jgilbert,bjacob

This commit is contained in:
Guillaume Abadie 2013-08-02 17:30:58 -04:00
parent f4bef5d942
commit 8eddab1693
4 changed files with 258 additions and 65 deletions

View File

@ -15,6 +15,7 @@
#include "GLContextProvider.h"
#include "GLTextureImage.h"
#include "nsIMemoryReporter.h"
#include "nsPrintfCString.h"
#include "nsThreadUtils.h"
#include "prenv.h"
#include "prlink.h"
@ -469,8 +470,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
// Check for aux symbols based on extensions
if (IsExtensionSupported(GLContext::ANGLE_framebuffer_blit) ||
IsExtensionSupported(GLContext::EXT_framebuffer_blit))
if (IsExtensionSupported(XXX_framebuffer_blit))
{
SymLoadStruct auxSymbols[] = {
{
@ -487,13 +487,12 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
NS_ERROR("GL supports framebuffer_blit without supplying glBlitFramebuffer");
MarkExtensionUnsupported(ANGLE_framebuffer_blit);
MarkExtensionUnsupported(EXT_framebuffer_blit);
MarkExtensionGroupUnsupported(XXX_framebuffer_blit);
mSymbols.fBlitFramebuffer = nullptr;
}
}
if (SupportsFramebufferMultisample())
if (IsExtensionSupported(XXX_framebuffer_multisample))
{
MOZ_ASSERT(SupportsSplitFramebuffer());
SymLoadStruct auxSymbols[] = {
@ -511,8 +510,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
NS_ERROR("GL supports framebuffer_multisample without supplying glRenderbufferStorageMultisample");
MarkExtensionUnsupported(ANGLE_framebuffer_multisample);
MarkExtensionUnsupported(EXT_framebuffer_multisample);
MarkExtensionGroupUnsupported(XXX_framebuffer_multisample);
mSymbols.fRenderbufferStorageMultisample = nullptr;
}
}
@ -572,9 +570,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (!LoadSymbols(&vaoSymbols[0], trygl, prefix)) {
NS_ERROR("GL supports Vertex Array Object without supplying its functions.");
MarkExtensionUnsupported(ARB_vertex_array_object);
MarkExtensionUnsupported(OES_vertex_array_object);
MarkExtensionUnsupported(APPLE_vertex_array_object);
MarkExtensionGroupUnsupported(XXX_vertex_array_object);
mSymbols.fIsVertexArray = nullptr;
mSymbols.fGenVertexArrays = nullptr;
mSymbols.fBindVertexArray = nullptr;
@ -597,7 +593,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (!LoadSymbols(&vaoSymbols[0], trygl, prefix)) {
NS_ERROR("GL supports Vertex Array Object without supplying its functions.");
MarkExtensionUnsupported(APPLE_vertex_array_object);
MarkExtensionGroupUnsupported(XXX_vertex_array_object);
mSymbols.fIsVertexArray = nullptr;
mSymbols.fGenVertexArrays = nullptr;
mSymbols.fBindVertexArray = nullptr;
@ -631,10 +627,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
if (!LoadSymbols(drawInstancedSymbols, trygl, prefix)) {
NS_ERROR("GL supports instanced draws without supplying its functions.");
MarkExtensionUnsupported(ARB_draw_instanced);
MarkExtensionUnsupported(EXT_draw_instanced);
MarkExtensionUnsupported(NV_draw_instanced);
MarkExtensionUnsupported(ANGLE_instanced_array);
MarkExtensionGroupUnsupported(XXX_draw_instanced);
mSymbols.fDrawArraysInstanced = nullptr;
mSymbols.fDrawElementsInstanced = nullptr;
}
@ -731,6 +724,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
NS_WARNING("InitWithPrefix failed!");
}
mVersionString = nsPrintfCString("%u.%u.%u", mVersion / 100, (mVersion / 10) % 10, mVersion % 10);
return mInitialized;
}

View File

@ -197,6 +197,13 @@ public:
return "OpenGL unknown profile";
}
/**
* Return true if we are running on a OpenGL core profile context
*/
const char* ProfileString() const {
return GetProfileName(mProfile);
}
/**
* Return true if the context is compatible with given parameters
*
@ -228,6 +235,10 @@ public:
return mVersion;
}
const char* VersionString() const {
return mVersionString.get();
}
int Vendor() const {
return mVendor;
}
@ -283,6 +294,7 @@ protected:
* the context is an OpenGL 2.1 context, mVersion value will be 210.
*/
unsigned int mVersion;
nsCString mVersionString;
ContextProfile mProfile;
int32_t mVendor;
@ -369,7 +381,8 @@ public:
EXT_draw_instanced,
NV_draw_instanced,
ANGLE_instanced_array,
Extensions_Max
Extensions_Max,
Extensions_End
};
bool IsExtensionSupported(GLExtensions aKnownExtension) const {
@ -460,69 +473,33 @@ public:
/**
* This enum should be sorted by name.
*/
enum GLExtensionPackages {
enum GLExtensionGroup {
XXX_draw_buffers,
XXX_draw_instanced,
XXX_framebuffer_blit,
XXX_framebuffer_multisample,
XXX_framebuffer_object,
XXX_robustness,
XXX_texture_float,
XXX_texture_non_power_of_two,
XXX_robustness,
XXX_vertex_array_object,
ExtensionPackages_Max
ExtensionGroup_Max
};
bool IsExtensionSupported(GLExtensionPackages aKnownExtensionPackage) const
{
switch (aKnownExtensionPackage)
{
case XXX_draw_buffers:
return IsExtensionSupported(ARB_draw_buffers) ||
IsExtensionSupported(EXT_draw_buffers);
bool IsExtensionSupported(GLExtensionGroup extensionGroup) const;
case XXX_draw_instanced:
return IsExtensionSupported(ARB_draw_instanced) ||
IsExtensionSupported(EXT_draw_instanced) ||
IsExtensionSupported(NV_draw_instanced) ||
IsExtensionSupported(ANGLE_instanced_array);
static const char* GetExtensionGroupName(GLExtensionGroup extensionGroup);
case XXX_framebuffer_blit:
return IsExtensionSupported(EXT_framebuffer_blit) ||
IsExtensionSupported(ANGLE_framebuffer_blit);
case XXX_framebuffer_multisample:
return IsExtensionSupported(EXT_framebuffer_multisample) ||
IsExtensionSupported(ANGLE_framebuffer_multisample);
private:
case XXX_framebuffer_object:
return IsExtensionSupported(ARB_framebuffer_object) ||
IsExtensionSupported(EXT_framebuffer_object);
case XXX_texture_float:
return IsExtensionSupported(ARB_texture_float) ||
IsExtensionSupported(OES_texture_float);
case XXX_robustness:
return IsExtensionSupported(ARB_robustness) ||
IsExtensionSupported(EXT_robustness);
case XXX_texture_non_power_of_two:
return IsExtensionSupported(ARB_texture_non_power_of_two) ||
IsExtensionSupported(OES_texture_npot);
case XXX_vertex_array_object:
return IsExtensionSupported(ARB_vertex_array_object) ||
IsExtensionSupported(OES_vertex_array_object) ||
IsExtensionSupported(APPLE_vertex_array_object);
default:
break;
}
MOZ_ASSERT(false, "GLContext::IsExtensionSupported : unknown <aKnownExtensionPackage>");
return false;
}
/**
* Mark all extensions of this group as unsupported.
*
* Returns false if marking this extension group as unsupported contradicts
* the OpenGL version and profile. Returns true otherwise.
*/
bool MarkExtensionGroupUnsupported(GLExtensionGroup extensionGroup);
// -----------------------------------------------------------------------------

View File

@ -0,0 +1,220 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GLContext.h"
#include "nsPrintfCString.h"
namespace mozilla {
namespace gl {
const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
struct ExtensionGroupInfo
{
const char* mName;
unsigned int mOpenGLVersion;
unsigned int mOpenGLESVersion;
GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
};
static const ExtensionGroupInfo sExtensionGroupInfoArr[] = {
{
"XXX_draw_buffers",
200, // OpenGL version
300, // OpenGL ES version
{
GLContext::ARB_draw_buffers,
GLContext::EXT_draw_buffers,
GLContext::Extensions_End
}
},
{
"XXX_draw_instanced",
310, // OpenGL version
300, // OpenGL ES version
{
GLContext::ARB_draw_instanced,
GLContext::EXT_draw_instanced,
GLContext::NV_draw_instanced,
GLContext::ANGLE_instanced_array,
GLContext::Extensions_End
}
},
{
"XXX_framebuffer_blit",
300, // OpenGL version
300, // OpenGL ES version
{
GLContext::EXT_framebuffer_blit,
GLContext::ANGLE_framebuffer_blit,
GLContext::Extensions_End
}
},
{
"XXX_framebuffer_multisample",
300, // OpenGL version
300, // OpenGL ES version
{
GLContext::EXT_framebuffer_multisample,
GLContext::ANGLE_framebuffer_multisample,
GLContext::Extensions_End
}
},
{
"XXX_framebuffer_object",
300, // OpenGL version
200, // OpenGL ES version
{
GLContext::ARB_framebuffer_object,
GLContext::EXT_framebuffer_object,
GLContext::Extensions_End
}
},
{
"XXX_robustness",
0, // OpenGL version
0, // OpenGL ES version
{
GLContext::ARB_robustness,
GLContext::EXT_robustness,
GLContext::Extensions_End
}
},
{
"XXX_texture_float",
310, // OpenGL version
300, // OpenGL ES version
{
GLContext::ARB_texture_float,
GLContext::OES_texture_float,
GLContext::Extensions_End
}
},
{
"XXX_texture_non_power_of_two",
200, // OpenGL version
300, // OpenGL ES version
{
GLContext::ARB_texture_non_power_of_two,
GLContext::OES_texture_npot,
GLContext::Extensions_End
}
},
{
"XXX_vertex_array_object",
300, // OpenGL version
300, // OpenGL ES version
{
GLContext::ARB_vertex_array_object,
GLContext::OES_vertex_array_object,
GLContext::APPLE_vertex_array_object,
GLContext::Extensions_End
}
}
};
static inline const ExtensionGroupInfo&
GetExtensionGroupInfo(GLContext::GLExtensionGroup extensionGroup)
{
static_assert(ArrayLength(sExtensionGroupInfoArr) == size_t(GLContext::ExtensionGroup_Max),
"Mismatched lengths for sExtensionGroupInfos and ExtensionGroup enums");
MOZ_ASSERT(extensionGroup < GLContext::ExtensionGroup_Max,
"GLContext::GetExtensionGroupInfo : unknown <extensionGroup>");
return sExtensionGroupInfoArr[extensionGroup];
}
static inline uint32_t
ProfileVersionForExtensionGroup(GLContext::GLExtensionGroup extensionGroup, ContextProfile profile)
{
MOZ_ASSERT(profile != ContextProfile::Unknown,
"GLContext::ProfileVersionForExtensionGroup : unknown <profile>");
const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
if (profile == ContextProfile::OpenGLES) {
return groupInfo.mOpenGLESVersion;
}
return groupInfo.mOpenGLVersion;
}
static inline bool
IsExtensionGroupIsPartOfProfileVersion(GLContext::GLExtensionGroup extensionGroup,
ContextProfile profile, unsigned int version)
{
unsigned int profileVersion = ProfileVersionForExtensionGroup(extensionGroup, profile);
return profileVersion && version >= profileVersion;
}
const char*
GLContext::GetExtensionGroupName(GLExtensionGroup extensionGroup)
{
return GetExtensionGroupInfo(extensionGroup).mName;
}
bool
GLContext::IsExtensionSupported(GLExtensionGroup extensionGroup) const
{
if (IsExtensionGroupIsPartOfProfileVersion(extensionGroup, mProfile, mVersion)) {
return true;
}
const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
for (size_t i = 0; true; i++)
{
MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
if (groupInfo.mExtensions[i] == GLContext::Extensions_End) {
break;
}
if (IsExtensionSupported(groupInfo.mExtensions[i])) {
return true;
}
}
return false;
}
bool
GLContext::MarkExtensionGroupUnsupported(GLExtensionGroup extensionGroup)
{
MOZ_ASSERT(IsExtensionSupported(extensionGroup), "extension group is already unsupported!");
if (IsExtensionGroupIsPartOfProfileVersion(extensionGroup, mProfile, mVersion)) {
NS_WARNING(nsPrintfCString("%s marked as unsupported, but it's supposed to be supported by %s %s",
GetExtensionGroupName(extensionGroup),
ProfileString(),
VersionString()).get());
return false;
}
const ExtensionGroupInfo& groupInfo = GetExtensionGroupInfo(extensionGroup);
for (size_t i = 0; true; i++)
{
MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
if (groupInfo.mExtensions[i] == GLContext::Extensions_End) {
break;
}
MarkExtensionUnsupported(groupInfo.mExtensions[i]);
}
MOZ_ASSERT(!IsExtensionSupported(extensionGroup), "GLContext::MarkExtensionGroupUnsupported has failed!");
NS_WARNING(nsPrintfCString("%s marked as unsupported", GetExtensionGroupName(extensionGroup)).get());
return true;
}
} /* namespace gl */
} /* namespace mozilla */

View File

@ -101,6 +101,7 @@ if gl_provider == 'EGL':
CPP_SOURCES += [
'GLContext.cpp',
'GLContextExtensionGroupQueries.cpp',
'GLContextTypes.cpp',
'GLContextUtils.cpp',
'GLLibraryLoader.cpp',