Bug 708207: implement WebGL's getShaderPrecisionFormat r=bjacob

This commit is contained in:
Doug Sherk 2011-12-16 13:11:59 -08:00
Родитель d1ee0713dc
Коммит 573bfdbe9c
12 изменённых файлов: 167 добавлений и 2 удалений

Просмотреть файл

@ -1285,6 +1285,17 @@ NS_INTERFACE_MAP_BEGIN(WebGLUniformLocation)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLUniformLocation)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(WebGLShaderPrecisionFormat)
NS_IMPL_RELEASE(WebGLShaderPrecisionFormat)
DOMCI_DATA(WebGLShaderPrecisionFormat, WebGLShaderPrecisionFormat)
NS_INTERFACE_MAP_BEGIN(WebGLShaderPrecisionFormat)
NS_INTERFACE_MAP_ENTRY(nsIWebGLShaderPrecisionFormat)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLShaderPrecisionFormat)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(WebGLActiveInfo)
NS_IMPL_RELEASE(WebGLActiveInfo)
@ -1401,6 +1412,30 @@ WebGLActiveInfo::GetName(nsAString & aName)
return NS_OK;
}
/* readonly attribute WebGLint rangeMin */
NS_IMETHODIMP
WebGLShaderPrecisionFormat::GetRangeMin(WebGLint *aRangeMin)
{
*aRangeMin = mRangeMin;
return NS_OK;
}
/* readonly attribute WebGLint rangeMax */
NS_IMETHODIMP
WebGLShaderPrecisionFormat::GetRangeMax(WebGLint *aRangeMax)
{
*aRangeMax = mRangeMax;
return NS_OK;
}
/* readonly attribute WebGLint precision */
NS_IMETHODIMP
WebGLShaderPrecisionFormat::GetPrecision(WebGLint *aPrecision)
{
*aPrecision = mPrecision;
return NS_OK;
}
NS_IMETHODIMP
WebGLContext::GetSupportedExtensions(nsIVariant **retval)
{

Просмотреть файл

@ -2300,6 +2300,27 @@ protected:
nsString mName;
};
class WebGLShaderPrecisionFormat
: public nsIWebGLShaderPrecisionFormat
{
public:
WebGLShaderPrecisionFormat(WebGLint rangeMin, WebGLint rangeMax, WebGLint precision) :
mRangeMin(rangeMin),
mRangeMax(rangeMax),
mPrecision(precision)
{
}
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBGLSHADERPRECISIONFORMAT
protected:
WebGLint mRangeMin;
WebGLint mRangeMax;
WebGLint mPrecision;
};
class WebGLExtension
: public nsIWebGLExtension
, public WebGLContextBoundObject

Просмотреть файл

@ -4540,6 +4540,45 @@ WebGLContext::GetShaderInfoLog(nsIWebGLShader *sobj, nsAString& retval)
return NS_OK;
}
NS_IMETHODIMP
WebGLContext::GetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype, nsIWebGLShaderPrecisionFormat **retval)
{
*retval = nsnull;
if (mContextLost)
return NS_OK;
switch (shadertype) {
case LOCAL_GL_FRAGMENT_SHADER:
case LOCAL_GL_VERTEX_SHADER:
break;
default:
return ErrorInvalidEnumInfo("getShaderPrecisionFormat: shadertype", shadertype);
}
switch (precisiontype) {
case LOCAL_GL_LOW_FLOAT:
case LOCAL_GL_MEDIUM_FLOAT:
case LOCAL_GL_HIGH_FLOAT:
case LOCAL_GL_LOW_INT:
case LOCAL_GL_MEDIUM_INT:
case LOCAL_GL_HIGH_INT:
break;
default:
return ErrorInvalidEnumInfo("getShaderPrecisionFormat: precisiontype", precisiontype);
}
MakeContextCurrent();
GLint range[2], precision;
gl->fGetShaderPrecisionFormat(shadertype, precisiontype, range, &precision);
WebGLShaderPrecisionFormat *retShaderPrecisionFormat
= new WebGLShaderPrecisionFormat(range[0], range[1], precision);
NS_ADDREF(*retval = retShaderPrecisionFormat);
return NS_OK;
}
NS_IMETHODIMP
WebGLContext::GetShaderSource(nsIWebGLShader *sobj, nsAString& retval)
{

Просмотреть файл

@ -51,6 +51,7 @@ DOMCI_DATA(WebGLShader, void)
DOMCI_DATA(WebGLFramebuffer, void)
DOMCI_DATA(WebGLRenderbuffer, void)
DOMCI_DATA(WebGLUniformLocation, void)
DOMCI_DATA(WebGLShaderPrecisionFormat, void)
DOMCI_DATA(WebGLActiveInfo, void)
DOMCI_DATA(WebGLExtension, void)
DOMCI_DATA(WebGLExtensionStandardDerivatives, void)

Просмотреть файл

@ -1465,6 +1465,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLUniformLocation, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLShaderPrecisionFormat, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLActiveInfo, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLExtension, nsDOMGenericSH,
@ -4048,6 +4050,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLRenderbuffer)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(WebGLShaderPrecisionFormat, nsIWebGLShaderPrecisionFormat)
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLShaderPrecisionFormat)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(WebGLUniformLocation, nsIWebGLUniformLocation)
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLUniformLocation)
DOM_CLASSINFO_MAP_END

Просмотреть файл

@ -474,6 +474,7 @@ DOMCI_CLASS(WebGLShader)
DOMCI_CLASS(WebGLFramebuffer)
DOMCI_CLASS(WebGLRenderbuffer)
DOMCI_CLASS(WebGLUniformLocation)
DOMCI_CLASS(WebGLShaderPrecisionFormat)
DOMCI_CLASS(WebGLActiveInfo)
DOMCI_CLASS(WebGLExtension)
DOMCI_CLASS(WebGLExtensionStandardDerivatives)

Просмотреть файл

@ -125,6 +125,14 @@ interface nsIWebGLActiveInfo : nsISupports
readonly attribute DOMString name;
};
[scriptable, builtinclass, uuid(76265e93-2e8f-40ca-b25b-eea5995e9641)]
interface nsIWebGLShaderPrecisionFormat : nsISupports
{
readonly attribute WebGLint rangeMin;
readonly attribute WebGLint rangeMax;
readonly attribute WebGLint precision;
};
[scriptable, builtinclass, uuid(d38b0467-623e-4c82-9140-5f14a3bd1bad)]
interface nsIWebGLUniformLocation : nsISupports
{
@ -700,8 +708,7 @@ interface nsIDOMWebGLRenderingContext : nsISupports
// Modified: void glGetShaderInfoLog(WebGLuint shader, WebGLsizei bufsize, WebGLsizei* length, char* infolog);
DOMString getShaderInfoLog(in nsIWebGLShader shader);
// TBD
//void glGetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype, WebGLint* range, WebGLint* precision);
nsIWebGLShaderPrecisionFormat getShaderPrecisionFormat(in WebGLenum shadertype, in WebGLenum precisiontype);
DOMString getShaderSource(in nsIWebGLShader shader);

Просмотреть файл

@ -404,6 +404,18 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
#endif
// Specially load this in because it's placed in a bizarre position in
// the ES2 symbol table (between shaderInfoLog and shaderSource).
SymLoadStruct symbols_shaderPrecisionFormat[] = {
{ (PRFuncPtr*) &mSymbols.fGetShaderPrecisionFormat, { "GetShaderPrecisionFormat", NULL } },
{ NULL, { NULL } },
};
if (mIsGLES2 && !LoadSymbols(&symbols_shaderPrecisionFormat[0], trygl, prefix)) {
NS_RUNTIMEABORT("OpenGL ES 2.0 supported, but has no GetShaderPrecisionFormat symbol.");
mInitialized = false;
}
InitExtensions();
NS_ASSERTION(!IsExtensionSupported(GLContext::ARB_pixel_buffer_object) ||

Просмотреть файл

@ -881,6 +881,28 @@ private:
GLuint mPrevReadFBOBinding;
bool mOffscreenFBOsDirty;
void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
switch (precisiontype) {
case LOCAL_GL_LOW_FLOAT:
case LOCAL_GL_MEDIUM_FLOAT:
case LOCAL_GL_HIGH_FLOAT:
// Assume IEEE 754 precision
range[0] = 127;
range[1] = 127;
*precision = 0;
break;
case LOCAL_GL_LOW_INT:
case LOCAL_GL_MEDIUM_INT:
case LOCAL_GL_HIGH_INT:
// Some (most) hardware only supports single-precision floating-point numbers,
// which can accurately represent integers up to +/-16777216
range[0] = 24;
range[1] = 24;
*precision = 0;
break;
}
}
void BeforeGLDrawCall() {
// Record and rebind if necessary
mPrevDrawFBOBinding = GetBoundDrawFBO();
@ -2331,6 +2353,17 @@ public:
AFTER_GL_CALL;
}
void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
BEFORE_GL_CALL;
if (mIsGLES2) {
mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
} else {
// Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions.
GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision);
}
AFTER_GL_CALL;
}
void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) {
BEFORE_GL_CALL;
mSymbols.fGetShaderSource(obj, maxLength, length, source);

Просмотреть файл

@ -281,6 +281,8 @@ struct GLContextSymbols
PFNGLGETSHADERIVPROC fGetShaderiv;
typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
PFNGLGETSHADERINFOLOGPROC fGetShaderInfoLog;
typedef void (GLAPIENTRY * PFNGETSHADERPRECISIONFORMAT) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
PFNGETSHADERPRECISIONFORMAT fGetShaderPrecisionFormat;
typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source);
PFNGLGETSHADERSOURCEPROC fGetShaderSource;
typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths);

Просмотреть файл

@ -3042,6 +3042,13 @@ typedef ptrdiff_t GLintptr;
#define LOCAL_GL_MAX_SAMPLES 0x8D57
#define LOCAL_GL_LOW_FLOAT 0x8DF0
#define LOCAL_GL_MEDIUM_FLOAT 0x8DF1
#define LOCAL_GL_HIGH_FLOAT 0x8DF2
#define LOCAL_GL_LOW_INT 0x8DF3
#define LOCAL_GL_MEDIUM_INT 0x8DF4
#define LOCAL_GL_HIGH_INT 0x8DF5
#define LOCAL_GL_GUILTY_CONTEXT_RESET_ARB 0x8253
#define LOCAL_GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
#define LOCAL_GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255

Просмотреть файл

@ -473,6 +473,7 @@ irregularFilenames = {
'nsIWebGLShaderArray': 'nsIDOMWebGLRenderingContext',
'nsIWebGLFramebuffer': 'nsIDOMWebGLRenderingContext',
'nsIWebGLRenderbuffer': 'nsIDOMWebGLRenderingContext',
'nsIWebGLShaderPrecisionFormat' : 'nsIDOMWebGLRenderingContext',
'nsIWebGLActiveInfo': 'nsIDOMWebGLRenderingContext',
'nsIWebGLUniformLocation': 'nsIDOMWebGLRenderingContext',
'nsIWebGLExtension': 'nsIDOMWebGLRenderingContext',