diff options
author | Robert Phillips <robertphillips@google.com> | 2017-06-08 18:22:53 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-06-09 00:39:00 +0000 |
commit | fee2b4ed0ff3776064c327c73f4f66b20727a1c1 (patch) | |
tree | e99b3d1042604e28ffafba58cbcc1c9548e2b779 /tools | |
parent | 21157ce0496c4dc7d4d280c3157b11279367b73f (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.cpp | 154 | ||||
-rw-r--r-- | tools/gpu/gl/angle/GLTestContext_angle.h | 3 |
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 |