From bc85755e10364fb856bd9af645d096b014a8c414 Mon Sep 17 00:00:00 2001 From: "shawnsingh@chromium.org" Date: Mon, 20 May 2013 23:36:50 +0000 Subject: Do not use antialiasing code path for surfaces if there is a perspective w<0 clipping status At this time, the antialiasing shader does not work when the quad+transform being rendered would have triggered a w<0 clipping issue. This patch adds the condition to prevent antialiasing, and adds a test for this scenario. BUG=237892 Review URL: https://chromiumcodereview.appspot.com/14735012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201169 0039d316-1c4b-4281-b951-d872f2087c98 --- cc/output/gl_renderer.cc | 9 +++--- cc/output/gl_renderer_unittest.cc | 64 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 10 deletions(-) (limited to 'cc/output') diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 34807ff..b3d51ee 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -734,14 +734,14 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, bool clipped = false; gfx::QuadF device_quad = MathUtil::MapQuad( contents_device_transform, SharedGeometryQuad(), &clipped); - DCHECK(!clipped); LayerQuad device_layer_bounds(gfx::QuadF(device_quad.BoundingBox())); LayerQuad device_layer_edges(device_quad); // Use anti-aliasing programs only when necessary. - bool use_aa = (!device_quad.IsRectilinear() || - !gfx::IsNearestRectWithinDistance(device_quad.BoundingBox(), - kAntiAliasingEpsilon)); + bool use_aa = !clipped && + (!device_quad.IsRectilinear() || + !gfx::IsNearestRectWithinDistance(device_quad.BoundingBox(), + kAntiAliasingEpsilon)); if (use_aa) { device_layer_bounds.InflateAntiAliasingDistance(); device_layer_edges.InflateAntiAliasingDistance(); @@ -992,7 +992,6 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, gfx::QuadF surface_quad = MathUtil::MapQuad(contents_device_transform_inverse, device_layer_edges.ToQuadF(), &clipped); - DCHECK(!clipped); SetShaderOpacity(quad->opacity(), shader_alpha_location); SetShaderQuadF(surface_quad, shader_quad_location); diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index 31f2603..2ee3a63 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -6,6 +6,7 @@ #include +#include "cc/base/math_util.h" #include "cc/output/compositor_frame_metadata.h" #include "cc/resources/prioritized_resource_manager.h" #include "cc/resources/resource_provider.h" @@ -336,10 +337,12 @@ class GLRendererShaderTest : public testing::Test { scoped_ptr( new ShaderCreatorMockGraphicsContext()))), resource_provider_(ResourceProvider::Create(output_surface_.get(), 0)), - renderer_(GLRenderer::Create(&mock_client_, - output_surface_.get(), - resource_provider_.get(), - 0)) {} + renderer_(scoped_ptr( + new FakeRendererGL(&mock_client_, + output_surface_.get(), + resource_provider_.get()))) { + renderer_->Initialize(); + } void TestRenderPassProgram() { EXPECT_PROGRAM_VALID(renderer_->render_pass_program_); @@ -398,7 +401,7 @@ class GLRendererShaderTest : public testing::Test { scoped_ptr output_surface_; FakeRendererClient mock_client_; scoped_ptr resource_provider_; - scoped_ptr renderer_; + scoped_ptr renderer_; }; namespace { @@ -1345,6 +1348,57 @@ TEST_F(GLRendererShaderTest, DISABLED_DrawRenderPassQuadShaderPermutations) { TestRenderPassMaskColorMatrixProgramAA(); } +// At this time, the AA code path cannot be taken if the surface's rect would +// project incorrectly by the given transform, because of w<0 clipping. +TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) { + gfx::Rect child_rect(50, 50); + RenderPass::Id child_pass_id(2, 0); + TestRenderPass* child_pass; + + gfx::Rect viewport_rect(mock_client_.DeviceViewportSize()); + RenderPass::Id root_pass_id(1, 0); + TestRenderPass* root_pass; + + gfx::Transform transform_preventing_aa; + transform_preventing_aa.ApplyPerspectiveDepth(40.0); + transform_preventing_aa.RotateAboutYAxis(-20.0); + transform_preventing_aa.Scale(30.0, 1.0); + + // Verify that the test transform and test rect actually do cause the clipped + // flag to trigger. Otherwise we are not testing the intended scenario. + bool clipped = false; + MathUtil::MapQuad(transform_preventing_aa, + gfx::QuadF(child_rect), + &clipped); + ASSERT_TRUE(clipped); + + // Set up the render pass quad to be drawn + ScopedPtrVector* render_passes = + mock_client_.render_passes_in_draw_order(); + + render_passes->clear(); + + child_pass = AddRenderPass( + render_passes, child_pass_id, child_rect, transform_preventing_aa); + + root_pass = AddRenderPass( + render_passes, root_pass_id, viewport_rect, gfx::Transform()); + + AddRenderPassQuad(root_pass, + child_pass, + 0, + skia::RefPtr(), + transform_preventing_aa); + + renderer_->DecideRenderPassAllocationsForFrame( + *mock_client_.render_passes_in_draw_order()); + renderer_->DrawFrame(mock_client_.render_passes_in_draw_order()); + + // If use_aa incorrectly ignores clipping, it will use the + // RenderPassProgramAA shader instead of the RenderPassProgram. + TestRenderPassProgram(); +} + TEST_F(GLRendererShaderTest, DrawSolidColorShader) { gfx::Rect viewport_rect(mock_client_.DeviceViewportSize()); ScopedPtrVector* render_passes = -- cgit v1.1