xref: /aosp_15_r20/external/skia/src/gpu/ganesh/gl/GrGLAttachment.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2011 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 "src/gpu/ganesh/gl/GrGLAttachment.h"
9 
10 #include "include/core/SkString.h"
11 #include "include/core/SkTraceMemoryDump.h"
12 #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
13 #include "include/gpu/ganesh/gl/GrGLFunctions.h"
14 #include "include/gpu/ganesh/gl/GrGLInterface.h"
15 #include "src/gpu/ganesh/gl/GrGLCaps.h"
16 #include "src/gpu/ganesh/gl/GrGLDefines.h"
17 #include "src/gpu/ganesh/gl/GrGLGpu.h"
18 #include "src/gpu/ganesh/gl/GrGLUtil.h"
19 
20 #include <string>
21 
22 #define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
23 
24 #define GL_ALLOC_CALL(call)                                   \
25     [&] {                                                     \
26         if (gpu->glCaps().skipErrorChecks()) {               \
27             GR_GL_CALL(gpu->glInterface(), call);            \
28             return static_cast<GrGLenum>(GR_GL_NO_ERROR);     \
29         } else {                                              \
30             gpu->clearErrorsAndCheckForOOM();                \
31             GR_GL_CALL_NOERRCHECK(gpu->glInterface(), call); \
32             return gpu->getErrorAndCheckForOOM();            \
33         }                                                     \
34     }()
35 
renderbuffer_storage_msaa(GrGLGpu * gpu,int sampleCount,GrGLenum format,int width,int height)36 static bool renderbuffer_storage_msaa(GrGLGpu* gpu,
37                                       int sampleCount,
38                                       GrGLenum format,
39                                       int width,
40                                       int height) {
41     SkASSERT(GrGLCaps::kNone_MSFBOType != gpu->glCaps().msFBOType());
42     GrGLenum error;
43     switch (gpu->glCaps().msFBOType()) {
44         case GrGLCaps::kStandard_MSFBOType:
45             error = GL_ALLOC_CALL(RenderbufferStorageMultisample(
46                     GR_GL_RENDERBUFFER, sampleCount, format, width, height));
47             break;
48         case GrGLCaps::kES_Apple_MSFBOType:
49             error = GL_ALLOC_CALL(RenderbufferStorageMultisampleES2APPLE(
50                     GR_GL_RENDERBUFFER, sampleCount, format, width, height));
51             break;
52         case GrGLCaps::kES_EXT_MsToTexture_MSFBOType:
53         case GrGLCaps::kES_IMG_MsToTexture_MSFBOType:
54             error = GL_ALLOC_CALL(RenderbufferStorageMultisampleES2EXT(
55                     GR_GL_RENDERBUFFER, sampleCount, format, width, height));
56             break;
57         case GrGLCaps::kNone_MSFBOType:
58             SkUNREACHABLE;
59     }
60     return error == GR_GL_NO_ERROR;
61 }
62 
MakeStencil(GrGLGpu * gpu,SkISize dimensions,int sampleCnt,GrGLFormat format)63 sk_sp<GrGLAttachment> GrGLAttachment::MakeStencil(GrGLGpu* gpu,
64                                                   SkISize dimensions,
65                                                   int sampleCnt,
66                                                   GrGLFormat format) {
67     GrGLuint rbID = 0;
68 
69     GL_CALL(GenRenderbuffers(1, &rbID));
70     if (!rbID) {
71         return nullptr;
72     }
73     GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbID));
74     GrGLenum glFmt = GrGLFormatToEnum(format);
75     // we do this "if" so that we don't call the multisample
76     // version on a GL that doesn't have an MSAA extension.
77     if (sampleCnt > 1) {
78         if (!renderbuffer_storage_msaa(gpu, sampleCnt, glFmt, dimensions.width(),
79                                        dimensions.height())) {
80             GL_CALL(DeleteRenderbuffers(1, &rbID));
81             return nullptr;
82         }
83     } else {
84         GrGLenum error = GL_ALLOC_CALL(RenderbufferStorage(
85                 GR_GL_RENDERBUFFER, glFmt, dimensions.width(), dimensions.height()));
86         if (error != GR_GL_NO_ERROR) {
87             GL_CALL(DeleteRenderbuffers(1, &rbID));
88             return nullptr;
89         }
90     }
91 
92     return sk_sp<GrGLAttachment>(new GrGLAttachment(gpu,
93                                                     rbID,
94                                                     dimensions,
95                                                     GrAttachment::UsageFlags::kStencilAttachment,
96                                                     sampleCnt,
97                                                     format,
98                                                     /*label=*/"GLAttachmentMakeStencil"));
99 }
100 
MakeMSAA(GrGLGpu * gpu,SkISize dimensions,int sampleCnt,GrGLFormat format)101 sk_sp<GrGLAttachment> GrGLAttachment::MakeMSAA(GrGLGpu* gpu,
102                                                SkISize dimensions,
103                                                int sampleCnt,
104                                                GrGLFormat format) {
105     GrGLuint rbID = 0;
106 
107     GL_CALL(GenRenderbuffers(1, &rbID));
108     if (!rbID) {
109         return nullptr;
110     }
111     GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbID));
112     GrGLenum glFmt = gpu->glCaps().getRenderbufferInternalFormat(format);
113     if (!renderbuffer_storage_msaa(
114             gpu, sampleCnt, glFmt, dimensions.width(), dimensions.height())) {
115         GL_CALL(DeleteRenderbuffers(1, &rbID));
116         return nullptr;
117     }
118 
119     return sk_sp<GrGLAttachment>(new GrGLAttachment(gpu,
120                                                     rbID,
121                                                     dimensions,
122                                                     GrAttachment::UsageFlags::kColorAttachment,
123                                                     sampleCnt,
124                                                     format,
125                                                     /*label=*/"GLAttachmentMakeMSAA"));
126 }
127 
128 
onRelease()129 void GrGLAttachment::onRelease() {
130     if (0 != fRenderbufferID) {
131         GrGLGpu* gpuGL = (GrGLGpu*)this->getGpu();
132         const GrGLInterface* gl = gpuGL->glInterface();
133         GR_GL_CALL(gl, DeleteRenderbuffers(1, &fRenderbufferID));
134         fRenderbufferID = 0;
135     }
136 
137     INHERITED::onRelease();
138 }
139 
onAbandon()140 void GrGLAttachment::onAbandon() {
141     fRenderbufferID = 0;
142 
143     INHERITED::onAbandon();
144 }
145 
backendFormat() const146 GrBackendFormat GrGLAttachment::backendFormat() const {
147     return GrBackendFormats::MakeGL(GrGLFormatToEnum(fFormat), GR_GL_TEXTURE_NONE);
148 }
149 
setMemoryBacking(SkTraceMemoryDump * traceMemoryDump,const SkString & dumpName) const150 void GrGLAttachment::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
151                                       const SkString& dumpName) const {
152     SkString renderbuffer_id;
153     renderbuffer_id.appendU32(this->renderbufferID());
154     traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_renderbuffer", renderbuffer_id.c_str());
155 }
156 
onSetLabel()157 void GrGLAttachment::onSetLabel() {
158     SkASSERT(fRenderbufferID);
159     if (!this->getLabel().empty()) {
160         const std::string label = "_Skia_" + this->getLabel();
161         GrGLGpu* glGpu = static_cast<GrGLGpu*>(this->getGpu());
162         if (glGpu->glCaps().debugSupport()) {
163             GR_GL_CALL(glGpu->glInterface(),
164                        ObjectLabel(GR_GL_TEXTURE, fRenderbufferID, -1, label.c_str()));
165         }
166     }
167 }
168