summaryrefslogtreecommitdiffstats
path: root/gfx/layers/LayerManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/layers/LayerManager.cpp216
1 files changed, 216 insertions, 0 deletions
diff --git a/gfx/layers/LayerManager.cpp b/gfx/layers/LayerManager.cpp
new file mode 100644
index 0000000000..a701aa1674
--- /dev/null
+++ b/gfx/layers/LayerManager.cpp
@@ -0,0 +1,216 @@
+/* -*- 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 "mozilla/layers/LayerManager.h"
+
+#include <stdint.h> // for uint64_t, uint8_t
+#include <stdlib.h> // for abort
+#include <algorithm> // for copy, copy_backward
+#include <utility> // for move, forward
+#include "FrameMetrics.h" // for FrameMetrics
+#include "ImageContainer.h" // for ImageContainer, ImageContainer::Mode
+#include "LayerUserData.h" // for LayerUserData
+#include "Layers.h" // for RecordCompositionPayloadsPresented, Layer
+#include "TreeTraversal.h" // for ForwardIterator, BreadthFirstSearch
+#include "gfxPlatform.h" // for gfxPlatform
+#include "mozilla/AlreadyAddRefed.h" // for already_AddRefed
+#include "mozilla/ArrayIterator.h" // for ArrayIterator
+#include "mozilla/Assertions.h" // for AssertionConditionType, MOZ_ASSERT, MOZ_ASSERT_HELPER1
+#include "mozilla/EffectSet.h" // for EffectSet
+#include "mozilla/Logging.h" // for LazyLogModule, LogModule (ptr only)
+#include "mozilla/RefPtr.h" // for RefPtr, getter_AddRefs, RefPtrGetterAddRefs
+#include "mozilla/StaticPrefs_layers.h" // for layers_componentalpha_enabled_AtStartup_DoNotUseDirectly
+#include "mozilla/UniquePtr.h" // for UniquePtr
+#include "mozilla/dom/Animation.h" // for Animation
+#include "mozilla/dom/AnimationEffect.h" // for AnimationEffect
+#include "mozilla/gfx/Point.h" // for IntSize
+#include "mozilla/gfx/Types.h" // for SurfaceFormat, gfx
+#include "mozilla/gfx/UserData.h" // for UserData, UserDataKey (ptr only)
+#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
+#include "mozilla/layers/LayersTypes.h" // for CompositionPayload
+#include "mozilla/layers/PersistentBufferProvider.h" // for PersistentBufferProviderBasic, PersistentBufferProvider (ptr only)
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, ScrollableLayerGuid::NULL_SCROLL_ID, ScrollableLayerGu...
+#include "nsHashKeys.h" // for nsUint64HashKey
+#include "nsRefPtrHashtable.h" // for nsRefPtrHashtable
+#include "nsTArray.h" // for nsTArray
+
+uint8_t gLayerManagerLayerBuilder;
+
+// Undo the damage done by mozzconf.h
+#undef compress
+#include "mozilla/Compression.h"
+
+namespace mozilla {
+namespace layers {
+
+using namespace mozilla::gfx;
+using namespace mozilla::Compression;
+
+//--------------------------------------------------
+// LayerManager
+
+LayerManager::LayerManager()
+ : mDestroyed(false),
+ mSnapEffectiveTransforms(true),
+ mId(0),
+ mInTransaction(false),
+ mContainsSVG(false),
+ mPaintedPixelCount(0) {}
+
+LayerManager::~LayerManager() = default;
+
+void LayerManager::Destroy() {
+ mDestroyed = true;
+ mUserData.Destroy();
+ mRoot = nullptr;
+ mPartialPrerenderedAnimations.Clear();
+}
+
+/* static */ mozilla::LogModule* LayerManager::GetLog() {
+ static LazyLogModule sLog("Layers");
+ return sLog;
+}
+
+ScrollableLayerGuid::ViewID LayerManager::GetRootScrollableLayerId() {
+ if (!mRoot) {
+ return ScrollableLayerGuid::NULL_SCROLL_ID;
+ }
+
+ LayerMetricsWrapper layerMetricsRoot = LayerMetricsWrapper(mRoot);
+
+ LayerMetricsWrapper rootScrollableLayerMetrics =
+ BreadthFirstSearch<ForwardIterator>(
+ layerMetricsRoot, [](LayerMetricsWrapper aLayerMetrics) {
+ return aLayerMetrics.Metrics().IsScrollable();
+ });
+
+ return rootScrollableLayerMetrics.IsValid()
+ ? rootScrollableLayerMetrics.Metrics().GetScrollId()
+ : ScrollableLayerGuid::NULL_SCROLL_ID;
+}
+
+LayerMetricsWrapper LayerManager::GetRootContentLayer() {
+ if (!mRoot) {
+ return LayerMetricsWrapper();
+ }
+
+ LayerMetricsWrapper root(mRoot);
+
+ return BreadthFirstSearch<ForwardIterator>(
+ root, [](LayerMetricsWrapper aLayerMetrics) {
+ return aLayerMetrics.Metrics().IsRootContent();
+ });
+}
+
+already_AddRefed<DrawTarget> LayerManager::CreateOptimalDrawTarget(
+ const gfx::IntSize& aSize, SurfaceFormat aFormat) {
+ return gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(aSize,
+ aFormat);
+}
+
+already_AddRefed<DrawTarget> LayerManager::CreateOptimalMaskDrawTarget(
+ const gfx::IntSize& aSize) {
+ return CreateOptimalDrawTarget(aSize, SurfaceFormat::A8);
+}
+
+already_AddRefed<DrawTarget> LayerManager::CreateDrawTarget(
+ const IntSize& aSize, SurfaceFormat aFormat) {
+ return gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(aSize,
+ aFormat);
+}
+
+already_AddRefed<PersistentBufferProvider>
+LayerManager::CreatePersistentBufferProvider(
+ const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat) {
+ RefPtr<PersistentBufferProviderBasic> bufferProvider =
+ PersistentBufferProviderBasic::Create(
+ aSize, aFormat,
+ gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
+
+ if (!bufferProvider) {
+ bufferProvider = PersistentBufferProviderBasic::Create(
+ aSize, aFormat, gfxPlatform::GetPlatform()->GetFallbackCanvasBackend());
+ }
+
+ return bufferProvider.forget();
+}
+
+already_AddRefed<ImageContainer> LayerManager::CreateImageContainer(
+ ImageContainer::Mode flag) {
+ RefPtr<ImageContainer> container = new ImageContainer(flag);
+ return container.forget();
+}
+
+bool LayerManager::LayersComponentAlphaEnabled() {
+ // If MOZ_GFX_OPTIMIZE_MOBILE is defined, we force component alpha off
+ // and ignore the preference.
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+ return false;
+#else
+ return StaticPrefs::
+ layers_componentalpha_enabled_AtStartup_DoNotUseDirectly();
+#endif
+}
+
+bool LayerManager::AreComponentAlphaLayersEnabled() {
+ return LayerManager::LayersComponentAlphaEnabled();
+}
+
+/*static*/
+void LayerManager::LayerUserDataDestroy(void* data) {
+ delete static_cast<LayerUserData*>(data);
+}
+
+UniquePtr<LayerUserData> LayerManager::RemoveUserData(void* aKey) {
+ UniquePtr<LayerUserData> d(static_cast<LayerUserData*>(
+ mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
+ return d;
+}
+
+void LayerManager::PayloadPresented(const TimeStamp& aTimeStamp) {
+ RecordCompositionPayloadsPresented(aTimeStamp, mPayload);
+}
+
+void LayerManager::AddPartialPrerenderedAnimation(
+ uint64_t aCompositorAnimationId, dom::Animation* aAnimation) {
+ mPartialPrerenderedAnimations.Put(aCompositorAnimationId, RefPtr{aAnimation});
+ aAnimation->SetPartialPrerendered(aCompositorAnimationId);
+}
+
+void LayerManager::RemovePartialPrerenderedAnimation(
+ uint64_t aCompositorAnimationId, dom::Animation* aAnimation) {
+ MOZ_ASSERT(aAnimation);
+#ifdef DEBUG
+ RefPtr<dom::Animation> animation;
+ if (mPartialPrerenderedAnimations.Remove(aCompositorAnimationId,
+ getter_AddRefs(animation)) &&
+ // It may be possible that either animation's effect has already been
+ // nulled out via Animation::SetEffect() so ignore such cases.
+ aAnimation->GetEffect() && aAnimation->GetEffect()->AsKeyframeEffect() &&
+ animation->GetEffect() && animation->GetEffect()->AsKeyframeEffect()) {
+ MOZ_ASSERT(EffectSet::GetEffectSetForEffect(
+ aAnimation->GetEffect()->AsKeyframeEffect()) ==
+ EffectSet::GetEffectSetForEffect(
+ animation->GetEffect()->AsKeyframeEffect()));
+ }
+#else
+ mPartialPrerenderedAnimations.Remove(aCompositorAnimationId);
+#endif
+ aAnimation->ResetPartialPrerendered();
+}
+
+void LayerManager::UpdatePartialPrerenderedAnimations(
+ const nsTArray<uint64_t>& aJankedAnimations) {
+ for (uint64_t id : aJankedAnimations) {
+ RefPtr<dom::Animation> animation;
+ if (mPartialPrerenderedAnimations.Remove(id, getter_AddRefs(animation))) {
+ animation->UpdatePartialPrerendered();
+ }
+ }
+}
+
+} // namespace layers
+} // namespace mozilla