mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1638568 - E.g. uniform1i(null, ...) should check avail len not total len. r=lsalzman
Also: * Propagate null-location UniformDatas to host * Move transpose validation to host-side Differential Revision: https://phabricator.services.mozilla.com/D98243
This commit is contained in:
parent
658d166b85
commit
47dcac63b7
@ -4262,11 +4262,6 @@ void ClientWebGLContext::UniformData(const GLenum funcElemType,
|
||||
const FuncScope funcScope(*this, "uniform setter");
|
||||
if (IsContextLost()) return;
|
||||
|
||||
if (!mIsWebGL2 && transpose) {
|
||||
EnqueueError(LOCAL_GL_INVALID_VALUE, "`transpose`:true requires WebGL 2.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& activeLinkResult = GetActiveLinkResult();
|
||||
if (!activeLinkResult) {
|
||||
EnqueueError(LOCAL_GL_INVALID_OPERATION, "No active linked Program.");
|
||||
@ -4292,56 +4287,57 @@ void ClientWebGLContext::UniformData(const GLenum funcElemType,
|
||||
|
||||
// -
|
||||
|
||||
if (!loc) {
|
||||
// We need to catch INVALID_VALUEs from bad-sized `bytes`. :S
|
||||
// For non-null `loc`, the Host side handles this safely.
|
||||
const auto lengthInType = bytes.length() / sizeof(float);
|
||||
const auto channels = ElemTypeComponents(funcElemType);
|
||||
if (!lengthInType || lengthInType % channels != 0) {
|
||||
EnqueueError(LOCAL_GL_INVALID_VALUE,
|
||||
"`values` length (%u) must be a positive integer multiple "
|
||||
"of size of %s.",
|
||||
lengthInType, EnumString(funcElemType).c_str());
|
||||
const auto channels = ElemTypeComponents(funcElemType);
|
||||
if (!availCount || availCount % channels != 0) {
|
||||
EnqueueError(LOCAL_GL_INVALID_VALUE,
|
||||
"`values` length (%u) must be a positive "
|
||||
"integer multiple of size of %s.",
|
||||
availCount, EnumString(funcElemType).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
uint32_t locId = -1;
|
||||
if (MOZ_LIKELY(loc)) {
|
||||
locId = loc->mLocation;
|
||||
if (!loc->ValidateUsable(*this, "location")) return;
|
||||
|
||||
// -
|
||||
|
||||
const auto& reqLinkInfo = loc->mParent.lock();
|
||||
if (reqLinkInfo.get() != activeLinkResult) {
|
||||
EnqueueError(LOCAL_GL_INVALID_OPERATION,
|
||||
"UniformLocation is not from the current active Program.");
|
||||
return;
|
||||
}
|
||||
return; // All that validation for a no-op!
|
||||
}
|
||||
if (!loc->ValidateUsable(*this, "location")) return;
|
||||
|
||||
// -
|
||||
// -
|
||||
|
||||
const auto& reqLinkInfo = loc->mParent.lock();
|
||||
if (reqLinkInfo.get() != activeLinkResult) {
|
||||
EnqueueError(LOCAL_GL_INVALID_OPERATION,
|
||||
"UniformLocation is not from the current active Program.");
|
||||
return;
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
bool funcMatchesLocation = false;
|
||||
for (const auto allowed : loc->mValidUploadElemTypes) {
|
||||
funcMatchesLocation |= (funcElemType == allowed);
|
||||
}
|
||||
if (MOZ_UNLIKELY(!funcMatchesLocation)) {
|
||||
std::string validSetters;
|
||||
bool funcMatchesLocation = false;
|
||||
for (const auto allowed : loc->mValidUploadElemTypes) {
|
||||
validSetters += EnumString(allowed);
|
||||
validSetters += '/';
|
||||
funcMatchesLocation |= (funcElemType == allowed);
|
||||
}
|
||||
validSetters.pop_back(); // Cheekily discard the extra trailing '/'.
|
||||
if (MOZ_UNLIKELY(!funcMatchesLocation)) {
|
||||
std::string validSetters;
|
||||
for (const auto allowed : loc->mValidUploadElemTypes) {
|
||||
validSetters += EnumString(allowed);
|
||||
validSetters += '/';
|
||||
}
|
||||
validSetters.pop_back(); // Cheekily discard the extra trailing '/'.
|
||||
|
||||
EnqueueError(LOCAL_GL_INVALID_OPERATION,
|
||||
"Uniform's `type` requires uniform setter of type %s.",
|
||||
validSetters.c_str());
|
||||
return;
|
||||
EnqueueError(LOCAL_GL_INVALID_OPERATION,
|
||||
"Uniform's `type` requires uniform setter of type %s.",
|
||||
validSetters.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
const auto ptr = bytes.begin().get() + (elemOffset * sizeof(float));
|
||||
const auto range = Range<const uint8_t>{ptr, availCount * sizeof(float)};
|
||||
Run<RPROC(UniformData)>(loc->mLocation, transpose, RawBuffer<>(range));
|
||||
Run<RPROC(UniformData)>(locId, transpose, RawBuffer<>(range));
|
||||
}
|
||||
|
||||
// -
|
||||
|
@ -1288,11 +1288,22 @@ void WebGLContext::StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
|
||||
void WebGLContext::UniformData(const uint32_t loc, const bool transpose,
|
||||
const Range<const uint8_t>& data) const {
|
||||
const FuncScope funcScope(*this, "uniform setter");
|
||||
|
||||
if (!IsWebGL2() && transpose) {
|
||||
GenerateError(LOCAL_GL_INVALID_VALUE, "`transpose`:true requires WebGL 2.");
|
||||
return;
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
const auto& link = mActiveProgramLinkInfo;
|
||||
if (!link) return;
|
||||
|
||||
const auto locInfo = MaybeFind(link->locationMap, loc);
|
||||
if (!locInfo) return;
|
||||
if (!locInfo) {
|
||||
// Null WebGLUniformLocations become -1, which will end up here.
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& validationInfo = locInfo->info;
|
||||
const auto& activeInfo = validationInfo.info;
|
||||
@ -1302,20 +1313,11 @@ void WebGLContext::UniformData(const uint32_t loc, const bool transpose,
|
||||
// -
|
||||
|
||||
const auto lengthInType = data.length() / sizeof(float);
|
||||
if (!lengthInType || lengthInType % channels != 0) {
|
||||
GenerateError(LOCAL_GL_INVALID_VALUE,
|
||||
"(uniform %s) `values` length (%u) must be a positive "
|
||||
"integer multiple of "
|
||||
"size of %s.",
|
||||
activeInfo.name.c_str(), lengthInType,
|
||||
EnumString(activeInfo.elemType).c_str());
|
||||
return;
|
||||
}
|
||||
const auto elemCount = lengthInType / channels;
|
||||
if (elemCount > 1 && !validationInfo.isArray) {
|
||||
GenerateError(
|
||||
LOCAL_GL_INVALID_OPERATION,
|
||||
"(uniform %s) `values` length (%u) must exactle match size of %s.",
|
||||
"(uniform %s) `values` length (%u) must exactly match size of %s.",
|
||||
activeInfo.name.c_str(), lengthInType,
|
||||
EnumString(activeInfo.elemType).c_str());
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user