示例#1
0
// Note: this need to be called within the lock and on the UI thread.
// Only called by updateDirtyTiles() and emptyQueue() for now
void TransferQueue::cleanupPendingDiscard()
{
    int index = getNextTransferQueueIndex();

    for (int i = 0 ; i < m_transferQueueSize; i++) {
        if (m_transferQueue[index].status == pendingDiscard) {
            // No matter what the current upload type is, as long as there has
            // been a Surf Tex enqueue operation, this updateTexImage need to
            // be called to keep things in sync.
            if (m_transferQueue[index].uploadType == GpuUpload) {
                status_t result = m_sharedSurfaceTexture->updateTexImage();
                if (result != OK)
                    ALOGE("unexpected error: updateTexImage return %d", result);
            }

            // since tiles in the queue may be from another webview, remove
            // their textures so that they will be repainted / retransferred
            Tile* tile = m_transferQueue[index].savedTilePtr;
            TileTexture* texture = m_transferQueue[index].savedTileTexturePtr;
            if (tile && texture && texture->owner() == tile) {
                // since tile destruction removes textures on the UI thread, the
                // texture->owner ptr guarantees the tile is valid
                tile->discardBackTexture();
                ALOGV("transfer queue discarded tile %p, removed texture", tile);
            }
            clearItemInTranferQueue(index);
        }
        index = (index + 1) % m_transferQueueSize;
    }
}
示例#2
0
// This function must be called inside the m_transferQueueItemLocks, for the
// wait, m_interruptedByRemovingOp and getHasGLContext().
// Only called by updateQueueWithBitmap() for now.
bool TransferQueue::readyForUpdate()
{
    if (!getHasGLContext())
        return false;
    // Don't use a while loop since when the WebView tear down, the emptyCount
    // will still be 0, and we bailed out b/c of GL context lost.
    if (!m_emptyItemCount) {
        if (m_interruptedByRemovingOp)
            return false;
        m_transferQueueItemCond.wait(m_transferQueueItemLocks);
        if (m_interruptedByRemovingOp)
            return false;
    }

    if (!getHasGLContext())
        return false;

    // Disable this wait until we figure out why this didn't work on some
    // drivers b/5332112.
#if 0
    if (m_currentUploadType == GpuUpload
        && m_currentDisplay != EGL_NO_DISPLAY) {
        // Check the GPU fence
        EGLSyncKHR syncKHR = m_transferQueue[getNextTransferQueueIndex()].m_syncKHR;
        if (syncKHR != EGL_NO_SYNC_KHR)
            eglClientWaitSyncKHR(m_currentDisplay,
                                 syncKHR,
                                 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                 EGL_FOREVER_KHR);
    }
    GLUtils::checkEglError("WaitSyncKHR");
#endif

    return true;
}
示例#3
0
// Call on UI thread to copy from the shared Surface Texture to the Tile's texture.
void TransferQueue::updateDirtyTiles()
{
    android::Mutex::Autolock lock(m_transferQueueItemLocks);

    cleanupPendingDiscard();
    if (!getHasGLContext())
        setHasGLContext(true);

    // Check the pure color tile first, since it is simpler.
    updatePureColorTiles();

    // Start from the oldest item, we call the updateTexImage to retrive
    // the texture and blit that into each Tile's texture.
    const int nextItemIndex = getNextTransferQueueIndex();
    int index = nextItemIndex;
    bool usedFboForUpload = false;
    for (int k = 0; k < m_transferQueueSize ; k++) {
        if (m_transferQueue[index].status == pendingBlit) {
            bool obsoleteTile = checkObsolete(&m_transferQueue[index]);
            // Save the needed info, update the Surf Tex, clean up the item in
            // the queue. Then either move on to next item or copy the content.
            TileTexture* destTexture = 0;
            if (!obsoleteTile)
                destTexture = m_transferQueue[index].savedTilePtr->backTexture();

            if (m_transferQueue[index].uploadType == GpuUpload) {
                status_t result = m_sharedSurfaceTexture->updateTexImage();
                if (result != OK)
                    ALOGE("unexpected error: updateTexImage return %d", result);
            }

            if (obsoleteTile) {
                ALOGV("Warning: the texture is obsolete for this baseTile");
                clearItemInTranferQueue(index);
                index = (index + 1) % m_transferQueueSize;
                continue;
            }

            // guarantee that we have a texture to blit into
            destTexture->requireGLTexture();
            GLUtils::checkGlError("before blitTileFromQueue");
            if (m_transferQueue[index].uploadType == CpuUpload) {
                // Here we just need to upload the bitmap content to the GL Texture
                GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId,
                                                 *m_transferQueue[index].bitmap);
            } else {
                if (!usedFboForUpload) {
                    saveGLState();
                    usedFboForUpload = true;
                }
                blitTileFromQueue(m_fboID, destTexture, m_sharedSurfaceTextureId,
                                  m_sharedSurfaceTexture->getCurrentTextureTarget(),
                                  index);
            }

            destTexture->setPure(false);
            destTexture->transferComplete();
            clearItemInTranferQueue(index);
            ALOGV("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d",
                  m_transferQueue[index].savedTilePtr,
                  destTexture,
                  destTexture->m_ownTextureId);
        }
        index = (index + 1) % m_transferQueueSize;
    }

    // Clean up FBO setup. Doing this for both CPU/GPU upload can make the
    // dynamic switch possible. Moving this out from the loop can save some
    // milli-seconds.
    if (usedFboForUpload) {
        restoreGLState();
        GLUtils::checkGlError("updateDirtyTiles");
    }

    m_emptyItemCount = m_transferQueueSize;
    m_transferQueueItemCond.signal();
}
示例#4
0
// Call on UI thread to copy from the shared Surface Texture to the BaseTile's texture.
void TransferQueue::updateDirtyBaseTiles()
{
    android::Mutex::Autolock lock(m_transferQueueItemLocks);

    cleanupTransportQueue();
    if (!getHasGLContext())
        setHasGLContext(true);

    // Start from the oldest item, we call the updateTexImage to retrive
    // the texture and blit that into each BaseTile's texture.
    const int nextItemIndex = getNextTransferQueueIndex();
    int index = nextItemIndex;
    bool usedFboForUpload = false;
    for (int k = 0; k < ST_BUFFER_NUMBER ; k++) {
        if (m_transferQueue[index].status == pendingBlit) {
            bool obsoleteBaseTile = checkObsolete(index);
            // Save the needed info, update the Surf Tex, clean up the item in
            // the queue. Then either move on to next item or copy the content.
            BaseTileTexture* destTexture = 0;
            if (!obsoleteBaseTile)
                destTexture = m_transferQueue[index].savedBaseTilePtr->backTexture();
            if (m_transferQueue[index].uploadType == GpuUpload) {
                status_t result = m_sharedSurfaceTexture->updateTexImage();
                if (result != OK)
                    XLOGC("unexpected error: updateTexImage return %d", result);
            }
            m_transferQueue[index].savedBaseTilePtr = 0;
            m_transferQueue[index].status = emptyItem;
            if (obsoleteBaseTile) {
                XLOG("Warning: the texture is obsolete for this baseTile");
                index = (index + 1) % ST_BUFFER_NUMBER;
                continue;
            }

            // guarantee that we have a texture to blit into
            destTexture->requireGLTexture();

            if (m_transferQueue[index].uploadType == CpuUpload) {
                // Here we just need to upload the bitmap content to the GL Texture
                GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId, 0, 0,
                                                 *m_transferQueue[index].bitmap);
            } else {
                if (!usedFboForUpload) {
                    saveGLState();
                    usedFboForUpload = true;
                }
                blitTileFromQueue(m_fboID, destTexture,
                                  m_sharedSurfaceTextureId,
                                  m_sharedSurfaceTexture->getCurrentTextureTarget(),
                                  index);
            }

            // After the base tile copied into the GL texture, we need to
            // update the texture's info such that at draw time, readyFor
            // will find the latest texture's info
            // We don't need a map any more, each texture contains its own
            // texturesTileInfo.
            destTexture->setOwnTextureTileInfoFromQueue(&m_transferQueue[index].tileInfo);

            XLOG("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d",
                 m_transferQueue[index].tileInfo.m_x,
                 m_transferQueue[index].tileInfo.m_y,
                 destTexture,
                 destTexture->m_ownTextureId);
        }
        index = (index + 1) % ST_BUFFER_NUMBER;
    }

    // Clean up FBO setup. Doing this for both CPU/GPU upload can make the
    // dynamic switch possible. Moving this out from the loop can save some
    // milli-seconds.
    if (usedFboForUpload) {
        glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO
        restoreGLState();
        GLUtils::checkGlError("updateDirtyBaseTiles");
    }

    m_emptyItemCount = ST_BUFFER_NUMBER;
    m_transferQueueItemCond.signal();
}