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:
parent
66c2dfbeba
commit
8fe920ccb0
@ -4,6 +4,7 @@
|
|||||||
#include "qwasmbackingstore.h"
|
#include "qwasmbackingstore.h"
|
||||||
#include "qwasmwindow.h"
|
#include "qwasmwindow.h"
|
||||||
#include "qwasmcompositor.h"
|
#include "qwasmcompositor.h"
|
||||||
|
#include "qwasmdom.h"
|
||||||
|
|
||||||
#include <QtGui/qpainter.h>
|
#include <QtGui/qpainter.h>
|
||||||
#include <QtGui/qbackingstore.h>
|
#include <QtGui/qbackingstore.h>
|
||||||
@ -75,39 +76,8 @@ void QWasmBackingStore::updateTexture(QWasmWindow *window)
|
|||||||
clippedDpiScaledRegion |= r;
|
clippedDpiScaledRegion |= r;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const QRect &dirtyRect : clippedDpiScaledRegion) {
|
for (const QRect &dirtyRect : clippedDpiScaledRegion)
|
||||||
constexpr int BytesPerColor = 4;
|
dom::drawImageToWebImageDataArray(m_image, m_webImageDataArray, dirtyRect);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dirty = QRegion();
|
m_dirty = QRegion();
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,46 @@ QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &
|
|||||||
return point + offset;
|
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
|
} // namespace dom
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QPoint;
|
class QPoint;
|
||||||
|
class QRect;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
inline emscripten::val document()
|
inline emscripten::val document()
|
||||||
@ -26,6 +27,9 @@ inline emscripten::val document()
|
|||||||
void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool flag);
|
void syncCSSClassWith(emscripten::val element, std::string cssClassName, bool flag);
|
||||||
|
|
||||||
QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point);
|
QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point);
|
||||||
|
|
||||||
|
void drawImageToWebImageDataArray(const QImage &source, emscripten::val destinationImageData,
|
||||||
|
const QRect &sourceRect);
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user