diff options
Diffstat (limited to 'WebCore/platform/graphics/android')
6 files changed, 158 insertions, 80 deletions
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index fe7b132..0fdbc21 100644 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -32,6 +32,7 @@ #include "RenderView.h" #include "RotateTransformOperation.h" #include "ScaleTransformOperation.h" +#include "ScrollableLayerAndroid.h" #include "SkCanvas.h" #include "TransformationMatrix.h" #include "TranslateTransformOperation.h" @@ -263,6 +264,8 @@ void GraphicsLayerAndroid::updateFixedPosition() void GraphicsLayerAndroid::setPosition(const FloatPoint& point) { + if (point == m_currentPosition) + return; m_currentPosition = point; m_needsDisplay = true; #ifdef LAYER_DEBUG_2 @@ -276,6 +279,8 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point) void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point) { + if (point == m_anchorPoint) + return; GraphicsLayer::setAnchorPoint(point); m_contentLayer->setAnchorPoint(point.x(), point.y()); askForSync(); @@ -283,14 +288,13 @@ void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point) void GraphicsLayerAndroid::setSize(const FloatSize& size) { - if ((size.width() != m_size.width()) - || (size.height() != m_size.height())) { - MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height()); - GraphicsLayer::setSize(size); - m_contentLayer->setSize(size.width(), size.height()); - updateFixedPosition(); - askForSync(); - } + if (size == m_size) + return; + MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height()); + GraphicsLayer::setSize(size); + m_contentLayer->setSize(size.width(), size.height()); + updateFixedPosition(); + askForSync(); } void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t) @@ -329,7 +333,7 @@ void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t) void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer) { if (layer == m_maskLayer) - return; + return; GraphicsLayer::setMaskLayer(layer); m_needsSyncMask = true; @@ -338,6 +342,8 @@ void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer) void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds) { + if (masksToBounds == m_masksToBounds) + return; GraphicsLayer::setMasksToBounds(masksToBounds); m_needsSyncMask = true; askForSync(); @@ -345,20 +351,30 @@ void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds) void GraphicsLayerAndroid::setDrawsContent(bool drawsContent) { + if (drawsContent == m_drawsContent) + return; GraphicsLayer::setDrawsContent(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); + 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 (false /* FIXME: disable until navigation is fixed */ && + layer->isRootLayer() && + layer->renderer()->frame()->ownerRenderer()) { + // Replace the content layer with a scrollable layer. + LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer); + m_contentLayer->unref(); + m_contentLayer = layer; + } } #endif @@ -370,6 +386,8 @@ void GraphicsLayerAndroid::setDrawsContent(bool drawsContent) void GraphicsLayerAndroid::setBackgroundColor(const Color& color) { + if (color == m_backgroundColor) + return; LOG("(%x) setBackgroundColor", this); GraphicsLayer::setBackgroundColor(color); SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue()); @@ -387,6 +405,8 @@ void GraphicsLayerAndroid::clearBackgroundColor() void GraphicsLayerAndroid::setContentsOpaque(bool opaque) { + if (opaque == m_contentsOpaque) + return; LOG("(%x) setContentsOpaque (%d)", this, opaque); GraphicsLayer::setContentsOpaque(opaque); m_haveContents = true; @@ -449,6 +469,7 @@ bool GraphicsLayerAndroid::repaint() // with SkPicture, we request the entire layer's content. IntRect layerBounds(0, 0, m_size.width(), m_size.height()); + RenderLayer* layer = renderLayerFromClient(m_client); if (m_foregroundLayer) { PaintingPhase phase(this); // Paint the background into a separate context. @@ -456,7 +477,6 @@ bool GraphicsLayerAndroid::repaint() 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(); @@ -485,11 +505,20 @@ bool GraphicsLayerAndroid::repaint() // 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); + // Set the scrollable bounds of the layer. + m_foregroundLayer->setScrollLimits(-x, -y, m_size.width(), m_size.height()); } else { // If there is no contents clip, we can draw everything into one // picture. if (!paintContext(m_contentLayer->recordContext(), layerBounds)) return false; + // Check for a scrollable iframe and report the scrolling + // limits based on the view size. + if (m_contentLayer->contentIsScrollable()) { + FrameView* view = layer->renderer()->frame()->view(); + static_cast<ScrollableLayerAndroid*>(m_contentLayer)->setScrollLimits( + m_position.x(), m_position.y(), view->layoutWidth(), view->layoutHeight()); + } } TLOG("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!", @@ -579,7 +608,7 @@ bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList, double beginTime) { if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() != 2) - return false; + return false; bool createdAnimations = false; if (valueList.property() == AnimatedPropertyWebkitTransform) { @@ -882,6 +911,8 @@ void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth) void GraphicsLayerAndroid::setZPosition(float position) { + if (position == m_zPosition) + return; LOG("(%x) setZPosition: %.2f", this, position); GraphicsLayer::setZPosition(position); askForSync(); diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index 098ad37..ea8c5c9 100644 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -32,6 +32,8 @@ class Image; namespace WebCore { +class ScrollableLayerAndroid; + class GraphicsLayerAndroid : public GraphicsLayer { public: @@ -149,7 +151,7 @@ private: Vector<FloatRect> m_invalidatedRects; LayerAndroid* m_contentLayer; - LayerAndroid* m_foregroundLayer; + ScrollableLayerAndroid* m_foregroundLayer; LayerAndroid* m_foregroundClipLayer; }; diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index ca9a0e3..f02136a 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -51,7 +51,6 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), m_haveClip(false), m_doRotation(false), m_isFixed(false), - m_contentScrollable(false), m_recordingPicture(0), m_contentsImage(0), m_extra(0), @@ -68,7 +67,6 @@ 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) { @@ -96,7 +94,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), SkSafeRef(m_recordingPicture); for (int i = 0; i < layer.countChildren(); i++) - addChild(new LayerAndroid(*layer.getChild(i)))->unref(); + addChild(layer.getChild(i)->copy())->unref(); KeyframesMap::const_iterator end = layer.m_animations.end(); for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) @@ -110,7 +108,6 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(), m_haveClip(false), m_doRotation(false), m_isFixed(false), - m_contentScrollable(false), m_recordingPicture(picture), m_contentsImage(0), m_extra(0), @@ -476,46 +473,6 @@ SkPicture* LayerAndroid::recordContext() return 0; } -bool LayerAndroid::scrollTo(int x, int y) { - SkIRect scrollBounds; - getScrollRect(&scrollBounds); - if (scrollBounds.fRight == 0 && scrollBounds.fBottom == 0) - return false; - - SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight); - SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom); - // Check for no change. - if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop) - return false; - - SkScalar diffX = newX - scrollBounds.fLeft; - SkScalar diffY = newY - scrollBounds.fTop; - const SkPoint& pos = getPosition(); - setPosition(pos.fX - diffX, pos.fY - diffY); - return true; -} - -void LayerAndroid::getScrollRect(SkIRect* out) const { - if (!contentIsScrollable()) - return; - - // Scrollable layers have a mask layer and then the actual main layer. - if (getParent() == 0 || getParent()->getParent() == 0) - return; - LayerAndroid* realLayer = static_cast<LayerAndroid*>(getParent()->getParent()); - - SkRect scrollBounds; - realLayer->bounds(&scrollBounds); - - const SkPoint& maskLayerPosition = getParent()->getPosition(); - const SkPoint& pos = getPosition(); - // Our original position is the offset of the mask layer's position. - out->fLeft = maskLayerPosition.fX - pos.fX; - out->fTop = maskLayerPosition.fY - pos.fY; - out->fRight = getSize().width() - scrollBounds.width(); - out->fBottom = getSize().height() - scrollBounds.height(); -} - bool LayerAndroid::prepareContext(bool force) { if (masksToBounds()) diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 30f5555..510014b 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -131,15 +131,6 @@ public: SkPicture* recordContext(); - // Returns true if the content position has changed. - bool scrollTo(int dx, int dy); - // Fills the rect with the current scroll offset and the maximum scroll. - // fLeft = scrollX - // fTop = scrollY - // fRight = maxX - // fBottom = maxY - void getScrollRect(SkIRect* out) const; - void addAnimation(PassRefPtr<AndroidAnimation> anim); void removeAnimation(const String& name); bool evaluateAnimations() const; @@ -193,12 +184,8 @@ public: 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; - } + virtual bool contentIsScrollable() const { return false; } + virtual LayerAndroid* copy() const { return new LayerAndroid(*this); } protected: virtual void onDraw(SkCanvas*, SkScalar opacity); @@ -219,7 +206,6 @@ private: bool m_doRotation; bool m_isFixed; bool m_backgroundColorSet; - bool m_contentScrollable; SkLength m_fixedLeft; SkLength m_fixedTop; diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp new file mode 100644 index 0000000..7b40b8d --- /dev/null +++ b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp @@ -0,0 +1,37 @@ +#include "config.h" +#include "ScrollableLayerAndroid.h" + +#if USE(ACCELERATED_COMPOSITING) + +namespace WebCore { + +bool ScrollableLayerAndroid::scrollTo(int x, int y) { + SkIRect scrollBounds; + getScrollRect(&scrollBounds); + if (scrollBounds.fRight == 0 && scrollBounds.fBottom == 0) + return false; + + SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight); + SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom); + // Check for no change. + if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop) + return false; + + SkScalar diffX = newX - scrollBounds.fLeft; + SkScalar diffY = newY - scrollBounds.fTop; + const SkPoint& pos = getPosition(); + setPosition(pos.fX - diffX, pos.fY - diffY); + return true; +} + +void ScrollableLayerAndroid::getScrollRect(SkIRect* out) const { + const SkPoint& pos = getPosition(); + out->fLeft = m_scrollLimits.fLeft - pos.fX; + out->fTop = m_scrollLimits.fTop - pos.fY; + out->fRight = getSize().width() - m_scrollLimits.width(); + out->fBottom = getSize().height() - m_scrollLimits.height(); +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h new file mode 100644 index 0000000..d63625a --- /dev/null +++ b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ScrollableLayerAndroid_h +#define ScrollableLayerAndroid_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerAndroid.h" + +namespace WebCore { + +class ScrollableLayerAndroid : public LayerAndroid { + +public: + ScrollableLayerAndroid() + : LayerAndroid(false) {} + ScrollableLayerAndroid(const ScrollableLayerAndroid& layer) + : LayerAndroid(layer) + , m_scrollLimits(layer.m_scrollLimits) {} + ScrollableLayerAndroid(const LayerAndroid& layer) + : LayerAndroid(layer) { + m_scrollLimits.setEmpty(); + } + virtual ~ScrollableLayerAndroid() {}; + + virtual bool contentIsScrollable() const { return true; } + + virtual LayerAndroid* copy() const { return new ScrollableLayerAndroid(*this); } + + // Returns true if the content position has changed. + bool scrollTo(int dx, int dy); + // Fills the rect with the current scroll offset and the maximum scroll. + // fLeft = scrollX + // fTop = scrollY + // fRight = maxX + // fBottom = maxY + void getScrollRect(SkIRect* out) const; + + void setScrollLimits(float x, float y, float width, float height) { + m_scrollLimits.set(x, y, width, height); + } + +private: + SkRect m_scrollLimits; +}; + +} + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif // LayerAndroid_h |