Bug 1677929 - Add a way to specify an ID for a generated frame, and propagate the ID to the APZSampler. r=gw,kats
This ID allows the compositor to track per-frame information from frame generation, through APZ sampling, to the NotifyDidRender notification. Differential Revision: https://phabricator.services.mozilla.com/D97535
This commit is contained in:
@@ -57,11 +57,13 @@ class APZSampler {
|
|||||||
*/
|
*/
|
||||||
static void SetSamplerThread(const wr::WrWindowId& aWindowId);
|
static void SetSamplerThread(const wr::WrWindowId& aWindowId);
|
||||||
static void SampleForWebRender(
|
static void SampleForWebRender(
|
||||||
const wr::WrWindowId& aWindowId, wr::Transaction* aTxn,
|
const wr::WrWindowId& aWindowId, const uint64_t* aGeneratedFrameId,
|
||||||
|
wr::Transaction* aTransaction,
|
||||||
const wr::WrPipelineIdEpochs* aEpochsBeingRendered);
|
const wr::WrPipelineIdEpochs* aEpochsBeingRendered);
|
||||||
|
|
||||||
void SetSampleTime(const SampleTime& aSampleTime);
|
void SetSampleTime(const SampleTime& aSampleTime);
|
||||||
void SampleForWebRender(wr::TransactionWrapper& aTxn,
|
void SampleForWebRender(const Maybe<VsyncId>& aGeneratedFrameId,
|
||||||
|
wr::TransactionWrapper& aTxn,
|
||||||
const wr::WrPipelineIdEpochs* aEpochsBeingRendered);
|
const wr::WrPipelineIdEpochs* aEpochsBeingRendered);
|
||||||
|
|
||||||
bool AdvanceAnimations(const SampleTime& aSampleTime);
|
bool AdvanceAnimations(const SampleTime& aSampleTime);
|
||||||
|
|||||||
@@ -706,7 +706,8 @@ void APZCTreeManager::UpdateHitTestingTree(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void APZCTreeManager::SampleForWebRender(
|
void APZCTreeManager::SampleForWebRender(
|
||||||
wr::TransactionWrapper& aTxn, const SampleTime& aSampleTime,
|
const Maybe<VsyncId>& aVsyncId, wr::TransactionWrapper& aTxn,
|
||||||
|
const SampleTime& aSampleTime,
|
||||||
const wr::WrPipelineIdEpochs* aEpochsBeingRendered) {
|
const wr::WrPipelineIdEpochs* aEpochsBeingRendered) {
|
||||||
AssertOnSamplerThread();
|
AssertOnSamplerThread();
|
||||||
MutexAutoLock lock(mMapLock);
|
MutexAutoLock lock(mMapLock);
|
||||||
|
|||||||
@@ -196,7 +196,8 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
|
|||||||
* In effect it is the webrender equivalent of (part of) the code in
|
* In effect it is the webrender equivalent of (part of) the code in
|
||||||
* AsyncCompositionManager.
|
* AsyncCompositionManager.
|
||||||
*/
|
*/
|
||||||
void SampleForWebRender(wr::TransactionWrapper& aTxn,
|
void SampleForWebRender(const Maybe<VsyncId>& aVsyncId,
|
||||||
|
wr::TransactionWrapper& aTxn,
|
||||||
const SampleTime& aSampleTime,
|
const SampleTime& aSampleTime,
|
||||||
const wr::WrPipelineIdEpochs* aEpochsBeingRendered);
|
const wr::WrPipelineIdEpochs* aEpochsBeingRendered);
|
||||||
|
|
||||||
|
|||||||
@@ -66,11 +66,14 @@ void APZSampler::SetSamplerThread(const wr::WrWindowId& aWindowId) {
|
|||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
void APZSampler::SampleForWebRender(
|
void APZSampler::SampleForWebRender(
|
||||||
const wr::WrWindowId& aWindowId, wr::Transaction* aTransaction,
|
const wr::WrWindowId& aWindowId, const uint64_t* aGeneratedFrameId,
|
||||||
|
wr::Transaction* aTransaction,
|
||||||
const wr::WrPipelineIdEpochs* aEpochsBeingRendered) {
|
const wr::WrPipelineIdEpochs* aEpochsBeingRendered) {
|
||||||
if (RefPtr<APZSampler> sampler = GetSampler(aWindowId)) {
|
if (RefPtr<APZSampler> sampler = GetSampler(aWindowId)) {
|
||||||
wr::TransactionWrapper txn(aTransaction);
|
wr::TransactionWrapper txn(aTransaction);
|
||||||
sampler->SampleForWebRender(txn, aEpochsBeingRendered);
|
Maybe<VsyncId> vsyncId =
|
||||||
|
aGeneratedFrameId ? Some(VsyncId{*aGeneratedFrameId}) : Nothing();
|
||||||
|
sampler->SampleForWebRender(vsyncId, txn, aEpochsBeingRendered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +87,7 @@ void APZSampler::SetSampleTime(const SampleTime& aSampleTime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void APZSampler::SampleForWebRender(
|
void APZSampler::SampleForWebRender(
|
||||||
wr::TransactionWrapper& aTxn,
|
const Maybe<VsyncId>& aVsyncId, wr::TransactionWrapper& aTxn,
|
||||||
const wr::WrPipelineIdEpochs* aEpochsBeingRendered) {
|
const wr::WrPipelineIdEpochs* aEpochsBeingRendered) {
|
||||||
AssertOnSamplerThread();
|
AssertOnSamplerThread();
|
||||||
SampleTime sampleTime;
|
SampleTime sampleTime;
|
||||||
@@ -121,7 +124,7 @@ void APZSampler::SampleForWebRender(
|
|||||||
? now
|
? now
|
||||||
: mSampleTime;
|
: mSampleTime;
|
||||||
}
|
}
|
||||||
mApz->SampleForWebRender(aTxn, sampleTime, aEpochsBeingRendered);
|
mApz->SampleForWebRender(aVsyncId, aTxn, sampleTime, aEpochsBeingRendered);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool APZSampler::AdvanceAnimations(const SampleTime& aSampleTime) {
|
bool APZSampler::AdvanceAnimations(const SampleTime& aSampleTime) {
|
||||||
@@ -331,10 +334,11 @@ void apz_register_sampler(mozilla::wr::WrWindowId aWindowId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void apz_sample_transforms(
|
void apz_sample_transforms(
|
||||||
mozilla::wr::WrWindowId aWindowId, mozilla::wr::Transaction* aTransaction,
|
mozilla::wr::WrWindowId aWindowId, const uint64_t* aGeneratedFrameId,
|
||||||
|
mozilla::wr::Transaction* aTransaction,
|
||||||
const mozilla::wr::WrPipelineIdEpochs* aEpochsBeingRendered) {
|
const mozilla::wr::WrPipelineIdEpochs* aEpochsBeingRendered) {
|
||||||
mozilla::layers::APZSampler::SampleForWebRender(aWindowId, aTransaction,
|
mozilla::layers::APZSampler::SampleForWebRender(
|
||||||
aEpochsBeingRendered);
|
aWindowId, aGeneratedFrameId, aTransaction, aEpochsBeingRendered);
|
||||||
}
|
}
|
||||||
|
|
||||||
void apz_deregister_sampler(mozilla::wr::WrWindowId aWindowId) {}
|
void apz_deregister_sampler(mozilla::wr::WrWindowId aWindowId) {}
|
||||||
|
|||||||
@@ -2091,7 +2091,7 @@ void WebRenderBridgeParent::MaybeGenerateFrame(VsyncId aId,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
MOZ_ASSERT(generateFrame);
|
MOZ_ASSERT(generateFrame);
|
||||||
fastTxn.GenerateFrame();
|
fastTxn.GenerateFrame(aId);
|
||||||
mApi->SendTransaction(fastTxn);
|
mApi->SendTransaction(fastTxn);
|
||||||
|
|
||||||
#if defined(MOZ_WIDGET_ANDROID)
|
#if defined(MOZ_WIDGET_ANDROID)
|
||||||
|
|||||||
@@ -252,8 +252,8 @@ void TransactionBuilder::ClearDisplayList(Epoch aEpoch,
|
|||||||
wr_transaction_clear_display_list(mTxn, aEpoch, aPipelineId);
|
wr_transaction_clear_display_list(mTxn, aEpoch, aPipelineId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransactionBuilder::GenerateFrame() {
|
void TransactionBuilder::GenerateFrame(const VsyncId& aVsyncId) {
|
||||||
wr_transaction_generate_frame(mTxn);
|
wr_transaction_generate_frame(mTxn, aVsyncId.mId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransactionBuilder::InvalidateRenderedFrame() {
|
void TransactionBuilder::InvalidateRenderedFrame() {
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class TransactionBuilder final {
|
|||||||
|
|
||||||
void ClearDisplayList(Epoch aEpoch, wr::WrPipelineId aPipeline);
|
void ClearDisplayList(Epoch aEpoch, wr::WrPipelineId aPipeline);
|
||||||
|
|
||||||
void GenerateFrame();
|
void GenerateFrame(const VsyncId& aVsyncId);
|
||||||
|
|
||||||
void InvalidateRenderedFrame();
|
void InvalidateRenderedFrame();
|
||||||
|
|
||||||
|
|||||||
@@ -917,6 +917,7 @@ extern "C" {
|
|||||||
fn apz_register_sampler(window_id: WrWindowId);
|
fn apz_register_sampler(window_id: WrWindowId);
|
||||||
fn apz_sample_transforms(
|
fn apz_sample_transforms(
|
||||||
window_id: WrWindowId,
|
window_id: WrWindowId,
|
||||||
|
generated_frame_id: *const u64,
|
||||||
transaction: &mut Transaction,
|
transaction: &mut Transaction,
|
||||||
epochs_being_rendered: &WrPipelineIdEpochs,
|
epochs_being_rendered: &WrPipelineIdEpochs,
|
||||||
);
|
);
|
||||||
@@ -1014,8 +1015,17 @@ impl AsyncPropertySampler for SamplerCallback {
|
|||||||
fn sample(
|
fn sample(
|
||||||
&self,
|
&self,
|
||||||
_document_id: DocumentId,
|
_document_id: DocumentId,
|
||||||
|
generated_frame_id: Option<u64>,
|
||||||
epochs_being_rendered: &FastHashMap<PipelineId, Epoch>,
|
epochs_being_rendered: &FastHashMap<PipelineId, Epoch>,
|
||||||
) -> Vec<FrameMsg> {
|
) -> Vec<FrameMsg> {
|
||||||
|
let generated_frame_id_value;
|
||||||
|
let generated_frame_id: *const u64 = match generated_frame_id {
|
||||||
|
Some(id) => {
|
||||||
|
generated_frame_id_value = id;
|
||||||
|
&generated_frame_id_value
|
||||||
|
}
|
||||||
|
None => ptr::null_mut(),
|
||||||
|
};
|
||||||
let mut transaction = Transaction::new();
|
let mut transaction = Transaction::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
// XXX: When we implement scroll-linked animations, we will probably
|
// XXX: When we implement scroll-linked animations, we will probably
|
||||||
@@ -1023,6 +1033,7 @@ impl AsyncPropertySampler for SamplerCallback {
|
|||||||
omta_sample(self.window_id, &mut transaction);
|
omta_sample(self.window_id, &mut transaction);
|
||||||
apz_sample_transforms(
|
apz_sample_transforms(
|
||||||
self.window_id,
|
self.window_id,
|
||||||
|
generated_frame_id,
|
||||||
&mut transaction,
|
&mut transaction,
|
||||||
&epochs_being_rendered.iter().map(WrPipelineIdAndEpoch::from).collect(),
|
&epochs_being_rendered.iter().map(WrPipelineIdAndEpoch::from).collect(),
|
||||||
)
|
)
|
||||||
@@ -1823,8 +1834,8 @@ pub extern "C" fn wr_transaction_set_document_view(txn: &mut Transaction, doc_re
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wr_transaction_generate_frame(txn: &mut Transaction) {
|
pub extern "C" fn wr_transaction_generate_frame(txn: &mut Transaction, id: u64) {
|
||||||
txn.generate_frame();
|
txn.generate_frame(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ void apz_deregister_updater(mozilla::wr::WrWindowId aWindowId);
|
|||||||
|
|
||||||
void apz_register_sampler(mozilla::wr::WrWindowId aWindowId);
|
void apz_register_sampler(mozilla::wr::WrWindowId aWindowId);
|
||||||
void apz_sample_transforms(
|
void apz_sample_transforms(
|
||||||
mozilla::wr::WrWindowId aWindowId, mozilla::wr::Transaction* aTransaction,
|
mozilla::wr::WrWindowId aWindowId, const uint64_t* aGeneratedFrameId,
|
||||||
|
mozilla::wr::Transaction* aTransaction,
|
||||||
const mozilla::wr::WrPipelineIdEpochs* aPipelineEpochs);
|
const mozilla::wr::WrPipelineIdEpochs* aPipelineEpochs);
|
||||||
void apz_deregister_sampler(mozilla::wr::WrWindowId aWindowId);
|
void apz_deregister_sampler(mozilla::wr::WrWindowId aWindowId);
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ impl Rectangle {
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
transaction.set_root_pipeline(pipeline_id);
|
transaction.set_root_pipeline(pipeline_id);
|
||||||
transaction.generate_frame();
|
transaction.generate_frame(0);
|
||||||
self.api.send_transaction(self.document_id, transaction);
|
self.api.send_transaction(self.document_id, transaction);
|
||||||
rx.recv().unwrap();
|
rx.recv().unwrap();
|
||||||
let renderer = self.renderer.as_mut().unwrap();
|
let renderer = self.renderer.as_mut().unwrap();
|
||||||
|
|||||||
@@ -417,7 +417,7 @@ fn main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
api.send_transaction(document_id, txn);
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
// Tick the compositor (in this sample, we don't block on UI events)
|
// Tick the compositor (in this sample, we don't block on UI events)
|
||||||
@@ -464,7 +464,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
api.send_transaction(document_id, txn);
|
api.send_transaction(document_id, txn);
|
||||||
current_epoch.0 += 1;
|
current_epoch.0 += 1;
|
||||||
time += 0.001;
|
time += 0.001;
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ impl Example for App {
|
|||||||
colors: vec![],
|
colors: vec![],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
api.send_transaction(document_id, txn);
|
api.send_transaction(document_id, txn);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ impl Example for App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !txn.is_empty() {
|
if !txn.is_empty() {
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
api.send_transaction(document_id, txn);
|
api.send_transaction(document_id, txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ pub fn main_wrapper<E: Example>(
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
txn.set_root_pipeline(pipeline_id);
|
txn.set_root_pipeline(pipeline_id);
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
api.send_transaction(document_id, txn);
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
println!("Entering event loop");
|
println!("Entering event loop");
|
||||||
@@ -312,7 +312,7 @@ pub fn main_wrapper<E: Example>(
|
|||||||
builder.finalize(),
|
builder.finalize(),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
}
|
}
|
||||||
api.send_transaction(document_id, txn);
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ impl Example for App {
|
|||||||
builder.finalize(),
|
builder.finalize(),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
api.send_transaction(doc.id, txn);
|
api.send_transaction(doc.id, txn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ impl Example for App {
|
|||||||
&DirtyRect::All,
|
&DirtyRect::All,
|
||||||
);
|
);
|
||||||
let mut txn = Transaction::new();
|
let mut txn = Transaction::new();
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
api.send_transaction(document_id, txn);
|
api.send_transaction(document_id, txn);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ impl Window {
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
txn.set_root_pipeline(self.pipeline_id);
|
txn.set_root_pipeline(self.pipeline_id);
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
api.send_transaction(self.document_id, txn);
|
api.send_transaction(self.document_id, txn);
|
||||||
|
|
||||||
renderer.update();
|
renderer.update();
|
||||||
|
|||||||
@@ -182,11 +182,11 @@ impl Example for App {
|
|||||||
ExternalScrollId(0, PipelineId::dummy()),
|
ExternalScrollId(0, PipelineId::dummy()),
|
||||||
ScrollClamping::ToContentBounds,
|
ScrollClamping::ToContentBounds,
|
||||||
);
|
);
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
}
|
}
|
||||||
if let Some(zoom) = zoom {
|
if let Some(zoom) = zoom {
|
||||||
txn.set_pinch_zoom(ZoomFactor::new(zoom));
|
txn.set_pinch_zoom(ZoomFactor::new(zoom));
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
winit::WindowEvent::CursorMoved { position: LogicalPosition { x, y }, .. } => {
|
winit::WindowEvent::CursorMoved { position: LogicalPosition { x, y }, .. } => {
|
||||||
@@ -207,7 +207,7 @@ impl Example for App {
|
|||||||
ScrollClamping::ToContentBounds,
|
ScrollClamping::ToContentBounds,
|
||||||
);
|
);
|
||||||
|
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
}
|
}
|
||||||
winit::WindowEvent::MouseInput { .. } => {
|
winit::WindowEvent::MouseInput { .. } => {
|
||||||
let results = api.hit_test(
|
let results = api.hit_test(
|
||||||
|
|||||||
@@ -106,6 +106,38 @@ impl fmt::Debug for ResourceUpdate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether to generate a frame, and if so, an id that allows tracking this
|
||||||
|
/// transaction through the various frame stages.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum GenerateFrame {
|
||||||
|
/// Generate a frame if something changed.
|
||||||
|
Yes {
|
||||||
|
/// An id that allows tracking the frame transaction through the various
|
||||||
|
/// frame stages. Specified by the caller of generate_frame().
|
||||||
|
id: u64,
|
||||||
|
},
|
||||||
|
/// Don't generate a frame even if something has changed.
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenerateFrame {
|
||||||
|
///
|
||||||
|
pub fn as_bool(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
GenerateFrame::Yes { .. } => true,
|
||||||
|
GenerateFrame::No => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the frame ID, if a frame is generated.
|
||||||
|
pub fn id(&self) -> Option<u64> {
|
||||||
|
match self {
|
||||||
|
GenerateFrame::Yes { id } => Some(*id),
|
||||||
|
GenerateFrame::No => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A Transaction is a group of commands to apply atomically to a document.
|
/// A Transaction is a group of commands to apply atomically to a document.
|
||||||
///
|
///
|
||||||
/// This mechanism ensures that:
|
/// This mechanism ensures that:
|
||||||
@@ -127,8 +159,10 @@ pub struct Transaction {
|
|||||||
/// it will be applied directly on the render backend.
|
/// it will be applied directly on the render backend.
|
||||||
use_scene_builder_thread: bool,
|
use_scene_builder_thread: bool,
|
||||||
|
|
||||||
///
|
/// Whether to generate a frame, and if so, an id that allows tracking this
|
||||||
generate_frame: bool,
|
/// transaction through the various frame stages. Specified by the caller of
|
||||||
|
/// generate_frame().
|
||||||
|
generate_frame: GenerateFrame,
|
||||||
|
|
||||||
/// Set to true in order to force re-rendering even if WebRender can't internally
|
/// Set to true in order to force re-rendering even if WebRender can't internally
|
||||||
/// detect that something has changed.
|
/// detect that something has changed.
|
||||||
@@ -146,7 +180,7 @@ impl Transaction {
|
|||||||
resource_updates: Vec::new(),
|
resource_updates: Vec::new(),
|
||||||
notifications: Vec::new(),
|
notifications: Vec::new(),
|
||||||
use_scene_builder_thread: true,
|
use_scene_builder_thread: true,
|
||||||
generate_frame: false,
|
generate_frame: GenerateFrame::No,
|
||||||
invalidate_rendered_frame: false,
|
invalidate_rendered_frame: false,
|
||||||
low_priority: false,
|
low_priority: false,
|
||||||
}
|
}
|
||||||
@@ -171,7 +205,7 @@ impl Transaction {
|
|||||||
|
|
||||||
/// Returns true if the transaction has no effect.
|
/// Returns true if the transaction has no effect.
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
!self.generate_frame &&
|
!self.generate_frame.as_bool() &&
|
||||||
!self.invalidate_rendered_frame &&
|
!self.invalidate_rendered_frame &&
|
||||||
self.scene_ops.is_empty() &&
|
self.scene_ops.is_empty() &&
|
||||||
self.frame_ops.is_empty() &&
|
self.frame_ops.is_empty() &&
|
||||||
@@ -342,8 +376,8 @@ impl Transaction {
|
|||||||
/// as to when happened.
|
/// as to when happened.
|
||||||
///
|
///
|
||||||
/// [notifier]: trait.RenderNotifier.html#tymethod.new_frame_ready
|
/// [notifier]: trait.RenderNotifier.html#tymethod.new_frame_ready
|
||||||
pub fn generate_frame(&mut self) {
|
pub fn generate_frame(&mut self, id: u64) {
|
||||||
self.generate_frame = true;
|
self.generate_frame = GenerateFrame::Yes{ id };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invalidate rendered frame. It ensure that frame will be rendered during
|
/// Invalidate rendered frame. It ensure that frame will be rendered during
|
||||||
@@ -556,7 +590,7 @@ pub struct TransactionMsg {
|
|||||||
/// Updates to resources that persist across display lists.
|
/// Updates to resources that persist across display lists.
|
||||||
pub resource_updates: Vec<ResourceUpdate>,
|
pub resource_updates: Vec<ResourceUpdate>,
|
||||||
/// Whether to trigger frame building and rendering if something has changed.
|
/// Whether to trigger frame building and rendering if something has changed.
|
||||||
pub generate_frame: bool,
|
pub generate_frame: GenerateFrame,
|
||||||
/// Whether to force frame building and rendering even if no changes are internally
|
/// Whether to force frame building and rendering even if no changes are internally
|
||||||
/// observed.
|
/// observed.
|
||||||
pub invalidate_rendered_frame: bool,
|
pub invalidate_rendered_frame: bool,
|
||||||
@@ -579,7 +613,7 @@ pub struct TransactionMsg {
|
|||||||
|
|
||||||
impl fmt::Debug for TransactionMsg {
|
impl fmt::Debug for TransactionMsg {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
writeln!(f, "threaded={}, genframe={}, invalidate={}, low_priority={}",
|
writeln!(f, "threaded={}, genframe={:?}, invalidate={}, low_priority={}",
|
||||||
self.use_scene_builder_thread,
|
self.use_scene_builder_thread,
|
||||||
self.generate_frame,
|
self.generate_frame,
|
||||||
self.invalidate_rendered_frame,
|
self.invalidate_rendered_frame,
|
||||||
@@ -603,7 +637,7 @@ impl fmt::Debug for TransactionMsg {
|
|||||||
impl TransactionMsg {
|
impl TransactionMsg {
|
||||||
/// Returns true if this transaction has no effect.
|
/// Returns true if this transaction has no effect.
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
!self.generate_frame &&
|
!self.generate_frame.as_bool() &&
|
||||||
!self.invalidate_rendered_frame &&
|
!self.invalidate_rendered_frame &&
|
||||||
self.scene_ops.is_empty() &&
|
self.scene_ops.is_empty() &&
|
||||||
self.frame_ops.is_empty() &&
|
self.frame_ops.is_empty() &&
|
||||||
@@ -1230,7 +1264,7 @@ impl RenderApi {
|
|||||||
frame_ops: vec![msg],
|
frame_ops: vec![msg],
|
||||||
resource_updates: Vec::new(),
|
resource_updates: Vec::new(),
|
||||||
notifications: Vec::new(),
|
notifications: Vec::new(),
|
||||||
generate_frame: false,
|
generate_frame: GenerateFrame::No,
|
||||||
invalidate_rendered_frame: false,
|
invalidate_rendered_frame: false,
|
||||||
use_scene_builder_thread: false,
|
use_scene_builder_thread: false,
|
||||||
low_priority: false,
|
low_priority: false,
|
||||||
@@ -1249,7 +1283,7 @@ impl RenderApi {
|
|||||||
frame_ops: Vec::new(),
|
frame_ops: Vec::new(),
|
||||||
resource_updates: Vec::new(),
|
resource_updates: Vec::new(),
|
||||||
notifications: Vec::new(),
|
notifications: Vec::new(),
|
||||||
generate_frame: false,
|
generate_frame: GenerateFrame::No,
|
||||||
invalidate_rendered_frame: false,
|
invalidate_rendered_frame: false,
|
||||||
use_scene_builder_thread: false,
|
use_scene_builder_thread: false,
|
||||||
low_priority: false,
|
low_priority: false,
|
||||||
@@ -1287,7 +1321,7 @@ impl RenderApi {
|
|||||||
self.resources.update(&mut transaction);
|
self.resources.update(&mut transaction);
|
||||||
|
|
||||||
transaction.use_scene_builder_thread |= !transaction.scene_ops.is_empty();
|
transaction.use_scene_builder_thread |= !transaction.scene_ops.is_empty();
|
||||||
if transaction.generate_frame {
|
if transaction.generate_frame.as_bool() {
|
||||||
transaction.profile.start_time(profiler::API_SEND_TIME);
|
transaction.profile.start_time(profiler::API_SEND_TIME);
|
||||||
transaction.profile.start_time(profiler::TOTAL_FRAME_CPU_TIME);
|
transaction.profile.start_time(profiler::TOTAL_FRAME_CPU_TIME);
|
||||||
}
|
}
|
||||||
@@ -1312,7 +1346,7 @@ impl RenderApi {
|
|||||||
.map(|(txn, id)| {
|
.map(|(txn, id)| {
|
||||||
let mut txn = txn.finalize(id);
|
let mut txn = txn.finalize(id);
|
||||||
self.resources.update(&mut txn);
|
self.resources.update(&mut txn);
|
||||||
if txn.generate_frame {
|
if txn.generate_frame.as_bool() {
|
||||||
txn.profile.start_time(profiler::API_SEND_TIME);
|
txn.profile.start_time(profiler::API_SEND_TIME);
|
||||||
txn.profile.start_time(profiler::TOTAL_FRAME_CPU_TIME);
|
txn.profile.start_time(profiler::TOTAL_FRAME_CPU_TIME);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1010,6 +1010,7 @@ impl RenderBackend {
|
|||||||
txn.frame_ops.take(),
|
txn.frame_ops.take(),
|
||||||
txn.notifications.take(),
|
txn.notifications.take(),
|
||||||
txn.render_frame,
|
txn.render_frame,
|
||||||
|
None,
|
||||||
txn.invalidate_rendered_frame,
|
txn.invalidate_rendered_frame,
|
||||||
frame_counter,
|
frame_counter,
|
||||||
has_built_scene,
|
has_built_scene,
|
||||||
@@ -1347,7 +1348,7 @@ impl RenderBackend {
|
|||||||
|
|
||||||
let mut built_frame = false;
|
let mut built_frame = false;
|
||||||
for mut txn in txns {
|
for mut txn in txns {
|
||||||
if txn.generate_frame {
|
if txn.generate_frame.as_bool() {
|
||||||
txn.profile.end_time(profiler::API_SEND_TIME);
|
txn.profile.end_time(profiler::API_SEND_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1358,7 +1359,8 @@ impl RenderBackend {
|
|||||||
txn.resource_updates.take(),
|
txn.resource_updates.take(),
|
||||||
txn.frame_ops.take(),
|
txn.frame_ops.take(),
|
||||||
txn.notifications.take(),
|
txn.notifications.take(),
|
||||||
txn.generate_frame,
|
txn.generate_frame.as_bool(),
|
||||||
|
txn.generate_frame.id(),
|
||||||
txn.invalidate_rendered_frame,
|
txn.invalidate_rendered_frame,
|
||||||
frame_counter,
|
frame_counter,
|
||||||
false
|
false
|
||||||
@@ -1395,6 +1397,7 @@ impl RenderBackend {
|
|||||||
Vec::default(),
|
Vec::default(),
|
||||||
Vec::default(),
|
Vec::default(),
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
false,
|
false,
|
||||||
frame_counter,
|
frame_counter,
|
||||||
false);
|
false);
|
||||||
@@ -1414,6 +1417,7 @@ impl RenderBackend {
|
|||||||
mut frame_ops: Vec<FrameMsg>,
|
mut frame_ops: Vec<FrameMsg>,
|
||||||
mut notifications: Vec<NotificationRequest>,
|
mut notifications: Vec<NotificationRequest>,
|
||||||
mut render_frame: bool,
|
mut render_frame: bool,
|
||||||
|
generated_frame_id: Option<u64>,
|
||||||
invalidate_rendered_frame: bool,
|
invalidate_rendered_frame: bool,
|
||||||
frame_counter: &mut u32,
|
frame_counter: &mut u32,
|
||||||
has_built_scene: bool,
|
has_built_scene: bool,
|
||||||
@@ -1430,7 +1434,7 @@ impl RenderBackend {
|
|||||||
// async transforms.
|
// async transforms.
|
||||||
if requested_frame || has_built_scene {
|
if requested_frame || has_built_scene {
|
||||||
if let Some(ref sampler) = self.sampler {
|
if let Some(ref sampler) = self.sampler {
|
||||||
frame_ops.append(&mut sampler.sample(document_id,
|
frame_ops.append(&mut sampler.sample(document_id, generated_frame_id,
|
||||||
&doc.scene.pipeline_epochs));
|
&doc.scene.pipeline_epochs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6907,7 +6907,7 @@ pub trait AsyncPropertySampler {
|
|||||||
/// This is called for each transaction with the generate_frame flag set
|
/// This is called for each transaction with the generate_frame flag set
|
||||||
/// (i.e. that will trigger a render). The list of frame messages returned
|
/// (i.e. that will trigger a render). The list of frame messages returned
|
||||||
/// are processed as though they were part of the original transaction.
|
/// are processed as though they were part of the original transaction.
|
||||||
fn sample(&self, document_id: DocumentId,
|
fn sample(&self, document_id: DocumentId, generated_frame_id: Option<u64>,
|
||||||
doc: &FastHashMap<PipelineId, Epoch>) -> Vec<FrameMsg>;
|
doc: &FastHashMap<PipelineId, Epoch>) -> Vec<FrameMsg>;
|
||||||
/// This is called exactly once, when the render backend thread is about to
|
/// This is called exactly once, when the render backend thread is about to
|
||||||
/// terminate.
|
/// terminate.
|
||||||
|
|||||||
@@ -687,7 +687,7 @@ impl SceneBuilderThread {
|
|||||||
|
|
||||||
Box::new(BuiltTransaction {
|
Box::new(BuiltTransaction {
|
||||||
document_id: txn.document_id,
|
document_id: txn.document_id,
|
||||||
render_frame: txn.generate_frame,
|
render_frame: txn.generate_frame.as_bool(),
|
||||||
invalidate_rendered_frame: txn.invalidate_rendered_frame,
|
invalidate_rendered_frame: txn.invalidate_rendered_frame,
|
||||||
built_scene,
|
built_scene,
|
||||||
view: doc.view,
|
view: doc.view,
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ impl<'a> RawtestHarness<'a> {
|
|||||||
);
|
);
|
||||||
epoch.0 += 1;
|
epoch.0 += 1;
|
||||||
|
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
self.wrench.api.send_transaction(self.wrench.document_id, txn);
|
self.wrench.api.send_transaction(self.wrench.document_id, txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1239,7 +1239,7 @@ impl<'a> RawtestHarness<'a> {
|
|||||||
builder.finalize(),
|
builder.finalize(),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
|
|
||||||
self.wrench.api.send_transaction(self.wrench.document_id, txn);
|
self.wrench.api.send_transaction(self.wrench.document_id, txn);
|
||||||
|
|
||||||
@@ -1274,7 +1274,7 @@ impl<'a> RawtestHarness<'a> {
|
|||||||
// 6. rebuild the scene and compare again
|
// 6. rebuild the scene and compare again
|
||||||
let mut txn = Transaction::new();
|
let mut txn = Transaction::new();
|
||||||
txn.set_root_pipeline(captured.root_pipeline_id.unwrap());
|
txn.set_root_pipeline(captured.root_pipeline_id.unwrap());
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
self.wrench.api.send_transaction(captured.document_id, txn);
|
self.wrench.api.send_transaction(captured.document_id, txn);
|
||||||
let pixels2 = self.render_and_get_pixels(window_rect);
|
let pixels2 = self.render_and_get_pixels(window_rect);
|
||||||
self.compare_pixels(pixels0, pixels2, window_rect.size);
|
self.compare_pixels(pixels0, pixels2, window_rect.size);
|
||||||
@@ -1305,7 +1305,7 @@ impl<'a> RawtestHarness<'a> {
|
|||||||
builder.finalize(),
|
builder.finalize(),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
self.wrench.api.send_transaction(doc_id, txn);
|
self.wrench.api.send_transaction(doc_id, txn);
|
||||||
|
|
||||||
// Ensure we get a notification from rendering the above, even though
|
// Ensure we get a notification from rendering the above, even though
|
||||||
|
|||||||
@@ -606,7 +606,7 @@ impl Wrench {
|
|||||||
txn.scroll_node_with_id(*offset, *id, ScrollClamping::NoClamping);
|
txn.scroll_node_with_id(*offset, *id, ScrollClamping::NoClamping);
|
||||||
}
|
}
|
||||||
|
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
self.api.send_transaction(self.document_id, txn);
|
self.api.send_transaction(self.document_id, txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,7 +627,7 @@ impl Wrench {
|
|||||||
pub fn refresh(&mut self) {
|
pub fn refresh(&mut self) {
|
||||||
self.begin_frame();
|
self.begin_frame();
|
||||||
let mut txn = Transaction::new();
|
let mut txn = Transaction::new();
|
||||||
txn.generate_frame();
|
txn.generate_frame(0);
|
||||||
self.api.send_transaction(self.document_id, txn);
|
self.api.send_transaction(self.document_id, txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user