Browse Source

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

- Bug 1187401 (Part 1) - Simplify the condition that determines whether we set RasterImage::mHasBeenDecoded. r=tn (69be36e7ef)
- Bug 1187401 (Part 2) - Eliminate the nsresult return value from RasterImage::SetMetadata, since it's not used anymore. r=tn (dc521c4b9f)
- Bug 1187401 (Part 3) - For consistency, call DoError if SetMetadata sees a negative size. r=tn (d9ca8ec91b)
- Bug 1207183 - micro-optimize removing work items from DecodePool's queues; r=seth (6bd2717e3a)
- No bug - Fix out-of-date comment in Decoder.cpp. r=me (54fdbbd444)
- Bug 1181324 - Eliminate the duplicate mRefCnt member in MultipartImage. r=seth (c4512a443e)
- Bug 1180105 - Do not leak the SourceSurface returned from imgIContainer::GetFrame in BlockUntilDecodedAndFinishObserving; r=seth (1cadbffc53)
- Bug 1181909 - Fix potential null dereference in NextPartObserver. r=tn (cfd8ad0119)
- Bug 108603 - Remove NS_IMPL_QUERY_INTERFACE_INHERITED0. r=mccr8, r=froydnj (4bfa6771fc)
- Bug 1159502 - Don't block onload for multipart images. r=tn (8b50eadf39)
- Bug 1200413 - Part 1: Re-write RefCountedInsideLambdaChecker to use captures instead of checking for DeclRef instances, r=ehsan (80ef99efe2)
- Bug 1200413 - Part 2: Make lambdas in ProgressTracker.cpp capture strong references, r=seth (9e4d96dffa)
- Bug 1194557 - Ensure that if the image was locked before RecoverFromLossOfFrames() was called, it's still locked afterwards. r=tn (ea4dc6ea9f)
- code style (ad3773ba42)
- Bug 1167590 - Mark imgRequestProxy::mListener as MOZ_UNSAFE_REF. r=seth (946ffaed8a)
- Bug 1148397 - Fix data race on imgRequest::mHadInsecureRedirect. r=tanvi (e73d0664f3)
- No bug - Tweak formatting of logging statement in imgRequest. r=me (cab2bcb014)
- Bug 1180126 - Read content disposition regardless of content type in imgRequest::PrepareForNewPart. r=tn (2934597743)
- Bug 1139225 - Followup - Remove duplicate multiPartChannel variable. (7f7f555a0b)
- Bug 1141398 - Do not always revalidate image cache entries for file URIs. r=tn (31d73cb508)
- Bug 1183563 - Fix incorrect mixed content warning after internal redirects. r=tanvi, r=seth (12a6c8a15f)
- Bug 1150127 - Stop leaking windows via imgCacheValidator. r=baku (a7809c5fa7)
- bits of Bug 1102048 (Part 20, imgLoader) (b2098c8a5a)
- (No bug) - Correct blatantly lying comment in imgLoader.cpp. r=me DONTBUILD (64c42a5b09)
- Bug 1160592 - Report image source size again in about:memory. r=dholbert (4e04cf3c3e)
- Add an assertion for the first argument of NewImageChannel, no bug (4c8f087a8f)
- Bug 1127534 - Remove assertion before creating a channel (r=sicking) (988692dc91)
- Bug 1175371 - Make VectorImage wait to deliver LOAD_COMPLETE until its size is available. r=dholbert (3c81e0daff)
- Bug 1181323 - Move nsSVGRenderingObserver's isupports/refcounting decl to subclasses, since one subclass (nsSVGFilterReference) already has its own redundant copy of the decl. r=dholbert (6171171c2c)
- Bug 1161722 - If we're shutting down, don't warn about untracked unlocked surfaces. r=dholbert (f7e18ce481)
- Bug 1170877 - Track how many times the SurfaceCache has overflowed and report it in about:memory. r=dholbert (884176cb1d)
- Bug 1161743 - Upgrade 'WARNING: Not expiration-tracking an unlocked surface' to an assertion. r=dholbert (9900169e7b)
- Bug 1167557 - Crash when a null surface is passed to SurfaceCache::Insert. r=dholbert (b3c4cf60aa)
- remove bypass cache not fonud either in FF nor TF (3ed4056a27)
- Missing bit Bug 1102048 (Part 25, header guards) - Make image/src files comply (cb8ed2428f)
- No bug - Remove obsolete comment in SourceBuffer.h. r=me (6e9c233448)
- coding style (94b7269690)
- Bug 1157065 - GFX: 2D: Add Loongson3 MMI helpers. r=jrmuizel (ebce946c91)
- reverto to FF52 and TFF settings (e147a8c7b5)
- Bug 1134599 - Fix rpi build target. r=jrmuizel, r=shuang (b9722f860c)
- Bug 1129147 - Part 1. Take CanvasPath into a separate file, to avoid circular dependency. r=roc (859bcad807)
- Bug 1129147 - Part 2. Path option to addHitRegion. r=ehsan r=gw280 (b2ab08a8a1)
- Bug 1206076: Use a specialized PersistentBufferProvider for Canvas2D when using a SkiaGL DrawTarget. r=jrmuizel (859589caf8)
- Bug 1188752 - Addendum: Make PersistentBufferProviderBasic constructor explicit. r=bustage on a CLOSED TREE (a27a4dc974)
- style (72a65dcb26)
- Bug 1198574 - Remove unnecessary argument for PersistentBufferProvider. r=bas (dca718bba8)
- Bug 1163124 - The initial value of the canvas filter property should be "none". r=roc (59df6a01d8)
master
roytam1 2 months ago
parent
commit
e7535dc94b
  1. 2
      b2g/app/b2g.js
  2. 24
      build/clang-plugin/clang-plugin.cpp
  3. 8
      build/clang-plugin/tests/TestNoRefcountedInsideLambdas.cpp
  4. 2
      dom/bindings/Bindings.conf
  5. 91
      dom/canvas/CanvasPath.h
  6. 30
      dom/canvas/CanvasRenderingContext2D.cpp
  7. 68
      dom/canvas/CanvasRenderingContext2D.h
  8. 1
      dom/canvas/moz.build
  9. 18
      dom/canvas/test/test_hitregion_event.html
  10. 6
      dom/system/gonk/AudioManager.cpp
  11. 1
      dom/webidl/CanvasRenderingContext2D.webidl
  12. 196
      gfx/2d/MMIHelpers.h
  13. 2
      gfx/2d/SourceSurfaceSkia.cpp
  14. 16
      gfx/2d/image_operations.cpp
  15. 4
      gfx/layers/Layers.cpp
  16. 4
      gfx/layers/PersistentBufferProvider.cpp
  17. 12
      gfx/layers/PersistentBufferProvider.h
  18. 2
      gfx/thebes/gfxPlatform.cpp
  19. 2
      image/DecodePool.cpp
  20. 5
      image/Decoder.cpp
  21. 5
      image/Decoder.h
  22. 37
      image/MultipartImage.cpp
  23. 2
      image/MultipartImage.h
  24. 4
      image/Orientation.h
  25. 12
      image/ProgressTracker.cpp
  26. 36
      image/RasterImage.cpp
  27. 10
      image/RasterImage.h
  28. 4
      image/SVGDocumentWrapper.h
  29. 9
      image/SourceBuffer.h
  30. 20
      image/SurfaceCache.cpp
  31. 86
      image/VectorImage.cpp
  32. 8
      image/VectorImage.h
  33. 68
      image/imgLoader.cpp
  34. 50
      image/imgRequest.cpp
  35. 10
      image/imgRequest.h
  36. 5
      image/imgRequestProxy.h
  37. 2
      image/moz.build
  38. 24
      image/test/mochitest/bug1180105-waiter.sjs
  39. 63
      image/test/mochitest/bug1180105.sjs
  40. 3
      image/test/mochitest/mochitest.ini
  41. 46
      image/test/mochitest/test_bug1180105.html
  42. 5
      layout/svg/nsSVGEffects.cpp
  43. 7
      layout/svg/nsSVGEffects.h
  44. 4
      modules/libpref/init/all.js
  45. 8
      xpcom/glue/nsISupportsImpl.h

2
b2g/app/b2g.js

@ -904,7 +904,7 @@ pref("devtools.debugger.unix-domain-socket", "/data/local/debugger-socket");
// falling back to Skia/software for smaller canvases
#ifdef MOZ_WIDGET_GONK
pref("gfx.canvas.azure.backends", "skia");
pref("gfx.canvas.azure.accelerated", true);
pref("gfx.canvas.azure.accelerated", false);
#endif
// Turn on dynamic cache size for Skia

24
build/clang-plugin/clang-plugin.cpp

@ -951,13 +951,7 @@ DiagnosticsMatcher::DiagnosticsMatcher() {
// lambda, where the declaration they reference is not inside the lambda.
// This excludes arguments and local variables, leaving only captured
// variables.
astMatcher.addMatcher(
lambdaExpr(hasDescendant(
declRefExpr(hasType(pointerType(pointee(isRefCounted()))),
to(decl().bind("decl")))
.bind("declref")),
unless(hasDescendant(decl(equalsBoundNode("decl"))))),
&refCountedInsideLambdaChecker);
astMatcher.addMatcher(lambdaExpr().bind("lambda"), &refCountedInsideLambdaChecker);
// Older clang versions such as the ones used on the infra recognize these
// conversions as 'operator _Bool', but newer clang versions recognize these
@ -1241,11 +1235,19 @@ void DiagnosticsMatcher::RefCountedInsideLambdaChecker::run(
"Refcounted variable %0 of type %1 cannot be captured by a lambda");
unsigned noteID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Note, "Please consider using a smart pointer");
const DeclRefExpr *declref = Result.Nodes.getNodeAs<DeclRefExpr>("declref");
const LambdaExpr *Lambda = Result.Nodes.getNodeAs<LambdaExpr>("lambda");
for (const LambdaCapture Capture : Lambda->captures()) {
if (Capture.capturesVariable()) {
QualType Pointee = Capture.getCapturedVar()->getType()->getPointeeType();
Diag.Report(declref->getLocStart(), errorID)
<< declref->getFoundDecl() << declref->getType()->getPointeeType();
Diag.Report(declref->getLocStart(), noteID);
if (!Pointee.isNull() && isClassRefCounted(Pointee)) {
Diag.Report(Capture.getLocation(), errorID)
<< Capture.getCapturedVar() << Pointee;
Diag.Report(Capture.getLocation(), noteID);
}
}
}
}
void DiagnosticsMatcher::ExplicitOperatorBoolChecker::run(

8
build/clang-plugin/tests/TestNoRefcountedInsideLambdas.cpp

@ -67,9 +67,9 @@ void foo() {
take(argsp);
take(localsp);
});
take([ptr](R* argptr) {
take([ptr](R* argptr) { // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
R* localptr;
ptr->method(); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
ptr->method();
argptr->method();
localptr->method();
});
@ -79,9 +79,9 @@ void foo() {
argsp->method();
localsp->method();
});
take([ptr](R* argptr) {
take([ptr](R* argptr) { // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
R* localptr;
take(ptr); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}}
take(ptr);
take(argptr);
take(localptr);
});

2
dom/bindings/Bindings.conf

@ -900,7 +900,7 @@ DOMInterfaces = {
'Path2D': {
'nativeType': 'mozilla::dom::CanvasPath',
'headerFile': 'CanvasRenderingContext2D.h'
'headerFile': 'CanvasPath.h'
},
'PeerConnectionImpl': {

91
dom/canvas/CanvasPath.h

@ -0,0 +1,91 @@
/* 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 CanvasPath_h
#define CanvasPath_h
#include "mozilla/Attributes.h"
#include "mozilla/RefPtr.h"
#include "nsWrapperCache.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/ErrorResult.h"
namespace mozilla {
namespace dom {
enum class CanvasWindingRule : uint32_t;
class SVGMatrix;
class CanvasPath final :
public nsWrapperCache
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPath)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
nsCOMPtr<nsISupports> GetParentObject() { return mParent; }
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
ErrorResult& rv);
static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
CanvasPath& aCanvasPath,
ErrorResult& rv);
static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
const nsAString& aPathString,
ErrorResult& rv);
void ClosePath();
void MoveTo(double x, double y);
void LineTo(double x, double y);
void QuadraticCurveTo(double cpx, double cpy, double x, double y);
void BezierCurveTo(double cp1x, double cp1y,
double cp2x, double cp2y,
double x, double y);
void ArcTo(double x1, double y1, double x2, double y2, double radius,
ErrorResult& error);
void Rect(double x, double y, double w, double h);
void Arc(double x, double y, double radius,
double startAngle, double endAngle, bool anticlockwise,
ErrorResult& error);
void Ellipse(double x, double y, double radiusX, double radiusY,
double rotation, double startAngle, double endAngle,
bool anticlockwise, ErrorResult& error);
void LineTo(const gfx::Point& aPoint);
void BezierTo(const gfx::Point& aCP1,
const gfx::Point& aCP2,
const gfx::Point& aCP3);
already_AddRefed<gfx::Path> GetPath(const CanvasWindingRule& aWinding,
const gfx::DrawTarget* aTarget) const;
explicit CanvasPath(nsISupports* aParent);
// already_AddRefed arg because the return value from Path::CopyToBuilder()
// is passed directly and we can't drop the only ref to have a raw pointer.
CanvasPath(nsISupports* aParent,
already_AddRefed<gfx::PathBuilder> aPathBuilder);
void AddPath(CanvasPath& aCanvasPath,
const Optional<NonNull<SVGMatrix>>& aMatrix);
private:
virtual ~CanvasPath() {}
nsCOMPtr<nsISupports> mParent;
static gfx::Float ToFloat(double aValue) { return gfx::Float(aValue); }
mutable RefPtr<gfx::Path> mPath;
mutable RefPtr<gfx::PathBuilder> mPathBuilder;
void EnsurePathBuilder() const;
};
} // namespace dom
} // namespace mozilla
#endif /* CanvasPath_h */

30
dom/canvas/CanvasRenderingContext2D.cpp

@ -101,6 +101,7 @@
#include "nsCCUncollectableMarker.h"
#include "nsWrapperCacheInlines.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
#include "mozilla/dom/CanvasPath.h"
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/SVGMatrix.h"
@ -1402,13 +1403,14 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
DemoteOldestContextIfNecessary();
mBufferProvider = nullptr;
#if USE_SKIA_GPU
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
#if USE_SKIA_GPU
if (glue && glue->GetGrContext() && glue->GetGLContext()) {
mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format);
if (mTarget) {
AddDemotableContext(this);
mBufferProvider = new PersistentBufferProviderBasic(mTarget);
} else {
printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
mode = RenderingMode::SoftwareBackendMode;
@ -3360,15 +3362,24 @@ CanvasRenderingContext2D::MeasureText(const nsAString& rawText,
void
CanvasRenderingContext2D::AddHitRegion(const HitRegionOptions& options, ErrorResult& error)
{
// check if the path is valid
EnsureUserSpacePath(CanvasWindingRule::Nonzero);
if(!mPath) {
RefPtr<gfx::Path> path;
if (options.mPath) {
path = options.mPath->GetPath(CanvasWindingRule::Nonzero, mTarget);
}
if (!path) {
// check if the path is valid
EnsureUserSpacePath(CanvasWindingRule::Nonzero);
path = mPath;
}
if(!path) {
error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
// get the bounds of the current path. They are relative to the canvas
mgfx::Rect bounds(mPath->GetBounds(mTarget->GetTransform()));
mgfx::Rect bounds(path->GetBounds(mTarget->GetTransform()));
if ((bounds.width == 0) || (bounds.height == 0) || !bounds.IsFinite()) {
// The specified region has no pixels.
error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
@ -3397,7 +3408,7 @@ CanvasRenderingContext2D::AddHitRegion(const HitRegionOptions& options, ErrorRes
RegionInfo info;
info.mId = options.mId;
info.mElement = options.mControl;
RefPtr<PathBuilder> pathBuilder = mPath->TransformedCopyToBuilder(mTarget->GetTransform());
RefPtr<PathBuilder> pathBuilder = path->TransformedCopyToBuilder(mTarget->GetTransform());
info.mPath = pathBuilder->Finish();
mHitRegionsOptions.InsertElementAt(0, info);
@ -5598,12 +5609,7 @@ CanvasRenderingContext2D::GetBufferProvider(LayerManager* aManager)
return nullptr;
}
mBufferProvider = aManager->CreatePersistentBufferProvider(mTarget->GetSize(), mTarget->GetFormat());
RefPtr<SourceSurface> surf = mTarget->Snapshot();
mTarget = mBufferProvider->GetDT(IntRect(IntPoint(), mTarget->GetSize()));
mTarget->CopySurface(surf, IntRect(IntPoint(), mTarget->GetSize()), IntPoint());
mBufferProvider = new PersistentBufferProviderBasic(mTarget);
return mBufferProvider;
}

68
dom/canvas/CanvasRenderingContext2D.h

@ -44,77 +44,12 @@ class StringOrCanvasGradientOrCanvasPattern;
class OwningStringOrCanvasGradientOrCanvasPattern;
class TextMetrics;
class CanvasFilterChainObserver;
class CanvasPath;
extern const mozilla::gfx::Float SIGMA_MAX;
template<typename T> class Optional;
class CanvasPath final :
public nsWrapperCache
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPath)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
nsCOMPtr<nsISupports> GetParentObject() { return mParent; }
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto);
static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
ErrorResult& rv);
static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
CanvasPath& aCanvasPath,
ErrorResult& rv);
static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
const nsAString& aPathString,
ErrorResult& rv);
void ClosePath();
void MoveTo(double x, double y);
void LineTo(double x, double y);
void QuadraticCurveTo(double cpx, double cpy, double x, double y);
void BezierCurveTo(double cp1x, double cp1y,
double cp2x, double cp2y,
double x, double y);
void ArcTo(double x1, double y1, double x2, double y2, double radius,
ErrorResult& error);
void Rect(double x, double y, double w, double h);
void Arc(double x, double y, double radius,
double startAngle, double endAngle, bool anticlockwise,
ErrorResult& error);
void Ellipse(double x, double y, double radiusX, double radiusY,
double rotation, double startAngle, double endAngle,
bool anticlockwise, ErrorResult& error);
void LineTo(const gfx::Point& aPoint);
void BezierTo(const gfx::Point& aCP1,
const gfx::Point& aCP2,
const gfx::Point& aCP3);
already_AddRefed<gfx::Path> GetPath(const CanvasWindingRule& aWinding,
const gfx::DrawTarget* aTarget) const;
explicit CanvasPath(nsISupports* aParent);
// already_AddRefed arg because the return value from Path::CopyToBuilder()
// is passed directly and we can't drop the only ref to have a raw pointer.
CanvasPath(nsISupports* aParent,
already_AddRefed<gfx::PathBuilder> aPathBuilder);
void AddPath(CanvasPath& aCanvasPath,
const Optional<NonNull<SVGMatrix>>& aMatrix);
private:
virtual ~CanvasPath() {}
nsCOMPtr<nsISupports> mParent;
static gfx::Float ToFloat(double aValue) { return gfx::Float(aValue); }
mutable RefPtr<gfx::Path> mPath;
mutable RefPtr<gfx::PathBuilder> mPathBuilder;
void EnsurePathBuilder() const;
};
struct CanvasBidiProcessor;
class CanvasRenderingContext2DUserData;
class CanvasDrawObserver;
@ -977,6 +912,7 @@ protected:
fillRule(mozilla::gfx::FillRule::FILL_WINDING),
lineCap(mozilla::gfx::CapStyle::BUTT),
lineJoin(mozilla::gfx::JoinStyle::MITER_OR_BEVEL),
filterString(MOZ_UTF16("none")),
imageSmoothingEnabled(true),
fontExplicitLanguage(false)
{ }

1
dom/canvas/moz.build

@ -28,6 +28,7 @@ EXPORTS.mozilla.ipc += [
EXPORTS.mozilla.dom += [
'CanvasGradient.h',
'CanvasPath.h',
'CanvasPattern.h',
'CanvasRenderingContext2D.h',
'CanvasUtils.h',

18
dom/canvas/test/test_hitregion_event.html

@ -32,16 +32,29 @@ SpecialPowers.pushPrefEnv({"set": [["canvas.hitregions.enabled", true]]}, functi
ctx.rect(20, 20, 100, 75);
ctx.fill();
ctx.addHitRegion({id: "a"});
ctx.beginPath();
ctx.fillStyle = "red";
ctx.rect(60, 40, 100, 75);
ctx.fill();
ctx.addHitRegion({id: "b"});
var mypath = new Path2D();
mypath.rect(80, 60, 10, 10);
ctx.beginPath();
ctx.fillStyle = "yellow";
ctx.rect(80, 60, 10, 10);
ctx.fill();
ctx.addHitRegion({id: "c"});
ctx.addHitRegion({id: "c", path: mypath});
ctx.beginPath();
ctx.fillStyle = "green";
ctx.rect(60, 60, 10, 10); // This region is on purpose not the hit region
ctx.fill();
var mypath = new Path2D();
mypath.rect(70, 30, 10, 10);
ctx.addHitRegion({id: "d", path: mypath});
synthesizeMouse(input, 25,25, {type: "mousedown"});
is(regionId, "a", "Hit region a", ". Found: " + regionId);
@ -55,6 +68,9 @@ SpecialPowers.pushPrefEnv({"set": [["canvas.hitregions.enabled", true]]}, functi
synthesizeMouse(input, 85,65, {type: "mousedown"});
is(regionId, "c", "Hit region c", ". Found: " + regionId);
synthesizeMouse(input, 75,35, {type: "mousedown"});
is(regionId, "d", "Hit region d", ". Found: " + regionId);
ctx.removeHitRegion("c");
synthesizeMouse(input, 85,65, {type: "mousedown"});
is(regionId, "b", "Hit region b", ". Found: " + regionId);

6
dom/system/gonk/AudioManager.cpp

@ -81,10 +81,14 @@ static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
};
// A bitwise variable for recording what kind of headset is attached.
static int sHeadsetState;
#if defined(MOZ_B2G_BT) || ANDROID_VERSION >= 17
static bool sBluetoothA2dpEnabled;
#endif
static const int kBtSampleRate = 8000;
static bool sSwitchDone = true;
#ifdef MOZ_B2G_BT
static bool sA2dpSwitchDone = true;
#endif
namespace mozilla {
namespace dom {
@ -216,6 +220,7 @@ static void ProcessDelayedAudioRoute(SwitchState aState)
sSwitchDone = true;
}
#ifdef MOZ_B2G_BT
static void ProcessDelayedA2dpRoute(audio_policy_dev_state_t aState, const nsCString aAddress)
{
if (sA2dpSwitchDone)
@ -228,6 +233,7 @@ static void ProcessDelayedA2dpRoute(audio_policy_dev_state_t aState, const nsCSt
AudioSystem::setParameters(0, cmd);
sA2dpSwitchDone = true;
}
#endif
NS_IMPL_ISUPPORTS(AudioManager, nsIAudioManager, nsIObserver)

1
dom/webidl/CanvasRenderingContext2D.webidl

@ -21,6 +21,7 @@ dictionary ContextAttributes2D {
};
dictionary HitRegionOptions {
Path2D? path = null;
DOMString id = "";
Element? control = null;
};

196
gfx/2d/MMIHelpers.h

@ -0,0 +1,196 @@
/*
============================================================================
Name : MMIHelpers.h
Author : Heiher <r@hev.cc>
Version : 0.0.1
Copyright : Copyright (c) 2015 everyone.
Description : The helpers for x86 SSE to Loongson MMI.
============================================================================
*/
#ifndef __MMI_HELPERS_H__
#define __MMI_HELPERS_H__
#define __mm_packxxxx(_f, _D, _d, _s, _t) \
#_f" %["#_t"], %["#_d"h], %["#_s"h] \n\t" \
#_f" %["#_D"l], %["#_d"l], %["#_s"l] \n\t" \
"punpckhwd %["#_D"h], %["#_D"l], %["#_t"] \n\t" \
"punpcklwd %["#_D"l], %["#_D"l], %["#_t"] \n\t"
#define _mm_or(_D, _d, _s) \
"or %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"or %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
#define _mm_xor(_D, _d, _s) \
"xor %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"xor %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
#define _mm_and(_D, _d, _s) \
"and %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"and %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: pandn */
#define _mm_pandn(_D, _d, _s) \
"pandn %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"pandn %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: pshuflw */
#define _mm_pshuflh(_D, _d, _s) \
"mov.d %["#_D"h], %["#_d"h] \n\t" \
"pshufh %["#_D"l], %["#_d"l], %["#_s"] \n\t"
/* SSE: psllw (bits) */
#define _mm_psllh(_D, _d, _s) \
"psllh %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"psllh %["#_D"l], %["#_d"l], %["#_s"] \n\t"
/* SSE: pslld (bits) */
#define _mm_psllw(_D, _d, _s) \
"psllw %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"psllw %["#_D"l], %["#_d"l], %["#_s"] \n\t"
/* SSE: psllq (bits) */
#define _mm_pslld(_D, _d, _s) \
"dsll %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"dsll %["#_D"l], %["#_d"l], %["#_s"] \n\t"
/* SSE: pslldq (bytes) */
#define _mm_psllq(_D, _d, _s, _s64, _tf) \
"subu %["#_tf"], %["#_s64"], %["#_s"] \n\t" \
"dsrl %["#_tf"], %["#_d"l], %["#_tf"] \n\t" \
"dsll %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"dsll %["#_D"l], %["#_d"l], %["#_s"] \n\t" \
"or %["#_D"h], %["#_D"h], %["#_tf"] \n\t"
/* SSE: psrlw (bits) */
#define _mm_psrlh(_D, _d, _s) \
"psrlh %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"psrlh %["#_D"l], %["#_d"l], %["#_s"] \n\t"
/* SSE: psrld (bits) */
#define _mm_psrlw(_D, _d, _s) \
"psrlw %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"psrlw %["#_D"l], %["#_d"l], %["#_s"] \n\t"
/* SSE: psrlq (bits) */
#define _mm_psrld(_D, _d, _s) \
"dsrl %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"dsrl %["#_D"l], %["#_d"l], %["#_s"] \n\t"
/* SSE: psrldq (bytes) */
#define _mm_psrlq(_D, _d, _s, _s64, _tf) \
"subu %["#_tf"], %["#_s64"], %["#_s"] \n\t" \
"dsll %["#_tf"], %["#_d"h], %["#_tf"] \n\t" \
"dsrl %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"dsrl %["#_D"l], %["#_d"l], %["#_s"] \n\t" \
"or %["#_D"l], %["#_D"l], %["#_tf"] \n\t"
/* SSE: psrad */
#define _mm_psraw(_D, _d, _s) \
"psraw %["#_D"h], %["#_d"h], %["#_s"] \n\t" \
"psraw %["#_D"l], %["#_d"l], %["#_s"] \n\t"
/* SSE: paddb */
#define _mm_paddb(_D, _d, _s) \
"paddb %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"paddb %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: paddw */
#define _mm_paddh(_D, _d, _s) \
"paddh %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"paddh %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: paddd */
#define _mm_paddw(_D, _d, _s) \
"paddw %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"paddw %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: paddq */
#define _mm_paddd(_D, _d, _s) \
"dadd %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"dadd %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: psubw */
#define _mm_psubh(_D, _d, _s) \
"psubh %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"psubh %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: psubd */
#define _mm_psubw(_D, _d, _s) \
"psubw %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"psubw %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: pmaxub */
#define _mm_pmaxub(_D, _d, _s) \
"pmaxub %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"pmaxub %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: pmullw */
#define _mm_pmullh(_D, _d, _s) \
"pmullh %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"pmullh %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: pmulhw */
#define _mm_pmulhh(_D, _d, _s) \
"pmulhh %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"pmulhh %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: pmuludq */
#define _mm_pmuluw(_D, _d, _s) \
"pmuluw %["#_D"h], %["#_d"h], %["#_s"h] \n\t" \
"pmuluw %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: packsswb */
#define _mm_packsshb(_D, _d, _s, _t) \
__mm_packxxxx(packsshb, _D, _d, _s, _t)
/* SSE: packssdw */
#define _mm_packsswh(_D, _d, _s, _t) \
__mm_packxxxx(packsswh, _D, _d, _s, _t)
/* SSE: packuswb */
#define _mm_packushb(_D, _d, _s, _t) \
__mm_packxxxx(packushb, _D, _d, _s, _t)
/* SSE: punpcklbw */
#define _mm_punpcklbh(_D, _d, _s) \
"punpckhbh %["#_D"h], %["#_d"l], %["#_s"l] \n\t" \
"punpcklbh %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: punpcklwd */
#define _mm_punpcklhw(_D, _d, _s) \
"punpckhhw %["#_D"h], %["#_d"l], %["#_s"l] \n\t" \
"punpcklhw %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: punpckldq */
#define _mm_punpcklwd(_D, _d, _s) \
"punpckhwd %["#_D"h], %["#_d"l], %["#_s"l] \n\t" \
"punpcklwd %["#_D"l], %["#_d"l], %["#_s"l] \n\t"
/* SSE: punpcklqdq */
#define _mm_punpckldq(_D, _d, _s) \
"mov.d %["#_D"h], %["#_s"l] \n\t" \
"mov.d %["#_D"l], %["#_d"l] \n\t"
/* SSE: punpckhbw */
#define _mm_punpckhbh(_D, _d, _s) \
"punpcklbh %["#_D"l], %["#_d"h], %["#_s"h] \n\t" \
"punpckhbh %["#_D"h], %["#_d"h], %["#_s"h] \n\t"
/* SSE: punpckhwd */
#define _mm_punpckhhw(_D, _d, _s) \
"punpcklhw %["#_D"l], %["#_d"h], %["#_s"h] \n\t" \
"punpckhhw %["#_D"h], %["#_d"h], %["#_s"h] \n\t"
/* SSE: punpckhdq */
#define _mm_punpckhwd(_D, _d, _s) \
"punpcklwd %["#_D"l], %["#_d"h], %["#_s"h] \n\t" \
"punpckhwd %["#_D"h], %["#_d"h], %["#_s"h] \n\t"
/* SSE: punpckhqdq */
#define _mm_punpckhdq(_D, _d, _s) \
"mov.d %["#_D"l], %["#_d"h] \n\t" \
"mov.d %["#_D"h], %["#_s"h] \n\t"
#endif /* __MMI_HELPERS_H__ */

2
gfx/2d/SourceSurfaceSkia.cpp

@ -101,6 +101,7 @@ SourceSurfaceSkia::InitFromTexture(DrawTargetSkia* aOwner,
SurfaceFormat aFormat)
{
MOZ_ASSERT(aOwner, "null GrContext");
#ifdef USE_SKIA_GPU
GrBackendTextureDesc skiaTexGlue;
mSize.width = skiaTexGlue.fWidth = aSize.width;
mSize.height = skiaTexGlue.fHeight = aSize.height;
@ -117,6 +118,7 @@ SourceSurfaceSkia::InitFromTexture(DrawTargetSkia* aOwner,
mBitmap.setPixelRef(texRef);
mFormat = aFormat;
mStride = mBitmap.rowBytes();
#endif
mDrawTarget = aOwner;
return true;

16
gfx/2d/image_operations.cpp

@ -168,15 +168,19 @@ ImageOperations::ResizeMethod ResizeMethodToAlgorithmMethod(
// GPU-acceleration in the cases where it is possible. So now we just
// pick the appropriate software method for each resize quality.
switch (method) {
// Users of RESIZE_GOOD are willing to trade a lot of quality to
// get speed, allowing the use of linear resampling to get hardware
// acceleration (SRB). Hence any of our "good" software filters
// will be acceptable, and we use the fastest one, Hamming-1.
case ImageOperations::RESIZE_GOOD:
// In visual tests we see that Hamming-1 is not as good as
// Lanczos-2, however it is about 40% faster, and Lanczos-2 itself is
// Users of RESIZE_BETTER are willing to trade some quality in order
// to improve performance, but are guaranteed not to devolve to a linear
// resampling. In visual tests we see that Hamming-1 is not as good as
// Lanczos-2, however it is about 40% faster and Lanczos-2 itself is
// about 30% faster than Lanczos-3. The use of Hamming-1 has been deemed
// an unacceptable trade-off between quality and speed due to the limited
// pixel space it operates in (<50%) before switching to HQ scaling
// becomes necessary to retain the fidelity of images.
// an acceptable trade-off between quality and speed.
case ImageOperations::RESIZE_BETTER:
return ImageOperations::RESIZE_LANCZOS2;
return ImageOperations::RESIZE_HAMMING1;
default:
return ImageOperations::RESIZE_LANCZOS3;
}

4
gfx/layers/Layers.cpp

@ -165,12 +165,12 @@ LayerManager::CreatePersistentBufferProvider(const mozilla::gfx::IntSize &aSize,
mozilla::gfx::SurfaceFormat aFormat)
{
RefPtr<PersistentBufferProviderBasic> bufferProvider =
new PersistentBufferProviderBasic(this, aSize, aFormat,
new PersistentBufferProviderBasic(aSize, aFormat,
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
if (!bufferProvider->IsValid()) {
bufferProvider =
new PersistentBufferProviderBasic(this, aSize, aFormat,
new PersistentBufferProviderBasic(aSize, aFormat,
gfxPlatform::GetPlatform()->GetFallbackCanvasBackend());
}

4
gfx/layers/PersistentBufferProvider.cpp

@ -16,8 +16,8 @@ using namespace gfx;
namespace layers {
PersistentBufferProviderBasic::PersistentBufferProviderBasic(LayerManager* aManager, gfx::IntSize aSize,
gfx::SurfaceFormat aFormat, gfx::BackendType aBackend)
PersistentBufferProviderBasic::PersistentBufferProviderBasic(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aBackend)
{
mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(aBackend, aSize, aFormat);
}

12
gfx/layers/PersistentBufferProvider.h

@ -7,7 +7,7 @@
#define MOZILLA_GFX_PersistentBUFFERPROVIDER_H
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/RefPtr.h" // for RefPtr, TemporaryRef, etc
#include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/gfx/Types.h"
@ -57,8 +57,9 @@ class PersistentBufferProviderBasic : public PersistentBufferProvider
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic)
PersistentBufferProviderBasic(LayerManager* aManager, gfx::IntSize aSize,
gfx::SurfaceFormat aFormat, gfx::BackendType aBackend);
PersistentBufferProviderBasic(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
gfx::BackendType aBackend);
explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget) : mDrawTarget(aTarget) {}
bool IsValid() { return !!mDrawTarget; }
virtual LayersBackend GetType() { return LayersBackend::LAYERS_BASIC; }
@ -69,6 +70,7 @@ private:
RefPtr<gfx::DrawTarget> mDrawTarget;
};
}
}
} // namespace layers
} // namespace mozilla
#endif

2
gfx/thebes/gfxPlatform.cpp

@ -1104,6 +1104,7 @@ void
gfxPlatform::InitializeSkiaCacheLimits()
{
if (UseAcceleratedSkiaCanvas()) {
#ifdef USE_SKIA_GPU
bool usingDynamicCache = gfxPrefs::CanvasSkiaGLDynamicCache();
int cacheItemLimit = gfxPrefs::CanvasSkiaGLCacheItems();
int cacheSizeLimit = gfxPrefs::CanvasSkiaGLCacheSize();
@ -1125,7 +1126,6 @@ gfxPlatform::InitializeSkiaCacheLimits()
printf_stderr("Determined SkiaGL cache limits: Size %i, Items: %i\n", cacheSizeLimit, cacheItemLimit);
#endif
#ifdef USE_SKIA_GPU
mSkiaGlue->GetGrContext()->setResourceCacheLimits(cacheItemLimit, cacheSizeLimit);
#endif
}

2
image/DecodePool.cpp

@ -246,7 +246,7 @@ private:
{
Work work;
work.mType = Work::Type::DECODE;
work.mDecoder = aQueue.LastElement();
work.mDecoder = aQueue.LastElement().forget();
aQueue.RemoveElementAt(aQueue.Length() - 1);
return work;

5
image/Decoder.cpp

@ -431,9 +431,10 @@ Decoder::PostIsAnimated(int32_t aFirstFrameTimeout)
}
void
Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */,
Decoder::PostFrameStop(Opacity aFrameOpacity
/* = Opacity::SOME_TRANSPARENCY */,
DisposalMethod aDisposalMethod
/* = DisposalMethod::KEEP */,
/* = DisposalMethod::KEEP */,
int32_t aTimeout /* = 0 */,
BlendMethod aBlendMethod /* = BlendMethod::OVER */)
{

5
image/Decoder.h

@ -196,7 +196,6 @@ public:
bool HasDecoderError() const { return NS_FAILED(mFailCode); }
bool ShouldReportError() const { return mShouldReportError; }
nsresult GetDecoderError() const { return mFailCode; }
void PostResizeError() { PostDataError(); }
/// Did we finish decoding enough that calling Decode() again would be useless?
bool GetDecodeDone() const
@ -205,10 +204,6 @@ public:
HasError() || mDataDone;
}
/// Did we finish decoding enough to set |RasterImage::mHasBeenDecoded|?
// XXX(seth): This will be removed in bug 1187401.
bool GetDecodeTotallyDone() const { return mDecodeDone && !IsMetadataDecode(); }
/// Are we in the middle of a frame right now? Used for assertions only.
bool InFrame() const { return mInFrame; }

37
image/MultipartImage.cpp

@ -38,10 +38,16 @@ public:
void BlockUntilDecodedAndFinishObserving()
{
// Use GetFrame() to block until our image finishes decoding.
mImage->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
FinishObserving();
nsRefPtr<SourceSurface> surface =
mImage->GetFrame(imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
// GetFrame() should've sent synchronous notifications that would have
// caused us to call FinishObserving() (and null out mImage) already. If for
// some reason it didn't, we should do so here.
if (mImage) {
FinishObserving();
}
}
virtual void Notify(int32_t aType,
@ -129,9 +135,7 @@ MultipartImage::~MultipartImage()
mTracker->ResetImage();
}
NS_IMPL_QUERY_INTERFACE_INHERITED0(MultipartImage, ImageWrapper)
NS_IMPL_ADDREF(MultipartImage)
NS_IMPL_RELEASE(MultipartImage)
NS_IMPL_ISUPPORTS_INHERITED0(MultipartImage, ImageWrapper)
void
MultipartImage::BeginTransitionToPart(Image* aNextPart)
@ -154,7 +158,16 @@ MultipartImage::BeginTransitionToPart(Image* aNextPart)
mNextPart->IncrementAnimationConsumers();
}
void MultipartImage::FinishTransition()
static Progress
FilterProgress(Progress aProgress)
{
// Filter out onload blocking notifications, since we don't want to block
// onload for multipart images.
return aProgress & ~(FLAG_ONLOAD_BLOCKED | FLAG_ONLOAD_UNBLOCKED);
}
void
MultipartImage::FinishTransition()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mNextPart, "Should have a next part here");
@ -169,7 +182,8 @@ void MultipartImage::FinishTransition()
mTracker->ResetForNewRequest();
nsRefPtr<ProgressTracker> currentPartTracker =
InnerImage()->GetProgressTracker();
mTracker->SyncNotifyProgress(currentPartTracker->GetProgress());
mTracker
->SyncNotifyProgress(FilterProgress(currentPartTracker->GetProgress()));
return;
}
@ -189,8 +203,9 @@ void MultipartImage::FinishTransition()
// Finally, send all the notifications for the new current part and send a
// FRAME_UPDATE notification so that observers know to redraw.
mTracker->SyncNotifyProgress(newCurrentPartTracker->GetProgress(),
GetMaxSizedIntRect());
mTracker
->SyncNotifyProgress(FilterProgress(newCurrentPartTracker->GetProgress()),
GetMaxSizedIntRect());
}
already_AddRefed<imgIContainer>

2
image/MultipartImage.h

@ -25,7 +25,7 @@ class MultipartImage
{
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(MultipartImage)
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS_INHERITED
void BeginTransitionToPart(Image* aNextPart);

4
image/Orientation.h

@ -56,7 +56,7 @@ struct Orientation
Flip flip;
};
}
}
} // namespace image
} // namespace mozilla
#endif // mozilla_image_Orientation_h

12
image/ProgressTracker.cpp

@ -441,13 +441,14 @@ void
ProgressTracker::AddObserver(IProgressObserver* aObserver)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<IProgressObserver> observer = aObserver;
mObservers.Write([=](ObserverTable* aTable) {
MOZ_ASSERT(!aTable->Get(aObserver, nullptr),
MOZ_ASSERT(!aTable->Get(observer, nullptr),
"Adding duplicate entry for image observer");
WeakPtr<IProgressObserver> weakPtr = aObserver;
aTable->Put(aObserver, weakPtr);
WeakPtr<IProgressObserver> weakPtr = observer.get();
aTable->Put(observer, weakPtr);
});
}
@ -455,11 +456,12 @@ bool
ProgressTracker::RemoveObserver(IProgressObserver* aObserver)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<IProgressObserver> observer = aObserver;
// Remove the observer from the list.
bool removed = mObservers.Write([=](ObserverTable* aTable) {
bool removed = aTable->Get(aObserver, nullptr);
aTable->Remove(aObserver);
bool removed = aTable->Get(observer, nullptr);
aTable->Remove(observer);
return removed;
});

36
image/RasterImage.cpp

@ -819,20 +819,22 @@ RasterImage::OnAddedFrame(uint32_t aNewFrameCount,
}
}
nsresult
void
RasterImage::SetMetadata(const ImageMetadata& aMetadata,
bool aFromMetadataDecode)
{
MOZ_ASSERT(NS_IsMainThread());
if (mError) {
return NS_ERROR_FAILURE;
return;
}
if (aMetadata.HasSize()) {
IntSize size = aMetadata.GetSize();
if (size.width < 0 || size.height < 0) {
return NS_ERROR_INVALID_ARG;
NS_WARNING("Image has negative intrinsic size");
DoError();
return;
}
MOZ_ASSERT(aMetadata.HasOrientation());
@ -843,7 +845,7 @@ RasterImage::SetMetadata(const ImageMetadata& aMetadata,
NS_WARNING("Image changed size or orientation on redecode! "
"This should not happen!");
DoError();
return NS_ERROR_UNEXPECTED;
return;
}
// Set the size and flag that we have it.
@ -887,8 +889,6 @@ RasterImage::SetMetadata(const ImageMetadata& aMetadata,
Set("hotspotX", intwrapx);
Set("hotspotY", intwrapy);
}
return NS_OK;
}
NS_IMETHODIMP
@ -1074,7 +1074,7 @@ RasterImage::NotifyForLoadEvent(Progress aProgress)
if (mError) {
aProgress |= FLAG_HAS_ERROR;
}
// Notify our listeners, which will fire this image's load event.
NotifyProgress(aProgress);
}
@ -1374,6 +1374,11 @@ RasterImage::RecoverFromInvalidFrames(const IntSize& aSize, uint32_t aFlags)
// Discard all existing frames, since they're probably all now invalid.
SurfaceCache::RemoveImage(ImageKey(this));
// Relock the image if it's supposed to be locked.
if (mLockCount > 0) {
SurfaceCache::LockImage(ImageKey(this));
}
// Animated images require some special handling, because we normally require
// that they never be discarded.
if (mAnim) {
@ -1707,22 +1712,20 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder)
MOZ_ASSERT(aDecoder->HasError() || !aDecoder->InFrame(),
"Finalizing a decoder in the middle of a frame");
bool wasMetadata = aDecoder->IsMetadataDecode();
bool done = aDecoder->GetDecodeDone();
// If the decoder detected an error, log it to the error console.
if (aDecoder->ShouldReportError() && !aDecoder->WasAborted()) {
ReportDecoderError(aDecoder);
}
// Record all the metadata the decoder gathered about this image.
nsresult rv = SetMetadata(aDecoder->GetImageMetadata(),
aDecoder->IsMetadataDecode());
if (NS_FAILED(rv)) {
aDecoder->PostResizeError();
}
SetMetadata(aDecoder->GetImageMetadata(), wasMetadata);
MOZ_ASSERT(mError || mHasSize || !aDecoder->HasSize(),
"Should have handed off size by now");
"SetMetadata should've gotten a size");
if (aDecoder->GetDecodeTotallyDone() && !mError) {
if (!wasMetadata && aDecoder->GetDecodeDone() && !aDecoder->WasAborted()) {
// Flag that we've been decoded before.
mHasBeenDecoded = true;
if (mAnim) {
@ -1735,9 +1738,6 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder)
aDecoder->TakeInvalidRect(),
aDecoder->GetSurfaceFlags());
bool wasMetadata = aDecoder->IsMetadataDecode();
bool done = aDecoder->GetDecodeDone();
if (!wasMetadata && aDecoder->ChunkCount()) {
/*Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS,
aDecoder->ChunkCount());*/

10
image/RasterImage.h

@ -325,7 +325,7 @@ private:
* @param aFromMetadataDecode True if this metadata came from a metadata
* decode; false if it came from a full decode.
*/
nsresult SetMetadata(const ImageMetadata& aMetadata, bool aFromMetadataDecode);
void SetMetadata(const ImageMetadata& aMetadata, bool aFromMetadataDecode);
/**
* In catastrophic circumstances like a GPU driver crash, the contents of our
@ -347,10 +347,10 @@ private: // data
/// If this has a value, we're waiting for SetSize() to send the load event.
Maybe<Progress> mLoadProgress;
nsCOMPtr<nsIProperties> mProperties;
nsCOMPtr<nsIProperties> mProperties;
/// If this image is animated, a FrameAnimator which manages its animation.
UniquePtr<FrameAnimator> mAnim;
UniquePtr<FrameAnimator> mAnim;
// Image locking.
uint32_t mLockCount;
@ -360,7 +360,7 @@ private: // data
// How many times we've decoded this image.
// This is currently only used for statistics
int32_t mDecodeCount;
int32_t mDecodeCount;
// If the image contains multiple resolutions, a hint as to which one
// should be used
@ -378,7 +378,7 @@ private: // data
DrawResult mLastImageContainerDrawResult;
#ifdef DEBUG
uint32_t mFramesNotified;
uint32_t mFramesNotified;
#endif
// The source data for this image.

4
image/SVGDocumentWrapper.h

@ -35,8 +35,8 @@ class SVGSVGElement;
namespace image {
class SVGDocumentWrapper final : public nsIStreamListener,
public nsIObserver,
nsSupportsWeakReference
public nsIObserver,
nsSupportsWeakReference
{
public:
SVGDocumentWrapper();

9
image/SourceBuffer.h

@ -120,7 +120,8 @@ public:
/// If at the end, returns the status passed to SourceBuffer::Complete().
nsresult CompletionStatus() const
{
MOZ_ASSERT(mState == COMPLETE, "Calling CompletionStatus() in the wrong state");
MOZ_ASSERT(mState == COMPLETE,
"Calling CompletionStatus() in the wrong state");
return mState == COMPLETE ? mData.mAtEnd.mStatus : NS_OK;
}
@ -209,12 +210,6 @@ private:
* keep a list of consumers which are waiting for new data, and to resume them
* when the producer appends more. All consumers must implement the IResumable
* interface to make this possible.
*
* XXX(seth): We should add support for compacting a SourceBuffer. To do this,
* we need to have SourceBuffer keep track of how many live
* SourceBufferIterator's point to it. When the SourceBuffer is complete and no
* live SourceBufferIterator's for it remain, we can compact its contents into a
* single chunk.
*/
class SourceBuffer final
{

20
image/SurfaceCache.cpp

@ -35,6 +35,7 @@
#include "nsSize.h"
#include "nsTArray.h"
#include "prsystem.h"
#include "ShutdownTracker.h"
#include "SVGImageContext.h"
using std::max;
@ -436,6 +437,7 @@ public:
, mMaxCost(aSurfaceCacheSize)
, mAvailableCost(aSurfaceCacheSize)
, mLockedCost(0)
, mOverflowCount(0)
{
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
@ -483,6 +485,7 @@ public:
// If this is bigger than we can hold after discarding everything we can,
// refuse to cache it.
if (MOZ_UNLIKELY(!CanHoldAfterDiscarding(aCost))) {
mOverflowCount++;
return InsertOutcome::FAILURE;
}
@ -582,7 +585,8 @@ public:
} else {
// Our call to AddObject must have failed in StartTracking; most likely
// we're in XPCOM shutdown right now.
NS_WARNING("Not expiration-tracking an unlocked surface!");
NS_ASSERTION(ShutdownTracker::ShutdownHasStarted(),
"Not expiration-tracking an unlocked surface!");
}
DebugOnly<bool> foundInCosts = mCosts.RemoveElementSorted(costEntry);
@ -863,6 +867,14 @@ public:
"imagelib surface cache.");
NS_ENSURE_SUCCESS(rv, rv);
rv = MOZ_COLLECT_REPORT("imagelib-surface-cache-overflow-count",
KIND_OTHER, UNITS_COUNT,
mOverflowCount,