Bug 603488 - Part 1: Refactor nsLayoutUtils to expose imgIContainer. r=roc
☠☠ backed out by aa59555856a1 ☠ ☠
authorJames Kolb <jck1089@gmail.com>
Mon, 15 Jul 2013 13:44:14 -0400
changeset 150810 eeed50e8e213916b7ae9aa291a4d27b8957d18a1
parent 150807 9d9f34dac338aa2684256178fd489f161541443a
child 150811 80520a16d7f1b1978c541dee89e4613ef3280d04
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs603488
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 603488 - Part 1: Refactor nsLayoutUtils to expose imgIContainer. r=roc
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4479,25 +4479,16 @@ nsLayoutUtils::IsReallyFixedPos(nsIFrame
 
 nsLayoutUtils::SurfaceFromElementResult
 nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement,
                                   uint32_t aSurfaceFlags)
 {
   SurfaceFromElementResult result;
   nsresult rv;
 
-  bool forceCopy = (aSurfaceFlags & SFE_WANT_NEW_SURFACE) != 0;
-  bool wantImageSurface = (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) != 0;
-  bool premultAlpha = (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA) == 0;
-
-  if (!premultAlpha) {
-    forceCopy = true;
-    wantImageSurface = true;
-  }
-
   // Push a null JSContext on the stack so that code that runs within
   // the below code doesn't think it's being called by JS. See bug
   // 604262.
   nsCxPusher pusher;
   pusher.PushNull();
 
   nsCOMPtr<imgIRequest> imgRequest;
   rv = aElement->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
@@ -4520,63 +4511,82 @@ nsLayoutUtils::SurfaceFromElement(nsIIma
   if (NS_FAILED(rv))
     return result;
 
   nsCOMPtr<imgIContainer> imgContainer;
   rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
   if (NS_FAILED(rv))
     return result;
 
+  uint32_t noRasterize = aSurfaceFlags & SFE_NO_RASTERIZING_VECTORS;
+
   uint32_t whichFrame = (aSurfaceFlags & SFE_WANT_FIRST_FRAME)
                         ? (uint32_t) imgIContainer::FRAME_FIRST
                         : (uint32_t) imgIContainer::FRAME_CURRENT;
   uint32_t frameFlags = imgIContainer::FLAG_SYNC_DECODE;
   if (aSurfaceFlags & SFE_NO_COLORSPACE_CONVERSION)
     frameFlags |= imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION;
   if (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA)
     frameFlags |= imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
-  nsRefPtr<gfxASurface> framesurf;
-  rv = imgContainer->GetFrame(whichFrame,
-                              frameFlags,
-                              getter_AddRefs(framesurf));
-  if (NS_FAILED(rv))
-    return result;
 
   int32_t imgWidth, imgHeight;
   rv = imgContainer->GetWidth(&imgWidth);
   nsresult rv2 = imgContainer->GetHeight(&imgHeight);
   if (NS_FAILED(rv) || NS_FAILED(rv2))
     return result;
 
-  if (wantImageSurface && framesurf->GetType() != gfxASurface::SurfaceTypeImage) {
-    forceCopy = true;
-  }
-
-  nsRefPtr<gfxASurface> gfxsurf = framesurf;
-  if (forceCopy) {
-    if (wantImageSurface) {
-      gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
-    } else {
-      gfxsurf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(imgWidth, imgHeight),
-                                                                   gfxASurface::CONTENT_COLOR_ALPHA);
+  if (!noRasterize || imgContainer->GetType() == imgIContainer::TYPE_RASTER) {
+    bool forceCopy = (aSurfaceFlags & SFE_WANT_NEW_SURFACE) != 0;
+    bool wantImageSurface = (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) != 0;
+    bool premultAlpha = (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA) == 0;
+
+    if (!premultAlpha) {
+      forceCopy = true;
+      wantImageSurface = true;
+    }
+
+    nsRefPtr<gfxASurface> framesurf;
+    rv = imgContainer->GetFrame(whichFrame,
+                                frameFlags,
+                                getter_AddRefs(framesurf));
+    if (NS_FAILED(rv))
+      return result;
+
+    if (wantImageSurface && framesurf->GetType() != gfxASurface::SurfaceTypeImage) {
+      forceCopy = true;
     }
 
-    nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
-
-    ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
-    ctx->SetSource(framesurf);
-    ctx->Paint();
+    nsRefPtr<gfxASurface> gfxsurf = framesurf;
+    if (forceCopy) {
+      if (wantImageSurface) {
+        gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
+      } else {
+        gfxsurf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(imgWidth, imgHeight),
+                                                                     gfxASurface::CONTENT_COLOR_ALPHA);
+      }
+
+      nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
+
+      ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+      ctx->SetSource(framesurf);
+      ctx->Paint();
+    }
+    result.mSurface = gfxsurf;
+  }
+  else {
+    result.mDrawInfo.mImgContainer = imgContainer;
+    result.mDrawInfo.mWhichFrame = whichFrame;
+    result.mDrawInfo.mDrawingFlags = frameFlags;
   }
 
   int32_t corsmode;
   if (NS_SUCCEEDED(imgRequest->GetCORSMode(&corsmode))) {
     result.mCORSUsed = (corsmode != imgIRequest::CORS_NONE);
   }
 
-  result.mSurface = gfxsurf;
   result.mSize = gfxIntSize(imgWidth, imgHeight);
   result.mPrincipal = principal.forget();
   // no images, including SVG images, can load content from another domain.
   result.mIsWriteOnly = false;
   result.mImageRequest = imgRequest.forget();
 
   return result;
 }
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1469,26 +1469,40 @@ public:
     /* Whether to extract the first frame (as opposed to the
        current frame) in the case that the element is an image. */
     SFE_WANT_FIRST_FRAME = 1 << 2,
     /* Whether we should skip colorspace/gamma conversion */
     SFE_NO_COLORSPACE_CONVERSION = 1 << 3,
     /* Whether we should skip premultiplication -- the resulting
        image will always be an image surface, and must not be given to
        Thebes for compositing! */
-    SFE_NO_PREMULTIPLY_ALPHA = 1 << 4
+    SFE_NO_PREMULTIPLY_ALPHA = 1 << 4,
+    /* Whether we should skip getting a surface for vector images and
+       return a DirectDrawInfo containing an imgIContainer instead. */
+    SFE_NO_RASTERIZING_VECTORS = 1 << 5
+  };
+
+  struct DirectDrawInfo {
+    /* imgIContainer to directly draw to a context */
+    nsCOMPtr<imgIContainer> mImgContainer;
+    /* which frame to draw */
+    uint32_t mWhichFrame;
+    /* imgIContainer flags to use when drawing */
+    uint32_t mDrawingFlags;
   };
 
   struct SurfaceFromElementResult {
     SurfaceFromElementResult() :
       // Use safe default values here
       mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false) {}
 
     /* mSurface will contain the resulting surface, or will be NULL on error */
     nsRefPtr<gfxASurface> mSurface;
+    /* Contains info for drawing when there is no mSurface. */
+    DirectDrawInfo mDrawInfo;
     /* The size of the surface */
     gfxIntSize mSize;
     /* The principal associated with the element whose surface was returned.
        If there is a surface, this will never be null. */
     nsCOMPtr<nsIPrincipal> mPrincipal;
     /* The image request, if the element is an nsIImageLoadingContent */
     nsCOMPtr<imgIRequest> mImageRequest;
     /* Whether the element was "write only", that is, the bits should not be exposed to content */