Commit 46b79d53 authored by enne@chromium.org's avatar enne@chromium.org

cc: Fix precision loss causing AA quads

By changing 1.f to 1.0, this allows the inverse contents
scale to cancel out properly in the transformation matrix.

BUG=259154

Review URL: https://chromiumcodereview.appspot.com/23572033

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221889 0039d316-1c4b-4281-b951-d872f2087c98
parent 917405ee
...@@ -1142,11 +1142,12 @@ static void SolidColorUniformLocation(T program, ...@@ -1142,11 +1142,12 @@ static void SolidColorUniformLocation(T program,
uniforms->color_location = program->fragment_shader().color_location(); uniforms->color_location = program->fragment_shader().color_location();
} }
// static
bool GLRenderer::SetupQuadForAntialiasing( bool GLRenderer::SetupQuadForAntialiasing(
const gfx::Transform& device_transform, const gfx::Transform& device_transform,
const DrawQuad* quad, const DrawQuad* quad,
gfx::QuadF* local_quad, gfx::QuadF* local_quad,
float edge[24]) const { float edge[24]) {
gfx::Rect tile_rect = quad->visible_rect; gfx::Rect tile_rect = quad->visible_rect;
bool clipped = false; bool clipped = false;
...@@ -1157,11 +1158,8 @@ bool GLRenderer::SetupQuadForAntialiasing( ...@@ -1157,11 +1158,8 @@ bool GLRenderer::SetupQuadForAntialiasing(
bool is_nearest_rect_within_epsilon = is_axis_aligned_in_target && bool is_nearest_rect_within_epsilon = is_axis_aligned_in_target &&
gfx::IsNearestRectWithinDistance(device_layer_quad.BoundingBox(), gfx::IsNearestRectWithinDistance(device_layer_quad.BoundingBox(),
kAntiAliasingEpsilon); kAntiAliasingEpsilon);
// AAing clipped quads is not supported by the code yet.
bool use_aa = Settings().allow_antialiasing && bool use_aa = !clipped && !is_nearest_rect_within_epsilon && quad->IsEdge();
!clipped && // code can't handle clipped quads
!is_nearest_rect_within_epsilon &&
quad->IsEdge();
if (!use_aa) if (!use_aa)
return false; return false;
...@@ -1250,8 +1248,9 @@ void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame, ...@@ -1250,8 +1248,9 @@ void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect)); gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
float edge[24]; float edge[24];
bool use_aa = !quad->force_anti_aliasing_off && SetupQuadForAntialiasing( bool use_aa =
device_transform, quad, &local_quad, edge); Settings().allow_antialiasing && !quad->force_anti_aliasing_off &&
SetupQuadForAntialiasing(device_transform, quad, &local_quad, edge);
SolidColorProgramUniforms uniforms; SolidColorProgramUniforms uniforms;
if (use_aa) if (use_aa)
...@@ -1389,7 +1388,7 @@ void GLRenderer::DrawContentQuad(const DrawingFrame* frame, ...@@ -1389,7 +1388,7 @@ void GLRenderer::DrawContentQuad(const DrawingFrame* frame,
gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect)); gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
float edge[24]; float edge[24];
bool use_aa = SetupQuadForAntialiasing( bool use_aa = Settings().allow_antialiasing && SetupQuadForAntialiasing(
device_transform, quad, &local_quad, edge); device_transform, quad, &local_quad, edge);
TileProgramUniforms uniforms; TileProgramUniforms uniforms;
......
...@@ -124,6 +124,17 @@ class CC_EXPORT GLRenderer : public DirectRenderer { ...@@ -124,6 +124,17 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
scoped_ptr<CopyOutputRequest> request) OVERRIDE; scoped_ptr<CopyOutputRequest> request) OVERRIDE;
virtual void FinishDrawingQuadList() OVERRIDE; virtual void FinishDrawingQuadList() OVERRIDE;
// Check if quad needs antialiasing and if so, inflate the quad and
// fill edge array for fragment shader. local_quad is set to
// inflated quad if antialiasing is required, otherwise it is left
// unchanged. edge array is filled with inflated quad's edge data
// if antialiasing is required, otherwise it is left unchanged.
// Returns true if quad requires antialiasing and false otherwise.
static bool SetupQuadForAntialiasing(const gfx::Transform& device_transform,
const DrawQuad* quad,
gfx::QuadF* local_quad,
float edge[24]);
private: private:
friend class GLRendererShaderPixelTest; friend class GLRendererShaderPixelTest;
friend class GLRendererShaderTest; friend class GLRendererShaderTest;
...@@ -174,17 +185,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer { ...@@ -174,17 +185,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
const gfx::Transform& draw_matrix, const gfx::Transform& draw_matrix,
bool flip_vertically); bool flip_vertically);
// Check if quad needs antialiasing and if so, inflate the quad and
// fill edge array for fragment shader. local_quad is set to
// inflated quad if antialiasing is required, otherwise it is left
// unchanged. edge array is filled with inflated quad's edge data
// if antialiasing is required, otherwise it is left unchanged.
// Returns true if quad requires antialiasing and false otherwise.
bool SetupQuadForAntialiasing(const gfx::Transform& device_transform,
const DrawQuad* quad,
gfx::QuadF* local_quad,
float edge[24]) const;
bool UseScopedTexture(DrawingFrame* frame, bool UseScopedTexture(DrawingFrame* frame,
const ScopedResource* resource, const ScopedResource* resource,
gfx::Rect viewport_rect); gfx::Rect viewport_rect);
......
...@@ -1409,8 +1409,9 @@ static void CalculateDrawPropertiesInternal( ...@@ -1409,8 +1409,9 @@ static void CalculateDrawPropertiesInternal(
// case, the render_surface re-parents the transforms. // case, the render_surface re-parents the transforms.
layer_draw_properties.target_space_transform = combined_transform; layer_draw_properties.target_space_transform = combined_transform;
// M[draw] = M[parent] * LT * S[layer2content] // M[draw] = M[parent] * LT * S[layer2content]
layer_draw_properties.target_space_transform.Scale layer_draw_properties.target_space_transform.Scale(
(1.f / layer->contents_scale_x(), 1.f / layer->contents_scale_y()); SK_MScalar1 / layer->contents_scale_x(),
SK_MScalar1 / layer->contents_scale_y());
// The layer's screen_space_transform represents the transform between root // The layer's screen_space_transform represents the transform between root
// layer's "screen space" and local content space. // layer's "screen space" and local content space.
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h" #include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/fake_picture_pile_impl.h"
#include "cc/test/fake_proxy.h" #include "cc/test/fake_proxy.h"
#include "cc/test/fake_rendering_stats_instrumentation.h" #include "cc/test/fake_rendering_stats_instrumentation.h"
#include "cc/test/fake_video_frame_provider.h" #include "cc/test/fake_video_frame_provider.h"
...@@ -48,6 +50,7 @@ ...@@ -48,6 +50,7 @@
#include "media/base/media.h" #include "media/base/media.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/size_conversions.h" #include "ui/gfx/size_conversions.h"
#include "ui/gfx/vector2d_conversions.h" #include "ui/gfx/vector2d_conversions.h"
...@@ -6157,6 +6160,79 @@ TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) { ...@@ -6157,6 +6160,79 @@ TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) {
} }
} }
class GLRendererWithSetupQuadForAntialiasing : public GLRenderer {
public:
using GLRenderer::SetupQuadForAntialiasing;
};
TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
// Due to precision issues (especially on Android), sometimes far
// away quads can end up thinking they need AA.
float device_scale_factor = 4.f / 3.f;
host_impl_->SetDeviceScaleFactor(device_scale_factor);
gfx::Size root_size(2000, 1000);
gfx::Size device_viewport_size =
gfx::ToCeiledSize(gfx::ScaleSize(root_size, device_scale_factor));
host_impl_->SetViewportSize(device_viewport_size);
host_impl_->CreatePendingTree();
host_impl_->pending_tree()
->SetPageScaleFactorAndLimits(1.f, 1.f / 16.f, 16.f);
scoped_ptr<LayerImpl> scoped_root =
LayerImpl::Create(host_impl_->pending_tree(), 1);
LayerImpl* root = scoped_root.get();
host_impl_->pending_tree()->SetRootLayer(scoped_root.Pass());
scoped_ptr<LayerImpl> scoped_scrolling_layer =
LayerImpl::Create(host_impl_->pending_tree(), 2);
LayerImpl* scrolling_layer = scoped_scrolling_layer.get();
root->AddChild(scoped_scrolling_layer.Pass());
gfx::Size content_layer_bounds(100000, 100);
gfx::Size pile_tile_size(3000, 3000);
scoped_refptr<FakePicturePileImpl> pile(FakePicturePileImpl::CreateFilledPile(
pile_tile_size, content_layer_bounds));
scoped_ptr<FakePictureLayerImpl> scoped_content_layer =
FakePictureLayerImpl::CreateWithPile(host_impl_->pending_tree(), 3, pile);
LayerImpl* content_layer = scoped_content_layer.get();
scrolling_layer->AddChild(scoped_content_layer.PassAs<LayerImpl>());
content_layer->SetBounds(content_layer_bounds);
content_layer->SetDrawsContent(true);
root->SetBounds(root_size);
gfx::Vector2d scroll_offset(100000, 0);
scrolling_layer->SetScrollable(true);
scrolling_layer->SetMaxScrollOffset(scroll_offset);
scrolling_layer->SetScrollOffset(scroll_offset);
host_impl_->ActivatePendingTree();
host_impl_->active_tree()->UpdateDrawProperties();
ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size());
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
const DrawQuad* quad = frame.render_passes[0]->quad_list[0];
float edge[24];
gfx::QuadF device_layer_quad;
bool antialiased =
GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing(
quad->quadTransform(), quad, &device_layer_quad, edge);
EXPECT_FALSE(antialiased);
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
}
class CompositorFrameMetadataTest : public LayerTreeHostImplTest { class CompositorFrameMetadataTest : public LayerTreeHostImplTest {
public: public:
CompositorFrameMetadataTest() CompositorFrameMetadataTest()
......
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