13724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
2d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com/*
3d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com * Copyright 2012 Google Inc.
4d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com *
5d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
6d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com * found in the LICENSE file.
7d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com */
8d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
9273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon#include "GLTestContext_angle.h"
10d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
11c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein#include <EGL/egl.h>
12c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein#include <EGL/eglext.h>
13c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
147ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon#include "gl/GrGLDefines.h"
157ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon#include "gl/GrGLUtil.h"
167ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
173724e574a744491b7cfb8187ac865a70ef3d4528bsalomon#include "gl/GrGLInterface.h"
183724e574a744491b7cfb8187ac865a70ef3d4528bsalomon#include "gl/GrGLAssembleInterface.h"
193724e574a744491b7cfb8187ac865a70ef3d4528bsalomon#include "../ports/SkOSLibrary.h"
203724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
21c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein#include <EGL/egl.h>
223724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
2310b371c6e376f1f3eba88ac4bfdf34652f3ab1dchendrikw#define EGL_PLATFORM_ANGLE_ANGLE                0x3202
2410b371c6e376f1f3eba88ac4bfdf34652f3ab1dchendrikw#define EGL_PLATFORM_ANGLE_TYPE_ANGLE           0x3203
2510b371c6e376f1f3eba88ac4bfdf34652f3ab1dchendrikw#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE      0x3207
2610b371c6e376f1f3eba88ac4bfdf34652f3ab1dchendrikw#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE     0x3208
27eddbefb4a5794b1d9f4e58a7cdf4e768b837c17fhendrikw#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE    0x320D
2842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
2911abd8d6cb2887bf66711863fb2dfe47da86d979bsalomonusing sk_gpu_test::ANGLEBackend;
3011abd8d6cb2887bf66711863fb2dfe47da86d979bsalomonusing sk_gpu_test::ANGLEContextVersion;
3111abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon
323724e574a744491b7cfb8187ac865a70ef3d4528bsalomonnamespace {
33c168a3ac3cb96555011c73938f71f8183990ab46Mike Kleinstruct Libs {
34c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    void* fGLLib;
35c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    void* fEGLLib;
36238b820369c4b556c2e7c8277855e6950de3d9ebBrian Salomon};
37238b820369c4b556c2e7c8277855e6950de3d9ebBrian Salomon
38238b820369c4b556c2e7c8277855e6950de3d9ebBrian Salomonstatic GrGLFuncPtr angle_get_gl_proc(void* ctx, const char name[]) {
39c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    const Libs* libs = reinterpret_cast<const Libs*>(ctx);
40c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    GrGLFuncPtr proc = (GrGLFuncPtr) GetProcedureAddress(libs->fGLLib, name);
41c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    if (proc) {
42c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        return proc;
43238b820369c4b556c2e7c8277855e6950de3d9ebBrian Salomon    }
44c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    proc = (GrGLFuncPtr) GetProcedureAddress(libs->fEGLLib, name);
45c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    if (proc) {
46c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        return proc;
47238b820369c4b556c2e7c8277855e6950de3d9ebBrian Salomon    }
48c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    return eglGetProcAddress(name);
49c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein}
50238b820369c4b556c2e7c8277855e6950de3d9ebBrian Salomon
51c168a3ac3cb96555011c73938f71f8183990ab46Mike Kleinvoid* get_angle_egl_display(void* nativeDisplay, ANGLEBackend type) {
52c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
53c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    eglGetPlatformDisplayEXT =
54c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
55c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
56c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    // We expect ANGLE to support this extension
57c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    if (!eglGetPlatformDisplayEXT) {
58c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        return EGL_NO_DISPLAY;
59c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    }
60c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
61c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    EGLint typeNum = 0;
62c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    switch (type) {
63c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        case ANGLEBackend::kD3D9:
64c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein            typeNum = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
65c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein            break;
66c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        case ANGLEBackend::kD3D11:
67c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein            typeNum = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
68c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein            break;
69c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        case ANGLEBackend::kOpenGL:
70c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein            typeNum = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
71c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein            break;
72c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    }
73c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    const EGLint attribs[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, typeNum, EGL_NONE };
74c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, attribs);
75c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein}
76238b820369c4b556c2e7c8277855e6950de3d9ebBrian Salomon
77273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonclass ANGLEGLContext : public sk_gpu_test::GLTestContext {
783724e574a744491b7cfb8187ac865a70ef3d4528bsalomonpublic:
7960c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    ANGLEGLContext(ANGLEBackend, ANGLEContextVersion, ANGLEGLContext* shareContext);
803724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    ~ANGLEGLContext() override;
813724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
823724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrEGLImage texture2DToEGLImage(GrGLuint texID) const override;
833724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    void destroyEGLImage(GrEGLImage) const override;
843724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLuint eglImageToExternalTexture(GrEGLImage) const override;
85145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner    std::unique_ptr<sk_gpu_test::GLTestContext> makeNew() const override;
863724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
873724e574a744491b7cfb8187ac865a70ef3d4528bsalomonprivate:
883724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    void destroyGLContext();
893724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
903724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    void onPlatformMakeCurrent() const override;
913724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    void onPlatformSwapBuffers() const override;
923724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
933724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
94c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    void*                       fContext;
95c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    void*                       fDisplay;
96c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    void*                       fSurface;
9711abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon    ANGLEBackend                fType;
9811abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon    ANGLEContextVersion         fVersion;
993724e574a744491b7cfb8187ac865a70ef3d4528bsalomon};
1003724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
10160c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian OsmanANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
10260c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman                               ANGLEGLContext* shareContext)
103c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    : fContext(EGL_NO_CONTEXT)
104c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    , fDisplay(EGL_NO_DISPLAY)
10511abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon    , fSurface(EGL_NO_SURFACE)
10611abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon    , fType(type)
10711abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon    , fVersion(version) {
108d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
109d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    EGLint numConfigs;
110d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    static const EGLint configAttribs[] = {
111d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
112d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
113d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_RED_SIZE, 8,
114d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_GREEN_SIZE, 8,
115d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_BLUE_SIZE, 8,
116d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_ALPHA_SIZE, 8,
117d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_NONE
118d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    };
119d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
120c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    fDisplay = get_angle_egl_display(EGL_DEFAULT_DISPLAY, type);
121c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    if (EGL_NO_DISPLAY == fDisplay) {
122c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        SkDebugf("Could not create EGL display!");
12342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        return;
12442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    }
12542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
126c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    EGLint majorVersion;
127c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    EGLint minorVersion;
128c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    eglInitialize(fDisplay, &majorVersion, &minorVersion);
129c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
130c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    EGLConfig surfaceConfig;
131c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs);
132c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
13311abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon    int versionNum = ANGLEContextVersion::kES2 == version ? 2 : 3;
13411abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon    const EGLint contextAttribs[] = {
13511abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon        EGL_CONTEXT_CLIENT_VERSION, versionNum,
136d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_NONE
137d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    };
13860c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    EGLContext eglShareContext = shareContext ? shareContext->fContext : nullptr;
13960c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    fContext = eglCreateContext(fDisplay, surfaceConfig, eglShareContext, contextAttribs);
140d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
141d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
142d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    static const EGLint surfaceAttribs[] = {
14342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        EGL_WIDTH, 1,
14442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        EGL_HEIGHT, 1,
14542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        EGL_NONE
14642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    };
14742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
148c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs);
149d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
150c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    eglMakeCurrent(fDisplay, fSurface, fSurface, fContext);
151d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
152c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    sk_sp<const GrGLInterface> gl(sk_gpu_test::CreateANGLEGLInterface());
15396fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == gl.get()) {
154d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        SkDebugf("Could not create ANGLE GL interface!\n");
155d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        this->destroyGLContext();
15630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        return;
15730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    }
158d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    if (!gl->validate()) {
15930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        SkDebugf("Could not validate ANGLE GL interface!\n");
16030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        this->destroyGLContext();
16130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        return;
162d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    }
163d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton
16418300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein    this->init(gl.release());
16530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen}
166d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
1673724e574a744491b7cfb8187ac865a70ef3d4528bsalomonANGLEGLContext::~ANGLEGLContext() {
168d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    this->teardown();
16930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    this->destroyGLContext();
17030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen}
17130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
1723724e574a744491b7cfb8187ac865a70ef3d4528bsalomonGrEGLImage ANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const {
1737ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (!this->gl()->hasExtension("EGL_KHR_gl_texture_2D_image")) {
1747ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return GR_EGL_NO_IMAGE;
1757ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
1767ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GrEGLImage img;
1777ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GrEGLint attribs[] = { GR_EGL_GL_TEXTURE_LEVEL, 0,
1787ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon                           GR_EGL_IMAGE_PRESERVED, GR_EGL_TRUE,
1797ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon                           GR_EGL_NONE };
1807ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    // 64 bit cast is to shut Visual C++ up about casting 32 bit value to a pointer.
1817ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GrEGLClientBuffer clientBuffer = reinterpret_cast<GrEGLClientBuffer>((uint64_t)texID);
1827ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GR_GL_CALL_RET(this->gl(), img,
183c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein                   EGLCreateImage(fDisplay, fContext, GR_EGL_GL_TEXTURE_2D, clientBuffer,
1847ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon                                  attribs));
1857ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    return img;
1867ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon}
1877ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
1883724e574a744491b7cfb8187ac865a70ef3d4528bsalomonvoid ANGLEGLContext::destroyEGLImage(GrEGLImage image) const {
189c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    GR_GL_CALL(this->gl(), EGLDestroyImage(fDisplay, image));
1907ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon}
1917ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
1923724e574a744491b7cfb8187ac865a70ef3d4528bsalomonGrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const {
1937ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GrGLClearErr(this->gl());
1947ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) {
1957ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return 0;
1967ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
197c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    typedef GrGLvoid (EGLAPIENTRY *EGLImageTargetTexture2DProc)(GrGLenum, GrGLeglImage);
198c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    EGLImageTargetTexture2DProc glEGLImageTargetTexture2D =
199c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        (EGLImageTargetTexture2DProc)eglGetProcAddress("glEGLImageTargetTexture2DOES");
2007ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (!glEGLImageTargetTexture2D) {
2017ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return 0;
2027ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
2037ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GrGLuint texID;
2047ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GR_GL_CALL(this->gl(), GenTextures(1, &texID));
2057ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (!texID) {
2067ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return 0;
2077ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
2087ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    GR_GL_CALL(this->gl(), BindTexture(GR_GL_TEXTURE_EXTERNAL, texID));
2097ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
2107ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
2117ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return 0;
2127ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
2137ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    glEGLImageTargetTexture2D(GR_GL_TEXTURE_EXTERNAL, image);
2147ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
2157ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
2167ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return 0;
2177ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
2187ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    return texID;
2197ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon}
2207ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
221145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagnerstd::unique_ptr<sk_gpu_test::GLTestContext> ANGLEGLContext::makeNew() const {
222145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner    std::unique_ptr<sk_gpu_test::GLTestContext> ctx =
223145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner        sk_gpu_test::MakeANGLETestContext(fType, fVersion);
2247ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    if (ctx) {
2257ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        ctx->makeCurrent();
2267ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
2277ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    return ctx;
2287ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon}
2297ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
2303724e574a744491b7cfb8187ac865a70ef3d4528bsalomonvoid ANGLEGLContext::destroyGLContext() {
23130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    if (fDisplay) {
232c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        eglMakeCurrent(fDisplay, 0, 0, 0);
23330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
23430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        if (fContext) {
235c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein            eglDestroyContext(fDisplay, fContext);
23630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen            fContext = EGL_NO_CONTEXT;
23730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        }
23830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
23930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        if (fSurface) {
240c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein            eglDestroySurface(fDisplay, fSurface);
24130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen            fSurface = EGL_NO_SURFACE;
24230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        }
243c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
244c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        //TODO should we close the display?
245c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        fDisplay = EGL_NO_DISPLAY;
24630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    }
247d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com}
248d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
2493724e574a744491b7cfb8187ac865a70ef3d4528bsalomonvoid ANGLEGLContext::onPlatformMakeCurrent() const {
250c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
251d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        SkDebugf("Could not set the context.\n");
252d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    }
253d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com}
254c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com
2553724e574a744491b7cfb8187ac865a70ef3d4528bsalomonvoid ANGLEGLContext::onPlatformSwapBuffers() const {
256c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    if (!eglSwapBuffers(fDisplay, fSurface)) {
257c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com        SkDebugf("Could not complete eglSwapBuffers.\n");
258c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com    }
259c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com}
260d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton
2613724e574a744491b7cfb8187ac865a70ef3d4528bsalomonGrGLFuncPtr ANGLEGLContext::onPlatformGetProcAddress(const char* name) const {
262c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    return eglGetProcAddress(name);
263d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton}
2643724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}  // anonymous namespace
2653724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
2663724e574a744491b7cfb8187ac865a70ef3d4528bsalomonnamespace sk_gpu_test {
2673724e574a744491b7cfb8187ac865a70ef3d4528bsalomonconst GrGLInterface* CreateANGLEGLInterface() {
268c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    static Libs gLibs = { nullptr, nullptr };
269c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
270c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    if (nullptr == gLibs.fGLLib) {
271c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        // We load the ANGLE library and never let it go
272c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein#if defined _WIN32
273c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.dll");
274c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        gLibs.fEGLLib = DynamicLoadLibrary("libEGL.dll");
275c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein#elif defined SK_BUILD_FOR_MAC
276c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.dylib");
277c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        gLibs.fEGLLib = DynamicLoadLibrary("libEGL.dylib");
278c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein#else
279c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        gLibs.fGLLib = DynamicLoadLibrary("libGLESv2.so");
280c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        gLibs.fEGLLib = DynamicLoadLibrary("libEGL.so");
281c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein#endif
282c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    }
283c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
284c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    if (nullptr == gLibs.fGLLib || nullptr == gLibs.fEGLLib) {
285c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein        // We can't setup the interface correctly w/o the so
2863724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        return nullptr;
2873724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
288c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein
289c168a3ac3cb96555011c73938f71f8183990ab46Mike Klein    return GrGLAssembleGLESInterface(&gLibs, angle_get_gl_proc);
2903724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}
2913724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
29260c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osmanstd::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend type, ANGLEContextVersion version,
29360c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman                                                    GLTestContext* shareContext){
29460c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    ANGLEGLContext* angleShareContext = reinterpret_cast<ANGLEGLContext*>(shareContext);
29560c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    std::unique_ptr<GLTestContext> ctx(new ANGLEGLContext(type, version, angleShareContext));
2963724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    if (!ctx->isValid()) {
297145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner        return nullptr;
2983724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
2993724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    return ctx;
3003724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}
3013724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}  // namespace sk_gpu_test
302