diff options
Diffstat (limited to 'Source')
14 files changed, 120 insertions, 42 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 94bf045..827c858 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -337,9 +337,13 @@ bool BaseLayerAndroid::drawGL(double currentTime, LayerAndroid* compositedRoot, TilesManager::instance()->videoLayerManager()->deleteUnusedTextures(); compositedRoot->prepare(m_glWebViewState); - if (compositedRoot->drawGL(m_glWebViewState, matrix)) - needsRedraw = true; - else if (!animsRunning) + if (compositedRoot->drawGL(m_glWebViewState, matrix)) { + if (TilesManager::instance()->layerTexturesRemain()) { + // only try redrawing for layers if layer textures remain, + // otherwise we'll repaint without getting anything done + needsRedraw = true; + } + } else if (!animsRunning) m_glWebViewState->resetLayersDirtyArea(); } diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index 318a969..b38c590 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -135,6 +135,8 @@ void BaseTile::reserveTexture() android::AutoMutex lock(m_atomicSync); if (texture && m_backTexture != texture) { + XLOG("tile %p reserving texture %p, back was %p (front %p)", + this, texture, m_backTexture, m_frontTexture); m_state = Unpainted; m_backTexture = texture; } @@ -148,8 +150,8 @@ void BaseTile::reserveTexture() bool BaseTile::removeTexture(BaseTileTexture* texture) { - XLOG("%x removeTexture back %x front %x... page %x", - this, m_backTexture, m_frontTexture, m_page); + XLOG("%p removeTexture %p, back %p front %p... page %p", + this, texture, m_backTexture, m_frontTexture, m_page); // We update atomically, so paintBitmap() can see the correct value android::AutoMutex lock(m_atomicSync); if (m_frontTexture == texture) { @@ -484,6 +486,8 @@ void BaseTile::paintBitmap() void BaseTile::discardTextures() { android::AutoMutex lock(m_atomicSync); + XLOG("%p discarding bt %p, ft %p", + this, m_backTexture, m_frontTexture); if (m_frontTexture) { m_frontTexture->release(this); m_frontTexture = 0; diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp index 54c96c8..cedad99 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp @@ -82,22 +82,18 @@ BaseTileTexture::~BaseTileTexture() #endif } -void BaseTileTexture::requireTexture() +void BaseTileTexture::requireGLTexture() { if (!m_ownTextureId) m_ownTextureId = GLUtils::createBaseTileGLTexture(m_size.width(), m_size.height()); } -void BaseTileTexture::discardTexture() +void BaseTileTexture::discardGLTexture() { if (m_ownTextureId) GLUtils::deleteTexture(&m_ownTextureId); - if (m_owner) { - // clear both Tile->Texture and Texture->Tile links - m_owner->removeTexture(this); - release(m_owner); - } + releaseAndRemoveFromTile(); } void BaseTileTexture::destroyTextures(SharedTexture** textures) @@ -185,19 +181,6 @@ bool BaseTileTexture::acquire(TextureOwner* owner, bool force) return setOwner(owner, force); } -bool BaseTileTexture::tryAcquire(TextureOwner* owner) -{ - m_busyLock.lock(); - if (!m_busy - && m_owner - && m_owner->state() != owner->state()) { - m_busyLock.unlock(); - return this->acquire(owner); - } - m_busyLock.unlock(); - return false; -} - bool BaseTileTexture::setOwner(TextureOwner* owner, bool force) { // if the writable texture is busy (i.e. currently being written to) then we @@ -232,6 +215,7 @@ bool BaseTileTexture::setOwner(TextureOwner* owner, bool force) bool BaseTileTexture::release(TextureOwner* owner) { android::Mutex::Autolock lock(m_busyLock); + XLOG("texture %p releasing tile %p, m_owner %p, m_busy %d", this, owner, m_owner, m_busy); if (m_owner != owner) return false; @@ -244,6 +228,15 @@ bool BaseTileTexture::release(TextureOwner* owner) return true; } +void BaseTileTexture::releaseAndRemoveFromTile() +{ + if (m_owner) { + // clear both Tile->Texture and Texture->Tile links + m_owner->removeTexture(this); + release(m_owner); + } +} + void BaseTileTexture::setTile(TextureInfo* info, int x, int y, float scale, TilePainter* painter, unsigned int pictureCount) diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h index 9c2d8a7..6a9ce43 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h @@ -82,7 +82,9 @@ public: // returns false if ownership cannot be transferred because the tile is busy bool acquire(TextureOwner* owner, bool force = false); bool release(TextureOwner* owner); - bool tryAcquire(TextureOwner* owner); + + // removes Tile->Texture, and Texture->Tile links to fully discard the texture + void releaseAndRemoveFromTile(); // set the texture owner if not busy. Return false if busy, true otherwise. bool setOwner(TextureOwner* owner, bool force = false); @@ -104,8 +106,8 @@ public: // OpenGL ID of backing texture, 0 when not allocated GLuint m_ownTextureId; // these are used for dynamically (de)allocating backing graphics memory - void requireTexture(); - void discardTexture(); + void requireGLTexture(); + void discardGLTexture(); void setOwnTextureTileInfoFromQueue(const TextureTileInfo* info); diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 9f266d2..b096c20 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -205,7 +205,8 @@ void GLWebViewState::inval(const IntRect& rect) m_currentPictureCounter++; if (!rect.isEmpty()) { // find which tiles fall within the invalRect and mark them as dirty - frontPage()->invalidateRect(rect, m_currentPictureCounter); + m_tiledPageA->invalidateRect(rect, m_currentPictureCounter); + m_tiledPageB->invalidateRect(rect, m_currentPictureCounter); if (m_frameworkInval.isEmpty()) m_frameworkInval = rect; else @@ -444,10 +445,8 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, // the BaseTiles' texture. TilesManager::instance()->transferQueue()->updateDirtyBaseTiles(); - if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) { + if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) XLOGC("WARNING, scale seems corrupted after update: %e", scale); - CRASH(); - } // gather the textures we can use TilesManager::instance()->gatherLayerTextures(); diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp index 8c63b42..ce4dc7f 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp @@ -219,8 +219,8 @@ bool TiledTexture::draw() for (unsigned int i = 0; i < m_tiles.size(); i++) { BaseTile* tile = m_tiles[i]; - askRedraw |= !tile->isTileReady(); if (tile->isTileVisible(m_area)) { + askRedraw |= !tile->isTileReady(); SkRect rect; rect.fLeft = tile->x() * tileWidth; rect.fTop = tile->y() * tileHeight; diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index f077d48..2d0cc7f 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -93,7 +93,7 @@ int TilesManager::getMaxTextureAllocation() } TilesManager::TilesManager() - : m_layersMemoryUsage(0) + : m_layerTexturesRemain(true) , m_maxTextureCount(0) , m_generatorReady(false) , m_showVisualIndicator(false) @@ -169,14 +169,14 @@ void TilesManager::deallocateTextures(bool allTextures) for (unsigned int i = 0; i < max; i++) { TextureOwner* owner = m_textures[i]->owner(); if (!owner || owner->drawCount() < sparedDrawCount) { - m_textures[i]->discardTexture(); + m_textures[i]->discardGLTexture(); dealloc++; } } for (unsigned int i = 0; i < maxLayer; i++) { TextureOwner* owner = m_tilesTextures[i]->owner(); if (!owner || owner->drawCount() < sparedDrawCount) { - m_tilesTextures[i]->discardTexture(); + m_tilesTextures[i]->discardGLTexture(); dealloc++; } } @@ -237,6 +237,7 @@ void TilesManager::gatherLayerTextures() { android::Mutex::Autolock lock(m_texturesLock); m_availableTilesTextures = m_tilesTextures; + m_layerTexturesRemain = true; } BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner) @@ -326,6 +327,13 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner) availableTexturePool->remove(availableTexturePool->find(farthestTexture)); return farthestTexture; } + } else { + if (owner->isLayerTile()) { + // couldn't find a tile for a layer, layers shouldn't request redraw + // TODO: once we do layer prefetching, don't set this for those + // tiles + m_layerTexturesRemain = false; + } } XLOG("Couldn't find an available texture for %s tile %x (%d, %d) out of %d available", diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h index 1549581..b7d6aa6 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.h +++ b/Source/WebCore/platform/graphics/android/TilesManager.h @@ -87,6 +87,8 @@ public: void gatherLayerTextures(); void gatherTextures(); + bool layerTexturesRemain() { return m_layerTexturesRemain; } + BaseTileTexture* getAvailableTexture(BaseTile* owner); void markGeneratorAsReady() @@ -197,11 +199,10 @@ private: Vector<BaseTileTexture*> m_tilesTextures; Vector<BaseTileTexture*> m_availableTilesTextures; + bool m_layerTexturesRemain; Vector<PaintedSurface*> m_paintedSurfaces; - unsigned int m_layersMemoryUsage; - int m_maxTextureCount; bool m_generatorReady; diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp index 43d73ee..a9d6b9a 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp @@ -308,7 +308,7 @@ void TransferQueue::updateDirtyBaseTiles() } // guarantee that we have a texture to blit into - destTexture->requireTexture(); + destTexture->requireGLTexture(); if (m_transferQueue[index].uploadType == CpuUpload) { // Here we just need to upload the bitmap content to the GL Texture @@ -357,6 +357,21 @@ void TransferQueue::updateDirtyBaseTiles() void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap) { + if (!tryUpdateQueueWithBitmap(renderInfo, x, y, bitmap)) { + // failed placing bitmap in queue, discard tile's texture so it will be + // re-enqueued (and repainted) + BaseTile* tile = renderInfo->baseTile; + if (tile) { + BaseTileTexture* texture = tile->backTexture(); + if (texture) + texture->releaseAndRemoveFromTile(); + } + } +} + +bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, + int x, int y, const SkBitmap& bitmap) +{ m_transferQueueItemLocks.lock(); bool ready = readyForUpdate(); TextureUploadType currentUploadType = m_currentUploadType; @@ -364,18 +379,18 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo, if (!ready) { XLOG("Quit bitmap update: not ready! for tile x y %d %d", renderInfo->x, renderInfo->y); - return; + return false; } if (currentUploadType == GpuUpload) { // a) Dequeue the Surface Texture and write into the buffer if (!m_ANW.get()) { XLOG("ERROR: ANW is null"); - return; + return false; } ANativeWindow_Buffer buffer; if (ANativeWindow_lock(m_ANW.get(), &buffer, 0)) - return; + return false; uint8_t* img = (uint8_t*)buffer.bits; int row, col; @@ -411,6 +426,7 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo, m_transferQueueItemLocks.unlock(); XLOG("Bitmap updated x, y %d %d, baseTile %p", renderInfo->x, renderInfo->y, renderInfo->baseTile); + return true; } // Note that there should be lock/unlock around this function call. @@ -476,6 +492,17 @@ void TransferQueue::cleanupTransportQueue() // be called to keep things in sync. if (m_transferQueue[index].uploadType == GpuUpload) m_sharedSurfaceTexture->updateTexImage(); + + // since tiles in the queue may be from another webview, remove + // their textures so that they will be repainted / retransferred + BaseTile* tile = m_transferQueue[index].savedBaseTilePtr; + if (tile) { + BaseTileTexture* texture = tile->backTexture(); + if (texture) + texture->releaseAndRemoveFromTile(); + } + XLOG("transfer queue discarded tile %p, removed texture", tile); + m_transferQueue[index].savedBaseTilePtr = 0; m_transferQueue[index].status = emptyItem; } diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h index 200df25..bddc85d 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.h +++ b/Source/WebCore/platform/graphics/android/TransferQueue.h @@ -112,6 +112,7 @@ public: void initSharedSurfaceTextures(int width, int height); + // insert the bitmap into the queue, mark the tile dirty if failing void updateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap); @@ -139,6 +140,9 @@ public: EGLSurface m_eglSurface; private: + // return true if successfully inserted into queue + bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y, + const SkBitmap& bitmap); bool getHasGLContext(); void setHasGLContext(bool hasContext); diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 17a8bc5..134408a 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -675,6 +675,13 @@ void WebViewCore::recordPictureSet(PictureSet* content) if (cacheBuilder().pictureSetDisabled()) content->clear(); +#if USE(ACCELERATED_COMPOSITING) + // Detects if the content size has changed + bool contentSizeChanged = false; + if (content->width() != width || content->height() != height) + contentSizeChanged = true; +#endif + content->setDimensions(width, height, &m_addInval); // Add the current inval rects to the PictureSet, and rebuild it. @@ -694,8 +701,25 @@ void WebViewCore::recordPictureSet(PictureSet* content) m_addInval.setRect(r); } + // Rebuild the pictureset (webkit repaint) rebuildPictureSet(content); +#if USE(ACCELERATED_COMPOSITING) + // We repainted the pictureset, but the invals are not always correct when + // the content size did change. For now, let's just reset the + // inval we will pass to the UI so that it invalidates the entire + // content -- tiles will be marked dirty and will have to be repainted. + // FIXME: the webkit invals ought to have been enough... + if (contentSizeChanged) { + SkIRect r; + r.fLeft = 0; + r.fTop = 0; + r.fRight = width; + r.fBottom = height; + m_addInval.setRect(r); + } +#endif + } // WebViewCoreRecordTimeCounter WebCore::Node* oldFocusNode = currentFocus(); diff --git a/Source/WebKit/android/nav/CacheBuilder.cpp b/Source/WebKit/android/nav/CacheBuilder.cpp index 3ec15f3..a4bc758 100644 --- a/Source/WebKit/android/nav/CacheBuilder.cpp +++ b/Source/WebKit/android/nav/CacheBuilder.cpp @@ -1246,6 +1246,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, type = TEXT_INPUT_CACHEDNODETYPE; cachedInput.init(); cachedInput.setAutoComplete(input->autoComplete()); + cachedInput.setSpellcheck(input->spellcheck()); cachedInput.setFormPointer(input->form()); cachedInput.setIsTextField(true); exported = input->value().threadsafeCopy(); diff --git a/Source/WebKit/android/nav/CachedInput.h b/Source/WebKit/android/nav/CachedInput.h index a3eabc7..77ae57b 100644 --- a/Source/WebKit/android/nav/CachedInput.h +++ b/Source/WebKit/android/nav/CachedInput.h @@ -78,7 +78,9 @@ public: void setPaddingLeft(int left) { mPaddingLeft = left; } void setPaddingRight(int right) { mPaddingRight = right; } void setPaddingTop(int top) { mPaddingTop = top; } + void setSpellcheck(bool spellcheck) { mSpellcheck = spellcheck; } void setTextSize(float textSize) { mTextSize = textSize; } + bool spellcheck() const { return mSpellcheck; } float textSize() const { return mTextSize; } private: @@ -94,6 +96,7 @@ private: float mTextSize; Type mType; bool mAutoComplete : 1; + bool mSpellcheck : 1; bool mIsRtlText : 1; bool mIsTextField : 1; bool mIsTextArea : 1; diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 1dcc7c4..d062db3 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -2125,6 +2125,12 @@ static jint nativeFocusCandidatePointer(JNIEnv *env, jobject obj) return reinterpret_cast<int>(node ? node->nodePointer() : 0); } +static jint nativeFocusCandidateIsSpellcheck(JNIEnv *env, jobject obj) +{ + const CachedInput* input = getInputCandidate(env, obj); + return input ? input->spellcheck() : false; +} + static jobject nativeFocusCandidateText(JNIEnv *env, jobject obj) { const CachedNode* node = getFocusCandidate(env, obj, 0); @@ -2835,6 +2841,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeFocusCandidateMaxLength }, { "nativeFocusCandidateIsAutoComplete", "()Z", (void*) nativeFocusCandidateIsAutoComplete }, + { "nativeFocusCandidateIsSpellcheck", "()Z", + (void*) nativeFocusCandidateIsSpellcheck }, { "nativeFocusCandidateName", "()Ljava/lang/String;", (void*) nativeFocusCandidateName }, { "nativeFocusCandidateNodeBounds", "()Landroid/graphics/Rect;", |