Index: tools/gpu/gl/angle/GLContext_angle.cpp |
diff --git a/src/gpu/gl/angle/SkANGLEGLContext.cpp b/tools/gpu/gl/angle/GLContext_angle.cpp |
similarity index 58% |
rename from src/gpu/gl/angle/SkANGLEGLContext.cpp |
rename to tools/gpu/gl/angle/GLContext_angle.cpp |
index c6ea44381f5e3ced522f5ae40bdbc7340a2ad515..f1e8aad50940399f04e9e7878463719f528f6f57 100644 |
--- a/src/gpu/gl/angle/SkANGLEGLContext.cpp |
+++ b/tools/gpu/gl/angle/GLContext_angle.cpp |
@@ -1,3 +1,4 @@ |
+ |
/* |
* Copyright 2012 Google Inc. |
* |
@@ -5,7 +6,7 @@ |
* found in the LICENSE file. |
*/ |
-#include "gl/angle/SkANGLEGLContext.h" |
+#include "GLContext_angle.h" |
#include <EGL/egl.h> |
#include <EGL/eglext.h> |
@@ -13,32 +14,57 @@ |
#include "gl/GrGLDefines.h" |
#include "gl/GrGLUtil.h" |
+#include "gl/GrGLInterface.h" |
+#include "gl/GrGLAssembleInterface.h" |
+#include "../ports/SkOSLibrary.h" |
+ |
+#include <EGL/egl.h> |
+ |
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202 |
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 |
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 |
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 |
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D |
-void* SkANGLEGLContext::GetD3DEGLDisplay(void* nativeDisplay, bool useGLBackend) { |
+namespace { |
+struct Libs { |
+ void* fGLLib; |
+ void* fEGLLib; |
+}; |
+ |
+static GrGLFuncPtr angle_get_gl_proc(void* ctx, const char name[]) { |
+ const Libs* libs = reinterpret_cast<const Libs*>(ctx); |
+ GrGLFuncPtr proc = (GrGLFuncPtr) GetProcedureAddress(libs->fGLLib, name); |
+ if (proc) { |
+ return proc; |
+ } |
+ proc = (GrGLFuncPtr) GetProcedureAddress(libs->fEGLLib, name); |
+ if (proc) { |
+ return proc; |
+ } |
+ return eglGetProcAddress(name); |
+} |
+ |
+void* get_angle_egl_display(void* nativeDisplay, bool useGLBackend) { |
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; |
eglGetPlatformDisplayEXT = |
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); |
+ // We expect ANGLE to support this extension |
if (!eglGetPlatformDisplayEXT) { |
- return eglGetDisplay(static_cast<EGLNativeDisplayType>(nativeDisplay)); |
+ return EGL_NO_DISPLAY; |
} |
EGLDisplay display = EGL_NO_DISPLAY; |
if (useGLBackend) { |
- // Try for an ANGLE D3D11 context, fall back to D3D9. |
EGLint attribs[3] = { |
- EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
- EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, |
- EGL_NONE |
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
+ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, |
+ EGL_NONE |
}; |
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, attribs); |
} else { |
- // Try for an ANGLE D3D11 context, fall back to D3D9, and finally GL. |
+ // Try for an ANGLE D3D11 context, fall back to D3D9. |
EGLint attribs[3][3] = { |
{ |
EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
@@ -50,11 +76,6 @@ void* SkANGLEGLContext::GetD3DEGLDisplay(void* nativeDisplay, bool useGLBackend) |
EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, |
EGL_NONE |
}, |
- { |
- EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
- EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, |
- EGL_NONE |
- } |
}; |
for (int i = 0; i < 3 && display == EGL_NO_DISPLAY; ++i) { |
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,nativeDisplay, attribs[i]); |
@@ -63,7 +84,30 @@ void* SkANGLEGLContext::GetD3DEGLDisplay(void* nativeDisplay, bool useGLBackend) |
return display; |
} |
-SkANGLEGLContext::SkANGLEGLContext(bool useGLBackend) |
+class ANGLEGLContext : public sk_gpu_test::GLContext { |
+public: |
+ ANGLEGLContext(bool preferGLBackend); |
+ ~ANGLEGLContext() override; |
+ |
+ GrEGLImage texture2DToEGLImage(GrGLuint texID) const override; |
+ void destroyEGLImage(GrEGLImage) const override; |
+ GrGLuint eglImageToExternalTexture(GrEGLImage) const override; |
+ sk_gpu_test::GLContext* createNew() const override; |
+ |
+private: |
+ void destroyGLContext(); |
+ |
+ void onPlatformMakeCurrent() const override; |
+ void onPlatformSwapBuffers() const override; |
+ GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override; |
+ |
+ void* fContext; |
+ void* fDisplay; |
+ void* fSurface; |
+ bool fIsGLBackend; |
+}; |
+ |
+ANGLEGLContext::ANGLEGLContext(bool useGLBackend) |
: fContext(EGL_NO_CONTEXT) |
, fDisplay(EGL_NO_DISPLAY) |
, fSurface(EGL_NO_SURFACE) { |
@@ -80,7 +124,7 @@ SkANGLEGLContext::SkANGLEGLContext(bool useGLBackend) |
}; |
fIsGLBackend = useGLBackend; |
- fDisplay = GetD3DEGLDisplay(EGL_DEFAULT_DISPLAY, useGLBackend); |
+ fDisplay = get_angle_egl_display(EGL_DEFAULT_DISPLAY, useGLBackend); |
if (EGL_NO_DISPLAY == fDisplay) { |
SkDebugf("Could not create EGL display!"); |
return; |
@@ -110,7 +154,7 @@ SkANGLEGLContext::SkANGLEGLContext(bool useGLBackend) |
eglMakeCurrent(fDisplay, fSurface, fSurface, fContext); |
- SkAutoTUnref<const GrGLInterface> gl(GrGLCreateANGLEInterface()); |
+ SkAutoTUnref<const GrGLInterface> gl(sk_gpu_test::CreateANGLEGLInterface()); |
if (nullptr == gl.get()) { |
SkDebugf("Could not create ANGLE GL interface!\n"); |
this->destroyGLContext(); |
@@ -125,12 +169,12 @@ SkANGLEGLContext::SkANGLEGLContext(bool useGLBackend) |
this->init(gl.release()); |
} |
-SkANGLEGLContext::~SkANGLEGLContext() { |
+ANGLEGLContext::~ANGLEGLContext() { |
this->teardown(); |
this->destroyGLContext(); |
} |
-GrEGLImage SkANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const { |
+GrEGLImage ANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const { |
if (!this->gl()->hasExtension("EGL_KHR_gl_texture_2D_image")) { |
return GR_EGL_NO_IMAGE; |
} |
@@ -146,17 +190,16 @@ GrEGLImage SkANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const { |
return img; |
} |
-void SkANGLEGLContext::destroyEGLImage(GrEGLImage image) const { |
+void ANGLEGLContext::destroyEGLImage(GrEGLImage image) const { |
GR_GL_CALL(this->gl(), EGLDestroyImage(fDisplay, image)); |
} |
-GrGLuint SkANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const { |
+GrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const { |
GrGLClearErr(this->gl()); |
if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) { |
return 0; |
} |
typedef GrGLvoid (*EGLImageTargetTexture2DProc)(GrGLenum, GrGLeglImage); |
- |
EGLImageTargetTexture2DProc glEGLImageTargetTexture2D = |
(EGLImageTargetTexture2DProc)eglGetProcAddress("glEGLImageTargetTexture2DOES"); |
if (!glEGLImageTargetTexture2D) { |
@@ -180,12 +223,12 @@ GrGLuint SkANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const { |
return texID; |
} |
-SkGLContext* SkANGLEGLContext::createNew() const { |
+sk_gpu_test::GLContext* ANGLEGLContext::createNew() const { |
#ifdef SK_BUILD_FOR_WIN |
- SkGLContext* ctx = fIsGLBackend ? SkANGLEGLContext::CreateOpenGL() |
- : SkANGLEGLContext::CreateDirectX(); |
+ sk_gpu_test::GLContext* ctx = fIsGLBackend ? sk_gpu_test::CreateANGLEOpenGLGLContext() |
+ : sk_gpu_test::CreateANGLEDirect3DGLContext(); |
#else |
- SkGLContext* ctx = SkANGLEGLContext::CreateOpenGL(); |
+ sk_gpu_test::GLContext* ctx = sk_gpu_test::CreateANGLEOpenGLGLContext(); |
#endif |
if (ctx) { |
ctx->makeCurrent(); |
@@ -193,7 +236,7 @@ SkGLContext* SkANGLEGLContext::createNew() const { |
return ctx; |
} |
-void SkANGLEGLContext::destroyGLContext() { |
+void ANGLEGLContext::destroyGLContext() { |
if (fDisplay) { |
eglMakeCurrent(fDisplay, 0, 0, 0); |
@@ -212,18 +255,66 @@ void SkANGLEGLContext::destroyGLContext() { |
} |
} |
-void SkANGLEGLContext::onPlatformMakeCurrent() const { |
+void ANGLEGLContext::onPlatformMakeCurrent() const { |
if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
SkDebugf("Could not set the context.\n"); |
} |
} |
-void SkANGLEGLContext::onPlatformSwapBuffers() const { |
+void ANGLEGLContext::onPlatformSwapBuffers() const { |
if (!eglSwapBuffers(fDisplay, fSurface)) { |
SkDebugf("Could not complete eglSwapBuffers.\n"); |
} |
} |
-GrGLFuncPtr SkANGLEGLContext::onPlatformGetProcAddress(const char* name) const { |
+GrGLFuncPtr ANGLEGLContext::onPlatformGetProcAddress(const char* name) const { |
return eglGetProcAddress(name); |
} |
+} // anonymous namespace |
+ |
+namespace sk_gpu_test { |
+const GrGLInterface* CreateANGLEGLInterface() { |
+ static Libs gLibs = { nullptr, nullptr }; |
+ |
+ if (nullptr == gLibs.fGLLib) { |
+ // We load the ANGLE library and never let it go |
+#if defined _WIN32 |
+ gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.dll"); |
+ gLibs.fEGLLib = DynamicLoadLibrary("libEGL.dll"); |
+#elif defined SK_BUILD_FOR_MAC |
+ gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.dylib"); |
+ gLibs.fEGLLib = DynamicLoadLibrary("libEGL.dylib"); |
+#else |
+ gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.so"); |
+ gLibs.fEGLLib = DynamicLoadLibrary("libEGL.so"); |
+#endif |
+ } |
+ |
+ if (nullptr == gLibs.fGLLib || nullptr == gLibs.fEGLLib) { |
+ // We can't setup the interface correctly w/o the so |
+ return nullptr; |
+ } |
+ |
+ return GrGLAssembleGLESInterface(&gLibs, angle_get_gl_proc); |
+} |
+ |
+#ifdef SK_BUILD_FOR_WIN |
+GLContext* CreateANGLEDirect3DGLContext() { |
+ ANGLEGLContext* ctx = new ANGLEGLContext(false); |
+ if (!ctx->isValid()) { |
+ delete ctx; |
+ return NULL; |
+ } |
+ return ctx; |
+ } |
+#endif |
+ |
+GLContext* CreateANGLEOpenGLGLContext() { |
+ ANGLEGLContext* ctx = new ANGLEGLContext(true); |
+ if (!ctx->isValid()) { |
+ delete ctx; |
+ return NULL; |
+ } |
+ return ctx; |
+} |
+} // namespace sk_gpu_test |