bug 899264 - Add OpenGL version and profile support in GLContext - r=jgilbert

This commit is contained in:
Guillaume Abadie 2013-08-01 19:43:27 -04:00
parent f7f1906708
commit d5c2e9336d
6 changed files with 124 additions and 17 deletions

View File

@ -293,7 +293,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
// Load OpenGL ES 2.0 symbols, or desktop if we aren't using ES 2.
if (mInitialized) {
if (mIsGLES2) {
if (IsGLES2()) {
SymLoadStruct symbols_ES2[] = {
{ (PRFuncPtr*) &mSymbols.fGetShaderPrecisionFormat, { "GetShaderPrecisionFormat", nullptr } },
{ (PRFuncPtr*) &mSymbols.fClearDepthf, { "ClearDepthf", nullptr } },
@ -1021,7 +1021,7 @@ GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
// If we're on ES2 hardware and we have an explicit request for 16 bits of color or less
// OR we don't support full 8-bit color, return a 4444 or 565 format.
bool bpp16 = caps.bpp16;
if (mIsGLES2) {
if (IsGLES2()) {
if (!IsExtensionSupported(OES_rgb8_rgba8))
bpp16 = true;
} else {
@ -1031,7 +1031,7 @@ GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
}
if (bpp16) {
MOZ_ASSERT(mIsGLES2);
MOZ_ASSERT(IsGLES2());
if (caps.alpha) {
formats.color_texInternalFormat = LOCAL_GL_RGBA;
formats.color_texFormat = LOCAL_GL_RGBA;
@ -1047,11 +1047,11 @@ GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
formats.color_texType = LOCAL_GL_UNSIGNED_BYTE;
if (caps.alpha) {
formats.color_texInternalFormat = mIsGLES2 ? LOCAL_GL_RGBA : LOCAL_GL_RGBA8;
formats.color_texInternalFormat = IsGLES2() ? LOCAL_GL_RGBA : LOCAL_GL_RGBA8;
formats.color_texFormat = LOCAL_GL_RGBA;
formats.color_rbFormat = LOCAL_GL_RGBA8;
} else {
formats.color_texInternalFormat = mIsGLES2 ? LOCAL_GL_RGB : LOCAL_GL_RGB8;
formats.color_texInternalFormat = IsGLES2() ? LOCAL_GL_RGB : LOCAL_GL_RGB8;
formats.color_texFormat = LOCAL_GL_RGB;
formats.color_rbFormat = LOCAL_GL_RGB8;
}
@ -1070,12 +1070,12 @@ GLContext::ChooseGLFormats(const SurfaceCaps& caps) const
// Be clear that these are 0 if unavailable.
formats.depthStencil = 0;
if (!mIsGLES2 || IsExtensionSupported(OES_packed_depth_stencil)) {
if (!IsGLES2() || IsExtensionSupported(OES_packed_depth_stencil)) {
formats.depthStencil = LOCAL_GL_DEPTH24_STENCIL8;
}
formats.depth = 0;
if (mIsGLES2) {
if (IsGLES2()) {
if (IsExtensionSupported(OES_depth24)) {
formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
} else {
@ -2323,7 +2323,7 @@ GLContext::TexImage2D(GLenum target, GLint level, GLint internalformat,
GLint pixelsize, GLint border, GLenum format,
GLenum type, const GLvoid *pixels)
{
if (mIsGLES2) {
if (IsGLES2()) {
NS_ASSERTION(format == (GLenum)internalformat,
"format and internalformat not the same for glTexImage2D on GLES2");
@ -2430,7 +2430,7 @@ GLContext::TexSubImage2D(GLenum target, GLint level,
GLint pixelsize, GLenum format,
GLenum type, const GLvoid* pixels)
{
if (mIsGLES2) {
if (IsGLES2()) {
if (stride == width * pixelsize) {
fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
std::min(GetAddressAlignment((ptrdiff_t)pixels),

View File

@ -84,6 +84,15 @@ namespace mozilla {
namespace gl {
typedef uintptr_t SharedTextureHandle;
MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t)
Unknown = 0,
OpenGL, // only for IsAtLeast's <profile> parameter
OpenGLCore,
OpenGLCompatibility,
OpenGLES
MOZ_END_ENUM_CLASS(ContextProfile)
class GLContext
: public GLLibraryLoader
, public GenericAtomicRefCounted
@ -140,6 +149,85 @@ public:
return false;
}
/**
* Return true if we are running on a OpenGL core profile context
*/
inline bool IsCoreProfile() const {
MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
return mProfile == ContextProfile::OpenGLCore;
}
/**
* Return true if we are running on a OpenGL compatibility profile context
* (legacy profile 2.1 on Max OS X)
*/
inline bool IsCompatibilityProfile() const {
MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
return mProfile == ContextProfile::OpenGLCompatibility;
}
/**
* Return true if the context is a true OpenGL ES context or an ANGLE context
*/
inline bool IsGLES() const {
MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
return mProfile == ContextProfile::OpenGLES;
}
static const char* GetProfileName(ContextProfile profile)
{
switch (profile)
{
case ContextProfile::OpenGL:
return "OpenGL";
case ContextProfile::OpenGLCore:
return "OpenGL Core";
case ContextProfile::OpenGLCompatibility:
return "OpenGL Compatibility";
case ContextProfile::OpenGLES:
return "OpenGL ES";
default:
break;
}
MOZ_ASSERT(profile != ContextProfile::Unknown, "unknown context profile");
return "OpenGL unknown profile";
}
/**
* Return true if the context is compatible with given parameters
*
* IsAtLeast(ContextProfile::OpenGL, N) is exactly same as
* IsAtLeast(ContextProfile::OpenGLCore, N) || IsAtLeast(ContextProfile::OpenGLCompatibility, N)
*/
inline bool IsAtLeast(ContextProfile profile, unsigned int version) const
{
MOZ_ASSERT(profile != ContextProfile::Unknown, "IsAtLeast: bad <profile> parameter");
MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
MOZ_ASSERT(mVersion != 0, "unknown context version");
if (profile == ContextProfile::OpenGL) {
return (profile == ContextProfile::OpenGLCore ||
profile == ContextProfile::OpenGLCompatibility) &&
version >= mVersion;
}
return profile == mProfile &&
version >= mVersion;
}
/**
* Return the version of the context.
* Example :
* If this a OpenGL 2.1, that will return 210
*/
inline unsigned int Version() const {
return mVersion;
}
int Vendor() const {
return mVendor;
}
@ -171,7 +259,7 @@ public:
* extensions).
*/
inline bool IsGLES2() const {
return mIsGLES2;
return IsAtLeast(ContextProfile::OpenGLES, 200);
}
/**
@ -189,14 +277,24 @@ protected:
bool mIsOffscreen;
bool mIsGlobalSharedContext;
bool mContextLost;
bool mIsGLES2;
/**
* mVersion store the OpenGL's version, multiplied by 100. For example, if
* the context is an OpenGL 2.1 context, mVersion value will be 210.
*/
unsigned int mVersion;
ContextProfile mProfile;
int32_t mVendor;
int32_t mRenderer;
inline void SetIsGLES2(bool isGLES2) {
MOZ_ASSERT(!mInitialized, "SetIsGLES2 can only be called before initialization!");
mIsGLES2 = isGLES2;
inline void SetProfileVersion(ContextProfile profile, unsigned int version) {
MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before initialization!");
MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion");
MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion");
mVersion = version;
mProfile = profile;
}
@ -2119,7 +2217,8 @@ protected:
mIsOffscreen(isOffscreen),
mIsGlobalSharedContext(false),
mContextLost(false),
mIsGLES2(false),
mVersion(0),
mProfile(ContextProfile::Unknown),
mVendor(-1),
mRenderer(-1),
mHasRobustness(false),

View File

@ -94,7 +94,9 @@ public:
: GLContext(caps, shareContext, isOffscreen),
mContext(context),
mTempTextureName(0)
{}
{
SetProfileVersion(ContextProfile::OpenGLCompatibility, 210);
}
~GLContextCGL()
{

View File

@ -270,7 +270,7 @@ public:
, mTemporaryEGLImageTexture(0)
{
// any EGL contexts will always be GLESv2
SetIsGLES2(true);
SetProfileVersion(ContextProfile::OpenGLES, 200);
#ifdef DEBUG
printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());

View File

@ -966,6 +966,8 @@ private:
mPixmap(aPixmap)
{
MOZ_ASSERT(mGLX);
// See 899855
SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
}
GLXContext mContext;

View File

@ -272,6 +272,8 @@ public:
mLibType(aLibUsed),
mIsDoubleBuffered(false)
{
// See 899855
SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
}
// From PBuffer
@ -292,6 +294,8 @@ public:
mLibType(aLibUsed),
mIsDoubleBuffered(false)
{
// See 899855
SetProfileVersion(ContextProfile::OpenGLCompatibility, 200);
}
~GLContextWGL()