diff options
Diffstat (limited to 'WebCore/platform')
11 files changed, 272 insertions, 84 deletions
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp index 12e0436..ddfa9a0 100644 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp +++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp @@ -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 diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h index 844715d..0b62224 100644 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h +++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h @@ -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; } diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index b84831d..9ed967f 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -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)) diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index aec039d..64060f7 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -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,22 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(), gDebugLayerAndroidInstances++; } +void LayerAndroid::removeTexture() +{ + XLOG("remove texture (m_drawingTexture: %x, m_reservedTexture: %x)", + m_drawingTexture, m_reservedTexture); + android::AutoMutex lock(m_atomicSync); + if (m_drawingTexture) + m_drawingTexture->release(this); + if (m_reservedTexture && m_reservedTexture != m_drawingTexture) + m_reservedTexture->release(this); + m_drawingTexture = 0; + m_reservedTexture = 0; +} + LayerAndroid::~LayerAndroid() { - if (m_texture) - m_texture->release(this); + removeTexture(); removeChildren(); m_contentsImage->safeUnref(); m_recordingPicture->safeUnref(); @@ -549,12 +567,15 @@ void LayerAndroid::reserveGLTextures() for (int i = 0; i < count; i++) this->getChild(i)->reserveGLTextures(); - if (needsTexture()) { - LayerTexture* texture; - texture = TilesManager::instance()->getExistingTextureForLayer(this); - // SMP flush - android::AutoMutex lock(m_atomicSync); - m_texture = texture; + LayerTexture* reservedTexture = 0; + if (needsTexture()) + reservedTexture = TilesManager::instance()->getExistingTextureForLayer(this); + + // SMP flush + android::AutoMutex lock(m_atomicSync); + if (m_reservedTexture && m_reservedTexture != reservedTexture) { + m_reservedTexture->release(this); + m_reservedTexture = reservedTexture; } } @@ -564,46 +585,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); + + if (!reservedTexture) + return; + + 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; + + // SMP flush + m_atomicSync.lock(); + m_reservedTexture = reservedTexture; + m_atomicSync.unlock(); + + 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 +652,14 @@ 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()) { + if (prepareContext() && m_drawingTexture) { + TextureInfo* textureInfo = m_drawingTexture->consumerLock(); + if (textureInfo && m_drawingTexture->isReady()) { TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), rect, 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 +691,44 @@ 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; + float scale = m_scale; 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) @@ -689,8 +740,11 @@ void LayerAndroid::paintBitmapGL() XLOG("LayerAndroid %d paintBitmapGL WE ARE PAINTING", uniqueId()); SkCanvas* canvas = texture->canvas(); + canvas->save(); canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); + canvas->scale(scale, scale); contentDraw(canvas); + canvas->restore(); XLOG("LayerAndroid %d paintBitmapGL PAINTING DONE, updating the texture", uniqueId()); m_atomicSync.lock(); diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 76b4cb8..41bd9ef 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -94,11 +94,9 @@ public: virtual ~LayerAndroid(); // TextureOwner methods - virtual void removeTexture() - { - android::AutoMutex lock(m_atomicSync); - m_texture = 0; - } + virtual void removeTexture(); + + 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,21 @@ 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; + // 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. diff --git a/WebCore/platform/graphics/android/PaintLayerOperation.cpp b/WebCore/platform/graphics/android/PaintLayerOperation.cpp index a3ef148..dd81d9a 100644 --- a/WebCore/platform/graphics/android/PaintLayerOperation.cpp +++ b/WebCore/platform/graphics/android/PaintLayerOperation.cpp @@ -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; +} diff --git a/WebCore/platform/graphics/android/PaintLayerOperation.h b/WebCore/platform/graphics/android/PaintLayerOperation.h index d393ac5..74e87af 100644 --- a/WebCore/platform/graphics/android/PaintLayerOperation.h +++ b/WebCore/platform/graphics/android/PaintLayerOperation.h @@ -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 diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp index 289665d..a1f514f 100644 --- a/WebCore/platform/graphics/android/TexturesGenerator.cpp +++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp @@ -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,10 +111,10 @@ 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(); mRequestedOperationsCond.wait(mRequestedOperationsLock); m_waitForCompletion = false; diff --git a/WebCore/platform/graphics/android/TexturesGenerator.h b/WebCore/platform/graphics/android/TexturesGenerator.h index 0e40e4a..d98eb5b 100644 --- a/WebCore/platform/graphics/android/TexturesGenerator.h +++ b/WebCore/platform/graphics/android/TexturesGenerator.h @@ -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); diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp index 3e174d1..d6e868d 100644 --- a/WebCore/platform/graphics/android/TilesManager.cpp +++ b/WebCore/platform/graphics/android/TilesManager.cpp @@ -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 @@ -228,11 +232,17 @@ BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner) LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer) { + SkSize layerSize; + layerSize.fWidth = static_cast<int>( + layer->getSize().fWidth * layer->getScale()); + layerSize.fHeight = static_cast<int>( + layer->getSize().fHeight * layer->getScale()); + 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 (layerSize != m_layersTextures[i]->getSize()) continue; XLOG("return layer %d (%x) for tile %d (%x)", @@ -248,46 +258,101 @@ 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 (scale %.2f, 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]->getScale(), + 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(); + } + } - 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) { - int w = layer->getWidth(); - int h = layer->getHeight(); - int size = w * h * BYTES_PER_PIXEL; + int w = static_cast<int>(layer->getWidth() * layer->getScale()); + int h = static_cast<int>(layer->getHeight() * 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 (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()); + + android::Mutex::Autolock lock(m_texturesLock); m_layersTextures.append(texture); texture->acquire(layer); m_layersMemoryUsage += size; diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h index e69db4c..576d508 100644 --- a/WebCore/platform/graphics/android/TilesManager.h +++ b/WebCore/platform/graphics/android/TilesManager.h @@ -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,7 +70,7 @@ public: BackedDoubleBufferedTexture* getAvailableTexture(BaseTile* owner); void printLayersTextures(const char* s); - void cleanupLayersTextures(bool forceCleanup = false); + void cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup = false); LayerTexture* getExistingTextureForLayer(LayerAndroid* layer); LayerTexture* createTextureForLayer(LayerAndroid* layer); @@ -99,6 +104,8 @@ private: Vector<LayerTexture*> m_layersTextures; unsigned int m_layersMemoryUsage; + GLint m_maxTextureSize; + unsigned int m_totalMaxTextureSize; bool m_generatorReady; |