diff options
author | Mike Klein <mtklein@chromium.org> | 2016-11-14 14:53:13 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-14 14:53:23 +0000 |
commit | c168a3ac3cb96555011c73938f71f8183990ab46 (patch) | |
tree | b82007a473656e03cacd4c19c82401d7b23e7a16 | |
parent | 238b820369c4b556c2e7c8277855e6950de3d9eb (diff) |
Revert "Always build the ANGLE test code. Always build ANGLE on windows and linux."
This reverts commit 238b820369c4b556c2e7c8277855e6950de3d9eb.
Reason for revert: breaks 32-bit bots, iOS bots, Google3 roll, -ASAN bot.
Original change's description:
> Always build the ANGLE test code. Always build ANGLE on windows and linux.
>
> Make ANGLE test code independent of having ANGLE lib. Make ANGLE test code not include EGL headers.
>
> GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4040
>
> DOCS_PREVIEW= https://skia.org/?cl=4040
>
> Change-Id: I7b857e9785246743f53fb969647b1162ce7419ab
> Reviewed-on: https://skia-review.googlesource.com/4040
> Commit-Queue: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Mike Klein <mtklein@chromium.org>
>
TBR=mtklein@chromium.org,mtklein@google.com,bsalomon@google.com,reviews@skia.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
Change-Id: I19bab8c93baebf032f8a4cefbedfe7359317e806
Reviewed-on: https://skia-review.googlesource.com/4758
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
-rw-r--r-- | BUILD.gn | 12 | ||||
-rw-r--r-- | infra/bots/recipe_modules/flavor/gn_flavor.py | 2 | ||||
-rw-r--r-- | infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json | 2 | ||||
-rw-r--r-- | infra/bots/recipes/swarm_compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json | 2 | ||||
-rw-r--r-- | site/user/special/angle.md | 3 | ||||
-rw-r--r-- | tests/ImageTest.cpp | 13 | ||||
-rw-r--r-- | tools/gpu/GrContextFactory.cpp | 6 | ||||
-rw-r--r-- | tools/gpu/gl/angle/GLTestContext_angle.cpp | 419 |
8 files changed, 116 insertions, 343 deletions
@@ -11,6 +11,7 @@ if (!defined(is_skia_standalone)) { } declare_args() { + skia_use_angle = false skia_use_expat = true skia_use_fontconfig = is_linux skia_use_freetype = is_android || is_fuchsia || is_linux @@ -754,7 +755,6 @@ if (skia_enable_tools) { "tools/gpu/GrTest.cpp", "tools/gpu/TestContext.cpp", "tools/gpu/gl/GLTestContext.cpp", - "tools/gpu/gl/angle/GLTestContext_angle.cpp", "tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp", "tools/gpu/gl/debug/DebugGLTestContext.cpp", "tools/gpu/gl/debug/GrBufferObj.cpp", @@ -774,7 +774,6 @@ if (skia_enable_tools) { libs += [ "OpenGLES.framework" ] } else if (is_linux) { sources += [ "tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp" ] - deps += [ "//third_party/angle2" ] } else if (is_mac) { sources += [ "tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp" ] } else if (is_win) { @@ -783,9 +782,13 @@ if (skia_enable_tools) { "Gdi32.lib", "OpenGL32.lib", ] - deps += [ "//third_party/angle2" ] } + if (skia_use_angle) { + public_defines += [ "SK_ANGLE" ] + deps += [ "//third_party/angle2" ] + sources += [ "tools/gpu/gl/angle/GLTestContext_angle.cpp" ] + } if (skia_use_mesa) { public_defines += [ "SK_MESA" ] sources += [ "tools/gpu/gl/mesa/GLTestContext_mesa.cpp" ] @@ -1100,6 +1103,9 @@ if (skia_enable_tools) { ":tool_utils", ":views", ] + if (skia_use_angle) { + deps += [ "//third_party/angle2" ] + } testonly = true } } diff --git a/infra/bots/recipe_modules/flavor/gn_flavor.py b/infra/bots/recipe_modules/flavor/gn_flavor.py index 705cfe292d..af400d9045 100644 --- a/infra/bots/recipe_modules/flavor/gn_flavor.py +++ b/infra/bots/recipe_modules/flavor/gn_flavor.py @@ -73,6 +73,8 @@ class GNFlavorUtils(default_flavor.DefaultFlavorUtils): if configuration != 'Debug': args['is_debug'] = 'false' + if extra_config == 'ANGLE': + args['skia_use_angle'] = 'true' if extra_config == 'CommandBuffer': self.m.run.run_once(self.build_command_buffer) if extra_config == 'GDI': diff --git a/infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json b/infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json index 3cc7a39463..79a420a8f3 100644 --- a/infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json +++ b/infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json @@ -92,7 +92,7 @@ "gn", "gen", "[CUSTOM_/_B_WORK]/skia/out/Build-Ubuntu-GCC-x86_64-Release-ANGLE/Release", - "--args=cc=\"gcc\" cxx=\"g++\" is_debug=false" + "--args=cc=\"gcc\" cxx=\"g++\" is_debug=false skia_use_angle=true" ], "cwd": "[CUSTOM_/_B_WORK]/skia", "env": { diff --git a/infra/bots/recipes/swarm_compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json b/infra/bots/recipes/swarm_compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json index c94c98a05f..39940cfc6e 100644 --- a/infra/bots/recipes/swarm_compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json +++ b/infra/bots/recipes/swarm_compile.expected/Build-Win-MSVC-x86-Debug-ANGLE.json @@ -92,7 +92,7 @@ "gn.bat", "gen", "[CUSTOM_C:\\_B_WORK]\\skia\\out\\Build-Win-MSVC-x86-Debug-ANGLE\\Debug", - "--args=target_cpu=\"x86\" windk=\"[SLAVE_BUILD]\\t\\depot_tools\\win_toolchain\\vs_files\\95ddda401ec5678f15eeed01d2bee08fcbc5ee97\"" + "--args=skia_use_angle=true target_cpu=\"x86\" windk=\"[SLAVE_BUILD]\\t\\depot_tools\\win_toolchain\\vs_files\\95ddda401ec5678f15eeed01d2bee08fcbc5ee97\"" ], "cwd": "[CUSTOM_C:\\_B_WORK]\\skia", "env": { diff --git a/site/user/special/angle.md b/site/user/special/angle.md index 2ff7a35c69..ff8f1c8d3e 100644 --- a/site/user/special/angle.md +++ b/site/user/special/angle.md @@ -13,7 +13,8 @@ Details `gclient sync` downloads ANGLE's source alongside Skia's other test-only dependencies. -ANGLE is built when building Skia test tools on Windows and Linux. +To build Skia testing tools against ANGLE, add `skia_use_angle = true` to your +`args.gn` file (or run `gn args` to edit it). When running tools, use `--config angle_<backend>_<frontend>`, e.g. diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp index 2752c9898f..0acb428d7a 100644 --- a/tests/ImageTest.cpp +++ b/tests/ImageTest.cpp @@ -452,16 +452,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(c, reporter, ctxInfo) { } } -static bool is_rendering_and_not_angle_gl(sk_gpu_test::GrContextFactory::ContextType type) { - if (type == sk_gpu_test::GrContextFactory::kANGLE_GL_ES3_ContextType || - type == sk_gpu_test::GrContextFactory::kANGLE_GL_ES2_ContextType) { - return false; - } - return sk_gpu_test::GrContextFactory::IsRenderingContext(type); -} - -DEF_GPUTEST_FOR_CONTEXTS(SkImage_newTextureImage, is_rendering_and_not_angle_gl, reporter, - contextInfo) { +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkImage_newTextureImage, reporter, contextInfo) { GrContext* context = contextInfo.grContext(); sk_gpu_test::TestContext* testContext = contextInfo.testContext(); @@ -893,7 +884,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(NewTextureFromPixmap, reporter, ctxInfo) { } } -DEF_GPUTEST_FOR_CONTEXTS(DeferredTextureImage, is_rendering_and_not_angle_gl, reporter, ctxInfo) { +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredTextureImage, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); sk_gpu_test::TestContext* testContext = ctxInfo.testContext(); sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy(); diff --git a/tools/gpu/GrContextFactory.cpp b/tools/gpu/GrContextFactory.cpp index 63d5f0a617..ffc5295ab2 100644 --- a/tools/gpu/GrContextFactory.cpp +++ b/tools/gpu/GrContextFactory.cpp @@ -9,7 +9,9 @@ #include "GrContextFactory.h" #include "gl/GLTestContext.h" -#include "gl/angle/GLTestContext_angle.h" +#if SK_ANGLE + #include "gl/angle/GLTestContext_angle.h" +#endif #include "gl/command_buffer/GLTestContext_command_buffer.h" #include "gl/debug/DebugGLTestContext.h" #if SK_MESA @@ -114,6 +116,7 @@ ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOptions op case kGLES_ContextType: glCtx = CreatePlatformGLTestContext(kGLES_GrGLStandard); break; +#if SK_ANGLE case kANGLE_D3D9_ES2_ContextType: glCtx = MakeANGLETestContext(ANGLEBackend::kD3D9, ANGLEContextVersion::kES2).release(); break; @@ -129,6 +132,7 @@ ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOptions op case kANGLE_GL_ES3_ContextType: glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES3).release(); break; +#endif case kCommandBuffer_ContextType: glCtx = CommandBufferGLTestContext::Create(); break; diff --git a/tools/gpu/gl/angle/GLTestContext_angle.cpp b/tools/gpu/gl/angle/GLTestContext_angle.cpp index 92c6cf4649..c3ec431b7e 100644 --- a/tools/gpu/gl/angle/GLTestContext_angle.cpp +++ b/tools/gpu/gl/angle/GLTestContext_angle.cpp @@ -8,6 +8,9 @@ #include "GLTestContext_angle.h" +#include <EGL/egl.h> +#include <EGL/eglext.h> + #include "gl/GrGLDefines.h" #include "gl/GrGLUtil.h" @@ -15,308 +18,61 @@ #include "gl/GrGLAssembleInterface.h" #include "../ports/SkOSLibrary.h" -#include "SkRefCnt.h" -#include "SkSpinlock.h" -#include "SkTDArray.h" - -/** - * EGL.h stuff. We don't want to worry about whether we're pulling in ANGLE's functions or some - * other system EGL implementation. So we just define all the EGL types we need and dynamically - * load all the functions we need. - */ - -#if defined(SK_BUILD_FOR_WIN) - #include <Windows.h> - using EGLNativeDisplayType = HDC; - using EGLNativePixmapType = HBITMAP; - using EGLNativeWindowType = HWND; -#elif defined(SK_BUILD_FOR_UNIX) - #include <X11/Xlib.h> - using EGLNativeDisplayType = Display*; - using EGLNativePixmapType = Pixmap; - using EGLNativeWindowType = Window; -#else - using EGLNativeDisplayType = void*; - using EGLNativePixmapType = void*; - using EGLNativeWindowType = void*; -#endif - -using EGLint = int32_t; -using EGLFn = void(void); -using EGLDisplay = void*; -using EGLSurface = void*; -using EGLContext = void*; -using EGLConfig = void*; -using EGLenum = unsigned int; -using EGLBoolean = unsigned int; - -using EGLGetProcAddressFn = EGLFn*(const char *procname); -using EGLInitializeFn = EGLBoolean(EGLDisplay display, EGLint * major, EGLint * minor); -using EGLTerminateFn = EGLBoolean(EGLDisplay display); -using EGLChooseConfigFn = EGLBoolean(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); -using EGLCreateContextFn = EGLContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); -using EGLCreatePbufferSurfaceFn = EGLSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); -using EGLMakeCurrentFn = EGLBoolean(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); -using EGLDestroyContextFn = EGLBoolean(EGLDisplay dpy, EGLContext ctx); -using EGLDestroySurfaceFn = EGLBoolean(EGLDisplay dpy, EGLSurface surface); -using EGLSwapBuffersFn = EGLBoolean(EGLDisplay dpy, EGLSurface surface); -using EGLGetErrorFn = EGLint(); +#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 -#define EGL_NO_DISPLAY ((EGLDisplay)0) -#define EGL_NO_CONTEXT ((EGLContext)0) -#define EGL_NO_SURFACE ((EGLSurface)0) -#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) -#define EGL_NONE 0x3038 -#define EGL_SURFACE_TYPE 0x3033 -#define EGL_PBUFFER_BIT 0x0001 -#define EGL_RENDERABLE_TYPE 0x3040 -#define EGL_OPENGL_ES2_BIT 0x0004 -#define EGL_RED_SIZE 0x3024 -#define EGL_GREEN_SIZE 0x3023 -#define EGL_BLUE_SIZE 0x3022 -#define EGL_ALPHA_SIZE 0x3021 -#define EGL_CONTEXT_CLIENT_VERSION 0x3098 -#define EGL_WIDTH 0x3057 -#define EGL_HEIGHT 0x3056 -#define EGL_FALSE 0 -#define EGL_TRUE 1 using sk_gpu_test::ANGLEBackend; using sk_gpu_test::ANGLEContextVersion; namespace { - -class ANGLE : public ::SkRefCnt { -public: - static sk_sp<ANGLE> Get() { - gSpinlock.acquire(); - if (!gANGLE) { - sk_sp<ANGLE> angle(new ANGLE); - if (angle->load()) { - gANGLE = angle; - } - } - gSpinlock.release(); - return gANGLE; - } - - EGLBoolean initialize(EGLDisplay display, EGLint * major, EGLint * minor) const { - return fInitialize(display, major, minor); - } - - EGLBoolean terminate(EGLDisplay display) const { - return fTerminate(display); - } - - EGLFn* getProcAddress(const char* procname) const { - void* lib = (0 == strncmp("gl", procname, 2)) ? fGLLib : fEGLLib; - EGLFn* proc = (EGLFn*)GetProcedureAddress(lib, procname); - if (!proc) { - proc = fGetProcAddress(procname); - } - return proc; - } - - EGLBoolean chooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, - EGLint config_size, EGLint *num_config) const { - return fChooseConfig(dpy, attrib_list, configs, config_size, num_config); - } - - EGLContext createContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, - const EGLint *attrib_list) const { - return fCreateContext(dpy, config, share_context, attrib_list); - } - - EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list) const { - return fCreatePbufferSurface(dpy, config, attrib_list); - } - - EGLBoolean makeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) const { - return fMakeCurrent(dpy, draw, read, ctx); - } - - EGLBoolean destroyContext(EGLDisplay dpy, EGLContext ctx) const { - return fDestroyContext(dpy, ctx); - } - - EGLBoolean destroySurface(EGLDisplay dpy, EGLSurface surface) const { - return fDestroySurface(dpy, surface); - } - - EGLBoolean swapBuffers(EGLDisplay display, EGLSurface surface) const { - return fSwapBuffers(display, surface); - } - - EGLint getError() const { return fGetError(); } - -private: - bool load() { - // We load the ANGLE library and never let it go -#if defined(SK_BUILD_FOR_WIN) - fGLLib = DynamicLoadLibrary("libGLESv2.dll"); - fEGLLib = DynamicLoadLibrary("libEGL.dll"); -#elif defined(SK_BUILD_FOR_MAC) - fGLLib = DynamicLoadLibrary("libGLESv2.dylib"); - fEGLLib = DynamicLoadLibrary("libEGL.dylib"); -#else - fGLLib = DynamicLoadLibrary("libGLESv2.so"); - fEGLLib = DynamicLoadLibrary("libEGL.so"); -#endif - if (!fGLLib || !fEGLLib) { - return false; - } -#define GET_PROC(NAME) f ## NAME = (EGL ## NAME ##Fn*) GetProcedureAddress(fEGLLib, "egl" #NAME); \ - if (!f ## NAME) { return false; } - GET_PROC(GetProcAddress); - GET_PROC(Initialize); - GET_PROC(Terminate); - GET_PROC(ChooseConfig); - GET_PROC(CreateContext) - GET_PROC(CreatePbufferSurface); - GET_PROC(MakeCurrent); - GET_PROC(DestroyContext); - GET_PROC(DestroySurface); - GET_PROC(SwapBuffers); - GET_PROC(GetError); -#undef GET_PROC - return true; - } - - ANGLE() = default; - ~ANGLE() { - SkDebugf("Done!"); - } - - EGLGetProcAddressFn* fGetProcAddress; - EGLInitializeFn* fInitialize; - EGLTerminateFn* fTerminate; - EGLChooseConfigFn* fChooseConfig; - EGLCreateContextFn* fCreateContext; - EGLCreatePbufferSurfaceFn* fCreatePbufferSurface; - EGLMakeCurrentFn* fMakeCurrent; - EGLDestroyContextFn* fDestroyContext; - EGLDestroySurfaceFn* fDestroySurface; - EGLSwapBuffersFn* fSwapBuffers; - EGLGetErrorFn* fGetError; - - void* fGLLib; - void* fEGLLib; - - static sk_sp<ANGLE> gANGLE; - static SkSpinlock gSpinlock; +struct Libs { + void* fGLLib; + void* fEGLLib; }; -SkSpinlock ANGLE::gSpinlock; -sk_sp<ANGLE> ANGLE::gANGLE; - static GrGLFuncPtr angle_get_gl_proc(void* ctx, const char name[]) { - const ANGLE* angle = reinterpret_cast<const ANGLE*>(ctx); - return angle->getProcAddress(name); -} - -class Display { -public: - static std::unique_ptr<Display> Make(ANGLEBackend type) { - gSpinlock.acquire(); - EGLDisplay display = GetEGLDisplay(type); - if (display == EGL_NO_DISPLAY) { - // This happens often (e.g. D3D on Linux) so no print. - if (0) { - SkDebugf("Could not get display.\n"); - } - gSpinlock.release(); - return nullptr; - } - int i = 0; - for (; i < gEGLDisplays.count(); ++i) { - if (gEGLDisplays[i].fDisplay == display) { - ++gEGLDisplays[i].fRefCnt; - break; - } - } - if (i == gEGLDisplays.count()) { - EGLint majorVersion; - EGLint minorVersion; - if (ANGLE::Get()->initialize(display, &majorVersion, &minorVersion) == EGL_FALSE) { - SkDebugf("Failed to initialize display.\n"); - gSpinlock.release(); - return nullptr; - } - gEGLDisplays.push()->fDisplay = display; - gEGLDisplays.top().fRefCnt = 1; - } - gSpinlock.release(); - return std::unique_ptr<Display>(new Display(display)); - } - - ~Display() { - gSpinlock.acquire(); - for (int i = 0; i < gEGLDisplays.count(); ++i) { - if (gEGLDisplays[i].fDisplay == fDisplay) { - if (--gEGLDisplays[i].fRefCnt == 0) { - ANGLE::Get()->terminate(fDisplay); - gEGLDisplays.removeShuffle(i); - } - gSpinlock.release(); - return; - } - } - SkFAIL("Didn't find ref counted EGLDisplay entry."); + const Libs* libs = reinterpret_cast<const Libs*>(ctx); + GrGLFuncPtr proc = (GrGLFuncPtr) GetProcedureAddress(libs->fGLLib, name); + if (proc) { + return proc; } - - EGLDisplay get() const { return fDisplay; } - -private: - Display& operator=(const Display&) = delete; - Display(EGLDisplay display) : fDisplay(display) {} - Display(const Display&) = delete; - - static EGLDisplay GetEGLDisplay(ANGLEBackend type) { - using EGLGetPlatformDisplayEXTFn = EGLDisplay(EGLenum platform, void *native_display, - const EGLint *attrib_list); - EGLGetPlatformDisplayEXTFn* eglGetPlatformDisplayEXT = - (EGLGetPlatformDisplayEXTFn*)ANGLE::Get()->getProcAddress( - "eglGetPlatformDisplayEXT"); - - // We expect ANGLE to support this extension - if (!eglGetPlatformDisplayEXT) { - return EGL_NO_DISPLAY; - } - - EGLint typeNum = 0; - switch (type) { - case ANGLEBackend::kD3D9: - typeNum = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE; - break; - case ANGLEBackend::kD3D11: - typeNum = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; - break; - case ANGLEBackend::kOpenGL: - typeNum = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; - break; - } - const EGLint attribs[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, typeNum, EGL_NONE }; - return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, attribs); + proc = (GrGLFuncPtr) GetProcedureAddress(libs->fEGLLib, name); + if (proc) { + return proc; } + return eglGetProcAddress(name); +} - EGLDisplay fDisplay; - - struct D { - EGLDisplay fDisplay; - int fRefCnt; - }; - static SkTDArray<D> gEGLDisplays; - static SkSpinlock gSpinlock; -}; - -SkSpinlock Display::gSpinlock; -SkTDArray<Display::D> Display::gEGLDisplays; +void* get_angle_egl_display(void* nativeDisplay, ANGLEBackend type) { + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; + eglGetPlatformDisplayEXT = + (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + + // We expect ANGLE to support this extension + if (!eglGetPlatformDisplayEXT) { + return EGL_NO_DISPLAY; + } + + EGLint typeNum = 0; + switch (type) { + case ANGLEBackend::kD3D9: + typeNum = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE; + break; + case ANGLEBackend::kD3D11: + typeNum = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE; + break; + case ANGLEBackend::kOpenGL: + typeNum = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; + break; + } + const EGLint attribs[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, typeNum, EGL_NONE }; + return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, attribs); +} class ANGLEGLContext : public sk_gpu_test::GLTestContext { public: @@ -329,32 +85,26 @@ public: std::unique_ptr<sk_gpu_test::GLTestContext> makeNew() const override; private: - EGLDisplay display() const { return fDisplay.get()->get(); } void destroyGLContext(); void onPlatformMakeCurrent() const override; void onPlatformSwapBuffers() const override; GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override; - sk_sp<ANGLE> fANGLE; - EGLContext fContext; - std::unique_ptr<Display> fDisplay; - EGLSurface fSurface; + void* fContext; + void* fDisplay; + void* fSurface; ANGLEBackend fType; ANGLEContextVersion fVersion; }; ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version) - : fANGLE(ANGLE::Get()) - , fContext(EGL_NO_CONTEXT) - , fDisplay(Display::Make(type)) + : fContext(EGL_NO_CONTEXT) + , fDisplay(EGL_NO_DISPLAY) , fSurface(EGL_NO_SURFACE) , fType(type) , fVersion(version) { - if (!fANGLE || !fDisplay) { - return; - } EGLint numConfigs; static const EGLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, @@ -366,24 +116,26 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version) EGL_NONE }; - EGLConfig surfaceConfig; - if (fANGLE->chooseConfig(this->display(), configAttribs, &surfaceConfig, 1, &numConfigs) == - EGL_FALSE) { - SkDebugf("Could not choose config for display!\n"); + fDisplay = get_angle_egl_display(EGL_DEFAULT_DISPLAY, type); + if (EGL_NO_DISPLAY == fDisplay) { + SkDebugf("Could not create EGL display!"); 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, EGL_NONE }; - fContext = fANGLE->createContext(this->display(), surfaceConfig, nullptr, contextAttribs); + fContext = eglCreateContext(fDisplay, surfaceConfig, nullptr, contextAttribs); - if (EGL_NO_CONTEXT == fContext) { - SkDebugf("Failed to create context\n"); - return; - } static const EGLint surfaceAttribs[] = { EGL_WIDTH, 1, @@ -391,12 +143,11 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version) EGL_NONE }; - fSurface = fANGLE->createPbufferSurface(this->display(), surfaceConfig, surfaceAttribs); + fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs); - fANGLE->makeCurrent(this->display(), fSurface, fSurface, fContext); + eglMakeCurrent(fDisplay, fSurface, fSurface, fContext); - sk_sp<const GrGLInterface> gl(GrGLAssembleGLESInterface((void*)fANGLE.get(), - angle_get_gl_proc)); + sk_sp<const GrGLInterface> gl(sk_gpu_test::CreateANGLEGLInterface()); if (nullptr == gl.get()) { SkDebugf("Could not create ANGLE GL interface!\n"); this->destroyGLContext(); @@ -427,13 +178,13 @@ GrEGLImage ANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const { // 64 bit cast is to shut Visual C++ up about casting 32 bit value to a pointer. GrEGLClientBuffer clientBuffer = reinterpret_cast<GrEGLClientBuffer>((uint64_t)texID); GR_GL_CALL_RET(this->gl(), img, - EGLCreateImage(this->display(), fContext, GR_EGL_GL_TEXTURE_2D, clientBuffer, + EGLCreateImage(fDisplay, fContext, GR_EGL_GL_TEXTURE_2D, clientBuffer, attribs)); return img; } void ANGLEGLContext::destroyEGLImage(GrEGLImage image) const { - GR_GL_CALL(this->gl(), EGLDestroyImage(this->display(), image)); + GR_GL_CALL(this->gl(), EGLDestroyImage(fDisplay, image)); } GrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const { @@ -441,9 +192,9 @@ GrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const { if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) { return 0; } - using EGLImageTargetTexture2DFn = GrGLvoid(GrGLenum, GrGLeglImage); - EGLImageTargetTexture2DFn* glEGLImageTargetTexture2D = - (EGLImageTargetTexture2DFn*)fANGLE->getProcAddress("glEGLImageTargetTexture2DOES"); + typedef GrGLvoid (EGLAPIENTRY *EGLImageTargetTexture2DProc)(GrGLenum, GrGLeglImage); + EGLImageTargetTexture2DProc glEGLImageTargetTexture2D = + (EGLImageTargetTexture2DProc)eglGetProcAddress("glEGLImageTargetTexture2DOES"); if (!glEGLImageTargetTexture2D) { return 0; } @@ -476,46 +227,64 @@ std::unique_ptr<sk_gpu_test::GLTestContext> ANGLEGLContext::makeNew() const { void ANGLEGLContext::destroyGLContext() { if (fDisplay) { - fANGLE->makeCurrent(this->display(), 0, 0, 0); + eglMakeCurrent(fDisplay, 0, 0, 0); if (fContext) { - fANGLE->destroyContext(this->display(), fContext); + eglDestroyContext(fDisplay, fContext); fContext = EGL_NO_CONTEXT; } if (fSurface) { - fANGLE->destroySurface(this->display(), fSurface); + eglDestroySurface(fDisplay, fSurface); fSurface = EGL_NO_SURFACE; } - fDisplay.reset(); + + //TODO should we close the display? + fDisplay = EGL_NO_DISPLAY; } } void ANGLEGLContext::onPlatformMakeCurrent() const { - if (!fANGLE->makeCurrent(this->display(), fSurface, fSurface, fContext)) { + if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { SkDebugf("Could not set the context.\n"); } } void ANGLEGLContext::onPlatformSwapBuffers() const { - if (!fANGLE->swapBuffers(this->display(), fSurface)) { + if (!eglSwapBuffers(fDisplay, fSurface)) { SkDebugf("Could not complete eglSwapBuffers.\n"); } } GrGLFuncPtr ANGLEGLContext::onPlatformGetProcAddress(const char* name) const { - return fANGLE->getProcAddress(name); + return eglGetProcAddress(name); } - } // anonymous namespace namespace sk_gpu_test { const GrGLInterface* CreateANGLEGLInterface() { - sk_sp<ANGLE> angle = ANGLE::Get(); - if (!angle) { + 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((void*)angle.get(), angle_get_gl_proc); + + return GrGLAssembleGLESInterface(&gLibs, angle_get_gl_proc); } std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend type, ANGLEContextVersion version){ |