Bug 716438; using flags to select a shader. r=Bas

This commit is contained in:
Nicholas Cameron 2012-03-01 17:29:30 +00:00
parent a4a19696e8
commit 08cb3dff93
7 changed files with 117 additions and 137 deletions

View File

@ -264,53 +264,14 @@ CanvasLayerD3D10::RenderLayer()
SetEffectTransformAndOpacity();
ID3D10EffectTechnique *technique;
if (LoadMaskTexture()) {
if (mDataIsPremultiplied) {
if (!mHasAlpha) {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPointMask");
} else {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulMask");
}
} else {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPointMask");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulMask");
}
}
} else {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremulPointMask");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremulMask");
}
}
} else { // no mask
if (mDataIsPremultiplied) {
if (!mHasAlpha) {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
}
} else {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
}
}
} else {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerNonPremul");
}
}
}
PRUint8 shaderFlags = 0;
shaderFlags |= LoadMaskTexture();
shaderFlags |= mDataIsPremultiplied
? SHADER_PREMUL : SHADER_NON_PREMUL | SHADER_RGBA;
shaderFlags |= mHasAlpha ? SHADER_RGBA : SHADER_RGB;
shaderFlags |= mFilter == gfxPattern::FILTER_NEAREST
? SHADER_POINT : SHADER_LINEAR;
ID3D10EffectTechnique* technique = SelectShader(shaderFlags);
if (mSRView) {
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(mSRView);

View File

@ -73,12 +73,7 @@ ColorLayerD3D10::RenderLayer()
effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
ID3D10EffectTechnique *technique;
if (LoadMaskTexture()) {
technique = effect()->GetTechniqueByName("RenderSolidColorLayerMask");
} else {
technique = effect()->GetTechniqueByName("RenderSolidColorLayer");
}
ID3D10EffectTechnique *technique = SelectShader(SHADER_SOLID | LoadMaskTexture());
nsIntRegionRectIterator iter(mVisibleRegion);

View File

@ -316,12 +316,12 @@ ContainerLayerD3D10::RenderLayer()
ID3D10EffectTechnique *technique;
if (LoadMaskTexture()) {
if (GetTransform().CanDraw2D()) {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulMask");
technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_MASK);
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulMask3D");
technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_MASK_3D);
}
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | SHADER_NO_MASK);
}
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(

View File

@ -211,35 +211,14 @@ ImageLayerD3D10::RenderLayer()
return;
}
if (LoadMaskTexture()) {
if (hasAlpha) {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPointMask");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulMask");
}
} else {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPointMask");
} else {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulMask");
}
}
} else {
if (hasAlpha) {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
}
} else {
if (mFilter == gfxPattern::FILTER_NEAREST) {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulPoint");
} else {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
}
}
}
PRUint8 shaderFlags = SHADER_PREMUL;
shaderFlags |= LoadMaskTexture();
shaderFlags |= hasAlpha
? SHADER_RGBA : SHADER_RGB;
shaderFlags |= mFilter == gfxPattern::FILTER_NEAREST
? SHADER_POINT : SHADER_LINEAR;
technique = SelectShader(shaderFlags);
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(srView);
@ -275,18 +254,12 @@ ImageLayerD3D10::RenderLayer()
return;
}
bool useMask = LoadMaskTexture();
// TODO: At some point we should try to deal with mFilter here, you don't
// really want to use point filtering in the case of NEAREST, since that
// would also use point filtering for Chroma upsampling. Where most likely
// the user would only want point filtering for final RGB image upsampling.
if (useMask) {
technique = effect()->GetTechniqueByName("RenderYCbCrLayerMask");
} else {
technique = effect()->GetTechniqueByName("RenderYCbCrLayer");
}
technique = SelectShader(SHADER_YCBCR | LoadMaskTexture());
effect()->GetVariableByName("tY")->AsShaderResource()->SetResource(data->mYView);
effect()->GetVariableByName("tCb")->AsShaderResource()->SetResource(data->mCbView);

View File

@ -842,7 +842,56 @@ LayerD3D10::LayerD3D10(LayerManagerD3D10 *aManager)
{
}
bool LayerD3D10::LoadMaskTexture()
ID3D10EffectTechnique*
LayerD3D10::SelectShader(PRUint8 aFlags)
{
switch (aFlags) {
case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_LINEAR | SHADER_MASK):
return effect()->GetTechniqueByName("RenderRGBALayerNonPremulMask");
case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderRGBALayerNonPremul");
case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_POINT | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderRGBALayerNonPremulPoint");
case (SHADER_RGBA | SHADER_NON_PREMUL | SHADER_POINT | SHADER_MASK):
return effect()->GetTechniqueByName("RenderRGBALayerNonPremulPointMask");
case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK_3D):
return effect()->GetTechniqueByName("RenderRGBALayerPremulMask3D");
case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK):
return effect()->GetTechniqueByName("RenderRGBALayerPremulMask");
case (SHADER_RGBA | SHADER_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderRGBALayerPremul");
case (SHADER_RGBA | SHADER_PREMUL | SHADER_POINT | SHADER_MASK):
return effect()->GetTechniqueByName("RenderRGBALayerPremulPointMask");
case (SHADER_RGBA | SHADER_PREMUL | SHADER_POINT | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderRGBALayerPremulPoint");
case (SHADER_RGB | SHADER_PREMUL | SHADER_POINT | SHADER_MASK):
return effect()->GetTechniqueByName("RenderRGBLayerPremulPointMask");
case (SHADER_RGB | SHADER_PREMUL | SHADER_POINT | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderRGBLayerPremulPoint");
case (SHADER_RGB | SHADER_PREMUL | SHADER_LINEAR | SHADER_MASK):
return effect()->GetTechniqueByName("RenderRGBLayerPremulMask");
case (SHADER_RGB | SHADER_PREMUL | SHADER_LINEAR | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderRGBLayerPremul");
case (SHADER_SOLID | SHADER_MASK):
return effect()->GetTechniqueByName("RenderSolidColorLayerMask");
case (SHADER_SOLID | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderSolidColorLayer");
case (SHADER_COMPONENT_ALPHA | SHADER_MASK):
return effect()->GetTechniqueByName("RenderComponentAlphaLayerMask");
case (SHADER_COMPONENT_ALPHA | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderComponentAlphaLayer");
case (SHADER_YCBCR | SHADER_MASK):
return effect()->GetTechniqueByName("RenderYCbCrLayerMask");
case (SHADER_YCBCR | SHADER_NO_MASK):
return effect()->GetTechniqueByName("RenderYCbCrLayer");
default:
NS_ERROR("Invalid shader.");
return nsnull;
}
}
PRUint8
LayerD3D10::LoadMaskTexture()
{
if (Layer* maskLayer = GetLayer()->GetMaskLayer()) {
gfxIntSize size;
@ -850,13 +899,14 @@ bool LayerD3D10::LoadMaskTexture()
static_cast<LayerD3D10*>(maskLayer->ImplData())->GetAsTexture(&size);
if (!maskSRV) {
return false;
return SHADER_NO_MASK;
}
gfxMatrix maskTransform;
bool maskIs2D = maskLayer->GetTransform().CanDraw2D(&maskTransform);
bool maskIs2D = maskLayer->GetEffectiveTransform().CanDraw2D(&maskTransform);
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
gfxRect bounds = gfxRect(maskTransform.GetTranslation(), size);
gfxRect bounds = gfxRect(gfxPoint(), size);
bounds = maskTransform.TransformBounds(bounds);
effect()->GetVariableByName("vMaskQuad")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
@ -867,10 +917,10 @@ bool LayerD3D10::LoadMaskTexture()
);
effect()->GetVariableByName("tMask")->AsShaderResource()->SetResource(maskSRV);
return true;
return SHADER_MASK;
}
return false;
return SHADER_NO_MASK;
}
WindowLayer::WindowLayer(LayerManagerD3D10* aManager)

View File

@ -319,10 +319,33 @@ protected:
/*
* Finds a texture for this layer's mask layer (if it has one) and sets it
* as an input to the shaders.
* Returns true if a texture is loaded, false if there was no mask layer, or
* a texture for the mask layer could not be loaded.
* Returns SHADER_MASK if a texture is loaded, SHADER_NO_MASK if there was no
* mask layer, or a texture for the mask layer could not be loaded.
*/
bool LoadMaskTexture();
PRUint8 LoadMaskTexture();
/**
* Select a shader technique using a combination of the following flags.
* Not all combinations of flags are supported, and might cause an error,
* check the fx file to see which shaders exist. In particular, aFlags should
* include any combination of the 0x20 bit = 0 flags OR one of the 0x20 bit = 1
* flags. Mask flags can be used in either case.
*/
ID3D10EffectTechnique* SelectShader(PRUint8 aFlags);
const static PRUint8 SHADER_NO_MASK = 0;
const static PRUint8 SHADER_MASK = 0x1;
const static PRUint8 SHADER_MASK_3D = 0x2;
// 0x20 bit = 0
const static PRUint8 SHADER_RGB = 0;
const static PRUint8 SHADER_RGBA = 0x4;
const static PRUint8 SHADER_NON_PREMUL = 0;
const static PRUint8 SHADER_PREMUL = 0x8;
const static PRUint8 SHADER_LINEAR = 0;
const static PRUint8 SHADER_POINT = 0x10;
// 0x20 bit = 1
const static PRUint8 SHADER_YCBCR = 0x20;
const static PRUint8 SHADER_COMPONENT_ALPHA = 0x24;
const static PRUint8 SHADER_SOLID = 0x28;
LayerManagerD3D10 *mD3DManager;
};

View File

@ -132,36 +132,19 @@ ThebesLayerD3D10::RenderLayer()
SetEffectTransformAndOpacity();
ID3D10EffectTechnique *technique;
if (LoadMaskTexture()) {
switch (mCurrentSurfaceMode) {
case SURFACE_COMPONENT_ALPHA:
technique = effect()->GetTechniqueByName("RenderComponentAlphaLayerMask");
break;
case SURFACE_OPAQUE:
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulMask");
break;
case SURFACE_SINGLE_CHANNEL_ALPHA:
technique = effect()->GetTechniqueByName("RenderRGBALayerPremulMask");
break;
default:
NS_ERROR("Unknown mode");
return;
}
} else {
switch (mCurrentSurfaceMode) {
case SURFACE_COMPONENT_ALPHA:
technique = effect()->GetTechniqueByName("RenderComponentAlphaLayer");
break;
case SURFACE_OPAQUE:
technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
break;
case SURFACE_SINGLE_CHANNEL_ALPHA:
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
break;
default:
NS_ERROR("Unknown mode");
return;
}
switch (mCurrentSurfaceMode) {
case SURFACE_COMPONENT_ALPHA:
technique = SelectShader(SHADER_COMPONENT_ALPHA | LoadMaskTexture());
break;
case SURFACE_OPAQUE:
technique = SelectShader(SHADER_RGB | SHADER_PREMUL | LoadMaskTexture());
break;
case SURFACE_SINGLE_CHANNEL_ALPHA:
technique = SelectShader(SHADER_RGBA | SHADER_PREMUL | LoadMaskTexture());
break;
default:
NS_ERROR("Unknown mode");
return;
}
nsIntRegionRectIterator iter(mVisibleRegion);
@ -652,12 +635,7 @@ ShadowThebesLayerD3D10::RenderLayer()
SetEffectTransformAndOpacity();
ID3D10EffectTechnique *technique;
if (LoadMaskTexture()) {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremulMask");
} else {
technique = effect()->GetTechniqueByName("RenderRGBLayerPremul");
}
ID3D10EffectTechnique *technique = SelectShader(SHADER_RGB | SHADER_PREMUL | LoadMaskTexture());
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(srView);