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