[PATCH 3/4] wined3d: Use surface_blt_to_drawable() in IWineD3DSurfaceImpl_BltOverride().
Henri Verbeet
hverbeet at codeweavers.com
Thu Oct 21 05:40:45 CDT 2010
---
dlls/wined3d/surface.c | 190 ++++++++++++++++++++++-------------------------
1 files changed, 89 insertions(+), 101 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index a1587b0..b24a6de 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3344,6 +3344,89 @@ static void surface_blt_fbo(IWineD3DDeviceImpl *device, const WINED3DTEXTUREFILT
context_release(context);
}
+static void surface_blt_to_drawable(IWineD3DDeviceImpl *device,
+ WINED3DTEXTUREFILTERTYPE filter, BOOL color_key,
+ IWineD3DSurfaceImpl *src_surface, const RECT *src_rect_in,
+ IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in)
+{
+ IWineD3DSwapChainImpl *swapchain = NULL;
+ struct wined3d_context *context;
+ RECT src_rect, dst_rect;
+
+ src_rect = *src_rect_in;
+ dst_rect = *dst_rect_in;
+
+ if (dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
+ swapchain = dst_surface->container.u.swapchain;
+
+ /* Make sure the surface is up-to-date. This should probably use
+ * surface_load_location() and worry about the destination surface too,
+ * unless we're overwriting it completely. */
+ surface_internal_preload(src_surface, SRGB_RGB);
+
+ /* Activate the destination context, set it up for blitting */
+ context = context_acquire(device, dst_surface);
+ context_apply_blit_state(context, device);
+
+ /* context_apply_blit_state() sets up a flipped (in GL terms) projection
+ * matrix. As a result, we need to skip the flip for onscreen surfaces,
+ * and have to flip for offscreen surfaces instead, to undo the flip done
+ * by the projection matrix. */
+ if (swapchain && dst_surface == swapchain->front_buffer)
+ {
+ surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect);
+ }
+ else if (surface_is_offscreen(dst_surface))
+ {
+ dst_rect.top = dst_surface->currentDesc.Height - dst_rect.top;
+ dst_rect.bottom = dst_surface->currentDesc.Height - dst_rect.bottom;
+ }
+
+ device->blitter->set_shader((IWineD3DDevice *)device, src_surface);
+
+ ENTER_GL();
+
+ if (color_key)
+ {
+ glEnable(GL_ALPHA_TEST);
+ checkGLcall("glEnable(GL_ALPHA_TEST)");
+
+ /* When the primary render target uses P8, the alpha component
+ * contains the palette index. Which means that the colorkey is one of
+ * the palette entries. In other cases pixels that should be masked
+ * away have alpha set to 0. */
+ if (primary_render_target_is_p8(device))
+ glAlphaFunc(GL_NOTEQUAL, (float)src_surface->SrcBltCKey.dwColorSpaceLowValue / 256.0f);
+ else
+ glAlphaFunc(GL_NOTEQUAL, 0.0f);
+ checkGLcall("glAlphaFunc");
+ }
+ else
+ {
+ glDisable(GL_ALPHA_TEST);
+ checkGLcall("glDisable(GL_ALPHA_TEST)");
+ }
+
+ draw_textured_quad(src_surface, &src_rect, &dst_rect, filter);
+
+ if (color_key)
+ {
+ glDisable(GL_ALPHA_TEST);
+ checkGLcall("glDisable(GL_ALPHA_TEST)");
+ }
+
+ LEAVE_GL();
+
+ /* Leave the opengl state valid for blitting */
+ device->blitter->unset_shader((IWineD3DDevice *)device);
+
+ if (wined3d_settings.strict_draw_ordering || (swapchain
+ && (dst_surface == swapchain->front_buffer || swapchain->num_contexts > 1)))
+ wglFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
+}
+
/* Do not call while under the GL lock. */
HRESULT surface_color_fill(IWineD3DSurfaceImpl *s, const RECT *rect, const WINED3DCOLORVALUE *color)
{
@@ -3611,7 +3694,6 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
/* Blit from offscreen surface to render target */
DWORD oldCKeyFlags = src_surface->CKeyFlags;
WINEDDCOLORKEY oldBltCKey = src_surface->SrcBltCKey;
- struct wined3d_context *context;
TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface);
@@ -3668,72 +3750,13 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
src_surface->CKeyFlags &= ~WINEDDSD_CKSRCBLT;
}
- /* Now load the surface */
- surface_internal_preload(src_surface, SRGB_RGB);
-
- /* Activate the destination context, set it up for blitting */
- context = context_acquire(device, dst_surface);
- context_apply_blit_state(context, device);
-
- if (dstSwapchain && dst_surface == dstSwapchain->front_buffer)
- surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect);
- else if (surface_is_offscreen(dst_surface))
- {
- dst_rect.top = dst_surface->currentDesc.Height - dst_rect.top;
- dst_rect.bottom = dst_surface->currentDesc.Height - dst_rect.bottom;
- }
-
- device->blitter->set_shader((IWineD3DDevice *)device, src_surface);
-
- ENTER_GL();
-
- /* This is for color keying */
- if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
- glEnable(GL_ALPHA_TEST);
- checkGLcall("glEnable(GL_ALPHA_TEST)");
-
- /* When the primary render target uses P8, the alpha component contains the palette index.
- * Which means that the colorkey is one of the palette entries. In other cases pixels that
- * should be masked away have alpha set to 0. */
- if (primary_render_target_is_p8(device))
- glAlphaFunc(GL_NOTEQUAL, (float)src_surface->SrcBltCKey.dwColorSpaceLowValue / 256.0f);
- else
- glAlphaFunc(GL_NOTEQUAL, 0.0f);
- checkGLcall("glAlphaFunc");
- } else {
- glDisable(GL_ALPHA_TEST);
- checkGLcall("glDisable(GL_ALPHA_TEST)");
- }
-
- /* Draw a textured quad
- */
- draw_textured_quad(src_surface, &src_rect, &dst_rect, Filter);
-
- if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
- glDisable(GL_ALPHA_TEST);
- checkGLcall("glDisable(GL_ALPHA_TEST)");
- }
+ surface_blt_to_drawable(device, Filter, Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE),
+ src_surface, &src_rect, dst_surface, &dst_rect);
/* Restore the color key parameters */
src_surface->CKeyFlags = oldCKeyFlags;
src_surface->SrcBltCKey = oldBltCKey;
- LEAVE_GL();
-
- /* Leave the opengl state valid for blitting */
- device->blitter->unset_shader((IWineD3DDevice *)device);
-
- if (wined3d_settings.strict_draw_ordering || (dstSwapchain
- && (dst_surface == dstSwapchain->front_buffer
- || dstSwapchain->num_contexts > 1)))
- wglFlush(); /* Flush to ensure ordering across contexts. */
-
- context_release(context);
-
- /* TODO: If the surface is locked often, perform the Blt in software on the memory instead */
- /* The surface is now in the drawable. On onscreen surfaces or without fbos the texture
- * is outdated now
- */
surface_modify_location(dst_surface, SFLAG_INDRAWABLE, TRUE);
return WINED3D_OK;
@@ -4325,44 +4348,6 @@ void surface_modify_location(IWineD3DSurfaceImpl *surface, DWORD flag, BOOL pers
}
}
-static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in)
-{
- IWineD3DDeviceImpl *device = This->resource.device;
- IWineD3DSwapChainImpl *swapchain;
- struct wined3d_context *context;
- RECT src_rect, dst_rect;
-
- surface_get_rect(This, rect_in, &src_rect);
-
- context = context_acquire(device, This);
- context_apply_blit_state(context, device);
-
- dst_rect = src_rect;
- if (context->render_offscreen)
- {
- dst_rect.top = This->currentDesc.Height - dst_rect.top;
- dst_rect.bottom = This->currentDesc.Height - dst_rect.bottom;
- }
-
- swapchain = This->container.type == WINED3D_CONTAINER_SWAPCHAIN ? This->container.u.swapchain : NULL;
- if (swapchain && This == swapchain->front_buffer)
- surface_translate_frontbuffer_coords(This, context->win_handle, &dst_rect);
-
- device->blitter->set_shader((IWineD3DDevice *) device, This);
-
- ENTER_GL();
- draw_textured_quad(This, &src_rect, &dst_rect, WINED3DTEXF_POINT);
- LEAVE_GL();
-
- device->blitter->unset_shader((IWineD3DDevice *) device);
-
- if (wined3d_settings.strict_draw_ordering || (swapchain
- && (This == swapchain->front_buffer || swapchain->num_contexts > 1)))
- wglFlush(); /* Flush to ensure ordering across contexts. */
-
- context_release(context);
-}
-
HRESULT surface_load_location(IWineD3DSurfaceImpl *surface, DWORD flag, const RECT *rect)
{
IWineD3DDeviceImpl *device = surface->resource.device;
@@ -4448,7 +4433,10 @@ HRESULT surface_load_location(IWineD3DSurfaceImpl *surface, DWORD flag, const RE
{
if (surface->Flags & SFLAG_INTEXTURE)
{
- surface_blt_to_drawable(surface, rect);
+ RECT r;
+
+ surface_get_rect(surface, rect, &r);
+ surface_blt_to_drawable(device, WINED3DTEXF_POINT, FALSE, surface, &r, surface, &r);
}
else
{
--
1.7.2.2
More information about the wine-patches
mailing list