Diff
Modified: trunk/Source/WebCore/ChangeLog (103128 => 103129)
--- trunk/Source/WebCore/ChangeLog 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/ChangeLog 2011-12-17 00:27:33 UTC (rev 103129)
@@ -1,3 +1,38 @@
+2011-12-16 Eric Penner <epen...@google.com>
+
+ [chromium] Need to prepaint tiles in TiledLayerChromium
+ https://bugs.webkit.org/show_bug.cgi?id=72686
+
+ Reviewed by James Robinson.
+
+ Tests: TiledLayerChromiumTest (idlePaintOutOfMemory, pushIdlePaintTiles)
+
+ * platform/graphics/chromium/ContentLayerChromium.cpp:
+ (WebCore::ContentLayerChromium::idlePaintContentsIfDirty): added idle paint function
+ * platform/graphics/chromium/ContentLayerChromium.h: ditto
+ * platform/graphics/chromium/LayerChromium.h: ditto
+ (WebCore::LayerChromium::idlePaintContentsIfDirty): ditto
+ * platform/graphics/chromium/TextureManager.cpp:
+ (WebCore::TextureManager::protectTexture): removed assert for protecting a texture twice
+ * platform/graphics/chromium/TiledLayerChromium.cpp:
+ (WebCore::TiledLayerChromium::TiledLayerChromium):
+ (WebCore::TiledLayerChromium::cleanupResources):
+ (WebCore::TiledLayerChromium::updateCompositorResources): refactoring to use tile indices
+ (WebCore::TiledLayerChromium::prepareToUpdateTiles): refactored common code and made idle/visible versions
+ (WebCore::TiledLayerChromium::prepareToUpdate): ditto
+ (WebCore::TiledLayerChromium::prepareToUpdateIdle): ditto
+ (WebCore::TiledLayerChromium::needsIdlePaint):
+ (WebCore::TiledLayerChromium::idlePaintRect):
+ * platform/graphics/chromium/TiledLayerChromium.h:
+ * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+ (WebCore::CCLayerTreeHost::CCLayerTreeHost):
+ (WebCore::CCLayerTreeHost::compositeAndReadback): set flag to avoid idle paint durring composite and readback
+ (WebCore::CCLayerTreeHost::updateLayers): added idle flag parameter
+ (WebCore::CCLayerTreeHost::paintContentsIfDirty): ditto
+ (WebCore::CCLayerTreeHost::paintMaskAndReplicaForRenderSurface): ditto
+ (WebCore::CCLayerTreeHost::paintLayerContents): chooses idle or visible paint
+ * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+
2011-12-16 Dean Jackson <d...@apple.com>
Miscellaneous Filter updates to align with spec
Modified: trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp (103128 => 103129)
--- trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp 2011-12-17 00:27:33 UTC (rev 103129)
@@ -108,6 +108,20 @@
m_needsDisplay = false;
}
+void ContentLayerChromium::idlePaintContentsIfDirty()
+{
+ if (!drawsContent())
+ return;
+
+ const IntRect& layerRect = visibleLayerRect();
+ if (layerRect.isEmpty())
+ return;
+
+ prepareToUpdateIdle(layerRect);
+ if (needsIdlePaint(layerRect))
+ setNeedsCommit();
+}
+
bool ContentLayerChromium::drawsContent() const
{
return m_delegate && m_delegate->drawsContent() && TiledLayerChromium::drawsContent();
Modified: trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h (103128 => 103129)
--- trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h 2011-12-17 00:27:33 UTC (rev 103129)
@@ -50,6 +50,7 @@
virtual ~ContentLayerChromium();
virtual void paintContentsIfDirty();
+ virtual void idlePaintContentsIfDirty();
protected:
explicit ContentLayerChromium(CCLayerDelegate*);
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h (103128 => 103129)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h 2011-12-17 00:27:33 UTC (rev 103129)
@@ -161,6 +161,7 @@
// These methods typically need to be overwritten by derived classes.
virtual bool drawsContent() const { return false; }
virtual void paintContentsIfDirty() { }
+ virtual void idlePaintContentsIfDirty() { }
virtual void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&) { }
virtual void setIsMask(bool) { }
virtual void unreserveContentsTexture() { }
Modified: trunk/Source/WebCore/platform/graphics/chromium/TextureManager.cpp (103128 => 103129)
--- trunk/Source/WebCore/platform/graphics/chromium/TextureManager.cpp 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/platform/graphics/chromium/TextureManager.cpp 2011-12-17 00:27:33 UTC (rev 103129)
@@ -141,7 +141,6 @@
void TextureManager::protectTexture(TextureToken token)
{
ASSERT(hasTexture(token));
- ASSERT(!m_textures.get(token).isProtected);
TextureInfo info = m_textures.take(token);
info.isProtected = true;
m_textures.add(token, info);
Modified: trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp (103128 => 103129)
--- trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp 2011-12-17 00:27:33 UTC (rev 103129)
@@ -72,6 +72,7 @@
: LayerChromium(delegate)
, m_textureFormat(GraphicsContext3D::INVALID_ENUM)
, m_skipsDraw(false)
+ , m_skipsIdlePaint(false)
, m_sampledTexelFormat(LayerTextureUpdater::SampledTexelFormatInvalid)
, m_tilingOption(AutoTile)
{
@@ -92,7 +93,7 @@
m_tiler.clear();
m_paintRect = IntRect();
- m_requestedUpdateRect = IntRect();
+ m_requestedUpdateTilesRect = IntRect();
}
void TiledLayerChromium::updateTileSizeAndTilingOption()
@@ -182,11 +183,13 @@
ASSERT(m_skipsDraw || m_tiler);
// Painting could cause compositing to get turned off, which may cause the tiler to become invalidated mid-update.
- if (m_skipsDraw || m_requestedUpdateRect.isEmpty() || !m_tiler || !m_tiler->numTiles())
+ if (m_skipsDraw || m_requestedUpdateTilesRect.isEmpty() || !m_tiler || !m_tiler->numTiles())
return;
- int left, top, right, bottom;
- m_tiler->contentRectToTileIndices(m_requestedUpdateRect, left, top, right, bottom);
+ int left = m_requestedUpdateTilesRect.x();
+ int top = m_requestedUpdateTilesRect.y();
+ int right = m_requestedUpdateTilesRect.maxX() - 1;
+ int bottom = m_requestedUpdateTilesRect.maxY() - 1;
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
UpdatableTile* tile = tileAt(i, j);
@@ -344,38 +347,17 @@
}
}
-void TiledLayerChromium::prepareToUpdate(const IntRect& contentRect)
+void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int right, int bottom)
{
- if (!m_tiler)
- createTiler(isNonCompositedContent() ? CCLayerTilingData::NoBorderTexels : CCLayerTilingData::HasBorderTexels);
-
- ASSERT(m_tiler);
-
- m_skipsDraw = false;
-
// Reset m_updateRect for all tiles.
for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin(); iter != m_tiler->tiles().end(); ++iter) {
UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second.get());
tile->m_updateRect = IntRect();
}
- if (contentRect.isEmpty()) {
- m_requestedUpdateRect = IntRect();
- return;
- }
-
- m_tiler->growLayerToContain(contentRect);
-
- if (!m_tiler->numTiles()) {
- m_requestedUpdateRect = IntRect();
- return;
- }
-
// Create tiles as needed, expanding a dirty rect to contain all
// the dirty regions currently being drawn.
IntRect dirtyLayerRect;
- int left, top, right, bottom;
- m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
UpdatableTile* tile = tileAt(i, j);
@@ -386,8 +368,11 @@
tile->m_dirtyLayerRect = m_tiler->tileLayerRect(tile);
if (!tile->managedTexture()->reserve(m_tiler->tileSize(), m_textureFormat)) {
- m_skipsDraw = true;
- cleanupResources();
+ m_skipsIdlePaint = true;
+ if (!idle) {
+ m_skipsDraw = true;
+ cleanupResources();
+ }
return;
}
@@ -395,22 +380,22 @@
}
}
- // 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
- // that original rect so we don't upload more tiles than necessary.
- m_requestedUpdateRect = contentRect;
-
m_paintRect = m_tiler->layerRectToContentRect(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());
textureUpdater()->prepareToUpdate(m_paintRect, m_tiler->tileSize(), m_tiler->hasBorderTexels(), contentsScale());
- m_tiler->contentRectToTileIndices(m_requestedUpdateRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
UpdatableTile* tile = tileAt(i, j);
@@ -442,5 +427,117 @@
}
}
+
+void TiledLayerChromium::prepareToUpdate(const IntRect& contentRect)
+{
+ if (!m_tiler)
+ createTiler(isNonCompositedContent() ? CCLayerTilingData::NoBorderTexels : CCLayerTilingData::HasBorderTexels);
+
+ ASSERT(m_tiler);
+
+ m_skipsDraw = false;
+ m_skipsIdlePaint = false;
+ m_requestedUpdateTilesRect = IntRect();
+ m_paintRect = IntRect();
+
+ m_tiler->growLayerToContain(IntRect(IntPoint::zero(), contentBounds()));
+
+ if (contentRect.isEmpty() || !m_tiler->numTiles())
+ return;
+
+ int left, top, right, bottom;
+ m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);
+
+ prepareToUpdateTiles(false, left, top, right, bottom);
}
+
+void TiledLayerChromium::prepareToUpdateIdle(const IntRect& contentRect)
+{
+ // Abort if we have already prepared a paint or run out of memory.
+ if (m_skipsIdlePaint || !m_paintRect.isEmpty())
+ return;
+
+ ASSERT(m_tiler);
+
+ m_tiler->growLayerToContain(IntRect(IntPoint::zero(), contentBounds()));
+
+ if (!m_tiler->numTiles())
+ return;
+
+ // Protect any textures in the pre-paint area so we don't end up just
+ // reclaiming them below.
+ IntRect idlePaintContentRect = idlePaintRect(contentRect);
+ protectTileTextures(idlePaintContentRect);
+
+ // Expand outwards until we find a dirty row or column to update.
+ int left, top, right, bottom;
+ m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);
+ int prepaintLeft, prepaintTop, prepaintRight, prepaintBottom;
+ m_tiler->contentRectToTileIndices(idlePaintContentRect, prepaintLeft, prepaintTop, prepaintRight, prepaintBottom);
+ while (!m_skipsIdlePaint && (left > prepaintLeft || top > prepaintTop || right < prepaintRight || bottom < prepaintBottom)) {
+ if (bottom < prepaintBottom) {
+ ++bottom;
+ prepareToUpdateTiles(true, left, bottom, right, bottom);
+ if (!m_paintRect.isEmpty() || m_skipsIdlePaint)
+ break;
+ }
+ if (top > prepaintTop) {
+ --top;
+ prepareToUpdateTiles(true, left, top, right, top);
+ if (!m_paintRect.isEmpty() || m_skipsIdlePaint)
+ break;
+ }
+ if (left > prepaintLeft) {
+ --left;
+ prepareToUpdateTiles(true, left, top, left, bottom);
+ if (!m_paintRect.isEmpty() || m_skipsIdlePaint)
+ break;
+ }
+ if (right < prepaintRight) {
+ ++right;
+ prepareToUpdateTiles(true, right, top, right, bottom);
+ if (!m_paintRect.isEmpty() || m_skipsIdlePaint)
+ break;
+ }
+ }
+}
+
+bool TiledLayerChromium::needsIdlePaint(const IntRect& contentRect)
+{
+ if (m_skipsIdlePaint)
+ return false;
+
+ ASSERT(m_tiler);
+
+ IntRect idlePaintContentRect = idlePaintRect(contentRect);
+
+ int left, top, right, bottom;
+ m_tiler->contentRectToTileIndices(idlePaintContentRect, left, top, right, bottom);
+ for (int j = top; j <= bottom; ++j) {
+ for (int i = left; i <= right; ++i) {
+ if (m_requestedUpdateTilesRect.contains(IntPoint(i, j)))
+ continue;
+ UpdatableTile* tile = tileAt(i, j);
+ if (!tile || !tile->managedTexture()->isValid(m_tiler->tileSize(), m_textureFormat) || tile->isDirty())
+ return true;
+ }
+ }
+ return false;
+}
+
+IntRect TiledLayerChromium::idlePaintRect(const IntRect& visibleContentRect)
+{
+ ASSERT(m_tiler);
+ IntRect prepaintRect = visibleContentRect;
+ // FIXME: This can be made a lot larger if we can:
+ // - reserve memory at a lower priority than for visible content
+ // - only reserve idle paint tiles up to a memory reclaim threshold and
+ // - insure we play nicely with other layers
+ prepaintRect.inflateX(m_tiler->tileSize().width());
+ prepaintRect.inflateY(m_tiler->tileSize().height());
+ prepaintRect.intersect(IntRect(IntPoint::zero(), contentBounds()));
+ return prepaintRect;
+}
+
+}
#endif // USE(ACCELERATED_COMPOSITING)
Modified: trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h (103128 => 103129)
--- trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h 2011-12-17 00:27:33 UTC (rev 103129)
@@ -75,9 +75,16 @@
// Set invalidations to be potentially repainted during update().
void invalidateRect(const IntRect& contentRect);
+
// Prepare data needed to update textures that intersect with contentRect.
void prepareToUpdate(const IntRect& contentRect);
+ // Same as above, but this will try to paint additional surrounding content if idle.
+ void prepareToUpdateIdle(const IntRect& contentRect);
+
+ // After preparing an update, returns true if more pre-painting is needed.
+ bool needsIdlePaint(const IntRect& contentRect);
+
virtual void protectVisibleTileTextures();
virtual TextureManager* textureManager() const;
@@ -90,17 +97,22 @@
void createTilerIfNeeded();
void setTilingOption(TilingOption);
+ void prepareToUpdateTiles(bool idle, int left, int top, int right, int bottom);
+ IntRect idlePaintRect(const IntRect& visibleContentRect);
+
UpdatableTile* tileAt(int, int) const;
UpdatableTile* createTile(int, int);
// Temporary state held between prepareToUpdate() and updateCompositorResources().
- IntRect m_requestedUpdateRect;
+ IntRect m_requestedUpdateTilesRect;
+
// State held between prepareToUpdate() and pushPropertiesTo(). This represents the area
// of the layer that is actually re-painted by WebKit.
IntRect m_paintRect;
GC3Denum m_textureFormat;
bool m_skipsDraw;
+ bool m_skipsIdlePaint;
LayerTextureUpdater::SampledTexelFormat m_sampledTexelFormat;
TilingOption m_tilingOption;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (103128 => 103129)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2011-12-17 00:27:33 UTC (rev 103129)
@@ -67,6 +67,7 @@
, m_pageScale(1)
, m_minPageScale(1)
, m_maxPageScale(1)
+ , m_triggerIdlePaints(true)
{
ASSERT(CCProxy::isMainThread());
numLayerTreeInstances++;
@@ -190,7 +191,9 @@
bool CCLayerTreeHost::compositeAndReadback(void *pixels, const IntRect& rect)
{
+ m_triggerIdlePaints = false;
return m_proxy->compositeAndReadback(pixels, rect);
+ m_triggerIdlePaints = true;
}
void CCLayerTreeHost::finishAllRendering()
@@ -375,33 +378,59 @@
CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(rootLayer, rootLayer, identityMatrix, identityMatrix, m_updateList, rootRenderSurface->layerList(), layerRendererCapabilities().maxTextureSize);
}
- paintLayerContents(m_updateList);
+ paintLayerContents(m_updateList, PaintVisible);
+ if (!m_triggerIdlePaints)
+ return;
+
+ size_t preferredLimitBytes = TextureManager::reclaimLimitBytes(m_viewportSize);
+ size_t maxLimitBytes = TextureManager::highLimitBytes(m_viewportSize);
+ contentsTextureManager()->reduceMemoryToLimit(preferredLimitBytes);
+ if (contentsTextureManager()->currentMemoryUseBytes() >= preferredLimitBytes)
+ return;
+
+ // Idle painting should fail when we hit the preferred memory limit,
+ // otherwise it will always push us towards the maximum limit.
+ m_contentsTextureManager->setMaxMemoryLimitBytes(preferredLimitBytes);
+ // The second (idle) paint will be a no-op in layers where painting already occured above.
+ paintLayerContents(m_updateList, PaintIdle);
+ m_contentsTextureManager->setMaxMemoryLimitBytes(maxLimitBytes);
}
-void CCLayerTreeHost::paintMaskAndReplicaForRenderSurface(LayerChromium* renderSurfaceLayer)
+// static
+void CCLayerTreeHost::paintContentsIfDirty(LayerChromium* layer, PaintType paintType)
{
+ ASSERT(layer);
+ ASSERT(PaintVisible == paintType || PaintIdle == paintType);
+ if (PaintVisible == paintType)
+ layer->paintContentsIfDirty();
+ else
+ layer->idlePaintContentsIfDirty();
+}
+
+void CCLayerTreeHost::paintMaskAndReplicaForRenderSurface(LayerChromium* renderSurfaceLayer, PaintType paintType)
+{
// Note: Masks and replicas only exist for layers that own render surfaces. If we reach this point
// in code, we already know that at least something will be drawn into this render surface, so the
// mask and replica should be painted.
if (renderSurfaceLayer->maskLayer()) {
renderSurfaceLayer->maskLayer()->setVisibleLayerRect(IntRect(IntPoint(), renderSurfaceLayer->contentBounds()));
- renderSurfaceLayer->maskLayer()->paintContentsIfDirty();
+ paintContentsIfDirty(renderSurfaceLayer->maskLayer(), paintType);
}
LayerChromium* replicaLayer = renderSurfaceLayer->replicaLayer();
if (replicaLayer) {
- replicaLayer->paintContentsIfDirty();
+ paintContentsIfDirty(replicaLayer, paintType);
if (replicaLayer->maskLayer()) {
replicaLayer->maskLayer()->setVisibleLayerRect(IntRect(IntPoint(), replicaLayer->maskLayer()->contentBounds()));
- replicaLayer->maskLayer()->paintContentsIfDirty();
+ paintContentsIfDirty(replicaLayer->maskLayer(), paintType);
}
}
}
-void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList)
+void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList, PaintType paintType)
{
for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
LayerChromium* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
@@ -409,7 +438,7 @@
ASSERT(renderSurface);
ASSERT(renderSurface->drawOpacity());
- paintMaskAndReplicaForRenderSurface(renderSurfaceLayer);
+ paintMaskAndReplicaForRenderSurface(renderSurfaceLayer, paintType);
const LayerList& layerList = renderSurface->layerList();
for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
@@ -420,10 +449,9 @@
if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget<LayerChromium>(layer, renderSurfaceLayer->id()))
continue;
- ASSERT(layer->opacity());
ASSERT(!layer->bounds().isEmpty());
- layer->paintContentsIfDirty();
+ paintContentsIfDirty(layer, paintType);
}
}
}
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h (103128 => 103129)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2011-12-17 00:27:33 UTC (rev 103129)
@@ -202,8 +202,10 @@
private:
typedef Vector<RefPtr<LayerChromium> > LayerList;
- void paintLayerContents(const LayerList&);
- void paintMaskAndReplicaForRenderSurface(LayerChromium*);
+ enum PaintType { PaintVisible, PaintIdle };
+ static void paintContentsIfDirty(LayerChromium*, PaintType);
+ void paintLayerContents(const LayerList&, PaintType);
+ void paintMaskAndReplicaForRenderSurface(LayerChromium*, PaintType);
void updateLayers(LayerChromium*);
void clearPendingUpdate();
@@ -234,6 +236,7 @@
float m_pageScale;
float m_minPageScale, m_maxPageScale;
+ bool m_triggerIdlePaints;
};
}
Modified: trunk/Source/WebKit/chromium/ChangeLog (103128 => 103129)
--- trunk/Source/WebKit/chromium/ChangeLog 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebKit/chromium/ChangeLog 2011-12-17 00:27:33 UTC (rev 103129)
@@ -1,3 +1,21 @@
+2011-12-16 Eric Penner <epen...@google.com>
+
+ [chromium] Need to prepaint tiles in TiledLayerChromium
+ https://bugs.webkit.org/show_bug.cgi?id=72686
+
+ Reviewed by James Robinson.
+
+ * tests/CCLayerTreeHostTest.cpp:
+ (WTF::ContentLayerChromiumWithUpdateTracking::idlePaintContentsCount):
+ (WTF::ContentLayerChromiumWithUpdateTracking::resetPaintContentsCount):
+ (WTF::ContentLayerChromiumWithUpdateTracking::idlePaintContentsIfDirty):
+ (WTF::ContentLayerChromiumWithUpdateTracking::ContentLayerChromiumWithUpdateTracking):
+ (WTF::CCLayerTreeHostTestOpacityChange::afterTest):
+ * tests/TiledLayerChromiumTest.cpp:
+ (WTF::FakeTiledLayerChromium::prepareToUpdateIdle):
+ (WTF::FakeTiledLayerChromium::needsIdlePaint):
+ (WTF::TEST):
+
2011-12-16 James Robinson <jam...@chromium.org>
[chromium] Remove WebCString's dependency on WebCore
Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (103128 => 103129)
--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2011-12-17 00:27:33 UTC (rev 103129)
@@ -953,7 +953,8 @@
static PassRefPtr<ContentLayerChromiumWithUpdateTracking> create(CCLayerDelegate *delegate) { return adoptRef(new ContentLayerChromiumWithUpdateTracking(delegate)); }
int paintContentsCount() { return m_paintContentsCount; }
- void resetPaintContentsCount() { m_paintContentsCount = 0; }
+ int idlePaintContentsCount() { return m_idlePaintContentsCount; }
+ void resetPaintContentsCount() { m_paintContentsCount = 0; m_idlePaintContentsCount = 0;}
int updateCount() { return m_updateCount; }
void resetUpdateCount() { m_updateCount = 0; }
@@ -964,6 +965,12 @@
m_paintContentsCount++;
}
+ virtual void idlePaintContentsIfDirty()
+ {
+ ContentLayerChromium::idlePaintContentsIfDirty();
+ m_idlePaintContentsCount++;
+ }
+
virtual void updateCompositorResources(GraphicsContext3D* context, CCTextureUpdater& updater)
{
ContentLayerChromium::updateCompositorResources(context, updater);
@@ -974,12 +981,14 @@
explicit ContentLayerChromiumWithUpdateTracking(CCLayerDelegate *delegate)
: ContentLayerChromium(delegate)
, m_paintContentsCount(0)
+ , m_idlePaintContentsCount(0)
, m_updateCount(0)
{
setBounds(IntSize(10, 10));
}
int m_paintContentsCount;
+ int m_idlePaintContentsCount;
int m_updateCount;
};
@@ -1010,6 +1019,9 @@
// paintContentsIfDirty() should have been called once.
EXPECT_EQ(1, m_updateCheckLayer->paintContentsCount());
+ // idlePaintContentsIfDirty() should have been called once
+ EXPECT_EQ(1, m_updateCheckLayer->idlePaintContentsCount());
+
// updateCompositorResources() should have been called the same
// amout of times as paintContentsIfDirty().
EXPECT_EQ(m_updateCheckLayer->paintContentsCount(),
Modified: trunk/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp (103128 => 103129)
--- trunk/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp 2011-12-17 00:18:52 UTC (rev 103128)
+++ trunk/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp 2011-12-17 00:27:33 UTC (rev 103129)
@@ -97,6 +97,16 @@
TiledLayerChromium::prepareToUpdate(rect);
}
+ void prepareToUpdateIdle(const IntRect& rect)
+ {
+ TiledLayerChromium::prepareToUpdateIdle(rect);
+ }
+
+ bool needsIdlePaint(const IntRect& rect)
+ {
+ return TiledLayerChromium::needsIdlePaint(rect);
+ }
+
virtual TextureManager* textureManager() const { return m_textureManager; }
private:
@@ -122,6 +132,7 @@
CCTextureUpdater updater(&textureAllocator);
// The tile size is 100x100, so this invalidates and then paints two tiles.
+ layer->setBounds(IntSize(100, 200));
layer->invalidateRect(IntRect(0, 0, 100, 200));
layer->prepareToUpdate(IntRect(0, 0, 100, 200));
layer->updateCompositorResources(0, updater);
@@ -145,5 +156,107 @@
EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
}
+TEST(TiledLayerChromiumTest, pushIdlePaintTiles)
+{
+ OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
+ RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
+ DebugScopedSetImplThread implThread;
+ RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0));
+
+ FakeTextureAllocator textureAllocator;
+ CCTextureUpdater updater(&textureAllocator);
+
+ // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the center.
+ IntSize contentBounds(500, 500);
+ IntRect contentRect(IntPoint::zero(), contentBounds);
+ IntRect visibleRect(200, 200, 100, 100);
+
+ // This invalidates 25 tiles and then paints one visible tile.
+ layer->setBounds(contentBounds);
+ layer->setVisibleLayerRect(visibleRect);
+ layer->invalidateRect(contentRect);
+ layer->prepareToUpdate(visibleRect);
+
+ // We should need idle-painting for 3x3 tiles in the center.
+ EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
+
+ layer->updateCompositorResources(0, updater);
+ layer->pushPropertiesTo(layerImpl.get());
+
+ // We should have one tile on the impl side.
+ EXPECT_TRUE(layerImpl->hasTileAt(2, 2));
+
+ textureManager->unprotectAllTextures();
+
+ // For the next four updates, we should detect we still need idle painting.
+ for (int i = 0; i < 4; i++) {
+ layer->prepareToUpdate(visibleRect);
+ EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
+ layer->prepareToUpdateIdle(visibleRect);
+ layer->updateCompositorResources(0, updater);
+ layer->pushPropertiesTo(layerImpl.get());
+ textureManager->unprotectAllTextures();
+ }
+
+ // After four passes of idle painting, we should be finished painting
+ EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
+
+ // We should have one tile surrounding the visible tile on all sides, but no other tiles.
+ IntRect idlePaintTiles(1, 1, 3, 3);
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ if (idlePaintTiles.contains(i, j))
+ EXPECT_TRUE(layerImpl->hasTileAt(i, j));
+ else
+ EXPECT_FALSE(layerImpl->hasTileAt(i, j));
+ }
+ }
+}
+
+
+TEST(TiledLayerChromiumTest, idlePaintOutOfMemory)
+{
+ // The tile size is 100x100. Setup 5x5 tiles with one 1x1 visible tile in the center.
+ IntSize contentBounds(300, 300);
+ IntRect contentRect(IntPoint::zero(), contentBounds);
+ IntRect visibleRect(100, 100, 100, 100);
+
+ // We have enough memory for only the visible rect, so we will run out of memory in first idle paint.
+ int memoryLimit = 4 * 100 * 100; // 2 tiles, 4 bytes per pixel.
+
+ OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit / 2, 1024);
+ RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
+ DebugScopedSetImplThread implThread;
+ RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0));
+
+ FakeTextureAllocator textureAllocator;
+ CCTextureUpdater updater(&textureAllocator);
+
+ // This invalidates 9 tiles and then paints one visible tile.
+ layer->setBounds(contentBounds);
+ layer->setVisibleLayerRect(visibleRect);
+ layer->invalidateRect(contentRect);
+ layer->prepareToUpdate(visibleRect);
+
+ // We should need idle-painting for 3x3 tiles surounding visible tile.
+ EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
+
+ layer->updateCompositorResources(0, updater);
+ layer->pushPropertiesTo(layerImpl.get());
+
+ // We should have one tile on the impl side.
+ EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
+
+ textureManager->unprotectAllTextures();
+ layer->prepareToUpdate(visibleRect);
+ layer->prepareToUpdateIdle(visibleRect);
+
+ // We shouldn't signal we need another idle paint after we run out of memory.
+ EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
+
+ layer->updateCompositorResources(0, updater);
+ layer->pushPropertiesTo(layerImpl.get());
+}
+
} // namespace