mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-26 03:23:46 +08:00
refactor use of pixman functions: use GAL_BlittingContext
This commit is contained in:
+95
-23
@@ -173,6 +173,10 @@ typedef struct _ShadowSurfaceHeader {
|
||||
RECT dirty_rc;
|
||||
} GAL_ShadowSurfaceHeader;
|
||||
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
typedef union pixman_image pixman_image_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This structure should be treated as read-only, except for 'pixels',
|
||||
* which, if not NULL, contains the raw pixel data for the surface.
|
||||
@@ -210,8 +214,10 @@ typedef struct GAL_Surface {
|
||||
/* reference count -- used when freeing surface */
|
||||
unsigned int refcount; /* Read-mostly */
|
||||
|
||||
/* temp. data */
|
||||
uintptr_t tmp_data; /* Private */
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
pixman_image_t *pix_img; /* The pixman image object for this surface */
|
||||
void *blit_ctxt; /* blitting context */
|
||||
#endif
|
||||
|
||||
#if IS_COMPOSITING_SCHEMA
|
||||
/* The pointer to GAL_SharedSurfaceHeader if the surface
|
||||
@@ -224,22 +230,42 @@ typedef struct GAL_Surface {
|
||||
|
||||
/* These are the currently supported flags for the GAL_surface */
|
||||
/* Available for GAL_CreateRGBSurface() or GAL_SetVideoMode() */
|
||||
#define GAL_SWSURFACE MEMDC_FLAG_SWSURFACE /* Surface is in system memory */
|
||||
#define GAL_HWSURFACE MEMDC_FLAG_HWSURFACE /* Surface is in video memory */
|
||||
#define GAL_ASYNCBLIT 0x00000004 /* Use asynchronous blits if possible */
|
||||
/* Available for GAL_SetVideoMode() */
|
||||
#define GAL_ANYFORMAT 0x10000000 /* Allow any video depth/pixel-format */
|
||||
#define GAL_HWPALETTE 0x20000000 /* Surface has exclusive palette */
|
||||
#define GAL_DOUBLEBUF 0x40000000 /* Set up double-buffered video mode */
|
||||
#define GAL_FULLSCREEN 0x80000000 /* Surface is a full screen display */
|
||||
|
||||
#define GAL_SWSURFACE 0x00000000 /* Surface is in system memory */
|
||||
#define GAL_HWSURFACE 0x00000001 /* Surface is in video memory */
|
||||
#define GAL_ASYNCBLIT 0x00000004 /* Use asynchronous blits if possible */
|
||||
|
||||
#define GAL_SRCCOLORKEY 0x00001000 /* Blit uses a source color key */
|
||||
#define GAL_RLEACCELOK 0x00002000 /* Private flag */
|
||||
#define GAL_RLEACCEL 0x00004000 /* Surface is RLE encoded */
|
||||
|
||||
#define GAL_SRCALPHA 0x00010000 /* Blit uses source alpha blending */
|
||||
#define GAL_SRCPIXELALPHA 0x00020000 /* Blit uses source per-pixel alpha blending */
|
||||
|
||||
/* Used internally (read-only) */
|
||||
#define GAL_HWACCEL 0x00000100 /* Blit uses hardware acceleration */
|
||||
#define GAL_SRCCOLORKEY MEMDC_FLAG_SRCCOLORKEY /* Blit uses a source color key */
|
||||
#define GAL_RLEACCELOK 0x00002000 /* Private flag */
|
||||
#define GAL_RLEACCEL MEMDC_FLAG_RLEACCEL /* Surface is RLE encoded */
|
||||
#define GAL_SRCALPHA MEMDC_FLAG_SRCALPHA /* Blit uses source alpha blending */
|
||||
#define GAL_SRCPIXELALPHA MEMDC_FLAG_SRCPIXELALPHA /* Blit uses source per-pixel alpha blending */
|
||||
#define GAL_PREALLOC 0x01000000 /* Surface uses preallocated memory */
|
||||
#define GAL_HWACCEL 0x00000100 /* Blit uses hardware acceleration */
|
||||
|
||||
#define GAL_PREALLOC 0x01000000 /* Surface uses preallocated memory */
|
||||
#define GAL_FORMAT_CHECKED 0x02000000 /* Pixman format checked */
|
||||
|
||||
/* Available for GAL_SetVideoMode() */
|
||||
#define GAL_ANYFORMAT 0x10000000 /* Allow any video depth/pixel-format */
|
||||
#define GAL_HWPALETTE 0x20000000 /* Surface has exclusive palette */
|
||||
#define GAL_DOUBLEBUF 0x40000000 /* Set up double-buffered video mode */
|
||||
#define GAL_FULLSCREEN 0x80000000 /* Surface is a full screen display */
|
||||
|
||||
/* Make sure the macros are ok */
|
||||
#define MGUI_COMPILE_TIME_ASSERT(name, x) \
|
||||
typedef int MGUI_dummy_ ## name[((x)?1:0) * 2 - 1]
|
||||
|
||||
MGUI_COMPILE_TIME_ASSERT(swsurface, GAL_SWSURFACE == MEMDC_FLAG_SWSURFACE);
|
||||
MGUI_COMPILE_TIME_ASSERT(hwsurface, GAL_HWSURFACE == MEMDC_FLAG_HWSURFACE);
|
||||
MGUI_COMPILE_TIME_ASSERT(colorkey, GAL_SRCCOLORKEY == MEMDC_FLAG_SRCCOLORKEY);
|
||||
MGUI_COMPILE_TIME_ASSERT(rleaccel, GAL_RLEACCEL == MEMDC_FLAG_RLEACCEL);
|
||||
MGUI_COMPILE_TIME_ASSERT(srcalpha, GAL_SRCALPHA == MEMDC_FLAG_SRCALPHA);
|
||||
MGUI_COMPILE_TIME_ASSERT(srcpixelapha, GAL_SRCPIXELALPHA == MEMDC_FLAG_SRCPIXELALPHA);
|
||||
|
||||
#undef MGUI_COMPILE_TIME_ASSERT
|
||||
|
||||
/* Evaluates to true if the surface needs to be locked before access */
|
||||
#define GAL_MUSTLOCK(surface) \
|
||||
@@ -779,8 +805,56 @@ GAL_Surface *GAL_ConvertSurface
|
||||
(GAL_Surface *src, GAL_PixelFormat *fmt, Uint32 flags);
|
||||
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
int GAL_CheckPixmanFormat (struct GAL_Surface *src, struct GAL_Surface *dst);
|
||||
#endif
|
||||
BOOL GAL_CreatePixmanImage (GAL_Surface *surface);
|
||||
static inline BOOL GAL_CheckPixmanFormats (GAL_Surface *src, GAL_Surface *dst)
|
||||
{
|
||||
if (GAL_CreatePixmanImage (src)) {
|
||||
if (dst != NULL && dst != src)
|
||||
return GAL_CreatePixmanImage (dst);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
typedef struct GAL_BlittingContext {
|
||||
uint16_t op;
|
||||
uint16_t filter;
|
||||
uint32_t alpha_bits;
|
||||
pixman_image_t *msk_img;
|
||||
} GAL_BlittingContext;
|
||||
|
||||
int GAL_SetupBlitting (GAL_Surface *src, GAL_Surface *dst, DWORD ops);
|
||||
|
||||
int GAL_CleanupBlitting (GAL_Surface *src, GAL_Surface *dst);
|
||||
|
||||
int GAL_SetupStretchBlit (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
GAL_Surface *dst, GAL_Rect *dstrect,
|
||||
const STRETCH_EXTRA_INFO *sei, DWORD ops);
|
||||
|
||||
int GAL_CleanupStretchBlit (GAL_Surface *src, GAL_Surface *dst);
|
||||
|
||||
#else /* defined _MGUSE_PIXMAN */
|
||||
|
||||
static inline int GAL_SetupBlitting (GAL_Surface *src, GAL_Surface *dst, DWORD ops) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int GAL_CleanupBlitting (GAL_Surface *src, GAL_Surface *dst) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int GAL_SetupStretchBlit (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
GAL_Surface *dst, GAL_Rect *dstrect,
|
||||
const STRETCH_EXTRA_INFO *sei, DWORD ops) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int GAL_CleanupStretchBlit (GAL_Surface *src, GAL_Surface *dst) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* not defined _MGUSE_PIXMAN */
|
||||
|
||||
/*
|
||||
* This performs a fast blit from the source surface to the destination
|
||||
@@ -878,14 +952,12 @@ static inline int GAL_BlitSurface (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
* can be generated by the GAL_MapRGB() function.
|
||||
* This function returns 0 on success, or -1 on error.
|
||||
*/
|
||||
int GAL_FillRect
|
||||
(GAL_Surface *dst, const GAL_Rect *dstrect, Uint32 color);
|
||||
int GAL_FillRect (GAL_Surface *dst, const GAL_Rect *dstrect, Uint32 color);
|
||||
|
||||
/*
|
||||
* This function returns the size of pad-aligned box bitmap.
|
||||
*/
|
||||
Uint32 GAL_GetBoxSize
|
||||
(GAL_Surface *src, Uint32 w, Uint32 h, Uint32* pitch_p);
|
||||
Uint32 GAL_GetBoxSize (GAL_Surface *src, Uint32 w, Uint32 h, Uint32* pitch_p);
|
||||
|
||||
/*
|
||||
* This function copies pixels in a rect from the surface to a box.
|
||||
|
||||
@@ -1303,7 +1303,7 @@ static void transit_to_layer (CompositorCtxt* ctxt, MG_Layer* to_layer)
|
||||
}
|
||||
}
|
||||
|
||||
_WRN_PRINTF ("Average time to composite the layers: %u (times: %u)\n", total_time_ms / total_times, total_times);
|
||||
_DBG_PRINTF ("Average time to composite the layers: %u (times: %u)\n", total_time_ms / total_times, total_times);
|
||||
}
|
||||
|
||||
CompositorOps __mg_fallback_compositor = {
|
||||
|
||||
@@ -17,6 +17,9 @@ DRIVERS = @VIDEO_DRIVERS@
|
||||
|
||||
# Include the architecture-independent sources
|
||||
COMMON_SRCS = \
|
||||
video.c \
|
||||
newgal.c \
|
||||
surface.c \
|
||||
RLEaccel.c \
|
||||
RLEaccel_c.h \
|
||||
blit.c \
|
||||
@@ -29,12 +32,9 @@ COMMON_SRCS = \
|
||||
leaks.h \
|
||||
pixels.c \
|
||||
pixels_c.h \
|
||||
surface.c \
|
||||
stretch.c \
|
||||
stretch_c.h \
|
||||
sysvideo.h \
|
||||
video.c \
|
||||
newgal.c \
|
||||
videomem-bucket.h \
|
||||
videomem-bucket.c \
|
||||
surface-shared.c \
|
||||
|
||||
+51
-150
@@ -163,7 +163,8 @@ static void GAL_BlitCopyOverlap(GAL_BlitInfo *info)
|
||||
}
|
||||
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
BOOL GAL_CheckPixmanFormat (struct GAL_Surface *src, struct GAL_Surface *dst);
|
||||
#include <pixman.h>
|
||||
|
||||
static int GAL_PixmanBlit (struct GAL_Surface *src, GAL_Rect *srcrect,
|
||||
struct GAL_Surface *dst, GAL_Rect *dstrect);
|
||||
#endif
|
||||
@@ -312,7 +313,7 @@ int GAL_CalculateBlit(GAL_Surface *surface)
|
||||
// have colorkey
|
||||
surface->map->sw_blit = GAL_SoftBlit;
|
||||
}
|
||||
else if (GAL_CheckPixmanFormat (surface, surface->map->dst)) {
|
||||
else if (surface->pix_img && surface->map->dst->pix_img) {
|
||||
surface->map->sw_blit = GAL_PixmanBlit;
|
||||
}
|
||||
else {
|
||||
@@ -326,179 +327,89 @@ int GAL_CalculateBlit(GAL_Surface *surface)
|
||||
}
|
||||
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
#include <pixman.h>
|
||||
|
||||
struct rgbamasks_pixman_format_map {
|
||||
uint32_t pixman_format;
|
||||
Uint32 Rmask, Gmask, Bmask, Amask;
|
||||
};
|
||||
|
||||
static struct rgbamasks_pixman_format_map _format_map_8bpp [] = {
|
||||
{ PIXMAN_r3g3b2, 0xE0, 0x1C, 0x03, 0x00 },
|
||||
{ PIXMAN_b2g3r3, 0x0E, 0x38, 0xC0, 0x00 },
|
||||
{ PIXMAN_a2r2g2b2, 0x30, 0x0C, 0x03, 0xC0 },
|
||||
{ PIXMAN_a2b2g2r2, 0x03, 0x0C, 0x03, 0xC0 },
|
||||
};
|
||||
|
||||
static struct rgbamasks_pixman_format_map _format_map_16bpp [] = {
|
||||
{ PIXMAN_x4r4g4b4, 0x0F00, 0x00F0, 0x000F, 0x0000 },
|
||||
{ PIXMAN_x4b4g4r4, 0x000F, 0x00F0, 0x0F00, 0x0000 },
|
||||
// { PIXMAN_r4g4b4x4, 0xF000, 0x0F00, 0x00F0, 0x0000 },
|
||||
// { PIXMAN_b4g4r4x4, 0x00F0, 0x0F00, 0xF000, 0x0000 },
|
||||
{ PIXMAN_a4r4g4b4, 0x0F00, 0x00F0, 0x000F, 0xF000 },
|
||||
{ PIXMAN_a4b4g4r4, 0x000F, 0x00F0, 0x0F00, 0xF000 },
|
||||
// { PIXMAN_r4g4b4a4, 0xF000, 0x0F00, 0x00F0, 0x000F },
|
||||
// { PIXMAN_b4g4r4a4, 0x00F0, 0x0F00, 0xF000, 0x000F },
|
||||
{ PIXMAN_x1r5g5b5, 0x7C00, 0x03E0, 0x001F, 0x0000 },
|
||||
{ PIXMAN_x1b5g5r5, 0x001F, 0x03E0, 0x7C00, 0x0000 },
|
||||
// { PIXMAN_r5g5b5x1, 0xF800, 0x07C0, 0x003E, 0x0000 },
|
||||
// { PIXMAN_b5g5r5x1, 0x003E, 0x07C0, 0xF800, 0x0000 },
|
||||
{ PIXMAN_a1r5g5b5, 0x7C00, 0x03E0, 0x001F, 0x8000 },
|
||||
{ PIXMAN_a1b5g5r5, 0x001F, 0x03E0, 0x7C00, 0x8000 },
|
||||
// { PIXMAN_r5g5b5a1, 0xF800, 0x07C0, 0x003E, 0x0001 },
|
||||
// { PIXMAN_b5g5r5a1, 0x003E, 0x07C0, 0xF800, 0x0001 },
|
||||
{ PIXMAN_r5g6b5, 0xF800, 0x07E0, 0x001F, 0x0000 },
|
||||
{ PIXMAN_b5g6r5, 0x001F, 0x07E0, 0xF800, 0x0000 },
|
||||
};
|
||||
|
||||
static struct rgbamasks_pixman_format_map _format_map_24bpp [] = {
|
||||
{ PIXMAN_r8g8b8, 0xFF0000, 0x00FF00, 0x0000FF, 0x000000 },
|
||||
{ PIXMAN_b8g8r8, 0x0000FF, 0x00FF00, 0xFF0000, 0x000000 },
|
||||
};
|
||||
|
||||
static struct rgbamasks_pixman_format_map _format_map_32bpp [] = {
|
||||
{ PIXMAN_x8r8g8b8, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
|
||||
{ PIXMAN_x8b8g8r8, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
|
||||
{ PIXMAN_r8g8b8x8, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 },
|
||||
{ PIXMAN_b8g8r8x8, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 },
|
||||
{ PIXMAN_a8r8g8b8, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 },
|
||||
{ PIXMAN_a8b8g8r8, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 },
|
||||
{ PIXMAN_r8g8b8a8, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF },
|
||||
{ PIXMAN_b8g8r8a8, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF },
|
||||
};
|
||||
|
||||
static uint32_t translate_gal_format(const GAL_PixelFormat *gal_format)
|
||||
int GAL_SetupBlitting (GAL_Surface *src, GAL_Surface *dst, DWORD ops)
|
||||
{
|
||||
struct rgbamasks_pixman_format_map* map;
|
||||
size_t i, n;
|
||||
if (GAL_CheckPixmanFormats (src, dst)) {
|
||||
GAL_BlittingContext* ctxt;
|
||||
src->blit_ctxt = malloc (sizeof (GAL_BlittingContext));
|
||||
if (src->blit_ctxt == NULL)
|
||||
return -1;
|
||||
|
||||
// XXX: ignore format with palette
|
||||
if (gal_format->BitsPerPixel <= 8 && gal_format->palette)
|
||||
return 0;
|
||||
ctxt = src->blit_ctxt;
|
||||
if ((src->flags & GAL_SRCALPHA) && src->format->alpha != GAL_ALPHA_OPAQUE) {
|
||||
memset (&ctxt->alpha_bits, src->format->alpha, sizeof(uint32_t));
|
||||
ctxt->msk_img = pixman_image_create_bits_no_clear (PIXMAN_a8, 1, 1,
|
||||
&ctxt->alpha_bits, 4);
|
||||
if (ctxt->msk_img)
|
||||
pixman_image_set_repeat (ctxt->msk_img, PIXMAN_REPEAT_NORMAL);
|
||||
}
|
||||
else
|
||||
ctxt->msk_img = NULL;
|
||||
|
||||
switch (gal_format->BitsPerPixel) {
|
||||
case 8:
|
||||
map = _format_map_8bpp;
|
||||
n = TABLESIZE(_format_map_8bpp);
|
||||
break;
|
||||
ops &= ~COLOR_BLEND_FLAGS_MASK;
|
||||
if (ops == COLOR_BLEND_LEGACY) {
|
||||
if ((src->flags & GAL_SRCPIXELALPHA) && src->format->Amask && src != dst) {
|
||||
ctxt->op = PIXMAN_OP_OVER;
|
||||
}
|
||||
else {
|
||||
ctxt->op = PIXMAN_OP_SRC;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ctxt->op = ops;
|
||||
}
|
||||
|
||||
case 16:
|
||||
map = _format_map_16bpp;
|
||||
n = TABLESIZE(_format_map_16bpp);
|
||||
break;
|
||||
|
||||
case 24:
|
||||
map = _format_map_24bpp;
|
||||
n = TABLESIZE(_format_map_24bpp);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
map = _format_map_32bpp;
|
||||
n = TABLESIZE(_format_map_32bpp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (gal_format->Rmask == map[i].Rmask &&
|
||||
gal_format->Gmask == map[i].Gmask &&
|
||||
gal_format->Bmask == map[i].Bmask &&
|
||||
gal_format->Amask == map[i].Amask) {
|
||||
return map[i].pixman_format;
|
||||
if (ctxt->op > PIXMAN_OP_HSL_LUMINOSITY ||
|
||||
ctxt->op < PIXMAN_OP_CLEAR) {
|
||||
ctxt->op = PIXMAN_OP_SRC;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL GAL_CheckPixmanFormat (struct GAL_Surface *src, struct GAL_Surface *dst)
|
||||
int GAL_CleanupBlitting (GAL_Surface *src, GAL_Surface *dst)
|
||||
{
|
||||
src->tmp_data = translate_gal_format (src->format);
|
||||
if (dst != src && dst != NULL) {
|
||||
dst->tmp_data = translate_gal_format (dst->format);
|
||||
return src->tmp_data && dst->tmp_data;
|
||||
if (src->blit_ctxt) {
|
||||
GAL_BlittingContext* ctxt = src->blit_ctxt;
|
||||
if (ctxt->msk_img)
|
||||
pixman_image_unref (ctxt->msk_img);
|
||||
free (src->blit_ctxt);
|
||||
src->blit_ctxt = NULL;
|
||||
}
|
||||
|
||||
return src->tmp_data != 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GAL_PixmanBlit (struct GAL_Surface *src, GAL_Rect *srcrect,
|
||||
struct GAL_Surface *dst, GAL_Rect *dstrect)
|
||||
{
|
||||
pixman_image_t *src_img = NULL, *dst_img = NULL, *msk_img = NULL;
|
||||
pixman_image_t *src_img = src->pix_img, *dst_img = dst->pix_img;
|
||||
pixman_image_t *msk_img;
|
||||
pixman_op_t op;
|
||||
uint32_t alpha_bits;
|
||||
int retv = -1;
|
||||
//pixman_region32_t clip_region;
|
||||
|
||||
assert (src->tmp_data);
|
||||
assert (dst->tmp_data);
|
||||
|
||||
if ((src->flags & GAL_SRCALPHA) && src->format->alpha != GAL_ALPHA_OPAQUE) {
|
||||
memset (&alpha_bits, src->format->alpha, sizeof(alpha_bits));
|
||||
msk_img = pixman_image_create_bits_no_clear (PIXMAN_a8, 1, 1, &alpha_bits, 4);
|
||||
if (msk_img)
|
||||
pixman_image_set_repeat (msk_img, PIXMAN_REPEAT_NORMAL);
|
||||
}
|
||||
|
||||
if (src->map->cop == COLOR_BLEND_LEGACY) {
|
||||
if ((src->flags & GAL_SRCPIXELALPHA) && src->format->Amask && src != dst) {
|
||||
op = PIXMAN_OP_OVER;
|
||||
}
|
||||
else {
|
||||
op = PIXMAN_OP_SRC;
|
||||
}
|
||||
if (src->blit_ctxt) {
|
||||
GAL_BlittingContext* ctxt = src->blit_ctxt;
|
||||
msk_img = ctxt->msk_img;
|
||||
op = (pixman_op_t)ctxt->op;
|
||||
}
|
||||
else {
|
||||
op = src->map->cop & ~COLOR_BLEND_FLAGS_MASK;
|
||||
}
|
||||
|
||||
if (op > PIXMAN_OP_HSL_LUMINOSITY || op < PIXMAN_OP_CLEAR) {
|
||||
msk_img = NULL;
|
||||
op = PIXMAN_OP_SRC;
|
||||
}
|
||||
|
||||
src_img = pixman_image_create_bits_no_clear ((pixman_format_code_t)src->tmp_data,
|
||||
src->w, src->h,
|
||||
(uint32_t *)((char*)src->pixels + src->pixels_off),
|
||||
src->pitch);
|
||||
if (src_img == NULL)
|
||||
goto out;
|
||||
|
||||
if (dst != src) {
|
||||
dst_img = pixman_image_create_bits_no_clear ((pixman_format_code_t)dst->tmp_data,
|
||||
dst->w, dst->h,
|
||||
(uint32_t *)((char*)dst->pixels + dst->pixels_off),
|
||||
dst->pitch);
|
||||
if (dst_img == NULL)
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
dst_img = src_img;
|
||||
}
|
||||
|
||||
_DBG_PRINTF ("srcrect: %d, %d, %dx%d; dstrect: %d, %d, %dx%d\n",
|
||||
srcrect->x, srcrect->y, srcrect->w, srcrect->h,
|
||||
dstrect->x, dstrect->y, dstrect->w, dstrect->h);
|
||||
|
||||
#if 0
|
||||
pixman_region32_t clip_region;
|
||||
pixman_region32_init_rect (&clip_region,
|
||||
dst->clip_rect.x, dst->clip_rect.y, dst->clip_rect.w, dst->clip_rect.h);
|
||||
pixman_image_set_clip_region32 (dst_img, &clip_region);
|
||||
#endif
|
||||
|
||||
retv = 0;
|
||||
pixman_image_composite32 (op, src_img, msk_img, dst_img,
|
||||
srcrect->x, srcrect->y,
|
||||
0, 0,
|
||||
@@ -507,17 +418,7 @@ static int GAL_PixmanBlit (struct GAL_Surface *src, GAL_Rect *srcrect,
|
||||
|
||||
//pixman_region32_fini (&clip_region);
|
||||
|
||||
out:
|
||||
if (msk_img)
|
||||
pixman_image_unref (msk_img);
|
||||
|
||||
if (src_img)
|
||||
pixman_image_unref (src_img);
|
||||
|
||||
if (dst_img != src_img && dst_img)
|
||||
pixman_image_unref (dst_img);
|
||||
|
||||
return retv;
|
||||
return 0;
|
||||
}
|
||||
#endif // _MGUSE_PIXMAN
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ typedef struct GAL_BlitMap {
|
||||
struct private_hwaccel *hw_data;
|
||||
struct private_swaccel *sw_data;
|
||||
|
||||
DWORD cop;
|
||||
int identity;
|
||||
/* the version count matches the destination; mismatch indicates
|
||||
an invalid mapping */
|
||||
|
||||
@@ -794,6 +794,10 @@ static GAL_Surface* create_surface_from_buffer (_THIS,
|
||||
surface->h = surface_buffer->height;
|
||||
surface->pitch = surface_buffer->pitch;
|
||||
surface->pixels_off = 0;
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
#if IS_COMPOSITING_SCHEMA
|
||||
surface->shared_header = NULL;
|
||||
surface->dirty_info = NULL;
|
||||
@@ -3289,8 +3293,12 @@ static BOOL DRM_SyncUpdate (_THIS)
|
||||
src_rect.h = RECTH (bound);
|
||||
dst_rect = src_rect;
|
||||
|
||||
GAL_SetupBlitting (this->hidden->shadow_screen,
|
||||
this->hidden->real_screen, 0);
|
||||
GAL_BlitSurface (this->hidden->shadow_screen, &src_rect,
|
||||
this->hidden->real_screen, &dst_rect);
|
||||
GAL_CleanupBlitting (this->hidden->shadow_screen,
|
||||
this->hidden->real_screen);
|
||||
#endif /* use blitting */
|
||||
}
|
||||
|
||||
@@ -3313,8 +3321,12 @@ static BOOL DRM_SyncUpdate (_THIS)
|
||||
dst_rect.y = eff_rc.top;
|
||||
dst_rect.w = src_rect.w;
|
||||
dst_rect.h = src_rect.h;
|
||||
GAL_SetupBlitting (this->hidden->cursor,
|
||||
this->hidden->real_screen, 0);
|
||||
GAL_BlitSurface (this->hidden->cursor, &src_rect,
|
||||
this->hidden->real_screen, &dst_rect);
|
||||
GAL_CleanupBlitting (this->hidden->cursor,
|
||||
this->hidden->real_screen);
|
||||
}
|
||||
}
|
||||
#endif /* _MGSCHEMA_COMPOSITING */
|
||||
|
||||
@@ -247,8 +247,12 @@ int shadowScreen_BlitToReal (_THIS)
|
||||
src_rect.h = RECTH (bound);
|
||||
dst_rect = src_rect;
|
||||
|
||||
GAL_SetupBlitting (this->hidden->shadow_screen,
|
||||
this->hidden->real_screen, 0);
|
||||
GAL_BlitSurface (this->hidden->shadow_screen, &src_rect,
|
||||
this->hidden->real_screen, &dst_rect);
|
||||
GAL_CleanupBlitting (this->hidden->shadow_screen,
|
||||
this->hidden->real_screen);
|
||||
#ifdef _MGSCHEMA_COMPOSITING
|
||||
if (this->hidden->cursor) {
|
||||
RECT csr_rc, eff_rc;
|
||||
@@ -267,8 +271,12 @@ int shadowScreen_BlitToReal (_THIS)
|
||||
dst_rect.y = eff_rc.top;
|
||||
dst_rect.w = src_rect.w;
|
||||
dst_rect.h = src_rect.h;
|
||||
GAL_SetupBlitting (this->hidden->cursor,
|
||||
this->hidden->real_screen, 0);
|
||||
GAL_BlitSurface (this->hidden->cursor, &src_rect,
|
||||
this->hidden->real_screen, &dst_rect);
|
||||
GAL_CleanupBlitting (this->hidden->cursor,
|
||||
this->hidden->real_screen);
|
||||
}
|
||||
}
|
||||
#endif /* _MGSCHEMA_COMPOSITING */
|
||||
|
||||
+106
-226
@@ -50,98 +50,6 @@
|
||||
#include "newgal.h"
|
||||
#include "blit.h"
|
||||
|
||||
/* This isn't ready for general consumption yet - it should be folded
|
||||
into the general blitting mechanism.
|
||||
*/
|
||||
|
||||
#if (defined(WIN32) && !defined(_M_ALPHA) && !defined(_WIN32_WCE)) || \
|
||||
defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)
|
||||
#define USE_ASM_STRETCH
|
||||
#endif
|
||||
|
||||
#ifdef USE_ASM_STRETCH
|
||||
|
||||
#if defined(WIN32) || defined(i386)
|
||||
#define PREFIX16 0x66
|
||||
#define STORE_BYTE 0xAA
|
||||
#define STORE_WORD 0xAB
|
||||
#define LOAD_BYTE 0xAC
|
||||
#define LOAD_WORD 0xAD
|
||||
#define RETURN 0xC3
|
||||
#else
|
||||
#error Need assembly opcodes for this architecture
|
||||
#endif
|
||||
|
||||
#if defined(__ELF__) && defined(__GNUC__)
|
||||
extern unsigned char _copy_row[4096] __attribute__ ((alias ("copy_row")));
|
||||
#endif
|
||||
static unsigned char copy_row[4096];
|
||||
|
||||
static int generate_rowbytes(int src_w, int dst_w, int bpp)
|
||||
{
|
||||
static struct {
|
||||
int bpp;
|
||||
int src_w;
|
||||
int dst_w;
|
||||
} last;
|
||||
|
||||
int i;
|
||||
int pos, inc;
|
||||
unsigned char *eip;
|
||||
unsigned char load, store;
|
||||
|
||||
/* See if we need to regenerate the copy buffer */
|
||||
if ( (src_w == last.src_w) &&
|
||||
(dst_w == last.src_w) && (bpp == last.bpp) ) {
|
||||
return(0);
|
||||
}
|
||||
last.bpp = bpp;
|
||||
last.src_w = src_w;
|
||||
last.dst_w = dst_w;
|
||||
|
||||
switch (bpp) {
|
||||
case 1:
|
||||
load = LOAD_BYTE;
|
||||
store = STORE_BYTE;
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
load = LOAD_WORD;
|
||||
store = STORE_WORD;
|
||||
break;
|
||||
default:
|
||||
GAL_SetError("NEWGAL: ASM stretch of %d bytes isn't supported.\n", bpp);
|
||||
return(-1);
|
||||
}
|
||||
pos = 0x10000;
|
||||
inc = (src_w << 16) / dst_w;
|
||||
eip = copy_row;
|
||||
for ( i=0; i<dst_w; ++i ) {
|
||||
while ( pos >= 0x10000L ) {
|
||||
if ( bpp == 2 ) {
|
||||
*eip++ = PREFIX16;
|
||||
}
|
||||
*eip++ = load;
|
||||
pos -= 0x10000L;
|
||||
}
|
||||
if ( bpp == 2 ) {
|
||||
*eip++ = PREFIX16;
|
||||
}
|
||||
*eip++ = store;
|
||||
pos += inc;
|
||||
}
|
||||
*eip++ = RETURN;
|
||||
|
||||
/* Verify that we didn't overflow (too late) */
|
||||
if ( eip > (copy_row+sizeof(copy_row)) ) {
|
||||
GAL_SetError("NEWGAL: Copy buffer overflow.\n");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define DEFINE_COPY_ROW(name, type) \
|
||||
static void name(type *src, int src_w, type *dst, int dst_w) \
|
||||
{ \
|
||||
@@ -165,8 +73,6 @@ DEFINE_COPY_ROW(copy_row1, Uint8)
|
||||
DEFINE_COPY_ROW(copy_row2, Uint16)
|
||||
DEFINE_COPY_ROW(copy_row4, Uint32)
|
||||
|
||||
#endif /* USE_ASM_STRETCH */
|
||||
|
||||
/* The ASM code doesn't handle 24-bpp stretch blits */
|
||||
static void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w)
|
||||
{
|
||||
@@ -203,9 +109,6 @@ static int GAL_SoftStretch(GAL_Surface *src, GAL_Rect *srcrect,
|
||||
Uint8 *dstp;
|
||||
GAL_Rect full_src;
|
||||
GAL_Rect full_dst;
|
||||
#if defined(USE_ASM_STRETCH) && defined(__GNUC__)
|
||||
int u1, u2;
|
||||
#endif
|
||||
const int bpp = dst->format->BytesPerPixel;
|
||||
|
||||
if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
|
||||
@@ -250,14 +153,6 @@ static int GAL_SoftStretch(GAL_Surface *src, GAL_Rect *srcrect,
|
||||
src_row = srcrect->y;
|
||||
dst_row = dstrect->y;
|
||||
|
||||
#ifdef USE_ASM_STRETCH
|
||||
/* Write the opcodes for this stretch */
|
||||
if ( (bpp != 3) &&
|
||||
(generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) {
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Perform the stretch blit */
|
||||
for ( dst_maxrow = dst_row+dstrect->h; dst_row<dst_maxrow; ++dst_row ) {
|
||||
dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch)
|
||||
@@ -268,40 +163,6 @@ static int GAL_SoftStretch(GAL_Surface *src, GAL_Rect *srcrect,
|
||||
++src_row;
|
||||
pos -= 0x10000L;
|
||||
}
|
||||
#ifdef USE_ASM_STRETCH
|
||||
switch (bpp) {
|
||||
case 3:
|
||||
copy_row3(srcp, srcrect->w, dstp, dstrect->w);
|
||||
break;
|
||||
default:
|
||||
#ifdef __GNUC__
|
||||
__asm__ __volatile__ (
|
||||
" call _copy_row "
|
||||
: "=&D" (u1), "=&S" (u2)
|
||||
: "0" (dstp), "1" (srcp)
|
||||
: "memory" );
|
||||
#else
|
||||
#ifdef WIN32
|
||||
{ void *code = ©_row;
|
||||
__asm {
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, dstp
|
||||
mov esi, srcp
|
||||
call dword ptr code
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
}
|
||||
}
|
||||
#else
|
||||
#error Need inline assembly for this compiler
|
||||
#endif
|
||||
#endif /* __GNUC__ */
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (bpp) {
|
||||
case 1:
|
||||
copy_row1(srcp, srcrect->w, dstp, dstrect->w);
|
||||
@@ -318,7 +179,6 @@ static int GAL_SoftStretch(GAL_Surface *src, GAL_Rect *srcrect,
|
||||
(Uint32 *)dstp, dstrect->w);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
pos += inc;
|
||||
}
|
||||
return(0);
|
||||
@@ -403,78 +263,55 @@ static int GAL_StretchBltLegacy (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
#include <pixman.h>
|
||||
#include <math.h>
|
||||
|
||||
int GAL_StretchBlt (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
int GAL_SetupStretchBlit (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
GAL_Surface *dst, GAL_Rect *dstrect,
|
||||
const STRETCH_EXTRA_INFO* sei, DWORD ops)
|
||||
const STRETCH_EXTRA_INFO *sei, DWORD ops)
|
||||
{
|
||||
pixman_image_t *src_img = NULL, *dst_img = NULL, *msk_img = NULL;
|
||||
pixman_op_t op;
|
||||
uint32_t alpha_bits;
|
||||
int retv = -1;
|
||||
DWORD cop = ops & ~COLOR_BLEND_FLAGS_MASK;
|
||||
DWORD filter = ops >> SCALING_FILTER_SHIFT;
|
||||
|
||||
if (!GAL_CheckPixmanFormat (src, dst) || (src->flags & GAL_SRCCOLORKEY))
|
||||
return GAL_StretchBltLegacy (src, srcrect, dst, dstrect, cop);
|
||||
|
||||
assert (src->tmp_data);
|
||||
assert (dst->tmp_data);
|
||||
|
||||
if ((src->flags & GAL_SRCALPHA) && src->format->alpha != GAL_ALPHA_OPAQUE) {
|
||||
memset (&alpha_bits, src->format->alpha, sizeof(alpha_bits));
|
||||
msk_img = pixman_image_create_bits_no_clear (PIXMAN_a8, 1, 1, &alpha_bits, 4);
|
||||
if (msk_img)
|
||||
pixman_image_set_repeat (msk_img, PIXMAN_REPEAT_NORMAL);
|
||||
}
|
||||
|
||||
if (cop == COLOR_BLEND_LEGACY) {
|
||||
if ((src->flags & GAL_SRCPIXELALPHA) && src->format->Amask && src != dst) {
|
||||
op = PIXMAN_OP_OVER;
|
||||
}
|
||||
else {
|
||||
op = PIXMAN_OP_SRC;
|
||||
}
|
||||
}
|
||||
else {
|
||||
op = cop & ~COLOR_BLEND_FLAGS_MASK;
|
||||
}
|
||||
|
||||
if (op > PIXMAN_OP_HSL_LUMINOSITY || op < PIXMAN_OP_CLEAR) {
|
||||
op = PIXMAN_OP_SRC;
|
||||
}
|
||||
|
||||
src_img = pixman_image_create_bits_no_clear ((pixman_format_code_t)src->tmp_data,
|
||||
src->w, src->h,
|
||||
(uint32_t *)((char*)src->pixels + src->pixels_off),
|
||||
src->pitch);
|
||||
if (src_img == NULL)
|
||||
goto out;
|
||||
|
||||
if (dst != src) {
|
||||
dst_img = pixman_image_create_bits_no_clear ((pixman_format_code_t)dst->tmp_data,
|
||||
dst->w, dst->h,
|
||||
(uint32_t *)((char*)dst->pixels + dst->pixels_off),
|
||||
dst->pitch);
|
||||
if (dst_img == NULL)
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
dst_img = src_img;
|
||||
}
|
||||
|
||||
{
|
||||
if (GAL_CheckPixmanFormats (src, dst)) {
|
||||
double fscale_x = srcrect->w * 1.0 / dstrect->w;
|
||||
double fscale_y = srcrect->h * 1.0 / dstrect->h;
|
||||
double rotation;
|
||||
pixman_f_transform_t ftransform;
|
||||
pixman_transform_t transform;
|
||||
pixman_region32_t clip_region;
|
||||
GAL_BlittingContext* ctxt;
|
||||
|
||||
_DBG_PRINTF ("srcrect: %d, %d, %dx%d; dstrect: %d, %d, %dx%d; scale: %f x %f; cliprect: %d, %d, %dx%d\n",
|
||||
srcrect->x, srcrect->y, srcrect->w, srcrect->h,
|
||||
dstrect->x, dstrect->y, dstrect->w, dstrect->h,
|
||||
1.0/fscale_x, 1.0/fscale_y,
|
||||
dst->clip_rect.x, dst->clip_rect.y, dst->clip_rect.w, dst->clip_rect.h);
|
||||
src->blit_ctxt = malloc (sizeof (GAL_BlittingContext));
|
||||
if (src->blit_ctxt == NULL)
|
||||
return -1;
|
||||
|
||||
ctxt = src->blit_ctxt;
|
||||
if ((src->flags & GAL_SRCALPHA) && src->format->alpha != GAL_ALPHA_OPAQUE) {
|
||||
memset (&ctxt->alpha_bits, src->format->alpha, sizeof(uint32_t));
|
||||
ctxt->msk_img = pixman_image_create_bits_no_clear (PIXMAN_a8, 1, 1,
|
||||
&ctxt->alpha_bits, 4);
|
||||
if (ctxt->msk_img)
|
||||
pixman_image_set_repeat (ctxt->msk_img, PIXMAN_REPEAT_NORMAL);
|
||||
}
|
||||
else
|
||||
ctxt->msk_img = NULL;
|
||||
|
||||
ctxt->filter = ops >> SCALING_FILTER_SHIFT;
|
||||
if (ctxt->filter > PIXMAN_FILTER_CONVOLUTION) {
|
||||
ctxt->filter = PIXMAN_FILTER_FAST;
|
||||
}
|
||||
|
||||
ops &= ~COLOR_BLEND_FLAGS_MASK;
|
||||
if (ops == COLOR_BLEND_LEGACY) {
|
||||
if ((src->flags & GAL_SRCPIXELALPHA) && src->format->Amask && src != dst) {
|
||||
ctxt->op = PIXMAN_OP_OVER;
|
||||
}
|
||||
else {
|
||||
ctxt->op = PIXMAN_OP_SRC;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ctxt->op = ops;
|
||||
}
|
||||
|
||||
if (ctxt->op > PIXMAN_OP_HSL_LUMINOSITY ||
|
||||
ctxt->op < PIXMAN_OP_CLEAR) {
|
||||
ctxt->op = PIXMAN_OP_SRC;
|
||||
}
|
||||
|
||||
pixman_f_transform_init_identity (&ftransform);
|
||||
if (sei && sei->rotation) {
|
||||
@@ -491,8 +328,9 @@ int GAL_StretchBlt (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
pixman_f_transform_translate (&ftransform, NULL, srcrect->x, srcrect->y);
|
||||
//pixman_f_transform_invert (&ftransform, &ftransform);
|
||||
pixman_transform_from_pixman_f_transform (&transform, &ftransform);
|
||||
pixman_image_set_transform (src_img, &transform);
|
||||
pixman_image_set_transform (src->pix_img, &transform);
|
||||
|
||||
#if 0
|
||||
fscale_x = hypot (ftransform.m[0][0], ftransform.m[0][1]) / ftransform.m[2][2];
|
||||
fscale_y = hypot (ftransform.m[1][0], ftransform.m[1][1]) / ftransform.m[2][2];
|
||||
if (filter > PIXMAN_FILTER_CONVOLUTION) {
|
||||
@@ -511,32 +349,74 @@ int GAL_StretchBlt (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
else {
|
||||
pixman_image_set_filter (src_img, (pixman_filter_t)filter, NULL, 0);
|
||||
}
|
||||
|
||||
pixman_region32_init_rect (&clip_region,
|
||||
dst->clip_rect.x, dst->clip_rect.y, dst->clip_rect.w, dst->clip_rect.h);
|
||||
pixman_image_set_clip_region32 (dst_img, &clip_region);
|
||||
|
||||
retv = 0;
|
||||
pixman_image_composite32 (op, src_img, msk_img, dst_img,
|
||||
dstrect->x, dstrect->y,
|
||||
0, 0,
|
||||
dstrect->x, dstrect->y,
|
||||
dstrect->w, dstrect->h);
|
||||
|
||||
pixman_region32_fini (&clip_region);
|
||||
#else
|
||||
pixman_image_set_filter (src->pix_img, (pixman_filter_t)ctxt->filter, NULL, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
out:
|
||||
if (msk_img)
|
||||
pixman_image_unref (msk_img);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src_img)
|
||||
pixman_image_unref (src_img);
|
||||
int GAL_CleanupStretchBlit (GAL_Surface *src, GAL_Surface *dst)
|
||||
{
|
||||
if (src->blit_ctxt) {
|
||||
pixman_transform_t transform;
|
||||
|
||||
if (dst_img != src_img && dst_img)
|
||||
pixman_image_unref (dst_img);
|
||||
GAL_BlittingContext* ctxt = src->blit_ctxt;
|
||||
if (ctxt->msk_img)
|
||||
pixman_image_unref (ctxt->msk_img);
|
||||
free (src->blit_ctxt);
|
||||
src->blit_ctxt = NULL;
|
||||
|
||||
return retv;
|
||||
pixman_transform_init_identity (&transform);
|
||||
pixman_image_set_transform (src->pix_img, &transform);
|
||||
pixman_image_set_filter (src->pix_img, PIXMAN_FILTER_FAST, NULL, 0);
|
||||
pixman_image_set_clip_region32 (dst->pix_img, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GAL_StretchBlt (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
GAL_Surface *dst, GAL_Rect *dstrect,
|
||||
const STRETCH_EXTRA_INFO* sei, DWORD ops)
|
||||
{
|
||||
pixman_image_t *src_img = src->pix_img, *dst_img = dst->pix_img;
|
||||
pixman_image_t *msk_img;
|
||||
pixman_op_t op;
|
||||
pixman_region32_t clip_region;
|
||||
|
||||
if (src_img == NULL || dst_img == NULL || (src->flags & GAL_SRCCOLORKEY))
|
||||
return GAL_StretchBltLegacy (src, srcrect, dst, dstrect,
|
||||
ops & ~COLOR_BLEND_FLAGS_MASK);
|
||||
|
||||
if (src->blit_ctxt) {
|
||||
GAL_BlittingContext* ctxt = src->blit_ctxt;
|
||||
msk_img = ctxt->msk_img;
|
||||
op = (pixman_op_t)ctxt->op;
|
||||
}
|
||||
else {
|
||||
msk_img = NULL;
|
||||
op = PIXMAN_OP_SRC;
|
||||
}
|
||||
|
||||
_DBG_PRINTF ("srcrect: %d,%d, %dx%d; dstrect: %d,%d, %dx%d; cliprect: %d,%d, %dx%d\n",
|
||||
srcrect->x, srcrect->y, srcrect->w, srcrect->h,
|
||||
dstrect->x, dstrect->y, dstrect->w, dstrect->h,
|
||||
dst->clip_rect.x, dst->clip_rect.y, dst->clip_rect.w, dst->clip_rect.h);
|
||||
|
||||
pixman_region32_init_rect (&clip_region,
|
||||
dst->clip_rect.x, dst->clip_rect.y, dst->clip_rect.w, dst->clip_rect.h);
|
||||
pixman_image_set_clip_region32 (dst_img, &clip_region);
|
||||
|
||||
pixman_image_composite32 (op, src_img, msk_img, dst_img,
|
||||
dstrect->x, dstrect->y,
|
||||
0, 0,
|
||||
dstrect->x, dstrect->y,
|
||||
dstrect->w, dstrect->h);
|
||||
|
||||
pixman_region32_fini (&clip_region);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* defined _MGUSE_PIXMAN */
|
||||
|
||||
@@ -103,6 +103,10 @@ GAL_Surface * GAL_CreateCursorSurface (GAL_VideoDevice *video,
|
||||
surface->hwdata = NULL;
|
||||
surface->map = NULL;
|
||||
surface->format_version = 0;
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
surface->shared_header = NULL;
|
||||
surface->dirty_info = NULL;
|
||||
GAL_SetClipRect (surface, NULL);
|
||||
|
||||
@@ -136,6 +136,10 @@ GAL_Surface * GAL_CreateSharedRGBSurface (GAL_VideoDevice *video,
|
||||
surface->hwdata = NULL;
|
||||
surface->map = NULL;
|
||||
surface->format_version = 0;
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
surface->shared_header = NULL;
|
||||
surface->dirty_info = NULL;
|
||||
GAL_SetClipRect (surface, NULL);
|
||||
@@ -272,6 +276,10 @@ error:
|
||||
surface->shared_header->map_size);
|
||||
}
|
||||
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
surface->shared_header = NULL;
|
||||
surface->dirty_info = NULL;
|
||||
}
|
||||
@@ -318,6 +326,10 @@ void GAL_FreeSharedSurfaceData (GAL_Surface *surface)
|
||||
}
|
||||
|
||||
surface->pixels = NULL;
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
surface->shared_header = NULL;
|
||||
surface->dirty_info = NULL;
|
||||
}
|
||||
@@ -358,7 +370,7 @@ GAL_Surface * GAL_AttachSharedRGBSurface (int fd, size_t map_size,
|
||||
}
|
||||
|
||||
surface->video = video;
|
||||
surface->flags = flags;
|
||||
surface->flags = flags & ~GAL_FORMAT_CHECKED;
|
||||
|
||||
surface->shared_header = NULL;
|
||||
surface->hwdata = NULL;
|
||||
@@ -410,6 +422,10 @@ GAL_Surface * GAL_AttachSharedRGBSurface (int fd, size_t map_size,
|
||||
surface->dpi = GDCAP_DPI_DEFAULT;
|
||||
surface->map = NULL;
|
||||
surface->format_version = 0;
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
GAL_SetClipRect (surface, NULL);
|
||||
|
||||
#ifdef _MGUSE_UPDATE_REGION
|
||||
@@ -463,6 +479,10 @@ void GAL_DettachSharedSurfaceData (GAL_Surface *surface)
|
||||
}
|
||||
|
||||
surface->pixels = NULL;
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
surface->shared_header = NULL;
|
||||
surface->dirty_info = NULL;
|
||||
}
|
||||
|
||||
+144
-23
@@ -142,6 +142,10 @@ GAL_Surface * GAL_CreateRGBSurface (Uint32 flags,
|
||||
surface->hwdata = NULL;
|
||||
surface->map = NULL;
|
||||
surface->format_version = 0;
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
#if IS_COMPOSITING_SCHEMA
|
||||
surface->shared_header = NULL;
|
||||
surface->dirty_info = NULL;
|
||||
@@ -506,8 +510,6 @@ int GAL_LowerBlit (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
GAL_blit do_blit;
|
||||
int ret;
|
||||
|
||||
src->map->cop = op;
|
||||
|
||||
/* Check to make sure the blit mapping is valid */
|
||||
if ((src->map->dst != dst) ||
|
||||
(src->map->dst->format_version != src->map->format_version)) {
|
||||
@@ -724,7 +726,128 @@ static void GAL_SoftFillRect (GAL_Surface *dst, const GAL_Rect *dstrect, Uint32
|
||||
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
#include <pixman.h>
|
||||
#endif
|
||||
|
||||
struct rgbamasks_pixman_format_map {
|
||||
uint32_t pixman_format;
|
||||
Uint32 Rmask, Gmask, Bmask, Amask;
|
||||
};
|
||||
|
||||
static struct rgbamasks_pixman_format_map _format_map_8bpp [] = {
|
||||
{ PIXMAN_r3g3b2, 0xE0, 0x1C, 0x03, 0x00 },
|
||||
{ PIXMAN_b2g3r3, 0x0E, 0x38, 0xC0, 0x00 },
|
||||
{ PIXMAN_a2r2g2b2, 0x30, 0x0C, 0x03, 0xC0 },
|
||||
{ PIXMAN_a2b2g2r2, 0x03, 0x0C, 0x03, 0xC0 },
|
||||
};
|
||||
|
||||
static struct rgbamasks_pixman_format_map _format_map_16bpp [] = {
|
||||
{ PIXMAN_x4r4g4b4, 0x0F00, 0x00F0, 0x000F, 0x0000 },
|
||||
{ PIXMAN_x4b4g4r4, 0x000F, 0x00F0, 0x0F00, 0x0000 },
|
||||
// { PIXMAN_r4g4b4x4, 0xF000, 0x0F00, 0x00F0, 0x0000 },
|
||||
// { PIXMAN_b4g4r4x4, 0x00F0, 0x0F00, 0xF000, 0x0000 },
|
||||
{ PIXMAN_a4r4g4b4, 0x0F00, 0x00F0, 0x000F, 0xF000 },
|
||||
{ PIXMAN_a4b4g4r4, 0x000F, 0x00F0, 0x0F00, 0xF000 },
|
||||
// { PIXMAN_r4g4b4a4, 0xF000, 0x0F00, 0x00F0, 0x000F },
|
||||
// { PIXMAN_b4g4r4a4, 0x00F0, 0x0F00, 0xF000, 0x000F },
|
||||
{ PIXMAN_x1r5g5b5, 0x7C00, 0x03E0, 0x001F, 0x0000 },
|
||||
{ PIXMAN_x1b5g5r5, 0x001F, 0x03E0, 0x7C00, 0x0000 },
|
||||
// { PIXMAN_r5g5b5x1, 0xF800, 0x07C0, 0x003E, 0x0000 },
|
||||
// { PIXMAN_b5g5r5x1, 0x003E, 0x07C0, 0xF800, 0x0000 },
|
||||
{ PIXMAN_a1r5g5b5, 0x7C00, 0x03E0, 0x001F, 0x8000 },
|
||||
{ PIXMAN_a1b5g5r5, 0x001F, 0x03E0, 0x7C00, 0x8000 },
|
||||
// { PIXMAN_r5g5b5a1, 0xF800, 0x07C0, 0x003E, 0x0001 },
|
||||
// { PIXMAN_b5g5r5a1, 0x003E, 0x07C0, 0xF800, 0x0001 },
|
||||
{ PIXMAN_r5g6b5, 0xF800, 0x07E0, 0x001F, 0x0000 },
|
||||
{ PIXMAN_b5g6r5, 0x001F, 0x07E0, 0xF800, 0x0000 },
|
||||
};
|
||||
|
||||
static struct rgbamasks_pixman_format_map _format_map_24bpp [] = {
|
||||
{ PIXMAN_r8g8b8, 0xFF0000, 0x00FF00, 0x0000FF, 0x000000 },
|
||||
{ PIXMAN_b8g8r8, 0x0000FF, 0x00FF00, 0xFF0000, 0x000000 },
|
||||
};
|
||||
|
||||
static struct rgbamasks_pixman_format_map _format_map_32bpp [] = {
|
||||
{ PIXMAN_x8r8g8b8, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
|
||||
{ PIXMAN_x8b8g8r8, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
|
||||
{ PIXMAN_r8g8b8x8, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 },
|
||||
{ PIXMAN_b8g8r8x8, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 },
|
||||
{ PIXMAN_a8r8g8b8, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 },
|
||||
{ PIXMAN_a8b8g8r8, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 },
|
||||
{ PIXMAN_r8g8b8a8, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF },
|
||||
{ PIXMAN_b8g8r8a8, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF },
|
||||
};
|
||||
|
||||
static uint32_t translate_gal_format(const GAL_PixelFormat *gal_format)
|
||||
{
|
||||
struct rgbamasks_pixman_format_map* map;
|
||||
size_t i, n;
|
||||
|
||||
// XXX: ignore format with palette
|
||||
if (gal_format->BitsPerPixel <= 8 && gal_format->palette)
|
||||
return 0;
|
||||
|
||||
switch (gal_format->BitsPerPixel) {
|
||||
case 8:
|
||||
map = _format_map_8bpp;
|
||||
n = TABLESIZE(_format_map_8bpp);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
map = _format_map_16bpp;
|
||||
n = TABLESIZE(_format_map_16bpp);
|
||||
break;
|
||||
|
||||
case 24:
|
||||
map = _format_map_24bpp;
|
||||
n = TABLESIZE(_format_map_24bpp);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
map = _format_map_32bpp;
|
||||
n = TABLESIZE(_format_map_32bpp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (gal_format->Rmask == map[i].Rmask &&
|
||||
gal_format->Gmask == map[i].Gmask &&
|
||||
gal_format->Bmask == map[i].Bmask &&
|
||||
gal_format->Amask == map[i].Amask) {
|
||||
return map[i].pixman_format;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL GAL_CreatePixmanImage (GAL_Surface *surface)
|
||||
{
|
||||
if (!(surface->flags & GAL_FORMAT_CHECKED)) {
|
||||
uint32_t pixman_format;
|
||||
|
||||
assert (surface->pix_img == NULL);
|
||||
|
||||
pixman_format = translate_gal_format (surface->format);
|
||||
|
||||
if (pixman_format) {
|
||||
surface->pix_img = pixman_image_create_bits_no_clear (
|
||||
(pixman_format_code_t)pixman_format,
|
||||
surface->w, surface->h,
|
||||
(uint32_t *)((char*)surface->pixels + surface->pixels_off),
|
||||
surface->pitch);
|
||||
}
|
||||
else
|
||||
surface->pix_img = NULL;
|
||||
|
||||
surface->flags |= GAL_FORMAT_CHECKED;
|
||||
}
|
||||
|
||||
return surface->pix_img != NULL;
|
||||
}
|
||||
|
||||
#endif /* defined _MGUSE_PIXMAN */
|
||||
|
||||
/*
|
||||
* This function performs a fast fill of the given rectangle with 'color'
|
||||
@@ -757,12 +880,10 @@ int GAL_FillRect(GAL_Surface *dst, const GAL_Rect *dstrect, Uint32 color)
|
||||
}
|
||||
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
if (GAL_CheckPixmanFormat (dst, NULL)) {
|
||||
Uint8 r, g, b, a;
|
||||
pixman_color_t pixman_color;
|
||||
if (GAL_CreatePixmanImage (dst)) {
|
||||
pixman_box32_t pixman_box;
|
||||
pixman_image_t *dst_img;
|
||||
int retv = -1;
|
||||
pixman_color_t pixman_color;
|
||||
Uint8 r, g, b, a;
|
||||
|
||||
GAL_GetRGBA (color, dst->format, &r, &g, &b, &a);
|
||||
pixman_color.red = (uint16_t)r << 8;
|
||||
@@ -775,21 +896,9 @@ int GAL_FillRect(GAL_Surface *dst, const GAL_Rect *dstrect, Uint32 color)
|
||||
pixman_box.x2 = my_dstrect.x + my_dstrect.w;
|
||||
pixman_box.y2 = my_dstrect.y + my_dstrect.h;
|
||||
|
||||
dst_img = pixman_image_create_bits_no_clear ((pixman_format_code_t)dst->tmp_data,
|
||||
dst->w, dst->h,
|
||||
(uint32_t *)((char*)dst->pixels + dst->pixels_off),
|
||||
dst->pitch);
|
||||
if (dst_img == NULL)
|
||||
goto out;
|
||||
|
||||
pixman_image_fill_boxes (PIXMAN_OP_SRC, dst_img, &pixman_color, 1, &pixman_box);
|
||||
retv = 0;
|
||||
|
||||
out:
|
||||
if (dst_img)
|
||||
pixman_image_unref (dst_img);
|
||||
|
||||
return retv;
|
||||
pixman_image_fill_boxes (PIXMAN_OP_SRC, dst->pix_img,
|
||||
&pixman_color, 1, &pixman_box);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
GAL_SoftFillRect (dst, &my_dstrect, color);
|
||||
@@ -1759,6 +1868,18 @@ void GAL_FreeSurface (GAL_Surface *surface)
|
||||
free (surface->pixels);
|
||||
}
|
||||
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
if (surface->pix_img) {
|
||||
pixman_image_unref (surface->pix_img);
|
||||
surface->pix_img = NULL;
|
||||
|
||||
}
|
||||
|
||||
if (surface->blit_ctxt) {
|
||||
_WRN_PRINTF ("There is not cleaned up blitting context: %p\n", surface->blit_ctxt);
|
||||
}
|
||||
#endif
|
||||
|
||||
free (surface);
|
||||
|
||||
#ifdef CHECK_LEAKS
|
||||
|
||||
@@ -1255,6 +1255,10 @@ static GAL_Surface *Slave_CreateSurface (GAL_VideoDevice *this,
|
||||
surface->hwdata = NULL;
|
||||
surface->map = NULL;
|
||||
surface->format_version = 0;
|
||||
#ifdef _MGUSE_PIXMAN
|
||||
surface->pix_img = NULL;
|
||||
surface->blit_ctxt = NULL;
|
||||
#endif
|
||||
#if IS_COMPOSITING_SCHEMA
|
||||
surface->shared_header = NULL;
|
||||
surface->dirty_info = NULL;
|
||||
|
||||
@@ -1158,6 +1158,7 @@ void GUIAPI BitBlt (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
* else should rc1 rc2 rc3 ..., rc4 rc5 rc6 ...
|
||||
*
|
||||
*/
|
||||
GAL_SetupBlitting (psdc->surface, pddc->surface, dwRop);
|
||||
if (pddc->surface == psdc->surface) {
|
||||
if (dy > sy) {
|
||||
cliprect = pddc->ecrgn.tail;
|
||||
@@ -1266,6 +1267,7 @@ void GUIAPI BitBlt (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
cliprect = cliprect->next;
|
||||
}
|
||||
}
|
||||
GAL_CleanupBlitting (psdc->surface, pddc->surface);
|
||||
|
||||
if (pddc->surface != psdc->surface && IS_SCREEN_SURFACE(psdc))
|
||||
kernel_ShowCursorForGDI (TRUE, psdc);
|
||||
@@ -1538,6 +1540,8 @@ BOOL GUIAPI StretchBltEx (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
|
||||
src.x = sx; src.y = sy; src.w = sw; src.h = sh;
|
||||
dst.x = dx; dst.y = dy; dst.w = dw; dst.h = dh;
|
||||
|
||||
GAL_SetupStretchBlit (psdc->surface, &src, pddc->surface, &dst, sei, dwRop);
|
||||
cliprect = pddc->ecrgn.head;
|
||||
while(cliprect) {
|
||||
if (IntersectRect (&eff_rc, &pddc->rc_output, &cliprect->rc)) {
|
||||
@@ -1548,6 +1552,7 @@ BOOL GUIAPI StretchBltEx (HDC hsdc, int sx, int sy, int sw, int sh,
|
||||
|
||||
cliprect = cliprect->next;
|
||||
}
|
||||
GAL_CleanupStretchBlit (psdc->surface, pddc->surface);
|
||||
|
||||
if (pddc->surface != psdc->surface && IS_SCREEN_SURFACE (psdc))
|
||||
kernel_ShowCursorForGDI (TRUE, psdc);
|
||||
|
||||
Reference in New Issue
Block a user