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>
This commit is contained in:
Robert Phillips 2017-06-08 18:22:53 -04:00 committed by Skia Commit-Bot
parent 21157ce049
commit fee2b4ed0f
3 changed files with 136 additions and 26 deletions

View File

@ -128,6 +128,11 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(EGLImageTest, reporter, ctxInfo) {
glCtx0->makeCurrent();
externalTexture.fTarget = GR_GL_TEXTURE_EXTERNAL;
externalTexture.fID = glCtx0->eglImageToExternalTexture(image);
if (0 == externalTexture.fID) {
ERRORF(reporter, "Error converting EGL Image back to texture");
cleanup(glCtx0, externalTexture.fID, glCtx1.get(), context1, backendTexture1, image);
return;
}
// Wrap this texture ID in a GrTexture
GrBackendTexture backendTex(kSize, kSize, kRGBA_8888_GrPixelConfig, externalTexture);

View File

@ -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;
}

View File

@ -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