summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qdrawhelper.cpp23
-rw-r--r--src/gui/painting/qdrawhelper_mips_dsp.cpp97
-rw-r--r--src/gui/painting/qdrawhelper_mips_dsp_asm.S478
-rw-r--r--src/gui/painting/qdrawhelper_mips_dsp_p.h45
-rw-r--r--src/gui/painting/qdrawhelper_mips_dspr2_asm.S550
-rw-r--r--src/gui/painting/qpainter.cpp5
-rw-r--r--src/gui/painting/qt_mips_asm_dsp_p.h166
7 files changed, 1348 insertions, 16 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c90b9ef365..39193dd093 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -436,12 +436,6 @@ inline void QT_FASTCALL storePixel<QPixelLayout::BPP24>(uchar *dest, int index,
reinterpret_cast<quint24 *>(dest)[index] = quint24(pixel);
}
-template <>
-inline void QT_FASTCALL storePixel<QPixelLayout::BPP32>(uchar *dest, int index, uint pixel)
-{
- reinterpret_cast<uint *>(dest)[index] = pixel;
-}
-
template <QPixelLayout::BPP width>
inline void QT_FASTCALL storePixels(uchar *dest, const uint *src, int index, int count)
{
@@ -1859,7 +1853,7 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
return buffer;
}
-static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
+static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
// Untransformed
{
0, // Invalid
@@ -6385,6 +6379,21 @@ void qInitDrawhelperAsm()
destStoreProc[QImage::Format_ARGB32] = qt_destStoreARGB32_mips_dsp;
+ sourceFetch[BlendUntransformed][QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
+ sourceFetch[BlendTiled][QImage::Format_RGB888] = qt_fetchUntransformed_888_mips_dsp;
+
+ sourceFetch[BlendUntransformed][QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
+ sourceFetch[BlendTiled][QImage::Format_RGB444] = qt_fetchUntransformed_444_mips_dsp;
+
+ sourceFetch[BlendUntransformed][QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
+ sourceFetch[BlendTiled][QImage::Format_ARGB8565_Premultiplied] = qt_fetchUntransformed_argb8565_premultiplied_mips_dsp;
+
+#if defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2)
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dspr2;
+#else
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_mips_dsp;
+#endif // QT_COMPILER_SUPPORTS_MIPS_DSPR2
+
#endif // QT_COMPILER_SUPPORTS_MIPS_DSP
if (functionForModeSolidAsm) {
const int destinationMode = QPainter::CompositionMode_Destination;
diff --git a/src/gui/painting/qdrawhelper_mips_dsp.cpp b/src/gui/painting/qdrawhelper_mips_dsp.cpp
index a9b551c226..2202b78ce8 100644
--- a/src/gui/painting/qdrawhelper_mips_dsp.cpp
+++ b/src/gui/painting/qdrawhelper_mips_dsp.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Copyright (C) 2013 Imagination Technologies Limited, www.imgtec.com
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -110,6 +110,78 @@ void qt_blend_rgb32_on_rgb32_mips_dsp(uchar *destPixels, int dbpl,
}
}
+#if defined QT_COMPILER_SUPPORTS_MIPS_DSPR2
+void qt_blend_rgb16_on_rgb16_mips_dspr2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ if (w < 256) {
+ const quint16 *src = (const quint16*) srcPixels;
+ quint16 *dst = (quint16*) destPixels;
+ for (int y = 0; y < h; ++y) {
+ qt_blend_rgb16_on_rgb16_const_alpha_256_mips_dsp_asm(dst, src, w);
+ dst = (quint16*) (((uchar*) dst) + dbpl);
+ src = (quint16*) (((uchar*) src) + sbpl);
+ }
+ }
+ else {
+ int length = w << 1;
+ while (h--) {
+ memcpy(destPixels, srcPixels, length);
+ destPixels += dbpl;
+ srcPixels += sbpl;
+ }
+ }
+ }
+ else if (const_alpha != 0) {
+ const quint16 *src = (const quint16*) srcPixels;
+ quint16 *dst = (quint16*) destPixels;
+ for (int y = 0; y < h; ++y) {
+ qt_blend_rgb16_on_rgb16_mips_dspr2_asm(dst, src, w, const_alpha);
+ dst = (quint16*) (((uchar*) dst) + dbpl);
+ src = (quint16*) (((uchar*) src) + sbpl);
+ }
+ }
+}
+#else
+void qt_blend_rgb16_on_rgb16_mips_dsp(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ if (const_alpha == 256) {
+ if (w < 256) {
+ const quint16 *src = (const quint16*) srcPixels;
+ quint16 *dst = (quint16*) destPixels;
+ for (int y = 0; y < h; ++y) {
+ qt_blend_rgb16_on_rgb16_const_alpha_256_mips_dsp_asm(dst, src, w);
+ dst = (quint16*) (((uchar*) dst) + dbpl);
+ src = (quint16*) (((uchar*) src) + sbpl);
+ }
+ }
+ else {
+ int length = w << 1;
+ while (h--) {
+ memcpy(destPixels, srcPixels, length);
+ destPixels += dbpl;
+ srcPixels += sbpl;
+ }
+ }
+ }
+ else if (const_alpha != 0) {
+ const quint16 *src = (const quint16*) srcPixels;
+ quint16 *dst = (quint16*) destPixels;
+ for (int y = 0; y < h; ++y) {
+ qt_blend_rgb16_on_rgb16_mips_dsp_asm(dst, src, w, const_alpha);
+ dst = (quint16*) (((uchar*) dst) + dbpl);
+ src = (quint16*) (((uchar*) src) + sbpl);
+ }
+ }
+}
+#endif
+
void comp_func_Source_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha)
{
if (const_alpha == 255) {
@@ -422,5 +494,28 @@ void QT_FASTCALL comp_func_SourceOut_mips_dsp(uint *dest, const uint *src, int l
comp_func_SourceOut_dsp_asm_x2(dest, src, length, const_alpha);
}
+const uint * QT_FASTCALL qt_fetchUntransformed_888_mips_dsp (uint *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
+{
+ uchar *line = (uchar *)data->texture.scanLine(y) + x;
+ fetchUntransformed_888_asm_mips_dsp(buffer, line, length);
+ return buffer;
+}
+
+const uint * QT_FASTCALL qt_fetchUntransformed_444_mips_dsp (uint *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
+{
+ uchar *line = (uchar *)data->texture.scanLine(y) + x;
+ fetchUntransformed_444_asm_mips_dsp(buffer, line, length);
+ return buffer;
+}
+
+const uint * QT_FASTCALL qt_fetchUntransformed_argb8565_premultiplied_mips_dsp (uint *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
+{
+ uchar *line = (uchar *)data->texture.scanLine(y) + x;
+ fetchUntransformed_argb8565_premultiplied_asm_mips_dsp(buffer, line, length);
+ return buffer;
+}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_mips_dsp_asm.S b/src/gui/painting/qdrawhelper_mips_dsp_asm.S
index 64fc635970..26b48f9d62 100644
--- a/src/gui/painting/qdrawhelper_mips_dsp_asm.S
+++ b/src/gui/painting/qdrawhelper_mips_dsp_asm.S
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Copyright (C) 2013 Imagination Technologies Limited, www.imgtec.com
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -1601,3 +1601,479 @@ LEAF_MIPS_DSP(qt_blend_argb32_on_argb32_const_alpha_256_mips_dsp_asm)
nop
END(qt_blend_argb32_on_argb32_const_alpha_256_mips_dsp_asm)
+
+
+#if defined(__MIPSEL) && __MIPSEL
+# define PACK(r, s, t) packrl.ph r, s, t
+# define SWHI(r, o, b) swl r, o + 1 (b)
+# define SWLO(r, o, b) swr r, o + 0 (b)
+# define LDHI(r, o, b) lwl r, o + 1 (b)
+# define LDLO(r, o, b) lwr r, o + 2 (b)
+#else
+# define PACK(r, s, t) packrl.ph r, t, s
+# define SWHI(r, o, b) swr r, o + 1 (b)
+# define SWLO(r, o, b) swl r, o + 0 (b)
+# define LDHI(r, o, b) lwr r, o + 1 (b)
+# define LDLO(r, o, b) lwl r, o + 2 (b)
+#endif
+
+LEAF_MIPS_DSP(qt_blend_rgb16_on_rgb16_const_alpha_256_mips_dsp_asm)
+/*
+ * a0 - dst (*r5g6b5)
+ * a1 - src (const *r5g6b5)
+ * a2 - len (unsigned int)
+ *
+ * Register usage:
+ * t0-3 - Scratch registers
+ * t4 - Number of iterations to do in unrolled loops
+ * t5-7 - Auxiliary scratch registers.
+ *
+ * Check if base addresses of src/dst are aligned, cases:
+ * a) Both aligned.
+ * b) Both unaligned:
+ * 1. Copy a halfword
+ * 2. Use aligned case.
+ * c) dst aligned, src unaligned:
+ * 1. Read a word from dst, halfword from src.
+ * 2. Continue reading words from both.
+ * d) dst unaligned, src aligned:
+ * 1. Read a word from src, halfword from dst.
+ * 2. Continue reading words from both.
+ */
+
+ beqz a2, 0f /* if (a2:len == 0): return */
+ andi t0, a0, 0x3 /* t0 = a0:dst % 4 */
+ andi t1, a1, 0x3 /* t1 = a1:dst % 4 */
+ or t2, t0, t1 /* t1 = t0 | t1 */
+
+ beqz t2, 4f /* both aligned */
+ nop
+ beqz t0, 3f /* dst aligned, src unaligned */
+ nop
+ beqz t1, 2f /* src aligned, dst unaligned */
+ nop
+
+ /*
+ * Both src/dst are unaligned: read 1 halfword from each,
+ * the fall-off to continue with word-aligned copy.
+ */
+ lhu t0, 0 (a1) /* t0 <- ((uint16_t*) src)[0] */
+ addiu a1, a1, 2 /* src++ */
+ addiu a2, a2,-1 /* len-- */
+ sh t0, 0 (a0) /* t1 -> ((uint16_t*) dst)[0] */
+ addiu a0, a0, 2 /* dst++ */
+
+ /*
+ * Both src/dst pointers are word-aligned, process eight
+ * items at a time in an unrolled loop.
+ */
+4: beqz a2, 0f /* if (len == 0): return */
+ srl t4, a2, 3 /* t4 = len / 8 */
+
+ beqz t4, 5f /* if (t4 == 0): tail */
+ andi a2, a2, 0x07 /* len = len % 8 */
+
+1: lw t0, 0 (a1)
+ lw t1, 4 (a1)
+ lw t2, 8 (a1)
+ lw t3, 12 (a1)
+
+ addiu t4, t4, -1 /* t4-- */
+ addiu a1, a1, 16 /* src += 8 */
+
+ sw t0, 0 (a0)
+ sw t1, 4 (a0)
+ sw t2, 8 (a0)
+ sw t3, 12 (a0)
+
+ bnez t4, 1b
+ addiu a0, a0, 16 /* dst += 8 */
+
+ b 5f
+ nop
+
+
+ /*
+ * dst pointer is unaligned
+ */
+2: beqz a2, 0f /* if (len == 0): return */
+ srl t4, a2, 3 /* t4 = len / 8 */
+ beqz t4, 5f /* if (t4 == 0): tail */
+ andi a2, a2, 0x07 /* len = len % 8 */
+
+1: lw t0, 0 (a1)
+ lw t1, 4 (a1)
+ lw t2, 8 (a1)
+ lw t3, 12 (a1)
+
+ addiu t4, t4, -1 /* t4-- */
+ addiu a1, a1, 16 /* src += 8 */
+
+ SWLO (t0, 0, a0)
+ PACK (t5, t1, t0)
+ PACK (t6, t2, t1)
+ PACK (t7, t3, t2)
+ SWHI (t3, 14, a0)
+ sw t5, 2 (a0)
+ sw t6, 6 (a0)
+ sw t7, 10 (a0)
+
+ bnez t4, 1b
+ addiu a0, a0, 16 /* dst += 8 */
+
+ b 5f
+ nop
+
+ /*
+ * src pointer is unaligned
+ */
+3: beqz a2, 0f /* if (len == 0): return */
+ srl t4, a2, 3 /* t4 = len / 8 */
+ beqz t4, 5f /* if (t4 == 0): tail */
+ andi a2, a2, 0x07 /* len = len % 8 */
+
+1: LDHI (t0, 0, a1)
+ lw t1, 2 (a1)
+ lw t2, 6 (a1)
+ lw t3, 10 (a1)
+ LDLO (t5, 12, a1)
+
+ addiu t4, t4, -1 /* t4-- */
+ addiu a1, a1, 16 /* src += 8 */
+
+ PACK (t0, t1, t0)
+ PACK (t6, t2, t1)
+ PACK (t7, t3, t2)
+ sw t0, 0 (a0)
+ PACK (t0, t5, t3)
+ sw t6, 4 (a0)
+ sw t7, 8 (a0)
+ sw t0, 12 (a0)
+
+ bnez t4, 1b
+ addiu a0, a0, 16 /* dst += 8 */
+
+
+5: /* Process remaining items (a2:len < 4), one at a time */
+ beqz a2, 0f
+ nop
+
+1: lhu t0, 0 (a1) /* t0 <- ((uint16_t*) src)[0] */
+ addiu a2, a2,-1 /* len-- */
+ addiu a1, a1, 2 /* src++ */
+ sh t0, 0 (a0) /* to -> ((uint16_t*) dst)[0] */
+ bnez a2, 1b /* if (len != 0): loop */
+ addiu a0, a0, 2 /* dst++ */
+
+0: jr ra
+ nop
+
+END(qt_blend_rgb16_on_rgb16_const_alpha_256_mips_dsp_asm)
+
+
+#undef LDHI
+#undef LDLO
+#undef PACK
+#undef SWHI
+#undef SWLO
+
+
+LEAF_MIPS_DSP(qt_blend_rgb16_on_rgb16_mips_dsp_asm)
+/*
+ * a0 - dst (*r5g6b5)
+ * a1 - src (const *r5g6b5)
+ * a2 - len (unsigned int) - batch length
+ * a3 - alpha (int)
+ */
+
+ beqz a2, 2f
+ li t9, 255
+ sll t8, a3, 8
+ subu a3, t8, a3
+ srl a3, a3, 8
+ subu t9, t9, a3
+ addiu a3, a3, 1
+ srl t4, a3, 2
+ addiu t9, t9, 1
+ srl t5, t9, 2
+1:
+ lhu t0, 0(a1)
+ lhu t1, 0(a0)
+ addiu a2, a2, -1
+ andi t2, t0, 0x07e0
+ andi t0, t0, 0xf81f
+ mul t2, t2, a3
+ mul t0, t0, t4
+ andi t3, t1, 0x07e0
+ andi t1, t1, 0xf81f
+ mul t3, t3, t9
+ mul t1, t1, t5
+ addiu a1, a1, 2
+ srl t2, t2, 8
+ srl t0, t0, 6
+ andi t2, t2, 0x07e0
+ andi t0, t0, 0xf81f
+ or t0, t0, t2
+ srl t3, t3, 8
+ srl t1, t1, 6
+ andi t3, t3, 0x07e0
+ andi t1, t1, 0xf81f
+ or t1, t1, t3
+ addu t0, t0, t1
+ sh t0, 0(a0)
+ bgtz a2, 1b
+ addiu a0, a0, 2
+2:
+ jr ra
+ nop
+
+END(qt_blend_rgb16_on_rgb16_mips_dsp_asm)
+
+
+LEAF_MIPS_DSP(fetchUntransformed_888_asm_mips_dsp)
+/*
+ * a0 - dst address (address of 32-bit aRGB value)
+ * a1 - src address
+ * a2 - length
+ */
+
+ beqz a2, 4f
+ lui t8, 0xff00
+ andi t0, a2, 0x1
+ beqz t0, 1f
+ nop
+/* case for one pixel */
+ lbu t1, 0(a1)
+ lbu v1, 2(a1)
+ lbu t0, 1(a1)
+ addiu a1, a1, 3
+ addiu a2, a2, -1
+ sll t1, t1, 0x10
+ or v1, v1, t8
+ sll t0, t0, 0x8
+ or v1, v1, t1
+ or v1, v1, t0
+ sw v1, 0(a0)
+ addiu a0, a0, 4
+
+ beqz a2, 4f /* only one pixel is present (length = 1) */
+ nop
+1:
+ andi t0, a1, 0x1
+ beqz t0, 3f
+ nop
+2:
+ lbu t0, 0(a1) /* t0 = | 0 | 0 | 0 | R1 | */
+ lhu t1, 1(a1) /* t1 = | 0 | 0 | B1 | G1 | */
+ addiu a1, a1, 3
+ lhu t2, 0(a1) /* t2 = | 0 | 0 | G2 | R2 | */
+ lbu t3, 2(a1) /* t3 = | 0 | 0 | 0 | B2 | */
+
+ sll t0, t0, 16
+ or t0, t0, t8 /* t0 = | ff | R1 | 0 | 0 | */
+ shll.ph t4, t1, 8 /* t4 = | 0 | 0 | G1 | 0 | */
+ srl t5, t1, 8
+ or t4, t4, t5 /* t4 = | 0 | 0 | G1 | B1 | */
+ or t0, t0, t4 /* t0 = | ff | R1 | G1 | B1 | */
+
+ shll.ph t4, t2, 8 /* t4 = | 0 | 0 | R2 | 0 | */
+ srl t5, t2, 8 /* t5 = | 0 | 0 | 0 | G2 | */
+ or t4, t4, t5
+ sll t4, t4, 8 /* t4 = | 0 | R2 | G2 | 0 | */
+ or t5, t3, t8
+ or t2, t4, t5 /* t2 = | ff | R2 | G2 | B2 | */
+
+ sw t0, 0(a0)
+ addiu a1, a1, 3
+ sw t2, 4(a0)
+ addiu a2, a2, -2
+ bnez a2, 2b
+ addiu a0, a0, 8
+ b 4f
+ nop
+3:
+ lhu t0, 0(a1) /* t0 = | 0 | 0 | G1 | R1 | */
+ lbu t1, 2(a1) /* t1 = | 0 | 0 | 0 | B1 | */
+ addiu a1, a1, 3
+ lbu t2, 0(a1) /* t2 = | 0 | 0 | 0 | R2 | */
+ lhu t3, 1(a1) /* t3 = | 0 | 0 | B2 | G2 | */
+
+ srl t4, t0, 8 /* t4 = | 0 | 0 | 0 | G1 | */
+ shll.ph t5, t0, 8 /* t5 = | 0 | 0 | R1 | 0 | */
+ or t0, t4, t5
+ sll t6, t0, 8 /* t6 = | 0 | R1 | G1 | 0 | */
+ or t4, t1, t8 /* t4 = | ff | 0 | 0 | B1 | */
+ or t0, t6, t4
+
+ sll t2, t2, 16
+ srl t4, t3, 8
+ shll.ph t5, t3, 8
+ or t3, t4, t5
+ or t2, t2, t3
+ or t2, t2, t8
+
+ sw t0, 0(a0)
+ addiu a1, a1, 3
+ sw t2, 4(a0)
+ addiu a2, a2, -2
+ bnez a2, 3b
+ addiu a0, a0, 8
+4:
+ jr ra
+ nop
+
+END(fetchUntransformed_888_asm_mips_dsp)
+
+
+LEAF_MIPS_DSP(fetchUntransformed_444_asm_mips_dsp)
+/*
+ * a0 - dst address (address of 32-bit aRGB value)
+ * a1 - src address
+ * a2 - length
+ */
+
+ lui t8, 0xff00
+ li t4, 0x1
+
+ beqz a2, 5f
+ move v0, a0 /* just return the address of buffer
+ * for storing returning values */
+ andi t0, a2, 0x1
+ beqz t0, 2f /* there is more then one pixel
+ * (check src memory alignment (word)) */
+ nop
+1:
+ lhu v0, 0(a1)
+ addiu a1, a1, 2
+ addiu a2, a2, -1
+ andi t0, v0, 0xf00
+ andi v1, v0, 0xf
+ andi v0, v0, 0xf0
+ sra t3, t0, 0x4
+ sra t1, v0, 0x4
+ sra t0, t0, 0x8
+ sll t2, v1, 0x4
+ or t0, t0, t3
+ or v0, t1, v0
+ lui t1, 0xff00
+ or v1, t2, v1
+ sll t0, t0, 0x10
+ or v1, v1, t1
+ sll v0, v0, 0x8
+ or v1, v1, t0
+ or v0, v1, v0
+ sw v0, 0(a0)
+ addiu a0, a0, 4
+ beqz a2, 5f /* no more pixels for processing */
+ nop
+ beq a2, t4, 4f /* only one more pixel remained */
+ nop
+/* check if src memory address is word aligned */
+2:
+ andi t0, a1, 0x3
+ beqz t0, 3f /* memory is word aligned */
+ andi a3, a2, 0x1 /* set the a3 register as the comparation
+ * for ending the unrolled loop
+ * (1 if odd, 0 if even) */
+ b 1b /* not word aligned,
+ * go another turn with
+ * just one pixel processing */
+ nop
+3:
+ lw t0, 0(a1)
+ addiu a2, a2, -2
+ preceu.ph.qbr t1, t0 /* t1 = | 0 | aR1 | 0 | G1B1 | */
+ preceu.ph.qbl t2, t0 /* t1 = | 0 | aR2 | 0 | G2B2 | */
+ shll.qb t3, t1, 4 /* t3 = | 0 | R1 0 | 0 | B1 0 | */
+ srl t4, t3, 4
+ or t0, t3, t4 /* t0 = | 0 | R1R1 | 0 | B1B1 | */
+ andi t3, t1, 0xf0
+ sll t3, t3, 8
+ srl t4, t3, 4
+ or t1, t3, t4
+ or t0, t0, t1 /* t0 = | 0 | R1R1 | G1G1 | B1B1 | */
+ or t0, t0, t8 /* t0 = | ff | R1R1 | G1G1 | B1B1 | */
+
+ shll.qb t3, t2, 4 /* t3 = | 0 | R1 0 | 0 | B1 0 | */
+ srl t4, t3, 4
+ or t7, t3, t4 /* t0 = | 0 | R1R1 | 0 | B1B1 | */
+ andi t3, t2, 0xf0
+ sll t3, t3, 8
+ srl t4, t3, 4
+ or t1, t3, t4
+ or t2, t7, t1 /* t0 = | 0 | R1R1 | G1G1 | B1B1 | */
+ or t2, t2, t8 /* t0 = | ff | R1R1 | G1G1 | B1B1 | */
+
+ sw t0, 0(a0)
+ addiu a1, a1, 4
+ sw t2, 4(a0)
+ bne a2, a3, 3b
+ addiu a0, a0, 8
+ beqz a2, 5f /* no more pixels for processing */
+ nop
+4:
+/* one more pixel remained (after loop unrolling process finished) */
+ lhu v0, 0(a1)
+ addiu a1, a1, 2
+ addiu a2, a2, -1
+ andi t0, v0, 0xf00
+ andi v1, v0, 0xf
+ andi v0, v0, 0xf0
+ sra t3, t0, 0x4
+ sra t1, v0, 0x4
+ sra t0, t0, 0x8
+ sll t2, v1, 0x4
+ or t0, t0, t3
+ or v0, t1, v0
+ lui t1, 0xff00
+ or v1, t2, v1
+ sll t0, t0, 0x10
+ or v1, v1, t1
+ sll v0, v0, 0x8
+ or v1, v1, t0
+ or v0, v1, v0
+ sw v0, 0(a0)
+ addiu a0, a0, 4
+5:
+ jr ra
+ nop
+
+END(fetchUntransformed_444_asm_mips_dsp)
+
+
+LEAF_MIPS_DSP(fetchUntransformed_argb8565_premultiplied_asm_mips_dsp)
+/*
+ * a0 - dst address
+ * a1 - src address
+ * a2 - length
+ */
+
+ beqz a2, 2f
+ nop
+
+1:
+ ulh t1, 0(a1)
+ lbu t2, 2(a1)
+ addiu a2, a2, -1
+ wsbh t1, t1
+ sll t0, t1, 8 /* t0 = 00000000rrrrrggggggbbbbb00000000 */
+ ins t0, t1, 3, 16 /* t0 = 00000000rrrrrrrrrrggggggbbbbb000 */
+ ins t0, t1, 5, 11 /* t0 = 00000000rrrrrrrrggggggbbbbbbb000 */
+ srl t4, t1, 9 /* t4 = 0000000000000000000000000rrrrrgg */
+ replv.qb t3, t2
+ ins t0, t4, 8, 2 /* t0 = 00000000rrrrrrrrggggggggbbbbb000 */
+ ins t0, t1, 3, 5 /* t0 = 00000000rrrrrrrrggggggggbbbbb000 */
+ srl t4, t1, 2 /* t4 = 000000000000000000rrrrrggggggbbb */
+ ins t0, t4, 0, 3 /* t0 = 00000000rrrrrrrrggggggggbbbbbbbb */
+ ins t0, t2, 24, 8 /* t0 =aaaaaaaarrrrrrrrggggggggbbbbbbbb */
+ cmpu.lt.qb t3, t0
+ pick.qb t0, t3, t0
+ addiu a1, a1, 3
+ sw t0, 0(a0)
+ bgtz a2, 1b
+ addiu a0, a0, 4
+2:
+ jr ra
+ nop
+
+END(fetchUntransformed_argb8565_premultiplied_asm_mips_dsp)
diff --git a/src/gui/painting/qdrawhelper_mips_dsp_p.h b/src/gui/painting/qdrawhelper_mips_dsp_p.h
index 2df7d4920a..3dceb7793d 100644
--- a/src/gui/painting/qdrawhelper_mips_dsp_p.h
+++ b/src/gui/painting/qdrawhelper_mips_dsp_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Copyright (C) 2013 Imagination Technologies Limited, www.imgtec.com
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -101,19 +101,34 @@ extern "C" void qt_blend_argb32_on_argb32_mips_dsp_asm_x2(uint *dest, const uint
extern "C" void qt_blend_argb32_on_argb32_const_alpha_256_mips_dsp_asm(uint *dest, const uint *src, int length);
+extern "C" void qt_blend_rgb16_on_rgb16_const_alpha_256_mips_dsp_asm(quint16 *dest, const quint16 *src, int length);
+
+extern "C" void qt_blend_rgb16_on_rgb16_mips_dsp_asm(quint16 *dest, const quint16 *src, int length, uint const_alpha);
+
extern "C" uint * destfetchARGB32_asm_mips_dsp(uint *buffer, const uint *data, int length);
extern "C" uint * qt_destStoreARGB32_asm_mips_dsp(uint *buffer, const uint *data, int length);
+extern "C" uint * fetchUntransformed_888_asm_mips_dsp(uint *buffer, const uchar *line, int length);
+
+extern "C" uint * fetchUntransformed_444_asm_mips_dsp(uint *buffer, const uchar *line, int length);
+
+extern "C" uint * fetchUntransformed_argb8565_premultiplied_asm_mips_dsp(uint *buffer, const uchar *line, int length);
+
void qt_blend_argb32_on_argb32_mips_dsp(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha);
void qt_blend_rgb32_on_rgb32_mips_dsp(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+void qt_blend_rgb16_on_rgb16_mips_dsp(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
void comp_func_Source_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha);
@@ -164,6 +179,21 @@ void QT_FASTCALL comp_func_SourceOut_mips_dsp(uint *dest, const uint *src, int l
void QT_FASTCALL comp_func_XOR_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha);
+const uint * QT_FASTCALL qt_fetchUntransformed_888_mips_dsp (uint *buffer,
+ const Operator *,
+ const QSpanData *data,
+ int y, int x, int length);
+
+const uint * QT_FASTCALL qt_fetchUntransformed_444_mips_dsp (uint *buffer,
+ const Operator *,
+ const QSpanData *data,
+ int y, int x, int length);
+
+const uint * QT_FASTCALL qt_fetchUntransformed_argb8565_premultiplied_mips_dsp (uint *buffer,
+ const Operator *,
+ const QSpanData *data,
+ int y, int x, int length);
+
#endif // QT_COMPILER_SUPPORTS_MIPS_DSP
@@ -171,6 +201,13 @@ void QT_FASTCALL comp_func_XOR_mips_dsp(uint *dest, const uint *src, int length,
extern "C" void qConvertRgb16To32_asm_mips_dspr2(quint32 *dest, const quint16 *src, int length);
+extern "C" void qt_blend_rgb16_on_rgb16_mips_dspr2_asm(quint16 *dest, const quint16 *src, int length, uint const_alpha);
+
+void qt_blend_rgb16_on_rgb16_mips_dspr2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
#endif // QT_COMPILER_SUPPORTS_MIPS_DSPR2
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_mips_dspr2_asm.S b/src/gui/painting/qdrawhelper_mips_dspr2_asm.S
index ec220732be..c7a603eebe 100644
--- a/src/gui/painting/qdrawhelper_mips_dspr2_asm.S
+++ b/src/gui/painting/qdrawhelper_mips_dspr2_asm.S
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Copyright (C) 2013 Imagination Technologies Limited, www.imgtec.com
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -122,3 +122,551 @@ LEAF_MIPS_DSPR2(qConvertRgb16To32_asm_mips_dspr2)
nop
END(qConvertRgb16To32_asm_mips_dspr2)
+
+
+#if defined(__MIPSEL) && __MIPSEL
+# define PACK(r, s, t) packrl.ph r, s, t
+# define LDHI(r, o, b) lwl r, o + 1 (b)
+# define LDLO(r, o, b) lwr r, o + 2 (b)
+#else
+# define PACK(r, s, t) packrl.ph r, t, s
+# define LDHI(r, o, b) lwr r, o + 1 (b)
+# define LDLO(r, o, b) lwl r, o + 2 (b)
+#endif
+
+
+LEAF_MIPS_DSPR2(qt_blend_rgb16_on_rgb16_mips_dspr2_asm)
+/*
++ * a0 - dst (*r5g6b5)
+ * a1 - src (const *r5g6b5)
+ * a2 - len (unsigned int) - batch length
+ * a3 - alpha (int)
+ *
+ * Register usage:
+ * t0-3 - Scratch registers
+ * t4 - Number of iterations to do in unrolled loops
+ * t5 - Inverse alpha
+ * t6 - Alpha >> 2
+ * t7 - Inverse alpha >> 2
+ * t8 - magic1 (0x07e007e0)
+ * t9 - magic2 (0xf81ff81f)
+ *
+ * NOTE:
+ * Cannot use DSP instructions for the multiplication of two
+ * 16-bit values: overflow would be always rounded or saturated.
+ */
+
+ beqz a2, 0f
+ andi t0, a0, 0x3
+ andi t1, a1, 0x3
+ /* Adjust alpha value, and calculate inverse alpha value */
+ li t5, 255
+ or t2, t0, t1 /* t0 = (dst & 0x3) | (src & 0x3) */
+ sll t8, a3, 8
+ subu a3, t8, a3
+ li t8, 0x07e007e0 /* magic1 */
+ srl a3, a3, 8 /* alpha >>= 8 */
+ li t9, 0xf81ff81f /* magic2 */
+ subu t5, t5, a3 /* ialpha = 255 - alpha */
+ addiu a3, a3, 1 /* alpha++ */
+ addiu t5, t5, 1 /* ialpha++ */
+ srl t6, a3, 2 /* ashift = alpha >> 2 */
+
+ beqz t2, 4f /* both aligned */
+ srl t7, t5, 2 /* iashift = ialpha >> 2 */
+
+ beqz t1, 2f /* src aligned, dst unaligned */
+ nop
+
+ beqz t0, 3f /* dst aligned, src unaligned */
+ nop
+
+ /*
+ * Both src/dst are unaligned: read 1 halfword from each, then
+ * fall-off to continue with word-aligned operation.
+ */
+ lhu t1, 0 (a1)
+ lhu t0, 0 (a0)
+ addiu a2, a2, -1 /* len-- */
+ andi t2, t1, 0x07e0
+ andi t1, t1, 0xf81f
+ mul t2, t2, a3
+ mul t1, t1, t6
+ andi t3, t0, 0x07e0
+ andi t0, t0, 0xf81f
+ mul t3, t3, t5
+ mul t0, t0, t7
+ addiu a1, a1, 2 /* src++ */
+ srl t2, t2, 8
+ srl t1, t1, 6
+ andi t2, t2, 0x07e0
+ andi t1, t1, 0xf81f
+ or t1, t1, t2
+ srl t3, t3, 8
+ srl t0, t0, 6
+ andi t3, t3, 0x07e0
+ andi t0, t0, 0xf81f
+ or t0, t0, t3
+ addu t0, t0, t1 /* src * alpha + dst * ialpha */
+ sh t0, 0 (a0)
+ addiu a0, a0, 2 /* dst++ */
+
+ /*
+ * Both src/dst pointers are word-aligned, process eight
+ * items at a time in an unrolled loop.
+ */
+4: beqz a2, 0f
+ srl t4, a2, 3 /* t4 = len / 8 */
+ beqz t4, 5f
+ andi a2, a2, 0x7 /* len = len % 8 */
+ SAVE_REGS_ON_STACK 12, s0, s1, s2, s3, s4, v0, v1
+
+1: lw t1, 0 (a1) /* [s0, s1] */
+ lw v1, 4 (a1) /* [s2, s3] */
+ lw s1, 8 (a1) /* [s4, s5] */
+ lw s3, 12 (a1) /* [s6, s7] */
+
+ lw t0, 0 (a0) /* [d0, d1] */
+ lw v0, 4 (a0) /* [d2, d3] */
+ lw s0, 8 (a0) /* [d4, d5] */
+ lw s2, 12 (a0) /* [d6, d7] */
+
+ pref 4, 16 (a1)
+ pref 5, 16 (a0)
+
+ and t2, t1, t8
+ ext t3, t2, 0, 16
+ srl t2, t2, 16
+ mul t3, t3, a3
+ mul t2, t2, a3
+ and t1, t1, t9
+ ext s4, t1, 0, 16
+ mul s4, s4, t6
+ srl t1, t1, 16
+ mul t1, t1, t6
+ srl t3, t3, 8
+ srl t2, t2, 8
+ append t2, t3, 16
+ and t2, t2, t8
+ srl s4, s4, 6
+ and t3, v1, t8
+ srl t1, t1, 6
+ append t1, s4, 16
+ and t1, t1, t9
+ or t1, t1, t2
+ ext t2, t3, 0, 16
+ srl t3, t3, 16
+ mul t2, t2, a3
+ mul t3, t3, a3
+ and v1, v1, t9
+ ext s4, v1, 0, 16
+ mul s4, s4, t6
+ srl v1, v1, 16
+ mul v1, v1, t6
+ srl t2, t2, 8
+ srl t3, t3, 8
+ append t3, t2, 16
+ and t3, t3, t8
+ srl s4, s4, 6
+ and t2, s1, t8
+ srl v1, v1, 6
+ append v1, s4, 16
+ and v1, v1, t9
+ or v1, v1, t3
+ ext t3, t2, 0, 16
+ srl t2, t2, 16
+ mul t3, t3, a3
+ mul t2, t2, a3
+ and s1, s1, t9
+ ext s4, s1, 0, 16
+ mul s4, s4, t6
+ srl s1, s1, 16
+ mul s1, s1, t6
+ srl t3, t3, 8
+ srl t2, t2, 8
+ append t2, t3, 16
+ and t2, t2, t8
+ srl s4, s4, 6
+ and t3, s3, t8
+ srl s1, s1, 6
+ append s1, s4, 16
+ and s1, s1, t9
+ or s1, s1, t2
+ ext t2, t3, 0, 16
+ srl t3, t3, 16
+ mul t2, t2, a3
+ mul t3, t3, a3
+ and s3, s3, t9
+ ext s4, s3, 0, 16
+ mul s4, s4, t6
+ srl s3, s3, 16
+ mul s3, s3, t6
+ srl t2, t2, 8
+ srl t3, t3, 8
+ append t3, t2, 16
+ and t3, t3, t8
+ srl s4, s4, 6
+ and t2, t0, t8
+ srl s3, s3, 6
+ append s3, s4, 16
+ and s3, s3, t9
+ or s3, s3, t3
+ ext t3, t2, 0, 16
+ srl t2, t2, 16
+ mul t3, t3, t5
+ mul t2, t2, t5
+ and t0, t0, t9
+ ext s4, t0, 0, 16
+ mul s4, s4, t7
+ srl t0, t0, 16
+ mul t0, t0, t7
+ srl t3, t3, 8
+ srl t2, t2, 8
+ append t2, t3, 16
+ and t2, t2, t8
+ srl s4, s4, 6
+ and t3, v0, t8
+ srl t0, t0, 6
+ append t0, s4, 16
+ and t0, t0, t9
+ or t0, t0, t2
+ ext t2, t3, 0, 16
+ srl t3, t3, 16
+ mul t2, t2, t5
+ mul t3, t3, t5
+ and v0, v0, t9
+ ext s4, v0, 0, 16
+ mul s4, s4, t7
+ srl v0, v0, 16
+ mul v0, v0, t7
+ srl t2, t2, 8
+ srl t3, t3, 8
+ append t3, t2, 16
+ and t3, t3, t8
+ srl s4, s4, 6
+ and t2, s0, t8
+ srl v0, v0, 6
+ append v0, s4, 16
+ and v0, v0, t9
+ or v0, v0, t3
+ ext t3, t2, 0, 16
+ srl t2, t2, 16
+ mul t3, t3, t5
+ mul t2, t2, t5
+ and s0, s0, t9
+ ext s4, s0, 0, 16
+ mul s4, s4, t7
+ srl s0, s0, 16
+ mul s0, s0, t7
+ srl t3, t3, 8
+ srl t2, t2, 8
+ append t2, t3, 16
+ and t2, t2, t8
+ srl s4, s4, 6
+ and t3, s2, t8
+ srl s0, s0, 6
+ append s0, s4, 16
+ and s0, s0, t9
+ or s0, s0, t2
+ ext t2, t3, 0, 16
+ srl t3, t3, 16
+ mul t2, t2, t5
+ mul t3, t3, t5
+ and s2, s2, t9
+ ext s4, s2, 0, 16
+ mul s4, s4, t7
+ srl s2, s2, 16
+ mul s2, s2, t7
+ srl t2, t2, 8
+ srl t3, t3, 8
+ append t3, t2, 16
+ and t3, t3, t8
+ srl s4, s4, 6
+ addu.ph t0, t0, t1
+ srl s2, s2, 6
+ append s2, s4, 16
+ and s2, s2, t9
+ or s2, s2, t3
+ addu.ph v0, v0, v1 /* v0 = [S2 + D2, S3 + D3] */
+ addu.ph s0, s0, s1 /* s0 = [S4 + D4, S5 + D5] */
+ addu.ph s2, s2, s3 /* s2 = [S6 + D6, S7 + D7] */
+
+ sw t0, 0 (a0) /* [SS0, SS1] */
+ sw v0, 4 (a0) /* [SS2, SS3] */
+ sw s0, 8 (a0) /* [SS4, SS5] */
+ sw s2, 12 (a0) /* [SS6, SS7] */
+
+ addiu t4, t4, -1 /* t4-- */
+ addiu a1, a1, 16 /* src += 8 */
+
+ bnez t4, 1b
+ addiu a0, a0, 16 /* dst += 8 */
+
+ RESTORE_REGS_FROM_STACK 12, s0, s1, s2, s3, s4, v0, v1
+ b 5f
+ nop
+
+
+ /* dst unaligned: do one item and fall down to the src unaligned case */
+2: lhu t1, 0 (a1)
+ lhu t0, 0 (a0)
+ addiu a2, a2, -1 /* len-- */
+ andi t2, t1, 0x07e0
+ andi t1, t1, 0xf81f
+ mul t2, t2, a3
+ mul t1, t1, t6
+ andi t3, t0, 0x07e0
+ andi t0, t0, 0xf81f
+ mul t3, t3, t5
+ mul t0, t0, t7
+ addiu a1, a1, 2 /* src++ */
+ srl t2, t2, 8
+ srl t1, t1, 6
+ andi t2, t2, 0x07e0
+ andi t1, t1, 0xf81f
+ or t1, t1, t2
+ srl t3, t3, 8
+ srl t0, t0, 6
+ andi t3, t3, 0x07e0
+ andi t0, t0, 0xf81f
+ or t0, t0, t3
+ addu t0, t0, t1 /* src * alpha + dst * ialpha */
+ sh t0, 0 (a0)
+ addiu a0, a0, 2 /* dst++ */
+
+ /* src unaligned */
+3: beqz a2, 0f
+ srl t4, a2, 3 /* t4 = len / 8 */
+ beqz t4, 5f
+ andi a2, a2, 0x7 /* len = len % 8 */
+ SAVE_REGS_ON_STACK 12, s0, s1, s2, s3, s4, v0, v1
+
+1: lw t0, 0 (a0) /* [d0, d1] */
+ lw v0, 4 (a0) /* [d2, d3] */
+ lw s0, 8 (a0) /* [d4, d5] */
+ lw s2, 12 (a0) /* [d6, d7] */
+
+ LDHI (t1, 0, a1) /* [s0, __] */
+ lw v1, 2 (a1) /* [s1, s2] */
+ lw s1, 6 (a1) /* [s3, s4] */
+ lw s3, 10 (a1) /* [s5, s6] */
+ LDLO (s4, 12, a1) /* [__, s7] */
+
+ pref 4, 14 (a1)
+ pref 5, 16 (a0)
+
+ PACK (t1, v1, t1) /* [s0, s1] */
+ PACK (v1, s1, v1) /* [s2, s3] */
+ PACK (s1, s3, s1) /* [s4, s5] */
+ PACK (s3, s4, s3) /* [s6, s7] */
+
+ and t2, t1, t8
+ ext t3, t2, 0, 16
+ srl t2, t2, 16
+ mul t3, t3, a3
+ mul t2, t2, a3
+ and t1, t1, t9
+ ext s4, t1, 0, 16
+ mul s4, s4, t6
+ srl t1, t1, 16
+ mul t1, t1, t6
+ srl t3, t3, 8
+ srl t2, t2, 8
+ append t2, t3, 16
+ and t2, t2, t8
+ srl s4, s4, 6
+ and t3, v1, t8
+ srl t1, t1, 6
+ append t1, s4, 16
+ and t1, t1, t9
+ or t1, t1, t2
+ ext t2, t3, 0, 16
+ srl t3, t3, 16
+ mul t2, t2, a3
+ mul t3, t3, a3
+ and v1, v1, t9
+ ext s4, v1, 0, 16
+ mul s4, s4, t6
+ srl v1, v1, 16
+ mul v1, v1, t6
+ srl t2, t2, 8
+ srl t3, t3, 8
+ append t3, t2, 16
+ and t3, t3, t8
+ srl s4, s4, 6
+ and t2, s1, t8
+ srl v1, v1, 6
+ append v1, s4, 16
+ and v1, v1, t9
+ or v1, v1, t3
+ ext t3, t2, 0, 16
+ srl t2, t2, 16
+ mul t3, t3, a3
+ mul t2, t2, a3
+ and s1, s1, t9
+ ext s4, s1, 0, 16
+ mul s4, s4, t6
+ srl s1, s1, 16
+ mul s1, s1, t6
+ srl t3, t3, 8
+ srl t2, t2, 8
+ append t2, t3, 16
+ and t2, t2, t8
+ srl s4, s4, 6
+ and t3, s3, t8
+ srl s1, s1, 6
+ append s1, s4, 16
+ and s1, s1, t9
+ or s1, s1, t2
+ ext t2, t3, 0, 16
+ srl t3, t3, 16
+ mul t2, t2, a3
+ mul t3, t3, a3
+ and s3, s3, t9
+ ext s4, s3, 0, 16
+ mul s4, s4, t6
+ srl s3, s3, 16
+ mul s3, s3, t6
+ srl t2, t2, 8
+ srl t3, t3, 8
+ append t3, t2, 16
+ and t3, t3, t8
+ srl s4, s4, 6
+ and t2, t0, t8
+ srl s3, s3, 6
+ append s3, s4, 16
+ and s3, s3, t9
+ or s3, s3, t3
+ ext t3, t2, 0, 16
+ srl t2, t2, 16
+ mul t3, t3, t5
+ mul t2, t2, t5
+ and t0, t0, t9
+ ext s4, t0, 0, 16
+ mul s4, s4, t7
+ srl t0, t0, 16
+ mul t0, t0, t7
+ srl t3, t3, 8
+ srl t2, t2, 8
+ append t2, t3, 16
+ and t2, t2, t8
+ srl s4, s4, 6
+ and t3, v0, t8
+ srl t0, t0, 6
+ append t0, s4, 16
+ and t0, t0, t9
+ or t0, t0, t2
+ ext t2, t3, 0, 16
+ srl t3, t3, 16
+ mul t2, t2, t5
+ mul t3, t3, t5
+ and v0, v0, t9
+ ext s4, v0, 0, 16
+ mul s4, s4, t7
+ srl v0, v0, 16
+ mul v0, v0, t7
+ srl t2, t2, 8
+ srl t3, t3, 8
+ append t3, t2, 16
+ and t3, t3, t8
+ srl s4, s4, 6
+ and t2, s0, t8
+ srl v0, v0, 6
+ append v0, s4, 16
+ and v0, v0, t9
+ or v0, v0, t3
+ ext t3, t2, 0, 16
+ srl t2, t2, 16
+ mul t3, t3, t5
+ mul t2, t2, t5
+ and s0, s0, t9
+ ext s4, s0, 0, 16
+ mul s4, s4, t7
+ srl s0, s0, 16
+ mul s0, s0, t7
+ srl t3, t3, 8
+ srl t2, t2, 8
+ append t2, t3, 16
+ and t2, t2, t8
+ srl s4, s4, 6
+ and t3, s2, t8
+ srl s0, s0, 6
+ append s0, s4, 16
+ and s0, s0, t9
+ or s0, s0, t2
+ ext t2, t3, 0, 16
+ srl t3, t3, 16
+ mul t2, t2, t5
+ mul t3, t3, t5
+ and s2, s2, t9
+ ext s4, s2, 0, 16
+ mul s4, s4, t7
+ srl s2, s2, 16
+ mul s2, s2, t7
+ srl t2, t2, 8
+ srl t3, t3, 8
+ append t3, t2, 16
+ and t3, t3, t8
+ srl s4, s4, 6
+ addu.ph t0, t0, t1
+ srl s2, s2, 6
+ append s2, s4, 16
+ and s2, s2, t9
+ or s2, s2, t3
+ addu.ph v0, v0, v1 /* v0 = [S2 + D2, S3 + D3] */
+ addu.ph s0, s0, s1 /* s0 = [S4 + D4, S5 + D5] */
+ addu.ph s2, s2, s3 /* s2 = [S6 + D6, S7 + D7] */
+
+ sw t0, 0 (a0) /* [SS0, SS1] */
+ sw v0, 4 (a0) /* [SS2, SS3] */
+ sw s0, 8 (a0) /* [SS4, SS5] */
+ sw s2, 12 (a0) /* [SS6, SS7] */
+
+ addiu t4, t4, -1 /* t4-- */
+ addiu a1, a1, 16 /* src += 8 */
+
+ bnez t4, 1b
+ addiu a0, a0, 16 /* dst += 8 */
+
+ RESTORE_REGS_FROM_STACK 12, s0, s1, s2, s3, s4, v0, v1
+
+5: /* Process remaining items (len < 8), one at a time */
+ beqz a2, 0f
+ nop
+
+1: lhu t1, 0 (a1)
+ lhu t0, 0 (a0)
+ addiu a1, a1, 2 /* src++ */
+ andi t2, t1, 0x07e0
+ andi t1, t1, 0xf81f
+ mul t2, t2, a3
+ mul t1, t1, t6
+ andi t3, t0, 0x07e0
+ andi t0, t0, 0xf81f
+ mul t3, t3, t5
+ mul t0, t0, t7
+ addiu a2, a2, -1 /* len-- */
+ srl t2, t2, 8
+ srl t1, t1, 6
+ andi t2, t2, 0x07e0
+ andi t1, t1, 0xf81f
+ or t1, t1, t2
+ srl t3, t3, 8
+ srl t0, t0, 6
+ andi t3, t3, 0x07e0
+ andi t0, t0, 0xf81f
+ or t0, t0, t3
+
+ addu t0, t0, t1 /* src*alpha + dst*ialpha */
+ sh t0, 0 (a0)
+ bnez a2, 1b
+ addiu a0, a0, 2 /* dst++ */
+
+0: jr ra
+ nop
+
+END(qt_blend_rgb16_on_rgb16_mips_dspr2_asm)
+
+#undef PACK
+#undef LDHI
+#undef LDLO
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 424ed554a2..41a2e39fc9 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -62,6 +62,7 @@
#include "qglyphrun.h"
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformintegration.h>
#include <private/qfontengine_p.h>
#include <private/qpaintengine_p.h>
@@ -155,7 +156,9 @@ static bool qt_painter_thread_test(int devType, const char *what)
// can be drawn onto these devices safely from any thread
break;
default:
- if (QThread::currentThread() != qApp->thread()) {
+ if (QThread::currentThread() != qApp->thread()
+ && (devType!=QInternal::Pixmap || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps))
+ && (devType!=QInternal::OpenGL || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL))) {
qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
return false;
}
diff --git a/src/gui/painting/qt_mips_asm_dsp_p.h b/src/gui/painting/qt_mips_asm_dsp_p.h
index 1b78eaf52c..54fcfab206 100644
--- a/src/gui/painting/qt_mips_asm_dsp_p.h
+++ b/src/gui/painting/qt_mips_asm_dsp_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 MIPS Technologies, www.mips.com, author Damir Tatalovic <dtatalovic@mips.com>
+** Copyright (C) 2013 Imagination Technologies Limited, www.imgtec.com
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -261,4 +261,168 @@ LEAF_MIPS32R2(symbol) \
or \out_1, \scratch1, \scratch3
.endm
+/*
+ * Checks if stack offset is big enough for storing/restoring regs_num
+ * number of register to/from stack. Stack offset must be greater than
+ * or equal to the number of bytes needed for storing registers (regs_num*4).
+ * Since MIPS ABI allows usage of first 16 bytes of stack frame (this is
+ * preserved for input arguments of the functions, already stored in a0-a3),
+ * stack size can be further optimized by utilizing this space.
+ */
+.macro CHECK_STACK_OFFSET regs_num, stack_offset
+.if \stack_offset < \regs_num * 4 - 16
+.error "Stack offset too small."
+.endif
+.endm
+
+/*
+ * Saves set of registers on stack. Maximum number of registers that
+ * can be saved on stack is limitted to 14 (a0-a3, v0-v1 and s0-s7).
+ * Stack offset is number of bytes that are added to stack pointer (sp)
+ * before registers are pushed in order to provide enough space on stack
+ * (offset must be multiple of 4, and must be big enough, as described by
+ * CHECK_STACK_OFFSET macro). This macro is intended to be used in
+ * combination with RESTORE_REGS_FROM_STACK macro. Example:
+ * SAVE_REGS_ON_STACK 4, v0, v1, s0, s1
+ * RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
+ */
+.macro SAVE_REGS_ON_STACK stack_offset = 0, r1, \
+ r2 = 0, r3 = 0, r4 = 0, \
+ r5 = 0, r6 = 0, r7 = 0, \
+ r8 = 0, r9 = 0, r10 = 0, \
+ r11 = 0, r12 = 0, r13 = 0, \
+ r14 = 0
+ .if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4)
+ .error "Stack offset must be positive and multiple of 4."
+ .endif
+ .if \stack_offset != 0
+ addiu sp, sp, -\stack_offset
+ .endif
+ sw \r1, 0(sp)
+ .if \r2 != 0
+ sw \r2, 4(sp)
+ .endif
+ .if \r3 != 0
+ sw \r3, 8(sp)
+ .endif
+ .if \r4 != 0
+ sw \r4, 12(sp)
+ .endif
+ .if \r5 != 0
+ CHECK_STACK_OFFSET 5, \stack_offset
+ sw \r5, 16(sp)
+ .endif
+ .if \r6 != 0
+ CHECK_STACK_OFFSET 6, \stack_offset
+ sw \r6, 20(sp)
+ .endif
+ .if \r7 != 0
+ CHECK_STACK_OFFSET 7, \stack_offset
+ sw \r7, 24(sp)
+ .endif
+ .if \r8 != 0
+ CHECK_STACK_OFFSET 8, \stack_offset
+ sw \r8, 28(sp)
+ .endif
+ .if \r9 != 0
+ CHECK_STACK_OFFSET 9, \stack_offset
+ sw \r9, 32(sp)
+ .endif
+ .if \r10 != 0
+ CHECK_STACK_OFFSET 10, \stack_offset
+ sw \r10, 36(sp)
+ .endif
+ .if \r11 != 0
+ CHECK_STACK_OFFSET 11, \stack_offset
+ sw \r11, 40(sp)
+ .endif
+ .if \r12 != 0
+ CHECK_STACK_OFFSET 12, \stack_offset
+ sw \r12, 44(sp)
+ .endif
+ .if \r13 != 0
+ CHECK_STACK_OFFSET 13, \stack_offset
+ sw \r13, 48(sp)
+ .endif
+ .if \r14 != 0
+ CHECK_STACK_OFFSET 14, \stack_offset
+ sw \r14, 52(sp)
+ .endif
+.endm
+
+/*
+ * Restores set of registers from stack. Maximum number of registers that
+ * can be restored from stack is limitted to 14 (a0-a3, v0-v1 and s0-s7).
+ * Stack offset is number of bytes that are added to stack pointer (sp)
+ * after registers are restored (offset must be multiple of 4, and must
+ * be big enough, as described by CHECK_STACK_OFFSET macro). This macro is
+ * intended to be used in combination with RESTORE_REGS_FROM_STACK macro.
+ * Example:
+ * SAVE_REGS_ON_STACK 4, v0, v1, s0, s1
+ * RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
+ */
+.macro RESTORE_REGS_FROM_STACK stack_offset = 0, r1, \
+ r2 = 0, r3 = 0, r4 = 0, \
+ r5 = 0, r6 = 0, r7 = 0, \
+ r8 = 0, r9 = 0, r10 = 0, \
+ r11 = 0, r12 = 0, r13 = 0, \
+ r14 = 0
+ .if (\stack_offset < 0) || (\stack_offset - (\stack_offset/4)*4)
+ .error "Stack offset must be pozitive and multiple of 4."
+ .endif
+ lw \r1, 0(sp)
+ .if \r2 != 0
+ lw \r2, 4(sp)
+ .endif
+ .if \r3 != 0
+ lw \r3, 8(sp)
+ .endif
+ .if \r4 != 0
+ lw \r4, 12(sp)
+ .endif
+ .if \r5 != 0
+ CHECK_STACK_OFFSET 5, \stack_offset
+ lw \r5, 16(sp)
+ .endif
+ .if \r6 != 0
+ CHECK_STACK_OFFSET 6, \stack_offset
+ lw \r6, 20(sp)
+ .endif
+ .if \r7 != 0
+ CHECK_STACK_OFFSET 7, \stack_offset
+ lw \r7, 24(sp)
+ .endif
+ .if \r8 != 0
+ CHECK_STACK_OFFSET 8, \stack_offset
+ lw \r8, 28(sp)
+ .endif
+ .if \r9 != 0
+ CHECK_STACK_OFFSET 9, \stack_offset
+ lw \r9, 32(sp)
+ .endif
+ .if \r10 != 0
+ CHECK_STACK_OFFSET 10, \stack_offset
+ lw \r10, 36(sp)
+ .endif
+ .if \r11 != 0
+ CHECK_STACK_OFFSET 11, \stack_offset
+ lw \r11, 40(sp)
+ .endif
+ .if \r12 != 0
+ CHECK_STACK_OFFSET 12, \stack_offset
+ lw \r12, 44(sp)
+ .endif
+ .if \r13 != 0
+ CHECK_STACK_OFFSET 13, \stack_offset
+ lw \r13, 48(sp)
+ .endif
+ .if \r14 != 0
+ CHECK_STACK_OFFSET 14, \stack_offset
+ lw \r14, 52(sp)
+ .endif
+ .if \stack_offset != 0
+ addiu sp, sp, \stack_offset
+ .endif
+.endm
+
#endif // QT_MIPS_ASM_DSP_H