Skip to content

Commit

Permalink
Merge pull request #72 from tworaz/for_upstream/jb30162_external_gl_c…
Browse files Browse the repository at this point in the history
…ontext

[xulrunner] Generalize and improve external gl context handling. Contributes to JB#30162
  • Loading branch information
tmeshkova committed Jun 25, 2015
2 parents 54094e2 + e214344 commit 872de3f
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 17 deletions.
6 changes: 6 additions & 0 deletions embedding/embedlite/embedding.js
Expand Up @@ -111,6 +111,12 @@ 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);
// Request the application to create GLContext for the compositor as
// soon as the top level PuppetWidget is creted for the view. Setting
// this pref only makes sense when using external compositor gl context.
pref("embedlite.compositor.request_external_gl_context_early", false);
pref("extensions.update.enabled", false);
pref("toolkit.storage.synchronous", 0);
/* new html5 forms */
Expand Down
72 changes: 64 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,8 @@ const size_t EmbedLitePuppetWidget::kMaxDimension = 4000;

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

NS_IMPL_ISUPPORTS_INHERITED(EmbedLitePuppetWidget, nsBaseWidget,
nsISupportsWeakReference)
Expand Down Expand Up @@ -92,6 +98,14 @@ 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);
Preferences::AddBoolVarCache(&sRequestGLContextEarly,
"embedlite.compositor.request_external_gl_context_early", false);
prefsInitialized = true;
}
}

EmbedLitePuppetWidget::~EmbedLitePuppetWidget()
Expand Down Expand Up @@ -143,6 +157,13 @@ EmbedLitePuppetWidget::Create(nsIWidget* aParent,
gTopLevelWindows.AppendElement(this);
}

if (sUseExternalGLContext && sRequestGLContextEarly) {
// GetPlatform() should create compositor loop if it doesn't exist, yet.
gfxPlatform::GetPlatform();
CompositorParent::CompositorLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&CreateGLContextEarly, mId));
}

return NS_OK;
}

Expand Down Expand Up @@ -263,6 +284,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 +443,45 @@ 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;
}

void
EmbedLitePuppetWidget::CreateGLContextEarly(uint32_t aViewId)
{
LOGT("ViewId:%u", aViewId);
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
MOZ_ASSERT(sRequestGLContextEarly);
EmbedLiteView* view = EmbedLiteApp::GetInstance()->GetViewByID(aViewId);
if (view) {
view->GetListener()->RequestCurrentGLContext();
} else {
NS_WARNING("Trying to early create GL context for non existing view!");
}
}

LayerManager*
EmbedLitePuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
LayersBackend aBackendHint,
Expand Down Expand Up @@ -577,14 +641,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
3 changes: 2 additions & 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,8 @@ class EmbedLitePuppetWidget : public nsBaseWidget
private:
nsresult Paint();
bool ViewIsValid();
mozilla::gl::GLContext* GetGLContext() const;
static void CreateGLContextEarly(uint32_t aViewId);

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 872de3f

Please sign in to comment.