Bug 1657523 - Compute the scale from size for async image pipelines in the compositor process, so that we get the size matching the current texture. r=aosmond

Differential Revision: https://phabricator.services.mozilla.com/D86132
This commit is contained in:
Matt Woodrow 2020-08-06 21:09:55 +00:00
Родитель 4719cf3e7d
Коммит 852a191d88
8 изменённых файлов: 23 добавлений и 76 удалений

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

@ -79,12 +79,9 @@ struct OpReleaseTextureOfImage {
struct OpUpdateAsyncImagePipeline {
PipelineId pipelineId;
LayoutDeviceRect scBounds;
Matrix4x4 scTransform;
MaybeIntSize scaleToSize;
Rotation rotation;
ImageRendering filter;
MixBlendMode mixBlendMode;
LayoutDeviceSize scaleFromSize;
};
struct OpUpdatedAsyncImagePipeline {

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

@ -180,10 +180,8 @@ void AsyncImagePipelineManager::RemoveAsyncImagePipeline(
void AsyncImagePipelineManager::UpdateAsyncImagePipeline(
const wr::PipelineId& aPipelineId, const LayoutDeviceRect& aScBounds,
const gfx::Matrix4x4& aScTransform, const gfx::MaybeIntSize& aScaleToSize,
const VideoInfo::Rotation aRotation, const wr::ImageRendering& aFilter,
const wr::MixBlendMode& aMixBlendMode,
const LayoutDeviceSize& aScaleFromSize) {
const wr::MixBlendMode& aMixBlendMode) {
if (mDestroyed) {
return;
}
@ -193,8 +191,7 @@ void AsyncImagePipelineManager::UpdateAsyncImagePipeline(
return;
}
pipeline->mInitialised = true;
pipeline->Update(aScBounds, aScTransform, aScaleToSize, aRotation, aFilter,
aMixBlendMode, aScaleFromSize);
pipeline->Update(aScBounds, aRotation, aFilter, aMixBlendMode);
}
Maybe<TextureHost::ResourceUpdateOp> AsyncImagePipelineManager::UpdateImageKeys(
@ -377,8 +374,6 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline(
aPipeline->mIsChanged = false;
gfx::Matrix4x4 scTransform = aPipeline->mScTransform;
wr::DisplayListBuilder builder(aPipelineId);
float opacity = 1.0f;
@ -387,23 +382,13 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline(
params.mix_blend_mode = aPipeline->mMixBlendMode;
wr::WrComputedTransformData computedTransform;
if (!aPipeline->mScaleFromSize.IsEmpty() ||
aPipeline->mRotation != VideoInfo::Rotation::kDegree_0) {
MOZ_ASSERT(scTransform.IsIdentity());
computedTransform.vertical_flip =
aPipeline->mCurrentTexture && aPipeline->mCurrentTexture->NeedsYFlip();
computedTransform.scale_from = wr::ToLayoutSize(aPipeline->mScaleFromSize);
computedTransform.rotation = ToWrRotation(aPipeline->mRotation);
params.computed_transform = &computedTransform;
} else {
if (aPipeline->mCurrentTexture &&
aPipeline->mCurrentTexture->NeedsYFlip()) {
scTransform
.PreTranslate(0, aPipeline->mCurrentTexture->GetSize().height, 0)
.PreScale(1, -1, 1);
}
params.mTransformPtr = scTransform.IsIdentity() ? nullptr : &scTransform;
}
computedTransform.vertical_flip =
aPipeline->mCurrentTexture && aPipeline->mCurrentTexture->NeedsYFlip();
computedTransform.scale_from = {
float(aPipeline->mCurrentTexture->GetSize().width),
float(aPipeline->mCurrentTexture->GetSize().height)};
computedTransform.rotation = ToWrRotation(aPipeline->mRotation);
params.computed_transform = &computedTransform;
Maybe<wr::WrSpatialId> referenceFrameId = builder.PushStackingContext(
params, wr::ToLayoutRect(aPipeline->mScBounds),
@ -418,10 +403,6 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline(
if (aPipeline->mCurrentTexture && !keys.IsEmpty()) {
LayoutDeviceRect rect(0, 0, aPipeline->mCurrentTexture->GetSize().width,
aPipeline->mCurrentTexture->GetSize().height);
if (aPipeline->mScaleToSize.isSome()) {
rect = LayoutDeviceRect(0, 0, aPipeline->mScaleToSize.value().width,
aPipeline->mScaleToSize.value().height);
}
if (aPipeline->mUseExternalImage) {
MOZ_ASSERT(aPipeline->mCurrentTexture->AsWebRenderTextureHost());

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

@ -101,12 +101,9 @@ class AsyncImagePipelineManager final {
void UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId,
const LayoutDeviceRect& aScBounds,
const gfx::Matrix4x4& aScTransform,
const gfx::MaybeIntSize& aScaleToSize,
VideoInfo::Rotation aRotation,
const wr::ImageRendering& aFilter,
const wr::MixBlendMode& aMixBlendMode,
const LayoutDeviceSize& aScaleFromSize);
const wr::MixBlendMode& aMixBlendMode);
void ApplyAsyncImagesOfImageBridge(wr::TransactionBuilder& aSceneBuilderTxn,
wr::TransactionBuilder& aFastTxn);
void ApplyAsyncImageForPipeline(const wr::PipelineId& aPipelineId,
@ -181,33 +178,22 @@ class AsyncImagePipelineManager final {
struct AsyncImagePipeline {
AsyncImagePipeline();
void Update(const LayoutDeviceRect& aScBounds,
const gfx::Matrix4x4& aScTransform,
const gfx::MaybeIntSize& aScaleToSize,
VideoInfo::Rotation aRotation,
const wr::ImageRendering& aFilter,
const wr::MixBlendMode& aMixBlendMode,
const LayoutDeviceSize& aScaleFromSize) {
const wr::MixBlendMode& aMixBlendMode) {
mIsChanged |= !mScBounds.IsEqualEdges(aScBounds) ||
mScTransform != aScTransform ||
mScaleToSize != aScaleToSize || mRotation != aRotation ||
mFilter != aFilter || mMixBlendMode != aMixBlendMode ||
mScaleFromSize != aScaleFromSize;
mRotation != aRotation || mFilter != aFilter ||
mMixBlendMode != aMixBlendMode;
mScBounds = aScBounds;
mScTransform = aScTransform;
mScaleToSize = aScaleToSize;
mRotation = aRotation;
mFilter = aFilter;
mMixBlendMode = aMixBlendMode;
mScaleFromSize = aScaleFromSize;
}
bool mInitialised;
bool mIsChanged;
bool mUseExternalImage;
LayoutDeviceRect mScBounds;
LayoutDeviceSize mScaleFromSize;
gfx::Matrix4x4 mScTransform;
gfx::MaybeIntSize mScaleToSize;
VideoInfo::Rotation mRotation;
wr::ImageRendering mFilter;
wr::MixBlendMode mMixBlendMode;

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

@ -1352,8 +1352,8 @@ bool WebRenderBridgeParent::ProcessWebRenderParentCommands(
const OpUpdateAsyncImagePipeline& op =
cmd.get_OpUpdateAsyncImagePipeline();
mAsyncImageManager->UpdateAsyncImagePipeline(
op.pipelineId(), op.scBounds(), op.scTransform(), op.scaleToSize(),
op.rotation(), op.filter(), op.mixBlendMode(), op.scaleFromSize());
op.pipelineId(), op.scBounds(), op.rotation(), op.filter(),
op.mixBlendMode());
mAsyncImageManager->ApplyAsyncImageForPipeline(op.pipelineId(), aTxn,
txnForImageBridge);
break;

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

@ -1856,14 +1856,12 @@ Maybe<wr::ImageKey> WebRenderCommandBuilder::CreateImageKey(
LayoutDeviceRect rect = aAsyncImageBounds.value();
LayoutDeviceRect scBounds(LayoutDevicePoint(0, 0), rect.Size());
gfx::Matrix4x4 transform;
// TODO!
// We appear to be using the image bridge for a lot (most/all?) of
// layers-free image handling and that breaks frame consistency.
imageData->CreateAsyncImageWebRenderCommands(
aBuilder, aContainer, aSc, rect, scBounds, transform,
gfx::MaybeIntSize(), aContainer->GetRotation(), aRendering,
wr::MixBlendMode::Normal, !aItem->BackfaceIsHidden());
aBuilder, aContainer, aSc, rect, scBounds, aContainer->GetRotation(),
aRendering, wr::MixBlendMode::Normal, !aItem->BackfaceIsHidden());
return Nothing();
}

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

@ -231,8 +231,7 @@ already_AddRefed<ImageClient> WebRenderImageData::GetImageClient() {
void WebRenderImageData::CreateAsyncImageWebRenderCommands(
mozilla::wr::DisplayListBuilder& aBuilder, ImageContainer* aContainer,
const StackingContextHelper& aSc, const LayoutDeviceRect& aBounds,
const LayoutDeviceRect& aSCBounds, const gfx::Matrix4x4& aSCTransform,
const gfx::MaybeIntSize& aScaleToSize, VideoInfo::Rotation aRotation,
const LayoutDeviceRect& aSCBounds, VideoInfo::Rotation aRotation,
const wr::ImageRendering& aFilter, const wr::MixBlendMode& aMixBlendMode,
bool aIsBackfaceVisible) {
MOZ_ASSERT(aContainer->IsAsync());
@ -254,14 +253,6 @@ void WebRenderImageData::CreateAsyncImageWebRenderCommands(
}
MOZ_ASSERT(!mImageClient);
LayoutDeviceSize scaleFromSize;
AutoLockImage autoLock(aContainer);
if (autoLock.HasImage()) {
mozilla::layers::Image* image = autoLock.GetImage();
gfx::IntSize size = image->GetSize();
scaleFromSize = LayoutDeviceSize(size.width, size.height);
}
// Push IFrame for async image pipeline.
//
// We don't push a stacking context for this async image pipeline here.
@ -275,8 +266,7 @@ void WebRenderImageData::CreateAsyncImageWebRenderCommands(
/*ignoreMissingPipelines*/ false);
WrBridge()->AddWebRenderParentCommand(OpUpdateAsyncImagePipeline(
mPipelineId.value(), aSCBounds, aSCTransform, aScaleToSize, aRotation,
aFilter, aMixBlendMode, scaleFromSize));
mPipelineId.value(), aSCBounds, aRotation, aFilter, aMixBlendMode));
}
void WebRenderImageData::CreateImageClientIfNeeded() {

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

@ -157,8 +157,7 @@ class WebRenderImageData : public WebRenderUserData {
void CreateAsyncImageWebRenderCommands(
mozilla::wr::DisplayListBuilder& aBuilder, ImageContainer* aContainer,
const StackingContextHelper& aSc, const LayoutDeviceRect& aBounds,
const LayoutDeviceRect& aSCBounds, const gfx::Matrix4x4& aSCTransform,
const gfx::MaybeIntSize& aScaleToSize, VideoInfo::Rotation aRotation,
const LayoutDeviceRect& aSCBounds, VideoInfo::Rotation aRotation,
const wr::ImageRendering& aFilter, const wr::MixBlendMode& aMixBlendMode,
bool aIsBackfaceVisible);

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

@ -165,18 +165,14 @@ class nsDisplayCanvas final : public nsPaintedDisplayItem {
aBuilder.PushIFrame(r, !BackfaceIsHidden(), data->GetPipelineId().ref(),
/*ignoreMissingPipelines*/ false);
gfx::Matrix4x4 scTransform;
MaybeIntSize scaleToSize;
LayoutDeviceRect scBounds(LayoutDevicePoint(0, 0), bounds.Size());
wr::ImageRendering filter = wr::ToImageRendering(
nsLayoutUtils::GetSamplingFilterForFrame(mFrame));
wr::MixBlendMode mixBlendMode = wr::MixBlendMode::Normal;
aManager->WrBridge()->AddWebRenderParentCommand(
OpUpdateAsyncImagePipeline(
data->GetPipelineId().value(), scBounds, scTransform,
scaleToSize, VideoInfo::Rotation::kDegree_0, filter,
mixBlendMode,
LayoutDeviceSize(canvasSizeInPx.width, canvasSizeInPx.height)));
OpUpdateAsyncImagePipeline(data->GetPipelineId().value(), scBounds,
VideoInfo::Rotation::kDegree_0, filter,
mixBlendMode));
break;
}
case CanvasContextType::WebGPU: {