• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 #include "include/core/SkSurfaceCharacterization.h"
9 
10 #if SK_SUPPORT_GPU
11 #include "src/gpu/GrCaps.h"
12 #include "src/gpu/GrContextThreadSafeProxyPriv.h"
13 
14 #ifdef SK_VULKAN
15 #include "include/gpu/vk/GrVkTypes.h"
16 #endif
17 
18 #ifdef SK_DEBUG
validate() const19 void SkSurfaceCharacterization::validate() const {
20     const GrCaps* caps = fContextInfo->priv().caps();
21 
22     GrColorType grCT = SkColorTypeToGrColorType(this->colorType());
23     SkASSERT(fSampleCnt && caps->isFormatAsColorTypeRenderable(grCT, fBackendFormat, fSampleCnt));
24 
25     SkASSERT(caps->areColorTypeAndFormatCompatible(grCT, fBackendFormat));
26 
27     SkASSERT(MipMapped::kNo == fIsMipMapped || Textureable::kYes == fIsTextureable);
28     SkASSERT(Textureable::kNo == fIsTextureable || UsesGLFBO0::kNo == fUsesGLFBO0);
29     auto backend = fBackendFormat.backend();
30     SkASSERT(UsesGLFBO0::kNo == fUsesGLFBO0 || backend == GrBackendApi::kOpenGL);
31     SkASSERT((VulkanSecondaryCBCompatible::kNo == fVulkanSecondaryCBCompatible &&
32               VkRTSupportsInputAttachment::kNo == fVkRTSupportsInputAttachment) ||
33              backend == GrBackendApi::kVulkan);
34     SkASSERT(VulkanSecondaryCBCompatible::kNo == fVulkanSecondaryCBCompatible ||
35              VkRTSupportsInputAttachment::kNo == fVkRTSupportsInputAttachment);
36     SkASSERT(Textureable::kNo == fIsTextureable ||
37              VulkanSecondaryCBCompatible::kNo == fVulkanSecondaryCBCompatible);
38 }
39 #endif
40 
41 
operator ==(const SkSurfaceCharacterization & other) const42 bool SkSurfaceCharacterization::operator==(const SkSurfaceCharacterization& other) const {
43     if (!this->isValid() || !other.isValid()) {
44         return false;
45     }
46 
47     if (fContextInfo != other.fContextInfo) {
48         return false;
49     }
50 
51     return fCacheMaxResourceBytes == other.fCacheMaxResourceBytes &&
52            fOrigin == other.fOrigin &&
53            fImageInfo == other.fImageInfo &&
54            fBackendFormat == other.fBackendFormat &&
55            fSampleCnt == other.fSampleCnt &&
56            fIsTextureable == other.fIsTextureable &&
57            fIsMipMapped == other.fIsMipMapped &&
58            fUsesGLFBO0 == other.fUsesGLFBO0 &&
59            fVulkanSecondaryCBCompatible == other.fVulkanSecondaryCBCompatible &&
60            fIsProtected == other.fIsProtected &&
61            fSurfaceProps == other.fSurfaceProps;
62 }
63 
createResized(int width,int height) const64 SkSurfaceCharacterization SkSurfaceCharacterization::createResized(int width, int height) const {
65     const GrCaps* caps = fContextInfo->priv().caps();
66     if (!caps) {
67         return SkSurfaceCharacterization();
68     }
69 
70     if (width <= 0 || height <= 0 || width > caps->maxRenderTargetSize() ||
71         height > caps->maxRenderTargetSize()) {
72         return SkSurfaceCharacterization();
73     }
74 
75     return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
76                                      fImageInfo.makeWH(width, height), fBackendFormat, fOrigin,
77                                      fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
78                                      fVkRTSupportsInputAttachment,
79                                      fVulkanSecondaryCBCompatible,
80                                      fIsProtected, fSurfaceProps);
81 }
82 
createColorSpace(sk_sp<SkColorSpace> cs) const83 SkSurfaceCharacterization SkSurfaceCharacterization::createColorSpace(
84                                                                      sk_sp<SkColorSpace> cs) const {
85     if (!this->isValid()) {
86         return SkSurfaceCharacterization();
87     }
88 
89     return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
90                                      fImageInfo.makeColorSpace(std::move(cs)), fBackendFormat,
91                                      fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
92                                      fVkRTSupportsInputAttachment,
93                                      fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
94 }
95 
createBackendFormat(SkColorType colorType,const GrBackendFormat & backendFormat) const96 SkSurfaceCharacterization SkSurfaceCharacterization::createBackendFormat(
97                                                     SkColorType colorType,
98                                                     const GrBackendFormat& backendFormat) const {
99     if (!this->isValid()) {
100         return SkSurfaceCharacterization();
101     }
102 
103     SkImageInfo newII = fImageInfo.makeColorType(colorType);
104 
105     return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes, newII, backendFormat,
106                                      fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
107                                      fVkRTSupportsInputAttachment,
108                                      fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
109 }
110 
createFBO0(bool usesGLFBO0) const111 SkSurfaceCharacterization SkSurfaceCharacterization::createFBO0(bool usesGLFBO0) const {
112     if (!this->isValid()) {
113         return SkSurfaceCharacterization();
114     }
115 
116     // We can't create an FBO0 characterization that is textureable or has any non-gl specific flags
117     if (fIsTextureable == Textureable::kYes ||
118         fVkRTSupportsInputAttachment == VkRTSupportsInputAttachment::kYes ||
119         fVulkanSecondaryCBCompatible == VulkanSecondaryCBCompatible::kYes) {
120         return SkSurfaceCharacterization();
121     }
122 
123     return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
124                                      fImageInfo, fBackendFormat,
125                                      fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped,
126                                      usesGLFBO0 ? UsesGLFBO0::kYes : UsesGLFBO0::kNo,
127                                      fVkRTSupportsInputAttachment,
128                                      fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
129 }
130 
isCompatible(const GrBackendTexture & backendTex) const131 bool SkSurfaceCharacterization::isCompatible(const GrBackendTexture& backendTex) const {
132     if (!this->isValid() || !backendTex.isValid()) {
133         return false;
134     }
135 
136     if (fBackendFormat != backendTex.getBackendFormat()) {
137         return false;
138     }
139 
140     if (this->usesGLFBO0()) {
141         // It is a backend texture so can't be wrapping FBO0
142         return false;
143     }
144 
145     if (this->vulkanSecondaryCBCompatible()) {
146         return false;
147     }
148 
149     if (this->vkRTSupportsInputAttachment()) {
150         if (backendTex.backend() != GrBackendApi::kVulkan) {
151             return false;
152         }
153 #ifdef SK_VULKAN
154         GrVkImageInfo vkInfo;
155         if (!backendTex.getVkImageInfo(&vkInfo)) {
156             return false;
157         }
158         if (!SkToBool(vkInfo.fImageUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
159             return false;
160         }
161 #endif  // SK_VULKAN
162     }
163 
164     if (this->isMipMapped() && !backendTex.hasMipmaps()) {
165         // backend texture is allowed to have mipmaps even if the characterization doesn't require
166         // them.
167         return false;
168     }
169 
170     if (this->width() != backendTex.width() || this->height() != backendTex.height()) {
171         return false;
172     }
173 
174     if (this->isProtected() != GrProtected(backendTex.isProtected())) {
175         return false;
176     }
177 
178     return true;
179 }
180 
181 
182 #endif
183