add fullscreen support in software directdraw engine (win xp)

SVN revision: 37887
This commit is contained in:
Vincent Torri 2008-12-01 20:38:05 +00:00
parent 9cf7c7c3a3
commit 6a06a92ac8
5 changed files with 124 additions and 63 deletions

View File

@ -16,9 +16,10 @@ struct _Evas_Engine_Info_Software_DDraw
Evas_Engine_Info magic; Evas_Engine_Info magic;
struct { struct {
HWND window; HWND window;
int depth; int depth;
int rotation; int rotation;
unsigned int fullscreen : 1;
} info; } info;
}; };

View File

@ -4,12 +4,11 @@
int int
evas_software_ddraw_init (HWND window, evas_software_ddraw_init (HWND window,
int depth, int depth,
int fullscreen,
Outbuf *buf) Outbuf *buf)
{ {
DDSURFACEDESC surface_desc; DDSURFACEDESC surface_desc;
DDPIXELFORMAT pixel_format; DDPIXELFORMAT pixel_format;
RECT rect;
LPDIRECTDRAW o;
HRESULT res; HRESULT res;
int width; int width;
int height; int height;
@ -17,62 +16,109 @@ evas_software_ddraw_init (HWND window,
if (!buf) if (!buf)
return 0; return 0;
if (!GetClientRect(window, &rect))
return 0;
width = rect.right - rect.left;
height = rect.bottom - rect.top;
buf->priv.dd.window = window; buf->priv.dd.window = window;
res = DirectDrawCreate(NULL, &buf->priv.dd.object, NULL); res = DirectDrawCreate(NULL, &buf->priv.dd.object, NULL);
if (FAILED(res)) if (FAILED(res))
return 0; return 0;
res = buf->priv.dd.object->SetCooperativeLevel(window, DDSCL_NORMAL); if (buf->priv.dd.fullscreen)
if (FAILED(res)) {
goto release_object; DDSCAPS caps;
res = buf->priv.dd.object->CreateClipper (0, &buf->priv.dd.clipper, NULL); res = buf->priv.dd.object->SetCooperativeLevel(window,
if (FAILED(res)) DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
goto release_object; if (FAILED(res))
goto release_object;
res = buf->priv.dd.clipper->SetHWnd (0, window); width = GetSystemMetrics(SM_CXSCREEN);
if (FAILED(res)) height = GetSystemMetrics(SM_CYSCREEN);
goto release_clipper;
memset(&surface_desc, 0, sizeof(surface_desc)); ZeroMemory(&pixel_format, sizeof(pixel_format));
surface_desc.dwSize = sizeof(surface_desc); pixel_format.dwSize = sizeof(pixel_format);
surface_desc.dwFlags = DDSD_CAPS; buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
res = buf->priv.dd.object->CreateSurface (&surface_desc, &buf->priv.dd.surface_primary, NULL); if (pixel_format.dwRGBBitCount != depth)
if (FAILED(res)) goto release_object;
goto release_clipper;
res = buf->priv.dd.surface_primary->SetClipper (buf->priv.dd.clipper); buf->priv.dd.depth = depth;
if (FAILED(res))
goto release_surface_primary;
memset (&surface_desc, 0, sizeof(surface_desc)); res = buf->priv.dd.object->SetDisplayMode(width, height, depth);
surface_desc.dwSize = sizeof(surface_desc); if (FAILED(res))
surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; goto release_object;
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
surface_desc.dwWidth = width;
surface_desc.dwHeight = height;
res = buf->priv.dd.object->CreateSurface (&surface_desc, &buf->priv.dd.surface_back, NULL); memset(&surface_desc, 0, sizeof(surface_desc));
if (FAILED(res)) surface_desc.dwSize = sizeof(surface_desc);
goto release_surface_primary; surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
surface_desc.dwBackBufferCount = 1;
ZeroMemory(&pixel_format, sizeof(pixel_format)); res = buf->priv.dd.object->CreateSurface(&surface_desc,
pixel_format.dwSize = sizeof(pixel_format); &buf->priv.dd.surface_primary, NULL);
buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format); if (FAILED(res))
goto release_object;
if (pixel_format.dwRGBBitCount != depth) caps.dwCaps = DDSCAPS_BACKBUFFER;
goto release_surface_back; res = buf->priv.dd.surface_primary->GetAttachedSurface(&caps,
&buf->priv.dd.surface_back);
if (FAILED(res))
goto release_surface_primary;
}
else
{
RECT rect;
buf->priv.dd.depth = depth; if (!GetClientRect(window, &rect))
goto release_object;
width = rect.right - rect.left;
height = rect.bottom - rect.top;
res = buf->priv.dd.object->SetCooperativeLevel(window, DDSCL_NORMAL);
if (FAILED(res))
goto release_object;
res = buf->priv.dd.object->CreateClipper(0, &buf->priv.dd.clipper, NULL);
if (FAILED(res))
goto release_object;
res = buf->priv.dd.clipper->SetHWnd(0, window);
if (FAILED(res))
goto release_clipper;
memset(&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS;
surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_primary, NULL);
if (FAILED(res))
goto release_clipper;
res = buf->priv.dd.surface_primary->SetClipper(buf->priv.dd.clipper);
if (FAILED(res))
goto release_surface_primary;
memset (&surface_desc, 0, sizeof(surface_desc));
surface_desc.dwSize = sizeof(surface_desc);
surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
surface_desc.dwWidth = width;
surface_desc.dwHeight = height;
res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_back, NULL);
if (FAILED(res))
goto release_surface_primary;
ZeroMemory(&pixel_format, sizeof(pixel_format));
pixel_format.dwSize = sizeof(pixel_format);
buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);
if (pixel_format.dwRGBBitCount != depth)
goto release_surface_back;
buf->priv.dd.depth = depth;
}
return 1; return 1;
@ -81,7 +127,8 @@ evas_software_ddraw_init (HWND window,
release_surface_primary: release_surface_primary:
buf->priv.dd.surface_primary->Release(); buf->priv.dd.surface_primary->Release();
release_clipper: release_clipper:
buf->priv.dd.clipper->Release(); if (buf->priv.dd.fullscreen)
buf->priv.dd.clipper->Release();
release_object: release_object:
buf->priv.dd.object->Release(); buf->priv.dd.object->Release();
@ -94,10 +141,16 @@ evas_software_ddraw_shutdown(Outbuf *buf)
if (!buf) if (!buf)
return; return;
buf->priv.dd.surface_back->Release(); if (buf->priv.dd.fullscreen)
buf->priv.dd.surface_primary->Release(); if (buf->priv.dd.surface_back)
buf->priv.dd.clipper->Release(); buf->priv.dd.surface_back->Release();
buf->priv.dd.object->Release(); if (buf->priv.dd.surface_primary)
buf->priv.dd.surface_primary->Release();
if (buf->priv.dd.fullscreen)
if (buf->priv.dd.clipper)
buf->priv.dd.clipper->Release();
if (buf->priv.dd.object)
buf->priv.dd.object->Release();
} }
int int

View File

@ -24,7 +24,8 @@ _output_setup(int width,
int height, int height,
int rot, int rot,
HWND window, HWND window,
int depth) int depth,
int fullscreen)
{ {
Render_Engine *re; Render_Engine *re;
@ -51,7 +52,7 @@ _output_setup(int width,
re->ob = evas_software_ddraw_outbuf_setup(width, height, rot, re->ob = evas_software_ddraw_outbuf_setup(width, height, rot,
OUTBUF_DEPTH_INHERIT, OUTBUF_DEPTH_INHERIT,
window, depth); window, depth, fullscreen);
if (!re->ob) if (!re->ob)
{ {
free(re); free(re);
@ -59,7 +60,7 @@ _output_setup(int width,
} }
/* for updates return 1 big buffer, but only use portions of it, also cache /* for updates return 1 big buffer, but only use portions of it, also cache
it and keepit around until an idle_flush */ it and keep it around until an idle_flush */
/* disable for now - i am hunting down why some expedite tests are slower, /* disable for now - i am hunting down why some expedite tests are slower,
* as well as shaped stuff is broken and probable non-32bpp is broken as * as well as shaped stuff is broken and probable non-32bpp is broken as
* convert funcs dont do the right thing * convert funcs dont do the right thing
@ -116,7 +117,8 @@ eng_setup(Evas *e, void *in)
e->output.h, e->output.h,
info->info.rotation, info->info.rotation,
info->info.window, info->info.window,
info->info.depth); info->info.depth,
info->info.fullscreen);
else else
{ {
int ponebuf = 0; int ponebuf = 0;
@ -129,7 +131,8 @@ eng_setup(Evas *e, void *in)
info->info.rotation, info->info.rotation,
OUTBUF_DEPTH_INHERIT, OUTBUF_DEPTH_INHERIT,
info->info.window, info->info.window,
info->info.depth); info->info.depth,
info->info.fullscreen);
re->ob->onebuf = ponebuf; re->ob->onebuf = ponebuf;
} }
if (!e->engine.data.output) return; if (!e->engine.data.output) return;

View File

@ -42,8 +42,9 @@ struct _Outbuf
LPDIRECTDRAWSURFACE surface_back; LPDIRECTDRAWSURFACE surface_back;
LPDIRECTDRAWCLIPPER clipper; LPDIRECTDRAWCLIPPER clipper;
int depth; int depth;
unsigned char swap : 1; unsigned char fullscreen : 1;
unsigned char bit_swap : 1; unsigned char swap : 1;
unsigned char bit_swap : 1;
} dd; } dd;
struct { struct {
DATA32 r, g, b; DATA32 r, g, b;
@ -58,10 +59,10 @@ struct _Outbuf
/* a list of previous frame pending regions to write to the target */ /* a list of previous frame pending regions to write to the target */
Eina_List *prev_pending_writes; Eina_List *prev_pending_writes;
unsigned char mask_dither : 1; unsigned char mask_dither : 1;
unsigned char destination_alpha : 1; unsigned char destination_alpha : 1;
unsigned char debug : 1; unsigned char debug : 1;
unsigned char synced : 1; unsigned char synced : 1;
} priv; } priv;
}; };
@ -97,7 +98,8 @@ Outbuf *evas_software_ddraw_outbuf_setup(int width,
int rotation, int rotation,
Outbuf_Depth depth, Outbuf_Depth depth,
HWND window, HWND window,
int w_depth); int w_depth,
int fullscreen);
void evas_software_ddraw_outbuf_reconfigure(Outbuf *buf, void evas_software_ddraw_outbuf_reconfigure(Outbuf *buf,
int width, int width,
@ -168,6 +170,7 @@ extern "C" {
int evas_software_ddraw_init (HWND window, int evas_software_ddraw_init (HWND window,
int depth, int depth,
int fullscreen,
Outbuf *buf); Outbuf *buf);
void evas_software_ddraw_shutdown(Outbuf *buf); void evas_software_ddraw_shutdown(Outbuf *buf);

View File

@ -103,7 +103,8 @@ evas_software_ddraw_outbuf_setup(int width,
int rotation, int rotation,
Outbuf_Depth depth, Outbuf_Depth depth,
HWND window, HWND window,
int w_depth) int w_depth,
int fullscreen)
{ {
Outbuf *buf; Outbuf *buf;
@ -116,7 +117,7 @@ evas_software_ddraw_outbuf_setup(int width,
buf->depth = depth; buf->depth = depth;
buf->rot = rotation; buf->rot = rotation;
if (!evas_software_ddraw_init(window, w_depth, buf)) if (!evas_software_ddraw_init(window, w_depth, fullscreen, buf))
{ {
free(buf); free(buf);
return NULL; return NULL;