зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1484780 - Cache gfx::Path to avoid building and flattening path at each restyle cycle. r=heycam
In most cases, we run an animation on an object by changing its offset-distance/offset-rotate, but keep its offset-path the same. Building and flattening the path is sometime expensive, especially for large path, so caching it makes sense to us and have a significant performance improvement. This is for the main thread motion path animations. Note: Even though we support compositor animations for motion path, nsIFrame::GetTransformMatrix() is still called during the animations for other usages, so we may still build the gfx::Path on the main thread without this patch, so this improvement becomes necessary for most cases. Differential Revision: https://phabricator.services.mozilla.com/D46667 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
21a6f50b1a
Коммит
abda0eb288
|
@ -439,17 +439,10 @@ static OffsetPathData GenerateOffsetPathData(const nsIFrame* aFrame) {
|
|||
const StyleOffsetPath& path = aFrame->StyleDisplay()->mOffsetPath;
|
||||
switch (path.tag) {
|
||||
case StyleOffsetPath::Tag::Path: {
|
||||
// Here we only need to build a valid path for motion path, so
|
||||
// using the default values of stroke-width, stoke-linecap, and fill-rule
|
||||
// is fine for now because what we want is get the point and its normal
|
||||
// vector along the path, instead of rendering it.
|
||||
// FIXME: Use cache for main-thread in Bug 1484780.
|
||||
RefPtr<gfx::PathBuilder> builder =
|
||||
gfxPlatform::GetPlatform()
|
||||
->ScreenReferenceDrawTarget()
|
||||
->CreatePathBuilder(gfx::FillRule::FILL_WINDING);
|
||||
RefPtr<gfx::Path> gfxPath =
|
||||
MotionPathUtils::BuildPath(path.AsPath(), builder);
|
||||
aFrame->GetProperty(nsIFrame::OffsetPathCache());
|
||||
MOZ_ASSERT(gfxPath,
|
||||
"Should have a valid cached gfx::Path for offset-path");
|
||||
return OffsetPathData::Path(path.AsPath(), gfxPath.forget());
|
||||
}
|
||||
case StyleOffsetPath::Tag::Ray:
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
#include "mozilla/ServoStyleSet.h"
|
||||
#include "mozilla/ServoStyleSetInlines.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
#include "mozilla/dom/SVGPathData.h"
|
||||
#include "mozilla/dom/TouchEvent.h"
|
||||
#include "mozilla/gfx/Tools.h"
|
||||
#include "mozilla/layers/WebRenderUserData.h"
|
||||
|
@ -1335,6 +1336,30 @@ void nsFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
|
|||
PresContext()->SetBidiEnabled();
|
||||
}
|
||||
|
||||
// The following part is for caching offset-path:path(). We cache the
|
||||
// flatten gfx path, so we don't have to rebuild and re-flattern it at
|
||||
// each cycle if we have animations on offset-* with a fixed offset-path.
|
||||
const StyleOffsetPath* oldPath =
|
||||
aOldComputedStyle ? &aOldComputedStyle->StyleDisplay()->mOffsetPath
|
||||
: nullptr;
|
||||
const StyleOffsetPath& newPath = StyleDisplay()->mOffsetPath;
|
||||
if (!oldPath || *oldPath != newPath) {
|
||||
if (newPath.IsPath()) {
|
||||
// Here we only need to build a valid path for motion path, so
|
||||
// using the default values of stroke-width, stoke-linecap, and fill-rule
|
||||
// is fine for now because what we want is to get the point and its normal
|
||||
// vector along the path, instead of rendering it.
|
||||
RefPtr<gfx::PathBuilder> builder =
|
||||
gfxPlatform::GetPlatform()
|
||||
->ScreenReferenceDrawTarget()
|
||||
->CreatePathBuilder(gfx::FillRule::FILL_WINDING);
|
||||
SetProperty(nsIFrame::OffsetPathCache(),
|
||||
MotionPathUtils::BuildPath(newPath.AsPath(), builder).take());
|
||||
} else if (oldPath) {
|
||||
DeleteProperty(nsIFrame::OffsetPathCache());
|
||||
}
|
||||
}
|
||||
|
||||
RemoveStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS | NS_FRAME_SIMPLE_DISPLAYLIST);
|
||||
|
||||
mMayHaveRoundedCorners = true;
|
||||
|
|
|
@ -1257,6 +1257,8 @@ class nsIFrame : public nsQueryFrame {
|
|||
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(PlaceholderFrameProperty,
|
||||
nsPlaceholderFrame)
|
||||
|
||||
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(OffsetPathCache, mozilla::gfx::Path)
|
||||
|
||||
mozilla::FrameBidiData GetBidiData() const {
|
||||
bool exists;
|
||||
mozilla::FrameBidiData bidiData = GetProperty(BidiDataProperty(), &exists);
|
||||
|
|
Загрузка…
Ссылка в новой задаче