Bug 1296657: Attempt to create an mOptSurface of the correct type for the DT we're drawing to. r=tnikkel

MozReview-Commit-ID: 2LIQWUPAuaF
This commit is contained in:
Bas Schouten 2016-09-15 13:53:12 +02:00
Родитель 747b361352
Коммит 77e2a32f4a
4 изменённых файлов: 33 добавлений и 44 удалений

Просмотреть файл

@ -874,7 +874,7 @@ VectorImage::Draw(gfxContext* aContext,
}
// We didn't get a hit in the surface cache, so we'll need to rerasterize.
CreateSurfaceAndShow(params);
CreateSurfaceAndShow(params, aContext->GetDrawTarget()->GetBackendType());
return DrawResult::SUCCESS;
}
@ -913,7 +913,7 @@ VectorImage::LookupCachedSurface(const SVGDrawingParameters& aParams)
}
void
VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams)
VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams, BackendType aBackend)
{
mSVGDocumentWrapper->UpdateViewportBounds(aParams.viewportSize);
mSVGDocumentWrapper->FlushImageTransformInvalidation();
@ -951,7 +951,8 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams)
nsresult rv =
frame->InitWithDrawable(svgDrawable, aParams.size,
SurfaceFormat::B8G8R8A8,
SamplingFilter::POINT, aParams.flags);
SamplingFilter::POINT, aParams.flags,
aBackend);
// If we couldn't create the frame, it was probably because it would end
// up way too big. Generally it also wouldn't fit in the cache, but the prefs

Просмотреть файл

@ -83,7 +83,8 @@ private:
already_AddRefed<gfxDrawable>
LookupCachedSurface(const SVGDrawingParameters& aParams);
void CreateSurfaceAndShow(const SVGDrawingParameters& aParams);
void CreateSurfaceAndShow(const SVGDrawingParameters& aParams,
gfx::BackendType aBackend);
void Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams);
nsresult Init(const char* aMimeType, uint32_t aFlags);

Просмотреть файл

@ -271,7 +271,8 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
const nsIntSize& aSize,
const SurfaceFormat aFormat,
SamplingFilter aSamplingFilter,
uint32_t aImageFlags)
uint32_t aImageFlags,
gfx::BackendType aBackend)
{
// Assert for properties that should be verified by decoders,
// warn for properties related to bad content.
@ -336,8 +337,13 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
// the documentation for this method.
MOZ_ASSERT(!mOptSurface, "Called imgFrame::InitWithDrawable() twice?");
target = gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(mFrameRect.Size(), mFormat);
if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(aBackend)) {
target = gfxPlatform::GetPlatform()->
CreateDrawTargetForBackend(aBackend, mFrameRect.Size(), mFormat);
} else {
target = gfxPlatform::GetPlatform()->
CreateOffscreenContentDrawTarget(mFrameRect.Size(), mFormat);
}
}
if (!target || !target->IsValid()) {
@ -394,12 +400,15 @@ imgFrame::CanOptimizeOpaqueImage()
}
nsresult
imgFrame::Optimize()
imgFrame::Optimize(DrawTarget* aTarget)
{
MOZ_ASSERT(NS_IsMainThread());
mMonitor.AssertCurrentThreadOwns();
MOZ_ASSERT(mLockCount == 1,
"Should only optimize when holding the lock exclusively");
if (mLockCount > 0 || !mOptimizable) {
// Don't optimize right now.
return NS_OK;
}
// Check whether image optimization is disabled -- not thread safe!
static bool gDisableOptimize = false;
@ -422,7 +431,7 @@ imgFrame::Optimize()
mImageSurface = CreateLockedSurface(mVBuf, mFrameRect.Size(), mFormat);
}
if (!mOptimizable || gDisableOptimize) {
if (gDisableOptimize) {
return NS_OK;
}
@ -454,6 +463,7 @@ imgFrame::Optimize()
// allow the operating system to free the memory if it needs to.
mVBufPtr = nullptr;
mImageSurface = nullptr;
mOptimizable = false;
return NS_OK;
}
@ -548,6 +558,10 @@ bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion,
MonitorAutoLock lock(mMonitor);
// Possibly convert this image into a GPU texture, this may also cause our
// mImageSurface to be released and the OS to release the underlying memory.
Optimize(aContext->GetDrawTarget());
bool doPartialDecode = !AreAllPixelsWritten();
RefPtr<SourceSurface> surf = GetSourceSurfaceInternal();
@ -749,21 +763,6 @@ imgFrame::AssertImageDataLocked() const
#endif
}
class UnlockImageDataRunnable : public Runnable
{
public:
explicit UnlockImageDataRunnable(imgFrame* aTarget)
: mTarget(aTarget)
{
MOZ_ASSERT(mTarget);
}
NS_IMETHOD Run() override { return mTarget->UnlockImageData(); }
private:
RefPtr<imgFrame> mTarget;
};
nsresult
imgFrame::UnlockImageData()
{
@ -777,22 +776,6 @@ imgFrame::UnlockImageData()
MOZ_ASSERT(mLockCount > 1 || mFinished || mAborted,
"Should have Finish()'d or aborted before unlocking");
// If we're about to become unlocked, we don't need to hold on to our data
// surface anymore. (But we don't need to do anything for paletted images,
// which don't have surfaces.)
if (mLockCount == 1 && !mPalettedImageData) {
// We can't safely optimize off-main-thread, so create a runnable to do it.
if (!NS_IsMainThread()) {
nsCOMPtr<nsIRunnable> runnable = new UnlockImageDataRunnable(this);
NS_DispatchToMainThread(runnable);
return NS_OK;
}
// Convert our data surface to a GPU surface if possible and release
// whatever memory we can.
Optimize();
}
mLockCount--;
return NS_OK;

Просмотреть файл

@ -230,12 +230,16 @@ public:
* that the underlying surface may not be stored in a volatile buffer on all
* platforms, and raw access to the surface (using RawAccessRef()) may be much
* more expensive than in the InitForDecoder() case.
*
* aBackend specifies the DrawTarget backend type this imgFrame is supposed
* to be drawn to.
*/
nsresult InitWithDrawable(gfxDrawable* aDrawable,
const nsIntSize& aSize,
const SurfaceFormat aFormat,
SamplingFilter aSamplingFilter,
uint32_t aImageFlags);
uint32_t aImageFlags,
gfx::BackendType aBackend);
DrawableFrameRef DrawableRef();
RawAccessFrameRef RawAccessRef();
@ -348,7 +352,7 @@ private: // methods
nsresult LockImageData();
nsresult UnlockImageData();
bool CanOptimizeOpaqueImage();
nsresult Optimize();
nsresult Optimize(gfx::DrawTarget* aTarget);
void AssertImageDataLocked() const;