summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/WebCore/dom/Element.cpp8
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp40
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp9
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp21
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h9
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h5
-rw-r--r--Source/WebCore/platform/graphics/android/MediaLayer.cpp7
-rw-r--r--Source/WebCore/platform/graphics/android/MediaLayer.h1
-rw-r--r--Source/WebCore/platform/graphics/android/MediaListener.h16
-rw-r--r--Source/WebCore/platform/graphics/android/MediaTexture.cpp12
-rw-r--r--Source/WebCore/platform/graphics/android/MediaTexture.h3
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.cpp36
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.h6
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp13
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.h5
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp60
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h3
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp12
-rw-r--r--Source/WebCore/plugins/android/PluginViewAndroid.cpp2
-rw-r--r--Source/WebCore/rendering/RenderInline.cpp5
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp5
-rw-r--r--Source/WebCore/rendering/RenderObjectChildList.cpp2
-rw-r--r--Source/WebKit/android/jni/PictureSet.cpp21
-rw-r--r--Source/WebKit/android/nav/WebView.cpp20
-rw-r--r--Source/WebKit/android/plugins/ANPVideoInterface.cpp16
-rw-r--r--Source/WebKit/android/plugins/ANPVideo_npapi.h15
-rw-r--r--Source/WebKit/android/plugins/PluginWidgetAndroid.cpp17
-rw-r--r--Source/WebKit/android/plugins/android_npapi.h1
31 files changed, 319 insertions, 123 deletions
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
index eef2419..64d3eed 100644
--- a/Source/WebCore/dom/Element.cpp
+++ b/Source/WebCore/dom/Element.cpp
@@ -1072,11 +1072,15 @@ bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderS
#ifdef ANDROID_STYLE_VERSION
static bool displayDiff(const RenderStyle* s1, const RenderStyle* s2)
{
- if (!s1 || !s2)
+ if (!s1 && !s2)
return false;
+ else if ((!s1 && s2) || (s1 && !s2))
+ return true;
+
return s1->display() != s2->display()
|| s1->left() != s2->left() || s1->top() != s2->top()
- || s1->right() != s2->right() || s1->bottom() != s2->bottom();
+ || s1->right() != s2->right() || s1->bottom() != s2->bottom()
+ || s1->width() != s2->width() || s1->height() != s2->height();
}
#endif
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index dcaf03a..2def2a6 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -381,8 +381,11 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy)
Node* currentFocusedNode = m_frame->document()->focusedNode();
if (currentFocusedNode)
currentFocusedNode->aboutToUnload();
- m_pageDismissalEventBeingDispatched = true;
- if (m_frame->domWindow()) {
+// ANDROID
+ // See http://b/issue?id=5264509
+ if (m_frame->domWindow() && !m_pageDismissalEventBeingDispatched) {
+ m_pageDismissalEventBeingDispatched = true;
+// END ANDROID
if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide)
m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document());
if (!m_frame->document()->inPageCache()) {
@@ -1837,6 +1840,20 @@ void FrameLoader::setDocumentLoader(DocumentLoader* loader)
m_documentLoader->detachFromFrame();
m_documentLoader = loader;
+
+ // The following abomination is brought to you by the unload event.
+ // The detachChildren() call above may trigger a child frame's unload event,
+ // which could do something obnoxious like call document.write("") on
+ // the main frame, which results in detaching children while detaching children.
+ // This can cause the new m_documentLoader to be detached from its Frame*, but still
+ // be alive. To make matters worse, DocumentLoaders with a null Frame* aren't supposed
+ // to happen when they're still alive (and many places below us on the stack think the
+ // DocumentLoader is still usable). Ergo, we reattach loader to its Frame, and pretend
+ // like nothing ever happened.
+ if (m_documentLoader && !m_documentLoader->frame()) {
+ ASSERT(!m_documentLoader->isLoading());
+ m_documentLoader->setFrame(m_frame);
+ }
}
void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
@@ -2563,12 +2580,14 @@ void FrameLoader::frameLoadCompleted()
void FrameLoader::detachChildren()
{
- // FIXME: Is it really necessary to do this in reverse order?
- Frame* previous;
- for (Frame* child = m_frame->tree()->lastChild(); child; child = previous) {
- previous = child->tree()->previousSibling();
- child->loader()->detachFromParent();
- }
+ typedef Vector<RefPtr<Frame> > FrameVector;
+ FrameVector childrenToDetach;
+ childrenToDetach.reserveCapacity(m_frame->tree()->childCount());
+ for (Frame* child = m_frame->tree()->lastChild(); child; child = child->tree()->previousSibling())
+ childrenToDetach.append(child);
+ FrameVector::iterator end = childrenToDetach.end();
+ for (FrameVector::iterator it = childrenToDetach.begin(); it != end; it++)
+ (*it)->loader()->detachFromParent();
}
void FrameLoader::closeAndRemoveChild(Frame* child)
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index 573ad6b..1fa69f8 100644
--- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -141,7 +141,10 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale,
nextTiledPage->setScale(scale);
m_glWebViewState->setFutureViewport(viewportTileBounds);
m_glWebViewState->lockBaseLayerUpdate();
- nextTiledPage->updateTileState(viewportTileBounds);
+
+ // ignore dirtiness return value since while zooming we repaint regardless
+ nextTiledPage->updateTileDirtiness(viewportTileBounds);
+
nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds,
TiledPage::VisibleBounds);
// Cancel pending paints for the foreground page
@@ -212,24 +215,27 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale,
*buffersSwappedPtr = true;
}
- // If stuff is happening such that we need a redraw, lock updates to the
- // base layer, and only then start painting.
+
bool needsRedraw = scrolling || zooming || !buffersSwapped;
- if (needsRedraw)
- m_glWebViewState->lockBaseLayerUpdate();
- else
+
+ // if we don't expect to redraw, unlock the invals
+ if (!needsRedraw)
m_glWebViewState->unlockBaseLayerUpdate();
- XLOG("scrolling %d, zooming %d, buffersSwapped %d, needsRedraw %d",
- scrolling, zooming, buffersSwapped, needsRedraw);
+ // if applied invals mark tiles dirty, need to redraw
+ needsRedraw |= tiledPage->updateTileDirtiness(preZoomBounds);
- tiledPage->updateTileState(preZoomBounds);
+ if (needsRedraw) {
+ // lock and paint what's needed unless we're zooming, since the new
+ // tiles won't be relevant soon anyway
+ m_glWebViewState->lockBaseLayerUpdate();
+ if (!zooming)
+ tiledPage->prepare(goingDown, goingLeft, preZoomBounds,
+ TiledPage::ExpandedBounds);
+ }
- // Only paint new textures if the base layer has been locked, but not if
- // we're zooming since the new tiles won't be relevant soon anyway
- if (needsRedraw && !zooming)
- tiledPage->prepare(goingDown, goingLeft, preZoomBounds,
- TiledPage::ExpandedBounds);
+ XLOG("scrolling %d, zooming %d, buffersSwapped %d, needsRedraw %d",
+ scrolling, zooming, buffersSwapped, needsRedraw);
tiledPage->draw(transparency, preZoomBounds);
@@ -260,13 +266,11 @@ bool BaseLayerAndroid::drawGL(double currentTime, LayerAndroid* compositedRoot,
compositedRoot->updateFixedLayersPositions(visibleRect);
FloatRect clip(0, 0, viewRect.width(), viewRect.height());
- compositedRoot->updateGLPositions(ident, clip, 1);
+ compositedRoot->updateGLPositionsAndScale(
+ ident, clip, 1, m_glWebViewState->zoomManager()->layersScale());
SkMatrix matrix;
matrix.setTranslate(viewRect.x(), viewRect.y());
- // get the scale factor from the zoom manager
- compositedRoot->setScale(m_glWebViewState->zoomManager()->layersScale());
-
#ifdef DEBUG
compositedRoot->showLayer(0);
XLOG("We have %d layers, %d textured",
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp
index 0a87ffe..8a4c2d5 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp
@@ -35,12 +35,15 @@
#include <cutils/atomic.h>
-#ifdef DEBUG
-
#include <cutils/log.h>
#include <wtf/CurrentTime.h>
#include <wtf/text/CString.h>
+#undef XLOGC
+#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
+
+#ifdef DEBUG
+
#undef XLOG
#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
@@ -432,6 +435,8 @@ void BaseTile::paintBitmap()
if (!m_dirtyArea[m_currentDirtyAreaIndex].isEmpty())
m_dirty = true;
+ XLOG("painted tile %p (%d, %d), dirty=%d", this, x, y, m_dirty);
+
if (!m_dirty)
m_isSwapNeeded = true;
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
index 34de9e7..8cc67b9 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
@@ -58,7 +58,7 @@ BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
, m_busy(false)
{
m_size.set(w, h);
- m_ownTextureId = GLUtils::createBaseTileGLTexture(w, h);
+ m_ownTextureId = 0;
// Make sure they are created on the UI thread.
TilesManager::instance()->transferQueue()->initSharedSurfaceTextures(w, h);
@@ -79,6 +79,18 @@ BaseTileTexture::~BaseTileTexture()
#endif
}
+void BaseTileTexture::requireTexture()
+{
+ if (!m_ownTextureId)
+ m_ownTextureId = GLUtils::createBaseTileGLTexture(m_size.width(), m_size.height());
+}
+
+void BaseTileTexture::discardTexture()
+{
+ if (m_ownTextureId)
+ GLUtils::deleteTexture(&m_ownTextureId);
+}
+
void BaseTileTexture::destroyTextures(SharedTexture** textures)
{
int x = 0;
@@ -263,6 +275,13 @@ void BaseTileTexture::setOwnTextureTileInfoFromQueue(const TextureTileInfo* info
bool BaseTileTexture::readyFor(BaseTile* baseTile)
{
+ if (!m_ownTextureId) {
+ // If our backing opengl texture doesn't exist, allocate it and return
+ // false since it won't have useful data
+ requireTexture();
+ return false;
+ }
+
const TextureTileInfo* info = &m_ownTextureTileInfo;
if (info &&
(info->m_x == baseTile->x()) &&
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
index 9c94a53..0f694a5 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
@@ -34,6 +34,8 @@
class SkCanvas;
+#define DEBUG_TRANSFER_USING_CPU_UPLOAD 0
+
namespace WebCore {
class BaseTile;
@@ -86,6 +88,9 @@ public:
TransferItemStatus status;
BaseTile* savedBaseTilePtr;
TextureTileInfo tileInfo;
+#if DEBUG_TRANSFER_USING_CPU_UPLOAD
+ SkBitmap bitmap;
+#endif
};
// DoubleBufferedTexture using a SkBitmap as backing mechanism
@@ -128,7 +133,11 @@ public:
bool readyFor(BaseTile* baseTile);
float scale();
+ // OpenGL ID of backing texture, 0 when not allocated
GLuint m_ownTextureId;
+ // these are used for dynamically (de)allocating backing graphics memory
+ void requireTexture();
+ void discardTexture();
void setOwnTextureTileInfoFromQueue(const TextureTileInfo* info);
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index f030e52..d85d8b7 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -473,7 +473,7 @@ double GLWebViewState::setupDrawing(IntRect& viewRect, SkRect& visibleRect,
glUseProgram(shader->program());
glUniform1i(shader->textureSampler(), 0);
shader->setViewRect(viewRect);
- shader->setViewport(visibleRect, scale);
+ shader->setViewport(visibleRect);
shader->setWebViewRect(webViewRect);
shader->setTitleBarHeight(titleBarHeight);
shader->setScreenClip(screenClip);
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index 4b24961..48dcaaa 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -17,6 +17,7 @@
#include "SkPicture.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
+#include <math.h>
#define LAYER_DEBUG // Add diagonals for debugging
#undef LAYER_DEBUG
@@ -558,8 +559,8 @@ void LayerAndroid::updatePositions()
this->getChild(i)->updatePositions();
}
-void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
- const FloatRect& clipping, float opacity)
+void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
+ const FloatRect& clipping, float opacity, float scale)
{
IntSize layerSize(getSize().width(), getSize().height());
FloatPoint anchorPoint(getAnchorPoint().fX, getAnchorPoint().fY);
@@ -580,8 +581,24 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
-anchorPointZ());
setDrawTransform(localMatrix);
+ if (m_drawTransform.isIdentityOrTranslation()) {
+ // adjust the translation coordinates of the draw transform matrix so
+ // that layers (defined in content coordinates) will align to display/view pixels
+ float desiredContentX = round(m_drawTransform.m41() * scale) / scale;
+ float desiredContentY = round(m_drawTransform.m42() * scale) / scale;
+ XLOG("fudging translation from %f, %f to %f, %f",
+ m_drawTransform.m41(), m_drawTransform.m42(),
+ desiredContentX, desiredContentY);
+ m_drawTransform.setM41(desiredContentX);
+ m_drawTransform.setM42(desiredContentY);
+ }
+
m_zValue = TilesManager::instance()->shader()->zValue(m_drawTransform, getSize().width(), getSize().height());
+ m_atomicSync.lock();
+ m_scale = scale;
+ m_atomicSync.unlock();
+
opacity *= getOpacity();
setDrawOpacity(opacity);
@@ -626,7 +643,7 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
localMatrix.translate(-getSize().width() * 0.5f, -getSize().height() * 0.5f);
}
for (int i = 0; i < count; i++)
- this->getChild(i)->updateGLPositions(localMatrix, drawClip(), opacity);
+ this->getChild(i)->updateGLPositionsAndScale(localMatrix, drawClip(), opacity, scale);
}
void LayerAndroid::copyBitmap(SkBitmap* bitmap)
@@ -651,7 +668,7 @@ void LayerAndroid::setContentsImage(SkBitmapRef* img)
bool LayerAndroid::needsTexture()
{
return m_contentsImage || (prepareContext()
- && m_recordingPicture->width() && m_recordingPicture->height() && !m_hasOverflowChildren);
+ && m_recordingPicture->width() && m_recordingPicture->height());
}
IntRect LayerAndroid::clippedRect() const
@@ -821,16 +838,6 @@ bool LayerAndroid::drawChildrenGL(GLWebViewState* glWebViewState, SkMatrix& matr
return askPaint;
}
-void LayerAndroid::setScale(float scale)
-{
- int count = this->countChildren();
- for (int i = 0; i < count; i++)
- this->getChild(i)->setScale(scale);
-
- android::AutoMutex lock(m_atomicSync);
- m_scale = scale;
-}
-
void LayerAndroid::extraDraw(SkCanvas* canvas)
{
m_atomicSync.lock();
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index a28f1e7..7192aaf 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -120,12 +120,11 @@ public:
int nbTexturedLayers();
void showLayer(int indent);
- void setScale(float scale);
float getScale() { return m_scale; }
virtual bool drawGL(GLWebViewState*, SkMatrix&);
bool drawChildrenGL(GLWebViewState*, SkMatrix&);
- void updateGLPositions(const TransformationMatrix& parentMatrix,
- const FloatRect& clip, float opacity);
+ void updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
+ const FloatRect& clip, float opacity, float scale);
void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
float drawOpacity() { return m_drawOpacity; }
void setVisible(bool value) { m_visible = value; }
diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.cpp b/Source/WebCore/platform/graphics/android/MediaLayer.cpp
index 5625bbe..85fb92f 100644
--- a/Source/WebCore/platform/graphics/android/MediaLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/MediaLayer.cpp
@@ -137,6 +137,13 @@ void MediaLayer::releaseNativeWindowForVideo(ANativeWindow* window)
m_videoTexture->releaseNativeWindow();
}
+void MediaLayer::setFramerateCallback(const ANativeWindow* window, FramerateCallbackProc callback)
+{
+ if (window != m_videoTexture->getNativeWindow())
+ return;
+ m_videoTexture->setFramerateCallback(callback);
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.h b/Source/WebCore/platform/graphics/android/MediaLayer.h
index 6d08ed6..cd15d9e 100644
--- a/Source/WebCore/platform/graphics/android/MediaLayer.h
+++ b/Source/WebCore/platform/graphics/android/MediaLayer.h
@@ -53,6 +53,7 @@ public:
ANativeWindow* acquireNativeWindowForVideo();
void setWindowDimensionsForVideo(const ANativeWindow* window, const SkRect& dimensions);
void releaseNativeWindowForVideo(ANativeWindow* window);
+ void setFramerateCallback(const ANativeWindow* window, FramerateCallbackProc callback);
private:
bool m_isCopy;
diff --git a/Source/WebCore/platform/graphics/android/MediaListener.h b/Source/WebCore/platform/graphics/android/MediaListener.h
index 0a85574..5fcbbb2 100644
--- a/Source/WebCore/platform/graphics/android/MediaListener.h
+++ b/Source/WebCore/platform/graphics/android/MediaListener.h
@@ -20,8 +20,10 @@
#if USE(ACCELERATED_COMPOSITING)
#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
#include <jni.h>
#include <JNIUtility.h>
+#include "MediaTexture.h"
#include "WebCoreJni.h"
#ifdef DEBUG
@@ -44,10 +46,15 @@ namespace WebCore {
class MediaListener : public android::SurfaceTexture::FrameAvailableListener {
public:
- MediaListener(jobject weakWebViewRef)
+ MediaListener(jobject weakWebViewRef,
+ const sp<android::SurfaceTexture>& surfaceTexture,
+ const sp<ANativeWindow>& nativeWindow)
: m_weakWebViewRef(weakWebViewRef)
, m_postInvalMethod(0)
, m_frameAvailable(false)
+ , m_surfaceTexture(surfaceTexture)
+ , m_nativeWindow(nativeWindow)
+ , m_framerateCallback(0)
{
if (!m_weakWebViewRef)
return;
@@ -75,15 +82,20 @@ public:
if (!m_frameAvailable) {
m_frameAvailable = true;
}
+ if (m_framerateCallback)
+ m_framerateCallback(m_nativeWindow.get(), m_surfaceTexture->getTimestamp());
}
- void resetFrameAvailable() { m_frameAvailable = false; }
bool isFrameAvailable() { return m_frameAvailable; }
+ void setFramerateCallback(FramerateCallbackProc callback) { m_framerateCallback = callback; }
private:
jobject m_weakWebViewRef;
jmethodID m_postInvalMethod;
bool m_frameAvailable;
+ sp<android::SurfaceTexture> m_surfaceTexture;
+ sp<ANativeWindow> m_nativeWindow;
+ FramerateCallbackProc m_framerateCallback;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/MediaTexture.cpp b/Source/WebCore/platform/graphics/android/MediaTexture.cpp
index eb143a4..0de7dfa 100644
--- a/Source/WebCore/platform/graphics/android/MediaTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/MediaTexture.cpp
@@ -61,7 +61,6 @@ MediaTexture::MediaTexture(jobject webViewRef) : android::LightRefBase<MediaText
m_dimensions.setEmpty();
m_newWindowRequest = false;
m_newWindowReady = false;
- m_mediaListener = new MediaListener(m_weakWebViewRef);
}
MediaTexture::~MediaTexture()
@@ -91,7 +90,9 @@ void MediaTexture::initNativeWindowIfNeeded()
m_surfaceTextureClient = new android::SurfaceTextureClient(m_surfaceTexture);
//setup callback
- m_mediaListener->resetFrameAvailable();
+ m_mediaListener = new MediaListener(m_weakWebViewRef,
+ m_surfaceTexture,
+ m_surfaceTextureClient);
m_surfaceTexture->setFrameAvailableListener(m_mediaListener);
m_newWindowRequest = false;
@@ -210,6 +211,7 @@ void MediaTexture::releaseNativeWindow()
m_surfaceTexture->setFrameAvailableListener(0);
// clear the strong pointer references
+ m_mediaListener.clear();
m_surfaceTextureClient.clear();
m_surfaceTexture.clear();
}
@@ -220,6 +222,12 @@ void MediaTexture::setDimensions(const SkRect& dimensions)
m_dimensions = dimensions;
}
+void MediaTexture::setFramerateCallback(FramerateCallbackProc callback)
+{
+ android::Mutex::Autolock lock(m_mediaLock);
+ m_mediaListener->setFramerateCallback(callback);
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/MediaTexture.h b/Source/WebCore/platform/graphics/android/MediaTexture.h
index c617264..d5ecd7b 100644
--- a/Source/WebCore/platform/graphics/android/MediaTexture.h
+++ b/Source/WebCore/platform/graphics/android/MediaTexture.h
@@ -31,6 +31,8 @@ namespace android {
namespace WebCore {
+typedef void (*FramerateCallbackProc)(ANativeWindow* window, int64_t timestamp);
+
class MediaListener;
class MediaTexture : public android::LightRefBase<MediaTexture> {
@@ -47,6 +49,7 @@ public:
ANativeWindow* getNativeWindow();
void releaseNativeWindow();
void setDimensions(const SkRect& dimensions);
+ void setFramerateCallback(FramerateCallbackProc callback);
private:
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
index 536d228..bf5f760 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
+++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
@@ -235,8 +235,6 @@ void ShaderProgram::init()
glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), coord, GL_STATIC_DRAW);
GLUtils::checkGlError("init");
-
- memset(m_webViewMatrix, 0, sizeof(m_webViewMatrix));
}
void ShaderProgram::resetBlending()
@@ -264,14 +262,13 @@ void ShaderProgram::setBlendingState(bool enableBlending)
// Drawing
/////////////////////////////////////////////////////////////////////////////////////////
-void ShaderProgram::setViewport(SkRect& viewport, float scale)
+void ShaderProgram::setViewport(SkRect& viewport)
{
TransformationMatrix ortho;
GLUtils::setOrthographicMatrix(ortho, viewport.fLeft, viewport.fTop,
viewport.fRight, viewport.fBottom, -1000, 1000);
m_projectionMatrix = ortho;
m_viewport = viewport;
- m_currentScale = scale;
}
void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrixHandle)
@@ -280,29 +277,8 @@ void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrix
translate.translate3d(geometry.fLeft, geometry.fTop, 0.0);
TransformationMatrix scale;
scale.scale3d(geometry.width(), geometry.height(), 1.0);
- // Translate float* to TransformationMatrix
- TransformationMatrix webViewTransformMatrix(
- m_webViewMatrix[0], m_webViewMatrix[1], m_webViewMatrix[2], m_webViewMatrix[3],
- m_webViewMatrix[4], m_webViewMatrix[5], m_webViewMatrix[6], m_webViewMatrix[7],
- m_webViewMatrix[8], m_webViewMatrix[9], m_webViewMatrix[10], m_webViewMatrix[11],
- m_webViewMatrix[12], m_webViewMatrix[13], m_webViewMatrix[14], m_webViewMatrix[15] );
-
-
- TransformationMatrix reposition;
- // After the webViewTranform, we need to reposition the rect to match our viewport.
- reposition.translate3d(-m_webViewRect.x(), -m_webViewRect.y() - m_titleBarHeight, 0);
- reposition.translate3d(m_viewport.fLeft * m_currentScale, m_viewport.fTop * m_currentScale, 0);
-
- // Basically, the webViewTransformMatrix should apply on the screen resolution.
- // So we start by doing the scale and translate to get each tile into screen coordinates.
- // After applying the webViewTransformMatrix, b/c the way it currently set up
- // for scroll and titlebar, we need to offset both of them.
- // Finally, map everything back to (-1, 1) by using the m_projectionMatrix.
- // TODO: Given that webViewTransformMatrix contains most of the tranformation
- // information, we should be able to get rid of some parameter we got from
- // Java side and simplify our code.
- TransformationMatrix total =
- m_projectionMatrix * reposition * webViewTransformMatrix * translate * scale;
+
+ TransformationMatrix total = m_projectionMatrix * translate * scale;
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, total);
@@ -597,12 +573,6 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
-void ShaderProgram::setWebViewMatrix(float* matrix)
-{
- if (matrix)
- memcpy(m_webViewMatrix, matrix, sizeof(m_webViewMatrix));
-}
-
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/ShaderProgram.h
index f31eb91..d8447bf 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.h
+++ b/Source/WebCore/platform/graphics/android/ShaderProgram.h
@@ -39,7 +39,7 @@ public:
int program() { return m_program; }
// Drawing
- void setViewport(SkRect& viewport, float scale);
+ void setViewport(SkRect& viewport);
float zValue(const TransformationMatrix& drawMatrix, float w, float h);
// For drawQuad and drawLayerQuad, they can handle 3 cases for now:
@@ -88,7 +88,6 @@ public:
contrast = MAX_CONTRAST;
m_contrast = contrast;
}
- void setWebViewMatrix(float* matrix);
private:
GLuint loadShader(GLenum shaderType, const char* pSource);
@@ -150,9 +149,6 @@ private:
// attribs
GLint m_hPosition;
GLint m_hVideoPosition;
-
- float m_webViewMatrix[16];
- float m_currentScale;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
index b6a0c47..78140fa 100644
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp
@@ -202,27 +202,32 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y
}
}
-void TiledPage::updateTileState(const SkIRect& tileBounds)
+bool TiledPage::updateTileDirtiness(const SkIRect& tileBounds)
{
if (!m_glWebViewState || tileBounds.isEmpty()) {
m_invalRegion.setEmpty();
m_invalTilesRegion.setEmpty();
- return;
+ return false;
}
+ bool visibleTileIsDirty = false;
for (int x = 0; x < m_baseTileSize; x++) {
BaseTile& tile = m_baseTiles[x];
// if the tile is in the dirty region then we must invalidate it
- if (m_invalRegion.contains(tile.x(), tile.y()))
+ if (m_invalRegion.contains(tile.x(), tile.y())) {
tile.markAsDirty(m_latestPictureInval, m_invalTilesRegion);
+ if (tileBounds.contains(tile.x(), tile.y()))
+ visibleTileIsDirty = true;
+ }
}
// clear the invalidated region as all tiles within that region have now
// been marked as dirty.
m_invalRegion.setEmpty();
m_invalTilesRegion.setEmpty();
+ return visibleTileIsDirty;
}
void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds)
@@ -231,8 +236,6 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
return;
TilesManager::instance()->gatherTextures();
- // update the tiles distance from the viewport
- updateTileState(tileBounds);
m_scrollingDown = goingDown;
int firstTileX = tileBounds.fLeft;
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.h b/Source/WebCore/platform/graphics/android/TiledPage.h
index 14306eb..946421c 100644
--- a/Source/WebCore/platform/graphics/android/TiledPage.h
+++ b/Source/WebCore/platform/graphics/android/TiledPage.h
@@ -68,7 +68,10 @@ public:
// prepare the page for display on the screen
void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds);
- void updateTileState(const SkIRect& tileBounds);
+
+ // update tiles with inval information, return true if visible ones are
+ // dirty (and thus repaint needed)
+ bool updateTileDirtiness(const SkIRect& tileBounds);
// check to see if the page is ready for display
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index 2c263e3..bb8feb9 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -149,6 +149,41 @@ void TilesManager::allocateTiles()
m_tilesTextures.size() * LAYER_TILE_WIDTH * LAYER_TILE_HEIGHT * 4 / 1024 / 1024);
}
+void TilesManager::deallocateTextures(bool allTextures)
+{
+ const unsigned int max = m_textures.size();
+ const unsigned int maxLayer = m_tilesTextures.size();
+
+ unsigned long long sparedDrawCount = ~0; // by default, spare no textures
+ if (!allTextures) {
+ // if we're not deallocating all textures, spare those with max drawcount
+ sparedDrawCount = 0;
+ for (unsigned int i = 0; i < max; i++) {
+ TextureOwner* owner = m_textures[i]->owner();
+ if (owner)
+ sparedDrawCount = std::max(sparedDrawCount, owner->drawCount());
+ }
+ }
+
+ int dealloc = 0;
+ for (unsigned int i = 0; i < max; i++) {
+ TextureOwner* owner = m_textures[i]->owner();
+ if (!owner || owner->drawCount() < sparedDrawCount) {
+ m_textures[i]->discardTexture();
+ dealloc++;
+ }
+ }
+ for (unsigned int i = 0; i < maxLayer; i++) {
+ TextureOwner* owner = m_tilesTextures[i]->owner();
+ if (!owner || owner->drawCount() < sparedDrawCount) {
+ m_tilesTextures[i]->discardTexture();
+ dealloc++;
+ }
+ }
+ XLOG("Deallocated %d gl textures (out of %d base tiles and %d layer tiles)",
+ dealloc, max, maxLayer);
+}
+
void TilesManager::printTextures()
{
#ifdef DEBUG
@@ -235,10 +270,11 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
// 1. If a tile isn't owned, break with that one
// 2. If we find a tile in the same page with a different scale,
// it's old and not visible. Break with that one
- // 3. Otherwise, use the least recently prepared tile
+ // 3. Otherwise, use the least recently prepared tile, but ignoring tiles
+ // drawn in the last frame to avoid flickering
BaseTileTexture* farthestTexture = 0;
- unsigned long long oldestDrawCount = ~0; //maximum u64
+ unsigned long long oldestDrawCount = getDrawGLCount() - 1;
const unsigned int max = availableTexturePool->size();
for (unsigned int i = 0; i < max; i++) {
BaseTileTexture* texture = (*availableTexturePool)[i];
@@ -263,16 +299,18 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
}
}
- TextureOwner* previousOwner = farthestTexture->owner();
- if (farthestTexture && farthestTexture->acquire(owner)) {
- if (previousOwner) {
- XLOG("%s texture %p stolen from tile %d, %d, drawCount was %llu",
- owner->isLayerTile() ? "LAYER" : "BASE",
- farthestTexture, owner->x(), owner->y(), oldestDrawCount);
+ if (farthestTexture) {
+ TextureOwner* previousOwner = farthestTexture->owner();
+ if (farthestTexture->acquire(owner)) {
+ if (previousOwner) {
+ XLOG("%s texture %p stolen from tile %d, %d, drawCount was %llu",
+ owner->isLayerTile() ? "LAYER" : "BASE",
+ farthestTexture, owner->x(), owner->y(), oldestDrawCount);
+ }
+
+ availableTexturePool->remove(availableTexturePool->find(farthestTexture));
+ return farthestTexture;
}
-
- availableTexturePool->remove(availableTexturePool->find(farthestTexture));
- return farthestTexture;
}
XLOG("Couldn't find an available texture for tile %x (%d, %d) out of %d available!!!",
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index 513494c..3298c94 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -112,6 +112,9 @@ public:
void allocateTiles();
+ // Called when webview is hidden to discard graphics memory
+ void deallocateTextures(bool allTextures);
+
bool getShowVisualIndicator()
{
return m_showVisualIndicator;
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
index b73f388..50502f6 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
@@ -134,6 +134,9 @@ bool TransferQueue::checkObsolete(int index)
void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, GLuint srcTexId, GLenum srcTexTarget)
{
+ // guarantee that we have a texture to blit into
+ destTex->requireTexture();
+
// Then set up the FBO and copy the SurfTex content in.
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
glFramebufferTexture2D(GL_FRAMEBUFFER,
@@ -260,9 +263,15 @@ void TransferQueue::updateDirtyBaseTiles()
continue;
}
+#if DEBUG_TRANSFER_USING_CPU_UPLOAD
+ // Here we just need to upload the bitmap content to the GL Texture
+ GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId, 0, 0,
+ m_transferQueue[index].bitmap);
+#else
blitTileFromQueue(m_fboID, destTexture,
m_sharedSurfaceTextureId,
m_sharedSurfaceTexture->getCurrentTextureTarget());
+#endif
// After the base tile copied into the GL texture, we need to
// update the texture's info such that at draw time, readyFor
@@ -336,6 +345,9 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
m_transferQueueItemLocks.lock();
// b) After update the Surface Texture, now udpate the transfer queue info.
addItemInTransferQueue(renderInfo);
+#if DEBUG_TRANSFER_USING_CPU_UPLOAD
+ bitmap.copyTo(&(m_transferQueue[m_transferQueueIndex].bitmap), bitmap.config());
+#endif
m_transferQueueItemLocks.unlock();
XLOG("Bitmap updated x, y %d %d, baseTile %p",
renderInfo->x, renderInfo->y, renderInfo->baseTile);
diff --git a/Source/WebCore/plugins/android/PluginViewAndroid.cpp b/Source/WebCore/plugins/android/PluginViewAndroid.cpp
index 8ac6486..dba7d3b 100644
--- a/Source/WebCore/plugins/android/PluginViewAndroid.cpp
+++ b/Source/WebCore/plugins/android/PluginViewAndroid.cpp
@@ -112,6 +112,7 @@ extern void ANPSystemInterfaceV1_Init(ANPInterface* value);
extern void ANPSystemInterfaceV2_Init(ANPInterface* value);
extern void ANPNativeWindowInterfaceV0_Init(ANPInterface* value);
extern void ANPVideoInterfaceV0_Init(ANPInterface* value);
+extern void ANPVideoInterfaceV1_Init(ANPInterface* value);
struct VarProcPair {
int enumValue;
@@ -142,6 +143,7 @@ static const VarProcPair gVarProcs[] = {
{ VARPROCLINE(SystemInterfaceV2) },
{ VARPROCLINE(NativeWindowInterfaceV0) },
{ VARPROCLINE(VideoInterfaceV0) },
+ { VARPROCLINE(VideoInterfaceV1) },
};
/* return true if var was an interface request (error will be set accordingly)
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index ae18514..13cadfa 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -567,6 +567,11 @@ void RenderInline::absoluteQuads(Vector<FloatQuad>& quads)
void RenderInline::culledInlineAbsoluteQuads(const RenderInline* container, Vector<FloatQuad>& quads)
{
+ if (!culledInlineFirstLineBox()) {
+ quads.append(localToAbsoluteQuad(FloatRect()));
+ return;
+ }
+
bool isHorizontal = style()->isHorizontalWritingMode();
for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
if (curr->isFloatingOrPositioned())
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index ce5bf27..904b1b2 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -2279,11 +2279,8 @@ void RenderLayer::updateScrollInfoAfterLayout()
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
bool hasOverflowScroll = ((horizontalOverflow && m_hBar) || (verticalOverflow && m_vBar));
if (hasOverflowScroll) {
- // Disable Android overflow scroll for positioned RenderBlock.
- if (renderer()->isRenderBlock() && renderer()->isPositioned())
- hasOverflowScroll = false;
// Disable UI side scrolling for non-readonly textareas.
- else if (renderer()->isTextArea() && (!renderer()->node()
+ if (renderer()->isTextArea() && (!renderer()->node()
|| !static_cast<HTMLTextAreaElement*>(renderer()->node())->readOnly()))
hasOverflowScroll = false;
}
diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp
index ff9ff15..1ea8675 100644
--- a/Source/WebCore/rendering/RenderObjectChildList.cpp
+++ b/Source/WebCore/rendering/RenderObjectChildList.cpp
@@ -258,7 +258,7 @@ static RenderObject* findBeforeAfterParent(RenderObject* object)
RenderObject* beforeAfterParent = object;
while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage()))
beforeAfterParent = beforeAfterParent->firstChild();
- return beforeAfterParent;
+ return beforeAfterParent ? beforeAfterParent->parent() : 0;
}
RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObject* owner) const
diff --git a/Source/WebKit/android/jni/PictureSet.cpp b/Source/WebKit/android/jni/PictureSet.cpp
index 839a887..e6a9ed5 100644
--- a/Source/WebKit/android/jni/PictureSet.cpp
+++ b/Source/WebKit/android/jni/PictureSet.cpp
@@ -96,6 +96,27 @@ PictureSet::PictureSet(SkPicture* picture)
mHeight = picture->height();
mBaseArea = mWidth * mHeight;
#ifdef FAST_PICTURESET
+ SkIRect area;
+ area.set(0, 0, mWidth, mHeight);
+ splitAdd(area);
+ WTF::Vector<Bucket*>* buckets = bucketsToUpdate();
+ for (unsigned int i = 0; i < buckets->size(); i++) {
+ Bucket* bucket = (*buckets)[i];
+ for (unsigned int j = 0; j < bucket->size(); j++) {
+ BucketPicture& bucketPicture = (*bucket)[j];
+ const SkIRect& inval = bucketPicture.mRealArea;
+ SkPicture *splitPicture = new SkPicture();
+ SkCanvas *canvas = splitPicture->beginRecording(
+ inval.width(), inval.height(),
+ SkPicture::kUsePathBoundsForClip_RecordingFlag);
+ canvas->translate(-inval.fLeft, -inval.fTop);
+ picture->draw(canvas);
+ splitPicture->endRecording();
+ SkSafeUnref(bucketPicture.mPicture);
+ bucketPicture.mPicture = splitPicture;
+ }
+ }
+ buckets->clear();
#else
Pictures pictureAndBounds;
pictureAndBounds.mPicture = picture;
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 8835f70..a528e9a 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -75,6 +75,15 @@
#include <wtf/text/AtomicString.h>
#include <wtf/text/CString.h>
+// Free as much as we possible can
+#define TRIM_MEMORY_COMPLETE 80
+// Free a lot (all textures gone)
+#define TRIM_MEMORY_MODERATE 60
+// More moderate free (keep bare minimum to restore quickly-ish - possibly clear all textures)
+#define TRIM_MEMORY_BACKGROUND 40
+// Moderate free (clear cached tiles, keep visible ones)
+#define TRIM_MEMORY_UI_HIDDEN 20
+
namespace android {
static jfieldID gWebViewField;
@@ -1581,7 +1590,6 @@ class GLDrawFunctor : Functor {
WebCore::IntRect clip(info->clipLeft, info->clipTop,
info->clipRight - info->clipLeft,
info->clipBottom - info->clipTop);
- TilesManager::instance()->shader()->setWebViewMatrix(info->transform);
bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, titlebarHeight, clip, scale, extras);
if (retVal) {
@@ -2563,6 +2571,14 @@ static jstring nativeGetProperty(JNIEnv *env, jobject obj, jstring key)
return 0;
}
+static void nativeOnTrimMemory(JNIEnv *env, jobject obj, jint level)
+{
+ if (TilesManager::hardwareAccelerationEnabled()) {
+ bool freeAllTextures = (level > TRIM_MEMORY_UI_HIDDEN);
+ TilesManager::instance()->deallocateTextures(freeAllTextures);
+ }
+}
+
static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)
{
#ifdef ANDROID_DUMP_DISPLAY_TREE
@@ -2866,6 +2882,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeSetProperty },
{ "nativeGetProperty", "(Ljava/lang/String;)Ljava/lang/String;",
(void*) nativeGetProperty },
+ { "nativeOnTrimMemory", "(I)V",
+ (void*) nativeOnTrimMemory },
};
int registerWebView(JNIEnv* env)
diff --git a/Source/WebKit/android/plugins/ANPVideoInterface.cpp b/Source/WebKit/android/plugins/ANPVideoInterface.cpp
index 8eb9846..f39d0b1 100644
--- a/Source/WebKit/android/plugins/ANPVideoInterface.cpp
+++ b/Source/WebKit/android/plugins/ANPVideoInterface.cpp
@@ -70,6 +70,14 @@ static void anp_releaseNativeWindow(NPP instance, ANativeWindow* window) {
mediaLayer->releaseNativeWindowForVideo(window);
}
+static void anp_setFramerateCallback(NPP instance, const ANativeWindow* window, ANPVideoFrameCallbackProc callback) {
+ WebCore::MediaLayer* mediaLayer = mediaLayerForInstance(instance);
+ if (!mediaLayer)
+ return;
+
+ mediaLayer->setFramerateCallback(window, callback);
+}
+
///////////////////////////////////////////////////////////////////////////////
#define ASSIGN(obj, name) (obj)->name = anp_##name
@@ -81,3 +89,11 @@ void ANPVideoInterfaceV0_Init(ANPInterface* value) {
ASSIGN(i, setWindowDimensions);
ASSIGN(i, releaseNativeWindow);
}
+
+void ANPVideoInterfaceV1_Init(ANPInterface* value) {
+ // initialize the functions from the previous interface
+ ANPVideoInterfaceV0_Init(value);
+ // add any new functions or override existing functions
+ ANPVideoInterfaceV1* i = reinterpret_cast<ANPVideoInterfaceV1*>(value);
+ ASSIGN(i, setFramerateCallback);
+}
diff --git a/Source/WebKit/android/plugins/ANPVideo_npapi.h b/Source/WebKit/android/plugins/ANPVideo_npapi.h
index 3d234f2..02e8392 100644
--- a/Source/WebKit/android/plugins/ANPVideo_npapi.h
+++ b/Source/WebKit/android/plugins/ANPVideo_npapi.h
@@ -58,4 +58,19 @@ struct ANPVideoInterfaceV0 : ANPInterface {
void (*releaseNativeWindow)(NPP instance, ANativeWindow* window);
};
+/** Called to notify the plugin that a video frame has been composited by the
+ * browser for display. This will be called in a separate thread and as such
+ * you cannot call releaseNativeWindow from the callback.
+ *
+ * The timestamp is in nanoseconds, and is monotonically increasing.
+ */
+typedef void (*ANPVideoFrameCallbackProc)(ANativeWindow* window, int64_t timestamp);
+
+struct ANPVideoInterfaceV1 : ANPVideoInterfaceV0 {
+ /** Set a callback to be notified when an ANativeWindow is composited by
+ * the browser.
+ */
+ void (*setFramerateCallback)(NPP instance, const ANativeWindow* window, ANPVideoFrameCallbackProc);
+};
+
#endif // ANPVideo_npapi_h
diff --git a/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp b/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
index c4c31e5..761e948 100644
--- a/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
+++ b/Source/WebKit/android/plugins/PluginWidgetAndroid.cpp
@@ -49,6 +49,8 @@
#define DEBUG_EVENTS 0 // logs event contents, return value, and processing time
#define DEBUG_VISIBLE_RECTS 0 // temporary debug printfs and fixes
+#define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) )
+
// this include statement must follow the declaration of PLUGIN_DEBUG_LOCAL
#include "PluginDebugAndroid.h"
@@ -571,20 +573,17 @@ void PluginWidgetAndroid::scrollToVisiblePluginRect() {
int rectCenterX = m_requestedVisibleRect.fLeft + m_requestedVisibleRect.width()/2;
int rectCenterY = m_requestedVisibleRect.fTop + m_requestedVisibleRect.height()/2;
- // find document coordinates for center of the visible screen
- int visibleDocCenterX = m_visibleDocRect.fLeft + m_visibleDocRect.width()/2;
- int visibleDocCenterY = m_visibleDocRect.fTop + m_visibleDocRect.height()/2;
-
- //compute the delta of the two points and scale to screen coordinates
- int deltaX = rectCenterX - visibleDocCenterX;
- int deltaY = rectCenterY - visibleDocCenterY;
+ // position the corner of the visible doc to center the requested rect
+ int scrollDocX = MAX(0, rectCenterX - (m_visibleDocRect.width()/2));
+ int scrollDocY = MAX(0, rectCenterY - (m_visibleDocRect.height()/2));
ScrollView* scrollView = m_pluginView->parent();
android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView);
#if DEBUG_VISIBLE_RECTS
- PLUGIN_LOG("%s call scrollBy (%d,%d)", __FUNCTION__, deltaX, deltaY);
+ PLUGIN_LOG("%s call scrollTo (%d,%d) to center (%d,%d)", __FUNCTION__,
+ scrollDocX, scrollDocX, rectCenterX, rectCenterY);
#endif
- core->scrollTo(rectCenterX, rectCenterY, true);
+ core->scrollTo(scrollDocX, scrollDocX, true);
}
void PluginWidgetAndroid::requestFullScreen() {
diff --git a/Source/WebKit/android/plugins/android_npapi.h b/Source/WebKit/android/plugins/android_npapi.h
index bcb0bbb..5305dc8 100644
--- a/Source/WebKit/android/plugins/android_npapi.h
+++ b/Source/WebKit/android/plugins/android_npapi.h
@@ -130,6 +130,7 @@ typedef uint32_t ANPMatrixFlag;
#define kWindowInterfaceV2_ANPGetValue ((NPNVariable)1018)
#define kNativeWindowInterfaceV0_ANPGetValue ((NPNVariable)1019)
+#define kVideoInterfaceV1_ANPGetValue ((NPNVariable)1020)
/** queries for the drawing models supported on this device.