Commit 398d8e6e by Geoff Lang

Add a basic WGL implementation.

BUG=angle:890 Change-Id: I5202086990b4f4fbf455fd73c3e29e5e3e1f6160 Reviewed-on: https://chromium-review.googlesource.com/240092Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 09b22474
......@@ -11,6 +11,8 @@
#include "libANGLE/renderer/gl/DisplayGL.h"
#include <GL/wglext.h>
namespace rx
{
......@@ -47,6 +49,28 @@ class DisplayWGL : public DisplayGL
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override;
bool isWGLExtensionSupported(const std::string &name) const;
HMODULE mOpenGLModule;
GLuint mGLVersionMajor;
GLuint mGLVersionMinor;
std::vector<std::string> mExtensions;
PFNWGLCREATECONTEXTATTRIBSARBPROC mCreateContextAttribsARB;
PFNWGLGETPIXELFORMATATTRIBIVARBPROC mGetPixelFormatAttribivARB;
PFNWGLSWAPINTERVALEXTPROC mSwapIntervalEXT;
ATOM mWindowClass;
HWND mWindow;
HDC mDeviceContext;
int mPixelFormat;
HGLRC mWGLContext;
egl::Display *mDisplay;
};
}
......
......@@ -9,23 +9,122 @@
#include "libANGLE/renderer/gl/wgl/SurfaceWGL.h"
#include "common/debug.h"
#include "libANGLE/renderer/gl/wgl/wgl_utils.h"
namespace rx
{
SurfaceWGL::SurfaceWGL(egl::Display *display, const egl::Config *config, EGLint fixedSize, EGLint postSubBufferSupported,
EGLenum textureFormat, EGLenum textureType)
: SurfaceGL(display, config, fixedSize, postSubBufferSupported, textureFormat, textureType)
EGLenum textureFormat, EGLenum textureType, EGLNativeWindowType window, ATOM windowClass, int pixelFormat,
HGLRC wglContext, PFNWGLSWAPINTERVALEXTPROC swapIntervalExt)
: SurfaceGL(display, config, fixedSize, postSubBufferSupported, textureFormat, textureType),
mWindowClass(windowClass),
mPixelFormat(pixelFormat),
mShareWGLContext(wglContext),
mParentWindow(window),
mChildWindow(nullptr),
mChildDeviceContext(nullptr),
mSwapIntervalEXT(swapIntervalExt)
{
}
SurfaceWGL::~SurfaceWGL()
{
mWindowClass = 0;
mPixelFormat = 0;
mShareWGLContext = nullptr;
wglMakeCurrent(mChildDeviceContext, nullptr);
ReleaseDC(mChildWindow, mChildDeviceContext);
mChildDeviceContext = nullptr;
DestroyWindow(mChildWindow);
mChildWindow = nullptr;
mSwapIntervalEXT = nullptr;
}
SurfaceWGL *SurfaceWGL::makeSurfaceWGL(SurfaceImpl *impl)
{
ASSERT(HAS_DYNAMIC_TYPE(SurfaceWGL*, impl));
return static_cast<SurfaceWGL*>(impl);
}
egl::Error SurfaceWGL::initialize()
{
// Create a child window of the supplied window to draw to.
RECT rect;
if (!GetClientRect(mParentWindow, &rect))
{
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the size of the native window.");
}
mChildWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY,
reinterpret_cast<const char*>(mWindowClass),
"",
WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE,
0,
0,
rect.right - rect.left,
rect.bottom - rect.top,
mParentWindow,
NULL,
NULL,
NULL);
if (!mChildWindow)
{
return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to create a child window.");
}
mChildDeviceContext = GetDC(mChildWindow);
if (!mChildDeviceContext)
{
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_SUCCESS);
}
egl::Error SurfaceWGL::makeCurrent()
{
if (!wglMakeCurrent(mChildDeviceContext, mShareWGLContext))
{
// TODO: What error type here?
return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current.");
}
return egl::Error(EGL_SUCCESS);
}
egl::Error SurfaceWGL::swap()
{
UNIMPLEMENTED();
// 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 (!SwapBuffers(mChildDeviceContext))
{
// TODO: What error type here?
return egl::Error(EGL_CONTEXT_LOST, "Failed to swap buffers on the child window.");
}
return egl::Error(EGL_SUCCESS);
}
......@@ -55,25 +154,35 @@ egl::Error SurfaceWGL::releaseTexImage(EGLint buffer)
void SurfaceWGL::setSwapInterval(EGLint interval)
{
UNIMPLEMENTED();
if (mSwapIntervalEXT)
{
mSwapIntervalEXT(interval);
}
}
EGLint SurfaceWGL::getWidth() const
{
UNIMPLEMENTED();
return 0;
RECT rect;
if (!GetClientRect(mParentWindow, &rect))
{
return 0;
}
return rect.right - rect.left;
}
EGLint SurfaceWGL::getHeight() const
{
UNIMPLEMENTED();
return 0;
RECT rect;
if (!GetClientRect(mParentWindow, &rect))
{
return 0;
}
return rect.bottom - rect.top;
}
EGLNativeWindowType SurfaceWGL::getWindowHandle() const
{
UNIMPLEMENTED();
return NULL;
return mChildWindow;
}
}
......@@ -11,6 +11,8 @@
#include "libANGLE/renderer/gl/SurfaceGL.h"
#include <GL/wglext.h>
namespace rx
{
......@@ -18,10 +20,16 @@ class SurfaceWGL : public SurfaceGL
{
public:
SurfaceWGL(egl::Display *display, const egl::Config *config, EGLint fixedSize, EGLint postSubBufferSupported,
EGLenum textureFormat, EGLenum textureType);
EGLenum textureFormat, EGLenum textureType, EGLNativeWindowType window, ATOM windowClass, int pixelFormat,
HGLRC wglContext, PFNWGLSWAPINTERVALEXTPROC swapIntervalExt);
~SurfaceWGL() override;
static SurfaceWGL *makeSurfaceWGL(SurfaceImpl *impl);
egl::Error initialize();
egl::Error makeCurrent();
egl::Error swap() override;
egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
......@@ -36,6 +44,17 @@ class SurfaceWGL : public SurfaceGL
private:
DISALLOW_COPY_AND_ASSIGN(SurfaceWGL);
ATOM mWindowClass;
int mPixelFormat;
HGLRC mShareWGLContext;
HWND mParentWindow;
HWND mChildWindow;
HDC mChildDeviceContext;
PFNWGLSWAPINTERVALEXTPROC mSwapIntervalEXT;
};
}
......
//
// Copyright (c) 2015 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.
//
// wgl_utils.cpp: Utility routines specific to the WGL->EGL implementation.
#include "libANGLE/renderer/gl/wgl/wgl_utils.h"
namespace rx
{
namespace wgl
{
PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor()
{
PIXELFORMATDESCRIPTOR pixelFormatDescriptor = { 0 };
pixelFormatDescriptor.nSize = sizeof(pixelFormatDescriptor);
pixelFormatDescriptor.nVersion = 1;
pixelFormatDescriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_GENERIC_ACCELERATED | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pixelFormatDescriptor.iPixelType = PFD_TYPE_RGBA;
pixelFormatDescriptor.cColorBits = 24;
pixelFormatDescriptor.cAlphaBits = 8;
pixelFormatDescriptor.cDepthBits = 24;
pixelFormatDescriptor.cStencilBits = 8;
pixelFormatDescriptor.iLayerType = PFD_MAIN_PLANE;
return pixelFormatDescriptor;
}
}
}
//
// Copyright (c) 2015 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.
//
// wgl_utils.h: Utility routines specific to the WGL->EGL implementation.
#ifndef LIBANGLE_RENDERER_GL_WGL_WGLUTILS_H_
#define LIBANGLE_RENDERER_GL_WGL_WGLUTILS_H_
#include "common/platform.h"
namespace rx
{
namespace wgl
{
PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor();
}
}
#endif // LIBANGLE_RENDERER_GL_WGL_WGLUTILS_H_
......@@ -400,6 +400,9 @@
'libANGLE/renderer/gl/wgl/DisplayWGL.h',
'libANGLE/renderer/gl/wgl/SurfaceWGL.cpp',
'libANGLE/renderer/gl/wgl/SurfaceWGL.h',
'libANGLE/renderer/gl/wgl/wgl_utils.cpp',
'libANGLE/renderer/gl/wgl/wgl_utils.h',
'third_party/khronos/GL/wglext.h',
],
'libglesv2_sources':
[
......@@ -451,6 +454,7 @@
[
'.',
'../include',
'third_party/khronos',
],
'sources':
[
......
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