Bug 1201796 (Part 3) - Enable downscale-during-decode for imgITools::EncodeScaledImage(). r=tn
authorSeth Fowler <mark.seth.fowler@gmail.com>
Sat, 19 Sep 2015 13:34:12 -0700
changeset 263436 3685c9cadbed8c7c7460a8df12f07a08868421de
parent 263435 7f20c039c994ae7c3d49ee1a3765c89fd349d462
child 263437 c5f5f19feef1a2339a85f2acab0a900239011619
push id15264
push userphilringnalda@gmail.com
push dateSun, 20 Sep 2015 04:09:18 +0000
treeherderfx-team@ccd6b5f5e544 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1201796
milestone43.0a1
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{