[Chromium] Fix CSS 3D corner anti-aliasing.

https://bugs.webkit.org/show_bug.cgi?id=68087

Patch by David Reveman <reveman@chromium.org> on 2011-09-23
Reviewed by James Robinson.

Source/WebCore:

Render sharp corners more correctly by adding bounding box
edges to anti-aliasing shaders.

Test: platform/chromium/compositing/3d-corners.html

* platform/graphics/chromium/ShaderChromium.cpp:
(WebCore::FragmentShaderRGBATexAlphaAA::getShaderString):
(WebCore::FragmentShaderRGBATexClampAlphaAA::getShaderString):
(WebCore::FragmentShaderRGBATexClampSwizzleAlphaAA::getShaderString):
(WebCore::FragmentShaderRGBATexAlphaMaskAA::getShaderString):
* platform/graphics/chromium/cc/CCRenderSurface.cpp:
(WebCore::CCRenderSurface::drawLayer):
(WebCore::CCRenderSurface::drawSurface):
* platform/graphics/chromium/cc/CCRenderSurface.h:
* platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
(WebCore::CCTiledLayerImpl::draw):
(WebCore::CCTiledLayerImpl::drawTiles):
* platform/graphics/chromium/cc/CCTiledLayerImpl.h:

LayoutTests:

Add a test to check sharp corner rendering of CSS 3D transformed
elements.

* platform/chromium-gpu-linux/compositing/flat-with-transformed-child-expected.checksum: Removed.
* platform/chromium-gpu-linux/compositing/flat-with-transformed-child-expected.png: Added.
* platform/chromium-gpu-linux/platform/chromium/compositing/3d-corners-expected.png: Added.
* platform/chromium-gpu-linux/platform/chromium/compositing/backface-visibility-transformed-expected.png:
* platform/chromium-gpu-linux/platform/chromium/compositing/perpendicular-layer-sorting-expected.png:
* platform/chromium/compositing/3d-corners-expected.txt: Added.
* platform/chromium/compositing/3d-corners.html: Added.
* platform/chromium/test_expectations.txt:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95870 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b41f7079
2011-09-23 David Reveman <reveman@chromium.org>
[Chromium] Fix CSS 3D corner anti-aliasing.
https://bugs.webkit.org/show_bug.cgi?id=68087
Reviewed by James Robinson.
Add a test to check sharp corner rendering of CSS 3D transformed
elements.
* platform/chromium-gpu-linux/compositing/flat-with-transformed-child-expected.checksum: Removed.
* platform/chromium-gpu-linux/compositing/flat-with-transformed-child-expected.png: Added.
* platform/chromium-gpu-linux/platform/chromium/compositing/3d-corners-expected.png: Added.
* platform/chromium-gpu-linux/platform/chromium/compositing/backface-visibility-transformed-expected.png:
* platform/chromium-gpu-linux/platform/chromium/compositing/perpendicular-layer-sorting-expected.png:
* platform/chromium/compositing/3d-corners-expected.txt: Added.
* platform/chromium/compositing/3d-corners.html: Added.
* platform/chromium/test_expectations.txt:
2011-09-23 Mihai Parparita <mihaip@chromium.org>
Add failing expectations for tests added by r95852.
<html>
<head>
<style type="text/css" media="screen">
.container {
position: relative;
height: 100px;
width: 500px;
margin: 50px 100px;
border: 1px solid blue;
-webkit-perspective: 10;
}
.parent {
-webkit-transform-style: preserve-3d;
-webkit-transform:translateY(0.1%);
}
#div1
{
height:500px;
background-color:green;
-webkit-transform-origin: center top;
-webkit-transform:rotate3d(1,0,0,-45deg);
}
#div2
{
height:500px;
background-color:green;
-webkit-transform-origin: center top;
-webkit-transform:rotate3d(1,0,0,-150deg);
}
#div3
{
height:500px;
background-color:green;
-webkit-transform-origin: center top;
-webkit-transform:rotate3d(1,0,0,-167deg);
}
</style>
<script type="text/javascript" charset="utf-8">
if (window.layoutTestController)
layoutTestController.dumpAsText(true);
</script>
</head>
<body style="overflow:hidden">
<div class="container">
<div class="parent">
<div id="div1"></div>
</div>
</div>
<div class="container">
<div class="parent">
<div id="div2"></div>
</div>
</div>
<div class="container">
<div class="parent">
<div id="div3"></div>
</div>
</div>
</body>
</html>
......@@ -3338,6 +3338,11 @@ BUGWK57312 SKIP : fast/regions = PASS
// CSS Exclusions support not yet enabled.
BUGWK57311 SKIP : fast/exclusions = PASS
BUGWK68087 WIN MAC GPU GPU-CG : compositing/flat-with-transformed-child.html = IMAGE
BUGWK68087 WIN MAC GPU GPU-CG : platform/chromium/compositing/3d-corners.html = IMAGE
BUGWK68087 WIN MAC GPU GPU-CG : platform/chromium/compositing/backface-visibility-transformed.html = IMAGE
BUGWK68087 WIN MAC GPU GPU-CG : platform/chromium/compositing/perpendicular-layer-sorting.html = IMAGE
BUGCR85755 : fast/js/exception-properties.html = TEXT
BUGWK62430 LINUX WIN : fast/dom/HTMLProgressElement/indeterminate-progress-001.html = FAIL
......
2011-09-23 David Reveman <reveman@chromium.org>
[Chromium] Fix CSS 3D corner anti-aliasing.
https://bugs.webkit.org/show_bug.cgi?id=68087
Reviewed by James Robinson.
Render sharp corners more correctly by adding bounding box
edges to anti-aliasing shaders.
Test: platform/chromium/compositing/3d-corners.html
* platform/graphics/chromium/ShaderChromium.cpp:
(WebCore::FragmentShaderRGBATexAlphaAA::getShaderString):
(WebCore::FragmentShaderRGBATexClampAlphaAA::getShaderString):
(WebCore::FragmentShaderRGBATexClampSwizzleAlphaAA::getShaderString):
(WebCore::FragmentShaderRGBATexAlphaMaskAA::getShaderString):
* platform/graphics/chromium/cc/CCRenderSurface.cpp:
(WebCore::CCRenderSurface::drawLayer):
(WebCore::CCRenderSurface::drawSurface):
* platform/graphics/chromium/cc/CCRenderSurface.h:
* platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
(WebCore::CCTiledLayerImpl::draw):
(WebCore::CCTiledLayerImpl::drawTiles):
* platform/graphics/chromium/cc/CCTiledLayerImpl.h:
2011-09-23 Oliver Hunt <oliver@apple.com>
Make write barriers actually do something when enabled
......@@ -305,7 +305,7 @@ String FragmentShaderRGBATexAlphaAA::getShaderString() const
varying vec2 v_texCoord;
uniform sampler2D s_texture;
uniform float alpha;
uniform vec3 edge[4];
uniform vec3 edge[8];
void main()
{
vec4 texColor = texture2D(s_texture, v_texCoord);
......@@ -314,7 +314,11 @@ String FragmentShaderRGBATexAlphaAA::getShaderString() const
float a1 = clamp(dot(edge[1], pos), 0.0, 1.0);
float a2 = clamp(dot(edge[2], pos), 0.0, 1.0);
float a3 = clamp(dot(edge[3], pos), 0.0, 1.0);
gl_FragColor = texColor * alpha * min(a0, a2) * min(a1, a3);
float a4 = clamp(dot(edge[4], pos), 0.0, 1.0);
float a5 = clamp(dot(edge[5], pos), 0.0, 1.0);
float a6 = clamp(dot(edge[6], pos), 0.0, 1.0);
float a7 = clamp(dot(edge[7], pos), 0.0, 1.0);
gl_FragColor = texColor * alpha * min(min(a0, a2) * min(a1, a3), min(a4, a6) * min(a5, a7));
}
);
}
......@@ -345,7 +349,7 @@ String FragmentShaderRGBATexClampAlphaAA::getShaderString() const
uniform sampler2D s_texture;
uniform float alpha;
uniform vec4 fragmentTexTransform;
uniform vec3 edge[4];
uniform vec3 edge[8];
void main()
{
vec2 texCoord = clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw + fragmentTexTransform.xy;
......@@ -355,7 +359,11 @@ String FragmentShaderRGBATexClampAlphaAA::getShaderString() const
float a1 = clamp(dot(edge[1], pos), 0.0, 1.0);
float a2 = clamp(dot(edge[2], pos), 0.0, 1.0);
float a3 = clamp(dot(edge[3], pos), 0.0, 1.0);
gl_FragColor = texColor * alpha * min(a0, a2) * min(a1, a3);
float a4 = clamp(dot(edge[4], pos), 0.0, 1.0);
float a5 = clamp(dot(edge[5], pos), 0.0, 1.0);
float a6 = clamp(dot(edge[6], pos), 0.0, 1.0);
float a7 = clamp(dot(edge[7], pos), 0.0, 1.0);
gl_FragColor = texColor * alpha * min(min(a0, a2) * min(a1, a3), min(a4, a6) * min(a5, a7));
}
);
}
......@@ -368,7 +376,7 @@ String FragmentShaderRGBATexClampSwizzleAlphaAA::getShaderString() const
uniform sampler2D s_texture;
uniform float alpha;
uniform vec4 fragmentTexTransform;
uniform vec3 edge[4];
uniform vec3 edge[8];
void main()
{
vec2 texCoord = clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw + fragmentTexTransform.xy;
......@@ -378,7 +386,11 @@ String FragmentShaderRGBATexClampSwizzleAlphaAA::getShaderString() const
float a1 = clamp(dot(edge[1], pos), 0.0, 1.0);
float a2 = clamp(dot(edge[2], pos), 0.0, 1.0);
float a3 = clamp(dot(edge[3], pos), 0.0, 1.0);
gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha * min(a0, a2) * min(a1, a3);
float a4 = clamp(dot(edge[4], pos), 0.0, 1.0);
float a5 = clamp(dot(edge[5], pos), 0.0, 1.0);
float a6 = clamp(dot(edge[6], pos), 0.0, 1.0);
float a7 = clamp(dot(edge[7], pos), 0.0, 1.0);
gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha * min(min(a0, a2) * min(a1, a3), min(a4, a6) * min(a5, a7));
}
);
}
......@@ -440,7 +452,7 @@ String FragmentShaderRGBATexAlphaMaskAA::getShaderString() const
uniform sampler2D s_texture;
uniform sampler2D s_mask;
uniform float alpha;
uniform vec3 edge[4];
uniform vec3 edge[8];
void main()
{
vec4 texColor = texture2D(s_texture, v_texCoord);
......@@ -450,7 +462,11 @@ String FragmentShaderRGBATexAlphaMaskAA::getShaderString() const
float a1 = clamp(dot(edge[1], pos), 0.0, 1.0);
float a2 = clamp(dot(edge[2], pos), 0.0, 1.0);
float a3 = clamp(dot(edge[3], pos), 0.0, 1.0);
gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w * min(a0, a2) * min(a1, a3);
float a4 = clamp(dot(edge[4], pos), 0.0, 1.0);
float a5 = clamp(dot(edge[5], pos), 0.0, 1.0);
float a6 = clamp(dot(edge[6], pos), 0.0, 1.0);
float a7 = clamp(dot(edge[7], pos), 0.0, 1.0);
gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w * min(min(a0, a2) * min(a1, a3), min(a4, a6) * min(a5, a7));
}
);
}
......
......@@ -137,6 +137,7 @@ void CCRenderSurface::drawLayer(LayerRendererChromium* layerRenderer, CCLayerImp
return;
FloatQuad quad = deviceMatrix.mapQuad(layerRenderer->sharedGeometryQuad());
CCLayerQuad deviceRect = CCLayerQuad(FloatQuad(quad.boundingBox()));
CCLayerQuad layerQuad = CCLayerQuad(quad);
#if defined(OS_CHROMEOS)
......@@ -147,8 +148,10 @@ void CCRenderSurface::drawLayer(LayerRendererChromium* layerRenderer, CCLayerImp
bool useAA = (!quad.isRectilinear() || !quad.boundingBox().isExpressibleAsIntRect());
#endif
if (useAA)
if (useAA) {
deviceRect.inflateAntiAliasingDistance();
layerQuad.inflateAntiAliasingDistance();
}
bool useMask = false;
if (maskLayer && maskLayer->drawsContent())
......@@ -158,24 +161,24 @@ void CCRenderSurface::drawLayer(LayerRendererChromium* layerRenderer, CCLayerImp
if (useMask) {
if (useAA) {
const MaskProgramAA* program = layerRenderer->renderSurfaceMaskProgramAA();
drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, layerQuad, program, program->fragmentShader().maskSamplerLocation(), program->vertexShader().pointLocation(), program->fragmentShader().edgeLocation());
drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, deviceRect, layerQuad, program, program->fragmentShader().maskSamplerLocation(), program->vertexShader().pointLocation(), program->fragmentShader().edgeLocation());
} else {
const MaskProgram* program = layerRenderer->renderSurfaceMaskProgram();
drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, layerQuad, program, program->fragmentShader().maskSamplerLocation(), -1, -1);
drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, deviceRect, layerQuad, program, program->fragmentShader().maskSamplerLocation(), -1, -1);
}
} else {
if (useAA) {
const ProgramAA* program = layerRenderer->renderSurfaceProgramAA();
drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, layerQuad, program, -1, program->vertexShader().pointLocation(), program->fragmentShader().edgeLocation());
drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, deviceRect, layerQuad, program, -1, program->vertexShader().pointLocation(), program->fragmentShader().edgeLocation());
} else {
const Program* program = layerRenderer->renderSurfaceProgram();
drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, layerQuad, program, -1, -1, -1);
drawSurface(layerRenderer, maskLayer, drawTransform, deviceMatrix, deviceRect, layerQuad, program, -1, -1, -1);
}
}
}
template <class T>
void CCRenderSurface::drawSurface(LayerRendererChromium* layerRenderer, CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad& layerQuad, const T* program, int shaderMaskSamplerLocation, int shaderQuadLocation, int shaderEdgeLocation)
void CCRenderSurface::drawSurface(LayerRendererChromium* layerRenderer, CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad& deviceRect, const CCLayerQuad& layerQuad, const T* program, int shaderMaskSamplerLocation, int shaderQuadLocation, int shaderEdgeLocation)
{
GraphicsContext3D* context3D = layerRenderer->context();
......@@ -194,9 +197,10 @@ void CCRenderSurface::drawSurface(LayerRendererChromium* layerRenderer, CCLayerI
}
if (shaderEdgeLocation != -1) {
float edge[12];
float edge[24];
layerQuad.toFloatArray(edge);
GLC(context3D, context3D->uniform3fv(shaderEdgeLocation, edge, 4));
deviceRect.toFloatArray(&edge[12]);
GLC(context3D, context3D->uniform3fv(shaderEdgeLocation, edge, 8));
}
// Map device space quad to layer space.
......
......@@ -100,7 +100,7 @@ public:
private:
void drawLayer(LayerRendererChromium*, CCLayerImpl*, const TransformationMatrix&);
template <class T>
void drawSurface(LayerRendererChromium*, CCLayerImpl*, const TransformationMatrix& drawTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad&, const T* program, int shaderMaskSamplerLocation, int shaderQuadLocation, int shaderEdgeLocation);
void drawSurface(LayerRendererChromium*, CCLayerImpl*, const TransformationMatrix& drawTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad& deviceRect, const CCLayerQuad&, const T* program, int shaderMaskSamplerLocation, int shaderQuadLocation, int shaderEdgeLocation);
CCLayerImpl* m_owningLayer;
CCLayerImpl* m_maskLayer;
......
......@@ -106,6 +106,7 @@ void CCTiledLayerImpl::draw(LayerRendererChromium* layerRenderer)
return;
FloatQuad quad = deviceMatrix.mapQuad(FloatQuad(layerRect));
CCLayerQuad deviceRect = CCLayerQuad(FloatQuad(quad.boundingBox()));
CCLayerQuad layerQuad = CCLayerQuad(quad);
#if defined(OS_CHROMEOS)
......@@ -116,8 +117,10 @@ void CCTiledLayerImpl::draw(LayerRendererChromium* layerRenderer)
bool useAA = (m_tiler->hasBorderTexels() && (!quad.isRectilinear() || !quad.boundingBox().isExpressibleAsIntRect()));
#endif
if (useAA)
if (useAA) {
deviceRect.inflateAntiAliasingDistance();
layerQuad.inflateAntiAliasingDistance();
}
GraphicsContext3D* context = layerRenderer->context();
if (isNonCompositedContent()) {
......@@ -129,19 +132,19 @@ void CCTiledLayerImpl::draw(LayerRendererChromium* layerRenderer)
case LayerTextureUpdater::SampledTexelFormatRGBA:
if (useAA) {
const ProgramAA* program = layerRenderer->tilerProgramAA();
drawTiles(layerRenderer, layerRect, m_tilingTransform, deviceMatrix, layerQuad, drawOpacity(), program, program->fragmentShader().fragmentTexTransformLocation(), program->fragmentShader().edgeLocation());
drawTiles(layerRenderer, layerRect, m_tilingTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, program->fragmentShader().fragmentTexTransformLocation(), program->fragmentShader().edgeLocation());
} else {
const Program* program = layerRenderer->tilerProgram();
drawTiles(layerRenderer, layerRect, m_tilingTransform, deviceMatrix, layerQuad, drawOpacity(), program, -1, -1);
drawTiles(layerRenderer, layerRect, m_tilingTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
}
break;
case LayerTextureUpdater::SampledTexelFormatBGRA:
if (useAA) {
const ProgramSwizzleAA* program = layerRenderer->tilerProgramSwizzleAA();
drawTiles(layerRenderer, layerRect, m_tilingTransform, deviceMatrix, layerQuad, drawOpacity(), program, program->fragmentShader().fragmentTexTransformLocation(), program->fragmentShader().edgeLocation());
drawTiles(layerRenderer, layerRect, m_tilingTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, program->fragmentShader().fragmentTexTransformLocation(), program->fragmentShader().edgeLocation());
} else {
const ProgramSwizzle* program = layerRenderer->tilerProgramSwizzle();
drawTiles(layerRenderer, layerRect, m_tilingTransform, deviceMatrix, layerQuad, drawOpacity(), program, -1, -1);
drawTiles(layerRenderer, layerRect, m_tilingTransform, deviceMatrix, deviceRect, layerQuad, drawOpacity(), program, -1, -1);
}
break;
default:
......@@ -172,7 +175,7 @@ void CCTiledLayerImpl::syncTextureId(int i, int j, Platform3DObject textureId)
}
template <class T>
void CCTiledLayerImpl::drawTiles(LayerRendererChromium* layerRenderer, const IntRect& contentRect, const TransformationMatrix& globalTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad& contentQuad, float opacity, const T* program, int fragmentTexTransformLocation, int edgeLocation)
void CCTiledLayerImpl::drawTiles(LayerRendererChromium* layerRenderer, const IntRect& contentRect, const TransformationMatrix& globalTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad& deviceRect, const CCLayerQuad& contentQuad, float opacity, const T* program, int fragmentTexTransformLocation, int edgeLocation)
{
GraphicsContext3D* context = layerRenderer->context();
GLC(context, context->useProgram(program->program()));
......@@ -182,9 +185,10 @@ void CCTiledLayerImpl::drawTiles(LayerRendererChromium* layerRenderer, const Int
TransformationMatrix quadTransform = deviceTransform.inverse();
if (edgeLocation != -1) {
float edge[12];
float edge[24];
contentQuad.toFloatArray(edge);
GLC(context, context->uniform3fv(edgeLocation, edge, 4));
deviceRect.toFloatArray(&edge[12]);
GLC(context, context->uniform3fv(edgeLocation, edge, 8));
}
CCLayerQuad::Edge prevEdgeY = contentQuad.top();
......
......@@ -77,7 +77,7 @@ private:
// Draw all tiles that intersect with contentRect.
template <class T>
void drawTiles(LayerRendererChromium*, const IntRect& contentRect, const TransformationMatrix& globalTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad&, float opacity, const T* program, int fragmentTexTransformLocation, int edgeLocation);
void drawTiles(LayerRendererChromium*, const IntRect& contentRect, const TransformationMatrix& globalTransform, const TransformationMatrix& deviceTransform, const CCLayerQuad& deviceRect, const CCLayerQuad& contentQuad, float opacity, const T* program, int fragmentTexTransformLocation, int edgeLocation);
TransformationMatrix m_tilingTransform;
bool m_skipsDraw;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment