Commit 5eadaf85 by Jamie Madill Committed by Commit Bot

Fix and improve UWP build.

Reorganizes the build files to work with a more divided setup. It is unclear if we'll ever be able to run tests in a UWP config. This at least sets up the organization so it would at some point be possible. Bug: angleproject:4182 Change-Id: I49dddfcdc0118b11466fe171f949c28d101ac6a2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1953484 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 680a7d3b
......@@ -51,31 +51,6 @@ bool SetCWD(const char *dirName)
return (SetCurrentDirectoryA(dirName) == TRUE);
}
bool UnsetEnvironmentVar(const char *variableName)
{
return (SetEnvironmentVariableA(variableName, nullptr) == TRUE);
}
bool SetEnvironmentVar(const char *variableName, const char *value)
{
return (SetEnvironmentVariableA(variableName, value) == TRUE);
}
std::string GetEnvironmentVar(const char *variableName)
{
std::array<char, MAX_PATH> oldValue;
DWORD result =
GetEnvironmentVariableA(variableName, oldValue.data(), static_cast<DWORD>(oldValue.size()));
if (result == 0)
{
return std::string();
}
else
{
return std::string(oldValue.data());
}
}
const char *GetPathSeparatorForEnvironmentVar()
{
return ";";
......@@ -92,56 +67,6 @@ double GetCurrentTime()
return static_cast<double>(curTime.QuadPart) / frequency.QuadPart;
}
class Win32Library : public Library
{
public:
Win32Library(const char *libraryName, SearchType searchType)
{
char buffer[MAX_PATH];
int ret = snprintf(buffer, MAX_PATH, "%s.%s", libraryName, GetSharedLibraryExtension());
if (ret > 0 && ret < MAX_PATH)
{
switch (searchType)
{
case SearchType::ApplicationDir:
mModule = LoadLibraryA(buffer);
break;
case SearchType::SystemDir:
mModule = LoadLibraryExA(buffer, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
break;
}
}
}
~Win32Library() override
{
if (mModule)
{
FreeLibrary(mModule);
}
}
void *getSymbol(const char *symbolName) override
{
if (!mModule)
{
return nullptr;
}
return reinterpret_cast<void *>(GetProcAddress(mModule, symbolName));
}
void *getNative() const override { return reinterpret_cast<void *>(mModule); }
private:
HMODULE mModule = nullptr;
};
Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
{
return new Win32Library(libraryName, searchType);
}
bool IsDirectory(const char *filename)
{
WIN32_FILE_ATTRIBUTE_DATA fileInformation;
......
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// system_utils_win32.cpp: Implementation of OS-specific functions for Windows.
#include "system_utils.h"
#include <windows.h>
#include <array>
namespace angle
{
bool UnsetEnvironmentVar(const char *variableName)
{
return (SetEnvironmentVariableA(variableName, nullptr) == TRUE);
}
bool SetEnvironmentVar(const char *variableName, const char *value)
{
return (SetEnvironmentVariableA(variableName, value) == TRUE);
}
std::string GetEnvironmentVar(const char *variableName)
{
std::array<char, MAX_PATH> oldValue;
DWORD result =
GetEnvironmentVariableA(variableName, oldValue.data(), static_cast<DWORD>(oldValue.size()));
if (result == 0)
{
return std::string();
}
else
{
return std::string(oldValue.data());
}
}
class Win32Library : public Library
{
public:
Win32Library(const char *libraryName, SearchType searchType)
{
char buffer[MAX_PATH];
int ret = snprintf(buffer, MAX_PATH, "%s.%s", libraryName, GetSharedLibraryExtension());
if (ret > 0 && ret < MAX_PATH)
{
switch (searchType)
{
case SearchType::ApplicationDir:
mModule = LoadLibraryA(buffer);
break;
case SearchType::SystemDir:
mModule = LoadLibraryExA(buffer, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
break;
}
}
}
~Win32Library() override
{
if (mModule)
{
FreeLibrary(mModule);
}
}
void *getSymbol(const char *symbolName) override
{
if (!mModule)
{
return nullptr;
}
return reinterpret_cast<void *>(GetProcAddress(mModule, symbolName));
}
void *getNative() const override { return reinterpret_cast<void *>(mModule); }
private:
HMODULE mModule = nullptr;
};
Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
{
return new Win32Library(libraryName, searchType);
}
} // namespace angle
......@@ -14,9 +14,6 @@
#include <codecvt>
#include <locale>
#include <string>
#include <vector>
#include "common/debug.h"
namespace angle
{
......@@ -33,37 +30,6 @@ std::string GetEnvironmentVar(const char *variableName)
return "";
}
const char *GetPathSeparatorForEnvironmentVar()
{
return ";";
}
const char *GetSharedLibraryExtension()
{
return "dll";
}
const char *GetExecutableExtension()
{
return ".exe";
}
char GetPathSeparator()
{
return '\\';
}
double GetCurrentTime()
{
LARGE_INTEGER frequency = {};
QueryPerformanceFrequency(&frequency);
LARGE_INTEGER curTime;
QueryPerformanceCounter(&curTime);
return static_cast<double>(curTime.QuadPart) / frequency.QuadPart;
}
class UwpLibrary : public Library
{
public:
......@@ -117,14 +83,4 @@ Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
{
return new UwpLibrary(libraryName, searchType);
}
bool IsDebuggerAttached()
{
return !!::IsDebuggerPresent();
}
void BreakDebugger()
{
__debugbreak();
}
} // namespace angle
......@@ -21,7 +21,7 @@ bool IsCoreWindow(EGLNativeWindowType window,
return false;
}
ComPtr<IInspectable> win = window;
ComPtr<IInspectable> win = reinterpret_cast<IInspectable *>(window);
ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin;
if (SUCCEEDED(win.As(&coreWin)))
{
......
......@@ -38,7 +38,7 @@ bool NativeWindow11WinRT::initialize()
// to use the EGLNativeWindowType specified in the property set.
// mWindow is treated as a raw pointer not an AddRef'd interface, so
// the old mWindow does not need a Release() before this assignment.
window = eglNativeWindow.Get();
window = reinterpret_cast<EGLNativeWindowType>(eglNativeWindow.Get());
}
ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
......
......@@ -89,10 +89,11 @@ if (is_mac) {
}
if (is_win) {
angle_system_utils_sources += [ "src/common/system_utils_win.cpp" ]
if (current_os == "winuwp") {
angle_system_utils_sources += [ "src/common/system_utils_winuwp.cpp" ]
} else {
angle_system_utils_sources += [ "src/common/system_utils_win.cpp" ]
angle_system_utils_sources += [ "src/common/system_utils_win32.cpp" ]
}
}
......
......@@ -214,7 +214,7 @@ namespace
{
// The following WaitForDebugger code is based on SwiftShader. See:
// https://cs.chromium.org/chromium/src/third_party/swiftshader/src/Vulkan/main.cpp
# if defined(ANGLE_ENABLE_ASSERTS)
# if defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
RECT rect;
......@@ -259,7 +259,7 @@ void WaitForDebugger(HINSTANCE instance)
}
# else
void WaitForDebugger(HINSTANCE instance) {}
# endif // defined(ANGLE_ENABLE_ASSERTS)
# endif // defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
} // namespace
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
......
......@@ -268,12 +268,12 @@ angle_source_set("angle_test_utils") {
]
if (is_win) {
sources += [
"windows/test_utils_win.cpp",
"windows/win32/test_utils_win32.cpp",
]
if (!angle_is_winuwp) {
sources += [ "windows/test_utils_win.cpp" ]
if (angle_is_winuwp) {
sources += [ "windows/test_utils_winuwp.cpp" ]
} else {
deps += [ ":angle_stack_walker" ]
sources += [ "windows/win32/test_utils_win32.cpp" ]
}
} else {
sources += [
......
# Copyright 2014 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
util_sources = [
"util/com_utils.h",
"util/keyboard.h",
"util/geometry_utils.cpp",
"util/geometry_utils.h",
"util/mouse.h",
"util/random_utils.cpp",
"util/random_utils.h",
"util/shader_utils.cpp",
"util/shader_utils.h",
"util/util_export.h",
"util/util_gl.h",
"util/Event.h",
"util/EGLPlatformParameters.h",
"util/EGLWindow.cpp",
"util/EGLWindow.h",
"util/Matrix.cpp",
"util/Matrix.h",
"util/OSPixmap.h",
"util/OSWindow.cpp",
"util/OSWindow.h",
]
if (is_win) {
util_sources += [ "util/windows/WGLWindow.h" ]
if (target_os != "winuwp") {
util_sources += [
"util/windows/win32/Win32Pixmap.cpp",
"util/windows/win32/Win32Pixmap.h",
"util/windows/win32/Win32Window.cpp",
"util/windows/win32/Win32Window.h",
]
}
}
util_x11_sources = [
"util/x11/X11Pixmap.cpp",
"util/x11/X11Pixmap.h",
"util/x11/X11Window.cpp",
"util/x11/X11Window.h",
]
util_fuchsia_sources = [
"util/fuchsia/ScenicWindow.cpp",
"util/fuchsia/ScenicWindow.h",
]
util_ozone_sources = [
"util/ozone/OzonePixmap.cpp",
"util/ozone/OzoneWindow.cpp",
"util/ozone/OzoneWindow.h",
]
util_osx_sources = [
"util/osx/OSXPixmap.mm",
"util/osx/OSXPixmap.h",
"util/osx/OSXWindow.mm",
"util/osx/OSXWindow.h",
]
util_android_sources = [
"util/android/AndroidPixmap.cpp",
"util/android/AndroidWindow.cpp",
"util/android/AndroidWindow.h",
"util/android/third_party/android_native_app_glue.c",
"util/android/third_party/android_native_app_glue.h",
]
......@@ -18,110 +18,11 @@
#include "anglebase/no_destructor.h"
#include "common/angleutils.h"
#include "util/windows/third_party/StackWalker/src/StackWalker.h"
namespace angle
{
namespace
{
static const struct
{
const char *name;
const DWORD code;
} kExceptions[] = {
#define _(E) \
{ \
# E, E \
}
_(EXCEPTION_ACCESS_VIOLATION),
_(EXCEPTION_BREAKPOINT),
_(EXCEPTION_INT_DIVIDE_BY_ZERO),
_(EXCEPTION_STACK_OVERFLOW),
#undef _
};
class CustomStackWalker : public StackWalker
{
public:
CustomStackWalker() {}
~CustomStackWalker() override {}
void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) override
{
char buffer[STACKWALK_MAX_NAMELEN];
size_t maxLen = _TRUNCATE;
if ((eType != lastEntry) && (entry.offset != 0))
{
if (entry.name[0] == 0)
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)",
_TRUNCATE);
if (entry.undName[0] != 0)
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, entry.undName, _TRUNCATE);
if (entry.undFullName[0] != 0)
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName, _TRUNCATE);
if (entry.lineFileName[0] == 0)
{
strncpy_s(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)",
_TRUNCATE);
if (entry.moduleName[0] == 0)
strncpy_s(entry.moduleName, STACKWALK_MAX_NAMELEN,
"(module-name not available)", _TRUNCATE);
_snprintf_s(buffer, maxLen, " %s - %p (%s): %s\n", entry.name,
reinterpret_cast<void *>(entry.offset), entry.moduleName,
entry.lineFileName);
}
else
_snprintf_s(buffer, maxLen, " %s (%s:%d)\n", entry.name, entry.lineFileName,
entry.lineNumber);
buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
printf("%s", buffer);
OutputDebugStringA(buffer);
}
}
};
void PrintBacktrace(CONTEXT *c)
{
printf("Backtrace:\n");
OutputDebugStringA("Backtrace:\n");
CustomStackWalker sw;
sw.ShowCallstack(GetCurrentThread(), c);
}
LONG WINAPI StackTraceCrashHandler(EXCEPTION_POINTERS *e)
{
const DWORD code = e->ExceptionRecord->ExceptionCode;
printf("\nCaught exception %lu", code);
for (size_t i = 0; i < ArraySize(kExceptions); i++)
{
if (kExceptions[i].code == code)
{
printf(" %s", kExceptions[i].name);
}
}
printf("\n");
PrintBacktrace(e->ContextRecord);
// Exit NOW. Don't notify other threads, don't call anything registered with atexit().
_exit(1);
// The compiler wants us to return something. This is what we'd do if we didn't _exit().
return EXCEPTION_EXECUTE_HANDLER;
}
CrashCallback *gCrashHandlerCallback;
LONG WINAPI CrashHandler(EXCEPTION_POINTERS *e)
{
if (gCrashHandlerCallback)
{
(*gCrashHandlerCallback)();
}
return StackTraceCrashHandler(e);
}
struct ScopedPipe
{
~ScopedPipe()
......@@ -168,12 +69,14 @@ struct ScopedPipe
return false;
}
#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
// Ensure the read handles to the pipes are not inherited.
if (::SetHandleInformation(readHandle, HANDLE_FLAG_INHERIT, 0) == FALSE)
{
std::cerr << "Error setting handle info on pipe: " << GetLastError() << "\n";
return false;
}
#endif // !defined(ANGLE_ENABLE_WINDOWS_UWP)
return true;
}
......@@ -220,7 +123,11 @@ bool ReturnSuccessOnNotFound()
// Job objects seems to have problems on the Chromium CI and Windows 7.
bool ShouldUseJobObjects()
{
#if defined(ANGLE_ENABLE_WINDOWS_UWP)
return false;
#else
return (::IsWindows10OrGreater());
#endif
}
class WindowsProcess : public Process
......@@ -284,6 +191,7 @@ class WindowsProcess : public Process
startInfo.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
}
#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
if (captureStdOut || captureStdErr)
{
startInfo.dwFlags |= STARTF_USESTDHANDLES;
......@@ -310,6 +218,7 @@ class WindowsProcess : public Process
return;
}
}
#endif // !defined(ANGLE_ENABLE_WINDOWS_UWP)
// Create the child process.
if (::CreateProcessA(nullptr, commandLineString.data(), nullptr, nullptr,
......@@ -320,6 +229,7 @@ class WindowsProcess : public Process
return;
}
#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
if (mJobHandle != nullptr)
{
if (::AssignProcessToJobObject(mJobHandle, mProcessInfo.hProcess) == FALSE)
......@@ -328,6 +238,7 @@ class WindowsProcess : public Process
return;
}
}
#endif // !defined(ANGLE_ENABLE_WINDOWS_UWP)
// Close the write end of the pipes, so EOF can be generated when child exits.
if (!mStdoutPipe.closeWriteHandle() || !mStderrPipe.closeWriteHandle())
......@@ -434,11 +345,13 @@ class WindowsProcess : public Process
}
mProcessInfo.hProcess = newHandle;
#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
if (::TerminateThread(mProcessInfo.hThread, 1) == FALSE)
{
std::cerr << "TerminateThread failed: " << GetLastError() << "\n";
return false;
}
#endif // !defined(ANGLE_ENABLE_WINDOWS_UWP)
if (::TerminateProcess(mProcessInfo.hProcess, 1) == FALSE)
{
......@@ -458,7 +371,7 @@ class WindowsProcess : public Process
PROCESS_INFORMATION mProcessInfo = {};
HANDLE mJobHandle = nullptr;
};
} // anonymous namespace
} // namespace
void Sleep(unsigned int milliseconds)
{
......@@ -480,29 +393,6 @@ void WriteDebugMessage(const char *format, ...)
OutputDebugStringA(buffer.data());
}
void InitCrashHandler(CrashCallback *callback)
{
if (callback)
{
gCrashHandlerCallback = callback;
}
SetUnhandledExceptionFilter(CrashHandler);
}
void TerminateCrashHandler()
{
gCrashHandlerCallback = nullptr;
SetUnhandledExceptionFilter(nullptr);
}
void PrintStackBacktrace()
{
CONTEXT context;
ZeroMemory(&context, sizeof(CONTEXT));
RtlCaptureContext(&context);
PrintBacktrace(&context);
}
Process *LaunchProcess(const std::vector<const char *> &args,
bool captureStdout,
bool captureStderr)
......@@ -554,9 +444,4 @@ bool DeleteFile(const char *path)
return !!::DeleteFileA(path) ? true : ReturnSuccessOnNotFound();
}
int NumberOfProcessors()
{
return ::GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
}
} // namespace angle
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// test_utils_uwp.cpp: Implementation of test utility functions for WinUWP.
#include "util/test_utils.h"
namespace angle
{
void PrintStackBacktrace()
{
// Not available on UWP
}
void InitCrashHandler(CrashCallback *callback)
{
// Not available on UWP
}
void TerminateCrashHandler()
{
// Not available on UWP
}
int NumberOfProcessors()
{
// A portable implementation could probably use GetLogicalProcessorInformation
return 1;
}
} // namespace angle
......@@ -11,8 +11,111 @@
#include <windows.h>
#include <array>
#include "util/windows/third_party/StackWalker/src/StackWalker.h"
namespace angle
{
namespace
{
static const struct
{
const char *name;
const DWORD code;
} kExceptions[] = {
#define _(E) \
{ \
# E, E \
}
_(EXCEPTION_ACCESS_VIOLATION),
_(EXCEPTION_BREAKPOINT),
_(EXCEPTION_INT_DIVIDE_BY_ZERO),
_(EXCEPTION_STACK_OVERFLOW),
#undef _
};
class CustomStackWalker : public StackWalker
{
public:
CustomStackWalker() {}
~CustomStackWalker() override {}
void OnCallstackEntry(CallstackEntryType eType, CallstackEntry &entry) override
{
char buffer[STACKWALK_MAX_NAMELEN];
size_t maxLen = _TRUNCATE;
if ((eType != lastEntry) && (entry.offset != 0))
{
if (entry.name[0] == 0)
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)",
_TRUNCATE);
if (entry.undName[0] != 0)
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, entry.undName, _TRUNCATE);
if (entry.undFullName[0] != 0)
strncpy_s(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName, _TRUNCATE);
if (entry.lineFileName[0] == 0)
{
strncpy_s(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)",
_TRUNCATE);
if (entry.moduleName[0] == 0)
strncpy_s(entry.moduleName, STACKWALK_MAX_NAMELEN,
"(module-name not available)", _TRUNCATE);
_snprintf_s(buffer, maxLen, " %s - %p (%s): %s\n", entry.name,
reinterpret_cast<void *>(entry.offset), entry.moduleName,
entry.lineFileName);
}
else
_snprintf_s(buffer, maxLen, " %s (%s:%d)\n", entry.name, entry.lineFileName,
entry.lineNumber);
buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
printf("%s", buffer);
OutputDebugStringA(buffer);
}
}
};
void PrintBacktrace(CONTEXT *c)
{
printf("Backtrace:\n");
OutputDebugStringA("Backtrace:\n");
CustomStackWalker sw;
sw.ShowCallstack(GetCurrentThread(), c);
}
LONG WINAPI StackTraceCrashHandler(EXCEPTION_POINTERS *e)
{
const DWORD code = e->ExceptionRecord->ExceptionCode;
printf("\nCaught exception %lu", code);
for (size_t i = 0; i < ArraySize(kExceptions); i++)
{
if (kExceptions[i].code == code)
{
printf(" %s", kExceptions[i].name);
}
}
printf("\n");
PrintBacktrace(e->ContextRecord);
// Exit NOW. Don't notify other threads, don't call anything registered with atexit().
_exit(1);
// The compiler wants us to return something. This is what we'd do if we didn't _exit().
return EXCEPTION_EXECUTE_HANDLER;
}
CrashCallback *gCrashHandlerCallback;
LONG WINAPI CrashHandler(EXCEPTION_POINTERS *e)
{
if (gCrashHandlerCallback)
{
(*gCrashHandlerCallback)();
}
return StackTraceCrashHandler(e);
}
} // namespace
void SetLowPriorityProcess()
{
::SetPriorityClass(::GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
......@@ -35,4 +138,33 @@ bool StabilizeCPUForBenchmarking()
return true;
}
void PrintStackBacktrace()
{
CONTEXT context;
ZeroMemory(&context, sizeof(CONTEXT));
RtlCaptureContext(&context);
PrintBacktrace(&context);
}
void InitCrashHandler(CrashCallback *callback)
{
if (callback)
{
gCrashHandlerCallback = callback;
}
SetUnhandledExceptionFilter(CrashHandler);
}
void TerminateCrashHandler()
{
gCrashHandlerCallback = nullptr;
SetUnhandledExceptionFilter(nullptr);
}
int NumberOfProcessors()
{
// A portable implementation could probably use GetLogicalProcessorInformation
return ::GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
}
} // namespace angle
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment