summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--LayoutTests/platform/android/test_expectations.txt8
-rw-r--r--WebCore/dom/Element.cpp15
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp4
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp16
-rw-r--r--WebCore/platform/graphics/android/BaseTile.h5
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp8
-rw-r--r--WebCore/platform/graphics/android/GraphicsContextAndroid.cpp11
-rw-r--r--WebCore/platform/graphics/android/TiledPage.cpp140
-rw-r--r--WebCore/platform/graphics/android/TiledPage.h12
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp23
-rw-r--r--WebCore/platform/graphics/android/TilesManager.h5
-rw-r--r--WebKit/android/nav/CachedRoot.cpp9
-rw-r--r--WebKit/android/nav/CachedRoot.h4
-rw-r--r--WebKit/android/nav/SelectText.cpp53
-rw-r--r--WebKit/android/nav/SelectText.h1
15 files changed, 196 insertions, 118 deletions
diff --git a/LayoutTests/platform/android/test_expectations.txt b/LayoutTests/platform/android/test_expectations.txt
index 8ad1bd8..bc38578 100644
--- a/LayoutTests/platform/android/test_expectations.txt
+++ b/LayoutTests/platform/android/test_expectations.txt
@@ -43,7 +43,6 @@ ietestcenter/Javascript/15.4.4.15-3-8.html CRASH // hangs the layout tests http:
// This first block of tests are for features for which Android
// should pass all tests. They are skipped only temporarily.
// TODO: Fix these failing tests and remove them from this list.
-fast/encoding/char-encoding.html FAIL // fails in Java HTTP stack, see http://b/issue?id=3047156
fast/encoding/char-decoding.html FAIL // fails in Java HTTP stack, see http://b/issue?id=3047156
fast/encoding/hanarei-blog32-fc2-com.html FAIL // fails in Java HTTP stack, see http://b/issue?id=3046986
fast/encoding/mailto-always-utf-8.html FAIL // Requires waitForPolicyDelegate(), see http://b/issue?id=3043468
@@ -96,6 +95,13 @@ dom/xhtml/level3/core/nodegetbaseuri18.xhtml FAIL
dom/xhtml/level3/core/nodelookupnamespaceuri01.xhtml FAIL
dom/xhtml/level3/core/nodelookupprefix19.xhtml FAIL
+// Expected failures for pixel tests
+fast/encoding/denormalised-voiced-japanese-chars.html FAIL
+fast/encoding/invalid-UTF-8.html FAIL
+fast/encoding/utf-16-big-endian.html FAIL
+fast/encoding/utf-16-little-endian.html FAIL
+fast/encoding/xmacroman-encoding-test.html FAIL
+
// Expected failures due to DumpRenderTree2 serving tests from http://127.0.0.1
// rather than file://
// TODO: Consider checking in Android expected results for these tests, once
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index a86f30a..be74487 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -947,6 +947,17 @@ bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderS
return false;
}
+#ifdef ANDROID_STYLE_VERSION
+static bool displayDiff(const RenderStyle* s1, const RenderStyle* s2)
+{
+ if (!s1 || !s2)
+ return false;
+ return s1->display() != s2->display()
+ || s1->left() != s2->left() || s1->top() != s2->top()
+ || s1->right() != s2->right() || s1->bottom() != s2->bottom();
+}
+#endif
+
void Element::recalcStyle(StyleChange change)
{
// Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
@@ -962,7 +973,9 @@ void Element::recalcStyle(StyleChange change)
if ((change > NoChange || needsStyleRecalc())) {
#ifdef ANDROID_STYLE_VERSION
- document()->incStyleVersion();
+ RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);
+ if (displayDiff(currentStyle.get(), newStyle.get()))
+ document()->incStyleVersion();
#endif
if (hasRareData())
rareData()->resetComputedStyle();
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index 2d38dc1..c7420c8 100644
--- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -186,8 +186,8 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale)
tiledPage->draw(transparency, viewport, originalTX, originalTY);
bool ret = false;
- if (!tiledPage->ready(originalTX, originalTY)
- || m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest)
+ if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest
+ || !tiledPage->ready(originalTX, originalTY))
ret = true;
if (doSwap)
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index ff5d9ca..6fd9e89 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -66,10 +66,10 @@ int BaseTile::count()
}
#endif
-BaseTile::BaseTile(TiledPage* page, int x, int y)
- : m_page(page)
- , m_x(x)
- , m_y(y)
+BaseTile::BaseTile()
+ : m_page(0)
+ , m_x(-1)
+ , m_y(-1)
, m_texture(0)
, m_scale(1)
, m_dirty(true)
@@ -91,6 +91,14 @@ BaseTile::~BaseTile()
// All the following functions must be called from the main GL thread.
+void BaseTile::setContents(TiledPage* page, int x, int y)
+{
+ android::AutoMutex lock(m_atomicSync);
+ m_page = page;
+ m_x = x;
+ m_y = y;
+}
+
void BaseTile::reserveTexture()
{
BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this);
diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h
index 8870cbf..8f095e3 100644
--- a/WebCore/platform/graphics/android/BaseTile.h
+++ b/WebCore/platform/graphics/android/BaseTile.h
@@ -64,9 +64,12 @@ public:
#ifdef DEBUG_COUNT
static int count();
#endif
- BaseTile(TiledPage* page, int x, int y);
+ BaseTile();
~BaseTile();
+ void setContents(TiledPage* page, int x, int y);
+ bool isAvailable() const { return !m_texture; }
+
void reserveTexture();
void removeTexture();
void setUsedLevel(int);
diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp
index 4ad22d8..617690c 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -217,9 +217,9 @@ void GLWebViewState::setViewport(SkRect& viewport, float scale)
return;
m_viewport = viewport;
- float fnbw = m_viewport.width() * scale / TilesManager::instance()->tileWidth();
+ float fnbw = m_viewport.width() * scale / TilesManager::tileWidth();
int nbw = static_cast<int>(ceilf(fnbw));
- float fnbh = m_viewport.height() * scale / TilesManager::instance()->tileHeight();
+ float fnbh = m_viewport.height() * scale / TilesManager::tileHeight();
int nbh = static_cast<int>(ceilf(fnbh));
m_nbTilesWidth = nbw + 1;
m_nbTilesHeight = nbh + 1;
@@ -227,8 +227,8 @@ void GLWebViewState::setViewport(SkRect& viewport, float scale)
m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom,
m_viewport.width(), m_viewport.height(), scale,
m_nbTilesWidth, m_nbTilesHeight);
- m_firstTileX = static_cast<int>(m_viewport.fLeft * scale / TilesManager::instance()->tileWidth());
- m_firstTileY = static_cast<int>(m_viewport.fTop * scale / TilesManager::instance()->tileHeight());
+ m_firstTileX = static_cast<int>(m_viewport.fLeft * scale / TilesManager::tileWidth());
+ m_firstTileY = static_cast<int>(m_viewport.fTop * scale / TilesManager::tileHeight());
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
index 5d38295..b76f5d5 100644
--- a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
@@ -70,7 +70,7 @@ template <typename T> T* deepCopyPtr(const T* src)
// Is Color premultiplied or not? If it is, then I can't blindly pass it to paint.setColor()
struct ShadowRec {
- SkScalar blur; // >=0 means valid shadow
+ SkScalar blur; // >0 means valid shadow
SkScalar dx;
SkScalar dy;
SkColor color;
@@ -149,13 +149,13 @@ public:
bool setupShadowPaint(SkPaint* paint, SkPoint* offset)
{
- if (shadow.blur >= 0) {
+ if (shadow.blur > 0) {
paint->setAntiAlias(true);
paint->setDither(true);
paint->setXfermodeMode(mode);
paint->setColor(shadow.color);
paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur,
- SkBlurMaskFilter::kNormal_BlurStyle))->safeUnref();
+ SkBlurMaskFilter::kNormal_BlurStyle))->unref();
offset->set(shadow.dx, shadow.dy);
return true;
}
@@ -253,7 +253,7 @@ public:
paint->setAntiAlias(m_state->useAA);
paint->setDither(true);
paint->setXfermodeMode(m_state->mode);
- if (m_state->shadow.blur >= 0) {
+ if (m_state->shadow.blur > 0) {
SkDrawLooper* looper = new SkBlurDrawLooper(m_state->shadow.blur,
m_state->shadow.dx,
m_state->shadow.dy,
@@ -944,6 +944,9 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const
if (paintingDisabled())
return;
+ if (blur <= 0)
+ this->clearPlatformShadow();
+
SkColor c;
if (color.isValid())
c = color.rgb();
diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp
index 358c1a8..eb500ac 100644
--- a/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/WebCore/platform/graphics/android/TiledPage.cpp
@@ -67,41 +67,47 @@ TiledPage::TiledPage(int id, GLWebViewState* state)
, m_glWebViewState(state)
, m_latestPictureInval(0)
{
+ // This value must be at least 1 greater than the max number of allowed
+ // textures. This is because prepare() asks for a tile before it reserves
+ // a texture for that tile. If all textures are currently in use by the
+ // page then there will be no available tile and having the extra tile
+ // ensures that this does not happen. After claiming the extra tile the call
+ // to reserveTexture() will cause some other tile in the page to lose it's
+ // texture and become available, thus ensuring that we always have at least
+ // one tile that is available.
+ m_baseTileSize = TilesManager::maxTextureCount() + 1;
+ m_baseTiles = new BaseTile[m_baseTileSize];
+
#ifdef DEBUG_COUNT
gTilePageCount++;
#endif
}
TiledPage::~TiledPage() {
- // Stop any pixmap generation
- if (m_baseTiles.size()) {
- TilesManager::instance()->removeSetsWithPage(this);
- }
- m_glWebViewState = 0;
- // At this point, we can safely deallocate the BaseTiles, as
- // there is no more BaseTile painting or scheduled to be painted
- // by the TextureGenerator, and as we did reset the BaseLayer in GLWebViewState,
- // in WebView's destructor (so no additional painting can be scheduled)
- deleteAllValues(m_baseTiles);
+ // In order to delete the page we must ensure that none of its BaseTiles are
+ // currently painting or scheduled to be painted by the TextureGenerator
+ TilesManager::instance()->removeSetsWithPage(this);
+ delete[] m_baseTiles;
#ifdef DEBUG_COUNT
gTilePageCount--;
#endif
}
-BaseTile* TiledPage::getBaseTile(int x, int y)
+BaseTile* TiledPage::getBaseTile(int x, int y) const
{
- // if (x,y) is (0,0) the HashMap will treat the key as a null value and will
- // not store the tile so we increment the key values by 1
- TileKey key(x+1, y+1);
- return m_baseTiles.get(key);
+ for (int j = 0; j < m_baseTileSize; j++) {
+ BaseTile& tile = m_baseTiles[j];
+ if (tile.x() == x && tile.y() == y && !tile.isAvailable())
+ return &tile;
+ }
+ return 0;
}
void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureCount)
{
// Given the current scale level we need to mark the appropriate tiles as dirty
- TilesManager* manager = TilesManager::instance();
- const float invTileContentWidth = m_scale / manager->tileWidth();
- const float invTileContentHeight = m_scale / manager->tileHeight();
+ const float invTileContentWidth = m_scale / TilesManager::tileWidth();
+ const float invTileContentHeight = m_scale / TilesManager::tileHeight();
const int firstDirtyTileX = static_cast<int>(floorf(inval.x() * invTileContentWidth));
const int firstDirtyTileY = static_cast<int>(floorf(inval.y() * invTileContentHeight));
@@ -131,20 +137,31 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y
else
x += (tilesInRow - 1) - i;
- TileKey key(x+1, y+1);
- BaseTile* tile = 0;
- if (!m_baseTiles.contains(key)) {
- tile = new BaseTile(this, x, y);
- m_baseTiles.set(key, tile);
+
+ BaseTile* currentTile = 0;
+ BaseTile* availableTile = 0;
+ for (int j = 0; j < m_baseTileSize; j++) {
+ BaseTile& tile = m_baseTiles[j];
+ if (tile.x() == x && tile.y() == y) {
+ currentTile = &tile;
+ break;
+ }
+ if (!availableTile && tile.isAvailable())
+ availableTile = &tile;
+ }
+
+ if (!currentTile) {
+ currentTile = availableTile;
+ currentTile->setContents(this, x, y);
}
- tile = m_baseTiles.get(key);
- tile->setScale(m_scale);
+
+ currentTile->setScale(m_scale);
// ensure there is a texture associated with the tile and then check to
// see if the texture is dirty and in need of repainting
- tile->reserveTexture();
- if(tile->isDirty())
- set->add(tile);
+ currentTile->reserveTexture();
+ if(currentTile->isDirty())
+ set->add(currentTile);
}
}
@@ -156,35 +173,36 @@ void TiledPage::updateTileState(int firstTileX, int firstTileY)
const int nbTilesWidth = m_glWebViewState->nbTilesWidth();
const int nbTilesHeight = m_glWebViewState->nbTilesHeight();
- TileMap::const_iterator end = m_baseTiles.end();
- for (TileMap::const_iterator it = m_baseTiles.begin(); it != end; ++it) {
- BaseTile* tile = it->second;
+ for (int x = 0; x < m_baseTileSize; x++) {
+
+ BaseTile& tile = m_baseTiles[x];
- if(!tile)
+ // if the tile no longer has a texture then proceed to the next tile
+ if (tile.isAvailable())
continue;
// if the tile is in the dirty region then we must invalidate it
- if (m_invalRegion.contains(tile->x(), tile->y()))
- tile->markAsDirty(m_latestPictureInval);
+ if (m_invalRegion.contains(tile.x(), tile.y()))
+ tile.markAsDirty(m_latestPictureInval);
// set the used level of the tile (e.g. distance from the viewport)
int dx = 0;
int dy = 0;
- if (firstTileX > tile->x())
- dx = firstTileX - tile->x();
- else if (firstTileX + (nbTilesWidth - 1) < tile->x())
- dx = tile->x() - firstTileX - (nbTilesWidth - 1);
+ if (firstTileX > tile.x())
+ dx = firstTileX - tile.x();
+ else if (firstTileX + (nbTilesWidth - 1) < tile.x())
+ dx = tile.x() - firstTileX - (nbTilesWidth - 1);
- if (firstTileY > tile->y())
- dy = firstTileY - tile->y();
- else if (firstTileY + (nbTilesHeight - 1) < tile->y())
- dy = tile->y() - firstTileY - (nbTilesHeight - 1);
+ if (firstTileY > tile.y())
+ dy = firstTileY - tile.y();
+ else if (firstTileY + (nbTilesHeight - 1) < tile.y())
+ dy = tile.y() - firstTileY - (nbTilesHeight - 1);
int d = std::max(dx, dy);
XLOG("setTileLevel tile: %x, fxy(%d, %d), level: %d", tile, firstTileX, firstTileY, d);
- tile->setUsedLevel(d);
+ tile.setUsedLevel(d);
}
// clear the invalidated region as all tiles within that region have now
@@ -245,32 +263,28 @@ void TiledPage::draw(float transparency, SkRect& viewport, int firstTileX, int f
if (!m_glWebViewState)
return;
- float w = TilesManager::instance()->tileWidth() * m_invScale;
- float h = TilesManager::instance()->tileHeight() * m_invScale;
- int nbTilesWidth = m_glWebViewState->nbTilesWidth();
- int nbTilesHeight = m_glWebViewState->nbTilesHeight();
-
- XLOG("WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
- for (int i = 0; i < nbTilesHeight; i++) {
- for (int j = 0; j < nbTilesWidth; j++) {
- int x = j + firstTileX;
- int y = i + firstTileY;
+ const float tileWidth = TilesManager::tileWidth() * m_invScale;
+ const float tileHeight = TilesManager::tileHeight() * m_invScale;
- BaseTile* tile = getBaseTile(x, y);
+ SkIRect viewportTilesRect;
+ viewportTilesRect.fLeft = firstTileX;
+ viewportTilesRect.fTop = firstTileY;
+ viewportTilesRect.fRight = firstTileY + m_glWebViewState->nbTilesWidth() + 1;
+ viewportTilesRect.fBottom = firstTileY + m_glWebViewState->nbTilesHeight() + 1;
- if (!tile) {
- XLOG("NO TILE AT %d, %d", x, y);
- continue;
- }
+ XLOG("WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
+ for (int j = 0; j < m_baseTileSize; j++) {
+ BaseTile& tile = m_baseTiles[j];
+ if(viewportTilesRect.contains(tile.x(), tile.y())) {
SkRect rect;
- rect.fLeft = x * w;
- rect.fTop = y * h;
- rect.fRight = rect.fLeft + w;
- rect.fBottom = rect.fTop + h;
+ rect.fLeft = tile.x() * tileWidth;
+ rect.fTop = tile.y() * tileHeight;
+ rect.fRight = rect.fLeft + tileWidth;
+ rect.fBottom = rect.fTop + tileHeight;
TilesManager::instance()->shader()->setViewport(viewport);
- tile->draw(transparency, rect);
+ tile.draw(transparency, rect);
}
}
diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h
index b532033..1edf5b4 100644
--- a/WebCore/platform/graphics/android/TiledPage.h
+++ b/WebCore/platform/graphics/android/TiledPage.h
@@ -38,9 +38,6 @@ namespace WebCore {
class GLWebViewState;
class IntRect;
-typedef std::pair<int, int> TileKey;
-typedef HashMap<TileKey, BaseTile*> TileMap;
-
/**
* The TiledPage represents a map of BaseTiles covering the viewport. Each
* GLWebViewState contains two TiledPages, one to display the page at the
@@ -83,9 +80,14 @@ private:
void updateTileState(int firstTileX, int firstTileY);
void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set);
- BaseTile* getBaseTile(int x, int y);
+ BaseTile* getBaseTile(int x, int y) const;
- TileMap m_baseTiles;
+ // array of tiles used to compose a page. The tiles are allocated in the
+ // constructor to prevent them from potentially being allocated on the stack
+ BaseTile* m_baseTiles;
+ // stores the number of tiles in the m_baseTiles array. This enables us to
+ // quickly iterate over the array without have to check it's size
+ int m_baseTileSize;
int m_id;
float m_scale;
float m_invScale;
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index 9ebfe02..38dd282 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -55,17 +55,17 @@
// second page used when scaling.
// In our case, we use 300x300 textures. On the tablet, this equals to
// at least 24 (6 * 4) textures, hence 48.
-#define DEFAULT_TEXTURES_ALLOCATION 48
-#define DEFAULT_TEXTURE_SIZE_WIDTH 300
-#define DEFAULT_TEXTURE_SIZE_HEIGHT 300
+#define MAX_TEXTURE_ALLOCATION 48
+#define TILE_WIDTH 300
+#define TILE_HEIGHT 300
namespace WebCore {
TilesManager::TilesManager()
: m_generatorReady(false)
{
- m_textures.reserveCapacity(DEFAULT_TEXTURES_ALLOCATION);
- for (int i = 0; i < DEFAULT_TEXTURES_ALLOCATION; i++) {
+ m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
+ for (int i = 0; i < MAX_TEXTURE_ALLOCATION; i++) {
BackedDoubleBufferedTexture* texture = new BackedDoubleBufferedTexture(
tileWidth(), tileHeight());
// the atomic load ensures that the texture has been fully initialized
@@ -217,14 +217,19 @@ BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner)
return 0;
}
-float TilesManager::tileWidth() const
+int TilesManager::maxTextureCount()
{
- return DEFAULT_TEXTURE_SIZE_WIDTH;
+ return MAX_TEXTURE_ALLOCATION;
}
-float TilesManager::tileHeight() const
+float TilesManager::tileWidth()
{
- return DEFAULT_TEXTURE_SIZE_HEIGHT;
+ return TILE_WIDTH;
+}
+
+float TilesManager::tileHeight()
+{
+ return TILE_HEIGHT;
}
TilesManager* TilesManager::instance()
diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h
index 1f9cd38..86f6ce0 100644
--- a/WebCore/platform/graphics/android/TilesManager.h
+++ b/WebCore/platform/graphics/android/TilesManager.h
@@ -69,8 +69,9 @@ public:
void resetTextureUsage(TiledPage* page);
void paintTexturesDefault();
- float tileWidth() const;
- float tileHeight() const;
+ static int maxTextureCount();
+ static float tileWidth();
+ static float tileHeight();
private:
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index 813357c..4ae66de 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -1661,7 +1661,7 @@ const CachedNode* CachedRoot::nextTextField(const CachedNode* start,
return CachedFrame::nextTextField(start, framePtr, &startFound);
}
-SkPicture* CachedRoot::pictureAt(int* xPtr, int* yPtr) const
+SkPicture* CachedRoot::pictureAt(int* xPtr, int* yPtr, int* id) const
{
#if USE(ACCELERATED_COMPOSITING)
if (mRootLayer) {
@@ -1675,13 +1675,18 @@ SkPicture* CachedRoot::pictureAt(int* xPtr, int* yPtr) const
layer->bounds(&localBounds);
*xPtr -= localBounds.fLeft;
*yPtr -= localBounds.fTop;
- if (picture)
+ if (picture) {
+ if (id)
+ *id = layer->uniqueId();
return picture;
+ }
}
}
#endif
DBG_NAV_LOGD("root mPicture=%p (%d,%d)", mPicture, mPicture ?
mPicture->width() : 0, mPicture ? mPicture->height() : 0);
+ if (id)
+ *id = -1;
return mPicture;
}
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index 18bace3..a09e4fb 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -85,7 +85,9 @@ public:
*/
const CachedNode* nextTextField(const CachedNode* start,
const CachedFrame** framePtr) const;
- SkPicture* pictureAt(int* xPtr, int* yPtr) const;
+ SkPicture* pictureAt(int* xPtr, int* yPtr, int* id) const;
+ SkPicture* pictureAt(int* xPtr, int* yPtr) const {
+ return pictureAt(xPtr, yPtr, 0); }
void reset();
CachedHistory* rootHistory() const { return mHistory; }
const WebCore::LayerAndroid* rootLayer() const { return mRootLayer; }
diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp
index 4af9521..36530b6 100644
--- a/WebKit/android/nav/SelectText.cpp
+++ b/WebKit/android/nav/SelectText.cpp
@@ -423,23 +423,26 @@ public:
*/
int dx = rect.fLeft + rect.fRight - (mFocusX << 1);
int dy = top() + bottom() - (mFocusY << 1);
- int distance = dx * dx + dy * dy;
+ dx = abs(dx);
+ dy = abs(dy);
#ifdef EXTRA_NOISY_LOGGING
- if (distance < 500 || abs(distance - mDistance) < 500)
- DBG_NAV_LOGD("FirstCheck distance=%d mDistance=%d", distance, mDistance);
+ if (dy < 15)
+ DBG_NAV_LOGD("FirstCheck dx/y=(%d, %d) mDx/y=(%d, %d)",
+ dx>>1, dy>>1, mDx>>1, mDy>>1);
#endif
- if (mDistance > distance) {
+ if (mDy > dy || (mDy == dy && mDx > dx)) {
mBestBase = base();
mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom());
#ifndef EXTRA_NOISY_LOGGING
- if (distance < 100)
+ if (dy < 10 && dx < 10)
#endif
{
- DBG_NAV_LOGD("FirstCheck mBestBounds={%d,%d,r=%d,b=%d} distance=%d",
+ DBG_NAV_LOGD("FirstCheck mBestBounds={%d,%d,r=%d,b=%d} dx/y=(%d, %d)",
mBestBounds.fLeft, mBestBounds.fTop,
- mBestBounds.fRight, mBestBounds.fBottom, distance >> 2);
+ mBestBounds.fRight, mBestBounds.fBottom, dx>>1, dy>>1);
}
- mDistance = distance;
+ mDx = dx;
+ mDy = dy;
if (mRecordGlyph)
recordGlyph(rec);
}
@@ -449,7 +452,7 @@ public:
void reset()
{
mBestBounds.setEmpty();
- mDistance = INT_MAX;
+ mDx = mDy = INT_MAX;
}
void setRecordGlyph()
@@ -460,7 +463,8 @@ public:
protected:
int mBestBase;
SkIRect mBestBounds;
- int mDistance;
+ int mDx;
+ int mDy;
int mFocusX;
int mFocusY;
bool mRecordGlyph;
@@ -496,28 +500,30 @@ public:
{
int dx = mLeft ? mFocusX - rect.fRight : rect.fLeft - mFocusX;
int dy = ((top() + bottom()) >> 1) - mFocusY;
+ dx = abs(dx);
+ dy = abs(dy);
if (mLeft ? mFocusX <= rect.fLeft : mFocusX >= rect.fRight) {
- if (abs(dx) <= 10 && abs(dy) <= 10) {
+ if (dx <= 10 && dy <= 10) {
DBG_NAV_LOGD("EdgeCheck fLeft=%d fRight=%d mFocusX=%d dx=%d dy=%d",
rect.fLeft, rect.fRight, mFocusX, dx, dy);
}
return false;
}
- int distance = dx * dx + dy * dy;
- if (mDistance > distance) {
+ if (mDy > dy || (mDy == dy && mDx > dx)) {
if (rec.fLSB == mLastGlyph.fLSB && rec.fRSB == mLastGlyph.fRSB) {
DBG_NAV_LOGD("dup rec.fLSB.fX=%g rec.fRSB.fX=%g",
SkFixedToScalar(rec.fLSB.fX), SkFixedToScalar(rec.fRSB.fX));
return false;
}
recordGlyph(rec);
- mDistance = distance;
+ mDx = dx;
+ mDy = dy;
mBestBase = base();
mBestBounds.set(rect.fLeft, top(), rect.fRight, bottom());
- if (distance <= 100) {
- DBG_NAV_LOGD("EdgeCheck mBestBounds={%d,%d,r=%d,b=%d} distance=%d",
+ if (dx <= 10 && dy <= 10) {
+ DBG_NAV_LOGD("EdgeCheck mBestBounds={%d,%d,r=%d,b=%d} dx/y=(%d, %d)",
mBestBounds.fLeft, mBestBounds.fTop,
- mBestBounds.fRight, mBestBounds.fBottom, distance);
+ mBestBounds.fRight, mBestBounds.fBottom, dx, dy);
}
}
return false;
@@ -830,6 +836,8 @@ public:
if (VERBOSE_LOGGING) DBG_NAV_LOGD("full == mEnd full=(%d,%d,r=%d,b=%d)",
full.fLeft, full.fTop, full.fRight, full.fBottom);
mCapture = false;
+ if (full == mStart)
+ addLastToRegion();
}
return false;
}
@@ -1288,8 +1296,12 @@ SelectText::~SelectText()
void SelectText::draw(SkCanvas* canvas, LayerAndroid* layer)
{
- if (!m_picture || m_picture != layer->picture())
+ if (m_layerId != layer->uniqueId())
return;
+ // reset m_picture to match m_layerId
+ m_picture->safeUnref();
+ m_picture = layer->picture();
+ m_picture->safeRef();
DBG_NAV_LOGD("m_extendSelection=%d m_drawPointer=%d layer [%d]",
m_extendSelection, m_drawPointer, layer->uniqueId());
if (m_extendSelection)
@@ -1328,6 +1340,8 @@ void SelectText::drawSelectionPointer(SkCanvas* canvas)
void SelectText::drawSelectionRegion(SkCanvas* canvas)
{
+ if (!m_picture)
+ return;
m_selRegion.setEmpty();
SkIRect ivisBounds = m_visibleRect;
ivisBounds.join(m_selStart);
@@ -1510,6 +1524,7 @@ void SelectText::reset()
m_startSelection = false;
m_picture->safeUnref();
m_picture = 0;
+ m_layerId = 0;
}
void SelectText::selectAll()
@@ -1546,7 +1561,7 @@ bool SelectText::startSelection(const CachedRoot* root, const IntRect& vis,
{
m_startOffset.set(x, y);
m_picture->safeUnref();
- m_picture = root->pictureAt(&x, &y);
+ m_picture = root->pictureAt(&x, &y, &m_layerId);
if (!m_picture) {
DBG_NAV_LOG("picture==0");
return false;
diff --git a/WebKit/android/nav/SelectText.h b/WebKit/android/nav/SelectText.h
index d210117..8247356 100644
--- a/WebKit/android/nav/SelectText.h
+++ b/WebKit/android/nav/SelectText.h
@@ -73,6 +73,7 @@ private:
SkIRect m_selEnd;
int m_startBase;
int m_endBase;
+ int m_layerId;
SkIRect m_visibleRect; // constrains picture computations to visible area
SkRegion m_selRegion; // computed from sel start, end
SkPicture m_startControl;