summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/BitmapImage.h2
-rw-r--r--Source/WebCore/platform/graphics/Color.cpp27
-rw-r--r--Source/WebCore/platform/graphics/ContextShadow.h2
-rw-r--r--Source/WebCore/platform/graphics/Font.cpp2
-rw-r--r--Source/WebCore/platform/graphics/Font.h11
-rw-r--r--Source/WebCore/platform/graphics/FontCache.cpp14
-rw-r--r--Source/WebCore/platform/graphics/FontDescription.h10
-rw-r--r--Source/WebCore/platform/graphics/FontFallbackList.cpp17
-rw-r--r--Source/WebCore/platform/graphics/FontFallbackList.h3
-rw-r--r--Source/WebCore/platform/graphics/FontFastPath.cpp64
-rw-r--r--Source/WebCore/platform/graphics/FontPlatformData.cpp63
-rw-r--r--Source/WebCore/platform/graphics/FontPlatformData.h359
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.h7
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.h30
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayer.h5
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.h4
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.cpp31
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.h35
-rw-r--r--Source/WebCore/platform/graphics/Path.cpp8
-rw-r--r--Source/WebCore/platform/graphics/Path.h8
-rw-r--r--Source/WebCore/platform/graphics/SimpleFontData.cpp42
-rw-r--r--Source/WebCore/platform/graphics/SimpleFontData.h30
-rw-r--r--Source/WebCore/platform/graphics/TextRun.h23
-rw-r--r--Source/WebCore/platform/graphics/Tile.h2
-rw-r--r--Source/WebCore/platform/graphics/TiledBackingStore.cpp10
-rw-r--r--Source/WebCore/platform/graphics/WOFFFileFormat.cpp4
-rw-r--r--Source/WebCore/platform/graphics/WidthIterator.cpp24
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp731
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h262
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h131
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm811
-rw-r--r--Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp12
-rw-r--r--Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h5
-rw-r--r--Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp7
-rw-r--r--Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp7
-rw-r--r--Source/WebCore/platform/graphics/cairo/FontCairo.cpp9
-rw-r--r--Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/cairo/GradientCairo.cpp3
-rw-r--r--Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp116
-rw-r--r--Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h30
-rw-r--r--Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp11
-rw-r--r--Source/WebCore/platform/graphics/cairo/ImageBufferData.h5
-rw-r--r--Source/WebCore/platform/graphics/cairo/ImageCairo.cpp6
-rw-r--r--Source/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cairo/OwnPtrCairo.h4
-rw-r--r--Source/WebCore/platform/graphics/cairo/PathCairo.cpp2
-rw-r--r--Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp38
-rw-r--r--Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h52
-rw-r--r--Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cairo/RefPtrCairo.h4
-rw-r--r--Source/WebCore/platform/graphics/cg/FontPlatformData.h105
-rw-r--r--Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp36
-rw-r--r--Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h13
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp60
-rw-r--r--Source/WebCore/platform/graphics/cg/PathCG.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp28
-rw-r--r--Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h7
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp51
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h6
-rw-r--r--Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm2
-rw-r--r--Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp19
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp3
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp30
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontLinux.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp10
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h11
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp394
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.h19
-rw-r--r--Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.cpp101
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.h38
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp313
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h61
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp148
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h51
-rw-r--r--Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp38
-rw-r--r--Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h13
-rw-r--r--Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp17
-rw-r--r--Source/WebCore/platform/graphics/chromium/ShaderChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp6
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp227
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h45
-rw-r--r--Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp16
-rw-r--r--Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp80
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h61
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp27
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h62
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp84
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h60
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp173
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h75
-rw-r--r--Source/WebCore/platform/graphics/cocoa/FontPlatformData.h176
-rw-r--r--Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm42
-rw-r--r--Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp2
-rw-r--r--Source/WebCore/platform/graphics/freetype/FontPlatformData.h1
-rw-r--r--Source/WebCore/platform/graphics/gpu/BicubicShader.cpp137
-rw-r--r--Source/WebCore/platform/graphics/gpu/BicubicShader.h58
-rw-r--r--Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp125
-rw-r--r--Source/WebCore/platform/graphics/gpu/ConvolutionShader.h58
-rw-r--r--Source/WebCore/platform/graphics/gpu/DrawingBuffer.h13
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp5
-rw-r--r--Source/WebCore/platform/graphics/gpu/PODRedBlackTree.h4
-rw-r--r--Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp69
-rw-r--r--Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h28
-rw-r--r--Source/WebCore/platform/graphics/gpu/TilingData.cpp2
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp36
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h2
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp2
-rw-r--r--Source/WebCore/platform/graphics/gtk/FontGtk.cpp23
-rw-r--r--Source/WebCore/platform/graphics/gtk/IconGtk.cpp6
-rw-r--r--Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp2
-rw-r--r--Source/WebCore/platform/graphics/gtk/ImageGtk.cpp5
-rw-r--r--Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp2
-rw-r--r--Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.cpp24
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.h1
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp2
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp6
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCacheMac.mm2
-rw-r--r--Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/mac/FontMac.mm86
-rw-r--r--Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm12
-rw-r--r--Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h6
-rw-r--r--Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm88
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp10
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm56
-rw-r--r--Source/WebCore/platform/graphics/mac/WebLayer.h3
-rw-r--r--Source/WebCore/platform/graphics/mac/WebLayer.mm6
-rw-r--r--Source/WebCore/platform/graphics/mac/WebTiledLayer.mm2
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp125
-rw-r--r--Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp6
-rw-r--r--Source/WebCore/platform/graphics/opengl/TextureMapperGL.h2
-rw-r--r--Source/WebCore/platform/graphics/openvg/PathOpenVG.cpp8
-rw-r--r--Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp2
-rw-r--r--Source/WebCore/platform/graphics/pango/FontPlatformData.h2
-rw-r--r--Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp1
-rw-r--r--Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h4
-rw-r--r--Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp2
-rw-r--r--Source/WebCore/platform/graphics/qt/FontPlatformData.h1
-rw-r--r--Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp2
-rw-r--r--Source/WebCore/platform/graphics/qt/FontQt.cpp32
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp324
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp3
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp44
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h8
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferData.h2
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp23
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp10
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp70
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h7
-rw-r--r--Source/WebCore/platform/graphics/qt/PathQt.cpp22
-rw-r--r--Source/WebCore/platform/graphics/qt/TileQt.cpp8
-rw-r--r--Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp5
-rw-r--r--Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h5
-rw-r--r--Source/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp2
-rw-r--r--Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp13
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp42
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageSkia.cpp1
-rw-r--r--Source/WebCore/platform/graphics/skia/PathSkia.cpp2
-rw-r--r--Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp27
-rw-r--r--Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp7
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp9
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h1
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapper.h4
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperNode.h8
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h8
-rw-r--r--Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp9
-rw-r--r--Source/WebCore/platform/graphics/win/FontCacheWin.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/FontCustomPlatformData.h4
-rw-r--r--Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp5
-rw-r--r--Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h2
-rw-r--r--Source/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp33
-rw-r--r--Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp69
-rw-r--r--Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp19
-rw-r--r--Source/WebCore/platform/graphics/win/FontWin.cpp4
-rw-r--r--Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp34
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp14
-rw-r--r--Source/WebCore/platform/graphics/win/QTMovie.cpp11
-rw-r--r--Source/WebCore/platform/graphics/win/QTMovie.h1
-rw-r--r--Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp10
-rw-r--r--Source/WebCore/platform/graphics/win/cairo/FontPlatformData.h114
-rw-r--r--Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp2
-rw-r--r--Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/wince/FontPlatformData.cpp2
-rw-r--r--Source/WebCore/platform/graphics/wince/FontPlatformData.h1
-rw-r--r--Source/WebCore/platform/graphics/wince/PathWinCE.cpp2
-rw-r--r--Source/WebCore/platform/graphics/wx/FontPlatformData.h1
-rw-r--r--Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp4
-rw-r--r--Source/WebCore/platform/graphics/wx/PathWx.cpp2
201 files changed, 5907 insertions, 2026 deletions
diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h
index 14a3094..c8cf0ab 100644
--- a/Source/WebCore/platform/graphics/BitmapImage.h
+++ b/Source/WebCore/platform/graphics/BitmapImage.h
@@ -165,7 +165,7 @@ protected:
enum RepetitionCountStatus {
Unknown, // We haven't checked the source's repetition count.
Uncertain, // We have a repetition count, but it might be wrong (some GIFs have a count after the image data, and will report "loop once" until all data has been decoded).
- Certain, // The repetition count is known to be correct.
+ Certain // The repetition count is known to be correct.
};
BitmapImage(NativeImagePtr, ImageObserver* = 0);
diff --git a/Source/WebCore/platform/graphics/Color.cpp b/Source/WebCore/platform/graphics/Color.cpp
index a1c5cd7..7dea765 100644
--- a/Source/WebCore/platform/graphics/Color.cpp
+++ b/Source/WebCore/platform/graphics/Color.cpp
@@ -27,13 +27,12 @@
#include "Color.h"
#include "HashTools.h"
-#include "PlatformString.h"
-#include <math.h>
#include <wtf/Assertions.h>
+#include <wtf/HexNumber.h>
#include <wtf/MathExtras.h>
+#include <wtf/text/StringBuilder.h>
using namespace std;
-using namespace WTF;
namespace WebCore {
@@ -180,14 +179,6 @@ Color::Color(const char* name)
}
}
-static inline void appendHexNumber(UChar* destination, uint8_t number)
-{
- static const char hexDigits[17] = "0123456789abcdef";
-
- destination[0] = hexDigits[number >> 4];
- destination[1] = hexDigits[number & 0xF];
-}
-
String Color::serialized() const
{
DEFINE_STATIC_LOCAL(const String, commaSpace, (", "));
@@ -195,13 +186,13 @@ String Color::serialized() const
DEFINE_STATIC_LOCAL(const String, zeroPointZero, ("0.0"));
if (!hasAlpha()) {
- UChar* characters;
- String result = String::createUninitialized(7, characters);
- characters[0] = '#';
- appendHexNumber(characters + 1, red());
- appendHexNumber(characters + 3, green());
- appendHexNumber(characters + 5, blue());
- return result;
+ StringBuilder builder;
+ builder.reserveCapacity(7);
+ builder.append('#');
+ appendByteAsHex(red(), builder, Lowercase);
+ appendByteAsHex(green(), builder, Lowercase);
+ appendByteAsHex(blue(), builder, Lowercase);
+ return builder.toString();
}
Vector<UChar> result;
diff --git a/Source/WebCore/platform/graphics/ContextShadow.h b/Source/WebCore/platform/graphics/ContextShadow.h
index c0571f0..850d489 100644
--- a/Source/WebCore/platform/graphics/ContextShadow.h
+++ b/Source/WebCore/platform/graphics/ContextShadow.h
@@ -32,7 +32,7 @@
#include "Color.h"
#include "FloatRect.h"
#include "IntRect.h"
-#include "RefCounted.h"
+#include <wtf/RefCounted.h>
#if PLATFORM(CAIRO)
typedef struct _cairo cairo_t;
diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp
index ee85e45..72e3e3b 100644
--- a/Source/WebCore/platform/graphics/Font.cpp
+++ b/Source/WebCore/platform/graphics/Font.cpp
@@ -177,7 +177,7 @@ float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFo
// If the complex text implementation cannot return fallback fonts, avoid
// returning them for simple text as well.
static bool returnFallbackFonts = canReturnFallbackFontsForComplexText();
- return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow ? glyphOverflow : 0);
+ return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow || (glyphOverflow && glyphOverflow->computeBounds) ? glyphOverflow : 0);
}
return floatWidthForComplexText(run, fallbackFonts, glyphOverflow);
diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h
index ce03aed..554f8a0 100644
--- a/Source/WebCore/platform/graphics/Font.h
+++ b/Source/WebCore/platform/graphics/Font.h
@@ -61,6 +61,7 @@ struct GlyphOverflow {
, right(0)
, top(0)
, bottom(0)
+ , computeBounds(false)
{
}
@@ -68,8 +69,10 @@ struct GlyphOverflow {
int right;
int top;
int bottom;
+ bool computeBounds;
};
+
class Font {
public:
Font();
@@ -138,8 +141,6 @@ public:
const FontData* fontDataAt(unsigned) const;
GlyphData glyphDataForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const;
bool primaryFontHasGlyphForCharacter(UChar32) const;
- // Used for complex text, and does not utilize the glyph map cache.
- const FontData* fontDataForCharacters(const UChar*, int length) const;
static bool isCJKIdeograph(UChar32);
static bool isCJKIdeographOrSymbol(UChar32);
@@ -255,12 +256,6 @@ inline const FontData* Font::fontDataAt(unsigned index) const
return m_fontList->fontDataAt(this, index);
}
-inline const FontData* Font::fontDataForCharacters(const UChar* characters, int length) const
-{
- ASSERT(m_fontList);
- return m_fontList->fontDataForCharacters(this, characters, length);
-}
-
inline bool Font::isFixedPitch() const
{
ASSERT(m_fontList);
diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp
index 5b508be..8c5edfe 100644
--- a/Source/WebCore/platform/graphics/FontCache.cpp
+++ b/Source/WebCore/platform/graphics/FontCache.cpp
@@ -57,7 +57,8 @@ struct FontPlatformDataCacheKey {
WTF_MAKE_FAST_ALLOCATED;
public:
FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, unsigned weight = 0, bool italic = false,
- bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode, FontOrientation orientation = Horizontal, FontWidthVariant widthVariant = RegularWidth)
+ bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode, FontOrientation orientation = Horizontal,
+ TextOrientation textOrientation = TextOrientationVerticalRight, FontWidthVariant widthVariant = RegularWidth)
: m_size(size)
, m_weight(weight)
, m_family(family)
@@ -65,6 +66,7 @@ public:
, m_printerFont(isPrinterFont)
, m_renderingMode(renderingMode)
, m_orientation(orientation)
+ , m_textOrientation(textOrientation)
, m_widthVariant(widthVariant)
{
}
@@ -76,7 +78,7 @@ public:
{
return equalIgnoringCase(m_family, other.m_family) && m_size == other.m_size &&
m_weight == other.m_weight && m_italic == other.m_italic && m_printerFont == other.m_printerFont &&
- m_renderingMode == other.m_renderingMode && m_orientation == other.m_orientation && m_widthVariant == other.m_widthVariant;
+ m_renderingMode == other.m_renderingMode && m_orientation == other.m_orientation && m_textOrientation == other.m_textOrientation && m_widthVariant == other.m_widthVariant;
}
unsigned m_size;
@@ -86,6 +88,7 @@ public:
bool m_printerFont;
FontRenderingMode m_renderingMode;
FontOrientation m_orientation;
+ TextOrientation m_textOrientation;
FontWidthVariant m_widthVariant;
private:
@@ -99,9 +102,9 @@ inline unsigned computeHash(const FontPlatformDataCacheKey& fontKey)
fontKey.m_size,
fontKey.m_weight,
fontKey.m_widthVariant,
- static_cast<unsigned>(fontKey.m_orientation) << 3 | static_cast<unsigned>(fontKey.m_italic) << 2 | static_cast<unsigned>(fontKey.m_printerFont) << 1 | static_cast<unsigned>(fontKey.m_renderingMode)
+ static_cast<unsigned>(fontKey.m_textOrientation) << 4 | static_cast<unsigned>(fontKey.m_orientation) << 3 | static_cast<unsigned>(fontKey.m_italic) << 2 | static_cast<unsigned>(fontKey.m_printerFont) << 1 | static_cast<unsigned>(fontKey.m_renderingMode)
};
- return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
+ return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
}
struct FontPlatformDataCacheKeyHash {
@@ -198,7 +201,8 @@ FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& fo
}
FontPlatformDataCacheKey key(familyName, fontDescription.computedPixelSize(), fontDescription.weight(), fontDescription.italic(),
- fontDescription.usePrinterFont(), fontDescription.renderingMode(), fontDescription.orientation(), fontDescription.widthVariant());
+ fontDescription.usePrinterFont(), fontDescription.renderingMode(), fontDescription.orientation(),
+ fontDescription.textOrientation(), fontDescription.widthVariant());
FontPlatformData* result = 0;
bool foundResult;
FontPlatformDataCache::iterator it = gFontPlatformDataCache->find(key);
diff --git a/Source/WebCore/platform/graphics/FontDescription.h b/Source/WebCore/platform/graphics/FontDescription.h
index 283d297..5b05f14 100644
--- a/Source/WebCore/platform/graphics/FontDescription.h
+++ b/Source/WebCore/platform/graphics/FontDescription.h
@@ -31,6 +31,7 @@
#include "FontSmoothingMode.h"
#include "FontTraitsMask.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include "TextRenderingMode.h"
namespace WebCore {
@@ -58,6 +59,7 @@ public:
: m_specifiedSize(0)
, m_computedSize(0)
, m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
, m_widthVariant(RegularWidth)
, m_italic(false)
, m_smallCaps(false)
@@ -99,6 +101,7 @@ public:
FontTraitsMask traitsMask() const;
bool isSpecifiedFont() const { return m_isSpecifiedFont; }
FontOrientation orientation() const { return m_orientation; }
+ TextOrientation textOrientation() const { return m_textOrientation; }
FontWidthVariant widthVariant() const { return m_widthVariant; }
void setFamily(const FontFamily& family) { m_familyList = family; }
@@ -120,6 +123,7 @@ public:
void setTextRenderingMode(TextRenderingMode rendering) { m_textRendering = rendering; }
void setIsSpecifiedFont(bool isSpecifiedFont) { m_isSpecifiedFont = isSpecifiedFont; }
void setOrientation(FontOrientation orientation) { m_orientation = orientation; }
+ void setTextOrientation(TextOrientation textOrientation) { m_textOrientation = textOrientation; }
void setWidthVariant(FontWidthVariant widthVariant) { m_widthVariant = widthVariant; }
private:
@@ -129,8 +133,9 @@ private:
// rounding, minimum font sizes, and zooming.
float m_computedSize; // Computed size adjusted for the minimum font size and the zoom factor.
- FontOrientation m_orientation;
-
+ FontOrientation m_orientation; // Whether the font is rendering on a horizontal line or a vertical line.
+ TextOrientation m_textOrientation; // Only used by vertical text. Determines the default orientation for non-ideograph glyphs.
+
FontWidthVariant m_widthVariant;
bool m_italic : 1;
@@ -169,6 +174,7 @@ inline bool FontDescription::operator==(const FontDescription& other) const
&& m_textRendering == other.m_textRendering
&& m_isSpecifiedFont == other.m_isSpecifiedFont
&& m_orientation == other.m_orientation
+ && m_textOrientation == other.m_textOrientation
&& m_widthVariant == other.m_widthVariant;
}
diff --git a/Source/WebCore/platform/graphics/FontFallbackList.cpp b/Source/WebCore/platform/graphics/FontFallbackList.cpp
index 649c117..7df58d9 100644
--- a/Source/WebCore/platform/graphics/FontFallbackList.cpp
+++ b/Source/WebCore/platform/graphics/FontFallbackList.cpp
@@ -111,23 +111,6 @@ const FontData* FontFallbackList::fontDataAt(const Font* font, unsigned realized
return result;
}
-const FontData* FontFallbackList::fontDataForCharacters(const Font* font, const UChar* characters, int length) const
-{
- // This method is only called when the primary font does not contain the characters we need.
- // Begin our search at position 1.
- unsigned realizedFontIndex = 1;
- const FontData* fontData = fontDataAt(font, realizedFontIndex);
- while (fontData && !fontData->containsCharacters(characters, length))
- fontData = fontDataAt(font, ++realizedFontIndex);
-
- if (!fontData) {
- ASSERT(fontCache()->generation() == m_generation);
- fontData = fontCache()->getFontDataForCharacters(*font, characters, length);
- }
-
- return fontData;
-}
-
void FontFallbackList::setPlatformFont(const FontPlatformData& platformData)
{
m_familyIndex = cAllFamiliesScanned;
diff --git a/Source/WebCore/platform/graphics/FontFallbackList.h b/Source/WebCore/platform/graphics/FontFallbackList.h
index a10f5af..e18477c 100644
--- a/Source/WebCore/platform/graphics/FontFallbackList.h
+++ b/Source/WebCore/platform/graphics/FontFallbackList.h
@@ -65,8 +65,7 @@ private:
const FontData* primaryFontData(const Font* f) const { return fontDataAt(f, 0); }
const FontData* fontDataAt(const Font*, unsigned index) const;
- const FontData* fontDataForCharacters(const Font*, const UChar*, int length) const;
-
+
void setPlatformFont(const FontPlatformData&);
void releaseFontData();
diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp
index e62df61..b741ca0 100644
--- a/Source/WebCore/platform/graphics/FontFastPath.cpp
+++ b/Source/WebCore/platform/graphics/FontFastPath.cpp
@@ -77,17 +77,57 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant va
page = node->page();
if (page) {
GlyphData data = page->glyphDataForCharacter(c);
+ if (data.fontData && (data.fontData->platformData().orientation() == Horizontal || data.fontData->isTextOrientationFallback()))
+ return data;
+
if (data.fontData) {
- if (data.fontData->platformData().orientation() == Vertical && data.fontData->orientation() == Horizontal && Font::isCJKIdeographOrSymbol(c)) {
- const SimpleFontData* ideographFontData = data.fontData->brokenIdeographFontData();
- GlyphPageTreeNode* ideographNode = GlyphPageTreeNode::getRootChild(ideographFontData, pageNumber);
- const GlyphPage* ideographPage = ideographNode->page();
- if (ideographPage) {
- GlyphData data = ideographPage->glyphDataForCharacter(c);
- if (data.fontData)
- return data;
+ if (isCJKIdeographOrSymbol(c)) {
+ if (!data.fontData->hasVerticalGlyphs()) {
+ // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs
+ // to make sure you get a square (even for broken glyphs like symbols used for punctuation).
+ const SimpleFontData* brokenIdeographFontData = data.fontData->brokenIdeographFontData();
+ GlyphPageTreeNode* brokenIdeographNode = GlyphPageTreeNode::getRootChild(brokenIdeographFontData, pageNumber);
+ const GlyphPage* brokenIdeographPage = brokenIdeographNode->page();
+ if (brokenIdeographPage) {
+ GlyphData brokenIdeographData = brokenIdeographPage->glyphDataForCharacter(c);
+ if (brokenIdeographData.fontData)
+ return brokenIdeographData;
+ }
+
+ // Shouldn't be possible to even reach this point.
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ if (m_fontDescription.textOrientation() == TextOrientationVerticalRight) {
+ const SimpleFontData* verticalRightFontData = data.fontData->verticalRightOrientationFontData();
+ GlyphPageTreeNode* verticalRightNode = GlyphPageTreeNode::getRootChild(verticalRightFontData, pageNumber);
+ const GlyphPage* verticalRightPage = verticalRightNode->page();
+ if (verticalRightPage) {
+ GlyphData verticalRightData = verticalRightPage->glyphDataForCharacter(c);
+ // If the glyphs are distinct, we will make the assumption that the font has a vertical-right glyph baked
+ // into it.
+ if (data.glyph != verticalRightData.glyph)
+ return data;
+ // The glyphs are identical, meaning that we should just use the horizontal glyph.
+ if (verticalRightData.fontData)
+ return verticalRightData;
+ }
+ } else if (m_fontDescription.textOrientation() == TextOrientationUpright) {
+ const SimpleFontData* uprightFontData = data.fontData->uprightOrientationFontData();
+ GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getRootChild(uprightFontData, pageNumber);
+ const GlyphPage* uprightPage = uprightNode->page();
+ if (uprightPage) {
+ GlyphData uprightData = uprightPage->glyphDataForCharacter(c);
+ // If the glyphs are the same, then we know we can just use the horizontal glyph rotated vertically to be upright.
+ if (data.glyph == uprightData.glyph)
+ return data;
+ // The glyphs are distinct, meaning that the font has a vertical-right glyph baked into it. We can't use that
+ // glyph, so we fall back to the upright data and use the horizontal glyph.
+ if (uprightData.fontData)
+ return uprightData;
+ }
}
-
+
// Shouldn't be possible to even reach this point.
ASSERT_NOT_REACHED();
}
@@ -364,7 +404,7 @@ void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuf
inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph)
{
- if (fontData->orientation() == Horizontal) {
+ if (fontData->platformData().orientation() == Horizontal) {
FloatRect bounds = fontData->boundsForGlyph(glyph);
return bounds.x() + bounds.width() / 2;
}
@@ -412,8 +452,8 @@ float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer
it.advance(run.length(), glyphBuffer);
if (glyphOverflow) {
- glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - fontMetrics().ascent());
- glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - fontMetrics().descent());
+ glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
+ glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().descent()));
glyphOverflow->left = ceilf(it.firstGlyphOverflow());
glyphOverflow->right = ceilf(it.lastGlyphOverflow());
}
diff --git a/Source/WebCore/platform/graphics/FontPlatformData.cpp b/Source/WebCore/platform/graphics/FontPlatformData.cpp
new file mode 100644
index 0000000..5a61cdf
--- /dev/null
+++ b/Source/WebCore/platform/graphics/FontPlatformData.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Brent Fulgham
+ *
+ * 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 "FontPlatformData.h"
+
+#include "PlatformString.h"
+#include <wtf/HashMap.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
+
+using namespace std;
+
+namespace WebCore {
+
+FontPlatformData::FontPlatformData(const FontPlatformData& source)
+ : m_syntheticBold(source.m_syntheticBold)
+ , m_syntheticOblique(source.m_syntheticOblique)
+ , m_orientation(source.m_orientation)
+ , m_textOrientation(source.m_textOrientation)
+ , m_size(source.m_size)
+ , m_widthVariant(source.m_widthVariant)
+ , m_isColorBitmapFont(source.m_isColorBitmapFont)
+{
+ platformDataInit(source);
+}
+
+const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
+{
+ // Check for self-assignment.
+ if (this == &other)
+ return *this;
+
+ m_syntheticBold = other.m_syntheticBold;
+ m_syntheticOblique = other.m_syntheticOblique;
+ m_orientation = other.m_orientation;
+ m_textOrientation = other.m_textOrientation;
+ m_size = other.m_size;
+ m_widthVariant = other.m_widthVariant;
+ m_isColorBitmapFont = other.m_isColorBitmapFont;
+
+ return platformDataAssign(other);
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/FontPlatformData.h b/Source/WebCore/platform/graphics/FontPlatformData.h
new file mode 100644
index 0000000..78c86ef
--- /dev/null
+++ b/Source/WebCore/platform/graphics/FontPlatformData.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc.
+ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
+ * Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * Copyright (C) 2010, 2011 Brent Fulgham <bfulgham@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.
+ *
+ */
+
+// FIXME: This is temporary until all ports switch to using this file.
+#if PLATFORM(CHROMIUM) && !OS(DARWIN)
+#include "chromium/FontPlatformData.h"
+#elif PLATFORM(QT)
+#include "qt/FontPlatformData.h"
+#elif PLATFORM(WIN) && OS(WINCE)
+#include "wince/FontPlatformData.h"
+#elif PLATFORM(WX)
+#include "wx/FontPlatformData.h"
+#elif (PLATFORM(EFL) || PLATFORM(GTK)) && USE(FREETYPE)
+#include "freetype/FontPlatformData.h"
+#elif (PLATFORM(EFL) || PLATFORM(GTK)) && USE(PANGO)
+#include "pango/FontPlatformData.h"
+#else
+
+#ifndef FontPlatformData_h
+#define FontPlatformData_h
+
+#include "FontOrientation.h"
+#include "FontWidthVariant.h"
+#include "GlyphBuffer.h"
+#include "TextOrientation.h"
+
+#if PLATFORM(WIN)
+#include "RefCountedGDIHandle.h"
+#endif
+
+#if PLATFORM(CAIRO)
+#include "HashFunctions.h"
+#include <cairo.h>
+#endif
+
+#if OS(DARWIN)
+#ifdef __OBJC__
+@class NSFont;
+#else
+class NSFont;
+#endif
+
+typedef struct CGFont* CGFontRef;
+#ifndef BUILDING_ON_TIGER
+typedef const struct __CTFont* CTFontRef;
+#endif
+
+#include <CoreFoundation/CFBase.h>
+#include <objc/objc-auto.h>
+#endif
+
+#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/text/StringImpl.h>
+
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
+#include "CrossProcessFontLoading.h"
+#endif
+
+#if PLATFORM(WIN)
+typedef struct HFONT__* HFONT;
+#endif
+
+#if PLATFORM(CG)
+typedef struct CGFont* CGFontRef;
+#if OS(DARWIN)
+#ifndef BUILDING_ON_TIGER
+typedef const struct __CTFont* CTFontRef;
+typedef UInt32 ATSUFontID;
+typedef UInt32 ATSFontRef;
+#endif
+#endif
+#endif
+
+namespace WebCore {
+
+class FontDescription;
+
+#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
+inline CTFontRef toCTFontRef(NSFont *nsFont) { return reinterpret_cast<CTFontRef>(nsFont); }
+#endif
+
+class FontPlatformData {
+public:
+ FontPlatformData(WTF::HashTableDeletedValueType)
+ : m_syntheticBold(false)
+ , m_syntheticOblique(false)
+ , m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
+ , m_size(0)
+ , m_widthVariant(RegularWidth)
+#if PLATFORM(WIN)
+ , m_font(WTF::HashTableDeletedValue)
+#elif OS(DARWIN)
+ , m_font(hashTableDeletedFontValue())
+#endif
+#if PLATFORM(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
+ , m_cgFont(0)
+#elif PLATFORM(CAIRO)
+ , m_scaledFont(hashTableDeletedFontValue())
+#endif
+ , m_isColorBitmapFont(false)
+#if PLATFORM(WIN)
+ , m_useGDI(false)
+#endif
+ {
+ }
+
+ FontPlatformData()
+ : m_syntheticBold(false)
+ , m_syntheticOblique(false)
+ , m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
+ , m_size(0)
+ , m_widthVariant(RegularWidth)
+#if OS(DARWIN)
+ , m_font(0)
+#endif
+#if PLATFORM(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
+ , m_cgFont(0)
+#elif PLATFORM(CAIRO)
+ , m_scaledFont(0)
+#endif
+ , m_isColorBitmapFont(false)
+#if PLATFORM(WIN)
+ , m_useGDI(false)
+#endif
+ {
+ }
+
+ FontPlatformData(const FontPlatformData&);
+ FontPlatformData(const FontDescription&, const AtomicString& family);
+ FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation = Horizontal,
+ TextOrientation textOrientation = TextOrientationVerticalRight, FontWidthVariant widthVariant = RegularWidth)
+ : m_syntheticBold(syntheticBold)
+ , m_syntheticOblique(syntheticOblique)
+ , m_orientation(orientation)
+ , m_textOrientation(textOrientation)
+ , m_size(size)
+ , m_widthVariant(widthVariant)
+#if OS(DARWIN)
+ , m_font(0)
+#endif
+#if PLATFORM(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
+ , m_cgFont(0)
+#elif PLATFORM(CAIRO)
+ , m_scaledFont(0)
+#endif
+ , m_isColorBitmapFont(false)
+#if PLATFORM(WIN)
+ , m_useGDI(false)
+#endif
+ {
+ }
+
+#if OS(DARWIN)
+ FontPlatformData(NSFont*, float size, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = Horizontal,
+ TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth);
+ FontPlatformData(CGFontRef cgFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation,
+ TextOrientation textOrientation, FontWidthVariant widthVariant)
+ : m_syntheticBold(syntheticBold)
+ , m_syntheticOblique(syntheticOblique)
+ , m_orientation(orientation)
+ , m_textOrientation(textOrientation)
+ , m_size(size)
+ , m_widthVariant(widthVariant)
+ , m_font(0)
+ , m_cgFont(cgFont)
+ , m_isColorBitmapFont(false)
+ {
+ }
+#endif
+#if PLATFORM(WIN)
+ FontPlatformData(HFONT, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
+#if PLATFORM(CG)
+ FontPlatformData(HFONT, CGFontRef, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
+#endif
+#endif
+#if PLATFORM(CAIRO)
+ FontPlatformData(cairo_font_face_t*, float size, bool bold, bool italic);
+#endif
+
+ ~FontPlatformData();
+
+#if PLATFORM(WIN)
+ HFONT hfont() const { return m_font ? m_font->handle() : 0; }
+ bool useGDI() const { return m_useGDI; }
+#elif OS(DARWIN)
+ NSFont* font() const { return m_font; }
+ void setFont(NSFont*);
+#endif
+
+#if PLATFORM(CG)
+#if OS(DARWIN)
+#ifndef BUILDING_ON_TIGER
+ CGFontRef cgFont() const { return m_cgFont.get(); }
+#else
+ CGFontRef cgFont() const { return m_cgFont; }
+#endif
+ CTFontRef ctFont() const;
+
+ bool roundsGlyphAdvances() const;
+ bool allowsLigatures() const;
+#else
+ CGFontRef cgFont() const { return m_cgFont.get(); }
+#endif
+#endif
+
+ bool isFixedPitch() const;
+ float size() const { return m_size; }
+ void setSize(float size) { m_size = size; }
+ bool syntheticBold() const { return m_syntheticBold; }
+ bool syntheticOblique() const { return m_syntheticOblique; }
+ bool isColorBitmapFont() const { return m_isColorBitmapFont; }
+ FontOrientation orientation() const { return m_orientation; }
+ TextOrientation textOrientation() const { return m_textOrientation; }
+ FontWidthVariant widthVariant() const { return m_widthVariant; }
+
+ void setOrientation(FontOrientation orientation) { m_orientation = orientation; }
+
+#if PLATFORM(CAIRO)
+ cairo_scaled_font_t* scaledFont() const { return m_scaledFont; }
+#endif
+
+ unsigned hash() const
+ {
+#if PLATFORM(WIN) && !PLATFORM(CAIRO)
+ return m_font ? m_font->hash() : 0;
+#elif OS(DARWIN)
+ ASSERT(m_font || !m_cgFont);
+ uintptr_t hashCodes[3] = { (uintptr_t)m_font, m_widthVariant, m_textOrientation << 3 | m_orientation << 2 | m_syntheticBold << 1 | m_syntheticOblique };
+ return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
+#elif PLATFORM(CAIRO)
+ return PtrHash<cairo_scaled_font_t*>::hash(m_scaledFont);
+#endif
+ }
+
+ const FontPlatformData& operator=(const FontPlatformData&);
+
+ bool operator==(const FontPlatformData& other) const
+ {
+ return platformIsEqual(other)
+ && m_size == other.m_size
+ && m_syntheticBold == other.m_syntheticBold
+ && m_syntheticOblique == other.m_syntheticOblique
+ && m_isColorBitmapFont == other.m_isColorBitmapFont
+ && m_orientation == other.m_orientation
+ && m_textOrientation == other.m_textOrientation
+ && m_widthVariant == other.m_widthVariant;
+ }
+
+ bool isHashTableDeletedValue() const
+ {
+#if PLATFORM(WIN) && !PLATFORM(CAIRO)
+ return m_font.isHashTableDeletedValue();
+#elif OS(DARWIN)
+ return m_font == hashTableDeletedFontValue();
+#elif PLATFORM(CAIRO)
+ return m_scaledFont == hashTableDeletedFontValue();
+#endif
+ }
+
+
+#ifndef NDEBUG
+ String description() const;
+#endif
+
+private:
+ bool platformIsEqual(const FontPlatformData&) const;
+ void platformDataInit(const FontPlatformData&);
+ const FontPlatformData& platformDataAssign(const FontPlatformData&);
+#if OS(DARWIN)
+ // Load various data about the font specified by |nsFont| with the size fontSize into the following output paramters:
+ // Note: Callers should always take into account that for the Chromium port, |outNSFont| isn't necessarily the same
+ // font as |nsFont|. This because the sandbox may block loading of the original font.
+ // * outNSFont - The font that was actually loaded, for the Chromium port this may be different than nsFont.
+ // The caller is responsible for calling CFRelease() on this parameter when done with it.
+ // * cgFont - CGFontRef representing the input font at the specified point size.
+ void loadFont(NSFont*, float fontSize, NSFont*& outNSFont, CGFontRef&);
+ static NSFont* hashTableDeletedFontValue() { return reinterpret_cast<NSFont *>(-1); }
+#elif PLATFORM(WIN)
+ void platformDataInit(HFONT, float size, HDC, WCHAR* faceName);
+#endif
+
+#if PLATFORM(CAIRO)
+ static cairo_scaled_font_t* hashTableDeletedFontValue() { return reinterpret_cast<cairo_scaled_font_t*>(-1); }
+#endif
+
+public:
+ bool m_syntheticBold;
+ bool m_syntheticOblique;
+ FontOrientation m_orientation;
+ TextOrientation m_textOrientation;
+ float m_size;
+ FontWidthVariant m_widthVariant;
+
+private:
+#if OS(DARWIN)
+ NSFont* m_font;
+#elif PLATFORM(WIN)
+ RefPtr<RefCountedGDIHandle<HFONT> > m_font;
+#endif
+
+#if PLATFORM(CG)
+#if PLATFORM(WIN)
+ RetainPtr<CGFontRef> m_cgFont;
+#else
+#ifndef BUILDING_ON_TIGER
+ RetainPtr<CGFontRef> m_cgFont;
+#else
+ CGFontRef m_cgFont; // It is not necessary to refcount this, since either an NSFont owns it or some CachedFont has it referenced.
+#endif
+ mutable RetainPtr<CTFontRef> m_CTFont;
+#endif
+#endif
+
+#if PLATFORM(CAIRO)
+ cairo_scaled_font_t* m_scaledFont;
+#endif
+
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
+ RefPtr<MemoryActivatedFont> m_inMemoryFont;
+#endif
+
+ bool m_isColorBitmapFont;
+
+#if PLATFORM(WIN)
+ bool m_useGDI;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // FontPlatformData_h
+
+#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h
index 5eafa16..c555a5f 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext.h
@@ -42,8 +42,9 @@ typedef struct CGContext PlatformGraphicsContext;
#elif PLATFORM(CAIRO)
namespace WebCore {
class ContextShadow;
+class PlatformContextCairo;
}
-typedef struct _cairo PlatformGraphicsContext;
+typedef WebCore::PlatformContextCairo PlatformGraphicsContext;
#elif PLATFORM(OPENVG)
namespace WebCore {
class SurfaceOpenVG;
@@ -279,6 +280,9 @@ namespace WebCore {
void setIsCALayerContext(bool);
bool isCALayerContext() const;
+
+ void setIsAcceleratedContext(bool);
+ bool isAcceleratedContext() const;
#endif
#if PLATFORM(ANDROID)
@@ -522,6 +526,7 @@ namespace WebCore {
#endif
#if PLATFORM(CAIRO)
+ GraphicsContext(cairo_t*);
void pushImageMask(cairo_surface_t*, const FloatRect&);
#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index a9db650..351b445 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -51,8 +51,8 @@
@class CALayer;
@class WebGLLayer;
#else
-typedef void* CALayer;
-typedef void* WebGLLayer;
+class CALayer;
+class WebGLLayer;
#endif
#elif PLATFORM(QT)
QT_BEGIN_NAMESPACE
@@ -420,6 +420,7 @@ public:
, antialias(true)
, premultipliedAlpha(true)
, canRecoverFromContextLoss(true)
+ , preserveDrawingBuffer(false)
{
}
@@ -429,6 +430,7 @@ public:
bool antialias;
bool premultipliedAlpha;
bool canRecoverFromContextLoss;
+ bool preserveDrawingBuffer;
};
enum RenderStyle {
@@ -449,8 +451,8 @@ public:
#if PLATFORM(MAC)
PlatformGraphicsContext3D platformGraphicsContext3D() const { return m_contextObj; }
- Platform3DObject platformTexture() const { return m_texture; }
- CALayer* platformLayer() const { return static_cast<CALayer*>(m_webGLLayer.get()); }
+ Platform3DObject platformTexture() const { return m_compositorTexture; }
+ CALayer* platformLayer() const { return reinterpret_cast<CALayer*>(m_webGLLayer.get()); }
#elif PLATFORM(CHROMIUM)
PlatformGraphicsContext3D platformGraphicsContext3D() const;
Platform3DObject platformTexture() const;
@@ -461,7 +463,7 @@ public:
PlatformGraphicsContext3D platformGraphicsContext3D();
Platform3DObject platformTexture() const;
#if USE(ACCELERATED_COMPOSITING)
- PlatformLayer* platformLayer() const { return 0; }
+ PlatformLayer* platformLayer() const;
#endif
#else
PlatformGraphicsContext3D platformGraphicsContext3D() const { return NullPlatformGraphicsContext3D; }
@@ -756,10 +758,14 @@ public:
int canvasWidth, int canvasHeight, CGContextRef context);
#endif
+ void markContextChanged();
+ void markLayerComposited();
+ bool layerComposited() const;
+
void paintRenderingResultsToCanvas(CanvasRenderingContext* context);
+ PassRefPtr<ImageData> paintRenderingResultsToImageData();
#if PLATFORM(QT)
- void paint(QPainter* painter, const QRect& rect) const;
bool paintsIntoCanvasBuffer() const { return true; }
#elif PLATFORM(CHROMIUM)
bool paintsIntoCanvasBuffer() const;
@@ -859,6 +865,10 @@ public:
// could not be honored based on the capabilities of the OpenGL
// implementation.
void validateAttributes();
+
+ // Read rendering results into a pixel array with the same format as the
+ // backbuffer.
+ void readRenderingResults(unsigned char* pixels, int pixelsSize);
#endif
int m_currentWidth, m_currentHeight;
@@ -881,12 +891,16 @@ public:
CGLContextObj m_contextObj;
RetainPtr<WebGLLayer> m_webGLLayer;
- GC3Duint m_texture;
+ GC3Duint m_texture, m_compositorTexture;
GC3Duint m_fbo;
GC3Duint m_depthStencilBuffer;
+ bool m_layerComposited;
+ GC3Duint m_internalColorFormat;
- // For tracking which FBO is bound
+ // For tracking which FBO/texture is bound
GC3Duint m_boundFBO;
+ GC3Denum m_activeTexture;
+ GC3Duint m_boundTexture0;
// For multisampling
GC3Duint m_multisampleFBO;
diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.h b/Source/WebCore/platform/graphics/GraphicsLayer.h
index e3a62b6..4f234d4 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayer.h
+++ b/Source/WebCore/platform/graphics/GraphicsLayer.h
@@ -46,12 +46,11 @@
#if PLATFORM(MAC)
#ifdef __OBJC__
-@class WebLayer;
@class CALayer;
-typedef CALayer PlatformLayer;
#else
-typedef void* PlatformLayer;
+class CALayer;
#endif
+typedef CALayer PlatformLayer;
#elif PLATFORM(WIN)
typedef struct _CACFLayer PlatformLayer;
#elif PLATFORM(QT)
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h
index 48878da..860f574 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.h
+++ b/Source/WebCore/platform/graphics/ImageBuffer.h
@@ -132,6 +132,10 @@ namespace WebCore {
ImageBuffer(const IntSize&, ColorSpace colorSpace, RenderingMode renderingMode, bool& success);
};
+#if PLATFORM(CG) || USE(SKIA)
+ String ImageDataToDataURL(const ImageData& input, const String& mimeType, const double* quality);
+#endif
+
} // namespace WebCore
#endif // ImageBuffer_h
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp
index 70576a5..03004b6 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp
@@ -47,6 +47,9 @@
#if PLATFORM(MAC)
#include "MediaPlayerPrivateQTKit.h"
+#if USE(AVFOUNDATION)
+#include "MediaPlayerPrivateAVFoundationObjC.h"
+#endif
#define PlatformMediaEngineClassName MediaPlayerPrivateQTKit
#elif OS(WINCE) && !PLATFORM(QT)
#include "MediaPlayerPrivateWinCE.h"
@@ -82,7 +85,7 @@ public:
virtual void load(const String&) { }
virtual void cancelLoad() { }
-
+
virtual void prepareToPlay() { }
virtual void play() { }
virtual void pause() { }
@@ -189,11 +192,15 @@ static Vector<MediaPlayerFactory*>& installedMediaEngines()
MediaPlayerPrivateGStreamer::registerMediaEngine(addMediaEngine);
#endif
+#if USE(AVFOUNDATION) && PLATFORM(MAC)
+ MediaPlayerPrivateAVFoundationObjC::registerMediaEngine(addMediaEngine);
+#endif
+
#if !PLATFORM(GTK) && !PLATFORM(EFL) && !(PLATFORM(QT) && USE(GSTREAMER))
PlatformMediaEngineClassName::registerMediaEngine(addMediaEngine);
#endif
}
-
+
return installedEngines;
}
@@ -241,7 +248,7 @@ static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, c
if (!codecs.isEmpty())
return 0;
}
-
+
MediaPlayerFactory* engine = 0;
MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
unsigned count = engines.size();
@@ -292,6 +299,7 @@ MediaPlayer::MediaPlayer(MediaPlayerClient* client)
, m_muted(false)
, m_preservesPitch(true)
, m_privateBrowsing(false)
+ , m_shouldPrepareToRender(false)
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
, m_playerProxy(0)
#endif
@@ -351,7 +359,7 @@ void MediaPlayer::loadWithNextMediaEngine(MediaPlayerFactory* current)
engine = nextMediaEngine(current);
else
engine = bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, current);
-
+
// Don't delete and recreate the player unless it comes from a different engine.
if (!engine) {
m_currentMediaEngine = engine;
@@ -368,6 +376,8 @@ void MediaPlayer::loadWithNextMediaEngine(MediaPlayerFactory* current)
m_private->setPrivateBrowsingMode(m_privateBrowsing);
m_private->setPreload(m_preload);
m_private->setPreservesPitch(preservesPitch());
+ if (m_shouldPrepareToRender)
+ m_private->prepareForRendering();
}
if (m_private)
@@ -383,17 +393,18 @@ bool MediaPlayer::hasAvailableVideoFrame() const
{
return m_private->hasAvailableVideoFrame();
}
-
+
void MediaPlayer::prepareForRendering()
{
- return m_private->prepareForRendering();
+ m_shouldPrepareToRender = true;
+ m_private->prepareForRendering();
}
-
+
bool MediaPlayer::canLoadPoster() const
{
return m_private->canLoadPoster();
}
-
+
void MediaPlayer::setPoster(const String& url)
{
m_private->setPoster(url);
@@ -408,7 +419,7 @@ void MediaPlayer::prepareToPlay()
{
m_private->prepareToPlay();
}
-
+
void MediaPlayer::play()
{
m_private->play();
@@ -478,7 +489,7 @@ bool MediaPlayer::inMediaDocument()
{
Frame* frame = m_frameView ? m_frameView->frame() : 0;
Document* document = frame ? frame->document() : 0;
-
+
return document && document->isMediaDocument();
}
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h
index f41af01..5872c88 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.h
+++ b/Source/WebCore/platform/graphics/MediaPlayer.h
@@ -46,8 +46,10 @@
#endif
#ifdef __OBJC__
+@class AVPlayer;
@class QTMovie;
#else
+class AVPlayer;
class QTMovie;
#endif
class QTMovieGWorld;
@@ -71,6 +73,7 @@ struct PlatformMedia {
GStreamerGWorldType,
ChromiumMediaPlayerType,
QtMediaPlayerType,
+ AVFoundationMediaPlayerType,
} type;
union {
@@ -80,6 +83,7 @@ struct PlatformMedia {
GStreamerGWorld* gstreamerGWorld;
MediaPlayerPrivateInterface* chromiumMediaPlayer;
MediaPlayerPrivateInterface* qtMediaPlayer;
+ AVPlayer* avfMediaPlayer;
} media;
};
@@ -115,10 +119,10 @@ public:
// time has jumped, eg. not as a result of normal playback
virtual void mediaPlayerTimeChanged(MediaPlayer*) { }
-
+
// the media file duration has changed, or is now known
virtual void mediaPlayerDurationChanged(MediaPlayer*) { }
-
+
// the playback rate has changed
virtual void mediaPlayerRateChanged(MediaPlayer*) { }
@@ -178,49 +182,53 @@ public:
IntSize naturalSize();
bool hasVideo() const;
bool hasAudio() const;
+<<<<<<< HEAD
#if PLATFORM(ANDROID)
enum MediaElementType { Video, Audio };
void setMediaElementType(MediaElementType type) { m_mediaElementType = type; }
MediaElementType mediaElementType() { return m_mediaElementType; }
#endif
+=======
+
+>>>>>>> webkit.org at r82507
void setFrameView(FrameView* frameView) { m_frameView = frameView; }
FrameView* frameView() { return m_frameView; }
bool inMediaDocument();
-
+
IntSize size() const { return m_size; }
void setSize(const IntSize& size);
-
+
void load(const String& url, const ContentType&);
void cancelLoad();
-
+
bool visible() const;
void setVisible(bool);
-
+
void prepareToPlay();
void play();
void pause();
-
+
bool paused() const;
bool seeking() const;
-
+
float duration() const;
float currentTime() const;
void seek(float time);
float startTime() const;
-
+
float rate() const;
void setRate(float);
bool preservesPitch() const;
void setPreservesPitch(bool);
-
+
PassRefPtr<TimeRanges> buffered();
float maxTimeSeekable();
unsigned bytesLoaded();
-
+
float volume() const;
void setVolume(float);
@@ -235,13 +243,13 @@ public:
void paint(GraphicsContext*, const IntRect&);
void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
-
+
enum NetworkState { Empty, Idle, Loading, Loaded, FormatError, NetworkError, DecodeError };
NetworkState networkState();
enum ReadyState { HaveNothing, HaveMetadata, HaveCurrentData, HaveFutureData, HaveEnoughData };
ReadyState readyState();
-
+
enum MovieLoadType { Unknown, Download, StoredStream, LiveStream };
MovieLoadType movieLoadType() const;
@@ -320,6 +328,7 @@ private:
bool m_muted;
bool m_preservesPitch;
bool m_privateBrowsing;
+ bool m_shouldPrepareToRender;
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
WebMediaPlayerProxy* m_playerProxy; // not owned or used, passed to m_private
#endif
diff --git a/Source/WebCore/platform/graphics/Path.cpp b/Source/WebCore/platform/graphics/Path.cpp
index 55760b1..f7aedbe 100644
--- a/Source/WebCore/platform/graphics/Path.cpp
+++ b/Source/WebCore/platform/graphics/Path.cpp
@@ -83,14 +83,14 @@ static void pathLengthApplierFunction(void* info, const PathElement* element)
}
}
-float Path::length()
+float Path::length() const
{
PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
apply(&traversalState, pathLengthApplierFunction);
return traversalState.m_totalLength;
}
-FloatPoint Path::pointAtLength(float length, bool& ok)
+FloatPoint Path::pointAtLength(float length, bool& ok) const
{
PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength);
traversalState.m_desiredLength = length;
@@ -99,10 +99,10 @@ FloatPoint Path::pointAtLength(float length, bool& ok)
return traversalState.m_current;
}
-float Path::normalAngleAtLength(float length, bool& ok)
+float Path::normalAngleAtLength(float length, bool& ok) const
{
PathTraversalState traversalState(PathTraversalState::TraversalNormalAngleAtLength);
- traversalState.m_desiredLength = length;
+ traversalState.m_desiredLength = length ? length : std::numeric_limits<float>::epsilon();
apply(&traversalState, pathLengthApplierFunction);
ok = traversalState.m_success;
return traversalState.m_normalAngle;
diff --git a/Source/WebCore/platform/graphics/Path.h b/Source/WebCore/platform/graphics/Path.h
index 31f2cd6..c2ca576 100644
--- a/Source/WebCore/platform/graphics/Path.h
+++ b/Source/WebCore/platform/graphics/Path.h
@@ -112,11 +112,11 @@ namespace WebCore {
bool contains(const FloatPoint&, WindRule rule = RULE_NONZERO) const;
bool strokeContains(StrokeStyleApplier*, const FloatPoint&) const;
FloatRect boundingRect() const;
- FloatRect strokeBoundingRect(StrokeStyleApplier* = 0);
+ FloatRect strokeBoundingRect(StrokeStyleApplier* = 0) const;
- float length();
- FloatPoint pointAtLength(float length, bool& ok);
- float normalAngleAtLength(float length, bool& ok);
+ float length() const;
+ FloatPoint pointAtLength(float length, bool& ok) const;
+ float normalAngleAtLength(float length, bool& ok) const;
void clear();
bool isEmpty() const;
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.cpp b/Source/WebCore/platform/graphics/SimpleFontData.cpp
index aaab666..82f770d 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/Source/WebCore/platform/graphics/SimpleFontData.cpp
@@ -47,15 +47,16 @@ using namespace std;
namespace WebCore {
-SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCustomFont, bool isLoading)
+SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCustomFont, bool isLoading, bool isTextOrientationFallback)
: m_maxCharWidth(-1)
, m_avgCharWidth(-1)
- , m_orientation(platformData.orientation())
, m_platformData(platformData)
, m_treatAsFixedPitch(false)
, m_isCustomFont(isCustomFont)
, m_isLoading(isLoading)
- , m_isBrokenIdeographFont(false)
+ , m_isTextOrientationFallback(isTextOrientationFallback)
+ , m_isBrokenIdeographFallback(false)
+ , m_hasVerticalGlyphs(false)
{
platformInit();
platformGlyphInit();
@@ -64,13 +65,14 @@ SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCust
#if ENABLE(SVG_FONTS)
SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bool syntheticBold, bool syntheticItalic)
- : m_orientation(Horizontal)
- , m_platformData(FontPlatformData(size, syntheticBold, syntheticItalic))
+ : m_platformData(FontPlatformData(size, syntheticBold, syntheticItalic))
, m_treatAsFixedPitch(false)
, m_svgFontData(svgFontData)
, m_isCustomFont(true)
, m_isLoading(false)
- , m_isBrokenIdeographFont(false)
+ , m_isTextOrientationFallback(false)
+ , m_isBrokenIdeographFallback(false)
+ , m_hasVerticalGlyphs(false)
{
SVGFontFaceElement* svgFontFaceElement = m_svgFontData->svgFontFaceElement();
unsigned unitsPerEm = svgFontFaceElement->unitsPerEm();
@@ -202,14 +204,34 @@ bool SimpleFontData::isSegmented() const
return false;
}
+SimpleFontData* SimpleFontData::verticalRightOrientationFontData() const
+{
+ if (!m_derivedFontData)
+ m_derivedFontData = DerivedFontData::create(isCustomFont());
+ if (!m_derivedFontData->verticalRightOrientation) {
+ FontPlatformData verticalRightPlatformData(m_platformData);
+ verticalRightPlatformData.setOrientation(Horizontal);
+ m_derivedFontData->verticalRightOrientation = new SimpleFontData(verticalRightPlatformData, isCustomFont(), false, true);
+ }
+ return m_derivedFontData->verticalRightOrientation.get();
+}
+
+SimpleFontData* SimpleFontData::uprightOrientationFontData() const
+{
+ if (!m_derivedFontData)
+ m_derivedFontData = DerivedFontData::create(isCustomFont());
+ if (!m_derivedFontData->uprightOrientation)
+ m_derivedFontData->uprightOrientation = new SimpleFontData(m_platformData, isCustomFont(), false, true);
+ return m_derivedFontData->uprightOrientation.get();
+}
+
SimpleFontData* SimpleFontData::brokenIdeographFontData() const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->brokenIdeograph) {
m_derivedFontData->brokenIdeograph = new SimpleFontData(m_platformData, isCustomFont(), false);
- m_derivedFontData->brokenIdeograph->m_orientation = Vertical;
- m_derivedFontData->brokenIdeograph->m_isBrokenIdeographFont = true;
+ m_derivedFontData->brokenIdeograph->m_isBrokenIdeographFallback = true;
}
return m_derivedFontData->brokenIdeograph.get();
}
@@ -242,6 +264,10 @@ SimpleFontData::DerivedFontData::~DerivedFontData()
GlyphPageTreeNode::pruneTreeCustomFontData(emphasisMark.get());
if (brokenIdeograph)
GlyphPageTreeNode::pruneTreeCustomFontData(brokenIdeograph.get());
+ if (verticalRightOrientation)
+ GlyphPageTreeNode::pruneTreeCustomFontData(verticalRightOrientation.get());
+ if (uprightOrientation)
+ GlyphPageTreeNode::pruneTreeCustomFontData(uprightOrientation.get());
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h
index 93d33bb..dfb4be3 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.h
+++ b/Source/WebCore/platform/graphics/SimpleFontData.h
@@ -71,7 +71,7 @@ enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
class SimpleFontData : public FontData {
public:
- SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false);
+ SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
#if ENABLE(SVG_FONTS)
SimpleFontData(PassOwnPtr<SVGFontData>, int size, bool syntheticBold, bool syntheticItalic);
#endif
@@ -97,11 +97,13 @@ public:
return const_cast<SimpleFontData*>(this);
}
+ SimpleFontData* verticalRightOrientationFontData() const;
+ SimpleFontData* uprightOrientationFontData() const;
SimpleFontData* brokenIdeographFontData() const;
-
- // FIXME: Use the actual metrics for fonts with vertical tables instead of just hard-coding. If the font is horizontally oriented or
- // a broken ideographic font, then just hard-code to split ascent/descent down the middle. Otherwise we should actually use the metrics
- // from the font itself.
+
+ bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
+ bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
+
const FontMetrics& fontMetrics() const { return m_fontMetrics; }
float maxCharWidth() const { return m_maxCharWidth; }
float avgCharWidth() const { return m_avgCharWidth; }
@@ -137,8 +139,6 @@ public:
virtual bool isLoading() const { return m_isLoading; }
virtual bool isSegmented() const;
- bool isBrokenIdeographFont() const { return m_isBrokenIdeographFont; }
-
const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
#ifndef NDEBUG
@@ -152,7 +152,7 @@ public:
#endif
#if PLATFORM(MAC) || USE(CORE_TEXT)
- CFDictionaryRef getCFStringAttributes(TypesettingFeatures) const;
+ CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const;
#endif
#if USE(ATSUI)
@@ -183,8 +183,6 @@ public:
wxFont* getWxFont() const { return m_platformData.font(); }
#endif
- FontOrientation orientation() const { return m_orientation; }
-
private:
void platformInit();
void platformGlyphInit();
@@ -209,9 +207,6 @@ private:
float m_maxCharWidth;
float m_avgCharWidth;
- FontOrientation m_orientation; // This is our supported orientation according to the tables in the font. FontPlatformData will just always have the desired orientation.
- // This value represents what we actually support.
-
FontPlatformData m_platformData;
mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap;
@@ -225,8 +220,11 @@ private:
bool m_isCustomFont; // Whether or not we are custom font loaded via @font-face
bool m_isLoading; // Whether or not this custom font is still in the act of loading.
- bool m_isBrokenIdeographFont;
-
+
+ bool m_isTextOrientationFallback;
+ bool m_isBrokenIdeographFallback;
+ bool m_hasVerticalGlyphs;
+
Glyph m_spaceGlyph;
float m_spaceWidth;
@@ -242,6 +240,8 @@ private:
OwnPtr<SimpleFontData> smallCaps;
OwnPtr<SimpleFontData> emphasisMark;
OwnPtr<SimpleFontData> brokenIdeograph;
+ OwnPtr<SimpleFontData> verticalRightOrientation;
+ OwnPtr<SimpleFontData> uprightOrientation;
private:
DerivedFontData(bool custom)
diff --git a/Source/WebCore/platform/graphics/TextRun.h b/Source/WebCore/platform/graphics/TextRun.h
index 4e0980b..ec763b9 100644
--- a/Source/WebCore/platform/graphics/TextRun.h
+++ b/Source/WebCore/platform/graphics/TextRun.h
@@ -33,17 +33,21 @@ class RenderSVGResource;
class TextRun {
public:
- enum TrailingExpansionBehavior {
- AllowTrailingExpansion,
- ForbidTrailingExpansion
+ enum ExpansionBehaviorFlags {
+ ForbidTrailingExpansion = 0 << 0,
+ AllowTrailingExpansion = 1 << 0,
+ ForbidLeadingExpansion = 0 << 1,
+ AllowLeadingExpansion = 1 << 1,
};
- TextRun(const UChar* c, int len, bool allowTabs = false, float xpos = 0, float expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false)
+ typedef unsigned ExpansionBehavior;
+
+ TextRun(const UChar* c, int len, bool allowTabs = false, float xpos = 0, float expansion = 0, ExpansionBehavior expansionBehavior = AllowTrailingExpansion | ForbidLeadingExpansion, bool rtl = false, bool directionalOverride = false)
: m_characters(c)
, m_len(len)
, m_xpos(xpos)
, m_expansion(expansion)
- , m_trailingExpansionBehavior(trailingExpansionBehavior)
+ , m_expansionBehavior(expansionBehavior)
#if ENABLE(SVG)
, m_horizontalGlyphStretch(1)
#endif
@@ -58,12 +62,12 @@ public:
{
}
- TextRun(const String& s, bool allowTabs = false, float xpos = 0, float expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false)
+ TextRun(const String& s, bool allowTabs = false, float xpos = 0, float expansion = 0, ExpansionBehavior expansionBehavior = AllowTrailingExpansion | ForbidLeadingExpansion, bool rtl = false, bool directionalOverride = false)
: m_characters(s.characters())
, m_len(s.length())
, m_xpos(xpos)
, m_expansion(expansion)
- , m_trailingExpansionBehavior(trailingExpansionBehavior)
+ , m_expansionBehavior(expansionBehavior)
#if ENABLE(SVG)
, m_horizontalGlyphStretch(1)
#endif
@@ -94,7 +98,8 @@ public:
bool allowTabs() const { return m_allowTabs; }
float xPos() const { return m_xpos; }
float expansion() const { return m_expansion; }
- bool allowsTrailingExpansion() const { return m_trailingExpansionBehavior == AllowTrailingExpansion; }
+ bool allowsLeadingExpansion() const { return m_expansionBehavior & AllowLeadingExpansion; }
+ bool allowsTrailingExpansion() const { return m_expansionBehavior & AllowTrailingExpansion; }
bool rtl() const { return m_rtl; }
bool ltr() const { return !m_rtl; }
bool directionalOverride() const { return m_directionalOverride; }
@@ -121,7 +126,7 @@ private:
// the text line is not the same as left start of the containing block.
float m_xpos;
float m_expansion;
- TrailingExpansionBehavior m_trailingExpansionBehavior;
+ ExpansionBehavior m_expansionBehavior;
#if ENABLE(SVG)
float m_horizontalGlyphStretch;
#endif
diff --git a/Source/WebCore/platform/graphics/Tile.h b/Source/WebCore/platform/graphics/Tile.h
index c623ec9..02076d2 100644
--- a/Source/WebCore/platform/graphics/Tile.h
+++ b/Source/WebCore/platform/graphics/Tile.h
@@ -49,7 +49,7 @@ public:
bool isDirty() const;
void invalidate(const IntRect&);
- void updateBackBuffer();
+ Vector<IntRect> updateBackBuffer();
void swapBackBufferToFront();
bool isReadyToPaint() const;
void paint(GraphicsContext*, const IntRect&);
diff --git a/Source/WebCore/platform/graphics/TiledBackingStore.cpp b/Source/WebCore/platform/graphics/TiledBackingStore.cpp
index 4d69334..ac7e9c6 100644
--- a/Source/WebCore/platform/graphics/TiledBackingStore.cpp
+++ b/Source/WebCore/platform/graphics/TiledBackingStore.cpp
@@ -102,8 +102,6 @@ void TiledBackingStore::updateTileBuffers()
if (!it->second->isDirty())
continue;
dirtyTiles.append(it->second);
- // FIXME: should not request system repaint for the full tile.
- paintedArea.append(mapToContents(it->second->rect()));
}
if (dirtyTiles.isEmpty()) {
@@ -115,11 +113,11 @@ void TiledBackingStore::updateTileBuffers()
// one by one and then swapped to front in one go. This would minimize the time spent
// blocking on tile updates.
unsigned size = dirtyTiles.size();
- for (unsigned n = 0; n < size; ++n)
- dirtyTiles[n]->updateBackBuffer();
-
- for (unsigned n = 0; n < size; ++n)
+ for (unsigned n = 0; n < size; ++n) {
+ Vector<IntRect> paintedRects = dirtyTiles[n]->updateBackBuffer();
+ paintedArea.append(paintedRects);
dirtyTiles[n]->swapBackBufferToFront();
+ }
m_client->tiledBackingStorePaintEnd(paintedArea);
}
diff --git a/Source/WebCore/platform/graphics/WOFFFileFormat.cpp b/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
index b1400ba..80a6dcb 100644
--- a/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
+++ b/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
@@ -248,7 +248,7 @@ bool convertWOFFToSfnt(SharedBuffer* woff, Vector<char>& sfnt)
return sfnt.size() == totalSfntSize;
}
+
+} // namespace WebCore
#endif // !ENABLE(OPENTYPE_SANITIZER)
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp
index 27b0627..750a4ac 100644
--- a/Source/WebCore/platform/graphics/WidthIterator.cpp
+++ b/Source/WebCore/platform/graphics/WidthIterator.cpp
@@ -47,7 +47,7 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const
, m_end(run.length())
, m_currentCharacter(0)
, m_runWidthSoFar(0)
- , m_isAfterExpansion(true)
+ , m_isAfterExpansion(!run.allowsLeadingExpansion())
, m_fallbackFonts(fallbackFonts)
, m_accountForGlyphBounds(accountForGlyphBounds)
, m_maxGlyphBoundingBoxY(numeric_limits<float>::min())
@@ -62,7 +62,7 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const
if (!m_expansion)
m_expansionPerOpportunity = 0;
else {
- bool isAfterExpansion = true;
+ bool isAfterExpansion = m_isAfterExpansion;
unsigned expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters(), m_end, m_run.ltr() ? LTR : RTL, isAfterExpansion);
if (isAfterExpansion && !m_run.allowsTrailingExpansion())
expansionOpportunityCount--;
@@ -164,18 +164,24 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
bool treatAsSpace = Font::treatAsSpace(c);
if (treatAsSpace || (expandAroundIdeographs && Font::isCJKIdeographOrSymbol(c))) {
// Distribute the run's total expansion evenly over all expansion opportunities in the run.
- if (m_expansion && (m_run.allowsTrailingExpansion() || (m_run.ltr() && currentCharacter + clusterLength < static_cast<size_t>(m_run.length()))
- || (m_run.rtl() && currentCharacter))) {
+ if (m_expansion) {
if (!treatAsSpace && !m_isAfterExpansion) {
// Take the expansion opportunity before this ideograph.
m_expansion -= m_expansionPerOpportunity;
m_runWidthSoFar += m_expansionPerOpportunity;
- if (glyphBuffer)
- glyphBuffer->expandLastAdvance(m_expansionPerOpportunity);
+ if (glyphBuffer) {
+ if (glyphBuffer->isEmpty())
+ glyphBuffer->add(fontData->spaceGlyph(), fontData, m_expansionPerOpportunity);
+ else
+ glyphBuffer->expandLastAdvance(m_expansionPerOpportunity);
+ }
+ }
+ if (m_run.allowsTrailingExpansion() || (m_run.ltr() && currentCharacter + clusterLength < static_cast<size_t>(m_run.length()))
+ || (m_run.rtl() && currentCharacter)) {
+ m_expansion -= m_expansionPerOpportunity;
+ width += m_expansionPerOpportunity;
+ m_isAfterExpansion = true;
}
- m_expansion -= m_expansionPerOpportunity;
- width += m_expansionPerOpportunity;
- m_isAfterExpansion = true;
} else
m_isAfterExpansion = false;
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
new file mode 100644
index 0000000..eb96532
--- /dev/null
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
@@ -0,0 +1,731 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+
+#include "MediaPlayerPrivateAVFoundation.h"
+
+#include "ApplicationCacheHost.h"
+#include "DocumentLoader.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
+#include "KURL.h"
+#include "Logging.h"
+#include "SoftLinking.h"
+#include "TimeRanges.h"
+#include <CoreMedia/CoreMedia.h>
+#include <wtf/UnusedParam.h>
+
+using namespace std;
+
+namespace WebCore {
+
+static const float invalidTime = -1.0f;
+
+MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation(MediaPlayer* player)
+ : m_player(player)
+ , m_queuedNotifications()
+ , m_queueMutex()
+ , m_mainThreadCallPending(false)
+ , m_networkState(MediaPlayer::Empty)
+ , m_readyState(MediaPlayer::HaveNothing)
+ , m_preload(MediaPlayer::Auto)
+ , m_scaleFactor(1, 1)
+ , m_cachedMaxTimeLoaded(0)
+ , m_cachedMaxTimeSeekable(0)
+ , m_cachedDuration(invalidTime)
+ , m_reportedDuration(invalidTime)
+ , m_seekTo(invalidTime)
+ , m_requestedRate(1)
+ , m_delayCallbacks(false)
+ , m_havePreparedToPlay(false)
+ , m_assetIsPlayable(false)
+ , m_visible(false)
+ , m_videoFrameHasDrawn(false)
+ , m_loadingMetadata(false)
+ , m_delayingLoad(false)
+ , m_isAllowedToRender(false)
+ , m_cachedHasAudio(false)
+ , m_cachedHasVideo(false)
+ , m_cachedHasCaptions(false)
+ , m_ignoreLoadStateChanges(false)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation(%p)", this);
+}
+
+MediaPlayerPrivateAVFoundation::~MediaPlayerPrivateAVFoundation()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::~MediaPlayerPrivateAVFoundation(%p)", this);
+ cancelCallOnMainThread(mainThreadCallback, this);
+}
+
+MediaPlayerPrivateAVFoundation::MediaRenderingMode MediaPlayerPrivateAVFoundation::currentRenderingMode() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (platformLayer())
+ return MediaRenderingToLayer;
+#endif
+
+ if (hasContextRenderer())
+ return MediaRenderingToContext;
+
+ return MediaRenderingNone;
+}
+
+MediaPlayerPrivateAVFoundation::MediaRenderingMode MediaPlayerPrivateAVFoundation::preferredRenderingMode() const
+{
+ if (!m_player->visible() || !m_player->frameView() || assetStatus() == MediaPlayerAVAssetStatusUnknown)
+ return MediaRenderingNone;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player))
+ return MediaRenderingToLayer;
+#endif
+
+ return MediaRenderingToContext;
+}
+
+void MediaPlayerPrivateAVFoundation::setUpVideoRendering()
+{
+ if (!isReadyForVideoSetup())
+ return;
+
+ MediaRenderingMode currentMode = currentRenderingMode();
+ MediaRenderingMode preferredMode = preferredRenderingMode();
+ if (currentMode == preferredMode && currentMode != MediaRenderingNone)
+ return;
+
+ LOG(Media, "MediaPlayerPrivateAVFoundation::setUpVideoRendering(%p) - current mode = %d, preferred mode = %d",
+ this, static_cast<int>(currentMode), static_cast<int>(preferredMode));
+
+ if (currentMode != MediaRenderingNone)
+ tearDownVideoRendering();
+
+ switch (preferredMode) {
+ case MediaRenderingNone:
+ case MediaRenderingToContext:
+ createContextVideoRenderer();
+ break;
+
+#if USE(ACCELERATED_COMPOSITING)
+ case MediaRenderingToLayer:
+ createVideoLayer();
+ break;
+#endif
+ }
+
+#if USE(ACCELERATED_COMPOSITING)
+ // If using a movie layer, inform the client so the compositing tree is updated.
+ if (currentMode == MediaRenderingToLayer || preferredMode == MediaRenderingToLayer) {
+ LOG(Media, "MediaPlayerPrivateAVFoundation::setUpVideoRendering(%p) - calling mediaPlayerRenderingModeChanged()", this);
+ m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
+ }
+#endif
+}
+
+void MediaPlayerPrivateAVFoundation::tearDownVideoRendering()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::tearDownVideoRendering(%p)", this);
+
+ destroyContextVideoRenderer();
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (platformLayer())
+ destroyVideoLayer();
+#endif
+}
+
+bool MediaPlayerPrivateAVFoundation::hasSetUpVideoRendering() const
+{
+ return hasLayerRenderer() || hasContextRenderer();
+}
+
+void MediaPlayerPrivateAVFoundation::resumeLoad()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::resumeLoad(%p)", this);
+
+ ASSERT(m_delayingLoad);
+ m_delayingLoad = false;
+
+ if (m_assetURL.length())
+ prepareToPlay();
+}
+
+void MediaPlayerPrivateAVFoundation::load(const String& url)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::load(%p)", this);
+
+ if (m_networkState != MediaPlayer::Loading) {
+ m_networkState = MediaPlayer::Loading;
+ m_player->networkStateChanged();
+ }
+ if (m_readyState != MediaPlayer::HaveNothing) {
+ m_readyState = MediaPlayer::HaveNothing;
+ m_player->readyStateChanged();
+ }
+
+ m_videoFrameHasDrawn = false;
+ m_assetURL = url;
+
+ // Don't do any more work if the url is empty.
+ if (!url.length())
+ return;
+
+ if (m_preload == MediaPlayer::None) {
+ LOG(Media, "MediaPlayerPrivateAVFoundation::load(%p) - preload==none so returning", this);
+ m_delayingLoad = true;
+ return;
+ }
+
+ prepareToPlay();
+}
+
+void MediaPlayerPrivateAVFoundation::playabilityKnown()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::playabilityKnown(%p)", this);
+
+ updateStates();
+ if (m_assetIsPlayable)
+ return;
+
+ // Nothing more to do if we already have all of the item's metadata.
+ if (assetStatus() > MediaPlayerAVAssetStatusLoading) {
+ LOG(Media, "MediaPlayerPrivateAVFoundation::playabilityKnown(%p) - all metadata loaded", this);
+ return;
+ }
+
+ // At this point we are supposed to load metadata. It is OK to ask the asset to load the same
+ // information multiple times, because if it has already been loaded the completion handler
+ // will just be called synchronously.
+ m_loadingMetadata = true;
+ beginLoadingMetadata();
+}
+
+void MediaPlayerPrivateAVFoundation::prepareToPlay()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::prepareToPlay(%p)", this);
+
+ m_preload = MediaPlayer::Auto;
+ if (m_havePreparedToPlay)
+ return;
+ m_havePreparedToPlay = true;
+
+ m_delayingLoad = false;
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : 0;
+ ApplicationCacheHost* cacheHost = frame ? frame->loader()->documentLoader()->applicationCacheHost() : 0;
+ ApplicationCacheResource* resource = 0;
+ if (cacheHost && cacheHost->shouldLoadResourceFromApplicationCache(ResourceRequest(m_assetURL), resource) && resource)
+ createAVPlayerForCacheResource(resource);
+ else
+#endif
+ createAVPlayerForURL(m_assetURL);
+ checkPlayability();
+}
+
+void MediaPlayerPrivateAVFoundation::paint(GraphicsContext*, const IntRect&)
+{
+ // This is the base class, only need to remember that a frame has been drawn.
+ m_videoFrameHasDrawn = true;
+}
+
+float MediaPlayerPrivateAVFoundation::duration() const
+{
+ if (!metaDataAvailable())
+ return 0;
+
+ if (m_cachedDuration == invalidTime) {
+ m_cachedDuration = platformDuration();
+ LOG(Media, "MediaPlayerPrivateAVFMac::duration(%p) - caching %f", this, m_cachedDuration);
+ }
+
+ return m_cachedDuration;
+}
+
+void MediaPlayerPrivateAVFoundation::seek(float time)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::seek(%p) - seeking to %f", this, time);
+ if (!metaDataAvailable())
+ return;
+
+ if (time > duration())
+ time = duration();
+
+ m_seekTo = time;
+
+ seekToTime(time);
+}
+
+void MediaPlayerPrivateAVFoundation::setRate(float rate)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::setRate(%p) - seting to %f", this, rate);
+ m_requestedRate = rate;
+}
+
+bool MediaPlayerPrivateAVFoundation::paused() const
+{
+ if (!metaDataAvailable())
+ return true;
+
+ return rate() == 0;
+}
+
+bool MediaPlayerPrivateAVFoundation::seeking() const
+{
+ if (!metaDataAvailable())
+ return false;
+
+ return m_seekTo != invalidTime;
+}
+
+IntSize MediaPlayerPrivateAVFoundation::naturalSize() const
+{
+ if (!metaDataAvailable())
+ return IntSize();
+
+ // In spite of the name of this method, return the natural size transformed by the
+ // initial movie scale because the spec says intrinsic size is:
+ //
+ // ... the dimensions of the resource in CSS pixels after taking into account the resource's
+ // dimensions, aspect ratio, clean aperture, resolution, and so forth, as defined for the
+ // format used by the resource
+
+ return m_cachedNaturalSize;
+}
+
+void MediaPlayerPrivateAVFoundation::setNaturalSize(IntSize size)
+{
+ IntSize oldSize = m_cachedNaturalSize;
+ m_cachedNaturalSize = size;
+ if (oldSize != m_cachedNaturalSize)
+ m_player->sizeChanged();
+}
+
+PassRefPtr<TimeRanges> MediaPlayerPrivateAVFoundation::buffered() const
+{
+ if (!m_cachedLoadedTimeRanges)
+ m_cachedLoadedTimeRanges = platformBufferedTimeRanges();
+
+ return m_cachedLoadedTimeRanges->copy();
+}
+
+float MediaPlayerPrivateAVFoundation::maxTimeSeekable() const
+{
+ if (!metaDataAvailable())
+ return 0;
+
+ if (!m_cachedMaxTimeSeekable)
+ m_cachedMaxTimeSeekable = platformMaxTimeSeekable();
+
+ LOG(Media, "MediaPlayerPrivateAVFoundation::maxTimeSeekable(%p) - returning %f", this, m_cachedMaxTimeSeekable);
+ return m_cachedMaxTimeSeekable;
+}
+
+float MediaPlayerPrivateAVFoundation::maxTimeLoaded() const
+{
+ if (!metaDataAvailable())
+ return 0;
+
+ if (!m_cachedMaxTimeLoaded)
+ m_cachedMaxTimeLoaded = platformMaxTimeLoaded();
+
+ return m_cachedMaxTimeLoaded;
+}
+
+unsigned MediaPlayerPrivateAVFoundation::bytesLoaded() const
+{
+ float dur = duration();
+ if (!dur)
+ return 0;
+ unsigned loaded = totalBytes() * maxTimeLoaded() / dur;
+ LOG(Media, "MediaPlayerPrivateAVFoundation::bytesLoaded(%p) - returning %i", this, loaded);
+ return loaded;
+}
+
+bool MediaPlayerPrivateAVFoundation::isReadyForVideoSetup() const
+{
+ return m_isAllowedToRender && m_readyState >= MediaPlayer::HaveMetadata && m_player->visible();
+}
+
+void MediaPlayerPrivateAVFoundation::prepareForRendering()
+{
+ if (m_isAllowedToRender)
+ return;
+ m_isAllowedToRender = true;
+
+ setUpVideoRendering();
+
+ if (currentRenderingMode() == MediaRenderingToLayer || preferredRenderingMode() == MediaRenderingToLayer)
+ m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
+}
+
+bool MediaPlayerPrivateAVFoundation::supportsFullscreen() const
+{
+#if ENABLE(FULLSCREEN_API)
+ return true;
+#else
+ // FIXME: WebVideoFullscreenController assumes a QTKit/QuickTime media engine
+ return false;
+#endif
+}
+
+void MediaPlayerPrivateAVFoundation::updateStates()
+{
+ MediaPlayer::NetworkState oldNetworkState = m_networkState;
+ MediaPlayer::ReadyState oldReadyState = m_readyState;
+
+ LOG(Media, "MediaPlayerPrivateAVFoundation::updateStates(%p) - entering with networkState = %i, readyState = %i",
+ this, static_cast<int>(m_networkState), static_cast<int>(m_readyState));
+
+ if (m_loadingMetadata)
+ m_networkState = MediaPlayer::Loading;
+ else {
+ // -loadValuesAsynchronouslyForKeys:completionHandler: has invoked its handler; test status of keys and determine state.
+ AVAssetStatus avAssetStatus = assetStatus();
+ ItemStatus itemStatus = playerItemStatus();
+
+ m_assetIsPlayable = (avAssetStatus == MediaPlayerAVAssetStatusPlayable);
+ if (m_readyState < MediaPlayer::HaveMetadata && avAssetStatus > MediaPlayerAVAssetStatusLoading) {
+ if (m_assetIsPlayable) {
+ if (itemStatus == MediaPlayerAVPlayerItemStatusUnknown) {
+ if (avAssetStatus == MediaPlayerAVAssetStatusFailed || m_preload > MediaPlayer::MetaData) {
+ // We may have a playable asset that doesn't support inspection prior to playback; go ahead
+ // and create the AVPlayerItem now. When the AVPlayerItem becomes ready to play, we will
+ // have access to its metadata. Or we may have been asked to become ready to play immediately.
+ m_networkState = MediaPlayer::Loading;
+ prepareToPlay();
+ } else
+ m_networkState = MediaPlayer::Idle;
+ }
+ if (avAssetStatus == MediaPlayerAVAssetStatusLoaded)
+ m_readyState = MediaPlayer::HaveMetadata;
+ } else {
+ // FIX ME: fetch the error associated with the @"playable" key to distinguish between format
+ // and network errors.
+ m_networkState = MediaPlayer::FormatError;
+ }
+ }
+
+ if (avAssetStatus >= MediaPlayerAVAssetStatusLoaded && itemStatus > MediaPlayerAVPlayerItemStatusUnknown) {
+ if (seeking())
+ m_readyState = m_readyState >= MediaPlayer::HaveMetadata ? MediaPlayer::HaveMetadata : MediaPlayer::HaveNothing;
+ else {
+ float maxLoaded = maxTimeLoaded();
+ switch (itemStatus) {
+ case MediaPlayerAVPlayerItemStatusUnknown:
+ break;
+ case MediaPlayerAVPlayerItemStatusFailed:
+ m_networkState = MediaPlayer::DecodeError;
+ break;
+ case MediaPlayerAVPlayerItemStatusPlaybackLikelyToKeepUp:
+ m_readyState = MediaPlayer::HaveEnoughData;
+ break;
+ case MediaPlayerAVPlayerItemStatusReadyToPlay:
+ case MediaPlayerAVPlayerItemStatusPlaybackBufferEmpty:
+ case MediaPlayerAVPlayerItemStatusPlaybackBufferFull:
+ if (maxLoaded > currentTime())
+ m_readyState = MediaPlayer::HaveFutureData;
+ else
+ m_readyState = MediaPlayer::HaveCurrentData;
+ break;
+ }
+
+ if (itemStatus >= MediaPlayerAVPlayerItemStatusReadyToPlay)
+ m_networkState = (maxLoaded == duration()) ? MediaPlayer::Loaded : MediaPlayer::Loading;
+ }
+ }
+ }
+
+ if (isReadyForVideoSetup() && currentRenderingMode() != preferredRenderingMode())
+ setUpVideoRendering();
+
+ if (m_networkState != oldNetworkState)
+ m_player->networkStateChanged();
+
+ if (m_readyState != oldReadyState)
+ m_player->readyStateChanged();
+
+ LOG(Media, "MediaPlayerPrivateAVFoundation::updateStates(%p) - exiting with networkState = %i, readyState = %i",
+ this, static_cast<int>(m_networkState), static_cast<int>(m_readyState));
+}
+
+void MediaPlayerPrivateAVFoundation::setSize(const IntSize&)
+{
+}
+
+void MediaPlayerPrivateAVFoundation::setVisible(bool visible)
+{
+ if (m_visible == visible)
+ return;
+
+ m_visible = visible;
+ if (visible)
+ setUpVideoRendering();
+ else
+ tearDownVideoRendering();
+}
+
+bool MediaPlayerPrivateAVFoundation::hasAvailableVideoFrame() const
+{
+ if (currentRenderingMode() == MediaRenderingToLayer)
+ return videoLayerIsReadyToDisplay();
+
+ // When using the software renderer we hope someone will signal that a frame is available so we might as well
+ // wait until we know that a frame has been drawn.
+ return m_videoFrameHasDrawn;
+}
+
+void MediaPlayerPrivateAVFoundation::acceleratedRenderingStateChanged()
+{
+ // Set up or change the rendering path if necessary.
+ setUpVideoRendering();
+}
+
+void MediaPlayerPrivateAVFoundation::metadataLoaded()
+{
+ m_loadingMetadata = false;
+ updateStates();
+}
+
+void MediaPlayerPrivateAVFoundation::loadStateChanged()
+{
+ if (m_ignoreLoadStateChanges)
+ return;
+ updateStates();
+}
+
+void MediaPlayerPrivateAVFoundation::rateChanged()
+{
+ updateStates();
+ m_player->rateChanged();
+}
+
+void MediaPlayerPrivateAVFoundation::loadedTimeRangesChanged()
+{
+ m_cachedLoadedTimeRanges = 0;
+ m_cachedMaxTimeLoaded = 0;
+ updateStates();
+
+ // For some media files, reported duration is estimated and updated as media is loaded
+ // so report duration changed when the estimate is upated.
+ float dur = duration();
+ if (dur != m_reportedDuration) {
+ if (m_reportedDuration != invalidTime)
+ m_player->durationChanged();
+ m_reportedDuration = dur;
+ }
+}
+
+void MediaPlayerPrivateAVFoundation::seekableTimeRangesChanged()
+{
+ m_cachedMaxTimeSeekable = 0;
+}
+
+void MediaPlayerPrivateAVFoundation::timeChanged(double time)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::timeChanged(%p) - time = %f", this, time);
+
+ if (m_seekTo == invalidTime)
+ return;
+
+ // AVFoundation may call our observer more than once during a seek, and we can't currently tell
+ // if we will be able to seek to an exact time, so assume that we are done seeking if we are
+ // "close enough" to the seek time.
+ const double smallSeekDelta = 1.0 / 100;
+
+ float currentRate = rate();
+ if ((currentRate > 0 && time >= m_seekTo) || (currentRate < 0 && time <= m_seekTo) || (abs(m_seekTo - time) <= smallSeekDelta)) {
+ m_seekTo = invalidTime;
+ updateStates();
+ m_player->timeChanged();
+ }
+}
+
+void MediaPlayerPrivateAVFoundation::didEnd()
+{
+ // Hang onto the current time and use it as duration from now on since we are definitely at
+ // the end of the movie. Do this because the initial duration is sometimes an estimate.
+ float now = currentTime();
+ if (now > 0)
+ m_cachedDuration = now;
+
+ updateStates();
+ m_player->timeChanged();
+}
+
+void MediaPlayerPrivateAVFoundation::repaint()
+{
+ m_videoFrameHasDrawn = true;
+ m_player->repaint();
+}
+
+MediaPlayer::MovieLoadType MediaPlayerPrivateAVFoundation::movieLoadType() const
+{
+ if (!metaDataAvailable() || assetStatus() == MediaPlayerAVAssetStatusUnknown)
+ return MediaPlayer::Unknown;
+
+ if (isinf(duration()))
+ return MediaPlayer::LiveStream;
+
+ return MediaPlayer::Download;
+}
+
+void MediaPlayerPrivateAVFoundation::setPreload(MediaPlayer::Preload preload)
+{
+ m_preload = preload;
+ if (m_delayingLoad && m_preload != MediaPlayer::None)
+ resumeLoad();
+}
+
+void MediaPlayerPrivateAVFoundation::setDelayCallbacks(bool delay)
+{
+ MutexLocker lock(m_queueMutex);
+ if (delay)
+ ++m_delayCallbacks;
+ else {
+ ASSERT(m_delayCallbacks);
+ --m_delayCallbacks;
+ }
+}
+
+void MediaPlayerPrivateAVFoundation::mainThreadCallback(void* context)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::mainThreadCallback(%p)", context);
+ MediaPlayerPrivateAVFoundation* player = static_cast<MediaPlayerPrivateAVFoundation*>(context);
+ player->clearMainThreadPendingFlag();
+ player->dispatchNotification();
+}
+
+void MediaPlayerPrivateAVFoundation::clearMainThreadPendingFlag()
+{
+ MutexLocker lock(m_queueMutex);
+ m_mainThreadCallPending = false;
+}
+
+void MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(Notification::Type type, double time)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(%p) - notification %d", this, static_cast<int>(type));
+ m_queueMutex.lock();
+
+ // It is important to always process the properties in the order that we are notified,
+ // so always go through the queue because notifications happen on different threads.
+ m_queuedNotifications.append(Notification(type, time));
+
+ bool delayDispatch = m_delayCallbacks || !isMainThread();
+ if (delayDispatch && !m_mainThreadCallPending) {
+ m_mainThreadCallPending = true;
+ callOnMainThread(mainThreadCallback, this);
+ }
+
+ m_queueMutex.unlock();
+
+ if (delayDispatch) {
+ LOG(Media, "MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(%p) - early return", this);
+ return;
+ }
+
+ dispatchNotification();
+}
+
+void MediaPlayerPrivateAVFoundation::dispatchNotification()
+{
+ ASSERT(isMainThread());
+
+ Notification notification = Notification();
+ {
+ MutexLocker lock(m_queueMutex);
+
+ if (m_queuedNotifications.isEmpty())
+ return;
+
+ if (!m_delayCallbacks) {
+ // Only dispatch one notification callback per invocation because they can cause recursion.
+ notification = m_queuedNotifications.first();
+ m_queuedNotifications.remove(0);
+ }
+
+ if (!m_queuedNotifications.isEmpty() && !m_mainThreadCallPending)
+ callOnMainThread(mainThreadCallback, this);
+
+ if (!notification.isValid())
+ return;
+ }
+
+ LOG(Media, "MediaPlayerPrivateAVFoundation::dispatchNotification(%p) - dispatching %d", this, static_cast<int>(notification.type()));
+
+ switch (notification.type()) {
+ case Notification::ItemDidPlayToEndTime:
+ didEnd();
+ break;
+ case Notification::ItemTracksChanged:
+ tracksChanged();
+ break;
+ case Notification::ItemStatusChanged:
+ loadStateChanged();
+ break;
+ case Notification::ItemSeekableTimeRangesChanged:
+ seekableTimeRangesChanged();
+ loadStateChanged();
+ break;
+ case Notification::ItemLoadedTimeRangesChanged:
+ loadedTimeRangesChanged();
+ loadStateChanged();
+ break;
+ case Notification::ItemPresentationSizeChanged:
+ sizeChanged();
+ break;
+ case Notification::ItemIsPlaybackLikelyToKeepUpChanged:
+ loadStateChanged();
+ break;
+ case Notification::ItemIsPlaybackBufferEmptyChanged:
+ loadStateChanged();
+ break;
+ case Notification::ItemIsPlaybackBufferFullChanged:
+ loadStateChanged();
+ break;
+ case Notification::PlayerRateChanged:
+ rateChanged();
+ break;
+ case Notification::PlayerTimeChanged:
+ timeChanged(notification.time());
+ break;
+ case Notification::AssetMetadataLoaded:
+ metadataLoaded();
+ break;
+ case Notification::AssetPlayabilityKnown:
+ playabilityKnown();
+ break;
+ case Notification::None:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
new file mode 100644
index 0000000..a768ab4
--- /dev/null
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaPlayerPrivateAVFoundation_h
+#define MediaPlayerPrivateAVFoundation_h
+
+#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+
+#include "FloatSize.h"
+#include "MediaPlayerPrivate.h"
+#include "Timer.h"
+#include <wtf/RetainPtr.h>
+
+namespace WebCore {
+
+class ApplicationCacheResource;
+
+class MediaPlayerPrivateAVFoundation : public MediaPlayerPrivateInterface {
+public:
+
+ virtual void repaint();
+ virtual void metadataLoaded();
+ virtual void loadStateChanged();
+ virtual void playabilityKnown();
+ virtual void rateChanged();
+ virtual void loadedTimeRangesChanged();
+ virtual void seekableTimeRangesChanged();
+ virtual void timeChanged(double);
+ virtual void didEnd();
+
+ class Notification {
+ public:
+ enum Type {
+ None,
+ ItemDidPlayToEndTime,
+ ItemTracksChanged,
+ ItemStatusChanged,
+ ItemSeekableTimeRangesChanged,
+ ItemLoadedTimeRangesChanged,
+ ItemPresentationSizeChanged,
+ ItemIsPlaybackLikelyToKeepUpChanged,
+ ItemIsPlaybackBufferEmptyChanged,
+ ItemIsPlaybackBufferFullChanged,
+ AssetMetadataLoaded,
+ AssetPlayabilityKnown,
+ PlayerRateChanged,
+ PlayerTimeChanged
+ };
+
+ Notification()
+ : m_type(None)
+ , m_time(0)
+ {
+ }
+
+ Notification(Type type, double time)
+ : m_type(type)
+ , m_time(time)
+ {
+ }
+
+ Type type() { return m_type; }
+ bool isValid() { return m_type != None; }
+ double time() { return m_time; }
+
+ private:
+ Type m_type;
+ double m_time;
+ };
+
+ void scheduleMainThreadNotification(Notification::Type, double time = 0);
+ void dispatchNotification();
+ void clearMainThreadPendingFlag();
+
+protected:
+ MediaPlayerPrivateAVFoundation(MediaPlayer*);
+ virtual ~MediaPlayerPrivateAVFoundation();
+
+ // MediaPlayerPrivatePrivateInterface overrides.
+ virtual void load(const String& url);
+ virtual void cancelLoad() = 0;
+
+ virtual void prepareToPlay();
+ virtual PlatformMedia platformMedia() const = 0;
+
+ virtual void play() = 0;
+ virtual void pause() = 0;
+
+ virtual IntSize naturalSize() const;
+ virtual bool hasVideo() const { return m_cachedHasVideo; }
+ virtual bool hasAudio() const { return m_cachedHasAudio; }
+ virtual void setVisible(bool);
+ virtual float duration() const;
+ virtual float currentTime() const = 0;
+ virtual void seek(float);
+ virtual bool seeking() const;
+ virtual void setRate(float);
+ virtual bool paused() const;
+ virtual void setVolume(float) = 0;
+ virtual bool hasClosedCaptions() const { return m_cachedHasCaptions; }
+ virtual void setClosedCaptionsVisible(bool) = 0;
+ virtual MediaPlayer::NetworkState networkState() const { return m_networkState; }
+ virtual MediaPlayer::ReadyState readyState() const { return m_readyState; }
+ virtual float maxTimeSeekable() const;
+ virtual PassRefPtr<TimeRanges> buffered() const;
+ virtual unsigned bytesLoaded() const;
+ virtual void setSize(const IntSize&);
+ virtual void paint(GraphicsContext*, const IntRect&);
+ virtual void paintCurrentFrameInContext(GraphicsContext*, const IntRect&) = 0;
+ virtual void setPreload(MediaPlayer::Preload);
+ virtual bool hasAvailableVideoFrame() const;
+#if USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const { return 0; }
+ virtual bool supportsAcceleratedRendering() const = 0;
+ virtual void acceleratedRenderingStateChanged();
+#endif
+ virtual bool hasSingleSecurityOrigin() const { return true; }
+ virtual MediaPlayer::MovieLoadType movieLoadType() const;
+ virtual void prepareForRendering();
+ virtual float mediaTimeForTimeValue(float) const = 0;
+
+ virtual bool supportsFullscreen() const;
+
+ // Required interfaces for concrete derived classes.
+ virtual void createAVPlayerForURL(const String& url) = 0;
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void createAVPlayerForCacheResource(ApplicationCacheResource*) = 0;
+#endif
+
+ enum ItemStatus {
+ MediaPlayerAVPlayerItemStatusUnknown,
+ MediaPlayerAVPlayerItemStatusFailed,
+ MediaPlayerAVPlayerItemStatusReadyToPlay,
+ MediaPlayerAVPlayerItemStatusPlaybackBufferEmpty,
+ MediaPlayerAVPlayerItemStatusPlaybackBufferFull,
+ MediaPlayerAVPlayerItemStatusPlaybackLikelyToKeepUp,
+ };
+ virtual ItemStatus playerItemStatus() const = 0;
+
+ enum AVAssetStatus {
+ MediaPlayerAVAssetStatusUnknown,
+ MediaPlayerAVAssetStatusLoading,
+ MediaPlayerAVAssetStatusFailed,
+ MediaPlayerAVAssetStatusCancelled,
+ MediaPlayerAVAssetStatusLoaded,
+ MediaPlayerAVAssetStatusPlayable,
+ };
+ virtual AVAssetStatus assetStatus() const = 0;
+
+ virtual void checkPlayability() = 0;
+ virtual float rate() const = 0;
+ virtual void seekToTime(float time) = 0;
+ virtual unsigned totalBytes() const = 0;
+ virtual PassRefPtr<TimeRanges> platformBufferedTimeRanges() const = 0;
+ virtual float platformMaxTimeSeekable() const = 0;
+ virtual float platformMaxTimeLoaded() const = 0;
+ virtual float platformDuration() const = 0;
+
+ virtual void beginLoadingMetadata() = 0;
+ virtual void tracksChanged() = 0;
+ virtual void sizeChanged() = 0;
+
+ virtual void createContextVideoRenderer() = 0;
+ virtual void destroyContextVideoRenderer() = 0;
+
+ virtual void createVideoLayer() = 0;
+ virtual void destroyVideoLayer() = 0;
+ virtual bool videoLayerIsReadyToDisplay() const = 0;
+
+ virtual bool hasContextRenderer() const = 0;
+ virtual bool hasLayerRenderer() const = 0;
+
+protected:
+ void resumeLoad();
+ void updateStates();
+
+ void setHasVideo(bool b) { m_cachedHasVideo = b; };
+ void setHasAudio(bool b) { m_cachedHasAudio = b; }
+ void setHasClosedCaptions(bool b) { m_cachedHasCaptions = b; }
+ void setDelayCallbacks(bool);
+ void setIgnoreLoadStateChanges(bool delay) { m_ignoreLoadStateChanges = delay; }
+ void setNaturalSize(IntSize);
+
+ enum MediaRenderingMode { MediaRenderingNone, MediaRenderingToContext, MediaRenderingToLayer };
+ MediaRenderingMode currentRenderingMode() const;
+ MediaRenderingMode preferredRenderingMode() const;
+
+ bool metaDataAvailable() const { return m_readyState >= MediaPlayer::HaveMetadata; }
+ float requestedRate() const { return m_requestedRate; }
+ float maxTimeLoaded() const;
+ bool isReadyForVideoSetup() const;
+ virtual void setUpVideoRendering();
+ virtual void tearDownVideoRendering();
+ bool hasSetUpVideoRendering() const;
+
+ static void mainThreadCallback(void*);
+
+private:
+
+ MediaPlayer* m_player;
+
+ Vector<Notification> m_queuedNotifications;
+ Mutex m_queueMutex;
+ bool m_mainThreadCallPending;
+
+ mutable RefPtr<TimeRanges> m_cachedLoadedTimeRanges;
+
+ MediaPlayer::NetworkState m_networkState;
+ MediaPlayer::ReadyState m_readyState;
+
+ String m_assetURL;
+ MediaPlayer::Preload m_preload;
+ FloatSize m_scaleFactor;
+
+ IntSize m_cachedNaturalSize;
+ mutable float m_cachedMaxTimeLoaded;
+ mutable float m_cachedMaxTimeSeekable;
+ mutable float m_cachedDuration;
+ float m_reportedDuration;
+
+ float m_seekTo;
+ float m_requestedRate;
+ int m_delayCallbacks;
+ bool m_havePreparedToPlay;
+ bool m_assetIsPlayable;
+ bool m_visible;
+ bool m_videoFrameHasDrawn;
+ bool m_loadingMetadata;
+ bool m_delayingLoad;
+ bool m_isAllowedToRender;
+ bool m_cachedHasAudio;
+ bool m_cachedHasVideo;
+ bool m_cachedHasCaptions;
+ bool m_ignoreLoadStateChanges;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h
new file mode 100644
index 0000000..cc00c15
--- /dev/null
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaPlayerPrivateAVFoundationObjC_h
+#define MediaPlayerPrivateAVFoundationObjC_h
+
+#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+
+#include "MediaPlayerPrivateAVFoundation.h"
+
+#ifdef __OBJC__
+@class AVAsset;
+@class AVPlayer;
+@class AVPlayerItem;
+@class AVPlayerLayer;
+@class AVAssetImageGenerator;
+@class WebCoreAVFMovieObserver;
+#else
+class AVAsset;
+class AVPlayer;
+class AVPlayerItem;
+class AVPlayerLayer;
+class AVAssetImageGenerator;
+class WebCoreAVFMovieObserver;
+typedef struct objc_object *id;
+#endif
+
+namespace WebCore {
+
+class ApplicationCacheResource;
+
+class MediaPlayerPrivateAVFoundationObjC : public MediaPlayerPrivateAVFoundation {
+public:
+
+ static void registerMediaEngine(MediaEngineRegistrar);
+
+ void setAsset(id);
+ virtual void tracksChanged();
+
+private:
+ MediaPlayerPrivateAVFoundationObjC(MediaPlayer*);
+ ~MediaPlayerPrivateAVFoundationObjC();
+
+ // engine support
+ static MediaPlayerPrivateInterface* create(MediaPlayer* player);
+ static void getSupportedTypes(HashSet<String>& types);
+ static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
+ static bool isAvailable();
+
+ virtual void cancelLoad();
+
+ virtual PlatformMedia platformMedia() const;
+
+ virtual void play();
+ virtual void pause();
+ virtual float currentTime() const;
+ virtual void setVolume(float);
+ virtual void setClosedCaptionsVisible(bool);
+ virtual void paint(GraphicsContext*, const IntRect&);
+ virtual void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
+ virtual PlatformLayer* platformLayer() const;
+ virtual bool supportsAcceleratedRendering() const { return true; }
+ virtual float mediaTimeForTimeValue(float) const;
+
+ virtual void createAVPlayer();
+ virtual void createAVPlayerForURL(const String& url);
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ virtual void createAVPlayerForCacheResource(ApplicationCacheResource*);
+#endif
+ virtual MediaPlayerPrivateAVFoundation::ItemStatus playerItemStatus() const;
+ virtual MediaPlayerPrivateAVFoundation::AVAssetStatus assetStatus() const;
+
+ virtual void checkPlayability();
+ virtual float rate() const;
+ virtual void seekToTime(float time);
+ virtual unsigned totalBytes() const;
+ virtual PassRefPtr<TimeRanges> platformBufferedTimeRanges() const;
+ virtual float platformMaxTimeSeekable() const;
+ virtual float platformDuration() const;
+ virtual float platformMaxTimeLoaded() const;
+ virtual void beginLoadingMetadata();
+ virtual void sizeChanged();
+
+ virtual void createContextVideoRenderer();
+ virtual void destroyContextVideoRenderer();
+
+ virtual void createVideoLayer();
+ virtual void destroyVideoLayer();
+ virtual bool videoLayerIsReadyToDisplay() const;
+
+ virtual bool hasContextRenderer() const;
+ virtual bool hasLayerRenderer() const;
+
+ RetainPtr<CGImageRef> createImageForTimeInRect(float, const IntRect&);
+
+ MediaPlayer* m_player;
+ RetainPtr<AVAsset> m_avAsset;
+ RetainPtr<AVPlayer> m_avPlayer;
+ RetainPtr<AVPlayerItem> m_avPlayerItem;
+ RetainPtr<AVPlayerLayer> m_videoLayer;
+ RetainPtr<WebCoreAVFMovieObserver> m_objcObserver;
+ RetainPtr<AVAssetImageGenerator> m_imageGenerator;
+ id m_timeObserver;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm
new file mode 100644
index 0000000..55eb433
--- /dev/null
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm
@@ -0,0 +1,811 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+
+#import "MediaPlayerPrivateAVFoundationObjC.h"
+
+#import "ApplicationCacheResource.h"
+#import "BlockExceptions.h"
+#import "FloatConversion.h"
+#import "FrameView.h"
+#import "FloatConversion.h"
+#import "GraphicsContext.h"
+#import "KURL.h"
+#import "Logging.h"
+#import "SoftLinking.h"
+#import "TimeRanges.h"
+#import "WebCoreSystemInterface.h"
+#import <objc/objc-runtime.h>
+#import <wtf/UnusedParam.h>
+
+#import <CoreMedia/CoreMedia.h>
+#import <AVFoundation/AVFoundation.h>
+
+SOFT_LINK_FRAMEWORK(AVFoundation)
+SOFT_LINK_FRAMEWORK(CoreMedia)
+
+SOFT_LINK(CoreMedia, CMTimeCompare, int32_t, (CMTime time1, CMTime time2), (time1, time2))
+SOFT_LINK(CoreMedia, CMTimeMakeWithSeconds, CMTime, (Float64 seconds, int32_t preferredTimeScale), (seconds, preferredTimeScale))
+SOFT_LINK(CoreMedia, CMTimeGetSeconds, Float64, (CMTime time), (time))
+SOFT_LINK(CoreMedia, CMTimeRangeGetEnd, CMTime, (CMTimeRange range), (range))
+
+SOFT_LINK_CLASS(AVFoundation, AVPlayer)
+SOFT_LINK_CLASS(AVFoundation, AVPlayerItem)
+SOFT_LINK_CLASS(AVFoundation, AVPlayerLayer)
+SOFT_LINK_CLASS(AVFoundation, AVURLAsset)
+SOFT_LINK_CLASS(AVFoundation, AVAssetImageGenerator)
+
+SOFT_LINK_POINTER(AVFoundation, AVMediaCharacteristicVisual, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVMediaCharacteristicAudible, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVMediaTypeClosedCaption, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVPlayerItemDidPlayToEndTimeNotification, NSString *)
+SOFT_LINK_POINTER(AVFoundation, AVAssetImageGeneratorApertureModeCleanAperture, NSString *)
+
+SOFT_LINK_CONSTANT(CoreMedia, kCMTimeZero, CMTime)
+
+#define AVPlayer getAVPlayerClass()
+#define AVPlayerItem getAVPlayerItemClass()
+#define AVPlayerLayer getAVPlayerLayerClass()
+#define AVURLAsset getAVURLAssetClass()
+#define AVAssetImageGenerator getAVAssetImageGeneratorClass()
+
+#define AVMediaCharacteristicVisual getAVMediaCharacteristicVisual()
+#define AVMediaCharacteristicAudible getAVMediaCharacteristicAudible()
+#define AVMediaTypeClosedCaption getAVMediaTypeClosedCaption()
+#define AVPlayerItemDidPlayToEndTimeNotification getAVPlayerItemDidPlayToEndTimeNotification()
+#define AVAssetImageGeneratorApertureModeCleanAperture getAVAssetImageGeneratorApertureModeCleanAperture()
+
+#define kCMTimeZero getkCMTimeZero()
+
+using namespace WebCore;
+using namespace std;
+
+enum MediaPlayerAVFoundationObservationContext {
+ MediaPlayerAVFoundationObservationContextPlayerItem,
+ MediaPlayerAVFoundationObservationContextPlayer
+};
+
+@interface WebCoreAVFMovieObserver : NSObject
+{
+ MediaPlayerPrivateAVFoundationObjC* m_callback;
+ int m_delayCallbacks;
+}
+-(id)initWithCallback:(MediaPlayerPrivateAVFoundationObjC*)callback;
+-(void)disconnect;
+-(void)playableKnown;
+-(void)metadataLoaded;
+-(void)timeChanged:(double)time;
+-(void)didEnd:(NSNotification *)notification;
+-(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(MediaPlayerAVFoundationObservationContext)context;
+@end
+
+namespace WebCore {
+
+static NSArray *assetMetadataKeyNames();
+static NSArray *itemKVOProperties();
+
+#if !LOG_DISABLED
+static const char *boolString(bool val)
+{
+ return val ? "true" : "false";
+}
+#endif
+
+static const float invalidTime = -1.0f;
+
+MediaPlayerPrivateInterface* MediaPlayerPrivateAVFoundationObjC::create(MediaPlayer* player)
+{
+ return new MediaPlayerPrivateAVFoundationObjC(player);
+}
+
+void MediaPlayerPrivateAVFoundationObjC::registerMediaEngine(MediaEngineRegistrar registrar)
+{
+ if (isAvailable())
+ registrar(create, getSupportedTypes, supportsType, 0, 0, 0);
+}
+
+MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC(MediaPlayer* player)
+ : MediaPlayerPrivateAVFoundation(player)
+ , m_objcObserver(AdoptNS, [[WebCoreAVFMovieObserver alloc] initWithCallback:this])
+ , m_timeObserver(0)
+{
+}
+
+MediaPlayerPrivateAVFoundationObjC::~MediaPlayerPrivateAVFoundationObjC()
+{
+ cancelLoad();
+ [m_objcObserver.get() disconnect];
+}
+
+void MediaPlayerPrivateAVFoundationObjC::cancelLoad()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::cancelLoad(%p)", this);
+ tearDownVideoRendering();
+
+ [[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()];
+
+ // Tell our observer to do nothing when our cancellation of pending loading calls its completion handler.
+ setIgnoreLoadStateChanges(true);
+ if (m_avAsset) {
+ [m_avAsset.get() cancelLoading];
+ m_avAsset = nil;
+ }
+ if (m_avPlayerItem) {
+ for (NSString *keyName in itemKVOProperties())
+ [m_avPlayerItem.get() removeObserver:m_objcObserver.get() forKeyPath:keyName];
+
+ m_avPlayerItem = nil;
+ }
+ if (m_avPlayer) {
+ if (m_timeObserver)
+ [m_avPlayer.get() removeTimeObserver:m_timeObserver];
+ [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@"rate"];
+ m_avPlayer = nil;
+ }
+ setIgnoreLoadStateChanges(false);
+}
+
+bool MediaPlayerPrivateAVFoundationObjC::hasLayerRenderer() const
+{
+ return m_videoLayer;
+}
+
+bool MediaPlayerPrivateAVFoundationObjC::hasContextRenderer() const
+{
+ return m_imageGenerator;
+}
+
+void MediaPlayerPrivateAVFoundationObjC::createContextVideoRenderer()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::createContextVideoRenderer(%p)", this);
+
+ if (!m_avAsset || m_imageGenerator)
+ return;
+
+ m_imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:m_avAsset.get()];
+
+ [m_imageGenerator.get() setApertureMode:AVAssetImageGeneratorApertureModeCleanAperture];
+ [m_imageGenerator.get() setAppliesPreferredTrackTransform:YES];
+
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::createImageGenerator(%p) - returning %p", this, m_imageGenerator.get());
+}
+
+void MediaPlayerPrivateAVFoundationObjC::destroyContextVideoRenderer()
+{
+ if (!m_imageGenerator)
+ return;
+
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::destroyContextVideoRenderer(%p) - destroying", this, m_imageGenerator.get());
+
+ m_imageGenerator = 0;
+}
+
+void MediaPlayerPrivateAVFoundationObjC::createVideoLayer()
+{
+ if (!m_avPlayer)
+ return;
+
+ if (!m_videoLayer) {
+ m_videoLayer.adoptNS([[AVPlayerLayer alloc] init]);
+ [m_videoLayer.get() setPlayer:m_avPlayer.get()];
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::createVideoLayer(%p) - returning", this, m_videoLayer.get());
+ }
+}
+
+void MediaPlayerPrivateAVFoundationObjC::destroyVideoLayer()
+{
+ if (!m_videoLayer)
+ return;
+
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::destroyVideoLayer(%p) - destroying", this, m_videoLayer.get());
+
+ [m_videoLayer.get() setPlayer:nil];
+
+ m_videoLayer = 0;
+}
+
+bool MediaPlayerPrivateAVFoundationObjC::videoLayerIsReadyToDisplay() const
+{
+ return (m_videoLayer && [m_videoLayer.get() isReadyForDisplay]);
+}
+
+void MediaPlayerPrivateAVFoundationObjC::createAVPlayerForURL(const String& url)
+{
+ setDelayCallbacks(true);
+
+ if (!m_avAsset) {
+ NSURL *cocoaURL = KURL(ParsedURLString, url);
+ m_avAsset.adoptNS([[AVURLAsset alloc] initWithURL:cocoaURL options:nil]);
+ }
+
+ createAVPlayer();
+}
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+void MediaPlayerPrivateAVFoundationObjC::createAVPlayerForCacheResource(ApplicationCacheResource* resource)
+{
+ // AVFoundation can't open arbitrary data pointers, so if this ApplicationCacheResource doesn't
+ // have a valid local path, just open the resource's original URL.
+ if (resource->path().isEmpty()) {
+ createAVPlayerForURL(resource->url());
+ return;
+ }
+
+ setDelayCallbacks(true);
+
+ if (!m_avAsset) {
+ NSURL* localURL = [NSURL fileURLWithPath:resource->path()];
+ m_avAsset.adoptNS([[AVURLAsset alloc] initWithURL:localURL options:nil]);
+ }
+
+ createAVPlayer();
+}
+#endif
+
+void MediaPlayerPrivateAVFoundationObjC::createAVPlayer()
+{
+ if (!m_avPlayer) {
+ m_avPlayer.adoptNS([[AVPlayer alloc] init]);
+
+ [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@"rate" options:nil context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
+
+ // Add a time observer, ask to be called infrequently because we don't really want periodic callbacks but
+ // our observer will also be called whenever a seek happens.
+ const double veryLongInterval = 60*60*60*24*30;
+ WebCoreAVFMovieObserver *observer = m_objcObserver.get();
+ m_timeObserver = [m_avPlayer.get() addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(veryLongInterval, 10) queue:nil usingBlock:^(CMTime time){
+ [observer timeChanged:CMTimeGetSeconds(time)];
+ }];
+ }
+
+ if (!m_avPlayerItem) {
+ // Create the player item so we can media data.
+ m_avPlayerItem.adoptNS([[AVPlayerItem alloc] initWithAsset:m_avAsset.get()]);
+
+ [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()selector:@selector(didEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:m_avPlayerItem.get()];
+
+ for (NSString *keyName in itemKVOProperties())
+ [m_avPlayerItem.get() addObserver:m_objcObserver.get() forKeyPath:keyName options:nil context:(void *)MediaPlayerAVFoundationObservationContextPlayerItem];
+
+ [m_avPlayer.get() replaceCurrentItemWithPlayerItem:m_avPlayerItem.get()];
+ }
+
+ setDelayCallbacks(false);
+}
+
+void MediaPlayerPrivateAVFoundationObjC::checkPlayability()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::checkPlayability(%p)", this);
+
+ [m_avAsset.get() loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"playable"] completionHandler:^{
+ [m_objcObserver.get() playableKnown];
+ }];
+}
+
+void MediaPlayerPrivateAVFoundationObjC::beginLoadingMetadata()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::playabilityKnown(%p) - requesting metadata loading", this);
+ [m_avAsset.get() loadValuesAsynchronouslyForKeys:[assetMetadataKeyNames() retain] completionHandler:^{
+ [m_objcObserver.get() metadataLoaded];
+ }];
+}
+
+MediaPlayerPrivateAVFoundation::ItemStatus MediaPlayerPrivateAVFoundationObjC::playerItemStatus() const
+{
+ if (!m_avPlayerItem)
+ return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusUnknown;
+
+ AVPlayerItemStatus status = [m_avPlayerItem.get() status];
+ if (status == AVPlayerItemStatusUnknown)
+ return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusUnknown;
+ if (status == AVPlayerItemStatusFailed)
+ return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusFailed;
+ if ([m_avPlayerItem.get() isPlaybackLikelyToKeepUp])
+ return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusPlaybackLikelyToKeepUp;
+ if ([m_avPlayerItem.get() isPlaybackBufferFull])
+ return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusPlaybackBufferFull;
+ if ([m_avPlayerItem.get() isPlaybackBufferEmpty])
+ return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusPlaybackBufferEmpty;
+
+ return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusReadyToPlay;
+}
+
+PlatformMedia MediaPlayerPrivateAVFoundationObjC::platformMedia() const
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::platformMedia(%p)", this);
+ PlatformMedia pm;
+ pm.type = PlatformMedia::AVFoundationMediaPlayerType;
+ pm.media.avfMediaPlayer = m_avPlayer.get();
+ return pm;
+}
+
+PlatformLayer* MediaPlayerPrivateAVFoundationObjC::platformLayer() const
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::platformLayer(%p)", this);
+ return m_videoLayer.get();
+}
+
+void MediaPlayerPrivateAVFoundationObjC::play()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::play(%p)", this);
+ if (!metaDataAvailable())
+ return;
+
+ setDelayCallbacks(true);
+ [m_avPlayer.get() setRate:requestedRate()];
+ setDelayCallbacks(false);
+}
+
+void MediaPlayerPrivateAVFoundationObjC::pause()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::pause(%p)", this);
+ if (!metaDataAvailable())
+ return;
+
+ setDelayCallbacks(true);
+ [m_avPlayer.get() setRate:nil];
+ setDelayCallbacks(false);
+}
+
+float MediaPlayerPrivateAVFoundationObjC::platformDuration() const
+{
+ if (!metaDataAvailable() || !m_avPlayerItem)
+ return 0;
+
+ float duration;
+ CMTime cmDuration = [m_avPlayerItem.get() duration];
+ if (CMTIME_IS_NUMERIC(cmDuration))
+ duration = narrowPrecisionToFloat(CMTimeGetSeconds(cmDuration));
+ else if (CMTIME_IS_INDEFINITE(cmDuration))
+ duration = numeric_limits<float>::infinity();
+ else {
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::duration(%p) - invalid duration, returning 0", this);
+ return 0;
+ }
+
+ return duration;
+}
+
+float MediaPlayerPrivateAVFoundationObjC::currentTime() const
+{
+ if (!metaDataAvailable() || !m_avPlayerItem)
+ return 0;
+
+ CMTime itemTime = [m_avPlayerItem.get() currentTime];
+ if (CMTIME_IS_NUMERIC(itemTime))
+ return narrowPrecisionToFloat(CMTimeGetSeconds(itemTime));
+
+ return 0;
+}
+
+void MediaPlayerPrivateAVFoundationObjC::seekToTime(float time)
+{
+ // setCurrentTime generates several event callbacks, update afterwards.
+ setDelayCallbacks(true);
+
+ float now = currentTime();
+ if (time != now)
+ [m_avPlayerItem.get() seekToTime:CMTimeMakeWithSeconds(time, 600) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
+ else {
+ // Force a call to the "time changed" notifier manually because a seek to the current time is a noop
+ // so the seek will never seem to complete.
+ [m_objcObserver.get() timeChanged:now];
+ }
+
+ setDelayCallbacks(false);
+}
+
+void MediaPlayerPrivateAVFoundationObjC::setVolume(float volume)
+{
+ if (!metaDataAvailable())
+ return;
+
+ [m_avPlayer.get() setVolume:volume];
+}
+
+void MediaPlayerPrivateAVFoundationObjC::setClosedCaptionsVisible(bool closedCaptionsVisible)
+{
+ if (!metaDataAvailable())
+ return;
+
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setClosedCaptionsVisible(%p) - setting to %s", this, boolString(closedCaptionsVisible));
+ [m_avPlayer.get() setClosedCaptionDisplayEnabled:closedCaptionsVisible];
+}
+
+float MediaPlayerPrivateAVFoundationObjC::rate() const
+{
+ if (!metaDataAvailable())
+ return 0;
+
+ return [m_avPlayer.get() rate];
+}
+
+PassRefPtr<TimeRanges> MediaPlayerPrivateAVFoundationObjC::platformBufferedTimeRanges() const
+{
+ RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+
+ if (!m_avPlayerItem)
+ return timeRanges.release();
+
+ NSArray *loadedRanges = [m_avPlayerItem.get() loadedTimeRanges];
+ for (NSValue *thisRangeValue in loadedRanges) {
+ CMTimeRange timeRange = [thisRangeValue CMTimeRangeValue];
+ if (CMTIMERANGE_IS_VALID(timeRange) && !CMTIMERANGE_IS_EMPTY(timeRange)) {
+ float rangeStart = narrowPrecisionToFloat(CMTimeGetSeconds(timeRange.start));
+ float rangeEnd = narrowPrecisionToFloat(CMTimeGetSeconds(CMTimeRangeGetEnd(timeRange)));
+ timeRanges->add(rangeStart, rangeEnd);
+ }
+ }
+ return timeRanges.release();
+}
+
+float MediaPlayerPrivateAVFoundationObjC::platformMaxTimeSeekable() const
+{
+ NSArray *seekableRanges = [m_avPlayerItem.get() seekableTimeRanges];
+ if (!seekableRanges)
+ return 0;
+
+ float maxTimeSeekable = 0;
+ for (NSValue *thisRangeValue in seekableRanges) {
+ CMTimeRange timeRange = [thisRangeValue CMTimeRangeValue];
+ if (!CMTIMERANGE_IS_VALID(timeRange) || CMTIMERANGE_IS_EMPTY(timeRange))
+ continue;
+
+ float endOfRange = narrowPrecisionToFloat(CMTimeGetSeconds(CMTimeRangeGetEnd(timeRange)));
+ if (maxTimeSeekable < endOfRange)
+ maxTimeSeekable = endOfRange;
+ }
+ return maxTimeSeekable;
+}
+
+float MediaPlayerPrivateAVFoundationObjC::platformMaxTimeLoaded() const
+{
+ NSArray *loadedRanges = [m_avPlayerItem.get() loadedTimeRanges];
+ if (!loadedRanges)
+ return 0;
+
+ float maxTimeLoaded = 0;
+ for (NSValue *thisRangeValue in loadedRanges) {
+ CMTimeRange timeRange = [thisRangeValue CMTimeRangeValue];
+ if (!CMTIMERANGE_IS_VALID(timeRange) || CMTIMERANGE_IS_EMPTY(timeRange))
+ continue;
+
+ float endOfRange = narrowPrecisionToFloat(CMTimeGetSeconds(CMTimeRangeGetEnd(timeRange)));
+ if (maxTimeLoaded < endOfRange)
+ maxTimeLoaded = endOfRange;
+ }
+
+ return maxTimeLoaded;
+}
+
+unsigned MediaPlayerPrivateAVFoundationObjC::totalBytes() const
+{
+ if (!metaDataAvailable())
+ return 0;
+
+ long long totalMediaSize = 0;
+ NSArray *tracks = [m_avAsset.get() tracks];
+ for (AVAssetTrack *thisTrack in tracks)
+ totalMediaSize += [thisTrack totalSampleDataLength];
+
+ return static_cast<unsigned>(totalMediaSize);
+}
+
+void MediaPlayerPrivateAVFoundationObjC::setAsset(id asset)
+{
+ m_avAsset = asset;
+}
+
+MediaPlayerPrivateAVFoundation::AVAssetStatus MediaPlayerPrivateAVFoundationObjC::assetStatus() const
+{
+ if (!m_avAsset)
+ return MediaPlayerAVAssetStatusUnknown;
+
+ for (NSString *keyName in assetMetadataKeyNames()) {
+ AVKeyValueStatus keyStatus = [m_avAsset.get() statusOfValueForKey:keyName error:nil];
+ if (keyStatus < AVKeyValueStatusLoaded)
+ return MediaPlayerAVAssetStatusLoading;// At least one key is not loaded yet.
+
+ if (keyStatus == AVKeyValueStatusFailed)
+ return MediaPlayerAVAssetStatusFailed; // At least one key could not be loaded.
+ if (keyStatus == AVKeyValueStatusCancelled)
+ return MediaPlayerAVAssetStatusCancelled; // Loading of at least one key was cancelled.
+ }
+
+ if ([[m_avAsset.get() valueForKey:@"playable"] boolValue])
+ return MediaPlayerAVAssetStatusPlayable;
+
+ return MediaPlayerAVAssetStatusLoaded;
+}
+
+void MediaPlayerPrivateAVFoundationObjC::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
+{
+ if (!metaDataAvailable() || context->paintingDisabled())
+ return;
+
+ paint(context, rect);
+}
+
+void MediaPlayerPrivateAVFoundationObjC::paint(GraphicsContext* context, const IntRect& rect)
+{
+ if (!metaDataAvailable() || context->paintingDisabled())
+ return;
+
+ setDelayCallbacks(true);
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+ RetainPtr<CGImageRef> image = createImageForTimeInRect(currentTime(), rect);
+ if (image) {
+ context->save();
+ context->translate(rect.x(), rect.y() + rect.height());
+ context->scale(FloatSize(1.0f, -1.0f));
+ context->setImageInterpolationQuality(InterpolationLow);
+ IntRect paintRect(IntPoint(0, 0), IntSize(rect.width(), rect.height()));
+ CGContextDrawImage(context->platformContext(), CGRectMake(0, 0, paintRect.width(), paintRect.height()), image.get());
+ context->restore();
+ image = 0;
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS;
+ setDelayCallbacks(false);
+
+ MediaPlayerPrivateAVFoundation::paint(context, rect);
+}
+
+static HashSet<String> mimeTypeCache()
+{
+ DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
+ static bool typeListInitialized = false;
+
+ if (typeListInitialized)
+ return cache;
+ typeListInitialized = true;
+
+ NSArray *types = [AVURLAsset audiovisualMIMETypes];
+ for (NSString *mimeType in types)
+ cache.add(mimeType);
+
+ return cache;
+}
+
+RetainPtr<CGImageRef> MediaPlayerPrivateAVFoundationObjC::createImageForTimeInRect(float time, const IntRect& rect)
+{
+ if (!m_imageGenerator)
+ createContextVideoRenderer();
+ ASSERT(m_imageGenerator);
+
+#if !LOG_DISABLED
+ double start = WTF::currentTime();
+#endif
+
+ [m_imageGenerator.get() setMaximumSize:CGSize(rect.size())];
+ CGImageRef image = [m_imageGenerator.get() copyCGImageAtTime:CMTimeMakeWithSeconds(time, 600) actualTime:nil error:nil];
+
+#if !LOG_DISABLED
+ double duration = WTF::currentTime() - start;
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::createImageForTimeInRect(%p) - creating image took %.4f", this, narrowPrecisionToFloat(duration));
+#endif
+
+ return image;
+}
+
+void MediaPlayerPrivateAVFoundationObjC::getSupportedTypes(HashSet<String>& supportedTypes)
+{
+ supportedTypes = mimeTypeCache();
+}
+
+MediaPlayer::SupportsType MediaPlayerPrivateAVFoundationObjC::supportsType(const String& type, const String& codecs)
+{
+ // Only return "IsSupported" if there is no codecs parameter for now as there is no way to ask if it supports an
+ // extended MIME type until rdar://6220037 is fixed.
+ if (mimeTypeCache().contains(type))
+ return codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported;
+
+ return MediaPlayer::IsNotSupported;
+}
+
+bool MediaPlayerPrivateAVFoundationObjC::isAvailable()
+{
+ return true;
+}
+
+float MediaPlayerPrivateAVFoundationObjC::mediaTimeForTimeValue(float timeValue) const
+{
+ if (!metaDataAvailable())
+ return timeValue;
+
+ // FIXME - impossible to implement until rdar://8721510 is fixed.
+ return timeValue;
+}
+
+void MediaPlayerPrivateAVFoundationObjC::tracksChanged()
+{
+ // This is called whenever the tracks collection changes so cache hasVideo and hasAudio since we get
+ // asked about those fairly fequently.
+ setHasVideo([[m_avAsset.get() tracksWithMediaCharacteristic:AVMediaCharacteristicVisual] count]);
+ setHasAudio([[m_avAsset.get() tracksWithMediaCharacteristic:AVMediaCharacteristicAudible] count]);
+ setHasClosedCaptions([[m_avAsset.get() tracksWithMediaType:AVMediaTypeClosedCaption] count]);
+
+ sizeChanged();
+}
+
+void MediaPlayerPrivateAVFoundationObjC::sizeChanged()
+{
+ NSArray *tracks = [m_avAsset.get() tracks];
+
+ // Some assets don't report track properties until they are completely ready to play, but we
+ // want to report a size as early as possible so use presentationSize when an asset has no tracks.
+ if (![tracks count]) {
+ setNaturalSize(IntSize([m_avPlayerItem.get() presentationSize]));
+ return;
+ }
+
+ // AVAsset's 'naturalSize' property only considers the movie's first video track, so we need to compute
+ // the union of all visual track rects.
+ CGRect trackUnionRect = CGRectZero;
+ for (AVAssetTrack *track in tracks) {
+ CGSize trackSize = [track naturalSize];
+ CGRect trackRect = CGRectMake(0, 0, trackSize.width, trackSize.height);
+ trackUnionRect = CGRectUnion(trackUnionRect, CGRectApplyAffineTransform(trackRect, [track preferredTransform]));
+ }
+
+ // The movie is always displayed at 0,0 so move the track rect to the origin before using width and height.
+ trackUnionRect = CGRectOffset(trackUnionRect, trackUnionRect.origin.x, trackUnionRect.origin.y);
+
+ // Also look at the asset's preferred transform so we account for a movie matrix.
+ CGSize naturalSize = CGSizeApplyAffineTransform(trackUnionRect.size, [m_avAsset.get() preferredTransform]);
+
+ // Cache the natural size (setNaturalSize will notify the player if it has changed).
+ setNaturalSize(IntSize(naturalSize));
+}
+
+NSArray* assetMetadataKeyNames()
+{
+ static NSArray* keys;
+ if (!keys) {
+ keys = [[NSArray alloc] initWithObjects:@"duration",
+ @"naturalSize",
+ @"preferredTransform",
+ @"preferredVolume",
+ @"preferredRate",
+ @"playable",
+ @"tracks",
+ nil];
+ }
+ return keys;
+}
+
+NSArray* itemKVOProperties()
+{
+ static NSArray* keys;
+ if (!keys) {
+ keys = [[NSArray alloc] initWithObjects:@"presentationSize",
+ @"status",
+ @"asset",
+ @"tracks",
+ @"seekableTimeRanges",
+ @"loadedTimeRanges",
+ @"playbackLikelyToKeepUp",
+ @"playbackBufferFull",
+ @"playbackBufferEmpty",
+ nil];
+ }
+ return keys;
+}
+
+} // namespace WebCore
+
+@implementation WebCoreAVFMovieObserver
+
+- (id)initWithCallback:(MediaPlayerPrivateAVFoundationObjC*)callback
+{
+ m_callback = callback;
+ return [super init];
+}
+
+- (void)disconnect
+{
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
+ m_callback = 0;
+}
+
+- (void)metadataLoaded
+{
+ if (!m_callback)
+ return;
+
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::AssetMetadataLoaded);
+}
+
+- (void)playableKnown
+{
+ if (!m_callback)
+ return;
+
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::AssetPlayabilityKnown);
+}
+
+- (void)timeChanged:(double)time
+{
+ if (!m_callback)
+ return;
+
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::PlayerTimeChanged, time);
+}
+
+- (void)didEnd:(NSNotification *)unusedNotification
+{
+ UNUSED_PARAM(unusedNotification);
+ if (!m_callback)
+ return;
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemDidPlayToEndTime);
+}
+
+- (void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(MediaPlayerAVFoundationObservationContext)context
+{
+ UNUSED_PARAM(change);
+
+ LOG(Media, "WebCoreAVFMovieObserver:observeValueForKeyPath(%p) - keyPath = %s", self, [keyPath UTF8String]);
+
+ if (!m_callback)
+ return;
+
+ if (context == MediaPlayerAVFoundationObservationContextPlayerItem) {
+ // A value changed for an AVPlayerItem
+ if ([keyPath isEqualToString:@"status"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemStatusChanged);
+ else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemIsPlaybackLikelyToKeepUpChanged);
+ else if ([keyPath isEqualToString:@"playbackBufferEmpty"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemIsPlaybackBufferEmptyChanged);
+ else if ([keyPath isEqualToString:@"playbackBufferFull"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemIsPlaybackBufferFullChanged);
+ else if ([keyPath isEqualToString:@"asset"])
+ m_callback->setAsset([object asset]);
+ else if ([keyPath isEqualToString:@"loadedTimeRanges"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemLoadedTimeRangesChanged);
+ else if ([keyPath isEqualToString:@"seekableTimeRanges"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemSeekableTimeRangesChanged);
+ else if ([keyPath isEqualToString:@"tracks"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemTracksChanged);
+ else if ([keyPath isEqualToString:@"presentationSize"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::ItemPresentationSizeChanged);
+
+ return;
+ }
+
+ if (context == MediaPlayerAVFoundationObservationContextPlayer) {
+ // A value changed for an AVPlayer.
+ if ([keyPath isEqualToString:@"rate"])
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::PlayerRateChanged);
+}
+}
+
+@end
+
+#endif
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
index e9663a6..427c7bf 100644
--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
@@ -550,11 +550,17 @@ void GraphicsLayerCA::setNeedsDisplay()
setNeedsDisplayInRect(hugeRect);
}
-void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& rect)
+void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& r)
{
if (!drawsContent())
return;
+ FloatRect rect(r);
+ FloatRect layerBounds(FloatPoint(), m_size);
+ rect.intersect(layerBounds);
+ if (rect.isEmpty())
+ return;
+
const size_t maxDirtyRects = 32;
for (size_t i = 0; i < m_dirtyRects.size(); ++i) {
@@ -1601,9 +1607,11 @@ bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValue
TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : functionList[animationIndex];
RefPtr<PlatformCAAnimation> caAnimation;
-#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD)
+#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) || PLATFORM(WIN)
// CA applies animations in reverse order (<rdar://problem/7095638>) so we need the last one we add (per property)
// to be non-additive.
+ // FIXME: This fix has not been added to QuartzCore on Windows yet (<rdar://problem/9112233>) so we expect the
+ // reversed animation behavior
bool additive = animationIndex < (numAnimations - 1);
#else
bool additive = animationIndex > 0;
diff --git a/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h b/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h
index a8528fd..8b5a460 100644
--- a/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h
+++ b/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h
@@ -38,11 +38,10 @@
#if PLATFORM(MAC)
#ifdef __OBJC__
@class CAPropertyAnimation;
-typedef CAPropertyAnimation* PlatformAnimationRef;
#else
-typedef void* CAPropertyAnimation; // So the m_animation declaration works
-typedef void* PlatformAnimationRef;
+class CAPropertyAnimation;
#endif
+typedef CAPropertyAnimation* PlatformAnimationRef;
#elif PLATFORM(WIN)
typedef struct _CACFAnimation* CACFAnimationRef;
typedef CACFAnimationRef PlatformAnimationRef;
diff --git a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp
index f2e1950..75f4a10 100644
--- a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp
@@ -307,13 +307,14 @@ void CACFLayerTreeHost::contextDidChange()
void CACFLayerTreeHost::notifyAnimationsStarted()
{
+ // Send currentTime to the pending animations. This function is called by CACF in a callback
+ // which occurs after the drawInContext calls. So currentTime is very close to the time
+ // the animations actually start
double currentTime = WTF::currentTime();
- double time = currentTime + lastCommitTime() - CACurrentMediaTime();
- ASSERT(time <= currentTime);
HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end();
for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it)
- (*it)->animationStarted(time);
+ (*it)->animationStarted(currentTime);
m_pendingAnimatedLayers.clear();
}
diff --git a/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp b/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
index b0588d6..0f90ce4 100644
--- a/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
@@ -34,6 +34,7 @@
#include "GraphicsContext.h"
#include "OwnPtrCairo.h"
#include "Path.h"
+#include "PlatformContextCairo.h"
#include "Timer.h"
#include <cairo.h>
@@ -88,7 +89,7 @@ PlatformContext ContextShadow::beginShadowLayer(GraphicsContext* context, const
adjustBlurDistance(context);
double x1, x2, y1, y2;
- cairo_clip_extents(context->platformContext(), &x1, &y1, &x2, &y2);
+ cairo_clip_extents(context->platformContext()->cr(), &x1, &y1, &x2, &y2);
IntRect layerRect = calculateLayerBoundingRect(context, layerArea, IntRect(x1, y1, x2 - x1, y2 - y1));
// Don't paint if we are totally outside the clip region.
@@ -120,7 +121,7 @@ void ContextShadow::endShadowLayer(GraphicsContext* context)
cairo_surface_mark_dirty(m_layerImage);
}
- cairo_t* cr = context->platformContext();
+ cairo_t* cr = context->platformContext()->cr();
cairo_save(cr);
setSourceRGBAFromColor(cr, m_color);
cairo_mask_surface(cr, m_layerImage, m_layerOrigin.x(), m_layerOrigin.y());
@@ -198,7 +199,7 @@ void ContextShadow::drawRectShadow(GraphicsContext* context, const IntRect& rect
int internalShadowHeight = radiusTwice + max(topLeftRadius.height(), topRightRadius.height()) +
max(bottomLeftRadius.height(), bottomRightRadius.height());
- cairo_t* cr = context->platformContext();
+ cairo_t* cr = context->platformContext()->cr();
// drawShadowedRect still does not work with rotations.
// https://bugs.webkit.org/show_bug.cgi?id=45042
diff --git a/Source/WebCore/platform/graphics/cairo/FontCairo.cpp b/Source/WebCore/platform/graphics/cairo/FontCairo.cpp
index 2d79499..58a7fd2 100644
--- a/Source/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -36,6 +36,7 @@
#include "GlyphBuffer.h"
#include "Gradient.h"
#include "GraphicsContext.h"
+#include "PlatformContextCairo.h"
#include "ImageBuffer.h"
#include "Pattern.h"
#include "SimpleFontData.h"
@@ -64,7 +65,7 @@ static void drawGlyphsToContext(cairo_t* context, const SimpleFontData* font, Gl
}
}
-static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs)
+static void drawGlyphsShadow(GraphicsContext* graphicsContext, const FloatPoint& point, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs)
{
ContextShadow* shadow = graphicsContext->contextShadow();
ASSERT(shadow);
@@ -74,6 +75,7 @@ static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context,
if (!shadow->mustUseContextShadow(graphicsContext)) {
// Optimize non-blurry shadows, by just drawing text without the ContextShadow.
+ cairo_t* context = graphicsContext->platformContext()->cr();
cairo_save(context);
cairo_translate(context, shadow->m_offset.width(), shadow->m_offset.height());
setSourceRGBAFromColor(context, shadow->m_color);
@@ -106,9 +108,10 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
offset += glyphBuffer.advanceAt(from + i);
}
- cairo_t* cr = context->platformContext();
- drawGlyphsShadow(context, cr, point, font, glyphs, numGlyphs);
+ PlatformContextCairo* platformContext = context->platformContext();
+ drawGlyphsShadow(context, point, font, glyphs, numGlyphs);
+ cairo_t* cr = platformContext->cr();
cairo_save(cr);
prepareContextForGlyphDrawing(cr, font, point);
if (context->textDrawingMode() & TextModeFill) {
diff --git a/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
index 5807102..f8f3c99 100644
--- a/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
@@ -25,6 +25,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -41,7 +42,7 @@ struct FontCustomPlatformData {
public:
FontCustomPlatformData(FT_Face, SharedBuffer*);
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
private:
diff --git a/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp b/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp
index 4e6ed07..225046a 100644
--- a/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp
@@ -29,6 +29,7 @@
#include "CSSParser.h"
#include "GraphicsContext.h"
+#include "PlatformContextCairo.h"
#include <cairo.h>
namespace WebCore {
@@ -87,7 +88,7 @@ void Gradient::setPlatformGradientSpaceTransform(const AffineTransform& gradient
void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
{
- cairo_t* cr = context->platformContext();
+ cairo_t* cr = context->platformContext()->cr();
context->save();
cairo_set_source(cr, platformGradient());
diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index e69a7a5..0fc94df 100644
--- a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -47,6 +47,7 @@
#include "NotImplemented.h"
#include "Path.h"
#include "Pattern.h"
+#include "PlatformContextCairo.h"
#include "RefPtrCairo.h"
#include "SimpleFontData.h"
#include <cairo.h>
@@ -148,7 +149,7 @@ static inline void drawPathShadow(GraphicsContext* context, PathDrawingStyle dra
return;
// Calculate the extents of the rendered solid paths.
- cairo_t* cairoContext = context->platformContext();
+ cairo_t* cairoContext = context->platformContext()->cr();
OwnPtr<cairo_path_t> path(cairo_copy_path(cairoContext));
FloatRect solidFigureExtents;
@@ -199,12 +200,18 @@ static void strokeCurrentCairoPath(GraphicsContext* context, cairo_t* cairoCont
cairo_new_path(cairoContext);
}
-void GraphicsContext::platformInit(PlatformGraphicsContext* cr)
+GraphicsContext::GraphicsContext(cairo_t* cr)
{
- m_data = new GraphicsContextPlatformPrivate;
- m_data->cr = cairo_reference(cr);
- m_data->syncContext(cr);
- setPaintingDisabled(!cr);
+ m_data = new GraphicsContextPlatformPrivate(new PlatformContextCairo(cr));
+}
+
+void GraphicsContext::platformInit(PlatformContextCairo* platformContext)
+{
+ m_data = new GraphicsContextPlatformPrivate(platformContext);
+ if (platformContext)
+ m_data->syncContext(platformContext->cr());
+ else
+ setPaintingDisabled(true);
}
void GraphicsContext::platformDestroy()
@@ -214,20 +221,20 @@ void GraphicsContext::platformDestroy()
AffineTransform GraphicsContext::getCTM() const
{
- cairo_t* cr = platformContext();
+ cairo_t* cr = platformContext()->cr();
cairo_matrix_t m;
cairo_get_matrix(cr, &m);
return AffineTransform(m.xx, m.yx, m.xy, m.yy, m.x0, m.y0);
}
-cairo_t* GraphicsContext::platformContext() const
+PlatformContextCairo* GraphicsContext::platformContext() const
{
- return m_data->cr;
+ return m_data->platformContext;
}
void GraphicsContext::savePlatformState()
{
- cairo_save(m_data->cr);
+ cairo_save(platformContext()->cr());
m_data->save();
m_data->shadowStack.append(m_data->shadow);
m_data->maskImageStack.append(ImageMaskInformation());
@@ -235,7 +242,8 @@ void GraphicsContext::savePlatformState()
void GraphicsContext::restorePlatformState()
{
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
+
const ImageMaskInformation& maskInformation = m_data->maskImageStack.last();
if (maskInformation.isValid()) {
const FloatRect& maskRect = maskInformation.maskRect();
@@ -251,7 +259,7 @@ void GraphicsContext::restorePlatformState()
m_data->shadowStack.removeLast();
}
- cairo_restore(m_data->cr);
+ cairo_restore(cr);
m_data->restore();
}
@@ -261,7 +269,7 @@ void GraphicsContext::drawRect(const IntRect& rect)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
if (fillColor().alpha())
@@ -289,7 +297,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
if (style == NoStroke)
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
float width = strokeThickness();
@@ -376,7 +384,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
float yRadius = .5 * rect.height();
float xRadius = .5 * rect.width();
@@ -415,7 +423,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
float fa = startAngle;
float falen = fa + angleSpan;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
if (w != h)
@@ -492,7 +500,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points
if (npoints <= 1)
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
cairo_set_antialias(cr, shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
@@ -522,7 +530,7 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin
if (numPoints <= 1)
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_new_path(cr);
cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
@@ -542,7 +550,7 @@ void GraphicsContext::fillPath(const Path& path)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
setPathOnCairoContext(cr, path.platformPath()->context());
fillCurrentCairoPath(this, cr);
}
@@ -552,7 +560,7 @@ void GraphicsContext::strokePath(const Path& path)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
setPathOnCairoContext(cr, path.platformPath()->context());
strokeCurrentCairoPath(this, cr);
}
@@ -562,7 +570,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
fillCurrentCairoPath(this, cr);
@@ -578,7 +586,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
m_data->shadow.drawRectShadow(this, enclosingIntRect(rect));
if (color.alpha())
- fillRectSourceOver(m_data->cr, rect, color);
+ fillRectSourceOver(platformContext()->cr(), rect, color);
}
void GraphicsContext::clip(const FloatRect& rect)
@@ -586,7 +594,7 @@ void GraphicsContext::clip(const FloatRect& rect)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
@@ -600,7 +608,7 @@ void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
setPathOnCairoContext(cr, path.platformPath()->context());
cairo_set_fill_rule(cr, clipRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
cairo_clip(cr);
@@ -638,7 +646,7 @@ void GraphicsContext::drawFocusRing(const Path& path, int width, int /* offset *
adjustFocusRingColor(ringColor);
adjustFocusRingLineWidth(width);
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
appendWebCorePathToCairoContext(cr, path);
setSourceRGBAFromColor(cr, ringColor);
@@ -655,7 +663,7 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int
unsigned rectCount = rects.size();
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
cairo_push_group(cr);
cairo_new_path(cr);
@@ -732,7 +740,7 @@ void GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float wi
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
switch (style) {
@@ -762,7 +770,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
FloatRect result;
double x = frect.x();
double y = frect.y();
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_user_to_device(cr, &x, &y);
x = round(x);
y = round(y);
@@ -799,7 +807,7 @@ void GraphicsContext::translate(float x, float y)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_translate(cr, x, y);
m_data->translate(x, y);
}
@@ -821,7 +829,7 @@ void GraphicsContext::setPlatformStrokeThickness(float strokeThickness)
if (paintingDisabled())
return;
- cairo_set_line_width(m_data->cr, strokeThickness);
+ cairo_set_line_width(platformContext()->cr(), strokeThickness);
}
void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
@@ -835,16 +843,16 @@ void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
switch (strokeStyle) {
case NoStroke:
// FIXME: is it the right way to emulate NoStroke?
- cairo_set_line_width(m_data->cr, 0);
+ cairo_set_line_width(platformContext()->cr(), 0);
break;
case SolidStroke:
- cairo_set_dash(m_data->cr, 0, 0, 0);
+ cairo_set_dash(platformContext()->cr(), 0, 0, 0);
break;
case DottedStroke:
- cairo_set_dash(m_data->cr, dotPattern, 2, 0);
+ cairo_set_dash(platformContext()->cr(), dotPattern, 2, 0);
break;
case DashedStroke:
- cairo_set_dash(m_data->cr, dashPattern, 2, 0);
+ cairo_set_dash(platformContext()->cr(), dashPattern, 2, 0);
break;
}
}
@@ -859,7 +867,7 @@ void GraphicsContext::concatCTM(const AffineTransform& transform)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
const cairo_matrix_t matrix = cairo_matrix_t(transform);
cairo_transform(cr, &matrix);
m_data->concatCTM(transform);
@@ -870,7 +878,7 @@ void GraphicsContext::setCTM(const AffineTransform& transform)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
const cairo_matrix_t matrix = cairo_matrix_t(transform);
cairo_set_matrix(cr, &matrix);
m_data->setCTM(transform);
@@ -881,7 +889,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
clip(rect);
Path p;
@@ -928,7 +936,7 @@ void GraphicsContext::beginTransparencyLayer(float opacity)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_push_group(cr);
m_data->layers.append(opacity);
m_data->beginTransparencyLayer();
@@ -939,7 +947,7 @@ void GraphicsContext::endTransparencyLayer()
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_pop_group_to_source(cr);
cairo_paint_with_alpha(cr, m_data->layers.last());
@@ -952,7 +960,7 @@ void GraphicsContext::clearRect(const FloatRect& rect)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
@@ -966,7 +974,7 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float width)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
cairo_set_line_width(cr, width);
@@ -991,12 +999,12 @@ void GraphicsContext::setLineCap(LineCap lineCap)
cairoCap = CAIRO_LINE_CAP_SQUARE;
break;
}
- cairo_set_line_cap(m_data->cr, cairoCap);
+ cairo_set_line_cap(platformContext()->cr(), cairoCap);
}
void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
{
- cairo_set_dash(m_data->cr, dashes.data(), dashes.size(), dashOffset);
+ cairo_set_dash(platformContext()->cr(), dashes.data(), dashes.size(), dashOffset);
}
void GraphicsContext::setLineJoin(LineJoin lineJoin)
@@ -1016,7 +1024,7 @@ void GraphicsContext::setLineJoin(LineJoin lineJoin)
cairoJoin = CAIRO_LINE_JOIN_BEVEL;
break;
}
- cairo_set_line_join(m_data->cr, cairoJoin);
+ cairo_set_line_join(platformContext()->cr(), cairoJoin);
}
void GraphicsContext::setMiterLimit(float miter)
@@ -1024,7 +1032,7 @@ void GraphicsContext::setMiterLimit(float miter)
if (paintingDisabled())
return;
- cairo_set_miter_limit(m_data->cr, miter);
+ cairo_set_miter_limit(platformContext()->cr(), miter);
}
void GraphicsContext::setAlpha(float alpha)
@@ -1042,7 +1050,7 @@ void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
if (paintingDisabled())
return;
- cairo_set_operator(m_data->cr, toCairoOperator(op));
+ cairo_set_operator(platformContext()->cr(), toCairoOperator(op));
}
void GraphicsContext::clip(const Path& path)
@@ -1050,7 +1058,7 @@ void GraphicsContext::clip(const Path& path)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
OwnPtr<cairo_path_t> p(cairo_copy_path(path.platformPath()->context()));
cairo_append_path(cr, p.get());
cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
@@ -1070,7 +1078,7 @@ void GraphicsContext::clipOut(const Path& path)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
double x1, y1, x2, y2;
cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
@@ -1087,7 +1095,7 @@ void GraphicsContext::rotate(float radians)
if (paintingDisabled())
return;
- cairo_rotate(m_data->cr, radians);
+ cairo_rotate(platformContext()->cr(), radians);
m_data->rotate(radians);
}
@@ -1096,7 +1104,7 @@ void GraphicsContext::scale(const FloatSize& size)
if (paintingDisabled())
return;
- cairo_scale(m_data->cr, size.width(), size.height());
+ cairo_scale(platformContext()->cr(), size.width(), size.height());
m_data->scale(size);
}
@@ -1105,7 +1113,7 @@ void GraphicsContext::clipOut(const IntRect& r)
if (paintingDisabled())
return;
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
double x1, y1, x2, y2;
cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
@@ -1132,7 +1140,7 @@ void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft,
if (hasShadow())
m_data->shadow.drawRectShadow(this, r, topLeft, topRight, bottomLeft, bottomRight);
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_save(cr);
Path path;
path.addRoundedRect(r, topLeft, topRight, bottomLeft, bottomRight);
@@ -1170,7 +1178,7 @@ void GraphicsContext::setPlatformShouldAntialias(bool enable)
// When true, use the default Cairo backend antialias mode (usually this
// enables standard 'grayscale' antialiasing); false to explicitly disable
// antialiasing. This is the same strategy as used in drawConvexPolygon().
- cairo_set_antialias(m_data->cr, enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
+ cairo_set_antialias(platformContext()->cr(), enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
}
void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
@@ -1196,7 +1204,7 @@ void GraphicsContext::pushImageMask(cairo_surface_t* surface, const FloatRect& r
// We want to allow the clipped elements to composite with the surface as it
// is now, but they are isolated in another group. To make this work, we're
// going to blit the current surface contents onto the new group once we push it.
- cairo_t* cr = m_data->cr;
+ cairo_t* cr = platformContext()->cr();
cairo_surface_t* currentTarget = cairo_get_target(cr);
cairo_surface_flush(currentTarget);
diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
index 924f69a..2bc290b 100644
--- a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
@@ -31,6 +31,7 @@
#include "GraphicsContext.h"
#include "ContextShadow.h"
+#include "PlatformContextCairo.h"
#include "RefPtrCairo.h"
#include <cairo.h>
#include <math.h>
@@ -67,8 +68,8 @@ private:
class GraphicsContextPlatformPrivate {
public:
- GraphicsContextPlatformPrivate()
- : cr(0)
+ GraphicsContextPlatformPrivate(PlatformContextCairo* newPlatformContext)
+ : platformContext(newPlatformContext)
#if PLATFORM(GTK)
, expose(0)
#elif PLATFORM(WIN)
@@ -82,7 +83,6 @@ public:
~GraphicsContextPlatformPrivate()
{
- cairo_destroy(cr);
}
#if PLATFORM(WIN)
@@ -99,7 +99,7 @@ public:
void setCTM(const AffineTransform&);
void beginTransparencyLayer() { m_transparencyCount++; }
void endTransparencyLayer() { m_transparencyCount--; }
- void syncContext(PlatformGraphicsContext* cr);
+ void syncContext(cairo_t* cr);
#else
// On everything else, we do nothing.
void save() {}
@@ -114,12 +114,11 @@ public:
void setCTM(const AffineTransform&) {}
void beginTransparencyLayer() {}
void endTransparencyLayer() {}
- void syncContext(PlatformGraphicsContext* cr) {}
+ void syncContext(cairo_t* cr) {}
#endif
- cairo_t* cr;
+ PlatformContextCairo* platformContext;
Vector<float> layers;
-
ContextShadow shadow;
Vector<ContextShadow> shadowStack;
Vector<ImageMaskInformation> maskImageStack;
@@ -133,6 +132,23 @@ public:
#endif
};
+// This is a specialized private section for the Cairo GraphicsContext, which knows how
+// to clean up the heap allocated PlatformContextCairo that we must use for the top-level
+// GraphicsContext.
+class GraphicsContextPlatformPrivateToplevel : public GraphicsContextPlatformPrivate {
+public:
+ GraphicsContextPlatformPrivateToplevel(PlatformContextCairo* platformContext)
+ : GraphicsContextPlatformPrivate(platformContext)
+ {
+ }
+
+ ~GraphicsContextPlatformPrivateToplevel()
+ {
+ delete platformContext;
+ }
+};
+
+
} // namespace WebCore
#endif // GraphicsContextPlatformPrivateCairo_h
diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index 9ee8a94..1d5d492 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -37,7 +37,9 @@
#include "MIMETypeRegistry.h"
#include "NotImplemented.h"
#include "Pattern.h"
+#include "PlatformContextCairo.h"
#include "PlatformString.h"
+#include "RefPtrCairo.h"
#include <cairo.h>
#include <wtf/Vector.h>
@@ -66,6 +68,7 @@ namespace WebCore {
ImageBufferData::ImageBufferData(const IntSize& size)
: m_surface(0)
+ , m_platformContext(0)
{
}
@@ -80,9 +83,9 @@ ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, bool& s
if (cairo_surface_status(m_data.m_surface) != CAIRO_STATUS_SUCCESS)
return; // create will notice we didn't set m_initialized and fail.
- cairo_t* cr = cairo_create(m_data.m_surface);
- m_context.set(new GraphicsContext(cr));
- cairo_destroy(cr); // The context is now owned by the GraphicsContext.
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(m_data.m_surface));
+ m_data.m_platformContext.setCr(cr.get());
+ m_context.set(new GraphicsContext(&m_data.m_platformContext));
success = true;
}
@@ -301,7 +304,7 @@ static cairo_status_t writeFunction(void* closure, const unsigned char* data, un
String ImageBuffer::toDataURL(const String& mimeType, const double*) const
{
- cairo_surface_t* image = cairo_get_target(context()->platformContext());
+ cairo_surface_t* image = cairo_get_target(context()->platformContext()->cr());
if (!image)
return "data:,";
diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferData.h b/Source/WebCore/platform/graphics/cairo/ImageBufferData.h
index 49f15df..42867d1 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferData.h
@@ -26,7 +26,9 @@
#ifndef ImageBufferData_h
#define ImageBufferData_h
-#include "cairo.h"
+#include "PlatformContextCairo.h"
+
+typedef struct _cairo_surface cairo_surface_t;
namespace WebCore {
@@ -37,6 +39,7 @@ public:
ImageBufferData(const IntSize&);
cairo_surface_t* m_surface;
+ PlatformContextCairo m_platformContext;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp
index e51d65a..d3a52ce 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp
@@ -36,6 +36,7 @@
#include "ContextShadow.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
+#include "PlatformContextCairo.h"
#include "ImageBuffer.h"
#include "ImageObserver.h"
#include "RefPtrCairo.h"
@@ -114,7 +115,7 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
IntSize selfSize = size();
- cairo_t* cr = context->platformContext();
+ cairo_t* cr = context->platformContext()->cr();
context->save();
// Set the compositing operation.
@@ -169,8 +170,7 @@ void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, con
if (!image) // If it's too early we won't have an image yet.
return;
- cairo_t* cr = context->platformContext();
-
+ cairo_t* cr = context->platformContext()->cr();
drawPatternToCairoContext(cr, image, size(), tileRect, patternTransform, phase, toCairoOperator(op), destRect);
if (imageObserver())
diff --git a/Source/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp b/Source/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp
index 94f6809..1594e7b 100644
--- a/Source/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp
@@ -20,7 +20,7 @@
#include "config.h"
#include "OwnPtrCairo.h"
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
#include <cairo-ft.h>
#include <fontconfig/fcfreetype.h>
#endif
@@ -29,7 +29,7 @@
namespace WTF {
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
template <> void deleteOwnedPtr<FcObjectSet>(FcObjectSet* ptr)
{
if (ptr)
diff --git a/Source/WebCore/platform/graphics/cairo/OwnPtrCairo.h b/Source/WebCore/platform/graphics/cairo/OwnPtrCairo.h
index 035d80e..e1dd370 100644
--- a/Source/WebCore/platform/graphics/cairo/OwnPtrCairo.h
+++ b/Source/WebCore/platform/graphics/cairo/OwnPtrCairo.h
@@ -22,7 +22,7 @@
#include "OwnPtr.h"
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
typedef struct _FcObjectSet FcObjectSet;
typedef struct _FcFontSet FcFontSet;
#endif
@@ -31,7 +31,7 @@ typedef struct cairo_path cairo_path_t;
namespace WTF {
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
template <> void deleteOwnedPtr<FcObjectSet>(FcObjectSet*);
template <> void deleteOwnedPtr<FcFontSet>(FcFontSet*);
#endif
diff --git a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp
index 7a09a52..533df10 100644
--- a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp
@@ -281,7 +281,7 @@ FloatRect Path::boundingRect() const
return FloatRect(x0, y0, x1 - x0, y1 - y0);
}
-FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
{
cairo_t* cr = platformPath()->context();
if (applier) {
diff --git a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp
new file mode 100644
index 0000000..ba75162
--- /dev/null
+++ b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PlatformContextCairo.h"
+
+#include <cairo.h>
+
+namespace WebCore {
+
+PlatformContextCairo::PlatformContextCairo(cairo_t* cr)
+ : m_cr(cr)
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h
new file mode 100644
index 0000000..c6cceda
--- /dev/null
+++ b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PlatformContextCairo_h
+#define PlatformContextCairo_h
+
+#include "ContextShadow.h"
+#include "RefPtrCairo.h"
+
+namespace WebCore {
+
+// Much like PlatformContextSkia in the Skia port, this class holds information that
+// would normally be private to GraphicsContext, except that we want to allow access
+// to it in Font and Image code. This allows us to separate the concerns of Cairo-specific
+// code from the platform-independent GraphicsContext.
+
+class PlatformContextCairo {
+ WTF_MAKE_NONCOPYABLE(PlatformContextCairo);
+public:
+ PlatformContextCairo(cairo_t*);
+ cairo_t* cr() { return m_cr.get(); }
+ void setCr(cairo_t* cr) { m_cr = cr; }
+
+private:
+ RefPtr<cairo_t> m_cr;
+};
+
+} // namespace WebCore
+
+#endif // PlatformContextCairo_h
diff --git a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
index c8b242c..1792002 100644
--- a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
@@ -21,7 +21,7 @@
#include <cairo.h>
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
#include <cairo-ft.h>
#include <fontconfig/fcfreetype.h>
#endif
@@ -88,7 +88,7 @@ template<> void derefIfNotNull(cairo_pattern_t* ptr)
cairo_pattern_destroy(ptr);
}
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
template<> void refIfNotNull(FcPattern* ptr)
{
if (LIKELY(ptr != 0))
diff --git a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h
index 204d1e3..540f9dc 100644
--- a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h
+++ b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h
@@ -28,7 +28,7 @@ typedef struct _cairo_font_face cairo_font_face_t;
typedef struct _cairo_scaled_font cairo_scaled_font_t;
typedef struct _cairo_pattern cairo_pattern_t;
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
typedef struct _FcPattern FcPattern;
#endif
@@ -49,7 +49,7 @@ template<> void derefIfNotNull(cairo_scaled_font_t* ptr);
template<> void refIfNotNull(cairo_pattern_t*);
template<> void derefIfNotNull(cairo_pattern_t*);
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
template<> void refIfNotNull(FcPattern* ptr);
template<> void derefIfNotNull(FcPattern* ptr);
#endif
diff --git a/Source/WebCore/platform/graphics/cg/FontPlatformData.h b/Source/WebCore/platform/graphics/cg/FontPlatformData.h
deleted file mode 100644
index e21b444..0000000
--- a/Source/WebCore/platform/graphics/cg/FontPlatformData.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * This file is part of the internal font implementation. It should not be included by anyone other than
- * FontMac.cpp, FontWin.cpp and Font.cpp.
- *
- * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc.
- *
- * 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.
- *
- */
-
-#ifndef FontPlatformData_h
-#define FontPlatformData_h
-
-#include "FontOrientation.h"
-#include "RefCountedGDIHandle.h"
-#include "StringImpl.h"
-#include <wtf/Forward.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RetainPtr.h>
-
-typedef struct HFONT__* HFONT;
-typedef struct CGFont* CGFontRef;
-
-namespace WebCore {
-
-class FontDescription;
-
-class FontPlatformData {
-public:
- FontPlatformData()
- : m_size(0)
- , m_syntheticBold(false)
- , m_syntheticOblique(false)
- , m_useGDI(false)
- {
- }
-
- FontPlatformData(HFONT, float size, bool bold, bool oblique, bool useGDI);
- FontPlatformData(float size, bool bold, bool oblique);
-
- FontPlatformData(HFONT, CGFontRef, float size, bool bold, bool oblique, bool useGDI);
- ~FontPlatformData();
-
- FontPlatformData(WTF::HashTableDeletedValueType) : m_font(WTF::HashTableDeletedValue) { }
- bool isHashTableDeletedValue() const { return m_font.isHashTableDeletedValue(); }
-
- HFONT hfont() const { return m_font->handle(); }
- CGFontRef cgFont() const { return m_cgFont.get(); }
-
- float size() const { return m_size; }
- void setSize(float size) { m_size = size; }
- bool syntheticBold() const { return m_syntheticBold; }
- bool syntheticOblique() const { return m_syntheticOblique; }
- bool useGDI() const { return m_useGDI; }
-
- FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
-
- unsigned hash() const
- {
- return m_font->hash();
- }
-
- bool operator==(const FontPlatformData& other) const
- {
- return m_font == other.m_font
- && m_cgFont == other.m_cgFont
- && m_size == other.m_size
- && m_syntheticBold == other.m_syntheticBold
- && m_syntheticOblique == other.m_syntheticOblique
- && m_useGDI == other.m_useGDI;
- }
-
-#ifndef NDEBUG
- String description() const;
-#endif
-
-private:
- void platformDataInit(HFONT, float size, HDC, WCHAR* faceName);
-
- RefPtr<RefCountedGDIHandle<HFONT> > m_font;
- RetainPtr<CGFontRef> m_cgFont;
-
- float m_size;
- bool m_syntheticBold;
- bool m_syntheticOblique;
- bool m_useGDI;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index dbcab45..7799137 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -695,7 +695,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
if (m_state.fillPattern)
applyFillPattern();
- bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
+ bool drawOwnShadow = !isAcceleratedContext() && hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
if (drawOwnShadow) {
float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
// Turn off CG shadows.
@@ -724,7 +724,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
if (oldFillColor != color || oldColorSpace != colorSpace)
setCGFillColor(context, color, colorSpace);
- bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
+ bool drawOwnShadow = !isAcceleratedContext() && hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
if (drawOwnShadow) {
float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
// Turn off CG shadows.
@@ -759,7 +759,7 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
Path path;
path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
- bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
+ bool drawOwnShadow = !isAcceleratedContext() && hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
if (drawOwnShadow) {
float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
@@ -803,7 +803,7 @@ void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const Rounded
setFillColor(color, colorSpace);
// fillRectWithRoundedHole() assumes that the edges of rect are clipped out, so we only care about shadows cast around inside the hole.
- bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms;
+ bool drawOwnShadow = !isAcceleratedContext() && hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms;
if (drawOwnShadow) {
float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
@@ -929,8 +929,7 @@ void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, con
CGFloat smallEigenvalue = narrowPrecisionToCGFloat(sqrt(0.5 * ((A + D) - sqrt(4 * B * C + (A - D) * (A - D)))));
- // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp
- blurRadius = min(blur * smallEigenvalue, narrowPrecisionToCGFloat(1000.0));
+ blurRadius = blur * smallEigenvalue;
CGSize offsetInBaseSpace = CGSizeApplyAffineTransform(offset, userToBaseCTM);
@@ -938,6 +937,9 @@ void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, con
yOffset = offsetInBaseSpace.height;
}
+ // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp
+ blurRadius = min(blurRadius, narrowPrecisionToCGFloat(1000.0));
+
// Work around <rdar://problem/5539388> by ensuring that the offsets will get truncated
// to the desired integer.
static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128);
@@ -1343,14 +1345,30 @@ void GraphicsContext::setAllowsFontSmoothing(bool allowsFontSmoothing)
#endif
}
-void GraphicsContext::setIsCALayerContext(bool)
+void GraphicsContext::setIsCALayerContext(bool isLayerContext)
{
- m_data->m_isCALayerContext = true;
+ if (isLayerContext)
+ m_data->m_contextFlags |= IsLayerCGContext;
+ else
+ m_data->m_contextFlags &= ~IsLayerCGContext;
}
bool GraphicsContext::isCALayerContext() const
{
- return m_data->m_isCALayerContext;
+ return m_data->m_contextFlags & IsLayerCGContext;
+}
+
+void GraphicsContext::setIsAcceleratedContext(bool isAccelerated)
+{
+ if (isAccelerated)
+ m_data->m_contextFlags |= IsAcceleratedCGContext;
+ else
+ m_data->m_contextFlags &= ~IsAcceleratedCGContext;
+}
+
+bool GraphicsContext::isAcceleratedContext() const
+{
+ return m_data->m_contextFlags & IsAcceleratedCGContext;
}
void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode)
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
index f9255df..722f5a0 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
@@ -31,9 +31,16 @@
namespace WebCore {
+enum GraphicsContextCGFlag {
+ IsLayerCGContext = 1 << 0,
+ IsAcceleratedCGContext = 1 << 1
+};
+
+typedef unsigned GraphicsContextCGFlags;
+
class GraphicsContextPlatformPrivate {
public:
- GraphicsContextPlatformPrivate(CGContextRef cgContext, bool isLayerContext = false)
+ GraphicsContextPlatformPrivate(CGContextRef cgContext, GraphicsContextCGFlags flags = 0)
: m_cgContext(cgContext)
#if PLATFORM(WIN)
, m_hdc(0)
@@ -41,7 +48,7 @@ public:
, m_shouldIncludeChildWindows(false)
#endif
, m_userToDeviceTransformKnownToBeIdentity(false)
- , m_isCALayerContext(isLayerContext)
+ , m_contextFlags(flags)
{
}
@@ -87,7 +94,7 @@ public:
RetainPtr<CGContextRef> m_cgContext;
bool m_userToDeviceTransformKnownToBeIdentity;
- bool m_isCALayerContext;
+ GraphicsContextCGFlags m_contextFlags;
};
}
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index 7c8e313..3c8f959 100644
--- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -32,6 +32,7 @@
#include "BitmapImage.h"
#include "GraphicsContext.h"
#include "GraphicsContextCG.h"
+#include "ImageData.h"
#include "MIMETypeRegistry.h"
#include <ApplicationServices/ApplicationServices.h>
#include <wtf/Assertions.h>
@@ -498,21 +499,8 @@ static RetainPtr<CFStringRef> utiFromMIMEType(const String& mimeType)
#endif
}
-String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const
+static String CGImageToDataURL(CGImageRef image, const String& mimeType, const double* quality)
{
- ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
-
- RetainPtr<CGImageRef> image;
- if (!m_accelerateRendering)
- image.adoptCF(CGBitmapContextCreateImage(context()->platformContext()));
-#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- else
- image.adoptCF(wkIOSurfaceContextCreateImage(context()->platformContext()));
-#endif
-
- if (!image)
- return "data:,";
-
RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0));
if (!data)
return "data:,";
@@ -533,7 +521,7 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality) con
imageProperties.adoptCF(CFDictionaryCreate(0, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
}
- CGImageDestinationAddImage(destination.get(), image.get(), imageProperties.get());
+ CGImageDestinationAddImage(destination.get(), image, imageProperties.get());
CGImageDestinationFinalize(destination.get());
Vector<char> out;
@@ -541,4 +529,46 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality) con
return makeString("data:", mimeType, ";base64,", out);
}
+
+String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const
+{
+ ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
+
+ RetainPtr<CGImageRef> image;
+ if (!m_accelerateRendering)
+ image.adoptCF(CGBitmapContextCreateImage(context()->platformContext()));
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ else
+ image.adoptCF(wkIOSurfaceContextCreateImage(context()->platformContext()));
+#endif
+
+ if (!image)
+ return "data:,";
+
+ return CGImageToDataURL(image.get(), mimeType, quality);
+}
+
+String ImageDataToDataURL(const ImageData& source, const String& mimeType, const double* quality)
+{
+ ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
+
+ RetainPtr<CGImageRef> image;
+ RetainPtr<CGDataProviderRef> dataProvider;
+
+ dataProvider.adoptCF(CGDataProviderCreateWithData(0, source.data()->data()->data(),
+ 4 * source.width() * source.height(), 0));
+
+ if (!dataProvider)
+ return "data:,";
+
+ image.adoptCF(CGImageCreate(source.width(), source.height(), 8, 32, 4 * source.width(),
+ CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrderDefault | kCGImageAlphaLast,
+ dataProvider.get(), 0, false, kCGRenderingIntentDefault));
+
+
+ if (!image)
+ return "data:,";
+
+ return CGImageToDataURL(image.get(), mimeType, quality);
+}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cg/PathCG.cpp b/Source/WebCore/platform/graphics/cg/PathCG.cpp
index d6a1e6e..b8fc7d4 100644
--- a/Source/WebCore/platform/graphics/cg/PathCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/PathCG.cpp
@@ -166,7 +166,7 @@ FloatRect Path::boundingRect() const
return CGPathGetBoundingBox(m_path);
}
-FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
{
CGContextRef context = scratchContext();
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
index ad961aa..4cb119a 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
@@ -56,7 +56,7 @@ Canvas2DLayerChromium::~Canvas2DLayerChromium()
layerRendererContext()->deleteTexture(m_textureId);
}
-void Canvas2DLayerChromium::updateContentsIfDirty()
+void Canvas2DLayerChromium::updateCompositorResources()
{
if (!m_contentsDirty || !m_drawingBuffer)
return;
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
index a14cb98..81b118c 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
@@ -46,7 +46,7 @@ public:
static PassRefPtr<Canvas2DLayerChromium> create(DrawingBuffer*, GraphicsLayerChromium* owner);
virtual ~Canvas2DLayerChromium();
virtual bool drawsContent() const { return true; }
- virtual void updateContentsIfDirty();
+ virtual void updateCompositorResources();
void setTextureChanged();
unsigned textureId() const;
@@ -55,8 +55,6 @@ public:
private:
explicit Canvas2DLayerChromium(DrawingBuffer*, GraphicsLayerChromium* owner);
DrawingBuffer* m_drawingBuffer;
-
- static unsigned m_shaderProgramId;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
index 0264868..f306207 100644
--- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
@@ -40,8 +40,6 @@
namespace WebCore {
-unsigned CanvasLayerChromium::m_shaderProgramId = 0;
-
CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
, m_textureChanged(true)
@@ -54,22 +52,18 @@ CanvasLayerChromium::~CanvasLayerChromium()
{
}
-void CanvasLayerChromium::draw()
+PassRefPtr<CCLayerImpl> CanvasLayerChromium::createCCLayerImpl()
{
- ASSERT(layerRenderer());
- const CanvasLayerChromium::Program* program = layerRenderer()->canvasLayerProgram();
- ASSERT(program && program->initialized());
- GraphicsContext3D* context = layerRendererContext();
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));
- GC3Denum sfactor = m_premultipliedAlpha ? GraphicsContext3D::ONE : GraphicsContext3D::SRC_ALPHA;
- GLC(context, context->blendFunc(sfactor, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
- layerRenderer()->useShader(program->program());
- GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(),
- bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(),
- program->vertexShader().matrixLocation(),
- program->fragmentShader().alphaLocation());
+ return CCCanvasLayerImpl::create(this);
+}
+
+void CanvasLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
+{
+ LayerChromium::pushPropertiesTo(layer);
+
+ CCCanvasLayerImpl* canvasLayer = static_cast<CCCanvasLayerImpl*>(layer);
+ canvasLayer->setTextureId(m_textureId);
+ canvasLayer->setPremultipliedAlpha(m_premultipliedAlpha);
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
index ed3a06f..cb2ccc9 100644
--- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
@@ -43,9 +43,9 @@ class CanvasLayerChromium : public LayerChromium {
public:
virtual ~CanvasLayerChromium();
- virtual void draw();
+ virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
- typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
+ virtual void pushPropertiesTo(CCLayerImpl*);
protected:
explicit CanvasLayerChromium(GraphicsLayerChromium* owner);
@@ -55,9 +55,6 @@ protected:
bool m_textureChanged;
unsigned m_textureId;
bool m_premultipliedAlpha;
-
-private:
- static unsigned m_shaderProgramId;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
index 78f93d5..4ea9c92 100644
--- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -66,7 +66,7 @@ void ContentLayerChromium::cleanupResources()
m_contentsTexture.clear();
}
-bool ContentLayerChromium::requiresClippedUpdateRect() const
+bool ContentLayerChromium::requiresClippedUpdateRect()
{
// To avoid allocating excessively large textures, switch into "large layer mode" if
// one of the layer's dimensions is larger than 2000 pixels or the size of
@@ -77,7 +77,7 @@ bool ContentLayerChromium::requiresClippedUpdateRect() const
|| !layerRenderer()->checkTextureSize(bounds()));
}
-void ContentLayerChromium::updateContentsIfDirty()
+void ContentLayerChromium::paintContentsIfDirty()
{
RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
if (!backing || backing->paintingGoesToWindow())
@@ -93,34 +93,25 @@ void ContentLayerChromium::updateContentsIfDirty()
// FIXME: Remove this test when tiled layers are implemented.
if (requiresClippedUpdateRect()) {
- // A layer with 3D transforms could require an arbitrarily large number
- // of texels to be repainted, so ignore these layers until tiling is
- // implemented.
- if (!ccLayerImpl()->drawTransform().isIdentityOrTranslation()) {
- m_skipsDraw = true;
- return;
- }
-
// Calculate the region of this layer that is currently visible.
const IntRect clipRect = ccLayerImpl()->targetRenderSurface()->contentRect();
TransformationMatrix layerOriginTransform = ccLayerImpl()->drawTransform();
layerOriginTransform.translate3d(-0.5 * bounds().width(), -0.5 * bounds().height(), 0);
- // For now we apply the large layer treatment only for layers that are either untransformed
- // or are purely translated. Their matrix is expected to be invertible.
- ASSERT(layerOriginTransform.isInvertible());
-
+ // We compute the visible portion of the layer by back-mapping the current RenderSurface
+ // content area to the layer. To do that, we invert the drawing matrix of the layer
+ // and project the content area rectangle to it. If the layer transform is not invertible
+ // then we skip rendering the layer.
+ if (!layerOriginTransform.isInvertible()) {
+ m_skipsDraw = true;
+ return;
+ }
TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse();
- IntRect visibleRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect);
+ FloatQuad mappedClipToLayer = targetToLayerMatrix.projectQuad(FloatRect(clipRect));
+ IntRect visibleRectInLayerCoords = mappedClipToLayer.enclosingBoundingBox();
visibleRectInLayerCoords.intersect(IntRect(0, 0, bounds().width(), bounds().height()));
- // For normal layers, the center of the texture corresponds with the center of the layer.
- // In large layers the center of the texture is the center of the visible region so we have
- // to keep track of the offset in order to render correctly.
- IntRect visibleRectInSurfaceCoords = layerOriginTransform.mapRect(visibleRectInLayerCoords);
- m_layerCenterInSurfaceCoords = FloatRect(visibleRectInSurfaceCoords).center();
-
// If this is still too large to render, then skip the layer completely.
if (!layerRenderer()->checkTextureSize(visibleRectInLayerCoords.size())) {
m_skipsDraw = true;
@@ -256,9 +247,14 @@ void ContentLayerChromium::draw()
GLC(context, context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
if (requiresClippedUpdateRect()) {
- float m43 = ccLayerImpl()->drawTransform().m43();
- TransformationMatrix transform;
- transform.translate3d(m_layerCenterInSurfaceCoords.x(), m_layerCenterInSurfaceCoords.y(), m43);
+ // Compute the offset between the layer's center point and the center of the visible portion
+ // of the layer.
+ FloatPoint visibleRectCenterOffset = FloatRect(m_visibleRectInLayerCoords).center();
+ visibleRectCenterOffset.move(-0.5 * bounds().width(), -0.5 * bounds().height());
+
+ TransformationMatrix transform = ccLayerImpl()->drawTransform();
+ transform.translate(visibleRectCenterOffset.x(), visibleRectCenterOffset.y());
+
drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
transform, m_visibleRectInLayerCoords.width(),
m_visibleRectInLayerCoords.height(), ccLayerImpl()->drawOpacity(),
@@ -273,6 +269,11 @@ void ContentLayerChromium::draw()
unreserveContentsTexture();
}
+void ContentLayerChromium::updateCompositorResources()
+{
+ updateTextureIfNeeded();
+}
+
void ContentLayerChromium::unreserveContentsTexture()
{
if (!m_skipsDraw && m_contentsTexture)
@@ -281,8 +282,6 @@ void ContentLayerChromium::unreserveContentsTexture()
void ContentLayerChromium::bindContentsTexture()
{
- updateTextureIfNeeded();
-
if (!m_skipsDraw && m_contentsTexture)
m_contentsTexture->bindTexture();
}
diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
index 6f070c2..cf296ab 100644
--- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
@@ -50,7 +50,8 @@ public:
virtual ~ContentLayerChromium();
- virtual void updateContentsIfDirty();
+ virtual void paintContentsIfDirty();
+ virtual void updateCompositorResources();
virtual void unreserveContentsTexture();
virtual void bindContentsTexture();
@@ -63,7 +64,7 @@ protected:
explicit ContentLayerChromium(GraphicsLayerChromium* owner);
virtual void cleanupResources();
- bool requiresClippedUpdateRect() const;
+ bool requiresClippedUpdateRect();
void resizeUploadBuffer(const IntSize&);
virtual const char* layerTypeAsString() const { return "ContentLayer"; }
@@ -82,7 +83,6 @@ private:
PlatformCanvas m_canvas;
IntRect m_visibleRectInLayerCoords;
- FloatPoint m_layerCenterInSurfaceCoords;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm b/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
index 227fbe4..b442d53 100644
--- a/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
+++ b/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
@@ -29,7 +29,7 @@
#import "config.h"
#import "CrossProcessFontLoading.h"
-#import "../graphics/cocoa/FontPlatformData.h"
+#import "../graphics/FontPlatformData.h"
#import "PlatformBridge.h"
#import <AppKit/NSFont.h>
#import <wtf/HashMap.h>
diff --git a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
index d956841..e559edb 100644
--- a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -46,10 +46,6 @@
namespace WebCore {
-#if ENABLE(SKIA_GPU)
-extern GrContext* GetGlobalGrContext();
-#endif
-
struct DrawingBufferInternal {
unsigned offscreenColorTexture;
#if USE(ACCELERATED_COMPOSITING)
@@ -91,6 +87,9 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
, m_multisampleFBO(0)
, m_multisampleColorBuffer(0)
, m_internal(new DrawingBufferInternal)
+#if ENABLE(SKIA_GPU)
+ , m_grContext(0)
+#endif
{
if (!m_context->getExtensions()->supports("GL_CHROMIUM_copy_texture_to_parent_texture")) {
m_context.clear();
@@ -137,7 +136,8 @@ void DrawingBuffer::publishToPlatformLayer()
// would insert a fence into the child command stream that the compositor could wait for.
m_context->makeContextCurrent();
#if ENABLE(SKIA_GPU)
- GetGlobalGrContext()->flush(false);
+ if (m_grContext)
+ m_grContext->flush(0);
#endif
static_cast<Extensions3DChromium*>(m_context->getExtensions())->copyTextureToParentTextureCHROMIUM(m_colorBuffer, parentTexture);
m_context->flush();
@@ -166,4 +166,13 @@ Platform3DObject DrawingBuffer::platformColorBuffer() const
return m_colorBuffer;
}
+#if ENABLE(SKIA_GPU)
+void DrawingBuffer::setGrContext(GrContext* context)
+{
+ // We just take a ptr without referencing it, as we require that we never outlive
+ // the SharedGraphicsContext3D object that is giving us the context.
+ m_grContext = context;
+}
+#endif
+
}
diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
index bbe6d62..598ae86 100644
--- a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
@@ -153,7 +153,8 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
fontDescription.computedSize(),
(style & SkTypeface::kBold) && !tf->isBold(),
(style & SkTypeface::kItalic) && !tf->isItalic(),
- fontDescription.orientation());
+ fontDescription.orientation(),
+ fontDescription.textOrientation());
tf->unref();
return result;
}
diff --git a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index e57a84c..3c254dc 100644
--- a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -196,7 +196,7 @@ class TransparencyAwareGlyphPainter : public TransparencyAwareFontPainter {
// left of m_point. We express it this way so that if we're using the Skia
// drawing path we can use floating-point positioning, even though we have
// to use integer positioning in the GDI path.
- bool drawGlyphs(int numGlyphs, const WORD* glyphs, const int* advances, int startAdvance) const;
+ bool drawGlyphs(int numGlyphs, const WORD* glyphs, const int* advances, float startAdvance) const;
private:
virtual IntRect estimateTextBounds();
@@ -256,11 +256,11 @@ IntRect TransparencyAwareGlyphPainter::estimateTextBounds()
bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
const WORD* glyphs,
const int* advances,
- int startAdvance) const
+ float startAdvance) const
{
if (!m_useGDI) {
SkPoint origin = m_point;
- origin.fX += startAdvance;
+ origin.fX += SkFloatToScalar(startAdvance);
return paintSkiaText(m_graphicsContext, m_font->platformData().hfont(),
numGlyphs, glyphs, advances, 0, &origin);
}
@@ -400,17 +400,25 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
Vector<WORD, kMaxBufferLength> glyphs;
Vector<int, kMaxBufferLength> advances;
int glyphIndex = 0; // The starting glyph of the current chunk.
- int curAdvance = 0; // How far from the left the current chunk is.
+
+ // In order to round all offsets to the correct pixel boundary, this code keeps track of the absolute position
+ // of each glyph in floating point units and rounds to integer advances at the last possible moment.
+
+ float horizontalOffset = point.x(); // The floating point offset of the left side of the current glyph.
+ int lastHorizontalOffsetRounded = lroundf(horizontalOffset); // The rounded offset of the left side of the last glyph rendered.
while (glyphIndex < numGlyphs) {
// How many chars will be in this chunk?
int curLen = std::min(kMaxBufferLength, numGlyphs - glyphIndex);
glyphs.resize(curLen);
advances.resize(curLen);
- int curWidth = 0;
+ float currentWidth = 0;
for (int i = 0; i < curLen; ++i, ++glyphIndex) {
glyphs[i] = glyphBuffer.glyphAt(from + glyphIndex);
- advances[i] = static_cast<int>(glyphBuffer.advanceAt(from + glyphIndex));
+ horizontalOffset += glyphBuffer.advanceAt(from + glyphIndex);
+ advances[i] = lroundf(horizontalOffset) - lastHorizontalOffsetRounded;
+ lastHorizontalOffsetRounded += advances[i];
+ currentWidth += glyphBuffer.advanceAt(from + glyphIndex);
// Bug 26088 - very large positive or negative runs can fail to
// render so we clamp the size here. In the specs, negative
@@ -420,15 +428,14 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
// -32830, so we give ourselves a little breathing room.
const int maxNegativeRun = -32768;
const int maxPositiveRun = 32768;
- if ((curWidth + advances[i] < maxNegativeRun) || (curWidth + advances[i] > maxPositiveRun))
+ if ((currentWidth + advances[i] < maxNegativeRun) || (currentWidth + advances[i] > maxPositiveRun))
advances[i] = 0;
- curWidth += advances[i];
}
// Actually draw the glyphs (with retry on failure).
bool success = false;
for (int executions = 0; executions < 2; ++executions) {
- success = painter.drawGlyphs(curLen, &glyphs[0], &advances[0], curAdvance);
+ success = painter.drawGlyphs(curLen, &glyphs[0], &advances[0], horizontalOffset - point.x() - currentWidth);
if (!success && executions == 0) {
// Ask the browser to load the font for us and retry.
PlatformBridge::ensureFontLoaded(font->platformData().hfont());
@@ -439,8 +446,6 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
if (!success)
LOG_ERROR("Unable to draw the glyphs after second attempt");
-
- curAdvance += curWidth;
}
}
@@ -509,8 +514,7 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
// Uniscribe counts the coordinates from the upper left, while WebKit uses
// the baseline, so we have to subtract off the ascent.
- state.draw(graphicsContext, hdc, static_cast<int>(point.x()),
- static_cast<int>(point.y() - fontMetrics().ascent()), from, to);
+ state.draw(graphicsContext, hdc, lroundf(point.x()), lroundf(point.y() - fontMetrics().ascent()), from, to);
context->canvas()->endPlatformPaint();
}
diff --git a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp
index 823dbc9..3c4a494 100644
--- a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -98,7 +98,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
SkPoint* vPosBegin = storage2.get();
SkPoint* vPosEnd = storage3.get();
- bool isVertical = font->orientation() == Vertical;
+ bool isVertical = font->platformData().orientation() == Vertical;
for (int i = 0; i < numGlyphs; i++) {
SkScalar myWidth = SkFloatToScalar(adv[i].width());
pos[i].set(x, y);
diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h b/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
index b6ebb2e..84edebc 100644
--- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
+++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
@@ -71,6 +71,7 @@ public:
float size() const { return m_size; }
FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
+ void setOrientation(FontOrientation) { } // FIXME: Implement.
unsigned hash() const
{
@@ -105,7 +106,7 @@ private:
HFONT hfont() const { return m_hfont; }
unsigned hash() const
{
- return WTF::StringHasher::createBlobHash<sizeof(HFONT)>(&m_hfont);
+ return StringHasher::hashMemory<sizeof(HFONT)>(&m_hfont);
}
bool operator==(const RefCountedHFONT& other) const
diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index 6f9009f..c3edfac 100644
--- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -76,13 +76,14 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src)
, m_fakeBold(src.m_fakeBold)
, m_fakeItalic(src.m_fakeItalic)
, m_orientation(src.m_orientation)
+ , m_textOrientation(src.m_textOrientation)
, m_style(src.m_style)
, m_harfbuzzFace(src.m_harfbuzzFace)
{
SkSafeRef(m_typeface);
}
-FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation)
+FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation, TextOrientation textOrientation)
: m_typeface(tf)
, m_family(family)
, m_textSize(textSize)
@@ -90,6 +91,7 @@ FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float tex
, m_fakeBold(fakeBold)
, m_fakeItalic(fakeItalic)
, m_orientation(orientation)
+ , m_textOrientation(textOrientation)
{
SkSafeRef(m_typeface);
querySystemForRenderStyle();
@@ -102,6 +104,8 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
, m_emSizeInFontUnits(src.m_emSizeInFontUnits)
, m_fakeBold(src.m_fakeBold)
, m_fakeItalic(src.m_fakeItalic)
+ , m_orientation(src.m_orientation)
+ , m_textOrientation(src.m_textOrientation)
, m_harfbuzzFace(src.m_harfbuzzFace)
{
SkSafeRef(m_typeface);
@@ -134,6 +138,7 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
m_fakeItalic = src.m_fakeItalic;
m_harfbuzzFace = src.m_harfbuzzFace;
m_orientation = src.m_orientation;
+ m_textOrientation = src.m_textOrientation;
m_style = src.m_style;
m_emSizeInFontUnits = src.m_emSizeInFontUnits;
@@ -199,13 +204,14 @@ bool FontPlatformData::operator==(const FontPlatformData& a) const
&& m_fakeBold == a.m_fakeBold
&& m_fakeItalic == a.m_fakeItalic
&& m_orientation == a.m_orientation
+ && m_textOrientation == a.m_textOrientation
&& m_style == a.m_style;
}
unsigned FontPlatformData::hash() const
{
unsigned h = SkTypeface::UniqueID(m_typeface);
- h ^= 0x01010101 * ((static_cast<int>(m_orientation) << 2) | (static_cast<int>(m_fakeBold) << 1) | static_cast<int>(m_fakeItalic));
+ h ^= 0x01010101 * ((static_cast<int>(m_textOrientation) << 3) | (static_cast<int>(m_orientation) << 2) | (static_cast<int>(m_fakeBold) << 1) | static_cast<int>(m_fakeItalic));
// This memcpy is to avoid a reinterpret_cast that breaks strict-aliasing
// rules. Memcpy is generally optimized enough so that performance doesn't
diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
index d9ebb61..541aa86 100644
--- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
+++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
@@ -33,6 +33,7 @@
#include "FontOrientation.h"
#include "FontRenderStyle.h"
+#include "TextOrientation.h"
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
#include <wtf/text/CString.h>
@@ -66,6 +67,8 @@ public:
, m_emSizeInFontUnits(0)
, m_fakeBold(false)
, m_fakeItalic(false)
+ , m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
{ }
FontPlatformData()
@@ -75,6 +78,7 @@ public:
, m_fakeBold(false)
, m_fakeItalic(false)
, m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
{ }
FontPlatformData(float textSize, bool fakeBold, bool fakeItalic)
@@ -84,10 +88,11 @@ public:
, m_fakeBold(fakeBold)
, m_fakeItalic(fakeItalic)
, m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
{ }
FontPlatformData(const FontPlatformData&);
- FontPlatformData(SkTypeface*, const char* name, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation = Horizontal);
+ FontPlatformData(SkTypeface*, const char* name, float textSize, bool fakeBold, bool fakeItalic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight);
FontPlatformData(const FontPlatformData& src, float textSize);
~FontPlatformData();
@@ -113,7 +118,8 @@ public:
int emSizeInFontUnits() const;
FontOrientation orientation() const { return m_orientation; }
-
+ void setOrientation(FontOrientation orientation) { m_orientation = orientation; }
+
bool operator==(const FontPlatformData&) const;
FontPlatformData& operator=(const FontPlatformData&);
bool isHashTableDeletedValue() const { return m_typeface == hashTableDeletedFontValue(); }
@@ -161,6 +167,7 @@ private:
bool m_fakeBold;
bool m_fakeItalic;
FontOrientation m_orientation;
+ TextOrientation m_textOrientation;
FontRenderStyle m_style;
mutable RefPtr<RefCountedHarfbuzzFace> m_harfbuzzFace;
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index 2ff6b8b..cc5a060 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -62,29 +62,51 @@ typedef void (GLAPIENTRY *TESSCB)();
typedef WTF::Vector<float> FloatVector;
typedef WTF::Vector<double> DoubleVector;
+struct PathAndTransform {
+ PathAndTransform(const Path& p, const AffineTransform& t)
+ : path(p)
+ , transform(t)
+ {
+ }
+ Path path;
+ AffineTransform transform;
+};
+
struct GLES2Canvas::State {
State()
: m_fillColor(0, 0, 0, 255)
+ , m_shadowColor(0, 0, 0, 0)
, m_alpha(1.0f)
, m_compositeOp(CompositeSourceOver)
- , m_clippingEnabled(false)
+ , m_numClippingPaths(0)
+ , m_shadowOffset(0, 0)
+ , m_shadowBlur(0)
+ , m_shadowsIgnoreTransforms(false)
{
}
State(const State& other)
: m_fillColor(other.m_fillColor)
+ , m_shadowColor(other.m_shadowColor)
, m_alpha(other.m_alpha)
, m_compositeOp(other.m_compositeOp)
, m_ctm(other.m_ctm)
, m_clippingPaths() // Don't copy; clipping paths are tracked per-state.
- , m_clippingEnabled(other.m_clippingEnabled)
+ , m_numClippingPaths(other.m_numClippingPaths)
+ , m_shadowOffset(other.m_shadowOffset)
+ , m_shadowBlur(other.m_shadowBlur)
+ , m_shadowsIgnoreTransforms(other.m_shadowsIgnoreTransforms)
{
}
Color m_fillColor;
+ Color m_shadowColor;
float m_alpha;
CompositeOperator m_compositeOp;
AffineTransform m_ctm;
- WTF::Vector<Path> m_clippingPaths;
- bool m_clippingEnabled;
+ WTF::Vector<PathAndTransform> m_clippingPaths;
+ int m_numClippingPaths;
+ FloatSize m_shadowOffset;
+ float m_shadowBlur;
+ bool m_shadowsIgnoreTransforms;
// Helper function for applying the state's alpha value to the given input
// color to produce a new output color. The logic is the same as
@@ -100,7 +122,11 @@ struct GLES2Canvas::State {
int a = (c.alpha() * s) >> 8;
return Color(c.red(), c.green(), c.blue(), a);
}
-
+ bool shadowActive() const
+ {
+ return m_shadowColor.alpha() > 0 && (m_shadowBlur || m_shadowOffset.width() || m_shadowOffset.height());
+ }
+ bool clippingEnabled() { return m_numClippingPaths > 0; }
};
static inline FloatPoint operator*(const FloatPoint& f, float scale)
@@ -193,12 +219,8 @@ void GLES2Canvas::bindFramebuffer()
void GLES2Canvas::clearRect(const FloatRect& rect)
{
bindFramebuffer();
- if (m_state->m_ctm.isIdentity() && !m_state->m_clippingEnabled) {
- m_context->scissor(rect.x(), m_size.height() - rect.height() - rect.y(), rect.width(), rect.height());
- m_context->enable(GraphicsContext3D::SCISSOR_TEST);
- m_context->clearColor(Color(RGBA32(0)));
- m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
- m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+ if (m_state->m_ctm.isIdentity() && !m_state->clippingEnabled()) {
+ scissorClear(rect.x(), rect.y(), rect.width(), rect.height());
} else {
save();
setCompositeOperation(CompositeClear);
@@ -207,35 +229,66 @@ void GLES2Canvas::clearRect(const FloatRect& rect)
}
}
+void GLES2Canvas::scissorClear(float x, float y, float width, float height)
+{
+ int intX = static_cast<int>(x + 0.5f);
+ int intY = static_cast<int>(y + 0.5f);
+ int intWidth = static_cast<int>(x + width + 0.5f) - intX;
+ int intHeight = static_cast<int>(y + height + 0.5f) - intY;
+ m_context->scissor(intX, m_size.height() - intHeight - intY, intWidth, intHeight);
+ m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+ m_context->clearColor(Color(RGBA32(0)));
+ m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
+ m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+}
+
void GLES2Canvas::fillPath(const Path& path)
{
+ if (m_state->shadowActive()) {
+ beginShadowDraw();
+ fillPathInternal(path, m_state->m_shadowColor);
+ endShadowDraw(path.boundingRect());
+ }
+
+ bindFramebuffer();
m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->m_clippingEnabled);
- fillPath(path, m_state->applyAlpha(m_state->m_fillColor));
+ applyClipping(m_state->clippingEnabled());
+
+ fillPathInternal(path, m_state->applyAlpha(m_state->m_fillColor));
}
void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
{
+ if (m_state->shadowActive()) {
+ beginShadowDraw();
+ fillRectInternal(rect, m_state->m_shadowColor);
+ endShadowDraw(rect);
+ }
+
+ bindFramebuffer();
m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->m_clippingEnabled);
- m_context->useQuadVertices();
+ applyClipping(m_state->clippingEnabled());
+
+ fillRectInternal(rect, color);
+}
+
+void GLES2Canvas::fillRect(const FloatRect& rect)
+{
+ fillRect(rect, m_state->applyAlpha(m_state->m_fillColor), ColorSpaceDeviceRGB);
+}
+void GLES2Canvas::fillRectInternal(const FloatRect& rect, const Color& color)
+{
AffineTransform matrix(m_flipMatrix);
matrix *= m_state->m_ctm;
matrix.translate(rect.x(), rect.y());
matrix.scale(rect.width(), rect.height());
+ m_context->useQuadVertices();
m_context->useFillSolidProgram(matrix, color);
-
- bindFramebuffer();
m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
}
-void GLES2Canvas::fillRect(const FloatRect& rect)
-{
- fillRect(rect, m_state->applyAlpha(m_state->m_fillColor), ColorSpaceDeviceRGB);
-}
-
void GLES2Canvas::setFillColor(const Color& color, ColorSpace colorSpace)
{
m_state->m_fillColor = color;
@@ -246,6 +299,26 @@ void GLES2Canvas::setAlpha(float alpha)
m_state->m_alpha = alpha;
}
+void GLES2Canvas::setShadowColor(const Color& color, ColorSpace)
+{
+ m_state->m_shadowColor = color;
+}
+
+void GLES2Canvas::setShadowOffset(const FloatSize& offset)
+{
+ m_state->m_shadowOffset = offset;
+}
+
+void GLES2Canvas::setShadowBlur(float shadowBlur)
+{
+ m_state->m_shadowBlur = shadowBlur;
+}
+
+void GLES2Canvas::setShadowsIgnoreTransforms(bool shadowsIgnoreTransforms)
+{
+ m_state->m_shadowsIgnoreTransforms = shadowsIgnoreTransforms;
+}
+
void GLES2Canvas::translate(float x, float y)
{
m_state->m_ctm.translate(x, y);
@@ -275,12 +348,12 @@ void GLES2Canvas::clipPath(const Path& path)
{
bindFramebuffer();
checkGLError("bindFramebuffer");
- beginStencilDraw();
+ beginStencilDraw(GraphicsContext3D::INCR);
// Red is used so we can see it if it ends up in the color buffer.
Color red(255, 0, 0, 255);
- fillPath(path, red);
- m_state->m_clippingPaths.append(path);
- m_state->m_clippingEnabled = true;
+ fillPathInternal(path, red);
+ m_state->m_clippingPaths.append(PathAndTransform(path, m_state->m_ctm));
+ m_state->m_numClippingPaths++;
}
void GLES2Canvas::clipOut(const Path& path)
@@ -297,53 +370,48 @@ void GLES2Canvas::save()
void GLES2Canvas::restore()
{
ASSERT(!m_stateStack.isEmpty());
- bool hadClippingPaths = !m_state->m_clippingPaths.isEmpty();
- m_stateStack.removeLast();
- m_state = &m_stateStack.last();
- if (hadClippingPaths) {
- m_context->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
- beginStencilDraw();
- StateVector::const_iterator iter;
- for (iter = m_stateStack.begin(); iter < m_stateStack.end(); ++iter) {
- const State& state = *iter;
- const Vector<Path>& clippingPaths = state.m_clippingPaths;
- Vector<Path>::const_iterator pathIter;
- for (pathIter = clippingPaths.begin(); pathIter < clippingPaths.end(); ++pathIter) {
- // Red is used so we can see it if it ends up in the color buffer.
- Color red(255, 0, 0, 255);
- fillPath(*pathIter, red);
- }
+ const Vector<PathAndTransform>& clippingPaths = m_state->m_clippingPaths;
+ if (!clippingPaths.isEmpty()) {
+ beginStencilDraw(GraphicsContext3D::DECR);
+ WTF::Vector<PathAndTransform>::const_iterator pathIter;
+ for (pathIter = clippingPaths.begin(); pathIter < clippingPaths.end(); ++pathIter) {
+ m_state->m_ctm = pathIter->transform;
+ // Red is used so we can see it if it ends up in the color buffer.
+ Color red(255, 0, 0, 255);
+ fillPathInternal(pathIter->path, red);
}
}
+ m_stateStack.removeLast();
+ m_state = &m_stateStack.last();
}
void GLES2Canvas::drawTexturedRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
{
+ bindFramebuffer();
m_context->applyCompositeOperator(compositeOp);
applyClipping(false);
- m_context->useQuadVertices();
m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
- drawQuad(textureSize, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha);
+ drawTexturedQuad(textureSize, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha);
}
void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
{
- drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp, m_state->m_clippingEnabled);
+ drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp, m_state->clippingEnabled());
}
void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha, ColorSpace colorSpace, CompositeOperator compositeOp, bool clip)
{
+ bindFramebuffer();
m_context->applyCompositeOperator(compositeOp);
applyClipping(clip);
const TilingData& tiles = texture->tiles();
IntRect tileIdxRect = tiles.overlappedTileIndices(srcRect);
- m_context->useQuadVertices();
m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
for (int y = tileIdxRect.y(); y <= tileIdxRect.maxY(); y++) {
@@ -367,13 +435,18 @@ void GLES2Canvas::drawTexturedRectTile(Texture* texture, int tile, const FloatRe
IntRect tileBoundsWithBorder = tiles.tileBoundsWithBorder(tile);
- drawQuad(tileBoundsWithBorder.size(), srcRectClippedInTileSpace, dstRectIntersected, transform, alpha);
+ drawTexturedQuad(tileBoundsWithBorder.size(), srcRectClippedInTileSpace, dstRectIntersected, transform, alpha);
}
-void GLES2Canvas::drawQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha)
+void GLES2Canvas::convolveRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, float imageIncrement[2], const float* kernel, int kernelWidth)
{
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
+ 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);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST);
+
AffineTransform matrix(m_flipMatrix);
- matrix *= transform;
matrix.translate(dstRect.x(), dstRect.y());
matrix.scale(dstRect.width(), dstRect.height());
@@ -382,13 +455,79 @@ void GLES2Canvas::drawQuad(const IntSize& textureSize, const FloatRect& srcRect,
texMatrix.translate(srcRect.x(), srcRect.y());
texMatrix.scale(srcRect.width(), srcRect.height());
- bindFramebuffer();
+ m_context->useQuadVertices();
+ m_context->useConvolutionProgram(matrix, texMatrix, kernel, kernelWidth, imageIncrement);
+ m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
+ checkGLError("glDrawArrays");
+}
+static float gauss(float x, float sigma)
+{
+ return exp(- (x * x) / (2.0f * sigma * sigma));
+}
+
+static void buildKernel(float sigma, float* kernel, int kernelWidth)
+{
+ float halfWidth = (kernelWidth - 1.0f) / 2.0f;
+ float sum = 0.0f;
+ for (int i = 0; i < kernelWidth; ++i) {
+ kernel[i] = gauss(i - halfWidth, sigma);
+ sum += kernel[i];
+ }
+ // Normalize the kernel
+ float scale = 1.0f / sum;
+ for (int i = 0; i < kernelWidth; ++i)
+ kernel[i] *= scale;
+}
+
+void GLES2Canvas::drawTexturedQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha)
+{
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= transform;
+ matrix.translate(dstRect.x(), dstRect.y());
+ matrix.scale(dstRect.width(), dstRect.height());
+
+ AffineTransform texMatrix;
+ texMatrix.scale(1.0f / textureSize.width(), 1.0f / textureSize.height());
+ texMatrix.translate(srcRect.x(), srcRect.y());
+ texMatrix.scale(srcRect.width(), srcRect.height());
+
+ m_context->useQuadVertices();
m_context->useTextureProgram(matrix, texMatrix, alpha);
m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
checkGLError("glDrawArrays");
}
+void GLES2Canvas::drawTexturedQuadMitchell(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha)
+{
+ static const float mitchellCoefficients[16] = {
+ 0.0f / 18.0f, 1.0f / 18.0f, 16.0f / 18.0f, 1.0f / 18.0f,
+ 0.0f / 18.0f, 9.0f / 18.0f, 0.0f / 18.0f, -9.0f / 18.0f,
+ -6.0f / 18.0f, 27.0f / 18.0f, -36.0f / 18.0f, 15.0f / 18.0f,
+ 7.0f / 18.0f, -21.0f / 18.0f, 21.0f / 18.0f, -7.0f / 18.0f,
+ };
+
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= transform;
+ matrix.translate(dstRect.x(), dstRect.y());
+ matrix.scale(dstRect.width(), dstRect.height());
+
+ float imageIncrement[2] = { 1.0f / textureSize.width(), 1.0f / textureSize.height() };
+
+ AffineTransform texMatrix;
+ texMatrix.scale(imageIncrement[0], imageIncrement[1]);
+ texMatrix.translate(srcRect.x(), srcRect.y());
+ texMatrix.scale(srcRect.width(), srcRect.height());
+
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST);
+
+ m_context->useQuadVertices();
+ m_context->useBicubicProgram(matrix, texMatrix, mitchellCoefficients, imageIncrement, alpha);
+ m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
+ checkGLError("glDrawArrays");
+}
+
void GLES2Canvas::setCompositeOperation(CompositeOperator op)
{
m_state->m_compositeOp = op;
@@ -554,12 +693,9 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
*count = indices.size();
}
-void GLES2Canvas::fillPath(const Path& path, const Color& color)
+void GLES2Canvas::fillPathInternal(const Path& path, const Color& color)
{
if (SharedGraphicsContext3D::useLoopBlinnForPathRendering()) {
- bindFramebuffer();
- m_context->applyCompositeOperator(m_state->m_compositeOp);
-
m_pathCache.clear();
LoopBlinnPathProcessor processor;
processor.process(path, m_pathCache);
@@ -590,18 +726,18 @@ void GLES2Canvas::fillPath(const Path& path, const Color& color)
int count;
unsigned vertexBuffer, indexBuffer;
createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer);
+
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= m_state->m_ctm;
+
m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer);
checkGLError("bindBuffer");
m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer);
checkGLError("bindBuffer");
- AffineTransform matrix(m_flipMatrix);
- matrix *= m_state->m_ctm;
-
m_context->useFillSolidProgram(matrix, color);
checkGLError("useFillSolidProgram");
- bindFramebuffer();
m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0);
checkGLError("drawArrays");
@@ -613,7 +749,141 @@ void GLES2Canvas::fillPath(const Path& path, const Color& color)
}
}
-void GLES2Canvas::beginStencilDraw()
+FloatRect GLES2Canvas::flipRect(const FloatRect& rect)
+{
+ FloatRect flippedRect(rect);
+ flippedRect.setY(m_size.height() - rect.y());
+ flippedRect.setHeight(-rect.height());
+ return flippedRect;
+}
+
+void GLES2Canvas::clearBorders(const FloatRect& rect, int width)
+{
+ scissorClear(rect.x(), rect.y() - width, rect.width() + width, width);
+ scissorClear(rect.maxX(), rect.y(), width, rect.height() + width);
+ scissorClear(rect.x() - width, rect.maxY(), rect.width() + width, width);
+ scissorClear(rect.x() - width, rect.y() - width, width, rect.height() + width);
+}
+
+void GLES2Canvas::beginShadowDraw()
+{
+ float offsetX = m_state->m_shadowOffset.width();
+ float offsetY = m_state->m_shadowOffset.height();
+ save();
+ if (m_state->m_shadowsIgnoreTransforms) {
+ AffineTransform newCTM;
+ newCTM.translate(offsetX, -offsetY);
+ newCTM *= m_state->m_ctm;
+ m_state->m_ctm = newCTM;
+ } else
+ m_state->m_ctm.translate(offsetX, offsetY);
+
+ if (m_state->m_shadowBlur > 0) {
+ // Draw hard shadow to offscreen buffer 0.
+ DrawingBuffer* dstBuffer = m_context->getOffscreenBuffer(0, m_size);
+ dstBuffer->bind();
+ m_context->applyCompositeOperator(CompositeCopy);
+ applyClipping(false);
+ m_context->clearColor(Color(RGBA32(0)));
+ m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
+ } else {
+ bindFramebuffer();
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->clippingEnabled());
+ }
+}
+
+void GLES2Canvas::endShadowDraw(const FloatRect& boundingBox)
+{
+ if (m_state->m_shadowBlur > 0) {
+ // Buffer 0 contains the primitive drawn with a hard shadow.
+ DrawingBuffer* srcBuffer = m_context->getOffscreenBuffer(0, m_size);
+ DrawingBuffer* dstBuffer = m_context->getOffscreenBuffer(1, m_size);
+
+ float sigma = m_state->m_shadowBlur * 0.333333f;
+ FloatRect shadowBoundingBox(m_state->m_ctm.mapRect(boundingBox));
+ FloatRect rect(FloatPoint(0, 0), m_size);
+ FloatRect srcRect(shadowBoundingBox);
+
+ int scaleFactor = 1;
+ while (sigma > cMaxSigma) {
+ srcRect.scale(0.5f);
+ scaleFactor *= 2;
+ sigma *= 0.5f;
+ }
+ srcRect = enclosingIntRect(srcRect);
+ srcRect.scale(scaleFactor);
+ for (int i = 1; i < scaleFactor; i *= 2) {
+ dstBuffer->bind();
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, srcBuffer->colorBuffer());
+ 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);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+ FloatRect dstRect(srcRect);
+ dstRect.scale(0.5f);
+ // Clear out 1 pixel border for linear filtering.
+ clearBorders(dstRect, 1);
+ drawTexturedQuad(srcBuffer->size(), flipRect(srcRect), dstRect, AffineTransform(), 1.0);
+ srcRect = dstRect;
+ std::swap(srcBuffer, dstBuffer);
+ }
+
+ int halfWidth = static_cast<int>(sigma * 3.0f);
+ int kernelWidth = halfWidth * 2 + 1;
+ OwnArrayPtr<float> kernel = adoptArrayPtr(new float[kernelWidth]);
+ buildKernel(sigma, kernel.get(), kernelWidth);
+
+ if (scaleFactor > 1) {
+ scissorClear(srcRect.maxX(), srcRect.y(), kernelWidth, srcRect.height());
+ scissorClear(srcRect.x() - kernelWidth, srcRect.y(), kernelWidth, srcRect.height());
+ }
+
+ // Blur in X offscreen.
+ dstBuffer->bind();
+ srcRect.inflateX(halfWidth);
+ srcRect.intersect(rect);
+ float imageIncrementX[2] = {1.0f / srcBuffer->size().width(), 0.0f};
+ convolveRect(srcBuffer->colorBuffer(), srcBuffer->size(), flipRect(srcRect), srcRect, imageIncrementX, kernel.get(), kernelWidth);
+
+ if (scaleFactor > 1) {
+ scissorClear(srcRect.x(), srcRect.maxY(), srcRect.width(), kernelWidth);
+ scissorClear(srcRect.x(), srcRect.y() - kernelWidth, srcRect.width(), kernelWidth);
+ }
+ srcRect.inflateY(halfWidth);
+ srcRect.intersect(rect);
+ std::swap(srcBuffer, dstBuffer);
+
+ float imageIncrementY[2] = {0.0f, 1.0f / srcBuffer->size().height()};
+ if (scaleFactor > 1) {
+ // Blur in Y offscreen.
+ dstBuffer->bind();
+ convolveRect(srcBuffer->colorBuffer(), srcBuffer->size(), flipRect(srcRect), srcRect, imageIncrementY, kernel.get(), kernelWidth);
+ // Clear out 2 pixel border for bicubic filtering.
+ clearBorders(srcRect, 2);
+ std::swap(srcBuffer, dstBuffer);
+
+ // Upsample srcBuffer -> main framebuffer using bicubic filtering.
+ bindFramebuffer();
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->clippingEnabled());
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, srcBuffer->colorBuffer());
+ FloatRect dstRect = srcRect;
+ dstRect.scale(scaleFactor);
+ drawTexturedQuadMitchell(srcBuffer->size(), flipRect(srcRect), dstRect, AffineTransform(), 1.0);
+ } else {
+ // Blur in Y directly to framebuffer.
+ bindFramebuffer();
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->clippingEnabled());
+
+ convolveRect(srcBuffer->colorBuffer(), srcBuffer->size(), flipRect(srcRect), srcRect, imageIncrementY, kernel.get(), kernelWidth);
+ }
+ }
+ restore();
+}
+
+void GLES2Canvas::beginStencilDraw(unsigned op)
{
// Turn on stencil test.
m_context->enableStencil(true);
@@ -624,9 +894,7 @@ void GLES2Canvas::beginStencilDraw()
checkGLError("stencilFunc");
// All writes incremement the stencil buffer.
- m_context->graphicsContext3D()->stencilOp(GraphicsContext3D::INCR,
- GraphicsContext3D::INCR,
- GraphicsContext3D::INCR);
+ m_context->graphicsContext3D()->stencilOp(op, op, op);
checkGLError("stencilOp");
}
@@ -635,7 +903,7 @@ void GLES2Canvas::applyClipping(bool enable)
m_context->enableStencil(enable);
if (enable) {
// Enable drawing only where stencil is non-zero.
- m_context->graphicsContext3D()->stencilFunc(GraphicsContext3D::EQUAL, m_state->m_clippingPaths.size() % 256, 1);
+ m_context->graphicsContext3D()->stencilFunc(GraphicsContext3D::EQUAL, m_state->m_numClippingPaths, -1);
checkGLError("stencilFunc");
// Keep all stencil values the same.
m_context->graphicsContext3D()->stencilOp(GraphicsContext3D::KEEP,
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
index 8887a16..f6a8bcf 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -64,6 +64,10 @@ public:
void clearRect(const FloatRect&);
void setFillColor(const Color&, ColorSpace);
void setAlpha(float alpha);
+ void setShadowColor(const Color&, ColorSpace);
+ void setShadowOffset(const FloatSize&);
+ void setShadowBlur(float);
+ void setShadowsIgnoreTransforms(bool);
void setCompositeOperation(CompositeOperator);
void translate(float x, float y);
void rotate(float angleInRadians);
@@ -96,12 +100,21 @@ public:
DrawingBuffer* drawingBuffer() const { return m_drawingBuffer; }
private:
+ void scissorClear(float x, float y, float width, float height);
void drawTexturedRectTile(Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
- void drawQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
+ void drawTexturedQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
+ void drawTexturedQuadMitchell(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
+ void convolveRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, float imageIncrement[2], const float* kernel, int kernelWidth);
+
void applyCompositeOperator(CompositeOperator);
void createVertexBufferFromPath(const Path&, int* count, unsigned* vertexBuffer, unsigned* indexBuffer);
- void fillPath(const Path&, const Color&);
- void beginStencilDraw();
+ void fillPathInternal(const Path&, const Color&);
+ void fillRectInternal(const FloatRect&, const Color&);
+ FloatRect flipRect(const FloatRect&);
+ void clearBorders(const FloatRect&, int width);
+ void beginShadowDraw();
+ void endShadowDraw(const FloatRect& boundingBox);
+ void beginStencilDraw(unsigned op);
void applyClipping(bool enable);
void checkGLError(const char* header);
diff --git a/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
index ee2b5ab..cfc1754 100644
--- a/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
@@ -36,8 +36,8 @@
#include "GlyphPageTreeNode.h"
#include "PlatformBridge.h"
#include "SimpleFontData.h"
+#include "SystemInfo.h"
#include "UniscribeHelperTextRun.h"
-#include "WindowsVersion.h"
namespace WebCore {
@@ -134,7 +134,7 @@ static bool fillBMPGlyphs(unsigned offset,
bool haveGlyphs = false;
int invalidGlyph = 0xFFFF;
const DWORD cffTableTag = 0x20464643; // 4-byte identifier for OpenType CFF table ('CFF ').
- if (!isVistaOrNewer() && !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && (GetFontData(dc, cffTableTag, 0, 0, 0) == GDI_ERROR))
+ if ((windowsVersion() < WindowsVista) && !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && (GetFontData(dc, cffTableTag, 0, 0, 0) == GDI_ERROR))
invalidGlyph = 0x1F;
Glyph spaceGlyph = 0; // Glyph for a space. Lazily filled.
diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index 7c42366..60c1332 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -60,7 +60,7 @@ void ImageLayerChromium::setContents(Image* contents)
setNeedsDisplay();
}
-void ImageLayerChromium::updateContentsIfDirty()
+void ImageLayerChromium::paintContentsIfDirty()
{
ASSERT(layerRenderer());
@@ -68,7 +68,7 @@ void ImageLayerChromium::updateContentsIfDirty()
if (requiresClippedUpdateRect()) {
// Use the base version of updateContents which draws a subset of the
// image to a bitmap, as the pixel contents can't be uploaded directly.
- ContentLayerChromium::updateContentsIfDirty();
+ ContentLayerChromium::paintContentsIfDirty();
return;
}
diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
index cc9064d..6addabc 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
@@ -50,7 +50,7 @@ class ImageLayerChromium : public ContentLayerChromium {
public:
static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0);
- virtual void updateContentsIfDirty();
+ virtual void paintContentsIfDirty();
virtual bool drawsContent() const { return m_contents; }
void setContents(Image* image);
diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 95b7386..bc28239 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -62,6 +62,7 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
: m_owner(owner)
, m_contentsDirty(false)
, m_maskLayer(0)
+ , m_ccLayerImpl(0)
, m_superlayer(0)
#ifndef NDEBUG
, m_debugID(s_nextLayerDebugID++)
@@ -77,7 +78,7 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
, m_opaque(true)
, m_geometryFlipped(false)
, m_needsDisplayOnBoundsChange(false)
- , m_ccLayerImpl(CCLayerImpl::create(this))
+ , m_doubleSided(true)
, m_replicaLayer(0)
{
}
@@ -94,7 +95,8 @@ LayerChromium::~LayerChromium()
void LayerChromium::cleanupResources()
{
- m_ccLayerImpl->cleanupResources();
+ if (m_ccLayerImpl)
+ m_ccLayerImpl->cleanupResources();
}
void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
@@ -105,8 +107,7 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
cleanupResources();
setNeedsDisplay();
}
-
- m_ccLayerImpl->setLayerRenderer(renderer);
+ m_layerRenderer = renderer;
}
void LayerChromium::setNeedsCommit()
@@ -188,7 +189,7 @@ void LayerChromium::setBounds(const IntSize& size)
bool firstResize = !bounds().width() && !bounds().height() && size.width() && size.height();
- m_ccLayerImpl->setBounds(size);
+ m_bounds = size;
if (firstResize)
setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height()));
@@ -240,7 +241,6 @@ LayerChromium* LayerChromium::superlayer() const
void LayerChromium::setName(const String& name)
{
m_name = name;
- m_ccLayerImpl->setName(name);
}
void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect)
@@ -288,6 +288,29 @@ void LayerChromium::toGLMatrix(float* flattened, const TransformationMatrix& m)
flattened[15] = m.m44();
}
+void LayerChromium::pushPropertiesTo(CCLayerImpl* layer)
+{
+ layer->setAnchorPoint(m_anchorPoint);
+ layer->setAnchorPointZ(m_anchorPointZ);
+ layer->setBounds(m_bounds);
+ layer->setDebugBorderColor(m_debugBorderColor);
+ layer->setDebugBorderWidth(m_debugBorderWidth);
+ layer->setDoubleSided(m_doubleSided);
+ layer->setLayerRenderer(m_layerRenderer.get());
+ layer->setMasksToBounds(m_masksToBounds);
+ layer->setName(m_name);
+ layer->setOpacity(m_opacity);
+ layer->setPosition(m_position);
+ layer->setPreserves3D(preserves3D());
+ layer->setSublayerTransform(m_sublayerTransform);
+ layer->setTransform(m_transform);
+
+ if (maskLayer())
+ maskLayer()->pushPropertiesTo(layer->maskLayer());
+ if (replicaLayer())
+ replicaLayer()->pushPropertiesTo(layer->replicaLayer());
+}
+
GraphicsContext3D* LayerChromium::layerRendererContext() const
{
ASSERT(layerRenderer());
@@ -316,31 +339,6 @@ void LayerChromium::drawTexturedQuad(GraphicsContext3D* context, const Transform
GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0));
}
-
-
-// Returns true if any of the layer's descendants has drawable content.
-bool LayerChromium::descendantsDrawContent()
-{
- const Vector<RefPtr<LayerChromium> >& sublayers = getSublayers();
- for (size_t i = 0; i < sublayers.size(); ++i)
- if (sublayers[i]->descendantsDrawContentRecursive())
- return true;
- return false;
-}
-
-// Returns true if either this layer or one of its descendants has drawable content.
-bool LayerChromium::descendantsDrawContentRecursive()
-{
- if (drawsContent())
- return true;
-
- const Vector<RefPtr<LayerChromium> >& sublayers = getSublayers();
- for (size_t i = 0; i < sublayers.size(); ++i)
- if (sublayers[i]->descendantsDrawContentRecursive())
- return true;
- return false;
-}
-
String LayerChromium::layerTreeAsText() const
{
TextStream ts;
@@ -359,7 +357,8 @@ void LayerChromium::dumpLayer(TextStream& ts, int indent) const
writeIndent(ts, indent);
ts << layerTypeAsString() << "(" << m_name << ")\n";
dumpLayerProperties(ts, indent+2);
- m_ccLayerImpl->dumpLayerProperties(ts, indent+2);
+ if (m_ccLayerImpl)
+ m_ccLayerImpl->dumpLayerProperties(ts, indent+2);
if (m_replicaLayer) {
writeIndent(ts, indent+2);
ts << "Replica:\n";
@@ -385,48 +384,38 @@ void LayerChromium::dumpLayerProperties(TextStream& ts, int indent) const
}
-// Begin calls that forward to the CCLayerImpl.
-// ==============================================
-// These exists just for debugging (via drawDebugBorder()).
-void LayerChromium::setBorderColor(const Color& color)
+PassRefPtr<CCLayerImpl> LayerChromium::createCCLayerImpl()
{
- m_ccLayerImpl->setDebugBorderColor(color);
- setNeedsCommit();
+ return CCLayerImpl::create(this);
}
-Color LayerChromium::borderColor() const
+void LayerChromium::createCCLayerImplIfNeeded()
{
- return m_ccLayerImpl->debugBorderColor();
+ if (!m_ccLayerImpl)
+ m_ccLayerImpl = createCCLayerImpl();
}
-void LayerChromium::setBorderWidth(float width)
+CCLayerImpl* LayerChromium::ccLayerImpl()
{
- m_ccLayerImpl->setDebugBorderWidth(width);
- setNeedsCommit();
+ return m_ccLayerImpl.get();
}
-float LayerChromium::borderWidth() const
-{
- return m_ccLayerImpl->debugBorderWidth();
-}
-
-LayerRendererChromium* LayerChromium::layerRenderer() const
+void LayerChromium::setBorderColor(const Color& color)
{
- return m_ccLayerImpl->layerRenderer();
+ m_debugBorderColor = color;
+ setNeedsCommit();
}
-void LayerChromium::setDoubleSided(bool doubleSided)
+void LayerChromium::setBorderWidth(float width)
{
- m_ccLayerImpl->setDoubleSided(doubleSided);
+ m_debugBorderWidth = width;
setNeedsCommit();
}
-const IntSize& LayerChromium::bounds() const
+LayerRendererChromium* LayerChromium::layerRenderer() const
{
- return m_ccLayerImpl->bounds();
+ return m_layerRenderer.get();
}
-// ==============================================
-// End calls that forward to the CCLayerImpl.
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerChromium.h
index 29a2165..428ce61 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -89,6 +89,9 @@ public:
void setBackgroundColor(const Color& color) { m_backgroundColor = color; setNeedsCommit(); }
Color backgroundColor() const { return m_backgroundColor; }
+ void setBounds(const IntSize&);
+ const IntSize& bounds() const { return m_bounds; }
+
void setClearsContext(bool clears) { m_clearsContext = clears; setNeedsCommit(); }
bool clearsContext() const { return m_clearsContext; }
@@ -133,6 +136,9 @@ public:
void setTransform(const TransformationMatrix& transform) { m_transform = transform; setNeedsCommit(); }
const TransformationMatrix& transform() const { return m_transform; }
+ bool doubleSided() const { return m_doubleSided; }
+ void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); }
+
// FIXME: This setting is currently ignored.
void setGeometryFlipped(bool flipped) { m_geometryFlipped = flipped; setNeedsCommit(); }
bool geometryFlipped() const { return m_geometryFlipped; }
@@ -143,9 +149,6 @@ public:
// in the LayerRendererChromium.
virtual void setLayerRenderer(LayerRendererChromium*);
- // Returns true if any of the layer's descendants has content to draw.
- bool descendantsDrawContent();
-
void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; }
void setReplicaLayer(LayerChromium* layer) { m_replicaLayer = layer; }
@@ -153,14 +156,14 @@ public:
// These methods typically need to be overwritten by derived classes.
virtual bool drawsContent() const { return false; }
- virtual void updateContentsIfDirty() { }
+ virtual void paintContentsIfDirty() { }
+ virtual void updateCompositorResources() { }
virtual void unreserveContentsTexture() { }
virtual void bindContentsTexture() { }
virtual void draw() { }
// These exists just for debugging (via drawDebugBorder()).
void setBorderColor(const Color&);
- Color borderColor() const;
#ifndef NDEBUG
int debugID() const { return m_debugID; }
@@ -170,21 +173,19 @@ public:
String layerTreeAsText() const;
void setBorderWidth(float);
- float borderWidth() const;
// Everything from here down in the public section will move to CCLayerImpl.
-
- CCLayerImpl* ccLayerImpl() const { return m_ccLayerImpl.get(); }
+ CCLayerImpl* ccLayerImpl();
+ void createCCLayerImplIfNeeded();
static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix,
float width, float height, float opacity,
int matrixLocation, int alphaLocation);
+ virtual void pushPropertiesTo(CCLayerImpl*);
+
// Begin calls that forward to the CCLayerImpl.
LayerRendererChromium* layerRenderer() const;
- void setDoubleSided(bool);
- void setBounds(const IntSize&);
- const IntSize& bounds() const;
// End calls that forward to the CCLayerImpl.
typedef ProgramBinding<VertexShaderPos, FragmentShaderColor> BorderProgram;
@@ -217,6 +218,11 @@ protected:
static const unsigned s_positionAttribLocation;
static const unsigned s_texCoordAttribLocation;
+ // Constructs a CCLayerImpl of the correct runtime type for this LayerChromium type.
+ virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
+
+ // For now, the LayerChromium directly owns its CCLayerImpl.
+ RefPtr<CCLayerImpl> m_ccLayerImpl;
private:
void setNeedsCommit();
@@ -233,19 +239,22 @@ private:
// This should only be called from removeFromSuperlayer.
void removeSublayer(LayerChromium*);
- bool descendantsDrawContentRecursive();
-
Vector<RefPtr<LayerChromium> > m_sublayers;
LayerChromium* m_superlayer;
+ RefPtr<LayerRendererChromium> m_layerRenderer;
+
#ifndef NDEBUG
int m_debugID;
#endif
// Layer properties.
+ IntSize m_bounds;
FloatPoint m_position;
FloatPoint m_anchorPoint;
Color m_backgroundColor;
+ Color m_debugBorderColor;
+ float m_debugBorderWidth;
float m_opacity;
float m_zPosition;
float m_anchorPointZ;
@@ -255,13 +264,12 @@ private:
bool m_opaque;
bool m_geometryFlipped;
bool m_needsDisplayOnBoundsChange;
+ bool m_doubleSided;
TransformationMatrix m_transform;
TransformationMatrix m_sublayerTransform;
FloatRect m_frame;
- // For now, the LayerChromium directly owns its CCLayerImpl.
- RefPtr<CCLayerImpl> m_ccLayerImpl;
// Replica layer used for reflections.
LayerChromium* m_replicaLayer;
diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index e7b299f..fc15abd 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -36,6 +36,7 @@
#include "cc/CCLayerImpl.h"
#include "Canvas2DLayerChromium.h"
+#include "FloatQuad.h"
#include "GeometryBinding.h"
#include "GraphicsContext3D.h"
#include "LayerChromium.h"
@@ -43,6 +44,7 @@
#include "NotImplemented.h"
#include "TextStream.h"
#include "TextureManager.h"
+#include "TraceEvent.h"
#include "WebGLLayerChromium.h"
#include "cc/CCLayerImpl.h"
#if USE(SKIA)
@@ -91,21 +93,23 @@ bool LayerRendererChromium::compareLayerZ(const CCLayerImpl* a, const CCLayerImp
return a->drawDepth() < b->drawDepth();
}
-PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context)
+PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint)
{
if (!context)
return 0;
- RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(context)));
+ RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(context, contentPaint, scrollbarPaint)));
if (!layerRenderer->hardwareCompositing())
return 0;
return layerRenderer.release();
}
-LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context)
- : m_rootLayer(0)
- , m_scrollPosition(IntPoint(-1, -1))
+LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint)
+ : m_viewportScrollPosition(IntPoint(-1, -1))
+ , m_rootLayer(0)
+ , m_rootLayerContentPaint(contentPaint)
+ , m_rootLayerScrollbarPaint(scrollbarPaint)
, m_currentShader(0)
, m_currentRenderSurface(0)
, m_offscreenFramebufferId(0)
@@ -114,8 +118,8 @@ LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> conte
, m_defaultRenderSurface(0)
{
m_hardwareCompositing = initializeSharedObjects();
- m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
- ASSERT(m_rootLayerTiler);
+ m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
+ ASSERT(m_rootLayerContentTiler);
m_headsUpDisplay = CCHeadsUpDisplay::create(this);
}
@@ -146,129 +150,149 @@ void LayerRendererChromium::useShader(unsigned programId)
}
}
-IntRect LayerRendererChromium::verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect)
+IntRect LayerRendererChromium::verticalScrollbarRect() const
{
- IntRect verticalScrollbar(IntPoint(contentRect.maxX(), contentRect.y()), IntSize(visibleRect.width() - contentRect.width(), visibleRect.height()));
+ IntRect verticalScrollbar(IntPoint(m_viewportContentRect.maxX(), m_viewportContentRect.y()), IntSize(m_viewportVisibleRect.width() - m_viewportContentRect.width(), m_viewportVisibleRect.height()));
return verticalScrollbar;
}
-IntRect LayerRendererChromium::horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect)
+IntRect LayerRendererChromium::horizontalScrollbarRect() const
{
- IntRect horizontalScrollbar(IntPoint(contentRect.x(), contentRect.maxY()), IntSize(visibleRect.width(), visibleRect.height() - contentRect.height()));
+ IntRect horizontalScrollbar(IntPoint(m_viewportContentRect.x(), m_viewportContentRect.maxY()), IntSize(m_viewportVisibleRect.width(), m_viewportVisibleRect.height() - m_viewportContentRect.height()));
return horizontalScrollbar;
}
-void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect)
+void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect)
{
- m_rootLayerTiler->invalidateRect(dirtyRect);
+ m_rootLayerContentTiler->invalidateRect(dirtyRect);
+
+ // Scrollbars never need to render beyond the fold, so clip to the viewport.
+ IntRect visibleDirtyRect = dirtyRect;
+ visibleDirtyRect.intersect(m_viewportVisibleRect);
+
if (m_horizontalScrollbarTiler) {
- IntRect scrollbar = horizontalScrollbarRect(visibleRect, contentRect);
- if (dirtyRect.intersects(scrollbar)) {
+ IntRect scrollbar = horizontalScrollbarRect();
+ if (visibleDirtyRect.intersects(scrollbar)) {
m_horizontalScrollbarTiler->setLayerPosition(scrollbar.location());
- m_horizontalScrollbarTiler->invalidateRect(dirtyRect);
+ m_horizontalScrollbarTiler->invalidateRect(visibleDirtyRect);
}
}
if (m_verticalScrollbarTiler) {
- IntRect scrollbar = verticalScrollbarRect(visibleRect, contentRect);
- if (dirtyRect.intersects(scrollbar)) {
+ IntRect scrollbar = verticalScrollbarRect();
+ if (visibleDirtyRect.intersects(scrollbar)) {
m_verticalScrollbarTiler->setLayerPosition(scrollbar.location());
- m_verticalScrollbarTiler->invalidateRect(dirtyRect);
+ m_verticalScrollbarTiler->invalidateRect(visibleDirtyRect);
}
}
}
-void LayerRendererChromium::updateRootLayerContents(TilePaintInterface& tilePaint, const IntRect& visibleRect)
+void LayerRendererChromium::updateRootLayerContents()
{
- m_rootLayerTiler->update(tilePaint, visibleRect);
+ TRACE_EVENT("LayerRendererChromium::updateRootLayerContents", this, 0);
+ m_rootLayerContentTiler->update(*m_rootLayerContentPaint, m_viewportVisibleRect);
}
-void LayerRendererChromium::updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect)
+void LayerRendererChromium::updateRootLayerScrollbars()
{
- if (visibleRect.width() > contentRect.width()) {
- IntRect verticalScrollbar = verticalScrollbarRect(visibleRect, contentRect);
+ TRACE_EVENT("LayerRendererChromium::updateRootLayerScrollbars", this, 0);
+ if (m_viewportVisibleRect.width() > m_viewportContentRect.width()) {
+ IntRect verticalScrollbar = verticalScrollbarRect();
IntSize tileSize = verticalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
if (!m_verticalScrollbarTiler)
m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels);
else
m_verticalScrollbarTiler->setTileSize(tileSize);
m_verticalScrollbarTiler->setLayerPosition(verticalScrollbar.location());
- m_verticalScrollbarTiler->update(scrollbarPaint, visibleRect);
+ m_verticalScrollbarTiler->update(*m_rootLayerScrollbarPaint, m_viewportVisibleRect);
} else
m_verticalScrollbarTiler.clear();
- if (visibleRect.height() > contentRect.height()) {
- IntRect horizontalScrollbar = horizontalScrollbarRect(visibleRect, contentRect);
+ if (m_viewportVisibleRect.height() > m_viewportContentRect.height()) {
+ IntRect horizontalScrollbar = horizontalScrollbarRect();
IntSize tileSize = horizontalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
if (!m_horizontalScrollbarTiler)
m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels);
else
m_horizontalScrollbarTiler->setTileSize(tileSize);
m_horizontalScrollbarTiler->setLayerPosition(horizontalScrollbar.location());
- m_horizontalScrollbarTiler->update(scrollbarPaint, visibleRect);
+ m_horizontalScrollbarTiler->update(*m_rootLayerScrollbarPaint, m_viewportVisibleRect);
} else
m_horizontalScrollbarTiler.clear();
}
void LayerRendererChromium::drawRootLayer()
{
- m_rootLayerTiler->draw(m_visibleRect);
+ m_rootLayerContentTiler->draw(m_viewportVisibleRect);
if (m_verticalScrollbarTiler)
- m_verticalScrollbarTiler->draw(m_visibleRect);
+ m_verticalScrollbarTiler->draw(m_viewportVisibleRect);
if (m_horizontalScrollbarTiler)
- m_horizontalScrollbarTiler->draw(m_visibleRect);
+ m_horizontalScrollbarTiler->draw(m_viewportVisibleRect);
+}
+
+void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition)
+{
+ bool visibleRectChanged = m_viewportVisibleRect.size() != visibleRect.size();
+
+ m_viewportVisibleRect = visibleRect;
+ m_viewportContentRect = contentRect;
+ m_viewportScrollPosition = scrollPosition;
+
+ if (visibleRectChanged) {
+ // Reset the current render surface to force an update of the viewport and
+ // projection matrix next time useRenderSurface is called.
+ m_currentRenderSurface = 0;
+
+ m_rootLayerContentTiler->invalidateEntireLayer();
+ if (m_horizontalScrollbarTiler)
+ m_horizontalScrollbarTiler->invalidateEntireLayer();
+ if (m_verticalScrollbarTiler)
+ m_verticalScrollbarTiler->invalidateEntireLayer();
+ }
}
-void LayerRendererChromium::updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
- TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint)
+void LayerRendererChromium::updateAndDrawLayers()
{
ASSERT(m_hardwareCompositing);
if (!m_rootLayer)
return;
- updateRootLayerContents(tilePaint, visibleRect);
+ updateRootLayerContents();
+
// Recheck that we still have a root layer. This may become null if
// compositing gets turned off during a paint operation.
if (!m_rootLayer)
return;
- updateRootLayerScrollbars(scrollbarPaint, visibleRect, contentRect);
+ updateRootLayerScrollbars();
Vector<CCLayerImpl*> renderSurfaceLayerList;
- updateLayers(visibleRect, contentRect, scrollPosition, renderSurfaceLayerList);
+ updateLayers(renderSurfaceLayerList);
drawLayers(renderSurfaceLayerList);
+
+ if (isCompositingOffscreen())
+ copyOffscreenTextureToDisplay();
}
-void LayerRendererChromium::updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
- Vector<CCLayerImpl*>& renderSurfaceLayerList)
+void LayerRendererChromium::updateLayers(Vector<CCLayerImpl*>& renderSurfaceLayerList)
{
+ TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0);
+ m_rootLayer->createCCLayerImplIfNeeded();
CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
if (!rootDrawLayer->renderSurface())
rootDrawLayer->createRenderSurface();
ASSERT(rootDrawLayer->renderSurface());
- // If the size of the visible area has changed then allocate a new texture
- // to store the contents of the root layer and adjust the projection matrix
- // and viewport.
-
- rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), visibleRect.size());
+ rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), m_viewportVisibleRect.size());
- if (visibleRect.size() != m_visibleRect.size()) {
- // Reset the current render surface to force an update of the viewport and
- // projection matrix next time useRenderSurface is called.
- m_currentRenderSurface = 0;
- }
- m_visibleRect = visibleRect;
-
- m_scrollPosition = scrollPosition;
// Scissor out the scrollbars to avoid rendering on top of them.
- IntRect rootScissorRect(contentRect);
+ IntRect rootScissorRect(m_viewportContentRect);
// The scissorRect should not include the scroll offset.
- rootScissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y());
+ rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y());
rootDrawLayer->setScissorRect(rootScissorRect);
m_defaultRenderSurface = rootDrawLayer->renderSurface();
@@ -283,16 +307,19 @@ void LayerRendererChromium::updateLayers(const IntRect& visibleRect, const IntRe
// concept of a large content layer.
updatePropertiesAndRenderSurfaces(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList);
- updateContentsRecursive(m_rootLayer.get());
+ paintContentsRecursive(m_rootLayer.get());
+
+ updateCompositorResourcesRecursive(m_rootLayer.get());
}
void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList)
{
+ TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
makeContextCurrent();
// The GL viewport covers the entire visible area, including the scrollbars.
- GLC(m_context.get(), m_context->viewport(0, 0, m_visibleRect.width(), m_visibleRect.height()));
+ GLC(m_context.get(), m_context->viewport(0, 0, m_viewportVisibleRect.width(), m_viewportVisibleRect.height()));
// Bind the common vertex attributes used for drawing all the layers.
m_sharedGeometry->prepareForDraw();
@@ -363,11 +390,13 @@ void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurface
void LayerRendererChromium::finish()
{
+ TRACE_EVENT("LayerRendererChromium::finish", this, 0);
m_context->finish();
}
void LayerRendererChromium::present()
{
+ TRACE_EVENT("LayerRendererChromium::present", this, 0);
// We're done! Time to swapbuffers!
// Note that currently this has the same effect as swapBuffers; we should
@@ -382,7 +411,7 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
m_rootLayer = layer;
if (m_rootLayer)
m_rootLayer->setLayerRenderer(this);
- m_rootLayerTiler->invalidateEntireLayer();
+ m_rootLayerContentTiler->invalidateEntireLayer();
if (m_horizontalScrollbarTiler)
m_horizontalScrollbarTiler->invalidateEntireLayer();
if (m_verticalScrollbarTiler)
@@ -391,7 +420,7 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
{
- ASSERT(rect.maxX() <= visibleRectSize().width() && rect.maxY() <= visibleRectSize().height());
+ ASSERT(rect.maxX() <= m_viewportVisibleRect.width() && rect.maxY() <= m_viewportVisibleRect.height());
if (!pixels)
return;
@@ -446,8 +475,29 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform
// necessary transformations, scissor rectangles, render surfaces, etc.
void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList)
{
+ // Make sure we have CCLayerImpls for this subtree.
+ layer->createCCLayerImplIfNeeded();
layer->setLayerRenderer(this);
+ if (layer->maskLayer()) {
+ layer->maskLayer()->createCCLayerImplIfNeeded();
+ layer->maskLayer()->setLayerRenderer(this);
+ }
+ if (layer->replicaLayer()) {
+ layer->replicaLayer()->createCCLayerImplIfNeeded();
+ layer->replicaLayer()->setLayerRenderer(this);
+ }
+ if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) {
+ layer->replicaLayer()->maskLayer()->createCCLayerImplIfNeeded();
+ layer->replicaLayer()->maskLayer()->setLayerRenderer(this);
+ }
+
CCLayerImpl* drawLayer = layer->ccLayerImpl();
+ // Currently we're calling pushPropertiesTo() twice - once here and once in updateCompositorResourcesRecursive().
+ // We should only call pushPropertiesTo() in commit, but because we rely on the draw layer state to update
+ // RenderSurfaces and we rely on RenderSurfaces being up to date in order to paint contents we have
+ // to update the draw layers twice.
+ // FIXME: Remove this call once layer updates no longer depend on render surfaces.
+ layer->pushPropertiesTo(drawLayer);
// Compute the new matrix transformation that will be applied to this layer and
// all its sublayers. It's important to remember that the layer's position
@@ -467,9 +517,9 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// Where: P is the projection matrix
// M is the layer's matrix computed above
// S is the scale adjustment (to scale up to the layer size)
- IntSize bounds = layer->bounds();
- FloatPoint anchorPoint = layer->anchorPoint();
- FloatPoint position = layer->position();
+ IntSize bounds = drawLayer->bounds();
+ FloatPoint anchorPoint = drawLayer->anchorPoint();
+ FloatPoint position = drawLayer->position();
// Offset between anchor point and the center of the quad.
float centerOffsetX = (0.5 - anchorPoint.x()) * bounds.width();
@@ -477,16 +527,16 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
TransformationMatrix layerLocalTransform;
// LT = Tr[l]
- layerLocalTransform.translate3d(position.x(), position.y(), layer->anchorPointZ());
+ layerLocalTransform.translate3d(position.x(), position.y(), drawLayer->anchorPointZ());
// LT = Tr[l] * M[l]
- layerLocalTransform.multiply(layer->transform());
+ layerLocalTransform.multiply(drawLayer->transform());
// LT = Tr[l] * M[l] * Tr[c]
- layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ());
+ layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -drawLayer->anchorPointZ());
TransformationMatrix combinedTransform = parentMatrix;
combinedTransform = combinedTransform.multiply(layerLocalTransform);
- FloatRect layerRect(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height(), layer->bounds().width(), layer->bounds().height());
+ FloatRect layerRect(-0.5 * drawLayer->bounds().width(), -0.5 * drawLayer->bounds().height(), drawLayer->bounds().width(), drawLayer->bounds().height());
IntRect transformedLayerRect;
// The layer and its descendants render on a new RenderSurface if any of
@@ -498,12 +548,11 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// If a layer preserves-3d then we don't create a RenderSurface for it to avoid flattening
// out its children. The opacity value of the children layers is multiplied by the opacity
// of their parent.
- bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
- bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D();
- bool useSurfaceForMasking = layer->maskDrawLayer();
- bool useSurfaceForReflection = layer->replicaLayer();
- if (((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent())
- || useSurfaceForMasking || useSurfaceForReflection) {
+ bool useSurfaceForClipping = drawLayer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
+ bool useSurfaceForOpacity = drawLayer->opacity() != 1 && !drawLayer->preserves3D();
+ bool useSurfaceForMasking = drawLayer->maskLayer();
+ bool useSurfaceForReflection = drawLayer->replicaLayer();
+ if (useSurfaceForMasking || useSurfaceForReflection || ((useSurfaceForClipping || useSurfaceForOpacity) && drawLayer->descendantsDrawsContent())) {
RenderSurfaceChromium* renderSurface = drawLayer->renderSurface();
if (!renderSurface)
renderSurface = drawLayer->createRenderSurface();
@@ -516,15 +565,15 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
transformedLayerRect = IntRect(0, 0, bounds.width(), bounds.height());
// Layer's opacity will be applied when drawing the render surface.
- renderSurface->m_drawOpacity = layer->opacity();
- if (layer->superlayer() && layer->superlayer()->preserves3D())
+ renderSurface->m_drawOpacity = drawLayer->opacity();
+ if (drawLayer->superlayer() && drawLayer->superlayer()->preserves3D())
renderSurface->m_drawOpacity *= drawLayer->superlayer()->drawOpacity();
drawLayer->setDrawOpacity(1);
TransformationMatrix layerOriginTransform = combinedTransform;
layerOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0);
renderSurface->m_originTransform = layerOriginTransform;
- if (layerOriginTransform.isInvertible() && layer->superlayer()) {
+ if (layerOriginTransform.isInvertible() && drawLayer->superlayer()) {
TransformationMatrix parentToLayer = layerOriginTransform.inverse();
drawLayer->setScissorRect(parentToLayer.mapRect(drawLayer->superlayer()->scissorRect()));
@@ -538,17 +587,14 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
renderSurface->m_layerList.clear();
- if (layer->maskDrawLayer()) {
- renderSurface->m_maskLayer = layer->maskDrawLayer();
- layer->maskDrawLayer()->setLayerRenderer(this);
- layer->maskDrawLayer()->setTargetRenderSurface(renderSurface);
+ if (drawLayer->maskLayer()) {
+ renderSurface->m_maskLayer = drawLayer->maskLayer();
+ drawLayer->maskLayer()->setTargetRenderSurface(renderSurface);
} else
renderSurface->m_maskLayer = 0;
- if (layer->replicaLayer() && layer->replicaLayer()->maskDrawLayer()) {
- layer->replicaLayer()->maskDrawLayer()->setLayerRenderer(this);
- layer->replicaLayer()->maskDrawLayer()->setTargetRenderSurface(renderSurface);
- }
+ if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->maskLayer())
+ drawLayer->replicaLayer()->maskLayer()->setTargetRenderSurface(renderSurface);
renderSurfaceLayerList.append(drawLayer);
} else {
@@ -556,10 +602,10 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
drawLayer->setDrawTransform(combinedTransform);
transformedLayerRect = enclosingIntRect(drawLayer->drawTransform().mapRect(layerRect));
- drawLayer->setDrawOpacity(layer->opacity());
+ drawLayer->setDrawOpacity(drawLayer->opacity());
- if (layer->superlayer()) {
- if (layer->superlayer()->preserves3D())
+ if (drawLayer->superlayer()) {
+ if (drawLayer->superlayer()->preserves3D())
drawLayer->setDrawOpacity(drawLayer->drawOpacity() * drawLayer->superlayer()->drawOpacity());
// Layers inherit the scissor rect from their superlayer.
@@ -571,7 +617,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
if (layer != m_rootLayer)
drawLayer->clearRenderSurface();
- if (layer->masksToBounds()) {
+ if (drawLayer->masksToBounds()) {
IntRect scissor = drawLayer->scissorRect();
scissor.intersect(transformedLayerRect);
drawLayer->setScissorRect(scissor);
@@ -581,7 +627,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
if (drawLayer->renderSurface())
drawLayer->setTargetRenderSurface(drawLayer->renderSurface());
else {
- ASSERT(layer->superlayer());
+ ASSERT(drawLayer->superlayer());
drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface());
}
@@ -595,7 +641,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
TransformationMatrix sublayerMatrix = drawLayer->drawTransform();
// Flatten to 2D if the layer doesn't preserve 3D.
- if (!layer->preserves3D()) {
+ if (!drawLayer->preserves3D()) {
sublayerMatrix.setM13(0);
sublayerMatrix.setM23(0);
sublayerMatrix.setM31(0);
@@ -606,7 +652,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
}
// Apply the sublayer transform at the center of the layer.
- sublayerMatrix.multiply(layer->sublayerTransform());
+ sublayerMatrix.multiply(drawLayer->sublayerTransform());
// The origin of the sublayers is the top left corner of the layer, not the
// center. The matrix passed down to the sublayers is therefore:
@@ -619,6 +665,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
for (size_t i = 0; i < sublayers.size(); ++i) {
+ sublayers[i]->createCCLayerImplIfNeeded();
CCLayerImpl* sublayer = sublayers[i]->ccLayerImpl();
updatePropertiesAndRenderSurfaces(sublayers[i].get(), sublayerMatrix, renderSurfaceLayerList, descendants);
@@ -635,7 +682,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
}
}
- if (layer->masksToBounds() || useSurfaceForMasking) {
+ if (drawLayer->masksToBounds() || useSurfaceForMasking) {
IntRect drawableContentRect = drawLayer->drawableContentRect();
drawableContentRect.intersect(transformedLayerRect);
drawLayer->setDrawableContentRect(drawableContentRect);
@@ -651,7 +698,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// Don't clip if the layer is reflected as the reflection shouldn't be
// clipped.
- if (!layer->replicaLayer()) {
+ if (!drawLayer->replicaLayer()) {
renderSurface->m_contentRect.intersect(drawLayer->scissorRect());
FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter();
centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter;
@@ -675,10 +722,10 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// Compute the transformation matrix used to draw the replica of the render
// surface.
- if (layer->replicaLayer()) {
+ if (drawLayer->replicaLayer()) {
renderSurface->m_replicaDrawTransform = renderSurface->m_originTransform;
- renderSurface->m_replicaDrawTransform.translate3d(layer->replicaLayer()->position().x(), layer->replicaLayer()->position().y(), 0);
- renderSurface->m_replicaDrawTransform.multiply(layer->replicaLayer()->transform());
+ renderSurface->m_replicaDrawTransform.translate3d(drawLayer->replicaLayer()->position().x(), drawLayer->replicaLayer()->position().y(), 0);
+ renderSurface->m_replicaDrawTransform.multiply(drawLayer->replicaLayer()->transform());
renderSurface->m_replicaDrawTransform.translate3d(surfaceCenter.x() - anchorPoint.x() * bounds.width(), surfaceCenter.y() - anchorPoint.y() * bounds.height(), 0);
}
}
@@ -686,8 +733,8 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// Compute the depth value of the center of the layer which will be used when
// sorting the layers for the preserves-3d property.
const TransformationMatrix& layerDrawMatrix = drawLayer->renderSurface() ? drawLayer->renderSurface()->m_drawTransform : drawLayer->drawTransform();
- if (layer->superlayer()) {
- if (!layer->superlayer()->preserves3D())
+ if (drawLayer->superlayer()) {
+ if (!drawLayer->superlayer()->preserves3D())
drawLayer->setDrawDepth(drawLayer->superlayer()->drawDepth());
else
drawLayer->setDrawDepth(layerDrawMatrix.m43());
@@ -697,24 +744,50 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// If preserves-3d then sort all the descendants by the Z coordinate of their
// center. If the preserves-3d property is also set on the superlayer then
// skip the sorting as the superlayer will sort all the descendants anyway.
- if (layer->preserves3D() && (!layer->superlayer() || !layer->superlayer()->preserves3D()))
+ if (drawLayer->preserves3D() && (!drawLayer->superlayer() || !drawLayer->superlayer()->preserves3D()))
std::stable_sort(&descendants.at(thisLayerIndex), descendants.end(), compareLayerZ);
}
-void LayerRendererChromium::updateContentsRecursive(LayerChromium* layer)
+void LayerRendererChromium::paintContentsRecursive(LayerChromium* layer)
{
const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
for (size_t i = 0; i < sublayers.size(); ++i)
- updateContentsRecursive(sublayers[i].get());
+ paintContentsRecursive(sublayers[i].get());
+
+ if (layer->bounds().isEmpty())
+ return;
if (layer->drawsContent())
- layer->updateContentsIfDirty();
+ layer->paintContentsIfDirty();
if (layer->maskLayer() && layer->maskLayer()->drawsContent())
- layer->maskLayer()->updateContentsIfDirty();
+ layer->maskLayer()->paintContentsIfDirty();
if (layer->replicaLayer() && layer->replicaLayer()->drawsContent())
- layer->replicaLayer()->updateContentsIfDirty();
+ layer->replicaLayer()->paintContentsIfDirty();
if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent())
- layer->replicaLayer()->maskLayer()->updateContentsIfDirty();
+ layer->replicaLayer()->maskLayer()->paintContentsIfDirty();
+}
+
+void LayerRendererChromium::updateCompositorResourcesRecursive(LayerChromium* layer)
+{
+ const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
+ for (size_t i = 0; i < sublayers.size(); ++i)
+ updateCompositorResourcesRecursive(sublayers[i].get());
+
+ if (layer->bounds().isEmpty())
+ return;
+
+ CCLayerImpl* drawLayer = layer->ccLayerImpl();
+
+ if (drawLayer->drawsContent())
+ drawLayer->updateCompositorResources();
+ if (drawLayer->maskLayer() && drawLayer->maskLayer()->drawsContent())
+ drawLayer->maskLayer()->updateCompositorResources();
+ if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->drawsContent())
+ drawLayer->replicaLayer()->updateCompositorResources();
+ if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->maskLayer() && drawLayer->replicaLayer()->maskLayer()->drawsContent())
+ drawLayer->replicaLayer()->maskLayer()->updateCompositorResources();
+
+ layer->pushPropertiesTo(drawLayer);
}
void LayerRendererChromium::setCompositeOffscreen(bool compositeOffscreen)
@@ -788,22 +861,38 @@ void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium*
return;
}
- if (layer->bounds().isEmpty())
+ if (layer->bounds().isEmpty()) {
+ layer->unreserveContentsTexture();
return;
+ }
setScissorToRect(layer->scissorRect());
// Check if the layer falls within the visible bounds of the page.
IntRect layerRect = layer->getDrawRect();
bool isLayerVisible = layer->scissorRect().intersects(layerRect);
- if (!isLayerVisible)
+ if (!isLayerVisible) {
+ layer->unreserveContentsTexture();
return;
+ }
// FIXME: Need to take into account the commulative render surface transforms all the way from
// the default render surface in order to determine visibility.
- TransformationMatrix combinedDrawMatrix = (layer->renderSurface() ? layer->renderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform());
- if (!layer->doubleSided() && combinedDrawMatrix.m33() < 0)
- return;
+ TransformationMatrix combinedDrawMatrix = (layer->targetRenderSurface() ? layer->targetRenderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform());
+
+ if (!layer->doubleSided()) {
+ FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds()));
+ FloatQuad mappedLayer = combinedDrawMatrix.mapQuad(FloatQuad(layerRect));
+ FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1();
+ FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1();
+ FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0);
+ FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0);
+ FloatPoint3D zAxis = xAxis.cross(yAxis);
+ if (zAxis.z() < 0) {
+ layer->unreserveContentsTexture();
+ return;
+ }
+ }
if (layer->drawsContent())
layer->draw();
@@ -880,10 +969,10 @@ bool LayerRendererChromium::initializeSharedObjects()
m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get()));
m_borderProgram = adoptPtr(new LayerChromium::BorderProgram(m_context.get()));
m_contentLayerProgram = adoptPtr(new ContentLayerChromium::Program(m_context.get()));
- m_canvasLayerProgram = adoptPtr(new CanvasLayerChromium::Program(m_context.get()));
- m_videoLayerRGBAProgram = adoptPtr(new VideoLayerChromium::RGBAProgram(m_context.get()));
- m_videoLayerYUVProgram = adoptPtr(new VideoLayerChromium::YUVProgram(m_context.get()));
- m_pluginLayerProgram = adoptPtr(new PluginLayerChromium::Program(m_context.get()));
+ m_canvasLayerProgram = adoptPtr(new CCCanvasLayerImpl::Program(m_context.get()));
+ m_videoLayerRGBAProgram = adoptPtr(new CCVideoLayerImpl::RGBAProgram(m_context.get()));
+ m_videoLayerYUVProgram = adoptPtr(new CCVideoLayerImpl::YUVProgram(m_context.get()));
+ m_pluginLayerProgram = adoptPtr(new CCPluginLayerImpl::Program(m_context.get()));
m_renderSurfaceProgram = adoptPtr(new RenderSurfaceChromium::Program(m_context.get()));
m_renderSurfaceMaskProgram = adoptPtr(new RenderSurfaceChromium::MaskProgram(m_context.get()));
m_tilerProgram = adoptPtr(new LayerTilerChromium::Program(m_context.get()));
@@ -920,7 +1009,7 @@ void LayerRendererChromium::cleanupSharedObjects()
GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
// Clear tilers before the texture manager, as they have references to textures.
- m_rootLayerTiler.clear();
+ m_rootLayerContentTiler.clear();
m_horizontalScrollbarTiler.clear();
m_verticalScrollbarTiler.clear();
diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index 7e8850a..667ede2 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -34,16 +34,17 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "CanvasLayerChromium.h"
#include "ContentLayerChromium.h"
#include "IntRect.h"
#include "LayerChromium.h"
#include "LayerTilerChromium.h"
-#include "PluginLayerChromium.h"
#include "RenderSurfaceChromium.h"
#include "SkBitmap.h"
#include "VideoLayerChromium.h"
+#include "cc/CCCanvasLayerImpl.h"
#include "cc/CCHeadsUpDisplay.h"
+#include "cc/CCPluginLayerImpl.h"
+#include "cc/CCVideoLayerImpl.h"
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
@@ -66,17 +67,18 @@ class CCHeadsUpDisplay;
// Class that handles drawing of composited render layers using GL.
class LayerRendererChromium : public RefCounted<LayerRendererChromium> {
public:
- static PassRefPtr<LayerRendererChromium> create(PassRefPtr<GraphicsContext3D> graphicsContext3D);
+ static PassRefPtr<LayerRendererChromium> create(PassRefPtr<GraphicsContext3D>, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint);
~LayerRendererChromium();
GraphicsContext3D* context();
- void invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect);
+ void invalidateRootLayerRect(const IntRect& dirtyRect);
+
+ void setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition);
// updates and draws the current layers onto the backbuffer
- void updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
- TilePaintInterface&, TilePaintInterface& scrollbarPaint);
+ void updateAndDrawLayers();
// waits for rendering to finish
void finish();
@@ -84,7 +86,7 @@ public:
// puts backbuffer onscreen
void present();
- IntSize visibleRectSize() const { return m_visibleRect.size(); }
+ IntSize viewportSize() const { return m_viewportVisibleRect.size(); }
void setRootLayer(PassRefPtr<LayerChromium> layer);
LayerChromium* rootLayer() { return m_rootLayer.get(); }
@@ -94,8 +96,6 @@ public:
void setCompositeOffscreen(bool);
bool isCompositingOffscreen() const { return m_compositeOffscreen; }
- LayerTexture* getOffscreenLayerTexture();
- void copyOffscreenTextureToDisplay();
unsigned createLayerTexture();
void deleteLayerTexture(unsigned);
@@ -111,13 +111,13 @@ public:
const GeometryBinding* sharedGeometry() const { return m_sharedGeometry.get(); }
const LayerChromium::BorderProgram* borderProgram() const { return m_borderProgram.get(); }
const ContentLayerChromium::Program* contentLayerProgram() const { return m_contentLayerProgram.get(); }
- const CanvasLayerChromium::Program* canvasLayerProgram() const { return m_canvasLayerProgram.get(); }
- const VideoLayerChromium::RGBAProgram* videoLayerRGBAProgram() const { return m_videoLayerRGBAProgram.get(); }
- const VideoLayerChromium::YUVProgram* videoLayerYUVProgram() const { return m_videoLayerYUVProgram.get(); }
- const PluginLayerChromium::Program* pluginLayerProgram() const { return m_pluginLayerProgram.get(); }
const RenderSurfaceChromium::Program* renderSurfaceProgram() const { return m_renderSurfaceProgram.get(); }
const RenderSurfaceChromium::MaskProgram* renderSurfaceMaskProgram() const { return m_renderSurfaceMaskProgram.get(); }
const LayerTilerChromium::Program* tilerProgram() const { return m_tilerProgram.get(); }
+ const CCCanvasLayerImpl::Program* canvasLayerProgram() const { return m_canvasLayerProgram.get(); }
+ const CCPluginLayerImpl::Program* pluginLayerProgram() const { return m_pluginLayerProgram.get(); }
+ const CCVideoLayerImpl::RGBAProgram* videoLayerRGBAProgram() const { return m_videoLayerRGBAProgram.get(); }
+ const CCVideoLayerImpl::YUVProgram* videoLayerYUVProgram() const { return m_videoLayerYUVProgram.get(); }
void resizeOnscreenContent(const IntSize&);
@@ -132,19 +132,21 @@ public:
String layerTreeAsText() const;
private:
- explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D> graphicsContext3D);
+ explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D>, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint);
- void updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
- Vector<CCLayerImpl*>& renderSurfaceLayerList);
- void updateRootLayerContents(TilePaintInterface&, const IntRect& visibleRect);
- void updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect);
+ void updateLayers(Vector<CCLayerImpl*>& renderSurfaceLayerList);
+ void updateRootLayerContents();
+ void updateRootLayerScrollbars();
void updatePropertiesAndRenderSurfaces(LayerChromium*, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList);
- void updateContentsRecursive(LayerChromium*);
+ void paintContentsRecursive(LayerChromium*);
+ void updateCompositorResourcesRecursive(LayerChromium*);
void drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList);
void drawLayer(CCLayerImpl*, RenderSurfaceChromium*);
void drawRootLayer();
+ LayerTexture* getOffscreenLayerTexture();
+ void copyOffscreenTextureToDisplay();
bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
@@ -161,19 +163,22 @@ private:
bool initializeSharedObjects();
void cleanupSharedObjects();
- static IntRect verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect);
- static IntRect horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect);
+ IntRect verticalScrollbarRect() const;
+ IntRect horizontalScrollbarRect() const;
- IntRect m_visibleRect;
+ IntRect m_viewportVisibleRect;
+ IntRect m_viewportContentRect;
+ IntPoint m_viewportScrollPosition;
TransformationMatrix m_projectionMatrix;
RefPtr<LayerChromium> m_rootLayer;
- OwnPtr<LayerTilerChromium> m_rootLayerTiler;
+ OwnPtr<TilePaintInterface> m_rootLayerContentPaint;
+ OwnPtr<TilePaintInterface> m_rootLayerScrollbarPaint;
+ OwnPtr<LayerTilerChromium> m_rootLayerContentTiler;
OwnPtr<LayerTilerChromium> m_horizontalScrollbarTiler;
OwnPtr<LayerTilerChromium> m_verticalScrollbarTiler;
- IntPoint m_scrollPosition;
bool m_hardwareCompositing;
unsigned m_currentShader;
@@ -202,13 +207,13 @@ private:
OwnPtr<GeometryBinding> m_sharedGeometry;
OwnPtr<LayerChromium::BorderProgram> m_borderProgram;
OwnPtr<ContentLayerChromium::Program> m_contentLayerProgram;
- OwnPtr<CanvasLayerChromium::Program> m_canvasLayerProgram;
- OwnPtr<VideoLayerChromium::RGBAProgram> m_videoLayerRGBAProgram;
- OwnPtr<VideoLayerChromium::YUVProgram> m_videoLayerYUVProgram;
- OwnPtr<PluginLayerChromium::Program> m_pluginLayerProgram;
OwnPtr<RenderSurfaceChromium::Program> m_renderSurfaceProgram;
OwnPtr<RenderSurfaceChromium::MaskProgram> m_renderSurfaceMaskProgram;
OwnPtr<LayerTilerChromium::Program> m_tilerProgram;
+ OwnPtr<CCCanvasLayerImpl::Program> m_canvasLayerProgram;
+ OwnPtr<CCVideoLayerImpl::RGBAProgram> m_videoLayerRGBAProgram;
+ OwnPtr<CCVideoLayerImpl::YUVProgram> m_videoLayerYUVProgram;
+ OwnPtr<CCPluginLayerImpl::Program> m_pluginLayerProgram;
OwnPtr<TextureManager> m_textureManager;
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
index 86592a6..bc37201 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
@@ -34,6 +34,7 @@
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
+#include "TraceEvent.h"
#include <wtf/PassOwnArrayPtr.h>
@@ -84,58 +85,50 @@ void LayerTilerChromium::reset()
{
m_tiles.clear();
m_unusedTiles.clear();
-
m_tilingData.setTotalSize(0, 0);
- m_lastUpdateLayerRect = IntRect();
}
LayerTilerChromium::Tile* LayerTilerChromium::createTile(int i, int j)
{
- const int index = tileIndex(i, j);
- ASSERT(!m_tiles[index]);
+ ASSERT(!tileAt(i, j));
+ RefPtr<Tile> tile;
if (m_unusedTiles.size() > 0) {
- m_tiles[index] = m_unusedTiles.last().release();
+ tile = m_unusedTiles.last().release();
m_unusedTiles.removeLast();
+ ASSERT(tile->refCount() == 1);
} else {
GraphicsContext3D* context = layerRendererContext();
TextureManager* manager = layerRenderer()->textureManager();
- OwnPtr<Tile> tile = adoptPtr(new Tile(LayerTexture::create(context, manager)));
- m_tiles[index] = tile.release();
+ tile = adoptRef(new Tile(LayerTexture::create(context, manager)));
}
+ m_tiles.add(make_pair(i, j), tile);
+
+ tile->moveTo(i, j);
+ tile->m_dirtyLayerRect = tileLayerRect(tile.get());
- m_tiles[index]->m_dirtyLayerRect = tileLayerRect(i, j);
- return m_tiles[index].get();
+ return tile.get();
}
-void LayerTilerChromium::invalidateTiles(const IntRect& oldLayerRect, const IntRect& newLayerRect)
+void LayerTilerChromium::invalidateTiles(const IntRect& contentRect)
{
if (!m_tiles.size())
return;
- IntRect oldContentRect = layerRectToContentRect(oldLayerRect);
- int oldLeft, oldTop, oldRight, oldBottom;
- contentRectToTileIndices(oldContentRect, oldLeft, oldTop, oldRight, oldBottom);
-
- IntRect newContentRect = layerRectToContentRect(newLayerRect);
- int newLeft, newTop, newRight, newBottom;
- contentRectToTileIndices(newContentRect, newLeft, newTop, newRight, newBottom);
-
- // Iterating through just the old tile indices is an optimization to avoid
- // iterating through the entire m_tiles array.
- for (int j = oldTop; j <= oldBottom; ++j) {
- for (int i = oldLeft; i <= oldRight; ++i) {
- if (i >= newLeft && i <= newRight && j >= newTop && j <= newBottom)
- continue;
-
- const int index = tileIndex(i, j);
- if (m_tiles[index])
- m_unusedTiles.append(m_tiles[index].release());
- }
+ Vector<TileMapKey> removeKeys;
+ for (TileMap::iterator iter = m_tiles.begin(); iter != m_tiles.end(); ++iter) {
+ Tile* tile = iter->second.get();
+ IntRect tileRect = tileContentRect(tile);
+ if (tileRect.intersects(contentRect))
+ continue;
+ removeKeys.append(iter->first);
}
+
+ for (size_t i = 0; i < removeKeys.size(); ++i)
+ m_unusedTiles.append(m_tiles.take(removeKeys[i]));
}
-void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, int &left, int &top, int &right, int &bottom) const
+void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, int& left, int& top, int& right, int& bottom) const
{
const IntRect layerRect = contentRectToLayerRect(contentRect);
@@ -163,36 +156,28 @@ IntRect LayerTilerChromium::layerRectToContentRect(const IntRect& layerRect) con
return contentRect;
}
-int LayerTilerChromium::tileIndex(int i, int j) const
+LayerTilerChromium::Tile* LayerTilerChromium::tileAt(int i, int j) const
{
- return m_tilingData.tileIndex(i, j);
+ Tile* tile = m_tiles.get(make_pair(i, j)).get();
+ ASSERT(!tile || tile->refCount() == 1);
+ return tile;
}
-IntRect LayerTilerChromium::tileContentRect(int i, int j) const
+IntRect LayerTilerChromium::tileContentRect(const Tile* tile) const
{
- IntRect contentRect = tileLayerRect(i, j);
+ IntRect contentRect = tileLayerRect(tile);
contentRect.move(m_layerPosition.x(), m_layerPosition.y());
return contentRect;
}
-IntRect LayerTilerChromium::tileLayerRect(int i, int j) const
+IntRect LayerTilerChromium::tileLayerRect(const Tile* tile) const
{
- const int index = m_tilingData.tileIndex(i, j);
+ const int index = m_tilingData.tileIndex(tile->i(), tile->j());
IntRect layerRect = m_tilingData.tileBoundsWithBorder(index);
layerRect.setSize(m_tileSize);
return layerRect;
}
-IntSize LayerTilerChromium::layerSize() const
-{
- return IntSize(m_tilingData.totalSizeX(), m_tilingData.totalSizeY());
-}
-
-IntSize LayerTilerChromium::layerTileSize() const
-{
- return IntSize(m_tilingData.numTilesX(), m_tilingData.numTilesY());
-}
-
void LayerTilerChromium::invalidateRect(const IntRect& contentRect)
{
if (contentRect.isEmpty())
@@ -202,16 +187,16 @@ void LayerTilerChromium::invalidateRect(const IntRect& contentRect)
// Dirty rects are always in layer space, as the layer could be repositioned
// after invalidation.
- IntRect layerRect = contentRectToLayerRect(contentRect);
+ const IntRect layerRect = contentRectToLayerRect(contentRect);
int left, top, right, bottom;
contentRectToTileIndices(contentRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
- Tile* tile = m_tiles[tileIndex(i, j)].get();
+ Tile* tile = tileAt(i, j);
if (!tile)
continue;
- IntRect bound = tileLayerRect(i, j);
+ IntRect bound = tileLayerRect(tile);
bound.intersect(layerRect);
tile->m_dirtyLayerRect.unite(bound);
}
@@ -220,14 +205,13 @@ void LayerTilerChromium::invalidateRect(const IntRect& contentRect)
void LayerTilerChromium::invalidateEntireLayer()
{
- for (size_t i = 0; i < m_tiles.size(); ++i) {
- if (m_tiles[i])
- m_unusedTiles.append(m_tiles[i].release());
+ for (TileMap::iterator iter = m_tiles.begin(); iter != m_tiles.end(); ++iter) {
+ ASSERT(iter->second->refCount() == 1);
+ m_unusedTiles.append(iter->second.release());
}
m_tiles.clear();
m_tilingData.setTotalSize(0, 0);
- m_lastUpdateLayerRect = IntRect();
}
void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& contentRect)
@@ -237,10 +221,7 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
// Invalidate old tiles that were previously used but aren't in use this
// frame so that they can get reused for new tiles.
- IntRect layerRect = contentRectToLayerRect(contentRect);
- invalidateTiles(m_lastUpdateLayerRect, layerRect);
- m_lastUpdateLayerRect = layerRect;
-
+ invalidateTiles(contentRect);
growLayerToContain(contentRect);
// Create tiles as needed, expanding a dirty rect to contain all
@@ -250,11 +231,11 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
contentRectToTileIndices(contentRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
- Tile* tile = m_tiles[tileIndex(i, j)].get();
+ Tile* tile = tileAt(i, j);
if (!tile)
tile = createTile(i, j);
if (!tile->texture()->isValid(m_tileSize, GraphicsContext3D::RGBA))
- tile->m_dirtyLayerRect = tileLayerRect(i, j);
+ tile->m_dirtyLayerRect = tileLayerRect(tile);
dirtyLayerRect.unite(tile->m_dirtyLayerRect);
}
}
@@ -267,10 +248,16 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
m_canvas.resize(paintRect.size());
PlatformCanvas::Painter canvasPainter(&m_canvas);
canvasPainter.context()->translate(-paintRect.x(), -paintRect.y());
- painter.paint(*canvasPainter.context(), paintRect);
+ {
+ TRACE_EVENT("LayerTilerChromium::update::paint", this, 0);
+ painter.paint(*canvasPainter.context(), paintRect);
+ }
PlatformCanvas::AutoLocker locker(&m_canvas);
- updateFromPixels(paintRect, locker.pixels());
+ {
+ TRACE_EVENT("LayerTilerChromium::updateFromPixels", this, 0);
+ updateFromPixels(paintRect, locker.pixels());
+ }
}
void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_t* paintPixels)
@@ -285,14 +272,14 @@ void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_
contentRectToTileIndices(paintRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
- Tile* tile = m_tiles[tileIndex(i, j)].get();
+ Tile* tile = tileAt(i, j);
if (!tile)
CRASH();
if (!tile->dirty())
continue;
// Calculate page-space rectangle to copy from.
- IntRect sourceRect = tileContentRect(i, j);
+ IntRect sourceRect = tileContentRect(tile);
const IntPoint anchor = sourceRect.location();
sourceRect.intersect(layerRectToContentRect(tile->m_dirtyLayerRect));
if (sourceRect.isEmpty())
@@ -366,8 +353,7 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
contentRectToTileIndices(contentRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
- const int index = tileIndex(i, j);
- Tile* tile = m_tiles[index].get();
+ Tile* tile = tileAt(i, j);
ASSERT(tile);
tile->texture()->bindTexture();
@@ -376,11 +362,11 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
// Don't use tileContentRect here, as that contains the full
// rect with border texels which shouldn't be drawn.
- IntRect tileRect = m_tilingData.tileBounds(index);
+ IntRect tileRect = m_tilingData.tileBounds(m_tilingData.tileIndex(tile->i(), tile->j()));
tileRect.move(m_layerPosition.x(), m_layerPosition.y());
tileMatrix.translate3d(tileRect.x() - contentRect.x() + tileRect.width() / 2.0, tileRect.y() - contentRect.y() + tileRect.height() / 2.0, 0);
- IntPoint texOffset = m_tilingData.textureOffset(i, j);
+ IntPoint texOffset = m_tilingData.textureOffset(tile->i(), tile->j());
float tileWidth = static_cast<float>(m_tileSize.width());
float tileHeight = static_cast<float>(m_tileSize.height());
float texTranslateX = texOffset.x() / tileWidth;
@@ -395,37 +381,15 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
}
}
-void LayerTilerChromium::resizeLayer(const IntSize& size)
-{
- if (layerSize() == size)
- return;
-
- const IntSize oldTileSize = layerTileSize();
- m_tilingData.setTotalSize(size.width(), size.height());
- const IntSize newTileSize = layerTileSize();
-
- if (oldTileSize == newTileSize)
- return;
-
- if (newTileSize.height() && (newTileSize.width() > INT_MAX / newTileSize.height()))
- CRASH();
-
- Vector<OwnPtr<Tile> > newTiles;
- newTiles.resize(newTileSize.width() * newTileSize.height());
- for (int j = 0; j < oldTileSize.height(); ++j)
- for (int i = 0; i < oldTileSize.width(); ++i)
- newTiles[i + j * newTileSize.width()].swap(m_tiles[i + j * oldTileSize.width()]);
- m_tiles.swap(newTiles);
-}
-
void LayerTilerChromium::growLayerToContain(const IntRect& contentRect)
{
// Grow the tile array to contain this content rect.
IntRect layerRect = contentRectToLayerRect(contentRect);
IntSize rectSize = IntSize(layerRect.maxX(), layerRect.maxY());
- IntSize newSize = rectSize.expandedTo(layerSize());
- resizeLayer(newSize);
+ IntSize oldLayerSize(m_tilingData.totalSizeX(), m_tilingData.totalSizeY());
+ IntSize newSize = rectSize.expandedTo(oldLayerSize);
+ m_tilingData.setTotalSize(newSize.width(), newSize.height());
}
void LayerTilerChromium::drawTexturedQuad(GraphicsContext3D* context, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix,
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
index bdb35a5..2f356e4 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
@@ -33,7 +33,9 @@
#include "LayerTexture.h"
#include "PlatformCanvas.h"
#include "TilingData.h"
+#include <wtf/HashTraits.h>
#include <wtf/OwnArrayPtr.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
@@ -70,20 +72,26 @@ public:
private:
LayerTilerChromium(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption);
- class Tile {
+ class Tile : public RefCounted<Tile> {
WTF_MAKE_NONCOPYABLE(Tile);
public:
- explicit Tile(PassOwnPtr<LayerTexture> tex) : m_tex(tex) {}
+ explicit Tile(PassOwnPtr<LayerTexture> tex) : m_tex(tex), m_i(-1), m_j(-1) {}
LayerTexture* texture() { return m_tex.get(); }
bool dirty() const { return !m_dirtyLayerRect.isEmpty(); }
void clearDirty() { m_dirtyLayerRect = IntRect(); }
+ int i() const { return m_i; }
+ int j() const { return m_j; }
+ void moveTo(int i, int j) { m_i = i; m_j = j; }
+
// Layer-space dirty rectangle that needs to be repainted.
IntRect m_dirtyLayerRect;
private:
OwnPtr<LayerTexture> m_tex;
+ int m_i;
+ int m_j;
};
void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix,
@@ -92,40 +100,45 @@ private:
float texScaleX, float texScaleY,
const LayerTilerChromium::Program*);
- void resizeLayer(const IntSize& size);
// Grow layer size to contain this rectangle.
void growLayerToContain(const IntRect& contentRect);
LayerRendererChromium* layerRenderer() const { return m_layerRenderer; }
GraphicsContext3D* layerRendererContext() const;
Tile* createTile(int i, int j);
- // Invalidate any tiles which do not intersect with the newLayerRect.
- void invalidateTiles(const IntRect& oldLayerRect, const IntRect& newLayerRect);
+ // Invalidate any tiles which do not intersect with the contentRect
+ void invalidateTiles(const IntRect& contentRect);
void reset();
void contentRectToTileIndices(const IntRect& contentRect, int &left, int &top, int &right, int &bottom) const;
IntRect contentRectToLayerRect(const IntRect& contentRect) const;
IntRect layerRectToContentRect(const IntRect& layerRect) const;
- // Returns the index into m_tiles for a given tile location.
- int tileIndex(int i, int j) const;
- // Returns the bounds in content space for a given tile location.
- IntRect tileContentRect(int i, int j) const;
- // Returns the bounds in layer space for a given tile location.
- IntRect tileLayerRect(int i, int j) const;
-
- IntSize layerSize() const;
- IntSize layerTileSize() const;
+ Tile* tileAt(int, int) const;
+ IntRect tileContentRect(const Tile*) const;
+ IntRect tileLayerRect(const Tile*) const;
IntSize m_tileSize;
- IntRect m_lastUpdateLayerRect;
IntPoint m_layerPosition;
bool m_skipsDraw;
- // Logical 2D array of tiles (dimensions of m_layerTileSize)
- Vector<OwnPtr<Tile> > m_tiles;
- // Linear array of unused tiles.
- Vector<OwnPtr<Tile> > m_unusedTiles;
+ // Default hash key traits for integers disallow 0 and -1 as a key, so
+ // use a custom hash trait which disallows -1 and -2 instead.
+ typedef std::pair<int, int> TileMapKey;
+ struct TileMapKeyTraits : HashTraits<TileMapKey> {
+ static const bool emptyValueIsZero = false;
+ static const bool needsDestruction = false;
+ static TileMapKey emptyValue() { return std::make_pair(-1, -1); }
+ static void constructDeletedValue(TileMapKey& slot) { slot = std::make_pair(-2, -2); }
+ static bool isDeletedValue(TileMapKey value) { return value.first == -2 && value.second == -2; }
+ };
+ // FIXME: The mapped value in TileMap should really be an OwnPtr, as the
+ // refcount of a Tile should never be more than 1. However, HashMap
+ // doesn't easily support OwnPtr as a value.
+ typedef HashMap<TileMapKey, RefPtr<Tile>, DefaultHash<TileMapKey>::Hash, TileMapKeyTraits> TileMap;
+ TileMap m_tiles;
+ // Tightly packed set of unused tiles.
+ Vector<RefPtr<Tile> > m_unusedTiles;
PlatformCanvas m_canvas;
diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
index 5d595ad..3667fbb 100644
--- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
@@ -29,10 +29,10 @@
#include "PluginLayerChromium.h"
-#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
-#include <GLES2/gl2.h>
+#include "cc/CCLayerImpl.h"
+#include "cc/CCPluginLayerImpl.h"
namespace WebCore {
@@ -43,40 +43,26 @@ PassRefPtr<PluginLayerChromium> PluginLayerChromium::create(GraphicsLayerChromiu
PluginLayerChromium::PluginLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
+ , m_textureId(0)
{
}
-void PluginLayerChromium::setTextureId(unsigned id)
+PassRefPtr<CCLayerImpl> PluginLayerChromium::createCCLayerImpl()
{
- m_textureId = id;
+ return CCPluginLayerImpl::create(this);
}
-void PluginLayerChromium::updateContentsIfDirty()
+void PluginLayerChromium::setTextureId(unsigned id)
{
+ m_textureId = id;
}
-void PluginLayerChromium::draw()
+void PluginLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
{
- ASSERT(layerRenderer());
- const PluginLayerChromium::Program* program = layerRenderer()->pluginLayerProgram();
- ASSERT(program && program->initialized());
- GraphicsContext3D* context = layerRendererContext();
- GLC(context, context->activeTexture(GL_TEXTURE0));
- GLC(context, context->bindTexture(GL_TEXTURE_2D, m_textureId));
-
- // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
- // where it will only happen once per texture.
- GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-
- layerRenderer()->useShader(program->program());
- GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(),
- bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(),
- program->vertexShader().matrixLocation(),
- program->fragmentShader().alphaLocation());
+ LayerChromium::pushPropertiesTo(layer);
+
+ CCPluginLayerImpl* pluginLayer = static_cast<CCPluginLayerImpl*>(layer);
+ pluginLayer->setTextureId(m_textureId);
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
index 8d66f5f..852dc2e 100644
--- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
@@ -38,18 +38,19 @@ class PluginLayerChromium : public LayerChromium {
public:
static PassRefPtr<PluginLayerChromium> create(GraphicsLayerChromium* owner = 0);
virtual bool drawsContent() const { return true; }
- virtual void updateContentsIfDirty();
- virtual void draw();
-
+
+ virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
+
void setTextureId(unsigned textureId);
-
- typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
+ unsigned textureId() const { return m_textureId; }
+
+ virtual void pushPropertiesTo(CCLayerImpl*);
protected:
virtual const char* layerTypeAsString() const { return "PluginLayer"; }
private:
- PluginLayerChromium(GraphicsLayerChromium* owner);
+ explicit PluginLayerChromium(GraphicsLayerChromium* owner);
unsigned m_textureId;
};
diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
index 49b3462..b7f447b 100644
--- a/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
@@ -248,7 +248,7 @@ FragmentShaderYUVVideo::FragmentShaderYUVVideo()
, m_vTextureLocation(-1)
, m_alphaLocation(-1)
, m_ccMatrixLocation(-1)
- , m_signAdjLocation(-1)
+ , m_yuvAdjLocation(-1)
{
}
@@ -259,10 +259,10 @@ bool FragmentShaderYUVVideo::init(GraphicsContext3D* context, unsigned program)
m_vTextureLocation = context->getUniformLocation(program, "v_texture");
m_alphaLocation = context->getUniformLocation(program, "alpha");
m_ccMatrixLocation = context->getUniformLocation(program, "cc_matrix");
- m_signAdjLocation = context->getUniformLocation(program, "adj");
+ m_yuvAdjLocation = context->getUniformLocation(program, "yuv_adj");
return m_yTextureLocation != -1 && m_uTextureLocation != -1 && m_vTextureLocation != -1
- && m_alphaLocation != -1 && m_ccMatrixLocation != -1 && m_signAdjLocation != -1;
+ && m_alphaLocation != -1 && m_ccMatrixLocation != -1 && m_yuvAdjLocation != -1;
}
String FragmentShaderYUVVideo::getShaderString() const
@@ -276,14 +276,15 @@ String FragmentShaderYUVVideo::getShaderString() const
uniform sampler2D u_texture;
uniform sampler2D v_texture;
uniform float alpha;
- uniform float adj;
+ uniform vec3 yuv_adj;
uniform mat3 cc_matrix;
void main()
{
- float y = texture2D(y_texture, y_texCoord).x;
- float u = texture2D(u_texture, uv_texCoord).x - adj;
- float v = texture2D(v_texture, uv_texCoord).x - adj;
- vec3 rgb = cc_matrix * vec3(y, u, v);
+ float y_raw = texture2D(y_texture, y_texCoord).x;
+ float u_unsigned = texture2D(u_texture, uv_texCoord).x;
+ float v_unsigned = texture2D(v_texture, uv_texCoord).x;
+ vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
+ vec3 rgb = cc_matrix * yuv;
gl_FragColor = vec4(rgb, float(1)) * alpha;
}
);
diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.h b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h
index 758c62b..3a3e175 100644
--- a/Source/WebCore/platform/graphics/chromium/ShaderChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h
@@ -158,7 +158,7 @@ public:
int vTextureLocation() const { return m_vTextureLocation; }
int alphaLocation() const { return m_alphaLocation; }
int ccMatrixLocation() const { return m_ccMatrixLocation; }
- int signAdjLocation() const { return m_signAdjLocation; }
+ int yuvAdjLocation() const { return m_yuvAdjLocation; }
private:
int m_yTextureLocation;
@@ -166,7 +166,7 @@ private:
int m_vTextureLocation;
int m_alphaLocation;
int m_ccMatrixLocation;
- int m_signAdjLocation;
+ int m_yuvAdjLocation;
};
class FragmentShaderColor {
diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
index 9423d1e..7cd47fe 100644
--- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
@@ -113,13 +113,13 @@ void SimpleFontData::platformInit()
m_fontMetrics.setXHeight(xHeight);
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
- if (m_orientation == Vertical) {
+ if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
size_t vheaSize = SkFontHost::GetTableSize(fontID, vheaTag);
size_t vorgSize = SkFontHost::GetTableSize(fontID, vorgTag);
- if ((vheaSize <= 0) && (vorgSize <= 0))
- m_orientation = Horizontal;
+ if ((vheaSize > 0) || (vorgSize > 0))
+ m_hasVerticalGlyphs = true;
}
// In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 5d7a6e7..182e730 100644
--- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -33,7 +33,6 @@
#if USE(ACCELERATED_COMPOSITING)
#include "VideoLayerChromium.h"
-#include "cc/CCLayerImpl.h"
#include "Extensions3DChromium.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
@@ -41,17 +40,11 @@
#include "RenderLayerBacking.h"
#include "VideoFrameChromium.h"
#include "VideoFrameProvider.h"
+#include "cc/CCLayerImpl.h"
+#include "cc/CCVideoLayerImpl.h"
namespace WebCore {
-// These values are magic numbers that are used in the transformation
-// from YUV to RGB color values.
-const float VideoLayerChromium::yuv2RGB[9] = {
- 1.f, 1.f, 1.f,
- 0.f, -.344f, 1.772f,
- 1.403f, -.714f, 0.f,
-};
-
PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner,
VideoFrameProvider* provider)
{
@@ -71,23 +64,37 @@ VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameP
VideoLayerChromium::~VideoLayerChromium()
{
cleanupResources();
+ deleteTexturesInUse();
}
-void VideoLayerChromium::cleanupResources()
+PassRefPtr<CCLayerImpl> VideoLayerChromium::createCCLayerImpl()
+{
+ return CCVideoLayerImpl::create(this);
+}
+
+void VideoLayerChromium::deleteTexturesInUse()
{
- LayerChromium::cleanupResources();
- releaseCurrentFrame();
if (!layerRenderer())
return;
GraphicsContext3D* context = layerRendererContext();
for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
- if (m_textures[plane])
- GLC(context, context->deleteTexture(m_textures[plane]));
+ Texture texture = m_textures[plane];
+ if (!texture.isEmpty && texture.ownedByLayerRenderer)
+ GLC(context, context->deleteTexture(texture.id));
}
}
-void VideoLayerChromium::updateContentsIfDirty()
+void VideoLayerChromium::cleanupResources()
+{
+ LayerChromium::cleanupResources();
+ if (m_currentFrame)
+ releaseCurrentFrame();
+ else
+ resetFrameParameters();
+}
+
+void VideoLayerChromium::updateCompositorResources()
{
if (!m_contentsDirty)
return;
@@ -116,6 +123,9 @@ void VideoLayerChromium::updateContentsIfDirty()
return;
}
+ // If the incoming frame is backed by a texture (i.e. decoded in hardware),
+ // then we do not need to allocate a texture via the layer renderer. Instead
+ // we save the texture data then exit.
if (frame->surfaceType() == VideoFrameChromium::TypeTexture) {
releaseCurrentFrame();
saveCurrentFrame(frame);
@@ -136,8 +146,9 @@ void VideoLayerChromium::updateContentsIfDirty()
// Update texture planes.
for (unsigned plane = 0; plane < frame->planes(); plane++) {
- ASSERT(frame->requiredTextureSize(plane) == m_textureSizes[plane]);
- updateTexture(context, m_textures[plane], frame->requiredTextureSize(plane), textureFormat, frame->data(plane));
+ Texture texture = m_textures[plane];
+ ASSERT(frame->requiredTextureSize(plane) == texture.size);
+ updateTexture(context, texture.id, texture.size, textureFormat, frame->data(plane));
}
m_dirtyRect.setSize(FloatSize());
@@ -146,7 +157,19 @@ void VideoLayerChromium::updateContentsIfDirty()
m_provider->putCurrentFrame(frame);
}
-unsigned VideoLayerChromium::determineTextureFormat(VideoFrameChromium* frame)
+void VideoLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
+{
+ LayerChromium::pushPropertiesTo(layer);
+
+ CCVideoLayerImpl* videoLayer = static_cast<CCVideoLayerImpl*>(layer);
+ videoLayer->setSkipsDraw(m_skipsDraw);
+ videoLayer->setFrameFormat(m_frameFormat);
+ for (size_t i = 0; i < 3; ++i)
+ videoLayer->setTexture(i, m_textures[i]);
+}
+
+
+unsigned VideoLayerChromium::determineTextureFormat(const VideoFrameChromium* frame)
{
switch (frame->format()) {
case VideoFrameChromium::YV12:
@@ -160,56 +183,68 @@ unsigned VideoLayerChromium::determineTextureFormat(VideoFrameChromium* frame)
return GraphicsContext3D::INVALID_VALUE;
}
-bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, VideoFrameChromium* frame, unsigned textureFormat)
+bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, const VideoFrameChromium* frame, unsigned textureFormat)
{
ASSERT(context);
ASSERT(frame);
for (unsigned plane = 0; plane < frame->planes(); plane++) {
- IntSize planeTextureSize = frame->requiredTextureSize(plane);
+ IntSize requiredTextureSize = frame->requiredTextureSize(plane);
+ Texture texture = m_textures[plane];
// If the renderer cannot handle this large of a texture, return false.
// FIXME: Remove this test when tiled layers are implemented.
- if (!layerRenderer()->checkTextureSize(planeTextureSize))
+ if (!layerRenderer()->checkTextureSize(requiredTextureSize))
return false;
- if (!m_textures[plane])
- m_textures[plane] = layerRenderer()->createLayerTexture();
-
- if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[plane]) {
- allocateTexture(context, m_textures[plane], planeTextureSize, textureFormat);
- m_textureSizes[plane] = planeTextureSize;
- int frameWidth = frame->width(plane);
- int frameHeight = frame->height(plane);
- // When there are dead pixels at the edge of the texture, decrease
- // the frame width by 1 to prevent the rightmost pixels from
- // interpolating with the dead pixels.
- if (frame->hasPaddingBytes(plane))
- --frameWidth;
- m_frameSizes[plane] = IntSize(frameWidth, frameHeight);
+ if (texture.isEmpty) {
+ texture.id = layerRenderer()->createLayerTexture();
+ texture.ownedByLayerRenderer = true;
+ texture.isEmpty = false;
+ }
+
+ if (!requiredTextureSize.isZero() && requiredTextureSize != texture.size) {
+ allocateTexture(context, texture.id, requiredTextureSize, textureFormat);
+ texture.size = requiredTextureSize;
+ texture.visibleSize = computeVisibleSize(frame, plane);
}
+ m_textures[plane] = texture;
}
+ return true;
+}
+
+IntSize VideoLayerChromium::computeVisibleSize(const VideoFrameChromium* frame, unsigned plane)
+{
+ int visibleWidth = frame->width(plane);
+ int visibleHeight = frame->height(plane);
+ // When there are dead pixels at the edge of the texture, decrease
+ // the frame width by 1 to prevent the rightmost pixels from
+ // interpolating with the dead pixels.
+ if (frame->hasPaddingBytes(plane))
+ --visibleWidth;
+
// In YV12, every 2x2 square of Y values corresponds to one U and
// one V value. If we decrease the width of the UV plane, we must decrease the
// width of the Y texture by 2 for proper alignment. This must happen
// always, even if Y's texture does not have padding bytes.
- if (frame->format() == VideoFrameChromium::YV12) {
- int yPlaneOriginalWidth = frame->width(VideoFrameChromium::yPlane);
- if (frame->hasPaddingBytes(VideoFrameChromium::uPlane))
- m_frameSizes[VideoFrameChromium::yPlane].setWidth(yPlaneOriginalWidth - 2);
+ if (plane == VideoFrameChromium::yPlane && frame->format() == VideoFrameChromium::YV12) {
+ if (frame->hasPaddingBytes(VideoFrameChromium::uPlane)) {
+ int originalWidth = frame->width(plane);
+ visibleWidth = originalWidth - 2;
+ }
}
- return true;
+ return IntSize(visibleWidth, visibleHeight);
}
-void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned textureFormat)
+void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned textureFormat) const
{
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
GLC(context, context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, GraphicsContext3D::UNSIGNED_BYTE));
}
-void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned format, const void* data)
+void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned format, const void* data) const
{
ASSERT(context);
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
@@ -225,33 +260,6 @@ void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text
}
}
-void VideoLayerChromium::draw()
-{
- if (m_skipsDraw)
- return;
-
- ASSERT(layerRenderer());
- const RGBAProgram* rgbaProgram = layerRenderer()->videoLayerRGBAProgram();
- ASSERT(rgbaProgram && rgbaProgram->initialized());
- const YUVProgram* yuvProgram = layerRenderer()->videoLayerYUVProgram();
- ASSERT(yuvProgram && yuvProgram->initialized());
-
- switch (m_frameFormat) {
- case VideoFrameChromium::YV12:
- case VideoFrameChromium::YV16:
- drawYUV(yuvProgram);
- break;
- case VideoFrameChromium::RGBA:
- drawRGBA(rgbaProgram);
- break;
- default:
- // FIXME: Implement other paths.
- notImplemented();
- break;
- }
- releaseCurrentFrame();
-}
-
void VideoLayerChromium::releaseCurrentFrame()
{
if (!m_currentFrame)
@@ -262,86 +270,29 @@ void VideoLayerChromium::releaseCurrentFrame()
resetFrameParameters();
}
-void VideoLayerChromium::drawYUV(const VideoLayerChromium::YUVProgram* program)
-{
- GraphicsContext3D* context = layerRendererContext();
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::yPlane]));
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::uPlane]));
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane]));
-
- layerRenderer()->useShader(program->program());
- unsigned yFrameWidth = m_frameSizes[VideoFrameChromium::yPlane].width();
- unsigned yTextureWidth = m_textureSizes[VideoFrameChromium::yPlane].width();
- // Arbitrarily take the u sizes because u and v dimensions are identical.
- unsigned uvFrameWidth = m_frameSizes[VideoFrameChromium::uPlane].width();
- unsigned uvTextureWidth = m_textureSizes[VideoFrameChromium::uPlane].width();
-
- float yWidthScaleFactor = static_cast<float>(yFrameWidth) / yTextureWidth;
- float uvWidthScaleFactor = static_cast<float>(uvFrameWidth) / uvTextureWidth;
- GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
- GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
-
- GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1));
- GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2));
- GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3));
-
- // This value of 0.5 maps to 128. It is used in the YUV to RGB conversion
- // formula to turn unsigned u and v values to signed u and v values.
- // This is loaded as a uniform because certain drivers have problems
- // reading literal float values.
- GLC(context, context->uniform1f(program->fragmentShader().signAdjLocation(), 0.5));
-
- GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
-
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(),
- bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(),
- program->vertexShader().matrixLocation(),
- program->fragmentShader().alphaLocation());
-
- // Reset active texture back to texture 0.
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
-}
-
-void VideoLayerChromium::drawRGBA(const VideoLayerChromium::RGBAProgram* program)
-{
- GraphicsContext3D* context = layerRendererContext();
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::rgbPlane]));
-
- layerRenderer()->useShader(program->program());
- unsigned frameWidth = m_frameSizes[VideoFrameChromium::rgbPlane].width();
- unsigned textureWidth = m_textureSizes[VideoFrameChromium::rgbPlane].width();
- float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
- GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
-
- GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
-
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(),
- bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(),
- program->vertexShader().matrixLocation(),
- program->fragmentShader().alphaLocation());
-}
-
void VideoLayerChromium::resetFrameParameters()
{
+ deleteTexturesInUse();
for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
- m_textures[plane] = 0;
- m_textureSizes[plane] = IntSize();
- m_frameSizes[plane] = IntSize();
+ m_textures[plane].id = 0;
+ m_textures[plane].size = IntSize();
+ m_textures[plane].visibleSize = IntSize();
+ m_textures[plane].ownedByLayerRenderer = false;
+ m_textures[plane].isEmpty = true;
}
}
void VideoLayerChromium::saveCurrentFrame(VideoFrameChromium* frame)
{
ASSERT(!m_currentFrame);
+ deleteTexturesInUse();
m_currentFrame = frame;
for (unsigned plane = 0; plane < frame->planes(); plane++) {
- m_textures[plane] = frame->texture(plane);
- m_textureSizes[plane] = frame->requiredTextureSize(plane);
- m_frameSizes[plane] = m_textureSizes[plane];
+ m_textures[plane].id = frame->texture(plane);
+ m_textures[plane].size = frame->requiredTextureSize(plane);
+ m_textures[plane].visibleSize = computeVisibleSize(frame, plane);
+ m_textures[plane].ownedByLayerRenderer = false;
+ m_textures[plane].isEmpty = false;
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
index 2170e13..ef08bd8 100644
--- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -42,19 +42,28 @@ namespace WebCore {
// A Layer that contains a Video element.
class VideoLayerChromium : public LayerChromium {
public:
+ struct Texture {
+ unsigned id;
+ IntSize size;
+ IntSize visibleSize;
+ bool ownedByLayerRenderer;
+ bool isEmpty;
+ };
+
static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0,
VideoFrameProvider* = 0);
virtual ~VideoLayerChromium();
- virtual void updateContentsIfDirty();
+
+ virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
+
+ virtual void updateCompositorResources();
virtual bool drawsContent() const { return true; }
- virtual void draw();
// This function is called by VideoFrameProvider. When this method is called
// putCurrentFrame() must be called to return the frame currently held.
void releaseCurrentFrame();
- typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
- typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram;
+ virtual void pushPropertiesTo(CCLayerImpl*);
protected:
virtual void cleanupResources();
@@ -63,27 +72,27 @@ protected:
private:
VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider*);
- static unsigned determineTextureFormat(VideoFrameChromium*);
- bool allocateTexturesIfNeeded(GraphicsContext3D*, VideoFrameChromium*, unsigned textureFormat);
- void updateYUVContents(GraphicsContext3D*, const VideoFrameChromium*);
- void updateRGBAContents(GraphicsContext3D*, const VideoFrameChromium*);
- void allocateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat);
- void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data);
- void drawYUV(const YUVProgram*);
- void drawRGBA(const RGBAProgram*);
+ static unsigned determineTextureFormat(const VideoFrameChromium*);
+ static IntSize computeVisibleSize(const VideoFrameChromium*, unsigned plane);
+ void deleteTexturesInUse();
+
+ bool allocateTexturesIfNeeded(GraphicsContext3D*, const VideoFrameChromium*, unsigned textureFormat);
+ void allocateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat) const;
+
+ void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data) const;
+
void resetFrameParameters();
void saveCurrentFrame(VideoFrameChromium*);
- static const float yuv2RGB[9];
-
bool m_skipsDraw;
VideoFrameChromium::Format m_frameFormat;
VideoFrameProvider* m_provider;
- VideoFrameChromium* m_currentFrame;
- unsigned m_textures[3];
- IntSize m_textureSizes[3];
- IntSize m_frameSizes[3];
+ Texture m_textures[3];
+
+ // This will be null for the entire duration of video playback if hardware
+ // decoding is not being used.
+ VideoFrameChromium* m_currentFrame;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
index e83d045..652e752 100644
--- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
@@ -47,10 +47,11 @@ PassRefPtr<WebGLLayerChromium> WebGLLayerChromium::create(GraphicsLayerChromium*
WebGLLayerChromium::WebGLLayerChromium(GraphicsLayerChromium* owner)
: CanvasLayerChromium(owner)
, m_context(0)
+ , m_textureUpdated(false)
{
}
-void WebGLLayerChromium::updateContentsIfDirty()
+void WebGLLayerChromium::updateCompositorResources()
{
if (!m_contentsDirty)
return;
@@ -68,19 +69,28 @@ void WebGLLayerChromium::updateContentsIfDirty()
m_textureChanged = false;
}
// Update the contents of the texture used by the compositor.
- if (m_contentsDirty) {
+ if (m_contentsDirty && m_textureUpdated) {
m_context->prepareTexture();
+ m_context->markLayerComposited();
m_contentsDirty = false;
+ m_textureUpdated = false;
}
}
+void WebGLLayerChromium::setTextureUpdated()
+{
+ m_textureUpdated = true;
+}
+
void WebGLLayerChromium::setContext(const GraphicsContext3D* context)
{
m_context = const_cast<GraphicsContext3D*>(context);
unsigned int textureId = m_context->platformTexture();
- if (textureId != m_textureId)
+ if (textureId != m_textureId) {
m_textureChanged = true;
+ m_textureUpdated = true;
+ }
m_textureId = textureId;
m_premultipliedAlpha = m_context->getContextAttributes().premultipliedAlpha;
}
diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
index 70be876..33db730 100644
--- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
@@ -45,7 +45,8 @@ class WebGLLayerChromium : public CanvasLayerChromium {
public:
static PassRefPtr<WebGLLayerChromium> create(GraphicsLayerChromium* owner = 0);
virtual bool drawsContent() const { return m_context; }
- virtual void updateContentsIfDirty();
+ virtual void updateCompositorResources();
+ void setTextureUpdated();
void setContext(const GraphicsContext3D* context);
@@ -55,6 +56,7 @@ protected:
private:
explicit WebGLLayerChromium(GraphicsLayerChromium* owner);
GraphicsContext3D* m_context;
+ bool m_textureUpdated;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp
new file mode 100644
index 0000000..649d049
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 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"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "cc/CCCanvasLayerImpl.h"
+
+#include "CanvasLayerChromium.h"
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+CCCanvasLayerImpl::CCCanvasLayerImpl(LayerChromium* owner)
+ : CCLayerImpl(owner)
+ , m_textureId(0)
+ , m_premultipliedAlpha(true)
+{
+}
+
+CCCanvasLayerImpl::~CCCanvasLayerImpl()
+{
+}
+
+void CCCanvasLayerImpl::draw()
+{
+ ASSERT(layerRenderer());
+ const CCCanvasLayerImpl::Program* program = layerRenderer()->canvasLayerProgram();
+ ASSERT(program && program->initialized());
+ GraphicsContext3D* context = layerRenderer()->context();
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));
+ GC3Denum sfactor = m_premultipliedAlpha ? GraphicsContext3D::ONE : GraphicsContext3D::SRC_ALPHA;
+ GLC(context, context->blendFunc(sfactor, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
+ layerRenderer()->useShader(program->program());
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+ LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+
+}
+
+
+void CCCanvasLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "canvas layer texture id: " << m_textureId << " premultiplied: " << m_premultipliedAlpha << "\n";
+ CCLayerImpl::dumpLayerProperties(ts, indent);
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
new file mode 100644
index 0000000..8cbf8d1
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 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 CCCanvasLayerImpl_h
+#define CCCanvasLayerImpl_h
+
+#include "ProgramBinding.h"
+#include "ShaderChromium.h"
+#include "cc/CCLayerImpl.h"
+
+namespace WebCore {
+
+class CCCanvasLayerImpl : public CCLayerImpl {
+public:
+ static PassRefPtr<CCCanvasLayerImpl> create(LayerChromium* owner)
+ {
+ return adoptRef(new CCCanvasLayerImpl(owner));
+ }
+ virtual ~CCCanvasLayerImpl();
+
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
+
+ virtual void draw();
+
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
+
+ void setTextureId(unsigned id) { m_textureId = id; }
+ void setPremultipliedAlpha(bool premultipliedAlpha) { m_premultipliedAlpha = premultipliedAlpha; }
+private:
+ explicit CCCanvasLayerImpl(LayerChromium*);
+
+ unsigned m_textureId;
+ bool m_premultipliedAlpha;
+};
+
+}
+
+#endif // CCCanvasLayerImpl_h
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
index 604ef61..404944b 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
@@ -66,8 +66,8 @@ void CCHeadsUpDisplay::draw()
// Use a fullscreen texture only if we need to...
IntSize hudSize;
if (m_showPlatformLayerTree) {
- hudSize.setWidth(min(2048, m_layerRenderer->visibleRectSize().width()));
- hudSize.setHeight(min(2048, m_layerRenderer->visibleRectSize().height()));
+ hudSize.setWidth(min(2048, m_layerRenderer->viewportSize().width()));
+ hudSize.setHeight(min(2048, m_layerRenderer->viewportSize().height()));
} else {
hudSize.setWidth(512);
hudSize.setHeight(128);
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
index dbac22a..d56f8ab 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
@@ -53,7 +53,7 @@ public:
void setShowPlatformLayerTree(bool enable) { m_showPlatformLayerTree = enable; }
bool showPlatformLayerTree() const { return m_showPlatformLayerTree; }
- bool enabled() const { return true || m_showPlatformLayerTree || m_showFPSCounter; }
+ bool enabled() const { return m_showPlatformLayerTree || m_showFPSCounter; }
void draw();
private:
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
index a0ad0fb..9411e5a 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
@@ -62,13 +62,18 @@ namespace WebCore {
CCLayerImpl::CCLayerImpl(LayerChromium* owner)
: m_owner(owner)
+ , m_anchorPoint(0.5, 0.5)
+ , m_anchorPointZ(0)
+ , m_doubleSided(true)
+ , m_masksToBounds(false)
+ , m_opacity(1.0)
+ , m_preserves3D(false)
#ifndef NDEBUG
, m_debugID(owner->debugID())
#endif
, m_targetRenderSurface(0)
, m_drawDepth(0)
, m_drawOpacity(0)
- , m_doubleSided(true)
, m_debugBorderColor(0, 0, 0, 0)
, m_debugBorderWidth(0)
, m_renderSurface(0)
@@ -107,7 +112,18 @@ RenderSurfaceChromium* CCLayerImpl::createRenderSurface()
return m_renderSurface.get();
}
-// These belong on CCLayerImpl, but should be subclased by each type and not defer to the LayerChromium subtypes.
+bool CCLayerImpl::descendantsDrawsContent()
+{
+ const Vector<RefPtr<LayerChromium> >& sublayers = m_owner->getSublayers();
+ for (size_t i = 0; i < sublayers.size(); ++i) {
+ sublayers[i]->createCCLayerImplIfNeeded();
+ if (sublayers[i]->ccLayerImpl()->drawsContent() || sublayers[i]->ccLayerImpl()->descendantsDrawsContent())
+ return true;
+ }
+ return false;
+}
+
+// These belong on CCLayerImpl, but should be overridden by each type and not defer to the LayerChromium subtypes.
bool CCLayerImpl::drawsContent() const
{
return m_owner->drawsContent();
@@ -118,6 +134,11 @@ void CCLayerImpl::draw()
return m_owner->draw();
}
+void CCLayerImpl::updateCompositorResources()
+{
+ return m_owner->updateCompositorResources();
+}
+
void CCLayerImpl::unreserveContentsTexture()
{
m_owner->unreserveContentsTexture();
@@ -167,7 +188,7 @@ void CCLayerImpl::drawDebugBorder()
GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short)));
}
-static void writeIndent(TextStream& ts, int indent)
+void CCLayerImpl::writeIndent(TextStream& ts, int indent)
{
for (int i = 0; i != indent; ++i)
ts << " ";
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
index 6892976..96c4f1b 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
@@ -49,7 +49,7 @@ public:
return adoptRef(new CCLayerImpl(owner));
}
// When this class gets subclasses, remember to add 'virtual' here.
- ~CCLayerImpl();
+ virtual ~CCLayerImpl();
#ifndef NDEBUG
int debugID() const { return m_debugID; }
@@ -59,13 +59,43 @@ public:
CCLayerImpl* maskLayer() const;
CCLayerImpl* replicaLayer() const;
- void draw();
- bool drawsContent() const;
+ virtual void draw();
+ virtual void updateCompositorResources();
void unreserveContentsTexture();
void bindContentsTexture();
+ // Returns true if this layer has content to draw.
+ virtual bool drawsContent() const;
+
+ // Returns true if any of the layer's descendants has content to draw.
+ bool descendantsDrawsContent();
+
void cleanupResources();
+ void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; }
+ const FloatPoint& anchorPoint() const { return m_anchorPoint; }
+
+ void setAnchorPointZ(float anchorPointZ) { m_anchorPointZ = anchorPointZ; }
+ float anchorPointZ() const { return m_anchorPointZ; }
+
+ void setMasksToBounds(bool masksToBounds) { m_masksToBounds = masksToBounds; }
+ bool masksToBounds() const { return m_masksToBounds; }
+
+ void setOpacity(float opacity) { m_opacity = opacity; }
+ float opacity() const { return m_opacity; }
+
+ void setPosition(const FloatPoint& position) { m_position = position; }
+ const FloatPoint& position() const { return m_position; }
+
+ void setPreserves3D(bool preserves3D) { m_preserves3D = preserves3D; }
+ bool preserves3D() const { return m_preserves3D; }
+
+ void setSublayerTransform(const TransformationMatrix& sublayerTransform) { m_sublayerTransform = sublayerTransform; }
+ const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; }
+
+ void setTransform(const TransformationMatrix& transform) { m_transform = transform; }
+ const TransformationMatrix& transform() const { return m_transform; }
+
void setName(const String& name) { m_name = name; }
const String& name() const { return m_name; }
@@ -108,11 +138,30 @@ public:
virtual void dumpLayerProperties(TextStream&, int indent) const;
-private:
+protected:
// For now, CCLayers are owned directly by a LayerChromium.
LayerChromium* m_owner;
explicit CCLayerImpl(LayerChromium*);
+ static void writeIndent(TextStream&, int indent);
+
+private:
+ // Properties synchronized from the associated LayerChromium.
+ FloatPoint m_anchorPoint;
+ float m_anchorPointZ;
+ IntSize m_bounds;
+
+ // Whether the "back" of this layer should draw.
+ bool m_doubleSided;
+
+ bool m_masksToBounds;
+ float m_opacity;
+ FloatPoint m_position;
+ bool m_preserves3D;
+ TransformationMatrix m_sublayerTransform;
+ TransformationMatrix m_transform;
+
+ // Properties owned exclusively by this CCLayerImpl.
// Debugging.
#ifndef NDEBUG
int m_debugID;
@@ -131,17 +180,12 @@ private:
float m_drawDepth;
float m_drawOpacity;
- // Whether the "back" of this layer should draw.
- bool m_doubleSided;
-
// Debug borders.
Color m_debugBorderColor;
float m_debugBorderWidth;
TransformationMatrix m_drawTransform;
- IntSize m_bounds;
-
// The scissor rectangle that should be used when this layer is drawn.
// Inherited by the parent layer and further restricted if this layer masks
// to bounds.
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
new file mode 100644
index 0000000..4aef639
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 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"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "cc/CCPluginLayerImpl.h"
+
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+#include "PluginLayerChromium.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+CCPluginLayerImpl::CCPluginLayerImpl(LayerChromium* owner)
+ : CCLayerImpl(owner)
+ , m_textureId(0)
+{
+}
+
+CCPluginLayerImpl::~CCPluginLayerImpl()
+{
+}
+
+void CCPluginLayerImpl::draw()
+{
+ ASSERT(layerRenderer());
+ const CCPluginLayerImpl::Program* program = layerRenderer()->pluginLayerProgram();
+ ASSERT(program && program->initialized());
+ GraphicsContext3D* context = layerRenderer()->context();
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));
+
+ // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
+ // where it will only happen once per texture.
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
+
+ layerRenderer()->useShader(program->program());
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+ LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+}
+
+
+void CCPluginLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "plugin layer texture id: " << m_textureId << "\n";
+ CCLayerImpl::dumpLayerProperties(ts, indent);
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
new file mode 100644
index 0000000..65eb5b7
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 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 CCPluginLayerImpl_h
+#define CCPluginLayerImpl_h
+
+#include "ProgramBinding.h"
+#include "ShaderChromium.h"
+#include "cc/CCLayerImpl.h"
+
+namespace WebCore {
+
+class CCPluginLayerImpl : public CCLayerImpl {
+public:
+ static PassRefPtr<CCPluginLayerImpl> create(LayerChromium* owner)
+ {
+ return adoptRef(new CCPluginLayerImpl(owner));
+ }
+ virtual ~CCPluginLayerImpl();
+
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
+
+ virtual void draw();
+
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
+
+ void setTextureId(unsigned id) { m_textureId = id; }
+
+private:
+ explicit CCPluginLayerImpl(LayerChromium*);
+
+ unsigned m_textureId;
+};
+
+}
+
+#endif // CCPluginLayerImpl_h
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
new file mode 100644
index 0000000..eb3612b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2011 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"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "cc/CCVideoLayerImpl.h"
+
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+#include "NotImplemented.h"
+#include "VideoLayerChromium.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// These values are magic numbers that are used in the transformation
+// from YUV to RGB color values.
+// They are taken from the following webpage:
+// http://www.fourcc.org/fccyvrgb.php
+const float CCVideoLayerImpl::yuv2RGB[9] = {
+ 1.164f, 1.164f, 1.164f,
+ 0.f, -.391f, 2.018f,
+ 1.596f, -.813f, 0.f,
+};
+
+// These values map to 16, 128, and 128 respectively, and are computed
+// as a fraction over 256 (e.g. 16 / 256 = 0.0625).
+// They are used in the YUV to RGBA conversion formula:
+// Y - 16 : Gives 16 values of head and footroom for overshooting
+// U - 128 : Turns unsigned U into signed U [-128,127]
+// V - 128 : Turns unsigned V into signed V [-128,127]
+const float CCVideoLayerImpl::yuvAdjust[3] = {
+ -0.0625f,
+ -0.5f,
+ -0.5f,
+};
+
+CCVideoLayerImpl::CCVideoLayerImpl(LayerChromium* owner)
+ : CCLayerImpl(owner)
+{
+}
+
+CCVideoLayerImpl::~CCVideoLayerImpl()
+{
+ cleanupResources();
+}
+
+void CCVideoLayerImpl::setTexture(size_t i, VideoLayerChromium::Texture texture)
+{
+ ASSERT(i < 3);
+ m_textures[i] = texture;
+}
+
+void CCVideoLayerImpl::draw()
+{
+ if (m_skipsDraw)
+ return;
+
+ ASSERT(layerRenderer());
+ const RGBAProgram* rgbaProgram = layerRenderer()->videoLayerRGBAProgram();
+ ASSERT(rgbaProgram && rgbaProgram->initialized());
+ const YUVProgram* yuvProgram = layerRenderer()->videoLayerYUVProgram();
+ ASSERT(yuvProgram && yuvProgram->initialized());
+
+ switch (m_frameFormat) {
+ case VideoFrameChromium::YV12:
+ case VideoFrameChromium::YV16:
+ drawYUV(yuvProgram);
+ break;
+ case VideoFrameChromium::RGBA:
+ drawRGBA(rgbaProgram);
+ break;
+ default:
+ // FIXME: Implement other paths.
+ notImplemented();
+ break;
+ }
+}
+
+void CCVideoLayerImpl::drawYUV(const CCVideoLayerImpl::YUVProgram* program) const
+{
+ GraphicsContext3D* context = layerRenderer()->context();
+ VideoLayerChromium::Texture yTexture = m_textures[VideoFrameChromium::yPlane];
+ VideoLayerChromium::Texture uTexture = m_textures[VideoFrameChromium::uPlane];
+ VideoLayerChromium::Texture vTexture = m_textures[VideoFrameChromium::vPlane];
+
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.id));
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.id));
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.id));
+
+ layerRenderer()->useShader(program->program());
+
+ float yWidthScaleFactor = static_cast<float>(yTexture.visibleSize.width()) / yTexture.size.width();
+ // Arbitrarily take the u sizes because u and v dimensions are identical.
+ float uvWidthScaleFactor = static_cast<float>(uTexture.visibleSize.width()) / uTexture.size.width();
+ GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
+ GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
+
+ GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1));
+ GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2));
+ GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3));
+
+ GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
+ GLC(context, context->uniform3fv(program->fragmentShader().yuvAdjLocation(), const_cast<float*>(yuvAdjust), 1));
+
+ LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+
+ // Reset active texture back to texture 0.
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+}
+
+void CCVideoLayerImpl::drawRGBA(const CCVideoLayerImpl::RGBAProgram* program) const
+{
+ GraphicsContext3D* context = layerRenderer()->context();
+ VideoLayerChromium::Texture texture = m_textures[VideoFrameChromium::rgbPlane];
+
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture.id));
+
+ layerRenderer()->useShader(program->program());
+ float widthScaleFactor = static_cast<float>(texture.visibleSize.width()) / texture.size.width();
+ GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
+
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+
+ LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+}
+
+
+void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "video layer\n";
+ CCLayerImpl::dumpLayerProperties(ts, indent);
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
new file mode 100644
index 0000000..62f8778
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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 CCVideoLayerImpl_h
+#define CCVideoLayerImpl_h
+
+#include "ProgramBinding.h"
+#include "ShaderChromium.h"
+#include "VideoFrameChromium.h"
+#include "VideoLayerChromium.h"
+#include "cc/CCLayerImpl.h"
+
+namespace WebCore {
+
+class VideoFrameProvider;
+
+class CCVideoLayerImpl : public CCLayerImpl {
+public:
+ static PassRefPtr<CCVideoLayerImpl> create(LayerChromium* owner)
+ {
+ return adoptRef(new CCVideoLayerImpl(owner));
+ }
+ virtual ~CCVideoLayerImpl();
+
+ typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
+ typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram;
+
+ virtual void draw();
+
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
+
+ void setSkipsDraw(bool skipsDraw) { m_skipsDraw = skipsDraw; }
+ void setFrameFormat(VideoFrameChromium::Format format) { m_frameFormat = format; }
+ void setTexture(size_t, VideoLayerChromium::Texture);
+
+private:
+ explicit CCVideoLayerImpl(LayerChromium*);
+
+ void drawYUV(const YUVProgram*) const;
+ void drawRGBA(const RGBAProgram*) const;
+
+ static const float yuv2RGB[9];
+ static const float yuvAdjust[3];
+
+ bool m_skipsDraw;
+ VideoFrameChromium::Format m_frameFormat;
+ VideoLayerChromium::Texture m_textures[3];
+};
+
+}
+
+#endif // CCVideoLayerImpl_h
+
diff --git a/Source/WebCore/platform/graphics/cocoa/FontPlatformData.h b/Source/WebCore/platform/graphics/cocoa/FontPlatformData.h
deleted file mode 100644
index ca38029..0000000
--- a/Source/WebCore/platform/graphics/cocoa/FontPlatformData.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * This file is part of the internal font implementation.
- * It should not be included by source files outside of it.
- *
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * 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.
- *
- */
-
-#ifndef FontPlatformData_h
-#define FontPlatformData_h
-
-#include "FontOrientation.h"
-#include "FontWidthVariant.h"
-#include <wtf/text/StringImpl.h>
-
-#ifdef __OBJC__
-@class NSFont;
-#else
-class NSFont;
-#endif
-
-typedef struct CGFont* CGFontRef;
-#ifndef BUILDING_ON_TIGER
-typedef const struct __CTFont* CTFontRef;
-#endif
-
-#include <CoreFoundation/CFBase.h>
-#include <objc/objc-auto.h>
-#include <wtf/Forward.h>
-#include <wtf/RetainPtr.h>
-
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
-#include "CrossProcessFontLoading.h"
-#endif
-
-
-typedef UInt32 ATSUFontID;
-typedef UInt32 ATSFontRef;
-
-namespace WebCore {
-
-#ifndef BUILDING_ON_TIGER
-inline CTFontRef toCTFontRef(NSFont *nsFont) { return reinterpret_cast<CTFontRef>(nsFont); }
-#endif
-
-class FontPlatformData {
- public:
- FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation = Horizontal, FontWidthVariant widthVariant = RegularWidth)
- : m_syntheticBold(syntheticBold)
- , m_syntheticOblique(syntheticOblique)
- , m_orientation(orientation)
- , m_size(size)
- , m_widthVariant(widthVariant)
- , m_font(0)
-#ifdef BUILDING_ON_TIGER
- , m_cgFont(0)
-#endif
- , m_isColorBitmapFont(false)
- {
- }
-
- FontPlatformData(NSFont*, float size, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = Horizontal, FontWidthVariant = RegularWidth);
-
- FontPlatformData(CGFontRef cgFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, FontWidthVariant widthVariant)
- : m_syntheticBold(syntheticBold)
- , m_syntheticOblique(syntheticOblique)
- , m_orientation(orientation)
- , m_size(size)
- , m_widthVariant(widthVariant)
- , m_font(0)
- , m_cgFont(cgFont)
- , m_isColorBitmapFont(false)
- {
- }
-
- FontPlatformData(const FontPlatformData&);
-
- ~FontPlatformData();
-
- FontPlatformData(WTF::HashTableDeletedValueType) : m_font(hashTableDeletedFontValue()) { }
- bool isHashTableDeletedValue() const { return m_font == hashTableDeletedFontValue(); }
-
- float size() const { return m_size; }
- bool syntheticBold() const { return m_syntheticBold; }
- bool syntheticOblique() const { return m_syntheticOblique; }
- FontOrientation orientation() const { return m_orientation; }
- FontWidthVariant widthVariant() const { return m_widthVariant; }
-
- bool m_syntheticBold;
- bool m_syntheticOblique;
- FontOrientation m_orientation;
-
- float m_size;
-
- FontWidthVariant m_widthVariant;
-
- unsigned hash() const
- {
- ASSERT(m_font != 0 || m_cgFont == 0);
- uintptr_t hashCodes[3] = { (uintptr_t)m_font, m_widthVariant, m_orientation << 2 | m_syntheticBold << 1 | m_syntheticOblique };
- return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
- }
-
- const FontPlatformData& operator=(const FontPlatformData& f);
-
- bool operator==(const FontPlatformData& other) const
- {
- return m_font == other.m_font && m_syntheticBold == other.m_syntheticBold && m_syntheticOblique == other.m_syntheticOblique &&
- m_cgFont == other.m_cgFont && m_size == other.m_size && m_orientation == other.m_orientation && m_widthVariant == other.m_widthVariant;
- }
-
- NSFont *font() const { return m_font; }
- void setFont(NSFont *font);
-
- CTFontRef ctFont() const;
-
- bool roundsGlyphAdvances() const;
- bool allowsLigatures() const;
- bool isColorBitmapFont() const { return m_isColorBitmapFont; }
-
-#ifndef BUILDING_ON_TIGER
- CGFontRef cgFont() const { return m_cgFont.get(); }
-#else
- CGFontRef cgFont() const { return m_cgFont; }
-#endif
-
-#ifndef NDEBUG
- String description() const;
-#endif
-
-private:
- static NSFont *hashTableDeletedFontValue() { return reinterpret_cast<NSFont *>(-1); }
-
- // Load various data about the font specified by |nsFont| with the size fontSize into the following output paramters:
- // Note: Callers should always take into account that for the Chromium port, |outNSFont| isn't necessarily the same
- // font as |nsFont|. This because the sandbox may block loading of the original font.
- // * outNSFont - The font that was actually loaded, for the Chromium port this may be different than nsFont.
- // The caller is responsible for calling CFRelease() on this parameter when done with it.
- // * cgFont - CGFontRef representing the input font at the specified point size.
- void loadFont(NSFont* nsFont, float fontSize, NSFont*& outNSFont, CGFontRef& cgFont);
-
- NSFont *m_font;
-
-#ifndef BUILDING_ON_TIGER
- RetainPtr<CGFontRef> m_cgFont;
-#else
- CGFontRef m_cgFont; // It is not necessary to refcount this, since either an NSFont owns it or some CachedFont has it referenced.
-#endif
-
- mutable RetainPtr<CTFontRef> m_CTFont;
-
- bool m_isColorBitmapFont;
-
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
- RefPtr<MemoryActivatedFont> m_inMemoryFont;
-#endif
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm b/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
index b40f698..6a17707 100644
--- a/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
+++ b/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
@@ -45,9 +45,12 @@ void FontPlatformData::loadFont(NSFont* nsFont, float, NSFont*& outNSFont, CGFon
}
#endif // PLATFORM(MAC)
-FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, FontWidthVariant widthVariant)
+FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation,
+ TextOrientation textOrientation, FontWidthVariant widthVariant)
: m_syntheticBold(syntheticBold)
, m_syntheticOblique(syntheticOblique)
+ , m_orientation(orientation)
+ , m_textOrientation(textOrientation)
, m_size(size)
, m_widthVariant(widthVariant)
, m_font(nsFont)
@@ -64,8 +67,6 @@ FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBol
CGFontRef cgFont = 0;
loadFont(nsFont, size, m_font, cgFont);
- m_orientation = orientation;
-
if (m_font)
CFRetain(m_font);
@@ -76,35 +77,26 @@ FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBol
#endif
}
-FontPlatformData::FontPlatformData(const FontPlatformData& f)
+FontPlatformData:: ~FontPlatformData()
+{
+ if (m_font && m_font != reinterpret_cast<NSFont *>(-1))
+ CFRelease(m_font);
+}
+
+void FontPlatformData::platformDataInit(const FontPlatformData& f)
{
m_font = f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1) ? const_cast<NSFont *>(static_cast<const NSFont *>(CFRetain(f.m_font))) : f.m_font;
- m_syntheticBold = f.m_syntheticBold;
- m_syntheticOblique = f.m_syntheticOblique;
- m_size = f.m_size;
- m_widthVariant = f.m_widthVariant;
m_cgFont = f.m_cgFont;
- m_isColorBitmapFont = f.m_isColorBitmapFont;
- m_orientation = f.m_orientation;
m_CTFont = f.m_CTFont;
+
#if PLATFORM(CHROMIUM) && OS(DARWIN)
m_inMemoryFont = f.m_inMemoryFont;
#endif
}
-FontPlatformData:: ~FontPlatformData()
+const FontPlatformData& FontPlatformData::platformDataAssign(const FontPlatformData& f)
{
- if (m_font && m_font != reinterpret_cast<NSFont *>(-1))
- CFRelease(m_font);
-}
-
-const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f)
-{
- m_syntheticBold = f.m_syntheticBold;
- m_syntheticOblique = f.m_syntheticOblique;
- m_size = f.m_size;
- m_widthVariant = f.m_widthVariant;
m_cgFont = f.m_cgFont;
if (m_font == f.m_font)
return *this;
@@ -113,8 +105,6 @@ const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f)
if (m_font && m_font != reinterpret_cast<NSFont *>(-1))
CFRelease(m_font);
m_font = f.m_font;
- m_isColorBitmapFont = f.m_isColorBitmapFont;
- m_orientation = f.m_orientation;
m_CTFont = f.m_CTFont;
#if PLATFORM(CHROMIUM) && OS(DARWIN)
m_inMemoryFont = f.m_inMemoryFont;
@@ -122,6 +112,12 @@ const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f)
return *this;
}
+bool FontPlatformData::platformIsEqual(const FontPlatformData& other) const
+{
+ return m_font == other.m_font
+ && m_cgFont == other.m_cgFont;
+}
+
void FontPlatformData::setFont(NSFont *font)
{
ASSERT_ARG(font, font);
diff --git a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp
index 841c8a3..b1cf96b 100644
--- a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp
+++ b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp
@@ -59,7 +59,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
cairo_font_face_destroy(m_fontFace);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode)
{
return FontPlatformData(m_fontFace, size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/freetype/FontPlatformData.h b/Source/WebCore/platform/graphics/freetype/FontPlatformData.h
index 2841b14..d1cb605 100644
--- a/Source/WebCore/platform/graphics/freetype/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/freetype/FontPlatformData.h
@@ -71,6 +71,7 @@ public:
bool hasCompatibleCharmap();
FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
+ void setOrientation(FontOrientation) { } // FIXME: Implement.
cairo_scaled_font_t* scaledFont() const { return m_scaledFont; }
diff --git a/Source/WebCore/platform/graphics/gpu/BicubicShader.cpp b/Source/WebCore/platform/graphics/gpu/BicubicShader.cpp
new file mode 100644
index 0000000..40c9843
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/BicubicShader.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+
+#include "BicubicShader.h"
+
+#include "GraphicsContext3D.h"
+
+namespace WebCore {
+
+BicubicShader::BicubicShader(GraphicsContext3D* context, unsigned program)
+ : Shader(context, program)
+ , m_matrixLocation(context->getUniformLocation(program, "matrix"))
+ , m_texMatrixLocation(context->getUniformLocation(program, "texMatrix"))
+ , m_coefficientsLocation(context->getUniformLocation(program, "coefficients"))
+ , m_imageIncrementLocation(context->getUniformLocation(program, "imageIncrement"))
+ , m_imageLocation(context->getUniformLocation(program, "image"))
+ , m_alphaLocation(context->getUniformLocation(program, "alpha"))
+ , m_positionLocation(context->getAttribLocation(program, "position"))
+{
+}
+
+PassOwnPtr<BicubicShader> BicubicShader::create(GraphicsContext3D* context)
+{
+ static const char* vertexShaderSource =
+ "uniform mat3 matrix;\n"
+ "uniform mat3 texMatrix;\n"
+ "attribute vec3 position;\n"
+ "varying vec2 texCoord;\n"
+ "void main() {\n"
+ " texCoord = (texMatrix * position).xy;\n"
+ " gl_Position = vec4(matrix * position, 1.0);\n"
+ "}\n";
+ static const char* fragmentShaderSource =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "uniform sampler2D image;\n"
+ "uniform vec2 imageIncrement;\n"
+ "uniform mat4 coefficients;\n"
+ "uniform float alpha;\n"
+ "varying vec2 texCoord;\n"
+ "vec4 cubicBlend(float t, vec4 c0, vec4 c1, vec4 c2, vec4 c3) {\n"
+ " vec4 ts = vec4(1.0, t, t * t, t * t * t);\n"
+ " vec4 result = coefficients * ts;\n"
+ " return result.w * c0 + result.z * c1 + result.y * c2 + result.x * c3;\n"
+ "}\n"
+ "void main() {\n"
+ " vec2 imageCoord = texCoord;\n"
+ " vec2 f = fract(imageCoord / imageIncrement) - vec2(0.5, 0.5);\n"
+ " vec4 t00 = texture2D(image, imageCoord + imageIncrement * vec2(-1, -1));\n"
+ " vec4 t10 = texture2D(image, imageCoord + imageIncrement * vec2( 0, -1));\n"
+ " vec4 t20 = texture2D(image, imageCoord + imageIncrement * vec2( 1, -1));\n"
+ " vec4 t30 = texture2D(image, imageCoord + imageIncrement * vec2( 2, -1));\n"
+ " vec4 t0 = cubicBlend(f.x, t00, t10, t20, t30);\n"
+ " vec4 t01 = texture2D(image, imageCoord + imageIncrement * vec2(-1, 0));\n"
+ " vec4 t11 = texture2D(image, imageCoord + imageIncrement * vec2( 0, 0));\n"
+ " vec4 t21 = texture2D(image, imageCoord + imageIncrement * vec2( 1, 0));\n"
+ " vec4 t31 = texture2D(image, imageCoord + imageIncrement * vec2( 2, 0));\n"
+ " vec4 t1 = cubicBlend(f.x, t01, t11, t21, t31);\n"
+ " vec4 t02 = texture2D(image, imageCoord + imageIncrement * vec2(-1, 1));\n"
+ " vec4 t12 = texture2D(image, imageCoord + imageIncrement * vec2( 0, 1));\n"
+ " vec4 t22 = texture2D(image, imageCoord + imageIncrement * vec2( 1, 1));\n"
+ " vec4 t32 = texture2D(image, imageCoord + imageIncrement * vec2( 2, 1));\n"
+ " vec4 t2 = cubicBlend(f.x, t02, t12, t22, t32);\n"
+ " vec4 t03 = texture2D(image, imageCoord + imageIncrement * vec2(-1, 2));\n"
+ " vec4 t13 = texture2D(image, imageCoord + imageIncrement * vec2( 0, 2));\n"
+ " vec4 t23 = texture2D(image, imageCoord + imageIncrement * vec2( 1, 2));\n"
+ " vec4 t33 = texture2D(image, imageCoord + imageIncrement * vec2( 2, 2));\n"
+ " vec4 t3 = cubicBlend(f.x, t03, t13, t23, t33);\n"
+ " gl_FragColor = cubicBlend(f.y, t0, t1, t2, t3);\n"
+ "}\n";
+
+ unsigned program = loadProgram(context, vertexShaderSource, fragmentShaderSource);
+ if (!program)
+ return 0;
+
+ return new BicubicShader(context, program);
+}
+
+void BicubicShader::use(const AffineTransform& transform, const AffineTransform& texTransform, const float coefficients[16], const float imageIncrement[2], float alpha)
+{
+ m_context->useProgram(m_program);
+ float matrix[9];
+ affineTo3x3(transform, matrix);
+ m_context->uniformMatrix3fv(m_matrixLocation, false /*transpose*/, matrix, 1 /*count*/);
+
+ float texMatrix[9];
+ affineTo3x3(texTransform, texMatrix);
+ m_context->uniformMatrix3fv(m_texMatrixLocation, false /*transpose*/, texMatrix, 1 /*count*/);
+ m_context->uniformMatrix4fv(m_coefficientsLocation, false /*transpose*/, const_cast<float *>(coefficients), 1 /*count*/);
+
+ m_context->uniform2f(m_imageIncrementLocation, imageIncrement[0], imageIncrement[1]);
+
+ // For now, we always use texture unit 0. If that ever changes, we should
+ // expose this parameter to the caller.
+ m_context->uniform1i(m_imageLocation, 0);
+ m_context->uniform1f(m_alphaLocation, alpha);
+
+ m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+
+ m_context->enableVertexAttribArray(m_positionLocation);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/graphics/gpu/BicubicShader.h b/Source/WebCore/platform/graphics/gpu/BicubicShader.h
new file mode 100644
index 0000000..f7522f4
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/BicubicShader.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BicubicShader_h
+#define BicubicShader_h
+
+#include "Shader.h"
+
+namespace WebCore {
+
+class BicubicShader : public Shader {
+public:
+ static PassOwnPtr<BicubicShader> create(GraphicsContext3D*);
+
+ void use(const AffineTransform&, const AffineTransform& texTransform, const float coefficients[16], const float imageIncrement[2], float alpha);
+
+private:
+ BicubicShader(GraphicsContext3D*, unsigned program);
+
+ int m_matrixLocation;
+ int m_texMatrixLocation;
+ int m_coefficientsLocation;
+ int m_imageIncrementLocation;
+ int m_imageLocation;
+ int m_alphaLocation;
+ int m_positionLocation;
+};
+
+}
+
+#endif // BicubicShader_h
diff --git a/Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp b/Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp
new file mode 100644
index 0000000..f0b6bd9
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(ACCELERATED_2D_CANVAS)
+
+#include "ConvolutionShader.h"
+
+#include "GraphicsContext3D.h"
+#include "StringExtras.h"
+
+namespace WebCore {
+
+ConvolutionShader::ConvolutionShader(GraphicsContext3D* context, unsigned program, int kernelWidth)
+ : Shader(context, program)
+ , m_kernelWidth(kernelWidth)
+ , m_matrixLocation(context->getUniformLocation(program, "matrix"))
+ , m_texMatrixLocation(context->getUniformLocation(program, "texMatrix"))
+ , m_kernelLocation(context->getUniformLocation(program, "kernel"))
+ , m_imageLocation(context->getUniformLocation(program, "image"))
+ , m_imageIncrementLocation(context->getUniformLocation(program, "imageIncrement"))
+ , m_positionLocation(context->getAttribLocation(program, "position"))
+{
+}
+
+PassOwnPtr<ConvolutionShader> ConvolutionShader::create(GraphicsContext3D* context, int kernelWidth)
+{
+ static const char* vertexShaderRaw =
+ "#define KERNEL_WIDTH %d\n"
+ "uniform mat3 matrix;\n"
+ "uniform mat3 texMatrix;\n"
+ "uniform vec2 imageIncrement;\n"
+ "attribute vec3 position;\n"
+ "varying vec2 imageCoord;\n"
+ "void main() {\n"
+ " // Offset image coords by half of kernel width, in image texels\n"
+ " gl_Position = vec4(matrix * position, 1.0);\n"
+ " float scale = (float(KERNEL_WIDTH) - 1.0) / 2.0;\n"
+ " imageCoord = (texMatrix * position).xy - vec2(scale, scale) * imageIncrement;\n"
+ "}\n";
+ char vertexShaderSource[1024];
+ snprintf(vertexShaderSource, sizeof(vertexShaderSource), vertexShaderRaw, kernelWidth);
+ static const char* fragmentShaderRaw =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "#define KERNEL_WIDTH %d\n"
+ "uniform sampler2D image;\n"
+ "uniform float kernel[KERNEL_WIDTH];\n"
+ "uniform vec2 imageIncrement;\n"
+ "varying vec2 imageCoord;\n"
+ "void main() {\n"
+ " vec2 coord = imageCoord;\n"
+ " vec4 sum = vec4(0, 0, 0, 0);\n"
+ " for (int i = 0; i < KERNEL_WIDTH; i++) {\n"
+ " sum += texture2D(image, coord) * kernel[i];\n"
+ " coord += imageIncrement;\n"
+ " }\n"
+ " gl_FragColor = sum;\n"
+ "}\n";
+ char fragmentShaderSource[1024];
+ snprintf(fragmentShaderSource, sizeof(fragmentShaderSource), fragmentShaderRaw, kernelWidth);
+
+ unsigned program = loadProgram(context, vertexShaderSource, fragmentShaderSource);
+ if (!program)
+ return 0;
+ return new ConvolutionShader(context, program, kernelWidth);
+}
+
+void ConvolutionShader::use(const AffineTransform& transform, const AffineTransform& texTransform, const float* kernel, int kernelWidth, float imageIncrement[2])
+{
+ m_context->useProgram(m_program);
+ float matrix[9];
+ affineTo3x3(transform, matrix);
+ m_context->uniformMatrix3fv(m_matrixLocation, false /*transpose*/, matrix, 1 /*count*/);
+
+ float texMatrix[9];
+ affineTo3x3(texTransform, texMatrix);
+ m_context->uniformMatrix3fv(m_texMatrixLocation, false /*transpose*/, texMatrix, 1 /*count*/);
+
+ m_context->uniform2f(m_imageIncrementLocation, imageIncrement[0], imageIncrement[1]);
+
+ // For now, we always use texture unit 0. If that ever changes, we should
+ // expose this parameter to the caller.
+ m_context->uniform1i(m_imageLocation, 0);
+ if (kernelWidth > m_kernelWidth)
+ kernelWidth = m_kernelWidth;
+ m_context->uniform1fv(m_kernelLocation, const_cast<float*>(kernel), kernelWidth);
+
+ m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+
+ m_context->enableVertexAttribArray(m_positionLocation);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/graphics/gpu/ConvolutionShader.h b/Source/WebCore/platform/graphics/gpu/ConvolutionShader.h
new file mode 100644
index 0000000..533e0f5
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/ConvolutionShader.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ConvolutionShader_h
+#define ConvolutionShader_h
+
+#include "Shader.h"
+
+namespace WebCore {
+
+class ConvolutionShader : public Shader {
+public:
+ static PassOwnPtr<ConvolutionShader> create(GraphicsContext3D*, int kernelWidth);
+
+ void use(const AffineTransform&, const AffineTransform& texTransform, const float* kernel, int kernelWidth, float imageIncrement[2]);
+
+private:
+ ConvolutionShader(GraphicsContext3D*, unsigned program, int kernelWidth);
+
+ int m_kernelWidth;
+ int m_matrixLocation;
+ int m_texMatrixLocation;
+ int m_kernelLocation;
+ int m_imageLocation;
+ int m_imageIncrementLocation;
+ int m_positionLocation;
+};
+
+}
+
+#endif // ConvolutionShader_h
diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
index 49ae114..606484e 100644
--- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
+++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
@@ -42,6 +42,10 @@
#include <wtf/RetainPtr.h>
#endif
+#if ENABLE(SKIA_GPU)
+class GrContext;
+#endif
+
namespace WebCore {
#if PLATFORM(CHROMIUM)
@@ -59,6 +63,7 @@ public:
void reset(const IntSize&);
void bind();
IntSize size() const { return m_size; }
+ Platform3DObject colorBuffer() const { return m_colorBuffer; }
// Clear all resources from this object, as well as context. Called when context is destroyed
// to prevent invalid accesses to the resources.
@@ -94,6 +99,10 @@ public:
void setWillPublishCallback(PassOwnPtr<WillPublishCallback> callback) { m_callback = callback; }
#endif
+#if ENABLE(SKIA_GPU)
+ void setGrContext(GrContext* ctx);
+#endif
+
PassRefPtr<GraphicsContext3D> graphicsContext3D() const { return m_context; }
private:
@@ -130,6 +139,10 @@ private:
#if PLATFORM(MAC)
RetainPtr<WebGLLayer> m_platformLayer;
#endif
+
+#if ENABLE(SKIA_GPU)
+ GrContext* m_grContext;
+#endif
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp
index 5439885..a96213c 100644
--- a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp
@@ -42,6 +42,8 @@
#include <algorithm>
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
+#include <wtf/UnusedParam.h>
+
#if USE(SKIA)
#include "SkGeometry.h"
@@ -701,6 +703,7 @@ void LoopBlinnPathProcessor::buildContours(const Path& path)
}
} while (verb != SkPath::kDone_Verb);
#else // !USE(SKIA)
+ UNUSED_PARAM(path);
// Must port to your platform.
ASSERT_NOT_REACHED();
#endif
@@ -1145,6 +1148,8 @@ static void combineCallback(GLdouble coords[3], void* vertexData[4],
GLfloat weight[4], void** outData,
void* polygonData)
{
+ UNUSED_PARAM(vertexData);
+ UNUSED_PARAM(weight);
TessellationState* state = static_cast<TessellationState*>(polygonData);
GLdouble* outVertex = static_cast<GLdouble*>(fastMalloc(3 * sizeof(GLdouble)));
state->allocatedPointers.append(outVertex);
diff --git a/Source/WebCore/platform/graphics/gpu/PODRedBlackTree.h b/Source/WebCore/platform/graphics/gpu/PODRedBlackTree.h
index bd08988..7dd9ddd 100644
--- a/Source/WebCore/platform/graphics/gpu/PODRedBlackTree.h
+++ b/Source/WebCore/platform/graphics/gpu/PODRedBlackTree.h
@@ -257,7 +257,7 @@ private:
// properly update such summary information based only on the values
// in the left and right children. This method should return true if
// the node's summary information changed.
- virtual bool updateNode(Node* node) { return false; }
+ virtual bool updateNode(Node*) { return false; }
//----------------------------------------------------------------------
// Generic binary search tree operations
@@ -713,7 +713,7 @@ private:
}
#ifdef NDEBUG
- void logIfVerbose(const char* output) const { }
+ void logIfVerbose(const char*) const { }
#else
void logIfVerbose(const char* output) const
{
diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
index ea8bc71..662d6a8 100644
--- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
+++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
@@ -35,7 +35,10 @@
#include "SharedGraphicsContext3D.h"
#include "AffineTransform.h"
+#include "BicubicShader.h"
#include "Color.h"
+#include "ConvolutionShader.h"
+#include "DrawingBuffer.h"
#include "Extensions3D.h"
#include "FloatRect.h"
#include "IntSize.h"
@@ -43,6 +46,15 @@
#include "SolidFillShader.h"
#include "TexShader.h"
+#if ENABLE(SKIA_GPU)
+#include "GrContext.h"
+// Limit the number of textures we hold in the bitmap->texture cache.
+static const int maxTextureCacheCount = 512;
+// Limit the bytes allocated toward textures in the bitmap->texture cache.
+static const size_t maxTextureCacheBytes = 50 * 1024 * 1024;
+#endif
+
+#include <wtf/OwnArrayPtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
@@ -65,16 +77,30 @@ PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow*
OwnPtr<TexShader> texShader = TexShader::create(context.get());
if (!texShader)
return 0;
- return adoptRef(new SharedGraphicsContext3D(context.release(), solidFillShader.release(), texShader.release()));
+ OwnPtr<BicubicShader> bicubicShader = BicubicShader::create(context.get());
+ if (!bicubicShader)
+ return 0;
+ OwnArrayPtr<OwnPtr<ConvolutionShader> > convolutionShaders = adoptArrayPtr(new OwnPtr<ConvolutionShader>[cMaxKernelWidth]);
+ for (int i = 0; i < cMaxKernelWidth; ++i) {
+ convolutionShaders[i] = ConvolutionShader::create(context.get(), i + 1);
+ if (!convolutionShaders[i])
+ return 0;
+ }
+ return adoptRef(new SharedGraphicsContext3D(context.release(), solidFillShader.release(), texShader.release(), bicubicShader.release(), convolutionShaders.release()));
}
-SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<SolidFillShader> solidFillShader, PassOwnPtr<TexShader> texShader)
+SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<SolidFillShader> solidFillShader, PassOwnPtr<TexShader> texShader, PassOwnPtr<BicubicShader> bicubicShader, PassOwnArrayPtr<OwnPtr<ConvolutionShader> > convolutionShaders)
: m_context(context)
, m_bgraSupported(false)
, m_quadVertices(0)
, m_solidFillShader(solidFillShader)
, m_texShader(texShader)
+ , m_bicubicShader(bicubicShader)
+ , m_convolutionShaders(convolutionShaders)
, m_oesStandardDerivativesSupported(false)
+#if ENABLE(SKIA_GPU)
+ , m_grContext(0)
+#endif
{
allContexts()->add(this);
Extensions3D* extensions = m_context->getExtensions();
@@ -92,6 +118,9 @@ SharedGraphicsContext3D::~SharedGraphicsContext3D()
{
m_context->deleteBuffer(m_quadVertices);
allContexts()->remove(this);
+#if ENABLE(SKIA_GPU)
+ GrSafeUnref(m_grContext);
+#endif
}
void SharedGraphicsContext3D::makeContextCurrent()
@@ -369,6 +398,17 @@ void SharedGraphicsContext3D::useTextureProgram(const AffineTransform& transform
m_texShader->use(transform, texTransform, 0, alpha);
}
+void SharedGraphicsContext3D::useBicubicProgram(const AffineTransform& transform, const AffineTransform& texTransform, const float coefficients[16], const float imageIncrement[2], float alpha)
+{
+ m_bicubicShader->use(transform, texTransform, coefficients, imageIncrement, alpha);
+}
+
+void SharedGraphicsContext3D::useConvolutionProgram(const AffineTransform& transform, const AffineTransform& texTransform, const float* kernel, int kernelWidth, float imageIncrement[2])
+{
+ ASSERT(kernelWidth >= 1 && kernelWidth <= cMaxKernelWidth);
+ m_convolutionShaders[kernelWidth - 1]->use(transform, texTransform, kernel, kernelWidth, imageIncrement);
+}
+
void SharedGraphicsContext3D::bindFramebuffer(Platform3DObject framebuffer)
{
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer);
@@ -411,6 +451,31 @@ void SharedGraphicsContext3D::useLoopBlinnExteriorProgram(unsigned vertexOffset,
m_loopBlinnExteriorShader->use(vertexOffset, klmOffset, transform, color);
}
+DrawingBuffer* SharedGraphicsContext3D::getOffscreenBuffer(unsigned index, const IntSize& size)
+{
+ if (index >= m_offscreenBuffers.size())
+ m_offscreenBuffers.resize(index + 1);
+
+ if (!m_offscreenBuffers[index])
+ m_offscreenBuffers[index] = m_context->createDrawingBuffer(size);
+
+ if (size.width() != m_offscreenBuffers[index]->size().width()
+ || size.height() != m_offscreenBuffers[index]->size().height())
+ m_offscreenBuffers[index]->reset(size);
+ return m_offscreenBuffers[index].get();
+}
+
+#if ENABLE(SKIA_GPU)
+GrContext* SharedGraphicsContext3D::grContext()
+{
+ if (!m_grContext) {
+ m_grContext = GrContext::CreateGLShaderContext();
+ m_grContext->setTextureCacheLimits(maxTextureCacheCount, maxTextureCacheBytes);
+ }
+ return m_grContext;
+}
+#endif
+
} // namespace WebCore
#endif
diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
index 707fd24..8fb3d50 100644
--- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
@@ -38,14 +38,22 @@
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/OwnArrayPtr.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
+#if ENABLE(SKIA_GPU)
+class GrContext;
+#endif
+
namespace WebCore {
class AffineTransform;
+class BicubicShader;
class Color;
+class ConvolutionShader;
+class DrawingBuffer;
class FloatRect;
class HostWindow;
class IntSize;
@@ -101,6 +109,8 @@ public:
void useFillSolidProgram(const AffineTransform&, const Color&);
void useTextureProgram(const AffineTransform&, const AffineTransform&, float alpha);
+ void useBicubicProgram(const AffineTransform&, const AffineTransform&, const float coefficients[16], const float imageIncrement[2], float alpha);
+ void useConvolutionProgram(const AffineTransform&, const AffineTransform& texTransform, const float* kernel, int kernelWidth, float imageIncrement[2]);
void setActiveTexture(GC3Denum textureUnit);
void bindTexture(GC3Denum target, Platform3DObject texture);
@@ -127,9 +137,14 @@ public:
static bool useLoopBlinnForPathRendering();
void useLoopBlinnInteriorProgram(unsigned vertexOffset, const AffineTransform&, const Color&);
void useLoopBlinnExteriorProgram(unsigned vertexOffset, unsigned klmOffset, const AffineTransform&, const Color&);
+ DrawingBuffer* getOffscreenBuffer(unsigned index, const IntSize&);
+
+#if ENABLE(SKIA_GPU)
+ GrContext* grContext();
+#endif
private:
- SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D>, PassOwnPtr<SolidFillShader>, PassOwnPtr<TexShader>);
+ SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D>, PassOwnPtr<SolidFillShader>, PassOwnPtr<TexShader>, PassOwnPtr<BicubicShader>, PassOwnArrayPtr<OwnPtr<ConvolutionShader> >);
// Used to implement removeTexturesFor(), see the comment above.
static HashSet<SharedGraphicsContext3D*>* allContexts();
@@ -142,6 +157,8 @@ private:
OwnPtr<SolidFillShader> m_solidFillShader;
OwnPtr<TexShader> m_texShader;
+ OwnPtr<BicubicShader> m_bicubicShader;
+ OwnArrayPtr<OwnPtr<ConvolutionShader> > m_convolutionShaders;
TextureHashMap m_textures;
@@ -150,8 +167,17 @@ private:
OwnPtr<LoopBlinnSolidFillShader> m_loopBlinnInteriorShader;
OwnPtr<LoopBlinnSolidFillShader> m_loopBlinnExteriorShader;
bool m_oesStandardDerivativesSupported;
+
+ WTF::Vector<RefPtr<DrawingBuffer> > m_offscreenBuffers;
+
+#if ENABLE(SKIA_GPU)
+ GrContext* m_grContext;
+#endif
};
+const float cMaxSigma = 4.0f;
+const int cMaxKernelWidth = 25;
+
} // namespace WebCore
#endif // SharedGraphicsContext3D_h
diff --git a/Source/WebCore/platform/graphics/gpu/TilingData.cpp b/Source/WebCore/platform/graphics/gpu/TilingData.cpp
index dd540b3..1370543 100644
--- a/Source/WebCore/platform/graphics/gpu/TilingData.cpp
+++ b/Source/WebCore/platform/graphics/gpu/TilingData.cpp
@@ -66,7 +66,7 @@ void TilingData::setTotalSize(int totalSizeX, int totalSizeY)
void TilingData::setMaxTextureSize(int maxTextureSize)
{
- m_maxTextureSize = m_maxTextureSize;
+ m_maxTextureSize = maxTextureSize;
recomputeNumTiles();
}
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index 3763ef7..2fb4cef 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -117,6 +117,13 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
|| err->code == GST_RESOURCE_ERROR_NOT_FOUND)
error = MediaPlayer::FormatError;
else if (err->domain == GST_STREAM_ERROR) {
+ // Let the mediaPlayerClient handle the stream error, in
+ // this case the HTMLMediaElement will emit a stalled
+ // event.
+ if (err->code == GST_STREAM_ERROR_TYPE_NOT_FOUND) {
+ LOG_VERBOSE(Media, "Decode error, let the Media element emit a stalled event.");
+ break;
+ }
error = MediaPlayer::DecodeError;
attemptNextLocation = true;
} else if (err->domain == GST_RESOURCE_ERROR)
@@ -495,7 +502,7 @@ float MediaPlayerPrivateGStreamer::currentTime() const
return 0.0f;
if (m_seeking)
- return static_cast<float>(m_seekTime);
+ return m_seekTime;
return playbackPosition(m_playBin);
@@ -513,17 +520,28 @@ void MediaPlayerPrivateGStreamer::seek(float time)
if (m_errorOccured)
return;
- GstClockTime sec = (GstClockTime)(static_cast<float>(time * GST_SECOND));
- LOG_VERBOSE(Media, "Seek: %" GST_TIME_FORMAT, GST_TIME_ARGS(sec));
+ // Extract the integer part of the time (seconds) and the
+ // fractional part (microseconds). Attempt to round the
+ // microseconds so no floating point precision is lost and we can
+ // perform an accurate seek.
+ float seconds;
+ float microSeconds = modf(time, &seconds) * 1000000;
+ GTimeVal timeValue;
+ timeValue.tv_sec = static_cast<glong>(seconds);
+ timeValue.tv_usec = static_cast<glong>(roundf(microSeconds / 10000) * 10000);
+
+ GstClockTime clockTime = GST_TIMEVAL_TO_TIME(timeValue);
+ LOG_VERBOSE(Media, "Seek: %" GST_TIME_FORMAT, GST_TIME_ARGS(clockTime));
+
if (!gst_element_seek(m_playBin, m_player->rate(),
GST_FORMAT_TIME,
- (GstSeekFlags)(GST_SEEK_FLAG_FLUSH),
- GST_SEEK_TYPE_SET, sec,
+ (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),
+ GST_SEEK_TYPE_SET, clockTime,
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
LOG_VERBOSE(Media, "Seek to %f failed", time);
else {
m_seeking = true;
- m_seekTime = sec;
+ m_seekTime = time;
}
}
@@ -1046,15 +1064,9 @@ void MediaPlayerPrivateGStreamer::updateStates()
if (!m_isStreaming && !m_buffering)
return;
- // Resume playback if a seek was performed in a live pipeline
- // or during progressive download. That second use-case
- // happens when the seek is performed to a region of the media
- // that hasn't been downloaded yet.
if (m_seeking) {
shouldUpdateAfterSeek = true;
m_seeking = false;
- if (m_paused)
- gst_element_set_state(m_playBin, GST_STATE_PLAYING);
}
break;
case GST_STATE_CHANGE_FAILURE:
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
index 11eb81b..8003887 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
@@ -161,7 +161,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
GstElement* m_videoSinkBin;
GstElement* m_fpsSink;
GstElement* m_source;
- GstClockTime m_seekTime;
+ float m_seekTime;
bool m_changingRate;
float m_endTime;
bool m_isEndReached;
diff --git a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
index 86e3e7a..66ea9ba 100644
--- a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
@@ -352,7 +352,7 @@ static void webKitWebSrcStop(WebKitWebSrc* src, bool seeking)
}
priv->resourceHandle = 0;
- if (priv->frame)
+ if (priv->frame && !seeking)
priv->frame.release();
GST_OBJECT_LOCK(src);
diff --git a/Source/WebCore/platform/graphics/gtk/FontGtk.cpp b/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
index 216fb56..d14b052 100644
--- a/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
+++ b/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
@@ -35,6 +35,7 @@
#include "CairoUtilities.h"
#include "ContextShadow.h"
+#include "PlatformContextCairo.h"
#include "GraphicsContext.h"
#include "NotImplemented.h"
#include "SimpleFontData.h"
@@ -44,7 +45,7 @@
#include <pango/pango.h>
#include <pango/pangocairo.h>
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
#include <pango/pangofc-fontmap.h>
#endif
@@ -171,13 +172,13 @@ static gchar* convertUniCharToUTF8(const UChar* characters, gint length, int fro
static void setPangoAttributes(const Font* font, const TextRun& run, PangoLayout* layout)
{
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
if (font->primaryFont()->platformData().m_pattern) {
PangoFontDescription* desc = pango_fc_font_description_from_pattern(font->primaryFont()->platformData().m_pattern.get(), FALSE);
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
}
-#elif defined(USE_PANGO)
+#elif USE(PANGO)
if (font->primaryFont()->platformData().m_font) {
PangoFontDescription* desc = pango_font_describe(font->primaryFont()->platformData().m_font);
pango_layout_set_font_description(layout, desc);
@@ -220,7 +221,7 @@ bool Font::canExpandAroundIdeographsInComplexText()
return false;
}
-static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point, PangoLayoutLine* layoutLine, PangoRegionType renderRegion)
+static void drawGlyphsShadow(GraphicsContext* graphicsContext, const FloatPoint& point, PangoLayoutLine* layoutLine, PangoRegionType renderRegion)
{
ContextShadow* shadow = graphicsContext->contextShadow();
ASSERT(shadow);
@@ -232,6 +233,7 @@ static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context,
// Optimize non-blurry shadows, by just drawing text without the ContextShadow.
if (!shadow->mustUseContextShadow(graphicsContext)) {
+ cairo_t* context = graphicsContext->platformContext()->cr();
cairo_save(context);
cairo_translate(context, totalOffset.x(), totalOffset.y());
@@ -255,6 +257,7 @@ static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context,
// because we don't want any bits and pieces of characters out of range to be
// drawn. Since ContextShadow expects a consistent transform, we have to undo the
// translation before calling endShadowLayer as well.
+ cairo_t* context = graphicsContext->platformContext()->cr();
cairo_save(context);
cairo_translate(context, totalOffset.x(), totalOffset.y());
gdk_cairo_region(context, renderRegion);
@@ -268,14 +271,14 @@ static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context,
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
if (!primaryFont()->platformData().m_pattern) {
drawSimpleText(context, run, point, from, to);
return;
}
#endif
- cairo_t* cr = context->platformContext();
+ cairo_t* cr = context->platformContext()->cr();
PangoLayout* layout = pango_cairo_create_layout(cr);
setPangoAttributes(this, run, layout);
@@ -294,7 +297,7 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
int ranges[] = {start - utf8, end - utf8};
partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1);
- drawGlyphsShadow(context, cr, point, layoutLine, partialRegion);
+ drawGlyphsShadow(context, point, layoutLine, partialRegion);
cairo_save(cr);
cairo_translate(cr, point.x(), point.y());
@@ -348,7 +351,7 @@ static PangoLayout* getDefaultPangoLayout(const TextRun& run)
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* overflow) const
{
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
if (!primaryFont()->platformData().m_pattern)
return floatWidthForSimpleText(run, 0, fallbackFonts, overflow);
#endif
@@ -373,7 +376,7 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, bool includePartialGlyphs) const
{
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
if (!primaryFont()->platformData().m_pattern)
return offsetForPositionForSimpleText(run, xFloat, includePartialGlyphs);
#endif
@@ -401,7 +404,7 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, bool
FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const
{
-#if defined(USE_FREETYPE)
+#if USE(FREETYPE)
if (!primaryFont()->platformData().m_pattern)
return selectionRectForSimpleText(run, point, h, from, to);
#endif
diff --git a/Source/WebCore/platform/graphics/gtk/IconGtk.cpp b/Source/WebCore/platform/graphics/gtk/IconGtk.cpp
index d56b52d..7fdc1f6 100644
--- a/Source/WebCore/platform/graphics/gtk/IconGtk.cpp
+++ b/Source/WebCore/platform/graphics/gtk/IconGtk.cpp
@@ -33,9 +33,9 @@
#include "GraphicsContext.h"
#include "MIMETypeRegistry.h"
#include "PassRefPtr.h"
-#include <wtf/text/CString.h>
-
+#include "PlatformContextCairo.h"
#include <gtk/gtk.h>
+#include <wtf/text/CString.h>
namespace WebCore {
@@ -117,7 +117,7 @@ void Icon::paint(GraphicsContext* context, const IntRect& rect)
return;
// TODO: Scale/clip the image if necessary.
- cairo_t* cr = context->platformContext();
+ cairo_t* cr = context->platformContext()->cr();
cairo_save(cr);
gdk_cairo_set_source_pixbuf(cr, m_icon, rect.x(), rect.y());
cairo_paint(cr);
diff --git a/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp b/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
index 2aa016e..3da0f9b 100644
--- a/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
+++ b/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
@@ -54,7 +54,7 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality) con
GError* error = 0;
gboolean success = FALSE;
if (type == "jpeg" && quality && *quality >= 0.0 && *quality <= 1.0) {
- String qualityString = String::format("%f", *quality);
+ String qualityString = String::format("%f", *quality * 100.0);
success = gdk_pixbuf_save_to_buffer(pixbuf.get(), &buffer.outPtr(), &bufferSize,
type.utf8().data(), &error, "quality", qualityString.utf8().data(), NULL);
} else {
diff --git a/Source/WebCore/platform/graphics/gtk/ImageGtk.cpp b/Source/WebCore/platform/graphics/gtk/ImageGtk.cpp
index 623ace6..9dd82a9 100644
--- a/Source/WebCore/platform/graphics/gtk/ImageGtk.cpp
+++ b/Source/WebCore/platform/graphics/gtk/ImageGtk.cpp
@@ -152,7 +152,10 @@ PassRefPtr<Image> Image::loadPlatformThemeIcon(const char* name, int size)
GdkPixbuf* BitmapImage::getGdkPixbuf()
{
- return cairoImageSurfaceToGdkPixbuf(frameAtIndex(currentFrame()));
+ cairo_surface_t* frame = frameAtIndex(currentFrame());
+ if (!frame)
+ return 0;
+ return cairoImageSurfaceToGdkPixbuf(frame);
}
}
diff --git a/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp
index 017b1e4..352de67 100644
--- a/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp
@@ -31,7 +31,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
{
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode)
{
return FontPlatformData(size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h
index 7ffe89a..a319ce5 100644
--- a/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h
@@ -24,6 +24,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -39,7 +40,7 @@ namespace WebCore {
static bool supportsFormat(const String&);
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
};
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*);
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
index 1a56664..07bc3ec 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -63,7 +63,8 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
, m_glyphInCurrentRun(0)
, m_characterInCurrentGlyph(0)
, m_expansion(run.expansion())
- , m_afterExpansion(true)
+ , m_leadingExpansion(0)
+ , m_afterExpansion(!run.allowsLeadingExpansion())
, m_fallbackFonts(fallbackFonts)
, m_minGlyphBoundingBoxX(numeric_limits<float>::max())
, m_maxGlyphBoundingBoxX(numeric_limits<float>::min())
@@ -73,7 +74,7 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
if (!m_expansion)
m_expansionPerOpportunity = 0;
else {
- bool isAfterExpansion = true;
+ bool isAfterExpansion = m_afterExpansion;
unsigned expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters(), m_end, m_run.ltr() ? LTR : RTL, isAfterExpansion);
if (isAfterExpansion && !m_run.allowsTrailingExpansion())
expansionOpportunityCount--;
@@ -86,12 +87,16 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
collectComplexTextRuns();
adjustGlyphsAndAdvances();
+
+ m_runWidthSoFar = m_leadingExpansion;
}
int ComplexTextController::offsetForPosition(float h, bool includePartialGlyphs)
{
if (h >= m_totalWidth)
return m_run.ltr() ? m_end : 0;
+
+ h -= m_leadingExpansion;
if (h < 0)
return m_run.ltr() ? 0 : m_end;
@@ -472,16 +477,21 @@ void ComplexTextController::adjustGlyphsAndAdvances()
// Handle justification and word-spacing.
if (treatAsSpace || Font::isCJKIdeographOrSymbol(ch)) {
// Distribute the run's total expansion evenly over all expansion opportunities in the run.
- if (m_expansion && (!lastGlyph || m_run.allowsTrailingExpansion())) {
+ if (m_expansion) {
if (!treatAsSpace && !m_afterExpansion) {
// Take the expansion opportunity before this ideograph.
m_expansion -= m_expansionPerOpportunity;
m_totalWidth += m_expansionPerOpportunity;
- m_adjustedAdvances.last().width += m_expansionPerOpportunity;
+ if (m_adjustedAdvances.isEmpty())
+ m_leadingExpansion = m_expansionPerOpportunity;
+ else
+ m_adjustedAdvances.last().width += m_expansionPerOpportunity;
+ }
+ if (!lastGlyph || m_run.allowsTrailingExpansion()) {
+ m_expansion -= m_expansionPerOpportunity;
+ advance.width += m_expansionPerOpportunity;
+ m_afterExpansion = true;
}
- m_expansion -= m_expansionPerOpportunity;
- advance.width += m_expansionPerOpportunity;
- m_afterExpansion = true;
} else
m_afterExpansion = false;
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.h b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
index 7373bfe..44a7994 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -175,6 +175,7 @@ private:
unsigned m_characterInCurrentGlyph;
float m_expansion;
float m_expansionPerOpportunity;
+ float m_leadingExpansion;
bool m_afterExpansion;
HashSet<const SimpleFontData*>* m_fallbackFonts;
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
index b367fdf..d965ada 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
@@ -264,7 +264,7 @@ static void disableLigatures(const SimpleFontData* fontData, ATSUStyle atsuStyle
// Don't be too aggressive: if the font doesn't contain 'a', then assume that any ligatures it contains are
// in characters that always go through ATSUI, and therefore allow them. Geeza Pro is an example.
// See bugzilla 5166.
- if ((typesettingFeatures & Ligatures) || (fontData->orientation() == Horizontal && fontData->platformData().allowsLigatures()))
+ if ((typesettingFeatures & Ligatures) || (fontData->platformData().orientation() == Horizontal && fontData->platformData().allowsLigatures()))
return;
ATSUFontFeatureType featureTypes[] = { kLigaturesType };
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
index 239113f..d2fbaf5 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
@@ -144,17 +144,17 @@ void ComplexTextController::collectComplexTextRunsForCharactersCoreText(const UC
static CFDictionaryRef rtlTypesetterOptions = CFDictionaryCreate(kCFAllocatorDefault, optionKeys, rtlOptionValues, WTF_ARRAY_LENGTH(optionKeys), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
- ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures()) };
+ ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation()) };
RetainPtr<CTTypesetterRef> typesetter(AdoptCF, wkCreateCTTypesetterWithUniCharProviderAndOptions(&provideStringAndAttributes, 0, &info, m_run.ltr() ? ltrTypesetterOptions : rtlTypesetterOptions));
#else
RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, cp, length, kCFAllocatorNull));
- RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(m_font.typesettingFeatures())));
+ RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation())));
RetainPtr<CTTypesetterRef> typesetter(AdoptCF, CTTypesetterCreateWithAttributedStringAndOptions(attributedString.get(), m_run.ltr() ? ltrTypesetterOptions : rtlTypesetterOptions));
#endif
line.adoptCF(CTTypesetterCreateLine(typesetter.get(), CFRangeMake(0, 0)));
} else {
- ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures()) };
+ ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation()) };
line.adoptCF(wkCreateCTLineWithUniCharProvider(&provideStringAndAttributes, 0, &info));
}
diff --git a/Source/WebCore/platform/graphics/mac/FontCacheMac.mm b/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
index c254906..f7ae6b7 100644
--- a/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
@@ -211,7 +211,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
bool syntheticBold = isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(actualWeight);
bool syntheticOblique = (traits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait);
- return new FontPlatformData(platformFont, size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.widthVariant());
+ return new FontPlatformData(platformFont, size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.textOrientation(), fontDescription.widthVariant());
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
index eed49a5..fe2a22c 100644
--- a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
@@ -111,8 +111,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
{
ComplexTextController controller(this, run, true, fallbackFonts);
if (glyphOverflow) {
- glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - fontMetrics().ascent());
- glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - fontMetrics().descent());
+ glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
+ glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().descent()));
glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.totalWidth()));
}
diff --git a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
index f2bc33d..383adef 100644
--- a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
@@ -38,9 +38,9 @@ FontCustomPlatformData::~FontCustomPlatformData()
CGFontRelease(m_cgFont);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant widthVariant, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, TextOrientation textOrientation, FontWidthVariant widthVariant, FontRenderingMode)
{
- return FontPlatformData(m_cgFont, size, bold, italic, orientation, widthVariant);
+ return FontPlatformData(m_cgFont, size, bold, italic, orientation, textOrientation, widthVariant);
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
diff --git a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
index c7ae1ca..c625304 100644
--- a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
@@ -24,6 +24,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include <CoreFoundation/CFBase.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -48,7 +49,7 @@ public:
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/mac/FontMac.mm b/Source/WebCore/platform/graphics/mac/FontMac.mm
index acd7562..4c28ead 100644
--- a/Source/WebCore/platform/graphics/mac/FontMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontMac.mm
@@ -52,28 +52,72 @@ bool Font::canExpandAroundIdeographsInComplexText()
return true;
}
-static void showGlyphsWithAdvances(const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
+// CTFontGetVerticalTranslationsForGlyphs is different on Snow Leopard. It returns values for a font-size of 1
+// without unitsPerEm applied. We have to apply a transform that scales up to the point size and that also
+// divides by unitsPerEm.
+static bool hasBrokenCTFontGetVerticalTranslationsForGlyphs()
{
+// Chromium runs the same binary on both Leopard and Snow Leopard, so the check has to happen at runtime.
+#if PLATFORM(CHROMIUM)
+ static bool isCached = false;
+ static bool result;
+
+ if (!isCached) {
+ SInt32 majorVersion = 0;
+ SInt32 minorVersion = 0;
+ Gestalt(gestaltSystemVersionMajor, &majorVersion);
+ Gestalt(gestaltSystemVersionMinor, &minorVersion);
+ result = majorVersion == 10 && minorVersion == 6;
+ isCached = true;
+ }
+ return result;
+#elif defined(BUILDING_ON_SNOW_LEOPARD)
+ return true;
+#else
+ return false;
+#endif
+}
+
+static void showGlyphsWithAdvances(const FloatPoint& point, const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
+{
+ CGContextSetTextPosition(context, point.x(), point.y());
+
const FontPlatformData& platformData = font->platformData();
if (!platformData.isColorBitmapFont()) {
CGAffineTransform savedMatrix;
- bool isVertical = font->orientation() == Vertical;
-
+ bool isVertical = font->platformData().orientation() == Vertical;
if (isVertical) {
CGAffineTransform rotateLeftTransform = CGAffineTransformMake(0, -1, 1, 0, 0, 0);
-
savedMatrix = CGContextGetTextMatrix(context);
CGAffineTransform runMatrix = CGAffineTransformConcat(savedMatrix, rotateLeftTransform);
- // Move start point to put glyphs into original region.
- runMatrix.tx = savedMatrix.tx + font->fontMetrics().ascent();
- runMatrix.ty = savedMatrix.ty + font->fontMetrics().descent();
CGContextSetTextMatrix(context, runMatrix);
- }
-
- CGContextShowGlyphsWithAdvances(context, glyphs, advances, count);
-
- if (isVertical)
+
+ CGAffineTransform translationsTransform;
+ if (hasBrokenCTFontGetVerticalTranslationsForGlyphs()) {
+ translationsTransform = CGAffineTransformMake(platformData.m_size, 0, 0, platformData.m_size, 0, 0);
+ translationsTransform = CGAffineTransformConcat(translationsTransform, rotateLeftTransform);
+ CGFloat unitsPerEm = CGFontGetUnitsPerEm(platformData.cgFont());
+ translationsTransform = CGAffineTransformConcat(translationsTransform, CGAffineTransformMakeScale(1 / unitsPerEm, 1 / unitsPerEm));
+ } else {
+ translationsTransform = rotateLeftTransform;
+ }
+ Vector<CGSize, 256> translations(count);
+ CTFontGetVerticalTranslationsForGlyphs(platformData.ctFont(), glyphs, translations.data(), count);
+
+ CGAffineTransform transform = CGAffineTransformInvert(CGContextGetTextMatrix(context));
+
+ CGPoint position = FloatPoint(point.x(), point.y() + font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent());
+ Vector<CGPoint, 256> positions(count);
+ for (size_t i = 0; i < count; ++i) {
+ CGSize translation = CGSizeApplyAffineTransform(translations[i], translationsTransform);
+ positions[i] = CGPointApplyAffineTransform(CGPointMake(position.x - translation.width, position.y + translation.height), transform);
+ position.x += advances[i].width;
+ position.y += advances[i].height;
+ }
+ CGContextShowGlyphsAtPositions(context, glyphs, positions.data(), count);
CGContextSetTextMatrix(context, savedMatrix);
+ } else
+ CGContextShowGlyphsWithAdvances(context, glyphs, advances, count);
}
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
else {
@@ -188,21 +232,15 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
float shadowTextX = point.x() + shadowOffset.width();
// If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
float shadowTextY = point.y() + shadowOffset.height() * (context->shadowsIgnoreTransforms() ? -1 : 1);
- CGContextSetTextPosition(cgContext, shadowTextX, shadowTextY);
- showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- if (font->syntheticBoldOffset()) {
- CGContextSetTextPosition(cgContext, shadowTextX + font->syntheticBoldOffset(), shadowTextY);
- showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- }
+ showGlyphsWithAdvances(FloatPoint(shadowTextX, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ if (font->syntheticBoldOffset())
+ showGlyphsWithAdvances(FloatPoint(shadowTextX + font->syntheticBoldOffset(), shadowTextY), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
context->setFillColor(fillColor, fillColorSpace);
}
- CGContextSetTextPosition(cgContext, point.x(), point.y());
- showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- if (font->syntheticBoldOffset()) {
- CGContextSetTextPosition(cgContext, point.x() + font->syntheticBoldOffset(), point.y());
- showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- }
+ showGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ if (font->syntheticBoldOffset())
+ showGlyphsWithAdvances(FloatPoint(point.x() + font->syntheticBoldOffset(), point.y()), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (hasSimpleShadow)
context->setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
diff --git a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
index fe2b33a..18d0dc5 100644
--- a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
#ifndef BUILDING_ON_TIGER
static bool shouldUseCoreText(UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
{
- if (fontData->platformData().widthVariant() != RegularWidth || (fontData->orientation() == Vertical && !fontData->isBrokenIdeographFont())) {
+ if (fontData->platformData().widthVariant() != RegularWidth || fontData->hasVerticalGlyphs()) {
// Ideographs don't have a vertical variant or width variants.
for (unsigned i = 0; i < bufferLength; ++i) {
if (!Font::isCJKIdeograph(buffer[i]))
@@ -70,7 +70,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
} else {
// We ask CoreText for possible vertical variant glyphs
RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buffer, bufferLength, kCFAllocatorNull));
- RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0)));
+ RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0, fontData->hasVerticalGlyphs() ? Vertical : Horizontal)));
RetainPtr<CTLineRef> line(AdoptCF, CTLineCreateWithAttributedString(attributedString.get()));
CFArrayRef runArray = CTLineGetGlyphRuns(line.get());
diff --git a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index aaa250b..997c976 100644
--- a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -93,9 +93,14 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi
, m_attrs(attrs)
, m_contextObj(0)
, m_texture(0)
+ , m_compositorTexture(0)
, m_fbo(0)
, m_depthStencilBuffer(0)
+ , m_layerComposited(false)
+ , m_internalColorFormat(0)
, m_boundFBO(0)
+ , m_activeTexture(0)
+ , m_boundTexture0(0)
, m_multisampleFBO(0)
, m_multisampleDepthStencilBuffer(0)
, m_multisampleColorBuffer(0)
@@ -166,6 +171,12 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi
::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ ::glGenTextures(1, &m_compositorTexture);
+ ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
+ ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
::glBindTexture(GL_TEXTURE_2D, 0);
// create an FBO
@@ -215,6 +226,7 @@ GraphicsContext3D::~GraphicsContext3D()
if (m_contextObj) {
CGLSetCurrentContext(m_contextObj);
::glDeleteTextures(1, &m_texture);
+ ::glDeleteTextures(1, &m_compositorTexture);
if (m_attrs.antialias) {
::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
if (m_attrs.stencil || m_attrs.depth)
diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 80bc94e..7bdc064 100644
--- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -54,6 +54,8 @@ class WebCoreMovieObserver;
#endif
namespace WebCore {
+
+class ApplicationCacheResource;
class MediaPlayerPrivateQTKit : public MediaPlayerPrivateInterface {
public:
@@ -139,6 +141,7 @@ private:
void createQTMovie(const String& url);
void createQTMovie(NSURL *, NSDictionary *movieAttributes);
+ void createQTMovie(ApplicationCacheResource*);
enum MediaRenderingMode { MediaRenderingNone, MediaRenderingMovieView, MediaRenderingSoftwareRenderer, MediaRenderingMovieLayer };
MediaRenderingMode currentRenderingMode() const;
@@ -178,6 +181,8 @@ private:
virtual double maximumDurationToCacheMediaTime() const { return 5; }
virtual void setPrivateBrowsingMode(bool);
+
+ NSMutableDictionary* commonMovieAttributes();
MediaPlayer* m_player;
RetainPtr<QTMovie> m_qtMovie;
@@ -211,6 +216,7 @@ private:
double m_timeStartedPlaying;
double m_timeStoppedPlaying;
#endif
+ mutable FloatSize m_cachedNaturalSize;
};
}
diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index ecb7d9f..400fdfb 100644
--- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -29,11 +29,18 @@
#import "MediaPlayerPrivateQTKit.h"
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "ApplicationCacheHost.h"
+#include "ApplicationCacheResource.h"
+#include "DocumentLoader.h"
+#endif
+
#ifdef BUILDING_ON_TIGER
#import "AutodrainedPool.h"
#endif
#import "BlockExceptions.h"
+#import "DocumentLoader.h"
#import "FrameView.h"
#import "GraphicsContext.h"
#import "KURL.h"
@@ -83,6 +90,7 @@ SOFT_LINK_POINTER(QTKit, QTMediaTypeText, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeVideo, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieAskUnresolvedDataRefsAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoopsAttribute, NSString *)
+SOFT_LINK_POINTER(QTKit, QTMovieDataAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDataSizeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDidEndNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieHasVideoAttribute, NSString *)
@@ -120,6 +128,7 @@ SOFT_LINK_POINTER(QTKit, QTMovieApertureModeAttribute, NSString *)
#define QTMediaTypeVideo getQTMediaTypeVideo()
#define QTMovieAskUnresolvedDataRefsAttribute getQTMovieAskUnresolvedDataRefsAttribute()
#define QTMovieLoopsAttribute getQTMovieLoopsAttribute()
+#define QTMovieDataAttribute getQTMovieDataAttribute()
#define QTMovieDataSizeAttribute getQTMovieDataSizeAttribute()
#define QTMovieDidEndNotification getQTMovieDidEndNotification()
#define QTMovieHasVideoAttribute getQTMovieHasVideoAttribute()
@@ -241,21 +250,26 @@ MediaPlayerPrivateQTKit::~MediaPlayerPrivateQTKit()
[m_objcObserver.get() disconnect];
}
-void MediaPlayerPrivateQTKit::createQTMovie(const String& url)
+NSMutableDictionary* MediaPlayerPrivateQTKit::commonMovieAttributes()
{
- NSURL *cocoaURL = KURL(ParsedURLString, url);
- NSMutableDictionary *movieAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- cocoaURL, QTMovieURLAttribute,
- [NSNumber numberWithBool:m_player->preservesPitch()], QTMovieRateChangesPreservePitchAttribute,
- [NSNumber numberWithBool:YES], QTMoviePreventExternalURLLinksAttribute,
- [NSNumber numberWithBool:YES], QTSecurityPolicyNoCrossSiteAttribute,
- [NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute,
- [NSNumber numberWithBool:NO], QTMovieLoopsAttribute,
- [NSNumber numberWithBool:!m_privateBrowsing], @"QTMovieAllowPersistentCacheAttribute",
+ return [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:m_player->preservesPitch()], QTMovieRateChangesPreservePitchAttribute,
+ [NSNumber numberWithBool:YES], QTMoviePreventExternalURLLinksAttribute,
+ [NSNumber numberWithBool:YES], QTSecurityPolicyNoCrossSiteAttribute,
+ [NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute,
+ [NSNumber numberWithBool:NO], QTMovieLoopsAttribute,
+ [NSNumber numberWithBool:!m_privateBrowsing], @"QTMovieAllowPersistentCacheAttribute",
#ifndef BUILDING_ON_TIGER
- QTMovieApertureModeClean, QTMovieApertureModeAttribute,
+ QTMovieApertureModeClean, QTMovieApertureModeAttribute,
#endif
- nil];
+ nil];
+}
+
+void MediaPlayerPrivateQTKit::createQTMovie(const String& url)
+{
+ NSURL *cocoaURL = KURL(ParsedURLString, url);
+ NSMutableDictionary *movieAttributes = commonMovieAttributes();
+ [movieAttributes setValue:cocoaURL forKey:QTMovieURLAttribute];
#if !defined(BUILDING_ON_LEOPARD)
CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings();
@@ -291,6 +305,33 @@ void MediaPlayerPrivateQTKit::createQTMovie(const String& url)
createQTMovie(cocoaURL, movieAttributes);
}
+void MediaPlayerPrivateQTKit::createQTMovie(ApplicationCacheResource* resource)
+{
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ ASSERT(resource);
+
+ NSMutableDictionary *movieAttributes = commonMovieAttributes();
+ [movieAttributes setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenForPlaybackAttribute"];
+
+ // ApplicationCacheResources can supply either a data pointer, or a path to a locally cached
+ // flat file. We would prefer the path over the data, but QTKit can handle either:
+ String localPath = resource->path();
+ NSURL* cocoaURL = !localPath.isEmpty() ? [NSURL fileURLWithPath:localPath isDirectory:NO] : nil;
+ if (cocoaURL)
+ [movieAttributes setValue:cocoaURL forKey:QTMovieURLAttribute];
+ else {
+ NSData* movieData = resource->data()->createNSData();
+ [movieAttributes setValue:movieData forKey:QTMovieDataAttribute];
+ [movieData release];
+ }
+
+ createQTMovie(cocoaURL, movieAttributes);
+
+#else
+ ASSERT_NOT_REACHED();
+#endif
+}
+
static void disableComponentsOnce()
{
static bool sComponentsDisabled = false;
@@ -658,6 +699,14 @@ void MediaPlayerPrivateQTKit::loadInternal(const String& url)
[m_objcObserver.get() setDelayCallbacks:YES];
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL;
+ ApplicationCacheHost* cacheHost = frame ? frame->loader()->documentLoader()->applicationCacheHost() : NULL;
+ ApplicationCacheResource* resource = NULL;
+ if (cacheHost && cacheHost->shouldLoadResourceFromApplicationCache(ResourceRequest(url), resource) && resource)
+ createQTMovie(resource);
+ else
+#endif
createQTMovie(url);
[m_objcObserver.get() loadStateChanged:nil];
@@ -827,8 +876,19 @@ IntSize MediaPlayerPrivateQTKit::naturalSize() const
// dimensions, aspect ratio, clean aperture, resolution, and so forth, as defined for the
// format used by the resource
- NSSize naturalSize = [[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
- return IntSize(naturalSize.width * m_scaleFactor.width(), naturalSize.height * m_scaleFactor.height());
+ FloatSize naturalSize([[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]);
+ if (naturalSize.isEmpty() && m_isStreaming) {
+ // HTTP Live Streams will occasionally return {0,0} natural sizes while scrubbing.
+ // Work around this problem (<rdar://problem/9078563>) by returning the last valid
+ // cached natural size:
+ naturalSize = m_cachedNaturalSize;
+ } else {
+ // Unfortunately, due to another QTKit bug (<rdar://problem/9082071>) we won't get a sizeChanged
+ // event when this happens, so we must cache the last valid naturalSize here:
+ m_cachedNaturalSize = naturalSize;
+ }
+
+ return IntSize(naturalSize.width() * m_scaleFactor.width(), naturalSize.height() * m_scaleFactor.height());
}
bool MediaPlayerPrivateQTKit::hasVideo() const
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp b/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
index 452bd54..832bb9d 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
@@ -39,15 +39,17 @@ using namespace std;
namespace WebCore {
-CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typesettingFeatures) const
+CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typesettingFeatures, FontOrientation orientation) const
{
unsigned key = typesettingFeatures + 1;
pair<HashMap<unsigned, RetainPtr<CFDictionaryRef> >::iterator, bool> addResult = m_CFStringAttributes.add(key, RetainPtr<CFDictionaryRef>());
RetainPtr<CFDictionaryRef>& attributesDictionary = addResult.first->second;
if (!addResult.second)
return attributesDictionary.get();
+
+ bool treatLineAsVertical = orientation == Vertical;
- bool allowLigatures = (orientation() == Horizontal && platformData().allowsLigatures()) || (typesettingFeatures & Ligatures);
+ bool allowLigatures = (!treatLineAsVertical && platformData().allowsLigatures()) || (typesettingFeatures & Ligatures);
static const int ligaturesNotAllowedValue = 0;
static CFNumberRef ligaturesNotAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesNotAllowedValue);
@@ -60,13 +62,13 @@ CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typese
static CFNumberRef kerningAdjustment = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &kerningAdjustmentValue);
static const void* keysWithKerningDisabled[] = { kCTFontAttributeName, kCTKernAttributeName, kCTLigatureAttributeName, kCTVerticalFormsAttributeName };
const void* valuesWithKerningDisabled[] = { platformData().ctFont(), kerningAdjustment, allowLigatures
- ? ligaturesAllowed : ligaturesNotAllowed, orientation() == Vertical ? kCFBooleanTrue : kCFBooleanFalse };
+ ? ligaturesAllowed : ligaturesNotAllowed, treatLineAsVertical ? kCFBooleanTrue : kCFBooleanFalse };
attributesDictionary.adoptCF(CFDictionaryCreate(0, keysWithKerningDisabled, valuesWithKerningDisabled,
WTF_ARRAY_LENGTH(keysWithKerningDisabled), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
} else {
// By omitting the kCTKernAttributeName attribute, we get Core Text's standard kerning.
static const void* keysWithKerningEnabled[] = { kCTFontAttributeName, kCTLigatureAttributeName, kCTVerticalFormsAttributeName };
- const void* valuesWithKerningEnabled[] = { platformData().ctFont(), allowLigatures ? ligaturesAllowed : ligaturesNotAllowed, orientation() == Vertical ? kCFBooleanTrue : kCFBooleanFalse };
+ const void* valuesWithKerningEnabled[] = { platformData().ctFont(), allowLigatures ? ligaturesAllowed : ligaturesNotAllowed, treatLineAsVertical ? kCFBooleanTrue : kCFBooleanFalse };
attributesDictionary.adoptCF(CFDictionaryCreate(0, keysWithKerningEnabled, valuesWithKerningEnabled,
WTF_ARRAY_LENGTH(keysWithKerningEnabled), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
}
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 3094498..cd34000 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -259,49 +259,32 @@ void SimpleFontData::platformInit()
descent = 3;
}
- if (m_orientation == Vertical) {
- // Ignore vertical orientation when the font doesn't support vertical metrics.
+ if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
// The check doesn't look neat but this is what AppKit does for vertical writing...
RetainPtr<CFArrayRef> tableTags(AdoptCF, CTFontCopyAvailableTables(m_platformData.ctFont(), kCTFontTableOptionExcludeSynthetic));
CFIndex numTables = CFArrayGetCount(tableTags.get());
- bool found = false;
for (CFIndex index = 0; index < numTables; ++index) {
CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tableTags.get(), index);
if (tag == kCTFontTableVhea || tag == kCTFontTableVORG) {
- found = true;
+ m_hasVerticalGlyphs = true;
break;
}
}
-
- if (found == false)
- m_orientation = Horizontal;
}
float xHeight;
- // Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
- // Unfortunately, NSFont will round this for us so we don't quite get the right value.
- GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
- NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
- if (xGlyph) {
- CGRect xBox = platformBoundsForGlyph(xGlyph);
- // Use the maximum of either width or height because "x" is nearly square
- // and web pages that foolishly use this metric for width will be laid out
- // poorly if we return an accurate height. Classic case is Times 13 point,
- // which has an "x" that is 7x6 pixels.
- xHeight = static_cast<float>(max(CGRectGetMaxX(xBox), -CGRectGetMinY(xBox)));
- } else {
-#ifndef BUILDING_ON_TIGER
- xHeight = static_cast<float>(CGFontGetXHeight(m_platformData.cgFont())) / unitsPerEm;
-#else
- xHeight = m_platformData.font() ? [m_platformData.font() xHeight] : 0;
-#endif
- // CGFontGetXHeight() returns a wrong value for "Apple Symbols" font (a float close to 0, but not strictly 0).
- // The following code makes a guess for xHeight in that case.
- // The int cast is a workaround for the "almost" zero value returned by CGFontGetXHeight().
- if (!static_cast<int>(xHeight) && ascent)
- xHeight = 2 * ascent / 3;
- }
+ if (platformData().orientation() == Horizontal) {
+ // Measure the actual character "x", since it's possible for it to extend below the baseline, and we need the
+ // reported x-height to only include the portion of the glyph that is above the baseline.
+ GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
+ NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
+ if (xGlyph)
+ xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph));
+ else
+ xHeight = scaleEmToUnits(CGFontGetXHeight(m_platformData.cgFont()), unitsPerEm) * pointSize;
+ } else
+ xHeight = verticalRightOrientationFontData()->fontMetrics().xHeight();
m_fontMetrics.setUnitsPerEm(unitsPerEm);
m_fontMetrics.setAscent(ascent);
@@ -474,17 +457,8 @@ void SimpleFontData::determinePitch()
FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
{
FloatRect boundingBox;
-#ifndef BUILDING_ON_TIGER
- boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(),
- orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1);
+ boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(), platformData().orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1);
boundingBox.setY(-boundingBox.maxY());
-#else
- // FIXME: Custom fonts don't have NSFonts, so this function doesn't compute correct bounds for these on Tiger.
- if (!m_platformData.font())
- return boundingBox;
- boundingBox = [m_platformData.font() boundingRectForGlyph:glyph];
- boundingBox.setY(-boundingBox.maxY());
-#endif
if (m_syntheticBoldOffset)
boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
@@ -494,7 +468,7 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
CGSize advance;
- if (orientation() == Horizontal || m_isBrokenIdeographFont) {
+ if (platformData().orientation() == Horizontal || m_isBrokenIdeographFallback) {
NSFont* font = platformData().font();
float pointSize = platformData().m_size;
CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
diff --git a/Source/WebCore/platform/graphics/mac/WebLayer.h b/Source/WebCore/platform/graphics/mac/WebLayer.h
index 30bf55b..2e9bea0 100644
--- a/Source/WebCore/platform/graphics/mac/WebLayer.h
+++ b/Source/WebCore/platform/graphics/mac/WebLayer.h
@@ -32,6 +32,7 @@
namespace WebCore {
class GraphicsLayer;
+ class PlatformCALayer;
class PlatformCALayerClient;
}
@@ -48,7 +49,7 @@ namespace WebCore {
@end
// Functions allows us to share implementation across WebTiledLayer and WebLayer
-void drawLayerContents(CGContextRef, CALayer *, WebCore::PlatformCALayerClient*);
+void drawLayerContents(CGContextRef, CALayer *, WebCore::PlatformCALayer*);
void setLayerNeedsDisplayInRect(CALayer *, WebCore::PlatformCALayerClient*, CGRect);
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/mac/WebLayer.mm b/Source/WebCore/platform/graphics/mac/WebLayer.mm
index 414a75f..c9705d0 100644
--- a/Source/WebCore/platform/graphics/mac/WebLayer.mm
+++ b/Source/WebCore/platform/graphics/mac/WebLayer.mm
@@ -40,8 +40,9 @@ using namespace WebCore;
@implementation WebLayer
-void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCALayerClient* layerContents)
+void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCALayer* platformLayer)
{
+ WebCore::PlatformCALayerClient* layerContents = platformLayer->owner();
if (!layerContents)
return;
@@ -62,6 +63,7 @@ void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCA
GraphicsContext graphicsContext(context);
graphicsContext.setIsCALayerContext(true);
+ graphicsContext.setIsAcceleratedContext(platformLayer->acceleratesDrawing());
if (!layerContents->platformCALayerContentsOpaque()) {
// Turn off font smoothing to improve the appearance of text rendered onto a transparent background.
@@ -167,7 +169,7 @@ void setLayerNeedsDisplayInRect(CALayer *layer, WebCore::PlatformCALayerClient*
{
PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
if (layer)
- drawLayerContents(context, self, layer->owner());
+ drawLayerContents(context, self, layer);
}
@end // implementation WebLayer
diff --git a/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm b/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
index e9fa5b7..9bcdd54 100644
--- a/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
+++ b/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
@@ -83,7 +83,7 @@ using namespace WebCore;
{
PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
if (layer)
- drawLayerContents(context, self, layer->owner());
+ drawLayerContents(context, self, layer);
}
@end // implementation WebTiledLayer
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index c224e20..f831550 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -38,6 +38,7 @@
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
#include "ImageBuffer.h"
+#include "ImageData.h"
#include "Int32Array.h"
#include "NotImplemented.h"
#include "Uint8Array.h"
@@ -53,11 +54,12 @@ namespace WebCore {
void GraphicsContext3D::validateAttributes()
{
- const char* extensions = reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS));
+ Extensions3D* extensions = getExtensions();
if (m_attrs.stencil) {
- if (std::strstr(extensions, "GL_EXT_packed_depth_stencil")) {
- if (!m_attrs.depth)
- m_attrs.depth = true;
+ if (extensions->supports("GL_EXT_packed_depth_stencil")) {
+ extensions->ensureEnabled("GL_EXT_packed_depth_stencil");
+ // Force depth if stencil is true.
+ m_attrs.depth = true;
} else
m_attrs.stencil = false;
}
@@ -67,24 +69,16 @@ void GraphicsContext3D::validateAttributes()
const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
if (!std::strstr(vendor, "NVIDIA"))
isValidVendor = false;
- if (!isValidVendor || !std::strstr(extensions, "GL_EXT_framebuffer_multisample"))
+ if (!isValidVendor || !extensions->supports("GL_ANGLE_framebuffer_multisample"))
m_attrs.antialias = false;
+ else
+ extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
}
- // FIXME: instead of enforcing premultipliedAlpha = true, implement the
- // correct behavior when premultipliedAlpha = false is requested.
- m_attrs.premultipliedAlpha = true;
}
-void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
+void GraphicsContext3D::readRenderingResults(unsigned char *pixels, int pixelsSize)
{
- HTMLCanvasElement* canvas = context->canvas();
- ImageBuffer* imageBuffer = canvas->buffer();
-
- int rowBytes = m_currentWidth * 4;
- int totalBytes = rowBytes * m_currentHeight;
-
- OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]);
- if (!pixels)
+ if (pixelsSize < m_currentWidth * m_currentHeight * 4)
return;
makeContextCurrent();
@@ -111,18 +105,62 @@ void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* co
mustRestorePackAlignment = true;
}
- ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.get());
+ ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
if (mustRestorePackAlignment)
::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
if (mustRestoreFBO)
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
+}
+
+void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
+{
+ HTMLCanvasElement* canvas = context->canvas();
+ ImageBuffer* imageBuffer = canvas->buffer();
+
+ int rowBytes = m_currentWidth * 4;
+ int totalBytes = rowBytes * m_currentHeight;
+
+ OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]);
+ if (!pixels)
+ return;
+
+ readRenderingResults(pixels.get(), totalBytes);
+
+ if (!m_attrs.premultipliedAlpha) {
+ for (int i = 0; i < totalBytes; i += 4) {
+ // Premultiply alpha
+ pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255);
+ pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255);
+ pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
+ }
+ }
paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
}
+PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
+{
+ // Reading premultiplied alpha would involve unpremultiplying, which is
+ // lossy
+ if (m_attrs.premultipliedAlpha)
+ return 0;
+
+ RefPtr<ImageData> imageData = ImageData::create(IntSize(m_currentWidth, m_currentHeight));
+ unsigned char* pixels = imageData->data()->data()->data();
+ int totalBytes = 4 * m_currentWidth * m_currentHeight;
+
+ readRenderingResults(pixels, totalBytes);
+
+ // Convert to RGBA
+ for (int i = 0; i < totalBytes; i += 4)
+ std::swap(pixels[i], pixels[i + 2]);
+
+ return imageData.release();
+}
+
void GraphicsContext3D::reshape(int width, int height)
{
if (!m_contextObj)
@@ -135,19 +173,23 @@ void GraphicsContext3D::reshape(int width, int height)
m_currentHeight = height;
makeContextCurrent();
-
- GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
+ validateAttributes();
+
+ GLuint colorFormat, internalDepthStencilFormat = 0;
if (m_attrs.alpha) {
- internalColorFormat = GL_RGBA8;
+ m_internalColorFormat = GL_RGBA8;
colorFormat = GL_RGBA;
} else {
- internalColorFormat = GL_RGB8;
+ m_internalColorFormat = GL_RGB8;
colorFormat = GL_RGB;
}
if (m_attrs.stencil || m_attrs.depth) {
// We don't allow the logic where stencil is required and depth is not.
- // See GraphicsContext3D constructor.
- if (m_attrs.stencil && m_attrs.depth)
+ // See GraphicsContext3D::validateAttributes.
+
+ Extensions3D* extensions = getExtensions();
+ // Use a 24 bit depth buffer where we know we have it
+ if (extensions->supports("GL_EXT_packed_depth_stencil"))
internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
else
internalDepthStencilFormat = GL_DEPTH_COMPONENT;
@@ -167,7 +209,7 @@ void GraphicsContext3D::reshape(int width, int height)
mustRestoreFBO = true;
}
::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
- ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
+ ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, m_internalColorFormat, width, height);
::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
if (m_attrs.stencil || m_attrs.depth) {
::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
@@ -190,8 +232,10 @@ void GraphicsContext3D::reshape(int width, int height)
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
}
::glBindTexture(GL_TEXTURE_2D, m_texture);
- ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
+ ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
::glBindTexture(GL_TEXTURE_2D, 0);
if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
@@ -278,19 +322,29 @@ IntSize GraphicsContext3D::getInternalFramebufferSize()
void GraphicsContext3D::prepareTexture()
{
+ if (m_layerComposited)
+ return;
makeContextCurrent();
if (m_attrs.antialias) {
::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
- ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
}
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ ::glActiveTexture(0);
+ ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
+ ::glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, 0, 0, m_currentWidth, m_currentHeight, 0);
+ ::glBindTexture(GL_TEXTURE_2D, m_boundTexture0);
+ ::glActiveTexture(m_activeTexture);
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
::glFinish();
+ m_layerComposited = true;
}
void GraphicsContext3D::activeTexture(GC3Denum texture)
{
makeContextCurrent();
+ m_activeTexture = texture;
::glActiveTexture(texture);
}
@@ -340,6 +394,8 @@ void GraphicsContext3D::bindRenderbuffer(GC3Denum target, Platform3DObject rende
void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
{
makeContextCurrent();
+ if (m_activeTexture && target == GL_TEXTURE_2D)
+ m_boundTexture0 = texture;
::glBindTexture(target, texture);
}
@@ -1442,6 +1498,21 @@ void GraphicsContext3D::synthesizeGLError(GC3Denum error)
m_syntheticErrors.add(error);
}
+void GraphicsContext3D::markContextChanged()
+{
+ m_layerComposited = false;
+}
+
+void GraphicsContext3D::markLayerComposited()
+{
+ m_layerComposited = true;
+}
+
+bool GraphicsContext3D::layerComposited() const
+{
+ return m_layerComposited;
+}
+
Extensions3D* GraphicsContext3D::getExtensions()
{
if (!m_extensions)
diff --git a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
index 2e2082d..9765937 100644
--- a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
@@ -21,11 +21,11 @@
#include "TextureMapperGL.h"
#include "GraphicsContext.h"
-#include "HashMap.h"
#include "Image.h"
-#include "PassRefPtr.h"
-#include "RefCounted.h"
#include "Timer.h"
+#include <wtf/HashMap.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
#if defined(TEXMAP_OPENGL_ES_2)
#include <GLES2/gl2.h>
diff --git a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h
index 8035abf..92c5198 100644
--- a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h
+++ b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h
@@ -24,8 +24,8 @@
#include "FloatQuad.h"
#include "IntSize.h"
+#include "TextureMapper.h"
#include "TransformationMatrix.h"
-#include "texmap/TextureMapper.h"
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/openvg/PathOpenVG.cpp b/Source/WebCore/platform/graphics/openvg/PathOpenVG.cpp
index 39a4b06..95df242 100644
--- a/Source/WebCore/platform/graphics/openvg/PathOpenVG.cpp
+++ b/Source/WebCore/platform/graphics/openvg/PathOpenVG.cpp
@@ -169,7 +169,7 @@ FloatRect Path::boundingRect() const
return FloatRect(FloatPoint(minX, minY), FloatSize(width, height));
}
-FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
{
notImplemented();
@@ -464,7 +464,7 @@ void Path::transform(const AffineTransform& transformation)
// functions and Path::apply() doesn't really work as long as we rely on VGPath
// as primary path storage.
-float Path::length()
+float Path::length() const
{
m_path->makeCompatibleContextCurrent();
VGfloat length = vgPathLength(m_path->vgPath(), 0, vgGetParameteri(m_path->vgPath(), VG_PATH_NUM_SEGMENTS));
@@ -472,7 +472,7 @@ float Path::length()
return length;
}
-FloatPoint Path::pointAtLength(float length, bool& ok)
+FloatPoint Path::pointAtLength(float length, bool& ok) const
{
VGfloat x = 0, y = 0;
m_path->makeCompatibleContextCurrent();
@@ -483,7 +483,7 @@ FloatPoint Path::pointAtLength(float length, bool& ok)
return FloatPoint(x, y);
}
-float Path::normalAngleAtLength(float length, bool& ok)
+float Path::normalAngleAtLength(float length, bool& ok) const
{
VGfloat tangentX, tangentY;
m_path->makeCompatibleContextCurrent();
diff --git a/Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp b/Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp
index f9d36d3..deff9f7 100644
--- a/Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp
+++ b/Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp
@@ -30,7 +30,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
{
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode)
{
return FontPlatformData(m_fontFace, size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/pango/FontPlatformData.h b/Source/WebCore/platform/graphics/pango/FontPlatformData.h
index 2929a3f..180d23b 100644
--- a/Source/WebCore/platform/graphics/pango/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/pango/FontPlatformData.h
@@ -74,7 +74,7 @@ public:
unsigned hash() const
{
uintptr_t hashCodes[1] = { reinterpret_cast<uintptr_t>(m_scaledFont) };
- return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
+ return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
}
bool operator==(const FontPlatformData&) const;
diff --git a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
index dcea72f..3adc93f 100644
--- a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
@@ -30,6 +30,7 @@
#include "Extensions3DQt.h"
#include "GraphicsContext3D.h"
+#include <QGLContext>
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
index e8441d2..3996d22 100644
--- a/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
@@ -25,6 +25,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include <wtf/FastAllocBase.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -43,7 +44,8 @@ public:
// for use with QFontDatabase::addApplicationFont/removeApplicationFont
int m_handle;
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight,
+ FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
};
diff --git a/Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp b/Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp
index ec8747d..20f161a 100644
--- a/Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp
@@ -34,7 +34,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
QFontDatabase::removeApplicationFont(m_handle);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode)
{
QFont font;
font.setFamily(QFontDatabase::applicationFontFamilies(m_handle)[0]);
diff --git a/Source/WebCore/platform/graphics/qt/FontPlatformData.h b/Source/WebCore/platform/graphics/qt/FontPlatformData.h
index 32e8a2d..4a92acf 100644
--- a/Source/WebCore/platform/graphics/qt/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/qt/FontPlatformData.h
@@ -141,6 +141,7 @@ public:
}
FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
+ void setOrientation(FontOrientation) { } // FIXME: Implement.
unsigned hash() const;
diff --git a/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
index 185ae85..95dabd5 100644
--- a/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
@@ -73,9 +73,7 @@ FontPlatformData::FontPlatformData(const FontDescription& description, const Ato
font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing);
const bool smallCaps = description.smallCaps();
font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase);
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
font.setStyleStrategy(QFont::ForceIntegerMetrics);
-#endif
m_data->bold = font.bold();
// WebKit allows font size zero but QFont does not. We will return
diff --git a/Source/WebCore/platform/graphics/qt/FontQt.cpp b/Source/WebCore/platform/graphics/qt/FontQt.cpp
index 646cd0e..3fe90a4 100644
--- a/Source/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/FontQt.cpp
@@ -169,21 +169,16 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
p->restore();
return;
}
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
int skipWidth = QFontMetrics(font).width(string, from, Qt::TextBypassShaping);
pt.setX(pt.x() + skipWidth);
string = fromRawDataWithoutRef(sanitized, from, to - from);
-#endif
}
p->setFont(font);
int flags = run.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight;
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
- // See QWebPagePrivate::QWebPagePrivate() where the default path is set to Complex for Qt 4.6 and earlier.
if (!isComplexText && !(ctx->textDrawingMode() & TextModeStroke))
flags |= Qt::TextBypassShaping;
-#endif
QPainterPath textStrokePath;
if (ctx->textDrawingMode() & TextModeStroke)
@@ -200,11 +195,7 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
p->restore();
} else {
QFontMetrics fm(font);
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
QRectF boundingRect(pt.x(), point.y() - fm.ascent(), fm.width(string, -1, flags), fm.height());
-#else
- QRectF boundingRect(pt.x(), point.y() - fm.ascent(), fm.width(string), fm.height());
-#endif
QPainter* shadowPainter = ctxShadow->beginShadowLayer(ctx, boundingRect);
if (shadowPainter) {
// Since it will be blurred anyway, we don't care about render hints.
@@ -221,11 +212,7 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
p->translate(-ctxShadow->offset());
} else {
QFontMetrics fm(font);
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
QRectF boundingRect(pt.x(), point.y() - fm.ascent(), fm.width(string, -1, flags), fm.height());
-#else
- QRectF boundingRect(pt.x(), point.y() - fm.ascent(), fm.width(string), fm.height());
-#endif
QPainter* shadowPainter = ctxShadow->beginShadowLayer(ctx, boundingRect);
if (shadowPainter) {
// Since it will be blurred anyway, we don't care about render hints.
@@ -250,11 +237,7 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
void Font::drawSimpleText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point, int from, int to) const
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
drawTextCommon(ctx, run, point, from, to, font(), /* isComplexText = */false);
-#else
- Q_ASSERT(false);
-#endif
}
void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point, int from, int to) const
@@ -295,7 +278,6 @@ float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer
if (!primaryFont()->platformData().size())
return 0;
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
if (!run.length())
return 0;
@@ -309,10 +291,6 @@ float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer
w -= m_wordSpacing;
return w + run.expansion();
-#else
- Q_ASSERT(false);
- return 0;
-#endif
}
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>*, GlyphOverflow*) const
@@ -339,7 +317,6 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
int Font::offsetForPositionForSimpleText(const TextRun& run, float position, bool includePartialGlyphs) const
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString string = fromRawDataWithoutRef(sanitized);
@@ -359,10 +336,6 @@ int Font::offsetForPositionForSimpleText(const TextRun& run, float position, boo
} while (++curPos < string.size());
return curPos;
-#else
- Q_ASSERT(false);
- return 0;
-#endif
}
int Font::offsetForPositionForComplexText(const TextRun& run, float position, bool) const
@@ -377,7 +350,6 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float position, bo
FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& pt, int h, int from, int to) const
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString wholeText = fromRawDataWithoutRef(sanitized);
QString selectedText = fromRawDataWithoutRef(sanitized, from, qMin(to - from, wholeText.length() - from));
@@ -386,10 +358,6 @@ FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint&
int width = QFontMetrics(font()).width(selectedText, -1, Qt::TextBypassShaping);
return FloatRect(pt.x() + startX, pt.y(), width, h);
-#else
- Q_ASSERT(false);
- return FloatRect();
-#endif
}
FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& pt, int h, int from, int to) const
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index b849214..4daa4dc 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -27,10 +27,14 @@
#include "HTMLCanvasElement.h"
#include "HostWindow.h"
#include "ImageBuffer.h"
+#include "ImageData.h"
#include "NotImplemented.h"
#include "QWebPageClient.h"
+#include "qwebpage.h"
#include <QAbstractScrollArea>
+#include <QGraphicsObject>
#include <QGLContext>
+#include <QStyleOptionGraphicsItem>
#include <wtf/UnusedParam.h>
#include <wtf/text/CString.h>
@@ -42,6 +46,10 @@ namespace WebCore {
typedef char GLchar;
#endif
+#if !defined(GL_DEPTH24_STENCIL8)
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
#if !defined(APIENTRY)
#define APIENTRY
#endif
@@ -145,13 +153,17 @@ typedef void (APIENTRY* glVertexAttrib4fType) (GLuint, const GLfloat, const GLfl
typedef void (APIENTRY* glVertexAttrib4fvType) (GLuint, const GLfloat*);
typedef void (APIENTRY* glVertexAttribPointerType) (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
-class GraphicsContext3DInternal {
+class GraphicsContext3DInternal : public QGraphicsObject {
public:
GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow);
~GraphicsContext3DInternal();
- bool isContextValid() { return m_contextValid; }
- QGLWidget* getOwnerGLWidget(QWebPageClient* webPageClient);
+ bool isValid() { return m_valid; }
+
+ QGLWidget* getViewportGLWidget();
+ void reshape(int width, int height);
+ void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
+ QRectF boundingRect() const;
glActiveTextureType activeTexture;
glAttachShaderType attachShader;
@@ -247,11 +259,13 @@ public:
GraphicsContext3D::Attributes m_attrs;
HostWindow* m_hostWindow;
QGLWidget* m_glWidget;
+ QGLWidget* m_viewportGLWidget;
+ QRectF m_boundingRect;
GLuint m_texture;
- GLuint m_mainFbo;
+ GLuint m_canvasFbo;
GLuint m_currentFbo;
GLuint m_depthBuffer;
- QImage m_pixels;
+ bool m_layerComposited;
ListHashSet<unsigned int> m_syntheticErrors;
OwnPtr<Extensions3DQt> m_extensions;
@@ -259,7 +273,7 @@ public:
private:
void* getProcAddress(const String& proc);
- bool m_contextValid;
+ bool m_valid;
};
#if defined (QT_OPENGL_ES_2)
@@ -281,39 +295,37 @@ GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attribut
: m_attrs(attrs)
, m_hostWindow(hostWindow)
, m_glWidget(0)
+ , m_viewportGLWidget(0)
, m_texture(0)
- , m_mainFbo(0)
+ , m_canvasFbo(0)
, m_currentFbo(0)
, m_depthBuffer(0)
- , m_contextValid(true)
+ , m_layerComposited(false)
+ , m_valid(true)
{
- QWebPageClient* webPageClient = hostWindow->platformPageClient();
- QGLWidget* ownerGLWidget = getOwnerGLWidget(webPageClient);
+ m_viewportGLWidget = getViewportGLWidget();
- if (ownerGLWidget)
- m_glWidget = new QGLWidget(0, ownerGLWidget);
- else {
- QGLFormat format;
- format.setDepth(true);
- format.setSampleBuffers(true);
- format.setStencil(false);
-
- m_glWidget = new QGLWidget(format);
- }
+ if (m_viewportGLWidget)
+ m_glWidget = new QGLWidget(0, m_viewportGLWidget);
+ else
+ m_glWidget = new QGLWidget();
if (!m_glWidget->isValid()) {
- LOG_ERROR("GraphicsContext3D: QGLWidget does not have a valid context");
- m_contextValid = false;
+ LOG_ERROR("GraphicsContext3D: QGLWidget initialization failed.");
+ m_valid = false;
return;
}
-
- QGLFormat format = m_glWidget->format();
- m_attrs.alpha = format.alpha();
- m_attrs.depth = format.depth();
- m_attrs.stencil = format.stencil();
+ // Geometry can be set to zero because m_glWidget is used only for its QGLContext.
+ m_glWidget->setGeometry(0, 0, 0, 0);
+
+#if defined(QT_OPENGL_ES_2)
+ m_attrs.stencil = false;
+#else
+ if (m_attrs.stencil)
+ m_attrs.depth = true;
+#endif
m_attrs.antialias = false;
- m_attrs.premultipliedAlpha = true;
m_glWidget->makeCurrent();
@@ -408,60 +420,165 @@ GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attribut
vertexAttrib4fv = GET_PROC_ADDRESS(glVertexAttrib4fv);
vertexAttribPointer = GET_PROC_ADDRESS(glVertexAttribPointer);
- if (!m_contextValid) {
+ if (!m_valid) {
LOG_ERROR("GraphicsContext3D: All needed OpenGL extensions are not available");
- m_contextValid = false;
return;
}
+ // Create buffers for the canvas FBO.
+ genFramebuffers(/* count */ 1, &m_canvasFbo);
+
glGenTextures(1, &m_texture);
glBindTexture(GraphicsContext3D::TEXTURE_2D, m_texture);
glTexParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
glTexParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
glTexParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
glTexParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
- glTexImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
glBindTexture(GraphicsContext3D::TEXTURE_2D, 0);
- genFramebuffers(/* count */ 1, &m_mainFbo);
- m_currentFbo = m_mainFbo;
+ if (m_attrs.depth)
+ genRenderbuffers(/* count */ 1, &m_depthBuffer);
+
+ // Bind canvas FBO and set initial clear color to black.
+ m_currentFbo = m_canvasFbo;
+ bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_canvasFbo);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+}
+
+GraphicsContext3DInternal::~GraphicsContext3DInternal()
+{
+ delete m_glWidget;
+ m_glWidget = 0;
+}
+
+QGLWidget* GraphicsContext3DInternal::getViewportGLWidget()
+{
+ QWebPageClient* webPageClient = m_hostWindow->platformPageClient();
+ if (!webPageClient)
+ return 0;
+
+ QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>(webPageClient->ownerWidget());
+ if (scrollArea)
+ return qobject_cast<QGLWidget*>(scrollArea->viewport());
+
+ return 0;
+}
+
+static inline quint32 swapBgrToRgb(quint32 pixel)
+{
+ return ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
+}
+
+void GraphicsContext3DInternal::reshape(int width, int height)
+{
+ if (width == m_boundingRect.width() && height == m_boundingRect.height())
+ return;
+
+ m_boundingRect = QRectF(QPointF(0, 0), QSizeF(width, height));
+
+ m_glWidget->makeCurrent();
- bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_mainFbo);
+ // Create color buffer
+ glBindTexture(GraphicsContext3D::TEXTURE_2D, m_texture);
+ if (m_attrs.alpha)
+ glTexImage2D(GraphicsContext3D::TEXTURE_2D, /* level */ 0, GraphicsContext3D::RGBA, width, height, /* border */ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, /* data */ 0);
+ else
+ glTexImage2D(GraphicsContext3D::TEXTURE_2D, /* level */ 0, GraphicsContext3D::RGB, width, height, /* border */ 0, GraphicsContext3D::RGB, GraphicsContext3D::UNSIGNED_BYTE, /* data */ 0);
+ glBindTexture(GraphicsContext3D::TEXTURE_2D, 0);
- genRenderbuffers(/* count */ 1, &m_depthBuffer);
- bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+ if (m_attrs.depth) {
+ // Create depth and stencil buffers.
+ bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
#if defined(QT_OPENGL_ES_2)
- renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, /* width */ 1, /* height */ 1);
+ renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, width, height);
#else
- renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT, /* width */ 1, /* height */ 1);
+ if (m_attrs.stencil)
+ renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+ else
+ renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT, width, height);
#endif
+ bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
+ }
- bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
-
+ // Construct canvas FBO.
+ bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_canvasFbo);
framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_texture, 0);
- framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
- glClearColor(/* red */ 0, /* green */ 0, /* blue */ 0, /* alpha */ 0);
+ if (m_attrs.depth)
+ framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+#if !defined(QT_OPENGL_ES_2)
+ if (m_attrs.stencil)
+ framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+#endif
- if (checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
- LOG_ERROR("GraphicsContext3D: Wasn't able to create the main framebuffer");
- m_contextValid = false;
+ GLenum status = checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER);
+ if (status != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+ LOG_ERROR("GraphicsContext3D: Canvas FBO initialization failed.");
+ return;
}
-}
-GraphicsContext3DInternal::~GraphicsContext3DInternal()
-{
- delete m_glWidget;
- m_glWidget = 0;
+ int clearFlags = GraphicsContext3D::COLOR_BUFFER_BIT;
+ if (m_attrs.depth)
+ clearFlags |= GraphicsContext3D::DEPTH_BUFFER_BIT;
+ if (m_attrs.stencil)
+ clearFlags |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+
+ glClear(clearFlags);
+ glFlush();
}
-QGLWidget* GraphicsContext3DInternal::getOwnerGLWidget(QWebPageClient* webPageClient)
+void GraphicsContext3DInternal::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
- QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>(webPageClient->ownerWidget());
+ Q_UNUSED(widget);
- if (scrollArea)
- return qobject_cast<QGLWidget*>(scrollArea->viewport());
+ QRectF rect = option ? option->rect : boundingRect();
- return 0;
+ // Use direct texture mapping if WebGL canvas has a shared OpenGL context
+ // with browsers OpenGL context.
+ QGLWidget* viewportGLWidget = getViewportGLWidget();
+ if (viewportGLWidget && viewportGLWidget == m_viewportGLWidget && viewportGLWidget == painter->device()) {
+ viewportGLWidget->drawTexture(rect, m_texture);
+ return;
+ }
+
+ // Alternatively read pixels to a memory buffer.
+ QImage offscreenImage(rect.width(), rect.height(), QImage::Format_ARGB32);
+ quint32* imagePixels = reinterpret_cast<quint32*>(offscreenImage.bits());
+
+ m_glWidget->makeCurrent();
+ bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_canvasFbo);
+ glReadPixels(/* x */ 0, /* y */ 0, rect.width(), rect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, imagePixels);
+
+ bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_currentFbo);
+
+ // OpenGL gives us ABGR on 32 bits, and with the origin at the bottom left
+ // We need RGB32 or ARGB32_PM, with the origin at the top left.
+ quint32* pixelsSrc = imagePixels;
+ const int height = static_cast<int>(rect.height());
+ const int width = static_cast<int>(rect.width());
+ const int halfHeight = height / 2;
+ for (int row = 0; row < halfHeight; ++row) {
+ const int targetIdx = (height - 1 - row) * width;
+ quint32* pixelsDst = imagePixels + targetIdx;
+ for (int column = 0; column < width; ++column) {
+ quint32 tempPixel = *pixelsSrc;
+ *pixelsSrc = swapBgrToRgb(*pixelsDst);
+ *pixelsDst = swapBgrToRgb(tempPixel);
+ ++pixelsSrc;
+ ++pixelsDst;
+ }
+ }
+ if (static_cast<int>(height) % 2) {
+ for (int column = 0; column < width; ++column) {
+ *pixelsSrc = swapBgrToRgb(*pixelsSrc);
+ ++pixelsSrc;
+ }
+ }
+ painter->drawImage(/* x */ 0, /* y */ 0, offscreenImage);
+}
+
+QRectF GraphicsContext3DInternal::boundingRect() const
+{
+ return m_boundingRect;
}
void* GraphicsContext3DInternal::getProcAddress(const String& proc)
@@ -477,7 +594,7 @@ void* GraphicsContext3DInternal::getProcAddress(const String& proc)
}
LOG_ERROR("GraphicsContext3D: Did not find GL function %s", proc.utf8().data());
- m_contextValid = false;
+ m_valid = false;
return 0;
}
@@ -493,7 +610,7 @@ PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attri
GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool)
: m_internal(new GraphicsContext3DInternal(attrs, hostWindow))
{
- if (!m_internal->isContextValid())
+ if (!m_internal->isValid())
m_internal = 0;
}
@@ -511,6 +628,11 @@ Platform3DObject GraphicsContext3D::platformTexture() const
return m_internal->m_texture;
}
+PlatformLayer* GraphicsContext3D::platformLayer() const
+{
+ return m_internal.get();
+}
+
void GraphicsContext3D::makeContextCurrent()
{
m_internal->m_glWidget->makeCurrent();
@@ -522,62 +644,25 @@ void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* co
HTMLCanvasElement* canvas = context->canvas();
ImageBuffer* imageBuffer = canvas->buffer();
QPainter* painter = imageBuffer->context()->platformContext();
- paint(painter, QRect(QPoint(0, 0), QSize(m_currentWidth, m_currentHeight)));
+ m_internal->paint(painter, 0, 0);
}
-void GraphicsContext3D::paint(QPainter* painter, const QRect& rect) const
+PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
- QWebPageClient* webPageClient = m_internal->m_hostWindow->platformPageClient();
- QGLWidget* ownerGLWidget = m_internal->getOwnerGLWidget(webPageClient);
- if (ownerGLWidget) {
- ownerGLWidget->drawTexture(rect, m_internal->m_texture);
- return;
- }
-#endif
- m_internal->m_glWidget->makeCurrent();
- m_internal->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_internal->m_mainFbo);
- glReadPixels(/* x */ 0, /* y */ 0, m_currentWidth, m_currentHeight, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, m_internal->m_pixels.bits());
- painter->drawImage(/* x */ 0, /* y */ 0, m_internal->m_pixels.rgbSwapped().transformed(QMatrix().rotate(180)));
- m_internal->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_internal->m_currentFbo);
+ // FIXME: This needs to be implemented for proper non-premultiplied-alpha
+ // support.
+ return 0;
}
void GraphicsContext3D::reshape(int width, int height)
{
- if (((width == m_currentWidth) && (height == m_currentHeight)) || (!m_internal))
+ if (width == m_currentWidth && height == m_currentHeight || (!m_internal))
return;
-
+
m_currentWidth = width;
m_currentHeight = height;
- m_internal->m_pixels = QImage(m_currentWidth, m_currentHeight, QImage::Format_ARGB32);
-
- m_internal->m_glWidget->makeCurrent();
-
- glBindTexture(GraphicsContext3D::TEXTURE_2D, m_internal->m_texture);
- glTexImage2D(GraphicsContext3D::TEXTURE_2D, /* level */ 0, GraphicsContext3D::RGBA, width, height, /* border */ 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, /* data */ 0);
- glBindTexture(GraphicsContext3D::TEXTURE_2D, 0);
-
- m_internal->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_internal->m_mainFbo);
- m_internal->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_internal->m_depthBuffer);
-#if defined(QT_OPENGL_ES_2)
- renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT16, width, height);
-#else
- renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_COMPONENT, width, height);
-#endif
- m_internal->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
-
- m_internal->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_internal->m_texture, 0);
- m_internal->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_internal->m_depthBuffer);
-
- GLenum status = m_internal->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER);
- if (status != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
- LOG_ERROR("GraphicsContext3D: Wasn't able to reshape the main framebuffer");
- notImplemented();
- }
-
- glClear(GraphicsContext3D::COLOR_BUFFER_BIT);
- glFlush();
+ m_internal->reshape(width, height);
}
IntSize GraphicsContext3D::getInternalFramebufferSize()
@@ -626,7 +711,7 @@ void GraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
{
m_internal->m_glWidget->makeCurrent();
- m_internal->m_currentFbo = buffer ? buffer : m_internal->m_mainFbo;
+ m_internal->m_currentFbo = buffer ? buffer : m_internal->m_canvasFbo;
m_internal->bindFramebuffer(target, m_internal->m_currentFbo);
}
@@ -1064,6 +1149,23 @@ void GraphicsContext3D::releaseShaderCompiler()
void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
{
m_internal->m_glWidget->makeCurrent();
+#if !defined(QT_OPENGL_ES_2)
+ switch (internalformat) {
+ case DEPTH_STENCIL:
+ internalformat = GL_DEPTH24_STENCIL8;
+ break;
+ case DEPTH_COMPONENT16:
+ internalformat = DEPTH_COMPONENT;
+ break;
+ case RGBA4:
+ case RGB5_A1:
+ internalformat = RGBA;
+ break;
+ case RGB565:
+ internalformat = RGB;
+ break;
+ }
+#endif
m_internal->renderbufferStorage(target, internalformat, width, height);
}
@@ -1598,6 +1700,22 @@ void GraphicsContext3D::synthesizeGLError(GC3Denum error)
m_internal->m_syntheticErrors.add(error);
}
+void GraphicsContext3D::markLayerComposited()
+{
+ m_internal->m_layerComposited = true;
+}
+
+void GraphicsContext3D::markContextChanged()
+{
+ // FIXME: Any accelerated compositor needs to be told to re-read from here.
+ m_internal->m_layerComposited = false;
+}
+
+bool GraphicsContext3D::layerComposited() const
+{
+ return m_internal->m_layerComposited;
+}
+
Extensions3D* GraphicsContext3D::getExtensions()
{
if (!m_internal->m_extensions)
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 9742755..e3e0fa6 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -9,6 +9,7 @@
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de>
* Copyright (C) 2010, 2011 Sencha, Inc.
+ * Copyright (C) 2011 Andreas Kling <kling@webkit.org>
*
* All rights reserved.
*
@@ -672,8 +673,6 @@ void GraphicsContext::fillRect(const FloatRect& rect)
ContextShadow* shadow = contextShadow();
if (m_state.fillPattern) {
- AffineTransform affine;
- QBrush brush(m_state.fillPattern->createPlatformPattern(affine));
QPixmap* image = m_state.fillPattern->tileImage()->nativeImageForCurrentFrame();
QPainter* shadowPainter = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
if (shadowPainter) {
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
index f3cfc47..1f77fc2 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -310,10 +310,6 @@ public:
}
} m_state;
-#if ENABLE(WEBGL)
- const GraphicsContext3D* m_gc3D;
-#endif
-
#ifndef QT_NO_ANIMATION
friend class AnimationQtBase;
#endif
@@ -340,9 +336,6 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer)
#if ENABLE(TILED_BACKING_STORE)
, m_tiledBackingStore(0)
#endif
-#if ENABLE(WEBGL)
- , m_gc3D(0)
-#endif
{
// We use graphics-view for compositing-only, not for interactivity.
setAcceptedMouseButtons(Qt::NoButton);
@@ -665,11 +658,6 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte
case MediaContentType:
// we don't need to paint anything: we have a QGraphicsItem from the media element
break;
-#if ENABLE(WEBGL)
- case Canvas3DContentType:
- m_gc3D->paint(painter, option->rect);
- break;
-#endif
}
}
@@ -808,16 +796,6 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
setFlag(ItemHasNoContents, !m_layer->drawsContent());
break;
-
-#if ENABLE(WEBGL)
- case Canvas3DContentType:
- if (m_pendingContent.contentType != m_currentContent.contentType)
- update();
-
- setCacheMode(NoCache);
- setFlag(ItemHasNoContents, false);
- break;
-#endif
}
}
@@ -1268,23 +1246,6 @@ void GraphicsLayerQt::setContentsBackgroundColor(const Color& color)
GraphicsLayer::setContentsBackgroundColor(color);
}
-#if ENABLE(WEBGL)
-void GraphicsLayerQt::setContentsToGraphicsContext3D(const GraphicsContext3D* ctx)
-{
- if (ctx == m_impl->m_gc3D)
- return;
-
- m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::Canvas3DContentType;
- m_impl->m_gc3D = ctx;
- m_impl->notifyChange(GraphicsLayerQtImpl::ContentChange);
-}
-
-void GraphicsLayerQt::setGraphicsContext3DNeedsDisplay()
-{
- setNeedsDisplay();
-}
-#endif
-
void GraphicsLayerQt::setContentsToMedia(PlatformLayer* media)
{
if (media) {
@@ -1297,6 +1258,11 @@ void GraphicsLayerQt::setContentsToMedia(PlatformLayer* media)
GraphicsLayer::setContentsToMedia(media);
}
+void GraphicsLayerQt::setContentsToCanvas(PlatformLayer* canvas)
+{
+ setContentsToMedia(canvas);
+}
+
/* \reimp (GraphicsLayer.h)
*/
void GraphicsLayerQt::setContentsOrientation(CompositingCoordinatesOrientation orientation)
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h
index 569bd8d..2af98fd 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h
+++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h
@@ -20,9 +20,6 @@
#ifndef GraphicsLayerQt_h
#define GraphicsLayerQt_h
-#if ENABLE(WEBGL)
-#include "GraphicsContext3D.h"
-#endif
#include "GraphicsLayer.h"
#include "GraphicsLayerClient.h"
@@ -78,11 +75,8 @@ public:
virtual void setContentsToImage(Image*);
virtual void setContentsNeedsDisplay();
virtual void setContentsToMedia(PlatformLayer*);
+ virtual void setContentsToCanvas(PlatformLayer*);
virtual void setContentsBackgroundColor(const Color&);
-#if ENABLE(WEBGL)
- virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*);
- virtual void setGraphicsContext3DNeedsDisplay();
-#endif
virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation);
virtual void distributeOpacity(float);
virtual float accumulatedOpacity() const;
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferData.h b/Source/WebCore/platform/graphics/qt/ImageBufferData.h
index aa32253..602197e 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferData.h
@@ -42,6 +42,8 @@ class ImageBufferData {
public:
ImageBufferData(const IntSize&);
+ QImage toQImage() const;
+
QPixmap m_pixmap;
OwnPtr<QPainter> m_painter;
RefPtr<Image> m_image;
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index 62f5c3e..f7d63ca 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -80,6 +80,21 @@ ImageBufferData::ImageBufferData(const IntSize& size)
m_image = StillImage::createForRendering(&m_pixmap);
}
+QImage ImageBufferData::toQImage() const
+{
+ QPaintEngine* paintEngine = m_pixmap.paintEngine();
+ if (!paintEngine || paintEngine->type() != QPaintEngine::Raster)
+ return m_pixmap.toImage();
+
+ // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it.
+ // For performance reasons, we don't want that here, so we temporarily redirect the paint engine.
+ QPaintDevice* currentPaintDevice = paintEngine->paintDevice();
+ paintEngine->setPaintDevice(0);
+ QImage image = m_pixmap.toImage();
+ paintEngine->setPaintDevice(currentPaintDevice);
+ return image;
+}
+
ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, bool& success)
: m_data(size)
, m_size(size)
@@ -159,7 +174,7 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
if (isPainting)
m_data.m_painter->end();
- QImage image = m_data.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ QImage image = m_data.toQImage().convertToFormat(QImage::Format_ARGB32);
ASSERT(!image.isNull());
uchar* bits = image.bits();
@@ -214,16 +229,12 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
int numRows = endy - originy;
// NOTE: For unmultiplied data, we undo the premultiplication below.
- QImage image = imageData.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ QImage image = imageData.toQImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
ASSERT(!image.isNull());
const int bytesPerLine = image.bytesPerLine();
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
const uchar* bits = image.constBits();
-#else
- const uchar* bits = image.bits();
-#endif
quint32* destRows = reinterpret_cast_ptr<quint32*>(&data[desty * rect.width() * 4 + destx * 4]);
diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index 3540994..8cda231 100644
--- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -194,15 +194,7 @@ void ImageDecoderQt::internalReadImage(size_t frameIndex)
bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex)
{
- QPixmap pixmap;
-
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
- pixmap = QPixmap::fromImageReader(m_reader.get());
-#else
- QImage img;
- if (m_reader->read(&img))
- pixmap = QPixmap::fromImage(img);
-#endif
+ QPixmap pixmap = QPixmap::fromImageReader(m_reader.get());
if (pixmap.isNull()) {
frameCount();
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index 001d45b..bc43acf 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -74,7 +74,7 @@ void MediaPlayerPrivateQt::getSupportedTypes(HashSet<String> &supported)
for (int i = 0; i < types.size(); i++) {
QString mime = types.at(i);
- if (mime.startsWith("audio/") || mime.startsWith("video/"))
+ if (mime.startsWith(QString::fromLatin1("audio/")) || mime.startsWith(QString::fromLatin1("video/")))
supported.add(mime);
}
}
@@ -103,7 +103,6 @@ MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player)
, m_isVisible(false)
, m_isSeeking(false)
, m_composited(false)
- , m_queuedSeek(-1)
, m_preload(MediaPlayer::Auto)
, m_suppressNextPlaybackChanged(false)
{
@@ -195,7 +194,7 @@ void MediaPlayerPrivateQt::commitLoad(const String& url)
HTMLMediaElement* element = static_cast<HTMLMediaElement*>(m_webCorePlayer->mediaPlayerClient());
// Construct the media content with a network request if the resource is http[s]
- if (scheme == "http" || scheme == "https") {
+ if (scheme == QString::fromLatin1("http") || scheme == QString::fromLatin1("https")) {
QNetworkRequest request = QNetworkRequest(rUrl);
// Grab the current document
@@ -220,7 +219,7 @@ void MediaPlayerPrivateQt::commitLoad(const String& url)
// Set the refferer, but not when requesting insecure content from a secure page
QUrl documentUrl = QUrl(QString(document->documentURI()));
- if (documentUrl.scheme().toLower() == "http" || scheme == "https")
+ if (documentUrl.scheme().toLower() == QString::fromLatin1("http") || scheme == QString::fromLatin1("https"))
request.setRawHeader("Referer", documentUrl.toEncoded());
// Set the user agent
@@ -296,32 +295,8 @@ void MediaPlayerPrivateQt::seek(float position)
if (m_mediaPlayerControl && !m_mediaPlayerControl->availablePlaybackRanges().contains(position * 1000))
return;
- if (m_isSeeking)
- return;
-
- if (position > duration())
- position = duration();
-
- // Seeking is most reliable when we're paused.
- // Webkit will try to pause before seeking, but due to the asynchronous nature
- // of the backend, the player may not actually be paused yet.
- // In this case, we should queue the seek and wait until pausing has completed
- // before attempting to seek.
- if (m_mediaPlayer->state() == QMediaPlayer::PlayingState) {
- m_mediaPlayer->pause();
- m_isSeeking = true;
- m_queuedSeek = static_cast<qint64>(position * 1000);
-
- // Set a timeout, so that in the event that we don't get a state changed
- // signal, we still attempt the seek.
- QTimer::singleShot(1000, this, SLOT(queuedSeekTimeout()));
- } else {
- m_isSeeking = true;
- m_mediaPlayer->setPosition(static_cast<qint64>(position * 1000));
-
- // Set a timeout, in case we don't get a position changed signal
- QTimer::singleShot(10000, this, SLOT(seekTimeout()));
- }
+ m_isSeeking = true;
+ m_mediaPlayer->setPosition(static_cast<qint64>(position * 1000));
}
bool MediaPlayerPrivateQt::seeking() const
@@ -443,13 +418,8 @@ void MediaPlayerPrivateQt::handleError(QMediaPlayer::Error)
updateStates();
}
-void MediaPlayerPrivateQt::stateChanged(QMediaPlayer::State state)
+void MediaPlayerPrivateQt::stateChanged(QMediaPlayer::State)
{
- if (state != QMediaPlayer::PlayingState && m_isSeeking && m_queuedSeek >= 0) {
- m_mediaPlayer->setPosition(m_queuedSeek);
- m_queuedSeek = -1;
- }
-
if (!m_suppressNextPlaybackChanged)
m_webCorePlayer->playbackStateChanged();
else
@@ -468,34 +438,12 @@ void MediaPlayerPrivateQt::nativeSizeChanged(const QSizeF& size)
m_webCorePlayer->sizeChanged();
}
-void MediaPlayerPrivateQt::queuedSeekTimeout()
-{
- // If we haven't heard anything, assume the player is now paused
- // and we can attempt the seek
- if (m_isSeeking && m_queuedSeek >= 0) {
- m_mediaPlayer->setPosition(m_queuedSeek);
- m_queuedSeek = -1;
-
- // Set a timeout, in case we don't get a position changed signal
- QTimer::singleShot(10000, this, SLOT(seekTimeout()));
- }
-}
-
-void MediaPlayerPrivateQt::seekTimeout()
-{
- // If we haven't heard anything, assume the seek succeeded
- if (m_isSeeking) {
- m_webCorePlayer->timeChanged();
- m_isSeeking = false;
- }
-}
-
void MediaPlayerPrivateQt::positionChanged(qint64)
{
// Only propagate this event if we are seeking
- if (m_isSeeking && m_queuedSeek == -1) {
- m_webCorePlayer->timeChanged();
+ if (m_isSeeking) {
m_isSeeking = false;
+ m_webCorePlayer->timeChanged();
}
}
@@ -649,7 +597,7 @@ void MediaPlayerPrivateQt::repaint()
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
-class TextureMapperVideoLayerQt : public virtual TextureMapperVideoLayer {
+class TextureMapperVideoLayerQt : public virtual TextureMapperMediaLayer {
public:
TextureMapperVideoLayerQt(QGraphicsVideoItem* videoItem)
: m_videoItem(videoItem)
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
index 81cdd79..c6398c9 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
@@ -33,7 +33,7 @@ QT_END_NAMESPACE
namespace WebCore {
-class TextureMapperVideoLayer;
+class TextureMapperMediaLayer;
class MediaPlayerPrivateQt : public QObject, public MediaPlayerPrivateInterface {
@@ -120,8 +120,6 @@ private slots:
void handleError(QMediaPlayer::Error);
void stateChanged(QMediaPlayer::State);
void nativeSizeChanged(const QSizeF&);
- void queuedSeekTimeout();
- void seekTimeout();
void positionChanged(qint64);
void durationChanged(qint64);
void bufferStatusChanged(int);
@@ -141,7 +139,7 @@ private:
QGraphicsVideoItem* m_videoItem;
QGraphicsScene* m_videoScene;
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
- OwnPtr<TextureMapperVideoLayer> m_platformLayer;
+ OwnPtr<TextureMapperMediaLayer> m_platformLayer;
#endif
mutable MediaPlayer::NetworkState m_networkState;
@@ -153,7 +151,6 @@ private:
bool m_isVisible;
bool m_isSeeking;
bool m_composited;
- qint64 m_queuedSeek;
MediaPlayer::Preload m_preload;
bool m_delayingLoad;
String m_mediaUrl;
diff --git a/Source/WebCore/platform/graphics/qt/PathQt.cpp b/Source/WebCore/platform/graphics/qt/PathQt.cpp
index ad482f7..ccc7f3d 100644
--- a/Source/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/PathQt.cpp
@@ -154,7 +154,7 @@ FloatRect Path::boundingRect() const
return m_path.boundingRect();
}
-FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
{
GraphicsContext* context = scratchContext();
QPainterPathStroker stroke;
@@ -398,23 +398,15 @@ void Path::apply(void* info, PathApplierFunction function) const
void Path::transform(const AffineTransform& transform)
{
QTransform qTransform(transform);
-#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
- // Workaround for http://bugreports.qt.nokia.com/browse/QTBUG-11264
- // QTransform.map doesn't handle the MoveTo element because of the isEmpty issue
- if (m_path.isEmpty() && m_path.elementCount()) {
- QPointF point = qTransform.map(m_path.currentPosition());
- moveTo(point);
- } else
-#endif
- m_path = qTransform.map(m_path);
-}
-
-float Path::length()
+ m_path = qTransform.map(m_path);
+}
+
+float Path::length() const
{
return m_path.length();
}
-FloatPoint Path::pointAtLength(float length, bool& ok)
+FloatPoint Path::pointAtLength(float length, bool& ok) const
{
ok = (length >= 0 && length <= m_path.length());
@@ -424,7 +416,7 @@ FloatPoint Path::pointAtLength(float length, bool& ok)
return point;
}
-float Path::normalAngleAtLength(float length, bool& ok)
+float Path::normalAngleAtLength(float length, bool& ok) const
{
ok = (length >= 0 && length <= m_path.length());
diff --git a/Source/WebCore/platform/graphics/qt/TileQt.cpp b/Source/WebCore/platform/graphics/qt/TileQt.cpp
index 096ce14..8723cd4 100644
--- a/Source/WebCore/platform/graphics/qt/TileQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/TileQt.cpp
@@ -91,10 +91,10 @@ void Tile::invalidate(const IntRect& dirtyRect)
*m_dirtyRegion += tileDirtyRect;
}
-void Tile::updateBackBuffer()
+Vector<IntRect> Tile::updateBackBuffer()
{
if (m_buffer && !isDirty())
- return;
+ return Vector<IntRect>();
if (!m_backBuffer) {
if (!m_buffer) {
@@ -115,15 +115,19 @@ void Tile::updateBackBuffer()
GraphicsContext context(&painter);
context.translate(-m_rect.x(), -m_rect.y());
+ Vector<IntRect> updatedRects;
int size = dirtyRects.size();
for (int n = 0; n < size; ++n) {
context.save();
IntRect rect = dirtyRects[n];
+ updatedRects.append(rect);
context.clip(FloatRect(rect));
context.scale(FloatSize(m_backingStore->m_contentsScale, m_backingStore->m_contentsScale));
m_backingStore->m_client->tiledBackingStorePaint(&context, m_backingStore->mapToContents(rect));
context.restore();
}
+
+ return updatedRects;
}
void Tile::swapBackBufferToFront()
diff --git a/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
index 0e68c21..cc695a5 100644
--- a/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
@@ -65,7 +65,8 @@ FontCustomPlatformData::~FontCustomPlatformData()
#endif
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant, FontRenderingMode mode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation,
+ TextOrientation textOrientation, FontWidthVariant, FontRenderingMode mode)
{
#if OS(WINDOWS)
ASSERT(m_fontReference);
@@ -102,7 +103,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
return FontPlatformData(hfont, size);
#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP)
ASSERT(m_fontReference);
- return FontPlatformData(m_fontReference, "", size, bold && !m_fontReference->isBold(), italic && !m_fontReference->isItalic(), orientation);
+ return FontPlatformData(m_fontReference, "", size, bold && !m_fontReference->isBold(), italic && !m_fontReference->isItalic(), orientation, textOrientation);
#else
notImplemented();
return FontPlatformData();
diff --git a/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h
index 2dee3ab..b68722b 100644
--- a/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h
@@ -35,6 +35,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -66,8 +67,8 @@ public:
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth,
- FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight,
+ FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp b/Source/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp
index 66e6839..f362fa3 100644
--- a/Source/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp
@@ -91,7 +91,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
return false;
}
- if ((fontData->orientation() == Vertical) && (!fontData->isBrokenIdeographFont())) {
+ if (fontData->hasVerticalGlyphs()) {
bool lookVariants = false;
for (unsigned i = 0; i < bufferLength; ++i) {
if (!Font::isCJKIdeograph(buffer[i])) {
diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 00afd07..df680eb 100644
--- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -1025,6 +1025,14 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size,
if (paintingDisabled())
return;
+ if (platformContext()->useGPU()) {
+ GLES2Canvas* canvas = platformContext()->gpuCanvas();
+ canvas->setShadowOffset(size);
+ canvas->setShadowBlur(blurFloat);
+ canvas->setShadowColor(color, colorSpace);
+ canvas->setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms);
+ }
+
// Detect when there's no effective shadow and clear the looper.
if (!size.width() && !size.height() && !blurFloat) {
platformContext()->setDrawLooper(0);
@@ -1035,14 +1043,15 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size,
double height = size.height();
double blur = blurFloat;
- SkBlurDrawLooper::BlurFlags blurFlags = SkBlurDrawLooper::kNone_BlurFlag;
+ uint32_t blurFlags = SkBlurDrawLooper::kHighQuality_BlurFlag |
+ SkBlurDrawLooper::kOverrideColor_BlurFlag;
if (m_state.shadowsIgnoreTransforms) {
// Currently only the GraphicsContext associated with the
// CanvasRenderingContext for HTMLCanvasElement have shadows ignore
// Transforms. So with this flag set, we know this state is associated
// with a CanvasRenderingContext.
- blurFlags = SkBlurDrawLooper::kIgnoreTransform_BlurFlag;
+ blurFlags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag;
// CG uses natural orientation for Y axis, but the HTML5 canvas spec
// does not.
diff --git a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 2721523..b89c68d 100644
--- a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -341,6 +341,28 @@ void ImageBuffer::putPremultipliedImageData(ByteArray* source, const IntSize& so
putImageData<Premultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas()->getDevice(), m_size);
}
+template <typename T>
+static String ImageToDataURL(T& source, const String& mimeType, const double* quality)
+{
+ Vector<unsigned char> encodedImage;
+ if (mimeType == "image/jpeg") {
+ int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality;
+ if (quality && *quality >= 0.0 && *quality <= 1.0)
+ compressionQuality = static_cast<int>(*quality * 100 + 0.5);
+ if (!JPEGImageEncoder::encode(source, compressionQuality, &encodedImage))
+ return "data:,";
+ } else {
+ if (!PNGImageEncoder::encode(source, &encodedImage))
+ return "data:,";
+ ASSERT(mimeType == "image/png");
+ }
+
+ Vector<char> base64Data;
+ base64Encode(*reinterpret_cast<Vector<char>*>(&encodedImage), base64Data);
+
+ return makeString("data:", mimeType, ";base64,", base64Data);
+}
+
String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const
{
ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
@@ -358,23 +380,13 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality) con
if (!device->readPixels(bounds, &bitmap))
return "data:,";
}
-
- if (mimeType == "image/jpeg") {
- int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality;
- if (quality && *quality >= 0.0 && *quality <= 1.0)
- compressionQuality = static_cast<int>(*quality * 100 + 0.5);
- if (!JPEGImageEncoder::encode(bitmap, compressionQuality, &encodedImage))
- return "data:,";
- } else {
- if (!PNGImageEncoder::encode(bitmap, &encodedImage))
- return "data:,";
- ASSERT(mimeType == "image/png");
- }
- Vector<char> base64Data;
- base64Encode(*reinterpret_cast<Vector<char>*>(&encodedImage), base64Data);
+ return ImageToDataURL(bitmap, mimeType, quality);
+}
- return makeString("data:", mimeType, ";base64,", base64Data);
+String ImageDataToDataURL(const ImageData& source, const String& mimeType, const double* quality)
+{
+ return ImageToDataURL(source, mimeType, quality);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
index 91a4e4f..72bec29 100644
--- a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -260,6 +260,7 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
paint.setXfermodeMode(compOp);
paint.setFilterBitmap(true);
paint.setAlpha(platformContext->getNormalizedAlpha());
+ paint.setLooper(platformContext->getDrawLooper());
skia::PlatformCanvas* canvas = platformContext->canvas();
diff --git a/Source/WebCore/platform/graphics/skia/PathSkia.cpp b/Source/WebCore/platform/graphics/skia/PathSkia.cpp
index 0344086..b037a0d 100644
--- a/Source/WebCore/platform/graphics/skia/PathSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PathSkia.cpp
@@ -228,7 +228,7 @@ void Path::transform(const AffineTransform& xform)
m_path->transform(xform);
}
-FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
{
GraphicsContext* scratch = scratchContext();
scratch->save();
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index eac5e4a..8e1937f 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -68,18 +68,6 @@
namespace WebCore {
-#if ENABLE(SKIA_GPU)
-GrContext* GetGlobalGrContext()
-{
- static GrContext* gGR;
- if (!gGR) {
- gGR = GrContext::CreateGLShaderContext();
- gGR->setTextureCacheLimits(512, 50 * 1024 * 1024);
- }
- return gGR;
-}
-#endif
-
extern bool isPathSkiaSafe(const SkMatrix& transform, const SkPath& path);
// State -----------------------------------------------------------------------
@@ -241,8 +229,14 @@ PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
PlatformContextSkia::~PlatformContextSkia()
{
#if ENABLE(ACCELERATED_2D_CANVAS)
- if (m_gpuCanvas)
+ if (m_gpuCanvas) {
+#if ENABLE(SKIA_GPU)
+ // make sure everything related to this platform context has been flushed
+ if (!m_useGPU)
+ m_gpuCanvas->context()->grContext()->flush(0);
+#endif
m_gpuCanvas->drawingBuffer()->setWillPublishCallback(0);
+ }
#endif
}
@@ -697,8 +691,7 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
bool PlatformContextSkia::canAccelerate() const
{
- return !m_state->m_fillShader // Can't accelerate with a fill gradient or pattern.
- && !m_state->m_looper; // Can't accelerate with a shadow.
+ return !m_state->m_fillShader; // Can't accelerate with a fill gradient or pattern.
}
bool PlatformContextSkia::canvasClipApplied() const
@@ -741,8 +734,10 @@ void PlatformContextSkia::setSharedGraphicsContext3D(SharedGraphicsContext3D* co
context->makeContextCurrent();
m_gpuCanvas->bindFramebuffer();
- GrContext* gr = GetGlobalGrContext();
+ GrContext* gr = context->grContext();
gr->resetContext();
+ drawingBuffer->setGrContext(gr);
+
SkDeviceFactory* factory = new SkGpuDeviceFactory(gr, SkGpuDevice::Current3DApiRenderTarget());
SkDevice* device = factory->newDevice(m_canvas, SkBitmap::kARGB_8888_Config, drawingBuffer->size().width(), drawingBuffer->size().height(), false, false);
m_canvas->setDevice(device)->unref();
diff --git a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
index 54aa35e..b0cb0c7 100644
--- a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
+++ b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
@@ -380,6 +380,11 @@ bool paintSkiaText(GraphicsContext* context,
paint.reset();
platformContext->setupPaintForStroking(&paint, 0, 0);
paint.setFlags(SkPaint::kAntiAlias_Flag);
+#if ENABLE(SKIA_TEXT)
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ setupPaintForFont(hfont, &paint);
+#endif
+
if (didFill) {
// If there is a shadow and we filled above, there will already be
// a shadow. We don't want to draw it again or it will be too dark
@@ -390,7 +395,7 @@ bool paintSkiaText(GraphicsContext* context,
// thing would be to draw to a new layer and then draw that layer
// with a shadow. But this is a lot of extra work for something
// that isn't normally an issue.
- SkSafeUnref(paint.setLooper(0));
+ paint.setLooper(0);
}
if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint,
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
index 4698239..760ba6c 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
@@ -336,7 +336,7 @@ void GraphicsLayerTextureMapper::setContentsToMedia(PlatformLayer* media)
notifyChange(TextureMapperNode::ContentChange);
m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
if (media)
- m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media);
+ m_pendingContent.media = static_cast<TextureMapperMediaLayer*>(media);
else
m_pendingContent.media = 0;
}
@@ -366,13 +366,6 @@ void GraphicsLayerTextureMapper::syncCompositingState()
}
/* \reimp (GraphicsLayer.h)
- */
-NativeLayer GraphicsLayerTextureMapper::nativeLayer() const
-{
- return m_node.get();
-}
-
-/* \reimp (GraphicsLayer.h)
*/
PlatformLayer* GraphicsLayerTextureMapper::platformLayer() const
{
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
index 47a27c6..dcf4938 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
@@ -81,7 +81,6 @@ public:
virtual void syncCompositingState();
virtual void syncCompositingStateForThisLayerOnly();
virtual void setName(const String& name);
- virtual NativeLayer nativeLayer() const;
virtual PlatformLayer* platformLayer() const;
virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
index 589fda1..8e46e3c 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
@@ -31,6 +31,7 @@
#include "IntRect.h"
#include "IntSize.h"
#include "TransformationMatrix.h"
+#include <wtf/UnusedParam.h>
/*
TextureMapper is a mechanism that enables hardware acceleration of CSS animations (accelerated compositing) without
@@ -68,7 +69,7 @@ public:
return beginPaint(IntRect(0, 0, size().width(), size().height()));
}
virtual void setContentsToImage(Image*) = 0;
- virtual bool save(const String& filename) { return false; }
+ virtual bool save(const String&) { return false; }
inline void lock() { ++m_lockCount; }
inline void unlock() { --m_lockCount; }
@@ -101,6 +102,7 @@ public:
virtual void bindSurface(BitmapTexture* surface) = 0;
virtual void paintToTarget(const BitmapTexture& texture, const IntSize&, const TransformationMatrix& matrix, float opacity, const IntRect& visibleRect)
{
+ UNUSED_PARAM(visibleRect);
drawTexture(texture, IntRect(0, 0, texture.contentSize().width(), texture.contentSize().height()), matrix, opacity, 0);
}
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h
index 9694043..c5decc1 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h
@@ -20,19 +20,19 @@
#ifndef TextureMapperNode_h
#define TextureMapperNode_h
-#include "CurrentTime.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "GraphicsLayer.h"
-#include "HashMap.h"
#include "Image.h"
-#include "RefCounted.h"
#include "TextureMapper.h"
#include "TextureMapperPlatformLayer.h"
#include "Timer.h"
#include "TransformOperations.h"
#include "TranslateTransformOperation.h"
#include "UnitBezier.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
@@ -94,7 +94,7 @@ public:
ContentType contentType;
RefPtr<Image> image;
- TextureMapperVideoLayer* media;
+ TextureMapperMediaLayer* media;
ContentData()
: needsDisplay(false)
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
index 2a38b90..d2d646a 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
@@ -43,7 +43,7 @@ class TextureMapperPlatformLayer {
public:
enum Type {
ContentLayer,
- VideoLayer
+ MediaLayer
};
virtual Type layerType() const = 0;
@@ -66,13 +66,11 @@ public:
virtual Type layerType() const { return ContentLayer; }
};
-#if ENABLE(VIDEO)
-class TextureMapperVideoLayer : public TextureMapperPlatformLayer {
+class TextureMapperMediaLayer : public TextureMapperPlatformLayer {
public:
virtual void paint(GraphicsContext*) = 0;
- virtual Type layerType() const { return VideoLayer; }
+ virtual Type layerType() const { return MediaLayer; }
};
-#endif
}
diff --git a/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp
index a8ad131..b1ea99b 100644
--- a/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp
+++ b/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "TranslateTransformOperation.h"
+#include "FloatConversion.h"
namespace WebCore {
@@ -30,15 +31,15 @@ PassRefPtr<TransformOperation> TranslateTransformOperation::blend(const Transfor
return this;
if (blendToIdentity)
- return TranslateTransformOperation::create(Length(m_x.type()).blend(m_x, progress),
- Length(m_y.type()).blend(m_y, progress),
- Length(m_z.type()).blend(m_z, progress), m_type);
+ return TranslateTransformOperation::create(Length(m_x.type()).blend(m_x, narrowPrecisionToFloat(progress)),
+ Length(m_y.type()).blend(m_y, narrowPrecisionToFloat(progress)),
+ Length(m_z.type()).blend(m_z, narrowPrecisionToFloat(progress)), m_type);
const TranslateTransformOperation* fromOp = static_cast<const TranslateTransformOperation*>(from);
Length fromX = fromOp ? fromOp->m_x : Length(m_x.type());
Length fromY = fromOp ? fromOp->m_y : Length(m_y.type());
Length fromZ = fromOp ? fromOp->m_z : Length(m_z.type());
- return TranslateTransformOperation::create(m_x.blend(fromX, progress), m_y.blend(fromY, progress), m_z.blend(fromZ, progress), m_type);
+ return TranslateTransformOperation::create(m_x.blend(fromX, narrowPrecisionToFloat(progress)), m_y.blend(fromY, narrowPrecisionToFloat(progress)), m_z.blend(fromZ, narrowPrecisionToFloat(progress)), m_type);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
index e800245..5382ef7 100644
--- a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
@@ -584,7 +584,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
#if PLATFORM(CG)
bool fontCreationFailed = !result->cgFont();
#elif PLATFORM(CAIRO)
- bool fontCreationFailed = !result->fontFace();
+ bool fontCreationFailed = !result->scaledFont();
#endif
if (fontCreationFailed) {
diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
index 4aee6cd..8348acb 100644
--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
@@ -59,7 +59,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
}
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode renderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode renderingMode)
{
ASSERT(m_fontReference);
ASSERT(T2embedLibrary());
diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h
index abdb356..65388d8 100644
--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h
@@ -25,6 +25,7 @@
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
#include "PlatformString.h"
+#include "TextOrientation.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -46,7 +47,8 @@ public:
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight,
+ FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
index fd30a6d..6f9bbf0 100644
--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
@@ -23,8 +23,11 @@
#include "SharedBuffer.h"
#include "FontPlatformData.h"
+
+#include <cairo-win32.h>
#include <wtf/RetainPtr.h>
+
namespace WebCore {
FontCustomPlatformData::~FontCustomPlatformData()
@@ -32,7 +35,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
cairo_font_face_destroy(m_fontFace);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant)
{
return FontPlatformData(m_fontFace, size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
index ea3ae38..bd90f18 100644
--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
@@ -42,7 +42,7 @@ public:
}
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp b/Source/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
index 9234229..287121b 100644
--- a/Source/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
@@ -115,11 +115,15 @@ void FontPlatformData::platformDataInit(HFONT font, float size, HDC hdc, WCHAR*
}
FontPlatformData::FontPlatformData(HFONT hfont, CGFontRef font, float size, bool bold, bool oblique, bool useGDI)
- : m_font(RefCountedGDIHandle<HFONT>::create(hfont))
+ : m_syntheticBold(bold)
+ , m_syntheticOblique(oblique)
+ , m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
, m_size(size)
+ , m_widthVariant(RegularWidth)
+ , m_font(RefCountedGDIHandle<HFONT>::create(hfont))
, m_cgFont(font)
- , m_syntheticBold(bold)
- , m_syntheticOblique(oblique)
+ , m_isColorBitmapFont(false)
, m_useGDI(useGDI)
{
}
@@ -128,4 +132,27 @@ FontPlatformData::~FontPlatformData()
{
}
+void FontPlatformData::platformDataInit(const FontPlatformData& source)
+{
+ m_font = source.m_font;
+ m_cgFont = source.m_cgFont;
+ m_useGDI = source.m_useGDI;
+}
+
+const FontPlatformData& FontPlatformData::platformDataAssign(const FontPlatformData& other)
+{
+ m_font = other.m_font;
+ m_cgFont = other.m_cgFont;
+ m_useGDI = other.m_useGDI;
+
+ return *this;
+}
+
+bool FontPlatformData::platformIsEqual(const FontPlatformData& other) const
+{
+ return m_font == other.m_font
+ && m_cgFont == other.m_cgFont
+ && m_useGDI == other.m_useGDI;
+}
+
}
diff --git a/Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp b/Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp
index 0f5c365..e60b69b 100644
--- a/Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp
@@ -4,7 +4,7 @@
*
* Copyright (C) 2006, 2007, 2008 Apple Inc.
* Copyright (C) 2007 Alp Toker
- * Copyright (C) 2008, 2010 Brent Fulgham
+ * Copyright (C) 2008, 2010, 2011 Brent Fulgham
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -40,7 +40,7 @@ namespace WebCore {
void FontPlatformData::platformDataInit(HFONT font, float size, HDC hdc, WCHAR* faceName)
{
- m_fontFace = cairo_win32_font_face_create_for_hfont(font);
+ cairo_font_face_t* fontFace = cairo_win32_font_face_create_for_hfont(font);
cairo_matrix_t sizeMatrix, ctm;
cairo_matrix_init_identity(&ctm);
@@ -52,14 +52,18 @@ void FontPlatformData::platformDataInit(HFONT font, float size, HDC hdc, WCHAR*
cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_SUBPIXEL);
}
- m_scaledFont = cairo_scaled_font_create(m_fontFace, &sizeMatrix, &ctm, fontOptions);
+ m_scaledFont = cairo_scaled_font_create(fontFace, &sizeMatrix, &ctm, fontOptions);
+ cairo_font_face_destroy(fontFace);
}
FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, float size, bool bold, bool oblique)
: m_font(0)
, m_size(size)
- , m_fontFace(fontFace)
+ , m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
+ , m_widthVariant(RegularWidth)
, m_scaledFont(0)
+ , m_isColorBitmapFont(false)
, m_syntheticBold(bold)
, m_syntheticOblique(oblique)
, m_useGDI(false)
@@ -79,64 +83,39 @@ FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, float size, bool
cairo_font_options_destroy(options);
}
-FontPlatformData::FontPlatformData(const FontPlatformData& source)
- : m_font(source.m_font)
- , m_size(source.m_size)
- , m_fontFace(0)
- , m_scaledFont(0)
- , m_syntheticBold(source.m_syntheticBold)
- , m_syntheticOblique(source.m_syntheticOblique)
- , m_useGDI(source.m_useGDI)
+FontPlatformData::~FontPlatformData()
{
- if (source.m_fontFace)
- m_fontFace = cairo_font_face_reference(source.m_fontFace);
-
- if (source.m_scaledFont)
- m_scaledFont = cairo_scaled_font_reference(source.m_scaledFont);
+ if (m_scaledFont && m_scaledFont != hashTableDeletedFontValue())
+ cairo_scaled_font_destroy(m_scaledFont);
}
-
-FontPlatformData::~FontPlatformData()
+void FontPlatformData::platformDataInit(const FontPlatformData& source)
{
- cairo_scaled_font_destroy(m_scaledFont);
- cairo_font_face_destroy(m_fontFace);
+ m_font = source.m_font;
+ m_useGDI = source.m_useGDI;
+ m_scaledFont = 0;
+
+ if (source.m_scaledFont)
+ m_scaledFont = cairo_scaled_font_reference(source.m_scaledFont);
}
-FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
+const FontPlatformData& FontPlatformData::platformDataAssign(const FontPlatformData& other)
{
- // Check for self-assignment.
- if (this == &other)
- return *this;
-
m_font = other.m_font;
- m_size = other.m_size;
- m_syntheticBold = other.m_syntheticBold;
- m_syntheticOblique = other.m_syntheticOblique;
m_useGDI = other.m_useGDI;
- if (other.m_fontFace)
- cairo_font_face_reference(other.m_fontFace);
- if (m_fontFace)
- cairo_font_face_destroy(m_fontFace);
- m_fontFace = other.m_fontFace;
-
- if (other.m_scaledFont)
- cairo_scaled_font_reference(other.m_scaledFont);
- if (m_scaledFont)
+ if (m_scaledFont && m_scaledFont != hashTableDeletedFontValue())
cairo_scaled_font_destroy(m_scaledFont);
- m_scaledFont = other.m_scaledFont;
+
+ m_scaledFont = cairo_scaled_font_reference(other.m_scaledFont);
return *this;
}
-bool FontPlatformData::operator==(const FontPlatformData& other) const
-{
+bool FontPlatformData::platformIsEqual(const FontPlatformData& other) const
+{
return m_font == other.m_font
- && m_fontFace == other.m_fontFace
&& m_scaledFont == other.m_scaledFont
- && m_size == other.m_size
- && m_syntheticBold == other.m_syntheticBold
- && m_syntheticOblique == other.m_syntheticOblique
&& m_useGDI == other.m_useGDI;
}
diff --git a/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp b/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
index 09ed4a6..301198d 100644
--- a/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
@@ -38,12 +38,15 @@ namespace WebCore {
FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool oblique, bool useGDI)
: m_font(RefCountedGDIHandle<HFONT>::create(font))
, m_size(size)
+ , m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
+ , m_widthVariant(RegularWidth)
#if PLATFORM(CG)
, m_cgFont(0)
#elif PLATFORM(CAIRO)
- , m_fontFace(0)
, m_scaledFont(0)
#endif
+ , m_isColorBitmapFont(false)
, m_syntheticBold(bold)
, m_syntheticOblique(oblique)
, m_useGDI(useGDI)
@@ -71,20 +74,6 @@ FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool obliq
ReleaseDC(0, hdc);
}
-FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
- : m_size(size)
-#if PLATFORM(CG)
- , m_cgFont(0)
-#elif PLATFORM(CAIRO)
- , m_fontFace(0)
- , m_scaledFont(0)
-#endif
- , m_syntheticBold(bold)
- , m_syntheticOblique(oblique)
- , m_useGDI(false)
-{
-}
-
#ifndef NDEBUG
String FontPlatformData::description() const
{
diff --git a/Source/WebCore/platform/graphics/win/FontWin.cpp b/Source/WebCore/platform/graphics/win/FontWin.cpp
index 47c44bc..9e31f56 100644
--- a/Source/WebCore/platform/graphics/win/FontWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontWin.cpp
@@ -127,8 +127,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
UniscribeController controller(this, run, fallbackFonts);
controller.advance(run.length());
if (glyphOverflow) {
- glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - fontMetrics().ascent());
- glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - fontMetrics().descent());
+ glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
+ glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().descent()));
glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.runWidthSoFar()));
}
diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
index b2c702f..7ce7ee9 100644
--- a/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
+++ b/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
@@ -72,18 +72,15 @@ GraphicsContext::GraphicsContext(HDC dc, bool hasAlpha)
void GraphicsContext::platformInit(HDC dc, bool hasAlpha)
{
- m_data = new GraphicsContextPlatformPrivate;
-
- if (dc) {
- m_data->cr = createCairoContextWithHDC(dc, hasAlpha);
- m_data->m_hdc = dc;
- } else {
+ cairo_t* cr = 0;
+ if (dc)
+ cr = createCairoContextWithHDC(dc, hasAlpha);
+ else
setPaintingDisabled(true);
- m_data->cr = 0;
- m_data->m_hdc = 0;
- }
- if (m_data->cr) {
+ m_data = new GraphicsContextPlatformPrivateTopLevel(new PlatformContextCairo(cr));
+ m_data->m_hdc = dc;
+ if (platformContext()->cr()) {
// Make sure the context starts in sync with our state.
setPlatformFillColor(fillColor(), fillColorSpace());
setPlatformStrokeColor(strokeColor(), strokeColorSpace());
@@ -131,24 +128,25 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo
// Scale the target surface to the new image size, and flip it
// so that when we set the srcImage as the surface it will draw
// right-side-up.
- cairo_save(m_data->cr);
- cairo_translate(m_data->cr, dstRect.x(), dstRect.height() + dstRect.y());
- cairo_scale(m_data->cr, 1.0, -1.0);
- cairo_set_source_surface(m_data->cr, image, 0, 0);
+ cairo_t* cr = platformContext()->cr();
+ cairo_save(cr);
+ cairo_translate(cr, dstRect.x(), dstRect.height() + dstRect.y());
+ cairo_scale(cr, 1, -1);
+ cairo_set_source_surface(cr, image, 0, 0);
if (m_data->layers.size())
- cairo_paint_with_alpha(m_data->cr, m_data->layers.last());
+ cairo_paint_with_alpha(cr, m_data->layers.last());
else
- cairo_paint(m_data->cr);
+ cairo_paint(cr);
// Delete all our junk.
cairo_surface_destroy(image);
::DeleteDC(hdc);
::DeleteObject(bitmap);
- cairo_restore(m_data->cr);
+ cairo_restore(cr);
}
-void GraphicsContextPlatformPrivate::syncContext(PlatformGraphicsContext* cr)
+void GraphicsContextPlatformPrivate::syncContext(cairo_t* cr)
{
if (!cr)
return;
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
index 40fe1d1..bac85f7 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
@@ -28,8 +28,11 @@
#if ENABLE(VIDEO)
#include "MediaPlayerPrivateQuickTimeVisualContext.h"
+#include "ApplicationCacheHost.h"
+#include "ApplicationCacheResource.h"
#include "Cookie.h"
#include "CookieJar.h"
+#include "DocumentLoader.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
@@ -369,7 +372,16 @@ void MediaPlayerPrivateQuickTimeVisualContext::loadInternal(const String& url)
setUpCookiesForQuickTime(url);
m_movie = adoptRef(new QTMovie(m_movieClient.get()));
- m_movie->load(url.characters(), url.length(), m_player->preservesPitch());
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : 0;
+ ApplicationCacheHost* cacheHost = frame ? frame->loader()->documentLoader()->applicationCacheHost() : 0;
+ ApplicationCacheResource* resource = 0;
+ if (cacheHost && cacheHost->shouldLoadResourceFromApplicationCache(ResourceRequest(url), resource) && resource && !resource->path().isEmpty())
+ m_movie->load(resource->path().characters(), resource->path().length(), m_player->preservesPitch());
+ else
+#endif
+ m_movie->load(url.characters(), url.length(), m_player->preservesPitch());
m_movie->setVolume(m_player->volume());
}
diff --git a/Source/WebCore/platform/graphics/win/QTMovie.cpp b/Source/WebCore/platform/graphics/win/QTMovie.cpp
index 05fbb86..6f9c668 100644
--- a/Source/WebCore/platform/graphics/win/QTMovie.cpp
+++ b/Source/WebCore/platform/graphics/win/QTMovie.cpp
@@ -442,6 +442,17 @@ void QTMovie::getNaturalSize(int& width, int& height)
height = (rect.bottom - rect.top) * m_private->m_heightScaleFactor;
}
+void QTMovie::loadPath(const UChar* url, int len, bool preservesPitch)
+{
+ CFStringRef urlStringRef = CFStringCreateWithCharacters(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(url), len);
+ CFURLRef cfURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlStringRef, kCFURLWindowsPathStyle, false);
+
+ load(cfURL, preservesPitch);
+
+ CFRelease(cfURL);
+ CFRelease(urlStringRef);
+}
+
void QTMovie::load(const UChar* url, int len, bool preservesPitch)
{
CFStringRef urlStringRef = CFStringCreateWithCharacters(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(url), len);
diff --git a/Source/WebCore/platform/graphics/win/QTMovie.h b/Source/WebCore/platform/graphics/win/QTMovie.h
index e97d16d..38b3473 100644
--- a/Source/WebCore/platform/graphics/win/QTMovie.h
+++ b/Source/WebCore/platform/graphics/win/QTMovie.h
@@ -70,6 +70,7 @@ public:
void addClient(QTMovieClient*);
void removeClient(QTMovieClient*);
+ void loadPath(const UChar* url, int len, bool preservesPitch);
void load(const UChar* url, int len, bool preservesPitch);
void load(CFURLRef, bool preservesPitch);
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
index 30a931e..12f1127 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
@@ -97,18 +97,14 @@ void SimpleFontData::platformInit()
m_fontMetrics.setLineGap(fLineGap);
m_fontMetrics.setLineSpacing(lroundf(fAscent) + lroundf(fDescent) + lroundf(fLineGap));
- // Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
- // Unfortunately, NSFont will round this for us so we don't quite get the right value.
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
Glyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
if (xGlyph) {
+ // Measure the actual character "x", since it's possible for it to extend below the baseline, and we need the
+ // reported x-height to only include the portion of the glyph that is above the baseline.
CGRect xBox;
CGFontGetGlyphBBoxes(font, &xGlyph, 1, &xBox);
- // Use the maximum of either width or height because "x" is nearly square
- // and web pages that foolishly use this metric for width will be laid out
- // poorly if we return an accurate height. Classic case is Times 13 point,
- // which has an "x" that is 7x6 pixels.
- m_fontMetrics.setXHeight(scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), unitsPerEm) * pointSize);
+ m_fontMetrics.setXHeight(scaleEmToUnits(CGRectGetMaxY(xBox), unitsPerEm) * pointSize);
} else {
int iXHeight = CGFontGetXHeight(font);
m_fontMetrics.setXHeight(scaleEmToUnits(iXHeight, unitsPerEm) * pointSize);
diff --git a/Source/WebCore/platform/graphics/win/cairo/FontPlatformData.h b/Source/WebCore/platform/graphics/win/cairo/FontPlatformData.h
deleted file mode 100644
index d8f538a..0000000
--- a/Source/WebCore/platform/graphics/win/cairo/FontPlatformData.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc.
- * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
- * Copyright (C) 2007 Holger Hans Peter Freyther
- * Copyright (C) 2007 Pioneer Research Center USA, Inc.
- * Copyright (C) 2010 Brent Fulgham <bfulgham@webkit.org>
- * All rights reserved.
- *
- * 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.
- *
- */
-
-#ifndef FontPlatformDataCairoWin_h
-#define FontPlatformDataCairoWin_h
-
-#include "FontOrientation.h"
-#include "GlyphBuffer.h"
-#include "RefCountedGDIHandle.h"
-#include "StringImpl.h"
-#include <cairo-win32.h>
-#include <cairo.h>
-#include <wtf/Forward.h>
-
-typedef struct HFONT__* HFONT;
-
-namespace WebCore {
-
-class FontDescription;
-
-class FontPlatformData {
-public:
- FontPlatformData(WTF::HashTableDeletedValueType)
- : m_fontFace(0)
- , m_useGDI(false)
- , m_font(WTF::HashTableDeletedValue)
- , m_size(0)
- , m_syntheticBold(false)
- , m_syntheticOblique(false)
- , m_scaledFont(0)
- { }
-
- FontPlatformData()
- : m_fontFace(0)
- , m_useGDI(false)
- , m_size(0)
- , m_syntheticBold(false)
- , m_syntheticOblique(false)
- , m_scaledFont(0)
- { }
-
- FontPlatformData(HFONT, float size, bool bold, bool oblique, bool useGDI);
- FontPlatformData(cairo_font_face_t* fontFace, float size, bool bold, bool italic);
- FontPlatformData(float size, bool bold, bool italic);
- FontPlatformData(const FontPlatformData&);
- ~FontPlatformData();
-
- HFONT hfont() const { return m_font->handle(); }
- bool useGDI() const { return m_useGDI; }
- cairo_font_face_t* fontFace() const { return m_fontFace; }
-
- bool isFixedPitch();
- float size() const { return m_size; }
- void setSize(float size) { m_size = size; }
- bool syntheticBold() const { return m_syntheticBold; }
- bool syntheticOblique() const { return m_syntheticOblique; }
-
- FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
-
- cairo_scaled_font_t* scaledFont() const { return m_scaledFont; }
-
- unsigned hash() const
- {
- return m_font->hash();
- }
-
- bool operator==(const FontPlatformData&) const;
- FontPlatformData& operator=(const FontPlatformData&);
- bool isHashTableDeletedValue() const
- {
- return m_font.isHashTableDeletedValue();
- }
-
-#ifndef NDEBUG
- String description() const;
-#endif
-
-private:
- void platformDataInit(HFONT, float size, HDC, WCHAR* faceName);
-
- RefPtr<RefCountedGDIHandle<HFONT> > m_font;
- cairo_font_face_t* m_fontFace;
- bool m_useGDI;
- float m_size;
- bool m_syntheticBold;
- bool m_syntheticOblique;
- cairo_scaled_font_t* m_scaledFont;
-};
-
-}
-
-#endif // FontPlatformDataCairoWin_h
diff --git a/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
index fb97fe1..07a8756 100644
--- a/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
@@ -45,7 +45,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
g_customFontCache->unregisterFont(m_name);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode renderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode renderingMode)
{
FontDescription fontDesc;
fontDesc.setComputedSize(size);
diff --git a/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h
index fe7ee94..12a86e9 100644
--- a/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h
@@ -24,6 +24,7 @@
#include "FontDescription.h"
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include "PlatformString.h"
#include <wtf/Noncopyable.h>
@@ -48,7 +49,7 @@ namespace WebCore {
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/wince/FontPlatformData.cpp b/Source/WebCore/platform/graphics/wince/FontPlatformData.cpp
index d9d8a72..d767ac7 100644
--- a/Source/WebCore/platform/graphics/wince/FontPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/wince/FontPlatformData.cpp
@@ -148,7 +148,7 @@ struct FixedSizeFontDataKeyHash {
font.m_weight,
// static_cast<unsigned>(font.m_italic);
};
- return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
+ return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
}
static bool equal(const FixedSizeFontDataKey& a, const FixedSizeFontDataKey& b)
diff --git a/Source/WebCore/platform/graphics/wince/FontPlatformData.h b/Source/WebCore/platform/graphics/wince/FontPlatformData.h
index e73a7b2..9c3f733 100644
--- a/Source/WebCore/platform/graphics/wince/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/wince/FontPlatformData.h
@@ -79,6 +79,7 @@ namespace WebCore {
static LONG adjustedGDIFontWeight(LONG gdiFontWeight, const String& family);
FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
+ void setOrientation(FontOrientation) { } // FIXME: Implement.
#ifndef NDEBUG
String description() const;
diff --git a/Source/WebCore/platform/graphics/wince/PathWinCE.cpp b/Source/WebCore/platform/graphics/wince/PathWinCE.cpp
index fa4c8fb..9c9112b 100644
--- a/Source/WebCore/platform/graphics/wince/PathWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/PathWinCE.cpp
@@ -133,7 +133,7 @@ void Path::transform(const AffineTransform& t)
m_path->transform(t);
}
-FloatRect Path::strokeBoundingRect(StrokeStyleApplier *)
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier*) const
{
notImplemented();
return FloatRect();
diff --git a/Source/WebCore/platform/graphics/wx/FontPlatformData.h b/Source/WebCore/platform/graphics/wx/FontPlatformData.h
index 3ef0179..8a2c4a0 100644
--- a/Source/WebCore/platform/graphics/wx/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/wx/FontPlatformData.h
@@ -150,6 +150,7 @@ public:
bool allowsLigatures() const { return false; }
FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
+ void setOrientation(FontOrientation) { } // FIXME: Implement.
// We don't support this yet, so just return the default value for now.
FontWidthVariant widthVariant() const { return RegularWidth; }
diff --git a/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp b/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
index c125b7c..830cd05 100644
--- a/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
@@ -126,10 +126,10 @@ unsigned FontPlatformData::computeHash() const
thisFont->GetStyle(),
thisFont->GetWeight(),
thisFont->GetUnderlined(),
- WTF::StringHasher::createHash(thisFont->GetFaceName().utf8_str().data())
+ StringHasher::computeHash(thisFont->GetFaceName().utf8_str().data())
};
- return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
+ return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
}
FontPlatformData::~FontPlatformData()
diff --git a/Source/WebCore/platform/graphics/wx/PathWx.cpp b/Source/WebCore/platform/graphics/wx/PathWx.cpp
index f5355f2..a95cc1c 100644
--- a/Source/WebCore/platform/graphics/wx/PathWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/PathWx.cpp
@@ -105,7 +105,7 @@ FloatRect Path::boundingRect() const
return FloatRect();
}
-FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
{
notImplemented();
return FloatRect();