예제 #1
0
PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox()
{
    if (m_recycledMailboxQueue.isEmpty())
        return PassRefPtr<MailboxInfo>();

    WebExternalTextureMailbox mailbox;
    while (!m_recycledMailboxQueue.isEmpty()) {
        mailbox = m_recycledMailboxQueue.takeLast();
        // Never have more than one mailbox in the released state.
        if (!m_recycledMailboxQueue.isEmpty())
            deleteMailbox(mailbox);
    }

    RefPtr<MailboxInfo> mailboxInfo;
    for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
        if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) {
            mailboxInfo = m_textureMailboxes[i];
            break;
        }
    }
    ASSERT(mailboxInfo);

    if (mailboxInfo->mailbox.validSyncToken) {
        m_gl->WaitSyncTokenCHROMIUM(mailboxInfo->mailbox.syncToken);
        mailboxInfo->mailbox.validSyncToken = false;
    }

    if (mailboxInfo->size != m_size) {
        resizeTextureMemory(&mailboxInfo->textureInfo, m_size);
        mailboxInfo->size = m_size;
    }

    return mailboxInfo.release();
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
void DrawingBuffer::deleteMailbox(const WebExternalTextureMailbox& mailbox)
{
    for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
        if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) {
            if (mailbox.validSyncToken)
                m_gl->WaitSyncTokenCHROMIUM(mailbox.syncToken);

            deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo);

            m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureId);
            m_textureMailboxes.remove(i);
            return;
        }
    }
    ASSERT_NOT_REACHED();
}
예제 #5
0
void DrawingBuffer::mailboxReleased(const WebExternalTextureMailbox& mailbox, bool lostResource)
{
    if (m_destructionInProgress || m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource || m_isHidden) {
        mailboxReleasedWithoutRecycling(mailbox);
        return;
    }

    for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
        RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i];
        if (nameEquals(mailboxInfo->mailbox, mailbox)) {
            memcpy(mailboxInfo->mailbox.syncToken, mailbox.syncToken,
                sizeof(mailboxInfo->mailbox.syncToken));
            mailboxInfo->mailbox.validSyncToken = mailbox.validSyncToken;
            ASSERT(mailboxInfo->m_parentDrawingBuffer.get() == this);
            mailboxInfo->m_parentDrawingBuffer.clear();
            m_recycledMailboxQueue.prepend(mailboxInfo->mailbox);
            return;
        }
    }
    ASSERT_NOT_REACHED();
}