Commit 435e4910 by Geoff Lang

Don't create child windows in the WGL implementation.

BUG=angleproject:890 Change-Id: I66fb7b97ea3f09d40ba25a769c8bc7fe04527805 Reviewed-on: https://chromium-review.googlesource.com/275307Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent b43846ee
......@@ -73,26 +73,6 @@ DisplayWGL::~DisplayWGL()
{
}
static LRESULT CALLBACK IntermediateWindowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_ERASEBKGND:
// Prevent windows from erasing the background.
return 1;
case WM_PAINT:
// Do not paint anything.
PAINTSTRUCT paint;
if (BeginPaint(window, &paint))
{
EndPaint(window, &paint);
}
return 0;
}
return DefWindowProc(window, message, wParam, lParam);
}
egl::Error DisplayWGL::initialize(egl::Display *display)
{
mDisplay = display;
......@@ -112,24 +92,26 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
// Work around compile error from not defining "UNICODE" while Chromium does
const LPSTR idcArrow = MAKEINTRESOURCEA(32512);
std::string className = FormatString("ANGLE DisplayWGL 0x%0.8p Intermediate Window Class", mDisplay);
WNDCLASSA intermediateClassDesc = { 0 };
intermediateClassDesc.style = CS_OWNDC;
intermediateClassDesc.lpfnWndProc = IntermediateWindowProc;
intermediateClassDesc.lpfnWndProc = DefWindowProc;
intermediateClassDesc.cbClsExtra = 0;
intermediateClassDesc.cbWndExtra = 0;
intermediateClassDesc.hInstance = GetModuleHandle(NULL);
intermediateClassDesc.hIcon = NULL;
intermediateClassDesc.hCursor = LoadCursorA(NULL, idcArrow);
intermediateClassDesc.hInstance = GetModuleHandle(nullptr);
intermediateClassDesc.hIcon = nullptr;
intermediateClassDesc.hCursor = LoadCursorA(nullptr, idcArrow);
intermediateClassDesc.hbrBackground = 0;
intermediateClassDesc.lpszMenuName = NULL;
intermediateClassDesc.lpszClassName = "ANGLE Intermediate Window";
intermediateClassDesc.lpszMenuName = nullptr;
intermediateClassDesc.lpszClassName = className.c_str();
mWindowClass = RegisterClassA(&intermediateClassDesc);
if (!mWindowClass)
{
return egl::Error(EGL_NOT_INITIALIZED, "Failed to register intermediate OpenGL window class.");
}
HWND dummyWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY,
HWND dummyWindow = CreateWindowExA(0,
reinterpret_cast<const char *>(mWindowClass),
"ANGLE Dummy Window",
WS_OVERLAPPEDWINDOW,
......@@ -137,10 +119,10 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
NULL,
NULL);
nullptr,
nullptr,
nullptr,
nullptr);
if (!dummyWindow)
{
return egl::Error(EGL_NOT_INITIALIZED, "Failed to create dummy OpenGL window.");
......@@ -188,16 +170,13 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
mFunctionsWGL->initialize(mOpenGLModule, dummyDeviceContext);
// Destroy the dummy window and context
mFunctionsWGL->makeCurrent(dummyDeviceContext, NULL);
mFunctionsWGL->makeCurrent(dummyDeviceContext, nullptr);
mFunctionsWGL->deleteContext(dummyWGLContext);
ReleaseDC(dummyWindow, dummyDeviceContext);
DestroyWindow(dummyWindow);
// Create the real intermediate context and windows
HDC parentHDC = display->getNativeDisplayId();
HWND parentWindow = WindowFromDC(parentHDC);
mWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY,
mWindow = CreateWindowExA(0,
reinterpret_cast<const char *>(mWindowClass),
"ANGLE Intermediate Window",
WS_OVERLAPPEDWINDOW,
......@@ -205,10 +184,10 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
parentWindow,
NULL,
NULL,
NULL);
nullptr,
nullptr,
nullptr,
nullptr);
if (!mWindow)
{
return egl::Error(EGL_NOT_INITIALIZED, "Failed to create intermediate OpenGL window.");
......@@ -329,7 +308,7 @@ SurfaceImpl *DisplayWGL::createWindowSurface(const egl::Config *configuration,
EGLNativeWindowType window,
const egl::AttributeMap &attribs)
{
return new WindowSurfaceWGL(window, mWindowClass, mPixelFormat, mWGLContext, mFunctionsWGL);
return new WindowSurfaceWGL(window, mPixelFormat, mWGLContext, mFunctionsWGL);
}
SurfaceImpl *DisplayWGL::createPbufferSurface(const egl::Config *configuration,
......
......@@ -15,68 +15,50 @@
namespace rx
{
WindowSurfaceWGL::WindowSurfaceWGL(EGLNativeWindowType window, ATOM windowClass, int pixelFormat, HGLRC wglContext, const FunctionsWGL *functions)
WindowSurfaceWGL::WindowSurfaceWGL(EGLNativeWindowType window, int pixelFormat, HGLRC wglContext, const FunctionsWGL *functions)
: SurfaceGL(),
mWindowClass(windowClass),
mPixelFormat(pixelFormat),
mShareWGLContext(wglContext),
mParentWindow(window),
mChildWindow(nullptr),
mChildDeviceContext(nullptr),
mWGLContext(wglContext),
mWindow(window),
mDeviceContext(nullptr),
mFunctionsWGL(functions)
{
}
WindowSurfaceWGL::~WindowSurfaceWGL()
{
mWindowClass = 0;
mPixelFormat = 0;
mShareWGLContext = nullptr;
ReleaseDC(mChildWindow, mChildDeviceContext);
mChildDeviceContext = nullptr;
DestroyWindow(mChildWindow);
mChildWindow = nullptr;
ReleaseDC(mWindow, mDeviceContext);
mDeviceContext = nullptr;
}
egl::Error WindowSurfaceWGL::initialize()
{
// Create a child window of the supplied window to draw to.
RECT rect;
if (!GetClientRect(mParentWindow, &rect))
mDeviceContext = GetDC(mWindow);
if (!mDeviceContext)
{
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the size of the native window.");
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the device context from the native window, "
"error: 0x%X.", GetLastError());
}
mChildWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY,
reinterpret_cast<const char*>(mWindowClass),
"ANGLE Intermediate Surface Window",
WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE,
0,
0,
rect.right - rect.left,
rect.bottom - rect.top,
mParentWindow,
NULL,
NULL,
NULL);
if (!mChildWindow)
// Require that the pixel format for this window has not been set yet or is equal to the Display's pixel format.
int windowPixelFormat = GetPixelFormat(mDeviceContext);
if (windowPixelFormat == 0)
{
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to create a child window.");
PIXELFORMATDESCRIPTOR pixelFormatDescriptor = { 0 };
if (!DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor))
{
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to DescribePixelFormat, error: 0x%X.", GetLastError());
}
if (!SetPixelFormat(mDeviceContext, mPixelFormat, &pixelFormatDescriptor))
{
return egl::Error(EGL_NOT_INITIALIZED, "Failed to set the pixel format on the device context, "
"error: 0x%X.", GetLastError());
}
}
mChildDeviceContext = GetDC(mChildWindow);
if (!mChildDeviceContext)
else if (windowPixelFormat != mPixelFormat)
{
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the device context of the child window.");
}
const PIXELFORMATDESCRIPTOR pixelFormatDescriptor = wgl::GetDefaultPixelFormatDescriptor();
if (!SetPixelFormat(mChildDeviceContext, mPixelFormat, &pixelFormatDescriptor))
{
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to set the pixel format on the child window.");
return egl::Error(EGL_NOT_INITIALIZED, "Pixel format of the NativeWindow and NativeDisplayType must match.");
}
return egl::Error(EGL_SUCCESS);
......@@ -84,7 +66,7 @@ egl::Error WindowSurfaceWGL::initialize()
egl::Error WindowSurfaceWGL::makeCurrent()
{
if (!mFunctionsWGL->makeCurrent(mChildDeviceContext, mShareWGLContext))
if (!mFunctionsWGL->makeCurrent(mDeviceContext, mWGLContext))
{
// TODO: What error type here?
return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current.");
......@@ -95,21 +77,7 @@ egl::Error WindowSurfaceWGL::makeCurrent()
egl::Error WindowSurfaceWGL::swap()
{
// Resize the child window to the interior of the parent window.
RECT rect;
if (!GetClientRect(mParentWindow, &rect))
{
// TODO: What error type here?
return egl::Error(EGL_CONTEXT_LOST, "Failed to get the size of the native window.");
}
if (!MoveWindow(mChildWindow, 0, 0, rect.right - rect.left, rect.bottom - rect.top, FALSE))
{
// TODO: What error type here?
return egl::Error(EGL_CONTEXT_LOST, "Failed to move the child window.");
}
if (!mFunctionsWGL->swapBuffers(mChildDeviceContext))
if (!mFunctionsWGL->swapBuffers(mDeviceContext))
{
// TODO: What error type here?
return egl::Error(EGL_CONTEXT_LOST, "Failed to swap buffers on the child window.");
......@@ -153,7 +121,7 @@ void WindowSurfaceWGL::setSwapInterval(EGLint interval)
EGLint WindowSurfaceWGL::getWidth() const
{
RECT rect;
if (!GetClientRect(mParentWindow, &rect))
if (!GetClientRect(mWindow, &rect))
{
return 0;
}
......@@ -163,7 +131,7 @@ EGLint WindowSurfaceWGL::getWidth() const
EGLint WindowSurfaceWGL::getHeight() const
{
RECT rect;
if (!GetClientRect(mParentWindow, &rect))
if (!GetClientRect(mWindow, &rect))
{
return 0;
}
......
......@@ -21,7 +21,7 @@ class FunctionsWGL;
class WindowSurfaceWGL : public SurfaceGL
{
public:
WindowSurfaceWGL(EGLNativeWindowType window, ATOM windowClass, int pixelFormat, HGLRC wglContext, const FunctionsWGL *functions);
WindowSurfaceWGL(EGLNativeWindowType window, int pixelFormat, HGLRC wglContext, const FunctionsWGL *functions);
~WindowSurfaceWGL() override;
egl::Error initialize() override;
......@@ -40,14 +40,12 @@ class WindowSurfaceWGL : public SurfaceGL
EGLint isPostSubBufferSupported() const override;
private:
ATOM mWindowClass;
int mPixelFormat;
HGLRC mShareWGLContext;
HGLRC mWGLContext;
HWND mParentWindow;
HWND mChildWindow;
HDC mChildDeviceContext;
HWND mWindow;
HDC mDeviceContext;
const FunctionsWGL *mFunctionsWGL;
};
......
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