1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLRenderTarget.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/core/SkTraceMemoryDump.h"
11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrBackendUtils.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrGpuResourcePriv.h"
15cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h"
16cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLGpu.h"
17cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLUtil.h"
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci#define GPUGL static_cast<GrGLGpu*>(this->getGpu())
20cb93a386Sopenharmony_ci#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
21cb93a386Sopenharmony_ci#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(GPUGL->glInterface(), RET, X)
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
24cb93a386Sopenharmony_ci// Constructor for wrapped render targets.
25cb93a386Sopenharmony_ciGrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu,
26cb93a386Sopenharmony_ci                                   const SkISize& dimensions,
27cb93a386Sopenharmony_ci                                   GrGLFormat format,
28cb93a386Sopenharmony_ci                                   int sampleCount,
29cb93a386Sopenharmony_ci                                   const IDs& ids,
30cb93a386Sopenharmony_ci                                   sk_sp<GrGLAttachment> stencil)
31cb93a386Sopenharmony_ci        : GrSurface(gpu, dimensions, GrProtected::kNo)
32cb93a386Sopenharmony_ci        , INHERITED(gpu, dimensions, sampleCount, GrProtected::kNo, std::move(stencil)) {
33cb93a386Sopenharmony_ci    this->init(format, ids);
34cb93a386Sopenharmony_ci    this->setFlags(gpu->glCaps(), ids);
35cb93a386Sopenharmony_ci    this->registerWithCacheWrapped(GrWrapCacheable::kNo);
36cb93a386Sopenharmony_ci}
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ciGrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu,
39cb93a386Sopenharmony_ci                                   const SkISize& dimensions,
40cb93a386Sopenharmony_ci                                   GrGLFormat format,
41cb93a386Sopenharmony_ci                                   int sampleCount,
42cb93a386Sopenharmony_ci                                   const IDs& ids)
43cb93a386Sopenharmony_ci        : GrSurface(gpu, dimensions, GrProtected::kNo)
44cb93a386Sopenharmony_ci        , INHERITED(gpu, dimensions, sampleCount, GrProtected::kNo) {
45cb93a386Sopenharmony_ci    this->init(format, ids);
46cb93a386Sopenharmony_ci    this->setFlags(gpu->glCaps(), ids);
47cb93a386Sopenharmony_ci}
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ciinline void GrGLRenderTarget::setFlags(const GrGLCaps& glCaps, const IDs& idDesc) {
50cb93a386Sopenharmony_ci    if ((fMultisampleFBOID | fSingleSampleFBOID) == 0) {
51cb93a386Sopenharmony_ci        this->setGLRTFBOIDIs0();
52cb93a386Sopenharmony_ci    }
53cb93a386Sopenharmony_ci}
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_civoid GrGLRenderTarget::init(GrGLFormat format, const IDs& idDesc) {
56cb93a386Sopenharmony_ci    fMultisampleFBOID = idDesc.fMultisampleFBOID;
57cb93a386Sopenharmony_ci    fSingleSampleFBOID = idDesc.fSingleSampleFBOID;
58cb93a386Sopenharmony_ci    fMSColorRenderbufferID = idDesc.fMSColorRenderbufferID;
59cb93a386Sopenharmony_ci    fRTFBOOwnership = idDesc.fRTFBOOwnership;
60cb93a386Sopenharmony_ci    fRTFormat = format;
61cb93a386Sopenharmony_ci    fTotalMemorySamplesPerPixel = idDesc.fTotalMemorySamplesPerPixel;
62cb93a386Sopenharmony_ci}
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_ciGrGLFormat stencil_bits_to_format(int stencilBits) {
65cb93a386Sopenharmony_ci    SkASSERT(stencilBits);
66cb93a386Sopenharmony_ci    switch (stencilBits) {
67cb93a386Sopenharmony_ci        case 8:
68cb93a386Sopenharmony_ci            // We pick the packed format here so when we query total size we are at least not
69cb93a386Sopenharmony_ci            // underestimating the total size of the stencil buffer. However, in reality this
70cb93a386Sopenharmony_ci            // rarely matters since we usually don't care about the size of wrapped objects.
71cb93a386Sopenharmony_ci            return GrGLFormat::kDEPTH24_STENCIL8;
72cb93a386Sopenharmony_ci        case 16:
73cb93a386Sopenharmony_ci            return GrGLFormat::kSTENCIL_INDEX16;
74cb93a386Sopenharmony_ci        default:
75cb93a386Sopenharmony_ci            SkASSERT(false);
76cb93a386Sopenharmony_ci            return GrGLFormat::kUnknown;
77cb93a386Sopenharmony_ci    }
78cb93a386Sopenharmony_ci}
79cb93a386Sopenharmony_ci
80cb93a386Sopenharmony_cisk_sp<GrGLRenderTarget> GrGLRenderTarget::MakeWrapped(GrGLGpu* gpu,
81cb93a386Sopenharmony_ci                                                      const SkISize& dimensions,
82cb93a386Sopenharmony_ci                                                      GrGLFormat format,
83cb93a386Sopenharmony_ci                                                      int sampleCount,
84cb93a386Sopenharmony_ci                                                      const IDs& idDesc,
85cb93a386Sopenharmony_ci                                                      int stencilBits) {
86cb93a386Sopenharmony_ci    sk_sp<GrGLAttachment> sb;
87cb93a386Sopenharmony_ci    if (stencilBits) {
88cb93a386Sopenharmony_ci        // We pick a "fake" actual format that matches the number of stencil bits. When wrapping
89cb93a386Sopenharmony_ci        // an FBO with some number of stencil bits all we care about in the future is that we have
90cb93a386Sopenharmony_ci        // a format with the same number of stencil bits. We don't even directly use the format or
91cb93a386Sopenharmony_ci        // any other properties. Thus it is fine for us to just assign an arbitrary format that
92cb93a386Sopenharmony_ci        // matches the stencil bit count.
93cb93a386Sopenharmony_ci        GrGLFormat sFmt = stencil_bits_to_format(stencilBits);
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci        // We don't have the actual renderbufferID but we need to make an attachment for the stencil
96cb93a386Sopenharmony_ci        // so we just set it to an invalid value of 0 to make sure we don't explicitly use it or try
97cb93a386Sopenharmony_ci        // and delete it.
98cb93a386Sopenharmony_ci        sb = GrGLAttachment::MakeWrappedRenderBuffer(gpu,
99cb93a386Sopenharmony_ci                                                     /*renderbufferID=*/0,
100cb93a386Sopenharmony_ci                                                     dimensions,
101cb93a386Sopenharmony_ci                                                     GrAttachment::UsageFlags::kStencilAttachment,
102cb93a386Sopenharmony_ci                                                     sampleCount,
103cb93a386Sopenharmony_ci                                                     sFmt);
104cb93a386Sopenharmony_ci    }
105cb93a386Sopenharmony_ci    return sk_sp<GrGLRenderTarget>(
106cb93a386Sopenharmony_ci            new GrGLRenderTarget(gpu, dimensions, format, sampleCount, idDesc, std::move(sb)));
107cb93a386Sopenharmony_ci}
108cb93a386Sopenharmony_ci
109cb93a386Sopenharmony_ciGrBackendRenderTarget GrGLRenderTarget::getBackendRenderTarget() const {
110cb93a386Sopenharmony_ci    bool useMultisampleFBO = (this->numSamples() > 1);
111cb93a386Sopenharmony_ci    GrGLFramebufferInfo fbi;
112cb93a386Sopenharmony_ci    fbi.fFBOID = (useMultisampleFBO) ? fMultisampleFBOID : fSingleSampleFBOID;
113cb93a386Sopenharmony_ci    fbi.fFormat = GrGLFormatToEnum(this->format());
114cb93a386Sopenharmony_ci    int numStencilBits = 0;
115cb93a386Sopenharmony_ci    if (GrAttachment* stencil = this->getStencilAttachment(useMultisampleFBO)) {
116cb93a386Sopenharmony_ci        numStencilBits = GrBackendFormatStencilBits(stencil->backendFormat());
117cb93a386Sopenharmony_ci    }
118cb93a386Sopenharmony_ci
119cb93a386Sopenharmony_ci    return GrBackendRenderTarget(
120cb93a386Sopenharmony_ci            this->width(), this->height(), this->numSamples(), numStencilBits, fbi);
121cb93a386Sopenharmony_ci}
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ciGrBackendFormat GrGLRenderTarget::backendFormat() const {
124cb93a386Sopenharmony_ci    // We should never have a GrGLRenderTarget (even a textureable one with a target that is not
125cb93a386Sopenharmony_ci    // texture 2D.
126cb93a386Sopenharmony_ci    return GrBackendFormat::MakeGL(GrGLFormatToEnum(fRTFormat), GR_GL_TEXTURE_2D);
127cb93a386Sopenharmony_ci}
128cb93a386Sopenharmony_ci
129cb93a386Sopenharmony_cisize_t GrGLRenderTarget::onGpuMemorySize() const {
130cb93a386Sopenharmony_ci    return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
131cb93a386Sopenharmony_ci                                  fTotalMemorySamplesPerPixel, GrMipmapped::kNo);
132cb93a386Sopenharmony_ci}
133cb93a386Sopenharmony_ci
134cb93a386Sopenharmony_cibool GrGLRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMultisampleFBO) {
135cb93a386Sopenharmony_ci    // We defer attaching the new stencil buffer until the next time our framebuffer is bound.
136cb93a386Sopenharmony_ci    if (this->getStencilAttachment(useMultisampleFBO) != stencil) {
137cb93a386Sopenharmony_ci        fNeedsStencilAttachmentBind[useMultisampleFBO] = true;
138cb93a386Sopenharmony_ci    }
139cb93a386Sopenharmony_ci    return true;
140cb93a386Sopenharmony_ci}
141cb93a386Sopenharmony_ci
142cb93a386Sopenharmony_cibool GrGLRenderTarget::ensureDynamicMSAAAttachment() {
143cb93a386Sopenharmony_ci    SkASSERT(this->numSamples() == 1);
144cb93a386Sopenharmony_ci    if (fMultisampleFBOID) {
145cb93a386Sopenharmony_ci        return true;
146cb93a386Sopenharmony_ci    }
147cb93a386Sopenharmony_ci    SkASSERT(!fDynamicMSAAAttachment);
148cb93a386Sopenharmony_ci
149cb93a386Sopenharmony_ci    GrResourceProvider* resourceProvider = this->getContext()->priv().resourceProvider();
150cb93a386Sopenharmony_ci    const GrCaps& caps = *this->getGpu()->caps();
151cb93a386Sopenharmony_ci
152cb93a386Sopenharmony_ci    int internalSampleCount = caps.internalMultisampleCount(this->backendFormat());
153cb93a386Sopenharmony_ci    if (internalSampleCount <= 1) {
154cb93a386Sopenharmony_ci        return false;
155cb93a386Sopenharmony_ci    }
156cb93a386Sopenharmony_ci
157cb93a386Sopenharmony_ci    if (resourceProvider->caps()->msaaResolvesAutomatically() && this->asTexture()) {
158cb93a386Sopenharmony_ci        // We can use EXT_multisampled_render_to_texture for MSAA. We will configure the FBO as MSAA
159cb93a386Sopenharmony_ci        // or not during bindFBO().
160cb93a386Sopenharmony_ci        fMultisampleFBOID = fSingleSampleFBOID;
161cb93a386Sopenharmony_ci        return true;
162cb93a386Sopenharmony_ci    }
163cb93a386Sopenharmony_ci
164cb93a386Sopenharmony_ci    GL_CALL(GenFramebuffers(1, &fMultisampleFBOID));
165cb93a386Sopenharmony_ci    if (!fMultisampleFBOID) {
166cb93a386Sopenharmony_ci        return false;
167cb93a386Sopenharmony_ci    }
168cb93a386Sopenharmony_ci
169cb93a386Sopenharmony_ci    this->getGLGpu()->bindFramebuffer(GR_GL_FRAMEBUFFER, fMultisampleFBOID);
170cb93a386Sopenharmony_ci
171cb93a386Sopenharmony_ci    fDynamicMSAAAttachment.reset(
172cb93a386Sopenharmony_ci            static_cast<GrGLAttachment*>(resourceProvider->getDiscardableMSAAAttachment(
173cb93a386Sopenharmony_ci                    this->dimensions(), this->backendFormat(), internalSampleCount,
174cb93a386Sopenharmony_ci                    GrProtected(this->isProtected()), GrMemoryless::kNo).release()));
175cb93a386Sopenharmony_ci    if (!fDynamicMSAAAttachment) {
176cb93a386Sopenharmony_ci        return false;
177cb93a386Sopenharmony_ci    }
178cb93a386Sopenharmony_ci
179cb93a386Sopenharmony_ci    GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_RENDERBUFFER,
180cb93a386Sopenharmony_ci                                    fDynamicMSAAAttachment->renderbufferID()));
181cb93a386Sopenharmony_ci    return true;
182cb93a386Sopenharmony_ci}
183cb93a386Sopenharmony_ci
184cb93a386Sopenharmony_civoid GrGLRenderTarget::bindInternal(GrGLenum fboTarget, bool useMultisampleFBO) {
185cb93a386Sopenharmony_ci    GrGLuint fboId = useMultisampleFBO ? fMultisampleFBOID : fSingleSampleFBOID;
186cb93a386Sopenharmony_ci    this->getGLGpu()->bindFramebuffer(fboTarget, fboId);
187cb93a386Sopenharmony_ci
188cb93a386Sopenharmony_ci    if (fSingleSampleFBOID != 0 &&
189cb93a386Sopenharmony_ci        fSingleSampleFBOID == fMultisampleFBOID &&
190cb93a386Sopenharmony_ci        useMultisampleFBO != fDMSAARenderToTextureFBOIsMultisample) {
191cb93a386Sopenharmony_ci        auto* glTex = static_cast<GrGLTexture*>(this->asTexture());
192cb93a386Sopenharmony_ci        if (this->getGLGpu()->glCaps().bindTexture0WhenChangingTextureFBOMultisampleCount()) {
193cb93a386Sopenharmony_ci            GL_CALL(FramebufferTexture2D(fboTarget,
194cb93a386Sopenharmony_ci                                         GR_GL_COLOR_ATTACHMENT0,
195cb93a386Sopenharmony_ci                                         GR_GL_TEXTURE_2D,
196cb93a386Sopenharmony_ci                                         0 /*texture*/,
197cb93a386Sopenharmony_ci                                         0 /*mipMapLevel*/));
198cb93a386Sopenharmony_ci        }
199cb93a386Sopenharmony_ci        if (useMultisampleFBO) {
200cb93a386Sopenharmony_ci            int internalSampleCount =
201cb93a386Sopenharmony_ci                    this->getGpu()->caps()->internalMultisampleCount(this->backendFormat());
202cb93a386Sopenharmony_ci            GL_CALL(FramebufferTexture2DMultisample(fboTarget,
203cb93a386Sopenharmony_ci                                                    GR_GL_COLOR_ATTACHMENT0,
204cb93a386Sopenharmony_ci                                                    glTex->target(),
205cb93a386Sopenharmony_ci                                                    glTex->textureID(),
206cb93a386Sopenharmony_ci                                                    0 /*mipMapLevel*/,
207cb93a386Sopenharmony_ci                                                    internalSampleCount));
208cb93a386Sopenharmony_ci        } else {
209cb93a386Sopenharmony_ci            GL_CALL(FramebufferTexture2D(fboTarget,
210cb93a386Sopenharmony_ci                                         GR_GL_COLOR_ATTACHMENT0,
211cb93a386Sopenharmony_ci                                         glTex->target(),
212cb93a386Sopenharmony_ci                                         glTex->textureID(),
213cb93a386Sopenharmony_ci                                         0 /*mipMapLevel*/));
214cb93a386Sopenharmony_ci        }
215cb93a386Sopenharmony_ci        fDMSAARenderToTextureFBOIsMultisample = useMultisampleFBO;
216cb93a386Sopenharmony_ci        fNeedsStencilAttachmentBind[useMultisampleFBO] = true;
217cb93a386Sopenharmony_ci    }
218cb93a386Sopenharmony_ci
219cb93a386Sopenharmony_ci    // Make sure the stencil attachment is valid. Even though a color buffer op doesn't use stencil,
220cb93a386Sopenharmony_ci    // our FBO still needs to be "framebuffer complete".
221cb93a386Sopenharmony_ci    if (fNeedsStencilAttachmentBind[useMultisampleFBO]) {
222cb93a386Sopenharmony_ci        if (auto stencil = this->getStencilAttachment(useMultisampleFBO)) {
223cb93a386Sopenharmony_ci            const GrGLAttachment* glStencil = static_cast<const GrGLAttachment*>(stencil);
224cb93a386Sopenharmony_ci            GL_CALL(FramebufferRenderbuffer(fboTarget,
225cb93a386Sopenharmony_ci                                            GR_GL_STENCIL_ATTACHMENT,
226cb93a386Sopenharmony_ci                                            GR_GL_RENDERBUFFER,
227cb93a386Sopenharmony_ci                                            glStencil->renderbufferID()));
228cb93a386Sopenharmony_ci            if (GrGLFormatIsPackedDepthStencil(glStencil->format())) {
229cb93a386Sopenharmony_ci                GL_CALL(FramebufferRenderbuffer(fboTarget,
230cb93a386Sopenharmony_ci                                                GR_GL_DEPTH_ATTACHMENT,
231cb93a386Sopenharmony_ci                                                GR_GL_RENDERBUFFER,
232cb93a386Sopenharmony_ci                                                glStencil->renderbufferID()));
233cb93a386Sopenharmony_ci            } else {
234cb93a386Sopenharmony_ci                GL_CALL(FramebufferRenderbuffer(fboTarget,
235cb93a386Sopenharmony_ci                                                GR_GL_DEPTH_ATTACHMENT,
236cb93a386Sopenharmony_ci                                                GR_GL_RENDERBUFFER,
237cb93a386Sopenharmony_ci                                                0));
238cb93a386Sopenharmony_ci            }
239cb93a386Sopenharmony_ci        } else {
240cb93a386Sopenharmony_ci            GL_CALL(FramebufferRenderbuffer(fboTarget,
241cb93a386Sopenharmony_ci                                            GR_GL_STENCIL_ATTACHMENT,
242cb93a386Sopenharmony_ci                                            GR_GL_RENDERBUFFER,
243cb93a386Sopenharmony_ci                                            0));
244cb93a386Sopenharmony_ci            GL_CALL(FramebufferRenderbuffer(fboTarget,
245cb93a386Sopenharmony_ci                                            GR_GL_DEPTH_ATTACHMENT,
246cb93a386Sopenharmony_ci                                            GR_GL_RENDERBUFFER,
247cb93a386Sopenharmony_ci                                            0));
248cb93a386Sopenharmony_ci        }
249cb93a386Sopenharmony_ci#ifdef SK_DEBUG
250cb93a386Sopenharmony_ci        if (!this->getGLGpu()->glCaps().skipErrorChecks() &&
251cb93a386Sopenharmony_ci            !this->getGLGpu()->glCaps().rebindColorAttachmentAfterCheckFramebufferStatus()) {
252cb93a386Sopenharmony_ci            GrGLenum status;
253cb93a386Sopenharmony_ci            GL_CALL_RET(status, CheckFramebufferStatus(fboTarget));
254cb93a386Sopenharmony_ci            if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
255cb93a386Sopenharmony_ci                // This can fail if the context has been asynchronously abandoned (see
256cb93a386Sopenharmony_ci                // skbug.com/5200).
257cb93a386Sopenharmony_ci                SkDebugf("WARNING: failed to attach stencil.\n");
258cb93a386Sopenharmony_ci            }
259cb93a386Sopenharmony_ci        }
260cb93a386Sopenharmony_ci#endif
261cb93a386Sopenharmony_ci        fNeedsStencilAttachmentBind[useMultisampleFBO] = false;
262cb93a386Sopenharmony_ci    }
263cb93a386Sopenharmony_ci}
264cb93a386Sopenharmony_ci
265cb93a386Sopenharmony_civoid GrGLRenderTarget::bindForResolve(GrGLGpu::ResolveDirection resolveDirection) {
266cb93a386Sopenharmony_ci    // If the multisample FBO is nonzero, it means we always have something to resolve (even if the
267cb93a386Sopenharmony_ci    // single sample buffer is FBO 0). If it's zero, then there's nothing to resolve.
268cb93a386Sopenharmony_ci    SkASSERT(fMultisampleFBOID != 0);
269cb93a386Sopenharmony_ci
270cb93a386Sopenharmony_ci    // In the EXT_multisampled_render_to_texture case, we shouldn't be resolving anything.
271cb93a386Sopenharmony_ci    SkASSERT(!this->isMultisampledRenderToTexture());
272cb93a386Sopenharmony_ci
273cb93a386Sopenharmony_ci    if (resolveDirection == GrGLGpu::ResolveDirection::kMSAAToSingle) {
274cb93a386Sopenharmony_ci        this->bindInternal(GR_GL_READ_FRAMEBUFFER, true);
275cb93a386Sopenharmony_ci        this->bindInternal(GR_GL_DRAW_FRAMEBUFFER, false);
276cb93a386Sopenharmony_ci    } else {
277cb93a386Sopenharmony_ci        SkASSERT(resolveDirection == GrGLGpu::ResolveDirection::kSingleToMSAA);
278cb93a386Sopenharmony_ci        SkASSERT(this->getGLGpu()->glCaps().canResolveSingleToMSAA());
279cb93a386Sopenharmony_ci        this->bindInternal(GR_GL_READ_FRAMEBUFFER, false);
280cb93a386Sopenharmony_ci        this->bindInternal(GR_GL_DRAW_FRAMEBUFFER, true);
281cb93a386Sopenharmony_ci    }
282cb93a386Sopenharmony_ci}
283cb93a386Sopenharmony_ci
284cb93a386Sopenharmony_civoid GrGLRenderTarget::onRelease() {
285cb93a386Sopenharmony_ci    if (GrBackendObjectOwnership::kBorrowed != fRTFBOOwnership) {
286cb93a386Sopenharmony_ci        GrGLGpu* gpu = this->getGLGpu();
287cb93a386Sopenharmony_ci        if (fSingleSampleFBOID) {
288cb93a386Sopenharmony_ci            gpu->deleteFramebuffer(fSingleSampleFBOID);
289cb93a386Sopenharmony_ci        }
290cb93a386Sopenharmony_ci        if (fMultisampleFBOID && fMultisampleFBOID != fSingleSampleFBOID) {
291cb93a386Sopenharmony_ci            gpu->deleteFramebuffer(fMultisampleFBOID);
292cb93a386Sopenharmony_ci        }
293cb93a386Sopenharmony_ci        if (fMSColorRenderbufferID) {
294cb93a386Sopenharmony_ci            GL_CALL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
295cb93a386Sopenharmony_ci        }
296cb93a386Sopenharmony_ci    }
297cb93a386Sopenharmony_ci    fMultisampleFBOID       = 0;
298cb93a386Sopenharmony_ci    fSingleSampleFBOID      = 0;
299cb93a386Sopenharmony_ci    fMSColorRenderbufferID  = 0;
300cb93a386Sopenharmony_ci    INHERITED::onRelease();
301cb93a386Sopenharmony_ci}
302cb93a386Sopenharmony_ci
303cb93a386Sopenharmony_civoid GrGLRenderTarget::onAbandon() {
304cb93a386Sopenharmony_ci    fMultisampleFBOID       = 0;
305cb93a386Sopenharmony_ci    fSingleSampleFBOID      = 0;
306cb93a386Sopenharmony_ci    fMSColorRenderbufferID  = 0;
307cb93a386Sopenharmony_ci    INHERITED::onAbandon();
308cb93a386Sopenharmony_ci}
309cb93a386Sopenharmony_ci
310cb93a386Sopenharmony_ciGrGLGpu* GrGLRenderTarget::getGLGpu() const {
311cb93a386Sopenharmony_ci    SkASSERT(!this->wasDestroyed());
312cb93a386Sopenharmony_ci    return static_cast<GrGLGpu*>(this->getGpu());
313cb93a386Sopenharmony_ci}
314cb93a386Sopenharmony_ci
315cb93a386Sopenharmony_cibool GrGLRenderTarget::canAttemptStencilAttachment(bool useMultisampleFBO) const {
316cb93a386Sopenharmony_ci    // This cap should have been handled at a higher level.
317cb93a386Sopenharmony_ci    SkASSERT(!this->getGpu()->getContext()->priv().caps()->avoidStencilBuffers());
318cb93a386Sopenharmony_ci    // Only modify the FBO's attachments if we have created the FBO. Public APIs do not currently
319cb93a386Sopenharmony_ci    // allow for borrowed FBO ownership, so we can safely assume that if an object is owned,
320cb93a386Sopenharmony_ci    // Skia created it.
321cb93a386Sopenharmony_ci    return this->fRTFBOOwnership == GrBackendObjectOwnership::kOwned ||
322cb93a386Sopenharmony_ci           // The dmsaa attachment is always owned and always supports adding stencil.
323cb93a386Sopenharmony_ci           (this->numSamples() == 1 && useMultisampleFBO);
324cb93a386Sopenharmony_ci}
325cb93a386Sopenharmony_ci
326cb93a386Sopenharmony_civoid GrGLRenderTarget::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
327cb93a386Sopenharmony_ci    // Don't check this->fRefsWrappedObjects, as we might be the base of a GrGLTextureRenderTarget
328cb93a386Sopenharmony_ci    // which is multiply inherited from both ourselves and a texture. In these cases, one part
329cb93a386Sopenharmony_ci    // (texture, rt) may be wrapped, while the other is owned by Skia.
330cb93a386Sopenharmony_ci    bool refsWrappedRenderTargetObjects =
331cb93a386Sopenharmony_ci            this->fRTFBOOwnership == GrBackendObjectOwnership::kBorrowed;
332cb93a386Sopenharmony_ci    if (refsWrappedRenderTargetObjects && !traceMemoryDump->shouldDumpWrappedObjects()) {
333cb93a386Sopenharmony_ci        return;
334cb93a386Sopenharmony_ci    }
335cb93a386Sopenharmony_ci
336cb93a386Sopenharmony_ci    int numSamplesNotInTexture = fTotalMemorySamplesPerPixel;
337cb93a386Sopenharmony_ci    if (this->asTexture()) {
338cb93a386Sopenharmony_ci        --numSamplesNotInTexture;  // GrGLTexture::dumpMemoryStatistics accounts for 1 sample.
339cb93a386Sopenharmony_ci    }
340cb93a386Sopenharmony_ci    if (numSamplesNotInTexture >= 1) {
341cb93a386Sopenharmony_ci        size_t size = GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
342cb93a386Sopenharmony_ci                                             numSamplesNotInTexture, GrMipmapped::kNo);
343cb93a386Sopenharmony_ci
344cb93a386Sopenharmony_ci        // Due to this resource having both a texture and a renderbuffer component, dump as
345cb93a386Sopenharmony_ci        // skia/gpu_resources/resource_#/renderbuffer
346cb93a386Sopenharmony_ci        SkString resourceName = this->getResourceName();
347cb93a386Sopenharmony_ci        resourceName.append("/renderbuffer");
348cb93a386Sopenharmony_ci
349cb93a386Sopenharmony_ci        this->dumpMemoryStatisticsPriv(traceMemoryDump, resourceName, "RenderTarget", size);
350cb93a386Sopenharmony_ci
351cb93a386Sopenharmony_ci        SkString renderbuffer_id;
352cb93a386Sopenharmony_ci        renderbuffer_id.appendU32(fMSColorRenderbufferID);
353cb93a386Sopenharmony_ci        traceMemoryDump->setMemoryBacking(resourceName.c_str(), "gl_renderbuffer",
354cb93a386Sopenharmony_ci                                          renderbuffer_id.c_str());
355cb93a386Sopenharmony_ci    }
356cb93a386Sopenharmony_ci}
357