From 8fe920ccb03a9264f936cfbc9c6d61687f6bb4d6 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 5 Oct 2023 13:37:38 +1000 Subject: [PATCH] wasm: move image to web conversion to dom:: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows other areas to utilize this Change-Id: I4bc7e8374289a19afe8b639b2b3b0dc0f8f65a3a Done-with: Mikolaj.Boc@qt.io Reviewed-by: Morten Johan Sørvig --- .../platforms/wasm/qwasmbackingstore.cpp | 36 ++--------------- src/plugins/platforms/wasm/qwasmdom.cpp | 40 +++++++++++++++++++ src/plugins/platforms/wasm/qwasmdom.h | 4 ++ 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.cpp b/src/plugins/platforms/wasm/qwasmbackingstore.cpp index f6d219dbde8..a3c1ae8a502 100644 --- a/src/plugins/platforms/wasm/qwasmbackingstore.cpp +++ b/src/plugins/platforms/wasm/qwasmbackingstore.cpp @@ -4,6 +4,7 @@ #include "qwasmbackingstore.h" #include "qwasmwindow.h" #include "qwasmcompositor.h" +#include "qwasmdom.h" #include #include @@ -75,39 +76,8 @@ void QWasmBackingStore::updateTexture(QWasmWindow *window) clippedDpiScaledRegion |= r; } - for (const QRect &dirtyRect : clippedDpiScaledRegion) { - constexpr int BytesPerColor = 4; - if (dirtyRect.width() == imageRect.width()) { - // Copy a contiguous chunk of memory - // ............... - // OOOOOOOOOOOOOOO - // OOOOOOOOOOOOOOO -> image data - // OOOOOOOOOOOOOOO - // ............... - auto imageMemory = emscripten::typed_memory_view(dirtyRect.width() * dirtyRect.height() - * BytesPerColor, - m_image.constScanLine(dirtyRect.y())); - m_webImageDataArray["data"].call("set", imageMemory, - dirtyRect.y() * m_image.width() * BytesPerColor); - } else { - // Go through the scanlines manually to set the individual lines in bulk. This is - // marginally less performant than the above. - // ............... - // ...OOOOOOOOO... r = 0 -> image data - // ...OOOOOOOOO... r = 1 -> image data - // ...OOOOOOOOO... r = 2 -> image data - // ............... - for (int r = 0; r < dirtyRect.height(); ++r) { - auto scanlineMemory = emscripten::typed_memory_view( - dirtyRect.width() * BytesPerColor, - m_image.constScanLine(r + dirtyRect.y()) + BytesPerColor * dirtyRect.x()); - m_webImageDataArray["data"].call("set", scanlineMemory, - (dirtyRect.y() + r) * m_image.width() - * BytesPerColor - + dirtyRect.x() * BytesPerColor); - } - } - } + for (const QRect &dirtyRect : clippedDpiScaledRegion) + dom::drawImageToWebImageDataArray(m_image, m_webImageDataArray, dirtyRect); m_dirty = QRegion(); } diff --git a/src/plugins/platforms/wasm/qwasmdom.cpp b/src/plugins/platforms/wasm/qwasmdom.cpp index 9aca102b2e8..ebb2dd4807a 100644 --- a/src/plugins/platforms/wasm/qwasmdom.cpp +++ b/src/plugins/platforms/wasm/qwasmdom.cpp @@ -36,6 +36,46 @@ QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF & return point + offset; } +void drawImageToWebImageDataArray(const QImage &sourceImage, emscripten::val destinationImageData, + const QRect &sourceRect) +{ + Q_ASSERT_X(destinationImageData["constructor"]["name"].as() == "ImageData", + Q_FUNC_INFO, "The destination should be an ImageData instance"); + + constexpr int BytesPerColor = 4; + if (sourceRect.width() == sourceImage.width()) { + // Copy a contiguous chunk of memory + // ............... + // OOOOOOOOOOOOOOO + // OOOOOOOOOOOOOOO -> image data + // OOOOOOOOOOOOOOO + // ............... + auto imageMemory = emscripten::typed_memory_view(sourceRect.width() * sourceRect.height() + * BytesPerColor, + sourceImage.constScanLine(sourceRect.y())); + destinationImageData["data"].call( + "set", imageMemory, sourceRect.y() * sourceImage.width() * BytesPerColor); + } else { + // Go through the scanlines manually to set the individual lines in bulk. This is + // marginally less performant than the above. + // ............... + // ...OOOOOOOOO... r = 0 -> image data + // ...OOOOOOOOO... r = 1 -> image data + // ...OOOOOOOOO... r = 2 -> image data + // ............... + for (int row = 0; row < sourceRect.height(); ++row) { + auto scanlineMemory = + emscripten::typed_memory_view(sourceRect.width() * BytesPerColor, + sourceImage.constScanLine(row + sourceRect.y()) + + BytesPerColor * sourceRect.x()); + destinationImageData["data"].call("set", scanlineMemory, + (sourceRect.y() + row) * sourceImage.width() + * BytesPerColor + + sourceRect.x() * BytesPerColor); + } + } +} + } // namespace dom QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmdom.h b/src/plugins/platforms/wasm/qwasmdom.h index 3f2e4242ef3..853e54540ec 100644 --- a/src/plugins/platforms/wasm/qwasmdom.h +++ b/src/plugins/platforms/wasm/qwasmdom.h @@ -16,6 +16,7 @@ QT_BEGIN_NAMESPACE class QPoint; +class QRect; namespace dom { inline emscripten::val document() @@ -26,6 +27,9 @@ inline emscripten::val document() void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool flag); QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point); + +void drawImageToWebImageDataArray(const QImage &source, emscripten::val destinationImageData, + const QRect &sourceRect); } // namespace dom QT_END_NAMESPACE