Skip to content

Commit

Permalink
Bug 1148213 - Implement image locking for VectorImage. r=dholbert
Browse files Browse the repository at this point in the history
  • Loading branch information
sethfowler committed Mar 28, 2015
1 parent a88105d commit b10e8c2
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 4 deletions.
75 changes: 71 additions & 4 deletions image/src/VectorImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ NS_IMPL_ISUPPORTS(VectorImage,
VectorImage::VectorImage(ProgressTracker* aProgressTracker,
ImageURL* aURI /* = nullptr */) :
ImageResource(aURI), // invoke superclass's constructor
mLockCount(0),
mIsInitialized(false),
mIsFullyLoaded(false),
mIsDrawing(false),
Expand Down Expand Up @@ -355,6 +356,14 @@ VectorImage::Init(const char* aMimeType,
"Flags unexpectedly set before initialization");
MOZ_ASSERT(!strcmp(aMimeType, IMAGE_SVG_XML), "Unexpected mimetype");

mDiscardable = !!(aFlags & INIT_FLAG_DISCARDABLE);

// Lock this image's surfaces in the SurfaceCache if we're not discardable.
if (!mDiscardable) {
mLockCount++;
SurfaceCache::LockImage(ImageKey(this));
}

mIsInitialized = true;
return NS_OK;
}
Expand Down Expand Up @@ -836,6 +845,14 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams)
if (bypassCache)
return Show(svgDrawable, aParams);

// We're about to rerasterize, which may mean that some of the previous
// surfaces we've rasterized aren't useful anymore. We can allow them to
// expire from the cache by unlocking them here, and then sending out an
// invalidation. If this image is locked, any surfaces that are still useful
// will become locked again when Draw touches them, and the remainder will
// eventually expire.
SurfaceCache::UnlockSurfaces(ImageKey(this));

// Try to create an imgFrame, initializing the surface it contains by drawing
// our gfxDrawable into it. (We use FILTER_NEAREST since we never scale here.)
nsRefPtr<imgFrame> frame = new imgFrame;
Expand All @@ -861,12 +878,17 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams)
VectorSurfaceKey(aParams.size,
aParams.svgContext,
aParams.animationTime),
Lifetime::Transient);
Lifetime::Persistent);

// Draw.
nsRefPtr<gfxDrawable> drawable =
new gfxSurfaceDrawable(surface, ThebesIntSize(aParams.size));
Show(drawable, aParams);

// Send out an invalidation so that surfaces that are still in use get
// re-locked. See the discussion of the UnlockSurfaces call above.
mProgressTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE,
nsIntRect::GetMaxSizedIntRect());
}


Expand Down Expand Up @@ -923,7 +945,19 @@ VectorImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
NS_IMETHODIMP
VectorImage::LockImage()
{
// This method is for image-discarding, which only applies to RasterImages.
MOZ_ASSERT(NS_IsMainThread());

if (mError) {
return NS_ERROR_FAILURE;
}

mLockCount++;

if (mLockCount == 1) {
// Lock this image's surfaces in the SurfaceCache.
SurfaceCache::LockImage(ImageKey(this));
}

return NS_OK;
}

Expand All @@ -932,7 +966,24 @@ VectorImage::LockImage()
NS_IMETHODIMP
VectorImage::UnlockImage()
{
// This method is for image-discarding, which only applies to RasterImages.
MOZ_ASSERT(NS_IsMainThread());

if (mError) {
return NS_ERROR_FAILURE;
}

if (mLockCount == 0) {
MOZ_ASSERT_UNREACHABLE("Calling UnlockImage with a zero lock count");
return NS_ERROR_ABORT;
}

mLockCount--;

if (mLockCount == 0) {
// Unlock this image's surfaces in the SurfaceCache.
SurfaceCache::UnlockImage(ImageKey(this));
}

return NS_OK;
}

Expand All @@ -941,10 +992,26 @@ VectorImage::UnlockImage()
NS_IMETHODIMP
VectorImage::RequestDiscard()
{
SurfaceCache::RemoveImage(ImageKey(this));
MOZ_ASSERT(NS_IsMainThread());

if (mDiscardable && mLockCount == 0) {
SurfaceCache::RemoveImage(ImageKey(this));
mProgressTracker->OnDiscard();
}

return NS_OK;
}

void
VectorImage::OnSurfaceDiscarded()
{
MOZ_ASSERT(mProgressTracker);

nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethod(mProgressTracker, &ProgressTracker::OnDiscard);
NS_DispatchToMainThread(runnable);
}

//******************************************************************************
/* void resetAnimation (); */
NS_IMETHODIMP
Expand Down
6 changes: 6 additions & 0 deletions image/src/VectorImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class VectorImage final : public ImageResource,
nsresult aResult,
bool aLastPart) override;

void OnSurfaceDiscarded() override;

/**
* Callback for SVGRootRenderingObserver.
*
Expand Down Expand Up @@ -100,7 +102,11 @@ class VectorImage final : public ImageResource,
nsRefPtr<SVGLoadEventListener> mLoadEventListener;
nsRefPtr<SVGParseCompleteListener> mParseCompleteListener;

/// Count of locks on this image (roughly correlated to visible instances).
uint32_t mLockCount;

bool mIsInitialized; // Have we been initalized?
bool mDiscardable; // Are we discardable?
bool mIsFullyLoaded; // Has the SVG document finished loading?
bool mIsDrawing; // Are we currently drawing?
bool mHaveAnimations; // Is our SVG content SMIL-animated?
Expand Down

0 comments on commit b10e8c2

Please sign in to comment.