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 SkSurfaceCharacterization_DEFINED
9 #define SkSurfaceCharacterization_DEFINED
10 
11 #include "include/gpu/GrTypes.h"
12 
13 #include "include/core/SkColorSpace.h"
14 #include "include/core/SkImageInfo.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkSurfaceProps.h"
17 
18 class SkColorSpace;
19 
20 #include "include/gpu/GrBackendSurface.h"
21 
22 #if SK_SUPPORT_GPU
23 #include "include/gpu/GrContextThreadSafeProxy.h"
24 
25 /** \class SkSurfaceCharacterization
26     A surface characterization contains all the information Ganesh requires to makes its internal
27     rendering decisions. When passed into a SkDeferredDisplayListRecorder it will copy the
28     data and pass it on to the SkDeferredDisplayList if/when it is created. Note that both of
29     those objects (the Recorder and the DisplayList) will take a ref on the
30     GrContextThreadSafeProxy and SkColorSpace objects.
31 */
32 class SK_API SkSurfaceCharacterization {
33 public:
34     enum class Textureable : bool { kNo = false, kYes = true };
35     enum class MipMapped : bool { kNo = false, kYes = true };
36     enum class UsesGLFBO0 : bool { kNo = false, kYes = true };
37     // This flag indicates that the backing VkImage for this Vulkan surface will have the
38     // VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set. This bit allows skia to handle advanced blends
39     // more optimally in a shader by being able to directly read the dst values.
40     enum class VkRTSupportsInputAttachment : bool { kNo = false, kYes = true };
41     // This flag indicates if the surface is wrapping a raw Vulkan secondary command buffer.
42     enum class VulkanSecondaryCBCompatible : bool { kNo = false, kYes = true };
43 
SkSurfaceCharacterization()44     SkSurfaceCharacterization()
45             : fCacheMaxResourceBytes(0)
46             , fOrigin(kBottomLeft_GrSurfaceOrigin)
47             , fSampleCnt(0)
48             , fIsTextureable(Textureable::kYes)
49             , fIsMipMapped(MipMapped::kYes)
50             , fUsesGLFBO0(UsesGLFBO0::kNo)
51             , fVulkanSecondaryCBCompatible(VulkanSecondaryCBCompatible::kNo)
52             , fIsProtected(GrProtected::kNo)
53             , fSurfaceProps(0, kUnknown_SkPixelGeometry) {
54     }
55 
56     SkSurfaceCharacterization(SkSurfaceCharacterization&&) = default;
57     SkSurfaceCharacterization& operator=(SkSurfaceCharacterization&&) = default;
58 
59     SkSurfaceCharacterization(const SkSurfaceCharacterization&) = default;
60     SkSurfaceCharacterization& operator=(const SkSurfaceCharacterization& other) = default;
61     bool operator==(const SkSurfaceCharacterization& other) const;
62     bool operator!=(const SkSurfaceCharacterization& other) const {
63         return !(*this == other);
64     }
65 
66     /*
67      * Return a new surface characterization with the only difference being a different width
68      * and height
69      */
70     SkSurfaceCharacterization createResized(int width, int height) const;
71 
72     /*
73      * Return a new surface characterization with only a replaced color space
74      */
75     SkSurfaceCharacterization createColorSpace(sk_sp<SkColorSpace>) const;
76 
77     /*
78      * Return a new surface characterization with the backend format replaced. A colorType
79      * must also be supplied to indicate the interpretation of the new format.
80      */
81     SkSurfaceCharacterization createBackendFormat(SkColorType colorType,
82                                                   const GrBackendFormat& backendFormat) const;
83 
84     /*
85      * Return a new surface characterization with just a different use of FBO0 (in GL)
86      */
87     SkSurfaceCharacterization createFBO0(bool usesGLFBO0) const;
88 
contextInfo()89     GrContextThreadSafeProxy* contextInfo() const { return fContextInfo.get(); }
refContextInfo()90     sk_sp<GrContextThreadSafeProxy> refContextInfo() const { return fContextInfo; }
cacheMaxResourceBytes()91     size_t cacheMaxResourceBytes() const { return fCacheMaxResourceBytes; }
92 
isValid()93     bool isValid() const { return kUnknown_SkColorType != fImageInfo.colorType(); }
94 
imageInfo()95     const SkImageInfo& imageInfo() const { return fImageInfo; }
backendFormat()96     const GrBackendFormat& backendFormat() const { return fBackendFormat; }
origin()97     GrSurfaceOrigin origin() const { return fOrigin; }
dimensions()98     SkISize dimensions() const { return fImageInfo.dimensions(); }
width()99     int width() const { return fImageInfo.width(); }
height()100     int height() const { return fImageInfo.height(); }
colorType()101     SkColorType colorType() const { return fImageInfo.colorType(); }
sampleCount()102     int sampleCount() const { return fSampleCnt; }
isTextureable()103     bool isTextureable() const { return Textureable::kYes == fIsTextureable; }
isMipMapped()104     bool isMipMapped() const { return MipMapped::kYes == fIsMipMapped; }
usesGLFBO0()105     bool usesGLFBO0() const { return UsesGLFBO0::kYes == fUsesGLFBO0; }
vkRTSupportsInputAttachment()106     bool vkRTSupportsInputAttachment() const {
107         return VkRTSupportsInputAttachment::kYes == fVkRTSupportsInputAttachment;
108     }
vulkanSecondaryCBCompatible()109     bool vulkanSecondaryCBCompatible() const {
110         return VulkanSecondaryCBCompatible::kYes == fVulkanSecondaryCBCompatible;
111     }
isProtected()112     GrProtected isProtected() const { return fIsProtected; }
colorSpace()113     SkColorSpace* colorSpace() const { return fImageInfo.colorSpace(); }
refColorSpace()114     sk_sp<SkColorSpace> refColorSpace() const { return fImageInfo.refColorSpace(); }
surfaceProps()115     const SkSurfaceProps& surfaceProps()const { return fSurfaceProps; }
116 
117     // Is the provided backend texture compatible with this surface characterization?
118     bool isCompatible(const GrBackendTexture&) const;
119 
120 private:
121     friend class SkSurface_Gpu; // for 'set' & 'config'
122     friend class GrVkSecondaryCBDrawContext; // for 'set' & 'config'
123     friend class GrContextThreadSafeProxy; // for private ctor
124     friend class SkDeferredDisplayListRecorder; // for 'config'
125     friend class SkSurface; // for 'config'
126 
127     SkDEBUGCODE(void validate() const;)
128 
SkSurfaceCharacterization(sk_sp<GrContextThreadSafeProxy> contextInfo,size_t cacheMaxResourceBytes,const SkImageInfo & ii,const GrBackendFormat & backendFormat,GrSurfaceOrigin origin,int sampleCnt,Textureable isTextureable,MipMapped isMipMapped,UsesGLFBO0 usesGLFBO0,VkRTSupportsInputAttachment vkRTSupportsInputAttachment,VulkanSecondaryCBCompatible vulkanSecondaryCBCompatible,GrProtected isProtected,const SkSurfaceProps & surfaceProps)129     SkSurfaceCharacterization(sk_sp<GrContextThreadSafeProxy> contextInfo,
130                               size_t cacheMaxResourceBytes,
131                               const SkImageInfo& ii,
132                               const GrBackendFormat& backendFormat,
133                               GrSurfaceOrigin origin,
134                               int sampleCnt,
135                               Textureable isTextureable,
136                               MipMapped isMipMapped,
137                               UsesGLFBO0 usesGLFBO0,
138                               VkRTSupportsInputAttachment vkRTSupportsInputAttachment,
139                               VulkanSecondaryCBCompatible vulkanSecondaryCBCompatible,
140                               GrProtected isProtected,
141                               const SkSurfaceProps& surfaceProps)
142             : fContextInfo(std::move(contextInfo))
143             , fCacheMaxResourceBytes(cacheMaxResourceBytes)
144             , fImageInfo(ii)
145             , fBackendFormat(backendFormat)
146             , fOrigin(origin)
147             , fSampleCnt(sampleCnt)
148             , fIsTextureable(isTextureable)
149             , fIsMipMapped(isMipMapped)
150             , fUsesGLFBO0(usesGLFBO0)
151             , fVkRTSupportsInputAttachment(vkRTSupportsInputAttachment)
152             , fVulkanSecondaryCBCompatible(vulkanSecondaryCBCompatible)
153             , fIsProtected(isProtected)
154             , fSurfaceProps(surfaceProps) {
155         SkDEBUGCODE(this->validate());
156     }
157 
set(sk_sp<GrContextThreadSafeProxy> contextInfo,size_t cacheMaxResourceBytes,const SkImageInfo & ii,const GrBackendFormat & backendFormat,GrSurfaceOrigin origin,int sampleCnt,Textureable isTextureable,MipMapped isMipMapped,UsesGLFBO0 usesGLFBO0,VkRTSupportsInputAttachment vkRTSupportsInputAttachment,VulkanSecondaryCBCompatible vulkanSecondaryCBCompatible,GrProtected isProtected,const SkSurfaceProps & surfaceProps)158     void set(sk_sp<GrContextThreadSafeProxy> contextInfo,
159              size_t cacheMaxResourceBytes,
160              const SkImageInfo& ii,
161              const GrBackendFormat& backendFormat,
162              GrSurfaceOrigin origin,
163              int sampleCnt,
164              Textureable isTextureable,
165              MipMapped isMipMapped,
166              UsesGLFBO0 usesGLFBO0,
167              VkRTSupportsInputAttachment vkRTSupportsInputAttachment,
168              VulkanSecondaryCBCompatible vulkanSecondaryCBCompatible,
169              GrProtected isProtected,
170              const SkSurfaceProps& surfaceProps) {
171         fContextInfo = contextInfo;
172         fCacheMaxResourceBytes = cacheMaxResourceBytes;
173 
174         fImageInfo = ii;
175         fBackendFormat = backendFormat;
176         fOrigin = origin;
177         fSampleCnt = sampleCnt;
178         fIsTextureable = isTextureable;
179         fIsMipMapped = isMipMapped;
180         fUsesGLFBO0 = usesGLFBO0;
181         fVkRTSupportsInputAttachment = vkRTSupportsInputAttachment;
182         fVulkanSecondaryCBCompatible = vulkanSecondaryCBCompatible;
183         fIsProtected = isProtected;
184         fSurfaceProps = surfaceProps;
185 
186         SkDEBUGCODE(this->validate());
187     }
188 
189     sk_sp<GrContextThreadSafeProxy> fContextInfo;
190     size_t                          fCacheMaxResourceBytes;
191 
192     SkImageInfo                     fImageInfo;
193     GrBackendFormat                 fBackendFormat;
194     GrSurfaceOrigin                 fOrigin;
195     int                             fSampleCnt;
196     Textureable                     fIsTextureable;
197     MipMapped                       fIsMipMapped;
198     UsesGLFBO0                      fUsesGLFBO0;
199     VkRTSupportsInputAttachment     fVkRTSupportsInputAttachment;
200     VulkanSecondaryCBCompatible     fVulkanSecondaryCBCompatible;
201     GrProtected                     fIsProtected;
202     SkSurfaceProps                  fSurfaceProps;
203 };
204 
205 #else// !SK_SUPPORT_GPU
206 
207 class SK_API SkSurfaceCharacterization {
208 public:
SkSurfaceCharacterization()209     SkSurfaceCharacterization() : fSurfaceProps(0, kUnknown_SkPixelGeometry) { }
210 
createResized(int width,int height)211     SkSurfaceCharacterization createResized(int width, int height) const {
212         return *this;
213     }
214 
createColorSpace(sk_sp<SkColorSpace>)215     SkSurfaceCharacterization createColorSpace(sk_sp<SkColorSpace>) const {
216         return *this;
217     }
218 
createBackendFormat(SkColorType,const GrBackendFormat &)219     SkSurfaceCharacterization createBackendFormat(SkColorType, const GrBackendFormat&) const {
220         return *this;
221     }
222 
createFBO0(bool usesGLFBO0)223     SkSurfaceCharacterization createFBO0(bool usesGLFBO0) const {
224         return *this;
225     }
226 
227     bool operator==(const SkSurfaceCharacterization& other) const { return false; }
228     bool operator!=(const SkSurfaceCharacterization& other) const {
229         return !(*this == other);
230     }
231 
cacheMaxResourceBytes()232     size_t cacheMaxResourceBytes() const { return 0; }
233 
isValid()234     bool isValid() const { return false; }
235 
width()236     int width() const { return 0; }
height()237     int height() const { return 0; }
stencilCount()238     int stencilCount() const { return 0; }
isTextureable()239     bool isTextureable() const { return false; }
isMipMapped()240     bool isMipMapped() const { return false; }
usesGLFBO0()241     bool usesGLFBO0() const { return false; }
vkRTSupportsAttachmentInput()242     bool vkRTSupportsAttachmentInput() const { return false; }
vulkanSecondaryCBCompatible()243     bool vulkanSecondaryCBCompatible() const { return false; }
colorSpace()244     SkColorSpace* colorSpace() const { return nullptr; }
refColorSpace()245     sk_sp<SkColorSpace> refColorSpace() const { return nullptr; }
surfaceProps()246     const SkSurfaceProps& surfaceProps()const { return fSurfaceProps; }
247 
248 private:
249     SkSurfaceProps fSurfaceProps;
250 };
251 
252 #endif
253 
254 #endif
255