void LayerRendererChromium::drawLayersInternal() { if (viewportSize().isEmpty() || !rootLayer()) return; TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0); CCLayerImpl* rootDrawLayer = rootLayer(); makeContextCurrent(); if (!rootDrawLayer->renderSurface()) rootDrawLayer->createRenderSurface(); rootDrawLayer->renderSurface()->setContentRect(IntRect(IntPoint(), viewportSize())); rootDrawLayer->setScissorRect(IntRect(IntPoint(), viewportSize())); CCLayerList renderSurfaceLayerList; renderSurfaceLayerList.append(rootDrawLayer); m_defaultRenderSurface = rootDrawLayer->renderSurface(); m_defaultRenderSurface->clearLayerList(); { TRACE_EVENT("LayerRendererChromium::drawLayersInternal::calcDrawEtc", this, 0); CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(rootDrawLayer, rootDrawLayer, m_zoomAnimatorTransform, m_zoomAnimatorTransform, renderSurfaceLayerList, m_defaultRenderSurface->layerList(), &m_layerSorter, m_capabilities.maxTextureSize); } // The GL viewport covers the entire visible area, including the scrollbars. GLC(m_context.get(), m_context->viewport(0, 0, viewportWidth(), viewportHeight())); m_windowMatrix = screenMatrix(0, 0, viewportWidth(), viewportHeight()); // Bind the common vertex attributes used for drawing all the layers. m_sharedGeometry->prepareForDraw(); GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST)); GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE)); useRenderSurface(m_defaultRenderSurface); if (m_zoomAnimatorTransform.isIdentity()) // Clear to blue to make it easier to spot unrendered regions. m_context->clearColor(0, 0, 1, 1); else // Clear to grey, as zoom animation may leave unrendered regions. // FIXME(wjmaclean): Render some interesting texture in unrendered regions. m_context->clearColor(0.25, 0.25, 0.25, 1); m_context->colorMask(true, true, true, true); m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); // Update the contents of the render surfaces. We traverse the array from // back to front to guarantee that nested render surfaces get rendered in the // correct order. for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get(); CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface(); ASSERT(renderSurface); renderSurface->setSkipsDraw(true); // Render surfaces whose drawable area has zero width or height // will have no layers associated with them and should be skipped. if (!renderSurface->layerList().size()) continue; // Skip completely transparent render surfaces. if (!renderSurface->drawOpacity()) continue; if (useRenderSurface(renderSurface)) { renderSurface->setSkipsDraw(false); if (renderSurfaceLayer != rootDrawLayer) { GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0)); GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT)); GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); } const CCLayerList& layerList = renderSurface->layerList(); for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) drawLayer(layerList[layerIndex].get(), renderSurface); } } if (m_headsUpDisplay->enabled()) { GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); useRenderSurface(m_defaultRenderSurface); m_headsUpDisplay->draw(); } GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); }
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); } } }