enhance GAL_blit to have a pointer to GAL_VideoDevice for hardware acceleration blits

This commit is contained in:
Vincent Wei
2023-07-23 15:05:54 +08:00
parent 2665200eee
commit d6a961aa6c
12 changed files with 191 additions and 110 deletions
+4 -2
View File
@@ -117,8 +117,10 @@ void GAL_FreeFormat(GAL_PixelFormat *format);
/* typedef for private surface blitting functions */
struct GAL_Surface;
typedef int (*GAL_blit)(struct GAL_Surface *src, GAL_Rect *srcrect,
struct GAL_Surface *dst, GAL_Rect *dstrect);
typedef int (*GAL_blit)(GAL_VideoDevice *video,
struct GAL_Surface *src, GAL_Rect *srcrect,
struct GAL_Surface *dst, GAL_Rect *dstrect);
#if IS_COMPOSITING_SCHEMA
typedef struct _DirtyInfo {
+79 -75
View File
@@ -462,99 +462,100 @@ static void RLEClipBlit(int w, Uint8 *srcbuf, GAL_Surface *dst,
}
/* blit a colorkeyed RLE surface */
int GAL_RLEBlit(GAL_Surface *src, GAL_Rect *srcrect,
int GAL_RLEBlit(GAL_VideoDevice *video, GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
{
Uint8 *dstbuf;
Uint8 *srcbuf;
int x, y;
int w = src->w;
unsigned alpha;
(void)video;
/* Set up the source and destination pointers */
x = dstrect->x;
y = dstrect->y;
dstbuf = (Uint8 *)dst->pixels
+ y * dst->pitch + x * src->format->BytesPerPixel;
srcbuf = (Uint8 *)src->map->sw_data->aux_data;
Uint8 *dstbuf;
Uint8 *srcbuf;
int x, y;
int w = src->w;
unsigned alpha;
{
/* skip lines at the top if neccessary */
int vskip = srcrect->y;
int ofs = 0;
if(vskip) {
/* Set up the source and destination pointers */
x = dstrect->x;
y = dstrect->y;
dstbuf = (Uint8 *)dst->pixels
+ y * dst->pitch + x * src->format->BytesPerPixel;
srcbuf = (Uint8 *)src->map->sw_data->aux_data;
{
/* skip lines at the top if neccessary */
int vskip = srcrect->y;
int ofs = 0;
if(vskip) {
#define RLESKIP(bpp, Type) \
for(;;) { \
int run; \
ofs += *(Type *)srcbuf; \
run = ((Type *)srcbuf)[1]; \
srcbuf += sizeof(Type) * 2; \
if(run) { \
srcbuf += run * bpp; \
ofs += run; \
} else if(!ofs) \
goto done; \
if(ofs == w) { \
ofs = 0; \
if(!--vskip) \
break; \
} \
}
for(;;) { \
int run; \
ofs += *(Type *)srcbuf; \
run = ((Type *)srcbuf)[1]; \
srcbuf += sizeof(Type) * 2; \
if(run) { \
srcbuf += run * bpp; \
ofs += run; \
} else if(!ofs) \
goto done; \
if(ofs == w) { \
ofs = 0; \
if(!--vskip) \
break; \
} \
}
switch(src->format->BytesPerPixel) {
case 1: RLESKIP(1, Uint8); break;
case 2: RLESKIP(2, Uint8); break;
case 3: RLESKIP(3, Uint8); break;
case 4: RLESKIP(4, Uint16); break;
}
switch(src->format->BytesPerPixel) {
case 1: RLESKIP(1, Uint8); break;
case 2: RLESKIP(2, Uint8); break;
case 3: RLESKIP(3, Uint8); break;
case 4: RLESKIP(4, Uint16); break;
}
#undef RLESKIP
}
}
}
alpha = (src->flags & GAL_SRCALPHA) == GAL_SRCALPHA
? src->format->alpha : 255;
/* if left or right edge clipping needed, call clip blit */
if ( srcrect->x || srcrect->w != src->w ) {
RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha);
} else {
GAL_PixelFormat *fmt = src->format;
alpha = (src->flags & GAL_SRCALPHA) == GAL_SRCALPHA
? src->format->alpha : 255;
/* if left or right edge clipping needed, call clip blit */
if ( srcrect->x || srcrect->w != src->w ) {
RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha);
} else {
GAL_PixelFormat *fmt = src->format;
#define RLEBLIT(bpp, Type, do_blit) \
do { \
int linecount = srcrect->h; \
int ofs = 0; \
for(;;) { \
unsigned run; \
ofs += *(Type *)srcbuf; \
run = ((Type *)srcbuf)[1]; \
srcbuf += 2 * sizeof(Type); \
if(run) { \
do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \
srcbuf += run * bpp; \
ofs += run; \
} else if(!ofs) \
break; \
if(ofs == w) { \
ofs = 0; \
dstbuf += dst->pitch; \
if(!--linecount) \
break; \
} \
do { \
int linecount = srcrect->h; \
int ofs = 0; \
for(;;) { \
unsigned run; \
ofs += *(Type *)srcbuf; \
run = ((Type *)srcbuf)[1]; \
srcbuf += 2 * sizeof(Type); \
if(run) { \
do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \
srcbuf += run * bpp; \
ofs += run; \
} else if(!ofs) \
break; \
if(ofs == w) { \
ofs = 0; \
dstbuf += dst->pitch; \
if(!--linecount) \
break; \
} \
} while(0)
} \
} while(0)
CHOOSE_BLIT(RLEBLIT, alpha, fmt);
CHOOSE_BLIT(RLEBLIT, alpha, fmt);
#undef RLEBLIT
}
}
done:
return(0);
return(0);
}
#undef OPAQUE_BLIT
@@ -720,9 +721,12 @@ static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, GAL_Surface *dst,
}
/* blit a pixel-alpha RLE surface */
int GAL_RLEAlphaBlit(GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
int GAL_RLEAlphaBlit(GAL_VideoDevice *video,
GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
{
(void)video;
int x, y;
int w = src->w;
Uint8 *srcbuf, *dstbuf;
@@ -1502,7 +1506,7 @@ void GAL_UnRLESurface(GAL_Surface *surface, int recode)
full.h = surface->h;
alpha_flag = surface->flags & GAL_SRCALPHA;
surface->flags &= ~GAL_SRCALPHA; /* opaque blit */
GAL_RLEBlit(surface, &full, surface, &full);
GAL_RLEBlit(NULL, surface, &full, surface, &full);
surface->flags |= alpha_flag;
} else
UnRLEAlpha(surface);
+6 -4
View File
@@ -47,9 +47,11 @@
/* Useful functions and variables from RLEaccel.c */
extern int GAL_RLESurface(GAL_Surface *surface);
extern int GAL_RLEBlit(GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect);
extern int GAL_RLEAlphaBlit(GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect);
extern int GAL_RLEBlit(GAL_VideoDevice *video,
GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect);
extern int GAL_RLEAlphaBlit(GAL_VideoDevice *video,
GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect);
extern void GAL_UnRLESurface(GAL_Surface *surface, int recode);
+11 -4
View File
@@ -57,9 +57,12 @@
#include "memops.h"
/* The general purpose software blit routine */
static int GAL_SoftBlit(GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
static int GAL_SoftBlit(GAL_VideoDevice *video,
GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
{
(void)video;
int okay;
/* Everything is okay at the beginning... */
@@ -166,7 +169,8 @@ static void GAL_BlitCopyOverlap(GAL_BlitInfo *info)
#ifdef _MGUSE_PIXMAN
#include <pixman.h>
static int GAL_PixmanBlit (struct GAL_Surface *src, GAL_Rect *srcrect,
static int GAL_PixmanBlit(GAL_VideoDevice *video,
struct GAL_Surface *src, GAL_Rect *srcrect,
struct GAL_Surface *dst, GAL_Rect *dstrect);
#endif
@@ -383,9 +387,12 @@ int GAL_CleanupBlitting (GAL_Surface *src, GAL_Surface *dst)
return 0;
}
static int GAL_PixmanBlit (struct GAL_Surface *src, GAL_Rect *srcrect,
static int GAL_PixmanBlit (GAL_VideoDevice *video,
struct GAL_Surface *src, GAL_Rect *srcrect,
struct GAL_Surface *dst, GAL_Rect *dstrect)
{
(void)video;
pixman_image_t *src_img = src->pix_img, *dst_img = dst->pix_img;
pixman_image_t *msk_img;
pixman_op_t op;
+5
View File
@@ -80,10 +80,15 @@ typedef struct GAL_BlitMap {
Uint8 *table;
GAL_blit hw_blit;
GAL_blit sw_blit;
GAL_VideoDevice *video;
/* data for hardware blittor */
union {
struct private_hwaccel *hw_data;
void *hw_void;
};
/* data for software blittor */
struct private_swaccel *sw_data;
int identity;
+3 -2
View File
@@ -3502,10 +3502,9 @@ static void DRM_FreeHWSurface_Accl(_THIS, GAL_Surface *surface)
surface->hwdata = NULL;
}
static int DRM_HWBlit(GAL_Surface *src, GAL_Rect *src_rc,
static int DRM_HWBlit(_THIS, GAL_Surface *src, GAL_Rect *src_rc,
GAL_Surface *dst, GAL_Rect *dst_rc)
{
GAL_VideoDevice *this = __mg_current_video;
DrmVideoData* vdata = this->hidden;
DrmSurfaceBuffer *src_buf, *dst_buf;
@@ -3576,10 +3575,12 @@ static int DRM_CheckHWBlit_Accl(_THIS, GAL_Surface *src, const GAL_Rect *srcrc,
dst_buf, dstrc, &blit_ops);
if (blitor) {
src->map->video = this;
src->map->hw_blit = DRM_HWBlit;
src->map->hw_void = blitor;
}
else {
src->map->video = NULL;
src->map->hw_blit = NULL;
src->flags &= ~GAL_HWACCEL;
}
+7 -2
View File
@@ -100,10 +100,9 @@ static int FillHWRect(_THIS, GAL_Surface *dst, const GAL_Rect *rect, Uint32 colo
return(0);
}
static int HWAccelBlit(GAL_Surface *src, GAL_Rect *srcrect,
static int HWAccelBlit(_THIS, GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
{
GAL_VideoDevice *this = __mg_current_video;
int bpp;
Uint32 src_format;
/* Uint32 dst_format; */
@@ -201,8 +200,14 @@ static int CheckHWBlit(_THIS, GAL_Surface *src, const GAL_Rect *srcrc,
/* Check to see if final surface blit is accelerated */
accelerated = !!(src->flags & GAL_HWACCEL);
if ( accelerated ) {
src->map->video = this;
src->map->hw_blit = HWAccelBlit;
}
else {
src->map->video = NULL;
src->map->hw_blit = NULL;
}
return(accelerated);
}
+8 -3
View File
@@ -118,10 +118,9 @@ static int FillHWRect(_THIS, GAL_Surface *dst, const GAL_Rect *rect, Uint32 colo
return(0);
}
static int HWAccelBlit(GAL_Surface *src, GAL_Rect *srcrect,
static int HWAccelBlit(_THIS, GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
{
GAL_VideoDevice *this = __mg_current_video;
int pitch, w, h;
int srcX, srcY;
int dstX, dstY;
@@ -132,7 +131,7 @@ static int HWAccelBlit(GAL_Surface *src, GAL_Rect *srcrect,
/* FIXME: For now, only blit to display surface */
if ( dst->pitch != GAL_VideoSurface->pitch ) {
return(src->map->sw_blit(src, srcrect, dst, dstrect));
return(src->map->sw_blit(this, src, srcrect, dst, dstrect));
}
/* Calculate source and destination base coordinates (in pixels) */
@@ -242,8 +241,14 @@ static int CheckHWBlit(_THIS, GAL_Surface *src, const GAL_Rect *srcrc,
/* Check to see if final surface blit is accelerated */
accelerated = !!(src->flags & GAL_HWACCEL);
if ( accelerated ) {
src->map->video = this;
src->map->hw_blit = HWAccelBlit;
}
else {
src->map->video = NULL;
src->map->hw_blit = NULL;
}
return(accelerated);
}
+9 -1
View File
@@ -189,9 +189,11 @@ static void make_rects (GAL_Rect *src, GAL_Rect* dst, const RECT* rc, Uint32 x,
dst->h = src->h;
}
static int HWAccelBlit (GAL_Surface *src, GAL_Rect *srcrect,
static int HWAccelBlit (_THIS, GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
{
(void)this;
RECT rc_src = {srcrect->x, srcrect->y, srcrect->x + srcrect->w, srcrect->y + srcrect->h};
RECT rc_dst = {dstrect->x, dstrect->y, dstrect->x + dstrect->w, dstrect->y + dstrect->h};
RECT rc_inter, rc_sub [4];
@@ -270,8 +272,14 @@ static int CheckHWBlit(_THIS, GAL_Surface *src, const GAL_Rect *srcrc,
/* Check to see if final surface blit is accelerated */
accelerated = !!(src->flags & GAL_HWACCEL);
if ( accelerated ) {
src->map->video = this;
src->map->hw_blit = HWAccelBlit;
}
else {
src->map->video = NULL;
src->map->hw_blit = NULL;
}
return(accelerated);
}
+8 -1
View File
@@ -770,9 +770,11 @@ static void SMI_BlitTransRect (int srcx, int srcy, int w, int h, int dstx,
#endif
}
static int SMI_HWAccelBlit (GAL_Surface *src, GAL_Rect *srcrect,
static int SMI_HWAccelBlit (_THIS, GAL_Surface *src, GAL_Rect *srcrect,
GAL_Surface *dst, GAL_Rect *dstrect)
{
(void)this;
SMIPtr pSmi = &smi_rec;
int srcx = srcrect->x;
int srcy = srcrect->y;
@@ -858,8 +860,13 @@ static int SMI_CheckHWBlit (_THIS, GAL_Surface *src, const GAL_Rect *srcrc,
/* Check to see if final surface blit is accelerated */
accelerated = !!(src->flags & GAL_HWACCEL);
if (accelerated) {
src->map->video = this;
src->map->hw_blit = SMI_HWAccelBlit;
}
else {
src->map->video = NULL;
src->map->hw_blit = NULL;
}
return (accelerated);
}
+50 -15
View File
@@ -271,8 +271,37 @@ static BOOL SHADOW_SyncUpdate (_THIS);
static BOOL SHADOW_SyncUpdateAsync (_THIS);
/* Hardware surface functions */
static int SHADOW_AllocHWSurface (_THIS, GAL_Surface *surface);
static void SHADOW_FreeHWSurface (_THIS, GAL_Surface *surface);
static int SHADOW_AllocHWSurface (_THIS, GAL_Surface *surface)
{
GAL_VideoDevice *real_device;
real_device = this->hidden->realfb_info->real_device;
return real_device->AllocHWSurface(real_device, surface);
}
static void SHADOW_FreeHWSurface (_THIS, GAL_Surface *surface)
{
GAL_VideoDevice *real_device;
if (this->hidden->realfb_info) {
real_device = this->hidden->realfb_info->real_device;
real_device->FreeHWSurface(real_device, surface);
}
}
static int SHADOW_CheckHWBlit(_THIS, GAL_Surface *src, const GAL_Rect *srcrc,
GAL_Surface *dst, const GAL_Rect *dstrc, DWORD op)
{
GAL_VideoDevice *real_device;
real_device = this->hidden->realfb_info->real_device;
return real_device->CheckHWBlit(real_device, src, srcrc, dst, dstrc, op);
}
static int SHADOW_FillHWRect(_THIS, GAL_Surface *dst, const GAL_Rect *dstrc,
Uint32 color)
{
GAL_VideoDevice *real_device;
real_device = this->hidden->realfb_info->real_device;
return real_device->FillHWRect(real_device, dst, dstrc, color);
}
#ifdef _MGRM_PROCESSES
static int shmid;
@@ -373,10 +402,10 @@ static GAL_VideoDevice *SHADOW_CreateDevice(int devindex)
device->SetVideoMode = SHADOW_SetVideoMode;
device->SetColors = SHADOW_SetColors;
device->VideoQuit = SHADOW_VideoQuit;
device->AllocHWSurface = SHADOW_AllocHWSurface;
device->AllocHWSurface = NULL;
device->CheckHWBlit = NULL;
device->FillHWRect = NULL;
device->FreeHWSurface = SHADOW_FreeHWSurface;
device->FreeHWSurface = NULL;
device->UpdateRects = SHADOW_UpdateRects;
#ifdef _MGRM_PROCESSES
if (mgIsServer)
@@ -733,6 +762,9 @@ static void *task_do_update(void *data)
if (RECTH(this->hidden->update_rect)) {
update_helper(this, real_device, &this->hidden->update_rect);
}
else {
_DBG_PRINTF("Empty update rectangle\n");
}
#if USE_UPDATE_SEM
if (sem_post(&this->hidden->update_sem))
@@ -1273,6 +1305,19 @@ static GAL_Surface *SHADOW_SetVideoMode(_THIS, GAL_Surface *current,
}
}
if (real_device->AllocHWSurface) {
this->AllocHWSurface = SHADOW_AllocHWSurface;
}
if (real_device->CheckHWBlit) {
this->CheckHWBlit = SHADOW_CheckHWBlit;
}
if (real_device->FillHWRect) {
this->FillHWRect = SHADOW_FillHWRect;
}
if (real_device->FreeHWSurface) {
this->FreeHWSurface = SHADOW_FreeHWSurface;
}
/* We're done */
return (current);
}
@@ -1457,6 +1502,7 @@ static void SHADOW_VideoQuit (_THIS)
_shadowfbheader = NULL;
shmdt (tmp);
shadow_fb_ops.release(this->hidden->realfb_info);
this->hidden->realfb_info = NULL;
if (shmctl (shmid, IPC_RMID, NULL))
perror ("NEWGAL>SHADOW: shmctl");
@@ -1474,17 +1520,6 @@ static GAL_Rect **SHADOW_ListModes (_THIS, GAL_PixelFormat *format,
return (GAL_Rect **) -1;
}
/* We don't actually allow hardware surfaces other than the main one */
static int SHADOW_AllocHWSurface (_THIS, GAL_Surface *surface)
{
return -1;
}
static void SHADOW_FreeHWSurface (_THIS, GAL_Surface *surface)
{
surface->pixels = NULL;
}
static int SHADOW_SetColors (_THIS, int firstcolor, int ncolors,
GAL_Color *colors)
{
+1 -1
View File
@@ -548,7 +548,7 @@ int GAL_LowerBlit (GAL_Surface *src, GAL_Rect *srcrect,
_DBG_PRINTF("calling do_blit: from (%d, %d, %d, %d) to (%d, %d)\n",
srcrect->x, srcrect->y, srcrect->w, srcrect->h,
dstrect->x, dstrect->y);
ret = do_blit(src, srcrect, dst, dstrect);
ret = do_blit(src->map->video, src, srcrect, dst, dstrect);
#endif
return ret;