• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 GrVkSecondaryCBDrawContext_DEFINED
9 #define GrVkSecondaryCBDrawContext_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/core/SkSurfaceProps.h"
13 #include "include/core/SkTypes.h"
14 
15 #include <memory>
16 
17 class GrBackendSemaphore;
18 class GrRecordingContext;
19 struct GrVkDrawableInfo;
20 namespace skgpu::v1 { class Device; }
21 class SkCanvas;
22 class SkDeferredDisplayList;
23 struct SkImageInfo;
24 class SkSurfaceCharacterization;
25 class SkSurfaceProps;
26 
27 /**
28  * This class is a private header that is intended to only be used inside of Chromium. This requires
29  * Chromium to burrow in and include this specifically since it is not part of skia's public include
30  * directory.
31  */
32 
33 /**
34  * This class is used to draw into an external Vulkan secondary command buffer that is imported
35  * by the client. The secondary command buffer that gets imported must already have had begin called
36  * on it with VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT. Thus any draws to the imported
37  * command buffer cannot require changing the render pass. This requirement means that certain types
38  * of draws will not be supported when using a GrVkSecondaryCBDrawContext. This includes:
39  *     Draws that require a dst copy for blending will be dropped
40  *     Text draws will be dropped (these may require intermediate uploads of text data)
41  *     Read and Write pixels will not work
42  *     Any other draw that requires a copy will fail (this includes using backdrop filter with save
43  *         layer).
44  *     Stenciling is also disabled, but that should not restrict any actual draws from working.
45  *
46  * While using a GrVkSecondaryCBDrawContext, the client can also draw into normal SkSurfaces and
47  * then draw those SkSufaces (as SkImages) into the GrVkSecondaryCBDrawContext. If any of the
48  * previously mentioned unsupported draws are needed by the client, they can draw them into an
49  * offscreen surface, and then draw that into the GrVkSecondaryCBDrawContext.
50  *
51  * After all drawing to the GrVkSecondaryCBDrawContext has been done, the client must call flush()
52  * on the GrVkSecondaryCBDrawContext to actually fill in the secondary VkCommandBuffer with the
53  * draws.
54  *
55  * Additionally, the client must keep the GrVkSecondaryCBDrawContext alive until the secondary
56  * VkCommandBuffer has been submitted and all work finished on the GPU. Before deleting the
57  * GrVkSecondaryCBDrawContext, the client must call releaseResources() so that Skia can cleanup
58  * any internal objects that were created for the draws into the secondary command buffer.
59  */
60 class SK_SPI GrVkSecondaryCBDrawContext : public SkRefCnt {
61 public:
62     static sk_sp<GrVkSecondaryCBDrawContext> Make(GrRecordingContext*,
63                                                   const SkImageInfo&,
64                                                   const GrVkDrawableInfo&,
65                                                   const SkSurfaceProps* props);
66 
67     ~GrVkSecondaryCBDrawContext() override;
68 
69     SkCanvas* getCanvas();
70 
71     // Records all the draws to the imported secondary command buffer and sets any dependent
72     // offscreen draws to the GPU.
73     void flush();
74 
75     /** Inserts a list of GPU semaphores that Skia will have the driver wait on before executing
76         commands for this secondary CB. The wait semaphores will get added to the VkCommandBuffer
77         owned by this GrContext when flush() is called, and not the command buffer which the
78         Secondary CB is from. This will guarantee that the driver waits on the semaphores before
79         the secondary command buffer gets executed. If this call returns false, then the GPU
80         back end will not wait on any passed in semaphores, and the client will still own the
81         semaphores, regardless of the value of deleteSemaphoresAfterWait.
82 
83         If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case
84         it is the client's responsibility to not destroy or attempt to reuse the semaphores until it
85         knows that Skia has finished waiting on them. This can be done by using finishedProcs
86         on flush calls.
87 
88         @param numSemaphores               size of waitSemaphores array
89         @param waitSemaphores              array of semaphore containers
90         @paramm deleteSemaphoresAfterWait  who owns and should delete the semaphores
91         @return                            true if GPU is waiting on semaphores
92     */
93     bool wait(int numSemaphores,
94               const GrBackendSemaphore waitSemaphores[],
95               bool deleteSemaphoresAfterWait = true);
96 
97     // This call will release all resources held by the draw context. The client must call
98     // releaseResources() before deleting the drawing context. However, the resources also include
99     // any Vulkan resources that were created and used for draws. Therefore the client must only
100     // call releaseResources() after submitting the secondary command buffer, and waiting for it to
101     // finish on the GPU. If it is called earlier then some vulkan objects may be deleted while they
102     // are still in use by the GPU.
103     void releaseResources();
104 
props()105     const SkSurfaceProps& props() const { return fProps; }
106 
107     // TODO: Fill out these calls to support DDL
108     bool characterize(SkSurfaceCharacterization* characterization) const;
109 
110 #ifndef SK_DDL_IS_UNIQUE_POINTER
111     bool draw(sk_sp<const SkDeferredDisplayList> deferredDisplayList);
112 #else
113     bool draw(const SkDeferredDisplayList* deferredDisplayList);
114 #endif
115 
116     bool isCompatible(const SkSurfaceCharacterization& characterization) const;
117 
118 private:
119     explicit GrVkSecondaryCBDrawContext(sk_sp<skgpu::v1::Device>, const SkSurfaceProps*);
120 
121     sk_sp<skgpu::v1::Device>  fDevice;
122     std::unique_ptr<SkCanvas> fCachedCanvas;
123     const SkSurfaceProps      fProps;
124 
125     using INHERITED = SkRefCnt;
126 };
127 
128 #endif
129