зеркало из https://github.com/mozilla/gecko-dev.git
Bug 795940 - Part 0.3 - Support stopping requests (on a best-effort basis). r=jrmuizel
--HG-- extra : rebase_source : 793d04fa7954bbf060f01436bc0d257edd05a28a
This commit is contained in:
Родитель
dace21eaac
Коммит
1f866d258a
|
@ -179,7 +179,8 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker) :
|
|||
mInDecoder(false),
|
||||
mAnimationFinished(false),
|
||||
mFinishing(false),
|
||||
mInUpdateImageContainer(false)
|
||||
mInUpdateImageContainer(false),
|
||||
mScaleRequest(nullptr)
|
||||
{
|
||||
// Set up the discard tracker node.
|
||||
mDiscardTrackerNode.img = this;
|
||||
|
@ -2623,9 +2624,13 @@ RasterImage::ScaleRunner::Run()
|
|||
// An alias just for ease of typing
|
||||
ScaleRequest* request = mScaleRequest;
|
||||
|
||||
request->done = mozilla::gfx::Scale(request->srcData, request->srcRect.width, request->srcRect.height, request->srcStride,
|
||||
request->dstData, request->dstSize.width, request->dstSize.height, request->dstStride,
|
||||
request->srcFormat);
|
||||
if (!request->stopped) {
|
||||
request->done = mozilla::gfx::Scale(request->srcData, request->srcRect.width, request->srcRect.height, request->srcStride,
|
||||
request->dstData, request->dstSize.width, request->dstSize.height, request->dstStride,
|
||||
request->srcFormat);
|
||||
} else {
|
||||
request->done = false;
|
||||
}
|
||||
|
||||
// OK, we've got a new scaled image. Let's get the main thread to unlock and
|
||||
// redraw it.
|
||||
|
@ -2649,7 +2654,7 @@ RasterImage::ScaleRunner::ScaleRunner(RasterImage* aImage, const gfxSize& aScale
|
|||
return;
|
||||
}
|
||||
|
||||
aImage->SetResultPending(request);
|
||||
aImage->ScalingStart(request);
|
||||
|
||||
mScaleRequest = request;
|
||||
}
|
||||
|
@ -2664,27 +2669,27 @@ RasterImage::DrawRunner::Run()
|
|||
// ScaleWorker is finished with this request, so we can unlock the data now.
|
||||
mScaleRequest->ReleaseSurfaces();
|
||||
|
||||
// Only set the scale result if the request finished successfully.
|
||||
if (mScaleRequest->done) {
|
||||
RasterImage* image = mScaleRequest->weakImage;
|
||||
if (image) {
|
||||
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(image->mObserver));
|
||||
if (observer) {
|
||||
imgFrame *scaledFrame = mScaleRequest->dstFrame.get();
|
||||
scaledFrame->ImageUpdated(scaledFrame->GetRect());
|
||||
observer->FrameChanged(&mScaleRequest->srcRect);
|
||||
}
|
||||
nsRefPtr<RasterImage> image = mScaleRequest->weakImage.get();
|
||||
|
||||
image->SetScaleResult(mScaleRequest);
|
||||
// Only set the scale result if the request finished successfully.
|
||||
if (mScaleRequest->done && image) {
|
||||
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(image->mObserver));
|
||||
if (observer) {
|
||||
imgFrame *scaledFrame = mScaleRequest->dstFrame.get();
|
||||
scaledFrame->ImageUpdated(scaledFrame->GetRect());
|
||||
observer->FrameChanged(&mScaleRequest->srcRect);
|
||||
}
|
||||
}
|
||||
|
||||
// Scaling failed. Reset the scale result on our image.
|
||||
else {
|
||||
RasterImage* image = mScaleRequest->weakImage;
|
||||
if (image) {
|
||||
image->SetScaleResult(nullptr);
|
||||
if (image) {
|
||||
ScaleStatus status;
|
||||
if (mScaleRequest->done) {
|
||||
status = SCALE_DONE;
|
||||
} else {
|
||||
status = SCALE_INVALID;
|
||||
}
|
||||
|
||||
image->ScalingDone(mScaleRequest, status);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2720,9 +2725,21 @@ RasterImage::CanScale(gfxPattern::GraphicsFilter aFilter,
|
|||
}
|
||||
|
||||
void
|
||||
RasterImage::SetScaleResult(ScaleRequest* request)
|
||||
RasterImage::ScalingStart(ScaleRequest* request)
|
||||
{
|
||||
if (request) {
|
||||
MOZ_ASSERT(request);
|
||||
mScaleResult.scale = request->scale;
|
||||
mScaleResult.status = SCALE_PENDING;
|
||||
mScaleRequest = request;
|
||||
}
|
||||
|
||||
void
|
||||
RasterImage::ScalingDone(ScaleRequest* request, ScaleStatus status)
|
||||
{
|
||||
MOZ_ASSERT(status == SCALE_DONE || status == SCALE_INVALID);
|
||||
MOZ_ASSERT(request);
|
||||
|
||||
if (status == SCALE_DONE) {
|
||||
MOZ_ASSERT(request->done);
|
||||
mScaleResult.status = SCALE_DONE;
|
||||
mScaleResult.frame = request->dstFrame;
|
||||
|
@ -2731,14 +2748,13 @@ RasterImage::SetScaleResult(ScaleRequest* request)
|
|||
mScaleResult.status = SCALE_INVALID;
|
||||
mScaleResult.frame = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RasterImage::SetResultPending(ScaleRequest* request)
|
||||
{
|
||||
MOZ_ASSERT(request);
|
||||
mScaleResult.scale = request->scale;
|
||||
mScaleResult.status = SCALE_PENDING;
|
||||
// If we were waiting for this scale to come through, forget the scale
|
||||
// request. Otherwise, we still have a scale outstanding that it's possible
|
||||
// for us to (want to) stop.
|
||||
if (mScaleRequest == request) {
|
||||
mScaleRequest = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2778,6 +2794,11 @@ RasterImage::DrawWithPreDownscaleIfNeeded(imgFrame *aFrame,
|
|||
|
||||
// If we're not waiting for exactly this result, ask for it.
|
||||
else if (!(mScaleResult.status == SCALE_PENDING && mScaleResult.scale == scale)) {
|
||||
// If we have an oustanding request, signal it to stop (if it can).
|
||||
if (mScaleRequest) {
|
||||
mScaleRequest->stopped = true;
|
||||
}
|
||||
|
||||
nsRefPtr<ScaleRunner> runner = new ScaleRunner(this, scale, frame);
|
||||
if (runner->IsOK()) {
|
||||
if (!sScaleWorkerThread) {
|
||||
|
|
|
@ -479,6 +479,7 @@ private:
|
|||
: scale(aScale)
|
||||
, dstLocked(false)
|
||||
, done(false)
|
||||
, stopped(false)
|
||||
{
|
||||
MOZ_ASSERT(!aSrcFrame->GetIsPaletted());
|
||||
MOZ_ASSERT(aScale.width > 0 && aScale.height > 0);
|
||||
|
@ -574,6 +575,10 @@ private:
|
|||
mozilla::gfx::SurfaceFormat srcFormat;
|
||||
bool dstLocked;
|
||||
bool done;
|
||||
// This boolean is accessed from both threads simultaneously without locking.
|
||||
// That's safe because stopping a ScaleRequest is strictly an optimization;
|
||||
// if we're not cache-coherent, at worst we'll do extra work.
|
||||
bool stopped;
|
||||
};
|
||||
|
||||
enum ScaleStatus
|
||||
|
@ -625,13 +630,15 @@ private:
|
|||
const gfxRect &aFill,
|
||||
const nsIntRect &aSubimage);
|
||||
|
||||
// Call this with a finished ScaleRequest to set this RasterImage's scale
|
||||
// result, or nullptr to reset the scale result.
|
||||
void SetScaleResult(ScaleRequest* request);
|
||||
|
||||
// Call this with a new ScaleRequest to mark this RasterImage's scale result
|
||||
// as waiting for the results of this request.
|
||||
void SetResultPending(ScaleRequest* request);
|
||||
// as waiting for the results of this request. You call to ScalingDone before
|
||||
// request is destroyed!
|
||||
void ScalingStart(ScaleRequest* request);
|
||||
|
||||
// Call this with a finished ScaleRequest to set this RasterImage's scale
|
||||
// result. Give it a ScaleStatus of SCALE_DONE if everything succeeded, and
|
||||
// SCALE_INVALID otherwise.
|
||||
void ScalingDone(ScaleRequest* request, ScaleStatus status);
|
||||
|
||||
/**
|
||||
* Advances the animation. Typically, this will advance a single frame, but it
|
||||
|
@ -846,6 +853,11 @@ private: // data
|
|||
inline bool CanScale(gfxPattern::GraphicsFilter aFilter, gfxSize aScale);
|
||||
ScaleResult mScaleResult;
|
||||
|
||||
// We hold on to a bare pointer to a ScaleRequest while it's outstanding so
|
||||
// we can mark it as stopped if necessary. The ScaleWorker/DrawWorker duo
|
||||
// will inform us when to let go of this pointer.
|
||||
ScaleRequest* mScaleRequest;
|
||||
|
||||
// Decoder shutdown
|
||||
enum eShutdownIntent {
|
||||
eShutdownIntent_Done = 0,
|
||||
|
|
Загрузка…
Ссылка в новой задаче