2016-03-31 01:56:19 +00:00
|
|
|
|
2011-10-19 20:43:20 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2011 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2016-03-31 17:59:06 +00:00
|
|
|
#include "gl/GLTestContext.h"
|
2014-10-09 12:24:15 +00:00
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
#include <GL/GL.h>
|
2014-11-14 15:21:29 +00:00
|
|
|
#include "win/SkWGL.h"
|
2011-10-19 20:43:20 +00:00
|
|
|
|
2013-12-03 15:23:37 +00:00
|
|
|
#include <windows.h>
|
2011-10-19 20:43:20 +00:00
|
|
|
|
2014-10-09 12:24:15 +00:00
|
|
|
namespace {
|
2011-10-24 21:17:53 +00:00
|
|
|
|
2017-11-17 14:25:23 +00:00
|
|
|
std::function<void()> context_restorer() {
|
|
|
|
auto glrc = wglGetCurrentContext();
|
|
|
|
auto dc = wglGetCurrentDC();
|
|
|
|
return [glrc, dc] { wglMakeCurrent(dc, glrc); };
|
|
|
|
}
|
|
|
|
|
2016-03-31 17:59:06 +00:00
|
|
|
class WinGLTestContext : public sk_gpu_test::GLTestContext {
|
2014-10-09 12:24:15 +00:00
|
|
|
public:
|
2017-02-21 21:58:08 +00:00
|
|
|
WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext);
|
|
|
|
~WinGLTestContext() override;
|
2011-10-19 20:43:20 +00:00
|
|
|
|
2014-10-09 12:24:15 +00:00
|
|
|
private:
|
2014-10-16 06:03:54 +00:00
|
|
|
void destroyGLContext();
|
|
|
|
|
2015-06-23 20:23:44 +00:00
|
|
|
void onPlatformMakeCurrent() const override;
|
2017-11-17 14:25:23 +00:00
|
|
|
std::function<void()> onPlatformGetAutoContextRestore() const override;
|
2015-06-23 20:23:44 +00:00
|
|
|
void onPlatformSwapBuffers() const override;
|
|
|
|
GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
|
|
|
|
|
2014-10-09 12:24:15 +00:00
|
|
|
HWND fWindow;
|
|
|
|
HDC fDeviceContext;
|
|
|
|
HGLRC fGlRenderContext;
|
|
|
|
static ATOM gWC;
|
|
|
|
SkWGLPbufferContext* fPbufferContext;
|
|
|
|
};
|
2014-10-08 11:14:24 +00:00
|
|
|
|
2016-03-31 17:59:06 +00:00
|
|
|
ATOM WinGLTestContext::gWC = 0;
|
2014-10-09 12:24:15 +00:00
|
|
|
|
2017-02-21 21:58:08 +00:00
|
|
|
WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext)
|
2015-08-27 14:41:13 +00:00
|
|
|
: fWindow(nullptr)
|
|
|
|
, fDeviceContext(nullptr)
|
2014-07-01 14:20:11 +00:00
|
|
|
, fGlRenderContext(0)
|
2015-08-27 14:41:13 +00:00
|
|
|
, fPbufferContext(nullptr) {
|
|
|
|
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr);
|
2011-10-19 20:43:20 +00:00
|
|
|
|
2013-03-05 19:30:54 +00:00
|
|
|
if (!gWC) {
|
|
|
|
WNDCLASS wc;
|
|
|
|
wc.cbClsExtra = 0;
|
|
|
|
wc.cbWndExtra = 0;
|
2015-08-27 14:41:13 +00:00
|
|
|
wc.hbrBackground = nullptr;
|
|
|
|
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
|
|
|
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
|
2013-03-05 19:30:54 +00:00
|
|
|
wc.hInstance = hInstance;
|
|
|
|
wc.lpfnWndProc = (WNDPROC) DefWindowProc;
|
|
|
|
wc.lpszClassName = TEXT("Griffin");
|
2015-08-27 14:41:13 +00:00
|
|
|
wc.lpszMenuName = nullptr;
|
2013-03-05 19:30:54 +00:00
|
|
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
|
|
|
|
|
|
|
gWC = RegisterClass(&wc);
|
|
|
|
if (!gWC) {
|
|
|
|
SkDebugf("Could not register window class.\n");
|
2014-10-16 06:03:54 +00:00
|
|
|
return;
|
2013-03-05 19:30:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(fWindow = CreateWindow(TEXT("Griffin"),
|
|
|
|
TEXT("The Invisible Man"),
|
|
|
|
WS_OVERLAPPEDWINDOW,
|
|
|
|
0, 0, 1, 1,
|
2015-08-27 14:41:13 +00:00
|
|
|
nullptr, nullptr,
|
|
|
|
hInstance, nullptr))) {
|
2013-03-05 19:30:54 +00:00
|
|
|
SkDebugf("Could not create window.\n");
|
2014-10-16 06:03:54 +00:00
|
|
|
return;
|
2013-03-05 19:30:54 +00:00
|
|
|
}
|
2011-10-19 20:43:20 +00:00
|
|
|
|
|
|
|
if (!(fDeviceContext = GetDC(fWindow))) {
|
|
|
|
SkDebugf("Could not get device context.\n");
|
|
|
|
this->destroyGLContext();
|
2014-10-16 06:03:54 +00:00
|
|
|
return;
|
2011-10-19 20:43:20 +00:00
|
|
|
}
|
2014-06-30 13:36:31 +00:00
|
|
|
// Requesting a Core profile would bar us from using NVPR. So we request
|
|
|
|
// compatibility profile or GL ES.
|
|
|
|
SkWGLContextRequest contextType =
|
|
|
|
kGLES_GrGLStandard == forcedGpuAPI ?
|
|
|
|
kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
|
2012-08-23 18:14:13 +00:00
|
|
|
|
2017-02-24 19:51:44 +00:00
|
|
|
HGLRC winShareContext = nullptr;
|
|
|
|
if (shareContext) {
|
|
|
|
winShareContext = shareContext->fPbufferContext ? shareContext->fPbufferContext->getGLRC()
|
|
|
|
: shareContext->fGlRenderContext;
|
|
|
|
}
|
2017-08-17 16:58:28 +00:00
|
|
|
fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, contextType, winShareContext);
|
2014-07-01 14:20:11 +00:00
|
|
|
|
|
|
|
HDC dc;
|
|
|
|
HGLRC glrc;
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == fPbufferContext) {
|
2017-02-21 21:58:08 +00:00
|
|
|
if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType,
|
|
|
|
winShareContext))) {
|
2014-07-01 14:20:11 +00:00
|
|
|
SkDebugf("Could not create rendering context.\n");
|
|
|
|
this->destroyGLContext();
|
2014-10-16 06:03:54 +00:00
|
|
|
return;
|
2014-07-01 14:20:11 +00:00
|
|
|
}
|
|
|
|
dc = fDeviceContext;
|
|
|
|
glrc = fGlRenderContext;
|
|
|
|
} else {
|
|
|
|
ReleaseDC(fWindow, fDeviceContext);
|
|
|
|
fDeviceContext = 0;
|
|
|
|
DestroyWindow(fWindow);
|
|
|
|
fWindow = 0;
|
|
|
|
|
|
|
|
dc = fPbufferContext->getDC();
|
|
|
|
glrc = fPbufferContext->getGLRC();
|
2011-10-19 20:43:20 +00:00
|
|
|
}
|
|
|
|
|
2017-11-17 14:25:23 +00:00
|
|
|
SkScopeExit restorer(context_restorer());
|
2014-07-01 14:20:11 +00:00
|
|
|
if (!(wglMakeCurrent(dc, glrc))) {
|
2011-10-19 20:43:20 +00:00
|
|
|
SkDebugf("Could not set the context.\n");
|
|
|
|
this->destroyGLContext();
|
2014-10-16 06:03:54 +00:00
|
|
|
return;
|
2011-10-19 20:43:20 +00:00
|
|
|
}
|
2014-07-01 14:20:11 +00:00
|
|
|
|
2017-12-11 15:06:31 +00:00
|
|
|
auto gl = GrGLMakeNativeInterface();
|
|
|
|
if (!gl) {
|
2011-10-19 20:43:20 +00:00
|
|
|
SkDebugf("Could not create GL interface.\n");
|
|
|
|
this->destroyGLContext();
|
2014-10-16 06:03:54 +00:00
|
|
|
return;
|
2011-10-19 20:43:20 +00:00
|
|
|
}
|
2015-06-23 20:23:44 +00:00
|
|
|
if (!gl->validate()) {
|
2014-10-16 06:03:54 +00:00
|
|
|
SkDebugf("Could not validate GL interface.\n");
|
|
|
|
this->destroyGLContext();
|
|
|
|
return;
|
|
|
|
}
|
2015-06-23 20:23:44 +00:00
|
|
|
|
2017-12-11 15:06:31 +00:00
|
|
|
this->init(std::move(gl));
|
2014-10-16 06:03:54 +00:00
|
|
|
}
|
2011-10-19 20:43:20 +00:00
|
|
|
|
2016-03-31 17:59:06 +00:00
|
|
|
WinGLTestContext::~WinGLTestContext() {
|
2015-06-23 20:23:44 +00:00
|
|
|
this->teardown();
|
2014-10-16 06:03:54 +00:00
|
|
|
this->destroyGLContext();
|
|
|
|
}
|
|
|
|
|
2016-03-31 17:59:06 +00:00
|
|
|
void WinGLTestContext::destroyGLContext() {
|
2014-10-16 06:03:54 +00:00
|
|
|
SkSafeSetNull(fPbufferContext);
|
|
|
|
if (fGlRenderContext) {
|
2017-11-17 14:25:23 +00:00
|
|
|
// This deletes the context immediately even if it is current.
|
2014-10-16 06:03:54 +00:00
|
|
|
wglDeleteContext(fGlRenderContext);
|
|
|
|
fGlRenderContext = 0;
|
|
|
|
}
|
|
|
|
if (fWindow && fDeviceContext) {
|
|
|
|
ReleaseDC(fWindow, fDeviceContext);
|
|
|
|
fDeviceContext = 0;
|
|
|
|
}
|
|
|
|
if (fWindow) {
|
|
|
|
DestroyWindow(fWindow);
|
|
|
|
fWindow = 0;
|
|
|
|
}
|
2011-10-19 20:43:20 +00:00
|
|
|
}
|
|
|
|
|
2016-03-31 17:59:06 +00:00
|
|
|
void WinGLTestContext::onPlatformMakeCurrent() const {
|
2014-07-01 14:20:11 +00:00
|
|
|
HDC dc;
|
|
|
|
HGLRC glrc;
|
|
|
|
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == fPbufferContext) {
|
2014-07-01 14:20:11 +00:00
|
|
|
dc = fDeviceContext;
|
|
|
|
glrc = fGlRenderContext;
|
|
|
|
} else {
|
|
|
|
dc = fPbufferContext->getDC();
|
|
|
|
glrc = fPbufferContext->getGLRC();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!wglMakeCurrent(dc, glrc)) {
|
2011-10-19 20:43:20 +00:00
|
|
|
SkDebugf("Could not create rendering context.\n");
|
|
|
|
}
|
|
|
|
}
|
2013-10-09 18:25:38 +00:00
|
|
|
|
2017-11-17 14:25:23 +00:00
|
|
|
std::function<void()> WinGLTestContext::onPlatformGetAutoContextRestore() const {
|
|
|
|
if (wglGetCurrentContext() == fGlRenderContext) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return context_restorer();
|
|
|
|
}
|
|
|
|
|
2016-03-31 17:59:06 +00:00
|
|
|
void WinGLTestContext::onPlatformSwapBuffers() const {
|
2014-07-01 14:20:11 +00:00
|
|
|
HDC dc;
|
|
|
|
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == fPbufferContext) {
|
2014-07-01 14:20:11 +00:00
|
|
|
dc = fDeviceContext;
|
|
|
|
} else {
|
|
|
|
dc = fPbufferContext->getDC();
|
|
|
|
}
|
|
|
|
if (!SwapBuffers(dc)) {
|
2013-10-09 18:25:38 +00:00
|
|
|
SkDebugf("Could not complete SwapBuffers.\n");
|
|
|
|
}
|
|
|
|
}
|
2014-10-09 12:24:15 +00:00
|
|
|
|
2016-03-31 17:59:06 +00:00
|
|
|
GrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const {
|
2015-06-23 20:23:44 +00:00
|
|
|
return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
|
|
|
|
}
|
|
|
|
|
2014-10-09 12:24:15 +00:00
|
|
|
} // anonymous namespace
|
|
|
|
|
2016-03-31 01:56:19 +00:00
|
|
|
namespace sk_gpu_test {
|
2016-03-31 17:59:06 +00:00
|
|
|
GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
|
|
|
|
GLTestContext *shareContext) {
|
2017-02-21 21:58:08 +00:00
|
|
|
WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext);
|
|
|
|
WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext);
|
2014-10-16 06:03:54 +00:00
|
|
|
if (!ctx->isValid()) {
|
2015-08-26 20:07:48 +00:00
|
|
|
delete ctx;
|
2015-08-27 14:41:13 +00:00
|
|
|
return nullptr;
|
2014-10-16 06:03:54 +00:00
|
|
|
}
|
|
|
|
return ctx;
|
2014-10-09 12:24:15 +00:00
|
|
|
}
|
2016-03-31 01:56:19 +00:00
|
|
|
} // namespace sk_gpu_test
|
|
|
|
|