Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / test / gpu / gpu_feature_browsertest.cc
blob8bed26b3fcf401c0a9e535404f16f3458bf7baf2
1 // Copyright (c) 2012 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.
5 #include "base/command_line.h"
6 #include "base/file_util.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/path_service.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/test/trace_event_analyzer.h"
11 #include "base/version.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_window.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/test/base/in_process_browser_test.h"
17 #include "chrome/test/base/tracing.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "content/public/browser/gpu_data_manager.h"
20 #include "content/public/common/content_client.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "gpu/config/gpu_feature_type.h"
24 #include "gpu/config/gpu_info.h"
25 #include "gpu/config/gpu_test_config.h"
26 #include "net/base/filename_util.h"
27 #include "ui/gl/gl_implementation.h"
29 #if defined(OS_MACOSX)
30 #include "ui/gl/io_surface_support_mac.h"
31 #endif
33 #if defined(OS_WIN)
34 #include "base/win/windows_version.h"
35 #endif
37 using content::GpuDataManager;
38 using gpu::GpuFeatureType;
39 using trace_analyzer::Query;
40 using trace_analyzer::TraceAnalyzer;
41 using trace_analyzer::TraceEventVector;
43 namespace {
45 const char kAcceleratedCanvasCreationEvent[] = "Canvas2DLayerBridgeCreation";
46 const char kWebGLCreationEvent[] = "DrawingBufferCreation";
48 class FakeContentClient : public content::ContentClient {
51 class GpuFeatureTest : public InProcessBrowserTest {
52 public:
53 GpuFeatureTest() : category_patterns_("test_gpu") {}
55 virtual void SetUp() OVERRIDE {
56 content::SetContentClient(&content_client_);
59 virtual void TearDown() OVERRIDE {
60 content::SetContentClient(NULL);
63 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
64 base::FilePath test_dir;
65 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
66 gpu_test_dir_ = test_dir.AppendASCII("gpu");
69 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
70 command_line->AppendSwitch(switches::kDisablePopupBlocking);
71 command_line->AppendSwitchASCII(switches::kWindowSize, "400,300");
74 void SetupBlacklist(const std::string& json_blacklist) {
75 gpu::GPUInfo gpu_info;
76 GpuDataManager::GetInstance()->InitializeForTesting(
77 json_blacklist, gpu_info);
80 // If expected_reply is NULL, we don't check the reply content.
81 void RunTest(const base::FilePath& url,
82 const char* expected_reply,
83 bool new_tab) {
84 #if defined(OS_LINUX) && !defined(NDEBUG)
85 // Bypass tests on GPU Linux Debug bots.
86 if (gfx::GetGLImplementation() != gfx::kGLImplementationOSMesaGL)
87 return;
88 #endif
90 base::FilePath test_path;
91 test_path = gpu_test_dir_.Append(url);
92 ASSERT_TRUE(base::PathExists(test_path))
93 << "Missing test file: " << test_path.value();
95 content::DOMMessageQueue message_queue;
96 if (new_tab) {
97 ui_test_utils::NavigateToURLWithDisposition(
98 browser(), net::FilePathToFileURL(test_path),
99 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_NONE);
100 } else {
101 ui_test_utils::NavigateToURL(
102 browser(), net::FilePathToFileURL(test_path));
105 std::string result;
106 // Wait for message indicating the test has finished running.
107 ASSERT_TRUE(message_queue.WaitForMessage(&result));
108 if (expected_reply)
109 EXPECT_STREQ(expected_reply, result.c_str());
112 // Open the URL and check the trace stream for the given event.
113 void RunEventTest(const base::FilePath& url,
114 const char* event_name = NULL,
115 bool event_expected = false) {
116 #if defined(OS_LINUX) && !defined(NDEBUG)
117 // Bypass tests on GPU Linux Debug bots.
118 if (gfx::GetGLImplementation() != gfx::kGLImplementationOSMesaGL)
119 return;
120 #endif
121 #if defined(OS_MACOSX)
122 // Bypass tests on Mac OSX 10.5 bots (IOSurfaceSupport is now required).
123 if (!IOSurfaceSupport::Initialize())
124 return;
125 #endif
127 ASSERT_TRUE(tracing::BeginTracing(category_patterns_));
129 // Have to use a new tab for the blacklist to work.
130 RunTest(url, NULL, true);
132 ASSERT_TRUE(tracing::EndTracing(&trace_events_json_));
134 analyzer_.reset(TraceAnalyzer::Create(trace_events_json_));
135 analyzer_->AssociateBeginEndEvents();
136 TraceEventVector events;
138 if (!event_name)
139 return;
141 size_t event_count =
142 analyzer_->FindEvents(Query::EventNameIs(event_name), &events);
144 if (event_expected)
145 EXPECT_GT(event_count, 0U);
146 else
147 EXPECT_EQ(event_count, 0U);
150 // Trigger a resize of the chrome window, and use tracing to wait for the
151 // given |wait_event|.
152 bool ResizeAndWait(const gfx::Rect& new_bounds,
153 const char* category_patterns,
154 const char* wait_category,
155 const char* wait_event) {
156 if (!tracing::BeginTracingWithWatch(category_patterns, wait_category,
157 wait_event, 1))
158 return false;
159 browser()->window()->SetBounds(new_bounds);
160 if (!tracing::WaitForWatchEvent(base::TimeDelta()))
161 return false;
162 if (!tracing::EndTracing(&trace_events_json_))
163 return false;
164 analyzer_.reset(TraceAnalyzer::Create(trace_events_json_));
165 analyzer_->AssociateBeginEndEvents();
166 return true;
169 protected:
170 base::FilePath gpu_test_dir_;
171 scoped_ptr<TraceAnalyzer> analyzer_;
172 std::string category_patterns_;
173 std::string trace_events_json_;
174 FakeContentClient content_client_;
177 class GpuFeaturePixelTest : public GpuFeatureTest {
178 protected:
179 virtual void SetUp() OVERRIDE {
180 EnablePixelOutput();
181 GpuFeatureTest::SetUp();
185 class GpuCompositingBlockedTest : public GpuFeatureTest {
186 public:
187 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
188 GpuFeatureTest::SetUpInProcessBrowserTestFixture();
189 const std::string json_blacklist =
190 "{\n"
191 " \"name\": \"gpu blacklist\",\n"
192 " \"version\": \"1.0\",\n"
193 " \"entries\": [\n"
194 " {\n"
195 " \"id\": 1,\n"
196 " \"features\": [\n"
197 " \"gpu_compositing\"\n"
198 " ]\n"
199 " }\n"
200 " ]\n"
201 "}";
202 SetupBlacklist(json_blacklist);
206 IN_PROC_BROWSER_TEST_F(GpuCompositingBlockedTest, GpuCompositingBlocked) {
207 EXPECT_TRUE(GpuDataManager::GetInstance()->IsFeatureBlacklisted(
208 gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING));
211 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLAllowed) {
212 EXPECT_FALSE(GpuDataManager::GetInstance()->IsFeatureBlacklisted(
213 gpu::GPU_FEATURE_TYPE_WEBGL));
215 // The below times out: http://crbug.com/166060
216 return;
218 const base::FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
219 RunEventTest(url, kWebGLCreationEvent, true);
222 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLBlocked) {
223 const std::string json_blacklist =
224 "{\n"
225 " \"name\": \"gpu blacklist\",\n"
226 " \"version\": \"1.0\",\n"
227 " \"entries\": [\n"
228 " {\n"
229 " \"id\": 1,\n"
230 " \"features\": [\n"
231 " \"webgl\"\n"
232 " ]\n"
233 " }\n"
234 " ]\n"
235 "}";
236 SetupBlacklist(json_blacklist);
237 EXPECT_TRUE(GpuDataManager::GetInstance()->IsFeatureBlacklisted(
238 gpu::GPU_FEATURE_TYPE_WEBGL));
240 const base::FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
241 RunEventTest(url, kWebGLCreationEvent, false);
244 class WebGLTest : public GpuFeatureTest {
245 public:
246 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
247 GpuFeatureTest::SetUpCommandLine(command_line);
248 #if !defined(OS_ANDROID)
249 // On Android, WebGL is disabled by default
250 command_line->AppendSwitch(switches::kDisableExperimentalWebGL);
251 #endif
255 IN_PROC_BROWSER_TEST_F(WebGLTest, WebGLDisabled) {
256 const base::FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
257 RunEventTest(url, kWebGLCreationEvent, false);
260 // This test is oblivious to the fact that multisample could be blacklisted on
261 // some configurations. Previously disabled on GOOGLE_CHROME_BUILD and
262 // on OS_MACOSX: http://crbug.com/314745
263 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, DISABLED_MultisamplingAllowed) {
264 if (gpu::GPUTestBotConfig::GpuBlacklistedOnBot())
265 return;
266 // Multisampling is not supported if running on top of osmesa.
267 if (gfx::GetGLImplementation() == gfx::kGLImplementationOSMesaGL)
268 return;
269 // Linux Intel uses mesa driver, where multisampling is not supported.
270 // Multisampling is also not supported on virtualized mac os.
271 std::vector<std::string> configs;
272 configs.push_back("LINUX INTEL");
273 configs.push_back("MAC VMWARE");
274 if (gpu::GPUTestBotConfig::CurrentConfigMatches(configs))
275 return;
277 const base::FilePath url(FILE_PATH_LITERAL("feature_multisampling.html"));
278 RunTest(url, "\"TRUE\"", true);
281 class WebGLMultisamplingTest : public GpuFeatureTest {
282 public:
283 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
284 GpuFeatureTest::SetUpCommandLine(command_line);
285 command_line->AppendSwitch(switches::kDisableGLMultisampling);
289 IN_PROC_BROWSER_TEST_F(WebGLMultisamplingTest, MultisamplingDisabled) {
290 // Multisampling fails on virtualized mac os.
291 if (gpu::GPUTestBotConfig::CurrentConfigMatches("MAC VMWARE"))
292 return;
294 const base::FilePath url(FILE_PATH_LITERAL("feature_multisampling.html"));
295 RunTest(url, "\"FALSE\"", true);
298 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DAllowed) {
299 // Accelerated canvas 2D is not supported on XP.
300 if (gpu::GPUTestBotConfig::CurrentConfigMatches("XP"))
301 return;
303 enum Canvas2DState {
304 ENABLED,
305 BLACKLISTED, // Disabled via the blacklist.
306 DISABLED, // Not disabled via the blacklist, but expected to be disabled
307 // by configuration.
308 } expected_state = ENABLED;
309 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
310 // Blacklist rule #24 disables accelerated_2d_canvas on Linux.
311 expected_state = BLACKLISTED;
312 #elif defined(OS_WIN)
313 // Blacklist rule #67 disables accelerated_2d_canvas on XP.
314 if (base::win::GetVersion() < base::win::VERSION_VISTA)
315 expected_state = BLACKLISTED;
316 #endif
318 if (gpu::GPUTestBotConfig::GpuBlacklistedOnBot())
319 expected_state = BLACKLISTED;
321 #if defined(USE_AURA)
322 // Canvas 2D is always disabled in software compositing mode, make sure it is
323 // marked as such if it wasn't blacklisted already.
324 if (expected_state == ENABLED &&
325 !content::GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor()) {
326 expected_state = DISABLED;
328 #endif
330 EXPECT_EQ(expected_state == BLACKLISTED,
331 GpuDataManager::GetInstance()->IsFeatureBlacklisted(
332 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS));
334 const base::FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
335 RunEventTest(url, kAcceleratedCanvasCreationEvent, expected_state == ENABLED);
338 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DBlocked) {
339 const std::string json_blacklist =
340 "{\n"
341 " \"name\": \"gpu blacklist\",\n"
342 " \"version\": \"1.0\",\n"
343 " \"entries\": [\n"
344 " {\n"
345 " \"id\": 1,\n"
346 " \"features\": [\n"
347 " \"accelerated_2d_canvas\"\n"
348 " ]\n"
349 " }\n"
350 " ]\n"
351 "}";
352 SetupBlacklist(json_blacklist);
353 EXPECT_TRUE(GpuDataManager::GetInstance()->IsFeatureBlacklisted(
354 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS));
356 const base::FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
357 RunEventTest(url, kAcceleratedCanvasCreationEvent, false);
360 class Canvas2DDisabledTest : public GpuFeatureTest {
361 public:
362 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
363 GpuFeatureTest::SetUpCommandLine(command_line);
364 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
368 IN_PROC_BROWSER_TEST_F(Canvas2DDisabledTest, Canvas2DDisabled) {
369 const base::FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
370 RunEventTest(url, kAcceleratedCanvasCreationEvent, false);
373 IN_PROC_BROWSER_TEST_F(GpuFeaturePixelTest,
374 CanOpenPopupAndRenderWithWebGLCanvas) {
375 if (gpu::GPUTestBotConfig::GpuBlacklistedOnBot())
376 return;
378 const base::FilePath url(FILE_PATH_LITERAL("webgl_popup.html"));
379 RunTest(url, "\"SUCCESS\"", false);
382 // crbug.com/176466
383 IN_PROC_BROWSER_TEST_F(GpuFeatureTest,
384 DISABLED_CanOpenPopupAndRenderWith2DCanvas) {
385 const base::FilePath url(FILE_PATH_LITERAL("canvas_popup.html"));
386 RunTest(url, "\"SUCCESS\"", false);
389 #if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_MACOSX)
390 // http://crbug.com/162343: flaky on Windows and Mac, failing on ChromiumOS.
391 #define MAYBE_RafNoDamage DISABLED_RafNoDamage
392 #else
393 #define MAYBE_RafNoDamage RafNoDamage
394 #endif
395 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, MAYBE_RafNoDamage) {
396 category_patterns_ = "-test_*";
397 const base::FilePath url(FILE_PATH_LITERAL("feature_raf_no_damage.html"));
398 RunEventTest(url);
400 if (!analyzer_.get())
401 return;
403 // Search for matching name on begin event or async_begin event (any begin).
404 Query query_raf =
405 (Query::EventPhaseIs(TRACE_EVENT_PHASE_BEGIN) ||
406 Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_BEGIN)) &&
407 Query::EventNameIs("___RafWithNoDamage___");
408 TraceEventVector events;
409 size_t num_events = analyzer_->FindEvents(query_raf, &events);
411 trace_analyzer::RateStats stats;
412 trace_analyzer::RateStatsOptions stats_options;
413 stats_options.trim_min = stats_options.trim_max = num_events / 10;
414 EXPECT_TRUE(trace_analyzer::GetRateStats(events, &stats, &stats_options));
416 LOG(INFO) << "Number of RAFs: " << num_events <<
417 " Mean: " << stats.mean_us <<
418 " Min: " << stats.min_us <<
419 " Max: " << stats.max_us <<
420 " StdDev: " << stats.standard_deviation_us;
422 // Expect that the average time between RAFs is more than 15ms. That will
423 // indicate that the renderer is not simply spinning on RAF.
424 EXPECT_GT(stats.mean_us, 15000.0);
426 // Print out the trace events upon error to debug failures.
427 if (stats.mean_us <= 15000.0) {
428 fprintf(stderr, "\n\nTRACE JSON:\n\n%s\n\n", trace_events_json_.c_str());
432 #if defined(OS_MACOSX)
433 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, IOSurfaceReuse) {
434 if (!IOSurfaceSupport::Initialize())
435 return;
437 if (gpu::GPUTestBotConfig::GpuBlacklistedOnBot())
438 return;
440 const base::FilePath url(
441 FILE_PATH_LITERAL("feature_compositing_static.html"));
442 base::FilePath test_path = gpu_test_dir_.Append(url);
443 ASSERT_TRUE(base::PathExists(test_path))
444 << "Missing test file: " << test_path.value();
446 ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(test_path));
448 LOG(INFO) << "did navigate";
449 gfx::Rect bounds = browser()->window()->GetBounds();
450 gfx::Rect new_bounds = bounds;
452 const char* create_event = "IOSurfaceImageTransportSurface::CreateIOSurface";
453 const char* resize_event = "IOSurfaceImageTransportSurface::OnResize";
454 const char* draw_event = "CompositingIOSurfaceMac::DrawIOSurface";
455 Query find_creates = Query::MatchBeginName(create_event);
456 Query find_resizes = Query::MatchBeginName(resize_event) &&
457 Query::EventHasNumberArg("old_width") &&
458 Query::EventHasNumberArg("new_width");
459 Query find_draws = Query::MatchBeginName(draw_event) &&
460 Query::EventHasNumberArg("scale");
462 const int roundup = 64;
463 // A few resize values assuming a roundup of 64 pixels. The test will resize
464 // by these values one at a time and verify that CreateIOSurface only happens
465 // when the rounded width changes.
466 int offsets[] = { 1, roundup - 1, roundup, roundup + 1, 2*roundup};
467 int num_offsets = static_cast<int>(arraysize(offsets));
468 int w_start = bounds.width();
470 for (int offset_i = 0; offset_i < num_offsets; ++offset_i) {
471 new_bounds.set_width(w_start + offsets[offset_i]);
472 LOG(INFO) << "before wait";
473 ASSERT_TRUE(ResizeAndWait(new_bounds, "gpu", "gpu", resize_event));
474 LOG(INFO) << "after wait";
476 TraceEventVector resize_events;
477 analyzer_->FindEvents(find_resizes, &resize_events);
478 LOG(INFO) << "num rezize events = " << resize_events.size();
479 for (size_t resize_i = 0; resize_i < resize_events.size(); ++resize_i) {
480 const trace_analyzer::TraceEvent* resize = resize_events[resize_i];
481 // Was a create allowed:
482 int old_width = resize->GetKnownArgAsInt("old_width");
483 int new_width = resize->GetKnownArgAsInt("new_width");
484 bool expect_create = (old_width/roundup != new_width/roundup ||
485 old_width == 0);
486 int expected_creates = expect_create ? 1 : 0;
488 // Find the create event inside this resize event (if any). This will
489 // determine if the resize triggered a reallocation of the IOSurface.
490 double begin_time = resize->timestamp;
491 double end_time = begin_time + resize->GetAbsTimeToOtherEvent();
492 Query find_this_create = find_creates &&
493 Query::EventTime() >= Query::Double(begin_time) &&
494 Query::EventTime() <= Query::Double(end_time);
495 TraceEventVector create_events;
496 int num_creates = static_cast<int>(analyzer_->FindEvents(find_this_create,
497 &create_events));
498 EXPECT_EQ(expected_creates, num_creates);
500 // For debugging failures, print out the width and height of each resize:
501 LOG(INFO) <<
502 base::StringPrintf(
503 "%d (resize offset %d): IOSurface width %d -> %d; Creates %d "
504 "Expected %d", offset_i, offsets[offset_i],
505 old_width, new_width, num_creates, expected_creates);
508 LOG(INFO) << "finished test";
510 #endif
512 } // namespace