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