tor-browser

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

UiCompositorControllerParent.cpp (9166B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 #include "UiCompositorControllerParent.h"
      7 
      8 #if defined(MOZ_WIDGET_ANDROID)
      9 #  include "apz/src/APZCTreeManager.h"
     10 #  include "mozilla/widget/AndroidCompositorWidget.h"
     11 #endif
     12 #include <utility>
     13 
     14 #include "FrameMetrics.h"
     15 #include "SynchronousTask.h"
     16 #include "mozilla/gfx/Types.h"
     17 #include "mozilla/ipc/Endpoint.h"
     18 #include "mozilla/layers/Compositor.h"
     19 #include "mozilla/layers/CompositorBridgeParent.h"
     20 #include "mozilla/layers/CompositorThread.h"
     21 #include "mozilla/layers/UiCompositorControllerMessageTypes.h"
     22 #include "mozilla/layers/WebRenderBridgeParent.h"
     23 
     24 namespace mozilla {
     25 namespace layers {
     26 
     27 typedef CompositorBridgeParent::LayerTreeState LayerTreeState;
     28 
     29 /* static */
     30 RefPtr<UiCompositorControllerParent>
     31 UiCompositorControllerParent::GetFromRootLayerTreeId(
     32    const LayersId& aRootLayerTreeId) {
     33  RefPtr<UiCompositorControllerParent> controller;
     34  CompositorBridgeParent::CallWithIndirectShadowTree(
     35      aRootLayerTreeId, [&](LayerTreeState& aState) -> void {
     36        controller = aState.mUiControllerParent;
     37      });
     38  return controller;
     39 }
     40 
     41 /* static */
     42 RefPtr<UiCompositorControllerParent> UiCompositorControllerParent::Start(
     43    const LayersId& aRootLayerTreeId,
     44    Endpoint<PUiCompositorControllerParent>&& aEndpoint) {
     45  RefPtr<UiCompositorControllerParent> parent =
     46      new UiCompositorControllerParent(aRootLayerTreeId);
     47 
     48  RefPtr<Runnable> task =
     49      NewRunnableMethod<Endpoint<PUiCompositorControllerParent>&&>(
     50          "layers::UiCompositorControllerParent::Open", parent,
     51          &UiCompositorControllerParent::Open, std::move(aEndpoint));
     52  CompositorThread()->Dispatch(task.forget());
     53 
     54  return parent;
     55 }
     56 
     57 mozilla::ipc::IPCResult UiCompositorControllerParent::RecvPause() {
     58  CompositorBridgeParent* parent =
     59      CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(
     60          mRootLayerTreeId);
     61  if (parent) {
     62    parent->PauseComposition();
     63  }
     64  return IPC_OK();
     65 }
     66 
     67 mozilla::ipc::IPCResult UiCompositorControllerParent::RecvResume(
     68    bool* aOutResumed) {
     69  *aOutResumed = false;
     70  CompositorBridgeParent* parent =
     71      CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(
     72          mRootLayerTreeId);
     73  if (parent) {
     74    *aOutResumed = parent->ResumeComposition();
     75  }
     76  return IPC_OK();
     77 }
     78 
     79 mozilla::ipc::IPCResult UiCompositorControllerParent::RecvResumeAndResize(
     80    const int32_t& aX, const int32_t& aY, const int32_t& aWidth,
     81    const int32_t& aHeight, bool* aOutResumed) {
     82  *aOutResumed = false;
     83  CompositorBridgeParent* parent =
     84      CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(
     85          mRootLayerTreeId);
     86  if (parent) {
     87    // Front-end expects a first paint callback upon resume/resize.
     88    parent->ForceIsFirstPaint();
     89 #if defined(MOZ_WIDGET_ANDROID)
     90    parent->GetWidget()->AsAndroid()->NotifyClientSizeChanged(
     91        LayoutDeviceIntSize(aWidth, aHeight));
     92 #endif
     93    *aOutResumed = parent->ResumeCompositionAndResize(aX, aY, aWidth, aHeight);
     94  }
     95  return IPC_OK();
     96 }
     97 
     98 mozilla::ipc::IPCResult
     99 UiCompositorControllerParent::RecvInvalidateAndRender() {
    100  CompositorBridgeParent* parent =
    101      CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(
    102          mRootLayerTreeId);
    103  if (parent) {
    104    parent->ScheduleComposition(wr::RenderReasons::OTHER);
    105  }
    106  return IPC_OK();
    107 }
    108 
    109 mozilla::ipc::IPCResult UiCompositorControllerParent::RecvMaxToolbarHeight(
    110    const int32_t& aHeight) {
    111  mMaxToolbarHeight = aHeight;
    112 
    113  return IPC_OK();
    114 }
    115 
    116 mozilla::ipc::IPCResult UiCompositorControllerParent::RecvFixedBottomOffset(
    117    const int32_t& aOffset) {
    118 #if defined(MOZ_WIDGET_ANDROID)
    119  CompositorBridgeParent* parent =
    120      CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(
    121          mRootLayerTreeId);
    122  if (parent) {
    123    parent->SetFixedLayerMargins(0, aOffset);
    124  }
    125 #endif  // defined(MOZ_WIDGET_ANDROID)
    126 
    127  return IPC_OK();
    128 }
    129 
    130 mozilla::ipc::IPCResult UiCompositorControllerParent::RecvDefaultClearColor(
    131    const uint32_t& aColor) {
    132  LayerTreeState* state =
    133      CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
    134 
    135  if (state && state->mWrBridge) {
    136    state->mWrBridge->SetClearColor(gfx::DeviceColor::UnusualFromARGB(aColor));
    137  }
    138 
    139  return IPC_OK();
    140 }
    141 
    142 mozilla::ipc::IPCResult
    143 UiCompositorControllerParent::RecvRequestScreenPixels() {
    144 #if defined(MOZ_WIDGET_ANDROID)
    145  LayerTreeState* state =
    146      CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
    147 
    148  if (state && state->mWrBridge) {
    149    state->mWrBridge->RequestScreenPixels(this);
    150    state->mWrBridge->ScheduleForcedGenerateFrame(wr::RenderReasons::OTHER);
    151  }
    152 #endif  // defined(MOZ_WIDGET_ANDROID)
    153 
    154  return IPC_OK();
    155 }
    156 
    157 mozilla::ipc::IPCResult
    158 UiCompositorControllerParent::RecvEnableLayerUpdateNotifications(
    159    const bool& aEnable) {
    160 #if defined(MOZ_WIDGET_ANDROID)
    161  // Layers updates are need by Robocop test which enables them
    162  mCompositorLayersUpdateEnabled = aEnable;
    163 #endif  // defined(MOZ_WIDGET_ANDROID)
    164 
    165  return IPC_OK();
    166 }
    167 
    168 void UiCompositorControllerParent::ActorDestroy(ActorDestroyReason aWhy) {
    169  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    170  Shutdown();
    171 }
    172 
    173 void UiCompositorControllerParent::ToolbarAnimatorMessageFromCompositor(
    174    int32_t aMessage) {
    175  // This function can be call from ether compositor or controller thread.
    176  if (!CompositorThreadHolder::IsInCompositorThread()) {
    177    CompositorThread()->Dispatch(NewRunnableMethod<int32_t>(
    178        "layers::UiCompositorControllerParent::"
    179        "ToolbarAnimatorMessageFromCompositor",
    180        this,
    181        &UiCompositorControllerParent::ToolbarAnimatorMessageFromCompositor,
    182        aMessage));
    183    return;
    184  }
    185 
    186  (void)SendToolbarAnimatorMessageFromCompositor(aMessage);
    187 }
    188 
    189 bool UiCompositorControllerParent::AllocPixelBuffer(const int32_t aSize,
    190                                                    ipc::Shmem* aMem) {
    191  MOZ_ASSERT(aSize > 0);
    192  return AllocShmem(aSize, aMem);
    193 }
    194 
    195 void UiCompositorControllerParent::NotifyLayersUpdated() {
    196 #ifdef MOZ_WIDGET_ANDROID
    197  if (mCompositorLayersUpdateEnabled) {
    198    ToolbarAnimatorMessageFromCompositor(LAYERS_UPDATED);
    199  }
    200 #endif
    201 }
    202 
    203 void UiCompositorControllerParent::NotifyFirstPaint() {
    204  ToolbarAnimatorMessageFromCompositor(FIRST_PAINT);
    205 }
    206 
    207 void UiCompositorControllerParent::NotifyCompositorScrollUpdate(
    208    const CompositorScrollUpdate& aUpdate) {
    209  CompositorThread()->Dispatch(NewRunnableMethod<CompositorScrollUpdate>(
    210      "UiCompositorControllerParent::SendNotifyCompositorScrollUpdate", this,
    211      &UiCompositorControllerParent::SendNotifyCompositorScrollUpdate,
    212      aUpdate));
    213 }
    214 
    215 UiCompositorControllerParent::UiCompositorControllerParent(
    216    const LayersId& aRootLayerTreeId)
    217    : mRootLayerTreeId(aRootLayerTreeId)
    218 #ifdef MOZ_WIDGET_ANDROID
    219      ,
    220      mCompositorLayersUpdateEnabled(false)
    221 #endif
    222      ,
    223      mMaxToolbarHeight(0) {
    224  MOZ_COUNT_CTOR(UiCompositorControllerParent);
    225 }
    226 
    227 UiCompositorControllerParent::~UiCompositorControllerParent() {
    228  MOZ_COUNT_DTOR(UiCompositorControllerParent);
    229 }
    230 
    231 void UiCompositorControllerParent::InitializeForSameProcess() {
    232  // This function is called by UiCompositorControllerChild in the main thread.
    233  // So dispatch to the compositor thread to Initialize.
    234  if (!CompositorThreadHolder::IsInCompositorThread()) {
    235    SetOtherEndpointProcInfo(ipc::EndpointProcInfo::Current());
    236    SynchronousTask task(
    237        "UiCompositorControllerParent::InitializeForSameProcess");
    238 
    239    CompositorThread()->Dispatch(NS_NewRunnableFunction(
    240        "UiCompositorControllerParent::InitializeForSameProcess", [&]() {
    241          AutoCompleteTask complete(&task);
    242          InitializeForSameProcess();
    243        }));
    244 
    245    task.Wait();
    246    return;
    247  }
    248 
    249  Initialize();
    250 }
    251 
    252 void UiCompositorControllerParent::InitializeForOutOfProcess() {
    253  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    254  Initialize();
    255 }
    256 
    257 void UiCompositorControllerParent::Initialize() {
    258  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    259  LayerTreeState* state =
    260      CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
    261  MOZ_ASSERT(state);
    262  MOZ_ASSERT(state->mParent);
    263  if (!state || !state->mParent) {
    264    return;
    265  }
    266  state->mUiControllerParent = this;
    267 }
    268 
    269 void UiCompositorControllerParent::Open(
    270    Endpoint<PUiCompositorControllerParent>&& aEndpoint) {
    271  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    272  if (!aEndpoint.Bind(this)) {
    273    // We can't recover from this.
    274    MOZ_CRASH("Failed to bind UiCompositorControllerParent to endpoint");
    275  }
    276  InitializeForOutOfProcess();
    277 }
    278 
    279 void UiCompositorControllerParent::Shutdown() {
    280  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
    281  LayerTreeState* state =
    282      CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
    283  if (state) {
    284    state->mUiControllerParent = nullptr;
    285  }
    286 }
    287 
    288 }  // namespace layers
    289 }  // namespace mozilla