Stefan Dösinger : wined3d: A function for checking if a surface is offscreen.
Alexandre Julliard
julliard at winehq.org
Mon Dec 7 10:26:18 CST 2009
Module: wine
Branch: master
Commit: 64291c60cb1f73ea16f12c464bec5c014de3320c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=64291c60cb1f73ea16f12c464bec5c014de3320c
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Sun Dec 6 15:45:46 2009 +0100
wined3d: A function for checking if a surface is offscreen.
---
dlls/wined3d/device.c | 8 +++---
dlls/wined3d/surface.c | 58 ++++++++++++++++++++++++----------------
dlls/wined3d/wined3d_private.h | 1 +
3 files changed, 40 insertions(+), 27 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 6ac60f1..12003d6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5676,7 +5676,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
IWineD3DSwapChain *swapchain;
swapchain = get_swapchain(surface);
- if (swapchain) {
+ if (!surface_is_offscreen(surface)) {
GLenum buffer;
TRACE("Surface %p is onscreen\n", surface);
@@ -5699,7 +5699,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
if (rect) {
glEnable(GL_SCISSOR_TEST);
- if(!swapchain) {
+ if(surface_is_offscreen(surface)) {
glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1);
} else {
glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2,
@@ -6088,7 +6088,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
gl_info = context->gl_info;
- if (src_swapchain) {
+ if (!surface_is_offscreen(src_surface)) {
GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain);
TRACE("Source surface %p is onscreen\n", src_surface);
@@ -6126,7 +6126,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
LEAVE_GL();
/* Attach dst surface to dst fbo */
- if (dst_swapchain) {
+ if (!surface_is_offscreen(dst_surface)) {
GLenum buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
TRACE("Destination surface %p is onscreen\n", dst_surface);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 1463dd4..7c4551b 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -923,7 +923,6 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
/* Read the framebuffer back into the surface */
static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, void *dest, UINT pitch) {
- IWineD3DSwapChainImpl *swapchain;
IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
struct wined3d_context *context;
BYTE *mem;
@@ -959,16 +958,8 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
* There is no need to keep track of the current read buffer or reset it, every part of the code
* that reads sets the read buffer as desired.
*/
- if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&swapchain)))
+ if (surface_is_offscreen((IWineD3DSurface *) This))
{
- GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *)swapchain);
- TRACE("Locking %#x buffer\n", buffer);
- glReadBuffer(buffer);
- checkGLcall("glReadBuffer");
-
- IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
- srcIsUpsideDown = FALSE;
- } else {
/* Locking the primary render target which is not on a swapchain(=offscreen render target).
* Read from the back buffer
*/
@@ -976,6 +967,15 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
glReadBuffer(myDevice->offscreenBuffer);
srcIsUpsideDown = TRUE;
}
+ else
+ {
+ /* Onscreen surfaces are always part of a swapchain */
+ GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *) This->container);
+ TRACE("Locking %#x buffer\n", buffer);
+ glReadBuffer(buffer);
+ checkGLcall("glReadBuffer");
+ srcIsUpsideDown = FALSE;
+ }
/* TODO: Get rid of the extra rectangle comparison and construction of a full surface rectangle */
if(!rect) {
@@ -1770,7 +1770,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
*internal = glDesc->glGammaInternal;
}
else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET
- && !(This->Flags & SFLAG_SWAPCHAIN))
+ && surface_is_offscreen((IWineD3DSurface *) This))
{
*internal = glDesc->rtInternal;
} else {
@@ -3102,7 +3102,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
/* Bind the target texture */
glBindTexture(This->texture_target, This->texture_name);
checkGLcall("glBindTexture");
- if(!swapchain) {
+ if(surface_is_offscreen(SrcSurface)) {
TRACE("Reading from an offscreen target\n");
upsidedown = !upsidedown;
glReadBuffer(myDevice->offscreenBuffer);
@@ -3241,12 +3241,12 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
Src->Flags &= ~SFLAG_INTEXTURE;
}
- if(swapchain) {
- glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain));
- } else {
+ if(surface_is_offscreen(SrcSurface)) {
TRACE("Reading from an offscreen target\n");
upsidedown = !upsidedown;
glReadBuffer(myDevice->offscreenBuffer);
+ } else {
+ glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain));
}
/* TODO: Only back up the part that will be overwritten */
@@ -4562,13 +4562,15 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW
persistent ? "TRUE" : "FALSE");
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
- if (This->Flags & SFLAG_SWAPCHAIN)
+ if (surface_is_offscreen(iface))
{
- TRACE("Surface %p is an onscreen surface\n", iface);
- } else {
/* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */
if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
}
+ else
+ {
+ TRACE("Surface %p is an onscreen surface\n", iface);
+ }
}
if(persistent) {
@@ -4829,16 +4831,20 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
int width, pitch, outpitch;
BYTE *mem;
BOOL drawable_read_ok = TRUE;
+ BOOL in_fbo = FALSE;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
- if (This->Flags & SFLAG_SWAPCHAIN)
+ if (surface_is_offscreen(iface))
{
- TRACE("Surface %p is an onscreen surface\n", iface);
- } else {
/* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets.
* Prefer SFLAG_INTEXTURE. */
if (flag == SFLAG_INDRAWABLE) flag = SFLAG_INTEXTURE;
drawable_read_ok = FALSE;
+ in_fbo = TRUE;
+ }
+ else
+ {
+ TRACE("Surface %p is an onscreen surface\n", iface);
}
}
@@ -5063,8 +5069,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
This->Flags |= flag;
}
- if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !(This->Flags & SFLAG_SWAPCHAIN)
- && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) {
+ if (in_fbo && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) {
/* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */
This->Flags |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
}
@@ -5121,6 +5126,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) {
return hr;
}
+BOOL surface_is_offscreen(IWineD3DSurface *iface)
+{
+ IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
+
+ return !(This->Flags & SFLAG_SWAPCHAIN);
+}
+
const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
{
/* IUnknown */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index bd8e58f..4fb556c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1727,6 +1727,7 @@ typedef struct IWineD3DBaseTextureClass
void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN;
BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
+BOOL surface_is_offscreen(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
typedef struct IWineD3DBaseTextureImpl
{
More information about the wine-cvs
mailing list