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