diff options
Diffstat (limited to 'Source/WebCore')
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 |