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;
struct {
HWND window;
int depth;
int rotation;
HWND window;
int depth;
int rotation;
unsigned int fullscreen : 1;
} info;
};

View File

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

View File

@ -24,7 +24,8 @@ _output_setup(int width,
int height,
int rot,
HWND window,
int depth)
int depth,
int fullscreen)
{
Render_Engine *re;
@ -51,7 +52,7 @@ _output_setup(int width,
re->ob = evas_software_ddraw_outbuf_setup(width, height, rot,
OUTBUF_DEPTH_INHERIT,
window, depth);
window, depth, fullscreen);
if (!re->ob)
{
free(re);
@ -59,7 +60,7 @@ _output_setup(int width,
}
/* 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,
* as well as shaped stuff is broken and probable non-32bpp is broken as
* convert funcs dont do the right thing
@ -116,7 +117,8 @@ eng_setup(Evas *e, void *in)
e->output.h,
info->info.rotation,
info->info.window,
info->info.depth);
info->info.depth,
info->info.fullscreen);
else
{
int ponebuf = 0;
@ -129,7 +131,8 @@ eng_setup(Evas *e, void *in)
info->info.rotation,
OUTBUF_DEPTH_INHERIT,
info->info.window,
info->info.depth);
info->info.depth,
info->info.fullscreen);
re->ob->onebuf = ponebuf;
}
if (!e->engine.data.output) return;

View File

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

View File

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