diff options
Diffstat (limited to 'Source/WebCore')
26 files changed, 215 insertions, 173 deletions
diff --git a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp index f2dd1d2..e7b854d 100644 --- a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp +++ b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp @@ -65,15 +65,29 @@ JavaClass* JavaInstanceJobject::getClass() const return m_class.get(); } -JavaValue JavaInstanceJobject::invokeMethod(const JavaMethod* method, JavaValue* args) +// ANDROID +JavaValue JavaInstanceJobject::invokeMethod(const JavaMethod* method, JavaValue* args, bool& didRaiseUncaughtException) { + didRaiseUncaughtException = false; +// END ANDROID + ASSERT(getClass()->methodsNamed(method->name().utf8().data()).find(method) != notFound); unsigned int numParams = method->numParameters(); OwnArrayPtr<jvalue> jvalueArgs = adoptArrayPtr(new jvalue[numParams]); for (unsigned int i = 0; i < numParams; ++i) jvalueArgs[i] = javaValueToJvalue(args[i]); jvalue result = callJNIMethod(javaInstance(), method->returnType(), method->name().utf8().data(), method->signature(), jvalueArgs.get()); + +// ANDROID + JNIEnv* env = getJNIEnv(); + if (env->ExceptionCheck() != JNI_FALSE) { + env->ExceptionClear(); + didRaiseUncaughtException = true; + return JavaValue(); + } + return jvalueToJavaValue(result, method->returnType()); +// END ANDROID } static void appendClassName(StringBuilder& builder, const char* className) diff --git a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h index bb38e77..255c190 100644 --- a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h +++ b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h @@ -52,7 +52,9 @@ public: // JavaInstance implementation virtual JavaClass* getClass() const; - virtual JavaValue invokeMethod(const JavaMethod*, JavaValue* args); +// ANDROID + virtual JavaValue invokeMethod(const JavaMethod*, JavaValue* args, bool& didRaiseUncaughtException); +// END ANDROID virtual JavaValue getField(const JavaField*); virtual void begin(); virtual void end(); diff --git a/Source/WebCore/bridge/jni/v8/JavaInstanceV8.h b/Source/WebCore/bridge/jni/v8/JavaInstanceV8.h index 7436de7..5a1960a 100644 --- a/Source/WebCore/bridge/jni/v8/JavaInstanceV8.h +++ b/Source/WebCore/bridge/jni/v8/JavaInstanceV8.h @@ -49,7 +49,9 @@ public: virtual JavaClass* getClass() const = 0; // args must be an array of length greater than or equal to the number of // arguments expected by the method. - virtual JavaValue invokeMethod(const JavaMethod*, JavaValue* args) = 0; +// ANDROID + virtual JavaValue invokeMethod(const JavaMethod*, JavaValue* args, bool& didRaiseUncaughtException) = 0; +// END ANDROID virtual JavaValue getField(const JavaField*) = 0; // These functions are called before and after the main entry points into diff --git a/Source/WebCore/bridge/jni/v8/JavaNPObjectV8.cpp b/Source/WebCore/bridge/jni/v8/JavaNPObjectV8.cpp index b22d57f..784ea01 100644 --- a/Source/WebCore/bridge/jni/v8/JavaNPObjectV8.cpp +++ b/Source/WebCore/bridge/jni/v8/JavaNPObjectV8.cpp @@ -146,10 +146,16 @@ bool JavaNPObjectInvoke(NPObject* obj, NPIdentifier identifier, const NPVariant* for (unsigned int i = 0; i < argCount; i++) jArgs[i] = convertNPVariantToJavaValue(args[i], jMethod->parameterAt(i)); - JavaValue jResult = instance->invokeMethod(jMethod, jArgs); +// ANDROID + bool exceptionOccurred; + JavaValue jResult = instance->invokeMethod(jMethod, jArgs, exceptionOccurred); instance->end(); delete[] jArgs; + if (exceptionOccurred) + return false; +// END ANDROID + VOID_TO_NPVARIANT(*result); convertJavaValueToNPVariant(jResult, result); return true; diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp index 2424349..d81cc9d 100644 --- a/Source/WebCore/css/CSSStyleSelector.cpp +++ b/Source/WebCore/css/CSSStyleSelector.cpp @@ -1285,8 +1285,11 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl if (m_parentStyle) m_style->inheritFrom(m_parentStyle); - else + else { m_parentStyle = style(); + // Make sure our fonts are initialized if we don't inherit them from our parent style. + m_style->font().update(0); + } if (e->isLink()) { m_style->setIsLink(true); diff --git a/Source/WebCore/dom/Range.cpp b/Source/WebCore/dom/Range.cpp index 268687f..37d0193 100644 --- a/Source/WebCore/dom/Range.cpp +++ b/Source/WebCore/dom/Range.cpp @@ -623,7 +623,9 @@ static inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offs { ASSERT(container); ASSERT(commonRoot); - ASSERT(commonRoot->contains(container)); + + if (!commonRoot->contains(container)) + return 0; if (container == commonRoot) { container = container->firstChild(); @@ -674,7 +676,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception if (ec) return 0; - Node* commonRoot = commonAncestorContainer(ec); + RefPtr<Node> commonRoot = commonAncestorContainer(ec); if (ec) return 0; ASSERT(commonRoot); @@ -685,8 +687,8 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception } // what is the highest node that partially selects the start / end of the range? - Node* partialStart = highestAncestorUnderCommonRoot(m_start.container(), commonRoot); - Node* partialEnd = highestAncestorUnderCommonRoot(m_end.container(), commonRoot); + RefPtr<Node> partialStart = highestAncestorUnderCommonRoot(m_start.container(), commonRoot.get()); + RefPtr<Node> partialEnd = highestAncestorUnderCommonRoot(m_end.container(), commonRoot.get()); // Start and end containers are different. // There are three possibilities here: @@ -705,29 +707,32 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception // // These are deleted, cloned, or extracted (i.e. both) depending on action. + // Note that we are verifying that our common root hierarchy is still intact + // after any DOM mutation event, at various stages below. See webkit bug 60350. + RefPtr<Node> leftContents; - if (m_start.container() != commonRoot) { + if (m_start.container() != commonRoot && commonRoot->contains(m_start.container())) { leftContents = processContentsBetweenOffsets(action, 0, m_start.container(), m_start.offset(), lengthOfContentsInNode(m_start.container()), ec); - leftContents = processAncestorsAndTheirSiblings(action, m_start.container(), ProcessContentsForward, leftContents, commonRoot, ec); + leftContents = processAncestorsAndTheirSiblings(action, m_start.container(), ProcessContentsForward, leftContents, commonRoot.get(), ec); } RefPtr<Node> rightContents; - if (m_end.container() != commonRoot) { + if (m_end.container() != commonRoot && commonRoot->contains(m_end.container())) { rightContents = processContentsBetweenOffsets(action, 0, m_end.container(), 0, m_end.offset(), ec); - rightContents = processAncestorsAndTheirSiblings(action, m_end.container(), ProcessContentsBackward, rightContents, commonRoot, ec); + rightContents = processAncestorsAndTheirSiblings(action, m_end.container(), ProcessContentsBackward, rightContents, commonRoot.get(), ec); } // delete all children of commonRoot between the start and end container - Node* processStart = childOfCommonRootBeforeOffset(m_start.container(), m_start.offset(), commonRoot); - if (m_start.container() != commonRoot) // processStart contains nodes before m_start. + RefPtr<Node> processStart = childOfCommonRootBeforeOffset(m_start.container(), m_start.offset(), commonRoot.get()); + if (processStart && m_start.container() != commonRoot) // processStart contains nodes before m_start. processStart = processStart->nextSibling(); - Node* processEnd = childOfCommonRootBeforeOffset(m_end.container(), m_end.offset(), commonRoot); + RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(m_end.container(), m_end.offset(), commonRoot.get()); // Collapse the range, making sure that the result is not within a node that was partially selected. if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) { - if (partialStart) + if (partialStart && commonRoot->contains(partialStart.get())) setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1, ec); - else if (partialEnd) + else if (partialEnd && commonRoot->contains(partialEnd.get())) setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), ec); if (ec) return 0; @@ -742,7 +747,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception if (processStart) { NodeVector nodes; - for (Node* n = processStart; n && n != processEnd; n = n->nextSibling()) + for (Node* n = processStart.get(); n && n != processEnd; n = n->nextSibling()) nodes.append(n); processNodes(action, nodes, commonRoot, fragment, ec); } @@ -832,7 +837,7 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef break; } - return result; + return result.release(); } void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode& ec) @@ -902,7 +907,7 @@ PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node firstChildInAncestorToProcess = direction == ProcessContentsForward ? ancestor->nextSibling() : ancestor->previousSibling(); } - return clonedContainer; + return clonedContainer.release(); } PassRefPtr<DocumentFragment> Range::extractContents(ExceptionCode& ec) diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index 36cdf51..51b87cb 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -1102,14 +1102,6 @@ void HTMLInputElement::defaultEventHandler(Event* evt) return; } -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - if (evt->isTouchEvent() && evt->type() == eventNames().touchstartEvent) { - m_inputType->handleTouchStartEvent(static_cast<TouchEvent*>(evt)); - if (evt->defaultHandled()) - return; - } -#endif - m_inputType->forwardEvent(evt); if (!callBaseClassEarly && !evt->defaultHandled()) diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp index 9756313..ba27408 100644 --- a/Source/WebCore/html/InputType.cpp +++ b/Source/WebCore/html/InputType.cpp @@ -310,12 +310,6 @@ void InputType::handleMouseDownEvent(MouseEvent*) { } -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) -void InputType::handleTouchStartEvent(TouchEvent*) -{ -} -#endif - void InputType::handleDOMActivateEvent(Event*) { } diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h index 1b34717..ed69883 100644 --- a/Source/WebCore/html/InputType.h +++ b/Source/WebCore/html/InputType.h @@ -173,10 +173,6 @@ public: virtual void handleWheelEvent(WheelEvent*); virtual void forwardEvent(Event*); -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - virtual void handleTouchStartEvent(TouchEvent*); -#endif - // Helpers for event handlers. virtual bool shouldSubmitImplicitly(Event*); virtual PassRefPtr<HTMLFormElement> formForSubmission() const; diff --git a/Source/WebCore/html/RangeInputType.cpp b/Source/WebCore/html/RangeInputType.cpp index 783eabc..88563c7 100644 --- a/Source/WebCore/html/RangeInputType.cpp +++ b/Source/WebCore/html/RangeInputType.cpp @@ -199,22 +199,6 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event) event->setDefaultHandled(); } -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) -void RangeInputType::handleTouchStartEvent(TouchEvent* touchEvent) -{ - if (SliderThumbElement* thumb = shadowSliderThumb()) { - if (touchEvent->touches() && touchEvent->touches()->item(0)) { - IntPoint curPoint; - curPoint.setX(touchEvent->touches()->item(0)->pageX()); - curPoint.setY(touchEvent->touches()->item(0)->pageY()); - thumb->dragFrom(curPoint); - touchEvent->setDefaultHandled(); - touchEvent->setDefaultPrevented(true); - } - } -} -#endif - void RangeInputType::createShadowSubtree() { ExceptionCode ec = 0; diff --git a/Source/WebCore/html/RangeInputType.h b/Source/WebCore/html/RangeInputType.h index 358a638..75e7a17 100644 --- a/Source/WebCore/html/RangeInputType.h +++ b/Source/WebCore/html/RangeInputType.h @@ -71,10 +71,6 @@ private: virtual bool shouldRespectListAttribute(); SliderThumbElement* shadowSliderThumb() const; - -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - virtual void handleTouchStartEvent(TouchEvent*); -#endif }; } // namespace WebCore diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp index e68ab00..6f4fedb 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.cpp +++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp @@ -87,6 +87,39 @@ void RenderSliderThumb::layout() RenderBlock::layout(); } +#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) +class SliderTouchEventListener : public EventListener { +public: + static PassRefPtr<SliderTouchEventListener> create(SliderThumbElement* slider) + { + return adoptRef(new SliderTouchEventListener(slider)); + } + virtual bool operator==(const EventListener& other) { + return this == &other; + } + virtual void handleEvent(ScriptExecutionContext*, Event* event) + { + if (!event || !event->isTouchEvent()) + return; + TouchEvent* touchEvent = static_cast<TouchEvent*>(event); + if (touchEvent->touches() && touchEvent->touches()->item(0)) { + IntPoint curPoint; + curPoint.setX(touchEvent->touches()->item(0)->pageX()); + curPoint.setY(touchEvent->touches()->item(0)->pageY()); + m_slider->setPositionFromPoint(curPoint); + touchEvent->setDefaultHandled(); + touchEvent->setDefaultPrevented(true); + } + } +private: + SliderTouchEventListener(SliderThumbElement* slider) + : EventListener(NativeEventListenerType) + , m_slider(slider) + {} + SliderThumbElement* m_slider; +}; +#endif + void SliderThumbElement::setPositionFromValue() { // Since today the code to calculate position is in the RenderSlider layout @@ -170,10 +203,6 @@ void SliderThumbElement::stopDragging() if (Frame* frame = document()->frame()) frame->eventHandler()->setCapturingMouseEventsNode(0); -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - if (Frame* frame = document()->frame()) - frame->page()->mainFrame()->eventHandler()->setCapturingTouchEventsNode(0); -#endif m_inDragMode = false; if (renderer()) renderer()->setNeedsLayout(true); @@ -181,82 +210,57 @@ void SliderThumbElement::stopDragging() void SliderThumbElement::defaultEventHandler(Event* event) { - if (!event->isMouseEvent() -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - && !event->isTouchEvent() -#endif - ) { + if (!event->isMouseEvent()) { HTMLDivElement::defaultEventHandler(event); return; } - -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - bool isLeftButton = false; - - if (event->isMouseEvent()) { - MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); - isLeftButton = mouseEvent->button() == LeftButton; - } -#else MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); bool isLeftButton = mouseEvent->button() == LeftButton; -#endif const AtomicString& eventType = event->type(); - if (eventType == eventNames().mousedownEvent && isLeftButton -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - || eventType == eventNames().touchstartEvent -#endif - ) { + if (eventType == eventNames().mousedownEvent && isLeftButton) { startDragging(); return; - } else if (eventType == eventNames().mouseupEvent && isLeftButton -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - || eventType == eventNames().touchendEvent - || eventType == eventNames().touchcancelEvent -#endif - ) { + } else if (eventType == eventNames().mouseupEvent && isLeftButton) { stopDragging(); return; - } else if (eventType == eventNames().mousemoveEvent -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - || eventType == eventNames().touchmoveEvent -#endif - ) { + } else if (eventType == eventNames().mousemoveEvent) { if (m_inDragMode) -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - { - if (event->isMouseEvent()) { - MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); -#endif setPositionFromPoint(mouseEvent->absoluteLocation()); -#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) - } else if (event->isTouchEvent()) { - TouchEvent* touchEvent = static_cast<TouchEvent*>(event); - if (touchEvent->touches() && touchEvent->touches()->item(0)) { - IntPoint curPoint; - curPoint.setX(touchEvent->touches()->item(0)->pageX()); - curPoint.setY(touchEvent->touches()->item(0)->pageY()); - setPositionFromPoint(curPoint); - // Tell the webview that webkit will handle the following move events - event->setDefaultPrevented(true); - } - } - - } -#endif return; } HTMLDivElement::defaultEventHandler(event); } +#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) +void SliderThumbElement::attach() +{ + HTMLDivElement::attach(); + // Add a touch event handler to ensure we get touch events. + if (!m_touchListener) + m_touchListener = SliderTouchEventListener::create(this); + addEventListener(eventNames().touchstartEvent, + m_touchListener, false); + addEventListener(eventNames().touchmoveEvent, + m_touchListener, false); +} +#endif + void SliderThumbElement::detach() { if (m_inDragMode) { if (Frame* frame = document()->frame()) frame->eventHandler()->setCapturingMouseEventsNode(0); } +#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) + if (m_touchListener) { + removeEventListener(eventNames().touchstartEvent, + m_touchListener.get(), false); + removeEventListener(eventNames().touchmoveEvent, + m_touchListener.get(), false); + } +#endif HTMLDivElement::detach(); } diff --git a/Source/WebCore/html/shadow/SliderThumbElement.h b/Source/WebCore/html/shadow/SliderThumbElement.h index 2fa60cb..47e12f1 100644 --- a/Source/WebCore/html/shadow/SliderThumbElement.h +++ b/Source/WebCore/html/shadow/SliderThumbElement.h @@ -44,6 +44,9 @@ class HTMLElement; class HTMLInputElement; class Event; class FloatPoint; +#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) +class SliderTouchEventListener; +#endif class SliderThumbElement : public HTMLDivElement { public: @@ -54,6 +57,9 @@ public: void dragFrom(const IntPoint&); virtual void defaultEventHandler(Event*); +#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) + virtual void attach(); +#endif virtual void detach(); virtual const AtomicString& shadowPseudoId() const; @@ -67,6 +73,10 @@ private: FloatPoint m_offsetToThumb; bool m_inDragMode; +#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS) + RefPtr<EventListener> m_touchListener; + friend class SliderTouchEventListener; +#endif }; inline SliderThumbElement::SliderThumbElement(Document* document) diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.cpp b/Source/WebCore/platform/android/RenderThemeAndroid.cpp index 173cfea..f8e1950 100644 --- a/Source/WebCore/platform/android/RenderThemeAndroid.cpp +++ b/Source/WebCore/platform/android/RenderThemeAndroid.cpp @@ -439,10 +439,8 @@ void RenderThemeAndroid::adjustSliderThumbSize(RenderObject* o) const { static const int sliderThumbWidth = RenderSkinMediaButton::sliderThumbWidth(); static const int sliderThumbHeight = RenderSkinMediaButton::sliderThumbHeight(); - if (o->style()->appearance() == MediaSliderThumbPart) { - o->style()->setWidth(Length(sliderThumbWidth, Fixed)); - o->style()->setHeight(Length(sliderThumbHeight, Fixed)); - } + o->style()->setWidth(Length(sliderThumbHeight, Fixed)); + o->style()->setHeight(Length(sliderThumbWidth, Fixed)); } #endif @@ -647,6 +645,30 @@ bool RenderThemeAndroid::paintMenuListButton(RenderObject* obj, const PaintInfo& return paintCombo(obj, info, rect); } +bool RenderThemeAndroid::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r) +{ + SkCanvas* canvas = getCanvasFromInfo(i); + if (!canvas) + return true; + static const bool translucent = true; + RenderSkinMediaButton::Draw(canvas, r, + RenderSkinMediaButton::SLIDER_TRACK, + translucent, o, false); + return false; +} + +bool RenderThemeAndroid::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r) +{ + SkCanvas* canvas = getCanvasFromInfo(i); + if (!canvas) + return true; + static const bool translucent = true; + RenderSkinMediaButton::Draw(canvas, r, + RenderSkinMediaButton::SLIDER_THUMB, + translucent, 0, false); + return false; +} + Color RenderThemeAndroid::platformFocusRingColor() const { static Color focusRingColor(0x33, 0xB5, 0xE5, 0x66); diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.h b/Source/WebCore/platform/android/RenderThemeAndroid.h index ed4d07f..06d272b 100644 --- a/Source/WebCore/platform/android/RenderThemeAndroid.h +++ b/Source/WebCore/platform/android/RenderThemeAndroid.h @@ -118,6 +118,9 @@ protected: virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); + private: RenderThemeAndroid(); void addIntrinsicMargins(RenderStyle*) const; diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index dc0a304..398beea 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -288,14 +288,14 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded) } // -rect(viewRect) is the webViewRect with inverted Y, in screen coordinate. -// -viewport(visibleRect) is the visible area in document coordinate. +// -visibleRect is the visible area in document coordinate. // They are both based on webViewRect and calculated in Java side. // // -clip is the final glViewport value in screen coordinate, and it contains the // animation translation/scale and FBO offset. // // TODO: Try to decrease the number of parameters as some info is redundant. -int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, +int GLWebViewState::drawGL(IntRect& rect, SkRect& visibleRect, IntRect* invalRect, IntRect& webViewRect, int titleBarHeight, IntRect& clip, float scale, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, @@ -303,14 +303,14 @@ int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, { TilesManager* tilesManager = TilesManager::instance(); if (shouldDraw) - tilesManager->getProfiler()->nextFrame(viewport.fLeft, viewport.fTop, - viewport.fRight, viewport.fBottom, + tilesManager->getProfiler()->nextFrame(visibleRect.fLeft, visibleRect.fTop, + visibleRect.fRight, visibleRect.fBottom, scale); tilesManager->incDrawGLCount(); - ALOGV("drawGL, rect/viewRect(%d, %d, %d, %d), viewport/visibleRect(%.2f, %.2f, %.2f, %.2f)", + ALOGV("drawGL, rect/viewRect(%d, %d, %d, %d), visibleRect(%.2f, %.2f, %.2f, %.2f)", rect.x(), rect.y(), rect.width(), rect.height(), - viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom); + visibleRect.fLeft, visibleRect.fTop, visibleRect.fRight, visibleRect.fBottom); ALOGV("drawGL, invalRect(%d, %d, %d, %d), webViewRect(%d, %d, %d, %d)" "clip/glViewport (%d, %d, %d, %d), scale %f titleBarHeight %d", @@ -340,12 +340,12 @@ int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, // gather the textures we can use tilesManager->gatherTextures(); - double currentTime = setupDrawing(rect, viewport, webViewRect, titleBarHeight, clip, scale); + double currentTime = setupDrawing(rect, visibleRect, webViewRect, titleBarHeight, clip, scale); TexturesResult nbTexturesNeeded; bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering; - m_glExtras.setViewport(viewport); - returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, rect, viewport, + m_glExtras.setViewport(visibleRect); + returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, rect, visibleRect, scale, fastSwap, collectionsSwappedPtr, newCollectionHasAnimPtr, &nbTexturesNeeded, shouldDraw); diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h index 2b28619..8d0f214 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.h +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h @@ -177,7 +177,7 @@ public: bool setLayersRenderingMode(TexturesResult&); - int drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, + int drawGL(IntRect& rect, SkRect& visibleRect, IntRect* invalRect, IntRect& webViewRect, int titleBarHeight, IntRect& clip, float scale, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, diff --git a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h index bce82f2..719df14 100644 --- a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h +++ b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h @@ -29,7 +29,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "Color.h" -#include "FloatPoint.h" +#include "FloatRect.h" #include "SkRect.h" #include <GLES2/gl2.h> @@ -51,13 +51,14 @@ public: const SkRect* geometry = 0, float opacity = 1.0f, bool forceBlending = true, - FloatPoint fillPortion = FloatPoint(1.0f, 1.0f)) + FloatRect fillPortion = FloatRect(0.0f, 0.0f, 1.0f, 1.0f)) : m_type(type) , m_drawMatrix(drawMatrix) , m_geometry(geometry) , m_opacity(opacity) , m_forceBlending(forceBlending) - , m_fillPortion(fillPortion.x(), fillPortion.y()) + , m_fillPortion(fillPortion.x(), fillPortion.y(), + fillPortion.width(), fillPortion.height()) { } @@ -67,7 +68,8 @@ public: , m_geometry(data.m_geometry) , m_opacity(data.m_opacity) , m_forceBlending(data.m_forceBlending) - , m_fillPortion(data.m_fillPortion.x(), data.m_fillPortion.y()) + , m_fillPortion(data.m_fillPortion.x(), data.m_fillPortion.y(), + data.m_fillPortion.width(), data.m_fillPortion.height()) { } @@ -90,7 +92,7 @@ public: virtual int textureId() const { return 0; } virtual GLint textureFilter() const { return 0; } virtual GLenum textureTarget() const { return 0; } - virtual FloatPoint fillPortion() const { return m_fillPortion; } + virtual FloatRect fillPortion() const { return m_fillPortion; } private: DrawQuadType m_type; @@ -98,7 +100,7 @@ private: const SkRect* m_geometry; float m_opacity; bool m_forceBlending; - FloatPoint m_fillPortion; + FloatRect m_fillPortion; }; class PureColorQuadData : public DrawQuadData { diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp index 817efb8..206fa27 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp @@ -44,14 +44,16 @@ namespace WebCore { +// fillPortion.xy = starting UV coordinate. +// fillPortion.zw = UV coordinate width and height. static const char gVertexShader[] = "attribute vec4 vPosition;\n" "uniform mat4 projectionMatrix;\n" - "uniform vec2 fillPortion;\n" + "uniform vec4 fillPortion;\n" "varying vec2 v_texCoord;\n" "void main() {\n" " gl_Position = projectionMatrix * vPosition;\n" - " v_texCoord = vPosition.xy * fillPortion;\n" + " v_texCoord = vPosition.xy * fillPortion.zw + fillPortion.xy;\n" "}\n"; static const char gFragmentShader[] = @@ -376,23 +378,9 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR m_titleBarHeight = titleBarHeight; //// viewport //// - TransformationMatrix ortho; - GLUtils::setOrthographicMatrix(ortho, visibleRect.fLeft, visibleRect.fTop, - visibleRect.fRight, visibleRect.fBottom, -1000, 1000); - // In most case , visibleRect / viewRect * scale should 1.0, but for the - // translation case, the scale factor can be 1 but visibleRect is smaller - // than viewRect, we need to tune in this factor to make sure we scale them - // right. Conceptually, that means, no matter how animation affects the - // visibleRect, the scaling should respect the viewRect if zoomScale is 1.0. - // Note that at TiledPage, we already scale the tile size inversely to make - // zooming animation right. - float orthoScaleX = scale * visibleRect.width() / viewRect.width(); - float orthoScaleY = scale * visibleRect.height() / viewRect.height(); - - TransformationMatrix orthoScale; - orthoScale.scale3d(orthoScaleX, orthoScaleY, 1.0); - - m_visibleRectProjectionMatrix = ortho * orthoScale; + GLUtils::setOrthographicMatrix(m_visibleRectProjectionMatrix, visibleRect.fLeft, + visibleRect.fTop, visibleRect.fRight, visibleRect.fBottom, + -1000, 1000); ALOGV("set m_clipProjectionMatrix, %d, %d, %d, %d", screenClip.x(), screenClip.y(), screenClip.x() + screenClip.width(), @@ -594,7 +582,7 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId, float opacity, GLenum textureTarget, GLenum filter, - const Color& pureColor, const FloatPoint& fillPortion) + const Color& pureColor, const FloatRect& fillPortion) { glUseProgram(m_handleArray[type].programHandle); glUniformMatrix4fv(m_handleArray[type].projMtxHandle, 1, GL_FALSE, matrix); @@ -611,7 +599,8 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix, if (contrastHandle != -1) glUniform1f(contrastHandle, m_contrast); - glUniform2f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y()); + glUniform4f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y(), + fillPortion.width(), fillPortion.height()); } else { glUniform4f(m_handleArray[type].pureColorHandle, pureColor.red() / 255.0, pureColor.green() / 255.0, @@ -643,7 +632,7 @@ GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data) const TransformationMatrix* matrix = data->drawMatrix(); const SkRect* geometry = data->geometry(); - FloatPoint fillPortion = data->fillPortion(); + FloatRect fillPortion = data->fillPortion(); // This modifiedDrawMatrix tranform (0,0)(1x1) to the final rect in screen // coordinate, before applying the m_webViewMatrix. // It first scale and translate the vertex array from (0,0)(1x1) to real @@ -654,9 +643,10 @@ GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data) TransformationMatrix modifiedDrawMatrix; if (type == LayerQuad) modifiedDrawMatrix = *matrix; - modifiedDrawMatrix.translate(geometry->fLeft, geometry->fTop); - modifiedDrawMatrix.scale3d(geometry->width() * fillPortion.x(), - geometry->height() * fillPortion.y(), 1); + modifiedDrawMatrix.translate(geometry->fLeft + geometry->width() * fillPortion.x(), + geometry->fTop + geometry->height() * fillPortion.y()); + modifiedDrawMatrix.scale3d(geometry->width() * fillPortion.width(), + geometry->height() * fillPortion.height(), 1); // Even when we are on a alpha layer or not, we need to respect the // m_webViewMatrix, it may contain the layout offset. Normally it is diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h index e290242..8c9e301 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h @@ -167,7 +167,7 @@ private: void setBlendingState(bool enableBlending); void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId, float opacity, GLenum textureTarget, GLenum filter, - const Color& pureColor, const FloatPoint& fillPortion); + const Color& pureColor, const FloatRect& fillPortion); Color shaderColor(Color pureColor, float opacity); ShaderType getTextureShaderType(GLenum textureTarget); void resetBlending(); diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp index 0501777..2ee45b0 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp @@ -210,7 +210,7 @@ void Tile::setRepaintPending(bool pending) bool Tile::drawGL(float opacity, const SkRect& rect, float scale, const TransformationMatrix* transform, bool forceBlending, bool usePointSampling, - const FloatPoint& fillPortion) + const FloatRect& fillPortion) { if (m_x < 0 || m_y < 0 || m_scale != scale) return false; @@ -220,9 +220,11 @@ bool Tile::drawGL(float opacity, const SkRect& rect, float scale, if (!m_frontTexture) return false; - if (fillPortion.x() < 1.0f || fillPortion.y() < 1.0f) - ALOGV("drawing tile %p (%d, %d with fill portions %f %f", - this, m_x, m_y, fillPortion.x(), fillPortion.y()); + if (fillPortion.maxX() < 1.0f || fillPortion.maxY() < 1.0f + || fillPortion.x() > 0.0f || fillPortion.y() > 0.0f) + ALOGV("drawing tile %p (%d, %d with fill portions %f %f->%f, %f", + this, m_x, m_y, fillPortion.x(), fillPortion.y(), + fillPortion.maxX(), fillPortion.maxY()); m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform, forceBlending, usePointSampling, fillPortion); diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h index 58ba15b..c115f1c 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.h +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h @@ -104,7 +104,7 @@ public: bool drawGL(float opacity, const SkRect& rect, float scale, const TransformationMatrix* transform, bool forceBlending, bool usePointSampling, - const FloatPoint& fillPortion); + const FloatRect& fillPortion); // the only thread-safe function called by the background thread void paintBitmap(TilePainter* painter); diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp index 7c6175f..8bf033e 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp @@ -296,10 +296,12 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, bool usePointSampling = TilesManager::instance()->shader()->usePointSampling(m_scale, transform); - + float minTileX = visibleArea.x() / tileWidth; + float minTileY = visibleArea.y() / tileWidth; float maxTileWidth = visibleArea.maxX() / tileWidth; float maxTileHeight = visibleArea.maxY() / tileWidth; - + ALOGV("minTileX, minTileY, maxTileWidth, maxTileHeight %f, %f, %f %f", + minTileX, minTileY, maxTileWidth, maxTileHeight); for (unsigned int i = 0; i < m_tiles.size(); i++) { Tile* tile = m_tiles[i]; @@ -316,8 +318,20 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, bool forceBaseBlending = background ? background->hasAlpha() : false; - FloatPoint fillPortion(std::min(maxTileWidth - tile->x(), 1.0f), - std::min(maxTileHeight - tile->y(), 1.0f)); + float left = std::max(minTileX - tile->x(), 0.0f); + float top = std::max(minTileY - tile->y(), 0.0f); + float right = std::min(maxTileWidth - tile->x(), 1.0f); + float bottom = std::min(maxTileHeight - tile->y(), 1.0f); + if (left > 1.0f || top > 1.0f || right < 0.0f || bottom < 0.0f) { + ALOGE("Unexpected portion:left, top, right, bottom %f %f %f %f", + left, top, right, bottom); + left = 0.0f; + top = 0.0f; + right = 1.0f; + bottom = 1.0f; + } + FloatRect fillPortion(left, top, right - left, bottom - top); + bool success = tile->drawGL(opacity, rect, m_scale, transform, forceBaseBlending, usePointSampling, fillPortion); if (semiOpaqueBaseSurface && success) { diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp index 54c67cc..be4b4db 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp @@ -121,7 +121,7 @@ void TileTexture::transferComplete() void TileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity, const TransformationMatrix* transform, bool forceBlending, bool usePointSampling, - const FloatPoint& fillPortion) + const FloatRect& fillPortion) { ShaderProgram* shader = TilesManager::instance()->shader(); diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h index b694241..e31da5b 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h +++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h @@ -27,7 +27,7 @@ #define TileTexture_h #include "Color.h" -#include "FloatPoint.h" +#include "FloatRect.h" #include "SkBitmap.h" #include "SkRect.h" #include "SkSize.h" @@ -82,7 +82,7 @@ public: void drawGL(bool isLayer, const SkRect& rect, float opacity, const TransformationMatrix* transform, bool forceBlending, bool usePointSampling, - const FloatPoint& fillPortion); + const FloatRect& fillPortion); private: TextureInfo m_ownTextureInfo; SkSize m_size; diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp index 66aab18..1ffa0de 100644 --- a/Source/WebCore/rendering/RenderLayer.cpp +++ b/Source/WebCore/rendering/RenderLayer.cpp @@ -1449,7 +1449,8 @@ void RenderLayer::scrollTo(int x, int y) #endif // Schedule the scroll DOM event. - renderer()->node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(renderer()->node(), EventQueue::ScrollEventElementTarget); + if (renderer()->node()) + renderer()->node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(renderer()->node(), EventQueue::ScrollEventElementTarget); } void RenderLayer::scrollRectToVisible(const IntRect& rect, bool scrollToAnchor, const ScrollAlignment& alignX, const ScrollAlignment& alignY) |