OSDN Git Service

am 58348114: Merge "DO NOT MERGE cursor ring drawing in GL" into honeycomb-mr2
authorJohn Reck <jreck@google.com>
Fri, 13 May 2011 00:35:33 +0000 (17:35 -0700)
committerAndroid Git Automerger <android-git-automerger@android.com>
Fri, 13 May 2011 00:35:33 +0000 (17:35 -0700)
* commit '58348114645f3987aaabae40612a876cfd2bc678':
  DO NOT MERGE cursor ring drawing in GL

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

index d17f9c8..09d80a1 100644 (file)
@@ -258,6 +258,7 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
         m_glWebViewState->unlockBaseLayerUpdate();
     }
 
+    m_glWebViewState->paintExtras();
     return needsRedraw;
 }
 #endif // USE(ACCELERATED_COMPOSITING)
index 23bf525..1b0d4be 100644 (file)
@@ -289,6 +289,25 @@ void GLUtils::deleteTexture(GLuint* texture)
     *texture = 0;
 }
 
+GLuint GLUtils::createSampleColorTexture(int r, int g, int b) {
+    GLuint texture;
+    glGenTextures(1, &texture);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    GLubyte pixels[4 *3] = {
+        r, g, b,
+        r, g, b,
+        r, g, b,
+        r, g, b
+    };
+    glBindTexture(GL_TEXTURE_2D, texture);
+    GLUtils::checkGlError("glBindTexture");
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+    GLUtils::checkGlError("glTexImage2D");
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    return texture;
+}
+
 GLuint GLUtils::createSampleTexture()
 {
     GLuint texture;
index 64aedbb..1e8df39 100644 (file)
@@ -59,6 +59,7 @@ public:
     // Texture utilities
     static EGLContext createBackgroundContext(EGLContext sharedContext);
     static void deleteTexture(GLuint* texture);
+    static GLuint createSampleColorTexture(int r, int g, int b);
     static GLuint createSampleTexture();
     static void createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR);
     static void updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint filter = GL_LINEAR);
index 6f95836..4acd563 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "BaseLayerAndroid.h"
 #include "ClassTracker.h"
+#include "GLUtils.h"
 #include "LayerAndroid.h"
 #include "TilesManager.h"
 #include <wtf/CurrentTime.h>
@@ -78,6 +79,8 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
     , m_baseLayerUpdate(true)
     , m_backgroundColor(SK_ColorWHITE)
     , m_prevDrawTime(0)
+    , m_displayRings(false)
+    , m_focusRingTexture(-1)
 {
     m_viewport.setEmpty();
     m_previousViewport.setEmpty();
@@ -144,6 +147,7 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval
         SkSafeUnref(m_currentBaseLayer);
         m_currentBaseLayer = layer;
     }
+    m_displayRings = false;
     invalRegion(inval);
 
 #ifdef MEASURES_PERF
@@ -155,6 +159,14 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval
     TilesManager::instance()->setShowVisualIndicator(showVisualIndicator);
 }
 
+void GLWebViewState::setRings(Vector<IntRect>& rings, bool isPressed)
+{
+    android::Mutex::Autolock lock(m_baseLayerLock);
+    m_displayRings = true;
+    m_rings = rings;
+    m_ringsIsPressed = isPressed;
+}
+
 void GLWebViewState::invalRegion(const SkRegion& region)
 {
     SkRegion::Iterator iterator(region);
@@ -197,6 +209,7 @@ void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture,
     if (!m_lastInval.isEmpty())
         inval(m_lastInval);
     m_lastInval = rect;
+    m_displayRings = false;
 }
 
 void GLWebViewState::inval(const IntRect& rect)
@@ -220,6 +233,87 @@ void GLWebViewState::inval(const IntRect& rect)
     }
 }
 
+void GLWebViewState::resetRings()
+{
+    m_displayRings = false;
+}
+
+void GLWebViewState::drawFocusRing(IntRect& srcRect)
+{
+    // TODO: use a 9-patch texture to draw the focus ring
+    // instead of plain colors
+    const float alpha = 0.3;
+    float borderAlpha = 0.40;
+
+    const int r = 104;
+    const int g = 153;
+    const int b = 255;
+
+    int padding = 4;
+    int border = 1;
+    int fuzzyBorder = border * 2;
+    if (!m_ringsIsPressed) {
+        padding = 0;
+        border = 2;
+        fuzzyBorder = 3;
+        borderAlpha = 0.2;
+    }
+    if (m_focusRingTexture == -1)
+        m_focusRingTexture = GLUtils::createSampleColorTexture(r, g, b);
+
+    SkRect rLeft, rTop, rRight, rBottom, rOverlay;
+
+    IntRect rect(srcRect.x() - padding, srcRect.y() - padding,
+                 srcRect.width() + (padding * 2), srcRect.height() + (padding * 2));
+    rLeft.set(rect.x() - border, rect.y(),
+              rect.x(), rect.y() + rect.height());
+    rTop.set(rect.x() - border, rect.y() - border,
+             rect.x() + rect.width() + border, rect.y());
+    rRight.set(rect.x() + rect.width(), rect.y(),
+               rect.x() + rect.width() + border,
+               rect.y() + rect.height());
+    rBottom.set(rect.x() - border, rect.y() + rect.height(),
+                rect.x() + rect.width() + border,
+                rect.y() + rect.height() + border);
+    rOverlay.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder,
+              rect.x() + rect.width() + fuzzyBorder,
+              rect.y() + rect.height() + fuzzyBorder);
+
+    TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, borderAlpha);
+    TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, borderAlpha);
+    TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, borderAlpha);
+    TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, borderAlpha);
+    if (m_ringsIsPressed) {
+        TilesManager::instance()->shader()->drawQuad(rOverlay, m_focusRingTexture, alpha);
+    } else {
+        rLeft.set(rect.x() - fuzzyBorder, rect.y(),
+                  rect.x(), rect.y() + rect.height());
+        rTop.set(rect.x() - fuzzyBorder, rect.y() - fuzzyBorder,
+                 rect.x() + rect.width() + fuzzyBorder, rect.y());
+        rRight.set(rect.x() + rect.width(), rect.y(),
+                   rect.x() + rect.width() + fuzzyBorder,
+                   rect.y() + rect.height());
+        rBottom.set(rect.x() - fuzzyBorder, rect.y() + rect.height(),
+                    rect.x() + rect.width() + fuzzyBorder,
+                    rect.y() + rect.height() + fuzzyBorder);
+        TilesManager::instance()->shader()->drawQuad(rLeft, m_focusRingTexture, alpha);
+        TilesManager::instance()->shader()->drawQuad(rTop, m_focusRingTexture, alpha);
+        TilesManager::instance()->shader()->drawQuad(rRight, m_focusRingTexture, alpha);
+        TilesManager::instance()->shader()->drawQuad(rBottom, m_focusRingTexture, alpha);
+    }
+}
+
+void GLWebViewState::paintExtras()
+{
+    if (m_displayRings) {
+        // TODO: handles correctly the multi-rings case
+        for (int i=0; i<m_rings.size(); i++) {
+            IntRect rect = m_rings.at(i);
+            drawFocusRing(rect);
+        }
+    }
+}
+
 unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas)
 {
     android::Mutex::Autolock lock(m_baseLayerLock);
index ac75605..980dd3c 100644 (file)
@@ -179,6 +179,11 @@ public:
                       bool isPictureAfterFirstLayout);
     void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&, bool allowSame);
     void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale);
+    void paintExtras();
+
+    void setRings(Vector<IntRect>& rings, bool isPressed);
+    void resetRings();
+    void drawFocusRing(IntRect& rect);
 
     TiledPage* sibling(TiledPage* page);
     TiledPage* frontPage();
@@ -283,6 +288,10 @@ private:
     double m_delayTimes[MAX_MEASURES_PERF];
     bool m_measurePerfs;
 #endif
+    bool m_displayRings;
+    Vector<IntRect> m_rings;
+    bool m_ringsIsPressed;
+    int m_focusRingTexture;
 };
 
 } // namespace WebCore
index be309a6..89312b5 100644 (file)
@@ -56,6 +56,7 @@ public:
     virtual void draw(SkCanvas* , LayerAndroid* , IntRect* );
     void setIsButton(const CachedNode* );
     bool setup();
+    WTF::Vector<IntRect>& rings() { return m_rings; }
 private:
     friend class WebView;
     WebViewCore* m_viewImpl; // copy for convenience
index b294112..f29d218 100644 (file)
@@ -470,13 +470,18 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In
     SkPicture picture;
     IntRect rect(0, 0, 0, 0);
     bool allowSame = false;
+    m_glWebViewState->resetRings();
     if (extra) {
-        LayerAndroid mainPicture(m_navPictureUI);
-        PictureSet* content = m_baseLayer->content();
-        SkCanvas* canvas = picture.beginRecording(content->width(),
-            content->height());
-        extra->draw(canvas, &mainPicture, &rect);
-        picture.endRecording();
+        if (extra == &m_ring) {
+            m_glWebViewState->setRings(m_ring.rings(), m_ring.m_isPressed);
+        } else {
+            LayerAndroid mainPicture(m_navPictureUI);
+            PictureSet* content = m_baseLayer->content();
+            SkCanvas* canvas = picture.beginRecording(content->width(),
+                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);