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