Created
February 22, 2012 13:16
-
-
Save kenchris/1885145 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 5e0d8a12f9cc2241f02dcda02f72e65335369df3 | |
Author: Kenneth Rohde Christiansen <kenneth@webkit.org> | |
Date: Wed Feb 22 13:59:54 2012 +0100 | |
Tiling WIP | |
diff --git a/Source/WebCore/platform/graphics/TiledBackingStore.cpp b/Source/WebCore/platform/graphics/TiledBackingStore.cpp | |
index 3b4b29c..8a0ce1b 100644 | |
--- a/Source/WebCore/platform/graphics/TiledBackingStore.cpp | |
+++ b/Source/WebCore/platform/graphics/TiledBackingStore.cpp | |
@@ -68,12 +68,15 @@ void TiledBackingStore::setTileCreationDelay(double delay) | |
m_tileCreationDelay = delay; | |
} | |
-void TiledBackingStore::setVisibleRectTrajectoryVector(const FloatPoint& vector) | |
+void TiledBackingStore::coverWithTilesIfNeeded(const FloatPoint& panningTrajectoryVector) | |
{ | |
- if (m_visibleRectTrajectoryVector == vector) | |
+ IntRect visibleRect = visibleContentsRect(); | |
+ if (m_visibleRectTrajectoryVector == panningTrajectoryVector && m_previousVisibleRect == visibleRect) | |
return; | |
- m_visibleRectTrajectoryVector = vector; | |
+ m_visibleRectTrajectoryVector = panningTrajectoryVector; | |
+ m_previousVisibleRect = visibleRect; | |
+ | |
startTileCreationTimer(); | |
} | |
@@ -161,17 +164,7 @@ void TiledBackingStore::paint(GraphicsContext* context, const IntRect& rect) | |
context->restore(); | |
} | |
-void TiledBackingStore::adjustVisibleRect() | |
-{ | |
- IntRect visibleRect = visibleContentsRect(); | |
- if (m_previousVisibleRect == visibleRect) | |
- return; | |
- m_previousVisibleRect = visibleRect; | |
- | |
- startTileCreationTimer(); | |
-} | |
- | |
-IntRect TiledBackingStore::visibleContentsRect() | |
+IntRect TiledBackingStore::visibleContentsRect() const | |
{ | |
return mapFromContents(intersection(m_client->tiledBackingStoreVisibleRect(), m_client->tiledBackingStoreContentsRect())); | |
} | |
@@ -210,7 +203,7 @@ double TiledBackingStore::tileDistance(const IntRect& viewport, const Tile::Coor | |
} | |
// Returns a ratio between 0.0f and 1.0f of the surface of contentsRect covered by rendered tiles. | |
-float TiledBackingStore::coverageRatio(const WebCore::IntRect& contentsRect) | |
+float TiledBackingStore::coverageRatio(const WebCore::IntRect& contentsRect) const | |
{ | |
IntRect dirtyRect = mapFromContents(contentsRect); | |
float rectArea = dirtyRect.width() * dirtyRect.height(); | |
@@ -232,6 +225,11 @@ float TiledBackingStore::coverageRatio(const WebCore::IntRect& contentsRect) | |
return coverArea / rectArea; | |
} | |
+bool TiledBackingStore::visibleAreaIsCovered() const | |
+{ | |
+ return coverageRatio(visibleContentsRect()) == 1.0f; | |
+} | |
+ | |
void TiledBackingStore::createTiles() | |
{ | |
if (m_contentsFrozen) | |
@@ -266,7 +264,7 @@ void TiledBackingStore::createTiles() | |
if (tileAt(currentCoordinate)) | |
continue; | |
++requiredTileCount; | |
- // Distance is 0 for all currently visible tiles. | |
+ // Distance is 0 for all tiles inside the visibleRect. | |
double distance = tileDistance(visibleRect, currentCoordinate); | |
if (distance > shortestDistance) | |
continue; | |
@@ -278,7 +276,7 @@ void TiledBackingStore::createTiles() | |
} | |
} | |
- // Now construct the tile(s) | |
+ // Now construct the tile(s) within the shortest distance. | |
unsigned tilesToCreateCount = tilesToCreate.size(); | |
for (unsigned n = 0; n < tilesToCreateCount; ++n) { | |
Tile::Coordinate coordinate = tilesToCreate[n]; | |
@@ -286,11 +284,11 @@ void TiledBackingStore::createTiles() | |
} | |
requiredTileCount -= tilesToCreateCount; | |
- // Paint the content of the newly created tiles | |
+ // Paint the content of the newly created tiles. | |
if (tilesToCreateCount || didResizeTiles) | |
updateTileBuffers(); | |
- // Keep creating tiles until the whole coverRect is covered. | |
+ // Re-call createTiles on a timer to cover the visible area with the newest shortest distance. | |
if (requiredTileCount) | |
m_tileCreationTimer->startOneShot(m_tileCreationDelay); | |
} | |
@@ -409,6 +407,11 @@ void TiledBackingStore::dropTilesOutsideRect(const IntRect& keepRect) | |
removeTile(toRemove[n]); | |
} | |
+void TiledBackingStore::removeAllNonVisibleTiles() | |
+{ | |
+ dropTilesOutsideRect(visibleContentsRect()); | |
+} | |
+ | |
PassRefPtr<Tile> TiledBackingStore::tileAt(const Tile::Coordinate& coordinate) const | |
{ | |
return m_tiles.get(coordinate); | |
diff --git a/Source/WebCore/platform/graphics/TiledBackingStore.h b/Source/WebCore/platform/graphics/TiledBackingStore.h | |
index f2e2a80..ec95bc9 100644 | |
--- a/Source/WebCore/platform/graphics/TiledBackingStore.h | |
+++ b/Source/WebCore/platform/graphics/TiledBackingStore.h | |
@@ -44,14 +44,16 @@ public: | |
TiledBackingStore(TiledBackingStoreClient*, PassOwnPtr<TiledBackingStoreBackend> = TiledBackingStoreBackend::create()); | |
~TiledBackingStore(); | |
- void adjustVisibleRect(); | |
- | |
TiledBackingStoreClient* client() { return m_client; } | |
+ | |
+ void coverWithTilesIfNeeded(const FloatPoint& panningTrajectoryVector = FloatPoint()); | |
+ | |
float contentsScale() { return m_contentsScale; } | |
void setContentsScale(float); | |
bool contentsFrozen() const { return m_contentsFrozen; } | |
void setContentsFrozen(bool); | |
+ | |
void updateTileBuffers(); | |
void invalidate(const IntRect& dirtyRect); | |
@@ -62,8 +64,6 @@ public: | |
double tileCreationDelay() const { return m_tileCreationDelay; } | |
void setTileCreationDelay(double delay); | |
- | |
- void setVisibleRectTrajectoryVector(const FloatPoint&); | |
IntRect mapToContents(const IntRect&) const; | |
IntRect mapFromContents(const IntRect&) const; | |
@@ -71,11 +71,15 @@ public: | |
IntRect tileRectForCoordinate(const Tile::Coordinate&) const; | |
Tile::Coordinate tileCoordinateForPoint(const IntPoint&) const; | |
double tileDistance(const IntRect& viewport, const Tile::Coordinate&) const; | |
- float coverageRatio(const WebCore::IntRect& contentsRect); | |
+ | |
+ bool visibleAreaIsCovered() const; | |
+ void removeAllNonVisibleTiles(); | |
void setSupportsAlpha(bool); | |
bool supportsAlpha() const { return m_supportsAlpha; } | |
+ bool resizeEdgeTiles(); | |
+ | |
private: | |
void startTileBufferUpdateTimer(); | |
void startTileCreationTimer(); | |
@@ -90,18 +94,20 @@ private: | |
void commitScaleChange(); | |
- bool resizeEdgeTiles(); | |
+ //bool resizeEdgeTiles(); | |
void dropTilesOutsideRect(const IntRect&); | |
PassRefPtr<Tile> tileAt(const Tile::Coordinate&) const; | |
void setTile(const Tile::Coordinate& coordinate, PassRefPtr<Tile> tile); | |
void removeTile(const Tile::Coordinate& coordinate); | |
- void adjustForContentsRect(IntRect&) const; | |
IntRect contentsRect() const; | |
- | |
+ IntRect visibleContentsRect() const; | |
+ | |
+ float coverageRatio(const IntRect&) const; | |
+ void adjustForContentsRect(IntRect&) const; | |
+ | |
void paintCheckerPattern(GraphicsContext*, const IntRect&, const Tile::Coordinate&); | |
- IntRect visibleContentsRect(); | |
private: | |
TiledBackingStoreClient* m_client; | |
diff --git a/Source/WebKit/qt/Api/qgraphicswebview.cpp b/Source/WebKit/qt/Api/qgraphicswebview.cpp | |
index c1eb529..a446aff 100644 | |
--- a/Source/WebKit/qt/Api/qgraphicswebview.cpp | |
+++ b/Source/WebKit/qt/Api/qgraphicswebview.cpp | |
@@ -288,9 +288,9 @@ void QGraphicsWebView::paint(QPainter* painter, const QStyleOptionGraphicsItem* | |
#if USE(TILED_BACKING_STORE) | |
if (WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page()->mainFrame())->tiledBackingStore()) { | |
// FIXME: We should set the backing store viewport earlier than in paint | |
- backingStore->adjustVisibleRect(); | |
+ backingStore->coverWithTilesIfNeeded(); | |
// QWebFrame::render is a public API, bypass it for tiled rendering so behavior does not need to change. | |
- WebCore::GraphicsContext context(painter); | |
+ WebCore::GraphicsContext context(painter); | |
page()->mainFrame()->d->renderFromTiledBackingStore(&context, option->exposedRect.toAlignedRect()); | |
painter->setRenderHints(oldHints); | |
return; | |
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp | |
index 26ad739..8fd108a 100644 | |
--- a/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp | |
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp | |
@@ -482,16 +482,26 @@ void WebGraphicsLayer::setRootLayer(bool isRoot) | |
void WebGraphicsLayer::setVisibleContentRectTrajectoryVector(const FloatPoint& trajectoryVector) | |
{ | |
if (m_mainBackingStore) | |
- m_mainBackingStore->setVisibleRectTrajectoryVector(trajectoryVector); | |
+ m_mainBackingStore->coverWithTilesIfNeeded(trajectoryVector); | |
} | |
void WebGraphicsLayer::setContentsScale(float scale) | |
{ | |
m_contentsScale = scale; | |
- if (m_mainBackingStore && m_mainBackingStore->contentsScale() != scale) { | |
- m_previousBackingStore = m_mainBackingStore.release(); | |
- createBackingStore(); | |
- } | |
+ | |
+ if (!m_mainBackingStore || m_mainBackingStore->contentsScale() == scale) | |
+ 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::createBackingStore() | |
@@ -582,12 +592,18 @@ void WebGraphicsLayer::updateContentBuffers() | |
} | |
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. | |
+ // 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 WebGraphicsLayer::purgeBackingStores() | |
@@ -628,7 +644,7 @@ void WebGraphicsLayer::setWebGraphicsLayerClient(WebKit::WebGraphicsLayerClient* | |
void WebGraphicsLayer::adjustVisibleRect() | |
{ | |
if (m_mainBackingStore) | |
- m_mainBackingStore->adjustVisibleRect(); | |
+ m_mainBackingStore->coverWithTilesIfNeeded(); | |
} | |
void WebGraphicsLayer::computeTransformedVisibleRect() | |
@@ -641,9 +657,9 @@ void WebGraphicsLayer::computeTransformedVisibleRect() | |
m_layerTransform.setFlattening(!preserves3D()); | |
m_layerTransform.setChildrenTransform(childrenTransform()); | |
m_layerTransform.combineTransforms(parent() ? toWebGraphicsLayer(parent())->m_layerTransform.combinedForChildren() : TransformationMatrix()); | |
+ | |
// The combined transform will be used in tiledBackingStoreVisibleRect. | |
- if (m_mainBackingStore) | |
- m_mainBackingStore->adjustVisibleRect(); | |
+ adjustVisibleRect(); | |
} | |
#endif | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment