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_DEBUG
validate() const15 void SkSurfaceCharacterization::validate() const {
16     const GrCaps* caps = fContextInfo->priv().caps();
17 
18     GrColorType grCT = SkColorTypeToGrColorType(this->colorType());
19     SkASSERT(fSampleCnt && caps->isFormatAsColorTypeRenderable(grCT, fBackendFormat, fSampleCnt));
20 
21     SkASSERT(caps->areColorTypeAndFormatCompatible(grCT, fBackendFormat));
22 }
23 #endif
24 
25 
operator ==(const SkSurfaceCharacterization & other) const26 bool SkSurfaceCharacterization::operator==(const SkSurfaceCharacterization& other) const {
27     if (!this->isValid() || !other.isValid()) {
28         return false;
29     }
30 
31     if (fContextInfo != other.fContextInfo) {
32         return false;
33     }
34 
35     return fCacheMaxResourceBytes == other.fCacheMaxResourceBytes &&
36            fOrigin == other.fOrigin &&
37            fImageInfo == other.fImageInfo &&
38            fBackendFormat == other.fBackendFormat &&
39            fSampleCnt == other.fSampleCnt &&
40            fIsTextureable == other.fIsTextureable &&
41            fIsMipMapped == other.fIsMipMapped &&
42            fUsesGLFBO0 == other.fUsesGLFBO0 &&
43            fVulkanSecondaryCBCompatible == other.fVulkanSecondaryCBCompatible &&
44            fIsProtected == other.fIsProtected &&
45            fSurfaceProps == other.fSurfaceProps;
46 }
47 
createResized(int width,int height) const48 SkSurfaceCharacterization SkSurfaceCharacterization::createResized(int width, int height) const {
49     const GrCaps* caps = fContextInfo->priv().caps();
50     if (!caps) {
51         return SkSurfaceCharacterization();
52     }
53 
54     if (width <= 0 || height <= 0 || width > caps->maxRenderTargetSize() ||
55         height > caps->maxRenderTargetSize()) {
56         return SkSurfaceCharacterization();
57     }
58 
59     return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
60                                      fImageInfo.makeWH(width, height), fBackendFormat, fOrigin,
61                                      fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
62                                      fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
63 }
64 
createColorSpace(sk_sp<SkColorSpace> cs) const65 SkSurfaceCharacterization SkSurfaceCharacterization::createColorSpace(
66                                                                      sk_sp<SkColorSpace> cs) const {
67     if (!this->isValid()) {
68         return SkSurfaceCharacterization();
69     }
70 
71     return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
72                                      fImageInfo.makeColorSpace(std::move(cs)), fBackendFormat,
73                                      fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
74                                      fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
75 }
76 
createBackendFormat(SkColorType colorType,const GrBackendFormat & backendFormat) const77 SkSurfaceCharacterization SkSurfaceCharacterization::createBackendFormat(
78                                                     SkColorType colorType,
79                                                     const GrBackendFormat& backendFormat) const {
80     if (!this->isValid()) {
81         return SkSurfaceCharacterization();
82     }
83 
84     SkImageInfo newII = fImageInfo.makeColorType(colorType);
85 
86     return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes, newII, backendFormat,
87                                      fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
88                                      fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
89 }
90 
createFBO0(bool usesGLFBO0) const91 SkSurfaceCharacterization SkSurfaceCharacterization::createFBO0(bool usesGLFBO0) const {
92     if (!this->isValid()) {
93         return SkSurfaceCharacterization();
94     }
95 
96     return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
97                                      fImageInfo, fBackendFormat,
98                                      fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped,
99                                      usesGLFBO0 ? UsesGLFBO0::kYes : UsesGLFBO0::kNo,
100                                      fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
101 }
102 
isCompatible(const GrBackendTexture & backendTex) const103 bool SkSurfaceCharacterization::isCompatible(const GrBackendTexture& backendTex) const {
104     if (!this->isValid() || !backendTex.isValid()) {
105         return false;
106     }
107 
108     if (fBackendFormat != backendTex.getBackendFormat()) {
109         return false;
110     }
111 
112     if (this->usesGLFBO0()) {
113         // It is a backend texture so can't be wrapping FBO0
114         return false;
115     }
116 
117     if (this->vulkanSecondaryCBCompatible()) {
118         return false;
119     }
120 
121     if (this->isMipMapped() && !backendTex.hasMipMaps()) {
122         // backend texture is allowed to have mipmaps even if the characterization doesn't require
123         // them.
124         return false;
125     }
126 
127     if (this->width() != backendTex.width() || this->height() != backendTex.height()) {
128         return false;
129     }
130 
131     if (this->isProtected() != GrProtected(backendTex.isProtected())) {
132         return false;
133     }
134 
135     return true;
136 }
137 
138 
139 #endif
140