Make hitting "Enter" submit the add/change profile dialog.
[chromium-blink-merge.git] / chrome / test / gpu / gpu_feature_browsertest.cc
blob405ca746b5a60ec68bf3bb8bbc458ac4276d1dd9
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/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/test_launcher_utils.h"
18 #include "chrome/test/base/tracing.h"
19 #include "chrome/test/base/ui_test_utils.h"
20 #include "content/public/browser/gpu_data_manager.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/common/gpu_info.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "content/test/gpu/gpu_test_config.h"
25 #include "net/base/net_util.h"
26 #include "ui/gl/gl_switches.h"
27 #include "ui/compositor/compositor_setup.h"
28 #if defined(OS_MACOSX)
29 #include "ui/surface/io_surface_support_mac.h"
30 #endif
32 #if defined(OS_WIN)
33 #include "base/win/windows_version.h"
34 #endif
36 using content::GpuDataManager;
37 using content::GpuFeatureType;
38 using trace_analyzer::Query;
39 using trace_analyzer::TraceAnalyzer;
40 using trace_analyzer::TraceEventVector;
42 namespace {
44 const char kSwapBuffersEvent[] = "SwapBuffers";
45 const char kAcceleratedCanvasCreationEvent[] = "Canvas2DLayerBridgeCreation";
46 const char kWebGLCreationEvent[] = "DrawingBufferCreation";
48 class GpuFeatureTest : public InProcessBrowserTest {
49 public:
50 GpuFeatureTest() : trace_categories_("test_gpu"), gpu_enabled_(false) {}
52 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
53 FilePath test_dir;
54 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
55 gpu_test_dir_ = test_dir.AppendASCII("gpu");
58 virtual void SetUpCommandLine(CommandLine* command_line) {
59 // Do not use mesa if real GPU is required.
60 if (!command_line->HasSwitch(switches::kUseGpuInTests)) {
61 #if !defined(OS_MACOSX)
62 CHECK(test_launcher_utils::OverrideGLImplementation(
63 command_line, gfx::kGLImplementationOSMesaName)) <<
64 "kUseGL must not be set by test framework code!";
65 #endif
66 } else {
67 gpu_enabled_ = true;
69 command_line->AppendSwitch(switches::kDisablePopupBlocking);
70 ui::DisableTestCompositor();
71 command_line->AppendSwitchASCII(switches::kWindowSize, "400,300");
74 void SetupBlacklist(const std::string& json_blacklist) {
75 content::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 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 (gpu_enabled_)
87 return;
88 #endif
90 FilePath test_path;
91 test_path = gpu_test_dir_.Append(url);
92 ASSERT_TRUE(file_util::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 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 (gpu_enabled_)
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(trace_categories_));
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* trace_categories,
154 const char* wait_category,
155 const char* wait_event) {
156 if (!tracing::BeginTracingWithWatch(trace_categories, 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 FilePath gpu_test_dir_;
171 scoped_ptr<TraceAnalyzer> analyzer_;
172 std::string trace_categories_;
173 std::string trace_events_json_;
174 bool gpu_enabled_;
177 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, AcceleratedCompositingAllowed) {
178 GpuFeatureType type =
179 GpuDataManager::GetInstance()->GetBlacklistedFeatures();
180 EXPECT_EQ(type, 0);
182 const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
183 RunEventTest(url, kSwapBuffersEvent, true);
186 // Flash Stage3D may be blacklisted for other reasons on XP, so ignore it.
187 GpuFeatureType IgnoreGpuFeatures(GpuFeatureType type) {
188 #if defined(OS_WIN)
189 if (base::win::GetVersion() < base::win::VERSION_VISTA)
190 return static_cast<GpuFeatureType>(type &
191 ~content::GPU_FEATURE_TYPE_FLASH_STAGE3D);
192 #endif
193 return type;
196 class AcceleratedCompositingBlockedTest : public GpuFeatureTest {
197 public:
198 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
199 GpuFeatureTest::SetUpInProcessBrowserTestFixture();
200 const std::string json_blacklist =
201 "{\n"
202 " \"name\": \"gpu blacklist\",\n"
203 " \"version\": \"1.0\",\n"
204 " \"entries\": [\n"
205 " {\n"
206 " \"id\": 1,\n"
207 " \"blacklist\": [\n"
208 " \"accelerated_compositing\"\n"
209 " ]\n"
210 " }\n"
211 " ]\n"
212 "}";
213 SetupBlacklist(json_blacklist);
217 #if (defined(OS_WIN) && defined(USE_AURA)) || defined(OS_CHROMEOS)
218 // Compositing is always on for Windows Aura.
219 // Disabled on chrome os due to http://crbug.com/167806
220 #define MAYBE_AcceleratedCompositingBlocked DISABLED_AcceleratedCompositingBlocked
221 #else
222 #define MAYBE_AcceleratedCompositingBlocked AcceleratedCompositingBlocked
223 #endif
225 IN_PROC_BROWSER_TEST_F(AcceleratedCompositingBlockedTest,
226 MAYBE_AcceleratedCompositingBlocked) {
227 GpuFeatureType type =
228 GpuDataManager::GetInstance()->GetBlacklistedFeatures();
229 type = IgnoreGpuFeatures(type);
231 EXPECT_EQ(type, content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING);
233 const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
234 RunEventTest(url, kSwapBuffersEvent, false);
237 class AcceleratedCompositingTest : public GpuFeatureTest {
238 public:
239 virtual void SetUpCommandLine(CommandLine* command_line) {
240 GpuFeatureTest::SetUpCommandLine(command_line);
241 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
245 #if defined(OS_WIN) && defined(USE_AURA)
246 // Compositing is always on for Windows Aura.
247 #define MAYBE_AcceleratedCompositingDisabled DISABLED_AcceleratedCompositingDisabled
248 #else
249 #define MAYBE_AcceleratedCompositingDisabled AcceleratedCompositingDisabled
250 #endif
252 IN_PROC_BROWSER_TEST_F(AcceleratedCompositingTest,
253 MAYBE_AcceleratedCompositingDisabled) {
254 // Compositing is always on for Windows Aura.
255 const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
256 RunEventTest(url, kSwapBuffersEvent, false);
259 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLAllowed) {
260 GpuFeatureType type =
261 GpuDataManager::GetInstance()->GetBlacklistedFeatures();
262 EXPECT_EQ(type, 0);
264 const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
265 RunEventTest(url, kWebGLCreationEvent, true);
268 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLBlocked) {
269 const std::string json_blacklist =
270 "{\n"
271 " \"name\": \"gpu blacklist\",\n"
272 " \"version\": \"1.0\",\n"
273 " \"entries\": [\n"
274 " {\n"
275 " \"id\": 1,\n"
276 " \"blacklist\": [\n"
277 " \"webgl\"\n"
278 " ]\n"
279 " }\n"
280 " ]\n"
281 "}";
282 SetupBlacklist(json_blacklist);
283 GpuFeatureType type =
284 GpuDataManager::GetInstance()->GetBlacklistedFeatures();
285 type = IgnoreGpuFeatures(type);
286 EXPECT_EQ(type, content::GPU_FEATURE_TYPE_WEBGL);
288 const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
289 RunEventTest(url, kWebGLCreationEvent, false);
292 class WebGLTest : public GpuFeatureTest {
293 public:
294 virtual void SetUpCommandLine(CommandLine* command_line) {
295 GpuFeatureTest::SetUpCommandLine(command_line);
296 #if !defined(OS_ANDROID)
297 // On Android, WebGL is disabled by default
298 command_line->AppendSwitch(switches::kDisableExperimentalWebGL);
299 #endif
303 IN_PROC_BROWSER_TEST_F(WebGLTest, WebGLDisabled) {
304 const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
305 RunEventTest(url, kWebGLCreationEvent, false);
308 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, MultisamplingAllowed) {
309 GpuFeatureType type =
310 GpuDataManager::GetInstance()->GetBlacklistedFeatures();
311 EXPECT_EQ(type, 0);
313 // Multisampling is not supported if running on top of osmesa.
314 std::string use_gl = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
315 switches::kUseGL);
316 if (use_gl == gfx::kGLImplementationOSMesaName)
317 return;
319 // Linux Intel uses mesa driver, where multisampling is not supported.
320 // Multisampling is also not supported on virtualized mac os.
321 std::vector<std::string> configs;
322 configs.push_back("LINUX INTEL");
323 configs.push_back("MAC VMWARE");
324 if (GPUTestBotConfig::CurrentConfigMatches(configs))
325 return;
327 const FilePath url(FILE_PATH_LITERAL("feature_multisampling.html"));
328 RunTest(url, "\"TRUE\"", true);
331 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, MultisamplingBlocked) {
332 // Multisampling fails on virtualized mac os.
333 if (GPUTestBotConfig::CurrentConfigMatches("MAC VMWARE"))
334 return;
336 const std::string json_blacklist =
337 "{\n"
338 " \"name\": \"gpu blacklist\",\n"
339 " \"version\": \"1.0\",\n"
340 " \"entries\": [\n"
341 " {\n"
342 " \"id\": 1,\n"
343 " \"blacklist\": [\n"
344 " \"multisampling\"\n"
345 " ]\n"
346 " }\n"
347 " ]\n"
348 "}";
349 SetupBlacklist(json_blacklist);
350 GpuFeatureType type =
351 GpuDataManager::GetInstance()->GetBlacklistedFeatures();
352 type = IgnoreGpuFeatures(type);
353 EXPECT_EQ(type, content::GPU_FEATURE_TYPE_MULTISAMPLING);
355 const FilePath url(FILE_PATH_LITERAL("feature_multisampling.html"));
356 RunTest(url, "\"FALSE\"", true);
359 class WebGLMultisamplingTest : public GpuFeatureTest {
360 public:
361 virtual void SetUpCommandLine(CommandLine* command_line) {
362 GpuFeatureTest::SetUpCommandLine(command_line);
363 command_line->AppendSwitch(switches::kDisableGLMultisampling);
367 IN_PROC_BROWSER_TEST_F(WebGLMultisamplingTest, MultisamplingDisabled) {
368 // Multisampling fails on virtualized mac os.
369 if (GPUTestBotConfig::CurrentConfigMatches("MAC VMWARE"))
370 return;
372 const FilePath url(FILE_PATH_LITERAL("feature_multisampling.html"));
373 RunTest(url, "\"FALSE\"", true);
376 #if defined(OS_LINUX)
377 #define MAYBE_Canvas2DAllowed DISABLED_Canvas2DAllowed
378 #else
379 #define MAYBE_Canvas2DAllowed Canvas2DAllowed
380 #endif
381 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, MAYBE_Canvas2DAllowed) {
382 // Accelerated canvas 2D is not supported on XP.
383 if (GPUTestBotConfig::CurrentConfigMatches("XP"))
384 return;
386 GpuFeatureType type =
387 GpuDataManager::GetInstance()->GetBlacklistedFeatures();
388 EXPECT_EQ(type, 0);
390 const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
391 RunEventTest(url, kAcceleratedCanvasCreationEvent, true);
394 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DBlocked) {
395 const std::string json_blacklist =
396 "{\n"
397 " \"name\": \"gpu blacklist\",\n"
398 " \"version\": \"1.0\",\n"
399 " \"entries\": [\n"
400 " {\n"
401 " \"id\": 1,\n"
402 " \"blacklist\": [\n"
403 " \"accelerated_2d_canvas\"\n"
404 " ]\n"
405 " }\n"
406 " ]\n"
407 "}";
408 SetupBlacklist(json_blacklist);
409 GpuFeatureType type =
410 GpuDataManager::GetInstance()->GetBlacklistedFeatures();
411 type = IgnoreGpuFeatures(type);
412 EXPECT_EQ(type, content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS);
414 const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
415 RunEventTest(url, kAcceleratedCanvasCreationEvent, false);
418 class Canvas2DDisabledTest : public GpuFeatureTest {
419 public:
420 virtual void SetUpCommandLine(CommandLine* command_line) {
421 GpuFeatureTest::SetUpCommandLine(command_line);
422 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas);
426 IN_PROC_BROWSER_TEST_F(Canvas2DDisabledTest, Canvas2DDisabled) {
427 const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
428 RunEventTest(url, kAcceleratedCanvasCreationEvent, false);
431 IN_PROC_BROWSER_TEST_F(GpuFeatureTest,
432 CanOpenPopupAndRenderWithWebGLCanvas) {
433 const FilePath url(FILE_PATH_LITERAL("webgl_popup.html"));
434 RunTest(url, "\"SUCCESS\"", false);
437 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, CanOpenPopupAndRenderWith2DCanvas) {
438 const FilePath url(FILE_PATH_LITERAL("canvas_popup.html"));
439 RunTest(url, "\"SUCCESS\"", false);
442 class ThreadedCompositorTest : public GpuFeatureTest {
443 public:
444 virtual void SetUpCommandLine(CommandLine* command_line) {
445 GpuFeatureTest::SetUpCommandLine(command_line);
446 command_line->AppendSwitch(switches::kEnableThreadedCompositing);
450 #if defined(OS_LINUX)
451 // http://crbug.com/157985: test fails on Linux
452 #define MAYBE_ThreadedCompositor DISABLED_ThreadedCompositor
453 #else
454 #define MAYBE_ThreadedCompositor ThreadedCompositor
455 #endif
456 IN_PROC_BROWSER_TEST_F(ThreadedCompositorTest, MAYBE_ThreadedCompositor) {
457 const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
458 RunEventTest(url, kSwapBuffersEvent, true);
462 #if defined(OS_WIN)
463 // http://crbug.com/162343: flaky on Windows
464 #define MAYBE_RafNoDamage DISABLED_RafNoDamage
465 #else
466 #define MAYBE_RafNoDamage RafNoDamage
467 #endif
468 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, MAYBE_RafNoDamage) {
469 trace_categories_ = "-test_*";
470 const FilePath url(FILE_PATH_LITERAL("feature_raf_no_damage.html"));
471 RunEventTest(url);
473 if (!analyzer_.get())
474 return;
476 // Search for matching name on begin event or async_begin event (any begin).
477 Query query_raf =
478 (Query::EventPhaseIs(TRACE_EVENT_PHASE_BEGIN) ||
479 Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_BEGIN)) &&
480 Query::EventNameIs("___RafWithNoDamage___");
481 TraceEventVector events;
482 size_t num_events = analyzer_->FindEvents(query_raf, &events);
484 trace_analyzer::RateStats stats;
485 trace_analyzer::RateStatsOptions stats_options;
486 stats_options.trim_min = stats_options.trim_max = num_events / 10;
487 EXPECT_TRUE(trace_analyzer::GetRateStats(events, &stats, &stats_options));
489 LOG(INFO) << "Number of RAFs: " << num_events <<
490 " Mean: " << stats.mean_us <<
491 " Min: " << stats.min_us <<
492 " Max: " << stats.max_us <<
493 " StdDev: " << stats.standard_deviation_us;
495 // Expect that the average time between RAFs is more than 15ms. That will
496 // indicate that the renderer is not simply spinning on RAF.
497 EXPECT_GT(stats.mean_us, 15000.0);
499 // Print out the trace events upon error to debug failures.
500 if (stats.mean_us <= 15000.0) {
501 fprintf(stderr, "\n\nTRACE JSON:\n\n%s\n\n", trace_events_json_.c_str());
505 #if defined(OS_MACOSX)
506 IN_PROC_BROWSER_TEST_F(GpuFeatureTest, IOSurfaceReuse) {
507 if (!IOSurfaceSupport::Initialize())
508 return;
510 const FilePath url(FILE_PATH_LITERAL("feature_compositing_static.html"));
511 FilePath test_path = gpu_test_dir_.Append(url);
512 ASSERT_TRUE(file_util::PathExists(test_path))
513 << "Missing test file: " << test_path.value();
515 ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(test_path));
517 gfx::Rect bounds = browser()->window()->GetBounds();
518 gfx::Rect new_bounds = bounds;
520 const char* create_event = "IOSurfaceImageTransportSurface::CreateIOSurface";
521 const char* resize_event = "IOSurfaceImageTransportSurface::OnResize";
522 const char* draw_event = "CompositingIOSurfaceMac::DrawIOSurface";
523 Query find_creates = Query::MatchBeginName(create_event);
524 Query find_resizes = Query::MatchBeginName(resize_event) &&
525 Query::EventHasNumberArg("old_width") &&
526 Query::EventHasNumberArg("new_width");
527 Query find_draws = Query::MatchBeginName(draw_event) &&
528 Query::EventHasNumberArg("scale");
530 const int roundup = 64;
531 // A few resize values assuming a roundup of 64 pixels. The test will resize
532 // by these values one at a time and verify that CreateIOSurface only happens
533 // when the rounded width changes.
534 int offsets[] = { 1, roundup - 1, roundup, roundup + 1, 2*roundup};
535 int num_offsets = static_cast<int>(arraysize(offsets));
536 int w_start = bounds.width();
538 for (int offset_i = 0; offset_i < num_offsets; ++offset_i) {
539 new_bounds.set_width(w_start + offsets[offset_i]);
540 ASSERT_TRUE(ResizeAndWait(new_bounds, "gpu", "gpu", resize_event));
542 TraceEventVector resize_events;
543 analyzer_->FindEvents(find_resizes, &resize_events);
544 for (size_t resize_i = 0; resize_i < resize_events.size(); ++resize_i) {
545 const trace_analyzer::TraceEvent* resize = resize_events[resize_i];
546 // Was a create allowed:
547 int old_width = resize->GetKnownArgAsInt("old_width");
548 int new_width = resize->GetKnownArgAsInt("new_width");
549 bool expect_create = (old_width/roundup != new_width/roundup ||
550 old_width == 0);
551 int expected_creates = expect_create ? 1 : 0;
553 // Find the create event inside this resize event (if any). This will
554 // determine if the resize triggered a reallocation of the IOSurface.
555 double begin_time = resize->timestamp;
556 double end_time = begin_time + resize->GetAbsTimeToOtherEvent();
557 Query find_this_create = find_creates &&
558 Query::EventTime() >= Query::Double(begin_time) &&
559 Query::EventTime() <= Query::Double(end_time);
560 TraceEventVector create_events;
561 int num_creates = static_cast<int>(analyzer_->FindEvents(find_this_create,
562 &create_events));
563 EXPECT_EQ(expected_creates, num_creates);
565 // For debugging failures, print out the width and height of each resize:
566 LOG(INFO) <<
567 base::StringPrintf(
568 "%d (resize offset %d): IOSurface width %d -> %d; Creates %d "
569 "Expected %d", offset_i, offsets[offset_i],
570 old_width, new_width, num_creates, expected_creates);
574 #endif
576 } // namespace anonymous