For comparison also a SSE2 version which takes a percent value from 0 - 100.
Code: Select all
Macro M_Color_Mix(channel)
!movzx eax, byte [p.v_color1 + channel]
!movzx edx, byte [p.v_color2 + channel]
!sub eax, edx
!imul eax, ecx
!add eax, 0x800000
!shr eax, 24
!add eax, edx
!mov [p.v_color1 + channel], al
EndMacro
Procedure Color_Mix_asm(color1.l, color2.l, percent.l)
!mov ecx, [p.v_percent]
!imul ecx, 167772
M_Color_Mix(0)
M_Color_Mix(1)
M_Color_Mix(2)
!mov eax, [p.v_color1]
ProcedureReturn
EndProcedure
Procedure Color_Mix_SSE2(color1.l, color2.l, percent.l)
!mov eax, [p.v_percent]
!imul eax, 167772
!shr eax, 8
!movd xmm0, [p.v_color1]
!movd xmm1, [p.v_color2]
!movd xmm2, eax
!punpcklbw xmm0, xmm0
!punpcklbw xmm1, xmm1
!pshuflw xmm2, xmm2, 0
!pcmpeqw xmm3, xmm3
!pxor xmm3, xmm2
!pmulhuw xmm0, xmm2
!pmulhuw xmm1, xmm3
!paddw xmm0, xmm1
!psrlw xmm0, 8
!packuswb xmm0, xmm0
!movd eax, xmm0
ProcedureReturn
EndProcedure
Procedure Color_Mix_pb(color1.l, color2.l, percent.l)
r= (Red(color1)*percent + Red(color2)*(100-percent)) / 100
g= (Green(color1)*percent + Green(color2)*(100-percent)) / 100
b= (Blue(color1)*percent + Blue(color2)*(100-percent)) / 100
ProcedureReturn RGB(r,g,b)
EndProcedure
; Debug RSet(Hex(Color_Mix_pb(#Red, #Green, 80),#PB_Long), 6, "0")
; Debug RSet(Hex(Color_Mix_asm(#Red, #Green, 80),#PB_Long), 6, "0")
; Debug RSet(Hex(Color_Mix_SSE2(#Red, #Green, 80),#PB_Long), 6, "0")
;
; End
CompilerIf #PB_Compiler_Debugger
MessageRequester("Notice:", "Please turn off the debugger for this test")
End
CompilerEndIf
s=ElapsedMilliseconds()
For i=1 To 10000000
Color_Mix_pb(#Green,#Blue, 50)
Next
e=ElapsedMilliseconds()-s
MessageRequester("PB Code Version", Str(ElapsedMilliseconds()-s))
s=ElapsedMilliseconds()
For i=1 To 10000000
Color_Mix_asm(#Green,#Blue, 50)
Next
MessageRequester("asm Version", Str(ElapsedMilliseconds()-s))
s=ElapsedMilliseconds()
For i=1 To 10000000
Color_Mix_SSE2(#Green,#Blue, 50)
Next
MessageRequester("SSE2 Version", Str(ElapsedMilliseconds()-s))