void SVGFilterRecordingContext::endContent(FilterData* filterData) { ASSERT(filterData->m_state == FilterData::RecordingContent); SourceGraphic* sourceGraphic = filterData->filter->sourceGraphic(); ASSERT(sourceGraphic); GraphicsContext* context = &paintingContext(); // Use the context that contains the filtered content. ASSERT(m_paintController); ASSERT(m_context); context = m_context.get(); context->beginRecording(filterData->filter->filterRegion()); m_paintController->commitNewDisplayItems(); m_paintController->paintArtifact().replay(*context); sourceGraphic->setPicture(context->endRecording()); // Content is cached by the source graphic so temporaries can be freed. m_paintController = nullptr; m_context = nullptr; filterData->m_state = FilterData::ReadyToPaint; }
PassRefPtr<SkImageFilter> FEImage::createImageFilterForRenderer(RenderObject* renderer, SkiaImageFilterBuilder* builder) { FloatRect dstRect = filterPrimitiveSubregion(); AffineTransform transform; SVGElement* contextNode = toSVGElement(renderer->node()); if (contextNode->hasRelativeLengths()) { SVGLengthContext lengthContext(contextNode); FloatSize viewportSize; // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport. // Build up a transformation that maps from the viewport space to the filter primitive subregion. if (lengthContext.determineViewport(viewportSize)) transform = makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), dstRect); } else { transform.translate(dstRect.x(), dstRect.y()); } GraphicsContext* context = builder->context(); if (!context) return adoptRef(SkBitmapSource::Create(SkBitmap())); AffineTransform contentTransformation; context->save(); context->beginRecording(FloatRect(FloatPoint(), dstRect.size())); context->concatCTM(transform); SVGRenderingContext::renderSubtree(context, renderer, contentTransformation); RefPtr<DisplayList> displayList = context->endRecording(); context->restore(); RefPtr<SkImageFilter> result = adoptRef(SkPictureImageFilter::Create(displayList->picture(), dstRect)); return result.release(); }
DrawingRecorder::DrawingRecorder(GraphicsContext& context, const DisplayItemClientWrapper& displayItemClient, DisplayItem::Type displayItemType, const FloatRect& cullRect) : m_context(context) , m_displayItemClient(displayItemClient) , m_displayItemType(displayItemType) #if ENABLE(ASSERT) , m_displayItemPosition(m_context.displayItemList()->newDisplayItems().size()) , m_underInvalidationCheckingMode(DrawingDisplayItem::CheckPicture) #endif { ASSERT(context.displayItemList()); if (context.displayItemList()->displayItemConstructionIsDisabled()) return; // Must check DrawingRecorder::useCachedDrawingIfPossible before creating the DrawingRecorder. ASSERT((RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled() && context.displayItemList()->paintOffsetWasInvalidated(displayItemClient.displayItemClient())) || RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() || !useCachedDrawingIfPossible(m_context, m_displayItemClient, m_displayItemType)); ASSERT(DisplayItem::isDrawingType(displayItemType)); #if ENABLE(ASSERT) context.setInDrawingRecorder(true); #endif context.beginRecording(cullRect); #if ENABLE(ASSERT) if (RuntimeEnabledFeatures::slimmingPaintStrictCullRectClippingEnabled()) { // Skia depends on the cull rect containing all of the display item commands. When strict // cull rect clipping is enabled, make this explicit. This allows us to identify potential // incorrect cull rects that might otherwise be masked due to Skia internal optimizations. context.save(); IntRect verificationClip = enclosingIntRect(cullRect); // Expand the verification clip by one pixel to account for Skia's SkCanvas::getClipBounds() // expansion, used in testing cull rects. // TODO(schenney) This is not the best place to do this. Ideally, we would expand by one pixel // in device (pixel) space, but to do that we would need to add the verification mode to Skia. verificationClip.inflate(1); context.clipRect(verificationClip, NotAntiAliased, SkRegion::kIntersect_Op); } #endif }