void LayerRendererChromium::updateLayers(LayerList& renderSurfaceLayerList) { TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0); CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl(); if (!rootDrawLayer->renderSurface()) rootDrawLayer->createRenderSurface(); ASSERT(rootDrawLayer->renderSurface()); rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), m_viewportVisibleRect.size()); IntRect rootScissorRect(m_viewportVisibleRect); // The scissorRect should not include the scroll offset. rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y()); rootDrawLayer->setScissorRect(rootScissorRect); m_defaultRenderSurface = rootDrawLayer->renderSurface(); renderSurfaceLayerList.append(rootDrawLayer); TransformationMatrix identityMatrix; m_defaultRenderSurface->m_layerList.clear(); // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the // concept of a large content layer. updatePropertiesAndRenderSurfaces(rootDrawLayer, identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList); #ifndef NDEBUG s_inPaintLayerContents = true; #endif paintLayerContents(renderSurfaceLayerList); #ifndef NDEBUG s_inPaintLayerContents = false; #endif // FIXME: Before updateCompositorResourcesRecursive, when the compositor runs in // its own thread, and when the copyTexImage2D bug is fixed, insert // a glWaitLatch(Compositor->Offscreen) on all child contexts here instead // of after updateCompositorResourcesRecursive. // Also uncomment the glSetLatch(Compositor->Offscreen) code in addChildContext. // if (hardwareCompositing() && m_contextSupportsLatch) { // // For each child context: // // glWaitLatch(Compositor->Offscreen); // ChildContextMap::iterator i = m_childContexts.begin(); // for (; i != m_childContexts.end(); ++i) { // Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(i->first->getExtensions()); // GC3Duint childToParentLatchId, parentToChildLatchId; // ext->getParentToChildLatchCHROMIUM(&parentToChildLatchId); // ext->waitLatchCHROMIUM(parentToChildLatchId); // } // } updateCompositorResourcesRecursive(m_rootLayer.get()); // After updateCompositorResourcesRecursive, set/wait latches for all child // contexts. This will prevent the compositor from using any of the child // parent textures while WebGL commands are executing from javascript *and* // while the final parent texture is being blit'd. copyTexImage2D // uses the parent texture as a temporary resolve buffer, so that's why the // waitLatch is below, to block the compositor from using the parent texture // until the next WebGL SwapBuffers (or copyTextureToParentTexture for // Canvas2D). if (hardwareCompositing() && m_contextSupportsLatch) { m_childContextsWereCopied = true; // For each child context: // glSetLatch(Offscreen->Compositor); // glWaitLatch(Compositor->Offscreen); ChildContextMap::iterator i = m_childContexts.begin(); for (; i != m_childContexts.end(); ++i) { Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(i->first->getExtensions()); GC3Duint childToParentLatchId, parentToChildLatchId; ext->getParentToChildLatchCHROMIUM(&parentToChildLatchId); ext->getChildToParentLatchCHROMIUM(&childToParentLatchId); ext->setLatchCHROMIUM(childToParentLatchId); ext->waitLatchCHROMIUM(parentToChildLatchId); } } }
void LayerRendererChromium::updateAndDrawLayers() { // FIXME: use the frame begin time from the overall compositor scheduler. // This value is currently inaccessible because it is up in Chromium's // RenderWidget. m_headsUpDisplay->onFrameBegin(currentTime()); ASSERT(m_hardwareCompositing); if (!m_rootLayer) return; updateRootLayerContents(); // Recheck that we still have a root layer. This may become null if // compositing gets turned off during a paint operation. if (!m_rootLayer) return; { TRACE_EVENT("LayerRendererChromium::synchronizeTrees", this, 0); m_rootCCLayerImpl = TreeSynchronizer::synchronizeTrees(m_rootLayer.get(), m_rootCCLayerImpl.get()); } LayerList renderSurfaceLayerList; updateLayers(renderSurfaceLayerList); // Before drawLayers: if (hardwareCompositing() && m_contextSupportsLatch) { // FIXME: The multithreaded compositor case will not work as long as // copyTexImage2D resolves to the parent texture, because the main // thread can execute WebGL calls on the child context at any time, // potentially clobbering the parent texture that is being renderered // by the compositor thread. if (m_childContextsWereCopied) { Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions()); // For each child context: // glWaitLatch(Offscreen->Compositor); ChildContextMap::iterator i = m_childContexts.begin(); for (; i != m_childContexts.end(); ++i) { Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions()); GC3Duint latchId; childExt->getChildToParentLatchCHROMIUM(&latchId); parentExt->waitLatchCHROMIUM(latchId); } } // Reset to false to indicate that we have consumed the dirty child // contexts' parent textures. (This is only useful when the compositor // is multithreaded.) m_childContextsWereCopied = false; } drawLayers(renderSurfaceLayerList); m_textureManager->unprotectAllTextures(); // After drawLayers: if (hardwareCompositing() && m_contextSupportsLatch) { Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions()); // For each child context: // glSetLatch(Compositor->Offscreen); ChildContextMap::iterator i = m_childContexts.begin(); for (; i != m_childContexts.end(); ++i) { Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions()); GC3Duint latchId; childExt->getParentToChildLatchCHROMIUM(&latchId); parentExt->setLatchCHROMIUM(latchId); } } if (isCompositingOffscreen()) copyOffscreenTextureToDisplay(); }