Esempio n. 1
0
void CCLayerTreeHostImpl::setFullRootLayerDamage()
{
    if (rootLayer()) {
        CCRenderSurface* renderSurface = rootLayer()->renderSurface();
        if (renderSurface)
            renderSurface->damageTracker()->forceFullDamageNextUpdate();
    }
}
Esempio n. 2
0
void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer)
{
    // FIXME: render surface layers should be a CCLayerImpl-derived class and
    // not be handled specially here.
    CCRenderSurface* surface = layer->renderSurface();
    OwnPtr<CCSharedQuadState> sharedQuadState = surface->createSharedQuadState();
    m_quadList.append(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect()));
    m_sharedQuadStateList.append(sharedQuadState.release());
}
Esempio n. 3
0
void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer)
{
    // FIXME: render surface layers should be a CCLayerImpl-derived class and
    // not be handled specially here.
    CCRenderSurface* surface = layer->renderSurface();
    bool isOpaque = false;
    OwnPtr<CCSharedQuadState> sharedQuadState = CCSharedQuadState::create(surface->drawTransform(), surface->drawTransform(), surface->contentRect(), surface->clipRect(), surface->drawOpacity(), isOpaque);
    m_quadList.append(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect()));
    m_sharedQuadStateList.append(sharedQuadState.release());
}
Esempio n. 4
0
void CCLayerTreeHostImpl::trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList)
{
    // For now, we use damage tracking to compute a global scissor. To do this, we must
    // compute all damage tracking before drawing anything, so that we know the root
    // damage rect. The root damage rect is then used to scissor each surface.

    for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
        CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex];
        CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
        ASSERT(renderSurface);
        renderSurface->damageTracker()->updateDamageTrackingState(renderSurface->layerList(), renderSurfaceLayer->id(), renderSurfaceLayer->maskLayer());
    }
}
Esempio n. 5
0
void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer)
{
    // FIXME: render surface layers should be a CCLayerImpl-derived class and
    // not be handled specially here.
    CCRenderSurface* surface = layer->renderSurface();
    OwnPtr<CCSharedQuadState> sharedQuadState = surface->createSharedQuadState();
    if (layer->hasDebugBorders()) {
        Color color(debugSurfaceBorderColorRed, debugSurfaceBorderColorGreen, debugSurfaceBorderColorBlue, debugSurfaceBorderAlpha);
        m_quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth));
    }
    bool isReplica = false;
    m_quadList.append(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect(), isReplica));
    m_sharedQuadStateList.append(sharedQuadState.release());

    // Add replica after the surface so that it appears below the surface.
    if (surface->hasReplica()) {
        OwnPtr<CCSharedQuadState> sharedQuadState = surface->createReplicaSharedQuadState();
        if (layer->hasDebugBorders()) {
            Color color(debugReplicaBorderColorRed, debugReplicaBorderColorGreen, debugReplicaBorderColorBlue, debugSurfaceBorderAlpha);
            m_quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState.get(), surface->contentRect(), color, debugSurfaceBorderWidth));
        }
        bool isReplica = true;
        m_quadList.append(CCRenderSurfaceDrawQuad::create(sharedQuadState.get(), surface->contentRect(), layer, surfaceDamageRect(), isReplica));
        m_sharedQuadStateList.append(sharedQuadState.release());
    }
}
Esempio n. 6
0
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());
    }
}
Esempio n. 7
0
void CCLayerSorter::createGraphNodes(LayerList::iterator first, LayerList::iterator last)
{
#if !defined( NDEBUG )
    LOG(CCLayerSorter, "Creating graph nodes:\n");
#endif
    float minZ = FLT_MAX;
    float maxZ = -FLT_MAX;
    for (LayerList::const_iterator it = first; it < last; it++) {
        m_nodes.append(GraphNode(it->get()));
        GraphNode& node = m_nodes.at(m_nodes.size() - 1);
        CCRenderSurface* renderSurface = node.layer->renderSurface();
        if (!node.layer->drawsContent() && !renderSurface)
            continue;

#if !defined( NDEBUG )
        LOG(CCLayerSorter, "Layer %d (%d x %d)\n", node.layer->debugID(), node.layer->bounds().width(), node.layer->bounds().height());
#endif

        TransformationMatrix drawTransform;
        float layerWidth, layerHeight;
        if (renderSurface) {
            drawTransform = renderSurface->drawTransform();
            layerWidth = 0.5 * renderSurface->contentRect().width();
            layerHeight = 0.5 * renderSurface->contentRect().height();
        } else {
            drawTransform = node.layer->drawTransform();
            layerWidth = 0.5 * node.layer->bounds().width();
            layerHeight = 0.5 * node.layer->bounds().height();
        }

        FloatPoint3D c1 = drawTransform.mapPoint(FloatPoint3D(-layerWidth, layerHeight, 0));
        FloatPoint3D c2 = drawTransform.mapPoint(FloatPoint3D(layerWidth, layerHeight, 0));
        FloatPoint3D c3 = drawTransform.mapPoint(FloatPoint3D(layerWidth, -layerHeight, 0));
        FloatPoint3D c4 = drawTransform.mapPoint(FloatPoint3D(-layerWidth, -layerHeight, 0));
        node.normal = (c2 - c1).cross(c3 - c1);
        node.c1 = FloatPoint(c1.x(), c1.y());
        node.c2 = FloatPoint(c2.x(), c2.y());
        node.c3 = FloatPoint(c3.x(), c3.y());
        node.c4 = FloatPoint(c4.x(), c4.y());
        node.origin = c1;
        node.boundingBox.fitToPoints(node.c1, node.c2, node.c3, node.c4);

        maxZ = max(c4.z(), max(c3.z(), max(c2.z(), max(maxZ, c1.z()))));
        minZ = min(c4.z(), min(c3.z(), min(c2.z(), min(minZ, c1.z()))));
    }
    if (last - first)
        m_zRange = fabsf(maxZ - minZ);
}
Esempio n. 8
0
static FloatRect damageInSurfaceSpace(CCLayerImpl* renderSurfaceLayer, const FloatRect& rootDamageRect)
{
    FloatRect surfaceDamageRect;
    // For now, we conservatively use the root damage as the damage for
    // all surfaces, except perspective transforms.
    TransformationMatrix screenSpaceTransform = computeScreenSpaceTransformForSurface(renderSurfaceLayer);
    if (screenSpaceTransform.hasPerspective()) {
        // Perspective projections do not play nice with mapRect of
        // inverse transforms. In this uncommon case, its simpler to
        // just redraw the entire surface.
        // FIXME: use calculateVisibleRect to handle projections.
        CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
        surfaceDamageRect = renderSurface->contentRect();
    } else {
        TransformationMatrix inverseScreenSpaceTransform = screenSpaceTransform.inverse();
        surfaceDamageRect = inverseScreenSpaceTransform.mapRect(rootDamageRect);
    }
    return surfaceDamageRect;
}
Esempio n. 9
0
void CCLayerSorter::createGraphNodes(LayerList::iterator first, LayerList::iterator last)
{
#if !defined( NDEBUG )
    LOG(CCLayerSorter, "Creating graph nodes:\n");
#endif
    float minZ = FLT_MAX;
    float maxZ = -FLT_MAX;
    for (LayerList::const_iterator it = first; it < last; it++) {
        m_nodes.append(GraphNode(*it));
        GraphNode& node = m_nodes.at(m_nodes.size() - 1);
        CCRenderSurface* renderSurface = node.layer->renderSurface();
        if (!node.layer->drawsContent() && !renderSurface)
            continue;

#if !defined( NDEBUG )
        LOG(CCLayerSorter, "Layer %d (%d x %d)\n", node.layer->debugID(), node.layer->bounds().width(), node.layer->bounds().height());
#endif

        TransformationMatrix drawTransform;
        float layerWidth, layerHeight;
        if (renderSurface) {
            drawTransform = renderSurface->drawTransform();
            layerWidth = renderSurface->contentRect().width();
            layerHeight = renderSurface->contentRect().height();
        } else {
            drawTransform = node.layer->drawTransform();
            layerWidth = node.layer->bounds().width();
            layerHeight = node.layer->bounds().height();
        }

        node.shape = LayerShape(layerWidth, layerHeight, drawTransform);

        maxZ = max(maxZ, node.shape.transformOrigin.z());
        minZ = min(minZ, node.shape.transformOrigin.z());
    }

    m_zRange = fabsf(maxZ - minZ);
}
Esempio n. 10
0
void CCDamageTracker::extendDamageForRenderSurface(CCLayerImpl* layer, FloatRect& targetDamageRect)
{
    // There are two ways a "descendant surface" can damage regions of the "target surface":
    //   1. Property change:
    //        - a surface's geometry can change because of
    //            - changes to descendants (i.e. the subtree) that affect the surface's content rect
    //            - changes to ancestor layers that propagate their property changes to their entire subtree.
    //        - just like layers, both the old surface rect and new surface rect will
    //          damage the target surface in this case.
    //
    //   2. Damage rect: This surface may have been damaged by its own layerList as well, and that damage
    //      should propagate to the target surface.
    //

    CCRenderSurface* renderSurface = layer->renderSurface();

    bool surfaceIsNew = false;
    FloatRect oldSurfaceRect = removeRectFromCurrentFrame(layer->id(), surfaceIsNew);

    FloatRect surfaceRectInTargetSpace = renderSurface->drawableContentRect(); // already includes replica if it exists.
    saveRectForNextFrame(layer->id(), surfaceRectInTargetSpace);

    FloatRect damageRectInLocalSpace;
    if (surfaceIsNew || renderSurface->surfacePropertyChanged() || layer->layerSurfacePropertyChanged()) {
        // The entire surface contributes damage.
        damageRectInLocalSpace = renderSurface->contentRect();

        // The surface's old region is now exposed on the target surface, too.
        targetDamageRect.uniteIfNonZero(oldSurfaceRect);
    } else {
        // Only the surface's damageRect will damage the target surface.
        damageRectInLocalSpace = renderSurface->damageTracker()->currentDamageRect();
    }

    // If there was damage, transform it to target space, and possibly contribute its reflection if needed.
    if (!damageRectInLocalSpace.isEmpty()) {
        const WebTransformationMatrix& drawTransform = renderSurface->drawTransform();
        FloatRect damageRectInTargetSpace = CCMathUtil::mapClippedRect(drawTransform, damageRectInLocalSpace);
        targetDamageRect.uniteIfNonZero(damageRectInTargetSpace);

        if (layer->replicaLayer()) {
            const WebTransformationMatrix& replicaDrawTransform = renderSurface->replicaDrawTransform();
            targetDamageRect.uniteIfNonZero(CCMathUtil::mapClippedRect(replicaDrawTransform, damageRectInLocalSpace));
        }
    }

    // If there was damage on the replica's mask, then the target surface receives that damage as well.
    if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) {
        CCLayerImpl* replicaMaskLayer = layer->replicaLayer()->maskLayer();

        bool replicaIsNew = false;
        removeRectFromCurrentFrame(replicaMaskLayer->id(), replicaIsNew);

        const WebTransformationMatrix& replicaDrawTransform = renderSurface->replicaDrawTransform();
        FloatRect replicaMaskLayerRect = CCMathUtil::mapClippedRect(replicaDrawTransform, FloatRect(FloatPoint::zero(), FloatSize(replicaMaskLayer->bounds().width(), replicaMaskLayer->bounds().height())));
        saveRectForNextFrame(replicaMaskLayer->id(), replicaMaskLayerRect);

        // In the current implementation, a change in the replica mask damages the entire replica region.
        if (replicaIsNew || replicaMaskLayer->layerPropertyChanged() || !replicaMaskLayer->updateRect().isEmpty())
            targetDamageRect.uniteIfNonZero(replicaMaskLayerRect);
    }

    // If the layer has a background filter, this may cause pixels in our surface to be expanded, so we will need to expand any damage
    // at or below this layer. We expand the damage from this layer too, as we need to readback those pixels from the surface with only
    // the contents of layers below this one in them. This means we need to redraw any pixels in the surface being used for the blur in
    // this layer this frame.
    if (layer->backgroundFilters().hasFilterThatMovesPixels())
        expandDamageRectInsideRectWithFilters(targetDamageRect, surfaceRectInTargetSpace, layer->backgroundFilters());
}
Esempio n. 11
0
void CCDamageTracker::extendDamageForRenderSurface(CCLayerImpl* layer, FloatRect& targetDamageRect)
{
    // There are two ways a "descendant surface" can damage regions of the "target surface":
    //   1. Property change:
    //        - a surface's geometry can change because of
    //            - changes to descendants (i.e. the subtree) that affect the surface's content rect
    //            - changes to ancestor layers that propagate their property changes to their entire subtree.
    //        - just like layers, both the old surface rect and new surface rect will
    //          damage the target surface in this case.
    //
    //   2. Damage rect: This surface may have been damaged by its own layerList as well, and that damage
    //      should propagate to the target surface.
    //

    CCRenderSurface* renderSurface = layer->renderSurface();

    bool surfaceIsNew = false;
    FloatRect oldSurfaceRect = removeRectFromCurrentFrame(layer->id(), surfaceIsNew);

    FloatRect surfaceRectInTargetSpace = renderSurface->drawableContentRect(); // already includes replica if it exists.
    saveRectForNextFrame(layer->id(), surfaceRectInTargetSpace);

    FloatRect damageRectInLocalSpace;
    if (surfaceIsNew || renderSurface->surfacePropertyChanged()) {
        // The entire surface contributes damage.
        damageRectInLocalSpace = renderSurface->contentRect();

        // The surface's old region is now exposed on the target surface, too.
        targetDamageRect.uniteIfNonZero(oldSurfaceRect);
    } else {
        // Only the surface's damageRect will damage the target surface.
        damageRectInLocalSpace = renderSurface->damageTracker()->currentDamageRect();
    }

    // If there was damage, transform it to target space, and possibly contribute its reflection if needed.
    if (!damageRectInLocalSpace.isEmpty()) {
        const TransformationMatrix& originTransform = renderSurface->originTransform();
        FloatRect damageRectInTargetSpace = CCMathUtil::mapClippedRect(originTransform, damageRectInLocalSpace);
        targetDamageRect.uniteIfNonZero(damageRectInTargetSpace);

        if (layer->replicaLayer()) {
            const TransformationMatrix& replicaOriginTransform = renderSurface->replicaOriginTransform();
            targetDamageRect.uniteIfNonZero(CCMathUtil::mapClippedRect(replicaOriginTransform, damageRectInLocalSpace));
        }
    }

    // If there was damage on the replica's mask, then the target surface receives that damage as well.
    if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) {
        CCLayerImpl* replicaMaskLayer = layer->replicaLayer()->maskLayer();

        bool replicaIsNew = false;
        removeRectFromCurrentFrame(replicaMaskLayer->id(), replicaIsNew);

        // Compute the replica's "originTransform" that maps from the replica's origin space to the target surface origin space.
        const TransformationMatrix& replicaOriginTransform = renderSurface->replicaOriginTransform();
        FloatRect replicaMaskLayerRect = CCMathUtil::mapClippedRect(replicaOriginTransform, FloatRect(FloatPoint::zero(), FloatSize(replicaMaskLayer->bounds().width(), replicaMaskLayer->bounds().height())));
        saveRectForNextFrame(replicaMaskLayer->id(), replicaMaskLayerRect);

        // In the current implementation, a change in the replica mask damages the entire replica region.
        if (replicaIsNew || replicaMaskLayer->layerPropertyChanged() || !replicaMaskLayer->updateRect().isEmpty())
            targetDamageRect.uniteIfNonZero(replicaMaskLayerRect);
    }
}
Esempio n. 12
0
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));
}