Bug 684853: implement OES_standard_derivatives

Implemented OES_standard_derivatives and fallbacks if it isn't available. Exposes dFdx, dFdy, and fwidth functions to WebGL scripts.
This commit is contained in:
Doug Sherk 2011-10-01 00:45:50 -04:00
parent f910be0580
commit 6d669bd3c0
12 changed files with 225 additions and 10 deletions

View File

@ -69,6 +69,7 @@ CPPSRCS += \
WebGLContextGL.cpp \ WebGLContextGL.cpp \
WebGLContextUtils.cpp \ WebGLContextUtils.cpp \
WebGLContextValidate.cpp \ WebGLContextValidate.cpp \
WebGLExtensionStandardDerivatives.cpp \
$(NULL) $(NULL)
DEFINES += -DUSE_ANGLE DEFINES += -DUSE_ANGLE

View File

@ -38,6 +38,7 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "WebGLContext.h" #include "WebGLContext.h"
#include "WebGLExtensions.h"
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
@ -941,12 +942,23 @@ WebGLContext::MozGetUnderlyingParamString(PRUint32 pname, nsAString& retval)
bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei) bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
{ {
if (ei == WebGL_OES_texture_float) { bool isSupported;
MakeContextCurrent();
return gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::OES_texture_float switch (ei) {
: GLContext::ARB_texture_float); case WebGL_OES_texture_float:
MakeContextCurrent();
isSupported = gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::OES_texture_float
: GLContext::ARB_texture_float);
break;
case WebGL_OES_standard_derivatives:
// We always support this extension.
isSupported = true;
break;
default:
isSupported = false;
} }
return false;
return isSupported;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -960,12 +972,23 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
if (IsExtensionSupported(WebGL_OES_texture_float)) if (IsExtensionSupported(WebGL_OES_texture_float))
ei = WebGL_OES_texture_float; ei = WebGL_OES_texture_float;
} }
else if (aName.EqualsLiteral("OES_standard_derivatives")) {
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
ei = WebGL_OES_standard_derivatives;
}
// create a WebGLExtension object for extensions that don't
// have any additional tokens or methods
if (ei != WebGLExtensionID_Max) { if (ei != WebGLExtensionID_Max) {
if (!IsExtensionEnabled(ei)) { if (!IsExtensionEnabled(ei)) {
mEnabledExtensions[ei] = new WebGLExtension(this); switch (ei) {
case WebGL_OES_standard_derivatives:
mEnabledExtensions[ei] = new WebGLExtensionStandardDerivatives(this);
break;
// create an extension for any types that don't
// have any additional tokens or methods
default:
mEnabledExtensions[ei] = new WebGLExtension(this);
break;
}
} }
NS_ADDREF(*retval = mEnabledExtensions[ei]); NS_ADDREF(*retval = mEnabledExtensions[ei]);
} }
@ -1209,6 +1232,19 @@ NS_INTERFACE_MAP_BEGIN(WebGLExtension)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtension) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtension)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(WebGLExtensionStandardDerivatives)
NS_IMPL_RELEASE(WebGLExtensionStandardDerivatives)
DOMCI_DATA(WebGLExtensionStandardDerivatives, WebGLExtensionStandardDerivatives)
NS_INTERFACE_MAP_BEGIN(WebGLExtensionStandardDerivatives)
//NS_INTERFACE_MAP_ENTRY(WebGLExtensionStandardDerivatives)
//NS_INTERFACE_MAP_ENTRY(WebGLExtension)
NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionStandardDerivatives)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionStandardDerivatives)
NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
/* readonly attribute WebGLsizei drawingBufferWidth; */ /* readonly attribute WebGLsizei drawingBufferWidth; */
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::GetDrawingBufferWidth(WebGLsizei *aWidth) WebGLContext::GetDrawingBufferWidth(WebGLsizei *aWidth)
@ -1272,6 +1308,8 @@ WebGLContext::GetSupportedExtensions(nsIVariant **retval)
if (IsExtensionSupported(WebGL_OES_texture_float)) if (IsExtensionSupported(WebGL_OES_texture_float))
extList.InsertElementAt(extList.Length(), "OES_texture_float"); extList.InsertElementAt(extList.Length(), "OES_texture_float");
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
extList.InsertElementAt(extList.Length(), "OES_standard_derivatives");
nsresult rv; nsresult rv;
if (extList.Length() > 0) { if (extList.Length() > 0) {

View File

@ -75,6 +75,7 @@ class WebGLShader;
class WebGLFramebuffer; class WebGLFramebuffer;
class WebGLRenderbuffer; class WebGLRenderbuffer;
class WebGLUniformLocation; class WebGLUniformLocation;
class WebGLExtension;
class WebGLZeroingObject; class WebGLZeroingObject;
class WebGLContextBoundObject; class WebGLContextBoundObject;
@ -475,9 +476,10 @@ protected:
// extensions // extensions
enum WebGLExtensionID { enum WebGLExtensionID {
WebGL_OES_texture_float, WebGL_OES_texture_float,
WebGL_OES_standard_derivatives,
WebGLExtensionID_Max WebGLExtensionID_Max
}; };
nsCOMPtr<nsIWebGLExtension> mEnabledExtensions[WebGLExtensionID_Max]; nsCOMPtr<WebGLExtension> mEnabledExtensions[WebGLExtensionID_Max];
bool IsExtensionEnabled(WebGLExtensionID ext) const { bool IsExtensionEnabled(WebGLExtensionID ext) const {
NS_ABORT_IF_FALSE(ext >= 0 && ext < WebGLExtensionID_Max, "bogus index!"); NS_ABORT_IF_FALSE(ext >= 0 && ext < WebGLExtensionID_Max, "bogus index!");
return mEnabledExtensions[ext] != nsnull; return mEnabledExtensions[ext] != nsnull;

View File

@ -1970,6 +1970,15 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
wrval->SetAsInt32(i); wrval->SetAsInt32(i);
} }
break; break;
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
if (mEnabledExtensions[WebGL_OES_standard_derivatives]) {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
wrval->SetAsInt32(i);
}
else
return ErrorInvalidEnum("getParameter: parameter", pname);
break;
case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS: case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
wrval->SetAsInt32(mGLMaxVertexUniformVectors); wrval->SetAsInt32(mGLMaxVertexUniformVectors);
@ -2794,8 +2803,22 @@ WebGLContext::GetVertexAttribOffset(WebGLuint index, WebGLenum pname, WebGLuint
} }
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::Hint(WebGLenum, WebGLenum) WebGLContext::Hint(WebGLenum target, WebGLenum mode)
{ {
bool isValid = false;
switch (target) {
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
if (mEnabledExtensions[WebGL_OES_standard_derivatives])
isValid = true;
break;
}
if (isValid) {
gl->fHint(target, mode);
return NS_OK;
}
return ErrorInvalidEnum("hint: invalid hint"); return ErrorInvalidEnum("hint: invalid hint");
} }
@ -3989,6 +4012,8 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
resources.MaxTextureImageUnits = mGLMaxTextureImageUnits; resources.MaxTextureImageUnits = mGLMaxTextureImageUnits;
resources.MaxFragmentUniformVectors = mGLMaxFragmentUniformVectors; resources.MaxFragmentUniformVectors = mGLMaxFragmentUniformVectors;
resources.MaxDrawBuffers = 1; resources.MaxDrawBuffers = 1;
if (mEnabledExtensions[WebGL_OES_standard_derivatives])
resources.OES_standard_derivatives = 1;
compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(), compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(),
SH_WEBGL_SPEC, SH_WEBGL_SPEC,

View File

@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdarg.h>
#include "WebGLContext.h"
#include "WebGLExtensions.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
WebGLExtensionStandardDerivatives::WebGLExtensionStandardDerivatives(WebGLContext* context) :
WebGLExtension(context)
{
}
WebGLExtensionStandardDerivatives::~WebGLExtensionStandardDerivatives()
{
}

View File

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef WEBGLEXTENSIONS_H_
#define WEBGLEXTENSIONS_H_
namespace mozilla {
class WebGLExtensionStandardDerivatives;
#define WEBGLEXTENSIONSTANDARDDERIVATIVES_PRIVATE_IID \
{0x3de3dfd9, 0x864a, 0x4e4c, {0x98, 0x9b, 0x29, 0x77, 0xea, 0xa8, 0x0b, 0x7b}}
class WebGLExtensionStandardDerivatives :
public nsIWebGLExtensionStandardDerivatives,
public WebGLExtension
{
public:
WebGLExtensionStandardDerivatives(WebGLContext* context);
virtual ~WebGLExtensionStandardDerivatives();
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBGLEXTENSION
NS_DECLARE_STATIC_IID_ACCESSOR(WEBGLEXTENSIONSTANDARDDERIVATIVES_PRIVATE_IID)
};
NS_DEFINE_STATIC_IID_ACCESSOR(WebGLExtensionStandardDerivatives, WEBGLACTIVEINFO_PRIVATE_IID)
}
#endif // WEBGLEXTENSIONS_H_

View File

@ -1449,6 +1449,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLExtension, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(WebGLExtension, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionStandardDerivatives, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(PaintRequest, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(PaintRequest, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -3994,6 +3996,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_BEGIN(WebGLExtension, nsIWebGLExtension) DOM_CLASSINFO_MAP_BEGIN(WebGLExtension, nsIWebGLExtension)
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtension) DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtension)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionStandardDerivatives, nsIWebGLExtensionStandardDerivatives)
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionStandardDerivatives)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(PaintRequest, nsIDOMPaintRequest) DOM_CLASSINFO_MAP_BEGIN(PaintRequest, nsIDOMPaintRequest)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMPaintRequest) DOM_CLASSINFO_MAP_ENTRY(nsIDOMPaintRequest)

View File

@ -475,6 +475,7 @@ DOMCI_CLASS(WebGLRenderbuffer)
DOMCI_CLASS(WebGLUniformLocation) DOMCI_CLASS(WebGLUniformLocation)
DOMCI_CLASS(WebGLActiveInfo) DOMCI_CLASS(WebGLActiveInfo)
DOMCI_CLASS(WebGLExtension) DOMCI_CLASS(WebGLExtension)
DOMCI_CLASS(WebGLExtensionStandardDerivatives)
DOMCI_CLASS(PaintRequest) DOMCI_CLASS(PaintRequest)
DOMCI_CLASS(PaintRequestList) DOMCI_CLASS(PaintRequestList)

View File

@ -139,6 +139,21 @@ interface nsIWebGLExtension : nsISupports
{ {
}; };
/* Classes that extend on nsIWebGLExtension and provide
* extra tokens, functions, etc.
*/
[scriptable, uuid(3de3dfd9-864a-4e4c-989b-2977eaa80b7b)]
interface nsIWebGLExtensionStandardDerivatives : nsIWebGLExtension
{
//
// CONSTANTS
//
/* Fragment shader hint */
const WebGLenum FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
};
[scriptable, uuid(ef15ae85-4670-4dc4-848d-51ca81e8397a)] [scriptable, uuid(ef15ae85-4670-4dc4-848d-51ca81e8397a)]
interface nsIDOMWebGLRenderingContext : nsISupports interface nsIDOMWebGLRenderingContext : nsISupports
{ {

View File

@ -437,6 +437,7 @@ static const char *sExtensionNames[] = {
"GL_OES_texture_float", "GL_OES_texture_float",
"GL_ARB_texture_float", "GL_ARB_texture_float",
"GL_EXT_unpack_subimage", "GL_EXT_unpack_subimage",
"GL_OES_standard_derivatives",
NULL NULL
}; };

View File

@ -981,6 +981,7 @@ public:
OES_texture_float, OES_texture_float,
ARB_texture_float, ARB_texture_float,
EXT_unpack_subimage, EXT_unpack_subimage,
OES_standard_derivatives,
Extensions_Max Extensions_Max
}; };

View File

@ -495,6 +495,7 @@ irregularFilenames = {
'nsIWebGLActiveInfo': 'nsIDOMWebGLRenderingContext', 'nsIWebGLActiveInfo': 'nsIDOMWebGLRenderingContext',
'nsIWebGLUniformLocation': 'nsIDOMWebGLRenderingContext', 'nsIWebGLUniformLocation': 'nsIDOMWebGLRenderingContext',
'nsIWebGLExtension': 'nsIDOMWebGLRenderingContext', 'nsIWebGLExtension': 'nsIDOMWebGLRenderingContext',
'nsIWebGLExtensionStandardDerivatives' : 'nsIDOMWebGLRenderingContext',
'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager', 'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',