Example #1
0
void
FrameBuilder::ProcessChildList(ContainerLayer* aContainer,
                               RenderViewMLGPU* aView,
                               const RenderTargetIntRect& aParentClipRect,
                               const Maybe<gfx::Polygon>& aParentGeometry)
{
  nsTArray<LayerPolygon> polygons =
    aContainer->SortChildrenBy3DZOrder(ContainerLayer::SortMode::WITH_GEOMETRY);

  // Visit layers in front-to-back order.
  for (auto iter = polygons.rbegin(); iter != polygons.rend(); iter++) {
    LayerPolygon& entry = *iter;
    Layer* child = entry.layer;
    if (child->IsBackfaceHidden() || !child->IsVisible()) {
      continue;
    }

    RenderTargetIntRect clip = child->CalculateScissorRect(aParentClipRect);
    if (clip.IsEmpty()) {
      continue;
    }

    Maybe<gfx::Polygon> geometry;
    if (aParentGeometry && entry.geometry) {
      // Both parent and child are split.
      geometry = Some(aParentGeometry->ClipPolygon(*entry.geometry));
    } else if (aParentGeometry) {
      geometry = aParentGeometry;
    } else if (entry.geometry) {
      geometry = Move(entry.geometry);
    }

    AssignLayer(child, aView, clip, Move(geometry));
  }
}
Example #2
0
void
Compositor::DrawGeometry(const gfx::Rect& aRect,
                         const gfx::IntRect& aClipRect,
                         const EffectChain& aEffectChain,
                         gfx::Float aOpacity,
                         const gfx::Matrix4x4& aTransform,
                         const gfx::Rect& aVisibleRect,
                         const Maybe<gfx::Polygon3D>& aGeometry)
{
  if (!aGeometry) {
    DrawQuad(aRect, aClipRect, aEffectChain,
             aOpacity, aTransform, aVisibleRect);
    return;
  }

  // Cull invisible polygons.
  if (aRect.Intersect(aGeometry->BoundingBox()).IsEmpty()) {
    return;
  }

  gfx::Polygon3D clipped = aGeometry->ClipPolygon(aRect);
  nsTArray<gfx::Triangle> triangles = clipped.ToTriangles();

  for (gfx::Triangle& geometry : triangles) {
    const gfx::Rect intersection = aRect.Intersect(geometry.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);

    gfx::TexturedTriangle triangle(Move(geometry));
    triangle.width = aRect.width;
    triangle.height = aRect.height;

    // Since the texture was created for non-split geometry, we need to
    // update the texture coordinates to account for the split.
    if (aEffectChain.mPrimaryEffect->mType == EffectTypes::RGB) {
      TexturedEffect* texturedEffect =
        static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());

      UpdateTextureCoordinates(triangle, aRect, intersection,
                               texturedEffect->mTextureCoords);
    }

    DrawTriangle(triangle, aClipRect, aEffectChain,
                 aOpacity, aTransform, aVisibleRect);
  }
}