diff options
author | Ben Murdoch <benm@google.com> | 2011-05-13 16:23:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-16 11:35:02 +0100 |
commit | 65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch) | |
tree | f478babb801e720de7bfaee23443ffe029f58731 /Source/WebCore/platform/graphics | |
parent | 47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff) | |
download | external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2 |
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebCore/platform/graphics')
76 files changed, 655 insertions, 1443 deletions
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp index b8a6859..c9c1f63 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.cpp +++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp @@ -30,6 +30,7 @@ #include "Font.h" #include "Generator.h" #include "ImageBuffer.h" +#include "IntRect.h" using namespace std; diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h index d72cba1..a648680 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.h +++ b/Source/WebCore/platform/graphics/GraphicsContext.h @@ -32,10 +32,8 @@ #include "FloatRect.h" #include "Gradient.h" #include "Image.h" -#include "IntRect.h" #include "Path.h" #include "Pattern.h" -#include "TextDirection.h" #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> @@ -129,6 +127,7 @@ namespace WebCore { class Generator; class GraphicsContextPlatformPrivate; class ImageBuffer; + class IntRect; class KURL; class SharedGraphicsContext3D; class TextRun; diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp index 1224bce..f7c5a66 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp +++ b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp @@ -33,6 +33,7 @@ #include "ArrayBufferView.h" #include "CheckedInt.h" #include "DrawingBuffer.h" +#include "Extensions3D.h" #include "Image.h" #include "ImageData.h" @@ -43,62 +44,6 @@ namespace WebCore { namespace { - unsigned int bytesPerComponent(GC3Denum type) - { - switch (type) { - case GraphicsContext3D::UNSIGNED_BYTE: - return 1; - case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: - case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: - case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: - return 2; - case GraphicsContext3D::FLOAT: - return 4; - default: - return 1; - } - } - - unsigned int componentsPerPixel(GC3Denum format, GC3Denum type) - { - switch (type) { - case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: - case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: - case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: - case GraphicsContext3D::FLOAT: - return 1; - default: - break; - } - switch (format) { - case GraphicsContext3D::ALPHA: - case GraphicsContext3D::LUMINANCE: - return 1; - case GraphicsContext3D::LUMINANCE_ALPHA: - return 2; - case GraphicsContext3D::RGB: - return 3; - case GraphicsContext3D::RGBA: - return 4; - default: - return 4; - } - } - - // This function should only be called if width and height is non-zero and - // format/type are valid. Return 0 if overflow happens. - unsigned int imageSizeInBytes(GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type) - { - ASSERT(width > 0 && height > 0); - CheckedInt<uint32_t> checkedWidth(width); - CheckedInt<uint32_t> checkedHeight(height); - CheckedInt<uint32_t> checkedBytesPerPixel(bytesPerComponent(type) * componentsPerPixel(format, type)); - CheckedInt<uint32_t> checkedSize = checkedWidth * checkedHeight * checkedBytesPerPixel; - if (checkedSize.valid()) - return checkedSize.value(); - return 0; - } - uint8_t convertColor16LittleTo8(uint16_t value) { return value >> 8; @@ -117,17 +62,19 @@ PassRefPtr<DrawingBuffer> GraphicsContext3D::createDrawingBuffer(const IntSize& return DrawingBuffer::create(this, size); } -bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type) +bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint unpackAlignment) { + ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); OwnArrayPtr<unsigned char> zero; if (width > 0 && height > 0) { - unsigned int size = imageSizeInBytes(width, height, format, type); - if (!size) { - synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + unsigned int size; + GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, 0); + if (error != GraphicsContext3D::NO_ERROR) { + synthesizeGLError(error); return false; } zero = adoptArrayPtr(new unsigned char[size]); - if (!zero.get()) { + if (!zero) { synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return false; } @@ -155,6 +102,7 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, *componentsPerPixel = 3; break; case GraphicsContext3D::RGBA: + case Extensions3D::BGRA_EXT: // GL_EXT_texture_format_BGRA8888 *componentsPerPixel = 4; break; default: @@ -162,16 +110,16 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, } switch (type) { case GraphicsContext3D::UNSIGNED_BYTE: - *bytesPerComponent = sizeof(unsigned char); + *bytesPerComponent = sizeof(GC3Dubyte); break; case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: *componentsPerPixel = 1; - *bytesPerComponent = sizeof(unsigned short); + *bytesPerComponent = sizeof(GC3Dushort); break; case GraphicsContext3D::FLOAT: // OES_texture_float - *bytesPerComponent = sizeof(float); + *bytesPerComponent = sizeof(GC3Dfloat); break; default: return false; @@ -179,6 +127,44 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, return true; } +GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum type, GC3Dsizei width, GC3Dsizei height, GC3Dint alignment, + unsigned int* imageSizeInBytes, unsigned int* paddingInBytes) +{ + ASSERT(imageSizeInBytes); + ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8); + if (width < 0 || height < 0) + return GraphicsContext3D::INVALID_VALUE; + unsigned int bytesPerComponent, componentsPerPixel; + if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel)) + return GraphicsContext3D::INVALID_ENUM; + if (!width || !height) { + *imageSizeInBytes = 0; + if (paddingInBytes) + *paddingInBytes = 0; + return GraphicsContext3D::NO_ERROR; + } + CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel); + checkedValue *= width; + if (!checkedValue.valid()) + return GraphicsContext3D::INVALID_VALUE; + unsigned int validRowSize = checkedValue.value(); + unsigned int padding = 0; + unsigned int residual = validRowSize % alignment; + if (residual) { + padding = alignment - residual; + checkedValue += padding; + } + // Last row needs no padding. + checkedValue *= (height - 1); + checkedValue += validRowSize; + if (!checkedValue.valid()) + return GraphicsContext3D::INVALID_VALUE; + *imageSizeInBytes = checkedValue.value(); + if (paddingInBytes) + *paddingInBytes = padding; + return GraphicsContext3D::NO_ERROR; +} + bool GraphicsContext3D::extractImageData(Image* image, GC3Denum format, GC3Denum type, diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h index a0d2778..10aa0d7 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext3D.h +++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h @@ -47,6 +47,8 @@ typedef unsigned int GC3Denum; typedef unsigned char GC3Dboolean; typedef unsigned int GC3Dbitfield; +typedef unsigned char GC3Dubyte; +typedef unsigned short GC3Dushort; typedef int GC3Dint; typedef int GC3Dsizei; typedef unsigned int GC3Duint; @@ -491,7 +493,8 @@ public: // Helper to texImage2D with pixel==0 case: pixels are initialized to 0. // Return true if no GL error is synthesized. - bool texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type); + // By default, alignment is 4, the OpenGL default setting. + bool texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint alignment = 4); bool isGLES2Compliant() const; @@ -507,6 +510,19 @@ public: unsigned int* componentsPerPixel, unsigned int* bytesPerComponent); + // Computes the image size in bytes. If paddingInBytes is not null, padding + // is also calculated in return. Returns NO_ERROR if succeed, otherwise + // return the suggested GL error indicating the cause of the failure: + // INVALID_VALUE if width/height is negative or overflow happens. + // INVALID_ENUM if format/type is illegal. + GC3Denum computeImageSizeInBytes(GC3Denum format, + GC3Denum type, + GC3Dsizei width, + GC3Dsizei height, + GC3Dint alignment, + unsigned int* imageSizeInBytes, + unsigned int* paddingInBytes); + // Extracts the contents of the given Image into the passed Vector, // packing the pixel data according to the given format and type, // and obeying the flipY, premultiplyAlpha, and ignoreGammaAndColorProfile diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.h b/Source/WebCore/platform/graphics/GraphicsLayer.h index ef3c1bc..8943f6c 100644 --- a/Source/WebCore/platform/graphics/GraphicsLayer.h +++ b/Source/WebCore/platform/graphics/GraphicsLayer.h @@ -322,6 +322,11 @@ public: // For hosting this GraphicsLayer in a native layer hierarchy. virtual PlatformLayer* platformLayer() const { return 0; } + // Change the scale at which the contents are rendered. Note that contentsScale may not return + // the same value passed to setContentsScale(), because of clamping and hysteresis. + virtual float contentsScale() const { return 1; } + virtual void setContentsScale(float) { } + void dumpLayer(TextStream&, int indent = 0, LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const; int repaintCount() const { return m_repaintCount; } diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp index 92553c5..984b7d2 100644 --- a/Source/WebCore/platform/graphics/ImageSource.cpp +++ b/Source/WebCore/platform/graphics/ImageSource.cpp @@ -130,8 +130,8 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index) if (!m_decoder) return 0; - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) + ImageFrame* buffer = m_decoder->frameBufferAtIndex(index); + if (!buffer || buffer->status() == ImageFrame::FrameEmpty) return 0; // Zero-height images can cause problems for some ports. If we have an @@ -149,8 +149,8 @@ float ImageSource::frameDurationAtIndex(size_t index) if (!m_decoder) return 0; - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) + ImageFrame* buffer = m_decoder->frameBufferAtIndex(index); + if (!buffer || buffer->status() == ImageFrame::FrameEmpty) return 0; // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. @@ -180,8 +180,8 @@ bool ImageSource::frameIsCompleteAtIndex(size_t index) if (!m_decoder) return false; - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - return buffer && buffer->status() == RGBA32Buffer::FrameComplete; + ImageFrame* buffer = m_decoder->frameBufferAtIndex(index); + return buffer && buffer->status() == ImageFrame::FrameComplete; } } diff --git a/Source/WebCore/platform/graphics/Pen.cpp b/Source/WebCore/platform/graphics/Pen.cpp deleted file mode 100644 index a3dcb86..0000000 --- a/Source/WebCore/platform/graphics/Pen.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Pen.h" - -namespace WebCore { - -Pen::Pen(const Color &color, unsigned width, PenStyle style) : m_style(style), m_width(width), m_color(color) -{ -} - -const Color &Pen::color() const -{ - return m_color; -} - -unsigned Pen::width() const -{ - return m_width; -} - -Pen::PenStyle Pen::style() const -{ - return m_style; -} - -void Pen::setColor(const Color &color) -{ - m_color = color; -} - -void Pen::setWidth(unsigned width) -{ - m_width = width; -} - -void Pen::setStyle(PenStyle style) -{ - m_style = style; -} - -bool Pen::operator==(const Pen &compareTo) const -{ - return (m_width == compareTo.m_width) && - (m_style == compareTo.m_style) && - (m_color == compareTo.m_color); -} - -bool Pen::operator!=(const Pen &compareTo) const -{ - return !(*this == compareTo); -} - -} diff --git a/Source/WebCore/platform/graphics/Pen.h b/Source/WebCore/platform/graphics/Pen.h deleted file mode 100644 index cb45a2e..0000000 --- a/Source/WebCore/platform/graphics/Pen.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2003-6 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef Pen_h -#define Pen_h - -#include "Color.h" - -#if PLATFORM(WX) -class wxPen; -#endif - -namespace WebCore { - -class Pen { -public: - enum PenStyle { - NoPen, - SolidLine, - DotLine, - DashLine - }; - - Pen(const Color &c = Color::black, unsigned w = 0, PenStyle ps = SolidLine); - - const Color &color() const; - unsigned width() const; - PenStyle style() const; - - void setColor(const Color &); - void setWidth(unsigned); - void setStyle(PenStyle); - - bool operator==(const Pen &) const; - bool operator!=(const Pen &) const; - -#if PLATFORM(WX) - Pen(const wxPen&); - operator wxPen() const; -#endif - -private: - PenStyle m_style; - unsigned m_width; - Color m_color; -}; - -} - -#endif diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp index 37385c0..b72d761 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp @@ -253,6 +253,7 @@ GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client) , m_contentsLayerPurpose(NoContentsLayer) , m_contentsLayerHasBackgroundColor(false) , m_uncommittedChanges(NoChange) + , m_contentsScale(1) { m_layer = PlatformCALayer::create(PlatformCALayer::LayerTypeWebLayer, this); @@ -857,6 +858,9 @@ void GraphicsLayerCA::commitLayerChangesBeforeSublayers() if (m_uncommittedChanges & AcceleratesDrawingChanged) updateAcceleratesDrawing(); + + if (m_uncommittedChanges & ContentsScaleChanged) + updateContentsScale(); } void GraphicsLayerCA::commitLayerChangesAfterSublayers() @@ -1897,6 +1901,44 @@ GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedProperty return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones(); } +void GraphicsLayerCA::setContentsScale(float scale) +{ + float newScale = clampedContentsScaleForScale(scale); + if (newScale == m_contentsScale) + return; + + m_contentsScale = newScale; + noteLayerPropertyChanged(ContentsScaleChanged); +} + +float GraphicsLayerCA::clampedContentsScaleForScale(float scale) const +{ + // Define some limits as a sanity check for the incoming scale value + // those too small to see. + const float maxScale = 5.0f; + const float minScale = 0.01f; + + // Avoid very slight scale changes that would be doing extra work for no benefit + const float maxAllowableDelta = 0.05f; + + // Clamp + float result = max(minScale, min(scale, maxScale)); + + // If it hasn't changed much, don't do any work + return ((fabs(result - m_contentsScale) / m_contentsScale) < maxAllowableDelta) ? m_contentsScale : result; +} + +void GraphicsLayerCA::updateContentsScale() +{ + bool needTiledLayer = requiresTiledLayer(m_size); + if (needTiledLayer != m_usingTiledLayer) + swapFromOrToTiledLayer(needTiledLayer); + + m_layer->setContentsScale(m_contentsScale); + if (drawsContent()) + m_layer->setNeedsDisplay(); +} + void GraphicsLayerCA::setDebugBackgroundColor(const Color& color) { if (color.isValid()) @@ -1950,12 +1992,11 @@ bool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer) { - if (useTiledLayer == m_usingTiledLayer) - return; - + ASSERT(useTiledLayer != m_usingTiledLayer); RefPtr<PlatformCALayer> oldLayer = m_layer; m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeWebTiledLayer : PlatformCALayer::LayerTypeWebLayer, this); + m_layer->setContentsScale(m_contentsScale); m_usingTiledLayer = useTiledLayer; @@ -2230,6 +2271,7 @@ PassRefPtr<PlatformCALayer> GraphicsLayerCA::cloneLayer(PlatformCALayer *layer, newLayer->setDoubleSided(layer->isDoubleSided()); newLayer->setOpaque(layer->isOpaque()); newLayer->setBackgroundColor(layer->backgroundColor()); + newLayer->setContentsScale(layer->contentsScale()); if (cloneLevel == IntermediateCloneLevel) { newLayer->setOpacity(layer->opacity()); diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h index 13cbdd1..2c39c0a 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h @@ -56,6 +56,9 @@ public: virtual PlatformLayer* platformLayer() const; virtual PlatformCALayer* platformCALayer() const { return primaryLayer(); } + virtual float contentsScale() const { return m_contentsScale; } + virtual void setContentsScale(float); + virtual bool setChildren(const Vector<GraphicsLayer*>&); virtual void addChild(GraphicsLayer*); virtual void addChildAtIndex(GraphicsLayer*, int index); @@ -278,6 +281,7 @@ private: void updateLayerAnimations(); void updateContentsNeedsDisplay(); void updateAcceleratesDrawing(); + void updateContentsScale(); enum StructuralLayerPurpose { NoStructuralLayer = 0, @@ -320,7 +324,8 @@ private: MaskLayerChanged = 1 << 21, ReplicatedLayerChanged = 1 << 22, ContentsNeedsDisplay = 1 << 23, - AcceleratesDrawingChanged = 1 << 24 + AcceleratesDrawingChanged = 1 << 24, + ContentsScaleChanged = 1 << 25 }; typedef unsigned LayerChangeFlags; void noteLayerPropertyChanged(LayerChangeFlags flags); @@ -391,6 +396,9 @@ private: Vector<FloatRect> m_dirtyRects; LayerChangeFlags m_uncommittedChanges; + + float clampedContentsScaleForScale(float) const; + float m_contentsScale; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h index 46f4bbf..68566b3 100644 --- a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h +++ b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h @@ -182,6 +182,9 @@ public: CFTimeInterval timeOffset() const; void setTimeOffset(CFTimeInterval); + + float contentsScale() const; + void setContentsScale(float); #if PLATFORM(WIN) && !defined(NDEBUG) void printTree() const; diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm index 28460a7..2e20c3f 100644 --- a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm +++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm @@ -723,4 +723,24 @@ void PlatformCALayer::setTimeOffset(CFTimeInterval value) END_BLOCK_OBJC_EXCEPTIONS } +float PlatformCALayer::contentsScale() const +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + return [m_layer.get() contentsScale]; +#else + return 1; +#endif +} + +void PlatformCALayer::setContentsScale(float value) +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + BEGIN_BLOCK_OBJC_EXCEPTIONS + [m_layer.get() setContentsScale:value]; + END_BLOCK_OBJC_EXCEPTIONS +#else + UNUSED_PARAM(value); +#endif +} + #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp index 919c3b3..66d0732 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp @@ -253,15 +253,8 @@ size_t PlatformCALayer::sublayerCount() const void PlatformCALayer::adoptSublayers(PlatformCALayer* source) { - // Make a list of the sublayers from source PlatformCALayerList sublayers; - size_t n = source->sublayerCount(); - CFArrayRef sourceSublayers = CACFLayerGetSublayers(source->platformLayer()); - - for (size_t i = 0; i < n; ++i) { - CACFLayerRef layer = static_cast<CACFLayerRef>(const_cast<void*>(CFArrayGetValueAtIndex(sourceSublayers, i))); - sublayers.append(platformCALayer(layer)); - } + intern(source)->getSublayers(sublayers); // Use setSublayers() because it properly nulls out the superlayer pointers. setSublayers(sublayers); @@ -586,6 +579,15 @@ void PlatformCALayer::setTimeOffset(CFTimeInterval value) setNeedsCommit(); } +float PlatformCALayer::contentsScale() const +{ + return 1; +} + +void PlatformCALayer::setContentsScale(float) +{ +} + #ifndef NDEBUG static void printIndent(int indent) { @@ -681,11 +683,11 @@ static void printLayer(const PlatformCALayer* layer, int indent) printIndent(indent + 1); fprintf(stderr, "(sublayers\n"); - CFArrayRef sublayers = CACFLayerGetSublayers(layer->platformLayer()); - for (int i = 0; i < n; ++i) { - PlatformCALayer* sublayer = PlatformCALayer::platformCALayer(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, i))); - printLayer(sublayer, indent + 2); - } + PlatformCALayerList sublayers; + intern(layer)->getSublayers(sublayers); + ASSERT(n == sublayers.size()); + for (int i = 0; i < n; ++i) + printLayer(sublayers[i].get(), indent + 2); printIndent(indent + 1); fprintf(stderr, ")\n"); diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp index 0b7eea0..cdf90db 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp @@ -210,6 +210,27 @@ void PlatformCALayerWinInternal::setSublayers(const PlatformCALayerList& list) } } +void PlatformCALayerWinInternal::getSublayers(PlatformCALayerList& list) const +{ + CFArrayRef sublayers = CACFLayerGetSublayers(owner()->platformLayer()); + if (!sublayers) { + list.clear(); + return; + } + + size_t count = CFArrayGetCount(sublayers); + + size_t layersToSkip = 0; + if (owner()->layerType() == PlatformCALayer::LayerTypeWebTiledLayer) { + // Exclude the tile parent layer. + layersToSkip = 1; + } + + list.resize(count - layersToSkip); + for (size_t arrayIndex = layersToSkip; arrayIndex < count; ++arrayIndex) + list[arrayIndex - layersToSkip] = PlatformCALayer::platformCALayer(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, arrayIndex))); +} + void PlatformCALayerWinInternal::removeAllSublayers() { CACFLayerSetSublayers(owner()->platformLayer(), 0); diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h index 1be9d26..39ef3b3 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h @@ -52,6 +52,7 @@ public: PlatformCALayer* owner() const { return m_owner; } void setSublayers(const PlatformCALayerList&); + void getSublayers(PlatformCALayerList&) const; void removeAllSublayers(); void insertSublayer(PlatformCALayer*, size_t); size_t sublayerCount() const; diff --git a/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h b/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h index 1e0a846..b90bb8c 100644 --- a/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h +++ b/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h @@ -23,6 +23,9 @@ #if PLATFORM(CAIRO) +#ifndef DrawErrorUnderline_h +#define DrawErrorUnderline_h + #include <cairo.h> // @@ -96,4 +99,6 @@ static inline void drawErrorUnderline(cairo_t* cr, double x, double y, double wi } } +#endif // DrawErrorUnderline_h + #endif diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h index 5602b6c..a0dfc8c 100644 --- a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h +++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h @@ -25,6 +25,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef GraphicsContextPlatformPrivateCairo_h +#define GraphicsContextPlatformPrivateCairo_h + #include "GraphicsContext.h" #include "ContextShadow.h" @@ -111,3 +114,4 @@ public: } // namespace WebCore +#endif // GraphicsContextPlatformPrivateCairo_h diff --git a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp index 03f1d10..0113427 100644 --- a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp @@ -5,6 +5,7 @@ 2005, 2007 Apple Inc. All Rights reserved. 2007 Alp Toker <alp@atoker.com> 2008 Dirk Schulze <krit@webkit.org> + 2011 Igalia S.L. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -143,18 +144,30 @@ void Path::addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& c controlPoint3.x(), controlPoint3.y()); } -void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool anticlockwise) +void Path::addArc(const FloatPoint& p, float r, float startAngle, float endAngle, bool anticlockwise) { // http://bugs.webkit.org/show_bug.cgi?id=16449 // cairo_arc() functions hang or crash when passed inf as radius or start/end angle - if (!isfinite(r) || !isfinite(sa) || !isfinite(ea)) + if (!isfinite(r) || !isfinite(startAngle) || !isfinite(endAngle)) return; cairo_t* cr = platformPath()->context(); - if (anticlockwise) - cairo_arc_negative(cr, p.x(), p.y(), r, sa, ea); - else - cairo_arc(cr, p.x(), p.y(), r, sa, ea); + float sweep = endAngle - startAngle; + const float twoPI = 2 * piFloat; + if ((sweep <= -twoPI || sweep >= twoPI) + && ((anticlockwise && (endAngle < startAngle)) || (!anticlockwise && (startAngle < endAngle)))) { + if (anticlockwise) + cairo_arc_negative(cr, p.x(), p.y(), r, startAngle, startAngle - twoPI); + else + cairo_arc(cr, p.x(), p.y(), r, startAngle, startAngle + twoPI); + cairo_new_sub_path(cr); + cairo_arc(cr, p.x(), p.y(), r, endAngle, endAngle); + } else { + if (anticlockwise) + cairo_arc_negative(cr, p.x(), p.y(), r, startAngle, endAngle); + else + cairo_arc(cr, p.x(), p.y(), r, startAngle, endAngle); + } } void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index acd912f..eddf735 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -546,21 +546,46 @@ void GraphicsContext::fillPath(const Path& path) CGContextRef context = platformContext(); - CGContextBeginPath(context); - CGContextAddPath(context, path.platformPath()); - if (m_state.fillGradient) { - CGContextSaveGState(context); - if (fillRule() == RULE_EVENODD) - CGContextEOClip(context); - else - CGContextClip(context); - CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform()); - m_state.fillGradient->paint(this); - CGContextRestoreGState(context); + if (hasShadow()) { + FloatRect rect = path.boundingRect(); + CGLayerRef layer = CGLayerCreateWithContext(context, CGSizeMake(rect.width(), rect.height()), 0); + CGContextRef layerContext = CGLayerGetContext(layer); + + CGContextTranslateCTM(layerContext, -rect.x(), -rect.y()); + CGContextBeginPath(layerContext); + CGContextAddPath(layerContext, path.platformPath()); + CGContextConcatCTM(layerContext, m_state.fillGradient->gradientSpaceTransform()); + + if (fillRule() == RULE_EVENODD) + CGContextEOClip(layerContext); + else + CGContextClip(layerContext); + + m_state.fillGradient->paint(layerContext); + CGContextDrawLayerAtPoint(context, CGPointMake(rect.left(), rect.top()), layer); + CGLayerRelease(layer); + } else { + CGContextBeginPath(context); + CGContextAddPath(context, path.platformPath()); + CGContextSaveGState(context); + CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform()); + + if (fillRule() == RULE_EVENODD) + CGContextEOClip(context); + else + CGContextClip(context); + + m_state.fillGradient->paint(this); + CGContextRestoreGState(context); + } + return; } + CGContextBeginPath(context); + CGContextAddPath(context, path.platformPath()); + if (m_state.fillPattern) applyFillPattern(); fillPathWithFillRule(context, fillRule()); diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h index 1d0a99f..d4fa32e 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h @@ -23,6 +23,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef GraphicsContextPlatformPrivateCG_h +#define GraphicsContextPlatformPrivateCG_h + #include <wtf/RetainPtr.h> #include <CoreGraphics/CGContext.h> @@ -84,3 +87,5 @@ public: }; } + +#endif // GraphicsContextPlatformPrivateCG_h diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp index 75a36e5..023d098 100644 --- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp @@ -54,6 +54,8 @@ using namespace std; namespace WebCore { #if USE(IOSURFACE_CANVAS_BACKING_STORE) +static const int maxIOSurfaceDimension = 4096; + static RetainPtr<IOSurfaceRef> createIOSurface(const IntSize& size) { unsigned pixelFormat = 'BGRA'; @@ -110,12 +112,15 @@ ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace imageColorSpace, Render , m_size(size) , m_accelerateRendering(renderingMode == Accelerated) { -#if !USE(IOSURFACE_CANVAS_BACKING_STORE) - ASSERT(renderingMode == Unaccelerated); -#endif success = false; // Make early return mean failure. if (size.width() < 0 || size.height() < 0) return; +#if USE(IOSURFACE_CANVAS_BACKING_STORE) + if (size.width() >= maxIOSurfaceDimension || size.height() >= maxIOSurfaceDimension) + m_accelerateRendering = false; +#else + ASSERT(renderingMode == Unaccelerated); +#endif unsigned bytesPerRow = size.width(); if (bytesPerRow > 0x3FFFFFFF) // Protect against overflow diff --git a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h index 790d620..ecd57be 100644 --- a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h +++ b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h @@ -23,6 +23,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef PDFDocumentImage_h +#define PDFDocumentImage_h + #include "Image.h" #include "FloatRect.h" @@ -76,3 +79,5 @@ namespace WebCore { } #endif // PLATFORM(CG) + +#endif // PDFDocumentImage_h diff --git a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp index b5eda93..99159e6 100644 --- a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp @@ -50,7 +50,6 @@ ComplexTextController::ComplexTextController(const TextRun& run, unsigned starti , m_startingX(startingX) , m_offsetX(m_startingX) , m_run(getNormalizedTextRun(run, m_normalizedRun, m_normalizedBuffer)) - , m_iterateBackwards(m_run.rtl()) , m_wordSpacingAdjustment(0) , m_padding(0) , m_padPerWordBreak(0) @@ -140,54 +139,33 @@ void ComplexTextController::setPadding(int padding) void ComplexTextController::reset() { - if (m_iterateBackwards) - m_indexOfNextScriptRun = m_run.length() - 1; - else - m_indexOfNextScriptRun = 0; + m_indexOfNextScriptRun = 0; m_offsetX = m_startingX; } -void ComplexTextController::setBackwardsIteration(bool isBackwards) -{ - m_iterateBackwards = isBackwards; - reset(); -} - // Advance to the next script run, returning false when the end of the // TextRun has been reached. bool ComplexTextController::nextScriptRun() { - if (m_iterateBackwards) { - // In right-to-left mode we need to render the shaped glyph backwards and - // also render the script runs themselves backwards. So given a TextRun: - // AAAAAAACTTTTTTT (A = Arabic, C = Common, T = Thai) - // we render: - // TTTTTTCAAAAAAA - // (and the glyphs in each A, C and T section are backwards too) - if (!hb_utf16_script_run_prev(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun)) - return false; - m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData; - } else { - if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun)) - return false; - - // It is actually wrong to consider script runs at all in this code. - // Other WebKit code (e.g. Mac) segments complex text just by finding - // the longest span of text covered by a single font. - // But we currently need to call hb_utf16_script_run_next anyway to fill - // in the harfbuzz data structures to e.g. pick the correct script's shaper. - // So we allow that to run first, then do a second pass over the range it - // found and take the largest subregion that stays within a single font. - m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData; - unsigned endOfRun; - for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) { - const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false).fontData; - if (nextFontData != m_currentFontData) - break; - } - m_item.item.length = endOfRun; - m_indexOfNextScriptRun = m_item.item.pos + endOfRun; + if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun)) + return false; + + // It is actually wrong to consider script runs at all in this code. + // Other WebKit code (e.g. Mac) segments complex text just by finding + // the longest span of text covered by a single font. + // But we currently need to call hb_utf16_script_run_next anyway to fill + // in the harfbuzz data structures to e.g. pick the correct script's shaper. + // So we allow that to run first, then do a second pass over the range it + // found and take the largest subregion that stays within a single font. + m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData; + unsigned endOfRun; + for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) { + const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false).fontData; + if (nextFontData != m_currentFontData) + break; } + m_item.item.length = endOfRun; + m_indexOfNextScriptRun = m_item.item.pos + endOfRun; setupFontForScriptRun(); shapeGlyphs(); @@ -273,7 +251,7 @@ void ComplexTextController::shapeGlyphs() { // HB_ShapeItem() resets m_item.num_glyphs. If the previous call to // HB_ShapeItem() used less space than was available, the capacity of - // the array may be larger than the current value of m_item.num_glyphs. + // the array may be larger than the current value of m_item.num_glyphs. // So, we need to reset the num_glyphs to the capacity of the array. m_item.num_glyphs = m_glyphsArrayCapacity; resetGlyphArrays(); @@ -291,62 +269,49 @@ void ComplexTextController::shapeGlyphs() void ComplexTextController::setGlyphXPositions(bool isRTL) { + const double rtlFlip = isRTL ? -1 : 1; double position = 0; - // logClustersIndex indexes logClusters for the first (or last when - // RTL) codepoint of the current glyph. Each time we advance a glyph, - // we skip over all the codepoints that contributed to the current - // glyph. + + // logClustersIndex indexes logClusters for the first codepoint of the current glyph. + // Each time we advance a glyph, we skip over all the codepoints that contributed to the current glyph. int logClustersIndex = 0; - if (isRTL) { - logClustersIndex = m_item.num_glyphs - 1; - - // Glyphs are stored in logical order, but for layout purposes we - // always go left to right. - for (int i = m_item.num_glyphs - 1; i >= 0; --i) { - if (!m_currentFontData->isZeroWidthSpaceGlyph(m_glyphs16[i])) { - // Whitespace must be laid out in logical order, so when inserting - // spaces in RTL (but iterating in LTR order) we must insert spaces - // _before_ the next glyph. - if (static_cast<unsigned>(i + 1) >= m_item.num_glyphs || m_item.attributes[i + 1].clusterStart) - position += m_letterSpacing; - - position += determineWordBreakSpacing(logClustersIndex); - } - - m_glyphs16[i] = m_item.glyphs[i]; - double offsetX = truncateFixedPointToInteger(m_item.offsets[i].x); - m_xPositions[i] = m_offsetX + position + offsetX; - - while (logClustersIndex > 0 && logClusters()[logClustersIndex] == i) - logClustersIndex--; - - if (!m_currentFontData->isZeroWidthSpaceGlyph(m_glyphs16[i])) - position += truncateFixedPointToInteger(m_item.advances[i]); - } - } else { - for (size_t i = 0; i < m_item.num_glyphs; ++i) { - m_glyphs16[i] = m_item.glyphs[i]; - double offsetX = truncateFixedPointToInteger(m_item.offsets[i].x); - m_xPositions[i] = m_offsetX + position + offsetX; + // Iterate through the glyphs in logical order, flipping for RTL where necessary. + // In RTL mode all variables are positive except m_xPositions, which starts from m_offsetX and runs negative. + // It is fixed up in a second pass below. + for (size_t i = 0; i < m_item.num_glyphs; ++i) { + while (static_cast<unsigned>(logClustersIndex) < m_item.item.length && logClusters()[logClustersIndex] < i) + logClustersIndex++; - if (m_currentFontData->isZeroWidthSpaceGlyph(m_glyphs16[i])) - continue; + // If the current glyph is just after a space, add in the word spacing. + position += determineWordBreakSpacing(logClustersIndex); - double advance = truncateFixedPointToInteger(m_item.advances[i]); + m_glyphs16[i] = m_item.glyphs[i]; + double offsetX = truncateFixedPointToInteger(m_item.offsets[i].x); + double advance = truncateFixedPointToInteger(m_item.advances[i]); + if (isRTL) + offsetX -= advance; - advance += determineWordBreakSpacing(logClustersIndex); + m_xPositions[i] = m_offsetX + (position * rtlFlip) + offsetX; - if (m_item.attributes[i].clusterStart) - advance += m_letterSpacing; + if (m_currentFontData->isZeroWidthSpaceGlyph(m_glyphs16[i])) + continue; - while (static_cast<unsigned>(logClustersIndex) < m_item.item.length && logClusters()[logClustersIndex] == i) - logClustersIndex++; + // At the end of each cluster, add in the letter spacing. + if (i + 1 == m_item.num_glyphs || m_item.attributes[i + 1].clusterStart) + position += m_letterSpacing; - position += advance; - } + position += advance; } - m_pixelWidth = std::max(position, 0.0); + const double width = position; + + // Now that we've computed the total width, do another pass to fix positioning for RTL. + if (isRTL) { + for (size_t i = 0; i < m_item.num_glyphs; ++i) + m_xPositions[i] += width; + } + + m_pixelWidth = std::max(width, 0.0); m_offsetX += m_pixelWidth; } diff --git a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h index 4ebbd89..e264b99 100644 --- a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h +++ b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h @@ -52,9 +52,8 @@ class SimpleFontData; // only ever done with script runs since the shapers only know how to deal with // a single script. // -// After creating it, the script runs are either iterated backwards or forwards. -// It defaults to backwards for RTL and forwards otherwise (which matches the -// presentation order), however you can set it with |setBackwardsIteration|. +// Iteration is always in logical (aka reading) order. For RTL text that means +// the rightmost part of the text will be first. // // Once you have setup the object, call |nextScriptRun| to get the first script // run. This will return false when the iteration is complete. At any time you @@ -70,7 +69,6 @@ public: // WebKit uses this to justify text. void setPadding(int); void reset(); - void setBackwardsIteration(bool); // Advance to the next script run, returning false when the end of the // TextRun has been reached. bool nextScriptRun(); @@ -148,7 +146,6 @@ private: OwnPtr<TextRun> m_normalizedRun; OwnArrayPtr<UChar> m_normalizedBuffer; // A buffer for normalized run. const TextRun& m_run; - bool m_iterateBackwards; int m_wordSpacingAdjustment; // delta adjustment (pixels) for each word break. float m_padding; // pixels to be distributed over the line at word breaks. float m_padPerWordBreak; // pixels to be added to each word break. diff --git a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp index 507c227..569dff4 100644 --- a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp @@ -67,9 +67,14 @@ static unsigned generateColorTexture(GraphicsContext3D* context, const IntSize& } -DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) +DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, + const IntSize& size, + bool multisampleExtensionSupported, + bool packedDepthStencilExtensionSupported) : m_context(context) , m_size(size) + , m_multisampleExtensionSupported(multisampleExtensionSupported) + , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported) , m_fbo(0) , m_colorBuffer(0) , m_depthStencilBuffer(0) @@ -85,6 +90,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) m_fbo = context->createFramebuffer(); context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); m_colorBuffer = generateColorTexture(context, size); + createSecondaryBuffers(); } DrawingBuffer::~DrawingBuffer() diff --git a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp index b256e70..f1eadf2 100644 --- a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp @@ -234,28 +234,21 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon return controller.widthOfFullRun(); } -static int glyphIndexForXPositionInScriptRun(const ComplexTextController& controller, int x) +static int glyphIndexForXPositionInScriptRun(const ComplexTextController& controller, int targetX) { - const HB_Fixed* advances = controller.advances(); - int letterSpacing = controller.letterSpacing(); - int glyphIndex; - if (controller.rtl()) { - for (glyphIndex = controller.length() - 1; glyphIndex >= 0; --glyphIndex) { - // When iterating LTR over RTL text, we must include the whitespace - // _before_ the glyph, so no + 1 here. - if (x < (static_cast<int>(controller.length()) - glyphIndex) * letterSpacing + truncateFixedPointToInteger(advances[glyphIndex])) - break; - x -= truncateFixedPointToInteger(advances[glyphIndex]); - } - } else { - for (glyphIndex = 0; static_cast<unsigned>(glyphIndex) < controller.length(); ++glyphIndex) { - if (x < (glyphIndex * letterSpacing + truncateFixedPointToInteger(advances[glyphIndex]))) - break; - x -= truncateFixedPointToInteger(advances[glyphIndex]); - } + // Iterate through the glyphs in logical order, seeing whether targetX falls between the previous + // position and halfway through the current glyph. + // FIXME: this code probably belongs in ComplexTextController. + int lastX = controller.rtl() ? controller.width() : 0; + for (int glyphIndex = 0; static_cast<unsigned>(glyphIndex) < controller.length(); ++glyphIndex) { + int advance = truncateFixedPointToInteger(controller.advances()[glyphIndex]); + int nextX = static_cast<int>(controller.xPositions()[glyphIndex]) + advance / 2; + if (std::min(nextX, lastX) <= targetX && targetX <= std::max(nextX, lastX)) + return glyphIndex; + lastX = nextX; } - return glyphIndex; + return controller.length() - 1; } // Return the code point index for the given |x| offset into the text run. @@ -345,20 +338,16 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int height, int from, int to) const { - int fromX = -1, toX = -1, fromAdvance = -1, toAdvance = -1; + int fromX = -1, toX = -1; ComplexTextController controller(run, 0, this); controller.setWordSpacingAdjustment(wordSpacing()); controller.setLetterSpacingAdjustment(letterSpacing()); - // Base will point to the x offset for the current script run. Note that, in + // Base will point to the x offset for the start of the current script run. Note that, in // the LTR case, width will be 0. int base = controller.rtl() ? controller.widthOfFullRun() : 0; - const int leftEdge = base; - - // We want to enumerate the script runs in code point order in the following - // code. This call also resets |controller|. - controller.setBackwardsIteration(false); + controller.reset(); while (controller.nextScriptRun() && (fromX == -1 || toX == -1)) { // ComplexTextController will helpfully accululate the x offsets for different // script runs for us. For this code, however, we always want the x offsets @@ -374,14 +363,16 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, // position. int glyph = controller.logClusters()[from]; fromX = base + controller.xPositions()[glyph]; - fromAdvance = controller.advances()[glyph]; + if (controller.rtl()) + fromX += truncateFixedPointToInteger(controller.advances()[glyph]); } else from -= controller.numCodePoints(); if (toX == -1 && to >= 0 && static_cast<unsigned>(to) < controller.numCodePoints()) { int glyph = controller.logClusters()[to]; toX = base + controller.xPositions()[glyph]; - toAdvance = controller.advances()[glyph]; + if (controller.rtl()) + toX += truncateFixedPointToInteger(controller.advances()[glyph]); } else to -= controller.numCodePoints(); @@ -390,14 +381,11 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, } // The position in question might be just after the text. - const int rightEdge = base; + const int endEdge = base; if (fromX == -1 && !from) - fromX = leftEdge; - else if (controller.rtl()) - fromX += truncateFixedPointToInteger(fromAdvance); - + fromX = endEdge; if (toX == -1 && !to) - toX = rightEdge; + toX = endEdge; ASSERT(fromX != -1 && toX != -1); diff --git a/Source/WebCore/platform/graphics/chromium/LayerTexture.h b/Source/WebCore/platform/graphics/chromium/LayerTexture.h index 312adfa..711e687 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTexture.h +++ b/Source/WebCore/platform/graphics/chromium/LayerTexture.h @@ -48,6 +48,11 @@ public: bool isValid(const IntSize&, unsigned format); bool reserve(const IntSize&, unsigned format); void unreserve(); + bool isReserved() + { + ASSERT(m_textureManager); + return m_textureManager->isProtected(m_token); + } void bindTexture(); void framebufferTexture2D(); diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp index 31649a4..b4b4a72 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp @@ -315,12 +315,18 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont IntRect sourceRect = tileContentRect(i, j); const IntPoint anchor = sourceRect.location(); sourceRect.intersect(layerRectToContentRect(tile->m_dirtyLayerRect)); + if (sourceRect.isEmpty()) + continue; // Calculate tile-space rectangle to upload into. IntRect destRect(IntPoint(sourceRect.x() - anchor.x(), sourceRect.y() - anchor.y()), sourceRect.size()); + ASSERT(destRect.x() >= 0); + ASSERT(destRect.y() >= 0); // Offset from paint rectangle to this tile's dirty rectangle. IntPoint paintOffset(sourceRect.x() - paintRect.x(), sourceRect.y() - paintRect.y()); + ASSERT(paintOffset.x() >= 0); + ASSERT(paintOffset.y() >= 0); uint8_t* pixelSource; if (paintRect.width() == sourceRect.width() && !paintOffset.x()) diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp index e8b9a12..696828f 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp @@ -124,6 +124,9 @@ bool RenderSurfaceChromium::prepareContentsTexture() if (!m_contentsTexture) m_contentsTexture = LayerTexture::create(layerRenderer()->context(), textureManager); + if (m_contentsTexture->isReserved()) + return true; + if (!m_contentsTexture->reserve(requiredSize, GraphicsContext3D::RGBA)) { m_skipsDraw = true; return false; diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp index 9579ef9..c4ad958 100644 --- a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp +++ b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp @@ -70,6 +70,11 @@ bool TextureManager::hasTexture(TextureToken token) return false; } +bool TextureManager::isProtected(TextureToken token) +{ + return token && hasTexture(token) && m_textures.get(token).isProtected; +} + void TextureManager::protectTexture(TextureToken token) { ASSERT(hasTexture(token)); diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.h b/Source/WebCore/platform/graphics/chromium/TextureManager.h index 1e850cd..4891cc7 100644 --- a/Source/WebCore/platform/graphics/chromium/TextureManager.h +++ b/Source/WebCore/platform/graphics/chromium/TextureManager.h @@ -51,6 +51,7 @@ public: void protectTexture(TextureToken); void unprotectTexture(TextureToken); + bool isProtected(TextureToken); private: TextureManager(GraphicsContext3D*, size_t memoryLimitBytes, int maxTextureSize); diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.cpp b/Source/WebCore/platform/graphics/filters/FEBlend.cpp index 7eeb128..ac68266 100644 --- a/Source/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/Source/WebCore/platform/graphics/filters/FEBlend.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "FloatPoint.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp index e0b15d1..33c4467 100644 --- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -27,6 +27,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/MathExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp index ca8e5d3..ab59332 100644 --- a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp +++ b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/MathExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.cpp b/Source/WebCore/platform/graphics/filters/FEComposite.cpp index 80cb2b2..bc7fa80 100644 --- a/Source/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/Source/WebCore/platform/graphics/filters/FEComposite.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp index b8f8aea..0483626 100644 --- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp +++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp @@ -27,6 +27,8 @@ #include "FEConvolveMatrix.h" #include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> diff --git a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp index 14d57f4..a8a825a 100644 --- a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp +++ b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp @@ -25,6 +25,8 @@ #include "FEDiffuseLighting.h" #include "LightSource.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp index b5151bf..88c87b7 100644 --- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp +++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> diff --git a/Source/WebCore/platform/graphics/filters/FEFlood.cpp b/Source/WebCore/platform/graphics/filters/FEFlood.cpp index 8bfdef8..0e0e94c 100644 --- a/Source/WebCore/platform/graphics/filters/FEFlood.cpp +++ b/Source/WebCore/platform/graphics/filters/FEFlood.cpp @@ -27,6 +27,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp index 37b5992..20fd923 100644 --- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp +++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp @@ -29,6 +29,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/MathExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/FEMerge.cpp b/Source/WebCore/platform/graphics/filters/FEMerge.cpp index 4395321..4099a96 100644 --- a/Source/WebCore/platform/graphics/filters/FEMerge.cpp +++ b/Source/WebCore/platform/graphics/filters/FEMerge.cpp @@ -26,6 +26,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp index 45c7edb..1eb554b 100644 --- a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp +++ b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp @@ -27,6 +27,8 @@ #include "FEMorphology.h" #include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/Vector.h> diff --git a/Source/WebCore/platform/graphics/filters/FEOffset.cpp b/Source/WebCore/platform/graphics/filters/FEOffset.cpp index f1d5914..99cac2d 100644 --- a/Source/WebCore/platform/graphics/filters/FEOffset.cpp +++ b/Source/WebCore/platform/graphics/filters/FEOffset.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp index d21dafd..36a6b72 100644 --- a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp +++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp @@ -25,6 +25,8 @@ #include "FESpecularLighting.h" #include "LightSource.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FETile.cpp b/Source/WebCore/platform/graphics/filters/FETile.cpp index e516c7e..1fcb71b 100644 --- a/Source/WebCore/platform/graphics/filters/FETile.cpp +++ b/Source/WebCore/platform/graphics/filters/FETile.cpp @@ -27,7 +27,9 @@ #include "Filter.h" #include "GraphicsContext.h" #include "Pattern.h" +#include "RenderTreeAsText.h" #include "SVGImageBufferTools.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp index f1a159b..068acee 100644 --- a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp +++ b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp @@ -27,6 +27,8 @@ #include "FETurbulence.h" #include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/MathExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp index 05c2a47..85154b5 100644 --- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp +++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp @@ -24,6 +24,9 @@ #if ENABLE(FILTERS) #include "FilterEffect.h" +#include "Filter.h" +#include "ImageBuffer.h" +#include "TextStream.h" #include <wtf/ByteArray.h> namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h index 2554d4b..062dd1b 100644 --- a/Source/WebCore/platform/graphics/filters/FilterEffect.h +++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h @@ -23,13 +23,10 @@ #define FilterEffect_h #if ENABLE(FILTERS) -#include "Filter.h" #include "FloatRect.h" -#include "GraphicsContext.h" -#include "ImageBuffer.h" -#include "RenderTreeAsText.h" -#include "TextStream.h" +#include "IntRect.h" +#include <wtf/ByteArray.h> #include <wtf/PassOwnPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> @@ -37,6 +34,11 @@ namespace WebCore { +class Filter; +class FilterEffect; +class ImageBuffer; +class TextStream; + typedef Vector<RefPtr<FilterEffect> > FilterEffectVector; enum FilterEffectType { diff --git a/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp b/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp index 2d2de00..45d74f5 100644 --- a/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp +++ b/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp @@ -23,9 +23,11 @@ #include "SourceAlpha.h" #include "Color.h" +#include "Filter.h" #include "GraphicsContext.h" #include "PlatformString.h" -#include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/StdLibExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp b/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp index 04082ad..8726bf3 100644 --- a/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp +++ b/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp @@ -22,9 +22,11 @@ #if ENABLE(FILTERS) #include "SourceGraphic.h" +#include "Filter.h" #include "GraphicsContext.h" #include "PlatformString.h" -#include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/StdLibExtras.h> diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp index d2415ca..c283068 100644 --- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp +++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp @@ -40,14 +40,16 @@ namespace WebCore { PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size) { - RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size)); Extensions3D* extensions = context->getExtensions(); bool multisampleSupported = extensions->supports("GL_ANGLE_framebuffer_blit") && extensions->supports("GL_ANGLE_framebuffer_multisample"); if (multisampleSupported) { extensions->ensureEnabled("GL_ANGLE_framebuffer_blit"); extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); } - drawingBuffer->m_multisampleExtensionSupported = multisampleSupported; + bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth_stencil"); + if (packedDepthStencilSupported) + extensions->ensureEnabled("GL_OES_packed_depth_stencil"); + RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size, multisampleSupported, packedDepthStencilSupported)); return (drawingBuffer->m_context) ? drawingBuffer.release() : 0; } @@ -88,6 +90,24 @@ void DrawingBuffer::clear() m_context.clear(); } +void DrawingBuffer::createSecondaryBuffers() +{ + const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes(); + + // Create the stencil and depth buffer if needed + if (!multisample() && (attributes.stencil || attributes.depth)) + m_depthStencilBuffer = m_context->createRenderbuffer(); + + // create a multisample FBO + if (multisample()) { + m_multisampleFBO = m_context->createFramebuffer(); + m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); + m_multisampleColorBuffer = m_context->createRenderbuffer(); + if (attributes.stencil || attributes.depth) + m_multisampleDepthStencilBuffer = m_context->createRenderbuffer(); + } +} + void DrawingBuffer::reset(const IntSize& newSize) { if (m_size == newSize) @@ -111,10 +131,13 @@ void DrawingBuffer::reset(const IntSize& newSize) if (attributes.stencil || attributes.depth) { // We don't allow the logic where stencil is required and depth is not. // See GraphicsContext3D constructor. - if (attributes.stencil && attributes.depth) - internalDepthStencilFormat = GraphicsContext3D::DEPTH_STENCIL; + + // FIXME: If packed depth/stencil is not supported, we should + // create separate renderbuffers for depth and stencil. + if (attributes.stencil && attributes.depth && m_packedDepthStencilExtensionSupported) + internalDepthStencilFormat = Extensions3D::DEPTH24_STENCIL8; else - internalDepthStencilFormat = GraphicsContext3D::DEPTH_COMPONENT; + internalDepthStencilFormat = GraphicsContext3D::DEPTH_COMPONENT16; } // resize multisample FBO @@ -150,7 +173,7 @@ void DrawingBuffer::reset(const IntSize& newSize) m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer); m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, internalColorFormat, m_size.width(), m_size.height(), 0, colorFormat, GraphicsContext3D::UNSIGNED_BYTE); - m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE, m_colorBuffer, 0); + m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0); m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); if (!multisample() && (attributes.stencil || attributes.depth)) { m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer); diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h index 9f79889..e0e0ee1 100644 --- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h +++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h @@ -63,6 +63,9 @@ public: // Clear all resources from this object, as well as context. Called when context is destroyed // to prevent invalid accesses to the resources. void clear(); + + // Create the depth/stencil and multisample buffers, if needed. + void createSecondaryBuffers(); // Copies the multisample color buffer to the normal color buffer and leaves m_fbo bound void commit(long x = 0, long y = 0, long width = -1, long height = -1); @@ -92,7 +95,7 @@ public: private: static PassRefPtr<DrawingBuffer> create(GraphicsContext3D*, const IntSize&); - DrawingBuffer(GraphicsContext3D*, const IntSize&); + DrawingBuffer(GraphicsContext3D*, const IntSize&, bool multisampleExtensionSupported, bool packedDepthStencilExtensionSupported); // Platform specific function called after reset() so each platform can do extra work if needed void didReset(); @@ -100,6 +103,7 @@ private: RefPtr<GraphicsContext3D> m_context; IntSize m_size; bool m_multisampleExtensionSupported; + bool m_packedDepthStencilExtensionSupported; Platform3DObject m_fbo; Platform3DObject m_colorBuffer; Platform3DObject m_depthStencilBuffer; diff --git a/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm b/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm index 89dcb9c..601454e 100644 --- a/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm +++ b/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm @@ -36,9 +36,14 @@ namespace WebCore { -DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) +DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, + const IntSize& size, + bool multisampleExtensionSupported, + bool packedDepthStencilExtensionSupported) : m_context(context) , m_size(size) + , m_multisampleExtensionSupported(multisampleExtensionSupported) + , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported) , m_fbo(context->createFramebuffer()) , m_colorBuffer(0) , m_depthStencilBuffer(0) @@ -77,21 +82,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) return; } - const GraphicsContext3D::Attributes& attributes = context->getContextAttributes(); - - // Create the stencil and depth buffer if needed - if (!multisample() && (attributes.stencil || attributes.depth)) - m_depthStencilBuffer = context->createRenderbuffer(); - - // create a multisample FBO - if (multisample()) { - m_multisampleFBO = context->createFramebuffer(); - context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); - m_multisampleColorBuffer = context->createRenderbuffer(); - if (attributes.stencil || attributes.depth) - m_multisampleDepthStencilBuffer = context->createRenderbuffer(); - } - + createSecondaryBuffers(); reset(size); } diff --git a/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp b/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp index d179601..a4b20be 100644 --- a/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp @@ -43,7 +43,8 @@ gboolean gstGWorldSyncMessageCallback(GstBus* bus, GstMessage* message, gpointer GStreamerGWorld* gstGWorld = static_cast<GStreamerGWorld*>(data); - if (gst_structure_has_name(message->structure, "prepare-xwindow-id")) + if (gst_structure_has_name(message->structure, "prepare-xwindow-id") + || gst_structure_has_name(message->structure, "have-ns-view")) gstGWorld->setWindowOverlay(message); return TRUE; } diff --git a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h index f2a3ff2..d71e6d3 100644 --- a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h +++ b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h @@ -25,6 +25,10 @@ #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +#endif + typedef struct _GstMessage GstMessage; namespace WebCore { @@ -38,13 +42,22 @@ class PlatformVideoWindow : public RefCounted<PlatformVideoWindow> { void prepareForOverlay(GstMessage*); +#if !PLATFORM(MAC) PlatformWidget window() const { return m_window; } +#else + PlatformWidget window() const { return m_window.get(); } +#endif unsigned long videoWindowId() const { return m_videoWindowId; } private: unsigned long m_videoWindowId; PlatformWidget m_videoWindow; +#if !PLATFORM(MAC) PlatformWidget m_window; +#else + RetainPtr<NSView> m_window; +#endif + }; } diff --git a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowMac.mm b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowMac.mm new file mode 100644 index 0000000..e98cf9b --- /dev/null +++ b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowMac.mm @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2011 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "PlatformVideoWindow.h" + +#if USE(GSTREAMER) + +#include <gst/gst.h> + +using namespace WebCore; + +PlatformVideoWindow::PlatformVideoWindow() +{ + m_window.adoptNS([[NSView alloc] init]); + m_videoWindowId = reinterpret_cast<unsigned long>(m_window.get()); +} + +PlatformVideoWindow::~PlatformVideoWindow() +{ + m_videoWindowId = 0; +} + +void PlatformVideoWindow::prepareForOverlay(GstMessage* message) +{ + if (gst_structure_has_name(message->structure, "have-ns-view")) { + m_videoWindow = static_cast<PlatformWidget>(g_value_get_pointer(gst_structure_get_value(message->structure, "nsview"))); + ASSERT(m_videoWindow); + [m_window.get() addSubview:m_videoWindow]; + } +} + +#endif // USE(GSTREAMER) diff --git a/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp index acd431d..4e17f94 100644 --- a/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp +++ b/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp @@ -34,7 +34,6 @@ #include "FontData.h" #include "NotImplemented.h" #include "Path.h" -#include "Pen.h" #include <wtf/text/CString.h> #include <GraphicsDefs.h> #include <Region.h> diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index e237fc0..253cd84 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -496,8 +496,17 @@ void GraphicsContext::fillPath(const Path& path) { QPainter* shadowPainter = shadow->beginShadowLayer(this, platformPath.controlPointRect()); if (shadowPainter) { - shadowPainter->setCompositionMode(QPainter::CompositionMode_Source); - shadowPainter->fillPath(platformPath, QColor(m_data->shadow.m_color)); + if (m_state.fillPattern) { + AffineTransform affine; + shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255); + shadowPainter->fillPath(platformPath, QBrush(m_state.fillPattern->createPlatformPattern(affine))); + } else if (m_state.fillGradient) { + QBrush brush(*m_state.fillGradient->platformGradient()); + brush.setTransform(m_state.fillGradient->gradientSpaceTransform()); + shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255); + shadowPainter->fillPath(platformPath, brush); + } else + shadowPainter->fillPath(platformPath, QColor(shadow->m_color)); shadow->endShadowLayer(this); } } else { diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index f31844a..75fb427 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -20,6 +20,8 @@ #include "config.h" #include "GraphicsLayerQt.h" +#if !defined(QT_NO_GRAPHICSVIEW) + #include "CurrentTime.h" #include "FloatRect.h" #include "GraphicsContext.h" @@ -1375,6 +1377,7 @@ static inline qreal applyTimingFunction(const TimingFunction* timingFunction, qr // Helper functions to safely get a value out of WebCore's AnimationValue*. +#ifndef QT_NO_ANIMATION static void webkitAnimationToQtAnimationValue(const AnimationValue* animationValue, TransformOperations& transformOperations) { transformOperations = TransformOperations(); @@ -1390,7 +1393,6 @@ static void webkitAnimationToQtAnimationValue(const AnimationValue* animationVal realValue = animationValue ? static_cast<const FloatAnimationValue*>(animationValue)->value() : 0; } -#ifndef QT_NO_ANIMATION // We put a bit of the functionality in a base class to allow casting and to save some code size. class AnimationQtBase : public QAbstractAnimation { @@ -1777,3 +1779,6 @@ void GraphicsLayerQt::resumeAnimations() } #include <GraphicsLayerQt.moc> + + +#endif // QT_NO_GRAPHICSVIEW diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h index b1692d2..8027143 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h +++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h @@ -26,6 +26,8 @@ #include "GraphicsLayer.h" #include "GraphicsLayerClient.h" +#if !defined(QT_NO_GRAPHICSVIEW) + namespace WebCore { class GraphicsLayerQtImpl; @@ -92,4 +94,5 @@ private: }; } +#endif #endif // GraphicsLayerQt_h diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp index 2bbb9ce..71352e4 100644 --- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp @@ -131,7 +131,7 @@ String ImageDecoderQt::filenameExtension() const return String(m_format.constData(), m_format.length()); }; -RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index) +ImageFrame* ImageDecoderQt::frameBufferAtIndex(size_t index) { // In case the ImageDecoderQt got recreated we don't know // yet how many images we are going to have and need to @@ -145,8 +145,8 @@ RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index) if (index >= count) return 0; - RGBA32Buffer& frame = m_frameBufferCache[index]; - if (frame.status() != RGBA32Buffer::FrameComplete && m_reader) + ImageFrame& frame = m_frameBufferCache[index]; + if (frame.status() != ImageFrame::FrameComplete && m_reader) internalReadImage(index); return &frame; } @@ -185,7 +185,7 @@ void ImageDecoderQt::internalReadImage(size_t frameIndex) // Attempt to return some memory for (int i = 0; i < m_frameBufferCache.size(); ++i) { - if (m_frameBufferCache[i].status() != RGBA32Buffer::FrameComplete) + if (m_frameBufferCache[i].status() != ImageFrame::FrameComplete) return; } @@ -211,10 +211,10 @@ bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) return false; } - // now into the RGBA32Buffer - even if the image is not - RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex]; + // now into the ImageFrame - even if the image is not + ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; buffer->setRect(m_reader->currentImageRect()); - buffer->setStatus(RGBA32Buffer::FrameComplete); + buffer->setStatus(ImageFrame::FrameComplete); buffer->setDuration(m_reader->nextImageDelay()); buffer->setPixmap(pixmap); return true; diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h index 23fb79a..bccb5be 100644 --- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h +++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h @@ -48,7 +48,7 @@ public: virtual bool isSizeAvailable(); virtual size_t frameCount(); virtual int repetitionCount() const; - virtual RGBA32Buffer* frameBufferAtIndex(size_t index); + virtual ImageFrame* frameBufferAtIndex(size_t index); virtual String filenameExtension() const; diff --git a/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/Source/WebCore/platform/graphics/qt/ImageQt.cpp index 49afd29..58f82ef 100644 --- a/Source/WebCore/platform/graphics/qt/ImageQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageQt.cpp @@ -68,6 +68,10 @@ static QPixmap loadResourcePixmap(const char *name) pixmap = QWebSettings::webGraphic(QWebSettings::DeleteButtonGraphic); else if (!qstrcmp(name, "inputSpeech")) pixmap = QWebSettings::webGraphic(QWebSettings::InputSpeechButtonGraphic); + else if (!qstrcmp(name, "searchCancelButton")) + pixmap = QWebSettings::webGraphic(QWebSettings::SearchCancelButtonGraphic); + else if (!qstrcmp(name, "searchCancelButtonPressed")) + pixmap = QWebSettings::webGraphic(QWebSettings::SearchCancelButtonPressedGraphic); return pixmap; } @@ -121,8 +125,30 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const if (!pixmap.hasAlpha() && p->compositionMode() == QPainter::CompositionMode_SourceOver) p->setCompositionMode(QPainter::CompositionMode_Source); - /* Translate the coordinates as phase is not in world matrix coordinate space but the tile rect origin is. */ QTransform transform(patternTransform); + + // If this would draw more than one scaled tile, we scale the pixmap first and then use the result to draw. + if (transform.type() == QTransform::TxScale) { + QRectF tileRectInTargetCoords = (transform * QTransform().translate(phase.x(), phase.y())).mapRect(tr); + + bool tileWillBePaintedOnlyOnce = tileRectInTargetCoords.contains(dr); + if (!tileWillBePaintedOnlyOnce) { + QSizeF scaledSize(float(pixmap.width()) * transform.m11(), float(pixmap.height()) * transform.m22()); + QPixmap scaledPixmap(scaledSize.toSize()); + if (pixmap.hasAlpha()) + scaledPixmap.fill(Qt::transparent); + { + QPainter painter(&scaledPixmap); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.setRenderHints(p->renderHints()); + painter.drawPixmap(QRect(0, 0, scaledPixmap.width(), scaledPixmap.height()), pixmap); + } + pixmap = scaledPixmap; + transform = QTransform::fromTranslate(transform.dx(), transform.dy()); + } + } + + /* Translate the coordinates as phase is not in world matrix coordinate space but the tile rect origin is. */ transform *= QTransform().translate(phase.x(), phase.y()); transform.translate(tr.x(), tr.y()); diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp index dd4b6e6..be6f732 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp @@ -108,7 +108,7 @@ MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player) , m_queuedSeek(-1) , m_preload(MediaPlayer::Auto) { - m_mediaPlayer->bind(m_videoItem); + m_mediaPlayer->setVideoOutput(m_videoItem); m_videoScene->addItem(m_videoItem); // Signal Handlers @@ -587,6 +587,22 @@ IntSize MediaPlayerPrivateQt::naturalSize() const return m_naturalSize; } +void MediaPlayerPrivateQt::removeVideoItem() +{ + m_oldNaturalSize = m_naturalSize; + m_mediaPlayer->setVideoOutput(static_cast<QGraphicsVideoItem*>(0)); + m_videoScene->removeItem(m_videoItem); +} + +void MediaPlayerPrivateQt::restoreVideoItem() +{ + m_mediaPlayer->setVideoOutput(m_videoItem); + m_videoScene->addItem(m_videoItem); + // FIXME: a qtmobility bug, need to reset the size when restore the videoitem, otherwise the size is 0 + // http://bugreports.qt.nokia.com/browse/QTMOBILITY-971 + nativeSizeChanged(QSize(m_oldNaturalSize)); +} + void MediaPlayerPrivateQt::paint(GraphicsContext* context, const IntRect& rect) { #if USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h index 93c9d1c..2621432 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h @@ -90,7 +90,7 @@ public: void paint(GraphicsContext*, const IntRect&); - bool supportsFullscreen() const { return false; } + bool supportsFullscreen() const { return true; } #if USE(ACCELERATED_COMPOSITING) #if USE(TEXTURE_MAPPER) @@ -108,6 +108,11 @@ public: #endif virtual PlatformMedia platformMedia() const; + + QMediaPlayer* mediaPlayer() const { return m_mediaPlayer; } + void removeVideoItem(); + void restoreVideoItem(); + private slots: void mediaStatusChanged(QMediaPlayer::MediaStatus); void handleError(QMediaPlayer::Error); @@ -142,6 +147,7 @@ private: IntSize m_currentSize; IntSize m_naturalSize; + IntSize m_oldNaturalSize; bool m_isVisible; bool m_isSeeking; bool m_composited; diff --git a/Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h b/Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h index 553f203..974f126 100644 --- a/Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h +++ b/Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h @@ -82,6 +82,8 @@ private: explicit BitmapImageSingleFrameSkia(const SkBitmap&); }; +FloatRect normalizeRect(const FloatRect&); + } // namespace WebCore #endif // BitmapImageSingleFrameSkia_h diff --git a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp index a9f6d3c..b65b5bd 100644 --- a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp @@ -114,11 +114,12 @@ void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con if (context->platformContext()->canAccelerate()) { DrawingBuffer* sourceDrawingBuffer = m_data.m_platformContext.gpuCanvas()->drawingBuffer(); unsigned sourceTexture = static_cast<unsigned>(sourceDrawingBuffer->platformColorBuffer()); - FloatRect destRectFlipped(destRect); - destRectFlipped.setY(destRect.y() + destRect.height()); - destRectFlipped.setHeight(-destRect.height()); + FloatRect destRectNormalized(normalizeRect(destRect)); + FloatRect srcRectFlipped(normalizeRect(srcRect)); + srcRectFlipped.setY(m_size.height() - srcRect.y()); + srcRectFlipped.setHeight(-srcRect.height()); context->platformContext()->prepareForHardwareDraw(); - context->platformContext()->gpuCanvas()->drawTexturedRect(sourceTexture, m_size, srcRect, destRectFlipped, styleColorSpace, op); + context->platformContext()->gpuCanvas()->drawTexturedRect(sourceTexture, m_size, srcRectFlipped, destRectNormalized, styleColorSpace, op); return; } m_data.m_platformContext.syncSoftwareCanvas(); diff --git a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp index c7fa6f4..91a4e4f 100644 --- a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp @@ -298,7 +298,7 @@ static void TransformDimensions(const SkMatrix& matrix, float srcWidth, float sr } // A helper method for translating negative width and height values. -static FloatRect normalizeRect(const FloatRect& rect) +FloatRect normalizeRect(const FloatRect& rect) { FloatRect norm = rect; if (norm.width() < 0) { diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp index cbe38aa..7abe2eb 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp @@ -80,6 +80,10 @@ void MediaPlayerPrivateFullscreenWindow::createWindow(HWND parentHwnd) parentHwnd, 0, WebCore::instanceHandle(), this); ASSERT(IsWindow(m_hwnd)); +#if USE(ACCELERATED_COMPOSITING) + m_layerRenderer->setHostWindow(m_hwnd); +#endif + ::SetFocus(m_hwnd); } @@ -139,17 +143,10 @@ LRESULT MediaPlayerPrivateFullscreenWindow::wndProc(HWND hWnd, UINT message, WPA switch (message) { case WM_CREATE: m_hwnd = hWnd; -#if USE(ACCELERATED_COMPOSITING) - m_layerRenderer->setHostWindow(m_hwnd); - m_layerRenderer->createRenderer(); - if (m_rootChild) - m_layerRenderer->setNeedsDisplay(); -#endif break; case WM_DESTROY: m_hwnd = 0; #if USE(ACCELERATED_COMPOSITING) - m_layerRenderer->destroyRenderer(); m_layerRenderer->setHostWindow(0); #endif break; @@ -169,7 +166,8 @@ LRESULT MediaPlayerPrivateFullscreenWindow::wndProc(HWND hWnd, UINT message, WPA break; case WM_PAINT: #if USE(ACCELERATED_COMPOSITING) - m_layerRenderer->renderSoon(); + m_layerRenderer->paint(); + ::ValidateRect(m_hwnd, 0); #endif break; } diff --git a/Source/WebCore/platform/graphics/win/WKCACFLayer.cpp b/Source/WebCore/platform/graphics/win/WKCACFLayer.cpp deleted file mode 100644 index a8714e3..0000000 --- a/Source/WebCore/platform/graphics/win/WKCACFLayer.cpp +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "WKCACFLayer.h" - -#include "WKCACFLayerRenderer.h" -#include <WebKitSystemInterface/WebKitSystemInterface.h> -#include <stdio.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -namespace WebCore { - -using namespace std; - -#ifndef NDEBUG -void WKCACFLayer::internalCheckLayerConsistency() -{ - ASSERT(layer()); - size_t n = sublayerCount(); - for (size_t i = 0; i < n; ++i) { - // This will ASSERT in internalSublayerAtIndex if this entry doesn't have proper user data - WKCACFLayer* sublayer = internalSublayerAtIndex(i); - - // Make sure we don't have any null entries in the list - ASSERT(sublayer); - - // Make sure the each layer has a corresponding CACFLayer - ASSERT(sublayer->layer()); - } -} -#endif - -static void displayCallback(CACFLayerRef layer, CGContextRef context) -{ - ASSERT_ARG(layer, WKCACFLayer::layer(layer)); - WKCACFLayer::layer(layer)->drawInContext(context); -} - -static CFStringRef toCACFLayerType(WKCACFLayer::LayerType type) -{ - switch (type) { - case WKCACFLayer::Layer: return kCACFLayer; - case WKCACFLayer::TransformLayer: return kCACFTransformLayer; - default: return 0; - } -} - -static CFStringRef toCACFContentsGravityType(WKCACFLayer::ContentsGravityType type) -{ - switch (type) { - case WKCACFLayer::Center: return kCACFGravityCenter; - case WKCACFLayer::Top: return kCACFGravityTop; - case WKCACFLayer::Bottom: return kCACFGravityBottom; - case WKCACFLayer::Left: return kCACFGravityLeft; - case WKCACFLayer::Right: return kCACFGravityRight; - case WKCACFLayer::TopLeft: return kCACFGravityTopLeft; - case WKCACFLayer::TopRight: return kCACFGravityTopRight; - case WKCACFLayer::BottomLeft: return kCACFGravityBottomLeft; - case WKCACFLayer::BottomRight: return kCACFGravityBottomRight; - case WKCACFLayer::Resize: return kCACFGravityResize; - case WKCACFLayer::ResizeAspect: return kCACFGravityResizeAspect; - case WKCACFLayer::ResizeAspectFill: return kCACFGravityResizeAspectFill; - default: return 0; - } -} - -static WKCACFLayer::ContentsGravityType fromCACFContentsGravityType(CFStringRef string) -{ - if (CFEqual(string, kCACFGravityTop)) - return WKCACFLayer::Top; - - if (CFEqual(string, kCACFGravityBottom)) - return WKCACFLayer::Bottom; - - if (CFEqual(string, kCACFGravityLeft)) - return WKCACFLayer::Left; - - if (CFEqual(string, kCACFGravityRight)) - return WKCACFLayer::Right; - - if (CFEqual(string, kCACFGravityTopLeft)) - return WKCACFLayer::TopLeft; - - if (CFEqual(string, kCACFGravityTopRight)) - return WKCACFLayer::TopRight; - - if (CFEqual(string, kCACFGravityBottomLeft)) - return WKCACFLayer::BottomLeft; - - if (CFEqual(string, kCACFGravityBottomRight)) - return WKCACFLayer::BottomRight; - - if (CFEqual(string, kCACFGravityResize)) - return WKCACFLayer::Resize; - - if (CFEqual(string, kCACFGravityResizeAspect)) - return WKCACFLayer::ResizeAspect; - - if (CFEqual(string, kCACFGravityResizeAspectFill)) - return WKCACFLayer::ResizeAspectFill; - - return WKCACFLayer::Center; -} - -static CFStringRef toCACFFilterType(WKCACFLayer::FilterType type) -{ - switch (type) { - case WKCACFLayer::Linear: return kCACFFilterLinear; - case WKCACFLayer::Nearest: return kCACFFilterNearest; - case WKCACFLayer::Trilinear: return kCACFFilterTrilinear; - default: return 0; - } -} - -static WKCACFLayer::FilterType fromCACFFilterType(CFStringRef string) -{ - if (CFEqual(string, kCACFFilterNearest)) - return WKCACFLayer::Nearest; - - if (CFEqual(string, kCACFFilterTrilinear)) - return WKCACFLayer::Trilinear; - - return WKCACFLayer::Linear; -} - -PassRefPtr<WKCACFLayer> WKCACFLayer::create(LayerType type) -{ - if (!WKCACFLayerRenderer::acceleratedCompositingAvailable()) - return 0; - return adoptRef(new WKCACFLayer(type)); -} - -// FIXME: It might be good to have a way of ensuring that all WKCACFLayers eventually -// get destroyed in debug builds. A static counter could accomplish this pretty easily. - -WKCACFLayer::WKCACFLayer(LayerType type) - : m_layer(AdoptCF, CACFLayerCreate(toCACFLayerType(type))) - , m_layoutClient(0) - , m_needsDisplayOnBoundsChange(false) -{ - CACFLayerSetUserData(layer(), this); - CACFLayerSetDisplayCallback(layer(), displayCallback); -} - -WKCACFLayer::~WKCACFLayer() -{ - // Our superlayer should be holding a reference to us, so there should be no way for us to be destroyed while we still have a superlayer. - ASSERT(!superlayer()); - - // Get rid of the children so we don't have any dangling references around - removeAllSublayers(); - -#ifndef NDEBUG - CACFLayerSetUserData(layer(), reinterpret_cast<void*>(0xDEADBEEF)); -#else - CACFLayerSetUserData(layer(), 0); -#endif - CACFLayerSetDisplayCallback(layer(), 0); -} - -void WKCACFLayer::becomeRootLayerForContext(WKCACFContext* context) -{ - wkCACFContextSetLayer(context, layer()); - setNeedsCommit(); -} - -void WKCACFLayer::setNeedsCommit() -{ - WKCACFLayer* root = rootLayer(); - - // Call setNeedsRender on the root layer, which will cause a render to - // happen in WKCACFLayerRenderer - root->setNeedsRender(); -} - -bool WKCACFLayer::isTransformLayer() const -{ - return CACFLayerGetClass(layer()) == kCACFTransformLayer; -} - -void WKCACFLayer::addSublayer(PassRefPtr<WKCACFLayer> sublayer) -{ - insertSublayer(sublayer, sublayerCount()); -} - -void WKCACFLayer::internalInsertSublayer(PassRefPtr<WKCACFLayer> sublayer, size_t index) -{ - index = min(index, sublayerCount() + 1); - sublayer->removeFromSuperlayer(); - CACFLayerInsertSublayer(layer(), sublayer->layer(), index); - setNeedsCommit(); - checkLayerConsistency(); -} - -void WKCACFLayer::insertSublayerAboveLayer(PassRefPtr<WKCACFLayer> sublayer, const WKCACFLayer* reference) -{ - if (!reference) { - insertSublayer(sublayer, 0); - return; - } - - int referenceIndex = internalIndexOfSublayer(reference); - if (referenceIndex == -1) { - addSublayer(sublayer); - return; - } - - insertSublayer(sublayer, referenceIndex + 1); -} - -void WKCACFLayer::insertSublayerBelowLayer(PassRefPtr<WKCACFLayer> sublayer, const WKCACFLayer* reference) -{ - if (!reference) { - insertSublayer(sublayer, 0); - return; - } - - int referenceIndex = internalIndexOfSublayer(reference); - if (referenceIndex == -1) { - addSublayer(sublayer); - return; - } - - insertSublayer(sublayer, referenceIndex); -} - -void WKCACFLayer::replaceSublayer(WKCACFLayer* reference, PassRefPtr<WKCACFLayer> newLayer) -{ - ASSERT_ARG(reference, reference); - ASSERT_ARG(reference, reference->superlayer() == this); - - if (reference == newLayer) - return; - - int referenceIndex = internalIndexOfSublayer(reference); - ASSERT(referenceIndex != -1); - if (referenceIndex == -1) - return; - - reference->removeFromSuperlayer(); - - if (newLayer) { - newLayer->removeFromSuperlayer(); - insertSublayer(newLayer, referenceIndex); - } -} - -size_t WKCACFLayer::internalSublayerCount() const -{ - CFArrayRef sublayers = CACFLayerGetSublayers(layer()); - return sublayers ? CFArrayGetCount(sublayers) : 0; -} - -void WKCACFLayer::adoptSublayers(WKCACFLayer* source) -{ - // We will use setSublayers() because it properly nulls - // out the superlayer pointer. - Vector<RefPtr<WKCACFLayer> > sublayers; - size_t n = source->sublayerCount(); - - for (size_t i = 0; i < n; ++i) - sublayers.append(source->internalSublayerAtIndex(i)); - - setSublayers(sublayers); - source->checkLayerConsistency(); -} - -void WKCACFLayer::removeFromSuperlayer() -{ - WKCACFLayer* superlayer = this->superlayer(); - CACFLayerRemoveFromSuperlayer(layer()); - checkLayerConsistency(); - - if (superlayer) - superlayer->setNeedsCommit(); -} - -WKCACFLayer* WKCACFLayer::internalSublayerAtIndex(int index) const -{ - CFArrayRef sublayers = CACFLayerGetSublayers(layer()); - if (!sublayers || index < 0 || CFArrayGetCount(sublayers) <= index) - return 0; - - return layer(static_cast<CACFLayerRef>(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, index)))); -} - -int WKCACFLayer::internalIndexOfSublayer(const WKCACFLayer* reference) -{ - CACFLayerRef ref = reference->layer(); - if (!ref) - return -1; - - CFArrayRef sublayers = CACFLayerGetSublayers(layer()); - if (!sublayers) - return -1; - - size_t n = CFArrayGetCount(sublayers); - - for (size_t i = 0; i < n; ++i) - if (CFArrayGetValueAtIndex(sublayers, i) == ref) - return i; - - return -1; -} - -WKCACFLayer* WKCACFLayer::ancestorOrSelfWithSuperlayer(WKCACFLayer* superlayer) const -{ - WKCACFLayer* layer = const_cast<WKCACFLayer*>(this); - for (WKCACFLayer* ancestor = this->superlayer(); ancestor; layer = ancestor, ancestor = ancestor->superlayer()) { - if (ancestor == superlayer) - return layer; - } - return 0; -} - -void WKCACFLayer::setBounds(const CGRect& rect) -{ - if (CGRectEqualToRect(rect, bounds())) - return; - - CACFLayerSetBounds(layer(), rect); - setNeedsCommit(); - - if (m_needsDisplayOnBoundsChange) - setNeedsDisplay(); - - if (m_layoutClient) - setNeedsLayout(); -} - -void WKCACFLayer::setFrame(const CGRect& rect) -{ - CGRect oldFrame = frame(); - if (CGRectEqualToRect(rect, oldFrame)) - return; - - CACFLayerSetFrame(layer(), rect); - setNeedsCommit(); - - if (m_needsDisplayOnBoundsChange && !CGSizeEqualToSize(rect.size, oldFrame.size)) - setNeedsDisplay(); - - if (m_layoutClient) - setNeedsLayout(); -} - -void WKCACFLayer::setContentsGravity(ContentsGravityType type) -{ - CACFLayerSetContentsGravity(layer(), toCACFContentsGravityType(type)); - setNeedsCommit(); -} - -WKCACFLayer::ContentsGravityType WKCACFLayer::contentsGravity() const -{ - return fromCACFContentsGravityType(CACFLayerGetContentsGravity(layer())); -} - -void WKCACFLayer::setMagnificationFilter(FilterType type) -{ - CACFLayerSetMagnificationFilter(layer(), toCACFFilterType(type)); - setNeedsCommit(); -} - -WKCACFLayer::FilterType WKCACFLayer::magnificationFilter() const -{ - return fromCACFFilterType(CACFLayerGetMagnificationFilter(layer())); -} - -void WKCACFLayer::setMinificationFilter(FilterType type) -{ - CACFLayerSetMinificationFilter(layer(), toCACFFilterType(type)); - setNeedsCommit(); -} - -WKCACFLayer::FilterType WKCACFLayer::minificationFilter() const -{ - return fromCACFFilterType(CACFLayerGetMinificationFilter(layer())); -} - -WKCACFLayer* WKCACFLayer::rootLayer() const -{ - WKCACFLayer* layer = const_cast<WKCACFLayer*>(this); - for (WKCACFLayer* superlayer = layer->superlayer(); superlayer; layer = superlayer, superlayer = superlayer->superlayer()) { } - return layer; -} - -void WKCACFLayer::internalRemoveAllSublayers() -{ - CACFLayerSetSublayers(layer(), 0); - setNeedsCommit(); -} - -void WKCACFLayer::internalSetSublayers(const Vector<RefPtr<WKCACFLayer> >& sublayers) -{ - // Remove all the current sublayers and add the passed layers - CACFLayerSetSublayers(layer(), 0); - - // Perform removeFromSuperLayer in a separate pass. CACF requires superlayer to - // be null or CACFLayerInsertSublayer silently fails. - for (size_t i = 0; i < sublayers.size(); i++) - CACFLayerRemoveFromSuperlayer(sublayers[i]->layer()); - - for (size_t i = 0; i < sublayers.size(); i++) - CACFLayerInsertSublayer(layer(), sublayers[i]->layer(), i); - - setNeedsCommit(); -} - -WKCACFLayer* WKCACFLayer::superlayer() const -{ - CACFLayerRef super = CACFLayerGetSuperlayer(layer()); - if (!super) - return 0; - return WKCACFLayer::layer(super); -} - -void WKCACFLayer::internalSetNeedsDisplay(const CGRect* dirtyRect) -{ - CACFLayerSetNeedsDisplay(layer(), dirtyRect); -} - -void WKCACFLayer::setLayoutClient(WKCACFLayerLayoutClient* layoutClient) -{ - if (layoutClient == m_layoutClient) - return; - - m_layoutClient = layoutClient; - CACFLayerSetLayoutCallback(layer(), m_layoutClient ? layoutSublayersProc : 0); -} - -void WKCACFLayer::layoutSublayersProc(CACFLayerRef caLayer) -{ - WKCACFLayer* layer = WKCACFLayer::layer(caLayer); - if (layer && layer->m_layoutClient) - layer->m_layoutClient->layoutSublayersOfLayer(layer); -} - -#ifndef NDEBUG -static void printIndent(int indent) -{ - for ( ; indent > 0; --indent) - fprintf(stderr, " "); -} - -static void printTransform(const CATransform3D& transform) -{ - fprintf(stderr, "[%g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]", - transform.m11, transform.m12, transform.m13, transform.m14, - transform.m21, transform.m22, transform.m23, transform.m24, - transform.m31, transform.m32, transform.m33, transform.m34, - transform.m41, transform.m42, transform.m43, transform.m44); -} - -void WKCACFLayer::printTree() const -{ - // Print heading info - CGRect rootBounds = bounds(); - fprintf(stderr, "\n\n** Render tree at time %g (bounds %g, %g %gx%g) **\n\n", - currentTime(), rootBounds.origin.x, rootBounds.origin.y, rootBounds.size.width, rootBounds.size.height); - - // Print layer tree from the root - printLayer(0); -} - -void WKCACFLayer::printLayer(int indent) const -{ - CGPoint layerPosition = position(); - CGPoint layerAnchorPoint = anchorPoint(); - CGRect layerBounds = bounds(); - printIndent(indent); - fprintf(stderr, "(%s [%g %g %g] [%g %g %g %g] [%g %g %g] superlayer=%p\n", - isTransformLayer() ? "transform-layer" : "layer", - layerPosition.x, layerPosition.y, zPosition(), - layerBounds.origin.x, layerBounds.origin.y, layerBounds.size.width, layerBounds.size.height, - layerAnchorPoint.x, layerAnchorPoint.y, anchorPointZ(), superlayer()); - - // Print name if needed - String layerName = name(); - if (!layerName.isEmpty()) { - printIndent(indent + 1); - fprintf(stderr, "(name %s)\n", layerName.utf8().data()); - } - - // Print masksToBounds if needed - bool layerMasksToBounds = masksToBounds(); - if (layerMasksToBounds) { - printIndent(indent + 1); - fprintf(stderr, "(masksToBounds true)\n"); - } - - // Print opacity if needed - float layerOpacity = opacity(); - if (layerOpacity != 1) { - printIndent(indent + 1); - fprintf(stderr, "(opacity %hf)\n", layerOpacity); - } - - // Print sublayerTransform if needed - CATransform3D layerTransform = sublayerTransform(); - if (!CATransform3DIsIdentity(layerTransform)) { - printIndent(indent + 1); - fprintf(stderr, "(sublayerTransform "); - printTransform(layerTransform); - fprintf(stderr, ")\n"); - } - - // Print transform if needed - layerTransform = transform(); - if (!CATransform3DIsIdentity(layerTransform)) { - printIndent(indent + 1); - fprintf(stderr, "(transform "); - printTransform(layerTransform); - fprintf(stderr, ")\n"); - } - - // Print contents if needed - CFTypeRef layerContents = contents(); - if (layerContents) { - if (CFGetTypeID(layerContents) == CGImageGetTypeID()) { - CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents)); - printIndent(indent + 1); - fprintf(stderr, "(contents (image [%d %d]))\n", - CGImageGetWidth(imageContents), CGImageGetHeight(imageContents)); - } - } - - // Print sublayers if needed - int n = sublayerCount(); - if (n > 0) { - printIndent(indent + 1); - fprintf(stderr, "(sublayers\n"); - for (int i = 0; i < n; ++i) - internalSublayerAtIndex(i)->printLayer(indent + 2); - - printIndent(indent + 1); - fprintf(stderr, ")\n"); - } - - printIndent(indent); - fprintf(stderr, ")\n"); -} -#endif // #ifndef NDEBUG -} - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/win/WKCACFLayer.h b/Source/WebCore/platform/graphics/win/WKCACFLayer.h deleted file mode 100644 index 4c6639a..0000000 --- a/Source/WebCore/platform/graphics/win/WKCACFLayer.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WKCACFLayer_h -#define WKCACFLayer_h - -#if USE(ACCELERATED_COMPOSITING) - -#include <wtf/RefCounted.h> - -#include <QuartzCore/CACFLayer.h> -#include <QuartzCore/CACFVector.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RetainPtr.h> -#include <wtf/Vector.h> -#include <wtf/text/StringHash.h> - -#include "GraphicsContext.h" -#include "PlatformString.h" -#include "TransformationMatrix.h" - -struct WKCACFContext; - -namespace WebCore { - -class WKCACFLayer; - -class WKCACFLayerLayoutClient { -public: - virtual void layoutSublayersOfLayer(WKCACFLayer*) = 0; -protected: - virtual ~WKCACFLayerLayoutClient() {} -}; - -class WKCACFLayer : public RefCounted<WKCACFLayer> { -public: - enum LayerType { Layer, TransformLayer }; - enum FilterType { Linear, Nearest, Trilinear }; - enum ContentsGravityType { Center, Top, Bottom, Left, Right, TopLeft, TopRight, - BottomLeft, BottomRight, Resize, ResizeAspect, ResizeAspectFill }; - - static PassRefPtr<WKCACFLayer> create(LayerType); - static WKCACFLayer* layer(CACFLayerRef layer) - { - ASSERT(CACFLayerGetUserData(layer) != reinterpret_cast<void*>(0xDEADBEEF)); - return static_cast<WKCACFLayer*>(CACFLayerGetUserData(layer)); - } - - virtual ~WKCACFLayer(); - - virtual void setNeedsRender() { } - - virtual void drawInContext(PlatformGraphicsContext*) { } - - void setLayoutClient(WKCACFLayerLayoutClient*); - WKCACFLayerLayoutClient* layoutClient() const { return m_layoutClient; } - void setNeedsLayout() { CACFLayerSetNeedsLayout(layer()); } - - void setNeedsDisplay(const CGRect* dirtyRect = 0) - { - internalSetNeedsDisplay(dirtyRect); - setNeedsCommit(); - } - - // Makes this layer the root when the passed context is rendered - void becomeRootLayerForContext(WKCACFContext*); - - static RetainPtr<CFTypeRef> cfValue(float value) { return RetainPtr<CFTypeRef>(AdoptCF, CFNumberCreate(0, kCFNumberFloat32Type, &value)); } - static RetainPtr<CFTypeRef> cfValue(const TransformationMatrix& value) - { - CATransform3D t; - t.m11 = value.m11(); - t.m12 = value.m12(); - t.m13 = value.m13(); - t.m14 = value.m14(); - t.m21 = value.m21(); - t.m22 = value.m22(); - t.m23 = value.m23(); - t.m24 = value.m24(); - t.m31 = value.m31(); - t.m32 = value.m32(); - t.m33 = value.m33(); - t.m34 = value.m34(); - t.m41 = value.m41(); - t.m42 = value.m42(); - t.m43 = value.m43(); - t.m44 = value.m44(); - return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreateTransform(t)); - } - static RetainPtr<CFTypeRef> cfValue(const FloatPoint& value) - { - CGPoint p; - p.x = value.x(); p.y = value.y(); - return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreatePoint(p)); - } - static RetainPtr<CFTypeRef> cfValue(const FloatRect& rect) - { - CGRect r; - r.origin.x = rect.x(); - r.origin.y = rect.y(); - r.size.width = rect.width(); - r.size.height = rect.height(); - CGFloat v[4] = { CGRectGetMinX(r), CGRectGetMinY(r), CGRectGetMaxX(r), CGRectGetMaxY(r) }; - return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreate(4, v)); - } - static RetainPtr<CFTypeRef> cfValue(const Color& color) - { - return RetainPtr<CFTypeRef>(AdoptCF, CGColorCreateGenericRGB(color.red(), color.green(), color.blue(), color.alpha())); - } - - bool isTransformLayer() const; - - void addSublayer(PassRefPtr<WKCACFLayer> sublayer); - void insertSublayerAboveLayer(PassRefPtr<WKCACFLayer>, const WKCACFLayer* reference); - void insertSublayerBelowLayer(PassRefPtr<WKCACFLayer>, const WKCACFLayer* reference); - void replaceSublayer(WKCACFLayer* reference, PassRefPtr<WKCACFLayer>); - void adoptSublayers(WKCACFLayer* source); - - void removeAllSublayers() { internalRemoveAllSublayers(); } - void setSublayers(const Vector<RefPtr<WKCACFLayer> >& sublayers) - { - internalSetSublayers(sublayers); - checkLayerConsistency(); - } - - void insertSublayer(PassRefPtr<WKCACFLayer> layer, size_t index) { internalInsertSublayer(layer, index); } - - size_t sublayerCount() const { return internalSublayerCount(); } - - void removeFromSuperlayer(); - - WKCACFLayer* ancestorOrSelfWithSuperlayer(WKCACFLayer*) const; - - void setAnchorPoint(const CGPoint& p) { CACFLayerSetAnchorPoint(layer(), p); setNeedsCommit(); } - CGPoint anchorPoint() const { return CACFLayerGetAnchorPoint(layer()); } - - void setAnchorPointZ(CGFloat z) { CACFLayerSetAnchorPointZ(layer(), z); setNeedsCommit(); } - CGFloat anchorPointZ() const { return CACFLayerGetAnchorPointZ(layer()); } - - void setBackgroundColor(CGColorRef color) { CACFLayerSetBackgroundColor(layer(), color); setNeedsCommit(); } - CGColorRef backgroundColor() const { return CACFLayerGetBackgroundColor(layer()); } - - void setBorderColor(CGColorRef color) { CACFLayerSetBorderColor(layer(), color); setNeedsCommit(); } - CGColorRef borderColor() const { return CACFLayerGetBorderColor(layer()); } - - void setBorderWidth(CGFloat width) { CACFLayerSetBorderWidth(layer(), width); setNeedsCommit(); } - CGFloat borderWidth() const { return CACFLayerGetBorderWidth(layer()); } - - virtual void setBounds(const CGRect&); - CGRect bounds() const { return CACFLayerGetBounds(layer()); } - - void setContents(CFTypeRef contents) { CACFLayerSetContents(layer(), contents); setNeedsCommit(); } - CFTypeRef contents() const { return CACFLayerGetContents(layer()); } - - void setContentsRect(const CGRect& contentsRect) { CACFLayerSetContentsRect(layer(), contentsRect); setNeedsCommit(); } - CGRect contentsRect() const { return CACFLayerGetContentsRect(layer()); } - - void setContentsGravity(ContentsGravityType); - ContentsGravityType contentsGravity() const; - - void setDoubleSided(bool b) { CACFLayerSetDoubleSided(layer(), b); setNeedsCommit(); } - bool doubleSided() const { return CACFLayerIsDoubleSided(layer()); } - - void setEdgeAntialiasingMask(uint32_t mask) { CACFLayerSetEdgeAntialiasingMask(layer(), mask); setNeedsCommit(); } - uint32_t edgeAntialiasingMask() const { return CACFLayerGetEdgeAntialiasingMask(layer()); } - - virtual void setFrame(const CGRect&); - CGRect frame() const { return CACFLayerGetFrame(layer()); } - - void setHidden(bool hidden) { CACFLayerSetHidden(layer(), hidden); setNeedsCommit(); } - bool isHidden() const { return CACFLayerIsHidden(layer()); } - - void setMasksToBounds(bool b) { CACFLayerSetMasksToBounds(layer(), b); } - bool masksToBounds() const { return CACFLayerGetMasksToBounds(layer()); } - - void setMagnificationFilter(FilterType); - FilterType magnificationFilter() const; - - void setMinificationFilter(FilterType); - FilterType minificationFilter() const; - - void setMinificationFilterBias(float bias) { CACFLayerSetMinificationFilterBias(layer(), bias); } - float minificationFilterBias() const { return CACFLayerGetMinificationFilterBias(layer()); } - - void setName(const String& name) { CACFLayerSetName(layer(), RetainPtr<CFStringRef>(AdoptCF, name.createCFString()).get()); } - String name() const { return CACFLayerGetName(layer()); } - - void setNeedsDisplayOnBoundsChange(bool needsDisplay) { m_needsDisplayOnBoundsChange = needsDisplay; } - - void setOpacity(float opacity) { CACFLayerSetOpacity(layer(), opacity); setNeedsCommit(); } - float opacity() const { return CACFLayerGetOpacity(layer()); } - - void setOpaque(bool b) { CACFLayerSetOpaque(layer(), b); setNeedsCommit(); } - bool opaque() const { return CACFLayerIsOpaque(layer()); } - - void setPosition(const CGPoint& position) { CACFLayerSetPosition(layer(), position); setNeedsCommit(); } - CGPoint position() const { return CACFLayerGetPosition(layer()); } - - void setZPosition(CGFloat position) { CACFLayerSetZPosition(layer(), position); setNeedsCommit(); } - CGFloat zPosition() const { return CACFLayerGetZPosition(layer()); } - - void setSpeed(float speed) { CACFLayerSetSpeed(layer(), speed); } - CFTimeInterval speed() const { return CACFLayerGetSpeed(layer()); } - - void setTimeOffset(CFTimeInterval t) { CACFLayerSetTimeOffset(layer(), t); } - CFTimeInterval timeOffset() const { return CACFLayerGetTimeOffset(layer()); } - - WKCACFLayer* rootLayer() const; - - void setSublayerTransform(const CATransform3D& transform) { CACFLayerSetSublayerTransform(layer(), transform); setNeedsCommit(); } - CATransform3D sublayerTransform() const { return CACFLayerGetSublayerTransform(layer()); } - - WKCACFLayer* superlayer() const; - - void setTransform(const CATransform3D& transform) { CACFLayerSetTransform(layer(), transform); setNeedsCommit(); } - CATransform3D transform() const { return CACFLayerGetTransform(layer()); } - - void setGeometryFlipped(bool flipped) { CACFLayerSetGeometryFlipped(layer(), flipped); setNeedsCommit(); } - bool geometryFlipped() const { return CACFLayerIsGeometryFlipped(layer()); } - -#ifndef NDEBUG - // Print the tree from the root. Also does consistency checks - void printTree() const; -#endif - -protected: - WKCACFLayer(LayerType); - - void setNeedsCommit(); - - CACFLayerRef layer() const { return m_layer.get(); } - // This should only be called from removeFromSuperlayer. - void removeSublayer(const WKCACFLayer*); - - void checkLayerConsistency() - { -#ifndef NDEBUG - internalCheckLayerConsistency(); -#endif - } - - // Methods to be overridden for sublayer and rendering management - virtual WKCACFLayer* internalSublayerAtIndex(int) const; - - // Returns the index of the passed layer in this layer's sublayers list - // or -1 if not found - virtual int internalIndexOfSublayer(const WKCACFLayer*); - - virtual size_t internalSublayerCount() const; - virtual void internalInsertSublayer(PassRefPtr<WKCACFLayer>, size_t index); - virtual void internalRemoveAllSublayers(); - virtual void internalSetSublayers(const Vector<RefPtr<WKCACFLayer> >&); - - virtual void internalSetNeedsDisplay(const CGRect* dirtyRect); - -#ifndef NDEBUG - virtual void internalCheckLayerConsistency(); -#endif - -#ifndef NDEBUG - // Print this layer and its children to the console - void printLayer(int indent) const; -#endif - -private: - static void layoutSublayersProc(CACFLayerRef); - - RetainPtr<CACFLayerRef> m_layer; - WKCACFLayerLayoutClient* m_layoutClient; - bool m_needsDisplayOnBoundsChange; -}; - -} - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // WKCACFLayer_h diff --git a/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp b/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp index 4c5e61d..7c83f86 100644 --- a/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp +++ b/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp @@ -187,7 +187,6 @@ WKCACFLayerRenderer::WKCACFLayerRenderer(WKCACFLayerRendererClient* client) , m_context(wkCACFContextCreate()) , m_hostWindow(0) , m_renderTimer(this, &WKCACFLayerRenderer::renderTimerFired) - , m_backingStoreDirty(false) , m_mustResetLostDeviceBeforeRendering(false) , m_syncLayerChanges(false) { @@ -224,32 +223,33 @@ WKCACFLayerRenderer::WKCACFLayerRenderer(WKCACFLayerRendererClient* client) WKCACFLayerRenderer::~WKCACFLayerRenderer() { - destroyRenderer(); + setHostWindow(0); + WKCACFContextFlusher::shared().removeContext(m_context); wkCACFContextDestroy(m_context); } -PlatformCALayer* WKCACFLayerRenderer::rootLayer() const +void WKCACFLayerRenderer::setHostWindow(HWND window) { - return m_rootLayer.get(); -} + if (window == m_hostWindow) + return; -void WKCACFLayerRenderer::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer) -{ - m_pendingAnimatedLayers.add(layer); + if (m_hostWindow) + destroyRenderer(); + + m_hostWindow = window; + + if (m_hostWindow) + createRenderer(); } -void WKCACFLayerRenderer::setRootContents(CGImageRef image) +PlatformCALayer* WKCACFLayerRenderer::rootLayer() const { - ASSERT(m_rootLayer); - m_rootLayer->setContents(image); - renderSoon(); + return m_rootLayer.get(); } -void WKCACFLayerRenderer::setRootContentsAndDisplay(CGImageRef image) +void WKCACFLayerRenderer::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer) { - ASSERT(m_rootLayer); - m_rootLayer->setContents(image); - paint(); + m_pendingAnimatedLayers.add(layer); } void WKCACFLayerRenderer::setRootChildLayer(PlatformCALayer* layer) @@ -266,16 +266,6 @@ void WKCACFLayerRenderer::layerTreeDidChange() renderSoon(); } -void WKCACFLayerRenderer::setNeedsDisplay(bool sync) -{ - if (!m_syncLayerChanges && sync) - m_syncLayerChanges = true; - - ASSERT(m_rootLayer); - m_rootLayer->setNeedsDisplay(0); - renderSoon(); -} - bool WKCACFLayerRenderer::createRenderer() { if (m_d3dDevice || !m_mightBeAbleToCreateDeviceLater) @@ -340,7 +330,7 @@ bool WKCACFLayerRenderer::createRenderer() initD3DGeometry(); - wkCACFContextInitializeD3DDevice(m_context, m_d3dDevice.get()); + wkCACFContextSetD3DDevice(m_context, m_d3dDevice.get()); if (IsWindow(m_hostWindow)) m_rootLayer->setBounds(bounds()); @@ -352,6 +342,7 @@ void WKCACFLayerRenderer::destroyRenderer() { wkCACFContextSetLayer(m_context, m_rootLayer->platformLayer()); + wkCACFContextSetD3DDevice(m_context, 0); m_d3dDevice = 0; if (s_d3d) s_d3d->Release(); @@ -422,15 +413,6 @@ void WKCACFLayerRenderer::paint() return; } - if (m_backingStoreDirty) { - // If the backing store is still dirty when we are about to draw the - // composited content, we need to force the window to paint into the - // backing store. The paint will only paint the dirty region that - // if being tracked in WebView. - UpdateWindow(m_hostWindow); - return; - } - Vector<CGRect> dirtyRects; getDirtyRects(m_hostWindow, dirtyRects); render(dirtyRects); @@ -545,6 +527,12 @@ void WKCACFLayerRenderer::renderSoon() m_renderTimer.startOneShot(0); } +void WKCACFLayerRenderer::syncCompositingStateSoon() +{ + m_syncLayerChanges = true; + renderSoon(); +} + CGRect WKCACFLayerRenderer::bounds() const { RECT clientRect; diff --git a/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.h b/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.h index aff1f83..02cdbdb 100644 --- a/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.h +++ b/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.h @@ -54,7 +54,6 @@ class WKCACFLayerRendererClient { public: virtual ~WKCACFLayerRendererClient() { } virtual bool shouldRender() const = 0; - virtual void animationsStarted(CFTimeInterval) { } virtual void syncCompositingState() { } }; @@ -70,17 +69,12 @@ public: static bool acceleratedCompositingAvailable(); - void setRootContents(CGImageRef); - void setRootContentsAndDisplay(CGImageRef); void setRootChildLayer(PlatformCALayer*); void layerTreeDidChange(); - void setNeedsDisplay(bool sync = false); - void setHostWindow(HWND window) { m_hostWindow = window; } - void setBackingStoreDirty(bool dirty) { m_backingStoreDirty = dirty; } - bool createRenderer(); - void destroyRenderer(); + void setHostWindow(HWND); + void paint(); void resize(); - void renderSoon(); + void syncCompositingStateSoon(); protected: PlatformCALayer* rootLayer() const; @@ -89,6 +83,9 @@ protected: private: WKCACFLayerRenderer(WKCACFLayerRendererClient*); + bool createRenderer(); + void destroyRenderer(); + void renderSoon(); void renderTimerFired(Timer<WKCACFLayerRenderer>*); CGRect bounds() const; @@ -102,7 +99,6 @@ private: bool resetDevice(ResetReason); void render(const Vector<CGRect>& dirtyRects = Vector<CGRect>()); - void paint(); WKCACFLayerRendererClient* m_client; bool m_mightBeAbleToCreateDeviceLater; @@ -112,7 +108,6 @@ private: WKCACFContext* m_context; HWND m_hostWindow; Timer<WKCACFLayerRenderer> m_renderTimer; - bool m_backingStoreDirty; bool m_mustResetLostDeviceBeforeRendering; bool m_syncLayerChanges; HashSet<RefPtr<PlatformCALayer> > m_pendingAnimatedLayers; diff --git a/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp b/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp index c0b2b53..cfcc487 100644 --- a/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp +++ b/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp @@ -41,7 +41,7 @@ namespace WebCore { -NativeImagePtr RGBA32Buffer::asNewNativeImage() const +NativeImagePtr ImageFrame::asNewNativeImage() const { return SharedBitmap::create(m_backingStore, m_size, hasAlpha()); } diff --git a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp index cee6aee..f1c09c5 100644 --- a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp +++ b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp @@ -31,7 +31,6 @@ #include "Font.h" #include "IntRect.h" #include "NotImplemented.h" -#include "Pen.h" #include <wtf/MathExtras.h> #include <math.h> diff --git a/Source/WebCore/platform/graphics/wx/PenWx.cpp b/Source/WebCore/platform/graphics/wx/PenWx.cpp deleted file mode 100644 index 5a131e3..0000000 --- a/Source/WebCore/platform/graphics/wx/PenWx.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Pen.h" - -#include <wx/defs.h> -#include <wx/pen.h> -#include <wx/colour.h> - -namespace WebCore { - -// Pen style conversion functions -static int penStyleToWxPenStyle(int p) -{ - if (p == Pen::SolidLine) - return wxSOLID; - if (p == Pen::DotLine) - return wxDOT; - if (p == Pen::DashLine) - return wxLONG_DASH; - if (p == Pen::NoPen) - return wxTRANSPARENT; - - return wxSOLID; -} - -static Pen::PenStyle wxPenStyleToPenStyle(int p) -{ - if (p == wxSOLID) - return Pen::SolidLine; - if (p == wxDOT) - return Pen::DotLine; - if (p == wxLONG_DASH || p == wxSHORT_DASH || p == wxDOT_DASH || p == wxUSER_DASH) - return Pen::DashLine; - if (p == wxTRANSPARENT) - return Pen::NoPen; - - return Pen::SolidLine; -} - -Pen::Pen(const wxPen& p) -{ - wxColour color = p.GetColour(); - setColor(Color(color.Red(), color.Green(), color.Blue())); - setWidth(p.GetWidth()); - setStyle(wxPenStyleToPenStyle(p.GetStyle())); -} - -Pen::operator wxPen() const -{ - return wxPen(wxColour(m_color.red(), m_color.blue(), m_color.green()), width(), penStyleToWxPenStyle(style())); -} - -} |