// Let's prepare the page if needed
if (prepareNextTiledPage) {
- TiledPage* nextTiledPage = m_glWebViewState->backPage();
nextTiledPage->setScale(scale);
m_glWebViewState->setFutureViewport(viewportTileBounds);
m_glWebViewState->lockBaseLayerUpdate();
- nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds);
+ nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds, TiledPage::kVisibleBounds);
// Cancel pending paints for the foreground page
TilesManager::instance()->removePaintOperationsForPage(tiledPage, false);
}
float nextTiledPageTransparency = 1;
zoomManager->processTransition(currentTime, scale, &doSwap,
&nextTiledPageTransparency, &transparency);
-
nextTiledPage->draw(nextTiledPageTransparency, viewportTileBounds);
}
bool needsRedraw = false;
- // We are now using an hybrid model -- during 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 (!doSwap && !zooming && !m_glWebViewState->moving()) {
- if (!tiledPage->ready(preZoomBounds, zoomManager->currentScale())) {
+ static bool waitOnScrollFinish = false;
+
+ if (m_glWebViewState->isScrolling()) {
+ if (!waitOnScrollFinish) {
+ waitOnScrollFinish = true;
+
+ //started scrolling, lock updates
m_glWebViewState->lockBaseLayerUpdate();
- nextTiledPage->setScale(zoomManager->currentScale());
- nextTiledPage->prepare(goingDown, goingLeft, preZoomBounds);
- }
- if (nextTiledPage->ready(preZoomBounds, zoomManager->currentScale())) {
- nextTiledPage->draw(transparency, preZoomBounds);
- m_glWebViewState->resetFrameworkInval();
- m_glWebViewState->unlockBaseLayerUpdate();
- doSwap = true;
- } else {
- tiledPage->draw(transparency, preZoomBounds);
}
} else {
- if (tiledPage->ready(preZoomBounds, zoomManager->currentScale()))
- m_glWebViewState->resetFrameworkInval();
-
- // Ask for the tiles and draw -- tiles may be out of date.
- if (!zooming)
- m_glWebViewState->unlockBaseLayerUpdate();
+ // wait until all tiles are rendered before anything else
+ if (waitOnScrollFinish) {
+ //wait for the page to finish rendering, then go into swap mode
+ if (tiledPage->ready(preZoomBounds, zoomManager->currentScale())) {
+ m_glWebViewState->resetFrameworkInval();
+ m_glWebViewState->unlockBaseLayerUpdate();
+ waitOnScrollFinish = false;
+ }
+ //should be prepared, simply draw
+ }
- if (!prepareNextTiledPage)
- tiledPage->prepare(goingDown, goingLeft, preZoomBounds);
- tiledPage->draw(transparency, preZoomBounds);
+ if (!waitOnScrollFinish) {
+ //completed page post-scroll
+ if (!tiledPage->ready(preZoomBounds, zoomManager->currentScale())) {
+ m_glWebViewState->lockBaseLayerUpdate();
+ }
+ }
}
+ if (!prepareNextTiledPage || tiledPage->ready(preZoomBounds, zoomManager->currentScale()))
+ tiledPage->prepare(goingDown, goingLeft, preZoomBounds, TiledPage::kExpandedBounds);
+ tiledPage->draw(transparency, preZoomBounds);
+
if (zoomManager->scaleRequestState() != ZoomManager::kNoScaleRequest
|| !tiledPage->ready(preZoomBounds, zoomManager->currentScale()))
needsRedraw = true;
if (doSwap) {
zoomManager->setCurrentScale(scale);
m_glWebViewState->swapPages();
- m_glWebViewState->unlockBaseLayerUpdate();
if (pagesSwapped)
*pagesSwapped = true;
}
// if no longer trailing behind invalidates, unlock (so invalidates can
// go directly to the the TiledPages without deferral)
- if (!needsRedraw)
+ if (!needsRedraw && !waitOnScrollFinish)
m_glWebViewState->unlockBaseLayerUpdate();
m_glWebViewState->paintExtras();
using namespace android;
GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
- : m_baseLayer(0)
+ : m_zoomManager(this)
+ , m_baseLayer(0)
, m_currentBaseLayer(0)
, m_previouslyUsedRoot(0)
, m_currentPictureCounter(0)
, m_backgroundColor(SK_ColorWHITE)
, m_displayRings(false)
, m_focusRingTexture(-1)
+ , m_isScrolling(false)
, m_goingDown(true)
, m_goingLeft(false)
, m_expandedTileBoundsX(0)
, m_expandedTileBoundsY(0)
- , m_zoomManager(this)
{
m_viewport.setEmpty();
- m_previousViewport.setEmpty();
m_futureViewportTileBounds.setEmpty();
m_viewportTileBounds.setEmpty();
m_preZoomBounds.setEmpty();
m_currentPictureCounter++;
if (!rect.isEmpty()) {
// find which tiles fall within the invalRect and mark them as dirty
- m_tiledPageA->invalidateRect(rect, m_currentPictureCounter);
- m_tiledPageB->invalidateRect(rect, m_currentPictureCounter);
+ frontPage()->invalidateRect(rect, m_currentPictureCounter);
if (m_frameworkInval.isEmpty())
m_frameworkInval = rect;
else
void GLWebViewState::setViewport(SkRect& viewport, float scale)
{
- m_previousViewport = m_viewport;
if ((m_viewport == viewport) &&
(zoomManager()->futureScale() == scale))
return;
- m_goingDown = m_previousViewport.fTop - viewport.fTop <= 0;
- m_goingLeft = m_previousViewport.fLeft - viewport.fLeft >= 0;
+ m_goingDown = m_viewport.fTop - viewport.fTop <= 0;
+ m_goingLeft = m_viewport.fLeft - viewport.fLeft >= 0;
m_viewport = viewport;
XLOG("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f currentScale: %.2f futureScale: %.2f)",
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;
- }
+ void setIsScrolling(bool isScrolling) { m_isScrolling = isScrolling; }
+ bool isScrolling() { return m_isScrolling; }
double setupDrawing(IntRect& rect, SkRect& viewport, IntRect& webViewRect,
int titleBarHeight, IntRect& screenClip,
ZoomManager m_zoomManager;
android::Mutex m_tiledPageLock;
SkRect m_viewport;
- SkRect m_previousViewport;
SkIRect m_viewportTileBounds;
SkIRect m_futureViewportTileBounds;
SkIRect m_preZoomBounds;
bool m_ringsIsPressed;
int m_focusRingTexture;
+ bool m_isScrolling;
bool m_goingDown;
bool m_goingLeft;
m_invalTilesRegion.setEmpty();
}
-void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds)
+void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds)
{
if (!m_glWebViewState)
return;
// smoother scrolling.
int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
int nMaxTilesPerPage = m_baseTileSize / 2;
- int expandX = m_glWebViewState->expandedTileBoundsX();
- int expandY = m_glWebViewState->expandedTileBoundsY();
- firstTileX -= expandX;
- lastTileX += expandX;
- nbTilesWidth += expandX * 2;
+ if (bounds == kExpandedBounds) {
+ // prepare tiles outside of the visible bounds
+ int expandX = m_glWebViewState->expandedTileBoundsX();
+ int expandY = m_glWebViewState->expandedTileBoundsY();
- firstTileY -= expandY;
- lastTileY += expandY;
- nbTilesHeight += expandY * 2;
+ firstTileX -= expandX;
+ lastTileX += expandX;
+ nbTilesWidth += expandX * 2;
+
+ firstTileY -= expandY;
+ lastTileY += expandY;
+ nbTilesHeight += expandY * 2;
+ }
m_expandedTileBounds.fLeft = firstTileX;
m_expandedTileBounds.fTop = firstTileY;
*/
class TiledPage : public TilePainter {
public:
+ enum PrepareBounds {
+ kExpandedBounds = 0,
+ kVisibleBounds = 1
+ };
+
TiledPage(int id, GLWebViewState* state);
~TiledPage();
TiledPage* sibling();
// prepare the page for display on the screen
- void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds);
+ void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds);
// check to see if the page is ready for display
bool ready(const SkIRect& tileBounds, float scale);
// draw the page on the screen
bool WebViewCore::drawIsPaused() const
{
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject javaObject = m_javaGlue->object(env);
- if (!javaObject.get())
- return false;
- return env->GetBooleanField(javaObject.get(), gWebViewCoreFields.m_drawIsPaused);
+ // returning true says scrollview should be offscreen, which pauses
+ // gifs. because this is not again queried when we stop scrolling, we don't
+ // use the stopping currently.
+ return false;
}
#if USE(CHROME_NETWORK_STACK)
return GET_NATIVE_VIEW(env, obj)->focusBoundsChanged();
}
+static void SetIsPaused(JNIEnv* env, jobject obj, jboolean isPaused)
+{
+ // tell the webcore thread to stop thinking while we do other work
+ // (selection and scrolling). This has nothing to do with the lifecycle
+ // pause and resume.
+ GET_NATIVE_VIEW(env, obj)->setIsPaused(isPaused);
+}
+
static void Pause(JNIEnv* env, jobject obj)
{
// This is called for the foreground tab when the browser is put to the
(void*) SetNewStorageLimit },
{ "nativeGeolocationPermissionsProvide", "(Ljava/lang/String;ZZ)V",
(void*) GeolocationPermissionsProvide },
+ { "nativeSetIsPaused", "(Z)V", (void*) SetIsPaused },
{ "nativePause", "()V", (void*) Pause },
{ "nativeResume", "()V", (void*) Resume },
{ "nativeFreeMemory", "()V", (void*) FreeMemory },
return result;
}
+void setIsScrolling(bool isScrolling)
+{
+ m_glWebViewState->setIsScrolling(isScrolling);
+}
+
bool hasCursorNode()
{
CachedRoot* root = getFrameCache(DontAllowNewer);
return false;
}
+static void nativeSetIsScrolling(JNIEnv* env, jobject jwebview, jboolean isScrolling)
+{
+ WebView* view = GET_NATIVE_VIEW(env, jwebview);
+ LOG_ASSERT(view, "view not set in %s", __FUNCTION__);
+ view->setIsScrolling(isScrolling);
+}
+
static void nativeUseHardwareAccelSkia(JNIEnv*, jobject, jboolean enabled)
{
BaseRenderer::setCurrentRendererType(enabled ? BaseRenderer::Ganesh : BaseRenderer::Raster);
(void*) nativeScrollableLayer },
{ "nativeScrollLayer", "(III)Z",
(void*) nativeScrollLayer },
+ { "nativeSetIsScrolling", "(Z)V",
+ (void*) nativeSetIsScrolling },
{ "nativeUseHardwareAccelSkia", "(Z)V",
(void*) nativeUseHardwareAccelSkia },
{ "nativeGetBackgroundColor", "()I",