Bug 1323791 - Part 1: Use no-repeat texture rects with polygon layers draft
authorMiko Mynttinen <mikokm@gmail.com>
Thu, 09 Feb 2017 12:37:34 +0100
changeset 493722 13568b25091d40e4baff93f957a806547c6bc8ef
parent 493721 8d026c60151005ad942e3d4389318fe28a0c8c54
child 493723 ae320c2ca2395d909553d6d409230cf22330845f
push id47827
push userbmo:mikokm@gmail.com
push dateSun, 05 Mar 2017 19:40:03 +0000
bugs1323791
milestone54.0a1
Bug 1323791 - Part 1: Use no-repeat texture rects with polygon layers MozReview-Commit-ID: 3ObTvCXQZAj
gfx/layers/Compositor.cpp
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -306,53 +306,86 @@ Compositor::DrawTriangles(const nsTArray
                           const gfx::Rect& aVisibleRect)
 {
   for (const gfx::TexturedTriangle& triangle : aTriangles) {
     DrawTriangle(triangle, aClipRect, aEffectChain,
                  aOpacity, aTransform, aVisibleRect);
   }
 }
 
+static nsTArray<gfx::TexturedTriangle>
+GenerateTexturedTriangles(const gfx::Polygon& aPolygon,
+                          const gfx::Rect& aRect,
+                          const gfx::Rect& aTexRect)
+{
+  nsTArray<gfx::TexturedTriangle> texturedTriangles;
+
+  gfx::Rect layerRects[4];
+  gfx::Rect textureRects[4];
+  size_t rects = DecomposeIntoNoRepeatRects(aRect, aTexRect,
+                                            &layerRects, &textureRects);
+  for (size_t i = 0; i < rects; ++i) {
+    const gfx::Rect& rect = layerRects[i];
+    const gfx::Rect& texRect = textureRects[i];
+    const gfx::Polygon clipped = aPolygon.ClipPolygon(rect);
+
+    if (clipped.IsEmpty()) {
+      continue;
+    }
+
+    for (const gfx::Triangle& triangle : clipped.ToTriangles()) {
+      const gfx::Rect intersection = rect.Intersect(triangle.BoundingBox());
+
+      // Cull completely invisible triangles.
+      if (intersection.IsEmpty()) {
+        continue;
+      }
+
+      MOZ_ASSERT(rect.width > 0.0f && rect.height > 0.0f);
+      MOZ_ASSERT(intersection.width > 0.0f && intersection.height > 0.0f);
+
+      // Since the texture was created for non-split geometry, we need to
+      // update the texture coordinates to account for the split.
+      gfx::TexturedTriangle t(triangle);
+      t.width = rect.width;
+      t.height = rect.height;
+      UpdateTextureCoordinates(t, rect, intersection, texRect);
+      texturedTriangles.AppendElement(Move(t));
+    }
+  }
+
+  return texturedTriangles;
+}
+
 void
 Compositor::DrawPolygon(const gfx::Polygon& aPolygon,
                         const gfx::Rect& aRect,
                         const gfx::IntRect& aClipRect,
                         const EffectChain& aEffectChain,
                         gfx::Float aOpacity,
                         const gfx::Matrix4x4& aTransform,
                         const gfx::Rect& aVisibleRect)
 {
   nsTArray<gfx::TexturedTriangle> texturedTriangles;
 
-  for (gfx::Triangle& triangle : aPolygon.ToTriangles()) {
-    const gfx::Rect intersection = aRect.Intersect(triangle.BoundingBox());
-
-    // Cull invisible triangles.
-    if (intersection.IsEmpty()) {
-      continue;
-    }
-
-    MOZ_ASSERT(aRect.width > 0.0f && aRect.height > 0.0f);
-    MOZ_ASSERT(intersection.width > 0.0f && intersection.height > 0.0f);
+  TexturedEffect* texturedEffect =
+    aEffectChain.mPrimaryEffect->AsTexturedEffect();
 
-    gfx::TexturedTriangle texturedTriangle(Move(triangle));
-    texturedTriangle.width = aRect.width;
-    texturedTriangle.height = aRect.height;
+  if (texturedEffect) {
+    texturedTriangles =
+      GenerateTexturedTriangles(aPolygon, aRect, texturedEffect->mTextureCoords);
+  } else {
+    for (const gfx::Triangle& triangle : aPolygon.ToTriangles()) {
+      texturedTriangles.AppendElement(gfx::TexturedTriangle(triangle));
+    }
+  }
 
-    // Since the texture was created for non-split geometry, we need to
-    // update the texture coordinates to account for the split.
-    TexturedEffect* texturedEffect =
-      aEffectChain.mPrimaryEffect->AsTexturedEffect();
-
-    if (texturedEffect) {
-      UpdateTextureCoordinates(texturedTriangle, aRect, intersection,
-                               texturedEffect->mTextureCoords);
-    }
-
-    texturedTriangles.AppendElement(Move(texturedTriangle));
+  if (texturedTriangles.IsEmpty()) {
+    // Nothing to render.
+    return;
   }
 
   DrawTriangles(texturedTriangles, aRect, aClipRect, aEffectChain,
                 aOpacity, aTransform, aVisibleRect);
 }
 
 void
 Compositor::SlowDrawRect(const gfx::Rect& aRect, const gfx::Color& aColor,