Bug 1136494 - Update LinkInfo. - r=mtseng

MozReview-Commit-ID: Fr4j8bHO5AG
This commit is contained in:
Jeff Gilbert 2016-07-14 12:04:31 -07:00
Родитель 95dd193042
Коммит 55d9d2af29
8 изменённых файлов: 299 добавлений и 197 удалений

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

@ -76,6 +76,8 @@ ElemSizeFromType(GLenum elemType)
}
}
////////////////////
WebGLActiveInfo::WebGLActiveInfo(WebGLContext* webgl, GLint elemCount, GLenum elemType,
bool isArray, const nsACString& baseUserName,
const nsACString& baseMappedName)
@ -88,6 +90,32 @@ WebGLActiveInfo::WebGLActiveInfo(WebGLContext* webgl, GLint elemCount, GLenum el
, mBaseMappedName(baseMappedName)
{ }
bool
WebGLActiveInfo::IsSampler() const
{
switch (mElemType) {
case LOCAL_GL_SAMPLER_2D:
case LOCAL_GL_SAMPLER_3D:
case LOCAL_GL_SAMPLER_CUBE:
case LOCAL_GL_SAMPLER_2D_SHADOW:
case LOCAL_GL_SAMPLER_2D_ARRAY:
case LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW:
case LOCAL_GL_SAMPLER_CUBE_SHADOW:
case LOCAL_GL_INT_SAMPLER_2D:
case LOCAL_GL_INT_SAMPLER_3D:
case LOCAL_GL_INT_SAMPLER_CUBE:
case LOCAL_GL_INT_SAMPLER_2D_ARRAY:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_3D:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
return true;
default:
return false;
}
}
////////////////////////////////////////////////////////////////////////////////
JSObject*

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

@ -43,6 +43,8 @@ public:
const uint8_t mElemSize;
const nsCString mBaseMappedName; // Without any final "[0]".
bool IsSampler() const;
WebGLActiveInfo(WebGLContext* webgl, GLint elemCount, GLenum elemType, bool isArray,
const nsACString& baseUserName, const nsACString& baseMappedName);
@ -91,6 +93,7 @@ private:
//////////
uint8_t ElemSizeFromType(GLenum elemType);
bool IsElemTypeSampler(GLenum elemType);
} // namespace mozilla

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

@ -122,6 +122,7 @@ namespace webgl {
struct LinkedProgramInfo;
class ShaderValidator;
class TexUnpackBlob;
struct UniformInfo;
} // namespace webgl
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
@ -1607,6 +1608,9 @@ public:
virtual UniquePtr<webgl::FormatUsageAuthority>
CreateFormatUsage(gl::GLContext* gl) const = 0;
const decltype(mBound2DTextures)* TexListForElemType(GLenum elemType) const;
// Friend list
friend class ScopedCopyTexImageSource;
friend class ScopedResolveTexturesForDraw;
@ -1615,6 +1619,7 @@ public:
friend class webgl::TexUnpackBytes;
friend class webgl::TexUnpackImage;
friend class webgl::TexUnpackSurface;
friend struct webgl::UniformInfo;
friend class WebGLTexture;
friend class WebGLFBAttachPoint;
friend class WebGLFramebuffer;

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

@ -971,10 +971,10 @@ WebGLContext::GetUniform(JSContext* js, WebGLProgram* prog,
if (!ValidateObject("getUniform: `location`", loc))
return JS::NullValue();
if (!loc->ValidateForProgram(prog, this, "getUniform"))
if (!loc->ValidateForProgram(prog, "getUniform"))
return JS::NullValue();
return loc->GetUniform(js, this);
return loc->GetUniform(js);
}
already_AddRefed<WebGLUniformLocation>

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

@ -69,36 +69,60 @@ ParseName(const nsCString& name, nsCString* const out_baseName,
return true;
}
static WebGLActiveInfo*
AddActiveInfo(WebGLContext* webgl, GLint elemCount, GLenum elemType, bool isArray,
const nsACString& baseUserName, const nsACString& baseMappedName,
std::vector<RefPtr<WebGLActiveInfo>>* activeInfoList,
std::map<nsCString, const WebGLActiveInfo*>* infoLocMap)
{
RefPtr<WebGLActiveInfo> info = new WebGLActiveInfo(webgl, elemCount, elemType,
isArray, baseUserName,
baseMappedName);
activeInfoList->push_back(info);
//////////
infoLocMap->insert(std::make_pair(info->mBaseUserName, info.get()));
return info.get();
/*static*/ const webgl::UniformInfo::TexListT*
webgl::UniformInfo::GetTexList(WebGLActiveInfo* activeInfo)
{
const auto& webgl = activeInfo->mWebGL;
switch (activeInfo->mElemType) {
case LOCAL_GL_SAMPLER_2D:
case LOCAL_GL_SAMPLER_2D_SHADOW:
case LOCAL_GL_INT_SAMPLER_2D:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D:
return &webgl->mBound2DTextures;
case LOCAL_GL_SAMPLER_CUBE:
case LOCAL_GL_SAMPLER_CUBE_SHADOW:
case LOCAL_GL_INT_SAMPLER_CUBE:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE:
return &webgl->mBoundCubeMapTextures;
case LOCAL_GL_SAMPLER_3D:
case LOCAL_GL_INT_SAMPLER_3D:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_3D:
return &webgl->mBound3DTextures;
case LOCAL_GL_SAMPLER_2D_ARRAY:
case LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW:
case LOCAL_GL_INT_SAMPLER_2D_ARRAY:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
return &webgl->mBound2DArrayTextures;
default:
return nullptr;
}
}
static void
AddActiveBlockInfo(const nsACString& baseUserName,
const nsACString& baseMappedName,
std::vector<RefPtr<webgl::UniformBlockInfo>>* activeInfoList)
webgl::UniformInfo::UniformInfo(WebGLActiveInfo* activeInfo)
: mActiveInfo(activeInfo)
, mSamplerTexList(GetTexList(activeInfo))
{
RefPtr<webgl::UniformBlockInfo> info = new webgl::UniformBlockInfo(baseUserName, baseMappedName);
activeInfoList->push_back(info);
if (mSamplerTexList) {
mSamplerValues.assign(mActiveInfo->mElemCount, 0);
}
}
//////////
//#define DUMP_SHADERVAR_MAPPINGS
static already_AddRefed<const webgl::LinkedProgramInfo>
QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
{
WebGLContext* const webgl = prog->mContext;
RefPtr<webgl::LinkedProgramInfo> info(new webgl::LinkedProgramInfo(prog));
GLuint maxAttribLenWithNull = 0;
@ -154,33 +178,37 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
mappedName.SetLength(lengthWithoutNull);
// Collect ActiveInfos:
// Attribs can't be arrays, so we can skip some of the mess we have in the Uniform
// path.
nsDependentCString userName;
if (!prog->FindAttribUserNameByMappedName(mappedName, &userName))
userName.Rebind(mappedName, 0);
///////
const GLint loc = gl->fGetAttribLocation(prog->mGLName,
mappedName.BeginReading());
if (loc == -1) {
MOZ_ASSERT(mappedName == "gl_InstanceID",
"Active attrib should have a location.");
continue;
}
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("[attrib %i] %s/%s\n", i, mappedName.BeginReading(),
printf_stderr("[attrib %i: %i] %s/%s\n", i, loc, mappedName.BeginReading(),
userName.BeginReading());
printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull);
#endif
const bool isArray = false;
const auto attrib = AddActiveInfo(prog->mContext, elemCount, elemType, isArray,
userName, mappedName, &info->activeAttribs,
&info->attribMap);
///////
// Collect active locations:
GLint loc = gl->fGetAttribLocation(prog->mGLName, mappedName.BeginReading());
if (loc == -1) {
if (mappedName != "gl_InstanceID")
MOZ_CRASH("GFX: Active attrib has no location.");
} else {
info->activeAttribLocs.insert({attrib, (GLuint)loc});
}
const bool isArray = false;
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount,
elemType, isArray,
userName,
mappedName);
const webgl::AttribInfo attrib = {activeInfo, uint32_t(loc)};
info->attribs.push_back(attrib);
}
// Uniforms
@ -203,6 +231,8 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
mappedName.SetLength(lengthWithoutNull);
///////
nsAutoCString baseMappedName;
bool isArray;
size_t arrayIndex;
@ -212,8 +242,11 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
// Note that for good drivers, `isArray` should already be correct.
// However, if FindUniform succeeds, it will be validator-guaranteed correct.
///////
nsAutoCString baseUserName;
if (!prog->FindUniformByMappedName(baseMappedName, &baseUserName, &isArray)) {
// Validator likely missing.
baseUserName = baseMappedName;
if (needsCheckForArrays && !isArray) {
@ -229,6 +262,8 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
}
}
///////
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("[uniform %i] %s/%i/%s/%s\n", i, mappedName.BeginReading(),
(int)isArray, baseMappedName.BeginReading(),
@ -237,11 +272,23 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
printf_stderr(" isArray: %d\n", (int)isArray);
#endif
AddActiveInfo(prog->mContext, elemCount, elemType, isArray, baseUserName,
baseMappedName, &info->activeUniforms, &info->uniformMap);
///////
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount,
elemType, isArray,
baseUserName,
baseMappedName);
auto* uniform = new webgl::UniformInfo(activeInfo);
info->uniforms.push_back(uniform);
if (uniform->mSamplerTexList) {
info->uniformSamplers.push_back(uniform);
}
}
// Uniform Blocks
// (no sampler types allowed!)
if (gl->IsSupported(gl::GLFeature::uniform_buffer_object)) {
GLuint numActiveUniformBlocks = 0;
@ -281,14 +328,15 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
}
#ifdef DUMP_SHADERVAR_MAPPINGS
printf_stderr("[uniform block %i] %s/%i/%s/%s\n", i, mappedName.BeginReading(),
(int)isArray, baseMappedName.BeginReading(),
baseUserName.BeginReading());
printf_stderr("[uniform block %i] %s/%i/%s/%s\n", i,
mappedName.BeginReading(), (int)isArray,
baseMappedName.BeginReading(), baseUserName.BeginReading());
printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull);
printf_stderr(" isArray: %d\n", (int)isArray);
#endif
AddActiveBlockInfo(baseUserName, baseMappedName, &info->uniformBlocks);
const auto* block = new webgl::UniformBlockInfo(baseUserName, baseMappedName);
info->uniformBlocks.push_back(block);
}
}
@ -304,19 +352,23 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
mappedName.SetLength(maxTransformFeedbackVaryingLenWithNull - 1);
GLint lengthWithoutNull;
GLsizei size;
GLenum type;
gl->fGetTransformFeedbackVarying(prog->mGLName, i, maxTransformFeedbackVaryingLenWithNull,
&lengthWithoutNull, &size, &type,
GLsizei elemCount;
GLenum elemType;
gl->fGetTransformFeedbackVarying(prog->mGLName, i,
maxTransformFeedbackVaryingLenWithNull,
&lengthWithoutNull, &elemCount, &elemType,
mappedName.BeginWriting());
mappedName.SetLength(lengthWithoutNull);
////
nsAutoCString baseMappedName;
bool isArray;
size_t arrayIndex;
if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver.");
nsAutoCString baseUserName;
if (!prog->FindVaryingByMappedName(mappedName, &baseUserName, &isArray)) {
baseUserName = baseMappedName;
@ -332,9 +384,15 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
}
}
AddActiveInfo(prog->mContext, size, type, isArray, baseUserName, mappedName,
&info->transformFeedbackVaryings,
&info->transformFeedbackVaryingsMap);
////
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl,
elemCount,
elemType,
isArray,
baseUserName,
mappedName);
info->transformFeedbackVaryings.push_back(activeInfo);
}
}
@ -347,6 +405,16 @@ webgl::LinkedProgramInfo::LinkedProgramInfo(WebGLProgram* prog)
: prog(prog)
{ }
webgl::LinkedProgramInfo::~LinkedProgramInfo()
{
for (auto& cur : uniforms) {
delete cur;
}
for (auto& cur : uniformBlocks) {
delete cur;
}
}
////////////////////////////////////////////////////////////////////////////////
// WebGLProgram
@ -487,15 +555,15 @@ WebGLProgram::GetActiveAttrib(GLuint index) const
return ret.forget();
}
const auto& activeList = mMostRecentLinkInfo->activeAttribs;
const auto& attribs = mMostRecentLinkInfo->attribs;
if (index >= activeList.size()) {
if (index >= attribs.size()) {
mContext->ErrorInvalidValue("`index` (%i) must be less than %s (%i).",
index, "ACTIVE_ATTRIBS", activeList.size());
index, "ACTIVE_ATTRIBS", attribs.size());
return nullptr;
}
RefPtr<WebGLActiveInfo> ret = activeList[index];
RefPtr<WebGLActiveInfo> ret = attribs[index].mActiveInfo;
return ret.forget();
}
@ -508,15 +576,15 @@ WebGLProgram::GetActiveUniform(GLuint index) const
return ret.forget();
}
const auto& activeList = mMostRecentLinkInfo->activeUniforms;
const auto& uniforms = mMostRecentLinkInfo->uniforms;
if (index >= activeList.size()) {
if (index >= uniforms.size()) {
mContext->ErrorInvalidValue("`index` (%i) must be less than %s (%i).",
index, "ACTIVE_UNIFORMS", activeList.size());
index, "ACTIVE_UNIFORMS", uniforms.size());
return nullptr;
}
RefPtr<WebGLActiveInfo> ret = activeList[index];
RefPtr<WebGLActiveInfo> ret = uniforms[index]->mActiveInfo;
return ret.forget();
}
@ -545,16 +613,11 @@ WebGLProgram::GetAttribLocation(const nsAString& userName_wide) const
const NS_LossyConvertUTF16toASCII userName(userName_wide);
const WebGLActiveInfo* info;
const webgl::AttribInfo* info;
if (!LinkInfo()->FindAttrib(userName, &info))
return -1;
const nsCString& mappedName = info->mBaseMappedName;
gl::GLContext* gl = mContext->GL();
gl->MakeCurrent();
return gl->fGetAttribLocation(mGLName, mappedName.BeginReading());
return GLint(info->mLoc);
}
GLint
@ -658,13 +721,12 @@ WebGLProgram::GetUniformBlockIndex(const nsAString& userName_wide) const
if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex))
return LOCAL_GL_INVALID_INDEX;
RefPtr<const webgl::UniformBlockInfo> info;
const webgl::UniformBlockInfo* info;
if (!LinkInfo()->FindUniformBlock(baseUserName, &info)) {
return LOCAL_GL_INVALID_INDEX;
}
const nsCString& baseMappedName = info->mBaseMappedName;
nsAutoCString mappedName(baseMappedName);
nsAutoCString mappedName(info->mBaseMappedName);
if (isArray) {
mappedName.AppendLiteral("[");
mappedName.AppendInt(uint32_t(arrayIndex));
@ -799,13 +861,11 @@ WebGLProgram::GetUniformLocation(const nsAString& userName_wide) const
if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex))
return nullptr;
const WebGLActiveInfo* activeInfo;
if (!LinkInfo()->FindUniform(baseUserName, &activeInfo))
webgl::UniformInfo* info;
if (!LinkInfo()->FindUniform(baseUserName, &info))
return nullptr;
const nsCString& baseMappedName = activeInfo->mBaseMappedName;
nsAutoCString mappedName(baseMappedName);
nsAutoCString mappedName(info->mActiveInfo->mBaseMappedName);
if (isArray) {
mappedName.AppendLiteral("[");
mappedName.AppendInt(uint32_t(arrayIndex));
@ -820,8 +880,7 @@ WebGLProgram::GetUniformLocation(const nsAString& userName_wide) const
return nullptr;
RefPtr<WebGLUniformLocation> locObj = new WebGLUniformLocation(mContext, LinkInfo(),
loc, arrayIndex,
activeInfo);
info, loc, arrayIndex);
return locObj.forget();
}
@ -846,15 +905,13 @@ WebGLProgram::GetUniformIndices(const dom::Sequence<nsString>& uniformNames,
continue;
}
const WebGLActiveInfo* activeInfo;
if (!LinkInfo()->FindUniform(baseUserName, &activeInfo)) {
webgl::UniformInfo* info;
if (!LinkInfo()->FindUniform(baseUserName, &info)) {
arr.AppendElement(LOCAL_GL_INVALID_INDEX);
continue;
}
const nsCString& baseMappedName = activeInfo->mBaseMappedName;
nsAutoCString mappedName(baseMappedName);
nsAutoCString mappedName(info->mActiveInfo->mBaseMappedName);
if (isArray) {
mappedName.AppendLiteral("[");
mappedName.AppendInt(uint32_t(arrayIndex));
@ -879,8 +936,7 @@ WebGLProgram::UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockB
}
const webgl::LinkedProgramInfo* linkInfo = LinkInfo();
GLuint uniformBlockCount = (GLuint)linkInfo->uniformBlocks.size();
if (uniformBlockIndex >= uniformBlockCount) {
if (uniformBlockIndex >= linkInfo->uniformBlocks.size()) {
mContext->ErrorInvalidValue("getActiveUniformBlockName: index %u invalid.", uniformBlockIndex);
return;
}
@ -1234,6 +1290,50 @@ WebGLProgram::FindUniformBlockByMappedName(const nsACString& mappedName,
////////////////////////////////////////////////////////////////////////////////
bool
webgl::LinkedProgramInfo::FindAttrib(const nsCString& baseUserName,
const webgl::AttribInfo** const out) const
{
for (const auto& attrib : attribs) {
if (attrib.mActiveInfo->mBaseUserName == baseUserName) {
*out = &attrib;
return true;
}
}
return false;
}
bool
webgl::LinkedProgramInfo::FindUniform(const nsCString& baseUserName,
webgl::UniformInfo** const out) const
{
for (const auto& uniform : uniforms) {
if (uniform->mActiveInfo->mBaseUserName == baseUserName) {
*out = uniform;
return true;
}
}
return false;
}
bool
webgl::LinkedProgramInfo::FindUniformBlock(const nsCString& baseUserName,
const webgl::UniformBlockInfo** const out) const
{
for (const auto& block : uniformBlocks) {
if (block->mBaseUserName == baseUserName) {
*out = block;
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
JSObject*
WebGLProgram::WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto)
{

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

@ -35,11 +35,30 @@ template<typename> class Sequence;
namespace webgl {
struct UniformBlockInfo final
: public RefCounted<UniformBlockInfo>
struct AttribInfo final
{
MOZ_DECLARE_REFCOUNTED_TYPENAME(UniformBlockInfo);
const RefPtr<WebGLActiveInfo> mActiveInfo;
uint32_t mLoc;
};
struct UniformInfo final
{
typedef decltype(WebGLContext::mBound2DTextures) TexListT;
const RefPtr<WebGLActiveInfo> mActiveInfo;
const TexListT* const mSamplerTexList;
std::vector<uint32_t> mSamplerValues;
protected:
static const TexListT*
GetTexList(WebGLActiveInfo* activeInfo);
public:
explicit UniformInfo(WebGLActiveInfo* activeInfo);
};
struct UniformBlockInfo final
{
const nsCString mBaseUserName;
const nsCString mBaseMappedName;
@ -57,61 +76,27 @@ struct LinkedProgramInfo final
MOZ_DECLARE_REFCOUNTED_TYPENAME(LinkedProgramInfo)
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(LinkedProgramInfo)
//////
WebGLProgram* const prog;
std::vector<RefPtr<WebGLActiveInfo>> activeAttribs;
std::vector<RefPtr<WebGLActiveInfo>> activeUniforms;
std::vector<AttribInfo> attribs;
std::vector<UniformInfo*> uniforms; // Owns its contents.
std::vector<const UniformBlockInfo*> uniformBlocks; // Owns its contents.
std::vector<RefPtr<WebGLActiveInfo>> transformFeedbackVaryings;
// Needed for Get{Attrib,Uniform}Location. The keys for these are non-mapped
// user-facing `GLActiveInfo::name`s, without any final "[0]".
std::map<nsCString, const WebGLActiveInfo*> attribMap;
std::map<nsCString, const WebGLActiveInfo*> uniformMap;
std::map<nsCString, const WebGLActiveInfo*> transformFeedbackVaryingsMap;
std::vector<RefPtr<UniformBlockInfo>> uniformBlocks;
// Needed for draw call validation.
std::map<const WebGLActiveInfo*, GLuint> activeAttribLocs;
std::vector<UniformInfo*> uniformSamplers;
//////
explicit LinkedProgramInfo(WebGLProgram* prog);
~LinkedProgramInfo();
bool FindAttrib(const nsCString& baseUserName,
const WebGLActiveInfo** const out_activeInfo) const
{
auto itr = attribMap.find(baseUserName);
if (itr == attribMap.end())
return false;
*out_activeInfo = itr->second;
return true;
}
bool FindUniform(const nsCString& baseUserName,
const WebGLActiveInfo** const out_activeInfo) const
{
auto itr = uniformMap.find(baseUserName);
if (itr == uniformMap.end())
return false;
*out_activeInfo = itr->second;
return true;
}
bool FindAttrib(const nsCString& baseUserName, const AttribInfo** const out) const;
bool FindUniform(const nsCString& baseUserName, UniformInfo** const out) const;
bool FindUniformBlock(const nsCString& baseUserName,
RefPtr<const UniformBlockInfo>* const out_info) const
{
const size_t count = uniformBlocks.size();
for (size_t i = 0; i < count; i++) {
if (baseUserName == uniformBlocks[i]->mBaseUserName) {
*out_info = uniformBlocks[i].get();
return true;
}
}
return false;
}
const UniformBlockInfo** const out) const;
};
} // namespace webgl

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

@ -16,34 +16,32 @@ namespace mozilla {
WebGLUniformLocation::WebGLUniformLocation(WebGLContext* webgl,
const webgl::LinkedProgramInfo* linkInfo,
GLuint loc,
size_t arrayIndex,
const WebGLActiveInfo* activeInfo)
webgl::UniformInfo* info, GLuint loc,
size_t arrayIndex)
: WebGLContextBoundObject(webgl)
, mLinkInfo(linkInfo)
, mInfo(info)
, mLoc(loc)
, mArrayIndex(arrayIndex)
, mActiveInfo(activeInfo)
{ }
WebGLUniformLocation::~WebGLUniformLocation()
{ }
bool
WebGLUniformLocation::ValidateForProgram(WebGLProgram* prog, WebGLContext* webgl,
const char* funcName) const
WebGLUniformLocation::ValidateForProgram(WebGLProgram* prog, const char* funcName) const
{
// Check the weak-pointer.
if (!mLinkInfo) {
webgl->ErrorInvalidOperation("%s: This uniform location is obsolete because its"
" program has been successfully relinked.",
funcName);
mContext->ErrorInvalidOperation("%s: This uniform location is obsolete because"
" its program has been successfully relinked.",
funcName);
return false;
}
if (mLinkInfo->prog != prog) {
webgl->ErrorInvalidOperation("%s: This uniform location corresponds to a"
" different program.", funcName);
mContext->ErrorInvalidOperation("%s: This uniform location corresponds to a"
" different program.", funcName);
return false;
}
@ -121,19 +119,22 @@ IsUniformSetterTypeValid(GLenum setterType, GLenum uniformType)
bool
WebGLUniformLocation::ValidateSizeAndType(uint8_t setterElemSize, GLenum setterType,
WebGLContext* webgl, const char* funcName) const
const char* funcName) const
{
MOZ_ASSERT(mLinkInfo);
if (setterElemSize != mActiveInfo->mElemSize) {
webgl->ErrorInvalidOperation("%s: Bad uniform size: %i", funcName,
mActiveInfo->mElemSize);
const auto& uniformElemSize = mInfo->mActiveInfo->mElemSize;
if (setterElemSize != uniformElemSize) {
mContext->ErrorInvalidOperation("%s: Function used differs from uniform size: %i",
funcName, uniformElemSize);
return false;
}
if (!IsUniformSetterTypeValid(setterType, mActiveInfo->mElemType)) {
webgl->ErrorInvalidOperation("%s: Bad uniform type: %i", funcName,
mActiveInfo->mElemSize);
const auto& uniformElemType = mInfo->mActiveInfo->mElemType;
if (!IsUniformSetterTypeValid(setterType, uniformElemType)) {
mContext->ErrorInvalidOperation("%s: Function used is incompatible with uniform"
" type: %i",
funcName, uniformElemType);
return false;
}
@ -142,16 +143,16 @@ WebGLUniformLocation::ValidateSizeAndType(uint8_t setterElemSize, GLenum setterT
bool
WebGLUniformLocation::ValidateArrayLength(uint8_t setterElemSize, size_t setterArraySize,
WebGLContext* webgl, const char* funcName) const
const char* funcName) const
{
MOZ_ASSERT(mLinkInfo);
if (setterArraySize == 0 ||
setterArraySize % setterElemSize)
{
webgl->ErrorInvalidValue("%s: expected an array of length a multiple of"
" %d, got an array of length %d.",
funcName, setterElemSize, setterArraySize);
mContext->ErrorInvalidValue("%s: Expected an array of length a multiple of %d,"
" got an array of length %d.",
funcName, setterElemSize, setterArraySize);
return false;
}
@ -162,55 +163,34 @@ WebGLUniformLocation::ValidateArrayLength(uint8_t setterElemSize, size_t setterA
* highest array element index used, as reported by `GetActiveUniform`, will be
* ignored by GL.
*/
if (!mActiveInfo->mIsArray &&
if (!mInfo->mActiveInfo->mIsArray &&
setterArraySize != setterElemSize)
{
webgl->ErrorInvalidOperation("%s: expected an array of length exactly %d"
" (since this uniform is not an array"
" uniform), got an array of length %d.",
funcName, setterElemSize, setterArraySize);
mContext->ErrorInvalidOperation("%s: Expected an array of length exactly %d"
" (since this uniform is not an array uniform),"
" got an array of length %d.",
funcName, setterElemSize, setterArraySize);
return false;
}
return true;
}
bool
WebGLUniformLocation::ValidateSamplerSetter(GLint value, WebGLContext* webgl,
const char* funcName) const
{
MOZ_ASSERT(mLinkInfo);
if (mActiveInfo->mElemType != LOCAL_GL_SAMPLER_2D &&
mActiveInfo->mElemType != LOCAL_GL_SAMPLER_CUBE)
{
return true;
}
if (value >= 0 && value < (GLint)webgl->GLMaxTextureUnits())
return true;
webgl->ErrorInvalidValue("%s: This uniform location is a sampler, but %d is not a"
" valid texture unit.",
funcName, value);
return false;
}
JS::Value
WebGLUniformLocation::GetUniform(JSContext* js, WebGLContext* webgl) const
WebGLUniformLocation::GetUniform(JSContext* js) const
{
MOZ_ASSERT(mLinkInfo);
uint8_t elemSize = mActiveInfo->mElemSize;
const uint8_t elemSize = mInfo->mActiveInfo->mElemSize;
static const uint8_t kMaxElemSize = 16;
MOZ_ASSERT(elemSize <= kMaxElemSize);
GLuint prog = mLinkInfo->prog->mGLName;
gl::GLContext* gl = webgl->GL();
gl::GLContext* gl = mContext->GL();
gl->MakeCurrent();
switch (mActiveInfo->mElemType) {
switch (mInfo->mActiveInfo->mElemType) {
case LOCAL_GL_INT:
case LOCAL_GL_INT_VEC2:
case LOCAL_GL_INT_VEC3:
@ -237,9 +217,9 @@ WebGLUniformLocation::GetUniform(JSContext* js, WebGLContext* webgl) const
if (elemSize == 1)
return JS::Int32Value(buffer[0]);
JSObject* obj = dom::Int32Array::Create(js, webgl, elemSize, buffer);
JSObject* obj = dom::Int32Array::Create(js, mContext, elemSize, buffer);
if (!obj) {
webgl->ErrorOutOfMemory("getUniform: out of memory");
mContext->ErrorOutOfMemory("getUniform: Out of memory.");
return JS::NullValue();
}
return JS::ObjectOrNullValue(obj);
@ -263,7 +243,7 @@ WebGLUniformLocation::GetUniform(JSContext* js, WebGLContext* webgl) const
JS::RootedValue val(js);
// Be careful: we don't want to convert all of |uv|!
if (!dom::ToJSValue(js, boolBuffer, elemSize, &val)) {
webgl->ErrorOutOfMemory("getUniform: out of memory");
mContext->ErrorOutOfMemory("getUniform: Out of memory.");
return JS::NullValue();
}
return val;
@ -289,9 +269,9 @@ WebGLUniformLocation::GetUniform(JSContext* js, WebGLContext* webgl) const
if (elemSize == 1)
return JS::DoubleValue(buffer[0]);
JSObject* obj = dom::Float32Array::Create(js, webgl, elemSize, buffer);
JSObject* obj = dom::Float32Array::Create(js, mContext, elemSize, buffer);
if (!obj) {
webgl->ErrorOutOfMemory("getUniform: out of memory");
mContext->ErrorOutOfMemory("getUniform: Out of memory.");
return JS::NullValue();
}
return JS::ObjectOrNullValue(obj);
@ -308,9 +288,9 @@ WebGLUniformLocation::GetUniform(JSContext* js, WebGLContext* webgl) const
if (elemSize == 1)
return JS::DoubleValue(buffer[0]); // This is Double because only Int32 is special cased.
JSObject* obj = dom::Uint32Array::Create(js, webgl, elemSize, buffer);
JSObject* obj = dom::Uint32Array::Create(js, mContext, elemSize, buffer);
if (!obj) {
webgl->ErrorOutOfMemory("getUniform: out of memory");
mContext->ErrorOutOfMemory("getUniform: Out of memory.");
return JS::NullValue();
}
return JS::ObjectOrNullValue(obj);

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

@ -39,24 +39,25 @@ public:
return mContext;
}
//////
const WeakPtr<const webgl::LinkedProgramInfo> mLinkInfo;
webgl::UniformInfo* const mInfo;
const GLuint mLoc;
const size_t mArrayIndex;
const WebGLActiveInfo* const mActiveInfo;
//////
WebGLUniformLocation(WebGLContext* webgl, const webgl::LinkedProgramInfo* linkInfo,
GLuint loc, size_t arrayIndex, const WebGLActiveInfo* activeInfo);
webgl::UniformInfo* info, GLuint loc, size_t arrayIndex);
bool ValidateForProgram(WebGLProgram* prog, WebGLContext* webgl,
const char* funcName) const;
bool ValidateSamplerSetter(GLint value, WebGLContext* webgl,
const char* funcName) const;
bool ValidateForProgram(WebGLProgram* prog, const char* funcName) const;
bool ValidateSizeAndType(uint8_t setterElemSize, GLenum setterType,
WebGLContext* webgl, const char* funcName) const;
const char* funcName) const;
bool ValidateArrayLength(uint8_t setterElemSize, size_t setterArraySize,
WebGLContext* webgl, const char* funcName) const;
const char* funcName) const;
JS::Value GetUniform(JSContext* js, WebGLContext* webgl) const;
JS::Value GetUniform(JSContext* js) const;
// Needed for certain helper functions like ValidateObject.
// `WebGLUniformLocation`s can't be 'Deleted' in the WebGL sense.