Bug 1234485 - Part 5. Implement MaskImageData::CreateImageAndImageContainer.
Simply move some code from ContainerState::CreateMaskLayer into MaskImageData,
so that we can reuse it later.
MozReview-Commit-ID: H2zktYL9PIh
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -1522,39 +1522,45 @@ struct MaskLayerUserData : public LayerU
nsTArray<DisplayItemClip::RoundedRect> mRoundedClipRects;
// scale from the masked layer which is applied to the mask
float mScaleX, mScaleY;
// The ContainerLayerParameters offset which is applied to the mask's transform.
nsIntPoint mOffset;
int32_t mAppUnitsPerDevPixel;
};
+/*
+ * A helper object to create a draw target for painting mask and create a
+ * image container to hold the drawing result. The caller can then bind this
+ * image container with a image mask layer via ImageLayer::SetContainer.
+ */
class MaskImageData
{
public:
MaskImageData(const gfx::IntSize& aSize, LayerManager* aLayerManager)
: mTextureClientLocked(false)
, mSize(aSize)
, mLayerManager(aLayerManager)
{
+ MOZ_ASSERT(!mSize.IsEmpty());
+ MOZ_ASSERT(mLayerManager);
}
~MaskImageData()
{
if (mTextureClientLocked) {
MOZ_ASSERT(mTextureClient);
// Clear DrawTarget before Unlock.
mDrawTarget = nullptr;
mTextureClient->Unlock();
}
}
gfx::DrawTarget* CreateDrawTarget()
{
- MOZ_ASSERT(mLayerManager);
if (mDrawTarget) {
return mDrawTarget;
}
if (mLayerManager->GetBackendType() == LayersBackend::LAYERS_BASIC) {
mDrawTarget = mLayerManager->CreateOptimalMaskDrawTarget(mSize);
return mDrawTarget;
}
@@ -1580,16 +1586,30 @@ public:
if (!mTextureClientLocked) {
return nullptr;
}
mDrawTarget = mTextureClient->BorrowDrawTarget();
return mDrawTarget;
}
+ already_AddRefed<ImageContainer> CreateImageAndImageContainer()
+ {
+ RefPtr<ImageContainer> container = mLayerManager->CreateImageContainer();
+ RefPtr<Image> image = CreateImage();
+
+ if (!image) {
+ return nullptr;
+ }
+ container->SetCurrentImageInTransaction(image);
+
+ return container.forget();
+ }
+
+private:
already_AddRefed<Image> CreateImage()
{
if (mLayerManager->GetBackendType() == LayersBackend::LAYERS_BASIC &&
mDrawTarget) {
RefPtr<SourceSurface> surface = mDrawTarget->Snapshot();
RefPtr<SourceSurfaceImage> image = new SourceSurfaceImage(mSize, surface);
// Disallow BIGIMAGE (splitting into multiple textures) for mask
// layer images
@@ -1599,20 +1619,20 @@ public:
if (mLayerManager->GetBackendType() == LayersBackend::LAYERS_CLIENT &&
mTextureClient &&
mDrawTarget) {
RefPtr<TextureWrapperImage> image =
new TextureWrapperImage(mTextureClient, gfx::IntRect(gfx::IntPoint(0, 0), mSize));
return image.forget();
}
+
return nullptr;
}
-private:
bool mTextureClientLocked;
gfx::IntSize mSize;
LayerManager* mLayerManager;
RefPtr<gfx::DrawTarget> mDrawTarget;
RefPtr<TextureClient> mTextureClient;
};
/**
@@ -6109,24 +6129,23 @@ ContainerState::CreateMaskLayer(Layer *a
// paint the clipping rects with alpha to create the mask
aClip.FillIntersectionOfRoundedRectClips(context,
Color(1.f, 1.f, 1.f, 1.f),
newData.mAppUnitsPerDevPixel,
0,
aRoundedRectClipCount);
// build the image and container
- container = aLayer->Manager()->CreateImageContainer();
+ MOZ_ASSERT(aLayer->Manager() == mManager);
+ container = imageData.CreateImageAndImageContainer();
NS_ASSERTION(container, "Could not create image container for mask layer.");
- RefPtr<Image> image = imageData.CreateImage();
- if (!image) {
+ if (!container) {
return nullptr;
}
- container->SetCurrentImageInTransaction(image);
GetMaskLayerImageCache()->PutImage(newKey.forget(), container);
}
maskLayer->SetContainer(container);
maskTransform.Invert();
Matrix4x4 matrix = Matrix4x4::From2D(maskTransform);