12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/pixel_test.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/command_line.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/run_loop.h" 101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "cc/base/switches.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame_metadata.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "cc/output/copy_output_request.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "cc/output/copy_output_result.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/gl_renderer.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "cc/output/output_surface_client.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/output/software_renderer.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/resource_provider.h" 1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "cc/resources/texture_mailbox_deleter.h" 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/test/fake_output_surface_client.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/paths.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "cc/test/pixel_test_output_surface.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "cc/test/pixel_test_software_output_device.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/pixel_test_utils.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gl/gl_implementation.h" 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/gpu/context_provider_in_process.h" 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PixelTest::PixelTest() 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : device_viewport_size_(gfx::Size(200, 200)), 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) disable_picture_quad_image_filtering_(false), 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) output_surface_client_(new FakeOutputSurfaceClient) {} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PixelTest::~PixelTest() {} 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool PixelTest::RunPixelTest(RenderPassList* pass_list, 39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OffscreenContextOption provide_offscreen_context, 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& ref_file, 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const PixelComparator& comparator) { 42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return RunPixelTestWithReadbackTarget(pass_list, 43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) pass_list->back(), 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) provide_offscreen_context, 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ref_file, 46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) comparator); 47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool PixelTest::RunPixelTestWithReadbackTarget( 50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RenderPassList* pass_list, 51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RenderPass* target, 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OffscreenContextOption provide_offscreen_context, 53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const base::FilePath& ref_file, 54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const PixelComparator& comparator) { 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::RunLoop run_loop; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) target->copy_requests.push_back(CopyOutputRequest::CreateBitmapRequest( 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&PixelTest::ReadbackResult, 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this), 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) run_loop.QuitClosure()))); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<webkit::gpu::ContextProviderInProcess> offscreen_contexts; 63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (provide_offscreen_context) { 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case NoOffscreenContext: 65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case WithOffscreenContext: 67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) offscreen_contexts = 68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) webkit::gpu::ContextProviderInProcess::CreateOffscreen(); 69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CHECK(offscreen_contexts->BindToCurrentThread()); 70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) float device_scale_factor = 1.f; 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect device_viewport_rect = 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect(device_viewport_size_) + external_device_viewport_offset_; 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect device_clip_rect = external_device_clip_rect_.IsEmpty() 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ? device_viewport_rect 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : external_device_clip_rect_; 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool allow_partial_swap = true; 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) renderer_->DecideRenderPassAllocationsForFrame(*pass_list); 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) renderer_->DrawFrame(pass_list, 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) offscreen_contexts.get(), 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) device_scale_factor, 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_viewport_rect, 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) device_clip_rect, 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) allow_partial_swap, 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) disable_picture_quad_image_filtering_); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Wait for the readback to complete. 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_provider_->Finish(); 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) run_loop.Run(); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PixelsMatchReference(ref_file, comparator); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PixelTest::ReadbackResult(base::Closure quit_run_loop, 987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<CopyOutputResult> result) { 997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(result->HasBitmap()); 1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) result_bitmap_ = result->TakeBitmap().Pass(); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) quit_run_loop.Run(); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file, 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const PixelComparator& comparator) { 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath test_data_dir; 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir)) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If this is false, we didn't set up a readback on a render pass. 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result_bitmap_) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CommandLine* cmd = CommandLine::ForCurrentProcess(); 1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (cmd->HasSwitch(switches::kCCRebaselinePixeltests)) 1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return MatchesPNGFile(*result_bitmap_, 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) test_data_dir.Append(ref_file), 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) comparator); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL)); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) using webkit::gpu::ContextProviderInProcess; 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) output_surface_.reset(new PixelTestOutputSurface( 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ContextProviderInProcess::CreateOffscreen())); 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) output_surface_->BindToClient(output_surface_client_.get()); 1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) resource_provider_ = 1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1); 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) texture_mailbox_deleter_ = make_scoped_ptr(new TextureMailboxDeleter); 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) renderer_ = GLRenderer::Create(this, 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &settings_, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_surface_.get(), 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) resource_provider_.get(), 14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) texture_mailbox_deleter_.get(), 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 0).PassAs<DirectRenderer>(); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PixelTest::ForceExpandedViewport(gfx::Size surface_expansion) { 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<PixelTestOutputSurface*>(output_surface_.get()) 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ->set_surface_expansion_size(surface_expansion); 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SoftwareOutputDevice* device = output_surface_->software_device(); 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (device) { 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<PixelTestSoftwareOutputDevice*>(device) 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ->set_surface_expansion_size(surface_expansion); 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PixelTest::ForceViewportOffset(gfx::Vector2d viewport_offset) { 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) external_device_viewport_offset_ = viewport_offset; 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PixelTest::ForceDeviceClip(gfx::Rect clip) { 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) external_device_clip_rect_ = clip; 16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 162fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid PixelTest::EnableExternalStencilTest() { 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static_cast<PixelTestOutputSurface*>(output_surface_.get()) 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ->set_has_external_stencil_test(true); 165fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch} 166fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PixelTest::SetUpSoftwareRenderer() { 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<SoftwareOutputDevice> device(new PixelTestSoftwareOutputDevice()); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) output_surface_.reset(new PixelTestOutputSurface(device.Pass())); 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) output_surface_->BindToClient(output_surface_client_.get()); 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) resource_provider_ = 1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1); 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) renderer_ = SoftwareRenderer::Create( 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) this, &settings_, output_surface_.get(), resource_provider_.get()) 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) .PassAs<DirectRenderer>(); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 179