Changeset 122252 in webkit
- Timestamp:
- Jul 10, 2012 1:14:36 PM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r122250 r122252 1 2012-07-10 Dana Jansens <danakj@chromium.org> 2 3 [chromium] Avoid allocating render pass textures that have no content 4 https://bugs.webkit.org/show_bug.cgi?id=90702 5 6 Reviewed by Adrienne Walker. 7 8 When OOM conditions are hit, textures are not allocated for some layers 9 which can prevent any quads from being present for a render surface. 10 This is used as a signal to prevent the RenderPass from allocating a 11 texture. 12 13 Replace the CCLayerTreeHostImpl::removePassesWithCachedTextures() method 14 with a general removeRenderPasses() which takes a culling control object 15 and will remove passes based on the inputs from the control object. 16 17 This new method is used for the old purpose of removing passes with cached 18 textures, as well as to remove passes that do not have any quad inputs. 19 20 Test: CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit 21 22 * platform/graphics/chromium/LayerRendererChromium.cpp: 23 (WebCore::LayerRendererChromium::drawRenderPassQuad): 24 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp: 25 (WebCore::CCLayerTreeHostImpl::calculateRenderPasses): 26 (WebCore): 27 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures::shouldRemoveRenderPass): 28 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithNoQuads::shouldRemoveRenderPass): 29 (WebCore::CCLayerTreeHostImpl::removeRenderPasses): 30 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h: 31 (WebCore): 32 (CullRenderPassesWithCachedTextures): 33 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures::renderPassListBegin): 34 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures::renderPassListEnd): 35 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures::renderPassListNext): 36 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures::CullRenderPassesWithCachedTextures): 37 (CCLayerTreeHostImpl): 38 (CullRenderPassesWithNoQuads): 39 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithNoQuads::renderPassListBegin): 40 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithNoQuads::renderPassListEnd): 41 (WebCore::CCLayerTreeHostImpl::CullRenderPassesWithNoQuads::renderPassListNext): 42 1 43 2012-07-10 Joshua Netterfield <jnetterfield@rim.com> 2 44 Make GC3D and E3D more maintainable for GLES platforms -
trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
r122196 r122252 613 613 void LayerRendererChromium::drawRenderPassQuad(const CCRenderPassDrawQuad* quad) 614 614 { 615 ManagedTexture* contentsTexture = m_renderPassTextures.get(quad->renderPassId()); 616 if (!contentsTexture || !contentsTexture->textureId()) 617 return; 618 615 619 WebTransformationMatrix renderTransform = quad->layerTransform(); 616 620 // Apply a scaling factor to size the quad from 1x1 to its intended size. … … 621 625 if (!contentsDeviceTransform.isInvertible()) 622 626 return; 623 624 ManagedTexture* contentsTexture = m_renderPassTextures.get(quad->renderPassId());625 ASSERT(contentsTexture && contentsTexture->textureId());626 627 627 628 OwnPtr<ManagedTexture> backgroundTexture = drawBackgroundFilters(quad, contentsDeviceTransform); -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
r122160 r122252 354 354 occlusionTracker.overdrawMetrics().recordMetrics(this); 355 355 356 removeRenderPasses(CullRenderPassesWithNoQuads(), frame); 356 357 m_layerRenderer->decideRenderPassAllocationsForFrame(frame.renderPasses); 357 remove PassesWithCachedTextures(frame.renderPasses, frame.skippedPasses, m_layerRenderer.get());358 removeRenderPasses(CullRenderPassesWithCachedTextures(*m_layerRenderer), frame); 358 359 359 360 return drawFrame; … … 406 407 } 407 408 409 // static 408 410 void CCLayerTreeHostImpl::removeRenderPassesRecursive(CCRenderPassList& passes, size_t bottomPass, const CCRenderPass* firstToRemove, CCRenderPassList& skippedPasses) 409 411 { … … 435 437 } 436 438 437 void CCLayerTreeHostImpl::removePassesWithCachedTextures(CCRenderPassList& passes, CCRenderPassList& skippedPasses, const CCRenderer* renderer) 438 { 439 for (int passIndex = passes.size() - 1; passIndex >= 0; --passIndex) { 440 CCRenderPass* currentPass = passes[passIndex].get(); 439 bool CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures::shouldRemoveRenderPass(const CCRenderPassList&, const CCRenderPassDrawQuad& quad) const 440 { 441 return quad.contentsChangedSinceLastFrame().isEmpty() && m_renderer.haveCachedResourcesForRenderPassId(quad.renderPassId()); 442 } 443 444 bool CCLayerTreeHostImpl::CullRenderPassesWithNoQuads::shouldRemoveRenderPass(const CCRenderPassList& passList, const CCRenderPassDrawQuad& quad) const 445 { 446 size_t passIndex = passList.find(quad.renderPass()); 447 ASSERT(passIndex != notFound); 448 449 // If any quad or RenderPass draws into this RenderPass, then keep it. 450 const CCQuadList& quadList = passList[passIndex]->quadList(); 451 for (CCQuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin(); quadListIterator != quadList.backToFrontEnd(); ++quadListIterator) { 452 CCDrawQuad* currentQuad = quadListIterator->get(); 453 454 if (currentQuad->material() != CCDrawQuad::RenderPass) 455 return false; 456 457 const CCRenderPassDrawQuad* quadInPass = static_cast<CCRenderPassDrawQuad*>(currentQuad); 458 if (passList.contains(quadInPass->renderPass())) 459 return false; 460 } 461 return true; 462 } 463 464 // Defined for linking tests. 465 template void CCLayerTreeHostImpl::removeRenderPasses<CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures>(CullRenderPassesWithCachedTextures, FrameData&); 466 template void CCLayerTreeHostImpl::removeRenderPasses<CCLayerTreeHostImpl::CullRenderPassesWithNoQuads>(CullRenderPassesWithNoQuads, FrameData&); 467 468 // static 469 template<typename RenderPassCuller> 470 void CCLayerTreeHostImpl::removeRenderPasses(RenderPassCuller culler, FrameData& frame) 471 { 472 for (size_t it = culler.renderPassListBegin(frame.renderPasses); it != culler.renderPassListEnd(frame.renderPasses); it = culler.renderPassListNext(it)) { 473 CCRenderPass* currentPass = frame.renderPasses[it].get(); 441 474 const CCQuadList& quadList = currentPass->quadList(); 442 475 CCQuadList::constBackToFrontIterator quadListIterator = quadList.backToFrontBegin(); … … 449 482 450 483 CCRenderPassDrawQuad* renderPassQuad = static_cast<CCRenderPassDrawQuad*>(currentQuad); 451 if (! renderPassQuad->contentsChangedSinceLastFrame().isEmpty())484 if (!culler.shouldRemoveRenderPass(frame.renderPasses, *renderPassQuad)) 452 485 continue; 453 if (!renderer->haveCachedResourcesForRenderPassId(renderPassQuad->renderPassId())) 454 continue;455 456 // We are changing the vector in the middle of reverse iteration.457 // We are guaranteed that any data from iterator to the end will not change.458 // Capture the iterator position from the end, and restore it after the change.459 int positionFromEnd = passes.size() - passIndex;460 removeRenderPassesRecursive( passes, passIndex, renderPassQuad->renderPass(),skippedPasses);461 passIndex = passes.size() - positionFromEnd;462 ASSERT( passIndex>= 0);486 487 // We are changing the vector in the middle of iteration. Because we 488 // delete render passes that draw into the current pass, we are 489 // guaranteed that any data from the iterator to the end will not 490 // change. So, capture the iterator position from the end of the 491 // list, and restore it after the change. 492 int positionFromEnd = frame.renderPasses.size() - it; 493 removeRenderPassesRecursive(frame.renderPasses, it, renderPassQuad->renderPass(), frame.skippedPasses); 494 it = frame.renderPasses.size() - positionFromEnd; 495 ASSERT(it >= 0); 463 496 } 464 497 } -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
r122160 r122252 43 43 class CCFrameRateCounter; 44 44 class CCHeadsUpDisplay; 45 class CCPageScaleAnimation;46 45 class CCLayerImpl; 47 46 class CCLayerTreeHostImplTimeSourceAdapter; 47 class CCPageScaleAnimation; 48 class CCRenderPassDrawQuad; 48 49 class LayerRendererChromium; 49 50 class TextureAllocator; … … 178 179 CCDebugRectHistory* debugRectHistory() const { return m_debugRectHistory.get(); } 179 180 180 // Removes all render passes for which we have cached textures, and which did not change their content. 181 static void removePassesWithCachedTextures(CCRenderPassList& passes, CCRenderPassList& skippedPasses, const CCRenderer*); 181 class CullRenderPassesWithCachedTextures { 182 public: 183 bool shouldRemoveRenderPass(const CCRenderPassList&, const CCRenderPassDrawQuad&) const; 184 185 // Iterates from the root first, in order to remove the surfaces closest 186 // to the root with cached textures, and all surfaces that draw into 187 // them. 188 size_t renderPassListBegin(const CCRenderPassList& list) const { return list.size() - 1; } 189 size_t renderPassListEnd(const CCRenderPassList&) const { return 0 - 1; } 190 size_t renderPassListNext(size_t it) const { return it - 1; } 191 192 CullRenderPassesWithCachedTextures(CCRenderer& renderer) : m_renderer(renderer) { } 193 private: 194 CCRenderer& m_renderer; 195 }; 196 197 class CullRenderPassesWithNoQuads { 198 public: 199 bool shouldRemoveRenderPass(const CCRenderPassList&, const CCRenderPassDrawQuad&) const; 200 201 // Iterates in draw order, so that when a surface is removed, and its 202 // target becomes empty, then its target can be removed also. 203 size_t renderPassListBegin(const CCRenderPassList&) const { return 0; } 204 size_t renderPassListEnd(const CCRenderPassList& list) const { return list.size(); } 205 size_t renderPassListNext(size_t it) const { return it + 1; } 206 }; 207 208 template<typename RenderPassCuller> 209 static void removeRenderPasses(RenderPassCuller, FrameData&); 182 210 183 211 protected: -
trunk/Source/WebKit/chromium/ChangeLog
r122230 r122252 1 2012-07-10 Dana Jansens <danakj@chromium.org> 2 3 [chromium] Avoid allocating render pass textures that have no content 4 https://bugs.webkit.org/show_bug.cgi?id=90702 5 6 Reviewed by Adrienne Walker. 7 8 * tests/CCLayerTreeHostImplTest.cpp: 9 * tests/CCLayerTreeHostTest.cpp: 10 (WTF::ContentLayerChromiumWithUpdateTracking::ContentLayerChromiumWithUpdateTracking): 11 (CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit): 12 (WTF::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit): 13 (WTF::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit::beginTest): 14 (WTF::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit::didCommit): 15 (WTF::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit::drawLayersOnCCThread): 16 (WTF::CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit::afterTest): 17 (WTF): 18 1 19 2012-07-10 Leandro Gracia Gil <leandrogracia@chromium.org> 2 20 -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
r122160 r122252 2878 2878 }; 2879 2879 2880 struct RenderPassRemovalTestData { 2881 CCRenderPassList renderPassList; 2880 struct RenderPassRemovalTestData : public CCLayerTreeHostImpl::FrameData { 2882 2881 std::map<char, RenderPassCacheEntry> renderPassCache; 2883 2882 std::map<const CCRenderPass*, char> renderPassId; … … 3020 3019 } 3021 3020 } 3022 testData.renderPass List.insert(0, renderPass.release());3021 testData.renderPasses.insert(0, renderPass.release()); 3023 3022 if (*currentChar) 3024 3023 currentChar++; … … 3029 3028 { 3030 3029 char* pos = buffer; 3031 CCRenderPassList::const_reverse_iterator it = testData.renderPassList.rbegin(); 3032 while (it != testData.renderPassList.rend()) { 3030 for (CCRenderPassList::const_reverse_iterator it = testData.renderPasses.rbegin(); it != testData.renderPasses.rend(); ++it) { 3033 3031 CCRenderPass* currentPass = it->get(); 3034 3032 char passId = testData.renderPassId.find(currentPass)->second; … … 3062 3060 *pos = '\n'; 3063 3061 pos++; 3064 it++;3065 3062 } 3066 3063 *pos = '\0'; … … 3225 3222 while (removeRenderPassesCases[testCaseIndex].name) { 3226 3223 RenderPassRemovalTestData testData; 3227 CCRenderPassList skippedPasses;3228 3224 configureRenderPassTestData(removeRenderPassesCases[testCaseIndex].initScript, testData, renderer.get()); 3229 CCLayerTreeHostImpl::remove PassesWithCachedTextures(testData.renderPassList, skippedPasses, renderer.get());3225 CCLayerTreeHostImpl::removeRenderPasses(CCLayerTreeHostImpl::CullRenderPassesWithCachedTextures(*renderer), testData); 3230 3226 verifyRenderPassTestData(removeRenderPassesCases[testCaseIndex], testData); 3231 3227 testCaseIndex++; -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
r122185 r122252 1172 1172 , m_paintContentsCount(0) 1173 1173 { 1174 setAnchorPoint(FloatPoint(0, 0)); 1174 1175 setBounds(IntSize(10, 10)); 1175 1176 setIsDrawable(true); … … 2262 2263 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestCompositeAndReadbackCleanup) 2263 2264 2265 class CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit : public CCLayerTreeHostTest { 2266 public: 2267 CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit() 2268 : m_rootLayer(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate)) 2269 , m_surfaceLayer1(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate)) 2270 , m_surfaceLayer2(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate)) 2271 { 2272 } 2273 2274 virtual void beginTest() 2275 { 2276 m_layerTreeHost->setViewportSize(IntSize(100, 100)); 2277 2278 m_rootLayer->setBounds(IntSize(100, 100)); 2279 m_surfaceLayer1->setBounds(IntSize(100, 100)); 2280 m_surfaceLayer1->setForceRenderSurface(true); 2281 m_surfaceLayer1->setOpacity(0.5); 2282 m_surfaceLayer2->setBounds(IntSize(100, 100)); 2283 m_surfaceLayer2->setForceRenderSurface(true); 2284 m_surfaceLayer2->setOpacity(0.5); 2285 2286 m_rootLayer->addChild(m_surfaceLayer1); 2287 m_surfaceLayer1->addChild(m_surfaceLayer2); 2288 m_layerTreeHost->setRootLayer(m_rootLayer); 2289 } 2290 2291 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* hostImpl) 2292 { 2293 CCRenderer* renderer = hostImpl->layerRenderer(); 2294 unsigned surface1RenderPassId = hostImpl->rootLayer()->children()[0]->id(); 2295 unsigned surface2RenderPassId = hostImpl->rootLayer()->children()[0]->children()[0]->id(); 2296 2297 switch (hostImpl->sourceFrameNumber()) { 2298 case 0: 2299 EXPECT_TRUE(renderer->haveCachedResourcesForRenderPassId(surface1RenderPassId)); 2300 EXPECT_TRUE(renderer->haveCachedResourcesForRenderPassId(surface2RenderPassId)); 2301 2302 // Reduce the memory limit to only fit the root layer and one render surface. This 2303 // prevents any contents drawing into surfaces from being allocated. 2304 hostImpl->setMemoryAllocationLimitBytes(100 * 100 * 4 * 2); 2305 break; 2306 case 1: 2307 EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface1RenderPassId)); 2308 EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface2RenderPassId)); 2309 2310 endTest(); 2311 break; 2312 } 2313 } 2314 2315 virtual void afterTest() 2316 { 2317 EXPECT_EQ(2, m_rootLayer->paintContentsCount()); 2318 EXPECT_EQ(2, m_surfaceLayer1->paintContentsCount()); 2319 EXPECT_EQ(2, m_surfaceLayer2->paintContentsCount()); 2320 2321 // Clear layer references so CCLayerTreeHost dies. 2322 m_rootLayer.clear(); 2323 m_surfaceLayer1.clear(); 2324 m_surfaceLayer2.clear(); 2325 } 2326 2327 private: 2328 MockContentLayerDelegate m_mockDelegate; 2329 RefPtr<ContentLayerChromiumWithUpdateTracking> m_rootLayer; 2330 RefPtr<ContentLayerChromiumWithUpdateTracking> m_surfaceLayer1; 2331 RefPtr<ContentLayerChromiumWithUpdateTracking> m_surfaceLayer2; 2332 }; 2333 2334 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit) 2335 2264 2336 } // namespace
Note: See TracChangeset
for help on using the changeset viewer.