Exemple #1
0
void TiledLayerChromium::reserveTextures()
{
    updateBounds();

    const IntRect& layerRect = visibleLayerRect();
    if (layerRect.isEmpty() || !m_tiler->numTiles())
        return;

    int left, top, right, bottom;
    m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom);

    createTextureUpdaterIfNeeded();
    for (int j = top; j <= bottom; ++j) {
        for (int i = left; i <= right; ++i) {
            UpdatableTile* tile = tileAt(i, j);
            if (!tile)
                tile = createTile(i, j);

            if (!tile->managedTexture()->isValid(m_tiler->tileSize(), m_textureFormat))
                tile->m_dirtyRect = m_tiler->tileRect(tile);

            if (!tile->managedTexture()->reserve(m_tiler->tileSize(), m_textureFormat))
                return;
        }
    }
}
Exemple #2
0
void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int right, int bottom, const CCOcclusionTracker* occlusion)
{
    createTextureUpdaterIfNeeded();

    // Create tiles as needed, expanding a dirty rect to contain all
    // the dirty regions currently being drawn. All dirty tiles that are to be painted
    // get their m_updateRect set to m_dirtyRect and m_dirtyRect cleared. This way if
    // invalidateRect is invoked during prepareToUpdate we don't lose the request.
    IntRect dirtyLayerRect;
    for (int j = top; j <= bottom; ++j) {
        for (int i = left; i <= right; ++i) {
            UpdatableTile* tile = tileAt(i, j);
            if (!tile)
                tile = createTile(i, j);

            // When not idle painting, if the visible region of the tile is occluded, don't reserve a texture or mark it for update.
            // If any part of the tile is visible, then we need to paint it so the tile is pushed to the impl thread.
            // This will also avoid painting the tile in the next loop, below.
            if (!idle && occlusion) {
                IntRect visibleTileRect = intersection(m_tiler->tileBounds(i, j), visibleLayerRect());
                if (occlusion->occluded(this, visibleTileRect))
                    continue;
            }

            // FIXME: Decide if partial update should be allowed based on cost
            // of update. https://bugs.webkit.org/show_bug.cgi?id=77376
            if (tileOnlyNeedsPartialUpdate(tile) && layerTreeHost() && layerTreeHost()->requestPartialTextureUpdate())
                tile->m_partialUpdate = true;
            else if (tileNeedsBufferedUpdate(tile) && layerTreeHost())
                layerTreeHost()->deleteTextureAfterCommit(tile->managedTexture()->steal());

            if (!tile->managedTexture()->isValid(m_tiler->tileSize(), m_textureFormat)) {
                // Sets the dirty rect to a full-sized tile with border texels.
                tile->m_dirtyRect = m_tiler->tileRect(tile);
            }

            if (!tile->managedTexture()->reserve(m_tiler->tileSize(), m_textureFormat)) {
                m_skipsIdlePaint = true;
                if (!idle) {
                    // If the background covers the viewport, always draw this
                    // layer so that checkerboarded tiles will still draw.
                    if (!backgroundCoversViewport())
                        m_skipsDraw = true;
                    m_tiler->reset();
                    m_paintRect = IntRect();
                    m_requestedUpdateTilesRect = IntRect();
                }
                return;
            }

            dirtyLayerRect.unite(tile->m_dirtyRect);
            tile->copyAndClearDirty();
        }
    }

    m_paintRect = dirtyLayerRect;
    if (dirtyLayerRect.isEmpty())
        return;

    // Due to borders, when the paint rect is extended to tile boundaries, it
    // may end up overlapping more tiles than the original content rect. Record
    // the original tiles so we don't upload more tiles than necessary.
    if (!m_paintRect.isEmpty())
        m_requestedUpdateTilesRect = IntRect(left, top, right - left + 1, bottom - top + 1);

    // Calling prepareToUpdate() calls into WebKit to paint, which may have the side
    // effect of disabling compositing, which causes our reference to the texture updater to be deleted.
    // However, we can't free the memory backing the GraphicsContext until the paint finishes,
    // so we grab a local reference here to hold the updater alive until the paint completes.
    RefPtr<LayerTextureUpdater> protector(textureUpdater());
    IntRect paintedOpaqueRect;
    textureUpdater()->prepareToUpdate(m_paintRect, m_tiler->tileSize(), m_tiler->hasBorderTexels(), contentsScale(), &paintedOpaqueRect);
    for (int j = top; j <= bottom; ++j) {
        for (int i = left; i <= right; ++i) {
            UpdatableTile* tile = tileAt(i, j);

            // Tiles are created before prepareToUpdate() is called.
            if (!tile)
                CRASH();

            IntRect tileRect = m_tiler->tileBounds(i, j);

            // Use m_updateRect as copyAndClearDirty above moved the existing dirty rect to m_updateRect if the tile isn't culled.
            const IntRect& dirtyRect = tile->m_updateRect;
            if (dirtyRect.isEmpty())
                continue;

            // Save what was painted opaque in the tile. Keep the old area if the paint didn't touch it, and didn't paint some
            // other part of the tile opaque.
            IntRect tilePaintedRect = intersection(tileRect, m_paintRect);
            IntRect tilePaintedOpaqueRect = intersection(tileRect, paintedOpaqueRect);
            if (!tilePaintedRect.isEmpty()) {
                IntRect paintInsideTileOpaqueRect = intersection(tile->opaqueRect(), tilePaintedRect);
                bool paintInsideTileOpaqueRectIsNonOpaque = !tilePaintedOpaqueRect.contains(paintInsideTileOpaqueRect);
                bool opaquePaintNotInsideTileOpaqueRect = !tilePaintedOpaqueRect.isEmpty() && !tile->opaqueRect().contains(tilePaintedOpaqueRect);

                if (paintInsideTileOpaqueRectIsNonOpaque || opaquePaintNotInsideTileOpaqueRect)
                    tile->setOpaqueRect(tilePaintedOpaqueRect);
            }

            // sourceRect starts as a full-sized tile with border texels included.
            IntRect sourceRect = m_tiler->tileRect(tile);
            sourceRect.intersect(dirtyRect);
            // Paint rect not guaranteed to line up on tile boundaries, so
            // make sure that sourceRect doesn't extend outside of it.
            sourceRect.intersect(m_paintRect);

            tile->m_updateRect = sourceRect;
            if (sourceRect.isEmpty())
                continue;

            tile->texture()->prepareRect(sourceRect);
        }
    }
}
Exemple #3
0
void ContentLayerChromium::update(CCTextureUpdateQueue& queue, const CCOcclusionTracker* occlusion, CCRenderingStats& stats)
{
    createTextureUpdaterIfNeeded();
    TiledLayerChromium::update(queue, occlusion, stats);
    m_needsDisplay = false;
}