Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  ContentCompositorBridgeParent.cpp

  Sprache: C
 

/* 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/ContentCompositorBridgeParent.h"

#include <stdint.h>  // for uint64_t

#include "apz/src/APZCTreeManager.h"  // for APZCTreeManager
#include "gfxUtils.h"
#ifdef XP_WIN
#  include "mozilla/gfx/DeviceManagerDx.h"  // for DeviceManagerDx
#  include "mozilla/layers/ImageDataSerializer.h"
#endif
#include "mozilla/layers/AnimationHelper.h"  // for CompositorAnimationStorage
#include "mozilla/layers/APZCTreeManagerParent.h"  // for APZCTreeManagerParent
#include "mozilla/layers/APZUpdater.h"             // for APZUpdater
#include "mozilla/layers/CompositorManagerParent.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/LayerTreeOwnerTracker.h"
#include "mozilla/layers/RemoteContentController.h"
#include "mozilla/layers/WebRenderBridgeParent.h"
#include "mozilla/layers/AsyncImagePipelineManager.h"
#include "mozilla/mozalloc.h"  // for operator new, etc
#include "nsDebug.h"           // for NS_ASSERTION, etc
#include "nsTArray.h"          // for nsTArray
#include "nsXULAppAPI.h"       // for XRE_GetAsyncIOEventTarget
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/BaseProfilerMarkerTypes.h"
#include "GeckoProfiler.h"

namespace mozilla::layers {

void EraseLayerState(LayersId aId);

void ContentCompositorBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
  mCanSend = false;

  // We must keep this object alive untill the code handling message
  // reception is finished on this thread.
  GetCurrentSerialEventTarget()->Dispatch(NewRunnableMethod(
      "layers::ContentCompositorBridgeParent::DeferredDestroy", this,
      &ContentCompositorBridgeParent::DeferredDestroy));
}

already_AddRefed<PAPZCTreeManagerParent>
ContentCompositorBridgeParent::AllocPAPZCTreeManagerParent(
    const LayersId& aLayersId) {
  // Check to see if this child process has access to this layer tree.
  if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
    NS_ERROR(
        "Unexpected layers id in AllocPAPZCTreeManagerParent; dropping "
        "message...");
    return nullptr;
  }

  return CompositorBridgeParent::WithIndirectLayerTreesLock(
      [&](const StaticMonitorAutoLock& aProofOfLock)
          -> already_AddRefed<PAPZCTreeManagerParent> {
        CompositorBridgeParent::LayerTreeState& state =
            CompositorBridgeParent::EnsureLayerTreeStateUnderLock(aLayersId,
                                                                  aProofOfLock);

        // If the widget has shutdown its compositor, we may not have had a
        // chance yet to unmap our layers id, and we could get here without a
        // parent compositor. In this case return an empty APZCTM.
        if (!state.mParent) {
          // Note: we immediately call ClearTree since otherwise the APZCTM will
          // retain a reference to itself, through the checkerboard observer.
          LayersId dummyId{0};
          const bool connectedToWebRender = false;
          RefPtr<APZCTreeManager> temp = APZCTreeManager::Create(dummyId);
          RefPtr tempUpdater =
              MakeRefPtr<APZUpdater>(temp, connectedToWebRender);
          tempUpdater->ClearTree(dummyId);
          return MakeAndAddRef<APZCTreeManagerParent>(aLayersId, temp,
                                                      tempUpdater);
        }

        // If we do not have APZ enabled, we should gracefully fail.
        if (!state.mParent->GetOptions().UseAPZ()) {
          return nullptr;
        }

        return state.mParent->AllocateAPZCTreeManagerParent(aProofOfLock,
                                                            aLayersId, state);
      });
}

already_AddRefed<PAPZParent> ContentCompositorBridgeParent::AllocPAPZParent(
    const LayersId& aLayersId) {
  // Check to see if this child process has access to this layer tree.
  if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
    NS_ERROR("Unexpected layers id in AllocPAPZParent; dropping message...");
    return nullptr;
  }

  auto controller = MakeRefPtr<RemoteContentController>();

  CompositorBridgeParent::WithIndirectLayerTreesLock(
      [&](const StaticMonitorAutoLock& aProofOfLock) {
        CompositorBridgeParent::LayerTreeState& state =
            CompositorBridgeParent::EnsureLayerTreeStateUnderLock(aLayersId,
                                                                  aProofOfLock);
        MOZ_ASSERT(!state.mController);
        state.mController = controller;
      });

  return controller.forget();
}

already_AddRefed<PWebRenderBridgeParent>
ContentCompositorBridgeParent::AllocPWebRenderBridgeParent(
    const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize,
    const WindowKind& aWindowKind) {
  LayersId layersId = wr::AsLayersId(aPipelineId);
  // Check to see if this child process has access to this layer tree.
  if (!LayerTreeOwnerTracker::Get()->IsMapped(layersId, OtherPid())) {
    NS_ERROR(
        "Unexpected layers id in AllocPWebRenderBridgeParent; dropping "
        "message...");
    return nullptr;
  }

  RefPtr<CompositorBridgeParent> cbp = nullptr;
  RefPtr<WebRenderBridgeParent> root = nullptr;

  CompositorBridgeParent::WithIndirectLayerTreesLock(
      [&](const StaticMonitorAutoLock& aProofOfLock) {
        MOZ_ASSERT(CompositorBridgeParent::GetLayerTreeStateUnderLock(
            layersId, aProofOfLock));
        CompositorBridgeParent::LayerTreeState& state =
            CompositorBridgeParent::EnsureLayerTreeStateUnderLock(layersId,
                                                                  aProofOfLock);
        MOZ_ASSERT(state.mWrBridge == nullptr);
        cbp = state.mParent;
        if (cbp) {
          root = CompositorBridgeParent::EnsureLayerTreeStateUnderLock(
                     cbp->RootLayerTreeId(), aProofOfLock)
                     .mWrBridge;
        }
      });

  RefPtr<wr::WebRenderAPI> api;
  if (root) {
    api = root->GetWebRenderAPI();
  }

  if (!root || !api) {
    // This could happen when this function is called after
    // CompositorBridgeParent destruction. This was observed during Tab move
    // between different windows.
    NS_WARNING(
        nsPrintfCString("Created child without a matching parent? root %p",
                        root.get())
            .get());
    nsCString error("NO_PARENT");
    return WebRenderBridgeParent::CreateDestroyed(aPipelineId,
                                                  std::move(error));
  }

  api = api->Clone();
  RefPtr<AsyncImagePipelineManager> holder = root->AsyncImageManager();
  auto parent = MakeRefPtr<WebRenderBridgeParent>(
      this, aPipelineId, root->CompositorScheduler(), std::move(api),
      std::move(holder), cbp->GetVsyncInterval());

  CompositorBridgeParent::WithIndirectLayerTreesLock(
      [&](const StaticMonitorAutoLock& aProofOfLock) {
        CompositorBridgeParent::LayerTreeState& state =
            CompositorBridgeParent::EnsureLayerTreeStateUnderLock(layersId,
                                                                  aProofOfLock);
        state.mContentCompositorBridgeParent = this;
        state.mWrBridge = parent;
      });

  return parent.forget();
}

mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvNotifyChildCreated(
    const LayersId& child, CompositorOptions* aOptions) {
  if (NS_WARN_IF(!LayerTreeOwnerTracker::Get()->IsMapped(child, OtherPid()))) {
    return IPC_OK();
  }

  bool found = false;
  CompositorBridgeParent::WithIndirectLayerTreesLock(
      [&](const StaticMonitorAutoLock& aProofOfLock) {
        CompositorBridgeParent::ForEachLayerTreeStateUnderLock(
            aProofOfLock,
            [&](LayersId, CompositorBridgeParent::LayerTreeState& lts) {
              if (!found && lts.mParent &&
                  lts.mContentCompositorBridgeParent == this) {
                lts.mParent->NotifyChildCreated(child);
                *aOptions = lts.mParent->GetOptions();
                found = true;
              }
            });
      });
  return found ? IPC_OK() : IPC_FAIL_NO_REASON(this);
}

mozilla::ipc::IPCResult
ContentCompositorBridgeParent::RecvMapAndNotifyChildCreated(
    const LayersId& child, const base::ProcessId& pid,
    CompositorOptions* aOptions) {
  // This can only be called from the browser process, as the mapping
  // ensures proper window ownership of layer trees.
  return IPC_FAIL_NO_REASON(this);
}

mozilla::ipc::IPCResult
ContentCompositorBridgeParent::RecvNotifyMemoryPressure() {
  // This can only be called from the browser process.
  return IPC_FAIL_NO_REASON(this);
}

mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvCheckContentOnlyTDR(
    const uint32_t& sequenceNum, bool* isContentOnlyTDR) {
  *isContentOnlyTDR = false;
#ifdef XP_WIN
  gfx::ContentDeviceData compositor;

  gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();

  // Check that the D3D11 device sequence numbers match.
  gfx::D3D11DeviceStatus status;
  dm->ExportDeviceInfo(&status);

  if (sequenceNum == static_cast<uint32_t>(status.sequenceNumber()) &&
      !dm->HasDeviceReset()) {
    *isContentOnlyTDR = true;
  }

#endif
  return IPC_OK();
};

mozilla::ipc::IPCResult
ContentCompositorBridgeParent::RecvCheckAndClearWRDidRasterize(
    const LayersId& aId, bool* aDidRasterize) {
  if (NS_WARN_IF(!LayerTreeOwnerTracker::Get()->IsMapped(aId, OtherPid()))) {
    return IPC_OK();
  }

  *aDidRasterize = false;

  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aId);
  if (!state || !state->mParent) {
    return IPC_OK();
  }

  // Forward to the parent compositor which owns the renderer
  RefPtr<wr::WebRenderAPI> api;
  CompositorBridgeParent::WithIndirectLayerTreesLock(
      [&](const StaticMonitorAutoLock& aProofOfLock) {
        LayersId rootId = state->mParent->RootLayerTreeId();
        const CompositorBridgeParent::LayerTreeState& rootState =
            CompositorBridgeParent::EnsureLayerTreeStateUnderLock(rootId,
                                                                  aProofOfLock);
        if (rootState.mWrBridge) {
          api = rootState.mWrBridge->GetWebRenderAPI();
        }
      });

  if (api) {
    *aDidRasterize = api->CheckAndClearDidRasterize();
  }

  return IPC_OK();
}

void ContentCompositorBridgeParent::DidCompositeLocked(
    LayersId aId, const VsyncId& aVsyncId, TimeStamp& aCompositeStart,
    TimeStamp& aCompositeEnd, const StaticMonitorAutoLock& aProofOfLock) {
  if (CompositorBridgeParent::EnsureLayerTreeStateUnderLock(aId, aProofOfLock)
          .mWrBridge) {
    MOZ_ASSERT(false);  // this should never get called for a WR compositor
  }
}

bool ContentCompositorBridgeParent::SetTestSampleTime(const LayersId& aId,
                                                      const TimeStamp& aTime) {
  MOZ_ASSERT(aId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aId);
  if (!state) {
    return false;
  }

  MOZ_ASSERT(state->mParent);
  return state->mParent->SetTestSampleTime(aId, aTime);
}

void ContentCompositorBridgeParent::LeaveTestMode(const LayersId& aId) {
  MOZ_ASSERT(aId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aId);
  if (!state) {
    return;
  }

  MOZ_ASSERT(state->mParent);
  state->mParent->LeaveTestMode(aId);
}

void ContentCompositorBridgeParent::SetTestAsyncScrollOffset(
    const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId,
    const CSSPoint& aPoint) {
  MOZ_ASSERT(aLayersId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aLayersId);
  if (!state) {
    return;
  }

  MOZ_ASSERT(state->mParent);
  state->mParent->SetTestAsyncScrollOffset(aLayersId, aScrollId, aPoint);
}

void ContentCompositorBridgeParent::SetTestAsyncZoom(
    const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId,
    const LayerToParentLayerScale& aZoom) {
  MOZ_ASSERT(aLayersId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aLayersId);
  if (!state) {
    return;
  }

  MOZ_ASSERT(state->mParent);
  state->mParent->SetTestAsyncZoom(aLayersId, aScrollId, aZoom);
}

void ContentCompositorBridgeParent::FlushApzRepaints(
    const LayersId& aLayersId) {
  MOZ_ASSERT(aLayersId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aLayersId);
  if (!state || !state->mParent) {
    return;
  }

  state->mParent->FlushApzRepaints(aLayersId);
}

void ContentCompositorBridgeParent::GetAPZTestData(const LayersId& aLayersId,
                                                   APZTestData* aOutData) {
  MOZ_ASSERT(aLayersId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aLayersId);
  if (!state || !state->mParent) {
    return;
  }

  state->mParent->GetAPZTestData(aLayersId, aOutData);
}

void ContentCompositorBridgeParent::GetFrameUniformity(
    const LayersId& aLayersId, FrameUniformityData* aOutData) {
  MOZ_ASSERT(aLayersId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aLayersId);
  if (!state || !state->mParent) {
    return;
  }

  state->mParent->GetFrameUniformity(aLayersId, aOutData);
}

void ContentCompositorBridgeParent::SetConfirmedTargetAPZC(
    const LayersId& aLayersId, const uint64_t& aInputBlockId,
    nsTArray<ScrollableLayerGuid>&& aTargets) {
  MOZ_ASSERT(aLayersId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aLayersId);
  if (!state || !state->mParent) {
    return;
  }

  state->mParent->SetConfirmedTargetAPZC(aLayersId, aInputBlockId,
                                         std::move(aTargets));
}

void ContentCompositorBridgeParent::EndWheelTransaction(
    const LayersId& aLayersId,
    PWebRenderBridgeParent::EndWheelTransactionResolver&& aResolve) {
  MOZ_ASSERT(aLayersId.IsValid());
  const CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aLayersId);
  if (!state || !state->mParent) {
    // The boolean value will never used so it doesn't matter whether it's true
    // or false.
    aResolve(true);
    return;
  }

  state->mParent->EndWheelTransaction(aLayersId, std::move(aResolve));
}

void ContentCompositorBridgeParent::DeferredDestroy() { mSelfRef = nullptr; }

ContentCompositorBridgeParent::~ContentCompositorBridgeParent() {
  MOZ_ASSERT(XRE_GetAsyncIOEventTarget());
}

already_AddRefed<PTextureParent>
ContentCompositorBridgeParent::AllocPTextureParent(
    const SurfaceDescriptor& aSharedData, ReadLockDescriptor& aReadLock,
    const LayersBackend& aLayersBackend, const TextureFlags& aFlags,
    const uint64_t& aSerial, const wr::MaybeExternalImageId& aExternalImageId) {
  if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorDcompSurface) {
    return nullptr;
  }
  if (aExternalImageId.isSome() &&
      !OwnsExternalImageId(aExternalImageId.ref())) {
    NS_ERROR("We do not own this external image id.");
    return nullptr;
  }
  return TextureHost::CreateIPDLActor(
      this, aSharedData, std::move(aReadLock), aLayersBackend, aFlags,
      mCompositorManager->GetContentId(), aSerial, aExternalImageId);
}

bool ContentCompositorBridgeParent::IsSameProcess() const {
  return OtherPid() == base::GetCurrentProcId();
}

void ContentCompositorBridgeParent::ObserveLayersUpdate(LayersId aLayersId,
                                                        bool aActive) {
  MOZ_ASSERT(aLayersId.IsValid());

  CompositorBridgeParent::LayerTreeState* state =
      CompositorBridgeParent::GetLayerTreeState(aLayersId);
  if (!state || !state->mParent) {
    return;
  }

  (void)state->mParent->SendObserveLayersUpdate(aLayersId, aActive);
}

}  // namespace mozilla::layers

Messung V0.5 in Prozent
C=91 H=97 G=93

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002