LCOV - code coverage report
Current view: top level - gfx/layers/mlgpu - LayerManagerMLGPU.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 247 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 40 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "LayerManagerMLGPU.h"
       7             : #include "LayerTreeInvalidation.h"
       8             : #include "PaintedLayerMLGPU.h"
       9             : #include "ImageLayerMLGPU.h"
      10             : #include "CanvasLayerMLGPU.h"
      11             : #include "GeckoProfiler.h"              // for profiler_*
      12             : #include "MLGDevice.h"
      13             : #include "RenderPassMLGPU.h"
      14             : #include "RenderViewMLGPU.h"
      15             : #include "ShaderDefinitionsMLGPU.h"
      16             : #include "SharedBufferMLGPU.h"
      17             : #include "UnitTransforms.h"
      18             : #include "TextureSourceProviderMLGPU.h"
      19             : #include "TreeTraversal.h"
      20             : #include "FrameBuilder.h"
      21             : #include "LayersLogging.h"
      22             : #include "UtilityMLGPU.h"
      23             : #include "mozilla/layers/Diagnostics.h"
      24             : #include "mozilla/layers/TextRenderer.h"
      25             : 
      26             : #ifdef XP_WIN
      27             : #include "mozilla/widget/WinCompositorWidget.h"
      28             : #include "mozilla/gfx/DeviceManagerDx.h"
      29             : #endif
      30             : 
      31             : using namespace std;
      32             : 
      33             : namespace mozilla {
      34             : namespace layers {
      35             : 
      36             : using namespace gfx;
      37             : 
      38             : static const int kDebugOverlayX = 2;
      39             : static const int kDebugOverlayY = 5;
      40             : static const int kDebugOverlayMaxWidth = 600;
      41             : static const int kDebugOverlayMaxHeight = 96;
      42             : 
      43           0 : LayerManagerMLGPU::LayerManagerMLGPU(widget::CompositorWidget* aWidget)
      44             :  : mWidget(aWidget),
      45             :    mDrawDiagnostics(false),
      46             :    mUsingInvalidation(false),
      47           0 :    mCurrentFrame(nullptr)
      48             : {
      49           0 :   if (!aWidget) {
      50           0 :     return;
      51             :   }
      52             : 
      53             : #ifdef WIN32
      54             :   mDevice = DeviceManagerDx::Get()->GetMLGDevice();
      55             : #endif
      56           0 :   if (!mDevice || !mDevice->IsValid()) {
      57           0 :     gfxWarning() << "Could not acquire an MLGDevice!";
      58           0 :     return;
      59             :   }
      60             : 
      61           0 :   mSwapChain = mDevice->CreateSwapChainForWidget(aWidget);
      62           0 :   if (!mSwapChain) {
      63           0 :     gfxWarning() << "Could not acquire an MLGSwapChain!";
      64           0 :     return;
      65             :   }
      66             : 
      67           0 :   mDiagnostics = MakeUnique<Diagnostics>();
      68           0 :   mTextRenderer = new TextRenderer();
      69             : }
      70             : 
      71           0 : LayerManagerMLGPU::~LayerManagerMLGPU()
      72             : {
      73           0 :   if (mTextureSourceProvider) {
      74           0 :     mTextureSourceProvider->Destroy();
      75             :   }
      76           0 : }
      77             : 
      78             : bool
      79           0 : LayerManagerMLGPU::Initialize()
      80             : {
      81           0 :   if (!mDevice || !mSwapChain) {
      82           0 :     return false;
      83             :   }
      84             : 
      85           0 :   mTextureSourceProvider = new TextureSourceProviderMLGPU(this, mDevice);
      86           0 :   return true;
      87             : }
      88             : 
      89             : void
      90           0 : LayerManagerMLGPU::Destroy()
      91             : {
      92           0 :   if (IsDestroyed()) {
      93           0 :     return;
      94             :   }
      95             : 
      96           0 :   LayerManager::Destroy();
      97             : 
      98           0 :   if (mDevice && mDevice->IsValid()) {
      99           0 :     mDevice->Flush();
     100             :   }
     101           0 :   if (mSwapChain) {
     102           0 :     mSwapChain->Destroy();
     103           0 :     mSwapChain = nullptr;
     104             :   }
     105           0 :   if (mTextureSourceProvider) {
     106           0 :     mTextureSourceProvider->Destroy();
     107           0 :     mTextureSourceProvider = nullptr;
     108             :   }
     109           0 :   mWidget = nullptr;
     110           0 :   mDevice = nullptr;
     111             : }
     112             : 
     113             : void
     114           0 : LayerManagerMLGPU::ForcePresent()
     115             : {
     116           0 :   if (!mDevice->IsValid()) {
     117           0 :     return;
     118             :   }
     119             : 
     120           0 :   IntSize windowSize = mWidget->GetClientSize().ToUnknownSize();
     121           0 :   if (mSwapChain->GetSize() != windowSize) {
     122           0 :     return;
     123             :   }
     124             : 
     125           0 :   mSwapChain->ForcePresent();
     126             : }
     127             : 
     128             : already_AddRefed<ContainerLayer>
     129           0 : LayerManagerMLGPU::CreateContainerLayer()
     130             : {
     131           0 :   return MakeAndAddRef<ContainerLayerMLGPU>(this);
     132             : }
     133             : 
     134             : already_AddRefed<ColorLayer>
     135           0 : LayerManagerMLGPU::CreateColorLayer()
     136             : {
     137           0 :   return MakeAndAddRef<ColorLayerMLGPU>(this);
     138             : }
     139             : 
     140             : already_AddRefed<RefLayer>
     141           0 : LayerManagerMLGPU::CreateRefLayer()
     142             : {
     143           0 :   return MakeAndAddRef<RefLayerMLGPU>(this);
     144             : }
     145             : 
     146             : already_AddRefed<PaintedLayer>
     147           0 : LayerManagerMLGPU::CreatePaintedLayer()
     148             : {
     149           0 :   return MakeAndAddRef<PaintedLayerMLGPU>(this);
     150             : }
     151             : 
     152             : already_AddRefed<ImageLayer>
     153           0 : LayerManagerMLGPU::CreateImageLayer()
     154             : {
     155           0 :   return MakeAndAddRef<ImageLayerMLGPU>(this);
     156             : }
     157             : 
     158             : already_AddRefed<BorderLayer>
     159           0 : LayerManagerMLGPU::CreateBorderLayer()
     160             : {
     161           0 :   MOZ_ASSERT_UNREACHABLE("Not yet implemented");
     162             :   return nullptr;
     163             : }
     164             : 
     165             : already_AddRefed<TextLayer>
     166           0 : LayerManagerMLGPU::CreateTextLayer()
     167             : {
     168           0 :   MOZ_ASSERT_UNREACHABLE("Not yet implemented");
     169             :   return nullptr;
     170             : }
     171             : 
     172             : already_AddRefed<CanvasLayer>
     173           0 : LayerManagerMLGPU::CreateCanvasLayer()
     174             : {
     175           0 :   return MakeAndAddRef<CanvasLayerMLGPU>(this);
     176             : }
     177             : 
     178             : TextureFactoryIdentifier
     179           0 : LayerManagerMLGPU::GetTextureFactoryIdentifier()
     180             : {
     181           0 :   TextureFactoryIdentifier ident;
     182           0 :   if (mDevice) {
     183           0 :     ident = mDevice->GetTextureFactoryIdentifier();
     184             :   }
     185           0 :   ident.mSupportsBackdropCopyForComponentAlpha = SupportsBackdropCopyForComponentAlpha();
     186           0 :   ident.mUsingAdvancedLayers = true;
     187           0 :   return ident;
     188             : }
     189             : 
     190             : LayersBackend
     191           0 : LayerManagerMLGPU::GetBackendType()
     192             : {
     193           0 :   return mDevice ? mDevice->GetLayersBackend() : LayersBackend::LAYERS_NONE;
     194             : }
     195             : 
     196             : void
     197           0 : LayerManagerMLGPU::SetRoot(Layer* aLayer)
     198             : {
     199           0 :   mRoot = aLayer;
     200           0 : }
     201             : 
     202             : bool
     203           0 : LayerManagerMLGPU::BeginTransaction()
     204             : {
     205           0 :   MOZ_ASSERT(!mTarget);
     206           0 :   return true;
     207             : }
     208             : 
     209             : void
     210           0 : LayerManagerMLGPU::BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget,
     211             :                                                   const gfx::IntRect& aRect)
     212             : {
     213           0 :   MOZ_ASSERT(!mTarget);
     214             : 
     215           0 :   mTarget = aTarget;
     216           0 :   mTargetRect = aRect;
     217           0 :   return;
     218             : }
     219             : 
     220             : // Helper class for making sure textures are unlocked.
     221             : class MOZ_STACK_CLASS AutoUnlockAllTextures
     222             : {
     223             : public:
     224           0 :   explicit AutoUnlockAllTextures(MLGDevice* aDevice)
     225           0 :    : mDevice(aDevice)
     226           0 :   {}
     227           0 :   ~AutoUnlockAllTextures() {
     228           0 :     mDevice->UnlockAllTextures();
     229           0 :   }
     230             : 
     231             : private:
     232             :   RefPtr<MLGDevice> mDevice;
     233             : };
     234             : 
     235             : void
     236           0 : LayerManagerMLGPU::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFlags aFlags)
     237             : {
     238           0 :   AUTO_PROFILER_LABEL("LayerManager::EndTransaction", GRAPHICS);
     239             : 
     240           0 :   SetCompositionTime(aTimeStamp);
     241             : 
     242           0 :   TextureSourceProvider::AutoReadUnlockTextures unlock(mTextureSourceProvider);
     243             : 
     244           0 :   if (!mRoot || (aFlags & END_NO_IMMEDIATE_REDRAW) || !mWidget) {
     245           0 :     return;
     246             :   }
     247             : 
     248           0 :   mCompositionStartTime = TimeStamp::Now();
     249             : 
     250           0 :   IntSize windowSize = mWidget->GetClientSize().ToUnknownSize();
     251           0 :   if (windowSize.IsEmpty()) {
     252           0 :     return;
     253             :   }
     254             : 
     255             :   // Resize the window if needed.
     256           0 :   if (mSwapChain->GetSize() != windowSize) {
     257             :     // Note: all references to the backbuffer must be cleared.
     258           0 :     mDevice->SetRenderTarget(nullptr);
     259           0 :     if (!mSwapChain->ResizeBuffers(windowSize)) {
     260           0 :       gfxCriticalNote << "Could not resize the swapchain (" <<
     261           0 :         hexa(windowSize.width) << "," << hexa(windowSize.height) << ")";
     262           0 :       return;
     263             :     }
     264             :   }
     265             : 
     266             :   // Don't draw the diagnostic overlay if we want to snapshot the output.
     267           0 :   mDrawDiagnostics = gfxPrefs::LayersDrawFPS() && !mTarget;
     268           0 :   mUsingInvalidation = gfxPrefs::AdvancedLayersUseInvalidation();
     269             : 
     270             :   // Compute transforms - and the changed area, if enabled.
     271           0 :   mRoot->ComputeEffectiveTransforms(Matrix4x4());
     272           0 :   ComputeInvalidRegion();
     273             : 
     274             :   // Build and execute draw commands, and present.
     275           0 :   if (PreRender()) {
     276           0 :     Composite();
     277           0 :     PostRender();
     278             :   }
     279             : 
     280           0 :   mTextureSourceProvider->FlushPendingNotifyNotUsed();
     281             : 
     282             :   // Finish composition.
     283           0 :   mLastCompositionEndTime = TimeStamp::Now();
     284             : }
     285             : 
     286             : void
     287           0 : LayerManagerMLGPU::Composite()
     288             : {
     289           0 :   AUTO_PROFILER_LABEL("LayerManagerMLGPU::Composite", GRAPHICS);
     290             : 
     291             :   // Don't composite if we're minimized/hidden, or if there is nothing to draw.
     292           0 :   if (mWidget->IsHidden()) {
     293           0 :     return;
     294             :   }
     295             : 
     296             :   // Make sure the diagnostic area gets invalidated. We do this now, rather than
     297             :   // earlier, so we don't accidentally cause extra composites.
     298           0 :   Maybe<IntRect> diagnosticRect;
     299           0 :   if (mDrawDiagnostics) {
     300           0 :     diagnosticRect = Some(IntRect(
     301             :       kDebugOverlayX, kDebugOverlayY,
     302           0 :       kDebugOverlayMaxWidth, kDebugOverlayMaxHeight));
     303             :   }
     304             : 
     305             :   AL_LOG("Computed invalid region: %s\n", Stringify(mInvalidRegion).c_str());
     306             : 
     307             :   // Now that we have the final invalid region, give it to the swap chain which
     308             :   // will tell us if we still need to render.
     309           0 :   if (!mSwapChain->ApplyNewInvalidRegion(Move(mInvalidRegion), diagnosticRect)) {
     310           0 :     return;
     311             :   }
     312             : 
     313           0 :   AutoUnlockAllTextures autoUnlock(mDevice);
     314             : 
     315           0 :   mDevice->BeginFrame();
     316             : 
     317           0 :   RenderLayers();
     318             : 
     319           0 :   if (mDrawDiagnostics) {
     320           0 :     DrawDebugOverlay();
     321             :   }
     322             : 
     323           0 :   if (mTarget) {
     324           0 :     mSwapChain->CopyBackbuffer(mTarget, mTargetRect);
     325           0 :     mTarget = nullptr;
     326           0 :     mTargetRect = IntRect();
     327             :   }
     328           0 :   mSwapChain->Present();
     329             : 
     330             :   // We call this here to mimic the behavior in LayerManagerComposite, as to
     331             :   // not change what Talos measures. That is, we do not record an empty frame
     332             :   // as a frame, since we short-circuit at the top of this function.
     333           0 :   RecordFrame();
     334             : 
     335           0 :   mDevice->EndFrame();
     336             : }
     337             : 
     338             : void
     339           0 : LayerManagerMLGPU::RenderLayers()
     340             : {
     341           0 :   AUTO_PROFILER_LABEL("LayerManagerMLGPU::RenderLayers", GRAPHICS);
     342             : 
     343             :   // Traverse the layer tree and assign each layer to a render target.
     344           0 :   FrameBuilder builder(this, mSwapChain);
     345           0 :   mCurrentFrame = &builder;
     346             : 
     347           0 :   if (!builder.Build()) {
     348           0 :     return;
     349             :   }
     350             : 
     351           0 :   if (mDrawDiagnostics) {
     352           0 :     mDiagnostics->RecordPrepareTime((TimeStamp::Now() - mCompositionStartTime).ToMilliseconds());
     353             :   }
     354             : 
     355             :   // Make sure we acquire/release the sync object.
     356           0 :   if (!mDevice->Synchronize()) {
     357             :     // Catastrophic failure - probably a device reset.
     358           0 :     return;
     359             :   }
     360             : 
     361           0 :   TimeStamp start = TimeStamp::Now();
     362             : 
     363             :   // Upload shared buffers.
     364           0 :   mDevice->FinishSharedBufferUse();
     365             : 
     366             :   // Prepare the pipeline.
     367           0 :   if (mDrawDiagnostics) {
     368           0 :     IntSize size = mSwapChain->GetBackBufferInvalidRegion().GetBounds().Size();
     369           0 :     uint32_t numPixels = size.width * size.height;
     370           0 :     mDevice->StartDiagnostics(numPixels);
     371             :   }
     372             : 
     373             :   // Execute all render passes.
     374           0 :   builder.Render();
     375           0 :   mCurrentFrame = nullptr;
     376             : 
     377           0 :   if (mDrawDiagnostics) {
     378           0 :     mDiagnostics->RecordCompositeTime((TimeStamp::Now() - start).ToMilliseconds());
     379           0 :     mDevice->EndDiagnostics();
     380             :   }
     381             : }
     382             : 
     383             : void
     384           0 : LayerManagerMLGPU::DrawDebugOverlay()
     385             : {
     386           0 :   IntSize windowSize = mSwapChain->GetSize();
     387             : 
     388           0 :   GPUStats stats;
     389           0 :   mDevice->GetDiagnostics(&stats);
     390           0 :   stats.mScreenPixels = windowSize.width * windowSize.height;
     391             : 
     392           0 :   std::string text = mDiagnostics->GetFrameOverlayString(stats);
     393             :   RefPtr<TextureSource> texture = mTextRenderer->RenderText(
     394             :     mTextureSourceProvider,
     395             :     text,
     396             :     30,
     397             :     600,
     398           0 :     TextRenderer::FontType::FixedWidth);
     399           0 :   if (!texture) {
     400           0 :     return;
     401             :   }
     402             : 
     403           0 :   if (mUsingInvalidation &&
     404           0 :       (texture->GetSize().width > kDebugOverlayMaxWidth ||
     405           0 :        texture->GetSize().height > kDebugOverlayMaxHeight))
     406             :   {
     407           0 :     gfxCriticalNote << "Diagnostic overlay exceeds invalidation area: %s" << Stringify(texture->GetSize()).c_str();
     408             :   }
     409             : 
     410           0 :   struct DebugRect {
     411             :     Rect bounds;
     412             :     Rect texCoords;
     413             :   };
     414             : 
     415           0 :   if (!mDiagnosticVertices) {
     416           0 :     DebugRect rect;
     417           0 :     rect.bounds = Rect(Point(kDebugOverlayX, kDebugOverlayY), Size(texture->GetSize()));
     418           0 :     rect.texCoords = Rect(0.0, 0.0, 1.0, 1.0);
     419             : 
     420           0 :     VertexStagingBuffer instances;
     421           0 :     if (!instances.AppendItem(rect)) {
     422           0 :       return;
     423             :     }
     424             : 
     425           0 :     mDiagnosticVertices = mDevice->CreateBuffer(
     426             :       MLGBufferType::Vertex,
     427           0 :       instances.NumItems() * instances.SizeOfItem(),
     428             :       MLGUsage::Immutable,
     429           0 :       instances.GetBufferStart());
     430           0 :     if (!mDiagnosticVertices) {
     431           0 :       return;
     432             :     }
     433             :   }
     434             : 
     435             :   // Note: we rely on the world transform being correctly left bound by the
     436             :   // outermost render view.
     437           0 :   mDevice->SetScissorRect(Nothing());
     438           0 :   mDevice->SetDepthTestMode(MLGDepthTestMode::Disabled);
     439           0 :   mDevice->SetTopology(MLGPrimitiveTopology::UnitQuad);
     440           0 :   mDevice->SetVertexShader(VertexShaderID::DiagnosticText);
     441           0 :   mDevice->SetVertexBuffer(1, mDiagnosticVertices, sizeof(DebugRect));
     442           0 :   mDevice->SetPixelShader(PixelShaderID::DiagnosticText);
     443           0 :   mDevice->SetBlendState(MLGBlendState::Over);
     444           0 :   mDevice->SetPSTexture(0, texture);
     445           0 :   mDevice->SetSamplerMode(0, SamplerMode::Point);
     446           0 :   mDevice->DrawInstanced(4, 1, 0, 0);
     447             : }
     448             : 
     449             : void
     450           0 : LayerManagerMLGPU::ComputeInvalidRegion()
     451             : {
     452             :   // If invalidation is disabled, throw away cloned properties and redraw the
     453             :   // whole target area.
     454           0 :   if (!mUsingInvalidation) {
     455           0 :     mInvalidRegion = mTarget ? mTargetRect : mRenderBounds;
     456           0 :     mNextFrameInvalidRegion.SetEmpty();
     457           0 :     return;
     458             :   }
     459             : 
     460           0 :   nsIntRegion changed;
     461           0 :   if (mClonedLayerTreeProperties) {
     462           0 :     changed = mClonedLayerTreeProperties->ComputeDifferences(mRoot, nullptr);
     463             :   } else {
     464           0 :     changed = mRenderBounds;
     465             :   }
     466             : 
     467             :   // We compute the change region, but if we're painting to a target, we save
     468             :   // it for the next frame instead.
     469           0 :   if (mTarget) {
     470           0 :     mInvalidRegion = mTargetRect;
     471           0 :     mNextFrameInvalidRegion.OrWith(changed);
     472             :   } else {
     473           0 :     mInvalidRegion = Move(mNextFrameInvalidRegion);
     474           0 :     mInvalidRegion.OrWith(changed);
     475             :   }
     476             : 
     477             :   // Free the old cloned property tree, then clone a new one. Note that we do
     478             :   // this before compositing since our CPU-based occlusion culling will update
     479             :   // the visible region to contain non-occluded draw rects. If a layer will not
     480             :   // be drawn, it will have no visible region. LTI might save this, and if the
     481             :   // layer is removed next frame, LTI will invalidate the wrong area.
     482             :   //
     483             :   // Instead, we always invalidate based on the full shadow tree.
     484             :   //
     485             :   // Note that the old compositor performs CPU-based occlusion culling *before*
     486             :   // invalidation. This maintains consistency, but we have more accurate draw
     487             :   // regions.
     488           0 :   mClonedLayerTreeProperties = nullptr;
     489           0 :   mClonedLayerTreeProperties = LayerProperties::CloneFrom(mRoot);
     490             : }
     491             : 
     492             : void
     493           0 : LayerManagerMLGPU::AddInvalidRegion(const nsIntRegion& aRegion)
     494             : {
     495           0 :   mNextFrameInvalidRegion.OrWith(aRegion);
     496           0 : }
     497             : 
     498             : TextureSourceProvider*
     499           0 : LayerManagerMLGPU::GetTextureSourceProvider() const
     500             : {
     501           0 :   return mTextureSourceProvider;
     502             : }
     503             : 
     504             : bool
     505           0 : LayerManagerMLGPU::IsCompositingToScreen() const
     506             : {
     507           0 :   return !mTarget;
     508             : }
     509             : 
     510             : bool
     511           0 : LayerManagerMLGPU::AreComponentAlphaLayersEnabled()
     512             : {
     513           0 :   return LayerManager::AreComponentAlphaLayersEnabled();
     514             : }
     515             : 
     516             : bool
     517           0 : LayerManagerMLGPU::BlendingRequiresIntermediateSurface()
     518             : {
     519           0 :   return true;
     520             : }
     521             : 
     522             : bool
     523           0 : LayerManagerMLGPU::SupportsBackdropCopyForComponentAlpha()
     524             : {
     525           0 :   return false;
     526             : }
     527             : 
     528             : void
     529           0 : LayerManagerMLGPU::EndTransaction(DrawPaintedLayerCallback aCallback,
     530             :                                   void* aCallbackData,
     531             :                                   EndTransactionFlags aFlags)
     532             : {
     533           0 :   MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)");
     534             : }
     535             : 
     536             : void
     537           0 : LayerManagerMLGPU::ClearCachedResources(Layer* aSubtree)
     538             : {
     539           0 :   Layer* root = aSubtree ? aSubtree : mRoot.get();
     540           0 :   if (!root) {
     541           0 :     return;
     542             :   }
     543             : 
     544           0 :   ForEachNode<ForwardIterator>(root, [](Layer* aLayer) {
     545           0 :     LayerMLGPU* layer = aLayer->AsHostLayer()->AsLayerMLGPU();
     546           0 :     if (!layer) {
     547           0 :       return;
     548             :     }
     549           0 :     layer->ClearCachedResources();
     550           0 :   });
     551             : }
     552             : 
     553             : void
     554           0 : LayerManagerMLGPU::NotifyShadowTreeTransaction()
     555             : {
     556           0 :   if (gfxPrefs::LayersDrawFPS()) {
     557           0 :     mDiagnostics->AddTxnFrame();
     558             :   }
     559           0 : }
     560             : 
     561             : void
     562           0 : LayerManagerMLGPU::UpdateRenderBounds(const gfx::IntRect& aRect)
     563             : {
     564           0 :   mRenderBounds = aRect;
     565           0 : }
     566             : 
     567             : bool
     568           0 : LayerManagerMLGPU::PreRender()
     569             : {
     570           0 :   AUTO_PROFILER_LABEL("LayerManagerMLGPU::PreRender", GRAPHICS);
     571             : 
     572             :   widget::WidgetRenderingContext context;
     573           0 :   if (!mWidget->PreRender(&context)) {
     574           0 :     return false;
     575             :   }
     576           0 :   mWidgetContext = Some(context);
     577           0 :   return true;
     578             : }
     579             : 
     580             : void
     581           0 : LayerManagerMLGPU::PostRender()
     582             : {
     583           0 :   mWidget->PostRender(mWidgetContext.ptr());
     584           0 :   mWidgetContext = Nothing();
     585           0 : }
     586             : 
     587             : } // namespace layers
     588             : } // namespace mozilla

Generated by: LCOV version 1.13