b=621986; fix webgl is-object test; r=bjacob

This commit is contained in:
Vladimir Vukicevic 2011-01-05 13:08:53 -08:00
parent fb4b3ea6da
commit c228ddb5ec
2 changed files with 90 additions and 20 deletions

View File

@ -510,7 +510,10 @@ protected:
WebGLObjectRefPtr<WebGLBuffer> mBoundArrayBuffer; WebGLObjectRefPtr<WebGLBuffer> mBoundArrayBuffer;
WebGLObjectRefPtr<WebGLBuffer> mBoundElementArrayBuffer; WebGLObjectRefPtr<WebGLBuffer> mBoundElementArrayBuffer;
WebGLObjectRefPtr<WebGLProgram> mCurrentProgram; // note nsRefPtr -- this stays alive even after being deleted,
// and is only explicitly removed from the current state via
// a call to UseProgram.
nsRefPtr<WebGLProgram> mCurrentProgram;
PRUint32 mMaxFramebufferColorAttachments; PRUint32 mMaxFramebufferColorAttachments;
@ -1145,7 +1148,7 @@ public:
WebGLShader(WebGLContext *context, WebGLuint name, WebGLenum stype) : WebGLShader(WebGLContext *context, WebGLuint name, WebGLenum stype) :
WebGLContextBoundObject(context), WebGLContextBoundObject(context),
mName(name), mDeleted(PR_FALSE), mType(stype), mName(name), mDeleted(PR_FALSE), mType(stype),
mNeedsTranslation(true) mNeedsTranslation(true), mAttachCount(0)
{ } { }
void Delete() { void Delete() {
@ -1155,10 +1158,14 @@ public:
mDeleted = PR_TRUE; mDeleted = PR_TRUE;
} }
PRBool Deleted() { return mDeleted; } PRBool Deleted() { return mDeleted && mAttachCount == 0; }
WebGLuint GLName() { return mName; } WebGLuint GLName() { return mName; }
WebGLenum ShaderType() { return mType; } WebGLenum ShaderType() { return mType; }
PRUint32 AttachCount() { return mAttachCount; }
void IncrementAttachCount() { mAttachCount++; }
void DecrementAttachCount() { mAttachCount--; }
void SetSource(const nsCString& src) { void SetSource(const nsCString& src) {
// XXX do some quick gzip here maybe -- getting this will be very rare // XXX do some quick gzip here maybe -- getting this will be very rare
mSource.Assign(src); mSource.Assign(src);
@ -1189,6 +1196,7 @@ protected:
nsCString mSource; nsCString mSource;
nsCString mTranslationLog; nsCString mTranslationLog;
bool mNeedsTranslation; bool mNeedsTranslation;
PRUint32 mAttachCount;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(WebGLShader, WEBGLSHADER_PRIVATE_IID) NS_DEFINE_STATIC_IID_ACCESSOR(WebGLShader, WEBGLSHADER_PRIVATE_IID)
@ -1205,7 +1213,8 @@ public:
WebGLProgram(WebGLContext *context, WebGLuint name) : WebGLProgram(WebGLContext *context, WebGLuint name) :
WebGLContextBoundObject(context), WebGLContextBoundObject(context),
mName(name), mDeleted(PR_FALSE), mLinkStatus(PR_FALSE), mGeneration(0), mName(name), mDeleted(PR_FALSE), mDeletePending(PR_FALSE),
mLinkStatus(PR_FALSE), mGeneration(0),
mUniformMaxNameLength(0), mAttribMaxNameLength(0), mUniformMaxNameLength(0), mAttribMaxNameLength(0),
mUniformCount(0), mAttribCount(0) mUniformCount(0), mAttribCount(0)
{ {
@ -1219,7 +1228,18 @@ public:
mDeleted = PR_TRUE; mDeleted = PR_TRUE;
} }
PRBool Deleted() { return mDeleted; } void DetachShaders() {
for (PRUint32 i = 0; i < mAttachedShaders.Length(); ++i) {
mAttachedShaders[i]->DecrementAttachCount();
}
mAttachedShaders.Clear();
}
PRBool Deleted() { return mDeleted && !mDeletePending; }
void SetDeletePending() { mDeletePending = PR_TRUE; }
void ClearDeletePending() { mDeletePending = PR_FALSE; }
PRBool HasDeletePending() { return mDeletePending; }
WebGLuint GLName() { return mName; } WebGLuint GLName() { return mName; }
const nsTArray<WebGLShader*>& AttachedShaders() const { return mAttachedShaders; } const nsTArray<WebGLShader*>& AttachedShaders() const { return mAttachedShaders; }
PRBool LinkStatus() { return mLinkStatus; } PRBool LinkStatus() { return mLinkStatus; }
@ -1235,12 +1255,17 @@ public:
if (ContainsShader(shader)) if (ContainsShader(shader))
return PR_FALSE; return PR_FALSE;
mAttachedShaders.AppendElement(shader); mAttachedShaders.AppendElement(shader);
shader->IncrementAttachCount();
return PR_TRUE; return PR_TRUE;
} }
// return true if the shader was found and removed // return true if the shader was found and removed
PRBool DetachShader(WebGLShader *shader) { PRBool DetachShader(WebGLShader *shader) {
return mAttachedShaders.RemoveElement(shader); if (mAttachedShaders.RemoveElement(shader)) {
shader->DecrementAttachCount();
return PR_TRUE;
}
return PR_FALSE;
} }
PRBool HasAttachedShaderOfType(GLenum shaderType) { PRBool HasAttachedShaderOfType(GLenum shaderType) {
@ -1285,10 +1310,14 @@ public:
protected: protected:
WebGLuint mName; WebGLuint mName;
PRPackedBool mDeleted; PRPackedBool mDeleted;
PRPackedBool mDeletePending;
PRPackedBool mLinkStatus; PRPackedBool mLinkStatus;
// attached shaders of the program object
nsTArray<WebGLShader*> mAttachedShaders; nsTArray<WebGLShader*> mAttachedShaders;
nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
CheckedUint32 mGeneration; CheckedUint32 mGeneration;
// post-link data
nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
GLint mUniformMaxNameLength; GLint mUniformMaxNameLength;
GLint mAttribMaxNameLength; GLint mAttribMaxNameLength;
GLint mUniformCount; GLint mUniformCount;

View File

@ -169,6 +169,8 @@ WebGLContext::AttachShader(nsIWebGLProgram *pobj, nsIWebGLShader *shobj)
gl->fAttachShader(progname, shadername); gl->fAttachShader(progname, shadername);
printf_stderr("AttachShader: %p AttachCount after attach %d\n", shader, shader->AttachCount());
return NS_OK; return NS_OK;
} }
@ -869,6 +871,13 @@ WebGLContext::DeleteProgram(nsIWebGLProgram *pobj)
MakeContextCurrent(); MakeContextCurrent();
gl->fDeleteProgram(progname); gl->fDeleteProgram(progname);
if (prog == mCurrentProgram) {
prog->SetDeletePending();
} else {
prog->DetachShaders();
}
prog->Delete(); prog->Delete();
mMapPrograms.Remove(progname); mMapPrograms.Remove(progname);
@ -890,6 +899,7 @@ WebGLContext::DeleteShader(nsIWebGLShader *sobj)
MakeContextCurrent(); MakeContextCurrent();
gl->fDeleteShader(shadername); gl->fDeleteShader(shadername);
printf_stderr("DeleteShader: shader %p AttachCount in delete %d\n", shader, shader->AttachCount());
shader->Delete(); shader->Delete();
mMapShaders.Remove(shadername); mMapShaders.Remove(shadername);
@ -902,10 +912,13 @@ WebGLContext::DetachShader(nsIWebGLProgram *pobj, nsIWebGLShader *shobj)
WebGLuint progname, shadername; WebGLuint progname, shadername;
WebGLProgram *program; WebGLProgram *program;
WebGLShader *shader; WebGLShader *shader;
PRBool shaderDeleted;
if (!GetConcreteObjectAndGLName("detachShader: program", pobj, &program, &progname) || if (!GetConcreteObjectAndGLName("detachShader: program", pobj, &program, &progname) ||
!GetConcreteObjectAndGLName("detachShader: shader", shobj, &shader, &shadername)) !GetConcreteObjectAndGLName("detachShader: shader", shobj, &shader, &shadername, nsnull, &shaderDeleted))
return NS_OK; return NS_OK;
// shaderDeleted is ignored -- it's valid to attempt to detach a
// deleted shader, since it's still a shader
if (!program->DetachShader(shader)) if (!program->DetachShader(shader))
return ErrorInvalidOperation("DetachShader: shader is not attached"); return ErrorInvalidOperation("DetachShader: shader is not attached");
@ -1426,7 +1439,7 @@ WebGLContext::GetAttachedShaders(nsIWebGLProgram *pobj, nsIVariant **retval)
MakeContextCurrent(); MakeContextCurrent();
if (isNull) { if (isNull) {
wrval->SetAsVoid(); wrval->SetAsEmpty();
// note no return, we still want to return the variant // note no return, we still want to return the variant
ErrorInvalidValue("getAttachedShaders: invalid program"); ErrorInvalidValue("getAttachedShaders: invalid program");
} else if (prog->AttachedShaders().Length() == 0) { } else if (prog->AttachedShaders().Length() == 0) {
@ -1956,7 +1969,8 @@ WebGLContext::GetProgramParameter(nsIWebGLProgram *pobj, PRUint32 pname, nsIVari
*retval = nsnull; *retval = nsnull;
WebGLuint progname; WebGLuint progname;
if (!GetGLName<WebGLProgram>("getProgramParameter: program", pobj, &progname)) PRBool isDeleted;
if (!GetGLName<WebGLProgram>("getProgramParameter: program", pobj, &progname, nsnull, &isDeleted))
return NS_OK; return NS_OK;
nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1"); nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1");
@ -2430,7 +2444,18 @@ NS_IMETHODIMP
WebGLContext::IsProgram(nsIWebGLProgram *pobj, WebGLboolean *retval) WebGLContext::IsProgram(nsIWebGLProgram *pobj, WebGLboolean *retval)
{ {
PRBool isDeleted; PRBool isDeleted;
*retval = CanGetConcreteObject<WebGLProgram>("isProgram", pobj, 0, &isDeleted) && !isDeleted; WebGLProgram *prog = nsnull;
PRBool ok = GetConcreteObject("isProgram", pobj, &prog, 0, &isDeleted, PR_FALSE);
if (!ok) {
*retval = PR_FALSE;
return NS_OK;
}
if (isDeleted) {
*retval = PR_FALSE;
} else {
*retval = PR_TRUE;
}
return NS_OK; return NS_OK;
} }
@ -2454,7 +2479,18 @@ NS_IMETHODIMP
WebGLContext::IsShader(nsIWebGLShader *sobj, WebGLboolean *retval) WebGLContext::IsShader(nsIWebGLShader *sobj, WebGLboolean *retval)
{ {
PRBool isDeleted; PRBool isDeleted;
*retval = CanGetConcreteObject<WebGLShader>("isShader", sobj, 0, &isDeleted) && !isDeleted; WebGLShader *shader = nsnull;
PRBool ok = GetConcreteObject("isShader", sobj, &shader, 0, &isDeleted, PR_FALSE);
if (!ok) {
*retval = PR_FALSE;
return NS_OK;
}
if (isDeleted) {
*retval = PR_FALSE;
} else {
*retval = PR_TRUE;
}
return NS_OK; return NS_OK;
} }
@ -3332,16 +3368,18 @@ WebGLContext::UseProgram(nsIWebGLProgram *pobj)
MakeContextCurrent(); MakeContextCurrent();
if (isNull) { if (prog && !prog->LinkStatus())
gl->fUseProgram(0); return ErrorInvalidOperation("UseProgram: program was not linked successfully");
mCurrentProgram = nsnull;
} else { gl->fUseProgram(progname);
if (!prog->LinkStatus())
return ErrorInvalidOperation("UseProgram: program was not linked successfully"); if (mCurrentProgram && mCurrentProgram->HasDeletePending()) {
gl->fUseProgram(progname); mCurrentProgram->DetachShaders();
mCurrentProgram = prog; mCurrentProgram->ClearDeletePending();
} }
mCurrentProgram = prog;
return NS_OK; return NS_OK;
} }
@ -3419,6 +3457,9 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
WebGLuint shadername; WebGLuint shadername;
if (!GetConcreteObjectAndGLName("compileShader", sobj, &shader, &shadername)) if (!GetConcreteObjectAndGLName("compileShader", sobj, &shader, &shadername))
return NS_OK; return NS_OK;
printf_stderr("CompileShader: shader %p AttachCount %d\n", shader, shader->AttachCount());
MakeContextCurrent(); MakeContextCurrent();
#if defined(USE_ANGLE) #if defined(USE_ANGLE)