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:
parent
21157ce049
commit
fee2b4ed0f
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user