Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[embedlite] Add support for using external compositor GL context.
This implements generic support for using compositor GL context provided
by the application. The aim of the patch is to generalize original Jolla
external window handling patch into something that can be included in
upstream embedlite. Compared to the original implementation this one
does not modify any code in the gecko engine itself. It's all contained
within embedlite layer.

The whole functionality is optional and can be controller by
embedlite.compositor.external_gl_context preference. When set to false
(default) Gecko composior will create GL context on it's own as it
normally does. Setting the pref to true will make embedlite request GL
context from the application through
EmbedLiteViewListener::RequestCurrentGLContext. The implementation of
the funtion is supposed to create the GL context and surface the
compositor is supposed to use and make it current via eglMakeCurrent
call.
  • Loading branch information
tworaz committed Jun 24, 2015
1 parent 5602689 commit 51366e0
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 17 deletions.
2 changes: 2 additions & 0 deletions embedding/embedlite/embedding.js
Expand Up @@ -111,6 +111,8 @@ pref("embedlite.azpc.json.singletap", false);
pref("embedlite.azpc.json.doubletap", false);
pref("embedlite.azpc.json.longtap", false);
pref("embedlite.azpc.json.scroll", false);
// Make gecko compositor use GL context/surface provided by the application.
pref("embedlite.compositor.external_gl_context", false);
pref("extensions.update.enabled", false);
pref("toolkit.storage.synchronous", 0);
/* new html5 forms */
Expand Down
48 changes: 40 additions & 8 deletions embedding/embedlite/embedshared/EmbedLitePuppetWidget.cpp
Expand Up @@ -19,12 +19,15 @@
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/ipc/MessageChannel.h"
#include "EmbedLitePuppetWidget.h"
#include "EmbedLiteView.h"
#include "nsIWidgetListener.h"

#include "Layers.h"
#include "BasicLayers.h"
#include "ClientLayerManager.h"
#include "GLContextProvider.h"
#include "GLContext.h"
#include "GLLibraryEGL.h"
#include "EmbedLiteCompositorParent.h"
#include "mozilla/Preferences.h"
#include "EmbedLiteApp.h"
Expand All @@ -33,6 +36,7 @@
#include "mozilla/BasicEvents.h"

using namespace mozilla::dom;
using namespace mozilla::gl;
using namespace mozilla::hal;
using namespace mozilla::layers;
using namespace mozilla::widget;
Expand All @@ -46,6 +50,7 @@ const size_t EmbedLitePuppetWidget::kMaxDimension = 4000;

static nsTArray<EmbedLitePuppetWidget*> gTopLevelWindows;
static bool sFailedToCreateGLContext = false;
static bool sUseExternalGLContext = false;

NS_IMPL_ISUPPORTS_INHERITED(EmbedLitePuppetWidget, nsBaseWidget,
nsISupportsWeakReference)
Expand Down Expand Up @@ -92,6 +97,12 @@ EmbedLitePuppetWidget::EmbedLitePuppetWidget(EmbedLiteViewChildIface* aEmbed, ui
{
MOZ_COUNT_CTOR(EmbedLitePuppetWidget);
LOGT("this:%p", this);
static bool prefsInitialized = false;
if (!prefsInitialized) {
Preferences::AddBoolVarCache(&sUseExternalGLContext,
"embedlite.compositor.external_gl_context", false);
prefsInitialized = true;
}
}

EmbedLitePuppetWidget::~EmbedLitePuppetWidget()
Expand Down Expand Up @@ -263,6 +274,10 @@ EmbedLitePuppetWidget::GetNativeData(uint32_t aDataType)
LOGW("aDataType:%i\n", __LINE__, aDataType);
return (void*)nullptr;
}
case NS_NATIVE_OPENGL_CONTEXT: {
MOZ_ASSERT(!GetParent());
return GetGLContext();
}
case NS_NATIVE_WINDOW:
case NS_NATIVE_DISPLAY:
case NS_NATIVE_PLUGIN_PORT:
Expand Down Expand Up @@ -418,6 +433,31 @@ EmbedLitePuppetWidget::ViewIsValid()
return EmbedLiteApp::GetInstance()->GetViewByID(mId) != nullptr;
}

GLContext*
EmbedLitePuppetWidget::GetGLContext() const
{
LOGT("this:%p, UseExternalContext:%d", this, sUseExternalGLContext);
if (sUseExternalGLContext) {
if (!sEGLLibrary.EnsureInitialized()) {
return nullptr;
}

EmbedLiteView* view = EmbedLiteApp::GetInstance()->GetViewByID(mId);
if (view && view->GetListener()->RequestCurrentGLContext()) {
void* surface = sEGLLibrary.fGetCurrentSurface(LOCAL_EGL_DRAW);
void* context = sEGLLibrary.fGetCurrentContext();
nsRefPtr<GLContext> mozContext = GLContextProvider::CreateWrappingExisting(context, surface);
if (!mozContext->Init()) {
return nullptr;
}
return mozContext.forget().take();
} else {
NS_ERROR("Embedder wants to use external GL context without actually providing it!");
}
}
return nullptr;
}

LayerManager*
EmbedLitePuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
LayersBackend aBackendHint,
Expand Down Expand Up @@ -577,14 +617,6 @@ EmbedLitePuppetWidget::GetNaturalBounds()
return nsIntRect();
}

bool
EmbedLitePuppetWidget::HasGLContext()
{
EmbedLiteCompositorParent* parent =
static_cast<EmbedLiteCompositorParent*>(mCompositorParent.get());
return parent->RequestGLContext();
}

void
EmbedLitePuppetWidget::DrawWindowUnderlay(LayerManagerComposite *aManager, nsIntRect aRect)
{
Expand Down
2 changes: 1 addition & 1 deletion embedding/embedlite/embedshared/EmbedLitePuppetWidget.h
Expand Up @@ -145,7 +145,6 @@ class EmbedLitePuppetWidget : public nsBaseWidget
virtual void CreateCompositor(int aWidth, int aHeight);
virtual void CreateCompositor();
virtual nsIntRect GetNaturalBounds();
virtual bool HasGLContext();

/**
* Called before the LayerManager draws the layer tree.
Expand All @@ -172,6 +171,7 @@ class EmbedLitePuppetWidget : public nsBaseWidget
private:
nsresult Paint();
bool ViewIsValid();
mozilla::gl::GLContext* GetGLContext() const;

EmbedLitePuppetWidget* TopWindow();
bool IsTopLevel();
Expand Down
6 changes: 0 additions & 6 deletions embedding/embedlite/embedthread/EmbedLiteCompositorParent.cpp
Expand Up @@ -317,12 +317,6 @@ EmbedLiteCompositorParent::ResumeRendering()
CompositorParent::ScheduleResumeOnCompositorThread(mLastViewSize.width, mLastViewSize.height);
}

bool EmbedLiteCompositorParent::RequestGLContext()
{
EmbedLiteView* view = EmbedLiteApp::GetInstance()->GetViewByID(mId);
return view ? view->GetListener()->RequestCurrentGLContext() : false;
}

void EmbedLiteCompositorParent::DrawWindowUnderlay(LayerManagerComposite *aManager, nsIntRect aRect)
{
EmbedLiteView* view = EmbedLiteApp::GetInstance()->GetViewByID(mId);
Expand Down
2 changes: 0 additions & 2 deletions embedding/embedlite/embedthread/EmbedLiteCompositorParent.h
Expand Up @@ -37,8 +37,6 @@ class EmbedLiteCompositorParent : public mozilla::layers::CompositorParent
virtual void SuspendRendering();
virtual void ResumeRendering();

virtual bool RequestGLContext();

void DrawWindowUnderlay(mozilla::layers::LayerManagerComposite *aManager, nsIntRect aRect);
void DrawWindowOverlay(mozilla::layers::LayerManagerComposite *aManager, nsIntRect aRect);

Expand Down

0 comments on commit 51366e0

Please sign in to comment.