mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 722217; keep only a single snapshot. r=jrmuizel
This commit is contained in:
parent
d6a99a40e3
commit
683496a28c
@ -297,7 +297,7 @@ DrawTargetCairo::DrawTargetCairo()
|
||||
|
||||
DrawTargetCairo::~DrawTargetCairo()
|
||||
{
|
||||
MarkSnapshotsIndependent();
|
||||
MarkSnapshotIndependent();
|
||||
if (mPathObserver) {
|
||||
mPathObserver->ForgetDrawTarget();
|
||||
}
|
||||
@ -316,14 +316,18 @@ DrawTargetCairo::GetSize()
|
||||
TemporaryRef<SourceSurface>
|
||||
DrawTargetCairo::Snapshot()
|
||||
{
|
||||
if (mSnapshot) {
|
||||
return mSnapshot;
|
||||
}
|
||||
|
||||
IntSize size = GetSize();
|
||||
|
||||
cairo_content_t content = cairo_surface_get_content(mSurface);
|
||||
RefPtr<SourceSurfaceCairo> surf = new SourceSurfaceCairo(mSurface, size,
|
||||
CairoContentToGfxFormat(content),
|
||||
this);
|
||||
AppendSnapshot(surf);
|
||||
return surf;
|
||||
mSnapshot = new SourceSurfaceCairo(mSurface,
|
||||
size,
|
||||
CairoContentToGfxFormat(content),
|
||||
this);
|
||||
return mSnapshot;
|
||||
}
|
||||
|
||||
void
|
||||
@ -868,45 +872,21 @@ DrawTargetCairo::GetNativeSurface(NativeSurfaceType aType)
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetCairo::MarkSnapshotsIndependent()
|
||||
DrawTargetCairo::MarkSnapshotIndependent()
|
||||
{
|
||||
// Make a copy of the vector, since MarkIndependent implicitly modifies mSnapshots.
|
||||
std::vector<SourceSurfaceCairo*> snapshots = mSnapshots;
|
||||
for (std::vector<SourceSurfaceCairo*>::iterator iter = snapshots.begin();
|
||||
iter != snapshots.end();
|
||||
++iter) {
|
||||
(*iter)->MarkIndependent();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetCairo::AppendSnapshot(SourceSurfaceCairo* aSnapshot)
|
||||
{
|
||||
mSnapshots.push_back(aSnapshot);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetCairo::RemoveSnapshot(SourceSurfaceCairo* aSnapshot)
|
||||
{
|
||||
std::vector<SourceSurfaceCairo*>::iterator iter = std::find(mSnapshots.begin(),
|
||||
mSnapshots.end(),
|
||||
aSnapshot);
|
||||
if (iter != mSnapshots.end()) {
|
||||
mSnapshots.erase(iter);
|
||||
if (mSnapshot) {
|
||||
if (mSnapshot->refCount() > 1) {
|
||||
// We only need to worry about snapshots that someone else knows about
|
||||
mSnapshot->DrawTargetWillChange();
|
||||
}
|
||||
mSnapshot = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetCairo::WillChange(const Path* aPath /* = nullptr */)
|
||||
{
|
||||
if (!mSnapshots.empty()) {
|
||||
for (std::vector<SourceSurfaceCairo*>::iterator iter = mSnapshots.begin();
|
||||
iter != mSnapshots.end(); ++iter) {
|
||||
(*iter)->DrawTargetWillChange();
|
||||
}
|
||||
// All snapshots will now have copied data.
|
||||
mSnapshots.clear();
|
||||
}
|
||||
MarkSnapshotIndependent();
|
||||
|
||||
if (mPathObserver &&
|
||||
(!aPath || !mPathObserver->ContainsPath(aPath))) {
|
||||
|
@ -147,19 +147,14 @@ private: // methods
|
||||
const DrawOptions& aOptions,
|
||||
DrawPatternType aDrawType);
|
||||
|
||||
// Copy-on-write support for snapshot surfaces.
|
||||
friend class SourceSurfaceCairo;
|
||||
void AppendSnapshot(SourceSurfaceCairo* aSnapshot);
|
||||
void RemoveSnapshot(SourceSurfaceCairo* aSnapshot);
|
||||
|
||||
// Call before you make any changes to the backing surface with which this
|
||||
// context is associated. Pass the path you're going to be using if you have
|
||||
// one.
|
||||
void WillChange(const Path* aPath = nullptr);
|
||||
|
||||
// Call if there is any reason to disassociate all snapshots from this draw
|
||||
// Call if there is any reason to disassociate the snapshot from this draw
|
||||
// target; for example, because we're going to be destroyed.
|
||||
void MarkSnapshotsIndependent();
|
||||
void MarkSnapshotIndependent();
|
||||
|
||||
// If the current operator is "source" then clear the destination before we
|
||||
// draw into it, to simulate the effect of an unbounded source operator.
|
||||
@ -168,7 +163,10 @@ private: // data
|
||||
cairo_t* mContext;
|
||||
cairo_surface_t* mSurface;
|
||||
IntSize mSize;
|
||||
std::vector<SourceSurfaceCairo*> mSnapshots;
|
||||
|
||||
// The latest snapshot of this surface. This needs to be told when this
|
||||
// target is modified. We keep it alive as a cache.
|
||||
RefPtr<SourceSurfaceCairo> mSnapshot;
|
||||
|
||||
// It is safe to use a regular pointer here because the CairoPathContext will
|
||||
// deregister itself on destruction. Using a RefPtr would extend the life-
|
||||
|
@ -42,7 +42,6 @@ SourceSurfaceCairo::SourceSurfaceCairo(cairo_surface_t* aSurface,
|
||||
|
||||
SourceSurfaceCairo::~SourceSurfaceCairo()
|
||||
{
|
||||
MarkIndependent();
|
||||
cairo_surface_destroy(mSurface);
|
||||
}
|
||||
|
||||
@ -111,15 +110,6 @@ SourceSurfaceCairo::DrawTargetWillChange()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceCairo::MarkIndependent()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->RemoveSnapshot(this);
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DataSourceSurfaceCairo::DataSourceSurfaceCairo(cairo_surface_t* imageSurf)
|
||||
: mImageSurface(imageSurf)
|
||||
{
|
||||
|
@ -36,7 +36,6 @@ public:
|
||||
private: // methods
|
||||
friend class DrawTargetCairo;
|
||||
void DrawTargetWillChange();
|
||||
void MarkIndependent();
|
||||
|
||||
private: // data
|
||||
IntSize mSize;
|
||||
|
Loading…
Reference in New Issue
Block a user