Exemple #1
0
void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollDelta)
{
    if (!m_isPaintingEnabled)
        return;

    if (m_layerTreeHost) {
        ASSERT(m_scrollRect.isEmpty());
        ASSERT(m_scrollOffset.isEmpty());
        ASSERT(m_dirtyRegion.isEmpty());

        m_layerTreeHost->scrollNonCompositedContents(scrollRect);
        return;
    }

    if (m_webPage->mainFrameHasCustomRepresentation())
        return;

    if (scrollRect.isEmpty())
        return;

    if (!m_scrollRect.isEmpty() && scrollRect != m_scrollRect) {
        unsigned scrollArea = scrollRect.width() * scrollRect.height();
        unsigned currentScrollArea = m_scrollRect.width() * m_scrollRect.height();

        if (currentScrollArea >= scrollArea) {
            // The rect being scrolled is at least as large as the rect we'd like to scroll.
            // Go ahead and just invalidate the scroll rect.
            setNeedsDisplayInRect(scrollRect);
            return;
        }

        // Just repaint the entire current scroll rect, we'll scroll the new rect instead.
        setNeedsDisplayInRect(m_scrollRect);
        m_scrollRect = IntRect();
        m_scrollOffset = IntSize();
    }

    // Get the part of the dirty region that is in the scroll rect.
    Region dirtyRegionInScrollRect = intersect(scrollRect, m_dirtyRegion);
    if (!dirtyRegionInScrollRect.isEmpty()) {
        // There are parts of the dirty region that are inside the scroll rect.
        // We need to subtract them from the region, move them and re-add them.
        m_dirtyRegion.subtract(scrollRect);

        // Move the dirty parts.
        Region movedDirtyRegionInScrollRect = intersect(translate(dirtyRegionInScrollRect, scrollDelta), scrollRect);

        // And add them back.
        m_dirtyRegion.unite(movedDirtyRegionInScrollRect);
    } 
    
    // Compute the scroll repaint region.
    Region scrollRepaintRegion = subtract(scrollRect, translate(scrollRect, scrollDelta));

    m_dirtyRegion.unite(scrollRepaintRegion);
    scheduleDisplay();

    m_scrollRect = scrollRect;
    m_scrollOffset += scrollDelta;
}
Exemple #2
0
void DrawingAreaImpl::setPageOverlayNeedsDisplay(PageOverlay* pageOverlay, const IntRect& rect)
{
    if (m_layerTreeHost) {
        m_layerTreeHost->setPageOverlayNeedsDisplay(pageOverlay, rect);
        return;
    }

    setNeedsDisplayInRect(rect);
}
void TextureMapperNode::setNeedsDisplay()
{
    if (m_effectTarget)
        m_effectTarget->setNeedsDisplay();
    if (m_transforms.targetBoundingRect.isEmpty())
        return;
    if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType)
        setNeedsDisplayInRect(m_transforms.targetBoundingRect);
}
Exemple #4
0
void DrawingAreaImpl::setNeedsDisplay()
{
    if (!m_isPaintingEnabled)
        return;

    if (m_layerTreeHost) {
        ASSERT(m_dirtyRegion.isEmpty());
        m_layerTreeHost->setNonCompositedContentsNeedDisplay();
        return;
    }

    setNeedsDisplayInRect(m_webPage->bounds());
}
Exemple #5
0
void GraphicsLayerClutter::setNeedsDisplay()
{
    FloatRect hugeRect(FloatPoint(), m_size);
    setNeedsDisplayInRect(hugeRect);
}
void WebGraphicsLayer::setNeedsDisplay()
{
    setNeedsDisplayInRect(IntRect(IntPoint::zero(), IntSize(size().width(), size().height())));
}
Exemple #7
0
void GraphicsLayerAndroid::setNeedsDisplay()
{
    LOG("(%x) setNeedsDisplay()", this);
    FloatRect rect(0, 0, m_size.width(), m_size.height());
    setNeedsDisplayInRect(rect);
}
void CoordinatedGraphicsLayer::setNeedsDisplay()
{
    setNeedsDisplayInRect(FloatRect(FloatPoint(), size()));
}
Exemple #9
0
void TileGrid::revalidateTiles(TileValidationPolicy validationPolicy)
{
    FloatRect coverageRect = m_controller.coverageRect();
    IntRect bounds = m_controller.bounds();

    if (coverageRect.isEmpty() || bounds.isEmpty())
        return;

    FloatRect scaledRect(coverageRect);
    scaledRect.scale(m_scale);
    IntRect coverageRectInTileCoords(enclosingIntRect(scaledRect));

    TileCohort currCohort = nextTileCohort();
    unsigned tilesInCohort = 0;

    double minimumRevalidationTimerDuration = std::numeric_limits<double>::max();
    bool needsTileRevalidation = false;

    // Move tiles newly outside the coverage rect into the cohort map.
    for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
        TileInfo& tileInfo = it->value;
        TileIndex tileIndex = it->key;

        PlatformCALayer* tileLayer = tileInfo.layer.get();
        IntRect tileRect = rectForTileIndex(tileIndex);
        if (tileRect.intersects(coverageRectInTileCoords)) {
            tileInfo.cohort = VisibleTileCohort;
            if (tileInfo.hasStaleContent) {
                // FIXME: store a dirty region per layer?
                tileLayer->setNeedsDisplay();
                tileInfo.hasStaleContent = false;
            }
        } else {
            // Add to the currentCohort if not already in one.
            if (tileInfo.cohort == VisibleTileCohort) {
                tileInfo.cohort = currCohort;
                ++tilesInCohort;

                if (m_controller.unparentsOffscreenTiles())
                    tileLayer->removeFromSuperlayer();
            } else if (m_controller.unparentsOffscreenTiles() && m_controller.shouldAggressivelyRetainTiles() && tileLayer->superlayer()) {
                // Aggressive tile retention means we'll never remove cohorts, but we need to make sure they're unparented.
                // We can't immediately unparent cohorts comprised of secondary tiles that never touch the primary coverage rect,
                // because that would defeat the usefulness of prepopulateRect(); instead, age prepopulated tiles out as if they were being removed.
                for (auto& cohort : m_cohortList) {
                    if (cohort.cohort != tileInfo.cohort)
                        continue;
                    double timeUntilCohortExpires = cohort.timeUntilExpiration();
                    if (timeUntilCohortExpires > 0) {
                        minimumRevalidationTimerDuration = std::min(minimumRevalidationTimerDuration, timeUntilCohortExpires);
                        needsTileRevalidation = true;
                    } else
                        tileLayer->removeFromSuperlayer();
                    break;
                }
            }
        }
    }

    if (needsTileRevalidation)
        m_controller.scheduleTileRevalidation(minimumRevalidationTimerDuration);

    if (tilesInCohort)
        startedNewCohort(currCohort);

    if (!m_controller.shouldAggressivelyRetainTiles()) {
        if (m_controller.shouldTemporarilyRetainTileCohorts())
            scheduleCohortRemoval();
        else if (tilesInCohort)
            removeTilesInCohort(currCohort);
    }

    // Ensure primary tile coverage tiles.
    m_primaryTileCoverageRect = ensureTilesForRect(coverageRect, CoverageType::PrimaryTiles);

    if (validationPolicy & PruneSecondaryTiles) {
        removeAllSecondaryTiles();
        m_cohortList.clear();
    } else {
        for (auto& secondaryCoverageRect : m_secondaryTileCoverageRects) {
            FloatRect secondaryRectInLayerCoordinates(secondaryCoverageRect);
            secondaryRectInLayerCoordinates.scale(1 / m_scale);
            ensureTilesForRect(secondaryRectInLayerCoordinates, CoverageType::SecondaryTiles);
        }
        m_secondaryTileCoverageRects.clear();
    }

    if (m_controller.unparentsOffscreenTiles() && (validationPolicy & UnparentAllTiles)) {
        for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
            it->value.layer->removeFromSuperlayer();
    }

    auto boundsAtLastRevalidate = m_controller.boundsAtLastRevalidate();
    if (boundsAtLastRevalidate != bounds) {
        // If there are margin tiles and the bounds have grown taller or wider, then the tiles that used to
        // be bottom or right margin tiles need to be invalidated.
        if (m_controller.hasMargins()) {
            if (bounds.width() > boundsAtLastRevalidate.width() || bounds.height() > boundsAtLastRevalidate.height()) {
                IntRect boundsWithoutMargin = m_controller.boundsWithoutMargin();
                IntRect oldBoundsWithoutMargin = m_controller.boundsAtLastRevalidateWithoutMargin();

                if (bounds.height() > boundsAtLastRevalidate.height()) {
                    IntRect formerBottomMarginRect = IntRect(oldBoundsWithoutMargin.x(), oldBoundsWithoutMargin.height(),
                                                     oldBoundsWithoutMargin.width(), boundsWithoutMargin.height() - oldBoundsWithoutMargin.height());
                    setNeedsDisplayInRect(formerBottomMarginRect);
                }

                if (bounds.width() > boundsAtLastRevalidate.width()) {
                    IntRect formerRightMarginRect = IntRect(oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.y(),
                                                            boundsWithoutMargin.width() - oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.height());
                    setNeedsDisplayInRect(formerRightMarginRect);
                }
            }
        }

        FloatRect scaledBounds(bounds);
        scaledBounds.scale(m_scale);
        IntRect boundsInTileCoords(enclosingIntRect(scaledBounds));

        TileIndex topLeftForBounds;
        TileIndex bottomRightForBounds;
        getTileIndexRangeForRect(boundsInTileCoords, topLeftForBounds, bottomRightForBounds);

        Vector<TileIndex> tilesToRemove;
        for (auto& index : m_tiles.keys()) {
            if (index.y() < topLeftForBounds.y() || index.y() > bottomRightForBounds.y() || index.x() < topLeftForBounds.x() || index.x() > bottomRightForBounds.x())
                tilesToRemove.append(index);
        }
        removeTiles(tilesToRemove);
    }

    m_controller.didRevalidateTiles();
}