Back out 8 changesets (bug 1207355) for OS X 10.10 reftest failures in generated-content/

CLOSED TREE

Backed out changeset aafd6db2fbb4 (bug 1207355)
Backed out changeset 9dd950b837fb (bug 1207355)
Backed out changeset e941e0e106a1 (bug 1207355)
Backed out changeset ecebca101fcb (bug 1207355)
Backed out changeset 08f2017137e1 (bug 1207355)
Backed out changeset 3dc69e37c9b4 (bug 1207355)
Backed out changeset bcdf51edb121 (bug 1207355)
Backed out changeset 1d4c00dbf49a (bug 1207355)
This commit is contained in:
Phil Ringnalda 2015-10-28 22:57:43 -07:00
parent a91e1ff9e9
commit a727c1fe68
21 changed files with 174 additions and 108 deletions

View File

@ -343,6 +343,7 @@ pref("image.mem.surfacecache.max_size_kb", 131072); // 128MB
pref("image.mem.surfacecache.size_factor", 8); // 1/8 of main memory
pref("image.mem.surfacecache.discard_factor", 2); // Discard 1/2 of the surface cache at a time.
pref("image.mem.surfacecache.min_expiration_ms", 86400000); // 24h, we rely on the out of memory hook
pref("image.onload.decode.limit", 24); /* don't decode more than 24 images eagerly */
// XXX this isn't a good check for "are touch events supported", but
// we don't really have a better one at the moment.

View File

@ -2117,6 +2117,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
tmp->mInUnlinkOrDeletion = false;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
static bool sPrefsInitialized = false;
static uint32_t sOnloadDecodeLimit = 0;
nsresult
nsDocument::Init()
{
@ -2124,6 +2127,11 @@ nsDocument::Init()
return NS_ERROR_ALREADY_INITIALIZED;
}
if (!sPrefsInitialized) {
sPrefsInitialized = true;
Preferences::AddUintVarCache(&sOnloadDecodeLimit, "image.onload.decode.limit", 0);
}
// Force initialization.
nsINode::nsSlots* slots = Slots();
@ -10514,8 +10522,12 @@ nsDocument::AddImage(imgIRequest* aImage)
// If this is the first insertion and we're locking images, lock this image
// too.
if (oldCount == 0 && mLockingImages) {
rv = aImage->LockImage();
if (oldCount == 0) {
if (mLockingImages)
rv = aImage->LockImage();
if (NS_SUCCEEDED(rv) && (!sOnloadDecodeLimit ||
mImageTracker.Count() < sOnloadDecodeLimit))
rv = aImage->StartDecoding();
}
// If this is the first insertion and we're animating images, request
@ -10646,6 +10658,7 @@ PLDHashOperator LockEnumerator(imgIRequest* aKey,
void* userArg)
{
aKey->LockImage();
aKey->RequestDecode();
return PL_DHASH_NEXT;
}

View File

@ -229,6 +229,53 @@ nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest, nsresult aStatus)
MOZ_ASSERT(aRequest == mCurrentRequest,
"One way or another, we should be current by now");
// We just loaded all the data we're going to get. If we're visible and
// haven't done an initial paint (*), we want to make sure the image starts
// decoding immediately, for two reasons:
//
// 1) This image is sitting idle but might need to be decoded as soon as we
// start painting, in which case we've wasted time.
//
// 2) We want to block onload until all visible images are decoded. We do this
// by blocking onload until all in-progress decodes get at least one frame
// decoded. However, if all the data comes in while painting is suppressed
// (ie, before the initial paint delay is finished), we fire onload without
// doing a paint first. This means that decode-on-draw images don't start
// decoding, so we can't wait for them to finish. See bug 512435.
//
// (*) IsPaintingSuppressed returns false if we haven't gotten the initial
// reflow yet, so we have to test !DidInitialize || IsPaintingSuppressed.
// It's possible for painting to be suppressed for reasons other than the
// initial paint delay (for example, being in the bfcache), but we probably
// aren't loading images in those situations.
// XXXkhuey should this be GetOurCurrentDoc? Decoding if we're not in
// the document seems silly.
nsIDocument* doc = GetOurOwnerDoc();
nsIPresShell* shell = doc ? doc->GetShell() : nullptr;
if (shell && shell->IsVisible() &&
(!shell->DidInitialize() || shell->IsPaintingSuppressed())) {
nsIFrame* f = GetOurPrimaryFrame();
// If we haven't gotten a frame yet either we aren't going to (so don't
// bother kicking off a decode), or we will get very soon on the next
// refresh driver tick when it flushes. And it will most likely be a
// specific image type frame (we only create generic (ie inline) type
// frames for images that don't have a size, and since we have all the data
// we should have the size) which will check its own visibility on its
// first reflow.
if (f) {
// If we've gotten a frame and that frame has called FrameCreate and that
// frame has been reflowed then we know that it checked it's own visibility
// so we can trust our visible count and we don't start decode if we are not
// visible.
if (!mFrameCreateCalled || (f->GetStateBits() & NS_FRAME_FIRST_REFLOW) ||
mVisibleCount > 0 || shell->AssumeAllImagesVisible()) {
mCurrentRequest->StartDecoding();
}
}
}
// Fire the appropriate DOM event.
if (NS_SUCCEEDED(aStatus)) {
FireEvent(NS_LITERAL_STRING("load"));

View File

@ -246,6 +246,12 @@ DynamicImage::Draw(gfxContext* aContext,
return DrawResult::SUCCESS;
}
NS_IMETHODIMP
DynamicImage::RequestDecode()
{
return NS_OK;
}
NS_IMETHODIMP
DynamicImage::StartDecoding()
{

View File

@ -214,6 +214,12 @@ ImageWrapper::Draw(gfxContext* aContext,
aFilter, aSVGContext, aFlags);
}
NS_IMETHODIMP
ImageWrapper::RequestDecode()
{
return mInnerImage->RequestDecode();
}
NS_IMETHODIMP
ImageWrapper::StartDecoding()
{

View File

@ -70,16 +70,6 @@ public:
return;
}
// Retrieve the image's intrinsic size.
int32_t width = 0;
int32_t height = 0;
mImage->GetWidth(&width);
mImage->GetHeight(&height);
// Request decoding at the intrinsic size.
mImage->RequestDecodeForSize(IntSize(width, height),
imgIContainer::DECODE_FLAGS_DEFAULT);
// If there's already an error, we may never get a FRAME_COMPLETE
// notification, so go ahead and notify our owner right away.
RefPtr<ProgressTracker> tracker = mImage->GetProgressTracker();
@ -135,6 +125,7 @@ MultipartImage::Init()
RefPtr<ProgressTracker> firstPartTracker =
InnerImage()->GetProgressTracker();
firstPartTracker->AddObserver(this);
InnerImage()->RequestDecode();
InnerImage()->IncrementAnimationConsumers();
}
@ -163,6 +154,7 @@ MultipartImage::BeginTransitionToPart(Image* aNextPart)
// Start observing the next part; we'll complete the transition when
// NextPartObserver calls FinishTransition.
mNextPartObserver->BeginObserving(mNextPart);
mNextPart->RequestDecode();
mNextPart->IncrementAnimationConsumers();
}

View File

@ -319,9 +319,6 @@ RasterImage::LookupFrame(uint32_t aFrameNum,
IntSize requestedSize = CanDownscaleDuringDecode(aSize, aFlags)
? aSize : mSize;
if (requestedSize.IsEmpty()) {
return DrawableFrameRef(); // Can't decode to a surface of zero size.
}
LookupResult result = LookupFrameInternal(aFrameNum, requestedSize, aFlags);
@ -1166,18 +1163,18 @@ RasterImage::CanDiscard() {
!mAnim; // Can never discard animated images
}
//******************************************************************************
NS_IMETHODIMP
RasterImage::RequestDecode()
{
return RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT);
}
NS_IMETHODIMP
RasterImage::StartDecoding()
{
if (mError) {
return NS_ERROR_FAILURE;
}
if (!mHasSize) {
mWantFullDecode = true;
return NS_OK;
}
return RequestDecodeForSize(mSize, FLAG_SYNC_DECODE_IF_FAST);
}
@ -1191,6 +1188,7 @@ RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags)
}
if (!mHasSize) {
mWantFullDecode = true;
return NS_OK;
}
@ -1790,7 +1788,7 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder)
// If we were a metadata decode and a full decode was requested, do it.
if (done && wasMetadata && mWantFullDecode) {
mWantFullDecode = false;
RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT);
RequestDecode();
}
}

View File

@ -964,6 +964,15 @@ VectorImage::RecoverFromLossOfSurfaces()
SurfaceCache::RemoveImage(ImageKey(this));
}
//******************************************************************************
NS_IMETHODIMP
VectorImage::RequestDecode()
{
// Nothing to do for SVG images
return NS_OK;
}
NS_IMETHODIMP
VectorImage::StartDecoding()
{

View File

@ -75,7 +75,7 @@ native nsIntSizeByVal(nsIntSize);
*
* Internally, imgIContainer also manages animation of images.
*/
[scriptable, builtinclass, uuid(a8dbee24-ff86-4755-b40e-51175caf31af)]
[scriptable, builtinclass, uuid(7c795421-a79c-43ac-9e20-6d4e8a9dfb76)]
interface imgIContainer : nsISupports
{
/**
@ -383,16 +383,22 @@ interface imgIContainer : nsISupports
/*
* Ensures that an image is decoding. Calling this function guarantees that
* the image will at some point fire off decode notifications. Images that
* can be decoded "quickly" according to some heuristic will be decoded
* synchronously.
* the image will at some point fire off decode notifications. Calling draw()
* or getFrame() triggers the same mechanism internally. Thus, if you want to
* be sure that the image will be decoded but don't want to access it until
* then, you must call requestDecode().
*/
void requestDecode();
/*
* This is equivalent to requestDecode() but it also synchronously decodes
* images that can be decoded "quickly" according to some heuristic.
*/
[noscript] void startDecoding();
/*
* This method triggers decoding for an image, but unlike startDecoding() it
* enables the caller to provide more detailed information about the decode
* request.
* This method is equivalent to requestDecode(), but enables the caller to
* provide more detailed information about the decode request.
*
* @param aSize The size to which the image should be scaled while decoding,
* if possible. If the image cannot be scaled to this size while

View File

@ -19,7 +19,7 @@ interface nsIPrincipal;
* @version 0.1
* @see imagelib2
*/
[scriptable, builtinclass, uuid(db0a945c-3883-424a-98d0-2ee0523b0255)]
[scriptable, builtinclass, uuid(4cb01f0a-ef94-4345-a8d7-1a93f15ff548)]
interface imgIRequest : nsIRequest
{
/**
@ -145,14 +145,15 @@ interface imgIRequest : nsIRequest
void cancelAndForgetObserver(in nsresult aStatus);
/**
* Requests a synchronous decode for the image.
* Requests a decode for the image.
*
* imgIContainer has a startDecoding() method, but callers may want to request
* imgIContainer has a requestDecode() method, but callers may want to request
* a decode before the container has necessarily been instantiated. Calling
* startDecoding() on the imgIRequest simply forwards along the request if the
* container already exists, or calls it once the container becomes available
* if it does not yet exist.
* requestDecode() on the imgIRequest simply forwards along the request if the
* container already exists, or calls it once it gets OnStartContainer if the
* container does not yet exist.
*/
void requestDecode();
void startDecoding();
/**

View File

@ -1590,7 +1590,7 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request,
// We will send notifications from imgCacheValidator::OnStartRequest().
// In the mean time, we must defer notifications because we are added to
// the imgRequest's proxy list, and we can get extra notifications
// resulting from methods such as StartDecoding(). See bug 579122.
// resulting from methods such as RequestDecode(). See bug 579122.
proxy->SetNotificationsDeferred(true);
// Attach the proxy without notifying
@ -1666,7 +1666,7 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request,
// We will send notifications from imgCacheValidator::OnStartRequest().
// In the mean time, we must defer notifications because we are added to
// the imgRequest's proxy list, and we can get extra notifications
// resulting from methods such as StartDecoding(). See bug 579122.
// resulting from methods such as RequestDecode(). See bug 579122.
req->SetNotificationsDeferred(true);
// Add the proxy without notifying

View File

@ -413,7 +413,7 @@ imgRequest::ContinueEvict()
}
void
imgRequest::StartDecoding()
imgRequest::RequestDecode()
{
MutexAutoLock lock(mMutex);
mDecodeRequested = true;
@ -1053,7 +1053,7 @@ imgRequest::FinishPreparingForNewPart(const NewPartResult& aResult)
}
if (IsDecodeRequested()) {
aResult.mImage->StartDecoding();
aResult.mImage->RequestDecode();
}
}

View File

@ -95,7 +95,7 @@ public:
void ContinueEvict();
// Request that we start decoding the image as soon as data becomes available.
void StartDecoding();
void RequestDecode();
inline uint64_t InnerWindowID() const {
return mInnerWindowId;
@ -220,7 +220,7 @@ private:
// Update the cache entry size based on the image container.
void UpdateCacheEntrySize();
/// Returns true if StartDecoding() was called.
/// Returns true if RequestDecode() was called.
bool IsDecodeRequested() const;
// Weak reference to parent loader; this request cannot outlive its owner.

View File

@ -208,6 +208,15 @@ imgRequestProxy::ChangeOwner(imgRequest* aNewOwner)
uint32_t oldAnimationConsumers = mAnimationConsumers;
ClearAnimationConsumers();
// Were we decoded before?
bool wasDecoded = false;
RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
if (progressTracker->HasImage() &&
progressTracker->GetImageStatus() &
imgIRequest::STATUS_FRAME_COMPLETE) {
wasDecoded = true;
}
GetOwner()->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER);
mBehaviour->SetOwner(aNewOwner);
@ -226,9 +235,9 @@ imgRequestProxy::ChangeOwner(imgRequest* aNewOwner)
GetOwner()->AddProxy(this);
// If we'd previously requested a synchronous decode, request a decode on the
// new image.
if (mDecodeRequested) {
// If we were decoded, or if we'd previously requested a decode, request a
// decode on the new image
if (wasDecoded || mDecodeRequested) {
StartDecoding();
}
@ -371,12 +380,31 @@ imgRequestProxy::StartDecoding()
}
if (GetOwner()) {
GetOwner()->StartDecoding();
GetOwner()->RequestDecode();
}
return NS_OK;
}
NS_IMETHODIMP
imgRequestProxy::RequestDecode()
{
// Flag this, so we know to transfer the request if our owner changes
mDecodeRequested = true;
RefPtr<Image> image = GetImage();
if (image) {
return image->RequestDecode();
}
if (GetOwner()) {
GetOwner()->RequestDecode();
}
return NS_OK;
}
NS_IMETHODIMP
imgRequestProxy::LockImage()
{

View File

@ -48,6 +48,12 @@ function ImageListener(start_callback, stop_callback)
{
do_check_false(this.synchronous);
try {
aRequest.requestDecode();
} catch (e) {
do_print("requestDecode threw " + e);
}
this.state |= LOAD_COMPLETE;
if (this.stop_callback)

View File

@ -168,7 +168,6 @@
#include "mozilla/Telemetry.h"
#include "nsCanvasFrame.h"
#include "nsIImageLoadingContent.h"
#include "nsImageFrame.h"
#include "nsIScreen.h"
#include "nsIScreenManager.h"
#include "nsPlaceholderFrame.h"
@ -10702,23 +10701,7 @@ nsresult
PresShell::UpdateImageLockingState()
{
// We're locked if we're both thawed and active.
bool locked = !mFrozen && mIsActive;
nsresult rv = mDocument->SetImageLockingState(locked);
if (locked) {
// Request decodes for visible images; we want to start decoding as
// quickly as possible when we get foregrounded to minimize flashing.
for (auto iter = mVisibleImages.Iter(); !iter.Done(); iter.Next()) {
nsCOMPtr<nsIContent> content = do_QueryInterface(iter.Get()->GetKey());
nsImageFrame* imageFrame = do_QueryFrame(content->GetPrimaryFrame());
if (imageFrame) {
imageFrame->MaybeDecodeForPredictedSize();
}
}
}
return rv;
return mDocument->SetImageLockingState(!mFrozen && mIsActive);
}
PresShell*

View File

@ -712,20 +712,9 @@ nsBulletFrame::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aDa
// Unconditionally start decoding for now.
// XXX(seth): We eventually want to decide whether to do this based on
// visibility. We should get that for free from bug 1091236.
nsCOMPtr<imgIContainer> container;
aRequest->GetImage(getter_AddRefs(container));
if (container) {
// Retrieve the intrinsic size of the image.
int32_t width = 0;
int32_t height = 0;
container->GetWidth(&width);
container->GetHeight(&height);
// Request a decode at that size.
container->RequestDecodeForSize(IntSize(width, height),
imgIContainer::DECODE_FLAGS_DEFAULT);
if (aRequest == mImageRequest) {
mImageRequest->RequestDecode();
}
InvalidateFrame();
}

View File

@ -1814,11 +1814,7 @@ nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// decoded yet. And we are not going to ask the image to draw, so this
// may be the only chance to tell it that it should decode.
if (currentRequest) {
uint32_t status = 0;
currentRequest->GetImageStatus(&status);
if (!(status & imgIRequest::STATUS_DECODE_COMPLETE)) {
MaybeDecodeForPredictedSize();
}
currentRequest->RequestDecode();
}
} else {
aLists.Content()->AppendNewToTop(new (aBuilder)
@ -2299,6 +2295,7 @@ nsresult nsImageFrame::LoadIcons(nsPresContext *aPresContext)
if (NS_FAILED(rv)) {
return rv;
}
gIconLoad->mLoadingImage->RequestDecode();
rv = LoadIcon(brokenSrc,
aPresContext,
@ -2306,6 +2303,7 @@ nsresult nsImageFrame::LoadIcons(nsPresContext *aPresContext)
if (NS_FAILED(rv)) {
return rv;
}
gIconLoad->mBrokenImage->RequestDecode();
return rv;
}
@ -2375,35 +2373,13 @@ void nsImageFrame::IconLoad::GetPrefs()
}
NS_IMETHODIMP
nsImageFrame::IconLoad::Notify(imgIRequest* aRequest,
int32_t aType,
const nsIntRect* aData)
nsImageFrame::IconLoad::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
{
MOZ_ASSERT(aRequest);
if (aType != imgINotificationObserver::LOAD_COMPLETE &&
aType != imgINotificationObserver::FRAME_UPDATE) {
return NS_OK;
}
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
nsCOMPtr<imgIContainer> image;
aRequest->GetImage(getter_AddRefs(image));
if (!image) {
return NS_ERROR_FAILURE;
}
// Retrieve the image's intrinsic size.
int32_t width = 0;
int32_t height = 0;
image->GetWidth(&width);
image->GetHeight(&height);
// Request a decode at that size.
image->RequestDecodeForSize(IntSize(width, height),
imgIContainer::DECODE_FLAGS_DEFAULT);
}
nsTObserverArray<nsImageFrame*>::ForwardIterator iter(mIconObservers);
nsImageFrame *frame;
while (iter.HasMore()) {

View File

@ -230,7 +230,6 @@ protected:
protected:
friend class nsImageListener;
friend class nsImageLoadingContent;
friend class PresShell;
nsresult OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage);
nsresult OnFrameUpdate(imgIRequest* aRequest, const nsIntRect* aRect);

View File

@ -962,6 +962,9 @@ struct nsStyleBorder {
return mBorderImageSource.IsLoaded();
}
// Defined in nsStyleStructInlines.h
inline nsresult RequestDecode();
void GetBorderColor(mozilla::css::Side aSide, nscolor& aColor,
bool& aForeground) const
{

View File

@ -4152,6 +4152,9 @@ pref("image.multithreaded_decoding.limit", -1);
// cache.
pref("canvas.image.cache.limit", 0);
// How many images to eagerly decode on a given page. 0 means "no limit".
pref("image.onload.decode.limit", 0);
// WebGL prefs
#ifdef ANDROID
// Disable MSAA on mobile.