Skip to content

Commit

Permalink
[embedlite] Fix LayerManager creation. Fixes JB#49551
Browse files Browse the repository at this point in the history
PuppetWidgetBase may create a layer manager but the sub-class must check
the bases result. Shutdown must be handled before calling base class implementation.
  • Loading branch information
rainemak committed May 5, 2020
1 parent f3c4afa commit 969274a
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 35 deletions.
47 changes: 47 additions & 0 deletions embedding/embedlite/embedshared/EmbedLitePuppetWidget.cpp
Expand Up @@ -13,6 +13,7 @@

#include "EmbedLitePuppetWidget.h"
#include "nsIWidgetListener.h"
#include "ClientLayerManager.h"
#include "BasicLayers.h"

#include "mozilla/Preferences.h"
Expand Down Expand Up @@ -370,6 +371,52 @@ void EmbedLitePuppetWidget::UpdateZoomConstraints(const uint32_t &aPresShellId,
}
}

void EmbedLitePuppetWidget::CreateCompositor()
{
MOZ_ASSERT(false, "nsWindow will create compositor");
}

void EmbedLitePuppetWidget::CreateCompositor(int aWidth, int aHeight)
{
(void)aWidth;
(void)aHeight;
MOZ_ASSERT(false, "nsWindow will create compositor with size");

}

LayerManager *
EmbedLitePuppetWidget::GetLayerManager(PLayerTransactionChild *aShadowManager, LayersBackend aBackendHint, LayerManagerPersistence aPersistence)
{
LOGT();

if (!mLayerManager) {
if (!mShutdownObserver) {
// We are shutting down, do not try to re-create a LayerManager
return nullptr;
}
}

LayerManager *lm = PuppetWidgetBase::GetLayerManager(aShadowManager, aBackendHint, aPersistence);
if (lm) {
mLayerManager = lm;
return mLayerManager;
}

if (EmbedLiteApp::GetInstance()->GetType() == EmbedLiteApp::EMBED_INVALID) {
LOGT("Create Layer Manager for Process View");

mLayerManager = new ClientLayerManager(this);
ShadowLayerForwarder* lf = mLayerManager->AsShadowForwarder();
if (!lf->HasShadowManager() && aShadowManager) {
lf->SetShadowManager(aShadowManager);
}
return mLayerManager;
}

mLayerManager = new ClientLayerManager(this);
return mLayerManager;
}

bool
EmbedLitePuppetWidget::DoSendContentReceivedInputBlock(const mozilla::layers::ScrollableLayerGuid &aGuid, uint64_t aInputBlockId, bool aPreventDefault)
{
Expand Down
7 changes: 7 additions & 0 deletions embedding/embedlite/embedshared/EmbedLitePuppetWidget.h
Expand Up @@ -69,6 +69,13 @@ class EmbedLitePuppetWidget : public PuppetWidgetBase
const FrameMetrics::ViewID& aViewId,
const mozilla::Maybe<ZoomConstraints>& aConstraints) override;

virtual void CreateCompositor() override;
virtual void CreateCompositor(int aWidth, int aHeight) override;

virtual LayerManager *GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;

bool DoSendContentReceivedInputBlock(const mozilla::layers::ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId,
bool aPreventDefault);
Expand Down
33 changes: 33 additions & 0 deletions embedding/embedlite/embedshared/PuppetWidgetBase.cpp
Expand Up @@ -10,6 +10,11 @@

#include "mozilla/Unused.h"

#include "Layers.h" // for LayerManager
#include "ClientLayerManager.h" // for ClientLayerManager

using namespace mozilla::layers;

namespace mozilla {
namespace embedlite {

Expand Down Expand Up @@ -365,6 +370,34 @@ PuppetWidgetBase::SetActive(bool active)
mActive = active;
}

LayerManager *
PuppetWidgetBase::GetLayerManager(PLayerTransactionChild *aShadowManager,
LayersBackend aBackendHint,
LayerManagerPersistence aPersistence)
{
if (mLayerManager) {
// This layer manager might be used for painting outside of DoDraw(), so we need
// to set the correct rotation on it.
if (mLayerManager->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
ClientLayerManager* manager =
static_cast<ClientLayerManager*>(mLayerManager.get());
manager->SetDefaultTargetConfiguration(mozilla::layers::BufferMode::BUFFER_NONE,
mRotation);
}
return mLayerManager;
}

LOGT();

nsIWidget* topWidget = GetTopLevelWidget();
if (topWidget != this) {
mLayerManager = topWidget->GetLayerManager();
}

// Layer manager can be null here. Sub-class shall handle this.
return mLayerManager;
}

void PuppetWidgetBase::DumpWidgetTree()
{
printf_stderr("PuppetWidgetBase Tree:\n");
Expand Down
8 changes: 8 additions & 0 deletions embedding/embedlite/embedshared/PuppetWidgetBase.h
Expand Up @@ -12,6 +12,10 @@

namespace mozilla {

namespace layers {
class LayerManager;
}

namespace gl {
class GLContext;
}
Expand Down Expand Up @@ -89,6 +93,10 @@ class PuppetWidgetBase : public nsBaseWidget
void UpdateSize();
void SetActive(bool active);

virtual mozilla::layers::LayerManager *GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;

static void DumpWidgetTree();
static void DumpWidgetTree(const nsTArray<PuppetWidgetBase *> &widgets, int indent = 0);
static void LogWidget(PuppetWidgetBase *widget, int index, int indent);
Expand Down
38 changes: 3 additions & 35 deletions embedding/embedlite/embedshared/nsWindow.cpp
Expand Up @@ -201,44 +201,12 @@ nsWindow::GetLayerManager(PLayerTransactionChild *aShadowManager, LayersBackend
}
}

// TODO: Check from nsBaseWidget.

if (mLayerManager) {
// This layer manager might be used for painting outside of DoDraw(), so we need
// to set the correct rotation on it.
if (mLayerManager->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
ClientLayerManager* manager =
static_cast<ClientLayerManager*>(mLayerManager.get());
manager->SetDefaultTargetConfiguration(mozilla::layers::BufferMode::BUFFER_NONE,
mRotation);
}
return mLayerManager;
}

LOGT();

nsIWidget* topWidget = GetTopLevelWidget();
if (topWidget != this) {
mLayerManager = topWidget->GetLayerManager();
}

if (mLayerManager) {
return mLayerManager;
}

if (EmbedLiteApp::GetInstance()->GetType() == EmbedLiteApp::EMBED_INVALID) {
printf("Create Layer Manager for Process View\n");
mLayerManager = new ClientLayerManager(this);
ShadowLayerForwarder* lf = mLayerManager->AsShadowForwarder();
if (!lf->HasShadowManager() && aShadowManager) {
lf->SetShadowManager(aShadowManager);
}
LayerManager *lm = PuppetWidgetBase::GetLayerManager(aShadowManager, aBackendHint, aPersistence);
if (lm) {
mLayerManager = lm;
return mLayerManager;
}

// TODO : We should really split this into Android/Gonk like nsWindow and separate PuppetWidget
// Only Widget hosting window can create compositor.
// Bug: https://bugs.merproject.org/show_bug.cgi?id=1603
if (mWindow && ShouldUseOffMainThreadCompositing()) {
CreateCompositor();
if (mLayerManager) {
Expand Down

0 comments on commit 969274a

Please sign in to comment.