Bug 1201796 (Part 3) - Enable downscale-during-decode for imgITools::EncodeScaledImage(). r=tn
☠☠ backed out by 577c248da8de ☠ ☠
authorSeth Fowler <mark.seth.fowler@gmail.com>
Sat, 19 Sep 2015 13:34:12 -0700
changeset 296035 3685c9cadbed8c7c7460a8df12f07a08868421de
parent 296034 7f20c039c994ae7c3d49ee1a3765c89fd349d462
child 296036 c5f5f19feef1a2339a85f2acab0a900239011619
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [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{