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 "include/core/SkRefCnt.h" 13 #include "include/gpu/GrTypes.h" 14 #include "include/private/SkNoncopyable.h" 15 #include "include/private/SkTemplates.h" 16 #include "src/core/SkScopeExit.h" 17 #include "tools/gpu/FenceSync.h" 18 19 class GrDirectContext; 20 struct GrContextOptions; 21 22 namespace sk_gpu_test { 23 24 class GpuTimer; 25 class FlushFinishTracker; 26 27 /** 28 * An offscreen 3D context. This class is intended for Skia's internal testing needs and not 29 * for general use. 30 */ 31 class TestContext : public SkNoncopyable { 32 public: 33 virtual ~TestContext(); 34 fenceSyncSupport()35 bool fenceSyncSupport() const { return fFenceSupport; } 36 gpuTimingSupport()37 bool gpuTimingSupport() const { return fGpuTimer != nullptr; } gpuTimer()38 GpuTimer* gpuTimer() const { SkASSERT(fGpuTimer); return fGpuTimer.get(); } 39 getMaxGpuFrameLag(int * maxFrameLag)40 bool getMaxGpuFrameLag(int *maxFrameLag) const { 41 if (!this->fenceSyncSupport()) { 42 return false; 43 } 44 *maxFrameLag = kMaxFrameLag; 45 return true; 46 } 47 48 void makeNotCurrent() const; 49 void makeCurrent() const; 50 51 /** 52 * Like makeCurrent() but this returns an object that will restore the previous current 53 * context in its destructor. Useful to undo the effect making this current before returning to 54 * a caller that doesn't expect the current context to be changed underneath it. 55 * 56 * The returned object restores the current context of the same type (e.g. egl, glx, ...) in its 57 * destructor. It is undefined behavior if that context is destroyed before the destructor 58 * executes. If the concept of a current context doesn't make sense for this context type then 59 * the returned object's destructor is a no-op. 60 */ 61 SkScopeExit SK_WARN_UNUSED_RESULT makeCurrentAndAutoRestore() const; 62 63 virtual GrBackendApi backend() = 0; 64 65 virtual sk_sp<GrDirectContext> makeContext(const GrContextOptions&); 66 67 /** 68 * This will flush work to the GPU. Additionally, if the platform supports fence syncs, we will 69 * add a finished callback to our flush call. We allow ourselves to have kMaxFrameLag number of 70 * unfinished flushes active on the GPU at a time. If we have 2 outstanding flushes then we will 71 * wait on the CPU until one has finished. 72 */ 73 void flushAndWaitOnSync(GrDirectContext* context); 74 75 /** 76 * This notifies the context that we are deliberately testing abandoning 77 * the context. It is useful for debugging contexts that would otherwise 78 * test that GPU resources are properly deleted. It also allows a debugging 79 * context to test that further API calls are not made by Skia GPU code. 80 */ 81 virtual void testAbandon(); 82 83 /** Wait until all GPU work is finished. */ 84 virtual void finish() = 0; 85 86 protected: 87 bool fFenceSupport = false; 88 89 std::unique_ptr<GpuTimer> fGpuTimer; 90 91 TestContext(); 92 93 /** This should destroy the 3D context. */ 94 virtual void teardown(); 95 96 virtual void onPlatformMakeNotCurrent() const = 0; 97 virtual void onPlatformMakeCurrent() const = 0; 98 /** 99 * Subclasses should implement such that the returned function will cause the current context 100 * of this type to be made current again when it is called. It should additionally be the 101 * case that if "this" is already current when this is called, then "this" is destroyed (thereby 102 * setting the null context as current), and then the std::function is called the null context 103 * should remain current. 104 */ 105 virtual std::function<void()> onPlatformGetAutoContextRestore() const = 0; 106 107 private: 108 enum { 109 kMaxFrameLag = 3 110 }; 111 112 sk_sp<FlushFinishTracker> fFinishTrackers[kMaxFrameLag - 1]; 113 int fCurrentFlushIdx = 0; 114 115 using INHERITED = SkNoncopyable; 116 }; 117 } // namespace sk_gpu_test 118 #endif 119