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