diff options
Diffstat (limited to 'WebCore')
15 files changed, 153 insertions, 74 deletions
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 2f0e999..35c3b36 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -116,12 +116,11 @@ void BaseLayerAndroid::drawCanvas(SkCanvas* canvas) } #if USE(ACCELERATED_COMPOSITING) -bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale) +bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double currentTime) { if (!m_glWebViewState) return false; - double currentTime = WTF::currentTime(); bool goingDown = m_previousVisible.fTop - viewport.fTop <= 0; bool goingLeft = m_previousVisible.fLeft - viewport.fLeft >= 0; @@ -282,7 +281,8 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, shader->setViewRect(viewRect); shader->setViewport(visibleRect); - ret = drawBasePictureInGL(visibleRect, scale); + double currentTime = WTF::currentTime(); + ret = drawBasePictureInGL(visibleRect, scale, currentTime); if (countChildren() >= 1) { LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0)); @@ -311,7 +311,7 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, scale = m_glWebViewState->futureScale(); } compositedRoot->setScale(scale); - compositedRoot->computeTextureSize(); + compositedRoot->computeTextureSize(currentTime); compositedRoot->reserveGLTextures(); #ifdef DEBUG @@ -337,12 +337,6 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, glBindBuffer(GL_ARRAY_BUFFER, 0); m_previousVisible = visibleRect; -#ifdef DEBUG_COUNT - XLOG("GLWebViewState(%d) DoubleBufferedTexture(%d) BaseTile(%d) TileSet(%d) TiledPage(%d)", - GLWebViewState::count(), DoubleBufferedTexture::count(), - BaseTile::count(), TileSet::count(), TiledPage::count()); -#endif // DEBUG_COUNT - #endif // USE(ACCELERATED_COMPOSITING) #ifdef DEBUG ClassTracker::instance()->show(); diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.h b/WebCore/platform/graphics/android/BaseLayerAndroid.h index c57b13d..cb1caef 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.h +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.h @@ -59,7 +59,7 @@ public: void swapExtra(BaseLayerAndroid* base) { m_extra.swap(base->m_extra); } private: #if USE(ACCELERATED_COMPOSITING) - bool drawBasePictureInGL(SkRect& viewport, float scale); + bool drawBasePictureInGL(SkRect& viewport, float scale, double currentTime); GLWebViewState* m_glWebViewState; android::Mutex m_drawLock; diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp index 5ba094b..53d5c5e 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -127,7 +127,7 @@ void GLWebViewState::unlockBaseLayerUpdate() { } void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture, - const IntRect& rect) + const IntRect& rect, bool allowSame) { android::Mutex::Autolock lock(m_baseLayerLock); if (!m_baseLayerUpdate) @@ -135,7 +135,7 @@ void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture, layer->setExtra(picture); - if (m_lastInval == rect) + if (!allowSame && m_lastInval == rect) return; if (!rect.isEmpty()) diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h index 2082f2c..d28c16a 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.h +++ b/WebCore/platform/graphics/android/GLWebViewState.h @@ -169,7 +169,7 @@ public: unsigned int paintBaseLayerContent(SkCanvas* canvas); void setBaseLayer(BaseLayerAndroid* layer, const IntRect& rect); - void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&); + void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&, bool allowSame); void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale); TiledPage* sibling(TiledPage* page); diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index e887964..49f20ab 100644 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -271,7 +271,17 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point) if (point == m_position) return; - GraphicsLayer::setPosition(point); + FloatPoint pos(point); +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + // Add the scroll position back in. When scrolling a layer, all the children + // are positioned based on the content scroll. Adding the scroll position + // back in allows the children to draw based on 0,0. + RenderLayer* layer = renderLayerFromClient(m_client); + if (layer && layer->parent() && layer->parent()->hasOverflowScroll()) + pos += layer->parent()->scrolledContentOffset(); +#endif + + GraphicsLayer::setPosition(pos); #ifdef LAYER_DEBUG_2 LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)", @@ -279,7 +289,7 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point) m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height()); #endif updateFixedPosition(); - m_contentLayer->setPosition(point.x(), point.y()); + m_contentLayer->setPosition(pos.x(), pos.y()); askForSync(); } @@ -368,31 +378,6 @@ void GraphicsLayerAndroid::setDrawsContent(bool drawsContent) if (m_contentLayer->isRootLayer()) return; if (m_drawsContent) { -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - RenderLayer* layer = renderLayerFromClient(m_client); - if (layer) { - if (layer->hasOverflowScroll() && !m_foregroundLayer) { - m_foregroundLayer = new ScrollableLayerAndroid(); - m_foregroundClipLayer = new LayerAndroid(false); - m_foregroundClipLayer->setMasksToBounds(true); - - m_foregroundClipLayer->addChild(m_foregroundLayer); - m_contentLayer->addChild(m_foregroundClipLayer); - } else if (layer->isRootLayer() - && layer->renderer()->frame()->ownerRenderer()) { - // We have to do another check for scrollable content since an - // iframe might be compositing for other reasons. - FrameView* view = layer->renderer()->frame()->view(); - if (view->hasOverflowScroll()) { - // Replace the content layer with a scrollable layer. - LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer); - m_contentLayer->unref(); - m_contentLayer = layer; - } - } - } -#endif - m_haveContents = true; setNeedsDisplay(); } @@ -478,6 +463,79 @@ private: GraphicsLayerPaintingPhase m_originalPhase; }; +void GraphicsLayerAndroid::updateScrollingLayers() +{ +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + RenderLayer* layer = renderLayerFromClient(m_client); + if (!layer) + return; + bool hasOverflowScroll = m_foregroundLayer || m_contentLayer->contentIsScrollable(); + bool layerNeedsOverflow = layer->hasOverflowScroll(); + bool iframeNeedsOverflow = layer->isRootLayer() && + layer->renderer()->frame()->ownerRenderer() && + layer->renderer()->frame()->view()->hasOverflowScroll(); + + if (hasOverflowScroll && (layerNeedsOverflow || iframeNeedsOverflow)) { + // Already has overflow layers. + return; + } + if (!hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow) { + // Does not need overflow layers. + return; + } + if (layerNeedsOverflow || iframeNeedsOverflow) { + ASSERT(!hasOverflowScroll); + if (layerNeedsOverflow) { + ASSERT(!m_foregroundLayer && !m_foregroundClipLayer); + m_foregroundLayer = new ScrollableLayerAndroid(); + m_foregroundClipLayer = new LayerAndroid(false); + m_foregroundClipLayer->setMasksToBounds(true); + m_foregroundClipLayer->addChild(m_foregroundLayer); + m_contentLayer->addChild(m_foregroundClipLayer); + } else { + ASSERT(iframeNeedsOverflow && !m_contentLayer->contentIsScrollable()); + // No need to copy the children as they will be removed and synced. + m_contentLayer->removeChildren(); + // Replace the content layer with a scrollable layer. + LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer); + m_contentLayer->unref(); + m_contentLayer = layer; + if (m_parent) { + // The content layer has changed so the parent needs to sync + // children. + static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true; + } + } + // Need to rebuild our children based on the new structure. + m_needsSyncChildren = true; + askForSync(); + } else { + ASSERT(hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow); + ASSERT(m_contentLayer); + // Remove the foreground layers. + if (m_foregroundLayer) { + m_foregroundLayer->unref(); + m_foregroundLayer = 0; + m_foregroundClipLayer->unref(); + m_foregroundClipLayer = 0; + } + // No need to copy over children. + m_contentLayer->removeChildren(); + LayerAndroid* layer = new LayerAndroid(*m_contentLayer); + m_contentLayer->unref(); + m_contentLayer = layer; + if (m_parent) { + // The content layer has changed so the parent needs to sync + // children. + static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true; + } + // Children are all re-parented. + m_needsSyncChildren = true; + askForSync(); + } +#endif +} + bool GraphicsLayerAndroid::repaint() { LOG("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ", @@ -506,8 +564,13 @@ bool GraphicsLayerAndroid::repaint() m_foregroundLayer->setSize(contentsRect.width(), contentsRect.height()); // Paint everything else into the main recording canvas. phase.clear(GraphicsLayerPaintBackground); - if (!paintContext(m_foregroundLayer->recordContext(), contentsRect)) - return false; + + // Paint at 0,0. + IntSize scroll = layer->scrolledContentOffset(); + layer->scrollToOffset(0, 0, true, false); + // At this point, it doesn't matter if painting failed. + (void) paintContext(m_foregroundLayer->recordContext(), contentsRect); + layer->scrollToOffset(scroll.width(), scroll.height(), true, false); // Construct the clip layer for masking the contents. IntRect clip = layer->renderer()->absoluteBoundingBoxRect(); @@ -830,10 +893,16 @@ void GraphicsLayerAndroid::syncChildren() { if (m_needsSyncChildren) { m_contentLayer->removeChildren(); - if (m_foregroundClipLayer) + LayerAndroid* layer = m_contentLayer; + if (m_foregroundClipLayer) { m_contentLayer->addChild(m_foregroundClipLayer); + // Use the scrollable content layer as the parent of the children so + // that they move with the content. + layer = m_foregroundLayer; + layer->removeChildren(); + } for (unsigned int i = 0; i < m_children.size(); i++) - m_contentLayer->addChild(m_children[i]->platformLayer()); + layer->addChild(m_children[i]->platformLayer()); m_needsSyncChildren = false; } } @@ -857,6 +926,7 @@ void GraphicsLayerAndroid::syncCompositingState() for (unsigned int i = 0; i < m_children.size(); i++) m_children[i]->syncCompositingState(); + updateScrollingLayers(); syncChildren(); syncMask(); diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index ce6bac1..da247ca 100644 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -127,6 +127,7 @@ private: void syncMask(); void updateFixedPosition(); + void updateScrollingLayers(); // with SkPicture, we always repaint the entire layer's content. bool repaint(); diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index bee423c..7375cba 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -75,7 +75,8 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), m_reservedTexture(0), m_pictureUsed(0), m_requestSent(false), - m_scale(1) + m_scale(1), + m_lastComputeTextureSize(0) { m_backgroundColor = 0; @@ -123,6 +124,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), m_dirty = layer.m_dirty; m_pictureUsed = layer.m_pictureUsed; m_scale = layer.m_scale; + m_lastComputeTextureSize = 0; for (int i = 0; i < layer.countChildren(); i++) addChild(layer.getChild(i)->copy())->unref(); @@ -147,7 +149,8 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(), m_drawingTexture(0), m_reservedTexture(0), m_requestSent(false), - m_scale(1) + m_scale(1), + m_lastComputeTextureSize(0) { m_backgroundColor = 0; m_dirty = false; @@ -651,8 +654,12 @@ static inline bool compareLayerFullSize(const LayerAndroid* a, const LayerAndroi return sizeA > sizeB; } -void LayerAndroid::computeTextureSize() +void LayerAndroid::computeTextureSize(double time) { + if (m_lastComputeTextureSize + s_computeTextureDelay > time) + return; + m_lastComputeTextureSize = time; + // First, we collect the layers, computing m_layerTextureRect // as being clipped against the viewport Vector <LayerAndroid*> layers; diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 2cb56c1..0d5a878 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -111,7 +111,7 @@ public: void showLayers(int indent = 0); // Texture size functions - void computeTextureSize(); + void computeTextureSize(double time); void collect(Vector<LayerAndroid*>& layers, int& size); int clippedTextureSize() const; @@ -325,6 +325,10 @@ private: float m_scale; + // We try to not always compute the texture size, as this is quite heavy + static const double s_computeTextureDelay = 0.2; // 200 ms + double m_lastComputeTextureSize; + // This mutex serves two purposes. (1) It ensures that certain operations // happen atomically and (2) it makes sure those operations are synchronized // across all threads and cores. diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp index 620aa6f..36988dd 100644 --- a/WebCore/platform/graphics/android/TiledPage.cpp +++ b/WebCore/platform/graphics/android/TiledPage.cpp @@ -49,8 +49,6 @@ #endif // DEBUG -#define MAX_TILES 256 - namespace WebCore { using namespace android; @@ -65,7 +63,7 @@ TiledPage::TiledPage(int id, GLWebViewState* state) , m_latestPictureInval(0) , m_prepare(false) { - m_baseTiles = new BaseTile[MAX_TILES]; + m_baseTiles = new BaseTile[TilesManager::getMaxTextureAllocation() + 1]; #ifdef DEBUG_COUNT ClassTracker::instance()->increment("TiledPage"); #endif diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp index 571d9cc..0fb3b1b 100644 --- a/WebCore/platform/graphics/android/TilesManager.cpp +++ b/WebCore/platform/graphics/android/TilesManager.cpp @@ -58,7 +58,7 @@ // at least 5 * 3 = 15 textures. We can also enable offscreen textures #define EXPANDED_TILE_BOUNDS_X 1 #define EXPANDED_TILE_BOUNDS_Y 4 -#define MAX_TEXTURE_ALLOCATION (5+EXPANDED_TILE_BOUNDS_X*2)*(3+EXPANDED_TILE_BOUNDS_Y*2)*2 +#define MAX_TEXTURE_ALLOCATION (5+1+EXPANDED_TILE_BOUNDS_X*2)*(3+1+EXPANDED_TILE_BOUNDS_Y*2)*2 #define TILE_WIDTH 300 #define TILE_HEIGHT 300 @@ -78,6 +78,11 @@ GLint TilesManager::getMaxTextureSize() return maxTextureSize; } +int TilesManager::getMaxTextureAllocation() +{ + return MAX_TEXTURE_ALLOCATION; +} + TilesManager::TilesManager() : m_layersMemoryUsage(0) , m_maxTextureCount(0) @@ -369,7 +374,8 @@ int TilesManager::maxTextureCount() void TilesManager::setMaxTextureCount(int max) { XLOG("setMaxTextureCount: %d", max); - if (m_maxTextureCount >= max && m_maxTextureCount) + if (max > MAX_TEXTURE_ALLOCATION || + (m_maxTextureCount >= max && m_maxTextureCount)) return; android::Mutex::Autolock lock(m_texturesLock); diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h index eeb38fe..29b7fc1 100644 --- a/WebCore/platform/graphics/android/TilesManager.h +++ b/WebCore/platform/graphics/android/TilesManager.h @@ -45,6 +45,7 @@ class TilesManager { public: static TilesManager* instance(); static GLint getMaxTextureSize(); + static int getMaxTextureAllocation(); static bool hardwareAccelerationEnabled() { diff --git a/WebCore/platform/graphics/android/android_graphics.cpp b/WebCore/platform/graphics/android/android_graphics.cpp index c046858..e50cfec 100644 --- a/WebCore/platform/graphics/android/android_graphics.cpp +++ b/WebCore/platform/graphics/android/android_graphics.cpp @@ -109,14 +109,8 @@ void CursorRing::draw(SkCanvas* canvas, LayerAndroid* layer, IntRect* inval) inval->unite(m_lastBounds); } -bool CursorRing::setup() +void CursorRing::setIsButton(const CachedNode* node) { - m_node->localCursorRings(m_frame, &m_rings); - if (!m_rings.size()) { - DBG_NAV_LOG("!rings.size()"); - m_viewImpl->m_hasCursorBounds = false; - return false; - } m_isButton = false; m_viewImpl->gButtonMutex.lock(); // If this is a button drawn by us (rather than webkit) do not draw the @@ -124,7 +118,7 @@ bool CursorRing::setup() // Should be in sync with recordButtons, since that will be called // before this. if (m_viewImpl->m_buttons.size() > 0) { - WebCore::Node* cursorPointer = (WebCore::Node*) m_node->nodePointer(); + WebCore::Node* cursorPointer = (WebCore::Node*) node->nodePointer(); Container* end = m_viewImpl->m_buttons.end(); for (Container* ptr = m_viewImpl->m_buttons.begin(); ptr != end; ptr++) { if (ptr->matches(cursorPointer)) { @@ -134,6 +128,17 @@ bool CursorRing::setup() } } m_viewImpl->gButtonMutex.unlock(); +} + +bool CursorRing::setup() +{ + m_node->localCursorRings(m_frame, &m_rings); + if (!m_rings.size()) { + DBG_NAV_LOG("!rings.size()"); + m_viewImpl->m_hasCursorBounds = false; + return false; + } + setIsButton(m_node); m_bounds = m_node->localBounds(m_frame); m_viewImpl->updateCursorBounds(m_root, m_frame, m_node); diff --git a/WebCore/platform/graphics/android/android_graphics.h b/WebCore/platform/graphics/android/android_graphics.h index 9f52a27..be309a6 100644 --- a/WebCore/platform/graphics/android/android_graphics.h +++ b/WebCore/platform/graphics/android/android_graphics.h @@ -54,6 +54,7 @@ public: CursorRing(WebViewCore* core) : m_viewImpl(core) {} virtual ~CursorRing() {} virtual void draw(SkCanvas* , LayerAndroid* , IntRect* ); + void setIsButton(const CachedNode* ); bool setup(); private: friend class WebView; diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp index 48aa3ec..0d39f7a 100644 --- a/WebCore/rendering/RenderLayerBacking.cpp +++ b/WebCore/rendering/RenderLayerBacking.cpp @@ -1021,14 +1021,6 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* bool selectionOnly = paintBehavior & PaintBehaviorSelectionOnly; if (shouldPaint && (paintingPhase & GraphicsLayerPaintForeground)) { -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - // Scroll to 0,0 and paint the entire contents, then scroll back the - // the original offset. - int x = m_owningLayer->scrollXOffset(); - int y = m_owningLayer->scrollYOffset(); - if (m_owningLayer->hasOverflowScroll()) - m_owningLayer->scrollToOffset(0, 0, false, false); -#endif // Set up the clip used when painting our children. setClip(context, paintDirtyRect, clipRectToApply); PaintInfo paintInfo(context, clipRectToApply, @@ -1067,10 +1059,6 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* // Now walk the sorted list of children with positive z-indices. m_owningLayer->paintList(m_owningLayer->posZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0); -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (m_owningLayer->hasOverflowScroll()) - m_owningLayer->scrollToOffset(x, y, false, false); -#endif } if (shouldPaint && (paintingPhase & GraphicsLayerPaintMask)) { diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp index f31ab9d..9775134 100644 --- a/WebCore/rendering/RenderLayerCompositor.cpp +++ b/WebCore/rendering/RenderLayerCompositor.cpp @@ -1288,6 +1288,10 @@ bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const // into the hierarchy between this layer and its children in the z-order hierarchy. bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const { +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + if (layer->hasOverflowScroll()) + return false; +#endif return layer->hasCompositingDescendant() && (layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip()); } |