void IncompleteTextureSet::onDestroy(const gl::Context *context) { // Clear incomplete textures. for (auto &incompleteTexture : mIncompleteTextures) { ANGLE_SWALLOW_ERR(incompleteTexture.second->onDestroy(context)); incompleteTexture.second.set(context, nullptr); } mIncompleteTextures.clear(); }
const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl::Context *context) { gl::DrawBufferMask activeProgramOutputs = context->getContextState().getState().getProgram()->getActiveOutputVariables(); if (mColorAttachmentsForRender.valid() && mCurrentActiveProgramOutputs == activeProgramOutputs) { return mColorAttachmentsForRender.value(); } // Does not actually free memory gl::AttachmentList colorAttachmentsForRender; const auto &colorAttachments = mState.getColorAttachments(); const auto &drawBufferStates = mState.getDrawBufferStates(); const auto &workarounds = mRenderer->getWorkarounds(); for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) { GLenum drawBufferState = drawBufferStates[attachmentIndex]; const gl::FramebufferAttachment &colorAttachment = colorAttachments[attachmentIndex]; if (colorAttachment.isAttached() && drawBufferState != GL_NONE && activeProgramOutputs[attachmentIndex]) { ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex)); colorAttachmentsForRender.push_back(&colorAttachment); } else if (!workarounds.mrtPerfWorkaround) { colorAttachmentsForRender.push_back(nullptr); } } // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel // shader. We add a dummy texture as render target in such case. if (mRenderer->getWorkarounds().addDummyTextureNoRenderTarget && colorAttachmentsForRender.empty() && activeProgramOutputs.any()) { static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32, "Size of active program outputs should less or equal than 32."); const GLuint activeProgramLocation = static_cast<GLuint>( gl::ScanForward(static_cast<uint32_t>(activeProgramOutputs.bits()))); if (mDummyAttachment.isAttached() && (mDummyAttachment.getBinding() - GL_COLOR_ATTACHMENT0) == activeProgramLocation) { colorAttachmentsForRender.push_back(&mDummyAttachment); } else { // Remove dummy attachment to prevents us from leaking it, and the program may require // it to be attached to a new binding point. if (mDummyAttachment.isAttached()) { mDummyAttachment.detach(context); } gl::Texture *dummyTex = nullptr; // TODO(Jamie): Handle error if dummy texture can't be created. ANGLE_SWALLOW_ERR(mRenderer->getIncompleteTexture(context, GL_TEXTURE_2D, &dummyTex)); if (dummyTex) { gl::ImageIndex index = gl::ImageIndex::Make2D(0); mDummyAttachment = gl::FramebufferAttachment( context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + activeProgramLocation, index, dummyTex); colorAttachmentsForRender.push_back(&mDummyAttachment); } } } mColorAttachmentsForRender = std::move(colorAttachmentsForRender); mCurrentActiveProgramOutputs = activeProgramOutputs; return mColorAttachmentsForRender.value(); }
void SurfaceDeleter::operator()(Surface *surface) { ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay)); }