зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1034345 (Part 2) - Implement OptimalImageSizeForDest for RasterImage. r=tn
--HG-- extra : rebase_source : 63c58e8df2c992f9550b481530e41938e8672ad1
This commit is contained in:
Родитель
c03739fc30
Коммит
5f4250d96a
|
@ -59,6 +59,7 @@ using namespace gfx;
|
|||
using namespace layers;
|
||||
|
||||
namespace image {
|
||||
using std::ceil;
|
||||
|
||||
// a mask for flags that will affect the decoding
|
||||
#define DECODE_FLAGS_MASK (imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA | imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION)
|
||||
|
@ -2586,6 +2587,39 @@ RasterImage::ScalingDone(ScaleRequest* request, ScaleStatus status)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RasterImage::RequestScale(imgFrame* aFrame, gfxSize aScale)
|
||||
{
|
||||
// We can't store more than one scaled version of an image right now, so if
|
||||
// there's more than one instance of this image, bail.
|
||||
if (mLockCount != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We also can't scale if we can't lock the image data for this frame.
|
||||
if (NS_FAILED(aFrame->LockImageData())) {
|
||||
aFrame->UnlockImageData();
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have an outstanding request, signal it to stop (if it can).
|
||||
if (mScaleRequest) {
|
||||
mScaleRequest->stopped = true;
|
||||
}
|
||||
|
||||
nsRefPtr<ScaleRunner> runner = new ScaleRunner(this, aScale, aFrame);
|
||||
if (runner->IsOK()) {
|
||||
if (!sScaleWorkerThread) {
|
||||
NS_NewNamedThread("Image Scaler", getter_AddRefs(sScaleWorkerThread));
|
||||
ClearOnShutdown(&sScaleWorkerThread);
|
||||
}
|
||||
|
||||
sScaleWorkerThread->Dispatch(runner, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
aFrame->UnlockImageData();
|
||||
}
|
||||
|
||||
bool
|
||||
RasterImage::DrawWithPreDownscaleIfNeeded(imgFrame *aFrame,
|
||||
gfxContext *aContext,
|
||||
|
@ -2636,27 +2670,8 @@ RasterImage::DrawWithPreDownscaleIfNeeded(imgFrame *aFrame,
|
|||
|
||||
// If we're not waiting for exactly this result, and there's only one
|
||||
// instance of this image on this page, ask for a scale.
|
||||
if (needScaleReq && mLockCount == 1) {
|
||||
if (NS_FAILED(frame->LockImageData())) {
|
||||
frame->UnlockImageData();
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we have an outstanding 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) {
|
||||
NS_NewNamedThread("Image Scaler", getter_AddRefs(sScaleWorkerThread));
|
||||
ClearOnShutdown(&sScaleWorkerThread);
|
||||
}
|
||||
|
||||
sScaleWorkerThread->Dispatch(runner, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
frame->UnlockImageData();
|
||||
if (needScaleReq) {
|
||||
RequestScale(frame, scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3656,5 +3671,45 @@ RasterImage::FrameNeededWorker::Run()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIntSize
|
||||
RasterImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
|
||||
GraphicsFilter aFilter, uint32_t aFlags)
|
||||
{
|
||||
MOZ_ASSERT(aDest.width >= 0 || ceil(aDest.width) <= INT32_MAX ||
|
||||
aDest.height >= 0 || ceil(aDest.height) <= INT32_MAX,
|
||||
"Unexpected destination size");
|
||||
|
||||
if (mSize.IsEmpty()) {
|
||||
return nsIntSize(0, 0);
|
||||
}
|
||||
|
||||
nsIntSize destSize(ceil(aDest.width), ceil(aDest.height));
|
||||
gfxSize scale(double(destSize.width) / mSize.width,
|
||||
double(destSize.height) / mSize.height);
|
||||
|
||||
if (CanScale(aFilter, scale, aFlags)) {
|
||||
if (mScaleResult.scale == scale) {
|
||||
if (mScaleResult.status == SCALE_DONE) {
|
||||
return destSize; // We have an existing HQ scale for this size.
|
||||
} else if (mScaleResult.status == SCALE_PENDING) {
|
||||
return mSize; // We're waiting for exactly this result.
|
||||
}
|
||||
}
|
||||
|
||||
// If there's only one instance of this image on this page, ask for a scale.
|
||||
uint32_t frameIndex = aWhichFrame == FRAME_FIRST ? 0
|
||||
: GetCurrentImgFrameIndex();
|
||||
|
||||
imgFrame* frame = GetDrawableImgFrame(frameIndex);
|
||||
if (frame) {
|
||||
RequestScale(frame, scale);
|
||||
}
|
||||
}
|
||||
|
||||
// We either can't HQ scale to this size or the scaled version isn't ready
|
||||
// yet. Use our intrinsic size for now.
|
||||
return mSize;
|
||||
}
|
||||
|
||||
} // namespace image
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -329,6 +329,9 @@ public:
|
|||
// Decode strategy
|
||||
|
||||
private:
|
||||
// Initiates an HQ scale for the given frame, if possible.
|
||||
void RequestScale(imgFrame* aFrame, gfxSize aScale);
|
||||
|
||||
already_AddRefed<imgStatusTracker> CurrentStatusTracker()
|
||||
{
|
||||
mDecodingMonitor.AssertCurrentThreadIn();
|
||||
|
|
Загрузка…
Ссылка в новой задаче