Bug 757346; mask image format stuff - use A8 textures (except DX10) and some small, misc fixes. r=roc

This commit is contained in:
Nicholas Cameron 2012-06-26 09:44:41 +12:00
parent 841c20e037
commit eabed73236
12 changed files with 94 additions and 9 deletions

View File

@ -181,6 +181,12 @@ LayerManager::CreateOptimalSurface(const gfxIntSize &aSize,
CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFormat));
}
already_AddRefed<gfxASurface>
LayerManager::CreateOptimalMaskSurface(const gfxIntSize &aSize)
{
return CreateOptimalSurface(aSize, gfxASurface::ImageFormatA8);
}
TemporaryRef<DrawTarget>
LayerManager::CreateDrawTarget(const IntSize &aSize,
SurfaceFormat aFormat)
@ -376,8 +382,6 @@ Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurf
gfxMatrix maskTranslation;
bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(&maskTranslation);
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
NS_ASSERTION(!maskTranslation.HasNonTranslation(),
"Mask layer has invalid transform.");
#endif
mMaskLayer->mEffectiveTransform.PreMultiply(mMaskLayer->GetTransform());
}

View File

@ -422,12 +422,21 @@ public:
virtual LayersBackend GetBackendType() = 0;
/**
* Creates a layer which is optimized for inter-operating with this layer
* Creates a surface which is optimized for inter-operating with this layer
* manager.
*/
virtual already_AddRefed<gfxASurface>
CreateOptimalSurface(const gfxIntSize &aSize,
gfxASurface::gfxImageFormat imageFormat);
/**
* Creates a surface for alpha masks which is optimized for inter-operating
* with this layer manager. In contrast to CreateOptimalSurface, this surface
* is optimised for drawing alpha only and we assume that drawing the mask
* is fairly simple.
*/
virtual already_AddRefed<gfxASurface>
CreateOptimalMaskSurface(const gfxIntSize &aSize);
/**
* Creates a DrawTarget which is optimized for inter-operating with this
@ -693,8 +702,7 @@ public:
if (aMaskLayer) {
gfxMatrix maskTransform;
bool maskIs2D = aMaskLayer->GetTransform().CanDraw2D(&maskTransform);
NS_ASSERTION(maskIs2D && maskTransform.HasOnlyIntegerTranslation(),
"Mask layer has invalid transform.");
NS_ASSERTION(maskIs2D, "Mask layer has invalid transform.");
}
#endif

View File

@ -431,6 +431,14 @@ LayerManagerD3D10::CreateOptimalSurface(const gfxIntSize &aSize,
return surface.forget();
}
already_AddRefed<gfxASurface>
LayerManagerD3D10::CreateOptimalMaskSurface(const gfxIntSize &aSize)
{
return CreateOptimalSurface(aSize, gfxASurface::ImageFormatARGB32);
}
TemporaryRef<DrawTarget>
LayerManagerD3D10::CreateDrawTarget(const IntSize &aSize,
SurfaceFormat aFormat)

View File

@ -138,6 +138,9 @@ public:
CreateOptimalSurface(const gfxIntSize &aSize,
gfxASurface::gfxImageFormat imageFormat);
virtual already_AddRefed<gfxASurface>
CreateOptimalMaskSurface(const gfxIntSize &aSize);
virtual TemporaryRef<mozilla::gfx::DrawTarget>
CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
mozilla::gfx::SurfaceFormat aFormat);

View File

@ -425,6 +425,13 @@ LayerManagerOGL::EndTransaction(DrawThebesLayerCallback aCallback,
#endif
}
already_AddRefed<gfxASurface>
LayerManagerOGL::CreateOptimalMaskSurface(const gfxIntSize &aSize)
{
return gfxPlatform::GetPlatform()->
CreateOffscreenImageSurface(aSize, gfxASurface::CONTENT_ALPHA);
}
already_AddRefed<ThebesLayer>
LayerManagerOGL::CreateThebesLayer()
{

View File

@ -142,6 +142,9 @@ public:
virtual LayersBackend GetBackendType() { return LAYERS_OPENGL; }
virtual void GetBackendName(nsAString& name) { name.AssignLiteral("OpenGL"); }
virtual already_AddRefed<gfxASurface>
CreateOptimalMaskSurface(const gfxIntSize &aSize);
/**
* Helper methods.
*/

View File

@ -387,6 +387,16 @@ gfxPlatform::~gfxPlatform()
#endif
}
already_AddRefed<gfxASurface>
gfxPlatform::CreateOffscreenImageSurface(const gfxIntSize& aSize,
gfxASurface::gfxContentType aContentType)
{
nsRefPtr<gfxASurface> newSurface;
newSurface = new gfxImageSurface(aSize, OptimalFormatForContent(aContentType));
return newSurface.forget();
}
already_AddRefed<gfxASurface>
gfxPlatform::OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format)

View File

@ -156,6 +156,17 @@ public:
virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxContentType contentType) = 0;
/**
* Create an offscreen surface of the given dimensions and image format which
* can be converted to a gfxImageSurface without copying. If we can provide
* a platform-hosted surface, then we will return that instead of an actual
* gfxImageSurface.
* Sub-classes should override this method if CreateOffscreenSurface returns a
* surface which implements GetAsImageSurface
*/
virtual already_AddRefed<gfxASurface>
CreateOffscreenImageSurface(const gfxIntSize& aSize,
gfxASurface::gfxContentType aContentType);
virtual already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format);

View File

@ -31,6 +31,17 @@ public:
already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxContentType contentType);
virtual already_AddRefed<gfxASurface>
CreateOffscreenImageSurface(const gfxIntSize& aSize,
gfxASurface::gfxContentType aContentType)
{
nsRefPtr<gfxASurface> surface = CreateOffscreenSurface(aSize, aContentType);
#ifdef DEBUG
nsRefPtr<gfxImageSurface> imageSurface = surface->GetAsImageSurface();
NS_ASSERTION(imageSurface, "Surface cannot be converted to a gfxImageSurface");
#endif
return surface;
}
already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format);

View File

@ -712,6 +712,24 @@ gfxWindowsPlatform::CreateOffscreenSurface(const gfxIntSize& size,
return surf;
}
already_AddRefed<gfxASurface>
gfxWindowsPlatform::CreateOffscreenImageSurface(const gfxIntSize& aSize,
gfxASurface::gfxContentType aContentType)
{
#ifdef CAIRO_HAS_D2D_SURFACE
if (mRenderMode == RENDER_DIRECT2D) {
return new gfxImageSurface(aSize, OptimalFormatForContent(aContentType));
}
#endif
nsRefPtr<gfxASurface> surface = CreateOffscreenSurface(aSize, aContentType);
#ifdef DEBUG
nsRefPtr<gfxImageSurface> imageSurface = surface->GetAsImageSurface();
NS_ASSERTION(imageSurface, "Surface cannot be converted to a gfxImageSurface");
#endif
return surface;
}
RefPtr<ScaledFont>
gfxWindowsPlatform::GetScaledFontForFont(gfxFont *aFont)
{

View File

@ -103,6 +103,10 @@ public:
already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxContentType contentType);
virtual already_AddRefed<gfxASurface>
CreateOffscreenImageSurface(const gfxIntSize& aSize,
gfxASurface::gfxContentType aContentType);
virtual mozilla::RefPtr<mozilla::gfx::ScaledFont>
GetScaledFontForFont(gfxFont *aFont);
virtual already_AddRefed<gfxASurface>

View File

@ -2906,8 +2906,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
} else {
// no existing mask image, so build a new one
nsRefPtr<gfxASurface> surface =
aLayer->Manager()->CreateOptimalSurface(surfaceSize,
gfxASurface::ImageFormatARGB32);
aLayer->Manager()->CreateOptimalMaskSurface(surfaceSize);
// fail if we can't get the right surface
if (!surface || surface->CairoStatus()) {
@ -2919,7 +2918,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
context->Multiply(imageTransform);
// paint the clipping rects with alpha to create the mask
context->SetColor(gfxRGBA(0, 0, 0, 1));
context->SetColor(gfxRGBA(1, 1, 1, 1));
aClip.DrawRoundedRectsTo(context, A2D, 0, aRoundedRectClipCount);
// build the image and container
@ -2945,7 +2944,6 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
userData->mScaleY = newData.mScaleY;
userData->mRoundedClipRects.SwapElements(newData.mRoundedClipRects);
userData->mImageKey = key;
key->AddRef();
aLayer->SetMaskLayer(maskLayer);
return;