LCOV - code coverage report
Current view: top level - gfx/layers/client - ClientLayerManager.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 220 411 53.5 %
Date: 2017-07-14 16:53:18 Functions: 30 62 48.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; 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 "ClientLayerManager.h"
       7             : #include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
       8             : #include "gfxPrefs.h"                   // for gfxPrefs::LayersTile...
       9             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
      10             : #include "mozilla/Hal.h"
      11             : #include "mozilla/dom/ScreenOrientation.h"  // for ScreenOrientation
      12             : #include "mozilla/dom/TabChild.h"       // for TabChild
      13             : #include "mozilla/dom/TabGroup.h"       // for TabGroup
      14             : #include "mozilla/hal_sandbox/PHal.h"   // for ScreenConfiguration
      15             : #include "mozilla/layers/CompositableClient.h"
      16             : #include "mozilla/layers/CompositorBridgeChild.h" // for CompositorBridgeChild
      17             : #include "mozilla/layers/FrameUniformityData.h"
      18             : #include "mozilla/layers/ISurfaceAllocator.h"
      19             : #include "mozilla/layers/LayersMessages.h"  // for EditReply, etc
      20             : #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
      21             : #include "mozilla/layers/LayerTransactionChild.h"
      22             : #include "mozilla/layers/PersistentBufferProvider.h"
      23             : #include "ClientReadbackLayer.h"        // for ClientReadbackLayer
      24             : #include "nsAString.h"
      25             : #include "nsDisplayList.h"
      26             : #include "nsIWidgetListener.h"
      27             : #include "nsTArray.h"                   // for AutoTArray
      28             : #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
      29             : #include "TiledLayerBuffer.h"
      30             : #include "FrameLayerBuilder.h"          // for FrameLayerbuilder
      31             : #ifdef MOZ_WIDGET_ANDROID
      32             : #include "AndroidBridge.h"
      33             : #include "LayerMetricsWrapper.h"
      34             : #endif
      35             : #ifdef XP_WIN
      36             : #include "mozilla/gfx/DeviceManagerDx.h"
      37             : #include "gfxDWriteFonts.h"
      38             : #endif
      39             : 
      40             : namespace mozilla {
      41             : namespace layers {
      42             : 
      43             : using namespace mozilla::gfx;
      44             : 
      45             : void
      46           0 : ClientLayerManager::MemoryPressureObserver::Destroy()
      47             : {
      48           0 :   UnregisterMemoryPressureEvent();
      49           0 :   mClientLayerManager = nullptr;
      50           0 : }
      51             : 
      52             : NS_IMETHODIMP
      53           0 : ClientLayerManager::MemoryPressureObserver::Observe(nsISupports* aSubject,
      54             :                                                     const char* aTopic,
      55             :                                                     const char16_t* aSomeData)
      56             : {
      57           0 :   if (!mClientLayerManager || strcmp(aTopic, "memory-pressure")) {
      58           0 :     return NS_OK;
      59             :   }
      60             : 
      61           0 :   mClientLayerManager->HandleMemoryPressure();
      62           0 :   return NS_OK;
      63             : }
      64             : 
      65             : void
      66           2 : ClientLayerManager::MemoryPressureObserver::RegisterMemoryPressureEvent()
      67             : {
      68             :   nsCOMPtr<nsIObserverService> observerService =
      69           4 :     mozilla::services::GetObserverService();
      70             : 
      71           2 :   MOZ_ASSERT(observerService);
      72             : 
      73           2 :   if (observerService) {
      74           2 :     observerService->AddObserver(this, "memory-pressure", false);
      75             :   }
      76           2 : }
      77             : 
      78             : void
      79           0 : ClientLayerManager::MemoryPressureObserver::UnregisterMemoryPressureEvent()
      80             : {
      81             :   nsCOMPtr<nsIObserverService> observerService =
      82           0 :       mozilla::services::GetObserverService();
      83             : 
      84           0 :   if (observerService) {
      85           0 :       observerService->RemoveObserver(this, "memory-pressure");
      86             :   }
      87           0 : }
      88             : 
      89           4 : NS_IMPL_ISUPPORTS(ClientLayerManager::MemoryPressureObserver, nsIObserver)
      90             : 
      91           2 : ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
      92             :   : mPhase(PHASE_NONE)
      93             :   , mWidget(aWidget)
      94             :   , mLatestTransactionId(0)
      95             :   , mLastPaintTime(TimeDuration::Forever())
      96             :   , mTargetRotation(ROTATION_0)
      97             :   , mRepeatTransaction(false)
      98             :   , mIsRepeatTransaction(false)
      99             :   , mTransactionIncomplete(false)
     100             :   , mCompositorMightResample(false)
     101             :   , mNeedsComposite(false)
     102             :   , mPaintSequenceNumber(0)
     103             :   , mDeviceResetSequenceNumber(0)
     104           4 :   , mForwarder(new ShadowLayerForwarder(this))
     105             : {
     106           2 :   MOZ_COUNT_CTOR(ClientLayerManager);
     107           2 :   mMemoryPressureObserver = new MemoryPressureObserver(this);
     108             : 
     109           2 :   if (XRE_IsContentProcess()) {
     110           1 :     mDeviceResetSequenceNumber = CompositorBridgeChild::Get()->DeviceResetSequenceNumber();
     111             :   }
     112           2 : }
     113             : 
     114             : 
     115           0 : ClientLayerManager::~ClientLayerManager()
     116             : {
     117           0 :   mMemoryPressureObserver->Destroy();
     118           0 :   ClearCachedResources();
     119             :   // Stop receiveing AsyncParentMessage at Forwarder.
     120             :   // After the call, the message is directly handled by LayerTransactionChild.
     121             :   // Basically this function should be called in ShadowLayerForwarder's
     122             :   // destructor. But when the destructor is triggered by
     123             :   // CompositorBridgeChild::Destroy(), the destructor can not handle it correctly.
     124             :   // See Bug 1000525.
     125           0 :   mForwarder->StopReceiveAsyncParentMessge();
     126           0 :   mRoot = nullptr;
     127             : 
     128           0 :   MOZ_COUNT_DTOR(ClientLayerManager);
     129           0 : }
     130             : 
     131             : void
     132           0 : ClientLayerManager::Destroy()
     133             : {
     134             :   // It's important to call ClearCachedResource before Destroy because the
     135             :   // former will early-return if the later has already run.
     136           0 :   ClearCachedResources();
     137           0 :   LayerManager::Destroy();
     138             : 
     139           0 :   if (mTransactionIdAllocator) {
     140             :     // Make sure to notify the refresh driver just in case it's waiting on a
     141             :     // pending transaction. Do this at the top of the event loop so we don't
     142             :     // cause a paint to occur during compositor shutdown.
     143           0 :     RefPtr<TransactionIdAllocator> allocator = mTransactionIdAllocator;
     144           0 :     uint64_t id = mLatestTransactionId;
     145             : 
     146           0 :     RefPtr<Runnable> task = NS_NewRunnableFunction(
     147             :       "TransactionIdAllocator::NotifyTransactionCompleted",
     148           0 :       [allocator, id] () -> void {
     149           0 :       allocator->NotifyTransactionCompleted(id);
     150           0 :     });
     151           0 :     NS_DispatchToMainThread(task.forget());
     152             :   }
     153             : 
     154             :   // Forget the widget pointer in case we outlive our owning widget.
     155           0 :   mWidget = nullptr;
     156           0 : }
     157             : 
     158             : TabGroup*
     159           2 : ClientLayerManager::GetTabGroup()
     160             : {
     161           2 :   if (mWidget) {
     162           2 :     if (TabChild* tabChild = mWidget->GetOwningTabChild()) {
     163           1 :       return tabChild->TabGroup();
     164             :     }
     165             :   }
     166           1 :   return nullptr;
     167             : }
     168             : 
     169             : int32_t
     170         131 : ClientLayerManager::GetMaxTextureSize() const
     171             : {
     172         131 :   return mForwarder->GetMaxTextureSize();
     173             : }
     174             : 
     175             : void
     176           0 : ClientLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
     177             :                                                   ScreenRotation aRotation)
     178             : {
     179           0 :   mTargetRotation = aRotation;
     180           0 :  }
     181             : 
     182             : void
     183          28 : ClientLayerManager::SetRoot(Layer* aLayer)
     184             : {
     185          28 :   if (mRoot != aLayer) {
     186             :     // Have to hold the old root and its children in order to
     187             :     // maintain the same view of the layer tree in this process as
     188             :     // the parent sees.  Otherwise layers can be destroyed
     189             :     // mid-transaction and bad things can happen (v. bug 612573)
     190           4 :     if (mRoot) {
     191           2 :       Hold(mRoot);
     192             :     }
     193           4 :     mForwarder->SetRoot(Hold(aLayer));
     194           4 :     NS_ASSERTION(aLayer, "Root can't be null");
     195           4 :     NS_ASSERTION(aLayer->Manager() == this, "Wrong manager");
     196           4 :     NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
     197           4 :     mRoot = aLayer;
     198             :   }
     199          28 : }
     200             : 
     201             : void
     202         279 : ClientLayerManager::Mutated(Layer* aLayer)
     203             : {
     204         279 :   LayerManager::Mutated(aLayer);
     205             : 
     206         279 :   NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
     207         279 :   mForwarder->Mutated(Hold(aLayer));
     208         279 : }
     209             : 
     210             : void
     211          24 : ClientLayerManager::MutatedSimple(Layer* aLayer)
     212             : {
     213          24 :   LayerManager::MutatedSimple(aLayer);
     214             : 
     215          24 :   NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
     216          24 :   mForwarder->MutatedSimple(Hold(aLayer));
     217          24 : }
     218             : 
     219             : already_AddRefed<ReadbackLayer>
     220           0 : ClientLayerManager::CreateReadbackLayer()
     221             : {
     222           0 :   RefPtr<ReadbackLayer> layer = new ClientReadbackLayer(this);
     223           0 :   return layer.forget();
     224             : }
     225             : 
     226             : bool
     227          29 : ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
     228             : {
     229             :   // Wait for any previous async paints to complete before starting to paint again.
     230          29 :   GetCompositorBridgeChild()->FlushAsyncPaints();
     231             : 
     232          29 :   MOZ_ASSERT(mForwarder, "ClientLayerManager::BeginTransaction without forwarder");
     233          29 :   if (!mForwarder->IPCOpen()) {
     234           0 :     gfxCriticalNote << "ClientLayerManager::BeginTransaction with IPC channel down. GPU process may have died.";
     235           0 :     return false;
     236             :   }
     237             : 
     238          62 :   if (XRE_IsContentProcess() &&
     239          29 :       mForwarder->DeviceCanReset() &&
     240           0 :       mDeviceResetSequenceNumber != CompositorBridgeChild::Get()->DeviceResetSequenceNumber())
     241             :   {
     242             :     // The compositor has informed this process that a device reset occurred,
     243             :     // but it has not finished informing each TabChild of its new
     244             :     // TextureFactoryIdentifier. Until then, it's illegal to paint. Note that
     245             :     // it is also illegal to request a new TIF synchronously, because we're
     246             :     // not guaranteed the UI process has finished acquiring new compositors
     247             :     // for each widget.
     248             :     //
     249             :     // Note that we only do this for accelerated backends, since we do not
     250             :     // perform resets on basic compositors.
     251           0 :     gfxCriticalNote << "Discarding a paint since a device reset has not yet been acknowledged.";
     252           0 :     return false;
     253             :   }
     254             : 
     255          29 :   mInTransaction = true;
     256          29 :   mTransactionStart = TimeStamp::Now();
     257             : 
     258             : #ifdef MOZ_LAYERS_HAVE_LOG
     259          29 :   MOZ_LAYERS_LOG(("[----- BeginTransaction"));
     260          29 :   Log();
     261             : #endif
     262             : 
     263          29 :   NS_ASSERTION(!InTransaction(), "Nested transactions not allowed");
     264          29 :   mPhase = PHASE_CONSTRUCTION;
     265             : 
     266          29 :   MOZ_ASSERT(mKeepAlive.IsEmpty(), "uncommitted txn?");
     267             : 
     268             :   // If the last transaction was incomplete (a failed DoEmptyTransaction),
     269             :   // don't signal a new transaction to ShadowLayerForwarder. Carry on adding
     270             :   // to the previous transaction.
     271             :   dom::ScreenOrientationInternal orientation;
     272          29 :   if (dom::TabChild* window = mWidget->GetOwningTabChild()) {
     273           4 :     orientation = window->GetOrientation();
     274             :   } else {
     275          50 :     hal::ScreenConfiguration currentConfig;
     276          25 :     hal::GetCurrentScreenConfiguration(&currentConfig);
     277          25 :     orientation = currentConfig.orientation();
     278             :   }
     279          29 :   LayoutDeviceIntRect targetBounds = mWidget->GetNaturalBounds();
     280          29 :   targetBounds.x = targetBounds.y = 0;
     281          58 :   mForwarder->BeginTransaction(targetBounds.ToUnknownRect(), mTargetRotation,
     282          29 :                                orientation);
     283             : 
     284             :   // If we're drawing on behalf of a context with async pan/zoom
     285             :   // enabled, then the entire buffer of painted layers might be
     286             :   // composited (including resampling) asynchronously before we get
     287             :   // a chance to repaint, so we have to ensure that it's all valid
     288             :   // and not rotated.
     289             :   //
     290             :   // Desktop does not support async zoom yet, so we ignore this for those
     291             :   // platforms.
     292             : #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_UIKIT)
     293             :   if (mWidget && mWidget->GetOwningTabChild()) {
     294             :     mCompositorMightResample = AsyncPanZoomEnabled();
     295             :   }
     296             : #endif
     297             : 
     298             :   // If we have a non-default target, we need to let our shadow manager draw
     299             :   // to it. This will happen at the end of the transaction.
     300          29 :   if (aTarget && XRE_IsParentProcess()) {
     301           0 :     mShadowTarget = aTarget;
     302             :   } else {
     303          29 :     NS_ASSERTION(!aTarget,
     304             :                  "Content-process ClientLayerManager::BeginTransactionWithTarget not supported");
     305             :   }
     306             : 
     307             :   // If this is a new paint, increment the paint sequence number.
     308          29 :   if (!mIsRepeatTransaction) {
     309             :     // Increment the paint sequence number even if test logging isn't
     310             :     // enabled in this process; it may be enabled in the parent process,
     311             :     // and the parent process expects unique sequence numbers.
     312          29 :     ++mPaintSequenceNumber;
     313          29 :     if (gfxPrefs::APZTestLoggingEnabled()) {
     314           0 :       mApzTestData.StartNewPaint(mPaintSequenceNumber);
     315             :     }
     316             :   }
     317          29 :   return true;
     318             : }
     319             : 
     320             : bool
     321          29 : ClientLayerManager::BeginTransaction()
     322             : {
     323          29 :   return BeginTransactionWithTarget(nullptr);
     324             : }
     325             : 
     326             : bool
     327          29 : ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
     328             :                                            void* aCallbackData,
     329             :                                            EndTransactionFlags)
     330             : {
     331          58 :   PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Rasterization);
     332          58 :   AutoProfilerTracing tracing("Paint", "Rasterize");
     333             : 
     334          58 :   Maybe<TimeStamp> startTime;
     335          29 :   if (gfxPrefs::LayersDrawFPS()) {
     336           0 :     startTime = Some(TimeStamp::Now());
     337             :   }
     338             : 
     339             : #ifdef WIN32
     340             :   if (aCallbackData) {
     341             :     // Content processes don't get OnPaint called. So update here whenever we
     342             :     // may do Thebes drawing.
     343             :     gfxDWriteFont::UpdateClearTypeUsage();
     344             :   }
     345             : #endif
     346             : 
     347          58 :   AUTO_PROFILER_LABEL("ClientLayerManager::EndTransactionInternal", GRAPHICS);
     348             : 
     349             : #ifdef MOZ_LAYERS_HAVE_LOG
     350          29 :   MOZ_LAYERS_LOG(("  ----- (beginning paint)"));
     351          29 :   Log();
     352             : #endif
     353             : 
     354          29 :   NS_ASSERTION(InConstruction(), "Should be in construction phase");
     355          29 :   mPhase = PHASE_DRAWING;
     356             : 
     357          29 :   ClientLayer* root = ClientLayer::ToClientLayer(GetRoot());
     358             : 
     359          29 :   mTransactionIncomplete = false;
     360             : 
     361             :   // Apply pending tree updates before recomputing effective
     362             :   // properties.
     363          29 :   GetRoot()->ApplyPendingUpdatesToSubtree();
     364             : 
     365          29 :   mPaintedLayerCallback = aCallback;
     366          29 :   mPaintedLayerCallbackData = aCallbackData;
     367             : 
     368          29 :   GetRoot()->ComputeEffectiveTransforms(Matrix4x4());
     369             : 
     370             :   // Skip the painting if the device is in device-reset status.
     371          29 :   if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
     372          29 :     if (gfxPrefs::AlwaysPaint() && XRE_IsContentProcess()) {
     373           0 :       TimeStamp start = TimeStamp::Now();
     374           0 :       root->RenderLayer();
     375           0 :       mLastPaintTime = TimeStamp::Now() - start;
     376             :     } else {
     377          29 :       root->RenderLayer();
     378             :     }
     379             :   } else {
     380           0 :     gfxCriticalNote << "LayerManager::EndTransaction skip RenderLayer().";
     381             :   }
     382             : 
     383          29 :   if (!mRepeatTransaction && !GetRoot()->GetInvalidRegion().IsEmpty()) {
     384           0 :     GetRoot()->Mutated();
     385             :   }
     386             : 
     387          29 :   if (!mIsRepeatTransaction) {
     388          29 :     mAnimationReadyTime = TimeStamp::Now();
     389          29 :     GetRoot()->StartPendingAnimations(mAnimationReadyTime);
     390             :   }
     391             : 
     392          29 :   mPaintedLayerCallback = nullptr;
     393          29 :   mPaintedLayerCallbackData = nullptr;
     394             : 
     395             :   // Go back to the construction phase if the transaction isn't complete.
     396             :   // Layout will update the layer tree and call EndTransaction().
     397          29 :   mPhase = mTransactionIncomplete ? PHASE_CONSTRUCTION : PHASE_NONE;
     398             : 
     399          29 :   NS_ASSERTION(!aCallback || !mTransactionIncomplete,
     400             :                "If callback is not null, transaction must be complete");
     401             : 
     402          29 :   if (gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
     403           0 :     FrameLayerBuilder::InvalidateAllLayers(this);
     404             :   }
     405             : 
     406          29 :   if (startTime) {
     407           0 :     PaintTiming& pt = mForwarder->GetPaintTiming();
     408           0 :     pt.rasterMs() = (TimeStamp::Now() - startTime.value()).ToMilliseconds();
     409             :   }
     410             : 
     411          58 :   return !mTransactionIncomplete;
     412             : }
     413             : 
     414             : void
     415           2 : ClientLayerManager::StorePluginWidgetConfigurations(const nsTArray<nsIWidget::Configuration>& aConfigurations)
     416             : {
     417           2 :   if (mForwarder) {
     418           2 :     mForwarder->StorePluginWidgetConfigurations(aConfigurations);
     419             :   }
     420           2 : }
     421             : 
     422             : void
     423          28 : ClientLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
     424             :                                    void* aCallbackData,
     425             :                                    EndTransactionFlags aFlags)
     426             : {
     427          28 :   if (!mForwarder->IPCOpen()) {
     428           0 :     mInTransaction = false;
     429           0 :     return;
     430             :   }
     431             : 
     432          28 :   if (mWidget) {
     433          28 :     mWidget->PrepareWindowEffects();
     434             :   }
     435          28 :   EndTransactionInternal(aCallback, aCallbackData, aFlags);
     436          28 :   ForwardTransaction(!(aFlags & END_NO_REMOTE_COMPOSITE));
     437             : 
     438          28 :   if (mRepeatTransaction) {
     439           0 :     mRepeatTransaction = false;
     440           0 :     mIsRepeatTransaction = true;
     441           0 :     if (BeginTransaction()) {
     442           0 :       ClientLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
     443             :     }
     444           0 :     mIsRepeatTransaction = false;
     445             :   } else {
     446          28 :     MakeSnapshotIfRequired();
     447             :   }
     448             : 
     449          28 :   mInTransaction = false;
     450          28 :   mTransactionStart = TimeStamp();
     451             : }
     452             : 
     453             : bool
     454           1 : ClientLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
     455             : {
     456           1 :   mInTransaction = false;
     457             : 
     458           1 :   if (!mRoot || !mForwarder->IPCOpen()) {
     459           0 :     return false;
     460             :   }
     461             : 
     462           1 :   if (!EndTransactionInternal(nullptr, nullptr, aFlags)) {
     463             :     // Return without calling ForwardTransaction. This leaves the
     464             :     // ShadowLayerForwarder transaction open; the following
     465             :     // EndTransaction will complete it.
     466           0 :     return false;
     467             :   }
     468           1 :   if (mWidget) {
     469           1 :     mWidget->PrepareWindowEffects();
     470             :   }
     471           1 :   ForwardTransaction(!(aFlags & END_NO_REMOTE_COMPOSITE));
     472           1 :   MakeSnapshotIfRequired();
     473           1 :   return true;
     474             : }
     475             : 
     476             : CompositorBridgeChild *
     477          60 : ClientLayerManager::GetRemoteRenderer()
     478             : {
     479          60 :   if (!mWidget) {
     480           0 :     return nullptr;
     481             :   }
     482             : 
     483          60 :   return mWidget->GetRemoteRenderer();
     484             : }
     485             : 
     486             : CompositorBridgeChild*
     487          65 : ClientLayerManager::GetCompositorBridgeChild()
     488             : {
     489          65 :   if (!XRE_IsParentProcess()) {
     490           5 :     return CompositorBridgeChild::Get();
     491             :   }
     492          60 :   return GetRemoteRenderer();
     493             : }
     494             : 
     495             : void
     496           0 : ClientLayerManager::ScheduleComposite()
     497             : {
     498           0 :   mForwarder->Composite();
     499           0 : }
     500             : 
     501             : void
     502          54 : ClientLayerManager::DidComposite(uint64_t aTransactionId,
     503             :                                  const TimeStamp& aCompositeStart,
     504             :                                  const TimeStamp& aCompositeEnd)
     505             : {
     506          54 :   MOZ_ASSERT(mWidget);
     507             : 
     508             :   // |aTransactionId| will be > 0 if the compositor is acknowledging a shadow
     509             :   // layers transaction.
     510          54 :   if (aTransactionId) {
     511          27 :     nsIWidgetListener *listener = mWidget->GetWidgetListener();
     512          27 :     if (listener) {
     513          23 :       listener->DidCompositeWindow(aTransactionId, aCompositeStart, aCompositeEnd);
     514             :     }
     515          27 :     listener = mWidget->GetAttachedWidgetListener();
     516          27 :     if (listener) {
     517          27 :       listener->DidCompositeWindow(aTransactionId, aCompositeStart, aCompositeEnd);
     518             :     }
     519          27 :     mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
     520             :   }
     521             : 
     522             :   // These observers fire whether or not we were in a transaction.
     523          54 :   for (size_t i = 0; i < mDidCompositeObservers.Length(); i++) {
     524           0 :     mDidCompositeObservers[i]->DidComposite();
     525             :   }
     526          54 : }
     527             : 
     528             : void
     529           0 : ClientLayerManager::GetCompositorSideAPZTestData(APZTestData* aData) const
     530             : {
     531           0 :   if (mForwarder->HasShadowManager()) {
     532           0 :     if (!mForwarder->GetShadowManager()->SendGetAPZTestData(aData)) {
     533           0 :       NS_WARNING("Call to PLayerTransactionChild::SendGetAPZTestData() failed");
     534             :     }
     535             :   }
     536           0 : }
     537             : 
     538             : void
     539          29 : ClientLayerManager::SetTransactionIdAllocator(TransactionIdAllocator* aAllocator)
     540             : {
     541             :   // When changing the refresh driver, the previous refresh driver may never
     542             :   // receive updates of pending transactions it's waiting for. So clear the
     543             :   // waiting state before assigning another refresh driver.
     544          29 :   if (mTransactionIdAllocator && (aAllocator != mTransactionIdAllocator)) {
     545           1 :     mTransactionIdAllocator->ClearPendingTransactions();
     546             : 
     547             :     // We should also reset the transaction id of the new allocator to previous
     548             :     // allocator's last transaction id, so that completed transactions for
     549             :     // previous allocator will be ignored and won't confuse the new allocator.
     550           1 :     if (aAllocator) {
     551           1 :       aAllocator->ResetInitialTransactionId(mTransactionIdAllocator->LastTransactionId());
     552             :     }
     553             :   }
     554             : 
     555          29 :   mTransactionIdAllocator = aAllocator;
     556          29 : }
     557             : 
     558             : float
     559           0 : ClientLayerManager::RequestProperty(const nsAString& aProperty)
     560             : {
     561           0 :   if (mForwarder->HasShadowManager()) {
     562             :     float value;
     563           0 :     if (!mForwarder->GetShadowManager()->SendRequestProperty(nsString(aProperty), &value)) {
     564           0 :       NS_WARNING("Call to PLayerTransactionChild::SendGetAPZTestData() failed");
     565             :     }
     566           0 :     return value;
     567             :   }
     568           0 :   return -1;
     569             : }
     570             : 
     571             : void
     572           0 : ClientLayerManager::StartNewRepaintRequest(SequenceNumber aSequenceNumber)
     573             : {
     574           0 :   if (gfxPrefs::APZTestLoggingEnabled()) {
     575           0 :     mApzTestData.StartNewRepaintRequest(aSequenceNumber);
     576             :   }
     577           0 : }
     578             : 
     579             : void
     580           0 : ClientLayerManager::GetFrameUniformity(FrameUniformityData* aOutData)
     581             : {
     582           0 :   MOZ_ASSERT(XRE_IsParentProcess(), "Frame Uniformity only supported in parent process");
     583             : 
     584           0 :   if (HasShadowManager()) {
     585           0 :     CompositorBridgeChild* child = GetRemoteRenderer();
     586           0 :     child->SendGetFrameUniformity(aOutData);
     587           0 :     return;
     588             :   }
     589             : 
     590           0 :   return LayerManager::GetFrameUniformity(aOutData);
     591             : }
     592             : 
     593             : void
     594          29 : ClientLayerManager::MakeSnapshotIfRequired()
     595             : {
     596          29 :   if (!mShadowTarget) {
     597          29 :     return;
     598             :   }
     599           0 :   if (mWidget) {
     600           0 :     if (CompositorBridgeChild* remoteRenderer = GetRemoteRenderer()) {
     601             :       // The compositor doesn't draw to a different sized surface
     602             :       // when there's a rotation. Instead we rotate the result
     603             :       // when drawing into dt
     604           0 :       LayoutDeviceIntRect outerBounds = mWidget->GetBounds();
     605             : 
     606           0 :       IntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
     607           0 :       if (mTargetRotation) {
     608             :         bounds =
     609           0 :           RotateRect(bounds, outerBounds.ToUnknownRect(), mTargetRotation);
     610             :       }
     611             : 
     612           0 :       SurfaceDescriptor inSnapshot;
     613           0 :       if (!bounds.IsEmpty() &&
     614           0 :           mForwarder->AllocSurfaceDescriptor(bounds.Size(),
     615             :                                              gfxContentType::COLOR_ALPHA,
     616             :                                              &inSnapshot)) {
     617             : 
     618             :         // Make a copy of |inSnapshot| because the call to send it over IPC
     619             :         // will call forget() on the Shmem inside, and zero it out.
     620           0 :         SurfaceDescriptor outSnapshot = inSnapshot;
     621             : 
     622           0 :         if (remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
     623           0 :           RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(outSnapshot);
     624           0 :           DrawTarget* dt = mShadowTarget->GetDrawTarget();
     625             : 
     626           0 :           Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
     627           0 :           Rect srcRect(0, 0, bounds.width, bounds.height);
     628             : 
     629             :           gfx::Matrix rotate =
     630           0 :             ComputeTransformForUnRotation(outerBounds.ToUnknownRect(),
     631           0 :                                           mTargetRotation);
     632             : 
     633           0 :           gfx::Matrix oldMatrix = dt->GetTransform();
     634           0 :           dt->SetTransform(rotate * oldMatrix);
     635             :           dt->DrawSurface(surf, dstRect, srcRect,
     636           0 :                           DrawSurfaceOptions(),
     637           0 :                           DrawOptions(1.0f, CompositionOp::OP_OVER));
     638           0 :           dt->SetTransform(oldMatrix);
     639             :         }
     640           0 :         mForwarder->DestroySurfaceDescriptor(&outSnapshot);
     641             :       }
     642             :     }
     643             :   }
     644           0 :   mShadowTarget = nullptr;
     645             : }
     646             : 
     647             : void
     648           1 : ClientLayerManager::FlushRendering()
     649             : {
     650           1 :   if (mWidget) {
     651           1 :     if (CompositorBridgeChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
     652           1 :       if (mWidget->SynchronouslyRepaintOnResize() || gfxPrefs::LayersForceSynchronousResize()) {
     653           1 :         remoteRenderer->SendFlushRendering();
     654             :       } else {
     655           0 :         remoteRenderer->SendFlushRenderingAsync();
     656             :       }
     657             :     }
     658             :   }
     659           1 : }
     660             : 
     661             : void
     662           0 : ClientLayerManager::WaitOnTransactionProcessed()
     663             : {
     664           0 :   CompositorBridgeChild* remoteRenderer = GetCompositorBridgeChild();
     665           0 :   if (remoteRenderer) {
     666           0 :     remoteRenderer->SendWaitOnTransactionProcessed();
     667             :   }
     668           0 : }
     669             : void
     670           1 : ClientLayerManager::UpdateTextureFactoryIdentifier(const TextureFactoryIdentifier& aNewIdentifier,
     671             :                                                    uint64_t aDeviceResetSeqNo)
     672             : {
     673           1 :   MOZ_ASSERT_IF(XRE_IsContentProcess(),
     674             :                 aDeviceResetSeqNo == CompositorBridgeChild::Get()->DeviceResetSequenceNumber());
     675             : 
     676           1 :   mForwarder->IdentifyTextureHost(aNewIdentifier);
     677           1 :   mDeviceResetSequenceNumber = aDeviceResetSeqNo;
     678           1 : }
     679             : 
     680             : void
     681           1 : ClientLayerManager::SendInvalidRegion(const nsIntRegion& aRegion)
     682             : {
     683           1 :   if (mWidget) {
     684           1 :     if (CompositorBridgeChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
     685           1 :       remoteRenderer->SendNotifyRegionInvalidated(aRegion);
     686             :     }
     687             :   }
     688           1 : }
     689             : 
     690             : uint32_t
     691           0 : ClientLayerManager::StartFrameTimeRecording(int32_t aBufferSize)
     692             : {
     693           0 :   CompositorBridgeChild* renderer = GetRemoteRenderer();
     694           0 :   if (renderer) {
     695             :     uint32_t startIndex;
     696           0 :     renderer->SendStartFrameTimeRecording(aBufferSize, &startIndex);
     697           0 :     return startIndex;
     698             :   }
     699           0 :   return -1;
     700             : }
     701             : 
     702             : void
     703           0 : ClientLayerManager::StopFrameTimeRecording(uint32_t         aStartIndex,
     704             :                                            nsTArray<float>& aFrameIntervals)
     705             : {
     706           0 :   CompositorBridgeChild* renderer = GetRemoteRenderer();
     707           0 :   if (renderer) {
     708           0 :     renderer->SendStopFrameTimeRecording(aStartIndex, &aFrameIntervals);
     709             :   }
     710           0 : }
     711             : 
     712             : void
     713          29 : ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
     714             : {
     715          58 :   AutoProfilerTracing tracing("Paint", "ForwardTransaction");
     716          29 :   TimeStamp start = TimeStamp::Now();
     717             : 
     718             :   // Skip the synchronization for buffer since we also skip the painting during
     719             :   // device-reset status.
     720          29 :   if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
     721          29 :     if (mForwarder->GetSyncObject() &&
     722           0 :         mForwarder->GetSyncObject()->IsSyncObjectValid()) {
     723           0 :       mForwarder->GetSyncObject()->FinalizeFrame();
     724             :     }
     725             :   }
     726             : 
     727          29 :   mPhase = PHASE_FORWARD;
     728             : 
     729          29 :   mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(!mIsRepeatTransaction);
     730          29 :   TimeStamp transactionStart;
     731          29 :   if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) {
     732          26 :     transactionStart = mTransactionIdAllocator->GetTransactionStart();
     733             :   } else {
     734           3 :     transactionStart = mTransactionStart;
     735             :   }
     736             : 
     737          29 :   if (gfxPrefs::AlwaysPaint() && XRE_IsContentProcess()) {
     738           0 :     mForwarder->SendPaintTime(mLatestTransactionId, mLastPaintTime);
     739             :   }
     740             : 
     741             :   // forward this transaction's changeset to our LayerManagerComposite
     742          29 :   bool sent = false;
     743          29 :   bool ok = mForwarder->EndTransaction(
     744             :     mRegionToClear, mLatestTransactionId, aScheduleComposite,
     745          29 :     mPaintSequenceNumber, mIsRepeatTransaction, transactionStart,
     746          29 :     &sent);
     747          29 :   if (ok) {
     748          29 :     if (sent) {
     749          28 :       mNeedsComposite = false;
     750             :     }
     751           0 :   } else if (HasShadowManager()) {
     752           0 :     NS_WARNING("failed to forward Layers transaction");
     753             :   }
     754             : 
     755          29 :   if (!sent) {
     756             :     // Clear the transaction id so that it doesn't get returned
     757             :     // unless we forwarded to somewhere that doesn't actually
     758             :     // have a compositor.
     759           1 :     mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId);
     760             :   }
     761             : 
     762          29 :   mPhase = PHASE_NONE;
     763             : 
     764             :   // this may result in Layers being deleted, which results in
     765             :   // PLayer::Send__delete__() and DeallocShmem()
     766          29 :   mKeepAlive.Clear();
     767             : 
     768          29 :   TabChild* window = mWidget ? mWidget->GetOwningTabChild() : nullptr;
     769          29 :   if (window) {
     770           4 :     TimeStamp end = TimeStamp::Now();
     771           4 :     window->DidRequestComposite(start, end);
     772             :   }
     773          29 : }
     774             : 
     775             : ShadowableLayer*
     776         490 : ClientLayerManager::Hold(Layer* aLayer)
     777             : {
     778         490 :   MOZ_ASSERT(HasShadowManager(),
     779             :              "top-level tree, no shadow tree to remote to");
     780             : 
     781         490 :   ShadowableLayer* shadowable = ClientLayer::ToClientLayer(aLayer);
     782         490 :   MOZ_ASSERT(shadowable, "trying to remote an unshadowable layer");
     783             : 
     784         490 :   mKeepAlive.AppendElement(aLayer);
     785         490 :   return shadowable;
     786             : }
     787             : 
     788             : bool
     789          85 : ClientLayerManager::IsCompositingCheap()
     790             : {
     791             :   // Whether compositing is cheap depends on the parent backend.
     792         255 :   return mForwarder->mShadowManager &&
     793         255 :          LayerManager::IsCompositingCheap(mForwarder->GetCompositorBackendType());
     794             : }
     795             : 
     796             : bool
     797           0 : ClientLayerManager::AreComponentAlphaLayersEnabled()
     798             : {
     799           0 :   return GetCompositorBackendType() != LayersBackend::LAYERS_BASIC &&
     800           0 :          AsShadowForwarder()->SupportsComponentAlpha() &&
     801           0 :          LayerManager::AreComponentAlphaLayersEnabled();
     802             : }
     803             : 
     804             : bool
     805           0 : ClientLayerManager::SupportsBackdropCopyForComponentAlpha()
     806             : {
     807           0 :   const TextureFactoryIdentifier& ident = AsShadowForwarder()->GetTextureFactoryIdentifier();
     808           0 :   return ident.mSupportsBackdropCopyForComponentAlpha;
     809             : }
     810             : 
     811             : void
     812           3 : ClientLayerManager::SetIsFirstPaint()
     813             : {
     814           3 :   mForwarder->SetIsFirstPaint();
     815           3 : }
     816             : 
     817             : void
     818          29 : ClientLayerManager::SetFocusTarget(const FocusTarget& aFocusTarget)
     819             : {
     820          29 :   mForwarder->SetFocusTarget(aFocusTarget);
     821          29 : }
     822             : 
     823             : void
     824           0 : ClientLayerManager::ClearCachedResources(Layer* aSubtree)
     825             : {
     826           0 :   if (mDestroyed) {
     827             :     // ClearCachedResource was already called by ClientLayerManager::Destroy
     828           0 :     return;
     829             :   }
     830           0 :   MOZ_ASSERT(!HasShadowManager() || !aSubtree);
     831           0 :   mForwarder->ClearCachedResources();
     832           0 :   if (aSubtree) {
     833           0 :     ClearLayer(aSubtree);
     834           0 :   } else if (mRoot) {
     835           0 :     ClearLayer(mRoot);
     836             :   }
     837             : }
     838             : 
     839             : void
     840           0 : ClientLayerManager::HandleMemoryPressure()
     841             : {
     842           0 :   if (mRoot) {
     843           0 :     HandleMemoryPressureLayer(mRoot);
     844             :   }
     845             : 
     846           0 :   if (GetCompositorBridgeChild()) {
     847           0 :     GetCompositorBridgeChild()->HandleMemoryPressure();
     848             :   }
     849           0 : }
     850             : 
     851             : void
     852           0 : ClientLayerManager::ClearLayer(Layer* aLayer)
     853             : {
     854           0 :   aLayer->ClearCachedResources();
     855           0 :   for (Layer* child = aLayer->GetFirstChild(); child;
     856             :        child = child->GetNextSibling()) {
     857           0 :     ClearLayer(child);
     858             :   }
     859           0 : }
     860             : 
     861             : void
     862           0 : ClientLayerManager::HandleMemoryPressureLayer(Layer* aLayer)
     863             : {
     864           0 :   ClientLayer::ToClientLayer(aLayer)->HandleMemoryPressure();
     865           0 :   for (Layer* child = aLayer->GetFirstChild(); child;
     866             :        child = child->GetNextSibling()) {
     867           0 :     HandleMemoryPressureLayer(child);
     868             :   }
     869           0 : }
     870             : 
     871             : void
     872           0 : ClientLayerManager::GetBackendName(nsAString& aName)
     873             : {
     874           0 :   switch (mForwarder->GetCompositorBackendType()) {
     875           0 :     case LayersBackend::LAYERS_NONE: aName.AssignLiteral("None"); return;
     876           0 :     case LayersBackend::LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
     877           0 :     case LayersBackend::LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
     878             :     case LayersBackend::LAYERS_D3D11: {
     879             : #ifdef XP_WIN
     880             :       if (DeviceManagerDx::Get()->IsWARP()) {
     881             :         aName.AssignLiteral("Direct3D 11 WARP");
     882             :       } else {
     883             :         aName.AssignLiteral("Direct3D 11");
     884             :       }
     885             : #endif
     886           0 :       return;
     887             :     }
     888           0 :     default: MOZ_CRASH("Invalid backend");
     889             :   }
     890             : }
     891             : 
     892             : bool
     893           1 : ClientLayerManager::AsyncPanZoomEnabled() const
     894             : {
     895           1 :   return mWidget && mWidget->AsyncPanZoomEnabled();
     896             : }
     897             : 
     898             : void
     899           2 : ClientLayerManager::SetLayerObserverEpoch(uint64_t aLayerObserverEpoch)
     900             : {
     901           2 :   mForwarder->SetLayerObserverEpoch(aLayerObserverEpoch);
     902           2 : }
     903             : 
     904             : void
     905           0 : ClientLayerManager::AddDidCompositeObserver(DidCompositeObserver* aObserver)
     906             : {
     907           0 :   if (!mDidCompositeObservers.Contains(aObserver)) {
     908           0 :     mDidCompositeObservers.AppendElement(aObserver);
     909             :   }
     910           0 : }
     911             : 
     912             : void
     913           0 : ClientLayerManager::RemoveDidCompositeObserver(DidCompositeObserver* aObserver)
     914             : {
     915           0 :   mDidCompositeObservers.RemoveElement(aObserver);
     916           0 : }
     917             : 
     918             : already_AddRefed<PersistentBufferProvider>
     919           0 : ClientLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize,
     920             :                                                    gfx::SurfaceFormat aFormat)
     921             : {
     922             :   // Don't use a shared buffer provider if compositing is considered "not cheap"
     923             :   // because the canvas will most likely be flattened into a thebes layer instead
     924             :   // of being sent to the compositor, in which case rendering into shared memory
     925             :   // is wasteful.
     926           0 :   if (IsCompositingCheap() &&
     927           0 :       gfxPrefs::PersistentBufferProviderSharedEnabled()) {
     928             :     RefPtr<PersistentBufferProvider> provider
     929           0 :       = PersistentBufferProviderShared::Create(aSize, aFormat, AsShadowForwarder());
     930           0 :     if (provider) {
     931           0 :       return provider.forget();
     932             :     }
     933             :   }
     934             : 
     935           0 :   return LayerManager::CreatePersistentBufferProvider(aSize, aFormat);
     936             : }
     937             : 
     938             : 
     939          46 : ClientLayer::~ClientLayer()
     940             : {
     941          23 :   MOZ_COUNT_DTOR(ClientLayer);
     942          23 : }
     943             : 
     944             : } // namespace layers
     945             : } // namespace mozilla

Generated by: LCOV version 1.13