LCOV - code coverage report
Current view: top level - gfx/layers/mlgpu - RenderViewMLGPU.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 200 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 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 "RenderViewMLGPU.h"
       7             : #include "ContainerLayerMLGPU.h"
       8             : #include "FrameBuilder.h"
       9             : #include "gfxPrefs.h"
      10             : #include "LayersHelpers.h"
      11             : #include "LayersLogging.h"
      12             : #include "MLGDevice.h"
      13             : #include "RenderPassMLGPU.h"
      14             : #include "ShaderDefinitionsMLGPU.h"
      15             : #include "UtilityMLGPU.h"
      16             : 
      17             : namespace mozilla {
      18             : namespace layers {
      19             : 
      20             : using namespace gfx;
      21             : 
      22           0 : RenderViewMLGPU::RenderViewMLGPU(FrameBuilder* aBuilder,
      23             :                                  MLGRenderTarget* aTarget,
      24           0 :                                  const nsIntRegion& aInvalidRegion)
      25           0 :  : RenderViewMLGPU(aBuilder, nullptr)
      26             : {
      27           0 :   mTarget = aTarget;
      28           0 :   mInvalidBounds = aInvalidRegion.GetBounds();
      29             : 
      30             :   // The clear region on the layer manager is the area that must be clear after
      31             :   // we finish drawing.
      32           0 :   mPostClearRegion = aBuilder->GetManager()->GetRegionToClear();
      33             : 
      34             :   // Clamp the post-clear region to the invalid bounds, since clears don't go
      35             :   // through the scissor rect if using ClearView.
      36           0 :   mPostClearRegion.AndWith(mInvalidBounds);
      37             : 
      38             :   // Since the post-clear will occlude everything, we include it in the final
      39             :   // opaque area.
      40             :   mOccludedRegion.OrWith(
      41           0 :     ViewAs<LayerPixel>(mPostClearRegion, PixelCastJustification::RenderTargetIsParentLayerForRoot));
      42             : 
      43             :   AL_LOG("RenderView %p root with invalid area %s, clear area %s\n",
      44             :     this,
      45             :     Stringify(mInvalidBounds).c_str(),
      46             :     Stringify(mPostClearRegion).c_str());
      47           0 : }
      48             : 
      49           0 : RenderViewMLGPU::RenderViewMLGPU(FrameBuilder* aBuilder,
      50             :                                  ContainerLayerMLGPU* aContainer,
      51           0 :                                  RenderViewMLGPU* aParent)
      52           0 :  : RenderViewMLGPU(aBuilder, aParent)
      53             : {
      54           0 :   mContainer = aContainer;
      55           0 :   mTargetOffset = aContainer->GetTargetOffset();
      56           0 :   mInvalidBounds = aContainer->GetInvalidRect();
      57           0 :   MOZ_ASSERT(!mInvalidBounds.IsEmpty());
      58             : 
      59             :   AL_LOG("RenderView %p starting with container %p and invalid area %s\n",
      60             :     this,
      61             :     aContainer->GetLayer(),
      62             :     Stringify(mInvalidBounds).c_str());
      63           0 : }
      64             : 
      65           0 : RenderViewMLGPU::RenderViewMLGPU(FrameBuilder* aBuilder, RenderViewMLGPU* aParent)
      66             :  : mBuilder(aBuilder),
      67             :    mDevice(aBuilder->GetDevice()),
      68             :    mParent(aParent),
      69             :    mContainer(nullptr),
      70             :    mFinishedBuilding(false),
      71             :    mCurrentLayerBufferIndex(kInvalidResourceIndex),
      72             :    mCurrentMaskRectBufferIndex(kInvalidResourceIndex),
      73             :    mNextSortIndex(1),
      74           0 :    mUseDepthBuffer(gfxPrefs::AdvancedLayersEnableDepthBuffer()),
      75           0 :    mDepthBufferNeedsClear(false)
      76             : {
      77           0 :   if (aParent) {
      78           0 :     aParent->AddChild(this);
      79             :   }
      80           0 : }
      81             : 
      82           0 : RenderViewMLGPU::~RenderViewMLGPU()
      83             : {
      84           0 :   for (const auto& child : mChildren) {
      85           0 :     child->mParent = nullptr;
      86             :   }
      87           0 : }
      88             : 
      89             : IntSize
      90           0 : RenderViewMLGPU::GetSize() const
      91             : {
      92           0 :   MOZ_ASSERT(mFinishedBuilding);
      93           0 :   return mTarget->GetSize();
      94             : }
      95             : 
      96             : MLGRenderTarget*
      97           0 : RenderViewMLGPU::GetRenderTarget() const
      98             : {
      99           0 :   MOZ_ASSERT(mFinishedBuilding);
     100           0 :   return mTarget;
     101             : }
     102             : 
     103             : void
     104           0 : RenderViewMLGPU::AddChild(RenderViewMLGPU* aParent)
     105             : {
     106           0 :   mChildren.push_back(aParent);
     107           0 : }
     108             : 
     109             : void
     110           0 : RenderViewMLGPU::Render()
     111             : {
     112             :   // We render tiles front-to-back, depth-first, to minimize render target switching.
     113           0 :   for (const auto& child : mChildren) {
     114           0 :     child->Render();
     115             :   }
     116             : 
     117           0 :   ExecuteRendering();
     118           0 : }
     119             : 
     120             : void
     121           0 : RenderViewMLGPU::FinishBuilding()
     122             : {
     123           0 :   MOZ_ASSERT(!mFinishedBuilding);
     124           0 :   mFinishedBuilding = true;
     125             : 
     126           0 :   if (mContainer) {
     127           0 :     MOZ_ASSERT(!mTarget);
     128             : 
     129           0 :     MLGRenderTargetFlags flags = MLGRenderTargetFlags::Default;
     130           0 :     if (mUseDepthBuffer) {
     131           0 :       flags |= MLGRenderTargetFlags::ZBuffer;
     132             :     }
     133           0 :     mTarget = mContainer->UpdateRenderTarget(mDevice, flags);
     134             :   }
     135           0 : }
     136             : 
     137             : void
     138           0 : RenderViewMLGPU::AddItem(LayerMLGPU* aItem,
     139             :                          const IntRect& aRect,
     140             :                          Maybe<Polygon>&& aGeometry)
     141             : {
     142             :   AL_LOG("RenderView %p analyzing layer %p\n", this, aItem->GetLayer());
     143             : 
     144             :   // If the item is not visible at all, skip it.
     145           0 :   if (aItem->GetComputedOpacity() == 0.0f) {
     146             :     AL_LOG("RenderView %p culling item %p with no opacity\n",
     147             :       this,
     148             :       aItem->GetLayer());
     149           0 :     return;
     150             :   }
     151             : 
     152             :   // When using the depth buffer, the z-index for items is important.
     153             :   //
     154             :   // Sort order starts at 1 and goes to positive infinity, with smaller values
     155             :   // being closer to the screen. Our viewport is the same, with anything
     156             :   // outside of [0.0, 1.0] being culled, and lower values occluding higher
     157             :   // values. To make this work our projection transform scales the z-axis.
     158             :   // Note that we do not use 0 as a sorting index (when depth-testing is
     159             :   // enabled) because this would result in a z-value of 1.0, which would be
     160             :   // culled.
     161           0 :   ItemInfo info(mBuilder, this, aItem, mNextSortIndex++, aRect, Move(aGeometry));
     162             : 
     163             :   // If the item is not visible, or we can't add it to the layer constant
     164             :   // buffer for some reason, bail out.
     165           0 :   if (!UpdateVisibleRegion(info) || !mBuilder->AddLayerToConstantBuffer(info)) {
     166             :     AL_LOG("RenderView %p culled item %p!\n", this, aItem->GetLayer());
     167           0 :     return;
     168             :   }
     169             : 
     170             :   // We support all layer types now.
     171           0 :   MOZ_ASSERT(info.type != RenderPassType::Unknown);
     172             : 
     173           0 :   if (info.renderOrder == RenderOrder::FrontToBack) {
     174           0 :     AddItemFrontToBack(aItem, info);
     175             :   } else {
     176           0 :     AddItemBackToFront(aItem, info);
     177             :   }
     178             : }
     179             : 
     180             : bool
     181           0 : RenderViewMLGPU::UpdateVisibleRegion(ItemInfo& aItem)
     182             : {
     183             :   // If the item has some kind of complex transform, we perform a very
     184             :   // simple occlusion test and move on. We using a depth buffer we skip
     185             :   // CPU-based occlusion culling as well, since the GPU will do most of our
     186             :   // culling work for us.
     187           0 :   if (mUseDepthBuffer ||
     188           0 :       !aItem.translation ||
     189           0 :       !gfxPrefs::AdvancedLayersEnableCPUOcclusion())
     190             :   {
     191             :     // Update the render region even if we won't compute visibility, since some
     192             :     // layer types (like Canvas and Image) need to have the visible region
     193             :     // clamped.
     194           0 :     LayerIntRegion region = Move(aItem.layer->GetShadowVisibleRegion());
     195           0 :     aItem.layer->SetRegionToRender(Move(region));
     196             : 
     197             :     AL_LOG("RenderView %p simple occlusion test, bounds=%s, translation?=%d\n",
     198             :       this,
     199             :       Stringify(aItem.bounds).c_str(),
     200             :       aItem.translation ? 1 : 0);
     201           0 :     return mInvalidBounds.Intersects(aItem.bounds);
     202             :   }
     203             : 
     204           0 :   MOZ_ASSERT(aItem.rectilinear);
     205             : 
     206             :   AL_LOG("RenderView %p starting visibility tests:\n", this);
     207             :   AL_LOG("  occluded=%s\n", Stringify(mOccludedRegion).c_str());
     208             : 
     209             :   // Compute the translation into render target space.
     210             :   LayerIntPoint translation =
     211           0 :     LayerIntPoint::FromUnknownPoint(aItem.translation.value() - mTargetOffset);
     212             :   AL_LOG("  translation=%s\n", Stringify(translation).c_str());
     213             : 
     214           0 :   IntRect clip = aItem.layer->GetComputedClipRect().ToUnknownRect();
     215             :   AL_LOG("  clip=%s\n", Stringify(translation).c_str());
     216             : 
     217           0 :   LayerIntRegion region = Move(aItem.layer->GetShadowVisibleRegion());
     218           0 :   region.MoveBy(translation);
     219             :   AL_LOG("  effective-visible=%s\n", Stringify(region).c_str());
     220             : 
     221           0 :   region.SubOut(mOccludedRegion);
     222           0 :   region.AndWith(LayerIntRect::FromUnknownRect(mInvalidBounds));
     223           0 :   region.AndWith(LayerIntRect::FromUnknownRect(clip));
     224           0 :   if (region.IsEmpty()) {
     225           0 :     return false;
     226             :   }
     227             : 
     228             :   // Move the visible region back into layer space.
     229           0 :   region.MoveBy(-translation);
     230             :   AL_LOG("  new-local-visible=%s\n", Stringify(region).c_str());
     231             : 
     232           0 :   aItem.layer->SetRegionToRender(Move(region));
     233             : 
     234             :   // Apply the new occluded area. We do another dance with the translation to
     235             :   // avoid copying the region. We do this after the SetRegionToRender call to
     236             :   // accomodate the possiblity of a layer changing its visible region.
     237           0 :   if (aItem.opaque) {
     238           0 :     mOccludedRegion.MoveBy(-translation);
     239           0 :     mOccludedRegion.OrWith(aItem.layer->GetShadowVisibleRegion());
     240           0 :     mOccludedRegion.MoveBy(translation);
     241             :     AL_LOG("  new-occluded=%s\n", Stringify(mOccludedRegion).c_str());
     242             : 
     243             :     // If the occluded region gets too complicated, we reset it.
     244           0 :     if (mOccludedRegion.GetNumRects() >= 32) {
     245           0 :       mOccludedRegion.SetEmpty();
     246             :       AL_LOG("  clear-occluded, too many rects\n");
     247             :     }
     248             :   }
     249           0 :   return true;
     250             : }
     251             : 
     252             : void
     253           0 : RenderViewMLGPU::AddItemFrontToBack(LayerMLGPU* aLayer, ItemInfo& aItem)
     254             : {
     255             :   // We receive items in front-to-back order. Ideally we want to push items
     256             :   // as far back into batches impossible, to ensure the GPU can do a good
     257             :   // job at culling. However we also want to make sure we actually batch
     258             :   // items versus drawing one primitive per pass.
     259             :   //
     260             :   // As a compromise we look at the most 3 recent batches and then give up.
     261             :   // This can be tweaked in the future.
     262             :   static const size_t kMaxSearch = 3;
     263           0 :   size_t iterations = 0;
     264           0 :   for (auto iter = mFrontToBack.rbegin(); iter != mFrontToBack.rend(); iter++) {
     265           0 :     RenderPassMLGPU* pass = (*iter);
     266           0 :     if (pass->IsCompatible(aItem) && pass->AcceptItem(aItem)) {
     267             :       AL_LOG("RenderView %p added layer %p to pass %p (%d)\n",
     268             :         this, aLayer->GetLayer(), pass, int(pass->GetType()));
     269           0 :       return;
     270             :     }
     271           0 :     if (++iterations > kMaxSearch) {
     272           0 :       break;
     273             :     }
     274             :   }
     275             : 
     276           0 :   RefPtr<RenderPassMLGPU> pass = RenderPassMLGPU::CreatePass(mBuilder, aItem);
     277           0 :   if (!pass || !pass->AcceptItem(aItem)) {
     278           0 :     MOZ_ASSERT_UNREACHABLE("Could not build a pass for item!");
     279             :     return;
     280             :   }
     281             :   AL_LOG("RenderView %p added layer %p to new pass %p (%d)\n",
     282             :     this, aLayer->GetLayer(), pass.get(), int(pass->GetType()));
     283             : 
     284           0 :   mFrontToBack.push_back(pass);
     285             : }
     286             : 
     287             : void
     288           0 : RenderViewMLGPU::AddItemBackToFront(LayerMLGPU* aLayer, ItemInfo& aItem)
     289             : {
     290             :   // We receive layers in front-to-back order, but there are two cases when we
     291             :   // actually draw back-to-front: when the depth buffer is disabled, or when
     292             :   // using the depth buffer and the item has transparent pixels (and therefore
     293             :   // requires blending). In these cases we will build vertex and constant
     294             :   // buffers in reverse, as well as execute batches in reverse, to ensure the
     295             :   // correct ordering.
     296             :   //
     297             :   // Note: We limit the number of batches we search through, since it's better
     298             :   // to add new draw calls than spend too much time finding compatible
     299             :   // batches further down.
     300             :   static const size_t kMaxSearch = 10;
     301           0 :   size_t iterations = 0;
     302           0 :   for (auto iter = mBackToFront.begin(); iter != mBackToFront.end(); iter++) {
     303           0 :     RenderPassMLGPU* pass = (*iter);
     304           0 :     if (pass->IsCompatible(aItem) && pass->AcceptItem(aItem)) {
     305             :       AL_LOG("RenderView %p added layer %p to pass %p (%d)\n",
     306             :         this, aLayer->GetLayer(), pass, int(pass->GetType()));
     307           0 :       return;
     308             :     }
     309           0 :     if (pass->Intersects(aItem)) {
     310           0 :       break;
     311             :     }
     312           0 :     if (++iterations > kMaxSearch) {
     313           0 :       break;
     314             :     }
     315             :   }
     316             : 
     317           0 :   RefPtr<RenderPassMLGPU> pass = RenderPassMLGPU::CreatePass(mBuilder, aItem);
     318           0 :   if (!pass || !pass->AcceptItem(aItem)) {
     319           0 :     MOZ_ASSERT_UNREACHABLE("Could not build a pass for item!");
     320             :     return;
     321             :   }
     322             :   AL_LOG("RenderView %p added layer %p to new pass %p (%d)\n",
     323             :     this, aLayer->GetLayer(), pass.get(), int(pass->GetType()));
     324             : 
     325           0 :   mBackToFront.push_front(pass);
     326             : }
     327             : 
     328             : void
     329           0 : RenderViewMLGPU::Prepare()
     330             : {
     331           0 :   if (!mTarget) {
     332           0 :     return;
     333             :   }
     334             : 
     335             :   // Prepare front-to-back passes. These are only present when using the depth
     336             :   // buffer, and they contain only opaque data.
     337           0 :   for (RefPtr<RenderPassMLGPU>& pass : mFrontToBack) {
     338           0 :     pass->PrepareForRendering();
     339             :   }
     340             : 
     341             :   // Prepare the Clear buffer, which will fill the render target with transparent
     342             :   // pixels. This must happen before we set up world constants, since it can
     343             :   // create new z-indices.
     344           0 :   PrepareClears();
     345             : 
     346             :   // Prepare the world constant buffer. This must be called after we've
     347             :   // finished allocating all z-indices.
     348             :   {
     349           0 :     WorldConstants vsConstants;
     350           0 :     Matrix4x4 projection = Matrix4x4::Translation(-1.0, 1.0, 0.0);
     351           0 :     projection.PreScale(2.0 / float(mTarget->GetSize().width),
     352           0 :                         2.0 / float(mTarget->GetSize().height),
     353           0 :                         1.0f);
     354           0 :     projection.PreScale(1.0f, -1.0f, 1.0f);
     355             : 
     356           0 :     memcpy(vsConstants.projection, &projection._11, 64);
     357           0 :     vsConstants.targetOffset = Point(mTargetOffset);
     358           0 :     vsConstants.sortIndexOffset = PrepareDepthBuffer();
     359             : 
     360           0 :     SharedConstantBuffer* shared = mDevice->GetSharedVSBuffer();
     361           0 :     if (!shared->Allocate(&mWorldConstants, vsConstants)) {
     362           0 :       return;
     363             :     }
     364             :   }
     365             : 
     366             :   // Prepare back-to-front passes. In depth buffer mode, these contain draw
     367             :   // calls that might produce transparent pixels. When using CPU-based occlusion
     368             :   // culling, all draw calls are back-to-front.
     369           0 :   for (RefPtr<RenderPassMLGPU>& pass : mBackToFront) {
     370           0 :     pass->PrepareForRendering();
     371             :   }
     372             : 
     373             :   // Now, process children.
     374           0 :   for (const auto& iter : mChildren) {
     375           0 :     iter->Prepare();
     376             :   }
     377             : }
     378             : 
     379             : void
     380           0 : RenderViewMLGPU::ExecuteRendering()
     381             : {
     382           0 :   if (!mTarget) {
     383           0 :     return;
     384             :   }
     385             : 
     386           0 :   mDevice->SetRenderTarget(mTarget);
     387           0 :   mDevice->SetViewport(IntRect(IntPoint(0, 0), mTarget->GetSize()));
     388           0 :   mDevice->SetScissorRect(Some(mInvalidBounds));
     389             : 
     390           0 :   if (!mWorldConstants.IsValid()) {
     391           0 :     gfxWarning() << "Failed to allocate constant buffer for world transform";
     392           0 :     return;
     393             :   }
     394           0 :   mDevice->SetVSConstantBuffer(kWorldConstantBufferSlot, &mWorldConstants);
     395             : 
     396             :   // If using the depth buffer, clear it (if needed) and enable writes.
     397           0 :   if (mUseDepthBuffer) {
     398           0 :     if (mDepthBufferNeedsClear) {
     399           0 :       mDevice->ClearDepthBuffer(mTarget);
     400             :     }
     401           0 :     mDevice->SetDepthTestMode(MLGDepthTestMode::Write);
     402             :   }
     403             : 
     404             :   // Opaque items, rendered front-to-back.
     405           0 :   for (auto iter = mFrontToBack.begin(); iter != mFrontToBack.end(); iter++) {
     406           0 :     ExecutePass(*iter);
     407             :   }
     408             : 
     409           0 :   if (mUseDepthBuffer) {
     410             :     // From now on we might be rendering transparent pixels, so we disable
     411             :     // writing to the z-buffer.
     412           0 :     mDevice->SetDepthTestMode(MLGDepthTestMode::ReadOnly);
     413             :   }
     414             : 
     415             :   // Clear any pixels that are not occluded, and therefore might require
     416             :   // blending.
     417           0 :   mDevice->DrawClearRegion(mPreClear);
     418             : 
     419             :   // Render back-to-front passes.
     420           0 :   for (auto iter = mBackToFront.begin(); iter != mBackToFront.end(); iter++) {
     421           0 :     ExecutePass(*iter);
     422             :   }
     423             : 
     424             :   // Make sure the post-clear area has no pixels.
     425           0 :   if (!mPostClearRegion.IsEmpty()) {
     426           0 :     mDevice->DrawClearRegion(mPostClear);
     427             :   }
     428             : 
     429             :   // We repaint the entire invalid region, even if it is partially occluded.
     430             :   // Thus it's safe for us to clear the invalid area here. If we ever switch
     431             :   // to nsIntRegions, we will have to take the difference between the paitned
     432             :   // area and the invalid area.
     433           0 :   if (mContainer) {
     434           0 :     mContainer->ClearInvalidRect();
     435             :   }
     436             : }
     437             : 
     438             : void
     439           0 : RenderViewMLGPU::ExecutePass(RenderPassMLGPU* aPass)
     440             : {
     441           0 :   if (!aPass->IsPrepared()) {
     442           0 :     return;
     443             :   }
     444             : 
     445             :   // Change the layer buffer if needed.
     446           0 :   if (aPass->GetLayerBufferIndex() != mCurrentLayerBufferIndex) {
     447           0 :     mCurrentLayerBufferIndex = aPass->GetLayerBufferIndex();
     448             : 
     449           0 :     ConstantBufferSection section = mBuilder->GetLayerBufferByIndex(mCurrentLayerBufferIndex);
     450           0 :     mDevice->SetVSConstantBuffer(kLayerBufferSlot, &section);
     451             :   }
     452             : 
     453             :   // Change the mask rect buffer if needed.
     454           0 :   if (aPass->GetMaskRectBufferIndex() &&
     455           0 :       aPass->GetMaskRectBufferIndex().value() != mCurrentMaskRectBufferIndex)
     456             :   {
     457           0 :     mCurrentMaskRectBufferIndex = aPass->GetMaskRectBufferIndex().value();
     458             : 
     459           0 :     ConstantBufferSection section = mBuilder->GetMaskRectBufferByIndex(mCurrentMaskRectBufferIndex);
     460           0 :     mDevice->SetVSConstantBuffer(kMaskBufferSlot, &section);
     461             :   }
     462             : 
     463             :   // Change the blend state if needed.
     464           0 :   if (Maybe<MLGBlendState> blendState = aPass->GetBlendState()) {
     465           0 :     mDevice->SetBlendState(blendState.value());
     466             :   }
     467             : 
     468           0 :   aPass->ExecuteRendering();
     469             : }
     470             : 
     471             : int32_t
     472           0 : RenderViewMLGPU::PrepareDepthBuffer()
     473             : {
     474           0 :   if (!mUseDepthBuffer) {
     475           0 :     return 0;
     476             :   }
     477             : 
     478             :   // Rather than clear the depth buffer every frame, we offset z-indices each
     479             :   // frame, starting with indices far away from the screen and moving toward
     480             :   // the user each successive frame. This ensures that frames can re-use the
     481             :   // depth buffer but never collide with previously written values.
     482             :   //
     483             :   // Once a frame runs out of sort indices, we finally clear the depth buffer
     484             :   // and start over again.
     485             : 
     486             :   // Note: the lowest sort index (kDepthLimit) is always occluded since it will
     487             :   // resolve to the clear value - kDepthLimit / kDepthLimit == 1.0.
     488             :   //
     489             :   // If we don't have any more indices to allocate, we need to clear the depth
     490             :   // buffer and start fresh.
     491           0 :   int32_t highestIndex = mTarget->GetLastDepthStart();
     492           0 :   if (highestIndex < mNextSortIndex) {
     493           0 :     mDepthBufferNeedsClear = true;
     494           0 :     highestIndex = kDepthLimit;
     495             :   }
     496             : 
     497             :   // We should not have more than kDepthLimit layers to draw. The last known
     498             :   // sort index might appear in the depth buffer and occlude something, so
     499             :   // we subtract 1. This ensures all our indices will compare less than all
     500             :   // old indices.
     501           0 :   int32_t sortOffset = highestIndex - mNextSortIndex - 1;
     502           0 :   MOZ_ASSERT(sortOffset >= 0);
     503             : 
     504           0 :   mTarget->SetLastDepthStart(sortOffset);
     505           0 :   return sortOffset;
     506             : }
     507             : 
     508             : void
     509           0 : RenderViewMLGPU::PrepareClears()
     510             : {
     511             :   // Get the list of rects to clear. If using the depth buffer, we don't
     512             :   // care if it's accurate since the GPU will do occlusion testing for us.
     513             :   // If not using the depth buffer, we subtract out the occluded region.
     514           0 :   LayerIntRegion region = LayerIntRect::FromUnknownRect(mInvalidBounds);
     515           0 :   if (!mUseDepthBuffer) {
     516             :     // Don't let the clear region become too complicated.
     517           0 :     region.SubOut(mOccludedRegion);
     518           0 :     region.SimplifyOutward(kMaxClearViewRects);
     519             :   }
     520             : 
     521           0 :   Maybe<int32_t> sortIndex;
     522           0 :   if (mUseDepthBuffer) {
     523             :     // Note that we use the lowest available sorting index, to ensure that when
     524             :     // using the z-buffer, we don't draw over already-drawn content.
     525           0 :     sortIndex = Some(mNextSortIndex++);
     526             :   }
     527             : 
     528           0 :   nsTArray<IntRect> rects = ToRectArray(region);
     529           0 :   mDevice->PrepareClearRegion(&mPreClear, Move(rects), sortIndex);
     530             : 
     531           0 :   if (!mPostClearRegion.IsEmpty()) {
     532             :     // Prepare the final clear as well. Note that we always do this clear at the
     533             :     // very end, even when the depth buffer is enabled, so we don't bother
     534             :     // setting a useful sorting index. If and when we try to ship the depth
     535             :     // buffer, we would execute this clear earlier in the pipeline and give it
     536             :     // the closest possible z-ordering to the screen.
     537           0 :     nsTArray<IntRect> rects = ToRectArray(mPostClearRegion);
     538           0 :     mDevice->PrepareClearRegion(&mPostClear, Move(rects), Nothing());
     539             :   }
     540           0 : }
     541             : 
     542             : } // namespace layers
     543             : } // namespace mozilla

Generated by: LCOV version 1.13