https://bugs.webkit.org/show_bug.cgi?id=72452
Instead of relying on the combination of clearing the surface and initializing
the alpha channel to 1.0 followed by disabling alpha in the color mask when
rendering the root layer tiles, add shaders to support writing out opaque layers
(alpha channel values written as 1.0).
Patch by Daniel Sievers <sievers@chromium.org> on 2011-11-16
Reviewed by James Robinson.
No functional change made that requires new tests.
* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::drawLayersInternal):
(WebCore::LayerRendererChromium::initializeSharedObjects):
(WebCore::LayerRendererChromium::tilerProgramOpaque):
(WebCore::LayerRendererChromium::tilerProgramOpaqueAA):
(WebCore::LayerRendererChromium::tilerProgramSwizzleOpaque):
(WebCore::LayerRendererChromium::tilerProgramSwizzleOpaqueAA):
(WebCore::LayerRendererChromium::cleanupSharedObjects):
* platform/graphics/chromium/LayerRendererChromium.h:
* platform/graphics/chromium/ShaderChromium.cpp:
(WebCore::FragmentTexOpaqueBinding::FragmentTexOpaqueBinding):
(WebCore::FragmentTexOpaqueBinding::init):
(WebCore::FragmentShaderRGBATexOpaque::getShaderString):
(WebCore::FragmentShaderRGBATexSwizzleOpaque::getShaderString):
(WebCore::FragmentTexClampOpaqueAABinding::FragmentTexClampOpaqueAABinding):
(WebCore::FragmentTexClampOpaqueAABinding::init):
(WebCore::FragmentShaderRGBATexClampOpaqueAA::getShaderString):
(WebCore::FragmentShaderRGBATexClampSwizzleOpaqueAA::getShaderString):
* platform/graphics/chromium/ShaderChromium.h:
(WebCore::FragmentTexOpaqueBinding::alphaLocation):
(WebCore::FragmentTexOpaqueBinding::samplerLocation):
(WebCore::FragmentTexClampOpaqueAABinding::alphaLocation):
(WebCore::FragmentTexClampOpaqueAABinding::samplerLocation):
(WebCore::FragmentTexClampOpaqueAABinding::fragmentTexTransformLocation):
(WebCore::FragmentTexClampOpaqueAABinding::edgeLocation):
* platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
(WebCore::CCTiledLayerImpl::draw):
* platform/graphics/chromium/cc/CCTiledLayerImpl.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@100536
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2011-11-16 Daniel Sievers <sievers@chromium.org>
+
+ [Chromium] Avoid color mask operations for root layers
+ https://bugs.webkit.org/show_bug.cgi?id=72452
+
+ Instead of relying on the combination of clearing the surface and initializing
+ the alpha channel to 1.0 followed by disabling alpha in the color mask when
+ rendering the root layer tiles, add shaders to support writing out opaque layers
+ (alpha channel values written as 1.0).
+
+ Reviewed by James Robinson.
+
+ No functional change made that requires new tests.
+
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::drawLayersInternal):
+ (WebCore::LayerRendererChromium::initializeSharedObjects):
+ (WebCore::LayerRendererChromium::tilerProgramOpaque):
+ (WebCore::LayerRendererChromium::tilerProgramOpaqueAA):
+ (WebCore::LayerRendererChromium::tilerProgramSwizzleOpaque):
+ (WebCore::LayerRendererChromium::tilerProgramSwizzleOpaqueAA):
+ (WebCore::LayerRendererChromium::cleanupSharedObjects):
+ * platform/graphics/chromium/LayerRendererChromium.h:
+ * platform/graphics/chromium/ShaderChromium.cpp:
+ (WebCore::FragmentTexOpaqueBinding::FragmentTexOpaqueBinding):
+ (WebCore::FragmentTexOpaqueBinding::init):
+ (WebCore::FragmentShaderRGBATexOpaque::getShaderString):
+ (WebCore::FragmentShaderRGBATexSwizzleOpaque::getShaderString):
+ (WebCore::FragmentTexClampOpaqueAABinding::FragmentTexClampOpaqueAABinding):
+ (WebCore::FragmentTexClampOpaqueAABinding::init):
+ (WebCore::FragmentShaderRGBATexClampOpaqueAA::getShaderString):
+ (WebCore::FragmentShaderRGBATexClampSwizzleOpaqueAA::getShaderString):
+ * platform/graphics/chromium/ShaderChromium.h:
+ (WebCore::FragmentTexOpaqueBinding::alphaLocation):
+ (WebCore::FragmentTexOpaqueBinding::samplerLocation):
+ (WebCore::FragmentTexClampOpaqueAABinding::alphaLocation):
+ (WebCore::FragmentTexClampOpaqueAABinding::samplerLocation):
+ (WebCore::FragmentTexClampOpaqueAABinding::fragmentTexTransformLocation):
+ (WebCore::FragmentTexClampOpaqueAABinding::edgeLocation):
+ * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
+ (WebCore::CCTiledLayerImpl::draw):
+ * platform/graphics/chromium/cc/CCTiledLayerImpl.h:
+
2011-11-16 Tim Horton <timothy_horton@apple.com>
Implement CSS3 Images cross-fade() image function
m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get()));
m_renderSurfaceProgram = adoptPtr(new CCRenderSurface::Program(m_context.get()));
m_tilerProgram = adoptPtr(new CCTiledLayerImpl::Program(m_context.get()));
+ m_tilerProgramOpaque = adoptPtr(new CCTiledLayerImpl::ProgramOpaque(m_context.get()));
GLC(m_context.get(), m_context->flush());
return m_tilerProgram.get();
}
+const CCTiledLayerImpl::ProgramOpaque* LayerRendererChromium::tilerProgramOpaque()
+{
+ ASSERT(m_tilerProgramOpaque);
+ if (!m_tilerProgramOpaque->initialized()) {
+ TRACE_EVENT("LayerRendererChromium::tilerProgramOpaque::initialize", this, 0);
+ m_tilerProgramOpaque->initialize(m_context.get());
+ }
+ return m_tilerProgramOpaque.get();
+}
+
const CCTiledLayerImpl::ProgramAA* LayerRendererChromium::tilerProgramAA()
{
if (!m_tilerProgramAA)
return m_tilerProgramSwizzle.get();
}
+const CCTiledLayerImpl::ProgramSwizzleOpaque* LayerRendererChromium::tilerProgramSwizzleOpaque()
+{
+ if (!m_tilerProgramSwizzleOpaque)
+ m_tilerProgramSwizzleOpaque = adoptPtr(new CCTiledLayerImpl::ProgramSwizzleOpaque(m_context.get()));
+ if (!m_tilerProgramSwizzleOpaque->initialized()) {
+ TRACE_EVENT("LayerRendererChromium::tilerProgramSwizzleOpaque::initialize", this, 0);
+ m_tilerProgramSwizzleOpaque->initialize(m_context.get());
+ }
+ return m_tilerProgramSwizzleOpaque.get();
+}
+
const CCTiledLayerImpl::ProgramSwizzleAA* LayerRendererChromium::tilerProgramSwizzleAA()
{
if (!m_tilerProgramSwizzleAA)
m_headsUpDisplayProgram->cleanup(m_context.get());
if (m_tilerProgram)
m_tilerProgram->cleanup(m_context.get());
+ if (m_tilerProgramOpaque)
+ m_tilerProgramOpaque->cleanup(m_context.get());
if (m_tilerProgramAA)
m_tilerProgramAA->cleanup(m_context.get());
if (m_tilerProgramSwizzle)
m_tilerProgramSwizzle->cleanup(m_context.get());
+ if (m_tilerProgramSwizzleOpaque)
+ m_tilerProgramSwizzleOpaque->cleanup(m_context.get());
if (m_tilerProgramSwizzleAA)
m_tilerProgramSwizzleAA->cleanup(m_context.get());
if (m_canvasLayerProgram)
m_borderProgram.clear();
m_headsUpDisplayProgram.clear();
m_tilerProgram.clear();
+ m_tilerProgramOpaque.clear();
m_tilerProgramAA.clear();
m_tilerProgramSwizzle.clear();
+ m_tilerProgramSwizzleOpaque.clear();
m_tilerProgramSwizzleAA.clear();
m_canvasLayerProgram.clear();
m_pluginLayerProgram.clear();
const CCRenderSurface::MaskProgram* renderSurfaceMaskProgram();
const CCRenderSurface::MaskProgramAA* renderSurfaceMaskProgramAA();
const CCTiledLayerImpl::Program* tilerProgram();
+ const CCTiledLayerImpl::ProgramOpaque* tilerProgramOpaque();
const CCTiledLayerImpl::ProgramAA* tilerProgramAA();
const CCTiledLayerImpl::ProgramSwizzle* tilerProgramSwizzle();
+ const CCTiledLayerImpl::ProgramSwizzleOpaque* tilerProgramSwizzleOpaque();
const CCTiledLayerImpl::ProgramSwizzleAA* tilerProgramSwizzleAA();
const CCCanvasLayerImpl::Program* canvasLayerProgram();
const CCPluginLayerImpl::Program* pluginLayerProgram();
OwnPtr<LayerChromium::BorderProgram> m_borderProgram;
OwnPtr<CCHeadsUpDisplay::Program> m_headsUpDisplayProgram;
OwnPtr<CCTiledLayerImpl::Program> m_tilerProgram;
+ OwnPtr<CCTiledLayerImpl::ProgramOpaque> m_tilerProgramOpaque;
OwnPtr<CCTiledLayerImpl::ProgramSwizzle> m_tilerProgramSwizzle;
+ OwnPtr<CCTiledLayerImpl::ProgramSwizzleOpaque> m_tilerProgramSwizzleOpaque;
OwnPtr<CCTiledLayerImpl::ProgramAA> m_tilerProgramAA;
OwnPtr<CCTiledLayerImpl::ProgramSwizzleAA> m_tilerProgramSwizzleAA;
OwnPtr<CCCanvasLayerImpl::Program> m_canvasLayerProgram;
ASSERT(m_samplerLocation != -1 && m_alphaLocation != -1);
}
+FragmentTexOpaqueBinding::FragmentTexOpaqueBinding()
+ : m_samplerLocation(-1)
+{
+}
+
+void FragmentTexOpaqueBinding::init(GraphicsContext3D* context, unsigned program)
+{
+ m_samplerLocation = context->getUniformLocation(program, "s_texture");
+
+ ASSERT(m_samplerLocation != -1);
+}
+
String FragmentShaderRGBATexFlipAlpha::getShaderString() const
{
return SHADER(
);
}
+String FragmentShaderRGBATexOpaque::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ void main()
+ {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ gl_FragColor = vec4(texColor.rgb, 1.0);
+ }
+ );
+}
+
String FragmentShaderRGBATexSwizzleAlpha::getShaderString() const
{
return SHADER(
);
}
+String FragmentShaderRGBATexSwizzleOpaque::getShaderString() const
+{
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ void main()
+ {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
+ }
+ );
+}
+
FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
: m_samplerLocation(-1)
, m_alphaLocation(-1)
int m_alphaLocation;
};
+class FragmentTexOpaqueBinding {
+public:
+ FragmentTexOpaqueBinding();
+
+ void init(GraphicsContext3D*, unsigned program);
+ int alphaLocation() const { return -1; }
+ int samplerLocation() const { return m_samplerLocation; }
+
+private:
+ int m_samplerLocation;
+};
+
class FragmentShaderRGBATexFlipAlpha : public FragmentTexAlphaBinding {
public:
String getShaderString() const;
String getShaderString() const;
};
-// Swizzles the red and blue component of sampled texel.
+class FragmentShaderRGBATexOpaque : public FragmentTexOpaqueBinding {
+public:
+ String getShaderString() const;
+};
+
+// Swizzles the red and blue component of sampled texel with alpha.
class FragmentShaderRGBATexSwizzleAlpha : public FragmentTexAlphaBinding {
public:
String getShaderString() const;
};
+// Swizzles the red and blue component of sampled texel without alpha.
+class FragmentShaderRGBATexSwizzleOpaque : public FragmentTexOpaqueBinding {
+public:
+ String getShaderString() const;
+};
+
class FragmentShaderRGBATexAlphaAA {
public:
FragmentShaderRGBATexAlphaAA();
}
GraphicsContext3D* context = layerRenderer->context();
- if (isNonCompositedContent()) {
- context->colorMask(true, true, true, false);
+ if (isNonCompositedContent())
GLC(context, context->disable(GraphicsContext3D::BLEND));
- }
switch (m_sampledTexelFormat) {
case LayerTextureUpdater::SampledTexelFormatRGBA:
const ProgramAA* program = layerRenderer->tilerProgramAA();
drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, program->fragmentShader().fragmentTexTransformLocation(), program->fragmentShader().edgeLocation());
} else {
- const Program* program = layerRenderer->tilerProgram();
- drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+ if (isNonCompositedContent()) {
+ const ProgramOpaque* program = layerRenderer->tilerProgramOpaque();
+ drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+ } else {
+ const Program* program = layerRenderer->tilerProgram();
+ drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+ }
}
break;
case LayerTextureUpdater::SampledTexelFormatBGRA:
const ProgramSwizzleAA* program = layerRenderer->tilerProgramSwizzleAA();
drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, program->fragmentShader().fragmentTexTransformLocation(), program->fragmentShader().edgeLocation());
} else {
- const ProgramSwizzle* program = layerRenderer->tilerProgramSwizzle();
- drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+ if (isNonCompositedContent()) {
+ const ProgramSwizzleOpaque* program = layerRenderer->tilerProgramSwizzleOpaque();
+ drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+ } else {
+ const ProgramSwizzle* program = layerRenderer->tilerProgramSwizzle();
+ drawTiles(layerRenderer, layerRect, layerTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
+ }
}
break;
default:
ASSERT_NOT_REACHED();
}
- if (isNonCompositedContent()) {
- context->colorMask(true, true, true, true);
+ if (isNonCompositedContent())
GLC(context, context->enable(GraphicsContext3D::BLEND));
- }
}
void CCTiledLayerImpl::setTilingData(const CCLayerTilingData& tiler)
// Used when texture format does not match native color format.
typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleAlpha> ProgramSwizzle;
+ // Same as above but ignoring alpha and writing out 1.0 for the alpha channel.
+ typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexOpaque> ProgramOpaque;
+ typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleOpaque> ProgramSwizzleOpaque;
+
// Shader program that produces anti-aliased layer edges.
typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexClampAlphaAA> ProgramAA;
typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexClampSwizzleAlphaAA> ProgramSwizzleAA;