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); } } } }
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); } } } }
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()); }
void TextureMapperLayer::paintRecursive(const TextureMapperPaintOptions& options) { if (!isVisible()) return; TextureMapperPaintOptions paintOptions(options); paintOptions.opacity *= m_currentOpacity; if (!shouldBlend()) { paintSelfAndChildrenWithReplica(paintOptions); return; } paintUsingOverlapRegions(paintOptions); }