зеркало из https://github.com/mozilla/pjs.git
Bug 756767 - Part 2: Deal with CreateSourceSurfaceFromData failing. r=jrmuizel
This commit is contained in:
Родитель
5981f7c8a2
Коммит
bd74709f48
|
@ -532,6 +532,7 @@ gfxContext::DrawSurface(gfxASurface *surface, const gfxSize& size)
|
|||
cairo_fill(mCairo);
|
||||
cairo_restore(mCairo);
|
||||
} else {
|
||||
// Lifetime needs to be limited here since we may wrap surface's data.
|
||||
RefPtr<SourceSurface> surf =
|
||||
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mDT, surface);
|
||||
|
||||
|
@ -1293,6 +1294,7 @@ gfxContext::SetColor(const gfxRGBA& c)
|
|||
cairo_set_source_rgba(mCairo, c.r, c.g, c.b, c.a);
|
||||
} else {
|
||||
CurrentState().pattern = NULL;
|
||||
CurrentState().sourceSurfCairo = NULL;
|
||||
CurrentState().sourceSurface = NULL;
|
||||
|
||||
if (gfxPlatform::GetCMSMode() == eCMSMode_All) {
|
||||
|
@ -1316,6 +1318,7 @@ gfxContext::SetDeviceColor(const gfxRGBA& c)
|
|||
cairo_set_source_rgba(mCairo, c.r, c.g, c.b, c.a);
|
||||
} else {
|
||||
CurrentState().pattern = NULL;
|
||||
CurrentState().sourceSurfCairo = NULL;
|
||||
CurrentState().sourceSurface = NULL;
|
||||
CurrentState().color = ToColor(c);
|
||||
}
|
||||
|
@ -1354,6 +1357,9 @@ gfxContext::SetSource(gfxASurface *surface, const gfxPoint& offset)
|
|||
CurrentState().surfTransform = Matrix(1.0f, 0, 0, 1.0f, Float(offset.x), Float(offset.y));
|
||||
CurrentState().pattern = NULL;
|
||||
CurrentState().patternTransformChanged = false;
|
||||
// Keep the underlying cairo surface around while we keep the
|
||||
// sourceSurface.
|
||||
CurrentState().sourceSurfCairo = surface;
|
||||
CurrentState().sourceSurface =
|
||||
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mDT, surface);
|
||||
}
|
||||
|
@ -1365,6 +1371,7 @@ gfxContext::SetPattern(gfxPattern *pattern)
|
|||
if (mCairo) {
|
||||
cairo_set_source(mCairo, pattern->CairoPattern());
|
||||
} else {
|
||||
CurrentState().sourceSurfCairo = NULL;
|
||||
CurrentState().sourceSurface = NULL;
|
||||
CurrentState().patternTransformChanged = false;
|
||||
CurrentState().pattern = pattern;
|
||||
|
@ -1421,6 +1428,7 @@ gfxContext::Mask(gfxASurface *surface, const gfxPoint& offset)
|
|||
if (mCairo) {
|
||||
cairo_mask_surface(mCairo, surface->CairoSurface(), offset.x, offset.y);
|
||||
} else {
|
||||
// Lifetime needs to be limited here as we may simply wrap surface's data.
|
||||
RefPtr<SourceSurface> sourceSurf =
|
||||
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mDT, surface);
|
||||
|
||||
|
@ -1582,6 +1590,7 @@ gfxContext::PopGroupToSource()
|
|||
} else {
|
||||
RefPtr<SourceSurface> src = mDT->Snapshot();
|
||||
Restore();
|
||||
CurrentState().sourceSurfCairo = NULL;
|
||||
CurrentState().sourceSurface = src;
|
||||
CurrentState().pattern = NULL;
|
||||
CurrentState().patternTransformChanged = false;
|
||||
|
|
|
@ -713,6 +713,7 @@ private:
|
|||
bool opIsClear;
|
||||
Color color;
|
||||
nsRefPtr<gfxPattern> pattern;
|
||||
nsRefPtr<gfxASurface> sourceSurfCairo;
|
||||
mozilla::RefPtr<SourceSurface> sourceSurface;
|
||||
Matrix surfTransform;
|
||||
Matrix transform;
|
||||
|
|
|
@ -151,6 +151,8 @@ gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
|
|||
|
||||
if (!mSourceSurface) {
|
||||
nsRefPtr<gfxASurface> gfxSurf = gfxASurface::Wrap(surf);
|
||||
// The underlying surface here will be kept around by the gfxPattern.
|
||||
// This function is intended to be used right away.
|
||||
mSourceSurface =
|
||||
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, gfxSurf);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
@ -472,6 +472,12 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa
|
|||
if (!srcBuffer) {
|
||||
nsRefPtr<gfxImageSurface> imgSurface = aSurface->GetAsImageSurface();
|
||||
|
||||
bool isWin32ImageSurf = false;
|
||||
|
||||
if (imgSurface && aSurface->GetType() != gfxASurface::SurfaceTypeWin32) {
|
||||
isWin32ImageSurf = true;
|
||||
}
|
||||
|
||||
if (!imgSurface) {
|
||||
imgSurface = new gfxImageSurface(aSurface->GetSize(), gfxASurface::FormatFromContent(aSurface->GetContentType()));
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(imgSurface);
|
||||
|
@ -498,17 +504,36 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa
|
|||
NS_RUNTIMEABORT("Invalid surface format!");
|
||||
}
|
||||
|
||||
IntSize size = IntSize(imgSurface->GetSize().width, imgSurface->GetSize().height);
|
||||
srcBuffer = aTarget->CreateSourceSurfaceFromData(imgSurface->Data(),
|
||||
IntSize(imgSurface->GetSize().width, imgSurface->GetSize().height),
|
||||
size,
|
||||
imgSurface->Stride(),
|
||||
format);
|
||||
|
||||
if (!srcBuffer) {
|
||||
// We need to check if our gfxASurface will keep the underlying data
|
||||
// alive! This is true if gfxASurface actually -is- an ImageSurface or
|
||||
// if it is a gfxWindowsSurface which supportes GetAsImageSurface.
|
||||
if (imgSurface != aSurface && !isWin32ImageSurf) {
|
||||
// This shouldn't happen for now, it can be easily supported by making
|
||||
// a copy. For now let's just abort.
|
||||
NS_RUNTIMEABORT("Attempt to create unsupported SourceSurface from"
|
||||
"non-image surface.");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
srcBuffer = Factory::CreateWrappingDataSourceSurface(imgSurface->Data(),
|
||||
imgSurface->Stride(),
|
||||
size, format);
|
||||
|
||||
}
|
||||
|
||||
cairo_surface_t *nullSurf =
|
||||
cairo_null_surface_create(CAIRO_CONTENT_COLOR_ALPHA);
|
||||
cairo_surface_set_user_data(nullSurf,
|
||||
&kSourceSurface,
|
||||
imgSurface,
|
||||
NULL);
|
||||
&kSourceSurface,
|
||||
imgSurface,
|
||||
NULL);
|
||||
cairo_surface_attach_snapshot(imgSurface->CairoSurface(), nullSurf, SourceSnapshotDetached);
|
||||
cairo_surface_destroy(nullSurf);
|
||||
}
|
||||
|
|
|
@ -163,6 +163,11 @@ public:
|
|||
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
|
||||
CreateDrawTargetForSurface(gfxASurface *aSurface);
|
||||
|
||||
/*
|
||||
* Creates a SourceSurface for a gfxASurface. This surface should -not- be
|
||||
* held around by the user after the underlying gfxASurface has been
|
||||
* destroyed as a copy of the data is not guaranteed.
|
||||
*/
|
||||
virtual mozilla::RefPtr<mozilla::gfx::SourceSurface>
|
||||
GetSourceSurfaceForSurface(mozilla::gfx::DrawTarget *aTarget, gfxASurface *aSurface);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче