[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
hyatt at apple.com
hyatt at apple.com
Wed Dec 22 12:10:44 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit ffec3a476965584382e6627af5520c23e28d073d
Author: hyatt at apple.com <hyatt at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Aug 16 20:44:01 2010 +0000
https://bugs.webkit.org/show_bug.cgi?id=43507, stop ImageBuffer from copying its data when rendering after canvas changes happen.
Reviewed by Anders Carlsson.
This patch renames ImageBuffer::image() to ImageBuffer::copyImage(). The new method always returns a new copy that is a current
snapshot of the ImageBuffer.
To draw an ImageBuffer, you now use new GraphicsContext calls: drawImageBuffer. Platforms can then optimize these calls to draw
efficiently without having to copy the bits of the ImageBuffer into an Image.
* WebCore.xcodeproj/project.pbxproj:
* css/CSSCanvasValue.cpp:
(WebCore::CSSCanvasValue::image):
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::willDraw):
(WebCore::HTMLCanvasElement::reset):
(WebCore::HTMLCanvasElement::paint):
(WebCore::HTMLCanvasElement::setSurfaceSize):
(WebCore::HTMLCanvasElement::copiedImage):
(WebCore::HTMLCanvasElement::clearCopiedImage):
* html/HTMLCanvasElement.h:
* html/canvas/CanvasPattern.cpp:
(WebCore::CanvasPattern::CanvasPattern):
* html/canvas/CanvasPattern.h:
(WebCore::CanvasPattern::create):
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::drawImage):
(WebCore::CanvasRenderingContext2D::createPattern):
(WebCore::CanvasRenderingContext2D::drawTextInternal):
* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::paintRenderingResultsToCanvas):
(WebCore::WebGLRenderingContext::reshape):
(WebCore::WebGLRenderingContext::texImage2D):
(WebCore::WebGLRenderingContext::texSubImage2D):
* html/canvas/WebGLRenderingContext.h:
(WebCore::WebGLRenderingContext::paintsIntoCanvasBuffer):
* platform/graphics/GeneratedImage.cpp:
(WebCore::GeneratedImage::drawPattern):
* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::drawImageBuffer):
(WebCore::GraphicsContext::clipToImageBuffer):
* platform/graphics/GraphicsContext.h:
* platform/graphics/GraphicsContext3D.h:
(WebCore::GraphicsContext3D::paintsIntoCanvasBuffer):
* platform/graphics/Image.h:
* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::width):
(WebCore::ImageBuffer::height):
* platform/graphics/Pattern.cpp:
(WebCore::Pattern::Pattern):
* platform/graphics/Pattern.h:
(WebCore::Pattern::create):
* platform/graphics/cairo/GraphicsContextCairo.cpp:
* platform/graphics/cairo/ImageBufferCairo.cpp:
(WebCore::ImageBuffer::drawsUsingCopy):
(WebCore::ImageBuffer::copyImage):
(WebCore::ImageBuffer::clip):
(WebCore::ImageBuffer::draw):
(WebCore::ImageBuffer::drawPattern):
* platform/graphics/cg/GraphicsContextCG.cpp:
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::ImageBuffer):
(WebCore::ImageBuffer::drawsUsingCopy):
(WebCore::ImageBuffer::copyImage):
(WebCore::ImageBuffer::draw):
(WebCore::ImageBuffer::drawPattern):
(WebCore::ImageBuffer::clip):
* platform/graphics/cg/ImageBufferData.h:
* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::FEColorMatrix::apply):
* platform/graphics/filters/FEComposite.cpp:
(WebCore::FEComposite::apply):
* platform/graphics/filters/SourceAlpha.cpp:
(WebCore::SourceAlpha::apply):
* platform/graphics/filters/SourceGraphic.cpp:
(WebCore::SourceGraphic::apply):
* platform/graphics/mac/GraphicsContext3DMac.mm:
* platform/graphics/qt/GraphicsContext3DQt.cpp:
* platform/graphics/qt/GraphicsContextQt.cpp:
* platform/graphics/qt/ImageBufferData.h:
* platform/graphics/qt/ImageBufferQt.cpp:
(WebCore::ImageBufferData::ImageBufferData):
(WebCore::ImageBuffer::drawsUsingCopy):
(WebCore::ImageBuffer::copyImage):
(WebCore::ImageBuffer::draw):
(WebCore::ImageBuffer::drawPattern):
(WebCore::ImageBuffer::clip):
* platform/graphics/skia/GraphicsContextSkia.cpp:
* platform/graphics/skia/ImageBufferSkia.cpp:
(WebCore::ImageBuffer::drawsUsingCopy):
(WebCore::ImageBuffer::copyImage):
(WebCore::ImageBuffer::clip):
(WebCore::):
* platform/graphics/wx/GraphicsContextWx.cpp:
* platform/graphics/wx/ImageBufferWx.cpp:
(WebCore::ImageBuffer::drawsUsingCopy):
(WebCore::ImageBuffer::copyImage):
(WebCore::ImageBuffer::clip):
(WebCore::ImageBuffer::draw):
(WebCore::ImageBuffer::drawPattern):
* platform/mac/ScrollbarThemeMac.mm:
(WebCore::ScrollbarThemeMac::paint):
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
* rendering/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::applyClippingToContext):
* rendering/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::postApplyResource):
* rendering/RenderSVGResourceGradient.cpp:
(WebCore::clipToTextMask):
* rendering/RenderSVGResourceMasker.cpp:
(WebCore::RenderSVGResourceMasker::applyResource):
* rendering/RenderSVGResourcePattern.cpp:
(WebCore::RenderSVGResourcePattern::buildPattern):
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::paintProgressBar):
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::build):
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::nativeImageForCurrentFrame):
* svg/graphics/SVGImage.h:
* svg/graphics/filters/SVGFEMerge.cpp:
(WebCore::FEMerge::apply):
* svg/graphics/filters/SVGFEOffset.cpp:
(WebCore::FEOffset::apply):
* svg/graphics/filters/SVGFETile.cpp:
(WebCore::FETile::apply):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65449 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 163f6c5..a5bbc74 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,133 @@
+2010-08-16 David Hyatt <hyatt at apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=43507, stop ImageBuffer from copying its data when rendering after canvas changes happen.
+
+ This patch renames ImageBuffer::image() to ImageBuffer::copyImage(). The new method always returns a new copy that is a current
+ snapshot of the ImageBuffer.
+
+ To draw an ImageBuffer, you now use new GraphicsContext calls: drawImageBuffer. Platforms can then optimize these calls to draw
+ efficiently without having to copy the bits of the ImageBuffer into an Image.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/CSSCanvasValue.cpp:
+ (WebCore::CSSCanvasValue::image):
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::willDraw):
+ (WebCore::HTMLCanvasElement::reset):
+ (WebCore::HTMLCanvasElement::paint):
+ (WebCore::HTMLCanvasElement::setSurfaceSize):
+ (WebCore::HTMLCanvasElement::copiedImage):
+ (WebCore::HTMLCanvasElement::clearCopiedImage):
+ * html/HTMLCanvasElement.h:
+ * html/canvas/CanvasPattern.cpp:
+ (WebCore::CanvasPattern::CanvasPattern):
+ * html/canvas/CanvasPattern.h:
+ (WebCore::CanvasPattern::create):
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::drawImage):
+ (WebCore::CanvasRenderingContext2D::createPattern):
+ (WebCore::CanvasRenderingContext2D::drawTextInternal):
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::paintRenderingResultsToCanvas):
+ (WebCore::WebGLRenderingContext::reshape):
+ (WebCore::WebGLRenderingContext::texImage2D):
+ (WebCore::WebGLRenderingContext::texSubImage2D):
+ * html/canvas/WebGLRenderingContext.h:
+ (WebCore::WebGLRenderingContext::paintsIntoCanvasBuffer):
+ * platform/graphics/GeneratedImage.cpp:
+ (WebCore::GeneratedImage::drawPattern):
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContext::drawImageBuffer):
+ (WebCore::GraphicsContext::clipToImageBuffer):
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/GraphicsContext3D.h:
+ (WebCore::GraphicsContext3D::paintsIntoCanvasBuffer):
+ * platform/graphics/Image.h:
+ * platform/graphics/ImageBuffer.h:
+ (WebCore::ImageBuffer::width):
+ (WebCore::ImageBuffer::height):
+ * platform/graphics/Pattern.cpp:
+ (WebCore::Pattern::Pattern):
+ * platform/graphics/Pattern.h:
+ (WebCore::Pattern::create):
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ * platform/graphics/cairo/ImageBufferCairo.cpp:
+ (WebCore::ImageBuffer::drawsUsingCopy):
+ (WebCore::ImageBuffer::copyImage):
+ (WebCore::ImageBuffer::clip):
+ (WebCore::ImageBuffer::draw):
+ (WebCore::ImageBuffer::drawPattern):
+ * platform/graphics/cg/GraphicsContextCG.cpp:
+ * platform/graphics/cg/ImageBufferCG.cpp:
+ (WebCore::ImageBuffer::ImageBuffer):
+ (WebCore::ImageBuffer::drawsUsingCopy):
+ (WebCore::ImageBuffer::copyImage):
+ (WebCore::ImageBuffer::draw):
+ (WebCore::ImageBuffer::drawPattern):
+ (WebCore::ImageBuffer::clip):
+ * platform/graphics/cg/ImageBufferData.h:
+ * platform/graphics/filters/FEColorMatrix.cpp:
+ (WebCore::FEColorMatrix::apply):
+ * platform/graphics/filters/FEComposite.cpp:
+ (WebCore::FEComposite::apply):
+ * platform/graphics/filters/SourceAlpha.cpp:
+ (WebCore::SourceAlpha::apply):
+ * platform/graphics/filters/SourceGraphic.cpp:
+ (WebCore::SourceGraphic::apply):
+ * platform/graphics/mac/GraphicsContext3DMac.mm:
+ * platform/graphics/qt/GraphicsContext3DQt.cpp:
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ * platform/graphics/qt/ImageBufferData.h:
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBufferData::ImageBufferData):
+ (WebCore::ImageBuffer::drawsUsingCopy):
+ (WebCore::ImageBuffer::copyImage):
+ (WebCore::ImageBuffer::draw):
+ (WebCore::ImageBuffer::drawPattern):
+ (WebCore::ImageBuffer::clip):
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::drawsUsingCopy):
+ (WebCore::ImageBuffer::copyImage):
+ (WebCore::ImageBuffer::clip):
+ (WebCore::):
+ * platform/graphics/wx/GraphicsContextWx.cpp:
+ * platform/graphics/wx/ImageBufferWx.cpp:
+ (WebCore::ImageBuffer::drawsUsingCopy):
+ (WebCore::ImageBuffer::copyImage):
+ (WebCore::ImageBuffer::clip):
+ (WebCore::ImageBuffer::draw):
+ (WebCore::ImageBuffer::drawPattern):
+ * platform/mac/ScrollbarThemeMac.mm:
+ (WebCore::ScrollbarThemeMac::paint):
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+ * rendering/RenderSVGResourceClipper.cpp:
+ (WebCore::RenderSVGResourceClipper::applyClippingToContext):
+ * rendering/RenderSVGResourceFilter.cpp:
+ (WebCore::RenderSVGResourceFilter::postApplyResource):
+ * rendering/RenderSVGResourceGradient.cpp:
+ (WebCore::clipToTextMask):
+ * rendering/RenderSVGResourceMasker.cpp:
+ (WebCore::RenderSVGResourceMasker::applyResource):
+ * rendering/RenderSVGResourcePattern.cpp:
+ (WebCore::RenderSVGResourcePattern::buildPattern):
+ * rendering/RenderThemeMac.mm:
+ (WebCore::RenderThemeMac::paintProgressBar):
+ * svg/SVGFEImageElement.cpp:
+ (WebCore::SVGFEImageElement::build):
+ * svg/graphics/SVGImage.cpp:
+ (WebCore::SVGImage::nativeImageForCurrentFrame):
+ * svg/graphics/SVGImage.h:
+ * svg/graphics/filters/SVGFEMerge.cpp:
+ (WebCore::FEMerge::apply):
+ * svg/graphics/filters/SVGFEOffset.cpp:
+ (WebCore::FEOffset::apply):
+ * svg/graphics/filters/SVGFETile.cpp:
+ (WebCore::FETile::apply):
+
2010-08-16 Paul Sawaya <psawaya at apple.com>
Reviewed by Chris Marrin.
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index e98543f..02834d4 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -4040,7 +4040,7 @@
B2A015A90AF6CD53006BCE0E /* GraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A015930AF6CD53006BCE0E /* GraphicsContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2A015AA0AF6CD53006BCE0E /* GraphicsTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2A015940AF6CD53006BCE0E /* GraphicsTypes.cpp */; };
B2A015AB0AF6CD53006BCE0E /* GraphicsTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A015950AF6CD53006BCE0E /* GraphicsTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
- B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A10B910B3818BD00099AA4 /* ImageBuffer.h */; };
+ B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A10B910B3818BD00099AA4 /* ImageBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2A10B940B3818D700099AA4 /* ImageBufferCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2A10B930B3818D700099AA4 /* ImageBufferCG.cpp */; };
B2A1F2AA0CEF0ABF00442F6A /* SVGFontElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2A1F2A10CEF0ABF00442F6A /* SVGFontElement.cpp */; };
B2A1F2AB0CEF0ABF00442F6A /* SVGFontElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A1F2A20CEF0ABF00442F6A /* SVGFontElement.h */; };
@@ -4772,6 +4772,7 @@
BCA8C83111E3D53200812FB7 /* BackForwardControllerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA8C83011E3D53200812FB7 /* BackForwardControllerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCA8CA5F11E4E6D100812FB7 /* BackForwardListImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA8CA5D11E4E6D100812FB7 /* BackForwardListImpl.cpp */; };
BCA8CA6011E4E6D100812FB7 /* BackForwardListImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA8CA5E11E4E6D100812FB7 /* BackForwardListImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BCA979171215D055005C485C /* ImageBufferData.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA979161215D055005C485C /* ImageBufferData.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCAA90C30A7EBA60008B1229 /* Scrollbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCAA90C20A7EBA60008B1229 /* Scrollbar.cpp */; };
BCACF3BC1072921A00C0C8A3 /* UserContentURLPattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCACF3BA1072921A00C0C8A3 /* UserContentURLPattern.cpp */; };
BCACF3BD1072921A00C0C8A3 /* UserContentURLPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = BCACF3BB1072921A00C0C8A3 /* UserContentURLPattern.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -10526,6 +10527,7 @@
BCA8C83011E3D53200812FB7 /* BackForwardControllerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardControllerClient.h; sourceTree = "<group>"; };
BCA8CA5D11E4E6D100812FB7 /* BackForwardListImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackForwardListImpl.cpp; sourceTree = "<group>"; };
BCA8CA5E11E4E6D100812FB7 /* BackForwardListImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardListImpl.h; sourceTree = "<group>"; };
+ BCA979161215D055005C485C /* ImageBufferData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferData.h; sourceTree = "<group>"; };
BCAA90C20A7EBA60008B1229 /* Scrollbar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Scrollbar.cpp; path = platform/Scrollbar.cpp; sourceTree = SOURCE_ROOT; };
BCACF3BA1072921A00C0C8A3 /* UserContentURLPattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserContentURLPattern.cpp; sourceTree = "<group>"; };
BCACF3BB1072921A00C0C8A3 /* UserContentURLPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserContentURLPattern.h; sourceTree = "<group>"; };
@@ -15615,6 +15617,7 @@
B2ED97700B1F55CE00257D0F /* GraphicsContextCG.cpp */,
A80D67070E9E9DEB00E420F0 /* GraphicsContextPlatformPrivateCG.h */,
B2A10B930B3818D700099AA4 /* ImageBufferCG.cpp */,
+ BCA979161215D055005C485C /* ImageBufferData.h */,
B27535300B053814002CE64F /* ImageCG.cpp */,
B27535310B053814002CE64F /* ImageSourceCG.cpp */,
4B3480920EEF50D400AC1B41 /* ImageSourceCG.h */,
@@ -20188,6 +20191,7 @@
97DD4D870FDF4D6E00ECF9A4 /* XSSAuditor.h in Headers */,
CE172E011136E8CE0062A533 /* ZoomMode.h in Headers */,
C50B561712119D23008B46E0 /* GroupSettings.h in Headers */,
+ BCA979171215D055005C485C /* ImageBufferData.h in Headers */,
490707E71219C04300D90E51 /* ANGLEWebKitBridge.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -20248,7 +20252,6 @@
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
compatibilityVersion = "Xcode 2.4";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
diff --git a/WebCore/css/CSSCanvasValue.cpp b/WebCore/css/CSSCanvasValue.cpp
index 0c1c3f9..767c11e 100644
--- a/WebCore/css/CSSCanvasValue.cpp
+++ b/WebCore/css/CSSCanvasValue.cpp
@@ -90,7 +90,7 @@ Image* CSSCanvasValue::image(RenderObject* renderer, const IntSize& /*size*/)
HTMLCanvasElement* elt = element(renderer->document());
if (!elt || !elt->buffer())
return 0;
- return elt->buffer()->image();
+ return elt->copiedImage();
}
} // namespace WebCore
diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp
index 3629776..84ab227 100644
--- a/WebCore/html/HTMLCanvasElement.cpp
+++ b/WebCore/html/HTMLCanvasElement.cpp
@@ -209,8 +209,7 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
void HTMLCanvasElement::willDraw(const FloatRect& rect)
{
- if (m_imageBuffer)
- m_imageBuffer->clearImage();
+ m_copiedImage.clear(); // Clear our image snapshot if we have one.
if (RenderBox* ro = renderBox()) {
FloatRect destRect = ro->contentBoxRect();
@@ -242,10 +241,10 @@ void HTMLCanvasElement::reset()
h = DefaultHeight;
IntSize oldSize = size();
- setSurfaceSize(IntSize(w, h));
+ setSurfaceSize(IntSize(w, h)); // The image buffer gets cleared here.
#if ENABLE(3D_CANVAS)
- if (m_context && m_context->is3d())
+ if (m_context && m_context->is3d() && oldSize != size())
static_cast<WebGLRenderingContext*>(m_context.get())->reshape(width(), height());
#endif
@@ -277,23 +276,21 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const IntRect& r)
WebGLRenderingContext* context3D = 0;
if (m_context && m_context->is3d()) {
context3D = static_cast<WebGLRenderingContext*>(m_context.get());
- context3D->beginPaint();
+ if (!context3D->paintsIntoCanvasBuffer())
+ return;
+ context3D->paintRenderingResultsToCanvas();
}
#endif
if (hasCreatedImageBuffer()) {
ImageBuffer* imageBuffer = buffer();
if (imageBuffer) {
- Image* image = imageBuffer->imageForRendering();
- if (image)
- context->drawImage(image, DeviceColorSpace, r);
+ if (imageBuffer->drawsUsingCopy())
+ context->drawImage(copiedImage(), DeviceColorSpace, r);
+ else
+ context->drawImageBuffer(imageBuffer, DeviceColorSpace, r);
}
}
-
-#if ENABLE(3D_CANVAS)
- if (context3D)
- context3D->endPaint();
-#endif
}
#if ENABLE(3D_CANVAS)
@@ -325,6 +322,7 @@ void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
m_size = size;
m_hasCreatedImageBuffer = false;
m_imageBuffer.clear();
+ m_copiedImage.clear();
}
String HTMLCanvasElement::toDataURL(const String& mimeType, const double* quality, ExceptionCode& ec)
@@ -420,6 +418,18 @@ ImageBuffer* HTMLCanvasElement::buffer() const
return m_imageBuffer.get();
}
+Image* HTMLCanvasElement::copiedImage() const
+{
+ if (!m_copiedImage && buffer())
+ m_copiedImage = buffer()->copyImage();
+ return m_copiedImage.get();
+}
+
+void HTMLCanvasElement::clearCopiedImage()
+{
+ m_copiedImage.clear();
+}
+
AffineTransform HTMLCanvasElement::baseTransform() const
{
ASSERT(m_hasCreatedImageBuffer);
diff --git a/WebCore/html/HTMLCanvasElement.h b/WebCore/html/HTMLCanvasElement.h
index b222007..a52cc9c 100644
--- a/WebCore/html/HTMLCanvasElement.h
+++ b/WebCore/html/HTMLCanvasElement.h
@@ -38,6 +38,7 @@ class CanvasContextAttributes;
class CanvasRenderingContext;
class GraphicsContext;
class HTMLCanvasElement;
+class Image;
class ImageBuffer;
class IntSize;
@@ -93,6 +94,8 @@ public:
CanvasRenderingContext* renderingContext() const { return m_context.get(); }
ImageBuffer* buffer() const;
+ Image* copiedImage() const;
+ void clearCopiedImage();
IntRect convertLogicalToDevice(const FloatRect&) const;
IntSize convertLogicalToDevice(const FloatSize&) const;
@@ -149,6 +152,8 @@ private:
// m_createdImageBuffer means we tried to malloc the buffer. We didn't necessarily get it.
mutable bool m_hasCreatedImageBuffer;
mutable OwnPtr<ImageBuffer> m_imageBuffer;
+
+ mutable RefPtr<Image> m_copiedImage; // FIXME: This is temporary for platforms that have to copy the image buffer to render (and for CSSCanvasValue).
};
} //namespace
diff --git a/WebCore/html/canvas/CanvasPattern.cpp b/WebCore/html/canvas/CanvasPattern.cpp
index 62a4620..818d7d3 100644
--- a/WebCore/html/canvas/CanvasPattern.cpp
+++ b/WebCore/html/canvas/CanvasPattern.cpp
@@ -57,7 +57,7 @@ void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool&
ec = SYNTAX_ERR;
}
-CanvasPattern::CanvasPattern(Image* image, bool repeatX, bool repeatY, bool originClean)
+CanvasPattern::CanvasPattern(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
: m_pattern(Pattern::create(image, repeatX, repeatY))
, m_originClean(originClean)
{
diff --git a/WebCore/html/canvas/CanvasPattern.h b/WebCore/html/canvas/CanvasPattern.h
index 91e0794..58848a9 100644
--- a/WebCore/html/canvas/CanvasPattern.h
+++ b/WebCore/html/canvas/CanvasPattern.h
@@ -41,7 +41,7 @@ namespace WebCore {
public:
static void parseRepetitionType(const String&, bool& repeatX, bool& repeatY, ExceptionCode&);
- static PassRefPtr<CanvasPattern> create(Image* image, bool repeatX, bool repeatY, bool originClean)
+ static PassRefPtr<CanvasPattern> create(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
{
return adoptRef(new CanvasPattern(image, repeatX, repeatY, originClean));
}
@@ -51,7 +51,7 @@ namespace WebCore {
bool originClean() const { return m_originClean; }
private:
- CanvasPattern(Image*, bool repeatX, bool repeatY, bool originClean);
+ CanvasPattern(PassRefPtr<Image>, bool repeatX, bool repeatY, bool originClean);
RefPtr<Pattern> m_pattern;
bool m_originClean;
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 559ddda..702b109 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -1264,7 +1264,7 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
sourceCanvas->makeRenderingResultsAvailable();
- c->drawImage(buffer->image(), DeviceColorSpace, destRect, sourceRect, state().m_globalComposite);
+ c->drawImageBuffer(buffer, DeviceColorSpace, destRect, sourceRect, state().m_globalComposite);
willDraw(destRect); // This call comes after drawImage, since the buffer we draw into may be our own, and we need to make sure it is dirty.
// FIXME: Arguably willDraw should become didDraw and occur after drawing calls and not before them to avoid problems like this.
}
@@ -1464,7 +1464,7 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElem
CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, ec);
if (ec)
return 0;
- return CanvasPattern::create(canvas->buffer()->image(), repeatX, repeatY, canvas->originClean());
+ return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
}
void CanvasRenderingContext2D::willDraw(const FloatRect& r, unsigned options)
@@ -1820,7 +1820,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
maskImageContext->drawBidiText(font, textRun, location);
c->save();
- c->clipToImageBuffer(maskRect, maskImage.get());
+ c->clipToImageBuffer(maskImage.get(), maskRect);
drawStyle->applyFillColor(c);
c->fillRect(maskRect);
c->restore();
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index b4ea464..4465833 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -158,27 +158,11 @@ void WebGLRenderingContext::markContextChanged()
void WebGLRenderingContext::paintRenderingResultsToCanvas()
{
- if (m_markedCanvasDirty) {
- // FIXME: It should not be necessary to clear the image before doing a readback.
- // Investigate why this is needed and remove if possible.
- canvas()->buffer()->clearImage();
- m_markedCanvasDirty = false;
- m_context->paintRenderingResultsToCanvas(this);
- }
-}
-
-void WebGLRenderingContext::beginPaint()
-{
- if (m_markedCanvasDirty)
- m_context->beginPaint(this);
-}
-
-void WebGLRenderingContext::endPaint()
-{
- if (m_markedCanvasDirty) {
- m_markedCanvasDirty = false;
- m_context->endPaint();
- }
+ if (!m_markedCanvasDirty)
+ return;
+ canvas()->clearCopiedImage();
+ m_markedCanvasDirty = false;
+ m_context->paintRenderingResultsToCanvas(this);
}
void WebGLRenderingContext::reshape(int width, int height)
@@ -191,7 +175,9 @@ void WebGLRenderingContext::reshape(int width, int height)
#endif
m_needsUpdate = false;
}
-
+
+ // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
+ // clear (and this matches what reshape will do).
m_context->reshape(width, height);
}
@@ -2197,7 +2183,8 @@ void WebGLRenderingContext::texImage2D(unsigned target, unsigned level, unsigned
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- texImage2DImpl(target, level, internalformat, format, type, canvas->buffer()->image(),
+
+ texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -2347,7 +2334,8 @@ void WebGLRenderingContext::texSubImage2D(unsigned target, unsigned level, unsig
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->buffer()->image(),
+
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index 6fe96b0..48fa7c8 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -279,12 +279,10 @@ public:
virtual void paintRenderingResultsToCanvas();
- // Helpers for notification about paint events.
- void beginPaint();
- void endPaint();
-
void removeObject(WebGLObject*);
+ bool paintsIntoCanvasBuffer() const { return m_context->paintsIntoCanvasBuffer(); }
+
private:
friend class WebGLObject;
diff --git a/WebCore/platform/graphics/GeneratedImage.cpp b/WebCore/platform/graphics/GeneratedImage.cpp
index cd0748e..5df2608 100644
--- a/WebCore/platform/graphics/GeneratedImage.cpp
+++ b/WebCore/platform/graphics/GeneratedImage.cpp
@@ -63,11 +63,8 @@ void GeneratedImage::drawPattern(GraphicsContext* context, const FloatRect& srcR
GraphicsContext* graphicsContext = imageBuffer->context();
graphicsContext->fillRect(FloatRect(FloatPoint(), adjustedSize), *m_generator.get());
- // Grab the final image from the image buffer.
- Image* bitmap = imageBuffer->image();
-
- // Now just call drawTiled on that image.
- bitmap->drawPattern(context, adjustedSrcRect, patternTransform, phase, styleColorSpace, compositeOp, destRect);
+ // Tile the image buffer into the context.
+ imageBuffer->drawPattern(context, adjustedSrcRect, patternTransform, phase, styleColorSpace, compositeOp, destRect);
}
}
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index c23ca1c..67a35ec 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -30,6 +30,7 @@
#include "Font.h"
#include "Generator.h"
#include "GraphicsContextPrivate.h"
+#include "ImageBuffer.h"
using namespace std;
@@ -442,6 +443,57 @@ void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, c
restore();
}
+void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntPoint& p, CompositeOperator op)
+{
+ drawImageBuffer(image, styleColorSpace, p, IntRect(0, 0, -1, -1), op);
+}
+
+void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntRect& r, CompositeOperator op, bool useLowQualityScale)
+{
+ drawImageBuffer(image, styleColorSpace, r, IntRect(0, 0, -1, -1), op, useLowQualityScale);
+}
+
+void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntPoint& dest, const IntRect& srcRect, CompositeOperator op)
+{
+ drawImageBuffer(image, styleColorSpace, IntRect(dest, srcRect.size()), srcRect, op);
+}
+
+void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, CompositeOperator op, bool useLowQualityScale)
+{
+ drawImageBuffer(image, styleColorSpace, FloatRect(dest), srcRect, op, useLowQualityScale);
+}
+
+void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op, bool useLowQualityScale)
+{
+ if (paintingDisabled() || !image)
+ return;
+
+ float tsw = src.width();
+ float tsh = src.height();
+ float tw = dest.width();
+ float th = dest.height();
+
+ if (tsw == -1)
+ tsw = image->width();
+ if (tsh == -1)
+ tsh = image->height();
+
+ if (tw == -1)
+ tw = image->width();
+ if (th == -1)
+ th = image->height();
+
+ if (useLowQualityScale) {
+ save();
+ setImageInterpolationQuality(InterpolationNone);
+ }
+
+ image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale);
+
+ if (useLowQualityScale)
+ restore();
+}
+
void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
const IntSize& bottomLeft, const IntSize& bottomRight)
{
@@ -460,6 +512,13 @@ void GraphicsContext::clipOutRoundedRect(const IntRect& rect, const IntSize& top
clipOut(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight));
}
+void GraphicsContext::clipToImageBuffer(ImageBuffer* buffer, const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+ buffer->clip(this, rect);
+}
+
int GraphicsContext::textDrawingMode()
{
return m_common->state.textDrawingMode;
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index c903ed7..5c43a4e 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -238,6 +238,13 @@ namespace WebCore {
Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
+ void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver);
+ void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
+ void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver);
+ void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
+ void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1),
+ CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
+
void setImageInterpolationQuality(InterpolationQuality);
InterpolationQuality imageInterpolationQuality() const;
@@ -248,8 +255,8 @@ namespace WebCore {
void clipOutEllipseInRect(const IntRect&);
void clipOutRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight);
void clipPath(WindRule);
- void clipToImageBuffer(const FloatRect&, const ImageBuffer*);
void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
+ void clipToImageBuffer(ImageBuffer*, const FloatRect&);
int textDrawingMode();
void setTextDrawingMode(int);
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 3c5eb50..165f197 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -720,11 +720,11 @@ public:
void paintRenderingResultsToCanvas(CanvasRenderingContext* context);
- // Helpers for notification about paint events
- void beginPaint(CanvasRenderingContext* context);
- void endPaint();
#if PLATFORM(QT)
void paint(QPainter* painter, const QRect& rect) const;
+ bool paintsIntoCanvasBuffer() const { return true; }
+#else
+ bool paintsIntoCanvasBuffer() const { return false; }
#endif
// Support for buffer creation and deletion
diff --git a/WebCore/platform/graphics/Image.h b/WebCore/platform/graphics/Image.h
index 17be9e0..5c2b715 100644
--- a/WebCore/platform/graphics/Image.h
+++ b/WebCore/platform/graphics/Image.h
@@ -150,6 +150,9 @@ public:
static PassRefPtr<Image> loadPlatformThemeIcon(const char* name, int size);
#endif
+ virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect);
+
protected:
Image(ImageObserver* = 0);
@@ -167,9 +170,6 @@ protected:
virtual bool mayFillWithSolidColor() { return false; }
virtual Color solidColor() const { return Color(); }
- virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform,
- const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect);
-
private:
RefPtr<SharedBuffer> m_data; // The encoded raw data for the image.
ImageObserver* m_imageObserver;
diff --git a/WebCore/platform/graphics/ImageBuffer.h b/WebCore/platform/graphics/ImageBuffer.h
index a54c721..3c0508e 100644
--- a/WebCore/platform/graphics/ImageBuffer.h
+++ b/WebCore/platform/graphics/ImageBuffer.h
@@ -29,6 +29,7 @@
#define ImageBuffer_h
#include "AffineTransform.h"
+#include "FloatRect.h"
#include "Image.h"
#include "IntSize.h"
#include "ImageBufferData.h"
@@ -71,16 +72,13 @@ namespace WebCore {
~ImageBuffer();
const IntSize& size() const { return m_size; }
+ int width() const { return m_size.width(); }
+ int height() const { return m_size.height(); }
+
GraphicsContext* context() const;
- Image* image() const;
-#if PLATFORM(QT)
- Image* imageForRendering() const;
-#else
- Image* imageForRendering() const { return image(); }
-#endif
-
- void clearImage() { m_image.clear(); }
+ bool drawsUsingCopy() const; // If the image buffer has to render using a copied image, it will return true.
+ PassRefPtr<Image> copyImage() const; // Return a new image that is a copy of the buffer.
PassRefPtr<ImageData> getUnmultipliedImageData(const IntRect&) const;
PassRefPtr<ImageData> getPremultipliedImageData(const IntRect&) const;
@@ -96,12 +94,23 @@ namespace WebCore {
#else
AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_size.height()); }
#endif
+
+ private:
+ void clip(GraphicsContext*, const FloatRect&) const;
+
+ // The draw method draws the contents of the buffer without copying it.
+ void draw(GraphicsContext*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1),
+ CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
+ void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect);
+ friend class GraphicsContext;
+ friend class GeneratedImage;
+
private:
ImageBufferData m_data;
IntSize m_size;
OwnPtr<GraphicsContext> m_context;
- mutable RefPtr<Image> m_image;
#if !PLATFORM(CG)
Vector<int> m_linearRgbLUT;
diff --git a/WebCore/platform/graphics/Pattern.cpp b/WebCore/platform/graphics/Pattern.cpp
index bb07307..82d0a24 100644
--- a/WebCore/platform/graphics/Pattern.cpp
+++ b/WebCore/platform/graphics/Pattern.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-Pattern::Pattern(Image* image, bool repeatX, bool repeatY)
+Pattern::Pattern(PassRefPtr<Image> image, bool repeatX, bool repeatY)
: m_tileImage(image)
, m_repeatX(repeatX)
, m_repeatY(repeatY)
@@ -39,7 +39,7 @@ Pattern::Pattern(Image* image, bool repeatX, bool repeatY)
, m_pattern(0)
#endif
{
- ASSERT(image);
+ ASSERT(m_tileImage);
}
Pattern::~Pattern()
diff --git a/WebCore/platform/graphics/Pattern.h b/WebCore/platform/graphics/Pattern.h
index 48e8d8b..e215f3d 100644
--- a/WebCore/platform/graphics/Pattern.h
+++ b/WebCore/platform/graphics/Pattern.h
@@ -29,6 +29,7 @@
#define Pattern_h
#include "AffineTransform.h"
+#include "Image.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -64,11 +65,10 @@ typedef void* PlatformPatternPtr;
namespace WebCore {
class AffineTransform;
-class Image;
class Pattern : public RefCounted<Pattern> {
public:
- static PassRefPtr<Pattern> create(Image* tileImage, bool repeatX, bool repeatY)
+ static PassRefPtr<Pattern> create(PassRefPtr<Image> tileImage, bool repeatX, bool repeatY)
{
return adoptRef(new Pattern(tileImage, repeatX, repeatY));
}
@@ -91,7 +91,7 @@ public:
bool repeatY() const { return m_repeatY; }
private:
- Pattern(Image*, bool repeatX, bool repeatY);
+ Pattern(PassRefPtr<Image>, bool repeatX, bool repeatY);
RefPtr<Image> m_tileImage;
bool m_repeatX;
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index f3fc943..8810984 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -908,14 +908,6 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
cairo_set_fill_rule(cr, savedFillRule);
}
-void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
-{
- if (paintingDisabled())
- return;
-
- notImplemented();
-}
-
void GraphicsContext::setPlatformShadow(FloatSize const& size, float, Color const&, ColorSpace)
{
// Cairo doesn't support shadows natively, they are drawn manually in the draw*
diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index 1a43e54..3826114 100644
--- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -97,26 +97,34 @@ GraphicsContext* ImageBuffer::context() const
return m_context.get();
}
-Image* ImageBuffer::image() const
+bool ImageBuffer::drawsUsingCopy() const
{
- if (!m_image) {
- // It's assumed that if image() is called, the actual rendering to the
- // GraphicsContext must be done.
- ASSERT(context());
-
- // This creates a COPY of the image and will cache that copy. This means
- // that if subsequent operations take place on the context, neither the
- // currently-returned image, nor the results of future image() calls,
- // will contain that operation.
- //
- // This seems silly, but is the way the CG port works: image() is
- // intended to be used only when rendering is "complete."
- cairo_surface_t* newsurface = copySurface(m_data.m_surface);
-
- // BitmapImage will release the passed in surface on destruction
- m_image = BitmapImage::create(newsurface);
- }
- return m_image.get();
+ return true;
+}
+
+PassRefPtr<Image> ImageBuffer::copyImage() const
+{
+ // BitmapImage will release the passed in surface on destruction
+ return BitmapImage::create(copySurface(m_data.m_surface));
+}
+
+void ImageBuffer::clip(GraphicsContext* context, const FloatRect&) const
+{
+ notImplemented();
+}
+
+void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
+ CompositeOperator op , bool useLowQualityScale)
+{
+ RefPtr<Image> imageCopy = copyImage();
+ context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+}
+
+void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
+{
+ RefPtr<Image> imageCopy = copyImage();
+ imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
}
void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index c3d4c07..e5079dc 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -753,18 +753,6 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
CGContextEOClip(context);
}
-void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
-{
- if (paintingDisabled())
- return;
-
- CGContextTranslateCTM(platformContext(), rect.x(), rect.y() + rect.height());
- CGContextScaleCTM(platformContext(), 1, -1);
- CGContextClipToMask(platformContext(), FloatRect(FloatPoint(), rect.size()), imageBuffer->image()->getCGImageRef());
- CGContextScaleCTM(platformContext(), 1, -1);
- CGContextTranslateCTM(platformContext(), -rect.x(), -rect.y() - rect.height());
-}
-
void GraphicsContext::beginTransparencyLayer(float opacity)
{
if (paintingDisabled())
diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index feb8cec..ecbcf60 100644
--- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -46,6 +46,11 @@ using namespace std;
namespace WebCore {
+static void releaseImageData(void*, const void* data, size_t)
+{
+ fastFree(const_cast<void*>(data));
+}
+
ImageBufferData::ImageBufferData(const IntSize&)
: m_data(0)
{
@@ -56,42 +61,46 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
, m_size(size)
{
success = false; // Make early return mean failure.
- unsigned bytesPerRow;
if (size.width() < 0 || size.height() < 0)
return;
- bytesPerRow = size.width();
+
+ unsigned bytesPerRow = size.width();
if (imageColorSpace != GrayScale) {
// Protect against overflow
if (bytesPerRow > 0x3FFFFFFF)
return;
bytesPerRow *= 4;
}
+ m_data.m_bytesPerRow = bytesPerRow;
+ size_t dataSize = size.height() * bytesPerRow;
if (!tryFastCalloc(size.height(), bytesPerRow).getValue(m_data.m_data))
return;
ASSERT((reinterpret_cast<size_t>(m_data.m_data) & 2) == 0);
- RetainPtr<CGColorSpaceRef> colorSpace;
switch(imageColorSpace) {
case DeviceRGB:
- colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
+ m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
break;
case GrayScale:
- colorSpace.adoptCF(CGColorSpaceCreateDeviceGray());
+ m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceGray());
break;
#if ((PLATFORM(MAC) || PLATFORM(CHROMIUM)) && !defined(BUILDING_ON_TIGER))
case LinearRGB:
- colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear));
+ m_data.m_colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear));
break;
+
#endif
default:
- colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
+ m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
break;
}
+ m_data.m_grayScale = imageColorSpace == GrayScale;
+ m_data.m_bitmapInfo = m_data.m_grayScale ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast;
RetainPtr<CGContextRef> cgContext(AdoptCF, CGBitmapContextCreate(m_data.m_data, size.width(), size.height(), 8, bytesPerRow,
- colorSpace.get(), (imageColorSpace == GrayScale) ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast));
+ m_data.m_colorSpace.get(), m_data.m_bitmapInfo));
if (!cgContext)
return;
@@ -99,11 +108,13 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
m_context->scale(FloatSize(1, -1));
m_context->translate(0, -size.height());
success = true;
+
+ // Create a live image that wraps the data.
+ m_data.m_dataProvider.adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, dataSize, releaseImageData));
}
ImageBuffer::~ImageBuffer()
{
- fastFree(m_data.m_data);
}
GraphicsContext* ImageBuffer::context() const
@@ -111,17 +122,59 @@ GraphicsContext* ImageBuffer::context() const
return m_context.get();
}
-Image* ImageBuffer::image() const
+bool ImageBuffer::drawsUsingCopy() const
+{
+ return false;
+}
+
+PassRefPtr<Image> ImageBuffer::copyImage() const
+{
+ // BitmapImage will release the passed in CGImage on destruction
+ return BitmapImage::create(CGBitmapContextCreateImage(context()->platformContext()));
+}
+
+static CGImageRef cgImage(const IntSize& size, const ImageBufferData& data)
{
- if (!m_image) {
- // It's assumed that if image() is called, the actual rendering to the
- // GraphicsContext must be done.
- ASSERT(context());
- CGImageRef cgImage = CGBitmapContextCreateImage(context()->platformContext());
- // BitmapImage will release the passed in CGImage on destruction
- m_image = BitmapImage::create(cgImage);
+ return CGImageCreate(size.width(), size.height(), 8, data.m_grayScale ? 8 : 32, data.m_bytesPerRow,
+ data.m_colorSpace.get(), data.m_bitmapInfo, data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault);
+}
+
+void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
+ CompositeOperator op, bool useLowQualityScale)
+{
+ if (destContext == context()) {
+ // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
+ RefPtr<Image> copy = copyImage();
+ destContext->drawImage(copy.get(), DeviceColorSpace, destRect, srcRect, op, useLowQualityScale);
+ } else {
+ RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data));
+ destContext->drawImage(imageForRendering.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+ }
+}
+
+void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
+{
+ if (destContext == context()) {
+ // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
+ RefPtr<Image> copy = copyImage();
+ copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
+ } else {
+ RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data));
+ imageForRendering->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
}
- return m_image.get();
+}
+
+void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
+{
+ RetainPtr<CGImageRef> image(AdoptCF, cgImage(m_size, m_data));
+
+ CGContextRef platformContext = context->platformContext();
+ CGContextTranslateCTM(platformContext, rect.x(), rect.y() + rect.height());
+ CGContextScaleCTM(platformContext, 1, -1);
+ CGContextClipToMask(platformContext, FloatRect(FloatPoint(), rect.size()), image.get());
+ CGContextScaleCTM(platformContext, 1, -1);
+ CGContextTranslateCTM(platformContext, -rect.x(), -rect.y() - rect.height());
}
template <Multiply multiplied>
diff --git a/WebCore/platform/graphics/cg/ImageBufferData.h b/WebCore/platform/graphics/cg/ImageBufferData.h
index 5e6fc4c..2f9d854 100644
--- a/WebCore/platform/graphics/cg/ImageBufferData.h
+++ b/WebCore/platform/graphics/cg/ImageBufferData.h
@@ -26,6 +26,14 @@
#ifndef ImageBufferData_h
#define ImageBufferData_h
+#include "Image.h"
+#include <wtf/RefPtr.h>
+#include <wtf/RetainPtr.h>
+
+typedef struct CGColorSpace *CGColorSpaceRef;
+typedef struct CGDataProvider *CGDataProviderRef;
+typedef uint32_t CGBitmapInfo;
+
namespace WebCore {
class IntSize;
@@ -35,6 +43,12 @@ public:
ImageBufferData(const IntSize&);
void* m_data;
+
+ RetainPtr<CGDataProviderRef> m_dataProvider;
+ CGBitmapInfo m_bitmapInfo;
+ bool m_grayScale;
+ unsigned m_bytesPerRow;
+ RetainPtr<CGColorSpaceRef> m_colorSpace;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index c5ae3b9..7718066 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -164,7 +164,7 @@ void FEColorMatrix::apply(Filter* filter)
if (!filterContext)
return;
- filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
+ filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
IntRect imageRect(IntPoint(), resultImage()->size());
PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect));
diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp
index 18df3b2..0bafc48 100644
--- a/WebCore/platform/graphics/filters/FEComposite.cpp
+++ b/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -131,26 +131,26 @@ void FEComposite::apply(Filter* filter)
FloatRect srcRect = FloatRect(0.f, 0.f, -1.f, -1.f);
switch (m_type) {
case FECOMPOSITE_OPERATOR_OVER:
- filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
- filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
+ filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
+ filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
break;
case FECOMPOSITE_OPERATOR_IN:
filterContext->save();
- filterContext->clipToImageBuffer(calculateDrawingRect(m_in2->scaledSubRegion()), m_in2->resultImage());
- filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
+ filterContext->clipToImageBuffer(m_in->resultImage(), calculateDrawingRect(m_in2->scaledSubRegion()));
+ filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
filterContext->restore();
break;
case FECOMPOSITE_OPERATOR_OUT:
- filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
- filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()), srcRect, CompositeDestinationOut);
+ filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
+ filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()), srcRect, CompositeDestinationOut);
break;
case FECOMPOSITE_OPERATOR_ATOP:
- filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
- filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeSourceAtop);
+ filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
+ filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeSourceAtop);
break;
case FECOMPOSITE_OPERATOR_XOR:
- filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
- filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeXOR);
+ filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
+ filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeXOR);
break;
case FECOMPOSITE_OPERATOR_ARITHMETIC: {
IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion());
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp
index eb23814..37b0023 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.cpp
+++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp
@@ -63,9 +63,9 @@ void SourceAlpha::apply(Filter* filter)
setIsAlphaImage(true);
- FloatRect imageRect(FloatPoint(), filter->sourceImage()->image()->size());
+ FloatRect imageRect(FloatPoint(), filter->sourceImage()->size());
filterContext->save();
- filterContext->clipToImageBuffer(imageRect, filter->sourceImage());
+ filterContext->clipToImageBuffer(filter->sourceImage(), imageRect);
filterContext->fillRect(imageRect, Color::black, DeviceColorSpace);
filterContext->restore();
}
diff --git a/WebCore/platform/graphics/filters/SourceGraphic.cpp b/WebCore/platform/graphics/filters/SourceGraphic.cpp
index a1864d6..5730d34 100644
--- a/WebCore/platform/graphics/filters/SourceGraphic.cpp
+++ b/WebCore/platform/graphics/filters/SourceGraphic.cpp
@@ -60,7 +60,7 @@ void SourceGraphic::apply(Filter* filter)
if (!filterContext)
return;
- filterContext->drawImage(filter->sourceImage()->image(), DeviceColorSpace, IntPoint());
+ filterContext->drawImageBuffer(filter->sourceImage(), DeviceColorSpace, IntPoint());
}
void SourceGraphic::dump()
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index b798832..be1d278 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -307,15 +307,6 @@ void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* co
canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
}
-void GraphicsContext3D::beginPaint(CanvasRenderingContext* context)
-{
- UNUSED_PARAM(context);
-}
-
-void GraphicsContext3D::endPaint()
-{
-}
-
bool GraphicsContext3D::isGLES2Compliant() const
{
return false;
diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index 273e2dd..d5e7b3f 100644
--- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -512,15 +512,6 @@ void GraphicsContext3D::makeContextCurrent()
m_internal->m_glWidget->makeCurrent();
}
-void GraphicsContext3D::beginPaint(CanvasRenderingContext* context)
-{
- paintRenderingResultsToCanvas();
-}
-
-void GraphicsContext3D::endPaint()
-{
-}
-
void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
{
m_internal->m_glWidget->makeCurrent();
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 059fc96..5779b96 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -1213,23 +1213,6 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
}
}
-void GraphicsContext::clipToImageBuffer(const FloatRect& floatRect, const ImageBuffer* image)
-{
- if (paintingDisabled())
- return;
-
- QPixmap* nativeImage = image->image()->nativeImageForCurrentFrame();
- if (!nativeImage)
- return;
-
- IntRect rect(floatRect);
- QPixmap alphaMask = *nativeImage;
- if (alphaMask.width() != rect.width() || alphaMask.height() != rect.height())
- alphaMask = alphaMask.scaled(rect.width(), rect.height());
-
- m_data->layers.push(new TransparencyLayer(m_data->p(), m_data->p()->transform().mapRect(rect), 1.0, alphaMask));
-}
-
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect,
int thickness)
{
diff --git a/WebCore/platform/graphics/qt/ImageBufferData.h b/WebCore/platform/graphics/qt/ImageBufferData.h
index 222dabe..aa32253 100644
--- a/WebCore/platform/graphics/qt/ImageBufferData.h
+++ b/WebCore/platform/graphics/qt/ImageBufferData.h
@@ -26,6 +26,9 @@
#ifndef ImageBufferData_h
#define ImageBufferData_h
+#include "Image.h"
+#include <wtf/RefPtr.h>
+
#include <QPainter>
#include <QPixmap>
@@ -41,6 +44,7 @@ public:
QPixmap m_pixmap;
OwnPtr<QPainter> m_painter;
+ RefPtr<Image> m_image;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index 761a4fe..ed8f07c 100644
--- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -33,6 +33,7 @@
#include "ImageData.h"
#include "MIMETypeRegistry.h"
#include "StillImageQt.h"
+#include "TransparencyLayer.h"
#include <wtf/text/CString.h>
#include <QBuffer>
@@ -74,6 +75,8 @@ ImageBufferData::ImageBufferData(const IntSize& size)
brush.setColor(Qt::black);
painter->setBrush(brush);
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
+
+ m_data.m_image = StillImage::createForRendering(&m_data.m_pixmap);
}
ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace, bool& success)
@@ -98,24 +101,50 @@ GraphicsContext* ImageBuffer::context() const
return m_context.get();
}
-Image* ImageBuffer::imageForRendering() const
+bool ImageBuffer::drawsUsingCopy() const
{
- if (!m_image)
- m_image = StillImage::createForRendering(&m_data.m_pixmap);
+ return false;
+}
- return m_image.get();
+PassRefPtr<Image> ImageBuffer::copyImage() const
+{
+ return StillImage::create(m_data.m_pixmap);
}
-Image* ImageBuffer::image() const
+void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
+ CompositeOperator op, bool useLowQualityScale)
{
- if (!m_image) {
- // It's assumed that if image() is called, the actual rendering to the
- // GraphicsContext must be done.
- ASSERT(context());
- m_image = StillImage::create(m_data.m_pixmap);
- }
+ if (destContext == context()) {
+ // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
+ RefPtr<Image> copy = copyImage();
+ destContext->drawImage(copy.get(), DeviceColorSpace, destRect, srcRect, op, useLowQualityScale);
+ } else
+ destContext->drawImage(m_data.m_image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+}
+
+void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
+{
+ if (destContext == context()) {
+ // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
+ RefPtr<Image> copy = copyImage();
+ copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
+ } else
+ m_data.m_image->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
+}
+
+void ImageBuffer::clip(GraphicsContext* context, const FloatRect& floatRect)
+{
+ QPixmap* nativeImage = m_data.m_image->nativeImageForCurrentFrame();
+ if (!nativeImage)
+ return;
+
+ IntRect rect(floatRect);
+ QPixmap alphaMask = *nativeImage;
+ if (alphaMask.width() != rect.width() || alphaMask.height() != rect.height())
+ alphaMask = alphaMask.scaled(rect.width(), rect.height());
- return m_image.get();
+ m_data->layers.push(new TransparencyLayer(m_data->p(), m_data->p()->transform().mapRect(rect), 1.0, alphaMask));
}
void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index f2a0a16..fe7f6ce 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -456,17 +456,6 @@ void GraphicsContext::clipPath(WindRule clipRule)
platformContext()->clipPathAntiAliased(path);
}
-void GraphicsContext::clipToImageBuffer(const FloatRect& rect,
- const ImageBuffer* imageBuffer)
-{
- if (paintingDisabled())
- return;
-
-#if OS(LINUX) || OS(WINDOWS)
- platformContext()->beginLayerClippedToImage(rect, imageBuffer);
-#endif
-}
-
void GraphicsContext::concatCTM(const AffineTransform& affine)
{
if (paintingDisabled())
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index eaa91ec..a63eec5 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -87,20 +87,35 @@ GraphicsContext* ImageBuffer::context() const
return m_context.get();
}
-Image* ImageBuffer::image() const
+bool ImageBuffer::drawsUsingCopy() const
{
- if (!m_image) {
- // This creates a COPY of the image and will cache that copy. This means
- // that if subsequent operations take place on the context, neither the
- // currently-returned image, nor the results of future image() calls,
- // will contain that operation.
- //
- // This seems silly, but is the way the CG port works: image() is
- // intended to be used only when rendering is "complete."
- m_image = BitmapImageSingleFrameSkia::create(
- *m_data.m_platformContext.bitmap());
- }
- return m_image.get();
+ return true;
+}
+
+PassRefPtr<Image> ImageBuffer::copyImage() const
+{
+ return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap());
+}
+
+void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
+{
+#if OS(LINUX) || OS(WINDOWS)
+ context->platformContext()->beginLayerClippedToImage(rect, this);
+#endif
+}
+
+void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
+ CompositeOperator op, bool useLowQualityScale)
+{
+ RefPtr<Image> imageCopy = copyImage();
+ context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+}
+
+void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
+{
+ RefPtr<Image> imageCopy = copyImage();
+ imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
}
void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index 4d5afd7..2428e7e 100644
--- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -378,11 +378,6 @@ void GraphicsContext::canvasClip(const Path& path)
clip(path);
}
-void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
-{
- notImplemented();
-}
-
AffineTransform GraphicsContext::getCTM() const
{
#if USE(WXGC)
diff --git a/WebCore/platform/graphics/wx/ImageBufferWx.cpp b/WebCore/platform/graphics/wx/ImageBufferWx.cpp
index 775e018..2522cbd 100644
--- a/WebCore/platform/graphics/wx/ImageBufferWx.cpp
+++ b/WebCore/platform/graphics/wx/ImageBufferWx.cpp
@@ -82,12 +82,36 @@ String ImageBuffer::toDataURL(const String&, const double*) const
return String();
}
-Image* ImageBuffer::image() const
+bool ImageBuffer::drawsUsingCopy() const
+{
+ return true;
+}
+
+PassRefPtr<Image> ImageBuffer::copyImage() const
{
notImplemented();
return 0;
}
+void ImageBuffer::clip(GraphicsContext*, const FloatRect&) const
+{
+ notImplemented();
+}
+
+void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
+ CompositeOperator op, bool useLowQualityScale)
+{
+ RefPtr<Image> imageCopy = copyImage();
+ context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+}
+
+void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
+{
+ RefPtr<Image> imageCopy = copyImage();
+ imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
+}
+
void ImageBuffer::platformTransformColorSpace(const Vector<int>&)
{
notImplemented();
diff --git a/WebCore/platform/mac/ScrollbarThemeMac.mm b/WebCore/platform/mac/ScrollbarThemeMac.mm
index 067f28f..bfa584a 100644
--- a/WebCore/platform/mac/ScrollbarThemeMac.mm
+++ b/WebCore/platform/mac/ScrollbarThemeMac.mm
@@ -396,7 +396,7 @@ bool ScrollbarThemeMac::paint(Scrollbar* scrollbar, GraphicsContext* context, co
return true;
HIThemeDrawTrack(&trackInfo, 0, imageBuffer->context()->platformContext(), kHIThemeOrientationNormal);
- context->drawImage(imageBuffer->image(), DeviceColorSpace, scrollbar->frameRect().location());
+ context->drawImageBuffer(imageBuffer.get(), DeviceColorSpace, scrollbar->frameRect().location());
}
return true;
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
index 9117ed8..78618d1 100644
--- a/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -531,7 +531,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
// The mask has been created. Now we just need to clip to it.
context->save();
- context->clipToImageBuffer(maskRect, maskImage.get());
+ context->clipToImageBuffer(maskImage.get(), maskRect);
}
StyleImage* bg = bgLayer->image();
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index 60081dd..626a880 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -173,7 +173,7 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* object, cons
if (!clipperData->clipMaskImage)
return false;
- context->clipToImageBuffer(repaintRect, clipperData->clipMaskImage.get());
+ context->clipToImageBuffer(clipperData->clipMaskImage.get(), repaintRect);
return true;
}
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
index 54abd1e..09e83f4 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.cpp
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -270,7 +270,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
#if !PLATFORM(CG)
resultImage->transformColorSpace(LinearRGB, DeviceRGB);
#endif
- context->drawImage(resultImage->image(), object->style()->colorSpace(), lastEffect->subRegion());
+ context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->subRegion());
}
}
diff --git a/WebCore/rendering/RenderSVGResourcePattern.cpp b/WebCore/rendering/RenderSVGResourcePattern.cpp
index 698a4d3..f4f5cf4 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.cpp
+++ b/WebCore/rendering/RenderSVGResourcePattern.cpp
@@ -297,14 +297,15 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(PatternData* p
void RenderSVGResourcePattern::buildPattern(PatternData* patternData, PassOwnPtr<ImageBuffer> tileImage) const
{
- if (!tileImage->image()) {
+ RefPtr<Image> copiedImage = tileImage->copyImage();
+ if (!copiedImage) {
patternData->pattern = 0;
return;
}
-
- IntRect tileRect = tileImage->image()->rect();
+
+ IntRect tileRect = copiedImage->rect();
if (tileRect.width() <= patternData->boundaries.width() && tileRect.height() <= patternData->boundaries.height()) {
- patternData->pattern = Pattern::create(tileImage->image(), true, true);
+ patternData->pattern = Pattern::create(copiedImage, true, true);
return;
}
@@ -330,13 +331,13 @@ void RenderSVGResourcePattern::buildPattern(PatternData* patternData, PassOwnPtr
newTileImageContext->translate(0, patternData->boundaries.height());
for (int j = numX; j > 0; --j) {
newTileImageContext->translate(patternData->boundaries.width(), 0);
- newTileImageContext->drawImage(tileImage->image(), style()->colorSpace(), tileRect, tileRect);
+ newTileImageContext->drawImage(copiedImage.get(), style()->colorSpace(), tileRect, tileRect);
}
newTileImageContext->translate(-patternData->boundaries.width() * numX, 0);
}
newTileImageContext->restore();
- patternData->pattern = Pattern::create(newTileImage->image(), true, true);
+ patternData->pattern = Pattern::create(newTileImage->copyImage(), true, true);
}
}
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index cc2ff1f..7982834 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -963,7 +963,8 @@ bool RenderThemeMac::paintProgressBar(RenderObject* renderObject, const PaintInf
paintInfo.context->translate(2 * rect.x() + rect.width(), 0);
paintInfo.context->scale(FloatSize(-1, 1));
}
- paintInfo.context->drawImage(imageBuffer->image(), DeviceColorSpace, rect.location());
+
+ paintInfo.context->drawImageBuffer(imageBuffer.get(), DeviceColorSpace, rect.location());
paintInfo.context->restore();
return false;
diff --git a/WebCore/rendering/SVGImageBufferTools.cpp b/WebCore/rendering/SVGImageBufferTools.cpp
index 30b6bd2..5b45ccc 100644
--- a/WebCore/rendering/SVGImageBufferTools.cpp
+++ b/WebCore/rendering/SVGImageBufferTools.cpp
@@ -64,7 +64,7 @@ void SVGImageBufferTools::clipToImageBuffer(GraphicsContext* context, const Affi
// The mask image has been created in the device coordinate space, as the image should not be scaled.
// So the actual masking process has to be done in the device coordinate space as well.
context->concatCTM(absoluteTransform.inverse());
- context->clipToImageBuffer(absoluteTargetRect, imageBuffer);
+ context->clipToImageBuffer(imageBuffer, absoluteTargetRect);
context->concatCTM(absoluteTransform);
}
diff --git a/WebCore/svg/SVGFEImageElement.cpp b/WebCore/svg/SVGFEImageElement.cpp
index f481892..92534e8 100644
--- a/WebCore/svg/SVGFEImageElement.cpp
+++ b/WebCore/svg/SVGFEImageElement.cpp
@@ -137,7 +137,7 @@ PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*)
SVGRenderSupport::renderSubtreeToImage(m_targetImage.get(), renderer);
}
- return FEImage::create(m_targetImage ? m_targetImage->image() : m_cachedImage->image(), preserveAspectRatio());
+ return FEImage::create(m_targetImage ? m_targetImage->copyImage() : m_cachedImage->image(), preserveAspectRatio());
}
void SVGFEImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
diff --git a/WebCore/svg/graphics/SVGImage.cpp b/WebCore/svg/graphics/SVGImage.cpp
index 990e41f..6608c9e 100644
--- a/WebCore/svg/graphics/SVGImage.cpp
+++ b/WebCore/svg/graphics/SVGImage.cpp
@@ -221,12 +221,13 @@ NativeImagePtr SVGImage::nativeImageForCurrentFrame()
if (!m_frameCache) {
if (!m_page)
return 0;
- m_frameCache = ImageBuffer::create(size());
- if (!m_frameCache) // failed to allocate image
+ OwnPtr<ImageBuffer> buffer = ImageBuffer::create(size());
+ if (!buffer) // failed to allocate image
return 0;
- draw(m_frameCache->context(), rect(), rect(), DeviceColorSpace, CompositeSourceOver);
+ draw(buffer->context(), rect(), rect(), DeviceColorSpace, CompositeSourceOver);
+ m_frameCache = buffer->copyImage();
}
- return m_frameCache->image()->nativeImageForCurrentFrame();
+ return m_frameCache->nativeImageForCurrentFrame();
}
bool SVGImage::dataChanged(bool allDataReceived)
diff --git a/WebCore/svg/graphics/SVGImage.h b/WebCore/svg/graphics/SVGImage.h
index 1936626..01eae71 100644
--- a/WebCore/svg/graphics/SVGImage.h
+++ b/WebCore/svg/graphics/SVGImage.h
@@ -33,7 +33,6 @@
namespace WebCore {
- class ImageBuffer;
class Page;
class SVGImageChromeClient;
@@ -72,7 +71,7 @@ namespace WebCore {
OwnPtr<SVGImageChromeClient> m_chromeClient;
OwnPtr<Page> m_page;
- OwnPtr<ImageBuffer> m_frameCache;
+ RefPtr<Image> m_frameCache;
};
}
diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.cpp b/WebCore/svg/graphics/filters/SVGFEMerge.cpp
index 649f670..11c7407 100644
--- a/WebCore/svg/graphics/filters/SVGFEMerge.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEMerge.cpp
@@ -79,7 +79,7 @@ void FEMerge::apply(Filter* filter)
for (unsigned i = 0; i < m_mergeInputs.size(); i++) {
FloatRect destRect = calculateDrawingRect(m_mergeInputs[i]->scaledSubRegion());
- filterContext->drawImage(m_mergeInputs[i]->resultImage()->image(), DeviceColorSpace, destRect);
+ filterContext->drawImageBuffer(m_mergeInputs[i]->resultImage(), DeviceColorSpace, destRect);
}
}
diff --git a/WebCore/svg/graphics/filters/SVGFEOffset.cpp b/WebCore/svg/graphics/filters/SVGFEOffset.cpp
index f6c1a3c..e12b8e0 100644
--- a/WebCore/svg/graphics/filters/SVGFEOffset.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEOffset.cpp
@@ -91,7 +91,7 @@ void FEOffset::apply(Filter* filter)
m_in->scaledSubRegion().width(),
m_in->scaledSubRegion().height());
- filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, dstRect);
+ filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, dstRect);
}
void FEOffset::dump()
diff --git a/WebCore/svg/graphics/filters/SVGFETile.cpp b/WebCore/svg/graphics/filters/SVGFETile.cpp
index fc172ee..56cbc1e 100644
--- a/WebCore/svg/graphics/filters/SVGFETile.cpp
+++ b/WebCore/svg/graphics/filters/SVGFETile.cpp
@@ -72,8 +72,8 @@ void FETile::apply(Filter* filter)
OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(tileRect.size());
GraphicsContext* tileImageContext = tileImage->context();
- tileImageContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, IntPoint());
- RefPtr<Pattern> pattern = Pattern::create(tileImage->image(), true, true);
+ tileImageContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, IntPoint());
+ RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true);
AffineTransform matrix;
matrix.translate(m_in->scaledSubRegion().x() - scaledSubRegion().x(), m_in->scaledSubRegion().y() - scaledSubRegion().y());
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list