OSDN Git Service

Merge "Fix (or partial fix) for 3355185, crash on broken-ideograph-small-caps.html...
authorRussell Brenner <russellbrenner@google.com>
Wed, 19 Jan 2011 18:04:09 +0000 (10:04 -0800)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Wed, 19 Jan 2011 18:04:09 +0000 (10:04 -0800)
29 files changed:
WebCore/page/FrameView.cpp
WebCore/page/FrameView.h
WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
WebCore/platform/graphics/android/BaseLayerAndroid.cpp
WebCore/platform/graphics/android/BaseTile.cpp
WebCore/platform/graphics/android/BaseTile.h
WebCore/platform/graphics/android/GLWebViewState.cpp
WebCore/platform/graphics/android/GLWebViewState.h
WebCore/platform/graphics/android/LayerAndroid.cpp
WebCore/platform/graphics/android/LayerAndroid.h
WebCore/platform/graphics/android/LayerTexture.h
WebCore/platform/graphics/android/PaintLayerOperation.cpp
WebCore/platform/graphics/android/PaintLayerOperation.h
WebCore/platform/graphics/android/ShaderProgram.cpp
WebCore/platform/graphics/android/ShaderProgram.h
WebCore/platform/graphics/android/TextureOwner.h
WebCore/platform/graphics/android/TexturesGenerator.cpp
WebCore/platform/graphics/android/TexturesGenerator.h
WebCore/platform/graphics/android/TilesManager.cpp
WebCore/platform/graphics/android/TilesManager.h
WebCore/rendering/RenderIFrame.cpp
WebCore/rendering/RenderLayerCompositor.cpp
WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp
WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
WebKit/android/WebCoreSupport/autofill/FormManagerAndroid.cpp
WebKit/android/jni/WebViewCore.cpp
WebKit/android/nav/WebView.cpp

index 3154a67..5314a32 100644 (file)
@@ -143,6 +143,9 @@ FrameView::FrameView(Frame* frame)
     , m_deferSetNeedsLayouts(0)
     , m_setNeedsLayoutWasDeferred(false)
     , m_scrollCorner(0)
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+    , m_hasOverflowScroll(false)
+#endif
 {
     init();
 }
@@ -553,11 +556,6 @@ void FrameView::updateCompositingLayers()
     RenderView* view = m_frame->contentRenderer();
     if (!view)
         return;
-#if ENABLE(ANDROID_OVERFLOW_SCROLL)
-    // Enter compositing mode for child frames that have layout dimensions.
-    if (hasOverflowScroll())
-        enterCompositingMode();
-#endif
 
     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
     view->compositor()->cacheAcceleratedCompositingFlags();
@@ -571,31 +569,6 @@ void FrameView::setNeedsOneShotDrawingSynchronization()
         page->chrome()->client()->setNeedsOneShotDrawingSynchronization();
 }
 
-#if ENABLE(ANDROID_OVERFLOW_SCROLL)
-bool FrameView::hasOverflowScroll() const
-{
-#ifndef ANDROID_FLATTEN_IFRAME
-    RenderObject* ownerRenderer = m_frame->ownerRenderer();
-    if (!ownerRenderer || !ownerRenderer->isRenderIFrame())
-        return false;
-    RenderLayer* layer = ownerRenderer->enclosingLayer();
-    // Make sure the layer has visible content or descendants.
-    if (!layer->hasVisibleContent() && !layer->hasVisibleDescendant())
-        return false;
-    // If either layout dimension is 0, return false.
-    if (!layoutWidth() || !layoutHeight())
-        return false;
-    ScrollbarMode h, v;
-    scrollbarModes(h, v);
-    if (h == ScrollbarAlwaysOff || v == ScrollbarAlwaysOff)
-        return false;
-    if (contentsWidth() <= layoutWidth() && contentsHeight() <= layoutHeight())
-        return false;
-    return true;
-#endif
-    return false;
-}
-#endif
 #endif // USE(ACCELERATED_COMPOSITING)
 
 bool FrameView::hasCompositedContent() const
@@ -955,6 +928,30 @@ void FrameView::layout(bool allowSubtree)
     InspectorInstrumentation::didLayout(cookie);
 
     m_nestedLayoutCount--;
+#if ENABLE(ANDROID_OVERFLOW_SCROLL) && !defined(ANDROID_FLATTEN_IFRAME)
+    // Reset to false each time we layout in case the overflow status changed.
+    bool hasOverflowScroll = false;
+    RenderObject* ownerRenderer = m_frame->ownerRenderer();
+    if (ownerRenderer && ownerRenderer->isRenderIFrame()) {
+        RenderLayer* layer = ownerRenderer->enclosingLayer();
+        if (layer) {
+            // Some sites use tiny iframes for loading so don't composite those.
+            if (canHaveScrollbars() && layoutWidth() > 1 && layoutHeight() > 1)
+                hasOverflowScroll = layoutWidth() < contentsWidth() || layoutHeight() < contentsHeight();
+        }
+    }
+    if (RenderView* view = m_frame->contentRenderer()) {
+        if (hasOverflowScroll != m_hasOverflowScroll) {
+            if (hasOverflowScroll)
+                enterCompositingMode();
+            else
+                // We are leaving overflow mode so we need to update the layer
+                // tree in case that is the reason we were composited.
+                view->compositor()->scheduleCompositingLayerUpdate();
+        }
+    }
+    m_hasOverflowScroll = hasOverflowScroll;
+#endif
 }
 
 void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
index d56b1ef..1b5b322 100644 (file)
@@ -103,9 +103,9 @@ public:
     // Called when changes to the GraphicsLayer hierarchy have to be synchronized with
     // content rendered via the normal painting path.
     void setNeedsOneShotDrawingSynchronization();
-#if ENABLE(ANDROID_OVERFLOW_SCROLL)
-    bool hasOverflowScroll() const;
 #endif
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+    bool hasOverflowScroll() const { return m_hasOverflowScroll; }
 #endif
 
     bool hasCompositedContent() const;
@@ -390,6 +390,9 @@ private:
     static double s_initialDeferredRepaintDelayDuringLoading;
     static double s_maxDeferredRepaintDelayDuringLoading;
     static double s_deferredRepaintDelayIncrementDuringLoading;
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+    bool m_hasOverflowScroll;
+#endif
 };
 
 } // namespace WebCore
index 12e0436..3462975 100644 (file)
@@ -98,6 +98,12 @@ void BackedDoubleBufferedTexture::producerReleaseAndSwap()
     m_busy = false;
 }
 
+bool BackedDoubleBufferedTexture::busy()
+{
+    android::Mutex::Autolock lock(m_busyLock);
+    return m_busy;
+}
+
 void BackedDoubleBufferedTexture::producerUpdate(TextureInfo* textureInfo)
 {
     // no need to upload a texture since the bitmap is empty
@@ -132,7 +138,7 @@ bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner)
     android::Mutex::Autolock lock(m_busyLock);
     if (!m_busy) {
         if (m_owner)
-            m_owner->removeTexture();
+            m_owner->removeTexture(this);
         m_owner = owner;
         return true;
     }
index 844715d..0b62224 100644 (file)
@@ -76,8 +76,7 @@ public:
     TextureOwner* owner() { return m_owner; } // only used by the consumer thread
     SkCanvas* canvas() { return m_canvas; } // only used by the producer thread
 
-    // This is to be only used for debugging on the producer thread
-    bool busy() { return m_busy; }
+    bool busy();
 
     const SkSize& getSize() const { return m_size; }
 
index b84831d..9ed967f 100644 (file)
@@ -272,11 +272,23 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect,
 #ifdef DEBUG
         TilesManager::instance()->printLayersTextures("reserve");
 #endif
+        // Get the current scale; if we are zooming, we don't change the scale
+        // factor immediately (see BaseLayerAndroid::drawBasePictureInGL()), but
+        // we change the scaleRequestState. When the state is kReceivedNewScale
+        // we can use the future scale instead of the current scale to request
+        // new textures. After a transition time, the scaleRequestState will be
+        // reset and the current scale will be set to the future scale.
+        float scale = m_glWebViewState->currentScale();
+        if (m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale) {
+            scale = m_glWebViewState->futureScale();
+        }
+        compositedRoot->setScale(scale);
         compositedRoot->reserveGLTextures();
-        // Now that we marked the textures being used, we delete the unnecessary
-        // ones to make space...
-        TilesManager::instance()->cleanupLayersTextures();
-        // Finally do another pass to create new textures if needed
+        // Now that we marked the textures being used, we delete
+        // the unnecessary ones to make space...
+        TilesManager::instance()->cleanupLayersTextures(compositedRoot);
+        // Finally do another pass to create new textures and schedule
+        // repaints if needed
         compositedRoot->createGLTextures();
 
         if (compositedRoot->drawGL(matrix))
index a506ac9..35de698 100644 (file)
@@ -115,12 +115,13 @@ void BaseTile::reserveTexture()
     m_texture = texture;
 }
 
-void BaseTile::removeTexture()
+void BaseTile::removeTexture(BackedDoubleBufferedTexture* texture)
 {
     XLOG("%x removeTexture res: %x...", this, m_texture);
     // We update atomically, so paintBitmap() can see the correct value
     android::AutoMutex lock(m_atomicSync);
-    m_texture = 0;
+    if (m_texture == texture)
+        m_texture = 0;
 }
 
 void BaseTile::setScale(float scale)
index f6ffe38..a7eae23 100644 (file)
@@ -90,7 +90,7 @@ public:
     BackedDoubleBufferedTexture* texture() { return m_texture; }
 
     // TextureOwner implementation
-    virtual void removeTexture();
+    virtual void removeTexture(BackedDoubleBufferedTexture* texture);
     virtual TiledPage* page() { return m_page; }
 
 private:
index 1c32848..45915e5 100644 (file)
@@ -63,7 +63,7 @@ int GLWebViewState::count()
 }
 #endif
 
-GLWebViewState::GLWebViewState()
+GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
     : m_scaleRequestState(kNoScaleRequest)
     , m_currentScale(1)
     , m_futureScale(1)
@@ -72,6 +72,7 @@ GLWebViewState::GLWebViewState()
     , m_baseLayer(0)
     , m_currentPictureCounter(0)
     , m_usePageA(true)
+    , m_globalButtonMutex(buttonMutex)
 {
     m_viewport.setEmpty();
     m_futureViewportTileBounds.setEmpty();
@@ -135,8 +136,11 @@ void GLWebViewState::inval(const IntRect& rect)
 unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
 {
     android::Mutex::Autolock lock(m_baseLayerLock);
-    if (m_baseLayer)
+    if (m_baseLayer) {
+        m_globalButtonMutex->lock();
         m_baseLayer->drawCanvas(canvas);
+        m_globalButtonMutex->unlock();
+    }
     return m_currentPictureCounter;
 }
 
index c627a6e..8d2216e 100644 (file)
@@ -152,7 +152,7 @@ public:
     };
     typedef int32_t GLScaleState;
 
-    GLWebViewState();
+    GLWebViewState(android::Mutex* globalButtonMutex);
     ~GLWebViewState();
     GLScaleState scaleRequestState() const { return m_scaleRequestState; }
     void setScaleRequestState(GLScaleState state) { m_scaleRequestState = state; }
@@ -222,6 +222,7 @@ private:
     TiledPage* m_tiledPageA;
     TiledPage* m_tiledPageB;
     SkIRect m_lastInval;
+    android::Mutex* m_globalButtonMutex;
 };
 
 } // namespace WebCore
index aec039d..95d4ff4 100644 (file)
@@ -75,8 +75,10 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(),
     m_contentsImage(0),
     m_extra(0),
     m_uniqueId(++gUniqueId),
-    m_texture(0),
-    m_pictureUsed(0)
+    m_drawingTexture(0),
+    m_reservedTexture(0),
+    m_pictureUsed(0),
+    m_scale(1)
 {
     m_backgroundColor = 0;
 
@@ -91,7 +93,8 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
     m_haveClip(layer.m_haveClip),
     m_extra(0), // deliberately not copied
     m_uniqueId(layer.m_uniqueId),
-    m_texture(0)
+    m_drawingTexture(0),
+    m_reservedTexture(0)
 {
     m_isFixed = layer.m_isFixed;
     m_contentsImage = layer.m_contentsImage;
@@ -119,6 +122,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
     m_childrenTransform = layer.m_childrenTransform;
     m_dirty = layer.m_dirty;
     m_pictureUsed = layer.m_pictureUsed;
+    m_scale = layer.m_scale;
 
     for (int i = 0; i < layer.countChildren(); i++)
         addChild(layer.getChild(i)->copy())->unref();
@@ -138,7 +142,9 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(),
     m_contentsImage(0),
     m_extra(0),
     m_uniqueId(-1),
-    m_texture(0)
+    m_drawingTexture(0),
+    m_reservedTexture(0),
+    m_scale(1)
 {
     m_backgroundColor = 0;
     m_dirty = false;
@@ -146,10 +152,33 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(),
     gDebugLayerAndroidInstances++;
 }
 
+void LayerAndroid::removeTexture(BackedDoubleBufferedTexture* aTexture)
+{
+    LayerTexture* texture = static_cast<LayerTexture*>(aTexture);
+    android::AutoMutex lock(m_atomicSync);
+    if (!texture) { // remove ourself from both textures
+        if (m_drawingTexture)
+            m_drawingTexture->release(this);
+        if (m_reservedTexture &&
+            m_reservedTexture != m_drawingTexture)
+            m_reservedTexture->release(this);
+    } else {
+        if (m_drawingTexture && m_drawingTexture == texture)
+            m_drawingTexture->release(this);
+        if (m_reservedTexture &&
+            m_reservedTexture == texture &&
+            m_reservedTexture != m_drawingTexture)
+            m_reservedTexture->release(this);
+    }
+    if (m_drawingTexture && m_drawingTexture->owner() != this)
+        m_drawingTexture = 0;
+    if (m_reservedTexture && m_reservedTexture->owner() != this)
+        m_reservedTexture = 0;
+}
+
 LayerAndroid::~LayerAndroid()
 {
-    if (m_texture)
-        m_texture->release(this);
+    removeTexture(0);
     removeChildren();
     m_contentsImage->safeUnref();
     m_recordingPicture->safeUnref();
@@ -521,6 +550,7 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
         localMatrix.setM34(0);
         localMatrix.setM43(0);
     }
+
     // now apply it to our children
 
     if (!m_childrenTransform.isIdentity()) {
@@ -549,12 +579,31 @@ void LayerAndroid::reserveGLTextures()
     for (int i = 0; i < count; i++)
         this->getChild(i)->reserveGLTextures();
 
+    LayerTexture* reservedTexture = 0;
     if (needsTexture()) {
-        LayerTexture* texture;
-        texture = TilesManager::instance()->getExistingTextureForLayer(this);
-        // SMP flush
-        android::AutoMutex lock(m_atomicSync);
-        m_texture = texture;
+        // Compute the layer size & position we need (clipped to the viewport)
+        IntRect r(0, 0, getWidth(), getHeight());
+        IntRect tr = drawTransform().mapRect(r);
+        IntRect cr = TilesManager::instance()->shader()->clippedRectWithViewport(tr);
+        m_layerTextureRect = drawTransform().inverse().mapRect(cr);
+
+        reservedTexture = TilesManager::instance()->getExistingTextureForLayer(this, m_layerTextureRect);
+
+        // If we do not have a drawing texture (i.e. new LayerAndroid tree),
+        // we get any one available.
+        if (!m_drawingTexture)
+            m_drawingTexture = TilesManager::instance()->getExistingTextureForLayer(this, m_layerTextureRect, true);
+    }
+
+    // SMP flush
+    android::AutoMutex lock(m_atomicSync);
+    // we set the reservedTexture if it's different from the drawing texture
+    if (m_reservedTexture != reservedTexture &&
+        ((m_reservedTexture != m_drawingTexture) ||
+         (m_reservedTexture == 0 && m_drawingTexture == 0))) {
+        if (m_reservedTexture)
+            m_reservedTexture->release(this);
+        m_reservedTexture = reservedTexture;
     }
 }
 
@@ -564,46 +613,56 @@ void LayerAndroid::createGLTextures()
     for (int i = 0; i < count; i++)
         this->getChild(i)->createGLTextures();
 
-    if (needsTexture() && !m_texture) {
-        LayerTexture* texture;
-        texture = TilesManager::instance()->createTextureForLayer(this);
-        // SMP flush + keep dirty bit in sync
-        android::AutoMutex lock(m_atomicSync);
-        m_texture = texture;
-        m_dirty = true;
+    if (!needsTexture())
+        return;
+
+    LayerTexture* reservedTexture = m_reservedTexture;
+    if (!reservedTexture)
+        reservedTexture = TilesManager::instance()->createTextureForLayer(this, m_layerTextureRect);
+
+    if (!reservedTexture)
+        return;
+
+    // SMP flush
+    m_atomicSync.lock();
+    m_reservedTexture = reservedTexture;
+    m_atomicSync.unlock();
+
+    if (reservedTexture &&
+        (reservedTexture != m_drawingTexture) &&
+         reservedTexture->isReady()) {
+        if (m_drawingTexture) {
+            TilesManager::instance()->removeOperationsForTexture(m_drawingTexture);
+            m_drawingTexture->release(this);
+        }
+        m_drawingTexture = reservedTexture;
     }
 
-    checkForObsolescence();
+    if (!needsScheduleRepaint(reservedTexture))
+        return;
+
+    XLOG("We schedule a paint for layer %d, because isReady %d or m_dirty %d, using texture %x",
+         uniqueId(), m_reservedTexture->isReady(), m_dirty, m_reservedTexture);
+    PaintLayerOperation* operation = new PaintLayerOperation(this);
+    TilesManager::instance()->scheduleOperation(operation);
 }
 
-void LayerAndroid::checkForObsolescence()
+bool LayerAndroid::needsScheduleRepaint(LayerTexture* texture)
 {
-    m_atomicSync.lock();
-    if (!m_texture) {
-        m_atomicSync.unlock();
-        return;
-    }
+    if (!texture)
+        return false;
 
-    if (!m_pictureUsed || m_texture->pictureUsed() != m_pictureUsed) {
+    if (!m_pictureUsed || texture->pictureUsed() != m_pictureUsed) {
         XLOG("We mark layer %d as dirty because: m_pictureUsed(%d == 0?), texture picture used %x",
-             uniqueId(), m_pictureUsed, m_texture->pictureUsed());
-        m_texture->setPictureUsed(m_pictureUsed);
+             uniqueId(), m_pictureUsed, texture->pictureUsed());
+        texture->setPictureUsed(m_pictureUsed);
         m_dirty = true;
     }
 
-    if (!m_texture->isReady())
+    if (!texture->isReady())
         m_dirty = true;
 
-    bool dirty = m_dirty;
-    m_atomicSync.unlock();
-
-    if (!dirty)
-        return;
-
-    XLOG("We schedule a paint for layer %d, because isReady %d or m_dirty %d",
-         uniqueId(), m_texture->isReady(), m_dirty);
-    PaintLayerOperation* operation = new PaintLayerOperation(this);
-    TilesManager::instance()->scheduleOperation(operation);
+    return m_dirty;
 }
 
 static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b)
@@ -621,14 +680,20 @@ bool LayerAndroid::drawGL(SkMatrix& matrix)
 
     TilesManager::instance()->shader()->clip(m_clippingRect);
 
-    if (prepareContext() && m_texture) {
-        TextureInfo* textureInfo = m_texture->consumerLock();
-        if (textureInfo && m_texture->isReady()) {
-            TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), rect,
+    if (prepareContext() && m_drawingTexture) {
+        TextureInfo* textureInfo = m_drawingTexture->consumerLock();
+        if (textureInfo && m_drawingTexture->isReady()) {
+            SkRect bounds;
+            IntRect textureRect = m_drawingTexture->rect();
+            bounds.set(0, 0, textureRect.width(), textureRect.height());
+            // move the drawing depending on where the texture is on the layer
+            TransformationMatrix m = drawTransform();
+            m.translate(textureRect.x(), textureRect.y());
+            TilesManager::instance()->shader()->drawLayerQuad(m, bounds,
                                                               textureInfo->m_textureId,
                                                               m_drawOpacity);
         }
-        m_texture->consumerRelease();
+        m_drawingTexture->consumerRelease();
     }
 
     // When the layer is dirty, the UI thread should be notified to redraw.
@@ -660,24 +725,43 @@ bool LayerAndroid::drawChildrenGL(SkMatrix& matrix)
     return askPaint;
 }
 
+void LayerAndroid::setScale(float scale)
+{
+    int count = this->countChildren();
+    for (int i = 0; i < count; i++)
+        this->getChild(i)->setScale(scale);
+
+    android::AutoMutex lock(m_atomicSync);
+    m_scale = scale;
+}
+
 // This is called from the texture generation thread
 void LayerAndroid::paintBitmapGL()
 {
-    XLOG("LayerAndroid paintBitmapGL (layer %d)", uniqueId());
     // We acquire the values below atomically. This ensures that we are reading
     // values correctly across cores. Further, once we have these values they
     // can be updated by other threads without consequence.
     m_atomicSync.lock();
-    LayerTexture* texture = m_texture;
-    m_atomicSync.unlock();
+    LayerTexture* texture = m_reservedTexture;
 
     if (!texture) {
+        m_atomicSync.unlock();
         XLOG("Layer %d doesn't have a texture!", uniqueId());
         return;
     }
 
+    XLOG("LayerAndroid paintBitmapGL (layer %d), texture used %x", uniqueId(), texture);
+
+    // We need to mark the texture as busy before relinquishing the lock
+    // -- so that TilesManager::cleanupLayersTextures() can check if the texture
+    // is used before trying to destroy it
+    // If LayerAndroid::removeTexture() is called before us, we'd have bailed
+    // out early as texture would have been null; if it is called after us, we'd
+    // have marked the texture has being busy, and the texture will not be
+    // destroy immediately.
     texture->producerAcquireContext();
     TextureInfo* textureInfo = texture->producerLock();
+    m_atomicSync.unlock();
 
     // at this point we can safely check the ownership (if the texture got
     // transferred to another BaseTile under us)
@@ -688,9 +772,16 @@ void LayerAndroid::paintBitmapGL()
 
     XLOG("LayerAndroid %d paintBitmapGL WE ARE PAINTING", uniqueId());
     SkCanvas* canvas = texture->canvas();
+    float scale = texture->scale();
+
+    IntRect textureRect = texture->rect();
 
+    canvas->save();
     canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+    canvas->scale(scale, scale);
+    canvas->translate(-textureRect.x(), -textureRect.y());
     contentDraw(canvas);
+    canvas->restore();
 
     XLOG("LayerAndroid %d paintBitmapGL PAINTING DONE, updating the texture", uniqueId());
     m_atomicSync.lock();
index 76b4cb8..95f8547 100644 (file)
@@ -94,11 +94,9 @@ public:
     virtual ~LayerAndroid();
 
     // TextureOwner methods
-    virtual void removeTexture()
-    {
-        android::AutoMutex lock(m_atomicSync);
-        m_texture = 0;
-    }
+    virtual void removeTexture(BackedDoubleBufferedTexture* texture);
+
+    LayerTexture* texture() { return m_reservedTexture; }
     virtual TiledPage* page() { return 0; }
 
     static int instancesCount();
@@ -111,8 +109,10 @@ public:
     void createGLTextures();
 
     virtual bool needsTexture();
-    void checkForObsolescence();
+    bool needsScheduleRepaint(LayerTexture* texture);
 
+    void setScale(float scale);
+    float getScale() { return m_scale; }
     virtual bool drawGL(SkMatrix&);
     bool drawChildrenGL(SkMatrix&);
     virtual void paintBitmapGL();
@@ -285,12 +285,24 @@ private:
     DrawExtra* m_extra;
     int m_uniqueId;
 
-    // GL textures management
-    LayerTexture* m_texture;
+    // We have two textures pointers -- one if the texture we are currently
+    // using to draw (m_drawingTexture), the other one is the one we get
+    // from trying to reserve a texture from the TilesManager. Usually, they
+    // are identical, but in some cases they are not (different scaling
+    // resulting in the need for different geometry, at initilisation, and
+    // if the texture asked does not fit in memory)
+    LayerTexture* m_drawingTexture;
+    LayerTexture* m_reservedTexture;
+
+    // rect used to query TilesManager for the right texture
+    IntRect m_layerTextureRect;
+
     // used to signal that the tile is out-of-date and needs to be redrawn
     bool m_dirty;
     unsigned int m_pictureUsed;
 
+    float m_scale;
+
     // This mutex serves two purposes. (1) It ensures that certain operations
     // happen atomically and (2) it makes sure those operations are synchronized
     // across all threads and cores.
index 959978f..3654476 100644 (file)
@@ -27,6 +27,7 @@
 #define LayerTexture_h
 
 #include "BackedDoubleBufferedTexture.h"
+#include "IntRect.h"
 
 namespace WebCore {
 
@@ -36,9 +37,11 @@ class LayerTexture : public BackedDoubleBufferedTexture {
                  SkBitmap::Config config = SkBitmap::kARGB_8888_Config)
         : BackedDoubleBufferedTexture(w, h, config)
         , m_id(0)
+        , m_scale(1)
         , m_pictureUsed(0)
         , m_textureUpdates(0)
     {}
+    virtual ~LayerTexture() {};
 
     int id() { return m_id; }
     void setId(int id) { m_id = id; }
@@ -47,11 +50,17 @@ class LayerTexture : public BackedDoubleBufferedTexture {
     void setPictureUsed(unsigned pictureUsed) { m_pictureUsed = pictureUsed; }
     bool isReady();
     virtual void producerUpdate(TextureInfo* textureInfo);
+    void setRect(const IntRect& r) { m_rect = r; }
+    IntRect& rect() { return m_rect; }
+    float scale() { return m_scale; }
+    void setScale(float scale) { m_scale = scale; }
 
  private:
     void update();
 
     int m_id;
+    IntRect m_rect;
+    float m_scale;
     unsigned int m_pictureUsed;
     unsigned int m_textureUpdates;
 };
index a3ef148..dd81d9a 100644 (file)
@@ -50,7 +50,14 @@ SkLayer* PaintLayerOperation::baseLayer()
     return m_layer->getRootLayer();
 }
 
-bool PaintLayerFilter::check(QueuedOperation* operation)
+LayerTexture* PaintLayerOperation::texture()
+{
+    if (!m_layer)
+        return 0;
+    return m_layer->texture();
+}
+
+bool PaintLayerBaseFilter::check(QueuedOperation* operation)
 {
     if (operation->type() == QueuedOperation::PaintLayer) {
         PaintLayerOperation* op = static_cast<PaintLayerOperation*>(operation);
@@ -59,3 +66,13 @@ bool PaintLayerFilter::check(QueuedOperation* operation)
     }
     return false;
 }
+
+bool PaintLayerTextureFilter::check(QueuedOperation* operation)
+{
+    if (operation->type() == QueuedOperation::PaintLayer) {
+        PaintLayerOperation* op = static_cast<PaintLayerOperation*>(operation);
+        if (op->texture() == m_texture)
+            return true;
+    }
+    return false;
+}
index d393ac5..74e87af 100644 (file)
@@ -33,6 +33,7 @@ class SkLayer;
 namespace WebCore {
 
 class LayerAndroid;
+class LayerTexture;
 
 class PaintLayerOperation : public QueuedOperation {
  public:
@@ -43,20 +44,31 @@ class PaintLayerOperation : public QueuedOperation {
     virtual bool operator==(const QueuedOperation* operation);
     virtual void run();
     SkLayer* baseLayer();
+    LayerAndroid* layer() { return m_layer; }
+    LayerTexture* texture();
 
  private:
     LayerAndroid* m_layer;
 };
 
-class PaintLayerFilter : public OperationFilter {
+class PaintLayerBaseFilter : public OperationFilter {
  public:
-    PaintLayerFilter(SkLayer* layer) : m_baseLayer(layer) {}
+    PaintLayerBaseFilter(SkLayer* layer) : m_baseLayer(layer) {}
     virtual bool check(QueuedOperation* operation);
 
  private:
     SkLayer* m_baseLayer;
 };
 
+class PaintLayerTextureFilter : public OperationFilter {
+ public:
+    PaintLayerTextureFilter(LayerTexture* texture) : m_texture(texture) {}
+    virtual bool check(QueuedOperation* operation);
+
+ private:
+    LayerTexture* m_texture;
+};
+
 }
 
 #endif // PaintLayerOperation_h
index f61186a..dc6577c 100644 (file)
@@ -231,6 +231,14 @@ void ShaderProgram::clip(const FloatRect& clip)
     m_clipRect = clip;
 }
 
+IntRect ShaderProgram::clippedRectWithViewport(const IntRect& rect)
+{
+    IntRect viewport(m_viewport.fLeft, m_viewport.fTop,
+                     m_viewport.width(), m_viewport.height());
+    viewport.intersect(rect);
+    return viewport;
+}
+
 void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
                                   SkRect& geometry, int textureId, float opacity)
 {
index 6508fdb..68cc560 100644 (file)
@@ -44,6 +44,7 @@ class ShaderProgram {
     FloatRect clipRectInScreenCoord(const TransformationMatrix& drawMatrix,
                                     const IntSize& size);
     void clip(const FloatRect& rect);
+    IntRect clippedRectWithViewport(const IntRect& rect);
 
  private:
     GLuint loadShader(GLenum shaderType, const char* pSource);
index 959b2bd..7b0673d 100644 (file)
 namespace WebCore {
 
 class TiledPage;
+class BackedDoubleBufferedTexture;
 
 class TextureOwner {
 public:
     virtual ~TextureOwner() {}
-    virtual void removeTexture() = 0;
+    virtual void removeTexture(BackedDoubleBufferedTexture* texture) = 0;
     virtual TiledPage* page() = 0;
 };
 
index 289665d..62cadc3 100644 (file)
@@ -80,7 +80,12 @@ void TexturesGenerator::removeOperationsForPage(TiledPage* page)
 
 void TexturesGenerator::removeOperationsForBaseLayer(BaseLayerAndroid* layer)
 {
-    removeOperationsForFilter(new PaintLayerFilter(layer));
+    removeOperationsForFilter(new PaintLayerBaseFilter(layer));
+}
+
+void TexturesGenerator::removeOperationsForTexture(LayerTexture* texture)
+{
+    removeOperationsForFilter(new PaintLayerTextureFilter(texture));
 }
 
 void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
@@ -106,11 +111,15 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
     if (!m_waitForCompletion)
         return;
 
-    // At this point, it means that we are currently painting a operation that
-    // we want to be removed -- we should wait until it is painted, so that
-    // when we return our caller can be sure that there is no more TileSet
-    // in the queue for that TiledPage and can safely deallocate the BaseTiles.
+    // 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.
     mRequestedOperationsLock.lock();
+    if (!m_waitForCompletion) {
+        mRequestedOperationsLock.unlock();
+        return; // operation treated
+    }
     mRequestedOperationsCond.wait(mRequestedOperationsLock);
     m_waitForCompletion = false;
     mRequestedOperationsLock.unlock();
index 0e40e4a..d98eb5b 100644 (file)
@@ -28,6 +28,7 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
+#include "LayerTexture.h"
 #include "QueuedOperation.h"
 #include "TileSet.h"
 #include "TiledPage.h"
@@ -50,6 +51,7 @@ public:
 
     void removeOperationsForPage(TiledPage* page);
     void removeOperationsForBaseLayer(BaseLayerAndroid* layer);
+    void removeOperationsForTexture(LayerTexture* texture);
     void removeOperationsForFilter(OperationFilter* filter);
 
     void scheduleOperation(QueuedOperation* operation);
index 3e174d1..1655016 100644 (file)
@@ -84,6 +84,10 @@ TilesManager::TilesManager()
 
     m_pixmapsGenerationThread = new TexturesGenerator();
     m_pixmapsGenerationThread->run("TexturesGenerator");
+
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
+    m_totalMaxTextureSize = m_maxTextureSize * m_maxTextureSize * BYTES_PER_PIXEL;
+    XLOG("Max texture size %d", m_maxTextureSize);
 }
 
 // Has to be run on the texture generation threads
@@ -226,13 +230,17 @@ BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner)
     return 0;
 }
 
-LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer)
+LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer,
+                                                       const IntRect& rect,
+                                                       bool any)
 {
     android::Mutex::Autolock lock(m_texturesLock);
     for (unsigned int i = 0; i< m_layersTextures.size(); i++) {
         if (m_layersTextures[i]->id() != layer->uniqueId())
             continue;
-        if (layer->getSize() != m_layersTextures[i]->getSize())
+        if (!any && rect != m_layersTextures[i]->rect())
+            continue;
+        if (!any && layer->getScale() != m_layersTextures[i]->scale())
             continue;
 
         XLOG("return layer %d (%x) for tile %d (%x)",
@@ -248,46 +256,105 @@ LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer)
 void TilesManager::printLayersTextures(const char* s)
 {
 #ifdef DEBUG
+    XLOG(">>> print layers textures (%s)", s);
     for (unsigned int i = 0; i< m_layersTextures.size(); i++) {
-        XLOG("[%d] %s, texture %x for layer %d, owner: %x", i, s, m_layersTextures[i],
-             m_layersTextures[i]->id(), m_layersTextures[i]->owner());
+        XLOG("[%d] %s, texture %x for layer %d (w: %.2f, h: %.2f), owner: %x",
+             i, s, m_layersTextures[i],
+             m_layersTextures[i]->id(),
+             m_layersTextures[i]->getSize().fWidth,
+             m_layersTextures[i]->getSize().fHeight,
+             m_layersTextures[i]->owner());
     }
+    XLOG("<<< print layers textures (%s)", s);
 #endif
 }
 
-void TilesManager::cleanupLayersTextures(bool forceCleanup)
+void TilesManager::cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup)
 {
     android::Mutex::Autolock lock(m_texturesLock);
+    SkLayer* rootLayer = layer->getRootLayer();
 #ifdef DEBUG
-    printLayersTextures("cleanup");
+    if (forceCleanup)
+        XLOG("FORCE cleanup");
+    XLOG("before cleanup, memory %d", m_layersMemoryUsage);
+    printLayersTextures("before cleanup");
 #endif
-    for (unsigned int i = 0; i< m_layersTextures.size(); i++) {
+    for (unsigned int i = 0; i< m_layersTextures.size();) {
         LayerTexture* texture = m_layersTextures[i];
 
-        if (forceCleanup)
-            texture->setOwner(0);
+        if (forceCleanup && texture->owner()) {
+            LayerAndroid* textureLayer =
+                static_cast<LayerAndroid*>(texture->owner());
+            if (textureLayer->getRootLayer() != rootLayer) {
+                // We only want to force destroy layers
+                // that are not used by the current page
+                XLOG("force removing texture %x for layer %d",
+                     texture, textureLayer->uniqueId());
+                textureLayer->removeTexture(texture);
+            }
+        }
 
-        if (!texture->owner()) {
+        // We only try to destroy textures that have no owners.
+        // This could be due to:
+        // 1) - the LayerAndroid dtor has been called (i.e. when swapping
+        // a LayerAndroid tree with a new one)
+        // 2) - or due to the above code, forcing a destroy.
+        // If the texture has been forced to be released (case #2), it
+        // could still be in use (in the middle of being painted). So we
+        // need to check that's not the case by checking busy(). See
+        // LayerAndroid::paintBitmapGL().
+        if (!texture->owner() && !texture->busy()) {
             m_layersMemoryUsage -= (int) texture->getSize().fWidth
                 * (int) texture->getSize().fHeight * BYTES_PER_PIXEL;
             m_layersTextures.remove(i);
+            // We can destroy the texture. We first remove it from the textures
+            // list, and then remove any queued drawing. At this point we know
+            // the texture has been removed from the layer, and that it's not
+            // busy, so it's safe to delete.
+            m_pixmapsGenerationThread->removeOperationsForTexture(texture);
+            XLOG("delete texture %x", texture);
             delete texture;
+        } else {
+            // only iterate if we don't delete (if we delete, no need to as we
+            // remove the element from the array)
+            i++;
         }
     }
+    printLayersTextures("after cleanup");
+    XLOG("after cleanup, memory %d", m_layersMemoryUsage);
 }
 
-LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer)
+LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer, const IntRect& rect)
 {
-    int w = layer->getWidth();
-    int h = layer->getHeight();
-    int size = w * h * BYTES_PER_PIXEL;
+    int w = rect.width() * layer->getScale();
+    int h = rect.height() * layer->getScale();
+    unsigned int size = w * h * BYTES_PER_PIXEL;
+
+    // We will not allocate textures that:
+    // 1) cannot be handled by the graphic card (m_maxTextureSize &
+    // m_totalMaxTextureSize)
+    // 2) will make us go past our texture limit (MAX_LAYERS_ALLOCATION)
+
+    bool large = w > m_maxTextureSize || h > m_maxTextureSize || size > m_totalMaxTextureSize;
+    XLOG("createTextureForLayer(%d) @scale %.2f => %d, %d (too large? %x)", layer->uniqueId(),
+         layer->getScale(), w, h, large);
+
+    // For now just return 0 if too large
+    if (large)
+        return 0;
+
+    if (w == 0 || h == 0) // empty layer
+        return 0;
 
     if (m_layersMemoryUsage + size > MAX_LAYERS_ALLOCATION)
-        cleanupLayersTextures(true);
+        cleanupLayersTextures(layer, true);
 
-    android::Mutex::Autolock lock(m_texturesLock);
     LayerTexture* texture = new LayerTexture(w, h);
     texture->setId(layer->uniqueId());
+    texture->setRect(rect);
+    texture->setScale(layer->getScale());
+
+    android::Mutex::Autolock lock(m_texturesLock);
     m_layersTextures.append(texture);
     texture->acquire(layer);
     m_layersMemoryUsage += size;
index e69db4c..c09a388 100644 (file)
@@ -55,6 +55,11 @@ public:
         m_pixmapsGenerationThread->removeOperationsForBaseLayer(layer);
     }
 
+    void removeOperationsForTexture(LayerTexture* texture)
+    {
+        m_pixmapsGenerationThread->removeOperationsForTexture(texture);
+    }
+
     void scheduleOperation(QueuedOperation* operation)
     {
         m_pixmapsGenerationThread->scheduleOperation(operation);
@@ -65,14 +70,16 @@ public:
     BackedDoubleBufferedTexture* getAvailableTexture(BaseTile* owner);
 
     void printLayersTextures(const char* s);
-    void cleanupLayersTextures(bool forceCleanup = false);
-    LayerTexture* getExistingTextureForLayer(LayerAndroid* layer);
-    LayerTexture* createTextureForLayer(LayerAndroid* layer);
+    void cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup = false);
+    LayerTexture* getExistingTextureForLayer(LayerAndroid* layer, const IntRect& rect,
+                                             bool any = false);
+    LayerTexture* createTextureForLayer(LayerAndroid* layer, const IntRect& rect);
 
     void markGeneratorAsReady()
     {
         android::Mutex::Autolock lock(m_generatorLock);
         m_generatorReadyCond.signal();
+        m_generatorReady = true;
     }
 
     void printTextures();
@@ -92,13 +99,16 @@ private:
     void waitForGenerator()
     {
         android::Mutex::Autolock lock(m_generatorLock);
-        m_generatorReadyCond.wait(m_generatorLock);
+        if (!m_generatorReady)
+            m_generatorReadyCond.wait(m_generatorLock);
     }
 
     Vector<BackedDoubleBufferedTexture*> m_textures;
     Vector<LayerTexture*> m_layersTextures;
 
     unsigned int m_layersMemoryUsage;
+    GLint m_maxTextureSize;
+    unsigned int m_totalMaxTextureSize;
 
     bool m_generatorReady;
 
index a2cf66c..36d2449 100644 (file)
@@ -266,6 +266,13 @@ bool RenderIFrame::requiresAcceleratedCompositing() const
     if (!node() || !node()->hasTagName(iframeTag))
         return false;
 
+#if PLATFORM(ANDROID)
+    // XXX: Bug submitted to webkit.org
+    // https://bugs.webkit.org/show_bug.cgi?id=52655
+    if (style()->visibility() != VISIBLE)
+        return false;
+#endif
+
     // If the contents of the iframe are composited, then we have to be as well.
     HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(node());
     if (Document* contentDocument = element->contentDocument()) {
index 654f6e6..0877468 100644 (file)
@@ -591,13 +591,12 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
     if (layer->isFixed())
         compositingState.m_fixedSibling = true;
 
-    if (!willBeComposited && compositingState.m_fixedSibling)
+    if (!willBeComposited && compositingState.m_fixedSibling) {
         layer->setMustOverlapCompositedLayers(true);
-
-    if (willBeComposited || compositingState.m_fixedSibling) {
-#else
-    if (willBeComposited) {
+        willBeComposited = true;
+    }
 #endif
+    if (willBeComposited) {
         // Tell the parent it has compositing descendants.
         compositingState.m_subtreeIsCompositing = true;
         // This layer now acts as the ancestor for kids.
index d165afa..cc21dad 100644 (file)
@@ -708,7 +708,9 @@ void FrameLoaderClientAndroid::didRunInsecureContent(SecurityOrigin*)
 void FrameLoaderClientAndroid::committedLoad(DocumentLoader* loader, const char* data, int length) {
     if (!m_manualLoader)
         loader->commitData(data, length);
-    else {
+
+    // commit data may have created a manual plugin loader
+    if (m_manualLoader) {
         if (!m_hasSentResponseToPlugin) {
             m_manualLoader->didReceiveResponse(loader->response());
             // Failure could cause the main document to have an error causing
@@ -807,12 +809,12 @@ void FrameLoaderClientAndroid::frameLoadCompleted() {
 void FrameLoaderClientAndroid::saveViewStateToItem(HistoryItem* item) {
     ASSERT(m_frame);
     ASSERT(item);
-    // We should have added a bridge when the child item was added to its
-    // parent.
-    AndroidWebHistoryBridge* bridge = item->bridge();
-    ASSERT(bridge);
     // store the current scale (only) for the top frame
     if (!m_frame->tree()->parent()) {
+        // We should have added a bridge when the child item was added to its
+        // parent.
+        AndroidWebHistoryBridge* bridge = item->bridge();
+        ASSERT(bridge);
         WebViewCore* webViewCore = WebViewCore::getWebViewCore(m_frame->view());
         bridge->setScale(webViewCore->scale());
         bridge->setTextWrapScale(webViewCore->textWrapScale());
index e9f4f3b..2158075 100644 (file)
@@ -149,7 +149,6 @@ void MediaPlayerPrivate::onEnded() {
     m_currentTime = duration();
     m_player->timeChanged();
     m_paused = true;
-    m_currentTime = 0;
     m_hasVideo = false;
     m_networkState = MediaPlayer::Idle;
     m_readyState = MediaPlayer::HaveNothing;
@@ -157,7 +156,6 @@ void MediaPlayerPrivate::onEnded() {
 
 void MediaPlayerPrivate::onPaused() {
     m_paused = true;
-    m_currentTime = 0;
     m_hasVideo = false;
     m_networkState = MediaPlayer::Idle;
     m_readyState = MediaPlayer::HaveNothing;
@@ -171,15 +169,30 @@ void MediaPlayerPrivate::onTimeupdate(int position) {
 
 class MediaPlayerVideoPrivate : public MediaPlayerPrivate {
 public:
-    void load(const String& url) { m_url = url; }
+    void load(const String& url) {
+        m_url = url;
+        // Cheat a bit here to make sure Window.onLoad event can be triggered
+        // at the right time instead of real video play time, since only full
+        // screen video play is supported in Java's VideoView.
+        // See also comments in prepareToPlay function.
+        m_networkState = MediaPlayer::Loading;
+        m_player->networkStateChanged();
+        m_readyState = MediaPlayer::HaveCurrentData;
+        m_player->readyStateChanged();
+    }
+
     void play() {
         JNIEnv* env = JSC::Bindings::getJNIEnv();
         if (!env || !m_url.length() || !m_glue->m_javaProxy)
             return;
 
         m_paused = false;
+
+        if (m_currentTime == duration())
+            m_currentTime = 0;
+
         jstring jUrl = wtfStringToJstring(env, m_url);
-        env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_play, jUrl);
+        env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_play, jUrl, static_cast<jint>(m_currentTime * 1000.0f));
         env->DeleteLocalRef(jUrl);
 
         checkException(env);
@@ -261,7 +274,7 @@ public:
         m_glue = new JavaGlue;
         m_glue->m_getInstance = env->GetStaticMethodID(clazz, "getInstance", "(Landroid/webkit/WebViewCore;I)Landroid/webkit/HTML5VideoViewProxy;");
         m_glue->m_loadPoster = env->GetMethodID(clazz, "loadPoster", "(Ljava/lang/String;)V");
-        m_glue->m_play = env->GetMethodID(clazz, "play", "(Ljava/lang/String;)V");
+        m_glue->m_play = env->GetMethodID(clazz, "play", "(Ljava/lang/String;I)V");
 
         m_glue->m_teardown = env->GetMethodID(clazz, "teardown", "()V");
         m_glue->m_seek = env->GetMethodID(clazz, "seek", "(I)V");
index d6224e0..ed7ece7 100644 (file)
@@ -302,7 +302,7 @@ void WebUrlLoaderClient::didReceiveResponse(PassOwnPtr<WebResponse> webResponse)
 
 void WebUrlLoaderClient::didReceiveData(scoped_refptr<net::IOBuffer> buf, int size)
 {
-    if (!isActive())
+    if (!isActive() || !size)
         return;
 
     // didReceiveData will take a copy of the data
@@ -313,7 +313,7 @@ void WebUrlLoaderClient::didReceiveData(scoped_refptr<net::IOBuffer> buf, int si
 // For data url's
 void WebUrlLoaderClient::didReceiveDataUrl(PassOwnPtr<std::string> str)
 {
-    if (!isActive())
+    if (!isActive() || !str->size())
         return;
 
     // didReceiveData will take a copy of the data
@@ -323,7 +323,7 @@ void WebUrlLoaderClient::didReceiveDataUrl(PassOwnPtr<std::string> str)
 // For special android files
 void WebUrlLoaderClient::didReceiveAndroidFileData(PassOwnPtr<std::vector<char> > vector)
 {
-    if (!isActive())
+    if (!isActive() || !vector->size())
         return;
 
     // didReceiveData will take a copy of the data
index d30918f..669eb19 100644 (file)
@@ -288,8 +288,8 @@ void GetOptionStringsFromElement(HTMLFormControlElement* element, std::vector<st
 namespace android {
 
 struct FormManager::FormElement {
-    HTMLFormElement* form_element;
-    std::vector<HTMLFormControlElement*> control_elements;
+    RefPtr<HTMLFormElement> form_element;
+    std::vector<RefPtr<HTMLFormControlElement> > control_elements;
     std::vector<string16> control_values;
 };
 
@@ -535,7 +535,7 @@ void FormManager::GetFormsInFrame(const Frame* frame, RequirementsMask requireme
             continue;
 
         FormData form;
-        HTMLFormElementToFormData(form_element->form_element, requirements, EXTRACT_VALUE, &form);
+        HTMLFormElementToFormData(form_element->form_element.get(), requirements, EXTRACT_VALUE, &form);
         if (form.fields.size() >= kRequiredAutoFillFields)
             forms->push_back(form);
     }
@@ -554,10 +554,11 @@ bool FormManager::FindFormWithFormControlElement(HTMLFormControlElement* element
         if (form_element->form_element->document()->frame() != frame)
             continue;
 
-        for (std::vector<HTMLFormControlElement*>::const_iterator iter = form_element->control_elements.begin(); iter != form_element->control_elements.end(); ++iter) {
-            if (nameForAutoFill(**iter) == nameForAutoFill(*element)) {
+        for (std::vector<RefPtr<HTMLFormControlElement> >::const_iterator iter = form_element->control_elements.begin(); iter != form_element->control_elements.end(); ++iter) {
+            HTMLFormControlElement* candidate = iter->get();
+            if (nameForAutoFill(*candidate) == nameForAutoFill(*element)) {
                 ExtractMask extract_mask = static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
-                return HTMLFormElementToFormData(form_element->form_element, requirements, extract_mask, form);
+                return HTMLFormElementToFormData(form_element->form_element.get(), requirements, extract_mask, form);
             }
         }
     }
@@ -592,7 +593,7 @@ bool FormManager::ClearFormWithNode(Node* node) {
         return false;
 
     for (size_t i = 0; i < form_element->control_elements.size(); ++i) {
-        HTMLFormControlElement* element = form_element->control_elements[i];
+        HTMLFormControlElement* element = form_element->control_elements[i].get();
         if (formControlType(*element) == kText) {
             HTMLInputElement* input_element = static_cast<HTMLInputElement*>(element);
 
@@ -623,7 +624,7 @@ bool FormManager::ClearPreviewedFormWithNode(Node* node, bool was_autofilled) {
         return false;
 
     for (size_t i = 0; i < form_element->control_elements.size(); ++i) {
-        HTMLFormControlElement* element = form_element->control_elements[i];
+        HTMLFormControlElement* element = form_element->control_elements[i].get();
 
         // Only input elements can be previewed.
         if (formControlType(*element) != kText)
@@ -688,7 +689,7 @@ bool FormManager::FormWithNodeIsAutoFilled(Node* node) {
         return false;
 
     for (size_t i = 0; i < form_element->control_elements.size(); ++i) {
-        HTMLFormControlElement* element = form_element->control_elements[i];
+        HTMLFormControlElement* element = form_element->control_elements[i].get();
         if (formControlType(*element) != kText)
             continue;
 
@@ -726,8 +727,8 @@ string16 FormManager::InferLabelForElement(const HTMLFormControlElement& element
 bool FormManager::FindCachedFormElementWithNode(Node* node,
                                                 FormElement** form_element) {
     for (FormElementList::const_iterator form_iter = form_elements_.begin(); form_iter != form_elements_.end(); ++form_iter) {
-        for (std::vector<HTMLFormControlElement*>::const_iterator iter = (*form_iter)->control_elements.begin(); iter != (*form_iter)->control_elements.end(); ++iter) {
-            if (*iter == node) {
+        for (std::vector<RefPtr<HTMLFormControlElement> >::const_iterator iter = (*form_iter)->control_elements.begin(); iter != (*form_iter)->control_elements.end(); ++iter) {
+            if (iter->get() == node) {
                 *form_element = *form_iter;
                 return true;
             }
@@ -765,7 +766,7 @@ void FormManager::ForEachMatchingFormField(FormElement* form, Node* node, Requir
     // one case in the wild where this happens, paypal.com signup form, the fields
     // are appended to the end of the form and are not visible.
     for (size_t i = 0, j = 0; i < form->control_elements.size() && j < data.fields.size(); ++i) {
-        HTMLFormControlElement* element = form->control_elements[i];
+        HTMLFormControlElement* element = form->control_elements[i].get();
         string16 element_name = nameForAutoFill(*element);
 
         if (element_name.empty())
index 27ced0e..69585b2 100644 (file)
@@ -863,6 +863,10 @@ BaseLayerAndroid* WebViewCore::createBaseLayer()
     BaseLayerAndroid* base = new BaseLayerAndroid();
     base->setContent(m_content);
 
+    bool layoutSucceeded = layoutIfNeededRecursive(m_mainFrame);
+    // Layout only fails if called during a layout.
+    LOG_ASSERT(layoutSucceeded, "Can never be called recursively");
+
 #if USE(ACCELERATED_COMPOSITING)
     // We set the background color
     if (m_mainFrame && m_mainFrame->document()
@@ -915,8 +919,8 @@ BaseLayerAndroid* WebViewCore::recordContent(SkRegion* region, SkIPoint* point)
 
 void WebViewCore::splitContent(PictureSet* content)
 {
-    bool layoutSuceeded = layoutIfNeededRecursive(m_mainFrame);
-    LOG_ASSERT(layoutSuceeded, "Can never be called recursively");
+    bool layoutSucceeded = layoutIfNeededRecursive(m_mainFrame);
+    LOG_ASSERT(layoutSucceeded, "Can never be called recursively");
     content->split(&m_content);
     rebuildPictureSet(&m_content);
     content->set(m_content);
index 4c4d6b5..2b1e854 100644 (file)
@@ -425,7 +425,7 @@ bool drawGL(WebCore::IntRect& viewRect, float scale, int extras)
         return false;
 
     if (!m_glWebViewState) {
-        m_glWebViewState = new GLWebViewState();
+        m_glWebViewState = new GLWebViewState(&m_viewImpl->gButtonMutex);
         if (m_baseLayer->content()) {
             IntRect rect(0, 0, m_baseLayer->content()->width(), m_baseLayer->content()->height());
             m_glWebViewState->setBaseLayer(m_baseLayer, rect);