Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | List of all members
GrVkSecondaryCBDrawContext Class Reference

#include <GrVkSecondaryCBDrawContext.h>

Inheritance diagram for GrVkSecondaryCBDrawContext:
SkRefCnt SkRefCntBase

Public Member Functions

 ~GrVkSecondaryCBDrawContext () override
 
SkCanvasgetCanvas ()
 
void flush ()
 
bool wait (int numSemaphores, const GrBackendSemaphore waitSemaphores[], bool deleteSemaphoresAfterWait=true)
 
void releaseResources ()
 
const SkSurfacePropsprops () const
 
bool characterize (GrSurfaceCharacterization *characterization) const
 
bool draw (sk_sp< const GrDeferredDisplayList > deferredDisplayList)
 
bool isCompatible (const GrSurfaceCharacterization &characterization) const
 
- Public Member Functions inherited from SkRefCntBase
 SkRefCntBase ()
 
virtual ~SkRefCntBase ()
 
bool unique () const
 
void ref () const
 
void unref () const
 

Static Public Member Functions

static sk_sp< GrVkSecondaryCBDrawContextMake (GrRecordingContext *, const SkImageInfo &, const GrVkDrawableInfo &, const SkSurfaceProps *props)
 

Detailed Description

This class is a private header that is intended to only be used inside of Chromium. This requires Chromium to burrow in and include this specifically since it is not part of skia's public include directory. This class is used to draw into an external Vulkan secondary command buffer that is imported by the client. The secondary command buffer that gets imported must already have had begin called on it with VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT. Thus any draws to the imported command buffer cannot require changing the render pass. This requirement means that certain types of draws will not be supported when using a GrVkSecondaryCBDrawContext. This includes: Draws that require a dst copy for blending will be dropped Text draws will be dropped (these may require intermediate uploads of text data) Read and Write pixels will not work Any other draw that requires a copy will fail (this includes using backdrop filter with save layer). Stenciling is also disabled, but that should not restrict any actual draws from working.

While using a GrVkSecondaryCBDrawContext, the client can also draw into normal SkSurfaces and then draw those SkSufaces (as SkImages) into the GrVkSecondaryCBDrawContext. If any of the previously mentioned unsupported draws are needed by the client, they can draw them into an offscreen surface, and then draw that into the GrVkSecondaryCBDrawContext.

After all drawing to the GrVkSecondaryCBDrawContext has been done, the client must call flush() on the GrVkSecondaryCBDrawContext to actually fill in the secondary VkCommandBuffer with the draws.

Additionally, the client must keep the GrVkSecondaryCBDrawContext alive until the secondary VkCommandBuffer has been submitted and all work finished on the GPU. Before deleting the GrVkSecondaryCBDrawContext, the client must call releaseResources() so that Skia can cleanup any internal objects that were created for the draws into the secondary command buffer.

Definition at line 62 of file GrVkSecondaryCBDrawContext.h.

Constructor & Destructor Documentation

◆ ~GrVkSecondaryCBDrawContext()

GrVkSecondaryCBDrawContext::~GrVkSecondaryCBDrawContext ( )
override

Definition at line 97 of file GrVkSecondaryCBDrawContext.cpp.

97 {
98 SkASSERT(!fDevice);
99 SkASSERT(!fCachedCanvas.get());
100}
#define SkASSERT(cond)
Definition: SkAssert.h:116

Member Function Documentation

◆ characterize()

bool GrVkSecondaryCBDrawContext::characterize ( GrSurfaceCharacterization characterization) const

Definition at line 129 of file GrVkSecondaryCBDrawContext.cpp.

129 {
130 auto direct = fDevice->recordingContext()->asDirectContext();
131 if (!direct) {
132 return false;
133 }
134
135 SkImageInfo ii = fDevice->imageInfo();
136 if (ii.colorType() == kUnknown_SkColorType) {
137 return false;
138 }
139
140 GrSurfaceProxyView readSurfaceView = fDevice->readSurfaceView();
141 size_t maxResourceBytes = direct->getResourceCacheLimit();
142
143 // We current don't support textured GrVkSecondaryCBDrawContexts.
144 SkASSERT(!readSurfaceView.asTextureProxy());
145
147 int numSamples = readSurfaceView.asRenderTargetProxy()->numSamples();
148 GrProtected isProtected = readSurfaceView.asRenderTargetProxy()->isProtected();
149
150 characterization->set(direct->threadSafeProxy(),
151 maxResourceBytes,
152 ii,
153 format,
154 readSurfaceView.origin(),
155 numSamples,
161 isProtected,
162 this->props());
163
164 return true;
165}
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
virtual GrDirectContext * asDirectContext()
GrTextureProxy * asTextureProxy() const
GrSurfaceOrigin origin() const
GrRenderTargetProxy * asRenderTargetProxy() const
GrProtected isProtected() const
const GrBackendFormat & backendFormat() const
const SkImageInfo & imageInfo() const
Definition: SkDevice.h:117
GrSurfaceProxyView readSurfaceView()
Definition: Device.cpp:1283
GrRecordingContext * recordingContext() const override
Definition: Device.h:101
uint32_t uint32_t * format
Protected
Definition: GpuTypes.h:61
SkColorType colorType() const
Definition: SkImageInfo.h:373

◆ draw()

bool GrVkSecondaryCBDrawContext::draw ( sk_sp< const GrDeferredDisplayList deferredDisplayList)

Definition at line 222 of file GrVkSecondaryCBDrawContext.cpp.

222 {
223#else
225#endif
226 if (!ddl || !this->isCompatible(ddl->characterization())) {
227 return false;
228 }
229
230 auto direct = fDevice->recordingContext()->asDirectContext();
231 if (!direct) {
232 return false;
233 }
234
235 GrSurfaceProxyView readSurfaceView = fDevice->readSurfaceView();
236
237 direct->priv().createDDLTask(std::move(ddl), readSurfaceView.asRenderTargetProxyRef());
238 return true;
239}
SK_API const GrSurfaceCharacterization & characterization() const
sk_sp< GrRenderTargetProxy > asRenderTargetProxyRef() const
bool draw(sk_sp< const GrDeferredDisplayList > deferredDisplayList)
bool isCompatible(const GrSurfaceCharacterization &characterization) const

◆ flush()

void GrVkSecondaryCBDrawContext::flush ( )

Definition at line 109 of file GrVkSecondaryCBDrawContext.cpp.

109 {
110 auto dContext = GrAsDirectContext(fDevice->recordingContext());
111
112 if (dContext) {
113 dContext->priv().flushSurface(fDevice->targetProxy());
114 dContext->submit();
115 }
116}
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
GrRenderTargetProxy * targetProxy()
Definition: Device.cpp:1287

◆ getCanvas()

SkCanvas * GrVkSecondaryCBDrawContext::getCanvas ( )

Definition at line 102 of file GrVkSecondaryCBDrawContext.cpp.

102 {
103 if (!fCachedCanvas) {
104 fCachedCanvas = std::make_unique<SkCanvas>(fDevice);
105 }
106 return fCachedCanvas.get();
107}

◆ isCompatible()

bool GrVkSecondaryCBDrawContext::isCompatible ( const GrSurfaceCharacterization characterization) const

Definition at line 167 of file GrVkSecondaryCBDrawContext.cpp.

168 {
169
170 auto dContext = fDevice->recordingContext()->asDirectContext();
171 if (!dContext) {
172 return false;
173 }
174
175 if (!characterization.isValid()) {
176 return false;
177 }
178
179 if (!characterization.vulkanSecondaryCBCompatible()) {
180 return false;
181 }
182
183 if (characterization.isTextureable()) {
184 // We don't support textureable DDL when rendering to a GrVkSecondaryCBDrawContext.
185 return false;
186 }
187
188 if (characterization.usesGLFBO0()) {
189 return false;
190 }
191
192 SkImageInfo ii = fDevice->imageInfo();
193 if (ii.colorType() == kUnknown_SkColorType) {
194 return false;
195 }
196
197 GrSurfaceProxyView readSurfaceView = fDevice->readSurfaceView();
198 // As long as the current state in the context allows for greater or equal resources,
199 // we allow the DDL to be replayed.
200 // DDL TODO: should we just remove the resource check and ignore the cache limits on playback?
201 size_t maxResourceBytes = dContext->getResourceCacheLimit();
202
204 int numSamples = readSurfaceView.asRenderTargetProxy()->numSamples();
205 GrProtected isProtected = readSurfaceView.asRenderTargetProxy()->isProtected();
206
207 return characterization.contextInfo() &&
208 characterization.contextInfo()->priv().matches(dContext) &&
209 characterization.cacheMaxResourceBytes() <= maxResourceBytes &&
210 characterization.origin() == readSurfaceView.origin() &&
211 characterization.backendFormat() == format &&
212 characterization.width() == ii.width() &&
213 characterization.height() == ii.height() &&
214 characterization.colorType() == ii.colorType() &&
215 characterization.sampleCount() == numSamples &&
216 SkColorSpace::Equals(characterization.colorSpace(), ii.colorInfo().colorSpace()) &&
217 characterization.isProtected() == isProtected &&
218 characterization.surfaceProps() == fDevice->surfaceProps();
219}
bool matches(GrContext_Base *candidate) const
GrContextThreadSafeProxyPriv priv()
GrContextThreadSafeProxy * contextInfo() const
SkColorSpace * colorSpace() const
Definition: SkImageInfo.cpp:66
static bool Equals(const SkColorSpace *, const SkColorSpace *)
const SkSurfaceProps & surfaceProps() const
Definition: SkDevice.h:131
const SkColorInfo & colorInfo() const
Definition: SkImageInfo.h:404
int width() const
Definition: SkImageInfo.h:365
int height() const
Definition: SkImageInfo.h:371

◆ Make()

sk_sp< GrVkSecondaryCBDrawContext > GrVkSecondaryCBDrawContext::Make ( GrRecordingContext rContext,
const SkImageInfo imageInfo,
const GrVkDrawableInfo vkInfo,
const SkSurfaceProps props 
)
static

Definition at line 27 of file GrVkSecondaryCBDrawContext.cpp.

30 {
31 if (!rContext) {
32 return nullptr;
33 }
34
35 if (rContext->backend() != GrBackendApi::kVulkan) {
36 return nullptr;
37 }
38
39
40 GrProxyProvider* gpp = rContext->priv().proxyProvider();
41 if (gpp->isAbandoned()) {
42 return nullptr;
43 }
44
45 GrResourceProvider* resourceProvider = gpp->resourceProvider();
46 if (!resourceProvider) {
47 return nullptr;
48 }
49
50 sk_sp<GrRenderTarget> rt = resourceProvider->wrapVulkanSecondaryCBAsRenderTarget(imageInfo,
51 vkInfo);
52 if (!rt) {
53 return nullptr;
54 }
55
56 SkASSERT(!rt->asTexture()); // A GrRenderTarget that's not textureable
57 SkASSERT(!rt->getUniqueKey().isValid());
58 // This proxy should be unbudgeted because we're just wrapping an external resource
59 SkASSERT(GrBudgetedType::kBudgeted != rt->resourcePriv().budgetedType());
60
62
64 colorType, GrBackendFormats::MakeVk(vkInfo.fFormat), /*sampleCount=*/1)) {
65 return nullptr;
66 }
67
69 new GrRenderTargetProxy(std::move(rt),
72
73 if (!proxy) {
74 return nullptr;
75 }
76
77 SkASSERT(proxy->isInstantiated());
78
79 auto device = rContext->priv().createDevice(SkColorTypeToGrColorType(imageInfo.colorType()),
80 std::move(proxy),
81 imageInfo.refColorSpace(),
85 if (!device) {
86 return nullptr;
87 }
88
90 props));
91}
GrColorType
Definition: GrTypesPriv.h:540
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
Definition: GrTypesPriv.h:629
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static SkSurfaceProps SkSurfacePropsCopyOrDefault(const SkSurfaceProps *props)
Definition: SkSurfacePriv.h:15
virtual bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat &format, int sampleCount=1) const =0
SK_API GrBackendApi backend() const
GrResourceProvider * resourceProvider() const
bool isAbandoned() const
const GrCaps * caps() const
GrProxyProvider * proxyProvider()
sk_sp< skgpu::ganesh::Device > createDevice(GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &, skgpu::ganesh::Device::InitContents)
GrRecordingContextPriv priv()
sk_sp< GrRenderTarget > wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo &, const GrVkDrawableInfo &)
const SkSurfaceProps & props() const
VkDevice device
Definition: main.cc:53
SK_API GrBackendFormat MakeVk(VkFormat format, bool willUseDRMFormatModifiers=false)
VkFormat fFormat
Definition: GrVkTypes.h:88
sk_sp< SkColorSpace > refColorSpace() const

◆ props()

const SkSurfaceProps & GrVkSecondaryCBDrawContext::props ( ) const
inline

Definition at line 108 of file GrVkSecondaryCBDrawContext.h.

108{ return fProps; }

◆ releaseResources()

void GrVkSecondaryCBDrawContext::releaseResources ( )

Definition at line 124 of file GrVkSecondaryCBDrawContext.cpp.

124 {
125 fCachedCanvas.reset();
126 fDevice.reset();
127}
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310

◆ wait()

bool GrVkSecondaryCBDrawContext::wait ( int  numSemaphores,
const GrBackendSemaphore  waitSemaphores[],
bool  deleteSemaphoresAfterWait = true 
)

Inserts a list of GPU semaphores that Skia will have the driver wait on before executing commands for this secondary CB. The wait semaphores will get added to the VkCommandBuffer owned by this GrContext when flush() is called, and not the command buffer which the Secondary CB is from. This will guarantee that the driver waits on the semaphores before the secondary command buffer gets executed. We will submit the semphore to wait at VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT and VK_PIPELINE_STAGE_TRANSFER_BIT. If this call returns false, then the GPU back end will not wait on any passed in semaphores, and the client will still own the semaphores, regardless of the value of deleteSemaphoresAfterWait.

If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case it is the client's responsibility to not destroy or attempt to reuse the semaphores until it knows that Skia has finished waiting on them. This can be done by using finishedProcs on flush calls.

Parameters
numSemaphoressize of waitSemaphores array
waitSemaphoresarray of semaphore containers @paramm deleteSemaphoresAfterWait who owns and should delete the semaphores
Returns
true if GPU is waiting on semaphores

Definition at line 118 of file GrVkSecondaryCBDrawContext.cpp.

120 {
121 return fDevice->wait(numSemaphores, waitSemaphores, deleteSemaphoresAfterWait);
122}
bool wait(int numSemaphores, const GrBackendSemaphore *waitSemaphores, bool deleteSemaphoresAfterWait)
Definition: Device.cpp:1291

The documentation for this class was generated from the following files: