1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkDeferredDisplayList_DEFINED 9 #define SkDeferredDisplayList_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/core/SkSurfaceCharacterization.h" 13 #include "include/core/SkTypes.h" 14 15 class SkDeferredDisplayListPriv; 16 17 #if SK_SUPPORT_GPU 18 #include "include/gpu/GrRecordingContext.h" 19 #include "include/private/SkTArray.h" 20 #include <map> 21 class GrRenderTask; 22 class GrRenderTargetProxy; 23 #else 24 using GrRenderTargetProxy = SkRefCnt; 25 #endif 26 27 /* 28 * This class contains pre-processed gpu operations that can be replayed into 29 * an SkSurface via SkSurface::draw(SkDeferredDisplayList*). 30 */ 31 class SkDeferredDisplayList : public SkNVRefCnt<SkDeferredDisplayList> { 32 public: 33 SK_API ~SkDeferredDisplayList(); 34 characterization()35 SK_API const SkSurfaceCharacterization& characterization() const { 36 return fCharacterization; 37 } 38 39 #if SK_SUPPORT_GPU 40 /** 41 * Iterate through the programs required by the DDL. 42 */ 43 class SK_API ProgramIterator { 44 public: 45 ProgramIterator(GrDirectContext*, SkDeferredDisplayList*); 46 ~ProgramIterator(); 47 48 // This returns true if any work was done. Getting a cache hit does not count as work. 49 bool compile(); 50 bool done() const; 51 void next(); 52 53 private: 54 GrDirectContext* fDContext; 55 const SkTArray<GrRecordingContext::ProgramData>& fProgramData; 56 int fIndex; 57 }; 58 #endif 59 60 // Provides access to functions that aren't part of the public API. 61 SkDeferredDisplayListPriv priv(); 62 const SkDeferredDisplayListPriv priv() const; // NOLINT(readability-const-return-type) 63 64 private: 65 friend class GrDrawingManager; // for access to 'fRenderTasks', 'fLazyProxyData', 'fArenas' 66 friend class SkDeferredDisplayListRecorder; // for access to 'fLazyProxyData' 67 friend class SkDeferredDisplayListPriv; 68 69 // This object is the source from which the lazy proxy backing the DDL will pull its backing 70 // texture when the DDL is replayed. It has to be separately ref counted bc the lazy proxy 71 // can outlive the DDL. 72 class LazyProxyData : public SkRefCnt { 73 #if SK_SUPPORT_GPU 74 public: 75 // Upon being replayed - this field will be filled in (by the DrawingManager) with the 76 // proxy backing the destination SkSurface. Note that, since there is no good place to 77 // clear it, it can become a dangling pointer. Additionally, since the renderTargetProxy 78 // doesn't get a ref here, the SkSurface that owns it must remain alive until the DDL 79 // is flushed. 80 // TODO: the drawing manager could ref the renderTargetProxy for the DDL and then add 81 // a renderingTask to unref it after the DDL's ops have been executed. 82 GrRenderTargetProxy* fReplayDest = nullptr; 83 #endif 84 }; 85 86 SK_API SkDeferredDisplayList(const SkSurfaceCharacterization& characterization, 87 sk_sp<GrRenderTargetProxy> fTargetProxy, 88 sk_sp<LazyProxyData>); 89 90 #if SK_SUPPORT_GPU programData()91 const SkTArray<GrRecordingContext::ProgramData>& programData() const { 92 return fProgramData; 93 } 94 #endif 95 96 const SkSurfaceCharacterization fCharacterization; 97 98 #if SK_SUPPORT_GPU 99 // These are ordered such that the destructor cleans op tasks up first (which may refer back 100 // to the arena and memory pool in their destructors). 101 GrRecordingContext::OwnedArenas fArenas; 102 SkTArray<sk_sp<GrRenderTask>> fRenderTasks; 103 104 SkTArray<GrRecordingContext::ProgramData> fProgramData; 105 sk_sp<GrRenderTargetProxy> fTargetProxy; 106 sk_sp<LazyProxyData> fLazyProxyData; 107 #endif 108 }; 109 110 #endif 111