diff options
Diffstat (limited to 'WebCore')
-rw-r--r-- | WebCore/platform/android/PlatformBridge.h | 2 | ||||
-rw-r--r-- | WebCore/platform/graphics/GraphicsLayer.h | 6 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BaseLayerAndroid.cpp | 5 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp | 121 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GraphicsLayerAndroid.h | 3 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.cpp | 129 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.h | 44 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayer.cpp | 33 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayer.h | 9 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayerBacking.cpp | 26 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayerCompositor.cpp | 7 |
11 files changed, 193 insertions, 192 deletions
diff --git a/WebCore/platform/android/PlatformBridge.h b/WebCore/platform/android/PlatformBridge.h index 2019d1a..2d6451a 100644 --- a/WebCore/platform/android/PlatformBridge.h +++ b/WebCore/platform/android/PlatformBridge.h @@ -137,8 +137,6 @@ public: static void updateTextfield(FrameView*, Node*, bool changeToPassword, const WTF::String& text); - // Updates the layers on the UI - static void updateLayers(FrameView* view); // Language static String computeDefaultLanguage(); // Memory details for V8 GC diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h index 991ca32..81aa6d0 100644 --- a/WebCore/platform/graphics/GraphicsLayer.h +++ b/WebCore/platform/graphics/GraphicsLayer.h @@ -82,6 +82,12 @@ class LayerChromium; typedef LayerChromium PlatformLayer; typedef void* NativeLayer; } +#elif PLATFORM(ANDROID) +namespace WebCore { +class LayerAndroid; +typedef LayerAndroid PlatformLayer; +typedef void* NativeLayer; +} #else typedef void* PlatformLayer; typedef void* NativeLayer; diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index f139eeb..996b272 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -92,7 +92,10 @@ void BaseLayerAndroid::setContent(const PictureSet& src) android::Mutex::Autolock lock(m_drawLock); #endif m_content.set(src); - setSize(src.width(), src.height()); + // FIXME: We cannot set the size of the base layer because it will screw up + // the matrix used. We need to fix matrix computation for the base layer + // and then we can set the size. + // setSize(src.width(), src.height()); } void BaseLayerAndroid::setExtra(SkPicture& src) diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index 593c896..fe7b132 100644 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -120,7 +120,9 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) : m_translateY(0), m_currentTranslateX(0), m_currentTranslateY(0), - m_currentPosition(0, 0) + m_currentPosition(0, 0), + m_foregroundLayer(0), + m_foregroundClipLayer(0) { m_contentLayer = new LayerAndroid(true); RenderLayer* renderLayer = renderLayerFromClient(m_client); @@ -134,6 +136,8 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) : GraphicsLayerAndroid::~GraphicsLayerAndroid() { m_contentLayer->unref(); + SkSafeUnref(m_foregroundLayer); + SkSafeUnref(m_foregroundClipLayer); gDebugGraphicsLayerAndroidInstances--; } @@ -162,8 +166,8 @@ bool GraphicsLayerAndroid::setChildren(const Vector<GraphicsLayer*>& children) void GraphicsLayerAndroid::addChild(GraphicsLayer* childLayer) { #ifndef NDEBUG - const char* n = (static_cast<GraphicsLayerAndroid*>(childLayer))->m_name.latin1().data(); - LOG("(%x) addChild: %x (%s)", this, childLayer, n); + const String& name = childLayer->name(); + LOG("(%x) addChild: %x (%s)", this, childLayer, name.latin1().data()); #endif GraphicsLayer::addChild(childLayer); m_needsSyncChildren = true; @@ -206,19 +210,11 @@ bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* void GraphicsLayerAndroid::removeFromParent() { LOG("(%x) removeFromParent()", this); - if (m_parent) - static_cast<GraphicsLayerAndroid*>(m_parent)->needsSyncChildren(); GraphicsLayer::removeFromParent(); m_needsSyncChildren = true; askForSync(); } -void GraphicsLayerAndroid::needsSyncChildren() -{ - m_needsSyncChildren = true; - askForSync(); -} - void GraphicsLayerAndroid::updateFixedPosition() { if (!m_client) @@ -353,6 +349,19 @@ 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 && layer->hasOverflowScroll() && !m_foregroundLayer) { + m_foregroundLayer = new LayerAndroid(false); + m_foregroundLayer->setContentScrollable(true); + m_foregroundClipLayer = new LayerAndroid(false); + m_foregroundClipLayer->setMasksToBounds(true); + + m_foregroundClipLayer->addChild(m_foregroundLayer); + m_contentLayer->addChild(m_foregroundClipLayer); + } +#endif + m_haveContents = true; setNeedsDisplay(); } @@ -440,18 +449,42 @@ bool GraphicsLayerAndroid::repaint() // with SkPicture, we request the entire layer's content. IntRect layerBounds(0, 0, m_size.width(), m_size.height()); - if (m_contentsRect.width() > m_size.width() || - m_contentsRect.height() > m_size.height()) { + if (m_foregroundLayer) { PaintingPhase phase(this); // Paint the background into a separate context. phase.set(GraphicsLayerPaintBackground); if (!paintContext(m_contentLayer->recordContext(), layerBounds)) return false; + + RenderLayer* layer = renderLayerFromClient(m_client); + // Construct the foreground layer and draw. + RenderBox* box = layer->renderBox(); + int outline = box->view()->maximalOutlineSize(); + IntRect contentsRect(0, 0, + box->borderLeft() + box->borderRight() + layer->scrollWidth(), + box->borderTop() + box->borderBottom() + layer->scrollHeight()); + contentsRect.inflate(outline); + // Update the foreground layer size. + m_foregroundLayer->setSize(contentsRect.width(), contentsRect.height()); // Paint everything else into the main recording canvas. phase.clear(GraphicsLayerPaintBackground); - if (!paintContext(m_contentLayer->foregroundContext(), - m_contentsRect)) + if (!paintContext(m_foregroundLayer->recordContext(), contentsRect)) return false; + + // Construct the clip layer for masking the contents. + IntRect clip = layer->renderer()->absoluteBoundingBoxRect(); + // absoluteBoundingBoxRect does not include the outline so we need + // to offset the position. + int x = box->borderLeft() + outline; + int y = box->borderTop() + outline; + int width = clip.width() - box->borderLeft() - box->borderRight(); + int height = clip.height() - box->borderTop() - box->borderBottom(); + m_foregroundClipLayer->setPosition(x, y); + m_foregroundClipLayer->setSize(width, height); + + // Need to offset the foreground layer by the clip layer in order + // for the contents to be in the correct position. + m_foregroundLayer->setPosition(-x, -y); } else { // If there is no contents clip, we can draw everything into one // picture. @@ -469,24 +502,6 @@ bool GraphicsLayerAndroid::repaint() m_needsRepaint = false; m_invalidatedRects.clear(); - RenderLayer* layer = renderLayerFromClient(m_client); - // Use the absolute bounds of the renderer instead of the layer's - // bounds because the layer will add in the outline. What we want - // is the content bounds inside the outline. - FloatRect clip = layer->renderer()->absoluteBoundingBoxRect(); - // Move the clip local to the layer position. - clip.setLocation(FloatPoint(0, 0)); -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (layer->hasOverflowScroll()) { - // If this is a scrollable layer, inset the clip by the border. - RenderBox* box = layer->renderBox(); - clip.move(box->borderLeft(), box->borderTop()); - clip.setWidth(clip.width() - box->borderLeft() - box->borderRight()); - clip.setHeight(clip.height() - box->borderTop() - box->borderBottom()); - } -#endif - m_contentLayer->setForegroundClip(clip); - return true; } return false; @@ -511,7 +526,7 @@ bool GraphicsLayerAndroid::paintContext(SkPicture* context, void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect) { for (unsigned int i = 0; i < m_children.size(); i++) { - GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]); + GraphicsLayer* layer = m_children[i]; if (layer) { FloatRect childrenRect(m_position.x() + m_translateX + rect.x(), m_position.y() + m_translateY + rect.y(), @@ -548,16 +563,6 @@ void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect) m_needsRepaint = true; askForSync(); - - if (!m_client) - return; - - // Update the layers on the UI - RenderLayer* renderLayer = renderLayerFromClient(m_client); - if (renderLayer) { - FrameView* frameView = renderLayer->root()->renderer()->view()->frameView(); - PlatformBridge::updateLayers(frameView); - } } void GraphicsLayerAndroid::pauseDisplay(bool state) @@ -862,7 +867,7 @@ void GraphicsLayerAndroid::setContentsToImage(Image* image) PlatformLayer* GraphicsLayerAndroid::platformLayer() const { LOG("platformLayer"); - return (PlatformLayer*) m_contentLayer; + return m_contentLayer; } #ifndef NDEBUG @@ -884,6 +889,9 @@ void GraphicsLayerAndroid::setZPosition(float position) void GraphicsLayerAndroid::askForSync() { + if (!m_client) + return; + if (m_client) m_client->notifySyncRequired(this); } @@ -892,10 +900,10 @@ void GraphicsLayerAndroid::syncChildren() { if (m_needsSyncChildren) { m_contentLayer->removeChildren(); - for (unsigned int i = 0; i < m_children.size(); i++) { - m_contentLayer->addChild( - (static_cast<GraphicsLayerAndroid*>(m_children[i]))->contentLayer()); - } + if (m_foregroundClipLayer) + m_contentLayer->addChild(m_foregroundClipLayer); + for (unsigned int i = 0; i < m_children.size(); i++) + m_contentLayer->addChild(m_children[i]->platformLayer()); m_needsSyncChildren = false; } } @@ -904,8 +912,7 @@ void GraphicsLayerAndroid::syncMask() { if (m_needsSyncMask) { if (m_maskLayer) { - GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_maskLayer); - LayerAndroid* mask = reinterpret_cast<LayerAndroid*>(layer->platformLayer()); + LayerAndroid* mask = m_maskLayer->platformLayer(); m_contentLayer->setMaskLayer(mask); } else m_contentLayer->setMaskLayer(0); @@ -929,10 +936,8 @@ void GraphicsLayerAndroid::syncPositionState() void GraphicsLayerAndroid::syncCompositingState() { - for (unsigned int i = 0; i < m_children.size(); i++) { - GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]); - layer->syncCompositingState(); - } + for (unsigned int i = 0; i < m_children.size(); i++) + m_children[i]->syncCompositingState(); syncChildren(); syncMask(); @@ -944,10 +949,8 @@ void GraphicsLayerAndroid::syncCompositingState() void GraphicsLayerAndroid::notifyClientAnimationStarted() { - for (unsigned int i = 0; i < m_children.size(); i++) { - GraphicsLayerAndroid* layer = static_cast<GraphicsLayerAndroid*>(m_children[i]); - layer->notifyClientAnimationStarted(); - } + for (unsigned int i = 0; i < m_children.size(); i++) + static_cast<GraphicsLayerAndroid*>(m_children[i])->notifyClientAnimationStarted(); if (m_needsNotifyClient) { if (client()) diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index 80c92f3..098ad37 100644 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -119,7 +119,6 @@ private: void askForSync(); void syncPositionState(); - void needsSyncChildren(); void syncChildren(); void syncMask(); @@ -150,6 +149,8 @@ private: Vector<FloatRect> m_invalidatedRects; LayerAndroid* m_contentLayer; + LayerAndroid* m_foregroundLayer; + LayerAndroid* m_foregroundClipLayer; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index 0a6d3e2..68bdec0 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -13,7 +13,6 @@ #include "SkPicture.h" #include <wtf/CurrentTime.h> - #define LAYER_DEBUG // Add diagonals for debugging #undef LAYER_DEBUG @@ -52,8 +51,8 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), m_haveClip(false), m_doRotation(false), m_isFixed(false), + m_contentScrollable(false), m_recordingPicture(0), - m_foregroundPicture(0), m_contentsImage(0), m_extra(0), m_uniqueId(++gUniqueId) @@ -62,8 +61,6 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), m_translation.set(0, 0); m_scale.set(1, 1); m_backgroundColor = 0; - m_foregroundClip.setEmpty(); - m_foregroundLocation.set(0, 0); gDebugLayerAndroidInstances++; } @@ -71,6 +68,7 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), m_isRootLayer(layer.m_isRootLayer), m_haveClip(layer.m_haveClip), + m_contentScrollable(layer.m_contentScrollable), m_extra(0), // deliberately not copied m_uniqueId(layer.m_uniqueId) { @@ -95,12 +93,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), m_fixedRect = layer.m_fixedRect; m_recordingPicture = layer.m_recordingPicture; - m_foregroundPicture = layer.m_foregroundPicture; SkSafeRef(m_recordingPicture); - SkSafeRef(m_foregroundPicture); - - m_foregroundClip = layer.m_foregroundClip; - m_foregroundLocation = layer.m_foregroundLocation; for (int i = 0; i < layer.countChildren(); i++) addChild(new LayerAndroid(*layer.getChild(i)))->unref(); @@ -117,8 +110,8 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(), m_haveClip(false), m_doRotation(false), m_isFixed(false), + m_contentScrollable(false), m_recordingPicture(picture), - m_foregroundPicture(0), m_contentsImage(0), m_extra(0), m_uniqueId(-1) @@ -127,8 +120,6 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(), m_translation.set(0, 0); m_scale.set(1, 1); m_backgroundColor = 0; - m_foregroundClip.setEmpty(); - m_foregroundLocation.set(0, 0); SkSafeRef(m_recordingPicture); gDebugLayerAndroidInstances++; } @@ -138,7 +129,6 @@ LayerAndroid::~LayerAndroid() removeChildren(); m_contentsImage->safeUnref(); m_recordingPicture->safeUnref(); - m_foregroundPicture->safeUnref(); m_animations.clear(); gDebugLayerAndroidInstances--; } @@ -198,11 +188,6 @@ void LayerAndroid::setMaskLayer(LayerAndroid* layer) m_haveClip = true; } -void LayerAndroid::setMasksToBounds(bool masksToBounds) -{ - m_haveClip = masksToBounds; -} - void LayerAndroid::setBackgroundColor(SkColor color) { m_backgroundColor = color; @@ -323,6 +308,11 @@ public: int x() const { return m_x; } int y() const { return m_y; } + void setLocation(int x, int y) { + m_x = x; + m_y = y; + } + protected: int m_x; int m_y; @@ -336,18 +326,20 @@ void LayerAndroid::findInner(LayerAndroid::FindState& state) const { int x = state.x(); int y = state.y(); - for (int i = 0; i < countChildren(); i++) - getChild(i)->findInner(state); SkRect localBounds; bounds(&localBounds); if (!localBounds.contains(x, y)) return; - if (!m_foregroundPicture) { - if (!m_recordingPicture) - return; - if (!state.drew(m_recordingPicture, localBounds)) - return; - } + // Move into local coordinates. + state.setLocation(x - localBounds.fLeft, y - localBounds.fTop); + for (int i = 0; i < countChildren(); i++) + getChild(i)->findInner(state); + // Move back into the parent coordinates. + state.setLocation(x + localBounds.fLeft, y + localBounds.fTop); + if (!m_recordingPicture) + return; + if (!state.drew(m_recordingPicture, localBounds)) + return; state.setBest(this); // set last match (presumably on top) } @@ -450,14 +442,6 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity) { canvas->drawBitmapRect(m_contentsImage->bitmap(), 0, dest); } else { canvas->drawPicture(*m_recordingPicture); - if (m_foregroundPicture) { - canvas->save(); - canvas->clipRect(m_foregroundClip); - canvas->translate(-m_foregroundLocation.fX, - -m_foregroundLocation.fY); - canvas->drawPicture(*m_foregroundPicture); - canvas->restore(); - } } if (m_extra) { IntRect dummy; // inval area, unused for now @@ -492,38 +476,48 @@ SkPicture* LayerAndroid::recordContext() return 0; } -SkPicture* LayerAndroid::foregroundContext() -{ - // Always create a new picture since this method is called only when - // recording the foreground picture. - m_foregroundPicture = new SkPicture(); - return m_foregroundPicture; -} - -bool LayerAndroid::contentIsScrollable() const { - return m_foregroundPicture != 0 && - (getWidth() < SkIntToScalar(m_foregroundPicture->width()) || - getHeight() < SkIntToScalar(m_foregroundPicture->height())); -} - bool LayerAndroid::scrollBy(int dx, int dy) { - if (m_foregroundPicture == 0) + if (!contentIsScrollable()) return false; - SkScalar maxScrollX = SkIntToScalar(m_foregroundPicture->width()) - getWidth(); - SkScalar maxScrollY = SkIntToScalar(m_foregroundPicture->height()) - getHeight(); - SkScalar x = m_foregroundLocation.fX + dx; - SkScalar y = m_foregroundLocation.fY + dy; - x = SkScalarClampMax(x, maxScrollX); - y = SkScalarClampMax(y, maxScrollY); - if (x != m_foregroundLocation.fX || y != m_foregroundLocation.fY) { - m_foregroundLocation.set(x, y); - return true; - } - return false; + + // Scrollable layers have a mask layer and then the actual main layer. + if (getParent() == 0 || getParent()->getParent() == 0) + return false; + LayerAndroid* realLayer = static_cast<LayerAndroid*>(getParent()->getParent()); + + SkRect scrollBounds; + realLayer->bounds(&scrollBounds); + + const SkPoint& maskLayerPosition = getParent()->getPosition(); + // Our original position is the offset of the mask layer's position. + SkScalar maxX = -maskLayerPosition.fX; + SkScalar maxY = -maskLayerPosition.fY; + SkScalar minX = maxX - (getSize().width() - scrollBounds.width()); + SkScalar minY = maxY - (getSize().height() - scrollBounds.height()); + + // Move the layer's position by the difference and pin the result to within + // the scrollable range. + SkPoint diff; + diff.iset(dx, dy); + SkPoint pos = getPosition() - diff; + pos.fX = SkScalarPin(pos.fX, minX, maxX); + pos.fY = SkScalarPin(pos.fY, minY, maxY); + + // Update the difference to reflect the changes. + diff = getPosition() - pos; + if (diff.equals(0, 0)) + // no change + return false; + + setPosition(pos.fX, pos.fY); + return true; } bool LayerAndroid::prepareContext(bool force) { + if (masksToBounds()) + return false; + if (!m_isRootLayer) { if (force || !m_recordingPicture || (m_recordingPicture @@ -696,17 +690,6 @@ void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const writeIntVal(file, indentLevel + 1, "m_recordingPicture.height", m_recordingPicture->height()); } - if (m_foregroundPicture) { - writeIntVal(file, indentLevel + 1, "m_foregroundPicture.width", m_foregroundPicture->width()); - writeIntVal(file, indentLevel + 1, "m_foregroundPicture.height", m_foregroundPicture->height()); - writeFloatVal(file, indentLevel + 1, "m_foregroundClip.fLeft", m_foregroundClip.fLeft); - writeFloatVal(file, indentLevel + 1, "m_foregroundClip.fTop", m_foregroundClip.fTop); - writeFloatVal(file, indentLevel + 1, "m_foregroundClip.fRight", m_foregroundClip.fRight); - writeFloatVal(file, indentLevel + 1, "m_foregroundClip.fBottom", m_foregroundClip.fBottom); - writeFloatVal(file, indentLevel + 1, "m_foregroundLocation.fX", m_foregroundLocation.fX); - writeFloatVal(file, indentLevel + 1, "m_foregroundLocation.fY", m_foregroundLocation.fY); - } - if (countChildren()) { writeln(file, indentLevel + 1, "children = ["); for (int i = 0; i < countChildren(); i++) { @@ -732,12 +715,12 @@ void LayerAndroid::dumpToLog() const fclose(file); } -const LayerAndroid* LayerAndroid::findById(int match) const +LayerAndroid* LayerAndroid::findById(int match) { if (m_uniqueId == match) return this; for (int i = 0; i < countChildren(); i++) { - const LayerAndroid* result = getChild(i)->findById(match); + LayerAndroid* result = getChild(i)->findById(match); if (result) return result; } diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 939c95c..a9a9c69 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -121,31 +121,18 @@ public: void setBackgroundColor(SkColor color); void setMaskLayer(LayerAndroid*); - void setMasksToBounds(bool); + void setMasksToBounds(bool masksToBounds) { + m_haveClip = masksToBounds; + } + bool masksToBounds() const { return m_haveClip; } void setIsRootLayer(bool isRootLayer) { m_isRootLayer = isRootLayer; } bool isRootLayer() const { return m_isRootLayer; } SkPicture* recordContext(); - // The foreground context is used to draw overflow scroll content. - SkPicture* foregroundContext(); - - // The foreground clip is set when there is content within the node that - // can be scrolled (i.e. a div with overflow:scroll). - void setForegroundClip(const SkRect& clip) { - m_foregroundClip = clip; - } - - // Return the foreground clip offset by the position of the layer. - SkRect foregroundClip() const { return m_foregroundClip; } - - bool contentIsScrollable() const; - // Returns true if the content position has changed. bool scrollBy(int dx, int dy); - const SkPoint& scrollPosition() const { return m_foregroundLocation; } - void setScrollPosition(const SkPoint& pos) { m_foregroundLocation = pos; } void addAnimation(PassRefPtr<AndroidAnimation> anim); void removeAnimation(const String& name); @@ -180,7 +167,10 @@ public: void clipArea(SkTDArray<SkRect>* region) const; const LayerAndroid* find(int x, int y, SkPicture* root) const; - const LayerAndroid* findById(int uniqueID) const; + const LayerAndroid* findById(int uniqueID) const { + return const_cast<LayerAndroid*>(this)->findById(uniqueID); + } + LayerAndroid* findById(int uniqueID); LayerAndroid* getChild(int index) const { return static_cast<LayerAndroid*>(this->INHERITED::getChild(index)); } @@ -196,6 +186,14 @@ public: void setContentsImage(SkBitmapRef* img); void bounds(SkRect* ) const; + + bool contentIsScrollable() const { return m_contentScrollable; } + + // Set when building the layer hierarchy for scrollable elements. + void setContentScrollable(bool scrollable) { + m_contentScrollable = scrollable; + } + protected: virtual void onDraw(SkCanvas*, SkScalar opacity); @@ -215,6 +213,7 @@ private: bool m_doRotation; bool m_isFixed; bool m_backgroundColorSet; + bool m_contentScrollable; SkLength m_fixedLeft; SkLength m_fixedTop; @@ -239,15 +238,6 @@ private: // it is a much faster method than using m_recordingPicture. SkPicture* m_recordingPicture; - // m_foregroundPicture is set only when compositing a scrollable div. It - // contains the contents minus the background and border which is drawn - // first by the rendering tree. When we draw the layer, we draw - // m_recordingPicture (containing the background + border) first and then - // clip to m_foregroundClip and draw m_foregroundPicture. - SkPicture* m_foregroundPicture; - SkRect m_foregroundClip; - SkPoint m_foregroundLocation; - SkBitmapRef* m_contentsImage; typedef HashMap<String, RefPtr<AndroidAnimation> > KeyframesMap; diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp index 12360c8..4221816 100644 --- a/WebCore/rendering/RenderLayer.cpp +++ b/WebCore/rendering/RenderLayer.cpp @@ -1938,6 +1938,14 @@ bool RenderLayer::hasOverflowScroll() const return true; return false; } + +bool RenderLayer::hasOverflowParent() const +{ + const RenderLayer* layer = this; + while (layer && !layer->hasOverflowScroll()) + layer = layer->parent(); + return layer; +} #endif void RenderLayer::positionOverflowControls(int tx, int ty) @@ -2012,13 +2020,6 @@ void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar) *needHBar = rightPos > clientWidth; if (needVBar) *needVBar = bottomPos > clientHeight; -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (hasOverflowScroll()) { - compositor()->setCompositingLayersNeedRebuild(true); - compositor()->enableCompositingMode(true); - compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange, this); - } -#endif } void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow) @@ -2154,6 +2155,14 @@ RenderLayer::updateScrollInfoAfterLayout() if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER)) updateOverflowStatus(horizontalOverflow, verticalOverflow); + +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + if (hasOverflowScroll()) { + rendererContentChanged(); + dirtyStackingContextZOrderLists(); + dirtyZOrderLists(); + } +#endif } void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty, const IntRect& damageRect) @@ -3213,6 +3222,15 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl if (renderer()->hasOverflowClip()) { IntRect newOverflowClip = toRenderBox(renderer())->overflowClipRect(x, y); +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + if (hasOverflowScroll()) { + RenderBox* box = toRenderBox(renderer()); + newOverflowClip = + IntRect(x, y, + box->borderLeft() + box->borderRight() + m_scrollWidth, + box->borderTop() + box->borderBottom() + m_scrollHeight); + } +#endif clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); if (renderer()->isPositioned() || renderer()->isRelPositioned()) clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); @@ -3277,6 +3295,7 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa // This layer establishes a clip of some kind. #if ENABLE(ANDROID_OVERFLOW_SCROLL) if (hasOverflowScroll()) { + // Use the entire foreground rectangle to record the contents. RenderBox* box = toRenderBox(renderer()); foregroundRect = IntRect(x, y, diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h index 27d2b31..6b60fe1 100644 --- a/WebCore/rendering/RenderLayer.h +++ b/WebCore/rendering/RenderLayer.h @@ -260,6 +260,7 @@ public: bool hasOverflowControls() const; #if ENABLE(ANDROID_OVERFLOW_SCROLL) bool hasOverflowScroll() const; + bool hasOverflowParent() const; #endif void positionOverflowControls(int tx, int ty); bool isPointInResizeControl(const IntPoint& absolutePoint) const; @@ -323,11 +324,19 @@ public: bool isFixed() const { return renderer()->isPositioned() && renderer()->style()->position() == FixedPosition; } // If fixed elements are composited, they will be containing children bool isStackingContext() const { +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + if (hasOverflowScroll()) + return true; +#endif return !hasAutoZIndex() || renderer()->isRenderView() || (isComposited() && isFixed()); } #else +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + bool isStackingContext() const { return !hasAutoZIndex() || renderer()->isRenderView() || hasOverflowScroll(); } +#else bool isStackingContext() const { return !hasAutoZIndex() || renderer()->isRenderView() ; } #endif +#endif void dirtyZOrderLists(); void dirtyStackingContextZOrderLists(); diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp index 517a6d2..215b41f 100644 --- a/WebCore/rendering/RenderLayerBacking.cpp +++ b/WebCore/rendering/RenderLayerBacking.cpp @@ -57,10 +57,6 @@ #include "Settings.h" #include "WebGLRenderingContext.h" -#if ENABLE(ANDROID_OVERFLOW_SCROLL) -#include "GraphicsLayerAndroid.h" -#endif - using namespace std; namespace WebCore { @@ -883,20 +879,6 @@ IntRect RenderLayerBacking::contentsBox() const } else #endif contentsRect = toRenderBox(renderer())->contentBoxRect(); -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (m_owningLayer->hasOverflowScroll()) { - // Update the contents rect to have the width and height of the entire - // contents. This rect is only used by the platform GraphicsLayer and - // the position of the rectangle is ignored. Use the layer's scroll - // width/height (which contain the padding). - RenderBox* box = toRenderBox(renderer()); - int outline = box->view()->maximalOutlineSize() << 1; - contentsRect.setWidth(box->borderLeft() + box->borderRight() + - m_owningLayer->scrollWidth() + outline); - contentsRect.setHeight(box->borderTop() + box->borderBottom() + - m_owningLayer->scrollHeight() + outline); - } -#endif IntSize contentOffset = contentOffsetInCompostingLayer(); contentsRect.move(contentOffset); @@ -1116,10 +1098,10 @@ void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& co // can compute and cache clipRects. IntRect enclosingBBox = compositedBounds(); #if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (m_owningLayer->hasOverflowScroll()) { - enclosingBBox.setSize(contentsBox().size()); - enclosingBBox.setLocation(m_compositedBounds.location()); - } + // If we encounter a scrollable layer, layers inside the scrollable layer + // will need their entire content recorded. + if (m_owningLayer->hasOverflowParent()) + enclosingBBox.setSize(clip.size()); #endif IntRect clipRect(clip); diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp index da804dd..cf75a2a 100644 --- a/WebCore/rendering/RenderLayerCompositor.cpp +++ b/WebCore/rendering/RenderLayerCompositor.cpp @@ -286,6 +286,13 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR // 3D transforms turn off the testing of overlap. if (requiresCompositingForTransform(layer->renderer())) setCompositingConsultsOverlap(false); +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + // If we are a child of a scrollable layer, ignore the overlap from the + // scrollable layer as it can cause child layers to become composited + // siblings and will not scroll with the main content layer. + if (layer->hasOverflowParent()) + setCompositingConsultsOverlap(false); +#endif if (!layer->backing()) { |