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 ++mAsyncImageEpoch; // Update webrender epoch
wr::Epoch epoch = wr::NewEpoch(mAsyncImageEpoch); 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. // We use a pipeline with a very small display list for each video element.
// Update each of them if needed. // Update each of them if needed.
for (auto iter = mAsyncImagePipelines.Iter(); !iter.Done(); iter.Next()) { for (auto iter = mAsyncImagePipelines.Iter(); !iter.Done(); iter.Next()) {
wr::ResourceUpdateQueue resourceUpdates; wr::ResourceUpdateQueue resourceUpdates;
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key()); wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
AsyncImagePipeline* pipeline = iter.Data(); AsyncImagePipeline* pipeline = iter.Data();
nsTArray<wr::ImageKey> keys; nsTArray<wr::ImageKey> keys;
auto op = UpdateImageKeys(resourceUpdates, pipeline, keys); auto op = UpdateImageKeys(resourceUpdates, pipeline, keys);
txn.UpdateResources(resourceUpdates);
bool updateDisplayList = pipeline->mInitialised && bool updateDisplayList = pipeline->mInitialised &&
(pipeline->mIsChanged || op == Some(TextureHost::ADD_IMAGE)) && (pipeline->mIsChanged || op == Some(TextureHost::ADD_IMAGE)) &&
!!pipeline->mCurrentTexture; !!pipeline->mCurrentTexture;
@ -299,7 +309,7 @@ AsyncImagePipelineManager::ApplyAsyncImages()
// We don't need to update the display list, either because we can't or because // We don't need to update the display list, either because we can't or because
// the previous one is still up to date. // the previous one is still up to date.
// We may, however, have updated some resources. // We may, however, have updated some resources.
mApi->UpdatePipelineResources(resourceUpdates, pipelineId, epoch); txn.UpdateEpoch(pipelineId, epoch);
if (pipeline->mCurrentTexture) { if (pipeline->mCurrentTexture) {
HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost()); HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost());
} }
@ -351,11 +361,14 @@ AsyncImagePipelineManager::ApplyAsyncImages()
wr::BuiltDisplayList dl; wr::BuiltDisplayList dl;
wr::LayoutSize builderContentSize; wr::LayoutSize builderContentSize;
builder.Finalize(builderContentSize, dl); builder.Finalize(builderContentSize, dl);
mApi->SetDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f), epoch, LayerSize(pipeline->mScBounds.Width(), pipeline->mScBounds.Height()), txn.SetDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f),
pipelineId, builderContentSize, epoch,
dl.dl_desc, dl.dl, LayerSize(pipeline->mScBounds.Width(), pipeline->mScBounds.Height()),
resourceUpdates); pipelineId, builderContentSize,
dl.dl_desc, dl.dl);
} }
mApi->SendTransaction(txn);
} }
void void

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

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

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

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