OSDN Git Service

Merge "DO NOT MERGE cursor ring drawing in GL" into honeycomb-mr2
authorJohn Reck <jreck@google.com>
Thu, 12 May 2011 23:29:48 +0000 (16:29 -0700)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Thu, 12 May 2011 23:29:48 +0000 (16:29 -0700)
19 files changed:
WebCore/Android.mk
WebCore/platform/graphics/android/BaseLayerAndroid.cpp
WebCore/platform/graphics/android/BaseTile.cpp
WebCore/platform/graphics/android/BaseTile.h
WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
WebCore/platform/graphics/android/GraphicsLayerAndroid.h
WebCore/platform/graphics/android/LayerAndroid.cpp
WebCore/platform/graphics/android/LayerAndroid.h
WebCore/platform/graphics/android/PaintTileOperation.cpp [moved from WebCore/platform/graphics/android/TileSet.cpp with 50% similarity]
WebCore/platform/graphics/android/PaintTileOperation.h [moved from WebCore/platform/graphics/android/PaintTileSetOperation.h with 69% similarity]
WebCore/platform/graphics/android/QueuedOperation.h
WebCore/platform/graphics/android/TexturesGenerator.cpp
WebCore/platform/graphics/android/TexturesGenerator.h
WebCore/platform/graphics/android/TileSet.h [deleted file]
WebCore/platform/graphics/android/TiledPage.cpp
WebCore/platform/graphics/android/TiledPage.h
WebCore/platform/graphics/android/TilesManager.h
WebKit/android/jni/WebViewCore.cpp
WebKit/android/nav/WebView.cpp

index feeb56b..5bc6d83 100644 (file)
@@ -620,6 +620,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
        platform/graphics/android/MediaLayer.cpp \
        platform/graphics/android/MediaTexture.cpp \
        platform/graphics/android/PaintLayerOperation.cpp \
+       platform/graphics/android/PaintTileOperation.cpp \
        platform/graphics/android/PathAndroid.cpp \
        platform/graphics/android/PatternAndroid.cpp \
        platform/graphics/android/PlatformGraphicsContext.cpp \
@@ -630,7 +631,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
        platform/graphics/android/TexturesGenerator.cpp \
        platform/graphics/android/TilesManager.cpp \
        platform/graphics/android/TiledPage.cpp \
-       platform/graphics/android/TileSet.cpp \
        platform/graphics/android/VideoLayerAndroid.cpp \
        platform/graphics/android/android_graphics.cpp \
 
index 9607c0f..09d80a1 100644 (file)
@@ -140,8 +140,8 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
     // so that we do not slow down zooming unnecessarily.
     if (m_glWebViewState->currentScale() != scale
         && (m_glWebViewState->scaleRequestState() == GLWebViewState::kNoScaleRequest
-            || m_glWebViewState->scaleRequestState() == GLWebViewState::kWillScheduleRequest
-            || m_glWebViewState->futureScale() != scale)) {
+            || m_glWebViewState->futureScale() != scale)
+        || m_glWebViewState->scaleRequestState() == GLWebViewState::kWillScheduleRequest) {
 
         // schedule the new request
         m_glWebViewState->scheduleUpdate(currentTime, viewportTileBounds, scale);
@@ -163,13 +163,19 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
         zooming = true;
     }
 
+    // Display the current page
+    TiledPage* tiledPage = m_glWebViewState->frontPage();
+    tiledPage->setScale(m_glWebViewState->currentScale());
+
     // 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, true);
+        nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds);
+        // Cancel pending paints for the foreground page
+        TilesManager::instance()->removePaintOperationsForPage(tiledPage, false);
     }
 
     float transparency = 1;
@@ -205,9 +211,6 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
         }
     }
 
-    // Display the current page
-    TiledPage* tiledPage = m_glWebViewState->frontPage();
-    tiledPage->setScale(m_glWebViewState->currentScale());
     const SkIRect& preZoomBounds = m_glWebViewState->preZoomBounds();
 
     TiledPage* nextTiledPage = m_glWebViewState->backPage();
@@ -240,7 +243,8 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
         if (!zooming)
            m_glWebViewState->unlockBaseLayerUpdate();
 
-        tiledPage->prepare(goingDown, goingLeft, preZoomBounds, true);
+        if (!prepareNextTiledPage)
+            tiledPage->prepare(goingDown, goingLeft, preZoomBounds);
         tiledPage->draw(transparency, preZoomBounds);
     }
 
index d58c549..c74a278 100644 (file)
@@ -66,11 +66,11 @@ BaseTile::BaseTile()
     , m_texture(0)
     , m_scale(1)
     , m_dirty(true)
+    , m_repaintPending(false)
     , m_usable(true)
     , m_lastDirtyPicture(0)
     , m_fullRepaintA(true)
     , m_fullRepaintB(true)
-    , m_painting(false)
     , m_lastPaintedPicture(0)
 {
 #ifdef DEBUG_COUNT
@@ -105,8 +105,7 @@ void BaseTile::reserveTexture()
     BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this);
 
     android::AutoMutex lock(m_atomicSync);
-    if (texture && !m_painting &&
-        m_texture != texture) {
+    if (texture && m_texture != texture) {
         m_lastPaintedPicture = 0;
         fullInval();
         m_texture = texture;
@@ -118,8 +117,6 @@ bool BaseTile::removeTexture(BackedDoubleBufferedTexture* 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_painting)
-        return false;
     if (m_texture == texture)
         m_texture = 0;
     return true;
@@ -166,12 +163,31 @@ bool BaseTile::isDirty()
     return m_dirty;
 }
 
+bool BaseTile::isRepaintPending()
+{
+    android::AutoMutex lock(m_atomicSync);
+    return m_repaintPending;
+}
+
+void BaseTile::setRepaintPending(bool pending)
+{
+    android::AutoMutex lock(m_atomicSync);
+    m_repaintPending = pending;
+}
+
 void BaseTile::setUsedLevel(int usedLevel)
 {
     if (m_texture)
         m_texture->setUsedLevel(usedLevel);
 }
 
+int BaseTile::usedLevel()
+{
+    if (m_texture)
+        return m_texture->usedLevel();
+    return -1;
+}
+
 void BaseTile::draw(float transparency, SkRect& rect, float scale)
 {
     if (m_x < 0 || m_y < 0 || m_scale != scale)
@@ -261,14 +277,12 @@ void BaseTile::paintBitmap()
     bool dirty = m_dirty;
     BackedDoubleBufferedTexture* texture = m_texture;
     SkRegion dirtyArea = *m_currentDirtyArea;
-    m_painting = true;
     float scale = m_scale;
     const int x = m_x;
     const int y = m_y;
     m_atomicSync.unlock();
 
     if (!dirty || !texture) {
-        m_painting = false;
         return;
     }
 
@@ -281,7 +295,6 @@ void BaseTile::paintBitmap()
     // transferred to another BaseTile under us)
     if (texture->owner() != this || texture->usedLevel() > 1) {
         texture->producerRelease();
-        m_painting = false;
         return;
     }
 
@@ -359,40 +372,40 @@ void BaseTile::paintBitmap()
     texture->setTile(textureInfo, x, y, scale, pictureCount);
     texture->producerReleaseAndSwap();
 
-    m_lastPaintedPicture = pictureCount;
-
-    // set the fullrepaint flags
+    if (texture == m_texture) {
+        m_lastPaintedPicture = pictureCount;
 
-    if ((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA)
-        m_fullRepaintA = false;
+        // set the fullrepaint flags
 
-    if ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB)
-        m_fullRepaintB = false;
+        if ((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA)
+            m_fullRepaintA = false;
 
-    // The various checks to see if we are still dirty...
+        if ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB)
+            m_fullRepaintB = false;
 
-    m_dirty = false;
+        // The various checks to see if we are still dirty...
 
-    if (m_scale != scale)
-        m_dirty = true;
+        m_dirty = false;
 
-    if (!fullRepaint)
-        m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op);
+        if (m_scale != scale)
+            m_dirty = true;
 
-    if (!m_currentDirtyArea->isEmpty())
-        m_dirty = true;
+        if (!fullRepaint)
+            m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op);
 
-    // Now we can swap the dirty areas
+        if (!m_currentDirtyArea->isEmpty())
+            m_dirty = true;
 
-    m_currentDirtyArea = m_currentDirtyArea == &m_dirtyAreaA ? &m_dirtyAreaB : &m_dirtyAreaA;
+        // Now we can swap the dirty areas
 
-    if (!m_currentDirtyArea->isEmpty())
-        m_dirty = true;
+        m_currentDirtyArea = m_currentDirtyArea == &m_dirtyAreaA ? &m_dirtyAreaB : &m_dirtyAreaA;
 
-    if (!m_dirty)
-        m_usable = true;
+        if (!m_currentDirtyArea->isEmpty())
+            m_dirty = true;
 
-    m_painting = false;
+        if (!m_dirty)
+            m_usable = true;
+    }
 
     m_atomicSync.unlock();
 }
index b832eee..7b28f76 100644 (file)
@@ -72,6 +72,7 @@ public:
 
     void reserveTexture();
     void setUsedLevel(int);
+    int usedLevel();
     bool isTileReady();
     void draw(float transparency, SkRect& rect, float scale);
 
@@ -89,6 +90,8 @@ public:
     void markAsDirty(const unsigned int pictureCount,
                      const SkRegion& dirtyArea);
     bool isDirty();
+    bool isRepaintPending();
+    void setRepaintPending(bool pending);
     void setUsable(bool usable);
     float scale() const { return m_scale; }
     void setScale(float scale);
@@ -114,6 +117,8 @@ private:
     float m_scale;
     // used to signal that the that the tile is out-of-date and needs to be redrawn
     bool m_dirty;
+    // used to signal that a repaint is pending
+    bool m_repaintPending;
     // used to signal whether or not the draw can use this tile.
     bool m_usable;
     // stores the id of the latest picture from webkit that caused this tile to
@@ -127,7 +132,6 @@ private:
     bool m_fullRepaintA;
     bool m_fullRepaintB;
     SkRegion* m_currentDirtyArea;
-    bool m_painting;
 
     // stores the id of the latest picture painted to the tile. If the id is 0
     // then we know that the picture has not yet been painted an there is nothing
index 96cfd3d..59f8408 100644 (file)
@@ -120,6 +120,8 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
     m_needsNotifyClient(false),
     m_haveContents(false),
     m_haveImage(false),
+    m_newImage(false),
+    m_imageRef(0),
     m_foregroundLayer(0),
     m_foregroundClipLayer(0)
 {
@@ -623,6 +625,14 @@ bool GraphicsLayerAndroid::repaint()
 
         return true;
     }
+    if (m_needsRepaint && m_haveImage && m_newImage) {
+        // We need to tell the GL thread that we will need to repaint the
+        // texture. Only do so if we effectively have a new image!
+        m_contentLayer->needsRepaint();
+        m_newImage = false;
+        m_needsRepaint = false;
+        return true;
+    }
     return false;
 }
 
@@ -834,9 +844,15 @@ void GraphicsLayerAndroid::setContentsToImage(Image* image)
     if (image) {
         m_haveContents = true;
         m_haveImage = true;
-        m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
-        setNeedsDisplay();
-        askForSync();
+        // Only pass the new image if it's a different one
+        if (image->nativeImageForCurrentFrame() != m_imageRef) {
+            m_newImage = true;
+            m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
+            // remember the passed image.
+            m_imageRef = image->nativeImageForCurrentFrame();
+            setNeedsDisplay();
+            askForSync();
+        }
     }
 }
 
index da247ca..94b828b 100644 (file)
 #include "GraphicsLayerClient.h"
 #include "LayerAndroid.h"
 #include "RefPtr.h"
+#include "SkBitmapRef.h"
 #include "Vector.h"
 
 class FloatPoint3D;
 class Image;
+class SkBitmapRef;
 
 namespace WebCore {
 
@@ -142,6 +144,8 @@ private:
 
     bool m_haveContents;
     bool m_haveImage;
+    bool m_newImage;
+    SkBitmapRef* m_imageRef; // only used to remember previously passed images
 
     Vector<FloatRect> m_invalidatedRects;
 
index 78e55c1..4ba2da0 100644 (file)
@@ -92,6 +92,7 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : SkLayer(),
 LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
     m_haveClip(layer.m_haveClip),
     m_isIframe(layer.m_isIframe),
+    m_contentsImage(0),
     m_extra(0), // deliberately not copied
     m_uniqueId(layer.m_uniqueId),
     m_drawingTexture(0),
@@ -100,8 +101,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
     m_owningLayer(layer.m_owningLayer)
 {
     m_isFixed = layer.m_isFixed;
-    m_contentsImage = layer.m_contentsImage;
-    SkSafeRef(m_contentsImage);
+    copyBitmap(layer.m_contentsImage);
     m_renderLayerPos = layer.m_renderLayerPos;
     m_transform = layer.m_transform;
     m_backgroundColor = layer.m_backgroundColor;
@@ -202,7 +202,7 @@ LayerAndroid::~LayerAndroid()
     removeTexture(0);
     removeChildren();
     delete m_extra;
-    SkSafeUnref(m_contentsImage);
+    delete m_contentsImage;
     SkSafeUnref(m_recordingPicture);
     m_animations.clear();
 #ifdef DEBUG_COUNT
@@ -650,9 +650,23 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
         this->getChild(i)->updateGLPositions(localMatrix, drawClip(), opacity);
 }
 
+void LayerAndroid::copyBitmap(SkBitmap* bitmap)
+{
+    if (!bitmap)
+        return;
+
+    delete m_contentsImage;
+    m_contentsImage = new SkBitmap();
+    SkBitmap::Config config = bitmap->config();
+    int w = bitmap->width();
+    int h = bitmap->height();
+    m_contentsImage->setConfig(config, w, h);
+    bitmap->copyTo(m_contentsImage, config);
+}
+
 void LayerAndroid::setContentsImage(SkBitmapRef* img)
 {
-    SkRefCnt_SafeAssign(m_contentsImage, img);
+    copyBitmap(&img->bitmap());
 }
 
 bool LayerAndroid::needsTexture()
@@ -889,7 +903,7 @@ void LayerAndroid::createGLTextures()
              uniqueId(), this, m_dirty, m_reservedTexture,
              m_reservedTexture->rect().width(), m_reservedTexture->rect().height());
         PaintLayerOperation* operation = new PaintLayerOperation(this);
-        TilesManager::instance()->scheduleOperation(operation, !m_drawingTexture);
+        TilesManager::instance()->scheduleOperation(operation);
     } else {
         XLOG("We don't schedule a paint for layer %d (%x), because we already sent a request",
              uniqueId(), this);
@@ -930,9 +944,8 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
 
     if (m_drawingTexture) {
         TextureInfo* textureInfo = m_drawingTexture->consumerLock();
-        if (!m_drawingTexture->readyFor(this))
-            m_dirty = true;
-        if (textureInfo) {
+        bool ready = m_drawingTexture->readyFor(this);
+        if (textureInfo && (!m_contentsImage || (ready && m_contentsImage))) {
             SkRect bounds;
             bounds.set(m_drawingTexture->rect());
             XLOG("LayerAndroid %d %x (%.2f, %.2f) drawGL (texture %x, %d, %d, %d, %d)",
@@ -944,6 +957,8 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
                                                               textureInfo->m_textureId,
                                                               m_drawOpacity, true);
         }
+        if (!ready)
+            m_dirty = true;
         m_drawingTexture->consumerRelease();
     } else if (needsTexture()) {
         m_dirty = true;
@@ -1034,14 +1049,18 @@ void LayerAndroid::paintBitmapGL()
     IntRect textureRect = texture->rect();
     canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
 
-    SkPicture picture;
-    SkCanvas* nCanvas = picture.beginRecording(textureRect.width(),
-                                               textureRect.height());
-    nCanvas->scale(scale, scale);
-    nCanvas->translate(-textureRect.x(), -textureRect.y());
-    contentDraw(nCanvas);
-    picture.endRecording();
-    picture.draw(canvas);
+    if (m_contentsImage) {
+        contentDraw(canvas);
+    } else {
+        SkPicture picture;
+        SkCanvas* nCanvas = picture.beginRecording(textureRect.width(),
+                                                   textureRect.height());
+        nCanvas->scale(scale, scale);
+        nCanvas->translate(-textureRect.x(), -textureRect.y());
+        contentDraw(nCanvas);
+        picture.endRecording();
+        picture.draw(canvas);
+    }
     extraDraw(canvas);
 
     m_atomicSync.lock();
@@ -1071,7 +1090,7 @@ void LayerAndroid::contentDraw(SkCanvas* canvas)
     if (m_contentsImage) {
       SkRect dest;
       dest.set(0, 0, getSize().width(), getSize().height());
-      canvas->drawBitmapRect(m_contentsImage->bitmap(), 0, dest);
+      canvas->drawBitmapRect(*m_contentsImage, 0, dest);
     } else {
       canvas->drawPicture(*m_recordingPicture);
     }
index 0846930..e01a9a7 100644 (file)
@@ -234,6 +234,7 @@ public:
     */
     void setContentsImage(SkBitmapRef* img);
     bool hasContentsImage() { return m_contentsImage; }
+    void copyBitmap(SkBitmap*);
 
     void bounds(SkRect*) const;
 
@@ -304,7 +305,7 @@ private:
     // it is a much faster method than using m_recordingPicture.
     SkPicture* m_recordingPicture;
 
-    SkBitmapRef* m_contentsImage;
+    SkBitmap* m_contentsImage;
 
     typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap;
     KeyframesMap m_animations;
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010, The Android Open Source Project
+ * Copyright 2011, The Android Open Source Project
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  */
 
 #include "config.h"
-#include "TileSet.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "ClassTracker.h"
-#include "TilesManager.h"
-
-#ifdef DEBUG
-
-#include <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TileSet", __VA_ARGS__)
-
-#else
-
-#undef XLOG
-#define XLOG(...)
-
-#endif // DEBUG
+#include "PaintTileOperation.h"
 
 namespace WebCore {
 
-TileSet::TileSet(TiledPage* tiledPage, int rows, int cols)
-    : m_tiledPage(tiledPage)
-    , m_nbRows(rows)
-    , m_nbCols(cols)
+PaintTileOperation::PaintTileOperation(BaseTile* tile)
+    : QueuedOperation(QueuedOperation::PaintTile, tile->page())
+    , m_tile(tile)
 {
-#ifdef DEBUG_COUNT
-    ClassTracker::instance()->increment("TileSet");
-#endif
+    if (m_tile)
+        m_tile->setRepaintPending(true);
 }
 
-TileSet::~TileSet()
+PaintTileOperation::~PaintTileOperation()
 {
-#ifdef DEBUG_COUNT
-    ClassTracker::instance()->decrement("TileSet");
-#endif
+    if (m_tile) {
+        m_tile->setRepaintPending(false);
+        m_tile = 0;
+    }
 }
 
-bool TileSet::operator==(const TileSet& set)
+bool PaintTileOperation::operator==(const QueuedOperation* operation)
 {
-    return m_tiledPage == set.m_tiledPage
-           && m_nbRows == set.m_nbRows
-           && m_nbCols == set.m_nbCols;
+    if (operation->type() != type())
+        return false;
+    const PaintTileOperation* op = static_cast<const PaintTileOperation*>(operation);
+    return op->m_tile == m_tile;
 }
 
-
-void TileSet::paint()
+void PaintTileOperation::run()
 {
-    XLOG("%x, painting %d tiles", this, m_tiles.size());
-    for (unsigned int i = 0; i < m_tiles.size(); i++)
-        m_tiles[i]->paintBitmap();
-    XLOG("%x, end of painting %d tiles", this, m_tiles.size());
+    if (m_tile) {
+        m_tile->paintBitmap();
+        m_tile->setRepaintPending(false);
+        m_tile = 0;
+    }
 }
 
-} // namespace WebCore
+int PaintTileOperation::priority()
+{
+    if (!m_tile || m_tile->usedLevel() < 0)
+        return -1;
+    bool goingDown = m_tile->page()->scrollingDown();
+    SkIRect *rect = m_tile->page()->expandedTileBounds();
+    int firstTileX = rect->fLeft;
+    int nbTilesWidth = rect->width();
+    int priority = m_tile->x() - firstTileX;
+    if (goingDown)
+        priority += (rect->fBottom - m_tile->y()) * nbTilesWidth;
+    else
+        priority += (m_tile->y() - rect->fTop) * nbTilesWidth;
+    priority += m_tile->usedLevel() * 100000;
+    return priority;
+}
 
-#endif // USE(ACCELERATED_COMPOSITING)
+}
 #define PaintTileSetOperation_h
 
 #include "QueuedOperation.h"
-#include "TileSet.h"
 
 namespace WebCore {
 
-class PaintTileSetOperation : public QueuedOperation {
+class PaintTileOperation : public QueuedOperation {
  public:
-    PaintTileSetOperation(TileSet* set)
-        : QueuedOperation(QueuedOperation::PaintTileSet, set->page())
-        , m_set(set) {}
-    virtual ~PaintTileSetOperation()
-    {
-        delete m_set;
-    }
-    virtual bool operator==(const QueuedOperation* operation)
-    {
-        if (operation->type() != type())
-            return false;
-        const PaintTileSetOperation* op = static_cast<const PaintTileSetOperation*>(operation);
-        return op->m_set == m_set;
-    }
-    virtual void run()
-    {
-        if (m_set)
-            m_set->paint();
-    }
+    PaintTileOperation(BaseTile* tile);
+    virtual ~PaintTileOperation();
+    virtual bool operator==(const QueuedOperation* operation);
+    virtual void run();
+    virtual int priority();
+
  private:
-    TileSet* m_set;
+    BaseTile* m_tile;
 };
 
 }
index 089483d..98f3e2f 100644 (file)
@@ -32,13 +32,14 @@ namespace WebCore {
 
 class QueuedOperation {
  public:
-    enum OperationType { Undefined, PaintTileSet, PaintLayer, DeleteTexture };
+    enum OperationType { Undefined, PaintTile, PaintLayer, DeleteTexture };
     QueuedOperation(OperationType type, TiledPage* page)
         : m_type(type)
         , m_page(page) {}
     virtual ~QueuedOperation() {}
     virtual void run() = 0;
     virtual bool operator==(const QueuedOperation* operation) = 0;
+    virtual int priority() { return -1; }
     OperationType type() const { return m_type; }
     TiledPage* page() const { return m_page; }
  private:
@@ -65,6 +66,20 @@ class PageFilter : public OperationFilter {
     TiledPage* m_page;
 };
 
+class PagePaintFilter : public OperationFilter {
+ public:
+    PagePaintFilter(TiledPage* page) : m_page(page) {}
+    virtual bool check(QueuedOperation* operation)
+    {
+        if (operation->type() == QueuedOperation::PaintTile
+                && operation->page() == m_page)
+            return true;
+        return false;
+    }
+ private:
+    TiledPage* m_page;
+};
+
 }
 
 #endif // QueuedOperation_h
index ad5de1f..e6bef6a 100644 (file)
 
 namespace WebCore {
 
-void TexturesGenerator::scheduleOperation(QueuedOperation* operation, bool scheduleFirst)
+void TexturesGenerator::scheduleOperation(QueuedOperation* operation)
 {
     {
         android::Mutex::Autolock lock(mRequestedOperationsLock);
-        for (unsigned int i = 0; i < mRequestedOperations.size(); i++) {
-            QueuedOperation** s = &mRequestedOperations[i];
-            // A similar operation is already in the queue. The newer operation may
-            // have additional dirty tiles so delete the existing operation and
-            // replace it with the new one.
-            if (*s && *s == operation) {
-                QueuedOperation* oldOperation = *s;
-                *s = operation;
-                delete oldOperation;
-                return;
-            }
-        }
-
-        if (scheduleFirst)
-            mRequestedOperations.prepend(operation);
-        else
-            mRequestedOperations.append(operation);
+        mRequestedOperations.append(operation);
     }
     mRequestedOperationsCond.signal();
 }
@@ -81,6 +65,11 @@ void TexturesGenerator::removeOperationsForPage(TiledPage* page)
     removeOperationsForFilter(new PageFilter(page));
 }
 
+void TexturesGenerator::removePaintOperationsForPage(TiledPage* page, bool waitForRunning)
+{
+    removeOperationsForFilter(new PagePaintFilter(page), waitForRunning);
+}
+
 void TexturesGenerator::removeOperationsForBaseLayer(BaseLayerAndroid* layer)
 {
     removeOperationsForFilter(new PaintLayerBaseFilter(layer));
@@ -93,6 +82,11 @@ void TexturesGenerator::removeOperationsForTexture(LayerTexture* texture)
 
 void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
 {
+    removeOperationsForFilter(filter, true);
+}
+
+void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter, bool waitForRunning)
+{
     android::Mutex::Autolock lock(mRequestedOperationsLock);
     for (unsigned int i = 0; i < mRequestedOperations.size();) {
         QueuedOperation* operation = mRequestedOperations[i];
@@ -104,18 +98,22 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
         }
     }
 
-    QueuedOperation* operation = m_currentOperation;
-    if (operation && filter->check(operation))
-        m_waitForCompletion = true;
-
-    delete filter;
-
-    // At this point, it means that we are currently executing an operation that
-    // we want to be removed -- we should wait until it is done, so that
-    // when we return our caller can be sure that there is no more operations
-    // in the queue matching the given filter.
-    while (m_waitForCompletion)
-        mRequestedOperationsCond.wait(mRequestedOperationsLock);
+    if (waitForRunning) {
+        QueuedOperation* operation = m_currentOperation;
+        if (operation && filter->check(operation))
+            m_waitForCompletion = true;
+
+        delete filter;
+
+        // At this point, it means that we are currently executing an operation that
+        // we want to be removed -- we should wait until it is done, so that
+        // when we return our caller can be sure that there is no more operations
+        // in the queue matching the given filter.
+        while (m_waitForCompletion)
+            mRequestedOperationsCond.wait(mRequestedOperationsLock);
+    } else {
+        delete filter;
+    }
 }
 
 status_t TexturesGenerator::readyToRun()
@@ -125,6 +123,37 @@ status_t TexturesGenerator::readyToRun()
     return NO_ERROR;
 }
 
+// Must be called from within a lock!
+QueuedOperation* TexturesGenerator::popNext()
+{
+    // Priority can change between when it was added and now
+    // Hence why the entire queue is rescanned
+    QueuedOperation* current = mRequestedOperations.last();
+    int currentPriority = current->priority();
+    if (currentPriority < 0) {
+        mRequestedOperations.removeLast();
+        return current;
+    }
+    int currentIndex = mRequestedOperations.size() - 1;
+    // Scan from the back to make removing faster (less items to copy)
+    for (int i = mRequestedOperations.size() - 2; i >= 0; i--) {
+        QueuedOperation *next = mRequestedOperations[i];
+        int nextPriority = next->priority();
+        if (nextPriority < 0) {
+            // Found a very high priority item, go ahead and just handle it now
+            mRequestedOperations.remove(i);
+            return next;
+        }
+        if (nextPriority < currentPriority) {
+            current = next;
+            currentPriority = nextPriority;
+            currentIndex = i;
+        }
+    }
+    mRequestedOperations.remove(currentIndex);
+    return current;
+}
+
 bool TexturesGenerator::threadLoop()
 {
     // Check if we have any pending operations.
@@ -138,20 +167,14 @@ bool TexturesGenerator::threadLoop()
     m_currentOperation = 0;
     bool stop = false;
     while (!stop) {
-        XLOG("threadLoop evaluating the requests");
         mRequestedOperationsLock.lock();
-        if (mRequestedOperations.size()) {
-            m_currentOperation = mRequestedOperations.first();
-            mRequestedOperations.remove(0);
-            XLOG("threadLoop, popping the first request (%d requests left)",
-                 mRequestedOperations.size());
-        }
+        if (mRequestedOperations.size())
+            m_currentOperation = popNext();
         mRequestedOperationsLock.unlock();
 
         if (m_currentOperation) {
-            XLOG("threadLoop, painting the request");
+            XLOG("threadLoop, painting the request with priority %d", m_currentOperation->priority());
             m_currentOperation->run();
-            XLOG("threadLoop, painting the request - DONE");
         }
 
         mRequestedOperationsLock.lock();
@@ -168,6 +191,7 @@ bool TexturesGenerator::threadLoop()
         mRequestedOperationsLock.unlock();
 
     }
+    XLOG("threadLoop empty");
 
     return true;
 }
index 169471c..b03f52d 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "LayerTexture.h"
 #include "QueuedOperation.h"
-#include "TileSet.h"
 #include "TiledPage.h"
 #include <utils/threads.h>
 
@@ -52,11 +51,14 @@ public:
     void removeOperationsForPage(TiledPage* page);
     void removeOperationsForBaseLayer(BaseLayerAndroid* layer);
     void removeOperationsForTexture(LayerTexture* texture);
+    void removePaintOperationsForPage(TiledPage* page, bool waitForRunning);
     void removeOperationsForFilter(OperationFilter* filter);
+    void removeOperationsForFilter(OperationFilter* filter, bool waitForRunning);
 
-    void scheduleOperation(QueuedOperation* operation, bool scheduleFirst);
+    void scheduleOperation(QueuedOperation* operation);
 
 private:
+    QueuedOperation* popNext();
     virtual bool threadLoop();
     Vector<QueuedOperation*> mRequestedOperations;
     android::Mutex mRequestedOperationsLock;
diff --git a/WebCore/platform/graphics/android/TileSet.h b/WebCore/platform/graphics/android/TileSet.h
deleted file mode 100644 (file)
index aa0f2ed..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TileSet_h
-#define TileSet_h
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "BaseTile.h"
-#include "Vector.h"
-
-namespace WebCore {
-
-/**
- * This purpose of this class is to act as a container for BaseTiles that need
- * to upload their contents to the GPU.  A TiledPage creates a new TileSet and
- * provides the set with identifying characteristics of the TiledPage's current
- * state (see constructor). This information allows the consumer of the TileSet
- * to determine if an equivalent TileSet already exists in the upload pipeline.
- */
-class TileSet {
-public:
-    TileSet(TiledPage* tiledPage, int nbRows, int nbCols);
-    ~TileSet();
-
-    bool operator==(const TileSet& set);
-    void paint();
-
-    void add(BaseTile* texture)
-    {
-        m_tiles.append(texture);
-    }
-
-    TiledPage* page()
-    {
-        return m_tiledPage;
-    }
-
-    unsigned int size()
-    {
-        return m_tiles.size();
-    }
-
-private:
-    Vector<BaseTile*> m_tiles;
-
-    TiledPage* m_tiledPage;
-    int m_nbRows;
-    int m_nbCols;
-};
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
-#endif // TileSet_h
index 6f910a3..5212871 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "GLUtils.h"
 #include "IntRect.h"
-#include "PaintTileSetOperation.h"
+#include "PaintTileOperation.h"
 #include "TilesManager.h"
 
 #ifdef DEBUG
@@ -82,7 +82,6 @@ void TiledPage::updateBaseTileSize()
     int baseTileSize = TilesManager::instance()->maxTextureCount() + 1;
     if (baseTileSize > m_baseTileSize)
         m_baseTileSize = baseTileSize;
-    XLOG("Allocate %d tiles", m_baseTileSize);
 }
 
 TiledPage::~TiledPage()
@@ -126,6 +125,7 @@ void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureC
     const int lastDirtyTileX = static_cast<int>(ceilf(inval.right() * invTileContentWidth));
     const int lastDirtyTileY = static_cast<int>(ceilf(inval.bottom() * invTileContentHeight));
 
+    XLOG("Marking X %d-%d and Y %d-%d dirty", firstDirtyTileX, lastDirtyTileX, firstDirtyTileY, lastDirtyTileY);
     // We defer marking the tile as dirty until the next time we need to prepare
     // to draw.
     m_invalRegion.op(firstDirtyTileX, firstDirtyTileY, lastDirtyTileX, lastDirtyTileY, SkRegion::kUnion_Op);
@@ -133,12 +133,10 @@ void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureC
     m_latestPictureInval = pictureCount;
 }
 
-void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set)
+void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds)
 {
     if (y < 0)
         return;
-    if (!set)
-        return;
 
     for (int i = 0; i < tilesInRow; i++) {
         int x = firstTileX;
@@ -177,12 +175,41 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y
             // ensure there is a texture associated with the tile and then check to
             // see if the texture is dirty and in need of repainting
             currentTile->reserveTexture();
-            if (currentTile->isDirty())
-                set->add(currentTile);
+            updateTileUsedLevel(tileBounds, *currentTile);
+            if (currentTile->isDirty() && !currentTile->isRepaintPending()) {
+                PaintTileOperation *operation = new PaintTileOperation(currentTile);
+                TilesManager::instance()->scheduleOperation(operation);
+            } else if (currentTile->isDirty()) {
+                XLOG("Tile %dx%d is dirty, but awaiting repaint", currentTile->x(), currentTile->y());
+            }
         }
     }
 }
 
+void TiledPage::updateTileUsedLevel(const SkIRect& tileBounds, BaseTile& tile)
+{
+    const int lastTileX = tileBounds.fRight - 1;
+    const int lastTileY = tileBounds.fBottom - 1;
+
+    // set the used level of the tile (e.g. distance from the viewport)
+    int dx = 0;
+    int dy = 0;
+
+    if (tileBounds.fLeft > tile.x())
+        dx = tileBounds.fLeft - tile.x();
+    else if (lastTileX < tile.x())
+        dx = tile.x() - lastTileX;
+
+    if (tileBounds.fTop > tile.y())
+        dy = tileBounds.fTop - tile.y();
+    else if (lastTileY < tile.y())
+        dy = tile.y() - lastTileY;
+
+    int d = std::max(dx, dy);
+
+    tile.setUsedLevel(d);
+}
+
 void TiledPage::updateTileState(const SkIRect& tileBounds)
 {
     if (!m_glWebViewState || tileBounds.isEmpty()) {
@@ -191,41 +218,19 @@ void TiledPage::updateTileState(const SkIRect& tileBounds)
         return;
     }
 
-    const int nbTilesWidth = tileBounds.width() - 1;
-    const int nbTilesHeight = tileBounds.height() - 1;
-
-    const int lastTileX = tileBounds.fRight - 1;
-    const int lastTileY = tileBounds.fBottom - 1;
-
     for (int x = 0; x < m_baseTileSize; x++) {
 
         BaseTile& tile = m_baseTiles[x];
 
-        // 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, m_invalTilesRegion);
-
         // if the tile no longer has a texture then proceed to the next tile
         if (tile.isAvailable())
             continue;
 
-        // set the used level of the tile (e.g. distance from the viewport)
-        int dx = 0;
-        int dy = 0;
-
-        if (tileBounds.fLeft > tile.x())
-            dx = tileBounds.fLeft - tile.x();
-        else if (lastTileX < tile.x())
-            dx = tile.x() - lastTileX;
-
-        if (tileBounds.fTop > tile.y())
-            dy = tileBounds.fTop - tile.y();
-        else if (lastTileY < tile.y())
-            dy = tile.y() - lastTileY;
-
-        int d = std::max(dx, dy);
+        // 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, m_invalTilesRegion);
 
-        tile.setUsedLevel(d);
+        updateTileUsedLevel(tileBounds, tile);
     }
 
     // clear the invalidated region as all tiles within that region have now
@@ -234,8 +239,7 @@ void TiledPage::updateTileState(const SkIRect& tileBounds)
     m_invalTilesRegion.setEmpty();
 }
 
-void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds,
-                        bool scheduleFirst)
+void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds)
 {
     if (!m_glWebViewState)
         return;
@@ -243,6 +247,7 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
     // update the tiles distance from the viewport
     updateTileState(tileBounds);
     m_prepare = true;
+    m_scrollingDown = goingDown;
 
     int firstTileX = tileBounds.fLeft;
     int firstTileY = tileBounds.fTop;
@@ -255,43 +260,29 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
     const int baseContentHeight = m_glWebViewState->baseContentHeight();
     const int baseContentWidth = m_glWebViewState->baseContentWidth();
 
-    TileSet* set = new TileSet(this, nbTilesHeight, nbTilesWidth);
-
-    if (!scheduleFirst) {
-        // Expand number of tiles to allow tiles outside of viewport to be prepared for
-        // smoother scrolling.
-        int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
-        int nMaxTilesPerPage = m_baseTileSize / 2;
-        int expandX = TilesManager::instance()->expandedTileBoundsX();
-        int expandY = TilesManager::instance()->expandedTileBoundsY();
-        if (nTilesToPrepare + (nbTilesHeight * expandX * 2) <= nMaxTilesPerPage) {
-            firstTileX -= expandX;
-            lastTileX += expandX;
-            nbTilesWidth += expandX * 2;
-        }
-        if (nTilesToPrepare + (nbTilesWidth * expandY * 2) <= nMaxTilesPerPage) {
-            firstTileY -= expandY;
-            lastTileY += expandY;
-            nbTilesHeight += expandY * 2;
-        }
+    // Expand number of tiles to allow tiles outside of viewport to be prepared for
+    // smoother scrolling.
+    int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
+    int nMaxTilesPerPage = m_baseTileSize / 2;
+    int expandX = TilesManager::instance()->expandedTileBoundsX();
+    int expandY = TilesManager::instance()->expandedTileBoundsY();
+    if (nTilesToPrepare + (nbTilesHeight * expandX * 2) <= nMaxTilesPerPage) {
+        firstTileX -= expandX;
+        lastTileX += expandX;
+        nbTilesWidth += expandX * 2;
     }
-
-    // We chose to prepare tiles depending on the scroll direction. Tiles are
-    // appended to the list and the texture uploader goes through the list front
-    // to back. So we append tiles in reverse order because the last additions
-    // to the are processed first.
-    if (goingDown) {
-        for (int i = 0; i < nbTilesHeight; i++)
-            prepareRow(goingLeft, nbTilesWidth, firstTileX, lastTileY - i, set);
-    } else {
-        for (int i = 0; i < nbTilesHeight; i++)
-            prepareRow(goingLeft, nbTilesWidth, firstTileX, firstTileY + i, set);
+    if (nTilesToPrepare + (nbTilesWidth * expandY * 2) <= nMaxTilesPerPage) {
+        firstTileY -= expandY;
+        lastTileY += expandY;
+        nbTilesHeight += expandY * 2;
     }
+    m_expandedTileBounds.fLeft = firstTileX;
+    m_expandedTileBounds.fTop = firstTileY;
+    m_expandedTileBounds.fRight = lastTileX;
+    m_expandedTileBounds.fBottom = lastTileY;
 
-    // The paint operation will take ownership of the tileSet here, so no delete
-    // is necessary.
-    PaintTileSetOperation* operation = new PaintTileSetOperation(set);
-    TilesManager::instance()->scheduleOperation(operation, scheduleFirst);
+    for (int i = 0; i < nbTilesHeight; i++)
+        prepareRow(goingLeft, nbTilesWidth, firstTileX, firstTileY + i, tileBounds);
 }
 
 bool TiledPage::ready(const SkIRect& tileBounds, float scale)
@@ -330,7 +321,6 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds)
     actualTileBounds.fLeft -= TilesManager::instance()->expandedTileBoundsX();
     actualTileBounds.fRight += TilesManager::instance()->expandedTileBoundsX();
 
-    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 (actualTileBounds.contains(tile.x(), tile.y())) {
@@ -344,11 +334,6 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds)
             tile.draw(transparency, rect, m_scale);
         }
     }
-
-#ifdef DEBUG
-    XLOG("FINISHED WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
-    TilesManager::instance()->printTextures();
-#endif // DEBUG
 }
 
 unsigned int TiledPage::paintBaseLayerContent(SkCanvas* canvas)
index 7e0bb2e..1aa3e61 100644 (file)
@@ -31,7 +31,6 @@
 #include "BaseTile.h"
 #include "SkCanvas.h"
 #include "SkRegion.h"
-#include "TileSet.h"
 
 namespace WebCore {
 
@@ -57,8 +56,7 @@ public:
     TiledPage* sibling();
 
     // prepare the page for display on the screen
-    void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds,
-                 bool scheduleFirst = false);
+    void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds);
     // check to see if the page is ready for display
     bool ready(const SkIRect& tileBounds, float scale);
     // draw the page on the screen
@@ -75,10 +73,13 @@ public:
     void invalidateRect(const IntRect& invalRect, const unsigned int pictureCount);
     void setUsable(bool usable);
     void updateBaseTileSize();
+    bool scrollingDown() { return m_scrollingDown; }
+    SkIRect* expandedTileBounds() { return &m_expandedTileBounds; }
 
 private:
     void updateTileState(const SkIRect& tileBounds);
-    void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set);
+    void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds);
+    void updateTileUsedLevel(const SkIRect& tileBounds, BaseTile& tile);
 
     BaseTile* getBaseTile(int x, int y) const;
 
@@ -103,6 +104,8 @@ private:
     SkRegion m_invalTilesRegion;
     unsigned int m_latestPictureInval;
     bool m_prepare;
+    bool m_scrollingDown;
+    SkIRect m_expandedTileBounds;
 };
 
 } // namespace WebCore
index 5a4e28a..6d49cca 100644 (file)
@@ -39,8 +39,6 @@
 
 namespace WebCore {
 
-class TileSet;
-
 class TilesManager {
 public:
     static TilesManager* instance();
@@ -57,6 +55,11 @@ public:
         m_pixmapsGenerationThread->removeOperationsForPage(page);
     }
 
+    void removePaintOperationsForPage(TiledPage* page, bool waitForCompletion)
+    {
+        m_pixmapsGenerationThread->removePaintOperationsForPage(page, waitForCompletion);
+    }
+
     void removeOperationsForBaseLayer(BaseLayerAndroid* layer)
     {
         m_pixmapsGenerationThread->removeOperationsForBaseLayer(layer);
@@ -67,9 +70,9 @@ public:
         m_pixmapsGenerationThread->removeOperationsForTexture(texture);
     }
 
-    void scheduleOperation(QueuedOperation* operation, bool scheduleFirst = false)
+    void scheduleOperation(QueuedOperation* operation)
     {
-        m_pixmapsGenerationThread->scheduleOperation(operation, scheduleFirst);
+        m_pixmapsGenerationThread->scheduleOperation(operation);
     }
 
     ShaderProgram* shader() { return &m_shader; }
index c038ccd..1d9c26b 100644 (file)
@@ -569,6 +569,11 @@ void WebViewCore::recordPictureSet(PictureSet* content)
         DBG_SET_LOG("!m_mainFrame->document()");
         return;
     }
+    // If there is a pending style recalculation, just return.
+    if (m_mainFrame->document()->isPendingStyleRecalc()) {
+        LOGW("recordPictureSet: pending style recalc, ignoring.");
+        return;
+    }
     if (m_addInval.isEmpty()) {
         DBG_SET_LOG("m_addInval.isEmpty()");
         return;
@@ -1116,9 +1121,7 @@ void WebViewCore::requestKeyboard(bool showKeyboard)
 
 void WebViewCore::notifyProgressFinished()
 {
-    DBG_NAV_LOG("call updateFrameCache");
     m_check_domtree_version = true;
-    updateFrameCache();
     sendNotifyProgressFinished();
 }
 
@@ -1515,6 +1518,18 @@ void WebViewCore::updateFrameCache()
         DBG_NAV_LOG("!m_frameCacheOutOfDate");
         return;
     }
+
+    // If there is a pending style recalculation, do not update the frame cache.
+    // Until the recalculation is complete, there may be internal objects that
+    // are in an inconsistent state (such as font pointers).
+    // In any event, there's not much point to updating the cache while a style
+    // recalculation is pending, since it will simply have to be updated again
+    // once the recalculation is complete.
+    // TODO: Do we need to reschedule an update for after the style is recalculated?
+    if (m_mainFrame && m_mainFrame->document() && m_mainFrame->document()->isPendingStyleRecalc()) {
+        LOGW("updateFrameCache: pending style recalc, ignoring.");
+        return;
+    }
 #ifdef ANDROID_INSTRUMENT
     TimeCounterAuto counter(TimeCounter::WebViewCoreBuildNavTimeCounter);
 #endif
index 6816611..f29d218 100644 (file)
@@ -326,14 +326,6 @@ void scrollRectOnScreen(const IntRect& rect)
         return;
     SkRect visible;
     calcOurContentVisibleRect(&visible);
-#if USE(ACCELERATED_COMPOSITING)
-    LayerAndroid* root = compositeRoot();
-    if (root) {
-        root->updateFixedLayersPositions(visible);
-        root->updatePositions();
-        visible = root->subtractLayers(visible);
-    }
-#endif
     int dx = 0;
     int left = rect.x();
     int right = rect.right();