Bug 1425453 - Move some WebRender api calls into transactions. r=kats

This commit is contained in:
Nicolas Silva 2018-01-12 12:24:03 +01:00
Родитель e9e30c02c6
Коммит 1595da23b6
3 изменённых файлов: 42 добавлений и 18 удалений

Просмотреть файл

@ -276,16 +276,26 @@ AsyncImagePipelineManager::ApplyAsyncImages()
++mAsyncImageEpoch; // Update webrender epoch
wr::Epoch epoch = wr::NewEpoch(mAsyncImageEpoch);
// TODO: We can improve upon this by using two transactions: one for everything that
// doesn't change the display list (in other words does not cause the scene to be
// re-built), and one for the rest. This way, if an async pipeline needs to re-build
// its display list, other async pipelines can still be rendered while the scene is
// building.
wr::TransactionBuilder txn;
// We use a pipeline with a very small display list for each video element.
// Update each of them if needed.
for (auto iter = mAsyncImagePipelines.Iter(); !iter.Done(); iter.Next()) {
wr::ResourceUpdateQueue resourceUpdates;
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
AsyncImagePipeline* pipeline = iter.Data();
nsTArray<wr::ImageKey> keys;
auto op = UpdateImageKeys(resourceUpdates, pipeline, keys);
txn.UpdateResources(resourceUpdates);
bool updateDisplayList = pipeline->mInitialised &&
(pipeline->mIsChanged || op == Some(TextureHost::ADD_IMAGE)) &&
!!pipeline->mCurrentTexture;
@ -299,7 +309,7 @@ AsyncImagePipelineManager::ApplyAsyncImages()
// We don't need to update the display list, either because we can't or because
// the previous one is still up to date.
// We may, however, have updated some resources.
mApi->UpdatePipelineResources(resourceUpdates, pipelineId, epoch);
txn.UpdateEpoch(pipelineId, epoch);
if (pipeline->mCurrentTexture) {
HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost());
}
@ -351,11 +361,14 @@ AsyncImagePipelineManager::ApplyAsyncImages()
wr::BuiltDisplayList dl;
wr::LayoutSize builderContentSize;
builder.Finalize(builderContentSize, dl);
mApi->SetDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f), epoch, LayerSize(pipeline->mScBounds.Width(), pipeline->mScBounds.Height()),
pipelineId, builderContentSize,
dl.dl_desc, dl.dl,
resourceUpdates);
txn.SetDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f),
epoch,
LayerSize(pipeline->mScBounds.Width(), pipeline->mScBounds.Height()),
pipelineId, builderContentSize,
dl.dl_desc, dl.dl);
}
mApi->SendTransaction(txn);
}
void

Просмотреть файл

@ -603,6 +603,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
uint32_t wrEpoch = GetNextWrEpoch();
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
ProcessWebRenderParentCommands(aCommands);
wr::ResourceUpdateQueue resources;
@ -610,6 +611,8 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
return IPC_FAIL(this, "Failed to deserialize resource updates");
}
wr::TransactionBuilder txn;
txn.UpdateResources(resources);
wr::Vec<uint8_t> dlData(Move(dl));
@ -619,13 +622,14 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
if (mIdNamespace == aIdNamespace) {
if (mWidget) {
LayoutDeviceIntSize size = mWidget->GetClientSize();
mApi->SetWindowParameters(size);
txn.SetWindowParameters(size);
}
gfx::Color clearColor(0.f, 0.f, 0.f, 0.f);
mApi->SetDisplayList(clearColor, wr::NewEpoch(wrEpoch), LayerSize(aSize.width, aSize.height),
mPipelineId, aContentSize,
dlDesc, dlData,
resources);
txn.SetDisplayList(clearColor, wr::NewEpoch(wrEpoch), LayerSize(aSize.width, aSize.height),
mPipelineId, aContentSize,
dlDesc, dlData);
mApi->SendTransaction(txn);
ScheduleGenerateFrame();
@ -686,12 +690,11 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
UpdateAPZ(false);
if (!aCommands.IsEmpty()) {
wr::TransactionBuilder txn;
uint32_t wrEpoch = GetNextWrEpoch();
// Send empty UpdatePipelineResources to WebRender just to notify a new epoch.
// The epoch is used to know a timing of calling DidComposite().
// This is much simpler than tracking an epoch of AsyncImagePipeline.
wr::ResourceUpdateQueue resourceUpdates;
mApi->UpdatePipelineResources(resourceUpdates, mPipelineId, wr::NewEpoch(wrEpoch));
txn.UpdateEpoch(mPipelineId, wr::NewEpoch(wrEpoch));
mApi->SendTransaction(txn);
HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
} else {
bool sendDidComposite = false;
@ -706,6 +709,7 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
mCompositorBridge->DidComposite(wr::AsUint64(mPipelineId), now, now);
}
}
return IPC_OK();
}
@ -1243,11 +1247,15 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
mApi->SetFrameStartTime(startTime);
#endif
wr::TransactionBuilder txn;
if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) {
mApi->GenerateFrame(opacityArray, transformArray);
} else {
mApi->GenerateFrame();
txn.UpdateDynamicProperties(opacityArray, transformArray);
}
txn.GenerateFrame();
mApi->SendTransaction(txn);
}
void

Просмотреть файл

@ -1072,6 +1072,9 @@ pub extern "C" fn wr_api_send_transaction(
dh: &mut DocumentHandle,
transaction: &mut Transaction
) {
if transaction.is_empty() {
return;
}
let txn = mem::replace(transaction, Transaction::new());
dh.api.send_transaction(dh.document_id, txn);
}