Mercurial > sdl-ios-xcode
diff src/video/fbcon/SDL_fbvideo.c @ 106:63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Fixed matrox blit bug where src Y less than dst Y
Fixed hardware surface init when no resolution change
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Fri, 13 Jul 2001 10:19:51 +0000 |
parents | e85e03f195b4 |
children | 5d4bafca35cd |
line wrap: on
line diff
--- a/src/video/fbcon/SDL_fbvideo.c Fri Jul 13 10:15:52 2001 +0000 +++ b/src/video/fbcon/SDL_fbvideo.c Fri Jul 13 10:19:51 2001 +0000 @@ -133,13 +133,14 @@ static void FB_VideoQuit(_THIS); /* Hardware surface functions */ -static int FB_InitHWSurfaces(_THIS, char *base, int size); +static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size); static void FB_FreeHWSurfaces(_THIS); static int FB_AllocHWSurface(_THIS, SDL_Surface *surface); static int FB_LockHWSurface(_THIS, SDL_Surface *surface); static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface); static void FB_FreeHWSurface(_THIS, SDL_Surface *surface); static void FB_WaitVBL(_THIS); +static void FB_WaitIdle(_THIS); static int FB_FlipHWSurface(_THIS, SDL_Surface *surface); /* Internal palette functions */ @@ -191,6 +192,7 @@ } memset(this->hidden, 0, (sizeof *this->hidden)); wait_vbl = FB_WaitVBL; + wait_idle = FB_WaitIdle; mouse_fd = -1; keyboard_fd = -1; @@ -665,7 +667,7 @@ if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { return(NULL); } - current->format->palette->ncolors = 16; + current->format->palette->ncolors = 16; /* Get the fixed information about the console hardware. This is necessary since finfo.line_length changes. @@ -759,6 +761,18 @@ return(NULL); } } + } else { + int maxheight; + + /* Figure out how much video memory is available */ + if ( flags & SDL_DOUBLEBUF ) { + maxheight = height*2; + } else { + maxheight = height; + } + if ( vinfo.yres_virtual > maxheight ) { + vinfo.yres_virtual = maxheight; + } } cache_vinfo = vinfo; #ifdef FBCON_DEBUG @@ -803,6 +817,13 @@ current->pitch = finfo.line_length; current->pixels = mapped_mem+mapped_offset; + /* Set up the information for hardware surfaces */ + surfaces_mem = (char *)current->pixels + + vinfo.yres_virtual*current->pitch; + surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem)); + FB_FreeHWSurfaces(this); + FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len); + /* Let the application know we have a hardware palette */ switch (finfo.visual) { case FB_VISUAL_PSEUDOCOLOR: @@ -820,17 +841,12 @@ flip_address[0] = (char *)current->pixels; flip_address[1] = (char *)current->pixels+ current->h*current->pitch; + this->screen = current; FB_FlipHWSurface(this, current); + this->screen = NULL; } } - /* Set up the information for hardware surfaces */ - surfaces_mem = (char *)current->pixels + - vinfo.yres_virtual*current->pitch; - surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem)); - FB_FreeHWSurfaces(this); - FB_InitHWSurfaces(this, surfaces_mem, surfaces_len); - /* Set the update rectangle function */ this->UpdateRects = FB_DirectUpdate; @@ -867,15 +883,36 @@ } #endif -static int FB_InitHWSurfaces(_THIS, char *base, int size) +static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size) { - surfaces.prev = NULL; - surfaces.used = 0; - surfaces.base = base; - surfaces.size = size; - surfaces.next = NULL; + vidmem_bucket *bucket; + surfaces_memtotal = size; surfaces_memleft = size; + + if ( surfaces_memleft > 0 ) { + bucket = (vidmem_bucket *)malloc(sizeof(*bucket)); + if ( bucket == NULL ) { + SDL_OutOfMemory(); + return(-1); + } + bucket->prev = &surfaces; + bucket->used = 0; + bucket->dirty = 0; + bucket->base = base; + bucket->size = size; + bucket->next = NULL; + } else { + bucket = NULL; + } + + surfaces.prev = NULL; + surfaces.used = 1; + surfaces.dirty = 0; + surfaces.base = screen->pixels; + surfaces.size = (unsigned int)((long)base - (long)surfaces.base); + surfaces.next = bucket; + screen->hwdata = (struct private_hwdata *)&surfaces; return(0); } static void FB_FreeHWSurfaces(_THIS) @@ -956,12 +993,14 @@ /* Set the current bucket values and return it! */ bucket->used = 1; bucket->size = size; + bucket->dirty = 0; #ifdef FBCON_DEBUG fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base); #endif surfaces_memleft -= size; surface->flags |= SDL_HWSURFACE; surface->pixels = bucket->base; + surface->hwdata = (struct private_hwdata *)bucket; return(0); } static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) @@ -970,58 +1009,64 @@ /* Look for the bucket in the current list */ for ( bucket=&surfaces; bucket; bucket=bucket->next ) { - if ( bucket->base == (char *)surface->pixels ) { + if ( bucket == (vidmem_bucket *)surface->hwdata ) { break; } } - if ( (bucket == NULL) || ! bucket->used ) { - return; - } - - /* Add the memory back to the total */ -#ifdef FBCON_DEBUG + if ( bucket && bucket->used ) { + /* Add the memory back to the total */ +#ifdef DGA_DEBUG printf("Freeing bucket of %d bytes\n", bucket->size); #endif - surfaces_memleft += bucket->size; + surfaces_memleft += bucket->size; - /* Can we merge the space with surrounding buckets? */ - bucket->used = 0; - if ( bucket->next && ! bucket->next->used ) { -#ifdef FBCON_DEBUG + /* Can we merge the space with surrounding buckets? */ + bucket->used = 0; + if ( bucket->next && ! bucket->next->used ) { +#ifdef DGA_DEBUG printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size); #endif - freeable = bucket->next; - bucket->size += bucket->next->size; - bucket->next = bucket->next->next; - if ( bucket->next ) { - bucket->next->prev = bucket; + freeable = bucket->next; + bucket->size += bucket->next->size; + bucket->next = bucket->next->next; + if ( bucket->next ) { + bucket->next->prev = bucket; + } + free(freeable); } - free(freeable); - } - if ( bucket->prev && ! bucket->prev->used ) { -#ifdef FBCON_DEBUG + if ( bucket->prev && ! bucket->prev->used ) { +#ifdef DGA_DEBUG printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size); #endif - freeable = bucket; - bucket->prev->size += bucket->size; - bucket->prev->next = bucket->next; - if ( bucket->next ) { - bucket->next->prev = bucket->prev; + freeable = bucket; + bucket->prev->size += bucket->size; + bucket->prev->next = bucket->next; + if ( bucket->next ) { + bucket->next->prev = bucket->prev; + } + free(freeable); } - free(freeable); } surface->pixels = NULL; + surface->hwdata = NULL; } static int FB_LockHWSurface(_THIS, SDL_Surface *surface) { - if ( surface == SDL_VideoSurface ) { + if ( surface == this->screen ) { SDL_mutexP(hw_lock); + if ( FB_IsSurfaceBusy(surface) ) { + FB_WaitBusySurfaces(this); + } + } else { + if ( FB_IsSurfaceBusy(surface) ) { + FB_WaitBusySurfaces(this); + } } return(0); } static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface) { - if ( surface == SDL_VideoSurface ) { + if ( surface == this->screen ) { SDL_mutexV(hw_lock); } } @@ -1034,10 +1079,18 @@ return; } +static void FB_WaitIdle(_THIS) +{ + return; +} + static int FB_FlipHWSurface(_THIS, SDL_Surface *surface) { /* Wait for vertical retrace and then flip display */ cache_vinfo.yoffset = flip_page*surface->h; + if ( FB_IsSurfaceBusy(this->screen) ) { + FB_WaitBusySurfaces(this); + } wait_vbl(this); if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) { SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed");