void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailbox, bool lostResource) { bool contextLost = !m_isSurfaceValid || m_contextProvider->context3d()->isContextLost(); ASSERT(m_mailboxes.last().m_parentLayerBridge.get() == this); // Mailboxes are typically released in FIFO order, so we iterate // from the end of m_mailboxes. auto releasedMailboxInfo = m_mailboxes.end(); auto firstMailbox = m_mailboxes.begin(); while (true) { --releasedMailboxInfo; if (nameEquals(releasedMailboxInfo->m_mailbox, mailbox)) { break; } if (releasedMailboxInfo == firstMailbox) { // Reached last entry without finding a match, should never happen. // FIXME: This used to be an ASSERT, and was (temporarily?) changed to a // CRASH to facilitate the investigation of crbug.com/443898. CRASH(); } } if (!contextLost) { // Invalidate texture state in case the compositor altered it since the copy-on-write. if (releasedMailboxInfo->m_image) { if (mailbox.syncPoint) { context()->waitSyncPoint(mailbox.syncPoint); } GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); if (texture) { if (lostResource) { texture->abandon(); } else { texture->textureParamsModified(); } } } } RefPtr<Canvas2DLayerBridge> selfRef; if (m_destructionInProgress) { // To avoid memory use after free, take a scoped self-reference // to postpone destruction until the end of this function. selfRef = this; } // The destruction of 'releasedMailboxInfo' will: // 1) Release the self reference held by the mailboxInfo, which may trigger // the self-destruction of this Canvas2DLayerBridge // 2) Release the SkImage, which will return the texture to skia's scratch // texture pool. m_mailboxes.remove(releasedMailboxInfo); Canvas2DLayerManager::get().layerTransientResourceAllocationChanged(this); }
void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailbox, bool lostResource) { ASSERT(isAccelerated()); bool contextLost = !m_surface || m_contextProvider->context3d()->isContextLost(); ASSERT(m_mailboxes.last().m_parentLayerBridge.get() == this); // Mailboxes are typically released in FIFO order, so we iterate // from the end of m_mailboxes. auto releasedMailboxInfo = m_mailboxes.end(); auto firstMailbox = m_mailboxes.begin(); while (true) { --releasedMailboxInfo; if (nameEquals(releasedMailboxInfo->m_mailbox, mailbox)) { break; } ASSERT(releasedMailboxInfo != firstMailbox); } if (!contextLost) { // Invalidate texture state in case the compositor altered it since the copy-on-write. if (releasedMailboxInfo->m_image) { if (mailbox.validSyncToken) { context()->waitSyncToken(mailbox.syncToken); } GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); if (texture) { if (lostResource) { texture->abandon(); } else { texture->textureParamsModified(); } } } } RefPtr<Canvas2DLayerBridge> selfRef; if (m_destructionInProgress) { // To avoid memory use after free, take a scoped self-reference // to postpone destruction until the end of this function. selfRef = this; } // The destruction of 'releasedMailboxInfo' will: // 1) Release the self reference held by the mailboxInfo, which may trigger // the self-destruction of this Canvas2DLayerBridge // 2) Release the SkImage, which will return the texture to skia's scratch // texture pool. m_mailboxes.remove(releasedMailboxInfo); }