glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
}
+GLenum GLUtils::getTextureTarget(android::SurfaceTexture* surfaceTexture)
+{
+#if DEPRECATED_SURFACE_TEXTURE_MODE
+ if (surfaceTexture) {
+ GLenum target = surfaceTexture->getCurrentTextureTarget();
+ // TODO: remove this translation when TEXTURE_2D+RGBA surface texture
+ // support is deprecated.
+ if (target == GL_TEXTURE_2D)
+ return 0;
+ return target;
+ }
+#endif
+ return GL_TEXTURE_2D;
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+namespace android {
+
+class SurfaceTexture;
+
+} // namespace android
+
namespace WebCore {
class GLUtils {
static void updateSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
#endif
static void updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, const SkBitmap& bitmap);
+
+ static GLenum getTextureTarget(android::SurfaceTexture*);
};
} // namespace WebCore
MediaLayer::MediaLayer(jobject weakWebViewRef) : LayerAndroid((RenderLayer*) NULL)
{
- m_bufferedTexture = new MediaTexture(EGL_NO_CONTEXT);
- m_bufferedTexture->producerInc();
- m_videoTexture = new VideoTexture(weakWebViewRef);
+ m_contentTexture = new MediaTexture(weakWebViewRef);
+ m_contentTexture->incStrong(this);
+ m_videoTexture = new MediaTexture(weakWebViewRef);
m_videoTexture->incStrong(this);
m_isCopy = false;
- m_currentTextureInfo = 0;
m_isContentInverted = false;
m_outlineSize = 0;
XLOG("Creating Media Layer %p", this);
- XLOG("producer: %d consumer: %d", m_bufferedTexture->getProducerCount(),
- m_bufferedTexture->getConsumerCount());
}
MediaLayer::MediaLayer(const MediaLayer& layer) : LayerAndroid(layer)
{
- m_bufferedTexture = layer.getTexture();
- m_bufferedTexture->consumerInc();
+ m_contentTexture = layer.m_contentTexture;
+ m_contentTexture->incStrong(this);
m_videoTexture = layer.m_videoTexture;
m_videoTexture->incStrong(this);
m_isCopy = true;
- m_currentTextureInfo = 0;
m_isContentInverted = layer.m_isContentInverted;
m_outlineSize = layer.m_outlineSize;
XLOG("Creating Media Layer Copy %p -> %p", &layer, this);
- XLOG("producer: %d consumer: %d COPY", m_bufferedTexture->getProducerCount(),
- m_bufferedTexture->getConsumerCount());
}
MediaLayer::~MediaLayer()
{
XLOG("Deleting Media Layer");
- XLOG("producer: %d consumer: %d %s", m_bufferedTexture->getProducerCount(),
- m_bufferedTexture->getConsumerCount(), (m_isCopy) ? "COPY" : "");
-
- if (m_isCopy)
- m_bufferedTexture->consumerDec();
- else
- m_bufferedTexture->producerDec();
+ m_contentTexture->decStrong(this);
m_videoTexture->decStrong(this);
}
// draw any video content if present
m_videoTexture->drawVideo(m_drawTransform, mediaBounds);
- // draw the primary content
- if (m_bufferedTexture) {
- TextureInfo* textureInfo = m_bufferedTexture->consumerLock();
- if (textureInfo && textureInfo->m_width != 0 && textureInfo->m_height != 0) {
- // the layer's shader draws the content inverted so we must undo
- // that change in the transformation matrix
- TransformationMatrix m = m_drawTransform;
- if (!m_isContentInverted) {
- m.flipY();
- m.translate(0, -getSize().height());
- }
-
- bool forceBlending = textureInfo->m_internalFormat == GL_RGBA ||
- textureInfo->m_internalFormat == GL_BGRA_EXT ||
- textureInfo->m_internalFormat == GL_ALPHA;
- TilesManager::instance()->shader()->drawLayerQuad(m, mediaBounds,
- textureInfo->m_textureId,
- 1.0f, forceBlending,
- textureInfo->getTextureTarget());
- }
- m_bufferedTexture->consumerRelease();
+ // the layer's shader draws the content inverted so we must undo
+ // that change in the transformation matrix
+ TransformationMatrix m = m_drawTransform;
+ if (!m_isContentInverted) {
+ m.flipY();
+ m.translate(0, -getSize().height());
}
+ // check to see if we need to create a content texture
+ m_contentTexture->initNativeWindowIfNeeded();
+ // draw any content if present
+ m_contentTexture->setDimensions(mediaBounds);
+ m_contentTexture->drawContent(m);
+
return drawChildrenGL(glWebViewState, matrix);
}
+ANativeWindow* MediaLayer::acquireNativeWindowForContent()
+{
+ return m_contentTexture->requestNewWindow();
+}
+
+
ANativeWindow* MediaLayer::acquireNativeWindowForVideo()
{
return m_videoTexture->requestNewWindow();
virtual bool isMedia() const { return true; }
virtual LayerAndroid* copy() const { return new MediaLayer(*this); }
- MediaTexture* getTexture() const { return m_bufferedTexture; }
-
- void setCurrentTextureInfo(TextureInfo* info) { m_currentTextureInfo = info; }
- TextureInfo* getCurrentTextureInfo() const { return m_currentTextureInfo; }
-
void invertContents(bool invertContent) { m_isContentInverted = invertContent; }
void setOutlineSize(int size) { m_outlineSize = size; }
+ // function to setup the primary SurfaceTexture in the renderer's context
+ ANativeWindow* acquireNativeWindowForContent();
+
// functions to manipulate secondary layers for video playback
ANativeWindow* acquireNativeWindowForVideo();
void setWindowDimensionsForVideo(const ANativeWindow* window, const SkRect& dimensions);
private:
bool m_isCopy;
-
- // Primary GL texture variables
- MediaTexture* m_bufferedTexture;
- TextureInfo* m_currentTextureInfo;
-
bool m_isContentInverted;
int m_outlineSize;
- // Video texture variables
- VideoTexture* m_videoTexture;
+ // SurfaceTexture member variables
+ MediaTexture* m_contentTexture;
+ MediaTexture* m_videoTexture;
};
} // namespace WebCore
* limitations under the License.
*/
-#ifndef VideoListener_h
-#define VideoListener_h
+#ifndef MediaListener_h
+#define MediaListener_h
#if USE(ACCELERATED_COMPOSITING)
#include <wtf/text/CString.h>
#undef XLOG
-#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "VideoListener", __VA_ARGS__)
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "MediaListener", __VA_ARGS__)
#else
namespace WebCore {
-class VideoListener : public android::SurfaceTexture::FrameAvailableListener {
+class MediaListener : public android::SurfaceTexture::FrameAvailableListener {
public:
- VideoListener(jobject weakWebViewRef)
+ MediaListener(jobject weakWebViewRef)
: m_weakWebViewRef(weakWebViewRef)
, m_postInvalMethod(0)
, m_frameAvailable(false)
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
-#endif // VideoListener_h
+#endif // MediaListener_h
#include "MediaTexture.h"
#include "TilesManager.h"
#include "GLUtils.h"
-#include "VideoListener.h"
+#include "MediaListener.h"
#if USE(ACCELERATED_COMPOSITING)
namespace WebCore {
-MediaTexture::MediaTexture(EGLContext sharedContext) : DoubleBufferedTexture(sharedContext, EglImageMode)
-{
- m_producerRefCount = 0;
- m_consumerRefCount = 0;
-}
-
-/* Increment the number of objects in the producer's thread that hold a reference
- * to this object. In practice, there is often only one producer reference for
- * the lifetime of the object.
- */
-void MediaTexture::producerInc()
-{
- android::Mutex::Autolock lock(m_mediaLock);
- m_producerRefCount++;
-}
-
-/* Decrement the number of objects in the producer's thread that are holding a
- * reference to this object. When removing the last reference we must cleanup
- * all GL objects that are associated with the producer's thread. There may not
- * be a consumer reference as the object may not have synced to the UI thread,
- * in which case the producer needs to handle the deletion of the object.
- */
-void MediaTexture::producerDec()
-{
- bool needsDeleted = false;
-
- m_mediaLock.lock();
- m_producerRefCount--;
- if (m_producerRefCount == 0) {
- producerDeleteTextures();
- if (m_consumerRefCount < 1) {
- XLOG("INFO: This texture has not been synced to the UI thread");
- needsDeleted = true;
- }
- }
- m_mediaLock.unlock();
-
- if (needsDeleted) {
- XLOG("Deleting MediaTexture Object");
- delete this;
- }
-}
-
-/* Increment the number of objects in the consumer's thread that hold a reference
- * to this object. In practice, there can be multiple producer references as the
- * consumer (i.e. UI) thread may have multiple copies of the layer tree.
- */
-void MediaTexture::consumerInc()
-{
- android::Mutex::Autolock lock(m_mediaLock);
- m_consumerRefCount++;
-}
-
-/* Decrement the number of objects in the consumer's thread that are holding a
- * reference to this object. When removing the last reference we must delete
- * this object and by extension cleanup all GL objects that are associated with
- * the consumer's thread. At the time of deletion if there is a remaining
- * producer reference we must cleanup the consumer GL objects in the event that
- * this texture will not be re-synced with the UI thread.
- */
-void MediaTexture::consumerDec()
-{
- bool needsDeleted = false;
-
- m_mediaLock.lock();
- m_consumerRefCount--;
- if (m_consumerRefCount == 0) {
- consumerDeleteTextures();
- if (m_producerRefCount < 1) {
- XLOG("WARNING: This texture still exists within webkit.");
- needsDeleted = true;
- }
- }
- m_mediaLock.unlock();
-
- if (needsDeleted) {
- XLOG("Deleting MediaTexture Object");
- delete this;
- }
-}
-
-VideoTexture::VideoTexture(jobject weakWebViewRef) : android::LightRefBase<VideoTexture>()
+MediaTexture::MediaTexture(jobject weakWebViewRef) : android::LightRefBase<MediaTexture>()
{
m_weakWebViewRef = weakWebViewRef;
m_textureId = 0;
m_dimensions.setEmpty();
m_newWindowRequest = false;
m_newWindowReady = false;
- m_videoListener = new VideoListener(m_weakWebViewRef);
+ m_mediaListener = new MediaListener(m_weakWebViewRef);
}
-VideoTexture::~VideoTexture()
+MediaTexture::~MediaTexture()
{
releaseNativeWindow();
if (m_textureId)
}
}
-void VideoTexture::initNativeWindowIfNeeded()
+void MediaTexture::initNativeWindowIfNeeded()
{
{
- android::Mutex::Autolock lock(m_videoLock);
+ android::Mutex::Autolock lock(m_mediaLock);
if(!m_newWindowRequest)
return;
m_surfaceTextureClient = new android::SurfaceTextureClient(m_surfaceTexture);
//setup callback
- m_videoListener->resetFrameAvailable();
- m_surfaceTexture->setFrameAvailableListener(m_videoListener);
+ m_mediaListener->resetFrameAvailable();
+ m_surfaceTexture->setFrameAvailableListener(m_mediaListener);
m_newWindowRequest = false;
m_newWindowReady = true;
}
- m_newVideoRequestCond.signal();
+ m_newMediaRequestCond.signal();
+}
+
+void MediaTexture::drawContent(const TransformationMatrix& matrix)
+{
+ android::Mutex::Autolock lock(m_mediaLock);
+
+ if(!m_surfaceTexture.get() || m_dimensions.isEmpty()
+ || !m_mediaListener->isFrameAvailable())
+ return;
+
+ m_surfaceTexture->updateTexImage();
+
+ bool forceBlending = ANativeWindow_getFormat(m_surfaceTextureClient.get()) == WINDOW_FORMAT_RGB_565;
+ GLenum target = GLUtils::getTextureTarget(m_surfaceTexture.get());
+ TilesManager::instance()->shader()->drawLayerQuad(matrix, m_dimensions,
+ m_textureId, 1.0f,
+ forceBlending, target);
}
-void VideoTexture::drawVideo(const TransformationMatrix& matrix, const SkRect& parentBounds)
+void MediaTexture::drawVideo(const TransformationMatrix& matrix, const SkRect& parentBounds)
{
- android::Mutex::Autolock lock(m_videoLock);
+ android::Mutex::Autolock lock(m_mediaLock);
if(!m_surfaceTexture.get() || m_dimensions.isEmpty()
- || !m_videoListener->isFrameAvailable())
+ || !m_mediaListener->isFrameAvailable())
return;
m_surfaceTexture->updateTexImage();
dimensions, m_textureId);
}
-ANativeWindow* VideoTexture::requestNewWindow()
+ANativeWindow* MediaTexture::requestNewWindow()
{
- android::Mutex::Autolock lock(m_videoLock);
+ android::Mutex::Autolock lock(m_mediaLock);
// the window was not ready before the timeout so return it this time
if (m_newWindowReady) {
//block until the request can be fulfilled or we time out
bool timedOut = false;
while (m_newWindowRequest && !timedOut) {
- int ret = m_newVideoRequestCond.waitRelative(m_videoLock, 500000000); // .5 sec
+ int ret = m_newMediaRequestCond.waitRelative(m_mediaLock, 500000000); // .5 sec
timedOut = ret == TIMED_OUT;
}
return m_surfaceTextureClient.get();
}
-ANativeWindow* VideoTexture::getNativeWindow()
+ANativeWindow* MediaTexture::getNativeWindow()
{
- android::Mutex::Autolock lock(m_videoLock);
+ android::Mutex::Autolock lock(m_mediaLock);
return m_surfaceTextureClient.get();
}
-void VideoTexture::releaseNativeWindow()
+void MediaTexture::releaseNativeWindow()
{
- android::Mutex::Autolock lock(m_videoLock);
+ android::Mutex::Autolock lock(m_mediaLock);
m_dimensions.setEmpty();
if (m_surfaceTexture.get())
m_surfaceTexture.clear();
}
-void VideoTexture::setDimensions(const SkRect& dimensions)
+void MediaTexture::setDimensions(const SkRect& dimensions)
{
- android::Mutex::Autolock lock(m_videoLock);
+ android::Mutex::Autolock lock(m_mediaLock);
m_dimensions = dimensions;
}
namespace WebCore {
-class VideoListener;
+class MediaListener;
-class MediaTexture : public DoubleBufferedTexture {
+class MediaTexture : public android::LightRefBase<MediaTexture> {
public:
- MediaTexture(EGLContext sharedContext);
-
- void producerInc();
- void producerDec();
- void consumerInc();
- void consumerDec();
-
- int getProducerCount() { android::Mutex::Autolock lock(m_mediaLock); return m_producerRefCount; }
- int getConsumerCount() { android::Mutex::Autolock lock(m_mediaLock); return m_consumerRefCount; }
-
-private:
- android::Mutex m_mediaLock;
- int m_producerRefCount;
- int m_consumerRefCount;
-};
-
-class VideoTexture : public android::LightRefBase<VideoTexture> {
-
-public:
- VideoTexture(jobject weakWebViewRef);
- ~VideoTexture();
+ MediaTexture(jobject weakWebViewRef);
+ ~MediaTexture();
void initNativeWindowIfNeeded();
+ void drawContent(const TransformationMatrix& matrix);
void drawVideo(const TransformationMatrix& matrix, const SkRect& parentBounds);
ANativeWindow* requestNewWindow();
GLuint m_textureId;
sp<android::SurfaceTexture> m_surfaceTexture;
sp<ANativeWindow> m_surfaceTextureClient;
- sp<VideoListener> m_videoListener;
+ sp<MediaListener> m_mediaListener;
SkRect m_dimensions;
bool m_newWindowRequest;
bool m_newWindowReady;
jobject m_weakWebViewRef;
- android::Mutex m_videoLock;
- android::Condition m_newVideoRequestCond;
+ android::Mutex m_mediaLock;
+ android::Condition m_newMediaRequestCond;
};
return otherTexture.m_textureId == m_textureId && equalsAttributes(&otherTexture);
}
-GLenum TextureInfo::getTextureTarget()
-{
-#if DEPRECATED_SURFACE_TEXTURE_MODE
- if (m_surfaceTexture.get()) {
- GLenum target = m_surfaceTexture->getCurrentTextureTarget();
- // TODO: remove this translation when TEXTURE_2D+RGBA surface texture
- // support is deprecated.
- if (target == GL_TEXTURE_2D)
- return 0;
- return target;
- }
-#endif
- return GL_TEXTURE_2D;
-}
-
} // namespace WebCore
#include "PluginWidgetAndroid.h"
#include "android_npapi.h"
-#include "ANPOpenGL_npapi.h"
+#include "ANPNativeWindow_npapi.h"
#include "ANPSurface_npapi.h"
#include "ANPSystem_npapi.h"
#include "ANPVideo_npapi.h"
extern void ANPSystemInterfaceV0_Init(ANPInterface* value);
extern void ANPSystemInterfaceV1_Init(ANPInterface* value);
extern void ANPSystemInterfaceV2_Init(ANPInterface* value);
-extern void ANPOpenGLInterfaceV0_Init(ANPInterface* value);
+extern void ANPNativeWindowInterfaceV0_Init(ANPInterface* value);
extern void ANPVideoInterfaceV0_Init(ANPInterface* value);
struct VarProcPair {
{ VARPROCLINE(SystemInterfaceV0) },
{ VARPROCLINE(SystemInterfaceV1) },
{ VARPROCLINE(SystemInterfaceV2) },
- { VARPROCLINE(OpenGLInterfaceV0) },
+ { VARPROCLINE(NativeWindowInterfaceV0) },
{ VARPROCLINE(VideoInterfaceV0) },
};
android/plugins/ANPEventInterface.cpp \
android/plugins/ANPLogInterface.cpp \
android/plugins/ANPMatrixInterface.cpp \
- android/plugins/ANPOpenGLInterface.cpp \
+ android/plugins/ANPNativeWindowInterface.cpp \
android/plugins/ANPPaintInterface.cpp \
android/plugins/ANPPathInterface.cpp \
android/plugins/ANPSoundInterface.cpp \
/*
- * Copyright 2010, The Android Open Source Project
+ * Copyright 2011, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
// must include config.h first for webkit to fiddle with new/delete
#include "config.h"
-#include "ANPOpenGL_npapi.h"
+#include "ANPNativeWindow_npapi.h"
+
+#include <android/native_window.h>
#include "PluginView.h"
#include "PluginWidgetAndroid.h"
#include "MediaLayer.h"
#include "Chrome.h"
#include "ChromeClient.h"
+
using namespace android;
static WebCore::PluginView* pluginViewForInstance(NPP instance) {
return WebCore::PluginView::currentPluginView();
}
-static EGLContext anp_acquireContext(NPP instance) {
+static WebCore::MediaLayer* mediaLayerForInstance(NPP instance) {
WebCore::PluginView* pluginView = pluginViewForInstance(instance);
PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget();
- WebCore::MediaLayer* mediaLayer = pluginWidget->getLayer();
-
- if (!mediaLayer)
- return EGL_NO_CONTEXT;
-
- return mediaLayer->getTexture()->producerAcquireContext();
+ return pluginWidget->getLayer();
}
-static ANPTextureInfo anp_lockTexture(NPP instance) {
- WebCore::PluginView* pluginView = pluginViewForInstance(instance);
- PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget();
- WebCore::MediaLayer* mediaLayer = pluginWidget->getLayer();
- WebCore::DoubleBufferedTexture* texture = mediaLayer->getTexture();
-
- // lock the texture and cache the internal info
- WebCore::TextureInfo* info = texture->producerLock();
- mediaLayer->setCurrentTextureInfo(info);
-
- ANPTextureInfo anpInfo;
- anpInfo.textureId = info->m_textureId;
- anpInfo.width = (int32_t) info->m_width;
- anpInfo.height = (int32_t) info->m_height;
- anpInfo.internalFormat = info->m_internalFormat;
- return anpInfo;
-}
-
-static void anp_releaseTexture(NPP instance, const ANPTextureInfo* textureInfo) {
- WebCore::PluginView* pluginView = pluginViewForInstance(instance);
- PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget();
- WebCore::MediaLayer* mediaLayer = pluginWidget->getLayer();
- WebCore::DoubleBufferedTexture* texture = mediaLayer->getTexture();
-
- //copy the info into our internal structure
- WebCore::TextureInfo* info = mediaLayer->getCurrentTextureInfo();
- info->m_textureId = textureInfo->textureId;
- info->m_width = textureInfo->width;
- info->m_height = textureInfo->height;
- info->m_internalFormat = textureInfo->internalFormat;
-
- texture->producerReleaseAndSwap();
+static ANativeWindow* anp_acquireNativeWindow(NPP instance) {
+ WebCore::MediaLayer* mediaLayer = mediaLayerForInstance(instance);
+ if (!mediaLayer)
+ return 0;
- // invalidate the java view so that this content is drawn
- pluginWidget->viewInvalidate();
+ return mediaLayer->acquireNativeWindowForContent();
}
static void anp_invertPluginContent(NPP instance, bool isContentInverted) {
- WebCore::PluginView* pluginView = pluginViewForInstance(instance);
+ PluginView* pluginView = pluginViewForInstance(instance);
PluginWidgetAndroid* pluginWidget = pluginView->platformPluginWidget();
WebCore::MediaLayer* mediaLayer = pluginWidget->getLayer();
+ // update the layer
mediaLayer->invertContents(isContentInverted);
//force the layer to sync to the UI thread
}
-
///////////////////////////////////////////////////////////////////////////////
#define ASSIGN(obj, name) (obj)->name = anp_##name
-void ANPOpenGLInterfaceV0_Init(ANPInterface* v) {
- ANPOpenGLInterfaceV0* i = reinterpret_cast<ANPOpenGLInterfaceV0*>(v);
+void ANPNativeWindowInterfaceV0_Init(ANPInterface* v) {
+ ANPNativeWindowInterfaceV0* i = reinterpret_cast<ANPNativeWindowInterfaceV0*>(v);
- ASSIGN(i, acquireContext);
- ASSIGN(i, lockTexture);
- ASSIGN(i, releaseTexture);
+ ASSIGN(i, acquireNativeWindow);
ASSIGN(i, invertPluginContent);
}
--- /dev/null
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ANPNativeWindow_npapi_h
+#define ANPNativeWindow_npapi_h
+
+#include "android_npapi.h"
+
+struct ANativeWindow;
+
+struct ANPNativeWindowInterfaceV0 : ANPInterface {
+ /**
+ * Constructs a new native window to be used for rendering plugin content.
+ *
+ * Subsequent calls will return the original constructed window. Further, if
+ * the browser is unable to acquire the window quickly it may return NULL in
+ * order to not block the plugin indefinitely. A subsequent call will then
+ * return the window if it is available.
+ */
+ ANativeWindow* (*acquireNativeWindow)(NPP instance);
+
+ /**
+ * Invert the contents of the plugin on the y-axis.
+ * default is to not be inverted (e.g. use OpenGL coordinates)
+ */
+ void (*invertPluginContent)(NPP instance, bool isContentInverted);
+};
+
+#endif // ANPNativeWindow_npapi_h
#define kSystemInterfaceV2_ANPGetValue ((NPNVariable)1017)
#define kWindowInterfaceV2_ANPGetValue ((NPNVariable)1018)
+#define kNativeWindowInterfaceV0_ANPGetValue ((NPNVariable)1019)
+
/** queries for the drawing models supported on this device.
NPN_GetValue(inst, kSupportedDrawingModel_ANPGetValue, uint32_t* bits)