summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp2
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp30
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp4
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp38
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.h20
-rw-r--r--WebCore/platform/graphics/android/TiledPage.cpp10
-rw-r--r--WebCore/platform/graphics/android/TiledPage.h1
7 files changed, 95 insertions, 10 deletions
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
index 3462975..6d9fe04 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
@@ -137,7 +137,7 @@ bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner)
// can't change the owner out from underneath that texture
android::Mutex::Autolock lock(m_busyLock);
if (!m_busy) {
- if (m_owner)
+ if (m_owner && m_owner != owner)
m_owner->removeTexture(this);
m_owner = owner;
return true;
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index 1e7e209..57a53ab 100644
--- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -174,6 +174,10 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale)
nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds);
}
+ bool zooming = false;
+ if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest)
+ zooming = true;
+
float transparency = 1;
bool doSwap = false;
@@ -209,8 +213,30 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale)
TiledPage* tiledPage = m_glWebViewState->frontPage();
tiledPage->setScale(m_glWebViewState->currentScale());
const SkIRect& preZoomBounds = m_glWebViewState->preZoomBounds();
- tiledPage->prepare(goingDown, goingLeft, preZoomBounds);
- tiledPage->draw(transparency, preZoomBounds);
+
+ TiledPage* nextTiledPage = m_glWebViewState->backPage();
+
+ // We are now using an hybrid model -- during zooming or scrolling,
+ // we will display the current tiledPage even if some tiles are
+ // out of date. When standing still on the other hand, we wait until
+ // the back page is ready before swapping the pages, ensuring that the
+ // displayed content is in sync.
+ if (!zooming && !m_glWebViewState->moving()) {
+ if (!tiledPage->ready(preZoomBounds)) {
+ nextTiledPage->setScale(m_glWebViewState->currentScale());
+ nextTiledPage->prepare(goingDown, goingLeft, preZoomBounds);
+ }
+ if (nextTiledPage->ready(preZoomBounds)) {
+ nextTiledPage->draw(transparency, preZoomBounds);
+ doSwap = true;
+ } else {
+ tiledPage->draw(transparency, preZoomBounds);
+ }
+ } else {
+ // Ask for the tiles and draw -- tiles may be out of date.
+ tiledPage->prepare(goingDown, goingLeft, preZoomBounds);
+ tiledPage->draw(transparency, preZoomBounds);
+ }
bool ret = false;
if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index 35de698..c45b138 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -117,7 +117,7 @@ void BaseTile::reserveTexture()
void BaseTile::removeTexture(BackedDoubleBufferedTexture* texture)
{
- XLOG("%x removeTexture res: %x...", this, m_texture);
+ XLOG("%x removeTexture res: %x... page %x", this, m_texture, m_page);
// We update atomically, so paintBitmap() can see the correct value
android::AutoMutex lock(m_atomicSync);
if (m_texture == texture)
@@ -164,7 +164,7 @@ void BaseTile::draw(float transparency, SkRect& rect)
// No need to mutex protect reads of m_texture as it is only written to by
// the consumer thread.
if (!m_texture) {
- XLOG("%x (%d, %d) trying to draw, but no m_texture!", this, x(), y());
+ XLOG("%x on page %x (%d, %d) trying to draw, but no m_texture!", this, m_page, x(), y());
return;
}
diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp
index 45915e5..326f360 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -70,11 +70,14 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
, m_updateTime(-1)
, m_transitionTime(-1)
, m_baseLayer(0)
+ , m_currentBaseLayer(0)
, m_currentPictureCounter(0)
, m_usePageA(true)
, m_globalButtonMutex(buttonMutex)
+ , m_baseLayerUpdate(true)
{
m_viewport.setEmpty();
+ m_previousViewport.setEmpty();
m_futureViewportTileBounds.setEmpty();
m_viewportTileBounds.setEmpty();
m_preZoomBounds.setEmpty();
@@ -88,6 +91,7 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
GLWebViewState::~GLWebViewState()
{
+ m_currentBaseLayer->safeUnref();
delete m_tiledPageA;
delete m_tiledPageB;
#ifdef DEBUG_COUNT
@@ -107,10 +111,30 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const IntRect& rect)
m_baseLayer = layer;
if (m_baseLayer) {
m_baseLayer->setGLWebViewState(this);
+ }
+ // We only update the layers if we are not currently
+ // waiting for a tiledPage to be painted
+ if (m_baseLayerUpdate) {
+ m_currentBaseLayer->safeUnref();
+ m_currentBaseLayer = layer;
+ m_currentBaseLayer->safeRef();
inval(rect);
+ } else {
+ m_invalidateRect.unite(rect);
}
}
+void GLWebViewState::unlockBaseLayerUpdate() {
+ m_baseLayerUpdate = true;
+ android::Mutex::Autolock lock(m_baseLayerLock);
+ m_currentBaseLayer->safeUnref();
+ m_currentBaseLayer = m_baseLayer;
+ m_currentBaseLayer->safeRef();
+ inval(m_invalidateRect);
+ IntRect empty;
+ m_invalidateRect = empty;
+}
+
void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture,
const IntRect& rect)
{
@@ -136,9 +160,9 @@ void GLWebViewState::inval(const IntRect& rect)
unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
{
android::Mutex::Autolock lock(m_baseLayerLock);
- if (m_baseLayer) {
+ if (m_currentBaseLayer) {
m_globalButtonMutex->lock();
- m_baseLayer->drawCanvas(canvas);
+ m_currentBaseLayer->drawCanvas(canvas);
m_globalButtonMutex->unlock();
}
return m_currentPictureCounter;
@@ -189,6 +213,11 @@ float GLWebViewState::transparency(double currentTime)
return fmin(1, fmax(0, t));
}
+TiledPage* GLWebViewState::sibling(TiledPage* page)
+{
+ return (page == m_tiledPageA) ? m_tiledPageB : m_tiledPageA;
+}
+
TiledPage* GLWebViewState::frontPage()
{
android::Mutex::Autolock lock(m_tiledPageLock);
@@ -213,16 +242,17 @@ void GLWebViewState::swapPages()
int GLWebViewState::baseContentWidth()
{
- return m_baseLayer ? m_baseLayer->getWidth() : 0;
+ return m_currentBaseLayer ? m_currentBaseLayer->getWidth() : 0;
}
int GLWebViewState::baseContentHeight()
{
- return m_baseLayer ? m_baseLayer->getHeight() : 0;
+ return m_currentBaseLayer ? m_currentBaseLayer->getHeight() : 0;
}
void GLWebViewState::setViewport(SkRect& viewport, float scale)
{
+ m_previousViewport = m_viewport;
if (m_viewport == viewport)
return;
diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h
index 8d2216e..3f933ca 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/WebCore/platform/graphics/android/GLWebViewState.h
@@ -173,6 +173,7 @@ public:
void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&);
void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale);
+ TiledPage* sibling(TiledPage* page);
TiledPage* frontPage();
TiledPage* backPage();
void swapPages();
@@ -191,6 +192,20 @@ public:
unsigned int currentPictureCounter() const { return m_currentPictureCounter; }
+ void lockBaseLayerUpdate() { m_baseLayerUpdate = false; }
+ void unlockBaseLayerUpdate();
+
+ bool moving() {
+ // This will only works if we are not zooming -- we check
+ // for this in BaseLayerAndroid::drawBasePictureInGL()
+ if ((m_viewport.fLeft != m_previousViewport.fLeft ||
+ m_viewport.fTop != m_previousViewport.fTop) &&
+ m_viewport.width() == m_previousViewport.width() &&
+ m_viewport.height() == m_previousViewport.height())
+ return true;
+ return false;
+ }
+
private:
void inval(const IntRect& rect); // caller must hold m_baseLayerLock
@@ -212,17 +227,22 @@ private:
double m_transitionTime;
android::Mutex m_tiledPageLock;
SkRect m_viewport;
+ SkRect m_previousViewport;
SkIRect m_viewportTileBounds;
SkIRect m_futureViewportTileBounds;
SkIRect m_preZoomBounds;
android::Mutex m_baseLayerLock;
BaseLayerAndroid* m_baseLayer;
+ BaseLayerAndroid* m_currentBaseLayer;
unsigned int m_currentPictureCounter;
bool m_usePageA;
TiledPage* m_tiledPageA;
TiledPage* m_tiledPageB;
SkIRect m_lastInval;
android::Mutex* m_globalButtonMutex;
+
+ bool m_baseLayerUpdate;
+ IntRect m_invalidateRect;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp
index 868a870..79509dd 100644
--- a/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/WebCore/platform/graphics/android/TiledPage.cpp
@@ -67,6 +67,7 @@ TiledPage::TiledPage(int id, GLWebViewState* state)
, m_invScale(1)
, m_glWebViewState(state)
, m_latestPictureInval(0)
+ , m_prepare(false)
{
// 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
@@ -231,6 +232,8 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
// update the tiles distance from the viewport
updateTileState(tileBounds);
+ m_prepare = true;
+ m_glWebViewState->lockBaseLayerUpdate();
int firstTileX = tileBounds.fLeft;
int firstTileY = tileBounds.fTop;
@@ -291,6 +294,9 @@ bool TiledPage::ready(const SkIRect& tileBounds)
if (!m_glWebViewState)
return false;
+ if (!m_invalRegion.isEmpty() && !m_prepare)
+ return false;
+
for (int x = tileBounds.fLeft; x < tileBounds.fRight; x++) {
for (int y = tileBounds.fTop; y < tileBounds.fBottom; y++) {
BaseTile* t = getBaseTile(x, y);
@@ -298,6 +304,8 @@ bool TiledPage::ready(const SkIRect& tileBounds)
return false;
}
}
+ m_prepare = false;
+ m_glWebViewState->unlockBaseLayerUpdate();
return true;
}
@@ -341,7 +349,7 @@ TiledPage* TiledPage::sibling()
{
if (!m_glWebViewState)
return 0;
- return (m_glWebViewState->frontPage() == this) ? m_glWebViewState->backPage() : this;
+ return m_glWebViewState->sibling(this);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h
index 72e20cd..a194ba5 100644
--- a/WebCore/platform/graphics/android/TiledPage.h
+++ b/WebCore/platform/graphics/android/TiledPage.h
@@ -99,6 +99,7 @@ private:
// within the page, not in content/view pixel coordinates.
SkRegion m_invalRegion;
unsigned int m_latestPictureInval;
+ bool m_prepare;
};
} // namespace WebCore