Commit 13a8c4d8 by Yuly Novikov Committed by Commit Bot

Fix several WGL test failures.

SimpleOperationTest.ClearAndSwap/ES2_WGL failed when run in isolation, since getGLWindow()->hasError() would report a previous error, instead of result of swapBuffers(). When running after an OPENGL test, swapBuffers() would clear the previous error, but that doesn't happen in isolation. The previous error is from loading WGL functions, some of which are expected not to be present. Clear the error in GetProcAddressWithFallback, but verify that there is no error entering it. This uncovers more errors in angle_perftests: DrawCallPerfBenchmark.Run/wgl DrawCallPerfBenchmark.Run/wgl_tex_change DrawCallPerfBenchmark.Run/wgl_vbo_change DrawElementsPerfBenchmark.Run/wgl_ushort They come from redundant calls when destroying a window. Fix this as well. Several more errors where uncovered by debug prints, fix those, too. Bug: angleproject:3153 Change-Id: I559c098be9dcdfd3add83f045f745d190250b986 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1515602 Commit-Queue: Yuly Novikov <ynovikov@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 4e87659e
...@@ -241,9 +241,20 @@ bool GetSystemInfo(SystemInfo *info) ...@@ -241,9 +241,20 @@ bool GetSystemInfo(SystemInfo *info)
} }
ASSERT(foundPrimary); ASSERT(foundPrimary);
ASSERT(GetLastError() == ERROR_SUCCESS);
// nvd3d9wrap.dll is loaded into all processes when Optimus is enabled. // nvd3d9wrap.dll is loaded into all processes when Optimus is enabled.
HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll"); HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll");
info->isOptimus = nvd3d9wrap != nullptr; info->isOptimus = nvd3d9wrap != nullptr;
// ERROR_MOD_NOT_FOUND is expected from GetModuleHandleW, reset last error if it happens.
if (GetLastError() != ERROR_SUCCESS && GetLastError() != ERROR_MOD_NOT_FOUND)
{
WARN() << "Unexpected error calling GetModuleHandleW: 0x" << std::hex << GetLastError()
<< std::endl;
}
else
{
SetLastError(ERROR_SUCCESS);
}
return true; return true;
} }
......
...@@ -9,9 +9,11 @@ ...@@ -9,9 +9,11 @@
#include "util/windows/WGLWindow.h" #include "util/windows/WGLWindow.h"
#include "common/debug.h"
#include "common/string_utils.h" #include "common/string_utils.h"
#include "util/OSWindow.h" #include "util/OSWindow.h"
#include "util/system_utils.h" #include "util/system_utils.h"
#include "util/windows/win32/Win32Window.h"
#include <iostream> #include <iostream>
...@@ -39,24 +41,44 @@ HMODULE gCurrentModule = nullptr; ...@@ -39,24 +41,44 @@ HMODULE gCurrentModule = nullptr;
angle::GenericProc WINAPI GetProcAddressWithFallback(const char *name) angle::GenericProc WINAPI GetProcAddressWithFallback(const char *name)
{ {
ASSERT(GetLastError() == ERROR_SUCCESS);
angle::GenericProc proc = reinterpret_cast<angle::GenericProc>(gCurrentWGLGetProcAddress(name)); angle::GenericProc proc = reinterpret_cast<angle::GenericProc>(gCurrentWGLGetProcAddress(name));
// ERROR_INVALID_HANDLE and ERROR_PROC_NOT_FOUND are expected from wglGetProcAddress,
// reset last error if they happen.
if (GetLastError() != ERROR_SUCCESS && GetLastError() != ERROR_INVALID_HANDLE &&
GetLastError() != ERROR_PROC_NOT_FOUND)
{
std::cerr << "Unexpected error calling wglGetProcAddress: 0x" << std::hex << GetLastError()
<< std::endl;
}
else
{
SetLastError(ERROR_SUCCESS);
}
if (proc) if (proc)
{ {
return proc; return proc;
} }
return reinterpret_cast<angle::GenericProc>(GetProcAddress(gCurrentModule, name)); proc = reinterpret_cast<angle::GenericProc>(GetProcAddress(gCurrentModule, name));
// ERROR_PROC_NOT_FOUND is expected from GetProcAddress, reset last error if it happens.
if (GetLastError() != ERROR_SUCCESS && GetLastError() != ERROR_PROC_NOT_FOUND)
{
std::cerr << "Unexpected error calling GetProcAddress: 0x" << std::hex << GetLastError()
<< std::endl;
}
else
{
SetLastError(ERROR_SUCCESS);
}
return proc;
} }
bool HasExtension(const std::vector<std::string> &extensions, const char *ext) bool HasExtension(const std::vector<std::string> &extensions, const char *ext)
{ {
return std::find(extensions.begin(), extensions.end(), ext) != extensions.end(); return std::find(extensions.begin(), extensions.end(), ext) != extensions.end();
} }
void DumpLastWindowsError()
{
std::cerr << "Last Windows error code: 0x" << std::hex << GetLastError() << std::endl;
}
} // namespace } // namespace
WGLWindow::WGLWindow(int glesMajorVersion, int glesMinorVersion) WGLWindow::WGLWindow(int glesMajorVersion, int glesMinorVersion)
...@@ -82,30 +104,15 @@ bool WGLWindow::initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibr ...@@ -82,30 +104,15 @@ bool WGLWindow::initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibr
gCurrentModule = reinterpret_cast<HMODULE>(glWindowingLibrary->getNative()); gCurrentModule = reinterpret_cast<HMODULE>(glWindowingLibrary->getNative());
angle::LoadWGL(GetProcAddressWithFallback); angle::LoadWGL(GetProcAddressWithFallback);
mWindow = osWindow->getNativeWindow(); Win32Window *win32Window = static_cast<Win32Window *>(osWindow);
mDeviceContext = GetDC(mWindow); if (!win32Window->setPixelFormat(GetDefaultPixelFormatDescriptor()))
const PIXELFORMATDESCRIPTOR pixelFormatDescriptor = GetDefaultPixelFormatDescriptor();
int pixelFormat = ChoosePixelFormat(mDeviceContext, &pixelFormatDescriptor);
if (pixelFormat == 0)
{ {
std::cerr << "Could not find a compatible pixel format." << std::endl; std::cerr << "Failed to set default pixel format." << std::endl;
DumpLastWindowsError();
return false; return false;
} }
// According to the Windows docs, it is an error to set a pixel format twice. mWindow = osWindow->getNativeWindow();
int currentPixelFormat = GetPixelFormat(mDeviceContext); mDeviceContext = GetDC(mWindow);
if (currentPixelFormat != pixelFormat)
{
if (SetPixelFormat(mDeviceContext, pixelFormat, &pixelFormatDescriptor) != TRUE)
{
std::cerr << "Failed to set the pixel format." << std::endl;
DumpLastWindowsError();
return false;
}
}
mWGLContext = _wglCreateContext(mDeviceContext); mWGLContext = _wglCreateContext(mDeviceContext);
if (!mWGLContext) if (!mWGLContext)
{ {
......
...@@ -8,10 +8,13 @@ ...@@ -8,10 +8,13 @@
#include "util/windows/win32/Win32Window.h" #include "util/windows/win32/Win32Window.h"
#include <iostream>
#include <sstream> #include <sstream>
#include "common/debug.h" #include "common/debug.h"
namespace
{
Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags) Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags)
{ {
switch (key) switch (key)
...@@ -228,6 +231,12 @@ Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags) ...@@ -228,6 +231,12 @@ Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags)
return Key(0); return Key(0);
} }
void DumpLastWindowsError()
{
std::cerr << "Last Windows error code: 0x" << std::hex << GetLastError() << std::endl;
}
} // namespace
LRESULT CALLBACK Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
switch (message) switch (message)
...@@ -485,7 +494,10 @@ LRESULT CALLBACK Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LP ...@@ -485,7 +494,10 @@ LRESULT CALLBACK Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LP
} }
Win32Window::Win32Window() Win32Window::Win32Window()
: mIsVisible(false), : mParentClassRegistered(false),
mChildClassRegistered(false),
mPixelFormatIsSet(false),
mIsVisible(false),
mSetVisibleTimer(CreateTimer()), mSetVisibleTimer(CreateTimer()),
mIsMouseInWindow(false), mIsMouseInWindow(false),
mNativeWindow(0), mNativeWindow(0),
...@@ -531,6 +543,7 @@ bool Win32Window::initialize(const std::string &name, size_t width, size_t heigh ...@@ -531,6 +543,7 @@ bool Win32Window::initialize(const std::string &name, size_t width, size_t heigh
{ {
return false; return false;
} }
mParentClassRegistered = true;
WNDCLASSEXA childWindowClass = {0}; WNDCLASSEXA childWindowClass = {0};
childWindowClass.cbSize = sizeof(WNDCLASSEXA); childWindowClass.cbSize = sizeof(WNDCLASSEXA);
...@@ -548,6 +561,7 @@ bool Win32Window::initialize(const std::string &name, size_t width, size_t heigh ...@@ -548,6 +561,7 @@ bool Win32Window::initialize(const std::string &name, size_t width, size_t heigh
{ {
return false; return false;
} }
mChildClassRegistered = true;
DWORD parentStyle = WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU; DWORD parentStyle = WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
DWORD parentExtendedStyle = WS_EX_APPWINDOW; DWORD parentExtendedStyle = WS_EX_APPWINDOW;
...@@ -560,7 +574,10 @@ bool Win32Window::initialize(const std::string &name, size_t width, size_t heigh ...@@ -560,7 +574,10 @@ bool Win32Window::initialize(const std::string &name, size_t width, size_t heigh
sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top, sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top,
nullptr, nullptr, GetModuleHandle(nullptr), this); nullptr, nullptr, GetModuleHandle(nullptr), this);
mNativeWindow = CreateWindowExA(0, mChildClassName.c_str(), name.c_str(), WS_CHILD, 0, 0, // An OpenGL window should be created with the WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles.
// Additionally, the window class attribute should not include the CS_PARENTDC style.
mNativeWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY, mChildClassName.c_str(), name.c_str(),
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0,
static_cast<int>(width), static_cast<int>(height), static_cast<int>(width), static_cast<int>(height),
mParentWindow, nullptr, GetModuleHandle(nullptr), this); mParentWindow, nullptr, GetModuleHandle(nullptr), this);
...@@ -594,8 +611,16 @@ void Win32Window::destroy() ...@@ -594,8 +611,16 @@ void Win32Window::destroy()
mParentWindow = 0; mParentWindow = 0;
} }
if (mParentClassRegistered)
{
UnregisterClassA(mParentClassName.c_str(), nullptr); UnregisterClassA(mParentClassName.c_str(), nullptr);
mParentClassRegistered = false;
}
if (mChildClassRegistered)
{
UnregisterClassA(mChildClassName.c_str(), nullptr); UnregisterClassA(mChildClassName.c_str(), nullptr);
mChildClassRegistered = false;
}
} }
bool Win32Window::takeScreenshot(uint8_t *pixelData) bool Win32Window::takeScreenshot(uint8_t *pixelData)
...@@ -809,6 +834,52 @@ void Win32Window::setVisible(bool isVisible) ...@@ -809,6 +834,52 @@ void Win32Window::setVisible(bool isVisible)
} }
} }
bool Win32Window::setPixelFormat(const PIXELFORMATDESCRIPTOR pixelFormatDescriptor)
{
HDC deviceContext = GetDC(getNativeWindow());
int pixelFormat = ChoosePixelFormat(deviceContext, &pixelFormatDescriptor);
if (pixelFormat == 0)
{
std::cerr << "Could not find a compatible pixel format." << std::endl;
DumpLastWindowsError();
return false;
}
ASSERT(GetLastError() == ERROR_SUCCESS);
int currentPixelFormat = GetPixelFormat(deviceContext);
if (GetLastError() != ERROR_SUCCESS)
{
// ERROR_INVALID_PIXEL_FORMAT is expected from GetPixelFormat, when !mPixelFormatIsSet,
// reset last error if it happens.
if (mPixelFormatIsSet || GetLastError() != ERROR_INVALID_PIXEL_FORMAT)
{
std::cerr << "Unexpected error calling GetPixelFormat: 0x" << std::hex << GetLastError()
<< std::endl;
return false;
}
else
{
SetLastError(ERROR_SUCCESS);
}
}
// According to the Windows docs, it is an error to set a pixel format twice.
if (mPixelFormatIsSet)
{
return currentPixelFormat == pixelFormat;
}
if (SetPixelFormat(deviceContext, pixelFormat, &pixelFormatDescriptor) != TRUE)
{
std::cerr << "Failed to set the pixel format." << std::endl;
DumpLastWindowsError();
return false;
}
mPixelFormatIsSet = true;
return true;
}
void Win32Window::pushEvent(Event event) void Win32Window::pushEvent(Event event)
{ {
OSWindow::pushEvent(event); OSWindow::pushEvent(event);
...@@ -816,7 +887,10 @@ void Win32Window::pushEvent(Event event) ...@@ -816,7 +887,10 @@ void Win32Window::pushEvent(Event event)
switch (event.Type) switch (event.Type)
{ {
case Event::EVENT_RESIZED: case Event::EVENT_RESIZED:
if (mNativeWindow)
{
MoveWindow(mNativeWindow, 0, 0, mWidth, mHeight, FALSE); MoveWindow(mNativeWindow, 0, 0, mWidth, mHeight, FALSE);
}
break; break;
default: default:
break; break;
......
...@@ -38,6 +38,7 @@ class Win32Window : public OSWindow ...@@ -38,6 +38,7 @@ class Win32Window : public OSWindow
bool setPosition(int x, int y) override; bool setPosition(int x, int y) override;
bool resize(int width, int height) override; bool resize(int width, int height) override;
void setVisible(bool isVisible) override; void setVisible(bool isVisible) override;
bool setPixelFormat(const PIXELFORMATDESCRIPTOR pixelFormatDescriptor);
void signalTestEvent() override; void signalTestEvent() override;
...@@ -46,6 +47,9 @@ class Win32Window : public OSWindow ...@@ -46,6 +47,9 @@ class Win32Window : public OSWindow
std::string mParentClassName; std::string mParentClassName;
std::string mChildClassName; std::string mChildClassName;
bool mParentClassRegistered;
bool mChildClassRegistered;
bool mPixelFormatIsSet;
bool mIsVisible; bool mIsVisible;
Timer *mSetVisibleTimer; Timer *mSetVisibleTimer;
......
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