diff options
-rw-r--r-- | cc/cc_tests.gyp | 2 | ||||
-rw-r--r-- | cc/layers/layer_impl.cc | 16 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 3 | ||||
-rw-r--r-- | cc/output/copy_output_request.cc | 1 | ||||
-rw-r--r-- | cc/output/copy_output_request.h | 22 | ||||
-rw-r--r-- | cc/output/gl_renderer.cc | 9 | ||||
-rw-r--r-- | cc/output/software_renderer.cc | 14 | ||||
-rw-r--r-- | cc/test/layer_tree_pixel_test.cc | 50 | ||||
-rw-r--r-- | cc/test/layer_tree_pixel_test.h | 15 | ||||
-rw-r--r-- | cc/test/solid_color_content_layer_client.cc | 29 | ||||
-rw-r--r-- | cc/test/solid_color_content_layer_client.h | 30 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 3 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_pixeltest_filters.cc | 12 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_pixeltest_masks.cc | 36 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc | 4 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_pixeltest_readback.cc | 623 |
16 files changed, 734 insertions, 135 deletions
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index 4661766..0a57347 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -163,6 +163,8 @@ 'test/render_pass_test_utils.h', 'test/scheduler_test_common.cc', 'test/scheduler_test_common.h', + 'test/solid_color_content_layer_client.h', + 'test/solid_color_content_layer_client.cc', 'test/skia_common.cc', 'test/skia_common.h', 'test/test_web_graphics_context_3d.cc', diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 8fa41b5..8aecda1 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -114,12 +114,26 @@ void LayerImpl::PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) { NoteLayerPropertyChangedForSubtree(); } -void LayerImpl::TakeCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests) { +void LayerImpl::TakeCopyRequestsAndTransformToTarget( + ScopedPtrVector<CopyOutputRequest>* requests) { if (copy_requests_.empty()) return; requests->insert_and_take(requests->end(), copy_requests_); copy_requests_.clear(); + + for (size_t i = 0; i < requests->size(); ++i) { + CopyOutputRequest* request = requests->at(i); + if (!request->has_area()) + continue; + + gfx::Rect request_in_layer_space = request->area(); + gfx::Rect request_in_content_space = + LayerRectToContentRect(request_in_layer_space); + request->set_area( + MathUtil::MapClippedRect(draw_properties_.target_space_transform, + request_in_content_space)); + } } void LayerImpl::CreateRenderSurface() { diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 7645d9f..170fc78 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -84,7 +84,8 @@ class CC_EXPORT LayerImpl : LayerAnimationValueObserver { void ClearChildList(); void PassCopyRequests(ScopedPtrVector<CopyOutputRequest>* requests); - void TakeCopyRequests(ScopedPtrVector<CopyOutputRequest>* request); + void TakeCopyRequestsAndTransformToTarget( + ScopedPtrVector<CopyOutputRequest>* request); bool HasCopyRequest() const { return !copy_requests_.empty(); } void SetMaskLayer(scoped_ptr<LayerImpl> mask_layer); diff --git a/cc/output/copy_output_request.cc b/cc/output/copy_output_request.cc index 90ece04..341d887 100644 --- a/cc/output/copy_output_request.cc +++ b/cc/output/copy_output_request.cc @@ -19,6 +19,7 @@ CopyOutputRequest::CopyOutputRequest( bool force_bitmap_result, const CopyOutputRequestCallback& result_callback) : force_bitmap_result_(force_bitmap_result), + has_area_(false), result_callback_(result_callback) { } diff --git a/cc/output/copy_output_request.h b/cc/output/copy_output_request.h index 54fff1a..b7eb0b4 100644 --- a/cc/output/copy_output_request.h +++ b/cc/output/copy_output_request.h @@ -8,7 +8,7 @@ #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" -#include "ui/gfx/size.h" +#include "ui/gfx/rect.h" class SkBitmap; @@ -35,15 +35,29 @@ class CC_EXPORT CopyOutputRequest { static scoped_ptr<CopyOutputRequest> CreateRelayRequest( const CopyOutputRequest& original_request, const CopyOutputRequestCallback& result_callback) { - return make_scoped_ptr(new CopyOutputRequest( - original_request.force_bitmap_result(), result_callback)); + scoped_ptr<CopyOutputRequest> relay = CreateRequest(result_callback); + relay->force_bitmap_result_ = original_request.force_bitmap_result_; + relay->has_area_ = original_request.has_area_; + relay->area_ = original_request.area_; + return relay.Pass(); } ~CopyOutputRequest(); bool IsEmpty() const { return result_callback_.is_null(); } + bool force_bitmap_result() const { return force_bitmap_result_; } + // By default copy requests copy the entire layer's subtree output. If an + // area is given, then the intersection of this rect (in layer space) with + // the layer's subtree output will be returned. + void set_area(gfx::Rect area) { + has_area_ = true; + area_ = area; + } + bool has_area() const { return has_area_; } + gfx::Rect area() const { return area_; } + void SendResult(scoped_ptr<CopyOutputResult> result); void SendBitmapResult(scoped_ptr<SkBitmap> bitmap); void SendTextureResult(gfx::Size size, @@ -60,6 +74,8 @@ class CC_EXPORT CopyOutputRequest { const CopyOutputRequestCallback& result_callback); bool force_bitmap_result_; + bool has_area_; + gfx::Rect area_; CopyOutputRequestCallback result_callback_; }; diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 2a27ff7..3527ed1 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -1914,8 +1914,13 @@ void GLRenderer::EnsureScissorTestDisabled() { void GLRenderer::CopyCurrentRenderPassToBitmap( DrawingFrame* frame, scoped_ptr<CopyOutputRequest> request) { - GetFramebufferPixelsAsync(frame->current_render_pass->output_rect, - request.Pass()); + gfx::Rect copy_rect = frame->current_render_pass->output_rect; + if (request->has_area()) { + // Intersect with the request's area, positioned with its origin at the + // origin of the full copy_rect. + copy_rect.Intersect(request->area() - copy_rect.OffsetFromOrigin()); + } + GetFramebufferPixelsAsync(copy_rect, request.Pass()); } void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) { diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index 3cf1f6a..4b604a8 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -456,12 +456,20 @@ void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame, void SoftwareRenderer::CopyCurrentRenderPassToBitmap( DrawingFrame* frame, scoped_ptr<CopyOutputRequest> request) { + gfx::Rect copy_rect = frame->current_render_pass->output_rect; + if (request->has_area()) { + // Intersect with the request's area, positioned with its origin at the + // origin of the full copy_rect. + copy_rect.Intersect(request->area() - copy_rect.OffsetFromOrigin()); + } + gfx::Rect window_copy_rect = MoveFromDrawToWindowSpace(copy_rect); + scoped_ptr<SkBitmap> bitmap(new SkBitmap); bitmap->setConfig(SkBitmap::kARGB_8888_Config, - current_viewport_rect_.width(), - current_viewport_rect_.height()); + window_copy_rect.width(), + window_copy_rect.height()); current_canvas_->readPixels( - bitmap.get(), current_viewport_rect_.x(), current_viewport_rect_.y()); + bitmap.get(), window_copy_rect.x(), window_copy_rect.y()); request->SendBitmapResult(bitmap.Pass()); } diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index 3d757ca..b948302 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc @@ -21,7 +21,8 @@ namespace cc { LayerTreePixelTest::LayerTreePixelTest() - : pixel_comparator_(new ExactPixelComparator(true)), use_gl_(true) {} + : pixel_comparator_(new ExactPixelComparator(true)), + test_type_(GL_WITH_DEFAULT) {} LayerTreePixelTest::~LayerTreePixelTest() {} @@ -30,23 +31,32 @@ scoped_ptr<OutputSurface> LayerTreePixelTest::CreateOutputSurface() { gfx::Size surface_expansion_size(40, 60); scoped_ptr<PixelTestOutputSurface> output_surface; - if (!use_gl_) { - scoped_ptr<PixelTestSoftwareOutputDevice> software_output_device( - new PixelTestSoftwareOutputDevice); - software_output_device->set_surface_expansion_size(surface_expansion_size); - output_surface = make_scoped_ptr( - new PixelTestOutputSurface( - software_output_device.PassAs<SoftwareOutputDevice>())); - } else { - CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL)); - - using WebKit::WebGraphicsContext3D; - using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl; - scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d( - WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext( - WebGraphicsContext3D::Attributes())); - output_surface = make_scoped_ptr( - new PixelTestOutputSurface(context3d.PassAs<WebGraphicsContext3D>())); + switch (test_type_) { + case SOFTWARE_WITH_DEFAULT: + case SOFTWARE_WITH_BITMAP: { + scoped_ptr<PixelTestSoftwareOutputDevice> software_output_device( + new PixelTestSoftwareOutputDevice); + software_output_device->set_surface_expansion_size( + surface_expansion_size); + output_surface = make_scoped_ptr( + new PixelTestOutputSurface( + software_output_device.PassAs<SoftwareOutputDevice>())); + break; + } + + case GL_WITH_DEFAULT: + case GL_WITH_BITMAP: { + CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL)); + + using WebKit::WebGraphicsContext3D; + using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl; + scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d( + WebGraphicsContext3DInProcessCommandBufferImpl:: + CreateOffscreenContext(WebGraphicsContext3D::Attributes())); + output_surface = make_scoped_ptr( + new PixelTestOutputSurface(context3d.PassAs<WebGraphicsContext3D>())); + break; + } } output_surface->set_viewport_offset(viewport_offset); @@ -141,8 +151,10 @@ scoped_refptr<SolidColorLayer> LayerTreePixelTest:: } void LayerTreePixelTest::RunPixelTest( + PixelTestType test_type, scoped_refptr<Layer> content_root, base::FilePath file_name) { + test_type_ = test_type; content_root_ = content_root; readback_target_ = NULL; ref_file_ = file_name; @@ -150,9 +162,11 @@ void LayerTreePixelTest::RunPixelTest( } void LayerTreePixelTest::RunPixelTestWithReadbackTarget( + PixelTestType test_type, scoped_refptr<Layer> content_root, Layer* target, base::FilePath file_name) { + test_type_ = test_type; content_root_ = content_root; readback_target_ = target; ref_file_ = file_name; diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h index b485237..72c14d5 100644 --- a/cc/test/layer_tree_pixel_test.h +++ b/cc/test/layer_tree_pixel_test.h @@ -47,10 +47,19 @@ class LayerTreePixelTest : public LayerTreeTest { int border_width, SkColor border_color); - void RunPixelTest(scoped_refptr<Layer> content_root, + enum PixelTestType { + GL_WITH_DEFAULT, + GL_WITH_BITMAP, + SOFTWARE_WITH_DEFAULT, + SOFTWARE_WITH_BITMAP + }; + + void RunPixelTest(PixelTestType type, + scoped_refptr<Layer> content_root, base::FilePath file_name); - void RunPixelTestWithReadbackTarget(scoped_refptr<Layer> content_root, + void RunPixelTestWithReadbackTarget(PixelTestType type, + scoped_refptr<Layer> content_root, Layer* target, base::FilePath file_name); @@ -68,7 +77,7 @@ class LayerTreePixelTest : public LayerTreeTest { scoped_ptr<PixelComparator> pixel_comparator_; protected: - bool use_gl_; + PixelTestType test_type_; scoped_refptr<Layer> content_root_; Layer* readback_target_; base::FilePath ref_file_; diff --git a/cc/test/solid_color_content_layer_client.cc b/cc/test/solid_color_content_layer_client.cc new file mode 100644 index 0000000..2d84947 --- /dev/null +++ b/cc/test/solid_color_content_layer_client.cc @@ -0,0 +1,29 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/test/solid_color_content_layer_client.h" + +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/rect_f.h" + +namespace cc { + +void SolidColorContentLayerClient::PaintContents( + SkCanvas* canvas, gfx::Rect rect, gfx::RectF* opaque_rect) { + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(color_); + + canvas->clear(SK_ColorTRANSPARENT); + canvas->drawRect( + SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()), + paint); + + if (SkColorGetA(color_) == 255) + *opaque_rect = rect; +} + +} // namespace cc diff --git a/cc/test/solid_color_content_layer_client.h b/cc/test/solid_color_content_layer_client.h new file mode 100644 index 0000000..ad7c0f0 --- /dev/null +++ b/cc/test/solid_color_content_layer_client.h @@ -0,0 +1,30 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_TEST_SOLID_COLOR_CONTENT_LAYER_CLIENT_H_ +#define CC_TEST_SOLID_COLOR_CONTENT_LAYER_CLIENT_H_ + +#include "base/compiler_specific.h" +#include "cc/layers/content_layer_client.h" +#include "third_party/skia/include/core/SkColor.h" + +namespace cc { + +class SolidColorContentLayerClient : public cc::ContentLayerClient { + public: + explicit SolidColorContentLayerClient(SkColor color) : color_(color) {} + + // ContentLayerClient implementation. + virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} + virtual void PaintContents(SkCanvas* canvas, + gfx::Rect rect, + gfx::RectF* opaque_rect) OVERRIDE; + + private: + SkColor color_; +}; + +} // namespace cc + +#endif // CC_TEST_SOLID_COLOR_CONTENT_LAYER_CLIENT_H_ diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index bbae5e7..eb079c9 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -641,7 +641,8 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { if (it.represents_target_render_surface()) { if (it->HasCopyRequest()) { have_copy_request = true; - it->TakeCopyRequests(&target_render_pass->copy_requests); + it->TakeCopyRequestsAndTransformToTarget( + &target_render_pass->copy_requests); } } else if (it.represents_contributing_render_surface()) { RenderPass::Id contributing_render_pass_id = diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc index 3c7e346..70b6dcd 100644 --- a/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -30,9 +30,9 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) { filters.append(WebKit::WebFilterOperation::createBlurFilter(2)); blur->SetBackgroundFilters(filters); - RunPixelTest(background, - base::FilePath(FILE_PATH_LITERAL( - "background_filter_blur.png"))); + RunPixelTest(GL_WITH_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("background_filter_blur.png"))); } TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) { @@ -55,7 +55,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) { filters.append(WebKit::WebFilterOperation::createBlurFilter(5)); blur->SetBackgroundFilters(filters); - RunPixelTest(background, + RunPixelTest(GL_WITH_BITMAP, + background, base::FilePath(FILE_PATH_LITERAL( "background_filter_blur_outsets.png"))); } @@ -108,7 +109,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) { small_error_allowed)); #endif - RunPixelTest(background, + RunPixelTest(GL_WITH_BITMAP, + background, base::FilePath(FILE_PATH_LITERAL( "background_filter_blur_off_axis.png"))); } diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc index ff3555d..afeaae7 100644 --- a/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -57,9 +57,9 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskOfLayer) { mask->SetIsMask(true); green->SetMaskLayer(mask.get()); - RunPixelTest(background, - base::FilePath(FILE_PATH_LITERAL( - "mask_of_layer.png"))); + RunPixelTest(GL_WITH_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png"))); } TEST_F(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { @@ -87,9 +87,9 @@ TEST_F(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { green->SetMaskLayer(mask.get()); background->AddChild(green); - RunPixelTest(background, - base::FilePath(FILE_PATH_LITERAL( - "image_mask_of_layer.png"))); + RunPixelTest(GL_WITH_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png"))); } TEST_F(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { @@ -115,9 +115,9 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { mask->SetIsMask(true); green->SetMaskLayer(mask.get()); - RunPixelTest(background, - base::FilePath(FILE_PATH_LITERAL( - "mask_of_clipped_layer.png"))); + RunPixelTest(GL_WITH_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("mask_of_clipped_layer.png"))); } TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplica) { @@ -144,9 +144,9 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplica) { replica->SetTransform(replica_transform); green->SetReplicaLayer(replica.get()); - RunPixelTest(background, - base::FilePath(FILE_PATH_LITERAL( - "mask_with_replica.png"))); + RunPixelTest(GL_WITH_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("mask_with_replica.png"))); } TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) { @@ -182,7 +182,8 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) { replica->SetTransform(replica_transform); green->SetReplicaLayer(replica.get()); - RunPixelTest(background, + RunPixelTest(GL_WITH_BITMAP, + background, base::FilePath(FILE_PATH_LITERAL( "mask_with_replica_of_clipped_layer.png"))); } @@ -216,9 +217,9 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplica) { replica->SetMaskLayer(mask.get()); green->SetReplicaLayer(replica.get()); - RunPixelTest(background, - base::FilePath(FILE_PATH_LITERAL( - "mask_of_replica.png"))); + RunPixelTest(GL_WITH_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("mask_of_replica.png"))); } TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) { @@ -258,7 +259,8 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) { replica->SetMaskLayer(mask.get()); green->SetReplicaLayer(replica.get()); - RunPixelTest(background, + RunPixelTest(GL_WITH_BITMAP, + background, base::FilePath(FILE_PATH_LITERAL( "mask_of_replica_of_clipped_layer.png"))); } diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc index eb2e28c..8a67c65 100644 --- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc +++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc @@ -99,7 +99,9 @@ TEST_F(LayerTreeHostOnDemandRasterPixelTest, RasterPictureLayer) { layer->SetBounds(layer_rect.size()); layer->SetPosition(layer_rect.origin()); - RunPixelTest(layer, base::FilePath(FILE_PATH_LITERAL("blue_yellow.png"))); + RunPixelTest(GL_WITH_BITMAP, + layer, + base::FilePath(FILE_PATH_LITERAL("blue_yellow.png"))); } } // namespace diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc index cd59ed5..6c8b094d 100644 --- a/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/cc/trees/layer_tree_host_pixeltest_readback.cc @@ -3,10 +3,13 @@ // found in the LICENSE file. #include "build/build_config.h" +#include "cc/layers/content_layer.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" #include "cc/test/layer_tree_pixel_test.h" #include "cc/test/paths.h" +#include "cc/test/solid_color_content_layer_client.h" +#include "cc/trees/layer_tree_impl.h" #if !defined(OS_ANDROID) @@ -15,24 +18,31 @@ namespace { class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest { protected: - LayerTreeHostReadbackPixelTest() : force_readback_as_bitmap_(false) {} - virtual scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest() OVERRIDE { - if (force_readback_as_bitmap_) { - return CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, - base::Unretained(this))); - } - - if (!use_gl_) { - return CopyOutputRequest::CreateRequest( - base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, - base::Unretained(this))); + scoped_ptr<CopyOutputRequest> request; + + switch (test_type_) { + case GL_WITH_BITMAP: + case SOFTWARE_WITH_BITMAP: + request = CopyOutputRequest::CreateBitmapRequest( + base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, + base::Unretained(this))); + break; + case SOFTWARE_WITH_DEFAULT: + request = CopyOutputRequest::CreateRequest( + base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, + base::Unretained(this))); + break; + case GL_WITH_DEFAULT: + request = CopyOutputRequest::CreateRequest( + base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture, + base::Unretained(this))); + break; } - return CopyOutputRequest::CreateRequest( - base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture, - base::Unretained(this))); + if (!copy_subrect_.IsEmpty()) + request->set_area(copy_subrect_); + return request.Pass(); } void ReadbackResultAsBitmap(scoped_ptr<CopyOutputResult> result) { @@ -55,13 +65,10 @@ class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest { texture_mailbox->RunReleaseCallback(0, false); } - bool force_readback_as_bitmap_; + gfx::Rect copy_subrect_; }; TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software) { - use_gl_ = false; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -69,15 +76,13 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software) { gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTest(background, + RunPixelTest(SOFTWARE_WITH_DEFAULT, + background, base::FilePath(FILE_PATH_LITERAL( "green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software_Bitmap) { - use_gl_ = false; - force_readback_as_bitmap_ = true; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -85,15 +90,13 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software_Bitmap) { gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTest(background, + RunPixelTest(SOFTWARE_WITH_BITMAP, + background, base::FilePath(FILE_PATH_LITERAL( "green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL_Bitmap) { - use_gl_ = true; - force_readback_as_bitmap_ = true; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -101,15 +104,13 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL_Bitmap) { gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTest(background, + RunPixelTest(GL_WITH_BITMAP, + background, base::FilePath(FILE_PATH_LITERAL( "green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL) { - use_gl_ = true; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -117,16 +118,14 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL) { gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTest(background, + RunPixelTest(GL_WITH_DEFAULT, + background, base::FilePath(FILE_PATH_LITERAL( "green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_Software) { - use_gl_ = false; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -138,15 +137,13 @@ TEST_F(LayerTreeHostReadbackPixelTest, gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTest(background, + RunPixelTest(SOFTWARE_WITH_DEFAULT, + background, base::FilePath(FILE_PATH_LITERAL( "green_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL_Bitmap) { - use_gl_ = true; - force_readback_as_bitmap_ = true; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -158,15 +155,13 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL_Bitmap) { gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTest(background, + RunPixelTest(GL_WITH_BITMAP, + background, base::FilePath(FILE_PATH_LITERAL( "green_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL) { - use_gl_ = true; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -178,15 +173,13 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL) { gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTest(background, + RunPixelTest(GL_WITH_DEFAULT, + background, base::FilePath(FILE_PATH_LITERAL( "green_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_Software) { - use_gl_ = false; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -194,16 +187,14 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_Software) { gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL_Bitmap) { - use_gl_ = true; - force_readback_as_bitmap_ = true; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -211,16 +202,14 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL_Bitmap) { gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL) { - use_gl_ = true; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -228,7 +217,8 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL) { gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green.png"))); @@ -236,9 +226,6 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL) { TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_Software) { - use_gl_ = false; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -246,16 +233,14 @@ TEST_F(LayerTreeHostReadbackPixelTest, gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green_small.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL_Bitmap) { - use_gl_ = true; - force_readback_as_bitmap_ = true; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -263,16 +248,14 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL_Bitmap) { gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green_small.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL) { - use_gl_ = true; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -280,7 +263,8 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL) { gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green_small.png"))); @@ -288,9 +272,6 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL) { TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_Software) { - use_gl_ = false; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -302,7 +283,8 @@ TEST_F(LayerTreeHostReadbackPixelTest, gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green_small_with_blue_corner.png"))); @@ -310,9 +292,6 @@ TEST_F(LayerTreeHostReadbackPixelTest, TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_GL_Bitmap) { - use_gl_ = true; - force_readback_as_bitmap_ = true; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -324,16 +303,14 @@ TEST_F(LayerTreeHostReadbackPixelTest, gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_GL) { - use_gl_ = true; - force_readback_as_bitmap_ = false; - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -345,7 +322,493 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_GL) { gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTestWithReadbackTarget(background, + RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_Software) { + scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorGREEN); + background->AddChild(green); + + scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( + gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + green->AddChild(blue); + + // Grab the middle of the root layer. + copy_subrect_ = gfx::Rect(50, 50, 100, 100); + + RunPixelTest(SOFTWARE_WITH_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_GL_Bitmap) { + scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorGREEN); + background->AddChild(green); + + scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( + gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + green->AddChild(blue); + + // Grab the middle of the root layer. + copy_subrect_ = gfx::Rect(50, 50, 100, 100); + + RunPixelTest(GL_WITH_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_GL) { + scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorGREEN); + background->AddChild(green); + + scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( + gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + green->AddChild(blue); + + // Grab the middle of the root layer. + copy_subrect_ = gfx::Rect(50, 50, 100, 100); + + RunPixelTest(GL_WITH_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_Software) { + scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( + gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); + background->AddChild(green); + + scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( + gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); + green->AddChild(blue); + + // Grab the middle of the green layer. + copy_subrect_ = gfx::Rect(25, 25, 100, 100); + + RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_GL_Bitmap) { + scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( + gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); + background->AddChild(green); + + scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( + gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); + green->AddChild(blue); + + // Grab the middle of the green layer. + copy_subrect_ = gfx::Rect(25, 25, 100, 100); + + RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_GL) { + scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( + gfx::Rect(200, 200), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( + gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); + background->AddChild(green); + + scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( + gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); + green->AddChild(blue); + + // Grab the middle of the green layer. + copy_subrect_ = gfx::Rect(25, 25, 100, 100); + + RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +class LayerTreeHostReadbackDeviceScalePixelTest + : public LayerTreeHostReadbackPixelTest { + protected: + LayerTreeHostReadbackDeviceScalePixelTest() + : device_scale_factor_(1.f), + white_client_(SK_ColorWHITE), + green_client_(SK_ColorGREEN), + blue_client_(SK_ColorBLUE) {} + + virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + // Cause the device scale factor to be inherited by contents scales. + settings->layer_transforms_should_scale_layer_contents = true; + } + + virtual void SetupTree() OVERRIDE { + layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_); + LayerTreePixelTest::SetupTree(); + } + + virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + LayerImpl* root_impl = host_impl->active_tree()->root_layer(); + + LayerImpl* background_impl = root_impl->children()[0]; + EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_x()); + EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_y()); + + LayerImpl* green_impl = background_impl->children()[0]; + EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_x()); + EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_y()); + + LayerImpl* blue_impl = green_impl->children()[0]; + EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_x()); + EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_y()); + } + + float device_scale_factor_; + SolidColorContentLayerClient white_client_; + SolidColorContentLayerClient green_client_; + SolidColorContentLayerClient blue_client_; +}; + +TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, + ReadbackSubrect_Software) { + scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + background->SetAnchorPoint(gfx::PointF()); + background->SetBounds(gfx::Size(100, 100)); + background->SetIsDrawable(true); + + scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + green->SetAnchorPoint(gfx::PointF()); + green->SetBounds(gfx::Size(100, 100)); + green->SetIsDrawable(true); + background->AddChild(green); + + scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + blue->SetAnchorPoint(gfx::PointF()); + blue->SetPosition(gfx::Point(50, 50)); + blue->SetBounds(gfx::Size(25, 25)); + blue->SetIsDrawable(true); + green->AddChild(blue); + + // Grab the middle of the root layer. + copy_subrect_ = gfx::Rect(25, 25, 50, 50); + device_scale_factor_ = 2.f; + + RunPixelTest(SOFTWARE_WITH_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, + ReadbackSubrect_GL) { + scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + background->SetAnchorPoint(gfx::PointF()); + background->SetBounds(gfx::Size(100, 100)); + background->SetIsDrawable(true); + + scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + green->SetAnchorPoint(gfx::PointF()); + green->SetBounds(gfx::Size(100, 100)); + green->SetIsDrawable(true); + background->AddChild(green); + + scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + blue->SetAnchorPoint(gfx::PointF()); + blue->SetPosition(gfx::Point(50, 50)); + blue->SetBounds(gfx::Size(25, 25)); + blue->SetIsDrawable(true); + green->AddChild(blue); + + // Grab the middle of the root layer. + copy_subrect_ = gfx::Rect(25, 25, 50, 50); + device_scale_factor_ = 2.f; + + RunPixelTest(GL_WITH_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, + ReadbackNonRootLayerSubrect_Software) { + scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + background->SetAnchorPoint(gfx::PointF()); + background->SetBounds(gfx::Size(100, 100)); + background->SetIsDrawable(true); + + scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + green->SetAnchorPoint(gfx::PointF()); + green->SetPosition(gfx::Point(10, 20)); + green->SetBounds(gfx::Size(90, 80)); + green->SetIsDrawable(true); + background->AddChild(green); + + scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + blue->SetAnchorPoint(gfx::PointF()); + blue->SetPosition(gfx::Point(50, 50)); + blue->SetBounds(gfx::Size(25, 25)); + blue->SetIsDrawable(true); + green->AddChild(blue); + + // Grab the green layer's content with blue in the bottom right. + copy_subrect_ = gfx::Rect(25, 25, 50, 50); + device_scale_factor_ = 2.f; + + RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, + ReadbackNonRootLayerSubrect_GL) { + scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + background->SetAnchorPoint(gfx::PointF()); + background->SetBounds(gfx::Size(100, 100)); + background->SetIsDrawable(true); + + scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + green->SetAnchorPoint(gfx::PointF()); + green->SetPosition(gfx::Point(10, 20)); + green->SetBounds(gfx::Size(90, 80)); + green->SetIsDrawable(true); + background->AddChild(green); + + scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + blue->SetAnchorPoint(gfx::PointF()); + blue->SetPosition(gfx::Point(50, 50)); + blue->SetBounds(gfx::Size(25, 25)); + blue->SetIsDrawable(true); + green->AddChild(blue); + + // Grab the green layer's content with blue in the bottom right. + copy_subrect_ = gfx::Rect(25, 25, 50, 50); + device_scale_factor_ = 2.f; + + RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +class LayerTreeHostReadbackViaCompositeAndReadbackPixelTest + : public LayerTreePixelTest { + protected: + LayerTreeHostReadbackViaCompositeAndReadbackPixelTest() + : device_scale_factor_(1.f), + white_client_(SK_ColorWHITE), + green_client_(SK_ColorGREEN), + blue_client_(SK_ColorBLUE) {} + + virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + // Cause the device scale factor to be inherited by contents scales. + settings->layer_transforms_should_scale_layer_contents = true; + } + + virtual void SetupTree() OVERRIDE { + layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_); + LayerTreePixelTest::SetupTree(); + } + + virtual void BeginTest() OVERRIDE { + EXPECT_EQ(device_scale_factor_, layer_tree_host()->device_scale_factor()); + if (TestEnded()) + return; + + gfx::Rect device_viewport_copy_rect( + layer_tree_host()->device_viewport_size()); + if (!device_viewport_copy_subrect_.IsEmpty()) + device_viewport_copy_rect.Intersect(device_viewport_copy_subrect_); + + scoped_ptr<SkBitmap> bitmap(new SkBitmap); + bitmap->setConfig(SkBitmap::kARGB_8888_Config, + device_viewport_copy_rect.width(), + device_viewport_copy_rect.height()); + bitmap->allocPixels(); + { + scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap)); + layer_tree_host()->CompositeAndReadback(bitmap->getPixels(), + device_viewport_copy_rect); + } + + result_bitmap_ = bitmap.Pass(); + EndTest(); + } + + virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + LayerImpl* root_impl = host_impl->active_tree()->root_layer(); + + LayerImpl* background_impl = root_impl->children()[0]; + EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_x()); + EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_y()); + + LayerImpl* green_impl = background_impl->children()[0]; + EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_x()); + EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_y()); + + LayerImpl* blue_impl = green_impl->children()[0]; + EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_x()); + EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_y()); + } + + gfx::Rect device_viewport_copy_subrect_; + float device_scale_factor_; + SolidColorContentLayerClient white_client_; + SolidColorContentLayerClient green_client_; + SolidColorContentLayerClient blue_client_; +}; + +TEST_F(LayerTreeHostReadbackViaCompositeAndReadbackPixelTest, + CompositeAndReadback_Software_1) { + scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + background->SetAnchorPoint(gfx::PointF()); + background->SetBounds(gfx::Size(200, 200)); + background->SetIsDrawable(true); + + scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + green->SetAnchorPoint(gfx::PointF()); + green->SetBounds(gfx::Size(200, 200)); + green->SetIsDrawable(true); + background->AddChild(green); + + scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + blue->SetAnchorPoint(gfx::PointF()); + blue->SetPosition(gfx::Point(100, 100)); + blue->SetBounds(gfx::Size(50, 50)); + blue->SetIsDrawable(true); + green->AddChild(blue); + + // Grab the middle of the device viewport. + device_viewport_copy_subrect_ = gfx::Rect(50, 50, 100, 100); + device_scale_factor_ = 1.f; + + RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackViaCompositeAndReadbackPixelTest, + CompositeAndReadback_Software_2) { + scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + background->SetAnchorPoint(gfx::PointF()); + background->SetBounds(gfx::Size(100, 100)); + background->SetIsDrawable(true); + + scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + green->SetAnchorPoint(gfx::PointF()); + green->SetBounds(gfx::Size(100, 100)); + green->SetIsDrawable(true); + background->AddChild(green); + + scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + blue->SetAnchorPoint(gfx::PointF()); + blue->SetPosition(gfx::Point(50, 50)); + blue->SetBounds(gfx::Size(25, 25)); + blue->SetIsDrawable(true); + green->AddChild(blue); + + // Grab the middle of the device viewport. + device_viewport_copy_subrect_ = gfx::Rect(50, 50, 100, 100); + device_scale_factor_ = 2.f; + + RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackViaCompositeAndReadbackPixelTest, + CompositeAndReadback_GL_1) { + scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + background->SetAnchorPoint(gfx::PointF()); + background->SetBounds(gfx::Size(200, 200)); + background->SetIsDrawable(true); + + scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + green->SetAnchorPoint(gfx::PointF()); + green->SetBounds(gfx::Size(200, 200)); + green->SetIsDrawable(true); + background->AddChild(green); + + scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + blue->SetAnchorPoint(gfx::PointF()); + blue->SetPosition(gfx::Point(100, 100)); + blue->SetBounds(gfx::Size(50, 50)); + blue->SetIsDrawable(true); + green->AddChild(blue); + + // Grab the middle of the device viewport. + device_viewport_copy_subrect_ = gfx::Rect(50, 50, 100, 100); + device_scale_factor_ = 1.f; + + RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL( + "green_small_with_blue_corner.png"))); +} + +TEST_F(LayerTreeHostReadbackViaCompositeAndReadbackPixelTest, + CompositeAndReadback_GL_2) { + scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + background->SetAnchorPoint(gfx::PointF()); + background->SetBounds(gfx::Size(100, 100)); + background->SetIsDrawable(true); + + scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + green->SetAnchorPoint(gfx::PointF()); + green->SetBounds(gfx::Size(100, 100)); + green->SetIsDrawable(true); + background->AddChild(green); + + scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + blue->SetAnchorPoint(gfx::PointF()); + blue->SetPosition(gfx::Point(50, 50)); + blue->SetBounds(gfx::Size(25, 25)); + blue->SetIsDrawable(true); + green->AddChild(blue); + + // Grab the middle of the device viewport. + device_viewport_copy_subrect_ = gfx::Rect(50, 50, 100, 100); + device_scale_factor_ = 2.f; + + RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, + background, green.get(), base::FilePath(FILE_PATH_LITERAL( "green_small_with_blue_corner.png"))); |