Esempio n. 1
0
void TextureMapperLayer::paintUsingOverlapRegions(const TextureMapperPaintOptions& options)
{
    Region overlapRegion;
    Region nonOverlapRegion;
    computeOverlapRegions(overlapRegion, nonOverlapRegion, ResolveSelfOverlapAlways);
    if (overlapRegion.isEmpty()) {
        paintSelfAndChildrenWithReplica(options);
        return;
    }

    Vector<IntRect> rects;

    nonOverlapRegion.translate(options.offset);
    rects = nonOverlapRegion.rects();
    for (size_t i = 0; i < rects.size(); ++i) {
        options.textureMapper->beginClip(TransformationMatrix(), rects[i]);
        paintSelfAndChildrenWithReplica(options);
        options.textureMapper->endClip();
    }

    rects = overlapRegion.rects();
    IntSize maxTextureSize = options.textureMapper->maxTextureSize();
    IntRect rect;
    for (size_t i = 0; i < rects.size(); ++i) {
        rect = rects[i];
        for (int x = rect.x(); x < rect.maxX(); x += maxTextureSize.width()) {
            for (int y = rect.y(); y < rect.maxY(); y += maxTextureSize.height()) {
                IntRect tileRect(IntPoint(x, y), maxTextureSize);
                tileRect.intersect(rect);
                paintWithIntermediateSurface(options, tileRect);
            }
        }
    }
}
Esempio n. 2
0
void TextureMapperLayer::paintUsingOverlapRegions(const TextureMapperPaintOptions& options)
{
    Region overlapRegion;
    Region nonOverlapRegion;
    computeOverlapRegions(overlapRegion, nonOverlapRegion, ResolveSelfOverlapAlways);
    if (overlapRegion.isEmpty()) {
        paintSelfAndChildrenWithReplica(options);
        return;
    }

    // Having both overlap and non-overlap regions carries some overhead. Avoid it if the overlap area
    // is big anyway.
    if (overlapRegion.bounds().size().area() > nonOverlapRegion.bounds().size().area()) {
        overlapRegion.unite(nonOverlapRegion);
        nonOverlapRegion = Region();
    }

    nonOverlapRegion.translate(options.offset);
    Vector<IntRect> rects = nonOverlapRegion.rects();

    for (size_t i = 0; i < rects.size(); ++i) {
        IntRect rect = rects[i];
        if (!rect.intersects(options.textureMapper->clipBounds()))
            continue;

        options.textureMapper->beginClip(TransformationMatrix(), rects[i]);
        paintSelfAndChildrenWithReplica(options);
        options.textureMapper->endClip();
    }

    rects = overlapRegion.rects();
    static const size_t OverlapRegionConsolidationThreshold = 4;
    if (nonOverlapRegion.isEmpty() && rects.size() > OverlapRegionConsolidationThreshold) {
        rects.clear();
        rects.append(overlapRegion.bounds());
    }

    IntSize maxTextureSize = options.textureMapper->maxTextureSize();
    IntRect adjustedClipBounds(options.textureMapper->clipBounds());
    adjustedClipBounds.move(-options.offset);
    for (size_t i = 0; i < rects.size(); ++i) {
        IntRect rect = rects[i];
        for (int x = rect.x(); x < rect.maxX(); x += maxTextureSize.width()) {
            for (int y = rect.y(); y < rect.maxY(); y += maxTextureSize.height()) {
                IntRect tileRect(IntPoint(x, y), maxTextureSize);
                tileRect.intersect(rect);
                if (!tileRect.intersects(adjustedClipBounds))
                    continue;

                paintWithIntermediateSurface(options, tileRect);
            }
        }
    }
}
Esempio n. 3
0
void TextureMapperLayer::paintRecursive(const TextureMapperPaintOptions& options)
{
    if (!isVisible())
        return;

    float opacity = options.opacity * m_opacity;
    RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->texture() : 0;

    TextureMapperPaintOptions paintOptions(options);
    paintOptions.mask = maskTexture.get();
    IntRect surfaceRect;

    RefPtr<BitmapTexture> surface;

    if (!shouldPaintToIntermediateSurface()) {
        paintOptions.opacity = opacity;
        paintSelfAndChildrenWithReplica(paintOptions);
        return;
    }

    // Prepare a surface to paint into.
    // We paint into the surface ignoring the opacity/transform of the current layer.
    surfaceRect = intermediateSurfaceRect();
    surface = options.textureMapper->acquireTextureFromPool(surfaceRect.size());
    options.textureMapper->bindSurface(surface.get());
    paintOptions.opacity = 1;

    // We have to use combinedForChildren() and not combined(), otherwise preserve-3D doesn't work.
    paintOptions.transform = m_transform.combinedForChildren().inverse();
    paintOptions.offset = -IntSize(surfaceRect.x(), surfaceRect.y());

    paintSelfAndChildrenWithReplica(paintOptions);

    // If we painted the replica, the mask is already applied so we don't need to paint it again.
    if (m_state.replicaLayer)
        maskTexture = 0;

#if ENABLE(CSS_FILTERS)
    surface = applyFilters(m_state.filters, options.textureMapper, surface.get(), surfaceRect);
#endif

    options.textureMapper->bindSurface(options.surface.get());
    TransformationMatrix targetTransform =
            TransformationMatrix(options.transform)
                .multiply(m_transform.combined())
                .translate(options.offset.width(), options.offset.height());
    options.textureMapper->drawTexture(*surface.get(), surfaceRect, targetTransform, opacity, maskTexture.get());
}
Esempio n. 4
0
void TextureMapperLayer::paintRecursive(const TextureMapperPaintOptions& options)
{
    if (!isVisible())
        return;

    TextureMapperPaintOptions paintOptions(options);
    paintOptions.opacity *= m_currentOpacity;

    if (!shouldBlend()) {
        paintSelfAndChildrenWithReplica(paintOptions);
        return;
    }

    paintUsingOverlapRegions(paintOptions);
}