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 "cc/trees/blocking_task_runner.h" 29 #include "gpu/command_buffer/client/gles2_interface.h" 30 #include "testing/gtest/include/gtest/gtest.h" 31 32 namespace cc { 33 34 PixelTest::PixelTest() 35 : device_viewport_size_(gfx::Size(200, 200)), 36 disable_picture_quad_image_filtering_(false), 37 output_surface_client_(new FakeOutputSurfaceClient), 38 main_thread_task_runner_( 39 BlockingTaskRunner::Create(base::MessageLoopProxy::current())) { 40 } 41 PixelTest::~PixelTest() {} 42 43 bool PixelTest::RunPixelTest(RenderPassList* pass_list, 44 const base::FilePath& ref_file, 45 const PixelComparator& comparator) { 46 return RunPixelTestWithReadbackTarget(pass_list, 47 pass_list->back(), 48 ref_file, 49 comparator); 50 } 51 52 bool PixelTest::RunPixelTestWithReadbackTarget( 53 RenderPassList* pass_list, 54 RenderPass* target, 55 const base::FilePath& ref_file, 56 const PixelComparator& comparator) { 57 base::RunLoop run_loop; 58 59 target->copy_requests.push_back(CopyOutputRequest::CreateBitmapRequest( 60 base::Bind(&PixelTest::ReadbackResult, 61 base::Unretained(this), 62 run_loop.QuitClosure()))); 63 64 float device_scale_factor = 1.f; 65 gfx::Rect device_viewport_rect = 66 gfx::Rect(device_viewport_size_) + external_device_viewport_offset_; 67 gfx::Rect device_clip_rect = external_device_clip_rect_.IsEmpty() 68 ? device_viewport_rect 69 : external_device_clip_rect_; 70 renderer_->DecideRenderPassAllocationsForFrame(*pass_list); 71 renderer_->DrawFrame(pass_list, 72 device_scale_factor, 73 device_viewport_rect, 74 device_clip_rect, 75 disable_picture_quad_image_filtering_); 76 77 // Wait for the readback to complete. 78 if (output_surface_->context_provider()) 79 output_surface_->context_provider()->ContextGL()->Finish(); 80 run_loop.Run(); 81 82 return PixelsMatchReference(ref_file, comparator); 83 } 84 85 void PixelTest::ReadbackResult(base::Closure quit_run_loop, 86 scoped_ptr<CopyOutputResult> result) { 87 ASSERT_TRUE(result->HasBitmap()); 88 result_bitmap_ = result->TakeBitmap().Pass(); 89 quit_run_loop.Run(); 90 } 91 92 bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file, 93 const PixelComparator& comparator) { 94 base::FilePath test_data_dir; 95 if (!PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir)) 96 return false; 97 98 // If this is false, we didn't set up a readback on a render pass. 99 if (!result_bitmap_) 100 return false; 101 102 CommandLine* cmd = CommandLine::ForCurrentProcess(); 103 if (cmd->HasSwitch(switches::kCCRebaselinePixeltests)) 104 return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true); 105 106 return MatchesPNGFile( 107 *result_bitmap_, test_data_dir.Append(ref_file), comparator); 108 } 109 110 void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) { 111 enable_pixel_output_.reset(new gfx::DisableNullDrawGLBindings); 112 113 output_surface_.reset( 114 new PixelTestOutputSurface(new TestInProcessContextProvider)); 115 output_surface_->BindToClient(output_surface_client_.get()); 116 117 shared_bitmap_manager_.reset(new TestSharedBitmapManager()); 118 resource_provider_ = ResourceProvider::Create(output_surface_.get(), 119 shared_bitmap_manager_.get(), 120 main_thread_task_runner_.get(), 121 0, 122 false, 123 1, 124 false); 125 126 texture_mailbox_deleter_ = make_scoped_ptr( 127 new TextureMailboxDeleter(base::MessageLoopProxy::current())); 128 129 renderer_ = GLRenderer::Create(this, 130 &settings_, 131 output_surface_.get(), 132 resource_provider_.get(), 133 texture_mailbox_deleter_.get(), 134 0).PassAs<DirectRenderer>(); 135 } 136 137 void PixelTest::ForceExpandedViewport(const gfx::Size& surface_expansion) { 138 static_cast<PixelTestOutputSurface*>(output_surface_.get()) 139 ->set_surface_expansion_size(surface_expansion); 140 SoftwareOutputDevice* device = output_surface_->software_device(); 141 if (device) { 142 static_cast<PixelTestSoftwareOutputDevice*>(device) 143 ->set_surface_expansion_size(surface_expansion); 144 } 145 } 146 147 void PixelTest::ForceViewportOffset(const gfx::Vector2d& viewport_offset) { 148 external_device_viewport_offset_ = viewport_offset; 149 } 150 151 void PixelTest::ForceDeviceClip(const gfx::Rect& clip) { 152 external_device_clip_rect_ = clip; 153 } 154 155 void PixelTest::EnableExternalStencilTest() { 156 static_cast<PixelTestOutputSurface*>(output_surface_.get()) 157 ->set_has_external_stencil_test(true); 158 } 159 160 void PixelTest::SetUpSoftwareRenderer() { 161 scoped_ptr<SoftwareOutputDevice> device(new PixelTestSoftwareOutputDevice()); 162 output_surface_.reset(new PixelTestOutputSurface(device.Pass())); 163 output_surface_->BindToClient(output_surface_client_.get()); 164 shared_bitmap_manager_.reset(new TestSharedBitmapManager()); 165 resource_provider_ = ResourceProvider::Create(output_surface_.get(), 166 shared_bitmap_manager_.get(), 167 main_thread_task_runner_.get(), 168 0, 169 false, 170 1, 171 false); 172 renderer_ = 173 SoftwareRenderer::Create( 174 this, &settings_, output_surface_.get(), resource_provider_.get()) 175 .PassAs<DirectRenderer>(); 176 } 177 178 } // namespace cc 179