зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f8179e8309
Коммит
942467690c
|
@ -70,6 +70,7 @@ CPPSRCS += \
|
|||
WebGLContextUtils.cpp \
|
||||
WebGLContextValidate.cpp \
|
||||
WebGLExtensionStandardDerivatives.cpp \
|
||||
WebGLExtensionLoseContext.cpp \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -DUSE_ANGLE
|
||||
|
|
|
@ -296,14 +296,21 @@ WebGLContext::WebGLContext()
|
|||
// See OpenGL ES 2.0.25 spec, 6.2 State Tables, table 6.13
|
||||
mPixelStorePackAlignment = 4;
|
||||
mPixelStoreUnpackAlignment = 4;
|
||||
|
||||
|
||||
WebGLMemoryReporter::AddWebGLContext(this);
|
||||
|
||||
mContextLost = false;
|
||||
mAllowRestore = false;
|
||||
}
|
||||
|
||||
WebGLContext::~WebGLContext()
|
||||
{
|
||||
DestroyResourcesAndContext();
|
||||
WebGLMemoryReporter::RemoveWebGLContext(this);
|
||||
if (mContextRestorer) {
|
||||
mContextRestorer->Cancel();
|
||||
mContextRestorer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
|
@ -822,6 +829,9 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
CanvasLayer *aOldLayer,
|
||||
LayerManager *aManager)
|
||||
{
|
||||
if (mContextLost)
|
||||
return nsnull;
|
||||
|
||||
if (!mResetLayer && aOldLayer &&
|
||||
aOldLayer->HasUserData(&gWebGLLayerUserData)) {
|
||||
NS_ADDREF(aOldLayer);
|
||||
|
@ -885,6 +895,12 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
NS_IMETHODIMP
|
||||
WebGLContext::GetContextAttributes(jsval *aResult)
|
||||
{
|
||||
if (mContextLost)
|
||||
{
|
||||
*aResult = OBJECT_TO_JSVAL(NULL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (!cx)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -923,6 +939,9 @@ WebGLContext::GetContextAttributes(jsval *aResult)
|
|||
NS_IMETHODIMP
|
||||
WebGLContext::MozGetUnderlyingParamString(PRUint32 pname, nsAString& retval)
|
||||
{
|
||||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
retval.SetIsVoid(true);
|
||||
|
||||
MakeContextCurrent();
|
||||
|
@ -959,6 +978,10 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
|
|||
// We always support this extension.
|
||||
isSupported = true;
|
||||
break;
|
||||
case WebGL_WEBKIT_lose_context:
|
||||
// We always support this extension.
|
||||
isSupported = true;
|
||||
break;
|
||||
default:
|
||||
isSupported = false;
|
||||
}
|
||||
|
@ -970,6 +993,8 @@ NS_IMETHODIMP
|
|||
WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
if (mDisableExtensions) {
|
||||
return NS_OK;
|
||||
|
@ -985,6 +1010,10 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
|
|||
if (IsExtensionSupported(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 (!IsExtensionEnabled(ei)) {
|
||||
|
@ -992,6 +1021,9 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
|
|||
case WebGL_OES_standard_derivatives:
|
||||
mEnabledExtensions[ei] = new WebGLExtensionStandardDerivatives(this);
|
||||
break;
|
||||
case WebGL_WEBKIT_lose_context:
|
||||
mEnabledExtensions[ei] = new WebGLExtensionLoseContext(this);
|
||||
break;
|
||||
// create an extension for any types that don't
|
||||
// have any additional tokens or methods
|
||||
default:
|
||||
|
@ -1095,6 +1127,86 @@ WebGLContext::EnsureBackbufferClearedAsNeeded()
|
|||
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
|
||||
//
|
||||
|
@ -1116,6 +1228,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIDOMWebGLRenderingContext)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWebGLRenderingContext)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLRenderingContext)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
@ -1254,10 +1367,24 @@ NS_INTERFACE_MAP_BEGIN(WebGLExtensionStandardDerivatives)
|
|||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionStandardDerivatives)
|
||||
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; */
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::GetDrawingBufferWidth(WebGLsizei *aWidth)
|
||||
{
|
||||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
*aWidth = mWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1266,6 +1393,9 @@ WebGLContext::GetDrawingBufferWidth(WebGLsizei *aWidth)
|
|||
NS_IMETHODIMP
|
||||
WebGLContext::GetDrawingBufferHeight(WebGLsizei *aHeight)
|
||||
{
|
||||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
*aHeight = mHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1311,6 +1441,8 @@ NS_IMETHODIMP
|
|||
WebGLContext::GetSupportedExtensions(nsIVariant **retval)
|
||||
{
|
||||
*retval = nsnull;
|
||||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
if (mDisableExtensions) {
|
||||
return NS_OK;
|
||||
|
@ -1343,7 +1475,7 @@ WebGLContext::GetSupportedExtensions(nsIVariant **retval)
|
|||
NS_IMETHODIMP
|
||||
WebGLContext::IsContextLost(WebGLboolean *retval)
|
||||
{
|
||||
*retval = false;
|
||||
*retval = mContextLost;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -339,9 +339,11 @@ struct WebGLContextOptions {
|
|||
class WebGLContext :
|
||||
public nsIDOMWebGLRenderingContext,
|
||||
public nsICanvasRenderingContextInternal,
|
||||
public nsSupportsWeakReference
|
||||
public nsSupportsWeakReference,
|
||||
public nsITimerCallback
|
||||
{
|
||||
friend class WebGLMemoryReporter;
|
||||
friend class WebGLExtensionLoseContext;
|
||||
|
||||
public:
|
||||
WebGLContext();
|
||||
|
@ -353,6 +355,8 @@ public:
|
|||
|
||||
NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
|
||||
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
// nsICanvasRenderingContextInternal
|
||||
NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
|
||||
NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
|
||||
|
@ -380,6 +384,9 @@ public:
|
|||
PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h)
|
||||
{ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
bool LoseContext();
|
||||
bool RestoreContext();
|
||||
|
||||
nsresult SynthesizeGLError(WebGLenum err);
|
||||
nsresult SynthesizeGLError(WebGLenum err, const char *fmt, ...);
|
||||
|
||||
|
@ -438,6 +445,22 @@ public:
|
|||
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:
|
||||
void SetDontKnowIfNeedFakeBlack() {
|
||||
mFakeBlackStatus = DontKnowIfNeedFakeBlack;
|
||||
|
@ -502,6 +525,7 @@ protected:
|
|||
enum WebGLExtensionID {
|
||||
WebGL_OES_texture_float,
|
||||
WebGL_OES_standard_derivatives,
|
||||
WebGL_WEBKIT_lose_context,
|
||||
WebGLExtensionID_Max
|
||||
};
|
||||
nsCOMPtr<WebGLExtension> mEnabledExtensions[WebGLExtensionID_Max];
|
||||
|
@ -633,6 +657,10 @@ protected:
|
|||
GLenum type,
|
||||
const GLvoid *data);
|
||||
|
||||
void MaybeRestoreContext();
|
||||
void ForceLoseContext();
|
||||
void ForceRestoreContext();
|
||||
|
||||
// the buffers bound to the current program's attribs
|
||||
nsTArray<WebGLVertexAttribData> mAttribBuffers;
|
||||
|
||||
|
@ -691,6 +719,10 @@ protected:
|
|||
|
||||
int mBackbufferClearingStatus;
|
||||
|
||||
nsCOMPtr<nsITimer> mContextRestorer;
|
||||
bool mContextLost;
|
||||
bool mAllowRestore;
|
||||
|
||||
public:
|
||||
// console logging helpers
|
||||
static void LogMessage(const char *fmt, ...);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -53,3 +53,4 @@ DOMCI_DATA(WebGLRenderbuffer, void)
|
|||
DOMCI_DATA(WebGLUniformLocation, void)
|
||||
DOMCI_DATA(WebGLActiveInfo, 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 {
|
||||
|
||||
class WebGLExtensionLoseContext;
|
||||
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 \
|
||||
{0x3de3dfd9, 0x864a, 0x4e4c, {0x98, 0x9b, 0x29, 0x77, 0xea, 0xa8, 0x0b, 0x7b}}
|
||||
class WebGLExtensionStandardDerivatives :
|
||||
|
|
|
@ -1450,6 +1450,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionStandardDerivatives, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionLoseContext, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(PaintRequest, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
@ -3986,6 +3988,10 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_MAP_ENTRY(nsIWebGLExtensionStandardDerivatives)
|
||||
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_ENTRY(nsIDOMPaintRequest)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
|
|
@ -472,6 +472,7 @@ DOMCI_CLASS(WebGLUniformLocation)
|
|||
DOMCI_CLASS(WebGLActiveInfo)
|
||||
DOMCI_CLASS(WebGLExtension)
|
||||
DOMCI_CLASS(WebGLExtensionStandardDerivatives)
|
||||
DOMCI_CLASS(WebGLExtensionLoseContext)
|
||||
|
||||
DOMCI_CLASS(PaintRequest)
|
||||
DOMCI_CLASS(PaintRequestList)
|
||||
|
|
|
@ -153,6 +153,12 @@ interface nsIWebGLExtensionStandardDerivatives : nsIWebGLExtension
|
|||
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)]
|
||||
interface nsIDOMWebGLRenderingContext : nsISupports
|
||||
|
|
|
@ -174,6 +174,8 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
|||
return true;
|
||||
}
|
||||
|
||||
mHasRobustness = IsExtensionSupported(ARB_robustness);
|
||||
|
||||
SymLoadStruct symbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fActiveTexture, { "ActiveTexture", "ActiveTextureARB", 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 ? NULL : "UnmapBuffer", NULL } },
|
||||
|
||||
{ mHasRobustness ? (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus : (PRFuncPtr*) NULL,
|
||||
{ mHasRobustness ? "GetGraphicsResetStatusARB" : NULL, NULL } },
|
||||
|
||||
{ NULL, { NULL } },
|
||||
|
||||
};
|
||||
|
@ -470,6 +475,7 @@ static const char *sExtensionNames[] = {
|
|||
"GL_EXT_framebuffer_multisample",
|
||||
"GL_ANGLE_framebuffer_multisample",
|
||||
"GL_OES_rgb8_rgba8",
|
||||
"GL_ARB_robustness",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -1242,6 +1242,7 @@ public:
|
|||
EXT_framebuffer_multisample,
|
||||
ANGLE_framebuffer_multisample,
|
||||
OES_rgb8_rgba8,
|
||||
ARB_robustness,
|
||||
Extensions_Max
|
||||
};
|
||||
|
||||
|
@ -1278,11 +1279,24 @@ public:
|
|||
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:
|
||||
bool mInitialized;
|
||||
bool mIsOffscreen;
|
||||
bool mIsGLES2;
|
||||
bool mIsGlobalSharedContext;
|
||||
bool mHasRobustness;
|
||||
|
||||
PRInt32 mVendor;
|
||||
|
||||
|
@ -2498,6 +2512,14 @@ public:
|
|||
AFTER_GL_CALL;
|
||||
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
|
||||
void THEBES_API CreatedProgram(GLContext *aOrigin, GLuint aName);
|
||||
void THEBES_API CreatedShader(GLContext *aOrigin, GLuint aName);
|
||||
|
|
|
@ -183,6 +183,11 @@ GLXLibrary::EnsureInitialized()
|
|||
{ NULL, { NULL } }
|
||||
};
|
||||
|
||||
LibrarySymbolLoader::SymLoadStruct symbols_robustness[] = {
|
||||
{ (PRFuncPtr*) &xCreateContextAttribsInternal, { "glXCreateContextAttribsARB", NULL } },
|
||||
{ NULL, { NULL } }
|
||||
};
|
||||
|
||||
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
|
||||
NS_WARNING("Couldn't find required entry point in OpenGL shared library");
|
||||
return false;
|
||||
|
@ -251,6 +256,17 @@ GLXLibrary::EnsureInitialized()
|
|||
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");
|
||||
gIsChromium = (serverVendor &&
|
||||
DoesVendorStringMatch(serverVendor, "Chromium")) ||
|
||||
|
@ -633,6 +649,23 @@ GLXLibrary::xWaitX()
|
|||
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;
|
||||
|
||||
class GLContextGLX : public GLContext
|
||||
|
@ -667,11 +700,25 @@ TRY_AGAIN_NO_SHARING:
|
|||
|
||||
error = false;
|
||||
|
||||
context = sGLXLibrary.xCreateNewContext(display,
|
||||
cfg,
|
||||
GLX_RGBA_TYPE,
|
||||
shareContext ? shareContext->mContext : NULL,
|
||||
True);
|
||||
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,
|
||||
cfg,
|
||||
GLX_RGBA_TYPE,
|
||||
shareContext ? shareContext->mContext : NULL,
|
||||
True);
|
||||
}
|
||||
|
||||
if (context) {
|
||||
glContext = new GLContextGLX(format,
|
||||
|
|
|
@ -373,6 +373,8 @@ struct GLContextSymbols
|
|||
typedef realGLboolean (GLAPIENTRY * PFNGLUNMAPBUFFER) (GLenum target);
|
||||
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_UNDERFLOW 0x0504
|
||||
#define LOCAL_GL_OUT_OF_MEMORY 0x0505
|
||||
#define LOCAL_GL_CONTEXT_LOST 0x9242
|
||||
#define LOCAL_GL_2D 0x0600
|
||||
#define LOCAL_GL_3D 0x0601
|
||||
#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_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_DRAW_TO_WINDOW_ARB 0x2001
|
||||
#define LOCAL_WGL_DRAW_TO_BITMAP_ARB 0x2002
|
||||
|
|
|
@ -50,7 +50,7 @@ class GLXLibrary
|
|||
public:
|
||||
GLXLibrary() : mInitialized(false), mTriedInitializing(false),
|
||||
mHasTextureFromPixmap(false), mDebug(false),
|
||||
mOGLLibrary(nsnull) {}
|
||||
mHasRobustness(false), mOGLLibrary(nsnull) {}
|
||||
|
||||
void xDestroyContext(Display* display, GLXContext context);
|
||||
Bool xMakeCurrent(Display* display,
|
||||
|
@ -108,6 +108,12 @@ public:
|
|||
void xWaitGL();
|
||||
void xWaitX();
|
||||
|
||||
GLXContext xCreateContextAttribs(Display* display,
|
||||
GLXFBConfig config,
|
||||
GLXContext share_list,
|
||||
Bool direct,
|
||||
const int* attrib_list);
|
||||
|
||||
bool EnsureInitialized();
|
||||
|
||||
GLXPixmap CreatePixmap(gfxASurface* aSurface);
|
||||
|
@ -116,6 +122,7 @@ public:
|
|||
void ReleaseTexImage(GLXPixmap aPixmap);
|
||||
|
||||
bool HasTextureFromPixmap() { return mHasTextureFromPixmap; }
|
||||
bool HasRobustness() { return mHasRobustness; }
|
||||
bool SupportsTextureFromPixmap(gfxASurface* aSurface);
|
||||
|
||||
private:
|
||||
|
@ -209,6 +216,13 @@ private:
|
|||
typedef void (GLAPIENTRY * PFNGLXWAITX) ();
|
||||
PFNGLXWAITGL xWaitXInternal;
|
||||
|
||||
typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXTATTRIBS) (Display *,
|
||||
GLXFBConfig,
|
||||
GLXContext,
|
||||
Bool,
|
||||
const int *);
|
||||
PFNGLXCREATECONTEXTATTRIBS xCreateContextAttribsInternal;
|
||||
|
||||
#ifdef DEBUG
|
||||
void BeforeGLXCall();
|
||||
void AfterGLXCall();
|
||||
|
@ -218,6 +232,7 @@ private:
|
|||
bool mTriedInitializing;
|
||||
bool mHasTextureFromPixmap;
|
||||
bool mDebug;
|
||||
bool mHasRobustness;
|
||||
PRLibrary *mOGLLibrary;
|
||||
};
|
||||
|
||||
|
|
|
@ -487,6 +487,7 @@ irregularFilenames = {
|
|||
'nsIWebGLUniformLocation': 'nsIDOMWebGLRenderingContext',
|
||||
'nsIWebGLExtension': 'nsIDOMWebGLRenderingContext',
|
||||
'nsIWebGLExtensionStandardDerivatives' : 'nsIDOMWebGLRenderingContext',
|
||||
'nsIWebGLExtensionLoseContext' : 'nsIDOMWebGLRenderingContext',
|
||||
|
||||
'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче