skia2/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp
Greg Daniel 02497d4016 Update nanobench and skpbench to use flush API for gpu syncing.
This also allows us to remove all the one off Fence code that we
implemented in all the backend TestContexts

Change-Id: I9ff7ba4690cf3f19a180f51fc510991a112bb62c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/272456
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
2020-02-24 17:21:35 +00:00

227 lines
6.3 KiB
C++

/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "tools/gpu/gl/GLTestContext.h"
#if defined(_M_ARM64)
namespace sk_gpu_test {
GLTestContext* CreatePlatformGLTestContext(GrGLStandard, GLTestContext*) { return nullptr; }
} // namespace sk_gpu_test
#else
#include <windows.h>
#include <GL/GL.h>
#include "src/utils/win/SkWGL.h"
#include <windows.h>
namespace {
std::function<void()> context_restorer() {
auto glrc = wglGetCurrentContext();
auto dc = wglGetCurrentDC();
return [glrc, dc] { wglMakeCurrent(dc, glrc); };
}
class WinGLTestContext : public sk_gpu_test::GLTestContext {
public:
WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext);
~WinGLTestContext() override;
private:
void destroyGLContext();
void onPlatformMakeNotCurrent() const override;
void onPlatformMakeCurrent() const override;
std::function<void()> onPlatformGetAutoContextRestore() const override;
GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
HWND fWindow;
HDC fDeviceContext;
HGLRC fGlRenderContext;
static ATOM gWC;
sk_sp<SkWGLPbufferContext> fPbufferContext;
};
ATOM WinGLTestContext::gWC = 0;
WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext)
: fWindow(nullptr)
, fDeviceContext(nullptr)
, fGlRenderContext(0)
, fPbufferContext(nullptr) {
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr);
if (!gWC) {
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = nullptr;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = (WNDPROC) DefWindowProc;
wc.lpszClassName = TEXT("Griffin");
wc.lpszMenuName = nullptr;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
gWC = RegisterClass(&wc);
if (!gWC) {
SkDebugf("Could not register window class.\n");
return;
}
}
if (!(fWindow = CreateWindow(TEXT("Griffin"),
TEXT("The Invisible Man"),
WS_OVERLAPPEDWINDOW,
0, 0, 1, 1,
nullptr, nullptr,
hInstance, nullptr))) {
SkDebugf("Could not create window.\n");
return;
}
if (!(fDeviceContext = GetDC(fWindow))) {
SkDebugf("Could not get device context.\n");
this->destroyGLContext();
return;
}
// 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;
HGLRC winShareContext = nullptr;
if (shareContext) {
winShareContext = shareContext->fPbufferContext ? shareContext->fPbufferContext->getGLRC()
: shareContext->fGlRenderContext;
}
fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, contextType, winShareContext);
HDC dc;
HGLRC glrc;
if (nullptr == fPbufferContext) {
if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType,
winShareContext))) {
SkDebugf("Could not create rendering context.\n");
this->destroyGLContext();
return;
}
dc = fDeviceContext;
glrc = fGlRenderContext;
} else {
ReleaseDC(fWindow, fDeviceContext);
fDeviceContext = 0;
DestroyWindow(fWindow);
fWindow = 0;
dc = fPbufferContext->getDC();
glrc = fPbufferContext->getGLRC();
}
SkScopeExit restorer(context_restorer());
if (!(wglMakeCurrent(dc, glrc))) {
SkDebugf("Could not set the context.\n");
this->destroyGLContext();
return;
}
auto gl = GrGLMakeNativeInterface();
if (!gl) {
SkDebugf("Could not create GL interface.\n");
this->destroyGLContext();
return;
}
if (!gl->validate()) {
SkDebugf("Could not validate GL interface.\n");
this->destroyGLContext();
return;
}
this->init(std::move(gl));
}
WinGLTestContext::~WinGLTestContext() {
this->teardown();
this->destroyGLContext();
}
void WinGLTestContext::destroyGLContext() {
fPbufferContext = nullptr;
if (fGlRenderContext) {
// This deletes the context immediately even if it is current.
wglDeleteContext(fGlRenderContext);
fGlRenderContext = 0;
}
if (fWindow && fDeviceContext) {
ReleaseDC(fWindow, fDeviceContext);
fDeviceContext = 0;
}
if (fWindow) {
DestroyWindow(fWindow);
fWindow = 0;
}
}
void WinGLTestContext::onPlatformMakeNotCurrent() const {
if (!wglMakeCurrent(NULL, NULL)) {
SkDebugf("Could not null out the rendering context.\n");
}
}
void WinGLTestContext::onPlatformMakeCurrent() const {
HDC dc;
HGLRC glrc;
if (nullptr == fPbufferContext) {
dc = fDeviceContext;
glrc = fGlRenderContext;
} else {
dc = fPbufferContext->getDC();
glrc = fPbufferContext->getGLRC();
}
if (!wglMakeCurrent(dc, glrc)) {
SkDebugf("Could not create rendering context.\n");
}
}
std::function<void()> WinGLTestContext::onPlatformGetAutoContextRestore() const {
if (wglGetCurrentContext() == fGlRenderContext) {
return nullptr;
}
return context_restorer();
}
GrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const {
return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
}
} // anonymous namespace
namespace sk_gpu_test {
GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
GLTestContext *shareContext) {
WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext);
WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext);
if (!ctx->isValid()) {
delete ctx;
return nullptr;
}
return ctx;
}
} // namespace sk_gpu_test
#endif