alphablend.asm
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:9k
源码类别:

Symbian

开发平台:

Visual C++

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