From d16ed2c5452cd9e23d0521307ab851aae1c9fca2 Mon Sep 17 00:00:00 2001 From: Sandor Molnar Date: Tue, 20 Feb 2024 21:25:02 +0200 Subject: [PATCH] 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) --- dom/canvas/ClientWebGLContext.cpp | 120 ++++++++++++++--------- dom/canvas/ClientWebGLContext.h | 12 +-- dom/canvas/DrawTargetWebgl.cpp | 18 ++-- dom/canvas/HostWebGLContext.h | 34 +++---- dom/canvas/QueueParamTraits.h | 4 - dom/canvas/TexUnpackBlob.cpp | 9 +- dom/canvas/WebGL2Context.h | 4 +- dom/canvas/WebGL2ContextFramebuffers.cpp | 14 +-- dom/canvas/WebGLContext.h | 4 +- dom/canvas/WebGLContextGL.cpp | 16 +-- dom/canvas/WebGLQueueParamTraits.h | 14 +-- dom/canvas/WebGLTextureUpload.cpp | 18 +++- dom/canvas/WebGLTypes.h | 72 ++++++++++---- 13 files changed, 212 insertions(+), 127 deletions(-) diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp index 75ef0eea63d5..bde265f9a044 100644 --- a/dom/canvas/ClientWebGLContext.cpp +++ b/dom/canvas/ClientWebGLContext.cpp @@ -1264,12 +1264,28 @@ RefPtr ClientWebGLContext::BackBufferSnapshot() { MOZ_ASSERT(static_cast(map.GetStride()) == stride); const auto desc = webgl::ReadPixelsDesc{{0, 0}, size}; - const auto pixels = Span(map.GetData(), stride * size.y); - if (!DoReadPixels(desc, pixels)) return nullptr; + const auto range = Range(map.GetData(), stride * size.y); + if (!DoReadPixels(desc, range)) return nullptr; - // 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})); + const auto begin = range.begin().get(); + + std::vector 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; @@ -3403,7 +3419,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->size(), + if (!child->SendGetBufferSubData(target, srcByteOffset, destView->length(), &rawShmem)) { return; } @@ -3413,13 +3429,14 @@ void ClientWebGLContext::GetBufferSubData(GLenum target, GLintptr srcByteOffset, return; } - const auto shmemView = Span{shmem.ByteRange()}; - MOZ_RELEASE_ASSERT(shmemView.size() == 1 + destView->size()); + const auto shmemView = shmem.ByteRange(); + MOZ_RELEASE_ASSERT(shmemView.length() == 1 + destView->length()); - const auto ok = bool(shmemView[0]); - const auto srcView = shmemView.subspan(1); + const auto ok = bool(*(shmemView.begin().get())); + const auto srcView = + Range{shmemView.begin() + 1, shmemView.end()}; if (ok) { - Memcpy(&*destView, srcView); + Memcpy(destView->begin(), srcView.begin(), srcView.length()); } }); } @@ -3446,8 +3463,8 @@ void ClientWebGLContext::BufferData( if (!ValidateNonNull("src", maybeSrc)) return; const auto& src = maybeSrc.Value(); - src.ProcessFixedData([&](const Span& aData) { - Run(target, aData, usage); + src.ProcessFixedData([&](const Span& aData) { + Run(target, RawBuffer<>(aData), usage); }); } @@ -3464,7 +3481,7 @@ void ClientWebGLContext::BufferData(GLenum target, if (!range) { return; } - Run(target, *range, usage); + Run(target, RawBuffer<>(*range), usage); }); } @@ -3474,8 +3491,8 @@ void ClientWebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset, const dom::ArrayBuffer& src) { const FuncScope funcScope(*this, "bufferSubData"); - src.ProcessFixedData([&](const Span& aData) { - Run(target, dstByteOffset, aData, + src.ProcessFixedData([&](const Span& aData) { + Run(target, dstByteOffset, RawBuffer<>(aData), /* unsynchronized */ false); }); } @@ -3494,7 +3511,7 @@ void ClientWebGLContext::BufferSubData(GLenum target, if (!range) { return; } - Run(target, dstByteOffset, *range, + Run(target, dstByteOffset, RawBuffer<>(*range), /* unsynchronized */ false); }); } @@ -3794,7 +3811,9 @@ void ClientWebGLContext::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, void ClientWebGLContext::InvalidateFramebuffer( GLenum target, const dom::Sequence& attachments, ErrorResult& unused) { - Run(target, Span{attachments}); + const auto range = MakeRange(attachments); + const auto& buffer = RawBufferView(range); + Run(target, buffer); // Never invalidate the backbuffer, so never needs AfterDrawCall. } @@ -3802,8 +3821,9 @@ void ClientWebGLContext::InvalidateFramebuffer( void ClientWebGLContext::InvalidateSubFramebuffer( GLenum target, const dom::Sequence& attachments, GLint x, GLint y, GLsizei width, GLsizei height, ErrorResult& unused) { - Run(target, Span{attachments}, x, y, width, - height); + const auto range = MakeRange(attachments); + const auto& buffer = RawBufferView(range); + Run(target, buffer, x, y, width, height); // Never invalidate the backbuffer, so never needs AfterDrawCall. } @@ -4082,11 +4102,13 @@ Range SubRange(const Range& full, const size_t offset, return Range{newBegin, newBegin + length}; } -Maybe> GetRangeFromData(const Span& data, - size_t bytesPerElem, - GLuint elemOffset, - GLuint elemCountOverride) { - auto elemCount = data.size() / bytesPerElem; +Maybe> GetRangeFromData(const Span& data, + size_t bytesPerElem, + GLuint elemOffset, + GLuint elemCountOverride) { + const auto byteRange = Range(data); // In bytes. + + auto elemCount = byteRange.length() / bytesPerElem; if (elemOffset > elemCount) return {}; elemCount -= elemOffset; @@ -4094,8 +4116,9 @@ Maybe> GetRangeFromData(const Span& data, if (elemCountOverride > elemCount) return {}; elemCount = elemCountOverride; } - return Some( - data.subspan(elemOffset * bytesPerElem, elemCount * bytesPerElem)); + const auto subrange = + SubRange(byteRange, elemOffset * bytesPerElem, elemCount * bytesPerElem); + return Some(subrange); } // - @@ -4142,8 +4165,7 @@ void webgl::TexUnpackBlobDesc::Shrink(const webgl::PackingInfo& pi) { CheckedInt(unpack.metrics.bytesPerRowStride) * unpack.metrics.totalRows; if (bytesUpperBound.isValid()) { - auto& span = *cpuData; - span = span.subspan(0, std::min(span.size(), bytesUpperBound.value())); + cpuData->Shrink(bytesUpperBound.value()); } } } @@ -4219,7 +4241,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget, return Some(webgl::TexUnpackBlobDesc{imageTarget, size.value(), gfxAlphaType::NonPremult, - Some(*range), + Some(RawBuffer<>{*range}), {}}); }); } @@ -4566,7 +4588,7 @@ void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims, RunWithGCData( std::move(aNoGC), sub, imageTarget, static_cast(level), - format, CastUvec3(offset), CastUvec3(isize), *range, + format, CastUvec3(offset), CastUvec3(isize), RawBuffer<>{*range}, static_cast(pboImageSize), Maybe()); return; }); @@ -4581,8 +4603,8 @@ void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims, Run( sub, imageTarget, static_cast(level), format, CastUvec3(offset), - CastUvec3(isize), Span{}, - static_cast(pboImageSize), Some(*src.mPboOffset)); + CastUvec3(isize), RawBuffer<>(), static_cast(pboImageSize), + Some(*src.mPboOffset)); } void ClientWebGLContext::CopyTexImage(uint8_t funcDims, GLenum imageTarget, @@ -4854,8 +4876,9 @@ void ClientWebGLContext::UniformData(const GLenum funcElemType, const auto begin = reinterpret_cast(bytes.begin().get()) + elemOffset; - const auto range = Span{begin, availCount}; - RunWithGCData(std::move(nogc), locId, transpose, range); + const auto range = Range{begin, availCount}; + RunWithGCData(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, - const Span dest) const { + const Range dest) const { const auto notLost = mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. if (!notLost) return false; @@ -5084,7 +5107,7 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc, const auto& child = notLost->outOfProcess; child->FlushPendingCmds(); webgl::ReadPixelsResultIpc res = {}; - if (!child->SendReadPixels(desc, dest.size(), &res)) { + if (!child->SendReadPixels(desc, dest.length(), &res)) { res = {}; } if (!res.byteStride || !res.shmem) return false; @@ -5096,7 +5119,7 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc, return false; } - const auto& shmemBytes = Span{shmem.ByteRange()}; + const auto& shmemBytes = shmem.ByteRange(); const auto pii = webgl::PackingInfoInfo::For(desc.pi); if (!pii) { @@ -5113,13 +5136,19 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc, const auto xByteSize = bpp * static_cast(subrect.width); const ptrdiff_t byteOffset = packRect.y * byteStride + packRect.x * bpp; - const auto srcSubrect = shmemBytes.subspan(byteOffset); - const auto destSubrect = dest.subspan(byteOffset); + auto srcItr = shmemBytes.begin() + byteOffset; + auto destItr = dest.begin() + byteOffset; for (const auto i : IntegerRange(subrect.height)) { - const auto srcRow = srcSubrect.subspan(i * byteStride, xByteSize); - const auto destRow = destSubrect.subspan(i * byteStride, xByteSize); - Memcpy(&destRow, srcRow); + 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); } return true; @@ -6543,7 +6572,7 @@ const webgl::LinkResult& ClientWebGLContext::GetLinkResult( // --------------------------- -Maybe> ClientWebGLContext::ValidateArrayBufferView( +Maybe> ClientWebGLContext::ValidateArrayBufferView( const Span& bytes, size_t elemSize, GLuint elemOffset, GLuint elemCountOverride, const GLenum errorEnum) const { size_t elemCount = bytes.Length() / elemSize; @@ -6561,7 +6590,8 @@ Maybe> ClientWebGLContext::ValidateArrayBufferView( elemCount = elemCountOverride; } - return Some(bytes.Subspan(elemOffset * elemSize, elemCount * elemSize)); + return Some(Range( + bytes.Subspan(elemOffset * elemSize, elemCount * elemSize))); } // --------------------------- diff --git a/dom/canvas/ClientWebGLContext.h b/dom/canvas/ClientWebGLContext.h index 3c011a3027bb..47e03d29c5f7 100644 --- a/dom/canvas/ClientWebGLContext.h +++ b/dom/canvas/ClientWebGLContext.h @@ -929,11 +929,11 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal, void EnqueueErrorImpl(GLenum errorOrZero, const nsACString&) const; public: - Maybe> ValidateArrayBufferView(const Span& bytes, - size_t elemSize, - GLuint elemOffset, - GLuint elemCountOverride, - const GLenum errorEnum) const; + Maybe> ValidateArrayBufferView(const Span& bytes, + size_t elemSize, + GLuint elemOffset, + GLuint elemCountOverride, + const GLenum errorEnum) const; protected: template @@ -1087,7 +1087,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal, private: RefPtr BackBufferSnapshot(); [[nodiscard]] bool DoReadPixels(const webgl::ReadPixelsDesc&, - Span) const; + Range) const; uvec2 DrawingBufferSize(); // - diff --git a/dom/canvas/DrawTargetWebgl.cpp b/dom/canvas/DrawTargetWebgl.cpp index ecb02d76da29..6055fa72e17f 100644 --- a/dom/canvas/DrawTargetWebgl.cpp +++ b/dom/canvas/DrawTargetWebgl.cpp @@ -621,13 +621,13 @@ bool SharedContextWebgl::SetNoClipMask() { } mWebgl->ActiveTexture(1); mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, mNoClipMask); - static const auto solidMask = std::array{0xFF, 0xFF, 0xFF, 0xFF}; - mWebgl->TexImage(0, LOCAL_GL_RGBA8, {0, 0, 0}, - {LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE}, - {LOCAL_GL_TEXTURE_2D, - {1, 1, 1}, - gfxAlphaType::NonPremult, - Some(Span{solidMask})}); + static const uint8_t solidMask[4] = {0xFF, 0xFF, 0xFF, 0xFF}; + mWebgl->TexImage( + 0, LOCAL_GL_RGBA8, {0, 0, 0}, {LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE}, + {LOCAL_GL_TEXTURE_2D, + {1, 1, 1}, + gfxAlphaType::NonPremult, + Some(RawBuffer(Range(solidMask, sizeof(solidMask))))}); InitTexParameters(mNoClipMask, false); mWebgl->ActiveTexture(0); mLastClipMask = mNoClipMask; @@ -1916,11 +1916,11 @@ bool SharedContextWebgl::UploadSurface(DataSourceSurface* aData, int32_t bpp = BytesPerPixel(aFormat); // Get the data pointer range considering the sampling rect offset and // size. - Span range( + Range range( map.GetData() + aSrcRect.y * size_t(stride) + aSrcRect.x * bpp, std::max(aSrcRect.height - 1, 0) * size_t(stride) + 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 // desired alignment regardless of format (even A8). Otherwise, we // default to byte alignment. diff --git a/dom/canvas/HostWebGLContext.h b/dom/canvas/HostWebGLContext.h index cc385bc26a63..c508a164c8bc 100644 --- a/dom/canvas/HostWebGLContext.h +++ b/dom/canvas/HostWebGLContext.h @@ -482,9 +482,8 @@ class HostWebGLContext final : public SupportsWeakPtr { return GetWebGL2Context()->GetBufferSubData(target, srcByteOffset, dest); } - void BufferData(GLenum target, const Span& srcData, - GLenum usage) const { - mContext->BufferData(target, srcData.size(), srcData.data(), usage); + void BufferData(GLenum target, const RawBuffer<>& srcData, GLenum usage) const { + mContext->BufferData(target, srcData.size(), srcData.begin(), usage); } 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, - const Span& srcData, + const RawBuffer<>& srcData, bool unsynchronized = false) const { - mContext->BufferSubData(target, dstByteOffset, srcData.size(), - srcData.data(), unsynchronized); + const auto& range = srcData.Data(); + mContext->BufferSubData(target, dstByteOffset, range.length(), + range.begin().get(), unsynchronized); } // -------------------------- Framebuffer Objects -------------------------- @@ -507,15 +507,16 @@ class HostWebGLContext final : public SupportsWeakPtr { } void InvalidateFramebuffer(GLenum target, - const Span& attachments) const { - GetWebGL2Context()->InvalidateFramebuffer(target, attachments); + const RawBuffer& attachments) const { + GetWebGL2Context()->InvalidateFramebuffer(target, MakeRange(attachments)); } void InvalidateSubFramebuffer(GLenum target, - const Span& attachments, GLint x, - GLint y, GLsizei width, GLsizei height) const { - GetWebGL2Context()->InvalidateSubFramebuffer(target, attachments, x, y, - width, height); + const RawBuffer& attachments, + GLint x, GLint y, GLsizei width, + GLsizei height) const { + GetWebGL2Context()->InvalidateSubFramebuffer(target, MakeRange(attachments), + x, y, width, height); } void ReadBuffer(GLenum mode) const { GetWebGL2Context()->ReadBuffer(mode); } @@ -553,11 +554,10 @@ class HostWebGLContext final : public SupportsWeakPtr { // CompressedTexSubImage if `sub` void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level, GLenum format, const uvec3& offset, const uvec3& size, - const Span& src, - const uint32_t pboImageSize, + const RawBuffer<>& src, const uint32_t pboImageSize, const Maybe& pboOffset) const { mContext->CompressedTexImage(sub, imageTarget, level, format, offset, size, - src, pboImageSize, pboOffset); + MakeRange(src), pboImageSize, pboOffset); } // CopyTexSubImage if `!respecFormat` @@ -603,8 +603,8 @@ class HostWebGLContext final : public SupportsWeakPtr { // ------------------------ Uniforms and attributes ------------------------ void UniformData(uint32_t loc, bool transpose, - const Span& data) const { - mContext->UniformData(loc, transpose, data); + const RawBuffer& data) const { + mContext->UniformData(loc, transpose, data.Data()); } void VertexAttrib4T(GLuint index, const webgl::TypedQuad& data) const { diff --git a/dom/canvas/QueueParamTraits.h b/dom/canvas/QueueParamTraits.h index fef59db7970a..fbedcdea0bf5 100644 --- a/dom/canvas/QueueParamTraits.h +++ b/dom/canvas/QueueParamTraits.h @@ -98,10 +98,6 @@ template <> struct BytesAlwaysValidT { static constexpr bool value = true; }; -template <> -struct BytesAlwaysValidT { - static constexpr bool value = true; -}; // - diff --git a/dom/canvas/TexUnpackBlob.cpp b/dom/canvas/TexUnpackBlob.cpp index e9e64fe9b99e..8598c362273f 100644 --- a/dom/canvas/TexUnpackBlob.cpp +++ b/dom/canvas/TexUnpackBlob.cpp @@ -476,7 +476,8 @@ bool TexUnpackBytes::Validate(const WebGLContext* const webgl, CheckedInt availBytes = 0; if (mDesc.cpuData) { - availBytes = mDesc.cpuData->size(); + const auto& range = mDesc.cpuData->Data(); + availBytes = range.length(); } else if (mDesc.pboOffset) { const auto& pboOffset = *mDesc.pboOffset; @@ -513,7 +514,11 @@ bool TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, const uint8_t* uploadPtr = nullptr; 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) { uploadPtr = reinterpret_cast(*mDesc.pboOffset); } diff --git a/dom/canvas/WebGL2Context.h b/dom/canvas/WebGL2Context.h index 018c81f298ec..138dd85b8072 100644 --- a/dom/canvas/WebGL2Context.h +++ b/dom/canvas/WebGL2Context.h @@ -47,9 +47,9 @@ class WebGL2Context final : public WebGLContext { GLbitfield mask, GLenum filter); void InvalidateFramebuffer(GLenum target, - const Span& attachments); + const Range& attachments); void InvalidateSubFramebuffer(GLenum target, - const Span& attachments, GLint x, + const Range& attachments, GLint x, GLint y, GLsizei width, GLsizei height); void ReadBuffer(GLenum mode); diff --git a/dom/canvas/WebGL2ContextFramebuffers.cpp b/dom/canvas/WebGL2ContextFramebuffers.cpp index ab9e848f620e..7056c83d03a0 100644 --- a/dom/canvas/WebGL2ContextFramebuffers.cpp +++ b/dom/canvas/WebGL2ContextFramebuffers.cpp @@ -106,7 +106,7 @@ static bool ValidateFramebufferAttachmentEnum(WebGLContext* webgl, } bool WebGLContext::ValidateInvalidateFramebuffer( - GLenum target, const Span& attachments, + GLenum target, const Range& attachments, std::vector* const scopedVector, GLsizei* const out_glNumAttachments, const GLenum** const out_glAttachments) { @@ -139,8 +139,8 @@ bool WebGLContext::ValidateInvalidateFramebuffer( } DoBindFB(fb, target); - *out_glNumAttachments = AutoAssertCast(attachments.size()); - *out_glAttachments = attachments.data(); + *out_glNumAttachments = attachments.length(); + *out_glAttachments = attachments.begin().get(); if (fb) { for (const auto& attachment : attachments) { @@ -153,7 +153,7 @@ bool WebGLContext::ValidateInvalidateFramebuffer( if (!isDefaultFB) { MOZ_ASSERT(scopedVector->empty()); - scopedVector->reserve(attachments.size()); + scopedVector->reserve(attachments.length()); for (const auto& attachment : attachments) { switch (attachment) { case LOCAL_GL_COLOR: @@ -172,7 +172,7 @@ bool WebGLContext::ValidateInvalidateFramebuffer( MOZ_CRASH(); } } - *out_glNumAttachments = AutoAssertCast(scopedVector->size()); + *out_glNumAttachments = scopedVector->size(); *out_glAttachments = scopedVector->data(); } } @@ -183,7 +183,7 @@ bool WebGLContext::ValidateInvalidateFramebuffer( } void WebGL2Context::InvalidateFramebuffer( - GLenum target, const Span& attachments) { + GLenum target, const Range& attachments) { const FuncScope funcScope(*this, "invalidateFramebuffer"); std::vector scopedVector; @@ -210,7 +210,7 @@ void WebGL2Context::InvalidateFramebuffer( } void WebGL2Context::InvalidateSubFramebuffer( - GLenum target, const Span& attachments, GLint x, GLint y, + GLenum target, const Range& attachments, GLint x, GLint y, GLsizei width, GLsizei height) { const FuncScope funcScope(*this, "invalidateSubFramebuffer"); diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index dbaca23a39bb..12727c4969a2 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -667,7 +667,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { ////////////////////////// void UniformData(uint32_t loc, bool transpose, - const Span& data) const; + const Range& data) const; //////////////////////////////////// @@ -1156,7 +1156,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { bool ValidateFramebufferTarget(GLenum target) const; bool ValidateInvalidateFramebuffer(GLenum target, - const Span& attachments, + const Range& attachments, std::vector* const scopedVector, GLsizei* const out_glNumAttachments, const GLenum** const out_glAttachments); diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp index ef068c899942..7411cec02fd9 100644 --- a/dom/canvas/WebGLContextGL.cpp +++ b/dom/canvas/WebGLContextGL.cpp @@ -1280,7 +1280,7 @@ void WebGLContext::StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, void WebGLContext::UniformData( const uint32_t loc, const bool transpose, - const Span& data) const { + const Range& data) const { const FuncScope funcScope(*this, "uniform setter"); 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; if (elemCount > 1 && !validationInfo.isArray) { GenerateError( LOCAL_GL_INVALID_OPERATION, "(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()); return; } @@ -1321,9 +1321,9 @@ void WebGLContext::UniformData( const auto& samplerInfo = locInfo->samplerInfo; if (samplerInfo) { - const auto idata = ReinterpretToSpan::From(data); + const auto idata = reinterpret_cast(data.begin().get()); const auto maxTexUnits = GLMaxTextureUnits(); - for (const auto& val : idata) { + for (const auto& val : Range(idata, elemCount)) { if (val >= maxTexUnits) { ErrorInvalidValue( "This uniform location is a sampler, but %d" @@ -1337,7 +1337,7 @@ void WebGLContext::UniformData( // - // This is a little galaxy-brain, sorry! - const auto ptr = static_cast(data.data()); + const auto ptr = static_cast(data.begin().get()); (*pfn)(*gl, static_cast(loc), elemCount, transpose, ptr); // - @@ -1345,12 +1345,12 @@ void WebGLContext::UniformData( if (samplerInfo) { auto& texUnits = samplerInfo->texUnits; - const auto srcBegin = reinterpret_cast(data.data()); + const auto srcBegin = reinterpret_cast(data.begin().get()); auto destIndex = locInfo->indexIntoUniform; if (destIndex < texUnits.length()) { // Only sample as many indexes as available tex units allow. const auto destCount = std::min(elemCount, texUnits.length() - destIndex); - for (const auto& val : Span(srcBegin, destCount)) { + for (const auto& val : Range(srcBegin, destCount)) { texUnits[destIndex] = AssertedCast(val); destIndex += 1; } diff --git a/dom/canvas/WebGLQueueParamTraits.h b/dom/canvas/WebGLQueueParamTraits.h index bffa9aa10635..db3ef0a44b07 100644 --- a/dom/canvas/WebGLQueueParamTraits.h +++ b/dom/canvas/WebGLQueueParamTraits.h @@ -114,21 +114,23 @@ USE_IS_ENUM_CASE(webgl::ProvokingVertex) // Custom QueueParamTraits template -struct QueueParamTraits> { +struct QueueParamTraits> { + using ParamType = RawBuffer; + template - static bool Write(ProducerView& view, const Span& in) { + static bool Write(ProducerView& view, const ParamType& in) { const auto& elemCount = in.size(); auto status = view.WriteParam(elemCount); if (!status) return status; if (!elemCount) return status; - status = view.WriteFromRange(Range{in}); + status = view.WriteFromRange(in.Data()); return status; } template - static bool Read(ConsumerView& view, Span* const out) { + static bool Read(ConsumerView& view, ParamType* const out) { size_t elemCount = 0; auto status = view.ReadParam(&elemCount); if (!status) return status; @@ -138,9 +140,9 @@ struct QueueParamTraits> { return true; } - auto data = view.template ReadRange(elemCount); + auto data = view.template ReadRange(elemCount); if (!data) return false; - *out = Span{*data}; + *out = std::move(RawBuffer{*data}); return true; } }; diff --git a/dom/canvas/WebGLTextureUpload.cpp b/dom/canvas/WebGLTextureUpload.cpp index fb8b7ae79c8a..6686c3417883 100644 --- a/dom/canvas/WebGLTextureUpload.cpp +++ b/dom/canvas/WebGLTextureUpload.cpp @@ -925,7 +925,23 @@ void WebGLTexture::TexStorage(TexTarget target, uint32_t levels, void WebGLTexture::TexImage(uint32_t level, GLenum respecFormat, const uvec3& offset, const webgl::PackingInfo& pi, const webgl::TexUnpackBlobDesc& src) { - const auto blob = webgl::TexUnpackBlob::Create(src); + Maybe> 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) { MOZ_ASSERT(false); return; diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h index 6e659da94c47..b23839b9cacf 100644 --- a/dom/canvas/WebGLTypes.h +++ b/dom/canvas/WebGLTypes.h @@ -24,7 +24,6 @@ #include "mozilla/RefCounted.h" #include "mozilla/Result.h" #include "mozilla/ResultVariant.h" -#include "mozilla/Span.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/BuildConstants.h" #include "mozilla/gfx/Logging.h" @@ -854,6 +853,47 @@ struct VertAttribPointerCalculated final { } // namespace webgl +// TODO: s/RawBuffer/Span/ +template +class RawBuffer final { + const T* mBegin = nullptr; + size_t mLen = 0; + + public: + using ElementType = T; + + explicit RawBuffer(const Range& data) + : mBegin(data.begin().get()), mLen(data.length()) { + if (mLen) { + MOZ_ASSERT(mBegin); + } + } + + ~RawBuffer() = default; + + Range 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 inline Range ShmemRange(const mozilla::ipc::Shmem& shmem) { return {shmem.get(), shmem.Size()}; @@ -1056,7 +1096,7 @@ struct TexUnpackBlobDesc final { uvec3 size; gfxAlphaType srcAlphaType = gfxAlphaType::NonPremult; - Maybe> cpuData; + Maybe> cpuData; Maybe pboOffset; Maybe structuredSrcSize; @@ -1094,6 +1134,11 @@ inline Range MakeRange(const dom::Sequence& seq) { return {seq.Elements(), seq.Length()}; } +template +inline Range MakeRange(const RawBuffer& from) { + return from.Data(); +} + // - constexpr auto kUniversalAlignment = alignof(std::max_align_t); @@ -1114,6 +1159,13 @@ inline size_t ByteSize(const Range& range) { // - +template +RawBuffer RawBufferView(const Range& range) { + return RawBuffer{range}; +} + +// - + Maybe CheckBindBufferRange( const GLenum target, const GLuint index, const bool isBuffer, const uint64_t offset, const uint64_t size, const webgl::Limits& limits); @@ -1155,13 +1207,6 @@ inline void Memcpy(const RangedPtr* const destBegin, Memcpy(destBegin, srcRange->begin(), srcRange->length()); } -template -inline void Memcpy(const Span* const dest, const Span& 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, @@ -1240,15 +1285,6 @@ inline const char* ToChars(const bool val) { return "false"; } -template -struct ReinterpretToSpan { - template - static inline constexpr Span From(const Span& from) { - static_assert(sizeof(From) == sizeof(To)); - return {reinterpret_cast(from.data()), from.size()}; - } -}; - } // namespace mozilla #endif