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