[chromium] LayerRendererChromium is not getting visibility messages in single threade...
authorjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jun 2012 23:52:48 +0000 (23:52 +0000)
committerjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jun 2012 23:52:48 +0000 (23:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=89045

Reviewed by Adrienne Walker.

Based on patch by Michal Mocny <mmocny@google.com>.

Source/WebCore:

Invariants:

1.) We never commit (paint, animate, any of it) when not visible on the main thread -except- for
compositeAndReadback, regardless of threaded vs non-threaded mode
2.) CCLayerTreeHost::m_contentsTextureManager's memory budget is only set by updateLayers() when we are going to
make a frame and is always set to a non-zero value
3.) Zero-sized allocations from the GPU process are always serviced immediately on the impl thread.  Non-zero
allocations are met in the next frame, whenever we would produce that frame according to our usual frame
scheduling logic.
4.) The impl thread always knows the set of currently-allocated managed texture IDs and can delete them all
whenever it likes without needing the main thread to be responsive.

Details:

There are two main changes - tweaking how the contents texture manager's budget is handled and tweaking frame
scheduling for the !visible case.

The scheduling change is a bit more subtle but it unifies the single and multi threaded paths and is really
important.  Except for compositeAndReadback (which I'll talk about below), we simply won't produce frames when
not visible.  This already happens in the single threaded path thanks to render_widget so the only change is to
the threaded path.  The difficulty here is we might post a beginFrame task from the impl thread and then get a
setVisible(false) call on the main thread before the beginFrame task runs.  Since I'm making the setVisible()
call a blocking call from main thread -> impl thread, when the beginFrame task eventually does run on the main
thread we can know that the impl thread's notion of visibility is in sync with the main threads.  Thus I'm
planning to simply abort the frame before doing any processing on the main thread.  The scheduler will know if
it gets a beginFrameAborted and COMMIT_STATE_IDLE.

compositeAndReadback is special - this call currently does come in when we aren't visible (in single and
threaded mode) and we need to service it.  In particular, we need to send a beginFrame over and have it
not be ignored on the main thread.  For this I'm thinking of having the proxy keep track of whether it's
servicing a compositeAndReadback() and use that bit on the main thread to know to process the beginFrame
normally.  On the impl side, we need a few changes.  First, we have to allocate a default framebuffer
(ensureFramebufferCHROMIUM) even if we've dropped it previously and remember to discard it after the
readPixels().  Second, we have to provide a non-zero contents texture allocation on the beginFrame message, and
again remember to delete the textures after the readPixels().  Third, we have to know that the beginFrame is a
forced frame so when we get the beginFrameComplete we go ahead with the rest of the frame.  For this, I think
I'll have to add ACTION_BEGIN_FORCED_FRAME and a corresponding COMMIT_STATE_FORCED_FRAME_IN_PROGRESS so the
scheduler can keep track of the magicness of this frame, and then add some logic after the readpixels call to
drop resources after the readback.  It's probably a good time to stop swapping on readbacks too....

The contents texture manager's budget is only relevant when we want to make a frame, so it's now passed in on
the updateLayers().  Since we only make frames when we are visible and we never have a zero allocation when
visible (thanks to the frame scheduling changes above), this value is always non-zero.  The other thing the
texture manager needs to know about is if we've killed all of the underlying textures from the impl thread -
this bit is passed in by the proxy before the updateLayers() call.  This means if we're running while visible
and the manager wants to decrease our budget to something other than zero, we'll get a new (non-zero) allocation
on the impl thread, schedule a frame, then when it's time to make the frame pass the new lower limit in to
updateLayers(), then have the contents texture manager evict down to our new limit and make a frame with the new
budget.  When the commit completes we'll get notified on the impl thread of which textures the contents texture
manager decided to evict and issue the deleteTexture() calls on them.

The texture budget we pass in will be based on the most recent non-zero memory allocation we received from the
GPU memory manager, or some default value I'll pull out my ass if we haven't heard anything yet.  On compositor
initialization, we can't afford to wait for a round-trip through the GPU process to get a budget for the first
frame.  I don't think handling a decrease to a non-zero budget on a visible tab needs to be terribly urgent - we
can get to it when we get to making the next frame.  If we wanted to satisfy reduced texture budgets directly
from the impl thread, we could keep a priority-list ordered set of textures once we have priorities and delete
based on that.  Let's worry about that later.

* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererGpuMemoryAllocationChangedCallbackAdapter::onGpuMemoryAllocationChangedOnImpl):
(WebCore::LayerRendererChromium::LayerRendererChromium):
(WebCore::LayerRendererChromium::initialize):
(WebCore::LayerRendererChromium::setVisible):
(WebCore::LayerRendererChromium::setGpuMemoryAllocation):
(WebCore):
(WebCore::LayerRendererChromium::swapBuffers):
(WebCore::LayerRendererChromium::getFramebufferPixels):
* platform/graphics/chromium/LayerRendererChromium.h:
(WebCore):
(LayerRendererChromium):
* platform/graphics/chromium/TextureManager.cpp:
(WebCore::TextureManager::evictAndRemoveAllDeletedTextures):
(WebCore):
* platform/graphics/chromium/TextureManager.h:
(TextureAllocator):
(TextureManager):
* platform/graphics/chromium/TrackingTextureAllocator.cpp:
(WebCore::TrackingTextureAllocator::createTexture):
(WebCore::TrackingTextureAllocator::deleteTexture):
(WebCore):
(WebCore::TrackingTextureAllocator::deleteAllTextures):
* platform/graphics/chromium/TrackingTextureAllocator.h:
(TrackingTextureAllocator):
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::CCLayerTreeHost):
(WebCore::CCLayerTreeHost::initializeLayerRenderer):
(WebCore::CCLayerTreeHost::finishCommitOnImplThread):
(WebCore::CCLayerTreeHost::setVisible):
(WebCore::CCLayerTreeHost::evictAllContentTextures):
(WebCore::CCLayerTreeHost::updateLayers):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(CCLayerTreeHost):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl):
(WebCore::CCLayerTreeHostImpl::commitComplete):
(WebCore::CCLayerTreeHostImpl::canDraw):
(WebCore::CCLayerTreeHostImpl::context):
(WebCore::CCLayerTreeHostImpl::releaseContentsTextures):
(WebCore):
(WebCore::CCLayerTreeHostImpl::setMemoryAllocationLimitBytes):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
(CCLayerTreeHostImplClient):
(WebCore::CCLayerTreeHostImpl::contentsTexturesWerePurgedSinceLastCommit):
(WebCore::CCLayerTreeHostImpl::memoryAllocationLimitBytes):
(CCLayerTreeHostImpl):
* platform/graphics/chromium/cc/CCProxy.h:
(CCProxy):
* platform/graphics/chromium/cc/CCRenderer.h:
(CCRendererClient):
* platform/graphics/chromium/cc/CCScheduler.cpp:
(WebCore::CCScheduler::beginFrameComplete):
(WebCore::CCScheduler::beginFrameAborted):
(WebCore):
(WebCore::CCScheduler::didSwapBuffersComplete):
(WebCore::CCScheduler::didLoseContext):
(WebCore::CCScheduler::didRecreateContext):
(WebCore::CCScheduler::vsyncTick):
* platform/graphics/chromium/cc/CCScheduler.h:
(CCScheduler):
* platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp:
(WebCore::CCSchedulerStateMachine::beginFrameAborted):
(WebCore):
* platform/graphics/chromium/cc/CCSchedulerStateMachine.h:
* platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
(WebCore::CCSingleThreadProxy::setVisible):
(WebCore):
(WebCore::CCSingleThreadProxy::stop):
(WebCore::CCSingleThreadProxy::commitAndComposite):
* platform/graphics/chromium/cc/CCSingleThreadProxy.h:
(CCSingleThreadProxy):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::CCThreadProxy):
(WebCore::CCThreadProxy::compositeAndReadback):
(WebCore::CCThreadProxy::setVisible):
(WebCore):
(WebCore::CCThreadProxy::setVisibleOnImplThread):
(WebCore::CCThreadProxy::scheduledActionBeginFrame):
(WebCore::CCThreadProxy::beginFrame):
(WebCore::CCThreadProxy::beginFrameAbortedOnImplThread):
(WebCore::CCThreadProxy::scheduledActionDrawAndSwapInternal):
(WebCore::CCThreadProxy::layerTreeHostClosedOnImplThread):
* platform/graphics/chromium/cc/CCThreadProxy.h:
(CCThreadProxy):
(BeginFrameAndCommitState):
* platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
(WebCore::CCVideoLayerImpl::~CCVideoLayerImpl):
(WebCore::CCVideoLayerImpl::willDraw):
(WebCore::CCVideoLayerImpl::willDrawInternal):
(WebCore::CCVideoLayerImpl::FramePlane::allocateData):
(WebCore::CCVideoLayerImpl::FramePlane::freeData):
(WebCore::CCVideoLayerImpl::allocatePlaneData):
(WebCore::CCVideoLayerImpl::freePlaneData):
(WebCore::CCVideoLayerImpl::freeUnusedPlaneData):
(WebCore::CCVideoLayerImpl::didLoseContext):
* platform/graphics/chromium/cc/CCVideoLayerImpl.h:
(FramePlane):

Source/WebKit/chromium:

Update various test fixtures and tests to cover scheduling, visibility, and resource allocation changes.

* tests/CCLayerTreeHostImplTest.cpp:
* tests/CCLayerTreeHostTest.cpp:
(CCLayerTreeHostTestAbortFrameWhenInvisible):
(WTF::CCLayerTreeHostTestAbortFrameWhenInvisible::CCLayerTreeHostTestAbortFrameWhenInvisible):
(WTF::CCLayerTreeHostTestAbortFrameWhenInvisible::beginTest):
(WTF::CCLayerTreeHostTestAbortFrameWhenInvisible::afterTest):
(WTF):
(WTF::TEST_F):
(WTF::CCLayerTreeHostTestLayerOcclusion::beginTest):
(WTF::CCLayerTreeHostTestLayerOcclusionWithFilters::beginTest):
(WTF::CCLayerTreeHostTestManySurfaces::beginTest):
* tests/CCSchedulerStateMachineTest.cpp:
(WebCore::TEST):
* tests/CCTiledLayerTestCommon.h:
* tests/FakeWebGraphicsContext3D.h:
(WebKit::FakeWebGraphicsContext3D::FakeWebGraphicsContext3D):
(FakeWebGraphicsContext3D):
(WebKit::FakeWebGraphicsContext3D::createTexture):
* tests/LayerRendererChromiumTest.cpp:
(TEST_F):
* tests/TiledLayerChromiumTest.cpp:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@120982 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
LayoutTests/platform/chromium/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
Source/WebCore/platform/graphics/chromium/TextureManager.cpp
Source/WebCore/platform/graphics/chromium/TextureManager.h
Source/WebCore/platform/graphics/chromium/TrackingTextureAllocator.cpp
Source/WebCore/platform/graphics/chromium/TrackingTextureAllocator.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCProxy.h
Source/WebCore/platform/graphics/chromium/cc/CCRenderer.h
Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp
Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h
Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp
Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h
Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h
Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp
Source/WebKit/chromium/tests/CCTiledLayerTestCommon.h
Source/WebKit/chromium/tests/FakeWebGraphicsContext3D.h
Source/WebKit/chromium/tests/LayerRendererChromiumTest.cpp
Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp

index 2425a9e..2e2ba02 100644 (file)
@@ -3528,6 +3528,9 @@ BUGWK85120 : fast/js/toString-number.html = TEXT
 
 BUGWK68744 : fast/block/float/float-not-removed-from-next-sibling4.html = IMAGE
 
+// Needs a new set of baselines due to generating less useless invalidations.
+BUGWK89045 : compositing/video-page-visibility.html = IMAGE
+
 BUGWK83076 SNOWLEOPARD RELEASE : compositing/geometry/outline-change.html = TIMEOUT PASS
 BUGWK83076 SNOWLEOPARD RELEASE : css3/selectors3/xml/css3-modsel-161.xml = TIMEOUT PASS
 BUGWK83076 SNOWLEOPARD RELEASE : css3/selectors3/xml/css3-modsel-166.xml = TIMEOUT PASS
index 8d2642c..d1f3df1 100644 (file)
@@ -1,3 +1,170 @@
+2012-06-19  James Robinson  <jamesr@chromium.org>
+
+        [chromium] LayerRendererChromium is not getting visibility messages in single threaded compositing mode.
+        https://bugs.webkit.org/show_bug.cgi?id=89045
+
+        Reviewed by Adrienne Walker.
+
+        Based on patch by Michal Mocny <mmocny@google.com>.
+
+        Invariants:
+
+        1.) We never commit (paint, animate, any of it) when not visible on the main thread -except- for
+        compositeAndReadback, regardless of threaded vs non-threaded mode
+        2.) CCLayerTreeHost::m_contentsTextureManager's memory budget is only set by updateLayers() when we are going to
+        make a frame and is always set to a non-zero value
+        3.) Zero-sized allocations from the GPU process are always serviced immediately on the impl thread.  Non-zero
+        allocations are met in the next frame, whenever we would produce that frame according to our usual frame
+        scheduling logic.
+        4.) The impl thread always knows the set of currently-allocated managed texture IDs and can delete them all
+        whenever it likes without needing the main thread to be responsive.
+
+        Details:
+
+        There are two main changes - tweaking how the contents texture manager's budget is handled and tweaking frame
+        scheduling for the !visible case.
+
+        The scheduling change is a bit more subtle but it unifies the single and multi threaded paths and is really
+        important.  Except for compositeAndReadback (which I'll talk about below), we simply won't produce frames when
+        not visible.  This already happens in the single threaded path thanks to render_widget so the only change is to
+        the threaded path.  The difficulty here is we might post a beginFrame task from the impl thread and then get a
+        setVisible(false) call on the main thread before the beginFrame task runs.  Since I'm making the setVisible()
+        call a blocking call from main thread -> impl thread, when the beginFrame task eventually does run on the main
+        thread we can know that the impl thread's notion of visibility is in sync with the main threads.  Thus I'm
+        planning to simply abort the frame before doing any processing on the main thread.  The scheduler will know if
+        it gets a beginFrameAborted and COMMIT_STATE_IDLE.
+
+        compositeAndReadback is special - this call currently does come in when we aren't visible (in single and
+        threaded mode) and we need to service it.  In particular, we need to send a beginFrame over and have it
+        not be ignored on the main thread.  For this I'm thinking of having the proxy keep track of whether it's
+        servicing a compositeAndReadback() and use that bit on the main thread to know to process the beginFrame
+        normally.  On the impl side, we need a few changes.  First, we have to allocate a default framebuffer
+        (ensureFramebufferCHROMIUM) even if we've dropped it previously and remember to discard it after the
+        readPixels().  Second, we have to provide a non-zero contents texture allocation on the beginFrame message, and
+        again remember to delete the textures after the readPixels().  Third, we have to know that the beginFrame is a
+        forced frame so when we get the beginFrameComplete we go ahead with the rest of the frame.  For this, I think
+        I'll have to add ACTION_BEGIN_FORCED_FRAME and a corresponding COMMIT_STATE_FORCED_FRAME_IN_PROGRESS so the
+        scheduler can keep track of the magicness of this frame, and then add some logic after the readpixels call to
+        drop resources after the readback.  It's probably a good time to stop swapping on readbacks too....
+
+        The contents texture manager's budget is only relevant when we want to make a frame, so it's now passed in on
+        the updateLayers().  Since we only make frames when we are visible and we never have a zero allocation when
+        visible (thanks to the frame scheduling changes above), this value is always non-zero.  The other thing the
+        texture manager needs to know about is if we've killed all of the underlying textures from the impl thread -
+        this bit is passed in by the proxy before the updateLayers() call.  This means if we're running while visible
+        and the manager wants to decrease our budget to something other than zero, we'll get a new (non-zero) allocation
+        on the impl thread, schedule a frame, then when it's time to make the frame pass the new lower limit in to
+        updateLayers(), then have the contents texture manager evict down to our new limit and make a frame with the new
+        budget.  When the commit completes we'll get notified on the impl thread of which textures the contents texture
+        manager decided to evict and issue the deleteTexture() calls on them.
+
+        The texture budget we pass in will be based on the most recent non-zero memory allocation we received from the
+        GPU memory manager, or some default value I'll pull out my ass if we haven't heard anything yet.  On compositor
+        initialization, we can't afford to wait for a round-trip through the GPU process to get a budget for the first
+        frame.  I don't think handling a decrease to a non-zero budget on a visible tab needs to be terribly urgent - we
+        can get to it when we get to making the next frame.  If we wanted to satisfy reduced texture budgets directly
+        from the impl thread, we could keep a priority-list ordered set of textures once we have priorities and delete
+        based on that.  Let's worry about that later.
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererGpuMemoryAllocationChangedCallbackAdapter::onGpuMemoryAllocationChangedOnImpl):
+        (WebCore::LayerRendererChromium::LayerRendererChromium):
+        (WebCore::LayerRendererChromium::initialize):
+        (WebCore::LayerRendererChromium::setVisible):
+        (WebCore::LayerRendererChromium::setGpuMemoryAllocation):
+        (WebCore):
+        (WebCore::LayerRendererChromium::swapBuffers):
+        (WebCore::LayerRendererChromium::getFramebufferPixels):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        (WebCore):
+        (LayerRendererChromium):
+        * platform/graphics/chromium/TextureManager.cpp:
+        (WebCore::TextureManager::evictAndRemoveAllDeletedTextures):
+        (WebCore):
+        * platform/graphics/chromium/TextureManager.h:
+        (TextureAllocator):
+        (TextureManager):
+        * platform/graphics/chromium/TrackingTextureAllocator.cpp:
+        (WebCore::TrackingTextureAllocator::createTexture):
+        (WebCore::TrackingTextureAllocator::deleteTexture):
+        (WebCore):
+        (WebCore::TrackingTextureAllocator::deleteAllTextures):
+        * platform/graphics/chromium/TrackingTextureAllocator.h:
+        (TrackingTextureAllocator):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+        (WebCore::CCLayerTreeHost::CCLayerTreeHost):
+        (WebCore::CCLayerTreeHost::initializeLayerRenderer):
+        (WebCore::CCLayerTreeHost::finishCommitOnImplThread):
+        (WebCore::CCLayerTreeHost::setVisible):
+        (WebCore::CCLayerTreeHost::evictAllContentTextures):
+        (WebCore::CCLayerTreeHost::updateLayers):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+        (CCLayerTreeHost):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+        (WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl):
+        (WebCore::CCLayerTreeHostImpl::commitComplete):
+        (WebCore::CCLayerTreeHostImpl::canDraw):
+        (WebCore::CCLayerTreeHostImpl::context):
+        (WebCore::CCLayerTreeHostImpl::releaseContentsTextures):
+        (WebCore):
+        (WebCore::CCLayerTreeHostImpl::setMemoryAllocationLimitBytes):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+        (CCLayerTreeHostImplClient):
+        (WebCore::CCLayerTreeHostImpl::contentsTexturesWerePurgedSinceLastCommit):
+        (WebCore::CCLayerTreeHostImpl::memoryAllocationLimitBytes):
+        (CCLayerTreeHostImpl):
+        * platform/graphics/chromium/cc/CCProxy.h:
+        (CCProxy):
+        * platform/graphics/chromium/cc/CCRenderer.h:
+        (CCRendererClient):
+        * platform/graphics/chromium/cc/CCScheduler.cpp:
+        (WebCore::CCScheduler::beginFrameComplete):
+        (WebCore::CCScheduler::beginFrameAborted):
+        (WebCore):
+        (WebCore::CCScheduler::didSwapBuffersComplete):
+        (WebCore::CCScheduler::didLoseContext):
+        (WebCore::CCScheduler::didRecreateContext):
+        (WebCore::CCScheduler::vsyncTick):
+        * platform/graphics/chromium/cc/CCScheduler.h:
+        (CCScheduler):
+        * platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp:
+        (WebCore::CCSchedulerStateMachine::beginFrameAborted):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCSchedulerStateMachine.h:
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
+        (WebCore::CCSingleThreadProxy::setVisible):
+        (WebCore):
+        (WebCore::CCSingleThreadProxy::stop):
+        (WebCore::CCSingleThreadProxy::commitAndComposite):
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.h:
+        (CCSingleThreadProxy):
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxy::CCThreadProxy):
+        (WebCore::CCThreadProxy::compositeAndReadback):
+        (WebCore::CCThreadProxy::setVisible):
+        (WebCore):
+        (WebCore::CCThreadProxy::setVisibleOnImplThread):
+        (WebCore::CCThreadProxy::scheduledActionBeginFrame):
+        (WebCore::CCThreadProxy::beginFrame):
+        (WebCore::CCThreadProxy::beginFrameAbortedOnImplThread):
+        (WebCore::CCThreadProxy::scheduledActionDrawAndSwapInternal):
+        (WebCore::CCThreadProxy::layerTreeHostClosedOnImplThread):
+        * platform/graphics/chromium/cc/CCThreadProxy.h:
+        (CCThreadProxy):
+        (BeginFrameAndCommitState):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
+        (WebCore::CCVideoLayerImpl::~CCVideoLayerImpl):
+        (WebCore::CCVideoLayerImpl::willDraw):
+        (WebCore::CCVideoLayerImpl::willDrawInternal):
+        (WebCore::CCVideoLayerImpl::FramePlane::allocateData):
+        (WebCore::CCVideoLayerImpl::FramePlane::freeData):
+        (WebCore::CCVideoLayerImpl::allocatePlaneData):
+        (WebCore::CCVideoLayerImpl::freePlaneData):
+        (WebCore::CCVideoLayerImpl::freeUnusedPlaneData):
+        (WebCore::CCVideoLayerImpl::didLoseContext):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.h:
+        (FramePlane):
+
 2012-06-20  Ryosuke Niwa  <rniwa@webkit.org>
 
         Shrink NodeListsNodeData
index b6ca674..595cae2 100644 (file)
@@ -35,7 +35,6 @@
 #include "LayerRendererChromium.h"
 
 #include "Extensions3D.h"
-#include "Extensions3DChromium.h"
 #include "FloatQuad.h"
 #include "GeometryBinding.h"
 #include "GrTexture.h"
@@ -219,11 +218,7 @@ private:
     void onGpuMemoryAllocationChangedOnImpl(Extensions3DChromium::GpuMemoryAllocationCHROMIUM allocation)
     {
         ASSERT(CCProxy::isImplThread());
-        if (!allocation.suggestHaveBackbuffer)
-            m_layerRenderer->discardFramebuffer();
-        else
-            m_layerRenderer->ensureFramebuffer();
-        m_layerRenderer->m_client->setContentsMemoryAllocationLimitBytes(allocation.gpuResourceSizeInBytes);
+        m_layerRenderer->setGpuMemoryAllocation(allocation);
     }
 
     LayerRendererChromium* m_layerRenderer;
@@ -251,6 +246,7 @@ LayerRendererChromium::LayerRendererChromium(CCRendererClient* client,
     , m_defaultRenderPass(0)
     , m_isViewportChanged(false)
     , m_isFramebufferDiscarded(false)
+    , m_visible(true)
     , m_textureUploaderSetting(textureUploaderSetting)
 {
     ASSERT(m_context.get());
@@ -334,7 +330,7 @@ bool LayerRendererChromium::initialize()
         Extensions3DChromium* extensions3DChromium = static_cast<Extensions3DChromium*>(extensions);
         extensions3DChromium->setGpuMemoryAllocationChangedCallbackCHROMIUM(LayerRendererGpuMemoryAllocationChangedCallbackAdapter::create(this));
     } else {
-        m_client->setContentsMemoryAllocationLimitBytes(TextureManager::highLimitBytes(viewportSize()));
+        m_client->setMemoryAllocationLimitBytes(TextureManager::highLimitBytes(viewportSize()));
     }
 
     m_capabilities.usingDiscardFramebuffer = extensions->supports("GL_CHROMIUM_discard_framebuffer");
@@ -375,8 +371,9 @@ void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char*
 
 void LayerRendererChromium::setVisible(bool visible)
 {
-    if (!visible)
-        releaseRenderPassTextures();
+    if (m_visible == visible)
+        return;
+    m_visible = visible;
 
     // TODO: Replace setVisibilityCHROMIUM with an extension to explicitly manage front/backbuffers
     // crbug.com/116049
@@ -1270,6 +1267,22 @@ void LayerRendererChromium::copyTextureToFramebuffer(int textureId, const IntSiz
                                     -1);
 }
 
+void LayerRendererChromium::setGpuMemoryAllocation(Extensions3DChromium::GpuMemoryAllocationCHROMIUM allocation)
+{
+    if (m_visible && !allocation.gpuResourceSizeInBytes)
+        return;
+
+    if (!allocation.suggestHaveBackbuffer && !m_visible)
+        discardFramebuffer();
+
+    if (!allocation.gpuResourceSizeInBytes) {
+        releaseRenderPassTextures();
+        m_client->releaseContentsTextures();
+        GLC(m_context, m_context->flush());
+    } else
+        m_client->setMemoryAllocationLimitBytes(allocation.gpuResourceSizeInBytes);
+}
+
 void LayerRendererChromium::finish()
 {
     TRACE_EVENT("LayerRendererChromium::finish", this, 0);
@@ -1278,12 +1291,8 @@ void LayerRendererChromium::finish()
 
 bool LayerRendererChromium::swapBuffers(const IntRect& subBuffer)
 {
-    // FIXME: Remove this once gpu process supports ignoring swap buffers command while framebuffer is discarded.
-    //        Alternatively (preferably?), protect all cc code so as not to attempt a swap after a framebuffer discard.
-    if (m_isFramebufferDiscarded) {
-        m_client->setFullRootLayerDamage();
-        return false;
-    }
+    ASSERT(m_visible);
+    ASSERT(!m_isFramebufferDiscarded);
 
     TRACE_EVENT("LayerRendererChromium::swapBuffers", this, 0);
     // We're done! Time to swapbuffers!
@@ -1387,6 +1396,14 @@ void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& re
         GLC(context, context->deleteFramebuffer(temporaryFBO));
         GLC(context, context->deleteTexture(temporaryTexture));
     }
+
+    if (!m_visible) {
+        TRACE_EVENT0("cc", "LayerRendererChromium::getFramebufferPixels dropping resources after readback");
+        discardFramebuffer();
+        releaseRenderPassTextures();
+        m_client->releaseContentsTextures();
+        GLC(m_context, m_context->flush());
+    }
 }
 
 bool LayerRendererChromium::getFramebufferTexture(ManagedTexture* texture, const IntRect& deviceRect)
index e525d07..f7ccb65 100644 (file)
@@ -34,6 +34,7 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
+#include "Extensions3DChromium.h"
 #include "TextureCopier.h"
 #include "TrackingTextureAllocator.h"
 #include "cc/CCRenderer.h"
@@ -53,7 +54,6 @@ class CCTileDrawQuad;
 class CCYUVVideoDrawQuad;
 class GeometryBinding;
 class GraphicsContext3D;
-class LayerRendererGpuMemoryAllocationChangedCallbackAdapter;
 class LayerRendererSwapBuffersCompleteCallbackAdapter;
 class ManagedTexture;
 class ScopedEnsureFramebufferAllocation;
@@ -111,9 +111,9 @@ public:
                           float width, float height, float opacity, const FloatQuad&,
                           int matrixLocation, int alphaLocation, int quadLocation);
     void copyTextureToFramebuffer(int textureId, const IntSize& bounds, const WebKit::WebTransformationMatrix& drawMatrix);
+    void setGpuMemoryAllocation(Extensions3DChromium::GpuMemoryAllocationCHROMIUM);
 
 protected:
-    friend class LayerRendererGpuMemoryAllocationChangedCallbackAdapter;
     void discardFramebuffer();
     void ensureFramebuffer();
     bool isFramebufferDiscarded() const { return m_isFramebufferDiscarded; }
@@ -258,6 +258,7 @@ private:
 
     bool m_isViewportChanged;
     bool m_isFramebufferDiscarded;
+    bool m_visible;
     TextureUploaderOption m_textureUploaderSetting;
 };
 
index 0a68840..d1f52fa 100644 (file)
@@ -242,6 +242,13 @@ void TextureManager::deleteEvictedTextures(TextureAllocator* allocator)
     m_evictedTextures.clear();
 }
 
+void TextureManager::evictAndRemoveAllDeletedTextures()
+{
+    unprotectAllTextures();
+    reduceMemoryToLimit(0);
+    m_evictedTextures.clear();
+}
+
 void TextureManager::evictAndDeleteAllTextures(TextureAllocator* allocator)
 {
     unprotectAllTextures();
index 3147635..7ca14f4 100644 (file)
@@ -44,6 +44,7 @@ class TextureAllocator {
 public:
     virtual unsigned createTexture(const IntSize&, GC3Denum format) = 0;
     virtual void deleteTexture(unsigned texture, const IntSize&, GC3Denum) = 0;
+    virtual void deleteAllTextures() = 0;
 
 protected:
     virtual ~TextureAllocator() { }
@@ -88,6 +89,7 @@ public:
     unsigned allocateTexture(TextureAllocator*, TextureToken);
     void deleteEvictedTextures(TextureAllocator*);
 
+    void evictAndRemoveAllDeletedTextures();
     void evictAndDeleteAllTextures(TextureAllocator*);
 
     void reduceMemoryToLimit(size_t);
index aa6c4ec..957711e 100644 (file)
@@ -89,6 +89,7 @@ unsigned TrackingTextureAllocator::createTexture(const IntSize& size, GC3Denum f
         extensions->texStorage2DEXT(GraphicsContext3D::TEXTURE_2D, 1, storageFormat, size.width(), size.height());
     } else
         GLC(m_context.get(), m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GraphicsContext3D::UNSIGNED_BYTE));
+    m_allocatedTextureIds.add(textureId);
     return textureId;
 }
 
@@ -96,6 +97,16 @@ void TrackingTextureAllocator::deleteTexture(unsigned textureId, const IntSize&
 {
     m_currentMemoryUseBytes -= TextureManager::memoryUseBytes(size, format);
     GLC(m_context.get(), m_context->deleteTexture(textureId));
+    ASSERT(m_allocatedTextureIds.contains(textureId));
+    m_allocatedTextureIds.remove(textureId);
+}
+
+void TrackingTextureAllocator::deleteAllTextures()
+{
+    for (HashSet<unsigned>::const_iterator it = m_allocatedTextureIds.begin(); it != m_allocatedTextureIds.end(); ++it)
+        GLC(m_context.get(), m_context->deleteTexture(*it));
+    m_currentMemoryUseBytes = 0;
+    m_allocatedTextureIds.clear();
 }
 
 }
index a8a5492..980b94e 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "GraphicsContext3D.h"
 #include "TextureManager.h"
+#include <wtf/HashSet.h>
 #include <wtf/PassRefPtr.h>
 
 namespace WebCore {
@@ -40,8 +41,9 @@ public:
     }
     virtual ~TrackingTextureAllocator();
 
-    virtual unsigned createTexture(const IntSize&, GC3Denum format);
-    virtual void deleteTexture(unsigned texture, const IntSize&, GC3Denum format);
+    virtual unsigned createTexture(const IntSize&, GC3Denum format) OVERRIDE;
+    virtual void deleteTexture(unsigned texture, const IntSize&, GC3Denum format) OVERRIDE;
+    virtual void deleteAllTextures() OVERRIDE;
 
     size_t currentMemoryUseBytes() const { return m_currentMemoryUseBytes; }
 
@@ -57,6 +59,7 @@ protected:
     size_t m_currentMemoryUseBytes;
     TextureUsageHint m_textureUsageHint;
     bool m_useTextureStorageExt;
+    HashSet<unsigned> m_allocatedTextureIds;
 };
 
 }
index bb6c064..7d14cf5 100644 (file)
@@ -73,7 +73,6 @@ CCLayerTreeHost::CCLayerTreeHost(CCLayerTreeHostClient* client, const CCLayerTre
     , m_needsAnimateLayers(false)
     , m_client(client)
     , m_frameNumber(0)
-    , m_frameIsForDisplay(false)
     , m_layerRendererInitialized(false)
     , m_contextLost(false)
     , m_numTimesRecreateShouldFail(0)
@@ -81,8 +80,6 @@ CCLayerTreeHost::CCLayerTreeHost(CCLayerTreeHostClient* client, const CCLayerTre
     , m_settings(settings)
     , m_deviceScaleFactor(1)
     , m_visible(true)
-    , m_memoryAllocationBytes(0)
-    , m_memoryAllocationIsForDisplay(false)
     , m_pageScaleFactor(1)
     , m_minPageScaleFactor(1)
     , m_maxPageScaleFactor(1)
@@ -152,11 +149,6 @@ void CCLayerTreeHost::initializeLayerRenderer()
 
     m_contentsTextureManager = TextureManager::create(0, 0, m_proxy->layerRendererCapabilities().maxTextureSize);
 
-    // FIXME: This is the same as setContentsMemoryAllocationLimitBytes, but
-    // we're in the middle of a commit here and don't want to force another.
-    m_memoryAllocationBytes = TextureManager::highLimitBytes(deviceViewportSize());
-    m_memoryAllocationIsForDisplay = true;
-
     m_layerRendererInitialized = true;
 
     m_settings.defaultTileSize = IntSize(min(m_settings.defaultTileSize.width(), m_proxy->layerRendererCapabilities().maxTextureSize),
@@ -257,8 +249,6 @@ void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl* hostImpl)
     hostImpl->setPageScaleFactorAndLimits(m_pageScaleFactor, m_minPageScaleFactor, m_maxPageScaleFactor);
     hostImpl->setBackgroundColor(m_backgroundColor);
     hostImpl->setHasTransparentBackground(m_hasTransparentBackground);
-    hostImpl->setVisible(m_visible);
-    hostImpl->setSourceFrameCanBeDrawn(m_frameIsForDisplay);
 
     m_frameNumber++;
 }
@@ -329,11 +319,6 @@ void CCLayerTreeHost::setNeedsCommit()
     m_proxy->setNeedsCommit();
 }
 
-void CCLayerTreeHost::setNeedsForcedCommit()
-{
-    m_proxy->setNeedsForcedCommit();
-}
-
 void CCLayerTreeHost::setNeedsRedraw()
 {
     m_proxy->setNeedsRedraw();
@@ -399,35 +384,15 @@ void CCLayerTreeHost::setVisible(bool visible)
 {
     if (m_visible == visible)
         return;
-
     m_visible = visible;
-
-    // FIXME: Remove this stuff, it is here just for the m20 merge.
-    if (!m_visible && m_layerRendererInitialized) {
-        if (m_proxy->layerRendererCapabilities().contextHasCachedFrontBuffer)
-            setContentsMemoryAllocationLimitBytes(0);
-        else
-            setContentsMemoryAllocationLimitBytes(m_contentsTextureManager->preferredMemoryLimitBytes());
-    }
-
-    setNeedsForcedCommit();
+    m_proxy->setVisible(visible);
 }
 
-void CCLayerTreeHost::setContentsMemoryAllocationLimitBytes(size_t bytes)
+void CCLayerTreeHost::evictAllContentTextures()
 {
     ASSERT(CCProxy::isMainThread());
-    if (m_memoryAllocationBytes == bytes)
-        return;
-
-    m_memoryAllocationBytes = bytes;
-    m_memoryAllocationIsForDisplay = bytes;
-
-    // When not visible, force a commit so that we change our memory allocation
-    // and evict/delete any textures if we are being requested to.
-    if (!m_visible)
-        setNeedsForcedCommit();
-    else
-        setNeedsCommit();
+    ASSERT(m_contentsTextureManager.get());
+    m_contentsTextureManager->evictAndRemoveAllDeletedTextures();
 }
 
 void CCLayerTreeHost::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec)
@@ -474,19 +439,10 @@ bool CCLayerTreeHost::initializeLayerRendererIfNeeded()
 }
 
 
-void CCLayerTreeHost::updateLayers(CCTextureUpdater& updater)
+void CCLayerTreeHost::updateLayers(CCTextureUpdater& updater, size_t contentsMemoryLimitBytes)
 {
     ASSERT(m_layerRendererInitialized);
-    // The visible state and memory allocation are set independently and in
-    // arbitrary order, so do not change the memory allocation used for the
-    // current commit until both values match intentions.
-    // FIXME: These two states should be combined into a single action so we
-    // need a single commit to change visible state, and this can be removed.
-    bool memoryAllocationStateMatchesVisibility = m_visible == m_memoryAllocationIsForDisplay;
-    if (memoryAllocationStateMatchesVisibility) {
-        m_contentsTextureManager->setMemoryAllocationLimitBytes(m_memoryAllocationBytes);
-        m_frameIsForDisplay = m_memoryAllocationIsForDisplay;
-    }
+    ASSERT(contentsMemoryLimitBytes);
 
     if (!rootLayer())
         return;
@@ -494,6 +450,8 @@ void CCLayerTreeHost::updateLayers(CCTextureUpdater& updater)
     if (viewportSize().isEmpty())
         return;
 
+    m_contentsTextureManager->setMemoryAllocationLimitBytes(contentsMemoryLimitBytes);
+
     updateLayers(rootLayer(), updater);
 }
 
index 58b7d2b..6f6946e 100644 (file)
@@ -171,7 +171,7 @@ public:
     virtual void acquireLayerTextures();
     // Returns false if we should abort this frame due to initialization failure.
     bool initializeLayerRendererIfNeeded();
-    void updateLayers(CCTextureUpdater&);
+    void updateLayers(CCTextureUpdater&, size_t contentsMemoryLimitBytes);
 
     CCLayerTreeHostClient* client() { return m_client; }
 
@@ -202,7 +202,6 @@ public:
     void setNeedsAnimate();
     // virtual for testing
     virtual void setNeedsCommit();
-    void setNeedsForcedCommit();
     void setNeedsRedraw();
     bool commitRequested() const;
 
@@ -228,7 +227,12 @@ public:
     void setHasTransparentBackground(bool transparent) { m_hasTransparentBackground = transparent; }
 
     TextureManager* contentsTextureManager() const;
-    void setContentsMemoryAllocationLimitBytes(size_t);
+
+    // This will cause contents texture manager to evict all textures, but
+    // without deleting them. This happens after all content textures have
+    // already been deleted on impl, after getting a 0 allocation limit.
+    // Set during a commit, but before updateLayers.
+    void evictAllContentTextures();
 
     bool visible() const { return m_visible; }
     void setVisible(bool);
@@ -281,7 +285,6 @@ private:
     CCLayerTreeHostClient* m_client;
 
     int m_frameNumber;
-    bool m_frameIsForDisplay;
 
     OwnPtr<CCProxy> m_proxy;
     bool m_layerRendererInitialized;
@@ -300,9 +303,6 @@ private:
 
     bool m_visible;
 
-    size_t m_memoryAllocationBytes;
-    bool m_memoryAllocationIsForDisplay;
-
     typedef HashMap<WebKit::WebGraphicsContext3D*, RefPtr<RateLimiter> > RateLimiterMap;
     RateLimiterMap m_rateLimiters;
 
index 94141d6..9a11bd2 100644 (file)
@@ -29,6 +29,7 @@
 #include "LayerRendererChromium.h"
 #include "TextStream.h"
 #include "TraceEvent.h"
+#include "TrackingTextureAllocator.h"
 #include "cc/CCActiveGestureAnimation.h"
 #include "cc/CCDamageTracker.h"
 #include "cc/CCDebugRectHistory.h"
@@ -120,7 +121,8 @@ CCLayerTreeHostImpl::CCLayerTreeHostImpl(const CCLayerTreeSettings& settings, CC
     , m_settings(settings)
     , m_deviceScaleFactor(1)
     , m_visible(true)
-    , m_sourceFrameCanBeDrawn(true)
+    , m_contentsTexturesWerePurgedSinceLastCommit(false)
+    , m_memoryAllocationLimitBytes(TextureManager::highLimitBytes(viewportSize()))
     , m_headsUpDisplay(CCHeadsUpDisplay::create())
     , m_pageScale(1)
     , m_pageScaleDelta(1)
@@ -155,6 +157,7 @@ void CCLayerTreeHostImpl::commitComplete()
     // Recompute max scroll position; must be after layer content bounds are
     // updated.
     updateMaxScrollPosition();
+    m_contentsTexturesWerePurgedSinceLastCommit = false;
 }
 
 bool CCLayerTreeHostImpl::canDraw()
@@ -165,12 +168,12 @@ bool CCLayerTreeHostImpl::canDraw()
         return false;
     if (!m_layerRenderer)
         return false;
-    if (!m_sourceFrameCanBeDrawn)
+    if (m_contentsTexturesWerePurgedSinceLastCommit)
         return false;
     return true;
 }
 
-CCGraphicsContext* CCLayerTreeHostImpl::context()
+CCGraphicsContext* CCLayerTreeHostImpl::context() const
 {
     return m_context.get();
 }
@@ -467,9 +470,20 @@ bool CCLayerTreeHostImpl::prepareToDraw(FrameData& frame)
     return true;
 }
 
-void CCLayerTreeHostImpl::setContentsMemoryAllocationLimitBytes(size_t bytes)
+void CCLayerTreeHostImpl::releaseContentsTextures()
 {
-    m_client->postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(bytes);
+    contentsTextureAllocator()->deleteAllTextures();
+    m_contentsTexturesWerePurgedSinceLastCommit = true;
+}
+
+void CCLayerTreeHostImpl::setMemoryAllocationLimitBytes(size_t bytes)
+{
+    if (m_memoryAllocationLimitBytes == bytes)
+        return;
+    m_memoryAllocationLimitBytes = bytes;
+
+    ASSERT(bytes);
+    m_client->setNeedsCommitOnImplThread();
 }
 
 void CCLayerTreeHostImpl::drawLayers(const FrameData& frame)
index 8279124..939e42e 100644 (file)
@@ -57,7 +57,6 @@ public:
     virtual void setNeedsRedrawOnImplThread() = 0;
     virtual void setNeedsCommitOnImplThread() = 0;
     virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime) = 0;
-    virtual void postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(size_t) = 0;
 };
 
 // CCLayerTreeHostImpl owns the CCLayerImpl tree as well as associated rendering state
@@ -109,11 +108,12 @@ public:
     virtual void didLoseContext() OVERRIDE;
     virtual void onSwapBuffersComplete() OVERRIDE;
     virtual void setFullRootLayerDamage() OVERRIDE;
-    virtual void setContentsMemoryAllocationLimitBytes(size_t) OVERRIDE;
+    virtual void releaseContentsTextures() OVERRIDE;
+    virtual void setMemoryAllocationLimitBytes(size_t) OVERRIDE;
 
     // Implementation
     bool canDraw();
-    CCGraphicsContext* context();
+    CCGraphicsContext* context() const;
 
     String layerTreeAsText() const;
     void setFontAtlas(PassOwnPtr<CCFontAtlas>);
@@ -146,8 +146,8 @@ public:
     int sourceFrameNumber() const { return m_sourceFrameNumber; }
     void setSourceFrameNumber(int frameNumber) { m_sourceFrameNumber = frameNumber; }
 
-    bool sourceFrameCanBeDrawn() const { return m_sourceFrameCanBeDrawn; }
-    void setSourceFrameCanBeDrawn(bool sourceFrameCanBeDrawn) { m_sourceFrameCanBeDrawn = sourceFrameCanBeDrawn; }
+    bool contentsTexturesWerePurgedSinceLastCommit() const { return m_contentsTexturesWerePurgedSinceLastCommit; }
+    size_t memoryAllocationLimitBytes() const { return m_memoryAllocationLimitBytes; }
 
     const IntSize& viewportSize() const { return m_viewportSize; }
     void setViewportSize(const IntSize&);
@@ -235,7 +235,8 @@ private:
     IntSize m_deviceViewportSize;
     float m_deviceScaleFactor;
     bool m_visible;
-    bool m_sourceFrameCanBeDrawn;
+    bool m_contentsTexturesWerePurgedSinceLastCommit;
+    size_t m_memoryAllocationLimitBytes;
 
     OwnPtr<CCHeadsUpDisplay> m_headsUpDisplay;
 
index fb2cbba..1c2f9ca 100644 (file)
@@ -70,6 +70,8 @@ public:
     // Indicates that the compositing surface associated with our context is ready to use.
     virtual void setSurfaceReady() = 0;
 
+    virtual void setVisible(bool) = 0;
+
     // Attempts to initialize the layer renderer. Returns false if the context isn't usable for compositing.
     virtual bool initializeLayerRenderer() = 0;
 
@@ -83,7 +85,6 @@ public:
 
     virtual void setNeedsAnimate() = 0;
     virtual void setNeedsCommit() = 0;
-    virtual void setNeedsForcedCommit() = 0;
     virtual void setNeedsRedraw() = 0;
 
     virtual void didAddAnimation() = 0;
index b89089f..abad02b 100644 (file)
@@ -49,7 +49,8 @@ public:
     virtual void didLoseContext() = 0;
     virtual void onSwapBuffersComplete() = 0;
     virtual void setFullRootLayerDamage() = 0;
-    virtual void setContentsMemoryAllocationLimitBytes(size_t) = 0;
+    virtual void releaseContentsTextures() = 0;
+    virtual void setMemoryAllocationLimitBytes(size_t) = 0;
 };
 
 class CCRenderer {
index 84b8423..d8355bd 100644 (file)
@@ -88,11 +88,18 @@ void CCScheduler::setMainThreadNeedsLayerTextures()
 
 void CCScheduler::beginFrameComplete()
 {
-    TRACE_EVENT("CCScheduler::beginFrameComplete", this, 0);
+    TRACE_EVENT0("cc", "CCScheduler::beginFrameComplete");
     m_stateMachine.beginFrameComplete();
     processScheduledActions();
 }
 
+void CCScheduler::beginFrameAborted()
+{
+    TRACE_EVENT0("cc", "CCScheduler::beginFrameAborted");
+    m_stateMachine.beginFrameAborted();
+    processScheduledActions();
+}
+
 void CCScheduler::setMaxFramesPending(int maxFramesPending)
 {
     m_frameRateController->setMaxFramesPending(maxFramesPending);
@@ -100,13 +107,13 @@ void CCScheduler::setMaxFramesPending(int maxFramesPending)
 
 void CCScheduler::didSwapBuffersComplete()
 {
-    TRACE_EVENT("CCScheduler::didSwapBuffersComplete", this, 0);
+    TRACE_EVENT0("cc", "CCScheduler::didSwapBuffersComplete");
     m_frameRateController->didFinishFrame();
 }
 
 void CCScheduler::didLoseContext()
 {
-    TRACE_EVENT("CCScheduler::didLoseContext", this, 0);
+    TRACE_EVENT0("cc", "CCScheduler::didLoseContext");
     m_frameRateController->didAbortAllPendingFrames();
     m_stateMachine.didLoseContext();
     processScheduledActions();
@@ -114,7 +121,7 @@ void CCScheduler::didLoseContext()
 
 void CCScheduler::didRecreateContext()
 {
-    TRACE_EVENT("CCScheduler::didRecreateContext", this, 0);
+    TRACE_EVENT0("cc", "CCScheduler::didRecreateContext");
     m_stateMachine.didRecreateContext();
     processScheduledActions();
 }
@@ -125,7 +132,7 @@ void CCScheduler::vsyncTick()
         m_updateMoreResourcesPending = false;
         m_stateMachine.beginUpdateMoreResourcesComplete(m_client->hasMoreResourceUpdates());
     }
-    TRACE_EVENT("CCScheduler::vsyncTick", this, 0);
+    TRACE_EVENT0("cc", "CCScheduler::vsyncTick");
 
     m_stateMachine.didEnterVSync();
     processScheduledActions();
index 0e69716..3e6f7aa 100644 (file)
@@ -94,6 +94,7 @@ public:
     void setNeedsForcedRedraw();
 
     void beginFrameComplete();
+    void beginFrameAborted();
 
     void setMaxFramesPending(int);
     void didSwapBuffersComplete();
index 928a6d6..23ab9ae 100644 (file)
@@ -299,6 +299,12 @@ void CCSchedulerStateMachine::beginFrameComplete()
     m_commitState = COMMIT_STATE_UPDATING_RESOURCES;
 }
 
+void CCSchedulerStateMachine::beginFrameAborted()
+{
+    ASSERT(m_commitState == COMMIT_STATE_FRAME_IN_PROGRESS);
+    m_commitState = COMMIT_STATE_IDLE;
+}
+
 void CCSchedulerStateMachine::beginUpdateMoreResourcesComplete(bool morePending)
 {
     ASSERT(m_commitState == COMMIT_STATE_UPDATING_RESOURCES);
index a3a94c2..fe1b180 100644 (file)
@@ -120,6 +120,10 @@ public:
     // updating of compositor resources can begin.
     void beginFrameComplete();
 
+    // Call this only in response to receiving an ACTION_BEGIN_FRAME
+    // from nextState if the client rejects the beginFrame message.
+    void beginFrameAborted();
+
     // Call this only in response to receiving an ACTION_UPDATE_MORE_RESOURCES
     // from nextState. Indicates that the specific update request completed.
     void beginUpdateMoreResourcesComplete(bool morePending);
index 14cdf1c..f54ba77 100644 (file)
@@ -153,6 +153,12 @@ void CCSingleThreadProxy::setSurfaceReady()
     // Scheduling is controlled by the embedder in the single thread case, so nothing to do.
 }
 
+void CCSingleThreadProxy::setVisible(bool visible)
+{
+    DebugScopedSetImplThread impl;
+    m_layerTreeHostImpl->setVisible(visible);
+}
+
 bool CCSingleThreadProxy::initializeLayerRenderer()
 {
     ASSERT(CCProxy::isMainThread());
@@ -258,12 +264,6 @@ void CCSingleThreadProxy::setNeedsCommit()
     m_layerTreeHost->scheduleComposite();
 }
 
-void CCSingleThreadProxy::setNeedsForcedCommit()
-{
-    // This proxy doesn't block commits when not visible so use a normal commit.
-    setNeedsCommit();
-}
-
 void CCSingleThreadProxy::setNeedsRedraw()
 {
     // FIXME: Once we move render_widget scheduling into this class, we can
@@ -290,7 +290,8 @@ void CCSingleThreadProxy::stop()
         DebugScopedSetMainThreadBlocked mainThreadBlocked;
         DebugScopedSetImplThread impl;
 
-        m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
+        if (!m_layerTreeHostImpl->contentsTexturesWerePurgedSinceLastCommit())
+            m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
         m_layerTreeHostImpl.clear();
     }
     m_layerTreeHost = 0;
@@ -310,14 +311,6 @@ void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr
     m_layerTreeHost->setAnimationEvents(events, wallClockTime);
 }
 
-void CCSingleThreadProxy::postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(size_t bytes)
-{
-    ASSERT(CCProxy::isImplThread());
-    DebugScopedSetMainThread main;
-    ASSERT(m_layerTreeHost);
-    m_layerTreeHost->setContentsMemoryAllocationLimitBytes(bytes);
-}
-
 // Called by the legacy scheduling path (e.g. where render_widget does the scheduling)
 void CCSingleThreadProxy::compositeImmediately()
 {
@@ -345,11 +338,15 @@ bool CCSingleThreadProxy::commitAndComposite()
 {
     ASSERT(CCProxy::isMainThread());
 
+
     if (!m_layerTreeHost->initializeLayerRendererIfNeeded())
         return false;
 
+    if (m_layerTreeHostImpl->contentsTexturesWerePurgedSinceLastCommit())
+        m_layerTreeHost->evictAllContentTextures();
+
     CCTextureUpdater updater;
-    m_layerTreeHost->updateLayers(updater);
+    m_layerTreeHost->updateLayers(updater, m_layerTreeHostImpl->memoryAllocationLimitBytes());
 
     m_layerTreeHost->willCommit();
     doCommit(updater);
index 93c128b..46cb302 100644 (file)
@@ -49,6 +49,7 @@ public:
     virtual bool isStarted() const OVERRIDE;
     virtual bool initializeContext() OVERRIDE;
     virtual void setSurfaceReady() OVERRIDE;
+    virtual void setVisible(bool) OVERRIDE;
     virtual bool initializeLayerRenderer() OVERRIDE;
     virtual bool recreateContext() OVERRIDE;
     virtual int compositorIdentifier() const OVERRIDE { return m_compositorIdentifier; }
@@ -56,7 +57,6 @@ public:
     virtual void loseContext() OVERRIDE;
     virtual void setNeedsAnimate() OVERRIDE;
     virtual void setNeedsCommit() OVERRIDE;
-    virtual void setNeedsForcedCommit() OVERRIDE;
     virtual void setNeedsRedraw() OVERRIDE;
     virtual bool commitRequested() const OVERRIDE;
     virtual void didAddAnimation() OVERRIDE;
@@ -73,7 +73,6 @@ public:
     virtual void setNeedsRedrawOnImplThread() OVERRIDE { m_layerTreeHost->scheduleComposite(); }
     virtual void setNeedsCommitOnImplThread() OVERRIDE { m_layerTreeHost->scheduleComposite(); }
     virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE;
-    virtual void postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(size_t) OVERRIDE;
 
     // Called by the legacy path where RenderWidget does the scheduling.
     void compositeImmediately();
index a9bfbc1..e2ecb9c 100644 (file)
@@ -80,6 +80,7 @@ CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost)
     , m_layerRendererInitialized(false)
     , m_started(false)
     , m_texturesAcquired(true)
+    , m_inCompositeAndReadback(false)
     , m_mainThreadProxy(CCScopedThreadProxy::create(CCProxy::mainThread()))
     , m_beginFrameCompletionEventOnImplThread(0)
     , m_readbackRequestOnImplThread(0)
@@ -114,7 +115,9 @@ bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
     CCCompletionEvent beginFrameCompletion;
     CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::forceBeginFrameOnImplThread, AllowCrossThreadAccess(&beginFrameCompletion)));
     beginFrameCompletion.wait();
+    m_inCompositeAndReadback = true;
     beginFrame();
+    m_inCompositeAndReadback = false;
 
     // Perform a synchronous readback.
     ReadbackRequest request;
@@ -203,6 +206,22 @@ void CCThreadProxy::setSurfaceReadyOnImplThread()
     m_schedulerOnImplThread->setCanBeginFrame(true);
 }
 
+void CCThreadProxy::setVisible(bool visible)
+{
+    TRACE_EVENT0("cc", "CCThreadProxy::setVisible");
+    CCCompletionEvent completion;
+    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setVisibleOnImplThread, AllowCrossThreadAccess(&completion), visible));
+    completion.wait();
+}
+
+void CCThreadProxy::setVisibleOnImplThread(CCCompletionEvent* completion, bool visible)
+{
+    TRACE_EVENT0("cc", "CCThreadProxy::setVisibleOnImplThread");
+    m_layerTreeHostImpl->setVisible(visible);
+    m_schedulerOnImplThread->setVisible(visible);
+    completion->signal();
+}
+
 bool CCThreadProxy::initializeLayerRenderer()
 {
     TRACE_EVENT("CCThreadProxy::initializeLayerRenderer", this, 0);
@@ -300,18 +319,6 @@ void CCThreadProxy::setNeedsCommit()
     CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnImplThread));
 }
 
-void CCThreadProxy::setNeedsForcedCommit()
-{
-    ASSERT(isMainThread());
-    if (m_forcedCommitRequested)
-        return;
-
-    TRACE_EVENT("CCThreadProxy::setNeedsForcedCommit", this, 0);
-    m_commitRequested = true;
-    m_forcedCommitRequested = true;
-    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsForcedCommitOnImplThread));
-}
-
 void CCThreadProxy::didLoseContextOnImplThread()
 {
     ASSERT(isImplThread());
@@ -349,12 +356,6 @@ void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAni
     m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnimationEvents, events, wallClockTime));
 }
 
-void CCThreadProxy::postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(size_t bytes)
-{
-    ASSERT(isImplThread());
-    m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setContentsMemoryAllocationLimitBytes, bytes));
-}
-
 void CCThreadProxy::setNeedsRedraw()
 {
     ASSERT(isMainThread());
@@ -456,6 +457,8 @@ void CCThreadProxy::scheduledActionBeginFrame()
     m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
     m_currentTextureUpdaterOnImplThread = adoptPtr(new CCTextureUpdater);
     m_pendingBeginFrameRequest->updater = m_currentTextureUpdaterOnImplThread.get();
+    m_pendingBeginFrameRequest->contentsTexturesWereDeleted = m_layerTreeHostImpl->contentsTexturesWerePurgedSinceLastCommit();
+    m_pendingBeginFrameRequest->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAllocationLimitBytes();
 
     m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrame));
 
@@ -498,9 +501,17 @@ void CCThreadProxy::beginFrame()
     // Re-do the commit flow so that we don't send the scrollInfo on the BFAC message.
     m_layerTreeHost->applyScrollAndScale(*request->scrollInfo);
 
+    if (!m_inCompositeAndReadback && !m_layerTreeHost->visible()) {
+        m_commitRequested = false;
+        m_forcedCommitRequested = false;
+
+        TRACE_EVENT0("cc", "EarlyOut_NotVisible");
+        CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrameAbortedOnImplThread));
+        return;
+    }
+
     m_layerTreeHost->willBeginFrame();
 
-    // FIXME: recreate the context if it was requested by the impl thread.
     m_layerTreeHost->updateAnimations(request->monotonicFrameBeginTime);
     m_layerTreeHost->layout();
 
@@ -513,7 +524,10 @@ void CCThreadProxy::beginFrame()
     if (!m_layerTreeHost->initializeLayerRendererIfNeeded())
         return;
 
-    m_layerTreeHost->updateLayers(*request->updater);
+    if (request->contentsTexturesWereDeleted)
+        m_layerTreeHost->evictAllContentTextures();
+
+    m_layerTreeHost->updateLayers(*request->updater, request->memoryAllocationLimitBytes);
 
     // Once single buffered layers are committed, they cannot be modified until
     // they are drawn by the impl thread.
@@ -561,6 +575,16 @@ void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion
     m_schedulerOnImplThread->beginFrameComplete();
 }
 
+void CCThreadProxy::beginFrameAbortedOnImplThread()
+{
+    TRACE_EVENT0("cc", "CCThreadProxy::beginFrameAbortedOnImplThread");
+    ASSERT(isImplThread());
+    ASSERT(m_schedulerOnImplThread);
+    ASSERT(m_schedulerOnImplThread->commitPending());
+
+    m_schedulerOnImplThread->beginFrameAborted();
+}
+
 bool CCThreadProxy::hasMoreResourceUpdates() const
 {
     if (!m_currentTextureUpdaterOnImplThread)
@@ -661,9 +685,7 @@ CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapInte
         }
         m_readbackRequestOnImplThread->completion.signal();
         m_readbackRequestOnImplThread = 0;
-    }
-
-    if (drawFrame)
+    } else if (drawFrame)
         result.didSwap = m_layerTreeHostImpl->swapBuffers();
 
     // Tell the main thread that the the newly-commited frame was drawn.
@@ -746,14 +768,6 @@ void CCThreadProxy::setAnimationEvents(PassOwnPtr<CCAnimationEventsVector> event
     m_layerTreeHost->setAnimationEvents(events, wallClockTime);
 }
 
-void CCThreadProxy::setContentsMemoryAllocationLimitBytes(size_t bytes)
-{
-    ASSERT(isMainThread());
-    if (!m_layerTreeHost)
-        return;
-    m_layerTreeHost->setContentsMemoryAllocationLimitBytes(bytes);
-}
-
 class CCThreadProxyContextRecreationTimer : public CCTimer, CCTimerClient {
 public:
     static PassOwnPtr<CCThreadProxyContextRecreationTimer> create(CCThreadProxy* proxy) { return adoptPtr(new CCThreadProxyContextRecreationTimer(proxy)); }
@@ -836,7 +850,8 @@ void CCThreadProxy::layerTreeHostClosedOnImplThread(CCCompletionEvent* completio
 {
     TRACE_EVENT("CCThreadProxy::layerTreeHostClosedOnImplThread", this, 0);
     ASSERT(isImplThread());
-    m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
+    if (!m_layerTreeHostImpl->contentsTexturesWerePurgedSinceLastCommit())
+        m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->contentsTextureAllocator());
     m_inputHandlerOnImplThread.clear();
     m_layerTreeHostImpl.clear();
     m_schedulerOnImplThread.clear();
index 5521f2f..572f9f4 100644 (file)
@@ -56,6 +56,7 @@ public:
     virtual bool isStarted() const OVERRIDE;
     virtual bool initializeContext() OVERRIDE;
     virtual void setSurfaceReady() OVERRIDE;
+    virtual void setVisible(bool) OVERRIDE;
     virtual bool initializeLayerRenderer() OVERRIDE;
     virtual bool recreateContext() OVERRIDE;
     virtual int compositorIdentifier() const OVERRIDE;
@@ -63,7 +64,6 @@ public:
     virtual void loseContext() OVERRIDE;
     virtual void setNeedsAnimate() OVERRIDE;
     virtual void setNeedsCommit() OVERRIDE;
-    virtual void setNeedsForcedCommit() OVERRIDE;
     virtual void setNeedsRedraw() OVERRIDE;
     virtual bool commitRequested() const OVERRIDE;
     virtual void didAddAnimation() OVERRIDE { }
@@ -80,7 +80,6 @@ public:
     virtual void setNeedsRedrawOnImplThread() OVERRIDE;
     virtual void setNeedsCommitOnImplThread() OVERRIDE;
     virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE;
-    virtual void postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(size_t) OVERRIDE;
 
     // CCSchedulerClient implementation
     virtual bool canDraw() OVERRIDE;
@@ -108,6 +107,8 @@ private:
         double monotonicFrameBeginTime;
         OwnPtr<CCScrollAndScaleSet> scrollInfo;
         CCTextureUpdater* updater;
+        bool contentsTexturesWereDeleted;
+        size_t memoryAllocationLimitBytes;
     };
     OwnPtr<BeginFrameAndCommitState> m_pendingBeginFrameRequest;
 
@@ -116,7 +117,6 @@ private:
     void didCommitAndDrawFrame();
     void didCompleteSwapBuffers();
     void setAnimationEvents(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime);
-    void setContentsMemoryAllocationLimitBytes(size_t);
     void beginContextRecreation();
     void tryToRecreateContext();
 
@@ -129,11 +129,13 @@ private:
     };
     void forceBeginFrameOnImplThread(CCCompletionEvent*);
     void beginFrameCompleteOnImplThread(CCCompletionEvent*);
+    void beginFrameAbortedOnImplThread();
     void requestReadbackOnImplThread(ReadbackRequest*);
     void requestStartPageScaleAnimationOnImplThread(IntSize targetPosition, bool useAnchor, float scale, double durationSec);
     void finishAllRenderingOnImplThread(CCCompletionEvent*);
     void initializeImplOnImplThread(CCCompletionEvent*);
     void setSurfaceReadyOnImplThread();
+    void setVisibleOnImplThread(CCCompletionEvent*, bool);
     void initializeContextOnImplThread(CCGraphicsContext*);
     void initializeLayerRendererOnImplThread(CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*);
     void layerTreeHostClosedOnImplThread(CCCompletionEvent*);
@@ -157,6 +159,7 @@ private:
     LayerRendererCapabilities m_layerRendererCapabilitiesMainThreadCopy;
     bool m_started;
     bool m_texturesAcquired;
+    bool m_inCompositeAndReadback;
 
     OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl;
 
index 46e578f..dbb07a0 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "Extensions3DChromium.h"
 #include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h" // For GLC macro
 #include "LayerTextureSubImage.h"
 #include "NotImplemented.h"
 #include "TextStream.h"
@@ -75,7 +76,7 @@ CCVideoLayerImpl::~CCVideoLayerImpl()
         m_provider->setVideoFrameProviderClient(0);
         m_provider = 0;
     }
-    freePlaneData(layerTreeHostImpl()->layerRenderer());
+    freePlaneData(layerTreeHostImpl()->context());
 
 #if !ASSERT_DISABLED
     for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i)
@@ -125,7 +126,7 @@ void CCVideoLayerImpl::willDraw(CCRenderer* layerRenderer, CCGraphicsContext* co
     m_providerMutex.lock();
 
     willDrawInternal(layerRenderer, context);
-    freeUnusedPlaneData(layerRenderer);
+    freeUnusedPlaneData(context);
 
     if (!m_frame)
         m_providerMutex.unlock();
@@ -159,7 +160,7 @@ void CCVideoLayerImpl::willDrawInternal(CCRenderer* layerRenderer, CCGraphicsCon
         return;
     }
 
-    if (!allocatePlaneData(layerRenderer)) {
+    if (!allocatePlaneData(layerRenderer, context)) {
         m_provider->putCurrentFrame(m_frame);
         m_frame = 0;
         return;
@@ -282,25 +283,43 @@ IntSize CCVideoLayerImpl::computeVisibleSize(const WebKit::WebVideoFrame& frame,
     return IntSize(visibleWidth, visibleHeight);
 }
 
-bool CCVideoLayerImpl::FramePlane::allocateData(CCRenderer* layerRenderer)
+bool CCVideoLayerImpl::FramePlane::allocateData(CCGraphicsContext* context)
 {
     if (textureId)
         return true;
 
-    textureId = layerRenderer->contentsTextureAllocator()->createTexture(size, format);
+    GraphicsContext3D* context3D = context->context3D();
+    if (!context3D)
+        return false;
+
+    GLC(context3D, textureId = context3D->createTexture());
+    GLC(context3D, context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
+    // Do basic linear filtering on resize.
+    GLC(context3D, context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
+    GLC(context3D, context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
+    // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
+    GLC(context3D, context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
+    GLC(context3D, context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
+
+    GLC(context3D, context3D->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GraphicsContext3D::UNSIGNED_BYTE));
+
     return textureId;
 }
 
-void CCVideoLayerImpl::FramePlane::freeData(CCRenderer* layerRenderer)
+void CCVideoLayerImpl::FramePlane::freeData(CCGraphicsContext* context)
 {
     if (!textureId)
         return;
 
-    layerRenderer->contentsTextureAllocator()->deleteTexture(textureId, size, format);
+    GraphicsContext3D* context3D = context->context3D();
+    if (!context3D)
+        return;
+
+    GLC(context3D, context3D->deleteTexture(textureId));
     textureId = 0;
 }
 
-bool CCVideoLayerImpl::allocatePlaneData(CCRenderer* layerRenderer)
+bool CCVideoLayerImpl::allocatePlaneData(CCRenderer* layerRenderer, CCGraphicsContext* context)
 {
     int maxTextureSize = layerRenderer->capabilities().maxTextureSize;
     for (unsigned planeIndex = 0; planeIndex < m_frame->planes(); ++planeIndex) {
@@ -312,13 +331,13 @@ bool CCVideoLayerImpl::allocatePlaneData(CCRenderer* layerRenderer)
             return false;
 
         if (plane.size != requiredTextureSize || plane.format != m_format) {
-            plane.freeData(layerRenderer);
+            plane.freeData(context);
             plane.size = requiredTextureSize;
             plane.format = m_format;
         }
 
         if (!plane.textureId) {
-            if (!plane.allocateData(layerRenderer))
+            if (!plane.allocateData(context))
                 return false;
             plane.visibleSize = computeVisibleSize(*m_frame, planeIndex);
         }
@@ -351,17 +370,17 @@ bool CCVideoLayerImpl::copyPlaneData(CCRenderer* layerRenderer, CCGraphicsContex
     return true;
 }
 
-void CCVideoLayerImpl::freePlaneData(CCRenderer* layerRenderer)
+void CCVideoLayerImpl::freePlaneData(CCGraphicsContext* context)
 {
     for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i)
-        m_framePlanes[i].freeData(layerRenderer);
+        m_framePlanes[i].freeData(context);
 }
 
-void CCVideoLayerImpl::freeUnusedPlaneData(CCRenderer* layerRenderer)
+void CCVideoLayerImpl::freeUnusedPlaneData(CCGraphicsContext* context)
 {
     unsigned firstUnusedPlane = m_frame ? m_frame->planes() : 0;
     for (unsigned i = firstUnusedPlane; i < WebKit::WebVideoFrame::maxPlanes; ++i)
-        m_framePlanes[i].freeData(layerRenderer);
+        m_framePlanes[i].freeData(context);
 }
 
 void CCVideoLayerImpl::didReceiveFrame()
@@ -381,7 +400,7 @@ void CCVideoLayerImpl::didUpdateMatrix(const float matrix[16])
 
 void CCVideoLayerImpl::didLoseContext()
 {
-    freePlaneData(layerTreeHostImpl()->layerRenderer());
+    freePlaneData(layerTreeHostImpl()->context());
 }
 
 void CCVideoLayerImpl::setNeedsRedraw()
index bef1d5f..b2e088f 100644 (file)
@@ -75,8 +75,8 @@ public:
 
         FramePlane() : textureId(0) { }
 
-        bool allocateData(CCRenderer*);
-        void freeData(CCRenderer*);
+        bool allocateData(CCGraphicsContext*);
+        void freeData(CCGraphicsContext*);
     };
 
 private:
@@ -86,10 +86,10 @@ private:
     virtual const char* layerTypeAsString() const OVERRIDE { return "VideoLayer"; }
 
     void willDrawInternal(CCRenderer*, CCGraphicsContext*);
-    bool allocatePlaneData(CCRenderer*);
+    bool allocatePlaneData(CCRenderer*, CCGraphicsContext*);
     bool copyPlaneData(CCRenderer*, CCGraphicsContext*);
-    void freePlaneData(CCRenderer*);
-    void freeUnusedPlaneData(CCRenderer*);
+    void freePlaneData(CCGraphicsContext*);
+    void freeUnusedPlaneData(CCGraphicsContext*);
 
     // Guards the destruction of m_provider and the frame that it provides
     Mutex m_providerMutex;
index 00390df..e3b15e9 100644 (file)
@@ -1,3 +1,37 @@
+2012-06-19  James Robinson  <jamesr@chromium.org>
+
+        [chromium] LayerRendererChromium is not getting visibility messages in single threaded compositing mode.
+        https://bugs.webkit.org/show_bug.cgi?id=89045
+
+        Reviewed by Adrienne Walker.
+
+        Based on patch by Michal Mocny <mmocny@google.com>.
+
+        Update various test fixtures and tests to cover scheduling, visibility, and resource allocation changes.
+
+        * tests/CCLayerTreeHostImplTest.cpp:
+        * tests/CCLayerTreeHostTest.cpp:
+        (CCLayerTreeHostTestAbortFrameWhenInvisible):
+        (WTF::CCLayerTreeHostTestAbortFrameWhenInvisible::CCLayerTreeHostTestAbortFrameWhenInvisible):
+        (WTF::CCLayerTreeHostTestAbortFrameWhenInvisible::beginTest):
+        (WTF::CCLayerTreeHostTestAbortFrameWhenInvisible::afterTest):
+        (WTF):
+        (WTF::TEST_F):
+        (WTF::CCLayerTreeHostTestLayerOcclusion::beginTest):
+        (WTF::CCLayerTreeHostTestLayerOcclusionWithFilters::beginTest):
+        (WTF::CCLayerTreeHostTestManySurfaces::beginTest):
+        * tests/CCSchedulerStateMachineTest.cpp:
+        (WebCore::TEST):
+        * tests/CCTiledLayerTestCommon.h:
+        * tests/FakeWebGraphicsContext3D.h:
+        (WebKit::FakeWebGraphicsContext3D::FakeWebGraphicsContext3D):
+        (FakeWebGraphicsContext3D):
+        (WebKit::FakeWebGraphicsContext3D::createTexture):
+        * tests/LayerRendererChromiumTest.cpp:
+        (TEST_F):
+        * tests/TiledLayerChromiumTest.cpp:
+
+
 2012-06-21  Mike West  <mkwst@chromium.org>
 
         [Chromium] Enable CSP_NEXT on the Chromium port.
index 49536bb..d19b036 100644 (file)
@@ -81,7 +81,6 @@ public:
     virtual void setNeedsRedrawOnImplThread() OVERRIDE { m_didRequestRedraw = true; }
     virtual void setNeedsCommitOnImplThread() OVERRIDE { m_didRequestCommit = true; }
     virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE { }
-    virtual void postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(size_t) OVERRIDE { }
 
     PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHost(bool partialSwap, PassRefPtr<CCGraphicsContext> graphicsContext, PassOwnPtr<CCLayerImpl> rootPtr)
     {
@@ -1792,7 +1791,7 @@ TEST_F(CCLayerTreeHostImplTest, partialSwapNoUpdate)
     Mock::VerifyAndClearExpectations(&mockContext);
 }
 
-class PartialSwapContext: public FakeWebGraphicsContext3D {
+class PartialSwapContext : public FakeWebGraphicsContext3D {
 public:
     WebString getString(WGC3Denum name)
     {
@@ -2041,12 +2040,17 @@ private:
 // FakeWebGraphicsContext3D have an id of 1).
 class StrictWebGraphicsContext3D : public FakeWebGraphicsContext3D {
 public:
+    StrictWebGraphicsContext3D()
+        : FakeWebGraphicsContext3D()
+    {
+        m_nextTextureId = 7; // Start allocating texture ids larger than any other resource IDs so we can tell if someone's mixing up their resource types.
+    }
+
     virtual WebGLId createBuffer() { return 2; }
     virtual WebGLId createFramebuffer() { return 3; }
     virtual WebGLId createProgram() { return 4; }
     virtual WebGLId createRenderbuffer() { return 5; }
     virtual WebGLId createShader(WGC3Denum) { return 6; }
-    virtual WebGLId createTexture() { return 7; }
 
     virtual void deleteBuffer(WebGLId id)
     {
@@ -2078,10 +2082,17 @@ public:
             ADD_FAILURE() << "Trying to delete shader id " << id;
     }
 
+    virtual WebGLId createTexture()
+    {
+        unsigned textureId = FakeWebGraphicsContext3D::createTexture();
+        m_allocatedTextureIds.add(textureId);
+        return textureId;
+    }
     virtual void deleteTexture(WebGLId id)
     {
-        if (id != 7)
+        if (!m_allocatedTextureIds.contains(id))
             ADD_FAILURE() << "Trying to delete texture id " << id;
+        m_allocatedTextureIds.remove(id);
     }
 
     virtual void bindBuffer(WGC3Denum, WebGLId id)
@@ -2116,7 +2127,7 @@ public:
 
     virtual void bindTexture(WGC3Denum, WebGLId id)
     {
-        if (id != 7 && id)
+        if (id && !m_allocatedTextureIds.contains(id))
             ADD_FAILURE() << "Trying to bind texture id " << id;
     }
 
@@ -2124,6 +2135,9 @@ public:
     {
         return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new StrictWebGraphicsContext3D()), GraphicsContext3D::RenderDirectlyToHostWindow);
     }
+
+private:
+    HashSet<unsigned> m_allocatedTextureIds;
 };
 
 // Fake video frame that represents a 4x4 YUV video frame.
@@ -2263,14 +2277,13 @@ TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext)
 class TrackingWebGraphicsContext3D : public FakeWebGraphicsContext3D {
 public:
     TrackingWebGraphicsContext3D()
-        : m_nextTextureId(1)
+        : FakeWebGraphicsContext3D()
         , m_numTextures(0)
     { }
 
     virtual WebGLId createTexture() OVERRIDE
     {
-        WebGLId id = m_nextTextureId;
-        ++m_nextTextureId;
+        WebGLId id = FakeWebGraphicsContext3D::createTexture();
 
         m_textures.set(id, true);
         ++m_numTextures;
@@ -2302,7 +2315,6 @@ public:
     unsigned numTextures() const { return m_numTextures; }
 
 private:
-    WebGLId m_nextTextureId;
     HashMap<WebGLId, bool> m_textures;
     unsigned m_numTextures;
 };
index 4a2fd31..d277379 100644 (file)
@@ -486,6 +486,40 @@ TEST_F(CCLayerTreeHostTestCompositeAndReadbackWhileInvisible, runMultiThread)
     runTestThreaded();
 }
 
+class CCLayerTreeHostTestAbortFrameWhenInvisible : public CCLayerTreeHostTestThreadOnly {
+public:
+    CCLayerTreeHostTestAbortFrameWhenInvisible()
+    {
+    }
+
+    virtual void beginTest()
+    {
+        // Request a commit (from the main thread), which will trigger the commit flow from the impl side.
+        m_layerTreeHost->setNeedsCommit();
+        // Then mark ourselves as not visible before processing any more messages on the main thread.
+        m_layerTreeHost->setVisible(false);
+        // If we make it without kicking a frame, we pass!
+        endTestAfterDelay(1);
+    }
+
+    virtual void layout() OVERRIDE
+    {
+        ASSERT_FALSE(true);
+        endTest();
+    }
+
+    virtual void afterTest()
+    {
+    }
+
+private:
+};
+
+TEST_F(CCLayerTreeHostTestAbortFrameWhenInvisible, runMultiThread)
+{
+    runTestThreaded();
+}
+
 
 // Trigger a frame with setNeedsCommit. Then, inside the resulting animate
 // callback, requet another frame using setNeedsAnimate. End the test when
@@ -997,113 +1031,6 @@ TEST_F(CCLayerTreeHostTestCommit, runTest)
     runTest(true);
 }
 
-class CCLayerTreeHostTestVisibilityAndAllocationControlDrawing : public CCLayerTreeHostTest {
-public:
-
-    CCLayerTreeHostTestVisibilityAndAllocationControlDrawing() { }
-
-    virtual void beginTest()
-    {
-        postSetNeedsCommitToMainThread();
-    }
-
-    virtual void didCommitAndDrawFrame()
-    {
-        int lastFrame = m_layerTreeHost->frameNumber() - 1;
-
-        // These frames should draw.
-        switch (lastFrame) {
-        case 0:
-            // Set the tree invisible, this should not draw.
-            m_layerTreeHost->setVisible(false);
-            break;
-        case 2:
-            // Set the tree invisible and give a non-visible allocation, this
-            // should not draw.
-            m_layerTreeHost->setVisible(false);
-            m_layerTreeHost->setContentsMemoryAllocationLimitBytes(0);
-            break;
-        case 5:
-            // Give a memory allocation not for display, but while we are
-            // visible. This should not be used and we should remain
-            // ready for display and it should draw.
-            m_layerTreeHost->setContentsMemoryAllocationLimitBytes(0);
-            break;
-        case 6:
-            endTest();
-            break;
-
-        default:
-            ASSERT_NOT_REACHED();
-        }
-    }
-
-    virtual void didCommit()
-    {
-        int lastFrame = m_layerTreeHost->frameNumber() - 1;
-
-        // These frames should not draw.
-        switch (lastFrame) {
-        case 1:
-            // Set the tree visible, this should draw.
-            m_layerTreeHost->setVisible(true);
-            break;
-        case 3:
-            // Set visible without giving a visible memory allocation, this
-            // shouldn't make the impl side ready for display, so it should
-            // not draw.
-            m_layerTreeHost->setVisible(true);
-            break;
-        case 4:
-            // Now give a memory allocation for display, this should draw.
-            m_layerTreeHost->setContentsMemoryAllocationLimitBytes(1);
-            break;
-        }
-    }
-
-    virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
-    {
-        switch (impl->sourceFrameNumber()) {
-        case 0:
-            // The host starts out visible and able to display before we do any commit.
-            EXPECT_TRUE(impl->visible());
-            EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
-            break;
-        case 1:
-            // We still have a memory allocation for display.
-            EXPECT_FALSE(impl->visible());
-            EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
-            break;
-        case 2:
-            EXPECT_TRUE(impl->visible());
-            EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
-            break;
-        case 3:
-            EXPECT_FALSE(impl->visible());
-            EXPECT_FALSE(impl->sourceFrameCanBeDrawn());
-            break;
-        case 4:
-            EXPECT_TRUE(impl->visible());
-            EXPECT_FALSE(impl->sourceFrameCanBeDrawn());
-            break;
-        case 5:
-            EXPECT_TRUE(impl->visible());
-            EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
-            break;
-        case 6:
-            EXPECT_TRUE(impl->visible());
-            EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
-            break;
-        }
-    }
-
-    virtual void afterTest()
-    {
-    }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestVisibilityAndAllocationControlDrawing)
-
 // Verifies that startPageScaleAnimation events propagate correctly from CCLayerTreeHost to
 // CCLayerTreeHostImpl in the MT compositor.
 class CCLayerTreeHostTestStartPageScaleAnimation : public CCLayerTreeHostTest {
@@ -1734,7 +1661,7 @@ public:
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
         ASSERT_TRUE(m_layerTreeHost->initializeLayerRendererIfNeeded());
         CCTextureUpdater updater;
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
@@ -1751,7 +1678,7 @@ public:
 
         m_layerTreeHost->setRootLayer(rootLayer);
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
@@ -1769,7 +1696,7 @@ public:
 
         m_layerTreeHost->setRootLayer(rootLayer);
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
@@ -1789,7 +1716,7 @@ public:
 
         m_layerTreeHost->setRootLayer(rootLayer);
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
@@ -1811,7 +1738,7 @@ public:
 
         m_layerTreeHost->setRootLayer(rootLayer);
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
@@ -1833,7 +1760,7 @@ public:
 
         m_layerTreeHost->setRootLayer(rootLayer);
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
@@ -1856,7 +1783,7 @@ public:
 
         m_layerTreeHost->setRootLayer(rootLayer);
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
@@ -1879,7 +1806,7 @@ public:
 
         m_layerTreeHost->setRootLayer(rootLayer);
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
@@ -1942,7 +1869,7 @@ public:
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
         ASSERT_TRUE(m_layerTreeHost->initializeLayerRendererIfNeeded());
         CCTextureUpdater updater;
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
@@ -1969,7 +1896,7 @@ public:
 
         m_layerTreeHost->setRootLayer(rootLayer);
         m_layerTreeHost->setViewportSize(rootLayer->bounds());
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
@@ -2031,7 +1958,7 @@ public:
         m_layerTreeHost->setViewportSize(layers[0]->bounds());
         ASSERT_TRUE(m_layerTreeHost->initializeLayerRendererIfNeeded());
         CCTextureUpdater updater;
-        m_layerTreeHost->updateLayers(updater);
+        m_layerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         m_layerTreeHost->commitComplete();
 
         for (int i = 0; i < numSurfaces-1; ++i) {
index a99149b..2e31d44 100644 (file)
@@ -807,7 +807,7 @@ TEST(CCSchedulerStateMachineTest, TestRequestCommitInvisible)
     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
 }
 
-TEST(CCSchedulerStateMachineTest, TestGoesInvisibleMidCommit)
+TEST(CCSchedulerStateMachineTest, TestGoesInvisibleBeforeBeginFrameCompletes)
 {
     StateMachine state;
     state.setCanBeginFrame(true);
@@ -823,33 +823,12 @@ TEST(CCSchedulerStateMachineTest, TestGoesInvisibleMidCommit)
     EXPECT_FALSE(state.needsCommit());
     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
 
-    // Become invisible
+    // Become invisible and abort the beginFrame.
     state.setVisible(false);
+    state.beginFrameAborted();
 
-    // Tell the scheduler the frame finished
-    state.beginFrameComplete();
-    EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES, state.commitState());
-    EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
-
-    // Tell the scheduler the update began and finished
-    state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
-    state.beginUpdateMoreResourcesComplete(false);
-    EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
-    EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
-
-    // Commit in invisible state should leave us:
-    // - COMMIT_STATE_WAITING_FOR_FIRST_DRAW
-    // - Waiting for redraw.
-    // - No commit needed
-    state.updateState(CCSchedulerStateMachine::ACTION_COMMIT);
-    EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
-    EXPECT_TRUE(state.needsRedraw());
-    EXPECT_FALSE(state.needsCommit());
-
-    // Expect to do nothing, both in and out of vsync.
-    state.didLeaveVSync();
-    EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
-    state.didEnterVSync();
+    // We should now be back in the idle state as if we didn't start a frame at all.
+    EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
 }
 
index 68fef64..614e1ee 100644 (file)
@@ -150,8 +150,9 @@ protected:
 
 class FakeTextureAllocator : public WebCore::TextureAllocator {
 public:
-    virtual unsigned createTexture(const WebCore::IntSize&, GC3Denum) { return 1; }
-    virtual void deleteTexture(unsigned, const WebCore::IntSize&, GC3Denum) { }
+    virtual unsigned createTexture(const WebCore::IntSize&, GC3Denum) OVERRIDE { return 1; }
+    virtual void deleteTexture(unsigned, const WebCore::IntSize&, GC3Denum) OVERRIDE { }
+    virtual void deleteAllTextures() OVERRIDE { }
 };
 
 class FakeTextureCopier : public WebCore::TextureCopier {
index 191d05f..b864c35 100644 (file)
@@ -35,6 +35,11 @@ namespace WebKit {
 // All operations are no-ops (returning 0 if necessary).
 class FakeWebGraphicsContext3D : public WebGraphicsContext3D {
 public:
+    FakeWebGraphicsContext3D()
+        : m_nextTextureId(1)
+    {
+    }
+
     virtual bool makeContextCurrent() { return true; }
 
     virtual int width() { return 0; }
@@ -246,7 +251,7 @@ public:
     virtual WebGLId createProgram() { return 1; }
     virtual WebGLId createRenderbuffer() { return 1; }
     virtual WebGLId createShader(WGC3Denum) { return 1; }
-    virtual WebGLId createTexture() { return 1; }
+    virtual WebGLId createTexture() { return m_nextTextureId++; }
 
     virtual void deleteBuffer(WebGLId) { }
     virtual void deleteFramebuffer(WebGLId) { }
@@ -267,6 +272,7 @@ public:
     virtual void getQueryObjectuivEXT(WebGLId, GC3Denum, GC3Duint*) { }
 
 protected:
+    unsigned m_nextTextureId;
     Attributes m_attrs;
 };
 
index 64d9d71..e465096 100644 (file)
@@ -84,12 +84,13 @@ public:
     }
 
     // CCRendererClient methods.
-    virtual const IntSize& deviceViewportSize() const OVERRIDE { static IntSize fakeSize; return fakeSize; }
+    virtual const IntSize& deviceViewportSize() const OVERRIDE { static IntSize fakeSize(1, 1); return fakeSize; }
     virtual const CCLayerTreeSettings& settings() const OVERRIDE { static CCLayerTreeSettings fakeSettings; return fakeSettings; }
     virtual void didLoseContext() OVERRIDE { }
     virtual void onSwapBuffersComplete() OVERRIDE { }
     virtual void setFullRootLayerDamage() OVERRIDE { m_setFullRootLayerDamageCount++; }
-    virtual void setContentsMemoryAllocationLimitBytes(size_t bytes) OVERRIDE { m_memoryAllocationLimitBytes = bytes; }
+    virtual void releaseContentsTextures() OVERRIDE { }
+    virtual void setMemoryAllocationLimitBytes(size_t bytes) OVERRIDE { m_memoryAllocationLimitBytes = bytes; }
 
     // Methods added for test.
     int setFullRootLayerDamageCount() const { return m_setFullRootLayerDamageCount; }
@@ -168,20 +169,34 @@ TEST_F(LayerRendererChromiumTest, SuggestBackbufferYesWhenItAlreadyExistsShouldD
 }
 
 // Test LayerRendererChromium discardFramebuffer functionality:
-// Suggest discarding framebuffer when one exists.
+// Suggest discarding framebuffer when one exists and the renderer is not visible.
 // Expected: it is discarded and damage tracker is reset.
-TEST_F(LayerRendererChromiumTest, SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayer)
+TEST_F(LayerRendererChromiumTest, SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerWhileNotVisible)
 {
+    m_layerRendererChromium.setVisible(false);
     m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
     EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
     EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
 }
 
 // Test LayerRendererChromium discardFramebuffer functionality:
+// Suggest discarding framebuffer when one exists and the renderer is visible.
+// Expected: the allocation is ignored.
+TEST_F(LayerRendererChromiumTest, SuggestBackbufferNoDoNothingWhenVisible)
+{
+    m_layerRendererChromium.setVisible(true);
+    m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
+    EXPECT_EQ(0, m_mockClient.setFullRootLayerDamageCount());
+    EXPECT_FALSE(m_layerRendererChromium.isFramebufferDiscarded());
+}
+
+
+// Test LayerRendererChromium discardFramebuffer functionality:
 // Suggest discarding framebuffer when one does not exist.
 // Expected: it does nothing.
 TEST_F(LayerRendererChromiumTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing)
 {
+    m_layerRendererChromium.setVisible(false);
     m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
     EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
     EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
@@ -192,37 +207,37 @@ TEST_F(LayerRendererChromiumTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNo
 }
 
 // Test LayerRendererChromium discardFramebuffer functionality:
-// Suggest discarding framebuffer, then try to swapBuffers.
-// Expected: framebuffer is discarded, swaps are ignored, and damage is reset after discard and after each swap.
-TEST_F(LayerRendererChromiumTest, SwapBuffersWhileBackbufferDiscardedShouldIgnoreSwapAndDamageRootLayer)
+// Begin drawing a frame while a framebuffer is discarded.
+// Expected: will recreate framebuffer.
+TEST_F(LayerRendererChromiumTest, DiscardedBackbufferIsRecreatedForScopeDuration)
 {
+    m_layerRendererChromium.setVisible(false);
     m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
     EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
     EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
 
-    swapBuffers();
-    EXPECT_EQ(0, m_mockContext.frameCount());
-    EXPECT_EQ(2, m_mockClient.setFullRootLayerDamageCount());
+    m_layerRendererChromium.setVisible(true);
+    m_layerRendererChromium.beginDrawingFrame(m_mockClient.rootRenderPass());
+    EXPECT_FALSE(m_layerRendererChromium.isFramebufferDiscarded());
 
     swapBuffers();
-    EXPECT_EQ(0, m_mockContext.frameCount());
-    EXPECT_EQ(3, m_mockClient.setFullRootLayerDamageCount());
+    EXPECT_EQ(1, m_mockContext.frameCount());
 }
 
-// Test LayerRendererChromium discardFramebuffer functionality:
-// Begin drawing a frame while a framebuffer is discarded.
-// Expected: will recreate framebuffer.
-TEST_F(LayerRendererChromiumTest, DiscardedBackbufferIsRecreatredForScopeDuration)
+TEST_F(LayerRendererChromiumTest, FramebufferDiscardedAfterReadbackWhenNotVisible)
 {
+    m_layerRendererChromium.setVisible(false);
     m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
     EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
     EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
 
+    char pixels[4];
     m_layerRendererChromium.beginDrawingFrame(m_mockClient.rootRenderPass());
     EXPECT_FALSE(m_layerRendererChromium.isFramebufferDiscarded());
 
-    swapBuffers();
-    EXPECT_EQ(1, m_mockContext.frameCount());
+    m_layerRendererChromium.getFramebufferPixels(pixels, IntRect(0, 0, 1, 1));
+    EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
+    EXPECT_EQ(2, m_mockClient.setFullRootLayerDamageCount());
 }
 
 class ForbidSynchronousCallContext : public FakeWebGraphicsContext3D {
index 073fa19..9495e70 100644 (file)
@@ -824,8 +824,7 @@ TEST(TiledLayerChromiumTest, skipsDrawGetsReset)
 
     ccLayerTreeHost->setRootLayer(rootLayer);
     ccLayerTreeHost->setViewportSize(IntSize(300, 300));
-    textureManager->setMaxMemoryLimitBytes(memoryLimit);
-    ccLayerTreeHost->updateLayers(updater);
+    ccLayerTreeHost->updateLayers(updater, memoryLimit);
 
     // We'll skip the root layer.
     EXPECT_TRUE(rootLayer->skipsDraw());
@@ -837,7 +836,7 @@ TEST(TiledLayerChromiumTest, skipsDrawGetsReset)
     // Remove the child layer.
     rootLayer->removeAllChildren();
 
-    ccLayerTreeHost->updateLayers(updater);
+    ccLayerTreeHost->updateLayers(updater, memoryLimit);
     EXPECT_FALSE(rootLayer->skipsDraw());
 
     ccLayerTreeHost->setRootLayer(0);
@@ -904,7 +903,7 @@ TEST(TiledLayerChromiumTest, partialUpdates)
     ccLayerTreeHost->setViewportSize(IntSize(300, 200));
 
     // Full update of all 6 tiles.
-    ccLayerTreeHost->updateLayers(updater);
+    ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
     {
         DebugScopedSetImplThread implThread;
         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
@@ -922,7 +921,7 @@ TEST(TiledLayerChromiumTest, partialUpdates)
 
     // Full update of 3 tiles and partial update of 3 tiles.
     layer->invalidateRect(IntRect(0, 0, 300, 150));
-    ccLayerTreeHost->updateLayers(updater);
+    ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
     {
         DebugScopedSetImplThread implThread;
         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
@@ -943,7 +942,7 @@ TEST(TiledLayerChromiumTest, partialUpdates)
     {
         DebugScopedSetImplThread implThread;
         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
-        ccLayerTreeHost->updateLayers(updater);
+        ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         updater.update(0, &allocator, &copier, &uploader, 4);
         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
         EXPECT_TRUE(updater.hasMoreUpdates());
@@ -970,7 +969,7 @@ TEST(TiledLayerChromiumTest, partialUpdates)
     {
         DebugScopedSetImplThread implThread;
         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
-        ccLayerTreeHost->updateLayers(updater);
+        ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         updater.update(0, &allocator, &copier, &uploader, 4);
         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
         EXPECT_TRUE(updater.hasMoreUpdates());
@@ -988,7 +987,7 @@ TEST(TiledLayerChromiumTest, partialUpdates)
     {
         DebugScopedSetImplThread implThread;
         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
-        ccLayerTreeHost->updateLayers(updater);
+        ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
         updater.update(0, &allocator, &copier, &uploader, 4);
         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
         EXPECT_FALSE(updater.hasMoreUpdates());