Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

209 lines
7.3 KiB

/**************************************************************************
*
* Copyright (c) 2000 Microsoft Corporation
*
* Module Name:
*
* CPU-specific scan operations
*
* Abstract:
*
* Handles scan operations which only work on certain CPU's.
* Currently only used by EpAlphaBlender. This works by overwriting the
* function pointer arrays with ones holding CPU-specific information.
*
* Created:
*
* 05/30/2000 agodfrey
* Created it.
*
**************************************************************************/
#include "precomp.hpp"
#include "scanoperationinternal.hpp"
using namespace ScanOperation;
// This variable records whether Initialize() has been called yet.
BOOL CPUSpecificOps::Initialized = FALSE;
/**************************************************************************\
*
* Special-case low-quality blend operations which blend directly to a
* given destination format (with the source in 32BPP_PARGB).
*
* Some of these operations may use MMX instructions.
*
* Notes:
*
* The 555/565 cases support both dithering and non-dithering, via the flag
* OtherParams::DoingDither.
*
* We leave out PIXFMT_32BPP_ARGB and PIXFMT_64BPP_ARGB, since they're not
* "ignore alpha" formats, so we'd need to AlphaDivide after the blend.
*
\**************************************************************************/
static ScanOpFunc BlendOpsLowQuality_MMX[PIXFMT_MAX] =
{
NULL, // PIXFMT_UNDEFINED
NULL, // PIXFMT_1BPP_INDEXED
NULL, // PIXFMT_4BPP_INDEXED
NULL, // PIXFMT_8BPP_INDEXED
NULL, // PIXFMT_16BPP_GRAYSCALE
Dither_Blend_sRGB_555_MMX, // PIXFMT_16BPP_RGB555
Dither_Blend_sRGB_565_MMX, // PIXFMT_16BPP_RGB565
NULL, // PIXFMT_16BPP_ARGB1555
Blend_sRGB_24, // PIXFMT_24BPP_RGB
Blend_sRGB_sRGB_MMX, // PIXFMT_32BPP_RGB
NULL, // PIXFMT_32BPP_ARGB
Blend_sRGB_sRGB_MMX, // PIXFMT_32BPP_PARGB
NULL, // PIXFMT_48BPP_RGB
NULL, // PIXFMT_64BPP_ARGB
NULL, // PIXFMT_64BPP_PARGB
Blend_sRGB_24BGR // PIXFMT_24BPP_BGR
};
/**************************************************************************\
*
* Special-case gamma-corrected blend operations which blend directly to a
* given destination format (with the source in 32BPP_PARGB).
*
* Some of these operations may use MMX instructions.
*
* Notes:
*
* We leave out PIXFMT_32BPP_ARGB and PIXFMT_64BPP_ARGB, since they're not
* "ignore alpha" formats, so we'd need to AlphaDivide after the blend.
*
\**************************************************************************/
static ScanOpFunc BlendOpsHighQuality_MMX[PIXFMT_MAX] =
{
NULL, // PIXFMT_UNDEFINED
NULL, // PIXFMT_1BPP_INDEXED
NULL, // PIXFMT_4BPP_INDEXED
NULL, // PIXFMT_8BPP_INDEXED
NULL, // PIXFMT_16BPP_GRAYSCALE
BlendLinear_sRGB_555_MMX, // PIXFMT_16BPP_RGB555
BlendLinear_sRGB_565_MMX, // PIXFMT_16BPP_RGB565
NULL, // PIXFMT_16BPP_ARGB1555
NULL, // PIXFMT_24BPP_RGB
BlendLinear_sRGB_32RGB_MMX, // PIXFMT_32BPP_RGB
NULL, // PIXFMT_32BPP_ARGB
NULL, // PIXFMT_32BPP_PARGB
NULL, // PIXFMT_48BPP_RGB
NULL, // PIXFMT_64BPP_ARGB
Blend_sRGB64_sRGB64_MMX, // PIXFMT_64BPP_PARGB
NULL // PIXFMT_24BPP_BGR
};
/**************************************************************************\
*
* Operations which convert from the closest canonical format - either
* 32BPP_ARGB or 64BPP_ARGB).
*
* This is specific to EpAlphaBlender. EpFormatConverter uses a different
* table; some of the entries are different.
*
* The NULL entries for 32BPP_ARGB and 64_BPP_ARGB are used to indicate that no
* conversion is necessary.
*
* Some of these operations use MMX instructions.
*
* Notes:
*
* The 555/565 cases support both dithering and non-dithering, via the flag
* OtherParams::DoingDither.
*
* For 8bpp, we use the 16-color halftoning function. Initialize() will
* need to work out if it can use something better, like the 216-color
* halftone function. We should really have a 'nearest-color-matching' function
* here, to support drawing to bitmaps with arbitrary palettes (the "16 VGA
* colors" assumption is only true for the screen.)
*
\**************************************************************************/
static ScanOpFunc ABConvertFromCanonicalOps_MMX[PIXFMT_MAX] =
{
NULL, // PIXFMT_UNDEFINED
NULL, // PIXFMT_1BPP_INDEXED
NULL, // PIXFMT_4BPP_INDEXED
HalftoneToScreen_sRGB_8_16, // PIXFMT_8BPP_INDEXED
NULL, // PIXFMT_16BPP_GRAYSCALE
Dither_sRGB_555_MMX, // PIXFMT_16BPP_RGB555
Dither_sRGB_565_MMX, // PIXFMT_16BPP_RGB565
Quantize_sRGB_1555, // PIXFMT_16BPP_ARGB1555
Quantize_sRGB_24, // PIXFMT_24BPP_RGB
Quantize_sRGB_32RGB, // PIXFMT_32BPP_RGB
NULL, // PIXFMT_32BPP_ARGB
AlphaMultiply_sRGB, // PIXFMT_32BPP_PARGB
Quantize_sRGB64_48, // PIXFMT_48BPP_RGB
NULL, // PIXFMT_64BPP_ARGB
AlphaMultiply_sRGB64, // PIXFMT_64BPP_PARGB
Quantize_sRGB_24BGR // PIXFMT_24BPP_BGR
};
/**************************************************************************
*
* Function Description:
*
* Initializes the function pointer arrays with processor-specific
* data. Should only be called once.
*
* Return Value:
*
* NONE
*
* Created:
*
* 05/30/2000 agodfrey
* Created it.
*
**************************************************************************/
VOID
CPUSpecificOps::Initialize()
{
// Thread-protect the access to the global "Initialized" and
// the function pointer arrays. Beware: Users of these tables (currently
// only EpAlphaBlender::Initialize()) must be careful when they read those
// arrays. They must either protect the access under this critical section,
// or simply ensure that they've called this function first.
LoadLibraryCriticalSection llcs; // Hey, it's an 'initialization' critsec!
// Make sure no-one calls us before OSInfo::HasMMX is initialized
#if DBG
static BOOL noMMX = FALSE;
ASSERT(!(noMMX && OSInfo::HasMMX));
if (!OSInfo::HasMMX)
{
noMMX = TRUE;
}
#endif
if (!Initialized)
{
INT i;
if (OSInfo::HasMMX)
{
for (i=0; i<PIXFMT_MAX; i++)
{
BlendOpsLowQuality[i] = BlendOpsLowQuality_MMX[i];
BlendOpsHighQuality[i] = BlendOpsHighQuality_MMX[i];
ABConvertFromCanonicalOps[i] = ABConvertFromCanonicalOps_MMX[i];
}
}
Initialized = TRUE;
}
}