xref: /aosp_15_r20/external/angle/src/common/system_utils_win.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // system_utils_win.cpp: Implementation of OS-specific functions for Windows
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "system_utils.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include <fileapi.h>
12*8975f5c5SAndroid Build Coastguard Worker #include <stdarg.h>
13*8975f5c5SAndroid Build Coastguard Worker #include <windows.h>
14*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
15*8975f5c5SAndroid Build Coastguard Worker #include <array>
16*8975f5c5SAndroid Build Coastguard Worker #include <vector>
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker namespace angle
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker namespace
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker 
GetPath(HMODULE module)24*8975f5c5SAndroid Build Coastguard Worker std::string GetPath(HMODULE module)
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker     std::array<wchar_t, MAX_PATH> executableFileBuf;
27*8975f5c5SAndroid Build Coastguard Worker     DWORD executablePathLen = GetModuleFileNameW(module, executableFileBuf.data(),
28*8975f5c5SAndroid Build Coastguard Worker                                                  static_cast<DWORD>(executableFileBuf.size()));
29*8975f5c5SAndroid Build Coastguard Worker     return Narrow(executablePathLen > 0 ? executableFileBuf.data() : L"");
30*8975f5c5SAndroid Build Coastguard Worker }
31*8975f5c5SAndroid Build Coastguard Worker 
GetDirectory(HMODULE module)32*8975f5c5SAndroid Build Coastguard Worker std::string GetDirectory(HMODULE module)
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker     std::string executablePath = GetPath(module);
35*8975f5c5SAndroid Build Coastguard Worker     return StripFilenameFromPath(executablePath);
36*8975f5c5SAndroid Build Coastguard Worker }
37*8975f5c5SAndroid Build Coastguard Worker 
38*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
39*8975f5c5SAndroid Build Coastguard Worker 
GetExecutablePath()40*8975f5c5SAndroid Build Coastguard Worker std::string GetExecutablePath()
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker     return GetPath(nullptr);
43*8975f5c5SAndroid Build Coastguard Worker }
44*8975f5c5SAndroid Build Coastguard Worker 
GetExecutableDirectory()45*8975f5c5SAndroid Build Coastguard Worker std::string GetExecutableDirectory()
46*8975f5c5SAndroid Build Coastguard Worker {
47*8975f5c5SAndroid Build Coastguard Worker     return GetDirectory(nullptr);
48*8975f5c5SAndroid Build Coastguard Worker }
49*8975f5c5SAndroid Build Coastguard Worker 
GetSharedLibraryExtension()50*8975f5c5SAndroid Build Coastguard Worker const char *GetSharedLibraryExtension()
51*8975f5c5SAndroid Build Coastguard Worker {
52*8975f5c5SAndroid Build Coastguard Worker     return "dll";
53*8975f5c5SAndroid Build Coastguard Worker }
54*8975f5c5SAndroid Build Coastguard Worker 
GetCWD()55*8975f5c5SAndroid Build Coastguard Worker Optional<std::string> GetCWD()
56*8975f5c5SAndroid Build Coastguard Worker {
57*8975f5c5SAndroid Build Coastguard Worker     std::array<wchar_t, MAX_PATH> pathBuf;
58*8975f5c5SAndroid Build Coastguard Worker     DWORD result = GetCurrentDirectoryW(static_cast<DWORD>(pathBuf.size()), pathBuf.data());
59*8975f5c5SAndroid Build Coastguard Worker     if (result == 0)
60*8975f5c5SAndroid Build Coastguard Worker     {
61*8975f5c5SAndroid Build Coastguard Worker         return Optional<std::string>::Invalid();
62*8975f5c5SAndroid Build Coastguard Worker     }
63*8975f5c5SAndroid Build Coastguard Worker     return Narrow(pathBuf.data());
64*8975f5c5SAndroid Build Coastguard Worker }
65*8975f5c5SAndroid Build Coastguard Worker 
SetCWD(const char * dirName)66*8975f5c5SAndroid Build Coastguard Worker bool SetCWD(const char *dirName)
67*8975f5c5SAndroid Build Coastguard Worker {
68*8975f5c5SAndroid Build Coastguard Worker     return (SetCurrentDirectoryW(Widen(dirName).c_str()) == TRUE);
69*8975f5c5SAndroid Build Coastguard Worker }
70*8975f5c5SAndroid Build Coastguard Worker 
GetPathSeparatorForEnvironmentVar()71*8975f5c5SAndroid Build Coastguard Worker const char *GetPathSeparatorForEnvironmentVar()
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker     return ";";
74*8975f5c5SAndroid Build Coastguard Worker }
75*8975f5c5SAndroid Build Coastguard Worker 
GetCurrentSystemTime()76*8975f5c5SAndroid Build Coastguard Worker double GetCurrentSystemTime()
77*8975f5c5SAndroid Build Coastguard Worker {
78*8975f5c5SAndroid Build Coastguard Worker     LARGE_INTEGER frequency = {};
79*8975f5c5SAndroid Build Coastguard Worker     QueryPerformanceFrequency(&frequency);
80*8975f5c5SAndroid Build Coastguard Worker 
81*8975f5c5SAndroid Build Coastguard Worker     LARGE_INTEGER curTime;
82*8975f5c5SAndroid Build Coastguard Worker     QueryPerformanceCounter(&curTime);
83*8975f5c5SAndroid Build Coastguard Worker 
84*8975f5c5SAndroid Build Coastguard Worker     return static_cast<double>(curTime.QuadPart) / frequency.QuadPart;
85*8975f5c5SAndroid Build Coastguard Worker }
86*8975f5c5SAndroid Build Coastguard Worker 
GetCurrentProcessCpuTime()87*8975f5c5SAndroid Build Coastguard Worker double GetCurrentProcessCpuTime()
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker     FILETIME creationTime = {};
90*8975f5c5SAndroid Build Coastguard Worker     FILETIME exitTime     = {};
91*8975f5c5SAndroid Build Coastguard Worker     FILETIME kernelTime   = {};
92*8975f5c5SAndroid Build Coastguard Worker     FILETIME userTime     = {};
93*8975f5c5SAndroid Build Coastguard Worker 
94*8975f5c5SAndroid Build Coastguard Worker     // Note this will not give accurate results if the current thread is
95*8975f5c5SAndroid Build Coastguard Worker     // scheduled for less than the tick rate, which is often 15 ms. In that
96*8975f5c5SAndroid Build Coastguard Worker     // case, GetProcessTimes will not return different values, making it
97*8975f5c5SAndroid Build Coastguard Worker     // possible to end up with 0 ms for a process that takes 93% of a core
98*8975f5c5SAndroid Build Coastguard Worker     // (14/15 ms)!  An alternative is QueryProcessCycleTime but there is no
99*8975f5c5SAndroid Build Coastguard Worker     // simple way to convert cycles back to seconds, and on top of that, it's
100*8975f5c5SAndroid Build Coastguard Worker     // not supported pre-Windows Vista.
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     // Returns 100-ns intervals, so we want to divide by 1e7 to get seconds
103*8975f5c5SAndroid Build Coastguard Worker     GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime);
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     ULARGE_INTEGER kernelInt64;
106*8975f5c5SAndroid Build Coastguard Worker     kernelInt64.LowPart      = kernelTime.dwLowDateTime;
107*8975f5c5SAndroid Build Coastguard Worker     kernelInt64.HighPart     = kernelTime.dwHighDateTime;
108*8975f5c5SAndroid Build Coastguard Worker     double systemTimeSeconds = static_cast<double>(kernelInt64.QuadPart) * 1e-7;
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     ULARGE_INTEGER userInt64;
111*8975f5c5SAndroid Build Coastguard Worker     userInt64.LowPart      = userTime.dwLowDateTime;
112*8975f5c5SAndroid Build Coastguard Worker     userInt64.HighPart     = userTime.dwHighDateTime;
113*8975f5c5SAndroid Build Coastguard Worker     double userTimeSeconds = static_cast<double>(userInt64.QuadPart) * 1e-7;
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker     return systemTimeSeconds + userTimeSeconds;
116*8975f5c5SAndroid Build Coastguard Worker }
117*8975f5c5SAndroid Build Coastguard Worker 
IsDirectory(const char * filename)118*8975f5c5SAndroid Build Coastguard Worker bool IsDirectory(const char *filename)
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker     WIN32_FILE_ATTRIBUTE_DATA fileInformation;
121*8975f5c5SAndroid Build Coastguard Worker 
122*8975f5c5SAndroid Build Coastguard Worker     BOOL result =
123*8975f5c5SAndroid Build Coastguard Worker         GetFileAttributesExW(Widen(filename).c_str(), GetFileExInfoStandard, &fileInformation);
124*8975f5c5SAndroid Build Coastguard Worker     if (result)
125*8975f5c5SAndroid Build Coastguard Worker     {
126*8975f5c5SAndroid Build Coastguard Worker         DWORD attribs = fileInformation.dwFileAttributes;
127*8975f5c5SAndroid Build Coastguard Worker         return (attribs != INVALID_FILE_ATTRIBUTES) && ((attribs & FILE_ATTRIBUTE_DIRECTORY) > 0);
128*8975f5c5SAndroid Build Coastguard Worker     }
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker     return false;
131*8975f5c5SAndroid Build Coastguard Worker }
132*8975f5c5SAndroid Build Coastguard Worker 
IsDebuggerAttached()133*8975f5c5SAndroid Build Coastguard Worker bool IsDebuggerAttached()
134*8975f5c5SAndroid Build Coastguard Worker {
135*8975f5c5SAndroid Build Coastguard Worker     return !!::IsDebuggerPresent();
136*8975f5c5SAndroid Build Coastguard Worker }
137*8975f5c5SAndroid Build Coastguard Worker 
BreakDebugger()138*8975f5c5SAndroid Build Coastguard Worker void BreakDebugger()
139*8975f5c5SAndroid Build Coastguard Worker {
140*8975f5c5SAndroid Build Coastguard Worker     __debugbreak();
141*8975f5c5SAndroid Build Coastguard Worker }
142*8975f5c5SAndroid Build Coastguard Worker 
GetExecutableExtension()143*8975f5c5SAndroid Build Coastguard Worker const char *GetExecutableExtension()
144*8975f5c5SAndroid Build Coastguard Worker {
145*8975f5c5SAndroid Build Coastguard Worker     return ".exe";
146*8975f5c5SAndroid Build Coastguard Worker }
147*8975f5c5SAndroid Build Coastguard Worker 
GetPathSeparator()148*8975f5c5SAndroid Build Coastguard Worker char GetPathSeparator()
149*8975f5c5SAndroid Build Coastguard Worker {
150*8975f5c5SAndroid Build Coastguard Worker     return '\\';
151*8975f5c5SAndroid Build Coastguard Worker }
152*8975f5c5SAndroid Build Coastguard Worker 
GetModuleDirectory()153*8975f5c5SAndroid Build Coastguard Worker std::string GetModuleDirectory()
154*8975f5c5SAndroid Build Coastguard Worker {
155*8975f5c5SAndroid Build Coastguard Worker // GetModuleHandleEx is unavailable on UWP
156*8975f5c5SAndroid Build Coastguard Worker #if !defined(ANGLE_IS_WINUWP)
157*8975f5c5SAndroid Build Coastguard Worker     static int placeholderSymbol = 0;
158*8975f5c5SAndroid Build Coastguard Worker     HMODULE module               = nullptr;
159*8975f5c5SAndroid Build Coastguard Worker     if (GetModuleHandleExW(
160*8975f5c5SAndroid Build Coastguard Worker             GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
161*8975f5c5SAndroid Build Coastguard Worker             reinterpret_cast<LPCWSTR>(&placeholderSymbol), &module))
162*8975f5c5SAndroid Build Coastguard Worker     {
163*8975f5c5SAndroid Build Coastguard Worker         return GetDirectory(module);
164*8975f5c5SAndroid Build Coastguard Worker     }
165*8975f5c5SAndroid Build Coastguard Worker #endif
166*8975f5c5SAndroid Build Coastguard Worker     return GetDirectory(nullptr);
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker 
GetRootDirectory()169*8975f5c5SAndroid Build Coastguard Worker std::string GetRootDirectory()
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker     return "C:\\";
172*8975f5c5SAndroid Build Coastguard Worker }
173*8975f5c5SAndroid Build Coastguard Worker 
CreateDirectories(const std::string & path)174*8975f5c5SAndroid Build Coastguard Worker bool CreateDirectories(const std::string &path)
175*8975f5c5SAndroid Build Coastguard Worker {
176*8975f5c5SAndroid Build Coastguard Worker     // First sanitize path so we can use "/" as universal path separator
177*8975f5c5SAndroid Build Coastguard Worker     std::string sanitizedPath(path);
178*8975f5c5SAndroid Build Coastguard Worker     MakeForwardSlashThePathSeparator(sanitizedPath);
179*8975f5c5SAndroid Build Coastguard Worker 
180*8975f5c5SAndroid Build Coastguard Worker     size_t pos = 0;
181*8975f5c5SAndroid Build Coastguard Worker     do
182*8975f5c5SAndroid Build Coastguard Worker     {
183*8975f5c5SAndroid Build Coastguard Worker         pos = sanitizedPath.find("/", pos);
184*8975f5c5SAndroid Build Coastguard Worker         std::string checkPath(sanitizedPath.substr(0, pos));
185*8975f5c5SAndroid Build Coastguard Worker         if (!checkPath.empty() && !IsDirectory(checkPath.c_str()))
186*8975f5c5SAndroid Build Coastguard Worker         {
187*8975f5c5SAndroid Build Coastguard Worker             if (!CreateDirectoryW(Widen(checkPath).c_str(), nullptr))
188*8975f5c5SAndroid Build Coastguard Worker             {
189*8975f5c5SAndroid Build Coastguard Worker                 return false;
190*8975f5c5SAndroid Build Coastguard Worker             }
191*8975f5c5SAndroid Build Coastguard Worker         }
192*8975f5c5SAndroid Build Coastguard Worker         if (pos == std::string::npos)
193*8975f5c5SAndroid Build Coastguard Worker         {
194*8975f5c5SAndroid Build Coastguard Worker             break;
195*8975f5c5SAndroid Build Coastguard Worker         }
196*8975f5c5SAndroid Build Coastguard Worker         ++pos;
197*8975f5c5SAndroid Build Coastguard Worker     } while (true);
198*8975f5c5SAndroid Build Coastguard Worker     return true;
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker 
MakeForwardSlashThePathSeparator(std::string & path)201*8975f5c5SAndroid Build Coastguard Worker void MakeForwardSlashThePathSeparator(std::string &path)
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker     std::replace(path.begin(), path.end(), '\\', '/');
204*8975f5c5SAndroid Build Coastguard Worker     return;
205*8975f5c5SAndroid Build Coastguard Worker }
206*8975f5c5SAndroid Build Coastguard Worker 
GetTempDirectory()207*8975f5c5SAndroid Build Coastguard Worker Optional<std::string> GetTempDirectory()
208*8975f5c5SAndroid Build Coastguard Worker {
209*8975f5c5SAndroid Build Coastguard Worker     char tempDirOut[MAX_PATH + 1];
210*8975f5c5SAndroid Build Coastguard Worker     GetTempPathA(MAX_PATH + 1, tempDirOut);
211*8975f5c5SAndroid Build Coastguard Worker     std::string tempDir = std::string(tempDirOut);
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker     if (tempDir.length() < 0 || tempDir.length() > MAX_PATH)
214*8975f5c5SAndroid Build Coastguard Worker     {
215*8975f5c5SAndroid Build Coastguard Worker         return Optional<std::string>::Invalid();
216*8975f5c5SAndroid Build Coastguard Worker     }
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker     if (tempDir.length() > 0 && tempDir.back() == '\\')
219*8975f5c5SAndroid Build Coastguard Worker     {
220*8975f5c5SAndroid Build Coastguard Worker         tempDir.pop_back();
221*8975f5c5SAndroid Build Coastguard Worker     }
222*8975f5c5SAndroid Build Coastguard Worker 
223*8975f5c5SAndroid Build Coastguard Worker     return tempDir;
224*8975f5c5SAndroid Build Coastguard Worker }
225*8975f5c5SAndroid Build Coastguard Worker 
CreateTemporaryFileInDirectory(const std::string & directory)226*8975f5c5SAndroid Build Coastguard Worker Optional<std::string> CreateTemporaryFileInDirectory(const std::string &directory)
227*8975f5c5SAndroid Build Coastguard Worker {
228*8975f5c5SAndroid Build Coastguard Worker     char fileName[MAX_PATH + 1];
229*8975f5c5SAndroid Build Coastguard Worker     if (GetTempFileNameA(directory.c_str(), "ANGLE", 0, fileName) == 0)
230*8975f5c5SAndroid Build Coastguard Worker         return Optional<std::string>::Invalid();
231*8975f5c5SAndroid Build Coastguard Worker 
232*8975f5c5SAndroid Build Coastguard Worker     return std::string(fileName);
233*8975f5c5SAndroid Build Coastguard Worker }
234*8975f5c5SAndroid Build Coastguard Worker 
GetLibraryPath(void * libraryHandle)235*8975f5c5SAndroid Build Coastguard Worker std::string GetLibraryPath(void *libraryHandle)
236*8975f5c5SAndroid Build Coastguard Worker {
237*8975f5c5SAndroid Build Coastguard Worker     if (!libraryHandle)
238*8975f5c5SAndroid Build Coastguard Worker     {
239*8975f5c5SAndroid Build Coastguard Worker         return "";
240*8975f5c5SAndroid Build Coastguard Worker     }
241*8975f5c5SAndroid Build Coastguard Worker 
242*8975f5c5SAndroid Build Coastguard Worker     std::array<wchar_t, MAX_PATH> buffer;
243*8975f5c5SAndroid Build Coastguard Worker     if (GetModuleFileNameW(reinterpret_cast<HMODULE>(libraryHandle), buffer.data(),
244*8975f5c5SAndroid Build Coastguard Worker                            buffer.size()) == 0)
245*8975f5c5SAndroid Build Coastguard Worker     {
246*8975f5c5SAndroid Build Coastguard Worker         return "";
247*8975f5c5SAndroid Build Coastguard Worker     }
248*8975f5c5SAndroid Build Coastguard Worker 
249*8975f5c5SAndroid Build Coastguard Worker     return Narrow(buffer.data());
250*8975f5c5SAndroid Build Coastguard Worker }
251*8975f5c5SAndroid Build Coastguard Worker 
GetLibrarySymbol(void * libraryHandle,const char * symbolName)252*8975f5c5SAndroid Build Coastguard Worker void *GetLibrarySymbol(void *libraryHandle, const char *symbolName)
253*8975f5c5SAndroid Build Coastguard Worker {
254*8975f5c5SAndroid Build Coastguard Worker     if (!libraryHandle)
255*8975f5c5SAndroid Build Coastguard Worker     {
256*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Module was not loaded\n");
257*8975f5c5SAndroid Build Coastguard Worker         return nullptr;
258*8975f5c5SAndroid Build Coastguard Worker     }
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker     return reinterpret_cast<void *>(
261*8975f5c5SAndroid Build Coastguard Worker         GetProcAddress(reinterpret_cast<HMODULE>(libraryHandle), symbolName));
262*8975f5c5SAndroid Build Coastguard Worker }
263*8975f5c5SAndroid Build Coastguard Worker 
CloseSystemLibrary(void * libraryHandle)264*8975f5c5SAndroid Build Coastguard Worker void CloseSystemLibrary(void *libraryHandle)
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker     if (libraryHandle)
267*8975f5c5SAndroid Build Coastguard Worker     {
268*8975f5c5SAndroid Build Coastguard Worker         FreeLibrary(reinterpret_cast<HMODULE>(libraryHandle));
269*8975f5c5SAndroid Build Coastguard Worker     }
270*8975f5c5SAndroid Build Coastguard Worker }
Narrow(const std::wstring_view & utf16)271*8975f5c5SAndroid Build Coastguard Worker std::string Narrow(const std::wstring_view &utf16)
272*8975f5c5SAndroid Build Coastguard Worker {
273*8975f5c5SAndroid Build Coastguard Worker     if (utf16.empty())
274*8975f5c5SAndroid Build Coastguard Worker     {
275*8975f5c5SAndroid Build Coastguard Worker         return {};
276*8975f5c5SAndroid Build Coastguard Worker     }
277*8975f5c5SAndroid Build Coastguard Worker     int requiredSize = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()),
278*8975f5c5SAndroid Build Coastguard Worker                                            nullptr, 0, nullptr, nullptr);
279*8975f5c5SAndroid Build Coastguard Worker     std::string utf8(requiredSize, '\0');
280*8975f5c5SAndroid Build Coastguard Worker     WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), &utf8[0],
281*8975f5c5SAndroid Build Coastguard Worker                         requiredSize, nullptr, nullptr);
282*8975f5c5SAndroid Build Coastguard Worker     return utf8;
283*8975f5c5SAndroid Build Coastguard Worker }
284*8975f5c5SAndroid Build Coastguard Worker 
Widen(const std::string_view & utf8)285*8975f5c5SAndroid Build Coastguard Worker std::wstring Widen(const std::string_view &utf8)
286*8975f5c5SAndroid Build Coastguard Worker {
287*8975f5c5SAndroid Build Coastguard Worker     if (utf8.empty())
288*8975f5c5SAndroid Build Coastguard Worker     {
289*8975f5c5SAndroid Build Coastguard Worker         return {};
290*8975f5c5SAndroid Build Coastguard Worker     }
291*8975f5c5SAndroid Build Coastguard Worker     int requiredSize =
292*8975f5c5SAndroid Build Coastguard Worker         MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), nullptr, 0);
293*8975f5c5SAndroid Build Coastguard Worker     std::wstring utf16(requiredSize, L'\0');
294*8975f5c5SAndroid Build Coastguard Worker     MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), &utf16[0],
295*8975f5c5SAndroid Build Coastguard Worker                         requiredSize);
296*8975f5c5SAndroid Build Coastguard Worker     return utf16;
297*8975f5c5SAndroid Build Coastguard Worker }
298*8975f5c5SAndroid Build Coastguard Worker 
SetCurrentThreadName(const char * name)299*8975f5c5SAndroid Build Coastguard Worker void SetCurrentThreadName(const char *name)
300*8975f5c5SAndroid Build Coastguard Worker {
301*8975f5c5SAndroid Build Coastguard Worker     // Not implemented
302*8975f5c5SAndroid Build Coastguard Worker }
303*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
304