Skip to content

Commit

Permalink
Attempt to rewrite Compositor using simple interface approach and alw…
Browse files Browse the repository at this point in the history
…ays in offscreen mode
  • Loading branch information
tmeshkova committed May 23, 2014
1 parent 424c45c commit 171f479
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 166 deletions.
2 changes: 0 additions & 2 deletions embedding/embedlite/EmbedLiteView.cpp
Expand Up @@ -314,8 +314,6 @@ EmbedLiteView::SetViewClipping(float aX, float aY, float aWidth, float aHeight)
void
EmbedLiteView::SetViewOpacity(float aOpacity)
{
NS_ENSURE_TRUE(mViewImpl, );
mViewImpl->SetViewOpacity(aOpacity);
}

void
Expand Down
1 change: 0 additions & 1 deletion embedding/embedlite/embedhelpers/EmbedLiteViewImplIface.h
Expand Up @@ -42,7 +42,6 @@ class EmbedLiteViewImplIface
virtual void SetGLViewPortSize(int width, int height) {}
virtual void SetGLViewTransform(gfx::Matrix matrix) {}
virtual void SetViewClipping(const gfxRect& aClipRect) {}
virtual void SetViewOpacity(const float aOpacity) {}
virtual void SetTransformation(float aScale, nsIntPoint aScrollOffset) {}
virtual void ScheduleRender() {}
virtual void SetClipping(nsIntRect aClipRect) {}
Expand Down
162 changes: 50 additions & 112 deletions embedding/embedlite/embedthread/EmbedLiteCompositorParent.cpp
Expand Up @@ -36,14 +36,14 @@ EmbedLiteCompositorParent::EmbedLiteCompositorParent(nsIWidget* aWidget,
int aSurfaceWidth,
int aSurfaceHeight,
uint32_t id)
: CompositorParent(aWidget, aRenderToEGLSurface, aSurfaceWidth, aSurfaceHeight)
, mId(id)
: mId(id)
, mCurrentCompositeTask(nullptr)
, mWorldOpacity(1.0f)
, mLastViewSize(aSurfaceWidth, aSurfaceHeight)
, mInitialPaintCount(0)
{
AddRef();
mCompositor = new CompositorParent(aWidget, aRenderToEGLSurface, aSurfaceWidth, aSurfaceHeight);
mCompositor->SetCompositorInterface(this);
EmbedLiteView* view = EmbedLiteApp::GetInstance()->GetViewByID(mId);
LOGT("this:%p, view:%p", this, view);
MOZ_ASSERT(view, "Something went wrong, Compositor not suspended on destroy?");
Expand All @@ -57,29 +57,20 @@ EmbedLiteCompositorParent::~EmbedLiteCompositorParent()
EmbedLiteApp::GetInstance()->ViewDestroyed(mId);
}

PLayerTransactionParent*
EmbedLiteCompositorParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
const uint64_t& aId,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
bool *aSuccess)
void
EmbedLiteCompositorParent::Created()
{
EmbedLiteView* view = EmbedLiteApp::GetInstance()->GetViewByID(mId);
EmbedLiteViewListener* listener = view ? view->GetListener() : nullptr;
if (listener) {
listener->CompositorCreated();
}

PLayerTransactionParent* parent =
CompositorParent::AllocPLayerTransactionParent(aBackendHints,
aId,
aTextureFactoryIdentifier,
aSuccess);

const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(RootLayerTreeId());
NS_ENSURE_TRUE(state && state->mLayerManager, parent);
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(mCompositor->RootLayerTreeId());
NS_ENSURE_TRUE(state && state->mLayerManager, );

GLContext* context = static_cast<CompositorOGL*>(state->mLayerManager->GetCompositor())->gl();
NS_ENSURE_TRUE(context, parent);
NS_ENSURE_TRUE(context, );

if (context->IsOffscreen()) {
GLScreenBuffer* screen = context->Screen();
Expand All @@ -101,62 +92,75 @@ EmbedLiteCompositorParent::AllocPLayerTransactionParent(const nsTArray<LayersBac
}
}
}

return parent;
}

bool
EmbedLiteCompositorParent::IsGLBackend()
EmbedLiteCompositorParent::Invalidate()
{
return EmbedLiteApp::GetInstance()->IsAccelerated();
LOGF();
EmbedLiteView* view = EmbedLiteApp::GetInstance()->GetViewByID(mId);
if (!view) {
LOGE("view not available.. forgot SuspendComposition call?");
return false;
}

const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(mCompositor->RootLayerTreeId());
NS_ENSURE_TRUE(state && state->mLayerManager, false);

GLContext* context = static_cast<CompositorOGL*>(state->mLayerManager->GetCompositor())->gl();
NS_ENSURE_TRUE(context, false);

state->mLayerManager->SetWorldTransform(mWorldTransform);

if (!mActiveClipping.IsEmpty() && state->mLayerManager->GetRoot()) {
state->mLayerManager->GetRoot()->SetClipRect(&mActiveClipping);
}

if (context->IsOffscreen() && context->OffscreenSize() != mLastViewSize) {
context->ResizeOffscreen(gfx::IntSize(mLastViewSize.width, mLastViewSize.height));
mCompositor->ScheduleRenderOnCompositorThread();
}

if (!view->GetListener()->Invalidate()) {
mCurrentCompositeTask = NewRunnableMethod(this, &EmbedLiteCompositorParent::RenderGL);
MessageLoop::current()->PostDelayedTask(FROM_HERE, mCurrentCompositeTask, 16);
}

return true;
}

bool EmbedLiteCompositorParent::RenderToContext(gfx::DrawTarget* aTarget)
{
LOGF();
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(RootLayerTreeId());
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(mCompositor->RootLayerTreeId());

NS_ENSURE_TRUE(state->mLayerManager, false);
if (!state->mLayerManager->GetRoot()) {
// Nothing to paint yet, just return silently
return false;
}
CompositeToTarget(aTarget);
mCompositor->CompositeToTarget(aTarget);
return true;
}

bool EmbedLiteCompositorParent::RenderGL()
{
LOGF();

mCurrentCompositeTask = nullptr;

bool retval = true;
NS_ENSURE_TRUE(IsGLBackend(), false);
if (mCurrentCompositeTask) {
mCurrentCompositeTask->Cancel();
mCurrentCompositeTask = nullptr;
}

const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(RootLayerTreeId());
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(mCompositor->RootLayerTreeId());
NS_ENSURE_TRUE(state && state->mLayerManager, false);

GLContext* context = static_cast<CompositorOGL*>(state->mLayerManager->GetCompositor())->gl();
NS_ENSURE_TRUE(context, false);

state->mLayerManager->SetWorldTransform(mWorldTransform);
state->mLayerManager->GetCompositor()->SetWorldOpacity(mWorldOpacity);

if (!mActiveClipping.IsEmpty() && state->mLayerManager->GetRoot()) {
state->mLayerManager->GetRoot()->SetClipRect(&mActiveClipping);
}

if (context->IsOffscreen() && context->OffscreenSize() != mLastViewSize) {
context->ResizeOffscreen(gfx::IntSize(mLastViewSize.width, mLastViewSize.height));
ScheduleRenderOnCompositorThread();
}

{
ScopedScissorRect autoScissor(context);
GLenum oldTexUnit;
context->GetUIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &oldTexUnit);
CompositorParent::Composite();
mCompositor->CompositeToTarget(nullptr);
context->fActiveTexture(oldTexUnit);
}

Expand All @@ -166,7 +170,7 @@ bool EmbedLiteCompositorParent::RenderGL()
}
// Temporary hack, we need two extra paints in order to get initial picture
if (mInitialPaintCount < 2) {
ScheduleRenderOnCompositorThread();
mCompositor->ScheduleRenderOnCompositorThread();
mInitialPaintCount++;
}
}
Expand All @@ -176,91 +180,25 @@ bool EmbedLiteCompositorParent::RenderGL()
view->GetListener()->CompositingFinished();
}

return retval;
}

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

void EmbedLiteCompositorParent::SetSurfaceSize(int width, int height)
{
NS_ENSURE_TRUE(IsGLBackend(),);
mLastViewSize.SizeTo(width, height);
CompositorParent::SetEGLSurfaceSize(width, height);
mCompositor->SetEGLSurfaceSize(width, height);
}

void EmbedLiteCompositorParent::SetWorldTransform(gfx::Matrix aMatrix)
{
mWorldTransform = aMatrix;
}

void EmbedLiteCompositorParent::SetWorldOpacity(float aOpacity)
{
mWorldOpacity = aOpacity;
}

void EmbedLiteCompositorParent::SetClipping(const gfxRect& aClipRect)
{
gfxUtils::GfxRectToIntRect(aClipRect, &mActiveClipping);
}

void EmbedLiteCompositorParent::DeferredDestroyCompositor()
{
if (GetChildCompositor()) {
// First iteration, if child compositor available
// Destroy it from current Child Message Loop and
// Post task for Parent Compositor destroy in Parent MessageLoop
NS_ASSERTION(MessageLoop::current() != EmbedLiteApp::GetInstance()->GetUILoop(),
"CompositorChild must be destroyed from Child Message Loop");
GetChildCompositor()->Release();
SetChildCompositor(nullptr, nullptr);
EmbedLiteApp::GetInstance()->GetUILoop()->PostTask(FROM_HERE,
NewRunnableMethod(this, &EmbedLiteCompositorParent::DeferredDestroyCompositor));
} else {
NS_ASSERTION(MessageLoop::current() == EmbedLiteApp::GetInstance()->GetUILoop(),
"CompositorParent must be destroyed from Parent Message Loop");
// Finally destroy Parent compositor
Release();
}
}

void
EmbedLiteCompositorParent::SetChildCompositor(CompositorChild* aCompositorChild, MessageLoop* childLoop)
{
LOGT();
mChildMessageLoop = childLoop;
mChildCompositor = aCompositorChild;
}

bool EmbedLiteCompositorParent::RecvStop()
{
LOGT("t: childComp:%p, mChildMessageLoop:%p, curLoop:%p", mChildCompositor.get(), MessageLoop::current());
Destroy();
// Delegate destroy of Child/Parent compositor in delayed task in order to avoid Child loop having dead objects
mChildMessageLoop->PostTask(FROM_HERE,
NewRunnableMethod(this, &EmbedLiteCompositorParent::DeferredDestroyCompositor));
return true;
}

void EmbedLiteCompositorParent::ScheduleTask(CancelableTask* task, int time)
{
LOGF();
EmbedLiteView* view = EmbedLiteApp::GetInstance()->GetViewByID(mId);
if (!view) {
LOGE("view not available.. forgot SuspendComposition call?");
return;
}
task->Cancel();
if (!view->GetListener()->Invalidate()) {
mCurrentCompositeTask = NewRunnableMethod(this, &EmbedLiteCompositorParent::RenderGL);
CompositorParent::ScheduleTask(mCurrentCompositeTask, time);
}
}

} // namespace embedlite
} // namespace mozilla

32 changes: 7 additions & 25 deletions embedding/embedlite/embedthread/EmbedLiteCompositorParent.h
Expand Up @@ -14,12 +14,9 @@
#include "EmbedLiteViewThreadParent.h"

namespace mozilla {
namespace layers {
class CompositingRenderTarget;
}
namespace embedlite {

class EmbedLiteCompositorParent : public mozilla::layers::CompositorParent
class EmbedLiteCompositorParent : public mozilla::layers::ICompositorListener
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(EmbedLiteCompositorParent)
public:
Expand All @@ -36,34 +33,19 @@ class EmbedLiteCompositorParent : public mozilla::layers::CompositorParent
void SetClipping(const gfxRect& aClipRect);
void SetWorldOpacity(float aOpacity);

virtual bool RecvStop() MOZ_OVERRIDE;
virtual void SetChildCompositor(mozilla::layers::CompositorChild*, MessageLoop*);
mozilla::layers::CompositorChild* GetChildCompositor() {
return mChildCompositor;
}
virtual bool RequestHasHWAcceleratedContext();
protected:
virtual PLayerTransactionParent*
AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
const uint64_t& aId,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
bool* aSuccess);

virtual void ScheduleTask(CancelableTask*, int);
virtual void Created();
virtual bool Invalidate();

void DeferredDestroyCompositor();
mozilla::layers::CompositorParent* Compositor() { return mCompositor.get(); }

bool IsGLBackend();

RefPtr<mozilla::layers::CompositorChild> mChildCompositor;
MessageLoop* mChildMessageLoop;
protected:
uint32_t mId;
gfx::Matrix mWorldTransform;
nsIntRect mActiveClipping;
CancelableTask *mCurrentCompositeTask;
float mWorldOpacity;
CancelableTask* mCurrentCompositeTask;
gfx::IntSize mLastViewSize;
short mInitialPaintCount;
RefPtr<mozilla::layers::CompositorParent> mCompositor;
};

} // embedlite
Expand Down
8 changes: 3 additions & 5 deletions embedding/embedlite/embedthread/EmbedLitePuppetWidget.cpp
Expand Up @@ -514,7 +514,8 @@ CompositorParent*
EmbedLitePuppetWidget::NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight)
{
gfxPlatform::GetPlatform();
return new EmbedLiteCompositorParent(this, true, aSurfaceWidth, aSurfaceHeight, mId);
mCompositorWrapper = new EmbedLiteCompositorParent(this, true, aSurfaceWidth, aSurfaceHeight, mId);
return mCompositorWrapper->Compositor();
}

void EmbedLitePuppetWidget::CreateCompositor()
Expand Down Expand Up @@ -543,7 +544,6 @@ void EmbedLitePuppetWidget::CreateCompositor(int aWidth, int aHeight)
ClientLayerManager* lm = new ClientLayerManager(this);
MessageLoop* childMessageLoop = CompositorParent::CompositorLoop();
mCompositorChild = new CompositorChild(lm);
static_cast<EmbedLiteCompositorParent*>(mCompositorParent.get())->SetChildCompositor(mCompositorChild, MessageLoop::current());
mCompositorChild->Open(parentChannel, childMessageLoop, ipc::ChildSide);

TextureFactoryIdentifier textureFactoryIdentifier;
Expand Down Expand Up @@ -591,9 +591,7 @@ EmbedLitePuppetWidget::GetNaturalBounds()
bool
EmbedLitePuppetWidget::HasGLContext()
{
EmbedLiteCompositorParent* parent =
static_cast<EmbedLiteCompositorParent*>(mCompositorParent.get());
return parent->RequestHasHWAcceleratedContext();
return true;
}

} // namespace widget
Expand Down
1 change: 1 addition & 0 deletions embedding/embedlite/embedthread/EmbedLitePuppetWidget.h
Expand Up @@ -174,6 +174,7 @@ class EmbedLitePuppetWidget : public nsBaseWidget,
nsCOMPtr<nsIWidget> mParent;

uint32_t mId;
RefPtr<EmbedLiteCompositorParent> mCompositorWrapper;
};

} // namespace widget
Expand Down
2 changes: 0 additions & 2 deletions embedding/embedlite/embedthread/EmbedLiteViewThreadChild.h
Expand Up @@ -107,8 +107,6 @@ class EmbedLiteViewThreadChild : public PEmbedLiteViewChild,
const nsAString& aData);
virtual bool RecvSetGLViewSize(const gfxSize&);

void RequestHasHWAcceleratedContextLooped();

virtual bool
RecvAddMessageListeners(const InfallibleTArray<nsString>& messageNames);

Expand Down

0 comments on commit 171f479

Please sign in to comment.