Bug 656824: Implemented ARB_robustness to detect driver resets in WebGL, only on GLX for now - r=bjacob

This patch implements ARB_robustness on GLX and allows scripts to handle driver resets
through events. The changes in this patch are very sweeping; they hit almost
every NS_IMETHODIMP function within WebGLContextGL.cpp and WebGLContext.cpp.
More work must be done on this to support EGL_CONTEXT_LOST.
This commit is contained in:
Doug Sherk 2011-10-26 16:00:44 -04:00
Родитель f8179e8309
Коммит 942467690c
17 изменённых файлов: 844 добавлений и 11 удалений

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

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

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

@ -298,12 +298,19 @@ WebGLContext::WebGLContext()
mPixelStoreUnpackAlignment = 4; mPixelStoreUnpackAlignment = 4;
WebGLMemoryReporter::AddWebGLContext(this); WebGLMemoryReporter::AddWebGLContext(this);
mContextLost = false;
mAllowRestore = false;
} }
WebGLContext::~WebGLContext() WebGLContext::~WebGLContext()
{ {
DestroyResourcesAndContext(); DestroyResourcesAndContext();
WebGLMemoryReporter::RemoveWebGLContext(this); WebGLMemoryReporter::RemoveWebGLContext(this);
if (mContextRestorer) {
mContextRestorer->Cancel();
mContextRestorer = NULL;
}
} }
static PLDHashOperator static PLDHashOperator
@ -822,6 +829,9 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
CanvasLayer *aOldLayer, CanvasLayer *aOldLayer,
LayerManager *aManager) LayerManager *aManager)
{ {
if (mContextLost)
return nsnull;
if (!mResetLayer && aOldLayer && if (!mResetLayer && aOldLayer &&
aOldLayer->HasUserData(&gWebGLLayerUserData)) { aOldLayer->HasUserData(&gWebGLLayerUserData)) {
NS_ADDREF(aOldLayer); NS_ADDREF(aOldLayer);
@ -885,6 +895,12 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::GetContextAttributes(jsval *aResult) WebGLContext::GetContextAttributes(jsval *aResult)
{ {
if (mContextLost)
{
*aResult = OBJECT_TO_JSVAL(NULL);
return NS_OK;
}
JSContext *cx = nsContentUtils::GetCurrentJSContext(); JSContext *cx = nsContentUtils::GetCurrentJSContext();
if (!cx) if (!cx)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -923,6 +939,9 @@ WebGLContext::GetContextAttributes(jsval *aResult)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::MozGetUnderlyingParamString(PRUint32 pname, nsAString& retval) WebGLContext::MozGetUnderlyingParamString(PRUint32 pname, nsAString& retval)
{ {
if (mContextLost)
return NS_OK;
retval.SetIsVoid(true); retval.SetIsVoid(true);
MakeContextCurrent(); MakeContextCurrent();
@ -959,6 +978,10 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
// We always support this extension. // We always support this extension.
isSupported = true; isSupported = true;
break; break;
case WebGL_WEBKIT_lose_context:
// We always support this extension.
isSupported = true;
break;
default: default:
isSupported = false; isSupported = false;
} }
@ -970,6 +993,8 @@ NS_IMETHODIMP
WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval) WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
{ {
*retval = nsnull; *retval = nsnull;
if (mContextLost)
return NS_OK;
if (mDisableExtensions) { if (mDisableExtensions) {
return NS_OK; return NS_OK;
@ -985,6 +1010,10 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
if (IsExtensionSupported(WebGL_OES_standard_derivatives)) if (IsExtensionSupported(WebGL_OES_standard_derivatives))
ei = WebGL_OES_standard_derivatives; ei = WebGL_OES_standard_derivatives;
} }
else if (aName.EqualsLiteral("WEBKIT_lose_context")) {
if (IsExtensionSupported(WebGL_WEBKIT_lose_context))
ei = WebGL_WEBKIT_lose_context;
}
if (ei != WebGLExtensionID_Max) { if (ei != WebGLExtensionID_Max) {
if (!IsExtensionEnabled(ei)) { if (!IsExtensionEnabled(ei)) {
@ -992,6 +1021,9 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
case WebGL_OES_standard_derivatives: case WebGL_OES_standard_derivatives:
mEnabledExtensions[ei] = new WebGLExtensionStandardDerivatives(this); mEnabledExtensions[ei] = new WebGLExtensionStandardDerivatives(this);
break; break;
case WebGL_WEBKIT_lose_context:
mEnabledExtensions[ei] = new WebGLExtensionLoseContext(this);
break;
// create an extension for any types that don't // create an extension for any types that don't
// have any additional tokens or methods // have any additional tokens or methods
default: default:
@ -1095,6 +1127,86 @@ WebGLContext::EnsureBackbufferClearedAsNeeded()
Invalidate(); Invalidate();
} }
NS_IMETHODIMP
WebGLContext::Notify(nsITimer* timer)
{
MaybeRestoreContext();
if (mContextRestorer) {
mContextRestorer->Cancel();
mContextRestorer = NULL;
}
return NS_OK;
}
void
WebGLContext::MaybeRestoreContext()
{
if (mContextLost || mAllowRestore)
return;
GLContext::ContextResetARB resetStatus =
(GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
if (resetStatus != GLContext::CONTEXT_NO_ERROR) {
// It's already lost, but clean up after it and signal to JS that it is
// lost.
ForceLoseContext();
}
switch (resetStatus) {
case GLContext::CONTEXT_NO_ERROR:
return;
case GLContext::CONTEXT_GUILTY_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page caused the graphics card to reset; not restoring the context");
return;
case GLContext::CONTEXT_INNOCENT_CONTEXT_RESET_ARB:
break;
case GLContext::CONTEXT_UNKNOWN_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page might have caused the graphics card to reset");
break;
}
ForceRestoreContext();
}
void
WebGLContext::ForceLoseContext()
{
if (mContextRestorer) {
mContextRestorer->Cancel();
mContextRestorer = NULL;
}
mWebGLError = LOCAL_GL_CONTEXT_LOST;
bool defaultAction;
mContextLost = true;
DestroyResourcesAndContext();
nsContentUtils::DispatchTrustedEvent(HTMLCanvasElement()->OwnerDoc(),
(nsIDOMHTMLCanvasElement*) HTMLCanvasElement(),
NS_LITERAL_STRING("webglcontextlost"),
PR_TRUE,
PR_TRUE,
&defaultAction);
if (defaultAction)
mAllowRestore = false;
}
void
WebGLContext::ForceRestoreContext()
{
mContextLost = false;
mAllowRestore = false;
SetDimensions(mHeight, mWidth);
nsContentUtils::DispatchTrustedEvent(HTMLCanvasElement()->OwnerDoc(),
(nsIDOMHTMLCanvasElement*) HTMLCanvasElement(),
NS_LITERAL_STRING("webglcontextrestored"),
PR_TRUE,
PR_TRUE);
}
// //
// XPCOM goop // XPCOM goop
// //
@ -1116,6 +1228,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
NS_INTERFACE_MAP_ENTRY(nsIDOMWebGLRenderingContext) NS_INTERFACE_MAP_ENTRY(nsIDOMWebGLRenderingContext)
NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal) NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWebGLRenderingContext) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWebGLRenderingContext)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLRenderingContext) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLRenderingContext)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
@ -1254,10 +1367,24 @@ NS_INTERFACE_MAP_BEGIN(WebGLExtensionStandardDerivatives)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionStandardDerivatives) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionStandardDerivatives)
NS_INTERFACE_MAP_END_INHERITING(WebGLExtension) NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
NS_IMPL_ADDREF(WebGLExtensionLoseContext)
NS_IMPL_RELEASE(WebGLExtensionLoseContext)
DOMCI_DATA(WebGLExtensionLoseContext, WebGLExtensionLoseContext)
NS_INTERFACE_MAP_BEGIN(WebGLExtensionLoseContext)
NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionLoseContext)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionLoseContext)
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)
{ {
if (mContextLost)
return NS_OK;
*aWidth = mWidth; *aWidth = mWidth;
return NS_OK; return NS_OK;
} }
@ -1266,6 +1393,9 @@ WebGLContext::GetDrawingBufferWidth(WebGLsizei *aWidth)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::GetDrawingBufferHeight(WebGLsizei *aHeight) WebGLContext::GetDrawingBufferHeight(WebGLsizei *aHeight)
{ {
if (mContextLost)
return NS_OK;
*aHeight = mHeight; *aHeight = mHeight;
return NS_OK; return NS_OK;
} }
@ -1311,6 +1441,8 @@ NS_IMETHODIMP
WebGLContext::GetSupportedExtensions(nsIVariant **retval) WebGLContext::GetSupportedExtensions(nsIVariant **retval)
{ {
*retval = nsnull; *retval = nsnull;
if (mContextLost)
return NS_OK;
if (mDisableExtensions) { if (mDisableExtensions) {
return NS_OK; return NS_OK;
@ -1343,7 +1475,7 @@ WebGLContext::GetSupportedExtensions(nsIVariant **retval)
NS_IMETHODIMP NS_IMETHODIMP
WebGLContext::IsContextLost(WebGLboolean *retval) WebGLContext::IsContextLost(WebGLboolean *retval)
{ {
*retval = false; *retval = mContextLost;
return NS_OK; return NS_OK;
} }

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

@ -339,9 +339,11 @@ struct WebGLContextOptions {
class WebGLContext : class WebGLContext :
public nsIDOMWebGLRenderingContext, public nsIDOMWebGLRenderingContext,
public nsICanvasRenderingContextInternal, public nsICanvasRenderingContextInternal,
public nsSupportsWeakReference public nsSupportsWeakReference,
public nsITimerCallback
{ {
friend class WebGLMemoryReporter; friend class WebGLMemoryReporter;
friend class WebGLExtensionLoseContext;
public: public:
WebGLContext(); WebGLContext();
@ -353,6 +355,8 @@ public:
NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
NS_DECL_NSITIMERCALLBACK
// nsICanvasRenderingContextInternal // nsICanvasRenderingContextInternal
NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas); NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height); NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
@ -380,6 +384,9 @@ public:
PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h) PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h)
{ return NS_ERROR_NOT_IMPLEMENTED; } { return NS_ERROR_NOT_IMPLEMENTED; }
bool LoseContext();
bool RestoreContext();
nsresult SynthesizeGLError(WebGLenum err); nsresult SynthesizeGLError(WebGLenum err);
nsresult SynthesizeGLError(WebGLenum err, const char *fmt, ...); nsresult SynthesizeGLError(WebGLenum err, const char *fmt, ...);
@ -438,6 +445,22 @@ public:
return mMinCapability; return mMinCapability;
} }
// Sets up the GL_ARB_robustness timer if it isn't already, so that if the
// driver gets restarted, the context may get reset with it.
void SetupRobustnessTimer() {
if (mContextLost)
return;
if (!mContextRestorer)
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
// As long as there's still activity, we reset the timer each time that
// this function gets called.
mContextRestorer->InitWithCallback(static_cast<nsITimerCallback*>(this),
PR_MillisecondsToInterval(1000),
nsITimer::TYPE_ONE_SHOT);
}
protected: protected:
void SetDontKnowIfNeedFakeBlack() { void SetDontKnowIfNeedFakeBlack() {
mFakeBlackStatus = DontKnowIfNeedFakeBlack; mFakeBlackStatus = DontKnowIfNeedFakeBlack;
@ -502,6 +525,7 @@ protected:
enum WebGLExtensionID { enum WebGLExtensionID {
WebGL_OES_texture_float, WebGL_OES_texture_float,
WebGL_OES_standard_derivatives, WebGL_OES_standard_derivatives,
WebGL_WEBKIT_lose_context,
WebGLExtensionID_Max WebGLExtensionID_Max
}; };
nsCOMPtr<WebGLExtension> mEnabledExtensions[WebGLExtensionID_Max]; nsCOMPtr<WebGLExtension> mEnabledExtensions[WebGLExtensionID_Max];
@ -633,6 +657,10 @@ protected:
GLenum type, GLenum type,
const GLvoid *data); const GLvoid *data);
void MaybeRestoreContext();
void ForceLoseContext();
void ForceRestoreContext();
// the buffers bound to the current program's attribs // the buffers bound to the current program's attribs
nsTArray<WebGLVertexAttribData> mAttribBuffers; nsTArray<WebGLVertexAttribData> mAttribBuffers;
@ -691,6 +719,10 @@ protected:
int mBackbufferClearingStatus; int mBackbufferClearingStatus;
nsCOMPtr<nsITimer> mContextRestorer;
bool mContextLost;
bool mAllowRestore;
public: public:
// console logging helpers // console logging helpers
static void LogMessage(const char *fmt, ...); static void LogMessage(const char *fmt, ...);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -53,3 +53,4 @@ DOMCI_DATA(WebGLRenderbuffer, void)
DOMCI_DATA(WebGLUniformLocation, void) DOMCI_DATA(WebGLUniformLocation, void)
DOMCI_DATA(WebGLActiveInfo, void) DOMCI_DATA(WebGLActiveInfo, void)
DOMCI_DATA(WebGLExtension, void) DOMCI_DATA(WebGLExtension, void)
DOMCI_DATA(WebGLExtensionLoseContext, void)

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

@ -0,0 +1,76 @@
/* -*- 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 Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Doug Sherk <dsherk@mozilla.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;
WebGLExtensionLoseContext::WebGLExtensionLoseContext(WebGLContext* context) :
WebGLExtension(context)
{
}
WebGLExtensionLoseContext::~WebGLExtensionLoseContext()
{
}
NS_IMETHODIMP
WebGLExtensionLoseContext::LoseContext()
{
if (!mContext->LoseContext())
return mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
return NS_OK;
}
NS_IMETHODIMP
WebGLExtensionLoseContext::RestoreContext()
{
if (!mContext->RestoreContext())
return mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
return NS_OK;
}

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

@ -41,8 +41,27 @@
namespace mozilla { namespace mozilla {
class WebGLExtensionLoseContext;
class WebGLExtensionStandardDerivatives; class WebGLExtensionStandardDerivatives;
#define WEBGLEXTENSIONLOSECONTEXT_PRIVATE_IID \
{0xb0afc2eb, 0x0895, 0x4509, {0x98, 0xde, 0x5c, 0x38, 0x3d, 0x16, 0x06, 0x94}}
class WebGLExtensionLoseContext :
public nsIWebGLExtensionLoseContext,
public WebGLExtension
{
public:
WebGLExtensionLoseContext(WebGLContext*);
virtual ~WebGLExtensionLoseContext();
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBGLEXTENSIONLOSECONTEXT
NS_DECLARE_STATIC_IID_ACCESSOR(WEBGLEXTENSIONLOSECONTEXT_PRIVATE_IID)
};
NS_DEFINE_STATIC_IID_ACCESSOR(WebGLExtensionLoseContext, WEBGLACTIVEINFO_PRIVATE_IID)
#define WEBGLEXTENSIONSTANDARDDERIVATIVES_PRIVATE_IID \ #define WEBGLEXTENSIONSTANDARDDERIVATIVES_PRIVATE_IID \
{0x3de3dfd9, 0x864a, 0x4e4c, {0x98, 0x9b, 0x29, 0x77, 0xea, 0xa8, 0x0b, 0x7b}} {0x3de3dfd9, 0x864a, 0x4e4c, {0x98, 0x9b, 0x29, 0x77, 0xea, 0xa8, 0x0b, 0x7b}}
class WebGLExtensionStandardDerivatives : class WebGLExtensionStandardDerivatives :

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

@ -1450,6 +1450,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionStandardDerivatives, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(WebGLExtensionStandardDerivatives, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionLoseContext, 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)
@ -3986,6 +3988,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionStandardDerivatives) DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionStandardDerivatives)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(WebGLExtensionLoseContext, nsIWebGLExtensionLoseContext)
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionLoseContext)
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)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END

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

@ -472,6 +472,7 @@ DOMCI_CLASS(WebGLUniformLocation)
DOMCI_CLASS(WebGLActiveInfo) DOMCI_CLASS(WebGLActiveInfo)
DOMCI_CLASS(WebGLExtension) DOMCI_CLASS(WebGLExtension)
DOMCI_CLASS(WebGLExtensionStandardDerivatives) DOMCI_CLASS(WebGLExtensionStandardDerivatives)
DOMCI_CLASS(WebGLExtensionLoseContext)
DOMCI_CLASS(PaintRequest) DOMCI_CLASS(PaintRequest)
DOMCI_CLASS(PaintRequestList) DOMCI_CLASS(PaintRequestList)

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

@ -153,6 +153,12 @@ interface nsIWebGLExtensionStandardDerivatives : nsIWebGLExtension
const WebGLenum FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B; const WebGLenum FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
}; };
[scriptable, uuid(b0afc2eb-0895-4509-98de-5c383d160694)]
interface nsIWebGLExtensionLoseContext : nsIWebGLExtension
{
void loseContext();
void restoreContext();
};
[scriptable, builtinclass, uuid(ef15ae85-4670-4dc4-848d-51ca81e8397a)] [scriptable, builtinclass, uuid(ef15ae85-4670-4dc4-848d-51ca81e8397a)]
interface nsIDOMWebGLRenderingContext : nsISupports interface nsIDOMWebGLRenderingContext : nsISupports

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

@ -174,6 +174,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
return true; return true;
} }
mHasRobustness = IsExtensionSupported(ARB_robustness);
SymLoadStruct symbols[] = { SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &mSymbols.fActiveTexture, { "ActiveTexture", "ActiveTextureARB", NULL } }, { (PRFuncPtr*) &mSymbols.fActiveTexture, { "ActiveTexture", "ActiveTextureARB", NULL } },
{ (PRFuncPtr*) &mSymbols.fAttachShader, { "AttachShader", "AttachShaderARB", NULL } }, { (PRFuncPtr*) &mSymbols.fAttachShader, { "AttachShader", "AttachShaderARB", NULL } },
@ -325,6 +327,9 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
{ mIsGLES2 ? (PRFuncPtr*) NULL : (PRFuncPtr*) &mSymbols.fUnmapBuffer, { mIsGLES2 ? (PRFuncPtr*) NULL : (PRFuncPtr*) &mSymbols.fUnmapBuffer,
{ mIsGLES2 ? NULL : "UnmapBuffer", NULL } }, { mIsGLES2 ? NULL : "UnmapBuffer", NULL } },
{ mHasRobustness ? (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus : (PRFuncPtr*) NULL,
{ mHasRobustness ? "GetGraphicsResetStatusARB" : NULL, NULL } },
{ NULL, { NULL } }, { NULL, { NULL } },
}; };
@ -470,6 +475,7 @@ static const char *sExtensionNames[] = {
"GL_EXT_framebuffer_multisample", "GL_EXT_framebuffer_multisample",
"GL_ANGLE_framebuffer_multisample", "GL_ANGLE_framebuffer_multisample",
"GL_OES_rgb8_rgba8", "GL_OES_rgb8_rgba8",
"GL_ARB_robustness",
NULL NULL
}; };

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

@ -1242,6 +1242,7 @@ public:
EXT_framebuffer_multisample, EXT_framebuffer_multisample,
ANGLE_framebuffer_multisample, ANGLE_framebuffer_multisample,
OES_rgb8_rgba8, OES_rgb8_rgba8,
ARB_robustness,
Extensions_Max Extensions_Max
}; };
@ -1278,11 +1279,24 @@ public:
bool values[setlen]; bool values[setlen];
}; };
/**
* Context reset constants.
* These are used to determine who is guilty when a context reset
* happens.
*/
enum ContextResetARB {
CONTEXT_NO_ERROR = 0,
CONTEXT_GUILTY_CONTEXT_RESET_ARB = 0x8253,
CONTEXT_INNOCENT_CONTEXT_RESET_ARB = 0x8254,
CONTEXT_UNKNOWN_CONTEXT_RESET_ARB = 0x8255,
};
protected: protected:
bool mInitialized; bool mInitialized;
bool mIsOffscreen; bool mIsOffscreen;
bool mIsGLES2; bool mIsGLES2;
bool mIsGlobalSharedContext; bool mIsGlobalSharedContext;
bool mHasRobustness;
PRInt32 mVendor; PRInt32 mVendor;
@ -2498,6 +2512,14 @@ public:
AFTER_GL_CALL; AFTER_GL_CALL;
TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names)); TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
} }
GLenum GLAPIENTRY fGetGraphicsResetStatus() {
BEFORE_GL_CALL;
GLenum ret = mHasRobustness ? mSymbols.fGetGraphicsResetStatus() : 0;
AFTER_GL_CALL;
return ret;
}
#ifdef DEBUG #ifdef DEBUG
void THEBES_API CreatedProgram(GLContext *aOrigin, GLuint aName); void THEBES_API CreatedProgram(GLContext *aOrigin, GLuint aName);
void THEBES_API CreatedShader(GLContext *aOrigin, GLuint aName); void THEBES_API CreatedShader(GLContext *aOrigin, GLuint aName);

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

@ -183,6 +183,11 @@ GLXLibrary::EnsureInitialized()
{ NULL, { NULL } } { NULL, { NULL } }
}; };
LibrarySymbolLoader::SymLoadStruct symbols_robustness[] = {
{ (PRFuncPtr*) &xCreateContextAttribsInternal, { "glXCreateContextAttribsARB", NULL } },
{ NULL, { NULL } }
};
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) { if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
NS_WARNING("Couldn't find required entry point in OpenGL shared library"); NS_WARNING("Couldn't find required entry point in OpenGL shared library");
return false; return false;
@ -251,6 +256,17 @@ GLXLibrary::EnsureInitialized()
NS_WARNING("Texture from pixmap disabled"); NS_WARNING("Texture from pixmap disabled");
} }
if (HasExtension(extensionsStr, "GL_ARB_robustness")) {
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) {
// We have no easy way of checking whether or not this extension
// exists, so it's best to just try to load it and accept that it
// might fail.
//NS_WARNING("Couldn't load ARB_robustness symbols");
} else {
mHasRobustness = true;
}
}
gIsATI = serverVendor && DoesVendorStringMatch(serverVendor, "ATI"); gIsATI = serverVendor && DoesVendorStringMatch(serverVendor, "ATI");
gIsChromium = (serverVendor && gIsChromium = (serverVendor &&
DoesVendorStringMatch(serverVendor, "Chromium")) || DoesVendorStringMatch(serverVendor, "Chromium")) ||
@ -633,6 +649,23 @@ GLXLibrary::xWaitX()
AFTER_GLX_CALL; AFTER_GLX_CALL;
} }
GLXContext
GLXLibrary::xCreateContextAttribs(Display* display,
GLXFBConfig config,
GLXContext share_list,
Bool direct,
const int* attrib_list)
{
BEFORE_GLX_CALL;
GLXContext result = xCreateContextAttribsInternal(display,
config,
share_list,
direct,
attrib_list);
AFTER_GLX_CALL;
return result;
}
GLXLibrary sGLXLibrary; GLXLibrary sGLXLibrary;
class GLContextGLX : public GLContext class GLContextGLX : public GLContext
@ -667,11 +700,25 @@ TRY_AGAIN_NO_SHARING:
error = false; error = false;
if (sGLXLibrary.HasRobustness()) {
int attrib_list[] = {
LOCAL_GL_CONTEXT_FLAGS_ARB, LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB,
0,
};
context = sGLXLibrary.xCreateContextAttribs(display,
cfg,
shareContext ? shareContext->mContext : NULL,
True,
attrib_list);
} else {
context = sGLXLibrary.xCreateNewContext(display, context = sGLXLibrary.xCreateNewContext(display,
cfg, cfg,
GLX_RGBA_TYPE, GLX_RGBA_TYPE,
shareContext ? shareContext->mContext : NULL, shareContext ? shareContext->mContext : NULL,
True); True);
}
if (context) { if (context) {
glContext = new GLContextGLX(format, glContext = new GLContextGLX(format,

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

@ -373,6 +373,8 @@ struct GLContextSymbols
typedef realGLboolean (GLAPIENTRY * PFNGLUNMAPBUFFER) (GLenum target); typedef realGLboolean (GLAPIENTRY * PFNGLUNMAPBUFFER) (GLenum target);
PFNGLUNMAPBUFFER fUnmapBuffer; PFNGLUNMAPBUFFER fUnmapBuffer;
typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUS) (void);
PFNGLGETGRAPHICSRESETSTATUS fGetGraphicsResetStatus;
}; };
} }

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

@ -178,6 +178,7 @@ typedef ptrdiff_t GLintptr;
#define LOCAL_GL_STACK_OVERFLOW 0x0503 #define LOCAL_GL_STACK_OVERFLOW 0x0503
#define LOCAL_GL_STACK_UNDERFLOW 0x0504 #define LOCAL_GL_STACK_UNDERFLOW 0x0504
#define LOCAL_GL_OUT_OF_MEMORY 0x0505 #define LOCAL_GL_OUT_OF_MEMORY 0x0505
#define LOCAL_GL_CONTEXT_LOST 0x9242
#define LOCAL_GL_2D 0x0600 #define LOCAL_GL_2D 0x0600
#define LOCAL_GL_3D 0x0601 #define LOCAL_GL_3D 0x0601
#define LOCAL_GL_3D_COLOR 0x0602 #define LOCAL_GL_3D_COLOR 0x0602
@ -3039,6 +3040,49 @@ typedef ptrdiff_t GLintptr;
#define LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 #define LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
#define LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 #define LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
#define LOCAL_GL_GUILTY_CONTEXT_RESET_ARB 0x8253
#define LOCAL_GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
#define LOCAL_GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
#define LOCAL_GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define LOCAL_GL_NO_RESET_NOTIFICATION_ARB 0x8261
#define LOCAL_GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define LOCAL_GL_NO_RESET_NOTIFICATION_ARB 0x8261
#define LOCAL_GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define LOCAL_WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#define LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define LOCAL_GL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define LOCAL_GL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define LOCAL_GL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define LOCAL_GL_CONTEXT_FLAGS_ARB 0x2094
#define LOCAL_GL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define LOCAL_WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define LOCAL_WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define LOCAL_WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define LOCAL_WGL_CONTEXT_FLAGS_ARB 0x2094
#define LOCAL_WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define LOCAL_GL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define LOCAL_GL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define LOCAL_WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define LOCAL_WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define LOCAL_GL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define LOCAL_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define LOCAL_GL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define LOCAL_WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define LOCAL_WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define LOCAL_WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 #define LOCAL_WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define LOCAL_WGL_DRAW_TO_WINDOW_ARB 0x2001 #define LOCAL_WGL_DRAW_TO_WINDOW_ARB 0x2001
#define LOCAL_WGL_DRAW_TO_BITMAP_ARB 0x2002 #define LOCAL_WGL_DRAW_TO_BITMAP_ARB 0x2002

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

@ -50,7 +50,7 @@ class GLXLibrary
public: public:
GLXLibrary() : mInitialized(false), mTriedInitializing(false), GLXLibrary() : mInitialized(false), mTriedInitializing(false),
mHasTextureFromPixmap(false), mDebug(false), mHasTextureFromPixmap(false), mDebug(false),
mOGLLibrary(nsnull) {} mHasRobustness(false), mOGLLibrary(nsnull) {}
void xDestroyContext(Display* display, GLXContext context); void xDestroyContext(Display* display, GLXContext context);
Bool xMakeCurrent(Display* display, Bool xMakeCurrent(Display* display,
@ -108,6 +108,12 @@ public:
void xWaitGL(); void xWaitGL();
void xWaitX(); void xWaitX();
GLXContext xCreateContextAttribs(Display* display,
GLXFBConfig config,
GLXContext share_list,
Bool direct,
const int* attrib_list);
bool EnsureInitialized(); bool EnsureInitialized();
GLXPixmap CreatePixmap(gfxASurface* aSurface); GLXPixmap CreatePixmap(gfxASurface* aSurface);
@ -116,6 +122,7 @@ public:
void ReleaseTexImage(GLXPixmap aPixmap); void ReleaseTexImage(GLXPixmap aPixmap);
bool HasTextureFromPixmap() { return mHasTextureFromPixmap; } bool HasTextureFromPixmap() { return mHasTextureFromPixmap; }
bool HasRobustness() { return mHasRobustness; }
bool SupportsTextureFromPixmap(gfxASurface* aSurface); bool SupportsTextureFromPixmap(gfxASurface* aSurface);
private: private:
@ -209,6 +216,13 @@ private:
typedef void (GLAPIENTRY * PFNGLXWAITX) (); typedef void (GLAPIENTRY * PFNGLXWAITX) ();
PFNGLXWAITGL xWaitXInternal; PFNGLXWAITGL xWaitXInternal;
typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXTATTRIBS) (Display *,
GLXFBConfig,
GLXContext,
Bool,
const int *);
PFNGLXCREATECONTEXTATTRIBS xCreateContextAttribsInternal;
#ifdef DEBUG #ifdef DEBUG
void BeforeGLXCall(); void BeforeGLXCall();
void AfterGLXCall(); void AfterGLXCall();
@ -218,6 +232,7 @@ private:
bool mTriedInitializing; bool mTriedInitializing;
bool mHasTextureFromPixmap; bool mHasTextureFromPixmap;
bool mDebug; bool mDebug;
bool mHasRobustness;
PRLibrary *mOGLLibrary; PRLibrary *mOGLLibrary;
}; };

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

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