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