1
2/*
3 * Copyright 2016 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
9#ifndef TestContext_DEFINED
10#define TestContext_DEFINED
11
12#include "FenceSync.h"
13#include "GrTypes.h"
14#include "../private/SkTemplates.h"
15
16namespace sk_gpu_test {
17
18class GpuTimer;
19
20/**
21 * An offscreen 3D context. This class is intended for Skia's internal testing needs and not
22 * for general use.
23 */
24class TestContext : public SkNoncopyable {
25public:
26    virtual ~TestContext();
27
28    virtual bool isValid() const = 0;
29
30    bool fenceSyncSupport() const { return fFenceSync != nullptr; }
31    FenceSync* fenceSync() { SkASSERT(fFenceSync); return fFenceSync.get(); }
32
33    bool gpuTimingSupport() const { return fGpuTimer != nullptr; }
34    GpuTimer* gpuTimer() const { SkASSERT(fGpuTimer); return fGpuTimer.get(); }
35
36    bool getMaxGpuFrameLag(int *maxFrameLag) const {
37        if (!fFenceSync) {
38            return false;
39        }
40        *maxFrameLag = kMaxFrameLag;
41        return true;
42    }
43
44    void makeCurrent() const;
45
46    virtual GrBackend backend() = 0;
47    virtual GrBackendContext backendContext() = 0;
48
49    /** Swaps front and back buffer (if the context has such buffers) */
50    void swapBuffers();
51
52    /**
53     * The only purpose of this function it to provide a means of scheduling
54     * work on the GPU (since all of the subclasses create primary buffers for
55     * testing that are small and not meant to be rendered to the screen).
56     *
57     * If the platform supports fence syncs (OpenGL 3.2+ or EGL_KHR_fence_sync),
58     * this will not swap any buffers, but rather emulate triple buffer synchronization
59     * using fences.
60     *
61     * Otherwise it will call the platform SwapBuffers method. This may or may
62     * not perform some sort of synchronization, depending on whether the
63     * drawing surface provided by the platform is double buffered.
64     *
65     * Implicitly performs a submit().
66     */
67    void waitOnSyncOrSwap();
68
69    /**
70     * This notifies the context that we are deliberately testing abandoning
71     * the context. It is useful for debugging contexts that would otherwise
72     * test that GPU resources are properly deleted. It also allows a debugging
73     * context to test that further API calls are not made by Skia GPU code.
74     */
75    virtual void testAbandon();
76
77    /** Ensures all work is submitted to the GPU for execution. */
78    virtual void submit() = 0;
79
80    /** Wait until all GPU work is finished. */
81    virtual void finish() = 0;
82
83protected:
84    std::unique_ptr<FenceSync> fFenceSync;
85    std::unique_ptr<GpuTimer>  fGpuTimer;
86
87    TestContext();
88
89    /** This should destroy the 3D context. */
90    virtual void teardown();
91
92    virtual void onPlatformMakeCurrent() const = 0;
93    virtual void onPlatformSwapBuffers() const = 0;
94
95private:
96    enum {
97        kMaxFrameLag = 3
98    };
99
100    PlatformFence fFrameFences[kMaxFrameLag - 1];
101    int fCurrentFenceIdx;
102
103    typedef SkNoncopyable INHERITED;
104};
105}  // namespace sk_gpu_test
106#endif
107