Bug 1201796 (Part 3) - Enable downscale-during-decode for imgITools::EncodeScaledImage(). r=tn
☠☠ backed out by 9244da13f5e8 ☠ ☠
authorSeth Fowler <mark.seth.fowler@gmail.com>
Fri, 18 Sep 2015 10:54:38 -0700
changeset 263317 9589882189767a704768a6a08a6f4e029647d629
parent 263316 494e7553d6419f9dc7be7003a2448eb508469691
child 263318 159d5d2946d35063ea553e6f9cc081db547f7985
push id29395
push userphilringnalda@gmail.com
push dateSat, 19 Sep 2015 04:34:52 +0000
treeherdermozilla-central@9f7b7ab7dc1f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1201796
milestone43.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 1201796 (Part 3) - Enable downscale-during-decode for imgITools::EncodeScaledImage(). r=tn
image/ImageFactory.cpp
image/imgTools.cpp
image/test/unit/image1png16x16.jpg
image/test/unit/image2jpg16x16.png
image/test/unit/test_imgtools.js
toolkit/components/places/tests/favicons/expected-favicon-big32.jpg.png
toolkit/components/places/tests/favicons/expected-favicon-big64.png.png
--- a/image/ImageFactory.cpp
+++ b/image/ImageFactory.cpp
@@ -137,17 +137,23 @@ ImageFactory::CreateAnonymousImage(const
   nsresult rv;
 
   nsRefPtr<RasterImage> newImage = new RasterImage();
 
   nsRefPtr<ProgressTracker> newTracker = new ProgressTracker();
   newTracker->SetImage(newImage);
   newImage->SetProgressTracker(newTracker);
 
-  rv = newImage->Init(aMimeType.get(), Image::INIT_FLAG_SYNC_LOAD);
+  uint32_t imageFlags = Image::INIT_FLAG_SYNC_LOAD;
+  if (gfxPrefs::ImageDownscaleDuringDecodeEnabled() &&
+      ShouldDownscaleDuringDecode(aMimeType)) {
+    imageFlags |= Image::INIT_FLAG_DOWNSCALE_DURING_DECODE;
+  }
+
+  rv = newImage->Init(aMimeType.get(), imageFlags);
   if (NS_FAILED(rv)) {
     return BadImage("RasterImage::Init failed", newImage);
   }
 
   return newImage.forget();
 }
 
 /* static */ already_AddRefed<MultipartImage>
--- a/image/imgTools.cpp
+++ b/image/imgTools.cpp
@@ -193,36 +193,37 @@ imgTools::EncodeScaledImage(imgIContaine
   NS_ENSURE_ARG(aScaledWidth >= 0 && aScaledHeight >= 0);
 
   // If no scaled size is specified, we'll just encode the image at its
   // original size (no scaling).
   if (aScaledWidth == 0 && aScaledHeight == 0) {
     return EncodeImage(aContainer, aMimeType, aOutputOptions, aStream);
   }
 
-  // Use frame 0 from the image container.
-  RefPtr<SourceSurface> frame =
-    aContainer->GetFrame(imgIContainer::FRAME_FIRST,
-                         imgIContainer::FLAG_SYNC_DECODE);
-  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
-
-  int32_t frameWidth = frame->GetSize().width;
-  int32_t frameHeight = frame->GetSize().height;
+  // Retrieve the image's size.
+  int32_t imageWidth = 0;
+  int32_t imageHeight = 0;
+  aContainer->GetWidth(&imageWidth);
+  aContainer->GetHeight(&imageHeight);
 
   // If the given width or height is zero we'll replace it with the image's
   // original dimensions.
-  if (aScaledWidth == 0) {
-    aScaledWidth = frameWidth;
-  } else if (aScaledHeight == 0) {
-    aScaledHeight = frameHeight;
-  }
+  IntSize scaledSize(aScaledWidth == 0 ? imageWidth : aScaledWidth,
+                     aScaledHeight == 0 ? imageHeight : aScaledHeight);
+
+  // Use frame 0 from the image container.
+  RefPtr<SourceSurface> frame =
+    aContainer->GetFrameAtSize(scaledSize,
+                               imgIContainer::FRAME_FIRST,
+                               imgIContainer::FLAG_HIGH_QUALITY_SCALING |
+                               imgIContainer::FLAG_SYNC_DECODE);
+  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   RefPtr<DataSourceSurface> dataSurface =
-    Factory::CreateDataSourceSurface(IntSize(aScaledWidth, aScaledHeight),
-                                     SurfaceFormat::B8G8R8A8);
+    Factory::CreateDataSourceSurface(scaledSize, SurfaceFormat::B8G8R8A8);
   if (NS_WARN_IF(!dataSurface)) {
     return NS_ERROR_FAILURE;
   }
 
   DataSourceSurface::MappedSurface map;
   if (!dataSurface->Map(DataSourceSurface::MapType::WRITE, &map)) {
     return NS_ERROR_FAILURE;
   }
@@ -233,19 +234,20 @@ imgTools::EncodeScaledImage(imgIContaine
                                      dataSurface->GetSize(),
                                      map.mStride,
                                      SurfaceFormat::B8G8R8A8);
   if (!dt) {
     gfxWarning() << "imgTools::EncodeImage failed in CreateDrawTargetForData";
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
+  IntSize frameSize = frame->GetSize();
   dt->DrawSurface(frame,
-                  Rect(0, 0, aScaledWidth, aScaledHeight),
-                  Rect(0, 0, frameWidth, frameHeight),
+                  Rect(0, 0, scaledSize.width, scaledSize.height),
+                  Rect(0, 0, frameSize.width, frameSize.height),
                   DrawSurfaceOptions(),
                   DrawOptions(1.0f, CompositionOp::OP_SOURCE));
 
   dataSurface->Unmap();
 
   return EncodeImageData(dataSurface, aMimeType, aOutputOptions, aStream);
 }
 
index 645bc114c8de46cc0a4f6afb02c190f3aea9c7a3..ea14dbedede96973213586f1754a29c774e72993
GIT binary patch
literal 1051
zc%1ux<NpH&0WUXCHwH#V1_nkTWcYuZ!I^=X2?RhSGZ3(_v48*v8yhPdCkGc7CkH1d
z7Y{!V7dIa_Cnv8UFCV{vfS>>ukC3pCfH06P05XITq?4J21E^7eo0D6BWbpq0gCGZk
z0D}NCqaXv5AS1IN<NqTJ@<4a8GJ*jE6fiO|v#_$Ub8vET0~Kr)U|<5;&BVgY%F4n5
zl&uBIGq4D<3Mm>ovIz$!vMUve7&T5@$f4}C@t|nX#SbdRNkvVZTw>x9l2WQ_>Kd9_
zCZ=ZQ7M51dF0O9w9-dyoA)#U65s^{JDXD4c8JStdC8cHM6_r)ZEv;?s9i3g1CQq3<
zZTgIvvlcC0vUJ(<6)RV5+Pr1!w(UE1?mBe%$kAiRPn<k;>GGAU*RJ2VdF$b$$4{O<
zd;a3(tB;>PfBE|D`;VW$K>lK6U}l5?to{N90wWU(Fi6=!{$gY*2PqI_VO2C_6LJh>
zPb?HxGHT=yahkYr<3Ubk<Dd_sNktdA#8gZks(u7{4eT@GJk~^(&)^<I`0Ew}4>Kb$
z@|Xn~>={1iH`p`%6R)w_c%jDekv+%DsOug2YjX4S7F~_Ap0TL5@&22SJ8pU2S-8XE
zISbcMKDoy|ar)-}PA_Z=?w&K<D(*jn-b&rt8%w?x-Cb+G@vDsgfgd$yZlAMetPGlx
zdGyo%=9xG5w-%q=x+Hm1)n2`@AJacLKbU`9`@T$c1+&xEi+chWW?nb{__v9F<CGm+
zdrqnpML$1Xp~4y(>$Gdfx!5A@mo=_O9$Dl?<lGF6I~A(zRdOq8W!&YSsY}mFXNy;C
z-8%DwjBwbpRIduHFZYeQ=cJeYTC(8Ut?i3n6xegsXV`O8Og<!)*7>OW`K3L+OK+}i
z%93*_X6v<koin-Z9NPoSbN-?~w;8LPHPSg3@n&1lx1!uzMpI;$esrH@wO)PYU&+bO
zB=g0dax-^Lwa=QgCre|0m6hgEuT!zNc4gkpP5b3pr(a|CgZIPlM`}Bl|M*jJ{E_()
zZR6$9TMAX&Zdh%SoU8m((c|Kc)^jgq)-#68>N)z{rg&Duhp!*bP2=X)tFQCRJ(;s}
w>3hGZ{8Wjxv3Dna__>am@z9r5!G}YG*9ZN%vuBm2ZO&p@<#qd;KK;K50H9=^rvLx|
index c3a4aee616675d212178f70a97d8ce73fc1813e2..5722223c26fe0024d8c4d18f198114d5fde708bb
GIT binary patch
literal 950
zc$@*Y14;aeP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV000AhNkl<ZIE_Wq
zeJq>@0LSr1x`a;5GDT;MVN#7Q+G@9E>!LFx#7w1~R@tVV5e<5mb0OH`Z5gEtr4tps
zSrf0-Rp*9zxeMFHxC*5l*K^hz(TrtMnz`rs?vLBc@84hY{qG|nfh2)wwes&KjVm<u
z>S!7mqpoL^Z~Al?mRA1zMXQJ;NdO3vB(Y=t3jo9FAIO_DeAF<4;?^%T=uMPs=SXkX
zl9*G@SCy4KURkt7B#<Nt0m;gSK}+YiHwa0)!l@cH)%_!U-aSa;;wm+>tH{;&$-G=m
zbNRdcI+VcLd>f*58%Y8|+Sz38S{mPF9HXK5B0Y6k+$nvJ&sti^8=d3)?VrfkEs?J3
zAu=wEf%fC9PegLBuLN=DDZ<Y7I{M;BmJ9q@E(*e^^riP>PpZn56m)iTX?Pmh=mOb&
zGrUvS%t?6$lbr{6qz+|mc?@A=L4%?A2n&~7Sjck2l)aaki!Y-oileYBpAS@O!fU=~
zUq&@&R6mn)t&5h+NBLdzI_Bwmgh%Q!X7l`bD05>;;l;AThsBb&sI5?vdi^%hHFtS7
zA_w763ddwBqU2Q!wS*%YV;S!{jbK(~GNbTfDaV7kPd({)+l7*I;e1k7PkikF3H4e6
z&s8A!ox(9Nk<gd~rn?SfHHR^I^8~^~VIotR9$0dH=nr+G(cg}ur1wcwT;Xi)Rb&;{
ziAentJNF0#hY(7YXV~fwU{n7JGe2BF7_H1@;{1zPa=e&2?aXA<F7BniN>5fOL&`8T
z#c?FX#Uj`R;piAdM|}c}1o3#}4W>q`5KP*B24h~rBKO3U?S?tknTdF3s$X*?C)kri
zu6_u@UUm!K$YO$-Z4Kn<*g@9jlbO_YAc)&r+&LS;_{rz6D7`Vs+*nq4qE7N6C3qii
z`b2QlBZ!LV{Ve4BVs3PRwJ7wO1lCp_AOM($e?%3qo9SqGj2C>EPj%zBJbxY*9OOan
z5e)eum~;J@&9-A}+!v$nFuH-OfP`SRiU8>AYpHvF7hNs_gFg059CzV<tSiQ3cT8z7
zuqd}@y>$<UyWaHPOlN!RPn!iv6cPW4%(S)8cwj#_oE&I&dWIHPdu|2T({o}s+Vnm2
ze-Xl9TPaUAH*BCp(WX%pMMTjSd1A4k`?`+qlw{hY!fB6>pj+`F!_8Hg=k))R7Hy>e
Y1{)a08Fp#&*8l(j07*qoM6N<$f@Rjr9RL6T
--- a/image/test/unit/test_imgtools.js
+++ b/image/test/unit/test_imgtools.js
@@ -164,17 +164,17 @@ testdesc = "test encoding a scaled JPEG"
 // we'll reuse the container from the previous test
 istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 16);
 
 var encodedBytes = streamToArray(istream);
 // Get bytes for exected result
 var refName = "image1png16x16.jpg";
 var refFile = do_get_file(refName);
 istream = getFileInputStream(refFile);
-do_check_eq(istream.available(), 1078);
+do_check_eq(istream.available(), 1051);
 var referenceBytes = streamToArray(istream);
 
 // compare the encoder's output to the reference file.
 compareArrays(encodedBytes, referenceBytes);
 
 
 /* ========== 3 ========== */
 testnum++;
@@ -223,17 +223,17 @@ if (!isWindows) {
 // we'll reuse the container from the previous test
 istream = imgTools.encodeScaledImage(container, "image/png", 16, 16);
 
 encodedBytes = streamToArray(istream);
 // Get bytes for exected result
 refName = isWindows ? "image2jpg16x16-win.png" : "image2jpg16x16.png";
 refFile = do_get_file(refName);
 istream = getFileInputStream(refFile);
-do_check_eq(istream.available(), 948);
+do_check_eq(istream.available(), 950);
 referenceBytes = streamToArray(istream);
 
 // compare the encoder's output to the reference file.
 compareArrays(encodedBytes, referenceBytes);
 }
 
 
 /* ========== 6 ========== */
index c3a4aee616675d212178f70a97d8ce73fc1813e2..5722223c26fe0024d8c4d18f198114d5fde708bb
GIT binary patch
literal 950
zc$@*Y14;aeP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV000AhNkl<ZIE_Wq
zeJq>@0LSr1x`a;5GDT;MVN#7Q+G@9E>!LFx#7w1~R@tVV5e<5mb0OH`Z5gEtr4tps
zSrf0-Rp*9zxeMFHxC*5l*K^hz(TrtMnz`rs?vLBc@84hY{qG|nfh2)wwes&KjVm<u
z>S!7mqpoL^Z~Al?mRA1zMXQJ;NdO3vB(Y=t3jo9FAIO_DeAF<4;?^%T=uMPs=SXkX
zl9*G@SCy4KURkt7B#<Nt0m;gSK}+YiHwa0)!l@cH)%_!U-aSa;;wm+>tH{;&$-G=m
zbNRdcI+VcLd>f*58%Y8|+Sz38S{mPF9HXK5B0Y6k+$nvJ&sti^8=d3)?VrfkEs?J3
zAu=wEf%fC9PegLBuLN=DDZ<Y7I{M;BmJ9q@E(*e^^riP>PpZn56m)iTX?Pmh=mOb&
zGrUvS%t?6$lbr{6qz+|mc?@A=L4%?A2n&~7Sjck2l)aaki!Y-oileYBpAS@O!fU=~
zUq&@&R6mn)t&5h+NBLdzI_Bwmgh%Q!X7l`bD05>;;l;AThsBb&sI5?vdi^%hHFtS7
zA_w763ddwBqU2Q!wS*%YV;S!{jbK(~GNbTfDaV7kPd({)+l7*I;e1k7PkikF3H4e6
z&s8A!ox(9Nk<gd~rn?SfHHR^I^8~^~VIotR9$0dH=nr+G(cg}ur1wcwT;Xi)Rb&;{
ziAentJNF0#hY(7YXV~fwU{n7JGe2BF7_H1@;{1zPa=e&2?aXA<F7BniN>5fOL&`8T
z#c?FX#Uj`R;piAdM|}c}1o3#}4W>q`5KP*B24h~rBKO3U?S?tknTdF3s$X*?C)kri
zu6_u@UUm!K$YO$-Z4Kn<*g@9jlbO_YAc)&r+&LS;_{rz6D7`Vs+*nq4qE7N6C3qii
z`b2QlBZ!LV{Ve4BVs3PRwJ7wO1lCp_AOM($e?%3qo9SqGj2C>EPj%zBJbxY*9OOan
z5e)eum~;J@&9-A}+!v$nFuH-OfP`SRiU8>AYpHvF7hNs_gFg059CzV<tSiQ3cT8z7
zuqd}@y>$<UyWaHPOlN!RPn!iv6cPW4%(S)8cwj#_oE&I&dWIHPdu|2T({o}s+Vnm2
ze-Xl9TPaUAH*BCp(WX%pMMTjSd1A4k`?`+qlw{hY!fB6>pj+`F!_8Hg=k))R7Hy>e
Y1{)a08Fp#&*8l(j07*qoM6N<$f@Rjr9RL6T
index 03a01c6de84a633c5a4a73a9b0187d92f4ba9125..238973189040030ed5071fb3f9ed8c141a802211
GIT binary patch
literal 979
zc$@*#11$WBP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV000A;Nkl<ZIE`(S
ze@xT`7{=d&lH(2p<TwsEMgktKACqh-LqkJQkU(KxwMZ~vw*wt=$FC4XKr%(N0;Eis
zjp4{i1VK<JAi0x}DHM9jj|2ky0WA2Z0`B{LpZ;*NSv`Ng&)(0TKc0t(h(ILKYPHt1
zBAt&*%!S0z!nTqZ(wdJ_*!j1K&Uid_QAk$we^U5myQ}q=Yocm~77SOW@%hj5sJt@=
z{TFu-k#>4!Q{dh*A}5FcKqfy6jz16;QADu~V-c;hIM>;Q(#95{X7pF#<GWKrTHA<_
z`(Zgu)$6g)={eG*SMDSt0!Z=*pm)7$F4}=lP8Fc5BH3ap@@IY1RW|fZ^E*wqIk$hD
zb+w&hSlI5R!S;1nGC#9amEx4MlHlh4H8=k}?j_9Usg~z5<>*Op<&$Oaabe?^IB?yJ
zj2mW7yLOj@3R-xpvC=Zqwgw9=UW?kexaX)V-EZ^MF`vcp423wB?k<iQJ$NKl&A(^7
zjMGJ_h^+q}VdbsRq*ifU-8IBi_i{r?xPTijsQlC`k%mhA&;Ieg4}LNzEt6Slp3L#U
zU&Wp{{!uX^>-rE~(F$ou4rqNcHfLVoAj4(uy|hih>?_=Sf*R@8p>_2$`5rux<tE%u
zapUGdIgZBdM8b)4h^gv<_Phyx`$|DRdm(@JO>B%b^8IFwh}lhi`-H;)b#HV2>bGn+
zewe4Wd=qTP4W0x;QWApluOKR~9tY3VVXM9Z*2?W5+YppyzQyQ}2^e3+*UxTjr+P10
z@l>i3lkd7)hF)LIqdSNnB&|kwdI0VjHJB*yMv`_HBvvniY+mC_)hQx+?7#zCP+J~V
zMu+I>fd1|F%TtGy;)FpZPU-A17;Dd!&)Xu)-y6P)mq4@@Bnf0=cqqo2Y?=FgdH%sZ
z%bpOI2qGfMMdznF9ws<q{IKitc$PCy=eTftyoz^kcoqI@b?{eh;SYBC@?4%1&sNx3
zAV$N~YTrjhG6In#jws+;mDS>Kj6yW)+$<w{C!RT?;DsX!p3L>;U-C6Pm+j7@I%|vN
zp0hCXqbuInK(PQx2=u6qMxw;8WdxH_jxM!K><xAiZtZaw&HGj2aH>)m$&ibGw_9P>
zWR1LVI`%}BA43v|qN|C1Xp^r(x1Ai{IoqRGBga6f6oUtC(2;37oS>2Eo_JoFD6JeE
z<E4~b>>#~(%2C==s*-jU`blfG-Zm*jr2h93{{ijx-bOEr5BmTB002ovPDHLkV1jWC
B;Kcv{