tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

NativeLayerRootRemoteMacChild.mm (7173B)


      1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "mozilla/layers/NativeLayerRemoteMac.h"
      7 #include "mozilla/layers/NativeLayerRootRemoteMacChild.h"
      8 #include "mozilla/layers/SurfacePool.h"
      9 
     10 namespace mozilla {
     11 namespace layers {
     12 
     13 already_AddRefed<NativeLayer> NativeLayerRootRemoteMacChild::CreateLayer(
     14    const gfx::IntSize& aSize, bool aIsOpaque,
     15    SurfacePoolHandle* aSurfacePoolHandle) {
     16  RefPtr<NativeLayerRemoteMac> layer = new NativeLayerRemoteMac(
     17      aSize, aIsOpaque, aSurfacePoolHandle->AsSurfacePoolHandleCA());
     18  mCommandQueue->AppendCommand(mozilla::layers::CommandCreateLayer(
     19      reinterpret_cast<uint64_t>(layer.get()), aSize, aIsOpaque));
     20  // Share our command queue.
     21  layer->mCommandQueue = mCommandQueue;
     22  return layer.forget();
     23 }
     24 
     25 already_AddRefed<NativeLayer>
     26 NativeLayerRootRemoteMacChild::CreateLayerForExternalTexture(bool aIsOpaque) {
     27  RefPtr<NativeLayerRemoteMac> layer = new NativeLayerRemoteMac(aIsOpaque);
     28  mCommandQueue->AppendCommand(
     29      mozilla::layers::CommandCreateLayerForExternalTexture(
     30          reinterpret_cast<uint64_t>(layer.get()), aIsOpaque));
     31  // Share our command queue.
     32  layer->mCommandQueue = mCommandQueue;
     33  return layer.forget();
     34 }
     35 
     36 already_AddRefed<NativeLayer>
     37 NativeLayerRootRemoteMacChild::CreateLayerForColor(gfx::DeviceColor aColor) {
     38  RefPtr<NativeLayerRemoteMac> layer = new NativeLayerRemoteMac(aColor);
     39  mCommandQueue->AppendCommand(mozilla::layers::CommandCreateLayerForColor(
     40      reinterpret_cast<uint64_t>(layer.get()), aColor));
     41  // Share our command queue.
     42  layer->mCommandQueue = mCommandQueue;
     43  return layer.forget();
     44 }
     45 
     46 void NativeLayerRootRemoteMacChild::AppendLayer(NativeLayer* aLayer) {}
     47 
     48 void NativeLayerRootRemoteMacChild::RemoveLayer(NativeLayer* aLayer) {}
     49 
     50 void NativeLayerRootRemoteMacChild::SetLayers(
     51    const nsTArray<RefPtr<NativeLayer>>& aLayers) {
     52  // We don't create a command for this, because we don't care
     53  // about the layers until CommitToScreen().
     54  nsTArray<RefPtr<NativeLayerRemoteMac>> layers(aLayers.Length());
     55  for (const auto& layer : aLayers) {
     56    RefPtr<NativeLayerRemoteMac> layerRemoteMac =
     57        layer->AsNativeLayerRemoteMac();
     58    MOZ_ASSERT(layerRemoteMac);
     59    layers.AppendElement(std::move(layerRemoteMac));
     60  }
     61 
     62  if (mNativeLayers == layers) {
     63    // A no-op.
     64    return;
     65  }
     66 
     67  mNativeLayersChanged = true;
     68  mNativeLayersChangedForSnapshot = true;
     69  mNativeLayers.Clear();
     70  mNativeLayers.AppendElements(layers);
     71 }
     72 
     73 UniquePtr<NativeLayerRootSnapshotter>
     74 NativeLayerRootRemoteMacChild::CreateSnapshotter() {
     75 #ifdef XP_MACOSX
     76  MOZ_RELEASE_ASSERT(!mWeakSnapshotter,
     77                     "No NativeLayerRootSnapshotter for this NativeLayerRoot "
     78                     "should exist when this is called");
     79  auto cr = NativeLayerRootSnapshotterCA::Create(
     80      MakeUnique<SnapshotterDelegate>(this));
     81  if (cr) {
     82    mWeakSnapshotter = cr.get();
     83  }
     84  return cr;
     85 #else
     86  return nullptr;
     87 #endif
     88 }
     89 
     90 void NativeLayerRootRemoteMacChild::OnNativeLayerRootSnapshotterDestroyed(
     91    NativeLayerRootSnapshotterCA* aNativeLayerRootSnapshotter) {
     92  MOZ_RELEASE_ASSERT(mWeakSnapshotter == aNativeLayerRootSnapshotter);
     93  mWeakSnapshotter = nullptr;
     94 }
     95 
     96 void NativeLayerRootRemoteMacChild::PrepareForCommit() {
     97  // Intentionally ignored.
     98 }
     99 
    100 bool NativeLayerRootRemoteMacChild::CommitToScreen() {
    101  // Prepare and send all commands to the parent actor.
    102 
    103  // Our shared command queue has all of our CreateLayer and LayerDestroyed
    104  // commands. That's good, because the commands that we're adding to the
    105  // queue rely upon those CreateLayer commands appearing first.
    106 
    107  // Iterate our layers to get the LayerInfo and ChangedSurface commands
    108  // into our shared command queue.
    109  for (const auto& layer : mNativeLayers) {
    110    layer->FlushDirtyLayerInfoToCommandQueue();
    111  }
    112 
    113  if (mNativeLayersChanged) {
    114    // If mNativeLayersChanged is set, we will send a SetLayers
    115    // command of this array filled with the IDs of everything
    116    // in mNativeLayers.
    117    nsTArray<uint64_t> setLayerIDs;
    118    for (const auto& layer : mNativeLayers) {
    119      auto ID = reinterpret_cast<uint64_t>(layer.get());
    120      setLayerIDs.AppendElement(ID);
    121    }
    122    mCommandQueue->AppendCommand(
    123        mozilla::layers::CommandSetLayers(setLayerIDs));
    124    mNativeLayersChanged = false;
    125  }
    126 
    127  // Now flush the shared command queue to our local command array,
    128  // which is suitable for sending to the parent process.
    129  nsTArray<NativeLayerCommand> commands;
    130  mCommandQueue->FlushToArray(commands);
    131 
    132  if (!commands.IsEmpty()) {
    133    // Send all the queued commands, including the ones we just added.
    134    MOZ_ASSERT(mRemoteChild);
    135    mRemoteChild->SendCommitNativeLayerCommands(std::move(commands));
    136  }
    137  return true;
    138 }
    139 
    140 void NativeLayerRootRemoteMacChild::WaitUntilCommitToScreenHasBeenProcessed() {
    141  mRemoteChild->SendFlush();
    142 }
    143 
    144 void NativeLayerRootRemoteMacChild::CommitForSnapshot(CALayer* aRootCALayer) {
    145  [CATransaction begin];
    146  [CATransaction setDisableActions:YES];  // disable cross-fade
    147 
    148  NSMutableArray<CALayer*>* sublayers =
    149      [NSMutableArray arrayWithCapacity:mNativeLayers.Length()];
    150  for (const auto& layer : mNativeLayers) {
    151    layer->UpdateSnapshotLayer();
    152    if (CALayer* caLayer = layer->CALayerForSnapshot()) {
    153      [sublayers addObject:caLayer];
    154    }
    155  }
    156 
    157  aRootCALayer.sublayers = sublayers;
    158  [CATransaction commit];
    159 
    160  mNativeLayersChangedForSnapshot = false;
    161 }
    162 
    163 bool NativeLayerRootRemoteMacChild::ReadbackPixelsFromParent(
    164    const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat,
    165    const Range<uint8_t>& aBuffer) {
    166  // In this process we only have the pixels of the individual layers,
    167  // but here we're asked to return the result of compositing all the
    168  // layers together. Computing the composited result is currently
    169  // only implemented in NativeLayerRootCA, which runs in the parent
    170  // process, so we send a sync IPC message to the parent to ask for
    171  // the composited result.
    172  if (aFormat != gfx::SurfaceFormat::B8G8R8A8) {
    173    return false;
    174  }
    175 
    176  ipc::Shmem pixels;
    177  if (!mRemoteChild->SendRequestReadback(aSize, &pixels)) {
    178    return false;
    179  }
    180 
    181  // Copy pixels into aBuffer.
    182  // TODO: Figure out a more idiomatic way to do this.
    183  auto byteCount = pixels.Size<uint8_t>();
    184  MOZ_RELEASE_ASSERT(aBuffer.length() >= byteCount);
    185  PodCopy(aBuffer.begin().get(), pixels.get<uint8_t>(), byteCount);
    186 
    187  return true;
    188 }
    189 
    190 NativeLayerRootRemoteMacChild::NativeLayerRootRemoteMacChild()
    191    : mRemoteChild(MakeRefPtr<NativeLayerRemoteChild>()),
    192      mCommandQueue(MakeRefPtr<NativeLayerCommandQueue>()) {}
    193 
    194 NativeLayerRootRemoteMacChild::~NativeLayerRootRemoteMacChild() {}
    195 
    196 NativeLayerRootRemoteMacChild::SnapshotterDelegate::SnapshotterDelegate(
    197    NativeLayerRootRemoteMacChild* aLayerRoot)
    198    : mLayerRoot(aLayerRoot) {}
    199 NativeLayerRootRemoteMacChild::SnapshotterDelegate::~SnapshotterDelegate() =
    200    default;
    201 
    202 }  // namespace layers
    203 }  // namespace mozilla