• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google LLC
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 #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
8 
9 #include "include/core/SkRefCnt.h"
10 #include "include/core/SkTextureCompressionType.h"
11 #include "include/gpu/ganesh/GrBackendSurface.h"
12 #include "include/gpu/ganesh/GrTypes.h"
13 #include "include/gpu/ganesh/gl/GrGLTypes.h"
14 #include "include/private/base/SkAssert.h"
15 #include "include/private/base/SkDebug.h"
16 #include "include/private/gpu/ganesh/GrTypesPriv.h"
17 #include "src/gpu/ganesh/GrBackendSurfacePriv.h"
18 #include "src/gpu/ganesh/gl/GrGLBackendSurfacePriv.h"
19 #include "src/gpu/ganesh/gl/GrGLDefines.h"
20 #include "src/gpu/ganesh/gl/GrGLTypesPriv.h"
21 #include "src/gpu/ganesh/gl/GrGLUtil.h"
22 
23 #include <algorithm>
24 #include <cstddef>
25 #include <cstdint>
26 #include <string>
27 
28 class GrGLBackendFormatData final : public GrBackendFormatData {
29 public:
GrGLBackendFormatData(GrGLenum format)30     GrGLBackendFormatData(GrGLenum format) : fGLFormat(format) {}
31 
asEnum() const32     GrGLenum asEnum() const { return fGLFormat; }
33 
34 private:
compressionType() const35     SkTextureCompressionType compressionType() const override {
36         switch (GrGLFormatFromGLEnum(fGLFormat)) {
37             case GrGLFormat::kCOMPRESSED_ETC1_RGB8:
38             case GrGLFormat::kCOMPRESSED_RGB8_ETC2:
39                 return SkTextureCompressionType::kETC2_RGB8_UNORM;
40             case GrGLFormat::kCOMPRESSED_RGB8_BC1:
41                 return SkTextureCompressionType::kBC1_RGB8_UNORM;
42             case GrGLFormat::kCOMPRESSED_RGBA8_BC1:
43                 return SkTextureCompressionType::kBC1_RGBA8_UNORM;
44             case GrGLFormat::kCOMPRESSED_ASTC_RGBA8_4x4:
45                 return SkTextureCompressionType::kASTC_RGBA8_4x4;
46             case GrGLFormat::kCOMPRESSED_ASTC_RGBA8_6x6:
47                 return SkTextureCompressionType::kASTC_RGBA8_6x6;
48             case GrGLFormat::kCOMPRESSED_ASTC_RGBA8_8x8:
49                 return SkTextureCompressionType::kASTC_RGBA8_8x8;
50             default:
51                 return SkTextureCompressionType::kNone;
52         }
53     }
54 
bytesPerBlock() const55     size_t bytesPerBlock() const override {
56         return GrGLFormatBytesPerBlock(GrGLFormatFromGLEnum(fGLFormat));
57     }
58 
stencilBits() const59     int stencilBits() const override {
60         return GrGLFormatStencilBits(GrGLFormatFromGLEnum(fGLFormat));
61     }
62 
channelMask() const63     uint32_t channelMask() const override {
64         return GrGLFormatChannels(GrGLFormatFromGLEnum(fGLFormat));
65     }
66 
desc() const67     GrColorFormatDesc desc() const override {
68         return GrGLFormatDesc(GrGLFormatFromGLEnum(fGLFormat));
69     }
70 
equal(const GrBackendFormatData * that) const71     bool equal(const GrBackendFormatData* that) const override {
72         SkASSERT(!that || that->type() == GrBackendApi::kOpenGL);
73         if (auto otherGL = static_cast<const GrGLBackendFormatData*>(that)) {
74             return fGLFormat == otherGL->fGLFormat;
75         }
76         return false;
77     }
78 
toString() const79     std::string toString() const override {
80 #if defined(SK_DEBUG) || defined(GPU_TEST_UTILS)
81         return GrGLFormatToStr(fGLFormat);
82 #else
83         return "";
84 #endif
85     }
86 
copyTo(AnyFormatData & formatData) const87     void copyTo(AnyFormatData& formatData) const override {
88         formatData.emplace<GrGLBackendFormatData>(fGLFormat);
89     }
90 
91 #if defined(SK_DEBUG)
type() const92     GrBackendApi type() const override { return GrBackendApi::kOpenGL; }
93 #endif
94 
95     GrGLenum fGLFormat;  // the sized, internal format of the GL resource
96 };
97 
gl_target_to_gr_target(GrGLenum target)98 static GrTextureType gl_target_to_gr_target(GrGLenum target) {
99     switch (target) {
100         case GR_GL_TEXTURE_NONE:
101             return GrTextureType::kNone;
102         case GR_GL_TEXTURE_2D:
103             return GrTextureType::k2D;
104         case GR_GL_TEXTURE_RECTANGLE:
105             return GrTextureType::kRectangle;
106         case GR_GL_TEXTURE_EXTERNAL:
107             return GrTextureType::kExternal;
108         default:
109             SkUNREACHABLE;
110     }
111 }
112 
get_and_cast_data(const GrBackendFormat & format)113 static const GrGLBackendFormatData* get_and_cast_data(const GrBackendFormat& format) {
114     auto data = GrBackendSurfacePriv::GetBackendData(format);
115     SkASSERT(!data || data->type() == GrBackendApi::kOpenGL);
116     return static_cast<const GrGLBackendFormatData*>(data);
117 }
118 
119 namespace GrBackendFormats {
MakeGL(GrGLenum format,GrGLenum target)120 GrBackendFormat MakeGL(GrGLenum format, GrGLenum target) {
121     return GrBackendSurfacePriv::MakeGrBackendFormat(
122             gl_target_to_gr_target(target), GrBackendApi::kOpenGL, GrGLBackendFormatData(format));
123 }
124 
AsGLFormat(const GrBackendFormat & format)125 GrGLFormat AsGLFormat(const GrBackendFormat& format) {
126     if (format.isValid() && format.backend() == GrBackendApi::kOpenGL) {
127         const GrGLBackendFormatData* data = get_and_cast_data(format);
128         SkASSERT(data);
129         return GrGLFormatFromGLEnum(data->asEnum());
130     }
131     return GrGLFormat::kUnknown;
132 }
133 
AsGLFormatEnum(const GrBackendFormat & format)134 GrGLenum AsGLFormatEnum(const GrBackendFormat& format) {
135     if (format.isValid() && format.backend() == GrBackendApi::kOpenGL) {
136         const GrGLBackendFormatData* data = get_and_cast_data(format);
137         SkASSERT(data);
138         return data->asEnum();
139     }
140     return 0;
141 }
142 }  // namespace GrBackendFormats
143 
GrGLBackendTextureData(const GrGLTextureInfo & info,sk_sp<GrGLTextureParameters> params)144 GrGLBackendTextureData::GrGLBackendTextureData(const GrGLTextureInfo& info,
145                                                sk_sp<GrGLTextureParameters> params)
146         : fGLInfo(info, params) {}
147 
copyTo(AnyTextureData & textureData) const148 void GrGLBackendTextureData::copyTo(AnyTextureData& textureData) const {
149     textureData.emplace<GrGLBackendTextureData>(fGLInfo.info(), fGLInfo.refParameters());
150 }
151 
isProtected() const152 bool GrGLBackendTextureData::isProtected() const { return fGLInfo.isProtected(); }
153 
equal(const GrBackendTextureData * that) const154 bool GrGLBackendTextureData::equal(const GrBackendTextureData* that) const {
155     SkASSERT(!that || that->type() == GrBackendApi::kOpenGL);
156     if (auto otherGL = static_cast<const GrGLBackendTextureData*>(that)) {
157         return fGLInfo.info() == otherGL->fGLInfo.info();
158     }
159     return false;
160 }
161 
isSameTexture(const GrBackendTextureData * that) const162 bool GrGLBackendTextureData::isSameTexture(const GrBackendTextureData* that) const {
163     SkASSERT(!that || that->type() == GrBackendApi::kOpenGL);
164     if (auto otherGL = static_cast<const GrGLBackendTextureData*>(that)) {
165         return fGLInfo.info().fID == otherGL->fGLInfo.info().fID;
166     }
167     return false;
168 }
169 
getBackendFormat() const170 GrBackendFormat GrGLBackendTextureData::getBackendFormat() const {
171     return GrBackendFormats::MakeGL(fGLInfo.info().fFormat, fGLInfo.info().fTarget);
172 }
173 
get_and_cast_data(const GrBackendTexture & texture)174 static const GrGLBackendTextureData* get_and_cast_data(const GrBackendTexture& texture) {
175     auto data = GrBackendSurfacePriv::GetBackendData(texture);
176     SkASSERT(!data || data->type() == GrBackendApi::kOpenGL);
177     return static_cast<const GrGLBackendTextureData*>(data);
178 }
179 
get_and_cast_data(GrBackendTexture * texture)180 static GrGLBackendTextureData* get_and_cast_data(GrBackendTexture* texture) {
181     auto data = GrBackendSurfacePriv::GetBackendData(texture);
182     SkASSERT(!data || data->type() == GrBackendApi::kOpenGL);
183     return static_cast<GrGLBackendTextureData*>(data);
184 }
185 
186 namespace GrBackendTextures {
MakeGL(int width,int height,skgpu::Mipmapped mipped,const GrGLTextureInfo & glInfo,std::string_view label)187 GrBackendTexture MakeGL(int width,
188                         int height,
189                         skgpu::Mipmapped mipped,
190                         const GrGLTextureInfo& glInfo,
191                         std::string_view label) {
192     auto tex = GrBackendSurfacePriv::MakeGrBackendTexture(
193             width,
194             height,
195             label,
196             mipped,
197             GrBackendApi::kOpenGL,
198             gl_target_to_gr_target(glInfo.fTarget),
199             GrGLBackendTextureData(glInfo, sk_make_sp<GrGLTextureParameters>()));
200     // Make no assumptions about client's texture's parameters.
201     GLTextureParametersModified(&tex);
202     return tex;
203 }
204 
MakeGL(int width,int height,skgpu::Mipmapped mipped,const GrGLTextureInfo & glInfo,sk_sp<GrGLTextureParameters> params,std::string_view label)205 GrBackendTexture MakeGL(int width,
206                         int height,
207                         skgpu::Mipmapped mipped,
208                         const GrGLTextureInfo& glInfo,
209                         sk_sp<GrGLTextureParameters> params,
210                         std::string_view label) {
211     return GrBackendSurfacePriv::MakeGrBackendTexture(width,
212                                                       height,
213                                                       label,
214                                                       mipped,
215                                                       GrBackendApi::kOpenGL,
216                                                       gl_target_to_gr_target(glInfo.fTarget),
217                                                       GrGLBackendTextureData(glInfo, params));
218 }
219 
GetGLTextureInfo(const GrBackendTexture & tex,GrGLTextureInfo * outInfo)220 bool GetGLTextureInfo(const GrBackendTexture& tex, GrGLTextureInfo* outInfo) {
221     if (!tex.isValid() || tex.backend() != GrBackendApi::kOpenGL) {
222         return false;
223     }
224     const GrGLBackendTextureData* data = get_and_cast_data(tex);
225     SkASSERT(data);
226     *outInfo = data->info().info();
227     return true;
228 }
229 
GLTextureParametersModified(GrBackendTexture * tex)230 void GLTextureParametersModified(GrBackendTexture* tex) {
231     if (tex && tex->isValid() && tex->backend() == GrBackendApi::kOpenGL) {
232         GrGLBackendTextureData* data = get_and_cast_data(tex);
233         SkASSERT(data);
234         data->info().parameters()->invalidate();
235     }
236 }
237 }  // namespace GrBackendTextures
238 
239 class GrGLBackendRenderTargetData final : public GrBackendRenderTargetData {
240 public:
GrGLBackendRenderTargetData(GrGLFramebufferInfo info)241     GrGLBackendRenderTargetData(GrGLFramebufferInfo info) : fGLInfo(info) {}
242 
info() const243     GrGLFramebufferInfo info() const { return fGLInfo; }
244 
245 private:
getBackendFormat() const246     GrBackendFormat getBackendFormat() const override {
247         return GrBackendFormats::MakeGL(fGLInfo.fFormat, GR_GL_TEXTURE_NONE);
248     }
249 
isProtected() const250     bool isProtected() const override { return fGLInfo.isProtected(); }
251 
equal(const GrBackendRenderTargetData * that) const252     bool equal(const GrBackendRenderTargetData* that) const override {
253         SkASSERT(!that || that->type() == GrBackendApi::kOpenGL);
254         if (auto otherGL = static_cast<const GrGLBackendRenderTargetData*>(that)) {
255             return fGLInfo == otherGL->fGLInfo;
256         }
257         return false;
258     }
259 
copyTo(AnyRenderTargetData & rtData) const260     void copyTo(AnyRenderTargetData& rtData) const override {
261         rtData.emplace<GrGLBackendRenderTargetData>(fGLInfo);
262     }
263 
264 #if defined(SK_DEBUG)
type() const265     GrBackendApi type() const override { return GrBackendApi::kOpenGL; }
266 #endif
267 
268     GrGLFramebufferInfo fGLInfo;
269 };
270 
get_and_cast_data(const GrBackendRenderTarget & rt)271 static const GrGLBackendRenderTargetData* get_and_cast_data(const GrBackendRenderTarget& rt) {
272     auto data = GrBackendSurfacePriv::GetBackendData(rt);
273     SkASSERT(!data || data->type() == GrBackendApi::kOpenGL);
274     return static_cast<const GrGLBackendRenderTargetData*>(data);
275 }
276 
277 namespace GrBackendRenderTargets {
278 // The GrGLTextureInfo must have a valid fFormat. If wrapping in an SkSurface we require the
279 // stencil bits to be either 0, 8 or 16.
MakeGL(int width,int height,int sampleCnt,int stencilBits,const GrGLFramebufferInfo & glInfo)280 GrBackendRenderTarget MakeGL(
281         int width, int height, int sampleCnt, int stencilBits, const GrGLFramebufferInfo& glInfo) {
282     return GrBackendSurfacePriv::MakeGrBackendRenderTarget(width,
283                                                            height,
284                                                            std::max(1, sampleCnt),
285                                                            stencilBits,
286                                                            GrBackendApi::kOpenGL,
287                                                            /*framebufferOnly=*/false,
288                                                            GrGLBackendRenderTargetData(glInfo));
289 }
290 
GetGLFramebufferInfo(const GrBackendRenderTarget & rt,GrGLFramebufferInfo * outInfo)291 bool GetGLFramebufferInfo(const GrBackendRenderTarget& rt, GrGLFramebufferInfo* outInfo) {
292     if (!rt.isValid() || rt.backend() != GrBackendApi::kOpenGL) {
293         return false;
294     }
295     const GrGLBackendRenderTargetData* data = get_and_cast_data(rt);
296     SkASSERT(data);
297     *outInfo = data->info();
298     return true;
299 }
300 
301 }  // namespace GrBackendRenderTargets
302