fune/layout/base/nsRefreshObservers.h
Sean Feng 708bd702d2 Bug 1682045 - Allow nsPresContext to store and release the last registered OneShotPostRefreshObserver r=smaug
OneShotPostRefreshObserver works as the caller registers it, and
let it deletes itself via the DidRefresh method. The issue is that
DidRefresh is not guaranteed to run, and it'll leak PresShell
if it doesn't run.

This patch allows nsPresContext to store and release the last
registered OneShotPostRefreshObserver, and converted the existing
usage of OneShotPostRefreshObserver to use that. So instead of asking
OneShotPostRefreshObserver to delete itself, we now ask nsPresContext
to release it.

Differential Revision: https://phabricator.services.mozilla.com/D99939
2021-01-18 19:23:10 +00:00

94 lines
3 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Code to notify things that animate before a refresh, at an appropriate
* refresh rate. (Perhaps temporary, until replaced by compositor.)
*/
#ifndef LAYOUT_BASE_NSREFRESHOBSERVERS_H_
#define LAYOUT_BASE_NSREFRESHOBSERVERS_H_
#include <functional>
#include "mozilla/Attributes.h"
#include "mozilla/TimeStamp.h"
#include "nsISupports.h"
namespace mozilla {
class AnimationEventDispatcher;
class PendingFullscreenEvent;
class PresShell;
class RefreshDriverTimer;
} // namespace mozilla
/**
* An abstract base class to be implemented by callers wanting to be
* notified at refresh times. When nothing needs to be painted, callers
* may not be notified.
*/
class nsARefreshObserver {
public:
// AddRef and Release signatures that match nsISupports. Implementors
// must implement reference counting, and those that do implement
// nsISupports will already have methods with the correct signature.
//
// The refresh driver does NOT hold references to refresh observers
// except while it is notifying them.
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
MOZ_CAN_RUN_SCRIPT virtual void WillRefresh(mozilla::TimeStamp aTime) = 0;
};
/**
* An abstract base class to be implemented by callers wanting to be notified
* when the observing refresh driver updated mMostRecentRefresh due to active
* timer changes. Callers must ensure an observer is removed before it is
* destroyed.
*/
class nsATimerAdjustmentObserver {
public:
virtual void NotifyTimerAdjusted(mozilla::TimeStamp aTime) = 0;
};
/**
* An abstract base class to be implemented by callers wanting to be notified
* that a refresh has occurred. Callers must ensure an observer is removed
* before it is destroyed.
*/
class nsAPostRefreshObserver {
public:
virtual void DidRefresh() = 0;
};
namespace mozilla {
/**
* A wrapper for nsAPostRefreshObserver that's one-shot (unregisters itself
* after firing once) and can be used without writing a derived class by passing
* in the action in the form of a lambda (or other function object).
*
* Note, while the observer unregisters itself, the registering still needs to
* be done by the caller.
*/
class OneShotPostRefreshObserver : public nsAPostRefreshObserver {
public:
using Action =
std::function<void(mozilla::PresShell*, OneShotPostRefreshObserver*)>;
NS_INLINE_DECL_REFCOUNTING(OneShotPostRefreshObserver)
OneShotPostRefreshObserver(mozilla::PresShell* aPresShell, Action&& aAction);
explicit OneShotPostRefreshObserver(mozilla::PresShell* aPresShell);
void DidRefresh() override;
protected:
virtual ~OneShotPostRefreshObserver();
RefPtr<mozilla::PresShell> mPresShell;
Action mAction;
};
} // namespace mozilla
#endif