diff options
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. |