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