LCOV - code coverage report
Current view: top level - gfx/layers/composite - TiledContentHost.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 304 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 26 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 "TiledContentHost.h"
       7             : #include "gfxPrefs.h"                   // for gfxPrefs
       8             : #include "PaintedLayerComposite.h"      // for PaintedLayerComposite
       9             : #include "mozilla/gfx/BaseSize.h"       // for BaseSize
      10             : #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
      11             : #include "mozilla/gfx/Point.h"          // for IntSize
      12             : #include "mozilla/layers/Compositor.h"  // for Compositor
      13             : //#include "mozilla/layers/CompositorBridgeParent.h"  // for CompositorBridgeParent
      14             : #include "mozilla/layers/Effects.h"     // for TexturedEffect, Effect, etc
      15             : #include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
      16             : #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
      17             : #include "nsAString.h"
      18             : #include "nsDebug.h"                    // for NS_WARNING
      19             : #include "nsPoint.h"                    // for IntPoint
      20             : #include "nsPrintfCString.h"            // for nsPrintfCString
      21             : #include "nsRect.h"                     // for IntRect
      22             : #include "mozilla/layers/TextureClient.h"
      23             : 
      24             : namespace mozilla {
      25             : using namespace gfx;
      26             : namespace layers {
      27             : 
      28             : class Layer;
      29             : 
      30             : float
      31           0 : TileHost::GetFadeInOpacity(float aOpacity)
      32             : {
      33           0 :   TimeStamp now = TimeStamp::Now();
      34           0 :   if (!gfxPrefs::LayerTileFadeInEnabled() ||
      35           0 :       mFadeStart.IsNull() ||
      36           0 :       now < mFadeStart)
      37             :   {
      38           0 :     return aOpacity;
      39             :   }
      40             : 
      41           0 :   float duration = gfxPrefs::LayerTileFadeInDuration();
      42           0 :   float elapsed = (now - mFadeStart).ToMilliseconds();
      43           0 :   if (elapsed > duration) {
      44           0 :     mFadeStart = TimeStamp();
      45           0 :     return aOpacity;
      46             :   }
      47           0 :   return aOpacity * (elapsed / duration);
      48             : }
      49             : 
      50           0 : TiledLayerBufferComposite::TiledLayerBufferComposite()
      51           0 :   : mFrameResolution()
      52           0 : {}
      53             : 
      54           0 : TiledLayerBufferComposite::~TiledLayerBufferComposite()
      55             : {
      56           0 :   Clear();
      57           0 : }
      58             : 
      59             : void
      60           0 : TiledLayerBufferComposite::SetTextureSourceProvider(TextureSourceProvider* aProvider)
      61             : {
      62           0 :   MOZ_ASSERT(aProvider);
      63           0 :   for (TileHost& tile : mRetainedTiles) {
      64           0 :     if (tile.IsPlaceholderTile()) continue;
      65           0 :     tile.mTextureHost->SetTextureSourceProvider(aProvider);
      66           0 :     if (tile.mTextureHostOnWhite) {
      67           0 :       tile.mTextureHostOnWhite->SetTextureSourceProvider(aProvider);
      68             :     }
      69             :   }
      70           0 : }
      71             : 
      72             : void
      73           0 : TiledLayerBufferComposite::AddAnimationInvalidation(nsIntRegion& aRegion)
      74             : {
      75             :   // We need to invalidate rects where we have a tile that is in the
      76             :   // process of fading in.
      77           0 :   for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
      78           0 :     if (!mRetainedTiles[i].mFadeStart.IsNull()) {
      79           0 :       TileIntPoint position = mTiles.TilePosition(i);
      80           0 :       IntPoint offset = GetTileOffset(position);
      81           0 :       nsIntRegion tileRegion = IntRect(offset, GetScaledTileSize());
      82           0 :       aRegion.OrWith(tileRegion);
      83             :     }
      84             :   }
      85           0 : }
      86             : 
      87           0 : TiledContentHost::TiledContentHost(const TextureInfo& aTextureInfo)
      88             :   : ContentHost(aTextureInfo)
      89             :   , mTiledBuffer(TiledLayerBufferComposite())
      90           0 :   , mLowPrecisionTiledBuffer(TiledLayerBufferComposite())
      91             : {
      92           0 :   MOZ_COUNT_CTOR(TiledContentHost);
      93           0 : }
      94             : 
      95           0 : TiledContentHost::~TiledContentHost()
      96             : {
      97           0 :   MOZ_COUNT_DTOR(TiledContentHost);
      98           0 : }
      99             : 
     100             : already_AddRefed<TexturedEffect>
     101           0 : TiledContentHost::GenEffect(const gfx::SamplingFilter aSamplingFilter)
     102             : {
     103           0 :   MOZ_ASSERT(mTiledBuffer.GetTileCount() == 1 && mLowPrecisionTiledBuffer.GetTileCount() == 0);
     104           0 :   MOZ_ASSERT(mTiledBuffer.GetTile(0).mTextureHost);
     105             : 
     106           0 :   TileHost& tile = mTiledBuffer.GetTile(0);
     107           0 :   if (!tile.mTextureHost->BindTextureSource(tile.mTextureSource)) {
     108           0 :     return nullptr;
     109             :   }
     110             : 
     111             :   return CreateTexturedEffect(tile.mTextureSource,
     112             :                               nullptr,
     113             :                               aSamplingFilter,
     114           0 :                               true);
     115             : }
     116             : 
     117             : void
     118           0 : TiledContentHost::Attach(Layer* aLayer,
     119             :                          TextureSourceProvider* aProvider,
     120             :                          AttachFlags aFlags /* = NO_FLAGS */)
     121             : {
     122           0 :   CompositableHost::Attach(aLayer, aProvider, aFlags);
     123           0 : }
     124             : 
     125             : void
     126           0 : TiledContentHost::Detach(Layer* aLayer,
     127             :                          AttachFlags aFlags /* = NO_FLAGS */)
     128             : {
     129           0 :   if (!mKeepAttached || aLayer == mLayer || aFlags & FORCE_DETACH) {
     130             :     // Clear the TiledLayerBuffers, which will take care of releasing the
     131             :     // copy-on-write locks.
     132           0 :     mTiledBuffer.Clear();
     133           0 :     mLowPrecisionTiledBuffer.Clear();
     134             :   }
     135           0 :   CompositableHost::Detach(aLayer,aFlags);
     136           0 : }
     137             : 
     138             : bool
     139           0 : TiledContentHost::UseTiledLayerBuffer(ISurfaceAllocator* aAllocator,
     140             :                                       const SurfaceDescriptorTiles& aTiledDescriptor)
     141             : {
     142           0 :   HostLayerManager* lm = GetLayerManager();
     143           0 :   if (!lm) {
     144           0 :     return false;
     145             :   }
     146             : 
     147           0 :   if (aTiledDescriptor.resolution() < 1) {
     148           0 :     if (!mLowPrecisionTiledBuffer.UseTiles(aTiledDescriptor, lm, aAllocator)) {
     149           0 :       return false;
     150             :     }
     151             :   } else {
     152           0 :     if (!mTiledBuffer.UseTiles(aTiledDescriptor, lm, aAllocator)) {
     153           0 :       return false;
     154             :     }
     155             :   }
     156           0 :   return true;
     157             : }
     158             : 
     159             : void
     160           0 : UseTileTexture(CompositableTextureHostRef& aTexture,
     161             :                CompositableTextureSourceRef& aTextureSource,
     162             :                const IntRect& aUpdateRect,
     163             :                Compositor* aCompositor)
     164             : {
     165           0 :   MOZ_ASSERT(aTexture);
     166           0 :   if (!aTexture) {
     167           0 :     return;
     168             :   }
     169             : 
     170           0 :   if (aCompositor) {
     171           0 :     aTexture->SetTextureSourceProvider(aCompositor);
     172             :   }
     173             : 
     174           0 :   if (!aUpdateRect.IsEmpty()) {
     175             :     // For !HasIntermediateBuffer() textures, this is likely a no-op.
     176           0 :     nsIntRegion region = aUpdateRect;
     177           0 :     aTexture->Updated(&region);
     178             :   }
     179             : 
     180           0 :   aTexture->PrepareTextureSource(aTextureSource);
     181             : }
     182             : 
     183           0 : class TextureSourceRecycler
     184             : {
     185             : public:
     186           0 :   explicit TextureSourceRecycler(nsTArray<TileHost>&& aTileSet)
     187           0 :     : mTiles(Move(aTileSet))
     188           0 :     , mFirstPossibility(0)
     189           0 :   {}
     190             : 
     191             :   // Attempts to recycle a texture source that is already bound to the
     192             :   // texture host for aTile.
     193           0 :   void RecycleTextureSourceForTile(TileHost& aTile) {
     194           0 :     for (size_t i = mFirstPossibility; i < mTiles.Length(); i++) {
     195             :       // Skip over existing tiles without a retained texture source
     196             :       // and make sure we don't iterate them in the future.
     197           0 :       if (!mTiles[i].mTextureSource) {
     198           0 :         if (i == mFirstPossibility) {
     199           0 :           mFirstPossibility++;
     200             :         }
     201           0 :         continue;
     202             :       }
     203             : 
     204             :       // If this tile matches, then copy across the retained texture source (if
     205             :       // any).
     206           0 :       if (aTile.mTextureHost == mTiles[i].mTextureHost) {
     207           0 :         aTile.mTextureSource = Move(mTiles[i].mTextureSource);
     208           0 :         if (aTile.mTextureHostOnWhite) {
     209           0 :           aTile.mTextureSourceOnWhite = Move(mTiles[i].mTextureSourceOnWhite);
     210             :         }
     211           0 :         break;
     212             :       }
     213             :     }
     214           0 :   }
     215             : 
     216             :   // Attempts to recycle any texture source to avoid needing to allocate
     217             :   // a new one.
     218           0 :   void RecycleTextureSource(TileHost& aTile) {
     219           0 :     for (size_t i = mFirstPossibility; i < mTiles.Length(); i++) {
     220           0 :       if (!mTiles[i].mTextureSource) {
     221           0 :         if (i == mFirstPossibility) {
     222           0 :           mFirstPossibility++;
     223             :         }
     224           0 :         continue;
     225             :       }
     226             : 
     227           0 :       if (mTiles[i].mTextureSource &&
     228           0 :           mTiles[i].mTextureHost->GetFormat() == aTile.mTextureHost->GetFormat()) {
     229           0 :         aTile.mTextureSource = Move(mTiles[i].mTextureSource);
     230           0 :         if (aTile.mTextureHostOnWhite) {
     231           0 :           aTile.mTextureSourceOnWhite = Move(mTiles[i].mTextureSourceOnWhite);
     232             :         }
     233           0 :         break;
     234             :       }
     235             :     }
     236           0 :   }
     237             : 
     238           0 :   void RecycleTileFading(TileHost& aTile) {
     239           0 :     for (size_t i = 0; i < mTiles.Length(); i++) {
     240           0 :       if (mTiles[i].mTextureHost == aTile.mTextureHost) {
     241           0 :         aTile.mFadeStart = mTiles[i].mFadeStart;
     242             :       }
     243             :     }
     244           0 :   }
     245             : 
     246             : protected:
     247             :   nsTArray<TileHost> mTiles;
     248             :   size_t mFirstPossibility;
     249             : };
     250             : 
     251             : bool
     252           0 : TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
     253             :                                     HostLayerManager* aLayerManager,
     254             :                                     ISurfaceAllocator* aAllocator)
     255             : {
     256           0 :   if (mResolution != aTiles.resolution() ||
     257           0 :       aTiles.tileSize() != mTileSize) {
     258           0 :     Clear();
     259             :   }
     260           0 :   MOZ_ASSERT(aAllocator);
     261           0 :   MOZ_ASSERT(aLayerManager);
     262           0 :   if (!aAllocator || !aLayerManager) {
     263           0 :     return false;
     264             :   }
     265             : 
     266           0 :   if (aTiles.resolution() == 0 || IsNaN(aTiles.resolution())) {
     267             :     // There are divisions by mResolution so this protects the compositor process
     268             :     // against malicious content processes and fuzzing.
     269           0 :     return false;
     270             :   }
     271             : 
     272           0 :   TilesPlacement newTiles(aTiles.firstTileX(), aTiles.firstTileY(),
     273           0 :                           aTiles.retainedWidth(), aTiles.retainedHeight());
     274             : 
     275           0 :   const InfallibleTArray<TileDescriptor>& tileDescriptors = aTiles.tiles();
     276             : 
     277           0 :   TextureSourceRecycler oldRetainedTiles(Move(mRetainedTiles));
     278           0 :   mRetainedTiles.SetLength(tileDescriptors.Length());
     279             : 
     280             :   // Step 1, deserialize the incoming set of tiles into mRetainedTiles, and attempt
     281             :   // to recycle the TextureSource for any repeated tiles.
     282             :   //
     283             :   // Since we don't have any retained 'tile' object, we have to search for instances
     284             :   // of the same TextureHost in the old tile set. The cost of binding a TextureHost
     285             :   // to a TextureSource for gralloc (binding EGLImage to GL texture) can be really
     286             :   // high, so we avoid this whenever possible.
     287           0 :   for (size_t i = 0; i < tileDescriptors.Length(); i++) {
     288           0 :     const TileDescriptor& tileDesc = tileDescriptors[i];
     289             : 
     290           0 :     TileHost& tile = mRetainedTiles[i];
     291             : 
     292           0 :     if (tileDesc.type() != TileDescriptor::TTexturedTileDescriptor) {
     293           0 :       NS_WARNING_ASSERTION(
     294             :         tileDesc.type() == TileDescriptor::TPlaceholderTileDescriptor,
     295             :         "Unrecognised tile descriptor type");
     296           0 :       continue;
     297             :     }
     298             : 
     299           0 :     const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor();
     300             : 
     301           0 :     tile.mTextureHost = TextureHost::AsTextureHost(texturedDesc.textureParent());
     302           0 :     tile.mTextureHost->SetTextureSourceProvider(aLayerManager->GetCompositor());
     303           0 :     tile.mTextureHost->DeserializeReadLock(texturedDesc.sharedLock(), aAllocator);
     304             : 
     305           0 :     if (texturedDesc.textureOnWhite().type() == MaybeTexture::TPTextureParent) {
     306             :       tile.mTextureHostOnWhite = TextureHost::AsTextureHost(
     307           0 :         texturedDesc.textureOnWhite().get_PTextureParent()
     308           0 :       );
     309           0 :       tile.mTextureHostOnWhite->DeserializeReadLock(
     310           0 :         texturedDesc.sharedLockOnWhite(), aAllocator
     311           0 :       );
     312             :     }
     313             : 
     314           0 :     tile.mTilePosition = newTiles.TilePosition(i);
     315             : 
     316             :     // If this same tile texture existed in the old tile set then this will move the texture
     317             :     // source into our new tile.
     318           0 :     oldRetainedTiles.RecycleTextureSourceForTile(tile);
     319             : 
     320             :     // If this tile is in the process of fading, we need to keep that going
     321           0 :     oldRetainedTiles.RecycleTileFading(tile);
     322             : 
     323           0 :     if (aTiles.isProgressive() &&
     324           0 :         texturedDesc.wasPlaceholder())
     325             :     {
     326             :       // This is a progressive paint, and the tile used to be a placeholder.
     327             :       // We need to begin fading it in (if enabled via layers.tiles.fade-in.enabled)
     328           0 :       tile.mFadeStart = TimeStamp::Now();
     329             : 
     330           0 :       aLayerManager->CompositeUntil(
     331           0 :         tile.mFadeStart + TimeDuration::FromMilliseconds(gfxPrefs::LayerTileFadeInDuration()));
     332             :     }
     333             :   }
     334             : 
     335             :   // Step 2, attempt to recycle unused texture sources from the old tile set into new tiles.
     336             :   //
     337             :   // For gralloc, binding a new TextureHost to the existing TextureSource is the fastest way
     338             :   // to ensure that any implicit locking on the old gralloc image is released.
     339           0 :   for (TileHost& tile : mRetainedTiles) {
     340           0 :     if (!tile.mTextureHost || tile.mTextureSource) {
     341           0 :       continue;
     342             :     }
     343           0 :     oldRetainedTiles.RecycleTextureSource(tile);
     344             :   }
     345             : 
     346             :   // Step 3, handle the texture uploads, texture source binding and release the
     347             :   // copy-on-write locks for textures with an internal buffer.
     348           0 :   for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
     349           0 :     TileHost& tile = mRetainedTiles[i];
     350           0 :     if (!tile.mTextureHost) {
     351           0 :       continue;
     352             :     }
     353             : 
     354           0 :     const TileDescriptor& tileDesc = tileDescriptors[i];
     355           0 :     const TexturedTileDescriptor& texturedDesc = tileDesc.get_TexturedTileDescriptor();
     356             : 
     357           0 :     UseTileTexture(tile.mTextureHost,
     358             :                    tile.mTextureSource,
     359           0 :                    texturedDesc.updateRect(),
     360           0 :                    aLayerManager->GetCompositor());
     361             : 
     362           0 :     if (tile.mTextureHostOnWhite) {
     363           0 :       UseTileTexture(tile.mTextureHostOnWhite,
     364             :                      tile.mTextureSourceOnWhite,
     365           0 :                      texturedDesc.updateRect(),
     366           0 :                      aLayerManager->GetCompositor());
     367             :     }
     368             :   }
     369             : 
     370           0 :   mTiles = newTiles;
     371           0 :   mTileSize = aTiles.tileSize();
     372           0 :   mTileOrigin = aTiles.tileOrigin();
     373           0 :   mValidRegion = aTiles.validRegion();
     374           0 :   mResolution = aTiles.resolution();
     375           0 :   mFrameResolution = CSSToParentLayerScale2D(aTiles.frameXResolution(),
     376           0 :                                              aTiles.frameYResolution());
     377             : 
     378           0 :   return true;
     379             : }
     380             : 
     381             : void
     382           0 : TiledLayerBufferComposite::Clear()
     383             : {
     384           0 :   mRetainedTiles.Clear();
     385           0 :   mTiles.mFirst = TileIntPoint();
     386           0 :   mTiles.mSize = TileIntSize();
     387           0 :   mValidRegion = nsIntRegion();
     388           0 :   mResolution = 1.0;
     389           0 : }
     390             : 
     391             : void
     392           0 : TiledContentHost::Composite(Compositor* aCompositor,
     393             :                             LayerComposite* aLayer,
     394             :                             EffectChain& aEffectChain,
     395             :                             float aOpacity,
     396             :                             const gfx::Matrix4x4& aTransform,
     397             :                             const gfx::SamplingFilter aSamplingFilter,
     398             :                             const gfx::IntRect& aClipRect,
     399             :                             const nsIntRegion* aVisibleRegion /* = nullptr */,
     400             :                             const Maybe<gfx::Polygon>& aGeometry)
     401             : {
     402             :   // Reduce the opacity of the low-precision buffer to make it a
     403             :   // little more subtle and less jarring. In particular, text
     404             :   // rendered at low-resolution and scaled tends to look pretty
     405             :   // heavy and this helps mitigate that. When we reduce the opacity
     406             :   // we also make sure to draw the background color behind the
     407             :   // reduced-opacity tile so that content underneath doesn't show
     408             :   // through.
     409             :   // However, in cases where the background is transparent, or the layer
     410             :   // already has some opacity, we want to skip this behaviour. Otherwise
     411             :   // we end up changing the expected overall transparency of the content,
     412             :   // and it just looks wrong.
     413           0 :   Color backgroundColor;
     414           0 :   if (aOpacity == 1.0f && gfxPrefs::LowPrecisionOpacity() < 1.0f) {
     415             :     // Background colors are only stored on scrollable layers. Grab
     416             :     // the one from the nearest scrollable ancestor layer.
     417           0 :     for (LayerMetricsWrapper ancestor(GetLayer(), LayerMetricsWrapper::StartAt::BOTTOM); ancestor; ancestor = ancestor.GetParent()) {
     418           0 :       if (ancestor.Metrics().IsScrollable()) {
     419           0 :         backgroundColor = ancestor.Metadata().GetBackgroundColor();
     420           0 :         break;
     421             :       }
     422             :     }
     423             :   }
     424             :   float lowPrecisionOpacityReduction =
     425           0 :         (aOpacity == 1.0f && backgroundColor.a == 1.0f)
     426           0 :         ? gfxPrefs::LowPrecisionOpacity() : 1.0f;
     427             : 
     428           0 :   nsIntRegion tmpRegion;
     429           0 :   const nsIntRegion* renderRegion = aVisibleRegion;
     430             : #ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
     431           0 :   if (PaintWillResample()) {
     432             :     // If we're resampling, then the texture image will contain exactly the
     433             :     // entire visible region's bounds, and we should draw it all in one quad
     434             :     // to avoid unexpected aliasing.
     435           0 :     tmpRegion = aVisibleRegion->GetBounds();
     436           0 :     renderRegion = &tmpRegion;
     437             :   }
     438             : #endif
     439             : 
     440             :   // Render the low and high precision buffers.
     441           0 :   RenderLayerBuffer(mLowPrecisionTiledBuffer, aCompositor,
     442             :                     lowPrecisionOpacityReduction < 1.0f ? &backgroundColor : nullptr,
     443             :                     aEffectChain, lowPrecisionOpacityReduction * aOpacity,
     444           0 :                     aSamplingFilter, aClipRect, *renderRegion, aTransform, aGeometry);
     445             : 
     446           0 :   RenderLayerBuffer(mTiledBuffer, aCompositor, nullptr, aEffectChain, aOpacity, aSamplingFilter,
     447           0 :                     aClipRect, *renderRegion, aTransform, aGeometry);
     448           0 : }
     449             : 
     450             : 
     451             : void
     452           0 : TiledContentHost::RenderTile(TileHost& aTile,
     453             :                              Compositor* aCompositor,
     454             :                              EffectChain& aEffectChain,
     455             :                              float aOpacity,
     456             :                              const gfx::Matrix4x4& aTransform,
     457             :                              const gfx::SamplingFilter aSamplingFilter,
     458             :                              const gfx::IntRect& aClipRect,
     459             :                              const nsIntRegion& aScreenRegion,
     460             :                              const IntPoint& aTextureOffset,
     461             :                              const IntSize& aTextureBounds,
     462             :                              const gfx::Rect& aVisibleRect,
     463             :                              const Maybe<gfx::Polygon>& aGeometry)
     464             : {
     465           0 :   MOZ_ASSERT(!aTile.IsPlaceholderTile());
     466             : 
     467           0 :   AutoLockTextureHost autoLock(aTile.mTextureHost);
     468           0 :   AutoLockTextureHost autoLockOnWhite(aTile.mTextureHostOnWhite);
     469           0 :   if (autoLock.Failed() ||
     470           0 :       autoLockOnWhite.Failed()) {
     471           0 :     NS_WARNING("Failed to lock tile");
     472           0 :     return;
     473             :   }
     474             : 
     475           0 :   if (!aTile.mTextureHost->BindTextureSource(aTile.mTextureSource)) {
     476           0 :     return;
     477             :   }
     478             : 
     479           0 :   if (aTile.mTextureHostOnWhite && !aTile.mTextureHostOnWhite->BindTextureSource(aTile.mTextureSourceOnWhite)) {
     480           0 :     return;
     481             :   }
     482             : 
     483             :   RefPtr<TexturedEffect> effect =
     484           0 :     CreateTexturedEffect(aTile.mTextureSource,
     485             :                          aTile.mTextureSourceOnWhite,
     486             :                          aSamplingFilter,
     487           0 :                          true);
     488           0 :   if (!effect) {
     489           0 :     return;
     490             :   }
     491             : 
     492           0 :   float opacity = aTile.GetFadeInOpacity(aOpacity);
     493           0 :   aEffectChain.mPrimaryEffect = effect;
     494             : 
     495           0 :   for (auto iter = aScreenRegion.RectIter(); !iter.Done(); iter.Next()) {
     496           0 :     const IntRect& rect = iter.Get();
     497           0 :     Rect graphicsRect(rect.x, rect.y, rect.width, rect.height);
     498           0 :     Rect textureRect(rect.x - aTextureOffset.x, rect.y - aTextureOffset.y,
     499           0 :                      rect.width, rect.height);
     500             : 
     501           0 :     effect->mTextureCoords = Rect(textureRect.x / aTextureBounds.width,
     502           0 :                                   textureRect.y / aTextureBounds.height,
     503           0 :                                   textureRect.width / aTextureBounds.width,
     504           0 :                                   textureRect.height / aTextureBounds.height);
     505             : 
     506             :     aCompositor->DrawGeometry(graphicsRect, aClipRect, aEffectChain, opacity,
     507           0 :                               aTransform, aVisibleRect, aGeometry);
     508             :   }
     509             : 
     510           0 :   DiagnosticFlags flags = DiagnosticFlags::CONTENT | DiagnosticFlags::TILE;
     511           0 :   if (aTile.mTextureHostOnWhite) {
     512           0 :     flags |= DiagnosticFlags::COMPONENT_ALPHA;
     513             :   }
     514           0 :   aCompositor->DrawDiagnostics(flags,
     515           0 :                                aScreenRegion, aClipRect, aTransform, mFlashCounter);
     516             : }
     517             : 
     518             : void
     519           0 : TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
     520             :                                     Compositor* aCompositor,
     521             :                                     const Color* aBackgroundColor,
     522             :                                     EffectChain& aEffectChain,
     523             :                                     float aOpacity,
     524             :                                     const gfx::SamplingFilter aSamplingFilter,
     525             :                                     const gfx::IntRect& aClipRect,
     526             :                                     nsIntRegion aVisibleRegion,
     527             :                                     gfx::Matrix4x4 aTransform,
     528             :                                     const Maybe<Polygon>& aGeometry)
     529             : {
     530           0 :   float resolution = aLayerBuffer.GetResolution();
     531           0 :   gfx::Size layerScale(1, 1);
     532             : 
     533             :   // We assume that the current frame resolution is the one used in our high
     534             :   // precision layer buffer. Compensate for a changing frame resolution when
     535             :   // rendering the low precision buffer.
     536           0 :   if (aLayerBuffer.GetFrameResolution() != mTiledBuffer.GetFrameResolution()) {
     537           0 :     const CSSToParentLayerScale2D& layerResolution = aLayerBuffer.GetFrameResolution();
     538           0 :     const CSSToParentLayerScale2D& localResolution = mTiledBuffer.GetFrameResolution();
     539           0 :     layerScale.width = layerResolution.xScale / localResolution.xScale;
     540           0 :     layerScale.height = layerResolution.yScale / localResolution.yScale;
     541           0 :     aVisibleRegion.ScaleRoundOut(layerScale.width, layerScale.height);
     542             :   }
     543             : 
     544             :   // Make sure we don't render at low resolution where we have valid high
     545             :   // resolution content, to avoid overdraw and artifacts with semi-transparent
     546             :   // layers.
     547           0 :   nsIntRegion maskRegion;
     548           0 :   if (resolution != mTiledBuffer.GetResolution()) {
     549           0 :     maskRegion = mTiledBuffer.GetValidRegion();
     550             :     // XXX This should be ScaleRoundIn, but there is no such function on
     551             :     //     nsIntRegion.
     552           0 :     maskRegion.ScaleRoundOut(layerScale.width, layerScale.height);
     553             :   }
     554             : 
     555             :   // Make sure the resolution and difference in frame resolution are accounted
     556             :   // for in the layer transform.
     557           0 :   aTransform.PreScale(1/(resolution * layerScale.width),
     558           0 :                       1/(resolution * layerScale.height), 1);
     559             : 
     560           0 :   DiagnosticFlags componentAlphaDiagnostic = DiagnosticFlags::NO_DIAGNOSTIC;
     561             : 
     562           0 :   nsIntRegion compositeRegion = aLayerBuffer.GetValidRegion();
     563           0 :   compositeRegion.AndWith(aVisibleRegion);
     564           0 :   compositeRegion.SubOut(maskRegion);
     565             : 
     566           0 :   IntRect visibleRect = aVisibleRegion.GetBounds();
     567             : 
     568           0 :   if (compositeRegion.IsEmpty()) {
     569           0 :     return;
     570             :   }
     571             : 
     572           0 :   if (aBackgroundColor) {
     573           0 :     nsIntRegion backgroundRegion = compositeRegion;
     574           0 :     backgroundRegion.ScaleRoundOut(resolution, resolution);
     575           0 :     EffectChain effect;
     576           0 :     effect.mPrimaryEffect = new EffectSolidColor(*aBackgroundColor);
     577           0 :     for (auto iter = backgroundRegion.RectIter(); !iter.Done(); iter.Next()) {
     578           0 :       const IntRect& rect = iter.Get();
     579           0 :       Rect graphicsRect(rect.x, rect.y, rect.width, rect.height);
     580             :       aCompositor->DrawGeometry(graphicsRect, aClipRect, effect,
     581           0 :                                 1.0, aTransform, aGeometry);
     582             :     }
     583             :   }
     584             : 
     585           0 :   for (size_t i = 0; i < aLayerBuffer.GetTileCount(); ++i) {
     586           0 :     TileHost& tile = aLayerBuffer.GetTile(i);
     587           0 :     if (tile.IsPlaceholderTile()) {
     588           0 :       continue;
     589             :     }
     590             : 
     591           0 :     TileIntPoint tilePosition = aLayerBuffer.GetPlacement().TilePosition(i);
     592             :     // A sanity check that catches a lot of mistakes.
     593           0 :     MOZ_ASSERT(tilePosition.x == tile.mTilePosition.x && tilePosition.y == tile.mTilePosition.y);
     594             : 
     595           0 :     IntPoint tileOffset = aLayerBuffer.GetTileOffset(tilePosition);
     596           0 :     nsIntRegion tileDrawRegion = IntRect(tileOffset, aLayerBuffer.GetScaledTileSize());
     597           0 :     tileDrawRegion.AndWith(compositeRegion);
     598             : 
     599           0 :     if (tileDrawRegion.IsEmpty()) {
     600           0 :       continue;
     601             :     }
     602             : 
     603           0 :     tileDrawRegion.ScaleRoundOut(resolution, resolution);
     604           0 :     RenderTile(tile, aCompositor, aEffectChain, aOpacity,
     605             :                aTransform, aSamplingFilter, aClipRect, tileDrawRegion,
     606           0 :                tileOffset * resolution, aLayerBuffer.GetTileSize(),
     607           0 :                gfx::Rect(visibleRect.x, visibleRect.y,
     608           0 :                          visibleRect.width, visibleRect.height),
     609           0 :                aGeometry);
     610             : 
     611           0 :     if (tile.mTextureHostOnWhite) {
     612           0 :       componentAlphaDiagnostic = DiagnosticFlags::COMPONENT_ALPHA;
     613             :     }
     614             :   }
     615             : 
     616           0 :   gfx::Rect rect(visibleRect.x, visibleRect.y,
     617           0 :                  visibleRect.width, visibleRect.height);
     618           0 :   aCompositor->DrawDiagnostics(DiagnosticFlags::CONTENT | componentAlphaDiagnostic,
     619           0 :                                rect, aClipRect, aTransform, mFlashCounter);
     620             : }
     621             : 
     622             : void
     623           0 : TiledContentHost::PrintInfo(std::stringstream& aStream, const char* aPrefix)
     624             : {
     625           0 :   aStream << aPrefix;
     626           0 :   aStream << nsPrintfCString("TiledContentHost (0x%p)", this).get();
     627             : 
     628           0 :   if (gfxPrefs::LayersDumpTexture() ||
     629           0 :       profiler_feature_active(ProfilerFeature::LayersDump)) {
     630           0 :     nsAutoCString pfx(aPrefix);
     631           0 :     pfx += "  ";
     632             : 
     633           0 :     Dump(aStream, pfx.get(), false);
     634             :   }
     635           0 : }
     636             : 
     637             : void
     638           0 : TiledContentHost::Dump(std::stringstream& aStream,
     639             :                        const char* aPrefix,
     640             :                        bool aDumpHtml)
     641             : {
     642           0 :   mTiledBuffer.Dump(aStream, aPrefix, aDumpHtml,
     643           0 :       TextureDumpMode::DoNotCompress /* compression not supported on host side */);
     644           0 : }
     645             : 
     646             : void
     647           0 : TiledContentHost::AddAnimationInvalidation(nsIntRegion& aRegion)
     648             : {
     649           0 :   return mTiledBuffer.AddAnimationInvalidation(aRegion);
     650             : }
     651             : 
     652             : 
     653             : } // namespace layers
     654             : } // namespace mozilla

Generated by: LCOV version 1.13