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