summaryrefslogtreecommitdiffstats
path: root/dom/canvas/ClientWebGLContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/ClientWebGLContext.cpp')
-rw-r--r--dom/canvas/ClientWebGLContext.cpp139
1 files changed, 56 insertions, 83 deletions
diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp
index bde265f9a0..1614d2ead2 100644
--- a/dom/canvas/ClientWebGLContext.cpp
+++ b/dom/canvas/ClientWebGLContext.cpp
@@ -847,7 +847,12 @@ bool ClientWebGLContext::CreateHostContext(const uvec2& requestedSize) {
ShouldResistFingerprinting(RFPTarget::WebGLRenderCapability);
const auto principalKey = GetPrincipalHashValue();
const auto initDesc = webgl::InitContextDesc{
- mIsWebGL2, resistFingerprinting, requestedSize, options, principalKey};
+ .isWebgl2 = mIsWebGL2,
+ .resistFingerprinting = resistFingerprinting,
+ .principalKey = principalKey,
+ .size = requestedSize,
+ .options = options,
+ };
// -
@@ -1264,28 +1269,13 @@ RefPtr<gfx::DataSourceSurface> ClientWebGLContext::BackBufferSnapshot() {
MOZ_ASSERT(static_cast<uint32_t>(map.GetStride()) == stride);
const auto desc = webgl::ReadPixelsDesc{{0, 0}, size};
- const auto range = Range<uint8_t>(map.GetData(), stride * size.y);
- if (!DoReadPixels(desc, range)) return nullptr;
-
- const auto begin = range.begin().get();
+ const auto pixels = Span<uint8_t>(map.GetData(), stride * size.y);
+ if (!DoReadPixels(desc, pixels)) return nullptr;
- std::vector<uint8_t> temp;
- temp.resize(stride);
- for (const auto i : IntegerRange(size.y / 2)) {
- const auto top = begin + stride * i;
- const auto bottom = begin + stride * (size.y - 1 - i);
- memcpy(temp.data(), top, stride);
- memcpy(top, bottom, stride);
- gfxUtils::ConvertBGRAtoRGBA(top, stride);
-
- memcpy(bottom, temp.data(), stride);
- gfxUtils::ConvertBGRAtoRGBA(bottom, stride);
- }
-
- if (size.y % 2) {
- const auto middle = begin + stride * (size.y / 2);
- gfxUtils::ConvertBGRAtoRGBA(middle, stride);
- }
+ // RGBA->BGRA and flip-y.
+ MOZ_RELEASE_ASSERT(gfx::SwizzleYFlipData(
+ pixels.data(), stride, gfx::SurfaceFormat::R8G8B8A8, pixels.data(),
+ stride, gfx::SurfaceFormat::B8G8R8A8, {size.x, size.y}));
}
return surf;
@@ -3419,7 +3409,7 @@ void ClientWebGLContext::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
const auto& child = notLost->outOfProcess;
child->FlushPendingCmds();
mozilla::ipc::Shmem rawShmem;
- if (!child->SendGetBufferSubData(target, srcByteOffset, destView->length(),
+ if (!child->SendGetBufferSubData(target, srcByteOffset, destView->size(),
&rawShmem)) {
return;
}
@@ -3429,14 +3419,13 @@ void ClientWebGLContext::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
return;
}
- const auto shmemView = shmem.ByteRange();
- MOZ_RELEASE_ASSERT(shmemView.length() == 1 + destView->length());
+ const auto shmemView = Span{shmem.ByteRange()};
+ MOZ_RELEASE_ASSERT(shmemView.size() == 1 + destView->size());
- const auto ok = bool(*(shmemView.begin().get()));
- const auto srcView =
- Range<const uint8_t>{shmemView.begin() + 1, shmemView.end()};
+ const auto ok = bool(shmemView[0]);
+ const auto srcView = shmemView.subspan(1);
if (ok) {
- Memcpy(destView->begin(), srcView.begin(), srcView.length());
+ Memcpy(&*destView, srcView);
}
});
}
@@ -3463,8 +3452,8 @@ void ClientWebGLContext::BufferData(
if (!ValidateNonNull("src", maybeSrc)) return;
const auto& src = maybeSrc.Value();
- src.ProcessFixedData([&](const Span<uint8_t>& aData) {
- Run<RPROC(BufferData)>(target, RawBuffer<>(aData), usage);
+ src.ProcessFixedData([&](const Span<const uint8_t>& aData) {
+ Run<RPROC(BufferData)>(target, aData, usage);
});
}
@@ -3481,7 +3470,7 @@ void ClientWebGLContext::BufferData(GLenum target,
if (!range) {
return;
}
- Run<RPROC(BufferData)>(target, RawBuffer<>(*range), usage);
+ Run<RPROC(BufferData)>(target, *range, usage);
});
}
@@ -3491,8 +3480,8 @@ void ClientWebGLContext::BufferSubData(GLenum target,
WebGLsizeiptr dstByteOffset,
const dom::ArrayBuffer& src) {
const FuncScope funcScope(*this, "bufferSubData");
- src.ProcessFixedData([&](const Span<uint8_t>& aData) {
- Run<RPROC(BufferSubData)>(target, dstByteOffset, RawBuffer<>(aData),
+ src.ProcessFixedData([&](const Span<const uint8_t>& aData) {
+ Run<RPROC(BufferSubData)>(target, dstByteOffset, aData,
/* unsynchronized */ false);
});
}
@@ -3511,7 +3500,7 @@ void ClientWebGLContext::BufferSubData(GLenum target,
if (!range) {
return;
}
- Run<RPROC(BufferSubData)>(target, dstByteOffset, RawBuffer<>(*range),
+ Run<RPROC(BufferSubData)>(target, dstByteOffset, *range,
/* unsynchronized */ false);
});
}
@@ -3811,9 +3800,7 @@ void ClientWebGLContext::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1,
void ClientWebGLContext::InvalidateFramebuffer(
GLenum target, const dom::Sequence<GLenum>& attachments,
ErrorResult& unused) {
- const auto range = MakeRange(attachments);
- const auto& buffer = RawBufferView(range);
- Run<RPROC(InvalidateFramebuffer)>(target, buffer);
+ Run<RPROC(InvalidateFramebuffer)>(target, Span{attachments});
// Never invalidate the backbuffer, so never needs AfterDrawCall.
}
@@ -3821,9 +3808,8 @@ void ClientWebGLContext::InvalidateFramebuffer(
void ClientWebGLContext::InvalidateSubFramebuffer(
GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y,
GLsizei width, GLsizei height, ErrorResult& unused) {
- const auto range = MakeRange(attachments);
- const auto& buffer = RawBufferView(range);
- Run<RPROC(InvalidateSubFramebuffer)>(target, buffer, x, y, width, height);
+ Run<RPROC(InvalidateSubFramebuffer)>(target, Span{attachments}, x, y, width,
+ height);
// Never invalidate the backbuffer, so never needs AfterDrawCall.
}
@@ -4102,13 +4088,11 @@ Range<T> SubRange(const Range<T>& full, const size_t offset,
return Range<T>{newBegin, newBegin + length};
}
-Maybe<Range<const uint8_t>> GetRangeFromData(const Span<uint8_t>& data,
- size_t bytesPerElem,
- GLuint elemOffset,
- GLuint elemCountOverride) {
- const auto byteRange = Range(data); // In bytes.
-
- auto elemCount = byteRange.length() / bytesPerElem;
+Maybe<Span<const uint8_t>> GetRangeFromData(const Span<uint8_t>& data,
+ size_t bytesPerElem,
+ GLuint elemOffset,
+ GLuint elemCountOverride) {
+ auto elemCount = data.size() / bytesPerElem;
if (elemOffset > elemCount) return {};
elemCount -= elemOffset;
@@ -4116,9 +4100,8 @@ Maybe<Range<const uint8_t>> GetRangeFromData(const Span<uint8_t>& data,
if (elemCountOverride > elemCount) return {};
elemCount = elemCountOverride;
}
- const auto subrange =
- SubRange(byteRange, elemOffset * bytesPerElem, elemCount * bytesPerElem);
- return Some(subrange);
+ return Some(
+ data.subspan(elemOffset * bytesPerElem, elemCount * bytesPerElem));
}
// -
@@ -4165,7 +4148,8 @@ void webgl::TexUnpackBlobDesc::Shrink(const webgl::PackingInfo& pi) {
CheckedInt<size_t>(unpack.metrics.bytesPerRowStride) *
unpack.metrics.totalRows;
if (bytesUpperBound.isValid()) {
- cpuData->Shrink(bytesUpperBound.value());
+ auto& span = *cpuData;
+ span = span.subspan(0, std::min(span.size(), bytesUpperBound.value()));
}
}
}
@@ -4241,7 +4225,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
return Some(webgl::TexUnpackBlobDesc{imageTarget,
size.value(),
gfxAlphaType::NonPremult,
- Some(RawBuffer<>{*range}),
+ Some(*range),
{}});
});
}
@@ -4378,12 +4362,9 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
const auto& contextInfo = mNotLost->info;
const auto fallbackReason = [&]() -> Maybe<std::string> {
- if (!respecFormat) {
- return Some(std::string{
- "Fast uploads not supported for TexSubImage. Use TexImage."});
- }
- auto fallbackReason = BlitPreventReason(
- level, offset, respecFormat, pi, *desc, contextInfo.isRgb8Renderable);
+ auto fallbackReason =
+ BlitPreventReason(level, offset, respecFormat, pi, *desc,
+ contextInfo.optionalRenderableFormatBits);
if (fallbackReason) return fallbackReason;
const bool canUploadViaSd = contextInfo.uploadableSdTypes[sdType];
@@ -4588,7 +4569,7 @@ void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims,
RunWithGCData<RPROC(CompressedTexImage)>(
std::move(aNoGC), sub, imageTarget, static_cast<uint32_t>(level),
- format, CastUvec3(offset), CastUvec3(isize), RawBuffer<>{*range},
+ format, CastUvec3(offset), CastUvec3(isize), *range,
static_cast<uint32_t>(pboImageSize), Maybe<uint64_t>());
return;
});
@@ -4603,8 +4584,8 @@ void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims,
Run<RPROC(CompressedTexImage)>(
sub, imageTarget, static_cast<uint32_t>(level), format, CastUvec3(offset),
- CastUvec3(isize), RawBuffer<>(), static_cast<uint32_t>(pboImageSize),
- Some(*src.mPboOffset));
+ CastUvec3(isize), Span<const uint8_t>{},
+ static_cast<uint32_t>(pboImageSize), Some(*src.mPboOffset));
}
void ClientWebGLContext::CopyTexImage(uint8_t funcDims, GLenum imageTarget,
@@ -4876,9 +4857,8 @@ void ClientWebGLContext::UniformData(const GLenum funcElemType,
const auto begin =
reinterpret_cast<const webgl::UniformDataVal*>(bytes.begin().get()) +
elemOffset;
- const auto range = Range{begin, availCount};
- RunWithGCData<RPROC(UniformData)>(std::move(nogc), locId, transpose,
- RawBuffer{range});
+ const auto range = Span{begin, availCount};
+ RunWithGCData<RPROC(UniformData)>(std::move(nogc), locId, transpose, range);
}
// -
@@ -5095,7 +5075,7 @@ void ClientWebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
}
bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
- const Range<uint8_t> dest) const {
+ const Span<uint8_t> dest) const {
const auto notLost =
mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF.
if (!notLost) return false;
@@ -5107,7 +5087,7 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
const auto& child = notLost->outOfProcess;
child->FlushPendingCmds();
webgl::ReadPixelsResultIpc res = {};
- if (!child->SendReadPixels(desc, dest.length(), &res)) {
+ if (!child->SendReadPixels(desc, dest.size(), &res)) {
res = {};
}
if (!res.byteStride || !res.shmem) return false;
@@ -5119,7 +5099,7 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
return false;
}
- const auto& shmemBytes = shmem.ByteRange();
+ const auto& shmemBytes = Span{shmem.ByteRange()};
const auto pii = webgl::PackingInfoInfo::For(desc.pi);
if (!pii) {
@@ -5136,19 +5116,13 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
const auto xByteSize = bpp * static_cast<uint32_t>(subrect.width);
const ptrdiff_t byteOffset = packRect.y * byteStride + packRect.x * bpp;
- auto srcItr = shmemBytes.begin() + byteOffset;
- auto destItr = dest.begin() + byteOffset;
+ const auto srcSubrect = shmemBytes.subspan(byteOffset);
+ const auto destSubrect = dest.subspan(byteOffset);
for (const auto i : IntegerRange(subrect.height)) {
- if (i) {
- // Don't trigger an assert on the last loop by pushing a RangedPtr past
- // its bounds.
- srcItr += byteStride;
- destItr += byteStride;
- MOZ_RELEASE_ASSERT(srcItr + xByteSize <= shmemBytes.end());
- MOZ_RELEASE_ASSERT(destItr + xByteSize <= dest.end());
- }
- Memcpy(destItr, srcItr, xByteSize);
+ const auto srcRow = srcSubrect.subspan(i * byteStride, xByteSize);
+ const auto destRow = destSubrect.subspan(i * byteStride, xByteSize);
+ Memcpy(&destRow, srcRow);
}
return true;
@@ -5858,7 +5832,7 @@ void ClientWebGLContext::AttachShader(WebGLProgramJS& prog,
void ClientWebGLContext::BindAttribLocation(WebGLProgramJS& prog,
const GLuint location,
const nsAString& name) const {
- const FuncScope funcScope(*this, "detachShader");
+ const FuncScope funcScope(*this, "bindAttribLocation");
if (IsContextLost()) return;
if (!prog.ValidateUsable(*this, "program")) return;
@@ -6572,7 +6546,7 @@ const webgl::LinkResult& ClientWebGLContext::GetLinkResult(
// ---------------------------
-Maybe<Range<uint8_t>> ClientWebGLContext::ValidateArrayBufferView(
+Maybe<Span<uint8_t>> ClientWebGLContext::ValidateArrayBufferView(
const Span<uint8_t>& bytes, size_t elemSize, GLuint elemOffset,
GLuint elemCountOverride, const GLenum errorEnum) const {
size_t elemCount = bytes.Length() / elemSize;
@@ -6590,8 +6564,7 @@ Maybe<Range<uint8_t>> ClientWebGLContext::ValidateArrayBufferView(
elemCount = elemCountOverride;
}
- return Some(Range<uint8_t>(
- bytes.Subspan(elemOffset * elemSize, elemCount * elemSize)));
+ return Some(bytes.Subspan(elemOffset * elemSize, elemCount * elemSize));
}
// ---------------------------