From d282cea27bf3749ad5332b7ec006c0d93a2e7e6b Mon Sep 17 00:00:00 2001
|
From: Jeffy Chen <jeffy.chen@rock-chips.com>
|
Date: Fri, 12 Jun 2020 09:09:47 +0800
|
Subject: [PATCH 22/31] HACK: qpaintengine_raster: Support rga in fillRect with
|
texture
|
|
Use QT_USE_RGA macro to enable it.
|
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
---
|
src/gui/image/qimage_p.h | 4 +
|
src/gui/painting/qpaintengine_raster.cpp | 46 +++++++++
|
src/gui/painting/rga.c | 117 +++++++++++++++++++++++
|
3 files changed, 167 insertions(+)
|
create mode 100644 src/gui/painting/rga.c
|
|
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
|
index 03ec43ea..27b9f646 100644
|
--- a/src/gui/image/qimage_p.h
|
+++ b/src/gui/image/qimage_p.h
|
@@ -258,7 +258,11 @@ inline QImage::Format qt_alphaVersion(QImage::Format format)
|
{
|
switch (format) {
|
case QImage::Format_RGB16:
|
+#ifdef QT_USE_RGA
|
+ return QImage::Format_ARGB32_Premultiplied;
|
+#else
|
return QImage::Format_ARGB8565_Premultiplied;
|
+#endif
|
case QImage::Format_RGB555:
|
return QImage::Format_ARGB8555_Premultiplied;
|
case QImage::Format_RGB666:
|
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
|
index a3e199ce..1e214705 100644
|
--- a/src/gui/painting/qpaintengine_raster.cpp
|
+++ b/src/gui/painting/qpaintengine_raster.cpp
|
@@ -1474,6 +1474,10 @@ void QRasterPaintEngine::fillPath(const QPainterPath &path, QSpanData *fillData)
|
d->rasterize(d->outlineMapper->convertPath(path), blend, fillData, d->rasterBuffer.data());
|
}
|
|
+#ifdef QT_USE_RGA
|
+#include "rga.c"
|
+#endif
|
+
|
static void fillRect_normalized(const QRect &r, QSpanData *data,
|
QRasterPaintEnginePrivate *pe)
|
{
|
@@ -1509,6 +1513,48 @@ static void fillRect_normalized(const QRect &r, QSpanData *data,
|
bool isUnclipped = rectClipped
|
|| (pe && pe->isUnclipped_normalized(QRect(x1, y1, width, height)));
|
|
+#ifdef QT_USE_RGA
|
+ if (pe && isUnclipped && width > 64 && height > 64) {
|
+ const QPainter::CompositionMode mode = pe->rasterBuffer->compositionMode;
|
+ const uchar *dst = data->rasterBuffer->buffer();
|
+ int dst_stride = data->rasterBuffer->bytesPerLine();
|
+ int dst_height = data->rasterBuffer->height();
|
+ QImage::Format dst_format = data->rasterBuffer->format;
|
+
|
+ const uchar *src = data->texture.imageData;
|
+ int src_stride = data->texture.bytesPerLine;
|
+ int src_height = data->texture.height;
|
+ QImage::Format src_format = data->texture.format;
|
+
|
+ if (data->type == QSpanData::Solid) {
|
+#if 0 // Somehow neon is faster than rga on this
|
+ if (mode == QPainter::CompositionMode_Source ||
|
+ (mode == QPainter::CompositionMode_SourceOver &&
|
+ data->solid.color.isOpaque())) {
|
+ if (rga_fill(dst, dst_stride, dst_height, dst_format,
|
+ data->solid.color.toArgb32(),
|
+ x1, y1, width, height))
|
+ return;
|
+ }
|
+#endif
|
+ } else if (data->type == QSpanData::Texture) {
|
+ int sx, sy, dx, dy;
|
+
|
+ sx = x1 - qRound(-data->dx);
|
+ sy = y1 - qRound(-data->dy);
|
+ dx = x1;
|
+ dy = y1;
|
+
|
+ if (rga_blit(src, src_stride, src_height,
|
+ dst, dst_stride, dst_height,
|
+ src_format, dst_format,
|
+ sx, sy, dx, dy, width, height,
|
+ mode, data->texture.const_alpha))
|
+ return;
|
+ }
|
+ }
|
+#endif
|
+
|
if (pe && isUnclipped) {
|
const QPainter::CompositionMode mode = pe->rasterBuffer->compositionMode;
|
|
diff --git a/src/gui/painting/rga.c b/src/gui/painting/rga.c
|
new file mode 100644
|
index 00000000..7f2833ee
|
--- /dev/null
|
+++ b/src/gui/painting/rga.c
|
@@ -0,0 +1,117 @@
|
+#include <rga/rga.h>
|
+#include <rga/RgaApi.h>
|
+
|
+static inline RgaSURF_FORMAT
|
+rga_get_format(QImage::Format format)
|
+{
|
+ switch (format) {
|
+ case QImage::Format_ARGB32:
|
+ case QImage::Format_ARGB32_Premultiplied:
|
+ return RK_FORMAT_BGRA_8888;
|
+ case QImage::Format_RGB16:
|
+ return RK_FORMAT_RGB_565;
|
+ default:
|
+ return RK_FORMAT_UNKNOWN;
|
+ }
|
+}
|
+
|
+static inline RgaSURF_FORMAT
|
+rga_get_reverse_format(QImage::Format format)
|
+{
|
+ switch (format) {
|
+ case QImage::Format_RGB32:
|
+ return RK_FORMAT_RGBX_8888;
|
+ case QImage::Format_ARGB32:
|
+ case QImage::Format_ARGB32_Premultiplied:
|
+ return RK_FORMAT_RGBA_8888;
|
+ default:
|
+ return RK_FORMAT_UNKNOWN;
|
+ }
|
+}
|
+
|
+bool rga_fill(const uchar *dst, int dst_stride, int dst_height,
|
+ QImage::Format format, int color,
|
+ int x, int y, int w, int h) {
|
+ if (c_RkRgaInit() < 0)
|
+ return false;
|
+
|
+ RgaSURF_FORMAT fmt = rga_get_format(format);
|
+ if (fmt == RK_FORMAT_UNKNOWN) {
|
+ if (format == QImage::Format_RGB32)
|
+ fmt = RK_FORMAT_BGRA_8888;
|
+ else
|
+ return false;
|
+ }
|
+
|
+ if (fmt == RK_FORMAT_RGB_565)
|
+ dst_stride /= 2;
|
+ else
|
+ dst_stride /= 4;
|
+
|
+ rga_info_t info;
|
+ memset(&info, 0, sizeof(info));
|
+ info.fd = -1;
|
+ info.virAddr = (void *)dst;
|
+ info.mmuFlag = 1;
|
+ rga_set_rect(&info.rect, x, y, w, h, dst_stride, dst_height, fmt);
|
+
|
+ info.color = color;
|
+
|
+ return c_RkRgaColorFill(&info) >= 0;
|
+}
|
+
|
+bool rga_blit(const uchar *src, int src_stride, int src_height,
|
+ const uchar *dst, int dst_stride, int dst_height,
|
+ QImage::Format src_format, QImage::Format dst_format,
|
+ int sx, int sy, int dx, int dy, int width, int height,
|
+ QPainter::CompositionMode mode, int alpha) {
|
+ if (c_RkRgaInit() < 0)
|
+ return false;
|
+
|
+ RgaSURF_FORMAT src_fmt = rga_get_format(src_format);
|
+ RgaSURF_FORMAT dst_fmt = rga_get_format(dst_format);
|
+ if (src_fmt == RK_FORMAT_UNKNOWN || dst_fmt == RK_FORMAT_UNKNOWN) {
|
+ src_fmt = rga_get_reverse_format(src_format);
|
+ dst_fmt = rga_get_reverse_format(dst_format);
|
+ if (src_fmt == RK_FORMAT_UNKNOWN || dst_fmt == RK_FORMAT_UNKNOWN)
|
+ return false;
|
+ }
|
+
|
+ if (src_fmt == RK_FORMAT_RGB_565)
|
+ src_stride /= 2;
|
+ else
|
+ src_stride /= 4;
|
+
|
+ if (dst_fmt == RK_FORMAT_RGB_565)
|
+ dst_stride /= 2;
|
+ else
|
+ dst_stride /= 4;
|
+
|
+ int blend = ((alpha * 255) >> 8) << 16;
|
+ if (mode == QPainter::CompositionMode_Source)
|
+ blend |= 0x0100;
|
+ else if (src_format == QImage::Format_ARGB32_Premultiplied)
|
+ blend |= 0x0105;
|
+ else
|
+ blend |= 0x0405;
|
+
|
+ rga_info_t src_info;
|
+ memset(&src_info, 0, sizeof(src_info));
|
+ src_info.fd = -1;
|
+ src_info.virAddr = (void *)src;
|
+ src_info.mmuFlag = 1;
|
+ rga_set_rect(&src_info.rect, sx, sy, width, height,
|
+ src_stride, src_height, src_fmt);
|
+
|
+ rga_info_t dst_info;
|
+ memset(&dst_info, 0, sizeof(dst_info));
|
+ dst_info.fd = -1;
|
+ dst_info.virAddr = (void *)dst;
|
+ dst_info.mmuFlag = 1;
|
+ rga_set_rect(&dst_info.rect, dx, dy, width, height,
|
+ dst_stride, dst_height, dst_fmt);
|
+
|
+ src_info.blend = blend;
|
+
|
+ return c_RkRgaBlit(&src_info, &dst_info, NULL) >= 0;
|
+}
|
--
|
2.20.1
|