/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qdrawhelper_arm_simd_p.h" #include #include #ifdef QT_HAVE_ARM_SIMD #if defined(Q_OS_SYMBIAN) #if !defined(__SWITCH_TO_ARM) #ifdef __MARM_THUMB__ #ifndef __ARMCC__ #define __SWITCH_TO_ARM asm("push {r0} ");\ asm("add r0, pc, #4 ");\ asm("bx r0 ");\ asm("nop ");\ asm(".align 2 ");\ asm(".code 32 ");\ asm("ldr r0, [sp], #4 ") #define __END_ARM asm(".code 16 ") #else #define __SWITCH_TO_ARM asm(".code 32 "); #define __END_ARM #endif // __ARMCC__ #else #define __SWITCH_TO_ARM #define __END_ARM #endif //__MARM_THUMB__ #endif #endif #if defined(Q_OS_SYMBIAN) && defined(Q_CC_RVCT) __asm void qt_blend_argb32_on_argb32_arm_simd(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, int const_alpha) { #ifndef __ARMCC__ __SWITCH_TO_ARM; #else CODE32 #endif // __ARMCC__ stmfd sp!, {r4-r12, r14} // read arguments off the stack add r8, sp, #10 * 4 ldmia r8, {r4-r6} // adjust dbpl and sbpl mov r14, #4 mul r14, r4, r14 sub r1, r1, r14 sub r3, r3, r14 // load 0xFF00FF00 to r12 mov r12, #0xFF000000 add r12, r12, #0xFF00 // load 0x800080 to r14 mov r14, #0x800000 add r14, r14, #0x80 /* Registers: r0 dst r1 dbpl r2 src r3 sbpl r4 w r5 h r6 const_alpha r12 0xFF0000 r14 0x800080 */ cmp r6, #256 //test if we have fully opaque constant alpha value bne argb32constalpha // branch if not argb32_next_row mov r7, r4 argb32_next_pixel ldr r8, [r2], #4 // load src pixel // Negate r8 and extract src alpha mvn r11, r8 // bitwise not uxtb r11, r11, ror #24 cmp r11, #0 // test for full src opacity (negated) beq argb32_no_blend cmp r11, #255 // test for full src transparency (negated) addeq r0, #4 beq argb32_nop ldr r9, [r0] // load dst pixel // blend uxtb16 r10, r9 uxtb16 r6, r9, ror #8 mla r10, r11, r10, r14 mla r9, r6, r11, r14 uxtab16 r10, r10, r10, ror #8 uxtab16 r9, r9, r9, ror #8 and r9, r9, r12 uxtab16 r10, r9, r10, ror #8 uqadd8 r8, r10, r8 argb32_no_blend str r8, [r0], #4 argb32_nop subs r7, r7, #1 bgt argb32_next_pixel add r0, r0, r1 // dest = dest + dbpl add r2, r2, r3 // src = src + sbpl subs r5, r5, #1 bgt argb32_next_row b argb32_blend_exit argb32constalpha cmp r6, #0 beq argb32_blend_exit ; const_alpha = (const_alpha * 255) >> 8; mov r11, #255 mul r6, r6, r11 mov r11, r6, lsr #8 argb32constalpha_next_row mov r7, r4 argb32constalpha_next_pixel ldr r9, [r2], #4 // load src pixel // blend uxtb16 r10, r9 uxtb16 r6, r9, ror #8 mla r10, r11, r10, r14 mla r9, r6, r11, r14 uxtab16 r10, r10, r10, ror #8 uxtab16 r9, r9, r9, ror #8 and r9, r9, r12 uxtab16 r8, r9, r10, ror #8 ldr r9, [r0] // load dst pixel // blend uxtb16 r10, r9 uxtb16 r6, r9, ror #8 // Negate r8 and extract src alpha mvn r9, r8 // bitwise not uxtb r9, r9, ror #24 mla r10, r9, r10, r14 mla r9, r6, r9, r14 uxtab16 r10, r10, r10, ror #8 uxtab16 r9, r9, r9, ror #8 and r9, r9, r12 uxtab16 r10, r9, r10, ror #8 uqadd8 r8, r10, r8 str r8, [r0], #4 subs r7, r7, #1 bgt argb32constalpha_next_pixel add r0, r0, r1 // dest = dest + dbpl add r2, r2, r3 // src = src + sbpl subs r5, r5, #1 bgt argb32constalpha_next_row argb32_blend_exit // Restore registers ldmfd sp!, {r4-r12, lr} bx lr __END_ARM } void qt_blend_rgb32_on_rgb32_arm_simd(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, int const_alpha) { if (const_alpha != 256) { qt_blend_argb32_on_argb32_arm_simd(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); return; } const uint *src = (const uint *) srcPixels; uint *dst = (uint *) destPixels; if (w <= 64) { for (int y=0; y= 0xff000000) dst[x] = s; else if (s != 0) dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); } dst = (quint32 *)(((uchar *) dst) + dbpl); src = (const quint32 *)(((const uchar *) src) + sbpl); } } else if (const_alpha != 0) { const_alpha = (const_alpha * 255) >> 8; for (int y=0; y