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 @@ ...@@ -11,6 +11,8 @@
#include "libANGLE/renderer/gl/DisplayGL.h" #include "libANGLE/renderer/gl/DisplayGL.h"
#include <GL/wglext.h>
namespace rx namespace rx
{ {
...@@ -47,6 +49,28 @@ class DisplayWGL : public DisplayGL ...@@ -47,6 +49,28 @@ class DisplayWGL : public DisplayGL
void generateExtensions(egl::DisplayExtensions *outExtensions) const override; void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) 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 @@ ...@@ -9,23 +9,122 @@
#include "libANGLE/renderer/gl/wgl/SurfaceWGL.h" #include "libANGLE/renderer/gl/wgl/SurfaceWGL.h"
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/renderer/gl/wgl/wgl_utils.h"
namespace rx namespace rx
{ {
SurfaceWGL::SurfaceWGL(egl::Display *display, const egl::Config *config, EGLint fixedSize, EGLint postSubBufferSupported, SurfaceWGL::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,
: SurfaceGL(display, config, fixedSize, postSubBufferSupported, textureFormat, textureType) 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() 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() 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); return egl::Error(EGL_SUCCESS);
} }
...@@ -55,25 +154,35 @@ egl::Error SurfaceWGL::releaseTexImage(EGLint buffer) ...@@ -55,25 +154,35 @@ egl::Error SurfaceWGL::releaseTexImage(EGLint buffer)
void SurfaceWGL::setSwapInterval(EGLint interval) void SurfaceWGL::setSwapInterval(EGLint interval)
{ {
UNIMPLEMENTED(); if (mSwapIntervalEXT)
{
mSwapIntervalEXT(interval);
}
} }
EGLint SurfaceWGL::getWidth() const EGLint SurfaceWGL::getWidth() const
{ {
UNIMPLEMENTED(); RECT rect;
return 0; if (!GetClientRect(mParentWindow, &rect))
{
return 0;
}
return rect.right - rect.left;
} }
EGLint SurfaceWGL::getHeight() const EGLint SurfaceWGL::getHeight() const
{ {
UNIMPLEMENTED(); RECT rect;
return 0; if (!GetClientRect(mParentWindow, &rect))
{
return 0;
}
return rect.bottom - rect.top;
} }
EGLNativeWindowType SurfaceWGL::getWindowHandle() const EGLNativeWindowType SurfaceWGL::getWindowHandle() const
{ {
UNIMPLEMENTED(); return mChildWindow;
return NULL;
} }
} }
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "libANGLE/renderer/gl/SurfaceGL.h" #include "libANGLE/renderer/gl/SurfaceGL.h"
#include <GL/wglext.h>
namespace rx namespace rx
{ {
...@@ -18,10 +20,16 @@ class SurfaceWGL : public SurfaceGL ...@@ -18,10 +20,16 @@ class SurfaceWGL : public SurfaceGL
{ {
public: public:
SurfaceWGL(egl::Display *display, const egl::Config *config, EGLint fixedSize, EGLint postSubBufferSupported, 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; ~SurfaceWGL() override;
static SurfaceWGL *makeSurfaceWGL(SurfaceImpl *impl);
egl::Error initialize();
egl::Error makeCurrent();
egl::Error swap() override; egl::Error swap() override;
egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
...@@ -36,6 +44,17 @@ class SurfaceWGL : public SurfaceGL ...@@ -36,6 +44,17 @@ class SurfaceWGL : public SurfaceGL
private: private:
DISALLOW_COPY_AND_ASSIGN(SurfaceWGL); 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 @@ ...@@ -400,6 +400,9 @@
'libANGLE/renderer/gl/wgl/DisplayWGL.h', 'libANGLE/renderer/gl/wgl/DisplayWGL.h',
'libANGLE/renderer/gl/wgl/SurfaceWGL.cpp', 'libANGLE/renderer/gl/wgl/SurfaceWGL.cpp',
'libANGLE/renderer/gl/wgl/SurfaceWGL.h', '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': 'libglesv2_sources':
[ [
...@@ -451,6 +454,7 @@ ...@@ -451,6 +454,7 @@
[ [
'.', '.',
'../include', '../include',
'third_party/khronos',
], ],
'sources': '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