1From 714e0affdd7c0274965e291f3c90ed23867e29ee Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Fri, 12 Jun 2020 09:09:47 +0800
4Subject: [PATCH 18/28] HACK: qpaintengine_raster: Support rga in fillRect with
5 texture
6
7Use QT_USE_RGA macro to enable it.
8
9Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
10---
11 src/gui/image/qimage_p.h                 |   4 +
12 src/gui/painting/qpaintengine_raster.cpp |  46 +++++++++
13 src/gui/painting/rga.c                   | 117 +++++++++++++++++++++++
14 3 files changed, 167 insertions(+)
15 create mode 100644 src/gui/painting/rga.c
16
17diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
18index b272377f..dde06267 100644
19--- a/src/gui/image/qimage_p.h
20+++ b/src/gui/image/qimage_p.h
21@@ -282,7 +282,11 @@ inline QImage::Format qt_alphaVersion(QImage::Format format)
22     case QImage::Format_ARGB32:
23         return QImage::Format_ARGB32_Premultiplied;
24     case QImage::Format_RGB16:
25+#ifdef QT_USE_RGA
26+        return QImage::Format_ARGB32_Premultiplied;
27+#else
28         return QImage::Format_ARGB8565_Premultiplied;
29+#endif
30     case QImage::Format_RGB555:
31         return QImage::Format_ARGB8555_Premultiplied;
32     case QImage::Format_RGB666:
33diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
34index b2570069..e4d73047 100644
35--- a/src/gui/painting/qpaintengine_raster.cpp
36+++ b/src/gui/painting/qpaintengine_raster.cpp
37@@ -1474,6 +1474,10 @@ void QRasterPaintEngine::fillPath(const QPainterPath &path, QSpanData *fillData)
38     d->rasterize(d->outlineMapper->convertPath(path), blend, fillData, d->rasterBuffer.data());
39 }
40
41+#ifdef QT_USE_RGA
42+#include "rga.c"
43+#endif
44+
45 static void fillRect_normalized(const QRect &r, QSpanData *data,
46                                 QRasterPaintEnginePrivate *pe)
47 {
48@@ -1509,6 +1513,48 @@ static void fillRect_normalized(const QRect &r, QSpanData *data,
49     bool isUnclipped = rectClipped
50                        || (pe && pe->isUnclipped_normalized(QRect(x1, y1, width, height)));
51
52+#ifdef QT_USE_RGA
53+    if (pe && isUnclipped && width > 64 && height > 64) {
54+        const QPainter::CompositionMode mode = pe->rasterBuffer->compositionMode;
55+        const uchar *dst = data->rasterBuffer->buffer();
56+        int dst_stride = data->rasterBuffer->bytesPerLine();
57+        int dst_height = data->rasterBuffer->height();
58+        QImage::Format dst_format = data->rasterBuffer->format;
59+
60+        const uchar *src = data->texture.imageData;
61+        int src_stride = data->texture.bytesPerLine;
62+        int src_height = data->texture.height;
63+        QImage::Format src_format = data->texture.format;
64+
65+        if (data->type == QSpanData::Solid) {
66+#if 0 // Somehow neon is faster than rga on this
67+            if (mode == QPainter::CompositionMode_Source ||
68+                (mode == QPainter::CompositionMode_SourceOver &&
69+                 data->solid.color.isOpaque())) {
70+                if (rga_fill(dst, dst_stride, dst_height, dst_format,
71+                             data->solid.color.toArgb32(),
72+                             x1, y1, width, height))
73+                    return;
74+            }
75+#endif
76+        } else if (data->type == QSpanData::Texture) {
77+            int sx, sy, dx, dy;
78+
79+            sx = x1 - qRound(-data->dx);
80+            sy = y1 - qRound(-data->dy);
81+            dx = x1;
82+            dy = y1;
83+
84+            if (rga_blit(src, src_stride, src_height,
85+                         dst, dst_stride, dst_height,
86+                         src_format, dst_format,
87+                         sx, sy, dx, dy, width, height,
88+                         mode, data->texture.const_alpha))
89+                return;
90+        }
91+    }
92+#endif
93+
94     if (pe && isUnclipped) {
95         const QPainter::CompositionMode mode = pe->rasterBuffer->compositionMode;
96
97diff --git a/src/gui/painting/rga.c b/src/gui/painting/rga.c
98new file mode 100644
99index 00000000..7f2833ee
100--- /dev/null
101+++ b/src/gui/painting/rga.c
102@@ -0,0 +1,117 @@
103+#include <rga/rga.h>
104+#include <rga/RgaApi.h>
105+
106+static inline RgaSURF_FORMAT
107+rga_get_format(QImage::Format format)
108+{
109+    switch (format) {
110+    case QImage::Format_ARGB32:
111+    case QImage::Format_ARGB32_Premultiplied:
112+        return RK_FORMAT_BGRA_8888;
113+    case QImage::Format_RGB16:
114+        return RK_FORMAT_RGB_565;
115+    default:
116+        return RK_FORMAT_UNKNOWN;
117+    }
118+}
119+
120+static inline RgaSURF_FORMAT
121+rga_get_reverse_format(QImage::Format format)
122+{
123+    switch (format) {
124+    case QImage::Format_RGB32:
125+        return RK_FORMAT_RGBX_8888;
126+    case QImage::Format_ARGB32:
127+    case QImage::Format_ARGB32_Premultiplied:
128+        return RK_FORMAT_RGBA_8888;
129+    default:
130+        return RK_FORMAT_UNKNOWN;
131+    }
132+}
133+
134+bool rga_fill(const uchar *dst, int dst_stride, int dst_height,
135+              QImage::Format format, int color,
136+              int x, int y, int w, int h) {
137+    if (c_RkRgaInit() < 0)
138+        return false;
139+
140+    RgaSURF_FORMAT fmt = rga_get_format(format);
141+    if (fmt == RK_FORMAT_UNKNOWN) {
142+        if (format == QImage::Format_RGB32)
143+            fmt = RK_FORMAT_BGRA_8888;
144+        else
145+            return false;
146+    }
147+
148+    if (fmt == RK_FORMAT_RGB_565)
149+        dst_stride /= 2;
150+    else
151+        dst_stride /= 4;
152+
153+    rga_info_t info;
154+    memset(&info, 0, sizeof(info));
155+    info.fd = -1;
156+    info.virAddr = (void *)dst;
157+    info.mmuFlag = 1;
158+    rga_set_rect(&info.rect, x, y, w, h, dst_stride, dst_height, fmt);
159+
160+    info.color = color;
161+
162+    return c_RkRgaColorFill(&info) >= 0;
163+}
164+
165+bool rga_blit(const uchar *src, int src_stride, int src_height,
166+              const uchar *dst, int dst_stride, int dst_height,
167+              QImage::Format src_format, QImage::Format dst_format,
168+              int sx, int sy, int dx, int dy, int width, int height,
169+              QPainter::CompositionMode mode, int alpha) {
170+    if (c_RkRgaInit() < 0)
171+        return false;
172+
173+    RgaSURF_FORMAT src_fmt = rga_get_format(src_format);
174+    RgaSURF_FORMAT dst_fmt = rga_get_format(dst_format);
175+    if (src_fmt == RK_FORMAT_UNKNOWN || dst_fmt == RK_FORMAT_UNKNOWN) {
176+        src_fmt = rga_get_reverse_format(src_format);
177+        dst_fmt = rga_get_reverse_format(dst_format);
178+        if (src_fmt == RK_FORMAT_UNKNOWN || dst_fmt == RK_FORMAT_UNKNOWN)
179+            return false;
180+    }
181+
182+    if (src_fmt == RK_FORMAT_RGB_565)
183+        src_stride /= 2;
184+    else
185+        src_stride /= 4;
186+
187+    if (dst_fmt == RK_FORMAT_RGB_565)
188+        dst_stride /= 2;
189+    else
190+        dst_stride /= 4;
191+
192+    int blend = ((alpha * 255) >> 8) << 16;
193+    if (mode == QPainter::CompositionMode_Source)
194+        blend |= 0x0100;
195+    else if (src_format == QImage::Format_ARGB32_Premultiplied)
196+        blend |= 0x0105;
197+    else
198+        blend |= 0x0405;
199+
200+    rga_info_t src_info;
201+    memset(&src_info, 0, sizeof(src_info));
202+    src_info.fd = -1;
203+    src_info.virAddr = (void *)src;
204+    src_info.mmuFlag = 1;
205+    rga_set_rect(&src_info.rect, sx, sy, width, height,
206+                 src_stride, src_height, src_fmt);
207+
208+    rga_info_t dst_info;
209+    memset(&dst_info, 0, sizeof(dst_info));
210+    dst_info.fd = -1;
211+    dst_info.virAddr = (void *)dst;
212+    dst_info.mmuFlag = 1;
213+    rga_set_rect(&dst_info.rect, dx, dy, width, height,
214+                 dst_stride, dst_height, dst_fmt);
215+
216+    src_info.blend = blend;
217+
218+    return c_RkRgaBlit(&src_info, &dst_info, NULL) >= 0;
219+}
220--
2212.20.1
222
223