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
28static 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
55sk_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, sampleCount: sampleCnt, format: glFmt, width: dimensions.width(),
71 height: 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
93sk_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, sampleCount: sampleCnt, format: glFmt, width: dimensions.width(), height: 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
121void 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
132void GrGLAttachment::onAbandon() {
133 fRenderbufferID = 0;
134
135 INHERITED::onAbandon();
136}
137
138GrBackendFormat GrGLAttachment::backendFormat() const {
139 return GrBackendFormats::MakeGL(format: GrGLFormatToEnum(format: fFormat), GR_GL_TEXTURE_NONE);
140}
141
142void GrGLAttachment::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
143 const SkString& dumpName) const {
144 SkString renderbuffer_id;
145 renderbuffer_id.appendU32(value: this->renderbufferID());
146 traceMemoryDump->setMemoryBacking(dumpName: dumpName.c_str(), backingType: "gl_renderbuffer", backingObjectId: renderbuffer_id.c_str());
147}
148
149void 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

source code of flutter_engine/third_party/skia/src/gpu/ganesh/gl/GrGLAttachment.cpp