Module: wine Branch: master Commit: 76a971277976cc65826d7b05c2ed161eb0cd46c8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=76a971277976cc65826d7b05c2...
Author: Roderick Colenbrander thunderbird2k@gmail.com Date: Thu Apr 8 22:49:51 2010 +0200
wined3d: Add an initial implementation of arbfp_blit_surface.
---
dlls/wined3d/arb_program_shader.c | 55 +++++++++++++++++++++++++++++++++++++ dlls/wined3d/surface.c | 16 ++++++++++- dlls/wined3d/wined3d_private.h | 7 +++++ 3 files changed, 77 insertions(+), 1 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 086bdb3..44c4ab0 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -6895,6 +6895,61 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, enum bli } }
+HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op, + DWORD Filter) +{ + struct wined3d_context *context; + IWineD3DSwapChainImpl *dst_swapchain = NULL; + RECT dst_rect = *dst_rect_in; + + /* Now load the surface */ + surface_internal_preload((IWineD3DSurface *)src_surface, SRGB_RGB); + + /* Activate the destination context, set it up for blitting */ + context = context_acquire(device, (IWineD3DSurface *)dst_surface, CTXUSAGE_BLIT); + + /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates', + * while OpenGL coordinates are window relative. + * Also beware of the origin difference(top left vs bottom left). + * Also beware that the front buffer's surface size is screen width x screen height, + * whereas the real gl drawable size is the size of the window. + */ + IWineD3DSurface_GetContainer((IWineD3DSurface *)dst_surface, &IID_IWineD3DSwapChain, (void **)&dst_swapchain); + if (dst_swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)dst_swapchain); + if (dst_swapchain && (IWineD3DSurface *)dst_surface == dst_swapchain->frontBuffer) + { + RECT windowsize; + POINT offset = {0,0}; + UINT h; + ClientToScreen(context->win_handle, &offset); + GetClientRect(context->win_handle, &windowsize); + h = windowsize.bottom - windowsize.top; + dst_rect.left -= offset.x; dst_rect.right -=offset.x; + dst_rect.top -= offset.y; dst_rect.bottom -=offset.y; + dst_rect.top += dst_surface->currentDesc.Height - h; dst_rect.bottom += dst_surface->currentDesc.Height - h; + } + + arbfp_blit_set((IWineD3DDevice *)device, src_surface); + + ENTER_GL(); + + /* Draw a textured quad */ + draw_textured_quad(src_surface, src_rect, &dst_rect, Filter); + + LEAVE_GL(); + + /* Leave the opengl state valid for blitting */ + arbfp_blit_unset((IWineD3DDevice *)device); + + wglFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); + + IWineD3DSurface_ModifyLocation((IWineD3DSurface *)dst_surface, SFLAG_INDRAWABLE, TRUE); + return WINED3D_OK; +} + static HRESULT arbfp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) { FIXME("Color filling not implemented by arbfp_blit\n"); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index ddbdcfd..1a9b6b0 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -287,7 +287,7 @@ static inline void surface_get_rect(IWineD3DSurfaceImpl *This, const RECT *rect_ }
/* GL locking and context activation is done by the caller */ -static void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter) +void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter) { IWineD3DBaseTextureImpl *texture; struct blt_info info; @@ -3859,6 +3859,20 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const return WINED3D_OK; }
+ if (!(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) + && arbfp_blit.blit_supported(&myDevice->adapter->gl_info, BLIT_OP_BLIT, + &src_rect, Src->resource.usage, Src->resource.pool, Src->resource.format_desc, + &dst_rect, This->resource.usage, This->resource.pool, This->resource.format_desc)) + { + HRESULT hr = arbfp_blit_surface(myDevice, Src, &src_rect, This, &dst_rect, BLIT_OP_BLIT, Filter); + + /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */ + if(paletteOverride) + Src->palette = NULL; + + return hr; + } + /* Color keying: Check if we have to do a color keyed blt, * and if not check if a color key is activated. * diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c574b9e..09e1b81 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1190,6 +1190,11 @@ extern const struct blit_shader ffp_blit DECLSPEC_HIDDEN; extern const struct blit_shader arbfp_blit DECLSPEC_HIDDEN; extern const struct blit_shader cpu_blit DECLSPEC_HIDDEN;
+/* Temporary blit_shader helper functions */ +HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op, + DWORD Filter) DECLSPEC_HIDDEN; + typedef enum ContextUsage { CTXUSAGE_RESOURCELOAD = 1, /* Only loads textures: No State is applied */ CTXUSAGE_DRAWPRIM = 2, /* OpenGL states are set up for blitting DirectDraw surfaces */ @@ -2160,6 +2165,8 @@ void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, U void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN; void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
+void draw_textured_quad(IWineD3DSurfaceImpl *src_surface, const RECT *src_rect, + const RECT *dst_rect, WINED3DTEXTUREFILTERTYPE Filter) DECLSPEC_HIDDEN; void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) DECLSPEC_HIDDEN;
/* Surface flags: */