summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics')
-rw-r--r--WebCore/platform/graphics/FloatPoint3D.cpp22
-rw-r--r--WebCore/platform/graphics/FloatPoint3D.h41
-rw-r--r--WebCore/platform/graphics/Font.cpp36
-rw-r--r--WebCore/platform/graphics/Font.h36
-rw-r--r--WebCore/platform/graphics/FontCache.cpp6
-rw-r--r--WebCore/platform/graphics/FontFallbackList.h10
-rw-r--r--WebCore/platform/graphics/GlyphPageTreeNode.h8
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h12
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.cpp24
-rw-r--r--WebCore/platform/graphics/ImageBuffer.cpp5
-rw-r--r--WebCore/platform/graphics/ImageSource.h5
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp16
-rw-r--r--WebCore/platform/graphics/MediaPlayer.h21
-rw-r--r--WebCore/platform/graphics/SimpleFontData.h15
-rw-r--r--WebCore/platform/graphics/TiledBackingStore.cpp36
-rw-r--r--WebCore/platform/graphics/TiledBackingStore.h4
-rw-r--r--WebCore/platform/graphics/TiledBackingStoreClient.h1
-rw-r--r--WebCore/platform/graphics/cairo/FontCairo.cpp8
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp12
-rw-r--r--WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp35
-rw-r--r--WebCore/platform/graphics/chromium/GraphicsLayerChromium.h2
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.cpp65
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.h14
-rw-r--r--WebCore/platform/graphics/filters/FEBlend.cpp36
-rw-r--r--WebCore/platform/graphics/filters/FEBlend.h1
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.cpp45
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.h1
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.cpp54
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.h1
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.cpp42
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.h93
-rw-r--r--WebCore/platform/graphics/filters/FEGaussianBlur.cpp10
-rw-r--r--WebCore/platform/graphics/filters/FEGaussianBlur.h33
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.cpp4
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.h3
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.cpp7
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.h1
-rw-r--r--WebCore/platform/graphics/filters/SourceGraphic.cpp7
-rw-r--r--WebCore/platform/graphics/filters/SourceGraphic.h1
-rw-r--r--WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp2
-rw-r--r--WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h1
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.cpp2
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp12
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm6
-rw-r--r--WebCore/platform/graphics/openvg/ImageOpenVG.cpp199
-rw-r--r--WebCore/platform/graphics/openvg/PainterOpenVG.cpp86
-rw-r--r--WebCore/platform/graphics/openvg/PainterOpenVG.h4
-rw-r--r--WebCore/platform/graphics/openvg/TiledImageOpenVG.cpp177
-rw-r--r--WebCore/platform/graphics/openvg/TiledImageOpenVG.h69
-rw-r--r--WebCore/platform/graphics/openvg/VGUtils.cpp112
-rw-r--r--WebCore/platform/graphics/openvg/VGUtils.h25
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp12
-rw-r--r--WebCore/platform/graphics/qt/GraphicsLayerQt.cpp14
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp17
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp968
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h189
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp96
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h20
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateTaskTimer.cpp65
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateTaskTimer.h48
-rw-r--r--WebCore/platform/graphics/win/QTCFDictionary.cpp60
-rw-r--r--WebCore/platform/graphics/win/QTCFDictionary.h44
-rw-r--r--WebCore/platform/graphics/win/QTMovie.cpp (renamed from WebCore/platform/graphics/win/QTMovieWin.cpp)515
-rw-r--r--WebCore/platform/graphics/win/QTMovie.h (renamed from WebCore/platform/graphics/win/QTMovieWin.h)58
-rw-r--r--WebCore/platform/graphics/win/QTMovieGWorld.cpp465
-rw-r--r--WebCore/platform/graphics/win/QTMovieGWorld.h84
-rw-r--r--WebCore/platform/graphics/win/QTMovieTask.cpp105
-rw-r--r--WebCore/platform/graphics/win/QTMovieTask.h69
-rw-r--r--WebCore/platform/graphics/win/QTMovieVisualContext.cpp253
-rw-r--r--WebCore/platform/graphics/win/QTMovieVisualContext.h78
-rw-r--r--WebCore/platform/graphics/win/QTPixelBuffer.cpp220
-rw-r--r--WebCore/platform/graphics/win/QTPixelBuffer.h97
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp53
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayerRenderer.h8
-rw-r--r--WebCore/platform/graphics/wx/FontPlatformData.h3
-rw-r--r--WebCore/platform/graphics/wx/FontPlatformDataWx.cpp6
-rw-r--r--WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm113
77 files changed, 4341 insertions, 787 deletions
diff --git a/WebCore/platform/graphics/FloatPoint3D.cpp b/WebCore/platform/graphics/FloatPoint3D.cpp
index 8c21ef3..3d37eea 100644
--- a/WebCore/platform/graphics/FloatPoint3D.cpp
+++ b/WebCore/platform/graphics/FloatPoint3D.cpp
@@ -22,32 +22,10 @@
#include "config.h"
#include <math.h>
-#include "FloatPoint.h"
#include "FloatPoint3D.h"
namespace WebCore {
-FloatPoint3D::FloatPoint3D()
- : m_x(0)
- , m_y(0)
- , m_z(0)
-{
-}
-
-FloatPoint3D::FloatPoint3D(float x, float y, float z)
- : m_x(x)
- , m_y(y)
- , m_z(z)
-{
-}
-
-FloatPoint3D::FloatPoint3D(const FloatPoint& p)
- : m_x(p.x())
- , m_y(p.y())
- , m_z(0)
-{
-}
-
void FloatPoint3D::normalize()
{
float length = sqrtf(m_x * m_x + m_y * m_y + m_z * m_z);
diff --git a/WebCore/platform/graphics/FloatPoint3D.h b/WebCore/platform/graphics/FloatPoint3D.h
index 73c3a37..d10e3c1 100644
--- a/WebCore/platform/graphics/FloatPoint3D.h
+++ b/WebCore/platform/graphics/FloatPoint3D.h
@@ -2,6 +2,7 @@
Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <wildfox@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
+ 2010 Zoltan Herczeg <zherczeg@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -22,15 +23,39 @@
#ifndef FloatPoint3D_h
#define FloatPoint3D_h
-namespace WebCore {
+#include "FloatPoint.h"
-class FloatPoint;
+namespace WebCore {
class FloatPoint3D {
public:
- FloatPoint3D();
- FloatPoint3D(float x, float y, float z);
- FloatPoint3D(const FloatPoint&);
+ FloatPoint3D()
+ : m_x(0)
+ , m_y(0)
+ , m_z(0)
+ {
+ }
+
+ FloatPoint3D(float x, float y, float z)
+ : m_x(x)
+ , m_y(y)
+ , m_z(z)
+ {
+ }
+
+ FloatPoint3D(const FloatPoint& p)
+ : m_x(p.x())
+ , m_y(p.y())
+ , m_z(0)
+ {
+ }
+
+ FloatPoint3D(const FloatPoint3D& p)
+ : m_x(p.x())
+ , m_y(p.y())
+ , m_z(p.z())
+ {
+ }
float x() const { return m_x; }
void setX(float x) { m_x = x; }
@@ -59,6 +84,12 @@ inline bool operator!=(const FloatPoint3D& a, const FloatPoint3D& b)
return a.x() != b.x() || a.y() != b.y() || a.z() != b.z();
}
+inline float operator*(const FloatPoint3D& a, const FloatPoint3D& b)
+{
+ // dot product
+ return a.x() * b.x() + a.y() * b.y() + a.z() * b.z();
+}
+
} // namespace WebCore
#endif // FloatPoint3D_h
diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp
index 21380be..2f7c216 100644
--- a/WebCore/platform/graphics/Font.cpp
+++ b/WebCore/platform/graphics/Font.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 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
@@ -26,7 +26,6 @@
#include "FloatRect.h"
#include "FontCache.h"
-#include "FontFallbackList.h"
#include "IntPoint.h"
#include "GlyphBuffer.h"
#include "WidthIterator.h"
@@ -101,10 +100,6 @@ Font& Font::operator=(const Font& other)
return *this;
}
-Font::~Font()
-{
-}
-
bool Font::operator==(const Font& other) const
{
// Our FontData don't have to be checked, since checking the font description will be fine.
@@ -123,24 +118,6 @@ bool Font::operator==(const Font& other) const
&& (m_fontList ? m_fontList->generation() : 0) == (other.m_fontList ? other.m_fontList->generation() : 0);
}
-const SimpleFontData* Font::primaryFont() const
-{
- ASSERT(m_fontList);
- return m_fontList->primarySimpleFontData(this);
-}
-
-const FontData* Font::fontDataAt(unsigned index) const
-{
- ASSERT(m_fontList);
- return m_fontList->fontDataAt(this, index);
-}
-
-const FontData* Font::fontDataForCharacters(const UChar* characters, int length) const
-{
- ASSERT(m_fontList);
- return m_fontList->fontDataForCharacters(this, characters, length);
-}
-
void Font::update(PassRefPtr<FontSelector> fontSelector) const
{
// FIXME: It is pretty crazy that we are willing to just poke into a RefPtr, but it ends up
@@ -153,12 +130,6 @@ void Font::update(PassRefPtr<FontSelector> fontSelector) const
m_fontList->invalidate(fontSelector);
}
-bool Font::isFixedPitch() const
-{
- ASSERT(m_fontList);
- return m_fontList->isFixedPitch(this);
-}
-
void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
// Don't draw anything while we are using custom fonts that are in the process of loading.
@@ -261,11 +232,6 @@ bool Font::isSVGFont() const
}
#endif
-FontSelector* Font::fontSelector() const
-{
- return m_fontList ? m_fontList->fontSelector() : 0;
-}
-
String Font::normalizeSpaces(const String& string)
{
const UChar* characters = string.characters();
diff --git a/WebCore/platform/graphics/Font.h b/WebCore/platform/graphics/Font.h
index da546f0..ef305c5 100644
--- a/WebCore/platform/graphics/Font.h
+++ b/WebCore/platform/graphics/Font.h
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* (C) 2000 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2006, 2007 Apple Computer, Inc.
+ * Copyright (C) 2003, 2006, 2007, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Holger Hans Peter Freyther
*
* This library is free software; you can redistribute it and/or
@@ -27,6 +27,7 @@
#include "CharacterNames.h"
#include "FontDescription.h"
+#include "FontFallbackList.h"
#include "SimpleFontData.h"
#include "TextRun.h"
#include "TypesettingFeatures.h"
@@ -226,6 +227,39 @@ private:
bool m_isPlatformFont;
};
+inline Font::~Font()
+{
+}
+
+inline const SimpleFontData* Font::primaryFont() const
+{
+ ASSERT(m_fontList);
+ return m_fontList->primarySimpleFontData(this);
+}
+
+inline const FontData* Font::fontDataAt(unsigned index) const
+{
+ ASSERT(m_fontList);
+ 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);
+ return m_fontList->isFixedPitch(this);
+}
+
+inline FontSelector* Font::fontSelector() const
+{
+ return m_fontList ? m_fontList->fontSelector() : 0;
+}
+
}
#endif
diff --git a/WebCore/platform/graphics/FontCache.cpp b/WebCore/platform/graphics/FontCache.cpp
index b3eca85..cb54cdd 100644
--- a/WebCore/platform/graphics/FontCache.cpp
+++ b/WebCore/platform/graphics/FontCache.cpp
@@ -56,9 +56,9 @@ FontCache::FontCache()
struct FontPlatformDataCacheKey : FastAllocBase {
FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, unsigned weight = 0, bool italic = false,
bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode)
- : m_family(family)
- , m_size(size)
+ : m_size(size)
, m_weight(weight)
+ , m_family(family)
, m_italic(italic)
, m_printerFont(isPrinterFont)
, m_renderingMode(renderingMode)
@@ -75,9 +75,9 @@ struct FontPlatformDataCacheKey : FastAllocBase {
m_renderingMode == other.m_renderingMode;
}
- AtomicString m_family;
unsigned m_size;
unsigned m_weight;
+ AtomicString m_family;
bool m_italic;
bool m_printerFont;
FontRenderingMode m_renderingMode;
diff --git a/WebCore/platform/graphics/FontFallbackList.h b/WebCore/platform/graphics/FontFallbackList.h
index 14ebbe4..a10f5af 100644
--- a/WebCore/platform/graphics/FontFallbackList.h
+++ b/WebCore/platform/graphics/FontFallbackList.h
@@ -1,8 +1,5 @@
/*
- * 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 Apple Computer, Inc.
+ * Copyright (C) 2006, 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
@@ -21,8 +18,8 @@
*
*/
-// This file has no guards on purpose in order to detect redundant includes. This is a private header
-// and so this may catch someone trying to include this file in public cpp files.
+#ifndef FontFallbackList_h
+#define FontFallbackList_h
#include "FontSelector.h"
#include "SimpleFontData.h"
@@ -89,3 +86,4 @@ private:
}
+#endif
diff --git a/WebCore/platform/graphics/GlyphPageTreeNode.h b/WebCore/platform/graphics/GlyphPageTreeNode.h
index 7918ac5..b68c0ed 100644
--- a/WebCore/platform/graphics/GlyphPageTreeNode.h
+++ b/WebCore/platform/graphics/GlyphPageTreeNode.h
@@ -172,8 +172,8 @@ public:
: m_parent(0)
, m_level(0)
, m_isSystemFallback(false)
- , m_systemFallbackChild(0)
, m_customFontCount(0)
+ , m_systemFallbackChild(0)
#ifndef NDEBUG
, m_pageNumber(0)
#endif
@@ -221,11 +221,11 @@ private:
GlyphPageTreeNode* m_parent;
RefPtr<GlyphPage> m_page;
- unsigned m_level;
- bool m_isSystemFallback;
+ unsigned m_level : 31;
+ bool m_isSystemFallback : 1;
+ unsigned m_customFontCount;
HashMap<const FontData*, GlyphPageTreeNode*> m_children;
GlyphPageTreeNode* m_systemFallbackChild;
- unsigned m_customFontCount;
#ifndef NDEBUG
unsigned m_pageNumber;
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index b64e9d3..b62f52c 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -60,12 +60,12 @@ const Platform3DObject NullPlatform3DObject = 0;
namespace WebCore {
class WebGLActiveInfo;
- class WebGLArray;
+ class ArrayBufferView;
class WebGLBuffer;
- class WebGLUnsignedByteArray;
- class WebGLFloatArray;
+ class Uint8Array;
+ class FloatArray;
class WebGLFramebuffer;
- class WebGLIntArray;
+ class Int32Array;
class WebGLProgram;
class WebGLRenderbuffer;
class WebGLRenderingContext;
@@ -499,8 +499,8 @@ namespace WebCore {
void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha);
void bufferData(unsigned long target, int size, unsigned long usage);
- void bufferData(unsigned long target, WebGLArray* data, unsigned long usage);
- void bufferSubData(unsigned long target, long offset, WebGLArray* data);
+ void bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage);
+ void bufferSubData(unsigned long target, long offset, ArrayBufferView* data);
unsigned long checkFramebufferStatus(unsigned long target);
void clear(unsigned long mask);
diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp
index b7567bf..c1e2ed6 100644
--- a/WebCore/platform/graphics/GraphicsLayer.cpp
+++ b/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -465,17 +465,21 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe
}
ts << ")\n";
- writeIndent(ts, indent + 1);
- ts << "(childrenTransform ";
- if (m_childrenTransform.isIdentity())
- ts << "identity";
- else {
- ts << "[" << m_childrenTransform.m11() << " " << m_childrenTransform.m12() << " " << m_childrenTransform.m13() << " " << m_childrenTransform.m14() << "] ";
- ts << "[" << m_childrenTransform.m21() << " " << m_childrenTransform.m22() << " " << m_childrenTransform.m23() << " " << m_childrenTransform.m24() << "] ";
- ts << "[" << m_childrenTransform.m31() << " " << m_childrenTransform.m32() << " " << m_childrenTransform.m33() << " " << m_childrenTransform.m34() << "] ";
- ts << "[" << m_childrenTransform.m41() << " " << m_childrenTransform.m42() << " " << m_childrenTransform.m43() << " " << m_childrenTransform.m44() << "]";
+ // Avoid dumping the sublayer transform on the root layer, because it's used for geometry flipping, whose behavior
+ // differs between platforms.
+ if (parent()) {
+ writeIndent(ts, indent + 1);
+ ts << "(childrenTransform ";
+ if (m_childrenTransform.isIdentity())
+ ts << "identity";
+ else {
+ ts << "[" << m_childrenTransform.m11() << " " << m_childrenTransform.m12() << " " << m_childrenTransform.m13() << " " << m_childrenTransform.m14() << "] ";
+ ts << "[" << m_childrenTransform.m21() << " " << m_childrenTransform.m22() << " " << m_childrenTransform.m23() << " " << m_childrenTransform.m24() << "] ";
+ ts << "[" << m_childrenTransform.m31() << " " << m_childrenTransform.m32() << " " << m_childrenTransform.m33() << " " << m_childrenTransform.m34() << "] ";
+ ts << "[" << m_childrenTransform.m41() << " " << m_childrenTransform.m42() << " " << m_childrenTransform.m43() << " " << m_childrenTransform.m44() << "]";
+ }
+ ts << ")\n";
}
- ts << ")\n";
if (m_replicaLayer) {
writeIndent(ts, indent + 1);
diff --git a/WebCore/platform/graphics/ImageBuffer.cpp b/WebCore/platform/graphics/ImageBuffer.cpp
index 55305d1..71b8189 100644
--- a/WebCore/platform/graphics/ImageBuffer.cpp
+++ b/WebCore/platform/graphics/ImageBuffer.cpp
@@ -42,7 +42,6 @@ void ImageBuffer::transformColorSpace(ImageColorSpace srcColorSpace, ImageColorS
(dstColorSpace != LinearRGB && dstColorSpace != DeviceRGB))
return;
- Vector<int> lookUpTable;
if (dstColorSpace == LinearRGB) {
if (m_linearRgbLUT.isEmpty()) {
for (unsigned i = 0; i < 256; i++) {
@@ -57,8 +56,8 @@ void ImageBuffer::transformColorSpace(ImageColorSpace srcColorSpace, ImageColorS
} else if (dstColorSpace == DeviceRGB) {
if (m_deviceRgbLUT.isEmpty()) {
for (unsigned i = 0; i < 256; i++) {
- float color = i / 255.0f;
- color = pow(1.055f * color, 1.0f / 2.4f) - 0.055f;
+ float color = i / 255.0f;
+ color = (powf(color, 1.0f / 2.4f) * 1.055f) - 0.055f;
color = std::max(0.0f, color);
color = std::min(1.0f, color);
m_deviceRgbLUT.append(static_cast<int>(color * 255));
diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h
index cc40f5e..5c6d75e 100644
--- a/WebCore/platform/graphics/ImageSource.h
+++ b/WebCore/platform/graphics/ImageSource.h
@@ -68,6 +68,11 @@ class String;
#if PLATFORM(CG)
typedef CGImageSourceRef NativeImageSourcePtr;
typedef CGImageRef NativeImagePtr;
+#elif PLATFORM(OPENVG)
+class ImageDecoder;
+class TiledImageOpenVG;
+typedef ImageDecoder* NativeImageSourcePtr;
+typedef TiledImageOpenVG* NativeImagePtr;
#elif PLATFORM(QT)
class ImageDecoderQt;
typedef ImageDecoderQt* NativeImageSourcePtr;
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index ee82083..ab88987 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -27,14 +27,14 @@
#if ENABLE(VIDEO)
#include "MediaPlayer.h"
-#include "MediaPlayerPrivate.h"
#include "ContentType.h"
+#include "Document.h"
+#include "Frame.h"
+#include "FrameView.h"
#include "IntRect.h"
#include "MIMETypeRegistry.h"
-#include "FrameView.h"
-#include "Frame.h"
-#include "Document.h"
+#include "MediaPlayerPrivate.h"
#include "TimeRanges.h"
#if PLATFORM(QT)
@@ -46,7 +46,8 @@
#elif OS(WINCE) && !PLATFORM(QT)
#include "MediaPlayerPrivateWince.h"
#elif PLATFORM(WIN)
-#include "MediaPlayerPrivateQuickTimeWin.h"
+#include "MediaPlayerPrivateQuickTimeVisualContext.h"
+#include "MediaPlayerPrivateQuicktimeWin.h"
#elif PLATFORM(GTK)
#include "MediaPlayerPrivateGStreamer.h"
#elif PLATFORM(QT)
@@ -64,6 +65,8 @@
namespace WebCore {
+const PlatformMedia NoPlatformMedia = { PlatformMedia::None, {0} };
+
// a null player to make MediaPlayer logic simpler
class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
@@ -165,6 +168,9 @@ static Vector<MediaPlayerFactory*>& installedMediaEngines()
#if USE(GSTREAMER)
MediaPlayerPrivateGStreamer::registerMediaEngine(addMediaEngine);
#else
+#if PLATFORM(WIN)
+ MediaPlayerPrivateQuickTimeVisualContext::registerMediaEngine(addMediaEngine);
+#endif
// FIXME: currently all the MediaEngines are named
// MediaPlayerPrivate. This code will need an update when bug
// 36663 is adressed.
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index 89021c3..9abbb15 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -49,6 +49,8 @@
#else
class QTMovie;
#endif
+class QTMovieGWorld;
+class QTMovieVisualContext;
namespace WebCore {
@@ -56,11 +58,22 @@ namespace WebCore {
// types supported by the current media player.
// We have to do that has multiple media players
// backend can live at runtime.
-typedef struct PlatformMedia {
- QTMovie* qtMovie;
-} PlatformMedia;
+struct PlatformMedia {
+ enum {
+ None,
+ QTMovieType,
+ QTMovieGWorldType,
+ QTMovieVisualContextType
+ } type;
+
+ union {
+ QTMovie* qtMovie;
+ QTMovieGWorld* qtMovieGWorld;
+ QTMovieVisualContext* qtMovieVisualContext;
+ } media;
+};
-static const PlatformMedia NoPlatformMedia = { 0 };
+extern const PlatformMedia NoPlatformMedia;
class ContentType;
class FrameView;
diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h
index 4c34f2b..bc897be 100644
--- a/WebCore/platform/graphics/SimpleFontData.h
+++ b/WebCore/platform/graphics/SimpleFontData.h
@@ -191,7 +191,7 @@ private:
FontPlatformData m_platformData;
- mutable GlyphMetricsMap<FloatRect> m_glyphToBoundsMap;
+ mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap;
mutable GlyphMetricsMap<float> m_glyphToWidthMap;
bool m_treatAsFixedPitch;
@@ -255,12 +255,17 @@ ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const
if (glyph == m_zeroWidthSpaceGlyph && glyph)
return FloatRect();
- FloatRect bounds = m_glyphToBoundsMap.metricsForGlyph(glyph);
- if (bounds.width() != cGlyphSizeUnknown)
- return bounds;
+ FloatRect bounds;
+ if (m_glyphToBoundsMap) {
+ bounds = m_glyphToBoundsMap->metricsForGlyph(glyph);
+ if (bounds.width() != cGlyphSizeUnknown)
+ return bounds;
+ }
bounds = platformBoundsForGlyph(glyph);
- m_glyphToBoundsMap.setMetricsForGlyph(glyph, bounds);
+ if (!m_glyphToBoundsMap)
+ m_glyphToBoundsMap.set(new GlyphMetricsMap<FloatRect>());
+ m_glyphToBoundsMap->setMetricsForGlyph(glyph, bounds);
return bounds;
}
diff --git a/WebCore/platform/graphics/TiledBackingStore.cpp b/WebCore/platform/graphics/TiledBackingStore.cpp
index 6214f1b..0250061 100644
--- a/WebCore/platform/graphics/TiledBackingStore.cpp
+++ b/WebCore/platform/graphics/TiledBackingStore.cpp
@@ -120,22 +120,23 @@ void TiledBackingStore::paint(GraphicsContext* context, const IntRect& rect)
if (currentTile && currentTile->isReadyToPaint())
currentTile->paint(context, dirtyRect);
else {
- FloatRect tileRect = tileRectForCoordinate(currentCoordinate);
- FloatRect target = intersection(tileRect, FloatRect(rect));
- Tile::paintCheckerPattern(context, target);
+ IntRect tileRect = tileRectForCoordinate(currentCoordinate);
+ IntRect target = intersection(tileRect, dirtyRect);
+ if (target.isEmpty())
+ continue;
+ Tile::paintCheckerPattern(context, FloatRect(target));
}
}
}
context->restore();
}
-void TiledBackingStore::viewportChanged(const IntRect& contentsViewport)
+void TiledBackingStore::adjustVisibleRect()
{
- IntRect viewport = mapFromContents(contentsViewport);
- if (m_viewport == viewport)
+ IntRect visibleRect = mapFromContents(m_client->tiledBackingStoreVisibleRect());
+ if (m_previousVisibleRect == visibleRect)
return;
-
- m_viewport = viewport;
+ m_previousVisibleRect = visibleRect;
startTileCreationTimer();
}
@@ -177,24 +178,27 @@ void TiledBackingStore::createTiles()
{
if (m_contentsFrozen)
return;
+
+ IntRect visibleRect = mapFromContents(m_client->tiledBackingStoreVisibleRect());
+ m_previousVisibleRect = visibleRect;
- if (m_viewport.isEmpty())
+ if (visibleRect.isEmpty())
return;
// Remove tiles that extend outside the current contents rect.
dropOverhangingTiles();
// FIXME: Make configurable/adapt to memory.
- IntRect keepRect = m_viewport;
- keepRect.inflateX(m_viewport.width());
- keepRect.inflateY(3 * m_viewport.height());
+ IntRect keepRect = visibleRect;
+ keepRect.inflateX(visibleRect.width());
+ keepRect.inflateY(3 * visibleRect.height());
keepRect.intersect(contentsRect());
dropTilesOutsideRect(keepRect);
- IntRect coverRect = m_viewport;
- coverRect.inflateX(m_viewport.width() / 2);
- coverRect.inflateY(2 * m_viewport.height());
+ IntRect coverRect = visibleRect;
+ coverRect.inflateX(visibleRect.width() / 2);
+ coverRect.inflateY(2 * visibleRect.height());
coverRect.intersect(contentsRect());
// Search for the tile position closest to the viewport center that does not yet contain a tile.
@@ -211,7 +215,7 @@ void TiledBackingStore::createTiles()
continue;
++requiredTileCount;
// Distance is 0 for all currently visible tiles.
- double distance = tileDistance(m_viewport, currentCoordinate);
+ double distance = tileDistance(visibleRect, currentCoordinate);
if (distance > shortestDistance)
continue;
if (distance < shortestDistance) {
diff --git a/WebCore/platform/graphics/TiledBackingStore.h b/WebCore/platform/graphics/TiledBackingStore.h
index 8ed4336..d12f191 100644
--- a/WebCore/platform/graphics/TiledBackingStore.h
+++ b/WebCore/platform/graphics/TiledBackingStore.h
@@ -41,7 +41,7 @@ public:
TiledBackingStore(TiledBackingStoreClient*);
~TiledBackingStore();
- void viewportChanged(const IntRect& viewportRect);
+ void adjustVisibleRect();
float contentsScale() { return m_contentsScale; }
void setContentsScale(float);
@@ -95,7 +95,7 @@ private:
IntSize m_tileSize;
- IntRect m_viewport;
+ IntRect m_previousVisibleRect;
float m_contentsScale;
float m_pendingScale;
diff --git a/WebCore/platform/graphics/TiledBackingStoreClient.h b/WebCore/platform/graphics/TiledBackingStoreClient.h
index 4adbbab..c5845b9 100644
--- a/WebCore/platform/graphics/TiledBackingStoreClient.h
+++ b/WebCore/platform/graphics/TiledBackingStoreClient.h
@@ -29,6 +29,7 @@ public:
virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&) = 0;
virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea) = 0;
virtual IntRect tiledBackingStoreContentsRect() = 0;
+ virtual IntRect tiledBackingStoreVisibleRect() = 0;
};
#else
diff --git a/WebCore/platform/graphics/cairo/FontCairo.cpp b/WebCore/platform/graphics/cairo/FontCairo.cpp
index c2aae49..71a2430 100644
--- a/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -138,12 +138,14 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
}
} else if (context->fillPattern()) {
AffineTransform affine;
- cairo_set_source(cr, context->fillPattern()->createPlatformPattern(affine));
+ cairo_pattern_t* pattern = context->fillPattern()->createPlatformPattern(affine);
+ cairo_set_source(cr, pattern);
if (context->getAlpha() < 1.0f) {
cairo_push_group(cr);
cairo_paint_with_alpha(cr, context->getAlpha());
cairo_pop_group_to_source(cr);
}
+ cairo_pattern_destroy(pattern);
} else {
float red, green, blue, alpha;
fillColor.getRGBA(red, green, blue, alpha);
@@ -172,12 +174,14 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
}
} else if (context->strokePattern()) {
AffineTransform affine;
- cairo_set_source(cr, context->strokePattern()->createPlatformPattern(affine));
+ cairo_pattern_t* pattern = context->strokePattern()->createPlatformPattern(affine);
+ cairo_set_source(cr, pattern);
if (context->getAlpha() < 1.0f) {
cairo_push_group(cr);
cairo_paint_with_alpha(cr, context->getAlpha());
cairo_pop_group_to_source(cr);
}
+ cairo_pattern_destroy(pattern);
} else {
Color strokeColor = context->strokeColor();
float red, green, blue, alpha;
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 0aa6b83..a2dcbaf 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -75,10 +75,12 @@ static inline void setColor(cairo_t* cr, const Color& col)
static inline void setPlatformFill(GraphicsContext* context, cairo_t* cr, GraphicsContextPrivate* gcp)
{
+ cairo_pattern_t* pattern = 0;
cairo_save(cr);
if (gcp->state.fillPattern) {
AffineTransform affine;
- cairo_set_source(cr, gcp->state.fillPattern->createPlatformPattern(affine));
+ pattern = gcp->state.fillPattern->createPlatformPattern(affine);
+ cairo_set_source(cr, pattern);
} else if (gcp->state.fillGradient)
cairo_set_source(cr, gcp->state.fillGradient->platformGradient());
else
@@ -86,14 +88,18 @@ static inline void setPlatformFill(GraphicsContext* context, cairo_t* cr, Graphi
cairo_clip_preserve(cr);
cairo_paint_with_alpha(cr, gcp->state.globalAlpha);
cairo_restore(cr);
+ if (pattern)
+ cairo_pattern_destroy(pattern);
}
static inline void setPlatformStroke(GraphicsContext* context, cairo_t* cr, GraphicsContextPrivate* gcp)
{
+ cairo_pattern_t* pattern = 0;
cairo_save(cr);
if (gcp->state.strokePattern) {
AffineTransform affine;
- cairo_set_source(cr, gcp->state.strokePattern->createPlatformPattern(affine));
+ pattern = gcp->state.strokePattern->createPlatformPattern(affine);
+ cairo_set_source(cr, pattern);
} else if (gcp->state.strokeGradient)
cairo_set_source(cr, gcp->state.strokeGradient->platformGradient());
else {
@@ -107,6 +113,8 @@ static inline void setPlatformStroke(GraphicsContext* context, cairo_t* cr, Grap
}
cairo_stroke_preserve(cr);
cairo_restore(cr);
+ if (pattern)
+ cairo_pattern_destroy(pattern);
}
// A fillRect helper
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 1227a6a..259cc0c 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -311,7 +311,23 @@ void GraphicsLayerChromium::setContentsRect(const IntRect& rect)
void GraphicsLayerChromium::setContentsToImage(Image* image)
{
- // FIXME: Implement
+ bool childrenChanged = false;
+ if (image) {
+ m_pendingContentsImage = image->nativeImageForCurrentFrame();
+ m_contentsLayerPurpose = ContentsLayerForImage;
+ if (!m_contentsLayer)
+ childrenChanged = true;
+ } else {
+ m_pendingContentsImage = 0;
+ m_contentsLayerPurpose = NoContentsLayer;
+ if (m_contentsLayer)
+ childrenChanged = true;
+ }
+
+ updateContentsImage();
+
+ if (childrenChanged)
+ updateSublayerList();
}
void GraphicsLayerChromium::setContentsToVideo(PlatformLayer* videoLayer)
@@ -489,7 +505,22 @@ void GraphicsLayerChromium::updateLayerBackgroundColor()
void GraphicsLayerChromium::updateContentsImage()
{
- // FIXME: Implement
+ if (m_pendingContentsImage) {
+ if (!m_contentsLayer.get()) {
+ RefPtr<LayerChromium> imageLayer = LayerChromium::create(LayerChromium::Layer, this);
+
+ setupContentsLayer(imageLayer.get());
+ m_contentsLayer = imageLayer;
+ // m_contentsLayer will be parented by updateSublayerList.
+ }
+ m_contentsLayer->setContents(m_pendingContentsImage);
+ m_pendingContentsImage = 0;
+
+ updateContentsRect();
+ } else {
+ // No image. m_contentsLayer will be removed via updateSublayerList.
+ m_contentsLayer = 0;
+ }
}
void GraphicsLayerChromium::updateContentsVideo()
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
index 03a6d41..bc86799 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
@@ -140,6 +140,8 @@ private:
ContentsLayerPurpose m_contentsLayerPurpose;
bool m_contentsLayerHasBackgroundColor : 1;
+
+ NativeImagePtr m_pendingContentsImage;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 4540ac1..05be15c 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -69,13 +69,15 @@ LayerChromium::LayerChromium(LayerType type, GraphicsLayerChromium* owner)
, m_skiaContext(0)
, m_graphicsContext(0)
, m_geometryFlipped(false)
+ , m_contents(0)
{
updateGraphicsContext(m_backingStoreRect);
}
LayerChromium::~LayerChromium()
{
- // Our superlayer should be holding a reference to us, so there should be no way for us to be destroyed while we still have a superlayer.
+ // Our superlayer should be holding a reference to us so there should be no
+ // way for us to be destroyed while we still have a superlayer.
ASSERT(!superlayer());
}
@@ -120,10 +122,18 @@ void LayerChromium::drawDebugBorder()
m_graphicsContext->drawLine(IntPoint(0, m_bounds.height()), IntPoint(m_bounds.width(), m_bounds.height()));
}
+void LayerChromium::setContents(NativeImagePtr contents)
+{
+ // Check if the image has changed.
+ if (m_contents == contents)
+ return;
+ m_contents = contents;
+}
+
void LayerChromium::setNeedsCommit()
{
// Call notifySyncRequired(), which in this implementation plumbs through to
- // call setRootLayerNeedsDisplay() on the WebView, which will cause LayerRendererSkia
+ // call setRootLayerNeedsDisplay() on the WebView, which will cause LayerRendererChromium
// to render a frame.
if (m_owner)
m_owner->notifySyncRequired();
@@ -137,18 +147,16 @@ void LayerChromium::addSublayer(PassRefPtr<LayerChromium> sublayer)
void LayerChromium::insertSublayer(PassRefPtr<LayerChromium> sublayer, size_t index)
{
index = min(index, m_sublayers.size());
- m_sublayers.insert(index, sublayer);
+ sublayer->removeFromSuperlayer();
sublayer->setSuperlayer(this);
+ m_sublayers.insert(index, sublayer);
setNeedsCommit();
}
void LayerChromium::removeFromSuperlayer()
{
- LayerChromium* superlayer = this->superlayer();
- if (!superlayer)
- return;
-
- superlayer->removeSublayer(this);
+ if (m_superlayer)
+ m_superlayer->removeSublayer(this);
}
void LayerChromium::removeSublayer(LayerChromium* sublayer)
@@ -157,11 +165,33 @@ void LayerChromium::removeSublayer(LayerChromium* sublayer)
if (foundIndex == -1)
return;
- m_sublayers.remove(foundIndex);
sublayer->setSuperlayer(0);
+ m_sublayers.remove(foundIndex);
setNeedsCommit();
}
+void LayerChromium::replaceSublayer(LayerChromium* reference, PassRefPtr<LayerChromium> newLayer)
+{
+ ASSERT_ARG(reference, reference);
+ ASSERT_ARG(reference, reference->superlayer() == this);
+
+ if (reference == newLayer)
+ return;
+
+ int referenceIndex = indexOfSublayer(reference);
+ if (referenceIndex == -1) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ reference->removeFromSuperlayer();
+
+ if (newLayer) {
+ newLayer->removeFromSuperlayer();
+ insertSublayer(newLayer, referenceIndex);
+ }
+}
+
int LayerChromium::indexOfSublayer(const LayerChromium* reference)
{
for (size_t i = 0; i < m_sublayers.size(); i++) {
@@ -214,18 +244,23 @@ const LayerChromium* LayerChromium::rootLayer() const
void LayerChromium::removeAllSublayers()
{
- m_sublayers.clear();
+ while (m_sublayers.size()) {
+ LayerChromium* layer = m_sublayers[0].get();
+ ASSERT(layer->superlayer());
+ layer->removeFromSuperlayer();
+ }
setNeedsCommit();
}
void LayerChromium::setSublayers(const Vector<RefPtr<LayerChromium> >& sublayers)
{
- m_sublayers = sublayers;
-}
+ if (sublayers == m_sublayers)
+ return;
-void LayerChromium::setSuperlayer(LayerChromium* superlayer)
-{
- m_superlayer = superlayer;
+ removeAllSublayers();
+ size_t listSize = sublayers.size();
+ for (size_t i = 0; i < listSize; i++)
+ addSublayer(sublayers[i]);
}
LayerChromium* LayerChromium::superlayer() const
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index 55b1288..5b93f77 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -67,6 +67,7 @@ public:
void addSublayer(PassRefPtr<LayerChromium>);
void insertSublayer(PassRefPtr<LayerChromium>, size_t index);
+ void replaceSublayer(LayerChromium* reference, PassRefPtr<LayerChromium> newLayer);
void removeFromSuperlayer();
void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; setNeedsCommit(); }
@@ -140,7 +141,6 @@ public:
void setSublayerTransform(const TransformationMatrix& transform) { m_sublayerTransform = transform; setNeedsCommit(); }
const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; }
- void setSuperlayer(LayerChromium* superlayer);
LayerChromium* superlayer() const;
@@ -152,6 +152,9 @@ public:
void updateContents();
+ void setContents(NativeImagePtr contents);
+ NativeImagePtr contents() const { return m_contents; }
+
skia::PlatformCanvas* platformCanvas() { return m_canvas.get(); }
GraphicsContext* graphicsContext() { return m_graphicsContext.get(); }
@@ -164,6 +167,8 @@ private:
void setNeedsCommit();
+ void setSuperlayer(LayerChromium* superlayer) { m_superlayer = superlayer; }
+
void paintMe();
size_t numSublayers() const
@@ -177,17 +182,19 @@ private:
// This should only be called from removeFromSuperlayer.
void removeSublayer(LayerChromium*);
- // Re-create the canvas and graphics context. This method
- // must be called every time the layer is resized.
+ // Re-creates the canvas and graphics context. This method
+ // must be called every time the layer is resized. Only layers
void updateGraphicsContext(const IntSize&);
Vector<RefPtr<LayerChromium> > m_sublayers;
LayerChromium* m_superlayer;
GraphicsLayerChromium* m_owner;
+#if PLATFORM(SKIA)
OwnPtr<skia::PlatformCanvas> m_canvas;
OwnPtr<PlatformContextSkia> m_skiaContext;
OwnPtr<GraphicsContext> m_graphicsContext;
+#endif
LayerType m_layerType;
@@ -217,6 +224,7 @@ private:
bool m_needsDisplayOnBoundsChange;
ContentsGravityType m_contentsGravity;
+ NativeImagePtr m_contents;
String m_name;
};
diff --git a/WebCore/platform/graphics/filters/FEBlend.cpp b/WebCore/platform/graphics/filters/FEBlend.cpp
index f362148..99c0ae7 100644
--- a/WebCore/platform/graphics/filters/FEBlend.cpp
+++ b/WebCore/platform/graphics/filters/FEBlend.cpp
@@ -145,6 +145,42 @@ void FEBlend::dump()
{
}
+static TextStream& operator<<(TextStream& ts, const BlendModeType& type)
+{
+ switch (type) {
+ case FEBLEND_MODE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FEBLEND_MODE_NORMAL:
+ ts << "NORMAL";
+ break;
+ case FEBLEND_MODE_MULTIPLY:
+ ts << "MULTIPLY";
+ break;
+ case FEBLEND_MODE_SCREEN:
+ ts << "SCREEN";
+ break;
+ case FEBLEND_MODE_DARKEN:
+ ts << "DARKEN";
+ break;
+ case FEBLEND_MODE_LIGHTEN:
+ ts << "LIGHTEN";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEBlend::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feBlend";
+ FilterEffect::externalRepresentation(ts);
+ ts << " mode=\"" << m_mode << "\"]\n";
+ m_in->externalRepresentation(ts, indent + 1);
+ m_in2->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEBlend.h b/WebCore/platform/graphics/filters/FEBlend.h
index 31c625f..a387814 100644
--- a/WebCore/platform/graphics/filters/FEBlend.h
+++ b/WebCore/platform/graphics/filters/FEBlend.h
@@ -51,6 +51,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get(), m_in2.get()); }
void apply(Filter*);
void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEBlend(FilterEffect*, FilterEffect*, BlendModeType);
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index bd19d14..c5ae3b9 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -195,6 +195,51 @@ void FEColorMatrix::dump()
{
}
+static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type)
+{
+ switch (type) {
+ case FECOLORMATRIX_TYPE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FECOLORMATRIX_TYPE_MATRIX:
+ ts << "MATRIX";
+ break;
+ case FECOLORMATRIX_TYPE_SATURATE:
+ ts << "SATURATE";
+ break;
+ case FECOLORMATRIX_TYPE_HUEROTATE:
+ ts << "HUEROTATE";
+ break;
+ case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
+ ts << "LUMINANCETOALPHA";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEColorMatrix::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feColorMatrix";
+ FilterEffect::externalRepresentation(ts);
+ ts << " type=\"" << m_type << "\"";
+ if (!m_values.isEmpty()) {
+ ts << " values=\"";
+ Vector<float>::const_iterator ptr = m_values.begin();
+ const Vector<float>::const_iterator end = m_values.end();
+ while (ptr < end) {
+ ts << *ptr;
+ ++ptr;
+ if (ptr < end)
+ ts << " ";
+ }
+ ts << "\"";
+ }
+ ts << "]\n";
+ m_in->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.h b/WebCore/platform/graphics/filters/FEColorMatrix.h
index 106b2fa..104a2e8 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.h
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.h
@@ -51,6 +51,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
void apply(Filter*);
void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEColorMatrix(FilterEffect*, ColorMatrixType, const Vector<float>&);
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
index f9aa011..19df970 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -185,6 +185,60 @@ void FEComponentTransfer::dump()
{
}
+static TextStream& operator<<(TextStream& ts, const ComponentTransferType& type)
+{
+ switch (type) {
+ case FECOMPONENTTRANSFER_TYPE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_IDENTITY:
+ ts << "IDENTITY";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_TABLE:
+ ts << "TABLE";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_DISCRETE:
+ ts << "DISCRETE";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_LINEAR:
+ ts << "LINEAR";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_GAMMA:
+ ts << "GAMMA";
+ break;
+ }
+ return ts;
+}
+
+static TextStream& operator<<(TextStream& ts, const ComponentTransferFunction& function)
+{
+ ts << "type=\"" << function.type
+ << "\" slope=\"" << function.slope
+ << "\" intercept=\"" << function.intercept
+ << "\" amplitude=\"" << function.amplitude
+ << "\" exponent=\"" << function.exponent
+ << "\" offset=\"" << function.offset << "\"";
+ return ts;
+}
+
+TextStream& FEComponentTransfer::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feComponentTransfer";
+ FilterEffect::externalRepresentation(ts);
+ ts << " \n";
+ writeIndent(ts, indent + 2);
+ ts << "{red: " << m_redFunc << "}\n";
+ writeIndent(ts, indent + 2);
+ ts << "{green: " << m_greenFunc << "}\n";
+ writeIndent(ts, indent + 2);
+ ts << "{blue: " << m_blueFunc << "}\n";
+ writeIndent(ts, indent + 2);
+ ts << "{alpha: " << m_alphaFunc << "}]\n";
+ m_in->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.h b/WebCore/platform/graphics/filters/FEComponentTransfer.h
index ab84cf0..a79e5df 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.h
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.h
@@ -81,6 +81,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
void apply(Filter*);
void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEComponentTransfer(FilterEffect*,const ComponentTransferFunction&, const ComponentTransferFunction&,
diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp
index 67d3d27..18df3b2 100644
--- a/WebCore/platform/graphics/filters/FEComposite.cpp
+++ b/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -173,6 +173,48 @@ void FEComposite::dump()
{
}
+static TextStream& operator<<(TextStream& ts, const CompositeOperationType& type)
+{
+ switch (type) {
+ case FECOMPOSITE_OPERATOR_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FECOMPOSITE_OPERATOR_OVER:
+ ts << "OVER";
+ break;
+ case FECOMPOSITE_OPERATOR_IN:
+ ts << "IN";
+ break;
+ case FECOMPOSITE_OPERATOR_OUT:
+ ts << "OUT";
+ break;
+ case FECOMPOSITE_OPERATOR_ATOP:
+ ts << "ATOP";
+ break;
+ case FECOMPOSITE_OPERATOR_XOR:
+ ts << "XOR";
+ break;
+ case FECOMPOSITE_OPERATOR_ARITHMETIC:
+ ts << "ARITHMETIC";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEComposite::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feComposite";
+ FilterEffect::externalRepresentation(ts);
+ ts << " operation=\"" << m_type << "\"";
+ if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC)
+ ts << " k1=\"" << m_k1 << "\" k2=\"" << m_k2 << "\" k3=\"" << m_k3 << "\" k4=\"" << m_k4 << "\"";
+ ts << "]\n";
+ m_in->externalRepresentation(ts, indent + 1);
+ m_in2->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEComposite.h b/WebCore/platform/graphics/filters/FEComposite.h
index ad096f2..b05cc66 100644
--- a/WebCore/platform/graphics/filters/FEComposite.h
+++ b/WebCore/platform/graphics/filters/FEComposite.h
@@ -30,52 +30,53 @@
namespace WebCore {
- enum CompositeOperationType {
- FECOMPOSITE_OPERATOR_UNKNOWN = 0,
- FECOMPOSITE_OPERATOR_OVER = 1,
- FECOMPOSITE_OPERATOR_IN = 2,
- FECOMPOSITE_OPERATOR_OUT = 3,
- FECOMPOSITE_OPERATOR_ATOP = 4,
- FECOMPOSITE_OPERATOR_XOR = 5,
- FECOMPOSITE_OPERATOR_ARITHMETIC = 6
- };
-
- class FEComposite : public FilterEffect {
- public:
- static PassRefPtr<FEComposite> create(FilterEffect*, FilterEffect*, const CompositeOperationType&,
- const float&, const float&, const float&, const float&);
-
- CompositeOperationType operation() const;
- void setOperation(CompositeOperationType);
-
- float k1() const;
- void setK1(float);
-
- float k2() const;
- void setK2(float);
-
- float k3() const;
- void setK3(float);
-
- float k4() const;
- void setK4(float);
-
- virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get(), m_in2.get()); }
- void apply(Filter*);
- void dump();
-
- private:
- FEComposite(FilterEffect*, FilterEffect*, const CompositeOperationType&,
- const float&, const float&, const float&, const float&);
-
- RefPtr<FilterEffect> m_in;
- RefPtr<FilterEffect> m_in2;
- CompositeOperationType m_type;
- float m_k1;
- float m_k2;
- float m_k3;
- float m_k4;
- };
+enum CompositeOperationType {
+ FECOMPOSITE_OPERATOR_UNKNOWN = 0,
+ FECOMPOSITE_OPERATOR_OVER = 1,
+ FECOMPOSITE_OPERATOR_IN = 2,
+ FECOMPOSITE_OPERATOR_OUT = 3,
+ FECOMPOSITE_OPERATOR_ATOP = 4,
+ FECOMPOSITE_OPERATOR_XOR = 5,
+ FECOMPOSITE_OPERATOR_ARITHMETIC = 6
+};
+
+class FEComposite : public FilterEffect {
+public:
+ static PassRefPtr<FEComposite> create(FilterEffect*, FilterEffect*, const CompositeOperationType&,
+ const float&, const float&, const float&, const float&);
+
+ CompositeOperationType operation() const;
+ void setOperation(CompositeOperationType);
+
+ float k1() const;
+ void setK1(float);
+
+ float k2() const;
+ void setK2(float);
+
+ float k3() const;
+ void setK3(float);
+
+ float k4() const;
+ void setK4(float);
+
+ virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get(), m_in2.get()); }
+ void apply(Filter*);
+ void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
+
+private:
+ FEComposite(FilterEffect*, FilterEffect*, const CompositeOperationType&,
+ const float&, const float&, const float&, const float&);
+
+ RefPtr<FilterEffect> m_in;
+ RefPtr<FilterEffect> m_in2;
+ CompositeOperationType m_type;
+ float m_k1;
+ float m_k2;
+ float m_k3;
+ float m_k4;
+};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
index 0b97e39..61aea90 100644
--- a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
@@ -139,6 +139,16 @@ void FEGaussianBlur::dump()
{
}
+TextStream& FEGaussianBlur::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feGaussianBlur";
+ FilterEffect::externalRepresentation(ts);
+ ts << " stdDeviation=\"" << m_x << ", " << m_y << "\"]\n";
+ m_in->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.h b/WebCore/platform/graphics/filters/FEGaussianBlur.h
index ecdb9e3..bcc030e 100644
--- a/WebCore/platform/graphics/filters/FEGaussianBlur.h
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.h
@@ -28,27 +28,28 @@
namespace WebCore {
- class FEGaussianBlur : public FilterEffect {
- public:
- static PassRefPtr<FEGaussianBlur> create(FilterEffect*, const float&, const float&);
+class FEGaussianBlur : public FilterEffect {
+public:
+ static PassRefPtr<FEGaussianBlur> create(FilterEffect*, const float&, const float&);
- float stdDeviationX() const;
- void setStdDeviationX(float);
+ float stdDeviationX() const;
+ void setStdDeviationX(float);
- float stdDeviationY() const;
- void setStdDeviationY(float);
+ float stdDeviationY() const;
+ void setStdDeviationY(float);
- virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
- void apply(Filter*);
- void dump();
+ virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
+ void apply(Filter*);
+ void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
- private:
- FEGaussianBlur(FilterEffect*, const float&, const float&);
+private:
+ FEGaussianBlur(FilterEffect*, const float&, const float&);
- RefPtr<FilterEffect> m_in;
- float m_x;
- float m_y;
- };
+ RefPtr<FilterEffect> m_in;
+ float m_x;
+ float m_y;
+};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp
index 5583813..4d7265c 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.cpp
+++ b/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -77,8 +77,10 @@ GraphicsContext* FilterEffect::getEffectContext()
return m_effectBuffer->context();
}
-TextStream& FilterEffect::externalRepresentation(TextStream& ts) const
+TextStream& FilterEffect::externalRepresentation(TextStream& ts, int) const
{
+ // FIXME: We should dump the subRegions of the filter primitives here later. This isn't
+ // possible at the moment, because we need more detailed informations from the target object.
return ts;
}
diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h
index a46d795..3b8b5a3 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.h
+++ b/WebCore/platform/graphics/filters/FilterEffect.h
@@ -26,6 +26,7 @@
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "ImageBuffer.h"
+#include "RenderTreeAsText.h"
#include "TextStream.h"
#include <wtf/PassOwnPtr.h>
@@ -84,7 +85,7 @@ namespace WebCore {
virtual bool isSourceInput() { return false; }
- virtual TextStream& externalRepresentation(TextStream&) const;
+ virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const;
protected:
FilterEffect();
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp
index 539bb44..eb23814 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.cpp
+++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp
@@ -74,6 +74,13 @@ void SourceAlpha::dump()
{
}
+TextStream& SourceAlpha::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[SourceAlpha]\n";
+ return ts;
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.h b/WebCore/platform/graphics/filters/SourceAlpha.h
index 172d05a..e5c6815 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.h
+++ b/WebCore/platform/graphics/filters/SourceAlpha.h
@@ -38,6 +38,7 @@ namespace WebCore {
virtual FloatRect calculateEffectRect(Filter*);
void apply(Filter*);
void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
SourceAlpha() { }
diff --git a/WebCore/platform/graphics/filters/SourceGraphic.cpp b/WebCore/platform/graphics/filters/SourceGraphic.cpp
index cc55618..a1864d6 100644
--- a/WebCore/platform/graphics/filters/SourceGraphic.cpp
+++ b/WebCore/platform/graphics/filters/SourceGraphic.cpp
@@ -67,6 +67,13 @@ void SourceGraphic::dump()
{
}
+TextStream& SourceGraphic::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[SourceGraphic]\n";
+ return ts;
+}
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/SourceGraphic.h b/WebCore/platform/graphics/filters/SourceGraphic.h
index 0c8095e..05238a2 100644
--- a/WebCore/platform/graphics/filters/SourceGraphic.h
+++ b/WebCore/platform/graphics/filters/SourceGraphic.h
@@ -39,6 +39,7 @@ namespace WebCore {
virtual FloatRect calculateEffectRect(Filter*);
void apply(Filter*);
void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
SourceGraphic() { }
diff --git a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
index 1d14b5a..75bf5e7 100644
--- a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
@@ -30,6 +30,6 @@ template <> void freeOwnedGPtr<GstElement>(GstElement* ptr)
if (ptr)
gst_object_unref(ptr);
}
-#endif
}
+#endif
diff --git a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
index 7ea7d91..f5379b6 100644
--- a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
@@ -20,7 +20,6 @@
#ifndef _HAVE_WEBKIT_VIDEO_SINK_H
#define _HAVE_WEBKIT_VIDEO_SINK_H
-#include <cairo.h>
#include <glib-object.h>
#include <gst/video/gstvideosink.h>
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.cpp b/WebCore/platform/graphics/mac/ComplexTextController.cpp
index efb92f8..61d5518 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -280,7 +280,7 @@ void ComplexTextController::collectComplexTextRuns()
static inline bool shouldUseATSUIAPI()
{
enum TypeRenderingAPIToUse { UnInitialized, UseATSUI, UseCoreText };
- DEFINE_STATIC_LOCAL(TypeRenderingAPIToUse, apiToUse, (UnInitialized));
+ static TypeRenderingAPIToUse apiToUse = UnInitialized;
if (UNLIKELY(apiToUse == UnInitialized)) {
if (&CTGetCoreTextVersion != 0 && CTGetCoreTextVersion() >= kCTVersionNumber10_6)
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
index af210df..3b3158f 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
@@ -33,16 +33,16 @@
#include "ImageBuffer.h"
#include "NotImplemented.h"
#include "WebGLActiveInfo.h"
-#include "WebGLArray.h"
+#include "ArrayBufferView.h"
#include "WebGLBuffer.h"
-#include "WebGLFloatArray.h"
+#include "FloatArray.h"
#include "WebGLFramebuffer.h"
-#include "WebGLIntArray.h"
+#include "Int32Array.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
-#include "WebGLUnsignedByteArray.h"
+#include "Uint8Array.h"
#include <CoreGraphics/CGBitmapContext.h>
#include <OpenGL/CGLRenderers.h>
#include <OpenGL/gl.h>
@@ -446,7 +446,7 @@ void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long
ensureContext(m_contextObj);
::glBufferData(target, size, 0, usage);
}
-void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsigned long usage)
+void GraphicsContext3D::bufferData(unsigned long target, ArrayBufferView* array, unsigned long usage)
{
if (!array || !array->length())
return;
@@ -455,7 +455,7 @@ void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsi
::glBufferData(target, array->byteLength(), array->baseAddress(), usage);
}
-void GraphicsContext3D::bufferSubData(unsigned long target, long offset, WebGLArray* array)
+void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBufferView* array)
{
if (!array || !array->length())
return;
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index c837b51..b49c52f 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -601,8 +601,10 @@ void MediaPlayerPrivate::prepareToPlay()
PlatformMedia MediaPlayerPrivate::platformMedia() const
{
- PlatformMedia plaftformMedia = { m_qtMovie.get() };
- return plaftformMedia;
+ PlatformMedia pm;
+ pm.type = PlatformMedia::QTMovieType;
+ pm.media.qtMovie = m_qtMovie.get();
+ return pm;
}
#if USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/openvg/ImageOpenVG.cpp b/WebCore/platform/graphics/openvg/ImageOpenVG.cpp
new file mode 100644
index 0000000..4c1932a
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/ImageOpenVG.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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.
+ */
+
+#include "config.h"
+#include "Image.h"
+
+#include "AffineTransform.h"
+#include "BitmapImage.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "ImageDecoder.h"
+#include "ImageObserver.h"
+#include "IntSize.h"
+#include "NotImplemented.h"
+#include "PainterOpenVG.h"
+#include "SurfaceOpenVG.h"
+#include "TiledImageOpenVG.h"
+#include "VGUtils.h"
+
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+bool FrameData::clear(bool clearMetadata)
+{
+ if (clearMetadata)
+ m_haveMetadata = false;
+
+ if (m_frame) {
+ delete m_frame;
+ m_frame = 0;
+ return true;
+ }
+ return false;
+}
+
+BitmapImage::BitmapImage(TiledImageOpenVG* tiledImage, ImageObserver* observer)
+ : Image(observer)
+ , m_size(tiledImage->size())
+ , m_currentFrame(0)
+ , m_frames(1)
+ , m_frameTimer(0)
+ , m_repetitionCount(cAnimationNone)
+ , m_repetitionCountStatus(Unknown)
+ , m_repetitionsComplete(0)
+ , m_desiredFrameStartTime(0)
+ , m_isSolidColor(false)
+ , m_checkedForSolidColor(false)
+ , m_animationFinished(false)
+ , m_allDataReceived(false)
+ , m_haveSize(true)
+ , m_sizeAvailable(true)
+ , m_hasUniformFrameSize(true)
+ , m_haveFrameCount(true)
+ , m_frameCount(1)
+{
+ initPlatformData();
+
+ ASSERT(m_size.width() > 0);
+ ASSERT(m_size.height() > 0);
+
+ m_decodedSize = m_size.width() * m_size.height() * 4;
+
+ m_frames[0].m_frame = tiledImage;
+ m_frames[0].m_hasAlpha = true;
+ m_frames[0].m_isComplete = true;
+ m_frames[0].m_haveMetadata = true;
+ checkForSolidColor();
+}
+
+void BitmapImage::checkForSolidColor()
+{
+ TiledImageOpenVG* tiledImage = 0;
+
+ if (m_frameCount == 1 && m_size.width() == 1 && m_size.height() == 1)
+ tiledImage = nativeImageForCurrentFrame();
+
+ if (tiledImage) {
+ m_isSolidColor = true;
+ RGBA32 pixel;
+ vgGetImageSubData(tiledImage->tile(0, 0), &pixel, 0, VG_sARGB_8888, 0, 0, 1, 1);
+ ASSERT_VG_NO_ERROR();
+ m_solidColor.setRGB(pixel);
+ } else
+ m_isSolidColor = false;
+
+ m_checkedForSolidColor = true;
+}
+
+void BitmapImage::initPlatformData()
+{
+}
+
+void BitmapImage::invalidatePlatformData()
+{
+}
+
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+static void adjustSourceRectForDownSampling(FloatRect& srcRect, const IntSize& origSize, const IntSize& scaledSize)
+{
+ // We assume down-sampling zoom rates in X direction and in Y direction are same.
+ if (origSize.width() == scaledSize.width())
+ return;
+
+ // Image has been down sampled.
+ double rate = static_cast<double>(scaledSize.width()) / origSize.width();
+ double temp = srcRect.right() * rate;
+ srcRect.setX(srcRect.x() * rate);
+ srcRect.setWidth(temp - srcRect.x());
+ temp = srcRect.bottom() * rate;
+ srcRect.setY(srcRect.y() * rate);
+ srcRect.setHeight(temp - srcRect.y());
+}
+#endif
+
+void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op)
+{
+ if (dst.isEmpty() || src.isEmpty())
+ return;
+
+ NativeImagePtr image = nativeImageForCurrentFrame();
+ if (!image)
+ return;
+
+ startAnimation();
+
+ if (mayFillWithSolidColor()) {
+ fillWithSolidColor(context, dst, solidColor(), styleColorSpace, op);
+ return;
+ }
+
+ context->save();
+
+ // Set the compositing operation.
+ if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
+ context->setCompositeOperation(CompositeCopy);
+ else
+ context->setCompositeOperation(op);
+
+ FloatRect srcRectLocal(src);
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ adjustSourceRectForDownSampling(srcRectLocal, size(), image->size());
+#endif
+
+ context->platformContext()->activePainter()->drawImage(image, dst, srcRectLocal);
+ context->restore();
+
+ if (imageObserver())
+ imageObserver()->didDraw(this);
+}
+
+void Image::drawPattern(GraphicsContext* context, const FloatRect& src,
+ const AffineTransform& patternTransformation,
+ const FloatPoint& phase, ColorSpace styleColorSpace,
+ CompositeOperator op, const FloatRect& dst)
+{
+ if (dst.isEmpty() || src.isEmpty())
+ return;
+
+ NativeImagePtr image = nativeImageForCurrentFrame();
+ if (!image)
+ return;
+
+ startAnimation();
+
+ if (mayFillWithSolidColor()) {
+ fillWithSolidColor(context, dst, solidColor(), styleColorSpace, op);
+ return;
+ }
+
+ notImplemented();
+
+ if (imageObserver())
+ imageObserver()->didDraw(this);
+}
+
+PassRefPtr<Image> Image::loadPlatformResource(char const* name)
+{
+ notImplemented();
+ return 0;
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.cpp b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
index 5842afd..7d60ca5 100644
--- a/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
@@ -31,6 +31,7 @@
#include "NotImplemented.h"
#include "PlatformPathOpenVG.h"
#include "SurfaceOpenVG.h"
+#include "TiledImageOpenVG.h"
#include "VGUtils.h"
#if PLATFORM(EGL)
@@ -1085,6 +1086,49 @@ void PainterOpenVG::drawPolygon(size_t numPoints, const FloatPoint* points, VGbi
ASSERT_VG_NO_ERROR();
}
+void PainterOpenVG::drawImage(TiledImageOpenVG* tiledImage, const FloatRect& dst, const FloatRect& src)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ // If buffers can be larger than the maximum OpenVG image sizes,
+ // we split them into tiles.
+ IntRect drawnTiles = tiledImage->tilesInRect(src);
+ AffineTransform srcToDstTransformation = makeMapBetweenRects(
+ FloatRect(FloatPoint(0.0, 0.0), src.size()), dst);
+ srcToDstTransformation.translate(-src.x(), -src.y());
+
+ for (int yIndex = drawnTiles.y(); yIndex < drawnTiles.bottom(); ++yIndex) {
+ for (int xIndex = drawnTiles.x(); xIndex < drawnTiles.right(); ++xIndex) {
+ // The srcTile rectangle is an aligned tile cropped by the src rectangle.
+ FloatRect tile(tiledImage->tileRect(xIndex, yIndex));
+ FloatRect srcTile = intersection(src, tile);
+
+ save();
+
+ // If the image is drawn in full, all we need is the proper transformation
+ // in order to get it drawn at the right spot on the surface.
+ concatTransformation(AffineTransform(srcToDstTransformation).translate(tile.x(), tile.y()));
+
+ // If only a part of the tile is drawn, we also need to clip the surface.
+ if (srcTile != tile) {
+ // Put boundaries relative to tile origin, as we already
+ // translated to (x, y) with the transformation matrix.
+ srcTile.move(-tile.x(), -tile.y());
+ intersectClipRect(srcTile);
+ }
+
+ VGImage image = tiledImage->tile(xIndex, yIndex);
+ if (image != VG_INVALID_HANDLE) {
+ vgDrawImage(image);
+ ASSERT_VG_NO_ERROR();
+ }
+
+ restore();
+ }
+ }
+}
+
#ifdef OPENVG_VERSION_1_1
void PainterOpenVG::drawText(VGFont vgFont, Vector<VGuint>& characters, VGfloat* adjustmentsX, VGfloat* adjustmentsY, const FloatPoint& point)
{
@@ -1137,6 +1181,48 @@ void PainterOpenVG::drawText(VGFont vgFont, Vector<VGuint>& characters, VGfloat*
}
#endif
+TiledImageOpenVG* PainterOpenVG::asNewNativeImage(const IntRect& src, VGImageFormat format)
+{
+ ASSERT(m_state);
+ m_surface->sharedSurface()->makeCurrent();
+
+ const IntSize vgMaxImageSize(vgGeti(VG_MAX_IMAGE_WIDTH), vgGeti(VG_MAX_IMAGE_HEIGHT));
+ ASSERT_VG_NO_ERROR();
+
+ const IntRect rect = intersection(src, IntRect(0, 0, m_surface->width(), m_surface->height()));
+ TiledImageOpenVG* tiledImage = new TiledImageOpenVG(rect.size(), vgMaxImageSize);
+
+ const int numColumns = tiledImage->numColumns();
+ const int numRows = tiledImage->numRows();
+
+ // Create the images as resources of the shared surface/context.
+ for (int yIndex = 0; yIndex < numRows; ++yIndex) {
+ for (int xIndex = 0; xIndex < numColumns; ++xIndex) {
+ IntRect tileRect = tiledImage->tileRect(xIndex, yIndex);
+ VGImage image = vgCreateImage(format, tileRect.width(), tileRect.height(), VG_IMAGE_QUALITY_FASTER);
+ ASSERT_VG_NO_ERROR();
+
+ tiledImage->setTile(xIndex, yIndex, image);
+ }
+ }
+
+ // Fill the image contents with our own surface/context being current.
+ m_surface->makeCurrent();
+
+ for (int yIndex = 0; yIndex < numRows; ++yIndex) {
+ for (int xIndex = 0; xIndex < numColumns; ++xIndex) {
+ IntRect tileRect = tiledImage->tileRect(xIndex, yIndex);
+
+ vgGetPixels(tiledImage->tile(xIndex, yIndex), 0, 0,
+ rect.x() + tileRect.x(), rect.y() + tileRect.y(),
+ tileRect.width(), tileRect.height());
+ ASSERT_VG_NO_ERROR();
+ }
+ }
+
+ return tiledImage;
+}
+
void PainterOpenVG::save(PainterOpenVG::SaveMode saveMode)
{
ASSERT(m_state);
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.h b/WebCore/platform/graphics/openvg/PainterOpenVG.h
index 30cdf31..e4c6688 100644
--- a/WebCore/platform/graphics/openvg/PainterOpenVG.h
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.h
@@ -37,6 +37,7 @@ class IntRect;
class IntSize;
class Path;
class SurfaceOpenVG;
+class TiledImageOpenVG;
struct PlatformPainterState;
@@ -101,6 +102,7 @@ public:
void drawArc(const IntRect& ellipseBounds, int startAngle, int angleSpan, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
void drawEllipse(const IntRect& bounds, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
void drawPolygon(size_t numPoints, const FloatPoint* points, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
+ void drawImage(TiledImageOpenVG*, const FloatRect& dst, const FloatRect& src);
#ifdef OPENVG_VERSION_1_1
void drawText(VGFont, Vector<VGuint>& characters, VGfloat* adjustmentsX, VGfloat* adjustmentsY, const FloatPoint&);
#endif
@@ -117,6 +119,8 @@ public:
void intersectClipRect(const FloatRect&);
void clipPath(const Path&, PainterOpenVG::ClipOperation, WindRule clipRule = RULE_NONZERO);
+ TiledImageOpenVG* asNewNativeImage(const IntRect& src, VGImageFormat);
+
void save(PainterOpenVG::SaveMode saveMode = CreateNewState);
void restore();
diff --git a/WebCore/platform/graphics/openvg/TiledImageOpenVG.cpp b/WebCore/platform/graphics/openvg/TiledImageOpenVG.cpp
new file mode 100644
index 0000000..64d94c9
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/TiledImageOpenVG.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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.
+ */
+
+#include "config.h"
+#include "TiledImageOpenVG.h"
+
+#include "FloatRect.h"
+#include "IntRect.h"
+#include "VGUtils.h"
+
+namespace WebCore {
+
+TiledImageOpenVG::TiledImageOpenVG(const IntSize& size, const IntSize& tileSize)
+ : SharedResourceOpenVG()
+ , m_size(size)
+ , m_maxTileSize(tileSize)
+ , m_numColumns((m_size.width() - 1) / m_maxTileSize.width() + 1)
+ , m_tiles(((m_size.height() - 1) / m_maxTileSize.height() + 1) * m_numColumns, VG_INVALID_HANDLE)
+{
+}
+
+TiledImageOpenVG::TiledImageOpenVG(const TiledImageOpenVG& other)
+ : SharedResourceOpenVG()
+ , m_size(other.m_size)
+ , m_maxTileSize(other.m_maxTileSize)
+ , m_numColumns(other.m_numColumns)
+ , m_tiles(other.m_tiles)
+{
+ detachTiles();
+}
+
+TiledImageOpenVG& TiledImageOpenVG::operator=(const TiledImageOpenVG& other)
+{
+ if (&other != this) {
+ destroyTiles();
+
+ m_size = other.m_size;
+ m_maxTileSize = other.m_maxTileSize;
+ m_numColumns = other.m_numColumns;
+ m_tiles = other.m_tiles;
+
+ detachTiles();
+ }
+ return *this;
+}
+
+TiledImageOpenVG::~TiledImageOpenVG()
+{
+ destroyTiles();
+}
+
+int TiledImageOpenVG::numTiles() const
+{
+ return m_tiles.size();
+}
+
+int TiledImageOpenVG::numColumns() const
+{
+ return m_numColumns;
+}
+
+int TiledImageOpenVG::numRows() const
+{
+ return m_tiles.size() / m_numColumns;
+}
+
+void TiledImageOpenVG::setTile(int xIndex, int yIndex, VGImage image)
+{
+ ASSERT(xIndex < m_numColumns);
+ int i = (yIndex * m_numColumns) + xIndex;
+ ASSERT(i < m_tiles.size());
+ m_tiles.at(i) = image;
+}
+
+IntRect TiledImageOpenVG::tilesInRect(const FloatRect& rect) const
+{
+ int leftIndex = static_cast<int>(rect.x()) / m_maxTileSize.width();
+ int topIndex = static_cast<int>(rect.y()) / m_maxTileSize.height();
+
+ if (leftIndex < 0)
+ leftIndex = 0;
+ if (topIndex < 0)
+ topIndex = 0;
+
+ // Round rect edges up to get the outer pixel boundaries.
+ int rightIndex = (static_cast<int>(ceil(rect.right())) - 1) / m_maxTileSize.width();
+ int bottomIndex = (static_cast<int>(ceil(rect.bottom())) - 1) / m_maxTileSize.height();
+ int columns = (rightIndex - leftIndex) + 1;
+ int rows = (bottomIndex - topIndex) + 1;
+
+ return IntRect(leftIndex, topIndex,
+ (columns <= m_numColumns) ? columns : m_numColumns,
+ (rows <= (m_tiles.size() / m_numColumns)) ? rows : (m_tiles.size() / m_numColumns));
+}
+
+VGImage TiledImageOpenVG::tile(int xIndex, int yIndex) const
+{
+ ASSERT(xIndex < m_numColumns);
+ int i = (yIndex * m_numColumns) + xIndex;
+ ASSERT(i < m_tiles.size());
+ return m_tiles.at(i);
+}
+
+IntRect TiledImageOpenVG::tileRect(int xIndex, int yIndex) const
+{
+ ASSERT(xIndex < m_numColumns);
+ ASSERT((yIndex * m_numColumns) + xIndex < m_tiles.size());
+
+ int x = xIndex * m_maxTileSize.width();
+ int y = yIndex * m_maxTileSize.height();
+
+ return IntRect(x, y,
+ ((m_maxTileSize.width() < m_size.width() - x) ? m_maxTileSize.width() : (m_size.width() - x)),
+ ((m_maxTileSize.height() < m_size.height() - y) ? m_maxTileSize.height() : (m_size.height() - y)));
+}
+
+void TiledImageOpenVG::detachTiles()
+{
+ makeSharedContextCurrent(); // because we create new images
+
+ int numTiles = m_tiles.size();
+ VGImage newTile, originalTile;
+
+ for (int i = 0; i < numTiles; ++i) {
+ originalTile = m_tiles.at(i);
+
+ if (originalTile == VG_INVALID_HANDLE)
+ continue;
+
+ VGImageFormat format = (VGImageFormat) vgGetParameteri(originalTile, VG_IMAGE_FORMAT);
+ VGint width = vgGetParameteri(originalTile, VG_IMAGE_WIDTH);
+ VGint height = vgGetParameteri(originalTile, VG_IMAGE_HEIGHT);
+ ASSERT_VG_NO_ERROR();
+
+ newTile = vgCreateImage(format, width, height, VG_IMAGE_QUALITY_FASTER);
+ ASSERT_VG_NO_ERROR();
+
+ vgCopyImage(newTile, 0, 0, originalTile, 0, 0, width, height, VG_FALSE /* dither */);
+ ASSERT_VG_NO_ERROR();
+
+ m_tiles.at(i) = newTile;
+ }
+}
+
+void TiledImageOpenVG::destroyTiles()
+{
+ makeCompatibleContextCurrent();
+
+ Vector<VGImage>::const_iterator it = m_tiles.begin();
+ Vector<VGImage>::const_iterator end = m_tiles.end();
+
+ for (; it != end; ++it) {
+ if (*it != VG_INVALID_HANDLE)
+ vgDestroyImage(*it);
+ }
+ ASSERT_VG_NO_ERROR();
+
+ m_tiles.fill(VG_INVALID_HANDLE);
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/TiledImageOpenVG.h b/WebCore/platform/graphics/openvg/TiledImageOpenVG.h
new file mode 100644
index 0000000..c8f55d2
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/TiledImageOpenVG.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 TiledImageOpenVG_h
+#define TiledImageOpenVG_h
+
+#include "IntRect.h"
+#include "IntSize.h"
+#include "SharedResourceOpenVG.h"
+
+#include <openvg.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FloatRect;
+
+class TiledImageOpenVG : public SharedResourceOpenVG {
+public:
+ TiledImageOpenVG(const IntSize& size, const IntSize& tileSize);
+ TiledImageOpenVG(const TiledImageOpenVG&);
+ ~TiledImageOpenVG();
+
+ TiledImageOpenVG& operator=(const TiledImageOpenVG&);
+
+ const IntSize& size() const { return m_size; }
+ const IntSize& maxTileSize() const { return m_maxTileSize; }
+
+ int numTiles() const;
+ int numColumns() const;
+ int numRows() const;
+
+ IntRect tilesInRect(const FloatRect&) const;
+
+ void setTile(int xIndex, int yIndex, VGImage);
+ VGImage tile(int xIndex, int yIndex) const;
+ IntRect tileRect(int xIndex, int yIndex) const;
+
+private:
+ void detachTiles();
+ void destroyTiles();
+
+ IntSize m_size;
+ IntSize m_maxTileSize;
+
+ int m_numColumns;
+
+ Vector<VGImage> m_tiles;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/openvg/VGUtils.cpp b/WebCore/platform/graphics/openvg/VGUtils.cpp
index ce9bcd2..2559aaf 100644
--- a/WebCore/platform/graphics/openvg/VGUtils.cpp
+++ b/WebCore/platform/graphics/openvg/VGUtils.cpp
@@ -120,4 +120,116 @@ FloatRect::operator VGRect() const
return VGRect(*this);
}
+int VGUtils::bytesForImage(VGImageFormat format, VGint width, VGint height)
+{
+ return width * height * imageFormatBitsPerPixel(format) / 8;
+}
+
+int VGUtils::bytesForImageScanline(VGImageFormat format, VGint width)
+{
+ int bits = width * imageFormatBitsPerPixel(format);
+ if (bits % 8 > 1) // If unaligned, round up to the next byte.
+ bits += 8 - (bits % 8);
+
+ return bits / 8;
+}
+
+int VGUtils::imageFormatBitsPerPixel(VGImageFormat format)
+{
+ switch (format) {
+ case VG_sRGBX_8888:
+ case VG_sRGBA_8888:
+ case VG_sRGBA_8888_PRE:
+ case VG_lRGBX_8888:
+ case VG_lRGBA_8888:
+ case VG_lRGBA_8888_PRE:
+ case VG_sXRGB_8888:
+ case VG_sARGB_8888:
+ case VG_sARGB_8888_PRE:
+ case VG_lXRGB_8888:
+ case VG_lARGB_8888:
+ case VG_lARGB_8888_PRE:
+ case VG_sBGRX_8888:
+ case VG_sBGRA_8888:
+ case VG_sBGRA_8888_PRE:
+ case VG_lBGRX_8888:
+ case VG_lBGRA_8888:
+ case VG_lBGRA_8888_PRE:
+ case VG_sXBGR_8888:
+ case VG_sABGR_8888:
+ case VG_sABGR_8888_PRE:
+ case VG_lXBGR_8888:
+ case VG_lABGR_8888:
+ case VG_lABGR_8888_PRE:
+ return 32;
+
+ case VG_sRGB_565:
+ case VG_sRGBA_5551:
+ case VG_sRGBA_4444:
+ case VG_sARGB_1555:
+ case VG_sARGB_4444:
+ case VG_sBGR_565:
+ case VG_sBGRA_5551:
+ case VG_sBGRA_4444:
+ case VG_sABGR_1555:
+ case VG_sABGR_4444:
+ return 16;
+
+ case VG_sL_8:
+ case VG_lL_8:
+ case VG_A_8:
+ return 8;
+
+ case VG_A_4:
+ return 4;
+
+ case VG_BW_1:
+ case VG_A_1:
+ return 1;
+
+ default: // Will only happen when OpenVG extends the enum and we don't.
+ ASSERT(false);
+ return 0;
+ }
+}
+
+#ifndef WTF_PLATFORM_BIG_ENDIAN
+VGImageFormat VGUtils::endianAwareImageFormat(VGImageFormat bigEndianFormat)
+{
+ switch (bigEndianFormat) {
+ case VG_sRGBX_8888: return VG_sXBGR_8888;
+ case VG_sRGBA_8888: return VG_sABGR_8888;
+ case VG_sRGBA_8888_PRE: return VG_sABGR_8888_PRE;
+ case VG_lRGBX_8888: return VG_lXBGR_8888;
+ case VG_lRGBA_8888: return VG_lABGR_8888;
+ case VG_lRGBA_8888_PRE: return VG_lABGR_8888_PRE;
+ case VG_sXRGB_8888: return VG_sBGRX_8888;
+ case VG_sARGB_8888: return VG_sBGRA_8888;
+ case VG_sARGB_8888_PRE: return VG_sBGRA_8888_PRE;
+ case VG_lXRGB_8888: return VG_lBGRX_8888;
+ case VG_lARGB_8888: return VG_lBGRA_8888;
+ case VG_lARGB_8888_PRE: return VG_lBGRA_8888_PRE;
+ case VG_sBGRX_8888: return VG_sXRGB_8888;
+ case VG_sBGRA_8888: return VG_sARGB_8888;
+ case VG_sBGRA_8888_PRE: return VG_sARGB_8888_PRE;
+ case VG_lBGRX_8888: return VG_lXRGB_8888;
+ case VG_lBGRA_8888: return VG_lARGB_8888;
+ case VG_lBGRA_8888_PRE: return VG_lARGB_8888_PRE;
+ case VG_sXBGR_8888: return VG_sRGBX_8888;
+ case VG_sABGR_8888: return VG_sRGBA_8888;
+ case VG_sABGR_8888_PRE: return VG_sRGBA_8888_PRE;
+ case VG_lXBGR_8888: return VG_lRGBX_8888;
+ case VG_lABGR_8888: return VG_lRGBA_8888;
+ case VG_lABGR_8888_PRE: return VG_lRGBA_8888_PRE;
+ default: ASSERT(false);
+ return (VGImageFormat) 0;
+ }
+}
+#else
+VGImageFormat VGUtils::endianAwareImageFormat(VGImageFormat bigEndianFormat)
+{
+ return bigEndianFormat;
+}
+#endif
+
}
diff --git a/WebCore/platform/graphics/openvg/VGUtils.h b/WebCore/platform/graphics/openvg/VGUtils.h
index 3a290cb..06d5fea 100644
--- a/WebCore/platform/graphics/openvg/VGUtils.h
+++ b/WebCore/platform/graphics/openvg/VGUtils.h
@@ -85,6 +85,31 @@ private:
VGfloat m_data[4];
};
+class VGUtils {
+public:
+ static int bytesForImage(VGImageFormat, VGint width, VGint height);
+ static int bytesForImageScanline(VGImageFormat, VGint width);
+ static int imageFormatBitsPerPixel(VGImageFormat);
+
+ /**
+ * Return a flipped VGImageFormat if the platform is little endian
+ * (e.g. VG_ABGR_8888 for a given VG_RGBA_8888), or return the image format
+ * as is if the platform is big endian.
+ *
+ * OpenVG itself is indifferent to endianness, it will always work on a
+ * single machine word with the bytes going from left to right as specified
+ * in the image format, no matter which one of the bytes is most or least
+ * significant.
+ *
+ * However, if you interface with vgImageSubData()/vgGetImageSubData()
+ * using a byte array then you want to make sure the byte order is
+ * appropriate for the given platform (otherwise the byte indexes need
+ * to be swapped depending on endianness). So, use this function when
+ * interfacing with byte arrays, and don't use it otherwise.
+ */
+ static VGImageFormat endianAwareImageFormat(VGImageFormat bigEndianFormat);
+};
+
}
#endif
diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index 8dfb967..ad43908 100644
--- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -28,17 +28,17 @@
#include "NotImplemented.h"
#include "QWebPageClient.h"
#include "WebGLActiveInfo.h"
-#include "WebGLArray.h"
+#include "ArrayBufferView.h"
#include "WebGLBuffer.h"
-#include "WebGLFloatArray.h"
+#include "FloatArray.h"
#include "WebGLFramebuffer.h"
-#include "WebGLIntArray.h"
+#include "Int32Array.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
#include "WebGLRenderingContext.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
-#include "WebGLUnsignedByteArray.h"
+#include "Uint8Array.h"
#include <QAbstractScrollArea>
#include <wtf/UnusedParam.h>
#include <wtf/text/CString.h>
@@ -671,7 +671,7 @@ void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long
m_internal->bufferData(target, size, /* data */ 0, usage);
}
-void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsigned long usage)
+void GraphicsContext3D::bufferData(unsigned long target, ArrayBufferView* array, unsigned long usage)
{
if (!array || !array->length())
return;
@@ -680,7 +680,7 @@ void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsi
m_internal->bufferData(target, array->byteLength(), array->baseAddress(), usage);
}
-void GraphicsContext3D::bufferSubData(unsigned long target, long offset, WebGLArray* array)
+void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBufferView* array)
{
if (!array || !array->length())
return;
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
index 86c01de..aac1164 100644
--- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -364,14 +364,6 @@ void GraphicsLayerQtImpl::updateTransform()
return;
}
- // Simplistic depth test - we stack the item behind its parent if its computed z is lower than the parent's computed z at the item's center point.
- if (parent) {
- const QPointF centerPointMappedToRoot = rootLayer()->mapFromItem(this, m_size.width() / 2, m_size.height() / 2);
- setFlag(ItemStacksBehindParent,
- m_transformRelativeToRootLayer.mapPoint(FloatPoint3D(centerPointMappedToRoot.x(), centerPointMappedToRoot.y(), 0)).z() <
- parent->m_transformRelativeToRootLayer.mapPoint(FloatPoint3D(centerPointMappedToRoot.x(), centerPointMappedToRoot.y(), 0)).z());
- }
-
// The item is front-facing or backface-visibility is on.
setVisible(true);
@@ -629,8 +621,10 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
if (m_maskEffect)
m_maskEffect.data()->update();
else if (m_changeMask & DisplayChange) {
- // Recache now: all the content is ready and we don't want to wait until the paint event.
- recache(m_pendingContent.regionToUpdate);
+ // Recache now: all the content is ready and we don't want to wait until the paint event. We only need to do this for HTML content,
+ // there's no point in caching directly composited content like images or solid rectangles.
+ if (m_pendingContent.contentType == HTMLContentType)
+ recache(m_pendingContent.regionToUpdate);
update(m_pendingContent.regionToUpdate.boundingRect());
m_pendingContent.regionToUpdate = QRegion();
}
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index b1bfbdd..21ba934 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -346,10 +346,19 @@ void Image::drawPattern(GraphicsContext* context,
if (resampling == RESAMPLE_AWESOME) {
// Do nice resampling.
- SkBitmap resampled = skia::ImageOperations::Resize(srcSubset,
- skia::ImageOperations::RESIZE_LANCZOS3,
- static_cast<int>(destBitmapWidth),
- static_cast<int>(destBitmapHeight));
+ SkBitmap resampled;
+ int width = static_cast<int>(destBitmapWidth);
+ int height = static_cast<int>(destBitmapHeight);
+ if (!srcRect.fLeft && !srcRect.fTop
+ && srcRect.fRight == bitmap->width() && srcRect.fBottom == bitmap->height()
+ && (bitmap->hasResizedBitmap(width, height)
+ || bitmap->shouldCacheResampling(width, height, width, height))) {
+ // resizedBitmap() caches resized image.
+ resampled = bitmap->resizedBitmap(width, height);
+ } else {
+ resampled = skia::ImageOperations::Resize(srcSubset,
+ skia::ImageOperations::RESIZE_LANCZOS3, width, height);
+ }
shader = SkShader::CreateBitmapShader(resampled, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
// Since we just resized the bitmap, we need to undo the scale set in
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
new file mode 100644
index 0000000..87625d3
--- /dev/null
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
@@ -0,0 +1,968 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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)
+#include "MediaPlayerPrivateQuickTimeVisualContext.h"
+
+#include "Cookie.h"
+#include "CookieJar.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "KURL.h"
+#include "MediaPlayerPrivateTaskTimer.h"
+#include "QTCFDictionary.h"
+#include "QTMovie.h"
+#include "QTMovieTask.h"
+#include "QTMovieVisualContext.h"
+#include "ScrollView.h"
+#include "SoftLinking.h"
+#include "StringBuilder.h"
+#include "StringHash.h"
+#include "TimeRanges.h"
+#include "Timer.h"
+#include <Wininet.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/HashSet.h>
+#include <wtf/MainThread.h>
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "GraphicsLayerCACF.h"
+#include "WKCACFLayer.h"
+#endif
+
+using namespace std;
+
+const CFStringRef kMinQuartzCoreVersion = CFSTR("1.0.43.0");
+const CFStringRef kMinCoreVideoVersion = CFSTR("1.0.0.2");
+
+namespace WebCore {
+
+SOFT_LINK_LIBRARY(Wininet)
+SOFT_LINK(Wininet, InternetSetCookieExW, DWORD, WINAPI, (LPCWSTR lpszUrl, LPCWSTR lpszCookieName, LPCWSTR lpszCookieData, DWORD dwFlags, DWORD_PTR dwReserved), (lpszUrl, lpszCookieName, lpszCookieData, dwFlags, dwReserved))
+
+// Interface declaration for MediaPlayerPrivateQuickTimeVisualContext's QTMovieClient aggregate
+class MediaPlayerPrivateQuickTimeVisualContext::MovieClient : public QTMovieClient {
+public:
+ MovieClient(MediaPlayerPrivateQuickTimeVisualContext* parent) : m_parent(parent) {}
+ virtual ~MovieClient() { m_parent = 0; }
+ virtual void movieEnded(QTMovie*);
+ virtual void movieLoadStateChanged(QTMovie*);
+ virtual void movieTimeChanged(QTMovie*);
+private:
+ MediaPlayerPrivateQuickTimeVisualContext* m_parent;
+};
+
+#if USE(ACCELERATED_COMPOSITING)
+// Interface declaration for MediaPlayerPrivateQuickTimeVisualContext's GraphicsLayerClient aggregate
+class MediaPlayerPrivateQuickTimeVisualContext::LayerClient : public GraphicsLayerClient {
+public:
+ LayerClient(MediaPlayerPrivateQuickTimeVisualContext* parent) : m_parent(parent) {}
+ virtual ~LayerClient() { m_parent = 0; }
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip);
+ virtual void notifyAnimationStarted(const GraphicsLayer*, double time) { }
+ virtual void notifySyncRequired(const GraphicsLayer*) { }
+ virtual bool showDebugBorders() const { return false; }
+ virtual bool showRepaintCounter() const { return false; }
+private:
+ MediaPlayerPrivateQuickTimeVisualContext* m_parent;
+};
+#endif
+
+class MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient : public QTMovieVisualContextClient {
+public:
+ VisualContextClient(MediaPlayerPrivateQuickTimeVisualContext* parent) : m_parent(parent) {}
+ virtual ~VisualContextClient() { m_parent = 0; }
+ void imageAvailableForTime(const QTCVTimeStamp*);
+ static void retrieveCurrentImageProc(void*);
+private:
+ MediaPlayerPrivateQuickTimeVisualContext* m_parent;
+};
+
+MediaPlayerPrivateInterface* MediaPlayerPrivateQuickTimeVisualContext::create(MediaPlayer* player)
+{
+ return new MediaPlayerPrivateQuickTimeVisualContext(player);
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::registerMediaEngine(MediaEngineRegistrar registrar)
+{
+ if (isAvailable())
+ registrar(create, getSupportedTypes, supportsType);
+}
+
+MediaPlayerPrivateQuickTimeVisualContext::MediaPlayerPrivateQuickTimeVisualContext(MediaPlayer* player)
+ : m_player(player)
+ , m_seekTo(-1)
+ , m_seekTimer(this, &MediaPlayerPrivateQuickTimeVisualContext::seekTimerFired)
+ , m_visualContextTimer(this, &MediaPlayerPrivateQuickTimeVisualContext::visualContextTimerFired)
+ , m_networkState(MediaPlayer::Empty)
+ , m_readyState(MediaPlayer::HaveNothing)
+ , m_enabledTrackCount(0)
+ , m_totalTrackCount(0)
+ , m_hasUnsupportedTracks(false)
+ , m_startedPlaying(false)
+ , m_isStreaming(false)
+ , m_visible(false)
+ , m_newFrameAvailable(false)
+ , m_movieClient(new MediaPlayerPrivateQuickTimeVisualContext::MovieClient(this))
+#if USE(ACCELERATED_COMPOSITING)
+ , m_layerClient(new MediaPlayerPrivateQuickTimeVisualContext::LayerClient(this))
+#endif
+ , m_visualContextClient(new MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient(this))
+{
+}
+
+MediaPlayerPrivateQuickTimeVisualContext::~MediaPlayerPrivateQuickTimeVisualContext()
+{
+ tearDownVideoRendering();
+ cancelCallOnMainThread(&VisualContextClient::retrieveCurrentImageProc, this);
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::supportsFullscreen() const
+{
+ return true;
+}
+
+PlatformMedia MediaPlayerPrivateQuickTimeVisualContext::platformMedia() const
+{
+ PlatformMedia p;
+ p.type = PlatformMedia::QTMovieVisualContextType;
+ p.media.qtMovieVisualContext = m_visualContext.get();
+ return p;
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+PlatformLayer* MediaPlayerPrivateQuickTimeVisualContext::platformLayer() const
+{
+ return m_qtVideoLayer ? m_qtVideoLayer->platformLayer() : 0;
+}
+#endif
+
+String MediaPlayerPrivateQuickTimeVisualContext::rfc2616DateStringFromTime(CFAbsoluteTime time)
+{
+ static const char* const dayStrings[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+ static const char* const monthStrings[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+ static const CFStringRef dateFormatString = CFSTR("%s, %02d %s %04d %02d:%02d:%02d GMT");
+ static CFTimeZoneRef gmtTimeZone;
+ if (!gmtTimeZone)
+ gmtTimeZone = CFTimeZoneCopyDefault();
+
+ CFGregorianDate dateValue = CFAbsoluteTimeGetGregorianDate(time, gmtTimeZone);
+ if (!CFGregorianDateIsValid(dateValue, kCFGregorianAllUnits))
+ return String();
+
+ time = CFGregorianDateGetAbsoluteTime(dateValue, gmtTimeZone);
+ SInt32 day = CFAbsoluteTimeGetDayOfWeek(time, 0);
+
+ RetainPtr<CFStringRef> dateCFString(AdoptCF, CFStringCreateWithFormat(0, 0, dateFormatString, dayStrings[day - 1], dateValue.day,
+ monthStrings[dateValue.month - 1], dateValue.year, dateValue.hour, dateValue.minute, (int)dateValue.second));
+ return dateCFString.get();
+}
+
+static void addCookieParam(StringBuilder& cookieBuilder, const String& name, const String& value)
+{
+ if (name.isEmpty())
+ return;
+
+ // If this isn't the first parameter added, terminate the previous one.
+ if (cookieBuilder.length())
+ cookieBuilder.append("; ");
+
+ // Add parameter name, and value if there is one.
+ cookieBuilder.append(name);
+ if (!value.isEmpty()) {
+ cookieBuilder.append("=");
+ cookieBuilder.append(value);
+ }
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::setUpCookiesForQuickTime(const String& url)
+{
+ // WebCore loaded the page with the movie URL with CFNetwork but QuickTime will
+ // use WinINet to download the movie, so we need to copy any cookies needed to
+ // download the movie into WinInet before asking QuickTime to open it.
+ Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : 0;
+ if (!frame || !frame->page() || !frame->page()->cookieEnabled())
+ return;
+
+ KURL movieURL = KURL(KURL(), url);
+ Vector<Cookie> documentCookies;
+ if (!getRawCookies(frame->document(), movieURL, documentCookies))
+ return;
+
+ for (size_t ndx = 0; ndx < documentCookies.size(); ndx++) {
+ const Cookie& cookie = documentCookies[ndx];
+
+ if (cookie.name.isEmpty())
+ continue;
+
+ // Build up the cookie string with as much information as we can get so WinINet
+ // knows what to do with it.
+ StringBuilder cookieBuilder;
+ addCookieParam(cookieBuilder, cookie.name, cookie.value);
+ addCookieParam(cookieBuilder, "path", cookie.path);
+ if (cookie.expires)
+ addCookieParam(cookieBuilder, "expires", rfc2616DateStringFromTime(cookie.expires));
+ if (cookie.httpOnly)
+ addCookieParam(cookieBuilder, "httpOnly", String());
+ cookieBuilder.append(";");
+
+ String cookieURL;
+ if (!cookie.domain.isEmpty()) {
+ StringBuilder urlBuilder;
+
+ urlBuilder.append(movieURL.protocol());
+ urlBuilder.append("://");
+ if (cookie.domain[0] == '.')
+ urlBuilder.append(cookie.domain.substring(1));
+ else
+ urlBuilder.append(cookie.domain);
+ if (cookie.path.length() > 1)
+ urlBuilder.append(cookie.path);
+
+ cookieURL = urlBuilder.toString();
+ } else
+ cookieURL = movieURL;
+
+ InternetSetCookieExW(cookieURL.charactersWithNullTermination(), 0, cookieBuilder.toString().charactersWithNullTermination(), 0, 0);
+ }
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::load(const String& url)
+{
+ if (!QTMovie::initializeQuickTime()) {
+ // FIXME: is this the right error to return?
+ m_networkState = MediaPlayer::DecodeError;
+ m_player->networkStateChanged();
+ return;
+ }
+
+ // Initialize the task timer.
+ MediaPlayerPrivateTaskTimer::initialize();
+
+ if (m_networkState != MediaPlayer::Loading) {
+ m_networkState = MediaPlayer::Loading;
+ m_player->networkStateChanged();
+ }
+ if (m_readyState != MediaPlayer::HaveNothing) {
+ m_readyState = MediaPlayer::HaveNothing;
+ m_player->readyStateChanged();
+ }
+ cancelSeek();
+
+ setUpCookiesForQuickTime(url);
+
+ m_movie = adoptRef(new QTMovie(m_movieClient.get()));
+ m_movie->load(url.characters(), url.length(), m_player->preservesPitch());
+ m_movie->setVolume(m_player->volume());
+
+ CFDictionaryRef options = QTMovieVisualContext::getCGImageOptions();
+ m_visualContext = adoptRef(new QTMovieVisualContext(m_visualContextClient.get(), options));
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::play()
+{
+ if (!m_movie)
+ return;
+ m_startedPlaying = true;
+
+ m_movie->play();
+ m_visualContextTimer.startRepeating(1.0 / 30);
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::pause()
+{
+ if (!m_movie)
+ return;
+ m_startedPlaying = false;
+
+ m_movie->pause();
+ m_visualContextTimer.stop();
+}
+
+float MediaPlayerPrivateQuickTimeVisualContext::duration() const
+{
+ if (!m_movie)
+ return 0;
+ return m_movie->duration();
+}
+
+float MediaPlayerPrivateQuickTimeVisualContext::currentTime() const
+{
+ if (!m_movie)
+ return 0;
+ return m_movie->currentTime();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::seek(float time)
+{
+ cancelSeek();
+
+ if (!m_movie)
+ return;
+
+ if (time > duration())
+ time = duration();
+
+ m_seekTo = time;
+ if (maxTimeLoaded() >= m_seekTo)
+ doSeek();
+ else
+ m_seekTimer.start(0, 0.5f);
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::doSeek()
+{
+ float oldRate = m_movie->rate();
+ if (oldRate)
+ m_movie->setRate(0);
+ m_movie->setCurrentTime(m_seekTo);
+ float timeAfterSeek = currentTime();
+ // restore playback only if not at end, othewise QTMovie will loop
+ if (oldRate && timeAfterSeek < duration())
+ m_movie->setRate(oldRate);
+ cancelSeek();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::cancelSeek()
+{
+ m_seekTo = -1;
+ m_seekTimer.stop();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::seekTimerFired(Timer<MediaPlayerPrivateQuickTimeVisualContext>*)
+{
+ if (!m_movie || !seeking() || currentTime() == m_seekTo) {
+ cancelSeek();
+ updateStates();
+ m_player->timeChanged();
+ return;
+ }
+
+ if (maxTimeLoaded() >= m_seekTo)
+ doSeek();
+ else {
+ MediaPlayer::NetworkState state = networkState();
+ if (state == MediaPlayer::Empty || state == MediaPlayer::Loaded) {
+ cancelSeek();
+ updateStates();
+ m_player->timeChanged();
+ }
+ }
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::paused() const
+{
+ if (!m_movie)
+ return true;
+ return (!m_movie->rate());
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::seeking() const
+{
+ if (!m_movie)
+ return false;
+ return m_seekTo >= 0;
+}
+
+IntSize MediaPlayerPrivateQuickTimeVisualContext::naturalSize() const
+{
+ if (!m_movie)
+ return IntSize();
+ int width;
+ int height;
+ m_movie->getNaturalSize(width, height);
+ return IntSize(width, height);
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::hasVideo() const
+{
+ if (!m_movie)
+ return false;
+ return m_movie->hasVideo();
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::hasAudio() const
+{
+ if (!m_movie)
+ return false;
+ return m_movie->hasAudio();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::setVolume(float volume)
+{
+ if (!m_movie)
+ return;
+ m_movie->setVolume(volume);
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::setRate(float rate)
+{
+ if (!m_movie)
+ return;
+
+ // Do not call setRate(...) unless we have started playing; otherwise
+ // QuickTime's VisualContext can get wedged waiting for a rate change
+ // call which will never come.
+ if (m_startedPlaying)
+ m_movie->setRate(rate);
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::setPreservesPitch(bool preservesPitch)
+{
+ if (!m_movie)
+ return;
+ m_movie->setPreservesPitch(preservesPitch);
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::hasClosedCaptions() const
+{
+ if (!m_movie)
+ return false;
+ return m_movie->hasClosedCaptions();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::setClosedCaptionsVisible(bool visible)
+{
+ if (!m_movie)
+ return;
+ m_movie->setClosedCaptionsVisible(visible);
+}
+
+PassRefPtr<TimeRanges> MediaPlayerPrivateQuickTimeVisualContext::buffered() const
+{
+ RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+ float loaded = maxTimeLoaded();
+ // rtsp streams are not buffered
+ if (!m_isStreaming && loaded > 0)
+ timeRanges->add(0, loaded);
+ return timeRanges.release();
+}
+
+float MediaPlayerPrivateQuickTimeVisualContext::maxTimeSeekable() const
+{
+ // infinite duration means live stream
+ return !isfinite(duration()) ? 0 : maxTimeLoaded();
+}
+
+float MediaPlayerPrivateQuickTimeVisualContext::maxTimeLoaded() const
+{
+ if (!m_movie)
+ return 0;
+ return m_movie->maxTimeLoaded();
+}
+
+unsigned MediaPlayerPrivateQuickTimeVisualContext::bytesLoaded() const
+{
+ if (!m_movie)
+ return 0;
+ float dur = duration();
+ float maxTime = maxTimeLoaded();
+ if (!dur)
+ return 0;
+ return totalBytes() * maxTime / dur;
+}
+
+unsigned MediaPlayerPrivateQuickTimeVisualContext::totalBytes() const
+{
+ if (!m_movie)
+ return 0;
+ return m_movie->dataSize();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::cancelLoad()
+{
+ if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)
+ return;
+
+ tearDownVideoRendering();
+
+ // Cancel the load by destroying the movie.
+ m_movie.clear();
+
+ updateStates();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::updateStates()
+{
+ MediaPlayer::NetworkState oldNetworkState = m_networkState;
+ MediaPlayer::ReadyState oldReadyState = m_readyState;
+
+ long loadState = m_movie ? m_movie->loadState() : QTMovieLoadStateError;
+
+ if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata) {
+ m_movie->disableUnsupportedTracks(m_enabledTrackCount, m_totalTrackCount);
+ if (m_player->inMediaDocument()) {
+ if (!m_enabledTrackCount || m_enabledTrackCount != m_totalTrackCount) {
+ // This is a type of media that we do not handle directly with a <video>
+ // element, eg. QuickTime VR, a movie with a sprite track, etc. Tell the
+ // MediaPlayerClient that we won't support it.
+ sawUnsupportedTracks();
+ return;
+ }
+ } else if (!m_enabledTrackCount)
+ loadState = QTMovieLoadStateError;
+ }
+
+ // "Loaded" is reserved for fully buffered movies, never the case when streaming
+ if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) {
+ m_networkState = MediaPlayer::Loaded;
+ m_readyState = MediaPlayer::HaveEnoughData;
+ } else if (loadState >= QTMovieLoadStatePlaythroughOK) {
+ m_readyState = MediaPlayer::HaveEnoughData;
+ } else if (loadState >= QTMovieLoadStatePlayable) {
+ // FIXME: This might not work correctly in streaming case, <rdar://problem/5693967>
+ m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
+ } else if (loadState >= QTMovieLoadStateLoaded) {
+ m_readyState = MediaPlayer::HaveMetadata;
+ } else if (loadState > QTMovieLoadStateError) {
+ m_networkState = MediaPlayer::Loading;
+ m_readyState = MediaPlayer::HaveNothing;
+ } else {
+ if (m_player->inMediaDocument()) {
+ // Something went wrong in the loading of media within a standalone file.
+ // This can occur with chained ref movies that eventually resolve to a
+ // file we don't support.
+ sawUnsupportedTracks();
+ return;
+ }
+
+ float loaded = maxTimeLoaded();
+ if (!loaded)
+ m_readyState = MediaPlayer::HaveNothing;
+
+ if (!m_enabledTrackCount)
+ m_networkState = MediaPlayer::FormatError;
+ else {
+ // FIXME: We should differentiate between load/network errors and decode errors <rdar://problem/5605692>
+ if (loaded > 0)
+ m_networkState = MediaPlayer::DecodeError;
+ else
+ m_readyState = MediaPlayer::HaveNothing;
+ }
+ }
+
+ if (isReadyForRendering() && !hasSetUpVideoRendering())
+ setUpVideoRendering();
+
+ if (seeking())
+ m_readyState = MediaPlayer::HaveNothing;
+
+ if (m_networkState != oldNetworkState)
+ m_player->networkStateChanged();
+ if (m_readyState != oldReadyState)
+ m_player->readyStateChanged();
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::isReadyForRendering() const
+{
+ return m_readyState >= MediaPlayer::HaveMetadata && m_player->visible();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::sawUnsupportedTracks()
+{
+ m_movie->setDisabled(true);
+ m_hasUnsupportedTracks = true;
+ m_player->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_player);
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::didEnd()
+{
+ if (m_hasUnsupportedTracks)
+ return;
+
+ m_startedPlaying = false;
+
+ updateStates();
+ m_player->timeChanged();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::setSize(const IntSize& size)
+{
+ if (m_hasUnsupportedTracks || !m_movie || m_size == size)
+ return;
+ m_size = size;
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::setVisible(bool visible)
+{
+ if (m_hasUnsupportedTracks || !m_movie || m_visible == visible)
+ return;
+
+ m_visible = visible;
+ if (m_visible) {
+ if (isReadyForRendering())
+ setUpVideoRendering();
+ } else
+ tearDownVideoRendering();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::paint(GraphicsContext* p, const IntRect& r)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_qtVideoLayer)
+ return;
+#endif
+
+ paintCompleted(*p, r);
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::paintCompleted(GraphicsContext& context, const IntRect& rect)
+{
+ m_newFrameAvailable = false;
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient::retrieveCurrentImageProc(void* refcon)
+{
+ static_cast<MediaPlayerPrivateQuickTimeVisualContext*>(refcon)->retrieveCurrentImage();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient::imageAvailableForTime(const QTCVTimeStamp* timeStamp)
+{
+ // This call may come in on another thread, so marshall to the main thread first:
+ callOnMainThread(&retrieveCurrentImageProc, m_parent);
+
+ // callOnMainThread must be paired with cancelCallOnMainThread in the destructor,
+ // in case this object is deleted before the main thread request is handled.
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::visualContextTimerFired(Timer<MediaPlayerPrivateQuickTimeVisualContext>*)
+{
+ retrieveCurrentImage();
+}
+
+static CFDictionaryRef QTCFDictionaryCreateWithDataCallback(CFAllocatorRef allocator, const UInt8* bytes, CFIndex length)
+{
+ CFDataRef data = CFDataCreateWithBytesNoCopy(allocator, bytes, length, 0);
+ if (!data)
+ return 0;
+
+ return reinterpret_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(allocator, data, kCFPropertyListImmutable, 0));
+}
+
+static CGImageRef CreateCGImageFromPixelBuffer(QTPixelBuffer buffer)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ CGDataProviderRef provider = 0;
+ CGColorSpaceRef colorSpace = 0;
+ CGImageRef image = 0;
+
+ size_t bitsPerComponent = 0;
+ size_t bitsPerPixel = 0;
+ CGImageAlphaInfo alphaInfo = kCGImageAlphaNone;
+
+ if (buffer.pixelFormatIs32BGRA()) {
+ bitsPerComponent = 8;
+ bitsPerPixel = 32;
+ alphaInfo = (CGImageAlphaInfo)(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little);
+ } else if (buffer.pixelFormatIs32ARGB()) {
+ bitsPerComponent = 8;
+ bitsPerPixel = 32;
+ alphaInfo = (CGImageAlphaInfo)(kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big);
+ } else {
+ // All other pixel formats are currently unsupported:
+ ASSERT_NOT_REACHED();
+ }
+
+ CGDataProviderDirectAccessCallbacks callbacks = {
+ &QTPixelBuffer::dataProviderGetBytePointerCallback,
+ &QTPixelBuffer::dataProviderReleaseBytePointerCallback,
+ &QTPixelBuffer::dataProviderGetBytesAtPositionCallback,
+ &QTPixelBuffer::dataProviderReleaseInfoCallback,
+ };
+
+ // Colorspace should be device, so that Quartz does not have to do an extra render.
+ colorSpace = CGColorSpaceCreateDeviceRGB();
+ require(colorSpace, Bail);
+
+ provider = CGDataProviderCreateDirectAccess(buffer.pixelBufferRef(), buffer.dataSize(), &callbacks);
+ require(provider, Bail);
+
+ // CGDataProvider does not retain the buffer, but it will release it later, so do an extra retain here:
+ QTPixelBuffer::retainCallback(buffer.pixelBufferRef());
+
+ image = CGImageCreate(buffer.width(), buffer.height(), bitsPerComponent, bitsPerPixel, buffer.bytesPerRow(), colorSpace, alphaInfo, provider, 0, false, kCGRenderingIntentDefault);
+
+Bail:
+ // Once the image is created we can release our reference to the provider and the colorspace, they are retained by the image
+ if (provider)
+ CGDataProviderRelease(provider);
+ if (colorSpace)
+ CGColorSpaceRelease(colorSpace);
+
+ return image;
+#else
+ return 0;
+#endif
+}
+
+
+void MediaPlayerPrivateQuickTimeVisualContext::retrieveCurrentImage()
+{
+ if (!m_visualContext)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (!m_qtVideoLayer)
+ return;
+
+ QTPixelBuffer buffer = m_visualContext->imageForTime(0);
+ if (!buffer.pixelBufferRef())
+ return;
+
+ WKCACFLayer* layer = static_cast<WKCACFLayer*>(m_qtVideoLayer->platformLayer());
+
+ if (!buffer.lockBaseAddress()) {
+#ifndef NDEBUG
+ // Debug QuickTime links against a non-Debug version of CoreFoundation, so the CFDictionary attached to the CVPixelBuffer cannot be directly passed on into the CAImageQueue without being converted to a non-Debug CFDictionary:
+ CFDictionaryRef attachments = QTCFDictionaryCreateCopyWithDataCallback(kCFAllocatorDefault, buffer.attachments(), &QTCFDictionaryCreateWithDataCallback);
+#else
+ // However, this is unnecssesary in the non-Debug case:
+ CFDictionaryRef attachments = static_cast<CFDictionaryRef>(CFRetain(buffer.attachments()));
+#endif
+
+ CFTimeInterval imageTime = QTMovieVisualContext::currentHostTime();
+
+ CGImageRef image = CreateCGImageFromPixelBuffer(buffer);
+ layer->setContents(image);
+ CGImageRelease(image);
+
+ if (attachments)
+ CFRelease(attachments);
+
+ buffer.unlockBaseAddress();
+ layer->rootLayer()->setNeedsRender();
+ }
+ m_visualContext->task();
+#endif
+}
+
+static HashSet<String> mimeTypeCache()
+{
+ DEFINE_STATIC_LOCAL(HashSet<String>, typeCache, ());
+ static bool typeListInitialized = false;
+
+ if (!typeListInitialized) {
+ unsigned count = QTMovie::countSupportedTypes();
+ for (unsigned n = 0; n < count; n++) {
+ const UChar* character;
+ unsigned len;
+ QTMovie::getSupportedType(n, character, len);
+ if (len)
+ typeCache.add(String(character, len));
+ }
+
+ typeListInitialized = true;
+ }
+
+ return typeCache;
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::getSupportedTypes(HashSet<String>& types)
+{
+ types = mimeTypeCache();
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::isAvailable()
+{
+ return QTMovie::initializeQuickTime();
+}
+
+MediaPlayer::SupportsType MediaPlayerPrivateQuickTimeVisualContext::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 QT if it supports an
+ // extended MIME type
+ return mimeTypeCache().contains(type) ? (codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::MovieClient::movieEnded(QTMovie* movie)
+{
+ if (m_parent->m_hasUnsupportedTracks)
+ return;
+
+ m_parent->m_visualContextTimer.stop();
+
+ ASSERT(m_parent->m_movie.get() == movie);
+ m_parent->didEnd();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::MovieClient::movieLoadStateChanged(QTMovie* movie)
+{
+ if (m_parent->m_hasUnsupportedTracks)
+ return;
+
+ ASSERT(m_parent->m_movie.get() == movie);
+ m_parent->updateStates();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::MovieClient::movieTimeChanged(QTMovie* movie)
+{
+ if (m_parent->m_hasUnsupportedTracks)
+ return;
+
+ ASSERT(m_parent->m_movie.get() == movie);
+ m_parent->updateStates();
+ m_parent->m_player->timeChanged();
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::hasSingleSecurityOrigin() const
+{
+ // We tell quicktime to disallow resources that come from different origins
+ // so we all media is single origin.
+ return true;
+}
+
+MediaPlayerPrivateQuickTimeVisualContext::MediaRenderingMode MediaPlayerPrivateQuickTimeVisualContext::currentRenderingMode() const
+{
+ if (!m_movie)
+ return MediaRenderingNone;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_qtVideoLayer)
+ return MediaRenderingMovieLayer;
+#endif
+
+ return MediaRenderingSoftwareRenderer;
+}
+
+MediaPlayerPrivateQuickTimeVisualContext::MediaRenderingMode MediaPlayerPrivateQuickTimeVisualContext::preferredRenderingMode() const
+{
+ if (!m_player->frameView() || !m_movie)
+ return MediaRenderingNone;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player))
+ return MediaRenderingMovieLayer;
+#endif
+
+ return MediaRenderingSoftwareRenderer;
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::setUpVideoRendering()
+{
+ MediaRenderingMode currentMode = currentRenderingMode();
+ MediaRenderingMode preferredMode = preferredRenderingMode();
+
+#if !USE(ACCELERATED_COMPOSITING)
+ ASSERT(preferredMode != MediaRenderingMovieLayer);
+#endif
+
+ if (currentMode == preferredMode && currentMode != MediaRenderingNone)
+ return;
+
+ if (currentMode != MediaRenderingNone)
+ tearDownVideoRendering();
+
+ if (preferredMode == MediaRenderingMovieLayer)
+ createLayerForMovie();
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (currentMode == MediaRenderingMovieLayer || preferredMode == MediaRenderingMovieLayer)
+ m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player);
+#endif
+
+ m_visualContext->setMovie(m_movie.get());
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::tearDownVideoRendering()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_qtVideoLayer)
+ destroyLayerForMovie();
+#endif
+
+ m_visualContext->setMovie(0);
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::hasSetUpVideoRendering() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ return m_qtVideoLayer || currentRenderingMode() != MediaRenderingMovieLayer;
+#else
+ return true;
+#endif
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::createLayerForMovie()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ ASSERT(supportsAcceleratedRendering());
+
+ if (!m_movie || m_qtVideoLayer)
+ return;
+
+ // Create a GraphicsLayer that won't be inserted directly into the render tree, but will used
+ // as a wrapper for a WKCACFLayer which gets inserted as the content layer of the video
+ // renderer's GraphicsLayer.
+ m_qtVideoLayer.set(new GraphicsLayerCACF(m_layerClient.get()));
+ if (!m_qtVideoLayer)
+ return;
+
+ // Mark the layer as drawing itself, anchored in the top left, and bottom-up.
+ m_qtVideoLayer->setDrawsContent(true);
+ m_qtVideoLayer->setAnchorPoint(FloatPoint3D());
+ m_qtVideoLayer->setContentsOrientation(GraphicsLayer::CompositingCoordinatesBottomUp);
+#ifndef NDEBUG
+ m_qtVideoLayer->setName("Video layer");
+#endif
+ // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration().
+#endif
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::destroyLayerForMovie()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (!m_qtVideoLayer)
+ return;
+ m_qtVideoLayer = 0;
+#endif
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+void MediaPlayerPrivateQuickTimeVisualContext::LayerClient::paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip)
+{
+}
+
+bool MediaPlayerPrivateQuickTimeVisualContext::supportsAcceleratedRendering() const
+{
+ return isReadyForRendering();
+}
+
+void MediaPlayerPrivateQuickTimeVisualContext::acceleratedRenderingStateChanged()
+{
+ // Set up or change the rendering path if necessary.
+ setUpVideoRendering();
+}
+
+#endif
+
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h
new file mode 100644
index 0000000..12166a3
--- /dev/null
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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 MediaPlayerPrivateQuickTimeVisualContext_h
+#define MediaPlayerPrivateQuickTimeVisualContext_h
+
+#if ENABLE(VIDEO)
+
+#include "GraphicsLayer.h"
+#include "MediaPlayerPrivate.h"
+#include "Timer.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/RetainPtr.h>
+
+#ifndef DRAW_FRAME_RATE
+#define DRAW_FRAME_RATE 0
+#endif
+
+typedef struct CGImage *CGImageRef;
+class QTMovie;
+class QTMovieVisualContext;
+class WKCAImageQueue;
+
+namespace WebCore {
+
+class GraphicsContext;
+class IntSize;
+class IntRect;
+class String;
+
+class MediaPlayerPrivateQuickTimeVisualContext : public MediaPlayerPrivateInterface {
+public:
+ static void registerMediaEngine(MediaEngineRegistrar);
+
+ ~MediaPlayerPrivateQuickTimeVisualContext();
+
+private:
+ MediaPlayerPrivateQuickTimeVisualContext(MediaPlayer*);
+
+ virtual bool supportsFullscreen() const;
+ virtual PlatformMedia platformMedia() const;
+#if USE(ACCELERATED_COMPOSITING)
+ PlatformLayer* platformLayer() const;
+#endif
+ IntSize naturalSize() const;
+ bool hasVideo() const;
+ bool hasAudio() const;
+
+ void load(const String& url);
+ void cancelLoad();
+
+ void play();
+ void pause();
+
+ bool paused() const;
+ bool seeking() const;
+
+ float duration() const;
+ float currentTime() const;
+ void seek(float time);
+
+ void setRate(float);
+ void setVolume(float);
+ void setPreservesPitch(bool);
+
+ MediaPlayer::NetworkState networkState() const { return m_networkState; }
+ MediaPlayer::ReadyState readyState() const { return m_readyState; }
+
+ PassRefPtr<TimeRanges> buffered() const;
+ float maxTimeSeekable() const;
+ unsigned bytesLoaded() const;
+ unsigned totalBytes() const;
+
+ void setVisible(bool);
+ void setSize(const IntSize&);
+
+ void loadStateChanged();
+ void didEnd();
+
+ void paint(GraphicsContext*, const IntRect&);
+ void paintCompleted(GraphicsContext&, const IntRect&);
+
+ bool hasSingleSecurityOrigin() const;
+
+ bool hasClosedCaptions() const;
+ void setClosedCaptionsVisible(bool);
+
+ void updateStates();
+ void doSeek();
+ void cancelSeek();
+ void seekTimerFired(Timer<MediaPlayerPrivateQuickTimeVisualContext>*);
+ float maxTimeLoaded() const;
+ void sawUnsupportedTracks();
+
+ // engine support
+ static MediaPlayerPrivateInterface* create(MediaPlayer*);
+ static void getSupportedTypes(HashSet<String>& types);
+ static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
+ static bool isAvailable();
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool supportsAcceleratedRendering() const;
+ virtual void acceleratedRenderingStateChanged();
+#endif
+
+ enum MediaRenderingMode { MediaRenderingNone, MediaRenderingSoftwareRenderer, MediaRenderingMovieLayer };
+ MediaRenderingMode currentRenderingMode() const;
+ MediaRenderingMode preferredRenderingMode() const;
+ bool isReadyForRendering() const;
+
+ void setUpVideoRendering();
+ void tearDownVideoRendering();
+ bool hasSetUpVideoRendering() const;
+
+ void createLayerForMovie();
+ void destroyLayerForMovie();
+
+ void setUpCookiesForQuickTime(const String& url);
+ String rfc2616DateStringFromTime(CFAbsoluteTime);
+
+ void visualContextTimerFired(Timer<MediaPlayerPrivateQuickTimeVisualContext>*);
+ void retrieveCurrentImage();
+
+ class MovieClient;
+ friend class MovieClient;
+ OwnPtr<MovieClient> m_movieClient;
+
+#if USE(ACCELERATED_COMPOSITING)
+ class LayerClient;
+ friend class LayerClient;
+ OwnPtr<LayerClient> m_layerClient;
+#endif
+
+ class VisualContextClient;
+ friend class VisualContextClient;
+ OwnPtr<VisualContextClient> m_visualContextClient;
+
+ MediaPlayer* m_player;
+ RefPtr<QTMovie> m_movie;
+#if USE(ACCELERATED_COMPOSITING)
+ OwnPtr<GraphicsLayer> m_qtVideoLayer;
+#endif
+ RefPtr<QTMovieVisualContext> m_visualContext;
+ float m_seekTo;
+ Timer<MediaPlayerPrivateQuickTimeVisualContext> m_seekTimer;
+ Timer<MediaPlayerPrivateQuickTimeVisualContext> m_visualContextTimer;
+ IntSize m_size;
+ MediaPlayer::NetworkState m_networkState;
+ MediaPlayer::ReadyState m_readyState;
+ unsigned m_enabledTrackCount;
+ unsigned m_totalTrackCount;
+ bool m_hasUnsupportedTracks;
+ bool m_startedPlaying;
+ bool m_isStreaming;
+ bool m_visible;
+ bool m_newFrameAvailable;
+#if DRAW_FRAME_RATE
+ double m_frameCountWhilePlaying;
+ double m_timeStartedPlaying;
+ double m_timeStoppedPlaying;
+#endif
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
index c848eb3..69aaeaf 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
@@ -34,7 +34,8 @@
#include "FrameView.h"
#include "GraphicsContext.h"
#include "KURL.h"
-#include "QTMovieWin.h"
+#include "MediaPlayerPrivateTaskTimer.h"
+#include "QTMovieTask.h"
#include "ScrollView.h"
#include "SoftLinking.h"
#include "StringBuilder.h"
@@ -53,10 +54,8 @@
#endif
#if DRAW_FRAME_RATE
-#include "Font.h"
-#include "FrameView.h"
-#include "Frame.h"
#include "Document.h"
+#include "Font.h"
#include "RenderObject.h"
#include "RenderStyle.h"
#include "Windows.h"
@@ -104,6 +103,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
MediaPlayerPrivate::~MediaPlayerPrivate()
{
tearDownVideoRendering();
+ m_qtGWorld->setMovie(0);
}
bool MediaPlayerPrivate::supportsFullscreen() const
@@ -114,7 +114,8 @@ bool MediaPlayerPrivate::supportsFullscreen() const
PlatformMedia MediaPlayerPrivate::platformMedia() const
{
PlatformMedia p;
- p.qtMovie = reinterpret_cast<QTMovie*>(m_qtMovie.get());
+ p.type = PlatformMedia::QTMovieGWorldType;
+ p.media.qtMovieGWorld = m_qtGWorld.get();
return p;
}
@@ -125,50 +126,6 @@ PlatformLayer* MediaPlayerPrivate::platformLayer() const
}
#endif
-class TaskTimer : TimerBase {
-public:
- static void initialize();
-
-private:
- static void setTaskTimerDelay(double);
- static void stopTaskTimer();
-
- void fired();
-
- static TaskTimer* s_timer;
-};
-
-TaskTimer* TaskTimer::s_timer = 0;
-
-void TaskTimer::initialize()
-{
- if (s_timer)
- return;
-
- s_timer = new TaskTimer;
-
- QTMovieWin::setTaskTimerFuncs(setTaskTimerDelay, stopTaskTimer);
-}
-
-void TaskTimer::setTaskTimerDelay(double delayInSeconds)
-{
- ASSERT(s_timer);
-
- s_timer->startOneShot(delayInSeconds);
-}
-
-void TaskTimer::stopTaskTimer()
-{
- ASSERT(s_timer);
-
- s_timer->stop();
-}
-
-void TaskTimer::fired()
-{
- QTMovieWin::taskTimerFired();
-}
-
String MediaPlayerPrivate::rfc2616DateStringFromTime(CFAbsoluteTime time)
{
static const char* const dayStrings[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
@@ -262,7 +219,7 @@ void MediaPlayerPrivate::setUpCookiesForQuickTime(const String& url)
void MediaPlayerPrivate::load(const String& url)
{
- if (!QTMovieWin::initializeQuickTime()) {
+ if (!QTMovie::initializeQuickTime()) {
// FIXME: is this the right error to return?
m_networkState = MediaPlayer::DecodeError;
m_player->networkStateChanged();
@@ -270,7 +227,7 @@ void MediaPlayerPrivate::load(const String& url)
}
// Initialize the task timer.
- TaskTimer::initialize();
+ MediaPlayerPrivateTaskTimer::initialize();
if (m_networkState != MediaPlayer::Loading) {
m_networkState = MediaPlayer::Loading;
@@ -284,10 +241,13 @@ void MediaPlayerPrivate::load(const String& url)
setUpCookiesForQuickTime(url);
- m_qtMovie.set(new QTMovieWin(this));
+ m_qtMovie = adoptRef(new QTMovie(this));
m_qtMovie->load(url.characters(), url.length(), m_player->preservesPitch());
m_qtMovie->setVolume(m_player->volume());
- m_qtMovie->setVisible(m_player->visible());
+
+ m_qtGWorld = adoptRef(new QTMovieGWorld(this));
+ m_qtGWorld->setMovie(m_qtMovie.get());
+ m_qtGWorld->setVisible(m_player->visible());
}
void MediaPlayerPrivate::play()
@@ -388,7 +348,7 @@ bool MediaPlayerPrivate::paused() const
{
if (!m_qtMovie)
return true;
- return m_qtMovie->rate() == 0.0f;
+ return (!m_qtMovie->rate());
}
bool MediaPlayerPrivate::seeking() const
@@ -612,7 +572,7 @@ void MediaPlayerPrivate::setSize(const IntSize& size)
if (m_hasUnsupportedTracks || !m_qtMovie || m_size == size)
return;
m_size = size;
- m_qtMovie->setSize(size.width(), size.height());
+ m_qtGWorld->setSize(size.width(), size.height());
}
void MediaPlayerPrivate::setVisible(bool visible)
@@ -620,7 +580,7 @@ void MediaPlayerPrivate::setVisible(bool visible)
if (m_hasUnsupportedTracks || !m_qtMovie || m_visible == visible)
return;
- m_qtMovie->setVisible(visible);
+ m_qtGWorld->setVisible(visible);
m_visible = visible;
if (m_visible) {
if (isReadyForRendering())
@@ -643,7 +603,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
HDC hdc = p->getWindowsContext(r);
if (!hdc) {
// The graphics context doesn't have an associated HDC so create a temporary
- // bitmap where QTMovieWin can draw the frame and we can copy it.
+ // bitmap where QTMovieGWorld can draw the frame and we can copy it.
usingTempBitmap = true;
bitmap.set(p->createWindowsBitmap(r.size()));
hdc = bitmap->hdc();
@@ -659,7 +619,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
SetWorldTransform(hdc, &xform);
}
- m_qtMovie->paint(hdc, r.x(), r.y());
+ m_qtGWorld->paint(hdc, r.x(), r.y());
if (usingTempBitmap)
p->drawWindowsBitmap(bitmap.get(), r.topLeft());
else
@@ -719,11 +679,11 @@ static HashSet<String> mimeTypeCache()
static bool typeListInitialized = false;
if (!typeListInitialized) {
- unsigned count = QTMovieWin::countSupportedTypes();
+ unsigned count = QTMovie::countSupportedTypes();
for (unsigned n = 0; n < count; n++) {
const UChar* character;
unsigned len;
- QTMovieWin::getSupportedType(n, character, len);
+ QTMovie::getSupportedType(n, character, len);
if (len)
typeCache.add(String(character, len));
}
@@ -741,7 +701,7 @@ void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
bool MediaPlayerPrivate::isAvailable()
{
- return QTMovieWin::initializeQuickTime();
+ return QTMovie::initializeQuickTime();
}
MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
@@ -751,7 +711,7 @@ MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, c
return mimeTypeCache().contains(type) ? (codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;
}
-void MediaPlayerPrivate::movieEnded(QTMovieWin* movie)
+void MediaPlayerPrivate::movieEnded(QTMovie* movie)
{
if (m_hasUnsupportedTracks)
return;
@@ -760,7 +720,7 @@ void MediaPlayerPrivate::movieEnded(QTMovieWin* movie)
didEnd();
}
-void MediaPlayerPrivate::movieLoadStateChanged(QTMovieWin* movie)
+void MediaPlayerPrivate::movieLoadStateChanged(QTMovie* movie)
{
if (m_hasUnsupportedTracks)
return;
@@ -769,7 +729,7 @@ void MediaPlayerPrivate::movieLoadStateChanged(QTMovieWin* movie)
updateStates();
}
-void MediaPlayerPrivate::movieTimeChanged(QTMovieWin* movie)
+void MediaPlayerPrivate::movieTimeChanged(QTMovie* movie)
{
if (m_hasUnsupportedTracks)
return;
@@ -779,12 +739,12 @@ void MediaPlayerPrivate::movieTimeChanged(QTMovieWin* movie)
m_player->timeChanged();
}
-void MediaPlayerPrivate::movieNewImageAvailable(QTMovieWin* movie)
+void MediaPlayerPrivate::movieNewImageAvailable(QTMovieGWorld* movie)
{
if (m_hasUnsupportedTracks)
return;
- ASSERT(m_qtMovie.get() == movie);
+ ASSERT(m_qtGWorld.get() == movie);
#if DRAW_FRAME_RATE
if (m_startedPlaying) {
m_frameCountWhilePlaying++;
@@ -900,9 +860,9 @@ void MediaPlayerPrivate::paintContents(const GraphicsLayer*, GraphicsContext& co
unsigned width;
unsigned height;
- m_qtMovie->getCurrentFrameInfo(buffer, bitsPerPixel, rowBytes, width, height);
+ m_qtGWorld->getCurrentFrameInfo(buffer, bitsPerPixel, rowBytes, width, height);
if (!buffer)
- return ;
+ return;
RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(0, static_cast<UInt8*>(buffer), rowBytes * height, kCFAllocatorNull));
RetainPtr<CGDataProviderRef> provider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
index 9de5894..ecdb9da 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
@@ -23,14 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaPlayerPrivateQTKit_h
-#define MediaPlayerPrivateQTKit_h
+#ifndef MediaPlayerPrivateQuickTimeWin_h
+#define MediaPlayerPrivateQuickTimeWin_h
#if ENABLE(VIDEO)
#include "MediaPlayerPrivate.h"
#include "Timer.h"
-#include <QTMovieWin.h>
+#include <QTMovie.h>
+#include <QTMovieGWorld.h>
#include <wtf/OwnPtr.h>
#include <wtf/RetainPtr.h>
@@ -51,7 +52,7 @@ class IntSize;
class IntRect;
class String;
-class MediaPlayerPrivate : public MediaPlayerPrivateInterface, public QTMovieWinClient
+class MediaPlayerPrivate : public MediaPlayerPrivateInterface, public QTMovieClient, public QTMovieGWorldClient
#if USE(ACCELERATED_COMPOSITING)
, public GraphicsLayerClient
#endif
@@ -130,10 +131,10 @@ private:
float maxTimeLoaded() const;
void sawUnsupportedTracks();
- virtual void movieEnded(QTMovieWin*);
- virtual void movieLoadStateChanged(QTMovieWin*);
- virtual void movieTimeChanged(QTMovieWin*);
- virtual void movieNewImageAvailable(QTMovieWin*);
+ virtual void movieEnded(QTMovie*);
+ virtual void movieLoadStateChanged(QTMovie*);
+ virtual void movieTimeChanged(QTMovie*);
+ virtual void movieNewImageAvailable(QTMovieGWorld*);
// engine support
static MediaPlayerPrivateInterface* create(MediaPlayer*);
@@ -162,7 +163,8 @@ private:
String rfc2616DateStringFromTime(CFAbsoluteTime);
MediaPlayer* m_player;
- OwnPtr<QTMovieWin> m_qtMovie;
+ RefPtr<QTMovie> m_qtMovie;
+ RefPtr<QTMovieGWorld> m_qtGWorld;
#if USE(ACCELERATED_COMPOSITING)
OwnPtr<GraphicsLayer> m_qtVideoLayer;
#endif
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateTaskTimer.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateTaskTimer.cpp
new file mode 100644
index 0000000..770e73e
--- /dev/null
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateTaskTimer.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "MediaPlayerPrivateTaskTimer.h"
+
+#include "QTMovieTask.h"
+
+namespace WebCore {
+
+MediaPlayerPrivateTaskTimer* MediaPlayerPrivateTaskTimer::s_timer = 0;
+
+void MediaPlayerPrivateTaskTimer::initialize()
+{
+ if (s_timer)
+ return;
+
+ s_timer = new MediaPlayerPrivateTaskTimer;
+
+ QTMovieTask::sharedTask()->setTaskTimerFuncs(setDelay, stopTaskTimer);
+}
+
+void MediaPlayerPrivateTaskTimer::setDelay(double delayInSeconds)
+{
+ ASSERT(s_timer);
+
+ s_timer->startOneShot(delayInSeconds);
+}
+
+void MediaPlayerPrivateTaskTimer::stopTaskTimer()
+{
+ ASSERT(s_timer);
+
+ s_timer->stop();
+}
+
+void MediaPlayerPrivateTaskTimer::fired()
+{
+ QTMovieTask::sharedTask()->fireTaskClients();
+}
+
+}
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateTaskTimer.h b/WebCore/platform/graphics/win/MediaPlayerPrivateTaskTimer.h
new file mode 100644
index 0000000..10f861e
--- /dev/null
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateTaskTimer.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaPlayerPrivateTaskTimer_h
+#define MediaPlayerPrivateTaskTimer_h
+
+#include "Timer.h"
+
+namespace WebCore {
+
+class MediaPlayerPrivateTaskTimer : TimerBase {
+public:
+ static void initialize();
+
+private:
+ static void setDelay(double);
+ static void stopTaskTimer();
+
+ void fired();
+
+ static MediaPlayerPrivateTaskTimer* s_timer;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/win/QTCFDictionary.cpp b/WebCore/platform/graphics/win/QTCFDictionary.cpp
new file mode 100644
index 0000000..ada1500
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTCFDictionary.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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"
+
+#include "QTCFDictionary.h"
+
+#include <CFData.h>
+#include <windows.h>
+
+CFDataRef QTCFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRef propertyList)
+{
+
+ typedef CFDataRef (* pfnCFPropertyListCreateXMLData)(CFAllocatorRef allocator, CFPropertyListRef propertyList);
+ static pfnCFPropertyListCreateXMLData pCFPropertyListCreateXMLData = 0;
+ if (!pCFPropertyListCreateXMLData) {
+ HMODULE qtcfDLL = LoadLibraryW(L"QTCF.dll");
+ if (qtcfDLL)
+ pCFPropertyListCreateXMLData = reinterpret_cast<pfnCFPropertyListCreateXMLData>(GetProcAddress(qtcfDLL, "QTCF_CFPropertyListCreateXMLData"));
+ }
+
+ if (pCFPropertyListCreateXMLData)
+ return pCFPropertyListCreateXMLData(allocator, propertyList);
+ return 0;
+}
+
+CFDictionaryRef QTCFDictionaryCreateCopyWithDataCallback(CFAllocatorRef allocator, CFDictionaryRef dictionary, QTCFDictonaryCreateFromDataCallback callback)
+{
+ ASSERT(dictionary);
+ ASSERT(callback);
+
+ CFDataRef data = QTCFPropertyListCreateXMLData(kCFAllocatorDefault, dictionary);
+ CFDictionaryRef outputDictionary = callback(allocator, CFDataGetBytePtr(data), CFDataGetLength(data));
+ if (data)
+ CFRelease(data);
+
+ return outputDictionary;
+}
diff --git a/WebCore/platform/graphics/win/QTCFDictionary.h b/WebCore/platform/graphics/win/QTCFDictionary.h
new file mode 100644
index 0000000..ff34328
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTCFDictionary.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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 QTCFDictionary_h
+#define QTCFDictionary_h
+
+#ifdef QTMOVIEWIN_EXPORTS
+#define QTMOVIEWIN_API __declspec(dllexport)
+#else
+#define QTMOVIEWIN_API __declspec(dllimport)
+#endif
+
+#include <CoreFoundation/CFBase.h>
+
+typedef const struct __CFDictionary * CFDictionaryRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+
+typedef CFDictionaryRef (* QTCFDictonaryCreateFromDataCallback)(CFAllocatorRef, const UInt8*, CFIndex);
+
+QTMOVIEWIN_API CFDictionaryRef QTCFDictionaryCreateCopyWithDataCallback(CFAllocatorRef, CFDictionaryRef, QTCFDictonaryCreateFromDataCallback);
+
+#endif
diff --git a/WebCore/platform/graphics/win/QTMovieWin.cpp b/WebCore/platform/graphics/win/QTMovie.cpp
index 4831062..032b446 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.cpp
+++ b/WebCore/platform/graphics/win/QTMovie.cpp
@@ -24,17 +24,15 @@
*/
#include "config.h"
-#include "QTMovieWin.h"
-
-// Put Movies.h first so build failures here point clearly to QuickTime
-#include <Movies.h>
+#include "QTMovie.h"
+#include "QTMovieTask.h"
#include "QTMovieWinTimer.h"
#include <GXMath.h>
+#include <Movies.h>
#include <QTML.h>
#include <QuickTimeComponents.h>
#include <wtf/Assertions.h>
-#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
@@ -47,7 +45,7 @@ static const long subTitleTrackType = 'sbtl';
static const long mpeg4ObjectDescriptionTrackType = 'odsm';
static const long mpeg4SceneDescriptionTrackType = 'sdsm';
static const long closedCaptionDisplayPropertyID = 'disp';
-static LPCTSTR fullscreenQTMovieWinPointerProp = TEXT("fullscreenQTMovieWinPointer");
+static LPCTSTR fullscreenQTMoviePointerProp = TEXT("fullscreenQTMoviePointer");
// Resizing GWorlds is slow, give them a minimum size so size of small
// videos can be animated smoothly
@@ -61,53 +59,26 @@ union UppParam {
void* ptr;
};
-static MovieDrawingCompleteUPP gMovieDrawingCompleteUPP = 0;
-static HashSet<QTMovieWinPrivate*>* gTaskList;
static Vector<CFStringRef>* gSupportedTypes = 0;
static SInt32 quickTimeVersion = 0;
-static QTMovieWin::SetTaskTimerDelayFunc gSetTaskTimerDelay = 0;
-static QTMovieWin::StopTaskTimerFunc gStopTaskTimer = 0;
-
-static void updateTaskTimer(int maxInterval = 1000)
-{
- if (!gTaskList->size()) {
- gStopTaskTimer();
- return;
- }
-
- long intervalInMS;
- QTGetTimeUntilNextTask(&intervalInMS, 1000);
- if (intervalInMS > maxInterval)
- intervalInMS = maxInterval;
- gSetTaskTimerDelay(static_cast<float>(intervalInMS) / 1000);
-}
-
-class QTMovieWinPrivate : public Noncopyable {
+class QTMoviePrivate : public Noncopyable, public QTMovieTaskClient {
public:
- QTMovieWinPrivate();
- ~QTMovieWinPrivate();
+ QTMoviePrivate();
+ ~QTMoviePrivate();
void task();
void startTask();
void endTask();
void createMovieController();
- void registerDrawingCallback();
- void drawingComplete();
- void updateGWorld();
- void createGWorld();
- void deleteGWorld();
- void clearGWorld();
void cacheMovieScale();
- void updateMovieSize();
-
- void setSize(int, int);
- QTMovieWin* m_movieWin;
+ QTMovie* m_movieWin;
Movie m_movie;
MovieController m_movieController;
bool m_tasking;
- QTMovieWinClient* m_client;
+ bool m_disabled;
+ Vector<QTMovieClient*> m_clients;
long m_loadState;
bool m_ended;
bool m_seeking;
@@ -116,10 +87,6 @@ public:
int m_width;
int m_height;
bool m_visible;
- GWorldPtr m_gWorld;
- int m_gWorldWidth;
- int m_gWorldHeight;
- GWorldPtr m_savedGWorld;
long m_loadError;
float m_widthScaleFactor;
float m_heightScaleFactor;
@@ -129,19 +96,13 @@ public:
#if !ASSERT_DISABLED
bool m_scaleCached;
#endif
- WindowPtr m_fullscreenWindow;
- GWorldPtr m_fullscreenOrigGWorld;
- Rect m_fullscreenRect;
- QTMovieWinFullscreenClient* m_fullscreenClient;
- char* m_fullscreenRestoreState;
};
-QTMovieWinPrivate::QTMovieWinPrivate()
+QTMoviePrivate::QTMoviePrivate()
: m_movieWin(0)
, m_movie(0)
, m_movieController(0)
, m_tasking(false)
- , m_client(0)
, m_loadState(0)
, m_ended(false)
, m_seeking(false)
@@ -150,35 +111,22 @@ QTMovieWinPrivate::QTMovieWinPrivate()
, m_width(0)
, m_height(0)
, m_visible(false)
- , m_gWorld(0)
- , m_gWorldWidth(0)
- , m_gWorldHeight(0)
- , m_savedGWorld(0)
, m_loadError(0)
, m_widthScaleFactor(1)
, m_heightScaleFactor(1)
, m_currentURL(0)
, m_timeToRestore(-1.0f)
, m_rateToRestore(-1.0f)
+ , m_disabled(false)
#if !ASSERT_DISABLED
, m_scaleCached(false)
#endif
- , m_fullscreenWindow(0)
- , m_fullscreenOrigGWorld(0)
- , m_fullscreenClient(0)
- , m_fullscreenRestoreState(0)
{
- Rect rect = { 0, 0, 0, 0 };
- m_fullscreenRect = rect;
}
-QTMovieWinPrivate::~QTMovieWinPrivate()
+QTMoviePrivate::~QTMoviePrivate()
{
- ASSERT(!m_fullscreenWindow);
-
endTask();
- if (m_gWorld)
- deleteGWorld();
if (m_movieController)
DisposeMovieController(m_movieController);
if (m_movie)
@@ -187,59 +135,25 @@ QTMovieWinPrivate::~QTMovieWinPrivate()
CFRelease(m_currentURL);
}
-void QTMovieWin::taskTimerFired()
-{
- // The hash content might change during task()
- Vector<QTMovieWinPrivate*> tasks;
- copyToVector(*gTaskList, tasks);
- size_t count = tasks.size();
- for (unsigned n = 0; n < count; ++n)
- tasks[n]->task();
-
- updateTaskTimer();
-}
-
-void QTMovieWinPrivate::startTask()
-{
- if (m_tasking)
- return;
- if (!gTaskList)
- gTaskList = new HashSet<QTMovieWinPrivate*>;
- gTaskList->add(this);
- m_tasking = true;
- updateTaskTimer();
-}
-
-void QTMovieWinPrivate::endTask()
+void QTMoviePrivate::startTask()
{
- if (!m_tasking)
- return;
- gTaskList->remove(this);
- m_tasking = false;
- updateTaskTimer();
+ if (!m_tasking) {
+ QTMovieTask::sharedTask()->addTaskClient(this);
+ m_tasking = true;
+ }
+ QTMovieTask::sharedTask()->updateTaskTimer();
}
-void QTMovieWinPrivate::cacheMovieScale()
+void QTMoviePrivate::endTask()
{
- Rect naturalRect;
- Rect initialRect;
-
- GetMovieNaturalBoundsRect(m_movie, &naturalRect);
- GetMovieBox(m_movie, &initialRect);
-
- float naturalWidth = naturalRect.right - naturalRect.left;
- float naturalHeight = naturalRect.bottom - naturalRect.top;
-
- if (naturalWidth)
- m_widthScaleFactor = (initialRect.right - initialRect.left) / naturalWidth;
- if (naturalHeight)
- m_heightScaleFactor = (initialRect.bottom - initialRect.top) / naturalHeight;
-#if !ASSERT_DISABLED
- m_scaleCached = true;;
-#endif
+ if (m_tasking) {
+ QTMovieTask::sharedTask()->removeTaskClient(this);
+ m_tasking = false;
+ }
+ QTMovieTask::sharedTask()->updateTaskTimer();
}
-void QTMovieWinPrivate::task()
+void QTMoviePrivate::task()
{
ASSERT(m_tasking);
@@ -256,7 +170,6 @@ void QTMovieWinPrivate::task()
// This is different from QTKit API and seems strange.
long loadState = m_loadError ? QTMovieLoadStateError : GetMovieLoadState(m_movie);
if (loadState != m_loadState) {
-
// we only need to erase the movie gworld when the load state changes to loaded while it
// is visible as the gworld is destroyed/created when visibility changes
bool shouldRestorePlaybackState = false;
@@ -264,15 +177,14 @@ void QTMovieWinPrivate::task()
m_loadState = loadState;
if (movieNewlyPlayable) {
cacheMovieScale();
- updateMovieSize();
- if (m_visible)
- clearGWorld();
shouldRestorePlaybackState = true;
}
if (!m_movieController && m_loadState >= QTMovieLoadStateLoaded)
createMovieController();
- m_client->movieLoadStateChanged(m_movieWin);
+
+ for (size_t i = 0; i < m_clients.size(); ++i)
+ m_clients[i]->movieLoadStateChanged(m_movieWin);
if (shouldRestorePlaybackState && m_timeToRestore != -1.0f) {
m_movieWin->setCurrentTime(m_timeToRestore);
@@ -281,7 +193,7 @@ void QTMovieWinPrivate::task()
m_rateToRestore = -1.0f;
}
- if (m_movieWin->m_disabled) {
+ if (m_disabled) {
endTask();
return;
}
@@ -292,23 +204,27 @@ void QTMovieWinPrivate::task()
bool ended = !!IsMovieDone(m_movie);
if (ended != m_ended) {
m_ended = ended;
- if (m_client && ended)
- m_client->movieEnded(m_movieWin);
+ if (ended) {
+ for (size_t i = 0; i < m_clients.size(); ++i)
+ m_clients[i]->movieEnded(m_movieWin);
+ }
}
float time = m_movieWin->currentTime();
if (time < m_lastMediaTime || time >= m_lastMediaTime + cNonContinuousTimeChange || m_seeking) {
m_seeking = false;
- if (m_client)
- m_client->movieTimeChanged(m_movieWin);
+ for (size_t i = 0; i < m_clients.size(); ++i)
+ m_clients[i]->movieTimeChanged(m_movieWin);
}
m_lastMediaTime = time;
if (m_loadError)
endTask();
+ else
+ QTMovieTask::sharedTask()->updateTaskTimer();
}
-void QTMovieWinPrivate::createMovieController()
+void QTMoviePrivate::createMovieController()
{
Rect bounds;
long flags;
@@ -324,155 +240,56 @@ void QTMovieWinPrivate::createMovieController()
m_movieController = NewMovieController(m_movie, &bounds, flags);
if (!m_movieController)
return;
-
- MCSetControllerPort(m_movieController, m_gWorld);
- MCSetControllerAttached(m_movieController, false);
}
-void QTMovieWinPrivate::registerDrawingCallback()
+void QTMoviePrivate::cacheMovieScale()
{
- UppParam param;
- param.ptr = this;
- SetMovieDrawingCompleteProc(m_movie, movieDrawingCallWhenChanged, gMovieDrawingCompleteUPP, param.longValue);
-}
-
-void QTMovieWinPrivate::drawingComplete()
-{
- if (!m_gWorld || m_movieWin->m_disabled || m_loadState < QTMovieLoadStateLoaded)
- return;
- m_client->movieNewImageAvailable(m_movieWin);
-}
-
-void QTMovieWinPrivate::updateGWorld()
-{
- bool shouldBeVisible = m_visible;
- if (!m_height || !m_width)
- shouldBeVisible = false;
-
- if (shouldBeVisible && !m_gWorld)
- createGWorld();
- else if (!shouldBeVisible && m_gWorld)
- deleteGWorld();
- else if (m_gWorld && (m_width > m_gWorldWidth || m_height > m_gWorldHeight)) {
- // need a bigger, better gWorld
- deleteGWorld();
- createGWorld();
- }
-}
-
-void QTMovieWinPrivate::createGWorld()
-{
- ASSERT(!m_gWorld);
- if (!m_movie || m_loadState < QTMovieLoadStateLoaded)
- return;
-
- m_gWorldWidth = max(cGWorldMinWidth, m_width);
- m_gWorldHeight = max(cGWorldMinHeight, m_height);
- Rect bounds;
- bounds.top = 0;
- bounds.left = 0;
- bounds.right = m_gWorldWidth;
- bounds.bottom = m_gWorldHeight;
- OSErr err = QTNewGWorld(&m_gWorld, k32BGRAPixelFormat, &bounds, 0, 0, 0);
- if (err)
- return;
- GetMovieGWorld(m_movie, &m_savedGWorld, 0);
- if (m_movieController)
- MCSetControllerPort(m_movieController, m_gWorld);
- SetMovieGWorld(m_movie, m_gWorld, 0);
- bounds.right = m_width;
- bounds.bottom = m_height;
- if (m_movieController)
- MCSetControllerBoundsRect(m_movieController, &bounds);
- SetMovieBox(m_movie, &bounds);
-}
-
-void QTMovieWinPrivate::clearGWorld()
-{
- if (!m_movie||!m_gWorld)
- return;
-
- GrafPtr savePort;
- GetPort(&savePort);
- MacSetPort((GrafPtr)m_gWorld);
-
- Rect bounds;
- bounds.top = 0;
- bounds.left = 0;
- bounds.right = m_gWorldWidth;
- bounds.bottom = m_gWorldHeight;
- EraseRect(&bounds);
-
- MacSetPort(savePort);
-}
+ Rect naturalRect;
+ Rect initialRect;
-void QTMovieWinPrivate::setSize(int width, int height)
-{
- if (m_width == width && m_height == height)
- return;
- m_width = width;
- m_height = height;
+ GetMovieNaturalBoundsRect(m_movie, &naturalRect);
+ GetMovieBox(m_movie, &initialRect);
- // Do not change movie box before reaching load state loaded as we grab
- // the initial size when task() sees that state for the first time, and
- // we need the initial size to be able to scale movie properly.
- if (!m_movie || m_loadState < QTMovieLoadStateLoaded)
- return;
+ float naturalWidth = naturalRect.right - naturalRect.left;
+ float naturalHeight = naturalRect.bottom - naturalRect.top;
+ if (naturalWidth)
+ m_widthScaleFactor = (initialRect.right - initialRect.left) / naturalWidth;
+ if (naturalHeight)
+ m_heightScaleFactor = (initialRect.bottom - initialRect.top) / naturalHeight;
#if !ASSERT_DISABLED
- ASSERT(m_scaleCached);
+ m_scaleCached = true;
#endif
-
- updateMovieSize();
}
-void QTMovieWinPrivate::updateMovieSize()
+QTMovie::QTMovie(QTMovieClient* client)
+ : m_private(new QTMoviePrivate())
{
- if (!m_movie || m_loadState < QTMovieLoadStateLoaded)
- return;
-
- Rect bounds;
- bounds.top = 0;
- bounds.left = 0;
- bounds.right = m_width;
- bounds.bottom = m_height;
- if (m_movieController)
- MCSetControllerBoundsRect(m_movieController, &bounds);
- SetMovieBox(m_movie, &bounds);
- updateGWorld();
+ m_private->m_movieWin = this;
+ if (client)
+ m_private->m_clients.append(client);
+ initializeQuickTime();
}
-
-void QTMovieWinPrivate::deleteGWorld()
+QTMovie::~QTMovie()
{
- ASSERT(m_gWorld);
- if (m_movieController)
- MCSetControllerPort(m_movieController, m_savedGWorld);
- if (m_movie)
- SetMovieGWorld(m_movie, m_savedGWorld, 0);
- m_savedGWorld = 0;
- DisposeGWorld(m_gWorld);
- m_gWorld = 0;
- m_gWorldWidth = 0;
- m_gWorldHeight = 0;
+ delete m_private;
}
-
-QTMovieWin::QTMovieWin(QTMovieWinClient* client)
- : m_private(new QTMovieWinPrivate())
- , m_disabled(false)
+void QTMovie::addClient(QTMovieClient* client)
{
- m_private->m_movieWin = this;
- m_private->m_client = client;
- initializeQuickTime();
+ if (client)
+ m_private->m_clients.append(client);
}
-QTMovieWin::~QTMovieWin()
+void QTMovie::removeClient(QTMovieClient* client)
{
- delete m_private;
+ size_t indexOfClient = m_private->m_clients.find(client);
+ if (indexOfClient != notFound)
+ m_private->m_clients.remove(indexOfClient);
}
-void QTMovieWin::play()
+void QTMovie::play()
{
m_private->m_timeToRestore = -1.0f;
@@ -483,7 +300,7 @@ void QTMovieWin::play()
m_private->startTask();
}
-void QTMovieWin::pause()
+void QTMovie::pause()
{
m_private->m_timeToRestore = -1.0f;
@@ -491,17 +308,17 @@ void QTMovieWin::pause()
MCDoAction(m_private->m_movieController, mcActionPlay, 0);
else
StopMovie(m_private->m_movie);
- updateTaskTimer();
+ QTMovieTask::sharedTask()->updateTaskTimer();
}
-float QTMovieWin::rate() const
+float QTMovie::rate() const
{
if (!m_private->m_movie)
return 0;
return FixedToFloat(GetMovieRate(m_private->m_movie));
}
-void QTMovieWin::setRate(float rate)
+void QTMovie::setRate(float rate)
{
if (!m_private->m_movie)
return;
@@ -511,10 +328,10 @@ void QTMovieWin::setRate(float rate)
MCDoAction(m_private->m_movieController, mcActionPrerollAndPlay, (void *)FloatToFixed(rate));
else
SetMovieRate(m_private->m_movie, FloatToFixed(rate));
- updateTaskTimer();
+ QTMovieTask::sharedTask()->updateTaskTimer();
}
-float QTMovieWin::duration() const
+float QTMovie::duration() const
{
if (!m_private->m_movie)
return 0;
@@ -523,7 +340,7 @@ float QTMovieWin::duration() const
return static_cast<float>(val) / scale;
}
-float QTMovieWin::currentTime() const
+float QTMovie::currentTime() const
{
if (!m_private->m_movie)
return 0;
@@ -532,7 +349,7 @@ float QTMovieWin::currentTime() const
return static_cast<float>(val) / scale;
}
-void QTMovieWin::setCurrentTime(float time) const
+void QTMovie::setCurrentTime(float time) const
{
if (!m_private->m_movie)
return;
@@ -541,22 +358,22 @@ void QTMovieWin::setCurrentTime(float time) const
m_private->m_seeking = true;
TimeScale scale = GetMovieTimeScale(m_private->m_movie);
- if (m_private->m_movieController){
+ if (m_private->m_movieController) {
QTRestartAtTimeRecord restart = { time * scale , 0 };
MCDoAction(m_private->m_movieController, mcActionRestartAtTime, (void *)&restart);
} else
SetMovieTimeValue(m_private->m_movie, TimeValue(time * scale));
- updateTaskTimer();
+ QTMovieTask::sharedTask()->updateTaskTimer();
}
-void QTMovieWin::setVolume(float volume)
+void QTMovie::setVolume(float volume)
{
if (!m_private->m_movie)
return;
SetMovieVolume(m_private->m_movie, static_cast<short>(volume * 256));
}
-void QTMovieWin::setPreservesPitch(bool preservesPitch)
+void QTMovie::setPreservesPitch(bool preservesPitch)
{
if (!m_private->m_movie || !m_private->m_currentURL)
return;
@@ -575,14 +392,14 @@ void QTMovieWin::setPreservesPitch(bool preservesPitch)
load(m_private->m_currentURL, preservesPitch);
}
-unsigned QTMovieWin::dataSize() const
+unsigned QTMovie::dataSize() const
{
if (!m_private->m_movie)
return 0;
return GetMovieDataSize(m_private->m_movie, 0, GetMovieDuration(m_private->m_movie));
}
-float QTMovieWin::maxTimeLoaded() const
+float QTMovie::maxTimeLoaded() const
{
if (!m_private->m_movie)
return 0;
@@ -592,12 +409,12 @@ float QTMovieWin::maxTimeLoaded() const
return static_cast<float>(val) / scale;
}
-long QTMovieWin::loadState() const
+long QTMovie::loadState() const
{
return m_private->m_loadState;
}
-void QTMovieWin::getNaturalSize(int& width, int& height)
+void QTMovie::getNaturalSize(int& width, int& height)
{
Rect rect = { 0, };
@@ -607,56 +424,7 @@ void QTMovieWin::getNaturalSize(int& width, int& height)
height = (rect.bottom - rect.top) * m_private->m_heightScaleFactor;
}
-void QTMovieWin::setSize(int width, int height)
-{
- m_private->setSize(width, height);
- updateTaskTimer(0);
-}
-
-void QTMovieWin::setVisible(bool b)
-{
- m_private->m_visible = b;
- m_private->updateGWorld();
-}
-
-void QTMovieWin::getCurrentFrameInfo(void*& buffer, unsigned& bitsPerPixel, unsigned& rowBytes, unsigned& width, unsigned& height)
-{
- if (!m_private->m_gWorld) {
- buffer = 0;
- bitsPerPixel = 0;
- rowBytes = 0;
- width = 0;
- height = 0;
- return;
- }
- PixMapHandle offscreenPixMap = GetGWorldPixMap(m_private->m_gWorld);
- buffer = (*offscreenPixMap)->baseAddr;
- bitsPerPixel = (*offscreenPixMap)->pixelSize;
- rowBytes = (*offscreenPixMap)->rowBytes & 0x3FFF;
- width = m_private->m_width;
- height = m_private->m_height;
-}
-
-void QTMovieWin::paint(HDC hdc, int x, int y)
-{
- if (!m_private->m_gWorld)
- return;
-
- HDC hdcSrc = static_cast<HDC>(GetPortHDC(reinterpret_cast<GrafPtr>(m_private->m_gWorld)));
- if (!hdcSrc)
- return;
-
- // FIXME: If we could determine the movie has no alpha, we could use BitBlt for those cases, which might be faster.
- BLENDFUNCTION blendFunction;
- blendFunction.BlendOp = AC_SRC_OVER;
- blendFunction.BlendFlags = 0;
- blendFunction.SourceConstantAlpha = 255;
- blendFunction.AlphaFormat = AC_SRC_ALPHA;
- AlphaBlend(hdc, x, y, m_private->m_width, m_private->m_height, hdcSrc,
- 0, 0, m_private->m_width, m_private->m_height, blendFunction);
-}
-
-void QTMovieWin::load(const UChar* url, int len, bool preservesPitch)
+void QTMovie::load(const UChar* url, int len, bool preservesPitch)
{
CFStringRef urlStringRef = CFStringCreateWithCharacters(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(url), len);
CFURLRef cfURL = CFURLCreateWithString(kCFAllocatorDefault, urlStringRef, 0);
@@ -667,15 +435,13 @@ void QTMovieWin::load(const UChar* url, int len, bool preservesPitch)
CFRelease(urlStringRef);
}
-void QTMovieWin::load(CFURLRef url, bool preservesPitch)
+void QTMovie::load(CFURLRef url, bool preservesPitch)
{
if (!url)
return;
if (m_private->m_movie) {
m_private->endTask();
- if (m_private->m_gWorld)
- m_private->deleteGWorld();
if (m_private->m_movieController)
DisposeMovieController(m_private->m_movieController);
m_private->m_movieController = 0;
@@ -768,14 +534,14 @@ void QTMovieWin::load(CFURLRef url, bool preservesPitch)
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
- ASSERT(moviePropCount <= sizeof(movieProps)/sizeof(movieProps[0]));
+ ASSERT(moviePropCount <= sizeof(movieProps) / sizeof(movieProps[0]));
m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, 0, &m_private->m_movie);
end:
m_private->startTask();
// get the load fail callback quickly
if (m_private->m_loadError)
- updateTaskTimer(0);
+ QTMovieTask::sharedTask()->updateTaskTimer(0);
else {
OSType mode = kQTApertureMode_CleanAperture;
@@ -784,11 +550,10 @@ end:
// the installed version of QT doesn't support it and it isn't serious enough to
// warrant failing.
QTSetMovieProperty(m_private->m_movie, kQTPropertyClass_Visual, kQTVisualPropertyID_ApertureMode, sizeof(mode), &mode);
- m_private->registerDrawingCallback();
}
}
-void QTMovieWin::disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned& totalTrackCount)
+void QTMovie::disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned& totalTrackCount)
{
if (!m_private->m_movie) {
totalTrackCount = 0;
@@ -903,20 +668,25 @@ void QTMovieWin::disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned&
}
}
-void QTMovieWin::setDisabled(bool b)
+bool QTMovie::isDisabled() const
+{
+ return m_private->m_disabled;
+}
+
+void QTMovie::setDisabled(bool b)
{
- m_disabled = b;
+ m_private->m_disabled = b;
}
-bool QTMovieWin::hasVideo() const
+bool QTMovie::hasVideo() const
{
if (!m_private->m_movie)
return false;
return (GetMovieIndTrackType(m_private->m_movie, 1, VisualMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly));
}
-bool QTMovieWin::hasAudio() const
+bool QTMovie::hasAudio() const
{
if (!m_private->m_movie)
return false;
@@ -924,14 +694,14 @@ bool QTMovieWin::hasAudio() const
}
-bool QTMovieWin::hasClosedCaptions() const
+bool QTMovie::hasClosedCaptions() const
{
if (!m_private->m_movie)
return false;
return GetMovieIndTrackType(m_private->m_movie, 1, closedCaptionTrackType, movieTrackMediaType);
}
-void QTMovieWin::setClosedCaptionsVisible(bool visible)
+void QTMovie::setClosedCaptionsVisible(bool visible)
{
if (!m_private->m_movie)
return;
@@ -944,16 +714,6 @@ void QTMovieWin::setClosedCaptionsVisible(bool visible)
QTSetTrackProperty(ccTrack, closedCaptionTrackType, closedCaptionDisplayPropertyID, sizeof(doDisplay), &doDisplay);
}
-pascal OSErr movieDrawingCompleteProc(Movie movie, long data)
-{
- UppParam param;
- param.longValue = data;
- QTMovieWinPrivate* mp = static_cast<QTMovieWinPrivate*>(param.ptr);
- if (mp)
- mp->drawingComplete();
- return 0;
-}
-
static void initializeSupportedTypes()
{
if (gSupportedTypes)
@@ -1043,13 +803,13 @@ static void initializeSupportedTypes()
}
}
-unsigned QTMovieWin::countSupportedTypes()
+unsigned QTMovie::countSupportedTypes()
{
initializeSupportedTypes();
return static_cast<unsigned>(gSupportedTypes->size());
}
-void QTMovieWin::getSupportedType(unsigned index, const UChar*& str, unsigned& len)
+void QTMovie::getSupportedType(unsigned index, const UChar*& str, unsigned& len)
{
initializeSupportedTypes();
ASSERT(index < gSupportedTypes->size());
@@ -1067,13 +827,7 @@ void QTMovieWin::getSupportedType(unsigned index, const UChar*& str, unsigned& l
}
-void QTMovieWin::setTaskTimerFuncs(SetTaskTimerDelayFunc setTaskTimerDelay, StopTaskTimerFunc stopTaskTimer)
-{
- gSetTaskTimerDelay = setTaskTimerDelay;
- gStopTaskTimer = stopTaskTimer;
-}
-
-bool QTMovieWin::initializeQuickTime()
+bool QTMovie::initializeQuickTime()
{
static bool initialized = false;
static bool initializationSucceeded = false;
@@ -1092,75 +846,14 @@ bool QTMovieWin::initializeQuickTime()
return false;
}
EnterMovies();
- gMovieDrawingCompleteUPP = NewMovieDrawingCompleteUPP(movieDrawingCompleteProc);
initializationSucceeded = true;
}
return initializationSucceeded;
}
-LRESULT QTMovieWin::fullscreenWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- QTMovieWin* movie = static_cast<QTMovieWin*>(GetProp(wnd, fullscreenQTMovieWinPointerProp));
-
- if (message == WM_DESTROY)
- RemoveProp(wnd, fullscreenQTMovieWinPointerProp);
-
- if (!movie)
- return DefWindowProc(wnd, message, wParam, lParam);
-
- return movie->m_private->m_fullscreenClient->fullscreenClientWndProc(wnd, message, wParam, lParam);
-}
-
-HWND QTMovieWin::enterFullscreen(QTMovieWinFullscreenClient* client)
-{
- m_private->m_fullscreenClient = client;
-
- BeginFullScreen(&m_private->m_fullscreenRestoreState, 0, 0, 0, &m_private->m_fullscreenWindow, 0, fullScreenAllowEvents);
- QTMLSetWindowWndProc(m_private->m_fullscreenWindow, fullscreenWndProc);
- CreatePortAssociation(GetPortNativeWindow(m_private->m_fullscreenWindow), 0, 0);
-
- GetMovieBox(m_private->m_movie, &m_private->m_fullscreenRect);
- GetMovieGWorld(m_private->m_movie, &m_private->m_fullscreenOrigGWorld, 0);
- SetMovieGWorld(m_private->m_movie, reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow), GetGWorldDevice(reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow)));
-
- // Set the size of the box to preserve aspect ratio
- Rect rect = m_private->m_fullscreenWindow->portRect;
-
- float movieRatio = static_cast<float>(m_private->m_width) / m_private->m_height;
- int windowWidth = rect.right - rect.left;
- int windowHeight = rect.bottom - rect.top;
- float windowRatio = static_cast<float>(windowWidth) / windowHeight;
- int actualWidth = (windowRatio > movieRatio) ? (windowHeight * movieRatio) : windowWidth;
- int actualHeight = (windowRatio < movieRatio) ? (windowWidth / movieRatio) : windowHeight;
- int offsetX = (windowWidth - actualWidth) / 2;
- int offsetY = (windowHeight - actualHeight) / 2;
-
- rect.left = offsetX;
- rect.right = offsetX + actualWidth;
- rect.top = offsetY;
- rect.bottom = offsetY + actualHeight;
-
- SetMovieBox(m_private->m_movie, &rect);
- ShowHideTaskBar(true);
-
- // Set the 'this' pointer on the HWND
- HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
- SetProp(wnd, fullscreenQTMovieWinPointerProp, static_cast<HANDLE>(this));
-
- return wnd;
-}
-
-void QTMovieWin::exitFullscreen()
+Movie QTMovie::getMovieHandle() const
{
- if (!m_private->m_fullscreenWindow)
- return;
-
- HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
- DestroyPortAssociation(reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow));
- SetMovieGWorld(m_private->m_movie, m_private->m_fullscreenOrigGWorld, 0);
- EndFullScreen(m_private->m_fullscreenRestoreState, 0L);
- SetMovieBox(m_private->m_movie, &m_private->m_fullscreenRect);
- m_private->m_fullscreenWindow = 0;
+ return m_private->m_movie;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
diff --git a/WebCore/platform/graphics/win/QTMovieWin.h b/WebCore/platform/graphics/win/QTMovie.h
index d2a7ed0..8fa4b6e 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.h
+++ b/WebCore/platform/graphics/win/QTMovie.h
@@ -23,11 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef QTMovieWin_h
-#define QTMovieWin_h
+#ifndef QTMovie_h
+#define QTMovie_h
#include <Unicode.h>
#include <windows.h>
+#include <wtf/RefCounted.h>
#ifdef QTMOVIEWIN_EXPORTS
#define QTMOVIEWIN_API __declspec(dllexport)
@@ -35,20 +36,15 @@
#define QTMOVIEWIN_API __declspec(dllimport)
#endif
-class QTMovieWin;
-class QTMovieWinPrivate;
+class QTMovie;
+class QTMoviePrivate;
+typedef struct MovieType** Movie;
-class QTMovieWinClient {
+class QTMovieClient {
public:
- virtual void movieEnded(QTMovieWin*) = 0;
- virtual void movieLoadStateChanged(QTMovieWin*) = 0;
- virtual void movieTimeChanged(QTMovieWin*) = 0;
- virtual void movieNewImageAvailable(QTMovieWin*) = 0;
-};
-
-class QTMovieWinFullscreenClient {
-public:
- virtual LRESULT fullscreenClientWndProc(HWND, UINT message, WPARAM, LPARAM) = 0;
+ virtual void movieEnded(QTMovie*) = 0;
+ virtual void movieLoadStateChanged(QTMovie*) = 0;
+ virtual void movieTimeChanged(QTMovie*) = 0;
};
enum {
@@ -61,19 +57,20 @@ enum {
typedef const struct __CFURL * CFURLRef;
-class QTMOVIEWIN_API QTMovieWin {
+class QTMOVIEWIN_API QTMovie : public RefCounted<QTMovie> {
public:
static bool initializeQuickTime();
-
- typedef void (*SetTaskTimerDelayFunc)(double);
- typedef void (*StopTaskTimerFunc)();
- static void setTaskTimerFuncs(SetTaskTimerDelayFunc, StopTaskTimerFunc);
static void taskTimerFired();
- QTMovieWin(QTMovieWinClient*);
- ~QTMovieWin();
+ QTMovie(QTMovieClient*);
+ ~QTMovie();
+
+ void addClient(QTMovieClient*);
+ void removeClient(QTMovieClient*);
void load(const UChar* url, int len, bool preservesPitch);
+ void load(CFURLRef, bool preservesPitch);
+
long loadState() const;
float maxTimeLoaded() const;
@@ -93,13 +90,10 @@ public:
unsigned dataSize() const;
void getNaturalSize(int& width, int& height);
- void setSize(int width, int height);
-
- void setVisible(bool);
- void paint(HDC, int x, int y);
- void getCurrentFrameInfo(void*& buffer, unsigned& bitsPerPixel, unsigned& rowBytes, unsigned& width, unsigned& height);
void disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned& totalTrackCount);
+
+ bool isDisabled() const;
void setDisabled(bool);
bool hasVideo() const;
@@ -111,17 +105,11 @@ public:
static unsigned countSupportedTypes();
static void getSupportedType(unsigned index, const UChar*& str, unsigned& len);
- // Returns the full-screen window created
- HWND enterFullscreen(QTMovieWinFullscreenClient*);
- void exitFullscreen();
+ Movie getMovieHandle() const;
private:
- void load(CFURLRef, bool preservesPitch);
- static LRESULT fullscreenWndProc(HWND, UINT message, WPARAM, LPARAM);
-
- QTMovieWinPrivate* m_private;
- bool m_disabled;
- friend class QTMovieWinPrivate;
+ QTMoviePrivate* m_private;
+ friend class QTMoviePrivate;
};
#endif
diff --git a/WebCore/platform/graphics/win/QTMovieGWorld.cpp b/WebCore/platform/graphics/win/QTMovieGWorld.cpp
new file mode 100644
index 0000000..e13f732
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTMovieGWorld.cpp
@@ -0,0 +1,465 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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"
+
+#include "QTMovieGWorld.h"
+
+#include "QTMovieTask.h"
+#include <GXMath.h>
+#include <Movies.h>
+#include <QTML.h>
+#include <QuickTimeComponents.h>
+#include <wtf/Assertions.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+using namespace std;
+
+static const long minimumQuickTimeVersion = 0x07300000; // 7.3
+
+static LPCTSTR fullscreenQTMovieGWorldPointerProp = TEXT("fullscreenQTMovieGWorldPointer");
+
+// Resizing GWorlds is slow, give them a minimum size so size of small
+// videos can be animated smoothly
+static const int cGWorldMinWidth = 640;
+static const int cGWorldMinHeight = 360;
+
+static const float cNonContinuousTimeChange = 0.2f;
+
+union UppParam {
+ long longValue;
+ void* ptr;
+};
+
+static MovieDrawingCompleteUPP gMovieDrawingCompleteUPP = 0;
+static HashSet<QTMovieGWorldPrivate*>* gTaskList;
+static Vector<CFStringRef>* gSupportedTypes = 0;
+static SInt32 quickTimeVersion = 0;
+
+class QTMovieGWorldPrivate : public QTMovieClient {
+public:
+ QTMovieGWorldPrivate(QTMovieGWorld* movieWin);
+ virtual ~QTMovieGWorldPrivate();
+
+ void registerDrawingCallback();
+ void unregisterDrawingCallback();
+ void drawingComplete();
+ void updateGWorld();
+ void createGWorld();
+ void deleteGWorld();
+ void clearGWorld();
+ void updateMovieSize();
+
+ void setSize(int, int);
+
+ virtual void movieEnded(QTMovie*);
+ virtual void movieLoadStateChanged(QTMovie*);
+ virtual void movieTimeChanged(QTMovie*);
+
+ QTMovieGWorld* m_movieWin;
+ RefPtr<QTMovie> m_qtMovie;
+ Movie m_movie;
+ QTMovieGWorldClient* m_client;
+ long m_loadState;
+ int m_width;
+ int m_height;
+ bool m_visible;
+ GWorldPtr m_gWorld;
+ int m_gWorldWidth;
+ int m_gWorldHeight;
+ GWorldPtr m_savedGWorld;
+ float m_widthScaleFactor;
+ float m_heightScaleFactor;
+#if !ASSERT_DISABLED
+ bool m_scaleCached;
+#endif
+ WindowPtr m_fullscreenWindow;
+ GWorldPtr m_fullscreenOrigGWorld;
+ Rect m_fullscreenRect;
+ QTMovieGWorldFullscreenClient* m_fullscreenClient;
+ char* m_fullscreenRestoreState;
+ bool m_disabled;
+};
+
+QTMovieGWorldPrivate::QTMovieGWorldPrivate(QTMovieGWorld* movieWin)
+ : m_movieWin(movieWin)
+ , m_movie(0)
+ , m_client(0)
+ , m_loadState(0)
+ , m_width(0)
+ , m_height(0)
+ , m_visible(false)
+ , m_gWorld(0)
+ , m_gWorldWidth(0)
+ , m_gWorldHeight(0)
+ , m_savedGWorld(0)
+ , m_widthScaleFactor(1)
+ , m_heightScaleFactor(1)
+#if !ASSERT_DISABLED
+ , m_scaleCached(false)
+#endif
+ , m_fullscreenWindow(0)
+ , m_fullscreenOrigGWorld(0)
+ , m_fullscreenClient(0)
+ , m_fullscreenRestoreState(0)
+ , m_disabled(false)
+ , m_qtMovie(0)
+{
+ Rect rect = { 0, 0, 0, 0 };
+ m_fullscreenRect = rect;
+}
+
+QTMovieGWorldPrivate::~QTMovieGWorldPrivate()
+{
+ ASSERT(!m_fullscreenWindow);
+
+ if (m_gWorld)
+ deleteGWorld();
+}
+
+pascal OSErr movieDrawingCompleteProc(Movie movie, long data)
+{
+ UppParam param;
+ param.longValue = data;
+ QTMovieGWorldPrivate* mp = static_cast<QTMovieGWorldPrivate*>(param.ptr);
+ if (mp)
+ mp->drawingComplete();
+ return 0;
+}
+
+void QTMovieGWorldPrivate::registerDrawingCallback()
+{
+ if (!gMovieDrawingCompleteUPP)
+ gMovieDrawingCompleteUPP = NewMovieDrawingCompleteUPP(movieDrawingCompleteProc);
+
+ UppParam param;
+ param.ptr = this;
+ SetMovieDrawingCompleteProc(m_movie, movieDrawingCallWhenChanged, gMovieDrawingCompleteUPP, param.longValue);
+}
+
+void QTMovieGWorldPrivate::unregisterDrawingCallback()
+{
+ SetMovieDrawingCompleteProc(m_movie, movieDrawingCallWhenChanged, 0, 0);
+}
+
+void QTMovieGWorldPrivate::drawingComplete()
+{
+ if (!m_gWorld || m_movieWin->m_private->m_disabled || m_loadState < QTMovieLoadStateLoaded)
+ return;
+ m_client->movieNewImageAvailable(m_movieWin);
+}
+
+void QTMovieGWorldPrivate::updateGWorld()
+{
+ bool shouldBeVisible = m_visible;
+ if (!m_height || !m_width)
+ shouldBeVisible = false;
+
+ if (shouldBeVisible && !m_gWorld)
+ createGWorld();
+ else if (!shouldBeVisible && m_gWorld)
+ deleteGWorld();
+ else if (m_gWorld && (m_width > m_gWorldWidth || m_height > m_gWorldHeight)) {
+ // need a bigger, better gWorld
+ deleteGWorld();
+ createGWorld();
+ }
+}
+
+void QTMovieGWorldPrivate::createGWorld()
+{
+ ASSERT(!m_gWorld);
+ if (!m_movie || m_loadState < QTMovieLoadStateLoaded)
+ return;
+
+ m_gWorldWidth = max(cGWorldMinWidth, m_width);
+ m_gWorldHeight = max(cGWorldMinHeight, m_height);
+ Rect bounds;
+ bounds.top = 0;
+ bounds.left = 0;
+ bounds.right = m_gWorldWidth;
+ bounds.bottom = m_gWorldHeight;
+ OSErr err = QTNewGWorld(&m_gWorld, k32BGRAPixelFormat, &bounds, 0, 0, 0);
+ if (err)
+ return;
+ GetMovieGWorld(m_movie, &m_savedGWorld, 0);
+ SetMovieGWorld(m_movie, m_gWorld, 0);
+ bounds.right = m_width;
+ bounds.bottom = m_height;
+ SetMovieBox(m_movie, &bounds);
+}
+
+void QTMovieGWorldPrivate::clearGWorld()
+{
+ if (!m_movie || !m_gWorld)
+ return;
+
+ GrafPtr savePort;
+ GetPort(&savePort);
+ MacSetPort((GrafPtr)m_gWorld);
+
+ Rect bounds;
+ bounds.top = 0;
+ bounds.left = 0;
+ bounds.right = m_gWorldWidth;
+ bounds.bottom = m_gWorldHeight;
+ EraseRect(&bounds);
+
+ MacSetPort(savePort);
+}
+
+void QTMovieGWorldPrivate::setSize(int width, int height)
+{
+ if (m_width == width && m_height == height)
+ return;
+ m_width = width;
+ m_height = height;
+
+ // Do not change movie box before reaching load state loaded as we grab
+ // the initial size when task() sees that state for the first time, and
+ // we need the initial size to be able to scale movie properly.
+ if (!m_movie || m_loadState < QTMovieLoadStateLoaded)
+ return;
+
+#if !ASSERT_DISABLED
+ ASSERT(m_scaleCached);
+#endif
+
+ updateMovieSize();
+}
+
+void QTMovieGWorldPrivate::updateMovieSize()
+{
+ if (!m_movie || m_loadState < QTMovieLoadStateLoaded)
+ return;
+
+ Rect bounds;
+ bounds.top = 0;
+ bounds.left = 0;
+ bounds.right = m_width;
+ bounds.bottom = m_height;
+ SetMovieBox(m_movie, &bounds);
+ updateGWorld();
+}
+
+
+void QTMovieGWorldPrivate::deleteGWorld()
+{
+ ASSERT(m_gWorld);
+ if (m_movie)
+ SetMovieGWorld(m_movie, m_savedGWorld, 0);
+ m_savedGWorld = 0;
+ DisposeGWorld(m_gWorld);
+ m_gWorld = 0;
+ m_gWorldWidth = 0;
+ m_gWorldHeight = 0;
+}
+
+void QTMovieGWorldPrivate::movieEnded(QTMovie*)
+{
+ // Do nothing
+}
+
+void QTMovieGWorldPrivate::movieLoadStateChanged(QTMovie* movie)
+{
+ long loadState = GetMovieLoadState(movie->getMovieHandle());
+ if (loadState != m_loadState) {
+
+ // we only need to erase the movie gworld when the load state changes to loaded while it
+ // is visible as the gworld is destroyed/created when visibility changes
+ bool movieNewlyPlayable = loadState >= QTMovieLoadStateLoaded && m_loadState < QTMovieLoadStateLoaded;
+ m_loadState = loadState;
+
+ if (movieNewlyPlayable) {
+ updateMovieSize();
+ if (m_visible)
+ clearGWorld();
+ }
+ }
+}
+
+void QTMovieGWorldPrivate::movieTimeChanged(QTMovie*)
+{
+ // Do nothing
+}
+
+QTMovieGWorld::QTMovieGWorld(QTMovieGWorldClient* client)
+ : m_private(new QTMovieGWorldPrivate(this))
+{
+ m_private->m_client = client;
+}
+
+QTMovieGWorld::~QTMovieGWorld()
+{
+ delete m_private;
+}
+
+void QTMovieGWorld::setSize(int width, int height)
+{
+ m_private->setSize(width, height);
+ QTMovieTask::sharedTask()->updateTaskTimer();
+}
+
+void QTMovieGWorld::setVisible(bool b)
+{
+ m_private->m_visible = b;
+ m_private->updateGWorld();
+}
+
+void QTMovieGWorld::getCurrentFrameInfo(void*& buffer, unsigned& bitsPerPixel, unsigned& rowBytes, unsigned& width, unsigned& height)
+{
+ if (!m_private->m_gWorld) {
+ buffer = 0;
+ bitsPerPixel = 0;
+ rowBytes = 0;
+ width = 0;
+ height = 0;
+ return;
+ }
+ PixMapHandle offscreenPixMap = GetGWorldPixMap(m_private->m_gWorld);
+ buffer = (*offscreenPixMap)->baseAddr;
+ bitsPerPixel = (*offscreenPixMap)->pixelSize;
+ rowBytes = (*offscreenPixMap)->rowBytes & 0x3FFF;
+ width = m_private->m_width;
+ height = m_private->m_height;
+}
+
+void QTMovieGWorld::paint(HDC hdc, int x, int y)
+{
+ if (!m_private->m_gWorld)
+ return;
+
+ HDC hdcSrc = static_cast<HDC>(GetPortHDC(reinterpret_cast<GrafPtr>(m_private->m_gWorld)));
+ if (!hdcSrc)
+ return;
+
+ // FIXME: If we could determine the movie has no alpha, we could use BitBlt for those cases, which might be faster.
+ BLENDFUNCTION blendFunction;
+ blendFunction.BlendOp = AC_SRC_OVER;
+ blendFunction.BlendFlags = 0;
+ blendFunction.SourceConstantAlpha = 255;
+ blendFunction.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(hdc, x, y, m_private->m_width, m_private->m_height, hdcSrc,
+ 0, 0, m_private->m_width, m_private->m_height, blendFunction);
+}
+
+void QTMovieGWorld::setDisabled(bool b)
+{
+ m_private->m_disabled = b;
+}
+
+bool QTMovieGWorld::isDisabled() const
+{
+ return m_private->m_disabled;
+}
+
+LRESULT QTMovieGWorld::fullscreenWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ QTMovieGWorld* movie = static_cast<QTMovieGWorld*>(GetProp(wnd, fullscreenQTMovieGWorldPointerProp));
+
+ if (message == WM_DESTROY)
+ RemoveProp(wnd, fullscreenQTMovieGWorldPointerProp);
+
+ if (!movie)
+ return DefWindowProc(wnd, message, wParam, lParam);
+
+ return movie->m_private->m_fullscreenClient->fullscreenClientWndProc(wnd, message, wParam, lParam);
+}
+
+HWND QTMovieGWorld::enterFullscreen(QTMovieGWorldFullscreenClient* client)
+{
+ m_private->m_fullscreenClient = client;
+
+ BeginFullScreen(&m_private->m_fullscreenRestoreState, 0, 0, 0, &m_private->m_fullscreenWindow, 0, fullScreenAllowEvents);
+ QTMLSetWindowWndProc(m_private->m_fullscreenWindow, fullscreenWndProc);
+ CreatePortAssociation(GetPortNativeWindow(m_private->m_fullscreenWindow), 0, 0);
+
+ GetMovieBox(m_private->m_movie, &m_private->m_fullscreenRect);
+ GetMovieGWorld(m_private->m_movie, &m_private->m_fullscreenOrigGWorld, 0);
+ SetMovieGWorld(m_private->m_movie, reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow), GetGWorldDevice(reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow)));
+
+ // Set the size of the box to preserve aspect ratio
+ Rect rect = m_private->m_fullscreenWindow->portRect;
+
+ float movieRatio = static_cast<float>(m_private->m_width) / m_private->m_height;
+ int windowWidth = rect.right - rect.left;
+ int windowHeight = rect.bottom - rect.top;
+ float windowRatio = static_cast<float>(windowWidth) / windowHeight;
+ int actualWidth = (windowRatio > movieRatio) ? (windowHeight * movieRatio) : windowWidth;
+ int actualHeight = (windowRatio < movieRatio) ? (windowWidth / movieRatio) : windowHeight;
+ int offsetX = (windowWidth - actualWidth) / 2;
+ int offsetY = (windowHeight - actualHeight) / 2;
+
+ rect.left = offsetX;
+ rect.right = offsetX + actualWidth;
+ rect.top = offsetY;
+ rect.bottom = offsetY + actualHeight;
+
+ SetMovieBox(m_private->m_movie, &rect);
+ ShowHideTaskBar(true);
+
+ // Set the 'this' pointer on the HWND
+ HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
+ SetProp(wnd, fullscreenQTMovieGWorldPointerProp, static_cast<HANDLE>(this));
+
+ return wnd;
+}
+
+void QTMovieGWorld::exitFullscreen()
+{
+ if (!m_private->m_fullscreenWindow)
+ return;
+
+ HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
+ DestroyPortAssociation(reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow));
+ SetMovieGWorld(m_private->m_movie, m_private->m_fullscreenOrigGWorld, 0);
+ EndFullScreen(m_private->m_fullscreenRestoreState, 0L);
+ SetMovieBox(m_private->m_movie, &m_private->m_fullscreenRect);
+ m_private->m_fullscreenWindow = 0;
+}
+
+void QTMovieGWorld::setMovie(PassRefPtr<QTMovie> movie)
+{
+ if (m_private->m_qtMovie) {
+ m_private->unregisterDrawingCallback();
+ m_private->m_qtMovie->removeClient(m_private);
+ m_private->m_qtMovie = 0;
+ m_private->m_movie = 0;
+ }
+
+ m_private->m_qtMovie = movie;
+
+ if (m_private->m_qtMovie) {
+ m_private->m_qtMovie->addClient(m_private);
+ m_private->m_movie = m_private->m_qtMovie->getMovieHandle();
+ m_private->registerDrawingCallback();
+ }
+}
+
+QTMovie* QTMovieGWorld::movie() const
+{
+ return m_private->m_qtMovie.get();
+}
diff --git a/WebCore/platform/graphics/win/QTMovieGWorld.h b/WebCore/platform/graphics/win/QTMovieGWorld.h
new file mode 100644
index 0000000..495fe25
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTMovieGWorld.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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 QTMovieGWorld_h
+#define QTMovieGWorld_h
+
+
+#include "QTMovie.h"
+#include <Unicode.h>
+#include <WTF/RefCounted.h>
+#include <WTF/RefPtr.h>
+#include <windows.h>
+
+#ifdef QTMOVIEWIN_EXPORTS
+#define QTMOVIEWIN_API __declspec(dllexport)
+#else
+#define QTMOVIEWIN_API __declspec(dllimport)
+#endif
+
+class QTMovieGWorld;
+class QTMovieGWorldPrivate;
+
+class QTMovieGWorldClient {
+public:
+ virtual void movieNewImageAvailable(QTMovieGWorld*) = 0;
+};
+
+class QTMovieGWorldFullscreenClient {
+public:
+ virtual LRESULT fullscreenClientWndProc(HWND, UINT message, WPARAM, LPARAM) = 0;
+};
+
+class QTMOVIEWIN_API QTMovieGWorld : public RefCounted<QTMovieGWorld> {
+public:
+ QTMovieGWorld(QTMovieGWorldClient*);
+ ~QTMovieGWorld();
+
+ void getNaturalSize(int& width, int& height);
+ void setSize(int width, int height);
+
+ void setVisible(bool);
+ void paint(HDC, int x, int y);
+ void getCurrentFrameInfo(void*& buffer, unsigned& bitsPerPixel, unsigned& rowBytes, unsigned& width, unsigned& height);
+
+ void setDisabled(bool);
+ bool isDisabled() const;
+
+ // Returns the full-screen window created
+ HWND enterFullscreen(QTMovieGWorldFullscreenClient*);
+ void exitFullscreen();
+
+ void setMovie(PassRefPtr<QTMovie>);
+ QTMovie* movie() const;
+
+private:
+ static LRESULT fullscreenWndProc(HWND, UINT message, WPARAM, LPARAM);
+
+ QTMovieGWorldPrivate* m_private;
+ friend class QTMovieGWorldPrivate;
+};
+
+#endif
diff --git a/WebCore/platform/graphics/win/QTMovieTask.cpp b/WebCore/platform/graphics/win/QTMovieTask.cpp
new file mode 100644
index 0000000..8713588
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTMovieTask.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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"
+
+#include "QTMovieTask.h"
+
+// Put Movies.h first so build failures here point clearly to QuickTime
+#include <Movies.h>
+
+#include <wtf/HashSet.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
+
+QTMovieTask::QTMovieTask()
+ : m_setTaskTimerDelay(0)
+ , m_stopTaskTimer(0)
+{
+}
+
+QTMovieTask::~QTMovieTask()
+{
+}
+
+QTMovieTask* QTMovieTask::sharedTask()
+{
+ static QTMovieTask* s_sharedTask = new QTMovieTask;
+ return s_sharedTask;
+}
+
+void QTMovieTask::updateTaskTimer(double maxInterval, double minInterval)
+{
+ ASSERT(m_setTaskTimerDelay);
+ if (!m_setTaskTimerDelay)
+ return;
+
+ ASSERT(m_stopTaskTimer);
+ if (!m_taskList.size() && m_stopTaskTimer) {
+ m_stopTaskTimer();
+ return;
+ }
+
+ long intervalInMS;
+ OSStatus status = QTGetTimeUntilNextTask(&intervalInMS, 1000);
+ double interval = intervalInMS / 1000.0;
+ if (interval < minInterval)
+ interval = minInterval;
+ if (interval > maxInterval)
+ interval = maxInterval;
+ m_setTaskTimerDelay(interval);
+}
+
+void QTMovieTask::fireTaskClients()
+{
+ Vector<QTMovieTaskClient*> clients;
+ copyToVector(m_taskList, clients);
+ for (Vector<QTMovieTaskClient*>::iterator i = clients.begin(); i != clients.end(); ++i)
+ (*i)->task();
+}
+
+void QTMovieTask::addTaskClient(QTMovieTaskClient* client)
+{
+ ASSERT(client);
+ if (!client)
+ return;
+
+ m_taskList.add(client);
+}
+
+void QTMovieTask::removeTaskClient(QTMovieTaskClient* client)
+{
+ ASSERT(client);
+ if (!client)
+ return;
+
+ m_taskList.remove(client);
+}
+
+void QTMovieTask::setTaskTimerFuncs(SetTaskTimerDelayFunc setTaskTimerDelay, StopTaskTimerFunc stopTaskTimer)
+{
+ m_setTaskTimerDelay = setTaskTimerDelay;
+ m_stopTaskTimer = stopTaskTimer;
+}
+
diff --git a/WebCore/platform/graphics/win/QTMovieTask.h b/WebCore/platform/graphics/win/QTMovieTask.h
new file mode 100644
index 0000000..e394d6e
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTMovieTask.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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 QTMovieTask_h
+#define QTMovieTask_h
+
+#include <WTF/HashSet.h>
+
+#ifdef QTMOVIEWIN_EXPORTS
+#define QTMOVIEWIN_API __declspec(dllexport)
+#else
+#define QTMOVIEWIN_API __declspec(dllimport)
+#endif
+
+class QTMovieTaskClient {
+public:
+ virtual void task() = 0;
+};
+
+typedef void (*SetTaskTimerDelayFunc)(double);
+typedef void (*StopTaskTimerFunc)();
+
+class QTMOVIEWIN_API QTMovieTask {
+public:
+ static QTMovieTask* sharedTask();
+
+ void addTaskClient(QTMovieTaskClient* client);
+ void removeTaskClient(QTMovieTaskClient*);
+ void fireTaskClients();
+
+ void updateTaskTimer(double maxInterval = 1.0, double minInterval = 1.0 / 30);
+ void setTaskTimerFuncs(SetTaskTimerDelayFunc setTaskTimerDelay, StopTaskTimerFunc stopTaskTimer);
+
+protected:
+ QTMovieTask();
+ ~QTMovieTask();
+
+ SetTaskTimerDelayFunc m_setTaskTimerDelay;
+ StopTaskTimerFunc m_stopTaskTimer;
+ HashSet<QTMovieTaskClient*> m_taskList;
+
+private:
+ QTMovieTask(const QTMovieTask&);
+ QTMovieTask& operator=(const QTMovieTask&);
+};
+
+#endif
diff --git a/WebCore/platform/graphics/win/QTMovieVisualContext.cpp b/WebCore/platform/graphics/win/QTMovieVisualContext.cpp
new file mode 100644
index 0000000..9c08cd9
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTMovieVisualContext.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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"
+
+#include "QTMovieVisualContext.h"
+
+#include "QTMovieTask.h"
+#include <CVBase.h>
+#include <CVHostTime.h>
+#include <ImageCompression.h>
+#include <Movies.h>
+#include <windows.h>
+
+struct QTCVTimeStamp {
+ CVTimeStamp t;
+};
+
+class QTMovieVisualContextPriv {
+public:
+ QTMovieVisualContextPriv(QTMovieVisualContext* parent, QTMovieVisualContextClient* client, CFDictionaryRef options);
+ ~QTMovieVisualContextPriv();
+
+ bool isImageAvailableForTime(const QTCVTimeStamp*) const;
+ QTPixelBuffer imageForTime(const QTCVTimeStamp*);
+ void task();
+
+ QTVisualContextRef visualContextRef();
+
+ void setMovie(PassRefPtr<QTMovie>);
+ QTMovie* movie() const;
+
+ static void imageAvailableCallback(QTVisualContextRef visualContext, const CVTimeStamp *timeStamp, void *refCon);
+
+private:
+ QTMovieVisualContext* m_parent;
+ QTMovieVisualContextClient* m_client;
+ QTVisualContextRef m_visualContext;
+ RefPtr<QTMovie> m_movie;
+
+};
+
+QTMovieVisualContextPriv::QTMovieVisualContextPriv(QTMovieVisualContext* parent, QTMovieVisualContextClient* client, CFDictionaryRef options)
+ : m_parent(parent)
+ , m_client(client)
+ , m_visualContext(0)
+{
+ typedef OSStatus ( __cdecl *pfnQTPixelBufferContextCreate)(CFAllocatorRef, CFDictionaryRef, QTVisualContextRef*);
+ static pfnQTPixelBufferContextCreate pPixelBufferContextCreate = 0;
+ if (!pPixelBufferContextCreate) {
+ HMODULE qtmlDLL = ::LoadLibraryW(L"QTMLClient.dll");
+ if (!qtmlDLL)
+ return;
+ pPixelBufferContextCreate = reinterpret_cast<pfnQTPixelBufferContextCreate>(GetProcAddress(qtmlDLL, "QTPixelBufferContextCreate"));
+ if (!pPixelBufferContextCreate)
+ return;
+ }
+
+ OSStatus status = pPixelBufferContextCreate(kCFAllocatorDefault, options, &m_visualContext);
+ if (status == noErr && m_visualContext)
+ QTVisualContextSetImageAvailableCallback(m_visualContext, &QTMovieVisualContextPriv::imageAvailableCallback, static_cast<void*>(this));
+}
+
+QTMovieVisualContextPriv::~QTMovieVisualContextPriv()
+{
+}
+
+bool QTMovieVisualContextPriv::isImageAvailableForTime(const QTCVTimeStamp* timeStamp) const
+{
+ if (!m_visualContext)
+ return false;
+
+ return QTVisualContextIsNewImageAvailable(m_visualContext, reinterpret_cast<const CVTimeStamp*>(timeStamp));
+}
+
+QTPixelBuffer QTMovieVisualContextPriv::imageForTime(const QTCVTimeStamp* timeStamp)
+{
+ QTPixelBuffer pixelBuffer;
+ if (m_visualContext) {
+ CVImageBufferRef newImage = 0;
+ OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, kCFAllocatorDefault, reinterpret_cast<const CVTimeStamp*>(timeStamp), &newImage);
+ if (status == noErr)
+ pixelBuffer.adopt(newImage);
+ }
+ return pixelBuffer;
+}
+
+void QTMovieVisualContextPriv::task()
+{
+ if (m_visualContext)
+ QTVisualContextTask(m_visualContext);
+}
+
+QTVisualContextRef QTMovieVisualContextPriv::visualContextRef()
+{
+ return m_visualContext;
+}
+
+void QTMovieVisualContextPriv::setMovie(PassRefPtr<QTMovie> movie)
+{
+ if (movie == m_movie)
+ return;
+
+ if (m_movie) {
+ SetMovieVisualContext(m_movie->getMovieHandle(), 0);
+ m_movie = 0;
+ }
+
+ if (movie)
+ OSStatus status = SetMovieVisualContext(movie->getMovieHandle(), m_visualContext);
+
+ m_movie = movie;
+}
+
+QTMovie* QTMovieVisualContextPriv::movie() const
+{
+ return m_movie.get();
+}
+
+void QTMovieVisualContextPriv::imageAvailableCallback(QTVisualContextRef visualContext, const CVTimeStamp *timeStamp, void *refCon)
+{
+ if (!refCon)
+ return;
+
+ QTMovieVisualContextPriv* vc = static_cast<QTMovieVisualContextPriv*>(refCon);
+ if (!vc->m_client)
+ return;
+
+ vc->m_client->imageAvailableForTime(reinterpret_cast<const QTCVTimeStamp*>(timeStamp));
+}
+
+static OSStatus SetNumberValue(CFMutableDictionaryRef inDict, CFStringRef inKey, SInt32 inValue)
+{
+ CFNumberRef number;
+
+ number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue);
+ if (!number)
+ return coreFoundationUnknownErr;
+
+ CFDictionarySetValue(inDict, inKey, number);
+
+ CFRelease(number);
+
+ return noErr;
+}
+
+CFDictionaryRef QTMovieVisualContext::getCGImageOptions()
+{
+ static CFDictionaryRef options = 0;
+
+ if (!options) {
+ CFMutableDictionaryRef pixelBufferOptions = 0;
+ CFMutableDictionaryRef visualContextOptions = 0;
+ OSStatus status = noErr;
+
+ // Pixel Buffer attributes
+ pixelBufferOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ // Use the k32BGRAPixelFormat, as QuartzCore will be able to use the pixels directly,
+ // without needing an aditional copy or rendering pass:s
+ SetNumberValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32BGRAPixelFormat);
+
+ // alignment
+ SetNumberValue(pixelBufferOptions, kCVPixelBufferBytesPerRowAlignmentKey, 16);
+
+ // compatability
+ SetNumberValue(pixelBufferOptions, kCVPixelBufferCGImageCompatibilityKey, 1);
+
+ // QT Visual Context attributes
+ visualContextOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ // set the pixel buffer attributes for the visual context
+ CFDictionarySetValue(visualContextOptions,
+ kQTVisualContextPixelBufferAttributesKey,
+ pixelBufferOptions);
+
+ if (pixelBufferOptions)
+ CFRelease(pixelBufferOptions);
+
+ options = visualContextOptions;
+ }
+
+ return options;
+}
+
+QTMovieVisualContext::QTMovieVisualContext(QTMovieVisualContextClient* client, CFDictionaryRef options)
+ : m_private(new QTMovieVisualContextPriv(this, client, options))
+{
+}
+
+QTMovieVisualContext::~QTMovieVisualContext()
+{
+}
+
+bool QTMovieVisualContext::isImageAvailableForTime(const QTCVTimeStamp* timeStamp) const
+{
+ return m_private->isImageAvailableForTime(timeStamp);
+}
+
+QTPixelBuffer QTMovieVisualContext::imageForTime(const QTCVTimeStamp* timeStamp)
+{
+ return m_private->imageForTime(timeStamp);
+}
+
+void QTMovieVisualContext::task()
+{
+ m_private->task();
+}
+
+QTVisualContextRef QTMovieVisualContext::visualContextRef()
+{
+ return m_private->visualContextRef();
+}
+
+void QTMovieVisualContext::setMovie(PassRefPtr<QTMovie> movie)
+{
+ m_private->setMovie(movie);
+}
+
+QTMovie* QTMovieVisualContext::movie() const
+{
+ return m_private->movie();
+}
+
+double QTMovieVisualContext::currentHostTime()
+{
+ return CVGetCurrentHostTime() / CVGetHostClockFrequency();
+}
diff --git a/WebCore/platform/graphics/win/QTMovieVisualContext.h b/WebCore/platform/graphics/win/QTMovieVisualContext.h
new file mode 100644
index 0000000..7afe589
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTMovieVisualContext.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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 QTMovieVisualContext_h
+#define QTMovieVisualContext_h
+
+#ifdef QTMOVIEWIN_EXPORTS
+#define QTMOVIEWIN_API __declspec(dllexport)
+#else
+#define QTMOVIEWIN_API __declspec(dllimport)
+#endif
+
+#include "QTMovie.h"
+#include "QTMovieTask.h"
+#include "QTPixelBuffer.h"
+#include <WTF/OwnPtr.h>
+#include <WTF/RefCounted.h>
+
+typedef struct OpaqueQTVisualContext* QTVisualContextRef;
+
+// QTCVTimeStamp is a struct containing only a CVTimeStamp. This is to
+// work around the inability of CVTimeStamp to be forward declared, in
+// addition to it being declared in different header files when building
+// the QTMovieWin and WebCore projects.
+struct QTCVTimeStamp;
+
+class QTMovieVisualContextClient {
+public:
+ virtual void imageAvailableForTime(const QTCVTimeStamp*) = 0;
+};
+
+class QTMOVIEWIN_API QTMovieVisualContext : public RefCounted<QTMovieVisualContext> {
+public:
+ QTMovieVisualContext(QTMovieVisualContextClient*, CFDictionaryRef options = 0);
+ ~QTMovieVisualContext();
+
+ bool isImageAvailableForTime(const QTCVTimeStamp*) const;
+ QTPixelBuffer imageForTime(const QTCVTimeStamp*);
+ void task();
+
+ QTVisualContextRef visualContextRef();
+
+ void setMovie(PassRefPtr<QTMovie>);
+ QTMovie* movie() const;
+
+ static CFDictionaryRef getCGImageOptions();
+ static double currentHostTime();
+
+protected:
+ void setupVisualContext();
+
+ friend class QTMovieVisualContextPriv;
+ OwnPtr<QTMovieVisualContextPriv> m_private;
+};
+
+#endif
diff --git a/WebCore/platform/graphics/win/QTPixelBuffer.cpp b/WebCore/platform/graphics/win/QTPixelBuffer.cpp
new file mode 100644
index 0000000..657b68e
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTPixelBuffer.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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"
+
+#include "QTPixelBuffer.h"
+
+#include <CFString.h>
+#include <CGColorSpace.h>
+#include <CGImage.h>
+#include <CVPixelBuffer.h>
+#include <QuickDraw.h>
+#include <memory.h>
+
+QTPixelBuffer::QTPixelBuffer()
+ : m_pixelBuffer(0)
+{
+}
+
+QTPixelBuffer::QTPixelBuffer(const QTPixelBuffer& p)
+ : m_pixelBuffer(p.m_pixelBuffer)
+{
+ CVPixelBufferRetain(m_pixelBuffer);
+}
+
+QTPixelBuffer::QTPixelBuffer(CVPixelBufferRef ref)
+ : m_pixelBuffer(ref)
+{
+ CVPixelBufferRetain(m_pixelBuffer);
+}
+
+QTPixelBuffer::~QTPixelBuffer()
+{
+ clear();
+}
+
+QTPixelBuffer& QTPixelBuffer::operator=(const QTPixelBuffer& p)
+{
+ set(p.m_pixelBuffer);
+ return *this;
+}
+
+void QTPixelBuffer::set(CVPixelBufferRef ref)
+{
+ CVPixelBufferRetain(ref);
+ CVPixelBufferRelease(m_pixelBuffer);
+ m_pixelBuffer = ref;
+}
+
+CVPixelBufferRef QTPixelBuffer::pixelBufferRef()
+{
+ return m_pixelBuffer;
+}
+
+void QTPixelBuffer::adopt(CVPixelBufferRef ref)
+{
+ if (ref == m_pixelBuffer)
+ return;
+ CVPixelBufferRelease(m_pixelBuffer);
+ m_pixelBuffer = ref;
+}
+
+void QTPixelBuffer::clear()
+{
+ CVPixelBufferRelease(m_pixelBuffer);
+ m_pixelBuffer = 0;
+}
+
+CVReturn QTPixelBuffer::lockBaseAddress()
+{
+ return CVPixelBufferLockBaseAddress(m_pixelBuffer, 0);
+}
+
+CVReturn QTPixelBuffer::unlockBaseAddress()
+{
+ return CVPixelBufferUnlockBaseAddress(m_pixelBuffer, 0);
+}
+
+void* QTPixelBuffer::baseAddress()
+{
+ return CVPixelBufferGetBaseAddress(m_pixelBuffer);
+}
+
+size_t QTPixelBuffer::width() const
+{
+ return CVPixelBufferGetWidth(m_pixelBuffer);
+}
+
+size_t QTPixelBuffer::height() const
+{
+ return CVPixelBufferGetHeight(m_pixelBuffer);
+}
+
+unsigned long QTPixelBuffer::pixelFormatType() const
+{
+ return CVPixelBufferGetPixelFormatType(m_pixelBuffer);
+}
+
+bool QTPixelBuffer::pixelFormatIs32ARGB() const
+{
+ return CVPixelBufferGetPixelFormatType(m_pixelBuffer) == k32ARGBPixelFormat;
+}
+
+bool QTPixelBuffer::pixelFormatIs32BGRA() const
+{
+ return CVPixelBufferGetPixelFormatType(m_pixelBuffer) == k32BGRAPixelFormat;
+}
+
+size_t QTPixelBuffer::bytesPerRow() const
+{
+ return CVPixelBufferGetBytesPerRow(m_pixelBuffer);
+}
+
+size_t QTPixelBuffer::dataSize() const
+{
+ return CVPixelBufferGetDataSize(m_pixelBuffer);
+}
+
+bool QTPixelBuffer::isPlanar() const
+{
+ return CVPixelBufferIsPlanar(m_pixelBuffer);
+}
+
+size_t QTPixelBuffer::planeCount() const
+{
+ return CVPixelBufferGetPlaneCount(m_pixelBuffer);
+}
+
+size_t QTPixelBuffer::widthOfPlane(size_t plane) const
+{
+ return CVPixelBufferGetWidthOfPlane(m_pixelBuffer, plane);
+}
+
+size_t QTPixelBuffer::heightOfPlane(size_t plane) const
+{
+ return CVPixelBufferGetHeightOfPlane(m_pixelBuffer, plane);
+}
+
+void* QTPixelBuffer::baseAddressOfPlane(size_t plane) const
+{
+ return CVPixelBufferGetBaseAddressOfPlane(m_pixelBuffer, plane);
+}
+
+size_t QTPixelBuffer::bytesPerRowOfPlane(size_t plane) const
+{
+ return CVPixelBufferGetBytesPerRowOfPlane(m_pixelBuffer, plane);
+}
+
+void QTPixelBuffer::getExtendedPixels(size_t* left, size_t* right, size_t* top, size_t* bottom) const
+{
+ return CVPixelBufferGetExtendedPixels(m_pixelBuffer, left, right, top, bottom);
+}
+
+CFDictionaryRef QTPixelBuffer::attachments() const
+{
+ return CVBufferGetAttachments(m_pixelBuffer, kCVAttachmentMode_ShouldPropagate);
+}
+
+void QTPixelBuffer::retainCallback(void* refcon)
+{
+ CVPixelBufferRetain(static_cast<CVPixelBufferRef>(refcon));
+}
+
+void QTPixelBuffer::releaseCallback(void* refcon)
+{
+ CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon));
+}
+
+void QTPixelBuffer::imageQueueReleaseCallback(unsigned int type, uint64_t id, void* refcon)
+{
+ CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon));
+}
+
+void QTPixelBuffer::dataProviderReleaseBytePointerCallback(void* refcon, const void* pointer)
+{
+ CVPixelBufferUnlockBaseAddress(static_cast<CVPixelBufferRef>(refcon), 0);
+}
+
+const void* QTPixelBuffer::dataProviderGetBytePointerCallback(void* refcon)
+{
+ CVPixelBufferLockBaseAddress(static_cast<CVPixelBufferRef>(refcon), 0);
+ return CVPixelBufferGetBaseAddress(static_cast<CVPixelBufferRef>(refcon));
+}
+
+size_t QTPixelBuffer::dataProviderGetBytesAtPositionCallback(void* refcon, void* buffer, size_t position, size_t count)
+{
+ char* data = (char*)CVPixelBufferGetBaseAddress(static_cast<CVPixelBufferRef>(refcon));
+ size_t size = CVPixelBufferGetDataSize(static_cast<CVPixelBufferRef>(refcon));
+ if (size - position < count)
+ count = size - position;
+
+ memcpy(buffer, data+position, count);
+ return count;
+}
+
+void QTPixelBuffer::dataProviderReleaseInfoCallback(void* refcon)
+{
+ CVPixelBufferRelease(static_cast<CVPixelBufferRef>(refcon));
+}
diff --git a/WebCore/platform/graphics/win/QTPixelBuffer.h b/WebCore/platform/graphics/win/QTPixelBuffer.h
new file mode 100644
index 0000000..22f8ba4
--- /dev/null
+++ b/WebCore/platform/graphics/win/QTPixelBuffer.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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 QTPixelBuffer_h
+#define QTPixelBuffer_h
+
+#ifdef QTMOVIEWIN_EXPORTS
+#define QTMOVIEWIN_API __declspec(dllexport)
+#else
+#define QTMOVIEWIN_API __declspec(dllimport)
+#endif
+
+#include <stdint.h>
+
+typedef struct __CVBuffer *CVBufferRef;
+typedef CVBufferRef CVPixelBufferRef;
+typedef struct CGImage* CGImageRef;
+typedef int32_t CVReturn;
+typedef const struct __CFDictionary * CFDictionaryRef;
+
+// QTPixelBuffer wraps QuickTime's implementation of CVPixelBuffer, so its functions are
+// safe to call within WebKit.
+class QTMOVIEWIN_API QTPixelBuffer {
+public:
+ QTPixelBuffer();
+ QTPixelBuffer(const QTPixelBuffer&);
+ QTPixelBuffer(CVPixelBufferRef);
+ QTPixelBuffer& operator=(const QTPixelBuffer&);
+ ~QTPixelBuffer();
+
+ void set(CVPixelBufferRef);
+ CVPixelBufferRef pixelBufferRef();
+ void adopt(CVPixelBufferRef);
+ void clear();
+
+ CVReturn lockBaseAddress();
+ CVReturn unlockBaseAddress();
+ void* baseAddress();
+
+ size_t width() const;
+ size_t height() const;
+ unsigned long pixelFormatType() const;
+ bool pixelFormatIs32ARGB() const;
+ bool pixelFormatIs32BGRA() const;
+ size_t bytesPerRow() const;
+ size_t dataSize() const;
+
+ bool isPlanar() const;
+ size_t planeCount() const;
+ size_t widthOfPlane(size_t) const;
+ size_t heightOfPlane(size_t) const;
+ void* baseAddressOfPlane(size_t) const;
+ size_t bytesPerRowOfPlane(size_t) const;
+
+ void getExtendedPixels(size_t* left, size_t* right, size_t* top, size_t* bottom) const;
+ CFDictionaryRef attachments() const;
+
+ // Generic CFRetain/CFRelease callbacks
+ static void releaseCallback(void* refcon);
+ static void retainCallback(void* refcon);
+
+ // CAImageQueue callbacks
+ static void imageQueueReleaseCallback(unsigned int type, uint64_t id, void* refcon);
+
+ // CGDataProvider callbacks
+ static void dataProviderReleaseBytePointerCallback(void* refcon, const void* pointer);
+ static const void* dataProviderGetBytePointerCallback(void* refcon);
+ static size_t dataProviderGetBytesAtPositionCallback(void* refcon, void* buffer, size_t position, size_t count);
+ static void dataProviderReleaseInfoCallback(void* refcon);
+
+private:
+ CVPixelBufferRef m_pixelBuffer;
+};
+
+#endif
diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
index 714a4ac..994d079 100644
--- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
+++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
@@ -231,6 +231,7 @@ WKCACFLayerRenderer::WKCACFLayerRenderer()
, m_scrollPosition(0, 0)
, m_scrollSize(1, 1)
, m_backingStoreDirty(false)
+ , m_mustResetLostDeviceBeforeRendering(false)
{
#ifndef NDEBUG
char* printTreeFlag = getenv("CA_PRINT_TREE");
@@ -422,7 +423,9 @@ void WKCACFLayerRenderer::resize()
if (!m_d3dDevice)
return;
- resetDevice();
+ // Resetting the device might fail here. But that's OK, because if it does it we will attempt to
+ // reset the device the next time we try to render.
+ resetDevice(ChangedWindowSize);
if (m_rootLayer) {
m_rootLayer->setFrame(bounds());
@@ -491,6 +494,12 @@ void WKCACFLayerRenderer::render(const Vector<CGRect>& dirtyRects)
{
ASSERT(m_d3dDevice);
+ if (m_mustResetLostDeviceBeforeRendering && !resetDevice(LostDevice)) {
+ // We can't reset the device right now. Try again soon.
+ renderSoon();
+ return;
+ }
+
// Flush the root layer to the render tree.
WKCACFContextFlusher::shared().flushAllContexts();
@@ -547,10 +556,12 @@ void WKCACFLayerRenderer::render(const Vector<CGRect>& dirtyRects)
err = m_d3dDevice->Present(0, 0, 0, 0);
if (err == D3DERR_DEVICELOST) {
- // Lost device situation.
- CARenderOGLPurge(m_renderer);
- resetDevice();
CARenderUpdateAddRect(u, &bounds);
+ if (!resetDevice(LostDevice)) {
+ // We can't reset the device right now. Try again soon.
+ renderSoon();
+ return;
+ }
}
} while (err == D3DERR_DEVICELOST);
@@ -593,13 +604,43 @@ void WKCACFLayerRenderer::initD3DGeometry()
m_d3dDevice->SetTransform(D3DTS_PROJECTION, &projection);
}
-void WKCACFLayerRenderer::resetDevice()
+bool WKCACFLayerRenderer::resetDevice(ResetReason reason)
{
ASSERT(m_d3dDevice);
+ ASSERT(m_renderContext);
+
+ HRESULT hr = m_d3dDevice->TestCooperativeLevel();
+
+ if (hr == D3DERR_DEVICELOST || hr == D3DERR_DRIVERINTERNALERROR) {
+ // The device cannot be reset at this time. Try again soon.
+ m_mustResetLostDeviceBeforeRendering = true;
+ return false;
+ }
+
+ m_mustResetLostDeviceBeforeRendering = false;
+
+ if (reason == LostDevice && hr == D3D_OK) {
+ // The device wasn't lost after all.
+ return true;
+ }
+
+ // We can reset the device.
+
+ // We have to purge the CARenderOGLContext whenever we reset the IDirect3DDevice9 in order to
+ // destroy any D3DPOOL_DEFAULT resources that Core Animation has allocated (e.g., textures used
+ // for mask layers). See <http://msdn.microsoft.com/en-us/library/bb174425(v=VS.85).aspx>.
+ CARenderOGLPurge(m_renderer);
D3DPRESENT_PARAMETERS parameters = initialPresentationParameters();
- m_d3dDevice->Reset(&parameters);
+ hr = m_d3dDevice->Reset(&parameters);
+
+ // TestCooperativeLevel told us the device may be reset now, so we should
+ // not be told here that the device is lost.
+ ASSERT(hr != D3DERR_DEVICELOST);
+
initD3DGeometry();
+
+ return true;
}
}
diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.h b/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
index b708464..259c52f 100644
--- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
+++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
@@ -84,7 +84,12 @@ private:
CGRect bounds() const;
void initD3DGeometry();
- void resetDevice();
+
+ // Call this when the device window has changed size or when IDirect3DDevice9::Present returns
+ // D3DERR_DEVICELOST. Returns true if the device was recovered, false if rendering must be
+ // aborted and reattempted soon.
+ enum ResetReason { ChangedWindowSize, LostDevice };
+ bool resetDevice(ResetReason);
void render(const Vector<CGRect>& dirtyRects = Vector<CGRect>());
void paint();
@@ -104,6 +109,7 @@ private:
IntPoint m_scrollPosition;
IntSize m_scrollSize;
bool m_backingStoreDirty;
+ bool m_mustResetLostDeviceBeforeRendering;
#ifndef NDEBUG
bool m_printTree;
#endif
diff --git a/WebCore/platform/graphics/wx/FontPlatformData.h b/WebCore/platform/graphics/wx/FontPlatformData.h
index 94585e6..9d506d6 100644
--- a/WebCore/platform/graphics/wx/FontPlatformData.h
+++ b/WebCore/platform/graphics/wx/FontPlatformData.h
@@ -156,9 +156,8 @@ public:
#if OS(DARWIN)
ATSUFontID m_atsuFontID;
CGFontRef cgFont() const;
- NSFont* nsFont() const;
+ NSFont* nsFont() const { return m_nsFont; }
void cacheNSFont();
-
#endif
float m_size;
diff --git a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
index 601d6b4..6c5b300 100644
--- a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
+++ b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
@@ -99,8 +99,12 @@ FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicStri
)
);
#endif
-#if OS(DARWIN)
+#if OS(DARWIN) && !defined(wxOSX_USE_CORE_TEXT)
+#if wxCHECK_VERSION(2,9,0)
+ m_atsuFontID = m_font->font()->OSXGetATSUFontID();
+#else
m_atsuFontID = m_font->font()->MacGetATSUFontID();
+#endif
cacheNSFont();
#endif
m_size = desc.computedPixelSize();
diff --git a/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm b/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm
index b719656..4290f04 100644
--- a/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm
+++ b/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Kevin Ollivier All rights reserved.
+ * Copyright (C) 2010 Kevin Ollivier, Stefan Csomor All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,20 +31,117 @@
#include <wx/defs.h>
#include <wx/font.h>
+#include <wx/fontutil.h>
-namespace WebCore {
+#if !wxCHECK_VERSION(2,9,0)
+#include <wx/mac/private.h>
+#else
+#include <wx/osx/private.h>
+#endif
+
+#if !wxCHECK_VERSION(2,9,0) || !wxOSX_USE_COCOA
-NSFont* FontPlatformData::nsFont() const
+static inline double DegToRad(double deg)
{
-#if wxCHECK_VERSION(2,9,1) && wxOSX_USE_COCOA
- if (m_font && m_font->font())
- return (NSFont*)m_font->font()->OSXGetNSFont();
-#endif
+ return (deg * M_PI) / 180.0;
}
-void FontPlatformData::cacheNSFont()
+static const NSAffineTransformStruct kSlantNSTransformStruct = { 1, 0, tan(DegToRad(11)), 1, 0, 0 };
+
+NSFont* OSXCreateNSFont(const wxNativeFontInfo* info)
{
+ NSFont* nsFont;
+ int weight = 5;
+ NSFontTraitMask traits = 0;
+ if (info->GetWeight() == wxFONTWEIGHT_BOLD)
+ {
+ traits |= NSBoldFontMask;
+ weight = 9;
+ }
+ else if (info->GetWeight() == wxFONTWEIGHT_LIGHT)
+ weight = 3;
+
+ if (info->GetStyle() == wxFONTSTYLE_ITALIC || info->GetStyle() == wxFONTSTYLE_SLANT)
+ traits |= NSItalicFontMask;
+
+ nsFont = [[NSFontManager sharedFontManager] fontWithFamily:(NSString*)(CFStringRef)wxMacCFStringHolder(info->GetFaceName())
+ traits:traits weight:weight size:info->GetPointSize()];
+
+ if ( nsFont == nil )
+ {
+ NSFontTraitMask remainingTraits = traits;
+ nsFont = [[NSFontManager sharedFontManager] fontWithFamily:(NSString*)(CFStringRef)wxMacCFStringHolder(info->GetFaceName())
+ traits:0 weight:5 size:info->GetPointSize()];
+ if ( nsFont == nil )
+ {
+ if ( info->GetWeight() == wxFONTWEIGHT_BOLD )
+ {
+ nsFont = [NSFont boldSystemFontOfSize:info->GetPointSize()];
+ remainingTraits &= ~NSBoldFontMask;
+ }
+ else
+ nsFont = [NSFont systemFontOfSize:info->GetPointSize()];
+ }
+
+ // fallback - if in doubt, let go of the bold attribute
+ if ( nsFont && (remainingTraits & NSItalicFontMask) )
+ {
+ NSFont* nsFontWithTraits = nil;
+ if ( remainingTraits & NSBoldFontMask)
+ {
+ nsFontWithTraits = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
+ if ( nsFontWithTraits == nil )
+ {
+ nsFontWithTraits = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSItalicFontMask];
+ if ( nsFontWithTraits != nil )
+ remainingTraits &= ~NSItalicFontMask;
+ }
+ else
+ {
+ remainingTraits &= ~NSBoldFontMask;
+ }
+ }
+ if ( remainingTraits & NSItalicFontMask)
+ {
+ if ( nsFontWithTraits == nil )
+ nsFontWithTraits = nsFont;
+
+ NSAffineTransform* transform = [NSAffineTransform transform];
+ [transform setTransformStruct:kSlantNSTransformStruct];
+ [transform scaleBy:info->GetPointSize()];
+ NSFontDescriptor* italicDesc = [[nsFontWithTraits fontDescriptor] fontDescriptorWithMatrix:transform];
+ if ( italicDesc != nil )
+ {
+ NSFont* f = [NSFont fontWithDescriptor:italicDesc size:(CGFloat)(info->GetPointSize())];
+ if ( f != nil )
+ nsFontWithTraits = f;
+ }
+ }
+ if ( nsFontWithTraits != nil )
+ nsFont = nsFontWithTraits;
+ }
+ }
+
+ wxASSERT_MSG(nsFont != nil,wxT("Couldn't create nsFont")) ;
+ wxMacCocoaRetain(nsFont);
+ return nsFont;
+}
+#endif
+
+namespace WebCore {
+
+void FontPlatformData::cacheNSFont()
+{
+ if (m_nsFont)
+ return;
+
+#if wxCHECK_VERSION(2,9,1) && wxOSX_USE_COCOA
+ if (m_font && m_font->font())
+ m_nsFont = (NSFont*)m_font->font()->OSXGetNSFont();
+#else
+ m_nsFont = OSXCreateNSFont(m_font->font()->GetNativeFontInfo());
+#endif
}
}