Bug 1119774 (Part 2) - Add RequestDecodeForSize to imgIContainer. r=tn
authorSeth Fowler <seth@mozilla.com>
Sun, 18 Jan 2015 14:02:13 -0800
changeset 224460 3ce28cb70ece9bc9677664817905cebee4a83dac
parent 224459 d77230596cb5c3e096f438858b2e4f62f43f6f37
child 224461 08965492c7703dd9e76b746a049cca434044ee82
push id28131
push usercbook@mozilla.com
push dateMon, 19 Jan 2015 15:10:25 +0000
treeherdermozilla-central@f8e4fdb89a05 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1119774
milestone38.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 1119774 (Part 2) - Add RequestDecodeForSize to imgIContainer. r=tn
image/public/imgIContainer.idl
image/src/DynamicImage.cpp
image/src/ImageWrapper.cpp
image/src/RasterImage.cpp
image/src/VectorImage.cpp
--- a/image/public/imgIContainer.idl
+++ b/image/public/imgIContainer.idl
@@ -64,17 +64,17 @@ native nsIntSizeByVal(nsIntSize);
 
 /**
  * imgIContainer is the interface that represents an image. It allows
  * access to frames as Thebes surfaces. It also allows drawing of images
  * onto Thebes contexts.
  *
  * Internally, imgIContainer also manages animation of images.
  */
-[scriptable, builtinclass, uuid(14ea6fa5-183e-4409-ac88-110bd2e05292)]
+[scriptable, builtinclass, uuid(4adb4c92-284d-4f5a-85e7-e924ec57510f)]
 interface imgIContainer : nsISupports
 {
   /**
    * The width of the container rectangle.  In the case of any error,
    * zero is returned, and an exception will be thrown.
    */
   readonly attribute int32_t width;
 
@@ -340,22 +340,38 @@ interface imgIContainer : nsISupports
    * the image will at some point fire off decode notifications. Calling draw()
    * or getFrame() triggers the same mechanism internally. Thus, if you want to
    * be sure that the image will be decoded but don't want to access it until
    * then, you must call requestDecode().
    */
   void requestDecode();
 
   /*
-   * This is equivalent to requestDecode() but it also decodes some of the
-   * image.
+   * This is equivalent to requestDecode() but it also synchronously decodes
+   * images that can be decoded "quickly" according to some heuristic.
    */
   [noscript] void startDecoding();
 
   /*
+   * This method is equivalent to requestDecode(), but enables the caller to
+   * provide more detailed information about the decode request.
+   *
+   * @param aSize The size to which the image should be scaled while decoding,
+   *              if possible. If the image cannot be scaled to this size while
+   *              being decoded, it will be decoded at its intrinsic size.
+   * @param aFlags Flags of the FLAG_* variety. Only the decode flags
+   *               (FLAG_DECODE_*) and FLAG_SYNC_DECODE (which will
+   *               synchronously decode images that can be decoded "quickly",
+   *               just like startDecoding() does) are accepted; others will be
+   *               ignored.
+   */
+  [noscript] void requestDecodeForSize([const] in nsIntSize aSize,
+                                       in uint32_t aFlags);
+
+  /*
    * Returns true if no more decoding can be performed on this image. Images
    * with errors return true since they cannot be decoded any further. Note that
    * because decoded images may be discarded, isDecoded() may return false even
    * if it has returned true in the past.
    */
   [noscript, notxpcom, nostdcall] bool isDecoded();
 
   /**
--- a/image/src/DynamicImage.cpp
+++ b/image/src/DynamicImage.cpp
@@ -250,16 +250,22 @@ DynamicImage::RequestDecode()
 }
 
 NS_IMETHODIMP
 DynamicImage::StartDecoding()
 {
   return NS_OK;
 }
 
+NS_IMETHODIMP
+DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
+{
+  return NS_OK;
+}
+
 bool
 DynamicImage::IsDecoded()
 {
   return true;
 }
 
 NS_IMETHODIMP
 DynamicImage::LockImage()
--- a/image/src/ImageWrapper.cpp
+++ b/image/src/ImageWrapper.cpp
@@ -219,16 +219,22 @@ ImageWrapper::RequestDecode()
 }
 
 NS_IMETHODIMP
 ImageWrapper::StartDecoding()
 {
   return mInnerImage->StartDecoding();
 }
 
+NS_IMETHODIMP
+ImageWrapper::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
+{
+  return mInnerImage->RequestDecodeForSize(aSize, aFlags);
+}
+
 bool
 ImageWrapper::IsDecoded()
 {
   return mInnerImage->IsDecoded();
 }
 
 NS_IMETHODIMP
 ImageWrapper::LockImage()
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -310,17 +310,17 @@ RasterImage::Init(const char* aMimeType,
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG_POINTER(aMimeType);
 
   // We must be non-discardable and non-decode-on-draw for
   // transient images.
   MOZ_ASSERT(!(aFlags & INIT_FLAG_TRANSIENT) ||
                (!(aFlags & INIT_FLAG_DISCARDABLE) &&
-                !(aFlags & INIT_FLAG_DECODE_ON_DRAW),
+                !(aFlags & INIT_FLAG_DECODE_ON_DRAW) &&
                 !(aFlags & INIT_FLAG_DOWNSCALE_DURING_DECODE)),
              "Illegal init flags for transient image");
 
   // Store initialization data
   mSourceDataMimeType.Assign(aMimeType);
   mDiscardable = !!(aFlags & INIT_FLAG_DISCARDABLE);
   mDecodeOnDraw = !!(aFlags & INIT_FLAG_DECODE_ON_DRAW);
   mTransient = !!(aFlags & INIT_FLAG_TRANSIENT);
@@ -1364,59 +1364,60 @@ RasterImage::WantDecodedFrames(uint32_t 
   Decode(DecodeStrategy::ASYNC, aFlags);
 }
 
 //******************************************************************************
 /* void requestDecode() */
 NS_IMETHODIMP
 RasterImage::RequestDecode()
 {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mError) {
-    return NS_ERROR_FAILURE;
-  }
-  if (!mHasSize) {
-    mWantFullDecode = true;
-    return NS_OK;
-  }
-
-  // Look up the first frame of the image, which will implicitly start decoding
-  // if it's not available right now.
-  // XXX(seth): Passing false for aShouldSyncNotify here has the effect of
-  // decoding asynchronously, but that's not obvious from the argument name.
-  // This API needs to be reworked.
-  LookupFrame(0, mSize, DECODE_FLAGS_DEFAULT, /* aShouldSyncNotify = */ false);
-
-  return NS_OK;
+  return RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT);
 }
 
 /* void startDecode() */
 NS_IMETHODIMP
 RasterImage::StartDecoding()
 {
   if (!NS_IsMainThread()) {
     return NS_DispatchToMainThread(
       NS_NewRunnableMethod(this, &RasterImage::StartDecoding));
   }
 
+  return RequestDecodeForSize(mSize, FLAG_SYNC_DECODE);
+}
+
+NS_IMETHODIMP
+RasterImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
   if (mError) {
     return NS_ERROR_FAILURE;
   }
+
   if (!mHasSize) {
     mWantFullDecode = true;
     return NS_OK;
   }
 
+  // Fall back to our intrinsic size if we don't support
+  // downscale-during-decode.
+  nsIntSize targetSize = mDownscaleDuringDecode ? aSize : mSize;
+
+  // Sync decode small images if requested.
+  bool shouldSyncDecodeSmallImages = aFlags & FLAG_SYNC_DECODE;
+
   // Look up the first frame of the image, which will implicitly start decoding
   // if it's not available right now.
   // XXX(seth): Passing true for aShouldSyncNotify here has the effect of
-  // synchronously decoding small images, but that's not obvious from the
-  // argument name. This API needs to be reworked.
-  LookupFrame(0, mSize, DECODE_FLAGS_DEFAULT, /* aShouldSyncNotify = */ true);
+  // synchronously decoding small images, while passing false has the effect of
+  // decoding asynchronously, but that's not obvious from the argument name.
+  // This API needs to be reworked.
+  LookupFrame(0, targetSize, DecodeFlags(aFlags),
+              /* aShouldSyncNotify = */ shouldSyncDecodeSmallImages);
 
   return NS_OK;
 }
 
 bool
 RasterImage::IsDecoded()
 {
   // XXX(seth): We need to get rid of this; it's not reliable.
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -894,16 +894,25 @@ VectorImage::RequestDecode()
 
 NS_IMETHODIMP
 VectorImage::StartDecoding()
 {
   // Nothing to do for SVG images
   return NS_OK;
 }
 
+NS_IMETHODIMP
+VectorImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
+{
+  // Nothing to do for SVG images, though in theory we could rasterize to the
+  // provided size ahead of time if we supported off-main-thread SVG
+  // rasterization...
+  return NS_OK;
+}
+
 bool
 VectorImage::IsDecoded()
 {
   return mIsFullyLoaded || mError;
 }
 
 //******************************************************************************
 /* void lockImage() */