LCOV - code coverage report
Current view: top level - gfx/layers - Compositor.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 33 265 12.5 %
Date: 2017-07-14 16:53:18 Functions: 9 33 27.3 %
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 "mozilla/layers/Compositor.h"
       7             : #include "base/message_loop.h"          // for MessageLoop
       8             : #include "mozilla/layers/CompositorBridgeParent.h"  // for CompositorBridgeParent
       9             : #include "mozilla/layers/Diagnostics.h"
      10             : #include "mozilla/layers/Effects.h"     // for Effect, EffectChain, etc
      11             : #include "mozilla/layers/TextureClient.h"
      12             : #include "mozilla/layers/TextureHost.h"
      13             : #include "mozilla/layers/CompositorThread.h"
      14             : #include "mozilla/mozalloc.h"           // for operator delete, etc
      15             : #include "gfx2DGlue.h"
      16             : #include "nsAppRunner.h"
      17             : #include "LayersHelpers.h"
      18             : 
      19             : namespace mozilla {
      20             : 
      21             : namespace layers {
      22             : 
      23           1 : Compositor::Compositor(widget::CompositorWidget* aWidget,
      24           1 :                       CompositorBridgeParent* aParent)
      25             :   : mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
      26             :   , mParent(aParent)
      27             :   , mPixelsPerFrame(0)
      28             :   , mPixelsFilled(0)
      29             :   , mScreenRotation(ROTATION_0)
      30             :   , mWidget(aWidget)
      31             :   , mIsDestroyed(false)
      32             : #if defined(MOZ_WIDGET_ANDROID)
      33             :   // If the default color isn't white for Fennec, there is a black
      34             :   // flash before the first page of a tab is loaded.
      35             :   , mClearColor(1.0, 1.0, 1.0, 1.0)
      36             :   , mDefaultClearColor(1.0, 1.0, 1.0, 1.0)
      37             : #else
      38             :   , mClearColor(0.0, 0.0, 0.0, 0.0)
      39           1 :   , mDefaultClearColor(0.0, 0.0, 0.0, 0.0)
      40             : #endif
      41             : {
      42           1 : }
      43             : 
      44           0 : Compositor::~Compositor()
      45             : {
      46           0 :   ReadUnlockTextures();
      47           0 : }
      48             : 
      49             : void
      50           0 : Compositor::Destroy()
      51             : {
      52           0 :   TextureSourceProvider::Destroy();
      53           0 :   mIsDestroyed = true;
      54           0 : }
      55             : 
      56             : void
      57          27 : Compositor::EndFrame()
      58             : {
      59          27 :   ReadUnlockTextures();
      60          27 :   mLastCompositionEndTime = TimeStamp::Now();
      61          27 : }
      62             : 
      63             : /* static */ void
      64         316 : Compositor::AssertOnCompositorThread()
      65             : {
      66         316 :   MOZ_ASSERT(!CompositorThreadHolder::Loop() ||
      67             :              CompositorThreadHolder::Loop() == MessageLoop::current(),
      68             :              "Can only call this from the compositor thread!");
      69         316 : }
      70             : 
      71             : bool
      72          86 : Compositor::ShouldDrawDiagnostics(DiagnosticFlags aFlags)
      73             : {
      74          86 :   if ((aFlags & DiagnosticFlags::TILE) && !(mDiagnosticTypes & DiagnosticTypes::TILE_BORDERS)) {
      75           0 :     return false;
      76             :   }
      77         258 :   if ((aFlags & DiagnosticFlags::BIGIMAGE) &&
      78         172 :       !(mDiagnosticTypes & DiagnosticTypes::BIGIMAGE_BORDERS)) {
      79           0 :     return false;
      80             :   }
      81          86 :   if (mDiagnosticTypes == DiagnosticTypes::NO_DIAGNOSTIC) {
      82          86 :     return false;
      83             :   }
      84           0 :   return true;
      85             : }
      86             : 
      87             : void
      88          56 : Compositor::DrawDiagnostics(DiagnosticFlags aFlags,
      89             :                             const nsIntRegion& aVisibleRegion,
      90             :                             const gfx::IntRect& aClipRect,
      91             :                             const gfx::Matrix4x4& aTransform,
      92             :                             uint32_t aFlashCounter)
      93             : {
      94          56 :   if (!ShouldDrawDiagnostics(aFlags)) {
      95          56 :     return;
      96             :   }
      97             : 
      98           0 :   if (aVisibleRegion.GetNumRects() > 1) {
      99           0 :     for (auto iter = aVisibleRegion.RectIter(); !iter.Done(); iter.Next()) {
     100           0 :       DrawDiagnostics(aFlags | DiagnosticFlags::REGION_RECT,
     101           0 :                       IntRectToRect(iter.Get()), aClipRect, aTransform,
     102           0 :                       aFlashCounter);
     103             :     }
     104             :   }
     105             : 
     106           0 :   DrawDiagnostics(aFlags, IntRectToRect(aVisibleRegion.GetBounds()),
     107           0 :                   aClipRect, aTransform, aFlashCounter);
     108             : }
     109             : 
     110             : void
     111          30 : Compositor::DrawDiagnostics(DiagnosticFlags aFlags,
     112             :                             const gfx::Rect& aVisibleRect,
     113             :                             const gfx::IntRect& aClipRect,
     114             :                             const gfx::Matrix4x4& aTransform,
     115             :                             uint32_t aFlashCounter)
     116             : {
     117          30 :   if (!ShouldDrawDiagnostics(aFlags)) {
     118          30 :     return;
     119             :   }
     120             : 
     121             :   DrawDiagnosticsInternal(aFlags, aVisibleRect, aClipRect, aTransform,
     122           0 :                           aFlashCounter);
     123             : }
     124             : 
     125             : void
     126           0 : Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags,
     127             :                                     const gfx::Rect& aVisibleRect,
     128             :                                     const gfx::IntRect& aClipRect,
     129             :                                     const gfx::Matrix4x4& aTransform,
     130             :                                     uint32_t aFlashCounter)
     131             : {
     132             : #ifdef ANDROID
     133             :   int lWidth = 10;
     134             : #else
     135           0 :   int lWidth = 2;
     136             : #endif
     137             : 
     138           0 :   gfx::Color color;
     139           0 :   if (aFlags & DiagnosticFlags::CONTENT) {
     140           0 :     color = gfx::Color(0.0f, 1.0f, 0.0f, 1.0f); // green
     141           0 :     if (aFlags & DiagnosticFlags::COMPONENT_ALPHA) {
     142           0 :       color = gfx::Color(0.0f, 1.0f, 1.0f, 1.0f); // greenish blue
     143             :     }
     144           0 :   } else if (aFlags & DiagnosticFlags::IMAGE) {
     145           0 :     if (aFlags & DiagnosticFlags::NV12) {
     146           0 :       color = gfx::Color(1.0f, 1.0f, 0.0f, 1.0f); // yellow
     147           0 :     } else if (aFlags & DiagnosticFlags::YCBCR) {
     148           0 :       color = gfx::Color(1.0f, 0.55f, 0.0f, 1.0f); // orange
     149             :     } else {
     150           0 :       color = gfx::Color(1.0f, 0.0f, 0.0f, 1.0f); // red
     151             :     }
     152           0 :   } else if (aFlags & DiagnosticFlags::COLOR) {
     153           0 :     color = gfx::Color(0.0f, 0.0f, 1.0f, 1.0f); // blue
     154           0 :   } else if (aFlags & DiagnosticFlags::CONTAINER) {
     155           0 :     color = gfx::Color(0.8f, 0.0f, 0.8f, 1.0f); // purple
     156             :   }
     157             : 
     158             :   // make tile borders a bit more transparent to keep layer borders readable.
     159           0 :   if (aFlags & DiagnosticFlags::TILE ||
     160           0 :       aFlags & DiagnosticFlags::BIGIMAGE ||
     161           0 :       aFlags & DiagnosticFlags::REGION_RECT) {
     162           0 :     lWidth = 1;
     163           0 :     color.r *= 0.7f;
     164           0 :     color.g *= 0.7f;
     165           0 :     color.b *= 0.7f;
     166           0 :     color.a = color.a * 0.5f;
     167             :   } else {
     168           0 :     color.a = color.a * 0.7f;
     169             :   }
     170             : 
     171             : 
     172           0 :   if (mDiagnosticTypes & DiagnosticTypes::FLASH_BORDERS) {
     173           0 :     float flash = (float)aFlashCounter / (float)DIAGNOSTIC_FLASH_COUNTER_MAX;
     174           0 :     color.r *= flash;
     175           0 :     color.g *= flash;
     176           0 :     color.b *= flash;
     177             :   }
     178             : 
     179           0 :   SlowDrawRect(aVisibleRect, color, aClipRect, aTransform, lWidth);
     180           0 : }
     181             : 
     182             : static void
     183           0 : UpdateTextureCoordinates(gfx::TexturedTriangle& aTriangle,
     184             :                          const gfx::Rect& aRect,
     185             :                          const gfx::Rect& aIntersection,
     186             :                          const gfx::Rect& aTextureCoords)
     187             : {
     188             :   // Calculate the relative offset of the intersection within the layer.
     189           0 :   float dx = (aIntersection.x - aRect.x) / aRect.width;
     190           0 :   float dy = (aIntersection.y - aRect.y) / aRect.height;
     191             : 
     192             :   // Update the texture offset.
     193           0 :   float x = aTextureCoords.x + dx * aTextureCoords.width;
     194           0 :   float y = aTextureCoords.y + dy * aTextureCoords.height;
     195             : 
     196             :   // Scale the texture width and height.
     197           0 :   float w = aTextureCoords.width * aIntersection.width / aRect.width;
     198           0 :   float h = aTextureCoords.height * aIntersection.height / aRect.height;
     199             : 
     200           0 :   static const auto Clamp = [](float& f)
     201             :   {
     202           0 :     if (f >= 1.0f) f = 1.0f;
     203           0 :     if (f <= 0.0f) f = 0.0f;
     204           0 :   };
     205             : 
     206           0 :   auto UpdatePoint = [&](const gfx::Point& p, gfx::Point& t)
     207             :   {
     208           0 :     t.x = x + (p.x - aIntersection.x) / aIntersection.width * w;
     209           0 :     t.y = y + (p.y - aIntersection.y) / aIntersection.height * h;
     210             : 
     211           0 :     Clamp(t.x);
     212           0 :     Clamp(t.y);
     213           0 :   };
     214             : 
     215           0 :   UpdatePoint(aTriangle.p1, aTriangle.textureCoords.p1);
     216           0 :   UpdatePoint(aTriangle.p2, aTriangle.textureCoords.p2);
     217           0 :   UpdatePoint(aTriangle.p3, aTriangle.textureCoords.p3);
     218           0 : }
     219             : 
     220             : void
     221          80 : Compositor::DrawGeometry(const gfx::Rect& aRect,
     222             :                          const gfx::IntRect& aClipRect,
     223             :                          const EffectChain& aEffectChain,
     224             :                          gfx::Float aOpacity,
     225             :                          const gfx::Matrix4x4& aTransform,
     226             :                          const gfx::Rect& aVisibleRect,
     227             :                          const Maybe<gfx::Polygon>& aGeometry)
     228             : {
     229          80 :   if (aRect.IsEmpty()) {
     230          99 :     return;
     231             :   }
     232             : 
     233          61 :   if (!aGeometry || !SupportsLayerGeometry()) {
     234             :     DrawQuad(aRect, aClipRect, aEffectChain,
     235          61 :              aOpacity, aTransform, aVisibleRect);
     236          61 :     return;
     237             :   }
     238             : 
     239             :   // Cull completely invisible polygons.
     240           0 :   if (aRect.Intersect(aGeometry->BoundingBox()).IsEmpty()) {
     241           0 :     return;
     242             :   }
     243             : 
     244           0 :   const gfx::Polygon clipped = aGeometry->ClipPolygon(aRect);
     245             : 
     246             :   // Cull polygons with no area.
     247           0 :   if (clipped.IsEmpty()) {
     248           0 :     return;
     249             :   }
     250             : 
     251             :   DrawPolygon(clipped, aRect, aClipRect, aEffectChain,
     252           0 :               aOpacity, aTransform, aVisibleRect);
     253             : }
     254             : 
     255             : void
     256           0 : Compositor::DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
     257             :                           const gfx::Rect& aRect,
     258             :                           const gfx::IntRect& aClipRect,
     259             :                           const EffectChain& aEffectChain,
     260             :                           gfx::Float aOpacity,
     261             :                           const gfx::Matrix4x4& aTransform,
     262             :                           const gfx::Rect& aVisibleRect)
     263             : {
     264           0 :   for (const gfx::TexturedTriangle& triangle : aTriangles) {
     265             :     DrawTriangle(triangle, aClipRect, aEffectChain,
     266           0 :                  aOpacity, aTransform, aVisibleRect);
     267             :   }
     268           0 : }
     269             : 
     270             : nsTArray<gfx::TexturedTriangle>
     271           0 : GenerateTexturedTriangles(const gfx::Polygon& aPolygon,
     272             :                           const gfx::Rect& aRect,
     273             :                           const gfx::Rect& aTexRect)
     274             : {
     275           0 :   nsTArray<gfx::TexturedTriangle> texturedTriangles;
     276             : 
     277           0 :   gfx::Rect layerRects[4];
     278           0 :   gfx::Rect textureRects[4];
     279             :   size_t rects = DecomposeIntoNoRepeatRects(aRect, aTexRect,
     280           0 :                                             &layerRects, &textureRects);
     281           0 :   for (size_t i = 0; i < rects; ++i) {
     282           0 :     const gfx::Rect& rect = layerRects[i];
     283           0 :     const gfx::Rect& texRect = textureRects[i];
     284           0 :     const gfx::Polygon clipped = aPolygon.ClipPolygon(rect);
     285             : 
     286           0 :     if (clipped.IsEmpty()) {
     287           0 :       continue;
     288             :     }
     289             : 
     290           0 :     for (const gfx::Triangle& triangle : clipped.ToTriangles()) {
     291           0 :       const gfx::Rect intersection = rect.Intersect(triangle.BoundingBox());
     292             : 
     293             :       // Cull completely invisible triangles.
     294           0 :       if (intersection.IsEmpty()) {
     295           0 :         continue;
     296             :       }
     297             : 
     298           0 :       MOZ_ASSERT(rect.width > 0.0f && rect.height > 0.0f);
     299           0 :       MOZ_ASSERT(intersection.width > 0.0f && intersection.height > 0.0f);
     300             : 
     301             :       // Since the texture was created for non-split geometry, we need to
     302             :       // update the texture coordinates to account for the split.
     303           0 :       gfx::TexturedTriangle t(triangle);
     304           0 :       UpdateTextureCoordinates(t, rect, intersection, texRect);
     305           0 :       texturedTriangles.AppendElement(Move(t));
     306             :     }
     307             :   }
     308             : 
     309           0 :   return texturedTriangles;
     310             : }
     311             : 
     312             : nsTArray<TexturedVertex>
     313           0 : TexturedTrianglesToVertexArray(const nsTArray<gfx::TexturedTriangle>& aTriangles)
     314             : {
     315           0 :   const auto VertexFromPoints = [](const gfx::Point& p, const gfx::Point& t) {
     316           0 :     return TexturedVertex { { p.x, p.y }, { t.x, t.y } };
     317           0 :   };
     318             : 
     319           0 :   nsTArray<TexturedVertex> vertices;
     320             : 
     321           0 :   for (const gfx::TexturedTriangle& t : aTriangles) {
     322           0 :     vertices.AppendElement(VertexFromPoints(t.p1, t.textureCoords.p1));
     323           0 :     vertices.AppendElement(VertexFromPoints(t.p2, t.textureCoords.p2));
     324           0 :     vertices.AppendElement(VertexFromPoints(t.p3, t.textureCoords.p3));
     325             :   }
     326             : 
     327           0 :   return vertices;
     328             : }
     329             : 
     330             : void
     331           0 : Compositor::DrawPolygon(const gfx::Polygon& aPolygon,
     332             :                         const gfx::Rect& aRect,
     333             :                         const gfx::IntRect& aClipRect,
     334             :                         const EffectChain& aEffectChain,
     335             :                         gfx::Float aOpacity,
     336             :                         const gfx::Matrix4x4& aTransform,
     337             :                         const gfx::Rect& aVisibleRect)
     338             : {
     339           0 :   nsTArray<gfx::TexturedTriangle> texturedTriangles;
     340             : 
     341             :   TexturedEffect* texturedEffect =
     342           0 :     aEffectChain.mPrimaryEffect->AsTexturedEffect();
     343             : 
     344           0 :   if (texturedEffect) {
     345             :     texturedTriangles =
     346           0 :       GenerateTexturedTriangles(aPolygon, aRect, texturedEffect->mTextureCoords);
     347             :   } else {
     348           0 :     for (const gfx::Triangle& triangle : aPolygon.ToTriangles()) {
     349           0 :       texturedTriangles.AppendElement(gfx::TexturedTriangle(triangle));
     350             :     }
     351             :   }
     352             : 
     353           0 :   if (texturedTriangles.IsEmpty()) {
     354             :     // Nothing to render.
     355           0 :     return;
     356             :   }
     357             : 
     358             :   DrawTriangles(texturedTriangles, aRect, aClipRect, aEffectChain,
     359           0 :                 aOpacity, aTransform, aVisibleRect);
     360             : }
     361             : 
     362             : void
     363           0 : Compositor::SlowDrawRect(const gfx::Rect& aRect, const gfx::Color& aColor,
     364             :                      const gfx::IntRect& aClipRect,
     365             :                      const gfx::Matrix4x4& aTransform, int aStrokeWidth)
     366             : {
     367             :   // TODO This should draw a rect using a single draw call but since
     368             :   // this is only used for debugging overlays it's not worth optimizing ATM.
     369           0 :   float opacity = 1.0f;
     370           0 :   EffectChain effects;
     371             : 
     372           0 :   effects.mPrimaryEffect = new EffectSolidColor(aColor);
     373             :   // left
     374           0 :   this->DrawQuad(gfx::Rect(aRect.x, aRect.y,
     375           0 :                            aStrokeWidth, aRect.height),
     376             :                  aClipRect, effects, opacity,
     377           0 :                  aTransform);
     378             :   // top
     379           0 :   this->DrawQuad(gfx::Rect(aRect.x + aStrokeWidth, aRect.y,
     380           0 :                            aRect.width - 2 * aStrokeWidth, aStrokeWidth),
     381             :                  aClipRect, effects, opacity,
     382           0 :                  aTransform);
     383             :   // right
     384           0 :   this->DrawQuad(gfx::Rect(aRect.x + aRect.width - aStrokeWidth, aRect.y,
     385           0 :                            aStrokeWidth, aRect.height),
     386             :                  aClipRect, effects, opacity,
     387           0 :                  aTransform);
     388             :   // bottom
     389           0 :   this->DrawQuad(gfx::Rect(aRect.x + aStrokeWidth, aRect.y + aRect.height - aStrokeWidth,
     390           0 :                            aRect.width - 2 * aStrokeWidth, aStrokeWidth),
     391             :                  aClipRect, effects, opacity,
     392           0 :                  aTransform);
     393           0 : }
     394             : 
     395             : void
     396           0 : Compositor::FillRect(const gfx::Rect& aRect, const gfx::Color& aColor,
     397             :                      const gfx::IntRect& aClipRect,
     398             :                      const gfx::Matrix4x4& aTransform)
     399             : {
     400           0 :   float opacity = 1.0f;
     401           0 :   EffectChain effects;
     402             : 
     403           0 :   effects.mPrimaryEffect = new EffectSolidColor(aColor);
     404             :   this->DrawQuad(aRect,
     405             :                  aClipRect, effects, opacity,
     406           0 :                  aTransform);
     407           0 : }
     408             : 
     409             : 
     410             : static float
     411           0 : WrapTexCoord(float v)
     412             : {
     413             :     // This should return values in range [0, 1.0)
     414           0 :     return v - floorf(v);
     415             : }
     416             : 
     417             : static void
     418           0 : SetRects(size_t n,
     419             :          decomposedRectArrayT* aLayerRects,
     420             :          decomposedRectArrayT* aTextureRects,
     421             :          float x0, float y0, float x1, float y1,
     422             :          float tx0, float ty0, float tx1, float ty1,
     423             :          bool flip_y)
     424             : {
     425           0 :   if (flip_y) {
     426           0 :     std::swap(ty0, ty1);
     427             :   }
     428           0 :   (*aLayerRects)[n] = gfx::Rect(x0, y0, x1 - x0, y1 - y0);
     429           0 :   (*aTextureRects)[n] = gfx::Rect(tx0, ty0, tx1 - tx0, ty1 - ty0);
     430           0 : }
     431             : 
     432             : #ifdef DEBUG
     433             : static inline bool
     434           0 : FuzzyEqual(float a, float b)
     435             : {
     436           0 :         return fabs(a - b) < 0.0001f;
     437             : }
     438             : static inline bool
     439           0 : FuzzyLTE(float a, float b)
     440             : {
     441           0 :         return a <= b + 0.0001f;
     442             : }
     443             : #endif
     444             : 
     445             : size_t
     446           0 : DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
     447             :                            const gfx::Rect& aTexCoordRect,
     448             :                            decomposedRectArrayT* aLayerRects,
     449             :                            decomposedRectArrayT* aTextureRects)
     450             : {
     451           0 :   gfx::Rect texCoordRect = aTexCoordRect;
     452             : 
     453             :   // If the texture should be flipped, it will have negative height. Detect that
     454             :   // here and compensate for it. We will flip each rect as we emit it.
     455           0 :   bool flipped = false;
     456           0 :   if (texCoordRect.height < 0) {
     457           0 :     flipped = true;
     458           0 :     texCoordRect.y += texCoordRect.height;
     459           0 :     texCoordRect.height = -texCoordRect.height;
     460             :   }
     461             : 
     462             :   // Wrap the texture coordinates so they are within [0,1] and cap width/height
     463             :   // at 1. We rely on this below.
     464           0 :   texCoordRect = gfx::Rect(gfx::Point(WrapTexCoord(texCoordRect.x),
     465             :                                       WrapTexCoord(texCoordRect.y)),
     466           0 :                            gfx::Size(std::min(texCoordRect.width, 1.0f),
     467           0 :                                      std::min(texCoordRect.height, 1.0f)));
     468             : 
     469           0 :   NS_ASSERTION(texCoordRect.x >= 0.0f && texCoordRect.x <= 1.0f &&
     470             :                texCoordRect.y >= 0.0f && texCoordRect.y <= 1.0f &&
     471             :                texCoordRect.width >= 0.0f && texCoordRect.width <= 1.0f &&
     472             :                texCoordRect.height >= 0.0f && texCoordRect.height <= 1.0f &&
     473             :                texCoordRect.XMost() >= 0.0f && texCoordRect.XMost() <= 2.0f &&
     474             :                texCoordRect.YMost() >= 0.0f && texCoordRect.YMost() <= 2.0f,
     475             :                "We just wrapped the texture coordinates, didn't we?");
     476             : 
     477             :   // Get the top left and bottom right points of the rectangle. Note that
     478             :   // tl.x/tl.y are within [0,1] but br.x/br.y are within [0,2].
     479           0 :   gfx::Point tl = texCoordRect.TopLeft();
     480           0 :   gfx::Point br = texCoordRect.BottomRight();
     481             : 
     482           0 :   NS_ASSERTION(tl.x >= 0.0f && tl.x <= 1.0f &&
     483             :                tl.y >= 0.0f && tl.y <= 1.0f &&
     484             :                br.x >= tl.x && br.x <= 2.0f &&
     485             :                br.y >= tl.y && br.y <= 2.0f &&
     486             :                FuzzyLTE(br.x - tl.x, 1.0f) &&
     487             :                FuzzyLTE(br.y - tl.y, 1.0f),
     488             :                "Somehow generated invalid texture coordinates");
     489             : 
     490             :   // Then check if we wrap in either the x or y axis.
     491           0 :   bool xwrap = br.x > 1.0f;
     492           0 :   bool ywrap = br.y > 1.0f;
     493             : 
     494             :   // If xwrap is false, the texture will be sampled from tl.x .. br.x.
     495             :   // If xwrap is true, then it will be split into tl.x .. 1.0, and
     496             :   // 0.0 .. WrapTexCoord(br.x). Same for the Y axis. The destination
     497             :   // rectangle is also split appropriately, according to the calculated
     498             :   // xmid/ymid values.
     499           0 :   if (!xwrap && !ywrap) {
     500           0 :     SetRects(0, aLayerRects, aTextureRects,
     501           0 :              aRect.x, aRect.y, aRect.XMost(), aRect.YMost(),
     502             :              tl.x, tl.y, br.x, br.y,
     503           0 :              flipped);
     504           0 :     return 1;
     505             :   }
     506             : 
     507             :   // If we are dealing with wrapping br.x and br.y are greater than 1.0 so
     508             :   // wrap them here as well.
     509           0 :   br = gfx::Point(xwrap ? WrapTexCoord(br.x) : br.x,
     510           0 :                   ywrap ? WrapTexCoord(br.y) : br.y);
     511             : 
     512             :   // If we wrap around along the x axis, we will draw first from
     513             :   // tl.x .. 1.0 and then from 0.0 .. br.x (which we just wrapped above).
     514             :   // The same applies for the Y axis. The midpoints we calculate here are
     515             :   // only valid if we actually wrap around.
     516           0 :   GLfloat xmid = aRect.x + (1.0f - tl.x) / texCoordRect.width * aRect.width;
     517           0 :   GLfloat ymid = aRect.y + (1.0f - tl.y) / texCoordRect.height * aRect.height;
     518             : 
     519             :   // Due to floating-point inaccuracy, we have to use XMost()-x and YMost()-y
     520             :   // to calculate width and height, respectively, to ensure that size will
     521             :   // remain consistent going from absolute to relative and back again.
     522           0 :   NS_ASSERTION(!xwrap ||
     523             :                (xmid >= aRect.x &&
     524             :                 xmid <= aRect.XMost() &&
     525             :                 FuzzyEqual((xmid - aRect.x) + (aRect.XMost() - xmid), aRect.XMost() - aRect.x)),
     526             :                "xmid should be within [x,XMost()] and the wrapped rect should have the same width");
     527           0 :   NS_ASSERTION(!ywrap ||
     528             :                (ymid >= aRect.y &&
     529             :                 ymid <= aRect.YMost() &&
     530             :                 FuzzyEqual((ymid - aRect.y) + (aRect.YMost() - ymid), aRect.YMost() - aRect.y)),
     531             :                "ymid should be within [y,YMost()] and the wrapped rect should have the same height");
     532             : 
     533           0 :   if (!xwrap && ywrap) {
     534           0 :     SetRects(0, aLayerRects, aTextureRects,
     535           0 :              aRect.x, aRect.y, aRect.XMost(), ymid,
     536             :              tl.x, tl.y, br.x, 1.0f,
     537           0 :              flipped);
     538           0 :     SetRects(1, aLayerRects, aTextureRects,
     539           0 :              aRect.x, ymid, aRect.XMost(), aRect.YMost(),
     540             :              tl.x, 0.0f, br.x, br.y,
     541           0 :              flipped);
     542           0 :     return 2;
     543             :   }
     544             : 
     545           0 :   if (xwrap && !ywrap) {
     546           0 :     SetRects(0, aLayerRects, aTextureRects,
     547           0 :              aRect.x, aRect.y, xmid, aRect.YMost(),
     548             :              tl.x, tl.y, 1.0f, br.y,
     549           0 :              flipped);
     550           0 :     SetRects(1, aLayerRects, aTextureRects,
     551           0 :              xmid, aRect.y, aRect.XMost(), aRect.YMost(),
     552             :              0.0f, tl.y, br.x, br.y,
     553           0 :              flipped);
     554           0 :     return 2;
     555             :   }
     556             : 
     557           0 :   SetRects(0, aLayerRects, aTextureRects,
     558           0 :            aRect.x, aRect.y, xmid, ymid,
     559             :            tl.x, tl.y, 1.0f, 1.0f,
     560           0 :            flipped);
     561           0 :   SetRects(1, aLayerRects, aTextureRects,
     562           0 :            xmid, aRect.y, aRect.XMost(), ymid,
     563             :            0.0f, tl.y, br.x, 1.0f,
     564           0 :            flipped);
     565           0 :   SetRects(2, aLayerRects, aTextureRects,
     566           0 :            aRect.x, ymid, xmid, aRect.YMost(),
     567             :            tl.x, 0.0f, 1.0f, br.y,
     568           0 :            flipped);
     569           0 :   SetRects(3, aLayerRects, aTextureRects,
     570             :            xmid, ymid, aRect.XMost(), aRect.YMost(),
     571             :            0.0f, 0.0f, br.x, br.y,
     572           0 :            flipped);
     573           0 :   return 4;
     574             : }
     575             : 
     576             : gfx::IntRect
     577           0 : Compositor::ComputeBackdropCopyRect(const gfx::Rect& aRect,
     578             :                                     const gfx::IntRect& aClipRect,
     579             :                                     const gfx::Matrix4x4& aTransform,
     580             :                                     gfx::Matrix4x4* aOutTransform,
     581             :                                     gfx::Rect* aOutLayerQuad)
     582             : {
     583             :   // Compute the clip.
     584           0 :   gfx::IntPoint rtOffset = GetCurrentRenderTarget()->GetOrigin();
     585           0 :   gfx::IntSize rtSize = GetCurrentRenderTarget()->GetSize();
     586             : 
     587             :   return layers::ComputeBackdropCopyRect(
     588             :     aRect,
     589             :     aClipRect,
     590             :     aTransform,
     591           0 :     gfx::IntRect(rtOffset, rtSize),
     592             :     aOutTransform,
     593           0 :     aOutLayerQuad);
     594             : }
     595             : 
     596             : gfx::IntRect
     597           0 : Compositor::ComputeBackdropCopyRect(const gfx::Triangle& aTriangle,
     598             :                                     const gfx::IntRect& aClipRect,
     599             :                                     const gfx::Matrix4x4& aTransform,
     600             :                                     gfx::Matrix4x4* aOutTransform,
     601             :                                     gfx::Rect* aOutLayerQuad)
     602             : {
     603           0 :   gfx::Rect boundingBox = aTriangle.BoundingBox();
     604             :   return ComputeBackdropCopyRect(boundingBox, aClipRect, aTransform,
     605           0 :                                  aOutTransform, aOutLayerQuad);
     606             : }
     607             : 
     608             : void
     609           0 : Compositor::SetInvalid()
     610             : {
     611           0 :   mParent = nullptr;
     612           0 : }
     613             : 
     614             : bool
     615          66 : Compositor::IsValid() const
     616             : {
     617          66 :   return !!mParent;
     618             : }
     619             : 
     620             : void
     621          27 : Compositor::SetDispAcquireFence(Layer* aLayer)
     622             : {
     623          27 : }
     624             : 
     625             : bool
     626           0 : Compositor::NotifyNotUsedAfterComposition(TextureHost* aTextureHost)
     627             : {
     628           0 :   if (IsDestroyed() || AsBasicCompositor()) {
     629           0 :     return false;
     630             :   }
     631           0 :   return TextureSourceProvider::NotifyNotUsedAfterComposition(aTextureHost);
     632             : }
     633             : 
     634             : void
     635           0 : Compositor::GetFrameStats(GPUStats* aStats)
     636             : {
     637           0 :   aStats->mInvalidPixels = mPixelsPerFrame;
     638           0 :   aStats->mPixelsFilled = mPixelsFilled;
     639           0 : }
     640             : 
     641             : } // namespace layers
     642             : } // namespace mozilla

Generated by: LCOV version 1.13