summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp20
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp147
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h4
-rw-r--r--Source/WebCore/platform/graphics/android/Layer.h19
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp34
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h17
-rw-r--r--Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h16
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp24
-rw-r--r--Source/WebKit/android/RenderSkinMediaButton.cpp2
-rw-r--r--Source/WebKit/android/WebCoreSupport/ChromiumInit.cpp3
-rw-r--r--Source/WebKit/android/jni/JavaSharedClient.cpp4
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp5
-rw-r--r--Source/WebKit/android/nav/FindCanvas.cpp9
-rw-r--r--Source/WebKit/android/nav/FindCanvas.h7
-rw-r--r--Source/WebKit/android/nav/WebView.cpp64
17 files changed, 244 insertions, 139 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index 1fa69f8..0ab28d7 100644
--- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -239,7 +239,6 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale,
tiledPage->draw(transparency, preZoomBounds);
- m_glWebViewState->paintExtras();
return needsRedraw;
}
#endif // USE(ACCELERATED_COMPOSITING)
@@ -281,12 +280,14 @@ bool BaseLayerAndroid::drawGL(double currentTime, LayerAndroid* compositedRoot,
// Clean up GL textures for video layer.
TilesManager::instance()->videoLayerManager()->deleteUnusedTextures();
+ compositedRoot->prepare(m_glWebViewState);
if (compositedRoot->drawGL(m_glWebViewState, matrix))
needsRedraw = true;
else if (!animsRunning)
m_glWebViewState->resetLayersDirtyArea();
}
+ m_glWebViewState->paintExtras();
m_previousVisible = visibleRect;
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp
index dc17a21..a4ce788 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp
@@ -135,13 +135,12 @@ void BaseTile::reserveTexture()
if (texture && m_backTexture != texture) {
m_swapDrawCount = 0; // no longer ready to swap
m_backTexture = texture;
-
- // this is to catch when the front texture is stolen from beneath us. We
- // should refine the stealing method to be simpler, and not require last
- // moment checks like this
- if (!m_frontTexture)
- m_dirty = true;
}
+
+ // a texture reservation will only happen if we're dirty, or ready to
+ // swap. if it's the former, ensure it's marked dirty.
+ if (!m_swapDrawCount)
+ m_dirty = true;
}
bool BaseTile::removeTexture(BaseTileTexture* texture)
@@ -150,12 +149,15 @@ bool BaseTile::removeTexture(BaseTileTexture* texture)
this, m_backTexture, m_frontTexture, m_page);
// We update atomically, so paintBitmap() can see the correct value
android::AutoMutex lock(m_atomicSync);
- if (m_frontTexture == texture) {
+ if (m_frontTexture == texture)
m_frontTexture = 0;
- m_dirty = true;
- }
if (m_backTexture == texture)
m_backTexture = 0;
+
+ // mark dirty regardless of which texture was taken - the back texture may
+ // have been ready to swap
+ m_dirty = true;
+
return true;
}
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 5764a6b..40a9428 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -32,6 +32,7 @@
#include "ClassTracker.h"
#include "GLUtils.h"
#include "LayerAndroid.h"
+#include "SkPath.h"
#include "TilesManager.h"
#include "TilesTracker.h"
#include <wtf/CurrentTime.h>
@@ -59,6 +60,14 @@
#define FRAMERATE_CAP 0.01666 // We cap at 60 fps
+// Touch ring border width. This is doubled if the ring is not pressed
+#define RING_BORDER_WIDTH 1
+// Color of the ring is 0x6633b5e5 (copied from framework)
+#define RING_COLOR_ALPHA 0.4
+#define RING_COLOR_R 0x33
+#define RING_COLOR_G 0xb5
+#define RING_COLOR_B 0xe5
+
namespace WebCore {
using namespace android;
@@ -170,7 +179,9 @@ void GLWebViewState::setRings(Vector<IntRect>& rings, bool isPressed)
{
android::Mutex::Autolock lock(m_baseLayerLock);
m_displayRings = true;
- m_rings = rings;
+ m_rings.setEmpty();
+ for (size_t i = 0; i < rings.size(); i++)
+ m_rings.op(rings.at(i), SkRegion::kUnion_Op);
m_ringsIsPressed = isPressed;
}
@@ -247,78 +258,80 @@ void GLWebViewState::resetRings()
m_displayRings = false;
}
-void GLWebViewState::drawFocusRing(IntRect& srcRect)
+void GLWebViewState::drawFocusRing(SkRect& srcRect)
{
- // TODO: use a 9-patch texture to draw the focus ring
- // instead of plain colors
- const float alpha = 0.3;
- float borderAlpha = 0.4;
-
- const int r = 51;
- const int g = 181;
- const int b = 229;
-
- int padding = 4;
- int border = 1;
- int fuzzyBorder = border * 2;
- if (!m_ringsIsPressed) {
- padding = 0;
- border = 2;
- fuzzyBorder = 3;
- borderAlpha = 0.2;
- }
if (m_focusRingTexture == -1)
- m_focusRingTexture = GLUtils::createSampleColorTexture(r, g, b);
-
- SkRect rLeft, rTop, rRight, rBottom, rOverlay;
-
- IntRect rect(srcRect.x() - padding, srcRect.y() - padding,
- srcRect.width() + (padding * 2), srcRect.height() + (padding * 2));
- rLeft.set(rect.x() - border, rect.y(),
- rect.x(), rect.y() + rect.height());
- rTop.set(rect.x() - border, rect.y() - border,
- rect.x() + rect.width() + border, rect.y());
- rRight.set(rect.x() + rect.width(), rect.y(),
- rect.x() + rect.width() + border,
- rect.y() + rect.height());
- rBottom.set(rect.x() - border, rect.y() + rect.height(),
- rect.x() + rect.width() + border,
- rect.y() + rect.height() + border);
- rOverlay.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder,
- rect.x() + rect.width() + fuzzyBorder,
- rect.y() + rect.height() + fuzzyBorder);
-
- TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, borderAlpha);
- TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, borderAlpha);
- TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, borderAlpha);
- TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, borderAlpha);
- if (m_ringsIsPressed) {
- TilesManager::instance()->shader()->drawQuad(rOverlay, m_focusRingTexture, alpha);
- } else {
- rLeft.set(rect.x() - fuzzyBorder, rect.y(),
- rect.x(), rect.y() + rect.height());
- rTop.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder,
- rect.x() + rect.width() + fuzzyBorder, rect.y());
- rRight.set(rect.x() + rect.width(), rect.y(),
- rect.x() + rect.width() + fuzzyBorder,
- rect.y() + rect.height());
- rBottom.set(rect.x() - fuzzyBorder, rect.y() + rect.height(),
- rect.x() + rect.width() + fuzzyBorder,
- rect.y() + rect.height() + fuzzyBorder);
- TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, alpha);
- TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, alpha);
- TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, alpha);
- TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, alpha);
- }
+ m_focusRingTexture = GLUtils::createSampleColorTexture(RING_COLOR_R,
+ RING_COLOR_G,
+ RING_COLOR_B);
+
+ TilesManager::instance()->shader()->drawQuad(srcRect, m_focusRingTexture,
+ RING_COLOR_ALPHA);
}
void GLWebViewState::paintExtras()
{
- if (m_displayRings) {
- // TODO: handles correctly the multi-rings case
- for (size_t i = 0; i < m_rings.size(); i++) {
- IntRect rect = m_rings.at(i);
- drawFocusRing(rect);
+ if (m_displayRings && !m_rings.isEmpty()) {
+ if (m_ringsIsPressed) {
+ SkRegion::Iterator rgnIter(m_rings);
+ while (!rgnIter.done()) {
+ SkIRect ir = rgnIter.rect();
+ SkRect r;
+ r.set(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom);
+ drawFocusRing(r);
+ rgnIter.next();
+ }
+ }
+ SkPath path;
+ if (!m_rings.getBoundaryPath(&path))
+ return;
+ SkPath::Iter iter(path, true);
+ SkPath::Verb verb;
+ SkPoint pts[4];
+ SkRegion clip;
+ SkIRect startRect;
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ if (verb == SkPath::kLine_Verb) {
+ SkRect r;
+ r.set(pts, 2);
+ SkIRect line;
+ int borderWidth = RING_BORDER_WIDTH;
+ if (!m_ringsIsPressed)
+ borderWidth *= 2;
+ line.fLeft = r.fLeft - borderWidth;
+ line.fRight = r.fRight + borderWidth;
+ line.fTop = r.fTop - borderWidth;
+ line.fBottom = r.fBottom + borderWidth;
+ if (clip.intersects(line)) {
+ clip.op(line, SkRegion::kReverseDifference_Op);
+ if (clip.isEmpty())
+ continue; // Nothing to draw, continue
+ line = clip.getBounds();
+ if (SkIRect::Intersects(startRect, line)) {
+ clip.op(startRect, SkRegion::kDifference_Op);
+ if (clip.isEmpty())
+ continue; // Nothing to draw, continue
+ line = clip.getBounds();
+ }
+ } else {
+ clip.setRect(line);
+ }
+ r.set(line.fLeft, line.fTop, line.fRight, line.fBottom);
+ drawFocusRing(r);
+ if (!m_ringsIsPressed) {
+ r.fLeft += RING_BORDER_WIDTH;
+ r.fRight -= RING_BORDER_WIDTH;
+ r.fTop += RING_BORDER_WIDTH;
+ r.fBottom -= RING_BORDER_WIDTH;
+ drawFocusRing(r);
+ }
+ if (startRect.isEmpty()) {
+ startRect.set(line.fLeft, line.fTop, line.fRight, line.fBottom);
+ }
+ }
+ if (verb == SkPath::kMove_Verb) {
+ startRect.setEmpty();
+ }
}
}
}
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index a7803de..6c7d31e 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -179,7 +179,7 @@ public:
void setRings(Vector<IntRect>& rings, bool isPressed);
void resetRings();
- void drawFocusRing(IntRect& rect);
+ void drawFocusRing(SkRect& rect);
TiledPage* sibling(TiledPage* page);
TiledPage* frontPage();
@@ -269,7 +269,7 @@ private:
bool m_measurePerfs;
#endif
bool m_displayRings;
- Vector<IntRect> m_rings;
+ SkRegion m_rings;
bool m_ringsIsPressed;
int m_focusRingTexture;
diff --git a/Source/WebCore/platform/graphics/android/Layer.h b/Source/WebCore/platform/graphics/android/Layer.h
index 6450fde..107c457 100644
--- a/Source/WebCore/platform/graphics/android/Layer.h
+++ b/Source/WebCore/platform/graphics/android/Layer.h
@@ -122,14 +122,17 @@ private:
kInheritFromRootTransform_Flag = 0x01
};
- Layer* fParent;
- SkScalar m_opacity;
- SkSize m_size;
- SkPoint m_position;
- SkPoint m_anchorPoint;
- SkMatrix fMatrix;
- SkMatrix fChildrenMatrix;
- uint32_t fFlags;
+ Layer* fParent;
+ SkScalar m_opacity;
+ SkSize m_size;
+ // The position of the origin of the layer, relative to the parent layer.
+ SkPoint m_position;
+ // The point in the layer used as the origin for local transformations,
+ // expressed as a fraction of the layer size.
+ SkPoint m_anchorPoint;
+ SkMatrix fMatrix;
+ SkMatrix fChildrenMatrix;
+ uint32_t fFlags;
SkTDArray<Layer*> m_children;
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index 48dcaaa..a39614f 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -267,7 +267,7 @@ void LayerAndroid::removeAnimationsForKeyframes(const String& name)
}
// We only use the bounding rect of the layer as mask...
-// TODO: use a real mask?
+// FIXME: use a real mask?
void LayerAndroid::setMaskLayer(LayerAndroid* layer)
{
if (layer)
@@ -546,7 +546,7 @@ void LayerAndroid::updatePositions()
if (!m_isFixed) {
// turn our fields into a matrix.
//
- // TODO: this should happen in the caller, and we should remove these
+ // FIXME: this should happen in the caller, and we should remove these
// fields from our subclass
SkMatrix matrix;
GLUtils::toSkMatrix(matrix, m_transform);
@@ -793,6 +793,26 @@ void LayerAndroid::clearDirtyRegion()
m_dirtyRegion.setEmpty();
}
+void LayerAndroid::prepare(GLWebViewState* glWebViewState)
+{
+ int count = this->countChildren();
+ if (count > 0) {
+ Vector <LayerAndroid*> sublayers;
+ for (int i = 0; i < count; i++)
+ sublayers.append(this->getChild(i));
+
+ // now we sort for the transparency
+ std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
+
+ // iterate in reverse so top layers get textures first
+ for (int i = count-1; i >= 0; i--)
+ sublayers[i]->prepare(glWebViewState);
+ }
+
+ if (m_texture)
+ m_texture->prepare(glWebViewState);
+}
+
bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
{
TilesManager::instance()->shader()->clip(m_clippingRect);
@@ -801,10 +821,8 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
bool askPaint = false;
- if (m_texture) {
- m_texture->prepare(glWebViewState);
+ if (m_texture)
askPaint |= m_texture->draw();
- }
// When the layer is dirty, the UI thread should be notified to redraw.
askPaint |= drawChildrenGL(glWebViewState, matrix);
@@ -817,7 +835,6 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
return askPaint;
}
-
bool LayerAndroid::drawChildrenGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
{
bool askPaint = false;
@@ -926,6 +943,11 @@ SkRect LayerAndroid::subtractLayers(const SkRect& visibleRect) const
{
SkRect result;
if (m_recordingPicture) {
+ // FIXME: This seems wrong. localToGlobal() applies the full local transform,
+ // se surely we should operate globalMatrix on size(), not bounds() with
+ // the position removed? Perhaps we never noticed the bug because most
+ // layers don't use a local transform?
+ // See http://b/5338388
SkRect globalRect = bounds();
globalRect.offset(-getPosition()); // localToGlobal adds in position
SkMatrix globalMatrix;
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index 7192aaf..8078762 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -109,6 +109,10 @@ public:
void setBackfaceVisibility(bool value) { m_backfaceVisibility = value; }
void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
FloatPoint translation() const;
+ // Returns a rect describing the bounds of the layer with the local
+ // transformation applied, expressed relative to the parent layer.
+ // FIXME: Currently we use only the translation component of the local
+ // transformation.
SkRect bounds() const;
IntRect clippedRect() const;
bool outsideViewport();
@@ -121,8 +125,14 @@ public:
void showLayer(int indent);
float getScale() { return m_scale; }
+
+ // draw layer and its children via Z, pre-order traversal
virtual bool drawGL(GLWebViewState*, SkMatrix&);
bool drawChildrenGL(GLWebViewState*, SkMatrix&);
+
+ // prepare layer and its children via reverse-Z, post-order traversal
+ void prepare(GLWebViewState*);
+
void updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
const FloatRect& clip, float opacity, float scale);
void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
@@ -183,9 +193,10 @@ public:
SkPicture* picture() const { return m_recordingPicture; }
- // remove layers bounds from visible rectangle to show what can be
- // scrolled into view; returns original minus layer bounds in global space.
- SkRect subtractLayers(const SkRect& visibleRect) const;
+ // Given a rect in global space, subtracts from it the bounds of this layer
+ // and of all of its children. Returns the bounding rectangle of the result,
+ // in global space.
+ SkRect subtractLayers(const SkRect&) const;
void dumpLayers(FILE*, int indentLevel) const;
void dumpToLog() const;
diff --git a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
index ca8f03c..2bb8b5c 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
@@ -18,10 +18,7 @@ bool ScrollableLayerAndroid::scrollTo(int x, int y)
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);
+ setPosition(m_scrollLimits.fLeft - newX, m_scrollLimits.fTop - newY);
return true;
}
diff --git a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
index c3fdecd..b59b4e1 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
@@ -42,15 +42,16 @@ public:
virtual LayerAndroid* copy() const { return new ScrollableLayerAndroid(*this); }
- // Returns true if the content position has changed.
- bool scrollTo(int dx, int dy);
+ // Scrolls to the given position in the layer.
+ // Returns whether or not any scrolling was required.
+ bool scrollTo(int x, int y);
- // Fills the rect with the current scroll offset and the maximum scroll.
+ // Fills the rect with the current scroll offset and the maximum scroll offset.
// fLeft = scrollX
// fTop = scrollY
- // fRight = maxX
- // fBottom = maxY
- void getScrollRect(SkIRect* out) const;
+ // fRight = maxScrollX
+ // fBottom = maxScrollY
+ void getScrollRect(SkIRect*) const;
void setScrollLimits(float x, float y, float width, float height)
{
@@ -61,6 +62,9 @@ public:
friend LayerAndroid* android::deserializeLayer(SkStream* stream);
private:
+ // The position of the visible area of the layer, relative to the parent
+ // layer. This is fixed during scrolling. We acheive scrolling by modifying
+ // the position of the layer.
SkRect m_scrollLimits;
};
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index ee35ce2..e1d7665 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -267,11 +267,13 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
}
// The heuristic for selecting a texture is as follows:
- // 1. If a tile isn't owned, break with that one
- // 2. Don't let tiles acquire their front textures
- // 3. If we find a tile in the same page with a different scale,
+ // 1. Skip textures currently being painted, they can't be painted while
+ // busy anyway
+ // 2. If a tile isn't owned, break with that one
+ // 3. Don't let tiles acquire their front textures
+ // 4. If we find a tile in the same page with a different scale,
// it's old and not visible. Break with that one
- // 4. Otherwise, use the least recently prepared tile, but ignoring tiles
+ // 5. Otherwise, use the least recently prepared tile, but ignoring tiles
// drawn in the last frame to avoid flickering
BaseTileTexture* farthestTexture = 0;
@@ -280,15 +282,23 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
for (unsigned int i = 0; i < max; i++) {
BaseTileTexture* texture = (*availableTexturePool)[i];
TextureOwner* currentOwner = texture->owner();
+
+ if (texture->busy()) {
+ // don't bother, since the acquire() will likely fail
+ continue;
+ }
+
if (!currentOwner) {
+ // unused texture! take it!
farthestTexture = texture;
break;
}
- // Don't let a tile acquire its own front texture, as the acquisition
- // logic doesn't handle that
- if (currentOwner == owner)
+ if (currentOwner == owner) {
+ // Don't let a tile acquire its own front texture, as the
+ // acquisition logic doesn't handle that
continue;
+ }
if (currentOwner->page() == owner->page() && texture->scale() != owner->scale()) {
// if we render the back page with one scale, then another while
diff --git a/Source/WebKit/android/RenderSkinMediaButton.cpp b/Source/WebKit/android/RenderSkinMediaButton.cpp
index 294dec5..ef4b313 100644
--- a/Source/WebKit/android/RenderSkinMediaButton.cpp
+++ b/Source/WebKit/android/RenderSkinMediaButton.cpp
@@ -62,7 +62,7 @@ static const PatchData gFiles[] =
{ "ic_media_video_poster.png", 0, 0 }, // VIDEO
{ "btn_media_player_disabled.9.png", 0, 0 }, // BACKGROUND_SLIDER
{ "scrubber_track_holo_dark.9.png", 0, 0 }, // SLIDER_TRACK
- { "scrubber_control_holo.png", 0, 0 } // SLIDER_THUMB
+ { "scrubber_control_normal_holo.png", 0, 0 } // SLIDER_THUMB
};
static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])];
diff --git a/Source/WebKit/android/WebCoreSupport/ChromiumInit.cpp b/Source/WebKit/android/WebCoreSupport/ChromiumInit.cpp
index 500975c..f5029d5 100644
--- a/Source/WebKit/android/WebCoreSupport/ChromiumInit.cpp
+++ b/Source/WebKit/android/WebCoreSupport/ChromiumInit.cpp
@@ -68,7 +68,8 @@ void initChromium()
if (!initCalled) {
logging::SetLogMessageHandler(logMessageHandler);
networkChangeNotifier.reset(net::NetworkChangeNotifier::Create());
- net::HttpNetworkLayer::EnableSpdy("npn");
+ // Disable SPDY for bug 5226268 [Browser] http keep-alive packets are sent too frequently to network
+ // net::HttpNetworkLayer::EnableSpdy("npn");
initCalled = true;
jni::SetJavaVM(JSC::Bindings::getJavaVM());
}
diff --git a/Source/WebKit/android/jni/JavaSharedClient.cpp b/Source/WebKit/android/jni/JavaSharedClient.cpp
index e884c99..4f40355 100644
--- a/Source/WebKit/android/jni/JavaSharedClient.cpp
+++ b/Source/WebKit/android/jni/JavaSharedClient.cpp
@@ -117,7 +117,7 @@ namespace android {
void (*proc)(void*) = 0;
void* payload = 0;
const FuncPtrRec* rec;
-
+
// we have to copy the proc/payload (if present). we do this so we
// don't call the proc inside the mutex (possible deadlock!)
gFuncPtrQMutex.acquire();
@@ -128,7 +128,7 @@ namespace android {
gFuncPtrQ.pop_front();
}
gFuncPtrQMutex.release();
-
+
if (!rec)
break;
proc(payload);
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index 8b2029f..24266f6 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -2189,6 +2189,11 @@ void WebViewCore::setSelection(int start, int end)
String WebViewCore::modifySelection(const int direction, const int axis)
{
DOMSelection* selection = m_mainFrame->domWindow()->getSelection();
+ ASSERT(selection);
+ // We've seen crashes where selection is null, but we don't know why
+ // See http://b/5244036
+ if (!selection)
+ return String();
if (selection->rangeCount() > 1)
selection->removeAllRanges();
switch (axis) {
diff --git a/Source/WebKit/android/nav/FindCanvas.cpp b/Source/WebKit/android/nav/FindCanvas.cpp
index 2d310b3..ca3cfba 100644
--- a/Source/WebKit/android/nav/FindCanvas.cpp
+++ b/Source/WebKit/android/nav/FindCanvas.cpp
@@ -532,9 +532,6 @@ IntRect FindOnPage::currentMatchBounds() const {
if (!m_matches || !m_matches->size())
return noBounds;
MatchInfo& info = (*m_matches)[m_findIndex];
- // FIXME: this should test if the match in the layer is visible
- if (info.isInLayer())
- return noBounds;
return info.getLocation().getBounds();
}
@@ -545,6 +542,10 @@ bool FindOnPage::currentMatchIsInLayer() const {
return info.isInLayer();
}
+int FindOnPage::currentMatchLayerId() const {
+ return (*m_matches)[m_findIndex].layerId();
+}
+
// This function is only used by findNext and setMatches. In it, we store
// upper left corner of the match specified by m_findIndex in
// m_currentMatchLocation.
@@ -597,7 +598,7 @@ void FindOnPage::draw(SkCanvas* canvas, LayerAndroid* layer, IntRect* inval) {
unsigned numberOfMatches = m_matches->size();
if (numberOfMatches > 1
&& numberOfMatches < MAX_NUMBER_OF_MATCHES_TO_DRAW) {
- for(unsigned i = 0; i < numberOfMatches; i++) {
+ for (unsigned i = 0; i < numberOfMatches; i++) {
// The current match has already been drawn
if (i == m_findIndex)
continue;
diff --git a/Source/WebKit/android/nav/FindCanvas.h b/Source/WebKit/android/nav/FindCanvas.h
index 76ee1e2..994ff17 100644
--- a/Source/WebKit/android/nav/FindCanvas.h
+++ b/Source/WebKit/android/nav/FindCanvas.h
@@ -54,9 +54,9 @@ public:
SkPicture* getPicture() const { return m_picture; }
// This will make a copy of the region, and increase the ref count on the
// SkPicture. If this MatchInfo already had one, unref it.
+ void set(const SkRegion& region, SkPicture* pic, int layerId);
bool isInLayer() const { return m_layerId >= 0; }
int layerId() const { return m_layerId; }
- void set(const SkRegion& region, SkPicture* pic, int layerId);
private:
MatchInfo& operator=(MatchInfo& src);
SkRegion m_location;
@@ -141,7 +141,7 @@ public:
const SkPaint& paint) {
}
- void drawLayers(LayerAndroid* );
+ void drawLayers(LayerAndroid*);
int found() const { return mNumFound; }
void setLayerId(int layerId) { mLayerId = layerId; }
@@ -227,6 +227,9 @@ public:
IntRect currentMatchBounds() const;
int currentMatchIndex() const { return m_findIndex; }
bool currentMatchIsInLayer() const;
+ // This requires the current match to be in a layer. See
+ // currentMatchIsInLayer().
+ int currentMatchLayerId() const;
virtual void draw(SkCanvas* , LayerAndroid* , IntRect* );
void findNext(bool forward);
bool isCurrentLocationValid() { return m_hasCurrentLocation; }
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index a528e9a..101e206 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -105,8 +105,7 @@ class WebView
public:
enum FrameCachePermission {
DontAllowNewer,
- AllowNewer,
- AllowNewest
+ AllowNewer
};
enum DrawExtras { // keep this in sync with WebView.java
@@ -332,8 +331,32 @@ void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate)
}
}
-// The caller has already determined that the desired document rect corresponds
-// to the main picture, and not a layer
+void scrollToCurrentMatch()
+{
+ if (!m_findOnPage.currentMatchIsInLayer()) {
+ scrollRectOnScreen(m_findOnPage.currentMatchBounds());
+ return;
+ }
+
+ SkRect matchBounds = m_findOnPage.currentMatchBounds();
+ const LayerAndroid* rootLayer = getFrameCache(DontAllowNewer)->rootLayer();
+ const Layer* layerContainingMatch = rootLayer->findById(m_findOnPage.currentMatchLayerId());
+ ASSERT(layerContainingMatch);
+
+ // FIXME: If the match is in a scrollable layer or a child of such a layer,
+ // we may need to scroll these layers to make sure the match is visible.
+ // See http://b/5262656.
+
+ // Convert matchBounds to the global space so we can scroll the main page.
+ SkMatrix transform;
+ layerContainingMatch->localToGlobal(&transform);
+ SkRect transformedMatchBounds;
+ transform.mapRect(&transformedMatchBounds, matchBounds);
+ SkIRect roundedTransformedMatchBounds;
+ transformedMatchBounds.roundOut(&roundedTransformedMatchBounds);
+ scrollRectOnScreen(roundedTransformedMatchBounds);
+}
+
void scrollRectOnScreen(const IntRect& rect)
{
if (rect.isEmpty())
@@ -489,8 +512,23 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In
m_glWebViewState->resetRings();
if (extra) {
if (extra == &m_ring) {
+ WTF::Vector<IntRect> rings;
if (root == m_ring.m_frame)
- m_glWebViewState->setRings(m_ring.rings(), m_ring.m_isPressed);
+ rings = m_ring.rings();
+ else {
+ // TODO: Fix the navcache to work with layers correctly
+ // In the meantime, this works around the bug. However, the rings
+ // it produces are not as nice for some reason, thus we use
+ // m_ring.rings() above for the base layer instead of the below
+ for (size_t i = 0; i < m_ring.m_node->rings().size(); i++) {
+ IntRect rect = m_ring.m_node->rings().at(i);
+ rect = m_ring.m_frame->adjustBounds(m_ring.m_node, rect);
+ rect.inflate(4);
+ rings.append(rect);
+ }
+ }
+ m_glWebViewState->setRings(rings, m_ring.m_isPressed);
+ extra = 0;
} else {
LayerAndroid mainPicture(m_navPictureUI);
PictureSet* content = m_baseLayer->content();
@@ -1290,8 +1328,7 @@ void sendMotionUp(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y
void findNext(bool forward)
{
m_findOnPage.findNext(forward);
- if (!m_findOnPage.currentMatchIsInLayer())
- scrollRectOnScreen(m_findOnPage.currentMatchBounds());
+ scrollToCurrentMatch();
viewInvalidate();
}
@@ -1303,21 +1340,16 @@ void setMatches(WTF::Vector<MatchInfo>* matches, jboolean sameAsLastSearch)
// location to determine whether to scroll. If the same word is found
// in the same place, then do not scroll.
IntRect oldLocation;
- bool checkAgainstOldLocation;
+ bool checkAgainstOldLocation = false;
if (sameAsLastSearch && m_findOnPage.isCurrentLocationValid()) {
oldLocation = m_findOnPage.currentMatchBounds();
checkAgainstOldLocation = true;
- } else
- checkAgainstOldLocation = false;
+ }
m_findOnPage.setMatches(matches);
- if (!checkAgainstOldLocation
- || oldLocation != m_findOnPage.currentMatchBounds()) {
- // FIXME: Need to scroll if the match is in a layer.
- if (!m_findOnPage.currentMatchIsInLayer())
- scrollRectOnScreen(m_findOnPage.currentMatchBounds());
- }
+ if (!checkAgainstOldLocation || oldLocation != m_findOnPage.currentMatchBounds())
+ scrollToCurrentMatch();
viewInvalidate();
}