WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-76295-20120207145441.patch (text/plain), 102.06 KB, created by
David Reveman
on 2012-02-07 11:54:43 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
David Reveman
Created:
2012-02-07 11:54:43 PST
Size:
102.06 KB
patch
obsolete
>Subversion Revision: 106953 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index faf7cec90cf49c1e852aeb8ba0d5189db9b5c47f..bcb9f2a5f8b43a1396384fbaccdb04193997f1bf 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,178 @@ >+2012-02-07 David Reveman <reveman@chromium.org> >+ >+ [Chromium] Replace TextureManager eviction list with deferred texture allocator. >+ https://bugs.webkit.org/show_bug.cgi?id=76295 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Instead of implicitly deferring texture creation/deletion inside >+ TextureManager add an explicit deferred texture allocator that uses >+ fake texture IDs and makes it possible to defer texture creation >+ until use on impl thread. >+ >+ No new tests. >+ >+ * WebCore.gypi: >+ * platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.cpp: >+ (WebCore::BitmapCanvasLayerTextureUpdater::Texture::updateRect): >+ (WebCore::BitmapCanvasLayerTextureUpdater::updateTextureRect): >+ * platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h: >+ (Texture): >+ (BitmapCanvasLayerTextureUpdater): >+ * platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.cpp: >+ (WebCore::BitmapSkPictureCanvasLayerTextureUpdater::Texture::updateRect): >+ * platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h: >+ (Texture): >+ * platform/graphics/chromium/Canvas2DLayerChromium.cpp: >+ (WebCore::Canvas2DLayerChromium::updateCompositorResources): >+ (WebCore::Canvas2DLayerChromium::pushPropertiesTo): >+ * platform/graphics/chromium/DeferredTextureAllocator.cpp: Added. >+ (WebCore): >+ (WebCore::DeferredTextureAllocator::DeferredTextureAllocator): >+ (WebCore::DeferredTextureAllocator::~DeferredTextureAllocator): >+ (WebCore::DeferredTextureAllocator::createTexture): >+ (WebCore::DeferredTextureAllocator::deleteTexture): >+ (WebCore::DeferredTextureAllocatorBinding::DeferredTextureAllocatorBinding): >+ (WebCore::DeferredTextureAllocatorBinding::~DeferredTextureAllocatorBinding): >+ (WebCore::DeferredTextureAllocatorBinding::createTexture): >+ (WebCore::DeferredTextureAllocatorBinding::deleteTexture): >+ (WebCore::DeferredTextureAllocatorBinding::textureId): >+ * platform/graphics/chromium/DeferredTextureAllocator.h: Added. >+ (WebCore): >+ (DeferredTextureAllocator): >+ (WebCore::DeferredTextureAllocator::create): >+ (WebCore::DeferredTextureAllocator::deletedTextures): >+ (DeferredTextureAllocatorBinding): >+ (WebCore::DeferredTextureAllocatorBinding::create): >+ (TextureEntry): >+ * platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.cpp: >+ (WebCore::createAcceleratedCanvas): >+ (WebCore::FrameBufferSkPictureCanvasLayerTextureUpdater::Texture::updateRect): >+ (WebCore::FrameBufferSkPictureCanvasLayerTextureUpdater::updateTextureRect): >+ * platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h: >+ (Texture): >+ (FrameBufferSkPictureCanvasLayerTextureUpdater): >+ * platform/graphics/chromium/ImageLayerChromium.cpp: >+ (WebCore::ImageLayerTextureUpdater::Texture::updateRect): >+ (WebCore::ImageLayerTextureUpdater::updateTextureRect): >+ * platform/graphics/chromium/LayerRendererChromium.cpp: >+ (WebCore::LayerRendererChromium::create): >+ (WebCore::LayerRendererChromium::LayerRendererChromium): >+ (WebCore::LayerRendererChromium::releaseRenderSurfaceTextures): >+ (WebCore::LayerRendererChromium::drawTileQuad): >+ (WebCore::LayerRendererChromium::drawCanvasQuad): >+ (WebCore::LayerRendererChromium::finishDrawingFrame): >+ (WebCore::LayerRendererChromium::useRenderSurface): >+ (WebCore::LayerRendererChromium::initializeSharedObjects): >+ * platform/graphics/chromium/LayerRendererChromium.h: >+ (LayerRendererChromium): >+ (WebCore::LayerRendererChromium::contentsTextureAllocatorBinding): >+ * platform/graphics/chromium/LayerTextureUpdater.h: >+ (WebCore): >+ (Texture): >+ * platform/graphics/chromium/ManagedTexture.cpp: >+ (WebCore::ManagedTexture::bindTexture): >+ (WebCore::ManagedTexture::framebufferTexture2D): >+ * platform/graphics/chromium/ManagedTexture.h: >+ (WebCore): >+ (ManagedTexture): >+ * platform/graphics/chromium/TextureManager.cpp: >+ (WebCore::PassthroughTextureAllocatorBinding::PassthroughTextureAllocatorBinding): >+ (WebCore): >+ (WebCore::PassthroughTextureAllocatorBinding::~PassthroughTextureAllocatorBinding): >+ (WebCore::PassthroughTextureAllocatorBinding::createTexture): >+ (WebCore::PassthroughTextureAllocatorBinding::deleteTexture): >+ (WebCore::TextureManager::TextureManager): >+ (WebCore::TextureManager::replaceTexture): >+ (WebCore::TextureManager::deleteAllTextures): >+ (WebCore::TextureManager::removeTexture): >+ (WebCore::TextureManager::allocateTexture): >+ (WebCore::TextureManager::requestTexture): >+ * platform/graphics/chromium/TextureManager.h: >+ (WebCore::TextureAllocator::~TextureAllocator): >+ (TextureAllocator): >+ (WebCore::TextureAllocator::context): >+ (WebCore): >+ (TextureAllocatorBinding): >+ (WebCore::TextureAllocatorBinding::~TextureAllocatorBinding): >+ (PassthroughTextureAllocatorBinding): >+ (WebCore::PassthroughTextureAllocatorBinding::create): >+ (WebCore::PassthroughTextureAllocatorBinding::textureId): >+ (WebCore::TextureManager::create): >+ (TextureManager): >+ (WebCore::TextureManager::allocator): >+ (TextureInfo): >+ * platform/graphics/chromium/TrackingTextureAllocator.h: >+ (WebCore::TrackingTextureAllocator::create): >+ (TrackingTextureAllocator): >+ (WebCore::TrackingTextureAllocator::context): >+ * platform/graphics/chromium/cc/CCCanvasDrawQuad.cpp: >+ (WebCore::CCCanvasDrawQuad::create): >+ (WebCore::CCCanvasDrawQuad::CCCanvasDrawQuad): >+ * platform/graphics/chromium/cc/CCCanvasDrawQuad.h: >+ (CCCanvasDrawQuad): >+ (WebCore::CCCanvasDrawQuad::doubleBuffered): >+ * platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp: >+ (WebCore::CCCanvasLayerImpl::CCCanvasLayerImpl): >+ (WebCore::CCCanvasLayerImpl::appendQuads): >+ * platform/graphics/chromium/cc/CCCanvasLayerImpl.h: >+ (WebCore::CCCanvasLayerImpl::setDoubleBuffered): >+ (CCCanvasLayerImpl): >+ * platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp: >+ (WebCore::CCHeadsUpDisplay::draw): >+ * platform/graphics/chromium/cc/CCLayerTreeHost.cpp: >+ (WebCore::CCLayerTreeHost::initialize): >+ (WebCore::CCLayerTreeHost::initializeLayerRenderer): >+ (WebCore::CCLayerTreeHost::deleteContentsTexturesOnImplThread): >+ (WebCore::CCLayerTreeHost::beginCommitOnImplThread): >+ (WebCore::CCLayerTreeHost::didBecomeInvisibleOnImplThread): >+ * platform/graphics/chromium/cc/CCLayerTreeHost.h: >+ (CCLayerTreeHost): >+ * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp: >+ (WebCore::CCLayerTreeHostImpl::contentsTextureAllocatorBinding): >+ (WebCore): >+ (WebCore::CCLayerTreeHostImpl::initializeLayerRenderer): >+ * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h: >+ (WebCore): >+ (CCLayerTreeHostImpl): >+ * platform/graphics/chromium/cc/CCProxy.h: >+ (WebCore): >+ (CCProxy): >+ * platform/graphics/chromium/cc/CCRenderSurface.cpp: >+ (WebCore::CCRenderSurface::drawSurface): >+ * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp: >+ (WebCore::CCSingleThreadProxy::initializeLayerRenderer): >+ (WebCore::CCSingleThreadProxy::doCommit): >+ (WebCore::CCSingleThreadProxy::stop): >+ (WebCore::CCSingleThreadProxy::contentsTextureAllocator): >+ (WebCore): >+ (WebCore::CCSingleThreadProxy::recreateContextIfNeeded): >+ * platform/graphics/chromium/cc/CCSingleThreadProxy.h: >+ (CCSingleThreadProxy): >+ * platform/graphics/chromium/cc/CCTextureUpdater.cpp: >+ (WebCore::CCTextureUpdater::CCTextureUpdater): >+ (WebCore::CCTextureUpdater::update): >+ * platform/graphics/chromium/cc/CCTextureUpdater.h: >+ (WebCore): >+ (CCTextureUpdater): >+ (WebCore::CCTextureUpdater::allocatorBinding): >+ * platform/graphics/chromium/cc/CCThreadProxy.cpp: >+ (WebCore::CCThreadProxy::CCThreadProxy): >+ (WebCore::CCThreadProxy::beginFrameAndCommit): >+ (WebCore::CCThreadProxy::contentsTextureAllocator): >+ (WebCore): >+ (WebCore::CCThreadProxy::beginFrameCompleteOnImplThread): >+ (WebCore::CCThreadProxy::scheduledActionCommit): >+ (WebCore::CCThreadProxy::initializeLayerRendererOnImplThread): >+ (WebCore::CCThreadProxy::layerTreeHostClosedOnImplThread): >+ * platform/graphics/chromium/cc/CCThreadProxy.h: >+ (WebCore): >+ (CCThreadProxy): >+ * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp: >+ (WebCore::CCTiledLayerImpl::bindContentsTexture): >+ * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp: >+ (WebCore::CCVideoLayerImpl::copyPlaneToTexture): >+ > 2012-02-07 Pavel Feldman <pfeldman@google.com> > > Web Inspector: add generic support for undo-ing DOM edits. >diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog >index 213dcfc430b0327c6fdd4f972d2c024cf60285d6..87396a184579e0efff3f00b8d0d038ea4fd1957f 100644 >--- a/Source/WebKit/chromium/ChangeLog >+++ b/Source/WebKit/chromium/ChangeLog >@@ -1,3 +1,31 @@ >+2012-02-07 David Reveman <reveman@chromium.org> >+ >+ [Chromium] Replace TextureManager eviction list with deferred texture allocator. >+ https://bugs.webkit.org/show_bug.cgi?id=76295 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Track changes to TextureManager. >+ >+ * tests/CCLayerTreeHostImplTest.cpp: >+ (WebKit::TEST_F): >+ * tests/Canvas2DLayerChromiumTest.cpp: >+ (WebCore::Canvas2DLayerChromiumTest::fullLifecycleTest): >+ * tests/TextureManagerTest.cpp: >+ (WTF::FakeTextureAllocator::create): >+ (FakeTextureAllocator): >+ (WTF::FakeTextureAllocator::FakeTextureAllocator): >+ (WTF::TextureManagerTest::TextureManagerTest): >+ (WTF::TextureManagerTest::createTextureManager): >+ (WTF::TextureManagerTest::requestTexture): >+ (TextureManagerTest): >+ * tests/TiledLayerChromiumTest.cpp: >+ (WTF::FakeTextureAllocator::create): >+ (FakeTextureAllocator): >+ (WTF::FakeTextureAllocator::FakeTextureAllocator): >+ (WTF::FakeLayerTextureUpdater::Texture::updateRect): >+ (WTF::TEST): >+ > 2012-02-07 Sheriff Bot <webkit.review.bot@gmail.com> > > Unreviewed, rolling out r106935. >diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi >index 07a340f8b62ff141ea7bfd547397517695ce6334..4d0405b619d80038143af89c4ef13f98d4da43ed 100644 >--- a/Source/WebCore/WebCore.gypi >+++ b/Source/WebCore/WebCore.gypi >@@ -3141,6 +3141,8 @@ > 'platform/graphics/chromium/ContentLayerChromium.h', > 'platform/graphics/chromium/CrossProcessFontLoading.h', > 'platform/graphics/chromium/CrossProcessFontLoading.mm', >+ 'platform/graphics/chromium/DeferredTextureAllocator.cpp', >+ 'platform/graphics/chromium/DeferredTextureAllocator.h', > 'platform/graphics/chromium/DrawingBufferChromium.cpp', > 'platform/graphics/chromium/Extensions3DChromium.h', > 'platform/graphics/chromium/FontCacheAndroid.cpp', >diff --git a/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.cpp b/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.cpp >index 0d97e52aede0f980ada15de0a14a1d28d86a1e88..37c254af07c4fded4d0f4202922170e966b74ce0 100644 >--- a/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.cpp >+++ b/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.cpp >@@ -46,9 +46,10 @@ BitmapCanvasLayerTextureUpdater::Texture::~Texture() > { > } > >-void BitmapCanvasLayerTextureUpdater::Texture::updateRect(GraphicsContext3D* context, TextureAllocator* allocator, const IntRect& sourceRect, const IntRect& destRect) >+void BitmapCanvasLayerTextureUpdater::Texture::updateRect(GraphicsContext3D* context, TextureAllocatorBinding* binding, const IntRect& sourceRect, const IntRect& destRect) > { >- textureUpdater()->updateTextureRect(context, allocator, texture(), sourceRect, destRect); >+ texture()->bindTexture(context, binding); >+ textureUpdater()->updateTextureRect(context, texture(), sourceRect, destRect); > } > > PassRefPtr<BitmapCanvasLayerTextureUpdater> BitmapCanvasLayerTextureUpdater::create(PassOwnPtr<LayerPainterChromium> painter, bool useMapTexSubImage) >@@ -98,11 +99,10 @@ void BitmapCanvasLayerTextureUpdater::prepareToUpdate(const IntRect& contentRect > *resultingOpaqueRect = canvasPainter.skiaContext()->opaqueRegion().asRect(); > } > >-void BitmapCanvasLayerTextureUpdater::updateTextureRect(GraphicsContext3D* context, TextureAllocator* allocator, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect) >+void BitmapCanvasLayerTextureUpdater::updateTextureRect(GraphicsContext3D* context, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect) > { > PlatformCanvas::AutoLocker locker(&m_canvas); > >- texture->bindTexture(context, allocator); > m_texSubImage.upload(locker.pixels(), contentRect(), sourceRect, destRect, texture->format(), context); > } > >diff --git a/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h >index 4e162295b86e00893c33ef03d4b62d2c1e52bd5f..07832e1baca17ece6033582ef1a824d542fdf207 100644 >--- a/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h >+++ b/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h >@@ -47,7 +47,7 @@ public: > Texture(BitmapCanvasLayerTextureUpdater*, PassOwnPtr<ManagedTexture>); > virtual ~Texture(); > >- virtual void updateRect(GraphicsContext3D*, TextureAllocator*, const IntRect& sourceRect, const IntRect& destRect); >+ virtual void updateRect(GraphicsContext3D*, TextureAllocatorBinding*, const IntRect& sourceRect, const IntRect& destRect); > > private: > BitmapCanvasLayerTextureUpdater* textureUpdater() { return m_textureUpdater; } >@@ -61,7 +61,7 @@ public: > virtual PassOwnPtr<LayerTextureUpdater::Texture> createTexture(TextureManager*); > virtual SampledTexelFormat sampledTexelFormat(GC3Denum textureFormat); > virtual void prepareToUpdate(const IntRect& contentRect, const IntSize& tileSize, int borderTexels, float contentsScale, IntRect* resultingOpaqueRect); >- void updateTextureRect(GraphicsContext3D*, TextureAllocator*, ManagedTexture*, const IntRect& sourceRect, const IntRect& destRect); >+ void updateTextureRect(GraphicsContext3D*, ManagedTexture*, const IntRect& sourceRect, const IntRect& destRect); > > virtual void setOpaque(bool); > >diff --git a/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.cpp b/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.cpp >index e2ab798386fccf07013d66bb3f28fe7d8f4ec27c..bcc4adafc71ed8ba865936055e040b30983423c4 100644 >--- a/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.cpp >+++ b/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.cpp >@@ -51,9 +51,9 @@ void BitmapSkPictureCanvasLayerTextureUpdater::Texture::prepareRect(const IntRec > textureUpdater()->paintContentsRect(canvas.get(), sourceRect); > } > >-void BitmapSkPictureCanvasLayerTextureUpdater::Texture::updateRect(GraphicsContext3D* context, TextureAllocator* allocator, const IntRect& sourceRect, const IntRect& destRect) >+void BitmapSkPictureCanvasLayerTextureUpdater::Texture::updateRect(GraphicsContext3D* context, TextureAllocatorBinding* binding, const IntRect& sourceRect, const IntRect& destRect) > { >- texture()->bindTexture(context, allocator); >+ texture()->bindTexture(context, binding); > ASSERT(m_pixelData.get()); > textureUpdater()->updateTextureRect(context, texture()->format(), destRect, m_pixelData.get()); > m_pixelData.clear(); >diff --git a/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h >index 1c564cdc183ea49591f6906efebd3a8d9b5f80cc..e4db95b30cd018235cd1a91873fab28d492473df 100644 >--- a/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h >+++ b/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h >@@ -45,7 +45,7 @@ public: > Texture(BitmapSkPictureCanvasLayerTextureUpdater*, PassOwnPtr<ManagedTexture>); > > virtual void prepareRect(const IntRect& sourceRect); >- virtual void updateRect(GraphicsContext3D*, TextureAllocator*, const IntRect& sourceRect, const IntRect& destRect); >+ virtual void updateRect(GraphicsContext3D*, TextureAllocatorBinding*, const IntRect& sourceRect, const IntRect& destRect); > > private: > BitmapSkPictureCanvasLayerTextureUpdater* textureUpdater() { return m_textureUpdater; } >diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp >index 14fe35a5805f6fd07f337434ef4595f479547760..3bd769caddbf9819b00fde347138edf2e947d45f 100644 >--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp >+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp >@@ -138,7 +138,7 @@ void Canvas2DLayerChromium::updateCompositorResources(GraphicsContext3D* context > if (!m_backTextureId || !m_frontTexture || !m_frontTexture->isValid(m_size, GraphicsContext3D::RGBA)) > return; > >- m_frontTexture->bindTexture(context, updater.allocator()); >+ m_frontTexture->bindTexture(context, updater.allocatorBinding()); > > GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo)); > GLC(context, context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_backTextureId, 0)); >@@ -154,6 +154,7 @@ void Canvas2DLayerChromium::pushPropertiesTo(CCLayerImpl* layer) > CanvasLayerChromium::pushPropertiesTo(layer); > > CCCanvasLayerImpl* canvasLayer = static_cast<CCCanvasLayerImpl*>(layer); >+ canvasLayer->setDoubleBuffered(m_useDoubleBuffering); > if (m_useDoubleBuffering) > canvasLayer->setTextureId(m_frontTexture->textureId()); > else >diff --git a/Source/WebCore/platform/graphics/chromium/DeferredTextureAllocator.cpp b/Source/WebCore/platform/graphics/chromium/DeferredTextureAllocator.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..bf238d807dbc76bf06b68c44b7be567e7d873c97 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/chromium/DeferredTextureAllocator.cpp >@@ -0,0 +1,91 @@ >+/* >+ * Copyright (C) 2012, Google Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON >+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+ >+#include "DeferredTextureAllocator.h" >+ >+namespace WebCore { >+ >+DeferredTextureAllocator::DeferredTextureAllocator() >+ : m_nextTextureId(1) >+{ >+} >+ >+DeferredTextureAllocator::~DeferredTextureAllocator() >+{ >+} >+ >+unsigned DeferredTextureAllocator::createTexture(const IntSize& size, GC3Denum format) >+{ >+ return m_nextTextureId++; >+} >+ >+void DeferredTextureAllocator::deleteTexture(unsigned textureId, const IntSize& size, GC3Denum format) >+{ >+ m_deletedTextures.append(textureId); >+} >+ >+DeferredTextureAllocatorBinding::DeferredTextureAllocatorBinding(PassRefPtr<TextureAllocator> allocator) >+ : m_allocator(allocator) >+{ >+} >+ >+DeferredTextureAllocatorBinding::~DeferredTextureAllocatorBinding() >+{ >+ TextureMap::iterator it = m_textures.begin(); >+ for (; it != m_textures.end(); ++it) >+ m_allocator->deleteTexture(it->second.textureId, it->second.size, it->second.format); >+} >+ >+unsigned DeferredTextureAllocatorBinding::createTexture(unsigned texture, const IntSize& size, GC3Denum format) >+{ >+ unsigned textureId = m_allocator->createTexture(size, format); >+ TextureEntry entry; >+ entry.textureId = textureId; >+ entry.size = size; >+ entry.format = format; >+ m_textures.add(texture, entry); >+ return textureId; >+} >+ >+void DeferredTextureAllocatorBinding::deleteTexture(unsigned texture) >+{ >+ TextureMap::iterator it = m_textures.find(texture); >+ if (it != m_textures.end()) { >+ m_allocator->deleteTexture(it->second.textureId, it->second.size, it->second.format); >+ m_textures.remove(it); >+ } >+} >+ >+unsigned DeferredTextureAllocatorBinding::textureId(unsigned texture) >+{ >+ TextureMap::iterator it = m_textures.find(texture); >+ if (it == m_textures.end()) >+ return 0; >+ >+ return it->second.textureId; >+} >+ >+} >diff --git a/Source/WebCore/platform/graphics/chromium/DeferredTextureAllocator.h b/Source/WebCore/platform/graphics/chromium/DeferredTextureAllocator.h >new file mode 100644 >index 0000000000000000000000000000000000000000..97edb61f2066aaab236a7118a7908e31051684d4 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/chromium/DeferredTextureAllocator.h >@@ -0,0 +1,86 @@ >+/* >+ * Copyright (C) 2012, Google Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON >+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef DeferredTextureAllocator_h >+#define DeferredTextureAllocator_h >+ >+#include "TextureManager.h" >+#include <wtf/PassRefPtr.h> >+ >+namespace WebCore { >+ >+// Texture allocator that generates uses fake texture IDs and allows >+// real texture ID creation to be deferred. >+class DeferredTextureAllocator : public TextureAllocator { >+ WTF_MAKE_NONCOPYABLE(DeferredTextureAllocator); >+public: >+ static PassRefPtr<DeferredTextureAllocator> create() >+ { >+ return adoptRef(new DeferredTextureAllocator()); >+ } >+ virtual ~DeferredTextureAllocator(); >+ >+ virtual unsigned createTexture(const IntSize&, GC3Denum format); >+ virtual void deleteTexture(unsigned texture, const IntSize&, GC3Denum format); >+ >+ Vector<unsigned>& deletedTextures() { return m_deletedTextures; } >+ >+protected: >+ DeferredTextureAllocator(); >+ >+ unsigned m_nextTextureId; >+ >+ Vector<unsigned> m_deletedTextures; >+}; >+ >+// Binds texture IDs generated by a deferred texture allocator to >+// texture IDs generated by a different texture allocator. >+class DeferredTextureAllocatorBinding : public TextureAllocatorBinding { >+public: >+ static PassOwnPtr<DeferredTextureAllocatorBinding> create(PassRefPtr<TextureAllocator> allocator) >+ { >+ return adoptPtr(new DeferredTextureAllocatorBinding(allocator)); >+ } >+ virtual ~DeferredTextureAllocatorBinding(); >+ >+ virtual unsigned createTexture(unsigned texture, const IntSize&, GC3Denum format); >+ virtual void deleteTexture(unsigned texture); >+ virtual unsigned textureId(unsigned texture); >+ >+private: >+ explicit DeferredTextureAllocatorBinding(PassRefPtr<TextureAllocator>); >+ >+ struct TextureEntry { >+ unsigned textureId; >+ IntSize size; >+ GC3Denum format; >+ }; >+ typedef HashMap<unsigned, TextureEntry> TextureMap; >+ TextureMap m_textures; >+ RefPtr<TextureAllocator> m_allocator; >+}; >+ >+} >+ >+#endif >diff --git a/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.cpp b/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.cpp >index 19dfa2f006c9884770e676c4585be9467134f3b3..ec3650fc939b8664522c85c29b6edc2bf858eba9 100644 >--- a/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.cpp >+++ b/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.cpp >@@ -38,11 +38,12 @@ > namespace WebCore { > > static PassOwnPtr<SkCanvas> createAcceleratedCanvas(GraphicsContext3D* context, >- TextureAllocator* allocator, >+ TextureAllocatorBinding* binding, > ManagedTexture* texture) > { >- // Allocate so that we have a valid texture id. >- texture->allocate(allocator); >+ unsigned textureId = binding->textureId(texture->textureId()); >+ if (!textureId) >+ textureId = binding->createTexture(texture->textureId(), texture->size(), texture->format()); > > GrContext* grContext = context->grContext(); > IntSize canvasSize = texture->size(); >@@ -51,7 +52,7 @@ static PassOwnPtr<SkCanvas> createAcceleratedCanvas(GraphicsContext3D* context, > textureDesc.fWidth = canvasSize.width(); > textureDesc.fHeight = canvasSize.height(); > textureDesc.fConfig = kRGBA_8888_GrPixelConfig; >- textureDesc.fTextureHandle = texture->textureId(); >+ textureDesc.fTextureHandle = textureId; > SkAutoTUnref<GrTexture> target(grContext->createPlatformTexture(textureDesc)); > SkAutoTUnref<SkDevice> device(new SkGpuDevice(grContext, target.get())); > return adoptPtr(new SkCanvas(device.get())); >@@ -67,9 +68,9 @@ FrameBufferSkPictureCanvasLayerTextureUpdater::Texture::~Texture() > { > } > >-void FrameBufferSkPictureCanvasLayerTextureUpdater::Texture::updateRect(GraphicsContext3D* context, TextureAllocator* allocator, const IntRect& sourceRect, const IntRect& destRect) >+void FrameBufferSkPictureCanvasLayerTextureUpdater::Texture::updateRect(GraphicsContext3D* context, TextureAllocatorBinding* binding, const IntRect& sourceRect, const IntRect& destRect) > { >- textureUpdater()->updateTextureRect(context, allocator, texture(), sourceRect, destRect); >+ textureUpdater()->updateTextureRect(context, binding, texture(), sourceRect, destRect); > } > > PassRefPtr<FrameBufferSkPictureCanvasLayerTextureUpdater> FrameBufferSkPictureCanvasLayerTextureUpdater::create(PassOwnPtr<LayerPainterChromium> painter) >@@ -97,7 +98,7 @@ LayerTextureUpdater::SampledTexelFormat FrameBufferSkPictureCanvasLayerTextureUp > return LayerTextureUpdater::SampledTexelFormatRGBA; > } > >-void FrameBufferSkPictureCanvasLayerTextureUpdater::updateTextureRect(GraphicsContext3D* context, TextureAllocator* allocator, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect) >+void FrameBufferSkPictureCanvasLayerTextureUpdater::updateTextureRect(GraphicsContext3D* context, TextureAllocatorBinding* binding, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect) > { > // Make sure SKIA uses the correct GL context. > context->makeContextCurrent(); >@@ -105,7 +106,7 @@ void FrameBufferSkPictureCanvasLayerTextureUpdater::updateTextureRect(GraphicsCo > context->grContext()->resetContext(); > > // Create an accelerated canvas to draw on. >- OwnPtr<SkCanvas> canvas = createAcceleratedCanvas(context, allocator, texture); >+ OwnPtr<SkCanvas> canvas = createAcceleratedCanvas(context, binding, texture); > > canvas->clipRect(SkRect(destRect)); > // The compositor expects the textures to be upside-down so it can flip >diff --git a/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h >index 4a10c858e4cda8c252ac16dfa07d09a5d908eec3..b45707f2dd8ccf19506d66fd3177f435734c4539 100644 >--- a/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h >+++ b/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h >@@ -44,7 +44,7 @@ public: > Texture(FrameBufferSkPictureCanvasLayerTextureUpdater*, PassOwnPtr<ManagedTexture>); > virtual ~Texture(); > >- virtual void updateRect(GraphicsContext3D*, TextureAllocator*, const IntRect& sourceRect, const IntRect& destRect); >+ virtual void updateRect(GraphicsContext3D*, TextureAllocatorBinding*, const IntRect& sourceRect, const IntRect& destRect); > > private: > FrameBufferSkPictureCanvasLayerTextureUpdater* textureUpdater() { return m_textureUpdater; } >@@ -57,7 +57,7 @@ public: > > virtual PassOwnPtr<LayerTextureUpdater::Texture> createTexture(TextureManager*); > virtual SampledTexelFormat sampledTexelFormat(GC3Denum textureFormat); >- void updateTextureRect(GraphicsContext3D*, TextureAllocator*, ManagedTexture*, const IntRect& sourceRect, const IntRect& destRect); >+ void updateTextureRect(GraphicsContext3D*, TextureAllocatorBinding*, ManagedTexture*, const IntRect& sourceRect, const IntRect& destRect); > > private: > explicit FrameBufferSkPictureCanvasLayerTextureUpdater(PassOwnPtr<LayerPainterChromium>); >diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp >index 1e44e87023fed5f46935df7c3fbd362e54ab0429..62d37b701b403a9918ebc048c665f31622f38149 100644 >--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp >+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp >@@ -54,9 +54,11 @@ public: > { > } > >- virtual void updateRect(GraphicsContext3D* context, TextureAllocator* allocator, const IntRect& sourceRect, const IntRect& destRect) >+ virtual void updateRect(GraphicsContext3D* context, TextureAllocatorBinding* binding, const IntRect& sourceRect, const IntRect& destRect) > { >- textureUpdater()->updateTextureRect(context, allocator, texture(), sourceRect, destRect); >+ texture()->bindTexture(context, binding); >+ context->bindTexture(GraphicsContext3D::TEXTURE_2D, binding->textureId(texture()->textureId())); >+ textureUpdater()->updateTextureRect(context, texture(), sourceRect, destRect); > } > > private: >@@ -88,10 +90,8 @@ public: > m_texSubImage.setSubImageSize(tileSize); > } > >- virtual void updateTextureRect(GraphicsContext3D* context, TextureAllocator* allocator, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect) >+ virtual void updateTextureRect(GraphicsContext3D* context, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect) > { >- texture->bindTexture(context, allocator); >- > // Source rect should never go outside the image pixels, even if this > // is requested because the texture extends outside the image. > IntRect clippedSourceRect = sourceRect; >diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp >index bae4da354119b6719760cab1effedd4934f70405..5bb4d7b6aa56e63a22b4ab8e76e5cbe73cff3d2a 100644 >--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp >+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp >@@ -160,9 +160,9 @@ private: > }; > > >-PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(CCLayerTreeHostImpl* owner, PassRefPtr<GraphicsContext3D> context) >+PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(CCLayerTreeHostImpl* owner, PassRefPtr<GraphicsContext3D> context, PassRefPtr<TrackingTextureAllocator> contentsTextureAllocator, PassOwnPtr<TextureAllocatorBinding> contentsTextureAllocatorBinding) > { >- OwnPtr<LayerRendererChromium> layerRenderer(adoptPtr(new LayerRendererChromium(owner, context))); >+ OwnPtr<LayerRendererChromium> layerRenderer(adoptPtr(new LayerRendererChromium(owner, context, contentsTextureAllocator, contentsTextureAllocatorBinding))); > if (!layerRenderer->initialize()) > return nullptr; > >@@ -170,10 +170,14 @@ PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(CCLayerTreeHostI > } > > LayerRendererChromium::LayerRendererChromium(CCLayerTreeHostImpl* owner, >- PassRefPtr<GraphicsContext3D> context) >+ PassRefPtr<GraphicsContext3D> context, >+ PassRefPtr<TrackingTextureAllocator> contentsTextureAllocator, >+ PassOwnPtr<TextureAllocatorBinding> contentsTextureAllocatorBinding) > : m_owner(owner) > , m_currentRenderSurface(0) > , m_offscreenFramebufferId(0) >+ , m_contentsTextureAllocator(contentsTextureAllocator) >+ , m_contentsTextureAllocatorBinding(contentsTextureAllocatorBinding) > , m_context(context) > , m_defaultRenderSurface(0) > , m_sharedGeometryQuad(FloatRect(-0.5f, -0.5f, 1.0f, 1.0f)) >@@ -294,7 +298,7 @@ void LayerRendererChromium::setVisible(bool visible) > void LayerRendererChromium::releaseRenderSurfaceTextures() > { > if (m_renderSurfaceTextureManager) >- m_renderSurfaceTextureManager->evictAndDeleteAllTextures(m_renderSurfaceTextureAllocator.get()); >+ m_renderSurfaceTextureManager->deleteAllTextures(); > } > > void LayerRendererChromium::viewportChanged() >@@ -579,7 +583,7 @@ void LayerRendererChromium::drawTileQuad(const CCTileDrawQuad* quad) > GLC(context(), context()->useProgram(uniforms.program)); > GLC(context(), context()->uniform1i(uniforms.samplerLocation, 0)); > GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0)); >- GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, quad->textureId())); >+ GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, contentsTextureAllocatorBinding()->textureId(quad->textureId()))); > GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, quad->textureFilter())); > GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, quad->textureFilter())); > >@@ -672,7 +676,8 @@ void LayerRendererChromium::drawCanvasQuad(const CCCanvasDrawQuad* quad) > const CCCanvasLayerImpl::Program* program = canvasLayerProgram(); > ASSERT(program && program->initialized()); > GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0)); >- GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, quad->textureId())); >+ Platform3DObject textureId = quad->doubleBuffered() ? contentsTextureAllocatorBinding()->textureId(quad->textureId()) : quad->textureId(); >+ GLC(context(), context()->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); > GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); > GLC(context(), context()->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); > >@@ -803,7 +808,6 @@ void LayerRendererChromium::finishDrawingFrame() > size_t preferredLimit = reclaimLimit > contentsMemoryUseBytes ? reclaimLimit - contentsMemoryUseBytes : 0; > m_renderSurfaceTextureManager->setPreferredMemoryLimitBytes(preferredLimit); > m_renderSurfaceTextureManager->reduceMemoryToLimit(preferredLimit); >- m_renderSurfaceTextureManager->deleteEvictedTextures(m_renderSurfaceTextureAllocator.get()); > > if (settings().compositeOffscreen) > copyOffscreenTextureToDisplay(); >@@ -948,7 +952,7 @@ bool LayerRendererChromium::useRenderSurface(CCRenderSurface* renderSurface) > if (!renderSurface->prepareContentsTexture(this)) > return false; > >- renderSurface->contentsTexture()->framebufferTexture2D(m_context.get(), m_renderSurfaceTextureAllocator.get()); >+ renderSurface->contentsTexture()->framebufferTexture2D(m_context.get()); > > #if !defined ( NDEBUG ) > if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) { >@@ -1020,17 +1024,15 @@ bool LayerRendererChromium::initializeSharedObjects() > > GLC(m_context.get(), m_context->flush()); > >- m_renderSurfaceTextureManager = TextureManager::create(TextureManager::highLimitBytes(viewportSize()), >+ m_renderSurfaceTextureAllocator = TrackingTextureAllocator::create(m_context.get()); >+ m_renderSurfaceTextureManager = TextureManager::create(m_renderSurfaceTextureAllocator, >+ TextureManager::highLimitBytes(viewportSize()), > TextureManager::reclaimLimitBytes(viewportSize()), > m_capabilities.maxTextureSize); >- m_contentsTextureAllocator = TrackingTextureAllocator::create(m_context.get()); >- m_renderSurfaceTextureAllocator = TrackingTextureAllocator::create(m_context.get()); > if (m_capabilities.usingTextureUsageHint) > m_renderSurfaceTextureAllocator->setTextureUsageHint(TrackingTextureAllocator::FramebufferAttachment); >- if (m_capabilities.usingTextureStorageExtension) { >- m_contentsTextureAllocator->setUseTextureStorageExt(true); >+ if (m_capabilities.usingTextureStorageExtension) > m_renderSurfaceTextureAllocator->setUseTextureStorageExt(true); >- } > > return true; > } >diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h >index 4bcb2582864ef2ee44fb10d0a50019678b9584ee..ee01c95bce793fc65028ff1031bbb92968e749ec 100644 >--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h >+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h >@@ -71,7 +71,7 @@ class LayerRendererSwapBuffersCompleteCallbackAdapter; > class LayerRendererChromium { > WTF_MAKE_NONCOPYABLE(LayerRendererChromium); > public: >- static PassOwnPtr<LayerRendererChromium> create(CCLayerTreeHostImpl*, PassRefPtr<GraphicsContext3D>); >+ static PassOwnPtr<LayerRendererChromium> create(CCLayerTreeHostImpl*, PassRefPtr<GraphicsContext3D>, PassRefPtr<TrackingTextureAllocator>, PassOwnPtr<TextureAllocatorBinding>); > > // Must be called in order to allow the LayerRendererChromium to destruct > void close(); >@@ -136,6 +136,7 @@ public: > TextureManager* renderSurfaceTextureManager() const { return m_renderSurfaceTextureManager.get(); } > TextureAllocator* renderSurfaceTextureAllocator() const { return m_renderSurfaceTextureAllocator.get(); } > TextureAllocator* contentsTextureAllocator() const { return m_contentsTextureAllocator.get(); } >+ TextureAllocatorBinding* contentsTextureAllocatorBinding() { return m_contentsTextureAllocatorBinding.get(); } > > CCHeadsUpDisplay* headsUpDisplay() { return m_headsUpDisplay.get(); } > >@@ -155,7 +156,7 @@ public: > int matrixLocation, int alphaLocation, int quadLocation); > > private: >- LayerRendererChromium(CCLayerTreeHostImpl*, PassRefPtr<GraphicsContext3D>); >+ LayerRendererChromium(CCLayerTreeHostImpl*, PassRefPtr<GraphicsContext3D>, PassRefPtr<TrackingTextureAllocator>, PassOwnPtr<TextureAllocatorBinding>); > bool initialize(); > > void drawQuad(const CCDrawQuad*, const FloatRect& surfaceDamageRect); >@@ -228,8 +229,9 @@ private: > OwnPtr<CCVideoLayerImpl::NativeTextureProgram> m_videoLayerNativeTextureProgram; > > OwnPtr<TextureManager> m_renderSurfaceTextureManager; >- OwnPtr<TrackingTextureAllocator> m_contentsTextureAllocator; >- OwnPtr<TrackingTextureAllocator> m_renderSurfaceTextureAllocator; >+ RefPtr<TrackingTextureAllocator> m_renderSurfaceTextureAllocator; >+ RefPtr<TrackingTextureAllocator> m_contentsTextureAllocator; >+ OwnPtr<TextureAllocatorBinding> m_contentsTextureAllocatorBinding; > > OwnPtr<CCHeadsUpDisplay> m_headsUpDisplay; > >diff --git a/Source/WebCore/platform/graphics/chromium/LayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/LayerTextureUpdater.h >index 179fea6e12bf103c5b07435cf24a3a48f8cd9323..191362087eb68872a11f0bde7e1e5fc7e793eb54 100644 >--- a/Source/WebCore/platform/graphics/chromium/LayerTextureUpdater.h >+++ b/Source/WebCore/platform/graphics/chromium/LayerTextureUpdater.h >@@ -38,7 +38,6 @@ namespace WebCore { > class GraphicsContext3D; > class IntRect; > class IntSize; >-class TextureAllocator; > class TextureManager; > > class LayerTextureUpdater : public RefCounted<LayerTextureUpdater> { >@@ -50,7 +49,7 @@ public: > > ManagedTexture* texture() { return m_texture.get(); } > virtual void prepareRect(const IntRect& /* sourceRect */) { } >- virtual void updateRect(GraphicsContext3D*, TextureAllocator*, const IntRect& sourceRect, const IntRect& destRect) = 0; >+ virtual void updateRect(GraphicsContext3D*, TextureAllocatorBinding*, const IntRect& sourceRect, const IntRect& destRect) = 0; > protected: > explicit Texture(PassOwnPtr<ManagedTexture> texture) : m_texture(texture) { } > >diff --git a/Source/WebCore/platform/graphics/chromium/ManagedTexture.cpp b/Source/WebCore/platform/graphics/chromium/ManagedTexture.cpp >index b29db0ed9e28dc6d0ef3f790a455b1d2b1f10089..adc7b6736dc080ee56376000b136032c863a41aa 100644 >--- a/Source/WebCore/platform/graphics/chromium/ManagedTexture.cpp >+++ b/Source/WebCore/platform/graphics/chromium/ManagedTexture.cpp >@@ -110,22 +110,24 @@ void ManagedTexture::unreserve() > m_textureManager->unprotectTexture(m_token); > } > >-void ManagedTexture::allocate(TextureAllocator* allocator) >+void ManagedTexture::bindTexture(GraphicsContext3D* context) > { >- ASSERT(m_textureManager->hasTexture(m_token)); >- if (!m_textureId) >- m_textureId = m_textureManager->allocateTexture(allocator, m_token); >+ ASSERT(context == m_textureManager->allocator()->context()); >+ context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); > } > >-void ManagedTexture::bindTexture(GraphicsContext3D* context, TextureAllocator* allocator) >+void ManagedTexture::bindTexture(GraphicsContext3D* context, TextureAllocatorBinding* binding) > { >- allocate(allocator); >- context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); >+ unsigned texture = binding->textureId(m_textureId); >+ if (!texture) >+ texture = binding->createTexture(m_textureId, m_size, m_format); >+ >+ context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture); > } > >-void ManagedTexture::framebufferTexture2D(GraphicsContext3D* context, TextureAllocator* allocator) >+void ManagedTexture::framebufferTexture2D(GraphicsContext3D* context) > { >- allocate(allocator); >+ ASSERT(context == m_textureManager->allocator()->context()); > context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_textureId, 0); > } > >diff --git a/Source/WebCore/platform/graphics/chromium/ManagedTexture.h b/Source/WebCore/platform/graphics/chromium/ManagedTexture.h >index ed4d450e969ce0ab547a9ac5138d4c093d839d62..6c4959c2772d6e86c7e71fc61a0f62f4b8fb7ed7 100644 >--- a/Source/WebCore/platform/graphics/chromium/ManagedTexture.h >+++ b/Source/WebCore/platform/graphics/chromium/ManagedTexture.h >@@ -36,6 +36,7 @@ > namespace WebCore { > > class GraphicsContext3D; >+class TextureAllocatorBinding; > > class ManagedTexture { > WTF_MAKE_NONCOPYABLE(ManagedTexture); >@@ -57,9 +58,9 @@ public: > return m_textureManager && m_textureManager->isProtected(m_token); > } > >- void allocate(TextureAllocator*); >- void bindTexture(GraphicsContext3D*, TextureAllocator*); >- void framebufferTexture2D(GraphicsContext3D*, TextureAllocator*); >+ void bindTexture(GraphicsContext3D*); >+ void bindTexture(GraphicsContext3D*, TextureAllocatorBinding*); >+ void framebufferTexture2D(GraphicsContext3D*); > > IntSize size() const { return m_size; } > unsigned format() const { return m_format; } >diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp >index f50af47ede5fae87a19a8de19057edf243f7db9f..5f120551e2eccd97cb5af83dad9e8c4e9b8e25df 100644 >--- a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp >+++ b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp >@@ -35,6 +35,24 @@ using namespace std; > > namespace WebCore { > >+PassthroughTextureAllocatorBinding::PassthroughTextureAllocatorBinding() >+{ >+} >+ >+PassthroughTextureAllocatorBinding::~PassthroughTextureAllocatorBinding() >+{ >+} >+ >+unsigned PassthroughTextureAllocatorBinding::createTexture(unsigned texture, const IntSize&, GC3Denum format) >+{ >+ ASSERT_NOT_REACHED(); >+ return 0; >+} >+ >+void PassthroughTextureAllocatorBinding::deleteTexture(unsigned texture) >+{ >+ ASSERT_NOT_REACHED(); >+} > > namespace { > size_t memoryLimitBytes(size_t viewportMultiplier, const IntSize& viewportSize, size_t minMegabytes, size_t maxMegabytes) >@@ -95,12 +113,13 @@ size_t TextureManager::memoryUseBytes(const IntSize& size, GC3Denum textureForma > } > > >-TextureManager::TextureManager(size_t maxMemoryLimitBytes, size_t preferredMemoryLimitBytes, int maxTextureSize) >+TextureManager::TextureManager(PassRefPtr<TextureAllocator> allocator, size_t maxMemoryLimitBytes, size_t preferredMemoryLimitBytes, int maxTextureSize) > : m_maxMemoryLimitBytes(maxMemoryLimitBytes) > , m_preferredMemoryLimitBytes(preferredMemoryLimitBytes) > , m_memoryUseBytes(0) > , m_maxTextureSize(maxTextureSize) > , m_nextToken(1) >+ , m_allocator(allocator) > { > } > >@@ -215,9 +234,6 @@ unsigned TextureManager::replaceTexture(TextureToken newToken, TextureInfo newIn > if (newInfo.size != info.size || newInfo.format != info.format) > continue; > newInfo.textureId = info.textureId; >-#ifndef NDEBUG >- newInfo.allocator = info.allocator; >-#endif > m_textures.remove(token); > m_textureLRUSet.remove(token); > m_textures.set(newToken, newInfo); >@@ -236,26 +252,10 @@ void TextureManager::addTexture(TextureToken token, TextureInfo info) > m_textureLRUSet.add(token); > } > >-void TextureManager::deleteEvictedTextures(TextureAllocator* allocator) >-{ >- if (allocator) { >- for (size_t i = 0; i < m_evictedTextures.size(); ++i) { >- if (m_evictedTextures[i].textureId) { >-#ifndef NDEBUG >- ASSERT(m_evictedTextures[i].allocator == allocator); >-#endif >- allocator->deleteTexture(m_evictedTextures[i].textureId, m_evictedTextures[i].size, m_evictedTextures[i].format); >- } >- } >- } >- m_evictedTextures.clear(); >-} >- >-void TextureManager::evictAndDeleteAllTextures(TextureAllocator* allocator) >+void TextureManager::deleteAllTextures() > { > unprotectAllTextures(); > reduceMemoryToLimit(0); >- deleteEvictedTextures(allocator); > } > > void TextureManager::removeTexture(TextureToken token, TextureInfo info) >@@ -266,28 +266,18 @@ void TextureManager::removeTexture(TextureToken token, TextureInfo info) > m_textures.remove(token); > ASSERT(m_textureLRUSet.contains(token)); > m_textureLRUSet.remove(token); >- EvictionEntry entry; >- entry.textureId = info.textureId; >- entry.size = info.size; >- entry.format = info.format; >-#ifndef NDEBUG >- entry.allocator = info.allocator; >-#endif >- m_evictedTextures.append(entry); >+ m_allocator->deleteTexture(info.textureId, info.size, info.format); > } > >-unsigned TextureManager::allocateTexture(TextureAllocator* allocator, TextureToken token) >+unsigned TextureManager::allocateTexture(TextureToken token) > { > TextureMap::iterator it = m_textures.find(token); > ASSERT(it != m_textures.end()); > TextureInfo* info = &it.get()->second; > ASSERT(info->isProtected); > >- unsigned textureId = allocator->createTexture(info->size, info->format); >+ unsigned textureId = m_allocator->createTexture(info->size, info->format); > info->textureId = textureId; >-#ifndef NDEBUG >- info->allocator = allocator; >-#endif > return textureId; > } > >@@ -317,9 +307,6 @@ bool TextureManager::requestTexture(TextureToken token, IntSize size, unsigned f > info.format = format; > info.textureId = 0; > info.isProtected = true; >-#ifndef NDEBUG >- info.allocator = 0; >-#endif > // Avoid churning by reusing the texture if it is about to be reclaimed and > // it has the same size and format as the requesting texture. > if (m_memoryUseBytes + memoryRequiredBytes > m_preferredMemoryLimitBytes) { >@@ -328,6 +315,7 @@ bool TextureManager::requestTexture(TextureToken token, IntSize size, unsigned f > return true; > } > addTexture(token, info); >+ textureId = allocateTexture(token); > return true; > } > >diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.h b/Source/WebCore/platform/graphics/chromium/TextureManager.h >index b8b2b1f42f37caacbfeaeaa136285167a6daf8fb..025afe54e7001617e08fa35587ccd5a459f5232e 100644 >--- a/Source/WebCore/platform/graphics/chromium/TextureManager.h >+++ b/Source/WebCore/platform/graphics/chromium/TextureManager.h >@@ -33,6 +33,7 @@ > #include <wtf/HashMap.h> > #include <wtf/HashSet.h> > #include <wtf/ListHashSet.h> >+#include <wtf/RefCounted.h> > #include <wtf/Vector.h> > > namespace WebCore { >@@ -40,21 +41,49 @@ namespace WebCore { > class ManagedTexture; > typedef int TextureToken; > >-class TextureAllocator { >+class TextureAllocator : public RefCounted<TextureAllocator> { > public: >+ virtual ~TextureAllocator() { } >+ > virtual unsigned createTexture(const IntSize&, GC3Denum format) = 0; > virtual void deleteTexture(unsigned texture, const IntSize&, GC3Denum) = 0; > >-protected: >- virtual ~TextureAllocator() { } >+#ifndef NDEBUG >+ virtual GraphicsContext3D* context() { return 0; } >+#endif >+}; >+ >+class TextureAllocatorBinding { >+public: >+ virtual ~TextureAllocatorBinding() { } >+ >+ virtual unsigned createTexture(unsigned texture, const IntSize&, GC3Denum format) = 0; >+ virtual void deleteTexture(unsigned texture) = 0; >+ virtual unsigned textureId(unsigned texture) = 0; >+}; >+ >+class PassthroughTextureAllocatorBinding : public TextureAllocatorBinding { >+public: >+ static PassOwnPtr<PassthroughTextureAllocatorBinding> create() >+ { >+ return adoptPtr(new PassthroughTextureAllocatorBinding()); >+ } >+ virtual ~PassthroughTextureAllocatorBinding(); >+ >+ virtual unsigned createTexture(unsigned texture, const IntSize&, GC3Denum format); >+ virtual void deleteTexture(unsigned texture); >+ virtual unsigned textureId(unsigned texture) { return texture; } >+ >+private: >+ PassthroughTextureAllocatorBinding(); > }; > > class TextureManager { > WTF_MAKE_NONCOPYABLE(TextureManager); > public: >- static PassOwnPtr<TextureManager> create(size_t maxMemoryLimitBytes, size_t preferredMemoryLimitBytes, int maxTextureSize) >+ static PassOwnPtr<TextureManager> create(PassRefPtr<TextureAllocator> allocator, size_t maxMemoryLimitBytes, size_t preferredMemoryLimitBytes, int maxTextureSize) > { >- return adoptPtr(new TextureManager(maxMemoryLimitBytes, preferredMemoryLimitBytes, maxTextureSize)); >+ return adoptPtr(new TextureManager(allocator, maxMemoryLimitBytes, preferredMemoryLimitBytes, maxTextureSize)); > } > ~TextureManager(); > >@@ -86,25 +115,25 @@ public: > void unprotectAllTextures(); > bool isProtected(TextureToken); > >- unsigned allocateTexture(TextureAllocator*, TextureToken); >- void deleteEvictedTextures(TextureAllocator*); >+ unsigned allocateTexture(TextureToken); > >- void evictAndDeleteAllTextures(TextureAllocator*); >+ void deleteAllTextures(); > > void reduceMemoryToLimit(size_t); > size_t currentMemoryUseBytes() const { return m_memoryUseBytes; } > >+#ifndef NDEBUG >+ TextureAllocator *allocator() { return m_allocator.get(); } >+#endif >+ > private: >- TextureManager(size_t maxMemoryLimitBytes, size_t preferredMemoryLimitBytes, int maxTextureSize); >+ TextureManager(PassRefPtr<TextureAllocator>, size_t maxMemoryLimitBytes, size_t preferredMemoryLimitBytes, int maxTextureSize); > > struct TextureInfo { > IntSize size; > GC3Denum format; > unsigned textureId; > bool isProtected; >-#ifndef NDEBUG >- TextureAllocator* allocator; >-#endif > }; > > void addTexture(TextureToken, TextureInfo); >@@ -122,17 +151,7 @@ private: > size_t m_memoryUseBytes; > int m_maxTextureSize; > TextureToken m_nextToken; >- >- struct EvictionEntry { >- unsigned textureId; >- IntSize size; >- GC3Denum format; >-#ifndef NDEBUG >- TextureAllocator* allocator; >-#endif >- }; >- >- Vector<EvictionEntry> m_evictedTextures; >+ RefPtr<TextureAllocator> m_allocator; > }; > > } >diff --git a/Source/WebCore/platform/graphics/chromium/TrackingTextureAllocator.h b/Source/WebCore/platform/graphics/chromium/TrackingTextureAllocator.h >index a8a54929a2fcab1934ef64491d7bf007c7988178..9174740323304e774eb60f37ec15bd64c54da377 100644 >--- a/Source/WebCore/platform/graphics/chromium/TrackingTextureAllocator.h >+++ b/Source/WebCore/platform/graphics/chromium/TrackingTextureAllocator.h >@@ -34,15 +34,19 @@ namespace WebCore { > class TrackingTextureAllocator : public TextureAllocator { > WTF_MAKE_NONCOPYABLE(TrackingTextureAllocator); > public: >- static PassOwnPtr<TrackingTextureAllocator> create(PassRefPtr<GraphicsContext3D> context) >+ static PassRefPtr<TrackingTextureAllocator> create(PassRefPtr<GraphicsContext3D> context) > { >- return adoptPtr(new TrackingTextureAllocator(context)); >+ return adoptRef(new TrackingTextureAllocator(context)); > } > virtual ~TrackingTextureAllocator(); > > virtual unsigned createTexture(const IntSize&, GC3Denum format); > virtual void deleteTexture(unsigned texture, const IntSize&, GC3Denum format); > >+#ifndef NDEBUG >+ virtual GraphicsContext3D* context() { return m_context.get(); } >+#endif >+ > size_t currentMemoryUseBytes() const { return m_currentMemoryUseBytes; } > > enum TextureUsageHint { Any, FramebufferAttachment }; >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasDrawQuad.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasDrawQuad.cpp >index 56f5083a55fc3a41a61b3e0402c5ffab6bdf7a11..7da3e87e72fb1501bd648acfff1c4d704dc9715b 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasDrawQuad.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasDrawQuad.cpp >@@ -29,16 +29,17 @@ > > namespace WebCore { > >-PassOwnPtr<CCCanvasDrawQuad> CCCanvasDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, unsigned textureId, bool hasAlpha, bool premultipliedAlpha) >+PassOwnPtr<CCCanvasDrawQuad> CCCanvasDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, unsigned textureId, bool hasAlpha, bool premultipliedAlpha, bool doubleBuffered) > { >- return adoptPtr(new CCCanvasDrawQuad(sharedQuadState, quadRect, textureId, hasAlpha, premultipliedAlpha)); >+ return adoptPtr(new CCCanvasDrawQuad(sharedQuadState, quadRect, textureId, hasAlpha, premultipliedAlpha, doubleBuffered)); > } > >-CCCanvasDrawQuad::CCCanvasDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, unsigned textureId, bool hasAlpha, bool premultipliedAlpha) >+CCCanvasDrawQuad::CCCanvasDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, unsigned textureId, bool hasAlpha, bool premultipliedAlpha, bool doubleBuffered) > : CCDrawQuad(sharedQuadState, CCDrawQuad::CanvasContent, quadRect) > , m_textureId(textureId) > , m_hasAlpha(hasAlpha) > , m_premultipliedAlpha(premultipliedAlpha) >+ , m_doubleBuffered(doubleBuffered) > { > } > >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasDrawQuad.h b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasDrawQuad.h >index aa85dbd134de804136ba639029e691ccb59ab2ff..6c3cccf29f1e8c7feeab76bd814818d8c59c167b 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasDrawQuad.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasDrawQuad.h >@@ -35,18 +35,20 @@ class CCLayerImpl; > class CCCanvasDrawQuad : public CCDrawQuad { > WTF_MAKE_NONCOPYABLE(CCCanvasDrawQuad); > public: >- static PassOwnPtr<CCCanvasDrawQuad> create(const CCSharedQuadState*, const IntRect&, unsigned texture_id, bool hasAlpha, bool premultipliedAlpha); >+ static PassOwnPtr<CCCanvasDrawQuad> create(const CCSharedQuadState*, const IntRect&, unsigned texture_id, bool hasAlpha, bool premultipliedAlpha, bool doubleBuffered); > > unsigned textureId() const { return m_textureId; } > bool hasAlpha() const { return m_hasAlpha; } > bool premultipliedAlpha() const { return m_premultipliedAlpha; } >+ bool doubleBuffered() const { return m_doubleBuffered; } > > private: >- CCCanvasDrawQuad(const CCSharedQuadState*, const IntRect&, unsigned texture_id, bool hasAlpha, bool premultipliedAlpha); >+ CCCanvasDrawQuad(const CCSharedQuadState*, const IntRect&, unsigned texture_id, bool hasAlpha, bool premultipliedAlpha, bool doubleBuffered); > > unsigned m_textureId; > bool m_hasAlpha; > bool m_premultipliedAlpha; >+ bool m_doubleBuffered; > }; > > } >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp >index 2bb3eff2278953151cba7ac1dfcc1417d45ecf96..0d613ab68ad62b8726cde7831efd0da6f143cfdb 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp >@@ -42,6 +42,7 @@ CCCanvasLayerImpl::CCCanvasLayerImpl(int id) > , m_textureId(0) > , m_hasAlpha(true) > , m_premultipliedAlpha(true) >+ , m_doubleBuffered(false) > { > } > >@@ -52,7 +53,7 @@ CCCanvasLayerImpl::~CCCanvasLayerImpl() > void CCCanvasLayerImpl::appendQuads(CCQuadList& quadList, const CCSharedQuadState* sharedQuadState) > { > IntRect quadRect(IntPoint(), bounds()); >- quadList.append(CCCanvasDrawQuad::create(sharedQuadState, quadRect, m_textureId, m_hasAlpha, m_premultipliedAlpha)); >+ quadList.append(CCCanvasDrawQuad::create(sharedQuadState, quadRect, m_textureId, m_hasAlpha, m_premultipliedAlpha, m_doubleBuffered)); > } > > void CCCanvasLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h >index 9126a7d44501e6325b5efd4b57cba9e46bc8a75a..f0603fe1bef43c7710e5dbe12c64a8a3f860db41 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h >@@ -50,6 +50,8 @@ public: > void setTextureId(unsigned id) { m_textureId = id; } > void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; } > void setPremultipliedAlpha(bool premultipliedAlpha) { m_premultipliedAlpha = premultipliedAlpha; } >+ void setDoubleBuffered(bool doubleBuffered) { m_doubleBuffered = doubleBuffered; } >+ > private: > explicit CCCanvasLayerImpl(int); > >@@ -58,6 +60,7 @@ private: > unsigned m_textureId; > bool m_hasAlpha; > bool m_premultipliedAlpha; >+ bool m_doubleBuffered; > }; > > } >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp >index 708bcff8801b78881060b529858b289b95328aec..ab7a6da99f6c650b0754b63306b68e06326c698d 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp >@@ -126,7 +126,7 @@ void CCHeadsUpDisplay::draw() > { > PlatformCanvas::AutoLocker locker(&canvas); > >- m_hudTexture->bindTexture(context, m_layerRenderer->renderSurfaceTextureAllocator()); >+ m_hudTexture->bindTexture(context); > bool uploadedViaMap = false; > if (m_useMapSubForUploads) { > Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(context->getExtensions()); >@@ -148,7 +148,7 @@ void CCHeadsUpDisplay::draw() > const Program* program = m_layerRenderer->headsUpDisplayProgram(); > ASSERT(program && program->initialized()); > GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); >- m_hudTexture->bindTexture(context, m_layerRenderer->renderSurfaceTextureAllocator()); >+ m_hudTexture->bindTexture(context); > GLC(context, context->useProgram(program->program())); > GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); > >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp >index 50d76a5e8c542d760b1c690050d66834fb798518..cb24c8f65a892db88871f82edbcc600c560446e0 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp >@@ -87,6 +87,7 @@ bool CCLayerTreeHost::initialize() > m_proxy = CCThreadProxy::create(this); > } else > m_proxy = CCSingleThreadProxy::create(this); >+ > m_proxy->start(); > > if (!m_proxy->initializeContext()) >@@ -122,19 +123,20 @@ void CCLayerTreeHost::initializeLayerRenderer() > // Update m_settings based on partial update capability. > m_settings.partialTextureUpdates = m_settings.partialTextureUpdates && m_proxy->partialTextureUpdateCapability(); > >- m_contentsTextureManager = TextureManager::create(TextureManager::highLimitBytes(viewportSize()), >+ m_contentsTextureManager = TextureManager::create(m_proxy->contentsTextureAllocator(), >+ TextureManager::highLimitBytes(viewportSize()), > TextureManager::reclaimLimitBytes(viewportSize()), > m_proxy->layerRendererCapabilities().maxTextureSize); > > m_layerRendererInitialized = true; > } > >- >-void CCLayerTreeHost::deleteContentsTexturesOnImplThread(TextureAllocator* allocator) >+void CCLayerTreeHost::deleteContentsTexturesOnImplThread() > { > ASSERT(CCProxy::isImplThread()); >+ > if (m_contentsTextureManager) >- m_contentsTextureManager->evictAndDeleteAllTextures(allocator); >+ m_contentsTextureManager->deleteAllTextures(); > } > > void CCLayerTreeHost::updateAnimations(double frameBeginTime) >@@ -155,7 +157,6 @@ void CCLayerTreeHost::beginCommitOnImplThread(CCLayerTreeHostImpl* hostImpl) > TRACE_EVENT("CCLayerTreeHost::commitTo", this, 0); > > m_contentsTextureManager->reduceMemoryToLimit(TextureManager::reclaimLimitBytes(viewportSize())); >- m_contentsTextureManager->deleteEvictedTextures(hostImpl->contentsTextureAllocator()); > } > > // This function commits the CCLayerTreeHost to an impl tree. When modifying >@@ -327,10 +328,9 @@ void CCLayerTreeHost::didBecomeInvisibleOnImplThread(CCLayerTreeHostImpl* hostIm > { > ASSERT(CCProxy::isImplThread()); > if (m_proxy->layerRendererCapabilities().contextHasCachedFrontBuffer) >- contentsTextureManager()->evictAndDeleteAllTextures(hostImpl->contentsTextureAllocator()); >+ contentsTextureManager()->deleteAllTextures(); > else { > contentsTextureManager()->reduceMemoryToLimit(TextureManager::reclaimLimitBytes(viewportSize())); >- contentsTextureManager()->deleteEvictedTextures(hostImpl->contentsTextureAllocator()); > } > > // Ensure that the dropped tiles are propagated to the impl tree. >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h >index 2224f7cc16082906210dbdd1bd42b11eb0ca771d..2fe89bfaa33e0e000575d9ca2efcdf0e36ed7273 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h >@@ -132,7 +132,7 @@ public: > void didRecreateGraphicsContext(bool success); > void didCommitAndDrawFrame() { m_client->didCommitAndDrawFrame(); } > void didCompleteSwapBuffers() { m_client->didCompleteSwapBuffers(); } >- void deleteContentsTexturesOnImplThread(TextureAllocator*); >+ void deleteContentsTexturesOnImplThread(); > > CCLayerTreeHostClient* client() { return m_client; } > >@@ -178,6 +178,7 @@ public: > void setPageScaleFactorLimits(float minScale, float maxScale); > > TextureManager* contentsTextureManager() const; >+ TextureAllocator* textureAllocator() const; > > bool visible() const { return m_visible; } > void setVisible(bool); >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp >index e930bc29e86c07702e0726f35f37eaa5a58adc82..9003f3ac5032bd918135639d63a4cedd88491e3a 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp >@@ -298,6 +298,11 @@ TextureAllocator* CCLayerTreeHostImpl::contentsTextureAllocator() const > return m_layerRenderer ? m_layerRenderer->contentsTextureAllocator() : 0; > } > >+TextureAllocatorBinding* CCLayerTreeHostImpl::contentsTextureAllocatorBinding() const >+{ >+ return m_layerRenderer ? m_layerRenderer->contentsTextureAllocatorBinding() : 0; >+} >+ > void CCLayerTreeHostImpl::swapBuffers() > { > ASSERT(m_layerRenderer && !isContextLost()); >@@ -350,10 +355,10 @@ void CCLayerTreeHostImpl::setVisible(bool visible) > m_layerRenderer->setVisible(visible); > } > >-bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D> context) >+bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D> context, PassRefPtr<TrackingTextureAllocator> contentsTextureAllocator, PassOwnPtr<TextureAllocatorBinding> contentsTextureAllocatorBinding) > { > OwnPtr<LayerRendererChromium> layerRenderer; >- layerRenderer = LayerRendererChromium::create(this, context); >+ layerRenderer = LayerRendererChromium::create(this, context, contentsTextureAllocator, contentsTextureAllocatorBinding); > > if (m_layerRenderer) > m_layerRenderer->close(); >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h >index 569d69fa3ed680fa517e98b0b1f4554900856445..68e5e369994bb37a029796a4e0f650d2fcdc4aa1 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h >@@ -38,7 +38,8 @@ class CCCompletionEvent; > class CCPageScaleAnimation; > class CCLayerImpl; > class LayerRendererChromium; >-class TextureAllocator; >+class TextureAllocatorBinding; >+class TrackingTextureAllocator; > struct LayerRendererCapabilities; > class TransformationMatrix; > >@@ -80,11 +81,12 @@ public: > void finishAllRendering(); > int frameNumber() const { return m_frameNumber; } > >- bool initializeLayerRenderer(PassRefPtr<GraphicsContext3D>); >+ bool initializeLayerRenderer(PassRefPtr<GraphicsContext3D>, PassRefPtr<TrackingTextureAllocator>, PassOwnPtr<TextureAllocatorBinding>); > bool isContextLost(); > LayerRendererChromium* layerRenderer() { return m_layerRenderer.get(); } > const LayerRendererCapabilities& layerRendererCapabilities() const; > TextureAllocator* contentsTextureAllocator() const; >+ TextureAllocatorBinding* contentsTextureAllocatorBinding() const; > > void swapBuffers(); > void onSwapBuffersComplete(); >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h b/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h >index a3aa716071c342ab698e3e0e93d22982373e75fa..1a2468f678d7042d2e28138a0c90fba665fb3db1 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h >@@ -39,6 +39,7 @@ class CCLayerTreeHostImpl; > class CCLayerTreeHostImplClient; > class GraphicsContext3D; > struct LayerRendererCapabilities; >+class TextureAllocator; > class TextureManager; > > // Abstract class responsible for proxying commands from the main-thread side of >@@ -84,6 +85,8 @@ public: > // updates are required. > virtual bool partialTextureUpdateCapability() const = 0; > >+ virtual TextureAllocator* contentsTextureAllocator() = 0; >+ > // Debug hooks > #ifndef NDEBUG > static bool isMainThread(); >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp >index a4c92569d7ff397fa503de3b869ace102ac31451..73d4b7776dcaee0a48b6f72dcdb9692cdf700945 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp >@@ -191,7 +191,7 @@ void CCRenderSurface::drawSurface(LayerRendererChromium* layerRenderer, CCLayerI > > GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); > GLC(context3D, context3D->uniform1i(program->fragmentShader().samplerLocation(), 0)); >- m_contentsTexture->bindTexture(context3D, layerRenderer->renderSurfaceTextureAllocator()); >+ m_contentsTexture->bindTexture(context3D); > > if (shaderMaskSamplerLocation != -1) { > GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1)); >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp >index 70dec054c5252163d3df0d7f9345f374168dff2a..5f15007a6e58cbcd600ef0008fa4c5d39dda43ff 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp >@@ -130,7 +130,8 @@ bool CCSingleThreadProxy::initializeLayerRenderer() > ASSERT(m_contextBeforeInitialization); > { > DebugScopedSetImplThread impl; >- bool ok = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitialization.release()); >+ RefPtr<GraphicsContext3D> context = m_contextBeforeInitialization; >+ bool ok = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitialization.release(), TrackingTextureAllocator::create(context), PassthroughTextureAllocatorBinding::create()); > if (ok) { > m_layerRendererInitialized = true; > m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities(); >@@ -167,7 +168,7 @@ void CCSingleThreadProxy::doCommit() > m_layerTreeHostImpl->beginCommit(); > > m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get()); >- CCTextureUpdater updater(m_layerTreeHostImpl->contentsTextureAllocator()); >+ CCTextureUpdater updater(m_layerTreeHostImpl->contentsTextureAllocatorBinding()); > m_layerTreeHost->updateCompositorResources(m_layerTreeHostImpl->context(), updater); > while (updater.update(m_layerTreeHostImpl->context(), 1)) { } > m_layerTreeHostImpl->setVisible(m_layerTreeHost->visible()); >@@ -216,12 +217,17 @@ void CCSingleThreadProxy::stop() > ASSERT(CCProxy::isMainThread()); > { > DebugScopedSetImplThread impl; >- m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator()); > m_layerTreeHostImpl.clear(); > } > m_layerTreeHost = 0; > } > >+TextureAllocator* CCSingleThreadProxy::contentsTextureAllocator() >+{ >+ ASSERT(m_layerTreeHostImpl); >+ return m_layerTreeHostImpl->contentsTextureAllocator(); >+} >+ > // Called by the legacy scheduling path (e.g. where render_widget does the scheduling) > void CCSingleThreadProxy::compositeImmediately() > { >@@ -256,8 +262,7 @@ bool CCSingleThreadProxy::recreateContextIfNeeded() > bool ok; > { > DebugScopedSetImplThread impl; >- m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator()); >- ok = m_layerTreeHostImpl->initializeLayerRenderer(context); >+ ok = m_layerTreeHostImpl->initializeLayerRenderer(context, TrackingTextureAllocator::create(context), PassthroughTextureAllocatorBinding::create()); > if (ok) > m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities(); > } >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h >index 4345ed62f604b7bc0b8e1b6171eb842b2dff6d06..394575a6df0d877d08b74cc2e9073708ce6a9ecc 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h >@@ -56,6 +56,7 @@ public: > virtual void start(); > virtual void stop(); > virtual bool partialTextureUpdateCapability() const { return true; } >+ virtual TextureAllocator* contentsTextureAllocator(); > > // CCLayerTreeHostImplClient implementation > virtual void onSwapBuffersCompleteOnImplThread() { ASSERT_NOT_REACHED(); } >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.cpp >index 8745c4ea0a710bde18ede1820f314fdb8cc872ab..7650e397c0486e4d4e36c917b0d548a752e6aac0 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.cpp >@@ -37,11 +37,11 @@ using namespace std; > > namespace WebCore { > >-CCTextureUpdater::CCTextureUpdater(TextureAllocator* allocator) >- : m_allocator(allocator) >+CCTextureUpdater::CCTextureUpdater(TextureAllocatorBinding* allocatorBinding) >+ : m_allocatorBinding(allocatorBinding) > , m_entryIndex(0) > { >- ASSERT(m_allocator); >+ ASSERT(m_allocatorBinding); > } > > CCTextureUpdater::~CCTextureUpdater() >@@ -69,7 +69,7 @@ bool CCTextureUpdater::update(GraphicsContext3D* context, size_t count) > size_t maxIndex = min(m_entryIndex + count, m_entries.size()); > for (; m_entryIndex < maxIndex; ++m_entryIndex) { > UpdateEntry& entry = m_entries[m_entryIndex]; >- entry.m_texture->updateRect(context, m_allocator, entry.m_sourceRect, entry.m_destRect); >+ entry.m_texture->updateRect(context, m_allocatorBinding, entry.m_sourceRect, entry.m_destRect); > } > > if (maxIndex < m_entries.size()) >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.h >index bf79ac9c2e22efc5eda9a64829e2efccec15bb30..5ba0036c52378aef19de93f514f4b5878a979113 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdater.h >@@ -33,11 +33,11 @@ > namespace WebCore { > > class GraphicsContext3D; >-class TextureAllocator; >+class TextureAllocatorBinding; > > class CCTextureUpdater { > public: >- CCTextureUpdater(TextureAllocator*); >+ CCTextureUpdater(TextureAllocatorBinding*); > ~CCTextureUpdater(); > > void append(LayerTextureUpdater::Texture*, const IntRect& sourceRect, const IntRect& destRect); >@@ -49,7 +49,7 @@ public: > > void clear(); > >- TextureAllocator* allocator() { return m_allocator; } >+ TextureAllocatorBinding* allocatorBinding() { return m_allocatorBinding; } > > private: > struct UpdateEntry { >@@ -58,7 +58,7 @@ private: > IntRect m_destRect; > }; > >- TextureAllocator* m_allocator; >+ TextureAllocatorBinding* m_allocatorBinding; > size_t m_entryIndex; > Vector<UpdateEntry> m_entries; > }; >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp >index 4b203f354b993f6331306bec2c0eaeabd83f48f3..0433c2787a3e31a9261386557c3e4f48438574d7 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp >@@ -26,8 +26,10 @@ > > #include "cc/CCThreadProxy.h" > >+#include "DeferredTextureAllocator.h" > #include "GraphicsContext3D.h" > #include "TraceEvent.h" >+#include "TrackingTextureAllocator.h" > #include "cc/CCDelayBasedTimeSource.h" > #include "cc/CCFrameRateController.h" > #include "cc/CCInputHandler.h" >@@ -68,6 +70,7 @@ CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost) > , m_finishAllRenderingCompletionEventOnImplThread(0) > , m_commitCompletionEventOnImplThread(0) > , m_nextFrameIsNewlyCommittedFrameOnImplThread(false) >+ , m_deferredTextureAllocator(DeferredTextureAllocator::create()) > { > TRACE_EVENT("CCThreadProxy::CCThreadProxy", this, 0); > ASSERT(isMainThread()); >@@ -405,6 +408,10 @@ void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTim > if (m_animateRequested) > setNeedsCommit(); > >+ // Copy and clear deleted texture vector for passing to impl thread. >+ OwnPtr<Vector<unsigned> > deletedTextures = adoptPtr(new Vector<unsigned>(m_deferredTextureAllocator->deletedTextures())); >+ m_deferredTextureAllocator->deletedTextures().clear(); >+ > // Notify the impl thread that the beginFrame has completed. This will > // begin the commit process, which is blocking from the main thread's > // point of view, but asynchronously performed on the impl thread, >@@ -412,7 +419,7 @@ void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTim > { > TRACE_EVENT("commit", this, 0); > CCCompletionEvent completion; >- CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrameCompleteOnImplThread, AllowCrossThreadAccess(&completion))); >+ CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrameCompleteOnImplThread, AllowCrossThreadAccess(&completion), deletedTextures.release())); > completion.wait(); > } > >@@ -421,7 +428,12 @@ void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTim > ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber); > } > >-void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion) >+TextureAllocator* CCThreadProxy::contentsTextureAllocator() >+{ >+ return m_deferredTextureAllocator.get(); >+} >+ >+void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion, PassOwnPtr<Vector<unsigned> > deletedTextures) > { > TRACE_EVENT("CCThreadProxy::beginFrameCompleteOnImplThread", this, 0); > ASSERT(!m_commitCompletionEventOnImplThread); >@@ -434,9 +446,10 @@ void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion > } > > m_commitCompletionEventOnImplThread = completion; >+ m_commitDeletedTexturesOnImplThread = deletedTextures; > > ASSERT(!m_currentTextureUpdaterOnImplThread); >- m_currentTextureUpdaterOnImplThread = adoptPtr(new CCTextureUpdater(m_layerTreeHostImpl->contentsTextureAllocator())); >+ m_currentTextureUpdaterOnImplThread = adoptPtr(new CCTextureUpdater(m_layerTreeHostImpl->contentsTextureAllocatorBinding())); > m_layerTreeHost->updateCompositorResources(m_layerTreeHostImpl->context(), *m_currentTextureUpdaterOnImplThread); > > m_schedulerOnImplThread->beginFrameComplete(); >@@ -481,6 +494,11 @@ void CCThreadProxy::scheduledActionCommit() > > m_layerTreeHostImpl->commitComplete(); > >+ // Delete textures no longer used after commit finished. >+ Vector<unsigned>::iterator it = m_commitDeletedTexturesOnImplThread->begin(); >+ for (; it != m_commitDeletedTexturesOnImplThread->end(); it++) >+ m_layerTreeHostImpl->contentsTextureAllocatorBinding()->deleteTexture(*it); >+ > m_nextFrameIsNewlyCommittedFrameOnImplThread = true; > > m_commitCompletionEventOnImplThread->signal(); >@@ -572,12 +590,17 @@ void CCThreadProxy::initializeLayerRendererOnImplThread(CCCompletionEvent* compl > { > TRACE_EVENT("CCThreadProxy::initializeLayerRendererOnImplThread", this, 0); > ASSERT(isImplThread()); >+ RefPtr<GraphicsContext3D> context = m_contextBeforeInitializationOnImplThread; >+ RefPtr<TrackingTextureAllocator> contentsTextureAllocator = TrackingTextureAllocator::create(context); >+ OwnPtr<DeferredTextureAllocatorBinding> contentsTextureAllocatorBinding = DeferredTextureAllocatorBinding::create(contentsTextureAllocator); > ASSERT(m_contextBeforeInitializationOnImplThread); >- *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitializationOnImplThread.release()); >+ *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitializationOnImplThread.release(), contentsTextureAllocator, contentsTextureAllocatorBinding.release()); > if (*initializeSucceeded) { > *capabilities = m_layerTreeHostImpl->layerRendererCapabilities(); > if (capabilities->usingSwapCompleteCallback) > m_schedulerOnImplThread->setMaxFramesPending(2); >+ if (capabilities->usingTextureStorageExtension) >+ contentsTextureAllocator->setUseTextureStorageExt(true); > } > > completion->signal(); >@@ -587,7 +610,7 @@ void CCThreadProxy::layerTreeHostClosedOnImplThread(CCCompletionEvent* completio > { > TRACE_EVENT("CCThreadProxy::layerTreeHostClosedOnImplThread", this, 0); > ASSERT(isImplThread()); >- m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator()); >+ m_layerTreeHost->deleteContentsTexturesOnImplThread(); > m_layerTreeHostImpl.clear(); > m_inputHandlerOnImplThread.clear(); > m_schedulerOnImplThread.clear(); >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h b/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h >index b65a6c604e2923fc8f09cf9ac7f5596d0ab0cdd0..dda23b1a2b86eea8ba573d286fbb9bd71538b508 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h >@@ -40,6 +40,7 @@ class CCScheduler; > class CCScopedThreadProxy; > class CCTextureUpdater; > class CCThread; >+class DeferredTextureAllocator; > > class CCThreadProxy : public CCProxy, CCLayerTreeHostImplClient, CCSchedulerClient { > public: >@@ -64,6 +65,7 @@ public: > virtual void start(); > virtual void stop(); > virtual bool partialTextureUpdateCapability() const; >+ virtual TextureAllocator* contentsTextureAllocator(); > > // CCLayerTreeHostImplClient implementation > virtual void onSwapBuffersCompleteOnImplThread(); >@@ -95,7 +97,7 @@ private: > }; > PassOwnPtr<CCThread::Task> createBeginFrameAndCommitTaskOnImplThread(); > void obtainBeginFrameAndCommitTaskFromCCThread(CCCompletionEvent*, CCThread::Task**); >- void beginFrameCompleteOnImplThread(CCCompletionEvent*); >+ void beginFrameCompleteOnImplThread(CCCompletionEvent*, PassOwnPtr<Vector<unsigned> > deletedTextures); > void requestReadbackOnImplThread(ReadbackRequest*); > void finishAllRenderingOnImplThread(CCCompletionEvent*); > void initializeImplOnImplThread(CCCompletionEvent*); >@@ -140,6 +142,10 @@ private: > > // Set when the next draw should post didCommitAndDrawFrame to the main thread. > bool m_nextFrameIsNewlyCommittedFrameOnImplThread; >+ >+ RefPtr<DeferredTextureAllocator> m_deferredTextureAllocator; >+ >+ OwnPtr<Vector<unsigned> > m_commitDeletedTexturesOnImplThread; > }; > > } >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp >index 80a0435fd9e1ca6aae8618de8d887afcbd96e8e5..2ab9a5d0bb82b403b07ae795f01a95912e85c055 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp >@@ -81,7 +81,7 @@ void CCTiledLayerImpl::bindContentsTexture(LayerRendererChromium* layerRenderer) > Platform3DObject textureId = tile ? tile->textureId() : 0; > ASSERT(textureId); > >- layerRenderer->context()->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); >+ layerRenderer->context()->bindTexture(GraphicsContext3D::TEXTURE_2D, layerRenderer->contentsTextureAllocatorBinding()->textureId(textureId)); > } > > void CCTiledLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const >diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp >index ff81acda8270717dda6a3c0be82e66a47e0d836b..cbe47c83fe898b42a4a234829fb02c5e94f9fd5d 100644 >--- a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp >+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp >@@ -198,8 +198,7 @@ void CCVideoLayerImpl::copyPlaneToTexture(LayerRendererChromium* layerRenderer, > { > Texture& texture = m_textures[index]; > GraphicsContext3D* context = layerRenderer->context(); >- TextureAllocator* allocator = layerRenderer->renderSurfaceTextureAllocator(); >- texture.m_texture->bindTexture(context, allocator); >+ texture.m_texture->bindTexture(context); > GC3Denum format = texture.m_texture->format(); > IntSize dimensions = texture.m_texture->size(); > >diff --git a/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp b/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp >index f59893de906418f8cbd75740ae2939e23cc2350a..4153f02a1926978c739f07b6e6511ced31038441 100644 >--- a/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp >+++ b/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp >@@ -349,7 +349,7 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers) > { > GraphicsContext3D::Attributes attrs; > RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new BlendStateTrackerContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread); >- m_hostImpl->initializeLayerRenderer(context); >+ m_hostImpl->initializeLayerRenderer(context, TrackingTextureAllocator::create(context), PassthroughTextureAllocatorBinding::create()); > m_hostImpl->setViewportSize(IntSize(10, 10)); > > RefPtr<CCLayerImpl> root = CCLayerImpl::create(0); >@@ -518,7 +518,7 @@ TEST_F(CCLayerTreeHostImplTest, reshapeNotCalledUntilDraw) > GraphicsContext3D::Attributes attrs; > ReshapeTrackerContext* reshapeTracker = new ReshapeTrackerContext(); > RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(reshapeTracker), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread); >- m_hostImpl->initializeLayerRenderer(context); >+ m_hostImpl->initializeLayerRenderer(context, TrackingTextureAllocator::create(context), PassthroughTextureAllocatorBinding::create()); > m_hostImpl->setViewportSize(IntSize(10, 10)); > > RefPtr<CCLayerImpl> root = adoptRef(new FakeDrawableCCLayerImpl(1)); >@@ -568,7 +568,7 @@ TEST_F(CCLayerTreeHostImplTest, partialSwapReceivesDamageRect) > CCSettings settings; > settings.partialSwapEnabled = true; > OwnPtr<CCLayerTreeHostImpl> layerTreeHostImpl = CCLayerTreeHostImpl::create(settings, this); >- layerTreeHostImpl->initializeLayerRenderer(context); >+ layerTreeHostImpl->initializeLayerRenderer(context, TrackingTextureAllocator::create(context), PassthroughTextureAllocatorBinding::create()); > layerTreeHostImpl->setViewportSize(IntSize(500, 500)); > > RefPtr<CCLayerImpl> root = adoptRef(new FakeDrawableCCLayerImpl(1)); >diff --git a/Source/WebKit/chromium/tests/Canvas2DLayerChromiumTest.cpp b/Source/WebKit/chromium/tests/Canvas2DLayerChromiumTest.cpp >index 4b3dd27d31d882104c70cfff5024fb80447ea141..3f85ea57cf5dc8f6c080757ea6a131f4d2d531eb 100644 >--- a/Source/WebKit/chromium/tests/Canvas2DLayerChromiumTest.cpp >+++ b/Source/WebKit/chromium/tests/Canvas2DLayerChromiumTest.cpp >@@ -65,8 +65,25 @@ public: > > class MockTextureAllocator : public TextureAllocator { > public: >+ static PassRefPtr<MockTextureAllocator> create(PassRefPtr<GraphicsContext3D> context) >+ { >+ return adoptRef(new MockTextureAllocator(context)); >+ } >+ > MOCK_METHOD2(createTexture, unsigned(const IntSize&, GC3Denum)); > MOCK_METHOD3(deleteTexture, void(unsigned, const IntSize&, GC3Denum)); >+ >+#ifndef NDEBUG >+ virtual GraphicsContext3D* context() { return m_context.get(); } >+#endif >+ >+private: >+ explicit MockTextureAllocator(PassRefPtr<GraphicsContext3D> context) >+ : m_context(context) >+ { >+ } >+ >+ RefPtr<GraphicsContext3D> m_context; > }; > > } // namespace >@@ -85,18 +102,19 @@ protected: > MockCanvasContext& mainMock = *static_cast<MockCanvasContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(mainContext.get())); > MockCanvasContext& implMock = *static_cast<MockCanvasContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(implContext.get())); > >- MockTextureAllocator allocatorMock; >- CCTextureUpdater updater(&allocatorMock); >+ RefPtr<MockTextureAllocator> allocatorMock = MockTextureAllocator::create(implContext); >+ OwnPtr<TextureAllocatorBinding> allocatorBinding = PassthroughTextureAllocatorBinding::create(); >+ CCTextureUpdater updater(allocatorBinding.get()); > > const IntSize size(300, 150); > const size_t maxTextureSize = size.width() * size.height() * 4; >- OwnPtr<TextureManager> textureManager = TextureManager::create(maxTextureSize, maxTextureSize, maxTextureSize); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(allocatorMock.get(), maxTextureSize, maxTextureSize, maxTextureSize); > > if (threaded) > CCProxy::setImplThread(new FakeCCThread); > >- const WebGLId backTextureId = 1; >- const WebGLId frontTextureId = 2; >+ const WebGLId frontTextureId = 1; >+ const WebGLId backTextureId = 2; > const WebGLId fboId = 3; > { > InSequence sequence; >@@ -109,7 +127,7 @@ protected: > .WillOnce(Return(fboId)); > > // Create texture and do the copy (on the impl thread). >- EXPECT_CALL(allocatorMock, createTexture(size, GraphicsContext3D::RGBA)) >+ EXPECT_CALL(*allocatorMock.get(), createTexture(size, GraphicsContext3D::RGBA)) > .WillOnce(Return(frontTextureId)); > EXPECT_CALL(implMock, bindTexture(GraphicsContext3D::TEXTURE_2D, frontTextureId)); > EXPECT_CALL(implMock, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, fboId)); >@@ -121,7 +139,7 @@ protected: > EXPECT_CALL(mainMock, deleteFramebuffer(fboId)); > > // Teardown TextureManager. >- EXPECT_CALL(allocatorMock, deleteTexture(frontTextureId, size, GraphicsContext3D::RGBA)); >+ EXPECT_CALL(*allocatorMock.get(), deleteTexture(frontTextureId, size, GraphicsContext3D::RGBA)); > } > } > >@@ -152,7 +170,6 @@ protected: > } > canvas.clear(); > textureManager->reduceMemoryToLimit(0); >- textureManager->deleteEvictedTextures(&allocatorMock); > } > }; > >diff --git a/Source/WebKit/chromium/tests/TextureManagerTest.cpp b/Source/WebKit/chromium/tests/TextureManagerTest.cpp >index da4aa03261dfa12ff3603e5ee0a0dce0a372a595..76216d9258ca8662e1c2d5d73e76e09d6572c1da 100644 >--- a/Source/WebKit/chromium/tests/TextureManagerTest.cpp >+++ b/Source/WebKit/chromium/tests/TextureManagerTest.cpp >@@ -36,15 +36,24 @@ namespace { > > class FakeTextureAllocator : public TextureAllocator { > public: >+ static PassRefPtr<FakeTextureAllocator> create() >+ { >+ return adoptRef(new FakeTextureAllocator()); >+ } > virtual ~FakeTextureAllocator() { } >+ > virtual unsigned createTexture(const IntSize&, GC3Denum) { return 1; } > virtual void deleteTexture(unsigned, const IntSize&, GC3Denum) { } >+ >+private: >+ FakeTextureAllocator() { } > }; > > class TextureManagerTest : public testing::Test { > public: > TextureManagerTest() >- : m_textureSize(256, 256) >+ : m_fakeTextureAllocator(FakeTextureAllocator::create()) >+ , m_textureSize(256, 256) > , m_textureFormat(GraphicsContext3D::RGBA) > { > } >@@ -60,20 +69,17 @@ public: > > PassOwnPtr<TextureManager> createTextureManager(size_t maxTextures, size_t preferredTextures) > { >- return TextureManager::create(texturesMemorySize(maxTextures), texturesMemorySize(preferredTextures), 1024); >+ return TextureManager::create(m_fakeTextureAllocator, texturesMemorySize(maxTextures), texturesMemorySize(preferredTextures), 1024); > } > > bool requestTexture(TextureManager* manager, TextureToken token) > { > unsigned textureId; >- bool result = manager->requestTexture(token, m_textureSize, m_textureFormat, textureId); >- if (result) >- manager->allocateTexture(&m_fakeTextureAllocator, token); >- return result; >+ return manager->requestTexture(token, m_textureSize, m_textureFormat, textureId); > } > > private: >- FakeTextureAllocator m_fakeTextureAllocator; >+ RefPtr<FakeTextureAllocator> m_fakeTextureAllocator; > const IntSize m_textureSize; > const GC3Denum m_textureFormat; > }; >diff --git a/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp b/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp >index 6069fd181388bb5469d9b613f8c753d6a5bfb899..bbfe4b742024df8790aa301c4570a06f41d43744 100644 >--- a/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp >+++ b/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp >@@ -50,8 +50,15 @@ namespace { > > class FakeTextureAllocator : public TextureAllocator { > public: >+ static PassRefPtr<FakeTextureAllocator> create() >+ { >+ return adoptRef(new FakeTextureAllocator()); >+ } > virtual unsigned createTexture(const IntSize&, GC3Denum) { return 0; } > virtual void deleteTexture(unsigned, const IntSize&, GC3Denum) { } >+ >+private: >+ FakeTextureAllocator() { } > }; > > class FakeTiledLayerChromium; >@@ -63,7 +70,7 @@ public: > Texture(PassOwnPtr<ManagedTexture> texture) : LayerTextureUpdater::Texture(texture) { } > virtual ~Texture() { } > >- virtual void updateRect(GraphicsContext3D*, TextureAllocator*, const IntRect&, const IntRect&) { } >+ virtual void updateRect(GraphicsContext3D*, TextureAllocatorBinding*, const IntRect&, const IntRect&) { } > }; > > FakeLayerTextureUpdater() : m_prepareCount(0) { } >@@ -204,13 +211,13 @@ void FakeLayerTextureUpdater::prepareToUpdate(const IntRect& contentRect, const > > TEST(TiledLayerChromiumTest, pushDirtyTiles) > { >- OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(FakeTextureAllocator::create(), 4*1024*1024, 2*1024*1024, 1024); > RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); > DebugScopedSetImplThread implThread; > RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0)); > >- FakeTextureAllocator textureAllocator; >- CCTextureUpdater updater(&textureAllocator); >+ OwnPtr<TextureAllocatorBinding> allocatorBinding = PassthroughTextureAllocatorBinding::create(); >+ CCTextureUpdater updater(allocatorBinding.get()); > > // The tile size is 100x100, so this invalidates and then paints two tiles. > layer->setBounds(IntSize(100, 200)); >@@ -239,14 +246,13 @@ TEST(TiledLayerChromiumTest, pushDirtyTiles) > > TEST(TiledLayerChromiumTest, pushIdlePaintTiles) > { >- OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(FakeTextureAllocator::create(), 4*1024*1024, 2*1024*1024, 1024); > RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); > DebugScopedSetImplThread implThread; > RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0)); > >- FakeTextureAllocator textureAllocator; >- CCTextureUpdater updater(&textureAllocator); >- >+ OwnPtr<TextureAllocatorBinding> allocatorBinding = PassthroughTextureAllocatorBinding::create(); >+ CCTextureUpdater updater(allocatorBinding.get()); > // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the center. > IntSize contentBounds(500, 500); > IntRect contentRect(IntPoint::zero(), contentBounds); >@@ -305,14 +311,13 @@ TEST(TiledLayerChromiumTest, idlePaintOutOfMemory) > // We have enough memory for only the visible rect, so we will run out of memory in first idle paint. > int memoryLimit = 4 * 100 * 100; // 2 tiles, 4 bytes per pixel. > >- OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit / 2, 1024); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(FakeTextureAllocator::create(), memoryLimit, memoryLimit / 2, 1024); > RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); > DebugScopedSetImplThread implThread; > RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0)); > >- FakeTextureAllocator textureAllocator; >- CCTextureUpdater updater(&textureAllocator); >- >+ OwnPtr<TextureAllocatorBinding> allocatorBinding = PassthroughTextureAllocatorBinding::create(); >+ CCTextureUpdater updater(allocatorBinding.get()); > // This invalidates 9 tiles and then paints one visible tile. > layer->setBounds(contentBounds); > layer->setVisibleLayerRect(visibleRect); >@@ -341,13 +346,13 @@ TEST(TiledLayerChromiumTest, idlePaintOutOfMemory) > > TEST(TiledLayerChromiumTest, invalidateFromPrepare) > { >- OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(FakeTextureAllocator::create(), 4*1024*1024, 2*1024*1024, 1024); > RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); > DebugScopedSetImplThread implThread; > RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0)); > >- FakeTextureAllocator textureAllocator; >- CCTextureUpdater updater(&textureAllocator); >+ OwnPtr<TextureAllocatorBinding> allocatorBinding = PassthroughTextureAllocatorBinding::create(); >+ CCTextureUpdater updater(allocatorBinding.get()); > > // The tile size is 100x100, so this invalidates and then paints two tiles. > layer->setBounds(IntSize(100, 200)); >@@ -385,11 +390,11 @@ TEST(TiledLayerChromiumTest, verifyUpdateRectWhenContentBoundsAreScaled) > // The updateRect (that indicates what was actually painted) should be in > // layer space, not the content space. > >- OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(FakeTextureAllocator::create(), 4*1024*1024, 2*1024*1024, 1024); > RefPtr<FakeTiledLayerWithScaledBounds> layer = adoptRef(new FakeTiledLayerWithScaledBounds(textureManager.get())); > >- FakeTextureAllocator textureAllocator; >- CCTextureUpdater updater(&textureAllocator); >+ OwnPtr<TextureAllocatorBinding> allocatorBinding = PassthroughTextureAllocatorBinding::create(); >+ CCTextureUpdater updater(allocatorBinding.get()); > > IntRect layerBounds(0, 0, 300, 200); > IntRect contentBounds(0, 0, 200, 250); >@@ -432,7 +437,7 @@ TEST(TiledLayerChromiumTest, skipsDrawGetsReset) > > // We have enough memory for only one of the two layers. > int memoryLimit = 4 * 300 * 300; // 4 bytes per pixel. >- OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit, memoryLimit); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(FakeTextureAllocator::create(), memoryLimit, memoryLimit, memoryLimit); > > RefPtr<FakeTiledLayerChromium> rootLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); > RefPtr<FakeTiledLayerChromium> childLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); >@@ -445,8 +450,8 @@ TEST(TiledLayerChromiumTest, skipsDrawGetsReset) > rootLayer->invalidateRect(contentRect); > childLayer->invalidateRect(contentRect); > >- FakeTextureAllocator textureAllocator; >- CCTextureUpdater updater(&textureAllocator); >+ OwnPtr<TextureAllocatorBinding> allocatorBinding = PassthroughTextureAllocatorBinding::create(); >+ CCTextureUpdater updater(allocatorBinding.get()); > > ccLayerTreeHost->setRootLayer(rootLayer); > ccLayerTreeHost->setViewportSize(IntSize(300, 300)); >@@ -474,7 +479,7 @@ TEST(TiledLayerChromiumTest, skipsDrawGetsReset) > > TEST(TiledLayerChromiumTest, layerAddsSelfToOccludedRegion) > { >- OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(FakeTextureAllocator::create(), 4*1024*1024, 2*1024*1024, 1024); > RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); > > // The tile size is 100x100, so this invalidates and then paints two tiles in various ways. >@@ -568,7 +573,7 @@ TEST(TiledLayerChromiumTest, layerAddsSelfToOccludedRegion) > > TEST(TiledLayerChromiumTest, resizeToSmaller) > { >- OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024); >+ OwnPtr<TextureManager> textureManager = TextureManager::create(FakeTextureAllocator::create(), 60*1024*1024, 60*1024*1024, 1024); > RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); > > layer->setBounds(IntSize(700, 700));
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 76295
:
123410
|
123571
|
125893