1 // Copyright (c) 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file contains some useful utilities for the ui/gl classes.
6 
7 #include "ui/gl/gl_utils.h"
8 
9 #include "base/debug/alias.h"
10 #include "base/logging.h"
11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/gl_features.h"
13 #include "ui/gl/gl_switches.h"
14 
15 #if defined(OS_ANDROID)
16 #include "base/posix/eintr_wrapper.h"
17 #include "third_party/libsync/src/include/sync/sync.h"
18 #endif
19 
20 #if defined(OS_WIN)
21 #include "ui/gl/direct_composition_surface_win.h"
22 #endif
23 
24 namespace gl {
25 
26 // Used by chrome://gpucrash and gpu_benchmarking_extension's
27 // CrashForTesting.
Crash()28 void Crash() {
29   DVLOG(1) << "GPU: Simulating GPU crash";
30   // Good bye, cruel world.
31   volatile int* it_s_the_end_of_the_world_as_we_know_it = nullptr;
32   *it_s_the_end_of_the_world_as_we_know_it = 0xdead;
33 }
34 
35 // Used by chrome://gpuhang.
Hang()36 void Hang() {
37   DVLOG(1) << "GPU: Simulating GPU hang";
38   int do_not_delete_me = 0;
39   for (;;) {
40     // Do not sleep here. The GPU watchdog timer tracks
41     // the amount of user time this thread is using and
42     // it doesn't use much while calling Sleep.
43 
44     // The following are multiple mechanisms to prevent compilers from
45     // optimizing out the endless loop. Hope at least one of them works.
46     base::debug::Alias(&do_not_delete_me);
47     ++do_not_delete_me;
48 
49 #ifdef _MSC_VER
50     _ReadWriteBarrier();
51 #else
52     __asm__ volatile("");
53 #endif
54   }
55 }
56 
57 #if defined(OS_ANDROID)
MergeFDs(base::ScopedFD a,base::ScopedFD b)58 base::ScopedFD MergeFDs(base::ScopedFD a, base::ScopedFD b) {
59   if (!a.is_valid())
60     return b;
61   if (!b.is_valid())
62     return a;
63 
64   base::ScopedFD merged(HANDLE_EINTR(sync_merge("", a.get(), b.get())));
65   if (!merged.is_valid())
66     LOG(ERROR) << "Failed to merge fences.";
67   return merged;
68 }
69 #endif
70 
UsePassthroughCommandDecoder(const base::CommandLine * command_line)71 bool UsePassthroughCommandDecoder(const base::CommandLine* command_line) {
72   std::string switch_value;
73   if (command_line->HasSwitch(switches::kUseCmdDecoder)) {
74     switch_value = command_line->GetSwitchValueASCII(switches::kUseCmdDecoder);
75   }
76 
77   if (switch_value == kCmdDecoderPassthroughName) {
78     return true;
79   } else if (switch_value == kCmdDecoderValidatingName) {
80     return false;
81   } else {
82     // Unrecognized or missing switch, use the default.
83     return base::FeatureList::IsEnabled(
84         features::kDefaultPassthroughCommandDecoder);
85   }
86 }
87 
88 #if defined(OS_WIN)
89 // This function is thread safe.
AreOverlaysSupportedWin()90 bool AreOverlaysSupportedWin() {
91   return gl::DirectCompositionSurfaceWin::AreOverlaysSupported();
92 }
93 #endif
94 }  // namespace gl
95