Bug 1646263 - Separate CompositorAnimationStorage from AnimationHelper.[cpp,h]. r=kats

Differential Revision: https://phabricator.services.mozilla.com/D79944
This commit is contained in:
Hiroyuki Ikezoe 2020-06-17 22:38:30 +00:00
Родитель 2259081765
Коммит 4af8413479
9 изменённых файлов: 310 добавлений и 266 удалений

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/dom/KeyframeEffect.h" // for dom::KeyFrameEffectReadOnly
#include "mozilla/dom/Nullable.h" // for dom::Nullable
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
#include "mozilla/layers/CompositorAnimationStorage.h" // for CompositorAnimationStorage
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
#include "mozilla/LayerAnimationInfo.h" // for GetCSSPropertiesFor()
#include "mozilla/MotionPathUtils.h" // for ResolveMotionPath()
@ -22,114 +23,6 @@
namespace mozilla {
namespace layers {
void CompositorAnimationStorage::Clear() {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
mAnimatedValues.Clear();
mAnimations.clear();
}
void CompositorAnimationStorage::ClearById(const uint64_t& aId) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
mAnimatedValues.Remove(aId);
mAnimations.erase(aId);
}
AnimatedValue* CompositorAnimationStorage::GetAnimatedValue(
const uint64_t& aId) const {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
return mAnimatedValues.Get(aId);
}
OMTAValue CompositorAnimationStorage::GetOMTAValue(const uint64_t& aId) const {
OMTAValue omtaValue = mozilla::null_t();
auto animatedValue = GetAnimatedValue(aId);
if (!animatedValue) {
return omtaValue;
}
animatedValue->Value().match(
[&](const AnimationTransform& aTransform) {
gfx::Matrix4x4 transform = aTransform.mFrameTransform;
const TransformData& data = aTransform.mData;
float scale = data.appUnitsPerDevPixel();
gfx::Point3D transformOrigin = data.transformOrigin();
// Undo the rebasing applied by
// nsDisplayTransform::GetResultingTransformMatrixInternal
transform.ChangeBasis(-transformOrigin);
// Convert to CSS pixels (this undoes the operations performed by
// nsStyleTransformMatrix::ProcessTranslatePart which is called from
// nsDisplayTransform::GetResultingTransformMatrix)
double devPerCss = double(scale) / double(AppUnitsPerCSSPixel());
transform._41 *= devPerCss;
transform._42 *= devPerCss;
transform._43 *= devPerCss;
omtaValue = transform;
},
[&](const float& aOpacity) { omtaValue = aOpacity; },
[&](const nscolor& aColor) { omtaValue = aColor; });
return omtaValue;
}
void CompositorAnimationStorage::SetAnimatedValue(
uint64_t aId, AnimatedValue* aPreviousValue,
gfx::Matrix4x4&& aTransformInDevSpace, gfx::Matrix4x4&& aFrameTransform,
const TransformData& aData) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
if (!aPreviousValue) {
MOZ_ASSERT(!mAnimatedValues.Contains(aId));
mAnimatedValues.Put(
aId, MakeUnique<AnimatedValue>(std::move(aTransformInDevSpace),
std::move(aFrameTransform), aData));
return;
}
MOZ_ASSERT(aPreviousValue->Is<AnimationTransform>());
MOZ_ASSERT(aPreviousValue == GetAnimatedValue(aId));
aPreviousValue->SetTransform(std::move(aTransformInDevSpace),
std::move(aFrameTransform), aData);
}
void CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
AnimatedValue* aPreviousValue,
nscolor aColor) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
if (!aPreviousValue) {
MOZ_ASSERT(!mAnimatedValues.Contains(aId));
mAnimatedValues.Put(aId, MakeUnique<AnimatedValue>(aColor));
return;
}
MOZ_ASSERT(aPreviousValue->Is<nscolor>());
MOZ_ASSERT(aPreviousValue == GetAnimatedValue(aId));
aPreviousValue->SetColor(aColor);
}
void CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
AnimatedValue* aPreviousValue,
float aOpacity) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
if (!aPreviousValue) {
MOZ_ASSERT(!mAnimatedValues.Contains(aId));
mAnimatedValues.Put(aId, MakeUnique<AnimatedValue>(aOpacity));
return;
}
MOZ_ASSERT(aPreviousValue->Is<float>());
MOZ_ASSERT(aPreviousValue == GetAnimatedValue(aId));
aPreviousValue->SetOpacity(aOpacity);
}
void CompositorAnimationStorage::SetAnimations(uint64_t aId,
const AnimationArray& aValue) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
mAnimations[aId] = std::make_unique<AnimationStorageData>(
AnimationHelper::ExtractAnimations(aValue));
}
enum class CanSkipCompose {
IfPossible,
No,

Просмотреть файл

@ -19,164 +19,13 @@
#include <unordered_map>
namespace mozilla {
struct AnimationValue;
namespace dom {
enum class CompositeOperation : uint8_t;
enum class IterationCompositeOperation : uint8_t;
}; // namespace dom
namespace layers {
class Animation;
class CompositorAnimationStorage;
struct AnimatedValue;
typedef nsTArray<layers::Animation> AnimationArray;
struct AnimationTransform {
/*
* This transform is calculated from sampleanimation in device pixel
* and used by compositor.
*/
gfx::Matrix4x4 mTransformInDevSpace;
/*
* This transform is calculated from frame and used by getOMTAStyle()
* for OMTA testing.
*/
gfx::Matrix4x4 mFrameTransform;
TransformData mData;
};
struct AnimatedValue final {
typedef Variant<AnimationTransform, float, nscolor> AnimatedValueType;
const AnimatedValueType& Value() const { return mValue; }
const AnimationTransform& Transform() const {
return mValue.as<AnimationTransform>();
}
const float& Opacity() const { return mValue.as<float>(); }
const nscolor& Color() const { return mValue.as<nscolor>(); }
template <typename T>
bool Is() const {
return mValue.is<T>();
}
AnimatedValue(gfx::Matrix4x4&& aTransformInDevSpace,
gfx::Matrix4x4&& aFrameTransform, const TransformData& aData)
: mValue(
AsVariant(AnimationTransform{std::move(aTransformInDevSpace),
std::move(aFrameTransform), aData})) {}
explicit AnimatedValue(const float& aValue) : mValue(AsVariant(aValue)) {}
explicit AnimatedValue(nscolor aValue) : mValue(AsVariant(aValue)) {}
void SetTransform(gfx::Matrix4x4&& aTransformInDevSpace,
gfx::Matrix4x4&& aFrameTransform,
const TransformData& aData) {
MOZ_ASSERT(mValue.is<AnimationTransform>());
AnimationTransform& previous = mValue.as<AnimationTransform>();
previous.mTransformInDevSpace = std::move(aTransformInDevSpace);
previous.mFrameTransform = std::move(aFrameTransform);
if (previous.mData != aData) {
previous.mData = aData;
}
}
void SetOpacity(float aOpacity) {
MOZ_ASSERT(mValue.is<float>());
mValue.as<float>() = aOpacity;
}
void SetColor(nscolor aColor) {
MOZ_ASSERT(mValue.is<nscolor>());
mValue.as<nscolor>() = aColor;
}
private:
AnimatedValueType mValue;
};
// CompositorAnimationStorage stores the animations and animated values
// keyed by a CompositorAnimationsId. The "animations" are a representation of
// an entire animation over time, while the "animated values" are values sampled
// from the animations at a particular point in time.
//
// There is one CompositorAnimationStorage per CompositorBridgeParent (i.e.
// one per browser window), and the CompositorAnimationsId key is unique within
// a particular CompositorAnimationStorage instance.
//
// Each layer which has animations gets a CompositorAnimationsId key, and reuses
// that key during its lifetime. Likewise, in layers-free webrender, a display
// item that is animated (e.g. nsDisplayTransform) gets a CompositorAnimationsId
// key and reuses that key (it persists the key via the frame user-data
// mechanism).
class CompositorAnimationStorage final {
typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable;
typedef std::unordered_map<uint64_t, std::unique_ptr<AnimationStorageData>>
AnimationsTable;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
public:
/**
* Set the animation transform based on the unique id and also
* set up |aFrameTransform| and |aData| for OMTA testing.
* If |aPreviousValue| is not null, the animation transform replaces the value
* in the |aPreviousValue|.
* NOTE: |aPreviousValue| should be the value for the |aId|.
*/
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
gfx::Matrix4x4&& aTransformInDevSpace,
gfx::Matrix4x4&& aFrameTransform,
const TransformData& aData);
/**
* Similar to above but for opacity.
*/
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
float aOpacity);
/**
* Similar to above but for color.
*/
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
nscolor aColor);
/**
* Return the animated value if a given id can map to its animated value
*/
AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
OMTAValue GetOMTAValue(const uint64_t& aId) const;
/**
* Return the iterator of animated value table
*/
AnimatedValueTable::Iterator ConstAnimatedValueTableIter() const {
return mAnimatedValues.ConstIter();
}
uint32_t AnimatedValueCount() const { return mAnimatedValues.Count(); }
/**
* Set the animations based on the unique id
*/
void SetAnimations(uint64_t aId, const AnimationArray& aAnimations);
const AnimationsTable& Animations() const { return mAnimations; }
bool HasAnimations() const { return !mAnimations.empty(); }
/**
* Clear AnimatedValues and Animations data
*/
void Clear();
void ClearById(const uint64_t& aId);
private:
~CompositorAnimationStorage(){};
private:
AnimatedValueTable mAnimatedValues;
AnimationsTable mAnimations;
};
/**
* This utility class allows reusing code between the webrender and
* non-webrender compositor-side implementations. It provides

Просмотреть файл

@ -0,0 +1,126 @@
/* -*- 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/. */
#include "CompositorAnimationStorage.h"
#include "AnimationHelper.h"
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
#include "nsDeviceContext.h" // for AppUnitsPerCSSPixel
#include "nsDisplayList.h" // for nsDisplayTransform, etc
namespace mozilla {
namespace layers {
void CompositorAnimationStorage::Clear() {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
mAnimatedValues.Clear();
mAnimations.clear();
}
void CompositorAnimationStorage::ClearById(const uint64_t& aId) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
mAnimatedValues.Remove(aId);
mAnimations.erase(aId);
}
AnimatedValue* CompositorAnimationStorage::GetAnimatedValue(
const uint64_t& aId) const {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
return mAnimatedValues.Get(aId);
}
OMTAValue CompositorAnimationStorage::GetOMTAValue(const uint64_t& aId) const {
OMTAValue omtaValue = mozilla::null_t();
auto animatedValue = GetAnimatedValue(aId);
if (!animatedValue) {
return omtaValue;
}
animatedValue->Value().match(
[&](const AnimationTransform& aTransform) {
gfx::Matrix4x4 transform = aTransform.mFrameTransform;
const TransformData& data = aTransform.mData;
float scale = data.appUnitsPerDevPixel();
gfx::Point3D transformOrigin = data.transformOrigin();
// Undo the rebasing applied by
// nsDisplayTransform::GetResultingTransformMatrixInternal
transform.ChangeBasis(-transformOrigin);
// Convert to CSS pixels (this undoes the operations performed by
// nsStyleTransformMatrix::ProcessTranslatePart which is called from
// nsDisplayTransform::GetResultingTransformMatrix)
double devPerCss = double(scale) / double(AppUnitsPerCSSPixel());
transform._41 *= devPerCss;
transform._42 *= devPerCss;
transform._43 *= devPerCss;
omtaValue = transform;
},
[&](const float& aOpacity) { omtaValue = aOpacity; },
[&](const nscolor& aColor) { omtaValue = aColor; });
return omtaValue;
}
void CompositorAnimationStorage::SetAnimatedValue(
uint64_t aId, AnimatedValue* aPreviousValue,
gfx::Matrix4x4&& aTransformInDevSpace, gfx::Matrix4x4&& aFrameTransform,
const TransformData& aData) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
if (!aPreviousValue) {
MOZ_ASSERT(!mAnimatedValues.Contains(aId));
mAnimatedValues.Put(
aId, MakeUnique<AnimatedValue>(std::move(aTransformInDevSpace),
std::move(aFrameTransform), aData));
return;
}
MOZ_ASSERT(aPreviousValue->Is<AnimationTransform>());
MOZ_ASSERT(aPreviousValue == GetAnimatedValue(aId));
aPreviousValue->SetTransform(std::move(aTransformInDevSpace),
std::move(aFrameTransform), aData);
}
void CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
AnimatedValue* aPreviousValue,
nscolor aColor) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
if (!aPreviousValue) {
MOZ_ASSERT(!mAnimatedValues.Contains(aId));
mAnimatedValues.Put(aId, MakeUnique<AnimatedValue>(aColor));
return;
}
MOZ_ASSERT(aPreviousValue->Is<nscolor>());
MOZ_ASSERT(aPreviousValue == GetAnimatedValue(aId));
aPreviousValue->SetColor(aColor);
}
void CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
AnimatedValue* aPreviousValue,
float aOpacity) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
if (!aPreviousValue) {
MOZ_ASSERT(!mAnimatedValues.Contains(aId));
mAnimatedValues.Put(aId, MakeUnique<AnimatedValue>(aOpacity));
return;
}
MOZ_ASSERT(aPreviousValue->Is<float>());
MOZ_ASSERT(aPreviousValue == GetAnimatedValue(aId));
aPreviousValue->SetOpacity(aOpacity);
}
void CompositorAnimationStorage::SetAnimations(uint64_t aId,
const AnimationArray& aValue) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
mAnimations[aId] = std::make_unique<AnimationStorageData>(
AnimationHelper::ExtractAnimations(aValue));
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,171 @@
/* -*- 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/. */
#ifndef mozilla_layers_CompositorAnimationStorage_h
#define mozilla_layers_CompositorAnimationStorage_h
#include "mozilla/layers/AnimationStorageData.h"
#include "mozilla/layers/LayersMessages.h" // for TransformData, etc
#include "mozilla/Variant.h"
#include "X11UndefineNone.h"
#include <unordered_map>
namespace mozilla {
namespace layers {
class Animation;
typedef nsTArray<layers::Animation> AnimationArray;
struct AnimationTransform {
/*
* This transform is calculated from sampleanimation in device pixel
* and used by compositor.
*/
gfx::Matrix4x4 mTransformInDevSpace;
/*
* This transform is calculated from frame and used by getOMTAStyle()
* for OMTA testing.
*/
gfx::Matrix4x4 mFrameTransform;
TransformData mData;
};
struct AnimatedValue final {
typedef Variant<AnimationTransform, float, nscolor> AnimatedValueType;
const AnimatedValueType& Value() const { return mValue; }
const AnimationTransform& Transform() const {
return mValue.as<AnimationTransform>();
}
const float& Opacity() const { return mValue.as<float>(); }
const nscolor& Color() const { return mValue.as<nscolor>(); }
template <typename T>
bool Is() const {
return mValue.is<T>();
}
AnimatedValue(gfx::Matrix4x4&& aTransformInDevSpace,
gfx::Matrix4x4&& aFrameTransform, const TransformData& aData)
: mValue(
AsVariant(AnimationTransform{std::move(aTransformInDevSpace),
std::move(aFrameTransform), aData})) {}
explicit AnimatedValue(const float& aValue) : mValue(AsVariant(aValue)) {}
explicit AnimatedValue(nscolor aValue) : mValue(AsVariant(aValue)) {}
void SetTransform(gfx::Matrix4x4&& aTransformInDevSpace,
gfx::Matrix4x4&& aFrameTransform,
const TransformData& aData) {
MOZ_ASSERT(mValue.is<AnimationTransform>());
AnimationTransform& previous = mValue.as<AnimationTransform>();
previous.mTransformInDevSpace = std::move(aTransformInDevSpace);
previous.mFrameTransform = std::move(aFrameTransform);
if (previous.mData != aData) {
previous.mData = aData;
}
}
void SetOpacity(float aOpacity) {
MOZ_ASSERT(mValue.is<float>());
mValue.as<float>() = aOpacity;
}
void SetColor(nscolor aColor) {
MOZ_ASSERT(mValue.is<nscolor>());
mValue.as<nscolor>() = aColor;
}
private:
AnimatedValueType mValue;
};
// CompositorAnimationStorage stores the animations and animated values
// keyed by a CompositorAnimationsId. The "animations" are a representation of
// an entire animation over time, while the "animated values" are values sampled
// from the animations at a particular point in time.
//
// There is one CompositorAnimationStorage per CompositorBridgeParent (i.e.
// one per browser window), and the CompositorAnimationsId key is unique within
// a particular CompositorAnimationStorage instance.
//
// Each layer which has animations gets a CompositorAnimationsId key, and reuses
// that key during its lifetime. Likewise, in layers-free webrender, a display
// item that is animated (e.g. nsDisplayTransform) gets a CompositorAnimationsId
// key and reuses that key (it persists the key via the frame user-data
// mechanism).
class CompositorAnimationStorage final {
typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable;
typedef std::unordered_map<uint64_t, std::unique_ptr<AnimationStorageData>>
AnimationsTable;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
public:
/**
* Set the animation transform based on the unique id and also
* set up |aFrameTransform| and |aData| for OMTA testing.
* If |aPreviousValue| is not null, the animation transform replaces the value
* in the |aPreviousValue|.
* NOTE: |aPreviousValue| should be the value for the |aId|.
*/
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
gfx::Matrix4x4&& aTransformInDevSpace,
gfx::Matrix4x4&& aFrameTransform,
const TransformData& aData);
/**
* Similar to above but for opacity.
*/
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
float aOpacity);
/**
* Similar to above but for color.
*/
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
nscolor aColor);
/**
* Return the animated value if a given id can map to its animated value
*/
AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
OMTAValue GetOMTAValue(const uint64_t& aId) const;
/**
* Return the iterator of animated value table
*/
AnimatedValueTable::Iterator ConstAnimatedValueTableIter() const {
return mAnimatedValues.ConstIter();
}
uint32_t AnimatedValueCount() const { return mAnimatedValues.Count(); }
/**
* Set the animations based on the unique id
*/
void SetAnimations(uint64_t aId, const AnimationArray& aAnimations);
const AnimationsTable& Animations() const { return mAnimations; }
bool HasAnimations() const { return !mAnimations.empty(); }
/**
* Clear AnimatedValues and Animations data
*/
void Clear();
void ClearById(const uint64_t& aId);
private:
~CompositorAnimationStorage(){};
private:
AnimatedValueTable mAnimatedValues;
AnimationsTable mAnimations;
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_layers_CompositorAnimationStorage_h

Просмотреть файл

@ -22,6 +22,7 @@
#include "mozilla/layers/APZSampler.h" // for APZSampler
#include "mozilla/layers/APZUtils.h" // for CompleteAsyncTransform
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorAnimationStorage.h" // for CompositorAnimationStorage
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent, etc
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction

Просмотреть файл

@ -35,7 +35,6 @@
#include "mozilla/ipc/Transport.h" // for Transport
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUParent.h"
#include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
#include "mozilla/layers/APZSampler.h" // for APZSampler
#include "mozilla/layers/APZThreadUtils.h" // for APZThreadUtils
@ -44,6 +43,7 @@
#include "mozilla/layers/BasicCompositor.h" // for BasicCompositor
#include "mozilla/layers/CompositionRecorder.h" // for CompositionRecorder
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorAnimationStorage.h" // for CompositorAnimationStorage
#include "mozilla/layers/CompositorManagerParent.h" // for CompositorManagerParent
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
#include "mozilla/layers/CompositorThread.h"

Просмотреть файл

@ -16,6 +16,7 @@
#include "mozilla/layers/CanvasLayerComposite.h"
#include "mozilla/layers/ColorLayerComposite.h"
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorAnimationStorage.h" // for CompositorAnimationStorage
#include "mozilla/layers/ContainerLayerComposite.h"
#include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
#include "mozilla/layers/ImageLayerComposite.h"

Просмотреть файл

@ -165,6 +165,7 @@ EXPORTS.mozilla.layers += [
'composite/TiledContentHost.h',
'CompositionRecorder.h',
'Compositor.h',
'CompositorAnimationStorage.h',
'CompositorTypes.h',
'D3D11ShareHandleImage.h',
'D3D11YCbCrImage.h',
@ -434,6 +435,7 @@ UNIFIED_SOURCES += [
'composite/TiledContentHost.cpp',
'CompositionRecorder.cpp',
'Compositor.cpp',
'CompositorAnimationStorage.cpp',
'Effects.cpp',
'FrameMetrics.cpp',
'GLImages.cpp',

Просмотреть файл

@ -22,6 +22,7 @@
#include "mozilla/layers/APZUpdater.h"
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorAnimationStorage.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/CompositorVsyncScheduler.h"
#include "mozilla/layers/ImageBridgeParent.h"