You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
4.7 KiB
203 lines
4.7 KiB
/* libs/pixelflinger/t32cb16blend.S |
|
** |
|
** Copyright 2006, The Android Open Source Project |
|
** |
|
** Licensed under the Apache License, Version 2.0 (the "License"); |
|
** you may not use this file except in compliance with the License. |
|
** You may obtain a copy of the License at |
|
** |
|
** http://www.apache.org/licenses/LICENSE-2.0 |
|
** |
|
** Unless required by applicable law or agreed to in writing, software |
|
** distributed under the License is distributed on an "AS IS" BASIS, |
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
** See the License for the specific language governing permissions and |
|
** limitations under the License. |
|
*/ |
|
|
|
|
|
.text |
|
.syntax unified |
|
.balign 4 |
|
|
|
.global scanline_t32cb16blend_arm |
|
|
|
|
|
/* |
|
* .macro pixel |
|
* |
|
* \DREG is a 32-bit register containing *two* original destination RGB565 |
|
* pixels, with the even one in the low-16 bits, and the odd one in the |
|
* high 16 bits. |
|
* |
|
* \SRC is a 32-bit 0xAABBGGRR pixel value, with pre-multiplied colors. |
|
* |
|
* \FB is a target register that will contain the blended pixel values. |
|
* |
|
* \ODD is either 0 or 1 and indicates if we're blending the lower or |
|
* upper 16-bit pixels in DREG into FB |
|
* |
|
* |
|
* clobbered: r6, r7, lr |
|
* |
|
*/ |
|
|
|
.macro pixel, DREG, SRC, FB, ODD |
|
|
|
// SRC = 0xAABBGGRR |
|
mov r7, \SRC, lsr #24 // sA |
|
add r7, r7, r7, lsr #7 // sA + (sA >> 7) |
|
rsb r7, r7, #0x100 // sA = 0x100 - (sA+(sA>>7)) |
|
|
|
1: |
|
|
|
.if \ODD |
|
|
|
// red |
|
mov lr, \DREG, lsr #(16 + 11) |
|
smulbb lr, r7, lr |
|
mov r6, \SRC, lsr #3 |
|
and r6, r6, #0x1F |
|
add lr, r6, lr, lsr #8 |
|
cmp lr, #0x1F |
|
orrhs \FB, \FB, #(0x1F<<(16 + 11)) |
|
orrlo \FB, \FB, lr, lsl #(16 + 11) |
|
|
|
// green |
|
and r6, \DREG, #(0x3F<<(16 + 5)) |
|
smulbt r6, r7, r6 |
|
mov lr, \SRC, lsr #(8+2) |
|
and lr, lr, #0x3F |
|
add r6, lr, r6, lsr #(5+8) |
|
cmp r6, #0x3F |
|
orrhs \FB, \FB, #(0x3F<<(16 + 5)) |
|
orrlo \FB, \FB, r6, lsl #(16 + 5) |
|
|
|
// blue |
|
and lr, \DREG, #(0x1F << 16) |
|
smulbt lr, r7, lr |
|
mov r6, \SRC, lsr #(8+8+3) |
|
and r6, r6, #0x1F |
|
add lr, r6, lr, lsr #8 |
|
cmp lr, #0x1F |
|
orrhs \FB, \FB, #(0x1F << 16) |
|
orrlo \FB, \FB, lr, lsl #16 |
|
|
|
.else |
|
|
|
// red |
|
mov lr, \DREG, lsr #11 |
|
and lr, lr, #0x1F |
|
smulbb lr, r7, lr |
|
mov r6, \SRC, lsr #3 |
|
and r6, r6, #0x1F |
|
add lr, r6, lr, lsr #8 |
|
cmp lr, #0x1F |
|
movhs \FB, #(0x1F<<11) |
|
movlo \FB, lr, lsl #11 |
|
|
|
|
|
// green |
|
and r6, \DREG, #(0x3F<<5) |
|
smulbb r6, r7, r6 |
|
mov lr, \SRC, lsr #(8+2) |
|
and lr, lr, #0x3F |
|
add r6, lr, r6, lsr #(5+8) |
|
cmp r6, #0x3F |
|
orrhs \FB, \FB, #(0x3F<<5) |
|
orrlo \FB, \FB, r6, lsl #5 |
|
|
|
// blue |
|
and lr, \DREG, #0x1F |
|
smulbb lr, r7, lr |
|
mov r6, \SRC, lsr #(8+8+3) |
|
and r6, r6, #0x1F |
|
add lr, r6, lr, lsr #8 |
|
cmp lr, #0x1F |
|
orrhs \FB, \FB, #0x1F |
|
orrlo \FB, \FB, lr |
|
|
|
.endif |
|
|
|
.endm |
|
|
|
|
|
// r0: dst ptr |
|
// r1: src ptr |
|
// r2: count |
|
// r3: d |
|
// r4: s0 |
|
// r5: s1 |
|
// r6: pixel |
|
// r7: pixel |
|
// r8: free |
|
// r9: free |
|
// r10: free |
|
// r11: free |
|
// r12: scratch |
|
// r14: pixel |
|
|
|
scanline_t32cb16blend_arm: |
|
stmfd sp!, {r4-r7, lr} |
|
|
|
pld [r0] |
|
pld [r1] |
|
|
|
// align DST to 32 bits |
|
tst r0, #0x3 |
|
beq aligned |
|
subs r2, r2, #1 |
|
ldmfdlo sp!, {r4-r7, lr} // return |
|
bxlo lr |
|
|
|
last: |
|
ldr r4, [r1], #4 |
|
ldrh r3, [r0] |
|
pixel r3, r4, r12, 0 |
|
strh r12, [r0], #2 |
|
|
|
aligned: |
|
subs r2, r2, #2 |
|
blo 9f |
|
|
|
// The main loop is unrolled twice and processes 4 pixels |
|
8: ldmia r1!, {r4, r5} |
|
// stream the source |
|
pld [r1, #32] |
|
add r0, r0, #4 |
|
// it's all zero, skip this pixel |
|
orrs r3, r4, r5 |
|
beq 7f |
|
|
|
// load the destination |
|
ldr r3, [r0, #-4] |
|
// stream the destination |
|
pld [r0, #32] |
|
pixel r3, r4, r12, 0 |
|
pixel r3, r5, r12, 1 |
|
// effectively, we're getting write-combining by virtue of the |
|
// cpu's write-back cache. |
|
str r12, [r0, #-4] |
|
|
|
// 2nd iterration of the loop, don't stream anything |
|
subs r2, r2, #2 |
|
movlt r4, r5 |
|
blt 9f |
|
ldmia r1!, {r4, r5} |
|
add r0, r0, #4 |
|
orrs r3, r4, r5 |
|
beq 7f |
|
ldr r3, [r0, #-4] |
|
pixel r3, r4, r12, 0 |
|
pixel r3, r5, r12, 16 |
|
str r12, [r0, #-4] |
|
|
|
|
|
7: subs r2, r2, #2 |
|
bhs 8b |
|
mov r4, r5 |
|
|
|
9: adds r2, r2, #1 |
|
ldmfdlo sp!, {r4-r7, lr} // return |
|
bxlo lr |
|
b last
|
|
|