void CCLayerTreeHostImpl::drawLayers() { TRACE_EVENT("CCLayerTreeHostImpl::drawLayers", this, 0); ASSERT(m_layerRenderer); if (!rootLayer()) return; CCRenderPassList passes; CCLayerList renderSurfaceLayerList; calculateRenderPasses(passes, renderSurfaceLayerList); optimizeRenderPasses(passes); m_layerRenderer->beginDrawingFrame(); for (size_t i = 0; i < passes.size(); ++i) m_layerRenderer->drawRenderPass(passes[i].get()); typedef CCLayerIterator<CCLayerImpl, Vector<CCLayerImpl*>, CCRenderSurface, CCLayerIteratorActions::BackToFront> CCLayerIteratorType; CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList); for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) { if (it.representsItself() && !it->visibleLayerRect().isEmpty()) it->didDraw(); } m_layerRenderer->finishDrawingFrame(); ++m_frameNumber; // The next frame should start by assuming nothing has changed, and changes are noted as they occur. rootLayer()->resetAllChangeTrackingForSubtree(); }
void CCDirectRenderer::drawFrame(const CCRenderPassList& renderPassesInDrawOrder, const CCRenderPassIdHashMap& renderPassesById) { const CCRenderPass* rootRenderPass = renderPassesInDrawOrder.last(); ASSERT(rootRenderPass); DrawingFrame frame; frame.renderPassesById = &renderPassesById; frame.rootRenderPass = rootRenderPass; frame.rootDamageRect = capabilities().usingPartialSwap ? rootRenderPass->damageRect() : rootRenderPass->outputRect(); frame.rootDamageRect.intersect(IntRect(IntPoint::zero(), viewportSize())); beginDrawingFrame(frame); for (size_t i = 0; i < renderPassesInDrawOrder.size(); ++i) drawRenderPass(frame, renderPassesInDrawOrder[i]); finishDrawingFrame(frame); }
void CCDirectRenderer::decideRenderPassAllocationsForFrame(const CCRenderPassList& renderPassesInDrawOrder) { HashMap<CCRenderPass::Id, const CCRenderPass*> renderPassesInFrame; for (size_t i = 0; i < renderPassesInDrawOrder.size(); ++i) renderPassesInFrame.set(renderPassesInDrawOrder[i]->id(), renderPassesInDrawOrder[i]); Vector<CCRenderPass::Id> passesToDelete; HashMap<CCRenderPass::Id, OwnPtr<CachedTexture> >::const_iterator passIterator; for (passIterator = m_renderPassTextures.begin(); passIterator != m_renderPassTextures.end(); ++passIterator) { #if WTF_NEW_HASHMAP_ITERATORS_INTERFACE const CCRenderPass* renderPassInFrame = renderPassesInFrame.get(passIterator->key); #else const CCRenderPass* renderPassInFrame = renderPassesInFrame.get(passIterator->first); #endif if (!renderPassInFrame) { #if WTF_NEW_HASHMAP_ITERATORS_INTERFACE passesToDelete.append(passIterator->key); #else passesToDelete.append(passIterator->first); #endif continue; } const IntSize& requiredSize = renderPassTextureSize(renderPassInFrame); GC3Denum requiredFormat = renderPassTextureFormat(renderPassInFrame); #if WTF_NEW_HASHMAP_ITERATORS_INTERFACE CachedTexture* texture = passIterator->value.get(); #else CachedTexture* texture = passIterator->second.get(); #endif ASSERT(texture); if (texture->id() && (texture->size() != requiredSize || texture->format() != requiredFormat)) texture->free(); } // Delete RenderPass textures from the previous frame that will not be used again. for (size_t i = 0; i < passesToDelete.size(); ++i) m_renderPassTextures.remove(passesToDelete[i]); for (size_t i = 0; i < renderPassesInDrawOrder.size(); ++i) { if (!m_renderPassTextures.contains(renderPassesInDrawOrder[i]->id())) { OwnPtr<CachedTexture> texture = CachedTexture::create(m_resourceProvider); m_renderPassTextures.set(renderPassesInDrawOrder[i]->id(), texture.release()); } } }
void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes, CCLayerList& renderSurfaceLayerList) { renderSurfaceLayerList.append(rootLayer()); if (!rootLayer()->renderSurface()) rootLayer()->createRenderSurface(); rootLayer()->renderSurface()->clearLayerList(); rootLayer()->renderSurface()->setContentRect(IntRect(IntPoint(), viewportSize())); rootLayer()->setClipRect(IntRect(IntPoint(), viewportSize())); { TransformationMatrix identityMatrix; TRACE_EVENT("CCLayerTreeHostImpl::calcDrawEtc", this, 0); CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(rootLayer(), rootLayer(), identityMatrix, identityMatrix, renderSurfaceLayerList, rootLayer()->renderSurface()->layerList(), &m_layerSorter, layerRendererCapabilities().maxTextureSize); } if (layerRendererCapabilities().usingPartialSwap) trackDamageForAllSurfaces(rootLayer(), renderSurfaceLayerList); m_rootDamageRect = rootLayer()->renderSurface()->damageTracker()->currentDamageRect(); for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex]; CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface(); OwnPtr<CCRenderPass> pass = CCRenderPass::create(renderSurface); FloatRect surfaceDamageRect; if (layerRendererCapabilities().usingPartialSwap) surfaceDamageRect = damageInSurfaceSpace(renderSurfaceLayer, m_rootDamageRect); pass->setSurfaceDamageRect(surfaceDamageRect); const CCLayerList& layerList = renderSurface->layerList(); for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) { CCLayerImpl* layer = layerList[layerIndex]; if (layer->visibleLayerRect().isEmpty()) continue; if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget(layer, renderSurfaceLayer->id())) { pass->appendQuadsForRenderSurfaceLayer(layer); continue; } layer->willDraw(m_layerRenderer.get()); pass->appendQuadsForLayer(layer); } passes.append(pass.release()); } }
void CCLayerTreeHostImpl::optimizeRenderPasses(CCRenderPassList& passes) { TRACE_EVENT1("webkit", "CCLayerTreeHostImpl::optimizeRenderPasses", "passes.size()", static_cast<long long unsigned>(passes.size())); bool haveDamageRect = layerRendererCapabilities().usingPartialSwap; // FIXME: compute overdraw metrics only occasionally, not every frame. CCOverdrawCounts overdrawCounts; for (unsigned i = 0; i < passes.size(); ++i) { FloatRect damageRect = passes[i]->targetSurface()->damageTracker()->currentDamageRect(); passes[i]->optimizeQuads(haveDamageRect, damageRect, &overdrawCounts); } float normalization = 1000.f / (m_layerRenderer->viewportWidth() * m_layerRenderer->viewportHeight()); PlatformSupport::histogramCustomCounts("Renderer4.pixelOverdrawOpaque", static_cast<int>(normalization * overdrawCounts.m_pixelsDrawnOpaque), 100, 1000000, 50); PlatformSupport::histogramCustomCounts("Renderer4.pixelOverdrawTransparent", static_cast<int>(normalization * overdrawCounts.m_pixelsDrawnTransparent), 100, 1000000, 50); PlatformSupport::histogramCustomCounts("Renderer4.pixelOverdrawCulled", static_cast<int>(normalization * overdrawCounts.m_pixelsCulled), 100, 1000000, 50); }