alphablend.asm
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:8k
源码类别:

Symbian

开发平台:

C/C++

  1. ;
  2. ; ***** BEGIN LICENSE BLOCK ***** 
  3. ; Version: RCSL 1.0/RPSL 1.0 
  4. ;  
  5. ; Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  6. ;      
  7. ; The contents of this file, and the files included with this file, are 
  8. ; subject to the current version of the RealNetworks Public Source License 
  9. ; Version 1.0 (the "RPSL") available at 
  10. ; http://www.helixcommunity.org/content/rpsl unless you have licensed 
  11. ; the file under the RealNetworks Community Source License Version 1.0 
  12. ; (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  13. ; in which case the RCSL will apply. You may also obtain the license terms 
  14. ; directly from RealNetworks.  You may not use this file except in 
  15. ; compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  16. ; applicable to this file, the RCSL.  Please see the applicable RPSL or 
  17. ; RCSL for the rights, obligations and limitations governing use of the 
  18. ; contents of the file.  
  19. ;  
  20. ; This file is part of the Helix DNA Technology. RealNetworks is the 
  21. ; developer of the Original Code and owns the copyrights in the portions 
  22. ; it created. 
  23. ;  
  24. ; This file, and the files included with this file, is distributed and made 
  25. ; available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  26. ; EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  27. ; INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  28. ; FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  29. ; Technology Compatibility Kit Test Suite(s) Location: 
  30. ;    http://www.helixcommunity.org/content/tck 
  31. ; Contributor(s): 
  32. ;  
  33. ; ***** END LICENSE BLOCK *****
  34. ;
  35. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  36. ;;
  37. ;;      alphablend.asm
  38. ;;
  39. ;;
  40. ;;      Alpha blend two ARGB images. Put result back into top image.
  41. ;;
  42. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  43. %ifdef   COFF
  44.         %define AlphaBlendMMX _AlphaBlendMMX
  45. %elifdef WIN32
  46.         %define AlphaBlendMMX _AlphaBlendMMX
  47. %elifdef ELF
  48.         %define AlphaBlendMMX AlphaBlendMMX
  49. %elifdef AOUTB
  50.         %define AlphaBlendMMX AlphaBlendMMX
  51. %else
  52.         %error linking format currently not supported by alphbablend.asm
  53. %endif
  54.          global AlphaBlendMMX
  55. ;  %include "standard.inc"
  56. section .data
  57. section .text
  58. ;;;
  59. ;;; void AlphaBlendMMX(unsigned char* p_top, unsigned char* p_bot, int size)
  60. ;;; copy bottom into top.
  61. ;;;
  62. ;;; we *MUST* preserve the top pixel alpha channel. This is used for
  63. ;;; transparent hit testing.
  64. AlphaBlendMMX:
  65.     
  66.         ;; Figure stack out.....
  67. struc parms
  68.                 resd 4  ; Register and return address
  69.         .p_top: resd 1  ; UCHAR* p_bot
  70.         .p_bot: resd 1  ; UCHAR* p_bot
  71.         .size:  resd 1  ; int  size
  72. endstruc
  73.         
  74.     ;; Save some stuff...
  75.     push ebx
  76.     push edi
  77.     push esi
  78.     ;; Get size.
  79.     mov esi, [esp+parms.p_top]
  80.     mov edi, [esp+parms.p_bot]
  81.     mov eax, [esp+parms.size]
  82.     mov ecx, 8 ; preload the additive constant
  83.     pxor    mm7, mm7
  84.     pcmpeqw mm6, mm6    ; For inverting the alpha channel
  85.     
  86.     movq    mm2, [esi]  ; mm2 = a2r2 g2b2 a1r1 g1b1 Top (P)
  87.     psrlw   mm6, 8      ; mm6 = 00ff 00ff 00ff 00ff
  88.     movq    mm3, [edi]  ; mm3 = a2r2 g2b2 a1r1 g1b1 Bot (Q)
  89.     shr     eax, 1      ; We only loop 1/2 the count.
  90.     jz      NEAR L2     ; skip if we only have 1 or no pixels.
  91. L1: movq    mm0,mm2     ; mm0 = a2r2 g2b2 a1r1 g1b1 Top (P)
  92.     movq    mm1,mm3     ; mm1 = a2r2 g2b2 a1r1 g1b1 Bot (Q)
  93.     punpcklbw mm0,mm7   ; mm0 = 00pa 00pr 00pg 00pb 1st pixel
  94.     punpcklbw mm1,mm7   ; mm1 = 00qa 00qr 00qg 00qb 1st pixel
  95.     ;; Prefetch next data needed....
  96. ;           prefetchnta [esi+16] ; This is only on >PIII
  97.     movq      mm4,mm0   ; mm4 = 00pa 00xx 00xx 00xx 1st pixel
  98.     punpckhbw mm2,mm7   ; mm2 = 00pa 00pr 00pg 00pb 2nd pixel
  99.     psubw     mm0,mm1   ; mm0 = P-Q (never mind alpha values) 1st pixel
  100.     punpckhbw mm3,mm7   ; mm3 = 00qa 00qr 00qg 00qb 2nd pixel
  101.     ; spread pa1,pa2 alpha to all channels;
  102.     movq      mm5,mm2   ; mm5 = 00pa 00pr 00pg 00pb 2nd pixel
  103.     punpckhwd mm4,mm4   ; mm4 = 00pa 00pa xxxx xxxx 1st pixel
  104.     psubw     mm2,mm3   ; mm2 = P-Q (never mind alpha values) 2nd pixel
  105.     punpckhwd mm5,mm5   ; mm5 = 00pa 00pa xxxx xxxx 2nd pixel
  106.     add       esi,ecx   ; esi += 8
  107.     punpckhdq mm4,mm4   ; mm4 = 00pa 00pa 00pa 00pa 1st pixel
  108.     add       edi,ecx   ; edi += 8
  109.     punpckhdq mm5,mm5   ; mm5 = 00pa 00pa 00pa 00pa 2nd pixel
  110.     ;; Invert Alpha channel because we output backwards from the
  111.     ;; renderers
  112.     pandn   mm4, mm6
  113.     pandn   mm5, mm6
  114.     ;; Prefetch next data needed....
  115. ;           prefetchnta [edi+8];this is only on >PIII
  116.     pmullw  mm0, mm4        ; mm0 = (P-Q)*alpha 1st pixel
  117.     pmullw  mm2, mm5        ; mm2 = (P-Q)*alpha 2nd pixel
  118.     dec eax             ; decrement loop counter.
  119.     
  120.     psllw   mm1, 8          ; mm1 = 256Q
  121.     psllw   mm3, 8          ; mm3 = 256Q
  122.     paddw   mm1, mm0        ; mm1 = 256Q + (P-Q)*alpha 1st pixel
  123.     paddw   mm3, mm2        ; mm3 = 256Q + (P-Q)*alpha 2nd pixel
  124.     psrlw   mm1, 8      ; mm1 = (256Q + (P-Q)*alpha)/256 1st pixel
  125.     psrlw   mm3, 8      ; mm3 = (256Q + (P-Q)*alpha)/256 2nd pixel
  126.     jz  L5
  127.     
  128.     movq     mm2,[esi]
  129.     packuswb mm1,mm3    ; mm1 = 00r2 g2b2 00r1 g1b1   NEW Top (P)
  130.     pandn    mm4, mm6   ; invert the alpha channel again to get original
  131.     pandn    mm5, mm6   ; invert the alpha channel again to get original
  132.     packuswb mm4, mm5       ; mm4 = qaqa qaqa papa papa
  133.     pslld    mm4, 24        ; mm4 = qa00 0000 pa00 0000
  134.     por      mm1, mm4       ; mm1 = a2r2 g2b2 a1r1 g1b1
  135.     movq     mm3,[edi]
  136.     movq     [esi-8],mm1
  137.     jmp L1
  138. L5:
  139.     packuswb mm1,mm3        ; mm1 = 00r2 g2b2 00r1 g1b1   NEW Top (P)
  140.     pandn    mm4, mm6   ; invert the alpha channel again to get original
  141.     pandn    mm5, mm6   ; invert the alpha channel again to get original
  142.     packuswb mm4, mm5       ; mm4 = qaqa qaqa papa papa
  143.     pslld    mm4, 24        ; mm4 = qa00 0000 pa00 0000
  144.     por      mm1, mm4       ; mm1 = a2r2 g2b2 a1r1 g1b1
  145.     movq     [esi-8],mm1
  146.     
  147. ;;; If there were an odd number of pixels, do the odd
  148. ;;; one here
  149. L2:
  150.     mov eax,[esp+parms.size]; Get the original count again.
  151.     shr eax,1
  152.     jnc L3                  ; skip if there was no odd pixel.
  153.     ;; mm2 and mm3 have the single pixel in their LSB double
  154.     ;; words now.
  155.     movd      mm2, [esi]    ; mm2 = xxxx xxxx a1r1 g1b1 Top
  156.     movd      mm3, [edi]    ; mm3 = xxxx xxxx a1r1 g1b1 Bottom
  157.     punpcklbw mm2,mm7       ; mm2 = 00pa 00pr 00pg 00pb 
  158.     punpcklbw mm3,mm7       ; mm3 = 00qa 00qr 00qg 00qb 
  159.     movq      mm4,mm2       ; mm4 = 00pa 00xx 00xx 00xx 
  160.     psubw     mm2,mm3       ; mm2 = P-Q (never mind alpha values)
  161.     ; spread pa1,pa2 alpha to all channels;
  162.     punpckhwd mm4,mm4   ; mm4 = 00pa 00pa xxxx xxxx 
  163.     punpckhdq mm4,mm4   ; mm4 = 00pa 00pa 00pa 00pa 
  164.     ;; Invert Alpha channel because we output backwards from the
  165.     ;; renderers
  166.     pandn    mm4, mm6
  167.     pmullw   mm2, mm4        ; mm2 = (P-Q)*alpha
  168.     psllw    mm3, 8          ; mm3 = 256Q
  169.     paddw    mm3, mm2        ; mm3 = 256Q + (P-Q)*alpha
  170.     psrlw    mm3, 8          ; mm3 = (256Q + (P-Q)*alpha)/256
  171.     packuswb mm3,mm7
  172.     
  173.     pandn    mm4, mm6       ; invert the alpha channel again to get original
  174.     pslld    mm4, 24        ; mm4 = pa00 0000 pa00 0000
  175.     por      mm3, mm4       ; mm3 = a2r2 g2b2 a1r1 g1b1
  176.     movd    [esi], mm3      ; store it.
  177.             
  178. ;;; Restore and return.
  179. L3: 
  180.         ;; No emms instruction. Done in outer loop
  181.         ;; Pop off the stack....
  182.         pop esi
  183.         pop edi
  184.         pop ebx
  185.         
  186.         ret                 ; Get out...
  187. ;;; leave a trace
  188. version: db '@(#) $ RealNetworks Revision: .9 $',0