Backed out 7 changesets (bug 1878930) for causing build bustages @ dom/canvas/WebGLTypes.h CLOSED TREE

Backed out changeset 631db0feebb4 (bug 1878930)
Backed out changeset 72ab4dbbf8ed (bug 1878930)
Backed out changeset e5119acd8c8f (bug 1878930)
Backed out changeset 3cd4b2423281 (bug 1878930)
Backed out changeset 4a5512ff4424 (bug 1878930)
Backed out changeset 6f5c64075e31 (bug 1878930)
Backed out changeset fb3b3487a529 (bug 1878930)
This commit is contained in:
Sandor Molnar 2024-02-20 21:25:02 +02:00
Родитель 3e1c394721
Коммит d16ed2c545
13 изменённых файлов: 212 добавлений и 127 удалений

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

@ -1264,12 +1264,28 @@ RefPtr<gfx::DataSourceSurface> ClientWebGLContext::BackBufferSnapshot() {
MOZ_ASSERT(static_cast<uint32_t>(map.GetStride()) == stride); MOZ_ASSERT(static_cast<uint32_t>(map.GetStride()) == stride);
const auto desc = webgl::ReadPixelsDesc{{0, 0}, size}; const auto desc = webgl::ReadPixelsDesc{{0, 0}, size};
const auto pixels = Span<uint8_t>(map.GetData(), stride * size.y); const auto range = Range<uint8_t>(map.GetData(), stride * size.y);
if (!DoReadPixels(desc, pixels)) return nullptr; if (!DoReadPixels(desc, range)) return nullptr;
// RGBA->BGRA and flip-y. const auto begin = range.begin().get();
MOZ_RELEASE_ASSERT(gfx::SwizzleYFlipData(pixels.data(), stride, gfx::SurfaceFormat::R8G8B8A8,
pixels.data(), stride, gfx::SurfaceFormat::B8G8R8A8, {size.x, size.y})); 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);
}
} }
return surf; return surf;
@ -3403,7 +3419,7 @@ void ClientWebGLContext::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
const auto& child = notLost->outOfProcess; const auto& child = notLost->outOfProcess;
child->FlushPendingCmds(); child->FlushPendingCmds();
mozilla::ipc::Shmem rawShmem; mozilla::ipc::Shmem rawShmem;
if (!child->SendGetBufferSubData(target, srcByteOffset, destView->size(), if (!child->SendGetBufferSubData(target, srcByteOffset, destView->length(),
&rawShmem)) { &rawShmem)) {
return; return;
} }
@ -3413,13 +3429,14 @@ void ClientWebGLContext::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
return; return;
} }
const auto shmemView = Span{shmem.ByteRange()}; const auto shmemView = shmem.ByteRange();
MOZ_RELEASE_ASSERT(shmemView.size() == 1 + destView->size()); MOZ_RELEASE_ASSERT(shmemView.length() == 1 + destView->length());
const auto ok = bool(shmemView[0]); const auto ok = bool(*(shmemView.begin().get()));
const auto srcView = shmemView.subspan(1); const auto srcView =
Range<const uint8_t>{shmemView.begin() + 1, shmemView.end()};
if (ok) { if (ok) {
Memcpy(&*destView, srcView); Memcpy(destView->begin(), srcView.begin(), srcView.length());
} }
}); });
} }
@ -3446,8 +3463,8 @@ void ClientWebGLContext::BufferData(
if (!ValidateNonNull("src", maybeSrc)) return; if (!ValidateNonNull("src", maybeSrc)) return;
const auto& src = maybeSrc.Value(); const auto& src = maybeSrc.Value();
src.ProcessFixedData([&](const Span<const uint8_t>& aData) { src.ProcessFixedData([&](const Span<uint8_t>& aData) {
Run<RPROC(BufferData)>(target, aData, usage); Run<RPROC(BufferData)>(target, RawBuffer<>(aData), usage);
}); });
} }
@ -3464,7 +3481,7 @@ void ClientWebGLContext::BufferData(GLenum target,
if (!range) { if (!range) {
return; return;
} }
Run<RPROC(BufferData)>(target, *range, usage); Run<RPROC(BufferData)>(target, RawBuffer<>(*range), usage);
}); });
} }
@ -3474,8 +3491,8 @@ void ClientWebGLContext::BufferSubData(GLenum target,
WebGLsizeiptr dstByteOffset, WebGLsizeiptr dstByteOffset,
const dom::ArrayBuffer& src) { const dom::ArrayBuffer& src) {
const FuncScope funcScope(*this, "bufferSubData"); const FuncScope funcScope(*this, "bufferSubData");
src.ProcessFixedData([&](const Span<const uint8_t>& aData) { src.ProcessFixedData([&](const Span<uint8_t>& aData) {
Run<RPROC(BufferSubData)>(target, dstByteOffset, aData, Run<RPROC(BufferSubData)>(target, dstByteOffset, RawBuffer<>(aData),
/* unsynchronized */ false); /* unsynchronized */ false);
}); });
} }
@ -3494,7 +3511,7 @@ void ClientWebGLContext::BufferSubData(GLenum target,
if (!range) { if (!range) {
return; return;
} }
Run<RPROC(BufferSubData)>(target, dstByteOffset, *range, Run<RPROC(BufferSubData)>(target, dstByteOffset, RawBuffer<>(*range),
/* unsynchronized */ false); /* unsynchronized */ false);
}); });
} }
@ -3794,7 +3811,9 @@ void ClientWebGLContext::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1,
void ClientWebGLContext::InvalidateFramebuffer( void ClientWebGLContext::InvalidateFramebuffer(
GLenum target, const dom::Sequence<GLenum>& attachments, GLenum target, const dom::Sequence<GLenum>& attachments,
ErrorResult& unused) { ErrorResult& unused) {
Run<RPROC(InvalidateFramebuffer)>(target, Span{attachments}); const auto range = MakeRange(attachments);
const auto& buffer = RawBufferView(range);
Run<RPROC(InvalidateFramebuffer)>(target, buffer);
// Never invalidate the backbuffer, so never needs AfterDrawCall. // Never invalidate the backbuffer, so never needs AfterDrawCall.
} }
@ -3802,8 +3821,9 @@ void ClientWebGLContext::InvalidateFramebuffer(
void ClientWebGLContext::InvalidateSubFramebuffer( void ClientWebGLContext::InvalidateSubFramebuffer(
GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y, GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y,
GLsizei width, GLsizei height, ErrorResult& unused) { GLsizei width, GLsizei height, ErrorResult& unused) {
Run<RPROC(InvalidateSubFramebuffer)>(target, Span{attachments}, x, y, width, const auto range = MakeRange(attachments);
height); const auto& buffer = RawBufferView(range);
Run<RPROC(InvalidateSubFramebuffer)>(target, buffer, x, y, width, height);
// Never invalidate the backbuffer, so never needs AfterDrawCall. // Never invalidate the backbuffer, so never needs AfterDrawCall.
} }
@ -4082,11 +4102,13 @@ Range<T> SubRange(const Range<T>& full, const size_t offset,
return Range<T>{newBegin, newBegin + length}; return Range<T>{newBegin, newBegin + length};
} }
Maybe<Span<const uint8_t>> GetRangeFromData(const Span<uint8_t>& data, Maybe<Range<const uint8_t>> GetRangeFromData(const Span<uint8_t>& data,
size_t bytesPerElem, size_t bytesPerElem,
GLuint elemOffset, GLuint elemOffset,
GLuint elemCountOverride) { GLuint elemCountOverride) {
auto elemCount = data.size() / bytesPerElem; const auto byteRange = Range(data); // In bytes.
auto elemCount = byteRange.length() / bytesPerElem;
if (elemOffset > elemCount) return {}; if (elemOffset > elemCount) return {};
elemCount -= elemOffset; elemCount -= elemOffset;
@ -4094,8 +4116,9 @@ Maybe<Span<const uint8_t>> GetRangeFromData(const Span<uint8_t>& data,
if (elemCountOverride > elemCount) return {}; if (elemCountOverride > elemCount) return {};
elemCount = elemCountOverride; elemCount = elemCountOverride;
} }
return Some( const auto subrange =
data.subspan(elemOffset * bytesPerElem, elemCount * bytesPerElem)); SubRange(byteRange, elemOffset * bytesPerElem, elemCount * bytesPerElem);
return Some(subrange);
} }
// - // -
@ -4142,8 +4165,7 @@ void webgl::TexUnpackBlobDesc::Shrink(const webgl::PackingInfo& pi) {
CheckedInt<size_t>(unpack.metrics.bytesPerRowStride) * CheckedInt<size_t>(unpack.metrics.bytesPerRowStride) *
unpack.metrics.totalRows; unpack.metrics.totalRows;
if (bytesUpperBound.isValid()) { if (bytesUpperBound.isValid()) {
auto& span = *cpuData; cpuData->Shrink(bytesUpperBound.value());
span = span.subspan(0, std::min(span.size(), bytesUpperBound.value()));
} }
} }
} }
@ -4219,7 +4241,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
return Some(webgl::TexUnpackBlobDesc{imageTarget, return Some(webgl::TexUnpackBlobDesc{imageTarget,
size.value(), size.value(),
gfxAlphaType::NonPremult, gfxAlphaType::NonPremult,
Some(*range), Some(RawBuffer<>{*range}),
{}}); {}});
}); });
} }
@ -4566,7 +4588,7 @@ void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims,
RunWithGCData<RPROC(CompressedTexImage)>( RunWithGCData<RPROC(CompressedTexImage)>(
std::move(aNoGC), sub, imageTarget, static_cast<uint32_t>(level), std::move(aNoGC), sub, imageTarget, static_cast<uint32_t>(level),
format, CastUvec3(offset), CastUvec3(isize), *range, format, CastUvec3(offset), CastUvec3(isize), RawBuffer<>{*range},
static_cast<uint32_t>(pboImageSize), Maybe<uint64_t>()); static_cast<uint32_t>(pboImageSize), Maybe<uint64_t>());
return; return;
}); });
@ -4581,8 +4603,8 @@ void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims,
Run<RPROC(CompressedTexImage)>( Run<RPROC(CompressedTexImage)>(
sub, imageTarget, static_cast<uint32_t>(level), format, CastUvec3(offset), sub, imageTarget, static_cast<uint32_t>(level), format, CastUvec3(offset),
CastUvec3(isize), Span<const uint8_t>{}, CastUvec3(isize), RawBuffer<>(), static_cast<uint32_t>(pboImageSize),
static_cast<uint32_t>(pboImageSize), Some(*src.mPboOffset)); Some(*src.mPboOffset));
} }
void ClientWebGLContext::CopyTexImage(uint8_t funcDims, GLenum imageTarget, void ClientWebGLContext::CopyTexImage(uint8_t funcDims, GLenum imageTarget,
@ -4854,8 +4876,9 @@ void ClientWebGLContext::UniformData(const GLenum funcElemType,
const auto begin = const auto begin =
reinterpret_cast<const webgl::UniformDataVal*>(bytes.begin().get()) + reinterpret_cast<const webgl::UniformDataVal*>(bytes.begin().get()) +
elemOffset; elemOffset;
const auto range = Span{begin, availCount}; const auto range = Range{begin, availCount};
RunWithGCData<RPROC(UniformData)>(std::move(nogc), locId, transpose, range); RunWithGCData<RPROC(UniformData)>(std::move(nogc), locId, transpose,
RawBuffer{range});
} }
// - // -
@ -5072,7 +5095,7 @@ void ClientWebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
} }
bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc, bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
const Span<uint8_t> dest) const { const Range<uint8_t> dest) const {
const auto notLost = const auto notLost =
mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF.
if (!notLost) return false; if (!notLost) return false;
@ -5084,7 +5107,7 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
const auto& child = notLost->outOfProcess; const auto& child = notLost->outOfProcess;
child->FlushPendingCmds(); child->FlushPendingCmds();
webgl::ReadPixelsResultIpc res = {}; webgl::ReadPixelsResultIpc res = {};
if (!child->SendReadPixels(desc, dest.size(), &res)) { if (!child->SendReadPixels(desc, dest.length(), &res)) {
res = {}; res = {};
} }
if (!res.byteStride || !res.shmem) return false; if (!res.byteStride || !res.shmem) return false;
@ -5096,7 +5119,7 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
return false; return false;
} }
const auto& shmemBytes = Span{shmem.ByteRange()}; const auto& shmemBytes = shmem.ByteRange();
const auto pii = webgl::PackingInfoInfo::For(desc.pi); const auto pii = webgl::PackingInfoInfo::For(desc.pi);
if (!pii) { if (!pii) {
@ -5113,13 +5136,19 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
const auto xByteSize = bpp * static_cast<uint32_t>(subrect.width); const auto xByteSize = bpp * static_cast<uint32_t>(subrect.width);
const ptrdiff_t byteOffset = packRect.y * byteStride + packRect.x * bpp; const ptrdiff_t byteOffset = packRect.y * byteStride + packRect.x * bpp;
const auto srcSubrect = shmemBytes.subspan(byteOffset); auto srcItr = shmemBytes.begin() + byteOffset;
const auto destSubrect = dest.subspan(byteOffset); auto destItr = dest.begin() + byteOffset;
for (const auto i : IntegerRange(subrect.height)) { for (const auto i : IntegerRange(subrect.height)) {
const auto srcRow = srcSubrect.subspan(i * byteStride, xByteSize); if (i) {
const auto destRow = destSubrect.subspan(i * byteStride, xByteSize); // Don't trigger an assert on the last loop by pushing a RangedPtr past
Memcpy(&destRow, srcRow); // its bounds.
srcItr += byteStride;
destItr += byteStride;
MOZ_RELEASE_ASSERT(srcItr + xByteSize <= shmemBytes.end());
MOZ_RELEASE_ASSERT(destItr + xByteSize <= dest.end());
}
Memcpy(destItr, srcItr, xByteSize);
} }
return true; return true;
@ -6543,7 +6572,7 @@ const webgl::LinkResult& ClientWebGLContext::GetLinkResult(
// --------------------------- // ---------------------------
Maybe<Span<uint8_t>> ClientWebGLContext::ValidateArrayBufferView( Maybe<Range<uint8_t>> ClientWebGLContext::ValidateArrayBufferView(
const Span<uint8_t>& bytes, size_t elemSize, GLuint elemOffset, const Span<uint8_t>& bytes, size_t elemSize, GLuint elemOffset,
GLuint elemCountOverride, const GLenum errorEnum) const { GLuint elemCountOverride, const GLenum errorEnum) const {
size_t elemCount = bytes.Length() / elemSize; size_t elemCount = bytes.Length() / elemSize;
@ -6561,7 +6590,8 @@ Maybe<Span<uint8_t>> ClientWebGLContext::ValidateArrayBufferView(
elemCount = elemCountOverride; elemCount = elemCountOverride;
} }
return Some(bytes.Subspan(elemOffset * elemSize, elemCount * elemSize)); return Some(Range<uint8_t>(
bytes.Subspan(elemOffset * elemSize, elemCount * elemSize)));
} }
// --------------------------- // ---------------------------

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

@ -929,11 +929,11 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
void EnqueueErrorImpl(GLenum errorOrZero, const nsACString&) const; void EnqueueErrorImpl(GLenum errorOrZero, const nsACString&) const;
public: public:
Maybe<Span<uint8_t>> ValidateArrayBufferView(const Span<uint8_t>& bytes, Maybe<Range<uint8_t>> ValidateArrayBufferView(const Span<uint8_t>& bytes,
size_t elemSize, size_t elemSize,
GLuint elemOffset, GLuint elemOffset,
GLuint elemCountOverride, GLuint elemCountOverride,
const GLenum errorEnum) const; const GLenum errorEnum) const;
protected: protected:
template <typename T> template <typename T>
@ -1087,7 +1087,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
private: private:
RefPtr<gfx::DataSourceSurface> BackBufferSnapshot(); RefPtr<gfx::DataSourceSurface> BackBufferSnapshot();
[[nodiscard]] bool DoReadPixels(const webgl::ReadPixelsDesc&, [[nodiscard]] bool DoReadPixels(const webgl::ReadPixelsDesc&,
Span<uint8_t>) const; Range<uint8_t>) const;
uvec2 DrawingBufferSize(); uvec2 DrawingBufferSize();
// - // -

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

@ -621,13 +621,13 @@ bool SharedContextWebgl::SetNoClipMask() {
} }
mWebgl->ActiveTexture(1); mWebgl->ActiveTexture(1);
mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, mNoClipMask); mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, mNoClipMask);
static const auto solidMask = std::array<const uint8_t, 4>{0xFF, 0xFF, 0xFF, 0xFF}; static const uint8_t solidMask[4] = {0xFF, 0xFF, 0xFF, 0xFF};
mWebgl->TexImage(0, LOCAL_GL_RGBA8, {0, 0, 0}, mWebgl->TexImage(
{LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE}, 0, LOCAL_GL_RGBA8, {0, 0, 0}, {LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE},
{LOCAL_GL_TEXTURE_2D, {LOCAL_GL_TEXTURE_2D,
{1, 1, 1}, {1, 1, 1},
gfxAlphaType::NonPremult, gfxAlphaType::NonPremult,
Some(Span{solidMask})}); Some(RawBuffer(Range<const uint8_t>(solidMask, sizeof(solidMask))))});
InitTexParameters(mNoClipMask, false); InitTexParameters(mNoClipMask, false);
mWebgl->ActiveTexture(0); mWebgl->ActiveTexture(0);
mLastClipMask = mNoClipMask; mLastClipMask = mNoClipMask;
@ -1916,11 +1916,11 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData,
int32_t bpp = BytesPerPixel(aFormat); int32_t bpp = BytesPerPixel(aFormat);
// Get the data pointer range considering the sampling rect offset and // Get the data pointer range considering the sampling rect offset and
// size. // size.
Span<const uint8_t> range( Range<const uint8_t> range(
map.GetData() + aSrcRect.y * size_t(stride) + aSrcRect.x * bpp, map.GetData() + aSrcRect.y * size_t(stride) + aSrcRect.x * bpp,
std::max(aSrcRect.height - 1, 0) * size_t(stride) + std::max(aSrcRect.height - 1, 0) * size_t(stride) +
aSrcRect.width * bpp); aSrcRect.width * bpp);
texDesc.cpuData = Some(range); texDesc.cpuData = Some(RawBuffer(range));
// If the stride happens to be 4 byte aligned, assume that is the // If the stride happens to be 4 byte aligned, assume that is the
// desired alignment regardless of format (even A8). Otherwise, we // desired alignment regardless of format (even A8). Otherwise, we
// default to byte alignment. // default to byte alignment.

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

@ -482,9 +482,8 @@ class HostWebGLContext final : public SupportsWeakPtr {
return GetWebGL2Context()->GetBufferSubData(target, srcByteOffset, dest); return GetWebGL2Context()->GetBufferSubData(target, srcByteOffset, dest);
} }
void BufferData(GLenum target, const Span<const uint8_t>& srcData, void BufferData(GLenum target, const RawBuffer<>& srcData, GLenum usage) const {
GLenum usage) const { mContext->BufferData(target, srcData.size(), srcData.begin(), usage);
mContext->BufferData(target, srcData.size(), srcData.data(), usage);
} }
void BufferData_SizeOnly(GLenum target, size_t byteSize, GLenum usage) const { void BufferData_SizeOnly(GLenum target, size_t byteSize, GLenum usage) const {
@ -492,10 +491,11 @@ class HostWebGLContext final : public SupportsWeakPtr {
} }
void BufferSubData(GLenum target, uint64_t dstByteOffset, void BufferSubData(GLenum target, uint64_t dstByteOffset,
const Span<const uint8_t>& srcData, const RawBuffer<>& srcData,
bool unsynchronized = false) const { bool unsynchronized = false) const {
mContext->BufferSubData(target, dstByteOffset, srcData.size(), const auto& range = srcData.Data();
srcData.data(), unsynchronized); mContext->BufferSubData(target, dstByteOffset, range.length(),
range.begin().get(), unsynchronized);
} }
// -------------------------- Framebuffer Objects -------------------------- // -------------------------- Framebuffer Objects --------------------------
@ -507,15 +507,16 @@ class HostWebGLContext final : public SupportsWeakPtr {
} }
void InvalidateFramebuffer(GLenum target, void InvalidateFramebuffer(GLenum target,
const Span<const GLenum>& attachments) const { const RawBuffer<const GLenum>& attachments) const {
GetWebGL2Context()->InvalidateFramebuffer(target, attachments); GetWebGL2Context()->InvalidateFramebuffer(target, MakeRange(attachments));
} }
void InvalidateSubFramebuffer(GLenum target, void InvalidateSubFramebuffer(GLenum target,
const Span<const GLenum>& attachments, GLint x, const RawBuffer<const GLenum>& attachments,
GLint y, GLsizei width, GLsizei height) const { GLint x, GLint y, GLsizei width,
GetWebGL2Context()->InvalidateSubFramebuffer(target, attachments, x, y, GLsizei height) const {
width, height); GetWebGL2Context()->InvalidateSubFramebuffer(target, MakeRange(attachments),
x, y, width, height);
} }
void ReadBuffer(GLenum mode) const { GetWebGL2Context()->ReadBuffer(mode); } void ReadBuffer(GLenum mode) const { GetWebGL2Context()->ReadBuffer(mode); }
@ -553,11 +554,10 @@ class HostWebGLContext final : public SupportsWeakPtr {
// CompressedTexSubImage if `sub` // CompressedTexSubImage if `sub`
void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level, void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level,
GLenum format, const uvec3& offset, const uvec3& size, GLenum format, const uvec3& offset, const uvec3& size,
const Span<const uint8_t>& src, const RawBuffer<>& src, const uint32_t pboImageSize,
const uint32_t pboImageSize,
const Maybe<uint64_t>& pboOffset) const { const Maybe<uint64_t>& pboOffset) const {
mContext->CompressedTexImage(sub, imageTarget, level, format, offset, size, mContext->CompressedTexImage(sub, imageTarget, level, format, offset, size,
src, pboImageSize, pboOffset); MakeRange(src), pboImageSize, pboOffset);
} }
// CopyTexSubImage if `!respecFormat` // CopyTexSubImage if `!respecFormat`
@ -603,8 +603,8 @@ class HostWebGLContext final : public SupportsWeakPtr {
// ------------------------ Uniforms and attributes ------------------------ // ------------------------ Uniforms and attributes ------------------------
void UniformData(uint32_t loc, bool transpose, void UniformData(uint32_t loc, bool transpose,
const Span<const webgl::UniformDataVal>& data) const { const RawBuffer<webgl::UniformDataVal>& data) const {
mContext->UniformData(loc, transpose, data); mContext->UniformData(loc, transpose, data.Data());
} }
void VertexAttrib4T(GLuint index, const webgl::TypedQuad& data) const { void VertexAttrib4T(GLuint index, const webgl::TypedQuad& data) const {

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

@ -98,10 +98,6 @@ template <>
struct BytesAlwaysValidT<webgl::UniformDataVal> { struct BytesAlwaysValidT<webgl::UniformDataVal> {
static constexpr bool value = true; static constexpr bool value = true;
}; };
template <>
struct BytesAlwaysValidT<const webgl::UniformDataVal> {
static constexpr bool value = true;
};
// - // -

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

@ -476,7 +476,8 @@ bool TexUnpackBytes::Validate(const WebGLContext* const webgl,
CheckedInt<size_t> availBytes = 0; CheckedInt<size_t> availBytes = 0;
if (mDesc.cpuData) { if (mDesc.cpuData) {
availBytes = mDesc.cpuData->size(); const auto& range = mDesc.cpuData->Data();
availBytes = range.length();
} else if (mDesc.pboOffset) { } else if (mDesc.pboOffset) {
const auto& pboOffset = *mDesc.pboOffset; const auto& pboOffset = *mDesc.pboOffset;
@ -513,7 +514,11 @@ bool TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec,
const uint8_t* uploadPtr = nullptr; const uint8_t* uploadPtr = nullptr;
if (mDesc.cpuData) { if (mDesc.cpuData) {
uploadPtr = mDesc.cpuData->data(); const auto range = mDesc.cpuData->Data();
uploadPtr = range.begin().get();
if (!uploadPtr) {
MOZ_ASSERT(!range.length());
}
} else if (mDesc.pboOffset) { } else if (mDesc.pboOffset) {
uploadPtr = reinterpret_cast<const uint8_t*>(*mDesc.pboOffset); uploadPtr = reinterpret_cast<const uint8_t*>(*mDesc.pboOffset);
} }

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

@ -47,9 +47,9 @@ class WebGL2Context final : public WebGLContext {
GLbitfield mask, GLenum filter); GLbitfield mask, GLenum filter);
void InvalidateFramebuffer(GLenum target, void InvalidateFramebuffer(GLenum target,
const Span<const GLenum>& attachments); const Range<const GLenum>& attachments);
void InvalidateSubFramebuffer(GLenum target, void InvalidateSubFramebuffer(GLenum target,
const Span<const GLenum>& attachments, GLint x, const Range<const GLenum>& attachments, GLint x,
GLint y, GLsizei width, GLsizei height); GLint y, GLsizei width, GLsizei height);
void ReadBuffer(GLenum mode); void ReadBuffer(GLenum mode);

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

@ -106,7 +106,7 @@ static bool ValidateFramebufferAttachmentEnum(WebGLContext* webgl,
} }
bool WebGLContext::ValidateInvalidateFramebuffer( bool WebGLContext::ValidateInvalidateFramebuffer(
GLenum target, const Span<const GLenum>& attachments, GLenum target, const Range<const GLenum>& attachments,
std::vector<GLenum>* const scopedVector, std::vector<GLenum>* const scopedVector,
GLsizei* const out_glNumAttachments, GLsizei* const out_glNumAttachments,
const GLenum** const out_glAttachments) { const GLenum** const out_glAttachments) {
@ -139,8 +139,8 @@ bool WebGLContext::ValidateInvalidateFramebuffer(
} }
DoBindFB(fb, target); DoBindFB(fb, target);
*out_glNumAttachments = AutoAssertCast(attachments.size()); *out_glNumAttachments = attachments.length();
*out_glAttachments = attachments.data(); *out_glAttachments = attachments.begin().get();
if (fb) { if (fb) {
for (const auto& attachment : attachments) { for (const auto& attachment : attachments) {
@ -153,7 +153,7 @@ bool WebGLContext::ValidateInvalidateFramebuffer(
if (!isDefaultFB) { if (!isDefaultFB) {
MOZ_ASSERT(scopedVector->empty()); MOZ_ASSERT(scopedVector->empty());
scopedVector->reserve(attachments.size()); scopedVector->reserve(attachments.length());
for (const auto& attachment : attachments) { for (const auto& attachment : attachments) {
switch (attachment) { switch (attachment) {
case LOCAL_GL_COLOR: case LOCAL_GL_COLOR:
@ -172,7 +172,7 @@ bool WebGLContext::ValidateInvalidateFramebuffer(
MOZ_CRASH(); MOZ_CRASH();
} }
} }
*out_glNumAttachments = AutoAssertCast(scopedVector->size()); *out_glNumAttachments = scopedVector->size();
*out_glAttachments = scopedVector->data(); *out_glAttachments = scopedVector->data();
} }
} }
@ -183,7 +183,7 @@ bool WebGLContext::ValidateInvalidateFramebuffer(
} }
void WebGL2Context::InvalidateFramebuffer( void WebGL2Context::InvalidateFramebuffer(
GLenum target, const Span<const GLenum>& attachments) { GLenum target, const Range<const GLenum>& attachments) {
const FuncScope funcScope(*this, "invalidateFramebuffer"); const FuncScope funcScope(*this, "invalidateFramebuffer");
std::vector<GLenum> scopedVector; std::vector<GLenum> scopedVector;
@ -210,7 +210,7 @@ void WebGL2Context::InvalidateFramebuffer(
} }
void WebGL2Context::InvalidateSubFramebuffer( void WebGL2Context::InvalidateSubFramebuffer(
GLenum target, const Span<const GLenum>& attachments, GLint x, GLint y, GLenum target, const Range<const GLenum>& attachments, GLint x, GLint y,
GLsizei width, GLsizei height) { GLsizei width, GLsizei height) {
const FuncScope funcScope(*this, "invalidateSubFramebuffer"); const FuncScope funcScope(*this, "invalidateSubFramebuffer");

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

@ -667,7 +667,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
////////////////////////// //////////////////////////
void UniformData(uint32_t loc, bool transpose, void UniformData(uint32_t loc, bool transpose,
const Span<const webgl::UniformDataVal>& data) const; const Range<const webgl::UniformDataVal>& data) const;
//////////////////////////////////// ////////////////////////////////////
@ -1156,7 +1156,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
bool ValidateFramebufferTarget(GLenum target) const; bool ValidateFramebufferTarget(GLenum target) const;
bool ValidateInvalidateFramebuffer(GLenum target, bool ValidateInvalidateFramebuffer(GLenum target,
const Span<const GLenum>& attachments, const Range<const GLenum>& attachments,
std::vector<GLenum>* const scopedVector, std::vector<GLenum>* const scopedVector,
GLsizei* const out_glNumAttachments, GLsizei* const out_glNumAttachments,
const GLenum** const out_glAttachments); const GLenum** const out_glAttachments);

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

@ -1280,7 +1280,7 @@ void WebGLContext::StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
void WebGLContext::UniformData( void WebGLContext::UniformData(
const uint32_t loc, const bool transpose, const uint32_t loc, const bool transpose,
const Span<const webgl::UniformDataVal>& data) const { const Range<const webgl::UniformDataVal>& data) const {
const FuncScope funcScope(*this, "uniform setter"); const FuncScope funcScope(*this, "uniform setter");
if (!IsWebGL2() && transpose) { if (!IsWebGL2() && transpose) {
@ -1306,13 +1306,13 @@ void WebGLContext::UniformData(
// - // -
const auto lengthInType = data.size(); const auto lengthInType = data.length();
const auto elemCount = lengthInType / channels; const auto elemCount = lengthInType / channels;
if (elemCount > 1 && !validationInfo.isArray) { if (elemCount > 1 && !validationInfo.isArray) {
GenerateError( GenerateError(
LOCAL_GL_INVALID_OPERATION, LOCAL_GL_INVALID_OPERATION,
"(uniform %s) `values` length (%u) must exactly match size of %s.", "(uniform %s) `values` length (%u) must exactly match size of %s.",
activeInfo.name.c_str(), (uint32_t)lengthInType, activeInfo.name.c_str(), lengthInType,
EnumString(activeInfo.elemType).c_str()); EnumString(activeInfo.elemType).c_str());
return; return;
} }
@ -1321,9 +1321,9 @@ void WebGLContext::UniformData(
const auto& samplerInfo = locInfo->samplerInfo; const auto& samplerInfo = locInfo->samplerInfo;
if (samplerInfo) { if (samplerInfo) {
const auto idata = ReinterpretToSpan<const uint32_t>::From(data); const auto idata = reinterpret_cast<const uint32_t*>(data.begin().get());
const auto maxTexUnits = GLMaxTextureUnits(); const auto maxTexUnits = GLMaxTextureUnits();
for (const auto& val : idata) { for (const auto& val : Range<const uint32_t>(idata, elemCount)) {
if (val >= maxTexUnits) { if (val >= maxTexUnits) {
ErrorInvalidValue( ErrorInvalidValue(
"This uniform location is a sampler, but %d" "This uniform location is a sampler, but %d"
@ -1337,7 +1337,7 @@ void WebGLContext::UniformData(
// - // -
// This is a little galaxy-brain, sorry! // This is a little galaxy-brain, sorry!
const auto ptr = static_cast<const void*>(data.data()); const auto ptr = static_cast<const void*>(data.begin().get());
(*pfn)(*gl, static_cast<GLint>(loc), elemCount, transpose, ptr); (*pfn)(*gl, static_cast<GLint>(loc), elemCount, transpose, ptr);
// - // -
@ -1345,12 +1345,12 @@ void WebGLContext::UniformData(
if (samplerInfo) { if (samplerInfo) {
auto& texUnits = samplerInfo->texUnits; auto& texUnits = samplerInfo->texUnits;
const auto srcBegin = reinterpret_cast<const uint32_t*>(data.data()); const auto srcBegin = reinterpret_cast<const uint32_t*>(data.begin().get());
auto destIndex = locInfo->indexIntoUniform; auto destIndex = locInfo->indexIntoUniform;
if (destIndex < texUnits.length()) { if (destIndex < texUnits.length()) {
// Only sample as many indexes as available tex units allow. // Only sample as many indexes as available tex units allow.
const auto destCount = std::min(elemCount, texUnits.length() - destIndex); const auto destCount = std::min(elemCount, texUnits.length() - destIndex);
for (const auto& val : Span<const uint32_t>(srcBegin, destCount)) { for (const auto& val : Range<const uint32_t>(srcBegin, destCount)) {
texUnits[destIndex] = AssertedCast<uint8_t>(val); texUnits[destIndex] = AssertedCast<uint8_t>(val);
destIndex += 1; destIndex += 1;
} }

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

@ -114,21 +114,23 @@ USE_IS_ENUM_CASE(webgl::ProvokingVertex)
// Custom QueueParamTraits // Custom QueueParamTraits
template <typename T> template <typename T>
struct QueueParamTraits<Span<T>> { struct QueueParamTraits<RawBuffer<T>> {
using ParamType = RawBuffer<T>;
template <typename U> template <typename U>
static bool Write(ProducerView<U>& view, const Span<T>& in) { static bool Write(ProducerView<U>& view, const ParamType& in) {
const auto& elemCount = in.size(); const auto& elemCount = in.size();
auto status = view.WriteParam(elemCount); auto status = view.WriteParam(elemCount);
if (!status) return status; if (!status) return status;
if (!elemCount) return status; if (!elemCount) return status;
status = view.WriteFromRange(Range<const T>{in}); status = view.WriteFromRange(in.Data());
return status; return status;
} }
template <typename U> template <typename U>
static bool Read(ConsumerView<U>& view, Span<const T>* const out) { static bool Read(ConsumerView<U>& view, ParamType* const out) {
size_t elemCount = 0; size_t elemCount = 0;
auto status = view.ReadParam(&elemCount); auto status = view.ReadParam(&elemCount);
if (!status) return status; if (!status) return status;
@ -138,9 +140,9 @@ struct QueueParamTraits<Span<T>> {
return true; return true;
} }
auto data = view.template ReadRange<const T>(elemCount); auto data = view.template ReadRange<T>(elemCount);
if (!data) return false; if (!data) return false;
*out = Span{*data}; *out = std::move(RawBuffer<T>{*data});
return true; return true;
} }
}; };

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

@ -925,7 +925,23 @@ void WebGLTexture::TexStorage(TexTarget target, uint32_t levels,
void WebGLTexture::TexImage(uint32_t level, GLenum respecFormat, void WebGLTexture::TexImage(uint32_t level, GLenum respecFormat,
const uvec3& offset, const webgl::PackingInfo& pi, const uvec3& offset, const webgl::PackingInfo& pi,
const webgl::TexUnpackBlobDesc& src) { const webgl::TexUnpackBlobDesc& src) {
const auto blob = webgl::TexUnpackBlob::Create(src); Maybe<RawBuffer<>> cpuDataView;
if (src.cpuData) {
cpuDataView = Some(RawBuffer<>{src.cpuData->Data()});
}
const auto srcViewDesc = webgl::TexUnpackBlobDesc{src.imageTarget,
src.size,
src.srcAlphaType,
std::move(cpuDataView),
src.pboOffset,
src.structuredSrcSize,
src.image,
src.sd,
src.dataSurf,
src.unpacking,
src.applyUnpackTransforms};
const auto blob = webgl::TexUnpackBlob::Create(srcViewDesc);
if (!blob) { if (!blob) {
MOZ_ASSERT(false); MOZ_ASSERT(false);
return; return;

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

@ -24,7 +24,6 @@
#include "mozilla/RefCounted.h" #include "mozilla/RefCounted.h"
#include "mozilla/Result.h" #include "mozilla/Result.h"
#include "mozilla/ResultVariant.h" #include "mozilla/ResultVariant.h"
#include "mozilla/Span.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/gfx/BuildConstants.h" #include "mozilla/gfx/BuildConstants.h"
#include "mozilla/gfx/Logging.h" #include "mozilla/gfx/Logging.h"
@ -854,6 +853,47 @@ struct VertAttribPointerCalculated final {
} // namespace webgl } // namespace webgl
// TODO: s/RawBuffer/Span/
template <typename T = uint8_t>
class RawBuffer final {
const T* mBegin = nullptr;
size_t mLen = 0;
public:
using ElementType = T;
explicit RawBuffer(const Range<const T>& data)
: mBegin(data.begin().get()), mLen(data.length()) {
if (mLen) {
MOZ_ASSERT(mBegin);
}
}
~RawBuffer() = default;
Range<const T> Data() const { return {begin(), mLen}; }
const auto& begin() const {
if (mLen) {
MOZ_RELEASE_ASSERT(mBegin);
}
return mBegin;
}
const auto& size() const { return mLen; }
void Shrink(const size_t newLen) {
if (mLen <= newLen) return;
mLen = newLen;
}
RawBuffer() = default;
RawBuffer(const RawBuffer&) = delete;
RawBuffer& operator=(const RawBuffer&) = delete;
RawBuffer(RawBuffer&&) = default;
RawBuffer& operator=(RawBuffer&&) = default;
};
template <class T> template <class T>
inline Range<T> ShmemRange(const mozilla::ipc::Shmem& shmem) { inline Range<T> ShmemRange(const mozilla::ipc::Shmem& shmem) {
return {shmem.get<T>(), shmem.Size<T>()}; return {shmem.get<T>(), shmem.Size<T>()};
@ -1056,7 +1096,7 @@ struct TexUnpackBlobDesc final {
uvec3 size; uvec3 size;
gfxAlphaType srcAlphaType = gfxAlphaType::NonPremult; gfxAlphaType srcAlphaType = gfxAlphaType::NonPremult;
Maybe<Span<const uint8_t>> cpuData; Maybe<RawBuffer<>> cpuData;
Maybe<uint64_t> pboOffset; Maybe<uint64_t> pboOffset;
Maybe<uvec2> structuredSrcSize; Maybe<uvec2> structuredSrcSize;
@ -1094,6 +1134,11 @@ inline Range<const T> MakeRange(const dom::Sequence<T>& seq) {
return {seq.Elements(), seq.Length()}; return {seq.Elements(), seq.Length()};
} }
template <typename T>
inline Range<const T> MakeRange(const RawBuffer<T>& from) {
return from.Data();
}
// - // -
constexpr auto kUniversalAlignment = alignof(std::max_align_t); constexpr auto kUniversalAlignment = alignof(std::max_align_t);
@ -1114,6 +1159,13 @@ inline size_t ByteSize(const Range<T>& range) {
// - // -
template <typename T>
RawBuffer<T> RawBufferView(const Range<T>& range) {
return RawBuffer<T>{range};
}
// -
Maybe<webgl::ErrorInfo> CheckBindBufferRange( Maybe<webgl::ErrorInfo> CheckBindBufferRange(
const GLenum target, const GLuint index, const bool isBuffer, const GLenum target, const GLuint index, const bool isBuffer,
const uint64_t offset, const uint64_t size, const webgl::Limits& limits); const uint64_t offset, const uint64_t size, const webgl::Limits& limits);
@ -1155,13 +1207,6 @@ inline void Memcpy(const RangedPtr<T>* const destBegin,
Memcpy(destBegin, srcRange->begin(), srcRange->length()); Memcpy(destBegin, srcRange->begin(), srcRange->length());
} }
template <typename Dst, typename Src>
inline void Memcpy(const Span<Dst>* const dest, const Span<Src>& src) {
MOZ_RELEASE_ASSERT(src.size_bytes() >= dest->size_bytes());
MOZ_ASSERT(src.size_bytes() == dest->size_bytes());
memcpy(dest->data(), src.data(), dest->size_bytes());
}
// - // -
inline bool StartsWith(const std::string_view str, inline bool StartsWith(const std::string_view str,
@ -1240,15 +1285,6 @@ inline const char* ToChars(const bool val) {
return "false"; return "false";
} }
template <class To>
struct ReinterpretToSpan {
template <class From>
static inline constexpr Span<To> From(const Span<From>& from) {
static_assert(sizeof(From) == sizeof(To));
return {reinterpret_cast<To*>(from.data()), from.size()};
}
};
} // namespace mozilla } // namespace mozilla
#endif #endif