Beispiel #1
0
void TiledLayerChromium::addSelfToOccludedScreenSpace(Region& occludedScreenSpace)
{
    if (m_skipsDraw || drawOpacity() != 1 || !isPaintedAxisAlignedInScreen())
        return;

    if (opaque()) {
        LayerChromium::addSelfToOccludedScreenSpace(occludedScreenSpace);
        return;
    }

    IntRect visibleRect = visibleLayerRect();
    TransformationMatrix contentTransform = contentToScreenSpaceTransform();

    // FIXME: Create/Use a FloatRegion for the occludedScreenSpace, instead of a Region based on ints, to avoid this step and get better accuracy between layers in target space.
    Region tileRegion;
    int left, top, right, bottom;
    m_tiler->layerRectToTileIndices(visibleLayerRect(), left, top, right, bottom);
    for (int j = top; j <= bottom; ++j) {
        for (int i = left; i <= right; ++i) {
            UpdatableTile* tile = tileAt(i, j);
            if (tile) {
                IntRect visibleTileOpaqueRect = intersection(visibleRect, tile->m_opaqueRect);
                FloatRect screenRect = contentTransform.mapRect(FloatRect(visibleTileOpaqueRect));
                IntRect screenIntRect = enclosedIntRect(screenRect);
                if (!screenIntRect.isEmpty())
                    occludedScreenSpace.unite(screenIntRect);
            }
        }
    }
}
Beispiel #2
0
PassOwnPtr<CCSharedQuadState> CCLayerImpl::createSharedQuadState() const
{
    IntRect layerClipRect;
    if (usesLayerClipping())
        layerClipRect = clipRect();
    return CCSharedQuadState::create(quadTransform(), drawTransform(), visibleLayerRect(), layerClipRect, drawOpacity(), opaque());
}
Beispiel #3
0
void ContentLayerChromium::draw(const IntRect& targetSurfaceRect)
{
    const TransformationMatrix transform = tilingTransform();
    IntRect layerRect = visibleLayerRect(targetSurfaceRect);
    if (!layerRect.isEmpty())
        m_tiler->draw(layerRect, transform, ccLayerImpl()->drawOpacity());
}
Beispiel #4
0
Region TiledLayerChromium::opaqueContentsRegion() const
{
    if (m_skipsDraw)
        return Region();

    return m_tiler->opaqueRegionInLayerRect(visibleLayerRect());
}
Beispiel #5
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;
        }
    }
}
Beispiel #6
0
void ContentLayerChromium::idlePaintContentsIfDirty()
{
    if (!drawsContent())
        return;

    const IntRect& layerRect = visibleLayerRect();
    if (layerRect.isEmpty())
        return;

    prepareToUpdateIdle(layerRect);
    if (needsIdlePaint(layerRect))
        setNeedsCommit();
}
void ContentLayerChromium::paintContentsIfDirty()
{
    updateTileSizeAndTilingOption();

    IntRect layerRect;

    // Always call prepareToUpdate() but with an empty layer rectangle when
    // layer doesn't draw contents.
    if (drawsContent())
        layerRect = visibleLayerRect();

    prepareToUpdate(layerRect);
    m_needsDisplay = false;
}
Beispiel #8
0
void ContentLayerChromium::paintContentsIfDirty(const IntRect& targetSurfaceRect)
{
    ASSERT(drawsContent());
    ASSERT(layerRenderer());

    updateLayerSize(layerBounds().size());

    IntRect layerRect = visibleLayerRect(targetSurfaceRect);
    if (layerRect.isEmpty())
        return;

    IntRect dirty = enclosingIntRect(m_dirtyRect);
    dirty.intersect(layerBounds());
    m_tiler->invalidateRect(dirty);

    m_tiler->prepareToUpdate(layerRect);
    m_dirtyRect = FloatRect();
}
void ContentLayerChromium::paintContentsIfDirty()
{
    ASSERT(drawsContent());

    updateTileSizeAndTilingOption();

    const IntRect& layerRect = visibleLayerRect();
    if (layerRect.isEmpty())
        return;

    IntRect dirty = enclosingIntRect(m_dirtyRect);
    dirty.intersect(IntRect(IntPoint(), contentBounds()));
    invalidateRect(dirty);

    if (!drawsContent())
        return;

    prepareToUpdate(layerRect);
    resetNeedsDisplay();
}
Beispiel #10
0
Region CCLayerImpl::visibleContentOpaqueRegion() const
{
    if (opaque())
        return visibleLayerRect();
    return Region();
}
Beispiel #11
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);
        }
    }
}
Beispiel #12
0
void TiledLayerChromium::protectVisibleTileTextures()
{
    protectTileTextures(visibleLayerRect());
}
Beispiel #13
0
void FakeTiledLayerChromium::update(CCTextureUpdater& updater, const CCOcclusionTracker* occlusion)
{
    updateLayerRect(updater, visibleLayerRect(), occlusion);
}
Beispiel #14
0
PassOwnPtr<CCSharedQuadState> CCLayerImpl::createSharedQuadState() const
{
    return CCSharedQuadState::create(quadTransform(), drawTransform(), visibleLayerRect(), m_scissorRect, drawOpacity(), opaque());
}