kolibrios-fun/programs/media/Fplay/pixlib2.c
Sergey Semyonov (Serge) 84726c7e7b sna scaler
git-svn-id: svn://kolibrios.org@2349 a494cfbc-eb01-0410-851d-a64ba20cac60
2012-02-13 22:34:36 +00:00

328 lines
7.0 KiB
C

#include <stdint.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <stdio.h>
#include <fcntl.h>
#include "fplay.h"
#define DISPLAY_VERSION 0x0200 /* 2.00 */
#define SRV_GETVERSION 0
#define SRV_GET_CAPS 3
#define SRV_CREATE_SURFACE 10
#define SRV_BLIT_VIDEO 20
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
//void InitPixlib(uint32_t flags);
static uint32_t service;
static uint32_t blit_caps;
typedef struct
{
uint32_t idx;
union
{
uint32_t opt[2];
struct {
uint32_t max_tex_width;
uint32_t max_tex_height;
}cap1;
};
}hwcaps_t;
static uint32_t get_service(char *name)
{
uint32_t retval = 0;
asm volatile ("int $0x40"
:"=a"(retval)
:"a"(68),"b"(16),"c"(name)
:"memory");
return retval;
};
static int call_service(ioctl_t *io)
{
int retval;
asm volatile("int $0x40"
:"=a"(retval)
:"a"(68),"b"(17),"c"(io)
:"memory","cc");
return retval;
};
#define BUFFER_SIZE(n) ((n)*sizeof(uint32_t))
uint32_t InitPixlib(uint32_t caps)
{
uint32_t api_version;
hwcaps_t hwcaps;
ioctl_t io;
// __asm__ __volatile__("int3");
service = get_service("DISPLAY");
if(service == 0)
goto fail;
io.handle = service;
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;
/*
* Let's see what this service can do
*/
hwcaps.idx = 0;
io.handle = service;
io.io_code = SRV_GET_CAPS;
io.input = &hwcaps;
io.inp_size = sizeof(hwcaps);
io.output = NULL;
io.out_size = 0;
if (call_service(&io)!=0)
goto fail;
blit_caps = hwcaps.opt[0];
printf("\nDISPLAY service handle %x\n", service);
if( blit_caps )
printf("service caps %s%s%s\n",
(blit_caps & HW_BIT_BLIT) != 0 ?"HW_BIT_BLIT ":"",
(blit_caps & HW_TEX_BLIT) != 0 ?"HW_TEX_BLIT ":"",
(blit_caps & HW_VID_BLIT) != 0 ?"HW_VID_BLIT ":"");
blit_caps&= caps;
return blit_caps;
fail:
service = 0;
return 0;
};
int create_bitmap(bitmap_t *bitmap)
{
// __asm__ __volatile__("int3");
if( blit_caps & HW_BIT_BLIT )
{
struct __attribute__((packed)) /* SRV_CREATE_SURFACE */
{
uint32_t handle; // ignored
void *data; // ignored
uint32_t width;
uint32_t height;
uint32_t pitch; // ignored
uint32_t max_width;
uint32_t max_height;
uint32_t format; // reserved mbz
}io_10;
ioctl_t io;
int err;
// printf("create bitmap %d x %d\n",
// bitmap->width, bitmap->height);
io_10.width = bitmap->width;
io_10.height = bitmap->height;
io_10.max_width = 0;
io_10.max_height = 0;
io_10.format = 0;
io.handle = service;
io.io_code = SRV_CREATE_SURFACE;
io.input = &io_10;
io.inp_size = BUFFER_SIZE(8);
io.output = NULL;
io.out_size = 0;
err = call_service(&io);
if(err==0)
{
bitmap->handle = io_10.handle;
bitmap->pitch = io_10.pitch;
bitmap->data = io_10.data;
// printf("Create hardware surface %x pitch %d, buffer %x\n",
// bitmap->handle, bitmap->pitch, bitmap->data);
return 0;
};
return err;
};
uint32_t size;
uint32_t pitch;
uint8_t *buffer;
pitch = ALIGN(bitmap->width*4, 16);
size = pitch * bitmap->height;
buffer = (uint8_t*)user_alloc(size);
if( buffer )
{
bitmap->handle = 0;
bitmap->pitch = pitch;
bitmap->data = buffer;
return 0;
};
printf("Cannot alloc frame buffer\n\r");
return -1;
};
struct blit_call
{
int dstx;
int dsty;
int w;
int h;
int srcx;
int srcy;
int srcw;
int srch;
unsigned char *bitmap;
int stride;
};
int blit_bitmap(bitmap_t *bitmap, int dst_x, int dst_y,
int w, int h)
{
if( blit_caps & HW_BIT_BLIT )
{
/*
* Now you will experience the full power of the dark side...
*/
struct __attribute__((packed))
{
uint32_t handle;
int dst_x;
int dst_y;
int src_x;
int src_y;
uint32_t w;
uint32_t h;
}io_20;
ioctl_t io;
int err;
io_20.handle = bitmap->handle;
io_20.dst_x = dst_x;
io_20.dst_y = dst_y;
io_20.src_x = 0;
io_20.src_y = 0;
io_20.w = w;
io_20.h = h;
io.handle = service;
io.io_code = SRV_BLIT_VIDEO;
io.input = &io_20;
io.inp_size = BUFFER_SIZE(7);
io.output = NULL;
io.out_size = 0;
// printf("do blit %x pitch %d\n",bitmap->handle,
// bitmap->pitch);
err = call_service(&io);
if (call_service(&io)==0)
{
//bitmap->data = NULL; Not now, Serge
// printf("blit done\n");
delay(1);
return 0;
};
return err;
};
volatile struct blit_call bc;
bc.dstx = dst_x;
bc.dsty = dst_y;
bc.w = w;
bc.h = h;
bc.srcx = 0;
bc.srcy = 0;
bc.srcw = w;
bc.srch = h;
bc.stride = bitmap->pitch;
bc.bitmap = bitmap->data;
__asm__ __volatile__(
"int $0x40"
::"a"(73),"b"(0),"c"(&bc));
};
static inline void* user_realloc(void *mem, size_t size)
{
void *val;
__asm__ __volatile__(
"int $0x40"
:"=eax"(val)
:"a"(68),"b"(12),"c"(size),"d"(mem)
:"memory");
return val;
}
int resize_bitmap(bitmap_t *bitmap)
{
// __asm__ __volatile__("int3");
if( blit_caps & HW_BIT_BLIT )
{
/* work in progress */
};
uint32_t size;
uint32_t pitch;
uint8_t *buffer;
pitch = ALIGN(bitmap->width*4, 16);
size = pitch * bitmap->height;
buffer = (uint8_t*)user_realloc(bitmap->data, size);
if( buffer )
{
bitmap->handle = 0;
bitmap->pitch = pitch;
bitmap->data = buffer;
return 0;
};
printf("Cannot realloc frame buffer\n\r");
return -1;
};