bool toWebFilterOperations(const FilterOperations& inOperations, WebFilterOperations* outOperations) { SkiaImageFilterBuilder builder; FilterOutsets outsets = inOperations.outsets(); builder.setCropOffset(FloatSize(outsets.left(), outsets.top())); return builder.buildFilterOperations(inOperations, outOperations); }
FilterPainter::FilterPainter(DeprecatedPaintLayer& layer, GraphicsContext* context, const LayoutPoint& offsetFromRoot, const ClipRect& clipRect, DeprecatedPaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed) : m_filterInProgress(false) , m_context(context) , m_layoutObject(layer.layoutObject()) { if (!layer.filterEffectBuilder() || !layer.paintsWithFilters()) return; ASSERT(layer.filterInfo()); SkiaImageFilterBuilder builder; RefPtrWillBeRawPtr<FilterEffect> lastEffect = layer.filterEffectBuilder()->lastEffect(); lastEffect->determineFilterPrimitiveSubregion(MapRectForward); RefPtr<SkImageFilter> imageFilter = builder.build(lastEffect.get(), ColorSpaceDeviceRGB); if (!imageFilter) return; if (!rootRelativeBoundsComputed) { rootRelativeBounds = layer.physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); rootRelativeBoundsComputed = true; } // We'll handle clipping to the dirty rect before filter rasterization. // Filter processing will automatically expand the clip rect and the offscreen to accommodate any filter outsets. // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved. // Subsequent code should not clip to the dirty rect, since we've already // done it above, and doing it later will defeat the outsets. paintingInfo.clipToDirtyRect = false; if (clipRect.rect() != paintingInfo.paintDirtyRect || clipRect.hasRadius()) { m_clipRecorder = adoptPtr(new LayerClipRecorder(*context, *layer.layoutObject(), DisplayItem::ClipLayerFilter, clipRect, &paintingInfo, LayoutPoint(), paintFlags)); } ASSERT(m_layoutObject); if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { ASSERT(context->displayItemList()); if (!context->displayItemList()->displayItemConstructionIsDisabled()) { FilterOperations filterOperations(layer.computeFilterOperations(m_layoutObject->styleRef())); OwnPtr<WebFilterOperations> webFilterOperations = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations()); builder.buildFilterOperations(filterOperations, webFilterOperations.get()); // FIXME: It's possible to have empty WebFilterOperations here even // though the SkImageFilter produced above is non-null, since the // layer's FilterEffectBuilder can have a stale representation of // the layer's filter. See crbug.com/502026. if (webFilterOperations->isEmpty()) return; context->displayItemList()->createAndAppend<BeginFilterDisplayItem>(*m_layoutObject, imageFilter, rootRelativeBounds, webFilterOperations.release()); } } else { BeginFilterDisplayItem filterDisplayItem(*m_layoutObject, imageFilter, rootRelativeBounds); filterDisplayItem.replay(*context); } m_filterInProgress = true; }
void GraphicsLayer::setFilters(const FilterOperations& filters) { SkiaImageFilterBuilder builder; OwnPtr<WebFilterOperations> webFilters = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations()); FilterOutsets outsets = filters.outsets(); builder.setCropOffset(FloatSize(outsets.left(), outsets.top())); builder.buildFilterOperations(filters, webFilters.get()); m_layer->layer()->setFilters(*webFilters); }
bool GraphicsLayer::setFilters(const FilterOperations& filters) { SkiaImageFilterBuilder builder; OwnPtr<WebFilterOperations> webFilters = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations()); FilterOutsets outsets = filters.outsets(); builder.setCropOffset(FloatSize(outsets.left(), outsets.top())); if (!builder.buildFilterOperations(filters, webFilters.get())) { // Make sure the filters are removed from the platform layer, as they are // going to fallback to software mode. webFilters->clear(); m_layer->layer()->setFilters(*webFilters); m_filters = FilterOperations(); return false; } m_layer->layer()->setFilters(*webFilters); m_filters = filters; return true; }