Merge "Fix 3366514 (again): browser emulator crash" into honeycomb
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index 07a0e00..42104dc 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -749,9 +749,11 @@
android::AutoMutex lock(m_atomicSync);
// we set the reservedTexture if it's different from the drawing texture
if (m_reservedTexture != reservedTexture &&
- ((m_reservedTexture != m_drawingTexture) ||
+ ((reservedTexture != m_drawingTexture) ||
(m_reservedTexture == 0 && m_drawingTexture == 0))) {
- if (m_reservedTexture)
+ // Call release on the reserved texture if it is not the same as the
+ // drawing texture.
+ if (m_reservedTexture && (m_reservedTexture != m_drawingTexture))
m_reservedTexture->release(this);
m_reservedTexture = reservedTexture;
}
diff --git a/WebCore/platform/graphics/android/MediaLayer.cpp b/WebCore/platform/graphics/android/MediaLayer.cpp
index fac94f5..7a4c02d 100644
--- a/WebCore/platform/graphics/android/MediaLayer.cpp
+++ b/WebCore/platform/graphics/android/MediaLayer.cpp
@@ -40,11 +40,11 @@
namespace WebCore {
-MediaLayer::MediaLayer() : LayerAndroid(false)
+MediaLayer::MediaLayer(jobject weakWebViewRef) : LayerAndroid(false)
{
m_bufferedTexture = new MediaTexture(EGL_NO_CONTEXT);
m_bufferedTexture->incStrong(this);
- m_videoTexture = new VideoTexture();
+ m_videoTexture = new VideoTexture(weakWebViewRef);
m_videoTexture->incStrong(this);
m_currentTextureInfo = 0;
@@ -78,6 +78,8 @@
// draw any video content if present
m_videoTexture->drawVideo(drawTransform());
+ bool needsInval = true;
+
// draw the primary content
if (m_bufferedTexture) {
TextureInfo* textureInfo = m_bufferedTexture->consumerLock();
@@ -95,14 +97,13 @@
TilesManager::instance()->shader()->drawLayerQuad(m, rect,
textureInfo->m_textureId,
1.0f); //TODO fix this m_drawOpacity
+ if (!rect.isEmpty())
+ needsInval = false;
}
m_bufferedTexture->consumerRelease();
}
- drawChildrenGL(matrix);
-
- //TODO allow plugins to specify when they should be drawn
- return true;
+ return drawChildrenGL(matrix) || needsInval;
}
ANativeWindow* MediaLayer::acquireNativeWindowForVideo()
diff --git a/WebCore/platform/graphics/android/MediaLayer.h b/WebCore/platform/graphics/android/MediaLayer.h
index dec6427..15bd6d8 100644
--- a/WebCore/platform/graphics/android/MediaLayer.h
+++ b/WebCore/platform/graphics/android/MediaLayer.h
@@ -21,6 +21,7 @@
#include "MediaTexture.h"
#include "LayerAndroid.h"
+#include <jni.h>
namespace android {
class SurfaceTexture;
@@ -31,7 +32,7 @@
class MediaLayer : public LayerAndroid {
public:
- MediaLayer();
+ MediaLayer(jobject weakWebViewRef);
MediaLayer(const MediaLayer& layer);
virtual ~MediaLayer();
diff --git a/WebCore/platform/graphics/android/MediaTexture.cpp b/WebCore/platform/graphics/android/MediaTexture.cpp
index 8481a20..a92b570 100644
--- a/WebCore/platform/graphics/android/MediaTexture.cpp
+++ b/WebCore/platform/graphics/android/MediaTexture.cpp
@@ -24,6 +24,8 @@
#include <gui/SurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
#include <wtf/CurrentTime.h>
+#include <JNIUtility.h>
+#include "WebCoreJni.h"
#define LAYER_DEBUG
#undef LAYER_DEBUG
@@ -45,8 +47,46 @@
namespace WebCore {
-VideoTexture::VideoTexture()
+class VideoListener : public android::SurfaceTexture::FrameAvailableListener {
+
+public:
+ VideoListener(jobject weakWebViewRef)
+ : m_weakWebViewRef(weakWebViewRef)
+ , m_postInvalMethod(0)
+ {
+ if (!m_weakWebViewRef)
+ return;
+
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jobject localWebViewRef = env->NewLocalRef(m_weakWebViewRef);
+ if (localWebViewRef) {
+ jclass wvClass = env->GetObjectClass(localWebViewRef);
+ m_postInvalMethod = env->GetMethodID(wvClass, "postInvalidate", "()V");
+ env->DeleteLocalRef(wvClass);
+ env->DeleteLocalRef(localWebViewRef);
+ }
+ checkException(env);
+ }
+
+ virtual void onFrameAvailable()
+ {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jobject localWebViewRef = env->NewLocalRef(m_weakWebViewRef);
+ if (localWebViewRef) {
+ env->CallVoidMethod(localWebViewRef, m_postInvalMethod);
+ env->DeleteLocalRef(localWebViewRef);
+ }
+ checkException(env);
+ }
+
+private:
+ jobject m_weakWebViewRef;
+ jmethodID m_postInvalMethod;
+};
+
+VideoTexture::VideoTexture(jobject weakWebViewRef) : android::LightRefBase<VideoTexture>()
{
+ m_weakWebViewRef = weakWebViewRef;
m_textureId = 0;
m_dimensions.setEmpty();
m_newWindowRequest = false;
@@ -58,6 +98,10 @@
releaseNativeWindow();
if (m_textureId)
glDeleteTextures(1, &m_textureId);
+ if (m_weakWebViewRef) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->DeleteWeakGlobalRef(m_weakWebViewRef);
+ }
}
void VideoTexture::initNativeWindowIfNeeded()
@@ -73,6 +117,11 @@
m_surfaceTexture = new android::SurfaceTexture(m_textureId);
m_surfaceTextureClient = new android::SurfaceTextureClient(m_surfaceTexture);
+
+ //setup callback
+ sp<VideoListener> listener = new VideoListener(m_weakWebViewRef);
+ m_surfaceTexture->setFrameAvailableListener(listener);
+
m_newWindowRequest = false;
m_newWindowReady = true;
m_newVideoRequestCond.signal();
@@ -109,8 +158,23 @@
}
m_newWindowRequest = true;
+
+ // post an inval message to the UI thread to fulfill the request
+ if (m_weakWebViewRef) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jobject localWebViewRef = env->NewLocalRef(m_weakWebViewRef);
+ if (localWebViewRef) {
+ jclass wvClass = env->GetObjectClass(localWebViewRef);
+ jmethodID postInvalMethod = env->GetMethodID(wvClass, "postInvalidate", "()V");
+ env->CallVoidMethod(localWebViewRef, postInvalMethod);
+ env->DeleteLocalRef(wvClass);
+ env->DeleteLocalRef(localWebViewRef);
+ }
+ checkException(env);
+ }
+
//block until the request can be fulfilled or we time out
- m_newVideoRequestCond.waitRelative(m_videoLock, 1000000000); // 1 sec
+ m_newVideoRequestCond.waitRelative(m_videoLock, 500000000); // .5 sec
if (m_surfaceTextureClient.get())
m_newWindowReady = false;
@@ -128,6 +192,11 @@
{
android::Mutex::Autolock lock(m_videoLock);
m_dimensions.setEmpty();
+
+ if (m_surfaceTexture.get())
+ m_surfaceTexture->setFrameAvailableListener(0);
+
+ // clear the strong pointer references
m_surfaceTextureClient.clear();
m_surfaceTexture.clear();
}
diff --git a/WebCore/platform/graphics/android/MediaTexture.h b/WebCore/platform/graphics/android/MediaTexture.h
index 156a67f..189905c 100644
--- a/WebCore/platform/graphics/android/MediaTexture.h
+++ b/WebCore/platform/graphics/android/MediaTexture.h
@@ -23,6 +23,7 @@
#include "DoubleBufferedTexture.h"
#include "LayerAndroid.h"
#include <utils/RefBase.h>
+#include <jni.h>
namespace android {
class SurfaceTexture;
@@ -40,7 +41,7 @@
class VideoTexture : public android::LightRefBase<VideoTexture> {
public:
- VideoTexture();
+ VideoTexture(jobject weakWebViewRef);
~VideoTexture();
void initNativeWindowIfNeeded();
@@ -60,6 +61,8 @@
bool m_newWindowRequest;
bool m_newWindowReady;
+ jobject m_weakWebViewRef;
+
android::Mutex m_videoLock;
android::Condition m_newVideoRequestCond;
};
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index d64a0b1..571d9cc 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -70,6 +70,14 @@
namespace WebCore {
+GLint TilesManager::getMaxTextureSize()
+{
+ static GLint maxTextureSize = 0;
+ if (!maxTextureSize)
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ return maxTextureSize;
+}
+
TilesManager::TilesManager()
: m_layersMemoryUsage(0)
, m_maxTextureCount(0)
@@ -84,10 +92,6 @@
m_tilesBitmap->eraseColor(0);
m_pixmapsGenerationThread = new TexturesGenerator();
m_pixmapsGenerationThread->run("TexturesGenerator");
-
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
- m_totalMaxTextureSize = m_maxTextureSize * m_maxTextureSize * BYTES_PER_PIXEL;
- XLOG("Max texture size %d", m_maxTextureSize);
}
void TilesManager::allocateTiles()
@@ -314,11 +318,13 @@
unsigned int size = w * h * BYTES_PER_PIXEL;
// We will not allocate textures that:
- // 1) cannot be handled by the graphic card (m_maxTextureSize &
- // m_totalMaxTextureSize)
+ // 1) cannot be handled by the graphic card (maxTextureSize &
+ // totalMaxTextureSize)
// 2) will make us go past our texture limit (MAX_LAYERS_ALLOCATION)
- bool large = w > m_maxTextureSize || h > m_maxTextureSize || size > m_totalMaxTextureSize;
+ GLint maxTextureSize = getMaxTextureSize();
+ unsigned totalMaxTextureSize = maxTextureSize * maxTextureSize * BYTES_PER_PIXEL;
+ bool large = w > maxTextureSize || h > maxTextureSize || size > totalMaxTextureSize;
XLOG("createTextureForLayer(%d) @scale %.2f => %d, %d (too large? %x)", layer->uniqueId(),
layer->getScale(), w, h, large);
diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h
index 8e8c089..eeb38fe 100644
--- a/WebCore/platform/graphics/android/TilesManager.h
+++ b/WebCore/platform/graphics/android/TilesManager.h
@@ -44,6 +44,7 @@
class TilesManager {
public:
static TilesManager* instance();
+ static GLint getMaxTextureSize();
static bool hardwareAccelerationEnabled()
{
@@ -121,8 +122,6 @@
Vector<LayerTexture*> m_layersTextures;
unsigned int m_layersMemoryUsage;
- GLint m_maxTextureSize;
- unsigned int m_totalMaxTextureSize;
int m_maxTextureCount;
bool m_expandedTileBounds;
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp
index 9d7a88e..fd6bbe2 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequest.cpp
@@ -451,7 +451,7 @@
if (!read(&bytesRead)) {
if (m_request && m_request->status().is_io_pending())
return; // Wait for OnReadCompleted()
- finish(false);
+ return finish(false);
}
// bytesRead == 0 indicates finished
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 91c2ddb..b329e3b 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -108,7 +108,6 @@
#include "SkPicture.h"
#include "SkUtils.h"
#include "Text.h"
-#include "TilesManager.h"
#include "TypingCommand.h"
#include "WebCoreFrameBridge.h"
#include "WebFrameView.h"
@@ -343,6 +342,7 @@
#endif
m_isPaused = false;
m_screenOnCounter = 0;
+ m_onlyScrollIfImeIsShowing = false;
LOG_ASSERT(m_mainFrame, "Uh oh, somehow a frameview was made without an initial frame!");
@@ -350,7 +350,7 @@
m_javaGlue = new JavaGlue;
m_javaGlue->m_obj = env->NewWeakGlobalRef(javaWebViewCore);
m_javaGlue->m_spawnScrollTo = GetJMethod(env, clazz, "contentSpawnScrollTo", "(II)V");
- m_javaGlue->m_scrollTo = GetJMethod(env, clazz, "contentScrollTo", "(II)V");
+ m_javaGlue->m_scrollTo = GetJMethod(env, clazz, "contentScrollTo", "(IIZ)V");
m_javaGlue->m_scrollBy = GetJMethod(env, clazz, "contentScrollBy", "(IIZ)V");
m_javaGlue->m_contentDraw = GetJMethod(env, clazz, "contentDraw", "()V");
m_javaGlue->m_layersDraw = GetJMethod(env, clazz, "layersDraw", "()V");
@@ -948,9 +948,11 @@
// LOGD("WebViewCore::scrollTo(%d %d)\n", x, y);
JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->CallVoidMethod(m_javaGlue->object(env).get(),
- animate ? m_javaGlue->m_spawnScrollTo : m_javaGlue->m_scrollTo,
- x, y);
+ if (animate)
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_spawnScrollTo, x, y);
+ else
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_scrollTo,
+ x, y, m_onlyScrollIfImeIsShowing);
checkException(env);
}
@@ -1323,8 +1325,11 @@
// If this was in response to touching a textfield and showing the IME,
// the IME may now cover textfield. Bring it back into view.
// If the scale changed, however, this was the result of a zoom.
- if (oldScale == m_scale)
+ if (oldScale == m_scale && osh > screenHeight) {
+ m_onlyScrollIfImeIsShowing = true;
revealSelection();
+ m_onlyScrollIfImeIsShowing = false;
+ }
// update the currently visible screen as perceived by the plugin
sendPluginVisibleScreen();
}
@@ -4514,15 +4519,6 @@
#endif
}
-static void SetExpandedTileBounds(JNIEnv *env, jobject obj, jboolean enabled)
-{
- WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
- if (!viewImpl)
- return;
- TilesManager::instance()->setExpandedTileBounds(enabled);
-}
-
-
// ----------------------------------------------------------------------------
/*
@@ -4630,8 +4626,6 @@
(void*) GetTouchHighlightRects },
{ "nativeAutoFillForm", "(I)V",
(void*) AutoFillForm },
- { "nativeSetExpandedTileBounds", "(Z)V",
- (void*) SetExpandedTileBounds },
};
int registerWebViewCore(JNIEnv* env)
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 1457089..5820dc5 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -610,6 +610,9 @@
int m_blurringNodePointer;
int m_lastFocusedSelStart;
int m_lastFocusedSelEnd;
+ // Pass along with a scroll message to tell the UI thread to only
+ // scroll the page if the IME is showing.
+ bool m_onlyScrollIfImeIsShowing;
PictureSet m_content; // the set of pictures to draw
SkRegion m_addInval; // the accumulated inval region (not yet drawn)
SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp
index 27eebd3..b25ad7d 100644
--- a/WebKit/android/nav/CachedFrame.cpp
+++ b/WebKit/android/nav/CachedFrame.cpp
@@ -50,13 +50,17 @@
mRoot->mViewBounds.x(), mRoot->mViewBounds.y(),
mRoot->mViewBounds.width(), mRoot->mViewBounds.height());
#if USE(ACCELERATED_COMPOSITING)
- if (mRoot) {
- const CachedLayer* cachedLayer = layer(node);
- const WebCore::LayerAndroid* rootLayer = mRoot->rootLayer();
- const LayerAndroid* aLayer = cachedLayer->layer(rootLayer);
- if (aLayer)
- return cachedLayer->adjustBounds(rootLayer, rect);
- }
+ if (!mRoot)
+ return rect;
+
+ const CachedLayer* cachedLayer = layer(node);
+ if (!cachedLayer)
+ return rect;
+
+ const WebCore::LayerAndroid* rootLayer = mRoot->rootLayer();
+ const LayerAndroid* aLayer = cachedLayer->layer(rootLayer);
+ if (aLayer)
+ return cachedLayer->adjustBounds(rootLayer, rect);
#endif
return rect;
}
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index f84f8b0..935aecd 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -206,7 +206,7 @@
// We must remove the m_glWebViewState prior to deleting m_baseLayer. If we
// do not remove it here, we risk having BaseTiles trying to paint using a
// deallocated base layer.
- delete m_glWebViewState;
+ stopGL();
#endif
delete m_frameCacheUI;
delete m_navPictureUI;
@@ -214,6 +214,14 @@
delete m_glDrawFunctor;
}
+void stopGL()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ delete m_glWebViewState;
+ m_glWebViewState = 0;
+#endif
+}
+
WebViewCore* getWebViewCore() const {
return m_viewImpl;
}
@@ -2207,6 +2215,11 @@
delete view;
}
+static void nativeStopGL(JNIEnv *env, jobject obj)
+{
+ GET_NATIVE_VIEW(env, obj)->stopGL();
+}
+
static bool nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
@@ -2395,6 +2408,11 @@
return false;
}
+static void nativeSetExpandedTileBounds(JNIEnv*, jobject, jboolean enabled)
+{
+ TilesManager::instance()->setExpandedTileBounds(enabled);
+}
+
/*
* JNI registration
*/
@@ -2559,6 +2577,8 @@
(void*) nativeShowCursorTimed },
{ "nativeStartSelection", "(II)Z",
(void*) nativeStartSelection },
+ { "nativeStopGL", "()V",
+ (void*) nativeStopGL },
{ "nativeSubtractLayers", "(Landroid/graphics/Rect;)Landroid/graphics/Rect;",
(void*) nativeSubtractLayers },
{ "nativeTextGeneration", "()I",
@@ -2573,6 +2593,8 @@
(void*) nativeScrollableLayer },
{ "nativeScrollLayer", "(III)Z",
(void*) nativeScrollLayer },
+ { "nativeSetExpandedTileBounds", "(Z)V",
+ (void*) nativeSetExpandedTileBounds },
};
int registerWebView(JNIEnv* env)
diff --git a/WebKit/android/plugins/ANPOpenGLInterface.cpp b/WebKit/android/plugins/ANPOpenGLInterface.cpp
index 8f5f9b4..015a04c 100644
--- a/WebKit/android/plugins/ANPOpenGLInterface.cpp
+++ b/WebKit/android/plugins/ANPOpenGLInterface.cpp
@@ -87,6 +87,9 @@
info->m_internalFormat = textureInfo->internalFormat;
texture->producerReleaseAndSwap();
+
+ // invalidate the java view so that this content is drawn
+ pluginWidget->viewInvalidate();
}
static void anp_invertPluginContent(NPP instance, bool isContentInverted) {
diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp
index 90dceba..a02047b 100644
--- a/WebKit/android/plugins/PluginWidgetAndroid.cpp
+++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp
@@ -156,8 +156,14 @@
bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) {
- if (model == kOpenGL_ANPDrawingModel && m_layer == 0)
- m_layer = new WebCore::MediaLayer();
+ if (model == kOpenGL_ANPDrawingModel && m_layer == 0) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jobject webview = m_core->getWebViewJavaObject();
+ jobject weakWebViewRef = 0;
+ if (webview)
+ weakWebViewRef = env->NewWeakGlobalRef(webview);
+ m_layer = new WebCore::MediaLayer(weakWebViewRef);
+ }
else if (model != kOpenGL_ANPDrawingModel && m_layer != 0)
m_layer->unref();
@@ -204,6 +210,12 @@
}
}
+void PluginWidgetAndroid::viewInvalidate() {
+ WebCore::IntRect rect(m_pluginBounds.fLeft, m_pluginBounds.fTop,
+ m_pluginBounds.width(), m_pluginBounds.height());
+ m_core->viewInvalidate(rect);
+}
+
void PluginWidgetAndroid::draw(SkCanvas* canvas) {
if (NULL == m_flipPixelRef || !m_flipPixelRef->isDirty()) {
return;
diff --git a/WebKit/android/plugins/PluginWidgetAndroid.h b/WebKit/android/plugins/PluginWidgetAndroid.h
index 9726a22..5d586b1 100644
--- a/WebKit/android/plugins/PluginWidgetAndroid.h
+++ b/WebKit/android/plugins/PluginWidgetAndroid.h
@@ -177,6 +177,8 @@
void setPowerState(ANPPowerState powerState);
+ void viewInvalidate();
+
private:
void computeVisiblePluginRect();
void scrollToVisiblePluginRect();