diff options
author | Nicolas Roard <nicolas@android.com> | 2010-11-03 19:49:27 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2011-04-11 15:04:49 -0700 |
commit | 6edf92433a1c328f0b8e166fefc687e691dd7298 (patch) | |
tree | edd77425c5f5346916789f88001b7ba698c63331 | |
parent | 5ba4a087b9212ca9ae083f015637f417199d85cc (diff) | |
download | external_webkit-6edf92433a1c328f0b8e166fefc687e691dd7298.zip external_webkit-6edf92433a1c328f0b8e166fefc687e691dd7298.tar.gz external_webkit-6edf92433a1c328f0b8e166fefc687e691dd7298.tar.bz2 |
Implements the focus ring drawing in GL.
In WebView::drawGL(), we check if the extras to draw are rings,
and if so we get their rectangles and pass that to GLWebViewState.
Updated with holo colors
Change-Id: Id5f8941f16dba1733e8a84eae8cd2b317fbc7c55
-rw-r--r-- | WebCore/platform/graphics/android/BaseLayerAndroid.cpp | 1 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GLUtils.cpp | 19 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GLUtils.h | 1 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GLWebViewState.cpp | 67 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GLWebViewState.h | 8 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/android_graphics.h | 1 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 17 |
7 files changed, 108 insertions, 6 deletions
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index c61a09a..ebf8c88 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -258,6 +258,7 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double m_glWebViewState->unlockBaseLayerUpdate(); } + m_glWebViewState->paintExtras(); return needsRedraw; } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/GLUtils.cpp b/WebCore/platform/graphics/android/GLUtils.cpp index 19be5c7..5eabb85 100644 --- a/WebCore/platform/graphics/android/GLUtils.cpp +++ b/WebCore/platform/graphics/android/GLUtils.cpp @@ -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; diff --git a/WebCore/platform/graphics/android/GLUtils.h b/WebCore/platform/graphics/android/GLUtils.h index 64aedbb..1e8df39 100644 --- a/WebCore/platform/graphics/android/GLUtils.h +++ b/WebCore/platform/graphics/android/GLUtils.h @@ -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); diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp index 6f95836..1400db5 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -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,13 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval TilesManager::instance()->setShowVisualIndicator(showVisualIndicator); } +void GLWebViewState::setRings(Vector<IntRect>& rings) +{ + android::Mutex::Autolock lock(m_baseLayerLock); + m_displayRings = true; + m_rings = rings; +} + void GLWebViewState::invalRegion(const SkRegion& region) { SkRegion::Iterator iterator(region); @@ -197,6 +208,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 +232,61 @@ void GLWebViewState::inval(const IntRect& rect) } } +void GLWebViewState::resetRings() +{ + m_displayRings = false; +} + +void GLWebViewState::drawFocusRing(IntRect& rect) +{ + // TODO: use a 9-patch texture to draw the focus ring + // instead of plain colors + const int border = 1; + const int fuzzyBorder = border * 2; + const float alpha = 0.16; + const float borderAlpha = 0.30; + + const int r = 104; + const int g = 153; + const int b = 255; + + if (m_focusRingTexture == -1) + m_focusRingTexture = GLUtils::createSampleColorTexture(r, g, b); + + SkRect rLeft, rTop, rRight, rBottom, rRect; + + 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); + rRect.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); + TilesManager::instance()->shader()->drawQuad(rRect, 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); diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h index ac75605..7892337 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.h +++ b/WebCore/platform/graphics/android/GLWebViewState.h @@ -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); + void resetRings(); + void drawFocusRing(IntRect& rect); TiledPage* sibling(TiledPage* page); TiledPage* frontPage(); @@ -283,6 +288,9 @@ private: double m_delayTimes[MAX_MEASURES_PERF]; bool m_measurePerfs; #endif + bool m_displayRings; + Vector<IntRect> m_rings; + int m_focusRingTexture; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/android/android_graphics.h b/WebCore/platform/graphics/android/android_graphics.h index be309a6..89312b5 100644 --- a/WebCore/platform/graphics/android/android_graphics.h +++ b/WebCore/platform/graphics/android/android_graphics.h @@ -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 diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 5b71948..fe69eae 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -485,13 +485,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()); + } 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); |