summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2010-11-10 15:31:59 -0800
committerTeng-Hui Zhu <ztenghui@google.com>2010-11-17 13:35:59 -0800
commit28040489d744e0c5d475a88663056c9040ed5320 (patch)
treec463676791e4a63e452a95f0a12b2a8519730693 /WebCore/platform
parenteff9be92c41913c92fb1d3b7983c071f3e718678 (diff)
downloadexternal_webkit-28040489d744e0c5d475a88663056c9040ed5320.zip
external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.gz
external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.bz2
Merge WebKit at r71558: Initial merge by git.
Change-Id: Ib345578fa29df7e4bc72b4f00e4a6fddcb754c4c
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/AsyncFileSystem.cpp2
-rw-r--r--WebCore/platform/AsyncFileSystem.h7
-rw-r--r--WebCore/platform/ContextMenu.cpp11
-rw-r--r--WebCore/platform/ContextMenu.h2
-rw-r--r--WebCore/platform/FileSystem.h1
-rw-r--r--WebCore/platform/HostWindow.h7
-rw-r--r--WebCore/platform/PurgePriority.h39
-rw-r--r--WebCore/platform/PurgeableBuffer.h6
-rw-r--r--WebCore/platform/ScrollView.cpp7
-rw-r--r--WebCore/platform/ScrollView.h1
-rw-r--r--WebCore/platform/UUID.cpp5
-rw-r--r--WebCore/platform/android/LanguageAndroid.cpp42
-rw-r--r--WebCore/platform/android/PlatformBridge.h5
-rw-r--r--WebCore/platform/android/TemporaryLinkStubs.cpp3
-rw-r--r--WebCore/platform/animation/Animation.h6
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h1
-rw-r--r--WebCore/platform/chromium/FileSystemChromium.cpp5
-rw-r--r--WebCore/platform/chromium/PopupMenuChromium.cpp22
-rw-r--r--WebCore/platform/graphics/Extensions3D.h75
-rw-r--r--WebCore/platform/graphics/FloatPoint3D.cpp5
-rw-r--r--WebCore/platform/graphics/FloatPoint3D.h2
-rw-r--r--WebCore/platform/graphics/GraphicsContext.cpp53
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h5
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.cpp203
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h109
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp5
-rw-r--r--WebCore/platform/graphics/MediaPlayer.h2
-rw-r--r--WebCore/platform/graphics/MediaPlayerPrivate.h4
-rw-r--r--WebCore/platform/graphics/cairo/CairoUtilities.cpp8
-rw-r--r--WebCore/platform/graphics/cairo/FontCacheFreeType.cpp12
-rw-r--r--WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp24
-rw-r--r--WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h16
-rw-r--r--WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp4
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp20
-rw-r--r--WebCore/platform/graphics/cairo/ImageCairo.cpp2
-rw-r--r--WebCore/platform/graphics/cairo/RefPtrCairo.cpp (renamed from WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp)50
-rw-r--r--WebCore/platform/graphics/cairo/RefPtrCairo.h (renamed from WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h)28
-rw-r--r--WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp18
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp71
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextCG.cpp11
-rw-r--r--WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp10
-rw-r--r--WebCore/platform/graphics/chromium/Extensions3DChromium.h70
-rw-r--r--WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp4
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.cpp1
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.cpp6
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.h3
-rw-r--r--WebCore/platform/graphics/chromium/PluginLayerChromium.cpp133
-rw-r--r--WebCore/platform/graphics/chromium/PluginLayerChromium.h74
-rw-r--r--WebCore/platform/graphics/chromium/VideoLayerChromium.cpp5
-rw-r--r--WebCore/platform/graphics/filters/FELighting.cpp279
-rw-r--r--WebCore/platform/graphics/filters/FELighting.h38
-rw-r--r--WebCore/platform/graphics/filters/LightSource.cpp7
-rw-r--r--WebCore/platform/graphics/filters/LightSource.h1
-rw-r--r--WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp16
-rw-r--r--WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h4
-rw-r--r--WebCore/platform/graphics/gpu/Texture.cpp5
-rw-r--r--WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp20
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.mm1
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContextMac.mm1
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h2
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm9
-rw-r--r--WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp82
-rw-r--r--WebCore/platform/graphics/opengl/Extensions3DOpenGL.h56
-rw-r--r--WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp23
-rw-r--r--WebCore/platform/graphics/opengl/TextureMapperGL.cpp324
-rw-r--r--WebCore/platform/graphics/opengl/TextureMapperGL.h18
-rw-r--r--WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp27
-rw-r--r--WebCore/platform/graphics/qt/Extensions3DQt.cpp56
-rw-r--r--WebCore/platform/graphics/qt/Extensions3DQt.h49
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp10
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp66
-rw-r--r--WebCore/platform/graphics/qt/GraphicsLayerQt.cpp116
-rw-r--r--WebCore/platform/graphics/qt/PathQt.cpp12
-rw-r--r--WebCore/platform/graphics/qt/TextureMapperQt.cpp89
-rw-r--r--WebCore/platform/graphics/qt/TextureMapperQt.h76
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp8
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp19
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp3
-rw-r--r--WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp1161
-rw-r--r--WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h19
-rw-r--r--WebCore/platform/graphics/texmap/TextureMapper.h35
-rw-r--r--WebCore/platform/graphics/texmap/TextureMapperNode.cpp877
-rw-r--r--WebCore/platform/graphics/texmap/TextureMapperNode.h252
-rw-r--r--WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h13
-rw-r--r--WebCore/platform/graphics/win/FontCacheWin.cpp2
-rw-r--r--WebCore/platform/graphics/win/IconWin.cpp2
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp10
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h2
-rw-r--r--WebCore/platform/graphics/win/QTMovie.cpp8
-rw-r--r--WebCore/platform/graphics/win/QTMovie.h2
-rw-r--r--WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp49
-rw-r--r--WebCore/platform/graphics/wince/ImageWinCE.cpp2
-rw-r--r--WebCore/platform/graphics/wince/SharedBitmap.cpp615
-rw-r--r--WebCore/platform/graphics/wince/SharedBitmap.h145
-rw-r--r--WebCore/platform/graphics/wx/GraphicsContextWx.cpp5
-rw-r--r--WebCore/platform/gtk/CursorGtk.cpp10
-rw-r--r--WebCore/platform/gtk/DragImageGtk.cpp6
-rw-r--r--WebCore/platform/gtk/PasteboardHelper.cpp28
-rw-r--r--WebCore/platform/gtk/PopupMenuGtk.cpp10
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.cpp5
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.h6
-rw-r--r--WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp30
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp39
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp32
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h2
-rw-r--r--WebCore/platform/image-decoders/png/PNGImageDecoder.cpp27
-rw-r--r--WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp7
-rw-r--r--WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp7
-rw-r--r--WebCore/platform/mac/ContextMenuItemMac.mm5
-rw-r--r--WebCore/platform/mac/ContextMenuMac.mm13
-rw-r--r--WebCore/platform/mac/Language.mm17
-rw-r--r--WebCore/platform/mac/PurgeableBufferMac.cpp15
-rw-r--r--WebCore/platform/network/curl/CookieJarCurl.cpp2
-rw-r--r--WebCore/platform/network/soup/SocketStreamHandle.h2
-rw-r--r--WebCore/platform/network/soup/SocketStreamHandleSoup.cpp55
-rw-r--r--WebCore/platform/qt/ContextMenuItemQt.cpp6
-rw-r--r--WebCore/platform/qt/ContextMenuQt.cpp5
-rw-r--r--WebCore/platform/qt/PlatformScreenQt.cpp18
-rw-r--r--WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp4
-rw-r--r--WebCore/platform/text/gtk/TextCodecGtk.cpp25
-rw-r--r--WebCore/platform/win/ClipboardUtilitiesWin.cpp4
-rw-r--r--WebCore/platform/win/ClipboardWin.cpp100
-rw-r--r--WebCore/platform/win/ContextMenuItemWin.cpp6
-rw-r--r--WebCore/platform/win/ContextMenuWin.cpp6
-rw-r--r--WebCore/platform/win/DragDataWin.cpp2
-rw-r--r--WebCore/platform/win/FileSystemWin.cpp2
-rw-r--r--WebCore/platform/win/WCDataObject.cpp2
127 files changed, 4197 insertions, 2122 deletions
diff --git a/WebCore/platform/AsyncFileSystem.cpp b/WebCore/platform/AsyncFileSystem.cpp
index 57305ff..b85a487 100644
--- a/WebCore/platform/AsyncFileSystem.cpp
+++ b/WebCore/platform/AsyncFileSystem.cpp
@@ -53,7 +53,7 @@ PassOwnPtr<AsyncFileSystem> AsyncFileSystem::create(const String&)
}
// Default implementation.
-void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, Type type, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
+void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, Type type, bool, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
{
String typeString = (type == Persistent) ? "Persistent" : "Temporary";
diff --git a/WebCore/platform/AsyncFileSystem.h b/WebCore/platform/AsyncFileSystem.h
index 3104ebc..d96c1ad 100644
--- a/WebCore/platform/AsyncFileSystem.h
+++ b/WebCore/platform/AsyncFileSystem.h
@@ -66,8 +66,8 @@ public:
// Creates and returns a new platform-specific AsyncFileSystem instance if the platform has its own implementation.
static PassOwnPtr<AsyncFileSystem> create(const String& rootPath);
- // Opens a new file system.
- static void openFileSystem(const String& basePath, const String& storageIdentifier, Type, PassOwnPtr<AsyncFileSystemCallbacks>);
+ // Opens a new file system. The create parameter specifies whether or not to create the path if it does not already exists.
+ static void openFileSystem(const String& basePath, const String& storageIdentifier, Type, bool create, PassOwnPtr<AsyncFileSystemCallbacks>);
// Moves a file or directory from srcPath to destPath.
// AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
@@ -128,6 +128,9 @@ public:
// Converts a given absolute virtual path to a platform path that starts with the platform root path of this file system.
virtual String virtualToPlatformPath(const String& path) const;
+ // Getter for this file system's root path.
+ String root() const { return m_platformRootPath; }
+
protected:
AsyncFileSystem(const String& platformRootPath)
: m_platformRootPath(platformRootPath)
diff --git a/WebCore/platform/ContextMenu.cpp b/WebCore/platform/ContextMenu.cpp
index 369f9ce..93cdfdf 100644
--- a/WebCore/platform/ContextMenu.cpp
+++ b/WebCore/platform/ContextMenu.cpp
@@ -30,6 +30,7 @@
#if ENABLE(CONTEXT_MENUS)
+#include "BackForwardController.h"
#include "ContextMenuController.h"
#include "ContextMenuClient.h"
#include "CSSComputedStyleDeclaration.h"
@@ -405,10 +406,10 @@ void ContextMenu::populate()
#if ENABLE(INSPECTOR)
if (!(frame->page() && frame->page()->inspectorController()->hasInspectorFrontendClient())) {
#endif
- if (frame->page() && frame->page()->canGoBackOrForward(-1))
+ if (frame->page() && frame->page()->backForward()->canGoBackOrForward(-1))
appendItem(BackItem);
- if (frame->page() && frame->page()->canGoBackOrForward(1))
+ if (frame->page() && frame->page()->backForward()->canGoBackOrForward(1))
appendItem(ForwardItem);
// use isLoadingInAPISense rather than isLoading because Stop/Reload are
@@ -428,7 +429,7 @@ void ContextMenu::populate()
} else { // Make an editing context menu
SelectionController* selection = frame->selection();
bool inPasswordField = selection->isInPasswordField();
- bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledInFocusedNode();
+ bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node);
if (!inPasswordField && spellCheckingEnabled) {
// Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range
@@ -783,10 +784,10 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
#endif
#if PLATFORM(GTK)
case ContextMenuItemTagGoBack:
- shouldEnable = frame->page() && frame->page()->canGoBackOrForward(-1);
+ shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(-1);
break;
case ContextMenuItemTagGoForward:
- shouldEnable = frame->page() && frame->page()->canGoBackOrForward(1);
+ shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(1);
break;
case ContextMenuItemTagStop:
shouldEnable = frame->loader()->documentLoader()->isLoadingInAPISense();
diff --git a/WebCore/platform/ContextMenu.h b/WebCore/platform/ContextMenu.h
index ca21f29..2a2a017 100644
--- a/WebCore/platform/ContextMenu.h
+++ b/WebCore/platform/ContextMenu.h
@@ -91,6 +91,8 @@ namespace WebCore {
#endif
};
+Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription);
+
}
#endif // ContextMenu_h
diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h
index e3916cf..32ab417 100644
--- a/WebCore/platform/FileSystem.h
+++ b/WebCore/platform/FileSystem.h
@@ -144,6 +144,7 @@ static const char PlatformFilePathSeparator = '\\';
static const char PlatformFilePathSeparator = '/';
#endif
+void revealFolderInOS(const String&);
bool fileExists(const String&);
bool deleteFile(const String&);
bool deleteEmptyDirectory(const String&);
diff --git a/WebCore/platform/HostWindow.h b/WebCore/platform/HostWindow.h
index b0ee653..7882d48 100644
--- a/WebCore/platform/HostWindow.h
+++ b/WebCore/platform/HostWindow.h
@@ -48,7 +48,12 @@ public:
// Requests the host invalidate the contents, not the window. This is the slow path for scrolling.
virtual void invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) = 0;
-
+
+#if ENABLE(TILED_BACKING_STORE)
+ // Requests the host to do the actual scrolling. This is only used in combination with a tiled backing store.
+ virtual void delegatedScrollRequested(const IntSize& scrollDelta) = 0;
+#endif
+
// Methods for doing coordinate conversions to and from screen coordinates.
virtual IntPoint screenToWindow(const IntPoint&) const = 0;
virtual IntRect windowToScreen(const IntRect&) const = 0;
diff --git a/WebCore/platform/PurgePriority.h b/WebCore/platform/PurgePriority.h
new file mode 100644
index 0000000..6a2894e
--- /dev/null
+++ b/WebCore/platform/PurgePriority.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 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 INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PurgePriority_h
+#define PurgePriority_h
+
+namespace WebCore {
+
+enum PurgePriority {
+ PurgeLast,
+ PurgeMiddle,
+ PurgeFirst,
+ PurgeDefault = PurgeMiddle
+};
+
+}
+
+#endif // PurgePriority_h
diff --git a/WebCore/platform/PurgeableBuffer.h b/WebCore/platform/PurgeableBuffer.h
index 32341c2..9bda2d5 100644
--- a/WebCore/platform/PurgeableBuffer.h
+++ b/WebCore/platform/PurgeableBuffer.h
@@ -26,6 +26,7 @@
#ifndef PurgeableBuffer_h
#define PurgeableBuffer_h
+#include "PurgePriority.h"
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
@@ -35,7 +36,6 @@ namespace WebCore {
class PurgeableBuffer : public Noncopyable {
public:
static PassOwnPtr<PurgeableBuffer> create(const char* data, size_t);
- static PassOwnPtr<PurgeableBuffer> create(const Vector<char>& vector) { return create(vector.data(), vector.size()); }
~PurgeableBuffer();
@@ -43,9 +43,8 @@ namespace WebCore {
const char* data() const;
size_t size() const { return m_size; }
- enum PurgePriority { PurgeLast, PurgeMiddle, PurgeFirst, PurgeDefault = PurgeMiddle };
PurgePriority purgePriority() const { return m_purgePriority; }
- void setPurgePriority(PurgePriority);
+ void setPurgePriority(PurgePriority priority) { m_purgePriority = priority; }
bool isPurgeable() const { return m_state != NonVolatile; }
bool wasPurged() const;
@@ -67,7 +66,6 @@ namespace WebCore {
inline PassOwnPtr<PurgeableBuffer> PurgeableBuffer::create(const char*, size_t) { return PassOwnPtr<PurgeableBuffer>(); }
inline PurgeableBuffer::~PurgeableBuffer() { }
inline const char* PurgeableBuffer::data() const { return 0; }
- inline void PurgeableBuffer::setPurgePriority(PurgePriority) { }
inline bool PurgeableBuffer::wasPurged() const { return false; }
inline bool PurgeableBuffer::makePurgeable(bool) { return false; }
#endif
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 5f745b8..40d598e 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -362,6 +362,13 @@ void ScrollView::setScrollPosition(const IntPoint& scrollPoint)
IntPoint newScrollPosition = scrollPoint.shrunkTo(maximumScrollPosition());
newScrollPosition.clampNegativeToZero();
+#if ENABLE(TILED_BACKING_STORE)
+ if (delegatesScrolling()) {
+ hostWindow()->delegatedScrollRequested(IntSize(scrollPoint.x(), scrollPoint.y()));
+ return;
+ }
+#endif
+
if (newScrollPosition == scrollPosition())
return;
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 739e1ac..7fb5d8e 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -104,6 +104,7 @@ public:
virtual void setCanHaveScrollbars(bool);
bool canHaveScrollbars() const { return horizontalScrollbarMode() != ScrollbarAlwaysOff || verticalScrollbarMode() != ScrollbarAlwaysOff; }
+ virtual bool delegatesScrolling() { return false; }
virtual bool avoidScrollbarCreation() { return false; }
// By default you only receive paint events for the area that is visible. In the case of using a
diff --git a/WebCore/platform/UUID.cpp b/WebCore/platform/UUID.cpp
index 5208bee..eb721e0 100644
--- a/WebCore/platform/UUID.cpp
+++ b/WebCore/platform/UUID.cpp
@@ -39,9 +39,6 @@
#if OS(WINDOWS)
#include <objbase.h>
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
-#endif
#elif OS(DARWIN)
#include <CoreFoundation/CoreFoundation.h>
#elif OS(LINUX) && !PLATFORM(CHROMIUM)
@@ -69,7 +66,7 @@ String createCanonicalUUIDString()
if (FAILED(hr))
return String();
wchar_t uuidStr[40];
- int num = StringFromGUID2(uuid, reinterpret_cast<LPOLESTR>(uuidStr), ARRAYSIZE(uuidStr));
+ int num = StringFromGUID2(uuid, reinterpret_cast<LPOLESTR>(uuidStr), WTF_ARRAY_LENGTH(uuidStr));
ASSERT(num == 39);
String canonicalUuidStr = String(uuidStr + 1, num - 3).lower(); // remove opening and closing bracket and make it lower.
ASSERT(canonicalUuidStr[uuidVersionIdentifierIndex] == uuidVersionRequired);
diff --git a/WebCore/platform/android/LanguageAndroid.cpp b/WebCore/platform/android/LanguageAndroid.cpp
new file mode 100644
index 0000000..52e614d
--- /dev/null
+++ b/WebCore/platform/android/LanguageAndroid.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Language.h"
+
+#include "PlatformBridge.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+// This function is used by Javascript to find out what the default language
+// the user has selected. It is used by the JS object Navigator.language
+// I guess this information should be mapped with the Accept-Language: HTTP header.
+String platformDefaultLanguage()
+{
+ return PlatformBridge::computeDefaultLanguage();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/android/PlatformBridge.h b/WebCore/platform/android/PlatformBridge.h
index 334629b..3098d6c 100644
--- a/WebCore/platform/android/PlatformBridge.h
+++ b/WebCore/platform/android/PlatformBridge.h
@@ -108,6 +108,7 @@ public:
static bool cookiesEnabled(const Document*);
// Plugin
static NPObject* pluginScriptableObject(Widget*);
+<<<<<<< HEAD
// Popups
static bool popupsAllowed(NPP);
@@ -139,6 +140,10 @@ public:
// Updates the layers on the UI
static void updateLayers(FrameView* view);
+=======
+ // Language
+ static String computeDefaultLanguage();
+>>>>>>> webkit.org at r71558
};
}
diff --git a/WebCore/platform/android/TemporaryLinkStubs.cpp b/WebCore/platform/android/TemporaryLinkStubs.cpp
index cf8aacf..b1c0276 100644
--- a/WebCore/platform/android/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/android/TemporaryLinkStubs.cpp
@@ -92,6 +92,7 @@ using namespace WebCore;
/* Completely empty stubs (mostly to allow DRT to run): */
/********************************************************/
+<<<<<<< HEAD
// This function is used by Javascript to find out what the default language
// the user has selected. It is used by the JS object Navigator.language
// I guess this information should be mapped with the Accept-Language: HTTP header.
@@ -101,6 +102,8 @@ String WebCore::platformDefaultLanguage()
return "en";
}
+=======
+>>>>>>> webkit.org at r71558
namespace WebCore {
// This function tells the bridge that a resource was loaded from the cache and thus
diff --git a/WebCore/platform/animation/Animation.h b/WebCore/platform/animation/Animation.h
index 1541b4d..d16f74c 100644
--- a/WebCore/platform/animation/Animation.h
+++ b/WebCore/platform/animation/Animation.h
@@ -93,7 +93,7 @@ public:
enum { IterationCountInfinite = -1 };
int iterationCount() const { return m_iterationCount; }
const String& name() const { return m_name; }
- unsigned playState() const { return m_playState; }
+ EAnimPlayState playState() const { return static_cast<EAnimPlayState>(m_playState); }
int property() const { return m_property; }
const PassRefPtr<TimingFunction> timingFunction() const { return m_timingFunction; }
@@ -103,7 +103,7 @@ public:
void setFillMode(unsigned f) { m_fillMode = f; m_fillModeSet = true; }
void setIterationCount(int c) { m_iterationCount = c; m_iterationCountSet = true; }
void setName(const String& n) { m_name = n; m_nameSet = true; }
- void setPlayState(unsigned d) { m_playState = d; m_playStateSet = true; }
+ void setPlayState(EAnimPlayState d) { m_playState = d; m_playStateSet = true; }
void setProperty(int t) { m_property = t; m_propertySet = true; }
void setTimingFunction(PassRefPtr<TimingFunction> f) { m_timingFunction = f; m_timingFunctionSet = true; }
@@ -155,7 +155,7 @@ public:
static unsigned initialAnimationFillMode() { return AnimationFillModeNone; }
static int initialAnimationIterationCount() { return 1; }
static String initialAnimationName() { return String("none"); }
- static unsigned initialAnimationPlayState() { return AnimPlayStatePlaying; }
+ static EAnimPlayState initialAnimationPlayState() { return AnimPlayStatePlaying; }
static int initialAnimationProperty() { return cAnimateAll; }
static PassRefPtr<TimingFunction> initialAnimationTimingFunction() { return CubicBezierTimingFunction::create(); }
};
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index 74bad04..55a4ce0 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -121,6 +121,7 @@ namespace WebCore {
static void prefetchDNS(const String& hostname);
// File ---------------------------------------------------------------
+ static void revealFolderInOS(const String&);
static bool fileExists(const String&);
static bool deleteFile(const String&);
static bool deleteEmptyDirectory(const String&);
diff --git a/WebCore/platform/chromium/FileSystemChromium.cpp b/WebCore/platform/chromium/FileSystemChromium.cpp
index 975caf6..d8a1e3f 100644
--- a/WebCore/platform/chromium/FileSystemChromium.cpp
+++ b/WebCore/platform/chromium/FileSystemChromium.cpp
@@ -57,6 +57,11 @@ bool getFileModificationTime(const String& path, time_t& result)
return ChromiumBridge::getFileModificationTime(path, result);
}
+void revealFolderInOS(const String& path)
+{
+ ChromiumBridge::revealFolderInOS(path);
+}
+
String directoryName(const String& path)
{
return ChromiumBridge::directoryName(path);
diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp
index 3c807ba..3ff4ff0 100644
--- a/WebCore/platform/chromium/PopupMenuChromium.cpp
+++ b/WebCore/platform/chromium/PopupMenuChromium.cpp
@@ -927,15 +927,16 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd
// Prepare text to be drawn.
String itemText = m_popupClient->itemText(rowIndex);
String itemLabel = m_popupClient->itemLabel(rowIndex);
+ String itemIcon = m_popupClient->itemIcon(rowIndex);
if (m_settings.restrictWidthOfListBox) { // Truncate strings to fit in.
// FIXME: We should leftTruncate for the rtl case.
// StringTruncator::leftTruncate would have to be implemented.
String str = StringTruncator::rightTruncate(itemText, maxWidth, itemFont);
if (str != itemText) {
itemText = str;
- // Don't display the label, we already don't have enough room for the
- // item text.
+ // Don't display the label or icon, we already don't have enough room for the item text.
itemLabel = "";
+ itemIcon = "";
} else if (!itemLabel.isEmpty()) {
int availableWidth = maxWidth - kTextToLabelPadding -
StringTruncator::width(itemText, itemFont);
@@ -966,7 +967,6 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd
int remainingWidth = rowRect.width() - rightPadding;
// Draw the icon if applicable.
- String itemIcon = m_popupClient->itemIcon(rowIndex);
RefPtr<Image> image(Image::loadPlatformResource(itemIcon.utf8().data()));
if (image && !image->isNull()) {
IntRect imageRect = image->rect();
@@ -1089,7 +1089,13 @@ int PopupListBox::getRowHeight(int index)
if (index < 0)
return 0;
- return getRowFont(index).height();
+ String icon = m_popupClient->itemIcon(index);
+ RefPtr<Image> image(Image::loadPlatformResource(icon.utf8().data()));
+
+ int fontHeight = getRowFont(index).height();
+ int iconHeight = (image && !image->isNull()) ? image->rect().height() : 0;
+
+ return max(fontHeight, iconHeight);
}
IntRect PopupListBox::getRowBounds(int index)
@@ -1257,6 +1263,8 @@ void PopupListBox::layout()
// Ensure the popup is wide enough to fit this item.
String text = m_popupClient->itemText(i);
String label = m_popupClient->itemLabel(i);
+ String icon = m_popupClient->itemIcon(i);
+ RefPtr<Image> iconImage(Image::loadPlatformResource(icon.utf8().data()));
int width = 0;
if (!text.isEmpty())
width = itemFont.width(TextRun(text));
@@ -1265,6 +1273,12 @@ void PopupListBox::layout()
width += kTextToLabelPadding;
width += itemFont.width(TextRun(label));
}
+ if (iconImage && !iconImage->isNull()) {
+ if (width > 0)
+ width += kLabelToIconPadding;
+ width += iconImage->rect().width();
+ }
+
baseWidth = max(baseWidth, width);
// FIXME: http://b/1210481 We should get the padding of individual option elements.
paddingWidth = max(paddingWidth,
diff --git a/WebCore/platform/graphics/Extensions3D.h b/WebCore/platform/graphics/Extensions3D.h
new file mode 100644
index 0000000..0aed8e7
--- /dev/null
+++ b/WebCore/platform/graphics/Extensions3D.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Extensions3D_h
+#define Extensions3D_h
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// This is a base class containing only pure virtual functions.
+// Implementations must provide a subclass.
+//
+// The supported extensions are defined below and in subclasses,
+// possibly platform-specific ones.
+//
+// Calling any extension function not supported by the current context
+// must be a no-op; in particular, it may not have side effects. In
+// this situation, if the function has a return value, 0 is returned.
+class Extensions3D {
+public:
+ virtual ~Extensions3D() {}
+
+ // Supported extensions:
+ // GL_EXT_texture_format_BGRA8888
+ // GL_EXT_read_format_bgra
+ // GL_ARB_robustness
+ // GL_EXT_packed_depth_stencil / GL_OES_packed_depth_stencil
+
+ // Takes full name of extension; for example,
+ // "GL_EXT_texture_format_BGRA8888".
+ virtual bool supports(const String&) = 0;
+
+ enum {
+ // GL_EXT_texture_format_BGRA8888 enums
+ BGRA_EXT = 0x80E1,
+
+ // GL_ARB_robustness enums
+ GUILTY_CONTEXT_RESET_ARB = 0x8253,
+ INNOCENT_CONTEXT_RESET_ARB = 0x8254,
+ UNKNOWN_CONTEXT_RESET_ARB = 0x8255,
+
+ // GL_EXT/OES_packed_depth_stencil enums
+ DEPTH24_STENCIL8 = 0x88F0
+ };
+
+ // GL_ARB_robustness
+ virtual int getGraphicsResetStatusARB() = 0;
+};
+
+} // namespace WebCore
+
+#endif // Extensions3D_h
diff --git a/WebCore/platform/graphics/FloatPoint3D.cpp b/WebCore/platform/graphics/FloatPoint3D.cpp
index bb05e7f..ed1816b 100644
--- a/WebCore/platform/graphics/FloatPoint3D.cpp
+++ b/WebCore/platform/graphics/FloatPoint3D.cpp
@@ -38,10 +38,5 @@ void FloatPoint3D::normalize()
}
}
-float FloatPoint3D::length() const
-{
- return sqrtf(lengthSquared());
-}
-
} // namespace WebCore
diff --git a/WebCore/platform/graphics/FloatPoint3D.h b/WebCore/platform/graphics/FloatPoint3D.h
index 9ee548d..b6cbaa8 100644
--- a/WebCore/platform/graphics/FloatPoint3D.h
+++ b/WebCore/platform/graphics/FloatPoint3D.h
@@ -113,8 +113,8 @@ public:
return result;
}
- float length() const;
float lengthSquared() const { return this->dot(*this); }
+ float length() const { return sqrtf(lengthSquared()); }
private:
float m_x;
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index ec15d26..52312a4 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -404,25 +404,27 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const
th = image->height();
if (useLowQualityScale) {
- save();
+ InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
+ // FIXME: Should be InterpolationLow
setImageInterpolationQuality(InterpolationNone);
- }
- image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op);
- if (useLowQualityScale)
- restore();
+ image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op);
+ setImageInterpolationQuality(previousInterpolationQuality);
+ } else
+ image->draw(this, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), styleColorSpace, op);
}
void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& rect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator op, bool useLowQualityScale)
{
if (paintingDisabled() || !image)
return;
+
if (useLowQualityScale) {
- save();
+ InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
setImageInterpolationQuality(InterpolationLow);
- }
- image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op);
- if (useLowQualityScale)
- restore();
+ image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op);
+ setImageInterpolationQuality(previousInterpolationQuality);
+ } else
+ image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op);
}
void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, Image::TileRule hRule, Image::TileRule vRule, CompositeOperator op, bool useLowQualityScale)
@@ -430,17 +432,19 @@ void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, c
if (paintingDisabled() || !image)
return;
- if (useLowQualityScale) {
- save();
- setImageInterpolationQuality(InterpolationLow);
- }
- if (hRule == Image::StretchTile && vRule == Image::StretchTile)
+ if (hRule == Image::StretchTile && vRule == Image::StretchTile) {
// Just do a scale.
drawImage(image, styleColorSpace, dest, srcRect, op);
- else
+ return;
+ }
+
+ if (useLowQualityScale) {
+ InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
+ setImageInterpolationQuality(InterpolationLow);
+ image->drawTiled(this, dest, srcRect, hRule, vRule, styleColorSpace, op);
+ setImageInterpolationQuality(previousInterpolationQuality);
+ } else
image->drawTiled(this, dest, srcRect, hRule, vRule, styleColorSpace, op);
- if (useLowQualityScale)
- restore();
}
void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntPoint& p, CompositeOperator op)
@@ -484,14 +488,13 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS
th = image->height();
if (useLowQualityScale) {
- save();
+ InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
+ // FIXME: Should be InterpolationLow
setImageInterpolationQuality(InterpolationNone);
- }
-
- image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale);
-
- if (useLowQualityScale)
- restore();
+ image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale);
+ setImageInterpolationQuality(previousInterpolationQuality);
+ } else
+ image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale);
}
void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index b1fa48a..a91f3d3 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -40,7 +40,6 @@
#if PLATFORM(CG)
typedef struct CGContext PlatformGraphicsContext;
#elif PLATFORM(CAIRO)
-#include "PlatformRefPtrCairo.h"
namespace WebCore {
class ContextShadow;
}
@@ -260,7 +259,6 @@ namespace WebCore {
void clearRect(const FloatRect&);
- void strokeRect(const FloatRect&);
void strokeRect(const FloatRect&, float lineWidth);
void drawImage(Image*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver);
@@ -289,7 +287,6 @@ namespace WebCore {
void addRoundedRectClip(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight);
void addInnerRoundedRectClip(const IntRect&, int thickness);
void clipOut(const IntRect&);
- void clipOutEllipseInRect(const IntRect&);
void clipOutRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight);
void clipPath(WindRule);
void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
@@ -355,7 +352,6 @@ namespace WebCore {
void rotate(float angleInRadians);
void translate(const FloatSize& size) { translate(size.width(), size.height()); }
void translate(float x, float y);
- IntPoint origin();
void setURLForRect(const KURL&, const IntRect&);
@@ -434,7 +430,6 @@ namespace WebCore {
bool inTransparencyLayer() const;
PlatformPath* currentPath();
void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask);
- QPen pen();
static QPainter::CompositionMode toQtCompositionMode(CompositeOperator op);
#endif
diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp
index b8c66d5..2a65128 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -132,13 +132,13 @@ bool GraphicsContext3D::extractImageData(ImageData* imageData,
int dataBytes = width * height * 4;
data.resize(dataBytes);
if (!packPixels(imageData->data()->data()->data(),
- kSourceFormatRGBA8,
+ SourceFormatRGBA8,
width,
height,
0,
format,
type,
- premultiplyAlpha ? kAlphaDoPremultiply : kAlphaDoNothing,
+ premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing,
data.data()))
return false;
if (flipY) {
@@ -164,37 +164,37 @@ bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int heig
Vector<uint8_t>& data)
{
// Assumes format, type, etc. have already been validated.
- SourceDataFormat sourceDataFormat = kSourceFormatRGBA8;
+ SourceDataFormat sourceDataFormat = SourceFormatRGBA8;
switch (type) {
case UNSIGNED_BYTE:
switch (format) {
case RGBA:
- sourceDataFormat = kSourceFormatRGBA8;
+ sourceDataFormat = SourceFormatRGBA8;
break;
case RGB:
- sourceDataFormat = kSourceFormatRGB8;
+ sourceDataFormat = SourceFormatRGB8;
break;
case ALPHA:
- sourceDataFormat = kSourceFormatA8;
+ sourceDataFormat = SourceFormatA8;
break;
case LUMINANCE:
- sourceDataFormat = kSourceFormatR8;
+ sourceDataFormat = SourceFormatR8;
break;
case LUMINANCE_ALPHA:
- sourceDataFormat = kSourceFormatRA8;
+ sourceDataFormat = SourceFormatRA8;
break;
default:
ASSERT_NOT_REACHED();
}
break;
case UNSIGNED_SHORT_5_5_5_1:
- sourceDataFormat = kSourceFormatRGBA5551;
+ sourceDataFormat = SourceFormatRGBA5551;
break;
case UNSIGNED_SHORT_4_4_4_4:
- sourceDataFormat = kSourceFormatRGBA4444;
+ sourceDataFormat = SourceFormatRGBA4444;
break;
case UNSIGNED_SHORT_5_6_5:
- sourceDataFormat = kSourceFormatRGB565;
+ sourceDataFormat = SourceFormatRGB565;
break;
default:
ASSERT_NOT_REACHED();
@@ -213,7 +213,7 @@ bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int heig
sourceDataFormat,
width, height, unpackAlignment,
format, type,
- (premultiplyAlpha ? kAlphaDoPremultiply : kAlphaDoNothing),
+ (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing),
data.data()))
return false;
// The pixel data is now tightly packed.
@@ -303,6 +303,14 @@ void unpackRGB16BigToRGBA8(const uint16_t* source, uint8_t* destination)
destination[3] = 0xFF;
}
+void unpackBGR8ToRGBA8(const uint8_t* source, uint8_t* destination)
+{
+ destination[0] = source[2];
+ destination[1] = source[1];
+ destination[2] = source[0];
+ destination[3] = 0xFF;
+}
+
void unpackARGB8ToRGBA8(const uint8_t* source, uint8_t* destination)
{
destination[0] = source[1];
@@ -327,6 +335,14 @@ void unpackARGB16BigToRGBA8(const uint16_t* source, uint8_t* destination)
destination[3] = convertColor16BigTo8(source[0]);
}
+void unpackABGR8ToRGBA8(const uint8_t* source, uint8_t* destination)
+{
+ destination[0] = source[3];
+ destination[1] = source[2];
+ destination[2] = source[1];
+ destination[3] = source[0];
+}
+
void unpackBGRA8ToRGBA8(const uint8_t* source, uint8_t* destination)
{
destination[0] = source[2];
@@ -566,7 +582,7 @@ void packRGBA8ToRGB8Unmultiply(const uint8_t* source, uint8_t* destination)
destination[2] = sourceB;
}
-// This is only used when the source format is different than kSourceFormatRGBA8.
+// This is only used when the source format is different than SourceFormatRGBA8.
void packRGBA8ToRGBA8(const uint8_t* source, uint8_t* destination)
{
destination[0] = source[0];
@@ -772,7 +788,7 @@ static void doPacking(const void* sourceData,
unsigned int destinationElementsPerPixel)
{
switch (sourceDataFormat) {
- case GraphicsContext3D::kSourceFormatRGBA8: {
+ case GraphicsContext3D::SourceFormatRGBA8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
if (!sourceElementsPerRow) {
@@ -789,157 +805,169 @@ static void doPacking(const void* sourceData,
}
break;
}
- case GraphicsContext3D::kSourceFormatRGBA16Little: {
+ case GraphicsContext3D::SourceFormatRGBA16Little: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRGBA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRGBA16Big: {
+ case GraphicsContext3D::SourceFormatRGBA16Big: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRGBA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRGB8: {
+ case GraphicsContext3D::SourceFormatRGB8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint8_t, DestType, unpackRGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRGB16Little: {
+ case GraphicsContext3D::SourceFormatRGB16Little: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 6, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRGB16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRGB16Big: {
+ case GraphicsContext3D::SourceFormatRGB16Big: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 6, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRGB16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatARGB8: {
+ case GraphicsContext3D::SourceFormatBGR8: {
+ unsigned int sourceElementsPerPixel, sourceElementsPerRow;
+ computeIncrementParameters<uint8_t>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
+ doUnpackingAndPacking<uint8_t, DestType, unpackBGR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
+ break;
+ }
+ case GraphicsContext3D::SourceFormatARGB8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint8_t, DestType, unpackARGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatARGB16Little: {
+ case GraphicsContext3D::SourceFormatARGB16Little: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackARGB16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatARGB16Big: {
+ case GraphicsContext3D::SourceFormatARGB16Big: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackARGB16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatBGRA8: {
+ case GraphicsContext3D::SourceFormatABGR8: {
+ unsigned int sourceElementsPerPixel, sourceElementsPerRow;
+ computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
+ doUnpackingAndPacking<uint8_t, DestType, unpackABGR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
+ break;
+ }
+ case GraphicsContext3D::SourceFormatBGRA8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint8_t, DestType, unpackBGRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatBGRA16Little: {
+ case GraphicsContext3D::SourceFormatBGRA16Little: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackBGRA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatBGRA16Big: {
+ case GraphicsContext3D::SourceFormatBGRA16Big: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackBGRA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRGBA5551: {
+ case GraphicsContext3D::SourceFormatRGBA5551: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRGBA5551ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRGBA4444: {
+ case GraphicsContext3D::SourceFormatRGBA4444: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRGBA4444ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRGB565: {
+ case GraphicsContext3D::SourceFormatRGB565: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRGB565ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatR8: {
+ case GraphicsContext3D::SourceFormatR8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint8_t, DestType, unpackR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatR16Little: {
+ case GraphicsContext3D::SourceFormatR16Little: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackR16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatR16Big: {
+ case GraphicsContext3D::SourceFormatR16Big: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackR16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRA8: {
+ case GraphicsContext3D::SourceFormatRA8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint8_t, DestType, unpackRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRA16Little: {
+ case GraphicsContext3D::SourceFormatRA16Little: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatRA16Big: {
+ case GraphicsContext3D::SourceFormatRA16Big: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackRA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatAR8: {
+ case GraphicsContext3D::SourceFormatAR8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint8_t, DestType, unpackAR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatAR16Little: {
+ case GraphicsContext3D::SourceFormatAR16Little: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackAR16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatAR16Big: {
+ case GraphicsContext3D::SourceFormatAR16Big: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackAR16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatA8: {
+ case GraphicsContext3D::SourceFormatA8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint8_t, DestType, unpackA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatA16Little: {
+ case GraphicsContext3D::SourceFormatA16Little: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
- case GraphicsContext3D::kSourceFormatA16Big: {
+ case GraphicsContext3D::SourceFormatA16Big: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
doUnpackingAndPacking<uint16_t, DestType, unpackA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
@@ -963,7 +991,7 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
switch (destinationType) {
case UNSIGNED_BYTE: {
uint8_t* destination = static_cast<uint8_t*>(destinationData);
- if (sourceDataFormat == kSourceFormatRGBA8 && destinationFormat == RGBA && sourceUnpackAlignment <= 4 && alphaOp == kAlphaDoNothing) {
+ if (sourceDataFormat == SourceFormatRGBA8 && destinationFormat == RGBA && sourceUnpackAlignment <= 4 && alphaOp == AlphaDoNothing) {
// No conversion necessary.
memcpy(destinationData, sourceData, width * height * 4);
break;
@@ -971,27 +999,27 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
switch (destinationFormat) {
case RGB:
switch (alphaOp) {
- case kAlphaDoNothing:
+ case AlphaDoNothing:
doPacking<uint8_t, packRGBA8ToRGB8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
break;
- case kAlphaDoPremultiply:
+ case AlphaDoPremultiply:
doPacking<uint8_t, packRGBA8ToRGB8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
break;
- case kAlphaDoUnmultiply:
+ case AlphaDoUnmultiply:
doPacking<uint8_t, packRGBA8ToRGB8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
break;
}
break;
case RGBA:
switch (alphaOp) {
- case kAlphaDoNothing:
- ASSERT(sourceDataFormat != kSourceFormatRGBA8 || sourceUnpackAlignment > 4); // Handled above with fast case.
+ case AlphaDoNothing:
+ ASSERT(sourceDataFormat != SourceFormatRGBA8 || sourceUnpackAlignment > 4); // Handled above with fast case.
doPacking<uint8_t, packRGBA8ToRGBA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
break;
- case kAlphaDoPremultiply:
+ case AlphaDoPremultiply:
doPacking<uint8_t, packRGBA8ToRGBA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
break;
- case kAlphaDoUnmultiply:
+ case AlphaDoUnmultiply:
doPacking<uint8_t, packRGBA8ToRGBA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
break;
default:
@@ -1009,13 +1037,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
// specification, Table 3.15), the red channel is chosen
// from the RGBA data.
switch (alphaOp) {
- case kAlphaDoNothing:
+ case AlphaDoNothing:
doPacking<uint8_t, packRGBA8ToR8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
- case kAlphaDoPremultiply:
+ case AlphaDoPremultiply:
doPacking<uint8_t, packRGBA8ToR8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
- case kAlphaDoUnmultiply:
+ case AlphaDoUnmultiply:
doPacking<uint8_t, packRGBA8ToR8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
}
@@ -1025,13 +1053,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
// specification, Table 3.15), the red and alpha channels
// are chosen from the RGBA data.
switch (alphaOp) {
- case kAlphaDoNothing:
+ case AlphaDoNothing:
doPacking<uint8_t, packRGBA8ToRA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
break;
- case kAlphaDoPremultiply:
+ case AlphaDoPremultiply:
doPacking<uint8_t, packRGBA8ToRA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
break;
- case kAlphaDoUnmultiply:
+ case AlphaDoUnmultiply:
doPacking<uint8_t, packRGBA8ToRA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
break;
}
@@ -1042,13 +1070,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
case UNSIGNED_SHORT_4_4_4_4: {
uint16_t* destination = static_cast<uint16_t*>(destinationData);
switch (alphaOp) {
- case kAlphaDoNothing:
+ case AlphaDoNothing:
doPacking<uint16_t, packRGBA8ToUnsignedShort4444>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
- case kAlphaDoPremultiply:
+ case AlphaDoPremultiply:
doPacking<uint16_t, packRGBA8ToUnsignedShort4444Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
- case kAlphaDoUnmultiply:
+ case AlphaDoUnmultiply:
doPacking<uint16_t, packRGBA8ToUnsignedShort4444Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
}
@@ -1057,13 +1085,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
case UNSIGNED_SHORT_5_5_5_1: {
uint16_t* destination = static_cast<uint16_t*>(destinationData);
switch (alphaOp) {
- case kAlphaDoNothing:
+ case AlphaDoNothing:
doPacking<uint16_t, packRGBA8ToUnsignedShort5551>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
- case kAlphaDoPremultiply:
+ case AlphaDoPremultiply:
doPacking<uint16_t, packRGBA8ToUnsignedShort5551Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
- case kAlphaDoUnmultiply:
+ case AlphaDoUnmultiply:
doPacking<uint16_t, packRGBA8ToUnsignedShort5551Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
}
@@ -1072,13 +1100,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
case UNSIGNED_SHORT_5_6_5: {
uint16_t* destination = static_cast<uint16_t*>(destinationData);
switch (alphaOp) {
- case kAlphaDoNothing:
+ case AlphaDoNothing:
doPacking<uint16_t, packRGBA8ToUnsignedShort565>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
- case kAlphaDoPremultiply:
+ case AlphaDoPremultiply:
doPacking<uint16_t, packRGBA8ToUnsignedShort565Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
- case kAlphaDoUnmultiply:
+ case AlphaDoUnmultiply:
doPacking<uint16_t, packRGBA8ToUnsignedShort565Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
break;
}
@@ -1088,55 +1116,6 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
return true;
}
-#if !PLATFORM(CHROMIUM)
-bool GraphicsContext3D::supportsBGRA()
-{
- // For OpenGL ES2.0, this requires checking for
- // GL_EXT_texture_format_BGRA8888 and GL_EXT_read_format_bgra.
- // For desktop GL, BGRA has been supported since OpenGL 1.2.
-
- // However, note that the GL ES2 extension requires the internalFormat to
- // glTexImage2D() be GL_BGRA, while desktop GL will not accept GL_BGRA
- // (must be GL_RGBA), so this must be checked on each platform.
- // Returning false for now to be safe.
- return false;
-}
-
-bool GraphicsContext3D::supportsMapSubCHROMIUM()
-{
- // We don't claim support for this extension at this time.
- return false;
-}
-
-void* GraphicsContext3D::mapBufferSubDataCHROMIUM(unsigned, int, int, unsigned)
-{
- return 0;
-}
-
-void GraphicsContext3D::unmapBufferSubDataCHROMIUM(const void*)
-{
-}
-
-void* GraphicsContext3D::mapTexSubImage2DCHROMIUM(unsigned, int, int, int, int, int, unsigned, unsigned, unsigned)
-{
- return 0;
-}
-
-void GraphicsContext3D::unmapTexSubImage2DCHROMIUM(const void*)
-{
-}
-
-bool GraphicsContext3D::supportsCopyTextureToParentTextureCHROMIUM()
-{
- // We don't claim support for this extension at this time.
- return false;
-}
-
-void GraphicsContext3D::copyTextureToParentTextureCHROMIUM(unsigned, unsigned)
-{
-}
-#endif
-
} // namespace WebCore
#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 20b4e2d..e34a2f8 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -76,6 +76,10 @@ const Platform3DObject NullPlatform3DObject = 0;
namespace WebCore {
class CanvasRenderingContext;
class DrawingBuffer;
+class Extensions3D;
+#if PLATFORM(MAC)
+class Extensions3DOpenGL;
+#endif
class HostWindow;
class Image;
class ImageData;
@@ -347,8 +351,6 @@ public:
VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A,
VERTEX_ATTRIB_ARRAY_POINTER = 0x8645,
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F,
- IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A,
- IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B,
COMPILE_STATUS = 0x8B81,
INFO_LOG_LENGTH = 0x8B84,
SHADER_SOURCE_LENGTH = 0x8B88,
@@ -401,19 +403,7 @@ public:
// WebGL-specific enums
UNPACK_FLIP_Y_WEBGL = 0x9240,
UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241,
-
- // GL_EXT_texture_format_BGRA8888
- BGRA_EXT = 0x80E1,
-
- // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object)
- READ_ONLY = 0x88B8,
- WRITE_ONLY = 0x88B9,
-
- // GL_ARB_robustness enums
- GUILTY_CONTEXT_RESET_ARB = 0x8253,
- INNOCENT_CONTEXT_RESET_ARB = 0x8254,
- UNKNOWN_CONTEXT_RESET_ARB = 0x8255
-
+ CONTEXT_LOST_WEBGL = 0x9242,
};
// Context creation attributes.
@@ -424,6 +414,7 @@ public:
, stencil(false)
, antialias(true)
, premultipliedAlpha(true)
+ , canRecoverFromContextLoss(true)
{
}
@@ -432,6 +423,7 @@ public:
bool stencil;
bool antialias;
bool premultipliedAlpha;
+ bool canRecoverFromContextLoss;
};
enum RenderStyle {
@@ -540,34 +532,36 @@ public:
// uploading. This enum must be public because it is accessed
// by non-member functions.
enum SourceDataFormat {
- kSourceFormatRGBA8 = 0,
- kSourceFormatRGBA16Little,
- kSourceFormatRGBA16Big,
- kSourceFormatRGB8,
- kSourceFormatRGB16Little,
- kSourceFormatRGB16Big,
- kSourceFormatBGRA8,
- kSourceFormatBGRA16Little,
- kSourceFormatBGRA16Big,
- kSourceFormatARGB8,
- kSourceFormatARGB16Little,
- kSourceFormatARGB16Big,
- kSourceFormatRGBA5551,
- kSourceFormatRGBA4444,
- kSourceFormatRGB565,
- kSourceFormatR8,
- kSourceFormatR16Little,
- kSourceFormatR16Big,
- kSourceFormatRA8,
- kSourceFormatRA16Little,
- kSourceFormatRA16Big,
- kSourceFormatAR8,
- kSourceFormatAR16Little,
- kSourceFormatAR16Big,
- kSourceFormatA8,
- kSourceFormatA16Little,
- kSourceFormatA16Big,
- kSourceFormatNumFormats
+ SourceFormatRGBA8 = 0,
+ SourceFormatRGBA16Little,
+ SourceFormatRGBA16Big,
+ SourceFormatRGB8,
+ SourceFormatRGB16Little,
+ SourceFormatRGB16Big,
+ SourceFormatBGR8,
+ SourceFormatBGRA8,
+ SourceFormatBGRA16Little,
+ SourceFormatBGRA16Big,
+ SourceFormatARGB8,
+ SourceFormatARGB16Little,
+ SourceFormatARGB16Big,
+ SourceFormatABGR8,
+ SourceFormatRGBA5551,
+ SourceFormatRGBA4444,
+ SourceFormatRGB565,
+ SourceFormatR8,
+ SourceFormatR16Little,
+ SourceFormatR16Big,
+ SourceFormatRA8,
+ SourceFormatRA16Little,
+ SourceFormatRA16Big,
+ SourceFormatAR8,
+ SourceFormatAR16Little,
+ SourceFormatAR16Big,
+ SourceFormatA8,
+ SourceFormatA16Little,
+ SourceFormatA16Big,
+ SourceFormatNumFormats
};
//----------------------------------------------------------------------
@@ -786,22 +780,11 @@ public:
// getError in the order they were added.
void synthesizeGLError(unsigned long error);
- // EXT_texture_format_BGRA8888
- bool supportsBGRA();
-
- // GL_CHROMIUM_map_sub
- bool supportsMapSubCHROMIUM();
- void* mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access);
- void unmapBufferSubDataCHROMIUM(const void*);
- void* mapTexSubImage2DCHROMIUM(unsigned target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, unsigned access);
- void unmapTexSubImage2DCHROMIUM(const void*);
-
- // GL_CHROMIUM_copy_texture_to_parent_texture
- bool supportsCopyTextureToParentTextureCHROMIUM();
- void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture);
-
- // GL_ARB_robustness
- int getGraphicsResetStatusARB();
+ // Support for extensions. Returns a non-null object, though not
+ // all methods it contains may necessarily be supported on the
+ // current hardware. Must call Extensions3D::supports() to
+ // determine this.
+ Extensions3D* getExtensions();
private:
GraphicsContext3D(Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow);
@@ -832,9 +815,9 @@ public:
// pixel packing. FIXME: kAlphaDoUnmultiply is lossy and must
// be removed.
enum AlphaOp {
- kAlphaDoNothing = 0,
- kAlphaDoPremultiply = 1,
- kAlphaDoUnmultiply = 2
+ AlphaDoNothing = 0,
+ AlphaDoPremultiply = 1,
+ AlphaDoUnmultiply = 2
};
// Helper for getImageData which implements packing of pixel
@@ -872,6 +855,8 @@ public:
ANGLEWebKitBridge m_compiler;
+ OwnPtr<Extensions3DOpenGL> m_extensions;
+
Attributes m_attrs;
Vector<Vector<float> > m_vertexArray;
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 79c33e0..9fb2d4a 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -648,6 +648,11 @@ MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const
return m_private->movieLoadType();
}
+float MediaPlayer::mediaTimeForTimeValue(float timeValue) const
+{
+ return m_private->mediaTimeForTimeValue(timeValue);
+}
+
// Client callbacks.
void MediaPlayer::networkStateChanged()
{
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index bf445e3..a199352 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -279,6 +279,8 @@ public:
bool hasSingleSecurityOrigin() const;
+ float mediaTimeForTimeValue(float) const;
+
private:
MediaPlayer(MediaPlayerClient*);
diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h
index a8d9b86..6a74714 100644
--- a/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -125,6 +125,10 @@ public:
virtual void prepareForRendering() { }
+ // Time value in the movie's time scale. It is only necessary to override this if the media
+ // engine uses rational numbers to represent media time.
+ virtual float mediaTimeForTimeValue(float timeValue) const { return timeValue; }
+
};
}
diff --git a/WebCore/platform/graphics/cairo/CairoUtilities.cpp b/WebCore/platform/graphics/cairo/CairoUtilities.cpp
index 7af5577..709ee8f 100644
--- a/WebCore/platform/graphics/cairo/CairoUtilities.cpp
+++ b/WebCore/platform/graphics/cairo/CairoUtilities.cpp
@@ -34,7 +34,7 @@
#include "IntRect.h"
#include "OwnPtrCairo.h"
#include "Path.h"
-#include "PlatformRefPtrCairo.h"
+#include "RefPtrCairo.h"
#include <wtf/Vector.h>
namespace WebCore {
@@ -126,11 +126,11 @@ void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSiz
cairo_save(cr);
- PlatformRefPtr<cairo_surface_t> clippedImageSurface = 0;
+ RefPtr<cairo_surface_t> clippedImageSurface = 0;
if (tileRect.size() != imageSize) {
IntRect imageRect = enclosingIntRect(tileRect);
- clippedImageSurface = adoptPlatformRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, imageRect.width(), imageRect.height()));
- PlatformRefPtr<cairo_t> clippedImageContext(cairo_create(clippedImageSurface.get()));
+ clippedImageSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, imageRect.width(), imageRect.height()));
+ RefPtr<cairo_t> clippedImageContext(cairo_create(clippedImageSurface.get()));
cairo_set_source_surface(clippedImageContext.get(), image, -tileRect.x(), -tileRect.y());
cairo_paint(clippedImageContext.get());
image = clippedImageSurface.get();
diff --git a/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp
index cd9ee46..61ee625 100644
--- a/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp
+++ b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp
@@ -25,7 +25,7 @@
#include "CString.h"
#include "Font.h"
#include "OwnPtrCairo.h"
-#include "PlatformRefPtrCairo.h"
+#include "RefPtrCairo.h"
#include "SimpleFontData.h"
#include <cairo-ft.h>
#include <cairo.h>
@@ -83,17 +83,17 @@ FcPattern* findBestFontGivenFallbacks(const FontPlatformData& fontData, FcPatter
const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
- PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(createFontConfigPatternForCharacters(characters, length));
+ RefPtr<FcPattern> pattern = adoptRef(createFontConfigPatternForCharacters(characters, length));
const FontPlatformData& fontData = font.primaryFont()->platformData();
- PlatformRefPtr<FcPattern> fallbackPattern = adoptPlatformRef(findBestFontGivenFallbacks(fontData, pattern.get()));
+ RefPtr<FcPattern> fallbackPattern = adoptRef(findBestFontGivenFallbacks(fontData, pattern.get()));
if (fallbackPattern) {
FontPlatformData alternateFontData(fallbackPattern.get(), font.fontDescription());
return getCachedFontData(&alternateFontData);
}
FcResult fontConfigResult;
- PlatformRefPtr<FcPattern> resultPattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fontConfigResult));
+ RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult));
if (!resultPattern)
return 0;
FontPlatformData alternateFontData(resultPattern.get(), font.fontDescription());
@@ -147,7 +147,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
// The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
// says that we must find an exact match for font family, slant (italic or oblique can be used)
// and font weight (we only match bold/non-bold here).
- PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(FcPatternCreate());
+ RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate());
String familyNameString(getFamilyNameStringFromFontDescriptionAndFamily(fontDescription, family));
if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data())))
return 0;
@@ -174,7 +174,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
String familyNameAfterConfiguration = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterConfiguration));
FcResult fontConfigResult;
- PlatformRefPtr<FcPattern> resultPattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fontConfigResult));
+ RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult));
if (!resultPattern) // No match.
return 0;
diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp
index ba307fa..394082d 100644
--- a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp
+++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp
@@ -120,8 +120,9 @@ FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fo
, m_syntheticBold(false)
, m_syntheticOblique(false)
, m_fixedWidth(false)
+ , m_scaledFont(0)
{
- PlatformRefPtr<cairo_font_face_t> fontFace = adoptPlatformRef(cairo_ft_font_face_create_for_pattern(m_pattern.get()));
+ RefPtr<cairo_font_face_t> fontFace = adoptRef(cairo_ft_font_face_create_for_pattern(m_pattern.get()));
initializeWithFontFace(fontFace.get());
int spacing;
@@ -142,6 +143,7 @@ FontPlatformData::FontPlatformData(float size, bool bold, bool italic)
, m_syntheticBold(bold)
, m_syntheticOblique(italic)
, m_fixedWidth(false)
+ , m_scaledFont(0)
{
// We cannot create a scaled font here.
}
@@ -151,13 +153,14 @@ FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, float size, bool
, m_size(size)
, m_syntheticBold(bold)
, m_syntheticOblique(italic)
+ , m_scaledFont(0)
{
initializeWithFontFace(fontFace);
- FT_Face fontConfigFace = cairo_ft_scaled_font_lock_face(m_scaledFont.get());
+ FT_Face fontConfigFace = cairo_ft_scaled_font_lock_face(m_scaledFont);
if (fontConfigFace) {
m_fixedWidth = fontConfigFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH;
- cairo_ft_scaled_font_unlock_face(m_scaledFont.get());
+ cairo_ft_scaled_font_unlock_face(m_scaledFont);
}
}
@@ -171,7 +174,6 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
m_syntheticBold = other.m_syntheticBold;
m_syntheticOblique = other.m_syntheticOblique;
m_fixedWidth = other.m_fixedWidth;
- m_scaledFont = other.m_scaledFont;
m_pattern = other.m_pattern;
if (m_fallbacks) {
@@ -180,11 +182,16 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
m_fallbacks = 0;
}
+ if (m_scaledFont && m_scaledFont != hashTableDeletedFontValue())
+ cairo_scaled_font_destroy(m_scaledFont);
+ m_scaledFont = cairo_scaled_font_reference(other.m_scaledFont);
+
return *this;
}
FontPlatformData::FontPlatformData(const FontPlatformData& other)
: m_fallbacks(0)
+ , m_scaledFont(0)
{
*this = other;
}
@@ -196,7 +203,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& other, float size)
// We need to reinitialize the instance, because the difference in size
// necessitates a new scaled font instance.
m_size = size;
- initializeWithFontFace(cairo_scaled_font_get_font_face(m_scaledFont.get()));
+ initializeWithFontFace(cairo_scaled_font_get_font_face(m_scaledFont));
}
FontPlatformData::~FontPlatformData()
@@ -205,6 +212,9 @@ FontPlatformData::~FontPlatformData()
FcFontSetDestroy(m_fallbacks);
m_fallbacks = 0;
}
+
+ if (m_scaledFont && m_scaledFont != hashTableDeletedFontValue())
+ cairo_scaled_font_destroy(m_scaledFont);
}
bool FontPlatformData::isFixedPitch()
@@ -216,7 +226,7 @@ bool FontPlatformData::operator==(const FontPlatformData& other) const
{
if (m_pattern == other.m_pattern)
return true;
- if (!m_pattern || m_pattern.isHashTableDeletedValue() || !other.m_pattern || other.m_pattern.isHashTableDeletedValue())
+ if (!m_pattern || !other.m_pattern)
return false;
return FcPatternEqual(m_pattern.get(), other.m_pattern.get());
}
@@ -256,7 +266,7 @@ void FontPlatformData::initializeWithFontFace(cairo_font_face_t* fontFace)
cairo_matrix_scale(&fontMatrix, m_size, m_size);
}
- m_scaledFont = adoptPlatformRef(cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options));
+ m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options);
cairo_font_options_destroy(options);
}
diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h
index d47d556..016489e 100644
--- a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h
+++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h
@@ -29,7 +29,7 @@
#include "FontDescription.h"
#include "GlyphBuffer.h"
#include "HashFunctions.h"
-#include "PlatformRefPtrCairo.h"
+#include "RefPtrCairo.h"
#include <wtf/Forward.h>
typedef struct _FcFontSet FcFontSet;
@@ -43,7 +43,7 @@ public:
, m_size(0)
, m_syntheticBold(false)
, m_syntheticOblique(false)
- , m_scaledFont(WTF::HashTableDeletedValue)
+ , m_scaledFont(hashTableDeletedFontValue())
{ }
FontPlatformData()
@@ -51,6 +51,7 @@ public:
, m_size(0)
, m_syntheticBold(false)
, m_syntheticOblique(false)
+ , m_scaledFont(0)
{ }
FontPlatformData(FcPattern*, const FontDescription&);
@@ -67,34 +68,35 @@ public:
bool syntheticBold() const { return m_syntheticBold; }
bool syntheticOblique() const { return m_syntheticOblique; }
- cairo_scaled_font_t* scaledFont() const { return m_scaledFont.get(); }
+ cairo_scaled_font_t* scaledFont() const { return m_scaledFont; }
unsigned hash() const
{
- return PtrHash<cairo_scaled_font_t*>::hash(m_scaledFont.get());
+ return PtrHash<cairo_scaled_font_t*>::hash(m_scaledFont);
}
bool operator==(const FontPlatformData&) const;
FontPlatformData& operator=(const FontPlatformData&);
bool isHashTableDeletedValue() const
{
- return m_scaledFont.isHashTableDeletedValue();
+ return m_scaledFont == hashTableDeletedFontValue();
}
#ifndef NDEBUG
String description() const;
#endif
- PlatformRefPtr<FcPattern> m_pattern;
+ RefPtr<FcPattern> m_pattern;
mutable FcFontSet* m_fallbacks; // Initialized lazily.
float m_size;
bool m_syntheticBold;
bool m_syntheticOblique;
bool m_fixedWidth;
- PlatformRefPtr<cairo_scaled_font_t> m_scaledFont;
+ cairo_scaled_font_t* m_scaledFont;
private:
void initializeWithFontFace(cairo_font_face_t*);
+ static cairo_scaled_font_t* hashTableDeletedFontValue() { return reinterpret_cast<cairo_scaled_font_t*>(-1); }
};
}
diff --git a/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp b/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp
index 66e9c16..e2f09f4 100644
--- a/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp
@@ -45,7 +45,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
if (bufferLength > GlyphPage::size)
return false;
- FT_Face face = cairo_ft_scaled_font_lock_face(fontData->platformData().m_scaledFont.get());
+ FT_Face face = cairo_ft_scaled_font_lock_face(fontData->platformData().scaledFont());
if (!face)
return false;
@@ -60,7 +60,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
}
}
- cairo_ft_scaled_font_unlock_face(fontData->platformData().m_scaledFont.get());
+ cairo_ft_scaled_font_unlock_face(fontData->platformData().scaledFont());
return haveGlyphs;
}
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 0847da1..755adff 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -46,7 +46,7 @@
#include "NotImplemented.h"
#include "Path.h"
#include "Pattern.h"
-#include "PlatformRefPtrCairo.h"
+#include "RefPtrCairo.h"
#include "SimpleFontData.h"
#include <cairo.h>
#include <math.h>
@@ -766,14 +766,6 @@ void GraphicsContext::translate(float x, float y)
m_data->translate(x, y);
}
-IntPoint GraphicsContext::origin()
-{
- cairo_matrix_t matrix;
- cairo_t* cr = m_data->cr;
- cairo_get_matrix(cr, &matrix);
- return IntPoint(static_cast<int>(matrix.x0), static_cast<int>(matrix.y0));
-}
-
void GraphicsContext::setPlatformFillColor(const Color& col, ColorSpace colorSpace)
{
// Cairo contexts can't hold separate fill and stroke colors
@@ -1092,16 +1084,6 @@ void GraphicsContext::clipOut(const IntRect& r)
cairo_set_fill_rule(cr, savedFillRule);
}
-void GraphicsContext::clipOutEllipseInRect(const IntRect& r)
-{
- if (paintingDisabled())
- return;
-
- Path p;
- p.addEllipse(r);
- clipOut(p);
-}
-
static inline FloatPoint getPhase(const FloatRect& dest, const FloatRect& tile)
{
FloatPoint phase = dest.location();
diff --git a/WebCore/platform/graphics/cairo/ImageCairo.cpp b/WebCore/platform/graphics/cairo/ImageCairo.cpp
index 8f7a194..0ac3955 100644
--- a/WebCore/platform/graphics/cairo/ImageCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageCairo.cpp
@@ -35,10 +35,10 @@
#include "Color.h"
#include "ContextShadow.h"
#include "FloatRect.h"
-#include "PlatformRefPtrCairo.h"
#include "GraphicsContext.h"
#include "ImageBuffer.h"
#include "ImageObserver.h"
+#include "RefPtrCairo.h"
#include <cairo.h>
#include <math.h>
#include <wtf/OwnPtr.h>
diff --git a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp b/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
index d289585..a6c983e 100644
--- a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp
+++ b/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
@@ -17,7 +17,7 @@
*/
#include "config.h"
-#include "PlatformRefPtrCairo.h"
+#include "RefPtrCairo.h"
#include <cairo.h>
@@ -28,71 +28,67 @@
namespace WTF {
-template <> cairo_t* refPlatformPtr(cairo_t* ptr)
+template<> void refIfNotNull(cairo_t* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
cairo_reference(ptr);
- return ptr;
}
-template <> void derefPlatformPtr(cairo_t* ptr)
+template<> void derefIfNotNull(cairo_t* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
cairo_destroy(ptr);
}
-template <> cairo_surface_t* refPlatformPtr(cairo_surface_t* ptr)
+template<> void refIfNotNull(cairo_surface_t* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
cairo_surface_reference(ptr);
- return ptr;
}
-template <> void derefPlatformPtr(cairo_surface_t* ptr)
+template<> void derefIfNotNull(cairo_surface_t* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
cairo_surface_destroy(ptr);
}
-template <> cairo_font_face_t* refPlatformPtr(cairo_font_face_t* ptr)
+template<> void refIfNotNull(cairo_font_face_t* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
cairo_font_face_reference(ptr);
- return ptr;
}
-template <> void derefPlatformPtr(cairo_font_face_t* ptr)
+template<> void derefIfNotNull(cairo_font_face_t* ptr)
{
- if (ptr)
- cairo_font_face_destroy(ptr);
+ if (LIKELY(ptr != 0))
+ cairo_font_face_reference(ptr);
}
-template <> cairo_scaled_font_t* refPlatformPtr(cairo_scaled_font_t* ptr)
+template<> void refIfNotNull(cairo_scaled_font_t* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
cairo_scaled_font_reference(ptr);
- return ptr;
}
-template <> void derefPlatformPtr(cairo_scaled_font_t* ptr)
+template<> void derefIfNotNull(cairo_scaled_font_t* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
cairo_scaled_font_destroy(ptr);
}
#if defined(USE_FREETYPE)
-template <> FcPattern* refPlatformPtr(FcPattern* ptr)
+template<> void refIfNotNull(FcPattern* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
FcPatternReference(ptr);
- return ptr;
}
-template <> void derefPlatformPtr(FcPattern* ptr)
+template<> void derefIfNotNull(FcPattern* ptr)
{
- if (ptr)
+ if (LIKELY(ptr != 0))
FcPatternDestroy(ptr);
}
+
#endif
}
diff --git a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h b/WebCore/platform/graphics/cairo/RefPtrCairo.h
index 3b720c6..0429ec5 100644
--- a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h
+++ b/WebCore/platform/graphics/cairo/RefPtrCairo.h
@@ -17,10 +17,10 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef PlatformRefPtrCairo_h
-#define PlatformRefPtrCairo_h
+#ifndef RefPtrCairo_h
+#define RefPtrCairo_h
-#include "PlatformRefPtr.h"
+#include "RefPtr.h"
typedef struct _cairo cairo_t;
typedef struct _cairo_surface cairo_surface_t;
@@ -33,23 +33,23 @@ typedef struct _FcPattern FcPattern;
namespace WTF {
-template <> cairo_t* refPlatformPtr(cairo_t* ptr);
-template <> void derefPlatformPtr(cairo_t* ptr);
+template<> void refIfNotNull(cairo_t* ptr);
+template<> void derefIfNotNull(cairo_t* ptr);
-template <> cairo_surface_t* refPlatformPtr(cairo_surface_t* ptr);
-template <> void derefPlatformPtr(cairo_surface_t* ptr);
+template<> void refIfNotNull(cairo_surface_t* ptr);
+template<> void derefIfNotNull(cairo_surface_t* ptr);
-template <> cairo_font_face_t* refPlatformPtr(cairo_font_face_t*);
-template <> void derefPlatformPtr(cairo_font_face_t*);
+template<> void refIfNotNull(cairo_font_face_t* ptr);
+template<> void derefIfNotNull(cairo_font_face_t* ptr);
-template <> cairo_scaled_font_t* refPlatformPtr(cairo_scaled_font_t*);
-template <> void derefPlatformPtr(cairo_scaled_font_t*);
+template<> void refIfNotNull(cairo_scaled_font_t* ptr);
+template<> void derefIfNotNull(cairo_scaled_font_t* ptr);
#if defined(USE_FREETYPE)
-template <> FcPattern* refPlatformPtr(FcPattern*);
-template <> void derefPlatformPtr(FcPattern*);
+template<> void refIfNotNull(FcPattern* ptr);
+template<> void derefIfNotNull(FcPattern* ptr);
#endif
}
-#endif
+#endif // RefPtrCairo_h
diff --git a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
index 3d7c34b..d350294 100644
--- a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
+++ b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
@@ -49,7 +49,7 @@ void SimpleFontData::platformInit()
{
cairo_font_extents_t font_extents;
cairo_text_extents_t text_extents;
- cairo_scaled_font_extents(m_platformData.m_scaledFont.get(), &font_extents);
+ cairo_scaled_font_extents(m_platformData.scaledFont(), &font_extents);
m_ascent = static_cast<int>(lroundf(font_extents.ascent));
m_descent = static_cast<int>(lroundf(font_extents.descent));
m_lineSpacing = static_cast<int>(lroundf(font_extents.height));
@@ -60,9 +60,9 @@ void SimpleFontData::platformInit()
// while we figure out what's going on.
if (m_lineSpacing < m_ascent + m_descent)
m_lineSpacing = m_ascent + m_descent;
- cairo_scaled_font_text_extents(m_platformData.m_scaledFont.get(), "x", &text_extents);
+ cairo_scaled_font_text_extents(m_platformData.scaledFont(), "x", &text_extents);
m_xHeight = text_extents.height;
- cairo_scaled_font_text_extents(m_platformData.m_scaledFont.get(), " ", &text_extents);
+ cairo_scaled_font_text_extents(m_platformData.scaledFont(), " ", &text_extents);
m_spaceWidth = static_cast<float>(text_extents.x_advance);
m_lineGap = m_lineSpacing - m_ascent - m_descent;
m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
@@ -94,19 +94,19 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
- FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.m_scaledFont.get());
+ FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.scaledFont());
if (!face)
return false;
for (int i = 0; i < length; i++) {
if (FcFreeTypeCharIndex(face, characters[i]) == 0) {
- cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont.get());
+ cairo_ft_scaled_font_unlock_face(m_platformData.scaledFont());
return false;
}
}
- cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont.get());
+ cairo_ft_scaled_font_unlock_face(m_platformData.scaledFont());
return true;
}
@@ -123,14 +123,14 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
- ASSERT(m_platformData.m_scaledFont);
+ ASSERT(m_platformData.scaledFont());
cairo_glyph_t cglyph = { glyph, 0, 0 };
cairo_text_extents_t extents;
- cairo_scaled_font_glyph_extents(m_platformData.m_scaledFont.get(), &cglyph, 1, &extents);
+ cairo_scaled_font_glyph_extents(m_platformData.scaledFont(), &cglyph, 1, &extents);
float w = (float)m_spaceWidth;
- if (cairo_scaled_font_status(m_platformData.m_scaledFont.get()) == CAIRO_STATUS_SUCCESS && extents.x_advance)
+ if (cairo_scaled_font_status(m_platformData.scaledFont()) == CAIRO_STATUS_SUCCESS && extents.x_advance)
w = (float)extents.x_advance;
return w;
diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index a1cc805..0c6acf9 100644
--- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -59,7 +59,7 @@ enum AlphaFormat {
AlphaFormatNumFormats
};
-// This returns kSourceFormatNumFormats if the combination of input parameters is unsupported.
+// This returns SourceFormatNumFormats if the combination of input parameters is unsupported.
static GraphicsContext3D::SourceDataFormat getSourceDataFormat(unsigned int componentsPerPixel, AlphaFormat alphaFormat, bool is16BitFormat, bool bigEndian)
{
const static SourceDataFormatBase formatTableBase[4][AlphaFormatNumFormats] = { // componentsPerPixel x AlphaFormat
@@ -69,26 +69,22 @@ static GraphicsContext3D::SourceDataFormat getSourceDataFormat(unsigned int comp
{ SourceFormatBaseRGB, SourceFormatBaseNumFormats, SourceFormatBaseNumFormats }, // 3 componentsPerPixel
{ SourceFormatBaseNumFormats, SourceFormatBaseARGB, SourceFormatBaseRGBA } // 4 componentsPerPixel
};
- const static GraphicsContext3D::SourceDataFormat formatTable[SourceFormatBaseNumFormats][3] = { // SourceDataFormatBase x bitsPerComponentAndEndian
- // 8bits 16bits, little endian 16bits, big endian
- { GraphicsContext3D::kSourceFormatR8, GraphicsContext3D::kSourceFormatR16Little, GraphicsContext3D::kSourceFormatR16Big },
- { GraphicsContext3D::kSourceFormatA8, GraphicsContext3D::kSourceFormatA16Little, GraphicsContext3D::kSourceFormatA16Big },
- { GraphicsContext3D::kSourceFormatRA8, GraphicsContext3D::kSourceFormatRA16Little, GraphicsContext3D::kSourceFormatRA16Big },
- { GraphicsContext3D::kSourceFormatAR8, GraphicsContext3D::kSourceFormatAR16Little, GraphicsContext3D::kSourceFormatAR16Big },
- { GraphicsContext3D::kSourceFormatRGB8, GraphicsContext3D::kSourceFormatRGB16Little, GraphicsContext3D::kSourceFormatRGB16Big },
- { GraphicsContext3D::kSourceFormatRGBA8, GraphicsContext3D::kSourceFormatRGBA16Little, GraphicsContext3D::kSourceFormatRGBA16Big },
- { GraphicsContext3D::kSourceFormatARGB8, GraphicsContext3D::kSourceFormatARGB16Little, GraphicsContext3D::kSourceFormatARGB16Big }
+ const static GraphicsContext3D::SourceDataFormat formatTable[SourceFormatBaseNumFormats][4] = { // SourceDataFormatBase x bitsPerComponent x endian
+ // 8bits, little endian 8bits, big endian 16bits, little endian 16bits, big endian
+ { GraphicsContext3D::SourceFormatR8, GraphicsContext3D::SourceFormatR8, GraphicsContext3D::SourceFormatR16Little, GraphicsContext3D::SourceFormatR16Big },
+ { GraphicsContext3D::SourceFormatA8, GraphicsContext3D::SourceFormatA8, GraphicsContext3D::SourceFormatA16Little, GraphicsContext3D::SourceFormatA16Big },
+ { GraphicsContext3D::SourceFormatAR8, GraphicsContext3D::SourceFormatRA8, GraphicsContext3D::SourceFormatRA16Little, GraphicsContext3D::SourceFormatRA16Big },
+ { GraphicsContext3D::SourceFormatRA8, GraphicsContext3D::SourceFormatAR8, GraphicsContext3D::SourceFormatAR16Little, GraphicsContext3D::SourceFormatAR16Big },
+ { GraphicsContext3D::SourceFormatBGR8, GraphicsContext3D::SourceFormatRGB8, GraphicsContext3D::SourceFormatRGB16Little, GraphicsContext3D::SourceFormatRGB16Big },
+ { GraphicsContext3D::SourceFormatABGR8, GraphicsContext3D::SourceFormatRGBA8, GraphicsContext3D::SourceFormatRGBA16Little, GraphicsContext3D::SourceFormatRGBA16Big },
+ { GraphicsContext3D::SourceFormatBGRA8, GraphicsContext3D::SourceFormatARGB8, GraphicsContext3D::SourceFormatARGB16Little, GraphicsContext3D::SourceFormatARGB16Big }
};
ASSERT(componentsPerPixel <= 4 && componentsPerPixel > 0);
SourceDataFormatBase formatBase = formatTableBase[componentsPerPixel - 1][alphaFormat];
if (formatBase == SourceFormatBaseNumFormats)
- return GraphicsContext3D::kSourceFormatNumFormats;
- if (!is16BitFormat)
- return formatTable[formatBase][0];
- if (!bigEndian)
- return formatTable[formatBase][1];
- return formatTable[formatBase][2];
+ return GraphicsContext3D::SourceFormatNumFormats;
+ return formatTable[formatBase][(is16BitFormat ? 2 : 0) + (bigEndian ? 1 : 0)];
}
bool GraphicsContext3D::getImageData(Image* image,
@@ -125,28 +121,47 @@ bool GraphicsContext3D::getImageData(Image* image,
return false;
size_t componentsPerPixel = bitsPerPixel / bitsPerComponent;
- bool srcByteOrder16Big = false;
+ CGBitmapInfo bitInfo = CGImageGetBitmapInfo(cgImage);
+ bool bigEndianSource = false;
+ // These could technically be combined into one large switch
+ // statement, but we prefer not to so that we fail fast if we
+ // encounter an unexpected image configuration.
if (bitsPerComponent == 16) {
- CGBitmapInfo bitInfo = CGImageGetBitmapInfo(cgImage);
switch (bitInfo & kCGBitmapByteOrderMask) {
case kCGBitmapByteOrder16Big:
- srcByteOrder16Big = true;
+ bigEndianSource = true;
break;
case kCGBitmapByteOrder16Little:
- srcByteOrder16Big = false;
+ bigEndianSource = false;
break;
case kCGBitmapByteOrderDefault:
// This is a bug in earlier version of cg where the default endian
// is little whereas the decoded 16-bit png image data is actually
// Big. Later version (10.6.4) no longer returns ByteOrderDefault.
- srcByteOrder16Big = true;
+ bigEndianSource = true;
+ break;
+ default:
+ return false;
+ }
+ } else {
+ switch (bitInfo & kCGBitmapByteOrderMask) {
+ case kCGBitmapByteOrder32Big:
+ bigEndianSource = true;
+ break;
+ case kCGBitmapByteOrder32Little:
+ bigEndianSource = false;
+ break;
+ case kCGBitmapByteOrderDefault:
+ // It appears that the default byte order is actually big
+ // endian even on little endian architectures.
+ bigEndianSource = true;
break;
default:
return false;
}
}
- AlphaOp neededAlphaOp = kAlphaDoNothing;
+ AlphaOp neededAlphaOp = AlphaDoNothing;
AlphaFormat alphaFormat = AlphaFormatNone;
switch (CGImageGetAlphaInfo(cgImage)) {
case kCGImageAlphaPremultipliedFirst:
@@ -155,13 +170,13 @@ bool GraphicsContext3D::getImageData(Image* image,
// in which case image->data() should be null.
ASSERT(!image->data());
if (!premultiplyAlpha)
- neededAlphaOp = kAlphaDoUnmultiply;
+ neededAlphaOp = AlphaDoUnmultiply;
alphaFormat = AlphaFormatFirst;
break;
case kCGImageAlphaFirst:
// This path is only accessible for MacOS earlier than 10.6.4.
if (premultiplyAlpha)
- neededAlphaOp = kAlphaDoPremultiply;
+ neededAlphaOp = AlphaDoPremultiply;
alphaFormat = AlphaFormatFirst;
break;
case kCGImageAlphaNoneSkipFirst:
@@ -173,12 +188,12 @@ bool GraphicsContext3D::getImageData(Image* image,
// in which case image->data() should be null.
ASSERT(!image->data());
if (!premultiplyAlpha)
- neededAlphaOp = kAlphaDoUnmultiply;
+ neededAlphaOp = AlphaDoUnmultiply;
alphaFormat = AlphaFormatLast;
break;
case kCGImageAlphaLast:
if (premultiplyAlpha)
- neededAlphaOp = kAlphaDoPremultiply;
+ neededAlphaOp = AlphaDoPremultiply;
alphaFormat = AlphaFormatLast;
break;
case kCGImageAlphaNoneSkipLast:
@@ -190,8 +205,8 @@ bool GraphicsContext3D::getImageData(Image* image,
default:
return false;
}
- SourceDataFormat srcDataFormat = getSourceDataFormat(componentsPerPixel, alphaFormat, bitsPerComponent == 16, srcByteOrder16Big);
- if (srcDataFormat == kSourceFormatNumFormats)
+ SourceDataFormat srcDataFormat = getSourceDataFormat(componentsPerPixel, alphaFormat, bitsPerComponent == 16, bigEndianSource);
+ if (srcDataFormat == SourceFormatNumFormats)
return false;
RetainPtr<CFDataRef> pixelData;
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 9e0a2f5..8d72b85 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -669,17 +669,6 @@ void GraphicsContext::clipOut(const IntRect& rect)
CGContextEOClip(platformContext());
}
-void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
-{
- if (paintingDisabled())
- return;
-
- CGContextBeginPath(platformContext());
- CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext()));
- CGContextAddEllipseInRect(platformContext(), rect);
- CGContextEOClip(platformContext());
-}
-
void GraphicsContext::clipPath(WindRule clipRule)
{
if (paintingDisabled())
diff --git a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
index b54a427..e44ec9d 100644
--- a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
+++ b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -32,6 +32,7 @@
#include "DrawingBuffer.h"
+#include "Extensions3DChromium.h"
#include "GraphicsContext3D.h"
#include "SharedGraphicsContext3D.h"
@@ -69,9 +70,14 @@ static unsigned generateColorTexture(GraphicsContext3D* context, const IntSize&
DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size)
: m_context(context)
, m_size(size)
- , m_fbo(context->createFramebuffer())
+ , m_fbo(0)
, m_internal(new DrawingBufferInternal)
{
+ if (!m_context->getExtensions()->supports("GL_CHROMIUM_copy_texture_to_parent_texture")) {
+ m_context.clear();
+ return;
+ }
+ m_fbo = context->createFramebuffer();
context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
m_internal->offscreenColorTexture = generateColorTexture(context, size);
}
@@ -107,7 +113,7 @@ void DrawingBuffer::publishToPlatformLayer()
// happens before the compositor draws. This means we might draw stale frames sometimes. Ideally this
// would insert a fence into the child command stream that the compositor could wait for.
m_context->makeContextCurrent();
- m_context->copyTextureToParentTextureCHROMIUM(m_internal->offscreenColorTexture, parentTexture);
+ static_cast<Extensions3DChromium*>(m_context->getExtensions())->copyTextureToParentTextureCHROMIUM(m_internal->offscreenColorTexture, parentTexture);
m_context->flush();
}
#endif
diff --git a/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/WebCore/platform/graphics/chromium/Extensions3DChromium.h
new file mode 100644
index 0000000..0fd1fff
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/Extensions3DChromium.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Extensions3DChromium_h
+#define Extensions3DChromium_h
+
+#include "Extensions3D.h"
+
+namespace WebCore {
+
+class GraphicsContext3DInternal;
+
+class Extensions3DChromium : public Extensions3D {
+public:
+ virtual ~Extensions3DChromium();
+
+ // Extensions3D methods.
+ virtual bool supports(const String&);
+ virtual int getGraphicsResetStatusARB();
+
+ enum {
+ // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object)
+ READ_ONLY = 0x88B8,
+ WRITE_ONLY = 0x88B9
+ };
+
+ // GL_CHROMIUM_map_sub
+ void* mapBufferSubDataCHROMIUM(unsigned target, int offset, int size, unsigned access);
+ void unmapBufferSubDataCHROMIUM(const void*);
+ void* mapTexSubImage2DCHROMIUM(unsigned target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, unsigned access);
+ void unmapTexSubImage2DCHROMIUM(const void*);
+
+ // GL_CHROMIUM_copy_texture_to_parent_texture
+ void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture);
+
+private:
+ // Instances of this class are strictly owned by the GraphicsContext3D implementation and do not
+ // need to be instantiated by any other code.
+ friend class GraphicsContext3DInternal;
+ explicit Extensions3DChromium(GraphicsContext3DInternal*);
+
+ // Weak pointer back to GraphicsContext3DInternal
+ GraphicsContext3DInternal* m_internal;
+};
+
+} // namespace WebCore
+
+#endif // Extensions3DChromium_h
diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
index 7c3e450..384b1c5 100644
--- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
@@ -391,10 +391,10 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
int numFonts = 0;
if (script == USCRIPT_HAN) {
panUniFonts = cjkFonts;
- numFonts = ARRAYSIZE(cjkFonts);
+ numFonts = WTF_ARRAY_LENGTH(cjkFonts);
} else {
panUniFonts = commonFonts;
- numFonts = ARRAYSIZE(commonFonts);
+ numFonts = WTF_ARRAY_LENGTH(commonFonts);
}
// Font returned from GetFallbackFamily may not cover |characters|
// because it's based on script to font mapping. This problem is
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index f668bbf..23e54e5 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -370,6 +370,7 @@ void LayerChromium::setNeedsDisplay()
{
m_dirtyRect.setSize(m_bounds);
m_contentsDirty = true;
+ setNeedsCommit();
}
void LayerChromium::resetNeedsDisplay()
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index e93e296..e1b525b 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -730,7 +730,10 @@ bool LayerRendererChromium::initializeSharedObjects()
m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get()));
m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get()));
m_videoLayerSharedValues = adoptPtr(new VideoLayerChromium::SharedValues(m_context.get()));
- if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized() || !m_videoLayerSharedValues->initialized()) {
+ m_pluginLayerSharedValues = adoptPtr(new PluginLayerChromium::SharedValues(m_context.get()));
+
+ if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized()
+ || !m_videoLayerSharedValues->initialized() || !m_pluginLayerSharedValues->initialized()) {
cleanupSharedObjects();
return false;
}
@@ -746,6 +749,7 @@ void LayerRendererChromium::cleanupSharedObjects()
m_contentLayerSharedValues.clear();
m_canvasLayerSharedValues.clear();
m_videoLayerSharedValues.clear();
+ m_pluginLayerSharedValues.clear();
if (m_scrollShaderProgram) {
GLC(m_context, m_context->deleteProgram(m_scrollShaderProgram));
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index b2a32ee..52fbe36 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -38,6 +38,7 @@
#include "ContentLayerChromium.h"
#include "IntRect.h"
#include "LayerChromium.h"
+#include "PluginLayerChromium.h"
#include "SkBitmap.h"
#include "VideoLayerChromium.h"
#include <wtf/HashMap.h>
@@ -107,6 +108,7 @@ public:
const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); }
const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); }
const VideoLayerChromium::SharedValues* videoLayerSharedValues() const { return m_videoLayerSharedValues.get(); }
+ const PluginLayerChromium::SharedValues* pluginLayerSharedValues() const { return m_pluginLayerSharedValues.get(); }
void resizeOnscreenContent(const IntSize&);
@@ -180,6 +182,7 @@ private:
OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues;
OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues;
OwnPtr<VideoLayerChromium::SharedValues> m_videoLayerSharedValues;
+ OwnPtr<PluginLayerChromium::SharedValues> m_pluginLayerSharedValues;
RefPtr<GraphicsContext3D> m_context;
};
diff --git a/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp b/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
new file mode 100644
index 0000000..2d1852f
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "PluginLayerChromium.h"
+
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+PluginLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context)
+ : m_context(context)
+ , m_shaderProgram(0)
+ , m_shaderSamplerLocation(-1)
+ , m_shaderMatrixLocation(-1)
+ , m_shaderAlphaLocation(-1)
+ , m_initialized(false)
+{
+ char vertexShaderString[] =
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "uniform mat4 matrix; \n"
+ "varying vec2 v_texCoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = matrix * a_position; \n"
+ " v_texCoord = a_texCoord; \n"
+ "} \n";
+
+ char fragmentShaderString[] =
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D s_texture; \n"
+ "uniform float alpha; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, v_texCoord.y)); \n"
+ " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
+ "} \n";
+
+ m_shaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString);
+ if (!m_shaderProgram) {
+ LOG_ERROR("PluginLayerChromium: Failed to create shader program");
+ return;
+ }
+
+ m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture");
+ m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix");
+ m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha");
+ ASSERT(m_shaderSamplerLocation != -1);
+ ASSERT(m_shaderMatrixLocation != -1);
+ ASSERT(m_shaderAlphaLocation != -1);
+
+ m_initialized = true;
+}
+
+PluginLayerChromium::SharedValues::~SharedValues()
+{
+ if (m_shaderProgram)
+ GLC(m_context, m_context->deleteProgram(m_shaderProgram));
+}
+
+PassRefPtr<PluginLayerChromium> PluginLayerChromium::create(GraphicsLayerChromium* owner)
+{
+ return adoptRef(new PluginLayerChromium(owner));
+}
+
+PluginLayerChromium::PluginLayerChromium(GraphicsLayerChromium* owner)
+ : LayerChromium(owner)
+{
+}
+
+void PluginLayerChromium::setTextureId(unsigned id)
+{
+ m_textureId = id;
+}
+
+void PluginLayerChromium::updateContents()
+{
+}
+
+void PluginLayerChromium::draw()
+{
+ ASSERT(layerRenderer());
+ const PluginLayerChromium::SharedValues* sv = layerRenderer()->pluginLayerSharedValues();
+ ASSERT(sv && sv->initialized());
+ GraphicsContext3D* context = layerRendererContext();
+ GLC(context, context->activeTexture(GL_TEXTURE0));
+ GLC(context, context->bindTexture(GL_TEXTURE_2D, m_textureId));
+
+ // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
+ // where it will only happen once per texture.
+ GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+
+ layerRenderer()->useShader(sv->shaderProgram());
+ GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/PluginLayerChromium.h b/WebCore/platform/graphics/chromium/PluginLayerChromium.h
new file mode 100644
index 0000000..44a6cc9
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/PluginLayerChromium.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef PluginLayerChromium_h
+#define PluginLayerChromium_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerChromium.h"
+
+namespace WebCore {
+
+// A Layer containing a the rendered output of a plugin instance.
+class PluginLayerChromium : public LayerChromium {
+public:
+ static PassRefPtr<PluginLayerChromium> create(GraphicsLayerChromium* owner = 0);
+ virtual bool drawsContent() { return true; }
+ virtual void updateContents();
+ virtual void draw();
+
+ void setTextureId(unsigned textureId);
+
+ class SharedValues {
+ public:
+ SharedValues(GraphicsContext3D* context);
+ ~SharedValues();
+
+ unsigned shaderProgram() const { return m_shaderProgram; }
+ int shaderSamplerLocation() const { return m_shaderSamplerLocation; }
+ int shaderMatrixLocation() const { return m_shaderMatrixLocation; }
+ int shaderAlphaLocation() const { return m_shaderAlphaLocation; }
+ bool initialized() const { return m_initialized; }
+
+ private:
+ GraphicsContext3D* m_context;
+ unsigned m_shaderProgram;
+ int m_shaderSamplerLocation;
+ int m_shaderMatrixLocation;
+ int m_shaderAlphaLocation;
+ bool m_initialized;
+ };
+
+private:
+ PluginLayerChromium(GraphicsLayerChromium* owner);
+ unsigned m_textureId;
+};
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 46c73a1..fa6c2c8 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -33,6 +33,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "VideoLayerChromium.h"
+#include "Extensions3DChromium.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include "RenderLayerBacking.h"
@@ -302,10 +303,10 @@ void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text
{
ASSERT(context);
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
- void* mem = context->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, GraphicsContext3D::WRITE_ONLY);
+ void* mem = static_cast<Extensions3DChromium*>(context->getExtensions())->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, Extensions3DChromium::WRITE_ONLY);
if (mem) {
memcpy(mem, data, dimensions.width() * dimensions.height());
- GLC(context, context->unmapTexSubImage2DCHROMIUM(mem));
+ GLC(context, static_cast<Extensions3DChromium*>(context->getExtensions())->unmapTexSubImage2DCHROMIUM(mem));
} else {
// FIXME: We should have some sort of code to handle the case when
// mapTexSubImage2D fails.
diff --git a/WebCore/platform/graphics/filters/FELighting.cpp b/WebCore/platform/graphics/filters/FELighting.cpp
index e1df580..803b9c1 100644
--- a/WebCore/platform/graphics/filters/FELighting.cpp
+++ b/WebCore/platform/graphics/filters/FELighting.cpp
@@ -54,85 +54,182 @@ FELighting::FELighting(LightingType lightingType, const Color& lightingColor, fl
const static int cPixelSize = 4;
const static int cAlphaChannelOffset = 3;
const static unsigned char cOpaqueAlpha = static_cast<unsigned char>(0xff);
+const static float cFactor1div2 = -1 / 2.f;
+const static float cFactor1div3 = -1 / 3.f;
+const static float cFactor1div4 = -1 / 4.f;
+const static float cFactor2div3 = -2 / 3.f;
-ALWAYS_INLINE int FELighting::LightingData::upLeftPixelValue()
+// << 1 is signed multiply by 2
+inline void FELighting::LightingData::topLeft(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize;
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-(center << 1) + (right << 1) - bottom + bottomRight);
+ normalVector.setY(-(center << 1) - right + (bottom << 1) + bottomRight);
}
-ALWAYS_INLINE int FELighting::LightingData::upPixelValue()
+inline void FELighting::LightingData::topRow(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize + cAlphaChannelOffset));
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize;
+ int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-(left << 1) + (right << 1) - bottomLeft + bottomRight);
+ normalVector.setY(-left - (center << 1) - right + bottomLeft + (bottom << 1) + bottomRight);
}
-ALWAYS_INLINE int FELighting::LightingData::upRightPixelValue()
+inline void FELighting::LightingData::topRight(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize + cPixelSize + cAlphaChannelOffset));
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize;
+ int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ normalVector.setX(-(left << 1) + (center << 1) - bottomLeft + bottom);
+ normalVector.setY(-left - (center << 1) + bottomLeft + (bottom << 1));
}
-ALWAYS_INLINE int FELighting::LightingData::leftPixelValue()
+inline void FELighting::LightingData::leftColumn(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize << 1;
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-top + topRight - (center << 1) + (right << 1) - bottom + bottomRight);
+ normalVector.setY(-(top << 1) - topRight + (bottom << 1) + bottomRight);
}
-ALWAYS_INLINE int FELighting::LightingData::centerPixelValue()
+inline void FELighting::LightingData::interior(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize << 1;
+ int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-topLeft + topRight - (left << 1) + (right << 1) - bottomLeft + bottomRight);
+ normalVector.setY(-topLeft - (top << 1) - topRight + bottomLeft + (bottom << 1) + bottomRight);
}
-ALWAYS_INLINE int FELighting::LightingData::rightPixelValue()
+inline void FELighting::LightingData::rightColumn(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize << 1;
+ int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ normalVector.setX(-topLeft + top - (left << 1) + (center << 1) - bottomLeft + bottom);
+ normalVector.setY(-topLeft - (top << 1) + bottomLeft + (bottom << 1));
}
-ALWAYS_INLINE int FELighting::LightingData::downLeftPixelValue()
+inline void FELighting::LightingData::bottomLeft(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-top + topRight - (center << 1) + (right << 1));
+ normalVector.setY(-(top << 1) - topRight + (center << 1) + right);
}
-ALWAYS_INLINE int FELighting::LightingData::downPixelValue()
+inline void FELighting::LightingData::bottomRow(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize + cAlphaChannelOffset));
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-topLeft + topRight - (left << 1) + (right << 1));
+ normalVector.setY(-topLeft - (top << 1) - topRight + left + (center << 1) + right);
}
-ALWAYS_INLINE int FELighting::LightingData::downRightPixelValue()
+inline void FELighting::LightingData::bottomRight(int offset, IntPoint& normalVector)
{
- return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize + cPixelSize + cAlphaChannelOffset));
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ normalVector.setX(-topLeft + top - (left << 1) + (center << 1));
+ normalVector.setY(-topLeft - (top << 1) + left + (center << 1));
}
-ALWAYS_INLINE void FELighting::setPixel(LightingData& data, LightSource::PaintingData& paintingData,
- int lightX, int lightY, float factorX, int normalX, float factorY, int normalY)
+inline void FELighting::inlineSetPixel(int offset, LightingData& data, LightSource::PaintingData& paintingData,
+ int lightX, int lightY, float factorX, float factorY, IntPoint& normal2DVector)
{
- m_lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->get(data.offset + 3)) * data.surfaceScale);
-
- data.normalVector.setX(factorX * static_cast<float>(normalX) * data.surfaceScale);
- data.normalVector.setY(factorY * static_cast<float>(normalY) * data.surfaceScale);
- data.normalVector.setZ(1.0f);
- data.normalVector.normalize();
-
- if (m_lightingType == FELighting::DiffuseLighting)
- data.lightStrength = m_diffuseConstant * (data.normalVector * paintingData.lightVector);
- else {
- FloatPoint3D halfwayVector = paintingData.lightVector;
- halfwayVector.setZ(halfwayVector.z() + 1.0f);
- halfwayVector.normalize();
- if (m_specularExponent == 1.0f)
- data.lightStrength = m_specularConstant * (data.normalVector * halfwayVector);
- else
- data.lightStrength = m_specularConstant * powf(data.normalVector * halfwayVector, m_specularExponent);
+ m_lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->get(offset + cAlphaChannelOffset)) * data.surfaceScale);
+
+ float lightStrength;
+ if (!normal2DVector.x() && !normal2DVector.y()) {
+ // Normal vector is (0, 0, 1). This is a quite frequent case.
+ if (m_lightingType == FELighting::DiffuseLighting)
+ lightStrength = m_diffuseConstant * paintingData.lightVector.z() / paintingData.lightVectorLength;
+ else {
+ FloatPoint3D halfwayVector = paintingData.lightVector;
+ halfwayVector.setZ(halfwayVector.z() + paintingData.lightVectorLength);
+ float halfwayVectorLength = halfwayVector.length();
+ if (m_specularExponent == 1)
+ lightStrength = m_specularConstant * halfwayVector.z() / halfwayVectorLength;
+ else
+ lightStrength = m_specularConstant * powf(halfwayVector.z() / halfwayVectorLength, m_specularExponent);
+ }
+ } else {
+ FloatPoint3D normalVector;
+ normalVector.setX(factorX * static_cast<float>(normal2DVector.x()) * data.surfaceScale);
+ normalVector.setY(factorY * static_cast<float>(normal2DVector.y()) * data.surfaceScale);
+ normalVector.setZ(1);
+ float normalVectorLength = normalVector.length();
+
+ if (m_lightingType == FELighting::DiffuseLighting)
+ lightStrength = m_diffuseConstant * (normalVector * paintingData.lightVector) / (normalVectorLength * paintingData.lightVectorLength);
+ else {
+ FloatPoint3D halfwayVector = paintingData.lightVector;
+ halfwayVector.setZ(halfwayVector.z() + paintingData.lightVectorLength);
+ float halfwayVectorLength = halfwayVector.length();
+ if (m_specularExponent == 1)
+ lightStrength = m_specularConstant * (normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength);
+ else
+ lightStrength = m_specularConstant * powf((normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength), m_specularExponent);
+ }
}
- if (data.lightStrength > 1.0f)
- data.lightStrength = 1.0f;
- if (data.lightStrength < 0.0f)
- data.lightStrength = 0.0f;
+ if (lightStrength > 1)
+ lightStrength = 1;
+ if (lightStrength < 0)
+ lightStrength = 0;
- data.pixels->set(data.offset, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.x()));
- data.pixels->set(data.offset + 1, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.y()));
- data.pixels->set(data.offset + 2, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.z()));
+ data.pixels->set(offset, static_cast<unsigned char>(lightStrength * paintingData.colorVector.x()));
+ data.pixels->set(offset + 1, static_cast<unsigned char>(lightStrength * paintingData.colorVector.y()));
+ data.pixels->set(offset + 2, static_cast<unsigned char>(lightStrength * paintingData.colorVector.z()));
+}
+
+void FELighting::setPixel(int offset, LightingData& data, LightSource::PaintingData& paintingData,
+ int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector)
+{
+ inlineSetPixel(offset, data, paintingData, lightX, lightY, factorX, factorY, normalVector);
}
-bool FELighting::drawLighting(CanvasPixelArray* pixels, int width, int height)
+bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
{
LightSource::PaintingData paintingData;
LightingData data;
@@ -154,81 +251,73 @@ bool FELighting::drawLighting(CanvasPixelArray* pixels, int width, int height)
m_lightSource->initPaintingData(paintingData);
// Top/Left corner
- data.offset = 0;
- setPixel(data, paintingData, 0, 0,
- -2.0f / 3.0f, -2 * data.centerPixelValue() + 2 * data.rightPixelValue() - data.downPixelValue() + data.downRightPixelValue(),
- -2.0f / 3.0f, -2 * data.centerPixelValue() - data.rightPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ IntPoint normalVector;
+ int offset = 0;
+ data.topLeft(offset, normalVector);
+ setPixel(offset, data, paintingData, 0, 0, cFactor2div3, cFactor2div3, normalVector);
// Top/Right pixel
- data.offset = data.widthMultipliedByPixelSize - cPixelSize;
- setPixel(data, paintingData, data.widthDecreasedByOne, 0,
- -2.0f / 3.0f, -2 * data.leftPixelValue() + 2 * data.centerPixelValue() - data.downLeftPixelValue() + data.downPixelValue(),
- -2.0f / 3.0f, -data.leftPixelValue() - 2 * data.centerPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue());
+ offset = data.widthMultipliedByPixelSize - cPixelSize;
+ data.topRight(offset, normalVector);
+ setPixel(offset, data, paintingData, data.widthDecreasedByOne, 0, cFactor2div3, cFactor2div3, normalVector);
// Bottom/Left pixel
- data.offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize;
- setPixel(data, paintingData, 0, data.heightDecreasedByOne,
- -2.0f / 3.0f, -data.upPixelValue() + data.upRightPixelValue() - 2 * data.centerPixelValue() + 2 * data.rightPixelValue(),
- -2.0f / 3.0f, -2 * data.upPixelValue() - data.upRightPixelValue() + 2 * data.centerPixelValue() + data.rightPixelValue());
+ offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize;
+ data.bottomLeft(offset, normalVector);
+ setPixel(offset, data, paintingData, 0, data.heightDecreasedByOne, cFactor2div3, cFactor2div3, normalVector);
// Bottom/Right pixel
- data.offset = height * data.widthMultipliedByPixelSize - cPixelSize;
- setPixel(data, paintingData, data.widthDecreasedByOne, data.heightDecreasedByOne,
- -2.0f / 3.0f, -data.upLeftPixelValue() + data.upPixelValue() - 2 * data.leftPixelValue() + 2 * data.centerPixelValue(),
- -2.0f / 3.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() + data.leftPixelValue() + 2 * data.centerPixelValue());
+ offset = height * data.widthMultipliedByPixelSize - cPixelSize;
+ data.bottomRight(offset, normalVector);
+ setPixel(offset, data, paintingData, data.widthDecreasedByOne, data.heightDecreasedByOne, cFactor2div3, cFactor2div3, normalVector);
if (width >= 3) {
- // Top line
- data.offset = cPixelSize;
- for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
- setPixel(data, paintingData, x, 0,
- -1.0f / 3.0f, -2 * data.leftPixelValue() + 2 * data.rightPixelValue() - data.downLeftPixelValue() + data.downRightPixelValue(),
- -1.0f / 2.0f, -data.leftPixelValue() - 2 * data.centerPixelValue() - data.rightPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ // Top row
+ offset = cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
+ data.topRow(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, x, 0, cFactor1div3, cFactor1div2, normalVector);
}
- // Bottom line
- data.offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize + cPixelSize;
- for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
- setPixel(data, paintingData, x, data.heightDecreasedByOne,
- -1.0f / 3.0f, -data.upLeftPixelValue() + data.upRightPixelValue() - 2 * data.leftPixelValue() + 2 * data.rightPixelValue(),
- -1.0f / 2.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() - data.upRightPixelValue() + data.leftPixelValue() + 2 * data.centerPixelValue() + data.rightPixelValue());
+ // Bottom row
+ offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize + cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
+ data.bottomRow(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, x, data.heightDecreasedByOne, cFactor1div3, cFactor1div2, normalVector);
}
}
if (height >= 3) {
- // Left line
- data.offset = data.widthMultipliedByPixelSize;
- for (int y = 1; y < data.heightDecreasedByOne; ++y, data.offset += data.widthMultipliedByPixelSize) {
- setPixel(data, paintingData, 0, y,
- -1.0f / 2.0f, -data.upPixelValue() + data.upRightPixelValue() - 2 * data.centerPixelValue() + 2 * data.rightPixelValue() - data.downPixelValue() + data.downRightPixelValue(),
- -1.0f / 3.0f, -2 * data.upPixelValue() - data.upRightPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ // Left column
+ offset = data.widthMultipliedByPixelSize;
+ for (int y = 1; y < data.heightDecreasedByOne; ++y, offset += data.widthMultipliedByPixelSize) {
+ data.leftColumn(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, 0, y, cFactor1div2, cFactor1div3, normalVector);
}
- // Right line
- data.offset = data.widthMultipliedByPixelSize + data.widthMultipliedByPixelSize - cPixelSize;
- for (int y = 1; y < data.heightDecreasedByOne; ++y, data.offset += data.widthMultipliedByPixelSize) {
- setPixel(data, paintingData, data.widthDecreasedByOne, y,
- -1.0f / 2.0f, -data.upLeftPixelValue() + data.upPixelValue() -2 * data.leftPixelValue() + 2 * data.centerPixelValue() - data.downLeftPixelValue() + data.downPixelValue(),
- -1.0f / 3.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue());
+ // Right column
+ offset = (data.widthMultipliedByPixelSize << 1) - cPixelSize;
+ for (int y = 1; y < data.heightDecreasedByOne; ++y, offset += data.widthMultipliedByPixelSize) {
+ data.rightColumn(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, data.widthDecreasedByOne, y, cFactor1div2, cFactor1div3, normalVector);
}
}
if (width >= 3 && height >= 3) {
// Interior pixels
for (int y = 1; y < data.heightDecreasedByOne; ++y) {
- data.offset = y * data.widthMultipliedByPixelSize + cPixelSize;
- for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
- setPixel(data, paintingData, x, y,
- -1.0f / 4.0f, -data.upLeftPixelValue() + data.upRightPixelValue() - 2 * data.leftPixelValue() + 2 * data.rightPixelValue() - data.downLeftPixelValue() + data.downRightPixelValue(),
- -1.0f / 4.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() - data.upRightPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ offset = y * data.widthMultipliedByPixelSize + cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
+ data.interior(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, normalVector);
}
}
}
- int totalSize = data.widthMultipliedByPixelSize * height;
+ int lastPixel = data.widthMultipliedByPixelSize * height;
if (m_lightingType == DiffuseLighting) {
- for (int i = 3; i < totalSize; i += 4)
+ for (int i = cAlphaChannelOffset; i < lastPixel; i += cPixelSize)
data.pixels->set(i, cOpaqueAlpha);
} else {
- for (int i = 0; i < totalSize; i += 4) {
+ for (int i = 0; i < lastPixel; i += cPixelSize) {
unsigned char a1 = data.pixels->get(i);
unsigned char a2 = data.pixels->get(i + 1);
unsigned char a3 = data.pixels->get(i + 2);
@@ -253,8 +342,8 @@ void FELighting::apply(Filter* filter)
setIsAlphaImage(false);
IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
- RefPtr<ImageData> srcImageData(in->resultImage()->getUnmultipliedImageData(effectDrawingRect));
- CanvasPixelArray* srcPixelArray(srcImageData->data());
+ RefPtr<ImageData> srcImageData = in->resultImage()->getUnmultipliedImageData(effectDrawingRect);
+ ByteArray* srcPixelArray = srcImageData->data()->data();
// FIXME: support kernelUnitLengths other than (1,1). The issue here is that the W3
// standard has no test case for them, and other browsers (like Firefox) has strange
diff --git a/WebCore/platform/graphics/filters/FELighting.h b/WebCore/platform/graphics/filters/FELighting.h
index bd56cee..c0f62ab 100644
--- a/WebCore/platform/graphics/filters/FELighting.h
+++ b/WebCore/platform/graphics/filters/FELighting.h
@@ -32,14 +32,12 @@
#include "Filter.h"
#include "FilterEffect.h"
#include "LightSource.h"
-#include <wtf/AlwaysInline.h>
+#include <wtf/ByteArray.h>
// Common base class for FEDiffuseLighting and FESpecularLighting
namespace WebCore {
-class CanvasPixelArray;
-
class FELighting : public FilterEffect {
public:
virtual void apply(Filter*);
@@ -53,31 +51,33 @@ protected:
};
struct LightingData {
- FloatPoint3D normalVector;
- CanvasPixelArray* pixels;
- float lightStrength;
+ // This structure contains only read-only (SMP safe) data
+ ByteArray* pixels;
float surfaceScale;
- int offset;
int widthMultipliedByPixelSize;
int widthDecreasedByOne;
int heightDecreasedByOne;
- ALWAYS_INLINE int upLeftPixelValue();
- ALWAYS_INLINE int upPixelValue();
- ALWAYS_INLINE int upRightPixelValue();
- ALWAYS_INLINE int leftPixelValue();
- ALWAYS_INLINE int centerPixelValue();
- ALWAYS_INLINE int rightPixelValue();
- ALWAYS_INLINE int downLeftPixelValue();
- ALWAYS_INLINE int downPixelValue();
- ALWAYS_INLINE int downRightPixelValue();
+ inline void topLeft(int offset, IntPoint& normalVector);
+ inline void topRow(int offset, IntPoint& normalVector);
+ inline void topRight(int offset, IntPoint& normalVector);
+ inline void leftColumn(int offset, IntPoint& normalVector);
+ inline void interior(int offset, IntPoint& normalVector);
+ inline void rightColumn(int offset, IntPoint& normalVector);
+ inline void bottomLeft(int offset, IntPoint& normalVector);
+ inline void bottomRow(int offset, IntPoint& normalVector);
+ inline void bottomRight(int offset, IntPoint& normalVector);
};
FELighting(LightingType, const Color&, float, float, float, float, float, float, PassRefPtr<LightSource>);
- bool drawLighting(CanvasPixelArray*, int, int);
- ALWAYS_INLINE void setPixel(LightingData&, LightSource::PaintingData&,
- int lightX, int lightY, float factorX, int normalX, float factorY, int normalY);
+ bool drawLighting(ByteArray*, int, int);
+ inline void inlineSetPixel(int offset, LightingData&, LightSource::PaintingData&,
+ int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector);
+
+ // Not worth to inline every occurence of setPixel.
+ void setPixel(int offset, LightingData&, LightSource::PaintingData&,
+ int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector);
LightingType m_lightingType;
RefPtr<LightSource> m_lightSource;
diff --git a/WebCore/platform/graphics/filters/LightSource.cpp b/WebCore/platform/graphics/filters/LightSource.cpp
index a80b14b..de0691e 100644
--- a/WebCore/platform/graphics/filters/LightSource.cpp
+++ b/WebCore/platform/graphics/filters/LightSource.cpp
@@ -42,7 +42,7 @@ void PointLightSource::updatePaintingData(PaintingData& paintingData, int x, int
paintingData.lightVector.setX(m_position.x() - x);
paintingData.lightVector.setY(m_position.y() - y);
paintingData.lightVector.setZ(m_position.z() - z);
- paintingData.lightVector.normalize();
+ paintingData.lightVectorLength = paintingData.lightVector.length();
}
// spot-light edge darkening depends on an absolute treshold
@@ -84,9 +84,9 @@ void SpotLightSource::updatePaintingData(PaintingData& paintingData, int x, int
paintingData.lightVector.setX(m_position.x() - x);
paintingData.lightVector.setY(m_position.y() - y);
paintingData.lightVector.setZ(m_position.z() - z);
- paintingData.lightVector.normalize();
+ paintingData.lightVectorLength = paintingData.lightVector.length();
- float cosineOfAngle = paintingData.lightVector * paintingData.directionVector;
+ float cosineOfAngle = (paintingData.lightVector * paintingData.directionVector) / paintingData.lightVectorLength;
if (cosineOfAngle > paintingData.coneCutOffLimit) {
// No light is produced, scanlines are not updated
paintingData.colorVector.setX(0.0f);
@@ -127,6 +127,7 @@ void DistantLightSource::initPaintingData(PaintingData& paintingData)
paintingData.lightVector.setX(cosf(azimuth) * cosf(elevation));
paintingData.lightVector.setY(sinf(azimuth) * cosf(elevation));
paintingData.lightVector.setZ(sinf(elevation));
+ paintingData.lightVectorLength = 1;
}
void DistantLightSource::updatePaintingData(PaintingData&, int, int, float)
diff --git a/WebCore/platform/graphics/filters/LightSource.h b/WebCore/platform/graphics/filters/LightSource.h
index 2e4c579..013e910 100644
--- a/WebCore/platform/graphics/filters/LightSource.h
+++ b/WebCore/platform/graphics/filters/LightSource.h
@@ -51,6 +51,7 @@ public:
// SVGFELighting also use them
FloatPoint3D lightVector;
FloatPoint3D colorVector;
+ float lightVectorLength;
// Private members
FloatPoint3D directionVector;
FloatPoint3D privateColorVector;
diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
index 87a0b69..a230384 100644
--- a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
+++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
@@ -36,6 +36,7 @@
#include "AffineTransform.h"
#include "Color.h"
+#include "Extensions3D.h"
#include "FloatRect.h"
#include "GraphicsContext3D.h"
#include "GraphicsTypes.h"
@@ -52,6 +53,7 @@ namespace WebCore {
PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow* hostWindow)
{
GraphicsContext3D::Attributes attr;
+ attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts.
RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow);
if (!context)
return 0;
@@ -178,18 +180,8 @@ void SharedGraphicsContext3D::readPixels(long x, long y, unsigned long width, un
bool SharedGraphicsContext3D::supportsBGRA()
{
- return m_context->supportsBGRA();
-}
-
-bool SharedGraphicsContext3D::supportsCopyTextureToParentTextureCHROMIUM()
-
-{
- return m_context->supportsCopyTextureToParentTextureCHROMIUM();
-}
-
-void SharedGraphicsContext3D::copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture)
-{
- return m_context->copyTextureToParentTextureCHROMIUM(texture, parentTexture);
+ return m_context->getExtensions()->supports("GL_EXT_texture_format_BGRA8888")
+ && m_context->getExtensions()->supports("GL_EXT_read_format_bgra");
}
Texture* SharedGraphicsContext3D::createTexture(NativeImagePtr ptr, Texture::Format format, int width, int height)
diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
index 05008c2..86c64b4 100644
--- a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
+++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
@@ -100,10 +100,6 @@ public:
bool supportsBGRA();
- // GL_CHROMIUM_copy_texture_to_parent_texture
- bool supportsCopyTextureToParentTextureCHROMIUM();
- void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture);
-
// Creates a texture associated with the given image. Is owned by this context's
// TextureHashMap.
Texture* createTexture(NativeImagePtr, Texture::Format, int width, int height);
diff --git a/WebCore/platform/graphics/gpu/Texture.cpp b/WebCore/platform/graphics/gpu/Texture.cpp
index 74807dc..18c9ead 100644
--- a/WebCore/platform/graphics/gpu/Texture.cpp
+++ b/WebCore/platform/graphics/gpu/Texture.cpp
@@ -34,6 +34,7 @@
#include "Texture.h"
+#include "Extensions3D.h"
#include "FloatRect.h"
#include "GraphicsContext3D.h"
#include "IntRect.h"
@@ -69,8 +70,8 @@ static void convertFormat(GraphicsContext3D* context, Texture::Format format, un
*glType = GraphicsContext3D::UNSIGNED_BYTE;
break;
case Texture::BGRA8:
- if (context->supportsBGRA()) {
- *glFormat = GraphicsContext3D::BGRA_EXT;
+ if (context->getExtensions()->supports("GL_EXT_texture_format_BGRA8888")) {
+ *glFormat = Extensions3D::BGRA_EXT;
*glType = GraphicsContext3D::UNSIGNED_BYTE;
} else {
*glFormat = GraphicsContext3D::RGBA;
diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
index 252abd7..6911b31 100644
--- a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
@@ -416,12 +416,6 @@ void GraphicsContext::translate(float x, float y)
notImplemented();
}
-IntPoint GraphicsContext::origin()
-{
- notImplemented();
- return IntPoint(0, 0);
-}
-
void GraphicsContext::rotate(float radians)
{
if (paintingDisabled())
@@ -446,14 +440,6 @@ void GraphicsContext::clipOut(const IntRect& rect)
notImplemented();
}
-void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
-{
- if (paintingDisabled())
- return;
-
- notImplemented();
-}
-
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
{
if (paintingDisabled())
@@ -482,6 +468,12 @@ void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
{
}
+InterpolationQuality GraphicsContext::imageInterpolationQuality() const
+{
+ notImplemented();
+ return InterpolationDefault;
+}
+
void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
{
notImplemented();
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index 78d004a..ab6993f 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -36,6 +36,7 @@
#include "ArrayBufferView.h"
#include "CanvasRenderingContext.h"
#include <CoreGraphics/CGBitmapContext.h>
+#include "Extensions3DOpenGL.h"
#include "Float32Array.h"
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
index aa754f2..15cae20 100644
--- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
@@ -147,6 +147,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width,
break;
}
#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+ // To support correction panel.
case TextCheckingReplacementLineStyle:
{
// Constants for spelling pattern color.
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 3895a00..876bc16 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -173,6 +173,8 @@ private:
bool isReadyForVideoSetup() const;
+ virtual float mediaTimeForTimeValue(float) const;
+
MediaPlayer* m_player;
RetainPtr<QTMovie> m_qtMovie;
RetainPtr<QTMovieView> m_qtMovieView;
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index 7b0e7af..06c7924 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -1540,6 +1540,15 @@ void MediaPlayerPrivate::setPreload(MediaPlayer::Preload preload)
resumeLoad();
}
+float MediaPlayerPrivate::mediaTimeForTimeValue(float timeValue) const
+{
+ if (!metaDataAvailable())
+ return timeValue;
+
+ QTTime qttime = createQTTime(timeValue);
+ return static_cast<float>(qttime.timeValue) / qttime.timeScale;
+}
+
} // namespace WebCore
@implementation WebCoreMovieObserver
diff --git a/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
new file mode 100644
index 0000000..8c62e9d
--- /dev/null
+++ b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS)
+
+#include "Extensions3DOpenGL.h"
+
+#include "GraphicsContext3D.h"
+#include <wtf/Vector.h>
+
+#if PLATFORM(MAC)
+#include <OpenGL/gl.h>
+#endif
+
+namespace WebCore {
+
+Extensions3DOpenGL::Extensions3DOpenGL()
+ : m_initializedAvailableExtensions(false)
+{
+}
+
+Extensions3DOpenGL::~Extensions3DOpenGL()
+{
+}
+
+bool Extensions3DOpenGL::supports(const String& name)
+{
+ // Note on support for BGRA:
+ //
+ // For OpenGL ES2.0, requires checking for
+ // GL_EXT_texture_format_BGRA8888 and GL_EXT_read_format_bgra.
+ // For desktop GL, BGRA has been supported since OpenGL 1.2.
+ //
+ // However, note that the GL ES2 extension requires the
+ // internalFormat to glTexImage2D() be GL_BGRA, while desktop GL
+ // will not accept GL_BGRA (must be GL_RGBA), so this must be
+ // checked on each platform. Desktop GL offers neither
+ // GL_EXT_texture_format_BGRA8888 or GL_EXT_read_format_bgra, so
+ // treat them as unsupported here.
+ if (!m_initializedAvailableExtensions) {
+ String extensionsString(reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS)));
+ Vector<String> availableExtensions;
+ extensionsString.split(" ", availableExtensions);
+ for (size_t i = 0; i < availableExtensions.size(); ++i)
+ m_availableExtensions.add(availableExtensions[i]);
+ m_initializedAvailableExtensions = true;
+ }
+ return m_availableExtensions.contains(name);
+}
+
+int Extensions3DOpenGL::getGraphicsResetStatusARB()
+{
+ return GraphicsContext3D::NO_ERROR;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
new file mode 100644
index 0000000..1b333b2
--- /dev/null
+++ b/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Extensions3DOpenGL_h
+#define Extensions3DOpenGL_h
+
+#include "Extensions3D.h"
+
+#include "GraphicsContext3D.h"
+#include <wtf/HashSet.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class Extensions3DOpenGL : public Extensions3D {
+public:
+ virtual ~Extensions3DOpenGL();
+
+ // Extensions3D methods.
+ virtual bool supports(const String&);
+ virtual int getGraphicsResetStatusARB();
+
+private:
+ // This class only needs to be instantiated by GraphicsContext3D implementations.
+ friend class GraphicsContext3D;
+ Extensions3DOpenGL();
+
+ bool m_initializedAvailableExtensions;
+ HashSet<String> m_availableExtensions;
+};
+
+} // namespace WebCore
+
+#endif // Extensions3DOpenGL_h
diff --git a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index daf3b12..85089a0 100644
--- a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -33,6 +33,7 @@
#include "ArrayBufferView.h"
#include "WebGLObject.h"
#include "CanvasRenderingContext.h"
+#include "Extensions3DOpenGL.h"
#include "Float32Array.h"
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
@@ -568,12 +569,7 @@ void GraphicsContext3D::flush()
void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, Platform3DObject buffer)
{
makeContextCurrent();
- GLuint renderbuffer = (GLuint) buffer;
- if (attachment == DEPTH_STENCIL_ATTACHMENT) {
- ::glFramebufferRenderbufferEXT(target, DEPTH_ATTACHMENT, renderbuffertarget, renderbuffer);
- ::glFramebufferRenderbufferEXT(target, STENCIL_ATTACHMENT, renderbuffertarget, renderbuffer);
- } else
- ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer);
+ ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, (GLuint) buffer);
}
void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, Platform3DObject texture, long level)
@@ -1116,21 +1112,12 @@ void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target
void GraphicsContext3D::getIntegerv(unsigned long pname, int* value)
{
- // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid
- // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most
- // useful for desktop WebGL users.
// Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS
// because desktop GL's corresponding queries return the number of components
// whereas GLES2 return the number of vectors (each vector has 4 components).
// Therefore, the value returned by desktop GL needs to be divided by 4.
makeContextCurrent();
switch (pname) {
- case IMPLEMENTATION_COLOR_READ_FORMAT:
- *value = GL_RGB;
- break;
- case IMPLEMENTATION_COLOR_READ_TYPE:
- *value = GL_UNSIGNED_BYTE;
- break;
case MAX_FRAGMENT_UNIFORM_VECTORS:
::glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value);
*value /= 4;
@@ -1445,9 +1432,11 @@ void GraphicsContext3D::synthesizeGLError(unsigned long error)
m_syntheticErrors.add(error);
}
-int GraphicsContext3D::getGraphicsResetStatusARB()
+Extensions3D* GraphicsContext3D::getExtensions()
{
- return NO_ERROR;
+ if (!m_extensions)
+ m_extensions = adoptPtr(new Extensions3DOpenGL);
+ return m_extensions.get();
}
}
diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
index 6527ce4..03f9b7c 100644
--- a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
+++ b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
@@ -30,8 +30,12 @@
#if defined(TEXMAP_OPENGL_ES_2)
#include <GLES2/gl2.h>
#elif OS(MAC_OS_X)
+#include <AGL/agl.h>
#include <gl.h>
#else
+#if OS(UNIX)
+#include <GL/glx.h>
+#endif
#include <GL/gl.h>
#endif
@@ -90,6 +94,132 @@ inline static void debugGLCommand(const char* command, int line)
#define GL_CMD(x) x
#endif
+static const GLuint gInVertexAttributeIndex = 0;
+
+struct TextureMapperGLData {
+ static struct ShaderInfo {
+ enum ShaderProgramIndex {
+ SimpleProgram,
+ OpacityAndMaskProgram,
+ TargetProgram,
+
+ ProgramCount
+ };
+
+ enum ShaderVariableIndex {
+ InMatrixVariable,
+ InSourceMatrixVariable,
+ InMaskMatrixVariable,
+ OpacityVariable,
+ SourceTextureVariable,
+ MaskTextureVariable,
+
+ VariableCount
+ };
+
+ struct ProgramInfo {
+ GLuint id;
+ GLint vars[VariableCount];
+ };
+
+ GLint getUniformLocation(ShaderProgramIndex prog, ShaderVariableIndex var, const char* name)
+ {
+ return programs[prog].vars[var] = glGetUniformLocation(programs[prog].id, name);
+ }
+
+ void createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource, ShaderProgramIndex index)
+ {
+ GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
+ GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ GL_CMD(glShaderSource(vertexShader, 1, &vertexShaderSource, 0))
+ GL_CMD(glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0))
+ GLuint programID = glCreateProgram();
+ GL_CMD(glCompileShader(vertexShader))
+ GL_CMD(glCompileShader(fragmentShader))
+ GL_CMD(glAttachShader(programID, vertexShader))
+ GL_CMD(glAttachShader(programID, fragmentShader))
+ GL_CMD(glBindAttribLocation(programID, gInVertexAttributeIndex, "InVertex"))
+ GL_CMD(glLinkProgram(programID))
+ programs[index].id = programID;
+#ifdef PRINT_PROGRAM_INFO_LOG
+ char infoLog[1024];
+ int len;
+ GL_CMD(glGetProgramInfoLog(programID, 1024, &len, infoLog));
+ LOG(Graphics, "Compiled program for texture mapper. Log: %s\n", infoLog);
+#endif
+ }
+
+ ProgramInfo programs[ProgramCount];
+
+ } shaderInfo;
+
+ struct DirectlyCompositedImageRepository {
+ struct Entry {
+ GLuint texture;
+ int refCount;
+ };
+ HashMap<NativeImagePtr, Entry> imageToTexture;
+
+ GLuint findOrCreate(NativeImagePtr image, bool& found)
+ {
+ HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image);
+ found = false;
+ if (it != imageToTexture.end()) {
+ it->second.refCount++;
+ found = true;
+ return it->second.texture;
+ }
+ Entry entry;
+ GL_CMD(glGenTextures(1, &entry.texture));
+ entry.refCount = 1;
+ imageToTexture.add(image, entry);
+ return entry.texture;
+ }
+
+ bool deref(NativeImagePtr image)
+ {
+ HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image);
+ if (it != imageToTexture.end()) {
+ if (it->second.refCount < 2) {
+ imageToTexture.remove(it);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ DirectlyCompositedImageRepository()
+ {
+ }
+
+ ~DirectlyCompositedImageRepository()
+ {
+ for (HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.begin(); it != imageToTexture.end(); ++it) {
+ GLuint texture = it->second.texture;
+ if (texture)
+ GL_CMD(glDeleteTextures(1, &texture));
+ }
+
+ }
+ } directlyCompositedImages;
+
+ TextureMapperGLData()
+ : currentProgram(TextureMapperGLData::ShaderInfo::TargetProgram)
+ { }
+
+ TransformationMatrix projectionMatrix;
+ int currentProgram;
+
+#if OS(MAC_OS_X)
+ AGLContext aglContext;
+#elif OS(UNIX)
+ Drawable glxDrawable;
+ GLXContext glxContext;
+#endif
+};
+
+TextureMapperGLData::ShaderInfo TextureMapperGLData::shaderInfo;
+
class BitmapTextureGL : public BitmapTexture {
public:
virtual void destroy();
@@ -99,6 +229,7 @@ public:
virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);
virtual void endPaint();
virtual void setContentsToImage(Image*);
+ ~BitmapTextureGL() { destroy(); }
private:
GLuint m_id;
@@ -111,78 +242,32 @@ private:
GLuint m_fbo;
IntSize m_actualSize;
bool m_surfaceNeedsReset;
+ TextureMapperGL* m_textureMapper;
BitmapTextureGL()
: m_id(0)
, m_image(0)
, m_opaque(false)
, m_fbo(0)
, m_surfaceNeedsReset(true)
+ , m_textureMapper(0)
{
}
friend class TextureMapperGL;
};
-static struct TexmapShaderInfo {
- enum ShaderProgramIndex {
- SimpleProgram,
- OpacityAndMaskProgram,
- TargetProgram,
- NumPrograms
- };
-
- enum ShaderVariableIndex {
- InMatrixVariable,
- InSourceMatrixVariable,
- InMaskMatrixVariable,
- InVertexVariable,
-
- OpacityVariable,
- SourceTextureVariable,
- MaskTextureVariable,
- NumVariables
- };
-
- struct ProgramInfo {
- GLuint id;
- GLint vars[NumVariables];
- };
-
- GLint getUniformLocation(ShaderProgramIndex prog, ShaderVariableIndex var, const char* name)
- {
- return programs[prog].vars[var] = glGetUniformLocation(programs[prog].id, name);
- }
-
- void createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource, ShaderProgramIndex index)
- {
- GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
- GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- GL_CMD(glShaderSource(vertexShader, 1, &vertexShaderSource, 0))
- GL_CMD(glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0))
- GLuint programID = glCreateProgram();
- GL_CMD(glCompileShader(vertexShader))
- GL_CMD(glCompileShader(fragmentShader))
- GL_CMD(glAttachShader(programID, vertexShader))
- GL_CMD(glAttachShader(programID, fragmentShader))
- GL_CMD(glBindAttribLocation(programID, 0, "InVertex"))
- GL_CMD(glLinkProgram(programID))
- programs[index].id = programID;
- }
-
- ProgramInfo programs[NumPrograms];
-
-} gShaderInfo;
-
#define TEXMAP_GET_SHADER_VAR_LOCATION(prog, var) \
- if (gShaderInfo.getUniformLocation(TexmapShaderInfo::prog##Program, TexmapShaderInfo::var##Variable, #var) < 0) \
- LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n");
-#define TEXMAP_BUILD_SHADER(program) gShaderInfo.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TexmapShaderInfo::program##Program);
+ if (TextureMapperGLData::shaderInfo.getUniformLocation(TextureMapperGLData::shaderInfo.prog##Program, TextureMapperGLData::shaderInfo.var##Variable, #var) < 0) \
+ LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n");
+
+#define TEXMAP_BUILD_SHADER(program) \
+ TextureMapperGLData::shaderInfo.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TextureMapperGLData::shaderInfo.program##Program);
-TextureMapperGL::TextureMapperGL(GraphicsContext* context)
- : TextureMapper(context)
- , m_currentProgram(TexmapShaderInfo::TargetProgram)
+TextureMapperGL::TextureMapperGL()
+ : m_data(new TextureMapperGLData)
{
static bool shadersCompiled = false;
+ obtainCurrentContext();
if (shadersCompiled)
return;
shadersCompiled = true;
@@ -282,18 +367,18 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture);
- TexmapShaderInfo::ShaderProgramIndex program;
+ TextureMapperGLData::ShaderInfo::ShaderProgramIndex program;
if (maskTexture)
- program = TexmapShaderInfo::OpacityAndMaskProgram;
+ program = TextureMapperGLData::ShaderInfo::OpacityAndMaskProgram;
else
- program = TexmapShaderInfo::SimpleProgram;
+ program = TextureMapperGLData::ShaderInfo::SimpleProgram;
- const TexmapShaderInfo::ProgramInfo& programInfo = gShaderInfo.programs[program];
- if (m_currentProgram != program) {
+ const TextureMapperGLData::ShaderInfo::ProgramInfo& programInfo = data().shaderInfo.programs[program];
+ if (data().currentProgram != program) {
GL_CMD(glUseProgram(programInfo.id))
- GL_CMD(glDisableVertexAttribArray(gShaderInfo.programs[m_currentProgram].vars[TexmapShaderInfo::InVertexVariable]))
- m_currentProgram = program;
- GL_CMD(glEnableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable]))
+ GL_CMD(glDisableVertexAttribArray(gInVertexAttributeIndex))
+ data().currentProgram = program;
+ GL_CMD(glEnableVertexAttribArray(gInVertexAttributeIndex))
}
GL_CMD(glDisable(GL_DEPTH_TEST))
@@ -305,7 +390,7 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
- TransformationMatrix matrix = TransformationMatrix(m_projectionMatrix).multLeft(modelViewMatrix).multLeft(TransformationMatrix(
+ TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multLeft(modelViewMatrix).multLeft(TransformationMatrix(
targetRect.width(), 0, 0, 0,
0, targetRect.height(), 0, 0,
0, 0, 1, 0,
@@ -321,10 +406,10 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
0, textureGL.m_relativeSize.height(), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
- GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMatrixVariable], 1, GL_FALSE, m4))
- GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src))
- GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::SourceTextureVariable], 0))
- GL_CMD(glUniform1f(programInfo.vars[TexmapShaderInfo::OpacityVariable], opacity))
+ GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMatrixVariable], 1, GL_FALSE, m4))
+ GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src))
+ GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::SourceTextureVariable], 0))
+ GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::ShaderInfo::OpacityVariable], opacity))
if (maskTexture && maskTexture->isValid()) {
const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture);
@@ -334,12 +419,11 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
0, maskTextureGL->m_relativeSize.height(), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
- glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask);
- GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::MaskTextureVariable], 1))
+ GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask));
+ GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::MaskTextureVariable], 1))
GL_CMD(glActiveTexture(GL_TEXTURE0))
}
-
if (textureGL.m_opaque && opacity > 0.99 && !maskTexture)
GL_CMD(glDisable(GL_BLEND))
else {
@@ -350,7 +434,6 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4))
}
-
const char* TextureMapperGL::type() const
{
return "OpenGL";
@@ -399,43 +482,6 @@ void BitmapTextureGL::endPaint()
m_buffer.clear();
}
-struct TexmapGLShaderTextures {
- struct Entry {
- GLuint texture;
- int refCount;
- };
- HashMap<NativeImagePtr, Entry> imageToTexture;
- GLuint findOrCreate(NativeImagePtr image, bool& found)
- {
- HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image);
- found = false;
- if (it != imageToTexture.end()) {
- it->second.refCount++;
- found = true;
- return it->second.texture;
- }
- Entry entry;
- GL_CMD(glGenTextures(1, &entry.texture));
- entry.refCount = 1;
- imageToTexture.add(image, entry);
- return entry.texture;
- }
-
- bool deref(NativeImagePtr image)
- {
- HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image);
- if (it != imageToTexture.end()) {
- if (it->second.refCount < 2) {
- imageToTexture.remove(it);
- return false;
- }
- }
- return true;
- }
-};
-
-static TexmapGLShaderTextures gTextureRepository;
-
void BitmapTextureGL::setContentsToImage(Image* image)
{
NativeImagePtr nativeImage = image ? image->nativeImageForCurrentFrame() : 0;
@@ -448,7 +494,7 @@ void BitmapTextureGL::setContentsToImage(Image* image)
if (nativeImage == m_image)
return;
bool found = false;
- GLuint newTextureID = gTextureRepository.findOrCreate(nativeImage, found);
+ GLuint newTextureID = m_textureMapper->data().directlyCompositedImages.findOrCreate(nativeImage, found);
if (newTextureID != m_id) {
destroy();
m_id = newTextureID;
@@ -464,7 +510,7 @@ void BitmapTextureGL::setContentsToImage(Image* image)
void BitmapTextureGL::destroy()
{
- if (m_id && (!m_image || !gTextureRepository.deref(m_image)))
+ if (m_id && (!m_image || !m_textureMapper->data().directlyCompositedImages.deref(m_image)))
GL_CMD(glDeleteTextures(1, &m_id))
if (m_fbo)
GL_CMD(glDeleteFramebuffers(1, &m_fbo))
@@ -493,8 +539,32 @@ static inline TransformationMatrix createProjectionMatrix(const IntSize& size, b
-1, flip ? 1 : -1, 0, 1);
}
-void TextureMapperGL::cleanup()
+TextureMapperGL::~TextureMapperGL()
{
+ makeContextCurrent();
+ delete m_data;
+}
+
+bool TextureMapperGL::makeContextCurrent()
+{
+#if OS(MAC_OS_X)
+ return aglSetCurrentContext(data().aglContext);
+#elif OS(UNIX)
+ Display* display = XOpenDisplay(0);
+ if (!display)
+ return false;
+ return glXMakeCurrent(display, data().glxDrawable, data().glxContext);
+#endif
+}
+
+void TextureMapperGL::obtainCurrentContext()
+{
+#if OS(MAC_OS_X)
+ data().aglContext = aglGetCurrentContext();
+#elif OS(UNIX)
+ data().glxDrawable = glXGetCurrentDrawable();
+ data().glxContext = glXGetCurrentContext();
+#endif
}
void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer)
@@ -503,6 +573,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer)
if (!surface)
return;
+
TransformationMatrix matrix = createProjectionMatrix(surface->size(), false);
matrix.translate(-surface->offset().x(), -surface->offset().y());
@@ -520,7 +591,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer)
}
GL_CMD(glViewport(0, 0, surface->size().width(), surface->size().height()))
- m_projectionMatrix = matrix;
+ data().projectionMatrix = matrix;
}
void TextureMapperGL::setClip(const IntRect& rect)
@@ -540,8 +611,7 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize
surface.m_actualSize.width(), 0, 0, 0,
0, surface.m_actualSize.height(), 0, 0,
0, 0, 1, 0,
- surface.offset().x(), surface.offset().y(), 0, 1
- )
+ surface.offset().x(), surface.offset().y(), 0, 1)
);
const GLfloat m4[] = {
@@ -557,18 +627,18 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize
0, 0, 0, 1};
// We already blended the alpha in; the result is premultiplied.
- GL_CMD(glUseProgram(gShaderInfo.programs[TexmapShaderInfo::TargetProgram].id))
+ GL_CMD(glUseProgram(data().shaderInfo.programs[TextureMapperGLData::ShaderInfo::TargetProgram].id))
GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0))
GL_CMD(glViewport(0, 0, surfaceSize.width(), surfaceSize.height()))
GL_CMD(glDisable(GL_STENCIL_TEST))
- const TexmapShaderInfo::ProgramInfo& programInfo = gShaderInfo.programs[TexmapShaderInfo::TargetProgram];
- GL_CMD(glUniform1f(programInfo.vars[TexmapShaderInfo::OpacityVariable], opacity))
+ const TextureMapperGLData::ShaderInfo::ProgramInfo& programInfo = data().shaderInfo.programs[TextureMapperGLData::ShaderInfo::TargetProgram];
+ GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::ShaderInfo::OpacityVariable], opacity))
GL_CMD(glActiveTexture(GL_TEXTURE0))
GL_CMD(glBindTexture(GL_TEXTURE_2D, surface.m_id))
- GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::SourceTextureVariable], 0))
- GL_CMD(glEnableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable]))
- GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMatrixVariable], 1, GL_FALSE, m4))
- GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src))
+ GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::ShaderInfo::SourceTextureVariable], 0))
+ GL_CMD(glEnableVertexAttribArray(gInVertexAttributeIndex))
+ GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InMatrixVariable], 1, GL_FALSE, m4))
+ GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src))
GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0))
const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
@@ -577,15 +647,17 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize
setClip(visibleRect);
GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4))
- GL_CMD(glDisableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable]))
+ GL_CMD(glDisableVertexAttribArray(0))
GL_CMD(glUseProgram(0))
GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0))
- m_currentProgram = TexmapShaderInfo::TargetProgram;
+ data().currentProgram = TextureMapperGLData::ShaderInfo::TargetProgram;
}
PassRefPtr<BitmapTexture> TextureMapperGL::createTexture()
{
- return adoptRef(new BitmapTextureGL());
+ BitmapTextureGL* texture = new BitmapTextureGL();
+ texture->m_textureMapper = this;
+ return adoptRef(texture);
}
};
diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.h b/WebCore/platform/graphics/opengl/TextureMapperGL.h
index 7a12c72..8035abf 100644
--- a/WebCore/platform/graphics/opengl/TextureMapperGL.h
+++ b/WebCore/platform/graphics/opengl/TextureMapperGL.h
@@ -29,11 +29,13 @@
namespace WebCore {
+class TextureMapperGLData;
+
// An OpenGL-ES2 implementation of TextureMapper.
class TextureMapperGL : public TextureMapper {
public:
- TextureMapperGL(GraphicsContext* gc);
- virtual ~TextureMapperGL() {}
+ TextureMapperGL();
+ virtual ~TextureMapperGL();
// reimps from TextureMapper
virtual void drawTexture(const BitmapTexture& texture, const IntRect&, const TransformationMatrix& transform, float opacity, const BitmapTexture* maskTexture);
@@ -43,11 +45,17 @@ public:
virtual bool allowSurfaceForRoot() const { return true; }
virtual PassRefPtr<BitmapTexture> createTexture();
virtual const char* type() const;
- virtual void cleanup();
+ void obtainCurrentContext();
+ bool makeContextCurrent();
+ static PassOwnPtr<TextureMapperGL> create()
+ {
+ return new TextureMapperGL;
+ }
private:
- TransformationMatrix m_projectionMatrix;
- int m_currentProgram;
+ inline TextureMapperGLData& data() { return *m_data; }
+ TextureMapperGLData* m_data;
+ friend class BitmapTextureGL;
};
// An offscreen buffer to be rendered by software.
diff --git a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
index 37fd8ad..0d16d4d 100644
--- a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
@@ -340,14 +340,6 @@ void GraphicsContext::clearRect(const FloatRect& rect)
m_data->setCompositeOperation(op);
}
-void GraphicsContext::strokeRect(const FloatRect& rect)
-{
- if (paintingDisabled())
- return;
-
- m_data->drawRect(rect, VG_STROKE_PATH);
-}
-
void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
{
if (paintingDisabled())
@@ -452,15 +444,6 @@ void GraphicsContext::translate(float dx, float dy)
m_data->translate(dx, dy);
}
-IntPoint GraphicsContext::origin()
-{
- if (paintingDisabled())
- return IntPoint();
-
- AffineTransform transformation = m_data->transformation();
- return IntPoint(roundf(transformation.e()), roundf(transformation.f()));
-}
-
void GraphicsContext::clipOut(const IntRect& rect)
{
if (paintingDisabled())
@@ -471,16 +454,6 @@ void GraphicsContext::clipOut(const IntRect& rect)
m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule);
}
-void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
-{
- if (paintingDisabled())
- return;
-
- Path path;
- path.addEllipse(rect);
- m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule);
-}
-
void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
{
if (paintingDisabled())
diff --git a/WebCore/platform/graphics/qt/Extensions3DQt.cpp b/WebCore/platform/graphics/qt/Extensions3DQt.cpp
new file mode 100644
index 0000000..6a34671
--- /dev/null
+++ b/WebCore/platform/graphics/qt/Extensions3DQt.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS)
+
+#include "Extensions3DQt.h"
+
+#include "GraphicsContext3D.h"
+
+namespace WebCore {
+
+Extensions3DQt::Extensions3DQt()
+{
+}
+
+Extensions3DQt::~Extensions3DQt()
+{
+}
+
+bool Extensions3DQt::supports(const String&)
+{
+ return false;
+}
+
+int Extensions3DQt::getGraphicsResetStatusARB()
+{
+ return GraphicsContext3D::NO_ERROR;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/platform/graphics/qt/Extensions3DQt.h b/WebCore/platform/graphics/qt/Extensions3DQt.h
new file mode 100644
index 0000000..29209ba
--- /dev/null
+++ b/WebCore/platform/graphics/qt/Extensions3DQt.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Extensions3DQt_h
+#define Extensions3DQt_h
+
+#include "Extensions3D.h"
+
+namespace WebCore {
+
+class Extensions3DQt : public Extensions3D {
+public:
+ virtual ~Extensions3DQt();
+
+ // Extensions3D methods.
+ virtual bool supports(const String&);
+ virtual int getGraphicsResetStatusARB();
+
+private:
+ // This class only needs to be instantiated by GraphicsContext3D implementations.
+ friend class GraphicsContext3D;
+ Extensions3DQt();
+};
+
+} // namespace WebCore
+
+#endif // Extensions3DQt_h
diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index cda8606..26db220 100644
--- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -22,6 +22,7 @@
#include "WebGLObject.h"
#include "CanvasRenderingContext.h"
+#include "Extensions3DQt.h"
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
#include "HostWindow.h"
@@ -253,6 +254,8 @@ public:
QImage m_pixels;
ListHashSet<unsigned long> m_syntheticErrors;
+ OwnPtr<Extensions3DQt> m_extensions;
+
private:
void* getProcAddress(const String& proc);
@@ -1632,6 +1635,13 @@ void GraphicsContext3D::synthesizeGLError(unsigned long error)
m_internal->m_syntheticErrors.add(error);
}
+Extensions3D* GraphicsContext3D::getExtensions()
+{
+ if (!m_internal->m_extensions)
+ m_internal->m_extensions = adoptPtr(new Extensions3DQt);
+ return m_internal->m_extensions;
+}
+
bool GraphicsContext3D::getImageData(Image* image,
unsigned int format,
unsigned int type,
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 50971b5..4f68577 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -504,16 +504,18 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin
for (size_t i = 1; i < numPoints; ++i)
path.lineTo(points[i]);
path.setFillRule(Qt::WindingFill);
- m_data->p()->setClipPath(path, Qt::IntersectClip);
-}
-
-QPen GraphicsContext::pen()
-{
- if (paintingDisabled())
- return QPen();
QPainter* p = m_data->p();
- return p->pen();
+
+ bool painterWasAntialiased = p->testRenderHint(QPainter::Antialiasing);
+
+ if (painterWasAntialiased != antialiased)
+ p->setRenderHint(QPainter::Antialiasing, antialiased);
+
+ p->setClipPath(path, Qt::IntersectClip);
+
+ if (painterWasAntialiased != antialiased)
+ p->setRenderHint(QPainter::Antialiasing, painterWasAntialiased);
}
void GraphicsContext::fillPath()
@@ -733,9 +735,21 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
QPainter* p = m_data->p();
if (m_data->hasShadow()) {
- p->translate(m_data->shadow.offset());
- p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
- p->translate(-m_data->shadow.offset());
+ ContextShadow* shadow = contextShadow();
+
+ if (shadow->m_type != ContextShadow::BlurShadow) {
+ // We do not need any layer for simple shadow.
+ p->translate(m_data->shadow.offset());
+ p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
+ p->translate(-m_data->shadow.offset());
+ } else {
+ QPainter* shadowPainter = shadow->beginShadowLayer(p, rect);
+ if (shadowPainter) {
+ shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
+ shadowPainter->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
+ shadow->endShadowLayer(p);
+ }
+ }
}
p->fillPath(path.platformPath(), QColor(color));
}
@@ -1128,14 +1142,6 @@ void GraphicsContext::translate(float x, float y)
}
}
-IntPoint GraphicsContext::origin()
-{
- if (paintingDisabled())
- return IntPoint();
- const QTransform &transform = m_data->p()->transform();
- return IntPoint(qRound(transform.dx()), qRound(transform.dy()));
-}
-
void GraphicsContext::rotate(float radians)
{
if (paintingDisabled())
@@ -1186,28 +1192,6 @@ void GraphicsContext::clipOut(const IntRect& rect)
}
}
-void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
-{
- if (paintingDisabled())
- return;
-
- QPainter* p = m_data->p();
- QPainterPath newClip;
- newClip.setFillRule(Qt::OddEvenFill);
- if (p->hasClipping()) {
- newClip.addRect(m_data->clipBoundingRect());
- newClip.addEllipse(QRect(rect));
- p->setClipPath(newClip, Qt::IntersectClip);
- } else {
- QRect clipOutRect(rect);
- QRect window(p->window());
- clipOutRect &= window;
- newClip.addRect(window);
- newClip.addEllipse(clipOutRect);
- p->setClipPath(newClip);
- }
-}
-
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect,
int thickness)
{
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
index aa7ed2f..49387a2 100644
--- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -37,12 +37,21 @@
#include <QtGui/qgraphicseffect.h>
#include <QtGui/qgraphicsitem.h>
#include <QtGui/qgraphicsscene.h>
+#include <QtGui/qgraphicsview.h>
#include <QtGui/qgraphicswidget.h>
#include <QtGui/qpainter.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qpixmapcache.h>
#include <QtGui/qstyleoption.h>
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledBackingStore.h"
+#include "TiledBackingStoreClient.h"
+
+// The minimum width/height for tiling. We use the same value as the Windows implementation.
+#define GRAPHICS_LAYER_TILING_THRESHOLD 2000
+#endif
+
#define QT_DEBUG_RECACHE 0
#define QT_DEBUG_CACHEDUMP 0
@@ -112,7 +121,11 @@ public:
};
#endif // QT_NO_GRAPHICSEFFECT
-class GraphicsLayerQtImpl : public QGraphicsObject {
+class GraphicsLayerQtImpl : public QGraphicsObject
+#if ENABLE(TILED_BACKING_STORE)
+, public virtual TiledBackingStoreClient
+#endif
+{
Q_OBJECT
public:
@@ -182,6 +195,16 @@ public:
// ChromeClientQt::scheduleCompositingLayerSync (meaning the sync will happen ASAP)
void flushChanges(bool recursive = true, bool forceTransformUpdate = false);
+#if ENABLE(TILED_BACKING_STORE)
+ // reimplementations from TiledBackingStoreClient
+ virtual void tiledBackingStorePaintBegin();
+ virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&);
+ virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea);
+ virtual IntRect tiledBackingStoreContentsRect();
+ virtual IntRect tiledBackingStoreVisibleRect();
+ virtual Color tiledBackingStoreBackgroundColor() const;
+#endif
+
public slots:
// We need to notify the client (ie. the layer compositor) when the animation actually starts.
void notifyAnimationStarted();
@@ -232,6 +255,10 @@ public:
int m_changeMask;
+#if ENABLE(TILED_BACKING_STORE)
+ TiledBackingStore* m_tiledBackingStore;
+#endif
+
QSizeF m_size;
struct {
QPixmapCache::Key key;
@@ -303,6 +330,9 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer)
, m_opacityAnimationRunning(false)
, m_blockNotifySyncRequired(false)
, m_changeMask(NoChanges)
+#if ENABLE(TILED_BACKING_STORE)
+ , m_tiledBackingStore(0)
+#endif
#if ENABLE(3D_CANVAS)
, m_gc3D(0)
#endif
@@ -330,7 +360,9 @@ GraphicsLayerQtImpl::~GraphicsLayerQtImpl()
item->setParentItem(0);
}
}
-
+#if ENABLE(TILED_BACKING_STORE)
+ delete m_tiledBackingStore;
+#endif
#ifndef QT_NO_ANIMATION
// We do, however, own the animations.
QList<QWeakPointer<QAbstractAnimation> >::iterator it;
@@ -352,6 +384,27 @@ QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate)
if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid())
return QPixmap();
+#if ENABLE(TILED_BACKING_STORE)
+ const bool requiresTiling = (m_state.drawsContent && m_currentContent.contentType == HTMLContentType) && (m_size.width() > GRAPHICS_LAYER_TILING_THRESHOLD || m_size.height() > GRAPHICS_LAYER_TILING_THRESHOLD);
+ if (requiresTiling && !m_tiledBackingStore) {
+ m_tiledBackingStore = new TiledBackingStore(this);
+ m_tiledBackingStore->setTileCreationDelay(0);
+ setFlag(ItemUsesExtendedStyleOption, true);
+ } else if (!requiresTiling && m_tiledBackingStore) {
+ delete m_tiledBackingStore;
+ m_tiledBackingStore = 0;
+ setFlag(ItemUsesExtendedStyleOption, false);
+ }
+
+ if (m_tiledBackingStore) {
+ m_tiledBackingStore->adjustVisibleRect();
+ const QVector<QRect> rects = regionToUpdate.rects();
+ for (int i = 0; i < rects.size(); ++i)
+ m_tiledBackingStore->invalidate(rects[i]);
+ return QPixmap();
+ }
+#endif
+
QPixmap pixmap;
QRegion region = regionToUpdate;
if (QPixmapCache::find(m_backingStore.key, &pixmap)) {
@@ -562,8 +615,15 @@ QRectF GraphicsLayerQtImpl::boundingRect() const
void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
+#if ENABLE(TILED_BACKING_STORE)
+ // FIXME: There's currently no Qt API to know if a new region of an item is exposed outside of the paint event.
+ // Suggested for Qt: http://bugreports.qt.nokia.com/browse/QTBUG-14877.
+ if (m_tiledBackingStore)
+ m_tiledBackingStore->adjustVisibleRect();
+#endif
+
if (m_currentContent.backgroundColor.isValid())
- painter->fillRect(option->rect, QColor(m_currentContent.backgroundColor));
+ painter->fillRect(option->exposedRect, QColor(m_currentContent.backgroundColor));
switch (m_currentContent.contentType) {
case HTMLContentType:
@@ -828,6 +888,56 @@ afterLayerChanges:
}
}
+#if ENABLE(TILED_BACKING_STORE)
+/* \reimp (TiledBackingStoreClient.h)
+*/
+void GraphicsLayerQtImpl::tiledBackingStorePaintBegin()
+{
+}
+
+/* \reimp (TiledBackingStoreClient.h)
+*/
+void GraphicsLayerQtImpl::tiledBackingStorePaint(GraphicsContext* gc, const IntRect& rect)
+{
+ m_layer->paintGraphicsLayerContents(*gc, rect);
+}
+
+/* \reimp (TiledBackingStoreClient.h)
+*/
+void GraphicsLayerQtImpl::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea)
+{
+ for (int i = 0; i < paintedArea.size(); ++i)
+ update(QRectF(paintedArea[i]));
+}
+
+/* \reimp (TiledBackingStoreClient.h)
+*/
+IntRect GraphicsLayerQtImpl::tiledBackingStoreContentsRect()
+{
+ return m_layer->contentsRect();
+}
+
+/* \reimp (TiledBackingStoreClient.h)
+*/
+Color GraphicsLayerQtImpl::tiledBackingStoreBackgroundColor() const
+{
+ if (m_currentContent.contentType == PixmapContentType && !m_currentContent.pixmap.hasAlphaChannel())
+ return Color(0, 0, 0);
+ // We return a transparent color so that the tiles initialize with alpha.
+ return Color(0, 0, 0, 0);
+}
+
+IntRect GraphicsLayerQtImpl::tiledBackingStoreVisibleRect()
+{
+ const QGraphicsView* view = scene()->views().isEmpty() ? 0 : scene()->views().first();
+ if (!view)
+ return mapFromScene(scene()->sceneRect()).boundingRect().toAlignedRect();
+
+ // All we get is the viewport's visible region. We have to map it to the scene and then to item coordinates.
+ return mapFromScene(view->mapToScene(view->viewport()->visibleRegion().boundingRect()).boundingRect()).boundingRect().toAlignedRect();
+}
+#endif
+
void GraphicsLayerQtImpl::notifyAnimationStarted()
{
// WebCore notifies javascript when the animation starts. Here we're letting it know.
diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp
index 508ba6a..b686fef 100644
--- a/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/WebCore/platform/graphics/qt/PathQt.cpp
@@ -134,10 +134,10 @@ bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point)
ASSERT(applier);
QPainterPathStroker stroke;
- GraphicsContext* gc = scratchContext();
- applier->strokeStyle(gc);
+ GraphicsContext* context = scratchContext();
+ applier->strokeStyle(context);
- QPen pen = gc->pen();
+ QPen pen = context->platformContext()->pen();
stroke.setWidth(pen.widthF());
stroke.setCapStyle(pen.capStyle());
stroke.setJoinStyle(pen.joinStyle());
@@ -162,12 +162,12 @@ FloatRect Path::boundingRect() const
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
{
- GraphicsContext* gc = scratchContext();
+ GraphicsContext* context = scratchContext();
QPainterPathStroker stroke;
if (applier) {
- applier->strokeStyle(gc);
+ applier->strokeStyle(context);
- QPen pen = gc->pen();
+ QPen pen = context->platformContext()->pen();
stroke.setWidth(pen.widthF());
stroke.setCapStyle(pen.capStyle());
stroke.setJoinStyle(pen.joinStyle());
diff --git a/WebCore/platform/graphics/qt/TextureMapperQt.cpp b/WebCore/platform/graphics/qt/TextureMapperQt.cpp
index 9236dae..6fdd7df 100644
--- a/WebCore/platform/graphics/qt/TextureMapperQt.cpp
+++ b/WebCore/platform/graphics/qt/TextureMapperQt.cpp
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "texmap/TextureMapper.h"
+#include "TextureMapperQt.h"
#include <QtCore/qdebug.h>
#include <QtGui/qpaintengine.h>
@@ -30,45 +30,6 @@
namespace WebCore {
-class BitmapTextureQt : public BitmapTexture {
- friend class TextureMapperQt;
-public:
- BitmapTextureQt() {}
- virtual void destroy();
- virtual IntSize size() const { return IntSize(m_pixmap.width(), m_pixmap.height()); }
- virtual void reset(const IntSize&, bool opaque);
- virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);
- virtual void endPaint();
- virtual void setContentsToImage(Image*);
- virtual bool save(const String& path);
- virtual bool isValid() const { return !m_pixmap.isNull(); }
- virtual bool allowOfflineTextureUpload() const { return true; }
- IntRect sourceRect() const { return IntRect(0, 0, contentSize().width(), contentSize().height()); }
-private:
- QPainter m_painter;
- QPixmap m_pixmap;
-};
-
-class TextureMapperQt : public TextureMapper {
-public:
- virtual void drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture);
- virtual void bindSurface(BitmapTexture* surface);
- virtual void setClip(const IntRect&);
- virtual bool allowSurfaceForRoot() const { return false; }
- TextureMapperQt(GraphicsContext* context);
- virtual const char* type() const { return "TextureMapperQt"; }
- virtual PassRefPtr<BitmapTexture> createTexture();
-
- static void initialize(QPainter* painter)
- {
- painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
- }
-
-private:
- QPainter* m_painter;
- RefPtr<BitmapTextureQt> m_currentSurface;
-};
-
void BitmapTextureQt::destroy()
{
if (m_pixmap.paintingActive())
@@ -117,18 +78,41 @@ void BitmapTextureQt::setContentsToImage(Image* image)
m_pixmap = *pixmap;
}
+void BitmapTextureQt::pack()
+{
+ if (m_pixmap.isNull())
+ return;
+
+ m_image = m_pixmap.toImage();
+ m_pixmap = QPixmap();
+ m_isPacked = true;
+}
+
+void BitmapTextureQt::unpack()
+{
+ m_isPacked = false;
+ if (m_image.isNull())
+ return;
+
+ m_pixmap = QPixmap::fromImage(m_image);
+ m_image = QImage();
+}
+
void TextureMapperQt::setClip(const IntRect& rect)
{
QPainter* painter = m_currentSurface ? &m_currentSurface->m_painter : m_painter;
painter->setClipRect(rect);
}
-TextureMapperQt::TextureMapperQt(GraphicsContext* context)
- : TextureMapper(context)
- , m_painter(context->platformContext())
- , m_currentSurface(0)
+TextureMapperQt::TextureMapperQt()
+ : m_currentSurface(0)
{
- TextureMapperQt::initialize(m_painter);
+}
+
+void TextureMapperQt::setGraphicsContext(GraphicsContext* context)
+{
+ m_painter = context->platformContext();
+ initialize(m_painter);
}
void TextureMapperQt::bindSurface(BitmapTexture* surface)
@@ -178,21 +162,26 @@ void TextureMapperQt::drawTexture(const BitmapTexture& texture, const IntRect& t
painter->setOpacity(prevOpacity);
}
-PassRefPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
+PassOwnPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
{
#ifdef QT_OPENGL_LIB
- if (context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2)
- return adoptRef(new TextureMapperGL(context));
+ if (context && context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2)
+ return new TextureMapperGL;
#endif
- return adoptRef(new TextureMapperQt(context));
+ return new TextureMapperQt;
}
-
PassRefPtr<BitmapTexture> TextureMapperQt::createTexture()
{
return adoptRef(new BitmapTextureQt());
}
+BitmapTextureQt::BitmapTextureQt()
+ : m_isPacked(false)
+{
+
+}
+
#ifdef QT_OPENGL_LIB
class RGBA32PremultimpliedBufferQt : public RGBA32PremultimpliedBuffer {
public:
diff --git a/WebCore/platform/graphics/qt/TextureMapperQt.h b/WebCore/platform/graphics/qt/TextureMapperQt.h
new file mode 100644
index 0000000..e17b968
--- /dev/null
+++ b/WebCore/platform/graphics/qt/TextureMapperQt.h
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ 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 "texmap/TextureMapper.h"
+
+#ifndef TextureMapperQt_h
+#define TextureMapperQt_h
+
+namespace WebCore {
+
+class BitmapTextureQt : public BitmapTexture {
+ friend class TextureMapperQt;
+public:
+ BitmapTextureQt();
+ ~BitmapTextureQt() { destroy(); }
+ virtual void destroy();
+ virtual IntSize size() const { return IntSize(m_pixmap.width(), m_pixmap.height()); }
+ virtual void reset(const IntSize&, bool opaque);
+ virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect);
+ virtual void endPaint();
+ virtual void setContentsToImage(Image*);
+ virtual bool save(const String& path);
+ virtual bool isValid() const { return !m_pixmap.isNull() || !m_image.isNull(); }
+ IntRect sourceRect() const { return IntRect(0, 0, contentSize().width(), contentSize().height()); }
+ virtual void pack();
+ virtual void unpack();
+ virtual bool isPacked() const { return m_isPacked; }
+
+private:
+ QPainter m_painter;
+ QPixmap m_pixmap;
+ QImage m_image;
+ bool m_isPacked;
+};
+
+class TextureMapperQt : public TextureMapper {
+public:
+ TextureMapperQt();
+
+ virtual void drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture);
+ virtual void bindSurface(BitmapTexture* surface);
+ virtual void setClip(const IntRect&);
+ virtual void setGraphicsContext(GraphicsContext*);
+ virtual bool allowSurfaceForRoot() const { return false; }
+ virtual PassRefPtr<BitmapTexture> createTexture();
+
+ static void initialize(QPainter* painter)
+ {
+ painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
+ }
+
+ static PassOwnPtr<TextureMapper> create() { return new TextureMapperQt; }
+
+private:
+ QPainter* m_painter;
+ RefPtr<BitmapTextureQt> m_currentSurface;
+};
+
+}
+#endif
diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
index c503307..d0dafb1 100644
--- a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
@@ -48,7 +48,7 @@ bool GraphicsContext3D::getImageData(Image* image,
return false;
OwnPtr<NativeImageSkia> pixels;
NativeImageSkia* skiaImage = 0;
- AlphaOp neededAlphaOp = kAlphaDoNothing;
+ AlphaOp neededAlphaOp = AlphaDoNothing;
if (image->data()) {
ImageSource decoder(false);
decoder.setData(image->data(), true);
@@ -63,12 +63,12 @@ bool GraphicsContext3D::getImageData(Image* image,
return false;
skiaImage = pixels.get();
if (hasAlpha && premultiplyAlpha)
- neededAlphaOp = kAlphaDoPremultiply;
+ neededAlphaOp = AlphaDoPremultiply;
} else {
// This is a special case for texImage2D with HTMLCanvasElement input.
skiaImage = image->nativeImageForCurrentFrame();
if (!premultiplyAlpha)
- neededAlphaOp = kAlphaDoUnmultiply;
+ neededAlphaOp = AlphaDoUnmultiply;
}
if (!skiaImage)
return false;
@@ -77,7 +77,7 @@ bool GraphicsContext3D::getImageData(Image* image,
ASSERT(skiaImage->rowBytes() == skiaImage->width() * 4);
outputVector.resize(skiaImage->rowBytes() * skiaImage->height());
return packPixels(reinterpret_cast<const uint8_t*>(skiaImage->getPixels()),
- kSourceFormatBGRA8, skiaImage->width(), skiaImage->height(), 0,
+ SourceFormatBGRA8, skiaImage->width(), skiaImage->height(), 0,
format, type, neededAlphaOp, outputVector.data());
}
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 4bc98fb..e506e5d 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -420,20 +420,6 @@ void GraphicsContext::clipOut(const Path& p)
platformContext()->canvas()->clipPath(path, SkRegion::kDifference_Op);
}
-void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
-{
- if (paintingDisabled())
- return;
-
- SkRect oval(rect);
- if (!isRectSkiaSafe(getCTM(), oval))
- return;
-
- SkPath path;
- path.addOval(oval, SkPath::kCCW_Direction);
- platformContext()->canvas()->clipPath(path, SkRegion::kDifference_Op);
-}
-
void GraphicsContext::clipPath(WindRule clipRule)
{
if (paintingDisabled())
@@ -946,6 +932,11 @@ void GraphicsContext::setCompositeOperation(CompositeOperator op)
platformContext()->setXfermodeMode(WebCoreCompositeToSkiaComposite(op));
}
+InterpolationQuality GraphicsContext::imageInterpolationQuality() const
+{
+ return platformContext()->interpolationQuality();
+}
+
void GraphicsContext::setImageInterpolationQuality(InterpolationQuality q)
{
platformContext()->setInterpolationQuality(q);
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 6204597..d610c2a 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -34,6 +34,7 @@
#include "AffineTransform.h"
#include "DrawingBuffer.h"
+#include "Extensions3D.h"
#include "GraphicsContext.h"
#include "GraphicsContext3D.h"
#include "ImageBuffer.h"
@@ -861,7 +862,7 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
for (int y = 0; y < height; ++y) {
uint32_t* pixels = bitmap.getAddr32(0, y);
if (context->supportsBGRA())
- context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::BGRA_EXT, GraphicsContext3D::UNSIGNED_BYTE, pixels);
+ context->readPixels(0, height - 1 - y, width, 1, Extensions3D::BGRA_EXT, GraphicsContext3D::UNSIGNED_BYTE, pixels);
else {
context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels);
for (int i = 0; i < width; ++i) {
diff --git a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
index 057bcfc..4698239 100644
--- a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
+++ b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
@@ -20,1077 +20,36 @@
#include "config.h"
#include "GraphicsLayerTextureMapper.h"
-#include "CurrentTime.h"
-#include "FloatRect.h"
-#include "GraphicsContext.h"
-#include "HashMap.h"
-#include "Image.h"
-#include "RefCounted.h"
-#include "TextureMapper.h"
-#include "TextureMapperPlatformLayer.h"
-#include "Timer.h"
-#include "TransformOperations.h"
-#include "TranslateTransformOperation.h"
-#include "UnitBezier.h"
-
-#define DEBUG_TEXMAP_FPS 0
+#include "TextureMapperNode.h"
namespace WebCore {
-struct TexmapPaintOptions {
- BitmapTexture* surface;
- TextureMapper* textureMapper;
- GraphicsContext* context;
- TextureMapperNode* rootLayer;
- float opacity;
- IntRect scissorRect;
- IntRect visibleRect;
- bool isSurface;
-};
-class TextureMapperCache {
-public:
- void mark(BitmapTexture* texture);
-
- class Entry {
- public:
- RefPtr<BitmapTexture> texture;
- Entry() : previousCost(0) { }
- inline int calculateCost() const
- {
- if (!texture || !texture->isValid())
- return 0;
- const IntSize textureSize = texture->size();
- // an image's cost in bytes is width * height * bytes per pixel (4).
- return textureSize.width() * textureSize.height() * 4;
- }
- Entry(BitmapTexture* newTexture)
- : texture(newTexture)
- {
- }
- bool operator==(const Entry& other) const { return texture == other.texture; }
- int previousCost;
- };
-
- TextureMapperCache() : m_totalCost(0) {}
-
- void purge();
- Vector<Entry> m_data;
- int m_totalCost;
-#ifndef TEXMAP_TEXTURE_CACHE_KBS
-#define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024
-#endif
- static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024;
- static const int PurgeAmount = MaxCost / 4;
-};
-
-
-void TextureMapperCache::purge()
-{
- // If this is in the GL implementation, we need an active GL context, because we might call glDeleteTextures.
- const int size = m_data.size();
-
- if (m_totalCost <= TextureMapperCache::MaxCost)
- return;
-
- // Ensure that we have the right count. It might be inaccurate if content changed size.
- // We only do this when we're actually ready to purge.
- m_totalCost = 0;
- for (int i = 0; i < size; ++i)
- m_totalCost += m_data[i].calculateCost();
-
- for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) {
- Entry& entry = m_data[i];
- if (entry.texture->isLocked() || !entry.texture->isValid())
- continue;
- m_totalCost -= entry.previousCost;
- entry.texture->destroy();
- m_data.remove(i);
- }
-}
-
-void TextureMapperCache::mark(BitmapTexture* texture)
-{
- if (!texture || !texture->isValid())
- return;
-
- Entry entry(texture);
- size_t index = m_data.find(entry);
- if (!index)
- return;
-
- if (index < m_data.size())
- m_data.remove(index);
- const int cost = entry.calculateCost();
- m_totalCost -= entry.previousCost;
- m_totalCost += (entry.previousCost = cost);
- m_data.prepend(entry);
-}
-
-TextureMapperCache gTextureMapperCache;
-
-class TextureMapperCacheLock {
-public:
- TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture)
- {
- if (m_texture)
- m_texture->lock();
- }
- ~TextureMapperCacheLock()
- {
- if (m_texture)
- m_texture->unlock();
- }
-
-private:
- RefPtr<BitmapTexture> m_texture;
-};
-
-class TextureMapperNode : public TextureMapperContentLayer {
-
-public:
- // This set of flags help us defer which properties of the layer have been
- // modified by the compositor, so we can know what to look for in the next flush.
- enum ChangeMask {
- NoChanges = 0,
-
- ParentChange = (1L << 0),
- ChildrenChange = (1L << 1),
- MaskLayerChange = (1L << 2),
- PositionChange = (1L << 3),
-
- AnchorPointChange = (1L << 4),
- SizeChange = (1L << 5),
- TransformChange = (1L << 6),
- ContentChange = (1L << 7),
-
- ContentsOrientationChange = (1L << 9),
- OpacityChange = (1L << 10),
- ContentsRectChange = (1L << 11),
-
- Preserves3DChange = (1L << 12),
- MasksToBoundsChange = (1L << 13),
- DrawsContentChange = (1L << 14),
- ContentsOpaqueChange = (1L << 15),
-
- BackfaceVisibilityChange = (1L << 16),
- ChildrenTransformChange = (1L << 17),
- DisplayChange = (1L << 18),
- BackgroundColorChange = (1L << 19),
-
- ReplicaLayerChange = (1L << 20)
- };
-
- // The compositor lets us special-case images and colors, so we try to do so.
- enum StaticContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType};
-
- TextureMapperNode* rootLayer();
-
- TextureMapperNode(GraphicsLayerTextureMapper* newLayer);
- virtual ~TextureMapperNode();
-
- void clearDirectImage();
- void computeTransformations();
- IntSize nearestSurfaceSize() const;
- void computeReplicaTransform();
- void computeLayerType();
- void computeLocalTransform();
- void flattenTo2DSpaceIfNecessary();
- void initializeTextureMapper(TextureMapper*);
- void invalidateTransform();
- void notifyChange(ChangeMask);
- void syncCompositingState(bool recurse);
- void performPostSyncOperations();
- void setNeedsDisplay();
- void setNeedsDisplayInRect(IntRect);
- virtual void cleanupTextureMapper();
-
- void paintRecursive(TexmapPaintOptions options);
- void paintSelf(const TexmapPaintOptions& options);
- void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect);
-
- int countDescendantsWithContent() const;
- bool hasSurfaceDescendants() const;
-
- IntSize size() const { return m_size; }
-
- virtual void setPlatformLayerClient(TextureMapperLayerClient*);
- virtual void paint(GraphicsContext*, const IntSize&, const IntRect& targetRect, const IntRect& exposedRect, const TransformationMatrix& transform, float opacity);
-
- static TextureMapperNode* toTextureMapperNode(GraphicsLayer*);
-public:
- GraphicsLayerTextureMapper* m_layer;
- const char* m_lastTextureMapperType;
- RefPtr<TextureMapper> m_lastTextureMapper;
- struct TransformData {
- TransformationMatrix base, target, replica, forDescendants, perspective, local;
- IntRect targetBoundingRect;
- float centerZ;
- bool dirty, localDirty, perspectiveDirty;
- IntRect boundingRectFromRoot;
- TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { }
- };
-
- TransformData m_transforms;
-
- enum LayerType {
- DefaultLayer,
- RootLayer,
- ScissorLayer,
- ClipLayer,
- TransparencyLayer
- };
-
- LayerType m_layerType;
-
- struct ContentData {
- IntRect needsDisplayRect;
- bool needsDisplay;
- Color backgroundColor;
-
- StaticContentType contentType;
- RefPtr<Image> image;
- TextureMapperVideoLayer* media;
-
- ContentData()
- : needsDisplay(false)
- , contentType(HTMLContentType)
- , image(0)
- , media(0)
- {
- }
-
- };
-
- inline IntRect targetRect() const
- {
- return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect;
- }
-
- inline IntRect entireRect() const
- {
- return IntRect(0, 0, m_size.width(), m_size.height());
- }
-
- inline IntRect replicaRect() const
- {
- return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect();
- }
-
- RefPtr<BitmapTexture> m_texture;
- RefPtr<BitmapTexture> m_surface, m_replicaSurface;
-
- ContentData m_pendingContent;
- ContentData m_currentContent;
-
- Vector<TextureMapperNode*> m_children;
- TextureMapperNode* m_parent;
- TextureMapperNode* m_effectTarget;
- int m_changeMask;
- IntSize m_size, m_nearestSurfaceSize;
- String m_name;
- TextureMapperLayerClient* m_platformClient;
-
- struct State {
- FloatPoint pos;
- FloatPoint3D anchorPoint;
- FloatSize size;
- TransformationMatrix transform;
- TransformationMatrix childrenTransform;
- Color backgroundColor;
- Color currentColor;
- GraphicsLayer::CompositingCoordinatesOrientation geoOrientation;
- GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation;
- float opacity;
- IntRect contentsRect;
- int descendantsWithContent;
- TextureMapperNode* maskLayer;
- TextureMapperNode* replicaLayer;
- bool preserves3D;
- bool masksToBounds;
- bool drawsContent;
- bool contentsOpaque;
- bool backfaceVisibility;
- bool visible;
- bool dirty;
- bool tiled;
- bool hasSurfaceDescendants;
-
- State()
- : opacity(1.f)
- , descendantsWithContent(0)
- , maskLayer(0)
- , replicaLayer(0)
- , preserves3D(false)
- , masksToBounds(false)
- , drawsContent(false)
- , contentsOpaque(false)
- , backfaceVisibility(false)
- , visible(true)
- , dirty(true)
- , tiled(false)
- , hasSurfaceDescendants(false)
- {
- }
- };
- State m_state;
-};
-
-void TextureMapperNode::setNeedsDisplayInRect(IntRect rect)
-{
- if (m_platformClient) {
- if (m_state.hasSurfaceDescendants) {
- m_platformClient->setNeedsDisplay();
- return;
- }
- rect.intersect(IntRect(0, 0, m_size.width(), m_size.height()));
- if (rect.isEmpty())
- return;
- m_platformClient->setNeedsDisplayInRect(rect);
- return;
- }
-
- if (!m_parent)
- return;
-
- m_parent->setNeedsDisplayInRect(rect);
-}
-
-void TextureMapperNode::setNeedsDisplay()
-{
- if (m_effectTarget)
- m_effectTarget->setNeedsDisplay();
- if (m_transforms.targetBoundingRect.isEmpty())
- return;
- if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType)
- setNeedsDisplayInRect(m_transforms.targetBoundingRect);
-}
-
-
-void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client)
-{
- m_platformClient = client;
-}
-
-static int compareGraphicsLayersZValue(const void* a, const void* b)
-{
- typedef const TextureMapperNode* NodePtr;
- const NodePtr* nodeA = static_cast<const NodePtr*>(a);
- const NodePtr* nodeB = static_cast<const NodePtr*>(b);
- return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000);
-}
-inline static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last)
-{
- qsort(array.data(), array.size(), sizeof(TextureMapperNode*), compareGraphicsLayersZValue);
-}
-
-bool TextureMapperNode::hasSurfaceDescendants() const
-{
- if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer)
- return true;
- const int size = m_children.size();
- for (int i = 0; i < size; ++i) {
- if (TextureMapperNode* child = m_children[i]) {
- if (child->hasSurfaceDescendants())
- return true;
- }
- }
- return false;
-
-}
-
-void TextureMapperNode::paint(GraphicsContext* context, const IntSize& size, const IntRect& targetRect, const IntRect& exposedRect, const TransformationMatrix& transform, float opacity)
-{
- ASSERT(m_layerType == RootLayer);
- if (m_size.isEmpty())
- return;
-
-#if 0
- WTF::StopWatch stopWatch;
- ("[TextureMapper] RootPaint!!\n");
-#endif
-
- RefPtr<TextureMapper> textureMapper = TextureMapper::create(context);
-
- if (textureMapper->type() != m_lastTextureMapperType)
- gTextureMapperCache.m_data.clear();
-
- m_lastTextureMapper = textureMapper;
- TexmapPaintOptions opt;
- opt.opacity = 1;
- opt.rootLayer = this;
- opt.scissorRect = targetRect;
- opt.visibleRect = exposedRect;
- opt.textureMapper = textureMapper.get();
- opt.context = textureMapper->graphicsContext();
- opt.surface = 0;
- paintRecursive(opt);
-
- if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) {
- textureMapper->bindSurface(0);
- textureMapper->paintToTarget(*m_surface.get(), size, transform, opacity * m_state.opacity, targetRect);
- }
- gTextureMapperCache.purge();
-}
-
-int TextureMapperNode::countDescendantsWithContent() const
-{
- if (!m_state.visible || m_state.opacity < 0.001)
- return 0;
- int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0;
-
- const int size = m_children.size();
- for (int i = 0; i < size; ++i) {
- if (TextureMapperNode* child = m_children[i])
- descendantsWithContent += child->countDescendantsWithContent();
- }
-
- return descendantsWithContent;
-}
-
-inline TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer)
-{
- return layer ? static_cast<GraphicsLayerTextureMapper*>(layer)->m_node.get() : 0;
-}
-
-void TextureMapperNode::computeLayerType()
-{
- // calculate layer type. A layer can be one of the following:
- // RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport.
- // only one layer is the root layer.
- // ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children.
- // A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip.
- // ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity.
- // A clip layer is a layer that masks to bounds, doesn't preserve 3D, has children, and has a transparency/mask or a non-rectangular transform.
- // TransparencyLayer: creates a new framebuffer idetical in size to the current framebuffer. Then draws the fb's texture to the current framebuffer with identity transform.
- // Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds.
- // DefaultLayer: draws itself and its children directly to the current framebuffer.
- // any layer that doesn't conform to the other rules is a DefaultLayer.
-
- const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType);
- const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0);
- const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer;
- const bool hasReplica = m_state.replicaLayer;
- m_layerType = DefaultLayer;
-
- // Layer has no parent, it must be a root layer.
- if (!m_parent && !m_effectTarget) {
- m_layerType = RootLayer;
- return;
- }
-
- // A layer with no contents is always a default layer.
- if (!m_state.descendantsWithContent)
- return;
-
- // A layer with content-descendants and a mask is always a clip layer.
- if (hasDescendantsWithContent && m_state.maskLayer) {
- m_layerType = ClipLayer;
- return;
- }
-
- // A masks-to bounds layer can be a clip or a scissor layer. It's a scissor layer only if it has a trivial clip (identity or translation), or if it has transparency.
- // That's because a ClipLayer would create an intermediate drawing surface (FB) - we want to limit it to when it's actually necessary, i.e. transparency or non-trivial clip.
- if (m_state.masksToBounds && hasDescendantsWithContent) {
- if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D)
- m_layerType = ClipLayer;
- else
- m_layerType = ScissorLayer;
- return;
- }
-
- // We use a transparency layer when we have two of the following 3: replica, transparency, descendants with contents.
- if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1))
- m_layerType = TransparencyLayer;
-}
-void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper)
-{
- if (textureMapper->type() == m_lastTextureMapperType)
- return;
- m_surface = textureMapper->createTexture();
- m_replicaSurface = textureMapper->createTexture();
- m_texture = textureMapper->createTexture();
- gTextureMapperCache.mark(m_texture.get());
- m_lastTextureMapperType = textureMapper->type();
-}
-
-TextureMapperNode::TextureMapperNode(GraphicsLayerTextureMapper* newLayer)
- : m_layer(newLayer)
- , m_lastTextureMapperType(0)
- , m_lastTextureMapper(0)
- , m_layerType(DefaultLayer)
- , m_surface(0)
- , m_parent(0)
- , m_effectTarget(0)
- , m_changeMask(NoChanges)
- , m_platformClient(0)
-{
-
-}
-
-TextureMapperNode* TextureMapperNode::rootLayer()
-{
- if (m_effectTarget)
- return m_effectTarget->rootLayer();
- if (m_parent)
- return m_parent->rootLayer();
- return this;
-}
-
-void TextureMapperNode::invalidateTransform()
-{
- m_transforms.dirty = true;
- if (m_layerType != ClipLayer)
- m_state.dirty = true;
- if (m_state.replicaLayer)
- m_state.replicaLayer->invalidateTransform();
- const int size = m_children.size();
- for (int i = 0; i < size; ++i) {
- if (TextureMapperNode* layer = m_children[i])
- layer->invalidateTransform();
- }
-}
-
-void TextureMapperNode::computeLocalTransform()
-{
- if (!m_transforms.localDirty)
- return;
- const float originX = m_state.anchorPoint.x() * m_size.width();
- const float originY = m_state.anchorPoint.y() * m_size.height();
- m_transforms.local =
- TransformationMatrix()
- .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
- .multLeft(m_state.transform)
- .translate3d(-originX, -originY, -m_state.anchorPoint.z());
- m_transforms.localDirty = false;
-}
-
-void TextureMapperNode::flattenTo2DSpaceIfNecessary()
-{
- if (m_state.preserves3D)
- return;
- m_transforms.forDescendants.setM13(0);
- m_transforms.forDescendants.setM23(0);
- m_transforms.forDescendants.setM31(0);
- m_transforms.forDescendants.setM32(0);
- m_transforms.forDescendants.setM33(1);
- m_transforms.forDescendants.setM34(0);
- m_transforms.forDescendants.setM43(0);
-}
-
-IntSize TextureMapperNode::nearestSurfaceSize() const
-{
- if (m_layerType == ClipLayer || m_layerType == RootLayer)
- return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size;
- return m_parent->nearestSurfaceSize();
-}
-
-void TextureMapperNode::computeReplicaTransform()
-{
- if (!m_state.replicaLayer)
- return;
-
- m_nearestSurfaceSize = nearestSurfaceSize();
-
- if (m_layerType != TransparencyLayer) {
- m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local);
- return;
- }
-
- const float originX = m_transforms.target.m41();
- const float originY = m_transforms.target.m42();
- m_transforms.replica =
- TransformationMatrix()
- .translate(originX, originY)
- .multLeft(m_state.replicaLayer->m_transforms.local)
- .translate(-originX, -originY);
-}
-
-void TextureMapperNode::computeTransformations()
-{
- if (!m_transforms.dirty)
- return;
-
- m_transforms.dirty = false;
- if ((m_size.isEmpty() && m_state.masksToBounds))
- return;
-
- TextureMapperNode* parent = m_parent;
- computeLocalTransform();
-
- m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local);
- m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target);
-
- if (m_effectTarget)
- return;
-
- m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect()));
- if (m_state.replicaLayer)
- m_state.replicaLayer->computeTransformations();
-
- flattenTo2DSpaceIfNecessary();
-
- if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) {
- m_state.visible = false;
- return;
- }
- m_state.visible = true;
-
- if (parent && parent->m_state.preserves3D)
- m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z();
-
- if (!m_children.size())
- return;
-
- if (m_state.childrenTransform.isIdentity())
- return;
-
- const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2);
- if (m_transforms.perspectiveDirty)
- m_transforms.perspective = TransformationMatrix()
- .translate(centerPoint.x(), centerPoint.y())
- .multLeft(m_state.childrenTransform)
- .translate(-centerPoint.x(), -centerPoint.y());
- m_transforms.perspectiveDirty = false;
- m_transforms.forDescendants.multLeft(m_transforms.perspective);
-}
-
-void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect)
-{
- if (m_size.isEmpty() || !m_layer) {
- m_texture->destroy();
- return;
- }
-
- if (m_currentContent.contentType == DirectImageContentType) {
- if (m_currentContent.image)
- m_texture->setContentsToImage(m_currentContent.image.get());
- return;
- }
-
- if (m_currentContent.contentType == MediaContentType) {
- if (!m_currentContent.media)
- return;
- m_texture->reset(m_size, true);
- PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia();
- GraphicsContext context(platformContext);
- m_currentContent.media->paint(&context);
- m_texture->endPaint();
- return;
- }
-
- const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid();
- if ((m_currentContent.contentType != HTMLContentType)
- || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset))
- return;
-
- IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height());
- if (!needsReset && !m_currentContent.needsDisplay)
- dirtyRect.intersect(m_currentContent.needsDisplayRect);
- if (needsReset)
- m_texture->reset(m_size, m_state.contentsOpaque);
- m_pendingContent.needsDisplayRect = IntRect();
-
- {
- GraphicsContext context(m_texture->beginPaint(dirtyRect));
- if (textureMapper && textureMapper->graphicsContext()) {
- GraphicsContext* originalContext = textureMapper->graphicsContext();
- context.setImageInterpolationQuality(originalContext->imageInterpolationQuality());
- context.setTextDrawingMode(originalContext->textDrawingMode());
- }
- m_layer->paintGraphicsLayerContents(context, dirtyRect);
- }
- m_texture->endPaint();
- m_currentContent.needsDisplay = false;
-
-}
-
-void TextureMapperNode::paintSelf(const TexmapPaintOptions& options)
-{
- if (!m_layer || m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType))
- return;
-
- RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0;
- RefPtr<BitmapTexture> replicaMaskTexture = 0;
- if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer)
- replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture;
-
- const float opacity = options.isSurface ? 1 : options.opacity;
-
- uploadTextureFromContent(options.textureMapper, options.visibleRect);
- if (m_state.replicaLayer && !options.isSurface)
- options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica,
- opacity * m_state.replicaLayer->m_state.opacity,
- replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
-
- const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect();
- const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target;
- options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get());
-}
-
-void TextureMapperNode::paintRecursive(TexmapPaintOptions options)
-{
- bool isDirty = m_state.dirty;
- m_state.dirty = false;
-
- if ((m_size.isEmpty() && (m_state.masksToBounds
- || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01)
- return;
-
- initializeTextureMapper(options.textureMapper);
- computeReplicaTransform();
-
- if (m_state.maskLayer) {
- m_state.maskLayer->initializeTextureMapper(options.textureMapper);
- m_state.maskLayer->m_state.dirty = false;
- }
-
- if (m_state.replicaLayer) {
- m_state.replicaLayer->initializeTextureMapper(options.textureMapper);
- m_state.replicaLayer->m_state.dirty = false;
- if (m_state.replicaLayer->m_state.maskLayer) {
- m_state.replicaLayer->m_state.maskLayer->initializeTextureMapper(options.textureMapper);
- m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false;
- }
- }
-
- TextureMapperNode* replica = m_state.replicaLayer;
- const bool isSurface = (m_layerType == ClipLayer
- || m_layerType == TransparencyLayer
- || (m_layerType == RootLayer
- && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants)
- ));
- if (isSurface)
- uploadTextureFromContent(options.textureMapper, options.visibleRect);
- const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect;
-
- options.opacity *= m_state.opacity;
-
- TexmapPaintOptions optionsForDescendants(options);
- optionsForDescendants.opacity = isSurface ? 1 : options.opacity;
- options.isSurface = isSurface;
-
- if (m_layerType == ClipLayer) {
- optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect);
- optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height());
- }
-
- if (m_layerType == ScissorLayer)
- optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect);
- options.textureMapper->setClip(optionsForDescendants.scissorRect);
-
- TextureMapperCacheLock(m_texture.get());
- TextureMapperCacheLock(m_surface.get());
- TextureMapperCacheLock(m_replicaSurface.get());
-
- gTextureMapperCache.purge();
-
- if (isSurface) {
- ASSERT(m_surface);
- if (!m_surface->isValid())
- isDirty = true;
- if (m_state.tiled) {
- m_surface->reset(options.visibleRect.size());
- m_surface->setOffset(options.visibleRect.location());
- } else if (isDirty)
- m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size);
- gTextureMapperCache.mark(m_surface.get());
- options.textureMapper->bindSurface(m_surface.get());
-
- optionsForDescendants.surface = m_surface.get();
- } else if (m_surface)
- m_surface->destroy();
-
- RefPtr<BitmapTexture> maskTexture;
- RefPtr<BitmapTexture> replicaMaskTexture;
- if (TextureMapperNode* mask = m_state.maskLayer) {
- mask->uploadTextureFromContent(options.textureMapper, options.visibleRect);
- maskTexture = mask->m_texture;
- }
-
- if (replica && replica->m_state.maskLayer) {
- replica->m_state.maskLayer->uploadTextureFromContent(options.textureMapper, options.visibleRect);
- replicaMaskTexture = replica->m_state.maskLayer->m_texture;
- }
-
- int childrenSize = m_children.size();
- if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid()) {
- bool didPaintSelf = false;
- if (!m_state.preserves3D || m_children.isEmpty()) {
- paintSelf(options);
- didPaintSelf = true;
- }
-
- if (m_children.isEmpty() && !isSurface)
- return;
-
- if (m_layerType == ScissorLayer)
- optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height())));
-
- for (int i = 0; i < childrenSize; ++i) {
- TextureMapperNode* layer = m_children[i];
- if (!layer)
- continue;
-
- if (!didPaintSelf && layer->m_transforms.centerZ >= 0) {
- paintSelf(options);
- didPaintSelf = true;
- }
- layer->paintRecursive(optionsForDescendants);
- if (isSurface) {
- ASSERT(m_surface);
- gTextureMapperCache.mark(m_surface.get());
- options.textureMapper->bindSurface(m_surface.get());
- }
- }
- if (!didPaintSelf) {
- paintSelf(options);
- didPaintSelf = true;
- }
- }
-
- if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer)
- return;
-
- ASSERT(m_surface);
- BitmapTexture& texture = *m_surface.get();
- if (replica) {
- ASSERT(m_replicaSurface);
- m_replicaSurface->reset(options.surface->size());
- m_replicaSurface->setOffset(options.surface->offset());
- gTextureMapperCache.mark(m_replicaSurface.get());
- options.textureMapper->bindSurface(m_replicaSurface.get());
- options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
- options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get());
- options.textureMapper->bindSurface(options.surface);
- gTextureMapperCache.mark(options.surface);
- options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0);
- return;
- }
-
- options.textureMapper->bindSurface(options.surface);
- options.textureMapper->drawTexture(texture,
- m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) :
- targetRect(),
- m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target,
- options.opacity, maskTexture.get());
- gTextureMapperCache.mark(&texture);
-}
-
-void TextureMapperNode::cleanupTextureMapper()
-{
- if (m_texture)
- m_texture->destroy();
- if (m_surface)
- m_surface->destroy();
- if (m_replicaSurface)
- m_replicaSurface->destroy();
- for (int i = 0; i < m_children.size(); ++i) {
- if (m_children[i])
- m_children[i]->cleanupTextureMapper();
- }
- if (m_lastTextureMapper)
- m_lastTextureMapper->cleanup();
-}
-
-TextureMapperNode::~TextureMapperNode()
+GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)
+ : GraphicsLayer(client)
+ , m_node(new TextureMapperNode())
+ , m_changeMask(0)
{
- setNeedsDisplay();
- {
- const int childrenSize = m_children.size();
- for (int i = childrenSize-1; i >= 0; --i) {
- ASSERT(m_children[i]->m_parent == this);
- m_children[i]->m_parent = 0;
- }
- }
- if (m_parent)
- m_parent->m_children.remove(m_parent->m_children.find(this));
}
-void TextureMapperNode::notifyChange(ChangeMask changeMask)
+void GraphicsLayerTextureMapper::notifyChange(TextureMapperNode::ChangeMask changeMask)
{
m_changeMask |= changeMask;
- if (!m_layer->client())
+ if (!client())
return;
- m_layer->client()->notifySyncRequired(m_layer);
-}
-
-void TextureMapperNode::performPostSyncOperations()
-{
- const LayerType prevLayerType = m_layerType;
- computeLayerType();
- if (prevLayerType != m_layerType)
- m_state.dirty = true;
- if (m_transforms.dirty)
- setNeedsDisplay();
-
- computeTransformations();
- if (m_state.maskLayer && !m_state.dirty)
- m_state.dirty = m_state.maskLayer->m_state.dirty;
- if (m_state.replicaLayer && !m_state.dirty)
- m_state.dirty = m_state.replicaLayer->m_state.dirty;
-
- const int size = m_children.size();
-
- for (int i = size - 1; i >= 0; --i) {
- TextureMapperNode* layer = m_children[i];
-
- layer->performPostSyncOperations();
- if (!m_state.dirty)
- m_state.dirty = layer->m_state.dirty;
- }
- m_state.hasSurfaceDescendants = hasSurfaceDescendants();
- if (m_state.dirty)
- m_state.descendantsWithContent = countDescendantsWithContent();
-
- if (m_state.preserves3D)
- sortByZOrder(m_children, 0, size);
- if (m_state.dirty)
- setNeedsDisplay();
+ client()->notifySyncRequired(this);
}
-void TextureMapperNode::syncCompositingState(bool recurse)
+void GraphicsLayerTextureMapper::didSynchronize()
{
- bool needsToInvalidateTransform = false;
-
- if (!m_layer)
- return;
-
- if (m_changeMask == NoChanges)
- goto afterCurrentLayerSync;
-
- setNeedsDisplay();
- if (m_parent)
- m_parent->m_state.dirty = true;
-
- if (m_currentContent.contentType == HTMLContentType && (m_changeMask & ParentChange)) {
- // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't
- // try to snatch that ownership.
-
- if (!m_layer->parent())
- m_parent = 0;
- else
- m_parent = toTextureMapperNode(m_layer->parent());
-
- if (!m_layer->parent() && m_parent) {
- size_t index = m_parent->m_children.find(this);
- m_parent->m_children.remove(index);
- }
-
- }
-
- if (m_changeMask & ChildrenChange) {
- m_children.clear();
- for (size_t i = 0; i < m_layer->children().size(); ++i) {
- if (TextureMapperNode* child = toTextureMapperNode(m_layer->children()[i])) {
- if (!child)
- continue;
- m_children.append(child);
- child->m_parent = this;
- }
- }
- m_state.dirty = true;
- }
-
- if (m_changeMask & (SizeChange | ContentsRectChange)) {
- IntSize wantedSize = IntSize(m_layer->size().width(), m_layer->size().height());
- if (wantedSize.isEmpty() && m_pendingContent.contentType == HTMLContentType)
- wantedSize = IntSize(m_layer->contentsRect().width(), m_layer->contentsRect().height());
-
- if (wantedSize != m_size) {
- m_size = IntSize(wantedSize.width(), wantedSize.height());
- if (m_platformClient)
- m_platformClient->setSizeChanged(m_size);
- const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000;
- if (m_state.tiled != needsTiling)
- m_state.tiled = needsTiling;
- m_state.dirty = true;
- }
- }
-
- if (m_changeMask & MaskLayerChange) {
- if (TextureMapperNode* layer = toTextureMapperNode(m_layer->maskLayer()))
- layer->m_effectTarget = this;
- }
-
- if (m_changeMask & ReplicaLayerChange) {
- if (TextureMapperNode* layer = toTextureMapperNode(m_layer->replicaLayer()))
- layer->m_effectTarget = this;
- }
-
- if (m_changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange))
- m_transforms.localDirty = true;
-
- if (m_changeMask & (ChildrenTransformChange | SizeChange))
- m_transforms.perspectiveDirty = true;
-
- if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange)) {
- // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
- // all these elements affect the transforms of all the descendants.
- needsToInvalidateTransform = true;
- }
-
- if (m_changeMask & DisplayChange)
- m_state.dirty = true;
-
- m_state.maskLayer = toTextureMapperNode(m_layer->maskLayer());
- m_state.replicaLayer = toTextureMapperNode(m_layer->replicaLayer());
- m_state.pos = m_layer->position();
- m_state.anchorPoint = m_layer->anchorPoint();
- m_state.size = m_layer->size();
- m_state.transform = m_layer->transform();
- m_state.contentsRect = m_layer->contentsRect();
- m_state.opacity = m_layer->opacity();
- m_state.contentsRect = m_layer->contentsRect();
- m_state.preserves3D = m_layer->preserves3D();
- m_state.masksToBounds = m_layer->masksToBounds();
- m_state.drawsContent = m_layer->drawsContent();
- m_state.contentsOpaque = m_layer->contentsOpaque();
- m_state.backfaceVisibility = m_layer->backfaceVisibility();
- m_state.childrenTransform = m_layer->childrenTransform();
- m_currentContent.contentType = m_pendingContent.contentType;
- m_currentContent.image = m_pendingContent.image;
- m_currentContent.media = m_pendingContent.media;
- m_currentContent.backgroundColor = m_pendingContent.backgroundColor;
- m_currentContent.needsDisplay = m_currentContent.needsDisplay || m_pendingContent.needsDisplay;
- m_currentContent.needsDisplayRect.unite(m_pendingContent.needsDisplayRect);
+ m_syncQueued = false;
+ m_changeMask = 0;
m_pendingContent.needsDisplay = false;
m_pendingContent.needsDisplayRect = IntRect();
- m_changeMask = NoChanges;
- afterCurrentLayerSync:
- if (needsToInvalidateTransform)
- invalidateTransform();
-
- if (m_state.maskLayer) {
- m_state.maskLayer->syncCompositingState(false);
- if (m_state.maskLayer->m_size.isEmpty())
- m_state.maskLayer->m_size = m_size;
- }
-
- if (m_state.replicaLayer)
- m_state.replicaLayer->syncCompositingState(false);
-
-#if 0
- if (m_state.dirty && m_texture && m_texture->allowOfflineTextureUpload())
- uploadTextureFromContent(0);
-#endif
-
- if (!recurse)
- return;
-
- const int childrenSize = m_children.size();
- for (int i = childrenSize-1; i >= 0; --i)
- m_children[i]->syncCompositingState(true);
-}
-
-GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)
- : GraphicsLayer(client)
- , m_node(new TextureMapperNode(this))
-{
}
void GraphicsLayerTextureMapper::setName(const String& name)
{
- m_node->m_name = name;
+ GraphicsLayer::setName(name);
}
GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()
@@ -1101,25 +60,25 @@ GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()
*/
void GraphicsLayerTextureMapper::setNeedsDisplay()
{
- m_node->m_pendingContent.needsDisplay = true;
- m_node->notifyChange(TextureMapperNode::DisplayChange);
+ m_pendingContent.needsDisplay = true;
+ notifyChange(TextureMapperNode::DisplayChange);
}
/* \reimp (GraphicsLayer.h)
*/
void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)
{
- if (m_node->m_pendingContent.needsDisplay)
+ if (m_pendingContent.needsDisplay)
return;
- m_node->m_pendingContent.needsDisplayRect.unite(IntRect(rect));
- m_node->notifyChange(TextureMapperNode::DisplayChange);
+ m_pendingContent.needsDisplayRect.unite(IntRect(rect));
+ notifyChange(TextureMapperNode::DisplayChange);
}
/* \reimp (GraphicsLayer.h)
*/
void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer)
{
- m_node->notifyChange(TextureMapperNode::ParentChange);
+ notifyChange(TextureMapperNode::ParentChange);
GraphicsLayer::setParent(layer);
}
@@ -1127,7 +86,7 @@ void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer)
*/
bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children)
{
- m_node->notifyChange(TextureMapperNode::ChildrenChange);
+ notifyChange(TextureMapperNode::ChildrenChange);
return GraphicsLayer::setChildren(children);
}
@@ -1135,7 +94,7 @@ bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& child
*/
void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)
{
- m_node->notifyChange(TextureMapperNode::ChildrenChange);
+ notifyChange(TextureMapperNode::ChildrenChange);
GraphicsLayer::addChild(layer);
}
@@ -1144,7 +103,7 @@ void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)
void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index)
{
GraphicsLayer::addChildAtIndex(layer, index);
- m_node->notifyChange(TextureMapperNode::ChildrenChange);
+ notifyChange(TextureMapperNode::ChildrenChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1152,7 +111,7 @@ void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index
void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
{
GraphicsLayer::addChildAbove(layer, sibling);
- m_node->notifyChange(TextureMapperNode::ChildrenChange);
+ notifyChange(TextureMapperNode::ChildrenChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1161,7 +120,7 @@ void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLay
{
GraphicsLayer::addChildBelow(layer, sibling);
- m_node->notifyChange(TextureMapperNode::ChildrenChange);
+ notifyChange(TextureMapperNode::ChildrenChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1169,10 +128,9 @@ void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLay
bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
{
if (GraphicsLayer::replaceChild(oldChild, newChild)) {
- m_node->notifyChange(TextureMapperNode::ChildrenChange);
+ notifyChange(TextureMapperNode::ChildrenChange);
return true;
}
-
return false;
}
@@ -1182,7 +140,7 @@ void GraphicsLayerTextureMapper::removeFromParent()
{
if (!parent())
return;
- m_node->notifyChange(TextureMapperNode::ParentChange);
+ notifyChange(TextureMapperNode::ParentChange);
GraphicsLayer::removeFromParent();
}
@@ -1193,7 +151,7 @@ void GraphicsLayerTextureMapper::setMaskLayer(GraphicsLayer* value)
if (value == maskLayer())
return;
GraphicsLayer::setMaskLayer(value);
- m_node->notifyChange(TextureMapperNode::MaskLayerChange);
+ notifyChange(TextureMapperNode::MaskLayerChange);
}
@@ -1204,7 +162,7 @@ void GraphicsLayerTextureMapper::setReplicatedByLayer(GraphicsLayer* value)
if (value == replicaLayer())
return;
GraphicsLayer::setReplicatedByLayer(value);
- m_node->notifyChange(TextureMapperNode::ReplicaLayerChange);
+ notifyChange(TextureMapperNode::ReplicaLayerChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1214,7 +172,7 @@ void GraphicsLayerTextureMapper::setPosition(const FloatPoint& value)
if (value == position())
return;
GraphicsLayer::setPosition(value);
- m_node->notifyChange(TextureMapperNode::PositionChange);
+ notifyChange(TextureMapperNode::PositionChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1224,7 +182,7 @@ void GraphicsLayerTextureMapper::setAnchorPoint(const FloatPoint3D& value)
if (value == anchorPoint())
return;
GraphicsLayer::setAnchorPoint(value);
- m_node->notifyChange(TextureMapperNode::AnchorPointChange);
+ notifyChange(TextureMapperNode::AnchorPointChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1235,7 +193,7 @@ void GraphicsLayerTextureMapper::setSize(const FloatSize& value)
return;
GraphicsLayer::setSize(value);
- m_node->notifyChange(TextureMapperNode::SizeChange);
+ notifyChange(TextureMapperNode::SizeChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1246,7 +204,7 @@ void GraphicsLayerTextureMapper::setTransform(const TransformationMatrix& value)
return;
GraphicsLayer::setTransform(value);
- m_node->notifyChange(TextureMapperNode::TransformChange);
+ notifyChange(TextureMapperNode::TransformChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1256,7 +214,7 @@ void GraphicsLayerTextureMapper::setChildrenTransform(const TransformationMatrix
if (value == childrenTransform())
return;
GraphicsLayer::setChildrenTransform(value);
- m_node->notifyChange(TextureMapperNode::ChildrenTransformChange);
+ notifyChange(TextureMapperNode::ChildrenTransformChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1266,7 +224,7 @@ void GraphicsLayerTextureMapper::setPreserves3D(bool value)
if (value == preserves3D())
return;
GraphicsLayer::setPreserves3D(value);
- m_node->notifyChange(TextureMapperNode::Preserves3DChange);
+ notifyChange(TextureMapperNode::Preserves3DChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1276,7 +234,7 @@ void GraphicsLayerTextureMapper::setMasksToBounds(bool value)
if (value == masksToBounds())
return;
GraphicsLayer::setMasksToBounds(value);
- m_node->notifyChange(TextureMapperNode::MasksToBoundsChange);
+ notifyChange(TextureMapperNode::MasksToBoundsChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1285,7 +243,7 @@ void GraphicsLayerTextureMapper::setDrawsContent(bool value)
{
if (value == drawsContent())
return;
- m_node->notifyChange(TextureMapperNode::DrawsContentChange);
+ notifyChange(TextureMapperNode::DrawsContentChange);
GraphicsLayer::setDrawsContent(value);
}
@@ -1293,22 +251,22 @@ void GraphicsLayerTextureMapper::setDrawsContent(bool value)
*/
void GraphicsLayerTextureMapper::setBackgroundColor(const Color& value)
{
- if (value == m_node->m_pendingContent.backgroundColor)
+ if (value == m_pendingContent.backgroundColor)
return;
- m_node->m_pendingContent.backgroundColor = value;
+ m_pendingContent.backgroundColor = value;
GraphicsLayer::setBackgroundColor(value);
- m_node->notifyChange(TextureMapperNode::BackgroundColorChange);
+ notifyChange(TextureMapperNode::BackgroundColorChange);
}
/* \reimp (GraphicsLayer.h)
*/
void GraphicsLayerTextureMapper::clearBackgroundColor()
{
- if (!m_node->m_pendingContent.backgroundColor.isValid())
+ if (!m_pendingContent.backgroundColor.isValid())
return;
- m_node->m_pendingContent.backgroundColor = Color();
+ m_pendingContent.backgroundColor = Color();
GraphicsLayer::clearBackgroundColor();
- m_node->notifyChange(TextureMapperNode::BackgroundColorChange);
+ notifyChange(TextureMapperNode::BackgroundColorChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1317,7 +275,7 @@ void GraphicsLayerTextureMapper::setContentsOpaque(bool value)
{
if (value == contentsOpaque())
return;
- m_node->notifyChange(TextureMapperNode::ContentsOpaqueChange);
+ notifyChange(TextureMapperNode::ContentsOpaqueChange);
GraphicsLayer::setContentsOpaque(value);
}
@@ -1328,7 +286,7 @@ void GraphicsLayerTextureMapper::setBackfaceVisibility(bool value)
if (value == backfaceVisibility())
return;
GraphicsLayer::setBackfaceVisibility(value);
- m_node->notifyChange(TextureMapperNode::BackfaceVisibilityChange);
+ notifyChange(TextureMapperNode::BackfaceVisibilityChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1338,7 +296,7 @@ void GraphicsLayerTextureMapper::setOpacity(float value)
if (value == opacity())
return;
GraphicsLayer::setOpacity(value);
- m_node->notifyChange(TextureMapperNode::OpacityChange);
+ notifyChange(TextureMapperNode::OpacityChange);
}
/* \reimp (GraphicsLayer.h)
@@ -1348,16 +306,16 @@ void GraphicsLayerTextureMapper::setContentsRect(const IntRect& value)
if (value == contentsRect())
return;
GraphicsLayer::setContentsRect(value);
- m_node->notifyChange(TextureMapperNode::ContentsRectChange);
+ notifyChange(TextureMapperNode::ContentsRectChange);
}
/* \reimp (GraphicsLayer.h)
*/
void GraphicsLayerTextureMapper::setContentsToImage(Image* image)
{
- m_node->notifyChange(TextureMapperNode::ContentChange);
- m_node->m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType;
- m_node->m_pendingContent.image = image;
+ notifyChange(TextureMapperNode::ContentChange);
+ m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType;
+ m_pendingContent.image = image;
GraphicsLayer::setContentsToImage(image);
}
@@ -1365,9 +323,9 @@ void GraphicsLayerTextureMapper::setContentsToImage(Image* image)
*/
void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color)
{
- m_node->notifyChange(TextureMapperNode::ContentChange);
- m_node->m_pendingContent.contentType = TextureMapperNode::ColorContentType;
- m_node->m_pendingContent.backgroundColor = color;
+ notifyChange(TextureMapperNode::ContentChange);
+ m_pendingContent.contentType = TextureMapperNode::ColorContentType;
+ m_pendingContent.backgroundColor = color;
GraphicsLayer::setContentsBackgroundColor(color);
}
@@ -1375,12 +333,12 @@ void GraphicsLayerTextureMapper::setContentsBackgroundColor(const Color& color)
void GraphicsLayerTextureMapper::setContentsToMedia(PlatformLayer* media)
{
GraphicsLayer::setContentsToMedia(media);
- m_node->notifyChange(TextureMapperNode::ContentChange);
- m_node->m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
+ notifyChange(TextureMapperNode::ContentChange);
+ m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
if (media)
- m_node->m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media);
+ m_pendingContent.media = static_cast<TextureMapperVideoLayer*>(media);
else
- m_node->m_pendingContent.media = 0;
+ m_pendingContent.media = 0;
}
/* \reimp (GraphicsLayer.h)
@@ -1389,7 +347,7 @@ void GraphicsLayerTextureMapper::setContentsOrientation(CompositingCoordinatesOr
{
if (contentsOrientation() == orientation)
return;
- m_node->notifyChange(TextureMapperNode::ContentsOrientationChange);
+ notifyChange(TextureMapperNode::ContentsOrientationChange);
GraphicsLayer::setContentsOrientation(orientation);
}
@@ -1397,17 +355,14 @@ void GraphicsLayerTextureMapper::setContentsOrientation(CompositingCoordinatesOr
*/
void GraphicsLayerTextureMapper::syncCompositingStateForThisLayerOnly()
{
- m_node->syncCompositingState(false);
- m_node->performPostSyncOperations();
+ m_node->syncCompositingState(this, false);
}
/* \reimp (GraphicsLayer.h)
*/
void GraphicsLayerTextureMapper::syncCompositingState()
{
- GraphicsLayer::syncCompositingState();
- m_node->syncCompositingState(true);
- m_node->performPostSyncOperations();
+ m_node->syncCompositingState(this, true);
}
/* \reimp (GraphicsLayer.h)
diff --git a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
index 36ebd74..85fa3ee 100644
--- a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
+++ b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
@@ -24,13 +24,12 @@
#include "GraphicsLayer.h"
#include "GraphicsLayerClient.h"
#include "Image.h"
+#include "TextureMapperNode.h"
#if ENABLE(3D_CANVAS)
#include "GraphicsContext3D.h"
#endif
-#define ENABLE_TEXMAP_ANIMATION 0
-
namespace WebCore {
class TextureMapperNode;
@@ -85,12 +84,24 @@ public:
virtual NativeLayer nativeLayer() const;
virtual PlatformLayer* platformLayer() const;
- virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*,
- const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
+ virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
+
+ void notifyChange(TextureMapperNode::ChangeMask changeMask);
+ inline TextureMapperNode::ContentData& pendingContent() { return m_pendingContent; }
+ inline int changeMask() const { return m_changeMask; }
+ void didSynchronize();
private:
OwnPtr<TextureMapperNode> m_node;
+ bool m_syncQueued;
+ int m_changeMask;
+ TextureMapperNode::ContentData m_pendingContent;
};
+inline static GraphicsLayerTextureMapper* toGraphicsLayerTextureMapper(GraphicsLayer* layer)
+{
+ return static_cast<GraphicsLayerTextureMapper*>(layer);
+}
+
}
#endif // GraphicsLayerTextureMapper_h
diff --git a/WebCore/platform/graphics/texmap/TextureMapper.h b/WebCore/platform/graphics/texmap/TextureMapper.h
index 03c1c6d..250125b 100644
--- a/WebCore/platform/graphics/texmap/TextureMapper.h
+++ b/WebCore/platform/graphics/texmap/TextureMapper.h
@@ -57,6 +57,10 @@ public:
m_contentSize = size;
}
+ virtual void pack() { }
+ virtual void unpack() { }
+ virtual bool isPacked() const { return false; }
+
virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect) = 0;
virtual void endPaint() = 0;
virtual PlatformGraphicsContext* beginPaintMedia()
@@ -72,6 +76,9 @@ public:
inline IntSize contentSize() const { return m_contentSize; }
inline void setOffset(const IntPoint& o) { m_offset = o; }
inline IntPoint offset() const { return m_offset; }
+
+protected:
+
private:
int m_lockCount;
IntSize m_contentSize;
@@ -81,11 +88,11 @@ private:
// A "context" class used to encapsulate accelerated texture mapping functions: i.e. drawing a texture
// onto the screen or into another texture with a specified transform, opacity and mask.
-class TextureMapper : public RefCounted<TextureMapper> {
+class TextureMapper {
friend class BitmapTexture;
public:
- static PassRefPtr<TextureMapper> create(GraphicsContext*);
+ static PassOwnPtr<TextureMapper> create(GraphicsContext* graphicsContext = 0);
virtual ~TextureMapper() { }
virtual void drawTexture(const BitmapTexture& texture, const IntRect& target, const TransformationMatrix& matrix = TransformationMatrix(), float opacity = 1.0f, const BitmapTexture* maskTexture = 0) = 0;
@@ -97,20 +104,28 @@ public:
drawTexture(texture, IntRect(0, 0, texture.contentSize().width(), texture.contentSize().height()), matrix, opacity, 0);
}
+ virtual void setGraphicsContext(GraphicsContext*) { }
virtual void setClip(const IntRect&) = 0;
virtual bool allowSurfaceForRoot() const = 0;
virtual PassRefPtr<BitmapTexture> createTexture() = 0;
- virtual const char* type() const = 0;
- virtual void cleanup() {}
- GraphicsContext* graphicsContext() const
- {
- return m_gc;
- }
+ void setImageInterpolationQuality(InterpolationQuality quality) { m_interpolationQuality = quality; }
+ void setTextDrawingMode(int mode) { m_textDrawingMode = mode; }
+
+ InterpolationQuality imageInterpolationQuality() const { return m_interpolationQuality; }
+ int textDrawingMode() const { return m_textDrawingMode; }
+
+ void setViewportSize(const IntSize&);
protected:
- TextureMapper(GraphicsContext* gc) : m_gc(gc) {}
- GraphicsContext* m_gc;
+ TextureMapper()
+ : m_interpolationQuality(InterpolationDefault)
+ , m_textDrawingMode(cTextFill)
+ {}
+
+private:
+ InterpolationQuality m_interpolationQuality;
+ int m_textDrawingMode;
};
};
diff --git a/WebCore/platform/graphics/texmap/TextureMapperNode.cpp b/WebCore/platform/graphics/texmap/TextureMapperNode.cpp
new file mode 100644
index 0000000..09051f9
--- /dev/null
+++ b/WebCore/platform/graphics/texmap/TextureMapperNode.cpp
@@ -0,0 +1,877 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ 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 "TextureMapperNode.h"
+
+#include "GraphicsLayerTextureMapper.h"
+
+namespace WebCore {
+
+class TextureMapperCache {
+public:
+ void mark(BitmapTexture* texture);
+
+ class Entry {
+ public:
+ RefPtr<BitmapTexture> texture;
+ Entry() : previousCost(0) { }
+ inline int computeCost() const
+ {
+ if (!texture || !texture->isValid() || texture->isPacked())
+ return 0;
+ const IntSize textureSize = texture->size();
+ // An image's cost in bytes is width * height * bytes per pixel (4).
+ return textureSize.width() * textureSize.height() * 4;
+ }
+ Entry(BitmapTexture* newTexture)
+ : texture(newTexture)
+ {
+ }
+ bool operator==(const Entry& other) const { return texture == other.texture; }
+ int previousCost;
+ };
+
+ TextureMapperCache()
+ : m_totalCost(0)
+ {
+ }
+
+ void purge();
+ Vector<Entry> m_data;
+ int m_totalCost;
+#ifndef TEXMAP_TEXTURE_CACHE_KBS
+#define TEXMAP_TEXTURE_CACHE_KBS 24 * 1024
+#endif
+ static const int MaxCost = TEXMAP_TEXTURE_CACHE_KBS * 1024;
+ static const int PurgeAmount = MaxCost / 4;
+};
+
+
+void TextureMapperCache::purge()
+{
+ const int size = m_data.size();
+
+ if (m_totalCost <= TextureMapperCache::MaxCost)
+ return;
+
+ // Ensure that we have the right count. It might be inaccurate if content changed size.
+ // We only do this when we're actually ready to purge.
+ m_totalCost = 0;
+ for (int i = 0; i < size; ++i)
+ m_totalCost += m_data[i].computeCost();
+
+ for (int i = size-1; i >= 0 && m_totalCost > TextureMapperCache::MaxCost - TextureMapperCache::PurgeAmount; --i) {
+ Entry& entry = m_data[i];
+ if (entry.texture->isLocked() || !entry.texture->isValid() || entry.texture->isPacked())
+ continue;
+ m_totalCost -= entry.previousCost;
+ entry.texture->pack();
+ m_data.remove(i);
+ }
+}
+
+void TextureMapperCache::mark(BitmapTexture* texture)
+{
+ if (!texture || !texture->isValid())
+ return;
+
+ Entry entry(texture);
+ size_t index = m_data.find(entry);
+ if (!index)
+ return;
+
+ int previousCost = 0;
+
+ if (index < m_data.size()) {
+ previousCost = m_data[index].previousCost;
+ m_data.remove(index);
+ }
+ const int cost = entry.computeCost();
+ m_totalCost -= previousCost;
+ m_totalCost += (entry.previousCost = cost);
+ m_data.prepend(entry);
+}
+
+class TextureMapperCacheLock {
+public:
+ TextureMapperCacheLock(BitmapTexture* texture) : m_texture(texture)
+ {
+ if (m_texture)
+ m_texture->lock();
+ }
+ ~TextureMapperCacheLock()
+ {
+ if (m_texture)
+ m_texture->unlock();
+ }
+
+private:
+ RefPtr<BitmapTexture> m_texture;
+};
+
+
+TextureMapperCache* TextureMapperNode::cache()
+{
+ TextureMapperNode* root = rootLayer();
+ if (!root)
+ return 0;
+ if (!root->m_cache)
+ root->m_cache = new TextureMapperCache;
+ return root->m_cache;
+}
+
+void TextureMapperNode::setNeedsDisplayInRect(IntRect rect)
+{
+ if (m_platformClient) {
+ if (m_state.hasSurfaceDescendants) {
+ m_platformClient->setNeedsDisplay();
+ return;
+ }
+ rect.intersect(IntRect(0, 0, m_size.width(), m_size.height()));
+ if (rect.isEmpty())
+ return;
+ m_platformClient->setNeedsDisplayInRect(rect);
+ return;
+ }
+
+ if (!m_parent)
+ return;
+
+ m_parent->setNeedsDisplayInRect(rect);
+}
+
+void TextureMapperNode::setNeedsDisplay()
+{
+ if (m_effectTarget)
+ m_effectTarget->setNeedsDisplay();
+ if (m_transforms.targetBoundingRect.isEmpty())
+ return;
+ if (m_state.drawsContent || m_currentContent.contentType != HTMLContentType)
+ setNeedsDisplayInRect(m_transforms.targetBoundingRect);
+}
+
+void TextureMapperNode::setPlatformLayerClient(TextureMapperLayerClient* client)
+{
+ m_platformClient = client;
+}
+
+int TextureMapperNode::compareGraphicsLayersZValue(const void* a, const void* b)
+{
+ typedef const TextureMapperNode* NodePtr;
+ const NodePtr* nodeA = static_cast<const NodePtr*>(a);
+ const NodePtr* nodeB = static_cast<const NodePtr*>(b);
+ return int(((*nodeA)->m_transforms.centerZ - (*nodeB)->m_transforms.centerZ) * 1000);
+}
+
+void TextureMapperNode::sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last)
+{
+ qsort(array.data(), array.size(), sizeof(TextureMapperNode*), TextureMapperNode::compareGraphicsLayersZValue);
+}
+
+bool TextureMapperNode::hasSurfaceDescendants() const
+{
+ if (m_layerType == ClipLayer || m_layerType == TransparencyLayer || m_state.replicaLayer)
+ return true;
+
+ const int size = m_children.size();
+ for (int i = 0; i < size; ++i) {
+ if (TextureMapperNode* child = m_children[i]) {
+ if (child->hasSurfaceDescendants())
+ return true;
+ }
+ }
+ return false;
+}
+
+int TextureMapperNode::countDescendantsWithContent() const
+{
+ if (!m_state.visible || m_state.opacity < 0.001)
+ return 0;
+
+ int descendantsWithContent = (m_state.drawsContent || m_currentContent.contentType != HTMLContentType) ? 1 : 0;
+
+ const int size = m_children.size();
+ for (int i = 0; i < size; ++i) {
+ if (TextureMapperNode* child = m_children[i])
+ descendantsWithContent += child->countDescendantsWithContent();
+ }
+
+ return descendantsWithContent;
+}
+
+TextureMapperNode* TextureMapperNode::toTextureMapperNode(GraphicsLayer* layer)
+{
+ return layer ? static_cast<TextureMapperNode*>(layer->platformLayer()) : 0;
+}
+
+void TextureMapperNode::computeLayerType()
+{
+ const bool selfHasContent = m_state.drawsContent || (m_currentContent.contentType != HTMLContentType);
+ const bool hasDescendantsWithContent = m_state.descendantsWithContent - (selfHasContent ? 1 : 0);
+ const bool hasTransparency = m_state.opacity < 0.99 || m_state.maskLayer;
+ const bool hasReplica = m_state.replicaLayer;
+
+ // DefaultLayer: draws itself and its children directly to the current framebuffer.
+ // any layer that doesn't conform to the other rules is a DefaultLayer.
+ m_layerType = DefaultLayer;
+
+ // RootLayer: the top level. Draws to a framebuffer, and the target texture draws into the viewport.
+ // only one layer is the root layer.
+ if (!m_parent && !m_effectTarget) {
+ m_layerType = RootLayer;
+ return;
+ }
+
+ // A layer with no contents is always a default layer.
+ if (!m_state.descendantsWithContent)
+ return;
+
+ // ClipLayer: creates a new framebuffer, the size of the layer, and then paints it to the enclosing BitmapTexture with the layer's transform/opacity.
+ // A clip layer is a layer that masks to bounds, doesn't preserve 3D, has children, and has a transparency/mask or a non-rectangular transform.
+ if (hasDescendantsWithContent && m_state.maskLayer) {
+ m_layerType = ClipLayer;
+ return;
+ }
+
+ // ScissorLayer: draws to the current framebuffer, and applies an extra scissor before drawing its children.
+ // A scissor layer is a layer with children that masks to bounds, is not a transparency layer, and has a rectangular clip.
+ if (m_state.masksToBounds && hasDescendantsWithContent) {
+ if (hasTransparency || !m_state.transform.isIdentityOrTranslation() || m_parent->m_state.preserves3D)
+ m_layerType = ClipLayer;
+ else
+ m_layerType = ScissorLayer;
+ return;
+ }
+
+ // TransparencyLayer: creates a new framebuffer idetical in size to the current framebuffer. Then draws the fb's texture to the current framebuffer with identity transform.
+ // Used for layers with children and transparency/mask that preserve 3D or don't mask to bounds.
+ if ((hasReplica && hasDescendantsWithContent) || (hasReplica && hasTransparency) || (hasTransparency && m_state.descendantsWithContent > 1))
+ m_layerType = TransparencyLayer;
+}
+
+void TextureMapperNode::initializeTextureMapper(TextureMapper* textureMapper)
+{
+ if (m_texture)
+ return;
+ m_surface = textureMapper->createTexture();
+ m_replicaSurface = textureMapper->createTexture();
+ m_texture = textureMapper->createTexture();
+ cache()->mark(m_texture.get());
+}
+
+TextureMapperNode::TextureMapperNode()
+ : m_layerType(DefaultLayer)
+ , m_surface(0)
+ , m_parent(0)
+ , m_effectTarget(0)
+ , m_platformClient(0)
+ , m_cache(0)
+{
+}
+
+TextureMapperNode* TextureMapperNode::rootLayer()
+{
+ if (m_effectTarget)
+ return m_effectTarget->rootLayer();
+ if (m_parent)
+ return m_parent->rootLayer();
+ return this;
+}
+
+void TextureMapperNode::invalidateTransform()
+{
+ m_transforms.dirty = true;
+ if (m_layerType != ClipLayer)
+ m_state.dirty = true;
+ if (m_state.replicaLayer)
+ m_state.replicaLayer->invalidateTransform();
+ const int size = m_children.size();
+ for (int i = 0; i < size; ++i) {
+ if (TextureMapperNode* layer = m_children[i])
+ layer->invalidateTransform();
+ }
+}
+
+void TextureMapperNode::computeLocalTransform()
+{
+ if (!m_transforms.localDirty)
+ return;
+ const float originX = m_state.anchorPoint.x() * m_size.width();
+ const float originY = m_state.anchorPoint.y() * m_size.height();
+ m_transforms.local =
+ TransformationMatrix()
+ .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
+ .multLeft(m_state.transform)
+ .translate3d(-originX, -originY, -m_state.anchorPoint.z());
+ m_transforms.localDirty = false;
+}
+
+void TextureMapperNode::flattenTo2DSpaceIfNecessary()
+{
+ if (m_state.preserves3D)
+ return;
+
+ m_transforms.forDescendants.setM13(0);
+ m_transforms.forDescendants.setM23(0);
+ m_transforms.forDescendants.setM31(0);
+ m_transforms.forDescendants.setM32(0);
+ m_transforms.forDescendants.setM33(1);
+ m_transforms.forDescendants.setM34(0);
+ m_transforms.forDescendants.setM43(0);
+}
+
+IntSize TextureMapperNode::nearestSurfaceSize() const
+{
+ if (m_layerType == ClipLayer || m_layerType == RootLayer)
+ return m_surface && !m_surface->size().isEmpty() ? m_surface->size() : m_size;
+ return m_parent->nearestSurfaceSize();
+}
+
+void TextureMapperNode::computeReplicaTransform()
+{
+ if (!m_state.replicaLayer)
+ return;
+
+ m_nearestSurfaceSize = nearestSurfaceSize();
+
+ if (m_layerType != TransparencyLayer) {
+ m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local);
+ return;
+ }
+
+ const float originX = m_transforms.target.m41();
+ const float originY = m_transforms.target.m42();
+ m_transforms.replica =
+ TransformationMatrix()
+ .translate(originX, originY)
+ .multLeft(m_state.replicaLayer->m_transforms.local)
+ .translate(-originX, -originY);
+}
+
+void TextureMapperNode::computeTransformations()
+{
+ if (!m_transforms.dirty)
+ return;
+
+ m_transforms.dirty = false;
+ if ((m_size.isEmpty() && m_state.masksToBounds))
+ return;
+
+ TextureMapperNode* parent = m_parent;
+ computeLocalTransform();
+
+ m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local);
+ m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target);
+
+ if (m_effectTarget)
+ return;
+
+ m_transforms.targetBoundingRect = IntRect(m_transforms.target.mapRect(entireRect()));
+ if (m_state.replicaLayer)
+ m_state.replicaLayer->computeTransformations();
+
+ flattenTo2DSpaceIfNecessary();
+
+ if (!m_state.backfaceVisibility && m_transforms.target.inverse().m33() < 0) {
+ m_state.visible = false;
+ return;
+ }
+ m_state.visible = true;
+
+ if (parent && parent->m_state.preserves3D)
+ m_transforms.centerZ = m_transforms.target.mapPoint(FloatPoint3D(m_size.width() / 2, m_size.height() / 2, 0)).z();
+
+ if (!m_children.size())
+ return;
+
+ if (m_state.childrenTransform.isIdentity())
+ return;
+
+ const FloatPoint centerPoint = FloatPoint(m_size.width() / 2, m_size.height() / 2);
+ if (m_transforms.perspectiveDirty)
+ m_transforms.perspective = TransformationMatrix()
+ .translate(centerPoint.x(), centerPoint.y())
+ .multLeft(m_state.childrenTransform)
+ .translate(-centerPoint.x(), -centerPoint.y());
+ m_transforms.perspectiveDirty = false;
+ m_transforms.forDescendants.multLeft(m_transforms.perspective);
+}
+
+void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer)
+{
+ if (m_size.isEmpty() || !layer) {
+ m_texture->destroy();
+ return;
+ }
+
+ if (m_currentContent.contentType == DirectImageContentType) {
+ if (m_currentContent.image)
+ m_texture->setContentsToImage(m_currentContent.image.get());
+ return;
+ }
+
+ if (m_currentContent.contentType == MediaContentType) {
+ if (!m_currentContent.media)
+ return;
+ m_texture->reset(m_size, true);
+ PlatformGraphicsContext* platformContext = m_texture->beginPaintMedia();
+ GraphicsContext context(platformContext);
+ m_currentContent.media->paint(&context);
+ m_texture->endPaint();
+ return;
+ }
+
+ const bool needsReset = (m_texture->contentSize() != m_size) || !m_texture->isValid();
+ if ((m_currentContent.contentType != HTMLContentType)
+ || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset))
+ return;
+
+ IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height());
+ if (!needsReset && !m_currentContent.needsDisplay)
+ dirtyRect.intersect(m_currentContent.needsDisplayRect);
+
+ if (needsReset)
+ m_texture->reset(m_size, m_state.contentsOpaque);
+
+ {
+ GraphicsContext context(m_texture->beginPaint(dirtyRect));
+ if (textureMapper) {
+ context.setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
+ context.setTextDrawingMode(textureMapper->textDrawingMode());
+ }
+ layer->paintGraphicsLayerContents(context, dirtyRect);
+ }
+ m_texture->endPaint();
+ m_currentContent.needsDisplay = false;
+}
+
+
+void TextureMapperNode::paint(TextureMapper* textureMapper, const TextureMapperContentLayer::PaintOptions& options)
+{
+ ASSERT(m_layerType == RootLayer);
+ if (m_size.isEmpty())
+ return;
+
+ TexmapPaintOptions opt;
+ opt.opacity = 1;
+ opt.rootLayer = this;
+ opt.scissorRect = options.targetRect;
+ opt.visibleRect = options.visibleRect;
+ opt.textureMapper = textureMapper;
+ opt.surface = 0;
+ opt.cache = m_cache;
+ paintRecursive(opt);
+
+ if (textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants) {
+ textureMapper->bindSurface(0);
+ textureMapper->paintToTarget(*m_surface.get(), options.viewportSize, options.transform, options.opacity * m_state.opacity, options.targetRect);
+ }
+ m_cache->purge();
+}
+
+void TextureMapperNode::paintSelf(const TexmapPaintOptions& options)
+{
+ if (m_size.isEmpty() || (!m_state.drawsContent && m_currentContent.contentType == HTMLContentType))
+ return;
+
+ RefPtr<BitmapTexture> replicaMaskTexture;
+ m_texture->unpack();
+
+ RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->m_texture : 0;
+ if (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer)
+ replicaMaskTexture = m_state.replicaLayer->m_state.maskLayer->m_texture;
+
+ if (maskTexture)
+ maskTexture->unpack();
+
+ if (replicaMaskTexture)
+ replicaMaskTexture->unpack();
+
+ const float opacity = options.isSurface ? 1 : options.opacity;
+
+ if (m_state.replicaLayer && !options.isSurface)
+ options.textureMapper->drawTexture(*m_texture.get(), replicaRect(), m_transforms.replica,
+ opacity * m_state.replicaLayer->m_state.opacity,
+ replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
+
+ const IntRect rect = m_layerType == ClipLayer ? entireRect() : targetRect();
+ const TransformationMatrix transform = m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target;
+ options.textureMapper->drawTexture(*m_texture.get(), rect, transform, opacity, options.isSurface ? 0 : maskTexture.get());
+ options.cache->mark(m_texture.get());
+}
+
+bool TextureMapperNode::paintReplica(const TexmapPaintOptions& options)
+{
+ BitmapTexture& texture = *m_surface.get();
+ TextureMapperNode* replica = m_state.replicaLayer;
+ RefPtr<BitmapTexture> maskTexture;
+ if (TextureMapperNode* mask = m_state.maskLayer)
+ maskTexture = mask->m_texture;
+ RefPtr<BitmapTexture> replicaMaskTexture;
+ if (!replica)
+ return false;
+
+ if (replica && replica->m_state.maskLayer)
+ replicaMaskTexture = replica->m_state.maskLayer->m_texture;
+
+ if (replicaMaskTexture)
+ replicaMaskTexture->unpack();
+ ASSERT(m_replicaSurface);
+ m_replicaSurface->reset(options.surface->size());
+ m_replicaSurface->setOffset(options.surface->offset());
+ options.cache->mark(m_replicaSurface.get());
+ options.textureMapper->bindSurface(m_replicaSurface.get());
+ options.textureMapper->drawTexture(texture, replicaRect(), m_transforms.replica, replica->m_state.opacity, replicaMaskTexture ? replicaMaskTexture.get() : maskTexture.get());
+ options.textureMapper->drawTexture(texture, IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), 1.0f, maskTexture.get());
+ options.textureMapper->bindSurface(options.surface);
+ options.cache->mark(options.surface);
+ options.textureMapper->drawTexture(*m_replicaSurface.get(), IntRect(IntPoint(0, 0), options.surface->size()), TransformationMatrix(), options.opacity, 0);
+ return true;
+}
+
+void TextureMapperNode::paintSurface(const TexmapPaintOptions& options)
+{
+ if (m_layerType == RootLayer || m_layerType == DefaultLayer || m_layerType == ScissorLayer)
+ return;
+
+ RefPtr<BitmapTexture> maskTexture;
+ if (TextureMapperNode* mask = m_state.maskLayer)
+ maskTexture = mask->m_texture;
+
+ ASSERT(m_surface);
+ BitmapTexture& texture = *m_surface.get();
+ if (maskTexture)
+ maskTexture->unpack();
+ texture.unpack();
+
+ if (paintReplica(options))
+ return;
+
+ options.textureMapper->bindSurface(options.surface);
+ options.textureMapper->drawTexture(texture,
+ m_layerType == TransparencyLayer ? IntRect(IntPoint(0, 0), options.surface->size()) :
+ targetRect(),
+ m_layerType == TransparencyLayer ? TransformationMatrix() : m_transforms.target,
+ options.opacity, maskTexture.get());
+ options.cache->mark(&texture);
+}
+
+void TextureMapperNode::paintSelfAndChildren(const TexmapPaintOptions& options, TexmapPaintOptions& optionsForDescendants)
+{
+ bool didPaintSelf = false;
+ if (!m_state.preserves3D || m_children.isEmpty()) {
+ paintSelf(options);
+ didPaintSelf = true;
+ }
+
+ if (m_children.isEmpty() && !options.isSurface)
+ return;
+
+ if (m_layerType == ScissorLayer)
+ optionsForDescendants.scissorRect.intersect(m_transforms.target.mapRect(IntRect(0, 0, m_size.width(), m_size.height())));
+
+ for (int i = 0; i < m_children.size(); ++i) {
+ TextureMapperNode* layer = m_children[i];
+ if (!layer)
+ continue;
+
+ if (!didPaintSelf && layer->m_transforms.centerZ >= 0) {
+ paintSelf(options);
+ didPaintSelf = true;
+ }
+ layer->paintRecursive(optionsForDescendants);
+ if (options.isSurface) {
+ ASSERT(m_surface);
+ options.cache->mark(m_surface.get());
+ options.textureMapper->bindSurface(m_surface.get());
+ }
+ }
+ if (!didPaintSelf) {
+ paintSelf(options);
+ didPaintSelf = true;
+ }
+}
+
+void TextureMapperNode::paintRecursive(TexmapPaintOptions options)
+{
+ bool isDirty = m_state.dirty;
+ m_state.dirty = false;
+
+ if ((m_size.isEmpty() && (m_state.masksToBounds
+ || m_children.isEmpty())) || !m_state.visible || options.opacity < 0.01 || m_state.opacity < 0.01)
+ return;
+
+ computeReplicaTransform();
+
+ if (m_state.maskLayer)
+ m_state.maskLayer->m_state.dirty = false;
+
+ if (m_state.replicaLayer) {
+ m_state.replicaLayer->m_state.dirty = false;
+ if (m_state.replicaLayer->m_state.maskLayer)
+ m_state.replicaLayer->m_state.maskLayer->m_state.dirty = false;
+ }
+
+ const bool isSurface = (m_layerType == ClipLayer
+ || m_layerType == TransparencyLayer
+ || (m_layerType == RootLayer
+ && (options.textureMapper->allowSurfaceForRoot() || m_state.hasSurfaceDescendants)
+ ));
+
+ const IntRect boundingRectfromNearestSurface = m_transforms.targetBoundingRect;
+
+ options.opacity *= m_state.opacity;
+
+ TexmapPaintOptions optionsForDescendants(options);
+ optionsForDescendants.opacity = isSurface ? 1 : options.opacity;
+ options.isSurface = isSurface;
+
+ if (m_layerType == ClipLayer) {
+ optionsForDescendants.visibleRect = TransformationMatrix().translate(-boundingRectfromNearestSurface.x(), -boundingRectfromNearestSurface.y()).mapRect(options.visibleRect);
+ optionsForDescendants.scissorRect = IntRect(0, 0, m_size.width(), m_size.height());
+ }
+
+ if (m_layerType == ScissorLayer)
+ optionsForDescendants.scissorRect.intersect(m_transforms.targetBoundingRect);
+ options.textureMapper->setClip(optionsForDescendants.scissorRect);
+
+ TextureMapperCacheLock(m_texture.get());
+ TextureMapperCacheLock(m_surface.get());
+ TextureMapperCacheLock(m_replicaSurface.get());
+
+ options.cache->purge();
+
+ if (isSurface) {
+ ASSERT(m_surface);
+ if (!m_surface->isValid())
+ isDirty = true;
+ if (m_state.tiled) {
+ m_surface->reset(options.visibleRect.size());
+ m_surface->setOffset(options.visibleRect.location());
+ } else if (isDirty)
+ m_surface->reset(m_layerType == TransparencyLayer ? options.surface->size() : m_size);
+ options.cache->mark(m_surface.get());
+ options.textureMapper->bindSurface(m_surface.get());
+ optionsForDescendants.surface = m_surface.get();
+ } else if (m_surface)
+ m_surface->destroy();
+
+ if (isDirty || !isSurface || m_state.tiled || !m_surface->isValid())
+ paintSelfAndChildren(options, optionsForDescendants);
+
+ paintSurface(options);
+}
+
+TextureMapperNode::~TextureMapperNode()
+{
+ setNeedsDisplay();
+ {
+ const int childrenSize = m_children.size();
+ for (int i = childrenSize-1; i >= 0; --i) {
+ ASSERT(m_children[i]->m_parent == this);
+ m_children[i]->m_parent = 0;
+ }
+ }
+ if (m_parent)
+ m_parent->m_children.remove(m_parent->m_children.find(this));
+ if (m_cache)
+ delete m_cache;
+}
+
+void TextureMapperNode::performPostSyncOperations()
+{
+ const LayerType prevLayerType = m_layerType;
+ computeLayerType();
+ if (prevLayerType != m_layerType)
+ m_state.dirty = true;
+ if (m_transforms.dirty)
+ setNeedsDisplay();
+
+ computeTransformations();
+ if (m_state.maskLayer && !m_state.dirty)
+ m_state.dirty = m_state.maskLayer->m_state.dirty;
+ if (m_state.replicaLayer && !m_state.dirty)
+ m_state.dirty = m_state.replicaLayer->m_state.dirty;
+
+ const int size = m_children.size();
+
+ for (int i = size - 1; i >= 0; --i) {
+ TextureMapperNode* layer = m_children[i];
+
+ layer->performPostSyncOperations();
+ if (!m_state.dirty)
+ m_state.dirty = layer->m_state.dirty;
+ }
+ m_state.hasSurfaceDescendants = hasSurfaceDescendants();
+ if (m_state.dirty)
+ m_state.descendantsWithContent = countDescendantsWithContent();
+
+ if (m_state.preserves3D)
+ sortByZOrder(m_children, 0, size);
+ if (m_state.dirty)
+ setNeedsDisplay();
+}
+
+void TextureMapperNode::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, bool recurse)
+{
+ TextureMapper* textureMapper = rootLayer()->m_platformClient->textureMapper();
+ syncCompositingStateInternal(graphicsLayer, recurse, textureMapper);
+ performPostSyncOperations();
+}
+
+void TextureMapperNode::syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper)
+{
+ const int changeMask = graphicsLayer->changeMask();
+ initializeTextureMapper(textureMapper);
+ const TextureMapperNode::ContentData& pendingContent = graphicsLayer->pendingContent();
+ if (changeMask == NoChanges && pendingContent.needsDisplayRect.isEmpty() && !pendingContent.needsDisplay)
+ return;
+
+ setNeedsDisplay();
+ if (m_parent)
+ m_parent->m_state.dirty = true;
+
+ if (m_currentContent.contentType == HTMLContentType && (changeMask & ParentChange)) {
+ // The WebCore compositor manages item ownership. We have to make sure graphicsview doesn't
+ // try to snatch that ownership.
+
+ if (!graphicsLayer->parent())
+ m_parent = 0;
+ else
+ m_parent = toTextureMapperNode(graphicsLayer->parent());
+
+ if (!graphicsLayer->parent() && m_parent) {
+ size_t index = m_parent->m_children.find(this);
+ m_parent->m_children.remove(index);
+ }
+ }
+
+ if (changeMask & ChildrenChange) {
+ m_children.clear();
+ for (size_t i = 0; i < graphicsLayer->children().size(); ++i) {
+ if (TextureMapperNode* child = toTextureMapperNode(graphicsLayer->children()[i])) {
+ if (!child)
+ continue;
+ m_children.append(child);
+ child->m_parent = this;
+ }
+ }
+ m_state.dirty = true;
+ }
+
+ if (changeMask & (SizeChange | ContentsRectChange)) {
+ IntSize wantedSize = IntSize(graphicsLayer->size().width(), graphicsLayer->size().height());
+ if (wantedSize.isEmpty() && pendingContent.contentType == HTMLContentType)
+ wantedSize = IntSize(graphicsLayer->contentsRect().width(), graphicsLayer->contentsRect().height());
+
+ if (wantedSize != m_size) {
+ m_size = IntSize(wantedSize.width(), wantedSize.height());
+ if (m_platformClient)
+ m_platformClient->setSizeChanged(m_size);
+ const bool needsTiling = m_size.width() > 2000 || m_size.height() > 2000;
+ if (m_state.tiled != needsTiling)
+ m_state.tiled = needsTiling;
+ m_state.dirty = true;
+ }
+ }
+
+ if (changeMask & MaskLayerChange) {
+ if (TextureMapperNode* layer = toTextureMapperNode(graphicsLayer->maskLayer()))
+ layer->m_effectTarget = this;
+ }
+
+ if (changeMask & ReplicaLayerChange) {
+ if (TextureMapperNode* layer = toTextureMapperNode(graphicsLayer->replicaLayer()))
+ layer->m_effectTarget = this;
+ }
+
+ if (changeMask & (TransformChange | SizeChange | AnchorPointChange | PositionChange))
+ m_transforms.localDirty = true;
+
+ if (changeMask & (ChildrenTransformChange | SizeChange))
+ m_transforms.perspectiveDirty = true;
+
+ if (changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | ContentsRectChange | BackfaceVisibilityChange | PositionChange | MaskLayerChange | DrawsContentChange | ContentChange | ReplicaLayerChange)) {
+ // Due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
+ // all these elements affect the transforms of all the descendants.
+ invalidateTransform();
+ }
+
+ if (changeMask & DisplayChange)
+ m_state.dirty = true;
+
+ m_state.maskLayer = toTextureMapperNode(graphicsLayer->maskLayer());
+ m_state.replicaLayer = toTextureMapperNode(graphicsLayer->replicaLayer());
+ m_state.pos = graphicsLayer->position();
+ m_state.anchorPoint = graphicsLayer->anchorPoint();
+ m_state.size = graphicsLayer->size();
+ m_state.transform = graphicsLayer->transform();
+ m_state.contentsRect = graphicsLayer->contentsRect();
+ m_state.opacity = graphicsLayer->opacity();
+ m_state.contentsRect = graphicsLayer->contentsRect();
+ m_state.preserves3D = graphicsLayer->preserves3D();
+ m_state.masksToBounds = graphicsLayer->masksToBounds();
+ m_state.drawsContent = graphicsLayer->drawsContent();
+ m_state.contentsOpaque = graphicsLayer->contentsOpaque();
+ m_state.backfaceVisibility = graphicsLayer->backfaceVisibility();
+ m_state.childrenTransform = graphicsLayer->childrenTransform();
+ m_currentContent.contentType = pendingContent.contentType;
+ m_currentContent.image = pendingContent.image;
+ m_currentContent.media = pendingContent.media;
+ m_currentContent.backgroundColor = pendingContent.backgroundColor;
+ m_currentContent.needsDisplay = m_currentContent.needsDisplay || pendingContent.needsDisplay;
+ m_currentContent.needsDisplayRect.unite(pendingContent.needsDisplayRect);
+
+}
+
+void TextureMapperNode::syncCompositingStateInternal(GraphicsLayerTextureMapper* graphicsLayer, bool recurse, TextureMapper* textureMapper)
+{
+ syncCompositingStateSelf(graphicsLayer, textureMapper);
+
+ graphicsLayer->didSynchronize();
+
+ if (m_state.maskLayer) {
+ m_state.maskLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), false, textureMapper);
+ if (m_state.maskLayer->m_size.isEmpty())
+ m_state.maskLayer->m_size = m_size;
+ }
+
+ if (m_state.replicaLayer)
+ m_state.replicaLayer->syncCompositingStateInternal(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), false, textureMapper);
+
+ if (m_state.dirty)
+ uploadTextureFromContent(textureMapper, m_state.visibleRect, graphicsLayer);
+
+ m_currentContent.needsDisplayRect = IntRect();
+ m_currentContent.needsDisplay = false;
+
+ if (!recurse)
+ return;
+
+ Vector<GraphicsLayer*> children = graphicsLayer->children();
+ for (int i = children.size() - 1; i >= 0; --i) {
+ TextureMapperNode* node = toTextureMapperNode(children[i]);
+ if (!node)
+ continue;
+ node->syncCompositingStateInternal(toGraphicsLayerTextureMapper(children[i]), true, textureMapper);
+ }
+}
+
+}
diff --git a/WebCore/platform/graphics/texmap/TextureMapperNode.h b/WebCore/platform/graphics/texmap/TextureMapperNode.h
new file mode 100644
index 0000000..9694043
--- /dev/null
+++ b/WebCore/platform/graphics/texmap/TextureMapperNode.h
@@ -0,0 +1,252 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ 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 TextureMapperNode_h
+#define TextureMapperNode_h
+
+#include "CurrentTime.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
+#include "HashMap.h"
+#include "Image.h"
+#include "RefCounted.h"
+#include "TextureMapper.h"
+#include "TextureMapperPlatformLayer.h"
+#include "Timer.h"
+#include "TransformOperations.h"
+#include "TranslateTransformOperation.h"
+#include "UnitBezier.h"
+
+namespace WebCore {
+
+class TextureMapperNode;
+class TextureMapperCache;
+class GraphicsLayerTextureMapper;
+
+struct TexmapPaintOptions {
+ BitmapTexture* surface;
+ TextureMapper* textureMapper;
+ TextureMapperNode* rootLayer;
+ float opacity;
+ IntRect scissorRect;
+ IntRect visibleRect;
+ bool isSurface;
+ TextureMapperCache* cache;
+};
+
+class TextureMapperNode : public TextureMapperContentLayer {
+
+public:
+ // This set of flags help us defer which properties of the layer have been
+ // modified by the compositor, so we can know what to look for in the next flush.
+ enum ChangeMask {
+ NoChanges = 0,
+
+ ParentChange = (1L << 0),
+ ChildrenChange = (1L << 1),
+ MaskLayerChange = (1L << 2),
+ PositionChange = (1L << 3),
+
+ AnchorPointChange = (1L << 4),
+ SizeChange = (1L << 5),
+ TransformChange = (1L << 6),
+ ContentChange = (1L << 7),
+
+ ContentsOrientationChange = (1L << 9),
+ OpacityChange = (1L << 10),
+ ContentsRectChange = (1L << 11),
+
+ Preserves3DChange = (1L << 12),
+ MasksToBoundsChange = (1L << 13),
+ DrawsContentChange = (1L << 14),
+ ContentsOpaqueChange = (1L << 15),
+
+ BackfaceVisibilityChange = (1L << 16),
+ ChildrenTransformChange = (1L << 17),
+ DisplayChange = (1L << 18),
+ BackgroundColorChange = (1L << 19),
+
+ ReplicaLayerChange = (1L << 20)
+ };
+ // The compositor lets us special-case images and colors, so we try to do so.
+ enum ContentType { HTMLContentType, DirectImageContentType, ColorContentType, MediaContentType, Canvas3DContentType};
+ struct ContentData {
+ IntRect needsDisplayRect;
+ bool needsDisplay;
+ Color backgroundColor;
+
+ ContentType contentType;
+ RefPtr<Image> image;
+ TextureMapperVideoLayer* media;
+
+ ContentData()
+ : needsDisplay(false)
+ , contentType(HTMLContentType)
+ , image(0)
+ , media(0)
+ {
+ }
+ };
+
+
+ TextureMapperNode();
+ virtual ~TextureMapperNode();
+
+ void syncCompositingState(GraphicsLayerTextureMapper*, bool recursive);
+
+protected:
+ // Reimps from TextureMapperContentLayer
+ virtual IntSize size() const { return m_size; }
+ virtual void setPlatformLayerClient(TextureMapperLayerClient*);
+ virtual void paint(TextureMapper*, const TextureMapperContentLayer::PaintOptions&);
+
+private:
+ TextureMapperNode* rootLayer();
+ void clearDirectImage();
+ void computeTransformations();
+ IntSize nearestSurfaceSize() const;
+ void computeReplicaTransform();
+ void computeLayerType();
+ void computeLocalTransform();
+ void flattenTo2DSpaceIfNecessary();
+ void initializeTextureMapper(TextureMapper*);
+ void invalidateTransform();
+ void notifyChange(ChangeMask);
+ void setNeedsDisplay();
+ void setNeedsDisplayInRect(IntRect);
+ void performPostSyncOperations();
+ void syncCompositingStateInternal(GraphicsLayerTextureMapper*, bool recursive, TextureMapper*);
+ void syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper);
+ TextureMapperCache* cache();
+
+ void paintRecursive(TexmapPaintOptions options);
+ bool paintReplica(const TexmapPaintOptions& options);
+ void paintSurface(const TexmapPaintOptions& options);
+ void paintSelf(const TexmapPaintOptions& options);
+ void paintSelfAndChildren(const TexmapPaintOptions& options, TexmapPaintOptions& optionsForDescendants);
+ void uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer);
+
+ int countDescendantsWithContent() const;
+ bool hasSurfaceDescendants() const;
+
+ TextureMapper* textureMapper();
+
+
+ static TextureMapperNode* toTextureMapperNode(GraphicsLayer*);
+ static int compareGraphicsLayersZValue(const void* a, const void* b);
+ static void sortByZOrder(Vector<TextureMapperNode* >& array, int first, int last);
+ struct TransformData {
+ TransformationMatrix base, target, replica, forDescendants, perspective, local;
+ IntRect targetBoundingRect;
+ float centerZ;
+ bool dirty, localDirty, perspectiveDirty;
+ IntRect boundingRectFromRoot;
+ TransformData() : dirty(true), localDirty(true), perspectiveDirty(true) { }
+ };
+
+ TransformData m_transforms;
+
+ enum LayerType {
+ DefaultLayer,
+ RootLayer,
+ ScissorLayer,
+ ClipLayer,
+ TransparencyLayer
+ };
+
+ LayerType m_layerType;
+
+ inline IntRect targetRect() const
+ {
+ return m_currentContent.contentType == HTMLContentType ? entireRect() : m_state.contentsRect;
+ }
+
+ inline IntRect entireRect() const
+ {
+ return IntRect(0, 0, m_size.width(), m_size.height());
+ }
+
+ inline IntRect replicaRect() const
+ {
+ return m_layerType == TransparencyLayer ? IntRect(0, 0, m_nearestSurfaceSize.width(), m_nearestSurfaceSize.height()) : entireRect();
+ }
+
+ RefPtr<BitmapTexture> m_texture;
+ RefPtr<BitmapTexture> m_surface, m_replicaSurface;
+
+ ContentData m_currentContent;
+
+ Vector<TextureMapperNode*> m_children;
+ TextureMapperNode* m_parent;
+ TextureMapperNode* m_effectTarget;
+ IntSize m_size, m_nearestSurfaceSize;
+ String m_name;
+ TextureMapperLayerClient* m_platformClient;
+
+ struct State {
+ FloatPoint pos;
+ FloatPoint3D anchorPoint;
+ FloatSize size;
+ TransformationMatrix transform;
+ TransformationMatrix childrenTransform;
+ Color backgroundColor;
+ Color currentColor;
+ GraphicsLayer::CompositingCoordinatesOrientation geoOrientation;
+ GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation;
+ float opacity;
+ IntRect contentsRect;
+ int descendantsWithContent;
+ TextureMapperNode* maskLayer;
+ TextureMapperNode* replicaLayer;
+ bool preserves3D;
+ bool masksToBounds;
+ bool drawsContent;
+ bool contentsOpaque;
+ bool backfaceVisibility;
+ bool visible;
+ bool dirty;
+ bool tiled;
+ bool hasSurfaceDescendants;
+ IntRect visibleRect;
+
+ State()
+ : opacity(1.f)
+ , descendantsWithContent(0)
+ , maskLayer(0)
+ , replicaLayer(0)
+ , preserves3D(false)
+ , masksToBounds(false)
+ , drawsContent(false)
+ , contentsOpaque(false)
+ , backfaceVisibility(false)
+ , visible(true)
+ , dirty(true)
+ , tiled(false)
+ , hasSurfaceDescendants(false)
+ {
+ }
+ };
+
+ State m_state;
+ TextureMapperCache* m_cache;
+};
+
+}
+#endif // TextureMapperNode_h
diff --git a/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h b/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
index 23e9fc9..2a38b90 100644
--- a/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
+++ b/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
@@ -25,6 +25,7 @@ namespace WebCore {
class GraphicsContext;
class IntRect;
class IntSize;
+class TextureMapper;
class TransformationMatrix;
@@ -35,6 +36,7 @@ public:
virtual void setNeedsDisplay() = 0;
virtual void setNeedsDisplayInRect(const IntRect& rect) = 0;
virtual void setSizeChanged(const IntSize&) = 0;
+ virtual TextureMapper* textureMapper() = 0;
};
class TextureMapperPlatformLayer {
@@ -50,10 +52,17 @@ public:
class TextureMapperContentLayer : public TextureMapperPlatformLayer {
public:
+ struct PaintOptions {
+ IntRect visibleRect;
+ IntRect targetRect;
+ IntSize viewportSize;
+ TransformationMatrix transform;
+ float opacity;
+ };
+
virtual void setPlatformLayerClient(TextureMapperLayerClient*) = 0;
- virtual void paint(GraphicsContext*, const IntSize&, const IntRect& targetRect, const IntRect& exposedRect, const TransformationMatrix& transform, float opacity) {}
+ virtual void paint(TextureMapper*, const PaintOptions&) {}
virtual IntSize size() const = 0;
- virtual void cleanupTextureMapper() {}
virtual Type layerType() const { return ContentLayer; }
};
diff --git a/WebCore/platform/graphics/win/FontCacheWin.cpp b/WebCore/platform/graphics/win/FontCacheWin.cpp
index 2240f80..e800245 100644
--- a/WebCore/platform/graphics/win/FontCacheWin.cpp
+++ b/WebCore/platform/graphics/win/FontCacheWin.cpp
@@ -330,7 +330,7 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& font
AtomicString("Arial")
};
SimpleFontData* simpleFont;
- for (int i = 0; i < ARRAYSIZE(fallbackFonts); ++i) {
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(fallbackFonts); ++i) {
if (simpleFont = getCachedFontData(fontDescription, fallbackFonts[i])) {
fallbackFontName = fallbackFonts[i];
return simpleFont;
diff --git a/WebCore/platform/graphics/win/IconWin.cpp b/WebCore/platform/graphics/win/IconWin.cpp
index 05959e0..4d4d219 100644
--- a/WebCore/platform/graphics/win/IconWin.cpp
+++ b/WebCore/platform/graphics/win/IconWin.cpp
@@ -69,7 +69,7 @@ PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames)
return 0;
#else
TCHAR buffer[MAX_PATH];
- UINT length = ::GetSystemDirectory(buffer, ARRAYSIZE(buffer));
+ UINT length = ::GetSystemDirectory(buffer, WTF_ARRAY_LENGTH(buffer));
if (!length)
return 0;
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
index 5544229..34a8817 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
@@ -1053,6 +1053,16 @@ void MediaPlayerPrivateQuickTimeVisualContext::setPreload(MediaPlayer::Preload p
resumeLoad();
}
+float MediaPlayerPrivateQuickTimeVisualContext::mediaTimeForTimeValue(float timeValue) const
+{
+ long timeScale;
+ if (m_readyState < MediaPlayer::HaveMetadata || !(timeScale = m_movie->timeScale()))
+ return timeValue;
+
+ long mediaTimeValue = static_cast<long>(timeValue * timeScale);
+ return static_cast<float>(mediaTimeValue) / timeScale;
+}
+
MediaPlayerPrivateQuickTimeVisualContext::MediaRenderingMode MediaPlayerPrivateQuickTimeVisualContext::currentRenderingMode() const
{
if (!m_movie)
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h
index 109fd0b..43d5bd5 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h
@@ -173,6 +173,8 @@ private:
void retrieveAndResetMovieTransform();
+ virtual float mediaTimeForTimeValue(float) const;
+
MediaPlayer* m_player;
RefPtr<QTMovie> m_movie;
#if USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/win/QTMovie.cpp b/WebCore/platform/graphics/win/QTMovie.cpp
index 375d8c2..e425bf8 100644
--- a/WebCore/platform/graphics/win/QTMovie.cpp
+++ b/WebCore/platform/graphics/win/QTMovie.cpp
@@ -738,6 +738,14 @@ void QTMovie::setClosedCaptionsVisible(bool visible)
QTSetTrackProperty(ccTrack, closedCaptionTrackType, closedCaptionDisplayPropertyID, sizeof(doDisplay), &doDisplay);
}
+long QTMovie::timeScale() const
+{
+ if (!m_private->m_movie)
+ return 0;
+
+ return GetMovieTimeScale(m_private->m_movie);
+}
+
static void initializeSupportedTypes()
{
if (gSupportedTypes)
diff --git a/WebCore/platform/graphics/win/QTMovie.h b/WebCore/platform/graphics/win/QTMovie.h
index e205b68..5e4c4e7 100644
--- a/WebCore/platform/graphics/win/QTMovie.h
+++ b/WebCore/platform/graphics/win/QTMovie.h
@@ -115,6 +115,8 @@ public:
Movie getMovieHandle() const;
+ long timeScale() const;
+
private:
QTMoviePrivate* m_private;
friend class QTMoviePrivate;
diff --git a/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
index a11b8d8..8af6ef7 100644
--- a/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
+++ b/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
@@ -194,11 +194,6 @@ public:
restore();
}
- IntPoint origin() const
- {
- return IntPoint(stableRound(-m_transform.e()), stableRound(-m_transform.f()));
- }
-
void translate(float x, float y)
{
m_transform.translate(x, y);
@@ -463,8 +458,7 @@ private:
RefPtr<SharedBitmap> m_bitmap;
RefPtr<SharedBitmap> m_rotatedBitmap;
RECT m_bmpRect;
- unsigned m_key1;
- unsigned m_key2;
+ unsigned m_key;
RotationTransform m_rotation;
float m_oldOpacity;
AlphaPaintType m_alphaPaintType;
@@ -532,7 +526,7 @@ TransparentLayerDC::TransparentLayerDC(GraphicsContextPlatformPrivate* data, Int
} else
m_bitmap = m_data->getTransparentLayerBitmap(m_origRect, m_alphaPaintType, m_bmpRect, true, mustCreateLayer);
if (m_bitmap)
- m_memDc = m_bitmap->getDC(&m_key1, &m_key2);
+ m_memDc = m_bitmap->getDC(&m_key);
else
m_memDc = m_data->m_dc;
}
@@ -540,15 +534,15 @@ TransparentLayerDC::TransparentLayerDC(GraphicsContextPlatformPrivate* data, Int
TransparentLayerDC::~TransparentLayerDC()
{
if (m_rotatedBitmap) {
- m_bitmap->releaseDC(m_memDc, m_key1, m_key2);
- m_key1 = m_key2 = 0;
+ m_bitmap->releaseDC(m_memDc, m_key);
+ m_key = 0;
rotateBitmap(m_rotatedBitmap.get(), m_bitmap.get(), m_rotation);
- m_memDc = m_rotatedBitmap->getDC(&m_key1, &m_key2);
+ m_memDc = m_rotatedBitmap->getDC(&m_key);
m_data->paintBackTransparentLayerBitmap(m_memDc, m_rotatedBitmap.get(), m_rotatedOrigRect, m_alphaPaintType, m_bmpRect);
- m_rotatedBitmap->releaseDC(m_memDc, m_key1, m_key2);
+ m_rotatedBitmap->releaseDC(m_memDc, m_key);
} else if (m_bitmap) {
m_data->paintBackTransparentLayerBitmap(m_memDc, m_bitmap.get(), m_origRect, m_alphaPaintType, m_bmpRect);
- m_bitmap->releaseDC(m_memDc, m_key1, m_key2);
+ m_bitmap->releaseDC(m_memDc, m_key);
}
m_data->m_opacity = m_oldOpacity;
}
@@ -572,19 +566,18 @@ public:
: m_data(data)
{
if (m_data->m_bitmap)
- m_data->m_dc = m_data->m_bitmap->getDC(&m_key1, &m_key2);
+ m_data->m_dc = m_data->m_bitmap->getDC(&m_key);
}
~ScopeDCProvider()
{
if (m_data->m_bitmap) {
- m_data->m_bitmap->releaseDC(m_data->m_dc, m_key1, m_key2);
+ m_data->m_bitmap->releaseDC(m_data->m_dc, m_key);
m_data->m_dc = 0;
}
}
private:
GraphicsContextPlatformPrivate* m_data;
- unsigned m_key1;
- unsigned m_key2;
+ unsigned m_key;
};
@@ -1159,11 +1152,6 @@ void GraphicsContext::rotate(float radians)
m_data->rotate(radians);
}
-IntPoint GraphicsContext::origin()
-{
- return m_data->origin();
-}
-
void GraphicsContext::scale(const FloatSize& size)
{
m_data->scale(size);
@@ -1219,11 +1207,6 @@ void GraphicsContext::clipOut(const Path&)
notImplemented();
}
-void GraphicsContext::clipOutEllipseInRect(const IntRect&)
-{
- notImplemented();
-}
-
static inline IntPoint rectCenterPoint(const RECT& rect)
{
return IntPoint(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2);
@@ -1539,6 +1522,12 @@ void GraphicsContext::clearPlatformShadow()
notImplemented();
}
+InterpolationQuality GraphicsContext::imageInterpolationQuality() const
+{
+ notImplemented();
+ return InterpolationDefault;
+}
+
void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
{
notImplemented();
@@ -1576,11 +1565,11 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo
gc.scale(FloatSize(m_data->m_transform.a(), m_data->m_transform.d()));
font.drawText(&gc, run, IntPoint(0, font.ascent()), from, to);
}
- unsigned key1, key2;
- HDC memDC = bmp->getDC(&key1, &key2);
+ unsigned key1;
+ HDC memDC = bmp->getDC(&key1);
if (memDC) {
m_data->paintBackTransparentLayerBitmap(memDC, bmp.get(), trRect, alphaPaintType, bmpRect);
- bmp->releaseDC(memDC, key1, key2);
+ bmp->releaseDC(memDC, key1);
}
}
diff --git a/WebCore/platform/graphics/wince/ImageWinCE.cpp b/WebCore/platform/graphics/wince/ImageWinCE.cpp
index ec7403e..c0b2b53 100644
--- a/WebCore/platform/graphics/wince/ImageWinCE.cpp
+++ b/WebCore/platform/graphics/wince/ImageWinCE.cpp
@@ -43,7 +43,7 @@ namespace WebCore {
NativeImagePtr RGBA32Buffer::asNewNativeImage() const
{
- return SharedBitmap::create(m_bytes, m_size, hasAlpha());
+ return SharedBitmap::create(m_backingStore, m_size, hasAlpha());
}
bool FrameData::clear(bool clearMetaData)
diff --git a/WebCore/platform/graphics/wince/SharedBitmap.cpp b/WebCore/platform/graphics/wince/SharedBitmap.cpp
new file mode 100644
index 0000000..05d1535
--- /dev/null
+++ b/WebCore/platform/graphics/wince/SharedBitmap.cpp
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ *
+ * 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 "SharedBitmap.h"
+
+#include "GDIExtras.h"
+#include "GraphicsContext.h"
+#include "GraphicsTypes.h"
+#include "TransformationMatrix.h"
+#include "WinCEGraphicsExtras.h"
+#include <wtf/HashSet.h>
+#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/PassOwnArrayPtr.h>
+#include <wtf/OwnPtr.h>
+
+#include <windows.h>
+
+namespace WebCore {
+
+#ifndef NDEBUG
+static WTF::RefCountedLeakCounter sharedBitmapLeakCounter("SharedBitmap");
+#endif
+
+
+PassRefPtr<SharedBitmap> SharedBitmap::create(const IntSize& size, BitmapInfo::BitCount bitCount, bool initPixels)
+{
+ RefPtr<SharedBitmap> resultantBitmap = adoptRef(new SharedBitmap(size, bitCount, initPixels));
+ if (resultantBitmap && !resultantBitmap->bytes())
+ return 0;
+ return resultantBitmap.release();
+}
+
+PassRefPtr<SharedBitmap> SharedBitmap::create(const Vector<unsigned>& data, const IntSize& size, bool hasAlpha)
+{
+ RefPtr<SharedBitmap> result = create(size, BitmapInfo::BitCount32, false);
+ if (!result)
+ return 0;
+ memcpy(result->bytes(), data.data(), data.size() * sizeof(unsigned));
+ result->setHasAlpha(hasAlpha);
+ return result.release();
+}
+
+SharedBitmap::SharedBitmap(const IntSize& size, BitmapInfo::BitCount bitCount, bool initPixels)
+ : m_bmpInfo(BitmapInfo::createBottomUp(size, bitCount))
+ , m_locked(false)
+ , m_usesTransparentColor(false)
+ , m_transparentColor(RGB(0, 0, 0))
+ , m_pixels(0)
+ , m_hasAlpha(false)
+ , m_validHeight(abs(size.height()))
+ , m_hbitmap(0)
+{
+#ifndef NDEBUG
+ sharedBitmapLeakCounter.increment();
+#endif
+
+ unsigned bufferSize = m_bmpInfo.numPixels();
+ if (bitCount == BitmapInfo::BitCount16)
+ bufferSize /= 2;
+
+ m_pixelData = adoptArrayPtr(new unsigned[bufferSize]);
+ m_pixels = m_pixelData.get();
+
+ if (initPixels)
+ resetPixels();
+}
+
+SharedBitmap::~SharedBitmap()
+{
+#ifndef NDEBUG
+ sharedBitmapLeakCounter.decrement();
+#endif
+}
+
+void SharedBitmap::resetPixels(bool black)
+{
+ if (!m_pixels)
+ return;
+
+ unsigned bufferSize = m_bmpInfo.numPixels();
+ if (black) {
+ unsigned bufferSizeInBytes = bufferSize * (is16bit() ? 2 : 4);
+ memset(m_pixels, 0, bufferSizeInBytes);
+ return;
+ }
+
+ if (is16bit()) {
+ // Fill it with white color
+ wmemset(static_cast<wchar_t*>(m_pixels), 0xFFFF, bufferSize);
+ return;
+ }
+
+ // Make it white but transparent
+ unsigned* pixel = static_cast<unsigned*>(m_pixels);
+ const unsigned* bufferEnd = pixel + bufferSize;
+ while (pixel < bufferEnd)
+ *pixel++ = 0x00FFFFFF;
+}
+
+static inline unsigned short convert32To16(unsigned pixel)
+{
+ unsigned short r = static_cast<unsigned short>((pixel & 0x00F80000) >> 8);
+ unsigned short g = static_cast<unsigned short>((pixel & 0x0000FC00) >> 5);
+ unsigned short b = static_cast<unsigned short>((pixel & 0x000000F8) >> 3);
+ return r | g | b;
+}
+
+bool SharedBitmap::to16bit()
+{
+ if (m_locked)
+ return false;
+ if (is16bit())
+ return true;
+
+ BitmapInfo newBmpInfo = BitmapInfo::create(m_bmpInfo.size(), BitmapInfo::BitCount16);
+
+ int width = newBmpInfo.width();
+ int paddedWidth = newBmpInfo.paddedWidth();
+ int bufferSize = paddedWidth * newBmpInfo.height();
+ OwnArrayPtr<unsigned> newPixelData(new unsigned[bufferSize / 2]);
+ void* newPixels = newPixelData.get();
+
+ if (!newPixels)
+ return false;
+
+ unsigned short* p16 = static_cast<unsigned short*>(newPixels);
+ const unsigned* p32 = static_cast<const unsigned*>(m_pixels);
+
+ bool skips = paddedWidth != width;
+
+ const unsigned short* p16end = p16 + bufferSize;
+ while (p16 < p16end) {
+ for (unsigned short* p16lineEnd = p16 + width; p16 < p16lineEnd; )
+ *p16++ = convert32To16(*p32++);
+
+ if (skips)
+ *p16++ = 0;
+ }
+
+ if (m_hbitmap)
+ m_hbitmap = nullptr;
+ else
+ m_pixelData = newPixelData.release();
+
+ m_pixels = newPixels;
+ m_bmpInfo = newBmpInfo;
+
+ setHasAlpha(false);
+ return true;
+}
+
+bool SharedBitmap::freeMemory()
+{
+ if (m_locked)
+ return false;
+
+ if (m_hbitmap) {
+ m_hbitmap = nullptr;
+ m_pixels = 0;
+ return true;
+ }
+
+ if (m_pixels) {
+ m_pixelData = nullptr;
+ m_pixels = 0;
+ return true;
+ }
+
+ return false;
+}
+
+PassOwnPtr<HBITMAP> SharedBitmap::createHandle(void** pixels, BitmapInfo* bmpInfo, int height, bool use16bit) const
+{
+ if (!m_pixels)
+ return 0;
+
+ if (height == -1)
+ height = this->height();
+ *bmpInfo = BitmapInfo::createBottomUp(IntSize(width(), height), (use16bit || is16bit()) ? BitmapInfo::BitCount16 : BitmapInfo::BitCount32);
+
+ OwnPtr<HBITMAP> hbmp = adoptPtr(CreateDIBSection(0, bmpInfo, DIB_RGB_COLORS, pixels, 0, 0));
+
+ if (!hbmp)
+ return 0;
+
+ OwnPtr<HDC> bmpDC = adoptPtr(CreateCompatibleDC(0));
+ HGDIOBJ hOldBmp = SelectObject(bmpDC.get(), hbmp.get());
+
+ StretchDIBits(bmpDC.get(), 0, 0, width(), height, 0, 0, width(), height, m_pixels, &m_bmpInfo, DIB_RGB_COLORS, SRCCOPY);
+
+ SelectObject(bmpDC.get(), hOldBmp);
+
+ return hbmp.release();
+}
+
+bool SharedBitmap::ensureHandle()
+{
+ if (m_hbitmap)
+ return true;
+
+ if (!m_pixels)
+ return false;
+
+ if (m_locked)
+ return false;
+
+ BitmapInfo bmpInfo;
+ void* pixels;
+ m_hbitmap = createHandle(&pixels, &bmpInfo, -1, !hasAlpha());
+
+ if (!m_hbitmap)
+ return false;
+
+ m_pixelData = nullptr;
+ m_pixels = pixels;
+ m_bmpInfo = bmpInfo;
+
+ return true;
+}
+
+void SharedBitmap::draw(GraphicsContext* ctxt, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp)
+{
+ if (!m_pixels)
+ return;
+ ctxt->drawBitmap(this, dstRect, srcRect, styleColorSpace, compositeOp);
+}
+
+void SharedBitmap::draw(HDC hdc, const IntRect& dstRect, const IntRect& srcRect, CompositeOperator compositeOp)
+{
+ if (!m_pixels)
+ return;
+
+ if (dstRect.isEmpty() || srcRect.isEmpty())
+ return;
+
+ HBITMAP hbitmap = 0;
+ OwnPtr<HBITMAP> hTempBitmap;
+ bool usingHandle = compositeOp == CompositeSourceOver && (hasAlpha() && hasAlphaBlendSupport() || usesTransparentColor());
+
+ if (usingHandle) {
+ if (ensureHandle())
+ hbitmap = m_hbitmap.get();
+ else {
+ void* pixels;
+ BitmapInfo bmpInfo;
+ hTempBitmap = createHandle(&pixels, &bmpInfo, -1, usesTransparentColor());
+ hbitmap = hTempBitmap.get();
+ }
+ }
+ if (!hbitmap) {
+ // FIXME: handle other composite operation types?
+ DWORD rop = compositeOp == CompositeCopy ? SRCCOPY
+ : compositeOp == CompositeXOR ? PATINVERT
+ : compositeOp == CompositeClear ? WHITENESS
+ : SRCCOPY;
+
+ StretchDIBits(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(),
+ srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), m_pixels, &m_bmpInfo, DIB_RGB_COLORS, rop);
+ return;
+ }
+
+ OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc));
+ HGDIOBJ hOldBmp = SelectObject(hmemdc.get(), hbitmap);
+
+ if (!usesTransparentColor() && hasAlphaBlendSupport()) {
+ static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
+ bool success = alphaBlendIfSupported(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), hmemdc.get(),
+ srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), blend);
+ ASSERT_UNUSED(success, success);
+ } else {
+ TransparentBlt(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), hmemdc.get(),
+ srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), transparentColor());
+ }
+
+ SelectObject(hmemdc.get(), hOldBmp);
+}
+
+PassOwnPtr<HBITMAP> SharedBitmap::clipBitmap(const IntRect& rect, bool useAlpha, BitmapInfo& bmpInfo, void*& pixels)
+{
+ if (!bytes())
+ return 0;
+
+ int oldWidth = width();
+ int oldHeight = height();
+ int copyWidth = std::min<int>(rect.width(), oldWidth - rect.x());
+ int copyHeight = std::min<int>(rect.height(), oldHeight - rect.y());
+ if (!copyWidth || !copyHeight)
+ return 0;
+
+ bmpInfo = BitmapInfo::createBottomUp(IntSize(copyWidth, copyHeight), (useAlpha && is32bit()) ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16);
+ OwnPtr<HBITMAP> newBmp = adoptPtr(CreateDIBSection(0, &bmpInfo, DIB_RGB_COLORS, &pixels, 0, 0));
+
+ if (!newBmp)
+ return 0;
+
+ OwnPtr<HDC> dcNew = adoptPtr(CreateCompatibleDC(0));
+ HGDIOBJ tmpNew = SelectObject(dcNew.get(), newBmp.get());
+
+ StretchDIBits(dcNew.get(), 0, 0, copyWidth, copyHeight, rect.x(), rect.y(), copyWidth, copyHeight,
+ bytes(), &bitmapInfo(), DIB_RGB_COLORS, SRCCOPY);
+
+ SelectObject(dcNew.get(), tmpNew);
+ return newBmp.release();
+}
+
+PassRefPtr<SharedBitmap> SharedBitmap::clipBitmap(const IntRect& rect, bool useAlpha)
+{
+ int oldWidth = width();
+ int oldHeight = height();
+ int copyWidth = std::min<int>(rect.width(), oldWidth - rect.x());
+ int copyHeight = std::min<int>(rect.height(), oldHeight - rect.y());
+ if (!copyWidth || !copyHeight)
+ return 0;
+
+ RefPtr<SharedBitmap> newBmp = create(IntSize(copyWidth, copyHeight), useAlpha && is32bit() ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16, false);
+
+ if (!newBmp || !newBmp->bytes())
+ return 0;
+
+ DCHolder dcNew(newBmp.get());
+
+ StretchDIBits(dcNew.get(), 0, 0, copyWidth, copyHeight, rect.x(), rect.y(), copyWidth, copyHeight,
+ bytes(), &bitmapInfo(), DIB_RGB_COLORS, SRCCOPY);
+
+ return newBmp;
+}
+
+static void drawPatternSimple(HDC hdc, const RECT& destRect, HBITMAP hbmp, const POINT& phase)
+{
+ OwnPtr<HBRUSH> hBrush = adoptPtr(CreatePatternBrush(hbmp));
+ if (!hBrush)
+ return;
+
+ POINT oldOrg;
+ SetBrushOrgEx(hdc, destRect.left - phase.x, destRect.top - phase.y, &oldOrg);
+ FillRect(hdc, &destRect, hBrush.get());
+ SetBrushOrgEx(hdc, oldOrg.x, oldOrg.y, 0);
+}
+
+static void drawPatternSimple(HDC hdc, const RECT& destRect, const SharedBitmap* bmp, const SIZE& bmpSize, const POINT& phase)
+{
+ int dstY = destRect.top;
+ for (int sourceY = phase.y; dstY < destRect.bottom; ) {
+ int sourceH = std::min<int>(bmpSize.cy - sourceY, destRect.bottom - dstY);
+ int dstX = destRect.left;
+ for (int sourceX = phase.x; dstX < destRect.right; ) {
+ int sourceW = std::min<int>(bmpSize.cx - sourceX, destRect.right - dstX);
+
+ StretchDIBits(hdc, dstX, dstY, sourceW, sourceH, sourceX, sourceY, sourceW, sourceH,
+ bmp->bytes(), &bmp->bitmapInfo(), DIB_RGB_COLORS, SRCCOPY);
+
+ dstX += sourceW;
+ sourceX = 0;
+ }
+
+ dstY += sourceH;
+ sourceY = 0;
+ }
+}
+
+static LONG normalizePhase(LONG phase, int limit)
+{
+ if (!phase || limit < 2)
+ return 0;
+
+ if (limit == 2)
+ return phase & 1;
+
+ if (phase < 0) {
+ phase = -phase;
+ if (phase > limit)
+ phase = static_cast<LONG>(static_cast<unsigned>(phase) % static_cast<unsigned>(limit));
+ if (phase)
+ phase = limit - phase;
+ return phase;
+ }
+
+ if (phase < limit)
+ return phase;
+
+ return static_cast<LONG>(static_cast<unsigned>(phase) % static_cast<unsigned>(limit));
+}
+
+void SharedBitmap::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize)
+{
+ if (!m_pixels)
+ return;
+ ctxt->drawBitmapPattern(this, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, origSourceSize);
+}
+
+void SharedBitmap::drawPattern(HDC hdc, const AffineTransform& transform, const FloatRect& tileRectIn, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize)
+{
+ if (!m_pixels)
+ return;
+
+ if (tileRectIn.width() <= 0 || tileRectIn.height() <= 0)
+ return;
+
+ bool useAlpha = op == CompositeSourceOver && hasAlpha() && is32bit();
+
+ int bmpWidth = width();
+ int bmpHeight = height();
+
+ FloatRect tileRect(tileRectIn);
+ if (bmpWidth != origSourceSize.width()) {
+ double rate = static_cast<double>(bmpWidth) / origSourceSize.width();
+ double temp = tileRect.width() * rate;
+ tileRect.setX(tileRect.x() * rate);
+ tileRect.setWidth(temp);
+ temp = tileRect.height() * rate;
+ tileRect.setY(tileRect.y() * rate);
+ tileRect.setHeight(temp);
+ }
+
+ OwnPtr<HBITMAP> clippedBmp;
+
+ if (tileRect.x() || tileRect.y() || tileRect.width() != bmpWidth || tileRect.height() != bmpHeight) {
+ BitmapInfo patternBmpInfo;
+ void* patternPixels;
+ clippedBmp = clipBitmap(IntRect(tileRect), useAlpha, patternBmpInfo, patternPixels);
+ if (!clippedBmp)
+ return;
+
+ bmpWidth = tileRect.width();
+ bmpHeight = tileRect.height();
+ }
+
+ AffineTransform tf = transform;
+ tf *= patternTransform;
+
+ FloatRect trRect = tf.mapRect(destRect);
+
+ RECT clipBox;
+ int clipType = GetClipBox(hdc, &clipBox);
+ if (clipType == SIMPLEREGION)
+ trRect.intersect(FloatRect(clipBox.left, clipBox.top, clipBox.right - clipBox.left, clipBox.bottom - clipBox.top));
+ else if (clipType == COMPLEXREGION) {
+ OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgn(0, 0, 0, 0));
+ if (GetClipRgn(hdc, clipRgn.get()) > 0) {
+ DWORD regionDataSize = GetRegionData(clipRgn.get(), sizeof(RGNDATA), 0);
+ if (regionDataSize) {
+ Vector<RGNDATA> regionData(regionDataSize);
+ GetRegionData(clipRgn.get(), regionDataSize, regionData.data());
+ RECT* rect = reinterpret_cast<RECT*>(regionData[0].Buffer);
+ for (DWORD i = 0; i < regionData[0].rdh.nCount; ++i, ++rect)
+ trRect.intersect(FloatRect(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top));
+ }
+ }
+ }
+
+ if (trRect.width() <= 0 || trRect.height() <= 0)
+ return;
+
+ trRect.inflate(1);
+ IntRect visibleDstRect = enclosingIntRect(tf.inverse().mapRect(trRect));
+ visibleDstRect.intersect(IntRect(destRect));
+
+ if (visibleDstRect.width() <= 0 || visibleDstRect.height() <= 0)
+ return;
+
+ trRect = tf.mapRect(visibleDstRect);
+ RECT dstRectWin = {
+ stableRound(trRect.x()),
+ stableRound(trRect.y()),
+ stableRound(trRect.right()),
+ stableRound(trRect.bottom()),
+ };
+ if (dstRectWin.right <= dstRectWin.left || dstRectWin.bottom <= dstRectWin.top)
+ return;
+
+ SIZE bmpSize = { bmpWidth, bmpHeight };
+
+ // Relative to destination, in bitmap pixels
+ POINT phaseWin = { stableRound(visibleDstRect.x() - phase.x()), stableRound(visibleDstRect.y() - phase.y()) };
+ phaseWin.x = normalizePhase(phaseWin.x, bmpSize.cx);
+ phaseWin.y = normalizePhase(phaseWin.y, bmpSize.cy);
+
+ RECT srcRectWin = {
+ 0,
+ 0,
+ stableRound(visibleDstRect.right()) - stableRound(visibleDstRect.x()),
+ stableRound(visibleDstRect.bottom()) - stableRound(visibleDstRect.y())
+ };
+ if (srcRectWin.right <= 0 || srcRectWin.bottom <= 0)
+ return;
+
+ BitmapInfo bmpInfo = BitmapInfo::createBottomUp(IntSize(srcRectWin.right, srcRectWin.bottom), useAlpha ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16);
+ void* pixels;
+ OwnPtr<HBITMAP> hbmpTemp = adoptPtr(CreateDIBSection(0, &bmpInfo, DIB_RGB_COLORS, &pixels, 0, 0));
+
+ if (!hbmpTemp)
+ return;
+
+ OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc));
+ HGDIOBJ oldBmp = SelectObject(hmemdc.get(), hbmpTemp.get());
+ if (clippedBmp)
+ drawPatternSimple(hmemdc.get(), srcRectWin, clippedBmp.get(), phaseWin);
+ else if ((op != CompositeSourceOver || canUseDIBits()) && srcRectWin.right <= bmpSize.cx * 2 && srcRectWin.bottom <= bmpSize.cy * 2)
+ drawPatternSimple(hmemdc.get(), srcRectWin, this, bmpSize, phaseWin);
+ else if (ensureHandle())
+ drawPatternSimple(hmemdc.get(), srcRectWin, getHandle(), phaseWin);
+ else {
+ void* pixels;
+ BitmapInfo bmpInfo;
+ OwnPtr<HBITMAP> hbmp = createHandle(&pixels, &bmpInfo, -1, false);
+ if (hbmp)
+ drawPatternSimple(hmemdc.get(), srcRectWin, hbmp.get(), phaseWin);
+ else {
+ SelectObject(hmemdc.get(), oldBmp);
+ return;
+ }
+ }
+
+ if (useAlpha && hasAlphaBlendSupport()) {
+ static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
+ bool success = alphaBlendIfSupported(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, dstRectWin.bottom - dstRectWin.top,
+ hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, blend);
+ ASSERT_UNUSED(success, success);
+ } else if (useAlpha && !hasAlphaBlendSupport() || op == CompositeSourceOver && usesTransparentColor()) {
+ TransparentBlt(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left,
+ dstRectWin.bottom - dstRectWin.top, hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, transparentColor());
+ } else {
+ DWORD bmpOp = op == CompositeCopy ? SRCCOPY
+ : op == CompositeSourceOver ? SRCCOPY
+ : op == CompositeXOR ? PATINVERT
+ : op == CompositeClear ? WHITENESS
+ : SRCCOPY; // FIXEME: other types?
+
+ StretchDIBits(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left,
+ dstRectWin.bottom - dstRectWin.top, 0, 0, srcRectWin.right, srcRectWin.bottom,
+ pixels, &bmpInfo, DIB_RGB_COLORS, bmpOp);
+ }
+ SelectObject(hmemdc.get(), oldBmp);
+}
+
+SharedBitmap::DCProvider* SharedBitmap::s_dcProvider = new SharedBitmap::DCProvider;
+
+HDC SharedBitmap::DCProvider::getDC(SharedBitmap* bmp, unsigned* key)
+{
+ if (!bmp || !bmp->ensureHandle())
+ return 0;
+
+ HDC hdc = CreateCompatibleDC(0);
+ if (!hdc)
+ return 0;
+
+ *key = reinterpret_cast<unsigned>(SelectObject(hdc, bmp->getHandle()));
+ RECT rect = { 0, 0, bmp->width(), bmp->height() };
+ OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgnIndirect(&rect));
+ SelectClipRgn(hdc, clipRgn.get());
+
+ return hdc;
+}
+
+void SharedBitmap::DCProvider::releaseDC(SharedBitmap*, HDC hdc, unsigned key1)
+{
+ if (!hdc)
+ return;
+
+ SelectObject(hdc, reinterpret_cast<HGDIOBJ>(key1));
+ DeleteDC(hdc);
+}
+
+void SharedBitmap::clearPixels(const IntRect& rect)
+{
+ if (!m_pixels)
+ return;
+
+ IntRect bmpRect(0, 0, width(), height());
+ bmpRect.intersect(rect);
+ if (is16bit()) {
+ unsigned w = m_bmpInfo.paddedWidth();
+ unsigned short* dst = static_cast<unsigned short*>(m_pixels);
+ dst += bmpRect.y() * w + bmpRect.x();
+ int wordsToSet = bmpRect.width();
+ const unsigned short* dstEnd = dst + bmpRect.height() * w;
+ while (dst < dstEnd) {
+ wmemset(reinterpret_cast<wchar_t*>(dst), 0, wordsToSet);
+ dst += w;
+ }
+ return;
+ }
+
+ unsigned w = width();
+ unsigned* dst = static_cast<unsigned*>(m_pixels);
+ dst += bmpRect.y() * w + bmpRect.x();
+ int wordsToSet = bmpRect.width() * 2;
+ const unsigned* dstEnd = dst + bmpRect.height() * w;
+ while (dst < dstEnd) {
+ wmemset(reinterpret_cast<wchar_t*>(dst), 0, wordsToSet);
+ dst += w;
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/wince/SharedBitmap.h b/WebCore/platform/graphics/wince/SharedBitmap.h
new file mode 100644
index 0000000..82f5d54
--- /dev/null
+++ b/WebCore/platform/graphics/wince/SharedBitmap.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ *
+ * 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 SharedBitmap_h
+#define SharedBitmap_h
+
+#include "AffineTransform.h"
+#include "BitmapInfo.h"
+#include "ColorSpace.h"
+#include "GraphicsTypes.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wingdi.h>
+
+namespace WebCore {
+
+class FloatPoint;
+class FloatRect;
+class GraphicsContext;
+class IntRect;
+class IntSize;
+class TransformationMatrix;
+
+class SharedBitmap: public RefCounted<SharedBitmap> {
+public:
+ ~SharedBitmap();
+ static PassRefPtr<SharedBitmap> create(const IntSize&, BitmapInfo::BitCount = BitmapInfo::BitCount32, bool initPixels = true);
+ static PassRefPtr<SharedBitmap> create(const Vector<unsigned>&, const IntSize&, bool hasAlpha = true);
+
+ const BitmapInfo& bitmapInfo() const { return m_bmpInfo; }
+ void* bytes() { return m_pixels; }
+ const void* bytes() const { return m_pixels; }
+ unsigned width() const { return m_bmpInfo.width(); }
+ unsigned height() const { return m_bmpInfo.height(); }
+ unsigned validHeight() const { return m_validHeight; }
+ void setValidHeight(unsigned validHeight) { m_validHeight = validHeight; }
+ void resetPixels(bool black = false);
+ void clearPixels(const IntRect& r);
+ bool locked() const { return m_locked; }
+ void lock() { m_locked = true; }
+ void unlock() { m_locked = false; }
+ bool freeMemory();
+ bool is16bit() const { return m_bmpInfo.is16bit(); }
+ bool is32bit() const { return m_bmpInfo.is32bit(); }
+ bool to16bit();
+ bool hasAlpha() const { return m_hasAlpha; }
+ void setHasAlpha(bool alpha) { m_hasAlpha = alpha; }
+ bool ensureHandle();
+ HBITMAP getHandle() { return m_hbitmap.get(); }
+ PassOwnPtr<HBITMAP> createHandle(void** pixels, BitmapInfo* bmpInfo, int h = -1, bool use16bit = true) const;
+ bool usesTransparentColor() const { return m_usesTransparentColor; }
+ COLORREF transparentColor() const { return m_transparentColor; }
+ void setTransparentColor(COLORREF c)
+ {
+ m_usesTransparentColor = true;
+ m_transparentColor = c;
+ }
+ bool canUseDIBits() const { return !hasAlpha() && !usesTransparentColor(); }
+
+ PassOwnPtr<HBITMAP> clipBitmap(const IntRect& rect, bool useAlpha, BitmapInfo& bmpInfo, void*& pixels);
+
+ PassRefPtr<SharedBitmap> clipBitmap(const IntRect& rect, bool useAlpha);
+
+ void draw(GraphicsContext* ctxt, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp);
+ void drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize);
+ void draw(HDC, const IntRect& dstRect, const IntRect& srcRect, CompositeOperator compositeOp);
+ void drawPattern(HDC, const AffineTransform&, const FloatRect& tileRectIn, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize);
+
+ class DCProvider {
+ public:
+ virtual HDC getDC(SharedBitmap*, unsigned*);
+ virtual void releaseDC(SharedBitmap*, HDC, unsigned);
+ };
+
+ static DCProvider* s_dcProvider;
+
+ HDC getDC(unsigned* key1) { return s_dcProvider->getDC(this, key1); }
+ void releaseDC(HDC hdc, unsigned key1) { s_dcProvider->releaseDC(this, hdc, key1); }
+
+ class DCHolder {
+ public:
+ DCHolder(SharedBitmap* bmp = 0) { setInternal(bmp); }
+ ~DCHolder() { clearInternal(); }
+ void set(SharedBitmap* bmp = 0)
+ {
+ clearInternal();
+ setInternal(bmp);
+ }
+ HDC get() const { return m_hdc; }
+ private:
+ DCHolder& operator=(const DCHolder&);
+ DCHolder(const DCHolder&);
+ void clearInternal()
+ {
+ if (m_hdc)
+ m_bitmap->releaseDC(m_hdc, m_key);
+ }
+ void setInternal(SharedBitmap* bmp)
+ {
+ m_bitmap = bmp;
+ m_hdc = bmp ? bmp->getDC(&m_key) : 0;
+ }
+ SharedBitmap* m_bitmap;
+ HDC m_hdc;
+ unsigned m_key;
+ };
+
+private:
+ SharedBitmap(const IntSize&, BitmapInfo::BitCount, bool initPixels);
+ BitmapInfo m_bmpInfo;
+ OwnPtr<HBITMAP> m_hbitmap;
+ void* m_pixels;
+ OwnArrayPtr<unsigned> m_pixelData;
+ COLORREF m_transparentColor;
+ int m_validHeight;
+ bool m_locked;
+ bool m_usesTransparentColor;
+ bool m_hasAlpha;
+};
+
+} // namespace WebCore
+
+#endif // SharedBitmap_h
diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index 30daa67..53a9ccd 100644
--- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -337,11 +337,6 @@ void GraphicsContext::clipOut(const IntRect&)
notImplemented();
}
-void GraphicsContext::clipOutEllipseInRect(const IntRect&)
-{
- notImplemented();
-}
-
void GraphicsContext::clipPath(WindRule)
{
notImplemented();
diff --git a/WebCore/platform/gtk/CursorGtk.cpp b/WebCore/platform/gtk/CursorGtk.cpp
index 9971bfb..39073ae 100644
--- a/WebCore/platform/gtk/CursorGtk.cpp
+++ b/WebCore/platform/gtk/CursorGtk.cpp
@@ -32,7 +32,7 @@
#include "Image.h"
#include "IntPoint.h"
-#include "PlatformRefPtrCairo.h"
+#include "RefPtrCairo.h"
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <wtf/Assertions.h>
@@ -47,10 +47,10 @@ static PlatformRefPtr<GdkCursor> createNamedCursor(CustomCursorType cursorType)
return c;
IntSize cursorSize = IntSize(32, 32);
- PlatformRefPtr<cairo_surface_t> source = adoptPlatformRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.bits), CAIRO_FORMAT_A1, 32, 32, 4));
- PlatformRefPtr<cairo_surface_t> mask = adoptPlatformRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.mask_bits), CAIRO_FORMAT_A1, 32, 32, 4));
- PlatformRefPtr<cairo_surface_t> surface = adoptPlatformRef(cairo_image_surface_create(CAIRO_FORMAT_A1, 32, 32));
- PlatformRefPtr<cairo_t> cr = adoptPlatformRef(cairo_create(surface.get()));
+ RefPtr<cairo_surface_t> source = adoptRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.bits), CAIRO_FORMAT_A1, 32, 32, 4));
+ RefPtr<cairo_surface_t> mask = adoptRef(cairo_image_surface_create_for_data(const_cast<unsigned char*>(cursor.mask_bits), CAIRO_FORMAT_A1, 32, 32, 4));
+ RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_A1, 32, 32));
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
cairo_set_source_surface(cr.get(), source.get(), cursor.hot_x, cursor.hot_y);
cairo_mask_surface(cr.get(), mask.get(), cursor.hot_x, cursor.hot_y);
diff --git a/WebCore/platform/gtk/DragImageGtk.cpp b/WebCore/platform/gtk/DragImageGtk.cpp
index 9d0d838..71a65e1 100644
--- a/WebCore/platform/gtk/DragImageGtk.cpp
+++ b/WebCore/platform/gtk/DragImageGtk.cpp
@@ -21,7 +21,7 @@
#include "CachedImage.h"
#include "Image.h"
-#include "PlatformRefPtrCairo.h"
+#include "RefPtrCairo.h"
#include <cairo.h>
namespace WebCore {
@@ -49,7 +49,7 @@ DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
int newHeight = scale.height() * cairo_image_surface_get_height(image);
cairo_surface_t* scaledSurface = cairo_surface_create_similar(image, CAIRO_CONTENT_COLOR_ALPHA, newWidth, newHeight);
- PlatformRefPtr<cairo_t> context = adoptPlatformRef(cairo_create(scaledSurface));
+ RefPtr<cairo_t> context = adoptRef(cairo_create(scaledSurface));
cairo_scale(context.get(), scale.width(), scale.height());
cairo_pattern_set_extend(cairo_get_source(context.get()), CAIRO_EXTEND_PAD);
cairo_pattern_set_filter(cairo_get_source(context.get()), CAIRO_FILTER_BEST);
@@ -66,7 +66,7 @@ DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction)
if (!image)
return 0;
- PlatformRefPtr<cairo_t> context = adoptPlatformRef(cairo_create(image));
+ RefPtr<cairo_t> context = adoptRef(cairo_create(image));
cairo_set_operator(context.get(), CAIRO_OPERATOR_DEST_IN);
cairo_set_source_rgba(context.get(), 0, 0, 0, fraction);
cairo_paint(context.get());
diff --git a/WebCore/platform/gtk/PasteboardHelper.cpp b/WebCore/platform/gtk/PasteboardHelper.cpp
index 9f75728..228d5e9 100644
--- a/WebCore/platform/gtk/PasteboardHelper.cpp
+++ b/WebCore/platform/gtk/PasteboardHelper.cpp
@@ -38,6 +38,16 @@ static GdkAtom textPlainAtom = gdk_atom_intern("text/plain;charset=utf-8", FALSE
static GdkAtom markupAtom = gdk_atom_intern("text/html", FALSE);
static GdkAtom netscapeURLAtom = gdk_atom_intern("_NETSCAPE_URL", FALSE);
static GdkAtom uriListAtom = gdk_atom_intern("text/uri-list", FALSE);
+static String gMarkupPrefix = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">";
+
+static void removeMarkupPrefix(String& markup)
+{
+
+ // The markup prefix is not harmful, but we remove it from the string anyway, so that
+ // we can have consistent results with other ports during the layout tests.
+ if (markup.startsWith(gMarkupPrefix))
+ markup.remove(0, gMarkupPrefix.length());
+}
PasteboardHelper::PasteboardHelper()
: m_targetList(gtk_target_list_new(0, 0))
@@ -112,7 +122,9 @@ void PasteboardHelper::getClipboardContents(GtkClipboard* clipboard)
if (gtk_clipboard_wait_is_target_available(clipboard, markupAtom)) {
if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, markupAtom)) {
- dataObject->setMarkup(selectionDataToUTF8String(data));
+ String markup(selectionDataToUTF8String(data));
+ removeMarkupPrefix(markup);
+ dataObject->setMarkup(markup);
gtk_selection_data_free(data);
}
}
@@ -131,9 +143,11 @@ void PasteboardHelper::fillSelectionData(GtkSelectionData* selectionData, guint
gtk_selection_data_set_text(selectionData, dataObject->text().utf8().data(), -1);
else if (info == getIdForTargetType(TargetTypeMarkup)) {
- GOwnPtr<gchar> markup(g_strdup(dataObject->markup().utf8().data()));
+ // Some Linux applications refuse to accept pasted markup unless it is
+ // prefixed by a content-type meta tag.
+ CString markup = (gMarkupPrefix + dataObject->markup()).utf8();
gtk_selection_data_set(selectionData, markupAtom, 8,
- reinterpret_cast<const guchar*>(markup.get()), strlen(markup.get()) + 1);
+ reinterpret_cast<const guchar*>(markup.data()), markup.length() + 1);
} else if (info == getIdForTargetType(TargetTypeURIList)) {
CString uriList = dataObject->uriList().utf8();
@@ -187,9 +201,11 @@ void PasteboardHelper::fillDataObjectFromDropData(GtkSelectionData* data, guint
GdkAtom target = gtk_selection_data_get_target(data);
if (target == textPlainAtom)
dataObject->setText(selectionDataToUTF8String(data));
- else if (target == markupAtom)
- dataObject->setMarkup(selectionDataToUTF8String(data));
- else if (target == uriListAtom) {
+ else if (target == markupAtom) {
+ String markup(selectionDataToUTF8String(data));
+ removeMarkupPrefix(markup);
+ dataObject->setMarkup(markup);
+ } else if (target == uriListAtom) {
dataObject->setURIList(selectionDataToUTF8String(data));
} else if (target == netscapeURLAtom) {
String urlWithLabel(selectionDataToUTF8String(data));
diff --git a/WebCore/platform/gtk/PopupMenuGtk.cpp b/WebCore/platform/gtk/PopupMenuGtk.cpp
index a679734..e7ff78e 100644
--- a/WebCore/platform/gtk/PopupMenuGtk.cpp
+++ b/WebCore/platform/gtk/PopupMenuGtk.cpp
@@ -97,7 +97,7 @@ void PopupMenuGtk::show(const IntRect& rect, FrameView* view, int index)
GList* children = gtk_container_get_children(GTK_CONTAINER(m_popup.get()));
GList* p = children;
- if (size)
+ if (size) {
for (int i = 0; i < size; i++) {
if (i > index)
break;
@@ -112,9 +112,11 @@ void PopupMenuGtk::show(const IntRect& rect, FrameView* view, int index)
m_menuPosition.setY(m_menuPosition.y() - itemRequisition.height);
p = g_list_next(p);
- } else
- // Center vertically the empty popup in the combo box area
- m_menuPosition.setY(m_menuPosition.y() - rect.height() / 2);
+ }
+ } else {
+ // Center vertically the empty popup in the combo box area
+ m_menuPosition.setY(m_menuPosition.y() - rect.height() / 2);
+ }
g_list_free(children);
gtk_menu_popup(m_popup.get(), 0, 0, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, 0, gtk_get_current_event_time());
diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp
index fa61871..43ff33b 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/ImageDecoder.cpp
@@ -194,6 +194,11 @@ void RGBA32Buffer::setHasAlpha(bool alpha)
m_hasAlpha = alpha;
}
+void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile)
+{
+ m_colorProfile = colorProfile;
+}
+
void RGBA32Buffer::setStatus(FrameStatus status)
{
m_status = status;
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h
index 9fe0e6b..81d6dbb 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/ImageDecoder.h
@@ -47,6 +47,9 @@
namespace WebCore {
+ // FIXME: Do we want better encapsulation?
+ typedef Vector<char> ColorProfile;
+
// The RGBA32Buffer object represents the decoded image data in RGBA32
// format. This buffer is what all decoders write a single frame into.
// Frames are then instantiated for drawing by being handed this buffer.
@@ -131,6 +134,7 @@ namespace WebCore {
bool premultiplyAlpha() const { return m_premultiplyAlpha; }
void setHasAlpha(bool alpha);
+ void setColorProfile(const ColorProfile&);
void setRect(const IntRect& r) { m_rect = r; }
void setStatus(FrameStatus status);
void setDuration(unsigned duration) { m_duration = duration; }
@@ -202,6 +206,7 @@ namespace WebCore {
// same as ImageDecoder::m_size.
bool m_hasAlpha; // Whether or not any of the pixels in the buffer
// have transparency.
+ ColorProfile m_colorProfile;
#endif
IntRect m_rect; // The rect of the original specified frame within
// the overall buffer. This will always just be
@@ -354,6 +359,7 @@ namespace WebCore {
RefPtr<SharedBuffer> m_data; // The encoded data.
Vector<RGBA32Buffer> m_frameBufferCache;
+ ColorProfile m_colorProfile;
bool m_scaled;
Vector<int> m_scaledColumns;
Vector<int> m_scaledRows;
diff --git a/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp b/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp
index 2fac7da..0f4dbc8 100644
--- a/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp
+++ b/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp
@@ -31,11 +31,16 @@
namespace WebCore {
+static RGBA32Buffer::PixelData* getPtrAsPixelData(CFMutableDataRef data)
+{
+ return data ? reinterpret_cast<RGBA32Buffer::PixelData*>(CFDataGetMutableBytePtr(data)) : 0;
+}
+
void RGBA32Buffer::copyReferenceToBitmapData(const RGBA32Buffer& other)
{
ASSERT(this != &other);
m_backingStore = other.m_backingStore;
- m_bytes = reinterpret_cast<PixelData*>(CFDataGetMutableBytePtr(m_backingStore.get()));
+ m_bytes = getPtrAsPixelData(m_backingStore.get());
// FIXME: The rest of this function seems redundant with RGBA32Buffer::copyBitmapData.
m_size = other.m_size;
setHasAlpha(other.m_hasAlpha);
@@ -47,7 +52,7 @@ bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other)
return true;
m_backingStore.adoptCF(CFDataCreateMutableCopy(kCFAllocatorDefault, 0, other.m_backingStore.get()));
- m_bytes = reinterpret_cast<PixelData*>(CFDataGetMutableBytePtr(m_backingStore.get()));
+ m_bytes = getPtrAsPixelData(m_backingStore.get());
m_size = other.m_size;
setHasAlpha(other.m_hasAlpha);
return true;
@@ -64,15 +69,30 @@ bool RGBA32Buffer::setSize(int newWidth, int newHeight)
return true;
}
+static CGColorSpaceRef createColorSpace(const ColorProfile& colorProfile)
+{
+ if (colorProfile.isEmpty())
+ return CGColorSpaceCreateDeviceRGB();
+
+ RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(colorProfile.data()), colorProfile.size()));
+#if !defined(TARGETING_TIGER) && !defined(TARGETING_LEOPARD)
+ return CGColorSpaceCreateWithICCProfile(data.get());
+#else
+ RetainPtr<CGColorSpaceRef> deviceColorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGDataProviderRef> profileDataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
+ CGFloat ranges[] = {0.0, 255.0, 0.0, 255.0, 0.0, 255.0};
+ return CGColorSpaceCreateICCBased(3, ranges, profileDataProvider.get(), deviceColorSpace.get());
+#endif
+}
+
NativeImagePtr RGBA32Buffer::asNewNativeImage() const
{
- // FIXME: Figure out the right color space.
- DEFINE_STATIC_LOCAL(RetainPtr<CGColorSpaceRef>, deviceColorSpace, (AdoptCF, CGColorSpaceCreateDeviceRGB()));
+ RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, createColorSpace(m_colorProfile));
RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_backingStore.get()));
CGImageAlphaInfo alphaInfo = m_premultiplyAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaFirst;
- return CGImageCreate(width(), height(), 8, 32, width() * sizeof(PixelData), deviceColorSpace.get(),
+ return CGImageCreate(width(), height(), 8, 32, width() * sizeof(PixelData), colorSpace.get(),
alphaInfo | kCGBitmapByteOrder32Host, dataProvider.get(), 0, false, kCGRenderingIntentDefault);
}
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
index 4797495..18cd903 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -96,21 +96,24 @@ int GIFImageDecoder::repetitionCount() const
// This value can arrive at any point in the image data stream. Most GIFs
// in the wild declare it near the beginning of the file, so it usually is
// set by the time we've decoded the size, but (depending on the GIF and the
- // packets sent back by the webserver) not always. Our caller is
- // responsible for waiting until image decoding has finished to ask this if
- // it needs an authoritative answer. In the meantime, we should default to
- // "loop once".
- if (m_reader) {
- // Added wrinkle: ImageSource::clear() may destroy the reader, making
- // the result from the reader _less_ authoritative on future calls. To
- // detect this, the reader returns cLoopCountNotSeen (-2) instead of
- // cAnimationLoopOnce (0) when its current incarnation hasn't actually
- // seen a loop count yet; in this case we return our previously-cached
- // value.
- const int repetitionCount = m_reader->loop_count;
- if (repetitionCount != cLoopCountNotSeen)
- m_repetitionCount = repetitionCount;
- }
+ // packets sent back by the webserver) not always. If the reader hasn't
+ // seen a loop count yet, it will return cLoopCountNotSeen, in which case we
+ // should default to looping once (the initial value for
+ // |m_repetitionCount|).
+ //
+ // There are two additional wrinkles here. First, ImageSource::clear() may
+ // destroy the reader, making the result from the reader _less_
+ // authoritative on future calls if the recreated reader hasn't seen the
+ // loop count. We don't need to special-case this because in this case the
+ // new reader will once again return cLoopCountNotSeen, and we won't
+ // overwrite the cached correct value.
+ //
+ // Second, a GIF might never set a loop count at all, in which case we
+ // should continue to treat it as a "loop once" animation. We don't need
+ // special code here either, because in this case we'll never change
+ // |m_repetitionCount| from its default value.
+ if (m_reader && (m_reader->loop_count != cLoopCountNotSeen))
+ m_repetitionCount = m_reader->loop_count;
return m_repetitionCount;
}
@@ -295,8 +298,10 @@ bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration,
void GIFImageDecoder::gifComplete()
{
- if (m_reader)
- m_repetitionCount = m_reader->loop_count;
+ // Cache the repetition count, which is now as authoritative as it's ever
+ // going to be.
+ repetitionCount();
+
m_reader.clear();
}
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index 6c6c782..da35739 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -51,7 +51,13 @@
#endif
extern "C" {
+
#include "jpeglib.h"
+
+#if USE(ICCJPEG)
+#include "iccjpeg.h"
+#endif
+
}
#include <setjmp.h>
@@ -86,6 +92,24 @@ struct decoder_source_mgr {
JPEGImageReader* decoder;
};
+static ColorProfile readColorProfile(jpeg_decompress_struct* info)
+{
+#if USE(ICCJPEG)
+ JOCTET* profile;
+ unsigned int profileLength;
+
+ if (!read_icc_profile(info, &profile, &profileLength))
+ return ColorProfile();
+
+ ColorProfile colorProfile;
+ colorProfile.append(reinterpret_cast<char*>(profile), profileLength);
+ free(profile);
+ return colorProfile;
+#else
+ return ColorProfile();
+#endif
+}
+
class JPEGImageReader
{
public:
@@ -123,6 +147,11 @@ public:
src->pub.resync_to_restart = jpeg_resync_to_restart;
src->pub.term_source = term_source;
src->decoder = this;
+
+ // Enable these markers for the ICC color profile.
+ // Apparently there are 16 of these markers. I don't see anywhere in the header with this constant.
+ for (unsigned i = 0; i < 0xF; ++i)
+ jpeg_save_markers(&m_info, JPEG_APP0 + i, 0xFFFF);
}
~JPEGImageReader()
@@ -212,6 +241,8 @@ public:
if (!m_decoder->setSize(m_info.image_width, m_info.image_height))
return false;
+ m_decoder->setColorProfile(readColorProfile(info()));
+
if (m_decodingSizeOnly) {
// We can stop here. Reduce our buffer length and available
// data.
@@ -421,6 +452,7 @@ bool JPEGImageDecoder::outputScanlines()
return setFailed();
buffer.setStatus(RGBA32Buffer::FramePartial);
buffer.setHasAlpha(false);
+ buffer.setColorProfile(m_colorProfile);
// For JPEGs, the frame always fills the entire image.
buffer.setRect(IntRect(IntPoint(), size()));
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
index 5047019..e942b01 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -54,6 +54,8 @@ namespace WebCore {
bool outputScanlines();
void jpegComplete();
+ void setColorProfile(const ColorProfile& colorProfile) { m_colorProfile = colorProfile; }
+
private:
// Decodes the image. If |onlySize| is true, stops decoding after
// calculating the image size. If decoding fails but there is no more
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
index 940e4c4..e4f7a0c 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -220,6 +220,22 @@ bool PNGImageDecoder::setFailed()
return ImageDecoder::setFailed();
}
+static ColorProfile readColorProfile(png_structp png, png_infop info)
+{
+#ifdef PNG_iCCP_SUPPORTED
+ char* profileName;
+ int compressionType;
+ char* profile;
+ png_uint_32 profileLength;
+ if (png_get_iCCP(png, info, &profileName, &compressionType, &profile, &profileLength)) {
+ ColorProfile colorProfile;
+ colorProfile.append(profile, profileLength);
+ return colorProfile;
+ }
+#endif
+ return ColorProfile();
+}
+
void PNGImageDecoder::headerAvailable()
{
png_structp png = m_reader->pngPtr();
@@ -249,6 +265,16 @@ void PNGImageDecoder::headerAvailable()
int bitDepth, colorType, interlaceType, compressionType, filterType, channels;
png_get_IHDR(png, info, &width, &height, &bitDepth, &colorType, &interlaceType, &compressionType, &filterType);
+ if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_RGB_ALPHA) {
+ // We currently support color profiles only for RGB and RGBA PNGs. Supporting
+ // color profiles for gray-scale images is slightly tricky, at least using the
+ // CoreGraphics ICC library, because we expand gray-scale images to RGB but we
+ // don't similarly transform the color profile. We'd either need to transform
+ // the color profile or we'd need to decode into a gray-scale image buffer and
+ // hand that to CoreGraphics.
+ m_colorProfile = readColorProfile(png, info);
+ }
+
// The options we set here match what Mozilla does.
// Expand to ensure we use 24-bit for RGB and 32-bit for RGBA.
@@ -311,6 +337,7 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
}
buffer.setStatus(RGBA32Buffer::FramePartial);
buffer.setHasAlpha(false);
+ buffer.setColorProfile(m_colorProfile);
// For PNGs, the frame always fills the entire image.
buffer.setRect(IntRect(IntPoint(), size()));
diff --git a/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp b/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp
index a782373..998234f 100644
--- a/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp
+++ b/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp
@@ -28,6 +28,8 @@
#include "config.h"
#include "ImageDecoder.h"
+#include "NotImplemented.h"
+
#include <QPixmap>
#include <stdio.h>
@@ -124,6 +126,11 @@ void RGBA32Buffer::setHasAlpha(bool alpha)
m_hasAlpha = alpha;
}
+void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile)
+{
+ notImplemented();
+}
+
void RGBA32Buffer::setStatus(FrameStatus status)
{
m_status = status;
diff --git a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
index 7baca5f..50e2106 100644
--- a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
+++ b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
@@ -30,6 +30,8 @@
#include "SkBitmapRef.h"
#endif
+#include "NotImplemented.h"
+
namespace WebCore {
RGBA32Buffer::RGBA32Buffer()
@@ -116,6 +118,11 @@ void RGBA32Buffer::setHasAlpha(bool alpha)
m_bitmap.setIsOpaque(!alpha);
}
+void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile)
+{
+ notImplemented();
+}
+
void RGBA32Buffer::setStatus(FrameStatus status)
{
m_status = status;
diff --git a/WebCore/platform/mac/ContextMenuItemMac.mm b/WebCore/platform/mac/ContextMenuItemMac.mm
index 48da786..ce779ec 100644
--- a/WebCore/platform/mac/ContextMenuItemMac.mm
+++ b/WebCore/platform/mac/ContextMenuItemMac.mm
@@ -154,6 +154,11 @@ bool ContextMenuItem::enabled() const
return [m_platformDescription.get() isEnabled];
}
+bool ContextMenuItem::checked() const
+{
+ return [m_platformDescription.get() state] == NSOnState;
+}
+
} // namespace WebCore
#endif // ENABLE(CONTEXT_MENUS)
diff --git a/WebCore/platform/mac/ContextMenuMac.mm b/WebCore/platform/mac/ContextMenuMac.mm
index 8ced8cb..c427e3c 100644
--- a/WebCore/platform/mac/ContextMenuMac.mm
+++ b/WebCore/platform/mac/ContextMenuMac.mm
@@ -153,6 +153,19 @@ NSMutableArray* ContextMenu::releasePlatformDescription()
return m_platformDescription.releaseRef();
}
+Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription menu)
+{
+ Vector<ContextMenuItem> items;
+ unsigned count = [menu count];
+ if (menu)
+ items.reserveCapacity(count);
+
+ for (unsigned i = 0; i < count; ++i)
+ items.append(ContextMenuItem([menu objectAtIndex:i]));
+
+ return items;
+}
+
} // namespace WebCore
#endif // ENABLE(CONTEXT_MENUS)
diff --git a/WebCore/platform/mac/Language.mm b/WebCore/platform/mac/Language.mm
index bb51cb5..c242e9e 100644
--- a/WebCore/platform/mac/Language.mm
+++ b/WebCore/platform/mac/Language.mm
@@ -69,17 +69,20 @@ static NSString *createHTTPStyleLanguageCode(NSString *languageCode)
// Make the string lowercase.
NSString *lowercaseLanguageCode = [languageCode lowercaseString];
+ NSString *httpStyleLanguageCode;
+
// Turn a '_' into a '-' if it appears after a 2-letter language code.
- if ([lowercaseLanguageCode length] < 3 || [lowercaseLanguageCode characterAtIndex:2] != '_')
- return lowercaseLanguageCode;
-
- NSMutableString *result = [lowercaseLanguageCode mutableCopy];
- [result replaceCharactersInRange:NSMakeRange(2, 1) withString:@"-"];
-
+ if ([lowercaseLanguageCode length] >= 3 && [lowercaseLanguageCode characterAtIndex:2] == '_') {
+ NSMutableString *mutableLanguageCode = [lowercaseLanguageCode mutableCopy];
+ [mutableLanguageCode replaceCharactersInRange:NSMakeRange(2, 1) withString:@"-"];
+ httpStyleLanguageCode = mutableLanguageCode;
+ } else
+ httpStyleLanguageCode = [lowercaseLanguageCode retain];
+
if (preferredLanguageCode)
CFRelease(preferredLanguageCode);
- return result;
+ return httpStyleLanguageCode;
}
String platformDefaultLanguage()
diff --git a/WebCore/platform/mac/PurgeableBufferMac.cpp b/WebCore/platform/mac/PurgeableBufferMac.cpp
index 54de4ed..fdbac1f 100644
--- a/WebCore/platform/mac/PurgeableBufferMac.cpp
+++ b/WebCore/platform/mac/PurgeableBufferMac.cpp
@@ -35,7 +35,9 @@
namespace WebCore {
-static const size_t minPurgeableBufferSize = 4096; // one page
+// Purgeable buffers are allocated in multiples of the page size (4KB in common CPUs) so
+// it does not make sense for very small buffers. Set our minimum size to 16KB.
+static const size_t minPurgeableBufferSize = 4 * 4096;
PurgeableBuffer::PurgeableBuffer(char* data, size_t size)
: m_data(data)
@@ -143,17 +145,6 @@ bool PurgeableBuffer::wasPurged() const
return false;
}
-void PurgeableBuffer::setPurgePriority(PurgePriority priority)
-{
- if (priority == m_purgePriority)
- return;
- m_purgePriority = priority;
- if (m_state != Volatile)
- return;
- m_state = NonVolatile;
- makePurgeable(true);
-}
-
const char* PurgeableBuffer::data() const
{
ASSERT(m_state == NonVolatile);
diff --git a/WebCore/platform/network/curl/CookieJarCurl.cpp b/WebCore/platform/network/curl/CookieJarCurl.cpp
index 6f8a6b7..36495d0 100644
--- a/WebCore/platform/network/curl/CookieJarCurl.cpp
+++ b/WebCore/platform/network/curl/CookieJarCurl.cpp
@@ -61,9 +61,11 @@ void deleteCookie(const Document*, const KURL&, const String&)
// FIXME: Not yet implemented
}
+#if !PLATFORM(EFL)
void setCookieStoragePrivateBrowsingEnabled(bool enabled)
{
// FIXME: Not yet implemented
}
+#endif
}
diff --git a/WebCore/platform/network/soup/SocketStreamHandle.h b/WebCore/platform/network/soup/SocketStreamHandle.h
index 2ba4504..08d2d94 100644
--- a/WebCore/platform/network/soup/SocketStreamHandle.h
+++ b/WebCore/platform/network/soup/SocketStreamHandle.h
@@ -51,6 +51,7 @@ namespace WebCore {
void connected(GSocketConnection*, GError*);
void readBytes(signed long, GError*);
void writeReady();
+ void* id() { return m_id; }
protected:
virtual int platformSend(const char* data, int length);
@@ -62,6 +63,7 @@ namespace WebCore {
PlatformRefPtr<GOutputStream> m_outputStream;
PlatformRefPtr<GSource> m_writeReadySource;
char* m_readBuffer;
+ void* m_id;
SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
diff --git a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
index d73b499..7f62d5a 100644
--- a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
+++ b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
@@ -48,25 +48,34 @@
namespace WebCore {
// These functions immediately call the similarly named SocketStreamHandle methods.
-static void connectedCallback(GSocketClient*, GAsyncResult*, SocketStreamHandle*);
-static void readReadyCallback(GInputStream*, GAsyncResult*, SocketStreamHandle*);
-static gboolean writeReadyCallback(GSocket*, GIOCondition, SocketStreamHandle*);
+static void connectedCallback(GSocketClient*, GAsyncResult*, void*);
+static void readReadyCallback(GInputStream*, GAsyncResult*, void*);
+static gboolean writeReadyCallback(GSocket*, GIOCondition, void*);
// Having a list of active handles means that we do not have to worry about WebCore
// reference counting in GLib callbacks. Once the handle is off the active handles list
// we just ignore it in the callback. We avoid a lot of extra checks and tricky
// situations this way.
-static Vector<SocketStreamHandle*> gActiveHandles;
-bool isActiveHandle(SocketStreamHandle* handle)
+static HashMap<void*, SocketStreamHandle*> gActiveHandles;
+static SocketStreamHandle* getHandleFromId(void* id)
{
- return gActiveHandles.find(handle) != notFound;
+ if (!gActiveHandles.contains(id))
+ return 0;
+ return gActiveHandles.get(id);
}
-void deactivateHandle(SocketStreamHandle* handle)
+static void deactivateHandle(SocketStreamHandle* handle)
{
- size_t handleIndex = gActiveHandles.find(handle);
- if (handleIndex != notFound)
- gActiveHandles.remove(handleIndex);
+ gActiveHandles.remove(handle->id());
+}
+
+static void* activateHandle(SocketStreamHandle* handle)
+{
+ // The first id cannot be 0, because it conflicts with the HashMap emptyValue.
+ static gint currentHandleId = 1;
+ void* id = GINT_TO_POINTER(currentHandleId++);
+ gActiveHandles.set(id, handle);
+ return id;
}
SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
@@ -78,10 +87,10 @@ SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient
return;
unsigned int port = url.hasPort() ? url.port() : 80;
- gActiveHandles.append(this);
+ m_id = activateHandle(this);
PlatformRefPtr<GSocketClient> socketClient = adoptPlatformRef(g_socket_client_new());
g_socket_client_connect_to_host_async(socketClient.get(), url.host().utf8().data(), port, 0,
- reinterpret_cast<GAsyncReadyCallback>(connectedCallback), this);
+ reinterpret_cast<GAsyncReadyCallback>(connectedCallback), m_id);
}
SocketStreamHandle::~SocketStreamHandle()
@@ -104,7 +113,7 @@ void SocketStreamHandle::connected(GSocketConnection* socketConnection, GError*
m_readBuffer = new char[READ_BUFFER_SIZE];
g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0,
- reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);
+ reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id);
// The client can close the handle, potentially removing the last reference.
RefPtr<SocketStreamHandle> protect(this);
@@ -131,7 +140,7 @@ void SocketStreamHandle::readBytes(signed long bytesRead, GError* error)
m_client->didReceiveData(this, m_readBuffer, bytesRead);
if (m_inputStream) // The client may have closed the connection.
g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0,
- reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);
+ reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), m_id);
}
void SocketStreamHandle::writeReady()
@@ -215,7 +224,7 @@ void SocketStreamHandle::beginWaitingForSocketWritability()
m_writeReadySource = adoptPlatformRef(g_socket_create_source(
g_socket_connection_get_socket(m_socketConnection.get()), static_cast<GIOCondition>(G_IO_OUT), 0));
- g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), this, 0);
+ g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), m_id, 0);
g_source_attach(m_writeReadySource.get(), 0);
}
@@ -228,14 +237,15 @@ void SocketStreamHandle::stopWaitingForSocketWritability()
m_writeReadySource = 0;
}
-static void connectedCallback(GSocketClient* client, GAsyncResult* result, SocketStreamHandle* handle)
+static void connectedCallback(GSocketClient* client, GAsyncResult* result, void* id)
{
// Always finish the connection, even if this SocketStreamHandle was deactivated earlier.
GOwnPtr<GError> error;
GSocketConnection* socketConnection = g_socket_client_connect_to_host_finish(client, result, &error.outPtr());
// The SocketStreamHandle has been deactivated, so just close the connection, ignoring errors.
- if (!isActiveHandle(handle)) {
+ SocketStreamHandle* handle = getHandleFromId(id);
+ if (!handle) {
g_io_stream_close(G_IO_STREAM(socketConnection), 0, &error.outPtr());
return;
}
@@ -243,20 +253,23 @@ static void connectedCallback(GSocketClient* client, GAsyncResult* result, Socke
handle->connected(socketConnection, error.get());
}
-static void readReadyCallback(GInputStream* stream, GAsyncResult* result, SocketStreamHandle* handle)
+static void readReadyCallback(GInputStream* stream, GAsyncResult* result, void* id)
{
// Always finish the read, even if this SocketStreamHandle was deactivated earlier.
GOwnPtr<GError> error;
gssize bytesRead = g_input_stream_read_finish(stream, result, &error.outPtr());
- if (!isActiveHandle(handle))
+ SocketStreamHandle* handle = getHandleFromId(id);
+ if (!handle)
return;
+
handle->readBytes(bytesRead, error.get());
}
-static gboolean writeReadyCallback(GSocket*, GIOCondition condition, SocketStreamHandle* handle)
+static gboolean writeReadyCallback(GSocket*, GIOCondition condition, void* id)
{
- if (!isActiveHandle(handle))
+ SocketStreamHandle* handle = getHandleFromId(id);
+ if (!handle)
return FALSE;
// G_IO_HUP and G_IO_ERR are are always active. See:
diff --git a/WebCore/platform/qt/ContextMenuItemQt.cpp b/WebCore/platform/qt/ContextMenuItemQt.cpp
index b91a2a7..a65e50c 100644
--- a/WebCore/platform/qt/ContextMenuItemQt.cpp
+++ b/WebCore/platform/qt/ContextMenuItemQt.cpp
@@ -104,6 +104,12 @@ void ContextMenuItem::setChecked(bool on)
m_platformDescription.checked = on;
}
+bool ContextMenuItem::checked() const
+{
+ // FIXME - Implement
+ return false;
+}
+
void ContextMenuItem::setEnabled(bool on)
{
m_platformDescription.enabled = on;
diff --git a/WebCore/platform/qt/ContextMenuQt.cpp b/WebCore/platform/qt/ContextMenuQt.cpp
index 30c4c2d..2c1a6cb 100644
--- a/WebCore/platform/qt/ContextMenuQt.cpp
+++ b/WebCore/platform/qt/ContextMenuQt.cpp
@@ -74,6 +74,11 @@ PlatformMenuDescription ContextMenu::releasePlatformDescription()
return PlatformMenuDescription();
}
+Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription)
+{
+ // FIXME - Implement
+ return Vector<ContextMenuItem>();
+}
}
// vim: ts=4 sw=4 et
diff --git a/WebCore/platform/qt/PlatformScreenQt.cpp b/WebCore/platform/qt/PlatformScreenQt.cpp
index 8221760..db34e21 100644
--- a/WebCore/platform/qt/PlatformScreenQt.cpp
+++ b/WebCore/platform/qt/PlatformScreenQt.cpp
@@ -58,16 +58,30 @@ int screenDepth(Widget* w)
int screenDepthPerComponent(Widget* w)
{
+ int depth = QApplication::desktop()->screen(0)->depth();
if (w) {
QWebPageClient* client = w->root()->hostWindow()->platformPageClient();
if (client) {
QWidget* view = client->ownerWidget();
if (view)
- return view->depth();
+ depth = view->depth();
}
}
- return QApplication::desktop()->screen(0)->depth();
+ // An interface to establish the actual number of bits per color
+ // doesn't exist in Qt, or probably at all, so use common-sense
+ // values for each screen depth and assume RGB/RGBA where appropriate.
+ // Per http://www.w3.org/TR/css3-mediaqueries/#color, 'If different color
+ // components are represented by different number of bits, the smallest
+ // number is used.'
+ switch (depth) {
+ case 8:
+ return 2;
+ case 32:
+ return 8;
+ default:
+ return qRound(depth / 3);
+ }
}
bool screenIsMonochrome(Widget* w)
diff --git a/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp b/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp
index be3f302..990e331 100644
--- a/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp
+++ b/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp
@@ -300,7 +300,7 @@ int textBreakNext(TextBreakIterator* iterator)
if ((iterator->m_type == UBRK_LINE && iterator->m_logAttrs[index].is_line_break)
|| (iterator->m_type == UBRK_WORD && (iterator->m_logAttrs[index].is_word_start || iterator->m_logAttrs[index].is_word_end))
|| (iterator->m_type == UBRK_CHARACTER && iterator->m_logAttrs[index].is_cursor_position)
- || (iterator->m_type == UBRK_SENTENCE && (iterator->m_logAttrs[index].is_sentence_start || iterator->m_logAttrs[index].is_sentence_end)) ) {
+ || (iterator->m_type == UBRK_SENTENCE && iterator->m_logAttrs[index].is_sentence_boundary)) {
break;
}
}
@@ -315,7 +315,7 @@ int textBreakPrevious(TextBreakIterator* iterator)
if ((iterator->m_type == UBRK_LINE && iterator->m_logAttrs[index].is_line_break)
|| (iterator->m_type == UBRK_WORD && (iterator->m_logAttrs[index].is_word_start || iterator->m_logAttrs[index].is_word_end))
|| (iterator->m_type == UBRK_CHARACTER && iterator->m_logAttrs[index].is_cursor_position)
- || (iterator->m_type == UBRK_SENTENCE && (iterator->m_logAttrs[index].is_sentence_start || iterator->m_logAttrs[index].is_sentence_end)) ) {
+ || (iterator->m_type == UBRK_SENTENCE && iterator->m_logAttrs[index].is_sentence_boundary)) {
break;
}
}
diff --git a/WebCore/platform/text/gtk/TextCodecGtk.cpp b/WebCore/platform/text/gtk/TextCodecGtk.cpp
index bf6afcd..9308b33 100644
--- a/WebCore/platform/text/gtk/TextCodecGtk.cpp
+++ b/WebCore/platform/text/gtk/TextCodecGtk.cpp
@@ -543,9 +543,28 @@ CString TextCodecGtk::encode(const UChar* characters, size_t length, Unencodable
&error.outPtr());
input += bytesRead;
inputLength -= bytesRead;
- result.grow(size + bytesWritten);
- memcpy(result.data() + size, buffer, bytesWritten);
- size += bytesWritten;
+ if (bytesWritten > 0) {
+ result.grow(size + bytesWritten);
+ memcpy(result.data() + size, buffer, bytesWritten);
+ size += bytesWritten;
+ }
+
+ if (error && g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_INVALID_DATA)) {
+ UChar codePoint = reinterpret_cast<const UChar*>(input)[0];
+ UnencodableReplacementArray replacement;
+ int replacementLength = TextCodec::getUnencodableReplacement(codePoint, handling, replacement);
+
+ // Consume the invalid character.
+ input += sizeof(UChar);
+ inputLength -= sizeof(UChar);
+
+ // Append replacement string to result buffer.
+ result.grow(size + replacementLength);
+ memcpy(result.data() + size, replacement, replacementLength);
+ size += replacementLength;
+
+ error.clear();
+ }
} while (inputLength && !error.get());
if (error) {
diff --git a/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/WebCore/platform/win/ClipboardUtilitiesWin.cpp
index 19888bf..eb1e659 100644
--- a/WebCore/platform/win/ClipboardUtilitiesWin.cpp
+++ b/WebCore/platform/win/ClipboardUtilitiesWin.cpp
@@ -86,13 +86,13 @@ static bool getWebLocData(IDataObject* dataObject, String& url, String* title)
if (!hdrop)
return false;
- if (!DragQueryFileW(hdrop, 0, filename, ARRAYSIZE(filename)))
+ if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename)))
goto exit;
if (_wcsicmp(PathFindExtensionW(filename), L".url"))
goto exit;
- if (!GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, urlBuffer, ARRAYSIZE(urlBuffer), filename))
+ if (!GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, urlBuffer, WTF_ARRAY_LENGTH(urlBuffer), filename))
goto exit;
if (title) {
diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp
index f467d65..58cfe44 100644
--- a/WebCore/platform/win/ClipboardWin.cpp
+++ b/WebCore/platform/win/ClipboardWin.cpp
@@ -56,7 +56,7 @@
#include <wininet.h>
#include <wtf/RefPtr.h>
#include <wtf/text/CString.h>
-#include <wtf/text/StringConcatenate.h>
+#include <wtf/text/StringConcatenate.h>
#include <wtf/text/StringHash.h>
using namespace std;
@@ -99,6 +99,7 @@ static inline FORMATETC* fileContentFormatZero()
return &fileContentFormat;
}
+#if !OS(WINCE)
static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length)
{
size_t writeTo = 0;
@@ -112,9 +113,14 @@ static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length)
}
psz[writeTo] = 0;
}
+#endif
static String filesystemPathFromUrlOrTitle(const String& url, const String& title, TCHAR* extension, bool isLink)
{
+#if OS(WINCE)
+ notImplemented();
+ return String();
+#else
static const size_t fsPathMaxLengthExcludingNullTerminator = MAX_PATH - 1;
bool usedURL = false;
WCHAR fsPathBuffer[MAX_PATH];
@@ -159,25 +165,7 @@ static String filesystemPathFromUrlOrTitle(const String& url, const String& titl
String result(static_cast<UChar*>(fsPathBuffer));
result += String(static_cast<UChar*>(extension));
return result;
-}
-
-static HGLOBAL createGlobalURLContent(const CString& content)
-{
- HRESULT hr = S_OK;
- HGLOBAL memObj = 0;
-
- char* fileContents;
-
- memObj = GlobalAlloc(GPTR, content.length());
- if (!memObj)
- return 0;
-
- fileContents = (PSTR)GlobalLock(memObj);
- CopyMemory(fileContents, content.data(), content.length());
-
- GlobalUnlock(memObj);
-
- return memObj;
+#endif
}
static HGLOBAL createGlobalImageFileContent(SharedBuffer* data)
@@ -213,9 +201,13 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share
else
return 0;
} else {
+#if OS(WINCE)
+ notImplemented();
+ return 0;
+#else
WCHAR tempPath[MAX_PATH];
WCHAR extension[MAX_PATH];
- if (!::GetTempPath(ARRAYSIZE(tempPath), tempPath))
+ if (!::GetTempPath(WTF_ARRAY_LENGTH(tempPath), tempPath))
return 0;
if (!::PathAppend(tempPath, fileName.charactersWithNullTermination()))
return 0;
@@ -242,6 +234,7 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share
CloseHandle(tempFileHandle);
if (!tempWriteSucceeded)
return 0;
+#endif
}
SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * (wcslen(filePath) + 2));
@@ -258,36 +251,6 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share
return memObj;
}
-static HGLOBAL createGlobalUrlFileDescriptor(const String& url, const String& title, const CString& content)
-{
- HRESULT hr = S_OK;
- HGLOBAL memObj = 0;
- String fsPath;
- memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
- if (!memObj)
- return 0;
-
- FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj);
- memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR));
- fgd->cItems = 1;
- fgd->fgd[0].dwFlags = FD_FILESIZE;
- fgd->fgd[0].nFileSizeLow = content.length();
- fsPath = filesystemPathFromUrlOrTitle(url, title, L".URL", true);
-
- if (fsPath.length() <= 0) {
- GlobalUnlock(memObj);
- GlobalFree(memObj);
- return 0;
- }
-
- int maxSize = min(fsPath.length(), ARRAYSIZE(fgd->fgd[0].cFileName));
- CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar));
- GlobalUnlock(memObj);
-
- return memObj;
-}
-
-
static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& title, CachedImage* image)
{
ASSERT_ARG(image, image);
@@ -322,7 +285,7 @@ static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String&
return 0;
}
- int maxSize = min(fsPath.length(), ARRAYSIZE(fgd->fgd[0].cFileName));
+ int maxSize = min(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar));
GlobalUnlock(memObj);
@@ -355,11 +318,13 @@ static HRESULT writeFileToDataObject(IDataObject* dataObject, HGLOBAL fileDescri
if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))
goto exit;
+#if PLATFORM(CF)
// HDROP
if (hDropContent) {
medium.hGlobal = hDropContent;
hr = dataObject->SetData(cfHDropFormat(), &medium, TRUE);
}
+#endif
exit:
if (FAILED(hr)) {
@@ -567,6 +532,10 @@ HashSet<String> ClipboardWin::types() const
PassRefPtr<FileList> ClipboardWin::files() const
{
+#if OS(WINCE)
+ notImplemented();
+ return 0;
+#else
RefPtr<FileList> files = FileList::create();
if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
return files.release();
@@ -585,7 +554,7 @@ PassRefPtr<FileList> ClipboardWin::files() const
WCHAR filename[MAX_PATH];
UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
for (UINT i = 0; i < fileCount; i++) {
- if (!DragQueryFileW(hdrop, i, filename, ARRAYSIZE(filename)))
+ if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
continue;
files->append(File::create(reinterpret_cast<UChar*>(filename)));
}
@@ -593,6 +562,7 @@ PassRefPtr<FileList> ClipboardWin::files() const
GlobalUnlock(medium.hGlobal);
ReleaseStgMedium(&medium);
return files.release();
+#endif
}
void ClipboardWin::setDragImage(CachedImage* image, Node *node, const IntPoint &loc)
@@ -725,16 +695,36 @@ void ClipboardWin::writeURL(const KURL& kurl, const String& titleStr, Frame*)
String url = kurl.string();
ASSERT(url.containsOnlyASCII()); // KURL::string() is URL encoded.
+ String fsPath = filesystemPathFromUrlOrTitle(url, titleStr, L".URL", true);
CString content = makeString("[InternetShortcut]\r\nURL=", url, "\r\n").ascii();
- HGLOBAL urlFileDescriptor = createGlobalUrlFileDescriptor(url, titleStr, content);
+ if (fsPath.length() <= 0)
+ return;
+
+ HGLOBAL urlFileDescriptor = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
if (!urlFileDescriptor)
return;
- HGLOBAL urlFileContent = createGlobalURLContent(content);
+
+ HGLOBAL urlFileContent = GlobalAlloc(GPTR, content.length());
if (!urlFileContent) {
GlobalFree(urlFileDescriptor);
return;
}
+
+ FILEGROUPDESCRIPTOR* fgd = static_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(urlFileDescriptor));
+ ZeroMemory(fgd, sizeof(FILEGROUPDESCRIPTOR));
+ fgd->cItems = 1;
+ fgd->fgd[0].dwFlags = FD_FILESIZE;
+ fgd->fgd[0].nFileSizeLow = content.length();
+
+ unsigned maxSize = min(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
+ CopyMemory(fgd->fgd[0].cFileName, fsPath.characters(), maxSize * sizeof(UChar));
+ GlobalUnlock(urlFileDescriptor);
+
+ char* fileContents = static_cast<char*>(GlobalLock(urlFileContent));
+ CopyMemory(fileContents, content.data(), content.length());
+ GlobalUnlock(urlFileContent);
+
writeFileToDataObject(m_writableDataObject.get(), urlFileDescriptor, urlFileContent, 0);
}
diff --git a/WebCore/platform/win/ContextMenuItemWin.cpp b/WebCore/platform/win/ContextMenuItemWin.cpp
index ade0db0..d2ce76d 100644
--- a/WebCore/platform/win/ContextMenuItemWin.cpp
+++ b/WebCore/platform/win/ContextMenuItemWin.cpp
@@ -184,6 +184,12 @@ void ContextMenuItem::setChecked(bool checked)
}
}
+bool ContextMenuItem::checked() const
+{
+ // FIXME - Implement
+ return false;
+}
+
void ContextMenuItem::setEnabled(bool enabled)
{
m_platformDescription->fMask |= MIIM_STATE;
diff --git a/WebCore/platform/win/ContextMenuWin.cpp b/WebCore/platform/win/ContextMenuWin.cpp
index 5260866..82511e4 100644
--- a/WebCore/platform/win/ContextMenuWin.cpp
+++ b/WebCore/platform/win/ContextMenuWin.cpp
@@ -155,4 +155,10 @@ HMENU ContextMenu::releasePlatformDescription()
return description;
}
+Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription)
+{
+ // FIXME - Implement
+ return Vector<ContextMenuItem>();
+}
+
}
diff --git a/WebCore/platform/win/DragDataWin.cpp b/WebCore/platform/win/DragDataWin.cpp
index 05f9103..56345e2 100644
--- a/WebCore/platform/win/DragDataWin.cpp
+++ b/WebCore/platform/win/DragDataWin.cpp
@@ -72,7 +72,7 @@ void DragData::asFilenames(Vector<String>& result) const
const unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
for (unsigned i = 0; i < numFiles; i++) {
- if (!DragQueryFileW(hdrop, 0, filename, ARRAYSIZE(filename)))
+ if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename)))
continue;
result.append((UChar*)filename);
}
diff --git a/WebCore/platform/win/FileSystemWin.cpp b/WebCore/platform/win/FileSystemWin.cpp
index 2cca08c..cef7196 100644
--- a/WebCore/platform/win/FileSystemWin.cpp
+++ b/WebCore/platform/win/FileSystemWin.cpp
@@ -274,7 +274,7 @@ bool safeCreateFile(const String& path, CFDataRef data)
{
// Create a temporary file.
WCHAR tempDirPath[MAX_PATH];
- if (!GetTempPathW(ARRAYSIZE(tempDirPath), tempDirPath))
+ if (!GetTempPathW(WTF_ARRAY_LENGTH(tempDirPath), tempDirPath))
return false;
WCHAR tempPath[MAX_PATH];
diff --git a/WebCore/platform/win/WCDataObject.cpp b/WebCore/platform/win/WCDataObject.cpp
index aaa41cf..6b4c859 100644
--- a/WebCore/platform/win/WCDataObject.cpp
+++ b/WebCore/platform/win/WCDataObject.cpp
@@ -285,6 +285,7 @@ void WCDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC
{
switch(pMedSrc->tymed)
{
+#if !OS(WINCE)
case TYMED_HGLOBAL:
pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal,pFmtSrc->cfFormat, 0);
break;
@@ -300,6 +301,7 @@ void WCDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC
case TYMED_FILE:
pMedSrc->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName,pFmtSrc->cfFormat, 0);
break;
+#endif
case TYMED_ISTREAM:
pMedDest->pstm = pMedSrc->pstm;
pMedSrc->pstm->AddRef();