summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Roard <nicolas@android.com>2010-11-03 19:49:27 -0700
committerJohn Reck <jreck@google.com>2011-04-11 15:04:49 -0700
commit6edf92433a1c328f0b8e166fefc687e691dd7298 (patch)
treeedd77425c5f5346916789f88001b7ba698c63331
parent5ba4a087b9212ca9ae083f015637f417199d85cc (diff)
downloadexternal_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.cpp1
-rw-r--r--WebCore/platform/graphics/android/GLUtils.cpp19
-rw-r--r--WebCore/platform/graphics/android/GLUtils.h1
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp67
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.h8
-rw-r--r--WebCore/platform/graphics/android/android_graphics.h1
-rw-r--r--WebKit/android/nav/WebView.cpp17
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);