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()); } }
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(); }
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); }