* applications from drawing to the screen while we've locked the frontbuffer.
* We'd like to do this in wined3d instead, but for that to work wined3d needs
* to support windowless rendering first. */
-HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read)
+HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
+ const RECT *rect, BOOL read, unsigned int swap_interval)
{
- struct ddraw *ddraw = surface->ddraw;
+ struct wined3d_texture *dst_texture;
HDC surface_dc, screen_dc;
int x, y, w, h;
HRESULT hr;
BOOL ret;
RECT r;
+ if (surface->ddraw->flags & DDRAW_SWAPPED && !read)
+ {
+ surface->ddraw->flags &= ~DDRAW_SWAPPED;
+ rect = NULL;
+ }
+
if (!rect)
{
SetRect(&r, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
if (w <= 0 || h <= 0)
return DD_OK;
- if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP))
+ if (surface->ddraw->swapchain_window && !(surface->ddraw->flags & DDRAW_GDI_FLIP))
{
/* Nothing to do, we control the frontbuffer, or at least the parts we
* care about. */
if (read)
return DD_OK;
- return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect,
- surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT);
+ if (swap_interval)
+ dst_texture = wined3d_swapchain_get_back_buffer(surface->ddraw->wined3d_swapchain, 0);
+ else
+ dst_texture = surface->ddraw->wined3d_frontbuffer;
+
+ if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture,
+ surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval)
+ {
+ hr = wined3d_swapchain_present(surface->ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0);
+ surface->ddraw->flags |= DDRAW_SWAPPED;
+ }
+ return hr;
}
if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc)))
palette_impl->flags |= DDPCAPS_PRIMARYSURFACE;
wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain,
palette_impl ? palette_impl->wined3d_palette : NULL);
- ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
+ ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
}
if (palette_impl)
IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface);
}
if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE);
+ hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0);
if (SUCCEEDED(hr))
hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture),
surface->sub_resource_idx, &map_desc, rect ? &box : NULL,
wined3d_mutex_lock();
hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx);
if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE);
+ hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE, 0);
wined3d_mutex_unlock();
return hr;
return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL);
}
+static unsigned int ddraw_swap_interval_from_flags(DWORD flags)
+{
+ if (flags & DDFLIP_NOVSYNC)
+ return 0;
+
+ switch (flags & (DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4))
+ {
+ case DDFLIP_INTERVAL2:
+ return 2;
+ case DDFLIP_INTERVAL3:
+ return 3;
+ case DDFLIP_INTERVAL4:
+ return 4;
+ default:
+ return 1;
+ }
+}
+
static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 *iface,
IDirectDrawSurface7 *src, DWORD flags)
{
wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture);
src_impl->wined3d_texture = texture;
- if (flags)
+ if (flags & ~(DDFLIP_NOVSYNC | DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4))
{
static UINT once;
if (!once++)
}
if (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE);
+ hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE, ddraw_swap_interval_from_flags(flags));
else
hr = DD_OK;
if (!dst_surface->clipper)
{
if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE);
+ hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0);
if (SUCCEEDED(hr))
hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fill_colour, fx, filter);
if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
- hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE);
+ hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0);
return hr;
}
if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
- if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE)))
+ if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE, 0)))
break;
}
}
if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
- if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE)))
+ if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE, 0)))
break;
}
}
if (surface->dc)
hr = DDERR_DCALREADYCREATED;
else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE);
+ hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0);
if (SUCCEEDED(hr))
hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, dc);
{
surface->dc = NULL;
if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
+ hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
}
wined3d_mutex_unlock();
}
if (src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE);
+ hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0);
if (SUCCEEDED(hr))
hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect,
src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT);
if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
- hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE);
+ hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0);
wined3d_mutex_unlock();
switch(hr)