CompositorParent::CompositorParent(nsIWidget* aWidget, bool aUseExternalSurfaceSize, int aSurfaceWidth, int aSurfaceHeight) : mWidget(aWidget) , mCurrentCompositeTask(nullptr) , mIsTesting(false) , mPendingTransaction(0) , mPaused(false) , mUseExternalSurfaceSize(aUseExternalSurfaceSize) , mEGLSurfaceSize(aSurfaceWidth, aSurfaceHeight) , mPauseCompositionMonitor("PauseCompositionMonitor") , mResumeCompositionMonitor("ResumeCompositionMonitor") , mOverrideComposeReadiness(false) , mForceCompositionTask(nullptr) { MOZ_ASSERT(sCompositorThread != nullptr, "The compositor thread must be Initialized before instanciating a CmpositorParent."); MOZ_COUNT_CTOR(CompositorParent); mCompositorID = 0; // FIXME: This holds on the the fact that right now the only thing that // can destroy this instance is initialized on the compositor thread after // this task has been processed. CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(&AddCompositor, this, &mCompositorID)); CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(SetThreadPriority)); mRootLayerTreeID = AllocateLayerTreeId(); sIndirectLayerTrees[mRootLayerTreeID].mParent = this; mApzcTreeManager = new APZCTreeManager(); ++sCompositorThreadRefCount; }
void CompositorParent::ScheduleResumeOnCompositorThread(int width, int height) { CancelableTask *resumeTask = NewRunnableMethod(this, &CompositorParent::ResumeCompositionAndResize, width, height); CompositorLoop()->PostTask(FROM_HERE, resumeTask); }
void CompositorParent::SchedulePauseOnCompositorThread() { CancelableTask *pauseTask = NewRunnableMethod(this, &CompositorParent::PauseComposition); CompositorLoop()->PostTask(FROM_HERE, pauseTask); }
/*static*/ uint64_t CompositorParent::AllocateLayerTreeId() { MOZ_ASSERT(CompositorLoop()); MOZ_ASSERT(NS_IsMainThread()); static uint64_t ids = 0; return ++ids; }
/*static*/ void CompositorParent::DeallocateLayerTreeId(uint64_t aId) { MOZ_ASSERT(NS_IsMainThread()); // Here main thread notifies compositor to remove an element from // sIndirectLayerTrees. This removed element might be queried soon. // Checking the elements of sIndirectLayerTrees exist or not before using. CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(&EraseLayerState, aId)); }
/*static*/ void CompositorParent::SetControllerForLayerTree(uint64_t aLayersId, GeckoContentController* aController) { // This ref is adopted by UpdateControllerForLayersId(). aController->AddRef(); CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(&UpdateControllerForLayersId, aLayersId, aController)); }
/* * This will execute a pause synchronously, waiting to make sure that the compositor * really is paused. */ void CompositorParent::SchedulePauseOnCompositorThread() { MonitorAutoLock lock(mPauseCompositionMonitor); CancelableTask *pauseTask = NewRunnableMethod(this, &CompositorParent::PauseComposition); CompositorLoop()->PostTask(FROM_HERE, pauseTask); // Wait until the pause has actually been processed by the compositor thread lock.Wait(); }
void CompositorParent::ScheduleResumeOnCompositorThread(int width, int height) { mozilla::MonitorAutoLock lock(mResumeCompositionMonitor); CancelableTask *resumeTask = NewRunnableMethod(this, &CompositorParent::ResumeCompositionAndResize, width, height); CompositorLoop()->PostTask(FROM_HERE, resumeTask); // Wait until the resume has actually been processed by the compositor thread lock.Wait(); }
bool CompositorParent::RecvStop() { Destroy(); // There are chances that the ref count reaches zero on the main thread shortly // after this function returns while some ipdl code still needs to run on // this thread. // We must keep the compositor parent alive untill the code handling message // reception is finished on this thread. this->AddRef(); // Corresponds to DeferredDeleteCompositorParent's Release CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(&DeferredDeleteCompositorParent, this)); return true; }
/*static*/ PCompositorParent* CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess) { nsRefPtr<CrossProcessCompositorParent> cpcp = new CrossProcessCompositorParent(aTransport, aOtherProcess); ProcessHandle handle; if (!base::OpenProcessHandle(aOtherProcess, &handle)) { // XXX need to kill |aOtherProcess|, it's boned return nullptr; } cpcp->mSelfRef = cpcp; CompositorLoop()->PostTask( FROM_HERE, NewRunnableFunction(OpenCompositor, cpcp.get(), aTransport, handle, XRE_GetIOMessageLoop())); // The return value is just compared to null for success checking, // we're not sharing a ref. return cpcp.get(); }
void CompositorParent::ScheduleRenderOnCompositorThread() { CancelableTask *renderTask = NewRunnableMethod(this, &CompositorParent::ScheduleComposition); CompositorLoop()->PostTask(FROM_HERE, renderTask); }