Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1682)

Unified Diff: Source/core/rendering/svg/RenderSVGResourceMasker.cpp

Issue 23643003: ImageBuffer-less SVG masking and clipping. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix the Win build. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/rendering/svg/RenderSVGResourceMasker.cpp
diff --git a/Source/core/rendering/svg/RenderSVGResourceMasker.cpp b/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
index ad9631da31e3ee2e9c899cba97f49a89e000e223..6a599a83aeb24a4e6f97d77caf06cdc4a08e9905 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
@@ -23,6 +23,7 @@
#include "core/platform/graphics/FloatRect.h"
#include "core/platform/graphics/GraphicsContext.h"
+#include "core/platform/graphics/GraphicsContextStateSaver.h"
#include "core/platform/graphics/ImageBuffer.h"
#include "core/platform/graphics/transforms/AffineTransform.h"
#include "core/rendering/svg/RenderSVGResource.h"
@@ -45,111 +46,89 @@ RenderSVGResourceMasker::RenderSVGResourceMasker(SVGMaskElement* node)
RenderSVGResourceMasker::~RenderSVGResourceMasker()
{
- if (m_masker.isEmpty())
- return;
-
- deleteAllValues(m_masker);
- m_masker.clear();
}
void RenderSVGResourceMasker::removeAllClientsFromCache(bool markForInvalidation)
{
m_maskContentBoundaries = FloatRect();
- if (!m_masker.isEmpty()) {
- deleteAllValues(m_masker);
- m_masker.clear();
- }
-
markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
void RenderSVGResourceMasker::removeClientFromCache(RenderObject* client, bool markForInvalidation)
{
ASSERT(client);
-
- if (m_masker.contains(client))
- delete m_masker.take(client);
-
markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}
-bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
+bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
+ GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(context);
+ ASSERT(style());
ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
+ ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
- bool missingMaskerData = !m_masker.contains(object);
- if (missingMaskerData)
- m_masker.set(object, new MaskerData);
-
- MaskerData* maskerData = m_masker.get(object);
+ FloatRect repaintRect = object->repaintRectInLocalCoordinates();
+ if (repaintRect.isEmpty() || !node()->hasChildNodes())
+ return false;
- AffineTransform absoluteTransform;
- SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform);
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
+ ASSERT(svgStyle);
+ ColorSpace colorSpace = svgStyle->colorInterpolation() == CI_LINEARRGB
+ ? ColorSpaceLinearRGB
+ : ColorSpaceDeviceRGB;
- FloatRect repaintRect = object->repaintRectInLocalCoordinates();
+ // Mask layer start.
+ context->beginTransparencyLayer(1, &repaintRect);
+ {
+ // Draw the mask with color conversion (when needed).
+ GraphicsContextStateSaver maskContentSaver(*context);
+ context->setColorSpaceConversion(ColorSpaceDeviceRGB, colorSpace);
- if (!maskerData->maskImage && !repaintRect.isEmpty()) {
- SVGMaskElement* maskElement = toSVGMaskElement(node());
- if (!maskElement)
- return false;
-
- ASSERT(style());
- const SVGRenderStyle* svgStyle = style()->svgStyle();
- ASSERT(svgStyle);
- ColorSpace colorSpace = svgStyle->colorInterpolation() == CI_LINEARRGB ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB;
- if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskerData->maskImage, Unaccelerated))
- return false;
-
- if (!drawContentIntoMaskImage(maskerData, colorSpace, maskElement, object)) {
- maskerData->maskImage.clear();
- }
+ drawMaskContent(context, object->objectBoundingBox());
}
- if (!maskerData->maskImage)
- return false;
+ // Content layer start.
+ MaskType maskType = svgStyle->maskType() == MT_LUMINANCE ? LuminanceMaskType : AlphaMaskType;
+ context->beginMaskedLayer(repaintRect, maskType);
- SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, repaintRect, maskerData->maskImage, missingMaskerData);
return true;
}
-bool RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, ColorSpace colorSpace, const SVGMaskElement* maskElement, RenderObject* object)
+void RenderSVGResourceMasker::postApplyResource(RenderObject*, GraphicsContext*& context,
+ unsigned short resourceMode, const Path*, const RenderSVGShape*)
{
- GraphicsContext* maskImageContext = maskerData->maskImage->context();
- ASSERT(maskImageContext);
+ ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
+
+ // Transfer content layer -> mask layer (SrcIn)
+ context->endLayer();
+ // Transfer mask layer -> bg layer (SrcOver)
+ context->endLayer();
+}
- // Eventually adjust the mask image context according to the target objectBoundingBox.
+void RenderSVGResourceMasker::drawMaskContent(GraphicsContext* context, const FloatRect& targetBoundingBox)
+{
+ ASSERT(context);
+
+ // Adjust the mask image context according to the target objectBoundingBox.
AffineTransform maskContentTransformation;
- if (maskElement->maskContentUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- FloatRect objectBoundingBox = object->objectBoundingBox();
- maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y());
- maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
- maskImageContext->concatCTM(maskContentTransformation);
+ if (toSVGMaskElement(node())->maskContentUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ maskContentTransformation.translate(targetBoundingBox.x(), targetBoundingBox.y());
+ maskContentTransformation.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height());
+ context->concatCTM(maskContentTransformation);
}
- // Draw the content into the ImageBuffer.
- for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
- RenderObject* renderer = node->renderer();
- if (!node->isSVGElement() || !renderer)
+ for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
+ RenderObject* renderer = childNode->renderer();
+ if (!childNode->isSVGElement() || !renderer)
continue;
- if (renderer->needsLayout())
- return false;
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
- SVGRenderingContext::renderSubtreeToImageBuffer(maskerData->maskImage.get(), renderer, maskContentTransformation);
- }
-
- maskerData->maskImage->transformColorSpace(ColorSpaceDeviceRGB, colorSpace);
-
- ASSERT(style());
- ASSERT(style()->svgStyle());
- // Create the luminance mask.
- if (style()->svgStyle()->maskType() == MT_LUMINANCE)
- maskerData->maskImage->convertToLuminanceMask();
- return true;
+ SVGRenderingContext::renderSubtree(context, renderer, maskContentTransformation);
+ }
}
void RenderSVGResourceMasker::calculateMaskContentRepaintRect()
« no previous file with comments | « Source/core/rendering/svg/RenderSVGResourceMasker.h ('k') | Source/core/rendering/svg/RenderSVGResourcePattern.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698