0,0 → 1,264 |
#include <stdio.h> |
#include <malloc.h> |
#include <stdbool.h> |
#include <kos32sys.h> |
|
#include "pixlib3.h" |
#include "pixdriver.h" |
|
#define DISPLAY_VERSION 0x0200 /* 2.00 */ |
|
#define SRV_GETVERSION 0 |
#define SRV_GET_CAPS 3 |
|
|
#define BUFFER_SIZE(n) ((n)*sizeof(uint32_t)) |
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) |
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) |
|
struct bitmap |
{ |
uint32_t width; |
uint32_t height; |
uint32_t pitch; |
void *buffer; |
uint32_t size; |
}; |
|
static uint32_t fd; |
static struct pix_driver *driver; |
|
|
static bitmap_t *sw_create_bitmap(uint32_t width, uint32_t height) |
{ |
bitmap_t *bitmap; |
|
bitmap = malloc(sizeof(bitmap_t)); |
if(bitmap == NULL) |
goto err_0; |
|
bitmap->width = width; |
bitmap->height = height; |
|
bitmap->pitch = ALIGN(width * 4, 16); |
bitmap->size = ALIGN(bitmap->pitch * height, 4096); |
|
bitmap->buffer = user_alloc(bitmap->size); |
if (bitmap->buffer == NULL) |
goto err_1; |
|
printf("create bitmap: %p %dx%d buffer: %p\n", |
bitmap, bitmap->width, bitmap->height, bitmap->buffer); |
|
return bitmap; |
|
err_1: |
free(bitmap); |
err_0: |
return NULL; |
}; |
|
static int sw_destroy_bitmap(bitmap_t * bitmap) |
{ |
user_free(bitmap->buffer); |
free(bitmap); |
return 0; |
}; |
|
static void *sw_lock_bitmap(bitmap_t *bitmap, uint32_t *pitch) |
{ |
*pitch = bitmap->pitch; |
|
return bitmap->buffer; |
}; |
|
static int sw_resize_bitmap(bitmap_t * bitmap, uint32_t width, uint32_t height) |
{ |
uint32_t size; |
uint32_t pitch; |
|
pitch = ALIGN(width * 4, 16); |
size = ALIGN(pitch * height, 4096); |
|
if (size > bitmap->size) |
{ |
bitmap->buffer = user_realloc(bitmap->buffer, size); /* grow buffer */ |
if (bitmap->buffer == NULL) |
return -1; |
|
bitmap->size = size; |
} |
else if (size < bitmap->size) |
user_unmap(bitmap->buffer, size, bitmap->size - size); /* unmap unused pages */ |
|
bitmap->width = width; |
bitmap->height = height; |
bitmap->pitch = pitch; |
|
return 0; |
}; |
|
static int sw_blit(bitmap_t * bitmap, int dst_x, int dst_y, |
uint32_t w, uint32_t h, int src_x, int src_y) |
{ |
struct blit_call bc; |
int ret; |
|
bc.dstx = dst_x; |
bc.dsty = dst_y; |
bc.w = w; |
bc.h = h; |
bc.srcx = src_x; |
bc.srcy = src_y; |
bc.srcw = bitmap->width; |
bc.srch = bitmap->height; |
bc.stride = bitmap->pitch; |
bc.bitmap = bitmap->buffer; |
|
__asm__ __volatile__( |
"int $0x40":"=a"(ret):"a"(73), "b"(0x00), |
"c"(&bc):"memory"); |
|
return ret; |
}; |
|
static int sw_create_client(int x, int y, uint32_t width, uint32_t height) |
{ |
return 0; |
}; |
|
static int sw_resize_client(int x, int y, uint32_t width, uint32_t height) |
{ |
return 0; |
}; |
|
bitmap_t *pxCreateBitmap(uint32_t width, uint32_t height) |
{ |
return driver->create_bitmap(width, height); |
}; |
|
int pxDestroyBitmap(bitmap_t *bitmap) |
{ |
return driver->destroy_bitmap(bitmap); |
}; |
|
void *pxLockBitmap(bitmap_t *bitmap, uint32_t *pitch) |
{ |
return driver->lock_bitmap(bitmap, pitch); |
}; |
|
int pxResizeBitmap(bitmap_t *bitmap, uint32_t width, uint32_t height) |
{ |
return driver->resize_bitmap(bitmap, width, height); |
}; |
|
int pxBlitBitmap(bitmap_t *bitmap, int dst_x, int dst_y, |
uint32_t w, uint32_t h, int src_x, int src_y) |
{ |
return driver->blit_bitmap(bitmap, dst_x, dst_y, |
w, h, src_x, src_y); |
}; |
|
int pxCreateClient(int x, int y, uint32_t width, uint32_t height) |
{ |
return driver->create_client(x, y, width, height); |
} |
|
int pxResizeClient(int x, int y, uint32_t width, uint32_t height) |
{ |
printf("resize client\n"); |
return driver->resize_client(x, y, width, height); |
} |
|
static struct pix_driver sw_driver = |
{ |
0, |
sw_create_bitmap, |
sw_destroy_bitmap, |
sw_lock_bitmap, |
sw_resize_bitmap, |
sw_blit, |
sw_create_client, |
sw_resize_client, |
NULL |
}; |
|
|
uint32_t pxInit(int hw) |
{ |
void *lib; |
struct pix_driver *(*drventry)(uint32_t service); |
|
uint32_t api_version; |
ioctl_t io; |
|
driver = &sw_driver; |
|
if(hw == 0) |
return 0; |
|
if (fd != 0) |
return driver->driver_caps; |
|
fd = get_service("DISPLAY"); |
if (fd == 0) |
goto fail; |
|
io.handle = fd; |
io.io_code = SRV_GETVERSION; |
io.input = NULL; |
io.inp_size = 0; |
io.output = &api_version; |
io.out_size = BUFFER_SIZE(1); |
|
if (call_service(&io) != 0) |
goto fail; |
|
if ((DISPLAY_VERSION > (api_version & 0xFFFF)) || |
(DISPLAY_VERSION < (api_version >> 16))) |
goto fail; |
|
lib = load_library("pixlib-gl.dll"); |
if(lib == 0) |
goto fail; |
|
drventry = get_proc_address(lib, "DrvInit"); |
|
if( drventry == NULL) |
goto fail; |
|
driver = drventry(fd); |
if(driver == NULL) |
{ |
driver = &sw_driver; |
goto fail; |
}; |
|
if (driver->driver_caps) |
printf("2D caps %s%s%s\n", |
(driver->driver_caps & HW_BIT_BLIT) != 0 ? "HW_BIT_BLIT " : "", |
(driver->driver_caps & HW_TEX_BLIT) != 0 ? "HW_TEX_BLIT " : "", |
(driver->driver_caps & HW_VID_BLIT) != 0 ? "HW_VID_BLIT " : ""); |
|
return driver->driver_caps; |
|
fail: |
printf("Warning! Hardware initialization failed.\n" |
"fallback to software rendering.\n"); |
fd = 0; |
return 0; |
}; |
|
void pxFini() |
{ |
if (driver->fini) |
driver->fini(); |
}; |
|
|
|
|
|
|
|
|