mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 00:08:39 +09:00
Issue #21 - Remove panning/tab animation performance measurements
Based on FranklinDM's follow-up for the issue. This would require browser FE changes, particularly removing the associated code in `tabbrowser.xml`, however, that was already done in Pale Moon previously. Other front-end applications may need to take note, though. Based on changes from the following bugs: * Bug 696398 - Need an api to analyze panning performance * Bug 800031 - Include paint time in tab switch telemetry * Bug 820167 - Enable performance measurement of tab animation * Bug 826383 - Improve Start/Stop FrameTimeRecording for telemetry usage
This commit is contained in:
parent
1ae5f60a1b
commit
2e944692c3
14 changed files with 1 additions and 344 deletions
|
|
@ -2367,75 +2367,6 @@ nsDOMWindowUtils::GetCurrentAudioBackend(nsAString& aBackend)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(startIndex);
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LayerManager *mgr = widget->GetLayerManager();
|
||||
if (!mgr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
|
||||
const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
|
||||
uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
|
||||
bufferSize = std::min(bufferSize, kRecordingMaxSize);
|
||||
bufferSize = std::max(bufferSize, kRecordingMinSize);
|
||||
*startIndex = mgr->StartFrameTimeRecording(bufferSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::StopFrameTimeRecording(uint32_t startIndex,
|
||||
uint32_t *frameCount,
|
||||
float **frameIntervals)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(frameCount);
|
||||
NS_ENSURE_ARG_POINTER(frameIntervals);
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LayerManager *mgr = widget->GetLayerManager();
|
||||
if (!mgr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsTArray<float> tmpFrameIntervals;
|
||||
mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
|
||||
*frameCount = tmpFrameIntervals.Length();
|
||||
|
||||
*frameIntervals = (float*)moz_xmalloc(*frameCount * sizeof(float));
|
||||
|
||||
/* copy over the frame intervals and paint times into the arrays we just allocated */
|
||||
for (uint32_t i = 0; i < *frameCount; i++) {
|
||||
(*frameIntervals)[i] = tmpFrameIntervals[i];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::BeginTabSwitch()
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LayerManager *mgr = widget->GetLayerManager();
|
||||
if (!mgr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mgr->BeginTabSwitch();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
ComputeAnimationValue(nsCSSPropertyID aProperty,
|
||||
Element* aElement,
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ interface nsIJSRAIIHelper;
|
|||
interface nsIContentPermissionRequest;
|
||||
interface nsIObserver;
|
||||
|
||||
[scriptable, uuid(7fcc7958-77d9-45ff-8c81-277bde5f0dc8)]
|
||||
[scriptable, uuid(58e97ce9-1d9e-4576-aabf-89480fdeb16d)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
|
|
@ -1425,38 +1425,6 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
*/
|
||||
readonly attribute AString currentAudioBackend;
|
||||
|
||||
/**
|
||||
* Record (and return) frame-intervals for frames which were presented
|
||||
* between calling StartFrameTimeRecording and StopFrameTimeRecording.
|
||||
*
|
||||
* - Uses a cyclic buffer and serves concurrent consumers, so if Stop is called too late
|
||||
* (elements were overwritten since Start), result is considered invalid and hence empty.
|
||||
* - Buffer is capable of holding 10 seconds @ 60fps (or more if frames were less frequent).
|
||||
* Can be changed (up to 1 hour) via pref: toolkit.framesRecording.bufferSize.
|
||||
* - Note: the first frame-interval may be longer than expected because last frame
|
||||
* might have been presented some time before calling StartFrameTimeRecording.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a handle which represents current recording start position.
|
||||
*/
|
||||
void startFrameTimeRecording([retval] out unsigned long startIndex);
|
||||
|
||||
/**
|
||||
* Returns number of recorded frames since startIndex was issued,
|
||||
* and allocates+populates 2 arraye with the recorded data.
|
||||
* - Allocation is infallible. Should be released even if size is 0.
|
||||
*/
|
||||
void stopFrameTimeRecording(in unsigned long startIndex,
|
||||
[optional] out unsigned long frameCount,
|
||||
[retval, array, size_is(frameCount)] out float frameIntervals);
|
||||
|
||||
/**
|
||||
* Signals that we're begining to tab switch. This is used by painting code to
|
||||
* determine total tab switch time.
|
||||
*/
|
||||
void beginTabSwitch();
|
||||
|
||||
/**
|
||||
* The DPI of the display
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1545,115 +1545,6 @@ RefLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
|||
aAttrs = RefLayerAttributes(GetReferentId(), mEventRegionsOverride);
|
||||
}
|
||||
|
||||
/**
|
||||
* StartFrameTimeRecording, together with StopFrameTimeRecording
|
||||
* enable recording of frame intervals.
|
||||
*
|
||||
* To allow concurrent consumers, a cyclic array is used which serves all
|
||||
* consumers, practically stateless with regard to consumers.
|
||||
*
|
||||
* To save resources, the buffer is allocated on first call to StartFrameTimeRecording
|
||||
* and recording is paused if no consumer which called StartFrameTimeRecording is able
|
||||
* to get valid results (because the cyclic buffer was overwritten since that call).
|
||||
*
|
||||
* To determine availability of the data upon StopFrameTimeRecording:
|
||||
* - mRecording.mNextIndex increases on each PostPresent, and never resets.
|
||||
* - Cyclic buffer position is realized as mNextIndex % bufferSize.
|
||||
* - StartFrameTimeRecording returns mNextIndex. When StopFrameTimeRecording is called,
|
||||
* the required start index is passed as an arg, and we're able to calculate the required
|
||||
* length. If this length is bigger than bufferSize, it means data was overwritten.
|
||||
* otherwise, we can return the entire sequence.
|
||||
* - To determine if we need to pause, mLatestStartIndex is updated to mNextIndex
|
||||
* on each call to StartFrameTimeRecording. If this index gets overwritten,
|
||||
* it means that all earlier start indices obtained via StartFrameTimeRecording
|
||||
* were also overwritten, hence, no point in recording, so pause.
|
||||
* - mCurrentRunStartIndex indicates the oldest index of the recording after which
|
||||
* the recording was not paused. If StopFrameTimeRecording is invoked with a start index
|
||||
* older than this, it means that some frames were not recorded, so data is invalid.
|
||||
*/
|
||||
uint32_t
|
||||
LayerManager::StartFrameTimeRecording(int32_t aBufferSize)
|
||||
{
|
||||
if (mRecording.mIsPaused) {
|
||||
mRecording.mIsPaused = false;
|
||||
|
||||
if (!mRecording.mIntervals.Length()) { // Initialize recording buffers
|
||||
mRecording.mIntervals.SetLength(aBufferSize);
|
||||
}
|
||||
|
||||
// After being paused, recent values got invalid. Update them to now.
|
||||
mRecording.mLastFrameTime = TimeStamp::Now();
|
||||
|
||||
// Any recording which started before this is invalid, since we were paused.
|
||||
mRecording.mCurrentRunStartIndex = mRecording.mNextIndex;
|
||||
}
|
||||
|
||||
// If we'll overwrite this index, there are no more consumers with aStartIndex
|
||||
// for which we're able to provide the full recording, so no point in keep recording.
|
||||
mRecording.mLatestStartIndex = mRecording.mNextIndex;
|
||||
return mRecording.mNextIndex;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManager::RecordFrame()
|
||||
{
|
||||
if (!mRecording.mIsPaused) {
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
uint32_t i = mRecording.mNextIndex % mRecording.mIntervals.Length();
|
||||
mRecording.mIntervals[i] = static_cast<float>((now - mRecording.mLastFrameTime)
|
||||
.ToMilliseconds());
|
||||
mRecording.mNextIndex++;
|
||||
mRecording.mLastFrameTime = now;
|
||||
|
||||
if (mRecording.mNextIndex > (mRecording.mLatestStartIndex + mRecording.mIntervals.Length())) {
|
||||
// We've just overwritten the most recent recording start -> pause.
|
||||
mRecording.mIsPaused = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerManager::PostPresent()
|
||||
{
|
||||
if (!mTabSwitchStart.IsNull()) {
|
||||
mTabSwitchStart = TimeStamp();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerManager::StopFrameTimeRecording(uint32_t aStartIndex,
|
||||
nsTArray<float>& aFrameIntervals)
|
||||
{
|
||||
uint32_t bufferSize = mRecording.mIntervals.Length();
|
||||
uint32_t length = mRecording.mNextIndex - aStartIndex;
|
||||
if (mRecording.mIsPaused || length > bufferSize || aStartIndex < mRecording.mCurrentRunStartIndex) {
|
||||
// aStartIndex is too old. Also if aStartIndex was issued before mRecordingNextIndex overflowed (uint32_t)
|
||||
// and stopped after the overflow (would happen once every 828 days of constant 60fps).
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if (!length) {
|
||||
aFrameIntervals.Clear();
|
||||
return; // empty recording, return empty arrays.
|
||||
}
|
||||
// Set length in advance to avoid possibly repeated reallocations
|
||||
aFrameIntervals.SetLength(length);
|
||||
|
||||
uint32_t cyclicPos = aStartIndex % bufferSize;
|
||||
for (uint32_t i = 0; i < length; i++, cyclicPos++) {
|
||||
if (cyclicPos == bufferSize) {
|
||||
cyclicPos = 0;
|
||||
}
|
||||
aFrameIntervals[i] = mRecording.mIntervals[cyclicPos];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayerManager::BeginTabSwitch()
|
||||
{
|
||||
mTabSwitchStart = TimeStamp::Now();
|
||||
}
|
||||
|
||||
static void PrintInfo(std::stringstream& aStream, LayerComposite* aLayerComposite);
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
|
|
|
|||
|
|
@ -586,36 +586,6 @@ public:
|
|||
*/
|
||||
void LogSelf(const char* aPrefix="");
|
||||
|
||||
/**
|
||||
* Record (and return) frame-intervals and paint-times for frames which were presented
|
||||
* between calling StartFrameTimeRecording and StopFrameTimeRecording.
|
||||
*
|
||||
* - Uses a cyclic buffer and serves concurrent consumers, so if Stop is called too late
|
||||
* (elements were overwritten since Start), result is considered invalid and hence empty.
|
||||
* - Buffer is capable of holding 10 seconds @ 60fps (or more if frames were less frequent).
|
||||
* Can be changed (up to 1 hour) via pref: toolkit.framesRecording.bufferSize.
|
||||
* - Note: the first frame-interval may be longer than expected because last frame
|
||||
* might have been presented some time before calling StartFrameTimeRecording.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a handle which represents current recording start position.
|
||||
*/
|
||||
virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize);
|
||||
|
||||
/**
|
||||
* Clears, then populates aFrameIntervals with the recorded frame timing
|
||||
* data. The array will be empty if data was overwritten since
|
||||
* aStartIndex was obtained.
|
||||
*/
|
||||
virtual void StopFrameTimeRecording(uint32_t aStartIndex,
|
||||
nsTArray<float>& aFrameIntervals);
|
||||
|
||||
void RecordFrame();
|
||||
void PostPresent();
|
||||
|
||||
void BeginTabSwitch();
|
||||
|
||||
static bool IsLogEnabled();
|
||||
static mozilla::LogModule* GetLog();
|
||||
|
||||
|
|
@ -686,27 +656,6 @@ protected:
|
|||
TimeStamp mAnimationReadyTime;
|
||||
// The count of pixels that were painted in the current transaction.
|
||||
uint32_t mPaintedPixelCount;
|
||||
private:
|
||||
struct FramesTimingRecording
|
||||
{
|
||||
// Stores state and data for frame intervals and paint times recording.
|
||||
// see LayerManager::StartFrameTimeRecording() at Layers.cpp for more details.
|
||||
FramesTimingRecording()
|
||||
: mNextIndex(0)
|
||||
, mLatestStartIndex(0)
|
||||
, mCurrentRunStartIndex(0)
|
||||
, mIsPaused(true)
|
||||
{}
|
||||
nsTArray<float> mIntervals;
|
||||
TimeStamp mLastFrameTime;
|
||||
uint32_t mNextIndex;
|
||||
uint32_t mLatestStartIndex;
|
||||
uint32_t mCurrentRunStartIndex;
|
||||
bool mIsPaused;
|
||||
};
|
||||
FramesTimingRecording mRecording;
|
||||
|
||||
TimeStamp mTabSwitchStart;
|
||||
|
||||
public:
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -629,8 +629,6 @@ BasicLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
|
|||
if (mWidget) {
|
||||
FlashWidgetUpdateArea(mTarget);
|
||||
}
|
||||
RecordFrame();
|
||||
PostPresent();
|
||||
|
||||
if (!mTransactionIncomplete) {
|
||||
// Clear out target if we have a complete transaction.
|
||||
|
|
|
|||
|
|
@ -617,28 +617,6 @@ ClientLayerManager::SendInvalidRegion(const nsIntRegion& aRegion)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ClientLayerManager::StartFrameTimeRecording(int32_t aBufferSize)
|
||||
{
|
||||
CompositorBridgeChild* renderer = GetRemoteRenderer();
|
||||
if (renderer) {
|
||||
uint32_t startIndex;
|
||||
renderer->SendStartFrameTimeRecording(aBufferSize, &startIndex);
|
||||
return startIndex;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::StopFrameTimeRecording(uint32_t aStartIndex,
|
||||
nsTArray<float>& aFrameIntervals)
|
||||
{
|
||||
CompositorBridgeChild* renderer = GetRemoteRenderer();
|
||||
if (renderer) {
|
||||
renderer->SendStopFrameTimeRecording(aStartIndex, &aFrameIntervals);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -98,11 +98,6 @@ public:
|
|||
virtual void FlushRendering() override;
|
||||
void SendInvalidRegion(const nsIntRegion& aRegion);
|
||||
|
||||
virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize) override;
|
||||
|
||||
virtual void StopFrameTimeRecording(uint32_t aStartIndex,
|
||||
nsTArray<float>& aFrameIntervals) override;
|
||||
|
||||
virtual bool NeedsWidgetInvalidation() override { return false; }
|
||||
|
||||
ShadowableLayer* Hold(Layer* aLayer);
|
||||
|
|
|
|||
|
|
@ -966,8 +966,6 @@ LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion, const nsIntRegi
|
|||
}
|
||||
|
||||
mCompositor->GetWidget()->PostRender(&widgetContext);
|
||||
|
||||
RecordFrame();
|
||||
}
|
||||
|
||||
already_AddRefed<PaintedLayerComposite>
|
||||
|
|
|
|||
|
|
@ -802,24 +802,6 @@ CompositorBridgeChild::SendFlushRendering()
|
|||
return PCompositorBridgeChild::SendFlushRendering();
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeChild::SendStartFrameTimeRecording(const int32_t& bufferSize, uint32_t* startIndex)
|
||||
{
|
||||
if (!mCanSend) {
|
||||
return false;
|
||||
}
|
||||
return PCompositorBridgeChild::SendStartFrameTimeRecording(bufferSize, startIndex);
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeChild::SendStopFrameTimeRecording(const uint32_t& startIndex, nsTArray<float>* intervals)
|
||||
{
|
||||
if (!mCanSend) {
|
||||
return false;
|
||||
}
|
||||
return PCompositorBridgeChild::SendStopFrameTimeRecording(startIndex, intervals);
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeChild::SendNotifyRegionInvalidated(const nsIntRegion& region)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -159,8 +159,6 @@ public:
|
|||
bool SendMakeSnapshot(const SurfaceDescriptor& inSnapshot, const gfx::IntRect& dirtyRect);
|
||||
bool SendFlushRendering();
|
||||
bool SendGetTileSize(int32_t* tileWidth, int32_t* tileHeight);
|
||||
bool SendStartFrameTimeRecording(const int32_t& bufferSize, uint32_t* startIndex);
|
||||
bool SendStopFrameTimeRecording(const uint32_t& startIndex, nsTArray<float>* intervals);
|
||||
bool SendNotifyRegionInvalidated(const nsIntRegion& region);
|
||||
bool SendRequestNotifyAfterRemotePaint();
|
||||
bool SendClearApproximatelyVisibleRegions(uint64_t aLayersId, uint32_t aPresShellId);
|
||||
|
|
|
|||
|
|
@ -817,27 +817,6 @@ CompositorBridgeParent::Invalidate()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex)
|
||||
{
|
||||
if (mLayerManager) {
|
||||
*aOutStartIndex = mLayerManager->StartFrameTimeRecording(aBufferSize);
|
||||
} else {
|
||||
*aOutStartIndex = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::RecvStopFrameTimeRecording(const uint32_t& aStartIndex,
|
||||
InfallibleTArray<float>* intervals)
|
||||
{
|
||||
if (mLayerManager) {
|
||||
mLayerManager->StopFrameTimeRecording(aStartIndex, *intervals);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::RecvClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
|
||||
const uint32_t& aPresShellId)
|
||||
|
|
|
|||
|
|
@ -281,8 +281,6 @@ public:
|
|||
}
|
||||
|
||||
virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) override;
|
||||
virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) override;
|
||||
virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) override;
|
||||
|
||||
// Unused for chrome <-> compositor communication (which this class does).
|
||||
// @see CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ public:
|
|||
virtual bool RecvFlushRendering() override { return true; }
|
||||
virtual bool RecvForcePresent() override { return true; }
|
||||
virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) override { return true; }
|
||||
virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) override { return true; }
|
||||
virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) override { return true; }
|
||||
|
||||
virtual bool RecvClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
|
||||
const uint32_t& aPresShellId) override;
|
||||
|
|
|
|||
|
|
@ -184,12 +184,6 @@ parent:
|
|||
// work around a windows presentation bug (See Bug 1232042)
|
||||
async ForcePresent();
|
||||
|
||||
sync StartFrameTimeRecording(int32_t bufferSize)
|
||||
returns (uint32_t startIndex);
|
||||
|
||||
sync StopFrameTimeRecording(uint32_t startIndex)
|
||||
returns (float[] intervals);
|
||||
|
||||
// layersBackendHints is an ordered list of preffered backends where
|
||||
// layersBackendHints[0] is the best backend. If any hints are LayersBackend::LAYERS_NONE
|
||||
// that hint is ignored.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue