diff options
author | Cary Clark <cary@android.com> | 2010-01-27 17:00:54 -0500 |
---|---|---|
committer | Cary Clark <cary@android.com> | 2010-02-17 13:13:54 -0500 |
commit | f4cefb9302ee62602c19cdfbdb6cc1fbdf540953 (patch) | |
tree | 26eb246c8427d0fe96326d32ae7f30bf8ec80c82 /WebCore/platform | |
parent | 441d8e9da254d840927752354b40a3b160d3ce68 (diff) | |
download | external_webkit-f4cefb9302ee62602c19cdfbdb6cc1fbdf540953.zip external_webkit-f4cefb9302ee62602c19cdfbdb6cc1fbdf540953.tar.gz external_webkit-f4cefb9302ee62602c19cdfbdb6cc1fbdf540953.tar.bz2 |
Add UI considerations to layers
companion fix is in framework/base
With fixed layers, parts of the web page are now
in motion relative to the document when the page
scrolls. Many routines that formerly read static
coordinates need to compute locations. In some cases,
new computations are cached for speed -- for instance,
the current cursor position is cached when it is
frequently compared.
The cursor rings and other drawing elements like
finding text on the page now to be drawn in the correct
order so that they appear both under and over layers.
There's quite a bit more work to be done. Major
pieces are drawing the text selection in the correct
order, and computing locations based on nest layers.
With this checkin, only the position of the child-
most layer is considered when computing bounds.
http://b/2369549
JavaScriptCore/wtf/Platform.h
- Turn compositing on. All routines that
reference LayerAndroid are bracketed by this
condition.
WebCore/platform/graphics/android/LayerAndroid.h
WebCore/platform/graphics/android/LayerAndroid.cpp
- Add a unique id to each layer. The unique id is
used to associate a layer created when the DOM is
parsed in the webkit thread with its copy in the
UI thread.
- Add: draw the text found on the page, as a call
out in the primary draw. The call out must follow
the drawing the layers' contents to show the found
text correctly. Note that this adds a new slot with
identical contents in every child LayerAndroid. In
a future optimization, a RootLayerAndroid could hold
data common for all child layers.
- Add: clipArea(), which returns an array of rectangles
describing the clip for this LayerAndroid and its
children. Generally, this is the part of the webpage
which is covered by one or more fixed layers.
- Add: find(FloatPoint) that returns the deepest layer
that contains this point. This is used to match taps
to the layer that is tapped on.
- Add: draw all layer pictures and identify
which layer is being drawn. This is used to analyze
the picture contents for finding and selecting text.
- Add: find the layer that matches a given id; this is
used to map cached DOM node data back to the layer
that contains it.
- Fix up includes, delete unused interfaces
WebKit/android/jni/WebViewCore.h
WebKit/android/jni/WebViewCore.cpp
- Remove local mRootLayer; use the one in WebView.cpp
instead (which is in sync with WebView.java)
WebKit/Android.mk
WebKit/android/nav/CachedLayer.h
WebKit/android/nav/CachedLayer.cpp
- CacheLayer associates the cached node with the
LayerAndroid instance. It contains the index to the
node in the cached frame, the LayerAndroid's unique id,
and the spacial offset of the node within the layer
when the DOM information was captured. It also caches
a pointer to the LayerAndroid instance.
CacheLayer computes the node's location each time
it is called, since the fixed layer may be constantly
moving relative to the document's coordinates.
WebKit/android/nav/CacheBuilder.h
WebKit/android/nav/CacheBuilder.cpp
- Track the active layer while building the nav cache.
The 'Tracker' structs were refactored to share common
code, and a new 'LayerTracker' struct identifies when
the node walker is inside a layer.
- Added code to dump layer information for debugging.
- Note that CachedNode::cursorRingsPtr can only be called
during nav data construction
- The cache builder can limit or exclude nodes that
are clipped out -- but until I have more understanding
of layer clipping, treat contained nodes as unclipped.
WebKit/android/nav/CachedDebug.h
- Add a variant that can dump either to a log file
or the console including the function it was dumped from.
WebKit/android/nav/CachedFrame.h
WebKit/android/nav/CachedFrame.cpp
- Add an array of CacheLayer instances.
- Protect bounds from direct access since they must
always be computed.
- Remove misnamed focus parameter from many routines
since the cursor node can be read from the root frame.
- Add: adjustBounds(), which computes the bounds as the
layer moves.
- Add: checkRings(), which gets the appropriate picture
for the node.
- Remove disabled code
- Find the layer list for the matching node by
using a binary search
- Add: resetLayers() to reset the LayerAndroid pointer
in CachedLayers when the layer world changes.
WebKit/android/nav/CachedHistory.h
WebKit/android/nav/CachedHistory.cpp
- Update history data to have matching frame and node
WebKit/android/nav/CachedNode.h
WebKit/android/nav/CachedNode.cpp
- Refactor functions that directly read coordinates
to compute them. In some cases, pass the frame in so
that the layer coordinates can be found.
- Add a bit to note that the node belongs to a layer.
- Remove duplicate bounds interfaces.
- Add methods to get cursor ring data at runtime.
- Update debugging info.
WebKit/android/nav/CachedRoot.h
WebKit/android/nav/CachedRoot.cpp
- Isolate direct picture access so that the layer
picture can be returned.
- Add knowledge of how the base is covered by layers.
- Add a pointer to the root LayerAndroid.
- delete disabled code.
- Move the cursor ring into view if it is obscured
by a layer (this isn't totally working)
- Before finding the next node to move to, set
up 'cursor cache' data, including the visible picture.
WebKit/android/nav/FindCanvas.h
WebKit/android/nav/FindCanvas.cpp
- Move find code here so that it can be called from
layers.
WebKit/android/nav/WebView.cpp
- Add java interface to get viewport metrics on demand.
- Pass frame with the node.
- Remove the find on page code (now in FindCanvas).
- Compute focus rings instead of reading them directly.
- Transfer layer id when getting new nav cache.
- Set up root LayerAndroid.
- Add utility to track if cursor is in a layer.
- Simplify drawLayers() to use common view metrics.
Diffstat (limited to 'WebCore/platform')
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.cpp | 130 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.h | 33 |
2 files changed, 117 insertions, 46 deletions
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index dcbb0c3..8fb335e 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -4,13 +4,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "AndroidAnimation.h" -#include "CString.h" -#include "GraphicsLayerAndroid.h" -#include "PlatformGraphicsContext.h" -#include "RenderLayer.h" -#include "RenderLayerBacking.h" -#include "RenderView.h" -#include "SkDevice.h" +#include "FindCanvas.h" #include "SkDrawFilter.h" #include <wtf/CurrentTime.h> @@ -20,6 +14,8 @@ namespace WebCore { static int gDebugLayerAndroidInstances; +static int gUniqueId; + inline int LayerAndroid::instancesCount() { return gDebugLayerAndroidInstances; @@ -49,7 +45,9 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), m_drawsContent(true), m_haveImage(false), m_haveClip(false), - m_recordingPicture(0) + m_recordingPicture(0), + m_findOnPage(0), + m_uniqueId(++gUniqueId) { gDebugLayerAndroidInstances++; } @@ -59,13 +57,15 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), m_haveContents(layer.m_haveContents), m_drawsContent(layer.m_drawsContent), m_haveImage(layer.m_haveImage), - m_haveClip(layer.m_haveClip) + m_haveClip(layer.m_haveClip), + m_findOnPage(0), + m_uniqueId(layer.m_uniqueId) { m_recordingPicture = layer.m_recordingPicture; SkSafeRef(m_recordingPicture); for (int i = 0; i < layer.countChildren(); i++) - addChild(new LayerAndroid(*static_cast<LayerAndroid*>(layer.getChild(i))))->unref(); + addChild(new LayerAndroid(*layer.getChild(i)))->unref(); KeyframesMap::const_iterator end = layer.m_animations.end(); for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) @@ -94,7 +94,7 @@ bool LayerAndroid::evaluateAnimations() const bool LayerAndroid::hasAnimations() const { for (int i = 0; i < countChildren(); i++) { - if (static_cast<LayerAndroid*>(getChild(i))->hasAnimations()) + if (getChild(i)->hasAnimations()) return true; } return !!m_animations.size(); @@ -104,7 +104,7 @@ bool LayerAndroid::evaluateAnimations(double time) const { bool hasRunningAnimations = false; for (int i = 0; i < countChildren(); i++) { - if (static_cast<LayerAndroid*>(getChild(i))->evaluateAnimations(time)) + if (getChild(i)->evaluateAnimations(time)) hasRunningAnimations = true; } KeyframesMap::const_iterator end = m_animations.end(); @@ -132,10 +132,8 @@ void LayerAndroid::removeAnimation(const String& name) void LayerAndroid::setDrawsContent(bool drawsContent) { m_drawsContent = drawsContent; - for (int i = 0; i < countChildren(); i++) { - LayerAndroid* layer = static_cast<LayerAndroid*>(getChild(i)); - layer->setDrawsContent(drawsContent); - } + for (int i = 0; i < countChildren(); i++) + getChild(i)->setDrawsContent(drawsContent); } // We only use the bounding rect of the layer as mask... @@ -167,13 +165,64 @@ void LayerAndroid::draw(SkCanvas* canvas, const SkRect* viewPort) paintChildren(viewPort, canvas, 1); } +void LayerAndroid::bounds(SkRect* rect) const +{ + rect->fLeft = m_position.fX + m_translation.fX; + rect->fTop = m_position.fY + m_translation.fY; + rect->fRight = rect->fLeft + m_size.width(); + rect->fBottom = rect->fTop + m_size.height(); +} + +bool LayerAndroid::boundsIsUnique(SkTDArray<SkRect>* region, + const SkRect& local) const +{ + for (int i = 0; i < region->count(); i++) { + if ((*region)[i].contains(local)) + return false; + } + return true; +} + +void LayerAndroid::clipArea(SkTDArray<SkRect>* region) const +{ + SkRect local; + local.set(0, 0, std::numeric_limits<float>::max(), + std::numeric_limits<float>::max()); + clipInner(region, local); +} + +void LayerAndroid::clipInner(SkTDArray<SkRect>* region, + const SkRect& local) const +{ + SkRect localBounds; + bounds(&localBounds); + localBounds.intersect(local); + if (localBounds.isEmpty()) + return; + if (m_recordingPicture && boundsIsUnique(region, localBounds)) + *region->append() = localBounds; + for (int i = 0; i < countChildren(); i++) + getChild(i)->clipInner(region, m_haveClip ? localBounds : local); +} + +const LayerAndroid* LayerAndroid::find(FloatPoint pos) const +{ + for (int i = 0; i < countChildren(); i++) { + const LayerAndroid* found = getChild(i)->find(pos); + if (found) + return found; + } + SkRect localBounds; + bounds(&localBounds); + if (localBounds.contains(pos)) + return this; + return 0; +} + void LayerAndroid::setClip(SkCanvas* canvas) { SkRect clip; - clip.fLeft = m_position.fX + m_translation.fX; - clip.fTop = m_position.fY + m_translation.fY; - clip.fRight = clip.fLeft + m_size.width(); - clip.fBottom = clip.fTop + m_size.height(); + bounds(&clip); canvas->clipRect(clip); } @@ -190,13 +239,9 @@ void LayerAndroid::paintChildren(const SkRect* viewPort, SkCanvas* canvas, m_position.fY + m_translation.fY); for (int i = 0; i < countChildren(); i++) { - LayerAndroid* layer = static_cast<LayerAndroid*>(getChild(i)); - if (layer) { - gDebugChildLevel++; - layer->paintChildren(viewPort, - canvas, opacity * m_opacity); - gDebugChildLevel--; - } + gDebugChildLevel++; + getChild(i)->paintChildren(viewPort, canvas, opacity * m_opacity); + gDebugChildLevel--; } canvas->restoreToCount(count); @@ -222,7 +267,9 @@ bool LayerAndroid::calcPosition(const SkRect* viewPort, else if (m_fixedBottom.defined()) y = dy + h - m_fixedBottom.calcFloatValue(h) - m_size.height(); - matrix->setTranslate(x, y); + if (matrix) + matrix->setTranslate(x, y); + setPosition(x, y); return true; } return false; @@ -283,6 +330,8 @@ void LayerAndroid::paintMe(const SkRect* viewPort, m_recordingPicture->draw(canvas); + if (m_findOnPage) + m_findOnPage->drawLayer(canvas, 0, m_uniqueId); #ifdef LAYER_DEBUG float w = m_size.width(); float h = m_size.height(); @@ -400,7 +449,7 @@ void writeLength(FILE* file, int indentLevel, const char* str, SkLength length) fprintf(file, "%s = { type = %d; value = %.2f; };\n", str, length.type, length.value); } -void LayerAndroid::dumpLayers(FILE* file, int indentLevel) +void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const { writeln(file, indentLevel, "{"); @@ -429,15 +478,32 @@ void LayerAndroid::dumpLayers(FILE* file, int indentLevel) for (int i = 0; i < countChildren(); i++) { if (i > 0) writeln(file, indentLevel + 1, ", "); - LayerAndroid* layer = static_cast<LayerAndroid*>(getChild(i)); - if (layer) - layer->dumpLayers(file, indentLevel + 1); + getChild(i)->dumpLayers(file, indentLevel + 1); } writeln(file, indentLevel + 1, "];"); } writeln(file, indentLevel, "}"); } +const LayerAndroid* LayerAndroid::findById(int match) const +{ + if (m_uniqueId == match) + return this; + for (int i = 0; i < countChildren(); i++) { + const LayerAndroid* result = getChild(i)->findById(match); + if (result) + return result; + } + return 0; +} + +void LayerAndroid::setFindOnPage(FindOnPage* findOnPage) +{ + m_findOnPage = findOnPage; + for (int i = 0; i < countChildren(); i++) + getChild(i)->setFindOnPage(findOnPage); +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 104c03a..deb51bc 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -19,26 +19,21 @@ #if USE(ACCELERATED_COMPOSITING) -#include "Color.h" #include "FloatPoint.h" -#include "FloatPoint3D.h" -#include "FloatSize.h" -#include "Length.h" #include "RefPtr.h" +#include "SkColor.h" #include "SkLayer.h" #include "StringHash.h" -#include "Vector.h" #include <wtf/HashMap.h> +class FindOnPage; class SkCanvas; class SkMatrix; class SkPicture; -class SkRect; namespace WebCore { class AndroidAnimation; -class AndroidAnimationValue; class LayerAndroid : public SkLayer { @@ -52,12 +47,14 @@ public: void setHaveContents(bool haveContents) { m_haveContents = haveContents; } void setHaveImage(bool haveImage) { m_haveImage = haveImage; } void setDrawsContent(bool drawsContent); + void setFindOnPage(FindOnPage* findOnPage); void setMaskLayer(LayerAndroid*); void setMasksToBounds(bool); virtual void setBackgroundColor(SkColor color); void setIsRootLayer(bool isRootLayer) { m_isRootLayer = isRootLayer; } virtual void draw(SkCanvas*, const SkRect* viewPort); +// GraphicsContext* paintContext(); bool prepareContext(bool force = false); void startRecording(); void stopRecording(); @@ -72,15 +69,21 @@ public: SkPicture* picture() const { return m_recordingPicture; } - void dumpLayers(FILE*, int indentLevel); - -private: + void dumpLayers(FILE*, int indentLevel) const; + void bounds(SkRect* ) const; bool calcPosition(const SkRect* viewPort, SkMatrix*); - - void paintChildren(const SkRect* viewPort, SkCanvas* canvas, - float opacity); - + void clipArea(SkTDArray<SkRect>* region) const; + const LayerAndroid* find(FloatPoint position) const; + const LayerAndroid* findById(int uniqueID) const; + LayerAndroid* getChild(int index) const { return + static_cast<LayerAndroid*>(m_children[index]); } + bool haveClip() const { return m_haveClip; } + int uniqueId() const { return m_uniqueId; } +private: + bool boundsIsUnique(SkTDArray<SkRect>* region, const SkRect& local) const; + void clipInner(SkTDArray<SkRect>* region, const SkRect& local) const; + void paintChildren(const SkRect* viewPort, SkCanvas* canvas, float opacity); void paintMe(const SkRect* viewPort, SkCanvas* canvas, float opacity); @@ -94,6 +97,8 @@ private: typedef HashMap<String, RefPtr<AndroidAnimation> > KeyframesMap; KeyframesMap m_animations; + FindOnPage* m_findOnPage; + int m_uniqueId; }; } |