diff options
-rw-r--r-- | cc/output/renderer_pixeltest.cc | 250 | ||||
-rw-r--r-- | cc/resources/picture_pile_impl_unittest.cc | 27 | ||||
-rw-r--r-- | cc/test/fake_content_layer_client.cc | 19 | ||||
-rw-r--r-- | cc/test/fake_content_layer_client.h | 4 | ||||
-rw-r--r-- | cc/test/fake_picture_pile_impl.cc | 9 | ||||
-rw-r--r-- | cc/test/fake_picture_pile_impl.h | 6 |
6 files changed, 281 insertions, 34 deletions
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc index 8dc6316..a24a5b3 100644 --- a/cc/output/renderer_pixeltest.cc +++ b/cc/output/renderer_pixeltest.cc @@ -6,13 +6,17 @@ #include "cc/layers/append_quads_data.h" #include "cc/output/gl_renderer.h" #include "cc/quads/draw_quad.h" +#include "cc/quads/picture_draw_quad.h" +#include "cc/resources/platform_color.h" #include "cc/resources/sync_point_helper.h" +#include "cc/test/fake_picture_pile_impl.h" #include "cc/test/pixel_test.h" #include "gpu/GLES2/gl2extchromium.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" #include "third_party/skia/include/effects/SkColorMatrixFilter.h" +#include "ui/gfx/rect_conversions.h" namespace cc { namespace { @@ -55,6 +59,24 @@ scoped_ptr<SharedQuadState> CreateTestSharedQuadState( return shared_state.Pass(); } +scoped_ptr<SharedQuadState> CreateTestSharedQuadStateClipped( + gfx::Transform content_to_target_transform, + gfx::Rect rect, + gfx::Rect clip_rect) { + const gfx::Size content_bounds = rect.size(); + const gfx::Rect visible_content_rect = clip_rect; + const bool is_clipped = true; + const float opacity = 1.0f; + scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create(); + shared_state->SetAll(content_to_target_transform, + content_bounds, + visible_content_rect, + clip_rect, + is_clipped, + opacity); + return shared_state.Pass(); +} + scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad( SharedQuadState* shared_state, gfx::Rect rect, RenderPass::Id pass_id) { scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create(); @@ -680,7 +702,233 @@ TEST_F(GLRendererPixelTest, SignalSyncPoint) { EXPECT_EQ(1, sync_point_callback_count); EXPECT_EQ(1, other_callback_count); } -#endif + +TEST_F(GLRendererPixelTest, PictureDrawQuadIdentityScale) { + gfx::Size pile_tile_size(1000, 1000); + gfx::Rect viewport(this->device_viewport_size_); + // TODO(enne): the renderer should figure this out on its own. + bool contents_swizzled = !PlatformColor::SameComponentOrder(GL_RGBA); + + RenderPass::Id id(1, 1); + gfx::Transform transform_to_root; + scoped_ptr<RenderPass> pass = + CreateTestRenderPass(id, viewport, transform_to_root); + + // One clipped blue quad in the lower right corner. Outside the clip + // is red, which should not appear. + gfx::Rect blue_rect(gfx::Size(100, 100)); + gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50)); + scoped_refptr<FakePicturePileImpl> blue_pile = + FakePicturePileImpl::CreateFilledPile(pile_tile_size, blue_rect.size()); + SkPaint red_paint; + red_paint.setColor(SK_ColorRED); + blue_pile->add_draw_rect_with_paint(blue_rect, red_paint); + SkPaint blue_paint; + blue_paint.setColor(SK_ColorBLUE); + blue_pile->add_draw_rect_with_paint(blue_clip_rect, blue_paint); + blue_pile->RerecordPile(); + + gfx::Transform blue_content_to_target_transform; + gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right()); + blue_content_to_target_transform.Translate(offset.x(), offset.y()); + gfx::RectF blue_scissor_rect = blue_clip_rect; + blue_content_to_target_transform.TransformRect(&blue_scissor_rect); + scoped_ptr<SharedQuadState> blue_shared_state = + CreateTestSharedQuadStateClipped(blue_content_to_target_transform, + blue_rect, + gfx::ToEnclosingRect(blue_scissor_rect)); + + scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create(); + + blue_quad->SetNew(blue_shared_state.get(), + viewport, // Intentionally bigger than clip. + gfx::Rect(), + viewport, + viewport.size(), + contents_swizzled, + viewport, + 1.f, + blue_pile); + pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>()); + + // One viewport-filling green quad. + scoped_refptr<FakePicturePileImpl> green_pile = + FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); + SkPaint green_paint; + green_paint.setColor(SK_ColorGREEN); + green_pile->add_draw_rect_with_paint(viewport, green_paint); + green_pile->RerecordPile(); + + gfx::Transform green_content_to_target_transform; + scoped_ptr<SharedQuadState> green_shared_state = + CreateTestSharedQuadState(green_content_to_target_transform, viewport); + + scoped_ptr<PictureDrawQuad> green_quad = PictureDrawQuad::Create(); + green_quad->SetNew(green_shared_state.get(), + viewport, + gfx::Rect(), + gfx::RectF(0.f, 0.f, 1.f, 1.f), + viewport.size(), + contents_swizzled, + viewport, + 1.f, + green_pile); + pass->quad_list.push_back(green_quad.PassAs<DrawQuad>()); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + + EXPECT_TRUE(this->RunPixelTest( + &pass_list, + base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")), + ExactPixelComparator(true))); +} + +TEST_F(GLRendererPixelTest, PictureDrawQuadNonIdentityScale) { + gfx::Size pile_tile_size(1000, 1000); + gfx::Rect viewport(gfx::Size(200, 200)); + // TODO(enne): the renderer should figure this out on its own. + bool contents_swizzled = !PlatformColor::SameComponentOrder(GL_RGBA); + + RenderPass::Id id(1, 1); + gfx::Transform transform_to_root; + scoped_ptr<RenderPass> pass = + CreateTestRenderPass(id, viewport, transform_to_root); + + // As scaling up the blue checkerboards will cause sampling on the GPU, + // a few extra "cleanup rects" need to be added to clobber the blending + // to make the output image more clean. This will also test subrects + // of the layer. + gfx::Transform green_content_to_target_transform; + gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100)); + gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20)); + scoped_refptr<FakePicturePileImpl> green_pile = + FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); + SkPaint red_paint; + red_paint.setColor(SK_ColorRED); + green_pile->add_draw_rect_with_paint(viewport, red_paint); + SkPaint green_paint; + green_paint.setColor(SK_ColorGREEN); + green_pile->add_draw_rect_with_paint(green_rect1, green_paint); + green_pile->add_draw_rect_with_paint(green_rect2, green_paint); + green_pile->RerecordPile(); + + scoped_ptr<SharedQuadState> top_right_green_shared_quad_state = + CreateTestSharedQuadState(green_content_to_target_transform, viewport); + + scoped_ptr<PictureDrawQuad> green_quad1 = PictureDrawQuad::Create(); + green_quad1->SetNew(top_right_green_shared_quad_state.get(), + green_rect1, + gfx::Rect(), + green_rect1, + green_rect1.size(), + contents_swizzled, + green_rect1, + 1.f, + green_pile); + pass->quad_list.push_back(green_quad1.PassAs<DrawQuad>()); + + scoped_ptr<PictureDrawQuad> green_quad2 = PictureDrawQuad::Create(); + green_quad2->SetNew(top_right_green_shared_quad_state.get(), + green_rect2, + gfx::Rect(), + green_rect2, + green_rect2.size(), + contents_swizzled, + green_rect2, + 1.f, + green_pile); + pass->quad_list.push_back(green_quad2.PassAs<DrawQuad>()); + + // Add a green clipped checkerboard in the bottom right to help test + // interleaving picture quad content and solid color content. + gfx::Rect bottom_right_rect( + gfx::Point(viewport.width() / 2, viewport.height() / 2), + gfx::Size(viewport.width() / 2, viewport.height() / 2)); + scoped_ptr<SharedQuadState> bottom_right_green_shared_state = + CreateTestSharedQuadStateClipped( + green_content_to_target_transform, viewport, bottom_right_rect); + scoped_ptr<SolidColorDrawQuad> bottom_right_color_quad = + SolidColorDrawQuad::Create(); + bottom_right_color_quad->SetNew( + bottom_right_green_shared_state.get(), viewport, SK_ColorGREEN); + pass->quad_list.push_back(bottom_right_color_quad.PassAs<DrawQuad>()); + + // Add two blue checkerboards taking up the bottom left and top right, + // but use content scales as content rects to make this happen. + // The content is at a 4x content scale. + gfx::Rect layer_rect(gfx::Size(20, 30)); + float contents_scale = 4.f; + // Two rects that touch at their corners, arbitrarily placed in the layer. + gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f)); + gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f)); + gfx::RectF union_layer_rect = blue_layer_rect1; + union_layer_rect.Union(blue_layer_rect2); + + // Because scaling up will cause sampling outside the rects, add one extra + // pixel of buffer at the final content scale. + float inset = -1.f / contents_scale; + blue_layer_rect1.Inset(inset, inset, inset, inset); + blue_layer_rect2.Inset(inset, inset, inset, inset); + + scoped_refptr<FakePicturePileImpl> pile = + FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_rect.size()); + pile->add_draw_rect_with_paint(layer_rect, red_paint); + SkPaint transparent_paint; + transparent_paint.setXfermodeMode(SkXfermode::kClear_Mode); + pile->add_draw_rect_with_paint(union_layer_rect, transparent_paint); + SkPaint blue_paint; + blue_paint.setColor(SK_ColorBLUE); + pile->add_draw_rect_with_paint(blue_layer_rect1, blue_paint); + pile->add_draw_rect_with_paint(blue_layer_rect2, blue_paint); + pile->RerecordPile(); + + gfx::Rect content_rect( + gfx::ToEnclosingRect(gfx::ScaleRect(layer_rect, contents_scale))); + gfx::Rect content_union_rect( + gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale))); + + // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels, + // so scale an additional 10x to make them 100x100. + gfx::Transform content_to_target_transform; + content_to_target_transform.Scale(10.0, 10.0); + gfx::Rect quad_content_rect(gfx::Size(20, 20)); + scoped_ptr<SharedQuadState> blue_shared_state = + CreateTestSharedQuadState(content_to_target_transform, quad_content_rect); + + scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create(); + blue_quad->SetNew(blue_shared_state.get(), + quad_content_rect, + gfx::Rect(), + quad_content_rect, + content_union_rect.size(), + contents_swizzled, + content_union_rect, + contents_scale, + pile); + pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>()); + + // Fill left half of viewport with green. + gfx::Transform half_green_content_to_target_transform; + gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height())); + scoped_ptr<SharedQuadState> half_green_shared_state = + CreateTestSharedQuadState(half_green_content_to_target_transform, + half_green_rect); + scoped_ptr<SolidColorDrawQuad> half_color_quad = SolidColorDrawQuad::Create(); + half_color_quad->SetNew( + half_green_shared_state.get(), half_green_rect, SK_ColorGREEN); + pass->quad_list.push_back(half_color_quad.PassAs<DrawQuad>()); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + + EXPECT_TRUE(this->RunPixelTest( + &pass_list, + base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), + ExactPixelComparator(true))); +} + +#endif // !defined(OS_ANDROID) } // namespace } // namespace cc diff --git a/cc/resources/picture_pile_impl_unittest.cc b/cc/resources/picture_pile_impl_unittest.cc index 1f622c3..5a31538 100644 --- a/cc/resources/picture_pile_impl_unittest.cc +++ b/cc/resources/picture_pile_impl_unittest.cc @@ -68,15 +68,6 @@ void CreateBitmap(gfx::Size size, const char* uri, SkBitmap* bitmap) { bitmap->setPixelRef(lazy_pixel_ref); } -void RerecordPile(scoped_refptr<FakePicturePileImpl> pile) { - for (int y = 0; y < pile->num_tiles_y(); ++y) { - for (int x = 0; x < pile->num_tiles_x(); ++x) { - pile->RemoveRecordingAt(x, y); - pile->AddRecordingAt(x, y); - } - } -} - TEST(PicturePileImplTest, AnalyzeIsSolidUnscaled) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(400, 400); @@ -93,7 +84,7 @@ TEST(PicturePileImplTest, AnalyzeIsSolidUnscaled) { non_solid_paint.setColor(non_solid_color); pile->add_draw_rect_with_paint(gfx::Rect(0, 0, 400, 400), solid_paint); - RerecordPile(pile); + pile->RerecordPile(); // Ensure everything is solid for (int y = 0; y <= 300; y += 100) { @@ -108,7 +99,7 @@ TEST(PicturePileImplTest, AnalyzeIsSolidUnscaled) { // One pixel non solid pile->add_draw_rect_with_paint(gfx::Rect(50, 50, 1, 1), non_solid_paint); - RerecordPile(pile); + pile->RerecordPile(); PicturePileImpl::Analysis analysis; pile->AnalyzeInRect(gfx::Rect(0, 0, 100, 100), 1.0, &analysis); @@ -151,7 +142,7 @@ TEST(PicturePileImplTest, AnalyzeIsSolidScaled) { non_solid_paint.setColor(non_solid_color); pile->add_draw_rect_with_paint(gfx::Rect(0, 0, 400, 400), solid_paint); - RerecordPile(pile); + pile->RerecordPile(); // Ensure everything is solid for (int y = 0; y <= 30; y += 10) { @@ -166,7 +157,7 @@ TEST(PicturePileImplTest, AnalyzeIsSolidScaled) { // One pixel non solid pile->add_draw_rect_with_paint(gfx::Rect(50, 50, 1, 1), non_solid_paint); - RerecordPile(pile); + pile->RerecordPile(); PicturePileImpl::Analysis analysis; pile->AnalyzeInRect(gfx::Rect(0, 0, 10, 10), 0.1f, &analysis); @@ -290,7 +281,7 @@ TEST(PicturePileImplTest, PixelRefIteratorNoLazyRefs) { pile->add_draw_bitmap(non_lazy_bitmap, gfx::Point(0, 128)); pile->add_draw_bitmap(non_lazy_bitmap, gfx::Point(150, 150)); - RerecordPile(pile); + pile->RerecordPile(); // Tile sized iterators. { @@ -382,7 +373,7 @@ TEST(PicturePileImplTest, PixelRefIteratorLazyRefs) { pile->add_draw_bitmap(lazy_bitmap[1][0], gfx::Point(0, 130)); pile->add_draw_bitmap(lazy_bitmap[1][1], gfx::Point(140, 140)); - RerecordPile(pile); + pile->RerecordPile(); // Tile sized iterators. These should find only one pixel ref. { @@ -512,7 +503,7 @@ TEST(PicturePileImplTest, PixelRefIteratorLazyRefsOneTile) { pile->add_draw_bitmap(lazy_bitmap[0][1], gfx::Point(260, 0)); pile->add_draw_bitmap(lazy_bitmap[1][1], gfx::Point(260, 260)); - RerecordPile(pile); + pile->RerecordPile(); // Tile sized iterators. These should find only one pixel ref. { @@ -670,7 +661,7 @@ TEST(PicturePileImplTest, PixelRefIteratorLazyRefsBaseNonLazy) { pile->add_draw_bitmap(lazy_bitmap[0][1], gfx::Point(260, 0)); pile->add_draw_bitmap(lazy_bitmap[1][1], gfx::Point(260, 260)); - RerecordPile(pile); + pile->RerecordPile(); // Tile sized iterators. These should find only one pixel ref. { @@ -805,7 +796,7 @@ TEST(PicturePileImplTest, PixelRefIteratorMultiplePictures) { // || |x|| // ||=======|| pile->add_draw_bitmap(non_lazy_bitmap, gfx::Point(0, 0)); - RerecordPile(pile); + pile->RerecordPile(); FakeContentLayerClient content_layer_clients[2][2]; scoped_refptr<Picture> pictures[2][2]; diff --git a/cc/test/fake_content_layer_client.cc b/cc/test/fake_content_layer_client.cc index 280459b..16033b7 100644 --- a/cc/test/fake_content_layer_client.cc +++ b/cc/test/fake_content_layer_client.cc @@ -17,21 +17,20 @@ FakeContentLayerClient::~FakeContentLayerClient() { } void FakeContentLayerClient::PaintContents(SkCanvas* canvas, - gfx::Rect rect, gfx::RectF* opaque_rect) { + gfx::Rect paint_rect, gfx::RectF* opaque_rect) { if (paint_all_opaque_) - *opaque_rect = rect; + *opaque_rect = paint_rect; - canvas->clipRect(gfx::RectToSkRect(rect)); + canvas->clipRect(gfx::RectToSkRect(paint_rect)); for (RectPaintVector::const_iterator it = draw_rects_.begin(); it != draw_rects_.end(); ++it) { - gfx::Rect rect = it->first; + const gfx::RectF& draw_rect = it->first; const SkPaint& paint = it->second; - SkRect draw_rect = SkRect::MakeXYWH( - rect.x(), - rect.y(), - rect.width(), - rect.height()); - canvas->drawRect(draw_rect, paint); + canvas->drawRectCoords(draw_rect.x(), + draw_rect.y(), + draw_rect.right(), + draw_rect.bottom(), + paint); } for (BitmapVector::const_iterator it = draw_bitmaps_.begin(); diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h index dfc8ce7..ff42855 100644 --- a/cc/test/fake_content_layer_client.h +++ b/cc/test/fake_content_layer_client.h @@ -28,7 +28,7 @@ class FakeContentLayerClient : public cc::ContentLayerClient { void set_paint_all_opaque(bool opaque) { paint_all_opaque_ = opaque; } - void add_draw_rect(gfx::Rect rect, const SkPaint& paint) { + void add_draw_rect(const gfx::RectF& rect, const SkPaint& paint) { draw_rects_.push_back(std::make_pair(rect, paint)); } @@ -37,7 +37,7 @@ class FakeContentLayerClient : public cc::ContentLayerClient { } private: - typedef std::vector<std::pair<gfx::Rect, SkPaint> > RectPaintVector; + typedef std::vector<std::pair<gfx::RectF, SkPaint> > RectPaintVector; typedef std::vector<std::pair<SkBitmap, gfx::Point> > BitmapVector; bool paint_all_opaque_; diff --git a/cc/test/fake_picture_pile_impl.cc b/cc/test/fake_picture_pile_impl.cc index 9c58313..15c1d17 100644 --- a/cc/test/fake_picture_pile_impl.cc +++ b/cc/test/fake_picture_pile_impl.cc @@ -80,4 +80,13 @@ void FakePicturePileImpl::RemoveRecordingAt(int x, int y) { UpdateRecordedRegion(); } +void FakePicturePileImpl::RerecordPile() { + for (int y = 0; y < num_tiles_y(); ++y) { + for (int x = 0; x < num_tiles_x(); ++x) { + RemoveRecordingAt(x, y); + AddRecordingAt(x, y); + } + } +} + } // namespace cc diff --git a/cc/test/fake_picture_pile_impl.h b/cc/test/fake_picture_pile_impl.h index 057376d..bedc6ce 100644 --- a/cc/test/fake_picture_pile_impl.h +++ b/cc/test/fake_picture_pile_impl.h @@ -24,15 +24,15 @@ class FakePicturePileImpl : public PicturePileImpl { TilingData& tiling() { return tiling_; } void AddRecordingAt(int x, int y); - void RemoveRecordingAt(int x, int y); + void RerecordPile(); void AddPictureToRecording( int x, int y, scoped_refptr<Picture> picture); - void add_draw_rect(gfx::Rect rect) { + void add_draw_rect(const gfx::RectF& rect) { client_.add_draw_rect(rect, default_paint_); } @@ -40,7 +40,7 @@ class FakePicturePileImpl : public PicturePileImpl { client_.add_draw_bitmap(bitmap, point); } - void add_draw_rect_with_paint(gfx::Rect rect, const SkPaint& paint) { + void add_draw_rect_with_paint(const gfx::RectF& rect, const SkPaint& paint) { client_.add_draw_rect(rect, paint); } |