summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
commitcfd86b747d32ac22246a1aa908eaa720c63a88c1 (patch)
tree24d68c6f61c464ecba1e05670b80390ea3b0e50c /Source/WebCore/platform/graphics
parent69d7c744c9de19d152dbe2d8e46eb7dfd4511d1a (diff)
Imported WebKit commit 20271caf2e2c016d5cef40184cddeefeac4f1876 (http://svn.webkit.org/repository/webkit/trunk@133733)
New snapshot that contains all previous fixes as well as build fix for latest QtMultimedia API changes.
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/BitmapImage.h4
-rw-r--r--Source/WebCore/platform/graphics/Font.cpp12
-rw-r--r--Source/WebCore/platform/graphics/Font.h85
-rw-r--r--Source/WebCore/platform/graphics/FontCache.cpp4
-rw-r--r--Source/WebCore/platform/graphics/FontFallbackList.h33
-rw-r--r--Source/WebCore/platform/graphics/FontPlatformData.h2
-rw-r--r--Source/WebCore/platform/graphics/FractionalLayoutSize.h14
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.cpp6
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.h3
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayer.cpp58
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayer.h36
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayerAnimation.cpp86
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayerAnimation.h21
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayerClient.h3
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.h2
-rw-r--r--Source/WebCore/platform/graphics/ImageObserver.h4
-rw-r--r--Source/WebCore/platform/graphics/ImageOrientation.cpp8
-rw-r--r--Source/WebCore/platform/graphics/ImageOrientation.h13
-rw-r--r--Source/WebCore/platform/graphics/ImageSource.cpp21
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.h3
-rw-r--r--Source/WebCore/platform/graphics/SimpleFontData.cpp23
-rw-r--r--Source/WebCore/platform/graphics/TiledBacking.h7
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm3
-rw-r--r--Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp12
-rw-r--r--Source/WebCore/platform/graphics/blackberry/ImageBlackBerry.cpp15
-rw-r--r--Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp46
-rw-r--r--Source/WebCore/platform/graphics/blackberry/LayerRenderer.h1
-rw-r--r--Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp1
-rw-r--r--Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp47
-rw-r--r--Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h2
-rw-r--r--Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp161
-rw-r--r--Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h11
-rw-r--r--Source/WebCore/platform/graphics/ca/PlatformCALayer.h1
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm9
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/TileCache.h11
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/TileCache.mm50
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm3
-rw-r--r--Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp3
-rw-r--r--Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp19
-rw-r--r--Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp2
-rw-r--r--Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp32
-rw-r--r--Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp54
-rw-r--r--Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp20
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp3
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageSourceCGMac.mm8
-rw-r--r--Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.cpp6
-rw-r--r--Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.h1
-rw-r--r--Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp40
-rw-r--r--Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.cpp6
-rw-r--r--Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp20
-rw-r--r--Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp4
-rw-r--r--Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp27
-rw-r--r--Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp39
-rw-r--r--Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h14
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterArrayParameter.h17
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.cpp10
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.h9
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterConstants.h12
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterMesh.cpp2
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterMesh.h8
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.cpp8
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h8
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterNumberParameter.h1
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp63
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterOperation.h45
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterParameterList.cpp104
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterParameterList.h56
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp12
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterProgram.h19
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp28
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h7
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterRenderer.cpp305
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterRenderer.h99
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp235
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.h6
-rw-r--r--Source/WebCore/platform/graphics/filters/FEBlend.h1
-rw-r--r--Source/WebCore/platform/graphics/filters/FEColorMatrix.h1
-rw-r--r--Source/WebCore/platform/graphics/filters/FEComponentTransfer.h1
-rw-r--r--Source/WebCore/platform/graphics/filters/FECustomFilter.cpp289
-rw-r--r--Source/WebCore/platform/graphics/filters/FECustomFilter.h53
-rw-r--r--Source/WebCore/platform/graphics/filters/FEGaussianBlur.h1
-rw-r--r--Source/WebCore/platform/graphics/filters/FELighting.h1
-rw-r--r--Source/WebCore/platform/graphics/filters/FEMorphology.h2
-rw-r--r--Source/WebCore/platform/graphics/filters/FilterEffect.h9
-rw-r--r--Source/WebCore/platform/graphics/filters/FilterOperation.h17
-rw-r--r--Source/WebCore/platform/graphics/filters/FilterOperations.cpp9
-rw-r--r--Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.cpp69
-rw-r--r--Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.h98
-rw-r--r--Source/WebCore/platform/graphics/filters/skia/FEBlendSkia.cpp9
-rw-r--r--Source/WebCore/platform/graphics/filters/skia/FEColorMatrixSkia.cpp44
-rw-r--r--Source/WebCore/platform/graphics/filters/skia/FEComponentTransferSkia.cpp14
-rw-r--r--Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp7
-rw-r--r--Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp66
-rw-r--r--Source/WebCore/platform/graphics/filters/skia/FEMorphologySkia.cpp11
-rw-r--r--Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.cpp265
-rw-r--r--Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.h50
-rw-r--r--Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp21
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp8
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm22
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp4
-rw-r--r--Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp20
-rw-r--r--Source/WebCore/platform/graphics/qt/FontQt.cpp8
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp8
-rw-r--r--Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp23
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp1
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageSkia.cpp48
-rw-r--r--Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp44
-rw-r--r--Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h5
-rw-r--r--Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h10
-rw-r--r--Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp36
-rw-r--r--Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp226
-rw-r--r--Source/WebCore/platform/graphics/surfaces/win/GraphicsSurfaceWin.cpp492
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp13
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h1
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapper.cpp107
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapper.h12
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp18
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp25
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h10
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp4
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h2
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformState.cpp36
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformState.h12
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp167
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformationMatrix.h6
-rw-r--r--Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp20
-rw-r--r--Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp20
-rw-r--r--Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp20
129 files changed, 3412 insertions, 1229 deletions
diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h
index 8fedc3e50..00387d64a 100644
--- a/Source/WebCore/platform/graphics/BitmapImage.h
+++ b/Source/WebCore/platform/graphics/BitmapImage.h
@@ -204,8 +204,8 @@ protected:
virtual void drawFrameMatchingSourceSize(GraphicsContext*, const FloatRect& dstRect, const IntSize& srcSize, ColorSpace styleColorSpace, CompositeOperator);
#endif
virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator);
-#if USE(CG)
- virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator, RespectImageOrientationEnum);
+#if USE(CG) || PLATFORM(CHROMIUM) || USE(CAIRO)
+ virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator, RespectImageOrientationEnum) OVERRIDE;
#endif
#if (OS(WINCE) && !PLATFORM(QT))
diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp
index 38ce35425..b3bf322e5 100644
--- a/Source/WebCore/platform/graphics/Font.cpp
+++ b/Source/WebCore/platform/graphics/Font.cpp
@@ -75,6 +75,7 @@ Font::Font()
, m_wordSpacing(0)
, m_isPlatformFont(false)
, m_needsTranscoding(false)
+ , m_typesettingFeatures(0)
{
}
@@ -84,6 +85,7 @@ Font::Font(const FontDescription& fd, short letterSpacing, short wordSpacing)
, m_wordSpacing(wordSpacing)
, m_isPlatformFont(false)
, m_needsTranscoding(fontTranscoder().needsTranscoding(fd))
+ , m_typesettingFeatures(computeTypesettingFeatures())
{
}
@@ -92,6 +94,7 @@ Font::Font(const FontPlatformData& fontData, bool isPrinterFont, FontSmoothingMo
, m_letterSpacing(0)
, m_wordSpacing(0)
, m_isPlatformFont(true)
+ , m_typesettingFeatures(computeTypesettingFeatures())
{
m_fontDescription.setUsePrinterFont(isPrinterFont);
m_fontDescription.setFontSmoothing(fontSmoothingMode);
@@ -106,6 +109,7 @@ Font::Font(const Font& other)
, m_wordSpacing(other.m_wordSpacing)
, m_isPlatformFont(other.m_isPlatformFont)
, m_needsTranscoding(other.m_needsTranscoding)
+ , m_typesettingFeatures(computeTypesettingFeatures())
{
}
@@ -117,6 +121,7 @@ Font& Font::operator=(const Font& other)
m_wordSpacing = other.m_wordSpacing;
m_isPlatformFont = other.m_isPlatformFont;
m_needsTranscoding = other.m_needsTranscoding;
+ m_typesettingFeatures = other.m_typesettingFeatures;
return *this;
}
@@ -148,6 +153,7 @@ void Font::update(PassRefPtr<FontSelector> fontSelector) const
if (!m_fontFallbackList)
m_fontFallbackList = FontFallbackList::create();
m_fontFallbackList->invalidate(fontSelector);
+ m_typesettingFeatures = computeTypesettingFeatures();
}
void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
@@ -210,11 +216,7 @@ float Font::width(const TextRun& run, int& charsConsumed, String& glyphName) con
charsConsumed = run.length();
glyphName = "";
-
- if (codePath(run) != Complex)
- return floatWidthForSimpleText(run);
-
- return floatWidthForComplexText(run);
+ return width(run);
}
#if !(PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)))
diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h
index aabcb2e70..b60d9dd3d 100644
--- a/Source/WebCore/platform/graphics/Font.h
+++ b/Source/WebCore/platform/graphics/Font.h
@@ -121,47 +121,7 @@ public:
FontRenderingMode renderingMode() const { return m_fontDescription.renderingMode(); }
- TypesettingFeatures typesettingFeatures() const
- {
- TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMode();
- TypesettingFeatures features = s_defaultTypesettingFeatures;
-
- switch(textRenderingMode) {
- case AutoTextRendering:
- break;
- case OptimizeSpeed:
- features &= ~(Kerning | Ligatures);
- break;
- case GeometricPrecision:
- case OptimizeLegibility:
- features |= Kerning | Ligatures;
- break;
- }
-
- switch (m_fontDescription.kerning()) {
- case FontDescription::NoneKerning:
- features &= ~Kerning;
- break;
- case FontDescription::NormalKerning:
- features |= Kerning;
- break;
- case FontDescription::AutoKerning:
- break;
- }
-
- switch (m_fontDescription.commonLigaturesState()) {
- case FontDescription::DisabledLigaturesState:
- features &= ~Ligatures;
- break;
- case FontDescription::EnabledLigaturesState:
- features |= Ligatures;
- break;
- case FontDescription::NormalLigaturesState:
- break;
- }
-
- return features;
- }
+ TypesettingFeatures typesettingFeatures() const { return m_typesettingFeatures; }
FontFamily& firstFamily() { return m_fontDescription.firstFamily(); }
const FontFamily& family() const { return m_fontDescription.family(); }
@@ -287,6 +247,48 @@ private:
return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
}
+ TypesettingFeatures computeTypesettingFeatures() const
+ {
+ TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMode();
+ TypesettingFeatures features = s_defaultTypesettingFeatures;
+
+ switch (textRenderingMode) {
+ case AutoTextRendering:
+ break;
+ case OptimizeSpeed:
+ features &= ~(Kerning | Ligatures);
+ break;
+ case GeometricPrecision:
+ case OptimizeLegibility:
+ features |= Kerning | Ligatures;
+ break;
+ }
+
+ switch (m_fontDescription.kerning()) {
+ case FontDescription::NoneKerning:
+ features &= ~Kerning;
+ break;
+ case FontDescription::NormalKerning:
+ features |= Kerning;
+ break;
+ case FontDescription::AutoKerning:
+ break;
+ }
+
+ switch (m_fontDescription.commonLigaturesState()) {
+ case FontDescription::DisabledLigaturesState:
+ features &= ~Ligatures;
+ break;
+ case FontDescription::EnabledLigaturesState:
+ features |= Ligatures;
+ break;
+ case FontDescription::NormalLigaturesState:
+ break;
+ }
+
+ return features;
+ }
+
#if PLATFORM(QT)
void initFormatForTextLayout(QTextLayout*) const;
#endif
@@ -299,6 +301,7 @@ private:
short m_wordSpacing;
bool m_isPlatformFont;
bool m_needsTranscoding;
+ mutable TypesettingFeatures m_typesettingFeatures; // Caches values computed from m_fontDescription.
};
inline Font::~Font()
diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp
index 3fea6c235..f60883ab3 100644
--- a/Source/WebCore/platform/graphics/FontCache.cpp
+++ b/Source/WebCore/platform/graphics/FontCache.cpp
@@ -293,8 +293,8 @@ static FontDataCache* gFontDataCache = 0;
const int cMaxInactiveFontData = 250;
const int cTargetInactiveFontData = 200;
#else
-const int cMaxInactiveFontData = 50; // Pretty Low Threshold
-const int cTargetInactiveFontData = 30;
+const int cMaxInactiveFontData = 225;
+const int cTargetInactiveFontData = 200;
#endif
static ListHashSet<RefPtr<SimpleFontData> >* gInactiveFontData = 0;
diff --git a/Source/WebCore/platform/graphics/FontFallbackList.h b/Source/WebCore/platform/graphics/FontFallbackList.h
index 88f1bc796..a14fb82ed 100644
--- a/Source/WebCore/platform/graphics/FontFallbackList.h
+++ b/Source/WebCore/platform/graphics/FontFallbackList.h
@@ -41,6 +41,29 @@ const int cAllFamiliesScanned = -1;
class FontFallbackList : public RefCounted<FontFallbackList> {
WTF_MAKE_NONCOPYABLE(FontFallbackList);
public:
+ typedef HashMap<int, GlyphPageTreeNode*, DefaultHash<int>::Hash> GlyphPages;
+
+ class GlyphPagesStateSaver {
+ public:
+ GlyphPagesStateSaver(FontFallbackList& fallbackList)
+ : m_fallbackList(fallbackList)
+ , m_pages(fallbackList.m_pages)
+ , m_pageZero(fallbackList.m_pageZero)
+ {
+ }
+
+ ~GlyphPagesStateSaver()
+ {
+ m_fallbackList.m_pages = m_pages;
+ m_fallbackList.m_pageZero = m_pageZero;
+ }
+
+ private:
+ FontFallbackList& m_fallbackList;
+ GlyphPages& m_pages;
+ GlyphPageTreeNode* m_pageZero;
+ };
+
static PassRefPtr<FontFallbackList> create() { return adoptRef(new FontFallbackList()); }
~FontFallbackList() { releaseFontData(); }
@@ -56,13 +79,6 @@ public:
unsigned fontSelectorVersion() const { return m_fontSelectorVersion; }
unsigned generation() const { return m_generation; }
- struct GlyphPagesHashTraits : HashTraits<int> {
- static const int minimumTableSize = 16;
- };
- typedef HashMap<int, GlyphPageTreeNode*, DefaultHash<int>::Hash, GlyphPagesHashTraits> GlyphPages;
- GlyphPageTreeNode* glyphPageZero() const { return m_pageZero; }
- const GlyphPages& glyphPages() const { return m_pages; }
-
private:
FontFallbackList();
@@ -80,8 +96,6 @@ private:
void setPlatformFont(const FontPlatformData&);
void releaseFontData();
- void setGlyphPageZero(GlyphPageTreeNode* pageZero) { m_pageZero = pageZero; }
- void setGlyphPages(const GlyphPages& pages) { m_pages = pages; }
mutable Vector<RefPtr<FontData>, 1> m_fontList;
mutable GlyphPages m_pages;
@@ -95,7 +109,6 @@ private:
mutable bool m_loadingCustomFonts : 1;
friend class Font;
- friend class SVGTextRunRenderingContext;
};
}
diff --git a/Source/WebCore/platform/graphics/FontPlatformData.h b/Source/WebCore/platform/graphics/FontPlatformData.h
index f7af70617..be82845ed 100644
--- a/Source/WebCore/platform/graphics/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/FontPlatformData.h
@@ -181,7 +181,7 @@ public:
#if USE(CG) || USE(SKIA_ON_MAC_CHROMIUM)
ASSERT(m_font || !m_cgFont);
#endif
- uintptr_t hashCodes[3] = { (uintptr_t)m_font, m_widthVariant, m_isPrinterFont << 4 | m_textOrientation << 3 | m_orientation << 2 | m_syntheticBold << 1 | m_syntheticOblique };
+ uintptr_t hashCodes[3] = { (uintptr_t)m_font, m_widthVariant, static_cast<uintptr_t>(m_isPrinterFont << 4 | m_textOrientation << 3 | m_orientation << 2 | m_syntheticBold << 1 | m_syntheticOblique) };
return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
#elif USE(CAIRO)
return PtrHash<cairo_scaled_font_t*>::hash(m_scaledFont);
diff --git a/Source/WebCore/platform/graphics/FractionalLayoutSize.h b/Source/WebCore/platform/graphics/FractionalLayoutSize.h
index 1071d8ae3..9ece2ed84 100644
--- a/Source/WebCore/platform/graphics/FractionalLayoutSize.h
+++ b/Source/WebCore/platform/graphics/FractionalLayoutSize.h
@@ -77,6 +77,12 @@ public:
m_width *= scale;
m_height *= scale;
}
+
+ void scale(float widthScale, float heightScale)
+ {
+ m_width *= widthScale;
+ m_height *= heightScale;
+ }
FractionalLayoutSize expandedTo(const FractionalLayoutSize& other) const
{
@@ -94,6 +100,14 @@ public:
{
*this = expandedTo(FractionalLayoutSize());
}
+
+ void clampToMinimumSize(const FractionalLayoutSize& minimumSize)
+ {
+ if (m_width < minimumSize.width())
+ m_width = minimumSize.width();
+ if (m_height < minimumSize.height())
+ m_height = minimumSize.height();
+ }
FractionalLayoutSize transposedSize() const
{
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
index bc899472c..5f6942bf5 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -116,9 +116,7 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format,
*componentsPerPixel = 1;
*bytesPerComponent = sizeof(GC3Dushort);
break;
-#if !PLATFORM(BLACKBERRY)
case GraphicsContext3D::UNSIGNED_INT_24_8:
-#endif
case GraphicsContext3D::UNSIGNED_INT:
*bytesPerComponent = sizeof(GC3Duint);
break;
@@ -149,7 +147,7 @@ GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum ty
}
CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel);
checkedValue *= width;
- if (!checkedValue.valid())
+ if (!checkedValue.isValid())
return GraphicsContext3D::INVALID_VALUE;
unsigned int validRowSize = checkedValue.value();
unsigned int padding = 0;
@@ -161,7 +159,7 @@ GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum ty
// Last row needs no padding.
checkedValue *= (height - 1);
checkedValue += validRowSize;
- if (!checkedValue.valid())
+ if (!checkedValue.isValid())
return GraphicsContext3D::INVALID_VALUE;
*imageSizeInBytes = checkedValue.value();
if (paddingInBytes)
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index 99a21a2d4..4ede0f817 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -72,6 +72,7 @@ typedef QOpenGLContext* PlatformGraphicsContext3D;
typedef QSurface* PlatformGraphicsSurface3D;
#else
typedef void* PlatformGraphicsContext3D;
+typedef void* PlatformGraphicsSurface3D;
#endif
#if (PLATFORM(CHROMIUM) || PLATFORM(BLACKBERRY)) && USE(SKIA)
@@ -947,7 +948,7 @@ public:
bool reshapeFBOs(const IntSize&);
void resolveMultisamplingIfNecessary(const IntRect& = IntRect());
-#if PLATFORM(QT) && USE(GRAPHICS_SURFACE)
+#if (PLATFORM(QT) || PLATFORM(EFL)) && USE(GRAPHICS_SURFACE)
void createGraphicsSurfaces(const IntSize&);
#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.cpp b/Source/WebCore/platform/graphics/GraphicsLayer.cpp
index 3a32b5145..dd3b7a9df 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayer.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -30,10 +30,12 @@
#include "GraphicsLayer.h"
#include "FloatPoint.h"
+#include "FloatRect.h"
#include "GraphicsContext.h"
#include "LayoutTypesInlineMethods.h"
#include "RotateTransformOperation.h"
#include "TextStream.h"
+#include <wtf/HashMap.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>
@@ -44,6 +46,13 @@
namespace WebCore {
+typedef HashMap<const GraphicsLayer*, Vector<FloatRect> > RepaintMap;
+static RepaintMap& repaintRectMap()
+{
+ DEFINE_STATIC_LOCAL(RepaintMap, map, ());
+ return map;
+}
+
void KeyframeValueList::insert(const AnimationValue* value)
{
for (size_t i = 0; i < m_values.size(); ++i) {
@@ -80,6 +89,8 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
, m_acceleratesDrawing(false)
, m_maintainsPixelAlignment(false)
, m_appliesPageScale(false)
+ , m_showDebugBorder(false)
+ , m_showRepaintCounter(false)
, m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip)
, m_contentsOrientation(CompositingCoordinatesTopDown)
, m_parent(0)
@@ -96,6 +107,7 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
GraphicsLayer::~GraphicsLayer()
{
+ resetTrackedRepaints();
ASSERT(!m_parent); // willBeDestroyed should have been called already.
}
@@ -364,7 +376,7 @@ void GraphicsLayer::getDebugBorderInfo(Color& color, float& width) const
void GraphicsLayer::updateDebugIndicators()
{
- if (!GraphicsLayer::showDebugBorders())
+ if (!isShowingDebugBorder())
return;
Color borderColor;
@@ -536,6 +548,28 @@ double GraphicsLayer::backingStoreMemoryEstimate() const
return static_cast<double>(4 * size().width()) * size().height();
}
+void GraphicsLayer::resetTrackedRepaints()
+{
+ repaintRectMap().remove(this);
+}
+
+void GraphicsLayer::addRepaintRect(const FloatRect& repaintRect)
+{
+ if (m_client->isTrackingRepaints()) {
+ FloatRect largestRepaintRect(FloatPoint(), m_size);
+ largestRepaintRect.intersect(repaintRect);
+ RepaintMap::iterator repaintIt = repaintRectMap().find(this);
+ if (repaintIt == repaintRectMap().end()) {
+ Vector<FloatRect> repaintRects;
+ repaintRects.append(largestRepaintRect);
+ repaintRectMap().set(this, repaintRects);
+ } else {
+ Vector<FloatRect>& repaintRects = repaintIt->value;
+ repaintRects.append(largestRepaintRect);
+ }
+ }
+}
+
void GraphicsLayer::writeIndent(TextStream& ts, int indent)
{
for (int i = 0; i != indent; ++i)
@@ -658,7 +692,25 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe
writeIndent(ts, indent + 1);
ts << "(replicated layer";
if (behavior & LayerTreeAsTextDebug)
- ts << " " << m_replicatedLayer;;
+ ts << " " << m_replicatedLayer;
+ ts << ")\n";
+ }
+
+ if (behavior & LayerTreeAsTextIncludeRepaintRects && repaintRectMap().contains(this) && !repaintRectMap().get(this).isEmpty()) {
+ writeIndent(ts, indent + 1);
+ ts << "(repaint rects\n";
+ for (size_t i = 0; i < repaintRectMap().get(this).size(); ++i) {
+ if (repaintRectMap().get(this)[i].isEmpty())
+ continue;
+ writeIndent(ts, indent + 2);
+ ts << "(rect ";
+ ts << repaintRectMap().get(this)[i].x() << " ";
+ ts << repaintRectMap().get(this)[i].y() << " ";
+ ts << repaintRectMap().get(this)[i].width() << " ";
+ ts << repaintRectMap().get(this)[i].height();
+ ts << ")\n";
+ }
+ writeIndent(ts, indent + 1);
ts << ")\n";
}
@@ -692,7 +744,7 @@ void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer)
if (!layer)
return;
- String output = layer->layerTreeAsText(LayerTreeAsTextDebug | LayerTreeAsTextIncludeVisibleRects);
+ String output = layer->layerTreeAsText(LayerTreeAsTextDebug | LayerTreeAsTextIncludeVisibleRects | LayerTreeAsTextIncludeTileCaches);
fprintf(stderr, "%s\n", output.utf8().data());
}
#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.h b/Source/WebCore/platform/graphics/GraphicsLayer.h
index e67a17eae..e2c82ba1b 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayer.h
+++ b/Source/WebCore/platform/graphics/GraphicsLayer.h
@@ -48,12 +48,15 @@ enum LayerTreeAsTextBehaviorFlags {
LayerTreeAsTextBehaviorNormal = 0,
LayerTreeAsTextDebug = 1 << 0, // Dump extra debugging info like layer addresses.
LayerTreeAsTextIncludeVisibleRects = 1 << 1,
+ LayerTreeAsTextIncludeTileCaches = 1 << 2,
+ LayerTreeAsTextIncludeRepaintRects = 1 << 3
};
typedef unsigned LayerTreeAsTextBehavior;
namespace WebCore {
class FloatPoint3D;
+class FloatRect;
class GraphicsContext;
class GraphicsLayerFactory;
class Image;
@@ -349,24 +352,26 @@ public:
// For hosting this GraphicsLayer in a native layer hierarchy.
virtual PlatformLayer* platformLayer() const { return 0; }
- void dumpLayer(TextStream&, int indent = 0, LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const;
-
- int repaintCount() const { return m_repaintCount; }
- int incrementRepaintCount() { return ++m_repaintCount; }
-
enum CompositingCoordinatesOrientation { CompositingCoordinatesTopDown, CompositingCoordinatesBottomUp };
// Flippedness of the contents of this layer. Does not affect sublayer geometry.
virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_contentsOrientation = orientation; }
CompositingCoordinatesOrientation contentsOrientation() const { return m_contentsOrientation; }
- bool showDebugBorders() const { return m_client ? m_client->showDebugBorders(this) : false; }
- bool showRepaintCounter() const { return m_client ? m_client->showRepaintCounter(this) : false; }
-
- void updateDebugIndicators();
-
+ void dumpLayer(TextStream&, int indent = 0, LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const;
+
+ virtual void setShowDebugBorder(bool show) { m_showDebugBorder = show; }
+ bool isShowingDebugBorder() const { return m_showDebugBorder; }
+
+ virtual void setShowRepaintCounter(bool show) { m_showRepaintCounter = show; }
+ bool isShowingRepaintCounter() const { return m_showRepaintCounter; }
+
+ int repaintCount() const { return m_repaintCount; }
+ int incrementRepaintCount() { return ++m_repaintCount; }
+
virtual void setDebugBackgroundColor(const Color&) { }
virtual void setDebugBorder(const Color&, float /*borderWidth*/) { }
+
// z-position is the z-equivalent of position(). It's only used for debugging purposes.
virtual float zPosition() const { return m_zPosition; }
virtual void setZPosition(float);
@@ -401,7 +406,10 @@ public:
bool usingTiledLayer() const { return m_usingTiledLayer; }
- virtual TiledBacking* tiledBacking() { return 0; }
+ virtual TiledBacking* tiledBacking() const { return 0; }
+
+ void resetTrackedRepaints();
+ void addRepaintRect(const FloatRect&);
#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
// This allows several alternative GraphicsLayer implementations in the same port,
@@ -410,6 +418,8 @@ public:
static void setGraphicsLayerFactory(GraphicsLayerFactoryCallback);
#endif
+ void updateDebugIndicators();
+
protected:
// Should be called from derived class destructors. Should call willBeDestroyed() on super.
virtual void willBeDestroyed();
@@ -480,7 +490,9 @@ protected:
bool m_acceleratesDrawing : 1;
bool m_maintainsPixelAlignment : 1;
bool m_appliesPageScale : 1; // Set for the layer which has the page scale applied to it.
-
+ bool m_showDebugBorder : 1;
+ bool m_showRepaintCounter : 1;
+
GraphicsLayerPaintingPhase m_paintingPhase;
CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents
diff --git a/Source/WebCore/platform/graphics/GraphicsLayerAnimation.cpp b/Source/WebCore/platform/graphics/GraphicsLayerAnimation.cpp
index 3aa25ac40..1b05d3f64 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayerAnimation.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsLayerAnimation.cpp
@@ -22,11 +22,59 @@
#if USE(ACCELERATED_COMPOSITING)
#include "GraphicsLayerAnimation.h"
+#include "FractionalLayoutSize.h"
#include "UnitBezier.h"
#include <wtf/CurrentTime.h>
namespace WebCore {
+#if ENABLE(CSS_FILTERS)
+static inline PassRefPtr<FilterOperation> blendFunc(FilterOperation* fromOp, FilterOperation* toOp, double progress, const IntSize& size, bool blendToPassthrough = false)
+{
+ ASSERT(toOp);
+ if (toOp->blendingNeedsRendererSize())
+ return toOp->blend(fromOp, progress, LayoutSize(size.width(), size.height()), blendToPassthrough);
+
+ return toOp->blend(fromOp, progress, blendToPassthrough);
+}
+
+
+static FilterOperations applyFilterAnimation(const FilterOperations* from, const FilterOperations* to, double progress, const IntSize& boxSize)
+{
+ // First frame of an animation.
+ if (!progress)
+ return *from;
+
+ // Last frame of an animation.
+ if (progress == 1)
+ return *to;
+
+ if (!from->operationsMatch(*to))
+ return *to;
+
+ FilterOperations result;
+
+ size_t fromSize = from->operations().size();
+ size_t toSize = to->operations().size();
+ size_t size = std::max(fromSize, toSize);
+ for (size_t i = 0; i < size; i++) {
+ RefPtr<FilterOperation> fromOp = (i < fromSize) ? from->operations()[i].get() : 0;
+ RefPtr<FilterOperation> toOp = (i < toSize) ? to->operations()[i].get() : 0;
+ RefPtr<FilterOperation> blendedOp = toOp ? blendFunc(fromOp.get(), toOp.get(), progress, boxSize) : (fromOp ? blendFunc(0, fromOp.get(), progress, boxSize, true) : 0);
+ if (blendedOp)
+ result.operations().append(blendedOp);
+ else {
+ RefPtr<FilterOperation> identityOp = PassthroughFilterOperation::create();
+ if (progress > 0.5)
+ result.operations().append(toOp ? toOp : identityOp);
+ else
+ result.operations().append(fromOp ? fromOp : identityOp);
+ }
+ }
+
+ return result;
+}
+#endif
static bool shouldReverseAnimationValue(Animation::AnimationDirection direction, int loopCount)
{
@@ -155,14 +203,23 @@ static TransformationMatrix applyTransformAnimation(const TransformOperations* f
return matrix;
}
+static const TimingFunction* timingFunctionForAnimationValue(const AnimationValue* animValue, const Animation* anim)
+{
+ if (animValue->timingFunction())
+ return animValue->timingFunction();
+ if (anim->timingFunction())
+ return anim->timingFunction().get();
+
+ return CubicBezierTimingFunction::defaultTimingFunction();
+}
-GraphicsLayerAnimation::GraphicsLayerAnimation(const String& name, const KeyframeValueList& keyframes, const IntSize& boxSize, const Animation* animation, double timeOffset, bool listsMatch)
+GraphicsLayerAnimation::GraphicsLayerAnimation(const String& name, const KeyframeValueList& keyframes, const IntSize& boxSize, const Animation* animation, double startTime, bool listsMatch)
: m_keyframes(keyframes)
, m_boxSize(boxSize)
, m_animation(Animation::create(animation))
, m_name(name)
, m_listsMatch(listsMatch)
- , m_startTime(WTF::currentTime() - timeOffset)
+ , m_startTime(startTime)
, m_pauseTime(0)
, m_state(PlayingState)
{
@@ -177,6 +234,11 @@ void GraphicsLayerAnimation::applyInternal(Client* client, const AnimationValue*
case AnimatedPropertyWebkitTransform:
client->setAnimatedTransform(applyTransformAnimation(static_cast<const TransformAnimationValue*>(from)->value(), static_cast<const TransformAnimationValue*>(to)->value(), progress, m_boxSize, m_listsMatch));
return;
+#if ENABLE(CSS_FILTERS)
+ case AnimatedPropertyWebkitFilter:
+ client->setAnimatedFilters(applyFilterAnimation(static_cast<const FilterAnimationValue*>(from)->value(), static_cast<const FilterAnimationValue*>(to)->value(), progress, m_boxSize));
+ return;
+#endif
default:
ASSERT_NOT_REACHED();
}
@@ -233,7 +295,8 @@ void GraphicsLayerAnimation::apply(Client* client)
return;
}
if (m_keyframes.size() == 2) {
- normalizedValue = applyTimingFunction(m_animation->timingFunction().get(), normalizedValue, m_animation->duration());
+ const TimingFunction* timingFunction = timingFunctionForAnimationValue(m_keyframes.at(0), m_animation.get());
+ normalizedValue = applyTimingFunction(timingFunction, normalizedValue, m_animation->duration());
applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), normalizedValue);
return;
}
@@ -245,17 +308,17 @@ void GraphicsLayerAnimation::apply(Client* client)
continue;
normalizedValue = (normalizedValue - from->keyTime()) / (to->keyTime() - from->keyTime());
- normalizedValue = applyTimingFunction(from->timingFunction(), normalizedValue, m_animation->duration());
+ const TimingFunction* timingFunction = timingFunctionForAnimationValue(from, m_animation.get());
+ normalizedValue = applyTimingFunction(timingFunction, normalizedValue, m_animation->duration());
applyInternal(client, from, to, normalizedValue);
break;
}
}
-void GraphicsLayerAnimation::pause(double offset)
+void GraphicsLayerAnimation::pause(double time)
{
- // FIXME: should apply offset here.
setState(PausedState);
- m_pauseTime = WTF::currentTime() - offset;
+ m_pauseTime = time;
}
void GraphicsLayerAnimations::add(const GraphicsLayerAnimation& animation)
@@ -285,6 +348,15 @@ void GraphicsLayerAnimations::apply(GraphicsLayerAnimation::Client* client)
m_animations[i].apply(client);
}
+GraphicsLayerAnimations GraphicsLayerAnimations::getActiveAnimations() const
+{
+ GraphicsLayerAnimations active;
+ for (size_t i = 0; i < m_animations.size(); ++i) {
+ if (m_animations[i].isActive())
+ active.add(m_animations[i]);
+ }
+ return active;
+}
}
#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsLayerAnimation.h b/Source/WebCore/platform/graphics/GraphicsLayerAnimation.h
index e58279c6a..fe4c44a5e 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayerAnimation.h
+++ b/Source/WebCore/platform/graphics/GraphicsLayerAnimation.h
@@ -36,6 +36,9 @@ public:
public:
virtual void setAnimatedTransform(const TransformationMatrix&) = 0;
virtual void setAnimatedOpacity(float) = 0;
+#if ENABLE(CSS_FILTERS)
+ virtual void setAnimatedFilters(const FilterOperations&) = 0;
+#endif
};
GraphicsLayerAnimation()
@@ -45,10 +48,20 @@ public:
void apply(Client*);
void pause(double);
AnimationState state() const { return m_state; }
- void setState(AnimationState s) { m_state = s; }
+ void setState(AnimationState s, double pauseTime = 0)
+ {
+ m_state = s;
+ m_pauseTime = pauseTime;
+ }
AnimatedPropertyID property() const { return m_keyframes.property(); }
bool isActive() const;
String name() const { return m_name; }
+ IntSize boxSize() const { return m_boxSize; }
+ double startTime() const { return m_startTime; }
+ double pauseTime() const { return m_pauseTime; }
+ PassRefPtr<Animation> animation() const { return m_animation.get(); }
+ const KeyframeValueList& keyframes() const { return m_keyframes; }
+ bool listsMatch() const { return m_listsMatch; }
private:
void applyInternal(Client*, const AnimationValue* from, const AnimationValue* to, float progress);
@@ -57,7 +70,6 @@ private:
RefPtr<Animation> m_animation;
String m_name;
bool m_listsMatch;
- bool m_hasBigRotation;
double m_startTime;
double m_pauseTime;
AnimationState m_state;
@@ -72,10 +84,15 @@ public:
void pause(const String&, double);
void apply(GraphicsLayerAnimation::Client*);
bool isEmpty() const { return m_animations.isEmpty(); }
+ size_t size() const { return m_animations.size(); }
+ const Vector<GraphicsLayerAnimation>& animations() const { return m_animations; }
+ Vector<GraphicsLayerAnimation>& animations() { return m_animations; }
bool hasRunningAnimations() const;
bool hasActiveAnimationsOfType(AnimatedPropertyID type) const;
+ GraphicsLayerAnimations getActiveAnimations() const;
+
private:
Vector<GraphicsLayerAnimation> m_animations;
};
diff --git a/Source/WebCore/platform/graphics/GraphicsLayerClient.h b/Source/WebCore/platform/graphics/GraphicsLayerClient.h
index 3e105ce6b..8b6bffd19 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayerClient.h
+++ b/Source/WebCore/platform/graphics/GraphicsLayerClient.h
@@ -82,8 +82,7 @@ public:
// Page scale factor.
virtual float pageScaleFactor() const { return 1; }
- virtual bool showDebugBorders(const GraphicsLayer*) const = 0;
- virtual bool showRepaintCounter(const GraphicsLayer*) const = 0;
+ virtual bool isTrackingRepaints() const { return false; }
#ifndef NDEBUG
// RenderLayerBacking overrides this to verify that it is not
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h
index fe0aee0f6..4b71c3590 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.h
+++ b/Source/WebCore/platform/graphics/ImageBuffer.h
@@ -119,6 +119,8 @@ namespace WebCore {
PlatformLayer* platformLayer() const;
#endif
+ // FIXME: current implementations of this method have the restriction that they only work
+ // with textures that are RGB or RGBA format, and UNSIGNED_BYTE type.
bool copyToPlatformTexture(GraphicsContext3D&, Platform3DObject, GC3Denum, bool, bool);
void reportMemoryUsage(MemoryObjectInfo*) const;
diff --git a/Source/WebCore/platform/graphics/ImageObserver.h b/Source/WebCore/platform/graphics/ImageObserver.h
index 8b693d984..804cdeb97 100644
--- a/Source/WebCore/platform/graphics/ImageObserver.h
+++ b/Source/WebCore/platform/graphics/ImageObserver.h
@@ -26,6 +26,8 @@
#ifndef ImageObserver_h
#define ImageObserver_h
+#include <wtf/Forward.h>
+
namespace WebCore {
class Image;
@@ -44,6 +46,8 @@ public:
virtual void animationAdvanced(const Image*) = 0;
virtual void changedInRect(const Image*, const IntRect&) = 0;
+
+ virtual void reportMemoryUsage(MemoryObjectInfo*) const = 0;
};
}
diff --git a/Source/WebCore/platform/graphics/ImageOrientation.cpp b/Source/WebCore/platform/graphics/ImageOrientation.cpp
index 8a5854e63..dc2b9782b 100644
--- a/Source/WebCore/platform/graphics/ImageOrientation.cpp
+++ b/Source/WebCore/platform/graphics/ImageOrientation.cpp
@@ -41,17 +41,17 @@ AffineTransform ImageOrientation::transformFromDefault(const FloatSize& drawnSiz
case OriginBottomRight:
return AffineTransform(-1, 0, 0, -1, w, h);
case OriginLeftBottom:
- return AffineTransform( 0, 1, -1, 0, w, 0);
- case OriginRightTop:
return AffineTransform( 0, -1, 1, 0, 0, h);
+ case OriginRightTop:
+ return AffineTransform( 0, 1, -1, 0, w, 0);
case OriginTopRight:
return AffineTransform(-1, 0, 0, 1, w, 0);
case OriginBottomLeft:
return AffineTransform( 1, 0, 0, -1, 0, h);
case OriginLeftTop:
- return AffineTransform( 0, -1, -1, 0, w, h);
- case OriginRightBottom:
return AffineTransform( 0, 1, 1, 0, 0, 0);
+ case OriginRightBottom:
+ return AffineTransform( 0, -1, -1, 0, w, h);
}
ASSERT_NOT_REACHED();
return AffineTransform();
diff --git a/Source/WebCore/platform/graphics/ImageOrientation.h b/Source/WebCore/platform/graphics/ImageOrientation.h
index 86be5fe77..b184dc2f7 100644
--- a/Source/WebCore/platform/graphics/ImageOrientation.h
+++ b/Source/WebCore/platform/graphics/ImageOrientation.h
@@ -36,13 +36,13 @@ class FloatSize;
enum ImageOrientationEnum {
// "TopLeft" means that the 0 row starts at the Top, the 0 column starts at the Left.
OriginTopLeft = 1, // default
- OriginTopRight = 2, // mirror along y-axes
+ OriginTopRight = 2, // mirror along y-axis
OriginBottomRight = 3, // 180 degree rotation
- OriginBottomLeft = 4, // mirror along the x-axes
- OriginLeftTop = 5, // -90 degree rotation + mirror along x-axes
- OriginRightTop = 6, // 90 degree rotation
- OriginRightBottom = 7, // 90 degree rotation + mirror along x-axes
- OriginLeftBottom = 8, // -90 degree rotation
+ OriginBottomLeft = 4, // mirror along the x-axis
+ OriginLeftTop = 5, // mirror along x-axis + 270 degree CW rotation
+ OriginRightTop = 6, // 90 degree CW rotation
+ OriginRightBottom = 7, // mirror along x-axis + 90 degree CW rotation
+ OriginLeftBottom = 8, // 270 degree CW rotation
// All other values are "reserved" as of EXIF 2.2
DefaultImageOrientation = OriginTopLeft,
};
@@ -76,6 +76,7 @@ public:
}
// This transform can be used for drawing an image according to the orientation.
+ // It should be used in a right-handed coordinate system.
AffineTransform transformFromDefault(const FloatSize& drawnSize) const;
inline bool operator==(const ImageOrientation& other) const { return other.m_orientation == m_orientation; }
diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp
index abfa5988b..56857a43f 100644
--- a/Source/WebCore/platform/graphics/ImageSource.cpp
+++ b/Source/WebCore/platform/graphics/ImageSource.cpp
@@ -106,20 +106,19 @@ bool ImageSource::isSizeAvailable()
IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
{
- // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
- if (shouldRespectOrientation == RespectImageOrientation)
- notImplemented();
-
- return m_decoder ? m_decoder->size() : IntSize();
+ return frameSizeAtIndex(0, shouldRespectOrientation);
}
IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
{
- // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
- if (shouldRespectOrientation == RespectImageOrientation)
- notImplemented();
+ if (!m_decoder)
+ return IntSize();
+
+ IntSize size = m_decoder->frameSizeAtIndex(index);
+ if ((shouldRespectOrientation == RespectImageOrientation) && m_decoder->orientation().usesWidthAsHeight())
+ return IntSize(size.height(), size.width());
- return m_decoder ? m_decoder->frameSizeAtIndex(index) : IntSize();
+ return size;
}
bool ImageSource::getHotSpot(IntPoint&) const
@@ -182,9 +181,7 @@ float ImageSource::frameDurationAtIndex(size_t index)
ImageOrientation ImageSource::orientationAtIndex(size_t) const
{
- // The JPEG and TIFF decoders need to be taught how to read EXIF, XMP, or IPTC data.
- notImplemented();
- return DefaultImageOrientation;
+ return m_decoder ? m_decoder->orientation() : DefaultImageOrientation;
}
bool ImageSource::frameHasAlphaAtIndex(size_t index)
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h
index be93e8701..bdeaaa0ab 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.h
+++ b/Source/WebCore/platform/graphics/MediaPlayer.h
@@ -193,7 +193,10 @@ public:
virtual String mediaPlayerReferrer() const { return String(); }
virtual String mediaPlayerUserAgent() const { return String(); }
virtual CORSMode mediaPlayerCORSMode() const { return Unspecified; }
+ virtual void mediaPlayerEnterFullscreen() { }
virtual void mediaPlayerExitFullscreen() { }
+ virtual bool mediaPlayerIsFullscreen() const { return false; }
+ virtual bool mediaPlayerIsFullscreenPermitted() const { return false; }
virtual bool mediaPlayerIsVideo() const { return false; }
virtual LayoutRect mediaPlayerContentBoxRect() const { return LayoutRect(); }
virtual void mediaPlayerSetSize(const IntSize&) { }
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.cpp b/Source/WebCore/platform/graphics/SimpleFontData.cpp
index 28fa5ab15..9e19a8298 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/Source/WebCore/platform/graphics/SimpleFontData.cpp
@@ -41,6 +41,9 @@ using namespace std;
namespace WebCore {
+const float smallCapsFontSizeMultiplier = 0.7f;
+const float emphasisMarkFontSizeMultiplier = 0.5f;
+
SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCustomFont, bool isLoading, bool isTextOrientationFallback)
: m_maxCharWidth(-1)
, m_avgCharWidth(-1)
@@ -193,6 +196,26 @@ PassRefPtr<SimpleFontData> SimpleFontData::uprightOrientationFontData() const
return m_derivedFontData->uprightOrientation;
}
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+{
+ if (!m_derivedFontData)
+ m_derivedFontData = DerivedFontData::create(isCustomFont());
+ if (!m_derivedFontData->smallCaps)
+ m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFontSizeMultiplier);
+
+ return m_derivedFontData->smallCaps;
+}
+
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+ if (!m_derivedFontData)
+ m_derivedFontData = DerivedFontData::create(isCustomFont());
+ if (!m_derivedFontData->emphasisMark)
+ m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, emphasisMarkFontSizeMultiplier);
+
+ return m_derivedFontData->emphasisMark;
+}
+
PassRefPtr<SimpleFontData> SimpleFontData::brokenIdeographFontData() const
{
if (!m_derivedFontData)
diff --git a/Source/WebCore/platform/graphics/TiledBacking.h b/Source/WebCore/platform/graphics/TiledBacking.h
index 4108f122b..5187bdd4a 100644
--- a/Source/WebCore/platform/graphics/TiledBacking.h
+++ b/Source/WebCore/platform/graphics/TiledBacking.h
@@ -43,6 +43,7 @@ public:
CoverageForVisibleArea = 0,
CoverageForVerticalScrolling = 1 << 0,
CoverageForHorizontalScrolling = 1 << 1,
+ CoverageForSlowScrolling = 1 << 2, // Indicates that we expect to paint a lot on scrolling.
CoverageForScrolling = CoverageForVerticalScrolling | CoverageForHorizontalScrolling
};
typedef unsigned TileCoverage;
@@ -50,10 +51,16 @@ public:
virtual void setTileCoverage(TileCoverage) = 0;
virtual TileCoverage tileCoverage() const = 0;
+ virtual IntSize tileSize() const = 0;
+
virtual void forceRepaint() = 0;
virtual void setScrollingPerformanceLoggingEnabled(bool) = 0;
virtual bool scrollingPerformanceLoggingEnabled() const = 0;
+
+ // Exposed for testing
+ virtual IntRect tileCoverageRect() const = 0;
+
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
index 5d9ddd9cb..c16e8d062 100644
--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
@@ -1089,7 +1089,10 @@ MediaPlayer::MediaKeyException MediaPlayerPrivateAVFoundationObjC::addKey(const
RetainPtr<AVAssetResourceLoadingRequest> avRequest = m_sessionIDToRequestMap.get(sessionID);
RetainPtr<NSData> keyData = adoptNS([[NSData alloc] initWithBytes:keyPtr length:keyLength]);
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[avRequest.get() finishLoadingWithResponse:nil data:keyData.get() redirect:nil];
+#pragma clang diagnostic pop
m_sessionIDToRequestMap.remove(sessionID);
player()->keyAdded(keySystem, sessionID);
diff --git a/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp
index c1a703acd..12fc69df8 100644
--- a/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp
@@ -379,20 +379,26 @@ void GraphicsLayerBlackBerry::setOpacity(float opacity)
void GraphicsLayerBlackBerry::setContentsNeedsDisplay()
{
- if (m_contentsLayer)
+ if (m_contentsLayer) {
m_contentsLayer->setNeedsDisplay();
+ addRepaintRect(contentsRect());
+ }
}
void GraphicsLayerBlackBerry::setNeedsDisplay()
{
- if (drawsContent())
+ if (drawsContent()) {
m_layer->setNeedsDisplay();
+ addRepaintRect(FloatRect(FloatPoint(), m_size));
+ }
}
void GraphicsLayerBlackBerry::setNeedsDisplayInRect(const FloatRect& rect)
{
- if (drawsContent())
+ if (drawsContent()) {
m_layer->setNeedsDisplayInRect(rect);
+ addRepaintRect(rect);
+ }
}
void GraphicsLayerBlackBerry::setContentsRect(const IntRect& rect)
diff --git a/Source/WebCore/platform/graphics/blackberry/ImageBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/ImageBlackBerry.cpp
index 8793298d1..07da9915e 100644
--- a/Source/WebCore/platform/graphics/blackberry/ImageBlackBerry.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/ImageBlackBerry.cpp
@@ -23,17 +23,20 @@
#include "ImageBuffer.h"
#include "SharedBuffer.h"
+#include <BlackBerryPlatformResourceStore.h>
+
+using BlackBerry::Platform::ResourceData;
+using BlackBerry::Platform::ResourceStore;
+
namespace WebCore {
PassRefPtr<Image> Image::loadPlatformResource(const char *name)
{
- // RESOURCE_PATH is set by CMake in OptionsBlackBerry.cmake
- String fullPath(RESOURCE_PATH);
- String extension(".png");
-
- fullPath = fullPath + name + extension;
+ ResourceData data = ResourceStore::instance()->requestResource(BlackBerry::Platform::String(name));
+ if (!data.data())
+ return BitmapImage::nullImage();
- RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(fullPath);
+ RefPtr<SharedBuffer> buffer = SharedBuffer::create(data.data(), data.len());
if (!buffer)
return BitmapImage::nullImage();
diff --git a/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp b/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp
index 4fd63cedd..ff86f38e1 100644
--- a/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp
@@ -47,8 +47,6 @@
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
-#define ENABLE_SCISSOR 1
-
#define DEBUG_LAYER_ANIMATIONS 0 // Show running animations as green.
#define DEBUG_CLIPPING 0
@@ -159,6 +157,7 @@ LayerRenderer::LayerRenderer(GLES2Context* context)
, m_context(context)
, m_isRobustnessSupported(false)
, m_needsCommit(false)
+ , m_stencilCleared(false)
{
if (makeContextCurrent()) {
m_isRobustnessSupported = String(reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS))).contains("GL_EXT_robustness");
@@ -279,7 +278,7 @@ void LayerRenderer::setViewport(const IntRect& targetRect, const IntRect& clipRe
glActiveTexture(GL_TEXTURE0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
- glEnable(GL_STENCIL_TEST);
+ glDisable(GL_STENCIL_TEST);
// If culling is enabled then we will cull the backface.
glCullFace(GL_BACK);
@@ -300,21 +299,18 @@ void LayerRenderer::setViewport(const IntRect& targetRect, const IntRect& clipRe
glViewport(m_viewport.x(), m_viewport.y(), m_viewport.width(), m_viewport.height());
-#if ENABLE_SCISSOR
glEnable(GL_SCISSOR_TEST);
#if DEBUG_CLIPPING
printf("LayerRenderer::compositeLayers(): clipping to (%d,%d %dx%d)\n", m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height());
fflush(stdout);
#endif
glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height());
-#endif
- glClearStencil(0);
- glClearColor(0, 0, 0, 0);
- GLenum buffersToClear = GL_STENCIL_BUFFER_BIT;
- if (m_clearSurfaceOnDrawLayers)
- buffersToClear |= GL_COLOR_BUFFER_BIT;
- glClear(buffersToClear);
+ if (m_clearSurfaceOnDrawLayers) {
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ m_stencilCleared = false;
}
void LayerRenderer::compositeLayers(const TransformationMatrix& matrix, LayerCompositingThread* rootLayer)
@@ -378,9 +374,7 @@ void LayerRenderer::compositeLayers(const TransformationMatrix& matrix, LayerCom
m_context->swapBuffers();
-#if ENABLE_SCISSOR
glDisable(GL_SCISSOR_TEST);
-#endif
glDisable(GL_STENCIL_TEST);
// PR 147254, the EGL implementation crashes when the last bound texture
@@ -523,10 +517,8 @@ void LayerRenderer::drawLayersOnSurfaces(const Vector<RefPtr<LayerCompositingThr
// Otherwise, we just need to set viewport.
if (surfaceLayers.size()) {
useSurface(0);
-#if ENABLE_SCISSOR
glEnable(GL_SCISSOR_TEST);
glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height());
-#endif
}
}
@@ -851,9 +843,6 @@ void LayerRenderer::compositeLayersRecursive(LayerCompositingThread* layer, int
layer->setVisible(layerVisible);
- glStencilFunc(GL_EQUAL, stencilValue, 0xff);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
// Note that there are two types of layers:
// 1. Layers that have their own GraphicsContext and can draw their contents on demand (layer->drawsContent() == true).
// 2. Layers that are just containers of images/video/etc that don't own a GraphicsContext (layer->contents() == true).
@@ -861,6 +850,11 @@ void LayerRenderer::compositeLayersRecursive(LayerCompositingThread* layer, int
if ((layer->needsTexture() || layer->layerRendererSurface()) && layerVisible) {
updateScissorIfNeeded(clipRect);
+ if (stencilValue) {
+ glStencilFunc(GL_EQUAL, stencilValue, 0xff);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ }
+
if (layer->doubleSided())
glDisable(GL_CULL_FACE);
else
@@ -918,13 +912,16 @@ void LayerRenderer::compositeLayersRecursive(LayerCompositingThread* layer, int
// If we need to mask to bounds but the transformation has a rotational component
// to it, scissoring is not enough and we need to use the stencil buffer for clipping.
-#if ENABLE_SCISSOR
bool stencilClip = layer->masksToBounds() && hasRotationalComponent(layer->drawTransform());
-#else
- bool stencilClip = layer->masksToBounds();
-#endif
if (stencilClip) {
+ if (!m_stencilCleared) {
+ glClearStencil(0);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ m_stencilCleared = true;
+ }
+
+ glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, stencilValue, 0xff);
glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
@@ -977,12 +974,14 @@ void LayerRenderer::compositeLayersRecursive(LayerCompositingThread* layer, int
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, &layer->getTransformedBounds());
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ if (!stencilValue)
+ glDisable(GL_STENCIL_TEST);
}
}
void LayerRenderer::updateScissorIfNeeded(const FloatRect& clipRect)
{
-#if ENABLE_SCISSOR
#if DEBUG_CLIPPING
printf("LayerRenderer::updateScissorIfNeeded(): clipRect=(%.2f,%.2f %.2fx%.2f)\n", clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height());
fflush(stdout);
@@ -997,7 +996,6 @@ void LayerRenderer::updateScissorIfNeeded(const FloatRect& clipRect)
fflush(stdout);
#endif
glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height());
-#endif
}
bool LayerRenderer::makeContextCurrent()
diff --git a/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h b/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h
index 353b7eca8..671c4a18d 100644
--- a/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h
+++ b/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h
@@ -212,6 +212,7 @@ private:
LayerRenderingResults m_lastRenderingResults;
bool m_needsCommit;
+ bool m_stencilCleared;
};
}
diff --git a/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp b/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp
index 142991cf5..5c0375356 100644
--- a/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp
@@ -417,6 +417,7 @@ bool LayerWebKitThread::filtersCanBeComposited(const FilterOperations& filters)
case FilterOperation::REFERENCE:
#if ENABLE(CSS_SHADERS)
case FilterOperation::CUSTOM:
+ case FilterOperation::VALIDATED_CUSTOM:
#endif
return false;
default:
diff --git a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
index ea3c89550..7a9e484b5 100644
--- a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
@@ -39,6 +39,7 @@
#include "TimeRanges.h"
#include "WebPageClient.h"
+#include <BlackBerryPlatformDeviceInfo.h>
#include <BlackBerryPlatformSettings.h>
#include <FrameLoaderClientBlackBerry.h>
#include <set>
@@ -113,6 +114,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
#endif
, m_userDrivenSeekTimer(this, &MediaPlayerPrivate::userDrivenSeekTimerFired)
, m_lastSeekTime(0)
+ , m_lastLoadingTime(0)
, m_lastSeekTimePending(false)
, m_isAuthenticationChallenging(false)
, m_waitMetadataTimer(this, &MediaPlayerPrivate::waitMetadataTimerFired)
@@ -187,8 +189,11 @@ void MediaPlayerPrivate::prepareToPlay()
void MediaPlayerPrivate::play()
{
- if (m_platformPlayer)
+ if (m_platformPlayer) {
m_platformPlayer->play();
+ if (m_platformPlayer->isMetadataReady())
+ conditionallyGoFullscreenAfterPlay();
+ }
}
void MediaPlayerPrivate::pause()
@@ -336,8 +341,15 @@ PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
bool MediaPlayerPrivate::didLoadingProgress() const
{
- notImplemented();
- return false;
+ if (!m_platformPlayer)
+ return false;
+
+ float bufferLoaded = m_platformPlayer->bufferLoaded();
+ if (bufferLoaded == m_lastLoadingTime)
+ return false;
+
+ m_lastLoadingTime = bufferLoaded;
+ return true;
}
void MediaPlayerPrivate::setSize(const IntSize&)
@@ -663,6 +675,7 @@ void MediaPlayerPrivate::waitMetadataTimerFired(Timer<MediaPlayerPrivate>*)
{
if (m_platformPlayer->isMetadataReady()) {
m_platformPlayer->playWithMetadataReady();
+ conditionallyGoFullscreenAfterPlay();
m_waitMetadataPopDialogCounter = 0;
return;
}
@@ -679,9 +692,10 @@ void MediaPlayerPrivate::waitMetadataTimerFired(Timer<MediaPlayerPrivate>*)
if (!wait)
onPauseNotified();
else {
- if (m_platformPlayer->isMetadataReady())
+ if (m_platformPlayer->isMetadataReady()) {
m_platformPlayer->playWithMetadataReady();
- else
+ conditionallyGoFullscreenAfterPlay();
+ } else
m_waitMetadataTimer.startOneShot(checkMetadataReadyInterval);
}
}
@@ -963,6 +977,29 @@ void MediaPlayerPrivate::drawBufferingAnimation(const TransformationMatrix& matr
}
#endif
+void MediaPlayerPrivate::conditionallyGoFullscreenAfterPlay()
+{
+ BlackBerry::Platform::DeviceInfo* info = BlackBerry::Platform::DeviceInfo::instance();
+ if (hasVideo() && m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsFullscreenPermitted() && info->isMobile()) {
+ // This is a mobile device (small screen), not a tablet, so we
+ // enter fullscreen video on user-initiated plays.
+ bool nothingIsFullscreen = !m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsFullscreen();
+#if ENABLE(FULLSCREEN_API)
+ if (m_webCorePlayer->mediaPlayerClient()->mediaPlayerOwningDocument()->webkitIsFullScreen())
+ nothingIsFullscreen = false;
+#endif
+ if (nothingIsFullscreen && currentTime() == 0.0f) {
+ // Only enter fullscreen when playing from the beginning. Doing
+ // so on every play is sure to annoy the user who does not want
+ // to watch the video fullscreen. Note that the following call
+ // will fail if we are not here due to a user gesture, as per the
+ // check in Document::requestFullScreenForElement() to prevent
+ // popups.
+ m_webCorePlayer->mediaPlayerClient()->mediaPlayerEnterFullscreen();
+ }
+ }
+}
+
} // namespace WebCore
#endif // ENABLE(VIDEO)
diff --git a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
index 7b6654dce..c055abc5e 100644
--- a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
+++ b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
@@ -170,9 +170,11 @@ private:
bool m_mediaIsBuffering;
#endif
+ void conditionallyGoFullscreenAfterPlay();
void userDrivenSeekTimerFired(Timer<MediaPlayerPrivate>*);
Timer<MediaPlayerPrivate> m_userDrivenSeekTimer;
float m_lastSeekTime;
+ mutable float m_lastLoadingTime;
bool m_lastSeekTimePending;
bool m_isAuthenticationChallenging;
void waitMetadataTimerFired(Timer<MediaPlayerPrivate>*);
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
index a74bb1cd0..e36b5e707 100644
--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
@@ -286,8 +286,6 @@ GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
}
m_layer = PlatformCALayer::create(layerType, this);
-
- updateDebugIndicators();
noteLayerPropertyChanged(ContentsScaleChanged);
}
@@ -520,7 +518,7 @@ void GraphicsLayerCA::setMasksToBounds(bool masksToBounds)
return;
GraphicsLayer::setMasksToBounds(masksToBounds);
- noteLayerPropertyChanged(MasksToBoundsChanged);
+ noteLayerPropertyChanged(MasksToBoundsChanged | DebugIndicatorsChanged);
}
void GraphicsLayerCA::setDrawsContent(bool drawsContent)
@@ -529,7 +527,7 @@ void GraphicsLayerCA::setDrawsContent(bool drawsContent)
return;
GraphicsLayer::setDrawsContent(drawsContent);
- noteLayerPropertyChanged(DrawsContentChanged);
+ noteLayerPropertyChanged(DrawsContentChanged | DebugIndicatorsChanged);
}
void GraphicsLayerCA::setContentsVisible(bool contentsVisible)
@@ -670,6 +668,8 @@ void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& r)
m_dirtyRects[0].unite(rect);
noteLayerPropertyChanged(DirtyRectsChanged);
+
+ addRepaintRect(rect);
}
void GraphicsLayerCA::setContentsNeedsDisplay()
@@ -910,7 +910,7 @@ void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
commitLayerChangesAfterSublayers();
}
-TiledBacking* GraphicsLayerCA::tiledBacking()
+TiledBacking* GraphicsLayerCA::tiledBacking() const
{
return m_layer->tiledBacking();
}
@@ -943,11 +943,14 @@ FloatRect GraphicsLayerCA::computeVisibleRect(TransformState& state) const
}
}
- state.applyTransform(layerTransform, accumulation);
+ bool applyWasClamped;
+ state.applyTransform(layerTransform, accumulation, &applyWasClamped);
- FloatRect clipRectForChildren = state.mappedQuad().boundingBox();
+ bool mapWasClamped;
+ FloatRect clipRectForChildren = state.mappedQuad(&mapWasClamped).boundingBox();
FloatRect clipRectForSelf(0, 0, m_size.width(), m_size.height());
- clipRectForSelf.intersect(clipRectForChildren);
+ if (!applyWasClamped && !mapWasClamped)
+ clipRectForSelf.intersect(clipRectForChildren);
if (masksToBounds()) {
ASSERT(accumulation == TransformState::FlattenTransform);
@@ -1039,7 +1042,7 @@ bool GraphicsLayerCA::platformCALayerShowRepaintCounter(PlatformCALayer* platfor
if (m_isPageTileCacheLayer && platformLayer)
return false;
- return showRepaintCounter();
+ return isShowingRepaintCounter();
}
void GraphicsLayerCA::platformCALayerPaintContents(GraphicsContext& context, const IntRect& clip)
@@ -1146,6 +1149,9 @@ void GraphicsLayerCA::commitLayerChangesBeforeSublayers(float pageScaleFactor, c
if (m_uncommittedChanges & AcceleratesDrawingChanged)
updateAcceleratesDrawing();
+ if (m_uncommittedChanges & DebugIndicatorsChanged)
+ updateDebugBorder();
+
if (m_uncommittedChanges & ChildrenChanged) {
updateSublayerList();
// Sublayers may set this flag again, so clear it to avoid always updating sublayers in commitLayerChangesAfterSublayers().
@@ -1184,54 +1190,47 @@ void GraphicsLayerCA::updateLayerNames()
void GraphicsLayerCA::updateSublayerList()
{
- PlatformCALayerList newSublayers;
- const Vector<GraphicsLayer*>& childLayers = children();
+ const PlatformCALayerList* customSublayers = m_layer->customSublayers();
- if (const PlatformCALayerList* customSublayers = m_layer->customSublayers())
- newSublayers.appendRange(customSublayers->begin(), customSublayers->end());
+ PlatformCALayerList structuralLayerChildren;
+ PlatformCALayerList primaryLayerChildren;
+
+ PlatformCALayerList& childListForSublayers = m_structuralLayer ? structuralLayerChildren : primaryLayerChildren;
+
+ if (customSublayers)
+ primaryLayerChildren.append(*customSublayers);
+
+ if (m_structuralLayer) {
+ if (m_replicaLayer)
+ structuralLayerChildren.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
- if (m_structuralLayer || m_contentsLayer || childLayers.size() > 0) {
- if (m_structuralLayer) {
- // Add the replica layer first.
- if (m_replicaLayer)
- newSublayers.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
- // Add the primary layer. Even if we have negative z-order children, the primary layer always comes behind.
- newSublayers.append(m_layer);
- } else if (m_contentsLayer && m_contentsVisible) {
- // FIXME: add the contents layer in the correct order with negative z-order children.
- // This does not cause visible rendering issues because currently contents layers are only used
- // for replaced elements that don't have children.
- newSublayers.append(m_contentsLayer);
- }
-
- size_t numChildren = childLayers.size();
- for (size_t i = 0; i < numChildren; ++i) {
- GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
- PlatformCALayer* childLayer = curChild->layerForSuperlayer();
- newSublayers.append(childLayer);
- }
+ structuralLayerChildren.append(m_layer);
+ }
- for (size_t i = 0; i < newSublayers.size(); --i)
- newSublayers[i]->removeFromSuperlayer();
+ if (m_contentsLayer && m_contentsVisible) {
+ // FIXME: add the contents layer in the correct order with negative z-order children.
+ // This does not cause visible rendering issues because currently contents layers are only used
+ // for replaced elements that don't have children.
+ primaryLayerChildren.append(m_contentsLayer);
}
+ const Vector<GraphicsLayer*>& childLayers = children();
+ size_t numChildren = childLayers.size();
+ for (size_t i = 0; i < numChildren; ++i) {
+ GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+ PlatformCALayer* childLayer = curChild->layerForSuperlayer();
+ childListForSublayers.append(childLayer);
+ }
+
#ifdef VISIBLE_TILE_WASH
if (m_visibleTileWashLayer)
- newSublayers.append(m_visibleTileWashLayer);
+ childListForSublayers.append(m_visibleTileWashLayer);
#endif
- if (m_structuralLayer) {
- m_structuralLayer->setSublayers(newSublayers);
-
- if (m_contentsLayer) {
- // If we have a transform layer, then the contents layer is parented in the
- // primary layer (which is itself a child of the transform layer).
- m_layer->removeAllSublayers();
- if (m_contentsVisible)
- m_layer->appendSublayer(m_contentsLayer.get());
- }
- } else
- m_layer->setSublayers(newSublayers);
+ if (m_structuralLayer)
+ m_structuralLayer->setSublayers(structuralLayerChildren);
+
+ m_layer->setSublayers(primaryLayerChildren);
}
void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& positionRelativeToBase)
@@ -1345,8 +1344,6 @@ void GraphicsLayerCA::updateMasksToBounds()
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
it->value->setMasksToBounds(m_masksToBounds);
}
-
- updateDebugIndicators();
}
void GraphicsLayerCA::updateContentsVisibility()
@@ -1356,7 +1353,7 @@ void GraphicsLayerCA::updateContentsVisibility()
if (m_drawsContent)
m_layer->setNeedsDisplay();
} else {
- m_layer.get()->setContents(0);
+ m_layer->setContents(0);
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
@@ -1368,7 +1365,7 @@ void GraphicsLayerCA::updateContentsVisibility()
void GraphicsLayerCA::updateContentsOpaque()
{
- m_layer.get()->setOpaque(m_contentsOpaque);
+ m_layer->setOpaque(m_contentsOpaque);
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
@@ -1401,9 +1398,9 @@ void GraphicsLayerCA::updateBackfaceVisibility()
#if ENABLE(CSS_FILTERS)
void GraphicsLayerCA::updateFilters()
{
- primaryLayer()->setFilters(m_filters);
+ m_layer->setFilters(m_filters);
- if (LayerMap* layerCloneMap = primaryLayerClones()) {
+ if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
if (m_replicaLayer && isReplicatedRootClone(it->key))
@@ -1530,7 +1527,6 @@ void GraphicsLayerCA::updateLayerDrawsContent(float pageScaleFactor, const Float
it->value->setContents(0);
}
}
- updateDebugIndicators();
}
void GraphicsLayerCA::updateAcceleratesDrawing()
@@ -1538,6 +1534,14 @@ void GraphicsLayerCA::updateAcceleratesDrawing()
m_layer->setAcceleratesDrawing(m_acceleratesDrawing);
}
+void GraphicsLayerCA::updateDebugBorder()
+{
+ if (isShowingDebugBorder())
+ updateDebugIndicators();
+ else
+ m_layer->setBorderWidth(0);
+}
+
FloatRect GraphicsLayerCA::adjustTiledLayerVisibleRect(TiledBacking* tiledBacking, const FloatRect& oldVisibleRect, const FloatSize& oldSize) const
{
// If the old visible rect is empty, we have no information about how the visible area is changing
@@ -1600,10 +1604,13 @@ FloatRect GraphicsLayerCA::adjustTiledLayerVisibleRect(TiledBacking* tiledBackin
void GraphicsLayerCA::updateVisibleRect(const FloatRect& oldVisibleRect)
{
- if (m_layer->layerType() != PlatformCALayer::LayerTypeTileCacheLayer)
+ if (!m_layer->usesTileCacheLayer())
return;
- FloatRect tileArea = adjustTiledLayerVisibleRect(tiledBacking(), oldVisibleRect, m_sizeAtLastVisibleRectUpdate);
+ FloatRect tileArea = m_visibleRect;
+ if (m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer)
+ tileArea = adjustTiledLayerVisibleRect(tiledBacking(), oldVisibleRect, m_sizeAtLastVisibleRectUpdate);
+
tiledBacking()->setVisibleRect(enclosingIntRect(tileArea));
m_sizeAtLastVisibleRectUpdate = m_size;
@@ -2497,6 +2504,24 @@ void GraphicsLayerCA::updateContentsScale(float pageScaleFactor, const FloatPoin
m_layer->setNeedsDisplay();
}
+void GraphicsLayerCA::setShowDebugBorder(bool showBorder)
+{
+ if (showBorder == m_showDebugBorder)
+ return;
+
+ GraphicsLayer::setShowDebugBorder(showBorder);
+ noteLayerPropertyChanged(DebugIndicatorsChanged);
+}
+
+void GraphicsLayerCA::setShowRepaintCounter(bool showCounter)
+{
+ if (showCounter == m_showRepaintCounter)
+ return;
+
+ GraphicsLayer::setShowRepaintCounter(showCounter);
+ noteLayerPropertyChanged(DebugIndicatorsChanged);
+}
+
void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
{
if (color.isValid())
@@ -2522,6 +2547,16 @@ void GraphicsLayerCA::dumpAdditionalProperties(TextStream& textStream, int inden
writeIndent(textStream, indent + 1);
textStream << "(visible rect " << m_visibleRect.x() << ", " << m_visibleRect.y() << " " << m_visibleRect.width() << " x " << m_visibleRect.height() << ")\n";
}
+
+ if (tiledBacking() && (behavior & LayerTreeAsTextIncludeTileCaches)) {
+ IntRect tileCoverageRect = tiledBacking()->tileCoverageRect();
+ writeIndent(textStream, indent + 1);
+ textStream << "(tile cache coverage " << tileCoverageRect.x() << ", " << tileCoverageRect.y() << " " << tileCoverageRect.width() << " x " << tileCoverageRect.height() << ")\n";
+
+ IntSize tileSize = tiledBacking()->tileSize();
+ writeIndent(textStream, indent + 1);
+ textStream << "(tile size " << tileSize.width() << " x " << tileSize.height() << ")\n";
+ }
}
void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
@@ -2600,10 +2635,9 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer, float /*pageSca
| BackgroundColorChanged
| ContentsScaleChanged
| AcceleratesDrawingChanged
-#if ENABLE(CSS_FILTERS)
| FiltersChanged
-#endif
- | OpacityChanged;
+ | OpacityChanged
+ | DebugIndicatorsChanged;
#ifndef NDEBUG
String name = String::format("%sCALayer(%p) GraphicsLayer(%p) ", (m_layer->layerType() == PlatformCALayer::LayerTypeWebTiledLayer) ? "Tiled " : "", m_layer->platformLayer(), this) + m_name;
@@ -2615,8 +2649,6 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer, float /*pageSca
// need to tell new layer to draw itself
setNeedsDisplay();
-
- updateDebugIndicators();
}
GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerCA::defaultContentsOrientation() const
@@ -2640,7 +2672,7 @@ void GraphicsLayerCA::setupContentsLayer(PlatformCALayer* contentsLayer)
} else
contentsLayer->setAnchorPoint(FloatPoint3D());
- if (showDebugBorders()) {
+ if (isShowingDebugBorder()) {
contentsLayer->setBorderColor(Color(0, 0, 128, 180));
contentsLayer->setBorderWidth(1.0f);
}
@@ -2828,13 +2860,14 @@ PassRefPtr<PlatformCALayer> GraphicsLayerCA::cloneLayer(PlatformCALayer *layer,
newLayer->setOpaque(layer->isOpaque());
newLayer->setBackgroundColor(layer->backgroundColor());
newLayer->setContentsScale(layer->contentsScale());
+ newLayer->copyFiltersFrom(layer);
if (cloneLevel == IntermediateCloneLevel) {
newLayer->setOpacity(layer->opacity());
moveOrCopyAnimations(Copy, layer, newLayer.get());
}
- if (showDebugBorders()) {
+ if (isShowingDebugBorder()) {
newLayer->setBorderColor(Color(255, 122, 251));
newLayer->setBorderWidth(2);
}
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
index c6b210e5b..2deb2e28c 100644
--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
@@ -121,6 +121,9 @@ public:
virtual bool hasContentsLayer() const { return m_contentsLayer; }
+ virtual void setShowDebugBorder(bool) OVERRIDE;
+ virtual void setShowRepaintCounter(bool) OVERRIDE;
+
virtual void setDebugBackgroundColor(const Color&);
virtual void setDebugBorder(const Color&, float borderWidth);
@@ -134,7 +137,7 @@ public:
virtual void flushCompositingState(const FloatRect&);
virtual void flushCompositingStateForThisLayerOnly();
- virtual TiledBacking* tiledBacking() OVERRIDE;
+ virtual TiledBacking* tiledBacking() const OVERRIDE;
bool allowTiledLayer() const { return m_allowTiledLayer; }
virtual void setAllowTiledLayer(bool b);
@@ -152,7 +155,7 @@ private:
virtual void platformCALayerAnimationStarted(CFTimeInterval beginTime);
virtual CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return contentsOrientation(); }
virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& clip);
- virtual bool platformCALayerShowDebugBorders() const { return showDebugBorders(); }
+ virtual bool platformCALayerShowDebugBorders() const { return isShowingDebugBorder(); }
virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const;
virtual int platformCALayerIncrementRepaintCount() { return incrementRepaintCount(); }
@@ -326,6 +329,7 @@ private:
void updateLayerAnimations();
void updateContentsNeedsDisplay();
void updateAcceleratesDrawing();
+ void updateDebugBorder();
void updateVisibleRect(const FloatRect& oldVisibleRect);
void updateContentsScale(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase);
@@ -377,9 +381,8 @@ private:
ContentsScaleChanged = 1 << 23,
ContentsVisibilityChanged = 1 << 24,
VisibleRectChanged = 1 << 25,
-#if ENABLE(CSS_FILTERS)
FiltersChanged = 1 << 26,
-#endif
+ DebugIndicatorsChanged = 1 << 27
};
typedef unsigned LayerChangeFlags;
void noteLayerPropertyChanged(LayerChangeFlags flags);
diff --git a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h
index 520711681..6b0591032 100644
--- a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h
+++ b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h
@@ -189,6 +189,7 @@ public:
#if ENABLE(CSS_FILTERS)
void setFilters(const FilterOperations&);
static bool filtersCanBeComposited(const FilterOperations&);
+ void copyFiltersFrom(const PlatformCALayer*);
#endif
String name() const;
diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
index 1659c4dca..408766404 100644
--- a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
+++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
@@ -715,7 +715,6 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
[m_layer.get() setShadowRadius:op->stdDeviation()];
[m_layer.get() setShadowOpacity:1];
-
break;
}
case FilterOperation::GRAYSCALE: {
@@ -838,6 +837,13 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
END_BLOCK_OBJC_EXCEPTIONS
}
+void PlatformCALayer::copyFiltersFrom(const PlatformCALayer* sourceLayer)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [m_layer.get() setFilters:[sourceLayer->platformLayer() filters]];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
bool PlatformCALayer::filtersCanBeComposited(const FilterOperations& filters)
{
// Return false if there are no filters to avoid needless work
@@ -850,6 +856,7 @@ bool PlatformCALayer::filtersCanBeComposited(const FilterOperations& filters)
case FilterOperation::REFERENCE:
#if ENABLE(CSS_SHADERS)
case FilterOperation::CUSTOM:
+ case FilterOperation::VALIDATED_CUSTOM:
#endif
return false;
case FilterOperation::DROP_SHADOW:
diff --git a/Source/WebCore/platform/graphics/ca/mac/TileCache.h b/Source/WebCore/platform/graphics/ca/mac/TileCache.h
index 17e98ee3c..32573c70d 100644
--- a/Source/WebCore/platform/graphics/ca/mac/TileCache.h
+++ b/Source/WebCore/platform/graphics/ca/mac/TileCache.h
@@ -51,7 +51,7 @@ class TileCache : public TiledBacking {
WTF_MAKE_NONCOPYABLE(TileCache);
public:
- static PassOwnPtr<TileCache> create(WebTileCacheLayer*, const IntSize& tileSize);
+ static PassOwnPtr<TileCache> create(WebTileCacheLayer*);
~TileCache();
void tileCacheLayerBoundsChanged();
@@ -79,7 +79,7 @@ public:
static unsigned blankPixelCountForTiles(const WebTileLayerList&, IntRect, IntPoint);
private:
- TileCache(WebTileCacheLayer*, const IntSize& tileSize);
+ TileCache(WebTileCacheLayer*);
// TiledBacking member functions.
virtual void setVisibleRect(const IntRect&) OVERRIDE;
@@ -87,8 +87,10 @@ private:
virtual void setTileCoverage(TileCoverage) OVERRIDE;
virtual TileCoverage tileCoverage() const OVERRIDE { return m_tileCoverage; }
virtual void forceRepaint() OVERRIDE;
+ virtual IntSize tileSize() const OVERRIDE { return m_tileSize; }
virtual void setScrollingPerformanceLoggingEnabled(bool flag) OVERRIDE { m_scrollingPerformanceLoggingEnabled = flag; }
virtual bool scrollingPerformanceLoggingEnabled() const OVERRIDE { return m_scrollingPerformanceLoggingEnabled; }
+ virtual IntRect tileCoverageRect() const;
IntRect bounds() const;
@@ -96,7 +98,8 @@ private:
IntRect rectForTileIndex(const TileIndex&) const;
void getTileIndexRangeForRect(const IntRect&, TileIndex& topLeft, TileIndex& bottomRight);
- IntRect tileCoverageRect() const;
+ IntRect computeTileCoverageRect() const;
+ IntSize tileSizeForCoverageRect(const IntRect&) const;
void scheduleTileRevalidation(double interval);
void tileRevalidationTimerFired(Timer<TileCache>*);
@@ -110,7 +113,7 @@ private:
WebTileCacheLayer* m_tileCacheLayer;
RetainPtr<CALayer> m_tileContainerLayer;
- const IntSize m_tileSize;
+ IntSize m_tileSize;
IntRect m_visibleRect;
typedef HashMap<TileIndex, RetainPtr<WebTileLayer> > TileMap;
diff --git a/Source/WebCore/platform/graphics/ca/mac/TileCache.mm b/Source/WebCore/platform/graphics/ca/mac/TileCache.mm
index 619244da9..9638f088a 100644
--- a/Source/WebCore/platform/graphics/ca/mac/TileCache.mm
+++ b/Source/WebCore/platform/graphics/ca/mac/TileCache.mm
@@ -45,15 +45,18 @@ using namespace std;
namespace WebCore {
-PassOwnPtr<TileCache> TileCache::create(WebTileCacheLayer* tileCacheLayer, const IntSize& tileSize)
+static const int defaultTileCacheWidth = 512;
+static const int defaultTileCacheHeight = 512;
+
+PassOwnPtr<TileCache> TileCache::create(WebTileCacheLayer* tileCacheLayer)
{
- return adoptPtr(new TileCache(tileCacheLayer, tileSize));
+ return adoptPtr(new TileCache(tileCacheLayer));
}
-TileCache::TileCache(WebTileCacheLayer* tileCacheLayer, const IntSize& tileSize)
+TileCache::TileCache(WebTileCacheLayer* tileCacheLayer)
: m_tileCacheLayer(tileCacheLayer)
, m_tileContainerLayer(adoptCF([[CALayer alloc] init]))
- , m_tileSize(tileSize)
+ , m_tileSize(defaultTileCacheWidth, defaultTileCacheHeight)
, m_tileRevalidationTimer(this, &TileCache::tileRevalidationTimerFired)
, m_scale(1)
, m_deviceScaleFactor(1)
@@ -300,18 +303,22 @@ void TileCache::getTileIndexRangeForRect(const IntRect& rect, TileIndex& topLeft
topLeft.setX(max(clampedRect.x() / m_tileSize.width(), 0));
topLeft.setY(max(clampedRect.y() / m_tileSize.height(), 0));
- bottomRight.setX(max(clampedRect.maxX() / m_tileSize.width(), 0));
- bottomRight.setY(max(clampedRect.maxY() / m_tileSize.height(), 0));
+
+ int bottomXRatio = ceil((float)clampedRect.maxX() / m_tileSize.width());
+ bottomRight.setX(max(bottomXRatio - 1, 0));
+
+ int bottomYRatio = ceil((float)clampedRect.maxY() / m_tileSize.height());
+ bottomRight.setY(max(bottomYRatio - 1, 0));
}
-IntRect TileCache::tileCoverageRect() const
+IntRect TileCache::computeTileCoverageRect() const
{
IntRect tileCoverageRect = m_visibleRect;
// If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
// Furthermore, if the page can't have scrollbars (for example if its body element has overflow:hidden) it's very unlikely that the
// page will ever be scrolled so we limit the tile coverage rect as well.
- if (m_isInWindow) {
+ if (m_isInWindow && !(m_tileCoverage & CoverageForSlowScrolling)) {
// Inflate the coverage rect so that it covers 2x of the visible width and 3x of the visible height.
// These values were chosen because it's more common to have tall pages and to scroll vertically,
// so we keep more tiles above and below the current area.
@@ -325,6 +332,13 @@ IntRect TileCache::tileCoverageRect() const
return tileCoverageRect;
}
+IntSize TileCache::tileSizeForCoverageRect(const IntRect& coverageRect) const
+{
+ if (m_tileCoverage & CoverageForSlowScrolling)
+ return coverageRect.size();
+ return IntSize(defaultTileCacheWidth, defaultTileCacheHeight);
+}
+
void TileCache::scheduleTileRevalidation(double interval)
{
if (m_tileRevalidationTimer.isActive() && m_tileRevalidationTimer.nextFireInterval() < interval)
@@ -377,7 +391,13 @@ void TileCache::revalidateTiles()
if (m_visibleRect.isEmpty() || bounds().isEmpty())
return;
- IntRect tileCoverageRect = this->tileCoverageRect();
+ IntRect tileCoverageRect = computeTileCoverageRect();
+ IntRect coverageRectInTileCoords(tileCoverageRect);
+ coverageRectInTileCoords.scale(m_scale);
+
+ IntSize oldTileSize = m_tileSize;
+ m_tileSize = tileSizeForCoverageRect(tileCoverageRect);
+ bool tileSizeChanged = m_tileSize != oldTileSize;
Vector<TileIndex> tilesToRemove;
@@ -386,7 +406,7 @@ void TileCache::revalidateTiles()
WebTileLayer* tileLayer = it->value.get();
- if (!rectForTileIndex(tileIndex).intersects(tileCoverageRect)) {
+ if (!rectForTileIndex(tileIndex).intersects(coverageRectInTileCoords) || tileSizeChanged) {
// Remove this layer.
[tileLayer removeFromSuperlayer];
[tileLayer setTileCache:0];
@@ -403,7 +423,7 @@ void TileCache::revalidateTiles()
TileIndex topLeft;
TileIndex bottomRight;
- getTileIndexRangeForRect(tileCoverageRect, topLeft, bottomRight);
+ getTileIndexRangeForRect(coverageRectInTileCoords, topLeft, bottomRight);
Vector<FloatRect> dirtyRects;
@@ -442,6 +462,14 @@ void TileCache::revalidateTiles()
platformLayer->owner()->platformCALayerDidCreateTiles(dirtyRects);
}
+// Return the rect in layer coords, not tile coords.
+IntRect TileCache::tileCoverageRect() const
+{
+ IntRect coverageRectInLayerCoords(m_tileCoverageRect);
+ coverageRectInLayerCoords.scale(1 / m_scale);
+ return coverageRectInLayerCoords;
+}
+
WebTileLayer* TileCache::tileLayerAtIndex(const TileIndex& index) const
{
return m_tiles.get(index).get();
diff --git a/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm b/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm
index c6aab8aff..d119f5bd2 100644
--- a/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm
+++ b/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm
@@ -40,8 +40,7 @@ using namespace WebCore;
if (!self)
return nil;
- // FIXME: The tile size should be configurable.
- _tileCache = TileCache::create(self, IntSize(512, 512));
+ _tileCache = TileCache::create(self);
#ifndef NDEBUG
[self setName:@"WebTileCacheLayer"];
#endif
diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp
index 97fb0b609..856a4fcad 100644
--- a/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp
@@ -151,8 +151,7 @@ PlatformCAAnimation::PlatformCAAnimation(AnimationType type, const String& keyPa
else
m_animation.adoptCF(CACFAnimationCreate(kCACFKeyframeAnimation));
- RetainPtr<CFStringRef> s(AdoptCF, keyPath.createCFString());
- CACFAnimationSetKeyPath(m_animation.get(), s.get());
+ CACFAnimationSetKeyPath(m_animation.get(), keyPath.createCFString().get());
}
PlatformCAAnimation::PlatformCAAnimation(PlatformAnimationRef animation)
diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
index 70168b210..bba8f2c5c 100644
--- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
@@ -176,10 +176,8 @@ void PlatformCALayer::animationStarted(CFTimeInterval beginTime)
static void resubmitAllAnimations(PlatformCALayer* layer)
{
HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = layer->animations().end();
- for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = layer->animations().begin(); it != end; ++it) {
- RetainPtr<CFStringRef> s(AdoptCF, it->key.createCFString());
- CACFLayerAddAnimation(layer->platformLayer(), s.get(), it->value->platformAnimation());
- }
+ for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = layer->animations().begin(); it != end; ++it)
+ CACFLayerAddAnimation(layer->platformLayer(), it->key.createCFString().get(), it->value->platformAnimation());
}
void PlatformCALayer::ensureAnimationsSubmitted()
@@ -297,8 +295,7 @@ void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation*
// Add it to the animation list
m_animations.add(key, animation);
- RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
- CACFLayerAddAnimation(m_layer.get(), s.get(), animation->platformAnimation());
+ CACFLayerAddAnimation(m_layer.get(), key.createCFString().get(), animation->platformAnimation());
setNeedsCommit();
// Tell the host about it so we can fire the start animation event
@@ -312,8 +309,7 @@ void PlatformCALayer::removeAnimationForKey(const String& key)
// Remove it from the animation list
m_animations.remove(key);
- RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
- CACFLayerRemoveAnimation(m_layer.get(), s.get());
+ CACFLayerRemoveAnimation(m_layer.get(), key.createCFString().get());
// We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation.
// There may be other active animations on the layer and if an animation
@@ -572,6 +568,10 @@ void PlatformCALayer::setFilters(const FilterOperations&)
{
}
+void PlatformCALayer::copyFiltersFrom(const PlatformCALayer*)
+{
+}
+
bool PlatformCALayer::filtersCanBeComposited(const FilterOperations&)
{
return false;
@@ -586,8 +586,7 @@ String PlatformCALayer::name() const
void PlatformCALayer::setName(const String& value)
{
- RetainPtr<CFStringRef> s(AdoptCF, value.createCFString());
- CACFLayerSetName(m_layer.get(), s.get());
+ CACFLayerSetName(m_layer.get(), value.createCFString().get());
setNeedsCommit();
}
diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp
index c430cf284..15275b3ae 100644
--- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp
@@ -459,7 +459,7 @@ void PlatformCALayerWinInternal::updateTiles()
#ifndef NDEBUG
String name = "Tile (" + String::number(i) + "," + String::number(j) + ")";
- CACFLayerSetName(tile, RetainPtr<CFStringRef>(AdoptCF, name.createCFString()).get());
+ CACFLayerSetName(tile, name.createCFString().get());
#endif
}
}
diff --git a/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp b/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp
index 83fac1fda..225dfb2f6 100644
--- a/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp
@@ -73,10 +73,12 @@ BitmapImage::BitmapImage(NativeImageCairo* nativeImage, ImageObserver* observer)
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op)
{
- FloatRect srcRect(src);
- FloatRect dstRect(dst);
+ draw(context, dst, src, styleColorSpace, op, DoNotRespectImageOrientation);
+}
- if (!dstRect.width() || !dstRect.height() || !srcRect.width() || !srcRect.height())
+void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation)
+{
+ if (!dst.width() || !dst.height() || !src.width() || !src.height())
return;
startAnimation();
@@ -86,7 +88,7 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
return;
if (mayFillWithSolidColor()) {
- fillWithSolidColor(context, dstRect, solidColor(), styleColorSpace, op);
+ fillWithSolidColor(context, dst, solidColor(), styleColorSpace, op);
return;
}
@@ -101,11 +103,29 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
cairo_surface_t* surface = nativeImage->surface();
IntSize scaledSize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
- FloatRect adjustedSrcRect = adjustSourceRectForDownSampling(srcRect, scaledSize);
+ FloatRect adjustedSrcRect = adjustSourceRectForDownSampling(src, scaledSize);
#else
- FloatRect adjustedSrcRect(srcRect);
+ FloatRect adjustedSrcRect(src);
#endif
+ ImageOrientation orientation = DefaultImageOrientation;
+ if (shouldRespectImageOrientation == RespectImageOrientation)
+ orientation = frameOrientationAtIndex(m_currentFrame);
+
+ FloatRect dstRect = dst;
+
+ if (orientation != DefaultImageOrientation) {
+ // ImageOrientation expects the origin to be at (0, 0).
+ context->translate(dstRect.x(), dstRect.y());
+ dstRect.setLocation(FloatPoint());
+ context->concatCTM(orientation.transformFromDefault(dstRect.size()));
+ if (orientation.usesWidthAsHeight()) {
+ // The destination rectangle will have it's width and height already reversed for the orientation of
+ // the image, as it was needed for page layout, so we need to reverse it back here.
+ dstRect = FloatRect(dstRect.x(), dstRect.y(), dstRect.height(), dstRect.width());
+ }
+ }
+
context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, adjustedSrcRect, context);
context->restore();
diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index 8ccb8d9bc..722cb6999 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -175,15 +175,26 @@ PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, const ImageBuffe
for (int x = 0; x < numColumns; x++) {
int basex = x * 4;
unsigned* pixel = row + x + originx;
- Color pixelColor;
- if (multiplied == Unmultiplied)
- pixelColor = colorFromPremultipliedARGB(*pixel);
- else
- pixelColor = Color(*pixel);
- destRows[basex] = pixelColor.red();
- destRows[basex + 1] = pixelColor.green();
- destRows[basex + 2] = pixelColor.blue();
- destRows[basex + 3] = pixelColor.alpha();
+
+ // Avoid calling Color::colorFromPremultipliedARGB() because one
+ // function call per pixel is too expensive.
+ unsigned alpha = (*pixel & 0xFF000000) >> 24;
+ unsigned red = (*pixel & 0x00FF0000) >> 16;
+ unsigned green = (*pixel & 0x0000FF00) >> 8;
+ unsigned blue = (*pixel & 0x000000FF);
+
+ if (multiplied == Unmultiplied) {
+ if (alpha && alpha != 255) {
+ red = red * 255 / alpha;
+ green = green * 255 / alpha;
+ blue = blue * 255 / alpha;
+ }
+ }
+
+ destRows[basex] = red;
+ destRows[basex + 1] = green;
+ destRows[basex + 2] = blue;
+ destRows[basex + 3] = alpha;
}
destRows += destBytesPerRow;
}
@@ -242,14 +253,23 @@ void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c
for (int x = 0; x < numColumns; x++) {
int basex = x * 4;
unsigned* pixel = row + x + destx;
- Color pixelColor = Color::createUnCheked(srcRows[basex],
- srcRows[basex + 1],
- srcRows[basex + 2],
- srcRows[basex + 3]);
- if (multiplied == Unmultiplied)
- *pixel = premultipliedARGBFromColor(pixelColor);
- else
- *pixel = pixelColor.rgb();
+
+ // Avoid calling Color::premultipliedARGBFromColor() because one
+ // function call per pixel is too expensive.
+ unsigned red = srcRows[basex];
+ unsigned green = srcRows[basex + 1];
+ unsigned blue = srcRows[basex + 2];
+ unsigned alpha = srcRows[basex + 3];
+
+ if (multiplied == Unmultiplied) {
+ if (alpha && alpha != 255) {
+ red = (red * alpha + 254) / 255;
+ green = (green * alpha + 254) / 255;
+ blue = (blue * alpha + 254) / 255;
+ }
+ }
+
+ *pixel = (alpha << 24) | red << 16 | green << 8 | blue;
}
srcRows += srcBytesPerRow;
}
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 6ceace35d..1edab0c33 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -326,9 +326,8 @@ void GraphicsContext::drawNativeImage(NativeImagePtr imagePtr, const FloatSize&
setPlatformCompositeOperation(op);
- // Flip the coords.
- CGContextTranslateCTM(context, adjustedDestRect.x(), adjustedDestRect.maxY());
- CGContextScaleCTM(context, 1, -1);
+ // ImageOrientation expects the origin to be at (0, 0)
+ CGContextTranslateCTM(context, adjustedDestRect.x(), adjustedDestRect.y());
adjustedDestRect.setLocation(FloatPoint());
if (orientation != DefaultImageOrientation) {
@@ -340,6 +339,10 @@ void GraphicsContext::drawNativeImage(NativeImagePtr imagePtr, const FloatSize&
}
}
+ // Flip the coords.
+ CGContextTranslateCTM(context, 0, adjustedDestRect.height());
+ CGContextScaleCTM(context, 1, -1);
+
// Adjust the color space.
image = Image::imageWithColorSpace(image.get(), styleColorSpace);
@@ -485,7 +488,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
}
}
- const CGFloat dottedLine[2] = { patWidth, patWidth };
+ const CGFloat dottedLine[2] = { static_cast<CGFloat>(patWidth), static_cast<CGFloat>(patWidth) };
CGContextSetLineDash(context, patternOffset, dottedLine, 2);
}
@@ -593,7 +596,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
}
}
- const CGFloat dottedLine[2] = { patWidth, patWidth };
+ const CGFloat dottedLine[2] = { static_cast<CGFloat>(patWidth), static_cast<CGFloat>(patWidth) };
CGContextSetLineDash(context, patternOffset, dottedLine, 2);
}
@@ -1057,7 +1060,12 @@ void GraphicsContext::clipOut(const IntRect& rect)
if (paintingDisabled())
return;
- CGRect rects[2] = { CGContextGetClipBoundingBox(platformContext()), rect };
+ // FIXME: Using CGRectInfinite is much faster than getting the clip bounding box. However, due
+ // to <rdar://problem/12584492>, CGRectInfinite can't be used with an accelerated context that
+ // has certain transforms that aren't just a translation or a scale.
+ const AffineTransform& ctm = getCTM();
+ bool canUseCGRectInfinite = !isAcceleratedContext() || (!ctm.b() && !ctm.c());
+ CGRect rects[2] = { canUseCGRectInfinite ? CGRectInfinite : CGContextGetClipBoundingBox(platformContext()), rect };
CGContextBeginPath(platformContext());
CGContextAddRects(platformContext(), rects, 2);
CGContextEOClip(platformContext());
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index 21e9db4c2..dd3781597 100644
--- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -377,8 +377,7 @@ static inline CFStringRef jpegUTI()
static RetainPtr<CFStringRef> utiFromMIMEType(const String& mimeType)
{
#if PLATFORM(MAC)
- RetainPtr<CFStringRef> mimeTypeCFString(AdoptCF, mimeType.createCFString());
- return RetainPtr<CFStringRef>(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeTypeCFString.get(), 0));
+ return adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType.createCFString().get(), 0));
#else
ASSERT(isMainThread()); // It is unclear if CFSTR is threadsafe.
diff --git a/Source/WebCore/platform/graphics/cg/ImageSourceCGMac.mm b/Source/WebCore/platform/graphics/cg/ImageSourceCGMac.mm
index bd50a3175..953bcb9d2 100644
--- a/Source/WebCore/platform/graphics/cg/ImageSourceCGMac.mm
+++ b/Source/WebCore/platform/graphics/cg/ImageSourceCGMac.mm
@@ -33,16 +33,12 @@ namespace WebCore {
String MIMETypeForImageSourceType(const String& uti)
{
- RetainPtr<CFStringRef> utiref(AdoptCF, uti.createCFString());
- RetainPtr<CFStringRef> mime(AdoptCF, UTTypeCopyPreferredTagWithClass(utiref.get(), kUTTagClassMIMEType));
- return mime.get();
+ return adoptCF(UTTypeCopyPreferredTagWithClass(uti.createCFString().get(), kUTTagClassMIMEType)).get();
}
String preferredExtensionForImageSourceType(const String& uti)
{
- RetainPtr<CFStringRef> type(AdoptCF, uti.createCFString());
- RetainPtr<CFStringRef> extension(AdoptCF, UTTypeCopyPreferredTagWithClass(type.get(), kUTTagClassFilenameExtension));
- return extension.get();
+ return adoptCF(UTTypeCopyPreferredTagWithClass(uti.createCFString().get(), kUTTagClassFilenameExtension)).get();
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.cpp b/Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.cpp
index 7574196e7..e9424dfc5 100644
--- a/Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.cpp
+++ b/Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.cpp
@@ -151,4 +151,10 @@ unsigned DeferredImageDecoder::frameBytesAtIndex(size_t index) const
return m_actualDecoder ? m_actualDecoder->frameBytesAtIndex(index) : 0;
}
+ImageOrientation DeferredImageDecoder::orientation() const
+{
+ // FIXME: Make this work with deferred decoding.
+ return m_actualDecoder ? m_actualDecoder->orientation() : DefaultImageOrientation;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.h b/Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.h
index 6b33fe35e..d82aec872 100644
--- a/Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.h
+++ b/Source/WebCore/platform/graphics/chromium/DeferredImageDecoder.h
@@ -56,6 +56,7 @@ public:
void clearFrameBufferCache(size_t);
bool frameHasAlphaAtIndex(size_t index) const;
unsigned frameBytesAtIndex(size_t index) const;
+ ImageOrientation orientation() const;
private:
explicit DeferredImageDecoder(ImageDecoder* actualDecoder);
diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 075749e9a..7a63b6801 100644
--- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -54,7 +54,9 @@
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
#include "ScrollableArea.h"
+#include "SkImageFilter.h"
#include "SkMatrix44.h"
+#include "SkiaImageFilterBuilder.h"
#include "SystemTime.h"
#include <public/Platform.h>
#include <public/WebAnimation.h>
@@ -105,6 +107,7 @@ GraphicsLayerChromium::GraphicsLayerChromium(GraphicsLayerClient* client)
m_layer = adoptPtr(Platform::current()->compositorSupport()->createContentLayer(m_opaqueRectTrackingContentLayerDelegate.get()));
m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible);
m_layer->layer()->setScrollClient(this);
+ m_layer->setAutomaticallyComputeRasterScale(true);
updateDebugIndicators();
}
@@ -299,6 +302,7 @@ void GraphicsLayerChromium::setContentsOpaque(bool opaque)
{
GraphicsLayer::setContentsOpaque(opaque);
m_layer->layer()->setOpaque(m_contentsOpaque);
+ m_opaqueRectTrackingContentLayerDelegate->setOpaque(m_contentsOpaque);
}
static bool copyWebCoreFilterOperationsToWebFilterOperations(const FilterOperations& filters, WebFilterOperations& webFilters)
@@ -366,6 +370,7 @@ static bool copyWebCoreFilterOperationsToWebFilterOperations(const FilterOperati
}
#if ENABLE(CSS_SHADERS)
case FilterOperation::CUSTOM:
+ case FilterOperation::VALIDATED_CUSTOM:
return false; // Not supported.
#endif
case FilterOperation::PASSTHROUGH:
@@ -378,15 +383,25 @@ static bool copyWebCoreFilterOperationsToWebFilterOperations(const FilterOperati
bool GraphicsLayerChromium::setFilters(const FilterOperations& filters)
{
- WebFilterOperations webFilters;
- if (!copyWebCoreFilterOperationsToWebFilterOperations(filters, webFilters)) {
- // Make sure the filters are removed from the platform layer, as they are
- // going to fallback to software mode.
- m_layer->layer()->setFilters(WebFilterOperations());
- GraphicsLayer::setFilters(FilterOperations());
- return false;
+ // FIXME: For now, we only use SkImageFilters if there is a reference
+ // filter in the chain. Once all issues have been ironed out, we should
+ // switch all filtering over to this path, and remove setFilters() and
+ // WebFilterOperations altogether.
+ if (filters.hasReferenceFilter()) {
+ SkiaImageFilterBuilder builder;
+ SkAutoTUnref<SkImageFilter> imageFilter(builder.build(filters));
+ m_layer->layer()->setFilter(imageFilter);
+ } else {
+ WebFilterOperations webFilters;
+ if (!copyWebCoreFilterOperationsToWebFilterOperations(filters, webFilters)) {
+ // Make sure the filters are removed from the platform layer, as they are
+ // going to fallback to software mode.
+ m_layer->layer()->setFilters(WebFilterOperations());
+ GraphicsLayer::setFilters(FilterOperations());
+ return false;
+ }
+ m_layer->layer()->setFilters(webFilters);
}
- m_layer->layer()->setFilters(webFilters);
return GraphicsLayer::setFilters(filters);
}
@@ -434,14 +449,17 @@ void GraphicsLayerChromium::setReplicatedByLayer(GraphicsLayer* layer)
void GraphicsLayerChromium::setContentsNeedsDisplay()
{
- if (WebLayer* contentsLayer = contentsLayerIfRegistered())
+ if (WebLayer* contentsLayer = contentsLayerIfRegistered()) {
contentsLayer->invalidate();
+ addRepaintRect(contentsRect());
+ }
}
void GraphicsLayerChromium::setNeedsDisplay()
{
if (drawsContent()) {
m_layer->layer()->invalidate();
+ addRepaintRect(FloatRect(FloatPoint(), m_size));
if (m_linkHighlight)
m_linkHighlight->invalidate();
}
@@ -451,6 +469,7 @@ void GraphicsLayerChromium::setNeedsDisplayInRect(const FloatRect& rect)
{
if (drawsContent()) {
m_layer->layer()->invalidateRect(rect);
+ addRepaintRect(rect);
if (m_linkHighlight)
m_linkHighlight->invalidate();
}
@@ -841,7 +860,7 @@ void GraphicsLayerChromium::setupContentsLayer(WebLayer* contentsLayer)
// shadow content that must display in front of the video.
m_layer->layer()->insertChild(m_contentsLayer, 0);
- if (showDebugBorders()) {
+ if (isShowingDebugBorder()) {
m_contentsLayer->setDebugBorderColor(Color(0, 0, 128, 180).rgb());
m_contentsLayer->setDebugBorderWidth(1);
}
@@ -862,7 +881,6 @@ bool GraphicsLayerChromium::appliesPageScale() const
void GraphicsLayerChromium::paint(GraphicsContext& context, const IntRect& clip)
{
- context.platformContext()->setDrawingToImageBuffer(true);
paintGraphicsLayerContents(context, clip);
}
diff --git a/Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.cpp b/Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.cpp
index a06ac666e..62edced17 100644
--- a/Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.cpp
+++ b/Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.cpp
@@ -49,7 +49,7 @@ OpaqueRectTrackingContentLayerDelegate::~OpaqueRectTrackingContentLayerDelegate(
{
}
-void OpaqueRectTrackingContentLayerDelegate::paintContents(SkCanvas* canvas, const WebRect& clip, WebFloatRect& opaque)
+void OpaqueRectTrackingContentLayerDelegate::paintContents(SkCanvas* canvas, const WebRect& clip, bool canPaintLCDText, WebFloatRect& opaque)
{
PlatformContextSkia platformContext(canvas);
#if defined(SK_SUPPORT_HINTING_SCALE_FACTOR)
@@ -57,6 +57,10 @@ void OpaqueRectTrackingContentLayerDelegate::paintContents(SkCanvas* canvas, con
platformContext.setHintingScaleFactor(canvas->getTotalMatrix().getScaleX());
#endif
platformContext.setTrackOpaqueRegion(!m_opaque);
+ // FIXME: Rename PlatformContextSkia::setDrawingToImageBuffer to setCanPaintLCDText.
+ // I also suspect that a function on PlatformContextSkia is not really needed.
+ // GraphicsContext::setAllowsFontSmoothing can be used for this purpose.
+ platformContext.setDrawingToImageBuffer(!(canPaintLCDText && m_opaque));
GraphicsContext context(&platformContext);
// Record transform prior to painting, as all opaque tracking will be
diff --git a/Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.h b/Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.h
index bb5c2ae96..451b647b1 100644
--- a/Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.h
+++ b/Source/WebCore/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.h
@@ -55,7 +55,7 @@ public:
void setOpaque(bool opaque) { m_opaque = opaque; }
// WebKit::WebContentLayerClient implementation.
- virtual void paintContents(SkCanvas*, const WebKit::WebRect& clip, WebKit::WebFloatRect& opaque) OVERRIDE;
+ virtual void paintContents(SkCanvas*, const WebKit::WebRect& clip, bool canPaintLCDText, WebKit::WebFloatRect& opaque) OVERRIDE;
private:
GraphicsContextPainter* m_painter;
diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
index 8510dfa52..a7aed729c 100644
--- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
@@ -119,26 +119,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
return SimpleFontData::create(FontPlatformData(hfont, scaledSize, m_platformData.orientation()), isCustomFont(), false);
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
-
- return m_derivedFontData->emphasisMark;
-}
-
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
// This used to be implemented with IMLangFontLink2, but since that code has
diff --git a/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp b/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
index 104b7982b..58bf38d5b 100644
--- a/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
+++ b/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
@@ -67,11 +67,13 @@ ClutterActor* GraphicsLayerClutter::platformLayer() const
void GraphicsLayerClutter::setNeedsDisplay()
{
notImplemented();
+ addRepaintRect(FloatRect(FloatPoint(), m_size));
}
-void GraphicsLayerClutter::setNeedsDisplayInRect(const FloatRect&)
+void GraphicsLayerClutter::setNeedsDisplayInRect(const FloatRect& rect)
{
notImplemented();
+ addRepaintRect(rect);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp b/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp
index 65f2d63b8..d1391307c 100644
--- a/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp
+++ b/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp
@@ -151,6 +151,31 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi
GraphicsContext3D::~GraphicsContext3D()
{
+ if (m_renderStyle == RenderToCurrentGLContext || !m_private)
+ return;
+
+ makeContextCurrent();
+ glDeleteTextures(1, &m_texture);
+
+ if (m_attrs.antialias) {
+ glDeleteRenderbuffers(1, &m_multisampleColorBuffer);
+
+ if (m_attrs.stencil || m_attrs.depth)
+ glDeleteRenderbuffers(1, &m_multisampleDepthStencilBuffer);
+
+ glDeleteFramebuffers(1, &m_multisampleFBO);
+ } else if (m_attrs.stencil || m_attrs.depth) {
+
+#if USE(OPENGL_ES_2)
+ if (m_attrs.depth)
+ glDeleteRenderbuffers(1, &m_depthBuffer);
+
+ if (m_attrs.stencil)
+ glDeleteRenderbuffers(1, &m_stencilBuffer);
+#endif
+ glDeleteRenderbuffers(1, &m_depthStencilBuffer);
+ }
+ glDeleteFramebuffers(1, &m_fbo);
}
PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D()
@@ -226,7 +251,7 @@ void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imag
#if USE(GRAPHICS_SURFACE)
void GraphicsContext3D::createGraphicsSurfaces(const IntSize& size)
{
- notImplemented();
+ m_private->createGraphicsSurfaces(size);
}
#endif
diff --git a/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp b/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp
index 0ab98929f..62d0a6e3a 100644
--- a/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp
+++ b/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp
@@ -25,6 +25,7 @@
#include "GraphicsContext.h"
#include "HostWindow.h"
#include "NotImplemented.h"
+#include "PlatformContextCairo.h"
#include <Ecore_Evas.h>
#include <Evas_GL.h>
#include <wtf/OwnArrayPtr.h>
@@ -87,6 +88,13 @@ GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, H
return;
makeContextCurrent();
+
+#if USE(GRAPHICS_SURFACE)
+ IntSize surfaceSize(m_context->m_currentWidth, m_context->m_currentHeight);
+ m_surfaceFlags = GraphicsSurface::SupportsTextureTarget | GraphicsSurface::SupportsSharing;
+ if (!surfaceSize.isEmpty())
+ m_graphicsSurface = GraphicsSurface::create(surfaceSize, m_surfaceFlags);
+#endif
}
GraphicsContext3DPrivate::~GraphicsContext3DPrivate()
@@ -101,8 +109,11 @@ GraphicsContext3DPrivate::~GraphicsContext3DPrivate()
evas_gl_context_destroy(m_evasGL, m_evasGLContext);
evas_gl_free(m_evasGL);
-}
+#if USE(GRAPHICS_SURFACE)
+ m_graphicsSurface.clear();
+#endif
+}
bool GraphicsContext3DPrivate::createSurface(PageClientEfl* pageClient, bool renderDirectlyToHostWindow)
{
@@ -169,6 +180,32 @@ void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper*, const FloatR
notImplemented();
}
#endif
+
+#if USE(GRAPHICS_SURFACE)
+void GraphicsContext3DPrivate::createGraphicsSurfaces(const IntSize& size)
+{
+ if (size.isEmpty())
+ m_graphicsSurface.clear();
+ else
+ m_graphicsSurface = GraphicsSurface::create(size, m_surfaceFlags);
+}
+
+uint32_t GraphicsContext3DPrivate::copyToGraphicsSurface()
+{
+ if (!m_graphicsSurface)
+ return 0;
+
+ makeContextCurrent();
+ m_graphicsSurface->copyFromTexture(m_context->m_texture, IntRect(0, 0, m_context->m_currentWidth, m_context->m_currentHeight));
+ return m_graphicsSurface->swapBuffers();
+}
+
+GraphicsSurfaceToken GraphicsContext3DPrivate::graphicsSurfaceToken() const
+{
+ return m_graphicsSurface->exportToken();
+}
+#endif
+
} // namespace WebCore
#endif // USE(3D_GRAPHICS) || USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h b/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h
index 08ccf77a6..1ae4351f9 100644
--- a/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h
+++ b/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h
@@ -26,6 +26,10 @@
#include <texmap/TextureMapperPlatformLayer.h>
#endif
+#if USE(GRAPHICS_SURFACE)
+#include "GraphicsSurface.h"
+#endif
+
typedef struct _Evas_GL Evas_GL;
typedef struct _Evas_GL_Surface Evas_GL_Surface;
typedef struct _Evas_GL_Context Evas_GL_Context;
@@ -52,6 +56,12 @@ public:
#if USE(TEXTURE_MAPPER_GL)
virtual void paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity, BitmapTexture* mask);
#endif
+#if USE(GRAPHICS_SURFACE)
+ virtual uint32_t copyToGraphicsSurface();
+ virtual GraphicsSurfaceToken graphicsSurfaceToken() const;
+ void createGraphicsSurfaces(const IntSize&);
+#endif
+
bool makeContextCurrent();
bool createSurface(PageClientEfl*, bool renderDirectlyToEvasGLObject);
void setCurrentGLContext(void*, void*);
@@ -59,6 +69,10 @@ public:
GraphicsContext3D::Attributes m_attributes;
GraphicsContext3D* m_context;
HostWindow* m_hostWindow;
+#if USE(GRAPHICS_SURFACE)
+ GraphicsSurface::Flags m_surfaceFlags;
+ RefPtr<GraphicsSurface> m_graphicsSurface;
+#endif
ListHashSet<GC3Denum> m_syntheticErrors;
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterArrayParameter.h b/Source/WebCore/platform/graphics/filters/CustomFilterArrayParameter.h
index b52236dde..3050cb445 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterArrayParameter.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterArrayParameter.h
@@ -31,6 +31,7 @@
#define CustomFilterArrayParameter_h
#if ENABLE(CSS_SHADERS)
+#include "AnimationUtilities.h"
#include "CustomFilterParameter.h"
#include <wtf/Vector.h>
@@ -50,11 +51,19 @@ public:
virtual PassRefPtr<CustomFilterParameter> blend(const CustomFilterParameter* from, double progress, const LayoutSize&)
{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=96437
- UNUSED_PARAM(from);
- UNUSED_PARAM(progress);
+ if (!from || !isSameType(*from))
+ return this;
- return this;
+ const CustomFilterArrayParameter* fromArray = static_cast<const CustomFilterArrayParameter*>(from);
+
+ if (size() != fromArray->size())
+ return this;
+
+ RefPtr<CustomFilterArrayParameter> result = CustomFilterArrayParameter::create(name());
+ for (size_t i = 0; i < size(); ++i)
+ result->addValue(WebCore::blend(fromArray->valueAt(i), valueAt(i), progress));
+
+ return result.release();
}
virtual bool operator==(const CustomFilterParameter& o) const
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.cpp
index 7e284bb83..26965d05e 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.cpp
@@ -50,7 +50,6 @@ CustomFilterCompiledProgram::CustomFilterCompiledProgram(PassRefPtr<GraphicsCont
, m_samplerLocation(-1)
, m_samplerSizeLocation(-1)
, m_contentSamplerLocation(-1)
- , m_internalTexCoordAttribLocation(-1)
, m_isInitialized(false)
{
m_context->makeContextCurrent();
@@ -130,14 +129,9 @@ void CustomFilterCompiledProgram::initializeParameterLocations(CustomFilterProgr
m_samplerSizeLocation = m_context->getUniformLocation(m_program, "u_textureSize");
m_contentSamplerLocation = m_context->getUniformLocation(m_program, "u_contentTexture");
if (programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) {
- // When the author uses the CSS mix function in a custom filter, we add internal symbols to the shader code.
- // One of them, css_u_texture, references the texture of the element.
+ // When the author uses the CSS mix function in a custom filter, WebKit adds the internal
+ // symbol css_u_texture to the shader code, which references the texture of the element.
m_samplerLocation = m_context->getUniformLocation(m_program, "css_u_texture");
- m_internalTexCoordAttribLocation = m_context->getAttribLocation(m_program, "css_a_texCoord");
-
- // These internal symbols should have been added to the validated shaders.
- ASSERT(m_samplerLocation != -1);
- ASSERT(m_internalTexCoordAttribLocation != -1);
}
}
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.h b/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.h
index f31fdf040..5dbf0d451 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.h
@@ -61,12 +61,6 @@ public:
int samplerLocation() const { return m_samplerLocation; }
int contentSamplerLocation() const { return m_contentSamplerLocation; }
int samplerSizeLocation() const { return m_samplerSizeLocation; }
- // FIXME: Get rid of the internal tex coord attribute "css_a_texCoord".
- // If the author defined "a_texCoord", we should leverage that.
- // If not, we should write "a_texCoord" in the shader.
- // This requires us to first get the list of attributes from the vertex shader using ANGLE.
- // https://bugs.webkit.org/show_bug.cgi?id=94358
- int internalTexCoordAttribLocation() const { return m_internalTexCoordAttribLocation; }
int uniformLocationByName(const String&);
@@ -94,9 +88,6 @@ private:
int m_samplerLocation;
int m_samplerSizeLocation;
int m_contentSamplerLocation;
- // FIXME: Get rid of the internal tex coord attribute "css_a_texCoord".
- // https://bugs.webkit.org/show_bug.cgi?id=94358
- int m_internalTexCoordAttribLocation;
bool m_isInitialized;
};
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterConstants.h b/Source/WebCore/platform/graphics/filters/CustomFilterConstants.h
index 6080c38f6..cdd453a2a 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterConstants.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterConstants.h
@@ -45,6 +45,18 @@ enum CustomFilterMeshConstants {
TriangleAttribOffset = MeshAttribOffset + MeshAttribSize * sizeof(float)
};
+enum CustomFilterMeshType {
+ MeshTypeAttached,
+ MeshTypeDetached
+};
+
+enum CustomFilterMeshBoxType {
+ MeshBoxTypeFilter,
+ MeshBoxTypeBorder,
+ MeshBoxTypePadding,
+ MeshBoxTypeContent
+};
+
} // namespace WebCore
#endif // CustomFilterConstants_h
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterMesh.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterMesh.cpp
index 0278abad0..eff07884c 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterMesh.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterMesh.cpp
@@ -37,7 +37,7 @@
namespace WebCore {
CustomFilterMesh::CustomFilterMesh(GraphicsContext3D* context, unsigned columns, unsigned rows,
- const FloatRect& meshBox, CustomFilterOperation::MeshType meshType)
+ const FloatRect& meshBox, CustomFilterMeshType meshType)
: m_context(context)
, m_verticesBufferObject(0)
, m_elementsBufferObject(0)
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterMesh.h b/Source/WebCore/platform/graphics/filters/CustomFilterMesh.h
index e3c7a6bac..2bb3d5af1 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterMesh.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterMesh.h
@@ -43,7 +43,7 @@ class GraphicsContext3D;
class CustomFilterMesh : public RefCounted<CustomFilterMesh> {
public:
- static PassRefPtr<CustomFilterMesh> create(GraphicsContext3D* context, unsigned cols, unsigned rows, const FloatRect& meshBox, CustomFilterOperation::MeshType meshType)
+ static PassRefPtr<CustomFilterMesh> create(GraphicsContext3D* context, unsigned cols, unsigned rows, const FloatRect& meshBox, CustomFilterMeshType meshType)
{
return adoptRef(new CustomFilterMesh(context, cols, rows, meshBox, meshType));
}
@@ -56,10 +56,10 @@ public:
unsigned indicesCount() const { return m_indicesCount; }
const FloatRect& meshBox() const { return m_meshBox; }
- CustomFilterOperation::MeshType meshType() const { return m_meshType; }
+ CustomFilterMeshType meshType() const { return m_meshType; }
private:
- CustomFilterMesh(GraphicsContext3D*, unsigned cols, unsigned rows, const FloatRect& meshBox, CustomFilterOperation::MeshType);
+ CustomFilterMesh(GraphicsContext3D*, unsigned cols, unsigned rows, const FloatRect& meshBox, CustomFilterMeshType);
GraphicsContext3D* m_context;
@@ -70,7 +70,7 @@ private:
unsigned m_indicesCount;
FloatRect m_meshBox;
- CustomFilterOperation::MeshType m_meshType;
+ CustomFilterMeshType m_meshType;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.cpp
index 3d9d4d1b2..774691457 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
static bool s_dumpCustomFilterMeshBuffers = false;
#endif
-CustomFilterMeshGenerator::CustomFilterMeshGenerator(unsigned columns, unsigned rows, const FloatRect& meshBox, CustomFilterOperation::MeshType meshType)
+CustomFilterMeshGenerator::CustomFilterMeshGenerator(unsigned columns, unsigned rows, const FloatRect& meshBox, CustomFilterMeshType meshType)
: m_meshType(meshType)
, m_points(columns + 1, rows + 1)
, m_tiles(columns, rows)
@@ -60,7 +60,7 @@ CustomFilterMeshGenerator::CustomFilterMeshGenerator(unsigned columns, unsigned
// when there's no need to explode the tiles.
// * detached: each triangle has its own vertices. This means each triangle can be moved independently and a vec3
// attribute is passed, so that each vertex can be uniquely identified.
- if (m_meshType == CustomFilterOperation::ATTACHED)
+ if (m_meshType == MeshTypeAttached)
generateAttachedMesh();
else
generateDetachedMesh();
@@ -152,8 +152,8 @@ void CustomFilterMeshGenerator::addDetachedMeshVertexAttributes(int quadX, int q
void CustomFilterMeshGenerator::dumpBuffers() const
{
printf("Mesh buffers: Points.width(): %d, Points.height(): %d meshBox: %f, %f, %f, %f, type: %s\n",
- m_points.width(), m_points.height(), m_meshBox.x(), m_meshBox.y(), m_meshBox.width(), m_meshBox.height(),
- (m_meshType == CustomFilterOperation::ATTACHED) ? "Attached" : "Detached");
+ m_points.width(), m_points.height(), m_meshBox.x(), m_meshBox.y(), m_meshBox.width(), m_meshBox.height(),
+ (m_meshType == MeshTypeAttached) ? "Attached" : "Detached");
printf("---Vertex:\n\t");
for (unsigned i = 0; i < m_vertices.size(); ++i) {
printf("%f ", m_vertices.at(i));
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h b/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h
index b3a184702..7abac12e2 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h
@@ -44,7 +44,7 @@ public:
// and 'columns' number of columns with a total of 'rows + 1' * 'columns + 1' vertices.
// MeshBox is the filtered area calculated defined using the border-box, padding-box, content-box or filter-box
// attributes. A value of (0, 0, 1, 1) will cover the entire output surface.
- CustomFilterMeshGenerator(unsigned columns, unsigned rows, const FloatRect& meshBox, CustomFilterOperation::MeshType);
+ CustomFilterMeshGenerator(unsigned columns, unsigned rows, const FloatRect& meshBox, CustomFilterMeshType);
const Vector<float>& vertices() const { return m_vertices; }
const Vector<uint16_t>& indices() const { return m_indices; }
@@ -66,12 +66,12 @@ public:
{
static const unsigned AttachedMeshVertexSize = PositionAttribSize + TexAttribSize + MeshAttribSize;
static const unsigned DetachedMeshVertexSize = AttachedMeshVertexSize + TriangleAttribSize;
- return m_meshType == CustomFilterOperation::ATTACHED ? AttachedMeshVertexSize : DetachedMeshVertexSize;
+ return m_meshType == MeshTypeAttached ? AttachedMeshVertexSize : DetachedMeshVertexSize;
}
unsigned verticesCount() const
{
- return m_meshType == CustomFilterOperation::ATTACHED ? pointsCount() : indicesCount();
+ return m_meshType == MeshTypeAttached ? pointsCount() : indicesCount();
}
private:
@@ -110,7 +110,7 @@ private:
Vector<float> m_vertices;
Vector<uint16_t> m_indices;
- CustomFilterOperation::MeshType m_meshType;
+ CustomFilterMeshType m_meshType;
IntSize m_points;
IntSize m_tiles;
FloatSize m_tileSizeInPixels;
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterNumberParameter.h b/Source/WebCore/platform/graphics/filters/CustomFilterNumberParameter.h
index 423ef547e..09378583c 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterNumberParameter.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterNumberParameter.h
@@ -31,6 +31,7 @@
#define CustomFilterNumberParameter_h
#if ENABLE(CSS_SHADERS)
+#include "AnimationUtilities.h"
#include "CustomFilterParameter.h"
#include <wtf/Vector.h>
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp
index ed57b7374..2526e5820 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp
@@ -36,66 +36,9 @@
#include "CustomFilterProgram.h"
#include "FilterOperation.h"
-#include <wtf/text/StringHash.h>
-
namespace WebCore {
-bool customFilterParametersEqual(const CustomFilterParameterList& listA, const CustomFilterParameterList& listB)
-{
- if (listA.size() != listB.size())
- return false;
- for (size_t i = 0; i < listA.size(); ++i) {
- if (listA.at(i).get() != listB.at(i).get()
- && *listA.at(i).get() != *listB.at(i).get())
- return false;
- }
- return true;
-}
-
-#if !ASSERT_DISABLED
-static bool checkCustomFilterParametersOrder(const CustomFilterParameterList& parameters)
-{
- for (unsigned i = 1; i < parameters.size(); ++i) {
- // Break for equal or not-sorted parameters.
- if (!codePointCompareLessThan(parameters.at(i - 1)->name(), parameters.at(i)->name()))
- return false;
- }
- return true;
-}
-#endif
-
-void blendCustomFilterParameters(const CustomFilterParameterList& fromList, const CustomFilterParameterList& toList,
- double progress, const LayoutSize& size, CustomFilterParameterList& resultList)
-{
- // This method expects both lists to be sorted by parameter name and the result list is also sorted.
- ASSERT(checkCustomFilterParametersOrder(fromList));
- ASSERT(checkCustomFilterParametersOrder(toList));
- size_t fromListIndex = 0, toListIndex = 0;
- while (fromListIndex < fromList.size() && toListIndex < toList.size()) {
- CustomFilterParameter* paramFrom = fromList.at(fromListIndex).get();
- CustomFilterParameter* paramTo = toList.at(toListIndex).get();
- if (paramFrom->name() == paramTo->name()) {
- resultList.append(paramTo->blend(paramFrom, progress, size));
- ++fromListIndex;
- ++toListIndex;
- continue;
- }
- if (codePointCompareLessThan(paramFrom->name(), paramTo->name())) {
- resultList.append(paramFrom);
- ++fromListIndex;
- continue;
- }
- resultList.append(paramTo);
- ++toListIndex;
- }
- for (; fromListIndex < fromList.size(); ++fromListIndex)
- resultList.append(fromList.at(fromListIndex));
- for (; toListIndex < toList.size(); ++toListIndex)
- resultList.append(toList.at(toListIndex));
- ASSERT(checkCustomFilterParametersOrder(resultList));
-}
-
-CustomFilterOperation::CustomFilterOperation(PassRefPtr<CustomFilterProgram> program, const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, MeshBoxType meshBoxType, MeshType meshType)
+CustomFilterOperation::CustomFilterOperation(PassRefPtr<CustomFilterProgram> program, const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType meshBoxType, CustomFilterMeshType meshType)
: FilterOperation(CUSTOM)
, m_program(program)
, m_parameters(sortedParameters)
@@ -105,7 +48,7 @@ CustomFilterOperation::CustomFilterOperation(PassRefPtr<CustomFilterProgram> pro
, m_meshType(meshType)
{
// Make sure that the parameters are alwyas sorted by name. We use that to merge two CustomFilterOperations in animations.
- ASSERT(checkCustomFilterParametersOrder(m_parameters));
+ ASSERT(m_parameters.checkAlphabeticalOrder());
}
CustomFilterOperation::~CustomFilterOperation()
@@ -129,7 +72,7 @@ PassRefPtr<FilterOperation> CustomFilterOperation::blend(const FilterOperation*
return this;
CustomFilterParameterList animatedParameters;
- blendCustomFilterParameters(fromOp->m_parameters, m_parameters, progress, size, animatedParameters);
+ m_parameters.blend(fromOp->m_parameters, progress, size, animatedParameters);
return CustomFilterOperation::create(m_program, animatedParameters, m_meshRows, m_meshColumns, m_meshBoxType, m_meshType);
}
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h b/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h
index 0d64d2368..edf0f129c 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h
@@ -31,38 +31,19 @@
#define CustomFilterOperation_h
#if ENABLE(CSS_SHADERS)
+#include "CustomFilterConstants.h"
+#include "CustomFilterParameterList.h"
#include "CustomFilterProgram.h"
#include "FilterOperation.h"
#include "LayoutTypes.h"
-#include <wtf/text/WTFString.h>
-
namespace WebCore {
// CSS Shaders
-class CustomFilterParameter;
-typedef Vector<RefPtr<CustomFilterParameter> > CustomFilterParameterList;
-
-bool customFilterParametersEqual(const CustomFilterParameterList&, const CustomFilterParameterList&);
-void blendCustomFilterParameters(const CustomFilterParameterList& listFrom, const CustomFilterParameterList& listTo,
- double progress, const LayoutSize&, CustomFilterParameterList& resultList);
-
class CustomFilterOperation : public FilterOperation {
public:
- enum MeshBoxType {
- FILTER_BOX,
- BORDER_BOX,
- PADDING_BOX,
- CONTENT_BOX
- };
-
- enum MeshType {
- ATTACHED,
- DETACHED
- };
-
- static PassRefPtr<CustomFilterOperation> create(PassRefPtr<CustomFilterProgram> program, const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, MeshBoxType meshBoxType, MeshType meshType)
+ static PassRefPtr<CustomFilterOperation> create(PassRefPtr<CustomFilterProgram> program, const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType meshBoxType, CustomFilterMeshType meshType)
{
return adoptRef(new CustomFilterOperation(program, sortedParameters, meshRows, meshColumns, meshBoxType, meshType));
}
@@ -74,8 +55,8 @@ public:
unsigned meshRows() const { return m_meshRows; }
unsigned meshColumns() const { return m_meshColumns; }
- MeshBoxType meshBoxType() const { return m_meshBoxType; }
- MeshType meshType() const { return m_meshType; }
+ CustomFilterMeshBoxType meshBoxType() const { return m_meshBoxType; }
+ CustomFilterMeshType meshType() const { return m_meshType; }
virtual ~CustomFilterOperation();
@@ -92,22 +73,22 @@ private:
const CustomFilterOperation* other = static_cast<const CustomFilterOperation*>(&o);
return *m_program.get() == *other->m_program.get()
- && m_meshRows == other->m_meshRows
- && m_meshColumns == other->m_meshColumns
- && m_meshBoxType == other->m_meshBoxType
- && m_meshType == other->m_meshType
- && customFilterParametersEqual(m_parameters, other->m_parameters);
+ && m_meshRows == other->m_meshRows
+ && m_meshColumns == other->m_meshColumns
+ && m_meshBoxType == other->m_meshBoxType
+ && m_meshType == other->m_meshType
+ && m_parameters == other->m_parameters;
}
- CustomFilterOperation(PassRefPtr<CustomFilterProgram>, const CustomFilterParameterList&, unsigned meshRows, unsigned meshColumns, MeshBoxType, MeshType);
+ CustomFilterOperation(PassRefPtr<CustomFilterProgram>, const CustomFilterParameterList&, unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType, CustomFilterMeshType);
RefPtr<CustomFilterProgram> m_program;
CustomFilterParameterList m_parameters;
unsigned m_meshRows;
unsigned m_meshColumns;
- MeshBoxType m_meshBoxType;
- MeshType m_meshType;
+ CustomFilterMeshBoxType m_meshBoxType;
+ CustomFilterMeshType m_meshType;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterParameterList.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterParameterList.cpp
new file mode 100644
index 000000000..cc633e9d9
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterParameterList.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER "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 THE COPYRIGHT HOLDER 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 ENABLE(CSS_SHADERS)
+#include "CustomFilterParameterList.h"
+
+#include "CustomFilterParameter.h"
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+CustomFilterParameterList::CustomFilterParameterList()
+{
+}
+
+CustomFilterParameterList::CustomFilterParameterList(size_t size)
+ : CustomFilterParameterListBase(size)
+{
+}
+
+bool CustomFilterParameterList::operator==(const CustomFilterParameterList& other) const
+{
+ if (size() != other.size())
+ return false;
+ for (size_t i = 0; i < size(); ++i) {
+ if (at(i).get() != other.at(i).get()
+ && *at(i).get() != *other.at(i).get())
+ return false;
+ }
+ return true;
+}
+
+bool CustomFilterParameterList::checkAlphabeticalOrder() const
+{
+ for (unsigned i = 1; i < size(); ++i) {
+ // Break for equal or not-sorted parameters.
+ if (!codePointCompareLessThan(at(i - 1)->name(), at(i)->name()))
+ return false;
+ }
+ return true;
+}
+
+void CustomFilterParameterList::blend(const CustomFilterParameterList& fromList,
+ double progress, const LayoutSize& frameSize, CustomFilterParameterList& resultList) const
+{
+ // This method expects both lists to be sorted by parameter name and the result list is also sorted.
+ ASSERT(checkAlphabeticalOrder());
+ ASSERT(fromList.checkAlphabeticalOrder());
+ size_t fromListIndex = 0, toListIndex = 0;
+ while (fromListIndex < fromList.size() && toListIndex < size()) {
+ CustomFilterParameter* paramFrom = fromList.at(fromListIndex).get();
+ CustomFilterParameter* paramTo = at(toListIndex).get();
+ if (paramFrom->name() == paramTo->name()) {
+ resultList.append(paramTo->blend(paramFrom, progress, frameSize));
+ ++fromListIndex;
+ ++toListIndex;
+ continue;
+ }
+ if (codePointCompareLessThan(paramFrom->name(), paramTo->name())) {
+ resultList.append(paramFrom);
+ ++fromListIndex;
+ continue;
+ }
+ resultList.append(paramTo);
+ ++toListIndex;
+ }
+ for (; fromListIndex < fromList.size(); ++fromListIndex)
+ resultList.append(fromList.at(fromListIndex));
+ for (; toListIndex < size(); ++toListIndex)
+ resultList.append(at(toListIndex));
+ ASSERT(resultList.checkAlphabeticalOrder());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(CSS_SHADERS)
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterParameterList.h b/Source/WebCore/platform/graphics/filters/CustomFilterParameterList.h
new file mode 100644
index 000000000..426756e79
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterParameterList.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER "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 THE COPYRIGHT HOLDER 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 CustomFilterParameterList_h
+#define CustomFilterParameterList_h
+
+#if ENABLE(CSS_SHADERS)
+#include "LayoutTypes.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class CustomFilterParameter;
+typedef Vector<RefPtr<CustomFilterParameter> > CustomFilterParameterListBase;
+
+class CustomFilterParameterList : public CustomFilterParameterListBase {
+public:
+ CustomFilterParameterList();
+ explicit CustomFilterParameterList(size_t);
+
+ bool checkAlphabeticalOrder() const;
+ void blend(const CustomFilterParameterList& from, double progress, const LayoutSize&, CustomFilterParameterList& resultList) const;
+ bool operator==(const CustomFilterParameterList&) const;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(CSS_SHADERS)
+
+#endif // CustomFilterParameterList_h
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp
index c9990d98d..2a8fce076 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp
@@ -38,9 +38,10 @@
namespace WebCore {
-CustomFilterProgram::CustomFilterProgram(CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings)
+CustomFilterProgram::CustomFilterProgram(CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
: m_programType(programType)
, m_mixSettings(mixSettings)
+ , m_meshType(meshType)
{
// Keep the constructor protected to prevent creating this object directly.
}
@@ -82,7 +83,14 @@ void CustomFilterProgram::notifyClients()
CustomFilterProgramInfo CustomFilterProgram::programInfo() const
{
ASSERT(isLoaded());
- return CustomFilterProgramInfo(vertexShaderString(), fragmentShaderString(), m_programType, m_mixSettings);
+ return CustomFilterProgramInfo(vertexShaderString(), fragmentShaderString(), m_programType, m_mixSettings, m_meshType);
+}
+
+bool CustomFilterProgram::operator==(const CustomFilterProgram& o) const
+{
+ return m_programType == o.m_programType
+ && (m_programType != PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE || m_mixSettings == o.m_mixSettings)
+ && m_meshType == o.m_meshType;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h b/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h
index 0492d476d..b755bb7ac 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h
@@ -51,38 +51,37 @@ public:
virtual ~CustomFilterProgram();
virtual bool isLoaded() const = 0;
-
- CustomFilterProgramMixSettings mixSettings() const { return m_mixSettings; }
void addClient(CustomFilterProgramClient*);
void removeClient(CustomFilterProgramClient*);
CustomFilterProgramInfo programInfo() const;
+
+ virtual String vertexShaderString() const = 0;
+ virtual String fragmentShaderString() const = 0;
CustomFilterProgramType programType() const { return m_programType; }
+ CustomFilterProgramMixSettings mixSettings() const { return m_mixSettings; }
+ CustomFilterMeshType meshType() const { return m_meshType; }
- // StyleCustomFilterProgram has the only implementation for the following method. That means, it casts to StyleCustomFilterProgram
- // withouth checking the type. If you add another implementation, also add a mechanism to check for the correct type.
- virtual bool operator==(const CustomFilterProgram&) const = 0;
+ virtual bool operator==(const CustomFilterProgram&) const;
bool operator!=(const CustomFilterProgram& o) const { return !(*this == o); }
protected:
// StyleCustomFilterProgram can notify the clients that the cached resources are
// loaded and it is ready to create CustomFilterCompiledProgram objects.
void notifyClients();
-
- virtual String vertexShaderString() const = 0;
- virtual String fragmentShaderString() const = 0;
-
+
virtual void willHaveClients() = 0;
virtual void didRemoveLastClient() = 0;
// Keep the constructor protected to prevent creating this object directly.
- CustomFilterProgram(CustomFilterProgramType, const CustomFilterProgramMixSettings&);
+ CustomFilterProgram(CustomFilterProgramType, const CustomFilterProgramMixSettings&, CustomFilterMeshType);
private:
typedef HashCountedSet<CustomFilterProgramClient*> CustomFilterProgramClientList;
CustomFilterProgramClientList m_clients;
CustomFilterProgramType m_programType;
CustomFilterProgramMixSettings m_mixSettings;
+ CustomFilterMeshType m_meshType;
};
}
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp
index bc1494faf..ddab9a787 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp
@@ -64,11 +64,12 @@ bool CustomFilterProgramInfo::isHashTableDeletedValue() const
&& m_fragmentShaderString.isHashTableDeletedValue();
}
-CustomFilterProgramInfo::CustomFilterProgramInfo(const String& vertexShader, const String& fragmentShader, CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings)
+CustomFilterProgramInfo::CustomFilterProgramInfo(const String& vertexShader, const String& fragmentShader, CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
: m_vertexShaderString(vertexShader)
, m_fragmentShaderString(fragmentShader)
, m_programType(programType)
, m_mixSettings(mixSettings)
+ , m_meshType(meshType)
{
// At least one of the shaders needs to be non-null.
ASSERT(!m_vertexShaderString.isNull() || !m_fragmentShaderString.isNull());
@@ -78,12 +79,15 @@ unsigned CustomFilterProgramInfo::hash() const
{
// At least one of the shaders needs to be non-null.
ASSERT(!m_vertexShaderString.isNull() || !m_fragmentShaderString.isNull());
- uintptr_t hashCodes[5] = {
+
+ bool blendsElementTexture = (m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
+ uintptr_t hashCodes[6] = {
hashPossiblyNullString(m_vertexShaderString),
hashPossiblyNullString(m_fragmentShaderString),
- m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE,
- m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE ? m_mixSettings.blendMode : 0,
- m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE ? m_mixSettings.compositeOperator : 0
+ blendsElementTexture,
+ static_cast<uintptr_t>(blendsElementTexture ? m_mixSettings.blendMode : 0),
+ static_cast<uintptr_t>(blendsElementTexture ? m_mixSettings.compositeOperator : 0),
+ m_meshType
};
return StringHasher::hashMemory<sizeof(hashCodes)>(&hashCodes);
}
@@ -93,15 +97,11 @@ bool CustomFilterProgramInfo::operator==(const CustomFilterProgramInfo& o) const
ASSERT(!isHashTableDeletedValue());
ASSERT(!o.isHashTableDeletedValue());
- if (m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE)
- return m_vertexShaderString == o.m_vertexShaderString
- && m_fragmentShaderString == o.m_fragmentShaderString
- && m_programType == o.m_programType
- && m_mixSettings == o.m_mixSettings;
-
- return m_vertexShaderString == o.m_vertexShaderString
- && m_fragmentShaderString == o.m_fragmentShaderString
- && m_programType == o.m_programType;
+ return m_programType == o.m_programType
+ && (m_programType != PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE || m_mixSettings == o.m_mixSettings)
+ && m_meshType == o.m_meshType
+ && m_vertexShaderString == o.m_vertexShaderString
+ && m_fragmentShaderString == o.m_fragmentShaderString;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h b/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h
index 3b544c5ad..cc60cca52 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h
@@ -31,6 +31,7 @@
#define CustomFilterProgramInfo_h
#if ENABLE(CSS_SHADERS)
+#include "CustomFilterConstants.h"
#include "GraphicsTypes.h"
#include <wtf/HashTraits.h>
@@ -46,7 +47,7 @@ enum CustomFilterProgramType {
struct CustomFilterProgramMixSettings {
CustomFilterProgramMixSettings()
: blendMode(BlendModeNormal)
- , compositeOperator(CompositeSourceOver)
+ , compositeOperator(CompositeSourceAtop)
{
}
@@ -64,7 +65,7 @@ struct CustomFilterProgramMixSettings {
// Null strings are placeholders for the default shader.
class CustomFilterProgramInfo {
public:
- CustomFilterProgramInfo(const String&, const String&, CustomFilterProgramType, const CustomFilterProgramMixSettings&);
+ CustomFilterProgramInfo(const String&, const String&, CustomFilterProgramType, const CustomFilterProgramMixSettings&, CustomFilterMeshType);
CustomFilterProgramInfo();
bool isEmptyValue() const;
@@ -79,11 +80,13 @@ public:
const String& fragmentShaderString() const { return m_fragmentShaderString; }
CustomFilterProgramType programType() const { return m_programType; }
const CustomFilterProgramMixSettings& mixSettings() const { return m_mixSettings; }
+ CustomFilterMeshType meshType() const { return m_meshType; }
private:
String m_vertexShaderString;
String m_fragmentShaderString;
CustomFilterProgramType m_programType;
CustomFilterProgramMixSettings m_mixSettings;
+ CustomFilterMeshType m_meshType;
};
struct CustomFilterProgramInfoHash {
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterRenderer.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterRenderer.cpp
new file mode 100644
index 000000000..1b32852cd
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterRenderer.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Company 100, 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 THE COPYRIGHT HOLDER “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 THE COPYRIGHT HOLDER 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 ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
+#include "CustomFilterRenderer.h"
+
+#include "CustomFilterArrayParameter.h"
+#include "CustomFilterConstants.h"
+#include "CustomFilterMesh.h"
+#include "CustomFilterNumberParameter.h"
+#include "CustomFilterParameter.h"
+#include "CustomFilterTransformParameter.h"
+#include "CustomFilterValidatedProgram.h"
+#include "GraphicsContext3D.h"
+#include "TransformationMatrix.h"
+
+namespace WebCore {
+
+static void orthogonalProjectionMatrix(TransformationMatrix& matrix, float left, float right, float bottom, float top)
+{
+ ASSERT(matrix.isIdentity());
+
+ float deltaX = right - left;
+ float deltaY = top - bottom;
+ if (!deltaX || !deltaY)
+ return;
+ matrix.setM11(2.0f / deltaX);
+ matrix.setM41(-(right + left) / deltaX);
+ matrix.setM22(2.0f / deltaY);
+ matrix.setM42(-(top + bottom) / deltaY);
+
+ // Use big enough near/far values, so that simple rotations of rather large objects will not
+ // get clipped. 10000 should cover most of the screen resolutions.
+ const float farValue = 10000;
+ const float nearValue = -10000;
+ matrix.setM33(-2.0f / (farValue - nearValue));
+ matrix.setM43(- (farValue + nearValue) / (farValue - nearValue));
+ matrix.setM44(1.0f);
+}
+
+PassRefPtr<CustomFilterRenderer> CustomFilterRenderer::create(PassRefPtr<GraphicsContext3D> context, PassRefPtr<CustomFilterValidatedProgram> validatedProgram, const CustomFilterParameterList& parameters,
+ unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType meshBoxType, CustomFilterMeshType meshType)
+{
+ return adoptRef(new CustomFilterRenderer(context, validatedProgram, parameters, meshRows, meshColumns, meshBoxType, meshType));
+}
+
+CustomFilterRenderer::CustomFilterRenderer(PassRefPtr<GraphicsContext3D> context, PassRefPtr<CustomFilterValidatedProgram> validatedProgram, const CustomFilterParameterList& parameters,
+ unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType, CustomFilterMeshType meshType)
+ : m_context(context)
+ , m_validatedProgram(validatedProgram)
+ , m_compiledProgram(0) // Don't compile the program unless we need to paint.
+ , m_parameters(parameters)
+ , m_meshRows(meshRows)
+ , m_meshColumns(meshColumns)
+ , m_meshType(meshType)
+{
+}
+
+CustomFilterRenderer::~CustomFilterRenderer()
+{
+}
+
+bool CustomFilterRenderer::premultipliedAlpha() const
+{
+ return m_validatedProgram->programInfo().programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE;
+}
+
+bool CustomFilterRenderer::programNeedsInputTexture() const
+{
+ ASSERT(m_compiledProgram.get());
+ return m_compiledProgram->samplerLocation() != -1;
+}
+
+void CustomFilterRenderer::draw(Platform3DObject inputTexture, const IntSize& size)
+{
+ // FIXME: We would need something like CustomFilterRendererState that will contain the size and other parameters in the future. We should pass that to bindProgramBuffers instead of storing it.
+ // https://bugs.webkit.org/show_bug.cgi?id=100107
+ m_contextSize = size;
+
+ bindProgramAndBuffers(inputTexture);
+ m_context->drawElements(GraphicsContext3D::TRIANGLES, m_mesh->indicesCount(), GraphicsContext3D::UNSIGNED_SHORT, 0);
+ unbindVertexAttributes();
+}
+
+bool CustomFilterRenderer::prepareForDrawing()
+{
+ m_context->makeContextCurrent();
+ initializeCompiledProgramIfNeeded();
+
+ // If the shader had compiler errors we cannot draw anything.
+ if (!m_compiledProgram->isInitialized())
+ return false;
+
+ initializeMeshIfNeeded();
+ return true;
+}
+
+void CustomFilterRenderer::initializeCompiledProgramIfNeeded()
+{
+ if (m_compiledProgram.get())
+ return;
+
+ m_compiledProgram = m_validatedProgram->compiledProgram();
+}
+
+void CustomFilterRenderer::initializeMeshIfNeeded()
+{
+ if (m_mesh.get())
+ return;
+
+ // FIXME: Sharing the mesh would just save the time needed to upload it to the GPU, so I assume we could
+ // benchmark that for performance.
+ // https://bugs.webkit.org/show_bug.cgi?id=88429
+ m_mesh = CustomFilterMesh::create(m_context.get(), m_meshColumns, m_meshRows, FloatRect(0, 0, 1, 1), m_meshType);
+}
+
+void CustomFilterRenderer::bindVertexAttribute(int attributeLocation, unsigned size, unsigned offset)
+{
+ if (attributeLocation != -1) {
+ m_context->vertexAttribPointer(attributeLocation, size, GraphicsContext3D::FLOAT, false, m_mesh->bytesPerVertex(), offset);
+ m_context->enableVertexAttribArray(attributeLocation);
+ }
+}
+
+void CustomFilterRenderer::unbindVertexAttribute(int attributeLocation)
+{
+ if (attributeLocation != -1)
+ m_context->disableVertexAttribArray(attributeLocation);
+}
+
+void CustomFilterRenderer::bindProgramArrayParameters(int uniformLocation, CustomFilterArrayParameter* arrayParameter)
+{
+ unsigned parameterSize = arrayParameter->size();
+ Vector<GC3Dfloat> floatVector;
+
+ for (unsigned i = 0; i < parameterSize; ++i)
+ floatVector.append(arrayParameter->valueAt(i));
+
+ m_context->uniform1fv(uniformLocation, parameterSize, floatVector.data());
+}
+
+void CustomFilterRenderer::bindProgramNumberParameters(int uniformLocation, CustomFilterNumberParameter* numberParameter)
+{
+ switch (numberParameter->size()) {
+ case 1:
+ m_context->uniform1f(uniformLocation, numberParameter->valueAt(0));
+ break;
+ case 2:
+ m_context->uniform2f(uniformLocation, numberParameter->valueAt(0), numberParameter->valueAt(1));
+ break;
+ case 3:
+ m_context->uniform3f(uniformLocation, numberParameter->valueAt(0), numberParameter->valueAt(1), numberParameter->valueAt(2));
+ break;
+ case 4:
+ m_context->uniform4f(uniformLocation, numberParameter->valueAt(0), numberParameter->valueAt(1), numberParameter->valueAt(2), numberParameter->valueAt(3));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void CustomFilterRenderer::bindProgramTransformParameter(int uniformLocation, CustomFilterTransformParameter* transformParameter)
+{
+ TransformationMatrix matrix;
+ if (m_contextSize.width() && m_contextSize.height()) {
+ // The viewport is a box with the size of 1 unit, so we are scaling up here to make sure that translations happen using real pixel
+ // units. At the end we scale back down in order to map it back to the original box. Note that transforms come in reverse order, because it is
+ // supposed to multiply to the left of the coordinates of the vertices.
+ // Note that the origin (0, 0) of the viewport is in the middle of the context, so there's no need to change the origin of the transform
+ // in order to rotate around the middle of mesh.
+ matrix.scale3d(1.0 / m_contextSize.width(), 1.0 / m_contextSize.height(), 1);
+ transformParameter->applyTransform(matrix, m_contextSize);
+ matrix.scale3d(m_contextSize.width(), m_contextSize.height(), 1);
+ }
+ float glMatrix[16];
+ matrix.toColumnMajorFloatArray(glMatrix);
+ m_context->uniformMatrix4fv(uniformLocation, 1, false, &glMatrix[0]);
+}
+
+void CustomFilterRenderer::bindProgramParameters()
+{
+ // FIXME: Find a way to reset uniforms that are not specified in CSS. This is needed to avoid using values
+ // set by other previous rendered filters.
+ // https://bugs.webkit.org/show_bug.cgi?id=76440
+
+ size_t parametersSize = m_parameters.size();
+ for (size_t i = 0; i < parametersSize; ++i) {
+ CustomFilterParameter* parameter = m_parameters.at(i).get();
+ int uniformLocation = m_compiledProgram->uniformLocationByName(parameter->name());
+ if (uniformLocation == -1)
+ continue;
+ switch (parameter->parameterType()) {
+ case CustomFilterParameter::ARRAY:
+ bindProgramArrayParameters(uniformLocation, static_cast<CustomFilterArrayParameter*>(parameter));
+ break;
+ case CustomFilterParameter::NUMBER:
+ bindProgramNumberParameters(uniformLocation, static_cast<CustomFilterNumberParameter*>(parameter));
+ break;
+ case CustomFilterParameter::TRANSFORM:
+ bindProgramTransformParameter(uniformLocation, static_cast<CustomFilterTransformParameter*>(parameter));
+ break;
+ }
+ }
+}
+
+void CustomFilterRenderer::bindProgramAndBuffers(Platform3DObject inputTexture)
+{
+ ASSERT(m_compiledProgram->isInitialized());
+
+ m_context->useProgram(m_compiledProgram->program());
+
+ if (programNeedsInputTexture()) {
+ // We should be binding the DOM element texture sampler only if the author is using the CSS mix function.
+ ASSERT(m_validatedProgram->programInfo().programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
+ ASSERT(m_compiledProgram->samplerLocation() != -1);
+
+ m_context->activeTexture(GraphicsContext3D::TEXTURE0);
+ m_context->uniform1i(m_compiledProgram->samplerLocation(), 0);
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, inputTexture);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ }
+
+ if (m_compiledProgram->projectionMatrixLocation() != -1) {
+ TransformationMatrix projectionMatrix;
+ orthogonalProjectionMatrix(projectionMatrix, -0.5, 0.5, -0.5, 0.5);
+ float glProjectionMatrix[16];
+ projectionMatrix.toColumnMajorFloatArray(glProjectionMatrix);
+ m_context->uniformMatrix4fv(m_compiledProgram->projectionMatrixLocation(), 1, false, &glProjectionMatrix[0]);
+ }
+
+ ASSERT(m_meshColumns);
+ ASSERT(m_meshRows);
+
+ if (m_compiledProgram->meshSizeLocation() != -1)
+ m_context->uniform2f(m_compiledProgram->meshSizeLocation(), m_meshColumns, m_meshRows);
+
+ if (m_compiledProgram->tileSizeLocation() != -1)
+ m_context->uniform2f(m_compiledProgram->tileSizeLocation(), 1.0 / m_meshColumns, 1.0 / m_meshRows);
+
+ if (m_compiledProgram->meshBoxLocation() != -1) {
+ // FIXME: This will change when filter margins will be implemented,
+ // see https://bugs.webkit.org/show_bug.cgi?id=71400
+ m_context->uniform4f(m_compiledProgram->meshBoxLocation(), -0.5, -0.5, 1.0, 1.0);
+ }
+
+ if (m_compiledProgram->samplerSizeLocation() != -1)
+ m_context->uniform2f(m_compiledProgram->samplerSizeLocation(), m_contextSize.width(), m_contextSize.height());
+
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_mesh->verticesBufferObject());
+ m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_mesh->elementsBufferObject());
+
+ bindVertexAttribute(m_compiledProgram->positionAttribLocation(), PositionAttribSize, PositionAttribOffset);
+ bindVertexAttribute(m_compiledProgram->texAttribLocation(), TexAttribSize, TexAttribOffset);
+ bindVertexAttribute(m_compiledProgram->meshAttribLocation(), MeshAttribSize, MeshAttribOffset);
+ if (m_meshType == MeshTypeDetached)
+ bindVertexAttribute(m_compiledProgram->triangleAttribLocation(), TriangleAttribSize, TriangleAttribOffset);
+
+ bindProgramParameters();
+}
+
+void CustomFilterRenderer::unbindVertexAttributes()
+{
+ unbindVertexAttribute(m_compiledProgram->positionAttribLocation());
+ unbindVertexAttribute(m_compiledProgram->texAttribLocation());
+ unbindVertexAttribute(m_compiledProgram->meshAttribLocation());
+ if (m_meshType == MeshTypeDetached)
+ unbindVertexAttribute(m_compiledProgram->triangleAttribLocation());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterRenderer.h b/Source/WebCore/platform/graphics/filters/CustomFilterRenderer.h
new file mode 100644
index 000000000..c0622ee04
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterRenderer.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Company 100, 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 THE COPYRIGHT HOLDER “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 THE COPYRIGHT HOLDER 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 CustomFilterRenderer_h
+#define CustomFilterRenderer_h
+
+#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
+
+#include "CustomFilterConstants.h"
+#include "CustomFilterParameterList.h"
+#include "GraphicsTypes3D.h"
+#include "IntSize.h"
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CustomFilterArrayParameter;
+class CustomFilterCompiledProgram;
+class CustomFilterMesh;
+class CustomFilterNumberParameter;
+class CustomFilterTransformParameter;
+class CustomFilterValidatedProgram;
+class GraphicsContext3D;
+
+class CustomFilterRenderer : public RefCounted<CustomFilterRenderer> {
+public:
+ static PassRefPtr<CustomFilterRenderer> create(PassRefPtr<GraphicsContext3D>, PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&,
+ unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType, CustomFilterMeshType);
+ ~CustomFilterRenderer();
+
+ bool premultipliedAlpha() const;
+ bool programNeedsInputTexture() const;
+
+ bool prepareForDrawing();
+
+ void draw(Platform3DObject, const IntSize&);
+
+private:
+ CustomFilterRenderer(PassRefPtr<GraphicsContext3D>, PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&,
+ unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType, CustomFilterMeshType);
+
+ void initializeCompiledProgramIfNeeded();
+ void initializeMeshIfNeeded();
+
+ void bindVertexAttribute(int attributeLocation, unsigned size, unsigned offset);
+ void unbindVertexAttribute(int attributeLocation);
+ void bindProgramArrayParameters(int uniformLocation, CustomFilterArrayParameter*);
+ void bindProgramNumberParameters(int uniformLocation, CustomFilterNumberParameter*);
+ void bindProgramTransformParameter(int uniformLocation, CustomFilterTransformParameter*);
+ void bindProgramParameters();
+ void bindProgramAndBuffers(Platform3DObject inputTexture);
+ void unbindVertexAttributes();
+
+ RefPtr<GraphicsContext3D> m_context;
+ RefPtr<CustomFilterValidatedProgram> m_validatedProgram;
+ RefPtr<CustomFilterCompiledProgram> m_compiledProgram;
+ RefPtr<CustomFilterMesh> m_mesh;
+ IntSize m_contextSize;
+
+ CustomFilterParameterList m_parameters;
+
+ unsigned m_meshRows;
+ unsigned m_meshColumns;
+ CustomFilterMeshType m_meshType;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
+
+#endif // CustomFilterRenderer_h
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
index 26e8b7e5f..f5ef6cff9 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
@@ -34,10 +34,12 @@
#include "CustomFilterValidatedProgram.h"
#include "ANGLEWebKitBridge.h"
+#include "CustomFilterConstants.h"
#include "CustomFilterGlobalContext.h"
#include "CustomFilterProgramInfo.h"
#include "NotImplemented.h"
#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringHash.h>
@@ -45,8 +47,6 @@ namespace WebCore {
#define SHADER(Src) (#Src)
-// FIXME: Reuse this type when we validate the types of built-in uniforms.
-// https://bugs.webkit.org/show_bug.cgi?id=98974
typedef HashMap<String, ShDataType> SymbolNameToTypeMap;
static SymbolNameToTypeMap* builtInAttributeNameToTypeMap()
@@ -62,7 +62,21 @@ static SymbolNameToTypeMap* builtInAttributeNameToTypeMap()
return nameToTypeMap;
}
-static bool validateSymbols(const Vector<ANGLEShaderSymbol>& symbols)
+static SymbolNameToTypeMap* builtInUniformNameToTypeMap()
+{
+ static SymbolNameToTypeMap* nameToTypeMap = 0;
+ if (!nameToTypeMap) {
+ nameToTypeMap = new SymbolNameToTypeMap;
+ nameToTypeMap->set("u_meshBox", SH_FLOAT_VEC4);
+ nameToTypeMap->set("u_meshSize", SH_FLOAT_VEC2);
+ nameToTypeMap->set("u_projectionMatrix", SH_FLOAT_MAT4);
+ nameToTypeMap->set("u_textureSize", SH_FLOAT_VEC2);
+ nameToTypeMap->set("u_tileSize", SH_FLOAT_VEC2);
+ }
+ return nameToTypeMap;
+}
+
+static bool validateSymbols(const Vector<ANGLEShaderSymbol>& symbols, CustomFilterMeshType meshType)
{
for (size_t i = 0; i < symbols.size(); ++i) {
const ANGLEShaderSymbol& symbol = symbols[i];
@@ -70,16 +84,27 @@ static bool validateSymbols(const Vector<ANGLEShaderSymbol>& symbols)
case SHADER_SYMBOL_TYPE_ATTRIBUTE: {
SymbolNameToTypeMap* attributeNameToTypeMap = builtInAttributeNameToTypeMap();
SymbolNameToTypeMap::iterator builtInAttribute = attributeNameToTypeMap->find(symbol.name);
- if (builtInAttribute != attributeNameToTypeMap->end() && symbol.dataType != builtInAttribute->value) {
+ if (builtInAttribute == attributeNameToTypeMap->end()) {
+ // The author defined a custom attribute.
+ // FIXME: Report the validation error.
+ // https://bugs.webkit.org/show_bug.cgi?id=74416
+ return false;
+ }
+ if (meshType == MeshTypeAttached && symbol.name == "a_triangleCoord") {
+ // a_triangleCoord is only available for detached meshes.
+ // FIXME: Report the validation error.
+ // https://bugs.webkit.org/show_bug.cgi?id=74416
+ return false;
+ }
+ if (symbol.dataType != builtInAttribute->value) {
// The author defined one of the built-in attributes with the wrong type.
+ // FIXME: Report the validation error.
+ // https://bugs.webkit.org/show_bug.cgi?id=74416
return false;
}
-
- // FIXME: Return false when the attribute is not one of the built-in attributes.
- // https://bugs.webkit.org/show_bug.cgi?id=98973
break;
}
- case SHADER_SYMBOL_TYPE_UNIFORM:
+ case SHADER_SYMBOL_TYPE_UNIFORM: {
if (symbol.isSampler()) {
// FIXME: For now, we restrict shaders with any sampler defined.
// When we implement texture parameters, we will allow shaders whose samplers are bound to valid textures.
@@ -89,9 +114,16 @@ static bool validateSymbols(const Vector<ANGLEShaderSymbol>& symbols)
return false;
}
- // FIXME: Validate the types of built-in uniforms.
- // https://bugs.webkit.org/show_bug.cgi?id=98974
+ SymbolNameToTypeMap* uniformNameToTypeMap = builtInUniformNameToTypeMap();
+ SymbolNameToTypeMap::iterator builtInUniform = uniformNameToTypeMap->find(symbol.name);
+ if (builtInUniform != uniformNameToTypeMap->end() && (symbol.isArray || symbol.dataType != builtInUniform->value)) {
+ // The author defined one of the built-in uniforms with the wrong type.
+ // FIXME: Report the validation error.
+ // https://bugs.webkit.org/show_bug.cgi?id=74416
+ return false;
+ }
break;
+ }
default:
ASSERT_NOT_REACHED();
break;
@@ -153,7 +185,7 @@ CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalCon
return;
}
- if (!validateSymbols(symbols)) {
+ if (!validateSymbols(symbols, m_programInfo.meshType())) {
// FIXME: Report validation errors.
// https://bugs.webkit.org/show_bug.cgi?id=74416
return;
@@ -161,7 +193,7 @@ CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalCon
// We need to add texture access, blending, and compositing code to shaders that are referenced from the CSS mix function.
if (blendsElementTexture) {
- rewriteMixVertexShader();
+ rewriteMixVertexShader(symbols);
rewriteMixFragmentShader();
}
@@ -171,26 +203,46 @@ CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalCon
PassRefPtr<CustomFilterCompiledProgram> CustomFilterValidatedProgram::compiledProgram()
{
ASSERT(m_isInitialized && m_globalContext && !m_validatedVertexShader.isNull() && !m_validatedFragmentShader.isNull());
- if (!m_compiledProgram)
+ if (!m_compiledProgram) {
m_compiledProgram = CustomFilterCompiledProgram::create(m_globalContext->context(), m_validatedVertexShader, m_validatedFragmentShader, m_programInfo.programType());
+ ASSERT(m_compiledProgram->samplerLocation() != -1 || !needsInputTexture());
+ }
return m_compiledProgram;
}
-void CustomFilterValidatedProgram::rewriteMixVertexShader()
+bool CustomFilterValidatedProgram::needsInputTexture() const
+{
+ return m_programInfo.programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE
+ && m_programInfo.mixSettings().compositeOperator != CompositeClear
+ && m_programInfo.mixSettings().compositeOperator != CompositeCopy;
+}
+
+void CustomFilterValidatedProgram::rewriteMixVertexShader(const Vector<ANGLEShaderSymbol>& symbols)
{
ASSERT(m_programInfo.programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
+ // If the author defined a_texCoord, we can use it to shuttle the texture coordinate to the fragment shader.
+ // Note that vertex attributes are read-only in GLSL, so the author could not have changed a_texCoord's value.
+ // Also, note that we would have already rejected the shader if the author defined a_texCoord with the wrong type.
+ bool texCoordAttributeDefined = false;
+ for (size_t i = 0; i < symbols.size(); ++i) {
+ if (symbols[i].name == "a_texCoord")
+ texCoordAttributeDefined = true;
+ }
+
+ if (!texCoordAttributeDefined)
+ m_validatedVertexShader.append("attribute mediump vec2 a_texCoord;");
+
// During validation, ANGLE renamed the author's "main" function to "css_main".
// We write our own "main" function and call "css_main" from it.
// This makes rewriting easy and ensures that our code runs after all author code.
m_validatedVertexShader.append(SHADER(
- attribute mediump vec2 css_a_texCoord;
varying mediump vec2 css_v_texCoord;
void main()
{
css_main();
- css_v_texCoord = css_a_texCoord;
+ css_v_texCoord = a_texCoord;
}
));
}
@@ -222,7 +274,7 @@ void CustomFilterValidatedProgram::rewriteMixFragmentShader()
css_main();
mediump vec4 originalColor = texture2D(css_u_texture, css_v_texCoord);
mediump vec4 multipliedColor = css_ColorMatrix * originalColor;
- mediump vec3 blendedColor = css_Blend(multipliedColor.rgb, css_MixColor.rgb);
+ mediump vec3 blendedColor = css_BlendColor(multipliedColor.rgb, css_MixColor.rgb);
gl_FragColor = css_Composite(multipliedColor.rgb, multipliedColor.a, blendedColor.rgb, css_MixColor.a);
}
));
@@ -233,36 +285,124 @@ String CustomFilterValidatedProgram::blendFunctionString(BlendMode blendMode)
{
// Implemented using the same symbol names as the Compositing and Blending spec:
// https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnormal
- // Cs: is the source color
- // Cb: is the backdrop color
- const char* expression = 0;
+ // Cs: is the source color in css_BlendColor() and the source color component in css_BlendComponent()
+ // Cb: is the backdrop color in css_BlendColor() and the backdrop color component in css_BlendComponent()
+ const char* blendColorExpression = "vec3(css_BlendComponent(Cb.r, Cs.r), css_BlendComponent(Cb.g, Cs.g), css_BlendComponent(Cb.b, Cs.b))";
+ const char* blendComponentExpression = "Co = 0.0;";
switch (blendMode) {
case BlendModeNormal:
- expression = "Cs";
+ blendColorExpression = "Cs";
break;
case BlendModeMultiply:
- expression = "Cs * Cb";
+ blendColorExpression = "Cs * Cb";
break;
case BlendModeScreen:
- expression = "Cb + Cs - (Cb * Cs)";
+ blendColorExpression = "Cb + Cs - (Cb * Cs)";
break;
case BlendModeDarken:
- expression = "min(Cb, Cs)";
+ blendColorExpression = "min(Cb, Cs)";
break;
case BlendModeLighten:
- expression = "max(Cb, Cs)";
+ blendColorExpression = "max(Cb, Cs)";
break;
case BlendModeDifference:
- expression = "abs(Cb - Cs)";
+ blendColorExpression = "abs(Cb - Cs)";
break;
case BlendModeExclusion:
- expression = "Cb + Cs - 2.0 * Cb * Cs";
+ blendColorExpression = "Cb + Cs - 2.0 * Cb * Cs";
break;
case BlendModeOverlay:
+ /*
+ Co = HardLight(Cs, Cb)
+ = if(Cb <= 0.5)
+ Multiply(Cs, 2 x Cb)
+ else
+ Screen(Cs, 2 x Cb - 1)
+ = if(Cb <= 0.5)
+ Cs x (2 x Cb)
+ else
+ Cs + (2 x Cb - 1) - (Cs x (2 x Cb - 1))
+ */
+ blendComponentExpression = SHADER(
+ if (Cb <= 0.5)
+ Co = Cs * (2.0 * Cb);
+ else
+ Co = Cs + (2.0 * Cb - 1.0) - (Cs * (2.0 * Cb - 1.0));
+ );
+ break;
case BlendModeColorDodge:
+ /*
+ Co = if(Cs < 1)
+ min(1, Cb / (1 - Cs))
+ else
+ 1
+ */
+ blendComponentExpression = SHADER(
+ if (Cs < 1.0)
+ Co = min(1.0, Cb / (1.0 - Cs));
+ else
+ Co = 1.0;
+ );
+ break;
case BlendModeColorBurn:
+ /*
+ Co = if(Cs > 0)
+ 1 - min(1, (1 - Cb) / Cs)
+ else
+ 0
+ */
+ blendComponentExpression = SHADER(
+ if (Cs > 0.0)
+ Co = 1.0 - min(1.0, (1.0 - Cb) / Cs);
+ else
+ Co = 0.0;
+ );
+ break;
case BlendModeHardLight:
+ /*
+ Co = if(Cs <= 0.5)
+ Multiply(Cb, 2 x Cs)
+ else
+ Screen(Cb, 2 x Cs -1)
+ = if(Cs <= 0.5)
+ Cb x (2 x Cs)
+ else
+ Cb + (2 x Cs - 1) - (Cb x (2 x Cs - 1))
+ */
+ blendComponentExpression = SHADER(
+ if (Cs <= 0.5)
+ Co = Cb * (2.0 * Cs);
+ else
+ Co = Cb + (2.0 * Cs - 1.0) - (Cb * (2.0 * Cs - 1.0));
+ );
+ break;
case BlendModeSoftLight:
+ /*
+ Co = if(Cs <= 0.5)
+ Cb - (1 - 2 x Cs) x Cb x (1 - Cb)
+ else
+ Cb + (2 x Cs - 1) x (D(Cb) - Cb)
+
+ with
+
+ D(Cb) = if(Cb <= 0.25)
+ (16 * Cb - 12) x Cb + 4) x Cb
+ else
+ sqrt(Cb)
+ */
+ blendComponentExpression = SHADER(
+ mediump float D;
+ if (Cb <= 0.25)
+ D = ((16.0 * Cb - 12.0) * Cb + 4.0) * Cb;
+ else
+ D = sqrt(Cb);
+
+ if (Cs <= 0.5)
+ Co = Cb - (1.0 - 2.0 * Cs) * Cb * (1.0 - Cb);
+ else
+ Co = Cb + (2.0 * Cs - 1.0) * (D - Cb);
+ );
+ break;
case BlendModeHue:
case BlendModeSaturation:
case BlendModeColor:
@@ -271,13 +411,18 @@ String CustomFilterValidatedProgram::blendFunctionString(BlendMode blendMode)
return String();
}
- ASSERT(expression);
return String::format(SHADER(
- mediump vec3 css_Blend(mediump vec3 Cb, mediump vec3 Cs)
+ mediump float css_BlendComponent(mediump float Cb, mediump float Cs)
+ {
+ mediump float Co;
+ %s
+ return Co;
+ }
+ mediump vec3 css_BlendColor(mediump vec3 Cb, mediump vec3 Cs)
{
return %s;
}
- ), expression);
+ ), blendComponentExpression, blendColorExpression);
}
String CustomFilterValidatedProgram::compositeFunctionString(CompositeOperator compositeOperator)
@@ -298,15 +443,45 @@ String CustomFilterValidatedProgram::compositeFunctionString(CompositeOperator c
Fb = "1.0 - as";
break;
case CompositeClear:
+ Fa = "0.0";
+ Fb = "0.0";
+ break;
case CompositeCopy:
+ Fa = "1.0";
+ Fb = "0.0";
+ break;
case CompositeSourceOver:
+ Fa = "1.0";
+ Fb = "1.0 - as";
+ break;
case CompositeSourceIn:
+ Fa = "ab";
+ Fb = "0.0";
+ break;
case CompositeSourceOut:
+ Fa = "1.0 - ab";
+ Fb = "0.0";
+ break;
case CompositeDestinationOver:
+ Fa = "1.0 - ab";
+ Fb = "1.0";
+ break;
case CompositeDestinationIn:
+ Fa = "0.0";
+ Fb = "as";
+ break;
case CompositeDestinationOut:
+ Fa = "0.0";
+ Fb = "1.0 - as";
+ break;
case CompositeDestinationAtop:
+ Fa = "1.0 - ab";
+ Fb = "as";
+ break;
case CompositeXOR:
+ Fa = "1.0 - ab";
+ Fb = "1.0 - as";
+ break;
case CompositePlusLighter:
notImplemented();
return String();
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.h b/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.h
index 610884d6e..b722ac35c 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.h
@@ -49,7 +49,7 @@ typedef WebCore::LayerCompiledProgram PlatformCompiledProgram;
namespace WebCore {
-class ANGLEWebKitBridge;
+struct ANGLEShaderSymbol;
class CustomFilterCompiledProgram;
class CustomFilterGlobalContext;
@@ -100,9 +100,11 @@ private:
static String blendFunctionString(BlendMode);
static String compositeFunctionString(CompositeOperator);
- void rewriteMixVertexShader();
+ void rewriteMixVertexShader(const Vector<ANGLEShaderSymbol>& symbols);
void rewriteMixFragmentShader();
+ bool needsInputTexture() const;
+
CustomFilterGlobalContext* m_globalContext;
CustomFilterProgramInfo m_programInfo;
diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.h b/Source/WebCore/platform/graphics/filters/FEBlend.h
index e58c8a3d0..5c71c2b72 100644
--- a/Source/WebCore/platform/graphics/filters/FEBlend.h
+++ b/Source/WebCore/platform/graphics/filters/FEBlend.h
@@ -51,6 +51,7 @@ public:
unsigned colorArrayLength);
#if USE(SKIA)
virtual bool platformApplySkia();
+ virtual SkImageFilter* createImageFilter(SkiaImageFilterBuilder*);
#endif
virtual void platformApplySoftware();
diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h
index 27a4ac843..99b650b9c 100644
--- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h
+++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h
@@ -51,6 +51,7 @@ public:
virtual void platformApplySoftware();
#if USE(SKIA)
virtual bool platformApplySkia();
+ virtual SkImageFilter* createImageFilter(SkiaImageFilterBuilder*);
#endif
virtual void dump();
diff --git a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h
index 18183e6cc..68454fd35 100644
--- a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h
+++ b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h
@@ -81,6 +81,7 @@ public:
virtual void platformApplySoftware();
#if USE(SKIA)
virtual bool platformApplySkia();
+ virtual SkImageFilter* createImageFilter(SkiaImageFilterBuilder*);
#endif
virtual void dump();
diff --git a/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp b/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp
index 707edb866..45a110fb2 100644
--- a/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp
+++ b/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp
@@ -33,61 +33,22 @@
#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
#include "FECustomFilter.h"
-#include "CustomFilterArrayParameter.h"
-#include "CustomFilterCompiledProgram.h"
-#include "CustomFilterConstants.h"
-#include "CustomFilterGlobalContext.h"
-#include "CustomFilterMesh.h"
-#include "CustomFilterNumberParameter.h"
-#include "CustomFilterParameter.h"
-#include "CustomFilterProgram.h"
-#include "CustomFilterTransformParameter.h"
+#include "CustomFilterRenderer.h"
#include "CustomFilterValidatedProgram.h"
-#include "DrawingBuffer.h"
#include "Extensions3D.h"
#include "GraphicsContext3D.h"
-#include "ImageData.h"
-#include "NotImplemented.h"
#include "RenderTreeAsText.h"
#include "TextStream.h"
-#include "TilingData.h"
-#include "TransformationMatrix.h"
#include <wtf/Uint8ClampedArray.h>
namespace WebCore {
-static const int kMaxSampleCount = 4;
-
-static void orthogonalProjectionMatrix(TransformationMatrix& matrix, float left, float right, float bottom, float top)
-{
- ASSERT(matrix.isIdentity());
-
- float deltaX = right - left;
- float deltaY = top - bottom;
- if (!deltaX || !deltaY)
- return;
- matrix.setM11(2.0f / deltaX);
- matrix.setM41(-(right + left) / deltaX);
- matrix.setM22(2.0f / deltaY);
- matrix.setM42(-(top + bottom) / deltaY);
-
- // Use big enough near/far values, so that simple rotations of rather large objects will not
- // get clipped. 10000 should cover most of the screen resolutions.
- const float farValue = 10000;
- const float nearValue = -10000;
- matrix.setM33(-2.0f / (farValue - nearValue));
- matrix.setM43(- (farValue + nearValue) / (farValue - nearValue));
- matrix.setM44(1.0f);
-}
-
-FECustomFilter::FECustomFilter(Filter* filter, CustomFilterGlobalContext* customFilterGlobalContext, PassRefPtr<CustomFilterValidatedProgram> validatedProgram, const CustomFilterParameterList& parameters,
- unsigned meshRows, unsigned meshColumns, CustomFilterOperation::MeshBoxType,
- CustomFilterOperation::MeshType meshType)
+FECustomFilter::FECustomFilter(Filter* filter, PassRefPtr<GraphicsContext3D> context, PassRefPtr<CustomFilterValidatedProgram> validatedProgram, const CustomFilterParameterList& parameters,
+ unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType meshBoxType, CustomFilterMeshType meshType)
: FilterEffect(filter)
- , m_globalContext(customFilterGlobalContext)
- , m_validatedProgram(validatedProgram)
- , m_compiledProgram(0) // Don't compile the program unless we need to paint.
+ , m_context(context)
+ , m_customFilterRenderer(CustomFilterRenderer::create(m_context, validatedProgram, parameters, meshRows, meshColumns, meshBoxType, meshType))
, m_inputTexture(0)
, m_frameBuffer(0)
, m_depthBuffer(0)
@@ -96,20 +57,13 @@ FECustomFilter::FECustomFilter(Filter* filter, CustomFilterGlobalContext* custom
, m_multisampleFrameBuffer(0)
, m_multisampleRenderBuffer(0)
, m_multisampleDepthBuffer(0)
- , m_parameters(parameters)
- , m_meshRows(meshRows)
- , m_meshColumns(meshColumns)
- , m_meshType(meshType)
{
- // An FECustomFilter shouldn't have been created unless the program passed validation.
- ASSERT(m_validatedProgram->isInitialized());
}
-PassRefPtr<FECustomFilter> FECustomFilter::create(Filter* filter, CustomFilterGlobalContext* customFilterGlobalContext, PassRefPtr<CustomFilterValidatedProgram> validatedProgram, const CustomFilterParameterList& parameters,
- unsigned meshRows, unsigned meshColumns, CustomFilterOperation::MeshBoxType meshBoxType,
- CustomFilterOperation::MeshType meshType)
+PassRefPtr<FECustomFilter> FECustomFilter::create(Filter* filter, PassRefPtr<GraphicsContext3D> context, PassRefPtr<CustomFilterValidatedProgram> validatedProgram, const CustomFilterParameterList& parameters,
+ unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType meshBoxType, CustomFilterMeshType meshType)
{
- return adoptRef(new FECustomFilter(filter, customFilterGlobalContext, validatedProgram, parameters, meshRows, meshColumns, meshBoxType, meshType));
+ return adoptRef(new FECustomFilter(filter, context, validatedProgram, parameters, meshRows, meshColumns, meshBoxType, meshType));
}
FECustomFilter::~FECustomFilter()
@@ -119,8 +73,7 @@ FECustomFilter::~FECustomFilter()
void FECustomFilter::deleteRenderBuffers()
{
- if (!m_context)
- return;
+ ASSERT(m_context);
m_context->makeContextCurrent();
if (m_inputTexture) {
m_context->deleteTexture(m_inputTexture);
@@ -187,45 +140,33 @@ void FECustomFilter::drawFilterMesh(Platform3DObject inputTexture)
bool multisample = canUseMultisampleBuffers();
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, multisample ? m_multisampleFrameBuffer : m_frameBuffer);
m_context->viewport(0, 0, m_contextSize.width(), m_contextSize.height());
-
+
m_context->clearColor(0, 0, 0, 0);
m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT);
-
- bindProgramAndBuffers(inputTexture);
- m_context->drawElements(GraphicsContext3D::TRIANGLES, m_mesh->indicesCount(), GraphicsContext3D::UNSIGNED_SHORT, 0);
- unbindVertexAttributes();
+
+ m_customFilterRenderer->draw(inputTexture, m_contextSize);
if (multisample)
resolveMultisampleBuffer();
}
-bool FECustomFilter::prepareForDrawing(CustomFilterDrawType filterDrawType)
+bool FECustomFilter::prepareForDrawing()
{
- if (!m_context && !initializeContext())
- return false;
m_context->makeContextCurrent();
- // If the shader had compiler errors we cannot draw anything.
- if (!m_compiledProgram->isInitialized())
+ if (!m_customFilterRenderer->prepareForDrawing())
return false;
-
+
// Only allocate a texture if the program needs one and the caller doesn't allocate one by itself.
- if ((programNeedsInputTexture() && (filterDrawType == NEEDS_INPUT_TEXTURE) && !ensureInputTexture())
- || !ensureFrameBuffer())
+ if ((m_customFilterRenderer->programNeedsInputTexture() && !ensureInputTexture()) || !ensureFrameBuffer())
return false;
-
- return true;
-}
-bool FECustomFilter::programNeedsInputTexture() const
-{
- ASSERT(m_compiledProgram.get());
- return m_compiledProgram->samplerLocation() != -1;
+ return true;
}
bool FECustomFilter::applyShader()
{
- Uint8ClampedArray* dstPixelArray = m_validatedProgram->programInfo().programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE ? createPremultipliedImageResult() : createUnmultipliedImageResult();
+ Uint8ClampedArray* dstPixelArray = m_customFilterRenderer->premultipliedAlpha() ? createPremultipliedImageResult() : createUnmultipliedImageResult();
if (!dstPixelArray)
return false;
@@ -238,7 +179,7 @@ bool FECustomFilter::applyShader()
if (!resizeContextIfNeeded(newContextSize))
return false;
- bool needsInputTexture = programNeedsInputTexture();
+ bool needsInputTexture = m_customFilterRenderer->programNeedsInputTexture();
if (needsInputTexture) {
RefPtr<Uint8ClampedArray> srcPixelArray = in->asUnmultipliedImage(effectDrawingRect);
uploadInputTexture(srcPixelArray.get());
@@ -251,25 +192,6 @@ bool FECustomFilter::applyShader()
return true;
}
-bool FECustomFilter::initializeContext()
-{
- ASSERT(!m_context.get());
- m_context = m_globalContext->context();
- if (!m_context)
- return false;
- m_context->makeContextCurrent();
- m_compiledProgram = m_validatedProgram->compiledProgram();
-
- // FIXME: Sharing the mesh would just save the time needed to upload it to the GPU, so I assume we could
- // benchmark that for performance.
- // https://bugs.webkit.org/show_bug.cgi?id=88429
- m_mesh = CustomFilterMesh::create(m_context.get(), m_meshColumns, m_meshRows,
- FloatRect(0, 0, 1, 1),
- m_meshType);
-
- return true;
-}
-
bool FECustomFilter::ensureInputTexture()
{
if (!m_inputTexture)
@@ -332,7 +254,7 @@ void FECustomFilter::resolveMultisampleBuffer()
m_context->bindFramebuffer(Extensions3D::READ_FRAMEBUFFER, 0);
m_context->bindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, 0);
-
+
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_frameBuffer);
}
@@ -344,11 +266,12 @@ bool FECustomFilter::canUseMultisampleBuffers() const
bool FECustomFilter::resizeMultisampleBuffers(const IntSize& newContextSize)
{
if (!m_triedMultisampleBuffer && !createMultisampleBuffer())
- return false;
-
+ return false;
+
if (!canUseMultisampleBuffers())
return false;
+ static const int kMaxSampleCount = 4;
int maxSupportedSampleCount = 0;
m_context->getIntegerv(Extensions3D::MAX_SAMPLES, &maxSupportedSampleCount);
int sampleCount = std::min(kMaxSampleCount, maxSupportedSampleCount);
@@ -359,7 +282,7 @@ bool FECustomFilter::resizeMultisampleBuffers(const IntSize& newContextSize)
Extensions3D* extensions = m_context->getExtensions();
ASSERT(extensions);
-
+
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFrameBuffer);
m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleRenderBuffer);
@@ -409,7 +332,7 @@ bool FECustomFilter::resizeContext(const IntSize& newContextSize)
m_context->texImage2DDirect(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, newContextSize.width(), newContextSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
#endif
m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_destTexture, 0);
-
+
// We don't need the depth buffer for the texture framebuffer, if we already
// have a multisample buffer.
if (!multisample) {
@@ -428,171 +351,11 @@ bool FECustomFilter::resizeContext(const IntSize& newContextSize)
}
m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
-
+
m_contextSize = newContextSize;
return true;
}
-void FECustomFilter::bindVertexAttribute(int attributeLocation, unsigned size, unsigned offset)
-{
- if (attributeLocation != -1) {
- m_context->vertexAttribPointer(attributeLocation, size, GraphicsContext3D::FLOAT, false, m_mesh->bytesPerVertex(), offset);
- m_context->enableVertexAttribArray(attributeLocation);
- }
-}
-
-void FECustomFilter::unbindVertexAttribute(int attributeLocation)
-{
- if (attributeLocation != -1)
- m_context->disableVertexAttribArray(attributeLocation);
-}
-
-void FECustomFilter::bindProgramArrayParameters(int uniformLocation, CustomFilterArrayParameter* arrayParameter)
-{
- unsigned parameterSize = arrayParameter->size();
- Vector<GC3Dfloat> floatVector;
-
- for (unsigned i = 0; i < parameterSize; ++i)
- floatVector.append(arrayParameter->valueAt(i));
-
- m_context->uniform1fv(uniformLocation, parameterSize, floatVector.data());
-}
-
-void FECustomFilter::bindProgramNumberParameters(int uniformLocation, CustomFilterNumberParameter* numberParameter)
-{
- switch (numberParameter->size()) {
- case 1:
- m_context->uniform1f(uniformLocation, numberParameter->valueAt(0));
- break;
- case 2:
- m_context->uniform2f(uniformLocation, numberParameter->valueAt(0), numberParameter->valueAt(1));
- break;
- case 3:
- m_context->uniform3f(uniformLocation, numberParameter->valueAt(0), numberParameter->valueAt(1), numberParameter->valueAt(2));
- break;
- case 4:
- m_context->uniform4f(uniformLocation, numberParameter->valueAt(0), numberParameter->valueAt(1), numberParameter->valueAt(2), numberParameter->valueAt(3));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-}
-
-void FECustomFilter::bindProgramTransformParameter(int uniformLocation, CustomFilterTransformParameter* transformParameter)
-{
- TransformationMatrix matrix;
- if (m_contextSize.width() && m_contextSize.height()) {
- // The viewport is a box with the size of 1 unit, so we are scalling up here to make sure that translations happen using real pixel
- // units. At the end we scale back down in order to map it back to the original box. Note that transforms come in reverse order, because it is
- // supposed to multiply to the left of the coordinates of the vertices.
- // Note that the origin (0, 0) of the viewport is in the middle of the context, so there's no need to change the origin of the transform
- // in order to rotate around the middle of mesh.
- matrix.scale3d(1.0 / m_contextSize.width(), 1.0 / m_contextSize.height(), 1);
- transformParameter->applyTransform(matrix, m_contextSize);
- matrix.scale3d(m_contextSize.width(), m_contextSize.height(), 1);
- }
- float glMatrix[16];
- matrix.toColumnMajorFloatArray(glMatrix);
- m_context->uniformMatrix4fv(uniformLocation, 1, false, &glMatrix[0]);
-}
-
-void FECustomFilter::bindProgramParameters()
-{
- // FIXME: Find a way to reset uniforms that are not specified in CSS. This is needed to avoid using values
- // set by other previous rendered filters.
- // https://bugs.webkit.org/show_bug.cgi?id=76440
-
- size_t parametersSize = m_parameters.size();
- for (size_t i = 0; i < parametersSize; ++i) {
- CustomFilterParameter* parameter = m_parameters.at(i).get();
- int uniformLocation = m_compiledProgram->uniformLocationByName(parameter->name());
- if (uniformLocation == -1)
- continue;
- switch (parameter->parameterType()) {
- case CustomFilterParameter::ARRAY:
- bindProgramArrayParameters(uniformLocation, static_cast<CustomFilterArrayParameter*>(parameter));
- break;
- case CustomFilterParameter::NUMBER:
- bindProgramNumberParameters(uniformLocation, static_cast<CustomFilterNumberParameter*>(parameter));
- break;
- case CustomFilterParameter::TRANSFORM:
- bindProgramTransformParameter(uniformLocation, static_cast<CustomFilterTransformParameter*>(parameter));
- break;
- }
- }
-}
-
-void FECustomFilter::bindProgramAndBuffers(Platform3DObject inputTexture)
-{
- ASSERT(m_compiledProgram->isInitialized());
-
- m_context->useProgram(m_compiledProgram->program());
-
- if (programNeedsInputTexture()) {
- // We should be binding the DOM element texture sampler only if the author is using the CSS mix function.
- ASSERT(m_validatedProgram->programInfo().programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
- ASSERT(m_compiledProgram->samplerLocation() != -1);
-
- m_context->activeTexture(GraphicsContext3D::TEXTURE0);
- m_context->uniform1i(m_compiledProgram->samplerLocation(), 0);
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, inputTexture);
- m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
- m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
- m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
- m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
- }
-
- if (m_compiledProgram->projectionMatrixLocation() != -1) {
- TransformationMatrix projectionMatrix;
- orthogonalProjectionMatrix(projectionMatrix, -0.5, 0.5, -0.5, 0.5);
- float glProjectionMatrix[16];
- projectionMatrix.toColumnMajorFloatArray(glProjectionMatrix);
- m_context->uniformMatrix4fv(m_compiledProgram->projectionMatrixLocation(), 1, false, &glProjectionMatrix[0]);
- }
-
- ASSERT(m_meshColumns);
- ASSERT(m_meshRows);
-
- if (m_compiledProgram->meshSizeLocation() != -1)
- m_context->uniform2f(m_compiledProgram->meshSizeLocation(), m_meshColumns, m_meshRows);
-
- if (m_compiledProgram->tileSizeLocation() != -1)
- m_context->uniform2f(m_compiledProgram->tileSizeLocation(), 1.0 / m_meshColumns, 1.0 / m_meshRows);
-
- if (m_compiledProgram->meshBoxLocation() != -1) {
- // FIXME: This will change when filter margins will be implemented,
- // see https://bugs.webkit.org/show_bug.cgi?id=71400
- m_context->uniform4f(m_compiledProgram->meshBoxLocation(), -0.5, -0.5, 1.0, 1.0);
- }
-
- if (m_compiledProgram->samplerSizeLocation() != -1)
- m_context->uniform2f(m_compiledProgram->samplerSizeLocation(), m_contextSize.width(), m_contextSize.height());
-
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_mesh->verticesBufferObject());
- m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_mesh->elementsBufferObject());
-
- bindVertexAttribute(m_compiledProgram->positionAttribLocation(), PositionAttribSize, PositionAttribOffset);
- bindVertexAttribute(m_compiledProgram->texAttribLocation(), TexAttribSize, TexAttribOffset);
- // FIXME: Get rid of the internal tex coord attribute "css_a_texCoord".
- // https://bugs.webkit.org/show_bug.cgi?id=94358
- bindVertexAttribute(m_compiledProgram->internalTexCoordAttribLocation(), TexAttribSize, TexAttribOffset);
- bindVertexAttribute(m_compiledProgram->meshAttribLocation(), MeshAttribSize, MeshAttribOffset);
- if (m_meshType == CustomFilterOperation::DETACHED)
- bindVertexAttribute(m_compiledProgram->triangleAttribLocation(), TriangleAttribSize, TriangleAttribOffset);
-
- bindProgramParameters();
-}
-
-void FECustomFilter::unbindVertexAttributes()
-{
- unbindVertexAttribute(m_compiledProgram->positionAttribLocation());
- unbindVertexAttribute(m_compiledProgram->texAttribLocation());
- unbindVertexAttribute(m_compiledProgram->internalTexCoordAttribLocation());
- unbindVertexAttribute(m_compiledProgram->meshAttribLocation());
- if (m_meshType == CustomFilterOperation::DETACHED)
- unbindVertexAttribute(m_compiledProgram->triangleAttribLocation());
-}
-
void FECustomFilter::dump()
{
}
diff --git a/Source/WebCore/platform/graphics/filters/FECustomFilter.h b/Source/WebCore/platform/graphics/filters/FECustomFilter.h
index 09da5f1c7..44e68f1ca 100644
--- a/Source/WebCore/platform/graphics/filters/FECustomFilter.h
+++ b/Source/WebCore/platform/graphics/filters/FECustomFilter.h
@@ -32,6 +32,7 @@
#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
+#include "CustomFilterConstants.h"
#include "CustomFilterOperation.h"
#include "Filter.h"
#include "FilterEffect.h"
@@ -44,23 +45,15 @@ class Uint8ClampedArray;
namespace WebCore {
-class CachedShader;
-class CustomFilterArrayParameter;
-class CustomFilterCompiledProgram;
-class CustomFilterGlobalContext;
-class CustomFilterMesh;
-class CustomFilterNumberParameter;
-class CustomFilterTransformParameter;
+class CustomFilterRenderer;
class CustomFilterValidatedProgram;
-class DrawingBuffer;
class GraphicsContext3D;
class IntSize;
class FECustomFilter : public FilterEffect {
public:
- static PassRefPtr<FECustomFilter> create(Filter*, CustomFilterGlobalContext*, PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&,
- unsigned meshRows, unsigned meshColumns, CustomFilterOperation::MeshBoxType,
- CustomFilterOperation::MeshType);
+ static PassRefPtr<FECustomFilter> create(Filter*, PassRefPtr<GraphicsContext3D>, PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&,
+ unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType, CustomFilterMeshType);
virtual void platformApplySoftware();
virtual void dump();
@@ -68,23 +61,17 @@ public:
virtual TextStream& externalRepresentation(TextStream&, int indention) const;
private:
- FECustomFilter(Filter*, CustomFilterGlobalContext*, PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&,
- unsigned meshRows, unsigned meshColumns, CustomFilterOperation::MeshBoxType,
- CustomFilterOperation::MeshType);
+ FECustomFilter(Filter*, PassRefPtr<GraphicsContext3D>, PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&,
+ unsigned meshRows, unsigned meshColumns, CustomFilterMeshBoxType, CustomFilterMeshType);
~FECustomFilter();
-
+
bool applyShader();
void clearShaderResult();
bool initializeContext();
-
- enum CustomFilterDrawType {
- NEEDS_INPUT_TEXTURE,
- NO_INPUT_TEXTURE
- };
- bool prepareForDrawing(CustomFilterDrawType = NEEDS_INPUT_TEXTURE);
+
+ bool prepareForDrawing();
void drawFilterMesh(Platform3DObject inputTexture);
- bool programNeedsInputTexture() const;
bool ensureInputTexture();
void uploadInputTexture(Uint8ClampedArray* srcPixelArray);
bool resizeContextIfNeeded(const IntSize&);
@@ -99,22 +86,8 @@ private:
bool ensureFrameBuffer();
void deleteRenderBuffers();
- void bindVertexAttribute(int attributeLocation, unsigned size, unsigned offset);
- void unbindVertexAttribute(int attributeLocation);
- void bindProgramArrayParameters(int uniformLocation, CustomFilterArrayParameter*);
- void bindProgramNumberParameters(int uniformLocation, CustomFilterNumberParameter*);
- void bindProgramTransformParameter(int uniformLocation, CustomFilterTransformParameter*);
- void bindProgramParameters();
- void bindProgramAndBuffers(Platform3DObject inputTexture);
- void unbindVertexAttributes();
-
- // No need to keep a reference here. It is owned by the RenderView.
- CustomFilterGlobalContext* m_globalContext;
-
RefPtr<GraphicsContext3D> m_context;
- RefPtr<CustomFilterValidatedProgram> m_validatedProgram;
- RefPtr<CustomFilterCompiledProgram> m_compiledProgram;
- RefPtr<CustomFilterMesh> m_mesh;
+ RefPtr<CustomFilterRenderer> m_customFilterRenderer;
IntSize m_contextSize;
Platform3DObject m_inputTexture;
@@ -126,12 +99,6 @@ private:
Platform3DObject m_multisampleFrameBuffer;
Platform3DObject m_multisampleRenderBuffer;
Platform3DObject m_multisampleDepthBuffer;
-
- CustomFilterParameterList m_parameters;
-
- unsigned m_meshRows;
- unsigned m_meshColumns;
- CustomFilterOperation::MeshType m_meshType;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h
index 7b3bdce29..daf3ef17a 100644
--- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h
+++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h
@@ -75,6 +75,7 @@ private:
inline void platformApplyGeneric(Uint8ClampedArray* srcPixelArray, Uint8ClampedArray* tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize);
#if USE(SKIA)
virtual bool platformApplySkia();
+ virtual SkImageFilter* createImageFilter(SkiaImageFilterBuilder*);
#endif
float m_stdX;
diff --git a/Source/WebCore/platform/graphics/filters/FELighting.h b/Source/WebCore/platform/graphics/filters/FELighting.h
index 4487835e8..288985d42 100644
--- a/Source/WebCore/platform/graphics/filters/FELighting.h
+++ b/Source/WebCore/platform/graphics/filters/FELighting.h
@@ -47,6 +47,7 @@ class FELighting : public FilterEffect {
public:
virtual void platformApplySoftware();
#if USE(SKIA)
+ virtual SkImageFilter* createImageFilter(SkiaImageFilterBuilder*);
virtual bool platformApplySkia();
#endif
diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.h b/Source/WebCore/platform/graphics/filters/FEMorphology.h
index 19da635a2..b38e673c3 100644
--- a/Source/WebCore/platform/graphics/filters/FEMorphology.h
+++ b/Source/WebCore/platform/graphics/filters/FEMorphology.h
@@ -49,6 +49,8 @@ public:
virtual void platformApplySoftware();
#if USE(SKIA)
virtual bool platformApplySkia();
+ virtual SkImageFilter* createImageFilter(SkiaImageFilterBuilder*);
+
#endif
virtual void dump();
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h
index 1620abf1e..069ede3ee 100644
--- a/Source/WebCore/platform/graphics/filters/FilterEffect.h
+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h
@@ -35,6 +35,10 @@
static const float kMaxFilterSize = 5000.0f;
+#if USE(SKIA)
+class SkImageFilter;
+#endif
+
namespace WebCore {
class Filter;
@@ -42,6 +46,10 @@ class FilterEffect;
class ImageBuffer;
class TextStream;
+#if USE(SKIA)
+class SkiaImageFilterBuilder;
+#endif
+
typedef Vector<RefPtr<FilterEffect> > FilterEffectVector;
enum FilterEffectType {
@@ -95,6 +103,7 @@ public:
virtual void platformApplySoftware() = 0;
#if USE(SKIA)
virtual bool platformApplySkia() { return false; }
+ virtual SkImageFilter* createImageFilter(SkiaImageFilterBuilder*) { return 0; }
#endif
virtual void dump() = 0;
diff --git a/Source/WebCore/platform/graphics/filters/FilterOperation.h b/Source/WebCore/platform/graphics/filters/FilterOperation.h
index 6d2503ac3..906706bea 100644
--- a/Source/WebCore/platform/graphics/filters/FilterOperation.h
+++ b/Source/WebCore/platform/graphics/filters/FilterOperation.h
@@ -29,6 +29,7 @@
#if ENABLE(CSS_FILTERS)
#include "Color.h"
+#include "FilterEffect.h"
#include "LayoutTypes.h"
#include "Length.h"
#include <wtf/OwnPtr.h>
@@ -69,6 +70,7 @@ public:
DROP_SHADOW,
#if ENABLE(CSS_SHADERS)
CUSTOM,
+ VALIDATED_CUSTOM,
#endif
PASSTHROUGH,
NONE
@@ -161,14 +163,21 @@ public:
return adoptRef(new ReferenceFilterOperation(url, fragment, type));
}
+ class Data {
+ public:
+ virtual ~Data() { }
+ };
+
virtual bool affectsOpacity() const { return true; }
virtual bool movesPixels() const { return true; }
const String& url() const { return m_url; }
const String& fragment() const { return m_fragment; }
- void* data() const { return m_data; }
- void setData(void* data) { m_data = data; }
+ Data* data() const { return m_data.get(); }
+ void setData(PassOwnPtr<Data> data) { m_data = data; }
+ FilterEffect* filterEffect() const { return m_filterEffect.get(); }
+ void setFilterEffect(PassRefPtr<FilterEffect> filterEffect) { m_filterEffect = filterEffect; }
private:
@@ -184,13 +193,13 @@ private:
: FilterOperation(type)
, m_url(url)
, m_fragment(fragment)
- , m_data(0)
{
}
String m_url;
String m_fragment;
- void* m_data;
+ OwnPtr<Data> m_data;
+ RefPtr<FilterEffect> m_filterEffect;
};
// GRAYSCALE, SEPIA, SATURATE and HUE_ROTATE are variations on a basic color matrix effect.
diff --git a/Source/WebCore/platform/graphics/filters/FilterOperations.cpp b/Source/WebCore/platform/graphics/filters/FilterOperations.cpp
index c4b876593..fcb74fc32 100644
--- a/Source/WebCore/platform/graphics/filters/FilterOperations.cpp
+++ b/Source/WebCore/platform/graphics/filters/FilterOperations.cpp
@@ -91,7 +91,8 @@ bool FilterOperations::operationsMatch(const FilterOperations& other) const
bool FilterOperations::hasCustomFilter() const
{
for (size_t i = 0; i < m_operations.size(); ++i) {
- if (m_operations.at(i)->getOperationType() == FilterOperation::CUSTOM)
+ FilterOperation::OperationType type = m_operations.at(i)->getOperationType();
+ if (type == FilterOperation::CUSTOM || type == FilterOperation::VALIDATED_CUSTOM)
return true;
}
return false;
@@ -146,8 +147,10 @@ void FilterOperations::getOutsets(int& top, int& right, int& bottom, int& left)
break;
}
#if ENABLE(CSS_SHADERS)
- case FilterOperation::CUSTOM: {
- // Need to include the filter margins here.
+ case FilterOperation::CUSTOM:
+ case FilterOperation::VALIDATED_CUSTOM: {
+ // FIXME: Need to include the filter margins here.
+ // https://bugs.webkit.org/show_bug.cgi?id=71400
break;
}
#endif
diff --git a/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.cpp b/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.cpp
new file mode 100644
index 000000000..35def2f38
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER "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 THE COPYRIGHT HOLDER 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 ENABLE(CSS_SHADERS)
+#include "ValidatedCustomFilterOperation.h"
+
+#include "CustomFilterParameter.h"
+#include "CustomFilterValidatedProgram.h"
+#include "FractionalLayoutSize.h"
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+ValidatedCustomFilterOperation::ValidatedCustomFilterOperation(PassRefPtr<CustomFilterValidatedProgram> validatedProgram,
+ const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, CustomFilterMeshType meshType)
+ : FilterOperation(VALIDATED_CUSTOM)
+ , m_validatedProgram(validatedProgram)
+ , m_parameters(sortedParameters)
+ , m_meshRows(meshRows)
+ , m_meshColumns(meshColumns)
+ , m_meshType(meshType)
+{
+}
+
+ValidatedCustomFilterOperation::~ValidatedCustomFilterOperation()
+{
+}
+
+PassRefPtr<FilterOperation> ValidatedCustomFilterOperation::blend(const FilterOperation*, double progress, const LayoutSize& size, bool blendToPassthrough)
+{
+ UNUSED_PARAM(progress);
+ UNUSED_PARAM(size);
+ UNUSED_PARAM(blendToPassthrough);
+
+ ASSERT_NOT_REACHED();
+ return this;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(CSS_SHADERS)
diff --git a/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.h b/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.h
new file mode 100644
index 000000000..cf88d5144
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER "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 THE COPYRIGHT HOLDER 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 ValidatedCustomFilterOperation_h
+#define ValidatedCustomFilterOperation_h
+
+#if ENABLE(CSS_SHADERS)
+#include "CustomFilterConstants.h"
+#include "CustomFilterParameterList.h"
+#include "FilterOperation.h"
+#include "LayoutTypes.h"
+
+namespace WebCore {
+
+class CustomFilterValidatedProgram;
+
+class ValidatedCustomFilterOperation : public FilterOperation {
+public:
+ static PassRefPtr<ValidatedCustomFilterOperation> create(PassRefPtr<CustomFilterValidatedProgram> validatedProgram,
+ const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, CustomFilterMeshType meshType)
+ {
+ return adoptRef(new ValidatedCustomFilterOperation(validatedProgram, sortedParameters, meshRows, meshColumns, meshType));
+ }
+
+ virtual ~ValidatedCustomFilterOperation();
+
+ virtual bool affectsOpacity() const { return true; }
+ virtual bool movesPixels() const { return true; }
+ virtual bool blendingNeedsRendererSize() const { return true; }
+
+ virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, const LayoutSize&, bool blendToPassthrough = false);
+
+ CustomFilterValidatedProgram* validatedProgram() const { return m_validatedProgram.get(); }
+ const CustomFilterParameterList& parameters() const { return m_parameters; }
+
+ unsigned meshRows() const { return m_meshRows; }
+ unsigned meshColumns() const { return m_meshColumns; }
+
+ CustomFilterMeshType meshType() const { return m_meshType; }
+
+private:
+ virtual bool operator==(const FilterOperation& o) const
+ {
+ if (!isSameType(o))
+ return false;
+
+ const ValidatedCustomFilterOperation* other = static_cast<const ValidatedCustomFilterOperation*>(&o);
+ return m_validatedProgram.get() == other->m_validatedProgram.get()
+ && m_meshRows == other->m_meshRows
+ && m_meshColumns == other->m_meshColumns
+ && m_meshType == other->m_meshType
+ && m_parameters == other->m_parameters;
+ }
+
+ ValidatedCustomFilterOperation(PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&, unsigned meshRows, unsigned meshColumns, CustomFilterMeshType);
+
+ RefPtr<CustomFilterValidatedProgram> m_validatedProgram;
+
+ CustomFilterParameterList m_parameters;
+ unsigned m_meshRows;
+ unsigned m_meshColumns;
+ CustomFilterMeshType m_meshType;
+
+ // FIXME: Add CustomFilterMeshBoxType after 100782 is landed.
+ // https://bugs.webkit.org/show_bug.cgi?id=100890
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(CSS_SHADERS)
+
+#endif // ValidatedCustomFilterOperation_h
diff --git a/Source/WebCore/platform/graphics/filters/skia/FEBlendSkia.cpp b/Source/WebCore/platform/graphics/filters/skia/FEBlendSkia.cpp
index fdca432f4..8089f3b50 100644
--- a/Source/WebCore/platform/graphics/filters/skia/FEBlendSkia.cpp
+++ b/Source/WebCore/platform/graphics/filters/skia/FEBlendSkia.cpp
@@ -31,6 +31,7 @@
#include "NativeImageSkia.h"
#include "SkBitmapSource.h"
#include "SkBlendImageFilter.h"
+#include "SkiaImageFilterBuilder.h"
namespace WebCore {
@@ -84,6 +85,14 @@ bool FEBlend::platformApplySkia()
return true;
}
+SkImageFilter* FEBlend::createImageFilter(SkiaImageFilterBuilder* builder)
+{
+ SkImageFilter* foreground = builder->build(inputEffect(0));
+ SkImageFilter* background = builder->build(inputEffect(1));
+ SkBlendImageFilter::Mode mode = toSkiaMode(m_mode);
+ return new SkBlendImageFilter(mode, background, foreground);
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/skia/FEColorMatrixSkia.cpp b/Source/WebCore/platform/graphics/filters/skia/FEColorMatrixSkia.cpp
index 0fd07776e..affbaead0 100644
--- a/Source/WebCore/platform/graphics/filters/skia/FEColorMatrixSkia.cpp
+++ b/Source/WebCore/platform/graphics/filters/skia/FEColorMatrixSkia.cpp
@@ -28,7 +28,9 @@
#include "FEColorMatrix.h"
#include "NativeImageSkia.h"
+#include "SkColorFilterImageFilter.h"
#include "SkColorMatrixFilter.h"
+#include "SkiaImageFilterBuilder.h"
namespace WebCore {
@@ -80,24 +82,15 @@ static void luminanceToAlphaMatrix(SkScalar matrix[20])
matrix[17] = 0.0721f;
}
-bool FEColorMatrix::platformApplySkia()
+static SkColorFilter* createColorFilter(ColorMatrixType type, const float* values)
{
- ImageBuffer* resultImage = createImageBufferResult();
- if (!resultImage)
- return false;
-
- FilterEffect* in = inputEffect(0);
-
- IntRect imageRect(IntPoint(), absolutePaintRect().size());
-
SkScalar matrix[20];
-
- switch (m_type) {
+ switch (type) {
case FECOLORMATRIX_TYPE_UNKNOWN:
break;
case FECOLORMATRIX_TYPE_MATRIX:
for (int i = 0; i < 20; ++i)
- matrix[i] = m_values[i];
+ matrix[i] = values[i];
matrix[4] *= SkScalar(255);
matrix[9] *= SkScalar(255);
@@ -105,15 +98,29 @@ bool FEColorMatrix::platformApplySkia()
matrix[19] *= SkScalar(255);
break;
case FECOLORMATRIX_TYPE_SATURATE:
- saturateMatrix(m_values[0], matrix);
+ saturateMatrix(values[0], matrix);
break;
case FECOLORMATRIX_TYPE_HUEROTATE:
- hueRotateMatrix(m_values[0], matrix);
+ hueRotateMatrix(values[0], matrix);
break;
case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
luminanceToAlphaMatrix(matrix);
break;
}
+ return new SkColorMatrixFilter(matrix);
+}
+
+bool FEColorMatrix::platformApplySkia()
+{
+ ImageBuffer* resultImage = createImageBufferResult();
+ if (!resultImage)
+ return false;
+
+ FilterEffect* in = inputEffect(0);
+
+ IntRect imageRect(IntPoint(), absolutePaintRect().size());
+
+ SkAutoTUnref<SkColorFilter> filter(createColorFilter(m_type, m_values.data()));
RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore);
NativeImageSkia* nativeImage = image->nativeImageForCurrentFrame();
@@ -122,12 +129,19 @@ bool FEColorMatrix::platformApplySkia()
SkCanvas* canvas = resultImage->context()->platformContext()->canvas();
SkPaint paint;
- paint.setColorFilter(new SkColorMatrixFilter(matrix))->unref();
+ paint.setColorFilter(filter);
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
canvas->drawBitmap(nativeImage->bitmap(), 0, 0, &paint);
return true;
}
+SkImageFilter* FEColorMatrix::createImageFilter(SkiaImageFilterBuilder* builder)
+{
+ SkAutoTUnref<SkImageFilter> input(builder->build(inputEffect(0)));
+ SkAutoTUnref<SkColorFilter> filter(createColorFilter(m_type, m_values.data()));
+ return SkColorFilterImageFilter::Create(filter, input);
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS) && USE(SKIA)
diff --git a/Source/WebCore/platform/graphics/filters/skia/FEComponentTransferSkia.cpp b/Source/WebCore/platform/graphics/filters/skia/FEComponentTransferSkia.cpp
index 577a5b065..86d5d7e66 100644
--- a/Source/WebCore/platform/graphics/filters/skia/FEComponentTransferSkia.cpp
+++ b/Source/WebCore/platform/graphics/filters/skia/FEComponentTransferSkia.cpp
@@ -29,7 +29,9 @@
#include "FEComponentTransfer.h"
#include "NativeImageSkia.h"
+#include "SkColorFilterImageFilter.h"
#include "SkTableColorFilter.h"
+#include "SkiaImageFilterBuilder.h"
namespace WebCore {
@@ -55,6 +57,18 @@ bool FEComponentTransfer::platformApplySkia()
return true;
}
+SkImageFilter* FEComponentTransfer::createImageFilter(SkiaImageFilterBuilder* builder)
+{
+ SkImageFilter* input = builder->build(inputEffect(0));
+
+ unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
+ getValues(rValues, gValues, bValues, aValues);
+
+ SkAutoTUnref<SkColorFilter> colorFilter(SkTableColorFilter::CreateARGB(aValues, rValues, gValues, bValues));
+
+ return SkColorFilterImageFilter::Create(colorFilter, input);
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp b/Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp
index b694c9b1c..f5f46daed 100644
--- a/Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp
+++ b/Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp
@@ -29,6 +29,7 @@
#include "BitmapImageSingleFrameSkia.h"
#include "SkBlurImageFilter.h"
+#include "SkiaImageFilterBuilder.h"
namespace WebCore {
@@ -61,5 +62,11 @@ bool FEGaussianBlur::platformApplySkia()
return true;
}
+SkImageFilter* FEGaussianBlur::createImageFilter(SkiaImageFilterBuilder* builder)
+{
+ SkAutoTUnref<SkImageFilter> input(builder->build(inputEffect(0)));
+ return new SkBlurImageFilter(SkFloatToScalar(m_stdX), SkFloatToScalar(m_stdY), input);
+}
+
};
#endif
diff --git a/Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp b/Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp
index 1a6a2d70e..167234d3b 100644
--- a/Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp
+++ b/Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp
@@ -31,32 +31,14 @@
#include "NativeImageSkia.h"
#include "PointLightSource.h"
#include "SkLightingImageFilter.h"
+#include "SkiaImageFilterBuilder.h"
#include "SpotLightSource.h"
namespace WebCore {
-bool FELighting::platformApplySkia()
+SkImageFilter* FELighting::createImageFilter(SkiaImageFilterBuilder* builder)
{
- // For now, only use the skia implementation for accelerated rendering.
- if (filter()->renderingMode() != Accelerated)
- return false;
-
- ImageBuffer* resultImage = createImageBufferResult();
- if (!resultImage)
- return false;
-
- FilterEffect* in = inputEffect(0);
-
- IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect());
-
- setIsAlphaImage(in->isAlphaImage());
-
- RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore);
- NativeImageSkia* nativeImage = image->nativeImageForCurrentFrame();
-
- GraphicsContext* dstContext = resultImage->context();
-
- SkPaint paint;
+ SkImageFilter* input = builder ? builder->build(inputEffect(0)) : 0;
switch (m_lightSource->type()) {
case LS_DISTANT: {
DistantLightSource* distantLightSource = static_cast<DistantLightSource*>(m_lightSource.get());
@@ -66,20 +48,18 @@ bool FELighting::platformApplySkia()
sinf(azimuthRad) * cosf(elevationRad),
sinf(elevationRad));
if (m_specularConstant > 0)
- paint.setImageFilter(SkLightingImageFilter::CreateDistantLitSpecular(direction, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent))->unref();
+ return SkLightingImageFilter::CreateDistantLitSpecular(direction, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input);
else
- paint.setImageFilter(SkLightingImageFilter::CreateDistantLitDiffuse(direction, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant))->unref();
- break;
+ return SkLightingImageFilter::CreateDistantLitDiffuse(direction, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant, input);
}
case LS_POINT: {
PointLightSource* pointLightSource = static_cast<PointLightSource*>(m_lightSource.get());
FloatPoint3D position = pointLightSource->position();
SkPoint3 skPosition(position.x(), position.y(), position.z());
if (m_specularConstant > 0)
- paint.setImageFilter(SkLightingImageFilter::CreatePointLitSpecular(skPosition, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent))->unref();
+ return SkLightingImageFilter::CreatePointLitSpecular(skPosition, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input);
else
- paint.setImageFilter(SkLightingImageFilter::CreatePointLitDiffuse(skPosition, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant))->unref();
- break;
+ return SkLightingImageFilter::CreatePointLitDiffuse(skPosition, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant, input);
}
case LS_SPOT: {
SpotLightSource* spotLightSource = static_cast<SpotLightSource*>(m_lightSource.get());
@@ -90,15 +70,39 @@ bool FELighting::platformApplySkia()
if (!limitingConeAngle || limitingConeAngle > 90 || limitingConeAngle < -90)
limitingConeAngle = 90;
if (m_specularConstant > 0)
- paint.setImageFilter(SkLightingImageFilter::CreateSpotLitSpecular(location, target, specularExponent, limitingConeAngle, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent))->unref();
+ return SkLightingImageFilter::CreateSpotLitSpecular(location, target, specularExponent, limitingConeAngle, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input);
else
- paint.setImageFilter(SkLightingImageFilter::CreateSpotLitDiffuse(location, target, specularExponent, limitingConeAngle, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant))->unref();
- break;
+ return SkLightingImageFilter::CreateSpotLitDiffuse(location, target, specularExponent, limitingConeAngle, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant, input);
}
default:
ASSERT_NOT_REACHED();
- return false;
+ return 0;
}
+}
+
+bool FELighting::platformApplySkia()
+{
+ // For now, only use the skia implementation for accelerated rendering.
+ if (filter()->renderingMode() != Accelerated)
+ return false;
+
+ ImageBuffer* resultImage = createImageBufferResult();
+ if (!resultImage)
+ return false;
+
+ FilterEffect* in = inputEffect(0);
+
+ IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect());
+
+ setIsAlphaImage(in->isAlphaImage());
+
+ RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore);
+ NativeImageSkia* nativeImage = image->nativeImageForCurrentFrame();
+
+ GraphicsContext* dstContext = resultImage->context();
+
+ SkPaint paint;
+ paint.setImageFilter(createImageFilter(0))->unref();
dstContext->platformContext()->canvas()->drawBitmap(nativeImage->bitmap(), drawingRegion.location().x(), drawingRegion.location().y(), &paint);
return true;
}
diff --git a/Source/WebCore/platform/graphics/filters/skia/FEMorphologySkia.cpp b/Source/WebCore/platform/graphics/filters/skia/FEMorphologySkia.cpp
index e7290bec7..b2e9f4fcf 100644
--- a/Source/WebCore/platform/graphics/filters/skia/FEMorphologySkia.cpp
+++ b/Source/WebCore/platform/graphics/filters/skia/FEMorphologySkia.cpp
@@ -28,6 +28,7 @@
#include "FEMorphology.h"
#include "SkMorphologyImageFilter.h"
+#include "SkiaImageFilterBuilder.h"
namespace WebCore {
@@ -62,5 +63,15 @@ bool FEMorphology::platformApplySkia()
return true;
}
+SkImageFilter* FEMorphology::createImageFilter(SkiaImageFilterBuilder* builder)
+{
+ SkAutoTUnref<SkImageFilter> input(builder->build(inputEffect(0)));
+ SkScalar radiusX = SkFloatToScalar(m_radiusX);
+ SkScalar radiusY = SkFloatToScalar(m_radiusY);
+ if (m_type == FEMORPHOLOGY_OPERATOR_DILATE)
+ return new SkDilateImageFilter(radiusX, radiusY, input);
+ return new SkErodeImageFilter(radiusX, radiusY, input);
+}
+
};
#endif
diff --git a/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.cpp b/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.cpp
new file mode 100644
index 000000000..da891fb85
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2012 Google 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 AND ITS CONTRIBUTORS "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 OR ITS 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 "SkiaImageFilterBuilder.h"
+
+#include "FilterEffect.h"
+#include "FilterOperations.h"
+#include "SkBlurImageFilter.h"
+#include "SkColorFilterImageFilter.h"
+#include "SkColorMatrixFilter.h"
+#include "SkMatrix.h"
+
+namespace {
+
+void getBrightnessMatrix(float amount, SkScalar matrix[20])
+{
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1;
+ matrix[4] = matrix[9] = matrix[14] = amount * 255;
+}
+
+void getContrastMatrix(float amount, SkScalar matrix[20])
+{
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = amount;
+ matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255;
+ matrix[18] = 1;
+}
+
+void getSaturateMatrix(float amount, SkScalar matrix[20])
+{
+ // Note, these values are computed to ensure matrixNeedsClamping is false
+ // for amount in [0..1]
+ matrix[0] = 0.213f + 0.787f * amount;
+ matrix[1] = 0.715f - 0.715f * amount;
+ matrix[2] = 1.f - (matrix[0] + matrix[1]);
+ matrix[3] = matrix[4] = 0;
+ matrix[5] = 0.213f - 0.213f * amount;
+ matrix[6] = 0.715f + 0.285f * amount;
+ matrix[7] = 1.f - (matrix[5] + matrix[6]);
+ matrix[8] = matrix[9] = 0;
+ matrix[10] = 0.213f - 0.213f * amount;
+ matrix[11] = 0.715f - 0.715f * amount;
+ matrix[12] = 1.f - (matrix[10] + matrix[11]);
+ matrix[13] = matrix[14] = 0;
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
+ matrix[18] = 1;
+}
+
+void getHueRotateMatrix(float hue, SkScalar matrix[20])
+{
+ float cosHue = cosf(hue * piFloat / 180);
+ float sinHue = sinf(hue * piFloat / 180);
+ matrix[0] = 0.213f + cosHue * 0.787f - sinHue * 0.213f;
+ matrix[1] = 0.715f - cosHue * 0.715f - sinHue * 0.715f;
+ matrix[2] = 0.072f - cosHue * 0.072f + sinHue * 0.928f;
+ matrix[3] = matrix[4] = 0;
+ matrix[5] = 0.213f - cosHue * 0.213f + sinHue * 0.143f;
+ matrix[6] = 0.715f + cosHue * 0.285f + sinHue * 0.140f;
+ matrix[7] = 0.072f - cosHue * 0.072f - sinHue * 0.283f;
+ matrix[8] = matrix[9] = 0;
+ matrix[10] = 0.213f - cosHue * 0.213f - sinHue * 0.787f;
+ matrix[11] = 0.715f - cosHue * 0.715f + sinHue * 0.715f;
+ matrix[12] = 0.072f + cosHue * 0.928f + sinHue * 0.072f;
+ matrix[13] = matrix[14] = 0;
+ matrix[15] = matrix[16] = matrix[17] = 0;
+ matrix[18] = 1;
+ matrix[19] = 0;
+}
+
+void getInvertMatrix(float amount, SkScalar matrix[20])
+{
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = 1 - 2 * amount;
+ matrix[4] = matrix[9] = matrix[14] = amount * 255;
+ matrix[18] = 1;
+}
+
+void getOpacityMatrix(float amount, SkScalar matrix[20])
+{
+ memset(matrix, 0, 20 * sizeof(SkScalar));
+ matrix[0] = matrix[6] = matrix[12] = 1;
+ matrix[18] = amount;
+}
+
+void getGrayscaleMatrix(float amount, SkScalar matrix[20])
+{
+ // Note, these values are computed to ensure matrixNeedsClamping is false
+ // for amount in [0..1]
+ matrix[0] = 0.2126f + 0.7874f * amount;
+ matrix[1] = 0.7152f - 0.7152f * amount;
+ matrix[2] = 1.f - (matrix[0] + matrix[1]);
+ matrix[3] = matrix[4] = 0;
+
+ matrix[5] = 0.2126f - 0.2126f * amount;
+ matrix[6] = 0.7152f + 0.2848f * amount;
+ matrix[7] = 1.f - (matrix[5] + matrix[6]);
+ matrix[8] = matrix[9] = 0;
+
+ matrix[10] = 0.2126f - 0.2126f * amount;
+ matrix[11] = 0.7152f - 0.7152f * amount;
+ matrix[12] = 1.f - (matrix[10] + matrix[11]);
+ matrix[13] = matrix[14] = 0;
+
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
+ matrix[18] = 1;
+}
+
+void getSepiaMatrix(float amount, SkScalar matrix[20])
+{
+ matrix[0] = 0.393f + 0.607f * amount;
+ matrix[1] = 0.769f - 0.769f * amount;
+ matrix[2] = 0.189f - 0.189f * amount;
+ matrix[3] = matrix[4] = 0;
+
+ matrix[5] = 0.349f - 0.349f * amount;
+ matrix[6] = 0.686f + 0.314f * amount;
+ matrix[7] = 0.168f - 0.168f * amount;
+ matrix[8] = matrix[9] = 0;
+
+ matrix[10] = 0.272f - 0.272f * amount;
+ matrix[11] = 0.534f - 0.534f * amount;
+ matrix[12] = 0.131f + 0.869f * amount;
+ matrix[13] = matrix[14] = 0;
+
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
+ matrix[18] = 1;
+}
+
+SkImageFilter* createMatrixImageFilter(SkScalar matrix[20], SkImageFilter* input)
+{
+ SkAutoTUnref<SkColorFilter> colorFilter(new SkColorMatrixFilter(matrix));
+ return SkColorFilterImageFilter::Create(colorFilter, input);
+}
+
+};
+
+namespace WebCore {
+
+SkiaImageFilterBuilder::SkiaImageFilterBuilder()
+{
+}
+
+SkImageFilter* SkiaImageFilterBuilder::build(FilterEffect* effect)
+{
+ if (!effect)
+ return 0;
+
+ FilterBuilderHashMap::iterator it = m_map.find(effect);
+ if (it != m_map.end())
+ return it->value;
+
+ SkImageFilter* filter = effect->createImageFilter(this);
+ m_map.set(effect, filter);
+ return filter;
+}
+
+SkImageFilter* SkiaImageFilterBuilder::build(const FilterOperations& operations)
+{
+ SkImageFilter* filter = 0;
+ SkScalar matrix[20];
+ for (size_t i = 0; i < operations.size(); ++i) {
+ const FilterOperation& op = *operations.at(i);
+ switch (op.getOperationType()) {
+ case FilterOperation::REFERENCE: {
+ FilterEffect* filterEffect = static_cast<const ReferenceFilterOperation*>(&op)->filterEffect();
+ // FIXME: hook up parent filter to image source
+ filter = SkiaImageFilterBuilder::build(filterEffect);
+ break;
+ }
+ case FilterOperation::GRAYSCALE: {
+ float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
+ getGrayscaleMatrix(amount, matrix);
+ filter = createMatrixImageFilter(matrix, filter);
+ break;
+ }
+ case FilterOperation::SEPIA: {
+ float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
+ getSepiaMatrix(amount, matrix);
+ filter = createMatrixImageFilter(matrix, filter);
+ break;
+ }
+ case FilterOperation::SATURATE: {
+ float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
+ getSaturateMatrix(amount, matrix);
+ filter = createMatrixImageFilter(matrix, filter);
+ break;
+ }
+ case FilterOperation::HUE_ROTATE: {
+ float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
+ getHueRotateMatrix(amount, matrix);
+ filter = createMatrixImageFilter(matrix, filter);
+ break;
+ }
+ case FilterOperation::INVERT: {
+ float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
+ getInvertMatrix(amount, matrix);
+ filter = createMatrixImageFilter(matrix, filter);
+ break;
+ }
+ case FilterOperation::OPACITY: {
+ float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
+ getOpacityMatrix(amount, matrix);
+ filter = createMatrixImageFilter(matrix, filter);
+ break;
+ }
+ case FilterOperation::BRIGHTNESS: {
+ float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
+ getBrightnessMatrix(amount, matrix);
+ filter = createMatrixImageFilter(matrix, filter);
+ break;
+ }
+ case FilterOperation::CONTRAST: {
+ float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
+ getContrastMatrix(amount, matrix);
+ filter = createMatrixImageFilter(matrix, filter);
+ break;
+ }
+ case FilterOperation::BLUR: {
+ float pixelRadius = static_cast<const BlurFilterOperation*>(&op)->stdDeviation().getFloatValue();
+ filter = new SkBlurImageFilter(pixelRadius, pixelRadius, filter);
+ break;
+ }
+ case FilterOperation::DROP_SHADOW: {
+// const DropShadowFilterOperation& dropShadowOp = *static_cast<const DropShadowFilterOperation*>(&op);
+ // FIXME: do offset and blur
+ break;
+ }
+#if ENABLE(CSS_SHADERS)
+ case FilterOperation::VALIDATED_CUSTOM:
+ case FilterOperation::CUSTOM:
+ // Not supported.
+#endif
+ case FilterOperation::PASSTHROUGH:
+ case FilterOperation::NONE:
+ break;
+ }
+ }
+ return filter;
+}
+
+};
diff --git a/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.h b/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.h
new file mode 100644
index 000000000..27bd68320
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/skia/SkiaImageFilterBuilder.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Google 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 AND ITS CONTRIBUTORS "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 OR ITS 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 SkiaImageFilterBuilder_h
+#define SkiaImageFilterBuilder_h
+
+#include <wtf/HashMap.h>
+
+class SkImageFilter;
+
+namespace WebCore {
+class FilterEffect;
+class FilterOperations;
+
+class SkiaImageFilterBuilder {
+public:
+ SkiaImageFilterBuilder();
+
+ SkImageFilter* build(FilterEffect*);
+ SkImageFilter* build(const FilterOperations&);
+private:
+ typedef HashMap<FilterEffect*, SkImageFilter*> FilterBuilderHashMap;
+ FilterBuilderHashMap m_map;
+};
+
+};
+
+#endif
diff --git a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
index 30d889f5c..a16ad17df 100644
--- a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
+++ b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
@@ -98,27 +98,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
m_platformData.syntheticOblique()), isCustomFont(), false);
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- // FIXME: I think we want to ask FontConfig for the right font again.
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
-
- return m_derivedFontData->emphasisMark;
-}
-
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
ASSERT(m_platformData.scaledFont());
diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp
index e0686166d..b7d444f08 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp
@@ -322,6 +322,14 @@ bool HarfBuzzShaper::shapeHarfBuzzRuns()
HarfBuzzRun* currentRun = m_harfbuzzRuns[runIndex].get();
const SimpleFontData* currentFontData = currentRun->fontData();
+ // This #if should be removed after all ports update harfbuzz-ng.
+#if PLATFORM(CHROMIUM)
+ // Add a space as pre-context to the buffer. This prevents showing dotted-circle
+ // for combining marks at the beginning of runs.
+ static const uint16_t preContext = ' ';
+ hb_buffer_add_utf16(harfbuzzBuffer.get(), &preContext, 1, 1, 0);
+#endif
+
if (m_font->isSmallCaps() && u_islower(m_normalizedBuffer[currentRun->startIndex()])) {
String upperText = String(m_normalizedBuffer.get() + currentRun->startIndex(), currentRun->numCharacters());
upperText.makeUpper();
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index f8bb43ba7..fc23bbd9b 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -52,8 +52,6 @@ using namespace std;
namespace WebCore {
-const float smallCapsFontSizeMultiplier = 0.7f;
-
static bool fontHasVerticalGlyphs(CTFontRef ctFont)
{
// The check doesn't look neat but this is what AppKit does for vertical writing...
@@ -352,26 +350,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
return 0;
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFontSizeMultiplier);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5f);
-
- return m_derivedFontData->emphasisMark;
-}
-
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
NSString *string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(characters) length:length freeWhenDone:NO];
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
index db9fe43b6..58cfd7f7e 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
@@ -222,7 +222,7 @@ void GraphicsContext3D::reshape(int width, int height)
if (width == m_currentWidth && height == m_currentHeight)
return;
-#if PLATFORM(QT) && USE(GRAPHICS_SURFACE)
+#if (PLATFORM(QT) || PLATFORM(EFL)) && USE(GRAPHICS_SURFACE)
::glFlush(); // Make sure all GL calls have been committed before resizing.
createGraphicsSurfaces(IntSize(width, height));
#endif
@@ -1406,6 +1406,8 @@ void GraphicsContext3D::deleteShader(Platform3DObject shader)
void GraphicsContext3D::deleteTexture(Platform3DObject texture)
{
makeContextCurrent();
+ if (m_boundTexture0 == texture)
+ m_boundTexture0 = 0;
glDeleteTextures(1, &texture);
}
diff --git a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
index 4fc1fbe3e..f88cbbb7a 100644
--- a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
+++ b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
@@ -92,26 +92,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
return SimpleFontData::create(platformData);
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
-
- return m_derivedFontData->emphasisMark;
-}
-
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
bool result = true;
diff --git a/Source/WebCore/platform/graphics/qt/FontQt.cpp b/Source/WebCore/platform/graphics/qt/FontQt.cpp
index f5bacddcc..e2cde765b 100644
--- a/Source/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/FontQt.cpp
@@ -210,7 +210,10 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
QTextLine line = setupLayout(&layout, run);
float x1 = line.cursorToX(0);
float x2 = line.cursorToX(run.length());
- const float width = qAbs(x2 - x1);
+ float width = qAbs(x2 - x1);
+ // RenderBlockLineLayout expects us to only add word-spacing for trailing spaces, not for leading spaces.
+ if (treatAsSpace(run[0]))
+ width -= m_wordSpacing;
return width + run.expansion();
}
@@ -275,6 +278,9 @@ void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
+ if (!fontData->platformData().size())
+ return;
+
if (context->paintingDisabled())
return;
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index 9ec765caa..e083e2973 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -45,6 +45,8 @@
#include <QTimer>
#include <QUrl>
#include <limits>
+#include <qmediametadata.h>
+#include <qmultimedia.h>
#include <wtf/HashSet.h>
#include <wtf/text/CString.h>
@@ -92,7 +94,7 @@ MediaPlayer::SupportsType MediaPlayerPrivateQt::supportsType(const String& mime,
codecListTrimmed.append(codecStrTrimmed);
}
- if (QMediaPlayer::hasSupport(mime, codecListTrimmed) >= QtMultimedia::ProbablySupported)
+ if (QMediaPlayer::hasSupport(mime, codecListTrimmed) >= QMultimedia::ProbablySupported)
return MediaPlayer::IsSupported;
return MediaPlayer::MayBeSupported;
@@ -366,8 +368,8 @@ bool MediaPlayerPrivateQt::didLoadingProgress() const
unsigned MediaPlayerPrivateQt::totalBytes() const
{
- if (m_mediaPlayer->availableMetaData().contains(QtMultimedia::MetaData::Size))
- return m_mediaPlayer->metaData(QtMultimedia::MetaData::Size).toInt();
+ if (m_mediaPlayer->availableMetaData().contains(QMediaMetaData::Size))
+ return m_mediaPlayer->metaData(QMediaMetaData::Size).toInt();
return 100;
}
diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
index 677d6086c..415f00d44 100644
--- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
@@ -34,9 +34,6 @@ void SimpleFontData::determinePitch()
m_treatAsFixedPitch = false;
}
-static const float smallCapsFraction = 0.7;
-static const float emphasisMarkFraction = 0.5;
-
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
QRawFont rawFont(m_platformData.rawFont());
@@ -67,26 +64,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
return SimpleFontData::create(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false);
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFraction);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, emphasisMarkFraction);
-
- return m_derivedFontData->emphasisMark;
-}
-
FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
{
notImplemented();
diff --git a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 697fde224..ad47cf4b2 100644
--- a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -194,6 +194,7 @@ bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3DOb
context.pixelStorei(Extensions3D::UNPACK_FLIP_Y_CHROMIUM, false);
context.pixelStorei(Extensions3D::UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false);
+ context.flush();
return true;
}
diff --git a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
index e5a52411d..1dbda0fda 100644
--- a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -389,9 +389,9 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
}
if (resampling == RESAMPLE_NONE) {
- // FIXME: This is to not break tests (it results in the filter bitmap flag
- // being set to true). We need to decide if we respect RESAMPLE_NONE
- // being returned from computeResamplingMode.
+ // FIXME: This is to not break tests (it results in the filter bitmap flag
+ // being set to true). We need to decide if we respect RESAMPLE_NONE
+ // being returned from computeResamplingMode.
resampling = RESAMPLE_LINEAR;
}
resampling = limitResamplingMode(platformContext, resampling);
@@ -449,6 +449,8 @@ bool FrameData::clear(bool clearMetadata)
if (clearMetadata)
m_haveMetadata = false;
+ m_orientation = DefaultImageOrientation;
+
if (m_frame) {
// ImageSource::createFrameAtIndex() allocated |m_frame| and passed
// ownership to BitmapImage; we must delete it here.
@@ -470,14 +472,15 @@ void Image::drawPattern(GraphicsContext* context,
#if PLATFORM(CHROMIUM)
TRACE_EVENT0("skia", "Image::drawPattern");
#endif
- FloatRect normSrcRect = normalizeRect(floatSrcRect);
- if (destRect.isEmpty() || normSrcRect.isEmpty())
- return; // nothing to draw
-
NativeImageSkia* bitmap = nativeImageForCurrentFrame();
if (!bitmap)
return;
+ FloatRect normSrcRect = normalizeRect(floatSrcRect);
+ normSrcRect.intersect(FloatRect(0, 0, bitmap->bitmap().width(), bitmap->bitmap().height()));
+ if (destRect.isEmpty() || normSrcRect.isEmpty())
+ return; // nothing to draw
+
SkMatrix ctm = context->platformContext()->canvas()->getTotalMatrix();
SkMatrix totalMatrix;
totalMatrix.setConcat(ctm, patternTransform);
@@ -582,8 +585,12 @@ void BitmapImage::checkForSolidColor()
}
}
-void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
- const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp)
+void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp)
+{
+ draw(ctxt, dstRect, srcRect, colorSpace, compositeOp, DoNotRespectImageOrientation);
+}
+
+void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp, RespectImageOrientationEnum shouldRespectImageOrientation)
{
if (!m_source.initialized())
return;
@@ -599,10 +606,32 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
FloatRect normDstRect = normalizeRect(dstRect);
FloatRect normSrcRect = normalizeRect(srcRect);
+ normSrcRect.intersect(FloatRect(0, 0, bm->bitmap().width(), bm->bitmap().height()));
if (normSrcRect.isEmpty() || normDstRect.isEmpty())
return; // Nothing to draw.
+ ImageOrientation orientation = DefaultImageOrientation;
+ if (shouldRespectImageOrientation == RespectImageOrientation)
+ orientation = frameOrientationAtIndex(m_currentFrame);
+
+ GraphicsContextStateSaver saveContext(*ctxt, false);
+ if (orientation != DefaultImageOrientation) {
+ saveContext.save();
+
+ // ImageOrientation expects the origin to be at (0, 0)
+ ctxt->translate(normDstRect.x(), normDstRect.y());
+ normDstRect.setLocation(FloatPoint());
+
+ ctxt->concatCTM(orientation.transformFromDefault(normDstRect.size()));
+
+ if (orientation.usesWidthAsHeight()) {
+ // The destination rect will have it's width and height already reversed for the orientation of
+ // the image, as it was needed for page layout, so we need to reverse it back here.
+ normDstRect = FloatRect(normDstRect.x(), normDstRect.y(), normDstRect.height(), normDstRect.width());
+ }
+ }
+
paintSkBitmap(ctxt->platformContext(),
*bm,
normSrcRect,
@@ -623,6 +652,7 @@ void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt,
{
FloatRect normDstRect = normalizeRect(dstRect);
FloatRect normSrcRect = normalizeRect(srcRect);
+ normSrcRect.intersect(FloatRect(0, 0, m_nativeImage.bitmap().width(), m_nativeImage.bitmap().height()));
if (normSrcRect.isEmpty() || normDstRect.isEmpty())
return; // Nothing to draw.
diff --git a/Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp b/Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp
index 4d32c74db..4fc098124 100644
--- a/Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp
@@ -47,9 +47,6 @@
namespace WebCore {
-// Smallcaps versions of fonts are 70% the size of the normal font.
-static const float smallCapsFraction = 0.7f;
-static const float emphasisMarkFraction = .5;
// This is the largest VDMX table which we'll try to load and parse.
static const size_t maxVDMXTableSize = 1024 * 1024; // 1 MB
@@ -183,26 +180,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
return SimpleFontData::create(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false);
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFraction);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, emphasisMarkFraction);
-
- return m_derivedFontData->emphasisMark;
-}
-
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
SkPaint paint;
@@ -234,9 +211,26 @@ void SimpleFontData::determinePitch()
m_treatAsFixedPitch = platformData().isFixedPitch();
}
-FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
{
- return FloatRect();
+ if (!m_platformData.size())
+ return FloatRect();
+
+ SkASSERT(sizeof(glyph) == 2); // compile-time assert
+
+ SkPaint paint;
+
+ m_platformData.setupPaint(&paint);
+
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ SkRect bounds;
+ paint.measureText(&glyph, 2, &bounds);
+ if (!paint.isSubpixelText()) {
+ SkIRect ir;
+ bounds.round(&ir);
+ bounds.set(ir);
+ }
+ return FloatRect(bounds);
}
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
diff --git a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h
index 13ac33051..5602cf521 100644
--- a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h
+++ b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h
@@ -35,10 +35,15 @@
typedef struct __IOSurface* IOSurfaceRef;
typedef IOSurfaceRef PlatformGraphicsSurface;
#endif
+
#if OS(LINUX)
typedef uint32_t PlatformGraphicsSurface;
#endif
+#if OS(WINDOWS)
+typedef HANDLE PlatformGraphicsSurface;
+#endif
+
namespace WebCore {
class BitmapTexture;
diff --git a/Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h b/Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h
index 45342f141..c97f368bd 100644
--- a/Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h
+++ b/Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h
@@ -33,7 +33,13 @@ namespace WebCore {
struct GraphicsSurfaceToken {
-typedef uint32_t BufferHandle;
+#if OS(DARWIN)
+ typedef mach_port_t BufferHandle;
+#elif OS(LINUX)
+ typedef uint32_t BufferHandle;
+#elif OS(WINDOWS)
+ typedef HANDLE BufferHandle;
+#endif
#if HAVE(GLX)
GraphicsSurfaceToken(uint32_t windowID = 0)
@@ -52,7 +58,7 @@ typedef uint32_t BufferHandle;
#endif
-#if OS(DARWIN)
+#if OS(DARWIN) || OS(WINDOWS)
GraphicsSurfaceToken(BufferHandle frontBuffer = 0, BufferHandle backBuffer = 0)
: frontBufferHandle(frontBuffer)
, backBufferHandle(backBuffer)
diff --git a/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp b/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
index d869eb5cf..8597eb4e2 100644
--- a/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
+++ b/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
@@ -29,6 +29,7 @@
#include <IOSurface/IOSurface.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
+#include <mach/mach.h>
#if PLATFORM(QT)
#include <QGuiApplication>
@@ -79,8 +80,8 @@ public:
, m_readFbo(0)
, m_drawFbo(0)
{
- m_frontBuffer = IOSurfaceLookup(m_token.frontBufferHandle);
- m_backBuffer = IOSurfaceLookup(m_token.backBufferHandle);
+ m_frontBuffer = IOSurfaceLookupFromMachPort(m_token.frontBufferHandle);
+ m_backBuffer = IOSurfaceLookupFromMachPort(m_token.backBufferHandle);
}
GraphicsSurfacePrivate(const PlatformGraphicsContext3D shareContext, const IntSize& size, GraphicsSurface::Flags flags)
@@ -91,22 +92,11 @@ public:
, m_drawFbo(0)
{
#if PLATFORM(QT)
-#if 0
- // This code path requires QCocoaNativeInterface::nativeResourceForContext() which is not availble in Qt5 on the build bots yet.
QPlatformNativeInterface* nativeInterface = QGuiApplication::platformNativeInterface();
CGLContextObj shareContextObject = static_cast<CGLContextObj>(nativeInterface->nativeResourceForContext(QByteArrayLiteral("cglContextObj"), shareContext));
if (!shareContextObject)
return;
-#else
- // This code path should be removed as soon as QCocoaNativeInterface::nativeResourceForContext() has become available in Qt5 on the build bots.
- CGLContextObj previousContext = CGLGetCurrentContext();
- QSurface* currentSurface = shareContext->surface();
- shareContext->makeCurrent(currentSurface);
- CGLContextObj shareContextObject = CGLGetCurrentContext();
-
- CGLSetCurrentContext(previousContext);
-#endif
CGLPixelFormatObj pixelFormatObject = CGLGetPixelFormat(shareContextObject);
if (kCGLNoError != CGLCreateContext(pixelFormatObject, shareContextObject, &m_context))
return;
@@ -127,8 +117,8 @@ public:
if (!allocSize)
return;
- const void *keys[7];
- const void *values[7];
+ const void *keys[6];
+ const void *values[6];
keys[0] = kIOSurfaceWidth;
values[0] = CFNumberCreate(0, kCFNumberIntType, &width);
keys[1] = kIOSurfaceHeight;
@@ -141,17 +131,18 @@ public:
values[4] = CFNumberCreate(0, kCFNumberLongType, &bytesPerRow);
keys[5] = kIOSurfaceAllocSize;
values[5] = CFNumberCreate(0, kCFNumberLongType, &allocSize);
- keys[6] = kIOSurfaceIsGlobal;
- values[6] = (flags & GraphicsSurface::SupportsSharing) ? kCFBooleanTrue : kCFBooleanFalse;
- CFDictionaryRef dict = CFDictionaryCreate(0, keys, values, 7, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- for (unsigned i = 0; i < 7; i++)
+ CFDictionaryRef dict = CFDictionaryCreate(0, keys, values, 6, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ for (unsigned i = 0; i < 6; i++)
CFRelease(values[i]);
m_frontBuffer = IOSurfaceCreate(dict);
m_backBuffer = IOSurfaceCreate(dict);
- m_token = GraphicsSurfaceToken(IOSurfaceGetID(m_frontBuffer), IOSurfaceGetID(m_backBuffer));
+ if (!(flags & GraphicsSurface::SupportsSharing))
+ return;
+
+ m_token = GraphicsSurfaceToken(IOSurfaceCreateMachPort(m_frontBuffer), IOSurfaceCreateMachPort(m_backBuffer));
}
~GraphicsSurfacePrivate()
@@ -177,6 +168,11 @@ public:
if (m_context)
CGLReleaseContext(m_context);
+ if (m_token.frontBufferHandle)
+ mach_port_deallocate(mach_task_self(), m_token.frontBufferHandle);
+ if (m_token.backBufferHandle)
+ mach_port_deallocate(mach_task_self(), m_token.backBufferHandle);
+
}
uint32_t swapBuffers()
diff --git a/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp b/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp
index fd62a0038..64077ba9c 100644
--- a/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp
+++ b/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp
@@ -22,13 +22,18 @@
#if USE(GRAPHICS_SURFACE)
+#include "NotImplemented.h"
#include "TextureMapperGL.h"
+
+#if PLATFORM(QT)
// Qt headers must be included before glx headers.
-#include <QCoreApplication>
+#include <QGuiApplication>
#include <QOpenGLContext>
-#include <QVector>
-#include <QWindow>
-#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformnativeinterface.h>
+#elif PLATFORM(EFL)
+#include <GL/gl.h>
+#endif
+
#include <GL/glext.h>
#include <GL/glx.h>
#include <X11/extensions/Xcomposite.h>
@@ -50,39 +55,55 @@ class OffScreenRootWindow {
public:
OffScreenRootWindow()
{
- ++refCount;
+ ++m_refCount;
}
- QWindow* get(Display* dpy)
+ Window getXWindow()
{
- if (!window) {
- window = new QWindow;
- window->setGeometry(QRect(-1, -1, 1, 1));
- window->create();
+ if (!m_window) {
+ Display* dpy = display();
+ m_window = XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy), -1, -1, 1, 1, 0, BlackPixel(dpy, 0), WhitePixel(dpy, 0));
XSetWindowAttributes attributes;
attributes.override_redirect = true;
- XChangeWindowAttributes(dpy, window->handle()->winId(), X11OverrideRedirect, &attributes);
- window->show();
+ XChangeWindowAttributes(dpy, m_window, X11OverrideRedirect, &attributes);
+ // Map window to the screen
+ XMapWindow(dpy, m_window);
}
- return window;
+ return m_window;
+ }
+
+ Display* display()
+ {
+ if (!m_display)
+ m_display = XOpenDisplay(0);
+ return m_display;
}
~OffScreenRootWindow()
{
- if (!--refCount) {
- delete window;
- window = 0;
+ if (--m_refCount || !m_display)
+ return;
+
+ if (m_window) {
+ XUnmapWindow(m_display, m_window);
+ XDestroyWindow(m_display, m_window);
+ m_window = 0;
}
+
+ XCloseDisplay(m_display);
+ m_display = 0;
}
private:
- static int refCount;
- static QWindow* window;
+ static int m_refCount;
+ static Window m_window;
+ static Display* m_display;
};
-int OffScreenRootWindow::refCount = 0;
-QWindow* OffScreenRootWindow::window = 0;
+int OffScreenRootWindow::m_refCount = 0;
+Window OffScreenRootWindow::m_window = 0;
+Display* OffScreenRootWindow::m_display = 0;
static const int glxSpec[] = {
// The specification is a set key value pairs stored in a simple array.
@@ -106,25 +127,54 @@ struct GraphicsSurfacePrivate {
: m_display(0)
, m_xPixmap(0)
, m_glxPixmap(0)
- , m_glContext(adoptPtr(new QOpenGLContext))
+ , m_glContext(0)
, m_detachedContext(0)
, m_detachedSurface(0)
, m_textureIsYInverted(false)
, m_hasAlpha(false)
{
- QSurface* currentSurface = 0;
- QOpenGLContext* currentContext = QOpenGLContext::currentContext();
- if (currentContext)
- currentSurface = currentContext->surface();
-
- m_display = XOpenDisplay(0);
- m_glContext->setShareContext(shareContext);
- m_glContext->create();
-
- // The GLX implementation of QOpenGLContext will reset the current context when create is being called.
- // Therefore we have to make the previous context current again.
- if (currentContext)
- currentContext->makeCurrent(currentSurface);
+ GLXContext shareContextObject = 0;
+ m_display = m_offScreenWindow.display();
+
+#if PLATFORM(QT)
+ if (shareContext) {
+#if 0
+ // This code path requires QXcbNativeInterface::nativeResourceForContext() which is not availble in Qt5 on the build bots yet.
+ QPlatformNativeInterface* nativeInterface = QGuiApplication::platformNativeInterface();
+ shareContextObject = static_cast<GLXContext>(nativeInterface->nativeResourceForContext(QByteArrayLiteral("glxcontext"), shareContext));
+ if (!shareContextObject)
+ return;
+#else
+ // This code path should be removed as soon as QXcbNativeInterface::nativeResourceForContext() can provide the GLXContext.
+ QOpenGLContext* previousContext = QOpenGLContext::currentContext();
+ QSurface* previousSurface = previousContext->surface();
+ QSurface* currentSurface = shareContext->surface();
+ shareContext->makeCurrent(currentSurface);
+
+ shareContextObject = glXGetCurrentContext();
+
+ previousContext->makeCurrent(previousSurface);
+#endif
+ }
+#else
+ UNUSED_PARAM(shareContext);
+#endif
+
+ int attributes[] = {
+ GLX_LEVEL, 0,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER, True,
+ None
+ };
+
+ int numReturned;
+ m_fbConfigs = glXChooseFBConfig(m_display, DefaultScreen(m_display), attributes, &numReturned);
+ // Create a GLX context for OpenGL rendering
+ m_glContext = glXCreateNewContext(m_display, m_fbConfigs[0], GLX_RGBA_TYPE, shareContextObject, true);
}
~GraphicsSurfacePrivate()
@@ -137,27 +187,34 @@ struct GraphicsSurfacePrivate {
XFreePixmap(m_display, m_xPixmap);
m_xPixmap = 0;
- if (m_display)
- XCloseDisplay(m_display);
- m_display = 0;
+ if (m_glContext)
+ glXDestroyContext(m_display, m_glContext);
}
uint32_t createSurface(const IntSize& size)
{
- m_surface = adoptPtr(new QWindow(m_offScreenWindow.get(m_display)));
- m_surface->setSurfaceType(QSurface::OpenGLSurface);
- m_surface->setGeometry(0, 0, size.width(), size.height());
- m_surface->create();
- XCompositeRedirectWindow(m_display, m_surface->handle()->winId(), CompositeRedirectManual);
+ XVisualInfo* visualInfo = glXGetVisualFromFBConfig(m_display, m_fbConfigs[0]);
+ if (!visualInfo)
+ return 0;
+
+ Colormap cmap = XCreateColormap(m_display, m_offScreenWindow.getXWindow(), visualInfo->visual, AllocNone);
+ XSetWindowAttributes a;
+ a.background_pixel = WhitePixel(m_display, 0);
+ a.border_pixel = BlackPixel(m_display, 0);
+ a.colormap = cmap;
+ m_surface = XCreateWindow(m_display, m_offScreenWindow.getXWindow(), 0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWBackPixel | CWBorderPixel | CWColormap, &a);
+ XSetWindowBackgroundPixmap(m_display, m_surface, 0);
+ XCompositeRedirectWindow(m_display, m_surface, CompositeRedirectManual);
// Make sure the XRender Extension is available.
int eventBasep, errorBasep;
if (!XRenderQueryExtension(m_display, &eventBasep, &errorBasep))
return 0;
- m_surface->show();
-
- return m_surface->handle()->winId();
+ XMapWindow(m_display, m_surface);
+ return m_surface;
}
void createPixmap(uint32_t winId)
@@ -184,18 +241,17 @@ struct GraphicsSurfacePrivate {
void makeCurrent()
{
- m_detachedContext = QOpenGLContext::currentContext();
- if (m_detachedContext)
- m_detachedSurface = m_detachedContext->surface();
-
+ m_detachedContext = glXGetCurrentContext();
+ m_detachedSurface = glXGetCurrentDrawable();
if (m_surface && m_glContext)
- m_glContext->makeCurrent(m_surface.get());
+ glXMakeCurrent(m_display, m_surface, m_glContext);
}
void doneCurrent()
{
if (m_detachedContext)
- m_detachedContext->makeCurrent(m_detachedSurface);
+ glXMakeCurrent(m_display, m_detachedSurface, m_detachedContext);
+ m_detachedContext = 0;
}
void swapBuffers()
@@ -206,20 +262,13 @@ struct GraphicsSurfacePrivate {
if (m_xPixmap)
return;
- if (!m_surface->isVisible())
- return;
-
- // Creating and exposing the surface is asynchronous. Therefore we have to wait here
- // before swapping the buffers. This should only be the case for the very first frame.
- while (!m_surface->isExposed())
- QCoreApplication::processEvents();
+ GLXContext glContext = glXGetCurrentContext();
- QOpenGLContext* glContext = QOpenGLContext::currentContext();
if (m_surface && glContext) {
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO);
- pGlBindFramebuffer(GL_FRAMEBUFFER, glContext->defaultFramebufferObject());
- glContext->swapBuffers(m_surface.get());
+ pGlBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glXSwapBuffers(m_display, m_surface);
pGlBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
}
}
@@ -242,7 +291,7 @@ struct GraphicsSurfacePrivate {
glBindTexture(GL_TEXTURE_2D, texture);
pGlFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
- pGlBindFramebuffer(GL_DRAW_FRAMEBUFFER, glContext()->defaultFramebufferObject());
+ pGlBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
pGlBlitFramebuffer(x, y, width, height, x, y, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
pGlFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
@@ -254,45 +303,40 @@ struct GraphicsSurfacePrivate {
doneCurrent();
}
-
Display* display() const { return m_display; }
GLXPixmap glxPixmap() const { return m_glxPixmap; }
IntSize size() const { return m_size; }
- QOpenGLContext* glContext() { return m_glContext.get(); }
-
private:
OffScreenRootWindow m_offScreenWindow;
IntSize m_size;
Display* m_display;
Pixmap m_xPixmap;
GLXPixmap m_glxPixmap;
- OwnPtr<QWindow> m_surface;
- OwnPtr<QOpenGLContext> m_glContext;
- QOpenGLContext* m_detachedContext;
- QSurface* m_detachedSurface;
+ Window m_surface;
+ GLXContext m_glContext;
+ GLXContext m_detachedContext;
+ GLXDrawable m_detachedSurface;
+ GLXFBConfig* m_fbConfigs;
bool m_textureIsYInverted;
bool m_hasAlpha;
};
-static bool resolveGLMethods(GraphicsSurfacePrivate* p)
+static bool resolveGLMethods(GraphicsSurfacePrivate*)
{
static bool resolved = false;
if (resolved)
return true;
-
- QOpenGLContext* glContext = p->glContext();
- pGlXBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glContext->getProcAddress("glXBindTexImageEXT"));
- pGlXReleaseTexImageEXT = reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(glContext->getProcAddress("glXReleaseTexImageEXT"));
- pGlBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(glContext->getProcAddress("glBindFramebuffer"));
- pGlBlitFramebuffer = reinterpret_cast<PFNGLBLITFRAMEBUFFERPROC>(glContext->getProcAddress("glBlitFramebuffer"));
-
- pGlGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(glContext->getProcAddress("glGenFramebuffers"));
- pGlDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(glContext->getProcAddress("glDeleteFramebuffers"));
- pGlFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(glContext->getProcAddress("glFramebufferTexture2D"));
-
+ pGlXBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXBindTexImageEXT")));
+ pGlXReleaseTexImageEXT = reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXReleaseTexImageEXT")));
+ pGlBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBindFramebuffer")));
+ pGlBlitFramebuffer = reinterpret_cast<PFNGLBLITFRAMEBUFFERPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glBlitFramebuffer")));
+
+ pGlGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGenFramebuffers")));
+ pGlDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glDeleteFramebuffers")));
+ pGlFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(glXGetProcAddress(reinterpret_cast<const GLubyte*>("glFramebufferTexture2D")));
resolved = pGlBlitFramebuffer && pGlBindFramebuffer && pGlXBindTexImageEXT && pGlXReleaseTexImageEXT;
return resolved;
@@ -318,7 +362,7 @@ uint32_t GraphicsSurface::platformGetTextureID()
return m_texture;
}
-void GraphicsSurface::platformCopyToGLTexture(uint32_t target, uint32_t id, const IntRect& targetRect, const IntPoint& offset)
+void GraphicsSurface::platformCopyToGLTexture(uint32_t /*target*/, uint32_t /*id*/, const IntRect& /*targetRect*/, const IntPoint& /*offset*/)
{
// This is not supported by GLX/Xcomposite.
}
@@ -331,9 +375,10 @@ void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& s
void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
{
+ TextureMapperGL* texMapGL = static_cast<TextureMapperGL*>(textureMapper);
TransformationMatrix adjustedTransform = transform;
adjustedTransform.multiply(TransformationMatrix::rectToRect(FloatRect(FloatPoint::zero(), m_size), targetRect));
- static_cast<TextureMapperGL*>(textureMapper)->drawTexture(platformGetTextureID(), 0, m_size, targetRect, adjustedTransform, opacity, mask);
+ texMapGL->drawTexture(platformGetTextureID(), TextureMapperGL::ShouldFlipTexture, m_size, targetRect, adjustedTransform, opacity, mask);
}
uint32_t GraphicsSurface::platformFrontBuffer() const
@@ -388,7 +433,7 @@ PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size,
return surface;
}
-char* GraphicsSurface::platformLock(const IntRect& rect, int* outputStride, LockOptions lockOptions)
+char* GraphicsSurface::platformLock(const IntRect&, int* /*outputStride*/, LockOptions)
{
// GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism.
return 0;
@@ -410,5 +455,18 @@ void GraphicsSurface::platformDestroy()
m_private = 0;
}
+#if !PLATFORM(QT)
+PassOwnPtr<GraphicsContext> GraphicsSurface::platformBeginPaint(const IntSize&, char*, int)
+{
+ notImplemented();
+ return nullptr;
+}
+
+PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect&)
+{
+ notImplemented();
+ return 0;
+}
+#endif
}
#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/win/GraphicsSurfaceWin.cpp b/Source/WebCore/platform/graphics/surfaces/win/GraphicsSurfaceWin.cpp
new file mode 100644
index 000000000..19bebd2ff
--- /dev/null
+++ b/Source/WebCore/platform/graphics/surfaces/win/GraphicsSurfaceWin.cpp
@@ -0,0 +1,492 @@
+/*
+
+ Copyright (C) 2012 Zeno Albisser <zeno@webkit.org>
+
+ 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 "GraphicsSurface.h"
+
+#if USE(GRAPHICS_SURFACE)
+#include "TextureMapperGL.h"
+
+#define EGL_EGLEXT_PROTOTYPES // This must be defined before including egl.h and eglext.h.
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#if PLATFORM(QT)
+#include <QGuiApplication>
+#include <QOpenGLContext>
+#include <qpa/qplatformnativeinterface.h>
+#endif
+
+namespace WebCore {
+
+#define STRINGIFY(...) #__VA_ARGS__
+
+static GLuint loadShader(GLenum type, const GLchar *shaderSrc)
+{
+ GLuint shader;
+ GLint compiled;
+
+ shader = glCreateShader(type);
+ if (!shader)
+ return 0;
+
+ glShaderSource(shader, 1, &shaderSrc, 0);
+ glCompileShader(shader);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ glDeleteShader(shader);
+ return 0;
+ }
+ return shader;
+}
+
+struct GraphicsSurfacePrivate {
+public:
+ GraphicsSurfacePrivate(const IntSize& size, GraphicsSurfaceToken token)
+ : m_token(token)
+ , m_detachedContext(0)
+ , m_detachedReadSurface(0)
+ , m_detachedDrawSurface(0)
+ , m_size(size)
+ , m_eglDisplay(0)
+ , m_eglContext(0)
+ , m_eglConfig(0)
+ , m_eglFrontBufferSurface(0)
+ , m_eglBackBufferSurface(0)
+ , m_initialFrontBufferShareHandle(token.frontBufferHandle)
+ , m_frontBufferShareHandle(token.frontBufferHandle)
+ , m_backBufferShareHandle(token.backBufferHandle)
+ , m_frontBufferTexture(0)
+ , m_shaderProgram(0)
+ {
+ initializeShaderProgram();
+ }
+
+
+ GraphicsSurfacePrivate(const PlatformGraphicsContext3D shareContext, const IntSize& size, GraphicsSurface::Flags flags)
+ : m_detachedContext(0)
+ , m_detachedReadSurface(0)
+ , m_detachedDrawSurface(0)
+ , m_size(size)
+ , m_eglDisplay(0)
+ , m_eglContext(0)
+ , m_eglConfig(0)
+ , m_eglFrontBufferSurface(0)
+ , m_eglBackBufferSurface(0)
+ , m_initialFrontBufferShareHandle(0)
+ , m_frontBufferShareHandle(0)
+ , m_backBufferShareHandle(0)
+ , m_frontBufferTexture(0)
+ , m_shaderProgram(0)
+ {
+ initializeShaderProgram();
+
+ static PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE = 0;
+ if (!eglQuerySurfacePointerANGLE) {
+ eglQuerySurfacePointerANGLE = reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>(eglGetProcAddress("eglQuerySurfacePointerANGLE"));
+ if (!eglQuerySurfacePointerANGLE)
+ return;
+ }
+
+ if (!m_eglDisplay || !m_eglContext || !m_eglConfig) {
+ m_eglDisplay = eglGetCurrentDisplay();
+
+#if PLATFORM(QT)
+ QPlatformNativeInterface* nativeInterface = QGuiApplication::platformNativeInterface();
+ m_eglConfig = static_cast<EGLConfig>(nativeInterface->nativeResourceForContext(QByteArrayLiteral("eglConfig"), shareContext));
+ EGLContext eglShareContext = static_cast<EGLContext>(nativeInterface->nativeResourceForContext(QByteArrayLiteral("eglContext"), shareContext));
+#endif
+ EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, eglShareContext, contextAttributes);
+ }
+
+ EGLint attributes[] = {
+ EGL_WIDTH, size.width(),
+ EGL_HEIGHT, size.height(),
+ EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
+ EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
+ EGL_NONE
+ };
+
+ m_eglFrontBufferSurface = eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, attributes);
+ m_eglBackBufferSurface = eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, attributes);
+ if (m_eglFrontBufferSurface == EGL_NO_SURFACE || m_eglBackBufferSurface == EGL_NO_SURFACE)
+ return;
+
+ eglQuerySurfacePointerANGLE(m_eglDisplay, m_eglFrontBufferSurface, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &m_frontBufferShareHandle);
+ eglQuerySurfacePointerANGLE(m_eglDisplay, m_eglBackBufferSurface, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &m_backBufferShareHandle);
+
+ m_initialFrontBufferShareHandle = m_frontBufferShareHandle;
+
+ m_token = GraphicsSurfaceToken(m_frontBufferShareHandle, m_backBufferShareHandle);
+ }
+
+ ~GraphicsSurfacePrivate()
+ {
+ releaseFrontBufferTexture();
+
+ if (m_eglBackBufferSurface)
+ eglDestroySurface(m_eglDisplay, m_eglBackBufferSurface);
+
+ if (m_shaderProgram)
+ glDeleteProgram(m_shaderProgram);
+ m_shaderProgram = 0;
+
+ if (m_eglDisplay && m_eglContext)
+ eglDestroyContext(m_eglDisplay, m_eglContext);
+ }
+
+ void copyFromTexture(uint32_t texture, const IntRect& sourceRect)
+ {
+ if (!makeCurrent())
+ return;
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ drawTexture(texture);
+ glFinish();
+ doneCurrent();
+ }
+
+ bool makeCurrent()
+ {
+ m_detachedContext = eglGetCurrentContext();
+ m_detachedReadSurface = eglGetCurrentSurface(EGL_READ);
+ m_detachedDrawSurface = eglGetCurrentSurface(EGL_DRAW);
+
+ return eglMakeCurrent(m_eglDisplay, m_eglBackBufferSurface, m_eglBackBufferSurface, m_eglContext);
+ }
+
+ bool doneCurrent()
+ {
+ if (!m_detachedContext || !m_detachedDrawSurface || !m_detachedReadSurface)
+ return false;
+
+ bool success = eglMakeCurrent(m_eglDisplay, m_detachedDrawSurface, m_detachedReadSurface, m_detachedContext);
+ m_detachedContext = 0;
+ m_detachedReadSurface = 0;
+ m_detachedDrawSurface = 0;
+ return success;
+ }
+
+ PlatformGraphicsSurface swapBuffers()
+ {
+ if (m_frontBufferTexture)
+ releaseFrontBufferTexture();
+ std::swap(m_eglFrontBufferSurface, m_eglBackBufferSurface);
+ std::swap(m_frontBufferShareHandle, m_backBufferShareHandle);
+
+ return m_frontBufferShareHandle;
+ }
+
+ GraphicsSurfaceToken token() const
+ {
+ return m_token;
+ }
+
+ uint32_t frontBufferTextureID()
+ {
+ if (!m_eglFrontBufferSurface) {
+ m_eglFrontBufferSurface = createSurfaceFromShareHandle(m_size, m_frontBufferShareHandle);
+
+ glGenTextures(1, &m_frontBufferTexture);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_frontBufferTexture);
+ eglBindTexImage(m_eglDisplay, m_eglFrontBufferSurface, EGL_BACK_BUFFER);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+
+ return m_frontBufferTexture;
+ }
+
+ PlatformGraphicsSurface initialFrontBufferShareHandle() const
+ {
+ return m_initialFrontBufferShareHandle;
+ }
+
+ PlatformGraphicsSurface frontBufferShareHandle() const
+ {
+ return m_frontBufferShareHandle;
+ }
+
+ PlatformGraphicsSurface backBufferShareHandle() const
+ {
+ return m_backBufferShareHandle;
+ }
+
+ void releaseFrontBufferTexture()
+ {
+ if (m_frontBufferTexture) {
+ eglReleaseTexImage(m_eglDisplay, m_eglFrontBufferSurface, EGL_BACK_BUFFER);
+ glDeleteTextures(1, &m_frontBufferTexture);
+ m_frontBufferTexture = 0;
+ }
+
+ if (m_eglFrontBufferSurface)
+ eglDestroySurface(m_eglDisplay, m_eglFrontBufferSurface);
+ m_eglFrontBufferSurface = 0;
+ }
+
+
+protected:
+ void initializeShaderProgram()
+ {
+ if (m_shaderProgram)
+ return;
+
+ GLchar vShaderStr[] =
+ STRINGIFY(
+ attribute highp vec2 vertex;
+ attribute highp vec2 textureCoordinates;
+ varying highp vec2 textureCoords;
+ void main(void)
+ {
+ gl_Position = vec4(vertex, 0.0, 1.0);
+ textureCoords = textureCoordinates;
+ }
+ );
+
+ GLchar fShaderStr[] =
+ STRINGIFY(
+ varying highp vec2 textureCoords;
+ uniform sampler2D texture;
+ void main(void)
+ {
+ highp vec3 color = texture2D(texture, textureCoords).rgb;
+ gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0);
+ }
+ );
+
+ GLuint vertexShader;
+ GLuint fragmentShader;
+ GLint linked;
+
+ vertexShader = loadShader(GL_VERTEX_SHADER, vShaderStr);
+ fragmentShader = loadShader(GL_FRAGMENT_SHADER, fShaderStr);
+ if (!vertexShader || !fragmentShader)
+ return;
+
+ m_shaderProgram = glCreateProgram();
+ if (!m_shaderProgram)
+ return;
+
+ glAttachShader(m_shaderProgram, vertexShader);
+ glAttachShader(m_shaderProgram, fragmentShader);
+
+ glLinkProgram(m_shaderProgram);
+ glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &linked);
+ if (!linked) {
+ glDeleteProgram(m_shaderProgram);
+ m_shaderProgram = 0;
+ }
+
+ m_vertexAttr = glGetAttribLocation(m_shaderProgram, "vertex");
+ m_textureCoordinatesAttr = glGetAttribLocation(m_shaderProgram, "textureCoordinates");
+ m_textureUniform = glGetAttribLocation(m_shaderProgram, "texture");
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+
+ EGLSurface createSurfaceFromShareHandle(const IntSize& size, HANDLE shareHandle)
+ {
+ if (!m_eglDisplay || !m_eglConfig) {
+ m_eglDisplay = eglGetCurrentDisplay();
+
+#if PLATFORM(QT)
+ QPlatformNativeInterface* nativeInterface = QGuiApplication::platformNativeInterface();
+ m_eglConfig = static_cast<EGLConfig>(nativeInterface->nativeResourceForContext(QByteArrayLiteral("eglConfig"), QOpenGLContext::currentContext()));
+#endif
+ }
+
+ EGLint attributes[] = {
+ EGL_WIDTH, size.width(),
+ EGL_HEIGHT, size.height(),
+ EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
+ EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
+ EGL_NONE
+ };
+
+ EGLSurface surface = eglCreatePbufferFromClientBuffer(m_eglDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, reinterpret_cast<EGLClientBuffer>(shareHandle), m_eglConfig, attributes);
+ ASSERT(surface);
+
+ return surface;
+ }
+
+ void drawTexture(uint32_t texture)
+ {
+ glUseProgram(m_shaderProgram);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ GLfloat afVertices[] = {
+ -1, -1,
+ 1, -1,
+ -1, 1,
+ 1, 1
+ };
+ glVertexAttribPointer(m_vertexAttr, 2, GL_FLOAT, GL_FALSE, 0, afVertices);
+
+ GLfloat aftextureCoordinates[] = {
+ 0, 1,
+ 1, 1,
+ 0, 0,
+ 1, 0
+ };
+ glVertexAttribPointer(m_textureCoordinatesAttr, 2, GL_FLOAT, GL_FALSE, 0, aftextureCoordinates);
+
+ glUniform1i(m_textureUniform, 0);
+
+ glEnableVertexAttribArray(m_vertexAttr);
+ glEnableVertexAttribArray(m_textureCoordinatesAttr);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisableVertexAttribArray(m_vertexAttr);
+ glDisableVertexAttribArray(m_textureCoordinatesAttr);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+private:
+ GraphicsSurfaceToken m_token;
+ EGLContext m_detachedContext;
+ EGLSurface m_detachedReadSurface;
+ EGLSurface m_detachedDrawSurface;
+ IntSize m_size;
+ EGLDisplay m_eglDisplay;
+ EGLContext m_eglContext;
+ EGLConfig m_eglConfig;
+ EGLSurface m_eglFrontBufferSurface;
+ EGLSurface m_eglBackBufferSurface;
+ PlatformGraphicsSurface m_initialFrontBufferShareHandle;
+ PlatformGraphicsSurface m_frontBufferShareHandle;
+ PlatformGraphicsSurface m_backBufferShareHandle;
+ GLuint m_frontBufferTexture;
+ GLint m_shaderProgram;
+
+ GLuint m_vertexAttr;
+ GLuint m_textureCoordinatesAttr;
+ GLuint m_textureUniform;
+};
+
+GraphicsSurfaceToken GraphicsSurface::platformExport()
+{
+ return m_private->token();
+}
+
+uint32_t GraphicsSurface::platformGetTextureID()
+{
+ return m_private->frontBufferTextureID();
+}
+
+void GraphicsSurface::platformCopyToGLTexture(uint32_t target, uint32_t id, const IntRect& targetRect, const IntPoint& offset)
+{
+ // Currently not implemented.
+}
+
+void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& sourceRect)
+{
+ m_private->copyFromTexture(texture, sourceRect);
+}
+
+void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+{
+ GLuint frontBufferTexture = platformGetTextureID();
+
+ TransformationMatrix adjustedTransform = transform;
+ adjustedTransform.multiply(TransformationMatrix::rectToRect(FloatRect(FloatPoint::zero(), m_size), targetRect));
+ static_cast<TextureMapperGL*>(textureMapper)->drawTexture(frontBufferTexture, 0, m_size, targetRect, adjustedTransform, opacity, mask);
+}
+
+uint32_t GraphicsSurface::platformFrontBuffer() const
+{
+ if (m_private->initialFrontBufferShareHandle() == m_private->frontBufferShareHandle())
+ return 0;
+ if (m_private->initialFrontBufferShareHandle() == m_private->backBufferShareHandle())
+ return 1;
+ return 0xFFFF;
+}
+
+uint32_t GraphicsSurface::platformSwapBuffers()
+{
+ m_private->swapBuffers();
+ return platformFrontBuffer();
+}
+
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags, const PlatformGraphicsContext3D shareContext)
+{
+ // Single buffered GraphicsSurface is currently not supported.
+ if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
+ return PassRefPtr<GraphicsSurface>();
+
+ RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
+ surface->m_private = new GraphicsSurfacePrivate(shareContext, size, flags);
+
+ if (!surface->m_private->frontBufferShareHandle() || !surface->m_private->backBufferShareHandle())
+ return PassRefPtr<GraphicsSurface>();
+
+ return surface;
+}
+
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token)
+{
+ // Single buffered GraphicsSurface is currently not supported.
+ if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
+ return PassRefPtr<GraphicsSurface>();
+
+ RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
+ surface->m_private = new GraphicsSurfacePrivate(size, token);
+
+ if (!surface->m_private->frontBufferShareHandle() || !surface->m_private->backBufferShareHandle())
+ return PassRefPtr<GraphicsSurface>();
+
+ return surface;
+}
+
+char* GraphicsSurface::platformLock(const IntRect& rect, int* outputStride, LockOptions lockOptions)
+{
+ // GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism.
+ return 0;
+}
+
+void GraphicsSurface::platformUnlock()
+{
+ // GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism.
+}
+
+void GraphicsSurface::platformDestroy()
+{
+ delete m_private;
+ m_private = 0;
+}
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
index 42954a499..41897c63e 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "GraphicsLayerTextureMapper.h"
+#include "GraphicsLayerAnimation.h"
#include "GraphicsLayerFactory.h"
#include "TextureMapperLayer.h"
@@ -87,6 +88,7 @@ void GraphicsLayerTextureMapper::setNeedsDisplay()
{
m_needsDisplay = true;
notifyChange(TextureMapperLayer::DisplayChange);
+ addRepaintRect(FloatRect(FloatPoint(), m_size));
}
/* \reimp (GraphicsLayer.h)
@@ -94,6 +96,7 @@ void GraphicsLayerTextureMapper::setNeedsDisplay()
void GraphicsLayerTextureMapper::setContentsNeedsDisplay()
{
notifyChange(TextureMapperLayer::DisplayChange);
+ addRepaintRect(contentsRect());
}
/* \reimp (GraphicsLayer.h)
@@ -104,6 +107,7 @@ void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)
return;
m_needsDisplayRect.unite(rect);
notifyChange(TextureMapperLayer::DisplayChange);
+ addRepaintRect(rect);
}
/* \reimp (GraphicsLayer.h)
@@ -392,12 +396,19 @@ bool GraphicsLayerTextureMapper::addAnimation(const KeyframeValueList& valueList
if (valueList.property() == AnimatedPropertyWebkitTransform)
listsMatch = validateTransformOperations(valueList, hasBigRotation) >= 0;
- m_animations.add(GraphicsLayerAnimation(keyframesName, valueList, boxSize, anim, timeOffset, listsMatch));
+ m_animations.add(GraphicsLayerAnimation(keyframesName, valueList, boxSize, anim, WTF::currentTime() - timeOffset, listsMatch));
notifyChange(TextureMapperLayer::AnimationChange);
m_animationStartedTimer.startOneShot(0);
return true;
}
+void GraphicsLayerTextureMapper::setAnimations(const GraphicsLayerAnimations& animations)
+{
+ m_animations = animations;
+ notifyChange(TextureMapperLayer::AnimationChange);
+}
+
+
void GraphicsLayerTextureMapper::pauseAnimation(const String& animationName, double timeOffset)
{
m_animations.pause(animationName, timeOffset);
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
index 637abd9d4..510b23f5c 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
@@ -81,6 +81,7 @@ public:
virtual bool addAnimation(const KeyframeValueList&, const IntSize&, const Animation*, const String&, double);
virtual void pauseAnimation(const String&, double);
virtual void removeAnimation(const String&);
+ void setAnimations(const GraphicsLayerAnimations&);
TextureMapperLayer* layer() const { return m_layer.get(); }
TextureMapperPlatformLayer* contentsLayer() const { return m_contentsLayer; }
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
index cee45b969..7a980a9c5 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
@@ -21,33 +21,108 @@
#include "TextureMapper.h"
#include "TextureMapperImageBuffer.h"
+#include "Timer.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/NonCopyingSort.h>
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
namespace WebCore {
-PassRefPtr<BitmapTexture> TextureMapper::acquireTextureFromPool(const IntSize& size)
+struct BitmapTexturePoolEntry {
+ explicit BitmapTexturePoolEntry(PassRefPtr<BitmapTexture> texture)
+ : m_texture(texture)
+ { }
+ inline void markUsed() { m_timeLastUsed = monotonicallyIncreasingTime(); }
+ static bool compareTimeLastUsed(const BitmapTexturePoolEntry& a, const BitmapTexturePoolEntry& b)
+ {
+ return a.m_timeLastUsed - b.m_timeLastUsed > 0;
+ }
+
+ RefPtr<BitmapTexture> m_texture;
+ double m_timeLastUsed;
+};
+
+class BitmapTexturePool {
+ WTF_MAKE_NONCOPYABLE(BitmapTexturePool);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ BitmapTexturePool();
+
+ PassRefPtr<BitmapTexture> acquireTexture(const IntSize&, TextureMapper*);
+
+private:
+ void scheduleReleaseUnusedTextures();
+ void releaseUnusedTexturesTimerFired(Timer<BitmapTexturePool>*);
+
+ Vector<BitmapTexturePoolEntry> m_textures;
+ Timer<BitmapTexturePool> m_releaseUnusedTexturesTimer;
+
+ static const double s_releaseUnusedSecondsTolerance;
+ static const double s_releaseUnusedTexturesTimerInterval;
+};
+
+const double BitmapTexturePool::s_releaseUnusedSecondsTolerance = 3;
+const double BitmapTexturePool::s_releaseUnusedTexturesTimerInterval = 0.5;
+
+BitmapTexturePool::BitmapTexturePool()
+ : m_releaseUnusedTexturesTimer(this, &BitmapTexturePool::releaseUnusedTexturesTimerFired)
+{ }
+
+void BitmapTexturePool::scheduleReleaseUnusedTextures()
+{
+ if (m_releaseUnusedTexturesTimer.isActive())
+ m_releaseUnusedTexturesTimer.stop();
+
+ m_releaseUnusedTexturesTimer.startOneShot(s_releaseUnusedTexturesTimerInterval);
+}
+
+void BitmapTexturePool::releaseUnusedTexturesTimerFired(Timer<BitmapTexturePool>*)
{
- RefPtr<BitmapTexture> selectedTexture;
+ if (m_textures.isEmpty())
+ return;
+
+ // Delete entries, which have been unused in s_releaseUnusedSecondsTolerance.
+ nonCopyingSort(m_textures.begin(), m_textures.end(), BitmapTexturePoolEntry::compareTimeLastUsed);
+
+ double minUsedTime = monotonicallyIncreasingTime() - s_releaseUnusedSecondsTolerance;
+ for (size_t i = 0; i < m_textures.size(); ++i) {
+ if (m_textures[i].m_timeLastUsed < minUsedTime) {
+ m_textures.remove(i, m_textures.size() - i);
+ break;
+ }
+ }
+}
- for (size_t i = 0; i < m_texturePool.size(); ++i) {
- RefPtr<BitmapTexture>& texture = m_texturePool[i];
+PassRefPtr<BitmapTexture> BitmapTexturePool::acquireTexture(const IntSize& size, TextureMapper* textureMapper)
+{
+ BitmapTexturePoolEntry* selectedEntry = 0;
+ for (size_t i = 0; i < m_textures.size(); ++i) {
+ BitmapTexturePoolEntry* entry = &m_textures[i];
- // If the surface has only one reference (the one in m_texturePool), we can safely reuse it.
- if (texture->refCount() > 1)
+ // If the surface has only one reference (the one in m_textures), we can safely reuse it.
+ if (entry->m_texture->refCount() > 1)
continue;
- if (texture->canReuseWith(size)) {
- selectedTexture = texture;
+ if (entry->m_texture->canReuseWith(size)) {
+ selectedEntry = entry;
break;
}
}
- if (!selectedTexture) {
- selectedTexture = createTexture();
- m_texturePool.append(selectedTexture);
+ if (!selectedEntry) {
+ m_textures.append(BitmapTexturePoolEntry(textureMapper->createTexture()));
+ selectedEntry = &m_textures.last();
}
+ scheduleReleaseUnusedTextures();
+ selectedEntry->markUsed();
+ return selectedEntry->m_texture;
+}
+
+PassRefPtr<BitmapTexture> TextureMapper::acquireTextureFromPool(const IntSize& size)
+{
+ RefPtr<BitmapTexture> selectedTexture = m_texturePool->acquireTexture(size, this);
selectedTexture->reset(size, BitmapTexture::SupportsAlpha);
return selectedTexture;
}
@@ -59,5 +134,15 @@ PassOwnPtr<TextureMapper> TextureMapper::create(AccelerationMode mode)
return platformCreateAccelerated();
}
+TextureMapper::TextureMapper(AccelerationMode accelerationMode)
+ : m_interpolationQuality(InterpolationDefault)
+ , m_textDrawingMode(TextModeFill)
+ , m_texturePool(adoptPtr(new BitmapTexturePool()))
+ , m_accelerationMode(accelerationMode)
+{ }
+
+TextureMapper::~TextureMapper()
+{ }
+
}
#endif
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
index 282bf2ca4..2693d9ad9 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
@@ -47,6 +47,7 @@
namespace WebCore {
+class BitmapTexturePool;
class TextureMapper;
// A 2D texture that can be the target of software or GL rendering.
@@ -115,7 +116,7 @@ public:
typedef unsigned PaintFlags;
static PassOwnPtr<TextureMapper> create(AccelerationMode newMode = SoftwareMode);
- virtual ~TextureMapper() { }
+ virtual ~TextureMapper();
enum ExposedEdges {
NoEdges = 0,
@@ -150,15 +151,10 @@ public:
virtual IntSize maxTextureSize() const { return IntSize(INT_MAX, INT_MAX); }
- // A surface is released implicitly when dereferenced.
virtual PassRefPtr<BitmapTexture> acquireTextureFromPool(const IntSize&);
protected:
- TextureMapper(AccelerationMode accelerationMode)
- : m_interpolationQuality(InterpolationDefault)
- , m_textDrawingMode(TextModeFill)
- , m_accelerationMode(accelerationMode)
- {}
+ TextureMapper(AccelerationMode);
private:
#if USE(TEXTURE_MAPPER_GL)
@@ -171,7 +167,7 @@ private:
#endif
InterpolationQuality m_interpolationQuality;
TextDrawingModeFlags m_textDrawingMode;
- Vector<RefPtr<BitmapTexture> > m_texturePool;
+ OwnPtr<BitmapTexturePool> m_texturePool;
GraphicsContext* m_context;
AccelerationMode m_accelerationMode;
};
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
index d4015a7c7..acfafb99b 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
@@ -33,10 +33,6 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#if USE(GRAPHICS_SURFACE)
-#include "GraphicsSurface.h"
-#endif
-
#if PLATFORM(QT)
#include "NativeImageQt.h"
#endif
@@ -381,7 +377,7 @@ void TextureMapperGL::drawTextureRectangleARB(uint32_t texture, Flags flags, con
m_context3D->uniform1i(program->samplerLocation(), 0);
m_context3D->uniform1f(program->flipLocation(), !!(flags & ShouldFlipTexture));
- m_context3D->uniform2f(program->textureSizeLocation(), textureSize.width(), textureSize.height());
+ m_context3D->uniform2f(program->samplerSizeLocation(), textureSize.width(), textureSize.height());
m_context3D->uniform1f(program->opacityLocation(), opacity);
if (maskTexture && maskTexture->isValid()) {
@@ -644,6 +640,7 @@ void BitmapTextureGL::updateContents(const void* srcData, const IntRect& targetR
const unsigned bytesPerPixel = 4;
char* data = reinterpret_cast<char*>(const_cast<void*>(srcData));
Vector<char> temporaryData;
+ IntPoint adjustedSourceOffset = sourceOffset;
// prepare temporaryData if necessary
if ((!driverSupportsBGRASwizzling() && updateContentsFlag == UpdateCannotModifyOriginalImageData)
@@ -659,14 +656,17 @@ void BitmapTextureGL::updateContents(const void* srcData, const IntRect& targetR
src += bytesPerLine;
dst += targetBytesPerLine;
}
+
+ bytesPerLine = targetBytesPerLine;
+ adjustedSourceOffset = IntPoint(0, 0);
}
if (driverSupportsBGRASwizzling())
glFormat = GraphicsContext3D::BGRA;
else
- swizzleBGRAToRGBA(reinterpret_cast<uint32_t*>(data), IntRect(sourceOffset, targetRect.size()), bytesPerLine / bytesPerPixel);
+ swizzleBGRAToRGBA(reinterpret_cast<uint32_t*>(data), IntRect(adjustedSourceOffset, targetRect.size()), bytesPerLine / bytesPerPixel);
- if (bytesPerLine == targetRect.width() * bytesPerPixel && sourceOffset == IntPoint::zero()) {
+ if (bytesPerLine == static_cast<int>(targetRect.width() * bytesPerPixel) && adjustedSourceOffset == IntPoint::zero()) {
m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, data);
return;
}
@@ -680,8 +680,8 @@ void BitmapTextureGL::updateContents(const void* srcData, const IntRect& targetR
#if !defined(TEXMAP_OPENGL_ES_2)
// Use the OpenGL sub-image extension, now that we know it's available.
m_context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, bytesPerLine / bytesPerPixel);
- m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, sourceOffset.y());
- m_context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, sourceOffset.x());
+ m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, adjustedSourceOffset.y());
+ m_context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, adjustedSourceOffset.x());
m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, data);
m_context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, 0);
m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, 0);
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
index 21bd7b235..401af8c3e 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
@@ -129,7 +129,7 @@ void TextureMapperLayer::updateBackingStore(TextureMapper* textureMapper, Graphi
context->translate(-dirtyRect.x(), -dirtyRect.y());
layer->paintGraphicsLayerContents(*context, dirtyRect);
- if (layer->showRepaintCounter()) {
+ if (layer->isShowingRepaintCounter()) {
layer->incrementRepaintCount();
drawRepaintCounter(context, layer);
}
@@ -138,7 +138,7 @@ void TextureMapperLayer::updateBackingStore(TextureMapper* textureMapper, Graphi
TextureMapperTiledBackingStore* backingStore = static_cast<TextureMapperTiledBackingStore*>(m_backingStore.get());
backingStore->updateContents(textureMapper, image.get(), m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);
- backingStore->setShowDebugBorders(layer->showDebugBorders());
+ backingStore->setShowDebugBorders(layer->isShowingDebugBorder());
backingStore->setDebugBorder(m_debugBorderColor, m_debugBorderWidth);
m_state.needsDisplay = false;
@@ -223,12 +223,12 @@ IntRect TextureMapperLayer::intermediateSurfaceRect(const TransformationMatrix&
}
#if ENABLE(CSS_FILTERS)
- if (m_state.filters.hasOutsets()) {
+ if (m_filters.hasOutsets()) {
int leftOutset;
int topOutset;
int bottomOutset;
int rightOutset;
- m_state.filters.getOutsets(topOutset, rightOutset, bottomOutset, leftOutset);
+ m_filters.getOutsets(topOutset, rightOutset, bottomOutset, leftOutset);
IntRect unfilteredTargetRect(rect);
rect.move(std::max(0, -leftOutset), std::max(0, -topOutset));
rect.expand(leftOutset + rightOutset, topOutset + bottomOutset);
@@ -262,7 +262,7 @@ TextureMapperLayer::ContentsLayerCount TextureMapperLayer::countPotentialLayersW
bool TextureMapperLayer::shouldPaintToIntermediateSurface() const
{
#if ENABLE(CSS_FILTERS)
- if (m_state.filters.size())
+ if (m_filters.size())
return true;
#endif
bool hasOpacity = m_opacity < 0.99;
@@ -381,7 +381,7 @@ void TextureMapperLayer::paintRecursive(const TextureMapperPaintOptions& options
maskTexture = 0;
#if ENABLE(CSS_FILTERS)
- surface = applyFilters(m_state.filters, options.textureMapper, surface.get(), surfaceRect);
+ surface = applyFilters(m_filters, options.textureMapper, surface.get(), surfaceRect);
#endif
options.textureMapper->bindSurface(options.surface.get());
@@ -510,6 +510,13 @@ bool TextureMapperLayer::descendantsOrSelfHaveRunningAnimations() const
return false;
}
+void TextureMapperLayer::applyAnimationsRecursively()
+{
+ syncAnimations();
+ for (size_t i = 0; i < m_children.size(); ++i)
+ m_children[i]->applyAnimationsRecursively();
+}
+
void TextureMapperLayer::syncAnimations()
{
m_animations.apply(this);
@@ -517,6 +524,10 @@ void TextureMapperLayer::syncAnimations()
setTransform(m_state.transform);
if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyOpacity))
setOpacity(m_state.opacity);
+#if ENABLE(CSS_FILTERS)
+ if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitFilter))
+ setFilters(m_state.filters);
+#endif
}
void TextureMapperLayer::flushCompositingState(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper, int options)
@@ -606,7 +617,7 @@ void TextureMapperLayer::drawRepaintCounter(GraphicsContext* context, GraphicsLa
cairo_text_extents(cr, repaintCount.data(), &repaintTextExtents);
static const int repaintCountBorderWidth = 10;
- setSourceRGBAFromColor(cr, layer->showDebugBorders() ? m_debugBorderColor : Color(0, 255, 0, 127));
+ setSourceRGBAFromColor(cr, layer->isShowingDebugBorder() ? m_debugBorderColor : Color(0, 255, 0, 127));
cairo_rectangle(cr, 0, 0,
repaintTextExtents.width + (repaintCountBorderWidth * 2),
repaintTextExtents.height + (repaintCountBorderWidth * 2));
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
index 5740acf52..5cd959d61 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
@@ -119,6 +119,9 @@ public:
IntSize size() const { return IntSize(m_size.width(), m_size.height()); }
void setTransform(const TransformationMatrix&);
void setOpacity(float value) { m_opacity = value; }
+#if ENABLE(CSS_FILTERS)
+ void setFilters(const FilterOperations& filters) { m_filters = filters; }
+#endif
void setTextureMapper(TextureMapper* texmap) { m_textureMapper = texmap; }
bool descendantsOrSelfHaveRunningAnimations() const;
@@ -132,6 +135,7 @@ public:
void setScrollPositionDeltaIfNeeded(const FloatSize&);
void setDebugBorder(const Color&, float width);
+ void applyAnimationsRecursively();
private:
TextureMapperLayer* rootLayer();
@@ -164,6 +168,9 @@ private:
// GraphicsLayerAnimation::Client
void setAnimatedTransform(const TransformationMatrix& matrix) { setTransform(matrix); }
void setAnimatedOpacity(float opacity) { setOpacity(opacity); }
+#if ENABLE(CSS_FILTERS)
+ virtual void setAnimatedFilters(const FilterOperations& filters) { setFilters(filters); }
+#endif
void syncAnimations();
bool isVisible() const;
@@ -190,6 +197,9 @@ private:
TextureMapperPlatformLayer* m_contentsLayer;
FloatSize m_size;
float m_opacity;
+#if ENABLE(CSS_FILTERS)
+ FilterOperations m_filters;
+#endif
float m_centerZ;
String m_name;
bool m_shouldUpdateBackingStoreFromLayer;
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp
index 27e786713..c8e1ae461 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp
@@ -224,12 +224,12 @@ static void getShaderSpec(TextureMapperShaderManager::ShaderKey key, String& ver
STRINGIFY(
precision mediump float;
uniform sampler2DRect s_sampler;
- uniform lowp vec2 s_samplerSize;
+ uniform lowp vec2 u_samplerSize;
uniform lowp float u_opacity;
varying highp vec2 v_sourceTexCoord;
void main(void)
{
- lowp vec4 color = texture2DRect(s_sampler, s_samplerSize * v_sourceTexCoord);
+ lowp vec4 color = texture2DRect(s_sampler, u_samplerSize * v_sourceTexCoord);
gl_FragColor = vec4(color.rgb * u_opacity, color.a * u_opacity);
}
);
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h
index b1f8d6107..380142945 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h
@@ -51,7 +51,7 @@ public:
TEXMAP_DECLARE_UNIFORM(matrix)
TEXMAP_DECLARE_UNIFORM(flip)
- TEXMAP_DECLARE_UNIFORM(textureSize)
+ TEXMAP_DECLARE_UNIFORM(samplerSize)
TEXMAP_DECLARE_UNIFORM(opacity)
TEXMAP_DECLARE_UNIFORM(color)
TEXMAP_DECLARE_UNIFORM(expandedQuadEdgesInScreenSpace)
diff --git a/Source/WebCore/platform/graphics/transforms/TransformState.cpp b/Source/WebCore/platform/graphics/transforms/TransformState.cpp
index a8fb8f32d..e0a9cec82 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformState.cpp
+++ b/Source/WebCore/platform/graphics/transforms/TransformState.cpp
@@ -76,13 +76,16 @@ void TransformState::move(LayoutUnit x, LayoutUnit y, TransformAccumulation accu
}
// FIXME: We transform AffineTransform to TransformationMatrix. This is rather inefficient.
-void TransformState::applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation accumulate)
+void TransformState::applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation accumulate, bool* wasClamped)
{
- applyTransform(transformFromContainer.toTransformationMatrix(), accumulate);
+ applyTransform(transformFromContainer.toTransformationMatrix(), accumulate, wasClamped);
}
-void TransformState::applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation accumulate)
+void TransformState::applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation accumulate, bool* wasClamped)
{
+ if (wasClamped)
+ *wasClamped = false;
+
// If we have an accumulated transform from last time, multiply in this transform
if (m_accumulatedTransform) {
if (m_direction == ApplyTransformDirection)
@@ -96,44 +99,53 @@ void TransformState::applyTransform(const TransformationMatrix& transformFromCon
if (accumulate == FlattenTransform) {
const TransformationMatrix* finalTransform = m_accumulatedTransform ? m_accumulatedTransform.get() : &transformFromContainer;
- flattenWithTransform(*finalTransform);
+ flattenWithTransform(*finalTransform, wasClamped);
}
m_accumulatingTransform = accumulate == AccumulateTransform;
}
-void TransformState::flatten()
+void TransformState::flatten(bool* wasClamped)
{
+ if (wasClamped)
+ *wasClamped = false;
+
if (!m_accumulatedTransform) {
m_accumulatingTransform = false;
return;
}
- flattenWithTransform(*m_accumulatedTransform);
+ flattenWithTransform(*m_accumulatedTransform, wasClamped);
}
-FloatPoint TransformState::mappedPoint() const
+FloatPoint TransformState::mappedPoint(bool* wasClamped) const
{
+ if (wasClamped)
+ *wasClamped = false;
+
if (!m_accumulatedTransform)
return m_lastPlanarPoint;
if (m_direction == ApplyTransformDirection)
return m_accumulatedTransform->mapPoint(m_lastPlanarPoint);
- return m_accumulatedTransform->inverse().projectPoint(m_lastPlanarPoint);
+ return m_accumulatedTransform->inverse().projectPoint(m_lastPlanarPoint, wasClamped);
}
-FloatQuad TransformState::mappedQuad() const
+FloatQuad TransformState::mappedQuad(bool* wasClamped) const
{
+ if (wasClamped)
+ *wasClamped = false;
+
if (!m_accumulatedTransform)
return m_lastPlanarQuad;
if (m_direction == ApplyTransformDirection)
return m_accumulatedTransform->mapQuad(m_lastPlanarQuad);
- return m_accumulatedTransform->inverse().projectQuad(m_lastPlanarQuad);
+ return m_accumulatedTransform->inverse().projectQuad(m_lastPlanarQuad, wasClamped);
}
-void TransformState::flattenWithTransform(const TransformationMatrix& t)
+void TransformState::flattenWithTransform(const TransformationMatrix& t, bool* wasClamped)
{
if (m_direction == ApplyTransformDirection) {
if (m_mapPoint)
@@ -145,7 +157,7 @@ void TransformState::flattenWithTransform(const TransformationMatrix& t)
if (m_mapPoint)
m_lastPlanarPoint = inverseTransform.projectPoint(m_lastPlanarPoint);
if (m_mapQuad)
- m_lastPlanarQuad = inverseTransform.projectQuad(m_lastPlanarQuad);
+ m_lastPlanarQuad = inverseTransform.projectQuad(m_lastPlanarQuad, wasClamped);
}
// We could throw away m_accumulatedTransform if we wanted to here, but that
diff --git a/Source/WebCore/platform/graphics/transforms/TransformState.h b/Source/WebCore/platform/graphics/transforms/TransformState.h
index 33eb7e0db..f34295f39 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformState.h
+++ b/Source/WebCore/platform/graphics/transforms/TransformState.h
@@ -81,20 +81,20 @@ public:
}
void move(LayoutUnit x, LayoutUnit y, TransformAccumulation = FlattenTransform);
- void applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation = FlattenTransform);
- void applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation = FlattenTransform);
- void flatten();
+ void applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = 0);
+ void applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = 0);
+ void flatten(bool* wasClamped = 0);
// Return the coords of the point or quad in the last flattened layer
FloatPoint lastPlanarPoint() const { return m_lastPlanarPoint; }
FloatQuad lastPlanarQuad() const { return m_lastPlanarQuad; }
// Return the point or quad mapped through the current transform
- FloatPoint mappedPoint() const;
- FloatQuad mappedQuad() const;
+ FloatPoint mappedPoint(bool* wasClamped = 0) const;
+ FloatQuad mappedQuad(bool* wasClamped = 0) const;
private:
- void flattenWithTransform(const TransformationMatrix&);
+ void flattenWithTransform(const TransformationMatrix&, bool* wasClamped);
FloatPoint m_lastPlanarPoint;
FloatQuad m_lastPlanarQuad;
diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
index 495b15f8b..a2fb7b687 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
@@ -589,7 +589,7 @@ FloatPoint TransformationMatrix::projectPoint(const FloatPoint& p, bool* clamped
return FloatPoint(static_cast<float>(outX), static_cast<float>(outY));
}
-FloatQuad TransformationMatrix::projectQuad(const FloatQuad& q) const
+FloatQuad TransformationMatrix::projectQuad(const FloatQuad& q, bool* clamped) const
{
FloatQuad projectedQuad;
@@ -603,6 +603,9 @@ FloatQuad TransformationMatrix::projectQuad(const FloatQuad& q) const
projectedQuad.setP3(projectPoint(q.p3(), &clamped3));
projectedQuad.setP4(projectPoint(q.p4(), &clamped4));
+ if (clamped)
+ *clamped = clamped1 || clamped2 || clamped3 || clamped4;
+
// If all points on the quad had w < 0, then the entire quad would not be visible to the projected surface.
bool everythingWasClipped = clamped1 && clamped2 && clamped3 && clamped4;
if (everythingWasClipped)
@@ -727,24 +730,22 @@ TransformationMatrix& TransformationMatrix::scale3d(double sx, double sy, double
TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double z, double angle)
{
- // Angles are in degrees. Switch to radians.
- angle = deg2rad(angle);
-
- double sinTheta = sin(angle);
- double cosTheta = cos(angle);
-
// Normalize the axis of rotation
double length = sqrt(x * x + y * y + z * z);
if (length == 0) {
- // bad vector, just use something reasonable
- x = 0;
- y = 0;
- z = 1;
+ // A direction vector that cannot be normalized, such as [0, 0, 0], will cause the rotation to not be applied.
+ return *this;
} else if (length != 1) {
x /= length;
y /= length;
z /= length;
}
+
+ // Angles are in degrees. Switch to radians.
+ angle = deg2rad(angle);
+
+ double sinTheta = sin(angle);
+ double cosTheta = cos(angle);
TransformationMatrix mat;
@@ -970,6 +971,149 @@ TransformationMatrix TransformationMatrix::rectToRect(const FloatRect& from, con
//
TransformationMatrix& TransformationMatrix::multiply(const TransformationMatrix& mat)
{
+#if CPU(APPLE_ARMV7S)
+ double* leftMatrix = &(m_matrix[0][0]);
+ const double* rightMatrix = &(mat.m_matrix[0][0]);
+ asm volatile (// First row of leftMatrix.
+ "mov r3, %[leftMatrix]\n\t"
+ "vld1.64 { d16-d19 }, [%[leftMatrix], :128]!\n\t"
+ "vld1.64 { d0-d3}, [%[rightMatrix], :128]!\n\t"
+ "vmul.f64 d4, d0, d16\n\t"
+ "vld1.64 { d20-d23 }, [%[leftMatrix], :128]!\n\t"
+ "vmla.f64 d4, d1, d20\n\t"
+ "vld1.64 { d24-d27 }, [%[leftMatrix], :128]!\n\t"
+ "vmla.f64 d4, d2, d24\n\t"
+ "vld1.64 { d28-d31 }, [%[leftMatrix], :128]!\n\t"
+ "vmla.f64 d4, d3, d28\n\t"
+
+ "vmul.f64 d5, d0, d17\n\t"
+ "vmla.f64 d5, d1, d21\n\t"
+ "vmla.f64 d5, d2, d25\n\t"
+ "vmla.f64 d5, d3, d29\n\t"
+
+ "vmul.f64 d6, d0, d18\n\t"
+ "vmla.f64 d6, d1, d22\n\t"
+ "vmla.f64 d6, d2, d26\n\t"
+ "vmla.f64 d6, d3, d30\n\t"
+
+ "vmul.f64 d7, d0, d19\n\t"
+ "vmla.f64 d7, d1, d23\n\t"
+ "vmla.f64 d7, d2, d27\n\t"
+ "vmla.f64 d7, d3, d31\n\t"
+ "vld1.64 { d0-d3}, [%[rightMatrix], :128]!\n\t"
+ "vst1.64 { d4-d7 }, [r3, :128]!\n\t"
+
+ // Second row of leftMatrix.
+ "vmul.f64 d4, d0, d16\n\t"
+ "vmla.f64 d4, d1, d20\n\t"
+ "vmla.f64 d4, d2, d24\n\t"
+ "vmla.f64 d4, d3, d28\n\t"
+
+ "vmul.f64 d5, d0, d17\n\t"
+ "vmla.f64 d5, d1, d21\n\t"
+ "vmla.f64 d5, d2, d25\n\t"
+ "vmla.f64 d5, d3, d29\n\t"
+
+ "vmul.f64 d6, d0, d18\n\t"
+ "vmla.f64 d6, d1, d22\n\t"
+ "vmla.f64 d6, d2, d26\n\t"
+ "vmla.f64 d6, d3, d30\n\t"
+
+ "vmul.f64 d7, d0, d19\n\t"
+ "vmla.f64 d7, d1, d23\n\t"
+ "vmla.f64 d7, d2, d27\n\t"
+ "vmla.f64 d7, d3, d31\n\t"
+ "vld1.64 { d0-d3}, [%[rightMatrix], :128]!\n\t"
+ "vst1.64 { d4-d7 }, [r3, :128]!\n\t"
+
+ // Third row of leftMatrix.
+ "vmul.f64 d4, d0, d16\n\t"
+ "vmla.f64 d4, d1, d20\n\t"
+ "vmla.f64 d4, d2, d24\n\t"
+ "vmla.f64 d4, d3, d28\n\t"
+
+ "vmul.f64 d5, d0, d17\n\t"
+ "vmla.f64 d5, d1, d21\n\t"
+ "vmla.f64 d5, d2, d25\n\t"
+ "vmla.f64 d5, d3, d29\n\t"
+
+ "vmul.f64 d6, d0, d18\n\t"
+ "vmla.f64 d6, d1, d22\n\t"
+ "vmla.f64 d6, d2, d26\n\t"
+ "vmla.f64 d6, d3, d30\n\t"
+
+ "vmul.f64 d7, d0, d19\n\t"
+ "vmla.f64 d7, d1, d23\n\t"
+ "vmla.f64 d7, d2, d27\n\t"
+ "vmla.f64 d7, d3, d31\n\t"
+ "vld1.64 { d0-d3}, [%[rightMatrix], :128]\n\t"
+ "vst1.64 { d4-d7 }, [r3, :128]!\n\t"
+
+ // Fourth and last row of leftMatrix.
+ "vmul.f64 d4, d0, d16\n\t"
+ "vmla.f64 d4, d1, d20\n\t"
+ "vmla.f64 d4, d2, d24\n\t"
+ "vmla.f64 d4, d3, d28\n\t"
+
+ "vmul.f64 d5, d0, d17\n\t"
+ "vmla.f64 d5, d1, d21\n\t"
+ "vmla.f64 d5, d2, d25\n\t"
+ "vmla.f64 d5, d3, d29\n\t"
+
+ "vmul.f64 d6, d0, d18\n\t"
+ "vmla.f64 d6, d1, d22\n\t"
+ "vmla.f64 d6, d2, d26\n\t"
+ "vmla.f64 d6, d3, d30\n\t"
+
+ "vmul.f64 d7, d0, d19\n\t"
+ "vmla.f64 d7, d1, d23\n\t"
+ "vmla.f64 d7, d2, d27\n\t"
+ "vmla.f64 d7, d3, d31\n\t"
+ "vst1.64 { d4-d7 }, [r3, :128]\n\t"
+ : [leftMatrix]"+r"(leftMatrix), [rightMatrix]"+r"(rightMatrix)
+ :
+ : "memory", "r3", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31");
+#elif CPU(ARM_VFP) && PLATFORM(IOS)
+
+#define MATRIX_MULTIPLY_ONE_LINE \
+ "vldmia.64 %[rightMatrix]!, { d0-d3}\n\t" \
+ "vmul.f64 d4, d0, d16\n\t" \
+ "vmla.f64 d4, d1, d20\n\t" \
+ "vmla.f64 d4, d2, d24\n\t" \
+ "vmla.f64 d4, d3, d28\n\t" \
+ \
+ "vmul.f64 d5, d0, d17\n\t" \
+ "vmla.f64 d5, d1, d21\n\t" \
+ "vmla.f64 d5, d2, d25\n\t" \
+ "vmla.f64 d5, d3, d29\n\t" \
+ \
+ "vmul.f64 d6, d0, d18\n\t" \
+ "vmla.f64 d6, d1, d22\n\t" \
+ "vmla.f64 d6, d2, d26\n\t" \
+ "vmla.f64 d6, d3, d30\n\t" \
+ \
+ "vmul.f64 d7, d0, d19\n\t" \
+ "vmla.f64 d7, d1, d23\n\t" \
+ "vmla.f64 d7, d2, d27\n\t" \
+ "vmla.f64 d7, d3, d31\n\t" \
+ "vstmia.64 %[leftMatrix]!, { d4-d7 }\n\t"
+
+ double* leftMatrix = &(m_matrix[0][0]);
+ const double* rightMatrix = &(mat.m_matrix[0][0]);
+ // We load the full m_matrix at once in d16-d31.
+ asm volatile("vldmia.64 %[leftMatrix], { d16-d31 }\n\t"
+ :
+ : [leftMatrix]"r"(leftMatrix)
+ : "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31");
+ for (unsigned i = 0; i < 4; ++i) {
+ asm volatile(MATRIX_MULTIPLY_ONE_LINE
+ : [leftMatrix]"+r"(leftMatrix), [rightMatrix]"+r"(rightMatrix)
+ :
+ : "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7");
+ }
+#undef MATRIX_MULTIPLY_ONE_LINE
+
+#else
Matrix4 tmp;
tmp[0][0] = (mat.m_matrix[0][0] * m_matrix[0][0] + mat.m_matrix[0][1] * m_matrix[1][0]
@@ -1009,6 +1153,7 @@ TransformationMatrix& TransformationMatrix::multiply(const TransformationMatrix&
+ mat.m_matrix[3][2] * m_matrix[2][3] + mat.m_matrix[3][3] * m_matrix[3][3]);
setMatrix(tmp);
+#endif
return *this;
}
diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
index 9eda74608..49e4b0796 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -72,7 +72,11 @@ class FloatQuad;
class TransformationMatrix {
WTF_MAKE_FAST_ALLOCATED;
public:
+#if CPU(APPLE_ARMV7S)
+ typedef double Matrix4[4][4] __attribute__((aligned (16)));
+#else
typedef double Matrix4[4][4];
+#endif
TransformationMatrix() { makeIdentity(); }
TransformationMatrix(const AffineTransform& t);
@@ -166,7 +170,7 @@ public:
// with the destination plane.
FloatPoint projectPoint(const FloatPoint&, bool* clamped = 0) const;
// Projects the four corners of the quad
- FloatQuad projectQuad(const FloatQuad&) const;
+ FloatQuad projectQuad(const FloatQuad&, bool* clamped = 0) const;
// Projects the four corners of the quad and takes a bounding box,
// while sanitizing values created when the w component is negative.
FractionalLayoutRect clampedBoundsOfProjectedQuad(const FloatQuad&) const;
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
index 72323518f..f2125c78f 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
@@ -148,26 +148,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
return SimpleFontData::create(FontPlatformData(hfont, scaledSize, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()), isCustomFont(), false);
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, cSmallCapsFontSizeMultiplier);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
-
- return m_derivedFontData->emphasisMark;
-}
-
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
// FIXME: Support custom fonts.
diff --git a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
index 5925c7aa9..842fad5f3 100644
--- a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
@@ -75,26 +75,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
return SimpleFontData::create(*result);
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
-
- return m_derivedFontData->emphasisMark;
-}
-
DWORD getKnownFontCodePages(const wchar_t* family);
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
index e08a1540c..a58d3e512 100644
--- a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
@@ -98,26 +98,6 @@ PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
return SimpleFontData::create(platformData, isCustomFont(), false);
}
-PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->smallCaps)
- m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
-
- return m_derivedFontData->smallCaps;
-}
-
-PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
-{
- if (!m_derivedFontData)
- m_derivedFontData = DerivedFontData::create(isCustomFont());
- if (!m_derivedFontData->emphasisMark)
- m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
-
- return m_derivedFontData->emphasisMark;
-}
-
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
// FIXME: We will need to implement this to load non-ASCII encoding sites