diff options
Diffstat (limited to 'Source')
64 files changed, 810 insertions, 680 deletions
diff --git a/Source/JavaScriptCore/wtf/Platform.h b/Source/JavaScriptCore/wtf/Platform.h index 5ac08d1..41850ee 100644 --- a/Source/JavaScriptCore/wtf/Platform.h +++ b/Source/JavaScriptCore/wtf/Platform.h @@ -780,8 +780,6 @@ #define ANDROID_ANIMATED_GIF // apple-touch-icon support in <link> tags #define ANDROID_APPLE_TOUCH_ICON -// track changes to the style that may change what is drawn -#define ANDROID_STYLE_VERSION // This is present in JavaScriptCore/config.h, which Android does not use. #define WTF_CHANGES 1 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..4ede2a8 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); 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/platform/android/PlatformBridge.h b/Source/WebCore/platform/android/PlatformBridge.h index e48e50c..5af5d2d 100644 --- a/Source/WebCore/platform/android/PlatformBridge.h +++ b/Source/WebCore/platform/android/PlatformBridge.h @@ -132,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/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/context/GraphicsOperation.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h index 927ff0a..942d9a6 100644 --- a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h +++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h @@ -48,7 +48,7 @@ namespace WebCore { namespace GraphicsOperation { -class Operation : public SkRefCnt { +class Operation { public: typedef enum { UndefinedOperation // State management @@ -71,10 +71,6 @@ public: , SetStrokeShaderOperation , SetStrokeStyleOperation , SetStrokeThicknessOperation - // Paint setup - , SetupPaintFillOperation - , SetupPaintShadowOperation - , SetupPaintStrokeOperation // Matrix operations , ConcatCTMOperation , ScaleOperation @@ -109,7 +105,7 @@ public: virtual ~Operation() {} virtual OperationType type() { return UndefinedOperation; } virtual String parameters() { return ""; } - String name() + const char* name() { switch (type()) { TYPE_CASE(UndefinedOperation) @@ -133,10 +129,6 @@ public: 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) @@ -375,48 +367,6 @@ private: }; //************************************** -// 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; -}; - -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; -}; - -//************************************** // Matrix operations //************************************** @@ -773,7 +723,6 @@ public: : 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); diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp index 9e6208d..1ebb369 100644 --- a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp +++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp @@ -13,49 +13,47 @@ namespace WebCore { -GraphicsOperationCollection::GraphicsOperationCollection(const IntRect& drawArea) - : m_drawArea(drawArea) +GraphicsOperationCollection::GraphicsOperationCollection() { } GraphicsOperationCollection::~GraphicsOperationCollection() { - for (unsigned int i = 0; i < m_operations.size(); i++) - SkSafeUnref(m_operations[i]); + clear(); } -void GraphicsOperationCollection::apply(PlatformGraphicsContext* context) +void GraphicsOperationCollection::apply(PlatformGraphicsContext* context) const { - 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()); + size_t size = m_operations.size(); + for (size_t i = 0; i < size; i++) m_operations[i]->apply(context); - } } -void GraphicsOperationCollection::append(GraphicsOperation::Operation* operation) +void GraphicsOperationCollection::adoptAndAppend(GraphicsOperation::Operation* operation) { m_operations.append(operation); } -bool GraphicsOperationCollection::isEmpty() +void GraphicsOperationCollection::transferFrom(GraphicsOperationCollection& moveFrom) { - return !m_operations.size(); + size_t size = moveFrom.m_operations.size(); + m_operations.reserveCapacity(m_operations.size() + size); + for (size_t i = 0; i < size; i++) + m_operations.append(moveFrom.m_operations[i]); + moveFrom.m_operations.clear(); } -AutoGraphicsOperationCollection::AutoGraphicsOperationCollection(const IntRect& area) +bool GraphicsOperationCollection::isEmpty() { - m_graphicsOperationCollection = new GraphicsOperationCollection(area); - m_platformGraphicsContext = new PlatformGraphicsContextRecording(m_graphicsOperationCollection); - m_graphicsContext = new GraphicsContext(m_platformGraphicsContext); + return !m_operations.size(); } -AutoGraphicsOperationCollection::~AutoGraphicsOperationCollection() +void GraphicsOperationCollection::clear() { - SkSafeUnref(m_graphicsOperationCollection); - delete m_graphicsContext; - delete m_platformGraphicsContext; + size_t size = m_operations.size(); + for (size_t i = 0; i < size; i++) + delete m_operations[i]; + m_operations.clear(); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h index 9d7b530..713d06e 100644 --- a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h +++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h @@ -28,9 +28,7 @@ #if USE(ACCELERATED_COMPOSITING) -#include "Color.h" #include "GraphicsOperation.h" -#include "IntRect.h" #include "SkRefCnt.h" namespace WebCore { @@ -39,32 +37,23 @@ class PlatformGraphicsContext; class GraphicsOperationCollection : public SkRefCnt { public: - GraphicsOperationCollection(const IntRect& drawArea); + GraphicsOperationCollection(); ~GraphicsOperationCollection(); - void apply(PlatformGraphicsContext* context); - void append(GraphicsOperation::Operation* operation); + void apply(PlatformGraphicsContext* context) const; + void adoptAndAppend(GraphicsOperation::Operation* operation); + + // Moves all the operations from moveFrom into this collection + // moveFrom will be empty after this call + void transferFrom(GraphicsOperationCollection& moveFrom); bool isEmpty(); + void clear(); private: - IntRect m_drawArea; Vector<GraphicsOperation::Operation*> m_operations; }; -class AutoGraphicsOperationCollection { -public: - AutoGraphicsOperationCollection(const IntRect& area); - ~AutoGraphicsOperationCollection(); - GraphicsContext* context() { return m_graphicsContext; } - GraphicsOperationCollection* picture() { return m_graphicsOperationCollection; } - -private: - GraphicsOperationCollection* m_graphicsOperationCollection; - PlatformGraphicsContext* m_platformGraphicsContext; - GraphicsContext* m_graphicsContext; -}; - } #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 3b37693..f9d7f21 100644 --- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp +++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp @@ -246,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) @@ -333,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) diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h index 1916014..69ccdaf 100644 --- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h +++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.h @@ -61,16 +61,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); diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp index d96124d..3b60ec0 100644 --- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp +++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp @@ -18,8 +18,8 @@ namespace WebCore { PlatformGraphicsContextRecording::PlatformGraphicsContextRecording(GraphicsOperationCollection* picture) : PlatformGraphicsContext() - , mGraphicsOperationCollection(picture) , mPicture(0) + , mGraphicsOperationCollection(picture) { } @@ -41,7 +41,7 @@ void PlatformGraphicsContextRecording::endRecording(int type) return; mPicture->endRecording(); GraphicsOperation::DrawComplexText* text = new GraphicsOperation::DrawComplexText(mPicture); - mGraphicsOperationCollection->append(text); + appendDrawingOperation(text); mPicture = 0; } @@ -52,24 +52,29 @@ void PlatformGraphicsContextRecording::endRecording(int type) void PlatformGraphicsContextRecording::beginTransparencyLayer(float opacity) { - mGraphicsOperationCollection->append(new GraphicsOperation::BeginTransparencyLayer(opacity)); + appendStateOperation(new GraphicsOperation::BeginTransparencyLayer(opacity)); } void PlatformGraphicsContextRecording::endTransparencyLayer() { - mGraphicsOperationCollection->append(new GraphicsOperation::EndTransparencyLayer()); + appendStateOperation(new GraphicsOperation::EndTransparencyLayer()); } void PlatformGraphicsContextRecording::save() { PlatformGraphicsContext::save(); - mGraphicsOperationCollection->append(new GraphicsOperation::Save()); + flushPendingOperations(); + mPendingOperations.adoptAndAppend(new GraphicsOperation::Save()); } void PlatformGraphicsContextRecording::restore() { PlatformGraphicsContext::restore(); - mGraphicsOperationCollection->append(new GraphicsOperation::Restore()); + // If we have pending operations then the save/restore pair is empty and a no-op, discard it + if (mPendingOperations.isEmpty()) + mGraphicsOperationCollection->adoptAndAppend(new GraphicsOperation::Restore()); + else + mPendingOperations.clear(); } //************************************** @@ -79,86 +84,98 @@ void PlatformGraphicsContextRecording::restore() void PlatformGraphicsContextRecording::setAlpha(float alpha) { PlatformGraphicsContext::setAlpha(alpha); - mGraphicsOperationCollection->append(new GraphicsOperation::SetAlpha(alpha)); + appendStateOperation(new GraphicsOperation::SetAlpha(alpha)); } void PlatformGraphicsContextRecording::setCompositeOperation(CompositeOperator op) { PlatformGraphicsContext::setCompositeOperation(op); - mGraphicsOperationCollection->append(new GraphicsOperation::SetCompositeOperation(op)); + appendStateOperation(new GraphicsOperation::SetCompositeOperation(op)); } -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)) { + appendStateOperation(new GraphicsOperation::SetFillColor(c)); + 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)) { + appendStateOperation(new GraphicsOperation::SetFillShader(fillShader)); + return true; + } + return false; } void PlatformGraphicsContextRecording::setLineCap(LineCap cap) { PlatformGraphicsContext::setLineCap(cap); - mGraphicsOperationCollection->append(new GraphicsOperation::SetLineCap(cap)); + appendStateOperation(new GraphicsOperation::SetLineCap(cap)); } void PlatformGraphicsContextRecording::setLineDash(const DashArray& dashes, float dashOffset) { PlatformGraphicsContext::setLineDash(dashes, dashOffset); - mGraphicsOperationCollection->append(new GraphicsOperation::SetLineDash(dashes, dashOffset)); + appendStateOperation(new GraphicsOperation::SetLineDash(dashes, dashOffset)); } void PlatformGraphicsContextRecording::setLineJoin(LineJoin join) { PlatformGraphicsContext::setLineJoin(join); - mGraphicsOperationCollection->append(new GraphicsOperation::SetLineJoin(join)); + appendStateOperation(new GraphicsOperation::SetLineJoin(join)); } void PlatformGraphicsContextRecording::setMiterLimit(float limit) { PlatformGraphicsContext::setMiterLimit(limit); - mGraphicsOperationCollection->append(new GraphicsOperation::SetMiterLimit(limit)); + appendStateOperation(new GraphicsOperation::SetMiterLimit(limit)); } 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)); + appendStateOperation(new GraphicsOperation::SetShadow(radius, dx, dy, c)); } void PlatformGraphicsContextRecording::setShouldAntialias(bool useAA) { m_state->useAA = useAA; PlatformGraphicsContext::setShouldAntialias(useAA); - mGraphicsOperationCollection->append(new GraphicsOperation::SetShouldAntialias(useAA)); + appendStateOperation(new GraphicsOperation::SetShouldAntialias(useAA)); } -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)) { + appendStateOperation(new GraphicsOperation::SetStrokeColor(c)); + 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)) { + appendStateOperation(new GraphicsOperation::SetStrokeShader(strokeShader)); + return true; + } + return false; } void PlatformGraphicsContextRecording::setStrokeStyle(StrokeStyle style) { PlatformGraphicsContext::setStrokeStyle(style); - mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeStyle(style)); + appendStateOperation(new GraphicsOperation::SetStrokeStyle(style)); } void PlatformGraphicsContextRecording::setStrokeThickness(float f) { PlatformGraphicsContext::setStrokeThickness(f); - mGraphicsOperationCollection->append(new GraphicsOperation::SetStrokeThickness(f)); + appendStateOperation(new GraphicsOperation::SetStrokeThickness(f)); } //************************************** @@ -168,26 +185,26 @@ void PlatformGraphicsContextRecording::setStrokeThickness(float f) void PlatformGraphicsContextRecording::concatCTM(const AffineTransform& affine) { mCurrentMatrix.preConcat(affine); - mGraphicsOperationCollection->append(new GraphicsOperation::ConcatCTM(affine)); + appendStateOperation(new GraphicsOperation::ConcatCTM(affine)); } void PlatformGraphicsContextRecording::rotate(float angleInRadians) { float value = angleInRadians * (180.0f / 3.14159265f); mCurrentMatrix.preRotate(SkFloatToScalar(value)); - mGraphicsOperationCollection->append(new GraphicsOperation::Rotate(angleInRadians)); + appendStateOperation(new GraphicsOperation::Rotate(angleInRadians)); } void PlatformGraphicsContextRecording::scale(const FloatSize& size) { mCurrentMatrix.preScale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height())); - mGraphicsOperationCollection->append(new GraphicsOperation::Scale(size)); + appendStateOperation(new GraphicsOperation::Scale(size)); } void PlatformGraphicsContextRecording::translate(float x, float y) { mCurrentMatrix.preTranslate(SkFloatToScalar(x), SkFloatToScalar(y)); - mGraphicsOperationCollection->append(new GraphicsOperation::Translate(x, y)); + appendStateOperation(new GraphicsOperation::Translate(x, y)); } const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix() @@ -202,7 +219,7 @@ const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix() void PlatformGraphicsContextRecording::addInnerRoundedRectClip(const IntRect& rect, int thickness) { - mGraphicsOperationCollection->append(new GraphicsOperation::InnerRoundedRectClip(rect, thickness)); + appendStateOperation(new GraphicsOperation::InnerRoundedRectClip(rect, thickness)); } void PlatformGraphicsContextRecording::canvasClip(const Path& path) @@ -212,12 +229,12 @@ void PlatformGraphicsContextRecording::canvasClip(const Path& path) void PlatformGraphicsContextRecording::clip(const FloatRect& rect) { - mGraphicsOperationCollection->append(new GraphicsOperation::Clip(rect)); + appendStateOperation(new GraphicsOperation::Clip(rect)); } void PlatformGraphicsContextRecording::clip(const Path& path) { - mGraphicsOperationCollection->append(new GraphicsOperation::ClipPath(path)); + appendStateOperation(new GraphicsOperation::ClipPath(path)); } void PlatformGraphicsContextRecording::clipConvexPolygon(size_t numPoints, @@ -228,24 +245,24 @@ void PlatformGraphicsContextRecording::clipConvexPolygon(size_t numPoints, void PlatformGraphicsContextRecording::clipOut(const IntRect& r) { - mGraphicsOperationCollection->append(new GraphicsOperation::ClipOut(r)); + appendStateOperation(new GraphicsOperation::ClipOut(r)); } void PlatformGraphicsContextRecording::clipOut(const Path& path) { - mGraphicsOperationCollection->append(new GraphicsOperation::ClipPath(path, true)); + appendStateOperation(new GraphicsOperation::ClipPath(path, true)); } void PlatformGraphicsContextRecording::clipPath(const Path& pathToClip, WindRule clipRule) { GraphicsOperation::ClipPath* operation = new GraphicsOperation::ClipPath(pathToClip); operation->setWindRule(clipRule); - mGraphicsOperationCollection->append(operation); + appendStateOperation(operation); } void PlatformGraphicsContextRecording::clearRect(const FloatRect& rect) { - mGraphicsOperationCollection->append(new GraphicsOperation::ClearRect(rect)); + appendDrawingOperation(new GraphicsOperation::ClearRect(rect)); } //************************************** @@ -256,14 +273,14 @@ 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 GraphicsOperation::DrawBitmapPattern(bitmap, matrix, compositeOp, 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 GraphicsOperation::DrawBitmapRect(bitmap, *src, dst, op)); } void PlatformGraphicsContextRecording::drawConvexPolygon(size_t numPoints, @@ -275,7 +292,7 @@ void PlatformGraphicsContextRecording::drawConvexPolygon(size_t numPoints, void PlatformGraphicsContextRecording::drawEllipse(const IntRect& rect) { - mGraphicsOperationCollection->append(new GraphicsOperation::DrawEllipse(rect)); + appendDrawingOperation(new GraphicsOperation::DrawEllipse(rect)); } void PlatformGraphicsContextRecording::drawFocusRing(const Vector<IntRect>& rects, @@ -307,33 +324,33 @@ void PlatformGraphicsContextRecording::drawHighlightForText( void PlatformGraphicsContextRecording::drawLine(const IntPoint& point1, const IntPoint& point2) { - mGraphicsOperationCollection->append(new GraphicsOperation::DrawLine(point1, point2)); + appendDrawingOperation(new GraphicsOperation::DrawLine(point1, point2)); } void PlatformGraphicsContextRecording::drawLineForText(const FloatPoint& pt, float width) { - mGraphicsOperationCollection->append(new GraphicsOperation::DrawLineForText(pt, width)); + appendDrawingOperation(new GraphicsOperation::DrawLineForText(pt, width)); } void PlatformGraphicsContextRecording::drawLineForTextChecking(const FloatPoint& pt, float width, GraphicsContext::TextCheckingLineStyle lineStyle) { - mGraphicsOperationCollection->append(new GraphicsOperation::DrawLineForTextChecking(pt, width, lineStyle)); + appendDrawingOperation(new GraphicsOperation::DrawLineForTextChecking(pt, width, lineStyle)); } void PlatformGraphicsContextRecording::drawRect(const IntRect& rect) { - mGraphicsOperationCollection->append(new GraphicsOperation::DrawRect(rect)); + appendDrawingOperation(new GraphicsOperation::DrawRect(rect)); } void PlatformGraphicsContextRecording::fillPath(const Path& pathToFill, WindRule fillRule) { - mGraphicsOperationCollection->append(new GraphicsOperation::FillPath(pathToFill, fillRule)); + appendDrawingOperation(new GraphicsOperation::FillPath(pathToFill, fillRule)); } void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect) { - mGraphicsOperationCollection->append(new GraphicsOperation::FillRect(rect)); + appendDrawingOperation(new GraphicsOperation::FillRect(rect)); } void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect, @@ -341,7 +358,7 @@ void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect, { GraphicsOperation::FillRect* operation = new GraphicsOperation::FillRect(rect); operation->setColor(color); - mGraphicsOperationCollection->append(operation); + appendDrawingOperation(operation); } void PlatformGraphicsContextRecording::fillRoundedRect( @@ -349,25 +366,47 @@ void PlatformGraphicsContextRecording::fillRoundedRect( const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color) { - mGraphicsOperationCollection->append(new GraphicsOperation::FillRoundedRect(rect, topLeft, + appendDrawingOperation(new GraphicsOperation::FillRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, color)); } void PlatformGraphicsContextRecording::strokeArc(const IntRect& r, int startAngle, int angleSpan) { - mGraphicsOperationCollection->append(new GraphicsOperation::StrokeArc(r, startAngle, angleSpan)); + appendDrawingOperation(new GraphicsOperation::StrokeArc(r, startAngle, angleSpan)); } void PlatformGraphicsContextRecording::strokePath(const Path& pathToStroke) { - mGraphicsOperationCollection->append(new GraphicsOperation::StrokePath(pathToStroke)); + appendDrawingOperation(new GraphicsOperation::StrokePath(pathToStroke)); } void PlatformGraphicsContextRecording::strokeRect(const FloatRect& rect, float lineWidth) { - mGraphicsOperationCollection->append(new GraphicsOperation::StrokeRect(rect, lineWidth)); + appendDrawingOperation(new GraphicsOperation::StrokeRect(rect, lineWidth)); +} + +void PlatformGraphicsContextRecording::appendDrawingOperation(GraphicsOperation::Operation* operation) +{ + flushPendingOperations(); + mGraphicsOperationCollection->adoptAndAppend(operation); } +void PlatformGraphicsContextRecording::appendStateOperation(GraphicsOperation::Operation* operation) +{ + // If we have pending operations, we are in a save/restore pair that we are not + // sure whether or not it does any drawing in which case we add this operation to + // the pending operations + if (mPendingOperations.isEmpty()) + mGraphicsOperationCollection->adoptAndAppend(operation); + else + mPendingOperations.adoptAndAppend(operation); +} + +void PlatformGraphicsContextRecording::flushPendingOperations() +{ + if (!mPendingOperations.isEmpty()) + mGraphicsOperationCollection->transferFrom(mPendingOperations); +} } // WebCore diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h index ebb0075..1cce5a6 100644 --- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h +++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h @@ -28,8 +28,12 @@ #include "PlatformGraphicsContext.h" +#include "GraphicsOperationCollection.h" + namespace WebCore { -class GraphicsOperationCollection; +namespace GraphicsOperation { +class Operation; +} class PlatformGraphicsContextRecording : public PlatformGraphicsContext { public: @@ -38,9 +42,6 @@ public: virtual bool isPaintingDisabled(); virtual SkCanvas* getCanvas() { return 0; } - GraphicsOperationCollection* mGraphicsOperationCollection; - SkMatrix mCurrentMatrix; - virtual SkCanvas* recordingCanvas(); virtual void endRecording(int type = 0); @@ -55,16 +56,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); @@ -121,7 +122,15 @@ private: return false; } + void appendDrawingOperation(GraphicsOperation::Operation* operation); + void appendStateOperation(GraphicsOperation::Operation* operation); + void flushPendingOperations(); + SkPicture* mPicture; + SkMatrix mCurrentMatrix; + + GraphicsOperationCollection* mGraphicsOperationCollection; + GraphicsOperationCollection mPendingOperations; }; } diff --git a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp index 869c7b6..d59674b 100644 --- a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp @@ -463,8 +463,7 @@ public: private: void setupFontForScriptRun(); - const FontPlatformData* setupComplexFont(FallbackScripts script, - const FontPlatformData& platformData); + const FontPlatformData* setupComplexFont(HB_Script script, const FontPlatformData& platformData); HB_FontRec* allocHarfbuzzFont(); void deleteGlyphArrays(); void createGlyphArrays(int); @@ -660,8 +659,7 @@ void TextRunWalker::setWordAndLetterSpacing(int wordSpacingAdjustment, } const FontPlatformData* TextRunWalker::setupComplexFont( - FallbackScripts script, - const FontPlatformData& platformData) + HB_Script script, const FontPlatformData& platformData) { static FallbackHash fallbackPlatformData; @@ -671,15 +669,19 @@ const FontPlatformData* TextRunWalker::setupComplexFont( // italic, then bold italic. additional fake style bits can be added. int scriptStyleIndex = script; if (platformData.isFakeBold()) - scriptStyleIndex += kFallbackScriptNumber; + scriptStyleIndex += HB_ScriptCount; if (platformData.isFakeItalic()) - scriptStyleIndex += kFallbackScriptNumber << 1; + scriptStyleIndex += HB_ScriptCount << 1; FallbackFontKey key(scriptStyleIndex, platformData.size()); FontPlatformData* newPlatformData = 0; if (!fallbackPlatformData.contains(key)) { - SkTypeface* typeface = SkCreateTypefaceForScript(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); @@ -697,61 +699,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(kBengali_FallbackScript, platformData); - break; - case HB_Script_Devanagari: - complexPlatformData = setupComplexFont(kDevanagari_FallbackScript, platformData); - break; - case HB_Script_Hebrew: - switch (platformData.typeface()->style()) { - case SkTypeface::kBold: - case SkTypeface::kBoldItalic: - complexPlatformData = setupComplexFont(kHebrewBold_FallbackScript, platformData); - break; - case SkTypeface::kNormal: - case SkTypeface::kItalic: - default: - complexPlatformData = setupComplexFont(kHebrewRegular_FallbackScript, platformData); - break; - } - break; - case HB_Script_Kannada: - complexPlatformData = setupComplexFont(kKannada_FallbackScript, platformData); - break; - case HB_Script_Malayalam: - complexPlatformData = setupComplexFont(kMalayalam_FallbackScript, platformData); - break; - case HB_Script_Arabic: - complexPlatformData = setupComplexFont(kArabic_FallbackScript, platformData); - break; - case HB_Script_Tamil: - switch (platformData.typeface()->style()) { - case SkTypeface::kBold: - case SkTypeface::kBoldItalic: - complexPlatformData = setupComplexFont(kTamilBold_FallbackScript, platformData); - break; - case SkTypeface::kNormal: - case SkTypeface::kItalic: - default: - complexPlatformData = setupComplexFont(kTamilRegular_FallbackScript, platformData); - break; - } - break; - case HB_Script_Telugu: - complexPlatformData = setupComplexFont(kTelugu_FallbackScript, platformData); - break; - case HB_Script_Thai: - complexPlatformData = setupComplexFont(kThai_FallbackScript, 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); 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 d709a9c..438d96c 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp @@ -289,6 +289,9 @@ void LayerAndroid::addDirtyArea() IntRect dirtyArea(area.x(), area.y(), area.width(), area.height()); state()->addDirtyArea(dirtyArea); + + for (int i = 0; i < countChildren(); i++) + getChild(i)->addDirtyArea(); } void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim) @@ -598,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" : "", @@ -951,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 79c84b4..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); @@ -274,7 +273,9 @@ public: void setIntrinsicallyComposited(bool intCom) { m_intrinsicallyComposited = intCom; } virtual bool needsIsolatedSurface() { - return (needsTexture() && m_intrinsicallyComposited) || m_animations.size(); + return (needsTexture() && m_intrinsicallyComposited) + || m_animations.size() + || m_imageCRC; } int setHwAccelerated(bool hwAccelerated); @@ -290,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/MediaLayer.h b/Source/WebCore/platform/graphics/android/layers/MediaLayer.h index 2f39d74..8e04681 100644 --- a/Source/WebCore/platform/graphics/android/layers/MediaLayer.h +++ b/Source/WebCore/platform/graphics/android/layers/MediaLayer.h @@ -39,6 +39,7 @@ public: virtual bool drawGL(bool layerTilesDisabled); virtual void paintBitmapGL() const { }; virtual bool needsTexture() { return false; } + virtual bool needsIsolatedSurface() { return true; } virtual bool isMedia() const { return true; } virtual LayerAndroid* copy() const { return new MediaLayer(*this); } 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/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h index dd88a85..5ebf615 100644 --- a/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/VideoLayerAndroid.h @@ -55,9 +55,10 @@ public: virtual bool isVideo() const { return true; } virtual LayerAndroid* copy() const { return new VideoLayerAndroid(*this); } - // The following 3 functions are called in UI thread only. + // The following functions are called in UI thread only. virtual bool drawGL(bool layerTilesDisabled); void setSurfaceTexture(sp<SurfaceTexture> texture, int textureName, PlayerState playerState); + virtual bool needsIsolatedSurface() { return true; } private: void init(); diff --git a/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp index a68c01a..d5a701b 100644 --- a/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp @@ -446,7 +446,7 @@ bool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo, } void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo, - const SkBitmap& bitmap) + SkBitmap& bitmap) { if (!renderInfo) return; @@ -472,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 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/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 8fb4d12..5c78ad9 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() @@ -68,9 +65,13 @@ 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(); @@ -79,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); @@ -93,14 +97,16 @@ 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) { - const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false); - renderInfo.isPureColor = GLUtils::isPureColorBitmap(bitmap, renderInfo.pureColor); + m_bitmapIsPureColor = GLUtils::isPureColorBitmap(m_bitmap, m_bitmapPureColor); + + renderInfo.isPureColor = m_bitmapIsPureColor; + renderInfo.pureColor = m_bitmapPureColor; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h index 39e00f2..34b57ca 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); 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/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/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp index 520a557..1270498 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp @@ -246,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); @@ -282,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 @@ -307,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 fa84f0d..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,7 +390,7 @@ void TransferQueue::updateDirtyTiles() } void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo, - const SkBitmap& bitmap) + SkBitmap& bitmap) { TRACE_METHOD(); if (!tryUpdateQueueWithBitmap(renderInfo, bitmap)) { @@ -402,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. @@ -428,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); @@ -474,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; @@ -486,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/plugins/android/PluginViewAndroid.cpp b/Source/WebCore/plugins/android/PluginViewAndroid.cpp index fdf6e03..2cc95b1 100644 --- a/Source/WebCore/plugins/android/PluginViewAndroid.cpp +++ b/Source/WebCore/plugins/android/PluginViewAndroid.cpp @@ -405,7 +405,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 +422,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 +490,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 +581,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)) diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp index cad23dc..9094732 100644 --- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp @@ -572,16 +572,6 @@ void ChromeClientAndroid::reachedApplicationCacheOriginQuota(SecurityOrigin*) notImplemented(); } -#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS) -void ChromeClientAndroid::webAppCanBeInstalled() -{ - FrameView* frameView = m_webFrame->page()->mainFrame()->view(); - android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView); - if (core) - core->notifyWebAppCanBeInstalled(); -} -#endif - #if ENABLE(VIDEO) bool ChromeClientAndroid::supportsFullscreenForNode(const Node* node) { @@ -594,16 +584,23 @@ void ChromeClientAndroid::enterFullscreenForNode(Node* node) return; HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(node); - String url = videoElement->currentSrc(); - LayerAndroid* layer = videoElement->platformLayer(); - if (!layer) - return; FrameView* frameView = m_webFrame->page()->mainFrame()->view(); android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView); - m_webFrame->page()->mainFrame()->document()->webkitWillEnterFullScreenForElement(videoElement); if (core) - core->enterFullscreenForVideoLayer(layer->uniqueId(), url); + core->enterFullscreenForVideoLayer(); + + MediaPlayer* player = videoElement->player(); + if (player) { + // We need to use the same document object as the + // MediaPlayerPrivateAndroid::onStopFullscreen(). + Document* doc = player->mediaPlayerClient()->mediaPlayerOwningDocument(); + if (doc) + doc->webkitWillEnterFullScreenForElement(videoElement); + // Now the player is responsible to trigger to the java side for + // entering full screen mode. + player->enterFullscreenMode(); + } } void ChromeClientAndroid::exitFullscreenForNode(Node* node) diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h index 82f3a23..4d27605 100644 --- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h +++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h @@ -180,10 +180,6 @@ namespace android { virtual void showContextMenu(); #endif -#if ENABLE(ANDROID_INSTALLABLE_WEB_APPS) - virtual void webAppCanBeInstalled(); -#endif - #if ENABLE(FULLSCREEN_API) virtual void exitFullScreenForElement(Element*); #endif diff --git a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp index 1607b0e..c01d916 100644 --- a/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp +++ b/Source/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp @@ -30,6 +30,7 @@ #include "BaseLayerAndroid.h" #include "GraphicsContext.h" +#include "HTMLMediaElement.h" #include "SkiaUtils.h" #include "TilesManager.h" #include "VideoLayerAndroid.h" @@ -55,6 +56,7 @@ static const char* g_ProxyJavaClassAudio = "android/webkit/HTML5Audio"; struct MediaPlayerPrivate::JavaGlue { jobject m_javaProxy; jmethodID m_play; + jmethodID m_enterFullscreenForVideoLayer; jmethodID m_teardown; jmethodID m_seek; jmethodID m_pause; @@ -191,11 +193,19 @@ void MediaPlayerPrivate::onTimeupdate(int position) m_player->timeChanged(); } -void MediaPlayerPrivate::onStopFullscreen() +void MediaPlayerPrivate::onStopFullscreen(bool stillPlaying) { - if (m_player && m_player->mediaPlayerClient() - && m_player->mediaPlayerClient()->mediaPlayerOwningDocument()) { - m_player->mediaPlayerClient()->mediaPlayerOwningDocument()->webkitCancelFullScreen(); + if (m_player && m_player->mediaPlayerClient()) { + Document* doc = m_player->mediaPlayerClient()->mediaPlayerOwningDocument(); + if (doc) { + HTMLMediaElement* element = + static_cast<HTMLMediaElement*>(doc->webkitCurrentFullScreenElement()); + element->exitFullscreen(); + doc->webkitDidExitFullScreenForElement(element); + + if (stillPlaying) + element->play(true); + } } } @@ -234,6 +244,22 @@ public: checkException(env); } + + void enterFullscreenMode() + { + JNIEnv* env = JSC::Bindings::getJNIEnv(); + if (!env || !m_url.length() || !m_glue->m_javaProxy) + return; + + jstring jUrl = wtfStringToJstring(env, m_url); + env->CallVoidMethod(m_glue->m_javaProxy, + m_glue->m_enterFullscreenForVideoLayer, jUrl, + m_videoLayer->uniqueId()); + env->DeleteLocalRef(jUrl); + + checkException(env); + } + bool canLoadPoster() const { return true; } void setPoster(const String& url) { @@ -319,9 +345,13 @@ public: return; m_glue = new JavaGlue; - m_glue->m_getInstance = env->GetStaticMethodID(clazz, "getInstance", "(Landroid/webkit/WebViewCore;I)Landroid/webkit/HTML5VideoViewProxy;"); + m_glue->m_getInstance = + env->GetStaticMethodID(clazz, "getInstance", + "(Landroid/webkit/WebViewCore;I)Landroid/webkit/HTML5VideoViewProxy;"); m_glue->m_loadPoster = env->GetMethodID(clazz, "loadPoster", "(Ljava/lang/String;)V"); m_glue->m_play = env->GetMethodID(clazz, "play", "(Ljava/lang/String;II)V"); + m_glue->m_enterFullscreenForVideoLayer = + env->GetMethodID(clazz, "enterFullscreenForVideoLayer", "(Ljava/lang/String;I)V"); m_glue->m_teardown = env->GetMethodID(clazz, "teardown", "()V"); m_glue->m_seek = env->GetMethodID(clazz, "seek", "(I)V"); @@ -628,12 +658,12 @@ static bool SendSurfaceTexture(JNIEnv* env, jobject obj, jobject surfTex, return true; } -static void OnStopFullscreen(JNIEnv* env, jobject obj, int pointer) +static void OnStopFullscreen(JNIEnv* env, jobject obj, int stillPlaying, int pointer) { if (pointer) { WebCore::MediaPlayerPrivate* player = reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); - player->onStopFullscreen(); + player->onStopFullscreen(stillPlaying); } } @@ -645,7 +675,7 @@ static JNINativeMethod g_MediaPlayerMethods[] = { (void*) OnPrepared }, { "nativeOnEnded", "(I)V", (void*) OnEnded }, - { "nativeOnStopFullscreen", "(I)V", + { "nativeOnStopFullscreen", "(II)V", (void*) OnStopFullscreen }, { "nativeOnPaused", "(I)V", (void*) OnPaused }, diff --git a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp index 56e7e24..864b27d 100644 --- a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp +++ b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp @@ -164,10 +164,10 @@ void PlatformBridge::updateViewport(FrameView* frameView) webViewCore->updateViewport(); } -void PlatformBridge::updateTextfield(FrameView* frameView, Node* nodePtr, bool changeToPassword, const WTF::String& text) +void PlatformBridge::updateTextfield(FrameView* frameView, Node* nodePtr, const WTF::String& text) { android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView); - webViewCore->updateTextfield(nodePtr, changeToPassword, text); + webViewCore->updateTextfield(nodePtr, text); } void PlatformBridge::setScrollPosition(ScrollView* scrollView, int x, int y) { diff --git a/Source/WebKit/android/jni/PicturePile.cpp b/Source/WebKit/android/jni/PicturePile.cpp index bdf347a..6a36ccf 100644 --- a/Source/WebKit/android/jni/PicturePile.cpp +++ b/Source/WebKit/android/jni/PicturePile.cpp @@ -35,11 +35,17 @@ #include "PlatformGraphicsContextSkia.h" #include "SkCanvas.h" #include "SkNWayCanvas.h" -#include "SkPicture.h" #include "SkPixelRef.h" #include "SkRect.h" #include "SkRegion.h" +#if USE_RECORDING_CONTEXT +#include "GraphicsOperationCollection.h" +#include "PlatformGraphicsContextRecording.h" +#else +#include "SkPicture.h" +#endif + #define ENABLE_PRERENDERED_INVALS true #define MAX_OVERLAP_COUNT 2 #define MAX_OVERLAP_AREA .7 @@ -57,6 +63,20 @@ static IntRect extractClipBounds(SkCanvas* canvas, const IntSize& size) { return enclosingIntRect(clip); } +PictureContainer::PictureContainer(const PictureContainer& other) + : picture(other.picture) + , area(other.area) + , dirty(other.dirty) + , prerendered(other.prerendered) +{ + SkSafeRef(picture); +} + +PictureContainer::~PictureContainer() +{ + SkSafeUnref(picture); +} + PicturePile::PicturePile(const PicturePile& other) : m_size(other.m_size) , m_pile(other.m_pile) @@ -64,15 +84,6 @@ PicturePile::PicturePile(const PicturePile& other) { } -PicturePile::PicturePile(SkPicture* picture) -{ - m_size = IntSize(picture->width(), picture->height()); - PictureContainer pc(IntRect(0, 0, m_size.width(), m_size.height())); - pc.picture = picture; - pc.dirty = false; - m_pile.append(pc); -} - void PicturePile::draw(SkCanvas* canvas) { /* Loop down recursively, subtracting the previous clip from the SkRegion, @@ -106,8 +117,7 @@ void PicturePile::drawWithClipRecursive(SkCanvas* canvas, SkRegion& clipRegion, drawWithClipRecursive(canvas, clipRegion, index - 1); int saved = canvas->save(); canvas->clipRect(intersection); - canvas->translate(pc.area.x(), pc.area.y()); - canvas->drawPicture(*pc.picture); + drawPicture(canvas, pc); canvas->restoreToCount(saved); } else drawWithClipRecursive(canvas, clipRegion, index - 1); @@ -162,43 +172,8 @@ void PicturePile::updatePicturesIfNeeded(PicturePainter* painter) void PicturePile::updatePicture(PicturePainter* painter, PictureContainer& pc) { - /* The ref counting here is a bit unusual. What happens is begin/end recording - * will ref/unref the recording canvas. However, 'canvas' might be pointing - * at an SkNWayCanvas instead of the recording canvas, which needs to be - * unref'd. Thus what we do is ref the recording canvas so that we can - * always unref whatever canvas we have at the end. - */ TRACE_METHOD(); - SkPicture* picture = new SkPicture(); - SkCanvas* canvas = picture->beginRecording(pc.area.width(), pc.area.height(), - SkPicture::kUsePathBoundsForClip_RecordingFlag); - SkSafeRef(canvas); - canvas->translate(-pc.area.x(), -pc.area.y()); - IntRect drawArea = pc.area; - if (pc.prerendered.get()) { - SkCanvas* prerender = painter->createPrerenderCanvas(pc.prerendered.get()); - if (!prerender) { - ALOGV("Failed to create prerendered for " INT_RECT_FORMAT, - INT_RECT_ARGS(pc.prerendered->area)); - pc.prerendered.clear(); - } else { - drawArea.unite(pc.prerendered->area); - SkNWayCanvas* nwayCanvas = new SkNWayCanvas(drawArea.width(), drawArea.height()); - nwayCanvas->translate(-drawArea.x(), -drawArea.y()); - nwayCanvas->addCanvas(canvas); - nwayCanvas->addCanvas(prerender); - SkSafeUnref(canvas); - SkSafeUnref(prerender); - canvas = nwayCanvas; - } - } - WebCore::PlatformGraphicsContextSkia pgc(canvas); - WebCore::GraphicsContext gc(&pgc); - ALOGV("painting picture: " INT_RECT_FORMAT, INT_RECT_ARGS(drawArea)); - painter->paintContents(&gc, drawArea); - SkSafeUnref(canvas); - picture->endRecording(); - + Picture* picture = recordPicture(painter, pc); SkSafeUnref(pc.picture); pc.picture = picture; pc.dirty = false; @@ -297,4 +272,69 @@ PrerenderedInval* PicturePile::prerenderedInvalForArea(const IntRect& area) return 0; } +#if USE_RECORDING_CONTEXT +void PicturePile::drawPicture(SkCanvas* canvas, PictureContainer& pc) +{ + PlatformGraphicsContextSkia pgc(canvas); + pc.picture->apply(&pgc); +} + +Picture* PicturePile::recordPicture(PicturePainter* painter, PictureContainer& pc) +{ + // TODO: Support? Not needed? + pc.prerendered.clear(); + GraphicsOperationCollection* picture = new GraphicsOperationCollection(); + WebCore::PlatformGraphicsContextRecording pgc(picture); + WebCore::GraphicsContext gc(&pgc); + painter->paintContents(&gc, pc.area); + return picture; +} +#else +void PicturePile::drawPicture(SkCanvas* canvas, PictureContainer& pc) +{ + canvas->translate(pc.area.x(), pc.area.y()); + pc.picture->draw(canvas); +} + +Picture* PicturePile::recordPicture(PicturePainter* painter, PictureContainer& pc) +{ + /* The ref counting here is a bit unusual. What happens is begin/end recording + * will ref/unref the recording canvas. However, 'canvas' might be pointing + * at an SkNWayCanvas instead of the recording canvas, which needs to be + * unref'd. Thus what we do is ref the recording canvas so that we can + * always unref whatever canvas we have at the end. + */ + SkPicture* picture = new SkPicture(); + SkCanvas* canvas = picture->beginRecording(pc.area.width(), pc.area.height(), + SkPicture::kUsePathBoundsForClip_RecordingFlag); + SkSafeRef(canvas); + canvas->translate(-pc.area.x(), -pc.area.y()); + IntRect drawArea = pc.area; + if (pc.prerendered.get()) { + SkCanvas* prerender = painter->createPrerenderCanvas(pc.prerendered.get()); + if (!prerender) { + ALOGV("Failed to create prerendered for " INT_RECT_FORMAT, + INT_RECT_ARGS(pc.prerendered->area)); + pc.prerendered.clear(); + } else { + drawArea.unite(pc.prerendered->area); + SkNWayCanvas* nwayCanvas = new SkNWayCanvas(drawArea.width(), drawArea.height()); + nwayCanvas->translate(-drawArea.x(), -drawArea.y()); + nwayCanvas->addCanvas(canvas); + nwayCanvas->addCanvas(prerender); + SkSafeUnref(canvas); + SkSafeUnref(prerender); + canvas = nwayCanvas; + } + } + WebCore::PlatformGraphicsContextSkia pgc(canvas); + WebCore::GraphicsContext gc(&pgc); + ALOGV("painting picture: " INT_RECT_FORMAT, INT_RECT_ARGS(drawArea)); + painter->paintContents(&gc, drawArea); + SkSafeUnref(canvas); + picture->endRecording(); + return picture; +} +#endif + } // namespace WebCore diff --git a/Source/WebKit/android/jni/PicturePile.h b/Source/WebKit/android/jni/PicturePile.h index b28a792..64caa95 100644 --- a/Source/WebKit/android/jni/PicturePile.h +++ b/Source/WebKit/android/jni/PicturePile.h @@ -38,7 +38,17 @@ #include <wtf/ThreadSafeRefCounted.h> #include <wtf/Vector.h> +#define USE_RECORDING_CONTEXT true +#if USE_RECORDING_CONTEXT +namespace WebCore { +class GraphicsOperationCollection; +} +typedef WebCore::GraphicsOperationCollection Picture; +#else class SkPicture; +typedef SkPicture Picture; +#endif + class SkCanvas; namespace WebCore { @@ -57,7 +67,7 @@ public: class PictureContainer { public: - SkPicture* picture; + Picture* picture; IntRect area; bool dirty; RefPtr<PrerenderedInval> prerendered; @@ -68,26 +78,14 @@ public: , dirty(true) {} - PictureContainer(const PictureContainer& other) - : picture(other.picture) - , area(other.area) - , dirty(other.dirty) - , prerendered(other.prerendered) - { - SkSafeRef(picture); - } - - ~PictureContainer() - { - SkSafeUnref(picture); - } + PictureContainer(const PictureContainer& other); + ~PictureContainer(); }; class PicturePile { public: PicturePile() {} PicturePile(const PicturePile& other); - PicturePile(SkPicture* picture); const IntSize& size() { return m_size; } @@ -107,8 +105,10 @@ public: private: void applyWebkitInvals(); void updatePicture(PicturePainter* painter, PictureContainer& container); + Picture* recordPicture(PicturePainter* painter, PictureContainer& container); void appendToPile(const IntRect& inval, const IntRect& originalInval = IntRect()); void drawWithClipRecursive(SkCanvas* canvas, SkRegion& clipRegion, int index); + void drawPicture(SkCanvas* canvas, PictureContainer& pc); IntSize m_size; Vector<PictureContainer> m_pile; diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp index 02ddca6..8963837 100644 --- a/Source/WebKit/android/jni/ViewStateSerializer.cpp +++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp @@ -30,6 +30,7 @@ #include "BaseLayerAndroid.h" #include "CreateJavaOutputStreamAdaptor.h" +#include "DumpLayer.h" #include "FixedPositioning.h" #include "ImagesManager.h" #include "IFrameContentLayerAndroid.h" @@ -56,6 +57,68 @@ enum LayerTypes { LTFixedLayerAndroid = 3 }; +#define ID "mID" +#define LEFT "layout:mLeft" +#define TOP "layout:mTop" +#define WIDTH "layout:getWidth()" +#define HEIGHT "layout:getHeight()" + +class HierarchyLayerDumper : public LayerDumper { +public: + HierarchyLayerDumper(SkWStream* stream, int level) + : LayerDumper(level) + , m_stream(stream) + {} + + virtual void beginLayer(const char* className, const LayerAndroid* layerPtr) { + LayerDumper::beginLayer(className, layerPtr); + for (int i = 0; i < m_indentLevel; i++) { + m_stream->writeText(" "); + } + m_stream->writeText(className); + m_stream->writeText("@"); + m_stream->writeHexAsText(layerPtr->uniqueId()); + m_stream->writeText(" "); + + writeHexVal(ID, (int) layerPtr); + writeIntVal(LEFT, layerPtr->getPosition().fX); + writeIntVal(TOP, layerPtr->getPosition().fY); + writeIntVal(WIDTH, layerPtr->getWidth()); + writeIntVal(HEIGHT, layerPtr->getHeight()); + } + + virtual void beginChildren(int childCount) { + m_stream->writeText("\n"); + LayerDumper::beginChildren(childCount); + } + +protected: + virtual void writeEntry(const char* label, const char* value) { + m_stream->writeText(label); + m_stream->writeText("="); + int len = strlen(value); + m_stream->writeDecAsText(len); + m_stream->writeText(","); + m_stream->writeText(value); + m_stream->writeText(" "); + } + +private: + SkWStream* m_stream; +}; + +static void nativeDumpLayerHierarchy(JNIEnv* env, jobject, jint jbaseLayer, jint level, + jobject jstream, jbyteArray jstorage) +{ + SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage); + BaseLayerAndroid* baseLayer = reinterpret_cast<BaseLayerAndroid*>(jbaseLayer); + SkSafeRef(baseLayer); + HierarchyLayerDumper dumper(stream, level); + baseLayer->dumpLayers(&dumper); + SkSafeUnref(baseLayer); + delete stream; +} + static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer, jobject jstream, jbyteArray jstorage) { @@ -478,6 +541,8 @@ LayerAndroid* deserializeLayer(int version, SkStream* stream) * JNI registration */ static JNINativeMethod gSerializerMethods[] = { + { "nativeDumpLayerHierarchy", "(IILjava/io/OutputStream;[B)V", + (void*) nativeDumpLayerHierarchy }, { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z", (void*) nativeSerializeViewState }, { "nativeDeserializeViewState", "(ILjava/io/InputStream;[B)I", diff --git a/Source/WebKit/android/jni/WebSettings.cpp b/Source/WebKit/android/jni/WebSettings.cpp index 7ee9033..467da3d 100644 --- a/Source/WebKit/android/jni/WebSettings.cpp +++ b/Source/WebKit/android/jni/WebSettings.cpp @@ -80,9 +80,9 @@ struct FieldIds { "Ljava/lang/String;"); mDefaultTextEncoding = env->GetFieldID(clazz, "mDefaultTextEncoding", "Ljava/lang/String;"); - mUserAgent = env->GetFieldID(clazz, "mUserAgent", - "Ljava/lang/String;"); - mAcceptLanguage = env->GetFieldID(clazz, "mAcceptLanguage", "Ljava/lang/String;"); + mGetUserAgentString = env->GetMethodID(clazz, "getUserAgentString", + "()Ljava/lang/String;"); + mGetAcceptLanguage = env->GetMethodID(clazz, "getAcceptLanguage", "()Ljava/lang/String;"); mMinimumFontSize = env->GetFieldID(clazz, "mMinimumFontSize", "I"); mMinimumLogicalFontSize = env->GetFieldID(clazz, "mMinimumLogicalFontSize", "I"); mDefaultFontSize = env->GetFieldID(clazz, "mDefaultFontSize", "I"); @@ -150,6 +150,7 @@ struct FieldIds { env->DeleteLocalRef(autoFillProfileClass); #endif mOverrideCacheMode = env->GetFieldID(clazz, "mOverrideCacheMode", "I"); + mPasswordEchoEnabled = env->GetFieldID(clazz, "mPasswordEchoEnabled", "Z"); ALOG_ASSERT(mLayoutAlgorithm, "Could not find field mLayoutAlgorithm"); ALOG_ASSERT(mTextSize, "Could not find field mTextSize"); @@ -160,8 +161,8 @@ struct FieldIds { ALOG_ASSERT(mCursiveFontFamily, "Could not find field mCursiveFontFamily"); ALOG_ASSERT(mFantasyFontFamily, "Could not find field mFantasyFontFamily"); ALOG_ASSERT(mDefaultTextEncoding, "Could not find field mDefaultTextEncoding"); - ALOG_ASSERT(mUserAgent, "Could not find field mUserAgent"); - ALOG_ASSERT(mAcceptLanguage, "Could not find field mAcceptLanguage"); + ALOG_ASSERT(mGetUserAgentString, "Could not find method getUserAgentString"); + ALOG_ASSERT(mGetAcceptLanguage, "Could not find method getAcceptLanguage"); ALOG_ASSERT(mMinimumFontSize, "Could not find field mMinimumFontSize"); ALOG_ASSERT(mMinimumLogicalFontSize, "Could not find field mMinimumLogicalFontSize"); ALOG_ASSERT(mDefaultFontSize, "Could not find field mDefaultFontSize"); @@ -193,6 +194,7 @@ struct FieldIds { ALOG_ASSERT(mMaximumDecodedImageSize, "Could not find field mMaximumDecodedImageSize"); ALOG_ASSERT(mUseDoubleTree, "Could not find field mUseDoubleTree"); ALOG_ASSERT(mPageCacheCapacity, "Could not find field mPageCacheCapacity"); + ALOG_ASSERT(mPasswordEchoEnabled, "Could not find field mPasswordEchoEnabled"); jclass enumClass = env->FindClass("java/lang/Enum"); ALOG_ASSERT(enumClass, "Could not find Enum class!"); @@ -211,8 +213,8 @@ struct FieldIds { jfieldID mCursiveFontFamily; jfieldID mFantasyFontFamily; jfieldID mDefaultTextEncoding; - jfieldID mUserAgent; - jfieldID mAcceptLanguage; + jmethodID mGetUserAgentString; + jmethodID mGetAcceptLanguage; jfieldID mMinimumFontSize; jfieldID mMinimumLogicalFontSize; jfieldID mDefaultFontSize; @@ -278,6 +280,7 @@ struct FieldIds { jfieldID mAutoFillProfilePhoneNumber; #endif jfieldID mOverrideCacheMode; + jfieldID mPasswordEchoEnabled; }; static struct FieldIds* gFieldIds; @@ -375,14 +378,14 @@ public: str = (jstring)env->GetObjectField(obj, gFieldIds->mDefaultTextEncoding); s->setDefaultTextEncodingName(jstringToWtfString(env, str)); - str = (jstring)env->GetObjectField(obj, gFieldIds->mUserAgent); + str = (jstring)env->CallObjectMethod(obj, gFieldIds->mGetUserAgentString); WebFrame::getWebFrame(pFrame)->setUserAgent(jstringToWtfString(env, str)); WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextUserAgent(); jint cacheMode = env->GetIntField(obj, gFieldIds->mOverrideCacheMode); WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextCacheMode(cacheMode); - str = (jstring)env->GetObjectField(obj, gFieldIds->mAcceptLanguage); + str = (jstring)env->CallObjectMethod(obj, gFieldIds->mGetAcceptLanguage); WebRequestContext::setAcceptLanguage(jstringToWtfString(env, str)); jint size = env->GetIntField(obj, gFieldIds->mMinimumFontSize); @@ -610,8 +613,9 @@ public: // has no style attached to it. http://trac.webkit.org/changeset/79799 s->setDeveloperExtrasEnabled(true); s->setSpatialNavigationEnabled(true); - - s->setPasswordEchoEnabled(true); + bool echoPassword = env->GetBooleanField(obj, + gFieldIds->mPasswordEchoEnabled); + s->setPasswordEchoEnabled(echoPassword); } }; diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 724f84d..ec027cd 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -368,8 +368,6 @@ struct WebViewCore::JavaGlue { jmethodID m_showRect; jmethodID m_centerFitRect; jmethodID m_setScrollbarModes; - jmethodID m_setInstallableWebApp; - jmethodID m_enterFullscreenForVideoLayer; jmethodID m_exitFullscreenVideo; jmethodID m_setWebTextViewAutoFillable; jmethodID m_selectAt; @@ -424,7 +422,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m , m_mainFrame(mainframe) , m_popupReply(0) , m_blockTextfieldUpdates(false) - , m_focusBoundsChanged(false) , m_skipContentDraw(false) , m_textGeneration(0) , m_maxXScroll(320/4) @@ -472,7 +469,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V"); m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V"); m_javaGlue->m_sendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "(IIII)V"); - m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V"); + m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(ILjava/lang/String;I)V"); m_javaGlue->m_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIIII)V"); m_javaGlue->m_updateTextSizeAndScroll = GetJMethod(env, clazz, "updateTextSizeAndScroll", "(IIIII)V"); m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V"); @@ -500,9 +497,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_showRect = GetJMethod(env, clazz, "showRect", "(IIIIIIFFFF)V"); m_javaGlue->m_centerFitRect = GetJMethod(env, clazz, "centerFitRect", "(IIII)V"); m_javaGlue->m_setScrollbarModes = GetJMethod(env, clazz, "setScrollbarModes", "(II)V"); - m_javaGlue->m_setInstallableWebApp = GetJMethod(env, clazz, "setInstallableWebApp", "()V"); #if ENABLE(VIDEO) - m_javaGlue->m_enterFullscreenForVideoLayer = GetJMethod(env, clazz, "enterFullscreenForVideoLayer", "(ILjava/lang/String;)V"); m_javaGlue->m_exitFullscreenVideo = GetJMethod(env, clazz, "exitFullscreenVideo", "()V"); #endif m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V"); @@ -729,13 +724,6 @@ void WebViewCore::clearContent() updateLocale(); } -bool WebViewCore::focusBoundsChanged() -{ - bool result = m_focusBoundsChanged; - m_focusBoundsChanged = false; - return result; -} - void WebViewCore::paintContents(WebCore::GraphicsContext* gc, WebCore::IntRect& dirty) { WebCore::FrameView* view = m_mainFrame->view(); @@ -1217,7 +1205,7 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, m_mainFrame->view()->forceLayout(); // scroll to restore current screen center - if (node) { + if (node && node->inDocument()) { const WebCore::IntRect& newBounds = node->getRect(); if ((osw && osh && bounds.width() && bounds.height()) && (bounds != newBounds)) { @@ -1605,6 +1593,20 @@ bool WebViewCore::isLtr(const Position& position) return isLtr; } +static Node* findInputParent(Node* node) +{ + Node* testNode = node; + while (testNode) { + RenderObject* renderer = testNode->renderer(); + if (renderer + && (renderer->isTextArea() || renderer->isTextControl())) { + return testNode; + } + testNode = testNode->parentOrHostNode(); + } + return node; +} + SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) { bool isCaret = selection.isCaret(); @@ -1649,6 +1651,18 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) ? SelectText::RightHandle : SelectText::LeftHandle; setSelectionCaretInfo(selectTextContainer, extent, frameOffset, SelectText::ExtentHandle, extentHandleType, extentOffset, affinity); + IntRect clipRect; + if (selection.isContentEditable()) { + Node* editable = findInputParent(base.anchorNode()); + RenderObject* render = editable->renderer(); + if (render && render->isBox() && !render->isBody()) { + RenderBox* renderBox = toRenderBox(render); + clipRect = renderBox->clientBoxRect(); + FloatPoint pos = renderBox->localToAbsolute(clipRect.location()); + clipRect.setX(pos.x()); + clipRect.setY(pos.y()); + } + } Node* stopNode = range->pastLastNode(); for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) { @@ -1662,7 +1676,8 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) int layerId = platformLayerIdFromNode(node, &layer); Vector<IntRect> rects; renderText->absoluteRectsForRange(rects, startOffset, endOffset, true); - selectTextContainer->addHighlightRegion(layer, rects, frameOffset); + selectTextContainer->addHighlightRegion(layer, rects, frameOffset, + clipRect); } } selectTextContainer->setText(range->text()); @@ -2973,7 +2988,7 @@ void WebViewCore::passToJs(int generation, const WTF::String& current, WTF::String test = getInputText(focus); if (test != current) { // If the text changed during the key event, update the UI text field. - updateTextfield(focus, false, test); + updateTextfield(focus, test); } // Now that the selection has settled down, send it. updateTextSelection(); @@ -3889,8 +3904,7 @@ void WebViewCore::updateTextSizeAndScroll(WebCore::Node* node) checkException(env); } -void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, - const WTF::String& text) +void WebViewCore::updateTextfield(WebCore::Node* ptr, const WTF::String& text) { JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue->object(env); @@ -3898,15 +3912,9 @@ void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword, return; if (m_blockTextfieldUpdates) return; - if (changeToPassword) { - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateTextfield, - (int) ptr, true, 0, m_textGeneration); - checkException(env); - return; - } jstring string = wtfStringToJstring(env, text); env->CallVoidMethod(javaObject.get(), m_javaGlue->m_updateTextfield, - (int) ptr, false, string, m_textGeneration); + (int) ptr, string, m_textGeneration); env->DeleteLocalRef(string); checkException(env); } @@ -4100,27 +4108,11 @@ void WebViewCore::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode checkException(env); } -void WebViewCore::notifyWebAppCanBeInstalled() -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue->object(env); - if (!javaObject.get()) - return; - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_setInstallableWebApp); - checkException(env); -} - #if ENABLE(VIDEO) -void WebViewCore::enterFullscreenForVideoLayer(int layerId, const WTF::String& url) +void WebViewCore::enterFullscreenForVideoLayer() { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - AutoJObject javaObject = m_javaGlue->object(env); - if (!javaObject.get()) - return; - jstring jUrlStr = wtfStringToJstring(env, url); - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_enterFullscreenForVideoLayer, layerId, jUrlStr); + // Just need to update the video mode, to avoid multiple exit full screen. m_fullscreenVideoMode = true; - checkException(env); } void WebViewCore::exitFullscreenVideo() @@ -4813,11 +4805,6 @@ static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jint nativeClass, WebCore::SchemeRegistry::registerURLSchemeAsLocal(jstringToWtfString(env, scheme)); } -static bool FocusBoundsChanged(JNIEnv* env, jobject obj, jint nativeClass) -{ - return reinterpret_cast<WebViewCore*>(nativeClass)->focusBoundsChanged(); -} - static void Pause(JNIEnv* env, jobject obj, jint nativeClass) { // This is called for the foreground tab when the browser is put to the @@ -5019,8 +5006,6 @@ static int FindNext(JNIEnv* env, jobject obj, jint nativeClass, static JNINativeMethod gJavaWebViewCoreMethods[] = { { "nativeClearContent", "(I)V", (void*) ClearContent }, - { "nativeFocusBoundsChanged", "(I)Z", - (void*) FocusBoundsChanged } , { "nativeKey", "(IIIIZZZZ)Z", (void*) Key }, { "nativeContentInvalidateAll", "(I)V", diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index ba35005..6e3604d 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -202,13 +202,9 @@ namespace android { /** * Tell the java side to update the focused textfield * @param pointer Pointer to the node for the input field. - * @param changeToPassword If true, we are changing the textfield to - * a password field, and ignore the WTF::String - * @param text If changeToPassword is false, this is the new text that - * should go into the textfield. + * @param text This is the new text that should go into the textfield. */ - void updateTextfield(WebCore::Node* pointer, - bool changeToPassword, const WTF::String& text); + void updateTextfield(WebCore::Node* pointer, const WTF::String& text); /** * Tell the java side to update the current selection in the focused @@ -509,8 +505,6 @@ namespace android { // reset the picture set to empty void clearContent(); - bool focusBoundsChanged(); - // record content in a new BaseLayerAndroid, copying the layer tree as well WebCore::BaseLayerAndroid* recordContent(SkIPoint* ); @@ -527,8 +521,6 @@ namespace android { WebCore::Frame* mainFrame() const { return m_mainFrame; } WebCore::Frame* focusedFrame() const; - void notifyWebAppCanBeInstalled(); - void deleteText(int startX, int startY, int endX, int endY); WTF::String getText(int startX, int startY, int endX, int endY); void insertText(const WTF::String &text); @@ -540,7 +532,7 @@ namespace android { void updateMatchCount() const; #if ENABLE(VIDEO) - void enterFullscreenForVideoLayer(int layerId, const WTF::String& url); + void enterFullscreenForVideoLayer(); void exitFullscreenVideo(); #endif @@ -760,7 +752,6 @@ namespace android { // Used in passToJS to avoid updating the UI text field until after the // key event has been processed. bool m_blockTextfieldUpdates; - bool m_focusBoundsChanged; bool m_skipContentDraw; // Passed in with key events to know when they were generated. Store it // with the cache so that we can ignore stale text changes. diff --git a/Source/WebKit/android/nav/DrawExtra.cpp b/Source/WebKit/android/nav/DrawExtra.cpp index 2f57dc1..a7d686c 100644 --- a/Source/WebKit/android/nav/DrawExtra.cpp +++ b/Source/WebKit/android/nav/DrawExtra.cpp @@ -52,7 +52,8 @@ SkRegion* RegionLayerDrawExtra::getHighlightRegionsForLayer(const LayerAndroid* } void RegionLayerDrawExtra::addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects, - const IntPoint& additionalOffset) + const IntPoint& additionalOffset, + const IntRect& clipRect) { if (rects.isEmpty()) return; @@ -66,6 +67,11 @@ void RegionLayerDrawExtra::addHighlightRegion(const LayerAndroid* layer, const V WebViewCore::layerToAbsoluteOffset(layer, offset); for (size_t i = 0; i < rects.size(); i++) { IntRect r = rects.at(i); + if (!clipRect.isEmpty()) { + r.intersect(clipRect); + if (r.isEmpty()) + continue; // don't add it to the region + } r.move(-offset.x(), -offset.y()); region->op(r.x(), r.y(), r.maxX(), r.maxY(), SkRegion::kUnion_Op); } diff --git a/Source/WebKit/android/nav/DrawExtra.h b/Source/WebKit/android/nav/DrawExtra.h index cc94476..1850b6b 100644 --- a/Source/WebKit/android/nav/DrawExtra.h +++ b/Source/WebKit/android/nav/DrawExtra.h @@ -65,7 +65,8 @@ public: virtual ~RegionLayerDrawExtra(); void addHighlightRegion(const LayerAndroid* layer, const Vector<IntRect>& rects, - const IntPoint& additionalOffset = IntPoint()); + const IntPoint& additionalOffset = IntPoint(), + const IntRect& clipRect = IntRect()); virtual void draw(SkCanvas*, LayerAndroid*); virtual void drawGL(GLExtras*, const LayerAndroid*); diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 8e88131..c708c25 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -32,6 +32,7 @@ #include "BaseLayerAndroid.h" #include "BaseRenderer.h" #include "DrawExtra.h" +#include "DumpLayer.h" #include "Frame.h" #include "GLWebViewState.h" #include "GraphicsJNI.h" @@ -995,6 +996,28 @@ static void nativeCopyBaseContentToPicture(JNIEnv *env, jobject obj, jobject pic GET_NATIVE_VIEW(env, obj)->copyBaseContentToPicture(picture); } +static jboolean nativeDumpLayerContentToPicture(JNIEnv *env, jobject obj, jint instance, + jstring jclassName, jint layerId, jobject pict) +{ + bool success = false; + SkPicture* picture = GraphicsJNI::getNativePicture(env, pict); + std::string classname = jstringToStdString(env, jclassName); + BaseLayerAndroid* baseLayer = reinterpret_cast<WebView*>(instance)->getBaseLayer(); + LayerAndroid* layer = baseLayer->findById(layerId); + SkSafeRef(layer); + if (layer && layer->subclassName() == classname) { + LayerContent* content = layer->content(); + if (content) { + SkCanvas* canvas = picture->beginRecording(content->width(), content->height()); + content->draw(canvas); + picture->endRecording(); + success = true; + } + } + SkSafeUnref(layer); + return success; +} + static bool nativeHasContent(JNIEnv *env, jobject obj) { return GET_NATIVE_VIEW(env, obj)->hasContent(); @@ -1187,7 +1210,8 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl) if (baseLayer) { FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w"); if (file) { - baseLayer->dumpLayers(file, 0); + WebCore::FileLayerDumper dumper(file); + baseLayer->dumpLayers(&dumper); fclose(file); } } @@ -1355,6 +1379,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeGetBaseLayer }, { "nativeCopyBaseContentToPicture", "(Landroid/graphics/Picture;)V", (void*) nativeCopyBaseContentToPicture }, + { "nativeDumpLayerContentToPicture", "(ILjava/lang/String;ILandroid/graphics/Picture;)Z", + (void*) nativeDumpLayerContentToPicture }, { "nativeHasContent", "()Z", (void*) nativeHasContent }, { "nativeDiscardAllTextures", "()V", |