1
2/*
3 * Copyright 2013 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#ifndef GLTestContext_DEFINED
9#define GLTestContext_DEFINED
10
11#include "TestContext.h"
12#include "gl/GrGLInterface.h"
13
14namespace sk_gpu_test {
15/**
16 * An offscreen OpenGL context. Provides a GrGLInterface struct of function pointers for the context
17 * This class is intended for Skia's internal testing needs and not for general use.
18 */
19class GLTestContext : public TestContext {
20public:
21    ~GLTestContext() override;
22
23    virtual GrBackend backend() override { return kOpenGL_GrBackend; }
24    virtual GrBackendContext backendContext() override {
25        return reinterpret_cast<GrBackendContext>(fGL.get());
26    }
27
28    bool isValid() const { return SkToBool(this->gl()); }
29
30    const GrGLInterface* gl() const { return fGL.get(); }
31
32    /** Used for testing EGLImage integration. Take a GL_TEXTURE_2D and wraps it in an EGL Image */
33    virtual GrEGLImage texture2DToEGLImage(GrGLuint /*texID*/) const { return nullptr; }
34
35    virtual void destroyEGLImage(GrEGLImage) const { }
36
37    /** Used for testing GL_TEXTURE_RECTANGLE integration. */
38    GrGLint createTextureRectangle(int width, int height, GrGLenum internalFormat,
39                                   GrGLenum externalFormat, GrGLenum externalType,
40                                   GrGLvoid *data);
41
42    /**
43     * Used for testing EGLImage integration. Takes a EGLImage and wraps it in a
44     * GL_TEXTURE_EXTERNAL_OES.
45     */
46    virtual GrGLuint eglImageToExternalTexture(GrEGLImage) const { return 0; }
47
48    void testAbandon() override;
49
50    /** Ensures all work is submitted to the GPU for execution. */
51    void submit() override;
52
53    /** Wait until all GPU work is finished. */
54    void finish() override;
55
56    /**
57     * Creates a new GL context of the same type and makes the returned context current
58     * (if not null).
59     */
60    virtual std::unique_ptr<GLTestContext> makeNew() const { return nullptr; }
61
62    template<typename Ret, typename... Args>
63    void getGLProcAddress(Ret(GR_GL_FUNCTION_TYPE** out)(Args...),
64                          const char* name, const char* ext = nullptr) const {
65        using Proc = Ret(GR_GL_FUNCTION_TYPE*)(Args...);
66        if (!SkStrStartsWith(name, "gl")) {
67            SK_ABORT("getGLProcAddress: proc name must have 'gl' prefix");
68            *out = nullptr;
69        } else if (ext) {
70            SkString fullname(name);
71            fullname.append(ext);
72            *out = reinterpret_cast<Proc>(this->onPlatformGetProcAddress(fullname.c_str()));
73        } else {
74            *out = reinterpret_cast<Proc>(this->onPlatformGetProcAddress(name));
75        }
76    }
77
78    sk_sp<GrContext> makeGrContext(const GrContextOptions& options) override;
79
80protected:
81    GLTestContext();
82
83    /*
84     * Methods that sublcasses must call from their constructors and destructors.
85     */
86    void init(sk_sp<const GrGLInterface>, std::unique_ptr<FenceSync> = nullptr);
87
88    void teardown() override;
89
90    virtual GrGLFuncPtr onPlatformGetProcAddress(const char *) const = 0;
91
92private:
93    /** Subclass provides the gl interface object if construction was
94     *  successful. */
95    sk_sp<const GrGLInterface> fGL;
96
97    typedef TestContext INHERITED;
98};
99
100/**
101 * Creates platform-dependent GL context object.  The shareContext parameter is in an optional
102 * context with which to share display lists. This should be a pointer to an GLTestContext created
103 * with SkCreatePlatformGLTestContext.  NULL indicates that no sharing is to take place. Returns a
104 * valid gl context object or NULL if such can not be created.
105 */
106GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
107                                           GLTestContext *shareContext = nullptr);
108
109}  // namespace sk_gpu_test
110#endif
111