summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp22
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h3
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.h1
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h9
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h2
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp6
-rw-r--r--Source/WebKit/android/jni/ViewStateSerializer.cpp32
-rw-r--r--Source/WebKit/android/nav/WebView.cpp22
9 files changed, 72 insertions, 29 deletions
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 85fa23f..09c647b 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -183,7 +183,7 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval
TilesManager::instance()->setShowVisualIndicator(showVisualIndicator);
}
-void GLWebViewState::setRings(Vector<IntRect>& rings, bool isPressed)
+void GLWebViewState::setRings(Vector<IntRect>& rings, bool isPressed, bool isButton)
{
android::Mutex::Autolock lock(m_baseLayerLock);
m_displayRings = true;
@@ -195,6 +195,7 @@ void GLWebViewState::setRings(Vector<IntRect>& rings, bool isPressed)
m_rings.op(rings.at(i), SkRegion::kUnion_Op);
}
m_ringsIsPressed = isPressed;
+ m_ringsIsButton = isButton;
}
void GLWebViewState::invalRegion(const SkRegion& region)
@@ -277,6 +278,10 @@ void GLWebViewState::drawFocusRing(SkRect& srcRect)
RING_COLOR_G,
RING_COLOR_B);
+ if (srcRect.fRight <= srcRect.fLeft || srcRect.fBottom <= srcRect.fTop) {
+ // Invalid rect, reject it
+ return;
+ }
TilesManager::instance()->shader()->drawQuad(srcRect, m_focusRingTexture,
RING_COLOR_ALPHA);
}
@@ -284,6 +289,16 @@ void GLWebViewState::drawFocusRing(SkRect& srcRect)
void GLWebViewState::paintExtras()
{
if (m_displayRings && !m_rings.isEmpty()) {
+ // Update the clip
+ SkIRect skbounds = m_rings.getBounds();
+ if (skbounds.isEmpty())
+ return;
+ FloatRect glclip;
+ glclip.setX(skbounds.fLeft);
+ glclip.setY(skbounds.fTop);
+ glclip.setWidth(skbounds.fRight - skbounds.fLeft);
+ glclip.setHeight(skbounds.fBottom - skbounds.fTop);
+ TilesManager::instance()->shader()->clip(glclip);
if (m_ringsIsPressed) {
SkRegion::Iterator rgnIter(m_rings);
while (!rgnIter.done()) {
@@ -294,6 +309,8 @@ void GLWebViewState::paintExtras()
rgnIter.next();
}
}
+ if (m_ringsIsButton && m_ringsIsPressed)
+ return;
SkPath path;
if (!m_rings.getBoundaryPath(&path))
return;
@@ -589,9 +606,6 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
double currentTime = setupDrawing(rect, viewport, webViewRect, titleBarHeight, clip, scale);
bool ret = baseLayer->drawGL(currentTime, compositedRoot, rect,
viewport, scale, buffersSwappedPtr);
- // Reset the clip to make sure we can draw the rings. If this isn't done, the
- // current clip will be the clip of whatever layer was last drawn
- TilesManager::instance()->shader()->clip(clip);
paintExtras();
glBindBuffer(GL_ARRAY_BUFFER, 0);
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index 6c7d31e..27e8148 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -177,7 +177,7 @@ public:
void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&, bool allowSame);
void paintExtras();
- void setRings(Vector<IntRect>& rings, bool isPressed);
+ void setRings(Vector<IntRect>& rings, bool isPressed, bool isButton);
void resetRings();
void drawFocusRing(SkRect& rect);
@@ -271,6 +271,7 @@ private:
bool m_displayRings;
SkRegion m_rings;
bool m_ringsIsPressed;
+ bool m_ringsIsButton;
int m_focusRingTexture;
bool m_isScrolling;
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/ImageTexture.h
index 7e51d2b..c2ea77c 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.h
+++ b/Source/WebCore/platform/graphics/android/ImageTexture.h
@@ -70,6 +70,7 @@ public:
void release();
unsigned int refCount() { return m_refCount; }
SkBitmapRef* imageRef() { return m_imageRef; }
+ SkBitmap* bitmap() { return m_image; }
private:
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index 38d867f..cd52937 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -57,6 +57,7 @@ namespace android {
class DrawExtra;
void serializeLayer(WebCore::LayerAndroid* layer, SkWStream* stream);
WebCore::LayerAndroid* deserializeLayer(SkStream* stream);
+void cleanupImageRefs(WebCore::LayerAndroid* layer);
}
using namespace android;
@@ -266,8 +267,10 @@ public:
void setIsIframe(bool isIframe) { m_isIframe = isIframe; }
float zValue() const { return m_zValue; }
+ // ViewStateSerializer friends
friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
friend LayerAndroid* android::deserializeLayer(SkStream* stream);
+ friend void android::cleanupImageRefs(LayerAndroid* layer);
PaintedSurface* texture() { return m_texture; }
void assignTextureTo(LayerAndroid* newTree);
@@ -330,16 +333,14 @@ private:
float m_anchorPointZ;
float m_drawOpacity;
- // Note that m_recordingPicture and m_contentsImage are mutually exclusive;
+ // Note that m_recordingPicture and m_imageRef are mutually exclusive;
// m_recordingPicture is used when WebKit is asked to paint the layer's
- // content, while m_contentsImage contains an image that we directly
+ // content, while m_imageRef contains an image that we directly
// composite, using the layer's dimensions as a destination rect.
// We do this as if the layer only contains an image, directly compositing
// it is a much faster method than using m_recordingPicture.
SkPicture* m_recordingPicture;
- SkBitmap* m_contentsImage;
-
typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap;
KeyframesMap m_animations;
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index cf66de5..f077d48 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -458,11 +458,11 @@ void TilesManager::showImages()
}
}
-ImageTexture* TilesManager::getTextureForImage(SkBitmapRef* img)
+ImageTexture* TilesManager::getTextureForImage(SkBitmapRef* img, bool retain)
{
android::Mutex::Autolock lock(m_imagesLock);
ImageTexture* image = m_images.get(img);
- if (image)
+ if (retain && image)
image->retain();
return image;
}
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index 071aa88..1549581 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -179,7 +179,7 @@ public:
}
void addImage(SkBitmapRef* img);
void removeImage(SkBitmapRef* img);
- ImageTexture* getTextureForImage(SkBitmapRef* img);
+ ImageTexture* getTextureForImage(SkBitmapRef* img, bool retain = true);
void showImages();
private:
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index e757080..4f4f553 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1533,7 +1533,13 @@ bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer)
// Don't go into compositing mode if height or width are zero, or size is 1x1.
IntRect contentBox = pluginRenderer->contentBoxRect();
+#if PLATFORM(ANDROID)
+ // allow all plugins including 1x1 to be composited, so that they are drawn,
+ // and acquire an ANativeWindow on the UI thread
+ return contentBox.height() * contentBox.width() > 0;
+#else
return contentBox.height() * contentBox.width() > 1;
+#endif
}
bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp
index b3556c3..c896637 100644
--- a/Source/WebKit/android/jni/ViewStateSerializer.cpp
+++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp
@@ -32,6 +32,7 @@
#include "PictureSet.h"
#include "ScrollableLayerAndroid.h"
#include "SkPicture.h"
+#include "TilesManager.h"
#include <JNIUtility.h>
#include <JNIHelp.h>
@@ -109,6 +110,11 @@ static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobjec
if (childLayer)
layer->addChild(childLayer);
}
+ // Now double back and delete any imageRefs
+ for (int i = 0; i < layer->countChildren(); i++) {
+ LayerAndroid* childLayer = static_cast<LayerAndroid*>(layer->getChild(i));
+ cleanupImageRefs(childLayer);
+ }
delete stream;
return layer;
}
@@ -290,12 +296,15 @@ void serializeLayer(LayerAndroid* layer, SkWStream* stream)
stream->writeBool(layer->m_preserves3D);
stream->writeScalar(layer->m_anchorPointZ);
stream->writeScalar(layer->m_drawOpacity);
- bool hasContentsImage = layer->m_contentsImage != 0;
+ bool hasContentsImage = layer->m_imageRef != 0;
stream->writeBool(hasContentsImage);
if (hasContentsImage) {
SkFlattenableWriteBuffer buffer(1024);
buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
- layer->m_contentsImage->flatten(buffer);
+ ImageTexture* imagetexture =
+ TilesManager::instance()->getTextureForImage(layer->m_imageRef, false);
+ if (imagetexture && imagetexture->bitmap())
+ imagetexture->bitmap()->flatten(buffer);
stream->write32(buffer.size());
buffer.writeToStream(stream);
}
@@ -374,8 +383,12 @@ LayerAndroid* deserializeLayer(SkStream* stream)
SkAutoMalloc storage(size);
stream->read(storage.get(), size);
SkFlattenableReadBuffer buffer(storage.get(), size);
- layer->m_contentsImage = new SkBitmap();
- layer->m_contentsImage->unflatten(buffer);
+ SkBitmap contentsImage;
+ contentsImage.unflatten(buffer);
+ SkBitmapRef* imageRef = new SkBitmapRef(contentsImage);
+ layer->setContentsImage(imageRef);
+ // We delay deleting the imageRef until after deserialization to make
+ // sure we have unique keys
}
bool hasRecordingPicture = stream->readBool();
if (hasRecordingPicture) {
@@ -404,6 +417,17 @@ LayerAndroid* deserializeLayer(SkStream* stream)
return layer;
}
+void cleanupImageRefs(LayerAndroid* layer)
+{
+ if (!layer)
+ return;
+ int count = layer->countChildren();
+ for (int i = 0; i < count; i++)
+ cleanupImageRefs(layer->getChild(i));
+ if (layer->m_imageRef)
+ delete layer->m_imageRef;
+}
+
/*
* JNI registration
*/
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 7aae758..13e1f5f 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -83,6 +83,8 @@
#define TRIM_MEMORY_BACKGROUND 40
// Moderate free (clear cached tiles, keep visible ones)
#define TRIM_MEMORY_UI_HIDDEN 20
+// Duration to show the pressed cursor ring
+#define PRESSED_STATE_DURATION 400
namespace android {
@@ -282,6 +284,7 @@ void hideCursor()
return;
DBG_NAV_LOG("");
hideCursor(root);
+ viewInvalidate();
}
void hideCursor(CachedRoot* root)
@@ -289,7 +292,6 @@ void hideCursor(CachedRoot* root)
DBG_NAV_LOG("inner");
m_viewImpl->m_hasCursorBounds = false;
root->hideCursor();
- viewInvalidate();
}
#if DUMP_NAV_CACHE
@@ -556,7 +558,7 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In
break;
case DrawExtrasCursorRing:
if (drawCursorPreamble(root) && m_ring.setup()) {
- if (!m_ring.m_isButton)
+ if (m_ring.m_isPressed || m_ringAnimationEnd == UINT_MAX)
extra = &m_ring;
drawCursorPostamble();
}
@@ -574,7 +576,7 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In
if (extra) {
if (extra == &m_ring) {
WTF::Vector<IntRect> rings;
- if (root == m_ring.m_frame)
+ if (!m_ring.m_isButton && root == m_ring.m_frame)
rings = m_ring.rings();
else {
// TODO: Fix the navcache to work with layers correctly
@@ -584,11 +586,12 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In
for (size_t i = 0; i < m_ring.m_node->rings().size(); i++) {
IntRect rect = m_ring.m_node->rings().at(i);
rect = m_ring.m_frame->adjustBounds(m_ring.m_node, rect);
- rect.inflate(4);
+ if (!m_ring.m_isButton)
+ rect.inflate(4);
rings.append(rect);
}
}
- m_glWebViewState->setRings(rings, m_ring.m_isPressed);
+ m_glWebViewState->setRings(rings, m_ring.m_isPressed, m_ring.m_isButton);
extra = 0;
} else {
LayerAndroid mainPicture(m_navPictureUI);
@@ -598,13 +601,6 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In
extra->draw(canvas, &mainPicture, &rect);
picture.endRecording();
}
- } else if (root && 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, allowSame);
@@ -1246,7 +1242,7 @@ void setFindIsEmpty()
void showCursorTimed()
{
DBG_NAV_LOG("");
- m_ringAnimationEnd = SkTime::GetMSecs() + 500;
+ m_ringAnimationEnd = SkTime::GetMSecs() + PRESSED_STATE_DURATION;
viewInvalidate();
}