wasm: move image to web conversion to dom::

This allows other areas to utilize this

Change-Id: I4bc7e8374289a19afe8b639b2b3b0dc0f8f65a3a
Done-with: Mikolaj.Boc@qt.io
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Lorn Potter 2023-10-05 13:37:38 +10:00
parent 66c2dfbeba
commit 8fe920ccb0
3 changed files with 47 additions and 33 deletions

View File

@ -4,6 +4,7 @@
#include "qwasmbackingstore.h"
#include "qwasmwindow.h"
#include "qwasmcompositor.h"
#include "qwasmdom.h"
#include <QtGui/qpainter.h>
#include <QtGui/qbackingstore.h>
@ -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<void>("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<void>("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();
}

View File

@ -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<std::string>() == "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<void>(
"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<void>("set", scanlineMemory,
(sourceRect.y() + row) * sourceImage.width()
* BytesPerColor
+ sourceRect.x() * BytesPerColor);
}
}
}
} // namespace dom
QT_END_NAMESPACE

View File

@ -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