OSDN Git Service

fix buttons in GL
authorCary Clark <cary@android.com>
Tue, 15 Feb 2011 19:57:24 +0000 (14:57 -0500)
committerCary Clark <cary@android.com>
Tue, 15 Feb 2011 20:27:33 +0000 (15:27 -0500)
Buttons failed to draw when selected with the keyboard, and
sometimes when selected by touch, for three reasons:

1) GL short-circuits if the last extra rectangle and the
   curent extra rectangle match. When buttons change color,
   the rectangles do match, but the picture still needs to
   be redrawn.

2) Buttons do not have cursor rings, so the button's bounds
   was not passed to GL.

3) The timeout logic to switch from a focused state to a normal
   state was incorrect.

This adds a flag to GLWebViewState::setExtra that can skip the
equal rectangle case. Note that the equal rectangle test hides
a more serious bug where the setExtra is called repeatedly -- so
it would be worthwhile to examine this further.

The logic that determines if the cursor is a button was split
out so that the cursor ring can be associated with a button even
if the cursor is hidden.

bug:3364248
Change-Id: I75944cb045486c128743aa13922d20758ccf783f

WebCore/platform/graphics/android/GLWebViewState.cpp
WebCore/platform/graphics/android/GLWebViewState.h
WebCore/platform/graphics/android/android_graphics.cpp
WebCore/platform/graphics/android/android_graphics.h
WebKit/android/nav/WebView.cpp

index 5ba094b..53d5c5e 100644 (file)
@@ -127,7 +127,7 @@ void GLWebViewState::unlockBaseLayerUpdate() {
 }
 
 void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture,
-    const IntRect& rect)
+    const IntRect& rect, bool allowSame)
 {
     android::Mutex::Autolock lock(m_baseLayerLock);
     if (!m_baseLayerUpdate)
@@ -135,7 +135,7 @@ void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture,
 
     layer->setExtra(picture);
 
-    if (m_lastInval == rect)
+    if (!allowSame && m_lastInval == rect)
         return;
 
     if (!rect.isEmpty())
index 2082f2c..d28c16a 100644 (file)
@@ -169,7 +169,7 @@ public:
 
     unsigned int paintBaseLayerContent(SkCanvas* canvas);
     void setBaseLayer(BaseLayerAndroid* layer, const IntRect& rect);
-    void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&);
+    void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&, bool allowSame);
     void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale);
 
     TiledPage* sibling(TiledPage* page);
index c046858..e50cfec 100644 (file)
@@ -109,14 +109,8 @@ void CursorRing::draw(SkCanvas* canvas, LayerAndroid* layer, IntRect* inval)
     inval->unite(m_lastBounds);
 }
 
-bool CursorRing::setup()
+void CursorRing::setIsButton(const CachedNode* node)
 {
-    m_node->localCursorRings(m_frame, &m_rings);
-    if (!m_rings.size()) {
-        DBG_NAV_LOG("!rings.size()");
-        m_viewImpl->m_hasCursorBounds = false;
-        return false;
-    }
     m_isButton = false;
     m_viewImpl->gButtonMutex.lock();
     // If this is a button drawn by us (rather than webkit) do not draw the
@@ -124,7 +118,7 @@ bool CursorRing::setup()
     // Should be in sync with recordButtons, since that will be called
     // before this.
     if (m_viewImpl->m_buttons.size() > 0) {
-        WebCore::Node* cursorPointer = (WebCore::Node*) m_node->nodePointer();
+        WebCore::Node* cursorPointer = (WebCore::Node*) node->nodePointer();
         Container* end = m_viewImpl->m_buttons.end();
         for (Container* ptr = m_viewImpl->m_buttons.begin(); ptr != end; ptr++) {
             if (ptr->matches(cursorPointer)) {
@@ -134,6 +128,17 @@ bool CursorRing::setup()
         }
     }
     m_viewImpl->gButtonMutex.unlock();
+}
+
+bool CursorRing::setup()
+{
+    m_node->localCursorRings(m_frame, &m_rings);
+    if (!m_rings.size()) {
+        DBG_NAV_LOG("!rings.size()");
+        m_viewImpl->m_hasCursorBounds = false;
+        return false;
+    }
+    setIsButton(m_node);
     m_bounds = m_node->localBounds(m_frame);
     m_viewImpl->updateCursorBounds(m_root, m_frame, m_node);
 
index 9f52a27..be309a6 100644 (file)
@@ -54,6 +54,7 @@ public:
     CursorRing(WebViewCore* core) : m_viewImpl(core) {}
     virtual ~CursorRing() {}
     virtual void draw(SkCanvas* , LayerAndroid* , IntRect* );
+    void setIsButton(const CachedNode* );
     bool setup();
 private:
     friend class WebView;
index 948ea6b..deb2b28 100644 (file)
@@ -303,10 +303,8 @@ void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate)
                 if (hasFocus) {
                     if (pressed || m_ring.m_isPressed)
                         state = RenderSkinAndroid::kPressed;
-                    else if (SkTime::GetMSecs() < m_ringAnimationEnd
-                        && m_ringAnimationEnd != UINT_MAX) {
+                    else if (SkTime::GetMSecs() < m_ringAnimationEnd)
                         state = RenderSkinAndroid::kFocused;
-                    }
                 }
             }
             ptr->updateFocusState(state);
@@ -390,6 +388,7 @@ bool drawCursorPreamble(CachedRoot* root)
         resetCursorRing();
         return false;
     }
+    m_ring.setIsButton(node);
     if (node->isHidden()) {
         DBG_NAV_LOG("node->isHidden()");
         m_viewImpl->m_hasCursorBounds = false;
@@ -473,6 +472,7 @@ bool drawGL(WebCore::IntRect& viewRect, float scale, int extras)
 
     SkPicture picture;
     IntRect rect(0, 0, 0, 0);
+    bool allowSame = false;
     if (extra) {
         LayerAndroid mainPicture(m_navPictureUI);
         PictureSet* content = m_baseLayer->content();
@@ -480,8 +480,15 @@ bool drawGL(WebCore::IntRect& viewRect, float scale, int extras)
             content->height());
         extra->draw(canvas, &mainPicture, &rect);
         picture.endRecording();
+    } else if (extras == DrawExtrasCursorRing && m_ring.m_isButton) {
+        const CachedFrame* cachedFrame;
+        const CachedNode* cachedCursor = root->currentCursor(&cachedFrame);
+        if (cachedCursor) {
+            rect = cachedCursor->bounds(cachedFrame);
+            allowSame = true;
+        }
     }
-    m_glWebViewState->setExtra(m_baseLayer, picture, rect);
+    m_glWebViewState->setExtra(m_baseLayer, picture, rect, allowSame);
 
     LayerAndroid* compositeLayer = compositeRoot();
     if (compositeLayer)