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::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 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 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); }