зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1416533 - Skip to generate frame if there is no update r=nical,kats
This commit is contained in:
Родитель
5988aed34a
Коммит
78b2129696
|
@ -904,8 +904,12 @@ CompositorBridgeParent::ScheduleComposition()
|
|||
return;
|
||||
}
|
||||
|
||||
if (mWrBridge) {
|
||||
mWrBridge->ScheduleGenerateFrame();
|
||||
} else {
|
||||
mCompositorScheduler->ScheduleComposition();
|
||||
}
|
||||
}
|
||||
|
||||
// Go down the composite layer tree, setting properties to match their
|
||||
// content-side counterparts.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "CompositableHost.h"
|
||||
#include "gfxEnv.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/WebRenderImageHost.h"
|
||||
#include "mozilla/layers/WebRenderTextureHost.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
|
@ -30,6 +31,7 @@ AsyncImagePipelineManager::AsyncImagePipelineManager(already_AddRefed<wr::WebRen
|
|||
, mIdNamespace(mApi->GetNamespace())
|
||||
, mResourceId(0)
|
||||
, mAsyncImageEpoch(0)
|
||||
, mWillGenerateFrame(false)
|
||||
, mDestroyed(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(AsyncImagePipelineManager);
|
||||
|
@ -48,6 +50,24 @@ AsyncImagePipelineManager::Destroy()
|
|||
mDestroyed = true;
|
||||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::SetWillGenerateFrame()
|
||||
{
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
|
||||
mWillGenerateFrame = true;
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncImagePipelineManager::GetAndResetWillGenerateFrame()
|
||||
{
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
|
||||
bool ret = mWillGenerateFrame;
|
||||
mWillGenerateFrame = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::AddPipeline(const wr::PipelineId& aPipelineId)
|
||||
{
|
||||
|
@ -270,6 +290,11 @@ AsyncImagePipelineManager::ApplyAsyncImages()
|
|||
(pipeline->mIsChanged || op == Some(TextureHost::ADD_IMAGE)) &&
|
||||
!!pipeline->mCurrentTexture;
|
||||
|
||||
// Request to generate frame if there is an update.
|
||||
if (updateDisplayList || !op.isNothing()) {
|
||||
SetWillGenerateFrame();
|
||||
}
|
||||
|
||||
if (!updateDisplayList) {
|
||||
// We don't need to update the display list, either because we can't or because
|
||||
// the previous one is still up to date.
|
||||
|
|
|
@ -91,6 +91,9 @@ public:
|
|||
aNotifications->AppendElements(Move(mImageCompositeNotifications));
|
||||
}
|
||||
|
||||
void SetWillGenerateFrame();
|
||||
bool GetAndResetWillGenerateFrame();
|
||||
|
||||
private:
|
||||
|
||||
uint32_t GetNextResourceId() { return ++mResourceId; }
|
||||
|
@ -168,6 +171,7 @@ private:
|
|||
nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> mPipelineTexturesHolders;
|
||||
nsClassHashtable<nsUint64HashKey, AsyncImagePipeline> mAsyncImagePipelines;
|
||||
uint32_t mAsyncImageEpoch;
|
||||
bool mWillGenerateFrame;
|
||||
bool mDestroyed;
|
||||
|
||||
// Render time for the current composition.
|
||||
|
|
|
@ -612,7 +612,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
|
|||
dlDesc, dl.mData, dl.mLen,
|
||||
resources);
|
||||
|
||||
ScheduleComposition();
|
||||
ScheduleGenerateFrame();
|
||||
|
||||
if (ShouldParentObserveEpoch()) {
|
||||
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
|
||||
|
@ -664,7 +664,7 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
|
|||
if (!aCommands.IsEmpty()) {
|
||||
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
|
||||
ProcessWebRenderParentCommands(aCommands);
|
||||
mCompositorScheduler->ScheduleComposition();
|
||||
ScheduleGenerateFrame();
|
||||
}
|
||||
|
||||
mScrollData.SetFocusTarget(aFocusTarget);
|
||||
|
@ -940,8 +940,8 @@ WebRenderBridgeParent::RecvClearCachedResources()
|
|||
|
||||
// Clear resources
|
||||
mApi->ClearDisplayList(wr::NewEpoch(GetNextWrEpoch()), mPipelineId);
|
||||
// Schedule composition to clean up Pipeline
|
||||
mCompositorScheduler->ScheduleComposition();
|
||||
// Schedule generate frame to clean up Pipeline
|
||||
ScheduleGenerateFrame();
|
||||
// Remove animations.
|
||||
for (std::unordered_set<uint64_t>::iterator iter = mActiveAnimations.begin(); iter != mActiveAnimations.end(); iter++) {
|
||||
mAnimStorage->ClearById(*iter);
|
||||
|
@ -998,7 +998,7 @@ WebRenderBridgeParent::RecvForceComposite()
|
|||
if (mDestroyed) {
|
||||
return IPC_OK();
|
||||
}
|
||||
ScheduleComposition();
|
||||
ScheduleGenerateFrame();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -1189,24 +1189,36 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
|
|||
if (!mForceRendering &&
|
||||
wr::RenderThread::Get()->TooManyPendingFrames(mApi->GetId())) {
|
||||
// Render thread is busy, try next time.
|
||||
ScheduleComposition();
|
||||
mCompositorScheduler->ScheduleComposition();
|
||||
return;
|
||||
}
|
||||
|
||||
bool scheduleComposite = false;
|
||||
nsTArray<wr::WrOpacityProperty> opacityArray;
|
||||
nsTArray<wr::WrTransformProperty> transformArray;
|
||||
|
||||
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
|
||||
mAsyncImageManager->ApplyAsyncImages();
|
||||
|
||||
if (!mAsyncImageManager->GetCompositeUntilTime().IsNull()) {
|
||||
// Trigger another CompositeToTarget() call because there might be another
|
||||
// frame that we want to generate after this one.
|
||||
// It will check if we actually want to generate the frame or not.
|
||||
mCompositorScheduler->ScheduleComposition();
|
||||
}
|
||||
|
||||
if (!mAsyncImageManager->GetAndResetWillGenerateFrame() &&
|
||||
!mForceRendering) {
|
||||
// Could skip generating frame now.
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<wr::WrOpacityProperty> opacityArray;
|
||||
nsTArray<wr::WrTransformProperty> transformArray;
|
||||
|
||||
SampleAnimations(opacityArray, transformArray);
|
||||
if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) {
|
||||
scheduleComposite = true;
|
||||
ScheduleGenerateFrame();
|
||||
}
|
||||
|
||||
if (PushAPZStateToWR(transformArray)) {
|
||||
scheduleComposite = true;
|
||||
ScheduleGenerateFrame();
|
||||
}
|
||||
|
||||
wr::RenderThread::Get()->IncPendingFrameCount(mApi->GetId());
|
||||
|
@ -1221,14 +1233,6 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
|
|||
} else {
|
||||
mApi->GenerateFrame();
|
||||
}
|
||||
|
||||
if (!mAsyncImageManager->GetCompositeUntilTime().IsNull()) {
|
||||
scheduleComposite = true;
|
||||
}
|
||||
|
||||
if (scheduleComposite) {
|
||||
ScheduleComposition();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1302,9 +1306,10 @@ WebRenderBridgeParent::GetLayersId() const
|
|||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::ScheduleComposition()
|
||||
WebRenderBridgeParent::ScheduleGenerateFrame()
|
||||
{
|
||||
if (mCompositorScheduler) {
|
||||
mAsyncImageManager->SetWillGenerateFrame();
|
||||
mCompositorScheduler->ScheduleComposition();
|
||||
}
|
||||
}
|
||||
|
@ -1368,8 +1373,8 @@ WebRenderBridgeParent::ClearResources()
|
|||
|
||||
uint32_t wrEpoch = GetNextWrEpoch();
|
||||
mApi->ClearDisplayList(wr::NewEpoch(wrEpoch), mPipelineId);
|
||||
// Schedule composition to clean up Pipeline
|
||||
mCompositorScheduler->ScheduleComposition();
|
||||
// Schedule generate frame to clean up Pipeline
|
||||
ScheduleGenerateFrame();
|
||||
// WrFontKeys and WrImageKeys are deleted during WebRenderAPI destruction.
|
||||
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
|
||||
iter.Data()->ClearWrBridge();
|
||||
|
|
|
@ -173,7 +173,18 @@ public:
|
|||
|
||||
void FlushRendering(bool aIsSync);
|
||||
|
||||
void ScheduleComposition();
|
||||
/**
|
||||
* Schedule generating WebRender frame definitely at next composite timing.
|
||||
*
|
||||
* WebRenderBridgeParent uses composite timing to check if there is an update
|
||||
* to AsyncImagePipelines. If there is no update, WebRenderBridgeParent skips
|
||||
* to generate frame. If we need to generate new frame at next composite timing,
|
||||
* call this method.
|
||||
*
|
||||
* Call CompositorVsyncScheduler::ScheduleComposition() directly, if we just
|
||||
* want to trigger AsyncImagePipelines update checks.
|
||||
*/
|
||||
void ScheduleGenerateFrame();
|
||||
|
||||
void UpdateWebRender(CompositorVsyncScheduler* aScheduler,
|
||||
wr::WebRenderAPI* aApi,
|
||||
|
|
|
@ -70,8 +70,9 @@ WebRenderImageHost::UseTextureHost(const nsTArray<TimedTexture>& aTextures)
|
|||
mImages.SwapElements(newImages);
|
||||
newImages.Clear();
|
||||
|
||||
if (mWrBridge && GetAsyncRef()) {
|
||||
mWrBridge->ScheduleComposition();
|
||||
if (mWrBridge && mWrBridge->CompositorScheduler() && GetAsyncRef()) {
|
||||
// Will check if we will generate frame.
|
||||
mWrBridge->CompositorScheduler()->ScheduleComposition();
|
||||
}
|
||||
|
||||
// Video producers generally send replacement images with the same frameID but
|
||||
|
|
Загрузка…
Ссылка в новой задаче