Loading gfx/layers/Compositor.h +0 −1 Original line number Diff line number Diff line Loading @@ -130,7 +130,6 @@ class TextureSource; class DataTextureSource; class CompositingRenderTarget; class CompositorBridgeParent; class LayerManagerComposite; class NativeLayer; class CompositorOGL; class CompositorD3D11; Loading gfx/layers/CompositorAnimationStorage.cpp +3 −336 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ #include "mozilla/layers/APZSampler.h" // for APZSampler #include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent #include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder #include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite, etc #include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper #include "mozilla/layers/OMTAController.h" // for OMTAController #include "mozilla/ScopeExit.h" Loading Loading @@ -341,337 +340,5 @@ WrAnimations CompositorAnimationStorage::CollectWebRenderAnimations() const { return animations; } static gfx::Matrix4x4 FrameTransformToTransformInDevice( const gfx::Matrix4x4& aFrameTransform, Layer* aLayer, const TransformData& aTransformData) { gfx::Matrix4x4 transformInDevice = aFrameTransform; // If our parent layer is a perspective layer, then the offset into reference // frame coordinates is already on that layer. If not, then we need to ask // for it to be added here. if (!aLayer->GetParent() || !aLayer->GetParent()->GetTransformIsPerspective()) { nsLayoutUtils::PostTranslate( transformInDevice, aTransformData.origin(), aTransformData.appUnitsPerDevPixel(), aLayer->GetContentFlags() & Layer::CONTENT_SNAP_TO_GRID); } if (ContainerLayer* c = aLayer->AsContainerLayer()) { transformInDevice.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1); } return transformInDevice; } static Matrix4x4 GetTransformForPartialPrerender( Layer* aLayer, const LayersId aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, const RefPtr<APZSampler>& aSampler) { MOZ_ASSERT(aLayer); ParentLayerPoint translationByApz; Matrix4x4 transform; for (Layer* layer = aLayer; layer; layer = layer->GetParent()) { if (layer->AsRefLayer()) { MOZ_ASSERT(layer->AsRefLayer()->GetReferentId() == aLayersId); break; } // Accumulate static transforms. if (layer != aLayer) { Matrix4x4 baseTransform = layer->GetBaseTransform(); if (ContainerLayer* container = layer->AsContainerLayer()) { baseTransform.PostScale(container->GetPreXScale(), container->GetPreYScale(), 1); } transform *= baseTransform; } if (!layer->GetIsStickyPosition() && !layer->GetIsFixedPosition()) { bool hasSameScrollId = false; for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) { // Factor APZ translation if there exists. if (aSampler) { LayerMetricsWrapper wrapper = LayerMetricsWrapper(layer, i); AsyncTransform asyncTransform = aSampler->GetCurrentAsyncTransform(wrapper, LayoutAndVisual); translationByApz += asyncTransform.mTranslation; } if (layer->GetFrameMetrics(i).GetScrollId() == aScrollId) { hasSameScrollId = true; } } if (hasSameScrollId) { break; } } else { // Bug 1642547: Fix for position:sticky layers. } } transform.PostTranslate(translationByApz.ToUnknownPoint()); return transform; } bool CompositorAnimationStorage::ApplyAnimatedValue( CompositorBridgeParent* aCompositorBridge, Layer* aLayer, nsCSSPropertyID aProperty, AnimatedValue* aPreviousValue, const nsTArray<RefPtr<RawServoAnimationValue>>& aValues) { mLock.AssertCurrentThreadOwns(); MOZ_ASSERT(!aValues.IsEmpty()); bool janked = false; HostLayer* layerCompositor = aLayer->AsHostLayer(); switch (aProperty) { case eCSSProperty_background_color: { MOZ_ASSERT(aValues.Length() == 1); // We don't support 'color' animations on the compositor yet so we never // meet currentColor on the compositor. nscolor color = Servo_AnimationValue_GetColor(aValues[0], NS_RGBA(0, 0, 0, 0)); aLayer->AsColorLayer()->SetColor(gfx::ToDeviceColor(color)); SetAnimatedValue(aLayer->GetCompositorAnimationsId(), aPreviousValue, color); layerCompositor->SetShadowOpacity(aLayer->GetOpacity()); layerCompositor->SetShadowOpacitySetByAnimation(false); layerCompositor->SetShadowBaseTransform(aLayer->GetBaseTransform()); layerCompositor->SetShadowTransformSetByAnimation(false); break; } case eCSSProperty_opacity: { MOZ_ASSERT(aValues.Length() == 1); float opacity = Servo_AnimationValue_GetOpacity(aValues[0]); layerCompositor->SetShadowOpacity(opacity); layerCompositor->SetShadowOpacitySetByAnimation(true); SetAnimatedValue(aLayer->GetCompositorAnimationsId(), aPreviousValue, opacity); layerCompositor->SetShadowBaseTransform(aLayer->GetBaseTransform()); layerCompositor->SetShadowTransformSetByAnimation(false); break; } case eCSSProperty_rotate: case eCSSProperty_scale: case eCSSProperty_translate: case eCSSProperty_transform: case eCSSProperty_offset_path: case eCSSProperty_offset_distance: case eCSSProperty_offset_rotate: case eCSSProperty_offset_anchor: { MOZ_ASSERT(aLayer->GetTransformData()); const TransformData& transformData = *aLayer->GetTransformData(); gfx::Matrix4x4 frameTransform = AnimationHelper::ServoAnimationValueToMatrix4x4( aValues, transformData, aLayer->CachedMotionPath()); gfx::Matrix4x4 transform = FrameTransformToTransformInDevice( frameTransform, aLayer, transformData); if (const Maybe<PartialPrerenderData>& partialPrerenderData = transformData.partialPrerenderData()) { Matrix4x4 transformInClip = GetTransformForPartialPrerender( aLayer, aLayer->GetAnimationLayersId(), partialPrerenderData->scrollId(), aCompositorBridge->GetAPZSampler()); transformInClip = transform * transformInClip; ParentLayerRect clipRect = GetClipRectForPartialPrerender( aLayer->GetAnimationLayersId(), *partialPrerenderData, aCompositorBridge->GetAPZSampler()); if (AnimationHelper::ShouldBeJank( partialPrerenderData->rect(), partialPrerenderData->overflowedSides(), transformInClip, clipRect)) { // It's possible that we don't have the previous value and we don't // either have enough area to composite in the first composition, // e.g. a translate animation with a step timing function. In such // cases we use the base transform value which was calculated on the // main-thread as a fallback value. transform = aPreviousValue ? aPreviousValue->Transform().mTransformInDevSpace : aLayer->GetBaseTransform(); janked = true; } } layerCompositor->SetShadowBaseTransform(transform); layerCompositor->SetShadowTransformSetByAnimation(true); SetAnimatedValue(aLayer->GetCompositorAnimationsId(), aPreviousValue, transform, frameTransform, transformData); layerCompositor->SetShadowOpacity(aLayer->GetOpacity()); layerCompositor->SetShadowOpacitySetByAnimation(false); break; } default: MOZ_ASSERT_UNREACHABLE("Unhandled animated property"); } return !janked; } bool CompositorAnimationStorage::SampleAnimations( Layer* aRoot, CompositorBridgeParent* aCompositorBridge, TimeStamp aPreviousFrameTime, TimeStamp aCurrentFrameTime) { MutexAutoLock lock(mLock); bool isAnimating = false; auto autoClearAnimationStorage = MakeScopeExit([&] { if (!isAnimating) { // Clean up the CompositorAnimationStorage because // there are no active animations running Clear(); } }); std::unordered_map<LayersId, nsTArray<uint64_t>, LayersId::HashFn> janked; ForEachNode<ForwardIterator>(aRoot, [&](Layer* layer) { auto& propertyAnimationGroups = layer->GetPropertyAnimationGroups(); if (propertyAnimationGroups.IsEmpty()) { return; } isAnimating = true; AnimatedValue* previousValue = GetAnimatedValue(layer->GetCompositorAnimationsId()); AutoTArray<RefPtr<RawServoAnimationValue>, 1> animationValues; AnimationHelper::SampleResult sampleResult = AnimationHelper::SampleAnimationForEachNode( aPreviousFrameTime, aCurrentFrameTime, previousValue, propertyAnimationGroups, animationValues); const PropertyAnimationGroup& lastPropertyAnimationGroup = propertyAnimationGroups.LastElement(); switch (sampleResult) { case AnimationHelper::SampleResult::Sampled: // We assume all transform like properties (on the same frame) live in // a single same layer, so using the transform data of the last element // should be fine. if (!ApplyAnimatedValue(aCompositorBridge, layer, lastPropertyAnimationGroup.mProperty, previousValue, animationValues)) { // Reset the last composition values in cases of jank so that we will // never mis-compare in a sanity check in the case of // SampleResult::Skipped below in this function. // // An example; // a translateX(0px) -> translateX(100px) animation with step(2,start) // and if the animation janked at translateX(50px) and in a later // frame if the calculated transform value is going to be still // translateX(50px) (i.e. at the same timing portion calculated by the // step timing function), we skip sampling. That's correct ideally. // But we have an assertion to do a sanity check for the skip sampling // case that the check compares the calculated value translateX(50px) // with the previous composited value. In this case the previous // composited value is translateX(0px). // // NOTE: Ideally we shouldn't update the last composition values when // we met janks, but it's quite hard to tell whether the jank will // happen or not when we calculate each transform like properties' // value (i.e. when we set the last composition value) since janks are // caused by a result of the combinations of all transform like // properties (e.g. `transform: translateX(50px)` and // `translate: -50px` results `translateX(0px)`. for (PropertyAnimationGroup& group : propertyAnimationGroups) { group.ResetLastCompositionValues(); } janked[layer->GetAnimationLayersId()].AppendElement( layer->GetCompositorAnimationsId()); } break; case AnimationHelper::SampleResult::Skipped: switch (lastPropertyAnimationGroup.mProperty) { case eCSSProperty_background_color: case eCSSProperty_opacity: { if (lastPropertyAnimationGroup.mProperty == eCSSProperty_opacity) { MOZ_ASSERT( layer->AsHostLayer()->GetShadowOpacitySetByAnimation()); #ifdef DEBUG // Disable this assertion until the root cause is fixed in bug // 1459775. // MOZ_ASSERT(FuzzyEqualsMultiplicative( // Servo_AnimationValue_GetOpacity(animationValue), // *(GetAnimationOpacity(layer->GetCompositorAnimationsId())))); #endif } // Even if opacity or background-color animation value has // unchanged, we have to set the shadow base transform value // here since the value might have been changed by APZC. HostLayer* layerCompositor = layer->AsHostLayer(); layerCompositor->SetShadowBaseTransform(layer->GetBaseTransform()); layerCompositor->SetShadowTransformSetByAnimation(false); break; } case eCSSProperty_rotate: case eCSSProperty_scale: case eCSSProperty_translate: case eCSSProperty_transform: case eCSSProperty_offset_path: case eCSSProperty_offset_distance: case eCSSProperty_offset_rotate: case eCSSProperty_offset_anchor: { MOZ_ASSERT( layer->AsHostLayer()->GetShadowTransformSetByAnimation()); MOZ_ASSERT(previousValue); MOZ_ASSERT(layer->GetTransformData()); #ifdef DEBUG gfx::Matrix4x4 frameTransform = AnimationHelper::ServoAnimationValueToMatrix4x4( animationValues, *layer->GetTransformData(), layer->CachedMotionPath()); gfx::Matrix4x4 transformInDevice = FrameTransformToTransformInDevice(frameTransform, layer, *layer->GetTransformData()); MOZ_ASSERT(previousValue->Transform() .mTransformInDevSpace.FuzzyEqualsMultiplicative( transformInDevice)); #endif // In the case of transform we have to set the unchanged // transform value again because APZC might have modified the // previous shadow base transform value. HostLayer* layerCompositor = layer->AsHostLayer(); layerCompositor->SetShadowBaseTransform( // FIXME: Bug 1459775: It seems possible that we somehow try // to sample animations and skip it even if the previous value // has been discarded from the animation storage when we enable // layer tree cache. So for the safety, in the case where we // have no previous animation value, we set non-animating value // instead. previousValue ? previousValue->Transform().mTransformInDevSpace : layer->GetBaseTransform()); break; } default: MOZ_ASSERT_UNREACHABLE("Unsupported properties"); break; } break; case AnimationHelper::SampleResult::None: { HostLayer* layerCompositor = layer->AsHostLayer(); layerCompositor->SetShadowBaseTransform(layer->GetBaseTransform()); layerCompositor->SetShadowTransformSetByAnimation(false); layerCompositor->SetShadowOpacity(layer->GetOpacity()); layerCompositor->SetShadowOpacitySetByAnimation(false); break; } default: break; } }); if (!janked.empty()) { aCompositorBridge->NotifyJankedAnimations(janked); } return isAnimating; } } // namespace layers } // namespace mozilla gfx/layers/CompositorAnimationStorage.h +0 −15 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ namespace mozilla { namespace layers { class Animation; class CompositorBridgeParent; class Layer; class OMTAController; typedef nsTArray<layers::Animation> AnimationArray; Loading Loading @@ -157,15 +156,6 @@ class CompositorAnimationStorage final { TimeStamp aPreviousFrameTime, TimeStamp aCurrentFrameTime); /** * Non WebRender version of above SampleAnimations. * * Note: This is called only by non WebRender. */ bool SampleAnimations(Layer* aRoot, CompositorBridgeParent* aCompositorBridge, TimeStamp aPreviousFrameTime, TimeStamp aCurrentFrameTime); bool HasAnimations() const; /** Loading Loading @@ -214,11 +204,6 @@ class CompositorAnimationStorage final { void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue, nscolor aColor); bool ApplyAnimatedValue( CompositorBridgeParent* aCompositorBridge, Layer* aLayer, nsCSSPropertyID aProperty, AnimatedValue* aPreviousValue, const nsTArray<RefPtr<RawServoAnimationValue>>& aValues); void Clear(); private: Loading gfx/layers/LayerManager.h +0 −6 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ namespace layers { class AsyncPanZoomController; class ClientLayerManager; class HostLayerManager; class Layer; class LayerMetricsWrapper; class PaintedLayer; Loading @@ -72,7 +71,6 @@ class RefLayer; class HostLayer; class FocusTarget; class KnowsCompositor; class LayerManagerComposite; class TransactionIdAllocator; class FrameUniformityData; class PersistentBufferProvider; Loading Loading @@ -160,10 +158,6 @@ class LayerManager : public WindowRenderer { virtual LayerManager* AsLayerManager() override { return this; } virtual LayerManagerComposite* AsLayerManagerComposite() { return nullptr; } virtual HostLayerManager* AsHostLayerManager() { return nullptr; } virtual WebRenderLayerManager* AsWebRenderLayerManager() { return nullptr; } /** Loading gfx/layers/LayerScope.cpp +0 −63 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ #include "mozilla/layers/CompositorOGL.h" #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/LayerManagerComposite.h" #include "mozilla/layers/TextureHostOGL.h" #include "gfxContext.h" Loading Loading @@ -741,8 +740,6 @@ NS_IMPL_ISUPPORTS(DebugDataSender::SendTask, nsIRunnable); class SenderHelper { // Sender public APIs public: static void SendLayer(LayerComposite* aLayer, int aWidth, int aHeight); static void SendEffectChain(gl::GLContext* aGLContext, const EffectChain& aEffectChain, int aWidth = 0, int aHeight = 0); Loading Loading @@ -796,47 +793,6 @@ bool SenderHelper::HasTextureIdBeenSent(GLuint aTextureId) { aTextureId) != sSentTextureIds.end(); } void SenderHelper::SendLayer(LayerComposite* aLayer, int aWidth, int aHeight) { MOZ_ASSERT(aLayer && aLayer->GetLayer()); if (!aLayer || !aLayer->GetLayer()) { return; } switch (aLayer->GetLayer()->GetType()) { case Layer::TYPE_COLOR: { EffectChain effect; aLayer->GenEffectChain(effect); LayerScope::DrawBegin(); LayerScope::DrawEnd(nullptr, effect, aWidth, aHeight); break; } case Layer::TYPE_IMAGE: case Layer::TYPE_CANVAS: case Layer::TYPE_PAINTED: { // Get CompositableHost and Compositor CompositableHost* compHost = aLayer->GetCompositableHost(); TextureSourceProvider* provider = compHost->GetTextureSourceProvider(); Compositor* comp = provider->AsCompositor(); // Send EffectChain only for CompositorOGL if (LayersBackend::LAYERS_OPENGL == comp->GetBackendType()) { CompositorOGL* compOGL = comp->AsCompositorOGL(); EffectChain effect; // Generate primary effect (lock and gen) AutoLockCompositableHost lock(compHost); aLayer->GenEffectChain(effect); LayerScope::DrawBegin(); LayerScope::DrawEnd(compOGL->gl(), effect, aWidth, aHeight); } break; } case Layer::TYPE_CONTAINER: default: break; } } void SenderHelper::SendColor(void* aLayerRef, const DeviceColor& aColor, int aWidth, int aHeight) { gLayerScopeManager.GetSocketManager()->AppendDebugData( Loading Loading @@ -1540,25 +1496,6 @@ void LayerScope::DrawEnd(gl::GLContext* aGLContext, draws.mTexIDs, aEffectChain.mLayerRef)); } /*static*/ void LayerScope::SendLayer(LayerComposite* aLayer, int aWidth, int aHeight) { // Protect this public function if (!CheckSendable()) { return; } SenderHelper::SendLayer(aLayer, aWidth, aHeight); } /*static*/ void LayerScope::SendLayerDump(UniquePtr<Packet> aPacket) { // Protect this public function if (!CheckSendable() || !SenderHelper::GetLayersTreeSendable()) { return; } gLayerScopeManager.GetSocketManager()->AppendDebugData( new DebugGLLayersData(std::move(aPacket))); } /*static*/ bool LayerScope::CheckSendable() { // Only compositor threads check LayerScope status Loading Loading
gfx/layers/Compositor.h +0 −1 Original line number Diff line number Diff line Loading @@ -130,7 +130,6 @@ class TextureSource; class DataTextureSource; class CompositingRenderTarget; class CompositorBridgeParent; class LayerManagerComposite; class NativeLayer; class CompositorOGL; class CompositorD3D11; Loading
gfx/layers/CompositorAnimationStorage.cpp +3 −336 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ #include "mozilla/layers/APZSampler.h" // for APZSampler #include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent #include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder #include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite, etc #include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper #include "mozilla/layers/OMTAController.h" // for OMTAController #include "mozilla/ScopeExit.h" Loading Loading @@ -341,337 +340,5 @@ WrAnimations CompositorAnimationStorage::CollectWebRenderAnimations() const { return animations; } static gfx::Matrix4x4 FrameTransformToTransformInDevice( const gfx::Matrix4x4& aFrameTransform, Layer* aLayer, const TransformData& aTransformData) { gfx::Matrix4x4 transformInDevice = aFrameTransform; // If our parent layer is a perspective layer, then the offset into reference // frame coordinates is already on that layer. If not, then we need to ask // for it to be added here. if (!aLayer->GetParent() || !aLayer->GetParent()->GetTransformIsPerspective()) { nsLayoutUtils::PostTranslate( transformInDevice, aTransformData.origin(), aTransformData.appUnitsPerDevPixel(), aLayer->GetContentFlags() & Layer::CONTENT_SNAP_TO_GRID); } if (ContainerLayer* c = aLayer->AsContainerLayer()) { transformInDevice.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1); } return transformInDevice; } static Matrix4x4 GetTransformForPartialPrerender( Layer* aLayer, const LayersId aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, const RefPtr<APZSampler>& aSampler) { MOZ_ASSERT(aLayer); ParentLayerPoint translationByApz; Matrix4x4 transform; for (Layer* layer = aLayer; layer; layer = layer->GetParent()) { if (layer->AsRefLayer()) { MOZ_ASSERT(layer->AsRefLayer()->GetReferentId() == aLayersId); break; } // Accumulate static transforms. if (layer != aLayer) { Matrix4x4 baseTransform = layer->GetBaseTransform(); if (ContainerLayer* container = layer->AsContainerLayer()) { baseTransform.PostScale(container->GetPreXScale(), container->GetPreYScale(), 1); } transform *= baseTransform; } if (!layer->GetIsStickyPosition() && !layer->GetIsFixedPosition()) { bool hasSameScrollId = false; for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) { // Factor APZ translation if there exists. if (aSampler) { LayerMetricsWrapper wrapper = LayerMetricsWrapper(layer, i); AsyncTransform asyncTransform = aSampler->GetCurrentAsyncTransform(wrapper, LayoutAndVisual); translationByApz += asyncTransform.mTranslation; } if (layer->GetFrameMetrics(i).GetScrollId() == aScrollId) { hasSameScrollId = true; } } if (hasSameScrollId) { break; } } else { // Bug 1642547: Fix for position:sticky layers. } } transform.PostTranslate(translationByApz.ToUnknownPoint()); return transform; } bool CompositorAnimationStorage::ApplyAnimatedValue( CompositorBridgeParent* aCompositorBridge, Layer* aLayer, nsCSSPropertyID aProperty, AnimatedValue* aPreviousValue, const nsTArray<RefPtr<RawServoAnimationValue>>& aValues) { mLock.AssertCurrentThreadOwns(); MOZ_ASSERT(!aValues.IsEmpty()); bool janked = false; HostLayer* layerCompositor = aLayer->AsHostLayer(); switch (aProperty) { case eCSSProperty_background_color: { MOZ_ASSERT(aValues.Length() == 1); // We don't support 'color' animations on the compositor yet so we never // meet currentColor on the compositor. nscolor color = Servo_AnimationValue_GetColor(aValues[0], NS_RGBA(0, 0, 0, 0)); aLayer->AsColorLayer()->SetColor(gfx::ToDeviceColor(color)); SetAnimatedValue(aLayer->GetCompositorAnimationsId(), aPreviousValue, color); layerCompositor->SetShadowOpacity(aLayer->GetOpacity()); layerCompositor->SetShadowOpacitySetByAnimation(false); layerCompositor->SetShadowBaseTransform(aLayer->GetBaseTransform()); layerCompositor->SetShadowTransformSetByAnimation(false); break; } case eCSSProperty_opacity: { MOZ_ASSERT(aValues.Length() == 1); float opacity = Servo_AnimationValue_GetOpacity(aValues[0]); layerCompositor->SetShadowOpacity(opacity); layerCompositor->SetShadowOpacitySetByAnimation(true); SetAnimatedValue(aLayer->GetCompositorAnimationsId(), aPreviousValue, opacity); layerCompositor->SetShadowBaseTransform(aLayer->GetBaseTransform()); layerCompositor->SetShadowTransformSetByAnimation(false); break; } case eCSSProperty_rotate: case eCSSProperty_scale: case eCSSProperty_translate: case eCSSProperty_transform: case eCSSProperty_offset_path: case eCSSProperty_offset_distance: case eCSSProperty_offset_rotate: case eCSSProperty_offset_anchor: { MOZ_ASSERT(aLayer->GetTransformData()); const TransformData& transformData = *aLayer->GetTransformData(); gfx::Matrix4x4 frameTransform = AnimationHelper::ServoAnimationValueToMatrix4x4( aValues, transformData, aLayer->CachedMotionPath()); gfx::Matrix4x4 transform = FrameTransformToTransformInDevice( frameTransform, aLayer, transformData); if (const Maybe<PartialPrerenderData>& partialPrerenderData = transformData.partialPrerenderData()) { Matrix4x4 transformInClip = GetTransformForPartialPrerender( aLayer, aLayer->GetAnimationLayersId(), partialPrerenderData->scrollId(), aCompositorBridge->GetAPZSampler()); transformInClip = transform * transformInClip; ParentLayerRect clipRect = GetClipRectForPartialPrerender( aLayer->GetAnimationLayersId(), *partialPrerenderData, aCompositorBridge->GetAPZSampler()); if (AnimationHelper::ShouldBeJank( partialPrerenderData->rect(), partialPrerenderData->overflowedSides(), transformInClip, clipRect)) { // It's possible that we don't have the previous value and we don't // either have enough area to composite in the first composition, // e.g. a translate animation with a step timing function. In such // cases we use the base transform value which was calculated on the // main-thread as a fallback value. transform = aPreviousValue ? aPreviousValue->Transform().mTransformInDevSpace : aLayer->GetBaseTransform(); janked = true; } } layerCompositor->SetShadowBaseTransform(transform); layerCompositor->SetShadowTransformSetByAnimation(true); SetAnimatedValue(aLayer->GetCompositorAnimationsId(), aPreviousValue, transform, frameTransform, transformData); layerCompositor->SetShadowOpacity(aLayer->GetOpacity()); layerCompositor->SetShadowOpacitySetByAnimation(false); break; } default: MOZ_ASSERT_UNREACHABLE("Unhandled animated property"); } return !janked; } bool CompositorAnimationStorage::SampleAnimations( Layer* aRoot, CompositorBridgeParent* aCompositorBridge, TimeStamp aPreviousFrameTime, TimeStamp aCurrentFrameTime) { MutexAutoLock lock(mLock); bool isAnimating = false; auto autoClearAnimationStorage = MakeScopeExit([&] { if (!isAnimating) { // Clean up the CompositorAnimationStorage because // there are no active animations running Clear(); } }); std::unordered_map<LayersId, nsTArray<uint64_t>, LayersId::HashFn> janked; ForEachNode<ForwardIterator>(aRoot, [&](Layer* layer) { auto& propertyAnimationGroups = layer->GetPropertyAnimationGroups(); if (propertyAnimationGroups.IsEmpty()) { return; } isAnimating = true; AnimatedValue* previousValue = GetAnimatedValue(layer->GetCompositorAnimationsId()); AutoTArray<RefPtr<RawServoAnimationValue>, 1> animationValues; AnimationHelper::SampleResult sampleResult = AnimationHelper::SampleAnimationForEachNode( aPreviousFrameTime, aCurrentFrameTime, previousValue, propertyAnimationGroups, animationValues); const PropertyAnimationGroup& lastPropertyAnimationGroup = propertyAnimationGroups.LastElement(); switch (sampleResult) { case AnimationHelper::SampleResult::Sampled: // We assume all transform like properties (on the same frame) live in // a single same layer, so using the transform data of the last element // should be fine. if (!ApplyAnimatedValue(aCompositorBridge, layer, lastPropertyAnimationGroup.mProperty, previousValue, animationValues)) { // Reset the last composition values in cases of jank so that we will // never mis-compare in a sanity check in the case of // SampleResult::Skipped below in this function. // // An example; // a translateX(0px) -> translateX(100px) animation with step(2,start) // and if the animation janked at translateX(50px) and in a later // frame if the calculated transform value is going to be still // translateX(50px) (i.e. at the same timing portion calculated by the // step timing function), we skip sampling. That's correct ideally. // But we have an assertion to do a sanity check for the skip sampling // case that the check compares the calculated value translateX(50px) // with the previous composited value. In this case the previous // composited value is translateX(0px). // // NOTE: Ideally we shouldn't update the last composition values when // we met janks, but it's quite hard to tell whether the jank will // happen or not when we calculate each transform like properties' // value (i.e. when we set the last composition value) since janks are // caused by a result of the combinations of all transform like // properties (e.g. `transform: translateX(50px)` and // `translate: -50px` results `translateX(0px)`. for (PropertyAnimationGroup& group : propertyAnimationGroups) { group.ResetLastCompositionValues(); } janked[layer->GetAnimationLayersId()].AppendElement( layer->GetCompositorAnimationsId()); } break; case AnimationHelper::SampleResult::Skipped: switch (lastPropertyAnimationGroup.mProperty) { case eCSSProperty_background_color: case eCSSProperty_opacity: { if (lastPropertyAnimationGroup.mProperty == eCSSProperty_opacity) { MOZ_ASSERT( layer->AsHostLayer()->GetShadowOpacitySetByAnimation()); #ifdef DEBUG // Disable this assertion until the root cause is fixed in bug // 1459775. // MOZ_ASSERT(FuzzyEqualsMultiplicative( // Servo_AnimationValue_GetOpacity(animationValue), // *(GetAnimationOpacity(layer->GetCompositorAnimationsId())))); #endif } // Even if opacity or background-color animation value has // unchanged, we have to set the shadow base transform value // here since the value might have been changed by APZC. HostLayer* layerCompositor = layer->AsHostLayer(); layerCompositor->SetShadowBaseTransform(layer->GetBaseTransform()); layerCompositor->SetShadowTransformSetByAnimation(false); break; } case eCSSProperty_rotate: case eCSSProperty_scale: case eCSSProperty_translate: case eCSSProperty_transform: case eCSSProperty_offset_path: case eCSSProperty_offset_distance: case eCSSProperty_offset_rotate: case eCSSProperty_offset_anchor: { MOZ_ASSERT( layer->AsHostLayer()->GetShadowTransformSetByAnimation()); MOZ_ASSERT(previousValue); MOZ_ASSERT(layer->GetTransformData()); #ifdef DEBUG gfx::Matrix4x4 frameTransform = AnimationHelper::ServoAnimationValueToMatrix4x4( animationValues, *layer->GetTransformData(), layer->CachedMotionPath()); gfx::Matrix4x4 transformInDevice = FrameTransformToTransformInDevice(frameTransform, layer, *layer->GetTransformData()); MOZ_ASSERT(previousValue->Transform() .mTransformInDevSpace.FuzzyEqualsMultiplicative( transformInDevice)); #endif // In the case of transform we have to set the unchanged // transform value again because APZC might have modified the // previous shadow base transform value. HostLayer* layerCompositor = layer->AsHostLayer(); layerCompositor->SetShadowBaseTransform( // FIXME: Bug 1459775: It seems possible that we somehow try // to sample animations and skip it even if the previous value // has been discarded from the animation storage when we enable // layer tree cache. So for the safety, in the case where we // have no previous animation value, we set non-animating value // instead. previousValue ? previousValue->Transform().mTransformInDevSpace : layer->GetBaseTransform()); break; } default: MOZ_ASSERT_UNREACHABLE("Unsupported properties"); break; } break; case AnimationHelper::SampleResult::None: { HostLayer* layerCompositor = layer->AsHostLayer(); layerCompositor->SetShadowBaseTransform(layer->GetBaseTransform()); layerCompositor->SetShadowTransformSetByAnimation(false); layerCompositor->SetShadowOpacity(layer->GetOpacity()); layerCompositor->SetShadowOpacitySetByAnimation(false); break; } default: break; } }); if (!janked.empty()) { aCompositorBridge->NotifyJankedAnimations(janked); } return isAnimating; } } // namespace layers } // namespace mozilla
gfx/layers/CompositorAnimationStorage.h +0 −15 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ namespace mozilla { namespace layers { class Animation; class CompositorBridgeParent; class Layer; class OMTAController; typedef nsTArray<layers::Animation> AnimationArray; Loading Loading @@ -157,15 +156,6 @@ class CompositorAnimationStorage final { TimeStamp aPreviousFrameTime, TimeStamp aCurrentFrameTime); /** * Non WebRender version of above SampleAnimations. * * Note: This is called only by non WebRender. */ bool SampleAnimations(Layer* aRoot, CompositorBridgeParent* aCompositorBridge, TimeStamp aPreviousFrameTime, TimeStamp aCurrentFrameTime); bool HasAnimations() const; /** Loading Loading @@ -214,11 +204,6 @@ class CompositorAnimationStorage final { void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue, nscolor aColor); bool ApplyAnimatedValue( CompositorBridgeParent* aCompositorBridge, Layer* aLayer, nsCSSPropertyID aProperty, AnimatedValue* aPreviousValue, const nsTArray<RefPtr<RawServoAnimationValue>>& aValues); void Clear(); private: Loading
gfx/layers/LayerManager.h +0 −6 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ namespace layers { class AsyncPanZoomController; class ClientLayerManager; class HostLayerManager; class Layer; class LayerMetricsWrapper; class PaintedLayer; Loading @@ -72,7 +71,6 @@ class RefLayer; class HostLayer; class FocusTarget; class KnowsCompositor; class LayerManagerComposite; class TransactionIdAllocator; class FrameUniformityData; class PersistentBufferProvider; Loading Loading @@ -160,10 +158,6 @@ class LayerManager : public WindowRenderer { virtual LayerManager* AsLayerManager() override { return this; } virtual LayerManagerComposite* AsLayerManagerComposite() { return nullptr; } virtual HostLayerManager* AsHostLayerManager() { return nullptr; } virtual WebRenderLayerManager* AsWebRenderLayerManager() { return nullptr; } /** Loading
gfx/layers/LayerScope.cpp +0 −63 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ #include "mozilla/layers/CompositorOGL.h" #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/LayerManagerComposite.h" #include "mozilla/layers/TextureHostOGL.h" #include "gfxContext.h" Loading Loading @@ -741,8 +740,6 @@ NS_IMPL_ISUPPORTS(DebugDataSender::SendTask, nsIRunnable); class SenderHelper { // Sender public APIs public: static void SendLayer(LayerComposite* aLayer, int aWidth, int aHeight); static void SendEffectChain(gl::GLContext* aGLContext, const EffectChain& aEffectChain, int aWidth = 0, int aHeight = 0); Loading Loading @@ -796,47 +793,6 @@ bool SenderHelper::HasTextureIdBeenSent(GLuint aTextureId) { aTextureId) != sSentTextureIds.end(); } void SenderHelper::SendLayer(LayerComposite* aLayer, int aWidth, int aHeight) { MOZ_ASSERT(aLayer && aLayer->GetLayer()); if (!aLayer || !aLayer->GetLayer()) { return; } switch (aLayer->GetLayer()->GetType()) { case Layer::TYPE_COLOR: { EffectChain effect; aLayer->GenEffectChain(effect); LayerScope::DrawBegin(); LayerScope::DrawEnd(nullptr, effect, aWidth, aHeight); break; } case Layer::TYPE_IMAGE: case Layer::TYPE_CANVAS: case Layer::TYPE_PAINTED: { // Get CompositableHost and Compositor CompositableHost* compHost = aLayer->GetCompositableHost(); TextureSourceProvider* provider = compHost->GetTextureSourceProvider(); Compositor* comp = provider->AsCompositor(); // Send EffectChain only for CompositorOGL if (LayersBackend::LAYERS_OPENGL == comp->GetBackendType()) { CompositorOGL* compOGL = comp->AsCompositorOGL(); EffectChain effect; // Generate primary effect (lock and gen) AutoLockCompositableHost lock(compHost); aLayer->GenEffectChain(effect); LayerScope::DrawBegin(); LayerScope::DrawEnd(compOGL->gl(), effect, aWidth, aHeight); } break; } case Layer::TYPE_CONTAINER: default: break; } } void SenderHelper::SendColor(void* aLayerRef, const DeviceColor& aColor, int aWidth, int aHeight) { gLayerScopeManager.GetSocketManager()->AppendDebugData( Loading Loading @@ -1540,25 +1496,6 @@ void LayerScope::DrawEnd(gl::GLContext* aGLContext, draws.mTexIDs, aEffectChain.mLayerRef)); } /*static*/ void LayerScope::SendLayer(LayerComposite* aLayer, int aWidth, int aHeight) { // Protect this public function if (!CheckSendable()) { return; } SenderHelper::SendLayer(aLayer, aWidth, aHeight); } /*static*/ void LayerScope::SendLayerDump(UniquePtr<Packet> aPacket) { // Protect this public function if (!CheckSendable() || !SenderHelper::GetLayersTreeSendable()) { return; } gLayerScopeManager.GetSocketManager()->AppendDebugData( new DebugGLLayersData(std::move(aPacket))); } /*static*/ bool LayerScope::CheckSendable() { // Only compositor threads check LayerScope status Loading