diff options
36 files changed, 392 insertions, 92 deletions
diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp index ee2206b..c7f162a 100644 --- a/Source/WebCore/page/DOMWindow.cpp +++ b/Source/WebCore/page/DOMWindow.cpp @@ -1095,7 +1095,11 @@ int DOMWindow::innerHeight() const if (!view) return 0; +#if PLATFORM(ANDROID) + return static_cast<int>(view->actualHeight() / m_frame->pageZoomFactor()); +#else return static_cast<int>(view->height() / m_frame->pageZoomFactor()); +#endif } int DOMWindow::innerWidth() const @@ -1107,7 +1111,11 @@ int DOMWindow::innerWidth() const if (!view) return 0; +#if PLATFORM(ANDROID) + return static_cast<int>(view->actualWidth() / m_frame->pageZoomFactor()); +#else return static_cast<int>(view->width() / m_frame->pageZoomFactor()); +#endif } int DOMWindow::screenX() const @@ -1145,7 +1153,11 @@ int DOMWindow::scrollX() const m_frame->document()->updateLayoutIgnorePendingStylesheets(); +#if PLATFORM(ANDROID) + return static_cast<int>(view->actualScrollX() / m_frame->pageZoomFactor()); +#else return static_cast<int>(view->scrollX() / m_frame->pageZoomFactor()); +#endif } int DOMWindow::scrollY() const @@ -1159,7 +1171,11 @@ int DOMWindow::scrollY() const m_frame->document()->updateLayoutIgnorePendingStylesheets(); +#if PLATFORM(ANDROID) + return static_cast<int>(view->actualScrollY() / m_frame->pageZoomFactor()); +#else return static_cast<int>(view->scrollY() / m_frame->pageZoomFactor()); +#endif } bool DOMWindow::closed() const diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp index 140c8e5..864fdc5 100644 --- a/Source/WebCore/platform/ScrollView.cpp +++ b/Source/WebCore/platform/ScrollView.cpp @@ -308,6 +308,30 @@ void ScrollView::setContentsSize(const IntSize& newSize) } #if PLATFORM(ANDROID) +int ScrollView::actualWidth() const { + if (platformWidget()) + return platformActualWidth(); + return width(); +} + +int ScrollView::actualHeight() const { + if (platformWidget()) + return platformActualHeight(); + return height(); +} + +int ScrollView::actualScrollX() const { + if (platformWidget()) + return platformActualScrollX(); + return scrollX(); +} + +int ScrollView::actualScrollY() const { + if (platformWidget()) + return platformActualScrollY(); + return scrollY(); +} + FrameView* ScrollView::frameView() { if (this->isFrameView()) { FrameView* frameView = reinterpret_cast<FrameView*>(this); diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h index e58d025..3228870 100644 --- a/Source/WebCore/platform/ScrollView.h +++ b/Source/WebCore/platform/ScrollView.h @@ -172,6 +172,10 @@ public: virtual void setContentsSize(const IntSize&); #if PLATFORM(ANDROID) + int actualWidth() const; + int actualHeight() const; + int actualScrollX() const; + int actualScrollY() const; FrameView* frameView(); #endif @@ -401,6 +405,13 @@ private: void platformSetScrollOrigin(const IntPoint&, bool updatePositionAtAll, bool updatePositionSynchronously); +#if PLATFORM(ANDROID) + int platformActualWidth() const; + int platformActualHeight() const; + int platformActualScrollX() const; + int platformActualScrollY() const; +#endif + #if PLATFORM(MAC) && defined __OBJC__ public: NSView* documentView() const; diff --git a/Source/WebCore/platform/android/ScrollViewAndroid.cpp b/Source/WebCore/platform/android/ScrollViewAndroid.cpp index cc1c09e..e7300a1 100644 --- a/Source/WebCore/platform/android/ScrollViewAndroid.cpp +++ b/Source/WebCore/platform/android/ScrollViewAndroid.cpp @@ -68,6 +68,34 @@ IntSize ScrollView::platformContentsSize() const return m_contentsSize; } +int ScrollView::platformActualWidth() const +{ + if (parent()) + return width(); + return platformWidget()->visibleWidth(); +} + +int ScrollView::platformActualHeight() const +{ + if (parent()) + return height(); + return platformWidget()->visibleHeight(); +} + +int ScrollView::platformActualScrollX() const +{ + if (parent()) + return scrollX(); + return platformWidget()->visibleX(); +} + +int ScrollView::platformActualScrollY() const +{ + if (parent()) + return scrollY(); + return platformWidget()->visibleY(); +} + void ScrollView::platformSetScrollPosition(const WebCore::IntPoint& pt) { PlatformBridge::setScrollPosition(this, m_scrollOrigin.x() + pt.x(), diff --git a/Source/WebCore/platform/android/WidgetAndroid.cpp b/Source/WebCore/platform/android/WidgetAndroid.cpp index 6858f29..3c5b1c8 100644 --- a/Source/WebCore/platform/android/WidgetAndroid.cpp +++ b/Source/WebCore/platform/android/WidgetAndroid.cpp @@ -49,7 +49,9 @@ Widget::~Widget() IntRect Widget::frameRect() const { - return m_frame; + if (!platformWidget()) + return m_frame; + return platformWidget()->getBounds(); } void Widget::setFocus(bool focused) @@ -89,6 +91,11 @@ void Widget::hide() void Widget::setFrameRect(const IntRect& rect) { m_frame = rect; + // platformWidget() is 0 when called from Scrollbar + if (!platformWidget()) + return; + platformWidget()->setLocation(rect.x(), rect.y()); + platformWidget()->setSize(rect.width(), rect.height()); } void Widget::setIsSelected(bool isSelected) 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/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp index 3239599..a0a1b58 100644 --- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp @@ -31,6 +31,7 @@ #include "AndroidLog.h" #include "CachedImage.h" +#include "ClassTracker.h" #include "DrawQuadData.h" #include "FixedPositioning.h" #include "GLWebViewState.h" @@ -80,7 +81,9 @@ void BaseLayerAndroid::updatePositionsRecursive(const SkRect& visibleContentRect updateLayerPositions(visibleContentRect); TransformationMatrix ident; FloatRect clip(0, 0, getWidth(), getHeight()); - updateGLPositionsAndScale(ident, clip, 1, state()->scale()); + + float scale = state() ? state()->scale() : 1.0f; + updateGLPositionsAndScale(ident, clip, 1, scale); } ForegroundBaseLayerAndroid::ForegroundBaseLayerAndroid(LayerContent* content) @@ -115,6 +118,10 @@ FixedBackgroundImageLayerAndroid::FixedBackgroundImageLayerAndroid(PassRefPtr<Re setFixedPosition(position); position->setPosition(left, top); + +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("FixedBackgroundImageLayerAndroid"); +#endif } FixedBackgroundImageLayerAndroid::FixedBackgroundImageLayerAndroid(const FixedBackgroundImageLayerAndroid& layer) @@ -122,6 +129,16 @@ FixedBackgroundImageLayerAndroid::FixedBackgroundImageLayerAndroid(const FixedBa , m_width(layer.m_width) , m_height(layer.m_height) { +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("FixedBackgroundImageLayerAndroid"); +#endif +} + +FixedBackgroundImageLayerAndroid::~FixedBackgroundImageLayerAndroid() +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("FixedBackgroundImageLayerAndroid"); +#endif } static bool needToDisplayImage(bool repeatX, bool repeatY, float dx, float dy) diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h index 9ce8a07..55b4b21 100644 --- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h @@ -65,6 +65,7 @@ class FixedBackgroundImageLayerAndroid : public LayerAndroid { public: FixedBackgroundImageLayerAndroid(PassRefPtr<RenderStyle> style, int w, int h); FixedBackgroundImageLayerAndroid(const FixedBackgroundImageLayerAndroid& layer); + virtual ~FixedBackgroundImageLayerAndroid(); virtual LayerAndroid* copy() const { return new FixedBackgroundImageLayerAndroid(*this); } virtual bool needsTexture() { return true; } virtual SubclassType subclassType() const { return LayerAndroid::FixedBackgroundImageLayer; } 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 7a25e7f..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 = @@ -816,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 52df0cf..9b239ee 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h @@ -281,7 +281,7 @@ public: Surface* surface() { return m_surface; } void setIntrinsicallyComposited(bool intCom) { m_intrinsicallyComposited = intCom; } - bool needsIsolatedSurface() { + virtual bool needsIsolatedSurface() { return (needsTexture() && m_intrinsicallyComposited) || m_animations.size(); } diff --git a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp index 87096b0..3fcbdb2 100644 --- a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp @@ -30,6 +30,7 @@ #include "PaintTileOperation.h" #include "AndroidLog.h" +#include "ClassTracker.h" #include "GLWebViewState.h" #include "ImageTexture.h" #include "ImagesManager.h" @@ -49,6 +50,9 @@ PaintTileOperation::PaintTileOperation(Tile* tile, TilePainter* painter, if (m_tile) m_tile->setRepaintPending(true); SkSafeRef(m_painter); +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("PaintTileOperation"); +#endif } PaintTileOperation::~PaintTileOperation() @@ -64,6 +68,9 @@ PaintTileOperation::~PaintTileOperation() } else { SkSafeUnref(m_painter); } +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("PaintTileOperation"); +#endif } bool PaintTileOperation::operator==(const QueuedOperation* operation) diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp index 7e4e918..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; @@ -253,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; } @@ -264,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 7100125..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(); diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp index af96560..fcd9655 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp @@ -31,6 +31,7 @@ #include "AndroidLog.h" #include "Color.h" +#include "ClassTracker.h" #include "GLWebViewState.h" #include "LayerAndroid.h" @@ -46,6 +47,9 @@ SurfaceBacking::SurfaceBacking(bool isBaseSurface) m_scale = -1; m_futureScale = -1; m_zooming = false; +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("SurfaceBacking"); +#endif } SurfaceBacking::~SurfaceBacking() @@ -53,6 +57,9 @@ SurfaceBacking::~SurfaceBacking() delete m_frontTileGrid; delete m_backTileGrid; delete m_lowResTileGrid; +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("SurfaceBacking"); +#endif } void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom, @@ -146,11 +153,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 7e5c2ca..f577d46 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp @@ -33,7 +33,7 @@ #include "BaseLayerAndroid.h" #include "ClassTracker.h" #include "GLWebViewState.h" -#include "BaseLayerAndroid.h" +#include "PaintTileOperation.h" #include "Surface.h" #include "ScrollableLayerAndroid.h" #include "TilesManager.h" @@ -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,16 +162,25 @@ 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(); } +void SurfaceCollection::removePainterOperations() +{ + for (unsigned int i = 0; i < m_surfaces.size(); i++) + TilesManager::instance()->removeOperationsForFilter(new TilePainterFilter(m_surfaces[i])); +} + void SurfaceCollection::computeTexturesAmount(TexturesResult* result) { for (unsigned int i = 0; i < m_surfaces.size(); i++) diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h index dfa37d6..ff4195f 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h @@ -47,13 +47,16 @@ public: SurfaceCollection(BaseLayerAndroid* compositedRoot); virtual ~SurfaceCollection(); - // Tiled painting methods (executed on groups) + // Tiled painting methods (executed on Surfaces) void prepareGL(const SkRect& visibleContentRect, bool tryToFastBlit = false); bool drawGL(const SkRect& visibleContentRect); Color getBackgroundColor(); void swapTiles(); + void addFrameworkInvals(); bool isReady(); + bool isBaseSurfaceReady(); bool isMissingBackgroundContent(); + void removePainterOperations(); void computeTexturesAmount(TexturesResult* result); // Recursive tree methods (animations, invals, etc) @@ -71,7 +74,7 @@ public: 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 e2ac011..724bf89 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,15 @@ 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(); + m_drawingCollection->removePainterOperations(); 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 @@ -87,6 +94,12 @@ void SurfaceCollectionManager::swap() // clear all of the content in the three collections held by the collection manager void SurfaceCollectionManager::clearCollections() { + // remove all painting operations, since they're no longer relevant + if (m_drawingCollection) + m_drawingCollection->removePainterOperations(); + if (m_paintingCollection) + m_paintingCollection->removePainterOperations(); + SkSafeUnref(m_drawingCollection); m_drawingCollection = 0; SkSafeUnref(m_paintingCollection); @@ -95,6 +108,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 +126,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 +155,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 +170,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 +235,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 +243,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 +256,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 +285,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); @@ -262,7 +313,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, #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 diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp index f37753e..012427c 100644 --- a/Source/WebCore/rendering/RenderObject.cpp +++ b/Source/WebCore/rendering/RenderObject.cpp @@ -1787,6 +1787,23 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt } } +void RenderObject::propagateStyleToAnonymousChildren() +{ + for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { + if (child->isAnonymous() && !child->isBeforeOrAfterContent()) { + RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); + if (style()->specifiesColumns()) { + if (child->style()->specifiesColumns()) + newStyle->inheritColumnPropertiesFrom(style()); + if (child->style()->columnSpan()) + newStyle->setColumnSpan(true); + } + newStyle->setDisplay(child->style()->display()); + child->setStyle(newStyle.release()); + } + } +} + void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers) { // Optimize the common case diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h index f5fe562..18086c9 100644 --- a/Source/WebCore/rendering/RenderObject.h +++ b/Source/WebCore/rendering/RenderObject.h @@ -315,6 +315,7 @@ public: inline bool isBeforeOrAfterContent() const; static inline bool isBeforeContent(const RenderObject* obj) { return obj && obj->isBeforeContent(); } static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); } + static inline bool isBeforeOrAfterContent(const RenderObject* obj) { return obj && obj->isBeforeOrAfterContent(); } bool childrenInline() const { return m_childrenInline; } void setChildrenInline(bool b = true) { m_childrenInline = b; } @@ -777,6 +778,7 @@ protected: virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); // Overrides should call the superclass at the start virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + void propagateStyleToAnonymousChildren(); void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide, Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false); diff --git a/Source/WebCore/rendering/RenderRuby.cpp b/Source/WebCore/rendering/RenderRuby.cpp index e0137de..41604d6 100644 --- a/Source/WebCore/rendering/RenderRuby.cpp +++ b/Source/WebCore/rendering/RenderRuby.cpp @@ -119,6 +119,12 @@ RenderRubyAsInline::~RenderRubyAsInline() { } +void RenderRubyAsInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderInline::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); +} + void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild) { // Insert :before and :after content before/after the RenderRubyRun(s) @@ -220,6 +226,12 @@ RenderRubyAsBlock::~RenderRubyAsBlock() { } +void RenderRubyAsBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderBlock::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); +} + void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild) { // Insert :before and :after content before/after the RenderRubyRun(s) diff --git a/Source/WebCore/rendering/RenderRuby.h b/Source/WebCore/rendering/RenderRuby.h index 24ac0db..2ab964c 100644 --- a/Source/WebCore/rendering/RenderRuby.h +++ b/Source/WebCore/rendering/RenderRuby.h @@ -59,6 +59,9 @@ public: virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); virtual void removeChild(RenderObject* child); +protected: + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + private: virtual bool isRuby() const { return true; } virtual const char* renderName() const { return "RenderRuby (inline)"; } @@ -75,6 +78,9 @@ public: virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); virtual void removeChild(RenderObject* child); +protected: + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + private: virtual bool isRuby() const { return true; } virtual const char* renderName() const { return "RenderRuby (block)"; } diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp index e9db5ad..072519e 100644 --- a/Source/WebCore/rendering/RenderTable.cpp +++ b/Source/WebCore/rendering/RenderTable.cpp @@ -79,6 +79,7 @@ RenderTable::~RenderTable() void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderBlock::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); ETableLayout oldTableLayout = oldStyle ? oldStyle->tableLayout() : TAUTO; diff --git a/Source/WebCore/rendering/RenderTableRow.cpp b/Source/WebCore/rendering/RenderTableRow.cpp index 2edcfc4..686bc3a 100644 --- a/Source/WebCore/rendering/RenderTableRow.cpp +++ b/Source/WebCore/rendering/RenderTableRow.cpp @@ -74,10 +74,10 @@ void RenderTableRow::updateBeforeAndAfterContent() void RenderTableRow::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderBox::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); if (parent()) updateBeforeAndAfterContent(); - } void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild) @@ -90,7 +90,7 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild) RenderObject* last = beforeChild; if (!last) last = lastChild(); - if (last && last->isAnonymous() && last->isTableCell()) { + if (last && last->isAnonymous() && last->isTableCell() && !last->isBeforeOrAfterContent()) { if (beforeChild == last) beforeChild = last->firstChild(); last->addChild(child, beforeChild); @@ -98,7 +98,7 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild) } // If beforeChild is inside an anonymous cell, insert into the cell. - if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous()) { + if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous() && !last->parent()->isBeforeOrAfterContent()) { last->parent()->addChild(child, beforeChild); return; } diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp index 06d326f..daa0a92 100644 --- a/Source/WebCore/rendering/RenderTableSection.cpp +++ b/Source/WebCore/rendering/RenderTableSection.cpp @@ -78,6 +78,12 @@ RenderTableSection::~RenderTableSection() clearGrid(); } +void RenderTableSection::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderBox::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); +} + void RenderTableSection::destroy() { RenderTable* recalcTable = table(); @@ -100,7 +106,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild RenderObject* last = beforeChild; if (!last) last = lastChild(); - if (last && last->isAnonymous()) { + if (last && last->isAnonymous() && !last->isBeforeOrAfterContent()) { if (beforeChild == last) beforeChild = last->firstChild(); last->addChild(child, beforeChild); @@ -112,7 +118,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild RenderObject* lastBox = last; while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableRow()) lastBox = lastBox->parent(); - if (lastBox && lastBox->isAnonymous()) { + if (lastBox && lastBox->isAnonymous() && !lastBox->isBeforeOrAfterContent()) { lastBox->addChild(child, beforeChild); return; } diff --git a/Source/WebCore/rendering/RenderTableSection.h b/Source/WebCore/rendering/RenderTableSection.h index cc969e8..db6edc2 100644 --- a/Source/WebCore/rendering/RenderTableSection.h +++ b/Source/WebCore/rendering/RenderTableSection.h @@ -118,6 +118,9 @@ public: int getBaseline(int row) { return m_grid[row].baseline; } +protected: + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + private: virtual RenderObjectChildList* virtualChildren() { return children(); } virtual const RenderObjectChildList* virtualChildren() const { return children(); } diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index dc4f70c..73abb07 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -1783,7 +1783,7 @@ bool WebViewCore::nodeIsClickableOrFocusable(Node* node) AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool doMoveMouse) { if (doMoveMouse) - moveMouse(x, y); + moveMouse(x, y, 0, true); HitTestResult hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(IntPoint(x, y), false, false, DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly, IntSize(slop, slop)); AndroidHitTestResult androidHitResult(this, hitTestResult); @@ -1930,19 +1930,26 @@ AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool do } else { androidHitResult.setURLElement(0); } - IntPoint frameAdjust; - if (frame != m_mainFrame) { - frameAdjust = frame->view()->contentsToWindow(IntPoint()); - frameAdjust.move(m_scrollOffsetX, m_scrollOffsetY); - } - IntRect rect = final.mBounds; - rect.move(frameAdjust.x(), frameAdjust.y()); - if (doMoveMouse) { - // adjust m_mousePos if it is not inside the returned highlight rectangle - testRect.move(frameAdjust.x(), frameAdjust.y()); - testRect.intersect(rect); - if (!testRect.contains(x, y)) - moveMouse(testRect.center().x(), testRect.center().y()); + Vector<IntRect>& highlightRects = androidHitResult.highlightRects(); + if (doMoveMouse && highlightRects.size() > 0) { + // adjust m_mousePos if it is not inside the returned highlight + // rectangles + IntRect foundIntersection; + IntRect inputRect = IntRect(x - slop, y - slop, + slop * 2 + 1, slop * 2 + 1); + for (size_t i = 0; i < highlightRects.size(); i++) { + IntRect& hr = highlightRects[i]; + IntRect test = inputRect; + test.intersect(hr); + if (!test.isEmpty()) { + foundIntersection = test; + break; + } + } + if (!foundIntersection.isEmpty() && !foundIntersection.contains(x, y)) { + IntPoint pt = foundIntersection.center(); + moveMouse(pt.x(), pt.y(), 0, true); + } } } else { androidHitResult.searchContentDetectors(); @@ -2121,10 +2128,12 @@ static PluginView* nodeIsPlugin(Node* node) { /////////////////////////////////////////////////////////////////////////////// // Update mouse position -void WebViewCore::moveMouse(int x, int y, HitTestResult* hoveredNode) +void WebViewCore::moveMouse(int x, int y, HitTestResult* hoveredNode, bool isClickCandidate) { // mouse event expects the position in the window coordinate m_mousePos = WebCore::IntPoint(x - m_scrollOffsetX, y - m_scrollOffsetY); + if (isClickCandidate) + m_mouseClickPos = m_mousePos; // validNode will still return true if the node is null, as long as we have // a valid frame. Do not want to make a call on frame unless it is valid. WebCore::PlatformMouseEvent mouseEvent(m_mousePos, m_mousePos, @@ -3240,12 +3249,12 @@ bool WebViewCore::handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint bool WebViewCore::performMouseClick() { - WebCore::PlatformMouseEvent mouseDown(m_mousePos, m_mousePos, WebCore::LeftButton, + WebCore::PlatformMouseEvent mouseDown(m_mouseClickPos, m_mouseClickPos, WebCore::LeftButton, WebCore::MouseEventPressed, 1, false, false, false, false, WTF::currentTime()); // ignore the return from as it will return true if the hit point can trigger selection change m_mainFrame->eventHandler()->handleMousePressEvent(mouseDown); - WebCore::PlatformMouseEvent mouseUp(m_mousePos, m_mousePos, WebCore::LeftButton, + WebCore::PlatformMouseEvent mouseUp(m_mouseClickPos, m_mouseClickPos, WebCore::LeftButton, WebCore::MouseEventReleased, 1, false, false, false, false, WTF::currentTime()); bool handled = m_mainFrame->eventHandler()->handleMouseReleaseEvent(mouseUp); diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index c6b26c6..bfd9387 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -299,7 +299,8 @@ namespace android { // scroll the selection on screen (if necessary). void revealSelection(); - void moveMouse(int x, int y, WebCore::HitTestResult* hoveredNode = 0); + void moveMouse(int x, int y, WebCore::HitTestResult* hoveredNode = 0, + bool isClickCandidate = false); // set the scroll amount that webview.java is currently showing void setScrollOffset(bool sendScrollEvent, int dx, int dy); @@ -766,6 +767,13 @@ namespace android { int m_scrollOffsetY; // webview.java's current scroll in Y double m_scrollSetTime; // when the scroll was last set WebCore::IntPoint m_mousePos; + // This is the location at which we will click. This is tracked + // separately from m_mousePos, because m_mousePos may be updated + // in the interval between ACTION_UP and when the click fires since + // that occurs after a delay. This also works around potential hardware + // issues if we get onHoverEvents when using the touch screen, as that + // will nullify the slop checking we do in hitTest (aka, ACTION_DOWN) + WebCore::IntPoint m_mouseClickPos; int m_screenWidth; // width of the visible rect in document coordinates int m_screenHeight;// height of the visible rect in document coordinates int m_textWrapWidth; |
