Bug 1227706 - Let GeckoView manage GLController instances; r=snorp

GLController instances are associated with a particular nsWindow, rather
than a particular View. Therefore, we need to let GeckoView manage
GLController instances, as part of GeckoView's handling of saving and
restoring states.
This commit is contained in:
Jim Chen 2015-12-23 22:03:34 -05:00
parent 43d7399cf2
commit 325ee148ee
9 changed files with 130 additions and 55 deletions

View File

@ -13,6 +13,7 @@ import java.util.Set;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.gfx.GLController;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.mozglue.JNIObject;
@ -115,8 +116,8 @@ public class GeckoView extends LayerView
@WrapForJNI
private static final class Window extends JNIObject {
static native void open(Window instance, GeckoView view, int width, int height);
static native void setLayerClient(Object client);
static native void open(Window instance, GeckoView view, GLController glController,
int width, int height);
@Override protected native void disposeNative();
native void close();
}
@ -155,14 +156,6 @@ public class GeckoView extends LayerView
initializeView(EventDispatcher.getInstance());
if (GeckoThread.isStateAtLeast(GeckoThread.State.JNI_READY)) {
Window.setLayerClient(getLayerClientObject());
} else {
GeckoThread.queueNativeCallUntil(GeckoThread.State.JNI_READY,
Window.class, "setLayerClient",
Object.class, getLayerClientObject());
}
// TODO: Fennec currently takes care of its own initialization, so this
// flag is a hack used in Fennec to prevent GeckoView initialization.
// This should go away once Fennec also uses GeckoView for
@ -225,17 +218,23 @@ public class GeckoView extends LayerView
@Override
public void onAttachedToWindow()
{
super.onAttachedToWindow();
final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
// TODO: reuse GLController when restoring state.
final GLController glController = new GLController();
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
Window.open(window, this, metrics.widthPixels, metrics.heightPixels);
Window.open(window, this, glController,
metrics.widthPixels, metrics.heightPixels);
} else {
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY, Window.class,
"open", window, GeckoView.class, this,
"open", window, GeckoView.class, this, glController,
metrics.widthPixels, metrics.heightPixels);
}
setGLController(glController);
super.onAttachedToWindow();
}
@Override

View File

@ -33,9 +33,7 @@ public class GLController extends JNIObject {
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
private static final String LOGTAG = "GeckoGLController";
private static GLController sInstance;
private LayerView mView;
/* package */ LayerView mView;
private boolean mServerSurfaceValid;
private int mWidth, mHeight;
@ -90,15 +88,7 @@ public class GLController extends JNIObject {
@WrapForJNI
/* package */ native void syncInvalidateAndScheduleComposite();
private GLController() {
}
static GLController getInstance(LayerView view) {
if (sInstance == null) {
sInstance = new GLController();
}
sInstance.mView = view;
return sInstance;
public GLController() {
}
synchronized void serverSurfaceDestroyed() {

View File

@ -55,7 +55,7 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
private GeckoLayerClient mLayerClient;
private PanZoomController mPanZoomController;
private DynamicToolbarAnimator mToolbarAnimator;
private final GLController mGLController;
private GLController mGLController;
private LayerRenderer mRenderer;
/* Must be a PAINT_xxx constant */
private int mPaintState;
@ -106,7 +106,6 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
public LayerView(Context context, AttributeSet attrs) {
super(context, attrs);
mGLController = GLController.getInstance(this);
mPaintState = PAINT_START;
mBackgroundColor = Color.WHITE;
mFullScreenState = FullScreenState.NONE;
@ -199,6 +198,12 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
if (mRenderer != null) {
mRenderer.destroy();
}
if (mGLController != null) {
if (mGLController.mView == this) {
mGLController.mView = null;
}
mGLController = null;
}
Tabs.unregisterOnTabsChangedListener(this);
}
@ -324,7 +329,6 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
// Don't expose GeckoLayerClient to things outside this package; only expose it as an Object
GeckoLayerClient getLayerClient() { return mLayerClient; }
public Object getLayerClientObject() { return mLayerClient; }
public PanZoomController getPanZoomController() { return mPanZoomController; }
public DynamicToolbarAnimator getDynamicToolbarAnimator() { return mToolbarAnimator; }
@ -433,6 +437,18 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
return mListener;
}
public void setGLController(final GLController glController) {
mGLController = glController;
glController.mView = this;
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
glController.setLayerClient(mLayerClient);
} else {
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
glController, "setLayerClient", mLayerClient);
}
}
public GLController getGLController() {
return mGLController;
}

View File

@ -203,11 +203,7 @@ public:
mozilla::jni::MakeNativeMethod<GeckoView::Window::Open_t>(
mozilla::jni::NativeStub<GeckoView::Window::Open_t, Impl>
::template Wrap<&Impl::Open>),
mozilla::jni::MakeNativeMethod<GeckoView::Window::SetLayerClient_t>(
mozilla::jni::NativeStub<GeckoView::Window::SetLayerClient_t, Impl>
::template Wrap<&Impl::SetLayerClient>)
::template Wrap<&Impl::Open>)
};
};

View File

@ -1113,9 +1113,6 @@ constexpr char GeckoView::Window::DisposeNative_t::signature[];
constexpr char GeckoView::Window::Open_t::name[];
constexpr char GeckoView::Window::Open_t::signature[];
constexpr char GeckoView::Window::SetLayerClient_t::name[];
constexpr char GeckoView::Window::SetLayerClient_t::signature[];
constexpr char PrefsHelper::name[];
constexpr char PrefsHelper::GetPrefsById_t::name[];

View File

@ -2983,27 +2983,12 @@ public:
typedef mozilla::jni::Args<
Window::Param,
GeckoView::Param,
mozilla::jni::Object::Param,
int32_t,
int32_t> Args;
static constexpr char name[] = "open";
static constexpr char signature[] =
"(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;II)V";
static const bool isStatic = true;
static const bool isMultithreaded = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
public:
struct SetLayerClient_t {
typedef Window Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::Object::Param> Args;
static constexpr char name[] = "setLayerClient";
static constexpr char signature[] =
"(Ljava/lang/Object;)V";
"(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Lorg/mozilla/gecko/gfx/GLController;II)V";
static const bool isStatic = true;
static const bool isMultithreaded = true;
static const mozilla::jni::ExceptionMode exceptionMode =

View File

@ -148,6 +148,12 @@ public:
return Ref<Cls>(static_cast<jobject>(obj));
}
// Construct a Ref form a generic object reference.
static Ref<Cls> From(const RefBase<Object, jobject>& obj)
{
return Ref<Cls>(obj.Get());
}
// Get the raw JNI reference.
JNIType Get() const
{

View File

@ -268,7 +268,7 @@ public:
// Create and attach a window.
static void Open(const jni::ClassObject::LocalRef& aCls,
GeckoView::Window::Param aWindow,
GeckoView::Param aView,
GeckoView::Param aView, jni::Object::Param aGLController,
int32_t aWidth, int32_t aHeight);
// Set the active layer client object
@ -374,6 +374,77 @@ public:
void OnImeUpdateComposition(int32_t aStart, int32_t aEnd);
};
/**
* GLController has some unique requirements for its native calls, so make it
* separate from GeckoViewSupport.
*/
class nsWindow::GLControllerSupport final
: public GLController::Natives<GLControllerSupport>
, public SupportsWeakPtr<GLControllerSupport>
, public UsesGeckoThreadProxy
{
nsWindow& window;
GLController::GlobalRef mGLController;
public:
typedef GLController::Natives<GLControllerSupport> Base;
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(GLControllerSupport);
GLControllerSupport(nsWindow* aWindow,
const GLController::LocalRef& aInstance)
: window(*aWindow)
, mGLController(aInstance)
{
Reattach(aInstance);
}
~GLControllerSupport()
{
GLController::GlobalRef glController(mozilla::Move(mGLController));
nsAppShell::gAppShell->PostEvent([glController] {
GLControllerSupport::DisposeNative(GLController::LocalRef(
jni::GetGeckoThreadEnv(), glController));
});
}
void Reattach(const GLController::LocalRef& aInstance)
{
Base::AttachNative(aInstance, this);
}
/**
* GLController methods
*/
public:
using Base::DisposeNative;
void SetLayerClient(jni::Object::Param aClient)
{
// TODO: implement.
}
void CreateCompositor(int32_t aWidth, int32_t aHeight)
{
// TODO: implement.
}
void PauseCompositor()
{
// TODO: implement.
}
void SyncResumeResizeCompositor(int32_t aWidth, int32_t aHeight)
{
// TODO: implement.
}
void SyncInvalidateAndScheduleComposite()
{
// TODO: implement.
}
};
nsWindow::GeckoViewSupport::~GeckoViewSupport()
{
// Disassociate our GeckoEditable instance with our native object.
@ -387,6 +458,7 @@ nsWindow::GeckoViewSupport::~GeckoViewSupport()
nsWindow::GeckoViewSupport::Open(const jni::ClassObject::LocalRef& aCls,
GeckoView::Window::Param aWindow,
GeckoView::Param aView,
jni::Object::Param aGLController,
int32_t aWidth, int32_t aHeight)
{
MOZ_ASSERT(NS_IsMainThread());
@ -400,6 +472,10 @@ nsWindow::GeckoViewSupport::Open(const jni::ClassObject::LocalRef& aCls,
gGeckoViewWindow->mGeckoViewSupport->Reattach(
GeckoView::Window::LocalRef(aCls.Env(), aWindow));
MOZ_ASSERT(gGeckoViewWindow->mGLControllerSupport);
gGeckoViewWindow->mGLControllerSupport->Reattach(GLController::LocalRef(
aCls.Env(), GLController::Ref::From(aGLController)));
// Associate our previous GeckoEditable with the new GeckoView.
gGeckoViewWindow->mGeckoViewSupport->mEditable->OnViewChange(aView);
return;
@ -443,6 +519,11 @@ nsWindow::GeckoViewSupport::Open(const jni::ClassObject::LocalRef& aCls,
window->mGeckoViewSupport = mozilla::MakeUnique<GeckoViewSupport>(
window, GeckoView::Window::LocalRef(aCls.Env(), aWindow), aView);
// Attach the GLController to the new window.
window->mGLControllerSupport = mozilla::MakeUnique<GLControllerSupport>(
window, GLController::LocalRef(
aCls.Env(), GLController::Ref::From(aGLController)));
gGeckoViewWindow = window;
}
@ -470,6 +551,7 @@ nsWindow::InitNatives()
{
nsWindow::GeckoViewSupport::Base::Init();
nsWindow::GeckoViewSupport::EditableBase::Init();
nsWindow::GLControllerSupport::Init();
}
nsWindow*

View File

@ -53,6 +53,10 @@ private:
// nullptr for nsWindows that were not opened from GeckoView.
mozilla::UniquePtr<GeckoViewSupport> mGeckoViewSupport;
class GLControllerSupport;
// Object that implements native GLController calls.
mozilla::UniquePtr<GLControllerSupport> mGLControllerSupport;
public:
static void OnGlobalAndroidEvent(mozilla::AndroidGeckoEvent *ae);
static mozilla::gfx::IntSize GetAndroidScreenBounds();