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> 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;
@ -1145,7 +1148,7 @@ public:
WebGLShader(WebGLContext *context, WebGLuint name, WebGLenum stype) :
WebGLContextBoundObject(context),
mName(name), mDeleted(PR_FALSE), mType(stype),
mNeedsTranslation(true)
mNeedsTranslation(true), mAttachCount(0)
{ }
void Delete() {
@ -1155,10 +1158,14 @@ public:
mDeleted = PR_TRUE;
}
PRBool Deleted() { return mDeleted; }
PRBool Deleted() { return mDeleted && mAttachCount == 0; }
WebGLuint GLName() { return mName; }
WebGLenum ShaderType() { return mType; }
PRUint32 AttachCount() { return mAttachCount; }
void IncrementAttachCount() { mAttachCount++; }
void DecrementAttachCount() { mAttachCount--; }
void SetSource(const nsCString& src) {
// XXX do some quick gzip here maybe -- getting this will be very rare
mSource.Assign(src);
@ -1189,6 +1196,7 @@ protected:
nsCString mSource;
nsCString mTranslationLog;
bool mNeedsTranslation;
PRUint32 mAttachCount;
};
NS_DEFINE_STATIC_IID_ACCESSOR(WebGLShader, WEBGLSHADER_PRIVATE_IID)
@ -1205,7 +1213,8 @@ public:
WebGLProgram(WebGLContext *context, WebGLuint name) :
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),
mUniformCount(0), mAttribCount(0)
{
@ -1219,7 +1228,18 @@ public:
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; }
const nsTArray<WebGLShader*>& AttachedShaders() const { return mAttachedShaders; }
PRBool LinkStatus() { return mLinkStatus; }
@ -1235,12 +1255,17 @@ public:
if (ContainsShader(shader))
return PR_FALSE;
mAttachedShaders.AppendElement(shader);
shader->IncrementAttachCount();
return PR_TRUE;
}
// return true if the shader was found and removed
PRBool DetachShader(WebGLShader *shader) {
return mAttachedShaders.RemoveElement(shader);
if (mAttachedShaders.RemoveElement(shader)) {
shader->DecrementAttachCount();
return PR_TRUE;
}
return PR_FALSE;
}
PRBool HasAttachedShaderOfType(GLenum shaderType) {
@ -1285,10 +1310,14 @@ public:
protected:
WebGLuint mName;
PRPackedBool mDeleted;
PRPackedBool mDeletePending;
PRPackedBool mLinkStatus;
// attached shaders of the program object
nsTArray<WebGLShader*> mAttachedShaders;
nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
CheckedUint32 mGeneration;
// post-link data
nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
GLint mUniformMaxNameLength;
GLint mAttribMaxNameLength;
GLint mUniformCount;

View File

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