Bug 1341565 - Use external image to handle mask layer. r=jrmuizel

This commit is contained in:
Ethan Lin 2017-03-10 17:51:47 +08:00
Родитель 68f1724050
Коммит 4aef499dc0
5 изменённых файлов: 73 добавлений и 36 удалений

Просмотреть файл

@ -290,7 +290,6 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
for (InfallibleTArray<WebRenderParentCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
const WebRenderParentCommand& cmd = aCommands[i];
switch (cmd.type()) {
case WebRenderParentCommand::TOpAddExternalImage: {
const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
@ -332,7 +331,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
}
IntSize size = dSurf->GetSize();
wr::ImageDescriptor descriptor(size, map.mStride, SurfaceFormat::B8G8R8A8);
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
auto slice = Range<uint8_t>(map.mData, size.height * map.mStride);
mApi->AddImage(key, descriptor, slice);

Просмотреть файл

@ -170,5 +170,64 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
//mContainer->SetImageFactory(originalIF);
}
Maybe<WrImageMask>
WebRenderImageLayer::RenderMaskLayer()
{
if (!mContainer) {
return Nothing();
}
CompositableType type = GetImageClientType();
if (type == CompositableType::UNKNOWN) {
return Nothing();
}
MOZ_ASSERT(GetImageClientType() != CompositableType::UNKNOWN);
if (GetImageClientType() == CompositableType::IMAGE && !mImageClient) {
mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
WrBridge(),
TextureFlags::DEFAULT);
if (!mImageClient) {
return Nothing();
}
mImageClient->Connect();
}
if (!mExternalImageId) {
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
MOZ_ASSERT(!mImageClient);
mExternalImageId = WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle());
} else {
// Handle CompositableType::IMAGE case
MOZ_ASSERT(mImageClient);
mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
}
}
MOZ_ASSERT(mExternalImageId);
// XXX Not good for async ImageContainer case.
AutoLockImage autoLock(mContainer);
Image* image = autoLock.GetImage();
if (!image) {
return Nothing();
}
if (mImageClient && !mImageClient->UpdateImage(mContainer, /* unused */0)) {
return Nothing();
}
WrImageKey key;
key.mNamespace = WrBridge()->GetNamespace();
key.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
gfx::IntSize size = image->GetSize();
WrImageMask imageMask;
imageMask.image = key;
imageMask.rect = wr::ToWrRect(Rect(0, 0, size.width, size.height));
imageMask.repeat = false;
return Some(imageMask);
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -33,6 +33,7 @@ protected:
public:
Layer* GetLayer() override { return this; }
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
Maybe<WrImageMask> RenderMaskLayer() override;
protected:
CompositableType GetImageClientType();

Просмотреть файл

@ -109,40 +109,14 @@ WebRenderLayer::TransformedVisibleBoundsRelativeToParent()
}
Maybe<WrImageMask>
WebRenderLayer::BuildWrMaskLayer() {
Maybe<WrImageMask> mask = Nothing();
WrImageMask imageMask;
Layer* maskLayer = GetLayer()->GetMaskLayer();
if (maskLayer) {
RefPtr<SourceSurface> surface = WebRenderLayer::ToWebRenderLayer(maskLayer)->GetAsSourceSurface();
if (surface) {
Matrix transform;
Matrix4x4 effectiveTransform = maskLayer->GetEffectiveTransform();
DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform);
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
//XXX: let's assert that the mask transform is the same as the layer transform
//transform.PostTranslate(-aDeviceOffset.x, -aDeviceOffset.y);
{
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::MapType::READ);
gfx::IntSize size = surface->GetSize();
MOZ_RELEASE_ASSERT(surface->GetFormat() == SurfaceFormat::A8, "bad format");
wr::ByteBuffer buf(size.height * map.GetStride(), map.GetData());
WrImageKey maskKey;
maskKey.mNamespace = WrBridge()->GetNamespace();
maskKey.mHandle = WrBridge()->GetNextResourceId();
WrBridge()->SendAddImage(maskKey, size, map.GetStride(), SurfaceFormat::A8, buf);
imageMask.image = maskKey;
imageMask.rect = wr::ToWrRect(Rect(0, 0, size.width, size.height));
imageMask.repeat = false;
WrManager()->AddImageKeyForDiscard(maskKey);
mask = Some(imageMask);
}
}
WebRenderLayer::BuildWrMaskLayer()
{
if (GetLayer()->GetMaskLayer()) {
WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer());
return maskLayer->RenderMaskLayer();
}
return mask;
return Nothing();
}
gfx::Rect

Просмотреть файл

@ -30,6 +30,11 @@ class WebRenderLayer
public:
virtual Layer* GetLayer() = 0;
virtual void RenderLayer(wr::DisplayListBuilder& aBuilder) = 0;
virtual Maybe<WrImageMask> RenderMaskLayer()
{
MOZ_ASSERT(false);
return Nothing();
}
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; }
static inline WebRenderLayer*
@ -54,7 +59,6 @@ protected:
gfx::Rect GetWrClipRect(gfx::Rect& aRect);
void DumpLayerInfo(const char* aLayerType, gfx::Rect& aRect);
Maybe<WrImageMask> BuildWrMaskLayer();
};
class WebRenderLayerManager final : public LayerManager