virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                   bool* aSnap) override {
    *aSnap = false;
    nsHTMLCanvasFrame* f = static_cast<nsHTMLCanvasFrame*>(Frame());
    HTMLCanvasElement* canvas =
      HTMLCanvasElement::FromContent(f->GetContent());
    nsRegion result;
    if (canvas->GetIsOpaque()) {
      // OK, the entire region painted by the canvas is opaque. But what is
      // that region? It's the canvas's "dest rect" (controlled by the
      // object-fit/object-position CSS properties), clipped to the container's
      // content box (which is what GetBounds() returns). So, we grab those
      // rects and intersect them.
      nsRect constraintRect = GetBounds(aBuilder, aSnap);

      // Need intrinsic size & ratio, for ComputeObjectDestRect:
      nsIntSize canvasSize = f->GetCanvasSize();
      IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSize);
      nsSize intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSize);

      const nsRect destRect =
        nsLayoutUtils::ComputeObjectDestRect(constraintRect,
                                             intrinsicSize, intrinsicRatio,
                                             f->StylePosition());
      return nsRegion(destRect.Intersect(constraintRect));
    }
    return result;
  }
 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                  bool* aSnap) {
   *aSnap = false;
   nsIFrame* f = GetUnderlyingFrame();
   HTMLCanvasElement *canvas =
     HTMLCanvasElement::FromContent(f->GetContent());
   nsRegion result;
   if (canvas->GetIsOpaque()) {
     result = GetBounds(aBuilder, aSnap);
   }
   return result;
 }