resize the directdraw surface when the evas is resized. move directdraw code to its own file

SVN revision: 31653
This commit is contained in:
doursse 2007-09-08 10:42:30 +00:00 committed by doursse
parent d6510b0c39
commit 59f024a008
4 changed files with 165 additions and 95 deletions

View File

@ -42,32 +42,36 @@ evas_software_ddraw_output_buffer_free(DDraw_Output_Buffer *ddob)
void void
evas_software_ddraw_output_buffer_paste(DDraw_Output_Buffer *ddob, evas_software_ddraw_output_buffer_paste(DDraw_Output_Buffer *ddob,
DDSURFACEDESC2 *surface_desc, void *ddraw_data,
int x, int ddraw_width,
int y) int ddraw_height,
int ddraw_pitch,
int ddraw_depth,
int x,
int y)
{ {
DATA8 *dd_data; DATA8 *dd_data;
DATA8 *evas_data; DATA8 *evas_data;
int width; int width;
int height; int height;
int pitch; int pitch;
int j; int j;
if ((x >= surface_desc->dwWidth) || (y >= surface_desc->dwHeight)) if ((x >= ddraw_width) || (y >= ddraw_height))
return; return;
/* compute the size of the data to copy on the back surface */ /* compute the size of the data to copy on the back surface */
width = ((x + ddob->width) > surface_desc->dwWidth) width = ((x + ddob->width) > ddraw_width)
? surface_desc->dwWidth - x ? ddraw_width - x
: ddob->width; : ddob->width;
height = ((y + ddob->height) > surface_desc->dwHeight) height = ((y + ddob->height) > ddraw_height)
? surface_desc->dwHeight - y ? ddraw_height - y
: ddob->height; : ddob->height;
pitch = width * ddob->depth / 8; pitch = width * ddob->depth / 8;
dd_data = (DATA8 *)surface_desc->lpSurface + y * surface_desc->lPitch + x * surface_desc->ddpfPixelFormat.dwRGBBitCount / 8; dd_data = (DATA8 *)ddraw_data + y * ddraw_pitch + x * ddraw_depth;
evas_data = (unsigned char *)ddob->image; evas_data = (unsigned char *)ddob->image;
for (j = 0; j < height; j++, evas_data += ddob->pitch, dd_data += surface_desc->lPitch) for (j = 0; j < height; j++, evas_data += ddob->pitch, dd_data += ddraw_pitch)
memcpy(dd_data, evas_data, pitch); memcpy(dd_data, evas_data, pitch);
} }

View File

@ -1,5 +1,96 @@
#include "evas_engine.h"
int
evas_software_ddraw_masks_get(Outbuf *buf)
{
DDPIXELFORMAT pixel_format;
ZeroMemory(&pixel_format, sizeof(pixel_format));
pixel_format.dwSize = sizeof(pixel_format);
if (FAILED(IDirectDrawSurface7_GetPixelFormat(buf->priv.dd.surface_primary,
&pixel_format)))
return 0;
buf->priv.mask.r = pixel_format.dwRBitMask;
buf->priv.mask.g = pixel_format.dwGBitMask;
buf->priv.mask.b = pixel_format.dwBBitMask;
return 1;
}
void *
evas_software_ddraw_lock(Outbuf *buf, int *ddraw_width, int *ddraw_height, int *ddraw_pitch, int *ddraw_depth)
{
DDSURFACEDESC2 surface_desc;
ZeroMemory(&surface_desc, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
if (FAILED(IDirectDrawSurface7_Lock(buf->priv.dd.surface_back, NULL,
&surface_desc,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL)))
return NULL;
*ddraw_width = surface_desc.dwWidth;
*ddraw_height = surface_desc.dwHeight;
*ddraw_pitch = surface_desc.lPitch;
*ddraw_depth = surface_desc.ddpfPixelFormat.dwRGBBitCount >> 3;
return surface_desc.lpSurface;
}
void void
evas_software_ddraw_init(void) evas_software_ddraw_unlock_and_flip(Outbuf *buf)
{ {
RECT dst_rect;
RECT src_rect;
POINT p;
if (FAILED(IDirectDrawSurface7_Unlock(buf->priv.dd.surface_back, NULL)))
return;
/* we figure out where on the primary surface our window lives */
p.x = 0;
p.y = 0;
ClientToScreen(buf->priv.dd.window, &p);
GetClientRect(buf->priv.dd.window, &dst_rect);
OffsetRect(&dst_rect, p.x, p.y);
SetRect(&src_rect, 0, 0, buf->width, buf->height);
/* nothing to do if the function fails, so we don't check the result */
IDirectDrawSurface7_Blt(buf->priv.dd.surface_primary, &dst_rect,
buf->priv.dd.surface_back, &src_rect,
DDBLT_WAIT, NULL);
}
void
evas_software_ddraw_surface_resize(Outbuf *buf)
{
DDSURFACEDESC2 surface_desc;
DDSURFACEDESC2 *sd;
IDirectDrawSurface7_Release(buf->priv.dd.surface_back);
memset (&surface_desc, 0, sizeof (surface_desc));
surface_desc.dwSize = sizeof (surface_desc);
/* FIXME: that code does not compile. Must know why */
#if 0
surface_desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
surface_desc.dwWidth = width;
surface_desc.dwHeight = height;
IDirectDrawSurface7_SetSurfaceDesc(buf->priv.dd.surface_back, &surface_desc, NULL);
#else
surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
surface_desc.dwWidth = buf->width;
surface_desc.dwHeight = buf->height;
/* Hack to cleanly remove a warning */
sd = &surface_desc;
IDirectDraw7_CreateSurface(buf->priv.dd.object,
(DDSURFACEDESC *)sd,
&buf->priv.dd.surface_back,
NULL);
#endif
} }

View File

@ -109,12 +109,21 @@ DDraw_Output_Buffer *evas_software_ddraw_output_buffer_new(int depth,
void *data); void *data);
void evas_software_ddraw_output_buffer_free(DDraw_Output_Buffer *ddob); void evas_software_ddraw_output_buffer_free(DDraw_Output_Buffer *ddob);
void evas_software_ddraw_output_buffer_paste(DDraw_Output_Buffer *ddob, void evas_software_ddraw_output_buffer_paste(DDraw_Output_Buffer *ddob,
DDSURFACEDESC2 *surface_desc, void *ddraw_data,
int ddraw_width,
int ddraw_height,
int ddraw_pitch,
int ddraw_depth,
int x, int x,
int y); int y);
DATA8 *evas_software_ddraw_output_buffer_data(DDraw_Output_Buffer *ddob, DATA8 *evas_software_ddraw_output_buffer_data(DDraw_Output_Buffer *ddob,
int *bytes_per_line_ret); int *bytes_per_line_ret);
int evas_software_ddraw_output_buffer_depth(DDraw_Output_Buffer *ddob); int evas_software_ddraw_output_buffer_depth(DDraw_Output_Buffer *ddob);
int evas_software_ddraw_masks_get(Outbuf *buf);
void *evas_software_ddraw_lock(Outbuf *buf, int *ddraw_width, int *ddraw_height, int *ddraw_pitch, int *ddraw_depth);
void evas_software_ddraw_unlock_and_flip(Outbuf *buf);
void evas_software_ddraw_surface_resize(Outbuf *buf);
#endif /* __EVAS_ENGINE_H__ */ #endif /* __EVAS_ENGINE_H__ */

View File

@ -1,34 +1,6 @@
#include "evas_engine.h" #include "evas_engine.h"
static void
_ddraw_surface_flip(HWND window,
LPDIRECTDRAWSURFACE surface_primary,
LPDIRECTDRAWSURFACE surface_back,
int width,
int height)
{
HRESULT res;
RECT dst_rect;
RECT src_rect;
POINT p;
/* we figure out where on the primary surface our window lives */
p.x = 0;
p.y = 0;
ClientToScreen (window, &p);
GetClientRect (window, &dst_rect);
OffsetRect (&dst_rect, p.x, p.y);
SetRect (&src_rect, 0, 0, width, height);
res = IDirectDrawSurface7_Blt (surface_primary, &dst_rect,
surface_back, &src_rect,
DDBLT_WAIT, NULL);
if (FAILED(res))
{
}
}
void void
evas_software_ddraw_outbuf_init(void) evas_software_ddraw_outbuf_init(void)
{ {
@ -77,35 +49,29 @@ evas_software_ddraw_outbuf_setup_dd(int width,
conv_func = NULL; conv_func = NULL;
if (ddob) if (ddob)
{ {
DDPIXELFORMAT pixel_format; if (evas_software_ddraw_masks_get(buf))
{
ZeroMemory(&pixel_format, sizeof(pixel_format)); if ((rotation == 0) || (rotation == 180))
pixel_format.dwSize = sizeof(pixel_format); conv_func = evas_common_convert_func_get(0,
IDirectDrawSurface7_GetPixelFormat(surface_primary, &pixel_format); width,
buf->priv.mask.r = pixel_format.dwRBitMask; height,
buf->priv.mask.g = pixel_format.dwGBitMask; evas_software_ddraw_output_buffer_depth (ddob),
buf->priv.mask.b = pixel_format.dwBBitMask; buf->priv.mask.r,
buf->priv.mask.g,
if ((rotation == 0) || (rotation == 180)) buf->priv.mask.b,
conv_func = evas_common_convert_func_get(0, PAL_MODE_NONE,
width, rotation);
height, else if ((rotation == 90) || (rotation == 270))
evas_software_ddraw_output_buffer_depth (ddob), conv_func = evas_common_convert_func_get(0,
buf->priv.mask.r, height,
buf->priv.mask.g, width,
buf->priv.mask.b, evas_software_ddraw_output_buffer_depth (ddob),
PAL_MODE_NONE, buf->priv.mask.r,
rotation); buf->priv.mask.g,
else if ((rotation == 90) || (rotation == 270)) buf->priv.mask.b,
conv_func = evas_common_convert_func_get(0, PAL_MODE_NONE,
height, rotation);
width, }
evas_software_ddraw_output_buffer_depth (ddob),
buf->priv.mask.r,
buf->priv.mask.g,
buf->priv.mask.b,
PAL_MODE_NONE,
rotation);
evas_software_ddraw_output_buffer_free(ddob); evas_software_ddraw_output_buffer_free(ddob);
if (!conv_func) if (!conv_func)
{ {
@ -198,17 +164,20 @@ evas_software_ddraw_outbuf_free_region_for_update(Outbuf *buf,
void void
evas_software_ddraw_outbuf_flush(Outbuf *buf) evas_software_ddraw_outbuf_flush(Outbuf *buf)
{ {
DDSURFACEDESC2 surface_desc; Evas_List *l;
HRESULT res; void *ddraw_data;
Evas_List *l; int ddraw_width;
int ddraw_height;
ZeroMemory(&surface_desc, sizeof(surface_desc)); int ddraw_pitch;
surface_desc.dwSize = sizeof(surface_desc); int ddraw_depth;
/* lock the back surface */ /* lock the back surface */
res = IDirectDrawSurface7_Lock (buf->priv.dd.surface_back, NULL, &surface_desc, if (!(ddraw_data = evas_software_ddraw_lock(buf,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); &ddraw_width,
if (FAILED(res)) goto free_images; &ddraw_height,
&ddraw_pitch,
&ddraw_depth)))
goto free_images;
/* copy safely the images that need to be drawn onto the back surface */ /* copy safely the images that need to be drawn onto the back surface */
for (l = buf->priv.pending_writes; l; l = l->next) for (l = buf->priv.pending_writes; l; l = l->next)
@ -220,21 +189,17 @@ evas_software_ddraw_outbuf_flush(Outbuf *buf)
ddob = im->extended_info; ddob = im->extended_info;
/* paste now */ /* paste now */
evas_software_ddraw_output_buffer_paste(ddob, evas_software_ddraw_output_buffer_paste(ddob,
&surface_desc, ddraw_data,
ddraw_width,
ddraw_height,
ddraw_pitch,
ddraw_depth,
ddob->x, ddob->x,
ddob->y); ddob->y);
} }
/* unlock the back surface */ /* unlock the back surface and flip the surface */
res = IDirectDrawSurface7_Unlock (buf->priv.dd.surface_back, NULL); evas_software_ddraw_unlock_and_flip(buf);
if (FAILED(res)) goto free_images;
/* flip the surfaces */
_ddraw_surface_flip(buf->priv.dd.window,
buf->priv.dd.surface_primary,
buf->priv.dd.surface_back,
buf->width,
buf->height);
free_images: free_images:
while (buf->priv.pending_writes) while (buf->priv.pending_writes)
@ -346,6 +311,7 @@ evas_software_ddraw_outbuf_reconfigure(Outbuf *buf,
buf->width = width; buf->width = width;
buf->height = height; buf->height = height;
buf->rot = rotation; buf->rot = rotation;
evas_software_ddraw_surface_resize(buf);
} }
int int