1 /* 2 * Copyright 2023 Google LLC 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 GrDeferredDisplayList_DEFINED 9 #define GrDeferredDisplayList_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/core/SkTypes.h" 13 #include "include/gpu/ganesh/GrRecordingContext.h" 14 #include "include/private/base/SkTArray.h" 15 #include "include/private/chromium/GrSurfaceCharacterization.h" 16 17 class GrDirectContext; 18 class GrRenderTargetProxy; 19 class GrRenderTask; 20 class GrDeferredDisplayListPriv; 21 class SkSurface; 22 23 /* 24 * This class contains pre-processed gpu operations that can be replayed into 25 * an SkSurface via SkSurface::draw(GrDeferredDisplayList*). 26 */ 27 class GrDeferredDisplayList : public SkNVRefCnt<GrDeferredDisplayList> { 28 public: 29 SK_API ~GrDeferredDisplayList(); 30 characterization()31 SK_API const GrSurfaceCharacterization& characterization() const { 32 return fCharacterization; 33 } 34 /** 35 * Iterate through the programs required by the DDL. 36 */ 37 class SK_API ProgramIterator { 38 public: 39 ProgramIterator(GrDirectContext*, GrDeferredDisplayList*); 40 ~ProgramIterator(); 41 42 // This returns true if any work was done. Getting a cache hit does not count as work. 43 bool compile(); 44 bool done() const; 45 void next(); 46 47 private: 48 GrDirectContext* fDContext; 49 const skia_private::TArray<GrRecordingContext::ProgramData>& fProgramData; 50 int fIndex; 51 }; 52 53 // Provides access to functions that aren't part of the public API. 54 GrDeferredDisplayListPriv priv(); 55 const GrDeferredDisplayListPriv priv() const; // NOLINT(readability-const-return-type) 56 57 private: 58 friend class GrDrawingManager; // for access to 'fRenderTasks', 'fLazyProxyData', 'fArenas' 59 friend class GrDeferredDisplayListRecorder; // for access to 'fLazyProxyData' 60 friend class GrDeferredDisplayListPriv; 61 62 // This object is the source from which the lazy proxy backing the DDL will pull its backing 63 // texture when the DDL is replayed. It has to be separately ref counted bc the lazy proxy 64 // can outlive the DDL. 65 class LazyProxyData : public SkRefCnt { 66 public: 67 // Upon being replayed - this field will be filled in (by the DrawingManager) with the 68 // proxy backing the destination SkSurface. Note that, since there is no good place to 69 // clear it, it can become a dangling pointer. Additionally, since the renderTargetProxy 70 // doesn't get a ref here, the SkSurface that owns it must remain alive until the DDL 71 // is flushed. 72 // TODO: the drawing manager could ref the renderTargetProxy for the DDL and then add 73 // a renderingTask to unref it after the DDL's ops have been executed. 74 GrRenderTargetProxy* fReplayDest = nullptr; 75 }; 76 77 SK_API GrDeferredDisplayList(const GrSurfaceCharacterization& characterization, 78 sk_sp<GrRenderTargetProxy> fTargetProxy, 79 sk_sp<LazyProxyData>); 80 programData()81 const skia_private::TArray<GrRecordingContext::ProgramData>& programData() const { 82 return fProgramData; 83 } 84 85 const GrSurfaceCharacterization fCharacterization; 86 87 // These are ordered such that the destructor cleans op tasks up first (which may refer back 88 // to the arena and memory pool in their destructors). 89 GrRecordingContext::OwnedArenas fArenas; 90 skia_private::TArray<sk_sp<GrRenderTask>> fRenderTasks; 91 92 skia_private::TArray<GrRecordingContext::ProgramData> fProgramData; 93 sk_sp<GrRenderTargetProxy> fTargetProxy; 94 sk_sp<LazyProxyData> fLazyProxyData; 95 }; 96 97 namespace skgpu::ganesh { 98 /** Draws the deferred display list created via a GrDeferredDisplayListRecorder. 99 If the deferred display list is not compatible with the surface, the draw is skipped 100 and false is return. 101 102 The xOffset and yOffset parameters are experimental and, if not both zero, will cause 103 the draw to be ignored. 104 When implemented, if xOffset or yOffset are non-zero, the DDL will be drawn offset by that 105 amount into the surface. 106 107 @param SkSurface The surface to apply the commands to, cannot be nullptr. 108 @param ddl drawing commands, cannot be nullptr. 109 @return false if ddl is not compatible 110 111 example: https://fiddle.skia.org/c/@Surface_draw_2 112 */ 113 SK_API bool DrawDDL(SkSurface*, 114 sk_sp<const GrDeferredDisplayList> ddl); 115 116 SK_API bool DrawDDL(sk_sp<SkSurface>, 117 sk_sp<const GrDeferredDisplayList> ddl); 118 } 119 120 #endif 121