diff options
5 files changed, 36 insertions, 8 deletions
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp index dc0962c..964422a 100644 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp +++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp @@ -137,6 +137,7 @@ void BackedDoubleBufferedTexture::setNotBusy() m_delayedRelease = false; m_delayedReleaseOwner = 0; } + m_busyCond.signal(); } bool BackedDoubleBufferedTexture::busy() @@ -189,7 +190,7 @@ void BackedDoubleBufferedTexture::producerUpdate(TextureInfo* textureInfo) producerReleaseAndSwap(); } -bool BackedDoubleBufferedTexture::acquire(TextureOwner* owner) +bool BackedDoubleBufferedTexture::acquire(TextureOwner* owner, bool force) { if (m_owner == owner) { if (m_delayedRelease) { @@ -199,7 +200,7 @@ bool BackedDoubleBufferedTexture::acquire(TextureOwner* owner) return true; } - return setOwner(owner); + return setOwner(owner, force); } bool BackedDoubleBufferedTexture::tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage) @@ -216,13 +217,16 @@ bool BackedDoubleBufferedTexture::tryAcquire(TextureOwner* owner, TiledPage* cur return false; } -bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner) +bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner, bool force) { // if the writable texture is busy (i.e. currently being written to) then we // can't change the owner out from underneath that texture m_busyLock.lock(); + while (m_busy && force) + m_busyCond.wait(m_busyLock); bool busy = m_busy; m_busyLock.unlock(); + if (!busy) { // if we are not busy we can try to remove the texture from the layer; // LayerAndroid::removeTexture() is protected by the same lock as diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h index 8bfae59..7c2ea90 100644 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h +++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h @@ -88,12 +88,12 @@ public: // allows consumer thread to assign ownership of the texture to the tile. It // returns false if ownership cannot be transferred because the tile is busy - bool acquire(TextureOwner* owner); + bool acquire(TextureOwner* owner, bool force = false); bool release(TextureOwner* owner); bool tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage); // set the texture owner if not busy. Return false if busy, true otherwise. - bool setOwner(TextureOwner* owner); + bool setOwner(TextureOwner* owner, bool force = false); // private member accessor functions TextureOwner* owner() { return m_owner; } // only used by the consumer thread @@ -136,6 +136,9 @@ private: // We mutex protect the reads/writes of m_busy to ensure that we are reading // the most up-to-date value even across processors in an SMP system. android::Mutex m_busyLock; + // We use this condition variable to signal that the texture + // is not busy anymore + android::Condition m_busyCond; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/android/ShaderProgram.cpp b/WebCore/platform/graphics/android/ShaderProgram.cpp index efa53ae..74328a1 100644 --- a/WebCore/platform/graphics/android/ShaderProgram.cpp +++ b/WebCore/platform/graphics/android/ShaderProgram.cpp @@ -259,17 +259,23 @@ void ShaderProgram::setViewRect(const IntRect& viewRect) // content coordinates in screen coordinates. TransformationMatrix translate; translate.translate(1.0, 1.0); + + TransformationMatrix screenTranslate; + screenTranslate.translate(-viewRect.x(), -viewRect.y()); + TransformationMatrix scale; scale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1); m_documentToScreenMatrix = m_projectionMatrix; m_documentToScreenMatrix.multiply(translate); m_documentToScreenMatrix.multiply(scale); + m_documentToScreenMatrix.multiply(screenTranslate); m_documentToInvScreenMatrix = m_projectionMatrix; translate.scale3d(1, -1, 1); m_documentToInvScreenMatrix.multiply(translate); m_documentToInvScreenMatrix.multiply(scale); + m_documentToScreenMatrix.multiply(screenTranslate); } // This function transform a clip rect extracted from the current layer diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp index afc53eb..5a9a164 100644 --- a/WebCore/platform/graphics/android/TilesManager.cpp +++ b/WebCore/platform/graphics/android/TilesManager.cpp @@ -249,7 +249,7 @@ LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer, layer->uniqueId(), layer); } - if (best && best->acquire(layer)) + if (best && best->acquire(layer, any)) return best; return 0; } diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp index fcfb4ca..cf218e7 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp +++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp @@ -180,14 +180,29 @@ bool WebUrlLoaderClient::start(bool isMainResource, bool isMainFrame, bool sync, thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start)); // Run callbacks until the queue is exhausted and m_finished is true. + // Sometimes, a sync load can wait forever and lock up the WebCore thread, + // here we use TimedWait() with multiple tries to avoid locking. + const int kMaxNumTimeout = 3; + const int kCallbackWaitingTime = 10; + int num_timeout = 0; while(!m_finished) { while (!m_queue.empty()) { OwnPtr<Task> task(m_queue.front()); m_queue.pop_front(); task->Run(); } - if (m_queue.empty() && !m_finished) { - syncCondition()->Wait(); + if (m_finished) break; + + syncCondition()->TimedWait(base::TimeDelta::FromSeconds(kCallbackWaitingTime)); + if (m_queue.empty()) { + LOGE("Synchronous request timed out after %d seconds for the %dth try, URL: %s", + kCallbackWaitingTime, num_timeout, m_request->getUrl().c_str()); + num_timeout++; + if (num_timeout >= kMaxNumTimeout) { + cancel(); + m_resourceHandle = 0; + return false; + } } } |
