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