Changeset 120889 in webkit


Ignore:
Timestamp:
Jun 20, 2012 5:43:08 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[Chromium] Damage tracker is not used without partial swap, causing valid render passes to be removed
https://bugs.webkit.org/show_bug.cgi?id=89589

Patch by Zeev Lieber <zlieber@chromium.org> on 2012-06-20
Reviewed by Adrienne Walker.

Source/WebCore:

When not using partial swap, the CCDamageTracker was not used, and
its m_currentDamageRect was always empty. As a result,
CCLayerTreeHostImpl was thinking no content was changed and was
removing more textures than needed. Fixed this by turning on
CCDamageTracker usage even if not using partial swap, but
overwriting the rootScissorRect with viewport rect if required.

Added unit tests to exercise this scenario.

  • platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:

(WebCore::CCLayerTreeHostImpl::calculateRenderSurfaceLayerList):

Source/WebKit/chromium:

Added unit tests to check surface texture caching when partial
swap is not used.

  • tests/CCLayerTreeHostImplTest.cpp:
Location:
trunk/Source
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r120888 r120889  
     12012-06-20  Zeev Lieber  <zlieber@chromium.org>
     2
     3        [Chromium] Damage tracker is not used without partial swap, causing valid render passes to be removed
     4        https://bugs.webkit.org/show_bug.cgi?id=89589
     5
     6        Reviewed by Adrienne Walker.
     7
     8        When not using partial swap, the CCDamageTracker was not used, and
     9        its m_currentDamageRect was always empty. As a result,
     10        CCLayerTreeHostImpl was thinking no content was changed and was
     11        removing more textures than needed. Fixed this by turning on
     12        CCDamageTracker usage even if not using partial swap, but
     13        overwriting the rootScissorRect with viewport rect if required.
     14
     15        Added unit tests to exercise this scenario.
     16
     17        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
     18        (WebCore::CCLayerTreeHostImpl::calculateRenderSurfaceLayerList):
     19
    1202012-06-20  Joshua Bell  <jsbell@chromium.org>
    221
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp

    r120820 r120889  
    256256        CCLayerTreeHostCommon::calculateDrawTransforms(m_rootLayerImpl.get(), m_rootLayerImpl.get(), deviceScaleTransform, identityMatrix, renderSurfaceLayerList, m_rootLayerImpl->renderSurface()->layerList(), &m_layerSorter, layerRendererCapabilities().maxTextureSize);
    257257
    258         if (layerRendererCapabilities().usingPartialSwap || settings().showSurfaceDamageRects)
    259             trackDamageForAllSurfaces(m_rootLayerImpl.get(), renderSurfaceLayerList);
    260         m_rootScissorRect = m_rootLayerImpl->renderSurface()->damageTracker()->currentDamageRect();
    261 
    262         if (!layerRendererCapabilities().usingPartialSwap)
     258        trackDamageForAllSurfaces(m_rootLayerImpl.get(), renderSurfaceLayerList);
     259
     260        if (layerRendererCapabilities().usingPartialSwap)
     261            m_rootScissorRect = m_rootLayerImpl->renderSurface()->damageTracker()->currentDamageRect();
     262        else
    263263            m_rootScissorRect = FloatRect(FloatPoint(0, 0), deviceViewportSize());
    264264
  • trunk/Source/WebKit/chromium/ChangeLog

    r120888 r120889  
     12012-06-20  Zeev Lieber  <zlieber@chromium.org>
     2
     3        [Chromium] Damage tracker is not used without partial swap, causing valid render passes to be removed
     4        https://bugs.webkit.org/show_bug.cgi?id=89589
     5
     6        Reviewed by Adrienne Walker.
     7
     8        Added unit tests to check surface texture caching when partial
     9        swap is not used.
     10
     11        * tests/CCLayerTreeHostImplTest.cpp:
     12
    1132012-06-20  Joshua Bell  <jsbell@chromium.org>
    214
  • trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp

    r120820 r120889  
    24112411}
    24122412
    2413 TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
    2414 {
    2415     CCSettings::setPartialSwapEnabled(true);
    2416    
    2417     CCLayerTreeSettings settings;
    2418     OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
    2419    
     2413static void setupLayersForTextureCaching(CCLayerTreeHostImpl* layerTreeHostImpl, CCLayerImpl*& rootPtr, CCLayerImpl*& intermediateLayerPtr, CCLayerImpl*& surfaceLayerPtr, CCLayerImpl*& childPtr)
     2414{
    24202415    RefPtr<CCGraphicsContext> context = CCGraphicsContext::create3D(GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new PartialSwapContext()), GraphicsContext3D::RenderDirectlyToHostWindow));
    24212416
    2422     myHostImpl->initializeLayerRenderer(context.release(), UnthrottledUploader);
    2423     myHostImpl->setViewportSize(IntSize(100, 100));
     2417    layerTreeHostImpl->initializeLayerRenderer(context.release(), UnthrottledUploader);
     2418    layerTreeHostImpl->setViewportSize(IntSize(100, 100));
    24242419
    24252420    OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
    2426     CCLayerImpl* rootPtr = root.get();
     2421    rootPtr = root.get();
    24272422
    24282423    root->setAnchorPoint(FloatPoint(0, 0));
     
    24322427    root->setVisibleLayerRect(IntRect(0, 0, 100, 100));
    24332428    root->setDrawsContent(true);
    2434     myHostImpl->setRootLayer(root.release());
     2429    layerTreeHostImpl->setRootLayer(root.release());
    24352430
    24362431    // Intermediate layer does not own a surface, and does not draw content.
    24372432    OwnPtr<CCLayerImpl> intermediateLayer = CCLayerImpl::create(2);
    2438     CCLayerImpl* intermediateLayerPtr = intermediateLayer.get();
     2433    intermediateLayerPtr = intermediateLayer.get();
    24392434
    24402435    intermediateLayerPtr->setAnchorPoint(FloatPoint(0, 0));
     
    24472442
    24482443    OwnPtr<CCLayerImpl> surfaceLayer = CCLayerImpl::create(3);
    2449     CCLayerImpl* surfaceLayerPtr = surfaceLayer.get();
     2444    surfaceLayerPtr = surfaceLayer.get();
    24502445
    24512446    // Surface layer is the layer that changes its opacity
     
    24622457    // Child of the surface layer will produce some quads
    24632458    OwnPtr<FakeLayerWithQuads> child = FakeLayerWithQuads::create(4);
    2464     FakeLayerWithQuads* childPtr = child.get();
     2459    childPtr = child.get();
    24652460
    24662461    childPtr->setAnchorPoint(FloatPoint(0, 0));
     
    24722467
    24732468    surfaceLayerPtr->addChild(child.release());
     2469}
     2470
     2471TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
     2472{
     2473    CCSettings::setPartialSwapEnabled(true);
     2474
     2475    CCLayerTreeSettings settings;
     2476    OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
     2477
     2478    CCLayerImpl* rootPtr;
     2479    CCLayerImpl* intermediateLayerPtr;
     2480    CCLayerImpl* surfaceLayerPtr;
     2481    CCLayerImpl* childPtr;
     2482
     2483    setupLayersForTextureCaching(myHostImpl.get(), rootPtr, intermediateLayerPtr, surfaceLayerPtr, childPtr);
    24742484
    24752485    {
     
    25902600        EXPECT_EQ(0U, frame.renderPasses[0]->quadList().size());
    25912601        EXPECT_EQ(0U, frame.renderPasses[1]->quadList().size());
     2602
     2603        myHostImpl->drawLayers(frame);
     2604        myHostImpl->didDrawAllLayers(frame);
     2605    }
     2606
     2607    // Change opacity on the intermediate layer
     2608    WebTransformationMatrix transform = intermediateLayerPtr->transform();
     2609    transform.setM11(1.0001);
     2610    intermediateLayerPtr->setTransform(transform);
     2611    {
     2612        CCLayerTreeHostImpl::FrameData frame;
     2613        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
     2614
     2615        // Must receive one render pass, as the other one should be culled.
     2616        ASSERT_EQ(1U, frame.renderPasses.size());
     2617        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
     2618
     2619        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[0]->quadList()[0]->material());
     2620        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[0]->quadList()[0].get());
     2621        EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
     2622
     2623        myHostImpl->drawLayers(frame);
     2624        myHostImpl->didDrawAllLayers(frame);
     2625    }
     2626}
     2627
     2628TEST_F(CCLayerTreeHostImplTest, surfaceTextureCachingNoPartialSwap)
     2629{
     2630    CCSettings::setPartialSwapEnabled(false);
     2631
     2632    CCLayerTreeSettings settings;
     2633    OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
     2634
     2635    CCLayerImpl* rootPtr;
     2636    CCLayerImpl* intermediateLayerPtr;
     2637    CCLayerImpl* surfaceLayerPtr;
     2638    CCLayerImpl* childPtr;
     2639
     2640    setupLayersForTextureCaching(myHostImpl.get(), rootPtr, intermediateLayerPtr, surfaceLayerPtr, childPtr);
     2641
     2642    {
     2643        CCLayerTreeHostImpl::FrameData frame;
     2644        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
     2645
     2646        // Must receive two render passes, each with one quad
     2647        ASSERT_EQ(2U, frame.renderPasses.size());
     2648        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
     2649        EXPECT_EQ(1U, frame.renderPasses[1]->quadList().size());
     2650
     2651        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
     2652        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
     2653        EXPECT_TRUE(quad->renderPass()->targetSurface()->contentsChanged());
     2654
     2655        myHostImpl->drawLayers(frame);
     2656        myHostImpl->didDrawAllLayers(frame);
     2657    }
     2658
     2659    // Draw without any change
     2660    {
     2661        CCLayerTreeHostImpl::FrameData frame;
     2662        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
     2663
     2664        // Even though there was no change, we set the damage to entire viewport.
     2665        // One of the passes should be culled as a result, since contents didn't change
     2666        // and we have cached texture.
     2667        ASSERT_EQ(1U, frame.renderPasses.size());
     2668        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
     2669
     2670        myHostImpl->drawLayers(frame);
     2671        myHostImpl->didDrawAllLayers(frame);
     2672    }
     2673
     2674    // Change opacity and draw
     2675    surfaceLayerPtr->setOpacity(0.6f);
     2676    {
     2677        CCLayerTreeHostImpl::FrameData frame;
     2678        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
     2679
     2680        // Must receive one render pass, as the other one should be culled
     2681        ASSERT_EQ(1U, frame.renderPasses.size());
     2682
     2683        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
     2684        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[0]->quadList()[0]->material());
     2685        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[0]->quadList()[0].get());
     2686        EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
     2687
     2688        myHostImpl->drawLayers(frame);
     2689        myHostImpl->didDrawAllLayers(frame);
     2690    }
     2691
     2692    // Change less benign property and draw - should have contents changed flag
     2693    surfaceLayerPtr->setStackingOrderChanged(true);
     2694    {
     2695        CCLayerTreeHostImpl::FrameData frame;
     2696        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
     2697
     2698        // Must receive two render passes, each with one quad
     2699        ASSERT_EQ(2U, frame.renderPasses.size());
     2700
     2701        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
     2702        EXPECT_EQ(CCDrawQuad::SolidColor, frame.renderPasses[0]->quadList()[0]->material());
     2703
     2704        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
     2705        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
     2706        EXPECT_TRUE(quad->renderPass()->targetSurface()->contentsChanged());
     2707
     2708        myHostImpl->drawLayers(frame);
     2709        myHostImpl->didDrawAllLayers(frame);
     2710    }
     2711
     2712    // Change opacity again, but evict the cached surface texture
     2713    surfaceLayerPtr->setOpacity(0.5f);
     2714    ManagedTexture* contentsTexture = surfaceLayerPtr->renderSurface()->contentsTexture();
     2715    ASSERT_TRUE(contentsTexture->isValid(contentsTexture->size(), contentsTexture->format()));
     2716    CCRenderer* renderer = myHostImpl->layerRenderer();
     2717    TextureManager* textureManager = renderer->implTextureManager();
     2718    size_t maxMemoryLimit = textureManager->maxMemoryLimitBytes();
     2719
     2720    // This should evice all cached surfaces
     2721    textureManager->setMaxMemoryLimitBytes(0);
     2722
     2723    // Restore original limit
     2724    textureManager->setMaxMemoryLimitBytes(maxMemoryLimit);
     2725
     2726    // Was our surface evicted?
     2727    ASSERT_FALSE(contentsTexture->isValid(contentsTexture->size(), contentsTexture->format()));
     2728
     2729    // Change opacity and draw
     2730    surfaceLayerPtr->setOpacity(0.6f);
     2731    {
     2732        CCLayerTreeHostImpl::FrameData frame;
     2733        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
     2734
     2735        // Must receive two render passes
     2736        ASSERT_EQ(2U, frame.renderPasses.size());
     2737
     2738        // Even though not enough properties changed, the entire thing must be
     2739        // redrawn as we don't have cached textures
     2740        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
     2741        EXPECT_EQ(1U, frame.renderPasses[1]->quadList().size());
     2742
     2743        EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
     2744        CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
     2745        EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
     2746
     2747        myHostImpl->drawLayers(frame);
     2748        myHostImpl->didDrawAllLayers(frame);
     2749    }
     2750
     2751    // Draw without any change, to make sure the state is clear
     2752    {
     2753        CCLayerTreeHostImpl::FrameData frame;
     2754        EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
     2755
     2756        // Even though there was no change, we set the damage to entire viewport.
     2757        // One of the passes should be culled as a result, since contents didn't change
     2758        // and we have cached texture.
     2759        ASSERT_EQ(1U, frame.renderPasses.size());
     2760        EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
    25922761
    25932762        myHostImpl->drawLayers(frame);
Note: See TracChangeset for help on using the changeset viewer.