Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GrRenderTargetProxy.h
Go to the documentation of this file.
1/*
2 * Copyright 2016 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 GrRenderTargetProxy_DEFINED
9#define GrRenderTargetProxy_DEFINED
10
11#include "include/core/SkRect.h"
20
21#include <cstddef>
22#include <cstdint>
23#include <string_view>
24
25class GrBackendFormat;
26class GrCaps;
28class GrSurface;
29enum class SkBackingFit;
30struct SkISize;
31namespace skgpu {
32enum class Budgeted : bool;
33enum class Protected : bool;
34}
35
36// GrArenas matches the lifetime of a single frame. It is created and held on the
37// SurfaceFillContext's RenderTargetProxy with the first call to get an arena. Each OpsTask
38// takes a ref on it to keep the arenas alive. When the first OpsTask's onExecute() is
39// completed, the arena ref on the SurfaceFillContext's RenderTargetProxy is nulled out so that
40// any new OpsTasks will create and ref a new set of arenas.
41class GrArenas : public SkNVRefCnt<GrArenas> {
42public:
44 SkDEBUGCODE(if (fIsFlushed) SK_ABORT("Using a flushed arena");)
45 return &fArenaAlloc;
46 }
47 void flush() {
48 SkDEBUGCODE(fIsFlushed = true;)
49 }
50 sktext::gpu::SubRunAllocator* subRunAlloc() { return &fSubRunAllocator; }
51
52private:
53 SkArenaAlloc fArenaAlloc{1024};
54 // An allocator specifically designed to minimize the overhead of sub runs. It provides a
55 // different dtor semantics than SkArenaAlloc.
56 sktext::gpu::SubRunAllocator fSubRunAllocator{1024};
57 SkDEBUGCODE(bool fIsFlushed = false;)
58};
59
60// This class delays the acquisition of RenderTargets until they are actually
61// required
62// Beware: the uniqueID of the RenderTargetProxy will usually be different than
63// the uniqueID of the RenderTarget it represents!
64class GrRenderTargetProxy : virtual public GrSurfaceProxy {
65public:
66 GrRenderTargetProxy* asRenderTargetProxy() override { return this; }
67 const GrRenderTargetProxy* asRenderTargetProxy() const override { return this; }
68
69 // Actually instantiate the backing rendertarget, if necessary.
70 bool instantiate(GrResourceProvider*) override;
71
72 // Returns true if this proxy either has a stencil attachment already, or if we can attach one
73 // during flush. Wrapped render targets without stencil will return false, since we are unable
74 // to modify their attachments.
75 bool canUseStencil(const GrCaps& caps) const;
76
77 /*
78 * Indicate that a draw to this proxy requires stencil.
79 */
80 void setNeedsStencil() { fNeedsStencil = true; }
81
82 int needsStencil() const { return fNeedsStencil; }
83
84 /**
85 * Returns the number of samples/pixel in the color buffer (One if non-MSAA).
86 */
87 int numSamples() const { return fSampleCnt; }
88
89 int maxWindowRectangles(const GrCaps& caps) const;
90
92
93 bool wrapsVkSecondaryCB() const { return fWrapsVkSecondaryCB == WrapsVkSecondaryCB::kYes; }
94
98
99 void markMSAADirty(SkIRect dirtyRect) {
102 fMSAADirtyRect.join(dirtyRect);
103 }
106 fMSAADirtyRect.setEmpty();
107 }
108 bool isMSAADirty() const {
109 SkASSERT(fMSAADirtyRect.isEmpty() || this->requiresManualMSAAResolve());
110 return this->requiresManualMSAAResolve() && !fMSAADirtyRect.isEmpty();
111 }
112 const SkIRect& msaaDirtyRect() const {
114 return fMSAADirtyRect;
115 }
116
117 // TODO: move this to a priv class!
118 bool refsWrappedObjects() const;
119
121 if (fArenas == nullptr) {
122 fArenas = sk_make_sp<GrArenas>();
123 }
124 return fArenas;
125 }
126
127 void clearArenas() {
128 if (fArenas != nullptr) {
129 fArenas->flush();
130 }
131 fArenas = nullptr;
132 }
133
134protected:
135 friend class GrProxyProvider; // for ctors
136 friend class GrVkSecondaryCBDrawContext; // for ctors
137 // Deferred version
139 const GrBackendFormat&,
140 SkISize,
141 int sampleCount,
147 std::string_view label);
148
149 enum class WrapsVkSecondaryCB : bool { kNo = false, kYes = true };
150
151 // Lazy-callback version
152 // There are two main use cases for lazily-instantiated proxies:
153 // basic knowledge - width, height, config, samples, origin are known
154 // minimal knowledge - only config is known.
155 //
156 // The basic knowledge version is used for DDL where we know the type of proxy we are going to
157 // use, but we don't have access to the GPU yet to instantiate it.
158 //
159 // The minimal knowledge version is used for when we are generating an atlas but we do not know
160 // the final size until we have finished adding to it.
162 const GrBackendFormat&,
163 SkISize,
164 int sampleCount,
171 std::string_view label);
172
173 // Wrapped version
177
179
180private:
181 size_t onUninstantiatedGpuMemorySize() const override;
182 SkDEBUGCODE(void onValidateSurface(const GrSurface*) override;)
183
184 LazySurfaceDesc callbackDesc() const override;
185
186 // WARNING: Be careful when adding or removing fields here. ASAN is likely to trigger warnings
187 // when instantiating GrTextureRenderTargetProxy. The std::function in GrSurfaceProxy makes
188 // each class in the diamond require 16 byte alignment. Clang appears to layout the fields for
189 // each class to achieve the necessary alignment. However, ASAN checks the alignment of 'this'
190 // in the constructors, and always looks for the full 16 byte alignment, even if the fields in
191 // that particular class don't require it. Changing the size of this object can move the start
192 // address of other types, leading to this problem.
193 int8_t fSampleCnt;
194 int8_t fNeedsStencil = false;
195 WrapsVkSecondaryCB fWrapsVkSecondaryCB;
196 SkIRect fMSAADirtyRect = SkIRect::MakeEmpty();
197 sk_sp<GrArenas> fArenas{nullptr};
198
199 // This is to fix issue in large comment above. Without the padding we can end up with the
200 // GrTextureProxy starting 8 byte aligned by not 16. This happens when the RT ends at bytes 1-8.
201 // Note: with the virtual inheritance an 8 byte pointer is at the start of GrRenderTargetProxy.
202 //
203 // In the current world we end the RT proxy at 12 bytes. Technically any padding between 0-4
204 // will work, but we use 4 to be more explicit about getting it to 16 byte alignment.
205 char fPadding[4];
206
208};
209
210#endif
GrInternalSurfaceFlags
#define SK_ABORT(message,...)
Definition SkAssert.h:70
#define SkASSERT(cond)
Definition SkAssert.h:116
SkBackingFit
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static bool contains(const SkRect &r, SkPoint p)
#define INHERITED(method,...)
sktext::gpu::SubRunAllocator * subRunAlloc()
SkArenaAlloc * arenaAlloc()
size_t onUninstantiatedGpuMemorySize() const override
GrRenderTargetProxy * asRenderTargetProxy() override
SkDEBUGCODE(void onValidateSurface(const GrSurface *) override;) LazySurfaceDesc callbackDesc() const override
int maxWindowRectangles(const GrCaps &caps) const
void markMSAADirty(SkIRect dirtyRect)
const GrRenderTargetProxy * asRenderTargetProxy() const override
bool supportsVkInputAttachment() const
bool instantiate(GrResourceProvider *) override
const SkIRect & msaaDirtyRect() const
sk_sp< GrSurface > createSurface(GrResourceProvider *) const override
bool wrapsVkSecondaryCB() const
sk_sp< GrArenas > arenas()
bool canUseStencil(const GrCaps &caps) const
SkISize backingStoreDimensions() const
bool requiresManualMSAAResolve() const
virtual LazySurfaceDesc callbackDesc() const =0
std::function< LazyCallbackResult(GrResourceProvider *, const LazySurfaceDesc &)> LazyInstantiateCallback
GrInternalSurfaceFlags fSurfaceFlags
Budgeted
Definition GpuTypes.h:35
Protected
Definition GpuTypes.h:61
void join(const SkIRect &r)
Definition SkRect.cpp:31
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66
static constexpr SkIRect MakeEmpty()
Definition SkRect.h:45
void setEmpty()
Definition SkRect.h:242
bool isEmpty() const
Definition SkRect.h:202