1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "cc/test/pixel_test.h" 6 7#include "base/command_line.h" 8#include "base/message_loop/message_loop_proxy.h" 9#include "base/path_service.h" 10#include "base/run_loop.h" 11#include "cc/base/switches.h" 12#include "cc/output/compositor_frame_metadata.h" 13#include "cc/output/copy_output_request.h" 14#include "cc/output/copy_output_result.h" 15#include "cc/output/gl_renderer.h" 16#include "cc/output/output_surface_client.h" 17#include "cc/output/software_renderer.h" 18#include "cc/resources/raster_worker_pool.h" 19#include "cc/resources/resource_provider.h" 20#include "cc/resources/texture_mailbox_deleter.h" 21#include "cc/test/fake_output_surface_client.h" 22#include "cc/test/paths.h" 23#include "cc/test/pixel_test_output_surface.h" 24#include "cc/test/pixel_test_software_output_device.h" 25#include "cc/test/pixel_test_utils.h" 26#include "cc/test/test_in_process_context_provider.h" 27#include "cc/test/test_shared_bitmap_manager.h" 28#include "testing/gtest/include/gtest/gtest.h" 29 30namespace cc { 31 32PixelTest::PixelTest() 33 : device_viewport_size_(gfx::Size(200, 200)), 34 disable_picture_quad_image_filtering_(false), 35 output_surface_client_(new FakeOutputSurfaceClient) {} 36 37PixelTest::~PixelTest() {} 38 39bool PixelTest::RunPixelTest(RenderPassList* pass_list, 40 const base::FilePath& ref_file, 41 const PixelComparator& comparator) { 42 return RunPixelTestWithReadbackTarget(pass_list, 43 pass_list->back(), 44 ref_file, 45 comparator); 46} 47 48bool PixelTest::RunPixelTestWithReadbackTarget( 49 RenderPassList* pass_list, 50 RenderPass* target, 51 const base::FilePath& ref_file, 52 const PixelComparator& comparator) { 53 base::RunLoop run_loop; 54 55 target->copy_requests.push_back(CopyOutputRequest::CreateBitmapRequest( 56 base::Bind(&PixelTest::ReadbackResult, 57 base::Unretained(this), 58 run_loop.QuitClosure()))); 59 60 float device_scale_factor = 1.f; 61 gfx::Rect device_viewport_rect = 62 gfx::Rect(device_viewport_size_) + external_device_viewport_offset_; 63 gfx::Rect device_clip_rect = external_device_clip_rect_.IsEmpty() 64 ? device_viewport_rect 65 : external_device_clip_rect_; 66 renderer_->DecideRenderPassAllocationsForFrame(*pass_list); 67 renderer_->DrawFrame(pass_list, 68 device_scale_factor, 69 device_viewport_rect, 70 device_clip_rect, 71 disable_picture_quad_image_filtering_); 72 73 // Wait for the readback to complete. 74 resource_provider_->Finish(); 75 run_loop.Run(); 76 77 return PixelsMatchReference(ref_file, comparator); 78} 79 80void PixelTest::ReadbackResult(base::Closure quit_run_loop, 81 scoped_ptr<CopyOutputResult> result) { 82 ASSERT_TRUE(result->HasBitmap()); 83 result_bitmap_ = result->TakeBitmap().Pass(); 84 quit_run_loop.Run(); 85} 86 87bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file, 88 const PixelComparator& comparator) { 89 base::FilePath test_data_dir; 90 if (!PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir)) 91 return false; 92 93 // If this is false, we didn't set up a readback on a render pass. 94 if (!result_bitmap_) 95 return false; 96 97 CommandLine* cmd = CommandLine::ForCurrentProcess(); 98 if (cmd->HasSwitch(switches::kCCRebaselinePixeltests)) 99 return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true); 100 101 return MatchesPNGFile( 102 *result_bitmap_, test_data_dir.Append(ref_file), comparator); 103} 104 105void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) { 106 enable_pixel_output_.reset(new gfx::DisableNullDrawGLBindings); 107 108 output_surface_.reset( 109 new PixelTestOutputSurface(new TestInProcessContextProvider)); 110 output_surface_->BindToClient(output_surface_client_.get()); 111 112 shared_bitmap_manager_.reset(new TestSharedBitmapManager()); 113 resource_provider_ = ResourceProvider::Create( 114 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, false); 115 116 texture_mailbox_deleter_ = make_scoped_ptr( 117 new TextureMailboxDeleter(base::MessageLoopProxy::current())); 118 119 renderer_ = GLRenderer::Create(this, 120 &settings_, 121 output_surface_.get(), 122 resource_provider_.get(), 123 texture_mailbox_deleter_.get(), 124 0).PassAs<DirectRenderer>(); 125} 126 127void PixelTest::ForceExpandedViewport(const gfx::Size& surface_expansion) { 128 static_cast<PixelTestOutputSurface*>(output_surface_.get()) 129 ->set_surface_expansion_size(surface_expansion); 130 SoftwareOutputDevice* device = output_surface_->software_device(); 131 if (device) { 132 static_cast<PixelTestSoftwareOutputDevice*>(device) 133 ->set_surface_expansion_size(surface_expansion); 134 } 135} 136 137void PixelTest::ForceViewportOffset(const gfx::Vector2d& viewport_offset) { 138 external_device_viewport_offset_ = viewport_offset; 139} 140 141void PixelTest::ForceDeviceClip(const gfx::Rect& clip) { 142 external_device_clip_rect_ = clip; 143} 144 145void PixelTest::EnableExternalStencilTest() { 146 static_cast<PixelTestOutputSurface*>(output_surface_.get()) 147 ->set_has_external_stencil_test(true); 148} 149 150void PixelTest::RunOnDemandRasterTask(Task* on_demand_raster_task) { 151 TaskGraphRunner task_graph_runner; 152 NamespaceToken on_demand_task_namespace = 153 task_graph_runner.GetNamespaceToken(); 154 155 // Construct a task graph that contains this single raster task. 156 TaskGraph graph; 157 graph.nodes.push_back( 158 TaskGraph::Node(on_demand_raster_task, 159 RasterWorkerPool::kOnDemandRasterTaskPriority, 160 0u)); 161 162 // Schedule task and wait for task graph runner to finish running it. 163 task_graph_runner.ScheduleTasks(on_demand_task_namespace, &graph); 164 task_graph_runner.RunUntilIdle(); 165 166 // Collect task now that it has finished running. 167 Task::Vector completed_tasks; 168 task_graph_runner.CollectCompletedTasks(on_demand_task_namespace, 169 &completed_tasks); 170 DCHECK_EQ(1u, completed_tasks.size()); 171 DCHECK_EQ(completed_tasks[0], on_demand_raster_task); 172} 173 174void PixelTest::SetUpSoftwareRenderer() { 175 scoped_ptr<SoftwareOutputDevice> device(new PixelTestSoftwareOutputDevice()); 176 output_surface_.reset(new PixelTestOutputSurface(device.Pass())); 177 output_surface_->BindToClient(output_surface_client_.get()); 178 shared_bitmap_manager_.reset(new TestSharedBitmapManager()); 179 resource_provider_ = ResourceProvider::Create( 180 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, false); 181 renderer_ = 182 SoftwareRenderer::Create( 183 this, &settings_, output_surface_.get(), resource_provider_.get()) 184 .PassAs<DirectRenderer>(); 185} 186 187} // namespace cc 188