• 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 GrContextThreadSafeProxy_DEFINED
9 #define GrContextThreadSafeProxy_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 
13 #if defined(SK_GANESH)
14 
15 #include "include/core/SkImageInfo.h"
16 #include "include/gpu/GrContextOptions.h"
17 #include "include/gpu/GrTypes.h"
18 
19 #include <atomic>
20 
21 class GrBackendFormat;
22 class GrCaps;
23 class GrContextThreadSafeProxyPriv;
24 class GrThreadSafeCache;
25 class GrThreadSafePipelineBuilder;
26 class SkSurfaceCharacterization;
27 class SkSurfaceProps;
28 
29 namespace sktext::gpu { class TextBlobRedrawCoordinator; }
30 
31 /**
32  * Can be used to perform actions related to the generating GrContext in a thread safe manner. The
33  * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext.
34  */
35 class SK_API GrContextThreadSafeProxy final : public SkNVRefCnt<GrContextThreadSafeProxy> {
36 public:
37     ~GrContextThreadSafeProxy();
38 
39     /**
40      *  Create a surface characterization for a DDL that will be replayed into the GrContext
41      *  that created this proxy. On failure the resulting characterization will be invalid (i.e.,
42      *  "!c.isValid()").
43      *
44      *  @param cacheMaxResourceBytes           The max resource bytes limit that will be in effect
45      *                                         when the DDL created with this characterization is
46      *                                         replayed.
47      *                                         Note: the contract here is that the DDL will be
48      *                                         created as if it had a full 'cacheMaxResourceBytes'
49      *                                         to use. If replayed into a GrContext that already has
50      *                                         locked GPU memory, the replay can exceed the budget.
51      *                                         To rephrase, all resource allocation decisions are
52      *                                         made at record time and at playback time the budget
53      *                                         limits will be ignored.
54      *  @param ii                              The image info specifying properties of the SkSurface
55      *                                         that the DDL created with this characterization will
56      *                                         be replayed into.
57      *                                         Note: Ganesh doesn't make use of the SkImageInfo's
58      *                                         alphaType
59      *  @param backendFormat                   Information about the format of the GPU surface that
60      *                                         will back the SkSurface upon replay
61      *  @param sampleCount                     The sample count of the SkSurface that the DDL
62      *                                         created with this characterization will be replayed
63      *                                         into
64      *  @param origin                          The origin of the SkSurface that the DDL created with
65      *                                         this characterization will be replayed into
66      *  @param surfaceProps                    The surface properties of the SkSurface that the DDL
67      *                                         created with this characterization will be replayed
68      *                                         into
69      *  @param isMipMapped                     Will the surface the DDL will be replayed into have
70      *                                         space allocated for mipmaps?
71      *  @param willUseGLFBO0                   Will the surface the DDL will be replayed into be
72      *                                         backed by GL FBO 0. This flag is only valid if using
73      *                                         an GL backend.
74      *  @param isTextureable                   Will the surface be able to act as a texture?
75      *  @param isProtected                     Will the (Vulkan) surface be DRM protected?
76      *  @param vkRTSupportsInputAttachment     Can the vulkan surface be used as in input
77                                                attachment?
78      *  @param forVulkanSecondaryCommandBuffer Will the surface be wrapping a vulkan secondary
79      *                                         command buffer via a GrVkSecondaryCBDrawContext? If
80      *                                         this is true then the following is required:
81      *                                         isTexureable = false
82      *                                         isMipMapped = false
83      *                                         willUseGLFBO0 = false
84      *                                         vkRTSupportsInputAttachment = false
85      */
86     SkSurfaceCharacterization createCharacterization(
87                                   size_t cacheMaxResourceBytes,
88                                   const SkImageInfo& ii,
89                                   const GrBackendFormat& backendFormat,
90                                   int sampleCount,
91                                   GrSurfaceOrigin origin,
92                                   const SkSurfaceProps& surfaceProps,
93                                   bool isMipMapped,
94                                   bool willUseGLFBO0 = false,
95                                   bool isTextureable = true,
96                                   GrProtected isProtected = GrProtected::kNo,
97                                   bool vkRTSupportsInputAttachment = false,
98                                   bool forVulkanSecondaryCommandBuffer = false);
99 
100     /*
101      * Retrieve the default GrBackendFormat for a given SkColorType and renderability.
102      * It is guaranteed that this backend format will be the one used by the following
103      * SkColorType and SkSurfaceCharacterization-based createBackendTexture methods.
104      *
105      * The caller should check that the returned format is valid.
106      */
107     GrBackendFormat defaultBackendFormat(SkColorType ct, GrRenderable renderable) const;
108 
109     /**
110      * Retrieve the GrBackendFormat for a given SkImage::CompressionType. This is
111      * guaranteed to match the backend format used by the following
112      * createCompressedBackendTexture methods that take a CompressionType.
113      *
114      * The caller should check that the returned format is valid.
115      */
116     GrBackendFormat compressedBackendFormat(SkImage::CompressionType c) const;
117 
118     /**
119      * Gets the maximum supported sample count for a color type. 1 is returned if only non-MSAA
120      * rendering is supported for the color type. 0 is returned if rendering to this color type
121      * is not supported at all.
122      */
123     int maxSurfaceSampleCountForColorType(SkColorType colorType) const;
124 
isValid()125     bool isValid() const { return nullptr != fCaps; }
126 
127     bool operator==(const GrContextThreadSafeProxy& that) const {
128         // Each GrContext should only ever have a single thread-safe proxy.
129         SkASSERT((this == &that) == (this->fContextID == that.fContextID));
130         return this == &that;
131     }
132 
133     bool operator!=(const GrContextThreadSafeProxy& that) const { return !(*this == that); }
134 
135     // Provides access to functions that aren't part of the public API.
136     GrContextThreadSafeProxyPriv priv();
137     const GrContextThreadSafeProxyPriv priv() const;  // NOLINT(readability-const-return-type)
138 
139 private:
140     friend class GrContextThreadSafeProxyPriv; // for ctor and hidden methods
141 
142     // DDL TODO: need to add unit tests for backend & maybe options
143     GrContextThreadSafeProxy(GrBackendApi, const GrContextOptions&);
144 
145     void abandonContext();
146     bool abandoned() const;
147 
148     // TODO: This should be part of the constructor but right now we have a chicken-and-egg problem
149     // with GrContext where we get the caps by creating a GPU which requires a context (see the
150     // `init` method on GrContext_Base).
151     void init(sk_sp<const GrCaps>, sk_sp<GrThreadSafePipelineBuilder>);
152 
153     const GrBackendApi                                      fBackend;
154     const GrContextOptions                                  fOptions;
155     const uint32_t                                          fContextID;
156     sk_sp<const GrCaps>                                     fCaps;
157     std::unique_ptr<sktext::gpu::TextBlobRedrawCoordinator> fTextBlobRedrawCoordinator;
158     std::unique_ptr<GrThreadSafeCache>                      fThreadSafeCache;
159     sk_sp<GrThreadSafePipelineBuilder>                      fPipelineBuilder;
160     std::atomic<bool>                                       fAbandoned{false};
161 };
162 
163 #else // !defined(SK_GANESH)
164 class SK_API GrContextThreadSafeProxy final : public SkNVRefCnt<GrContextThreadSafeProxy> {};
165 #endif
166 
167 #endif
168