SDL doesn't works on sparc64

Hello Jacob Meuser,
I have tried to use SDL library on my SunBlade 2500, but I only get a core
dump.

Follow the info on my machine:

sysctl -n kern.version

OpenBSD 5.2 (GENERIC.MP) #236: Mon Jul 30 16:38:18 MDT 2012
deraadt at sparc64.openbsd.org:/usr/src/sys/arch/sparc64/compile/GENERIC.MP

dmesg | grep fb

ifb0 at pci3 dev 2 function 0 “3D Labs Wildcat 5110” rev 0x01
ifb0: XVR-600 (SUNW,375-3153), 1280x1024
wsdisplay0 at ifb0 mux 1: console (std, sun emulation)

xdpyinfo

name of display: :0
version number: 11.0
vendor string: The X.Org Foundation
vendor release number: 11202000
X.Org version: 1.12.2
maximum request size: 16777212 bytes
motion buffer size: 256
bitmap unit, bit order, padding: 8, MSBFirst, 32
image byte order: MSBFirst
number of supported pixmap formats: 8
supported pixmap formats:
depth 1, bits_per_pixel 1, scanline_pad 32
depth 4, bits_per_pixel 8, scanline_pad 32
depth 8, bits_per_pixel 8, scanline_pad 32
depth 15, bits_per_pixel 16, scanline_pad 32
depth 16, bits_per_pixel 16, scanline_pad 32
depth 24, bits_per_pixel 32, scanline_pad 32
depth 32, bits_per_pixel 32, scanline_pad 32
depth 7, bits_per_pixel 8, scanline_pad 32
keycode range: minimum 8, maximum 255
focus: window 0x80000d, revert to Parent
number of extensions: 26
BIG-REQUESTS
DAMAGE
DOUBLE-BUFFER
DPMS
DRI2
GLX
Generic Event Extension
MIT-SCREEN-SAVER
MIT-SHM
RANDR
RECORD
RENDER
SECURITY
SGI-GLX
SHAPE
SYNC
X-Resource
XC-MISC
XFIXES
XFree86-DGA
XFree86-VidModeExtension
XINERAMA
XInputExtension
XKEYBOARD
XTEST
XVideo
default screen number: 0
number of screens: 1

screen #0:
dimensions: 1280x1024 pixels (339x271 millimeters)
resolution: 96x96 dots per inch
depths (8): 7, 1, 4, 8, 15, 16, 24, 32
root window id: 0xce
depth of root window: 7 planes
number of colormaps: minimum 1, maximum 1
default colormap: 0x20
default number of colormap cells: 128
preallocated pixels: black 0, white 1
options: backing-store NO, save-unders NO
largest cursor: 1280x1024
current input event mask: 0x58003d
KeyPressMask ButtonPressMask ButtonReleaseMask
EnterWindowMask LeaveWindowMask SubstructureNotifyMask
SubstructureRedirectMask PropertyChangeMask
number of visuals: 6
default visual id: 0x21
visual:
visual id: 0x21
class: PseudoColor
depth: 7 planes
available colormap entries: 128
red, green, blue masks: 0x0, 0x0, 0x0
significant bits in color specification: 6 bits
visual:
visual id: 0x22
class: GrayScale
depth: 7 planes
available colormap entries: 128
red, green, blue masks: 0x0, 0x0, 0x0
significant bits in color specification: 6 bits
visual:
visual id: 0x23
class: StaticColor
depth: 7 planes
available colormap entries: 128
red, green, blue masks: 0x7, 0x18, 0x60
significant bits in color specification: 6 bits
visual:
visual id: 0x24
class: TrueColor
depth: 7 planes
available colormap entries: 8 per subfield
red, green, blue masks: 0x7, 0x18, 0x60
significant bits in color specification: 6 bits
visual:
visual id: 0x25
class: DirectColor
depth: 7 planes
available colormap entries: 8 per subfield
red, green, blue masks: 0x7, 0x18, 0x60
significant bits in color specification: 6 bits
visual:
visual id: 0x26
class: StaticGray
depth: 7 planes
available colormap entries: 128
red, green, blue masks: 0x0, 0x0, 0x0
significant bits in color specification: 6 bits

pkg_info sdl

Information for inst:sdl-1.2.15p2

Comment:
cross-platform multimedia library

Description:
Simple DirectMedia Layer is a cross-platform multimedia
library designed to provide fast access to the graphics
framebuffer and audio device. It is used by MPEG playback
software, emulators, and many popular games.

Packages can be built with additional FLAVORs:

aa: SDL built with ASCII art support.
This FLAVOR requires the aalib package.

no_x11: Built without X11.

Maintainer: Jacob Meuser

WWW: http://www.libsdl.org/

and the program to reproduce the bug:

cat test-sdl.c

/* : gcc -Wall -O0 -g test-sdl.c sdl-config --cflags --libs */

#include <SDL.h>

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);
SDL_SetVideoMode(512, 512, 0, SDL_RESIZABLE);

SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);

for (;;) {
	SDL_Event e;
	while (SDL_WaitEvent(&e)) {
		if (e.type == SDL_QUIT) break;
	}

	break;
}

SDL_Quit();

return EXIT_SUCCESS;

}

The call to SDL_SetVideoMode() generated a core on my machine, so I
rebuilt the package in debug mode (-O0 -g) to investigate the problem.

The crash happens on src/video/x11/SDL_x11video.c:1420

[…snip…]
SDL_Color *want, *reject;
unsigned long freelist;
int i;
int nfree = 0;
int nc = this->screen->format->palette->ncolors;
colors = this->screen->format->palette->colors;
freelist = SDL_stack_alloc(unsigned long, nc);
/
make sure multiple allocations of the same cell are freed */
for(i = 0; i < ncolors; i++) {
int pixel = firstcolor + i;
while(SDL_XPixels[pixel]) {
freelist[nfree++] = pixel;
–SDL_XPixels[pixel];
}
}
XFreeColors(GFX_Display, SDL_XColorMap, freelist, nfree, 0);
SDL_stack_free(freelist);
[…snip…]

I think the bug is due an false statement, that is the SDL_XPixels array
size equals “this->screen->format->palette->ncolors” (256), but actually it
is “SDL_Visual->map_entries” (128) due the allocation on this point:

src/video/x11/SDL_x11video.c:987
[…snip…]
int ncolors;

/* Allocate the pixel flags */
ncolors = SDL_Visual->map_entries;
SDL_XPixels = SDL_malloc(ncolors * sizeof(int));
if(SDL_XPixels == NULL) {
SDL_OutOfMemory();
return -1;
}
SDL_memset(SDL_XPixels, 0, ncolors * sizeof(*SDL_XPixels));
[…snip…]

where “SDL_Visual->map_entries” on my machine is 128 and according to
the man page of wildcatfb:

wildcatfb is an Xorg driver for the Sun Expert3D framebuffer family,
relying upon the OpenBSD console mode framebuffer driver of the same
name. This driver is not accelerated yet, and only supports a 7-bit
framebuffer depth.

I think it’s right due to the 7-bit framebuffer depth.

Now I think that SDL always states 256 colors in spite the real value,
moreover inside the “allocate_nearest()” function it uses the constant
value 256:

[…snip…]
XColor all[256];
int i;
for(i = 0; i < 256; i++)
all[i].pixel = i;
/*

  • XQueryColors sets the flags in the XColor struct, so we use
  • that to keep track of which colours are available
    */
    XQueryColors(GFX_Display, SDL_XColorMap, all, 256);

for(i = 0; i < nwant; i++) {
XColor c;
int j;
int best = 0;
int mindist = 0x7fffffff;
int ri = want[i].r;
int gi = want[i].g;
int bi = want[i].b;
for(j = 0; j < 256; j++) {
int rj, gj, bj, d2;
if(!all[j].flags)
continue; /
unavailable colour cell */
rj = all[j].red >> 8;
gj = all[j].green >> 8;
bj = all[j].blue >> 8;
d2 = COLOUR_DIST(ri, gi, bi, rj, gj, bj);
if(d2 < mindist) {
mindist = d2;
best = j;
}
}
if(SDL_XPixels[best])
[…snip…]

Is anyone interested to fix this bugs?