summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp28
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h2
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasLayer.h1
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp49
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.h3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp9
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp25
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h7
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp84
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h11
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp6
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp35
20 files changed, 217 insertions, 98 deletions
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 1fe30de..4440912 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -60,10 +60,11 @@
namespace WebCore {
-using namespace android;
+using namespace android::uirenderer;
GLWebViewState::GLWebViewState()
: m_frameworkLayersInval(0, 0, 0, 0)
+ , m_doFrameworkFullInval(false)
, m_isScrolling(false)
, m_isVisibleContentRectScrolling(false)
, m_goingDown(true)
@@ -194,6 +195,12 @@ void GLWebViewState::resetLayersDirtyArea()
m_frameworkLayersInval.setY(0);
m_frameworkLayersInval.setWidth(0);
m_frameworkLayersInval.setHeight(0);
+ m_doFrameworkFullInval = false;
+}
+
+void GLWebViewState::doFrameworkFullInval()
+{
+ m_doFrameworkFullInval = true;
}
double GLWebViewState::setupDrawing(const IntRect& invScreenRect,
@@ -338,7 +345,7 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect,
// TODO: upload as many textures as possible within a certain time limit
int returnFlags = 0;
if (ImagesManager::instance()->prepareTextures(this))
- returnFlags |= uirenderer::DrawGlInfo::kStatusDraw;
+ returnFlags |= DrawGlInfo::kStatusDraw;
if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) {
ALOGW("WARNING, scale seems corrupted after update: %e", scale);
@@ -352,11 +359,14 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect,
titleBarHeight, screenClip, scale);
TexturesResult nbTexturesNeeded;
- bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering;
+ bool scrolling = isScrolling();
+ bool singleSurfaceMode = m_layersRenderingMode == kSingleSurfaceRendering;
m_glExtras.setVisibleContentRect(visibleContentRect);
+
returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, invScreenRect,
visibleContentRect,
- scale, fastSwap,
+ scale, scrolling,
+ singleSurfaceMode,
collectionsSwappedPtr,
newCollectionHasAnimPtr,
&nbTexturesNeeded, shouldDraw);
@@ -371,16 +381,16 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect,
if (setLayersRenderingMode(nbTexturesNeeded)) {
TilesManager::instance()->dirtyAllTiles();
- returnFlags |= uirenderer::DrawGlInfo::kStatusDraw | uirenderer::DrawGlInfo::kStatusInvoke;
+ returnFlags |= DrawGlInfo::kStatusDraw | DrawGlInfo::kStatusInvoke;
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
- if (returnFlags & uirenderer::DrawGlInfo::kStatusDraw) {
+ if (returnFlags & DrawGlInfo::kStatusDraw) {
// returnFlags & kStatusDraw && empty inval region means we've inval'd everything,
// but don't have new content. Keep redrawing full view (0,0,0,0)
// until tile generation catches up and we swap pages.
- bool fullScreenInval = m_frameworkLayersInval.isEmpty();
+ bool fullScreenInval = m_frameworkLayersInval.isEmpty() || m_doFrameworkFullInval;
if (!fullScreenInval) {
m_frameworkLayersInval.inflate(1);
@@ -390,8 +400,8 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect,
invalRect->setWidth(m_frameworkLayersInval.width());
invalRect->setHeight(m_frameworkLayersInval.height());
- ALOGV("invalRect(%d, %d, %d, %d)", inval.x(),
- inval.y(), inval.width(), inval.height());
+ ALOGV("invalRect(%d, %d, %d, %d)", invalRect->x(),
+ invalRect->y(), invalRect->width(), invalRect->height());
if (!invalRect->intersects(invScreenRect)) {
// invalidate is occurring offscreen, do full inval to guarantee redraw
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index 7892e83..b643405 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -189,6 +189,7 @@ public:
void addDirtyArea(const IntRect& rect);
void resetLayersDirtyArea();
+ void doFrameworkFullInval();
bool goingDown() { return m_goingDown; }
bool goingLeft() { return m_goingLeft; }
@@ -219,6 +220,7 @@ private:
SkRect m_visibleContentRect;
IntRect m_frameworkLayersInval;
+ bool m_doFrameworkFullInval;
#ifdef MEASURES_PERF
unsigned int m_totalTimeCounter;
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index a6bf6af..3975545 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -531,8 +531,8 @@ void GraphicsLayerAndroid::updateScrollingLayers()
if (layerNeedsOverflow) {
ASSERT(!m_foregroundLayer && !m_foregroundClipLayer);
m_foregroundLayer = new ScrollableLayerAndroid(layer);
+ m_foregroundLayer->setIntrinsicallyComposited(true);
- // TODO: can clip layer be set to not intrinsically composited?
m_foregroundClipLayer = new LayerAndroid(layer);
m_foregroundClipLayer->setMasksToBounds(true);
m_foregroundClipLayer->addChild(m_foregroundLayer);
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
index 62a5824..3241a61 100644
--- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
@@ -79,8 +79,10 @@ void BaseLayerAndroid::updatePositionsRecursive(const SkRect& visibleContentRect
{
updateLayerPositions(visibleContentRect);
TransformationMatrix ident;
- FloatRect clip(0, 0, 1e10, 1e10);
- updateGLPositionsAndScale(ident, clip, 1, state()->scale());
+ FloatRect clip(0, 0, getWidth(), getHeight());
+
+ float scale = state() ? state()->scale() : 1.0f;
+ updateGLPositionsAndScale(ident, clip, 1, scale);
}
ForegroundBaseLayerAndroid::ForegroundBaseLayerAndroid(LayerContent* content)
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp
index 93806ff..4a7f161 100644
--- a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp
@@ -52,6 +52,8 @@ CanvasLayer::CanvasLayer(RenderLayer* owner, HTMLCanvasElement* canvas)
{
init();
m_canvas->addObserver(this);
+ // Make sure we initialize in case the canvas has already been laid out
+ canvasResized(m_canvas);
}
CanvasLayer::CanvasLayer(const CanvasLayer& layer)
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h
index c719451..fce6453 100644
--- a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h
@@ -52,6 +52,7 @@ public:
virtual bool drawGL(bool layerTilesDisabled);
virtual void contentDraw(SkCanvas* canvas, PaintStyle style);
virtual bool needsTexture();
+ virtual bool needsIsolatedSurface() { return true; }
protected:
virtual InvalidateFlags onSetHwAccelerated(bool hwAccelerated);
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index 4a6bcbe..95e6825 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
@@ -273,6 +273,11 @@ void LayerAndroid::initAnimations() {
void LayerAndroid::addDirtyArea()
{
+ if (m_drawTransform.hasPerspective()) {
+ state()->doFrameworkFullInval();
+ return;
+ }
+
IntSize layerSize(getSize().width(), getSize().height());
FloatRect area =
@@ -578,9 +583,9 @@ void LayerAndroid::showLayer(int indent)
IntRect visible = visibleContentArea();
IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
m_clippingRect.width(), m_clippingRect.height());
- ALOGD("%s %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
+ ALOGD("%s s:%x %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
"clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d originalLayer: %x %d",
- spaces, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(),
+ spaces, m_surface, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(),
subclassType(), uniqueId(), this, m_owningLayer,
needsTexture() ? "needsTexture" : "",
m_imageCRC ? "hasImage" : "",
@@ -626,19 +631,8 @@ bool LayerAndroid::canJoinSurface(Surface* surface)
LayerAndroid* lastLayer = surface->getFirstLayer();
- // isolate non-tiled layers
- // TODO: remove this check so that multiple tiled layers with a invisible
- // one inbetween can be merged
- if (!needsTexture() || !lastLayer->needsTexture())
- return false;
-
- // isolate clipped layers
- // TODO: paint correctly with clip when merged
- if (m_haveClip || lastLayer->m_haveClip)
- return false;
-
// isolate intrinsically composited layers
- if (m_intrinsicallyComposited || lastLayer->m_intrinsicallyComposited)
+ if (needsIsolatedSurface() || lastLayer->needsIsolatedSurface())
return false;
// TODO: investigate potential for combining transformed layers
@@ -646,11 +640,6 @@ bool LayerAndroid::canJoinSurface(Surface* surface)
|| !lastLayer->m_drawTransform.isIdentityOrTranslation())
return false;
- // currently, we don't surface zoomable with non-zoomable layers (unless the
- // surface or the layer doesn't need a texture)
- if (surface->needsTexture() && needsTexture() && m_content->hasText() != surface->hasText())
- return false;
-
// TODO: compare other layer properties - fixed? overscroll? transformed?
return true;
#endif
@@ -670,24 +659,26 @@ void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
}
#ifdef LAYER_MERGING_DEBUG
- ALOGD("%*slayer %p(%d) rl %p %s surface %p, fixed %d, anim %d, intCom %d, haveClip %d scroll %d",
+ ALOGD("%*slayer %p(%d) rl %p %s surface %p lvl: %d, fixed %d, anim %d, intCom %d, haveClip %d scroll %d hasText (layer: %d surface: %d) hasContent %d size %.2f x %.2f",
4*mergeState->depth, "", this, m_uniqueId, m_owningLayer,
needNewSurface ? "NEW" : "joins", mergeState->currentSurface,
+ mergeState->nonMergeNestedLevel,
isPositionFixed(), m_animations.size() != 0,
m_intrinsicallyComposited,
m_haveClip,
- contentIsScrollable());
+ contentIsScrollable(), m_content ? m_content->hasText() : -1,
+ mergeState->currentSurface ? mergeState->currentSurface->hasText() : -1,
+ needsTexture(), getWidth(), getHeight());
#endif
mergeState->currentSurface->addLayer(this, m_drawTransform);
m_surface = mergeState->currentSurface;
- if (m_haveClip || contentIsScrollable() || isPositionFixed()) {
+ if (contentIsScrollable() || isPositionFixed()) {
// disable layer merging within the children of these layer types
mergeState->nonMergeNestedLevel++;
}
-
// pass the surface through children in drawing order, so that they may
// attach themselves (and paint on it) if possible, or ignore it and create
// a new one if not
@@ -705,13 +696,17 @@ void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
mergeState->depth--;
}
- if (m_haveClip || contentIsScrollable() || isPositionFixed()) {
+ if (contentIsScrollable() || isPositionFixed()) {
// re-enable joining
mergeState->nonMergeNestedLevel--;
// disallow layers painting after to join with this surface
mergeState->currentSurface = 0;
}
+
+ if (needsIsolatedSurface())
+ mergeState->currentSurface = 0;
+
}
// We call this in WebViewCore, when copying the tree of layers.
@@ -826,12 +821,10 @@ bool LayerAndroid::drawGL(bool layerTilesDisabled)
bool askScreenUpdate = false;
m_atomicSync.lock();
- if (m_hasRunningAnimations || m_drawTransform.hasPerspective()) {
+ if (m_hasRunningAnimations)
askScreenUpdate = true;
- addDirtyArea();
- }
-
m_atomicSync.unlock();
+
return askScreenUpdate;
}
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index c7c795f..9b239ee 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -281,6 +281,9 @@ public:
Surface* surface() { return m_surface; }
void setIntrinsicallyComposited(bool intCom) { m_intrinsicallyComposited = intCom; }
+ virtual bool needsIsolatedSurface() {
+ return (needsTexture() && m_intrinsicallyComposited) || m_animations.size();
+ }
int setHwAccelerated(bool hwAccelerated);
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
index 2ec2659..be1e176 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -99,7 +99,8 @@ bool Surface::tryUpdateSurface(Surface* oldSurface)
bool fullInval = m_layers.size() != oldSurface->m_layers.size();
if (!fullInval) {
for (unsigned int i = 0; i < m_layers.size(); i++) {
- if (m_layers[i]->uniqueId() != oldSurface->m_layers[i]->uniqueId()) {
+ if ((m_layers[i]->uniqueId() != oldSurface->m_layers[i]->uniqueId())
+ || (m_layers[i]->fullContentAreaMapped() != oldSurface->m_layers[i]->fullContentAreaMapped())) {
// layer list has changed, fully invalidate
// TODO: partially invalidate based on layer size/position
fullInval = true;
@@ -226,19 +227,20 @@ void Surface::prepareGL(bool layerTilesDisabled, bool updateWithBlit)
bool Surface::drawGL(bool layerTilesDisabled)
{
bool tilesDisabled = layerTilesDisabled && !isBase();
- if (!getFirstLayer()->visible())
+ if (singleLayer() && !getFirstLayer()->visible())
return false;
bool isBaseLayer = isBase()
|| getFirstLayer()->subclassType() == LayerAndroid::FixedBackgroundImageLayer
|| getFirstLayer()->subclassType() == LayerAndroid::ForegroundBaseLayer;
- if (!isBaseLayer) {
- // TODO: why are clipping regions wrong for base layer?
- FloatRect drawClip = getFirstLayer()->drawClip();
- FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
- TilesManager::instance()->shader()->clip(clippingRect);
+ FloatRect drawClip = getFirstLayer()->drawClip();
+ if (!singleLayer()) {
+ for (unsigned int i = 1; i < m_layers.size(); i++)
+ drawClip.unite(m_layers[i]->drawClip());
}
+ FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
+ TilesManager::instance()->shader()->clip(clippingRect);
bool askRedraw = false;
if (m_surfaceBacking && !tilesDisabled) {
@@ -252,8 +254,12 @@ bool Surface::drawGL(bool layerTilesDisabled)
}
// draw member layers (draws image textures, glextras)
- for (unsigned int i = 0; i < m_layers.size(); i++)
- askRedraw |= m_layers[i]->drawGL(tilesDisabled);
+ for (unsigned int i = 0; i < m_layers.size(); i++) {
+ if (m_layers[i]->drawGL(tilesDisabled)) {
+ m_layers[i]->addDirtyArea();
+ askRedraw = true;
+ }
+ }
return askRedraw;
}
@@ -263,7 +269,16 @@ void Surface::swapTiles()
if (!m_surfaceBacking)
return;
- m_surfaceBacking->swapTiles();
+ if (m_surfaceBacking->swapTiles())
+ addFrameworkInvals();
+}
+
+void Surface::addFrameworkInvals()
+{
+ // Let's return an inval area to framework that will
+ // contain all of our layers' areas
+ for (unsigned int i = 0; i < m_layers.size(); i++)
+ m_layers[i]->addDirtyArea();
}
bool Surface::isReady()
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.h b/Source/WebCore/platform/graphics/android/rendering/Surface.h
index a79a286..0286259 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.h
@@ -52,6 +52,7 @@ public:
void prepareGL(bool layerTilesDisabled, bool updateWithBlit);
bool drawGL(bool layerTilesDisabled);
void swapTiles();
+ void addFrameworkInvals();
bool isReady();
bool isMissingContent();
bool canUpdateWithBlit();
@@ -93,7 +94,7 @@ public:
LayerMergeState(Vector<Surface*>* const allGroups)
: surfaceList(allGroups)
, currentSurface(0)
- , nonMergeNestedLevel(-1) // start at -1 to ignore first LayerAndroid's clipping
+ , nonMergeNestedLevel(0)
, depth(0)
{}
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
index af96560..78a9861 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
@@ -146,11 +146,12 @@ void SurfaceBacking::markAsDirty(const SkRegion& dirtyArea)
m_lowResTileGrid->markAsDirty(dirtyArea);
}
-void SurfaceBacking::swapTiles()
+bool SurfaceBacking::swapTiles()
{
- m_backTileGrid->swapTiles();
- m_frontTileGrid->swapTiles();
- m_lowResTileGrid->swapTiles();
+ bool swap = m_backTileGrid->swapTiles();
+ swap |= m_frontTileGrid->swapTiles();
+ swap |= m_lowResTileGrid->swapTiles();
+ return swap;
}
void SurfaceBacking::computeTexturesAmount(TexturesResult* result, LayerAndroid* layer)
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
index 7d3e93c..137a25b 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
@@ -44,7 +44,7 @@ public:
const IntRect& prepareArea, const IntRect& fullContentArea,
TilePainter* painter, bool aggressiveRendering,
bool updateWithBlit);
- void swapTiles();
+ bool swapTiles();
void drawGL(const IntRect& visibleContentArea, float opacity,
const TransformationMatrix* transform, bool aggressiveRendering,
const Color* background);
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
index 3b6b306..0e5c3ba 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
@@ -139,6 +139,12 @@ void SurfaceCollection::swapTiles()
m_surfaces[i]->swapTiles();
}
+void SurfaceCollection::addFrameworkInvals()
+{
+ for (unsigned int i = 0; i < m_surfaces.size(); i++)
+ m_surfaces[i]->addFrameworkInvals();
+}
+
bool SurfaceCollection::isReady()
{
// Override layer readiness check for single surface mode
@@ -156,11 +162,14 @@ bool SurfaceCollection::isReady()
return true;
}
-bool SurfaceCollection::isMissingBackgroundContent()
+bool SurfaceCollection::isBaseSurfaceReady()
{
- if (!m_compositedRoot)
- return true;
+ // m_surfaces[0] should be the base surface when in single surface mode.
+ return m_surfaces[0]->isReady();
+}
+bool SurfaceCollection::isMissingBackgroundContent()
+{
// return true when the first surface is missing content (indicating the
// entire viewport isn't covered)
return m_surfaces[0]->isMissingContent();
@@ -238,4 +247,14 @@ void SurfaceCollection::updateLayerPositions(const SkRect& visibleContentRect)
#endif
}
+int SurfaceCollection::backedSize()
+{
+ int count = 0;
+ for (unsigned int i = 0; i < m_surfaces.size(); i++) {
+ if (m_surfaces[i]->needsTexture())
+ count++;
+ }
+ return count;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
index 5967c70..7088bec 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
@@ -52,7 +52,9 @@ public:
bool drawGL(const SkRect& visibleContentRect);
Color getBackgroundColor();
void swapTiles();
+ void addFrameworkInvals();
bool isReady();
+ bool isBaseSurfaceReady();
bool isMissingBackgroundContent();
void computeTexturesAmount(TexturesResult* result);
@@ -66,9 +68,12 @@ public:
bool hasCompositedAnimations();
void updateScrollableLayer(int layerId, int x, int y);
+ int size() { return m_surfaces.size(); }
+ int backedSize();
+
private:
void updateLayerPositions(const SkRect& visibleContentRect);
- BaseLayerAndroid* m_compositedRoot;
+ BaseLayerAndroid* const m_compositedRoot;
WTF::Vector<Surface*> m_surfaces;
};
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
index 7c42bd9..5abca02 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
@@ -36,11 +36,15 @@
namespace WebCore {
+using namespace android::uirenderer;
+
SurfaceCollectionManager::SurfaceCollectionManager()
: m_drawingCollection(0)
, m_paintingCollection(0)
, m_queuedCollection(0)
, m_fastSwapMode(false)
+ , m_previouslyScrolling(false)
+ , m_newPaintingCollection(false)
{
}
@@ -64,12 +68,14 @@ void SurfaceCollectionManager::swap()
// if we have a drawing collection, discard it since the painting collection is done
if (m_drawingCollection) {
ALOGV("destroying drawing collection %p", m_drawingCollection);
+ m_drawingCollection->addFrameworkInvals();
SkSafeUnref(m_drawingCollection);
}
// painting collection becomes the drawing collection
ALOGV("drawing collection %p", m_paintingCollection);
m_paintingCollection->setIsDrawing(); // initialize animations
+ m_paintingCollection->addFrameworkInvals();
if (m_queuedCollection) {
// start painting with the queued collection
@@ -95,6 +101,13 @@ void SurfaceCollectionManager::clearCollections()
m_queuedCollection = 0;
}
+void SurfaceCollectionManager::updatePaintingCollection(SurfaceCollection* newCollection)
+{
+ m_paintingCollection = newCollection;
+ m_paintingCollection->setIsPainting(m_drawingCollection);
+ m_newPaintingCollection = true;
+}
+
// a new layer collection has arrived, queue it if we're painting something already,
// or start painting it if we aren't. Returns true if the manager has two collections
// already queued.
@@ -106,10 +119,8 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne
if (!newCollection || brandNew) {
clearCollections();
- if (brandNew) {
- m_paintingCollection = newCollection;
- m_paintingCollection->setIsPainting(m_drawingCollection);
- }
+ if (brandNew)
+ updatePaintingCollection(newCollection);
return false;
}
@@ -137,8 +148,7 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne
m_queuedCollection = newCollection;
} else {
// don't have painting collection, paint this one!
- m_paintingCollection = newCollection;
- m_paintingCollection->setIsPainting(m_drawingCollection);
+ updatePaintingCollection(newCollection);
}
return m_drawingCollection && TilesManager::instance()->useDoubleBuffering();
}
@@ -153,18 +163,52 @@ void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y)
m_drawingCollection->updateScrollableLayer(layerId, x, y);
}
+
+int SurfaceCollectionManager::singleSurfaceModeInvalidation(bool scrolling,
+ bool shouldDraw)
+{
+ int returnFlags = 0;
+ // In single surface mode, we need to dirty all the tiles when we are finishing
+ // scrolling or have an incoming painting tree.
+ bool requireDirtyAll = (m_previouslyScrolling && !scrolling)
+ || m_newPaintingCollection;
+ if (requireDirtyAll)
+ TilesManager::instance()->dirtyAllTiles();
+
+ // We also need to tell the framework to continue to invoke until
+ // the base layer is ready.
+ bool drawingBaseSurfaceReady = m_drawingCollection
+ && m_drawingCollection->isBaseSurfaceReady();
+ bool requireInvoke = requireDirtyAll || !drawingBaseSurfaceReady;
+ if (requireInvoke)
+ returnFlags |= DrawGlInfo::kStatusInvoke;
+
+ // When the base layer is ready, we can ask the framework to draw.
+ if (!shouldDraw && drawingBaseSurfaceReady)
+ returnFlags |= DrawGlInfo::kStatusDraw;
+
+ m_newPaintingCollection = false;
+ m_previouslyScrolling = scrolling;
+
+ return returnFlags;
+}
+
int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleContentRect, float scale,
- bool enterFastSwapMode,
+ bool scrolling, bool singleSurfaceMode,
bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
TexturesResult* texturesResultPtr, bool shouldDraw)
{
- m_fastSwapMode |= enterFastSwapMode;
+ m_fastSwapMode |= scrolling || singleSurfaceMode;
ALOGV("drawGL, D %p, P %p, Q %p, fastSwap %d shouldDraw %d",
m_drawingCollection, m_paintingCollection,
m_queuedCollection, m_fastSwapMode, shouldDraw);
+ // ask for kStatusInvoke while painting, kStatusDraw if we have content to be redrawn next frame
+ // returning 0 indicates all painting complete, no framework inval needed.
+ int returnFlags = 0;
+
bool didCollectionSwap = false;
if (m_paintingCollection) {
ALOGV("preparing painting collection %p", m_paintingCollection);
@@ -184,6 +228,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
if (newCollectionHasAnimPtr)
*newCollectionHasAnimPtr = m_paintingCollection->hasCompositedAnimations();
swap();
+ returnFlags |= uirenderer::DrawGlInfo::kStatusDraw;
}
} else if (m_drawingCollection) {
ALOGV("preparing drawing collection %p", m_drawingCollection);
@@ -191,12 +236,11 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
m_drawingCollection->computeTexturesAmount(texturesResultPtr);
}
- // ask for kStatusInvoke while painting, kStatusDraw if we have content to be redrawn next frame
- // returning 0 indicates all painting complete, no framework inval needed.
- int returnFlags = 0;
-
if (m_paintingCollection)
- returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke;
+ returnFlags |= DrawGlInfo::kStatusInvoke;
+
+ if (singleSurfaceMode)
+ returnFlags |= singleSurfaceModeInvalidation(scrolling, shouldDraw);
if (!shouldDraw) {
if (didCollectionSwap
@@ -205,11 +249,11 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
&& m_drawingCollection->isReady())) {
// either a swap just occurred, or there is no more work to be done: do a full draw
m_drawingCollection->swapTiles();
- returnFlags |= uirenderer::DrawGlInfo::kStatusDraw;
+ returnFlags |= DrawGlInfo::kStatusDraw;
} else {
// current collection not ready - invoke functor in process mode
// until either drawing or painting collection is ready
- returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke;
+ returnFlags |= DrawGlInfo::kStatusInvoke;
}
return returnFlags;
@@ -234,7 +278,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
m_fastSwapMode = false;
} else {
// drawing isn't ready, must redraw
- returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke;
+ returnFlags |= DrawGlInfo::kStatusInvoke;
}
m_drawingCollection->evaluateAnimations(currentTime);
@@ -255,8 +299,14 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
GLUtils::clearBackgroundIfOpaque(&background);
}
+#ifdef DEBUG
+ ALOGV("Drawing %d / %d surfaces",
+ m_drawingCollection ? m_drawingCollection->backedSize() : -1,
+ m_drawingCollection ? m_drawingCollection->size() : -1);
+#endif
+
if (m_drawingCollection && m_drawingCollection->drawGL(visibleContentRect))
- returnFlags |= uirenderer::DrawGlInfo::kStatusDraw;
+ returnFlags |= DrawGlInfo::kStatusDraw;
ALOGV("returnFlags %d, m_paintingCollection %d ", returnFlags, m_paintingCollection);
return returnFlags;
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
index be4fbca..6aed060 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
@@ -51,18 +51,25 @@ public:
int drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleContentRect, float scale,
- bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
+ bool scrolling, bool singleSurfaceMode,
+ bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
TexturesResult* texturesResultPtr, bool shouldDraw);
private:
void swap();
void clearCollections();
-
+ void updatePaintingCollection(SurfaceCollection* newCollection);
+ int singleSurfaceModeInvalidation(bool scrolling, bool shouldDraw);
SurfaceCollection* m_drawingCollection;
SurfaceCollection* m_paintingCollection;
SurfaceCollection* m_queuedCollection;
bool m_fastSwapMode;
+ // Used in single surface mode only. True if the previous frame is scrolling.
+ bool m_previouslyScrolling;
+ // Used in single surface mode only. True if there is a new painting tree
+ // added for the current frame.
+ bool m_newPaintingCollection;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
index 3487acd..9cd904e 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
@@ -97,13 +97,14 @@ bool TileGrid::isMissingContent()
return false;
}
-void TileGrid::swapTiles()
+bool TileGrid::swapTiles()
{
int swaps = 0;
for (unsigned int i = 0; i < m_tiles.size(); i++)
if (m_tiles[i]->swapTexturesIfNeeded())
swaps++;
ALOGV("TG %p swapping, swaps = %d", this, swaps);
+ return swaps != 0;
}
IntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale)
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.h b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
index b480419..665f4ec 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
@@ -52,7 +52,7 @@ public:
const IntRect& prepareArea, const IntRect& fullContentArea,
TilePainter* painter, int regionFlags = StandardRegion,
bool isLowResPrefetch = false, bool updateWithBlit = false);
- void swapTiles();
+ bool swapTiles();
void drawGL(const IntRect& visibleContentArea, float opacity,
const TransformationMatrix* transform, const Color* background = 0);
diff --git a/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp b/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
index 66c4bf3..03ef714 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
@@ -292,7 +292,11 @@ TileTexture* TilesManager::getAvailableTexture(Tile* owner)
// Sanity check that the tile does not already own a texture
if (owner->backTexture() && owner->backTexture()->owner() == owner) {
- availableTexturePool->remove(availableTexturePool->find(owner->backTexture()));
+ int removeIndex = availableTexturePool->find(owner->backTexture());
+
+ // TODO: investigate why texture isn't found
+ if (removeIndex >= 0)
+ availableTexturePool->remove(removeIndex);
return owner->backTexture();
}
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 6b669e8..f5dddc0 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -302,6 +302,7 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
bool layersChanged = false;
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ compState.m_positionedSibling = false;
compState.m_hasFixedElement = false;
#endif
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
@@ -657,27 +658,25 @@ bool RenderLayerCompositor::checkForPositionedElements(Vector<RenderLayer*>* lis
// composited. The layers' surfaces will be merged if needed UI-side.
for (int j = 0; j < listSize; ++j) {
RenderLayer* currentLayer = list->at(j);
- if (currentLayer->shouldComposite())
- continue;
- if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
- haveFixedLayer = j;
- fixedSibling = true;
- }
+ // clear the composited flag first
+ currentLayer->setShouldComposite(false);
- // Bypass fixed layers with a width or height or 1 or less...
- IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
- FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
- if ((currentLayerBounds.width() <= 1
- || currentLayerBounds.height() <= 1)
- && haveFixedLayer == j) {
- haveFixedLayer = -1;
- fixedSibling = false;
+ if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
+ // Ignore fixed layers with a width or height or 1 or less...
+ IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
+ FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
+ if (currentLayerBounds.width() > 1 && currentLayerBounds.height() > 1) {
+ haveFixedLayer = j;
+ fixedSibling = true;
+ }
+ continue;
}
- if (haveFixedLayer != -1 && haveFixedLayer != j)
+ if (haveFixedLayer != -1)
currentLayer->setShouldComposite(true);
}
+
return positionedSibling || fixedSibling;
}
@@ -867,6 +866,8 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
if (childState.m_hasFixedElement)
compositingState.m_hasFixedElement = true;
+ if (childState.m_positionedSibling)
+ compositingState.m_positionedSibling = true;
#endif
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
if (childState.m_hasScrollableElement)
@@ -889,7 +890,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
// We also need to check that we don't have a scrollable layer, as this
// would not have set the m_subtreeIsCompositing flag
- if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !childState.m_hasScrollableElement && !childState.m_hasFixedElement && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
+ if (layer->isRootLayer() && !childState.m_subtreeIsCompositing
+ && !childState.m_hasScrollableElement && !childState.m_positionedSibling && !childState.m_hasFixedElement
+ && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
#else
if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
#endif