1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLDefines.h" 9cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLUtil.h" 10cb93a386Sopenharmony_ci#include "tools/gpu/gl/GLTestContext.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#define GL_GLEXT_PROTOTYPES 13cb93a386Sopenharmony_ci#include <EGL/egl.h> 14cb93a386Sopenharmony_ci#include <EGL/eglext.h> 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cinamespace { 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_cistd::function<void()> context_restorer() { 19cb93a386Sopenharmony_ci auto display = eglGetCurrentDisplay(); 20cb93a386Sopenharmony_ci auto dsurface = eglGetCurrentSurface(EGL_DRAW); 21cb93a386Sopenharmony_ci auto rsurface = eglGetCurrentSurface(EGL_READ); 22cb93a386Sopenharmony_ci auto context = eglGetCurrentContext(); 23cb93a386Sopenharmony_ci return [display, dsurface, rsurface, context] { 24cb93a386Sopenharmony_ci eglMakeCurrent(display, dsurface, rsurface, context); 25cb93a386Sopenharmony_ci }; 26cb93a386Sopenharmony_ci} 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ciclass EGLGLTestContext : public sk_gpu_test::GLTestContext { 29cb93a386Sopenharmony_cipublic: 30cb93a386Sopenharmony_ci EGLGLTestContext(GrGLStandard forcedGpuAPI, EGLGLTestContext* shareContext); 31cb93a386Sopenharmony_ci ~EGLGLTestContext() override; 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci GrEGLImage texture2DToEGLImage(GrGLuint texID) const override; 34cb93a386Sopenharmony_ci void destroyEGLImage(GrEGLImage) const override; 35cb93a386Sopenharmony_ci GrGLuint eglImageToExternalTexture(GrEGLImage) const override; 36cb93a386Sopenharmony_ci std::unique_ptr<sk_gpu_test::GLTestContext> makeNew() const override; 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ciprivate: 39cb93a386Sopenharmony_ci void destroyGLContext(); 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci void onPlatformMakeNotCurrent() const override; 42cb93a386Sopenharmony_ci void onPlatformMakeCurrent() const override; 43cb93a386Sopenharmony_ci std::function<void()> onPlatformGetAutoContextRestore() const override; 44cb93a386Sopenharmony_ci GrGLFuncPtr onPlatformGetProcAddress(const char*) const override; 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci PFNEGLCREATEIMAGEKHRPROC fEglCreateImageProc = nullptr; 47cb93a386Sopenharmony_ci PFNEGLDESTROYIMAGEKHRPROC fEglDestroyImageProc = nullptr; 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci EGLContext fContext; 50cb93a386Sopenharmony_ci EGLDisplay fDisplay; 51cb93a386Sopenharmony_ci EGLSurface fSurface; 52cb93a386Sopenharmony_ci}; 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_cistatic EGLContext create_gles_egl_context(EGLDisplay display, 55cb93a386Sopenharmony_ci EGLConfig surfaceConfig, 56cb93a386Sopenharmony_ci EGLContext eglShareContext, 57cb93a386Sopenharmony_ci EGLint eglContextClientVersion) { 58cb93a386Sopenharmony_ci const EGLint contextAttribsForOpenGLES[] = { 59cb93a386Sopenharmony_ci EGL_CONTEXT_CLIENT_VERSION, 60cb93a386Sopenharmony_ci eglContextClientVersion, 61cb93a386Sopenharmony_ci EGL_NONE 62cb93a386Sopenharmony_ci }; 63cb93a386Sopenharmony_ci return eglCreateContext(display, surfaceConfig, eglShareContext, contextAttribsForOpenGLES); 64cb93a386Sopenharmony_ci} 65cb93a386Sopenharmony_cistatic EGLContext create_gl_egl_context(EGLDisplay display, 66cb93a386Sopenharmony_ci EGLConfig surfaceConfig, 67cb93a386Sopenharmony_ci EGLContext eglShareContext) { 68cb93a386Sopenharmony_ci const EGLint contextAttribsForOpenGL[] = { 69cb93a386Sopenharmony_ci EGL_NONE 70cb93a386Sopenharmony_ci }; 71cb93a386Sopenharmony_ci return eglCreateContext(display, surfaceConfig, eglShareContext, contextAttribsForOpenGL); 72cb93a386Sopenharmony_ci} 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ciEGLGLTestContext::EGLGLTestContext(GrGLStandard forcedGpuAPI, EGLGLTestContext* shareContext) 75cb93a386Sopenharmony_ci : fContext(EGL_NO_CONTEXT) 76cb93a386Sopenharmony_ci , fDisplay(EGL_NO_DISPLAY) 77cb93a386Sopenharmony_ci , fSurface(EGL_NO_SURFACE) { 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_ci EGLContext eglShareContext = shareContext ? shareContext->fContext : nullptr; 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci static const GrGLStandard kStandards[] = { 82cb93a386Sopenharmony_ci kGL_GrGLStandard, 83cb93a386Sopenharmony_ci kGLES_GrGLStandard, 84cb93a386Sopenharmony_ci }; 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci size_t apiLimit = SK_ARRAY_COUNT(kStandards); 87cb93a386Sopenharmony_ci size_t api = 0; 88cb93a386Sopenharmony_ci if (forcedGpuAPI == kGL_GrGLStandard) { 89cb93a386Sopenharmony_ci apiLimit = 1; 90cb93a386Sopenharmony_ci } else if (forcedGpuAPI == kGLES_GrGLStandard) { 91cb93a386Sopenharmony_ci api = 1; 92cb93a386Sopenharmony_ci } 93cb93a386Sopenharmony_ci SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kStandards[api] == forcedGpuAPI); 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci sk_sp<const GrGLInterface> gl; 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci for (; nullptr == gl.get() && api < apiLimit; ++api) { 98cb93a386Sopenharmony_ci fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci EGLint majorVersion; 101cb93a386Sopenharmony_ci EGLint minorVersion; 102cb93a386Sopenharmony_ci eglInitialize(fDisplay, &majorVersion, &minorVersion); 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci#if 0 105cb93a386Sopenharmony_ci SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); 106cb93a386Sopenharmony_ci SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); 107cb93a386Sopenharmony_ci SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); 108cb93a386Sopenharmony_ci SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS)); 109cb93a386Sopenharmony_ci#endif 110cb93a386Sopenharmony_ci bool gles = kGLES_GrGLStandard == kStandards[api]; 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci if (!eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) { 113cb93a386Sopenharmony_ci continue; 114cb93a386Sopenharmony_ci } 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci EGLint numConfigs = 0; 117cb93a386Sopenharmony_ci const EGLint configAttribs[] = { 118cb93a386Sopenharmony_ci EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 119cb93a386Sopenharmony_ci EGL_RENDERABLE_TYPE, gles ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_BIT, 120cb93a386Sopenharmony_ci EGL_RED_SIZE, 8, 121cb93a386Sopenharmony_ci EGL_GREEN_SIZE, 8, 122cb93a386Sopenharmony_ci EGL_BLUE_SIZE, 8, 123cb93a386Sopenharmony_ci EGL_ALPHA_SIZE, 8, 124cb93a386Sopenharmony_ci EGL_NONE 125cb93a386Sopenharmony_ci }; 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci EGLConfig surfaceConfig; 128cb93a386Sopenharmony_ci if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) { 129cb93a386Sopenharmony_ci SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError()); 130cb93a386Sopenharmony_ci continue; 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci if (0 == numConfigs) { 134cb93a386Sopenharmony_ci SkDebugf("No suitable EGL config found.\n"); 135cb93a386Sopenharmony_ci continue; 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci if (gles) { 139cb93a386Sopenharmony_ci#ifdef GR_EGL_TRY_GLES3_THEN_GLES2 140cb93a386Sopenharmony_ci // Some older devices (Nexus7/Tegra3) crash when you try this. So it is (for now) 141cb93a386Sopenharmony_ci // hidden behind this flag. 142cb93a386Sopenharmony_ci fContext = create_gles_egl_context(fDisplay, surfaceConfig, eglShareContext, 3); 143cb93a386Sopenharmony_ci if (EGL_NO_CONTEXT == fContext) { 144cb93a386Sopenharmony_ci fContext = create_gles_egl_context(fDisplay, surfaceConfig, eglShareContext, 2); 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci#else 147cb93a386Sopenharmony_ci fContext = create_gles_egl_context(fDisplay, surfaceConfig, eglShareContext, 2); 148cb93a386Sopenharmony_ci#endif 149cb93a386Sopenharmony_ci } else { 150cb93a386Sopenharmony_ci fContext = create_gl_egl_context(fDisplay, surfaceConfig, eglShareContext); 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci if (EGL_NO_CONTEXT == fContext) { 153cb93a386Sopenharmony_ci SkDebugf("eglCreateContext failed. EGL Error: 0x%08x\n", eglGetError()); 154cb93a386Sopenharmony_ci continue; 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_ci static const EGLint kSurfaceAttribs[] = { 158cb93a386Sopenharmony_ci EGL_WIDTH, 1, 159cb93a386Sopenharmony_ci EGL_HEIGHT, 1, 160cb93a386Sopenharmony_ci EGL_NONE 161cb93a386Sopenharmony_ci }; 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_ci fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs); 164cb93a386Sopenharmony_ci if (EGL_NO_SURFACE == fSurface) { 165cb93a386Sopenharmony_ci SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglGetError()); 166cb93a386Sopenharmony_ci this->destroyGLContext(); 167cb93a386Sopenharmony_ci continue; 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci SkScopeExit restorer(context_restorer()); 171cb93a386Sopenharmony_ci if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 172cb93a386Sopenharmony_ci SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError()); 173cb93a386Sopenharmony_ci this->destroyGLContext(); 174cb93a386Sopenharmony_ci continue; 175cb93a386Sopenharmony_ci } 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci#ifdef SK_GL 178cb93a386Sopenharmony_ci gl = GrGLMakeNativeInterface(); 179cb93a386Sopenharmony_ci if (!gl) { 180cb93a386Sopenharmony_ci SkDebugf("Failed to create gl interface.\n"); 181cb93a386Sopenharmony_ci this->destroyGLContext(); 182cb93a386Sopenharmony_ci continue; 183cb93a386Sopenharmony_ci } 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ci if (!gl->validate()) { 186cb93a386Sopenharmony_ci SkDebugf("Failed to validate gl interface.\n"); 187cb93a386Sopenharmony_ci this->destroyGLContext(); 188cb93a386Sopenharmony_ci continue; 189cb93a386Sopenharmony_ci } 190cb93a386Sopenharmony_ci const char* extensions = eglQueryString(fDisplay, EGL_EXTENSIONS); 191cb93a386Sopenharmony_ci if (strstr(extensions, "EGL_KHR_image")) { 192cb93a386Sopenharmony_ci fEglCreateImageProc = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR"); 193cb93a386Sopenharmony_ci fEglDestroyImageProc = 194cb93a386Sopenharmony_ci (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR"); 195cb93a386Sopenharmony_ci } 196cb93a386Sopenharmony_ci 197cb93a386Sopenharmony_ci this->init(std::move(gl)); 198cb93a386Sopenharmony_ci#else 199cb93a386Sopenharmony_ci // Allow the GLTestContext creation to succeed without a GrGLInterface to support 200cb93a386Sopenharmony_ci // GrContextFactory's persistent GL context workaround for Vulkan. We won't need the 201cb93a386Sopenharmony_ci // GrGLInterface since we're not running the GL backend. 202cb93a386Sopenharmony_ci this->init(nullptr); 203cb93a386Sopenharmony_ci#endif 204cb93a386Sopenharmony_ci break; 205cb93a386Sopenharmony_ci } 206cb93a386Sopenharmony_ci} 207cb93a386Sopenharmony_ci 208cb93a386Sopenharmony_ciEGLGLTestContext::~EGLGLTestContext() { 209cb93a386Sopenharmony_ci this->teardown(); 210cb93a386Sopenharmony_ci this->destroyGLContext(); 211cb93a386Sopenharmony_ci} 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_civoid EGLGLTestContext::destroyGLContext() { 214cb93a386Sopenharmony_ci if (fDisplay) { 215cb93a386Sopenharmony_ci if (fContext) { 216cb93a386Sopenharmony_ci if (eglGetCurrentContext() == fContext) { 217cb93a386Sopenharmony_ci // This will ensure that the context is immediately deleted. 218cb93a386Sopenharmony_ci eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 219cb93a386Sopenharmony_ci } 220cb93a386Sopenharmony_ci eglDestroyContext(fDisplay, fContext); 221cb93a386Sopenharmony_ci fContext = EGL_NO_CONTEXT; 222cb93a386Sopenharmony_ci } 223cb93a386Sopenharmony_ci 224cb93a386Sopenharmony_ci if (fSurface) { 225cb93a386Sopenharmony_ci eglDestroySurface(fDisplay, fSurface); 226cb93a386Sopenharmony_ci fSurface = EGL_NO_SURFACE; 227cb93a386Sopenharmony_ci } 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_ci //TODO should we close the display? 230cb93a386Sopenharmony_ci fDisplay = EGL_NO_DISPLAY; 231cb93a386Sopenharmony_ci } 232cb93a386Sopenharmony_ci} 233cb93a386Sopenharmony_ci 234cb93a386Sopenharmony_ciGrEGLImage EGLGLTestContext::texture2DToEGLImage(GrGLuint texID) const { 235cb93a386Sopenharmony_ci#ifdef SK_GL 236cb93a386Sopenharmony_ci if (!this->gl()->hasExtension("EGL_KHR_gl_texture_2D_image") || !fEglCreateImageProc) { 237cb93a386Sopenharmony_ci return GR_EGL_NO_IMAGE; 238cb93a386Sopenharmony_ci } 239cb93a386Sopenharmony_ci EGLint attribs[] = { GR_EGL_GL_TEXTURE_LEVEL, 0, GR_EGL_NONE }; 240cb93a386Sopenharmony_ci GrEGLClientBuffer clientBuffer = reinterpret_cast<GrEGLClientBuffer>(texID); 241cb93a386Sopenharmony_ci return fEglCreateImageProc(fDisplay, fContext, GR_EGL_GL_TEXTURE_2D, clientBuffer, attribs); 242cb93a386Sopenharmony_ci#else 243cb93a386Sopenharmony_ci (void)fEglCreateImageProc; 244cb93a386Sopenharmony_ci return nullptr; 245cb93a386Sopenharmony_ci#endif 246cb93a386Sopenharmony_ci} 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_civoid EGLGLTestContext::destroyEGLImage(GrEGLImage image) const { 249cb93a386Sopenharmony_ci fEglDestroyImageProc(fDisplay, image); 250cb93a386Sopenharmony_ci} 251cb93a386Sopenharmony_ci 252cb93a386Sopenharmony_ciGrGLuint EGLGLTestContext::eglImageToExternalTexture(GrEGLImage image) const { 253cb93a386Sopenharmony_ci#ifdef SK_GL 254cb93a386Sopenharmony_ci while (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {} 255cb93a386Sopenharmony_ci if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) { 256cb93a386Sopenharmony_ci return 0; 257cb93a386Sopenharmony_ci } 258cb93a386Sopenharmony_ci typedef GrGLvoid (*EGLImageTargetTexture2DProc)(GrGLenum, GrGLeglImage); 259cb93a386Sopenharmony_ci 260cb93a386Sopenharmony_ci EGLImageTargetTexture2DProc glEGLImageTargetTexture2D = 261cb93a386Sopenharmony_ci (EGLImageTargetTexture2DProc) eglGetProcAddress("glEGLImageTargetTexture2DOES"); 262cb93a386Sopenharmony_ci if (!glEGLImageTargetTexture2D) { 263cb93a386Sopenharmony_ci return 0; 264cb93a386Sopenharmony_ci } 265cb93a386Sopenharmony_ci GrGLuint texID; 266cb93a386Sopenharmony_ci GR_GL_CALL(this->gl(), GenTextures(1, &texID)); 267cb93a386Sopenharmony_ci if (!texID) { 268cb93a386Sopenharmony_ci return 0; 269cb93a386Sopenharmony_ci } 270cb93a386Sopenharmony_ci GR_GL_CALL_NOERRCHECK(this->gl(), BindTexture(GR_GL_TEXTURE_EXTERNAL, texID)); 271cb93a386Sopenharmony_ci if (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) { 272cb93a386Sopenharmony_ci GR_GL_CALL(this->gl(), DeleteTextures(1, &texID)); 273cb93a386Sopenharmony_ci return 0; 274cb93a386Sopenharmony_ci } 275cb93a386Sopenharmony_ci glEGLImageTargetTexture2D(GR_GL_TEXTURE_EXTERNAL, image); 276cb93a386Sopenharmony_ci if (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) { 277cb93a386Sopenharmony_ci GR_GL_CALL(this->gl(), DeleteTextures(1, &texID)); 278cb93a386Sopenharmony_ci return 0; 279cb93a386Sopenharmony_ci } 280cb93a386Sopenharmony_ci return texID; 281cb93a386Sopenharmony_ci#else 282cb93a386Sopenharmony_ci return 0; 283cb93a386Sopenharmony_ci#endif 284cb93a386Sopenharmony_ci} 285cb93a386Sopenharmony_ci 286cb93a386Sopenharmony_cistd::unique_ptr<sk_gpu_test::GLTestContext> EGLGLTestContext::makeNew() const { 287cb93a386Sopenharmony_ci std::unique_ptr<sk_gpu_test::GLTestContext> ctx(new EGLGLTestContext(this->gl()->fStandard, 288cb93a386Sopenharmony_ci nullptr)); 289cb93a386Sopenharmony_ci if (ctx) { 290cb93a386Sopenharmony_ci ctx->makeCurrent(); 291cb93a386Sopenharmony_ci } 292cb93a386Sopenharmony_ci return ctx; 293cb93a386Sopenharmony_ci} 294cb93a386Sopenharmony_ci 295cb93a386Sopenharmony_civoid EGLGLTestContext::onPlatformMakeNotCurrent() const { 296cb93a386Sopenharmony_ci if (!eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT )) { 297cb93a386Sopenharmony_ci SkDebugf("Could not reset the context.\n"); 298cb93a386Sopenharmony_ci } 299cb93a386Sopenharmony_ci} 300cb93a386Sopenharmony_ci 301cb93a386Sopenharmony_civoid EGLGLTestContext::onPlatformMakeCurrent() const { 302cb93a386Sopenharmony_ci if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 303cb93a386Sopenharmony_ci SkDebugf("Could not set the context.\n"); 304cb93a386Sopenharmony_ci } 305cb93a386Sopenharmony_ci} 306cb93a386Sopenharmony_ci 307cb93a386Sopenharmony_cistd::function<void()> EGLGLTestContext::onPlatformGetAutoContextRestore() const { 308cb93a386Sopenharmony_ci if (eglGetCurrentContext() == fContext) { 309cb93a386Sopenharmony_ci return nullptr; 310cb93a386Sopenharmony_ci } 311cb93a386Sopenharmony_ci return context_restorer(); 312cb93a386Sopenharmony_ci} 313cb93a386Sopenharmony_ci 314cb93a386Sopenharmony_ciGrGLFuncPtr EGLGLTestContext::onPlatformGetProcAddress(const char* procName) const { 315cb93a386Sopenharmony_ci return eglGetProcAddress(procName); 316cb93a386Sopenharmony_ci} 317cb93a386Sopenharmony_ci 318cb93a386Sopenharmony_ci} // anonymous namespace 319cb93a386Sopenharmony_ci 320cb93a386Sopenharmony_cinamespace sk_gpu_test { 321cb93a386Sopenharmony_ciGLTestContext *CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, 322cb93a386Sopenharmony_ci GLTestContext *shareContext) { 323cb93a386Sopenharmony_ci EGLGLTestContext* eglShareContext = reinterpret_cast<EGLGLTestContext*>(shareContext); 324cb93a386Sopenharmony_ci EGLGLTestContext *ctx = new EGLGLTestContext(forcedGpuAPI, eglShareContext); 325cb93a386Sopenharmony_ci if (!ctx->isValid()) { 326cb93a386Sopenharmony_ci delete ctx; 327cb93a386Sopenharmony_ci return nullptr; 328cb93a386Sopenharmony_ci } 329cb93a386Sopenharmony_ci return ctx; 330cb93a386Sopenharmony_ci} 331cb93a386Sopenharmony_ci} // namespace sk_gpu_test 332