RasterImage.cpp 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. * This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. // Must #include ImageLogging.h before any IPDL-generated files or other files
  6. // that #include prlog.h
  7. #include "ImageLogging.h"
  8. #include "RasterImage.h"
  9. #include "gfxPlatform.h"
  10. #include "nsComponentManagerUtils.h"
  11. #include "nsError.h"
  12. #include "Decoder.h"
  13. #include "prenv.h"
  14. #include "prsystem.h"
  15. #include "IDecodingTask.h"
  16. #include "ImageContainer.h"
  17. #include "ImageRegion.h"
  18. #include "Layers.h"
  19. #include "LookupResult.h"
  20. #include "nsIConsoleService.h"
  21. #include "nsIInputStream.h"
  22. #include "nsIScriptError.h"
  23. #include "nsISupportsPrimitives.h"
  24. #include "nsPresContext.h"
  25. #include "SourceBuffer.h"
  26. #include "SurfaceCache.h"
  27. #include "FrameAnimator.h"
  28. #include "gfxContext.h"
  29. #include "mozilla/gfx/2D.h"
  30. #include "mozilla/DebugOnly.h"
  31. #include "mozilla/Likely.h"
  32. #include "mozilla/RefPtr.h"
  33. #include "mozilla/Move.h"
  34. #include "mozilla/MemoryReporting.h"
  35. #include "mozilla/Services.h"
  36. #include <stdint.h>
  37. #include "mozilla/TimeStamp.h"
  38. #include "mozilla/Telemetry.h"
  39. #include "mozilla/Tuple.h"
  40. #include "mozilla/ClearOnShutdown.h"
  41. #include "mozilla/gfx/Scale.h"
  42. #include "GeckoProfiler.h"
  43. #include "gfx2DGlue.h"
  44. #include "gfxPrefs.h"
  45. #include <algorithm>
  46. namespace mozilla {
  47. using namespace gfx;
  48. using namespace layers;
  49. namespace image {
  50. using std::ceil;
  51. using std::min;
  52. #ifndef DEBUG
  53. NS_IMPL_ISUPPORTS(RasterImage, imgIContainer, nsIProperties)
  54. #else
  55. NS_IMPL_ISUPPORTS(RasterImage, imgIContainer, nsIProperties,
  56. imgIContainerDebug)
  57. #endif
  58. //******************************************************************************
  59. RasterImage::RasterImage(ImageURL* aURI /* = nullptr */) :
  60. ImageResource(aURI), // invoke superclass's constructor
  61. mSize(0,0),
  62. mLockCount(0),
  63. mDecodeCount(0),
  64. mRequestedSampleSize(0),
  65. mImageProducerID(ImageContainer::AllocateProducerID()),
  66. mLastFrameID(0),
  67. mLastImageContainerDrawResult(DrawResult::NOT_READY),
  68. #ifdef DEBUG
  69. mFramesNotified(0),
  70. #endif
  71. mSourceBuffer(WrapNotNull(new SourceBuffer())),
  72. mHasSize(false),
  73. mTransient(false),
  74. mSyncLoad(false),
  75. mDiscardable(false),
  76. mHasSourceData(false),
  77. mHasBeenDecoded(false),
  78. mPendingAnimation(false),
  79. mAnimationFinished(false),
  80. mWantFullDecode(false)
  81. {
  82. }
  83. //******************************************************************************
  84. RasterImage::~RasterImage()
  85. {
  86. // Make sure our SourceBuffer is marked as complete. This will ensure that any
  87. // outstanding decoders terminate.
  88. if (!mSourceBuffer->IsComplete()) {
  89. mSourceBuffer->Complete(NS_ERROR_ABORT);
  90. }
  91. // Release all frames from the surface cache.
  92. SurfaceCache::RemoveImage(ImageKey(this));
  93. }
  94. nsresult
  95. RasterImage::Init(const char* aMimeType,
  96. uint32_t aFlags)
  97. {
  98. // We don't support re-initialization
  99. if (mInitialized) {
  100. return NS_ERROR_ILLEGAL_VALUE;
  101. }
  102. // Not sure an error can happen before init, but be safe
  103. if (mError) {
  104. return NS_ERROR_FAILURE;
  105. }
  106. // We want to avoid redecodes for transient images.
  107. MOZ_ASSERT_IF(aFlags & INIT_FLAG_TRANSIENT,
  108. !(aFlags & INIT_FLAG_DISCARDABLE));
  109. // Store initialization data
  110. mDiscardable = !!(aFlags & INIT_FLAG_DISCARDABLE);
  111. mWantFullDecode = !!(aFlags & INIT_FLAG_DECODE_IMMEDIATELY);
  112. mTransient = !!(aFlags & INIT_FLAG_TRANSIENT);
  113. mSyncLoad = !!(aFlags & INIT_FLAG_SYNC_LOAD);
  114. // Use the MIME type to select a decoder type, and make sure there *is* a
  115. // decoder for this MIME type.
  116. NS_ENSURE_ARG_POINTER(aMimeType);
  117. mDecoderType = DecoderFactory::GetDecoderType(aMimeType);
  118. if (mDecoderType == DecoderType::UNKNOWN) {
  119. return NS_ERROR_FAILURE;
  120. }
  121. // Lock this image's surfaces in the SurfaceCache if we're not discardable.
  122. if (!mDiscardable) {
  123. mLockCount++;
  124. SurfaceCache::LockImage(ImageKey(this));
  125. }
  126. if (!mSyncLoad) {
  127. // Create an async metadata decoder and verify we succeed in doing so.
  128. nsresult rv = DecodeMetadata(DECODE_FLAGS_DEFAULT);
  129. if (NS_FAILED(rv)) {
  130. return NS_ERROR_FAILURE;
  131. }
  132. }
  133. // Mark us as initialized
  134. mInitialized = true;
  135. return NS_OK;
  136. }
  137. //******************************************************************************
  138. NS_IMETHODIMP_(void)
  139. RasterImage::RequestRefresh(const TimeStamp& aTime)
  140. {
  141. if (HadRecentRefresh(aTime)) {
  142. return;
  143. }
  144. EvaluateAnimation();
  145. if (!mAnimating) {
  146. return;
  147. }
  148. RefreshResult res;
  149. if (mAnimationState) {
  150. MOZ_ASSERT(mFrameAnimator);
  151. res = mFrameAnimator->RequestRefresh(*mAnimationState, aTime);
  152. }
  153. if (res.mFrameAdvanced) {
  154. // Notify listeners that our frame has actually changed, but do this only
  155. // once for all frames that we've now passed (if AdvanceFrame() was called
  156. // more than once).
  157. #ifdef DEBUG
  158. mFramesNotified++;
  159. #endif
  160. NotifyProgress(NoProgress, res.mDirtyRect);
  161. }
  162. if (res.mAnimationFinished) {
  163. mAnimationFinished = true;
  164. EvaluateAnimation();
  165. }
  166. }
  167. //******************************************************************************
  168. NS_IMETHODIMP
  169. RasterImage::GetWidth(int32_t* aWidth)
  170. {
  171. NS_ENSURE_ARG_POINTER(aWidth);
  172. if (mError) {
  173. *aWidth = 0;
  174. return NS_ERROR_FAILURE;
  175. }
  176. *aWidth = mSize.width;
  177. return NS_OK;
  178. }
  179. //******************************************************************************
  180. NS_IMETHODIMP
  181. RasterImage::GetHeight(int32_t* aHeight)
  182. {
  183. NS_ENSURE_ARG_POINTER(aHeight);
  184. if (mError) {
  185. *aHeight = 0;
  186. return NS_ERROR_FAILURE;
  187. }
  188. *aHeight = mSize.height;
  189. return NS_OK;
  190. }
  191. //******************************************************************************
  192. NS_IMETHODIMP
  193. RasterImage::GetIntrinsicSize(nsSize* aSize)
  194. {
  195. if (mError) {
  196. return NS_ERROR_FAILURE;
  197. }
  198. *aSize = nsSize(nsPresContext::CSSPixelsToAppUnits(mSize.width),
  199. nsPresContext::CSSPixelsToAppUnits(mSize.height));
  200. return NS_OK;
  201. }
  202. //******************************************************************************
  203. NS_IMETHODIMP
  204. RasterImage::GetIntrinsicRatio(AspectRatio* aRatio)
  205. {
  206. if (mError) {
  207. return NS_ERROR_FAILURE;
  208. }
  209. *aRatio = AspectRatio::FromSize(mSize);
  210. return NS_OK;
  211. }
  212. NS_IMETHODIMP_(Orientation)
  213. RasterImage::GetOrientation()
  214. {
  215. return mOrientation;
  216. }
  217. //******************************************************************************
  218. NS_IMETHODIMP
  219. RasterImage::GetType(uint16_t* aType)
  220. {
  221. NS_ENSURE_ARG_POINTER(aType);
  222. *aType = imgIContainer::TYPE_RASTER;
  223. return NS_OK;
  224. }
  225. LookupResult
  226. RasterImage::LookupFrameInternal(const IntSize& aSize,
  227. uint32_t aFlags,
  228. PlaybackType aPlaybackType)
  229. {
  230. if (mAnimationState && aPlaybackType == PlaybackType::eAnimated) {
  231. MOZ_ASSERT(mFrameAnimator);
  232. MOZ_ASSERT(ToSurfaceFlags(aFlags) == DefaultSurfaceFlags(),
  233. "Can't composite frames with non-default surface flags");
  234. const size_t index = mAnimationState->GetCurrentAnimationFrameIndex();
  235. return mFrameAnimator->GetCompositedFrame(index);
  236. }
  237. SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
  238. // We don't want any substitution for sync decodes, and substitution would be
  239. // illegal when high quality downscaling is disabled, so we use
  240. // SurfaceCache::Lookup in this case.
  241. if ((aFlags & FLAG_SYNC_DECODE) || !(aFlags & FLAG_HIGH_QUALITY_SCALING)) {
  242. return SurfaceCache::Lookup(ImageKey(this),
  243. RasterSurfaceKey(aSize,
  244. surfaceFlags,
  245. PlaybackType::eStatic));
  246. }
  247. // We'll return the best match we can find to the requested frame.
  248. return SurfaceCache::LookupBestMatch(ImageKey(this),
  249. RasterSurfaceKey(aSize,
  250. surfaceFlags,
  251. PlaybackType::eStatic));
  252. }
  253. DrawableSurface
  254. RasterImage::LookupFrame(const IntSize& aSize,
  255. uint32_t aFlags,
  256. PlaybackType aPlaybackType)
  257. {
  258. MOZ_ASSERT(NS_IsMainThread());
  259. // If we're opaque, we don't need to care about premultiplied alpha, because
  260. // that can only matter for frames with transparency.
  261. if (IsOpaque()) {
  262. aFlags &= ~FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
  263. }
  264. IntSize requestedSize = CanDownscaleDuringDecode(aSize, aFlags)
  265. ? aSize : mSize;
  266. if (requestedSize.IsEmpty()) {
  267. return DrawableSurface(); // Can't decode to a surface of zero size.
  268. }
  269. LookupResult result =
  270. LookupFrameInternal(requestedSize, aFlags, aPlaybackType);
  271. if (!result && !mHasSize) {
  272. // We can't request a decode without knowing our intrinsic size. Give up.
  273. return DrawableSurface();
  274. }
  275. if (result.Type() == MatchType::NOT_FOUND ||
  276. result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND ||
  277. ((aFlags & FLAG_SYNC_DECODE) && !result)) {
  278. // We don't have a copy of this frame, and there's no decoder working on
  279. // one. (Or we're sync decoding and the existing decoder hasn't even started
  280. // yet.) Trigger decoding so it'll be available next time.
  281. MOZ_ASSERT(aPlaybackType != PlaybackType::eAnimated ||
  282. !mAnimationState || mAnimationState->KnownFrameCount() < 1,
  283. "Animated frames should be locked");
  284. Decode(requestedSize, aFlags, aPlaybackType);
  285. // If we can sync decode, we should already have the frame.
  286. if (aFlags & FLAG_SYNC_DECODE) {
  287. result = LookupFrameInternal(requestedSize, aFlags, aPlaybackType);
  288. }
  289. }
  290. if (!result) {
  291. // We still weren't able to get a frame. Give up.
  292. return DrawableSurface();
  293. }
  294. if (result.Surface()->GetCompositingFailed()) {
  295. return DrawableSurface();
  296. }
  297. MOZ_ASSERT(!result.Surface()->GetIsPaletted(),
  298. "Should not have a paletted frame");
  299. // Sync decoding guarantees that we got the frame, but if it's owned by an
  300. // async decoder that's currently running, the contents of the frame may not
  301. // be available yet. Make sure we get everything.
  302. if (mHasSourceData && (aFlags & FLAG_SYNC_DECODE)) {
  303. result.Surface()->WaitUntilFinished();
  304. }
  305. // If we could have done some decoding in this function we need to check if
  306. // that decoding encountered an error and hence aborted the surface. We want
  307. // to avoid calling IsAborted if we weren't passed any sync decode flag because
  308. // IsAborted acquires the monitor for the imgFrame.
  309. if (aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST) &&
  310. result.Surface()->IsAborted()) {
  311. return DrawableSurface();
  312. }
  313. return Move(result.Surface());
  314. }
  315. bool
  316. RasterImage::IsOpaque()
  317. {
  318. if (mError) {
  319. return false;
  320. }
  321. Progress progress = mProgressTracker->GetProgress();
  322. // If we haven't yet finished decoding, the safe answer is "not opaque".
  323. if (!(progress & FLAG_DECODE_COMPLETE)) {
  324. return false;
  325. }
  326. // Other, we're opaque if FLAG_HAS_TRANSPARENCY is not set.
  327. return !(progress & FLAG_HAS_TRANSPARENCY);
  328. }
  329. NS_IMETHODIMP_(bool)
  330. RasterImage::WillDrawOpaqueNow()
  331. {
  332. if (!IsOpaque()) {
  333. return false;
  334. }
  335. if (mAnimationState) {
  336. // We never discard frames of animated images.
  337. return true;
  338. }
  339. // If we are not locked our decoded data could get discard at any time (ie
  340. // between the call to this function and when we are asked to draw), so we
  341. // have to return false if we are unlocked.
  342. if (IsUnlocked()) {
  343. return false;
  344. }
  345. LookupResult result =
  346. SurfaceCache::LookupBestMatch(ImageKey(this),
  347. RasterSurfaceKey(mSize,
  348. DefaultSurfaceFlags(),
  349. PlaybackType::eStatic));
  350. MatchType matchType = result.Type();
  351. if (matchType == MatchType::NOT_FOUND || matchType == MatchType::PENDING ||
  352. !result.Surface()->IsFinished()) {
  353. return false;
  354. }
  355. return true;
  356. }
  357. void
  358. RasterImage::OnSurfaceDiscarded()
  359. {
  360. MOZ_ASSERT(mProgressTracker);
  361. NS_DispatchToMainThread(NewRunnableMethod(mProgressTracker, &ProgressTracker::OnDiscard));
  362. }
  363. //******************************************************************************
  364. NS_IMETHODIMP
  365. RasterImage::GetAnimated(bool* aAnimated)
  366. {
  367. if (mError) {
  368. return NS_ERROR_FAILURE;
  369. }
  370. NS_ENSURE_ARG_POINTER(aAnimated);
  371. // If we have an AnimationState, we can know for sure.
  372. if (mAnimationState) {
  373. *aAnimated = true;
  374. return NS_OK;
  375. }
  376. // Otherwise, we need to have been decoded to know for sure, since if we were
  377. // decoded at least once mAnimationState would have been created for animated
  378. // images. This is true even though we check for animation during the
  379. // metadata decode, because we may still discover animation only during the
  380. // full decode for corrupt images.
  381. if (!mHasBeenDecoded) {
  382. return NS_ERROR_NOT_AVAILABLE;
  383. }
  384. // We know for sure
  385. *aAnimated = false;
  386. return NS_OK;
  387. }
  388. //******************************************************************************
  389. NS_IMETHODIMP_(int32_t)
  390. RasterImage::GetFirstFrameDelay()
  391. {
  392. if (mError) {
  393. return -1;
  394. }
  395. bool animated = false;
  396. if (NS_FAILED(GetAnimated(&animated)) || !animated) {
  397. return -1;
  398. }
  399. MOZ_ASSERT(mAnimationState, "Animated images should have an AnimationState");
  400. return mAnimationState->FirstFrameTimeout().AsEncodedValueDeprecated();
  401. }
  402. NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
  403. RasterImage::GetFrame(uint32_t aWhichFrame,
  404. uint32_t aFlags)
  405. {
  406. return GetFrameInternal(mSize, aWhichFrame, aFlags).second().forget();
  407. }
  408. NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
  409. RasterImage::GetFrameAtSize(const IntSize& aSize,
  410. uint32_t aWhichFrame,
  411. uint32_t aFlags)
  412. {
  413. return GetFrameInternal(aSize, aWhichFrame, aFlags).second().forget();
  414. }
  415. Pair<DrawResult, RefPtr<SourceSurface>>
  416. RasterImage::GetFrameInternal(const IntSize& aSize,
  417. uint32_t aWhichFrame,
  418. uint32_t aFlags)
  419. {
  420. MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
  421. if (aSize.IsEmpty()) {
  422. return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
  423. }
  424. if (aWhichFrame > FRAME_MAX_VALUE) {
  425. return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
  426. }
  427. if (mError) {
  428. return MakePair(DrawResult::BAD_IMAGE, RefPtr<SourceSurface>());
  429. }
  430. // Get the frame. If it's not there, it's probably the caller's fault for
  431. // not waiting for the data to be loaded from the network or not passing
  432. // FLAG_SYNC_DECODE.
  433. DrawableSurface surface =
  434. LookupFrame(aSize, aFlags, ToPlaybackType(aWhichFrame));
  435. if (!surface) {
  436. // The OS threw this frame away and we couldn't redecode it.
  437. return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
  438. }
  439. RefPtr<SourceSurface> sourceSurface = surface->GetSourceSurface();
  440. if (!surface->IsFinished()) {
  441. return MakePair(DrawResult::INCOMPLETE, Move(sourceSurface));
  442. }
  443. return MakePair(DrawResult::SUCCESS, Move(sourceSurface));
  444. }
  445. Pair<DrawResult, RefPtr<layers::Image>>
  446. RasterImage::GetCurrentImage(ImageContainer* aContainer, uint32_t aFlags)
  447. {
  448. MOZ_ASSERT(NS_IsMainThread());
  449. MOZ_ASSERT(aContainer);
  450. DrawResult drawResult;
  451. RefPtr<SourceSurface> surface;
  452. Tie(drawResult, surface) =
  453. GetFrameInternal(mSize, FRAME_CURRENT, aFlags | FLAG_ASYNC_NOTIFY);
  454. if (!surface) {
  455. // The OS threw out some or all of our buffer. We'll need to wait for the
  456. // redecode (which was automatically triggered by GetFrame) to complete.
  457. return MakePair(drawResult, RefPtr<layers::Image>());
  458. }
  459. RefPtr<layers::Image> image = new layers::SourceSurfaceImage(surface);
  460. return MakePair(drawResult, Move(image));
  461. }
  462. NS_IMETHODIMP_(bool)
  463. RasterImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
  464. {
  465. int32_t maxTextureSize = aManager->GetMaxTextureSize();
  466. if (!mHasSize ||
  467. mSize.width > maxTextureSize ||
  468. mSize.height > maxTextureSize) {
  469. return false;
  470. }
  471. return true;
  472. }
  473. NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
  474. RasterImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
  475. {
  476. MOZ_ASSERT(NS_IsMainThread());
  477. MOZ_ASSERT(aManager);
  478. MOZ_ASSERT((aFlags & ~(FLAG_SYNC_DECODE |
  479. FLAG_SYNC_DECODE_IF_FAST |
  480. FLAG_ASYNC_NOTIFY))
  481. == FLAG_NONE,
  482. "Unsupported flag passed to GetImageContainer");
  483. int32_t maxTextureSize = aManager->GetMaxTextureSize();
  484. if (!mHasSize ||
  485. mSize.width > maxTextureSize ||
  486. mSize.height > maxTextureSize) {
  487. return nullptr;
  488. }
  489. if (IsUnlocked() && mProgressTracker) {
  490. mProgressTracker->OnUnlockedDraw();
  491. }
  492. RefPtr<layers::ImageContainer> container = mImageContainer.get();
  493. bool mustRedecode =
  494. (aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST)) &&
  495. mLastImageContainerDrawResult != DrawResult::SUCCESS &&
  496. mLastImageContainerDrawResult != DrawResult::BAD_IMAGE;
  497. if (container && !mustRedecode) {
  498. return container.forget();
  499. }
  500. // We need a new ImageContainer, so create one.
  501. container = LayerManager::CreateImageContainer();
  502. DrawResult drawResult;
  503. RefPtr<layers::Image> image;
  504. Tie(drawResult, image) = GetCurrentImage(container, aFlags);
  505. if (!image) {
  506. return nullptr;
  507. }
  508. // |image| holds a reference to a SourceSurface which in turn holds a lock on
  509. // the current frame's VolatileBuffer, ensuring that it doesn't get freed as
  510. // long as the layer system keeps this ImageContainer alive.
  511. AutoTArray<ImageContainer::NonOwningImage, 1> imageList;
  512. imageList.AppendElement(ImageContainer::NonOwningImage(image, TimeStamp(),
  513. mLastFrameID++,
  514. mImageProducerID));
  515. container->SetCurrentImagesInTransaction(imageList);
  516. mLastImageContainerDrawResult = drawResult;
  517. mImageContainer = container;
  518. return container.forget();
  519. }
  520. void
  521. RasterImage::UpdateImageContainer()
  522. {
  523. MOZ_ASSERT(NS_IsMainThread());
  524. RefPtr<layers::ImageContainer> container = mImageContainer.get();
  525. if (!container) {
  526. return;
  527. }
  528. DrawResult drawResult;
  529. RefPtr<layers::Image> image;
  530. Tie(drawResult, image) = GetCurrentImage(container, FLAG_NONE);
  531. if (!image) {
  532. return;
  533. }
  534. mLastImageContainerDrawResult = drawResult;
  535. AutoTArray<ImageContainer::NonOwningImage, 1> imageList;
  536. imageList.AppendElement(ImageContainer::NonOwningImage(image, TimeStamp(),
  537. mLastFrameID++,
  538. mImageProducerID));
  539. container->SetCurrentImages(imageList);
  540. }
  541. size_t
  542. RasterImage::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
  543. {
  544. return mSourceBuffer->SizeOfIncludingThisWithComputedFallback(aMallocSizeOf);
  545. }
  546. void
  547. RasterImage::CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
  548. MallocSizeOf aMallocSizeOf) const
  549. {
  550. SurfaceCache::CollectSizeOfSurfaces(ImageKey(this), aCounters, aMallocSizeOf);
  551. if (mFrameAnimator) {
  552. mFrameAnimator->CollectSizeOfCompositingSurfaces(aCounters, aMallocSizeOf);
  553. }
  554. }
  555. bool
  556. RasterImage::SetMetadata(const ImageMetadata& aMetadata,
  557. bool aFromMetadataDecode)
  558. {
  559. MOZ_ASSERT(NS_IsMainThread());
  560. if (mError) {
  561. return true;
  562. }
  563. if (aMetadata.HasSize()) {
  564. IntSize size = aMetadata.GetSize();
  565. if (size.width < 0 || size.height < 0) {
  566. NS_WARNING("Image has negative intrinsic size");
  567. DoError();
  568. return true;
  569. }
  570. MOZ_ASSERT(aMetadata.HasOrientation());
  571. Orientation orientation = aMetadata.GetOrientation();
  572. // If we already have a size, check the new size against the old one.
  573. if (mHasSize && (size != mSize || orientation != mOrientation)) {
  574. NS_WARNING("Image changed size or orientation on redecode! "
  575. "This should not happen!");
  576. DoError();
  577. return true;
  578. }
  579. // Set the size and flag that we have it.
  580. mSize = size;
  581. mOrientation = orientation;
  582. mHasSize = true;
  583. }
  584. if (mHasSize && aMetadata.HasAnimation() && !mAnimationState) {
  585. // We're becoming animated, so initialize animation stuff.
  586. mAnimationState.emplace(mAnimationMode);
  587. mFrameAnimator = MakeUnique<FrameAnimator>(this, mSize);
  588. // We don't support discarding animated images (See bug 414259).
  589. // Lock the image and throw away the key.
  590. LockImage();
  591. if (!aFromMetadataDecode) {
  592. // The metadata decode reported that this image isn't animated, but we
  593. // discovered that it actually was during the full decode. This is a
  594. // rare failure that only occurs for corrupt images. To recover, we need
  595. // to discard all existing surfaces and redecode.
  596. return false;
  597. }
  598. }
  599. if (mAnimationState) {
  600. mAnimationState->SetLoopCount(aMetadata.GetLoopCount());
  601. mAnimationState->SetFirstFrameTimeout(aMetadata.GetFirstFrameTimeout());
  602. if (aMetadata.HasLoopLength()) {
  603. mAnimationState->SetLoopLength(aMetadata.GetLoopLength());
  604. }
  605. if (aMetadata.HasFirstFrameRefreshArea()) {
  606. mAnimationState
  607. ->SetFirstFrameRefreshArea(aMetadata.GetFirstFrameRefreshArea());
  608. }
  609. }
  610. if (aMetadata.HasHotspot()) {
  611. IntPoint hotspot = aMetadata.GetHotspot();
  612. nsCOMPtr<nsISupportsPRUint32> intwrapx =
  613. do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID);
  614. nsCOMPtr<nsISupportsPRUint32> intwrapy =
  615. do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID);
  616. intwrapx->SetData(hotspot.x);
  617. intwrapy->SetData(hotspot.y);
  618. Set("hotspotX", intwrapx);
  619. Set("hotspotY", intwrapy);
  620. }
  621. return true;
  622. }
  623. NS_IMETHODIMP
  624. RasterImage::SetAnimationMode(uint16_t aAnimationMode)
  625. {
  626. if (mAnimationState) {
  627. mAnimationState->SetAnimationMode(aAnimationMode);
  628. }
  629. return SetAnimationModeInternal(aAnimationMode);
  630. }
  631. //******************************************************************************
  632. nsresult
  633. RasterImage::StartAnimation()
  634. {
  635. if (mError) {
  636. return NS_ERROR_FAILURE;
  637. }
  638. MOZ_ASSERT(ShouldAnimate(), "Should not animate!");
  639. // If we're not ready to animate, then set mPendingAnimation, which will cause
  640. // us to start animating if and when we do become ready.
  641. mPendingAnimation = !mAnimationState || mAnimationState->KnownFrameCount() < 1;
  642. if (mPendingAnimation) {
  643. return NS_OK;
  644. }
  645. // Don't bother to animate if we're displaying the first frame forever.
  646. if (mAnimationState->GetCurrentAnimationFrameIndex() == 0 &&
  647. mAnimationState->FirstFrameTimeout() == FrameTimeout::Forever()) {
  648. mAnimationFinished = true;
  649. return NS_ERROR_ABORT;
  650. }
  651. // We need to set the time that this initial frame was first displayed, as
  652. // this is used in AdvanceFrame().
  653. mAnimationState->InitAnimationFrameTimeIfNecessary();
  654. return NS_OK;
  655. }
  656. //******************************************************************************
  657. nsresult
  658. RasterImage::StopAnimation()
  659. {
  660. MOZ_ASSERT(mAnimating, "Should be animating!");
  661. nsresult rv = NS_OK;
  662. if (mError) {
  663. rv = NS_ERROR_FAILURE;
  664. } else {
  665. mAnimationState->SetAnimationFrameTime(TimeStamp());
  666. }
  667. mAnimating = false;
  668. return rv;
  669. }
  670. //******************************************************************************
  671. NS_IMETHODIMP
  672. RasterImage::ResetAnimation()
  673. {
  674. if (mError) {
  675. return NS_ERROR_FAILURE;
  676. }
  677. mPendingAnimation = false;
  678. if (mAnimationMode == kDontAnimMode || !mAnimationState ||
  679. mAnimationState->GetCurrentAnimationFrameIndex() == 0) {
  680. return NS_OK;
  681. }
  682. mAnimationFinished = false;
  683. if (mAnimating) {
  684. StopAnimation();
  685. }
  686. MOZ_ASSERT(mAnimationState, "Should have AnimationState");
  687. mAnimationState->ResetAnimation();
  688. NotifyProgress(NoProgress, mAnimationState->FirstFrameRefreshArea());
  689. // Start the animation again. It may not have been running before, if
  690. // mAnimationFinished was true before entering this function.
  691. EvaluateAnimation();
  692. return NS_OK;
  693. }
  694. //******************************************************************************
  695. NS_IMETHODIMP_(void)
  696. RasterImage::SetAnimationStartTime(const TimeStamp& aTime)
  697. {
  698. if (mError || mAnimationMode == kDontAnimMode || mAnimating || !mAnimationState) {
  699. return;
  700. }
  701. mAnimationState->SetAnimationFrameTime(aTime);
  702. }
  703. NS_IMETHODIMP_(float)
  704. RasterImage::GetFrameIndex(uint32_t aWhichFrame)
  705. {
  706. MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE, "Invalid argument");
  707. return (aWhichFrame == FRAME_FIRST || !mAnimationState)
  708. ? 0.0f
  709. : mAnimationState->GetCurrentAnimationFrameIndex();
  710. }
  711. NS_IMETHODIMP_(IntRect)
  712. RasterImage::GetImageSpaceInvalidationRect(const IntRect& aRect)
  713. {
  714. return aRect;
  715. }
  716. nsresult
  717. RasterImage::OnImageDataComplete(nsIRequest*, nsISupports*, nsresult aStatus,
  718. bool aLastPart)
  719. {
  720. MOZ_ASSERT(NS_IsMainThread());
  721. // Record that we have all the data we're going to get now.
  722. mHasSourceData = true;
  723. // Let decoders know that there won't be any more data coming.
  724. mSourceBuffer->Complete(aStatus);
  725. // Allow a synchronous metadata decode if mSyncLoad was set, or if we're
  726. // running on a single thread (in which case waiting for the async metadata
  727. // decoder could delay this image's load event quite a bit), or if this image
  728. // is transient.
  729. bool canSyncDecodeMetadata = mSyncLoad || mTransient ||
  730. DecodePool::NumberOfCores() < 2;
  731. if (canSyncDecodeMetadata && !mHasSize) {
  732. // We're loading this image synchronously, so it needs to be usable after
  733. // this call returns. Since we haven't gotten our size yet, we need to do a
  734. // synchronous metadata decode here.
  735. DecodeMetadata(FLAG_SYNC_DECODE);
  736. }
  737. // Determine our final status, giving precedence to Necko failure codes. We
  738. // check after running the metadata decode in case it triggered an error.
  739. nsresult finalStatus = mError ? NS_ERROR_FAILURE : NS_OK;
  740. if (NS_FAILED(aStatus)) {
  741. finalStatus = aStatus;
  742. }
  743. // If loading failed, report an error.
  744. if (NS_FAILED(finalStatus)) {
  745. DoError();
  746. }
  747. Progress loadProgress = LoadCompleteProgress(aLastPart, mError, finalStatus);
  748. if (!mHasSize && !mError) {
  749. // We don't have our size yet, so we'll fire the load event in SetSize().
  750. MOZ_ASSERT(!canSyncDecodeMetadata,
  751. "Firing load async after metadata sync decode?");
  752. NotifyProgress(FLAG_ONLOAD_BLOCKED);
  753. mLoadProgress = Some(loadProgress);
  754. return finalStatus;
  755. }
  756. NotifyForLoadEvent(loadProgress);
  757. return finalStatus;
  758. }
  759. void
  760. RasterImage::NotifyForLoadEvent(Progress aProgress)
  761. {
  762. MOZ_ASSERT(mHasSize || mError, "Need to know size before firing load event");
  763. MOZ_ASSERT(!mHasSize ||
  764. (mProgressTracker->GetProgress() & FLAG_SIZE_AVAILABLE),
  765. "Should have notified that the size is available if we have it");
  766. // If we encountered an error, make sure we notify for that as well.
  767. if (mError) {
  768. aProgress |= FLAG_HAS_ERROR;
  769. }
  770. // Notify our listeners, which will fire this image's load event.
  771. NotifyProgress(aProgress);
  772. }
  773. nsresult
  774. RasterImage::OnImageDataAvailable(nsIRequest*,
  775. nsISupports*,
  776. nsIInputStream* aInputStream,
  777. uint64_t,
  778. uint32_t aCount)
  779. {
  780. nsresult rv = mSourceBuffer->AppendFromInputStream(aInputStream, aCount);
  781. if (NS_FAILED(rv)) {
  782. DoError();
  783. }
  784. return rv;
  785. }
  786. nsresult
  787. RasterImage::SetSourceSizeHint(uint32_t aSizeHint)
  788. {
  789. return mSourceBuffer->ExpectLength(aSizeHint);
  790. }
  791. /********* Methods to implement lazy allocation of nsIProperties object *******/
  792. NS_IMETHODIMP
  793. RasterImage::Get(const char* prop, const nsIID& iid, void** result)
  794. {
  795. if (!mProperties) {
  796. return NS_ERROR_FAILURE;
  797. }
  798. return mProperties->Get(prop, iid, result);
  799. }
  800. NS_IMETHODIMP
  801. RasterImage::Set(const char* prop, nsISupports* value)
  802. {
  803. if (!mProperties) {
  804. mProperties = do_CreateInstance("@mozilla.org/properties;1");
  805. }
  806. if (!mProperties) {
  807. return NS_ERROR_OUT_OF_MEMORY;
  808. }
  809. return mProperties->Set(prop, value);
  810. }
  811. NS_IMETHODIMP
  812. RasterImage::Has(const char* prop, bool* _retval)
  813. {
  814. NS_ENSURE_ARG_POINTER(_retval);
  815. if (!mProperties) {
  816. *_retval = false;
  817. return NS_OK;
  818. }
  819. return mProperties->Has(prop, _retval);
  820. }
  821. NS_IMETHODIMP
  822. RasterImage::Undefine(const char* prop)
  823. {
  824. if (!mProperties) {
  825. return NS_ERROR_FAILURE;
  826. }
  827. return mProperties->Undefine(prop);
  828. }
  829. NS_IMETHODIMP
  830. RasterImage::GetKeys(uint32_t* count, char*** keys)
  831. {
  832. if (!mProperties) {
  833. *count = 0;
  834. *keys = nullptr;
  835. return NS_OK;
  836. }
  837. return mProperties->GetKeys(count, keys);
  838. }
  839. void
  840. RasterImage::Discard()
  841. {
  842. MOZ_ASSERT(NS_IsMainThread());
  843. MOZ_ASSERT(CanDiscard(), "Asked to discard but can't");
  844. MOZ_ASSERT(!mAnimationState, "Asked to discard for animated image");
  845. // Delete all the decoded frames.
  846. SurfaceCache::RemoveImage(ImageKey(this));
  847. // Notify that we discarded.
  848. if (mProgressTracker) {
  849. mProgressTracker->OnDiscard();
  850. }
  851. }
  852. bool
  853. RasterImage::CanDiscard() {
  854. return mHasSourceData && // ...have the source data...
  855. !mAnimationState; // Can never discard animated images
  856. }
  857. NS_IMETHODIMP
  858. RasterImage::StartDecoding()
  859. {
  860. if (mError) {
  861. return NS_ERROR_FAILURE;
  862. }
  863. if (!mHasSize) {
  864. mWantFullDecode = true;
  865. return NS_OK;
  866. }
  867. return RequestDecodeForSize(mSize, FLAG_SYNC_DECODE_IF_FAST);
  868. }
  869. NS_IMETHODIMP
  870. RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags)
  871. {
  872. MOZ_ASSERT(NS_IsMainThread());
  873. if (mError) {
  874. return NS_ERROR_FAILURE;
  875. }
  876. if (!mHasSize) {
  877. return NS_OK;
  878. }
  879. // Decide whether to sync decode images we can decode quickly. Here we are
  880. // explicitly trading off flashing for responsiveness in the case that we're
  881. // redecoding an image (see bug 845147).
  882. bool shouldSyncDecodeIfFast =
  883. !mHasBeenDecoded && (aFlags & FLAG_SYNC_DECODE_IF_FAST);
  884. uint32_t flags = shouldSyncDecodeIfFast
  885. ? aFlags
  886. : aFlags & ~FLAG_SYNC_DECODE_IF_FAST;
  887. // Perform a frame lookup, which will implicitly start decoding if needed.
  888. LookupFrame(aSize, flags, mAnimationState ? PlaybackType::eAnimated
  889. : PlaybackType::eStatic);
  890. return NS_OK;
  891. }
  892. static void
  893. LaunchDecodingTask(IDecodingTask* aTask,
  894. RasterImage* aImage,
  895. uint32_t aFlags,
  896. bool aHaveSourceData)
  897. {
  898. if (aHaveSourceData) {
  899. // If we have all the data, we can sync decode if requested.
  900. if (aFlags & imgIContainer::FLAG_SYNC_DECODE) {
  901. PROFILER_LABEL_PRINTF("DecodePool", "SyncRunIfPossible",
  902. js::ProfileEntry::Category::GRAPHICS,
  903. "%s", aImage->GetURIString().get());
  904. DecodePool::Singleton()->SyncRunIfPossible(aTask);
  905. return;
  906. }
  907. if (aFlags & imgIContainer::FLAG_SYNC_DECODE_IF_FAST) {
  908. PROFILER_LABEL_PRINTF("DecodePool", "SyncRunIfPreferred",
  909. js::ProfileEntry::Category::GRAPHICS,
  910. "%s", aImage->GetURIString().get());
  911. DecodePool::Singleton()->SyncRunIfPreferred(aTask);
  912. return;
  913. }
  914. }
  915. // Perform an async decode. We also take this path if we don't have all the
  916. // source data yet, since sync decoding is impossible in that situation.
  917. DecodePool::Singleton()->AsyncRun(aTask);
  918. }
  919. NS_IMETHODIMP
  920. RasterImage::Decode(const IntSize& aSize,
  921. uint32_t aFlags,
  922. PlaybackType aPlaybackType)
  923. {
  924. MOZ_ASSERT(NS_IsMainThread());
  925. if (mError) {
  926. return NS_ERROR_FAILURE;
  927. }
  928. // If we don't have a size yet, we can't do any other decoding.
  929. if (!mHasSize) {
  930. mWantFullDecode = true;
  931. return NS_OK;
  932. }
  933. // We're about to decode again, which may mean that some of the previous sizes
  934. // we've decoded at aren't useful anymore. We can allow them to expire from
  935. // the cache by unlocking them here. When the decode finishes, it will send an
  936. // invalidation that will cause all instances of this image to redraw. If this
  937. // image is locked, any surfaces that are still useful will become locked
  938. // again when LookupFrame touches them, and the remainder will eventually
  939. // expire.
  940. SurfaceCache::UnlockEntries(ImageKey(this));
  941. // Determine which flags we need to decode this image with.
  942. DecoderFlags decoderFlags = DefaultDecoderFlags();
  943. if (aFlags & FLAG_ASYNC_NOTIFY) {
  944. decoderFlags |= DecoderFlags::ASYNC_NOTIFY;
  945. }
  946. if (mTransient) {
  947. decoderFlags |= DecoderFlags::IMAGE_IS_TRANSIENT;
  948. }
  949. if (mHasBeenDecoded) {
  950. decoderFlags |= DecoderFlags::IS_REDECODE;
  951. }
  952. SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
  953. if (IsOpaque()) {
  954. // If there's no transparency, it doesn't matter whether we premultiply
  955. // alpha or not.
  956. surfaceFlags &= ~SurfaceFlags::NO_PREMULTIPLY_ALPHA;
  957. }
  958. // Create a decoder.
  959. RefPtr<IDecodingTask> task;
  960. if (mAnimationState && aPlaybackType == PlaybackType::eAnimated) {
  961. task = DecoderFactory::CreateAnimationDecoder(mDecoderType, WrapNotNull(this),
  962. mSourceBuffer, mSize,
  963. decoderFlags, surfaceFlags);
  964. } else {
  965. task = DecoderFactory::CreateDecoder(mDecoderType, WrapNotNull(this),
  966. mSourceBuffer, mSize, aSize,
  967. decoderFlags, surfaceFlags,
  968. mRequestedSampleSize);
  969. }
  970. // Make sure DecoderFactory was able to create a decoder successfully.
  971. if (!task) {
  972. return NS_ERROR_FAILURE;
  973. }
  974. mDecodeCount++;
  975. // We're ready to decode; start the decoder.
  976. LaunchDecodingTask(task, this, aFlags, mHasSourceData);
  977. return NS_OK;
  978. }
  979. NS_IMETHODIMP
  980. RasterImage::DecodeMetadata(uint32_t aFlags)
  981. {
  982. if (mError) {
  983. return NS_ERROR_FAILURE;
  984. }
  985. MOZ_ASSERT(!mHasSize, "Should not do unnecessary metadata decodes");
  986. // Create a decoder.
  987. RefPtr<IDecodingTask> task =
  988. DecoderFactory::CreateMetadataDecoder(mDecoderType, WrapNotNull(this),
  989. mSourceBuffer, mRequestedSampleSize);
  990. // Make sure DecoderFactory was able to create a decoder successfully.
  991. if (!task) {
  992. return NS_ERROR_FAILURE;
  993. }
  994. // We're ready to decode; start the decoder.
  995. LaunchDecodingTask(task, this, aFlags, mHasSourceData);
  996. return NS_OK;
  997. }
  998. void
  999. RasterImage::RecoverFromInvalidFrames(const IntSize& aSize, uint32_t aFlags)
  1000. {
  1001. if (!mHasSize) {
  1002. return;
  1003. }
  1004. NS_WARNING("A RasterImage's frames became invalid. Attempting to recover...");
  1005. // Discard all existing frames, since they're probably all now invalid.
  1006. SurfaceCache::RemoveImage(ImageKey(this));
  1007. // Relock the image if it's supposed to be locked.
  1008. if (mLockCount > 0) {
  1009. SurfaceCache::LockImage(ImageKey(this));
  1010. }
  1011. // Animated images require some special handling, because we normally require
  1012. // that they never be discarded.
  1013. if (mAnimationState) {
  1014. Decode(mSize, aFlags | FLAG_SYNC_DECODE, PlaybackType::eAnimated);
  1015. ResetAnimation();
  1016. return;
  1017. }
  1018. // For non-animated images, it's fine to recover using an async decode.
  1019. Decode(aSize, aFlags, PlaybackType::eStatic);
  1020. }
  1021. static bool
  1022. HaveSkia()
  1023. {
  1024. #ifdef MOZ_ENABLE_SKIA
  1025. return true;
  1026. #else
  1027. return false;
  1028. #endif
  1029. }
  1030. bool
  1031. RasterImage::CanDownscaleDuringDecode(const IntSize& aSize, uint32_t aFlags)
  1032. {
  1033. // Check basic requirements: downscale-during-decode is enabled, Skia is
  1034. // available, this image isn't transient, we have all the source data and know
  1035. // our size, and the flags allow us to do it.
  1036. if (!mHasSize || mTransient || !HaveSkia() ||
  1037. !gfxPrefs::ImageDownscaleDuringDecodeEnabled() ||
  1038. !(aFlags & imgIContainer::FLAG_HIGH_QUALITY_SCALING)) {
  1039. return false;
  1040. }
  1041. // We don't downscale animated images during decode.
  1042. if (mAnimationState) {
  1043. return false;
  1044. }
  1045. // Never upscale.
  1046. if (aSize.width >= mSize.width || aSize.height >= mSize.height) {
  1047. return false;
  1048. }
  1049. // Zero or negative width or height is unacceptable.
  1050. if (aSize.width < 1 || aSize.height < 1) {
  1051. return false;
  1052. }
  1053. // There's no point in scaling if we can't store the result.
  1054. if (!SurfaceCache::CanHold(aSize)) {
  1055. return false;
  1056. }
  1057. return true;
  1058. }
  1059. DrawResult
  1060. RasterImage::DrawInternal(DrawableSurface&& aSurface,
  1061. gfxContext* aContext,
  1062. const IntSize& aSize,
  1063. const ImageRegion& aRegion,
  1064. SamplingFilter aSamplingFilter,
  1065. uint32_t aFlags)
  1066. {
  1067. gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
  1068. ImageRegion region(aRegion);
  1069. bool frameIsFinished = aSurface->IsFinished();
  1070. // By now we may have a frame with the requested size. If not, we need to
  1071. // adjust the drawing parameters accordingly.
  1072. IntSize finalSize = aSurface->GetImageSize();
  1073. bool couldRedecodeForBetterFrame = false;
  1074. if (finalSize != aSize) {
  1075. gfx::Size scale(double(aSize.width) / finalSize.width,
  1076. double(aSize.height) / finalSize.height);
  1077. aContext->Multiply(gfxMatrix::Scaling(scale.width, scale.height));
  1078. region.Scale(1.0 / scale.width, 1.0 / scale.height);
  1079. couldRedecodeForBetterFrame = CanDownscaleDuringDecode(aSize, aFlags);
  1080. }
  1081. if (!aSurface->Draw(aContext, region, aSamplingFilter, aFlags)) {
  1082. RecoverFromInvalidFrames(aSize, aFlags);
  1083. return DrawResult::TEMPORARY_ERROR;
  1084. }
  1085. if (!frameIsFinished) {
  1086. return DrawResult::INCOMPLETE;
  1087. }
  1088. if (couldRedecodeForBetterFrame) {
  1089. return DrawResult::WRONG_SIZE;
  1090. }
  1091. return DrawResult::SUCCESS;
  1092. }
  1093. //******************************************************************************
  1094. NS_IMETHODIMP_(DrawResult)
  1095. RasterImage::Draw(gfxContext* aContext,
  1096. const IntSize& aSize,
  1097. const ImageRegion& aRegion,
  1098. uint32_t aWhichFrame,
  1099. SamplingFilter aSamplingFilter,
  1100. const Maybe<SVGImageContext>& /*aSVGContext - ignored*/,
  1101. uint32_t aFlags)
  1102. {
  1103. if (aWhichFrame > FRAME_MAX_VALUE) {
  1104. return DrawResult::BAD_ARGS;
  1105. }
  1106. if (mError) {
  1107. return DrawResult::BAD_IMAGE;
  1108. }
  1109. // Illegal -- you can't draw with non-default decode flags.
  1110. // (Disabling colorspace conversion might make sense to allow, but
  1111. // we don't currently.)
  1112. if (ToSurfaceFlags(aFlags) != DefaultSurfaceFlags()) {
  1113. return DrawResult::BAD_ARGS;
  1114. }
  1115. if (!aContext) {
  1116. return DrawResult::BAD_ARGS;
  1117. }
  1118. if (IsUnlocked() && mProgressTracker) {
  1119. mProgressTracker->OnUnlockedDraw();
  1120. }
  1121. // If we're not using SamplingFilter::GOOD, we shouldn't high-quality scale or
  1122. // downscale during decode.
  1123. uint32_t flags = aSamplingFilter == SamplingFilter::GOOD
  1124. ? aFlags
  1125. : aFlags & ~FLAG_HIGH_QUALITY_SCALING;
  1126. DrawableSurface surface =
  1127. LookupFrame(aSize, flags, ToPlaybackType(aWhichFrame));
  1128. if (!surface) {
  1129. // Getting the frame (above) touches the image and kicks off decoding.
  1130. if (mDrawStartTime.IsNull()) {
  1131. mDrawStartTime = TimeStamp::Now();
  1132. }
  1133. return DrawResult::NOT_READY;
  1134. }
  1135. auto result = DrawInternal(Move(surface), aContext, aSize,
  1136. aRegion, aSamplingFilter, flags);
  1137. return result;
  1138. }
  1139. //******************************************************************************
  1140. NS_IMETHODIMP
  1141. RasterImage::LockImage()
  1142. {
  1143. MOZ_ASSERT(NS_IsMainThread(),
  1144. "Main thread to encourage serialization with UnlockImage");
  1145. if (mError) {
  1146. return NS_ERROR_FAILURE;
  1147. }
  1148. // Increment the lock count
  1149. mLockCount++;
  1150. // Lock this image's surfaces in the SurfaceCache.
  1151. if (mLockCount == 1) {
  1152. SurfaceCache::LockImage(ImageKey(this));
  1153. }
  1154. return NS_OK;
  1155. }
  1156. //******************************************************************************
  1157. NS_IMETHODIMP
  1158. RasterImage::UnlockImage()
  1159. {
  1160. MOZ_ASSERT(NS_IsMainThread(),
  1161. "Main thread to encourage serialization with LockImage");
  1162. if (mError) {
  1163. return NS_ERROR_FAILURE;
  1164. }
  1165. // It's an error to call this function if the lock count is 0
  1166. MOZ_ASSERT(mLockCount > 0,
  1167. "Calling UnlockImage with mLockCount == 0!");
  1168. if (mLockCount == 0) {
  1169. return NS_ERROR_ABORT;
  1170. }
  1171. // Decrement our lock count
  1172. mLockCount--;
  1173. // Unlock this image's surfaces in the SurfaceCache.
  1174. if (mLockCount == 0 ) {
  1175. SurfaceCache::UnlockImage(ImageKey(this));
  1176. }
  1177. return NS_OK;
  1178. }
  1179. //******************************************************************************
  1180. NS_IMETHODIMP
  1181. RasterImage::RequestDiscard()
  1182. {
  1183. if (mDiscardable && // Enabled at creation time...
  1184. mLockCount == 0 && // ...not temporarily disabled...
  1185. CanDiscard()) {
  1186. Discard();
  1187. }
  1188. return NS_OK;
  1189. }
  1190. // Indempotent error flagging routine. If a decoder is open, shuts it down.
  1191. void
  1192. RasterImage::DoError()
  1193. {
  1194. // If we've flagged an error before, we have nothing to do
  1195. if (mError) {
  1196. return;
  1197. }
  1198. // We can't safely handle errors off-main-thread, so dispatch a worker to
  1199. // do it.
  1200. if (!NS_IsMainThread()) {
  1201. HandleErrorWorker::DispatchIfNeeded(this);
  1202. return;
  1203. }
  1204. // Put the container in an error state.
  1205. mError = true;
  1206. // Stop animation and release our FrameAnimator.
  1207. if (mAnimating) {
  1208. StopAnimation();
  1209. }
  1210. mAnimationState = Nothing();
  1211. mFrameAnimator = nullptr;
  1212. // Release all locks.
  1213. mLockCount = 0;
  1214. SurfaceCache::UnlockImage(ImageKey(this));
  1215. // Release all frames from the surface cache.
  1216. SurfaceCache::RemoveImage(ImageKey(this));
  1217. // Invalidate to get rid of any partially-drawn image content.
  1218. NotifyProgress(NoProgress, IntRect(0, 0, mSize.width, mSize.height));
  1219. MOZ_LOG(gImgLog, LogLevel::Error,
  1220. ("RasterImage: [this=%p] Error detected for image\n", this));
  1221. }
  1222. /* static */ void
  1223. RasterImage::HandleErrorWorker::DispatchIfNeeded(RasterImage* aImage)
  1224. {
  1225. RefPtr<HandleErrorWorker> worker = new HandleErrorWorker(aImage);
  1226. NS_DispatchToMainThread(worker);
  1227. }
  1228. RasterImage::HandleErrorWorker::HandleErrorWorker(RasterImage* aImage)
  1229. : mImage(aImage)
  1230. {
  1231. MOZ_ASSERT(mImage, "Should have image");
  1232. }
  1233. NS_IMETHODIMP
  1234. RasterImage::HandleErrorWorker::Run()
  1235. {
  1236. mImage->DoError();
  1237. return NS_OK;
  1238. }
  1239. bool
  1240. RasterImage::ShouldAnimate()
  1241. {
  1242. return ImageResource::ShouldAnimate() &&
  1243. mAnimationState &&
  1244. mAnimationState->KnownFrameCount() >= 1 &&
  1245. !mAnimationFinished;
  1246. }
  1247. #ifdef DEBUG
  1248. NS_IMETHODIMP
  1249. RasterImage::GetFramesNotified(uint32_t* aFramesNotified)
  1250. {
  1251. NS_ENSURE_ARG_POINTER(aFramesNotified);
  1252. *aFramesNotified = mFramesNotified;
  1253. return NS_OK;
  1254. }
  1255. #endif
  1256. void
  1257. RasterImage::NotifyProgress(Progress aProgress,
  1258. const IntRect& aInvalidRect /* = IntRect() */,
  1259. const Maybe<uint32_t>& aFrameCount /* = Nothing() */,
  1260. DecoderFlags aDecoderFlags
  1261. /* = DefaultDecoderFlags() */,
  1262. SurfaceFlags aSurfaceFlags
  1263. /* = DefaultSurfaceFlags() */)
  1264. {
  1265. MOZ_ASSERT(NS_IsMainThread());
  1266. // Ensure that we stay alive long enough to finish notifying.
  1267. RefPtr<RasterImage> image = this;
  1268. const bool wasDefaultFlags = aSurfaceFlags == DefaultSurfaceFlags();
  1269. if (!aInvalidRect.IsEmpty() && wasDefaultFlags) {
  1270. // Update our image container since we're invalidating.
  1271. UpdateImageContainer();
  1272. }
  1273. if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY)) {
  1274. // We may have decoded new animation frames; update our animation state.
  1275. MOZ_ASSERT_IF(aFrameCount && *aFrameCount > 1, mAnimationState || mError);
  1276. if (mAnimationState && aFrameCount) {
  1277. mAnimationState->UpdateKnownFrameCount(*aFrameCount);
  1278. }
  1279. // If we should start animating right now, do so.
  1280. if (mAnimationState && aFrameCount == Some(1u) &&
  1281. mPendingAnimation && ShouldAnimate()) {
  1282. StartAnimation();
  1283. }
  1284. }
  1285. // Tell the observers what happened.
  1286. image->mProgressTracker->SyncNotifyProgress(aProgress, aInvalidRect);
  1287. }
  1288. void
  1289. RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
  1290. const ImageMetadata& aMetadata,
  1291. const DecoderTelemetry& aTelemetry,
  1292. Progress aProgress,
  1293. const IntRect& aInvalidRect,
  1294. const Maybe<uint32_t>& aFrameCount,
  1295. DecoderFlags aDecoderFlags,
  1296. SurfaceFlags aSurfaceFlags)
  1297. {
  1298. MOZ_ASSERT(NS_IsMainThread());
  1299. // If the decoder detected an error, log it to the error console.
  1300. if (aStatus.mShouldReportError) {
  1301. ReportDecoderError();
  1302. }
  1303. // Record all the metadata the decoder gathered about this image.
  1304. bool metadataOK = SetMetadata(aMetadata, aStatus.mWasMetadataDecode);
  1305. if (!metadataOK) {
  1306. // This indicates a serious error that requires us to discard all existing
  1307. // surfaces and redecode to recover. We'll drop the results from this
  1308. // decoder on the floor, since they aren't valid.
  1309. RecoverFromInvalidFrames(mSize,
  1310. FromSurfaceFlags(aSurfaceFlags));
  1311. return;
  1312. }
  1313. MOZ_ASSERT(mError || mHasSize || !aMetadata.HasSize(),
  1314. "SetMetadata should've gotten a size");
  1315. if (!aStatus.mWasMetadataDecode && aStatus.mFinished) {
  1316. // Flag that we've been decoded before.
  1317. mHasBeenDecoded = true;
  1318. }
  1319. // Send out any final notifications.
  1320. NotifyProgress(aProgress, aInvalidRect, aFrameCount,
  1321. aDecoderFlags, aSurfaceFlags);
  1322. if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY) &&
  1323. mHasBeenDecoded && mAnimationState) {
  1324. // We've finished a full decode of all animation frames and our AnimationState
  1325. // has been notified about them all, so let it know not to expect anymore.
  1326. mAnimationState->SetDoneDecoding(true);
  1327. }
  1328. // Only act on errors if we have no usable frames from the decoder.
  1329. if (aStatus.mHadError &&
  1330. (!mAnimationState || mAnimationState->KnownFrameCount() == 0)) {
  1331. DoError();
  1332. } else if (aStatus.mWasMetadataDecode && !mHasSize) {
  1333. DoError();
  1334. }
  1335. // XXX(aosmond): Can we get this far without mFinished == true?
  1336. if (aStatus.mFinished && aStatus.mWasMetadataDecode) {
  1337. // If we were waiting to fire the load event, go ahead and fire it now.
  1338. if (mLoadProgress) {
  1339. NotifyForLoadEvent(*mLoadProgress);
  1340. mLoadProgress = Nothing();
  1341. NotifyProgress(FLAG_ONLOAD_UNBLOCKED);
  1342. }
  1343. // If we were a metadata decode and a full decode was requested, do it.
  1344. if (mWantFullDecode) {
  1345. mWantFullDecode = false;
  1346. RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT);
  1347. }
  1348. }
  1349. }
  1350. void
  1351. RasterImage::ReportDecoderError()
  1352. {
  1353. nsCOMPtr<nsIConsoleService> consoleService =
  1354. do_GetService(NS_CONSOLESERVICE_CONTRACTID);
  1355. nsCOMPtr<nsIScriptError> errorObject =
  1356. do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
  1357. if (consoleService && errorObject) {
  1358. nsAutoString msg(NS_LITERAL_STRING("Image corrupt or truncated."));
  1359. nsAutoString src;
  1360. if (GetURI()) {
  1361. nsCString uri;
  1362. if (GetURI()->GetSpecTruncatedTo1k(uri) == ImageURL::TruncatedTo1k) {
  1363. msg += NS_LITERAL_STRING(" URI in this note truncated due to length.");
  1364. }
  1365. src = NS_ConvertUTF8toUTF16(uri);
  1366. }
  1367. if (NS_SUCCEEDED(errorObject->InitWithWindowID(
  1368. msg,
  1369. src,
  1370. EmptyString(), 0, 0, nsIScriptError::errorFlag,
  1371. "Image", InnerWindowID()
  1372. ))) {
  1373. consoleService->LogMessage(errorObject);
  1374. }
  1375. }
  1376. }
  1377. already_AddRefed<imgIContainer>
  1378. RasterImage::Unwrap()
  1379. {
  1380. nsCOMPtr<imgIContainer> self(this);
  1381. return self.forget();
  1382. }
  1383. void
  1384. RasterImage::PropagateUseCounters(nsIDocument*)
  1385. {
  1386. // No use counters.
  1387. }
  1388. IntSize
  1389. RasterImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
  1390. SamplingFilter aSamplingFilter, uint32_t aFlags)
  1391. {
  1392. MOZ_ASSERT(aDest.width >= 0 || ceil(aDest.width) <= INT32_MAX ||
  1393. aDest.height >= 0 || ceil(aDest.height) <= INT32_MAX,
  1394. "Unexpected destination size");
  1395. if (mSize.IsEmpty() || aDest.IsEmpty()) {
  1396. return IntSize(0, 0);
  1397. }
  1398. IntSize destSize = IntSize::Ceil(aDest.width, aDest.height);
  1399. if (aSamplingFilter == SamplingFilter::GOOD &&
  1400. CanDownscaleDuringDecode(destSize, aFlags)) {
  1401. return destSize;
  1402. }
  1403. // We can't scale to this size. Use our intrinsic size for now.
  1404. return mSize;
  1405. }
  1406. } // namespace image
  1407. } // namespace mozilla