Bug 1322650 - Adjust Android Flash support to API changes r=jchen

MozReview-Commit-ID: CmMINaGcTER
This commit is contained in:
James Willcox
2017-03-09 17:51:17 -06:00
parent cfc584ce3c
commit f36c3659d7
7 changed files with 90 additions and 56 deletions

View File

@@ -58,6 +58,8 @@ using namespace mozilla::dom;
#include "TexturePoolOGL.h" #include "TexturePoolOGL.h"
#include "SurfaceTypes.h" #include "SurfaceTypes.h"
#include "EGLUtils.h" #include "EGLUtils.h"
#include "GeneratedJNIWrappers.h"
#include "GeneratedJNINatives.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::gl; using namespace mozilla::gl;
@@ -106,7 +108,7 @@ static bool EnsureGLContext()
static std::map<NPP, nsNPAPIPluginInstance*> sPluginNPPMap; static std::map<NPP, nsNPAPIPluginInstance*> sPluginNPPMap;
#endif #endif // MOZ_WIDGET_ANDROID
using namespace mozilla; using namespace mozilla;
using namespace mozilla::plugins::parent; using namespace mozilla::plugins::parent;
@@ -202,14 +204,12 @@ nsNPAPIPluginInstance::Destroy()
mAudioChannelAgent = nullptr; mAudioChannelAgent = nullptr;
#if MOZ_WIDGET_ANDROID #if MOZ_WIDGET_ANDROID
if (mContentSurface) if (mContentSurface) {
mContentSurface->SetFrameAvailableCallback(nullptr); java::SurfaceAllocator::DisposeSurface(mContentSurface);
}
mContentSurface = nullptr;
std::map<void*, VideoInfo*>::iterator it; std::map<void*, VideoInfo*>::iterator it;
for (it = mVideos.begin(); it != mVideos.end(); it++) { for (it = mVideos.begin(); it != mVideos.end(); it++) {
it->second->mSurfaceTexture->SetFrameAvailableCallback(nullptr);
delete it->second; delete it->second;
} }
mVideos.clear(); mVideos.clear();
@@ -858,24 +858,50 @@ GLContext* nsNPAPIPluginInstance::GLContext()
return sPluginContext; return sPluginContext;
} }
already_AddRefed<AndroidSurfaceTexture> nsNPAPIPluginInstance::CreateSurfaceTexture() class PluginTextureListener
: public java::SurfaceTextureListener::Natives<PluginTextureListener>
{ {
if (!EnsureGLContext()) using Base = java::SurfaceTextureListener::Natives<PluginTextureListener>;
return nullptr;
GLuint texture = TexturePoolOGL::AcquireTexture(); const nsCOMPtr<nsIRunnable> mCallback;
if (!texture) public:
return nullptr; using Base::AttachNative;
using Base::DisposeNative;
RefPtr<AndroidSurfaceTexture> surface = AndroidSurfaceTexture::Create(TexturePoolOGL::GetGLContext(), PluginTextureListener(nsIRunnable* aCallback) : mCallback(aCallback) {}
texture);
if (!surface) { void OnFrameAvailable()
{
if (NS_IsMainThread()) {
mCallback->Run();
return;
}
NS_DispatchToMainThread(mCallback);
}
};
java::GeckoSurface::LocalRef nsNPAPIPluginInstance::CreateSurface()
{
java::GeckoSurface::LocalRef surf = java::SurfaceAllocator::AcquireSurface(0, 0, false);
if (!surf) {
return nullptr; return nullptr;
} }
nsCOMPtr<nsIRunnable> frameCallback = NewRunnableMethod(this, &nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable); nsCOMPtr<nsIRunnable> frameCallback = NewRunnableMethod(this, &nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable);
surface->SetFrameAvailableCallback(frameCallback);
return surface.forget(); java::SurfaceTextureListener::LocalRef listener = java::SurfaceTextureListener::New();
PluginTextureListener::AttachNative(listener, MakeUnique<PluginTextureListener>(frameCallback.get()));
java::GeckoSurfaceTexture::LocalRef gst = java::GeckoSurfaceTexture::Lookup(surf->GetHandle());
if (!gst) {
return nullptr;
}
const auto& st = java::sdk::SurfaceTexture::Ref::From(gst);
st->SetOnFrameAvailableListener(listener);
return surf;
} }
void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable() void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable()
@@ -886,35 +912,29 @@ void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable()
void* nsNPAPIPluginInstance::AcquireContentWindow() void* nsNPAPIPluginInstance::AcquireContentWindow()
{ {
if (!mContentSurface) { if (!mContentWindow.NativeWindow()) {
mContentSurface = CreateSurfaceTexture(); mContentSurface = CreateSurface();
if (!mContentSurface) if (!mContentSurface)
return nullptr; return nullptr;
mContentWindow = AndroidNativeWindow(mContentSurface);
} }
return mContentSurface->NativeWindow(); return mContentWindow.NativeWindow();
} }
AndroidSurfaceTexture* java::GeckoSurface::Param
nsNPAPIPluginInstance::AsSurfaceTexture() nsNPAPIPluginInstance::AsSurface()
{ {
if (!mContentSurface)
return nullptr;
return mContentSurface; return mContentSurface;
} }
void* nsNPAPIPluginInstance::AcquireVideoWindow() void* nsNPAPIPluginInstance::AcquireVideoWindow()
{ {
RefPtr<AndroidSurfaceTexture> surface = CreateSurfaceTexture(); java::GeckoSurface::LocalRef surface = CreateSurface();
if (!surface) {
return nullptr;
}
VideoInfo* info = new VideoInfo(surface); VideoInfo* info = new VideoInfo(surface);
void* window = info->mSurfaceTexture->NativeWindow(); void* window = info->mNativeWindow.NativeWindow();
mVideos.insert(std::pair<void*, VideoInfo*>(window, info)); mVideos.insert(std::pair<void*, VideoInfo*>(window, info));
return window; return window;

View File

@@ -21,7 +21,7 @@
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
#include "nsIRunnable.h" #include "nsIRunnable.h"
#include "GLContextTypes.h" #include "GLContextTypes.h"
#include "AndroidSurfaceTexture.h" #include "AndroidNativeWindow.h"
#include "AndroidBridge.h" #include "AndroidBridge.h"
#include <map> #include <map>
class PluginEventRunnable; class PluginEventRunnable;
@@ -215,22 +215,24 @@ public:
// For ANPNativeWindow // For ANPNativeWindow
void* AcquireContentWindow(); void* AcquireContentWindow();
mozilla::gl::AndroidSurfaceTexture* AsSurfaceTexture(); mozilla::java::GeckoSurface::Param AsSurface();
// For ANPVideo // For ANPVideo
class VideoInfo { class VideoInfo {
public: public:
VideoInfo(mozilla::gl::AndroidSurfaceTexture* aSurfaceTexture) : VideoInfo(mozilla::java::GeckoSurface::Param aSurface)
mSurfaceTexture(aSurfaceTexture) : mSurface(aSurface)
, mNativeWindow(aSurface)
{ {
} }
~VideoInfo() ~VideoInfo()
{ {
mSurfaceTexture = nullptr; mozilla::java::SurfaceAllocator::DisposeSurface(mSurface);
} }
RefPtr<mozilla::gl::AndroidSurfaceTexture> mSurfaceTexture; mozilla::java::GeckoSurface::GlobalRef mSurface;
mozilla::gl::AndroidNativeWindow mNativeWindow;
gfxRect mDimensions; gfxRect mDimensions;
}; };
@@ -359,7 +361,8 @@ protected:
bool mFullScreen; bool mFullScreen;
mozilla::gl::OriginPos mOriginPos; mozilla::gl::OriginPos mOriginPos;
RefPtr<mozilla::gl::AndroidSurfaceTexture> mContentSurface; mozilla::java::GeckoSurface::GlobalRef mContentSurface;
mozilla::gl::AndroidNativeWindow mContentWindow;
#endif #endif
enum { enum {
@@ -409,8 +412,7 @@ private:
mozilla::TimeStamp mStopTime; mozilla::TimeStamp mStopTime;
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
already_AddRefed<mozilla::gl::AndroidSurfaceTexture> CreateSurfaceTexture(); mozilla::java::GeckoSurface::LocalRef CreateSurface();
std::map<void*, VideoInfo*> mVideos; std::map<void*, VideoInfo*> mVideos;
bool mOnScreen; bool mOnScreen;

View File

@@ -165,22 +165,23 @@ nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder)
#if MOZ_WIDGET_ANDROID #if MOZ_WIDGET_ANDROID
static void static void
AttachToContainerAsSurfaceTexture(ImageContainer* container, AttachToContainerAsSurface(ImageContainer* container,
nsNPAPIPluginInstance* instance, nsNPAPIPluginInstance* instance,
const LayoutDeviceRect& rect, const LayoutDeviceRect& rect,
RefPtr<Image>* out_image) RefPtr<Image>* out_image)
{ {
MOZ_ASSERT(out_image); MOZ_ASSERT(out_image);
MOZ_ASSERT(!*out_image); MOZ_ASSERT(!*out_image);
mozilla::gl::AndroidSurfaceTexture* surfTex = instance->AsSurfaceTexture(); java::GeckoSurface::LocalRef surface = instance->AsSurface();
if (!surfTex) { if (!surface) {
return; return;
} }
RefPtr<Image> img = new SurfaceTextureImage( RefPtr<Image> img = new SurfaceTextureImage(
surfTex, surface->GetHandle(),
gfx::IntSize::Truncate(rect.width, rect.height), gfx::IntSize::Truncate(rect.width, rect.height),
true, // continuously update without a transaction
instance->OriginPos()); instance->OriginPos());
*out_image = img; *out_image = img;
} }
@@ -223,7 +224,7 @@ nsPluginInstanceOwner::GetImageContainer()
if (r.width && r.height) { if (r.width && r.height) {
// Try to get it as an EGLImage first. // Try to get it as an EGLImage first.
RefPtr<Image> img; RefPtr<Image> img;
AttachToContainerAsSurfaceTexture(container, mInstance, r, &img); AttachToContainerAsSurface(container, mInstance, r, &img);
if (img) { if (img) {
container->SetCurrentImageInTransaction(img); container->SetCurrentImageInTransaction(img);
@@ -1585,8 +1586,9 @@ nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInf
if (aVideoInfo->mDimensions.width && aVideoInfo->mDimensions.height) { if (aVideoInfo->mDimensions.width && aVideoInfo->mDimensions.height) {
RefPtr<Image> img = new SurfaceTextureImage( RefPtr<Image> img = new SurfaceTextureImage(
aVideoInfo->mSurfaceTexture, aVideoInfo->mSurface->GetHandle(),
gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height), gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height),
true, /* continuous */
gl::OriginPos::BottomLeft); gl::OriginPos::BottomLeft);
container->SetCurrentImageInTransaction(img); container->SetCurrentImageInTransaction(img);
} }

View File

@@ -19,6 +19,9 @@ namespace gl {
class AndroidNativeWindow { class AndroidNativeWindow {
public: public:
AndroidNativeWindow() : mNativeWindow(nullptr) {
}
AndroidNativeWindow(java::sdk::Surface::Param aSurface) { AndroidNativeWindow(java::sdk::Surface::Param aSurface) {
mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(), mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
aSurface.Get()); aSurface.Get());

View File

@@ -17,10 +17,12 @@ final class SurfaceTextureListener
private SurfaceTextureListener() { private SurfaceTextureListener() {
} }
@WrapForJNI(dispatchTo = "gecko") @Override // JNIObject
protected native void disposeNative();
@Override @Override
protected void disposeNative() { protected void finalize() {
// SurfaceTextureListener is disposed inside AndroidSurfaceTexture. disposeNative();
throw new IllegalStateException("unreachable code");
} }
@WrapForJNI(stubName = "OnFrameAvailable") @WrapForJNI(stubName = "OnFrameAvailable")

View File

@@ -7,5 +7,10 @@ public abstract class JNIObject
private long mHandle; private long mHandle;
// Dispose of any reference to a native object. // Dispose of any reference to a native object.
//
// If the native instance is destroyed from the native side, this should never be
// called, so you should throw an UnsupportedOperationException. If instead you
// want to destroy the native side from the Java end, make override this with
// a native call, and the right thing will be done in the native code.
protected abstract void disposeNative(); protected abstract void disposeNative();
} }

View File

@@ -44,7 +44,7 @@ namespace jni {
* *
* void AttachTo(const MyJavaClass::LocalRef& instance) * void AttachTo(const MyJavaClass::LocalRef& instance)
* { * {
* MyJavaClass::Natives<MyClass>::AttachInstance( * MyJavaClass::Natives<MyClass>::AttachNative(
* instance, static_cast<SupportsWeakPtr<MyClass>*>(this)); * instance, static_cast<SupportsWeakPtr<MyClass>*>(this));
* *
* // "instance" does NOT own "this", so the C++ object * // "instance" does NOT own "this", so the C++ object
@@ -70,7 +70,7 @@ namespace jni {
* *
* void AttachTo(const MyJavaClass::LocalRef& instance) * void AttachTo(const MyJavaClass::LocalRef& instance)
* { * {
* MyJavaClass::Natives<MyClass>::AttachInstance(instance, this); * MyJavaClass::Natives<MyClass>::AttachNative(instance, this);
* *
* // "instance" owns "this" through the RefPtr, so the C++ object * // "instance" owns "this" through the RefPtr, so the C++ object
* // may be destroyed as soon as instance.disposeNative() is called. * // may be destroyed as soon as instance.disposeNative() is called.
@@ -91,7 +91,7 @@ namespace jni {
* *
* static void AttachTo(const MyJavaClass::LocalRef& instance) * static void AttachTo(const MyJavaClass::LocalRef& instance)
* { * {
* MyJavaClass::Natives<MyClass>::AttachInstance( * MyJavaClass::Natives<MyClass>::AttachNative(
* instance, mozilla::MakeUnique<MyClass>()); * instance, mozilla::MakeUnique<MyClass>());
* *
* // "instance" owns the newly created C++ object, so the C++ * // "instance" owns the newly created C++ object, so the C++