Bug 1359842 - Add a StackingContextHelper to reduce duplicated code. r=nical

This class is a RAII class that can be used to push a stacking context
with properties from a WebRenderLayer. It can also then be used to
convert rects in the layer coordinate system to be relative to the
stacking context, which is what we want for passing to WR.

MozReview-Commit-ID: 1WVrfRYqLqc
This commit is contained in:
Kartikaya Gupta 2017-04-27 12:04:25 -04:00
Родитель 93d9aa4545
Коммит 1dd42d38a4
9 изменённых файлов: 137 добавлений и 62 удалений

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

@ -199,6 +199,7 @@ EXPORTS.mozilla.layers += [
'TextureWrapperImage.h',
'TransactionIdAllocator.h',
'UpdateImageHelper.h',
'wr/StackingContextHelper.h',
'wr/WebRenderBridgeChild.h',
'wr/WebRenderBridgeParent.h',
'wr/WebRenderCompositableHolder.h',
@ -393,6 +394,7 @@ UNIFIED_SOURCES += [
'SourceSurfaceVolatileData.cpp',
'TextureSourceProvider.cpp',
'TextureWrapperImage.cpp',
'wr/StackingContextHelper.cpp',
'wr/WebRenderBridgeChild.cpp',
'wr/WebRenderBridgeParent.cpp',
'wr/WebRenderCanvasLayer.cpp',

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

@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 2; 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/. */
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderLayer.h"
namespace mozilla {
namespace layers {
StackingContextHelper::StackingContextHelper(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
const Maybe<gfx::Matrix4x4>& aTransform)
: mBuilder(&aBuilder)
{
LayerRect scBounds = aLayer->RelativeToParent(aLayer->BoundsForStackingContext());
Layer* layer = aLayer->GetLayer();
gfx::Matrix4x4 transform = aTransform.valueOr(layer->GetTransform());
mBuilder->PushStackingContext(wr::ToWrRect(scBounds),
1.0f,
transform,
wr::ToWrMixBlendMode(layer->GetMixBlendMode()));
mOrigin = aLayer->Bounds().TopLeft();
}
StackingContextHelper::~StackingContextHelper()
{
mBuilder->PopStackingContext();
}
WrRect
StackingContextHelper::ToRelativeWrRect(const LayerRect& aRect)
{
return wr::ToWrRect(aRect - mOrigin);
}
} // namespace layers
} // namespace mozilla

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

@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 2; 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/. */
#ifndef GFX_STACKINGCONTEXTHELPER_H
#define GFX_STACKINGCONTEXTHELPER_H
#include "mozilla/Attributes.h"
#include "mozilla/gfx/MatrixFwd.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "Units.h"
namespace mozilla {
namespace layers {
class WebRenderLayer;
/**
* This is a helper class that pushes/pops a stacking context, and manages
* some of the coordinate space transformations needed.
*/
class MOZ_RAII StackingContextHelper
{
public:
// Pushes a stacking context onto the provided DisplayListBuilder. It uses
// the transform if provided, otherwise takes the transform from the layer.
// It also takes the mix-blend-mode and bounds from the layer, and uses 1.0
// for the opacity.
StackingContextHelper(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
const Maybe<gfx::Matrix4x4>& aTransform = Nothing());
// Pops the stacking context
~StackingContextHelper();
// When this StackingContextHelper is in scope, this function can be used
// to convert a rect from the layer system's coordinate space to a WrRect
// that is relative to the stacking context. This is useful because most
// things that are pushed inside the stacking context need to be relative
// to the stacking context.
WrRect ToRelativeWrRect(const LayerRect& aRect);
private:
wr::DisplayListBuilder* mBuilder;
LayerPoint mOrigin;
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_STACKINGCONTEXTHELPER_H */

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

@ -7,6 +7,7 @@
#include "mozilla/layers/WebRenderBridgeParent.h"
#include "CompositableHost.h"
#include "gfxPrefs.h"
#include "GLContext.h"
#include "GLContextProvider.h"
#include "mozilla/Range.h"

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

@ -12,6 +12,7 @@
#include "GLScreenBuffer.h"
#include "LayersLogging.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "PersistentBufferProvider.h"
@ -54,23 +55,25 @@ WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mCanvasClient));
}
gfx::Matrix4x4 transform = GetTransform();
Maybe<gfx::Matrix4x4> transform;
const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
if (needsYFlip) {
transform.PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1);
transform = Some(GetTransform().PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1));
}
LayerRect relBounds = GetWrRelBounds();
LayerRect rect = RelativeToVisible(LayerRect(0, 0, mBounds.width, mBounds.height));
StackingContextHelper sc(aBuilder, this, transform);
LayerRect clipRect = GetWrClipRect(rect);
LayerRect rect(0, 0, mBounds.width, mBounds.height);
DumpLayerInfo("CanvasLayer", rect);
LayerRect clipRect = ClipRect().valueOr(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
WrClipRegion clip = aBuilder.BuildClipRegion(
sc.ToRelativeWrRect(clipRect),
mask.ptrOr(nullptr));
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
DumpLayerInfo("CanvasLayer", rect);
if (gfxPrefs::LayersDump()) {
printf_stderr("CanvasLayer %p texture-filter=%s\n",
this->GetLayer(),
@ -81,12 +84,7 @@ WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
Manager()->AddImageKeyForDiscard(key);
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
1.0f,
transform,
mixBlendMode);
aBuilder.PushImage(wr::ToWrRect(rect), clip, filter, key);
aBuilder.PopStackingContext();
aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, key);
}
void

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

@ -9,6 +9,7 @@
#include "LayersLogging.h"
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
namespace mozilla {
@ -19,24 +20,18 @@ using namespace mozilla::gfx;
void
WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
gfx::Matrix4x4 transform = GetTransform();
LayerRect relBounds = GetWrRelBounds();
LayerRect rect = GetWrBoundsRect();
LayerRect clipRect = GetWrClipRect(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
StackingContextHelper sc(aBuilder, this);
LayerRect rect = Bounds();
DumpLayerInfo("ColorLayer", rect);
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
1.0f,
transform,
mixBlendMode);
aBuilder.PushRect(wr::ToWrRect(rect), clip, wr::ToWrColor(mColor));
aBuilder.PopStackingContext();
LayerRect clipRect = ClipRect().valueOr(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(
sc.ToRelativeWrRect(clipRect),
mask.ptrOr(nullptr));
aBuilder.PushRect(sc.ToRelativeWrRect(rect), clip, wr::ToWrColor(mColor));
}
} // namespace layers

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

@ -8,6 +8,7 @@
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/layers/ImageClient.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClientRecycleAllocator.h"
#include "mozilla/layers/TextureWrapperImage.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
@ -163,8 +164,7 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
return;
}
gfx::Matrix4x4 transform = GetTransform();
LayerRect relBounds = GetWrRelBounds();
StackingContextHelper sc(aBuilder, this);
LayerRect rect(0, 0, size.width, size.height);
if (mScaleMode != ScaleMode::SCALE_NONE) {
@ -172,14 +172,14 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
"No other scalemodes than stretch and none supported yet.");
rect = LayerRect(0, 0, mScaleToSize.width, mScaleToSize.height);
}
rect = RelativeToVisible(rect);
LayerRect clipRect = GetWrClipRect(rect);
LayerRect clipRect = ClipRect().valueOr(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
WrClipRegion clip = aBuilder.BuildClipRegion(
sc.ToRelativeWrRect(clipRect),
mask.ptrOr(nullptr));
wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
DumpLayerInfo("Image Layer", rect);
if (gfxPrefs::LayersDump()) {
@ -188,12 +188,7 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
Stringify(filter).c_str());
}
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
1.0f,
transform,
mixBlendMode);
aBuilder.PushImage(wr::ToWrRect(rect), clip, filter, mKey.value());
aBuilder.PopStackingContext();
aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, filter, mKey.value());
}
Maybe<WrImageMask>

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

@ -52,10 +52,11 @@ public:
LayerRect VisibleBoundsRelativeToParent();
LayerPoint GetOffsetToParent();
gfx::Rect TransformedVisibleBoundsRelativeToParent();
protected:
LayerRect Bounds();
BoundsTransformMatrix BoundsTransform();
LayerRect BoundsForStackingContext();
protected:
BoundsTransformMatrix BoundsTransform();
LayerRect ParentBounds();
Maybe<LayerRect> ClipRect();

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

@ -7,6 +7,7 @@
#include "LayersLogging.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/layers/UpdateImageHelper.h"
#include "mozilla/webrender/WebRenderTypes.h"
@ -90,32 +91,22 @@ WebRenderPaintedLayer::UpdateImageClient()
void
WebRenderPaintedLayer::CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder)
{
LayerIntRegion visibleRegion = GetVisibleRegion();
LayerIntRect bounds = visibleRegion.GetBounds();
LayerIntSize size = bounds.Size();
gfx::Matrix4x4 transform = GetTransform();
LayerRect relBounds = GetWrRelBounds();
LayerRect rect(0, 0, size.width, size.height);
LayerRect clipRect = GetWrClipRect(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
StackingContextHelper sc(aBuilder, this);
LayerRect rect = Bounds();
DumpLayerInfo("PaintedLayer", rect);
LayerRect clipRect = ClipRect().valueOr(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
WrClipRegion clip = aBuilder.BuildClipRegion(
sc.ToRelativeWrRect(clipRect),
mask.ptrOr(nullptr));
WrImageKey key = GetImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
Manager()->AddImageKeyForDiscard(key);
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
1.0f,
transform,
mixBlendMode);
aBuilder.PushImage(wr::ToWrRect(rect), clip, wr::ImageRendering::Auto, key);
aBuilder.PopStackingContext();
aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, wr::ImageRendering::Auto, key);
}
void