mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 541588 subpatch 2: Use nsRefreshDriver instead of nsITimer to schedule sample callbacks for nsSMILAnimationController. r=roc
This commit is contained in:
parent
85d3ff805d
commit
199de9f2f6
@ -51,17 +51,6 @@
|
||||
//----------------------------------------------------------------------
|
||||
// nsSMILAnimationController implementation
|
||||
|
||||
// In my testing the minimum needed for smooth animation is 36 frames per
|
||||
// second which seems like a lot (Flash traditionally uses 14fps).
|
||||
//
|
||||
// Redrawing is synchronous. This is deliberate so that later we can tune the
|
||||
// timer based on how long the callback takes. To achieve 36fps we'd need 28ms
|
||||
// between frames. For now we set the timer interval to be a little less than
|
||||
// this (to allow for the render itself) and then let performance decay as the
|
||||
// image gets more complicated and render times increase.
|
||||
//
|
||||
const PRUint32 nsSMILAnimationController::kTimerInterval = 22;
|
||||
|
||||
// Helper method
|
||||
static nsRefreshDriver*
|
||||
GetRefreshDriverForDoc(nsIDocument* aDoc)
|
||||
@ -91,8 +80,6 @@ nsSMILAnimationController::nsSMILAnimationController()
|
||||
nsSMILAnimationController::~nsSMILAnimationController()
|
||||
{
|
||||
StopSampling(GetRefreshDriverForDoc(mDocument));
|
||||
mTimer = nsnull;
|
||||
|
||||
NS_ASSERTION(mAnimationElementTable.Count() == 0,
|
||||
"Animation controller shouldn't be tracking any animation"
|
||||
" elements when it dies");
|
||||
@ -118,9 +105,6 @@ nsSMILAnimationController::Init(nsIDocument* aDoc)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDoc);
|
||||
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
NS_ENSURE_TRUE(mTimer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Keep track of document, so we can traverse its set of animation elements
|
||||
mDocument = aDoc;
|
||||
|
||||
@ -172,7 +156,6 @@ NS_IMPL_ADDREF(nsSMILAnimationController)
|
||||
NS_IMPL_RELEASE(nsSMILAnimationController)
|
||||
|
||||
// nsRefreshDriver Callback function
|
||||
// XXXdholbert NOTE: This function isn't used yet
|
||||
void
|
||||
nsSMILAnimationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
{
|
||||
@ -256,39 +239,29 @@ nsSMILAnimationController::Unlink()
|
||||
//----------------------------------------------------------------------
|
||||
// Timer-related implementation helpers
|
||||
|
||||
/*static*/ void
|
||||
nsSMILAnimationController::Notify(nsITimer* timer, void* aClosure)
|
||||
{
|
||||
nsSMILAnimationController* controller = (nsSMILAnimationController*)aClosure;
|
||||
|
||||
NS_ASSERTION(controller->mTimer == timer,
|
||||
"nsSMILAnimationController::Notify called with incorrect timer");
|
||||
|
||||
controller->Sample();
|
||||
}
|
||||
|
||||
nsresult
|
||||
void
|
||||
nsSMILAnimationController::StartSampling(nsRefreshDriver* aRefreshDriver)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTimer, NS_ERROR_FAILURE);
|
||||
NS_ASSERTION(mPauseState == 0, "Starting timer but controller is paused");
|
||||
|
||||
//
|
||||
// XXX Make this self-tuning. Sounds like control theory to me and not
|
||||
// something I'm familiar with.
|
||||
//
|
||||
return mTimer->InitWithFuncCallback(nsSMILAnimationController::Notify,
|
||||
this,
|
||||
kTimerInterval,
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
NS_ASSERTION(mPauseState == 0, "Starting sampling but controller is paused");
|
||||
if (aRefreshDriver) {
|
||||
NS_ABORT_IF_FALSE(!GetRefreshDriverForDoc(mDocument) ||
|
||||
aRefreshDriver == GetRefreshDriverForDoc(mDocument),
|
||||
"Starting sampling with wrong refresh driver");
|
||||
aRefreshDriver->AddRefreshObserver(this, Flush_Style);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
void
|
||||
nsSMILAnimationController::StopSampling(nsRefreshDriver* aRefreshDriver)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTimer, NS_ERROR_FAILURE);
|
||||
|
||||
return mTimer->Cancel();
|
||||
if (aRefreshDriver) {
|
||||
// NOTE: The document might already have been detached from its PresContext
|
||||
// (and RefreshDriver), which would make GetRefreshDriverForDoc return null.
|
||||
NS_ABORT_IF_FALSE(!GetRefreshDriverForDoc(mDocument) ||
|
||||
aRefreshDriver == GetRefreshDriverForDoc(mDocument),
|
||||
"Stopping sampling with wrong refresh driver");
|
||||
aRefreshDriver->RemoveRefreshObserver(this, Flush_Style);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -111,8 +111,9 @@ public:
|
||||
void Unlink();
|
||||
|
||||
// Methods for controlling whether we're sampling
|
||||
nsresult StartSampling(nsRefreshDriver* aRefreshDriver);
|
||||
nsresult StopSampling(nsRefreshDriver* aRefreshDriver);
|
||||
// (Use to register/unregister us with the given nsRefreshDriver)
|
||||
void StartSampling(nsRefreshDriver* aRefreshDriver);
|
||||
void StopSampling(nsRefreshDriver* aRefreshDriver);
|
||||
|
||||
protected:
|
||||
// Typedefs
|
||||
@ -148,9 +149,6 @@ protected:
|
||||
PR_STATIC_CALLBACK(PLDHashOperator) CompositorTableEntryTraverse(
|
||||
nsSMILCompositor* aCompositor, void* aArg);
|
||||
|
||||
// Timer-related implementation helpers
|
||||
static void Notify(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
// Sample-related callbacks and implementation helpers
|
||||
virtual void DoSample();
|
||||
void DoSample(PRBool aSkipUnchangedContainers);
|
||||
@ -179,7 +177,6 @@ protected:
|
||||
NS_DECL_OWNINGTHREAD
|
||||
|
||||
static const PRUint32 kTimerInterval;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
AnimationElementHashtable mAnimationElementTable;
|
||||
TimeContainerHashtable mChildContainerTable;
|
||||
PRPackedBool mResampleNeeded;
|
||||
|
@ -1703,6 +1703,15 @@ PresShell::Init(nsIDocument* aDocument,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
if (mDocument->HasAnimationController()) {
|
||||
nsSMILAnimationController* animCtrl = mDocument->GetAnimationController();
|
||||
if (!animCtrl->IsPaused()) {
|
||||
animCtrl->StartSampling(GetPresContext()->RefreshDriver());
|
||||
}
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1812,10 +1821,15 @@ PresShell::Destroy()
|
||||
mDocument->DeleteShell();
|
||||
}
|
||||
|
||||
nsRefreshDriver* rd = GetPresContext()->RefreshDriver();
|
||||
if (mDocument->HasAnimationController()) {
|
||||
mDocument->GetAnimationController()->StopSampling(rd);
|
||||
}
|
||||
|
||||
// Revoke any pending events. We need to do this and cancel pending reflows
|
||||
// before we destroy the frame manager, since apparently frame destruction
|
||||
// sometimes spins the event queue when plug-ins are involved(!).
|
||||
GetPresContext()->RefreshDriver()->RemoveRefreshObserver(this, Flush_Layout);
|
||||
rd->RemoveRefreshObserver(this, Flush_Layout);
|
||||
mResizeEvent.Revoke();
|
||||
if (mAsyncResizeTimerIsActive) {
|
||||
mAsyncResizeEventTimer->Cancel();
|
||||
|
Loading…
Reference in New Issue
Block a user