void CoordinatedGraphicsLayer::updateContentBuffers()
{
    if (!shouldHaveBackingStore()) {
        m_mainBackingStore = nullptr;
        m_previousBackingStore = nullptr;
        return;
    }

    if (m_pendingContentsScaleAdjustment) {
        adjustContentsScale();
        m_pendingContentsScaleAdjustment = false;
    }

    // This is the only place we (re)create the main tiled backing store, once we
    // have a remote client and we are ready to send our data to the UI process.
    if (!m_mainBackingStore)
        createBackingStore();

    if (m_pendingVisibleRectAdjustment) {
        m_pendingVisibleRectAdjustment = false;
        m_mainBackingStore->coverWithTilesIfNeeded();
    }

    m_mainBackingStore->updateTileBuffers();

    // The previous backing store is kept around to avoid flickering between
    // removing the existing tiles and painting the new ones. The first time
    // the visibleRect is full painted we remove the previous backing store.
    if (m_mainBackingStore->visibleAreaIsCovered())
        m_previousBackingStore = nullptr;
}
void ChromeClient::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* rootLayer)
{
    AcceleratedCompositingContext* context = m_webView->priv->acceleratedCompositingContext.get();
    bool turningOffCompositing = !rootLayer && context->enabled();
    bool turningOnCompositing = rootLayer && !context->enabled();

    context->setRootCompositingLayer(rootLayer);

    if (turningOnCompositing) {
        m_displayTimer.stop();
        m_webView->priv->backingStore = createBackingStore(GTK_WIDGET(m_webView), IntSize(1, 1));
    }

    if (turningOffCompositing) {
        m_webView->priv->backingStore = createBackingStore(GTK_WIDGET(m_webView), getWebViewRect(m_webView).size());
        RefPtr<cairo_t> cr = adoptRef(cairo_create(m_webView->priv->backingStore->cairoSurface()));
        clearEverywhereInBackingStore(m_webView, cr.get());
    }
}
Esempio n. 3
0
void WebGraphicsLayer::adjustContentsScale()
{
    if (!drawsContent())
        return;

    if (!m_mainBackingStore || m_mainBackingStore->contentsScale() == effectiveContentsScale())
        return;

    // Between creating the new backing store and painting the content,
    // we do not want to drop the previous one as that might result in
    // briefly seeing flickering as the old tiles may be dropped before
    // something replaces them.
    m_previousBackingStore = m_mainBackingStore.release();

    // No reason to save the previous backing store for non-visible areas.
    m_previousBackingStore->removeAllNonVisibleTiles();

    createBackingStore();
}
Esempio n. 4
0
void WebGraphicsLayer::updateContentBuffers()
{
    if (!drawsContent()) {
        m_mainBackingStore.clear();
        m_previousBackingStore.clear();
        return;
    }

    m_inUpdateMode = true;
    // This is the only place we (re)create the main tiled backing store, once we
    // have a remote client and we are ready to send our data to the UI process.
    if (!m_mainBackingStore)
        createBackingStore();
    m_mainBackingStore->updateTileBuffers();
    m_inUpdateMode = false;

    // The previous backing store is kept around to avoid flickering between
    // removing the existing tiles and painting the new ones. The first time
    // the visibleRect is full painted we remove the previous backing store.
    if (m_mainBackingStore->visibleAreaIsCovered())
        m_previousBackingStore.clear();
}
void ChromeClient::widgetSizeChanged(const IntSize& oldWidgetSize, IntSize newSize)
{
#if USE(ACCELERATED_COMPOSITING)
    AcceleratedCompositingContext* compositingContext = m_webView->priv->acceleratedCompositingContext.get();
    if (compositingContext->enabled()) {
        m_webView->priv->acceleratedCompositingContext->resizeRootLayer(newSize);
        return;
    }
#endif

    // Grow the backing store by at least 1.5 times the current size. This prevents
    // lots of unnecessary allocations during an opaque resize.
    WidgetBackingStore* backingStore = m_webView->priv->backingStore.get();
    if (backingStore && oldWidgetSize == newSize)
        return;

    if (backingStore) {
        const IntSize& oldSize = backingStore->size();
        if (newSize.width() > oldSize.width())
            newSize.setWidth(std::max(newSize.width(), static_cast<int>(oldSize.width() * 1.5)));
        if (newSize.height() > oldSize.height())
            newSize.setHeight(std::max(newSize.height(), static_cast<int>(oldSize.height() * 1.5)));
    }

    // If we did not have a backing store before or if the backing store is growing, we need
    // to reallocate a new one and set it up so that we don't see artifacts while resizing.
    if (!backingStore
        || newSize.width() > backingStore->size().width()
        || newSize.height() > backingStore->size().height()) {

        OwnPtr<WidgetBackingStore> newBackingStore = createBackingStore(GTK_WIDGET(m_webView), newSize);
        RefPtr<cairo_t> cr = adoptRef(cairo_create(newBackingStore->cairoSurface()));

        clearEverywhereInBackingStore(m_webView, cr.get());

        // Now we copy the old backing store image over the new cleared surface to prevent
        // annoying flashing as the widget grows. We do the "real" paint in a timeout
        // since we don't want to block resizing too long.
        if (backingStore) {
            cairo_set_source_surface(cr.get(), backingStore->cairoSurface(), 0, 0);
            cairo_rectangle(cr.get(), 0, 0, backingStore->size().width(), backingStore->size().height());
            cairo_fill(cr.get());
        }

        m_webView->priv->backingStore = newBackingStore.release();
        backingStore = m_webView->priv->backingStore.get();

    } else if (oldWidgetSize.width() < newSize.width() || oldWidgetSize.height() < newSize.height()) {
        // The widget is growing, but we did not need to create a new backing store.
        // We should clear any old data outside of the old widget region.
        RefPtr<cairo_t> cr = adoptRef(cairo_create(backingStore->cairoSurface()));
        clipOutOldWidgetArea(cr.get(), oldWidgetSize, newSize);
        clearEverywhereInBackingStore(m_webView, cr.get());
    }

    // We need to force a redraw and ignore the framerate cap.
    m_lastDisplayTime = 0;
    m_dirtyRegion.unite(IntRect(IntPoint(), backingStore->size()));

    // WebCore timers by default have a lower priority which leads to more artifacts when opaque
    // resize is on, thus we use g_timeout_add here to force a higher timeout priority.
    if (!m_repaintSoonSourceId)
        m_repaintSoonSourceId = g_timeout_add(0, reinterpret_cast<GSourceFunc>(repaintEverythingSoonTimeout), this);
}