mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 717921. Only have one thebes surface. r=bas
This commit is contained in:
parent
8960edcfc7
commit
57f0178ec2
@ -532,9 +532,26 @@ DataSourceSurfaceDestroy(void *dataSourceSurface)
|
||||
static_cast<DataSourceSurface*>(dataSourceSurface)->Release();
|
||||
}
|
||||
|
||||
void DestroyThebesSurface(void *data)
|
||||
{
|
||||
gfxASurface *surface = static_cast<gfxASurface*>(data);
|
||||
surface->Release();
|
||||
}
|
||||
|
||||
UserDataKey ThebesSurfaceKey;
|
||||
|
||||
// The semantics of this function are sort of weird. We snapshot the first
|
||||
// time and then return the snapshotted surface for the lifetime of the
|
||||
// draw target
|
||||
already_AddRefed<gfxASurface>
|
||||
gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
|
||||
{
|
||||
void *surface = aTarget->GetUserData(&ThebesSurfaceKey);
|
||||
if (surface) {
|
||||
nsRefPtr<gfxASurface> surf = static_cast<gfxASurface*>(surface);
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> source = aTarget->Snapshot();
|
||||
RefPtr<DataSourceSurface> data = source->GetDataSurface();
|
||||
|
||||
@ -545,12 +562,18 @@ gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
|
||||
IntSize size = data->GetSize();
|
||||
gfxASurface::gfxImageFormat format = gfxASurface::FormatFromContent(ContentForFormat(data->GetFormat()));
|
||||
|
||||
nsRefPtr<gfxImageSurface> image =
|
||||
nsRefPtr<gfxImageSurface> surf =
|
||||
new gfxImageSurface(data->GetData(), gfxIntSize(size.width, size.height),
|
||||
data->Stride(), format);
|
||||
|
||||
image->SetData(&kDrawSourceSurface, data.forget().drop(), DataSourceSurfaceDestroy);
|
||||
return image.forget();
|
||||
surf->SetData(&kDrawSourceSurface, data.forget().drop(), DataSourceSurfaceDestroy);
|
||||
|
||||
// add a reference to be held by the drawTarget
|
||||
// careful, the reference graph is getting complicated here
|
||||
surf->AddRef();
|
||||
aTarget->AddUserData(&ThebesSurfaceKey, surf.get(), DestroyThebesSurface);
|
||||
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget>
|
||||
|
@ -71,6 +71,9 @@ class gfxTextRun;
|
||||
class nsIURI;
|
||||
class nsIAtom;
|
||||
|
||||
extern mozilla::gfx::UserDataKey ThebesSurfaceKey;
|
||||
void DestroyThebesSurface(void *data);
|
||||
|
||||
extern cairo_user_data_key_t kDrawTarget;
|
||||
|
||||
// pref lang id's for font prefs
|
||||
|
@ -303,16 +303,26 @@ already_AddRefed<gfxASurface>
|
||||
gfxPlatformMac::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
|
||||
{
|
||||
if (aTarget->GetType() == BACKEND_COREGRAPHICS) {
|
||||
CGContextRef cg = static_cast<CGContextRef>(aTarget->GetNativeSurface(NATIVE_SURFACE_CGCONTEXT));
|
||||
void *surface = aTarget->GetUserData(&ThebesSurfaceKey);
|
||||
if (surface) {
|
||||
nsRefPtr<gfxASurface> surf = static_cast<gfxQuartzSurface*>(surface);
|
||||
return surf.forget();
|
||||
} else {
|
||||
CGContextRef cg = static_cast<CGContextRef>(aTarget->GetNativeSurface(NATIVE_SURFACE_CGCONTEXT));
|
||||
|
||||
//XXX: it would be nice to have an implicit conversion from IntSize to gfxIntSize
|
||||
IntSize intSize = aTarget->GetSize();
|
||||
gfxIntSize size(intSize.width, intSize.height);
|
||||
//XXX: it would be nice to have an implicit conversion from IntSize to gfxIntSize
|
||||
IntSize intSize = aTarget->GetSize();
|
||||
gfxIntSize size(intSize.width, intSize.height);
|
||||
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
new gfxQuartzSurface(cg, size);
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
new gfxQuartzSurface(cg, size);
|
||||
|
||||
return surf.forget();
|
||||
// add a reference to be held by the drawTarget
|
||||
surf->AddRef();
|
||||
aTarget->AddUserData(&ThebesSurfaceKey, surf.get(), DestroyThebesSurface);
|
||||
|
||||
return surf.forget();
|
||||
}
|
||||
}
|
||||
|
||||
return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget);
|
||||
|
@ -507,22 +507,35 @@ gfxWindowsPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
if (aTarget->GetType() == BACKEND_DIRECT2D) {
|
||||
RefPtr<ID3D10Texture2D> texture =
|
||||
static_cast<ID3D10Texture2D*>(aTarget->GetNativeSurface(NATIVE_SURFACE_D3D10_TEXTURE));
|
||||
void *surface = aTarget->GetUserData(&ThebesSurfaceKey);
|
||||
if (surface) {
|
||||
nsRefPtr<gfxASurface> surf = static_cast<gfxASurface*>(surface);
|
||||
return surf.forget();
|
||||
} else {
|
||||
RefPtr<ID3D10Texture2D> texture =
|
||||
static_cast<ID3D10Texture2D*>(aTarget->GetNativeSurface(NATIVE_SURFACE_D3D10_TEXTURE));
|
||||
|
||||
if (!texture) {
|
||||
return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget);
|
||||
if (!texture) {
|
||||
return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget);
|
||||
}
|
||||
|
||||
aTarget->Flush();
|
||||
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
new gfxD2DSurface(texture, ContentForFormat(aTarget->GetFormat()));
|
||||
|
||||
// add a reference to be held by the drawTarget
|
||||
surf->AddRef();
|
||||
aTarget->AddUserData(&ThebesSurfaceKey, surf.get(), DestroyThebesSurface);
|
||||
/* "It might be worth it to clear cairo surfaces associated with a drawtarget.
|
||||
The strong reference means for example for D2D that cairo's scratch surface
|
||||
will be kept alive (well after a user being done) and consume extra VRAM.
|
||||
We can deal with this in a follow-up though." */
|
||||
|
||||
// shouldn't this hold a reference?
|
||||
surf->SetData(&kDrawTarget, aTarget, NULL);
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
aTarget->Flush();
|
||||
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
new gfxD2DSurface(texture, ContentForFormat(aTarget->GetFormat()));
|
||||
|
||||
// shouldn't this hold a reference?
|
||||
surf->SetData(&kDrawTarget, aTarget, NULL);
|
||||
|
||||
return surf.forget();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user