12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 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 "base/command_line.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_util.h" 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_view_host.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/render_widget_host_view.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_paths.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_switches.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/test/browser_test_utils.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/shell/shell.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/test/content_browser_test.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/test/content_browser_test_utils.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "gpu/config/gpu_test_config.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_util.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gl/gl_switches.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/snapshot/snapshot.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)enum ReferenceImageOption { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kReferenceImageLocal, 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kReferenceImageCheckedIn, 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kReferenceImageNone // Only check a few key pixels. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ReferencePixel { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x, y; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char r, g, b; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Command line flag for overriding the default location for putting generated 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// test images that do not match references. 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kGeneratedDir[] = "generated-dir"; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Command line flag for overriding the default location for reference images. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kReferenceDir[] = "reference-dir"; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Command line flag for Chromium build revision. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kBuildRevision[] = "build-revision"; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// should have been encoded using |gfx::PNGCodec::Encode|. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ReadPNGFile(const base::FilePath& file_path, SkBitmap* bitmap) { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(bitmap); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath abs_path(base::MakeAbsoluteFilePath(file_path)); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (abs_path.empty()) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string png_data; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return file_util::ReadFileToString(abs_path, &png_data) && 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]), 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) png_data.length(), 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bitmap); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Encodes a bitmap into a PNG and write to disk. Returns true on success. The 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// parent directory does not have to exist. 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<unsigned char> png_data; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) && 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_util::CreateDirectory(file_path.DirName())) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bytes_written = file_util::WriteFile( 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_path, reinterpret_cast<char*>(&png_data[0]), png_data.size()); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bytes_written == static_cast<int>(png_data.size())) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Write an empty file, whose name indicates the chrome revision when the ref 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// image was generated. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WriteREVFile(const base::FilePath& file_path) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (file_util::CreateDirectory(file_path.DirName())) { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char one_byte = 0; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bytes_written = file_util::WriteFile(file_path, &one_byte, 1); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bytes_written == 1) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace anonymous 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test fixture for GPU image comparison tests. 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(kkania): Document how to add to/modify these tests. 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GpuPixelBrowserTest : public ContentBrowserTest { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuPixelBrowserTest() 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : ref_img_revision_(0), 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_img_revision_no_older_than_(0), 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_img_option_(kReferenceImageNone) { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 108a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch virtual void SetUp() { 109a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch // We expect real pixel output for these tests. 110a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch UseRealGLContexts(); 111a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch 112a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch ContentBrowserTest::SetUp(); 113a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch } 114a031efa9dbd9b321781674193e8ac7636d47eb1dBen Murdoch 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line->AppendSwitchASCII(switches::kTestGLLib, 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "libllvmpipe.so"); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContentBrowserTest::SetUpInProcessBrowserTestFixture(); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line->HasSwitch(switches::kUseGpuInTests)) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_img_option_ = kReferenceImageLocal; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line->HasSwitch(kBuildRevision)) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) build_revision_ = command_line->GetSwitchValueASCII(kBuildRevision); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_data_dir_)); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_data_dir_ = test_data_dir_.AppendASCII("gpu"); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line->HasSwitch(kGeneratedDir)) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) generated_img_dir_ = command_line->GetSwitchValuePath(kGeneratedDir); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) generated_img_dir_ = test_data_dir_.AppendASCII("generated"); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (ref_img_option_) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kReferenceImageLocal: 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (command_line->HasSwitch(kReferenceDir)) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_img_dir_ = command_line->GetSwitchValuePath(kReferenceDir); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_img_dir_ = test_data_dir_.AppendASCII("gpu_reference"); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kReferenceImageCheckedIn: 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_img_dir_ = test_data_dir_.AppendASCII("llvmpipe_reference"); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_name_ = testing::UnitTest::GetInstance()->current_test_info()->name(); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* test_status_prefixes[] = { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "DISABLED_", "FLAKY_", "FAILS_", "MANUAL_"}; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(test_status_prefixes); ++i) { 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReplaceFirstSubstringAfterOffset( 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &test_name_, 0, test_status_prefixes[i], std::string()); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the existing ref image was saved from an revision older than the 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ref_img_update_revision, refresh the ref image. 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RunPixelTest(const gfx::Size& tab_container_size, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& url, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 ref_img_update_revision, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReferencePixel* ref_pixels, 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t ref_pixel_count) { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ref_img_option_ == kReferenceImageLocal) { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_img_revision_no_older_than_ = ref_img_update_revision; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObtainLocalRefImageRevision(); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DOMMessageQueue message_queue; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NavigateToURL(shell(), net::FilePathToFileURL(url)); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Wait for notification that page is loaded. 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(message_queue.WaitForMessage(&message)); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_STREQ("\"SUCCESS\"", message.c_str()) << message; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkBitmap bitmap; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(TabSnapShotToImage(&bitmap, tab_container_size)); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool same_pixels = true; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ref_img_option_ == kReferenceImageNone && ref_pixels && ref_pixel_count) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) same_pixels = ComparePixels(bitmap, ref_pixels, ref_pixel_count); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) same_pixels = CompareImages(bitmap); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(same_pixels); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& test_data_dir() const { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return test_data_dir_; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_data_dir_; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath generated_img_dir_; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath ref_img_dir_; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 ref_img_revision_; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string build_revision_; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The name of the test, with any special prefixes dropped. 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string test_name_; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Any local ref image generated from older revision is ignored. 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 ref_img_revision_no_older_than_; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether use locally generated ref images, or checked in ref images, or 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // simply check a few key pixels. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReferenceImageOption ref_img_option_; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compares the generated bitmap with the appropriate reference image on disk. 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true iff the images were the same. 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If no valid reference image exists, save the generated bitmap to the disk. 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The image format is: 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // <test_name>_<revision>.png 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // E.g., 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WebGLTeapot_19762.png 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The number is the chromium revision that generated the image. 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On failure or on ref image generation, the image and diff image will be 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // written to disk. The formats are: 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // FAIL_<ref_image_name>, DIFF_<ref_image_name> 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // E.g., 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // FAIL_WebGLTeapot_19762.png, DIFF_WebGLTeapot_19762.png 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool CompareImages(const SkBitmap& gen_bmp) { 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkBitmap ref_bmp_on_disk; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath img_path = ref_img_dir_.AppendASCII(test_name_ + ".png"); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool found_ref_img = ReadPNGFile(img_path, &ref_bmp_on_disk); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!found_ref_img && ref_img_option_ == kReferenceImageCheckedIn) { 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Couldn't find reference image: " 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << img_path.value(); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No image to compare to, exit early. 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkBitmap* ref_bmp; 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool save_gen = false; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool save_diff = true; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool rt = true; 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((ref_img_revision_ <= 0 && ref_img_option_ == kReferenceImageLocal) || 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !found_ref_img) { 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath rev_path = ref_img_dir_.AppendASCII( 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_name_ + "_" + build_revision_ + ".rev"); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!WritePNGFile(gen_bmp, img_path)) { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Can't save generated image to: " 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << img_path.value() 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " as future reference."; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rt = false; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(INFO) << "Saved reference image to: " 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << img_path.value(); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rt) { 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!WriteREVFile(rev_path)) { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Can't save revision file to: " 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << rev_path.value(); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rt = false; 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(img_path, false); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(INFO) << "Saved revision file to: " 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << rev_path.value(); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ref_img_revision_ > 0) { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Can't read the local ref image: " 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << img_path.value() 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ", reset it."; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rt = false; 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we re-generate the ref image, we save the gen and diff images so 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the ref image can be uploaded to the server and be viewed later. 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) save_gen = true; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) save_diff = true; 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_bmp = &gen_bmp; 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_bmp = &ref_bmp_on_disk; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkBitmap diff_bmp; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ref_bmp->width() != gen_bmp.width() || 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_bmp->height() != gen_bmp.height()) { 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Dimensions do not match (Expected) vs (Actual):" 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "(" << ref_bmp->width() << "x" << ref_bmp->height() 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ") vs. " 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "(" << gen_bmp.width() << "x" << gen_bmp.height() << ")"; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ref_img_option_ == kReferenceImageLocal) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) save_gen = true; 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rt = false; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compare pixels and create a simple diff image. 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int diff_pixels_count = 0; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) diff_bmp.setConfig(SkBitmap::kARGB_8888_Config, 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gen_bmp.width(), gen_bmp.height()); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) diff_bmp.allocPixels(); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) diff_bmp.eraseColor(SK_ColorWHITE); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkAutoLockPixels lock_bmp(gen_bmp); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkAutoLockPixels lock_ref_bmp(*ref_bmp); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkAutoLockPixels lock_diff_bmp(diff_bmp); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The reference images were saved with no alpha channel. Use the mask to 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // set alpha to 0. 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32_t kAlphaMask = 0x00FFFFFF; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int x = 0; x < gen_bmp.width(); ++x) { 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int y = 0; y < gen_bmp.height(); ++y) { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) != 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*ref_bmp->getAddr32(x, y) & kAlphaMask)) { 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++diff_pixels_count; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *diff_bmp.getAddr32(x, y) = 192 << 16; // red 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (diff_pixels_count > 0) { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << diff_pixels_count 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " pixels do not match."; 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ref_img_option_ == kReferenceImageLocal) { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) save_gen = true; 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) save_diff = true; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rt = false; 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string ref_img_filename = img_path.BaseName().MaybeAsASCII(); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (save_gen) { 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath img_fail_path = generated_img_dir_.AppendASCII( 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "FAIL_" + ref_img_filename); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!WritePNGFile(gen_bmp, img_fail_path)) { 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Can't save generated image to: " 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << img_fail_path.value(); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(INFO) << "Saved generated image to: " 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << img_fail_path.value(); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (save_diff) { 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath img_diff_path = generated_img_dir_.AppendASCII( 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "DIFF_" + ref_img_filename); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!WritePNGFile(diff_bmp, img_diff_path)) { 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Can't save generated diff image to: " 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << img_diff_path.value(); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(INFO) << "Saved difference image to: " 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << img_diff_path.value(); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rt; 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ComparePixels(const SkBitmap& gen_bmp, 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReferencePixel* ref_pixels, 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t ref_pixel_count) { 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkAutoLockPixels lock_bmp(gen_bmp); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < ref_pixel_count; ++i) { 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int x = ref_pixels[i].x; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int y = ref_pixels[i].y; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char r = ref_pixels[i].r; 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char g = ref_pixels[i].g; 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char b = ref_pixels[i].b; 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(x >= 0 && x < gen_bmp.width() && y >= 0 && y < gen_bmp.height()); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char* rgba = reinterpret_cast<unsigned char*>( 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gen_bmp.getAddr32(x, y)); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(rgba); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rgba[0] != b || rgba[1] != g || rgba[2] != r) { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string error_message = base::StringPrintf( 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "pixel(%d,%d) expects [%u,%u,%u], but gets [%u,%u,%u] instead", 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) x, y, r, g, b, rgba[0], rgba[1], rgba[2]); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << error_message.c_str(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Take snapshot of the tab, encode it as PNG, and save to a SkBitmap. 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool TabSnapShotToImage(SkBitmap* bitmap, const gfx::Size& size) { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(bitmap); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<unsigned char> png; 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect snapshot_bounds(size); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderViewHost* view_host = shell()->web_contents()->GetRenderViewHost(); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ui::GrabViewSnapshot(view_host->GetView()->GetNativeView(), 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &png, snapshot_bounds)) { 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "ui::GrabViewSnapShot() failed"; 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&*png.begin()), 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) png.size(), bitmap)) { 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Decode PNG to a SkBitmap failed"; 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If no valid local revision file is located, the ref_img_revision_ is 0. 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ObtainLocalRefImageRevision() { 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath filter; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) filter = filter.AppendASCII(test_name_ + "_*.rev"); 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator locator(ref_img_dir_, 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) false, // non recursive 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator::FILES, 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) filter.value()); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 max_revision = 0; 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath> outdated_revs; 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::FilePath full_path = locator.Next(); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !full_path.empty(); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) full_path = locator.Next()) { 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string filename = 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) full_path.BaseName().RemoveExtension().MaybeAsASCII(); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string revision_string = 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) filename.substr(test_name_.length() + 1); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 revision = 0; 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool converted = base::StringToInt64(revision_string, &revision); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!converted) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (revision < ref_img_revision_no_older_than_ || 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) revision < max_revision) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) outdated_revs.push_back(full_path); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_revision = revision; 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_img_revision_ = max_revision; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < outdated_revs.size(); ++i) 4327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(outdated_revs[i], false); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GpuPixelBrowserTest); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GpuPixelBrowserTest, MANUAL_WebGLGreenTriangle) { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If test baseline needs to be updated after a given revision, update the 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // following number. If no revision requirement, then 0. 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int64 ref_img_revision_update = 123489; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReferencePixel ref_pixels[] = { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // x, y, r, g, b 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {50, 100, 0, 0, 0}, 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {100, 100, 0, 255, 0}, 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {150, 100, 0, 0, 0}, 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {50, 150, 0, 255, 0}, 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {100, 150, 0, 255, 0}, 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {150, 150, 0, 255, 0} 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t ref_pixel_count = sizeof(ref_pixels) / sizeof(ReferencePixel); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size container_size(400, 300); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath url = 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_data_dir().AppendASCII("pixel_webgl.html"); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunPixelTest(container_size, url, ref_img_revision_update, 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_pixels, ref_pixel_count); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GpuPixelBrowserTest, MANUAL_CSS3DBlueBox) { 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If test baseline needs to be updated after a given revision, update the 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // following number. If no revision requirement, then 0. 464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int64 ref_img_revision_update = 209827; 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReferencePixel ref_pixels[] = { 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // x, y, r, g, b 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {70, 50, 0, 0, 255}, 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {150, 50, 0, 0, 0}, 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {70, 90, 0, 0, 255}, 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {150, 90, 0, 0, 255}, 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {70, 125, 0, 0, 255}, 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {150, 125, 0, 0, 0} 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t ref_pixel_count = sizeof(ref_pixels) / sizeof(ReferencePixel); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size container_size(400, 300); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath url = 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_data_dir().AppendASCII("pixel_css3d.html"); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunPixelTest(container_size, url, ref_img_revision_update, 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_pixels, ref_pixel_count); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GpuPixelBrowserTest, MANUAL_Canvas2DRedBoxHD) { 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If test baseline needs to be updated after a given revision, update the 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // following number. If no revision requirement, then 0. 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int64 ref_img_revision_update = 123489; 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReferencePixel ref_pixels[] = { 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // x, y, r, g, b 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {40, 100, 0, 0, 0}, 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {60, 100, 127, 0, 0}, 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {140, 100, 127, 0, 0}, 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {160, 100, 0, 0, 0} 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t ref_pixel_count = sizeof(ref_pixels) / sizeof(ReferencePixel); 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size container_size(400, 300); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath url = 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_data_dir().AppendASCII("pixel_canvas2d.html"); 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunPixelTest(container_size, url, ref_img_revision_update, 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_pixels, ref_pixel_count); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GpuPixelTestCanvas2DSD : public GpuPixelBrowserTest { 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuPixelBrowserTest::SetUpCommandLine(command_line); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas); 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GpuPixelTestCanvas2DSD, MANUAL_Canvas2DRedBoxSD) { 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If test baseline needs to be updated after a given revision, update the 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // following number. If no revision requirement, then 0. 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int64 ref_img_revision_update = 123489; 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReferencePixel ref_pixels[] = { 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // x, y, r, g, b 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {40, 100, 0, 0, 0}, 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {60, 100, 127, 0, 0}, 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {140, 100, 127, 0, 0}, 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {160, 100, 0, 0, 0} 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t ref_pixel_count = sizeof(ref_pixels) / sizeof(ReferencePixel); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size container_size(400, 300); 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath url = 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_data_dir().AppendASCII("pixel_canvas2d.html"); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunPixelTest(container_size, url, ref_img_revision_update, 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_pixels, ref_pixel_count); 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GpuPixelTestBrowserPlugin : public GpuPixelBrowserTest { 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuPixelBrowserTest::SetUpCommandLine(command_line); 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_line->AppendSwitch(switches::kEnableBrowserPluginForAllViewTypes); 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// TODO(fsamuel): re-enable as MANUAL_BrowserPluginBlueBox: crbug.com/166165 543ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochIN_PROC_BROWSER_TEST_F(GpuPixelTestBrowserPlugin, 544ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DISABLED_BrowserPluginBlueBox) { 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If test baseline needs to be updated after a given revision, update the 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // following number. If no revision requirement, then 0. 547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int64 ref_img_revision_update = 209445; 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReferencePixel ref_pixels[] = { 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // x, y, r, g, b 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {70, 50, 0, 0, 255}, 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {150, 50, 0, 0, 0}, 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {70, 90, 0, 0, 255}, 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {150, 90, 0, 0, 255}, 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {70, 125, 0, 0, 255}, 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {150, 125, 0, 0, 0} 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t ref_pixel_count = sizeof(ref_pixels) / sizeof(ReferencePixel); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size container_size(400, 300); 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath url = 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_data_dir().AppendASCII("pixel_browser_plugin.html"); 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunPixelTest(container_size, url, ref_img_revision_update, 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ref_pixels, ref_pixel_count); 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 569