view src/hermes/x86p_16.asm @ 4216:5b99971a27b4 SDL-1.2

Fixed bug #698 Hans de Goede 2009-02-13 01:10:52 PST Since the new "glitch free" version of pulseaudio (used in Fedora 10 amongst others), the sound of SDL using apps (like a simple playmus call) has been crackling. While looking in to fixing this I noticed that the current pulseaudio code in SDL uses pa_simple. However pa_simple uses a thread to pump pulseaudio events and ipc, given that SDL already has its own thread for audio handling this is clearly suboptimal, leading to unnecessary context switching IPC, etc. Also pa_simple does not allow one to implement the WaitAudio() callback for SDL audiodrivers properly. Given that my work is mostly a rewrite (although some original pieces remain) I'm attaching the new .c and .h file, as that is easier to review then the huge diff. Let me know if you also want the diff. This new version has the following features: -no longer use an additional thread next to the SDL sound thread -do not crackle with glitch free audio -when used with a newer pulse, which does glitch free audio, the total latency is the same as with the alsa driver -proper WaitAudio() implementation, saving another mixlen worth of latency -adds a WaitDone() implementation This patch has been written in consultancy with Lennart Poetering (the pulseaudio author) and has been reviewed by him for correct use of the pa API.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 21 Sep 2009 09:27:08 +0000
parents 540466e900db
children
line wrap: on
line source

;
; x86 format converters for HERMES
; Copyright (c) 1998 Glenn Fielder (gaffer@gaffer.org)
; This source code is licensed under the GNU LGPL
; 
; Please refer to the file COPYING.LIB contained in the distribution for
; licensing conditions		
; 
; Routines adjusted for Hermes by Christian Nentwich (brn@eleet.mcb.at)
; Used with permission.
; 

BITS 32

%include "common.inc"

SDL_FUNC _ConvertX86p16_16BGR565
SDL_FUNC _ConvertX86p16_16RGB555
SDL_FUNC _ConvertX86p16_16BGR555
SDL_FUNC _ConvertX86p16_8RGB332

EXTERN _ConvertX86

SECTION .text

_ConvertX86p16_16BGR565:

    ; check short
    cmp ecx,BYTE 16
    ja .L3


.L1 ; short loop
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    shr eax,11
    and eax,BYTE 11111b
    and ebx,11111100000b
    shl edx,11
    add eax,ebx
    add eax,edx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2
    dec ecx
    jnz .L1
.L2
    retn

.L3 ; head
    mov eax,edi
    and eax,BYTE 11b
    jz .L4
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    shr eax,11
    and eax,BYTE 11111b
    and ebx,11111100000b
    shl edx,11
    add eax,ebx
    add eax,edx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2
    dec ecx

.L4 ; save count
    push ecx

    ; unroll twice
    shr ecx,1
    
    ; point arrays to end
    lea esi,[esi+ecx*4]
    lea edi,[edi+ecx*4]

    ; negative counter 
    neg ecx
    jmp SHORT .L6
                              
.L5     mov [edi+ecx*4-4],eax
.L6     mov eax,[esi+ecx*4]

        mov ebx,[esi+ecx*4]
        and eax,07E007E0h         

        mov edx,[esi+ecx*4]
        and ebx,0F800F800h

        shr ebx,11
        and edx,001F001Fh

        shl edx,11
        add eax,ebx

        add eax,edx                 
        inc ecx

        jnz .L5                 
         
    mov [edi+ecx*4-4],eax

    ; tail
    pop ecx
    and ecx,BYTE 1
    jz .L7
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    shr eax,11
    and eax,BYTE 11111b
    and ebx,11111100000b
    shl edx,11
    add eax,ebx
    add eax,edx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2

.L7
    retn






_ConvertX86p16_16RGB555:

    ; check short
    cmp ecx,BYTE 32
    ja .L3


.L1 ; short loop
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    shr ebx,1
    and ebx,     0111111111100000b
    and eax,BYTE 0000000000011111b
    add eax,ebx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2
    dec ecx
    jnz .L1
.L2
    retn

.L3 ; head
    mov eax,edi
    and eax,BYTE 11b
    jz .L4
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    shr ebx,1
    and ebx,     0111111111100000b
    and eax,BYTE 0000000000011111b
    add eax,ebx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2
    dec ecx

.L4 ; save ebp
    push ebp

    ; save count
    push ecx

    ; unroll four times
    shr ecx,2
    
    ; point arrays to end
    lea esi,[esi+ecx*8]
    lea edi,[edi+ecx*8]

    ; negative counter 
    xor ebp,ebp
    sub ebp,ecx

.L5     mov eax,[esi+ebp*8]        ; agi?
        mov ecx,[esi+ebp*8+4]
       
        mov ebx,eax
        mov edx,ecx

        and eax,0FFC0FFC0h
        and ecx,0FFC0FFC0h

        shr eax,1
        and ebx,001F001Fh

        shr ecx,1
        and edx,001F001Fh

        add eax,ebx
        add ecx,edx

        mov [edi+ebp*8],eax
        mov [edi+ebp*8+4],ecx

        inc ebp
        jnz .L5                 

    ; tail
    pop ecx
.L6 and ecx,BYTE 11b
    jz .L7
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    shr ebx,1
    and ebx,     0111111111100000b
    and eax,BYTE 0000000000011111b
    add eax,ebx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2
    dec ecx
    jmp SHORT .L6

.L7 pop ebp
    retn






_ConvertX86p16_16BGR555:

    ; check short
    cmp ecx,BYTE 16
    ja .L3

	
.L1 ; short loop
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    shr eax,11
    and eax,BYTE 11111b
    shr ebx,1
    and ebx,1111100000b
    shl edx,10
    and edx,0111110000000000b
    add eax,ebx
    add eax,edx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2
    dec ecx
    jnz .L1
.L2
    retn

.L3 ; head
    mov eax,edi
    and eax,BYTE 11b
    jz .L4
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    shr eax,11
    and eax,BYTE 11111b
    shr ebx,1
    and ebx,1111100000b
    shl edx,10
    and edx,0111110000000000b
    add eax,ebx
    add eax,edx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2
    dec ecx

.L4 ; save count
    push ecx

    ; unroll twice
    shr ecx,1
    
    ; point arrays to end
    lea esi,[esi+ecx*4]
    lea edi,[edi+ecx*4]

    ; negative counter 
    neg ecx
    jmp SHORT .L6
                              
.L5     mov [edi+ecx*4-4],eax
.L6     mov eax,[esi+ecx*4]

        shr eax,1
        mov ebx,[esi+ecx*4]
        
        and eax,03E003E0h         
        mov edx,[esi+ecx*4]

        and ebx,0F800F800h

        shr ebx,11
        and edx,001F001Fh

        shl edx,10
        add eax,ebx

        add eax,edx                 
        inc ecx

        jnz .L5                 
         
    mov [edi+ecx*4-4],eax

    ; tail
    pop ecx
    and ecx,BYTE 1
    jz .L7
    mov al,[esi]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    shr eax,11
    and eax,BYTE 11111b
    shr ebx,1
    and ebx,1111100000b
    shl edx,10
    and edx,0111110000000000b
    add eax,ebx
    add eax,edx
    mov [edi],al
    mov [edi+1],ah
    add esi,BYTE 2
    add edi,BYTE 2

.L7
    retn






_ConvertX86p16_8RGB332:

    ; check short
    cmp ecx,BYTE 16
    ja .L3


.L1 ; short loop
    mov al,[esi+0]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    and eax,BYTE 11000b         ; blue
    shr eax,3
    and ebx,11100000000b        ; green
    shr ebx,6
    and edx,1110000000000000b   ; red
    shr edx,8
    add eax,ebx
    add eax,edx
    mov [edi],al
    add esi,BYTE 2
    inc edi
    dec ecx
    jnz .L1
.L2
    retn

.L3 mov eax,edi
    and eax,BYTE 11b
    jz .L4
    mov al,[esi+0]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    and eax,BYTE 11000b         ; blue
    shr eax,3
    and ebx,11100000000b        ; green
    shr ebx,6
    and edx,1110000000000000b   ; red
    shr edx,8
    add eax,ebx
    add eax,edx
    mov [edi],al
    add esi,BYTE 2
    inc edi
    dec ecx
    jmp SHORT .L3

.L4 ; save ebp
    push ebp

    ; save count
    push ecx

    ; unroll 4 times
    shr ecx,2

    ; prestep
    mov dl,[esi+0]
    mov bl,[esi+1]
    mov dh,[esi+2]
        
.L5     shl edx,16
        mov bh,[esi+3]
        
        shl ebx,16
        mov dl,[esi+4]

        mov dh,[esi+6]
        mov bl,[esi+5]

        and edx,00011000000110000001100000011000b
        mov bh,[esi+7]

        ror edx,16+3
        mov eax,ebx                                     ; setup eax for reds

        and ebx,00000111000001110000011100000111b
        and eax,11100000111000001110000011100000b       ; reds

        ror ebx,16-2
        add esi,BYTE 8

        ror eax,16
        add edi,BYTE 4

        add eax,ebx
        mov bl,[esi+1]                                  ; greens

        add eax,edx
        mov dl,[esi+0]                                  ; blues

        mov [edi-4],eax
        mov dh,[esi+2]

        dec ecx
        jnz .L5                 
    
    ; check tail
    pop ecx
    and ecx,BYTE 11b
    jz .L7

.L6 ; tail
    mov al,[esi+0]
    mov ah,[esi+1]
    mov ebx,eax
    mov edx,eax
    and eax,BYTE 11000b         ; blue
    shr eax,3
    and ebx,11100000000b        ; green
    shr ebx,6
    and edx,1110000000000000b   ; red
    shr edx,8
    add eax,ebx
    add eax,edx
    mov [edi],al
    add esi,BYTE 2
    inc edi
    dec ecx
    jnz .L6

.L7 pop ebp
    retn

%ifidn __OUTPUT_FORMAT__,elf
section .note.GNU-stack noalloc noexec nowrite progbits
%endif