Bug 1089454: Prevent usage of incompatible graphics objects after device reset. r=jrmuizel

This commit is contained in:
Bas Schouten 2015-01-28 00:54:19 +00:00
parent 8e730610d5
commit e7a45f235f
7 changed files with 39 additions and 5 deletions

View File

@ -162,6 +162,7 @@ public:
virtual ~GradientStops() {} virtual ~GradientStops() {}
virtual BackendType GetBackendType() const = 0; virtual BackendType GetBackendType() const = 0;
virtual bool IsValid() const { return true; }
protected: protected:
GradientStops() {} GradientStops() {}

View File

@ -1300,7 +1300,7 @@ DrawTargetD2D::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops, E
return nullptr; return nullptr;
} }
return new GradientStopsD2D(stopCollection); return new GradientStopsD2D(stopCollection, Factory::GetDirect3D11Device());
} }
TemporaryRef<FilterNode> TemporaryRef<FilterNode>

View File

@ -725,7 +725,7 @@ DrawTargetD2D1::CreateGradientStops(GradientStop *rawStops, uint32_t aNumStops,
return nullptr; return nullptr;
} }
return new GradientStopsD2D(stopCollection); return new GradientStopsD2D(stopCollection, Factory::GetDirect3D11Device());
} }
TemporaryRef<FilterNode> TemporaryRef<FilterNode>
@ -1228,6 +1228,12 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)), D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)),
stops->mStopCollection, stops->mStopCollection,
byRef(gradBrush)); byRef(gradBrush));
if (!gradBrush) {
gfxWarning() << "Couldn't create gradient brush.";
return CreateTransparentBlackBrush();
}
return gradBrush.forget(); return gradBrush.forget();
} }
if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) { if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) {
@ -1251,6 +1257,11 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
stops->mStopCollection, stops->mStopCollection,
byRef(gradBrush)); byRef(gradBrush));
if (!gradBrush) {
gfxWarning() << "Couldn't create gradient brush.";
return CreateTransparentBlackBrush();
}
return gradBrush.forget(); return gradBrush.forget();
} }
if (aPattern.GetType() == PatternType::SURFACE) { if (aPattern.GetType() == PatternType::SURFACE) {
@ -1279,6 +1290,8 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
Float(pat->mSurface->GetSize().height)); Float(pat->mSurface->GetSize().height));
} }
MOZ_ASSERT(pat->mSurface->IsValid());
RefPtr<ID2D1ImageBrush> imageBrush; RefPtr<ID2D1ImageBrush> imageBrush;
RefPtr<ID2D1Image> image = GetImageForSurface(pat->mSurface, mat, pat->mExtendMode, !pat->mSamplingRect.IsEmpty() ? &pat->mSamplingRect : nullptr); RefPtr<ID2D1Image> image = GetImageForSurface(pat->mSurface, mat, pat->mExtendMode, !pat->mSamplingRect.IsEmpty() ? &pat->mSamplingRect : nullptr);

View File

@ -17,17 +17,21 @@ class GradientStopsD2D : public GradientStops
{ {
public: public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsD2D) MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsD2D)
GradientStopsD2D(ID2D1GradientStopCollection *aStopCollection) GradientStopsD2D(ID2D1GradientStopCollection *aStopCollection, ID3D11Device *aDevice)
: mStopCollection(aStopCollection) : mStopCollection(aStopCollection)
, mDevice(aDevice)
{} {}
virtual BackendType GetBackendType() const { return BackendType::DIRECT2D; } virtual BackendType GetBackendType() const { return BackendType::DIRECT2D; }
virtual bool IsValid() const MOZ_FINAL{ return mDevice == Factory::GetDirect3D11Device(); }
private: private:
friend class DrawTargetD2D; friend class DrawTargetD2D;
friend class DrawTargetD2D1; friend class DrawTargetD2D1;
mutable RefPtr<ID2D1GradientStopCollection> mStopCollection; mutable RefPtr<ID2D1GradientStopCollection> mStopCollection;
RefPtr<ID3D11Device> mDevice;
}; };
} }

View File

@ -185,7 +185,15 @@ gfxGradientCache::GetGradientStops(const DrawTarget *aDT, nsTArray<GradientStop>
} }
GradientCacheData* cached = GradientCacheData* cached =
gGradientCache->Lookup(aStops, aExtend, aDT->GetBackendType()); gGradientCache->Lookup(aStops, aExtend, aDT->GetBackendType());
return cached ? cached->mStops : nullptr; if (cached && cached->mStops) {
if (!cached->mStops->IsValid()) {
gGradientCache->NotifyExpired(cached);
} else {
return cached->mStops;
}
}
return nullptr;
} }
GradientStops * GradientStops *

View File

@ -673,6 +673,8 @@ protected:
// Hardware vsync source. Only valid on parent process // Hardware vsync source. Only valid on parent process
nsRefPtr<mozilla::gfx::VsyncSource> mVsyncSource; nsRefPtr<mozilla::gfx::VsyncSource> mVsyncSource;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mScreenReferenceDrawTarget;
private: private:
/** /**
* Start up Thebes. * Start up Thebes.
@ -688,7 +690,6 @@ private:
virtual void GetPlatformCMSOutputProfile(void *&mem, size_t &size); virtual void GetPlatformCMSOutputProfile(void *&mem, size_t &size);
nsRefPtr<gfxASurface> mScreenReferenceSurface; nsRefPtr<gfxASurface> mScreenReferenceSurface;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mScreenReferenceDrawTarget;
nsTArray<uint32_t> mCJKPrefLangs; nsTArray<uint32_t> mCJKPrefLangs;
nsCOMPtr<nsIObserver> mSRGBOverrideObserver; nsCOMPtr<nsIObserver> mSRGBOverrideObserver;
nsCOMPtr<nsIObserver> mFontPrefsObserver; nsCOMPtr<nsIObserver> mFontPrefsObserver;

View File

@ -386,6 +386,7 @@ gfxWindowsPlatform::UpdateRenderMode()
/* Pick the default render mode for /* Pick the default render mode for
* desktop. * desktop.
*/ */
bool didReset = false;
if (DidRenderingDeviceReset()) { if (DidRenderingDeviceReset()) {
mD3D11DeviceInitialized = false; mD3D11DeviceInitialized = false;
mD3D11Device = nullptr; mD3D11Device = nullptr;
@ -395,6 +396,8 @@ gfxWindowsPlatform::UpdateRenderMode()
imgLoader::Singleton()->ClearCache(true); imgLoader::Singleton()->ClearCache(true);
imgLoader::Singleton()->ClearCache(false); imgLoader::Singleton()->ClearCache(false);
Factory::SetDirect3D11Device(nullptr); Factory::SetDirect3D11Device(nullptr);
didReset = true;
} }
mRenderMode = RENDER_GDI; mRenderMode = RENDER_GDI;
@ -512,6 +515,10 @@ gfxWindowsPlatform::UpdateRenderMode()
contentMask |= BackendTypeBit(BackendType::SKIA); contentMask |= BackendTypeBit(BackendType::SKIA);
InitBackendPrefs(canvasMask, defaultBackend, InitBackendPrefs(canvasMask, defaultBackend,
contentMask, defaultBackend); contentMask, defaultBackend);
if (didReset) {
mScreenReferenceDrawTarget = CreateOffscreenContentDrawTarget(IntSize(1, 1), SurfaceFormat::B8G8R8A8);
}
} }
#ifdef CAIRO_HAS_D2D_SURFACE #ifdef CAIRO_HAS_D2D_SURFACE