Browse Source

import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1188569: Drop unneeded MOZ_WARN_UNUSED_RESULT from from LookupBestMatch in SurfaceCache.cpp. r=seth (5e74e0028c)
- Bug 1192356 (Part 1) - Take advantage of mozilla::Tie() in SurfaceCache.cpp. r=dholbert (e4908c725d)
- Bug 1192356 (Part 2) - Take advantage of mozilla::Tie() in RasterImage.cpp. r=tn (1204189b73)
- Bug 1185800 - Add DecoderFlags and SurfaceFlags enum classes and use them instead of imgIContainer flags in all decoder-related code. r=tn (3abdab11f6)
- Bug 1196066 (Part 3) - Rewrite nsICODecoder to use StreamingLexer. r=tn (e2ba590c9d)
- Bug 1196066 (Part 4) - Enable the ICOMultiChunk test, which now passes. r=tn (9e02611959)
- Bug 1124084 - Flip on downscale-during-decode everywhere. r=tn (bd9deff966)
- Bug 1160801 - Treat invalid GIF disposal methods as DisposalMethod::NOT_SPECIFIED. r=jrmuizel (e26feaf8fb)
- Bug 1201796 (Part 1) - Treat ICOs with wrong widths and heights as corrupt. r=tn (322ba20808)
- Bug 1201796 (Part 2) - Add GetFrameAtSize() to support downscale-during-decode for GetFrame() use cases. r=tn (92f5d3a0a7)
- Bug 1194906 - Replace 'NS_ENSURE_TRUE(BadImage(..))' warnings with more useful messages. r=tn (cc3b368673)
- Bug 1201796 (Part 3) - Enable downscale-during-decode for imgITools::EncodeScaledImage(). r=tn (e2cdb5b520)
- Bug 1194472 - Correctly fetch compositor backend in WebGLContext. r=jgilbert (0092052dfc)
- Bug 1161913 - Part 1 - Add invalidation state for CaptureStream to Canvas and Contexts. r=mt (0377d6bbe7)
- Bug 1168075 - Fix CanvasCaptureMediaStream build fail for bluetooth2. r=pehrsons (53c67c0056)
- Bug 1176363 - Part 1: Make a raw copy of each Canvas::CaptureStream frame. r=mattwoodrow (a5df5793d6)
- Bug 1194575 - Rename RecoverFromLossOfFrames() to RecoverFromInvalidFrames() to better reflect its role. r=tn (baa6455e79)
- Bug 1146663 (Part 1) - Remove HQ scaling, which is now dead code. r=tn (efaddadea0)
- Bug 1146663 (Part 2) - Remove the concept of lifetimes from the SurfaceCache. r=dholbert (ab9862d7ee)
- Bug 1146663 (Part 3) - Make it impossible to deoptimize imgFrames. r=tn (19e2f1b370)
- Bug 1201763 - Add downscale-during-decode support for the ICON decoder. r=tn (33a2b95e5c)
- Bug 1194058 (Part 1) - Add Deinterlacer to allow Downscaler to work with interlaced images. r=tn (f7c57b7a8e)
- Bug 1194058 (Part 2) - Add downscale-during-decode support for the GIF decoder. r=tn (85622f9d55)
- Bug 1201796 (Part 4) - Add downscale-during-decode support for the ICO decoder. r=tn (d09d18b0d9)
- Bug 1146663 (Part 4) - Make all RasterImages support downscale-during-decode. r=tn (264642a895)
- Bug 1146663 (Part 5) - Require that all image decoders support downscale-during-decode. r=tn (79ad99885d)
- Bug 1206836 - When downscaling ICOs, downscale the AND mask as well. r=tn a=KWierso (08ec3d092b)
- missing bit of Bug 1138293 - Use malloc/free/realloc/calloc (eb8e5e1b9c)
- missing bit of Bug 1146663 (Part 3) - Make it impossible to deoptimize imgFrames. (233befe48f)
- Bug 1208935 - Move Deinterlacer to a standalone file. r=seth (b50322abc286)
master
roytam1 1 month ago
parent
commit
f1d1e16669
  1. 2
      b2g/app/b2g.js
  2. 22
      dom/canvas/CanvasRenderingContext2D.cpp
  3. 9
      dom/canvas/CanvasRenderingContext2D.h
  4. 24
      dom/canvas/WebGLContext.cpp
  5. 7
      dom/canvas/WebGLContext.h
  6. 7
      dom/canvas/nsICanvasRenderingContextInternal.h
  7. 15
      dom/html/HTMLCanvasElement.cpp
  8. 7
      dom/html/HTMLCanvasElement.h
  9. 40
      dom/media/CanvasCaptureMediaStream.cpp
  10. 5
      dom/media/CanvasCaptureMediaStream.h
  11. 5
      gfx/thebes/gfxPrefs.h
  12. 10
      image/ClippedImage.cpp
  13. 4
      image/ClippedImage.h
  14. 24
      image/DecodePool.cpp
  15. 41
      image/Decoder.cpp
  16. 80
      image/Decoder.h
  17. 40
      image/DecoderFactory.cpp
  18. 41
      image/DecoderFactory.h
  19. 42
      image/DecoderFlags.h
  20. 45
      image/Deinterlacer.cpp
  21. 50
      image/Deinterlacer.h
  22. 2
      image/Downscaler.cpp
  23. 1
      image/Downscaler.h
  24. 14
      image/DynamicImage.cpp
  25. 6
      image/FrameAnimator.cpp
  26. 8
      image/FrozenImage.cpp
  27. 4
      image/FrozenImage.h
  28. 11
      image/Image.h
  29. 47
      image/ImageFactory.cpp
  30. 4
      image/ImageOps.cpp
  31. 8
      image/ImageWrapper.cpp
  32. 10
      image/OrientedImage.cpp
  33. 4
      image/OrientedImage.h
  34. 486
      image/RasterImage.cpp
  35. 64
      image/RasterImage.h
  36. 80
      image/SurfaceCache.cpp
  37. 111
      image/SurfaceCache.h
  38. 56
      image/SurfaceFlags.h
  39. 46
      image/VectorImage.cpp
  40. 14
      image/decoders/nsBMPDecoder.cpp
  41. 6
      image/decoders/nsBMPDecoder.h
  42. 165
      image/decoders/nsGIFDecoder2.cpp
  43. 6
      image/decoders/nsGIFDecoder2.h
  44. 832
      image/decoders/nsICODecoder.cpp
  45. 106
      image/decoders/nsICODecoder.h
  46. 101
      image/decoders/nsIconDecoder.cpp
  47. 6
      image/decoders/nsIconDecoder.h
  48. 16
      image/decoders/nsJPEGDecoder.cpp
  49. 5
      image/decoders/nsJPEGDecoder.h
  50. 18
      image/decoders/nsPNGDecoder.cpp
  51. 4
      image/decoders/nsPNGDecoder.h
  52. 90
      image/imgFrame.cpp
  53. 4
      image/imgFrame.h
  54. 17
      image/imgIContainer.idl
  55. 5
      image/imgLoader.cpp
  56. 36
      image/imgTools.cpp
  57. 2
      image/moz.build
  58. 12
      image/test/crashtests/crashtests.list
  59. BIN
      image/test/crashtests/invalid-disposal-method-1.gif
  60. BIN
      image/test/crashtests/invalid-disposal-method-2.gif
  61. BIN
      image/test/crashtests/invalid-disposal-method-3.gif
  62. 0
      image/test/crashtests/invalid_ico_height.ico
  63. 0
      image/test/crashtests/invalid_ico_width.ico
  64. 3
      image/test/gtest/TestDecoders.cpp
  65. 6
      image/test/gtest/TestMetadata.cpp
  66. 5
      image/test/mochitest/test_has_transparency.html
  67. 17
      image/test/reftest/downscaling/reftest.list
  68. BIN
      image/test/reftest/ico/cur/pointer.cur
  69. 5
      image/test/reftest/ico/ico-bmp-corrupted/reftest.list
  70. 13
      image/test/reftest/ico/ico-mixed/reftest.list
  71. BIN
      image/test/reftest/ico/ico-png/transparent-png.ico
  72. BIN
      image/test/unit/image1png16x16.jpg
  73. BIN
      image/test/unit/image2jpg16x16.png
  74. 12
      image/test/unit/test_imgtools.js
  75. 4
      layout/tools/reftest/reftest-preferences.js
  76. 12
      modules/libpref/init/all.js
  77. BIN
      toolkit/components/places/tests/favicons/expected-favicon-big32.jpg.png
  78. BIN
      toolkit/components/places/tests/favicons/expected-favicon-big64.png.png

2
b2g/app/b2g.js

@ -62,7 +62,6 @@ pref("browser.cache.memory_limit", 2048); // 2 MB
/* image cache prefs */
pref("image.cache.size", 1048576); // bytes
pref("image.high_quality_downscaling.enabled", false);
pref("canvas.image.cache.limit", 20971520); // 20 MB
/* offline cache prefs */
@ -326,6 +325,7 @@ pref("media.gonk.enabled", true);
pref("media.video-queue.default-size", 3);
// optimize images' memory usage
pref("image.downscale-during-decode.enabled", true);
pref("image.decode-only-on-draw.enabled", true);
pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */
// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.

22
dom/canvas/CanvasRenderingContext2D.cpp

@ -949,7 +949,9 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
, mIPC(false)
, mDrawObserver(nullptr)
, mIsEntireFrameInvalid(false)
, mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
, mPredictManyRedrawCalls(false)
, mIsCapturedFrameInvalid(false)
, mPathTransformWillUpdate(false)
, mInvalidateCount(0)
{
sNumLivingContexts++;
@ -1054,6 +1056,7 @@ CanvasRenderingContext2D::Reset()
// no longer be valid.
mIsEntireFrameInvalid = false;
mPredictManyRedrawCalls = false;
mIsCapturedFrameInvalid = false;
return NS_OK;
}
@ -1112,6 +1115,8 @@ CanvasRenderingContext2D::StyleColorToString(const nscolor& aColor, nsAString& a
nsresult
CanvasRenderingContext2D::Redraw()
{
mIsCapturedFrameInvalid = true;
if (mIsEntireFrameInvalid) {
return NS_OK;
}
@ -1133,6 +1138,8 @@ CanvasRenderingContext2D::Redraw()
void
CanvasRenderingContext2D::Redraw(const mgfx::Rect &r)
{
mIsCapturedFrameInvalid = true;
++mInvalidateCount;
if (mIsEntireFrameInvalid) {
@ -1170,6 +1177,8 @@ CanvasRenderingContext2D::DidRefresh()
void
CanvasRenderingContext2D::RedrawUser(const gfxRect& r)
{
mIsCapturedFrameInvalid = true;
if (mIsEntireFrameInvalid) {
++mInvalidateCount;
return;
@ -5710,6 +5719,17 @@ CanvasRenderingContext2D::MarkContextClean()
mInvalidateCount = 0;
}
void
CanvasRenderingContext2D::MarkContextCleanForFrameCapture()
{
mIsCapturedFrameInvalid = false;
}
bool
CanvasRenderingContext2D::IsContextCleanForFrameCapture()
{
return !mIsCapturedFrameInvalid;
}
bool
CanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager *aManager)

9
dom/canvas/CanvasRenderingContext2D.h

@ -527,6 +527,8 @@ public:
LayerManager *aManager) override;
virtual bool ShouldForceInactiveLayer(LayerManager *aManager) override;
void MarkContextClean() override;
void MarkContextCleanForFrameCapture() override;
bool IsContextCleanForFrameCapture() override;
NS_IMETHOD SetIsIPC(bool isIPC) override;
// this rect is in canvas device space
void Redraw(const mozilla::gfx::Rect &r);
@ -819,6 +821,13 @@ protected:
*/
bool mPredictManyRedrawCalls;
/**
* Flag to avoid unnecessary surface copies to FrameCaptureListeners in the
* case when the canvas is not currently being drawn into and not rendered
* but canvas capturing is still ongoing.
*/
bool mIsCapturedFrameInvalid;
// This is stored after GetThebesSurface has been called once to avoid
// excessive ThebesSurface initialization overhead.
nsRefPtr<gfxASurface> mThebesSurface;

24
dom/canvas/WebGLContext.cpp

@ -220,6 +220,7 @@ WebGLContext::WebGLContext()
{
mGeneration = 0;
mInvalidated = false;
mCapturedFrameInvalidated = false;
mShouldPresent = true;
mResetLayer = true;
mOptionsFrozen = false;
@ -413,10 +414,12 @@ WebGLContext::DestroyResourcesAndContext()
void
WebGLContext::Invalidate()
{
if (mInvalidated)
if (!mCanvasElement)
return;
if (!mCanvasElement)
mCapturedFrameInvalidated = true;
if (mInvalidated)
return;
nsSVGEffects::InvalidateDirectRenderingObservers(mCanvasElement);
@ -669,6 +672,7 @@ PopulateCapFallbackQueue(const SurfaceCaps& baseCaps,
static bool
CreateOffscreen(GLContext* gl, const WebGLContextOptions& options,
const nsCOMPtr<nsIGfxInfo>& gfxInfo, WebGLContext* webgl,
layers::LayersBackend layersBackend,
layers::ISurfaceAllocator* surfAllocator)
{
SurfaceCaps baseCaps;
@ -686,7 +690,7 @@ CreateOffscreen(GLContext* gl, const WebGLContextOptions& options,
if (gl->IsANGLE() ||
(gl->GetContextType() == GLContextType::GLX &&
gfxPlatform::GetPlatform()->GetCompositorBackend() == LayersBackend::LAYERS_OPENGL))
layersBackend == LayersBackend::LAYERS_OPENGL))
{
// We can't use no-alpha formats on ANGLE yet because of:
// https://code.google.com/p/angleproject/issues/detail?id=764
@ -760,7 +764,8 @@ WebGLContext::CreateOffscreenGL(bool forceEnabled)
if (!gl)
break;
if (!CreateOffscreen(gl, mOptions, gfxInfo, this, surfAllocator))
if (!CreateOffscreen(gl, mOptions, gfxInfo, this,
GetCompositorBackendType(), surfAllocator))
break;
if (!InitAndValidateGL())
@ -1278,6 +1283,17 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* builder,
return canvasLayer.forget();
}
layers::LayersBackend
WebGLContext::GetCompositorBackendType() const
{
nsIWidget* docWidget = nsContentUtils::WidgetForDocument(mCanvasElement->OwnerDoc());
if (docWidget) {
layers::LayerManager* layerManager = docWidget->GetLayerManager();
return layerManager->GetCompositorBackendType();
}
return LayersBackend::LAYERS_NONE;
}
void
WebGLContext::GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval)
{

7
dom/canvas/WebGLContext.h

@ -315,6 +315,10 @@ public:
// contents of the buffer.
void MarkContextClean() override { mInvalidated = false; }
void MarkContextCleanForFrameCapture() override { mCapturedFrameInvalidated = false; }
bool IsContextCleanForFrameCapture() override { return !mCapturedFrameInvalidated; }
gl::GLContext* GL() const { return gl; }
bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
@ -362,6 +366,8 @@ public:
return IsContextLost() ? 0 : mHeight;
}
layers::LayersBackend GetCompositorBackendType() const;
void
GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
@ -1031,6 +1037,7 @@ protected:
WebGLContextOptions mOptions;
bool mInvalidated;
bool mCapturedFrameInvalidated;
bool mResetLayer;
bool mOptionsFrozen;
bool mMinCapability;

7
dom/canvas/nsICanvasRenderingContextInternal.h

@ -134,6 +134,13 @@ public:
virtual void MarkContextClean() = 0;
// Called when a frame is captured.
virtual void MarkContextCleanForFrameCapture() = 0;
// Whether the context is clean or has been invalidated since the last frame
// was captured.
virtual bool IsContextCleanForFrameCapture() = 0;
// Redraw the dirty rectangle of this canvas.
NS_IMETHOD Redraw(const gfxRect &dirty) = 0;

15
dom/html/HTMLCanvasElement.cpp

@ -1033,6 +1033,21 @@ HTMLCanvasElement::MarkContextClean()
mCurrentContext->MarkContextClean();
}
void
HTMLCanvasElement::MarkContextCleanForFrameCapture()
{
if (!mCurrentContext)
return;
mCurrentContext->MarkContextCleanForFrameCapture();
}
bool
HTMLCanvasElement::IsContextCleanForFrameCapture()
{
return mCurrentContext && mCurrentContext->IsContextCleanForFrameCapture();
}
already_AddRefed<SourceSurface>
HTMLCanvasElement::GetSurfaceSnapshot(bool* aPremultAlpha)
{

7
dom/html/HTMLCanvasElement.h

@ -214,6 +214,13 @@ public:
// take a snapshot of the canvas that needs to be "live" (e.g. -moz-element).
void MarkContextClean();
// Call this after capturing a frame, so we can avoid unnecessary surface
// copies for future frames when no drawing has occurred.
void MarkContextCleanForFrameCapture();
// Starts returning false when something is drawn.
bool IsContextCleanForFrameCapture();
nsresult GetContext(const nsAString& aContextId, nsISupports** aContext);
protected:

40
dom/media/CanvasCaptureMediaStream.cpp

@ -8,9 +8,10 @@
#include "gfxPlatform.h"
#include "ImageContainer.h"
#include "MediaStreamGraph.h"
#include "mozilla/Mutex.h"
#include "mozilla/dom/CanvasCaptureMediaStreamBinding.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/Mutex.h"
#include "nsContentUtils.h"
using namespace mozilla::layers;
@ -204,15 +205,42 @@ public:
return NS_ERROR_FAILURE;
}
RefPtr<SourceSurface> opt = gfxPlatform::GetPlatform()
->ScreenReferenceDrawTarget()->OptimizeSourceSurface(snapshot);
if (!opt) {
RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
if (!data) {
return NS_ERROR_FAILURE;
}
RefPtr<DataSourceSurface> copy;
{
DataSourceSurface::ScopedMap read(data, DataSourceSurface::READ);
if (!read.IsMapped()) {
return NS_ERROR_FAILURE;
}
copy = Factory::CreateDataSourceSurfaceWithStride(data->GetSize(),
data->GetFormat(),
read.GetStride());
if (!copy) {
return NS_ERROR_FAILURE;
}
DataSourceSurface::ScopedMap write(copy, DataSourceSurface::WRITE);
if (!write.IsMapped()) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(read.GetStride() == write.GetStride());
MOZ_ASSERT(data->GetSize() == copy->GetSize());
MOZ_ASSERT(data->GetFormat() == copy->GetFormat());
memcpy(write.GetData(), read.GetData(),
write.GetStride() * copy->GetSize().height);
}
CairoImage::Data imageData;
imageData.mSize = opt->GetSize();
imageData.mSourceSurface = opt;
imageData.mSize = copy->GetSize();
imageData.mSourceSurface = copy;
RefPtr<CairoImage> image = new layers::CairoImage();
image->SetData(imageData);

5
dom/media/CanvasCaptureMediaStream.h

@ -6,6 +6,9 @@
#ifndef mozilla_dom_CanvasCaptureMediaStream_h_
#define mozilla_dom_CanvasCaptureMediaStream_h_
#include "DOMMediaStream.h"
#include "StreamBuffer.h"
namespace mozilla {
class DOMMediaStream;
class MediaStreamListener;
@ -13,7 +16,7 @@ class SourceMediaStream;
namespace layers {
class Image;
}
} // namespace layers
namespace dom {
class CanvasCaptureMediaStream;

5
gfx/thebes/gfxPrefs.h

@ -272,10 +272,7 @@ private:
DECL_GFX_PREF(Once, "image.cache.size", ImageCacheSize, int32_t, 5*1024*1024);
DECL_GFX_PREF(Once, "image.cache.timeweight", ImageCacheTimeWeight, int32_t, 500);
DECL_GFX_PREF(Live, "image.decode-immediately.enabled", ImageDecodeImmediatelyEnabled, bool, false);
DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, false);
DECL_GFX_PREF(Live, "image.high_quality_downscaling.enabled", ImageHQDownscalingEnabled, bool, false);
DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000);
DECL_GFX_PREF(Live, "image.high_quality_upscaling.max_size", ImageHQUpscalingMaxSize, uint32_t, 20971520);
DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, true);
DECL_GFX_PREF(Live, "image.infer-src-animation.threshold-ms", ImageInferSrcAnimationThresholdMS, uint32_t, 2000);
DECL_GFX_PREF(Once, "image.mem.decode_bytes_at_a_time", ImageMemDecodeBytesAtATime, uint32_t, 200000);
DECL_GFX_PREF(Live, "image.mem.discardable", ImageMemDiscardable, bool, false);

10
image/ClippedImage.cpp

@ -220,6 +220,16 @@ ClippedImage::GetFrame(uint32_t aWhichFrame,
return GetFrameInternal(mClip.Size(), Nothing(), aWhichFrame, aFlags);
}
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
ClippedImage::GetFrameAtSize(const IntSize& aSize,
uint32_t aWhichFrame,
uint32_t aFlags)
{
// XXX(seth): It'd be nice to support downscale-during-decode for this case,
// but right now we just fall back to the intrinsic size.
return GetFrame(aWhichFrame, aFlags);
}
already_AddRefed<SourceSurface>
ClippedImage::GetFrameInternal(const nsIntSize& aSize,
const Maybe<SVGImageContext>& aSVGContext,

4
image/ClippedImage.h

@ -37,6 +37,10 @@ public:
NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) override;
NS_IMETHOD_(already_AddRefed<SourceSurface>)
GetFrame(uint32_t aWhichFrame, uint32_t aFlags) override;
NS_IMETHOD_(already_AddRefed<SourceSurface>)
GetFrameAtSize(const gfx::IntSize& aSize,
uint32_t aWhichFrame,
uint32_t aFlags) override;
NS_IMETHOD_(bool) IsImageContainerAvailable(layers::LayerManager* aManager,
uint32_t aFlags) override;
NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)

24
image/DecodePool.cpp

@ -47,35 +47,37 @@ public:
static void Dispatch(RasterImage* aImage,
Progress aProgress,
const nsIntRect& aInvalidRect,
uint32_t aFlags)
SurfaceFlags aSurfaceFlags)
{
MOZ_ASSERT(aImage);
nsCOMPtr<nsIRunnable> worker =
new NotifyProgressWorker(aImage, aProgress, aInvalidRect, aFlags);
new NotifyProgressWorker(aImage, aProgress, aInvalidRect, aSurfaceFlags);
NS_DispatchToMainThread(worker);
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
mImage->NotifyProgress(mProgress, mInvalidRect, mFlags);
mImage->NotifyProgress(mProgress, mInvalidRect, mSurfaceFlags);
return NS_OK;
}
private:
NotifyProgressWorker(RasterImage* aImage, Progress aProgress,
const nsIntRect& aInvalidRect, uint32_t aFlags)
NotifyProgressWorker(RasterImage* aImage,
Progress aProgress,
const nsIntRect& aInvalidRect,
SurfaceFlags aSurfaceFlags)
: mImage(aImage)
, mProgress(aProgress)
, mInvalidRect(aInvalidRect)
, mFlags(aFlags)
, mSurfaceFlags(aSurfaceFlags)
{ }
nsRefPtr<RasterImage> mImage;
const Progress mProgress;
const nsIntRect mInvalidRect;
const uint32_t mFlags;
const SurfaceFlags mSurfaceFlags;
};
class NotifyDecodeCompleteWorker : public nsRunnable
@ -470,17 +472,17 @@ DecodePool::NotifyProgress(Decoder* aDecoder)
MOZ_ASSERT(aDecoder);
if (!NS_IsMainThread() ||
(aDecoder->GetFlags() & imgIContainer::FLAG_ASYNC_NOTIFY)) {
(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) {
NotifyProgressWorker::Dispatch(aDecoder->GetImage(),
aDecoder->TakeProgress(),
aDecoder->TakeInvalidRect(),
aDecoder->GetDecodeFlags());
aDecoder->GetSurfaceFlags());
return;
}
aDecoder->GetImage()->NotifyProgress(aDecoder->TakeProgress(),
aDecoder->TakeInvalidRect(),
aDecoder->GetDecodeFlags());
aDecoder->GetSurfaceFlags());
}
void
@ -489,7 +491,7 @@ DecodePool::NotifyDecodeComplete(Decoder* aDecoder)
MOZ_ASSERT(aDecoder);
if (!NS_IsMainThread() ||
(aDecoder->GetFlags() & imgIContainer::FLAG_ASYNC_NOTIFY)) {
(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) {
NotifyDecodeCompleteWorker::Dispatch(aDecoder);
return;
}

41
image/Decoder.cpp

@ -31,13 +31,11 @@ Decoder::Decoder(RasterImage* aImage)
, mFrameCount(0)
, mFailCode(NS_OK)
, mChunkCount(0)
, mFlags(0)
, mDecoderFlags(DefaultDecoderFlags())
, mSurfaceFlags(DefaultSurfaceFlags())
, mBytesDecoded(0)
, mInitialized(false)
, mMetadataDecode(false)
, mSendPartialInvalidations(false)
, mImageIsTransient(false)
, mFirstFrameDecode(false)
, mInFrame(false)
, mDataDone(false)
, mDecodeDone(false)
@ -238,12 +236,28 @@ Decoder::CompleteDecode()
// If this image wasn't animated and isn't a transient image, mark its frame
// as optimizable. We don't support optimizing animated images and
// optimizing transient images isn't worth it.
if (!HasAnimation() && !mImageIsTransient && mCurrentFrame) {
if (!HasAnimation() &&
!(mDecoderFlags & DecoderFlags::IMAGE_IS_TRANSIENT) &&
mCurrentFrame) {
mCurrentFrame->SetOptimizable();
}
}
}
nsresult
Decoder::SetTargetSize(const nsIntSize& aSize)
{
// Make sure the size is reasonable.
if (MOZ_UNLIKELY(aSize.width <= 0 || aSize.height <= 0)) {
return NS_ERROR_FAILURE;
}
// Create a downscaler that we'll filter our output through.
mDownscaler.emplace(aSize);
return NS_OK;
}
nsresult
Decoder::AllocateFrame(uint32_t aFrameNum,
const nsIntSize& aTargetSize,
@ -252,8 +266,8 @@ Decoder::AllocateFrame(uint32_t aFrameNum,
uint8_t aPaletteDepth)
{
mCurrentFrame = AllocateFrameInternal(aFrameNum, aTargetSize, aFrameRect,
GetDecodeFlags(), aFormat,
aPaletteDepth, mCurrentFrame.get());
aFormat, aPaletteDepth,
mCurrentFrame.get());
if (mCurrentFrame) {
// Gather the raw pointers the decoders will use.
@ -279,7 +293,6 @@ RawAccessFrameRef
Decoder::AllocateFrameInternal(uint32_t aFrameNum,
const nsIntSize& aTargetSize,
const nsIntRect& aFrameRect,
uint32_t aDecodeFlags,
SurfaceFormat aFormat,
uint8_t aPaletteDepth,
imgFrame* aPreviousFrame)
@ -307,8 +320,7 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
}
nsRefPtr<imgFrame> frame = new imgFrame();
bool nonPremult =
aDecodeFlags & imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
bool nonPremult = bool(mSurfaceFlags & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
if (NS_FAILED(frame->InitForDecoder(aTargetSize, aFrameRect, aFormat,
aPaletteDepth, nonPremult))) {
NS_WARNING("imgFrame::Init should succeed");
@ -325,9 +337,8 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
InsertOutcome outcome =
SurfaceCache::Insert(frame, ImageKey(mImage.get()),
RasterSurfaceKey(aTargetSize,
aDecodeFlags,
aFrameNum),
Lifetime::Persistent);
mSurfaceFlags,
aFrameNum));
if (outcome == InsertOutcome::FAILURE) {
// We couldn't insert the surface, almost certainly due to low memory. We
// treat this as a permanent error to help the system recover; otherwise,
@ -440,7 +451,7 @@ Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */,
// If we're not sending partial invalidations, then we send an invalidation
// here when the first frame is complete.
if (!mSendPartialInvalidations && !HasAnimation()) {
if (!ShouldSendPartialInvalidations() && !HasAnimation()) {
mInvalidRect.UnionRect(mInvalidRect,
gfx::IntRect(gfx::IntPoint(0, 0), GetSize()));
}
@ -457,7 +468,7 @@ Decoder::PostInvalidation(const nsIntRect& aRect,
// Record this invalidation, unless we're not sending partial invalidations
// or we're past the first frame.
if (mSendPartialInvalidations && !HasAnimation()) {
if (ShouldSendPartialInvalidations() && !HasAnimation()) {
mInvalidRect.UnionRect(mInvalidRect, aRect);
mCurrentFrame->ImageUpdated(aRectAtTargetSize.valueOr(aRect));
}

80
image/Decoder.h

@ -10,9 +10,12 @@
#include "RasterImage.h"
#include "mozilla/RefPtr.h"
#include "DecodePool.h"
#include "DecoderFlags.h"
#include "Downscaler.h"
#include "ImageMetadata.h"
#include "Orientation.h"
#include "SourceBuffer.h"
#include "SurfaceFlags.h"
namespace mozilla {
@ -110,19 +113,14 @@ public:
* If this decoder supports downscale-during-decode, sets the target size that
* this image should be decoded to.
*
* If this decoder *doesn't* support downscale-during-decode, returns
* NS_ERROR_NOT_AVAILABLE. If the provided size is unacceptable, returns
* another error.
* If the provided size is unacceptable, an error is returned.
*
* Returning NS_OK from this method is a promise that the decoder will decode
* the image to the requested target size unless it encounters an error.
*
* This must be called before Init() is called.
*/
virtual nsresult SetTargetSize(const nsIntSize& aSize)
{
return NS_ERROR_NOT_AVAILABLE;
}
nsresult SetTargetSize(const nsIntSize& aSize);
/**
* Set the requested sample size for this decoder. Used to implement the
@ -140,24 +138,6 @@ public:
*/
virtual void SetResolution(const gfx::IntSize& aResolution) { }
/**
* Set whether should send partial invalidations.
*
* If @aSend is true, we'll send partial invalidations when decoding the first
* frame of the image, so image notifications observers will be able to
* gradually draw in the image as it downloads.
*
* If @aSend is false (the default), we'll only send an invalidation when we
* complete the first frame.
*
* This must be called before Init() is called.
*/
void SetSendPartialInvalidations(bool aSend)
{
MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
mSendPartialInvalidations = aSend;
}
/**
* Set an iterator to the SourceBuffer which will feed data to this decoder.
*
@ -174,27 +154,21 @@ public:
}
/**
* Set whether this decoder is associated with a transient image. The decoder
* may choose to avoid certain optimizations that don't pay off for
* short-lived images in this case.
* Should this decoder send partial invalidations?
*/
void SetImageIsTransient(bool aIsTransient)
bool ShouldSendPartialInvalidations() const
{
MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
mImageIsTransient = aIsTransient;
return !(mDecoderFlags & DecoderFlags::IS_REDECODE);
}
/**
* Set whether we should stop decoding after the first frame.
* Should we stop decoding after the first frame?
*/
void SetIsFirstFrameDecode()
bool IsFirstFrameDecode() const
{
MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
mFirstFrameDecode = true;
return bool(mDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY);
}
bool IsFirstFrameDecode() const { return mFirstFrameDecode; }
size_t BytesDecoded() const { return mBytesDecoded; }
// The amount of time we've spent inside Write() so far for this decoder.
@ -258,9 +232,26 @@ public:
SEQUENTIAL // decode to final image immediately
};
void SetFlags(uint32_t aFlags) { mFlags = aFlags; }
uint32_t GetFlags() const { return mFlags; }
uint32_t GetDecodeFlags() const { return DecodeFlags(mFlags); }
/**
* Get or set the DecoderFlags that influence the behavior of this decoder.
*/
void SetDecoderFlags(DecoderFlags aDecoderFlags)
{
MOZ_ASSERT(!mInitialized);
mDecoderFlags = aDecoderFlags;
}
DecoderFlags GetDecoderFlags() const { return mDecoderFlags; }
/**
* Get or set the SurfaceFlags that select the kind of output this decoder
* will produce.
*/
void SetSurfaceFlags(SurfaceFlags aSurfaceFlags)
{
MOZ_ASSERT(!mInitialized);
mSurfaceFlags = aSurfaceFlags;
}
SurfaceFlags GetSurfaceFlags() const { return mSurfaceFlags; }
bool HasSize() const { return mImageMetadata.HasSize(); }
@ -408,12 +399,13 @@ protected:
RawAccessFrameRef AllocateFrameInternal(uint32_t aFrameNum,
const nsIntSize& aTargetSize,
const nsIntRect& aFrameRect,
uint32_t aDecodeFlags,
gfx::SurfaceFormat aFormat,
uint8_t aPaletteDepth,
imgFrame* aPreviousFrame);
protected:
Maybe<Downscaler> mDownscaler;
uint8_t* mImageData; // Pointer to image data in either Cairo or 8bit format
uint32_t mImageDataLength;
uint32_t* mColormap; // Current colormap to be used in Cairo format
@ -435,14 +427,12 @@ private:
TimeDuration mDecodeTime;
uint32_t mChunkCount;
uint32_t mFlags;
DecoderFlags mDecoderFlags;
SurfaceFlags mSurfaceFlags;
size_t mBytesDecoded;
bool mInitialized : 1;
bool mMetadataDecode : 1;
bool mSendPartialInvalidations : 1;
bool mImageIsTransient : 1;
bool mFirstFrameDecode : 1;
bool mInFrame : 1;
bool mDataDone : 1;
bool mDecodeDone : 1;

40
image/DecoderFactory.cpp

@ -134,34 +134,30 @@ DecoderFactory::CreateDecoder(DecoderType aType,
RasterImage* aImage,
SourceBuffer* aSourceBuffer,
const Maybe<IntSize>& aTargetSize,
uint32_t aFlags,
DecoderFlags aDecoderFlags,
SurfaceFlags aSurfaceFlags,
int aSampleSize,
const IntSize& aResolution,
bool aIsRedecode,
bool aImageIsTransient)
const IntSize& aResolution)
{
if (aType == DecoderType::UNKNOWN) {
return nullptr;
}
nsRefPtr<Decoder> decoder = GetDecoder(aType, aImage, aIsRedecode);
nsRefPtr<Decoder> decoder =
GetDecoder(aType, aImage, bool(aDecoderFlags & DecoderFlags::IS_REDECODE));
MOZ_ASSERT(decoder, "Should have a decoder now");
// Initialize the decoder.
decoder->SetMetadataDecode(false);
decoder->SetIterator(aSourceBuffer->Iterator());
decoder->SetFlags(aFlags);
decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY);
decoder->SetSurfaceFlags(aSurfaceFlags);
decoder->SetSampleSize(aSampleSize);
decoder->SetResolution(aResolution);
decoder->SetSendPartialInvalidations(!aIsRedecode);
decoder->SetImageIsTransient(aImageIsTransient);
decoder->SetIsFirstFrameDecode();
// Set a target size for downscale-during-decode if applicable.
if (aTargetSize) {
DebugOnly<nsresult> rv = decoder->SetTargetSize(*aTargetSize);
MOZ_ASSERT(nsresult(rv) != NS_ERROR_NOT_AVAILABLE,
"We're downscale-during-decode but decoder doesn't support it?");
MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?");
}
@ -177,7 +173,8 @@ DecoderFactory::CreateDecoder(DecoderType aType,
DecoderFactory::CreateAnimationDecoder(DecoderType aType,
RasterImage* aImage,
SourceBuffer* aSourceBuffer,
uint32_t aFlags,
DecoderFlags aDecoderFlags,
SurfaceFlags aSurfaceFlags,
const IntSize& aResolution)
{
if (aType == DecoderType::UNKNOWN) {
@ -194,9 +191,9 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
// Initialize the decoder.
decoder->SetMetadataDecode(false);
decoder->SetIterator(aSourceBuffer->Iterator());
decoder->SetFlags(aFlags);
decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::IS_REDECODE);
decoder->SetSurfaceFlags(aSurfaceFlags);
decoder->SetResolution(aResolution);
decoder->SetSendPartialInvalidations(false);
decoder->Init();
if (NS_FAILED(decoder->GetDecoderError())) {
@ -238,7 +235,7 @@ DecoderFactory::CreateMetadataDecoder(DecoderType aType,
/* static */ already_AddRefed<Decoder>
DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
SourceBuffer* aSourceBuffer,
uint32_t aFlags)
SurfaceFlags aSurfaceFlags)
{
if (aType == DecoderType::UNKNOWN) {
return nullptr;
@ -251,15 +248,20 @@ DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
// Initialize the decoder.
decoder->SetMetadataDecode(false);
decoder->SetIterator(aSourceBuffer->Iterator());
decoder->SetFlags(aFlags);
decoder->SetImageIsTransient(true);
// Anonymous decoders are always transient; we don't want to optimize surfaces
// or do any other expensive work that might be wasted.
DecoderFlags decoderFlags = DecoderFlags::IMAGE_IS_TRANSIENT;
// Without an image, the decoder can't store anything in the SurfaceCache, so
// callers will only be able to retrieve the most recent frame via
// Decoder::GetCurrentFrame(). That means that anonymous decoders should
// always be first-frame-only decoders, because nobody ever wants the *last*
// frame.
decoder->SetIsFirstFrameDecode();
decoderFlags |= DecoderFlags::FIRST_FRAME_ONLY;
decoder->SetDecoderFlags(decoderFlags);
decoder->SetSurfaceFlags(aSurfaceFlags);
decoder->Init();
if (NS_FAILED(decoder->GetDecoderError())) {
@ -284,7 +286,7 @@ DecoderFactory::CreateAnonymousMetadataDecoder(DecoderType aType,
// Initialize the decoder.
decoder->SetMetadataDecode(true);
decoder->SetIterator(aSourceBuffer->Iterator());
decoder->SetIsFirstFrameDecode();
decoder->SetDecoderFlags(DecoderFlags::FIRST_FRAME_ONLY);
decoder->Init();
if (NS_FAILED(decoder->GetDecoderError())) {

41
image/DecoderFactory.h

@ -7,9 +7,12 @@
#ifndef mozilla_image_DecoderFactory_h
#define mozilla_image_DecoderFactory_h
#include "DecoderFlags.h"
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/gfx/2D.h"
#include "nsCOMPtr.h"
#include "SurfaceFlags.h"
class nsACString;
@ -20,6 +23,10 @@ class Decoder;
class RasterImage;
class SourceBuffer;
/**
* The type of decoder; this is usually determined from a MIME type using
* DecoderFactory::GetDecoderType().
*/
enum class DecoderType
{
PNG,
@ -44,10 +51,6 @@ public:
* (If the image *is* animated, only the first frame will be decoded.) The
* decoder will send notifications to @aImage.
*
* XXX(seth): @aIsRedecode and @aImageIsTransient should really be part of
* @aFlags. This requires changes to the way that decoder flags work, though.
* See bug 1185800.
*
* @param aType Which type of decoder to create - JPEG, PNG, etc.
* @param aImage The image will own the decoder and which should receive
* notifications as decoding progresses.
@ -57,25 +60,23 @@ public:
* be scaled to during decoding. It's an error to specify
* a target size for a decoder type which doesn't support
* downscale-during-decode.
* @param aFlags Flags specifying what type of output the decoder should
* produce; see GetDecodeFlags() in RasterImage.h.
* @param aDecoderFlags Flags specifying the behavior of this decoder.
* @param aSurfaceFlags Flags specifying the type of output this decoder
* should produce.
* @param aSampleSize The sample size requested using #-moz-samplesize (or 0
* if none).
* @param aResolution The resolution requested using #-moz-resolution (or an
* empty rect if none).
* @param aIsRedecode Specify 'true' if this image has been decoded before.
* @param aImageIsTransient Specify 'true' if this image is transient.
*/
static already_AddRefed<Decoder>
CreateDecoder(DecoderType aType,
RasterImage* aImage,
SourceBuffer* aSourceBuffer,
const Maybe<gfx::IntSize>& aTargetSize,
uint32_t aFlags,
DecoderFlags aDecoderFlags,
SurfaceFlags aSurfaceFlags,
int aSampleSize,
const gfx::IntSize& aResolution,
bool aIsRedecode,
bool aImageIsTransient);
const gfx::IntSize& aResolution);
/**
* Creates and initializes a decoder for animated images of type @aType.
@ -86,8 +87,9 @@ public:
* notifications as decoding progresses.
* @param aSourceBuffer The SourceBuffer which the decoder will read its data
* from.
* @param aFlags Flags specifying what type of output the decoder should
* produce; see GetDecodeFlags() in RasterImage.h.
* @param aDecoderFlags Flags specifying the behavior of this decoder.
* @param aSurfaceFlags Flags specifying the type of output this decoder
* should produce.
* @param aResolution The resolution requested using #-moz-resolution (or an
* empty rect if none).
*/
@ -95,7 +97,8 @@ public:
CreateAnimationDecoder(DecoderType aType,
RasterImage* aImage,
SourceBuffer* aSourceBuffer,
uint32_t aFlags,
DecoderFlags aDecoderFlags,
SurfaceFlags aSurfaceFlags,
const gfx::IntSize& aResolution);
/**
@ -128,13 +131,13 @@ public:
* @param aType Which type of decoder to create - JPEG, PNG, etc.
* @param aSourceBuffer The SourceBuffer which the decoder will read its data
* from.
* @param aFlags Flags specifying what type of output the decoder should
* produce; see GetDecodeFlags() in RasterImage.h.
* @param aSurfaceFlags Flags specifying the type of output this decoder
* should produce.
*/
static already_AddRefed<Decoder>
CreateAnonymousDecoder(DecoderType aType,
SourceBuffer* aSourceBuffer,
uint32_t aFlags);
SurfaceFlags aSurfaceFlags);
/**
* Creates and initializes an anonymous metadata decoder (one which isn't
@ -145,8 +148,6 @@ public:
* @param aType Which type of decoder to create - JPEG, PNG, etc.
* @param aSourceBuffer The SourceBuffer which the decoder will read its data
* from.
* @param aFlags Flags specifying what type of output the decoder should
* produce; see GetDecodeFlags() in RasterImage.h.
*/
static already_AddRefed<Decoder>
CreateAnonymousMetadataDecoder(DecoderType aType,

42
image/DecoderFlags.h

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_image_DecoderFlags_h
#define mozilla_image_DecoderFlags_h
#include "mozilla/TypedEnumBits.h"
namespace mozilla {
namespace image {
/**
* Flags that influence decoder behavior. Note that these flags *don't*
* influence the logical content of the surfaces that the decoder generates, so
* they're not in a factor in SurfaceCache lookups and the like. These flags
* instead either influence which surfaces are generated at all or the tune the
* decoder's behavior for a particular scenario.
*/
enum class DecoderFlags : uint8_t
{
FIRST_FRAME_ONLY = 1 << 0,
IS_REDECODE = 1 << 1,
IMAGE_IS_TRANSIENT = 1 << 2,
ASYNC_NOTIFY = 1 << 3
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DecoderFlags)
/**
* @return the default set of decode flags.
*/
inline DecoderFlags
DefaultDecoderFlags()
{
return DecoderFlags();
}
} // namespace image
} // namespace mozilla
#endif // mozilla_image_DecoderFlags_h

45
image/Deinterlacer.cpp

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Downscaler.h"
namespace mozilla {
namespace image {
Deinterlacer::Deinterlacer(const nsIntSize& aImageSize)
: mImageSize(aImageSize)
, mBuffer(MakeUnique<uint8_t[]>(mImageSize.width *
mImageSize.height *
sizeof(uint32_t)))
{ }
uint32_t
Deinterlacer::RowSize() const
{
return mImageSize.width * sizeof(uint32_t);
}
uint8_t*
Deinterlacer::RowBuffer(uint32_t aRow)
{
uint32_t offset = aRow * RowSize();
MOZ_ASSERT(offset < mImageSize.width * mImageSize.height * sizeof(uint32_t),
"Row is outside of image");
return mBuffer.get() + offset;
}
void
Deinterlacer::PropagatePassToDownscaler(Downscaler& aDownscaler)
{
for (int32_t row = 0 ; row < mImageSize.height ; ++row) {
memcpy(aDownscaler.RowBuffer(), RowBuffer(row), RowSize());
aDownscaler.CommitRow();
}
}
} // namespace image
} // namespace mozilla

50
image/Deinterlacer.h

@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Deinterlacer is a utility class to allow Downscaler to work with interlaced
* images.
* Since Downscaler needs to receive rows in top-to-bottom or
* bottom-to-top order, it can't natively handle interlaced images, in which the
* rows arrive in an interleaved order. Deinterlacer solves this problem by
* acting as an intermediate buffer that records decoded rows. Unlike
* Downscaler, it allows the rows to be written in arbitrary order. After each
* pass, calling PropagatePassToDownscaler() will downscale every buffered row
* in a single operation. The rows remain in the buffer, so rows that were
* written in one pass will be included in subsequent passes.
*/
#ifndef mozilla_image_Deinterlacer_h
#define mozilla_image_Deinterlacer_h
#include "Downscaler.h"
namespace mozilla {
namespace image {
class Deinterlacer
{
public:
explicit Deinterlacer(const nsIntSize& aImageSize);
uint8_t* RowBuffer(uint32_t aRow);
void PropagatePassToDownscaler(Downscaler& aDownscaler);
private:
uint32_t RowSize() const;
nsIntSize mImageSize;
UniquePtr<uint8_t[]> mBuffer;
};
} // namespace image
} // namespace mozilla
#endif // mozilla_image_Deinterlacer_h

2
image/Downscaler.cpp

@ -287,5 +287,7 @@ Downscaler::DownscaleInputLine()
}
}
} // namespace image
} // namespace mozilla

1
image/Downscaler.h

@ -162,6 +162,7 @@ public:
#endif // MOZ_ENABLE_SKIA
} // namespace image
} // namespace mozilla

14
image/DynamicImage.cpp

@ -168,10 +168,18 @@ DynamicImage::GetFrame(uint32_t aWhichFrame,
uint32_t aFlags)
{
gfxIntSize size(mDrawable->Size());
return GetFrameAtSize(IntSize(size.width, size.height),
aWhichFrame,
aFlags);
}
NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
DynamicImage::GetFrameAtSize(const IntSize& aSize,
uint32_t aWhichFrame,
uint32_t aFlags)
{
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(IntSize(size.width, size.height),
SurfaceFormat::B8G8R8A8);
CreateOffscreenContentDrawTarget(aSize, SurfaceFormat::B8G8R8A8);
if (!dt) {
gfxWarning() <<
"DynamicImage::GetFrame failed in CreateOffscreenContentDrawTarget";
@ -179,7 +187,7 @@ DynamicImage::GetFrame(uint32_t aWhichFrame,
}
nsRefPtr<gfxContext> context = new gfxContext(dt);
auto result = Draw(context, size, ImageRegion::Create(size),
auto result = Draw(context, aSize, ImageRegion::Create(aSize),
aWhichFrame, GraphicsFilter::FILTER_NEAREST,
Nothing(), aFlags);

6
image/FrameAnimator.cpp

@ -281,7 +281,7 @@ FrameAnimator::GetCompositedFrame(uint32_t aFrameNum)
LookupResult result =
SurfaceCache::Lookup(ImageKey(mImage),
RasterSurfaceKey(mSize,
0, // Default decode flags.
DefaultSurfaceFlags(),
aFrameNum));
MOZ_ASSERT(!result || !result.DrawableRef()->GetIsPaletted(),
"About to return a paletted frame");
@ -332,7 +332,7 @@ DoCollectSizeOfCompositingSurfaces(const RawAccessFrameRef& aSurface,
{
// Concoct a SurfaceKey for this surface.
SurfaceKey key = RasterSurfaceKey(aSurface->GetImageSize(),
imgIContainer::DECODE_FLAGS_DEFAULT,
DefaultSurfaceFlags(),
/* aFrameNum = */ 0);
// Create a counter for this surface.
@ -374,7 +374,7 @@ FrameAnimator::GetRawFrame(uint32_t aFrameNum) const
LookupResult result =
SurfaceCache::Lookup(ImageKey(mImage),
RasterSurfaceKey(mSize,
0, // Default decode flags.
DefaultSurfaceFlags(),
aFrameNum));
return result ? result.DrawableRef()->RawAccessRef()<