Module: wine
Branch: master
Commit: 0b3d880c8e912391563ccda2e961cc3fdd7ac751
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0b3d880c8e912391563ccda2e…
Author: Roderick Colenbrander <thunderbird2k(a)gmx.net>
Date: Thu Feb 21 21:58:53 2008 +0100
wined3d: Use the color key in glAlphaFunc in case of index_in_alpha.
---
dlls/wined3d/surface.c | 23 +++++++++++++++--------
1 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 2d42679..58540d9 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2048,14 +2048,14 @@ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4]
table[i][1] = pal->palents[i].peGreen;
table[i][2] = pal->palents[i].peBlue;
- /* BltOverride uses a GL_ALPHA_TEST based on GL_NOT_EQUAL 0, so the alpha component
- of pixels that should be masked away should be 0. When inde_in_alpha is set,
- we will store the palette index (the glReadPixels code reads GL_ALPHA back)
- or else we store 0xff. */
- if(colorkey && (i >= This->SrcBltCKey.dwColorSpaceLowValue) && (i <= This->SrcBltCKey.dwColorSpaceHighValue)) {
- table[i][3] = 0x00;
- } else if(index_in_alpha) {
+ /* When index_in_alpha is the palette index is stored in the alpha component. In case of a readback
+ we can then read GL_ALPHA. Color keying is handled in BltOverride using a GL_ALPHA_TEST using GL_NOT_EQUAL.
+ In case of index_in_alpha the color key itself is passed to glAlphaFunc in other cases the alpha component
+ of pixels that should be masked away is set to 0. */
+ if(index_in_alpha) {
table[i][3] = i;
+ } else if(colorkey && (i >= This->SrcBltCKey.dwColorSpaceLowValue) && (i <= This->SrcBltCKey.dwColorSpaceHighValue)) {
+ table[i][3] = 0x00;
} else if(pal->Flags & WINEDDPCAPS_ALPHA) {
table[i][3] = pal->palents[i].peFlags;
} else {
@@ -3270,7 +3270,14 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
glEnable(GL_ALPHA_TEST);
checkGLcall("glEnable GL_ALPHA_TEST");
- glAlphaFunc(GL_NOTEQUAL, 0.0);
+
+ /* 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(myDevice))
+ glAlphaFunc(GL_NOTEQUAL, (float)This->SrcBltCKey.dwColorSpaceLowValue / 256.0);
+ else
+ glAlphaFunc(GL_NOTEQUAL, 0.0);
checkGLcall("glAlphaFunc\n");
} else {
glDisable(GL_ALPHA_TEST);
Module: wine
Branch: master
Commit: 0cdccfc8b5179294e02d62f2db3b02988ecd68ed
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0cdccfc8b5179294e02d62f2d…
Author: Roderick Colenbrander <thunderbird2k(a)gmx.net>
Date: Thu Feb 21 21:41:20 2008 +0100
wined3d: Unify p8 render target detection code.
---
dlls/wined3d/surface.c | 27 +++++++++++++--------------
1 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index e56b928..2d42679 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -56,6 +56,17 @@ static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This) {
IWineD3DSurface_BindTexture((IWineD3DSurface *)This);
}
+/* This function checks if the primary render target uses the 8bit paletted format. */
+static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
+{
+ if (device->render_targets && device->render_targets[0]) {
+ IWineD3DSurfaceImpl* render_target = (IWineD3DSurfaceImpl*)device->render_targets[0];
+ if((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET) && (render_target->resource.format == WINED3DFMT_P8))
+ return TRUE;
+ }
+ return FALSE;
+}
+
/* This call just downloads data, the caller is responsible for activating the
* right context and binding the correct texture. */
static void surface_download_data(IWineD3DSurfaceImpl *This) {
@@ -1441,7 +1452,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & WINEDDSD_CKSRCBLT);
const GlPixelFormatDesc *glDesc;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
- BOOL p8_render_target = FALSE;
getFormatDescEntry(This->resource.format, &GLINFO_LOCATION, &glDesc);
/* Default values: From the surface */
@@ -1465,12 +1475,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
Paletted Texture
**************** */
- if (device->render_targets && device->render_targets[0]) {
- IWineD3DSurfaceImpl* render_target = (IWineD3DSurfaceImpl*)device->render_targets[0];
- if((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET) && (render_target->resource.format == WINED3DFMT_P8))
- p8_render_target = TRUE;
- }
-
/* Use conversion when the paletted texture extension OR fragment shaders are available. When either
* of the two is available make sure texturing is requested as neither of the two works in
* conjunction with calls like glDraw-/glReadPixels. Further also use conversion in case of color keying.
@@ -1478,7 +1482,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
* in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which
* conflicts with this.
*/
- if( !(GL_SUPPORT(EXT_PALETTED_TEXTURE) || (GL_SUPPORT(ARB_FRAGMENT_PROGRAM) && p8_render_target)) || colorkey_active || !use_texturing ) {
+ if( !(GL_SUPPORT(EXT_PALETTED_TEXTURE) || (GL_SUPPORT(ARB_FRAGMENT_PROGRAM) && primary_render_target_is_p8(device))) || colorkey_active || !use_texturing ) {
*format = GL_RGBA;
*internal = GL_RGBA;
*type = GL_UNSIGNED_BYTE;
@@ -2016,12 +2020,7 @@ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4]
* is slow. Further RGB->P8 conversion is not possible because palettes can have
* duplicate entries. Store the color key in the unused alpha component to speed the
* download up and to make conversion unneeded. */
- if (device->render_targets && device->render_targets[0]) {
- IWineD3DSurfaceImpl* render_target = (IWineD3DSurfaceImpl*)device->render_targets[0];
-
- if((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET) && (render_target->resource.format == WINED3DFMT_P8))
- index_in_alpha = TRUE;
- }
+ index_in_alpha = primary_render_target_is_p8(device);
if (pal == NULL) {
/* In DirectDraw the palette is a property of the surface, there are no such things as device palettes. */
Module: wine
Branch: master
Commit: a5444cb897bb250d28e4fb83323e0bcf6fa01d23
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a5444cb897bb250d28e4fb833…
Author: Roderick Colenbrander <thunderbird2k(a)gmx.net>
Date: Thu Feb 21 18:36:50 2008 +0100
wined3d: In DirectDraw a palette is a property of a surface while in d3d8/9 it is a property of a device.
---
dlls/wined3d/surface.c | 44 +++++++++++++++++++++++++-------------------
1 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index c74c80f..e56b928 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2024,31 +2024,22 @@ static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4]
}
if (pal == NULL) {
+ /* In DirectDraw the palette is a property of the surface, there are no such things as device palettes. */
+ if(dxVersion <= 7) {
+ ERR("This code should never get entered for DirectDraw!, expect problems\n");
+ return;
+ }
+
/* Still no palette? Use the device's palette */
/* can ddraw and d3d < 8 surfaces use device's palette (d3d >= 8 feature)? */
for (i = 0; i < 256; i++) {
table[i][0] = device->palettes[device->currentPalette][i].peRed;
table[i][1] = device->palettes[device->currentPalette][i].peGreen;
table[i][2] = device->palettes[device->currentPalette][i].peBlue;
-
- if(dxVersion >= 8) {
- /* Direct3D >= 8 palette usage style: P8 textures use device palettes, palette entry format is A8R8G8B8,
- alpha is stored in peFlags and may be used by the app if D3DPTEXTURECAPS_ALPHAPALETTE device
- capability flag is present (wine does advertise this capability) */
- table[i][3] = device->palettes[device->currentPalette][i].peFlags;
- } else {
- /* BltOverride uses a GL_ALPHA_TEST based on GL_NOT_EQUAL 0, so the alpha component
- of pixels that should be masked away should be 0. When inde_in_alpha is set,
- we will store the palette index (the glReadPixels code reads GL_ALPHA back)
- or else we store 0xff. */
- if(colorkey && (i >= This->SrcBltCKey.dwColorSpaceLowValue) && (i <= This->SrcBltCKey.dwColorSpaceHighValue)) {
- table[i][3] = 0;
- } else if(index_in_alpha) {
- table[i][3] = i;
- } else {
- table[i][3] = 0xFF;
- }
- }
+ /* Direct3D >= 8 palette usage style: P8 textures use device palettes, palette entry format is A8R8G8B8,
+ alpha is stored in peFlags and may be used by the app if D3DPTEXTURECAPS_ALPHAPALETTE device
+ capability flag is present (wine does advertise this capability) */
+ table[i][3] = device->palettes[device->currentPalette][i].peFlags;
}
} else {
TRACE("Using surface palette %p\n", pal);
@@ -3176,6 +3167,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
DWORD oldCKeyFlags = Src->CKeyFlags;
WINEDDCOLORKEY oldBltCKey = This->SrcBltCKey;
RECT SourceRectangle;
+ BOOL paletteOverride = FALSE;
TRACE("Blt from surface %p to rendertarget %p\n", Src, This);
@@ -3227,6 +3219,16 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
Src->CKeyFlags &= ~WINEDDSD_CKSRCBLT;
}
+ /* When blitting from an offscreen surface to a rendertarget, the source
+ * surface is not required to have a palette. Our rendering / conversion
+ * code further down the road retrieves the palette from the surface, so
+ * it must have a palette set. */
+ if((Src->resource.format == WINED3DFMT_P8) && (Src->palette == NULL)) {
+ paletteOverride = TRUE;
+ TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This);
+ Src->palette = This->palette;
+ }
+
/* Now load the surface */
IWineD3DSurface_PreLoad((IWineD3DSurface *) Src);
@@ -3327,6 +3329,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
Src->CKeyFlags = oldCKeyFlags;
This->SrcBltCKey = oldBltCKey;
+ /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
+ if(paletteOverride)
+ Src->palette = NULL;
+
LEAVE_GL();
/* TODO: If the surface is locked often, perform the Blt in software on the memory instead */
Module: wine
Branch: master
Commit: 98a0786096711d33d4ac1bce650dd4edb9f09f79
URL: http://source.winehq.org/git/wine.git/?a=commit;h=98a0786096711d33d4ac1bce6…
Author: Roderick Colenbrander <thunderbird2k(a)gmx.net>
Date: Thu Feb 21 18:21:34 2008 +0100
wined3d: Don't flush in D3D RealizePalette without a palette.
---
dlls/wined3d/surface.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index f1217d9..c74c80f 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3581,9 +3581,10 @@ HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) {
SetDIBColorTable(This->hDC, 0, 256, col);
}
- /* Propagate the changes to the drawable.
+ /* Propagate the changes to the drawable when we have a palette. This function is also called
+ * when the palette is removed.
* TODO: in case of hardware p8 palettes we should only upload the palette. */
- if(This->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ if(pal && (This->resource.usage & WINED3DUSAGE_RENDERTARGET))
IWineD3DSurface_LoadLocation(iface, SFLAG_INDRAWABLE, NULL);
return WINED3D_OK;
Module: wine
Branch: master
Commit: c623ffd7d02e365544c44ae7d3eafbf6fcb1a191
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c623ffd7d02e365544c44ae7d…
Author: Roderick Colenbrander <thunderbird2k(a)gmx.net>
Date: Thu Feb 21 18:19:44 2008 +0100
wined3d: Don't flush in GDI RealizePalette without a palette.
---
dlls/wined3d/surface_gdi.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index c0f54bc..5193e4a 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -657,10 +657,11 @@ HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface) {
SetDIBColorTable(This->hDC, 0, 256, col);
}
- /* Update the image because of the palette change. Some games like e.g Red Alert
- * call SetEntries a lot to implement fading.
+ /* Update the image because of the palette change. Note that this function is also
+ * called on a palette removal. In such a case we don't have to update the screen.
+ * Some games like e.g Red Alert call SetEntries a lot to implement fading.
*/
- if(This->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ if(pal && This->resource.usage & WINED3DUSAGE_RENDERTARGET)
x11_copy_to_screen(This, NULL);
return WINED3D_OK;
Module: wine
Branch: master
Commit: 582de7ba0dab10488c6b9abc8d70c5c5e0134670
URL: http://source.winehq.org/git/wine.git/?a=commit;h=582de7ba0dab10488c6b9abc8…
Author: Rob Shearman <rob(a)codeweavers.com>
Date: Thu Feb 21 16:44:52 2008 +0000
gdi32: Optimise StretchBlt for the case where no stretching is being done and the whole image is being set.
In this case, we can just call SetDIBits which is likely to be a lot faster.
---
dlls/gdi32/dib.c | 118 ++++++++++++++++++++++++++++++++++--------------------
1 files changed, 75 insertions(+), 43 deletions(-)
diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index e8b3dc9..d53b8f2 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -205,13 +205,12 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
}
else /* use StretchBlt */
{
- HBITMAP hBitmap, hOldBitmap;
- HPALETTE hpal = NULL;
- HDC hdcMem;
LONG height;
LONG width;
WORD planes, bpp;
DWORD compr, size;
+ HBITMAP hBitmap;
+ BOOL fastpath = FALSE;
release_dc_ptr( dc );
@@ -227,51 +226,84 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
return 0;
}
- hdcMem = CreateCompatibleDC( hdc );
- hBitmap = CreateCompatibleBitmap(hdc, width, height);
- hOldBitmap = SelectObject( hdcMem, hBitmap );
- if(wUsage == DIB_PAL_COLORS)
+ hBitmap = GetCurrentObject(hdc, OBJ_BITMAP);
+
+ if (xDst == 0 && yDst == 0 && xSrc == 0 && ySrc == 0 &&
+ widthDst == widthSrc && heightDst == heightSrc &&
+ info->bmiHeader.biCompression == BI_RGB &&
+ dwRop == SRCCOPY)
{
- hpal = GetCurrentObject(hdc, OBJ_PAL);
- hpal = SelectPalette(hdcMem, hpal, FALSE);
+ BITMAPOBJ *bmp;
+ if ((bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC )))
+ {
+ if (bmp->bitmap.bmBitsPixel == bpp &&
+ bmp->bitmap.bmWidth == widthSrc &&
+ bmp->bitmap.bmHeight == heightSrc &&
+ bmp->bitmap.bmPlanes == planes)
+ fastpath = TRUE;
+ GDI_ReleaseObj( hBitmap );
+ }
}
- if (info->bmiHeader.biCompression == BI_RLE4 ||
- info->bmiHeader.biCompression == BI_RLE8) {
-
- /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
- * contain all the rectangle described in bmiHeader, but only part of it.
- * This mean that those undescribed pixels must be left untouched.
- * So, we first copy on a memory bitmap the current content of the
- * destination rectangle, blit the DIB bits on top of it - hence leaving
- * the gaps untouched -, and blitting the rectangle back.
- * This insure that gaps are untouched on the destination rectangle
- * Not doing so leads to trashed images (the gaps contain what was on the
- * memory bitmap => generally black or garbage)
- * Unfortunately, RLE DIBs without gaps will be slowed down. But this is
- * another speed vs correctness issue. Anyway, if speed is needed, then the
- * pStretchDIBits function shall be implemented.
- * ericP (2000/09/09)
- */
-
- /* copy existing bitmap from destination dc */
- StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
- widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
- dwRop );
+ if (fastpath)
+ {
+ /* fast path */
+ TRACE("using fast path\n");
+ heightSrc = SetDIBits( hdc, hBitmap, 0, height, bits, info, wUsage);
}
+ else
+ {
+ /* slow path - need to use StretchBlt */
+ HBITMAP hOldBitmap;
+ HPALETTE hpal = NULL;
+ HDC hdcMem;
+
+ hdcMem = CreateCompatibleDC( hdc );
+ hBitmap = CreateCompatibleBitmap(hdc, width, height);
+ hOldBitmap = SelectObject( hdcMem, hBitmap );
+ if(wUsage == DIB_PAL_COLORS)
+ {
+ hpal = GetCurrentObject(hdc, OBJ_PAL);
+ hpal = SelectPalette(hdcMem, hpal, FALSE);
+ }
- SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
-
- /* Origin for DIBitmap may be bottom left (positive biHeight) or top
- left (negative biHeight) */
- StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
- hdcMem, xSrc, abs(height) - heightSrc - ySrc,
- widthSrc, heightSrc, dwRop );
- if(hpal)
- SelectPalette(hdcMem, hpal, FALSE);
- SelectObject( hdcMem, hOldBitmap );
- DeleteDC( hdcMem );
- DeleteObject( hBitmap );
+ if (info->bmiHeader.biCompression == BI_RLE4 ||
+ info->bmiHeader.biCompression == BI_RLE8) {
+
+ /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
+ * contain all the rectangle described in bmiHeader, but only part of it.
+ * This mean that those undescribed pixels must be left untouched.
+ * So, we first copy on a memory bitmap the current content of the
+ * destination rectangle, blit the DIB bits on top of it - hence leaving
+ * the gaps untouched -, and blitting the rectangle back.
+ * This insure that gaps are untouched on the destination rectangle
+ * Not doing so leads to trashed images (the gaps contain what was on the
+ * memory bitmap => generally black or garbage)
+ * Unfortunately, RLE DIBs without gaps will be slowed down. But this is
+ * another speed vs correctness issue. Anyway, if speed is needed, then the
+ * pStretchDIBits function shall be implemented.
+ * ericP (2000/09/09)
+ */
+
+ /* copy existing bitmap from destination dc */
+ StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
+ widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
+ dwRop );
+ }
+
+ SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
+
+ /* Origin for DIBitmap may be bottom left (positive biHeight) or top
+ left (negative biHeight) */
+ StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
+ hdcMem, xSrc, abs(height) - heightSrc - ySrc,
+ widthSrc, heightSrc, dwRop );
+ if(hpal)
+ SelectPalette(hdcMem, hpal, FALSE);
+ SelectObject( hdcMem, hOldBitmap );
+ DeleteDC( hdcMem );
+ DeleteObject( hBitmap );
+ }
}
return heightSrc;
}