summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/Android.mk12
-rw-r--r--Source/WebCore/dom/Document.cpp8
-rw-r--r--Source/WebCore/dom/Document.h8
-rw-r--r--Source/WebCore/dom/Element.cpp20
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp10
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp16
-rw-r--r--Source/WebCore/html/HTMLMetaElement.cpp14
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.cpp2
-rw-r--r--Source/WebCore/loader/EmptyClients.h4
-rw-r--r--Source/WebCore/page/ChromeClient.h4
-rw-r--r--Source/WebCore/page/Geolocation.cpp12
-rw-r--r--Source/WebCore/page/GeolocationController.cpp3
-rw-r--r--Source/WebCore/page/Settings.cpp2
-rw-r--r--Source/WebCore/page/Settings.h8
-rw-r--r--Source/WebCore/platform/GeolocationService.h5
-rw-r--r--Source/WebCore/platform/android/GeolocationServiceAndroid.cpp204
-rw-r--r--Source/WebCore/platform/android/GeolocationServiceAndroid.h79
-rw-r--r--Source/WebCore/platform/android/GeolocationServiceBridge.cpp246
-rw-r--r--Source/WebCore/platform/android/PlatformBridge.h6
-rw-r--r--Source/WebCore/platform/android/RenderThemeAndroid.cpp64
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.cpp8
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.h1
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayerPrivate.h4
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp45
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h10
-rw-r--r--Source/WebCore/platform/graphics/android/ImageAndroid.cpp1
-rw-r--r--Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp20
-rw-r--r--Source/WebCore/platform/graphics/android/ImageBufferDataAndroid.h5
-rw-r--r--Source/WebCore/platform/graphics/android/PathAndroid.cpp1
-rw-r--r--Source/WebCore/platform/graphics/android/PatternAndroid.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp12
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperation.cpp (renamed from Source/WebCore/platform/graphics/android/context/android_graphics.h)37
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperation.h629
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp63
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp46
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h40
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp805
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h125
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp39
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h25
-rw-r--r--Source/WebCore/platform/graphics/android/context/RTree.cpp589
-rw-r--r--Source/WebCore/platform/graphics/android/context/RTree.h180
-rw-r--r--Source/WebCore/platform/graphics/android/context/RecordingContextCanvasProxy.cpp (renamed from Source/WebCore/platform/android/GeolocationServiceBridge.h)68
-rw-r--r--Source/WebCore/platform/graphics/android/context/RecordingContextCanvasProxy.h102
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp145
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp7
-rw-r--r--Source/WebCore/platform/graphics/android/layers/DumpLayer.cpp88
-rw-r--r--Source/WebCore/platform/graphics/android/layers/DumpLayer.h66
-rw-r--r--Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp28
-rw-r--r--Source/WebCore/platform/graphics/android/layers/FixedPositioning.h2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.h2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp64
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h8
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerContent.h2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/MediaPlayerPrivateAndroid.h4
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp15
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h1
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp10
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h13
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerManager.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp19
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp1
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLUtils.h4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/InstrumentedPlatformCanvas.h305
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp53
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h8
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp80
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp28
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp31
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp21
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h10
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.cpp11
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.h8
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp42
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.h25
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp23
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.h6
-rw-r--r--Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp180
-rw-r--r--Source/WebCore/platform/graphics/android/utils/LinearAllocator.h (renamed from Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h)59
-rw-r--r--Source/WebCore/platform/mock/GeolocationServiceMock.cpp5
-rwxr-xr-xSource/WebCore/platform/mock/GeolocationServiceMock.h5
-rw-r--r--Source/WebCore/plugins/android/PluginViewAndroid.cpp16
96 files changed, 3206 insertions, 1836 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk
index 742fade..10eb822 100644
--- a/Source/WebCore/Android.mk
+++ b/Source/WebCore/Android.mk
@@ -496,6 +496,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
page/FrameTree.cpp \
page/FrameView.cpp \
page/Geolocation.cpp \
+ page/GeolocationController.cpp \
page/GeolocationPositionCache.cpp \
page/GroupSettings.cpp \
page/History.cpp \
@@ -545,7 +546,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/FileChooser.cpp \
platform/FileStream.cpp \
platform/FileSystem.cpp \
- platform/GeolocationService.cpp \
platform/KURL.cpp \
platform/KURLGoogle.cpp \
platform/KillRingNone.cpp \
@@ -576,8 +576,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/android/EventLoopAndroid.cpp \
platform/android/FileChooserAndroid.cpp \
platform/android/FileSystemAndroid.cpp \
- platform/android/GeolocationServiceAndroid.cpp \
- platform/android/GeolocationServiceBridge.cpp \
platform/android/KeyEventAndroid.cpp \
platform/android/LanguageAndroid.cpp \
platform/android/LocalizedStringsAndroid.cpp \
@@ -644,10 +642,12 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/SharedBufferStream.cpp \
\
platform/graphics/android/context/GraphicsContextAndroid.cpp \
- platform/graphics/android/context/GraphicsOperationCollection.cpp \
+ platform/graphics/android/context/GraphicsOperation.cpp \
platform/graphics/android/context/PlatformGraphicsContext.cpp \
platform/graphics/android/context/PlatformGraphicsContextRecording.cpp \
platform/graphics/android/context/PlatformGraphicsContextSkia.cpp \
+ platform/graphics/android/context/RecordingContextCanvasProxy.cpp \
+ platform/graphics/android/context/RTree.cpp \
\
platform/graphics/android/fonts/FontAndroid.cpp \
platform/graphics/android/fonts/FontCacheAndroid.cpp \
@@ -699,7 +699,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/rendering/TilesProfiler.cpp \
platform/graphics/android/rendering/TransferQueue.cpp \
\
- platform/graphics/android/utils/ClassTracker.cpp
+ platform/graphics/android/utils/ClassTracker.cpp \
+ platform/graphics/android/utils/LinearAllocator.cpp
ifeq ($(ENABLE_SVG), true)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
@@ -757,7 +758,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
\
platform/mock/DeviceOrientationClientMock.cpp \
platform/mock/GeolocationClientMock.cpp \
- platform/mock/GeolocationServiceMock.cpp \
platform/mock/SpeechInputClientMock.cpp \
\
platform/network/AuthenticationChallengeBase.cpp \
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index b6a1393..063b8a2 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -387,9 +387,6 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_compatibilityMode(NoQuirksMode)
, m_compatibilityModeLocked(false)
, m_domTreeVersion(++s_globalTreeVersion)
-#ifdef ANDROID_STYLE_VERSION
- , m_styleVersion(0)
-#endif
, m_styleSheets(StyleSheetList::create(this))
, m_readyState(Complete)
, m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
@@ -4880,11 +4877,6 @@ void Document::webkitCancelFullScreen()
return;
page()->chrome()->client()->exitFullScreenForElement(m_fullScreenElement.get());
-#if PLATFORM(ANDROID)
- // The next time we try to enter full screen, we need this change to know
- // we are not in full screen any more.
- m_fullScreenElement = 0;
-#endif
}
void Document::webkitWillEnterFullScreenForElement(Element* element)
diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h
index ce82b2e..c4ccb9c 100644
--- a/Source/WebCore/dom/Document.h
+++ b/Source/WebCore/dom/Document.h
@@ -905,11 +905,6 @@ public:
void incDOMTreeVersion() { m_domTreeVersion = ++s_globalTreeVersion; }
uint64_t domTreeVersion() const { return m_domTreeVersion; }
-#ifdef ANDROID_STYLE_VERSION
- void incStyleVersion() { ++m_styleVersion; }
- unsigned styleVersion() const { return m_styleVersion; }
-#endif
-
void setDocType(PassRefPtr<DocumentType>);
#if ENABLE(XPATH)
@@ -1223,9 +1218,6 @@ private:
uint64_t m_domTreeVersion;
static uint64_t s_globalTreeVersion;
-#ifdef ANDROID_STYLE_VERSION
- unsigned m_styleVersion;
-#endif
HashSet<NodeIterator*> m_nodeIterators;
HashSet<Range*> m_ranges;
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
index 64d3eed..5fb6cdc 100644
--- a/Source/WebCore/dom/Element.cpp
+++ b/Source/WebCore/dom/Element.cpp
@@ -1069,21 +1069,6 @@ bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderS
return false;
}
-#ifdef ANDROID_STYLE_VERSION
-static bool displayDiff(const RenderStyle* s1, const RenderStyle* s2)
-{
- if (!s1 && !s2)
- return false;
- else if ((!s1 && s2) || (s1 && !s2))
- return true;
-
- return s1->display() != s2->display()
- || s1->left() != s2->left() || s1->top() != s2->top()
- || s1->right() != s2->right() || s1->bottom() != s2->bottom()
- || s1->width() != s2->width() || s1->height() != s2->height();
-}
-#endif
-
void Element::recalcStyle(StyleChange change)
{
// Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
@@ -1092,11 +1077,6 @@ void Element::recalcStyle(StyleChange change)
bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
if ((change > NoChange || needsStyleRecalc())) {
-#ifdef ANDROID_STYLE_VERSION
- RefPtr<RenderStyle> newStyle = document()->styleForElementIgnoringPendingStylesheets(this);
- if (displayDiff(currentStyle.get(), newStyle.get()))
- document()->incStyleVersion();
-#endif
if (hasRareData())
rareData()->resetComputedStyle();
}
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 36cdf51..27b29a8 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -444,10 +444,6 @@ void HTMLInputElement::setType(const String& type)
void HTMLInputElement::updateType()
{
OwnPtr<InputType> newType = InputType::create(this, fastGetAttribute(typeAttr));
-#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
- if (newType->isPasswordField() && document()->focusedNode() == this)
- PlatformBridge::updateTextfield(document()->view(), this, true, String());
-#endif
bool hadType = m_hasType;
m_hasType = true;
if (m_inputType->formControlType() == newType->formControlType())
@@ -912,7 +908,7 @@ void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
unsigned max = m_data.value().length();
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
// Make sure our UI side textfield changes to match the RenderTextControl
- PlatformBridge::updateTextfield(document()->view(), this, false, value);
+ PlatformBridge::updateTextfield(document()->view(), this, value);
#endif
if (document()->focusedNode() == this)
InputElement::updateSelectionRange(this, this, max, max);
@@ -1573,7 +1569,11 @@ bool HTMLInputElement::hasSpinButton() const
bool HTMLInputElement::supportsPlaceholder() const
{
+#if PLATFORM(ANDROID)
+ return isTextType() || isNumberField();
+#else
return isTextType();
+#endif
}
CheckedRadioButtons& HTMLInputElement::checkedRadioButtons() const
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index 328b6db..f3cc170 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -185,9 +185,9 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum
document->registerForDocumentActivationCallbacks(this);
document->registerForMediaVolumeCallbacks(this);
document->registerForPrivateBrowsingStateChangedCallbacks(this);
-#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
- m_restrictions |= RequireUserGestureForRateChangeRestriction;
-#endif
+
+ if (document->settings() && document->settings()->mediaPlaybackRequiresUserGesture())
+ m_restrictions |= RequireUserGestureForRateChangeRestriction;
}
HTMLMediaElement::~HTMLMediaElement()
@@ -1036,7 +1036,10 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
scheduleEvent(eventNames().playingEvent);
-
+#if PLATFORM(ANDROID)
+ // autoplay should not be honored if we require user gesture.
+ if (!(m_restrictions & RequireUserGestureForRateChangeRestriction))
+#endif
if (m_autoplaying && m_paused && autoplay()) {
m_paused = false;
invalidateCachedTime();
@@ -2272,8 +2275,11 @@ void HTMLMediaElement::stopPeriodicTimers()
void HTMLMediaElement::userCancelledLoad()
{
LOG(Media, "HTMLMediaElement::userCancelledLoad");
-
+#if PLATFORM(ANDROID)
+ if (m_networkState == NETWORK_EMPTY)
+#else
if (m_networkState == NETWORK_EMPTY || m_completelyLoaded)
+#endif
return;
// If the media data fetching process is aborted by the user:
diff --git a/Source/WebCore/html/HTMLMetaElement.cpp b/Source/WebCore/html/HTMLMetaElement.cpp
index cb7f4c0..4f65065 100644
--- a/Source/WebCore/html/HTMLMetaElement.cpp
+++ b/Source/WebCore/html/HTMLMetaElement.cpp
@@ -32,10 +32,6 @@
#include "Settings.h"
#endif
-#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
-#include "ChromeClient.h"
-#endif
-
namespace WebCore {
using namespace HTMLNames;
@@ -89,16 +85,6 @@ void HTMLMetaElement::process()
}
#endif
-#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
- // If this web site is informing us it is possible for it to be installed, inform the chrome
- // client so it can offer this to the user.
- if (equalIgnoringCase(name(), "fullscreen-web-app-capable")
- && equalIgnoringCase(m_content, "yes")) {
- if (Page* page = document()->page())
- page->chrome()->client()->webAppCanBeInstalled();
- }
-#endif
-
// Get the document to process the tag, but only if we're actually part of DOM tree (changing a meta tag while
// it's not in the tree shouldn't have any effect on the document)
if (!m_equiv.isNull())
diff --git a/Source/WebCore/html/HTMLTextAreaElement.cpp b/Source/WebCore/html/HTMLTextAreaElement.cpp
index 5b12a14..50471d1 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.cpp
+++ b/Source/WebCore/html/HTMLTextAreaElement.cpp
@@ -329,7 +329,7 @@ void HTMLTextAreaElement::setValueCommon(const String& value)
if (document()->focusedNode() == this) {
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
// Make sure our UI side textfield changes to match the RenderTextControl
- PlatformBridge::updateTextfield(document()->view(), this, false, value);
+ PlatformBridge::updateTextfield(document()->view(), this, value);
#endif
unsigned endOfString = m_value.length();
setSelectionRange(endOfString, endOfString);
diff --git a/Source/WebCore/loader/EmptyClients.h b/Source/WebCore/loader/EmptyClients.h
index 45df6ec..058db37 100644
--- a/Source/WebCore/loader/EmptyClients.h
+++ b/Source/WebCore/loader/EmptyClients.h
@@ -97,10 +97,6 @@ public:
virtual float scaleFactor() { return 1.f; }
-#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
- virtual void webAppCanBeInstalled() { }
-#endif
-
virtual void focus() { }
virtual void unfocus() { }
diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
index 91511ac..0ec366b 100644
--- a/Source/WebCore/page/ChromeClient.h
+++ b/Source/WebCore/page/ChromeClient.h
@@ -319,10 +319,6 @@ namespace WebCore {
};
virtual void willRunModalDialogDuringPageDismissal(const DialogType&) const { }
-#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS)
- virtual void webAppCanBeInstalled() = 0;
-#endif
-
protected:
virtual ~ChromeClient() { }
};
diff --git a/Source/WebCore/page/Geolocation.cpp b/Source/WebCore/page/Geolocation.cpp
index f0dd76a..352e06b 100644
--- a/Source/WebCore/page/Geolocation.cpp
+++ b/Source/WebCore/page/Geolocation.cpp
@@ -708,20 +708,8 @@ bool Geolocation::startUpdating(GeoNotifier* notifier)
page->geolocationController()->addObserver(this, notifier->m_options->enableHighAccuracy());
return true;
#else
-#if PLATFORM(ANDROID)
- // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
- // Note that the correct fix is to use a 'paused' flag in WebCore, rather
- // than calling into PlatformBridge.
- if (!m_frame)
- return false;
- FrameView* view = m_frame->view();
- if (!view)
- return false;
- return m_service->startUpdating(notifier->m_options.get(), PlatformBridge::isWebViewPaused(view));
-#else
return m_service->startUpdating(notifier->m_options.get());
#endif
-#endif
}
void Geolocation::stopUpdating()
diff --git a/Source/WebCore/page/GeolocationController.cpp b/Source/WebCore/page/GeolocationController.cpp
index b9533ca..56c11a5 100644
--- a/Source/WebCore/page/GeolocationController.cpp
+++ b/Source/WebCore/page/GeolocationController.cpp
@@ -59,7 +59,10 @@ void GeolocationController::addObserver(Geolocation* observer, bool enableHighAc
if (m_client) {
if (enableHighAccuracy)
m_client->setEnableHighAccuracy(true);
+// See https://bugs.webkit.org/show_bug.cgi?id=87030
+#if !PLATFORM(ANDROID)
if (wasEmpty)
+#endif
m_client->startUpdating();
}
}
diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp
index f668f3e..79e38d1 100644
--- a/Source/WebCore/page/Settings.cpp
+++ b/Source/WebCore/page/Settings.cpp
@@ -201,6 +201,8 @@ Settings::Settings(Page* page)
#else
, m_passwordEchoEnabled(false)
#endif
+ , m_mediaPlaybackRequiresUserGesture(false)
+ , m_mediaPlaybackAllowsInline(true)
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h
index 2cf7715..84828ab 100644
--- a/Source/WebCore/page/Settings.h
+++ b/Source/WebCore/page/Settings.h
@@ -479,6 +479,12 @@ namespace WebCore {
bool blockNetworkImage() const { return m_blockNetworkImage; }
#endif
+ void setMediaPlaybackRequiresUserGesture(bool flag) { m_mediaPlaybackRequiresUserGesture = flag; };
+ bool mediaPlaybackRequiresUserGesture() const { return m_mediaPlaybackRequiresUserGesture; }
+
+ void setMediaPlaybackAllowsInline(bool flag) { m_mediaPlaybackAllowsInline = flag; };
+ bool mediaPlaybackAllowsInline() const { return m_mediaPlaybackAllowsInline; }
+
private:
Page* m_page;
@@ -633,6 +639,8 @@ namespace WebCore {
#ifdef ANDROID_PLUGINS
bool m_pluginsOnDemand : 1;
#endif
+ bool m_mediaPlaybackRequiresUserGesture : 1;
+ bool m_mediaPlaybackAllowsInline : 1;
bool m_passwordEchoEnabled : 1;
#if USE(SAFARI_THEME)
diff --git a/Source/WebCore/platform/GeolocationService.h b/Source/WebCore/platform/GeolocationService.h
index 27be6c3..1045bb3 100644
--- a/Source/WebCore/platform/GeolocationService.h
+++ b/Source/WebCore/platform/GeolocationService.h
@@ -48,12 +48,7 @@ public:
static GeolocationService* create(GeolocationServiceClient*);
virtual ~GeolocationService() { }
-#if PLATFORM(ANDROID)
- // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
- virtual bool startUpdating(PositionOptions*, bool suspend) { return false; }
-#else
virtual bool startUpdating(PositionOptions*) { return false; }
-#endif
virtual void stopUpdating() { }
virtual void suspend() { }
diff --git a/Source/WebCore/platform/android/GeolocationServiceAndroid.cpp b/Source/WebCore/platform/android/GeolocationServiceAndroid.cpp
deleted file mode 100644
index 0f07722..0000000
--- a/Source/WebCore/platform/android/GeolocationServiceAndroid.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright 2009, 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 "GeolocationServiceAndroid.h"
-
-#include "Geolocation.h"
-#include "GeolocationServiceBridge.h"
-#include "Geoposition.h"
-#include "PositionError.h"
-#include "PositionOptions.h"
-
-#if PLATFORM(ANDROID)
-// Required for sim-eng build
-#include <math.h>
-#endif
-#include <wtf/CurrentTime.h>
-
-using JSC::Bindings::getJNIEnv;
-using namespace std;
-
-namespace WebCore {
-
-// GeolocationServiceAndroid is the Android implmentation of Geolocation
-// service. Each object of this class owns an object of type
-// GeolocationServiceBridge, which in turn owns a Java GeolocationService
-// object. Therefore, there is a 1:1 mapping between Geolocation,
-// GeolocationServiceAndroid, GeolocationServiceBridge and Java
-// GeolocationService objects. In the case where multiple Geolocation objects
-// exist simultaneously, the corresponsing Java GeolocationService objects all
-// register with the platform location service. It is the platform service that
-// handles making sure that updates are passed to all Geolocation objects.
-GeolocationService* GeolocationServiceAndroid::create(GeolocationServiceClient* client)
-{
- return new GeolocationServiceAndroid(client);
-}
-
-GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceAndroid::create;
-
-GeolocationServiceAndroid::GeolocationServiceAndroid(GeolocationServiceClient* client)
- : GeolocationService(client)
- , m_timer(this, &GeolocationServiceAndroid::timerFired)
- , m_javaBridge(0)
-{
-}
-
-// ANDROID
-// TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
-bool GeolocationServiceAndroid::startUpdating(PositionOptions* options, bool suspend)
-{
- // ANDROID
- // This is an ugly hack. A correct fix would require a change to WebCore,
- // but this isn't worth the effort as we're in the process of switching to a
- // client-based implementation. See https://bugs.webkit.org/show_bug.cgi?id=40373
- Frame* frame = reinterpret_cast<Geolocation*>(geolocationServiceClient())->frame();
- if (!frame)
- return false;
-
- // This method is called every time a new watch or one-shot position request
- // is started. If we already have a position or an error, call back
- // immediately.
- if (m_lastPosition || m_lastError) {
- ASSERT(m_javaBridge);
- m_timer.startOneShot(0);
- }
-
- // Lazilly create the Java object.
- bool haveJavaBridge = m_javaBridge;
- if (!haveJavaBridge)
- m_javaBridge.set(new GeolocationServiceBridge(this, frame));
- ASSERT(m_javaBridge);
-
- // On Android, high power == GPS. Set whether to use GPS before we start the
- // implementation.
- ASSERT(options);
- if (options->enableHighAccuracy())
- m_javaBridge->setEnableGps(true);
-
- // We need only start the service when it's first created.
- if (!haveJavaBridge) {
- // If the browser is paused, don't start the service. It will be started
- // when we get the call to resume.
- // ANDROID
- // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
- if (!suspend)
- return m_javaBridge->start();
- }
-
- return true;
-}
-
-void GeolocationServiceAndroid::stopUpdating()
-{
- // Called when the Geolocation object has no watches or one shots in
- // progress. This may be called repeatedly.
- m_javaBridge.clear();
- // Reset last position and error to make sure that we always try to get a
- // new position from the system service when a request is first made.
- m_lastPosition = 0;
- m_lastError = 0;
- // remove the pending timer
- if (m_timer.isActive())
- m_timer.stop();
-}
-
-void GeolocationServiceAndroid::suspend()
-{
- if (m_javaBridge)
- m_javaBridge->stop();
-}
-
-void GeolocationServiceAndroid::resume()
-{
- if (m_javaBridge)
- m_javaBridge->start();
-}
-
-// Note that there is no guarantee that subsequent calls to this method offer a
-// more accurate or updated position.
-void GeolocationServiceAndroid::newPositionAvailable(PassRefPtr<Geoposition> position)
-{
- ASSERT(position);
- if (!m_lastPosition
- || isPositionMovement(m_lastPosition.get(), position.get())
- || isPositionMoreAccurate(m_lastPosition.get(), position.get())
- || isPositionMoreTimely(m_lastPosition.get(), position.get())) {
- m_lastPosition = position;
- // Remove the last error.
- m_lastError = 0;
- positionChanged();
- }
-}
-
-void GeolocationServiceAndroid::newErrorAvailable(PassRefPtr<PositionError> error)
-{
- ASSERT(error);
- // We leave the last position
- m_lastError = error;
- errorOccurred();
-}
-
-void GeolocationServiceAndroid::timerFired(Timer<GeolocationServiceAndroid>* timer)
-{
- ASSERT(&m_timer == timer);
- ASSERT(m_lastPosition || m_lastError);
- if (m_lastPosition)
- positionChanged();
- else if (m_lastError)
- errorOccurred();
-}
-
-bool GeolocationServiceAndroid::isPositionMovement(Geoposition* position1, Geoposition* position2)
-{
- ASSERT(position1 && position2);
- // For the small distances in which we are likely concerned, it's reasonable
- // to approximate the distance between the two positions as the sum of the
- // differences in latitude and longitude.
- double delta = fabs(position1->coords()->latitude() - position2->coords()->latitude())
- + fabs(position1->coords()->longitude() - position2->coords()->longitude());
- // Approximate conversion from degrees of arc to metres.
- delta *= 60 * 1852;
- // The threshold is when the distance between the two positions exceeds the
- // worse (larger) of the two accuracies.
- int maxAccuracy = max(position1->coords()->accuracy(), position2->coords()->accuracy());
- return delta > maxAccuracy;
-}
-
-bool GeolocationServiceAndroid::isPositionMoreAccurate(Geoposition* position1, Geoposition* position2)
-{
- ASSERT(position1 && position2);
- return position2->coords()->accuracy() < position1->coords()->accuracy();
-}
-
-bool GeolocationServiceAndroid::isPositionMoreTimely(Geoposition* position1, Geoposition* position2)
-{
- ASSERT(position1 && position2);
- DOMTimeStamp currentTime = convertSecondsToDOMTimeStamp(WTF::currentTime());
- DOMTimeStamp maximumAge = convertSecondsToDOMTimeStamp(10 * 60); // 10 minutes
- return currentTime - position1->timestamp() > maximumAge;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/android/GeolocationServiceAndroid.h b/Source/WebCore/platform/android/GeolocationServiceAndroid.h
deleted file mode 100644
index 72532f6..0000000
--- a/Source/WebCore/platform/android/GeolocationServiceAndroid.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2009, 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.
- */
-
-#ifndef GeolocationServiceAndroid_h
-#define GeolocationServiceAndroid_h
-
-#include "GeolocationService.h"
-#include "Timer.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-
-namespace WebCore {
-
-// The GeolocationServiceBridge is the bridge to the Java implementation of
-// the Geolocation service. It is an implementation detail of
-// GeolocationServiceAndroid.
-class GeolocationServiceBridge;
-
-class GeolocationServiceAndroid : public GeolocationService {
-public:
- static GeolocationService* create(GeolocationServiceClient*);
-
- virtual ~GeolocationServiceAndroid() { };
-
- // ANDROID
- // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
- virtual bool startUpdating(PositionOptions*, bool suspend);
- virtual void stopUpdating();
-
- virtual Geoposition* lastPosition() const { return m_lastPosition.get(); }
- virtual PositionError* lastError() const { return m_lastError.get(); }
-
- virtual void suspend();
- virtual void resume();
-
- // Android-specific
- void newPositionAvailable(PassRefPtr<Geoposition>);
- void newErrorAvailable(PassRefPtr<PositionError>);
- void timerFired(Timer<GeolocationServiceAndroid>* timer);
-
-private:
- GeolocationServiceAndroid(GeolocationServiceClient*);
-
- static bool isPositionMovement(Geoposition* position1, Geoposition* position2);
- static bool isPositionMoreAccurate(Geoposition* position1, Geoposition* position2);
- static bool isPositionMoreTimely(Geoposition* position1, Geoposition* position2);
-
- Timer<GeolocationServiceAndroid> m_timer;
- RefPtr<Geoposition> m_lastPosition;
- RefPtr<PositionError> m_lastError;
- OwnPtr<GeolocationServiceBridge> m_javaBridge;
-};
-
-} // namespace WebCore
-
-#endif // GeolocationServiceAndroid_h
diff --git a/Source/WebCore/platform/android/GeolocationServiceBridge.cpp b/Source/WebCore/platform/android/GeolocationServiceBridge.cpp
deleted file mode 100644
index 697b63b..0000000
--- a/Source/WebCore/platform/android/GeolocationServiceBridge.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2009, 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 "GeolocationServiceBridge.h"
-
-#include "Frame.h"
-#include "GeolocationServiceAndroid.h"
-#include "Geoposition.h"
-#include "PositionError.h"
-#include "WebViewCore.h"
-#include <JNIHelp.h>
-
-namespace WebCore {
-
-using JSC::Bindings::getJNIEnv;
-
-static const char* javaGeolocationServiceClassName = "android/webkit/GeolocationService";
-enum javaGeolocationServiceClassMethods {
- GeolocationServiceMethodInit = 0,
- GeolocationServiceMethodStart,
- GeolocationServiceMethodStop,
- GeolocationServiceMethodSetEnableGps,
- GeolocationServiceMethodCount,
-};
-static jmethodID javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodCount];
-
-static const JNINativeMethod javaGeolocationServiceClassNativeMethods[] = {
- { "nativeNewLocationAvailable", "(JLandroid/location/Location;)V",
- (void*) GeolocationServiceBridge::newLocationAvailable },
- { "nativeNewErrorAvailable", "(JLjava/lang/String;)V",
- (void*) GeolocationServiceBridge::newErrorAvailable }
-};
-
-static const char *javaLocationClassName = "android/location/Location";
-enum javaLocationClassMethods {
- LocationMethodGetLatitude = 0,
- LocationMethodGetLongitude,
- LocationMethodHasAltitude,
- LocationMethodGetAltitude,
- LocationMethodHasAccuracy,
- LocationMethodGetAccuracy,
- LocationMethodHasBearing,
- LocationMethodGetBearing,
- LocationMethodHasSpeed,
- LocationMethodGetSpeed,
- LocationMethodGetTime,
- LocationMethodCount,
-};
-static jmethodID javaLocationClassMethodIDs[LocationMethodCount];
-
-GeolocationServiceBridge::GeolocationServiceBridge(ListenerInterface* listener, Frame* frame)
- : m_listener(listener)
- , m_javaGeolocationServiceObject(0)
-{
- ASSERT(m_listener);
- startJavaImplementation(frame);
-}
-
-GeolocationServiceBridge::~GeolocationServiceBridge()
-{
- stop();
- stopJavaImplementation();
-}
-
-bool GeolocationServiceBridge::start()
-{
- if (!m_javaGeolocationServiceObject)
- return false;
- return getJNIEnv()->CallBooleanMethod(m_javaGeolocationServiceObject,
- javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart]);
-}
-
-void GeolocationServiceBridge::stop()
-{
- if (!m_javaGeolocationServiceObject)
- return;
- getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
- javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop]);
-}
-
-void GeolocationServiceBridge::setEnableGps(bool enable)
-{
- if (!m_javaGeolocationServiceObject)
- return;
- getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
- javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps],
- enable);
-}
-
-void GeolocationServiceBridge::newLocationAvailable(JNIEnv* env, jclass, jlong nativeObject, jobject location)
-{
- ASSERT(nativeObject);
- ASSERT(location);
- GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
- object->m_listener->newPositionAvailable(toGeoposition(env, location));
-}
-
-void GeolocationServiceBridge::newErrorAvailable(JNIEnv* env, jclass, jlong nativeObject, jstring message)
-{
- GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
- RefPtr<PositionError> error =
- PositionError::create(PositionError::POSITION_UNAVAILABLE, android::jstringToWtfString(env, message));
- object->m_listener->newErrorAvailable(error.release());
-}
-
-PassRefPtr<Geoposition> GeolocationServiceBridge::toGeoposition(JNIEnv *env, const jobject &location)
-{
- // Altitude is optional and may not be supplied.
- bool hasAltitude =
- env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAltitude]);
- double Altitude =
- hasAltitude ?
- env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetAltitude]) :
- 0.0;
- // Accuracy is required, but is not supplied by the emulator.
- double Accuracy =
- env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAccuracy]) ?
- env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetAccuracy]) :
- 0.0;
- // heading is optional and may not be supplied.
- bool hasHeading =
- env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasBearing]);
- double heading =
- hasHeading ?
- env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetBearing]) :
- 0.0;
- // speed is optional and may not be supplied.
- bool hasSpeed =
- env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasSpeed]);
- double speed =
- hasSpeed ?
- env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetSpeed]) :
- 0.0;
-
- RefPtr<Coordinates> newCoordinates = WebCore::Coordinates::create(
- env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLatitude]),
- env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLongitude]),
- hasAltitude, Altitude,
- Accuracy,
- false, 0.0, // AltitudeAccuracy not provided.
- hasHeading, heading,
- hasSpeed, speed);
-
- return WebCore::Geoposition::create(
- newCoordinates.release(),
- env->CallLongMethod(location, javaLocationClassMethodIDs[LocationMethodGetTime]));
-}
-
-void GeolocationServiceBridge::startJavaImplementation(Frame* frame)
-{
- JNIEnv* env = getJNIEnv();
-
- // Get the Java GeolocationService class.
- jclass javaGeolocationServiceClass = env->FindClass(javaGeolocationServiceClassName);
- ASSERT(javaGeolocationServiceClass);
-
- // Set up the methods we wish to call on the Java GeolocationService class.
- javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit] =
- env->GetMethodID(javaGeolocationServiceClass, "<init>", "(Landroid/content/Context;J)V");
- javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart] =
- env->GetMethodID(javaGeolocationServiceClass, "start", "()Z");
- javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop] =
- env->GetMethodID(javaGeolocationServiceClass, "stop", "()V");
- javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps] =
- env->GetMethodID(javaGeolocationServiceClass, "setEnableGps", "(Z)V");
-
- // Create the Java GeolocationService object.
- jobject context = android::WebViewCore::getWebViewCore(frame->view())->getContext();
- if (!context)
- return;
- jlong nativeObject = reinterpret_cast<jlong>(this);
- jobject object = env->NewObject(javaGeolocationServiceClass,
- javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit],
- context,
- nativeObject);
-
- m_javaGeolocationServiceObject = getJNIEnv()->NewGlobalRef(object);
- ASSERT(m_javaGeolocationServiceObject);
-
- // Register to handle calls to native methods of the Java GeolocationService
- // object. We register once only.
- static int registered = jniRegisterNativeMethods(env,
- javaGeolocationServiceClassName,
- javaGeolocationServiceClassNativeMethods,
- NELEM(javaGeolocationServiceClassNativeMethods));
- ASSERT(registered == JNI_OK);
-
- // Set up the methods we wish to call on the Java Location class.
- jclass javaLocationClass = env->FindClass(javaLocationClassName);
- ASSERT(javaLocationClass);
- javaLocationClassMethodIDs[LocationMethodGetLatitude] =
- env->GetMethodID(javaLocationClass, "getLatitude", "()D");
- javaLocationClassMethodIDs[LocationMethodGetLongitude] =
- env->GetMethodID(javaLocationClass, "getLongitude", "()D");
- javaLocationClassMethodIDs[LocationMethodHasAltitude] =
- env->GetMethodID(javaLocationClass, "hasAltitude", "()Z");
- javaLocationClassMethodIDs[LocationMethodGetAltitude] =
- env->GetMethodID(javaLocationClass, "getAltitude", "()D");
- javaLocationClassMethodIDs[LocationMethodHasAccuracy] =
- env->GetMethodID(javaLocationClass, "hasAccuracy", "()Z");
- javaLocationClassMethodIDs[LocationMethodGetAccuracy] =
- env->GetMethodID(javaLocationClass, "getAccuracy", "()F");
- javaLocationClassMethodIDs[LocationMethodHasBearing] =
- env->GetMethodID(javaLocationClass, "hasBearing", "()Z");
- javaLocationClassMethodIDs[LocationMethodGetBearing] =
- env->GetMethodID(javaLocationClass, "getBearing", "()F");
- javaLocationClassMethodIDs[LocationMethodHasSpeed] =
- env->GetMethodID(javaLocationClass, "hasSpeed", "()Z");
- javaLocationClassMethodIDs[LocationMethodGetSpeed] =
- env->GetMethodID(javaLocationClass, "getSpeed", "()F");
- javaLocationClassMethodIDs[LocationMethodGetTime] =
- env->GetMethodID(javaLocationClass, "getTime", "()J");
-}
-
-void GeolocationServiceBridge::stopJavaImplementation()
-{
- // Called by GeolocationServiceAndroid on WebKit thread.
- if (!m_javaGeolocationServiceObject)
- return;
- getJNIEnv()->DeleteGlobalRef(m_javaGeolocationServiceObject);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/android/PlatformBridge.h b/Source/WebCore/platform/android/PlatformBridge.h
index a4c1048..5af5d2d 100644
--- a/Source/WebCore/platform/android/PlatformBridge.h
+++ b/Source/WebCore/platform/android/PlatformBridge.h
@@ -124,10 +124,6 @@ public:
};
static String* globalLocalizedName(rawResId resId);
- // Whether the WebView is paused.
- // ANDROID
- // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
- static bool isWebViewPaused(const FrameView*);
static String resolveFilePathForContentUri(const String&);
static int screenDepth();
@@ -136,7 +132,7 @@ public:
// Update the viewport meta data.
static void updateViewport(FrameView*);
- static void updateTextfield(FrameView*, Node*, bool changeToPassword, const WTF::String& text);
+ static void updateTextfield(FrameView*, Node*, const WTF::String& text);
static void setScrollPosition(ScrollView*, int x, int y);
diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.cpp b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
index 86380e7..eaf4593 100644
--- a/Source/WebCore/platform/android/RenderThemeAndroid.cpp
+++ b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
@@ -39,6 +39,7 @@
#endif
#include "RenderSkinAndroid.h"
#include "RenderSkinMediaButton.h"
+#include "RenderSlider.h"
#include "RoundedIntRect.h"
#include "SkCanvas.h"
#include "UserAgentStyleSheets.h"
@@ -85,12 +86,6 @@ const float scaleFactor[RenderSkinAndroid::ResolutionCount] = {
2.0f // extra high res
};
-
-static SkCanvas* getCanvasFromInfo(const PaintInfo& info)
-{
- return info.context->platformContext()->getCanvas();
-}
-
static android::WebFrame* getWebFrame(const Node* node)
{
if (!node)
@@ -341,9 +336,7 @@ bool RenderThemeAndroid::paintMediaFullscreenButton(RenderObject* o, const Paint
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- if (!getCanvasFromInfo(paintInfo))
- return true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::FULLSCREEN, translucent);
+ paintInfo.context->platformContext()->drawMediaButton(rect, RenderSkinMediaButton::FULLSCREEN, translucent);
return false;
}
@@ -352,9 +345,7 @@ bool RenderThemeAndroid::paintMediaMuteButton(RenderObject* o, const PaintInfo&
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- if (!getCanvasFromInfo(paintInfo))
- return true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::MUTE, translucent);
+ paintInfo.context->platformContext()->drawMediaButton(rect, RenderSkinMediaButton::MUTE, translucent);
return false;
}
@@ -364,12 +355,10 @@ bool RenderThemeAndroid::paintMediaPlayButton(RenderObject* o, const PaintInfo&
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
if (MediaControlPlayButtonElement* btn = static_cast<MediaControlPlayButtonElement*>(o->node())) {
- if (!getCanvasFromInfo(paintInfo))
- return true;
if (btn->displayType() == MediaPlayButton)
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PLAY, translucent);
+ paintInfo.context->platformContext()->drawMediaButton(rect, RenderSkinMediaButton::PLAY, translucent);
else
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::PAUSE, translucent);
+ paintInfo.context->platformContext()->drawMediaButton(rect, RenderSkinMediaButton::PAUSE, translucent);
return false;
}
return true;
@@ -380,9 +369,7 @@ bool RenderThemeAndroid::paintMediaSeekBackButton(RenderObject* o, const PaintIn
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- if (!getCanvasFromInfo(paintInfo))
- return true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::REWIND, translucent);
+ paintInfo.context->platformContext()->drawMediaButton(rect, RenderSkinMediaButton::REWIND, translucent);
return false;
}
@@ -391,9 +378,7 @@ bool RenderThemeAndroid::paintMediaSeekForwardButton(RenderObject* o, const Pain
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- if (!getCanvasFromInfo(paintInfo))
- return true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect, RenderSkinMediaButton::FORWARD, translucent);
+ paintInfo.context->platformContext()->drawMediaButton(rect, RenderSkinMediaButton::FORWARD, translucent);
return false;
}
@@ -402,11 +387,9 @@ bool RenderThemeAndroid::paintMediaControlsBackground(RenderObject* o, const Pai
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- if (!getCanvasFromInfo(paintInfo))
- return true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
+ paintInfo.context->platformContext()->drawMediaButton(rect,
RenderSkinMediaButton::BACKGROUND_SLIDER,
- translucent, 0, false);
+ translucent, false);
return false;
}
@@ -415,10 +398,11 @@ bool RenderThemeAndroid::paintMediaSliderTrack(RenderObject* o, const PaintInfo&
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- if (!getCanvasFromInfo(paintInfo))
- return true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
- RenderSkinMediaButton::SLIDER_TRACK, translucent, o);
+ IntRect thumb;
+ if (o && o->isSlider())
+ thumb = toRenderSlider(o)->thumbRect();
+ paintInfo.context->platformContext()->drawMediaButton(rect,
+ RenderSkinMediaButton::SLIDER_TRACK, translucent, true, thumb);
return false;
}
@@ -427,11 +411,9 @@ bool RenderThemeAndroid::paintMediaSliderThumb(RenderObject* o, const PaintInfo&
bool translucent = false;
if (o && toParentMediaElement(o) && toParentMediaElement(o)->hasTagName(HTMLNames::videoTag))
translucent = true;
- if (!getCanvasFromInfo(paintInfo))
- return true;
- RenderSkinMediaButton::Draw(getCanvasFromInfo(paintInfo), rect,
+ paintInfo.context->platformContext()->drawMediaButton(rect,
RenderSkinMediaButton::SLIDER_THUMB,
- translucent, 0, false);
+ translucent, false);
return false;
}
@@ -647,25 +629,19 @@ bool RenderThemeAndroid::paintMenuListButton(RenderObject* obj, const PaintInfo&
bool RenderThemeAndroid::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
- SkCanvas* canvas = getCanvasFromInfo(i);
- if (!canvas)
- return true;
static const bool translucent = true;
- RenderSkinMediaButton::Draw(canvas, r,
+ i.context->platformContext()->drawMediaButton(r,
RenderSkinMediaButton::SLIDER_TRACK,
- translucent, o, false);
+ translucent, false);
return false;
}
bool RenderThemeAndroid::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
- SkCanvas* canvas = getCanvasFromInfo(i);
- if (!canvas)
- return true;
static const bool translucent = true;
- RenderSkinMediaButton::Draw(canvas, r,
+ i.context->platformContext()->drawMediaButton(r,
RenderSkinMediaButton::SLIDER_THUMB,
- translucent, 0, false);
+ translucent, false);
return false;
}
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp
index a7e4b90..4e00382 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp
@@ -689,6 +689,14 @@ void MediaPlayer::exitFullscreen()
}
#endif
+#if PLATFORM(ANDROID)
+void MediaPlayer::enterFullscreenMode()
+{
+ // Tell the player to enter full screen mode.
+ m_private->enterFullscreenMode();
+}
+#endif
+
#if USE(ACCELERATED_COMPOSITING)
void MediaPlayer::acceleratedRenderingStateChanged()
{
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h
index 41cb6d2..884f915 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.h
+++ b/Source/WebCore/platform/graphics/MediaPlayer.h
@@ -190,6 +190,7 @@ public:
enum MediaElementType { Video, Audio };
void setMediaElementType(MediaElementType type) { m_mediaElementType = type; }
MediaElementType mediaElementType() { return m_mediaElementType; }
+ void enterFullscreenMode();
#endif
void setFrameView(FrameView* frameView) { m_frameView = frameView; }
diff --git a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
index b4490bc..fa92e06 100644
--- a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -113,7 +113,9 @@ public:
virtual void enterFullscreen() { }
virtual void exitFullscreen() { }
#endif
-
+#if PLATFORM(ANDROID)
+ virtual void enterFullscreenMode() { }
+#endif
#if USE(ACCELERATED_COMPOSITING)
// whether accelerated rendering is supported by the media engine for the current media.
virtual bool supportsAcceleratedRendering() const { return false; }
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 55c4eec..256a678 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -353,10 +353,8 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect,
if (ImagesManager::instance()->prepareTextures(this))
returnFlags |= DrawGlInfo::kStatusDraw;
- if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) {
+ if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING)
ALOGW("WARNING, scale seems corrupted after update: %e", scale);
- scale = 1.0f; // WORKAROUND for corrupted scale: use 1.0
- }
double currentTime = setupDrawing(invScreenRect, visibleContentRect, screenRect,
titleBarHeight, screenClip, scale);
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 779dba5..25441f4 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -41,6 +41,7 @@
#include "Length.h"
#include "MediaLayer.h"
#include "PictureLayerContent.h"
+#include "PicturePileLayerContent.h"
#include "PlatformBridge.h"
#include "PlatformGraphicsContextSkia.h"
#include "RenderLayerBacking.h"
@@ -828,22 +829,9 @@ bool GraphicsLayerAndroid::repaint()
return false;
}
-SkPicture* GraphicsLayerAndroid::paintPicture(const IntRect& rect)
+void GraphicsLayerAndroid::paintContents(GraphicsContext* gc, IntRect& dirty)
{
- SkPicture* picture = new SkPicture();
- SkCanvas* canvas = picture->beginRecording(rect.width(), rect.height(), 0);
- if (!canvas) {
- picture->endRecording();
- SkSafeUnref(picture);
- return 0;
- }
-
- PlatformGraphicsContextSkia platformContext(canvas);
- GraphicsContext graphicsContext(&platformContext);
-
- paintGraphicsLayerContents(graphicsContext, rect);
-
- return picture;
+ paintGraphicsLayerContents(*gc, dirty);
}
bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
@@ -853,19 +841,22 @@ bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
if (!layer)
return false;
- SkPicture* picture = paintPicture(rect);
- if (!picture)
- return false;
- picture->endRecording();
+ TRACE_METHOD();
+
+ // TODO: we might be able to reuse an existing picture instead of recreating it.
+ // we can't do that because of transparency -- for now, we just create
+ // a new picture every time.
+ WebCore::PicturePile picture;
+ picture.setSize(IntSize(m_size.width(), m_size.height()));
+
+ // TODO: add content checks (text, opacity, etc.)
+ picture.updatePicturesIfNeeded(this);
+
+ // store the newly painted content in the layer if it's not empty
+ PicturePileLayerContent* content = new PicturePileLayerContent(picture);
+ layer->setContent(content->isEmpty() ? 0 : content);
+ SkSafeUnref(content);
- PictureLayerContent* layerContent = new PictureLayerContent(picture);
- if (checkOptimisations)
- layerContent->checkForOptimisations();
- else
- layerContent->setCheckForOptimisations(false);
- layer->setContent(layerContent);
- SkSafeUnref(layerContent);
- SkSafeUnref(picture);
return true;
}
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 460e00f..b40459d 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -24,6 +24,7 @@
#include "GraphicsLayer.h"
#include "GraphicsLayerClient.h"
#include "LayerContent.h"
+#include "PicturePile.h"
#include "RefPtr.h"
#include "ScrollableLayerAndroid.h"
#include "SkBitmapRef.h"
@@ -40,12 +41,18 @@ class LayerAndroid;
class FixedBackgroundImageLayerAndroid;
class ScrollableLayerAndroid;
-class GraphicsLayerAndroid : public GraphicsLayer {
+class GraphicsLayerAndroid : public GraphicsLayer, PicturePainter {
public:
GraphicsLayerAndroid(GraphicsLayerClient*);
virtual ~GraphicsLayerAndroid();
+ // PicturePainter
+
+ virtual void paintContents(GraphicsContext* gc, IntRect& dirty);
+
+ /////
+
virtual void setName(const String&);
// for hosting this GraphicsLayer in a native layer hierarchy
@@ -147,7 +154,6 @@ private:
bool repaint();
void needsNotifyClient();
- SkPicture* paintPicture(const IntRect& rect);
bool paintContext(LayerAndroid* layer,
const IntRect& rect,
bool checkOptimisations = true);
diff --git a/Source/WebCore/platform/graphics/android/ImageAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
index 08f72e0..4958622 100644
--- a/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageAndroid.cpp
@@ -34,7 +34,6 @@
#include "PlatformString.h"
#include "SharedBuffer.h"
-#include "android_graphics.h"
#include "SkBitmapRef.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
diff --git a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
index e56f424..f36200d 100644
--- a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
@@ -33,6 +33,7 @@
#include "NotImplemented.h"
#include "PlatformBridge.h"
#include "PlatformGraphicsContext.h"
+#include "PlatformGraphicsContextSkia.h"
#include "SkBitmapRef.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
@@ -41,12 +42,21 @@
#include "SkImageEncoder.h"
#include "SkStream.h"
#include "SkUnPreMultiply.h"
-#include "android_graphics.h"
using namespace std;
namespace WebCore {
+SkCanvas* imageBufferCanvas(const ImageBuffer* buffer)
+{
+ // We know that our PlatformGraphicsContext is a PlatformGraphicsContextSkia
+ // because that is what we create in GraphicsContext::createOffscreenContext
+ if (!buffer || !buffer->context())
+ return 0;
+ PlatformGraphicsContext* pc = buffer->context()->platformContext();
+ return static_cast<PlatformGraphicsContextSkia*>(pc)->canvas();
+}
+
ImageBufferData::ImageBufferData(const IntSize&)
{
}
@@ -82,7 +92,7 @@ PassRefPtr<Image> ImageBuffer::copyImage() const
{
ASSERT(context());
- SkCanvas* canvas = context()->platformContext()->getCanvas();
+ SkCanvas* canvas = imageBufferCanvas(this);
if (!canvas)
return 0;
@@ -123,7 +133,7 @@ PassRefPtr<ByteArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect)
return 0;
}
- const SkBitmap& src = android_gc2canvas(gc)->getDevice()->accessBitmap(false);
+ const SkBitmap& src = imageBufferCanvas(this)->getDevice()->accessBitmap(false);
SkAutoLockPixels alp(src);
if (!src.getPixels()) {
return 0;
@@ -185,7 +195,7 @@ void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sou
return;
}
- const SkBitmap& dst = android_gc2canvas(gc)->getDevice()->accessBitmap(true);
+ const SkBitmap& dst = imageBufferCanvas(this)->getDevice()->accessBitmap(true);
SkAutoLockPixels alp(dst);
if (!dst.getPixels()) {
return;
@@ -240,7 +250,7 @@ String ImageBuffer::toDataURL(const String&, const double*) const
{
// Encode the image into a vector.
SkDynamicMemoryWStream pngStream;
- const SkBitmap& dst = android_gc2canvas(context())->getDevice()->accessBitmap(true);
+ const SkBitmap& dst = imageBufferCanvas(this)->getDevice()->accessBitmap(true);
SkImageEncoder::EncodeStream(&pngStream, dst, SkImageEncoder::kPNG_Type, 100);
// Convert it into base64.
diff --git a/Source/WebCore/platform/graphics/android/ImageBufferDataAndroid.h b/Source/WebCore/platform/graphics/android/ImageBufferDataAndroid.h
index 80cf79f..eeade6e 100644
--- a/Source/WebCore/platform/graphics/android/ImageBufferDataAndroid.h
+++ b/Source/WebCore/platform/graphics/android/ImageBufferDataAndroid.h
@@ -26,9 +26,14 @@
#ifndef ImageBufferDataAndroid_h
#define ImageBufferDataAndroid_h
+class SkCanvas;
+
namespace WebCore {
class IntSize;
+class ImageBuffer;
+
+SkCanvas* imageBufferCanvas(const ImageBuffer* buffer);
class ImageBufferData {
public:
diff --git a/Source/WebCore/platform/graphics/android/PathAndroid.cpp b/Source/WebCore/platform/graphics/android/PathAndroid.cpp
index 554e187..e70f983 100644
--- a/Source/WebCore/platform/graphics/android/PathAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/PathAndroid.cpp
@@ -37,7 +37,6 @@
#include "SkRegion.h"
#include "StrokeStyleApplier.h"
#include "TransformationMatrix.h"
-#include "android_graphics.h"
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/android/PatternAndroid.cpp b/Source/WebCore/platform/graphics/android/PatternAndroid.cpp
index 568036c..ed3265b 100644
--- a/Source/WebCore/platform/graphics/android/PatternAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/PatternAndroid.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "Pattern.h"
-#include "android_graphics.h"
#include "GraphicsContext.h"
#include "SkBitmapRef.h"
#include "SkCanvas.h"
@@ -51,6 +50,8 @@ SkShader* Pattern::platformPattern(const AffineTransform&)
if (m_pattern)
return m_pattern;
+ if (!tileImage())
+ return 0;
SkBitmapRef* ref = tileImage()->nativeImageForCurrentFrame();
if (!ref)
return 0;
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp
index 3b93d51..23b22e6 100644
--- a/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp
@@ -46,7 +46,6 @@
#include "SkString.h"
#include "SkiaUtils.h"
#include "TransformationMatrix.h"
-#include "android_graphics.h"
using namespace std;
@@ -110,7 +109,7 @@ GraphicsContext* GraphicsContext::createOffscreenContext(int width, int height)
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
bitmap.allocPixels();
bitmap.eraseColor(0);
- pgc->getCanvas()->setBitmapDevice(bitmap);
+ pgc->canvas()->setBitmapDevice(bitmap);
GraphicsContext* ctx = new GraphicsContext(pgc);
return ctx;
@@ -511,6 +510,8 @@ void GraphicsContext::translate(float x, float y)
{
if (paintingDisabled())
return;
+ if (!x && !y)
+ return;
platformContext()->translate(x, y);
}
@@ -660,10 +661,3 @@ void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run,
}
} // namespace WebCore
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkCanvas* android_gc2canvas(WebCore::GraphicsContext* gc)
-{
- return gc->platformContext()->getCanvas();
-}
diff --git a/Source/WebCore/platform/graphics/android/context/android_graphics.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.cpp
index 7faa781..ab6e676 100644
--- a/Source/WebCore/platform/graphics/android/context/android_graphics.h
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2007, The Android Open Source Project
+ * Copyright 2012, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,21 +22,34 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define LOG_TAG "GraphicsOperation"
-#ifndef android_graphics_DEFINED
-#define android_graphics_DEFINED
+#include "config.h"
+#include "GraphicsOperation.h"
+
+#include "AndroidLog.h"
+#include "LinearAllocator.h"
namespace WebCore {
- class GraphicsContext;
-}
-class SkCanvas;
+namespace GraphicsOperation {
-// TODO: Move this somewhere else. The implementation for this is actually in
-// GraphicsContextAndroid.cpp, but this is used by a handful of other files
-SkCanvas* android_gc2canvas(WebCore::GraphicsContext* gc);
+void* Operation::operator new(size_t size, LinearAllocator* allocator)
+{
+ return allocator->alloc(size);
+}
-// used to inflate node cache entry
-#define CURSOR_RING_HIT_TEST_RADIUS 5
+void* Operation::operator new(size_t size)
+{
+ ALOGE("Cannot allocate a new Operation directly!");
+ CRASH();
+ return (void*) 0xBADBEEF;
+}
+void Operation::operator delete(void*)
+{
+ ALOGE("Cannot call delete on an Operation!");
+ CRASH();
+}
-#endif
+} // namespace GraphicsOperation
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
index 927ff0a..c9c382a 100644
--- a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
@@ -26,8 +26,6 @@
#ifndef GraphicsOperation_h
#define GraphicsOperation_h
-#if USE(ACCELERATED_COMPOSITING)
-
#include "Color.h"
#include "FloatRect.h"
#include "GlyphBuffer.h"
@@ -44,37 +42,54 @@
#define TYPE_CASE(type) case type: return #type;
+#define DEBUG_GRAPHICS_OPERATIONS false
+
+#if DEBUG_GRAPHICS_OPERATIONS
+#define TYPE(x) virtual OperationType type() { return x; }
+#else
+#define TYPE(x)
+#endif
+
namespace WebCore {
+class CanvasState;
+class LinearAllocator;
+
namespace GraphicsOperation {
-class Operation : public SkRefCnt {
+class Operation {
public:
+ Operation()
+ : m_state(0)
+ , m_canvasState(0)
+ {}
+
+ void* operator new(size_t size, LinearAllocator* allocator);
+
+ // Purposely not implemented - use a LinearAllocator please
+ void* operator new(size_t size);
+ void operator delete(void* ptr);
+
+ // This m_state is applied by ourselves
+ PlatformGraphicsContext::State* m_state;
+ // This is the canvas state that this operation needs
+ // Only used for drawing operations, state operations will be undefined
+ CanvasState* m_canvasState;
+
+ bool apply(PlatformGraphicsContext* context) {
+ if (m_state)
+ context->setRawState(m_state);
+ return applyImpl(context);
+ }
+ virtual bool applyImpl(PlatformGraphicsContext* context) = 0;
+ virtual ~Operation() {}
+
+ virtual const IntRect* opaqueRect() { return 0; }
+ virtual bool isOpaque() { return false; }
+ virtual void setOpaqueRect(const IntRect& bounds) {}
+
+#if DEBUG_GRAPHICS_OPERATIONS
typedef enum { UndefinedOperation
- // State management
- , BeginTransparencyLayerOperation
- , EndTransparencyLayerOperation
- , SaveOperation
- , RestoreOperation
- // State setters
- , SetAlphaOperation
- , SetCompositeOpOperation
- , SetFillColorOperation
- , SetFillShaderOperation
- , SetLineCapOperation
- , SetLineDashOperation
- , SetLineJoinOperation
- , SetMiterLimitOperation
- , SetShadowOperation
- , SetShouldAntialiasOperation
- , SetStrokeColorOperation
- , SetStrokeShaderOperation
- , SetStrokeStyleOperation
- , SetStrokeThicknessOperation
- // Paint setup
- , SetupPaintFillOperation
- , SetupPaintShadowOperation
- , SetupPaintStrokeOperation
// Matrix operations
, ConcatCTMOperation
, ScaleOperation
@@ -89,7 +104,9 @@ public:
// Drawing
, DrawBitmapPatternOperation
, DrawBitmapRectOperation
+ , DrawConvexPolygonQuadOperation
, DrawEllipseOperation
+ , DrawFocusRingOperation
, DrawLineOperation
, DrawLineForTextOperation
, DrawLineForTextCheckingOperation
@@ -100,43 +117,15 @@ public:
, StrokeArcOperation
, StrokePathOperation
, StrokeRectOperation
+ , DrawMediaButtonOperation
// Text
- , DrawComplexTextOperation
- , DrawTextOperation
+ , DrawPosTextOperation
} OperationType;
- virtual void apply(PlatformGraphicsContext* context) = 0;
- virtual ~Operation() {}
- virtual OperationType type() { return UndefinedOperation; }
- virtual String parameters() { return ""; }
- String name()
+ const char* name()
{
switch (type()) {
TYPE_CASE(UndefinedOperation)
- // State management
- TYPE_CASE(BeginTransparencyLayerOperation)
- TYPE_CASE(EndTransparencyLayerOperation)
- TYPE_CASE(SaveOperation)
- TYPE_CASE(RestoreOperation)
- // State setters
- TYPE_CASE(SetAlphaOperation)
- TYPE_CASE(SetCompositeOpOperation)
- TYPE_CASE(SetFillColorOperation)
- TYPE_CASE(SetFillShaderOperation)
- TYPE_CASE(SetLineCapOperation)
- TYPE_CASE(SetLineDashOperation)
- TYPE_CASE(SetLineJoinOperation)
- TYPE_CASE(SetMiterLimitOperation)
- TYPE_CASE(SetShadowOperation)
- TYPE_CASE(SetShouldAntialiasOperation)
- TYPE_CASE(SetStrokeColorOperation)
- TYPE_CASE(SetStrokeShaderOperation)
- TYPE_CASE(SetStrokeStyleOperation)
- TYPE_CASE(SetStrokeThicknessOperation)
- // Paint setup
- TYPE_CASE(SetupPaintFillOperation)
- TYPE_CASE(SetupPaintShadowOperation)
- TYPE_CASE(SetupPaintStrokeOperation)
// Matrix operations
TYPE_CASE(ConcatCTMOperation)
TYPE_CASE(ScaleOperation)
@@ -151,7 +140,9 @@ public:
// Drawing
TYPE_CASE(DrawBitmapPatternOperation)
TYPE_CASE(DrawBitmapRectOperation)
+ TYPE_CASE(DrawConvexPolygonQuadOperation)
TYPE_CASE(DrawEllipseOperation)
+ TYPE_CASE(DrawFocusRingOperation)
TYPE_CASE(DrawLineOperation)
TYPE_CASE(DrawLineForTextOperation)
TYPE_CASE(DrawLineForTextCheckingOperation)
@@ -162,258 +153,23 @@ public:
TYPE_CASE(StrokeArcOperation)
TYPE_CASE(StrokePathOperation)
TYPE_CASE(StrokeRectOperation)
+ TYPE_CASE(DrawMediaButtonOperation)
// Text
- TYPE_CASE(DrawComplexTextOperation)
- TYPE_CASE(DrawTextOperation)
+ TYPE_CASE(DrawPosTextOperation)
}
return "Undefined";
}
+#endif
+ TYPE(UndefinedOperation)
};
-//**************************************
-// State management
-//**************************************
-
-class BeginTransparencyLayer : public Operation {
-public:
- BeginTransparencyLayer(const float opacity) : m_opacity(opacity) {}
- virtual void apply(PlatformGraphicsContext* context) { context->beginTransparencyLayer(m_opacity); }
- virtual OperationType type() { return BeginTransparencyLayerOperation; }
-private:
- float m_opacity;
-};
-class EndTransparencyLayer : public Operation {
-public:
- EndTransparencyLayer() {}
- virtual void apply(PlatformGraphicsContext* context) { context->endTransparencyLayer(); }
- virtual OperationType type() { return EndTransparencyLayerOperation; }
-};
-class Save : public Operation {
-public:
- virtual void apply(PlatformGraphicsContext* context) { context->save(); }
- virtual OperationType type() { return SaveOperation; }
-};
-class Restore : public Operation {
-public:
- virtual void apply(PlatformGraphicsContext* context) { context->restore(); }
- virtual OperationType type() { return RestoreOperation; }
-};
-
-//**************************************
-// State setters
-//**************************************
-
-class SetAlpha : public Operation {
-public:
- SetAlpha(const float alpha) : m_alpha(alpha) {}
- virtual void apply(PlatformGraphicsContext* context) { context->setAlpha(m_alpha); }
- virtual OperationType type() { return SetAlphaOperation; }
-private:
- float m_alpha;
-};
-
-class SetCompositeOperation : public Operation {
-public:
- SetCompositeOperation(CompositeOperator op) : m_operator(op) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setCompositeOperation(m_operator);
- }
- virtual OperationType type() { return SetCompositeOpOperation; }
-private:
- CompositeOperator m_operator;
-};
-
-class SetFillColor : public Operation {
-public:
- SetFillColor(Color color) : m_color(color) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setFillColor(m_color);
- }
- virtual OperationType type() { return SetFillColorOperation; }
- virtual String parameters() {
- return String::format("r: %d g: %d b: %d a: %d",
- m_color.red(),
- m_color.green(),
- m_color.blue(),
- m_color.alpha());
- }
-private:
- Color m_color;
-};
-
-class SetFillShader : public Operation {
-public:
- SetFillShader(SkShader* shader) : m_shader(shader) {
- SkSafeRef(m_shader);
- }
- ~SetFillShader() { SkSafeUnref(m_shader); }
- virtual void apply(PlatformGraphicsContext* context) {
- context->setFillShader(m_shader);
- }
- virtual OperationType type() { return SetFillShaderOperation; }
-private:
- SkShader* m_shader;
-};
-
-class SetLineCap : public Operation {
-public:
- SetLineCap(LineCap cap) : m_cap(cap) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setLineCap(m_cap);
- }
- virtual OperationType type() { return SetLineCapOperation; }
-private:
- LineCap m_cap;
-};
-
-class SetLineDash : public Operation {
-public:
- SetLineDash(const DashArray& dashes, float dashOffset)
- : m_dashes(dashes), m_dashOffset(dashOffset) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setLineDash(m_dashes, m_dashOffset);
- }
- virtual OperationType type() { return SetLineDashOperation; }
-private:
- DashArray m_dashes;
- float m_dashOffset;
-};
-
-class SetLineJoin : public Operation {
-public:
- SetLineJoin(LineJoin join) : m_join(join) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setLineJoin(m_join);
- }
- virtual OperationType type() { return SetLineJoinOperation; }
-private:
- LineJoin m_join;
-};
-
-class SetMiterLimit : public Operation {
-public:
- SetMiterLimit(float limit) : m_limit(limit) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setMiterLimit(m_limit);
- }
- virtual OperationType type() { return SetMiterLimitOperation; }
-private:
- float m_limit;
-};
-
-class SetShadow : public Operation {
-public:
- SetShadow(int radius, int dx, int dy, SkColor c)
- : m_radius(radius), m_dx(dx), m_dy(dy), m_color(c) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setShadow(m_radius, m_dx, m_dy, m_color);
- }
- virtual OperationType type() { return SetShadowOperation; }
-private:
- int m_radius;
- int m_dx;
- int m_dy;
- SkColor m_color;
-};
-
-class SetShouldAntialias : public Operation {
-public:
- SetShouldAntialias(bool useAA) : m_useAA(useAA) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setShouldAntialias(m_useAA);
- }
- virtual OperationType type() { return SetShouldAntialiasOperation; }
-private:
- bool m_useAA;
-};
-
-class SetStrokeColor : public Operation {
-public:
- SetStrokeColor(const Color& c) : m_color(c) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setStrokeColor(m_color);
- }
- virtual OperationType type() { return SetStrokeColorOperation; }
-private:
- Color m_color;
-};
-
-class SetStrokeShader : public Operation {
-public:
- SetStrokeShader(SkShader* strokeShader) : m_shader(strokeShader) {
- SkSafeRef(m_shader);
- }
- ~SetStrokeShader() { SkSafeUnref(m_shader); }
- virtual void apply(PlatformGraphicsContext* context) {
- context->setStrokeShader(m_shader);
- }
- virtual OperationType type() { return SetStrokeShaderOperation; }
-private:
- SkShader* m_shader;
-};
-
-class SetStrokeStyle : public Operation {
+class PossiblyOpaqueOperation : public Operation {
public:
- SetStrokeStyle(StrokeStyle style) : m_style(style) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setStrokeStyle(m_style);
- }
- virtual OperationType type() { return SetStrokeStyleOperation; }
-private:
- StrokeStyle m_style;
-};
-
-class SetStrokeThickness : public Operation {
-public:
- SetStrokeThickness(float thickness) : m_thickness(thickness) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setStrokeThickness(m_thickness);
- }
- virtual OperationType type() { return SetStrokeThicknessOperation; }
-private:
- float m_thickness;
-};
-
-//**************************************
-// Paint setup
-//**************************************
-
-class SetupPaintFill : public Operation {
-public:
- SetupPaintFill(SkPaint* paint) : m_paint(*paint) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setupPaintFill(&m_paint);
- }
- virtual OperationType type() { return SetupPaintFillOperation; }
-private:
- SkPaint m_paint;
-};
-
-class SetupPaintShadow : public Operation {
-public:
- SetupPaintShadow(SkPaint* paint, SkPoint* offset)
- : m_paint(*paint), m_offset(*offset) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setupPaintShadow(&m_paint, &m_offset);
- }
- virtual OperationType type() { return SetupPaintShadowOperation; }
-private:
- SkPaint m_paint;
- SkPoint m_offset;
-};
+ virtual const IntRect* opaqueRect() { return &m_absoluteOpaqueRect; }
+ virtual void setOpaqueRect(const IntRect& bounds) { m_absoluteOpaqueRect = bounds; }
-class SetupPaintStroke : public Operation {
-public:
- SetupPaintStroke(SkPaint* paint, SkRect* rect, bool isHLine)
- : m_paint(*paint), m_rect(*rect), m_isHLine(isHLine) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->setupPaintStroke(&m_paint, &m_rect, m_isHLine);
- }
- virtual OperationType type() { return SetupPaintStrokeOperation; }
private:
- SkPaint m_paint;
- SkRect m_rect;
- bool m_isHLine;
+ IntRect m_absoluteOpaqueRect;
};
//**************************************
@@ -423,10 +179,11 @@ private:
class ConcatCTM : public Operation {
public:
ConcatCTM(const AffineTransform& affine) : m_matrix(affine) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->concatCTM(m_matrix);
+ return true;
}
- virtual OperationType type() { return ConcatCTMOperation; }
+ TYPE(ConcatCTMOperation)
private:
AffineTransform m_matrix;
};
@@ -434,10 +191,11 @@ private:
class Rotate : public Operation {
public:
Rotate(float angleInRadians) : m_angle(angleInRadians) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->rotate(m_angle);
+ return true;
}
- virtual OperationType type() { return RotateOperation; }
+ TYPE(RotateOperation)
private:
float m_angle;
};
@@ -445,10 +203,11 @@ private:
class Scale : public Operation {
public:
Scale(const FloatSize& size) : m_scale(size) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->scale(m_scale);
+ return true;
}
- virtual OperationType type() { return ScaleOperation; }
+ TYPE(ScaleOperation)
private:
FloatSize m_scale;
};
@@ -456,10 +215,11 @@ private:
class Translate : public Operation {
public:
Translate(float x, float y) : m_x(x), m_y(y) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->translate(m_x, m_y);
+ return true;
}
- virtual OperationType type() { return TranslateOperation; }
+ TYPE(TranslateOperation)
private:
float m_x;
float m_y;
@@ -473,10 +233,11 @@ class InnerRoundedRectClip : public Operation {
public:
InnerRoundedRectClip(const IntRect& rect, int thickness)
: m_rect(rect), m_thickness(thickness) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->addInnerRoundedRectClip(m_rect, m_thickness);
+ return true;
}
- virtual OperationType type() { return InnerRoundedRectClipOperation; }
+ TYPE(InnerRoundedRectClipOperation)
private:
IntRect m_rect;
int m_thickness;
@@ -485,10 +246,10 @@ private:
class Clip : public Operation {
public:
Clip(const FloatRect& rect) : m_rect(rect) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->clip(m_rect);
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
+ return context->clip(m_rect);
}
- virtual OperationType type() { return ClipOperation; }
+ TYPE(ClipOperation)
private:
const FloatRect m_rect;
};
@@ -498,17 +259,16 @@ public:
ClipPath(const Path& path, bool clipout = false)
: m_path(path), m_clipOut(clipout), m_hasWindRule(false) {}
void setWindRule(WindRule rule) { m_windRule = rule; m_hasWindRule = true; }
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
if (m_hasWindRule) {
- context->clipPath(m_path, m_windRule);
- return;
+ return context->clipPath(m_path, m_windRule);
}
if (m_clipOut)
- context->clipOut(m_path);
+ return context->clipOut(m_path);
else
- context->clip(m_path);
+ return context->clip(m_path);
}
- virtual OperationType type() { return ClipPathOperation; }
+ TYPE(ClipPathOperation)
private:
const Path m_path;
bool m_clipOut;
@@ -519,10 +279,10 @@ private:
class ClipOut : public Operation {
public:
ClipOut(const IntRect& rect) : m_rect(rect) {}
- virtual void apply(PlatformGraphicsContext* context) {
- context->clipOut(m_rect);
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
+ return context->clipOut(m_rect);
}
- virtual OperationType type() { return ClipOutOperation; }
+ TYPE(ClipOutOperation)
private:
const IntRect m_rect;
};
@@ -530,10 +290,11 @@ private:
class ClearRect : public Operation {
public:
ClearRect(const FloatRect& rect) : m_rect(rect) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->clearRect(m_rect);
+ return true;
}
- virtual OperationType type() { return ClearRectOperation; }
+ TYPE(ClearRectOperation)
private:
FloatRect m_rect;
};
@@ -542,63 +303,101 @@ private:
// Drawing
//**************************************
-class DrawBitmapPattern : public Operation {
+class DrawBitmapPattern : public PossiblyOpaqueOperation {
public:
DrawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
CompositeOperator op, const FloatRect& destRect)
: m_bitmap(bitmap), m_matrix(matrix), m_operator(op), m_destRect(destRect) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->drawBitmapPattern(m_bitmap, m_matrix, m_operator, m_destRect);
+ return true;
}
- virtual OperationType type() { return DrawBitmapPatternOperation; }
+ virtual bool isOpaque() { return m_bitmap.isOpaque(); }
+ TYPE(DrawBitmapPatternOperation)
+
private:
- // TODO: use refcounted bitmap
- const SkBitmap m_bitmap;
+ SkBitmap m_bitmap;
SkMatrix m_matrix;
CompositeOperator m_operator;
FloatRect m_destRect;
};
-class DrawBitmapRect : public Operation {
+class DrawBitmapRect : public PossiblyOpaqueOperation {
public:
DrawBitmapRect(const SkBitmap& bitmap, const SkIRect& srcR,
const SkRect& dstR, CompositeOperator op)
: m_bitmap(bitmap), m_srcR(srcR), m_dstR(dstR), m_operator(op) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->drawBitmapRect(m_bitmap, &m_srcR, m_dstR, m_operator);
+ return true;
}
- virtual OperationType type() { return DrawBitmapRectOperation; }
- virtual String parameters() {
- return String::format("%.2f, %.2f - %.2f x %.2f",
- m_dstR.fLeft, m_dstR.fTop,
- m_dstR.width(), m_dstR.height());
- }
+ virtual bool isOpaque() { return m_bitmap.isOpaque(); }
+ TYPE(DrawBitmapRectOperation)
private:
- const SkBitmap& m_bitmap;
+ SkBitmap m_bitmap;
SkIRect m_srcR;
SkRect m_dstR;
CompositeOperator m_operator;
};
+class DrawConvexPolygonQuad : public Operation {
+public:
+ DrawConvexPolygonQuad(const FloatPoint* points, bool shouldAntiAlias)
+ : m_shouldAntiAlias(shouldAntiAlias)
+ {
+ memcpy(m_points, points, 4 * sizeof(FloatPoint));
+ }
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
+ context->drawConvexPolygon(4, m_points, m_shouldAntiAlias);
+ return true;
+ }
+ TYPE(DrawConvexPolygonQuadOperation)
+private:
+ bool m_shouldAntiAlias;
+ FloatPoint m_points[4];
+};
+
class DrawEllipse : public Operation {
public:
DrawEllipse(const IntRect& rect) : m_rect(rect) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->drawEllipse(m_rect);
+ return true;
}
- virtual OperationType type() { return DrawEllipseOperation; }
+ TYPE(DrawEllipseOperation)
private:
IntRect m_rect;
};
+class DrawFocusRing : public Operation {
+public:
+ DrawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
+ : m_rects(rects)
+ , m_width(width)
+ , m_offset(offset)
+ , m_color(color)
+ {}
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
+ context->drawFocusRing(m_rects, m_width, m_offset, m_color);
+ return true;
+ }
+ TYPE(DrawFocusRingOperation)
+private:
+ Vector<IntRect> m_rects;
+ int m_width;
+ int m_offset;
+ Color m_color;
+};
+
class DrawLine : public Operation {
public:
DrawLine(const IntPoint& point1, const IntPoint& point2)
: m_point1(point1), m_point2(point2) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->drawLine(m_point1, m_point2);
+ return true;
}
- virtual OperationType type() { return DrawLineOperation; }
+ TYPE(DrawLineOperation)
private:
IntPoint m_point1;
IntPoint m_point2;
@@ -608,10 +407,11 @@ class DrawLineForText : public Operation {
public:
DrawLineForText(const FloatPoint& pt, float width)
: m_point(pt), m_width(width) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->drawLineForText(m_point, m_width);
+ return true;
}
- virtual OperationType type() { return DrawLineForTextOperation; }
+ TYPE(DrawLineForTextOperation)
private:
FloatPoint m_point;
float m_width;
@@ -622,10 +422,11 @@ public:
DrawLineForTextChecking(const FloatPoint& pt, float width,
GraphicsContext::TextCheckingLineStyle lineStyle)
: m_point(pt), m_width(width), m_lineStyle(lineStyle) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->drawLineForTextChecking(m_point, m_width, m_lineStyle);
+ return true;
}
- virtual OperationType type() { return DrawLineForTextCheckingOperation; }
+ TYPE(DrawLineForTextCheckingOperation)
private:
FloatPoint m_point;
float m_width;
@@ -635,10 +436,11 @@ private:
class DrawRect : public Operation {
public:
DrawRect(const IntRect& rect) : m_rect(rect) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->drawRect(m_rect);
+ return true;
}
- virtual OperationType type() { return DrawRectOperation; }
+ TYPE(DrawRectOperation)
private:
IntRect m_rect;
};
@@ -647,26 +449,30 @@ class FillPath : public Operation {
public:
FillPath(const Path& pathToFill, WindRule fillRule)
: m_path(pathToFill), m_fillRule(fillRule) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->fillPath(m_path, m_fillRule);
+ return true;
}
- virtual OperationType type() { return FillPathOperation; }
+ TYPE(FillPathOperation)
private:
Path m_path;
WindRule m_fillRule;
};
-class FillRect : public Operation {
+class FillRect : public PossiblyOpaqueOperation {
public:
FillRect(const FloatRect& rect) : m_rect(rect), m_hasColor(false) {}
void setColor(Color c) { m_color = c; m_hasColor = true; }
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
if (m_hasColor)
context->fillRect(m_rect, m_color);
else
context->fillRect(m_rect);
+ return true;
}
- virtual OperationType type() { return FillRectOperation; }
+ virtual bool isOpaque() { return (m_hasColor && !m_color.hasAlpha())
+ || (!m_hasColor && SkColorGetA(m_state->fillColor) == 0xFF); }
+ TYPE(FillRectOperation)
private:
FloatRect m_rect;
Color m_color;
@@ -688,12 +494,13 @@ public:
, m_bottomRight(bottomRight)
, m_color(color)
{}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->fillRoundedRect(m_rect, m_topLeft, m_topRight,
m_bottomLeft, m_bottomRight,
m_color);
+ return true;
}
- virtual OperationType type() { return FillRoundedRectOperation; }
+ TYPE(FillRoundedRectOperation)
private:
IntRect m_rect;
IntSize m_topLeft;
@@ -710,10 +517,11 @@ public:
, m_startAngle(startAngle)
, m_angleSpan(angleSpan)
{}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->strokeArc(m_rect, m_startAngle, m_angleSpan);
+ return true;
}
- virtual OperationType type() { return StrokeArcOperation; }
+ TYPE(StrokeArcOperation)
private:
IntRect m_rect;
int m_startAngle;
@@ -723,10 +531,11 @@ private:
class StrokePath : public Operation {
public:
StrokePath(const Path& path) : m_path(path) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->strokePath(m_path);
+ return true;
}
- virtual OperationType type() { return StrokePathOperation; }
+ TYPE(StrokePathOperation)
private:
Path m_path;
};
@@ -736,74 +545,72 @@ class StrokeRect : public Operation {
public:
StrokeRect(const FloatRect& rect, float lineWidth)
: m_rect(rect), m_lineWidth(lineWidth) {}
- virtual void apply(PlatformGraphicsContext* context) {
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
context->strokeRect(m_rect, m_lineWidth);
+ return true;
}
- virtual OperationType type() { return StrokeRectOperation; }
+ TYPE(StrokeRectOperation)
private:
FloatRect m_rect;
float m_lineWidth;
};
-//**************************************
-// Text
-//**************************************
-
-class DrawComplexText : public Operation {
+class DrawMediaButton : public Operation {
public:
- DrawComplexText(SkPicture* picture) : m_picture(picture) {
- SkSafeRef(m_picture);
- }
- ~DrawComplexText() { SkSafeUnref(m_picture); }
- virtual void apply(PlatformGraphicsContext* context) {
- if (!context->getCanvas())
- return;
- context->getCanvas()->drawPicture(*m_picture);
+ DrawMediaButton(const IntRect& rect, RenderSkinMediaButton::MediaButton buttonType,
+ bool translucent, bool drawBackground,
+ const IntRect& thumb)
+ : m_rect(rect)
+ , m_thumb(thumb)
+ , m_buttonType(buttonType)
+ , m_translucent(translucent)
+ , m_drawBackground(drawBackground)
+ {}
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
+ context->drawMediaButton(m_rect, m_buttonType, m_translucent, m_drawBackground, m_thumb);
+ return true;
}
- virtual OperationType type() { return DrawComplexTextOperation; }
+ TYPE(DrawMediaButtonOperation)
private:
- SkPicture* m_picture;
+ IntRect m_rect;
+ IntRect m_thumb;
+ RenderSkinMediaButton::MediaButton m_buttonType;
+ bool m_translucent : 1;
+ bool m_drawBackground : 1;
};
-class DrawText : public Operation {
+//**************************************
+// Text
+//**************************************
+
+class DrawPosText : public Operation {
public:
- DrawText(const Font* font, const SimpleFontData* simpleFont,
- const GlyphBuffer& glyphBuffer,
- int from, int numGlyphs, const FloatPoint& point)
- : m_font(font), m_simpleFont(simpleFont)
- , m_glyphBuffer(glyphBuffer), m_from(from)
- , m_numGlyphs(numGlyphs), m_point(point) {
-
- SkPicture* picture = new SkPicture();
- SkCanvas* canvas = picture->beginRecording(0, 0, 0);
- PlatformGraphicsContextSkia platformContext(canvas);
- GraphicsContext graphicsContext(&platformContext);
- m_font->drawGlyphs(&graphicsContext, m_simpleFont,
- m_glyphBuffer, m_from, m_numGlyphs, m_point);
- picture->endRecording();
- m_picture = picture;
- }
- ~DrawText() { SkSafeUnref(m_picture); }
- virtual void apply(PlatformGraphicsContext* context) {
- if (!context->getCanvas())
- return;
- context->getCanvas()->drawPicture(*m_picture);
- }
- virtual OperationType type() { return DrawTextOperation; }
-private:
- SkPicture* m_picture;
- const Font* m_font;
- const SimpleFontData* m_simpleFont;
- const GlyphBuffer m_glyphBuffer;
- int m_from;
- int m_numGlyphs;
- const FloatPoint m_point;
+ DrawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint)
+ : m_byteLength(byteLength)
+ , m_paint(paint)
+ {
+ size_t points = paint.countText(text, byteLength);
+ m_pos = new SkPoint[points];
+ memcpy(m_pos, pos, sizeof(SkPoint) * points);
+ m_text = malloc(byteLength);
+ memcpy(m_text, text, byteLength);
+ }
+ ~DrawPosText() { delete m_pos; free(m_text); }
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
+ context->drawPosText(m_text, m_byteLength, m_pos, m_paint);
+ return true;
+ }
+ TYPE(DrawPosTextOperation)
+private:
+ void* m_text;
+ size_t m_byteLength;
+ SkPoint* m_pos;
+ SkPaint m_paint;
};
}
}
-#endif // USE(ACCELERATED_COMPOSITING)
-
#endif // GraphicsOperation_h
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp
deleted file mode 100644
index 9e6208d..0000000
--- a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#define LOG_TAG "GraphicsOperationCollection"
-#define LOG_NDEBUG 1
-
-#include "config.h"
-#include "GraphicsOperationCollection.h"
-
-#include "AndroidLog.h"
-#include "GraphicsContext.h"
-#include "PlatformGraphicsContext.h"
-#include "PlatformGraphicsContextRecording.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-namespace WebCore {
-
-GraphicsOperationCollection::GraphicsOperationCollection(const IntRect& drawArea)
- : m_drawArea(drawArea)
-{
-}
-
-GraphicsOperationCollection::~GraphicsOperationCollection()
-{
- for (unsigned int i = 0; i < m_operations.size(); i++)
- SkSafeUnref(m_operations[i]);
-}
-
-void GraphicsOperationCollection::apply(PlatformGraphicsContext* context)
-{
- ALOGD("\nApply GraphicsOperationCollection %x, %d operations", this, m_operations.size());
- for (unsigned int i = 0; i < m_operations.size(); i++) {
- ALOGD("[%d] (%x) %s %s", i, this, m_operations[i]->name().ascii().data(),
- m_operations[i]->parameters().ascii().data());
- m_operations[i]->apply(context);
- }
-}
-
-void GraphicsOperationCollection::append(GraphicsOperation::Operation* operation)
-{
- m_operations.append(operation);
-}
-
-bool GraphicsOperationCollection::isEmpty()
-{
- return !m_operations.size();
-}
-
-AutoGraphicsOperationCollection::AutoGraphicsOperationCollection(const IntRect& area)
-{
- m_graphicsOperationCollection = new GraphicsOperationCollection(area);
- m_platformGraphicsContext = new PlatformGraphicsContextRecording(m_graphicsOperationCollection);
- m_graphicsContext = new GraphicsContext(m_platformGraphicsContext);
-}
-
-AutoGraphicsOperationCollection::~AutoGraphicsOperationCollection()
-{
- SkSafeUnref(m_graphicsOperationCollection);
- delete m_graphicsContext;
- delete m_platformGraphicsContext;
-}
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp
index ce9ce5a..367abda 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp
@@ -82,6 +82,8 @@ static bool setBitmapDash(SkPaint* paint, int width) {
s->setLocalMatrix(matrix);
paint->setShader(s)->unref();
+ paint->setFilterBitmap(true);
+ paint->setAntiAlias(true);
return true;
}
@@ -159,7 +161,7 @@ bool PlatformGraphicsContext::State::setupShadowPaint(SkPaint* paint, SkPoint* o
// HTMLCanvasElement have shadows ignore transforms set. This
// allows us to distinguish between CSS and Canvas shadows which
// have different rendering specifications.
- uint32_t flags = SkBlurMaskFilter::kHighQuality_BlurFlag;
+ uint32_t flags = SkBlurMaskFilter::kNone_BlurFlag;
if (shadowsIgnoreTransforms) {
offset->fY = -offset->fY;
flags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag;
@@ -167,7 +169,7 @@ bool PlatformGraphicsContext::State::setupShadowPaint(SkPaint* paint, SkPoint* o
if (shadow.blur > 0) {
paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur,
- SkBlurMaskFilter::kNormal_BlurStyle))->unref();
+ SkBlurMaskFilter::kNormal_BlurStyle, flags))->unref();
}
return SkColorGetA(shadow.color) && (shadow.blur || shadow.dx || shadow.dy);
}
@@ -244,22 +246,31 @@ void PlatformGraphicsContext::setCompositeOperation(CompositeOperator op)
m_state->mode = WebCoreCompositeToSkiaComposite(op);
}
-void PlatformGraphicsContext::setFillColor(const Color& c)
+bool PlatformGraphicsContext::setFillColor(const Color& c)
{
- m_state->fillColor = c.rgb();
- setFillShader(0);
+ bool dirty = false;
+ if (m_state->fillColor != c.rgb()) {
+ m_state->fillColor = c.rgb();
+ dirty = true;
+ }
+ return setFillShader(0) || dirty;
}
-void PlatformGraphicsContext::setFillShader(SkShader* fillShader)
+bool PlatformGraphicsContext::setFillShader(SkShader* fillShader)
{
- if (fillShader)
+ bool dirty = false;
+ if (fillShader && m_state->fillColor != Color::black) {
m_state->fillColor = Color::black;
+ dirty = true;
+ }
if (fillShader != m_state->fillShader) {
SkSafeUnref(m_state->fillShader);
m_state->fillShader = fillShader;
SkSafeRef(m_state->fillShader);
+ dirty = true;
}
+ return dirty;
}
void PlatformGraphicsContext::setLineCap(LineCap cap)
@@ -331,22 +342,31 @@ void PlatformGraphicsContext::setShouldAntialias(bool useAA)
m_state->useAA = useAA;
}
-void PlatformGraphicsContext::setStrokeColor(const Color& c)
+bool PlatformGraphicsContext::setStrokeColor(const Color& c)
{
- m_state->strokeColor = c.rgb();
- setStrokeShader(0);
+ bool dirty = false;
+ if (m_state->strokeColor != c.rgb()) {
+ m_state->strokeColor = c.rgb();
+ dirty = true;
+ }
+ return setStrokeShader(0) || dirty;
}
-void PlatformGraphicsContext::setStrokeShader(SkShader* strokeShader)
+bool PlatformGraphicsContext::setStrokeShader(SkShader* strokeShader)
{
- if (strokeShader)
+ bool dirty = false;
+ if (strokeShader && m_state->strokeColor != Color::black) {
m_state->strokeColor = Color::black;
+ dirty = true;
+ }
if (strokeShader != m_state->strokeShader) {
SkSafeUnref(m_state->strokeShader);
m_state->strokeShader = strokeShader;
SkSafeRef(m_state->strokeShader);
+ dirty = true;
}
+ return dirty;
}
void PlatformGraphicsContext::setStrokeStyle(StrokeStyle style)
@@ -375,7 +395,7 @@ void PlatformGraphicsContext::setupPaintCommon(SkPaint* paint) const
// allows us to distinguish between CSS and Canvas shadows which
// have different rendering specifications.
SkScalar dy = m_state->shadow.dy;
- uint32_t flags = SkBlurDrawLooper::kHighQuality_BlurFlag;
+ uint32_t flags = SkBlurDrawLooper::kNone_BlurFlag;
if (shadowsIgnoreTransforms()) {
dy = -dy;
flags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag;
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h
index 1916014..56aceff 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h
@@ -29,6 +29,7 @@
#include "IntRect.h"
#include "GraphicsContext.h"
#include "RenderSkinAndroid.h"
+#include "RenderSkinMediaButton.h"
#include "SkCanvas.h"
#include "SkPicture.h"
#include "SkTDArray.h"
@@ -40,10 +41,11 @@ namespace WebCore {
class PlatformGraphicsContext {
public:
+ class State;
+
PlatformGraphicsContext();
virtual ~PlatformGraphicsContext();
virtual bool isPaintingDisabled() = 0;
- virtual SkCanvas* getCanvas() = 0;
void setGraphicsContext(GraphicsContext* gc) { m_gc = gc; }
virtual bool deleteUs() const { return false; }
@@ -61,16 +63,16 @@ public:
virtual void setAlpha(float alpha);
int getNormalizedAlpha() const;
virtual void setCompositeOperation(CompositeOperator op);
- virtual void setFillColor(const Color& c);
- virtual void setFillShader(SkShader* fillShader);
+ virtual bool setFillColor(const Color& c);
+ virtual bool setFillShader(SkShader* fillShader);
virtual void setLineCap(LineCap cap);
virtual void setLineDash(const DashArray& dashes, float dashOffset);
virtual void setLineJoin(LineJoin join);
virtual void setMiterLimit(float limit);
virtual void setShadow(int radius, int dx, int dy, SkColor c);
virtual void setShouldAntialias(bool useAA);
- virtual void setStrokeColor(const Color& c);
- virtual void setStrokeShader(SkShader* strokeShader);
+ virtual bool setStrokeColor(const Color& c);
+ virtual bool setStrokeShader(SkShader* strokeShader);
virtual void setStrokeStyle(StrokeStyle style);
virtual void setStrokeThickness(float f);
@@ -92,19 +94,20 @@ public:
// Clipping
virtual void addInnerRoundedRectClip(const IntRect& rect, int thickness) = 0;
virtual void canvasClip(const Path& path) = 0;
- virtual void clip(const FloatRect& rect) = 0;
- virtual void clip(const Path& path) = 0;
- virtual void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias) = 0;
- virtual void clipOut(const IntRect& r) = 0;
- virtual void clipOut(const Path& p) = 0;
- virtual void clipPath(const Path& pathToClip, WindRule clipRule) = 0;
+ virtual bool clip(const FloatRect& rect) = 0;
+ virtual bool clip(const Path& path) = 0;
+ virtual bool clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias) = 0;
+ virtual bool clipOut(const IntRect& r) = 0;
+ virtual bool clipOut(const Path& p) = 0;
+ virtual bool clipPath(const Path& pathToClip, WindRule clipRule) = 0;
+ virtual SkIRect getTotalClipBounds() = 0;
// Drawing
virtual void clearRect(const FloatRect& rect) = 0;
virtual void drawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
CompositeOperator compositeOp, const FloatRect& destRect) = 0;
virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
- const SkRect& dst, CompositeOperator op) = 0;
+ const SkRect& dst, CompositeOperator op = CompositeSourceOver) = 0;
virtual void drawConvexPolygon(size_t numPoints, const FloatPoint* points,
bool shouldAntialias) = 0;
virtual void drawEllipse(const IntRect& rect) = 0;
@@ -117,7 +120,7 @@ public:
virtual void drawLine(const IntPoint& point1, const IntPoint& point2) = 0;
virtual void drawLineForText(const FloatPoint& pt, float width) = 0;
virtual void drawLineForTextChecking(const FloatPoint& pt, float width,
- GraphicsContext::TextCheckingLineStyle) = 0;
+ GraphicsContext::TextCheckingLineStyle) = 0;
virtual void drawRect(const IntRect& rect) = 0;
virtual void fillPath(const Path& pathToFill, WindRule fillRule) = 0;
virtual void fillRect(const FloatRect& rect) = 0;
@@ -138,10 +141,15 @@ public:
virtual void strokePath(const Path& pathToStroke) = 0;
virtual void strokeRect(const FloatRect& rect, float lineWidth) = 0;
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint) = 0;
+ virtual void drawMediaButton(const IntRect& rect, RenderSkinMediaButton::MediaButton buttonType,
+ bool translucent = false, bool drawBackground = true,
+ const IntRect& thumb = IntRect()) = 0;
+
virtual SkCanvas* recordingCanvas() = 0;
- virtual void endRecording(int type = 0) = 0;
-protected:
+ void setRawState(State* state) { m_state = state; }
struct ShadowRec {
SkScalar blur;
@@ -192,11 +200,11 @@ protected:
friend class PlatformGraphicsContextSkia;
};
+protected:
virtual bool shadowsIgnoreTransforms() const = 0;
void setupPaintCommon(SkPaint* paint) const;
GraphicsContext* m_gc; // Back-ptr to our parent
- struct State;
WTF::Vector<State> m_stateStack;
State* m_state;
};
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
index d96124d..6c033b6 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
@@ -1,3 +1,28 @@
+/*
+ * Copyright 2012, 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.
+ */
+
#define LOG_TAG "PlatformGraphicsContextRecording"
#define LOG_NDEBUG 1
@@ -5,71 +30,470 @@
#include "PlatformGraphicsContextRecording.h"
#include "AndroidLog.h"
+#include "FloatRect.h"
+#include "FloatQuad.h"
#include "Font.h"
#include "GraphicsContext.h"
-#include "GraphicsOperationCollection.h"
#include "GraphicsOperation.h"
+#include "LinearAllocator.h"
+#include "PlatformGraphicsContextSkia.h"
+#include "RTree.h"
+
+#include "wtf/NonCopyingSort.h"
+#include "wtf/HashSet.h"
+#include "wtf/StringHasher.h"
+
+#define NEW_OP(X) new (operationHeap()) GraphicsOperation::X
+
+#define USE_CLIPPING_PAINTER true
namespace WebCore {
+static FloatRect approximateTextBounds(size_t numGlyphs,
+ const SkPoint pos[], const SkPaint& paint)
+{
+ if (!numGlyphs || !pos) {
+ return FloatRect();
+ }
+
+ // get glyph position bounds
+ SkScalar minX = pos[0].x();
+ SkScalar maxX = minX;
+ SkScalar minY = pos[0].y();
+ SkScalar maxY = minY;
+ for (size_t i = 1; i < numGlyphs; ++i) {
+ SkScalar x = pos[i].x();
+ SkScalar y = pos[i].y();
+ minX = std::min(minX, x);
+ maxX = std::max(maxX, x);
+ minY = std::min(minY, y);
+ maxY = std::max(maxY, y);
+ }
+
+ // build final rect
+ SkPaint::FontMetrics metrics;
+ SkScalar bufY = paint.getFontMetrics(&metrics);
+ SkScalar bufX = bufY * 2;
+ SkScalar adjY = metrics.fAscent / 2;
+ minY += adjY;
+ maxY += adjY;
+ SkRect rect;
+ rect.set(minX - bufX, minY - bufY, maxX + bufX, maxY + bufY);
+ return rect;
+}
+
+class StateHash {
+public:
+ static unsigned hash(PlatformGraphicsContext::State* const& state)
+ {
+ return StringHasher::hashMemory(state, sizeof(PlatformGraphicsContext::State));
+ }
+
+ static bool equal(PlatformGraphicsContext::State* const& a,
+ PlatformGraphicsContext::State* const& b)
+ {
+ return a && b && !memcmp(a, b, sizeof(PlatformGraphicsContext::State));
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+typedef HashSet<PlatformGraphicsContext::State*, StateHash> StateHashSet;
+
+class CanvasState {
+public:
+ CanvasState(CanvasState* parent)
+ : m_parent(parent)
+ , m_isTransparencyLayer(false)
+ {}
+
+ CanvasState(CanvasState* parent, float opacity)
+ : m_parent(parent)
+ , m_isTransparencyLayer(true)
+ , m_opacity(opacity)
+ {}
+
+ ~CanvasState() {
+ ALOGV("Delete %p", this);
+ for (size_t i = 0; i < m_operations.size(); i++)
+ delete m_operations[i];
+ m_operations.clear();
+ }
+
+ bool isParentOf(CanvasState* other) {
+ while (other->m_parent) {
+ if (other->m_parent == this)
+ return true;
+ other = other->m_parent;
+ }
+ return false;
+ }
+
+ void playback(PlatformGraphicsContext* context, size_t fromId, size_t toId) const {
+ ALOGV("playback %p from %d->%d", this, fromId, toId);
+ for (size_t i = 0; i < m_operations.size(); i++) {
+ RecordingData *data = m_operations[i];
+ if (data->m_orderBy < fromId)
+ continue;
+ if (data->m_orderBy > toId)
+ break;
+ ALOGV("Applying operation[%d] %p->%s()", i, data->m_operation,
+ data->m_operation->name());
+ data->m_operation->apply(context);
+ }
+ }
+
+ CanvasState* parent() { return m_parent; }
+
+ void enterState(PlatformGraphicsContext* context) {
+ ALOGV("enterState %p", this);
+ if (m_isTransparencyLayer)
+ context->beginTransparencyLayer(m_opacity);
+ else
+ context->save();
+ }
+
+ void exitState(PlatformGraphicsContext* context) {
+ ALOGV("exitState %p", this);
+ if (m_isTransparencyLayer)
+ context->endTransparencyLayer();
+ else
+ context->restore();
+ }
+
+ void adoptAndAppend(RecordingData* data) {
+ m_operations.append(data);
+ }
+
+ bool isTransparencyLayer() {
+ return m_isTransparencyLayer;
+ }
+
+ void* operator new(size_t size, LinearAllocator* la) {
+ return la->alloc(size);
+ }
+
+private:
+ CanvasState *m_parent;
+ bool m_isTransparencyLayer;
+ float m_opacity;
+ Vector<RecordingData*> m_operations;
+};
+
+class RecordingImpl {
+private:
+ // Careful, ordering matters here. Ordering is first constructed == last destroyed,
+ // so we have to make sure our Heap is the first thing listed so that it is
+ // the last thing destroyed.
+ LinearAllocator m_operationHeap;
+ LinearAllocator m_canvasStateHeap;
+ LinearAllocator m_stateHeap;
+public:
+ RecordingImpl()
+ : m_canvasStateHeap(sizeof(CanvasState))
+ , m_stateHeap(sizeof(PlatformGraphicsContext::State))
+ , m_nodeCount(0)
+ {
+ }
+
+ ~RecordingImpl() {
+ clearStates();
+ clearCanvasStates();
+ }
+
+ PlatformGraphicsContext::State* getState(PlatformGraphicsContext::State* inState) {
+ StateHashSet::iterator it = m_states.find(inState);
+ if (it != m_states.end())
+ return (*it);
+ void* buf = m_stateHeap.alloc(sizeof(PlatformGraphicsContext::State));
+ PlatformGraphicsContext::State* state = new (buf) PlatformGraphicsContext::State(*inState);
+ m_states.add(state);
+ return state;
+ }
+
+ void addCanvasState(CanvasState* state) {
+ m_canvasStates.append(state);
+ }
+
+ void removeCanvasState(const CanvasState* state) {
+ if (m_canvasStates.last() == state)
+ m_canvasStates.removeLast();
+ else {
+ size_t indx = m_canvasStates.find(state);
+ m_canvasStates.remove(indx);
+ }
+ }
+
+ void applyState(PlatformGraphicsContext* context,
+ CanvasState* fromState, size_t fromId,
+ CanvasState* toState, size_t toId) {
+ ALOGV("applyState(%p->%p, %d-%d)", fromState, toState, fromId, toId);
+ if (fromState != toState && fromState) {
+ if (fromState->isParentOf(toState)) {
+ // Going down the tree, playback any parent operations then save
+ // before playing back our current operations
+ applyState(context, fromState, fromId, toState->parent(), toId);
+ toState->enterState(context);
+ } else if (toState->isParentOf(fromState)) {
+ // Going up the tree, pop some states
+ while (fromState != toState) {
+ fromState->exitState(context);
+ fromState = fromState->parent();
+ }
+ } else {
+ // Siblings in the tree
+ fromState->exitState(context);
+ applyState(context, fromState->parent(), fromId, toState, toId);
+ return;
+ }
+ } else if (!fromState) {
+ if (toState->parent())
+ applyState(context, fromState, fromId, toState->parent(), toId);
+ toState->enterState(context);
+ }
+ toState->playback(context, fromId, toId);
+ }
+
+ LinearAllocator* operationHeap() { return &m_operationHeap; }
+ LinearAllocator* canvasStateHeap() { return &m_canvasStateHeap; }
+
+ RTree::RTree m_tree;
+ int m_nodeCount;
+
+private:
+
+ void clearStates() {
+ StateHashSet::iterator end = m_states.end();
+ for (StateHashSet::iterator it = m_states.begin(); it != end; ++it)
+ (*it)->~State();
+ m_states.clear();
+ }
+
+ void clearCanvasStates() {
+ for (size_t i = 0; i < m_canvasStates.size(); i++)
+ m_canvasStates[i]->~CanvasState();
+ m_canvasStates.clear();
+ }
+
+ // TODO: Use a global pool?
+ StateHashSet m_states;
+ Vector<CanvasState*> m_canvasStates;
+};
+
+Recording::~Recording()
+{
+ delete m_recording;
+}
+
+static bool CompareRecordingDataOrder(const RecordingData* a, const RecordingData* b)
+{
+ return a->m_orderBy < b->m_orderBy;
+}
+
+static IntRect enclosedIntRect(const FloatRect& rect)
+{
+ float left = ceilf(rect.x());
+ float top = ceilf(rect.y());
+ float width = floorf(rect.maxX()) - left;
+ float height = floorf(rect.maxY()) - top;
+
+ return IntRect(clampToInteger(left), clampToInteger(top),
+ clampToInteger(width), clampToInteger(height));
+}
+
+#if USE_CLIPPING_PAINTER
+class ClippingPainter {
+public:
+ ClippingPainter(RecordingImpl* recording,
+ PlatformGraphicsContextSkia& context,
+ const SkMatrix& initialMatrix,
+ Vector<RecordingData*> &nodes)
+ : m_recording(recording)
+ , m_context(context)
+ , m_initialMatrix(initialMatrix)
+ , m_nodes(nodes)
+ , m_lastOperationId(0)
+ , m_currState(0)
+ {}
+
+ void draw(const SkIRect& bounds) {
+ SkRegion coveredArea(bounds);
+
+ drawWithClipRecursive(static_cast<int>(m_nodes.size()) - 1, coveredArea);
+
+ while (m_currState) {
+ m_currState->exitState(&m_context);
+ m_currState = m_currState->parent();
+ }
+ }
+
+private:
+ void drawOperation(RecordingData* node, const SkRegion& covered)
+ {
+ GraphicsOperation::Operation* op = node->m_operation;
+ m_recording->applyState(&m_context, m_currState,
+ m_lastOperationId, op->m_canvasState, node->m_orderBy);
+ m_currState = op->m_canvasState;
+ m_lastOperationId = node->m_orderBy;
+
+ // if other opaque operations will cover the current one, clip that area out
+ // (and restore the clip immediately after drawing)
+ if (!covered.isEmpty()) {
+ m_context.save();
+ m_context.canvas()->clipRegion(covered, SkRegion::kIntersect_Op);
+ }
+ op->apply(&(m_context));
+ if (!covered.isEmpty())
+ m_context.restore();
+ }
+
+ void drawWithClipRecursive(int index, const SkRegion& covered)
+ {
+ if (index < 0)
+ return;
+ RecordingData* recordingData = m_nodes[index];
+ GraphicsOperation::Operation* op = recordingData->m_operation;
+ if (index != 0) {
+ const IntRect* opaqueRect = op->opaqueRect();
+ if (!opaqueRect || opaqueRect->isEmpty()) {
+ drawWithClipRecursive(index - 1, covered);
+ } else {
+ SkRegion newCovered = covered;
+ SkRect mappedRect = *opaqueRect;
+ m_initialMatrix.mapRect(&mappedRect);
+ newCovered.op(enclosedIntRect(mappedRect), SkRegion::kDifference_Op);
+ if (!newCovered.isEmpty())
+ drawWithClipRecursive(index - 1, newCovered);
+ }
+ }
+ drawOperation(recordingData, covered);
+ }
+
+ RecordingImpl* m_recording;
+ PlatformGraphicsContextSkia& m_context;
+ const SkMatrix& m_initialMatrix;
+ const Vector<RecordingData*>& m_nodes;
+ size_t m_lastOperationId;
+ CanvasState* m_currState;
+};
+#endif // USE_CLIPPING_PAINTER
+
+void Recording::draw(SkCanvas* canvas)
+{
+ if (!m_recording) {
+ ALOGW("No recording!");
+ return;
+ }
+ SkRect clip;
+ if (!canvas->getClipBounds(&clip)) {
+ ALOGW("Empty clip!");
+ return;
+ }
+ Vector<RecordingData*> nodes;
+
+ WebCore::IntRect iclip = enclosingIntRect(clip);
+ m_recording->m_tree.search(iclip, nodes);
+
+ size_t count = nodes.size();
+ ALOGV("Drawing %d nodes out of %d", count, m_recording->m_nodeCount);
+ if (count) {
+ int saveCount = canvas->getSaveCount();
+ nonCopyingSort(nodes.begin(), nodes.end(), CompareRecordingDataOrder);
+ PlatformGraphicsContextSkia context(canvas);
+#if USE_CLIPPING_PAINTER
+ ClippingPainter painter(recording(), context, canvas->getTotalMatrix(), nodes);
+ painter.draw(canvas->getTotalClip().getBounds());
+#else
+ CanvasState* currState = 0;
+ size_t lastOperationId = 0;
+ for (size_t i = 0; i < count; i++) {
+ GraphicsOperation::Operation* op = nodes[i]->m_operation;
+ m_recording->applyState(&context, currState, lastOperationId,
+ op->m_canvasState, nodes[i]->m_orderBy);
+ currState = op->m_canvasState;
+ lastOperationId = nodes[i]->m_orderBy;
+ ALOGV("apply: %p->%s()", op, op->name());
+ op->apply(&context);
+ }
+ while (currState) {
+ currState->exitState(&context);
+ currState = currState->parent();
+ }
+#endif
+ if (saveCount != canvas->getSaveCount()) {
+ ALOGW("Save/restore mismatch! %d vs. %d", saveCount, canvas->getSaveCount());
+ }
+ }
+}
+
+void Recording::setRecording(RecordingImpl* impl)
+{
+ if (m_recording == impl)
+ return;
+ if (m_recording)
+ delete m_recording;
+ m_recording = impl;
+}
+
//**************************************
// PlatformGraphicsContextRecording
//**************************************
-PlatformGraphicsContextRecording::PlatformGraphicsContextRecording(GraphicsOperationCollection* picture)
+PlatformGraphicsContextRecording::PlatformGraphicsContextRecording(Recording* recording)
: PlatformGraphicsContext()
- , mGraphicsOperationCollection(picture)
, mPicture(0)
+ , mRecording(recording)
+ , mOperationState(0)
+ , m_hasText(false)
+ , m_isEmpty(true)
+ , m_canvasProxy(this)
{
+ if (mRecording)
+ mRecording->setRecording(new RecordingImpl());
+ mMatrixStack.append(SkMatrix::I());
+ mCurrentMatrix = &(mMatrixStack.last());
+ pushStateOperation(new (canvasStateHeap()) CanvasState(0));
}
bool PlatformGraphicsContextRecording::isPaintingDisabled()
{
- return !mGraphicsOperationCollection;
+ return !mRecording;
}
SkCanvas* PlatformGraphicsContextRecording::recordingCanvas()
{
- SkSafeUnref(mPicture);
- mPicture = new SkPicture();
- return mPicture->beginRecording(0, 0, 0);
+ m_hasText = true;
+ return &m_canvasProxy;
}
-void PlatformGraphicsContextRecording::endRecording(int type)
-{
- if (!mPicture)
- return;
- mPicture->endRecording();
- GraphicsOperation::DrawComplexText* text = new GraphicsOperation::DrawComplexText(mPicture);
- mGraphicsOperationCollection->append(text);
- mPicture = 0;
-}
-
-
//**************************************
// State management
//**************************************
void PlatformGraphicsContextRecording::beginTransparencyLayer(float opacity)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::BeginTransparencyLayer(opacity));
+ CanvasState* parent = mRecordingStateStack.last().mCanvasState;
+ pushStateOperation(new (canvasStateHeap()) CanvasState(parent, opacity));
}
void PlatformGraphicsContextRecording::endTransparencyLayer()
{
- mGraphicsOperationCollection->append(new GraphicsOperation::EndTransparencyLayer());
+ popStateOperation();
}
void PlatformGraphicsContextRecording::save()
{
PlatformGraphicsContext::save();
- mGraphicsOperationCollection->append(new GraphicsOperation::Save());
+ CanvasState* parent = mRecordingStateStack.last().mCanvasState;
+ pushStateOperation(new (canvasStateHeap()) CanvasState(parent));
+ pushMatrix();
}
void PlatformGraphicsContextRecording::restore()
{
PlatformGraphicsContext::restore();
- mGraphicsOperationCollection->append(new GraphicsOperation::Restore());
+ popMatrix();
+ popStateOperation();
}
//**************************************
@@ -79,86 +503,98 @@ void PlatformGraphicsContextRecording::restore()
void PlatformGraphicsContextRecording::setAlpha(float alpha)
{
PlatformGraphicsContext::setAlpha(alpha);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetAlpha(alpha));
+ mOperationState = 0;
}
void PlatformGraphicsContextRecording::setCompositeOperation(CompositeOperator op)
{
PlatformGraphicsContext::setCompositeOperation(op);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetCompositeOperation(op));
+ mOperationState = 0;
}
-void PlatformGraphicsContextRecording::setFillColor(const Color& c)
+bool PlatformGraphicsContextRecording::setFillColor(const Color& c)
{
- PlatformGraphicsContext::setFillColor(c);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetFillColor(c));
+ if (PlatformGraphicsContext::setFillColor(c)) {
+ mOperationState = 0;
+ return true;
+ }
+ return false;
}
-void PlatformGraphicsContextRecording::setFillShader(SkShader* fillShader)
+bool PlatformGraphicsContextRecording::setFillShader(SkShader* fillShader)
{
- PlatformGraphicsContext::setFillShader(fillShader);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetFillShader(fillShader));
+ if (PlatformGraphicsContext::setFillShader(fillShader)) {
+ mOperationState = 0;
+ return true;
+ }
+ return false;
}
void PlatformGraphicsContextRecording::setLineCap(LineCap cap)
{
PlatformGraphicsContext::setLineCap(cap);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetLineCap(cap));
+ mOperationState = 0;
}
void PlatformGraphicsContextRecording::setLineDash(const DashArray& dashes, float dashOffset)
{
PlatformGraphicsContext::setLineDash(dashes, dashOffset);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetLineDash(dashes, dashOffset));
+ mOperationState = 0;
}
void PlatformGraphicsContextRecording::setLineJoin(LineJoin join)
{
PlatformGraphicsContext::setLineJoin(join);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetLineJoin(join));
+ mOperationState = 0;
}
void PlatformGraphicsContextRecording::setMiterLimit(float limit)
{
PlatformGraphicsContext::setMiterLimit(limit);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetMiterLimit(limit));
+ mOperationState = 0;
}
void PlatformGraphicsContextRecording::setShadow(int radius, int dx, int dy, SkColor c)
{
PlatformGraphicsContext::setShadow(radius, dx, dy, c);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetShadow(radius, dx, dy, c));
+ mOperationState = 0;
}
void PlatformGraphicsContextRecording::setShouldAntialias(bool useAA)
{
m_state->useAA = useAA;
PlatformGraphicsContext::setShouldAntialias(useAA);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetShouldAntialias(useAA));
+ mOperationState = 0;
}
-void PlatformGraphicsContextRecording::setStrokeColor(const Color& c)
+bool PlatformGraphicsContextRecording::setStrokeColor(const Color& c)
{
- PlatformGraphicsContext::setStrokeColor(c);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeColor(c));
+ if (PlatformGraphicsContext::setStrokeColor(c)) {
+ mOperationState = 0;
+ return true;
+ }
+ return false;
}
-void PlatformGraphicsContextRecording::setStrokeShader(SkShader* strokeShader)
+bool PlatformGraphicsContextRecording::setStrokeShader(SkShader* strokeShader)
{
- PlatformGraphicsContext::setStrokeShader(strokeShader);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeShader(strokeShader));
+ if (PlatformGraphicsContext::setStrokeShader(strokeShader)) {
+ mOperationState = 0;
+ return true;
+ }
+ return false;
}
void PlatformGraphicsContextRecording::setStrokeStyle(StrokeStyle style)
{
PlatformGraphicsContext::setStrokeStyle(style);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeStyle(style));
+ mOperationState = 0;
}
void PlatformGraphicsContextRecording::setStrokeThickness(float f)
{
PlatformGraphicsContext::setStrokeThickness(f);
- mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeThickness(f));
+ mOperationState = 0;
}
//**************************************
@@ -167,32 +603,32 @@ void PlatformGraphicsContextRecording::setStrokeThickness(float f)
void PlatformGraphicsContextRecording::concatCTM(const AffineTransform& affine)
{
- mCurrentMatrix.preConcat(affine);
- mGraphicsOperationCollection->append(new GraphicsOperation::ConcatCTM(affine));
+ mCurrentMatrix->preConcat(affine);
+ appendStateOperation(NEW_OP(ConcatCTM)(affine));
}
void PlatformGraphicsContextRecording::rotate(float angleInRadians)
{
float value = angleInRadians * (180.0f / 3.14159265f);
- mCurrentMatrix.preRotate(SkFloatToScalar(value));
- mGraphicsOperationCollection->append(new GraphicsOperation::Rotate(angleInRadians));
+ mCurrentMatrix->preRotate(SkFloatToScalar(value));
+ appendStateOperation(NEW_OP(Rotate)(angleInRadians));
}
void PlatformGraphicsContextRecording::scale(const FloatSize& size)
{
- mCurrentMatrix.preScale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height()));
- mGraphicsOperationCollection->append(new GraphicsOperation::Scale(size));
+ mCurrentMatrix->preScale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height()));
+ appendStateOperation(NEW_OP(Scale)(size));
}
void PlatformGraphicsContextRecording::translate(float x, float y)
{
- mCurrentMatrix.preTranslate(SkFloatToScalar(x), SkFloatToScalar(y));
- mGraphicsOperationCollection->append(new GraphicsOperation::Translate(x, y));
+ mCurrentMatrix->preTranslate(SkFloatToScalar(x), SkFloatToScalar(y));
+ appendStateOperation(NEW_OP(Translate)(x, y));
}
const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix()
{
- return mCurrentMatrix;
+ return *mCurrentMatrix;
}
//**************************************
@@ -202,50 +638,65 @@ const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix()
void PlatformGraphicsContextRecording::addInnerRoundedRectClip(const IntRect& rect,
int thickness)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::InnerRoundedRectClip(rect, thickness));
+ mRecordingStateStack.last().setHasComplexClip();
+ appendStateOperation(NEW_OP(InnerRoundedRectClip)(rect, thickness));
}
void PlatformGraphicsContextRecording::canvasClip(const Path& path)
{
+ mRecordingStateStack.last().setHasComplexClip();
clip(path);
}
-void PlatformGraphicsContextRecording::clip(const FloatRect& rect)
+bool PlatformGraphicsContextRecording::clip(const FloatRect& rect)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::Clip(rect));
+ clipState(rect);
+ appendStateOperation(NEW_OP(Clip)(rect));
+ return true;
}
-void PlatformGraphicsContextRecording::clip(const Path& path)
+bool PlatformGraphicsContextRecording::clip(const Path& path)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::ClipPath(path));
+ mRecordingStateStack.last().setHasComplexClip();
+ clipState(path.boundingRect());
+ appendStateOperation(NEW_OP(ClipPath)(path));
+ return true;
}
-void PlatformGraphicsContextRecording::clipConvexPolygon(size_t numPoints,
+bool PlatformGraphicsContextRecording::clipConvexPolygon(size_t numPoints,
const FloatPoint*, bool antialias)
{
// TODO
+ return true;
}
-void PlatformGraphicsContextRecording::clipOut(const IntRect& r)
+bool PlatformGraphicsContextRecording::clipOut(const IntRect& r)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::ClipOut(r));
+ mRecordingStateStack.last().setHasComplexClip();
+ appendStateOperation(NEW_OP(ClipOut)(r));
+ return true;
}
-void PlatformGraphicsContextRecording::clipOut(const Path& path)
+bool PlatformGraphicsContextRecording::clipOut(const Path& path)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::ClipPath(path, true));
+ mRecordingStateStack.last().setHasComplexClip();
+ appendStateOperation(NEW_OP(ClipPath)(path, true));
+ return true;
}
-void PlatformGraphicsContextRecording::clipPath(const Path& pathToClip, WindRule clipRule)
+bool PlatformGraphicsContextRecording::clipPath(const Path& pathToClip, WindRule clipRule)
{
- GraphicsOperation::ClipPath* operation = new GraphicsOperation::ClipPath(pathToClip);
+ mRecordingStateStack.last().setHasComplexClip();
+ clipState(pathToClip.boundingRect());
+ GraphicsOperation::ClipPath* operation = NEW_OP(ClipPath)(pathToClip);
operation->setWindRule(clipRule);
- mGraphicsOperationCollection->append(operation);
+ appendStateOperation(operation);
+ return true;
}
void PlatformGraphicsContextRecording::clearRect(const FloatRect& rect)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::ClearRect(rect));
+ appendDrawingOperation(NEW_OP(ClearRect)(rect), rect);
}
//**************************************
@@ -256,33 +707,48 @@ void PlatformGraphicsContextRecording::drawBitmapPattern(
const SkBitmap& bitmap, const SkMatrix& matrix,
CompositeOperator compositeOp, const FloatRect& destRect)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::DrawBitmapPattern(bitmap, matrix, compositeOp, destRect));
+ appendDrawingOperation(
+ NEW_OP(DrawBitmapPattern)(bitmap, matrix, compositeOp, destRect),
+ destRect);
}
void PlatformGraphicsContextRecording::drawBitmapRect(const SkBitmap& bitmap,
const SkIRect* src, const SkRect& dst,
CompositeOperator op)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::DrawBitmapRect(bitmap, *src, dst, op));
+ appendDrawingOperation(NEW_OP(DrawBitmapRect)(bitmap, *src, dst, op), dst);
}
void PlatformGraphicsContextRecording::drawConvexPolygon(size_t numPoints,
const FloatPoint* points,
bool shouldAntialias)
{
- // TODO
+ if (numPoints < 1) return;
+ if (numPoints != 4) {
+ // TODO: Build a path and call draw on that (webkit currently never calls this)
+ ALOGW("drawConvexPolygon with numPoints != 4 is not supported!");
+ return;
+ }
+ FloatRect bounds;
+ bounds.fitToPoints(points[0], points[1], points[2], points[3]);
+ appendDrawingOperation(NEW_OP(DrawConvexPolygonQuad)(points, shouldAntialias), bounds);
}
void PlatformGraphicsContextRecording::drawEllipse(const IntRect& rect)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::DrawEllipse(rect));
+ appendDrawingOperation(NEW_OP(DrawEllipse)(rect), rect);
}
void PlatformGraphicsContextRecording::drawFocusRing(const Vector<IntRect>& rects,
- int /* width */, int /* offset */,
+ int width, int offset,
const Color& color)
{
- // TODO
+ if (!rects.size())
+ return;
+ IntRect bounds = rects[0];
+ for (size_t i = 1; i < rects.size(); i++)
+ bounds.unite(rects[i]);
+ appendDrawingOperation(NEW_OP(DrawFocusRing)(rects, width, offset, color), bounds);
}
void PlatformGraphicsContextRecording::drawHighlightForText(
@@ -307,41 +773,47 @@ void PlatformGraphicsContextRecording::drawHighlightForText(
void PlatformGraphicsContextRecording::drawLine(const IntPoint& point1,
const IntPoint& point2)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::DrawLine(point1, point2));
+ FloatRect bounds = FloatQuad(point1, point1, point2, point2).boundingBox();
+ float width = m_state->strokeThickness;
+ if (!width) width = 1;
+ bounds.inflate(width);
+ appendDrawingOperation(NEW_OP(DrawLine)(point1, point2), bounds);
}
void PlatformGraphicsContextRecording::drawLineForText(const FloatPoint& pt, float width)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::DrawLineForText(pt, width));
+ FloatRect bounds(pt.x(), pt.y(), width, m_state->strokeThickness);
+ appendDrawingOperation(NEW_OP(DrawLineForText)(pt, width), bounds);
}
void PlatformGraphicsContextRecording::drawLineForTextChecking(const FloatPoint& pt,
float width, GraphicsContext::TextCheckingLineStyle lineStyle)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::DrawLineForTextChecking(pt, width, lineStyle));
+ FloatRect bounds(pt.x(), pt.y(), width, m_state->strokeThickness);
+ appendDrawingOperation(NEW_OP(DrawLineForTextChecking)(pt, width, lineStyle), bounds);
}
void PlatformGraphicsContextRecording::drawRect(const IntRect& rect)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::DrawRect(rect));
+ appendDrawingOperation(NEW_OP(DrawRect)(rect), rect);
}
void PlatformGraphicsContextRecording::fillPath(const Path& pathToFill, WindRule fillRule)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::FillPath(pathToFill, fillRule));
+ appendDrawingOperation(NEW_OP(FillPath)(pathToFill, fillRule), pathToFill.boundingRect());
}
void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::FillRect(rect));
+ appendDrawingOperation(NEW_OP(FillRect)(rect), rect);
}
void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect,
const Color& color)
{
- GraphicsOperation::FillRect* operation = new GraphicsOperation::FillRect(rect);
+ GraphicsOperation::FillRect* operation = NEW_OP(FillRect)(rect);
operation->setColor(color);
- mGraphicsOperationCollection->append(operation);
+ appendDrawingOperation(operation, rect);
}
void PlatformGraphicsContextRecording::fillRoundedRect(
@@ -349,25 +821,186 @@ void PlatformGraphicsContextRecording::fillRoundedRect(
const IntSize& bottomLeft, const IntSize& bottomRight,
const Color& color)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::FillRoundedRect(rect, topLeft,
- topRight, bottomLeft, bottomRight, color));
+ appendDrawingOperation(NEW_OP(FillRoundedRect)(rect, topLeft,
+ topRight, bottomLeft, bottomRight, color), rect);
}
void PlatformGraphicsContextRecording::strokeArc(const IntRect& r, int startAngle,
int angleSpan)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::StrokeArc(r, startAngle, angleSpan));
+ appendDrawingOperation(NEW_OP(StrokeArc)(r, startAngle, angleSpan), r);
}
void PlatformGraphicsContextRecording::strokePath(const Path& pathToStroke)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::StrokePath(pathToStroke));
+ appendDrawingOperation(NEW_OP(StrokePath)(pathToStroke), pathToStroke.boundingRect());
}
void PlatformGraphicsContextRecording::strokeRect(const FloatRect& rect, float lineWidth)
{
- mGraphicsOperationCollection->append(new GraphicsOperation::StrokeRect(rect, lineWidth));
+ FloatRect bounds = rect;
+ bounds.inflate(lineWidth);
+ appendDrawingOperation(NEW_OP(StrokeRect)(rect, lineWidth), bounds);
+}
+
+void PlatformGraphicsContextRecording::drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint)
+{
+ if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) {
+ ALOGE("Unsupported text encoding! %d", paint.getTextEncoding());
+ }
+ FloatRect bounds = approximateTextBounds(byteLength / sizeof(uint16_t), pos, paint);
+ appendDrawingOperation(NEW_OP(DrawPosText)(text, byteLength, pos, paint), bounds);
+}
+
+void PlatformGraphicsContextRecording::drawMediaButton(const IntRect& rect, RenderSkinMediaButton::MediaButton buttonType,
+ bool translucent, bool drawBackground,
+ const IntRect& thumb)
+{
+ appendDrawingOperation(NEW_OP(DrawMediaButton)(rect, buttonType,
+ translucent, drawBackground, thumb), rect);
+}
+
+void PlatformGraphicsContextRecording::clipState(const FloatRect& clip)
+{
+ if (mRecordingStateStack.size()) {
+ SkRect mapBounds;
+ mCurrentMatrix->mapRect(&mapBounds, clip);
+ mRecordingStateStack.last().clip(mapBounds);
+ }
+}
+
+void PlatformGraphicsContextRecording::pushStateOperation(CanvasState* canvasState)
+{
+ ALOGV("pushStateOperation: %p(isLayer=%d)", canvasState, canvasState->isTransparencyLayer());
+ mRecordingStateStack.append(canvasState);
+ mRecording->recording()->addCanvasState(canvasState);
+}
+
+void PlatformGraphicsContextRecording::popStateOperation()
+{
+ RecordingState state = mRecordingStateStack.last();
+ mRecordingStateStack.removeLast();
+ if (!state.mHasDrawing) {
+ ALOGV("popStateOperation is deleting %p(isLayer=%d)",
+ state.mCanvasState, state.mCanvasState->isTransparencyLayer());
+ mRecording->recording()->removeCanvasState(state.mCanvasState);
+ state.mCanvasState->~CanvasState();
+ canvasStateHeap()->rewindTo(state.mCanvasState);
+ } else {
+ ALOGV("popStateOperation: %p(isLayer=%d)",
+ state.mCanvasState, state.mCanvasState->isTransparencyLayer());
+ // Make sure we propagate drawing upwards so we don't delete our parent
+ mRecordingStateStack.last().mHasDrawing = true;
+ }
+}
+
+void PlatformGraphicsContextRecording::pushMatrix()
+{
+ mMatrixStack.append(mMatrixStack.last());
+ mCurrentMatrix = &(mMatrixStack.last());
+}
+
+void PlatformGraphicsContextRecording::popMatrix()
+{
+ mMatrixStack.removeLast();
+ mCurrentMatrix = &(mMatrixStack.last());
+}
+
+IntRect PlatformGraphicsContextRecording::calculateFinalBounds(FloatRect bounds)
+{
+ if (bounds.isEmpty() && mRecordingStateStack.last().mHasClip) {
+ ALOGV("Empty bounds, but has clip so using that");
+ return enclosingIntRect(mRecordingStateStack.last().mBounds);
+ }
+ if (m_gc->hasShadow()) {
+ const ShadowRec& shadow = m_state->shadow;
+ if (shadow.blur > 0)
+ bounds.inflate(ceilf(shadow.blur));
+ bounds.setWidth(bounds.width() + abs(shadow.dx));
+ bounds.setHeight(bounds.height() + abs(shadow.dy));
+ if (shadow.dx < 0)
+ bounds.move(shadow.dx, 0);
+ if (shadow.dy < 0)
+ bounds.move(0, shadow.dy);
+ // Add a bit extra to deal with rounding and blurring
+ bounds.inflate(4);
+ }
+ if (m_state->strokeStyle != NoStroke)
+ bounds.inflate(std::min(1.0f, m_state->strokeThickness));
+ SkRect translated;
+ mCurrentMatrix->mapRect(&translated, bounds);
+ FloatRect ftrect = translated;
+ if (mRecordingStateStack.last().mHasClip
+ && !translated.intersect(mRecordingStateStack.last().mBounds)) {
+ ALOGV("Operation bounds=" FLOAT_RECT_FORMAT " clipped out by clip=" FLOAT_RECT_FORMAT,
+ FLOAT_RECT_ARGS(ftrect), FLOAT_RECT_ARGS(mRecordingStateStack.last().mBounds));
+ return IntRect();
+ }
+ return enclosingIntRect(translated);
+}
+
+IntRect PlatformGraphicsContextRecording::calculateCoveredBounds(FloatRect bounds)
+{
+ SkRect translated;
+ mCurrentMatrix->mapRect(&translated, bounds);
+ FloatRect ftrect = translated;
+ if (mRecordingStateStack.last().mHasClip
+ && !translated.intersect(mRecordingStateStack.last().mBounds)) {
+ ALOGV("Operation opaque area=" FLOAT_RECT_FORMAT " clipped out by clip=" FLOAT_RECT_FORMAT,
+ FLOAT_RECT_ARGS(ftrect), FLOAT_RECT_ARGS(mRecordingStateStack.last().mBounds));
+ return IntRect();
+ }
+ return enclosedIntRect(translated);
+}
+
+void PlatformGraphicsContextRecording::appendDrawingOperation(
+ GraphicsOperation::Operation* operation, const FloatRect& untranslatedBounds)
+{
+ m_isEmpty = false;
+ RecordingState& state = mRecordingStateStack.last();
+ state.mHasDrawing = true;
+ if (!mOperationState)
+ mOperationState = mRecording->recording()->getState(m_state);
+ operation->m_state = mOperationState;
+ operation->m_canvasState = state.mCanvasState;
+
+ WebCore::IntRect ibounds = calculateFinalBounds(untranslatedBounds);
+ if (ibounds.isEmpty()) {
+ ALOGV("Operation %s() was clipped out", operation->name());
+ operation->~Operation();
+ operationHeap()->rewindTo(operation);
+ return;
+ }
+ if (operation->isOpaque()
+ && !untranslatedBounds.isEmpty()
+ && operation->m_state->alpha == 1.0f
+ && mCurrentMatrix->rectStaysRect()
+ && !state.mHasComplexClip) {
+ // if the operation maps to an opaque rect, record the area it will cover
+ operation->setOpaqueRect(calculateCoveredBounds(untranslatedBounds));
+ }
+ ALOGV("appendOperation %p->%s() bounds " INT_RECT_FORMAT, operation, operation->name(),
+ INT_RECT_ARGS(ibounds));
+ RecordingData* data = new RecordingData(operation, mRecording->recording()->m_nodeCount++);
+ mRecording->recording()->m_tree.insert(ibounds, data);
+}
+
+void PlatformGraphicsContextRecording::appendStateOperation(GraphicsOperation::Operation* operation)
+{
+ ALOGV("appendOperation %p->%s()", operation, operation->name());
+ RecordingData* data = new RecordingData(operation, mRecording->recording()->m_nodeCount++);
+ mRecordingStateStack.last().mCanvasState->adoptAndAppend(data);
}
+LinearAllocator* PlatformGraphicsContextRecording::operationHeap()
+{
+ return mRecording->recording()->operationHeap();
+}
+
+LinearAllocator* PlatformGraphicsContextRecording::canvasStateHeap()
+{
+ return mRecording->recording()->canvasStateHeap();
+}
} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
index ebb0075..0461749 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
@@ -28,21 +28,42 @@
#include "PlatformGraphicsContext.h"
+#include "RecordingContextCanvasProxy.h"
+#include "SkRefCnt.h"
+
namespace WebCore {
-class GraphicsOperationCollection;
+namespace GraphicsOperation {
+class Operation;
+}
+
+class CanvasState;
+class LinearAllocator;
+class RecordingImpl;
+class PlatformGraphicsContextSkia;
+class RecordingData;
+
+class Recording : public SkRefCnt {
+public:
+ Recording()
+ : m_recording(0)
+ {}
+ ~Recording();
+
+ void draw(SkCanvas* canvas);
+ void setRecording(RecordingImpl* impl);
+ RecordingImpl* recording() { return m_recording; }
+
+private:
+ RecordingImpl* m_recording;
+};
class PlatformGraphicsContextRecording : public PlatformGraphicsContext {
public:
- PlatformGraphicsContextRecording(GraphicsOperationCollection* picture);
+ PlatformGraphicsContextRecording(Recording* picture);
virtual ~PlatformGraphicsContextRecording() {}
virtual bool isPaintingDisabled();
- virtual SkCanvas* getCanvas() { return 0; }
-
- GraphicsOperationCollection* mGraphicsOperationCollection;
- SkMatrix mCurrentMatrix;
virtual SkCanvas* recordingCanvas();
- virtual void endRecording(int type = 0);
virtual ContextType type() { return RecordingContext; }
@@ -55,16 +76,16 @@ public:
// State values
virtual void setAlpha(float alpha);
virtual void setCompositeOperation(CompositeOperator op);
- virtual void setFillColor(const Color& c);
- virtual void setFillShader(SkShader* fillShader);
+ virtual bool setFillColor(const Color& c);
+ virtual bool setFillShader(SkShader* fillShader);
virtual void setLineCap(LineCap cap);
virtual void setLineDash(const DashArray& dashes, float dashOffset);
virtual void setLineJoin(LineJoin join);
virtual void setMiterLimit(float limit);
virtual void setShadow(int radius, int dx, int dy, SkColor c);
virtual void setShouldAntialias(bool useAA);
- virtual void setStrokeColor(const Color& c);
- virtual void setStrokeShader(SkShader* strokeShader);
+ virtual bool setStrokeColor(const Color& c);
+ virtual bool setStrokeShader(SkShader* strokeShader);
virtual void setStrokeStyle(StrokeStyle style);
virtual void setStrokeThickness(float f);
@@ -78,19 +99,20 @@ public:
// Clipping
virtual void addInnerRoundedRectClip(const IntRect& rect, int thickness);
virtual void canvasClip(const Path& path);
- virtual void clip(const FloatRect& rect);
- virtual void clip(const Path& path);
- virtual void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
- virtual void clipOut(const IntRect& r);
- virtual void clipOut(const Path& p);
- virtual void clipPath(const Path& pathToClip, WindRule clipRule);
+ virtual bool clip(const FloatRect& rect);
+ virtual bool clip(const Path& path);
+ virtual bool clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
+ virtual bool clipOut(const IntRect& r);
+ virtual bool clipOut(const Path& p);
+ virtual bool clipPath(const Path& pathToClip, WindRule clipRule);
+ virtual SkIRect getTotalClipBounds() { return enclosingIntRect(mRecordingStateStack.last().mBounds); }
// Drawing
virtual void clearRect(const FloatRect& rect);
virtual void drawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
CompositeOperator compositeOp, const FloatRect& destRect);
virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
- const SkRect& dst, CompositeOperator op);
+ const SkRect& dst, CompositeOperator op = CompositeSourceOver);
virtual void drawConvexPolygon(size_t numPoints, const FloatPoint* points,
bool shouldAntialias);
virtual void drawEllipse(const IntRect& rect);
@@ -103,7 +125,7 @@ public:
virtual void drawLine(const IntPoint& point1, const IntPoint& point2);
virtual void drawLineForText(const FloatPoint& pt, float width);
virtual void drawLineForTextChecking(const FloatPoint& pt, float width,
- GraphicsContext::TextCheckingLineStyle);
+ GraphicsContext::TextCheckingLineStyle);
virtual void drawRect(const IntRect& rect);
virtual void fillPath(const Path& pathToFill, WindRule fillRule);
virtual void fillRect(const FloatRect& rect);
@@ -115,13 +137,78 @@ public:
virtual void strokePath(const Path& pathToStroke);
virtual void strokeRect(const FloatRect& rect, float lineWidth);
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint);
+ virtual void drawMediaButton(const IntRect& rect, RenderSkinMediaButton::MediaButton buttonType,
+ bool translucent = false, bool drawBackground = true,
+ const IntRect& thumb = IntRect());
+
+ bool hasText() { return m_hasText; }
+ bool isEmpty() { return m_isEmpty; }
private:
virtual bool shadowsIgnoreTransforms() const {
return false;
}
+ void clipState(const FloatRect& clip);
+ void appendDrawingOperation(GraphicsOperation::Operation* operation, const FloatRect& bounds);
+ void appendStateOperation(GraphicsOperation::Operation* operation);
+ void pushStateOperation(CanvasState* canvasState);
+ void popStateOperation();
+ void pushMatrix();
+ void popMatrix();
+ IntRect calculateFinalBounds(FloatRect bounds);
+ IntRect calculateCoveredBounds(FloatRect bounds);
+ LinearAllocator* operationHeap();
+ LinearAllocator* canvasStateHeap();
+
SkPicture* mPicture;
+ SkMatrix* mCurrentMatrix;
+
+ Recording* mRecording;
+ class RecordingState {
+ public:
+ RecordingState(CanvasState* state)
+ : mCanvasState(state)
+ , mHasDrawing(false)
+ , mHasClip(false)
+ , mHasComplexClip(false)
+ {}
+
+ RecordingState(const RecordingState& other)
+ : mCanvasState(other.mCanvasState)
+ , mHasDrawing(other.mHasDrawing)
+ , mHasClip(other.mHasClip)
+ , mHasComplexClip(false)
+ , mBounds(other.mBounds)
+ {}
+
+ void setHasComplexClip() { mHasComplexClip = true; }
+
+ void clip(const FloatRect& rect)
+ {
+ if (mHasClip)
+ mBounds.intersect(rect);
+ else {
+ mBounds = rect;
+ mHasClip = true;
+ }
+ }
+
+ CanvasState* mCanvasState;
+ bool mHasDrawing;
+ bool mHasClip;
+ bool mHasComplexClip;
+ FloatRect mBounds;
+ };
+ Vector<RecordingState> mRecordingStateStack;
+ Vector<SkMatrix> mMatrixStack;
+ State* mOperationState;
+
+ bool m_hasText;
+ bool m_isEmpty;
+ RecordingContextCanvasProxy m_canvasProxy;
};
}
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp
index f00bb02..fcd9ade 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.cpp
@@ -174,43 +174,45 @@ void PlatformGraphicsContextSkia::canvasClip(const Path& path)
clip(path);
}
-void PlatformGraphicsContextSkia::clip(const FloatRect& rect)
+bool PlatformGraphicsContextSkia::clip(const FloatRect& rect)
{
- mCanvas->clipRect(rect);
+ return mCanvas->clipRect(rect);
}
-void PlatformGraphicsContextSkia::clip(const Path& path)
+bool PlatformGraphicsContextSkia::clip(const Path& path)
{
- mCanvas->clipPath(*path.platformPath(), SkRegion::kIntersect_Op, true);
+ return mCanvas->clipPath(*path.platformPath(), SkRegion::kIntersect_Op, true);
}
-void PlatformGraphicsContextSkia::clipConvexPolygon(size_t numPoints,
+bool PlatformGraphicsContextSkia::clipConvexPolygon(size_t numPoints,
const FloatPoint*, bool antialias)
{
if (numPoints <= 1)
- return;
+ return true;
// This is only used if HAVE_PATH_BASED_BORDER_RADIUS_DRAWING is defined
// in RenderObject.h which it isn't for us. TODO: Support that :)
+ return true;
}
-void PlatformGraphicsContextSkia::clipOut(const IntRect& r)
+bool PlatformGraphicsContextSkia::clipOut(const IntRect& r)
{
- mCanvas->clipRect(r, SkRegion::kDifference_Op);
+ return mCanvas->clipRect(r, SkRegion::kDifference_Op);
}
-void PlatformGraphicsContextSkia::clipOut(const Path& path)
+bool PlatformGraphicsContextSkia::clipOut(const Path& path)
{
- mCanvas->clipPath(*path.platformPath(), SkRegion::kDifference_Op);
+ return mCanvas->clipPath(*path.platformPath(), SkRegion::kDifference_Op);
}
-void PlatformGraphicsContextSkia::clipPath(const Path& pathToClip, WindRule clipRule)
+bool PlatformGraphicsContextSkia::clipPath(const Path& pathToClip, WindRule clipRule)
{
SkPath path = *pathToClip.platformPath();
path.setFillType(clipRule == RULE_EVENODD
? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
- mCanvas->clipPath(path);
+ return mCanvas->clipPath(path);
}
+
void PlatformGraphicsContextSkia::clearRect(const FloatRect& rect)
{
SkPaint paint;
@@ -605,4 +607,17 @@ void PlatformGraphicsContextSkia::strokeRect(const FloatRect& rect, float lineWi
mCanvas->drawRect(rect, paint);
}
+void PlatformGraphicsContextSkia::drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint)
+{
+ mCanvas->drawPosText(text, byteLength, pos, paint);
+}
+
+void PlatformGraphicsContextSkia::drawMediaButton(const IntRect& rect, RenderSkinMediaButton::MediaButton buttonType,
+ bool translucent, bool drawBackground,
+ const IntRect& thumb)
+{
+ RenderSkinMediaButton::Draw(mCanvas, rect, buttonType, translucent, drawBackground, thumb);
+}
+
} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h
index 724e20b..6bf53d7 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextSkia.h
@@ -35,11 +35,10 @@ public:
PlatformGraphicsContextSkia(SkCanvas* canvas, bool takeCanvasOwnership = false);
virtual ~PlatformGraphicsContextSkia();
virtual bool isPaintingDisabled();
- virtual SkCanvas* getCanvas() { return mCanvas; }
+ SkCanvas* canvas() { return mCanvas; }
virtual ContextType type() { return PaintingContext; }
virtual SkCanvas* recordingCanvas() { return mCanvas; }
- virtual void endRecording(int type = 0) {}
// FIXME: This is used by ImageBufferAndroid, which should really be
// managing the canvas lifecycle itself
@@ -62,19 +61,20 @@ public:
// Clipping
virtual void addInnerRoundedRectClip(const IntRect& rect, int thickness);
virtual void canvasClip(const Path& path);
- virtual void clip(const FloatRect& rect);
- virtual void clip(const Path& path);
- virtual void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
- virtual void clipOut(const IntRect& r);
- virtual void clipOut(const Path& p);
- virtual void clipPath(const Path& pathToClip, WindRule clipRule);
+ virtual bool clip(const FloatRect& rect);
+ virtual bool clip(const Path& path);
+ virtual bool clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
+ virtual bool clipOut(const IntRect& r);
+ virtual bool clipOut(const Path& p);
+ virtual bool clipPath(const Path& pathToClip, WindRule clipRule);
+ virtual SkIRect getTotalClipBounds() { return mCanvas->getTotalClip().getBounds(); }
// Drawing
virtual void clearRect(const FloatRect& rect);
virtual void drawBitmapPattern(const SkBitmap& bitmap, const SkMatrix& matrix,
CompositeOperator compositeOp, const FloatRect& destRect);
virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
- const SkRect& dst, CompositeOperator op);
+ const SkRect& dst, CompositeOperator op = CompositeSourceOver);
virtual void drawConvexPolygon(size_t numPoints, const FloatPoint* points,
bool shouldAntialias);
virtual void drawEllipse(const IntRect& rect);
@@ -87,7 +87,7 @@ public:
virtual void drawLine(const IntPoint& point1, const IntPoint& point2);
virtual void drawLineForText(const FloatPoint& pt, float width);
virtual void drawLineForTextChecking(const FloatPoint& pt, float width,
- GraphicsContext::TextCheckingLineStyle);
+ GraphicsContext::TextCheckingLineStyle);
virtual void drawRect(const IntRect& rect);
virtual void fillPath(const Path& pathToFill, WindRule fillRule);
virtual void fillRect(const FloatRect& rect);
@@ -98,6 +98,11 @@ public:
virtual void strokeArc(const IntRect& r, int startAngle, int angleSpan);
virtual void strokePath(const Path& pathToStroke);
virtual void strokeRect(const FloatRect& rect, float lineWidth);
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint);
+ virtual void drawMediaButton(const IntRect& rect, RenderSkinMediaButton::MediaButton buttonType,
+ bool translucent = false, bool drawBackground = true,
+ const IntRect& thumb = IntRect());
private:
diff --git a/Source/WebCore/platform/graphics/android/context/RTree.cpp b/Source/WebCore/platform/graphics/android/context/RTree.cpp
new file mode 100644
index 0000000..fa048b7
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/RTree.cpp
@@ -0,0 +1,589 @@
+/*
+ * Copyright 2012, 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.
+ */
+
+#define LOG_TAG "RTree"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+
+#include "RTree.h"
+
+#include "AndroidLog.h"
+#include "LinearAllocator.h"
+
+namespace RTree {
+
+#ifdef DEBUG
+static unsigned gID = 0;
+#endif
+
+class Element;
+
+//////////////////////////////////////////////////////////////////////
+// utility functions used by ElementList and Node
+
+static void recomputeBounds(int& minx, int& miny,
+ int& maxx, int& maxy,
+ unsigned& nbChildren,
+ Node**& children, int* area)
+{
+ // compute the bounds
+
+ if (nbChildren) {
+ minx = children[0]->m_minX;
+ miny = children[0]->m_minY;
+ maxx = children[0]->m_maxX;
+ maxy = children[0]->m_maxY;
+ }
+
+ for (unsigned int i = 1; i < nbChildren; i++)
+ {
+ minx = std::min(minx, children[i]->m_minX);
+ miny = std::min(miny, children[i]->m_minY);
+ maxx = std::max(maxx, children[i]->m_maxX);
+ maxy = std::max(maxy, children[i]->m_maxY);
+ }
+
+ if (area) {
+ int w = maxx - minx;
+ int h = maxy - miny;
+ *area = w * h;
+ }
+}
+
+int computeDeltaArea(Node* node, int& minx, int& miny,
+ int& maxx, int& maxy)
+{
+ int newMinX = std::min(minx, node->m_minX);
+ int newMinY = std::min(miny, node->m_minY);
+ int newMaxX = std::max(maxx, node->m_maxX);
+ int newMaxY = std::max(maxy, node->m_maxY);
+ int w = newMaxX - newMinX;
+ int h = newMaxY - newMinY;
+ return w * h;
+}
+
+//////////////////////////////////////////////////////////////////////
+// RTree
+//////////////////////////////////////////////////////////////////////
+//
+// This is an implementation of the R-Tree data structure
+// "R-Trees - a dynamic index structure for spatial searching", Guttman(84)
+//
+// The structure works as follow -- elements have bounds, intermediate
+// nodes will also maintain bounds (the union of their children' bounds).
+//
+// Searching is simple -- we just traverse the tree comparing the bounds
+// until we find the elements we are interested in.
+//
+// Each node can have at most M children -- the performances / memory usage
+// is strongly impacted by a choice of a good M value (RTree::m_maxChildren).
+//
+// Inserting an element
+// --------------------
+//
+// To find the leaf node N where we can insert a new element (RTree::insert(),
+// Node::insert()), we need to traverse the tree, picking the branch where
+// adding the new element will result in the least growth of its bounds,
+// until we reach a leaf node (Node::findNode()).
+//
+// If the number of children of that leaf node is under M, we simply
+// insert it. Otherwise, if we reached maximum capacity for that leaf,
+// we split the list of children (Node::split()), creating two lists,
+// where each list' elements is as far as each other as possible
+// (to decrease the likelyhood of future splits).
+//
+// We can then assign one of the list to the original leaf node N, and
+// we then create a new node NN that we try to attach to N's parent.
+//
+// If N's parent is also full, we go up in the hierachy and repeat
+// (Node::adjustTree()).
+//
+//////////////////////////////////////////////////////////////////////
+
+RTree::RTree(int M)
+{
+ m_maxChildren = M;
+ m_listA = new ElementList(M);
+ m_listB = new ElementList(M);
+ m_allocator = new WebCore::LinearAllocator(sizeof(Node));
+ m_root = Node::create(this);
+}
+
+RTree::~RTree()
+{
+ delete m_listA;
+ delete m_listB;
+ deleteNode(m_root);
+ delete m_allocator;
+}
+
+void RTree::insert(WebCore::IntRect& bounds, WebCore::RecordingData* payload)
+{
+ Node* e = Node::create(this, bounds.x(), bounds.y(),
+ bounds.maxX(), bounds.maxY(), payload);
+ m_root->insert(e);
+}
+
+void RTree::search(WebCore::IntRect& clip, Vector<WebCore::RecordingData*>&list)
+{
+ m_root->search(clip.x(), clip.y(), clip.maxX(), clip.maxY(), list);
+}
+
+void RTree::remove(WebCore::IntRect& clip)
+{
+ m_root->remove(clip.x(), clip.y(), clip.maxX(), clip.maxY());
+}
+
+void RTree::display()
+{
+#ifdef DEBUG
+ m_root->drawTree();
+#endif
+}
+
+void* RTree::allocateNode()
+{
+ return m_allocator->alloc(sizeof(Node));
+}
+
+void RTree::deleteNode(Node* n)
+{
+ if (n)
+ n->~Node();
+}
+
+//////////////////////////////////////////////////////////////////////
+// ElementList
+
+ElementList::ElementList(int size)
+ : m_nbChildren(0)
+ , m_minX(0)
+ , m_maxX(0)
+ , m_minY(0)
+ , m_maxY(0)
+ , m_area(0)
+ , m_didTighten(false)
+{
+ m_children = new Node*[size];
+}
+
+ElementList::~ElementList()
+{
+ delete[] m_children;
+}
+
+void ElementList::add(Node* node)
+{
+ m_children[m_nbChildren] = node;
+ m_nbChildren++;
+ m_didTighten = false;
+}
+
+void ElementList::tighten()
+{
+ if (m_didTighten)
+ return;
+ recomputeBounds(m_minX, m_minY, m_maxX, m_maxY,
+ m_nbChildren, m_children, &m_area);
+ m_didTighten = true;
+}
+
+int ElementList::delta(Node* node)
+{
+ if (!m_didTighten)
+ tighten();
+ return computeDeltaArea(node, m_minX, m_minY, m_maxX, m_maxY);
+}
+
+void ElementList::removeAll()
+{
+ m_nbChildren = 0;
+ m_minX = 0;
+ m_maxX = 0;
+ m_minY = 0;
+ m_maxY = 0;
+ m_area = 0;
+ m_didTighten = false;
+}
+
+void ElementList::display() {
+#ifdef DEBUG
+ for (unsigned int i = 0; i < m_nbChildren; i++)
+ m_children[i]->display(0);
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////
+// Node
+
+Node::Node(RTree* t, int minx, int miny, int maxx, int maxy, WebCore::RecordingData* payload)
+ : m_tree(t)
+ , m_parent(0)
+ , m_children(0)
+ , m_nbChildren(0)
+ , m_payload(payload)
+ , m_minX(minx)
+ , m_minY(miny)
+ , m_maxX(maxx)
+ , m_maxY(maxy)
+#ifdef DEBUG
+ , m_tid(gID++)
+#endif
+{
+#ifdef DEBUG
+ ALOGV("-> New Node %d", m_tid);
+#endif
+}
+
+Node::~Node()
+{
+ for (unsigned i = 0; i < m_nbChildren; i++)
+ m_tree->deleteNode(m_children[i]);
+ delete[] m_children;
+ delete m_payload;
+}
+
+void Node::setParent(Node* node)
+{
+ m_parent = node;
+}
+
+void Node::insert(Node* node)
+{
+ Node* N = findNode(node);
+#ifdef DEBUG
+ ALOGV("-> Insert Node %d (%d, %d) in node %d",
+ node->m_tid, node->m_minX, node->m_minY, N->m_tid);
+#endif
+ N->add(node);
+}
+
+Node* Node::findNode(Node* node)
+{
+ if (m_nbChildren == 0)
+ return m_parent ? m_parent : this;
+
+ // pick the child whose bounds will be extended least
+
+ Node* pick = m_children[0];
+ int minIncrease = pick->delta(node);
+ for (unsigned int i = 1; i < m_nbChildren; i++) {
+ int increase = m_children[i]->delta(node);
+ if (increase < minIncrease) {
+ minIncrease = increase;
+ pick = m_children[i];
+ }
+ }
+
+ return pick->findNode(node);
+}
+
+void Node::tighten()
+{
+ recomputeBounds(m_minX, m_minY, m_maxX, m_maxY,
+ m_nbChildren, m_children, 0);
+}
+
+int Node::delta(Node* node)
+{
+ return computeDeltaArea(node, m_minX, m_minY, m_maxX, m_maxY);
+}
+
+void Node::simpleAdd(Node* node)
+{
+ node->setParent(this);
+ if (!m_children)
+ m_children = new Node*[m_tree->m_maxChildren + 1];
+ m_children[m_nbChildren] = node;
+ m_nbChildren++;
+}
+
+void Node::add(Node* node)
+{
+ simpleAdd(node);
+ Node* NN = 0;
+ if (m_nbChildren > m_tree->m_maxChildren)
+ NN = split();
+
+ adjustTree(this, NN);
+}
+
+void Node::remove(Node* node)
+{
+ int nodeIndex = -1;
+ for (unsigned int i = 0; i < m_nbChildren; i++) {
+ if (m_children[i] == node) {
+ nodeIndex = i;
+ break;
+ }
+ }
+ if (nodeIndex == -1)
+ return;
+
+ // compact
+ for (unsigned int i = nodeIndex; i < m_nbChildren - 1; i++)
+ m_children[i] = m_children[i + 1];
+ m_nbChildren--;
+}
+
+void Node::destroy(int index)
+{
+ delete m_children[index];
+ // compact
+ for (unsigned int i = index; i < m_nbChildren - 1; i++)
+ m_children[i] = m_children[i + 1];
+ m_nbChildren--;
+}
+
+void Node::removeAll()
+{
+ m_nbChildren = 0;
+ m_minX = 0;
+ m_maxX = 0;
+ m_minY = 0;
+ m_maxY = 0;
+}
+
+Node* Node::split()
+{
+ // First, let's get the seeds
+ // The idea is to get elements as distant as possible
+ // as we can, so that the resulting splitted lists
+ // will be more likely to not overlap.
+ Node* minElementX = m_children[0];
+ Node* maxElementX = m_children[0];
+ Node* minElementY = m_children[0];
+ Node* maxElementY = m_children[0];
+ for (unsigned int i = 1; i < m_nbChildren; i++) {
+ if (m_children[i]->m_minX < minElementX->m_minX)
+ minElementX = m_children[i];
+ if (m_children[i]->m_minY < minElementY->m_minY)
+ minElementY = m_children[i];
+ if (m_children[i]->m_maxX >= maxElementX->m_maxX)
+ maxElementX = m_children[i];
+ if (m_children[i]->m_maxY >= maxElementY->m_maxY)
+ maxElementY = m_children[i];
+ }
+
+ int dx = maxElementX->m_maxX - minElementX->m_minX;
+ int dy = maxElementY->m_maxY - minElementY->m_minY;
+
+ // assign the two seeds...
+ Node* elementA = minElementX;
+ Node* elementB = maxElementX;
+
+ if (dx < dy) {
+ elementA = minElementY;
+ elementB = maxElementY;
+ }
+
+ // If we get the same element, just get the first and
+ // last element inserted...
+ if (elementA == elementB) {
+ elementA = m_children[0];
+ elementB = m_children[m_nbChildren - 1];
+ }
+
+#ifdef DEBUG
+ ALOGV("split Node %d, dx: %d dy: %d elem A is %d, elem B is %d",
+ m_tid, dx, dy, elementA->m_tid, elementB->m_tid);
+#endif
+
+ // Let's use some temporary lists to do the split
+ ElementList* listA = m_tree->m_listA;
+ ElementList* listB = m_tree->m_listB;
+ listA->removeAll();
+ listB->removeAll();
+
+ listA->add(elementA);
+ listB->add(elementB);
+
+ remove(elementA);
+ remove(elementB);
+
+ // For any remaining elements, insert it into the list
+ // resulting in the smallest growth
+ for (unsigned int i = 0; i < m_nbChildren; i++) {
+ Node* node = m_children[i];
+ int dA = listA->delta(node);
+ int dB = listB->delta(node);
+
+ if (dA < dB && listA->m_nbChildren < m_tree->m_maxChildren)
+ listA->add(node);
+ else if (dB < dA && listB->m_nbChildren < m_tree->m_maxChildren)
+ listB->add(node);
+ else {
+ ElementList* smallestList =
+ listA->m_nbChildren > listB->m_nbChildren ? listB : listA;
+ smallestList->add(node);
+ }
+ }
+
+ // Use the list to rebuild the nodes
+ removeAll();
+ for (unsigned int i = 0; i < listA->m_nbChildren; i++)
+ simpleAdd(listA->m_children[i]);
+
+ Node* NN = Node::create(m_tree);
+ for (unsigned int i = 0; i < listB->m_nbChildren; i++)
+ NN->simpleAdd(listB->m_children[i]);
+ NN->tighten();
+
+ return NN;
+}
+
+bool Node::isRoot()
+{
+ return m_tree->m_root == this;
+}
+
+void Node::adjustTree(Node* N, Node* NN)
+{
+ bool callParent = N->updateBounds();
+
+ if (N->isRoot() && NN) {
+ // build new root
+ Node* root = Node::create(m_tree);
+#ifdef DEBUG
+ ALOGV("-> node %d created as new root", root->m_tid);
+#endif
+ root->simpleAdd(N);
+ root->simpleAdd(NN);
+ root->tighten();
+ m_tree->m_root = root;
+ return;
+ }
+
+ if (N->isRoot())
+ return;
+
+ if (N->m_parent) {
+ if (NN)
+ N->m_parent->add(NN);
+ else if (callParent)
+ adjustTree(N->m_parent, 0);
+ }
+}
+
+bool Node::updateBounds()
+{
+ int ominx = m_minX;
+ int ominy = m_minY;
+ int omaxx = m_maxX;
+ int omaxy = m_maxY;
+ tighten();
+ if ((ominx != m_minX)
+ || (ominy != m_minY)
+ || (omaxx != m_maxX)
+ || (omaxy != m_maxY))
+ return true;
+ return false;
+}
+
+#ifdef DEBUG
+static int gMaxLevel = 0;
+static int gNbNodes = 0;
+static int gNbElements = 0;
+
+void Node::drawTree(int level)
+{
+ if (level == 0) {
+ ALOGV("\n*** show tree ***\n");
+ gMaxLevel = 0;
+ gNbNodes = 0;
+ gNbElements = 0;
+ }
+
+ display(level);
+ for (unsigned int i = 0; i < m_nbChildren; i++)
+ {
+ m_children[i]->drawTree(level + 1);
+ }
+
+ if (gMaxLevel < level)
+ gMaxLevel = level;
+
+ if (!m_nbChildren)
+ gNbElements++;
+ else
+ gNbNodes++;
+
+ if (level == 0) {
+ ALOGV("********************\n");
+ ALOGV("Depth level %d, total bytes: %d, %d nodes, %d bytes (%d bytes/node), %d elements, %d bytes (%d bytes/node)",
+ gMaxLevel, gNbNodes * sizeof(Node) + gNbElements * sizeof(Element),
+ gNbNodes, gNbNodes * sizeof(Node), sizeof(Node),
+ gNbElements, gNbElements * sizeof(Element), sizeof(Element));
+ }
+}
+#endif
+
+#ifdef DEBUG
+void Node::display(int level)
+{
+ ALOGV("%*sNode %d - %d, %d, %d, %d (%d x %d)",
+ 2*level, "", m_tid, m_minX, m_minY, m_maxX, m_maxY, m_maxX - m_minX, m_maxY - m_minY);
+}
+#endif
+
+bool Node::overlap(int minx, int miny, int maxx, int maxy)
+{
+ return ! (minx > m_maxX
+ || maxx < m_minX
+ || maxy < m_minY
+ || miny > m_maxY);
+}
+
+void Node::search(int minx, int miny, int maxx, int maxy, Vector<WebCore::RecordingData*>& list)
+{
+ if (isElement() && overlap(minx, miny, maxx, maxy))
+ list.append(this->m_payload);
+
+ for (unsigned int i = 0; i < m_nbChildren; i++) {
+ if (m_children[i]->overlap(minx, miny, maxx, maxy))
+ m_children[i]->search(minx, miny, maxx, maxy, list);
+ }
+}
+
+bool Node::inside(int minx, int miny, int maxx, int maxy)
+{
+ return (minx <= m_minX
+ && maxx >= m_maxX
+ && miny <= m_minY
+ && maxy >= m_maxY);
+}
+
+void Node::remove(int minx, int miny, int maxx, int maxy)
+{
+ for (unsigned int i = 0; i < m_nbChildren; i++) {
+ if (m_children[i]->inside(minx, miny, maxx, maxy))
+ destroy(i);
+ else if (m_children[i]->overlap(minx, miny, maxx, maxy))
+ m_children[i]->remove(minx, miny, maxx, maxy);
+ }
+}
+
+} // Namespace RTree
diff --git a/Source/WebCore/platform/graphics/android/context/RTree.h b/Source/WebCore/platform/graphics/android/context/RTree.h
new file mode 100644
index 0000000..366e3d1
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/RTree.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2012, 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.
+ */
+
+#ifndef RTree_h
+#define RTree_h
+
+#include <Vector.h>
+#include "IntRect.h"
+#include "GraphicsOperation.h"
+
+namespace WebCore {
+
+class LinearAllocator;
+
+class RecordingData {
+public:
+ RecordingData(GraphicsOperation::Operation* ops, size_t orderBy)
+ : m_orderBy(orderBy)
+ , m_operation(ops)
+ {}
+ ~RecordingData() {
+ m_operation->~Operation();
+ }
+
+ size_t m_orderBy;
+ GraphicsOperation::Operation* m_operation;
+};
+
+} // namespace WebCore
+
+namespace RTree {
+
+class ElementList;
+class Node;
+
+class RTree {
+public:
+ // M -- max number of children per node
+ RTree(int M = 10);
+ ~RTree();
+
+ void insert(WebCore::IntRect& bounds, WebCore::RecordingData* payload);
+ // Does an overlap search
+ void search(WebCore::IntRect& clip, Vector<WebCore::RecordingData*>& list);
+ // Does an inclusive remove -- all elements fully inside the clip will
+ // be removed from the tree
+ void remove(WebCore::IntRect& clip);
+ void display();
+
+ void* allocateNode();
+ void deleteNode(Node* n);
+
+private:
+
+ Node* m_root;
+ unsigned m_maxChildren;
+ ElementList* m_listA;
+ ElementList* m_listB;
+ WebCore::LinearAllocator* m_allocator;
+
+ friend class Node;
+};
+
+class ElementList {
+public:
+
+ ElementList(int size);
+ ~ElementList();
+ void add(Node* n);
+ void tighten();
+ int delta(Node* n);
+ void removeAll();
+ void display();
+
+ Node** m_children;
+ unsigned m_nbChildren;
+
+private:
+
+ int m_minX;
+ int m_maxX;
+ int m_minY;
+ int m_maxY;
+ int m_area;
+ bool m_didTighten;
+};
+
+class Node {
+public:
+ static Node* gRoot;
+
+ static Node* create(RTree* tree) {
+ return create(tree, 0, 0, 0, 0, 0);
+ }
+
+ static Node* create(RTree* tree, int minx, int miny, int maxx, int maxy,
+ WebCore::RecordingData* payload) {
+ return new (tree->allocateNode()) Node(tree, minx, miny, maxx, maxy, payload);
+ }
+
+ ~Node();
+
+ void insert(Node* n);
+ void search(int minx, int miny, int maxx, int maxy, Vector<WebCore::RecordingData*>& list);
+ void remove(int minx, int miny, int maxx, int maxy);
+
+ // Intentionally not implemented as Node* is custom allocated, we don't want to use this
+ void operator delete(void*);
+
+private:
+ Node(RTree* tree, int minx, int miny, int maxx, int maxy, WebCore::RecordingData* payload);
+
+ void setParent(Node* n);
+ Node* findNode(Node* n);
+ void simpleAdd(Node* n);
+ void add(Node* n);
+ void remove(Node* n);
+ void destroy(int index);
+ void removeAll();
+ Node* split();
+ void adjustTree(Node* N, Node* NN);
+ void tighten();
+ bool updateBounds();
+ int delta(Node* n);
+
+ bool overlap(int minx, int miny, int maxx, int maxy);
+ bool inside(int minx, int miny, int maxx, int maxy);
+
+ bool isElement() { return m_payload; }
+ bool isRoot();
+
+private:
+
+ RTree* m_tree;
+ Node* m_parent;
+
+ Node** m_children;
+ unsigned m_nbChildren;
+
+ WebCore::RecordingData* m_payload;
+
+public:
+
+ int m_minX;
+ int m_minY;
+ int m_maxX;
+ int m_maxY;
+
+#ifdef DEBUG
+ void drawTree(int level = 0);
+ void display(int level = 0);
+ unsigned m_tid;
+#endif
+};
+
+} // namespace RTree
+
+#endif // RTree_h
diff --git a/Source/WebCore/platform/android/GeolocationServiceBridge.h b/Source/WebCore/platform/graphics/android/context/RecordingContextCanvasProxy.cpp
index 3997d65..838e450 100644
--- a/Source/WebCore/platform/android/GeolocationServiceBridge.h
+++ b/Source/WebCore/platform/graphics/android/context/RecordingContextCanvasProxy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2009, The Android Open Source Project
+ * Copyright 2012, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,44 +23,46 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef GeolocationServiceBridge_h
-#define GeolocationServiceBridge_h
+#include "config.h"
+#include "RecordingContextCanvasProxy.h"
-#include "JNIUtility.h"
-#include <wtf/PassRefPtr.h>
+#include "PlatformGraphicsContextRecording.h"
namespace WebCore {
-class Frame;
-class GeolocationServiceAndroid;
-class Geoposition;
+// Return value is unused by FontAndroid
+int RecordingContextCanvasProxy::save(SaveFlags)
+{
+ m_pgc->save();
+ return -1;
+}
-// GeolocationServiceBridge is the bridge to the Java implementation. It manages
-// the lifetime of the Java object. It is an implementation detail of
-// GeolocationServiceAndroid.
-class GeolocationServiceBridge {
-public:
- typedef GeolocationServiceAndroid ListenerInterface;
- GeolocationServiceBridge(ListenerInterface* listener, Frame* frame);
- ~GeolocationServiceBridge();
+void RecordingContextCanvasProxy::restore()
+{
+ m_pgc->restore();
+}
- bool start();
- void stop();
- void setEnableGps(bool enable);
+void RecordingContextCanvasProxy::drawPosText(const void* text,
+ size_t byteLength,
+ const SkPoint pos[],
+ const SkPaint& paint)
+{
+ m_pgc->drawPosText(text, byteLength, pos, paint);
+}
- // Static wrapper functions to hide JNI nastiness.
- static void newLocationAvailable(JNIEnv *env, jclass, jlong nativeObject, jobject location);
- static void newErrorAvailable(JNIEnv *env, jclass, jlong nativeObject, jstring message);
- static PassRefPtr<Geoposition> toGeoposition(JNIEnv *env, const jobject &location);
+void RecordingContextCanvasProxy::drawBitmapRect(const SkBitmap& bitmap,
+ const SkIRect* src,
+ const SkRect& dst,
+ const SkPaint*)
+{
+ m_pgc->drawBitmapRect(bitmap, src, dst);
+}
-private:
- void startJavaImplementation(Frame* frame);
- void stopJavaImplementation();
+// Return value is unused by FontAndroid
+bool RecordingContextCanvasProxy::rotate(SkScalar degrees)
+{
+ m_pgc->rotate(degrees / (180.0f / 3.14159265f));
+ return true;
+}
- ListenerInterface* m_listener;
- jobject m_javaGeolocationServiceObject;
-};
-
-} // namespace WebCore
-
-#endif // GeolocationServiceBridge_h
+} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/RecordingContextCanvasProxy.h b/Source/WebCore/platform/graphics/android/context/RecordingContextCanvasProxy.h
new file mode 100644
index 0000000..4daf5e7
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/RecordingContextCanvasProxy.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2012, 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.
+ */
+
+#ifndef RecordingContextCanvasProxy_h
+#define RecordingContextCanvasProxy_h
+
+#include "SkCanvas.h"
+
+namespace WebCore {
+
+class PlatformGraphicsContextRecording;
+
+class RecordingContextCanvasProxy : public SkCanvas {
+public:
+ RecordingContextCanvasProxy(PlatformGraphicsContextRecording* pgc)
+ : m_pgc(pgc)
+ {}
+
+ // Used by FontAndroid
+
+ // Return value is unused by FontAndroid
+ virtual int save(SaveFlags);
+ virtual void restore();
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint);
+ virtual bool rotate(SkScalar degrees);
+
+ // Used by EmojiFont
+
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, const SkPaint*);
+
+ // These aren't used by anyone
+
+ virtual int saveLayer(const SkRect* bounds, const SkPaint*, SaveFlags) { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+ virtual bool translate(SkScalar dx, SkScalar dy) { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+ virtual bool scale(SkScalar sx, SkScalar sy) { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+ virtual bool skew(SkScalar sx, SkScalar sy) { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+ virtual bool concat(const SkMatrix& matrix) { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+ virtual void setMatrix(const SkMatrix& matrix) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual bool clipRect(const SkRect&, SkRegion::Op, bool) { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+ virtual bool clipPath(const SkPath&, SkRegion::Op, bool) { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+ virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+ virtual void clear(SkColor) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawPaint(const SkPaint& paint) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
+ const SkPaint&) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawRect(const SkRect& rect, const SkPaint&) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawPath(const SkPath& path, const SkPaint&) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
+ const SkPaint*) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
+ const SkPaint*) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, const SkPaint*) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawSprite(const SkBitmap&, int left, int top,
+ const SkPaint*) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawText(const void* text, size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint&) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawPosTextH(const void* text, size_t byteLength,
+ const SkScalar xpos[], SkScalar constY, const SkPaint&) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint&) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawPicture(SkPicture& picture) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawVertices(VertexMode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode*,
+ const uint16_t indices[], int indexCount,
+ const SkPaint&) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual void drawData(const void*, size_t) { /* NOT IMPLEMENTED*/ CRASH(); }
+ virtual bool isDrawingToLayer() const { /* NOT IMPLEMENTED*/ CRASH(); return -1; }
+
+private:
+ PlatformGraphicsContextRecording* m_pgc;
+};
+
+} // namespace WebCore
+
+#endif // RecordingContextCanvasProxy_h
diff --git a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp
index 7bed5bb..fcb78ed 100644
--- a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp
@@ -26,8 +26,10 @@
#include "config.h"
+#define LOG_TAG "FontAndroid"
+
+#include "AndroidLog.h"
#include "EmojiFont.h"
-#include "GraphicsOperationCollection.h"
#include "GraphicsOperation.h"
#include "Font.h"
#include "FontData.h"
@@ -45,6 +47,7 @@
#include "SkTypeface.h"
#include "SkUtils.h"
#include "TextRun.h"
+#include "SkTypeface_android.h"
#ifdef SUPPORT_COMPLEX_SCRIPTS
#include "HarfbuzzSkia.h"
@@ -191,6 +194,12 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
// compile-time assert
SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t));
+ if (numGlyphs == 1 && glyphBuffer.glyphAt(from) == 0x3) {
+ // Webkit likes to draw end text control command for some reason
+ // Just ignore it
+ return;
+ }
+
SkPaint paint;
if (!setupForText(&paint, gc, font)) {
return;
@@ -220,10 +229,11 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
int localCount = 0;
for (int i = 0; i < numGlyphs; i++) {
if (EmojiFont::IsEmojiGlyph(glyphs[i])) {
- if (localCount)
+ if (localCount) {
canvas->drawPosText(&glyphs[localIndex],
- localCount * sizeof(uint16_t),
- &pos[localIndex], paint);
+ localCount * sizeof(uint16_t),
+ &pos[localIndex], paint);
+ }
EmojiFont::Draw(canvas, glyphs[i], x, y, paint);
// reset local index/count track for "real" glyphs
localCount = 0;
@@ -236,10 +246,11 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
y += SkFloatToScalar(adv[i].height());
}
// draw the last run of glyphs (if any)
- if (localCount)
+ if (localCount) {
canvas->drawPosText(&glyphs[localIndex],
- localCount * sizeof(uint16_t),
- &pos[localIndex], paint);
+ localCount * sizeof(uint16_t),
+ &pos[localIndex], paint);
+ }
} else {
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
@@ -255,13 +266,12 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
rotator.setRotate(90);
rotator.mapPoints(pos, numGlyphs);
}
-
- canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
+ canvas->drawPosText(glyphs,
+ numGlyphs * sizeof(uint16_t), pos, paint);
if (font->platformData().orientation() == Vertical)
canvas->restore();
}
- gc->platformContext()->endRecording();
}
void Font::drawEmphasisMarksForComplexText(WebCore::GraphicsContext*, WebCore::TextRun const&, WTF::AtomicString const&, WebCore::FloatPoint const&, int, int) const
@@ -461,26 +471,8 @@ public:
}
private:
- enum CustomScript {
- Bengali,
- Devanagari,
- Hebrew,
- HebrewBold,
- Kannada,
- Malayalam,
- Naskh,
- Tamil,
- TamilBold,
- Telugu,
- Thai,
- NUM_SCRIPTS
- };
-
- static const char* paths[NUM_SCRIPTS];
-
void setupFontForScriptRun();
- const FontPlatformData* setupComplexFont(CustomScript script,
- const FontPlatformData& platformData);
+ const FontPlatformData* setupComplexFont(HB_Script script, const FontPlatformData& platformData);
HB_FontRec* allocHarfbuzzFont();
void deleteGlyphArrays();
void createGlyphArrays(int);
@@ -522,22 +514,6 @@ private:
unsigned m_letterSpacing; // pixels to be added after each glyph.
};
-
-// Indexed using enum CustomScript
-const char* TextRunWalker::paths[] = {
- "/system/fonts/Lohit-Bengali.ttf",
- "/system/fonts/DroidSansDevanagari-Regular.ttf",
- "/system/fonts/DroidSansHebrew-Regular.ttf",
- "/system/fonts/DroidSansHebrew-Bold.ttf",
- "/system/fonts/Lohit-Kannada.ttf",
- "/system/fonts/AnjaliNewLipi-light.ttf",
- "/system/fonts/DroidNaskh-Regular.ttf",
- "/system/fonts/DroidSansTamil-Regular.ttf",
- "/system/fonts/DroidSansTamil-Bold.ttf",
- "/system/fonts/Lohit-Telugu.ttf",
- "/system/fonts/DroidSansThai.ttf"
-};
-
TextRunWalker::TextRunWalker(const TextRun& run, int startingX, int startingY, const Font* font)
: m_font(font)
, m_startingX(startingX)
@@ -692,8 +668,7 @@ void TextRunWalker::setWordAndLetterSpacing(int wordSpacingAdjustment,
}
const FontPlatformData* TextRunWalker::setupComplexFont(
- CustomScript script,
- const FontPlatformData& platformData)
+ HB_Script script, const FontPlatformData& platformData)
{
static FallbackHash fallbackPlatformData;
@@ -703,15 +678,19 @@ const FontPlatformData* TextRunWalker::setupComplexFont(
// italic, then bold italic. additional fake style bits can be added.
int scriptStyleIndex = script;
if (platformData.isFakeBold())
- scriptStyleIndex += NUM_SCRIPTS;
+ scriptStyleIndex += HB_ScriptCount;
if (platformData.isFakeItalic())
- scriptStyleIndex += NUM_SCRIPTS << 1;
+ scriptStyleIndex += HB_ScriptCount << 1;
FallbackFontKey key(scriptStyleIndex, platformData.size());
FontPlatformData* newPlatformData = 0;
if (!fallbackPlatformData.contains(key)) {
- SkTypeface* typeface = SkTypeface::CreateFromFile(paths[script]);
+ SkTypeface::Style currentStyle = SkTypeface::kNormal;
+ if (platformData.typeface())
+ currentStyle = platformData.typeface()->style();
+ SkTypeface* typeface = SkCreateTypefaceForScript(script, currentStyle,
+ SkPaint::kElegant_Variant);
newPlatformData = new FontPlatformData(platformData, typeface);
SkSafeUnref(typeface);
fallbackPlatformData.set(key, newPlatformData);
@@ -729,61 +708,8 @@ void TextRunWalker::setupFontForScriptRun()
const FontData* fontData = m_font->glyphDataForCharacter(m_run[0], false).fontData;
const FontPlatformData& platformData =
fontData->fontDataForCharacter(' ')->platformData();
- const FontPlatformData* complexPlatformData = &platformData;
-
- switch (m_item.item.script) {
- case HB_Script_Bengali:
- complexPlatformData = setupComplexFont(Bengali, platformData);
- break;
- case HB_Script_Devanagari:
- complexPlatformData = setupComplexFont(Devanagari, platformData);
- break;
- case HB_Script_Hebrew:
- switch (platformData.typeface()->style()) {
- case SkTypeface::kBold:
- case SkTypeface::kBoldItalic:
- complexPlatformData = setupComplexFont(HebrewBold, platformData);
- break;
- case SkTypeface::kNormal:
- case SkTypeface::kItalic:
- default:
- complexPlatformData = setupComplexFont(Hebrew, platformData);
- break;
- }
- break;
- case HB_Script_Kannada:
- complexPlatformData = setupComplexFont(Kannada, platformData);
- break;
- case HB_Script_Malayalam:
- complexPlatformData = setupComplexFont(Malayalam, platformData);
- break;
- case HB_Script_Arabic:
- complexPlatformData = setupComplexFont(Naskh, platformData);
- break;
- case HB_Script_Tamil:
- switch (platformData.typeface()->style()) {
- case SkTypeface::kBold:
- case SkTypeface::kBoldItalic:
- complexPlatformData = setupComplexFont(TamilBold, platformData);
- break;
- case SkTypeface::kNormal:
- case SkTypeface::kItalic:
- default:
- complexPlatformData = setupComplexFont(Tamil, platformData);
- break;
- }
- break;
- case HB_Script_Telugu:
- complexPlatformData = setupComplexFont(Telugu, platformData);
- break;
- case HB_Script_Thai:
- complexPlatformData = setupComplexFont(Thai, platformData);
- break;
- default:
- // HB_Script_Common; includes Ethiopic
- complexPlatformData = &platformData;
- break;
- }
+ const FontPlatformData* complexPlatformData = setupComplexFont(m_item.item.script, platformData);
+
m_item.face = complexPlatformData->harfbuzzFace();
m_item.font->userData = const_cast<FontPlatformData*>(complexPlatformData);
@@ -1113,18 +1039,17 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
if (fill) {
walker.fontPlatformDataForScriptRun()->setupPaint(&fillPaint);
adjustTextRenderMode(&fillPaint, haveMultipleLayers);
- canvas->drawPosText(walker.glyphs(), walker.length() << 1,
- walker.positions(), fillPaint);
+ canvas->drawPosText(walker.glyphs(),
+ walker.length() << 1, walker.positions(), fillPaint);
}
if (stroke) {
walker.fontPlatformDataForScriptRun()->setupPaint(&strokePaint);
adjustTextRenderMode(&strokePaint, haveMultipleLayers);
- canvas->drawPosText(walker.glyphs(), walker.length() << 1,
- walker.positions(), strokePaint);
+ canvas->drawPosText(walker.glyphs(),
+ walker.length() << 1, walker.positions(), strokePaint);
}
}
- gc->platformContext()->endRecording();
}
float Font::floatWidthForComplexText(const TextRun& run,
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp b/Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp
index e4b2bc6..aacb0bc 100644
--- a/Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasTexture.cpp
@@ -31,7 +31,6 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "android_graphics.h"
#include "AndroidLog.h"
#include "GLUtils.h"
#include "Image.h"
@@ -134,10 +133,10 @@ bool CanvasTexture::uploadImageBuffer(ImageBuffer* imageBuffer)
// Size mismatch, early abort (will fall back to software)
if (imageBuffer->size() != m_size)
return false;
- GraphicsContext* gc = imageBuffer ? imageBuffer->context() : 0;
- if (!gc)
+ SkCanvas* canvas = imageBufferCanvas(imageBuffer);
+ if (!canvas)
return false;
- const SkBitmap& bitmap = android_gc2canvas(gc)->getDevice()->accessBitmap(false);
+ const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
if (!GLUtils::updateSharedSurfaceTextureWithBitmap(anw, bitmap))
return false;
m_hasValidTexture = true;
diff --git a/Source/WebCore/platform/graphics/android/layers/DumpLayer.cpp b/Source/WebCore/platform/graphics/android/layers/DumpLayer.cpp
index 5551965..d827c44 100644
--- a/Source/WebCore/platform/graphics/android/layers/DumpLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/DumpLayer.cpp
@@ -3,79 +3,87 @@
#if USE(ACCELERATED_COMPOSITING)
+#define WRITE_VAL(format, ...) (snprintf(m_valueBuffer, BUF_SIZE, format, __VA_ARGS__), writeEntry(label, m_valueBuffer))
+
namespace WebCore {
-void lwrite(FILE* file, const char* str)
+void LayerDumper::writeIntVal(const char* label, int value)
{
- fwrite(str, sizeof(char), strlen(str), file);
+ WRITE_VAL("%d", value);
}
-void writeIndent(FILE* file, int indentLevel)
+void LayerDumper::writeHexVal(const char* label, int value)
{
- if (indentLevel)
- fprintf(file, "%*s", indentLevel*2, " ");
+ WRITE_VAL("%x", value);
}
-void writeln(FILE* file, int indentLevel, const char* str)
+void LayerDumper::writeFloatVal(const char* label, float value)
{
- writeIndent(file, indentLevel);
- lwrite(file, str);
- lwrite(file, "\n");
+ WRITE_VAL("%.3f", value);
}
-void writeIntVal(FILE* file, int indentLevel, const char* str, int value)
+void LayerDumper::writePoint(const char* label, SkPoint point)
{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = %d;\n", str, value);
+ WRITE_VAL("{ x = %.3f; y = %.3f; }", point.fX, point.fY);
}
-void writeHexVal(FILE* file, int indentLevel, const char* str, int value)
+void LayerDumper::writeIntPoint(const char* label, IntPoint point)
{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = %x;\n", str, value);
+ WRITE_VAL("{ x = %d; y = %d; }", point.x(), point.y());
}
-void writeFloatVal(FILE* file, int indentLevel, const char* str, float value)
+void LayerDumper::writeSize(const char* label, SkSize size)
{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = %.3f;\n", str, value);
+ WRITE_VAL("{ w = %.3f; h = %.3f; }", size.width(), size.height());
}
-void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point)
+void LayerDumper::writeRect(const char* label, SkRect rect)
{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { x = %.3f; y = %.3f; };\n", str, point.fX, point.fY);
+ WRITE_VAL("{ x = %.3f; y = %.3f; w = %.3f; h = %.3f; }",
+ rect.fLeft, rect.fTop, rect.width(), rect.height());
}
-void writeIntPoint(FILE* file, int indentLevel, const char* str, IntPoint point)
+void LayerDumper::writeMatrix(const char* label, const TransformationMatrix& matrix)
{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { x = %d; y = %d; };\n", str, point.x(), point.y());
+ WRITE_VAL("{ (%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f),"
+ "(%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f) }",
+ matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(),
+ matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(),
+ matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(),
+ matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44());
}
-void writeSize(FILE* file, int indentLevel, const char* str, SkSize size)
+void LayerDumper::writeLength(const char* label, SkLength value)
{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { w = %.3f; h = %.3f; };\n", str, size.width(), size.height());
+ if (value.defined())
+ WRITE_VAL("{ type = %d; value = %.2f; }", value.type, value.value);
+ else
+ writeEntry(label, "<undefined>");
}
-void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect)
+void FileLayerDumper::beginLayer(const char* className, const LayerAndroid* layerPtr)
{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { x = %.3f; y = %.3f; w = %.3f; h = %.3f; };\n",
- str, rect.fLeft, rect.fTop, rect.width(), rect.height());
+ LayerDumper::beginLayer(className, layerPtr);
+ writeLine("{");
+ writeHexVal("layer", (int)layerPtr);
}
-void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix)
+void FileLayerDumper::endLayer()
{
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { (%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f),"
- "(%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f) };\n",
- str,
- matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(),
- matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(),
- matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(),
- matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44());
+ writeLine("}");
+ LayerDumper::endLayer();
+}
+
+void FileLayerDumper::writeEntry(const char* label, const char* value)
+{
+ fprintf(m_file, "%*s%s = %s\n", (m_indentLevel + 1) * 2, " ", label, value);
+}
+
+void FileLayerDumper::writeLine(const char* str)
+{
+ if (m_indentLevel)
+ fprintf(m_file, "%*s", m_indentLevel * 2, " ");
+ fprintf(m_file, "%s\n", str);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/layers/DumpLayer.h b/Source/WebCore/platform/graphics/android/layers/DumpLayer.h
index 5b30952..9fd3365 100644
--- a/Source/WebCore/platform/graphics/android/layers/DumpLayer.h
+++ b/Source/WebCore/platform/graphics/android/layers/DumpLayer.h
@@ -17,7 +17,9 @@
#ifndef DumpLayer_h
#define DumpLayer_h
+#include "FixedPositioning.h"
#include "IntPoint.h"
+#include "LayerAndroid.h"
#include "SkPoint.h"
#include "SkRect.h"
#include "SkSize.h"
@@ -50,17 +52,59 @@
namespace WebCore {
-void lwrite(FILE* file, const char* str);
-void writeIndent(FILE* file, int indentLevel);
-void writeln(FILE* file, int indentLevel, const char* str);
-void writeIntVal(FILE* file, int indentLevel, const char* str, int value);
-void writeHexVal(FILE* file, int indentLevel, const char* str, int value);
-void writeFloatVal(FILE* file, int indentLevel, const char* str, float value);
-void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point);
-void writeIntPoint(FILE* file, int indentLevel, const char* str, IntPoint point);
-void writeSize(FILE* file, int indentLevel, const char* str, SkSize size);
-void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect);
-void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix);
+class LayerDumper {
+public:
+ LayerDumper(int initialIndentLevel = 0)
+ : m_indentLevel(initialIndentLevel)
+ {}
+ virtual ~LayerDumper() {}
+
+ virtual void beginLayer(const char* className, const LayerAndroid* layerPtr) {}
+
+ virtual void endLayer() {}
+
+ virtual void beginChildren(int childCount) {
+ m_indentLevel++;
+ }
+ virtual void endChildren() {
+ m_indentLevel--;
+ }
+
+ void writeIntVal(const char* label, int value);
+ void writeHexVal(const char* label, int value);
+ void writeFloatVal(const char* label, float value);
+ void writePoint(const char* label, SkPoint value);
+ void writeIntPoint(const char* label, IntPoint value);
+ void writeSize(const char* label, SkSize value);
+ void writeRect(const char* label, SkRect value);
+ void writeMatrix(const char* label, const TransformationMatrix& value);
+ void writeLength(const char* label, SkLength value);
+
+protected:
+ virtual void writeEntry(const char* label, const char* value) = 0;
+
+ int m_indentLevel;
+
+private:
+ static const int BUF_SIZE = 4096;
+ char m_valueBuffer[BUF_SIZE];
+};
+
+class FileLayerDumper : public LayerDumper {
+public:
+ FileLayerDumper(FILE* file)
+ : m_file(file)
+ {}
+
+ virtual void beginLayer(const char* className, const LayerAndroid* layerPtr);
+ virtual void endLayer();
+protected:
+ virtual void writeEntry(const char* label, const char* value);
+
+private:
+ void writeLine(const char* str);
+ FILE* m_file;
+};
}
diff --git a/Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp
index 82afe8f..aa204f8 100644
--- a/Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp
@@ -86,25 +86,17 @@ void FixedPositioning::contentDraw(SkCanvas* canvas, Layer::PaintStyle style)
}
}
-void writeLength(FILE* file, int indentLevel, const char* str, SkLength length)
+void FixedPositioning::dumpLayer(LayerDumper* dumper) const
{
- if (!length.defined())
- return;
- writeIndent(file, indentLevel);
- fprintf(file, "%s = { type = %d; value = %.2f; };\n", str, length.type, length.value);
-}
-
-void FixedPositioning::dumpLayer(FILE* file, int indentLevel) const
-{
- writeLength(file, indentLevel + 1, "fixedLeft", m_fixedLeft);
- writeLength(file, indentLevel + 1, "fixedTop", m_fixedTop);
- writeLength(file, indentLevel + 1, "fixedRight", m_fixedRight);
- writeLength(file, indentLevel + 1, "fixedBottom", m_fixedBottom);
- writeLength(file, indentLevel + 1, "fixedMarginLeft", m_fixedMarginLeft);
- writeLength(file, indentLevel + 1, "fixedMarginTop", m_fixedMarginTop);
- writeLength(file, indentLevel + 1, "fixedMarginRight", m_fixedMarginRight);
- writeLength(file, indentLevel + 1, "fixedMarginBottom", m_fixedMarginBottom);
- writeRect(file, indentLevel + 1, "fixedRect", m_fixedRect);
+ dumper->writeLength("fixedLeft", m_fixedLeft);
+ dumper->writeLength("fixedTop", m_fixedTop);
+ dumper->writeLength("fixedRight", m_fixedRight);
+ dumper->writeLength("fixedBottom", m_fixedBottom);
+ dumper->writeLength("fixedMarginLeft", m_fixedMarginLeft);
+ dumper->writeLength("fixedMarginTop", m_fixedMarginTop);
+ dumper->writeLength("fixedMarginRight", m_fixedMarginRight);
+ dumper->writeLength("fixedMarginBottom", m_fixedMarginBottom);
+ dumper->writeRect("fixedRect", m_fixedRect);
}
BackgroundImagePositioning::BackgroundImagePositioning(LayerAndroid* layer, const BackgroundImagePositioning& position)
diff --git a/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h
index e273a25..ac838c8 100644
--- a/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h
+++ b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h
@@ -130,7 +130,7 @@ public:
void contentDraw(SkCanvas* canvas, Layer::PaintStyle style);
- void dumpLayer(FILE*, int indentLevel) const;
+ void dumpLayer(LayerDumper*) const;
// ViewStateSerializer friends
friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
diff --git a/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.cpp
index 3532542..4481f55 100644
--- a/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.cpp
@@ -29,10 +29,10 @@ IFrameLayerAndroid* IFrameLayerAndroid::updatePosition(SkRect viewport,
return this;
}
-void IFrameLayerAndroid::dumpLayer(FILE* file, int indentLevel) const
+void IFrameLayerAndroid::dumpLayer(LayerDumper* dumper) const
{
- writeIntVal(file, indentLevel + 1, "m_isIframe", true);
- writeIntPoint(file, indentLevel + 1, "m_iframeOffset", m_iframeOffset);
+ LayerAndroid::dumpLayer(dumper);
+ dumper->writeIntPoint("m_iframeOffset", m_iframeOffset);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.h
index f2fbf49..08e7212 100644
--- a/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/IFrameLayerAndroid.h
@@ -53,7 +53,7 @@ public:
virtual IFrameLayerAndroid* updatePosition(SkRect viewport,
IFrameLayerAndroid* parentIframeLayer);
- virtual void dumpLayer(FILE*, int indentLevel) const;
+ virtual void dumpLayer(LayerDumper*) const;
const IntPoint& iframeOffset() const { return m_iframeOffset; }
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index 228a30e..438d96c 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
@@ -601,7 +601,7 @@ void LayerAndroid::showLayer(int indent)
m_clippingRect.width(), m_clippingRect.height());
ALOGD("%s s:%x %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
"clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d originalLayer: %x %d",
- spaces, m_surface, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(),
+ spaces, m_surface, m_haveClip ? "CLIP LAYER" : "", subclassName(),
subclassType(), uniqueId(), this, m_owningLayer,
needsTexture() ? "needsTexture" : "",
m_imageCRC ? "hasImage" : "",
@@ -954,60 +954,42 @@ void LayerAndroid::setFixedPosition(FixedPositioning* position) {
m_fixedPosition = position;
}
-void LayerAndroid::dumpLayer(FILE* file, int indentLevel) const
+void LayerAndroid::dumpLayer(LayerDumper* dumper) const
{
- writeHexVal(file, indentLevel + 1, "layer", (int)this);
- writeIntVal(file, indentLevel + 1, "layerId", m_uniqueId);
- writeIntVal(file, indentLevel + 1, "haveClip", m_haveClip);
- writeIntVal(file, indentLevel + 1, "isFixed", isPositionFixed());
+ dumper->writeIntVal("layerId", m_uniqueId);
+ dumper->writeIntVal("haveClip", m_haveClip);
+ dumper->writeIntVal("isFixed", isPositionFixed());
- writeFloatVal(file, indentLevel + 1, "opacity", getOpacity());
- writeSize(file, indentLevel + 1, "size", getSize());
- writePoint(file, indentLevel + 1, "position", getPosition());
- writePoint(file, indentLevel + 1, "anchor", getAnchorPoint());
+ dumper->writeFloatVal("opacity", getOpacity());
+ dumper->writeSize("size", getSize());
+ dumper->writePoint("position", getPosition());
+ dumper->writePoint("anchor", getAnchorPoint());
- writeMatrix(file, indentLevel + 1, "drawMatrix", m_drawTransform);
- writeMatrix(file, indentLevel + 1, "transformMatrix", m_transform);
- writeRect(file, indentLevel + 1, "clippingRect", SkRect(m_clippingRect));
+ dumper->writeMatrix("drawMatrix", m_drawTransform);
+ dumper->writeMatrix("transformMatrix", m_transform);
+ dumper->writeRect("clippingRect", SkRect(m_clippingRect));
if (m_content) {
- writeIntVal(file, indentLevel + 1, "m_content.width", m_content->width());
- writeIntVal(file, indentLevel + 1, "m_content.height", m_content->height());
+ dumper->writeIntVal("m_content.width", m_content->width());
+ dumper->writeIntVal("m_content.height", m_content->height());
}
if (m_fixedPosition)
- return m_fixedPosition->dumpLayer(file, indentLevel);
+ m_fixedPosition->dumpLayer(dumper);
}
-void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const
+void LayerAndroid::dumpLayers(LayerDumper* dumper) const
{
- writeln(file, indentLevel, "{");
-
- dumpLayer(file, indentLevel);
+ dumper->beginLayer(subclassName(), this);
+ dumpLayer(dumper);
+ dumper->beginChildren(countChildren());
if (countChildren()) {
- writeln(file, indentLevel + 1, "children = [");
- for (int i = 0; i < countChildren(); i++) {
- if (i > 0)
- writeln(file, indentLevel + 1, ", ");
- getChild(i)->dumpLayers(file, indentLevel + 1);
- }
- writeln(file, indentLevel + 1, "];");
+ for (int i = 0; i < countChildren(); i++)
+ getChild(i)->dumpLayers(dumper);
}
- writeln(file, indentLevel, "}");
-}
-
-void LayerAndroid::dumpToLog() const
-{
- FILE* file = fopen("/data/data/com.android.browser/layertmp", "w");
- dumpLayers(file, 0);
- fclose(file);
- file = fopen("/data/data/com.android.browser/layertmp", "r");
- char buffer[512];
- bzero(buffer, sizeof(buffer));
- while (fgets(buffer, sizeof(buffer), file))
- SkDebugf("%s", buffer);
- fclose(file);
+ dumper->endChildren();
+ dumper->endLayer();
}
LayerAndroid* LayerAndroid::findById(int match)
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index 41f6420..b28daef 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -73,6 +73,7 @@ class IFrameLayerAndroid;
class LayerMergeState;
class RenderLayer;
class PaintedSurface;
+class LayerDumper;
class TexturesResult {
public:
@@ -100,7 +101,7 @@ public:
CanvasLayer, BaseLayer } SubclassType;
typedef enum { InvalidateNone = 0, InvalidateLayers } InvalidateFlags;
- String subclassName()
+ const char* subclassName() const
{
switch (subclassType()) {
case LayerAndroid::StandardLayer:
@@ -195,9 +196,7 @@ public:
bool hasAnimations() const;
void addDirtyArea();
- virtual void dumpLayer(FILE*, int indentLevel) const;
- void dumpLayers(FILE*, int indentLevel) const;
- void dumpToLog() const;
+ void dumpLayers(LayerDumper*) const;
virtual IFrameLayerAndroid* updatePosition(SkRect viewport,
IFrameLayerAndroid* parentIframeLayer);
@@ -292,6 +291,7 @@ public:
}
protected:
+ virtual void dumpLayer(LayerDumper*) const;
/** Call this with the current viewport (scrolling, zoom) to update
the position of the fixed layers.
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerContent.h b/Source/WebCore/platform/graphics/android/layers/LayerContent.h
index 10b6507..a18e4c8 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerContent.h
@@ -42,7 +42,7 @@ class LayerContent : public SkRefCnt {
public:
virtual int width() = 0;
virtual int height() = 0;
- virtual bool isEmpty() { return !width() || !height(); }
+ bool isEmpty() { return !width() || !height(); }
virtual void setCheckForOptimisations(bool check) = 0;
virtual void checkForOptimisations() = 0;
virtual bool hasText() = 0;
diff --git a/Source/WebCore/platform/graphics/android/layers/MediaPlayerPrivateAndroid.h b/Source/WebCore/platform/graphics/android/layers/MediaPlayerPrivateAndroid.h
index 17fd4d8..3b4f630 100644
--- a/Source/WebCore/platform/graphics/android/layers/MediaPlayerPrivateAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/MediaPlayerPrivateAndroid.h
@@ -104,8 +104,8 @@ public:
{
return m_videoLayer;
}
- void onStopFullscreen();
-
+ void onStopFullscreen(bool stillPlaying);
+ virtual void enterFullscreenMode() { }
protected:
// Android-specific methods and fields.
static MediaPlayerPrivateInterface* create(MediaPlayer* player);
diff --git a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
index 4398146..e40c9b6 100644
--- a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
@@ -1,6 +1,10 @@
+#define LOG_TAG "PictureLayerContent"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "PictureLayerContent.h"
+#include "AndroidLog.h"
#include "InspectorCanvas.h"
#include "SkPicture.h"
@@ -41,16 +45,6 @@ int PictureLayerContent::height()
return m_picture->height();
}
-bool PictureLayerContent::isEmpty()
-{
- if (!m_picture)
- return true;
- if (m_picture->width() == 0
- || m_picture->height() == 0)
- return true;
- return false;
-}
-
void PictureLayerContent::checkForOptimisations()
{
if (!m_checkedContent)
@@ -90,6 +84,7 @@ void PictureLayerContent::draw(SkCanvas* canvas)
if (!m_picture)
return;
+ TRACE_METHOD();
android::Mutex::Autolock lock(m_drawLock);
SkRect r = SkRect::MakeWH(width(), height());
canvas->clipRect(r);
diff --git a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
index 1567f44..cf633cb 100644
--- a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
@@ -38,7 +38,6 @@ public:
virtual int width();
virtual int height();
- virtual bool isEmpty();
virtual void setCheckForOptimisations(bool check) { m_checkedContent = !check; }
virtual void checkForOptimisations();
virtual bool hasText();
diff --git a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp
index b648e72..1167bda 100644
--- a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp
@@ -1,6 +1,10 @@
+#define LOG_TAG "PicturePileLayerContent"
+#define LOG_NDEBUG 1
+
#include "config.h"
#include "PicturePileLayerContent.h"
+#include "AndroidLog.h"
#include "SkCanvas.h"
#include "SkPicture.h"
@@ -8,13 +12,19 @@ namespace WebCore {
PicturePileLayerContent::PicturePileLayerContent(const PicturePile& picturePile)
: m_picturePile(picturePile)
+ , m_hasText(picturePile.hasText())
+ , m_hasContent(!picturePile.isEmpty())
{
}
void PicturePileLayerContent::draw(SkCanvas* canvas)
{
+ TRACE_METHOD();
android::Mutex::Autolock lock(m_drawLock);
m_picturePile.draw(canvas);
+
+ if (CC_UNLIKELY(!m_hasContent))
+ ALOGW("Warning: painting PicturePile without content!");
}
void PicturePileLayerContent::serialize(SkWStream* stream)
diff --git a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h
index 4fc123e..9f3a263 100644
--- a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h
@@ -35,18 +35,23 @@ class PicturePileLayerContent : public LayerContent {
public:
PicturePileLayerContent(const PicturePile& picturePile);
- virtual int width() { return m_picturePile.size().width(); }
- virtual int height() { return m_picturePile.size().height(); }
+ // return 0 when no content, so don't have to paint
+ virtual int width() { return m_hasContent ? m_picturePile.size().width() : 0; }
+ virtual int height() { return m_hasContent ? m_picturePile.size().height() : 0; }
+
virtual void setCheckForOptimisations(bool check) {}
- virtual void checkForOptimisations() {}
- virtual bool hasText() { return true; }
+ virtual void checkForOptimisations() {} // already performed, stored in m_hasText/m_hasContent
+ virtual bool hasText() { return m_hasText; }
virtual void draw(SkCanvas* canvas);
virtual void serialize(SkWStream* stream);
virtual PrerenderedInval* prerenderForRect(const IntRect& dirty);
virtual void clearPrerenders();
+ PicturePile* picturePile() { return &m_picturePile; }
private:
PicturePile m_picturePile;
+ bool m_hasText;
+ bool m_hasContent;
};
} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h
index 5ebf615..07c241f 100644
--- a/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h
@@ -44,7 +44,7 @@ namespace WebCore {
// Otherwise will draw a static image.
// NOTE: These values are matching the ones in HTML5VideoView.java
// Please keep them in sync when changed here.
-typedef enum {INITIALIZED, PREPARING, PREPARED, PLAYING, RELEASED} PlayerState;
+typedef enum {INITIALIZED, PREPARING, PREPARED, PLAYING, RESETTED, RELEASED} PlayerState;
class VideoLayerAndroid : public LayerAndroid {
diff --git a/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.cpp b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.cpp
index a7b3184..1f28cdf 100644
--- a/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.cpp
@@ -73,7 +73,7 @@ int VideoLayerManager::getButtonSize()
return VIDEO_BUTTON_SIZE;
}
-GLuint VideoLayerManager::createTextureFromImage(int buttonType)
+GLuint VideoLayerManager::createTextureFromImage(RenderSkinMediaButton::MediaButton buttonType)
{
SkRect rect = SkRect(m_buttonRect);
SkBitmap bitmap;
@@ -83,8 +83,7 @@ GLuint VideoLayerManager::createTextureFromImage(int buttonType)
SkCanvas canvas(bitmap);
canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
- RenderSkinMediaButton::Draw(&canvas, m_buttonRect, buttonType, true, 0,
- false);
+ RenderSkinMediaButton::Draw(&canvas, m_buttonRect, buttonType, true, false);
GLuint texture;
glGenTextures(1, &texture);
diff --git a/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
index adce0f4..346afe4 100644
--- a/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
+++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerManager.h
@@ -28,6 +28,7 @@
#include "GLUtils.h"
#include "IntRect.h"
+#include "RenderSkinMediaButton.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
#include <utils/threads.h>
@@ -122,7 +123,7 @@ private:
Vector<GLuint> m_retiredTextures;
android::Mutex m_retiredTexturesLock;
- GLuint createTextureFromImage(int buttonType);
+ GLuint createTextureFromImage(RenderSkinMediaButton::MediaButton buttonType);
// Texture for showing the static image will be created at native side.
bool m_createdTexture;
diff --git a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
index 6f679da..0ab72b7 100644
--- a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
@@ -34,6 +34,7 @@
#include "AndroidLog.h"
#include "GaneshRenderer.h"
#include "GLUtils.h"
+#include "InstrumentedPlatformCanvas.h"
#include "RasterRenderer.h"
#include "SkBitmap.h"
#include "SkBitmapRef.h"
@@ -94,7 +95,10 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
const bool visualIndicator = TilesManager::instance()->getShowVisualIndicator();
const SkSize& tileSize = renderInfo.tileSize;
- SkCanvas canvas;
+ Color *background = renderInfo.tilePainter->background();
+ InstrumentedPlatformCanvas canvas(TilesManager::instance()->tileWidth(),
+ TilesManager::instance()->tileHeight(),
+ background ? *background : Color::transparent);
setupCanvas(renderInfo, &canvas);
if (!canvas.getDevice()) {
@@ -112,10 +116,8 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
canvas.translate(-renderInfo.x * tileSize.width(), -renderInfo.y * tileSize.height());
canvas.scale(renderInfo.scale, renderInfo.scale);
renderInfo.tilePainter->paint(&canvas);
- if (renderInfo.baseTile && renderInfo.baseTile->backTexture())
- checkForPureColor(renderInfo, &canvas);
- else
- renderInfo.isPureColor = false;
+
+ checkForPureColor(renderInfo, canvas);
if (visualIndicator) {
double after = currentTimeMS();
@@ -144,6 +146,13 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
renderingComplete(renderInfo, &canvas);
}
+void BaseRenderer::checkForPureColor(TileRenderInfo& renderInfo, InstrumentedPlatformCanvas& canvas)
+{
+ renderInfo.isPureColor = canvas.isSolidColor();
+ renderInfo.pureColor = canvas.solidColor();
+ deviceCheckForPureColor(renderInfo, &canvas);
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
index b25a50e..dc8831a 100644
--- a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
@@ -37,6 +37,7 @@ class SkDevice;
namespace WebCore {
+class InstrumentedPlatformCanvas;
class TextureInfo;
class TilePainter;
class Tile;
@@ -87,7 +88,10 @@ protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
- virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
+ void checkForPureColor(TileRenderInfo& renderInfo, InstrumentedPlatformCanvas& canvas);
+
+ // performs additional pure color check, renderInfo.isPureColor may already be set to true
+ virtual void deviceCheckForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
void drawTileInfo(SkCanvas* canvas, const TileRenderInfo& renderInfo,
int updateCount, double renderDuration);
diff --git a/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp b/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp
index 2c114d6..175c552 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp
@@ -35,7 +35,6 @@
#include "IntRect.h"
#include "SkPath.h"
#include "TilesManager.h"
-#include "android_graphics.h"
// Touch ring border width. This is doubled if the ring is not pressed
#define RING_BORDER_WIDTH 1
diff --git a/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp
index 4a0b77b..1a54cb7 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp
@@ -384,6 +384,7 @@ bool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor)
// If the bitmap is the pure color, skip the transfer step, and update the Tile Info.
// This check is taking < 1ms if we do full bitmap check per tile.
// TODO: use the SkPicture to determine whether or not a tile is single color.
+ TRACE_METHOD();
pureColor = Color(Color::transparent);
bitmap.lockPixels();
bool sameColor = true;
@@ -445,7 +446,7 @@ bool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
}
void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
- const SkBitmap& bitmap)
+ SkBitmap& bitmap)
{
if (!renderInfo)
return;
@@ -471,7 +472,7 @@ void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
}
}
-void GLUtils::updateQueueWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap)
+void GLUtils::updateQueueWithBitmap(const TileRenderInfo* renderInfo, SkBitmap& bitmap)
{
if (!renderInfo
|| !renderInfo->textureInfo
@@ -483,6 +484,7 @@ void GLUtils::updateQueueWithBitmap(const TileRenderInfo* renderInfo, const SkBi
bool GLUtils::updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkBitmap& bitmap)
{
+ TRACE_METHOD();
SkAutoLockPixels alp(bitmap);
if (!bitmap.getPixels())
return false;
diff --git a/Source/WebCore/platform/graphics/android/rendering/GLUtils.h b/Source/WebCore/platform/graphics/android/rendering/GLUtils.h
index c2dec7d..3b093d1 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GLUtils.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GLUtils.h
@@ -80,8 +80,8 @@ public:
static void createEGLImageFromTexture(GLuint texture, EGLImageKHR* image);
static void createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter = GL_LINEAR);
- static void paintTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap);
- static void updateQueueWithBitmap(const TileRenderInfo* , const SkBitmap& bitmap);
+ static void paintTextureWithBitmap(const TileRenderInfo* renderInfo, SkBitmap& bitmap);
+ static void updateQueueWithBitmap(const TileRenderInfo* , SkBitmap& bitmap);
static bool updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkBitmap& bitmap);
static void convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix);
diff --git a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp
index d779af4..8b5e30a 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp
@@ -94,7 +94,8 @@ void GaneshRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanva
// tile's ANativeWindow (i.e. SurfaceTexture) buffer
TransferQueue* tileQueue = TilesManager::instance()->transferQueue();
eglSwapBuffers(eglGetCurrentDisplay(), tileQueue->m_eglSurface);
- tileQueue->addItemInTransferQueue(&renderInfo, GpuUpload, 0);
+ SkBitmap dummyBitmap;
+ tileQueue->addItemInTransferQueue(&renderInfo, GpuUpload, dummyBitmap);
tileQueue->unlockQueue();
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
index cdd9f3e..77982e8 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
@@ -48,9 +48,7 @@ protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas);
- virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) {
- renderInfo.isPureColor = false;
- }
+ virtual void deviceCheckForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) {}
};
diff --git a/Source/WebCore/platform/graphics/android/rendering/InstrumentedPlatformCanvas.h b/Source/WebCore/platform/graphics/android/rendering/InstrumentedPlatformCanvas.h
new file mode 100644
index 0000000..508795a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/InstrumentedPlatformCanvas.h
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef InstrumentedPlatformCanvas_h
+#define InstrumentedPlatformCanvas_h
+
+#include "SkCanvas.h"
+
+#define DEBUG_SKIA_DRAWING 0
+#if DEBUG_SKIA_DRAWING
+#define WRAPCANVAS_LOG_ENTRY(...) do { \
+ fprintf(stderr, "%s ", __FUNCTION__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+} while (0)
+#else
+#define WRAPCANVAS_LOG_ENTRY(...) ((void)0)
+#endif
+
+namespace WebCore {
+
+class InstrumentedPlatformCanvas : public SkCanvas {
+public:
+ InstrumentedPlatformCanvas(int width, int height, Color initialColor)
+ : m_size(width, height)
+ , m_isSolidColor(true)
+ , m_solidColor(initialColor)
+ {
+ }
+
+ virtual ~InstrumentedPlatformCanvas() { }
+
+ bool isSolidColor() const { return m_isSolidColor; }
+ Color solidColor() const { return m_solidColor; }
+
+ // overrides from SkCanvas
+ virtual int save(SaveFlags flags = kMatrixClip_SaveFlag)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::save(flags);
+ }
+
+ virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ return SkCanvas::saveLayer(bounds, paint, flags);
+ }
+
+ virtual void restore()
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ SkCanvas::restore();
+ }
+
+ virtual bool translate(SkScalar dx, SkScalar dy)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::translate(dx, dy);
+ }
+
+ virtual bool scale(SkScalar sx, SkScalar sy)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::scale(sx, sy);
+ }
+
+ virtual bool rotate(SkScalar degrees)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::rotate(degrees);
+ }
+
+ virtual bool skew(SkScalar sx, SkScalar sy)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::skew(sx, sy);
+ }
+
+ virtual bool concat(const SkMatrix& matrix)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::concat(matrix);
+ }
+
+ virtual void setMatrix(const SkMatrix& matrix)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ SkCanvas::setMatrix(matrix);
+ }
+
+ virtual bool clipRect(const SkRect& rect, SkRegion::Op op)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::clipRect(rect, op);
+ }
+
+ virtual bool clipPath(const SkPath& path, SkRegion::Op op)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ return SkCanvas::clipPath(path, op);
+ }
+
+ virtual bool clipRegion(const SkRegion& region, SkRegion::Op op)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ return SkCanvas::clipRegion(region, op);
+ }
+
+ virtual void clear(SkColor color)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = true;
+ m_solidColor = Color(color);
+ SkCanvas::clear(color);
+ }
+
+ virtual void drawPaint(const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPaint(paint);
+ }
+
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPoints(mode, count, pts, paint);
+ }
+
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint)
+ {
+#if DEBUG_SKIA_DRAWING
+ IntRect rectToDraw(rect);
+ WRAPCANVAS_LOG_ENTRY("rect = (x=%d,y=%d,width=%d,height=%d)", INT_RECT_ARGS(rectToDraw);
+#endif
+ IntRect canvasRect(IntPoint(), m_size);
+ if (m_isSolidColor
+ && getTotalMatrix().rectStaysRect()
+ && getTotalClip().contains(canvasRect)) {
+ const SkMatrix& matrix = getTotalMatrix();
+ SkRect mapped;
+ matrix.mapRect(&mapped, rect);
+ if (mapped.contains(canvasRect)) {
+ Color color = solidColor(paint);
+ m_isSolidColor = color.isValid();
+ m_solidColor = color;
+ } else
+ m_isSolidColor = false;
+ } else
+ m_isSolidColor = false;
+ SkCanvas::drawRect(rect, paint);
+ }
+
+ virtual void drawPath(const SkPath& path, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPath(path, paint);
+ }
+
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
+ SkScalar top, const SkPaint* paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawBitmap(bitmap, left, top, paint);
+ }
+
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, const SkPaint* paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawBitmapRect(bitmap, src, dst, paint);
+ }
+
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap,
+ const SkMatrix& matrix, const SkPaint* paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawBitmapMatrix(bitmap, matrix, paint);
+ }
+
+ virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, const SkPaint* paint = 0)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawBitmapNine(bitmap, center, dst, paint);
+ }
+
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawSprite(bitmap, left, top, paint);
+ }
+
+ virtual void drawText(const void* text, size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawText(text, byteLength, x, y, paint);
+ }
+
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPosText(text, byteLength, pos, paint);
+ }
+
+ virtual void drawPosTextH(const void* text, size_t byteLength,
+ const SkScalar xpos[], SkScalar constY, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint);
+ }
+
+ virtual void drawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawTextOnPath(text, byteLength, path, matrix, paint);
+ }
+
+ virtual void drawPicture(SkPicture& picture)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPicture(picture);
+ }
+
+ virtual void drawVertices(VertexMode mode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xfermode,
+ const uint16_t indices[], int indexCount, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawVertices(mode, vertexCount, vertices, texs,
+ colors, xfermode, indices, indexCount, paint);
+ }
+
+ virtual void drawData(const void* data, size_t size)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawData(data, size);
+ }
+
+private:
+ Color solidColor(const SkPaint& paint)
+ {
+ if (paint.getStyle() != SkPaint::kFill_Style)
+ return Color();
+ if (paint.getLooper() || paint.getShader())
+ return Color();
+
+ SkXfermode::Mode mode;
+ SkXfermode::AsMode(paint.getXfermode(), &mode);
+ if (mode == SkXfermode::kClear_Mode)
+ return Color(0, 0, 0, 0);
+
+ if ((mode == SkXfermode::kSrcOver_Mode && paint.getAlpha() == 255)
+ || mode == SkXfermode::kSrc_Mode)
+ return Color(paint.getColor());
+ return Color();
+ }
+
+ IntSize m_size;
+ bool m_isSolidColor;
+ Color m_solidColor;
+ SkPaint m_solidPaint;
+};
+
+} // namespace WebCore
+
+#endif // InstrumentedPlatformCanvas_h
diff --git a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp
index 3fcbdb2..c1b91a3 100644
--- a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.cpp
@@ -79,12 +79,12 @@ bool PaintTileOperation::operator==(const QueuedOperation* operation)
return op->m_tile == m_tile;
}
-void PaintTileOperation::run()
+void PaintTileOperation::run(BaseRenderer* renderer)
{
TRACE_METHOD();
if (m_tile) {
- m_tile->paintBitmap(m_painter);
+ m_tile->paintBitmap(m_painter, renderer);
m_tile->setRepaintPending(false);
m_tile = 0;
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h
index c82cdcd..ecd3ce9 100644
--- a/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h
+++ b/Source/WebCore/platform/graphics/android/rendering/PaintTileOperation.h
@@ -42,7 +42,7 @@ public:
GLWebViewState* state, bool isLowResPrefetch);
virtual ~PaintTileOperation();
virtual bool operator==(const QueuedOperation* operation);
- virtual void run();
+ virtual void run(BaseRenderer* renderer);
virtual void* uniquePtr() { return m_tile; }
// returns a rendering priority for m_tile, lower values are processed faster
virtual int priority();
diff --git a/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h b/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h
index 7625528..fe6f8a3 100644
--- a/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h
+++ b/Source/WebCore/platform/graphics/android/rendering/QueuedOperation.h
@@ -28,10 +28,12 @@
namespace WebCore {
+class BaseRenderer;
+
class QueuedOperation {
public:
virtual ~QueuedOperation() {}
- virtual void run() = 0;
+ virtual void run(BaseRenderer* renderer) = 0;
virtual bool operator==(const QueuedOperation* operation) = 0;
virtual void* uniquePtr() = 0;
virtual int priority() = 0;
diff --git a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
index 47e5c17..fd26380 100644
--- a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
@@ -42,20 +42,17 @@
namespace WebCore {
-SkBitmap* RasterRenderer::g_bitmap = 0;
-
-RasterRenderer::RasterRenderer() : BaseRenderer(BaseRenderer::Raster)
+RasterRenderer::RasterRenderer()
+ : BaseRenderer(BaseRenderer::Raster)
+ , m_bitmapIsPureColor(false)
{
+ m_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ TilesManager::instance()->tileWidth(),
+ TilesManager::instance()->tileHeight());
+ m_bitmap.allocPixels();
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("RasterRenderer");
#endif
- if (!g_bitmap) {
- g_bitmap = new SkBitmap();
- g_bitmap->setConfig(SkBitmap::kARGB_8888_Config,
- TilesManager::instance()->tileWidth(),
- TilesManager::instance()->tileHeight());
- g_bitmap->allocPixels();
- }
}
RasterRenderer::~RasterRenderer()
@@ -67,9 +64,14 @@ RasterRenderer::~RasterRenderer()
void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
+ TRACE_METHOD();
+
if (renderInfo.baseTile->isLayerTile()) {
- g_bitmap->setIsOpaque(false);
- g_bitmap->eraseARGB(0, 0, 0, 0);
+ m_bitmap.setIsOpaque(false);
+
+ // clear bitmap if necessary
+ if (!m_bitmapIsPureColor || m_bitmapPureColor != Color::transparent)
+ m_bitmap.eraseARGB(0, 0, 0, 0);
} else {
Color defaultBackground = Color::white;
Color* background = renderInfo.tilePainter->background();
@@ -78,12 +80,15 @@ void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
background = &defaultBackground;
}
ALOGV("setupCanvas use background on Base Layer %x", background->rgb());
- g_bitmap->setIsOpaque(!background->hasAlpha());
- g_bitmap->eraseARGB(background->alpha(), background->red(),
- background->green(), background->blue());
+ m_bitmap.setIsOpaque(!background->hasAlpha());
+
+ // fill background color if necessary
+ if (!m_bitmapIsPureColor || m_bitmapPureColor != *background)
+ m_bitmap.eraseARGB(background->alpha(), background->red(),
+ background->green(), background->blue());
}
- SkDevice* device = new SkDevice(*g_bitmap);
+ SkDevice* device = new SkDevice(m_bitmap);
canvas->setDevice(device);
@@ -92,14 +97,20 @@ void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
void RasterRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
- GLUtils::paintTextureWithBitmap(&renderInfo, bitmap);
+ // We may swap the content of m_bitmap with the bitmap in the transfer queue.
+ GLUtils::paintTextureWithBitmap(&renderInfo, m_bitmap);
}
-void RasterRenderer::checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas)
+void RasterRenderer::deviceCheckForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
- renderInfo.isPureColor = GLUtils::isPureColorBitmap(bitmap, renderInfo.pureColor);
+ if (!renderInfo.isPureColor) {
+ // base renderer may have already determined isPureColor, so only do the
+ // brute force check if needed
+ renderInfo.isPureColor = GLUtils::isPureColorBitmap(m_bitmap, renderInfo.pureColor);
+ }
+
+ m_bitmapIsPureColor = renderInfo.isPureColor;
+ m_bitmapPureColor = renderInfo.pureColor;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h
index 39e00f2..791c6b6 100644
--- a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h
@@ -46,14 +46,14 @@ public:
~RasterRenderer();
protected:
-
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas);
- virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas);
+ virtual void deviceCheckForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas);
private:
- static SkBitmap* g_bitmap;
-
+ SkBitmap m_bitmap;
+ bool m_bitmapIsPureColor;
+ Color m_bitmapPureColor;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
index d7266a3..b59b6e2 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
@@ -257,6 +257,16 @@ GLint ShaderProgram::createProgram(const char* pVertexSource, const char* pFragm
return program;
}
+void ShaderProgram::initProgram(ShaderType type)
+{
+ // initialize shader's static texSampler and position values
+ glUseProgram(m_handleArray[type].programHandle);
+
+ if (m_handleArray[type].texSamplerHandle != -1)
+ glUniform1i(m_handleArray[type].texSamplerHandle, 0);
+ glEnableVertexAttribArray(m_handleArray[type].positionHandle);
+}
+
ShaderProgram::ShaderProgram()
: m_blendingEnabled(false)
, m_contrast(1)
@@ -321,6 +331,7 @@ void ShaderProgram::initGLResources()
GLint pureColorValue = glGetUniformLocation(pureColorProgram, "inputColor");
m_handleArray[PureColor].init(-1, -1, pureColorPosition, pureColorProgram,
pureColorProjMtx, pureColorValue, -1, -1, -1, -1);
+ initProgram(PureColor);
GLint tex2DAlpha = glGetUniformLocation(tex2DProgram, "alpha");
GLint tex2DPosition = glGetAttribLocation(tex2DProgram, "vPosition");
@@ -329,6 +340,7 @@ void ShaderProgram::initGLResources()
GLint tex2DFillPortion = glGetUniformLocation(tex2DProgram, "fillPortion");
m_handleArray[Tex2D].init(tex2DAlpha, -1, tex2DPosition, tex2DProgram,
tex2DProjMtx, -1, tex2DTexSampler, -1, tex2DFillPortion, -1);
+ initProgram(Tex2D);
GLint tex2DInvAlpha = glGetUniformLocation(tex2DInvProgram, "alpha");
GLint tex2DInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast");
@@ -340,6 +352,7 @@ void ShaderProgram::initGLResources()
tex2DInvPosition, tex2DInvProgram,
tex2DInvProjMtx, -1,
tex2DInvTexSampler, -1, tex2DInvFillPortion, -1);
+ initProgram(Tex2DInv);
GLint repeatTexAlpha = glGetUniformLocation(repeatTexProgram, "alpha");
GLint repeatTexPosition = glGetAttribLocation(repeatTexProgram, "vPosition");
@@ -351,6 +364,7 @@ void ShaderProgram::initGLResources()
repeatTexProgram,repeatTexProjMtx, -1,
repeatTexTexSampler, -1, repeatTexFillPortion,
repeatTexScale);
+ initProgram(RepeatTex);
GLint repeatTexInvAlpha = glGetUniformLocation(repeatTexInvProgram, "alpha");
GLint repeatTexInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast");
@@ -364,6 +378,7 @@ void ShaderProgram::initGLResources()
repeatTexInvProjMtx, -1,
repeatTexInvTexSampler, -1,
repeatTexInvFillPortion, repeatTexInvScale);
+ initProgram(RepeatTexInv);
GLint texOESAlpha = glGetUniformLocation(texOESProgram, "alpha");
GLint texOESPosition = glGetAttribLocation(texOESProgram, "vPosition");
@@ -372,6 +387,7 @@ void ShaderProgram::initGLResources()
GLint texOESFillPortion = glGetUniformLocation(texOESProgram, "fillPortion");
m_handleArray[TexOES].init(texOESAlpha, -1, texOESPosition, texOESProgram,
texOESProjMtx, -1, texOESTexSampler, -1, texOESFillPortion, -1);
+ initProgram(TexOES);
GLint texOESInvAlpha = glGetUniformLocation(texOESInvProgram, "alpha");
GLint texOESInvContrast = glGetUniformLocation(texOESInvProgram, "contrast");
@@ -383,6 +399,7 @@ void ShaderProgram::initGLResources()
texOESInvPosition, texOESInvProgram,
texOESInvProjMtx, -1,
texOESInvTexSampler, -1, texOESInvFillPortion, -1);
+ initProgram(TexOESInv);
GLint videoPosition = glGetAttribLocation(videoProgram, "vPosition");
GLint videoProjMtx = glGetUniformLocation(videoProgram, "projectionMatrix");
@@ -391,6 +408,7 @@ void ShaderProgram::initGLResources()
m_handleArray[Video].init(-1, -1, videoPosition, videoProgram,
videoProjMtx, -1, videoTexSampler,
videoTexMtx, -1, -1);
+ initProgram(Video);
const GLfloat coord[] = {
0.0f, 0.0f, // C
@@ -539,6 +557,16 @@ void ShaderProgram::setupDrawing(const IntRect& invScreenRect,
// Set up m_clipProjectionMatrix, m_currentScale and m_webViewMatrix before
// calling this function.
setupSurfaceProjectionMatrix();
+
+ //// initialize frame-constant values ////
+ glActiveTexture(GL_TEXTURE0);
+ glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
+
+ //// initialize GL cache ////
+ m_cachedProgramType = UndefinedShader;
+ m_cachedOpacity = -1;
+ m_cachedFillPortion = FloatRect();
+ m_cachedPureColor = Color();
}
// Calculate the right color value sent into the shader considering the (0,1)
@@ -695,23 +723,34 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix,
const Color& pureColor, const FloatRect& fillPortion,
const FloatSize& repeatScale)
{
- glUseProgram(m_handleArray[type].programHandle);
+ if (m_cachedProgramType != type) {
+ glUseProgram(m_handleArray[type].programHandle);
+ glVertexAttribPointer(m_handleArray[type].positionHandle,
+ 2, GL_FLOAT, GL_FALSE, 0, 0);
+ m_cachedProgramType = type;
+ m_cachedOpacity = -1; // reset cache for variable shared by multiple programs
+ }
glUniformMatrix4fv(m_handleArray[type].projMtxHandle, 1, GL_FALSE, matrix);
if (type != PureColor) {
- glActiveTexture(GL_TEXTURE0);
- glUniform1i(m_handleArray[type].texSamplerHandle, 0);
glBindTexture(textureTarget, textureId);
glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, filter);
- glUniform1f(m_handleArray[type].alphaHandle, opacity);
+
+ if (m_cachedOpacity != opacity) {
+ glUniform1f(m_handleArray[type].alphaHandle, opacity);
+ m_cachedOpacity = opacity;
+ }
GLint contrastHandle = m_handleArray[type].contrastHandle;
if (contrastHandle != -1)
glUniform1f(contrastHandle, m_contrast);
- glUniform4f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y(),
- fillPortion.width(), fillPortion.height());
+ if (m_cachedFillPortion != fillPortion) {
+ glUniform4f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y(),
+ fillPortion.width(), fillPortion.height());
+ m_cachedFillPortion = fillPortion;
+ }
// Only when we have repeat scale, this handle can be >= 0;
if (m_handleArray[type].scaleHandle != -1) {
@@ -719,16 +758,14 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix,
repeatScale.width(), repeatScale.height());
}
} else {
- glUniform4f(m_handleArray[type].pureColorHandle,
- pureColor.red() / 255.0, pureColor.green() / 255.0,
- pureColor.blue() / 255.0, pureColor.alpha() / 255.0);
+ if (m_cachedPureColor != pureColor) {
+ glUniform4f(m_handleArray[type].pureColorHandle,
+ pureColor.red() / 255.0, pureColor.green() / 255.0,
+ pureColor.blue() / 255.0, pureColor.alpha() / 255.0);
+ m_cachedPureColor = pureColor;
+ }
}
- GLint positionHandle = m_handleArray[type].positionHandle;
- glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
- glEnableVertexAttribArray(positionHandle);
- glVertexAttribPointer(positionHandle, 2, GL_FLOAT, GL_FALSE, 0, 0);
-
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
@@ -819,7 +856,13 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
int textureId)
{
// switch to our custom yuv video rendering program
- glUseProgram(m_handleArray[Video].programHandle);
+ if (m_cachedProgramType != Video) {
+ glUseProgram(m_handleArray[Video].programHandle);
+ glVertexAttribPointer(m_handleArray[Video].positionHandle,
+ 2, GL_FLOAT, GL_FALSE, 0, 0);
+ m_cachedProgramType = Video;
+ }
+
// TODO: Merge drawVideoLayerQuad into drawQuad.
TransformationMatrix modifiedDrawMatrix;
modifiedDrawMatrix.scale3d(m_currentScale, m_currentScale, 1);
@@ -835,15 +878,8 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
projectionMatrix);
glUniformMatrix4fv(m_handleArray[Video].videoMtxHandle, 1, GL_FALSE,
textureMatrix);
- glActiveTexture(GL_TEXTURE0);
- glUniform1i(m_handleArray[Video].texSamplerHandle, 0);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
- GLint videoPosition = m_handleArray[Video].positionHandle;
- glBindBuffer(GL_ARRAY_BUFFER, m_textureBuffer[0]);
- glEnableVertexAttribArray(videoPosition);
- glVertexAttribPointer(videoPosition, 2, GL_FLOAT, GL_FALSE, 0, 0);
-
setBlendingState(false);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
index 27eb737..9c5dc17 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
@@ -168,6 +168,7 @@ public:
private:
GLuint loadShader(GLenum shaderType, const char* pSource);
GLint createProgram(const char* vertexSource, const char* fragmentSource);
+ void initProgram(ShaderType type);
GLfloat* getTileProjectionMatrix(const DrawQuadData* data);
void setBlendingState(bool enableBlending);
void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
@@ -231,6 +232,11 @@ private:
GLfloat m_tileProjMatrix[16];
Vector<ShaderResource> m_resources;
+
+ ShaderType m_cachedProgramType;
+ GLfloat m_cachedOpacity;
+ FloatRect m_cachedFillPortion;
+ Color m_cachedPureColor;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
index 1898910..96a4a16 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -218,7 +218,7 @@ void Surface::prepareGL(bool layerTilesDisabled, bool updateWithBlit)
ALOGV("prepareGL on Surf %p with SurfBack %p, %d layers, first layer %s (%d) "
"prepareArea(%d, %d - %d x %d) fullArea(%d, %d - %d x %d)",
this, m_surfaceBacking, m_layers.size(),
- getFirstLayer()->subclassName().ascii().data(),
+ getFirstLayer()->subclassName(),
getFirstLayer()->uniqueId(),
prepareArea.x(), prepareArea.y(), prepareArea.width(), prepareArea.height(),
fullArea.x(), fullArea.y(), fullArea.width(), fullArea.height());
@@ -253,7 +253,7 @@ bool Surface::drawGL(bool layerTilesDisabled)
bool askRedraw = false;
if (m_surfaceBacking && !tilesDisabled) {
ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking,
- getFirstLayer()->subclassName().ascii().data(), getFirstLayer()->uniqueId());
+ getFirstLayer()->subclassName(), getFirstLayer()->uniqueId());
bool force3dContentVisible = true;
IntRect drawArea = visibleContentArea(force3dContentVisible);
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
index d7f6535..5b11df6 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
@@ -40,13 +40,15 @@
namespace WebCore {
SurfaceBacking::SurfaceBacking(bool isBaseSurface)
+ : m_frontTileGrid(new TileGrid(isBaseSurface))
+ , m_backTileGrid(new TileGrid(isBaseSurface))
+ , m_lowResTileGrid(new TileGrid(isBaseSurface))
+ , m_scale(-1)
+ , m_futureScale(-1)
+ , m_zooming(false)
+ , m_hasAllowedZoom(false)
+
{
- m_frontTileGrid = new TileGrid(isBaseSurface);
- m_backTileGrid = new TileGrid(isBaseSurface);
- m_lowResTileGrid = new TileGrid(isBaseSurface);
- m_scale = -1;
- m_futureScale = -1;
- m_zooming = false;
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("SurfaceBacking");
#endif
@@ -67,9 +69,16 @@ void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom,
TilePainter* painter, bool aggressiveRendering,
bool updateWithBlit)
{
+ // If the surface backing has ever zoomed beyond 1.0 scale, it's always
+ // allowed to (so repaints aren't necessary when allowZoom toggles). If not,
+ // and allowZoom is false, don't allow scale greater than 1.0
+ m_hasAllowedZoom |= allowZoom;
float scale = state->scale();
- if (scale > 1 && !allowZoom)
+ bool scaleOverridden = false;
+ if (scale > 1 && !m_hasAllowedZoom) {
scale = 1;
+ scaleOverridden = true;
+ }
if (m_scale == -1) {
m_scale = scale;
@@ -78,7 +87,10 @@ void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom,
if (m_futureScale != scale) {
m_futureScale = scale;
- m_zoomUpdateTime = WTF::currentTime() + SurfaceBacking::s_zoomUpdateDelay;
+ if (scaleOverridden)
+ m_zoomUpdateTime = 0; // start rendering immediately
+ else
+ m_zoomUpdateTime = WTF::currentTime() + SurfaceBacking::s_zoomUpdateDelay;
m_zooming = true;
// release back TileGrid's TileTextures, so they can be reused immediately
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
index 5709f2a..80c6545 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
@@ -85,7 +85,7 @@ private:
void swapTileGrids();
// Delay before we schedule a new tile at the new scale factor
- static const double s_zoomUpdateDelay = 0.2; // 200 ms
+ static const double s_zoomUpdateDelay = 0.1; // 100 ms
TileGrid* m_frontTileGrid;
TileGrid* m_backTileGrid;
@@ -95,6 +95,7 @@ private:
float m_futureScale;
double m_zoomUpdateTime;
bool m_zooming;
+ bool m_hasAllowedZoom;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
index 174720f..1270498 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
@@ -38,6 +38,10 @@ namespace WebCore {
using namespace android::uirenderer;
+// Tag used to display current number of SurfaceCollections.
+// Note: this will only work if one webview is actively drawing at a time.
+static const char* COLLECTION_COUNT_TAG = "CollectionCount";
+
SurfaceCollectionManager::SurfaceCollectionManager()
: m_drawingCollection(0)
, m_paintingCollection(0)
@@ -87,6 +91,12 @@ void SurfaceCollectionManager::swap()
m_paintingCollection = m_queuedCollection;
m_queuedCollection = 0;
+ if (ATRACE_ENABLED()) {
+ ATRACE_INT(COLLECTION_COUNT_TAG,
+ (m_drawingCollection ? 1 : 0)
+ + (m_paintingCollection ? 1 : 0));
+ }
+
ALOGV("SWAPPING COMPLETE, D %p, P %p, Q %p",
m_drawingCollection, m_paintingCollection, m_queuedCollection);
}
@@ -106,6 +116,8 @@ void SurfaceCollectionManager::clearCollections()
m_paintingCollection = 0;
SkSafeUnref(m_queuedCollection);
m_queuedCollection = 0;
+
+ ATRACE_INT(COLLECTION_COUNT_TAG, 0);
}
void SurfaceCollectionManager::updatePaintingCollection(SurfaceCollection* newCollection)
@@ -126,8 +138,10 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne
if (!newCollection || brandNew) {
clearCollections();
- if (brandNew)
+ if (brandNew) {
updatePaintingCollection(newCollection);
+ ATRACE_INT(COLLECTION_COUNT_TAG, 1);
+ }
return false;
}
@@ -157,6 +171,13 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne
// don't have painting collection, paint this one!
updatePaintingCollection(newCollection);
}
+
+ if (ATRACE_ENABLED()) {
+ ATRACE_INT(COLLECTION_COUNT_TAG,
+ (m_drawingCollection ? 1 : 0)
+ + (m_paintingCollection ? 1 : 0)
+ + (m_queuedCollection ? 1 : 0));
+ }
return m_drawingCollection && TilesManager::instance()->useDoubleBuffering();
}
@@ -225,12 +246,12 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
int returnFlags = 0;
bool didCollectionSwap = false;
+ bool tryFastBlit = !m_fastSwapMode;
if (m_paintingCollection) {
ALOGV("preparing painting collection %p", m_paintingCollection);
m_paintingCollection->evaluateAnimations(currentTime);
- bool tryFastBlit = !m_fastSwapMode;
m_paintingCollection->prepareGL(visibleContentRect, tryFastBlit);
m_paintingCollection->computeTexturesAmount(texturesResultPtr);
@@ -261,6 +282,9 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
&& m_drawingCollection->isReady())) {
// either a swap just occurred, or there is no more work to be done: do a full draw
m_drawingCollection->swapTiles();
+
+ if (didCollectionSwap && m_paintingCollection)
+ m_paintingCollection->prepareGL(visibleContentRect, tryFastBlit);
returnFlags |= DrawGlInfo::kStatusDraw;
} else {
// current collection not ready - invoke functor in process mode
@@ -286,6 +310,9 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
if (didCollectionSwap || m_fastSwapMode || (drawingReady && !m_paintingCollection))
m_drawingCollection->swapTiles();
+ if (didCollectionSwap && m_paintingCollection)
+ m_paintingCollection->prepareGL(visibleContentRect, tryFastBlit);
+
if (drawingReady) {
// exit fast swap mode, as content is up to date
m_fastSwapMode = false;
diff --git a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
index cc94c9c..74e663a 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.cpp
@@ -32,6 +32,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "AndroidLog.h"
+#include "BaseRenderer.h"
#include "GLUtils.h"
#include "PaintTileOperation.h"
#include "TilesManager.h"
@@ -39,6 +40,19 @@
namespace WebCore {
+TexturesGenerator::TexturesGenerator(TilesManager* instance)
+ : Thread(false)
+ , m_tilesManager(instance)
+ , m_deferredMode(false)
+ , m_renderer(0)
+{
+}
+
+TexturesGenerator::~TexturesGenerator()
+{
+ delete m_renderer;
+}
+
bool TexturesGenerator::tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter)
{
android::Mutex::Autolock lock(mRequestedOperationsLock);
@@ -83,12 +97,11 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
i++;
}
}
- delete filter;
}
status_t TexturesGenerator::readyToRun()
{
- ALOGV("Thread ready to run");
+ m_renderer = BaseRenderer::createRenderer();
return NO_ERROR;
}
@@ -165,7 +178,9 @@ bool TexturesGenerator::threadLoop()
if (currentOperation) {
ALOGV("threadLoop, painting the request with priority %d",
currentOperation->priority());
- currentOperation->run();
+ // swap out the renderer if necessary
+ BaseRenderer::swapRendererIfNeeded(m_renderer);
+ currentOperation->run(m_renderer);
}
mRequestedOperationsLock.lock();
diff --git a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h
index 290ad08..e487edb 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TexturesGenerator.h
@@ -29,7 +29,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "QueuedOperation.h"
-#include "TilePainter.h"
+#include "TransferQueue.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
@@ -43,10 +43,9 @@ class TilesManager;
class TexturesGenerator : public Thread {
public:
- TexturesGenerator(TilesManager* instance) : Thread(false)
- , m_tilesManager(instance)
- , m_deferredMode(false) { }
- virtual ~TexturesGenerator() { }
+ TexturesGenerator(TilesManager* instance);
+ virtual ~TexturesGenerator();
+
virtual status_t readyToRun();
bool tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter);
@@ -69,6 +68,7 @@ private:
TilesManager* m_tilesManager;
bool m_deferredMode;
+ BaseRenderer* m_renderer;
// defer painting for one second if best in queue has priority
// QueuedOperation::gDeferPriorityCutoff or higher
diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
index 96b189a..76be981 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
@@ -33,7 +33,7 @@
#include "AndroidLog.h"
#include "GLUtils.h"
-#include "RasterRenderer.h"
+#include "BaseRenderer.h"
#include "TextureInfo.h"
#include "TileTexture.h"
#include "TilesManager.h"
@@ -64,7 +64,6 @@ Tile::Tile(bool isLayerTile)
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("Tile");
#endif
- m_renderer = BaseRenderer::createRenderer();
}
Tile::~Tile()
@@ -74,8 +73,6 @@ Tile::~Tile()
if (m_frontTexture)
m_frontTexture->release(this);
- delete m_renderer;
-
#ifdef DEBUG_COUNT
ClassTracker::instance()->decrement("Tile");
#endif
@@ -297,7 +294,7 @@ bool Tile::isTileVisible(const IntRect& viewTileBounds)
}
// This is called from the texture generation thread
-void Tile::paintBitmap(TilePainter* painter)
+void Tile::paintBitmap(TilePainter* painter, BaseRenderer* renderer)
{
// We acquire the values below atomically. This ensures that we are reading
// values correctly across cores. Further, once we have these values they
@@ -328,8 +325,6 @@ void Tile::paintBitmap(TilePainter* painter)
return;
}
- // swap out the renderer if necessary
- BaseRenderer::swapRendererIfNeeded(m_renderer);
// setup the common renderInfo fields;
TileRenderInfo renderInfo;
renderInfo.x = x;
@@ -343,7 +338,7 @@ void Tile::paintBitmap(TilePainter* painter)
const float tileWidth = renderInfo.tileSize.width();
const float tileHeight = renderInfo.tileSize.height();
- m_renderer->renderTiledContent(renderInfo);
+ renderer->renderTiledContent(renderInfo);
m_atomicSync.lock();
diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h
index b045f1f..f467bb0 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Tile.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h
@@ -28,7 +28,6 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "BaseRenderer.h"
#include "FloatPoint.h"
#include "SkRect.h"
#include "SkRegion.h"
@@ -39,9 +38,10 @@
namespace WebCore {
+class BaseRenderer;
+class GLWebViewState;
class TextureInfo;
class TileTexture;
-class GLWebViewState;
/**
* An individual tile that is used to construct part of a webpage's BaseLayer of
@@ -107,7 +107,7 @@ public:
const FloatRect& fillPortion);
// the only thread-safe function called by the background thread
- void paintBitmap(TilePainter* painter);
+ void paintBitmap(TilePainter* painter, BaseRenderer* renderer);
bool intersectWithRect(int x, int y, int tileWidth, int tileHeight,
float scale, const SkRect& dirtyRect,
@@ -171,8 +171,6 @@ private:
// across all threads and cores.
android::Mutex m_atomicSync;
- BaseRenderer* m_renderer;
-
bool m_isLayerTile;
// the most recent GL draw before this tile was prepared. used for
diff --git a/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp b/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
index 0b4ba7b..e584b81 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
@@ -65,6 +65,10 @@
#define LAYER_TEXTURES_DESTROY_TIMEOUT 60 // If we do not need layers for 60 seconds, free the textures
+// Eventually this should be dynamically be determined, and smart scheduling
+// between the generators should be implemented
+#define NUM_TEXTURES_GENERATORS 1
+
namespace WebCore {
int TilesManager::getMaxTextureAllocation()
@@ -105,10 +109,21 @@ TilesManager::TilesManager()
m_availableTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
m_tilesTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
m_availableTilesTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
- m_pixmapsGenerationThread = new TexturesGenerator(this);
- m_pixmapsGenerationThread->run("TexturesGenerator");
+
+ m_textureGenerators = new sp<TexturesGenerator>[NUM_TEXTURES_GENERATORS];
+ for (int i = 0; i < NUM_TEXTURES_GENERATORS; i++) {
+ m_textureGenerators[i] = new TexturesGenerator(this);
+ ALOGD("Starting TG #%d, %p", i, m_textureGenerators[i].get());
+ m_textureGenerators[i]->run("TexturesGenerator");
+ }
}
+TilesManager::~TilesManager()
+{
+ delete[] m_textureGenerators;
+}
+
+
void TilesManager::allocateTextures()
{
int nbTexturesToAllocate = m_currentTextureCount - m_textures.size();
@@ -488,6 +503,29 @@ void TilesManager::updateTilesIfContextVerified()
return;
}
+void TilesManager::removeOperationsForFilter(OperationFilter* filter)
+{
+ for (int i = 0; i < NUM_TEXTURES_GENERATORS; i++)
+ m_textureGenerators[i]->removeOperationsForFilter(filter);
+ delete filter;
+}
+
+bool TilesManager::tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter)
+{
+ for (int i = 0; i < NUM_TEXTURES_GENERATORS; i++) {
+ if (m_textureGenerators[i]->tryUpdateOperationWithPainter(tile, painter))
+ return true;
+ }
+ return false;
+}
+
+void TilesManager::scheduleOperation(QueuedOperation* operation)
+{
+ // TODO: painter awareness, store prefer awareness, store preferred thread into painter
+ m_scheduleThread = (m_scheduleThread + 1) % NUM_TEXTURES_GENERATORS;
+ m_textureGenerators[m_scheduleThread]->scheduleOperation(operation);
+}
+
int TilesManager::tileWidth()
{
return TILE_WIDTH;
diff --git a/Source/WebCore/platform/graphics/android/rendering/TilesManager.h b/Source/WebCore/platform/graphics/android/rendering/TilesManager.h
index f0d2eac..0781ef6 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesManager.h
@@ -53,23 +53,9 @@ public:
return gInstance != 0;
}
- void removeOperationsForFilter(OperationFilter* filter)
- {
- m_pixmapsGenerationThread->removeOperationsForFilter(filter);
- }
-
- bool tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter)
- {
- return m_pixmapsGenerationThread->tryUpdateOperationWithPainter(tile, painter);
- }
-
- void scheduleOperation(QueuedOperation* operation)
- {
- m_pixmapsGenerationThread->scheduleOperation(operation);
- }
-
ShaderProgram* shader() { return &m_shader; }
TransferQueue* transferQueue();
+
VideoLayerManager* videoLayerManager() { return &m_videoLayerManager; }
void updateTilesIfContextVerified();
@@ -165,8 +151,15 @@ public:
return m_drawGLCount;
}
+ // operations on/for texture generator threads
+ void removeOperationsForFilter(OperationFilter* filter);
+ bool tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter);
+ void scheduleOperation(QueuedOperation* operation);
+
private:
TilesManager();
+ ~TilesManager();
+ int m_scheduleThread;
void discardTexturesVector(unsigned long long sparedDrawCount,
WTF::Vector<TileTexture*>& textures,
@@ -198,7 +191,7 @@ private:
unsigned int m_contentUpdates; // nr of successful tiled paints
unsigned int m_webkitContentUpdates; // nr of paints from webkit
- sp<TexturesGenerator> m_pixmapsGenerationThread;
+ sp<TexturesGenerator>* m_textureGenerators;
android::Mutex m_texturesLock;
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
index f37afa4..b15fa6d 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
@@ -32,6 +32,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "AndroidLog.h"
+#include "BaseRenderer.h"
#include "DrawQuadData.h"
#include "GLUtils.h"
#include "Tile.h"
@@ -389,8 +390,9 @@ void TransferQueue::updateDirtyTiles()
}
void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
- const SkBitmap& bitmap)
+ SkBitmap& bitmap)
{
+ TRACE_METHOD();
if (!tryUpdateQueueWithBitmap(renderInfo, bitmap)) {
// failed placing bitmap in queue, discard tile's texture so it will be
// re-enqueued (and repainted)
@@ -401,7 +403,7 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
}
bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
- const SkBitmap& bitmap)
+ SkBitmap& bitmap)
{
// This lock need to cover the full update since it is possible that queue
// will be cleaned up in the middle of this update without the lock.
@@ -427,7 +429,7 @@ bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
}
// b) After update the Surface Texture, now udpate the transfer queue info.
- addItemInTransferQueue(renderInfo, currentUploadType, &bitmap);
+ addItemInTransferQueue(renderInfo, currentUploadType, bitmap);
ALOGV("Bitmap updated x, y %d %d, baseTile %p",
renderInfo->x, renderInfo->y, renderInfo->baseTile);
@@ -473,7 +475,7 @@ void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo,
// Currently only called by GLUtils::updateSharedSurfaceTextureWithBitmap.
void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo,
TextureUploadType type,
- const SkBitmap* bitmap)
+ SkBitmap& bitmap)
{
m_transferQueueIndex = (m_transferQueueIndex + 1) % m_transferQueueSize;
@@ -485,15 +487,18 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo,
TileTransferData* data = &m_transferQueue[index];
addItemCommon(renderInfo, type, data);
- if (type == CpuUpload && bitmap) {
+ if (type == CpuUpload) {
// Lazily create the bitmap
if (!m_transferQueue[index].bitmap) {
m_transferQueue[index].bitmap = new SkBitmap();
- int w = bitmap->width();
- int h = bitmap->height();
- m_transferQueue[index].bitmap->setConfig(bitmap->config(), w, h);
+ int w = bitmap.width();
+ int h = bitmap.height();
+ m_transferQueue[index].bitmap->setConfig(bitmap.config(), w, h);
+ m_transferQueue[index].bitmap->allocPixels();
}
- bitmap->copyTo(m_transferQueue[index].bitmap, bitmap->config());
+ SkBitmap temp = (*m_transferQueue[index].bitmap);
+ (*m_transferQueue[index].bitmap) = bitmap;
+ bitmap = temp;
}
m_emptyItemCount--;
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
index c0835d7..55011b0 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
@@ -115,11 +115,11 @@ public:
// insert the bitmap into the queue, mark the tile dirty if failing
void updateQueueWithBitmap(const TileRenderInfo* renderInfo,
- const SkBitmap& bitmap);
+ SkBitmap& bitmap);
void addItemInTransferQueue(const TileRenderInfo* info,
TextureUploadType type,
- const SkBitmap* bitmap);
+ SkBitmap& bitmap);
// Check if the item @ index is ready for update.
// The lock will be done when returning true.
bool readyForUpdate();
@@ -145,7 +145,7 @@ public:
private:
// return true if successfully inserted into queue
bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
- const SkBitmap& bitmap);
+ SkBitmap& bitmap);
bool getHasGLContext();
void setHasGLContext(bool hasContext);
void emptyAndAbandonQueue();
diff --git a/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp
new file mode 100644
index 0000000..1899557
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2012, 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.
+ */
+
+#define LOG_TAG "LinearAllocator"
+#define LOG_NDEBUG 1
+
+#include "config.h"
+#include "LinearAllocator.h"
+
+#include "AndroidLog.h"
+
+namespace WebCore {
+
+// The ideal size of a page allocation
+#define TARGET_PAGE_SIZE 16384 // 16kb
+
+// our pool needs to big enough to hold at least this many items
+#define MIN_OBJECT_COUNT 4
+
+#if LOG_NDEBUG
+#define ADD_ALLOCATION(size)
+#define RM_ALLOCATION(size)
+#else
+#include <utils/Thread.h>
+static size_t s_totalAllocations = 0;
+static double s_lastLogged = 0;
+static android::Mutex s_mutex;
+
+static void _logUsageLocked() {
+ double now = currentTimeMS();
+ if (now - s_lastLogged > 5) {
+ s_lastLogged = now;
+ ALOGV("Total memory usage: %d kb", s_totalAllocations / 1024);
+ }
+}
+
+static void _addAllocation(size_t size) {
+ android::AutoMutex lock(s_mutex);
+ s_totalAllocations += size;
+ _logUsageLocked();
+}
+
+#define ADD_ALLOCATION(size) _addAllocation(size);
+#define RM_ALLOCATION(size) _addAllocation(-size);
+#endif
+
+class LinearAllocator::Page {
+public:
+ Page* next() { return m_nextPage; }
+ void setNext(Page* next) { m_nextPage = next; }
+
+ Page()
+ : m_nextPage(0)
+ {}
+
+ void* start()
+ {
+ return (void*) (((unsigned)this) + sizeof(LinearAllocator::Page));
+ }
+
+ void* end(int pageSize)
+ {
+ return (void*) (((unsigned)start()) + pageSize);
+ }
+
+private:
+ Page(const Page& other) {}
+ Page* m_nextPage;
+};
+
+LinearAllocator::LinearAllocator(size_t averageAllocSize)
+ : m_next(0)
+ , m_currentPage(0)
+ , m_pages(0)
+{
+ if (averageAllocSize) {
+ int usable_page_size = TARGET_PAGE_SIZE - sizeof(LinearAllocator::Page);
+ int pcount = usable_page_size / averageAllocSize;
+ if (pcount < MIN_OBJECT_COUNT)
+ pcount = MIN_OBJECT_COUNT;
+ m_pageSize = pcount * averageAllocSize + sizeof(LinearAllocator::Page);
+ } else
+ m_pageSize = TARGET_PAGE_SIZE;
+ m_maxAllocSize = (m_pageSize - sizeof(LinearAllocator::Page));
+}
+
+LinearAllocator::~LinearAllocator(void)
+{
+ Page* p = m_pages;
+ while (p) {
+ Page* next = p->next();
+ delete p;
+ RM_ALLOCATION(m_pageSize);
+ p = next;
+ }
+}
+
+void* LinearAllocator::start(Page* p)
+{
+ return ((char*)p) + sizeof(Page);
+}
+
+void* LinearAllocator::end(Page* p)
+{
+ return ((char*)p) + m_pageSize;
+}
+
+void LinearAllocator::ensureNext(size_t size)
+{
+ if (m_next && ((char*)m_next + size) <= end(m_currentPage))
+ return;
+ Page* p = newPage();
+ if (m_currentPage)
+ m_currentPage->setNext(p);
+ m_currentPage = p;
+ if (!m_pages)
+ m_pages = m_currentPage;
+ m_next = start(m_currentPage);
+}
+
+unsigned LinearAllocator::memusage()
+{
+ unsigned memusage = 0;
+ Page* p = m_pages;
+ while (p) {
+ memusage += m_pageSize;
+ p = p->next();
+ }
+ return memusage;
+}
+
+void* LinearAllocator::alloc(size_t size)
+{
+ if (size > m_maxAllocSize) {
+ ALOGE("Allocation too large! (%d exceeds max size %d)", size, m_maxAllocSize);
+ return 0;
+ }
+ ensureNext(size);
+ void* ptr = m_next;
+ m_next = ((char*)m_next) + size;
+ return ptr;
+}
+
+void LinearAllocator::rewindTo(void* ptr)
+{
+ // Don't bother rewinding across pages
+ if (ptr >= start(m_currentPage) && ptr < end(m_currentPage))
+ m_next = ptr;
+}
+
+LinearAllocator::Page* LinearAllocator::newPage()
+{
+ ADD_ALLOCATION(m_pageSize);
+ void* buf = malloc(m_pageSize);
+ return new (buf) Page();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.h
index 9d7b530..1f3265c 100644
--- a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h
+++ b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.h
@@ -23,50 +23,39 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef GraphicsOperationCollection_h
-#define GraphicsOperationCollection_h
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "Color.h"
-#include "GraphicsOperation.h"
-#include "IntRect.h"
-#include "SkRefCnt.h"
+#ifndef LinearAllocator_h
+#define LinearAllocator_h
namespace WebCore {
-class PlatformGraphicsContext;
-
-class GraphicsOperationCollection : public SkRefCnt {
+class LinearAllocator
+{
public:
- GraphicsOperationCollection(const IntRect& drawArea);
- ~GraphicsOperationCollection();
+ LinearAllocator(size_t averageAllocSize = 0);
+ ~LinearAllocator();
- void apply(PlatformGraphicsContext* context);
- void append(GraphicsOperation::Operation* operation);
-
- bool isEmpty();
+ void* alloc(size_t size);
+ void rewindTo(void*);
private:
- IntRect m_drawArea;
- Vector<GraphicsOperation::Operation*> m_operations;
-};
+ LinearAllocator(const LinearAllocator& other);
-class AutoGraphicsOperationCollection {
-public:
- AutoGraphicsOperationCollection(const IntRect& area);
- ~AutoGraphicsOperationCollection();
- GraphicsContext* context() { return m_graphicsContext; }
- GraphicsOperationCollection* picture() { return m_graphicsOperationCollection; }
+ class Page;
-private:
- GraphicsOperationCollection* m_graphicsOperationCollection;
- PlatformGraphicsContext* m_platformGraphicsContext;
- GraphicsContext* m_graphicsContext;
-};
+ Page* newPage();
+ void ensureNext(size_t size);
+ void* start(Page *p);
+ void* end(Page* p);
-}
+ unsigned memusage();
+
+ size_t m_pageSize;
+ size_t m_maxAllocSize;
+ void* m_next;
+ Page* m_currentPage;
+ Page* m_pages;
+};
-#endif // USE(ACCELERATED_COMPOSITING)
+} // namespace WebCore
-#endif // GraphicsOperationCollection_h
+#endif // LinearAllocator_h
diff --git a/Source/WebCore/platform/mock/GeolocationServiceMock.cpp b/Source/WebCore/platform/mock/GeolocationServiceMock.cpp
index c3ba7b4..b254cb8 100644
--- a/Source/WebCore/platform/mock/GeolocationServiceMock.cpp
+++ b/Source/WebCore/platform/mock/GeolocationServiceMock.cpp
@@ -80,12 +80,7 @@ void GeolocationServiceMock::setError(PassRefPtr<PositionError> error)
makeGeolocationCallbackFromAllInstances();
}
-#if PLATFORM(ANDROID)
-// TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
-bool GeolocationServiceMock::startUpdating(PositionOptions*, bool /* suspend */)
-#else
bool GeolocationServiceMock::startUpdating(PositionOptions*)
-#endif
{
m_isActive = true;
m_timer.startOneShot(0);
diff --git a/Source/WebCore/platform/mock/GeolocationServiceMock.h b/Source/WebCore/platform/mock/GeolocationServiceMock.h
index 1b4db93..7d02797 100755
--- a/Source/WebCore/platform/mock/GeolocationServiceMock.h
+++ b/Source/WebCore/platform/mock/GeolocationServiceMock.h
@@ -46,12 +46,7 @@ class GeolocationServiceMock : public GeolocationService {
GeolocationServiceMock(GeolocationServiceClient*);
virtual ~GeolocationServiceMock();
-#if PLATFORM(ANDROID)
- // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
- virtual bool startUpdating(PositionOptions*, bool suspend);
-#else
virtual bool startUpdating(PositionOptions*);
-#endif
virtual void stopUpdating();
static void setPosition(PassRefPtr<Geoposition> position);
diff --git a/Source/WebCore/plugins/android/PluginViewAndroid.cpp b/Source/WebCore/plugins/android/PluginViewAndroid.cpp
index fdf6e03..24a14aa 100644
--- a/Source/WebCore/plugins/android/PluginViewAndroid.cpp
+++ b/Source/WebCore/plugins/android/PluginViewAndroid.cpp
@@ -55,7 +55,6 @@
#include "Touch.h"
#include "TouchEvent.h"
#include "TouchList.h"
-#include "android_graphics.h"
#include "SkCanvas.h"
#include "npruntime_impl.h"
// #include "runtime_root.h"
@@ -405,7 +404,7 @@ bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPErr
// our interface query is valid with no NPP instance
*result = NPERR_GENERIC_ERROR;
- switch (variable) {
+ switch ((int)variable) {
case NPNVisOfflineBool: {
if (value != NULL) {
bool* retValue = static_cast<bool*>(value);
@@ -422,7 +421,7 @@ bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPErr
return true;
}
default:
- ; // do nothing
+ break; // do nothing
}
(void)anp_getInterface(variable, value, result);
@@ -490,7 +489,7 @@ void PluginView::setNPWindowIfNeeded()
bool PluginView::platformGetValue(NPNVariable variable, void* value, NPError* result)
{
- switch (variable) {
+ switch ((int)variable) {
case NPNVWindowNPObject: {
NPObject* windowScriptObject =
m_parentFrame->script()->windowScriptNPObject();
@@ -581,7 +580,7 @@ NPError PluginView::platformSetValue(NPPVariable variable, void* value)
{
NPError error = NPERR_GENERIC_ERROR;
- switch (variable) {
+ switch ((int)variable) {
case kRequestDrawingModel_ANPSetValue: {
ANPDrawingModel model = reinterpret_cast<ANPDrawingModel>(value);
if (m_window->setDrawingModel(model))
@@ -690,15 +689,12 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
notification of its global position change.
*/
updatePluginWidget();
- SkCanvas* canvas = context->platformContext()->getCanvas();
- if (!canvas)
- return;
- m_window->setSurfaceClip(canvas->getTotalClip().getBounds());
+ m_window->setSurfaceClip(context->platformContext()->getTotalClipBounds());
} else {
m_window->inval(rect, false);
context->save();
context->translate(frame.x(), frame.y());
- m_window->draw(android_gc2canvas(context));
+ m_window->draw(context->platformContext());
context->restore();
}