Bug 1323791 - Part 1: Use no-repeat texture rects with polygon layers
MozReview-Commit-ID: 3ObTvCXQZAj
--- 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,