Bug 625409. ColorLayer implementations need to premultiply by the alpha value of their color. r=bas,a=blocking
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 19 Jan 2011 21:27:54 +1300
changeset 60852 9163f9b80bce2c68446229b7a71bf8a127957bed
parent 60851 e807269acaa316f55dbfa2b54a1e85db84c5f751
child 60853 756269dfadeeb9111420453220e79c2dc8fc7072
push id18137
push userrocallahan@mozilla.com
push dateWed, 19 Jan 2011 08:28:48 +0000
treeherdermozilla-central@710c1a6faf99 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas, blocking
bugs625409
milestone2.0b10pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 625409. ColorLayer implementations need to premultiply by the alpha value of their color. r=bas,a=blocking
gfx/layers/d3d10/ColorLayerD3D10.cpp
gfx/layers/d3d9/ColorLayerD3D9.cpp
gfx/layers/opengl/ColorLayerOGL.cpp
layout/reftests/bugs/625409-1-ref.html
layout/reftests/bugs/625409-1.html
layout/reftests/bugs/reftest.list
--- a/gfx/layers/d3d10/ColorLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ColorLayerD3D10.cpp
@@ -53,22 +53,23 @@ ColorLayerD3D10::GetLayer()
 {
   return this;
 }
 
 void
 ColorLayerD3D10::RenderLayer()
 {
   float color[4];
-  // color is premultiplied, so we need to adjust all channels
-  float opacity = GetEffectiveOpacity();
+  // output color is premultiplied, so we need to adjust all channels.
+  // mColor is not premultiplied.
+  float opacity = GetEffectiveOpacity() * mColor.a;
   color[0] = (float)(mColor.r * opacity);
   color[1] = (float)(mColor.g * opacity);
   color[2] = (float)(mColor.b * opacity);
-  color[3] = (float)(mColor.a * opacity);
+  color[3] = (float)(mColor.a);
 
   const gfx3DMatrix& transform = GetEffectiveTransform();
   void* raw = &const_cast<gfx3DMatrix&>(transform)._11;
   effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
   effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
 
   ID3D10EffectTechnique *technique;
   technique = effect()->GetTechniqueByName("RenderSolidColorLayer");
--- a/gfx/layers/d3d9/ColorLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ColorLayerD3D9.cpp
@@ -62,22 +62,23 @@ ColorLayerD3D9::RenderLayer()
                        visibleRect.width,
                        visibleRect.height),
     1);
 
   const gfx3DMatrix& transform = GetEffectiveTransform();
   device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
 
   float color[4];
-  float opacity = GetEffectiveOpacity();
-  // color is premultiplied, so we need to adjust all channels
+  float opacity = GetEffectiveOpacity() * mColor.a;
+  // output color is premultiplied, so we need to adjust all channels.
+  // mColor is not premultiplied.
   color[0] = (float)(mColor.r * opacity);
   color[1] = (float)(mColor.g * opacity);
   color[2] = (float)(mColor.b * opacity);
-  color[3] = (float)(mColor.a * opacity);
+  color[3] = (float)(opacity);
 
   device()->SetPixelShaderConstantF(0, color, 1);
 
   mD3DManager->SetShaderMode(DeviceManagerD3D9::SOLIDCOLORLAYER);
 
   device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
 }
 
--- a/gfx/layers/opengl/ColorLayerOGL.cpp
+++ b/gfx/layers/opengl/ColorLayerOGL.cpp
@@ -51,22 +51,22 @@ RenderColorLayer(ColorLayer* aLayer, Lay
 
   nsIntRect visibleRect = aLayer->GetEffectiveVisibleRegion().GetBounds();
   
   /* Multiply color by the layer opacity, as the shader
    * ignores layer opacity and expects a final color to
    * write to the color buffer.  This saves a needless
    * multiply in the fragment shader.
    */
-  float opacity = aLayer->GetEffectiveOpacity();
   gfxRGBA color(aLayer->GetColor());
+  float opacity = aLayer->GetEffectiveOpacity() * color.a;
   color.r *= opacity;
   color.g *= opacity;
   color.b *= opacity;
-  color.a *= opacity;
+  color.a = opacity;
 
   SolidColorLayerProgram *program = aManager->GetColorLayerProgram();
   program->Activate();
   program->SetLayerQuadRect(visibleRect);
   program->SetLayerTransform(aLayer->GetEffectiveTransform());
   program->SetRenderOffset(aOffset);
   program->SetRenderColor(color);
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/625409-1-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<html>
+<body style="background:rgb(0,0,0);">
+  <div style="position:fixed;left:0;top:0;width:200px;height:300px;background:rgba(255,255,255,0.5);">
+    <div style="margin-top:200px;height:100px;background:rgb(0,0,0);"></div>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/625409-1.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<html>
+<body style="background:rgb(0,0,0);">
+  <div style="position:fixed;left:0;top:0;width:200px;height:200px;background:rgba(255,255,255,0.5);"></div>
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1561,8 +1561,9 @@ fails-if(!haveTestPlugin) == 599476.html
 HTTP(..) == 615121-1.html 615121-1-ref.html
 HTTP(..) != 615121-2.html 615121-2-notref.html
 == 617242-1.html 617242-1-ref.html
 != 618071.html 618071-notref.html
 == 621253-1.xhtml 621253-1-ref.xhtml
 HTTP(..) == 619511-1.html 619511-1-ref.html
 random-if(winWidget) == 621918-1.svg 621918-1-ref.svg # 1-pixel diacritic positioning discrepancy in rotated text (may depend on platform fonts)
 HTTP(..) == 621918-2.svg 621918-2-ref.svg # http(..) for filters.svg, used to mask antialiasing issues where glyphs touch
+== 625409-1.html 625409-1-ref.html