aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-06-08 18:22:53 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-09 00:39:00 +0000
commitfee2b4ed0ff3776064c327c73f4f66b20727a1c1 (patch)
treee99b3d1042604e28ffafba58cbcc1c9548e2b779 /tools
parent21157ce0496c4dc7d4d280c3157b11279367b73f (diff)
Create a new HDC for each ANGLE context
Bug: skia:6711 Change-Id: I9c4720a8dbad4c6b18efe73e0e61afbdc19627bc Reviewed-on: https://skia-review.googlesource.com/19090 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/gpu/gl/angle/GLTestContext_angle.cpp154
-rw-r--r--tools/gpu/gl/angle/GLTestContext_angle.h3
2 files changed, 131 insertions, 26 deletions
diff --git a/tools/gpu/gl/angle/GLTestContext_angle.cpp b/tools/gpu/gl/angle/GLTestContext_angle.cpp
index c0ea48595c..52cc5128da 100644
--- a/tools/gpu/gl/angle/GLTestContext_angle.cpp
+++ b/tools/gpu/gl/angle/GLTestContext_angle.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2012 Google Inc.
*
@@ -76,7 +75,7 @@ void* get_angle_egl_display(void* nativeDisplay, ANGLEBackend type) {
class ANGLEGLContext : public sk_gpu_test::GLTestContext {
public:
- ANGLEGLContext(ANGLEBackend, ANGLEContextVersion, ANGLEGLContext* shareContext);
+ ANGLEGLContext(ANGLEBackend, ANGLEContextVersion, ANGLEGLContext* shareContext, void* display);
~ANGLEGLContext() override;
GrEGLImage texture2DToEGLImage(GrGLuint texID) const override;
@@ -96,15 +95,85 @@ private:
void* fSurface;
ANGLEBackend fType;
ANGLEContextVersion fVersion;
+
+#ifdef SK_BUILD_FOR_WIN
+ HWND fWindow;
+ HDC fDeviceContext;
+ static ATOM gWC;
+#endif
};
+#ifdef SK_BUILD_FOR_WIN
+ATOM ANGLEGLContext::gWC = 0;
+#endif
+
ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
- ANGLEGLContext* shareContext)
+ ANGLEGLContext* shareContext, void* display)
: fContext(EGL_NO_CONTEXT)
- , fDisplay(EGL_NO_DISPLAY)
+ , fDisplay(display)
, fSurface(EGL_NO_SURFACE)
, fType(type)
, fVersion(version) {
+#ifdef SK_BUILD_FOR_WIN
+ fWindow = nullptr;
+ fDeviceContext = nullptr;
+
+ if (EGL_NO_DISPLAY == fDisplay) {
+ 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("ANGLE-win");
+ 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("ANGLE-win"),
+ 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;
+ }
+
+ fDisplay = get_angle_egl_display(fDeviceContext, type);
+ }
+#else
+ SkASSERT(EGL_NO_DISPLAY == fDisplay);
+ fDisplay = get_angle_egl_display(EGL_DEFAULT_DISPLAY, type);
+#endif
+ if (EGL_NO_DISPLAY == fDisplay) {
+ SkDebugf("Could not create EGL display!");
+ return;
+ }
+
+ EGLint majorVersion;
+ EGLint minorVersion;
+ if (!eglInitialize(fDisplay, &majorVersion, &minorVersion)) {
+ SkDebugf("Could not initialize display!");
+ this->destroyGLContext();
+ return;
+ }
EGLint numConfigs;
static const EGLint configAttribs[] = {
@@ -117,19 +186,13 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
EGL_NONE
};
- fDisplay = get_angle_egl_display(EGL_DEFAULT_DISPLAY, type);
- if (EGL_NO_DISPLAY == fDisplay) {
- SkDebugf("Could not create EGL display!");
+ EGLConfig surfaceConfig;
+ if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) {
+ SkDebugf("Could not create choose config!");
+ this->destroyGLContext();
return;
}
- EGLint majorVersion;
- EGLint minorVersion;
- eglInitialize(fDisplay, &majorVersion, &minorVersion);
-
- EGLConfig surfaceConfig;
- eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs);
-
int versionNum = ANGLEContextVersion::kES2 == version ? 2 : 3;
const EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, versionNum,
@@ -137,7 +200,11 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
};
EGLContext eglShareContext = shareContext ? shareContext->fContext : nullptr;
fContext = eglCreateContext(fDisplay, surfaceConfig, eglShareContext, contextAttribs);
-
+ if (EGL_NO_CONTEXT == fContext) {
+ SkDebugf("Could not create context!");
+ this->destroyGLContext();
+ return;
+ }
static const EGLint surfaceAttribs[] = {
EGL_WIDTH, 1,
@@ -147,7 +214,11 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs);
- eglMakeCurrent(fDisplay, fSurface, fSurface, fContext);
+ if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
+ SkDebugf("Could not set the context.");
+ this->destroyGLContext();
+ return;
+ }
sk_sp<const GrGLInterface> gl(sk_gpu_test::CreateANGLEGLInterface());
if (nullptr == gl.get()) {
@@ -161,6 +232,24 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
return;
}
+#ifdef SK_DEBUG
+ // Verify that the interface we requested was actually returned to us
+ const GrGLubyte* rendererUByte;
+ GR_GL_CALL_RET(gl.get(), rendererUByte, GetString(GR_GL_RENDERER));
+ const char* renderer = reinterpret_cast<const char*>(rendererUByte);
+ switch (type) {
+ case ANGLEBackend::kD3D9:
+ SkASSERT(strstr(renderer, "Direct3D9"));
+ break;
+ case ANGLEBackend::kD3D11:
+ SkASSERT(strstr(renderer, "Direct3D11"));
+ break;
+ case ANGLEBackend::kOpenGL:
+ SkASSERT(strstr(renderer, "OpenGL"));
+ break;
+ }
+#endif
+
this->init(gl.release());
}
@@ -219,8 +308,10 @@ GrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const {
}
std::unique_ptr<sk_gpu_test::GLTestContext> ANGLEGLContext::makeNew() const {
+ // For EGLImage sharing between contexts to work in ANGLE the two contexts
+ // need to share the same display
std::unique_ptr<sk_gpu_test::GLTestContext> ctx =
- sk_gpu_test::MakeANGLETestContext(fType, fVersion);
+ sk_gpu_test::MakeANGLETestContext(fType, fVersion, nullptr, fDisplay);
if (ctx) {
ctx->makeCurrent();
}
@@ -228,27 +319,39 @@ std::unique_ptr<sk_gpu_test::GLTestContext> ANGLEGLContext::makeNew() const {
}
void ANGLEGLContext::destroyGLContext() {
- if (fDisplay) {
- eglMakeCurrent(fDisplay, 0, 0, 0);
+ if (EGL_NO_DISPLAY != fDisplay) {
+ eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (fContext) {
+ if (EGL_NO_CONTEXT != fContext) {
eglDestroyContext(fDisplay, fContext);
fContext = EGL_NO_CONTEXT;
}
- if (fSurface) {
+ if (EGL_NO_SURFACE != fSurface) {
eglDestroySurface(fDisplay, fSurface);
fSurface = EGL_NO_SURFACE;
}
- //TODO should we close the display?
+ eglTerminate(fDisplay);
fDisplay = EGL_NO_DISPLAY;
}
+
+#ifdef SK_BUILD_FOR_WIN
+ if (fWindow) {
+ if (fDeviceContext) {
+ ReleaseDC(fWindow, fDeviceContext);
+ fDeviceContext = 0;
+ }
+
+ DestroyWindow(fWindow);
+ fWindow = 0;
+ }
+#endif
}
void ANGLEGLContext::onPlatformMakeCurrent() const {
if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
- SkDebugf("Could not set the context.\n");
+ SkDebugf("Could not set the context 0x%x.\n", eglGetError());
}
}
@@ -290,9 +393,10 @@ const GrGLInterface* CreateANGLEGLInterface() {
}
std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend type, ANGLEContextVersion version,
- GLTestContext* shareContext){
+ GLTestContext* shareContext, void* display){
ANGLEGLContext* angleShareContext = reinterpret_cast<ANGLEGLContext*>(shareContext);
- std::unique_ptr<GLTestContext> ctx(new ANGLEGLContext(type, version, angleShareContext));
+ std::unique_ptr<GLTestContext> ctx(new ANGLEGLContext(type, version,
+ angleShareContext, display));
if (!ctx->isValid()) {
return nullptr;
}
diff --git a/tools/gpu/gl/angle/GLTestContext_angle.h b/tools/gpu/gl/angle/GLTestContext_angle.h
index 5433ee0ffa..5a72b93428 100644
--- a/tools/gpu/gl/angle/GLTestContext_angle.h
+++ b/tools/gpu/gl/angle/GLTestContext_angle.h
@@ -31,7 +31,8 @@ enum class ANGLEContextVersion {
/** Creates a GLTestContext backed by ANGLE. */
std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend, ANGLEContextVersion,
- GLTestContext* shareContext = nullptr);
+ GLTestContext* shareContext = nullptr,
+ void* display = nullptr);
} // namespace sk_gpu_test
#endif