--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -265,17 +265,17 @@ void
Compositor::DrawGeometry(const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect,
const Maybe<gfx::Polygon>& aGeometry)
{
- if (!aGeometry) {
+ if (!aGeometry || !SupportsLayerGeometry()) {
DrawQuad(aRect, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect);
return;
}
// Cull invisible polygons.
if (aRect.Intersect(aGeometry->BoundingBox()).IsEmpty()) {
return;
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -354,16 +354,21 @@ public:
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect)
{
MOZ_CRASH("Compositor::DrawTriangle is not implemented for the current platform!");
}
+ virtual bool SupportsLayerGeometry() const
+ {
+ return false;
+ }
+
/**
* Draw an unfilled solid color rect. Typically used for debugging overlays.
*/
void SlowDrawRect(const gfx::Rect& aRect, const gfx::Color& color,
const gfx::IntRect& aClipRect = gfx::IntRect(),
const gfx::Matrix4x4& aTransform = gfx::Matrix4x4(),
int aStrokeWidth = 1);
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -23,17 +23,19 @@
#include "gfx2DGlue.h"
#include "mozilla/DebugOnly.h" // for DebugOnly
#include "mozilla/Telemetry.h" // for Accumulate
#include "mozilla/ToString.h"
#include "mozilla/dom/Animation.h" // for ComputedTimingFunction
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
+#include "mozilla/gfx/Polygon.h" // for Polygon
#include "mozilla/layers/AsyncCanvasRenderer.h"
+#include "mozilla/layers/BSPTree.h" // for BSPTree
#include "mozilla/layers/CompositableClient.h" // for CompositableClient
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
#include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
#include "mozilla/layers/LayersMessages.h" // for TransformFunction, etc
#include "mozilla/layers/LayersTypes.h" // for TextureDumpMode
@@ -42,16 +44,19 @@
#include "nsAString.h"
#include "nsCSSValue.h" // for nsCSSValue::Array, etc
#include "nsPrintfCString.h" // for nsPrintfCString
#include "nsStyleStruct.h" // for nsTimingFunction, etc
#include "protobuf/LayerScopePacket.pb.h"
#include "mozilla/Compression.h"
#include "TreeTraversal.h" // for ForEachNode
+#include <deque>
+#include <set>
+
uint8_t gLayerManagerLayerBuilder;
namespace mozilla {
namespace layers {
FILE*
FILEOrDefault(FILE* aFile)
{
@@ -1336,44 +1341,132 @@ ContainerLayer::Collect3DContextLeaves(n
else {
aToSort.AppendElement(layer);
return TraversalFlag::Skip;
}
}
);
}
-void
-ContainerLayer::SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray)
+static nsTArray<LayerPolygon>
+SortLayersWithBSPTree(nsTArray<Layer*>& aArray)
+{
+ std::deque<LayerPolygon> inputLayers;
+ nsTArray<LayerPolygon> orderedLayers;
+
+ // Build a list of polygons to be sorted.
+ for (Layer* layer : aArray) {
+ // Ignore invisible layers.
+ if (!layer->IsVisible()) {
+ continue;
+ }
+
+ const gfx::IntRect& bounds =
+ layer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds();
+ const gfx::Matrix4x4& transform = layer->GetEffectiveTransform();
+
+ gfx::Polygon polygon = gfx::Polygon::FromRect(gfx::Rect(bounds));
+
+ // Transform the polygon to screen space.
+ polygon.TransformToScreenSpace(transform);
+
+ if (polygon.GetPoints().Length() >= 3) {
+ inputLayers.push_back(LayerPolygon(layer, Move(polygon)));
+ }
+ }
+
+ if (inputLayers.empty()) {
+ return orderedLayers;
+ }
+
+ // Build a BSP tree from the list of polygons.
+ BSPTree tree(inputLayers);
+ orderedLayers = Move(tree.GetDrawOrder());
+
+ // Transform the polygons back to layer space.
+ for (LayerPolygon& layerPolygon : orderedLayers) {
+ gfx::Matrix4x4 inverse =
+ layerPolygon.layer->GetEffectiveTransform().Inverse();
+
+ MOZ_ASSERT(layerPolygon.geometry);
+ layerPolygon.geometry->TransformToLayerSpace(inverse);
+ }
+
+ return orderedLayers;
+}
+
+static nsTArray<LayerPolygon>
+StripLayerGeometry(const nsTArray<LayerPolygon>& aLayers)
+{
+ nsTArray<LayerPolygon> layers;
+ std::set<Layer*> uniqueLayers;
+
+ for (const LayerPolygon& layerPolygon : aLayers) {
+ auto result = uniqueLayers.insert(layerPolygon.layer);
+
+ if (result.second) {
+ // Layer was added to the set.
+ layers.AppendElement(LayerPolygon(layerPolygon.layer));
+ }
+ }
+
+ return layers;
+}
+
+nsTArray<LayerPolygon>
+ContainerLayer::SortChildrenBy3DZOrder(SortMode aSortMode)
{
AutoTArray<Layer*, 10> toSort;
+ nsTArray<LayerPolygon> drawOrder;
- for (Layer* l = GetFirstChild(); l; l = l->GetNextSibling()) {
- ContainerLayer* container = l->AsContainerLayer();
+ for (Layer* layer = GetFirstChild(); layer; layer = layer->GetNextSibling()) {
+ ContainerLayer* container = layer->AsContainerLayer();
+
if (container && container->Extend3DContext() &&
!container->UseIntermediateSurface()) {
+
+ // Collect 3D layers in toSort array.
container->Collect3DContextLeaves(toSort);
- } else {
+
+ // Sort the 3D layers.
if (toSort.Length() > 0) {
- SortLayersBy3DZOrder(toSort);
- aArray.AppendElements(Move(toSort));
- // XXX The move analysis gets confused here, because toSort gets moved
- // here, and then gets used again outside of the loop. To clarify that
- // we realize that the array is going to be empty to the move checker,
- // we clear it again here. (This method renews toSort for the move
- // analysis)
+ nsTArray<LayerPolygon> sorted = SortLayersWithBSPTree(toSort);
+ drawOrder.AppendElements(Move(sorted));
+
toSort.ClearAndRetainStorage();
}
- aArray.AppendElement(l);
+
+ continue;
}
+
+ drawOrder.AppendElement(LayerPolygon(layer));
+ }
+
+ if (aSortMode == SortMode::WITHOUT_GEOMETRY) {
+ // Compositor does not support arbitrary layers, strip the layer geometry
+ // and duplicate layers.
+ return StripLayerGeometry(drawOrder);
}
- if (toSort.Length() > 0) {
- SortLayersBy3DZOrder(toSort);
- aArray.AppendElements(Move(toSort));
+
+ return drawOrder;
+}
+
+bool
+ContainerLayer::AnyAncestorOrThisIs3DContextLeaf()
+{
+ Layer* parent = this;
+ while (parent != nullptr) {
+ if (parent->Is3DContextLeaf()) {
+ return true;
+ }
+
+ parent = parent->GetParent();
}
+
+ return false;
}
void
ContainerLayer::DefaultComputeEffectiveTransforms(const Matrix4x4& aTransformToSurface)
{
Matrix residual;
Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
@@ -1396,17 +1489,18 @@ ContainerLayer::DefaultComputeEffectiveT
* WebKit/blink behaviour, but is changing in the latest spec.
*/
float opacity = GetEffectiveOpacity();
CompositionOp blendMode = GetEffectiveMixBlendMode();
if ((HasMultipleChildren() || Creates3DContextWithExtendingChildren()) &&
((opacity != 1.0f && !Extend3DContext()) ||
(blendMode != CompositionOp::OP_OVER))) {
useIntermediateSurface = true;
- } else if (!idealTransform.Is2D() && Creates3DContextWithExtendingChildren()) {
+ } else if ((!idealTransform.Is2D() || AnyAncestorOrThisIs3DContextLeaf()) &&
+ Creates3DContextWithExtendingChildren()) {
useIntermediateSurface = true;
} else {
useIntermediateSurface = false;
gfx::Matrix contTransform;
bool checkClipRect = false;
bool checkMaskLayers = false;
if (!idealTransform.Is2D(&contTransform)) {
@@ -1708,17 +1802,17 @@ void WriteSnapshotToDumpFile(Compositor*
RefPtr<SourceSurface> surf = aTarget->Snapshot();
RefPtr<DataSourceSurface> dSurf = surf->GetDataSurface();
WriteSnapshotToDumpFile_internal(aCompositor, dSurf);
}
#endif
void
Layer::Dump(std::stringstream& aStream, const char* aPrefix,
- bool aDumpHtml, bool aSorted)
+ bool aDumpHtml, bool aSorted, const Maybe<gfx::Polygon>& aGeometry)
{
#ifdef MOZ_DUMP_PAINTING
bool dumpCompositorTexture = gfxEnv::DumpCompositorTextures() && AsHostLayer() &&
AsHostLayer()->GetCompositableHost();
bool dumpClientTexture = gfxEnv::DumpPaint() && AsShadowableLayer() &&
AsShadowableLayer()->GetCompositableClient();
nsCString layerId(Name());
layerId.Append('-');
@@ -1728,17 +1822,17 @@ Layer::Dump(std::stringstream& aStream,
aStream << nsPrintfCString(R"(<li><a id="%p" )", this).get();
#ifdef MOZ_DUMP_PAINTING
if (dumpCompositorTexture || dumpClientTexture) {
aStream << nsPrintfCString(R"lit(href="javascript:ViewImage('%s')")lit", layerId.BeginReading()).get();
}
#endif
aStream << ">";
}
- DumpSelf(aStream, aPrefix);
+ DumpSelf(aStream, aPrefix, aGeometry);
#ifdef MOZ_DUMP_PAINTING
if (dumpCompositorTexture) {
AsHostLayer()->GetCompositableHost()->Dump(aStream, aPrefix, aDumpHtml);
} else if (dumpClientTexture) {
if (aDumpHtml) {
aStream << nsPrintfCString(R"(<script>array["%s"]=")", layerId.BeginReading()).get();
}
@@ -1776,48 +1870,70 @@ Layer::Dump(std::stringstream& aStream,
#ifdef MOZ_DUMP_PAINTING
for (size_t i = 0; i < mExtraDumpInfo.Length(); i++) {
const nsCString& str = mExtraDumpInfo[i];
aStream << aPrefix << " Info:\n" << str.get();
}
#endif
if (ContainerLayer* container = AsContainerLayer()) {
- AutoTArray<Layer*, 12> children;
+ nsTArray<LayerPolygon> children;
if (aSorted) {
- container->SortChildrenBy3DZOrder(children);
+ children =
+ container->SortChildrenBy3DZOrder(ContainerLayer::SortMode::WITH_GEOMETRY);
} else {
for (Layer* l = container->GetFirstChild(); l; l = l->GetNextSibling()) {
- children.AppendElement(l);
+ children.AppendElement(LayerPolygon(l));
}
}
nsAutoCString pfx(aPrefix);
pfx += " ";
if (aDumpHtml) {
aStream << "<ul>";
}
- for (Layer* child : children) {
- child->Dump(aStream, pfx.get(), aDumpHtml, aSorted);
+ for (LayerPolygon& child : children) {
+ child.layer->Dump(aStream, pfx.get(), aDumpHtml, aSorted, child.geometry);
}
if (aDumpHtml) {
aStream << "</ul>";
}
}
if (aDumpHtml) {
aStream << "</li>";
}
}
+static void
+DumpGeometry(std::stringstream& aStream, const Maybe<gfx::Polygon>& aGeometry)
+{
+ aStream << " [geometry=[";
+
+ const nsTArray<gfx::Point4D>& points = aGeometry->GetPoints();
+ for (size_t i = 0; i < points.Length(); ++i) {
+ const gfx::IntPoint point = TruncatedToInt(points[i].As2DPoint());
+ const char* sfx = (i != points.Length() - 1) ? "," : "";
+ AppendToString(aStream, point, "", sfx);
+ }
+
+ aStream << "]]";
+}
+
void
-Layer::DumpSelf(std::stringstream& aStream, const char* aPrefix)
+Layer::DumpSelf(std::stringstream& aStream, const char* aPrefix,
+ const Maybe<gfx::Polygon>& aGeometry)
{
PrintInfo(aStream, aPrefix);
+
+ if (aGeometry) {
+ DumpGeometry(aStream, aGeometry);
+ }
+
aStream << "\n";
}
void
Layer::Dump(layerscope::LayersPacket* aPacket, const void* aParent)
{
DumpPacket(aPacket, aParent);
@@ -2388,17 +2504,17 @@ LayerManager::Dump(std::stringstream& aS
aStream << "</li></ul>";
}
return;
}
if (aDumpHtml) {
aStream << "<ul>";
}
- GetRoot()->Dump(aStream, pfx.get(), aDumpHtml);
+ GetRoot()->Dump(aStream, pfx.get(), aDumpHtml, aSorted);
if (aDumpHtml) {
aStream << "</ul></li></ul>";
}
aStream << "\n";
}
void
LayerManager::DumpSelf(std::stringstream& aStream, const char* aPrefix, bool aSorted)
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -28,16 +28,17 @@
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
#include "mozilla/UniquePtr.h" // for UniquePtr
#include "mozilla/gfx/BaseMargin.h" // for BaseMargin
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/TiledRegion.h" // for TiledIntRegion
#include "mozilla/gfx/Types.h" // for SurfaceFormat
#include "mozilla/gfx/UserData.h" // for UserData, etc
+#include "mozilla/layers/BSPTree.h" // for LayerPolygon
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "nsAutoPtr.h" // for nsAutoPtr, nsRefPtr, etc
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsCSSPropertyID.h" // for nsCSSPropertyID
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for Layer::Release, etc
#include "nsRect.h" // for mozilla::gfx::IntRect
@@ -1686,21 +1687,23 @@ public:
void SetNextSibling(Layer* aSibling) { mNextSibling = aSibling; }
void SetPrevSibling(Layer* aSibling) { mPrevSibling = aSibling; }
/**
* Dump information about this layer manager and its managed tree to
* aStream.
*/
void Dump(std::stringstream& aStream, const char* aPrefix="",
- bool aDumpHtml=false, bool aSorted=false);
+ bool aDumpHtml=false, bool aSorted=false,
+ const Maybe<gfx::Polygon>& aGeometry=Nothing());
/**
* Dump information about just this layer manager itself to aStream.
*/
- void DumpSelf(std::stringstream& aStream, const char* aPrefix="");
+ void DumpSelf(std::stringstream& aStream, const char* aPrefix="",
+ const Maybe<gfx::Polygon>& aGeometry=Nothing());
/**
* Dump information about this layer and its child & sibling layers to
* layerscope packet.
*/
void Dump(layerscope::LayersPacket* aPacket, const void* aParent);
/**
@@ -2148,23 +2151,27 @@ public:
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScaleToResolution", this));
mScaleToResolution = aScaleToResolution;
mPresShellResolution = aResolution;
Mutated();
}
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override;
- void SortChildrenBy3DZOrder(nsTArray<Layer*>& aArray);
+ enum class SortMode {
+ WITH_GEOMETRY,
+ WITHOUT_GEOMETRY,
+ };
- // These getters can be used anytime.
+ nsTArray<LayerPolygon> SortChildrenBy3DZOrder(SortMode aSortMode);
virtual ContainerLayer* AsContainerLayer() override { return this; }
virtual const ContainerLayer* AsContainerLayer() const override { return this; }
+ // These getters can be used anytime.
virtual Layer* GetFirstChild() const override { return mFirstChild; }
virtual Layer* GetLastChild() const override { return mLastChild; }
float GetPreXScale() const { return mPreXScale; }
float GetPreYScale() const { return mPreYScale; }
float GetInheritedXScale() const { return mInheritedXScale; }
float GetInheritedYScale() const { return mInheritedYScale; }
float GetPresShellResolution() const { return mPresShellResolution; }
bool ScaleToResolution() const { return mScaleToResolution; }
@@ -2236,18 +2243,39 @@ public:
}
protected:
friend class ReadbackProcessor;
void DidInsertChild(Layer* aLayer);
void DidRemoveChild(Layer* aLayer);
+ bool AnyAncestorOrThisIs3DContextLeaf();
+
void Collect3DContextLeaves(nsTArray<Layer*>& aToSort);
+ // Collects child layers that do not extend 3D context. For ContainerLayers
+ // that do extend 3D context, the 3D context leaves are collected.
+ nsTArray<Layer*> CollectChildren() {
+ nsTArray<Layer*> children;
+
+ for (Layer* layer = GetFirstChild(); layer; layer = layer->GetNextSibling()) {
+ ContainerLayer* container = layer->AsContainerLayer();
+
+ if (container && container->Extend3DContext() &&
+ !container->UseIntermediateSurface()) {
+ container->Collect3DContextLeaves(children);
+ } else {
+ children.AppendElement(layer);
+ }
+ }
+
+ return children;
+ }
+
ContainerLayer(LayerManager* aManager, void* aImplData);
/**
* A default implementation of ComputeEffectiveTransforms for use by OpenGL
* and D3D.
*/
void DefaultComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface);
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -715,20 +715,22 @@ BasicLayerManager::PaintSelfOrChildren(P
} else {
data->Paint(aGroupTarget->GetDrawTarget(),
aGroupTarget->GetDeviceOffset(),
aPaintContext.mLayer->GetMaskLayer());
}
} else {
ContainerLayer* container =
static_cast<ContainerLayer*>(aPaintContext.mLayer);
- AutoTArray<Layer*, 12> children;
- container->SortChildrenBy3DZOrder(children);
+
+ nsTArray<LayerPolygon> children =
+ container->SortChildrenBy3DZOrder(ContainerLayer::SortMode::WITHOUT_GEOMETRY);
+
for (uint32_t i = 0; i < children.Length(); i++) {
- Layer* layer = children.ElementAt(i);
+ Layer* layer = children.ElementAt(i).layer;
if (layer->IsBackfaceHidden()) {
continue;
}
if (!layer->AsContainerLayer() && !layer->IsVisible()) {
continue;
}
PaintLayer(aGroupTarget, layer, aPaintContext.mCallback,
--- a/gfx/layers/client/ClientContainerLayer.h
+++ b/gfx/layers/client/ClientContainerLayer.h
@@ -42,25 +42,23 @@ protected:
MOZ_COUNT_DTOR(ClientContainerLayer);
}
public:
virtual void RenderLayer() override
{
RenderMaskLayers(this);
-
+
DefaultComputeSupportsComponentAlphaChildren();
- AutoTArray<Layer*, 12> children;
- SortChildrenBy3DZOrder(children);
-
ReadbackProcessor readback;
readback.BuildUpdates(this);
+ nsTArray<Layer*> children = CollectChildren();
for (uint32_t i = 0; i < children.Length(); i++) {
Layer* child = children.ElementAt(i);
ToClientLayer(child)->RenderLayerWithReadback(&readback);
if (!ClientManager()->GetRepeatTransaction() &&
!child->GetInvalidRegion().IsEmpty()) {
child->Mutated();
--- a/gfx/layers/composite/CanvasLayerComposite.cpp
+++ b/gfx/layers/composite/CanvasLayerComposite.cpp
@@ -73,17 +73,18 @@ CanvasLayerComposite::GetRenderState()
{
if (mDestroyed || !mCompositableHost || !mCompositableHost->IsAttached()) {
return LayerRenderState();
}
return mCompositableHost->GetRenderState();
}
void
-CanvasLayerComposite::RenderLayer(const IntRect& aClipRect)
+CanvasLayerComposite::RenderLayer(const IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry)
{
if (!mCompositableHost || !mCompositableHost->IsAttached()) {
return;
}
mCompositor->MakeCurrent();
#ifdef MOZ_DUMP_PAINTING
--- a/gfx/layers/composite/CanvasLayerComposite.h
+++ b/gfx/layers/composite/CanvasLayerComposite.h
@@ -46,17 +46,18 @@ public:
virtual void Disconnect() override
{
Destroy();
}
virtual void SetLayerManager(HostLayerManager* aManager) override;
virtual Layer* GetLayer() override;
- virtual void RenderLayer(const gfx::IntRect& aClipRect) override;
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) override;
virtual void CleanupResources() override;
virtual void GenEffectChain(EffectChain& aEffect) override;
CompositableHost* GetCompositableHost() override;
virtual HostLayer* AsHostLayer() override { return this; }
--- a/gfx/layers/composite/ColorLayerComposite.cpp
+++ b/gfx/layers/composite/ColorLayerComposite.cpp
@@ -15,26 +15,29 @@
#include "mozilla/mozalloc.h" // for operator delete, etc
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
void
-ColorLayerComposite::RenderLayer(const IntRect& aClipRect)
+ColorLayerComposite::RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry)
{
Rect rect(GetBounds());
+
const Matrix4x4& transform = GetEffectiveTransform();
RenderWithAllMasks(this, mCompositor, aClipRect,
[&](EffectChain& effectChain, const IntRect& clipRect) {
GenEffectChain(effectChain);
- mCompositor->DrawQuad(rect, clipRect, effectChain, GetEffectiveOpacity(),
- transform);
+
+ mCompositor->DrawGeometry(rect, clipRect, effectChain,
+ GetEffectiveOpacity(), transform, aGeometry);
});
mCompositor->DrawDiagnostics(DiagnosticFlags::COLOR, rect, aClipRect,
transform);
}
void
ColorLayerComposite::GenEffectChain(EffectChain& aEffect)
--- a/gfx/layers/composite/ColorLayerComposite.h
+++ b/gfx/layers/composite/ColorLayerComposite.h
@@ -42,17 +42,19 @@ public:
virtual void SetLayerManager(HostLayerManager* aManager) override
{
LayerComposite::SetLayerManager(aManager);
mManager = aManager;
}
virtual void Destroy() override { mDestroyed = true; }
- virtual void RenderLayer(const gfx::IntRect& aClipRect) override;
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) override;
+
virtual void CleanupResources() override {};
virtual void GenEffectChain(EffectChain& aEffect) override;
CompositableHost* GetCompositableHost() override { return nullptr; }
virtual HostLayer* AsHostLayer() override { return this; }
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -9,16 +9,17 @@
#include <stdint.h> // for uint64_t
#include <stdio.h> // for FILE
#include "gfxRect.h" // for gfxRect
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Attributes.h" // for override
#include "mozilla/RefPtr.h" // for RefPtr, RefCounted, etc
#include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for Point
+#include "mozilla/gfx/Polygon.h" // for Polygon
#include "mozilla/gfx/Rect.h" // for Rect
#include "mozilla/gfx/Types.h" // for SamplingFilter
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
#include "mozilla/layers/Effects.h" // for Texture Effect
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
#include "mozilla/layers/LayersMessages.h"
@@ -78,17 +79,18 @@ public:
// composite the contents of this buffer host to the compositor's surface
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
- const nsIntRegion* aVisibleRegion = nullptr) = 0;
+ const nsIntRegion* aVisibleRegion = nullptr,
+ const Maybe<gfx::Polygon>& aGeometry = Nothing()) = 0;
/**
* Update the content host.
* aUpdated is the region which should be updated
* aUpdatedRegionBack is the region in aNewBackResult which has been updated
*/
virtual bool UpdateThebes(const ThebesBufferData& aData,
const nsIntRegion& aUpdated,
@@ -286,17 +288,17 @@ private:
* that is accessed only on the compositor thread. During a layer transaction we
* send the message OpAttachAsyncCompositable(ID, PLayer), and on the compositor
* side we lookup the ID in the map and attach the corresponding compositable to
* the layer.
*
* CompositableMap must be global because the image bridge doesn't have any
* reference to whatever we have created with PLayerTransaction. So, the only way to
* actually connect these two worlds is to have something global that they can
- * both query (in the same thread). The map is not allocated the map on the
+ * both query (in the same thread). The map is not allocated the map on the
* stack to avoid the badness of static initialization.
*
* Also, we have a compositor/PLayerTransaction protocol/etc. per layer manager, and the
* ImageBridge is used by all the existing compositors that have a video, so
* there isn't an instance or "something" that lives outside the boudaries of a
* given layer manager on the compositor thread except the image bridge and the
* thread itself.
*/
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -47,21 +47,21 @@
#define XY(k) (k).x, (k).y
#define WH(k) (k).width, (k).height
namespace mozilla {
namespace layers {
using namespace gfx;
-static void DrawLayerInfo(const RenderTargetIntRect& aClipRect,
- LayerManagerComposite* aManager,
- Layer* aLayer)
+static void
+DrawLayerInfo(const RenderTargetIntRect& aClipRect,
+ LayerManagerComposite* aManager,
+ Layer* aLayer)
{
-
if (aLayer->GetType() == Layer::LayerType::TYPE_CONTAINER) {
// XXX - should figure out a way to render this, but for now this
// is hard to do, since it will often get superimposed over the first
// child of the layer, which is bad.
return;
}
std::stringstream ss;
@@ -72,24 +72,18 @@ static void DrawLayerInfo(const RenderTa
uint32_t maxWidth = std::min<uint32_t>(visibleRegion.GetBounds().width, 500);
IntPoint topLeft = visibleRegion.ToUnknownRegion().GetBounds().TopLeft();
aManager->GetTextRenderer()->RenderText(ss.str().c_str(), topLeft,
aLayer->GetEffectiveTransform(), 16,
maxWidth);
}
-template<class ContainerT>
-static gfx::IntRect ContainerVisibleRect(ContainerT* aContainer)
-{
- gfx::IntRect surfaceRect = aContainer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds();
- return surfaceRect;
-}
-
-static void PrintUniformityInfo(Layer* aLayer)
+static void
+PrintUniformityInfo(Layer* aLayer)
{
#ifdef MOZ_ENABLE_PROFILER_SPS
if (!profiler_is_active()) {
return;
}
// Don't want to print a log for smaller layers
if (aLayer->GetLocalVisibleRegion().GetBounds().width < 300 ||
@@ -103,23 +97,79 @@ static void PrintUniformityInfo(Layer* a
}
Point translation = transform.As2D().GetTranslation();
LayerTranslationPayload* payload = new LayerTranslationPayload(aLayer, translation);
PROFILER_MARKER_PAYLOAD("LayerTranslation", payload);
#endif
}
+static Maybe<gfx::Polygon>
+SelectLayerGeometry(const Maybe<gfx::Polygon>& aParentGeometry,
+ const Maybe<gfx::Polygon>& aChildGeometry)
+{
+ // Both the parent and the child layer were split.
+ if (aParentGeometry && aChildGeometry) {
+ // As we use intermediate surface in these cases, this branch should never
+ // get executed.
+ MOZ_ASSERT(false,
+ "Both parent and child geometry present in nested 3D context!");
+ return Some(aParentGeometry->ClipPolygon(*aChildGeometry));
+ }
+
+ // The parent layer was split.
+ if (aParentGeometry) {
+ return aParentGeometry;
+ }
+
+ // The child layer was split.
+ if(aChildGeometry) {
+ return aChildGeometry;
+ }
+
+ // No split.
+ return Nothing();
+}
+
+static void
+TransformLayerGeometry(Layer* aLayer, Maybe<gfx::Polygon>& aGeometry)
+{
+ Layer* parent = aLayer->GetParent();
+ gfx::Matrix4x4 transform;
+
+ // Collect all parent transforms.
+ while (parent != nullptr && !parent->Is3DContextLeaf()) {
+ transform = transform * parent->GetLocalTransform();
+ parent = parent->GetParent();
+ }
+
+ // Transform the geometry to the parent 3D context leaf coordinate space.
+ aGeometry->TransformToScreenSpace(transform.ProjectTo2D().Inverse());
+}
+
+
+template<class ContainerT>
+static gfx::IntRect ContainerVisibleRect(ContainerT* aContainer)
+{
+ gfx::IntRect surfaceRect = aContainer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds();
+ return surfaceRect;
+}
+
+
/* all of the per-layer prepared data we need to maintain */
struct PreparedLayer
{
- PreparedLayer(LayerComposite *aLayer, RenderTargetIntRect aClipRect) :
- mLayer(aLayer), mClipRect(aClipRect) {}
+ PreparedLayer(LayerComposite *aLayer,
+ RenderTargetIntRect aClipRect,
+ Maybe<gfx::Polygon> aGeometry)
+ : mLayer(aLayer), mClipRect(aClipRect), mGeometry(aGeometry) {}
+
LayerComposite* mLayer;
RenderTargetIntRect mClipRect;
+ Maybe<Polygon> mGeometry;
};
/* all of the prepared data that we need in RenderLayer() */
struct PreparedData
{
RefPtr<CompositingRenderTarget> mTmpTarget;
AutoTArray<PreparedLayer, 12> mLayers;
bool mNeedsSurfaceCopy;
@@ -129,27 +179,30 @@ struct PreparedData
template<class ContainerT> void
ContainerPrepare(ContainerT* aContainer,
LayerManagerComposite* aManager,
const RenderTargetIntRect& aClipRect)
{
aContainer->mPrepared = MakeUnique<PreparedData>();
aContainer->mPrepared->mNeedsSurfaceCopy = false;
- /**
- * Determine which layers to draw.
- */
- AutoTArray<Layer*, 12> children;
- aContainer->SortChildrenBy3DZOrder(children);
+ const ContainerLayerComposite::SortMode sortMode =
+ aManager->GetCompositor()->SupportsLayerGeometry()
+ ? ContainerLayerComposite::SortMode::WITH_GEOMETRY
+ : ContainerLayerComposite::SortMode::WITHOUT_GEOMETRY;
- for (uint32_t i = 0; i < children.Length(); i++) {
- LayerComposite* layerToRender = static_cast<LayerComposite*>(children.ElementAt(i)->AsHostLayer());
+ const nsTArray<LayerPolygon> polygons =
+ aContainer->SortChildrenBy3DZOrder(sortMode);
- RenderTargetIntRect clipRect = layerToRender->GetLayer()->
- CalculateScissorRect(aClipRect);
+ for (const LayerPolygon& layer : polygons) {
+ LayerComposite* layerToRender =
+ static_cast<LayerComposite*>(layer.layer->ImplData());
+
+ RenderTargetIntRect clipRect =
+ layerToRender->GetLayer()->CalculateScissorRect(aClipRect);
if (layerToRender->GetLayer()->IsBackfaceHidden()) {
continue;
}
// We don't want to skip container layers because otherwise their mPrepared
// may be null which is not allowed.
if (!layerToRender->GetLayer()->AsContainerLayer()) {
@@ -163,17 +216,17 @@ ContainerPrepare(ContainerT* aContainer,
CULLING_LOG("Sublayer %p has an empty world clip rect\n", layerToRender->GetLayer());
continue;
}
}
CULLING_LOG("Preparing sublayer %p\n", layerToRender->GetLayer());
layerToRender->Prepare(clipRect);
- aContainer->mPrepared->mLayers.AppendElement(PreparedLayer(layerToRender, clipRect));
+ aContainer->mPrepared->mLayers.AppendElement(PreparedLayer(layerToRender, clipRect, layer.geometry));
}
CULLING_LOG("Preparing container layer %p\n", aContainer->GetLayer());
/**
* Setup our temporary surface for rendering the contents of this container.
*/
@@ -329,28 +382,30 @@ RenderMinimap(ContainerT* aContainer, La
compositor->SlowDrawRect(r, criticalDisplayPortColor, clipRect, aContainer->GetEffectiveTransform());
}
// Render the viewport.
r = transform.TransformBounds(viewRect.ToUnknownRect());
compositor->SlowDrawRect(r, viewPortColor, clipRect, aContainer->GetEffectiveTransform(), 2);
}
-
template<class ContainerT> void
-RenderLayers(ContainerT* aContainer,
- LayerManagerComposite* aManager,
- const RenderTargetIntRect& aClipRect)
+RenderLayers(ContainerT* aContainer, LayerManagerComposite* aManager,
+ const RenderTargetIntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry)
{
Compositor* compositor = aManager->GetCompositor();
for (size_t i = 0u; i < aContainer->mPrepared->mLayers.Length(); i++) {
PreparedLayer& preparedData = aContainer->mPrepared->mLayers[i];
+
+ const gfx::IntRect clipRect = preparedData.mClipRect.ToUnknownRect();
LayerComposite* layerToRender = preparedData.mLayer;
- const RenderTargetIntRect& clipRect = preparedData.mClipRect;
+ const Maybe<gfx::Polygon>& childGeometry = preparedData.mGeometry;
+
Layer* layer = layerToRender->GetLayer();
if (layerToRender->HasStaleCompositor()) {
continue;
}
if (gfxPrefs::LayersDrawFPS()) {
for (const auto& metadata : layer->GetAllScrollMetadata()) {
@@ -367,46 +422,53 @@ RenderLayers(ContainerT* aContainer,
color = Color(255 / 255.f, 188 / 255.f, 217 / 255.f, 1.f); // "Cotton Candy"
}
// Ideally we would want to intersect the checkerboard region from the APZ with the layer bounds
// and only fill in that area. However the layer bounds takes into account the base translation
// for the painted layer whereas the checkerboard region does not. One does not simply
// intersect areas in different coordinate spaces. So we do this a little more permissively
// and only fill in the background when we know there is checkerboard, which in theory
// should only occur transiently.
- gfx::IntRect layerBounds = layer->GetLayerBounds();
EffectChain effectChain(layer);
effectChain.mPrimaryEffect = new EffectSolidColor(color);
- aManager->GetCompositor()->DrawQuad(gfx::Rect(layerBounds.x, layerBounds.y, layerBounds.width, layerBounds.height),
- clipRect.ToUnknownRect(),
+ aManager->GetCompositor()->DrawQuad(gfx::Rect(layer->GetLayerBounds()), clipRect,
effectChain, layer->GetEffectiveOpacity(),
layer->GetEffectiveTransform());
}
if (layerToRender->HasLayerBeenComposited()) {
// Composer2D will compose this layer so skip GPU composition
// this time. The flag will be reset for the next composition phase
// at the beginning of LayerManagerComposite::Rener().
gfx::IntRect clearRect = layerToRender->GetClearRect();
if (!clearRect.IsEmpty()) {
// Clear layer's visible rect on FrameBuffer with transparent pixels
gfx::Rect fbRect(clearRect.x, clearRect.y, clearRect.width, clearRect.height);
compositor->ClearRect(fbRect);
layerToRender->SetClearRect(gfx::IntRect(0, 0, 0, 0));
}
} else {
- layerToRender->RenderLayer(clipRect.ToUnknownRect());
+ Maybe<gfx::Polygon> geometry =
+ SelectLayerGeometry(aGeometry, childGeometry);
+
+ // If we are dealing with a nested 3D context, we might need to transform
+ // the geometry to the coordinate space of the parent 3D context leaf.
+ if (geometry && !layer->Is3DContextLeaf()) {
+ TransformLayerGeometry(layer, geometry);
+ }
+
+ layerToRender->RenderLayer(clipRect, geometry);
}
if (gfxPrefs::UniformityInfo()) {
PrintUniformityInfo(layer);
}
if (gfxPrefs::DrawLayerInfo()) {
- DrawLayerInfo(clipRect, aManager, layer);
+ DrawLayerInfo(preparedData.mClipRect, aManager, layer);
}
// Draw a border around scrollable layers.
// A layer can be scrolled by multiple scroll frames. Draw a border
// for each.
// Within the list of scroll frames for a layer, the layer border for a
// scroll frame lower down is affected by the async transforms on scroll
// frames higher up, so loop from the top down, and accumulate an async
@@ -497,25 +559,29 @@ RenderIntermediate(ContainerT* aContaine
RefPtr<CompositingRenderTarget> previousTarget = compositor->GetCurrentRenderTarget();
if (!surface) {
return;
}
compositor->SetRenderTarget(surface);
// pre-render all of the layers into our temporary
- RenderLayers(aContainer, aManager, RenderTargetIntRect::FromUnknownRect(aClipRect));
+ RenderLayers(aContainer, aManager,
+ RenderTargetIntRect::FromUnknownRect(aClipRect),
+ Nothing());
+
// Unbind the current surface and rebind the previous one.
compositor->SetRenderTarget(previousTarget);
}
template<class ContainerT> void
ContainerRender(ContainerT* aContainer,
LayerManagerComposite* aManager,
- const gfx::IntRect& aClipRect)
+ const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry)
{
MOZ_ASSERT(aContainer->mPrepared);
if (aContainer->UseIntermediateSurface()) {
RefPtr<CompositingRenderTarget> surface;
if (aContainer->mPrepared->mNeedsSurfaceCopy) {
// we needed to copy the background so we waited until now to render the intermediate
@@ -527,38 +593,42 @@ ContainerRender(ContainerT* aContainer,
}
if (!surface) {
aContainer->mPrepared = nullptr;
return;
}
gfx::Rect visibleRect(aContainer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
+
RefPtr<Compositor> compositor = aManager->GetCompositor();
#ifdef MOZ_DUMP_PAINTING
if (gfxEnv::DumpCompositorTextures()) {
RefPtr<gfx::DataSourceSurface> surf = surface->Dump(compositor);
if (surf) {
WriteSnapshotToDumpFile(aContainer, surf);
}
}
#endif
RefPtr<ContainerT> container = aContainer;
RenderWithAllMasks(aContainer, compositor, aClipRect,
[&, surface, compositor, container](EffectChain& effectChain, const IntRect& clipRect) {
effectChain.mPrimaryEffect = new EffectRenderTarget(surface);
- compositor->DrawQuad(visibleRect, clipRect, effectChain,
- container->GetEffectiveOpacity(),
- container->GetEffectiveTransform());
+
+ compositor->DrawGeometry(visibleRect, clipRect, effectChain,
+ container->GetEffectiveOpacity(),
+ container->GetEffectiveTransform(), aGeometry);
});
+
} else {
- RenderLayers(aContainer, aManager, RenderTargetIntRect::FromUnknownRect(aClipRect));
+ RenderLayers(aContainer, aManager,
+ RenderTargetIntRect::FromUnknownRect(aClipRect),
+ aGeometry);
}
- aContainer->mPrepared = nullptr;
// If it is a scrollable container layer with no child layers, and one of the APZCs
// attached to it has a nonempty async transform, then that transform is not applied
// to any visible content. Display a warning box (conditioned on the FPS display being
// enabled).
if (gfxPrefs::LayersDrawFPS() && aContainer->IsScrollInfoLayer()) {
// Since aContainer doesn't have any children we can just iterate from the top metrics
// on it down to the bottom using GetFirstChild and not worry about walking onto another
@@ -618,19 +688,26 @@ ContainerLayerComposite::GetFirstChildCo
{
if (!mFirstChild) {
return nullptr;
}
return static_cast<LayerComposite*>(mFirstChild->AsHostLayer());
}
void
-ContainerLayerComposite::RenderLayer(const gfx::IntRect& aClipRect)
+ContainerLayerComposite::Cleanup()
{
- ContainerRender(this, mCompositeManager, aClipRect);
+ mPrepared = nullptr;
+}
+
+void
+ContainerLayerComposite::RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry)
+{
+ ContainerRender(this, mCompositeManager, aClipRect, aGeometry);
}
void
ContainerLayerComposite::Prepare(const RenderTargetIntRect& aClipRect)
{
ContainerPrepare(this, mCompositeManager, aClipRect);
}
@@ -669,19 +746,20 @@ RefLayerComposite::GetFirstChildComposit
{
if (!mFirstChild) {
return nullptr;
}
return static_cast<LayerComposite*>(mFirstChild->AsHostLayer());
}
void
-RefLayerComposite::RenderLayer(const gfx::IntRect& aClipRect)
+RefLayerComposite::RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry)
{
- ContainerRender(this, mCompositeManager, aClipRect);
+ ContainerRender(this, mCompositeManager, aClipRect, aGeometry);
}
void
RefLayerComposite::Prepare(const RenderTargetIntRect& aClipRect)
{
ContainerPrepare(this, mCompositeManager, aClipRect);
}
--- a/gfx/layers/composite/ContainerLayerComposite.h
+++ b/gfx/layers/composite/ContainerLayerComposite.h
@@ -24,21 +24,23 @@ class ContainerLayerComposite : public C
{
template<class ContainerT>
friend void ContainerPrepare(ContainerT* aContainer,
LayerManagerComposite* aManager,
const RenderTargetIntRect& aClipRect);
template<class ContainerT>
friend void ContainerRender(ContainerT* aContainer,
LayerManagerComposite* aManager,
- const RenderTargetIntRect& aClipRect);
+ const RenderTargetIntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry);
template<class ContainerT>
friend void RenderLayers(ContainerT* aContainer,
LayerManagerComposite* aManager,
- const RenderTargetIntRect& aClipRect);
+ const RenderTargetIntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry);
template<class ContainerT>
friend void RenderIntermediate(ContainerT* aContainer,
LayerManagerComposite* aManager,
const gfx::IntRect& aClipRect,
RefPtr<CompositingRenderTarget> surface);
template<class ContainerT>
friend RefPtr<CompositingRenderTarget>
CreateTemporaryTargetAndCopyFromBackground(ContainerT* aContainer,
@@ -74,17 +76,21 @@ public:
child->SetLayerManager(aManager);
}
}
virtual void Destroy() override;
LayerComposite* GetFirstChildComposite() override;
- virtual void RenderLayer(const gfx::IntRect& aClipRect) override;
+ virtual void Cleanup() override;
+
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) override;
+
virtual void Prepare(const RenderTargetIntRect& aClipRect) override;
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
}
virtual void CleanupResources() override;
@@ -123,21 +129,23 @@ class RefLayerComposite : public RefLaye
{
template<class ContainerT>
friend void ContainerPrepare(ContainerT* aContainer,
LayerManagerComposite* aManager,
const RenderTargetIntRect& aClipRect);
template<class ContainerT>
friend void ContainerRender(ContainerT* aContainer,
LayerManagerComposite* aManager,
- const gfx::IntRect& aClipRect);
+ const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry);
template<class ContainerT>
friend void RenderLayers(ContainerT* aContainer,
LayerManagerComposite* aManager,
- const gfx::IntRect& aClipRect);
+ const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry);
template<class ContainerT>
friend void RenderIntermediate(ContainerT* aContainer,
LayerManagerComposite* aManager,
const gfx::IntRect& aClipRect,
RefPtr<CompositingRenderTarget> surface);
template<class ContainerT>
friend RefPtr<CompositingRenderTarget>
CreateTemporaryTargetAndCopyFromBackground(ContainerT* aContainer,
@@ -158,17 +166,19 @@ protected:
public:
/** LayerOGL implementation */
Layer* GetLayer() override { return this; }
void Destroy() override;
LayerComposite* GetFirstChildComposite() override;
- virtual void RenderLayer(const gfx::IntRect& aClipRect) override;
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) override;
+
virtual void Prepare(const RenderTargetIntRect& aClipRect) override;
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
}
virtual void CleanupResources() override;
--- a/gfx/layers/composite/ContentHost.cpp
+++ b/gfx/layers/composite/ContentHost.cpp
@@ -33,17 +33,18 @@ ContentHostBase::~ContentHostBase()
void
ContentHostTexture::Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const SamplingFilter aSamplingFilter,
const IntRect& aClipRect,
- const nsIntRegion* aVisibleRegion)
+ const nsIntRegion* aVisibleRegion,
+ const Maybe<gfx::Polygon>& aGeometry)
{
NS_ASSERTION(aVisibleRegion, "Requires a visible region");
AutoLockCompositableHost lock(this);
if (lock.Failed()) {
return;
}
@@ -175,17 +176,20 @@ ContentHostTexture::Composite(LayerCompo
}
gfx::Rect rect(tileScreenRect.x, tileScreenRect.y,
tileScreenRect.width, tileScreenRect.height);
effect->mTextureCoords = Rect(Float(tileRegionRect.x) / texRect.width,
Float(tileRegionRect.y) / texRect.height,
Float(tileRegionRect.width) / texRect.width,
Float(tileRegionRect.height) / texRect.height);
- GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain, aOpacity, aTransform);
+
+ GetCompositor()->DrawGeometry(rect, aClipRect, aEffectChain,
+ aOpacity, aTransform, aGeometry);
+
if (usingTiles) {
DiagnosticFlags diagnostics = DiagnosticFlags::CONTENT | DiagnosticFlags::BIGIMAGE;
if (iterOnWhite) {
diagnostics |= DiagnosticFlags::COMPONENT_ALPHA;
}
GetCompositor()->DrawDiagnostics(diagnostics, rect, aClipRect,
aTransform, mFlashCounter);
}
--- a/gfx/layers/composite/ContentHost.h
+++ b/gfx/layers/composite/ContentHost.h
@@ -11,16 +11,17 @@
#include "mozilla-config.h" // for MOZ_DUMP_PAINTING
#include "CompositableHost.h" // for CompositableHost, etc
#include "RotatedBuffer.h" // for RotatedContentBuffer, etc
#include "mozilla/Attributes.h" // for override
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for Point
+#include "mozilla/gfx/Polygon.h" // for Polygon
#include "mozilla/gfx/Rect.h" // for Rect
#include "mozilla/gfx/Types.h" // for SamplingFilter
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/LayersTypes.h" // for etc
#include "mozilla/layers/TextureHost.h" // for TextureHost
#include "mozilla/mozalloc.h" // for operator delete
@@ -118,17 +119,18 @@ public:
{ }
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
- const nsIntRegion* aVisibleRegion = nullptr) override;
+ const nsIntRegion* aVisibleRegion = nullptr,
+ const Maybe<gfx::Polygon>& aGeometry = Nothing()) override;
virtual void SetCompositor(Compositor* aCompositor) override;
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
virtual void Dump(std::stringstream& aStream,
const char* aPrefix="",
bool aDumpHtml=false) override;
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -282,17 +282,18 @@ void ImageHost::Attach(Layer* aLayer,
void
ImageHost::Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
- const nsIntRegion* aVisibleRegion)
+ const nsIntRegion* aVisibleRegion,
+ const Maybe<gfx::Polygon>& aGeometry)
{
if (!GetCompositor()) {
// should only happen when a tab is dragged to another window and
// async-video is still sending frames but we haven't attached the
// set the new compositor yet.
return;
}
@@ -387,18 +388,18 @@ ImageHost::Composite(LayerComposite* aLa
effect->mTextureCoords = Rect(Float(rect.x - tileRect.x) / tileRect.width,
Float(rect.y - tileRect.y) / tileRect.height,
Float(rect.width) / tileRect.width,
Float(rect.height) / tileRect.height);
if (img->mTextureHost->GetFlags() & TextureFlags::ORIGIN_BOTTOM_LEFT) {
effect->mTextureCoords.y = effect->mTextureCoords.YMost();
effect->mTextureCoords.height = -effect->mTextureCoords.height;
}
- GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain,
- aOpacity, aTransform);
+ GetCompositor()->DrawGeometry(rect, aClipRect, aEffectChain,
+ aOpacity, aTransform, aGeometry);
GetCompositor()->DrawDiagnostics(diagnosticFlags | DiagnosticFlags::BIGIMAGE,
rect, aClipRect, aTransform, mFlashCounter);
} while (it->NextTile());
it->EndBigImageIteration();
// layer border
GetCompositor()->DrawDiagnostics(diagnosticFlags, pictureRect,
aClipRect, aTransform, mFlashCounter);
} else {
@@ -408,18 +409,18 @@ ImageHost::Composite(LayerComposite* aLa
Float(img->mPictureRect.width) / textureSize.width,
Float(img->mPictureRect.height) / textureSize.height);
if (img->mTextureHost->GetFlags() & TextureFlags::ORIGIN_BOTTOM_LEFT) {
effect->mTextureCoords.y = effect->mTextureCoords.YMost();
effect->mTextureCoords.height = -effect->mTextureCoords.height;
}
- GetCompositor()->DrawQuad(pictureRect, aClipRect, aEffectChain,
- aOpacity, aTransform);
+ GetCompositor()->DrawGeometry(pictureRect, aClipRect, aEffectChain,
+ aOpacity, aTransform, aGeometry);
GetCompositor()->DrawDiagnostics(diagnosticFlags,
pictureRect, aClipRect,
aTransform, mFlashCounter);
}
}
// Update mBias last. This can change which frame ChooseImage(Index) would
// return, and we don't want to do that until we've finished compositing
--- a/gfx/layers/composite/ImageHost.h
+++ b/gfx/layers/composite/ImageHost.h
@@ -7,16 +7,17 @@
#define MOZILLA_GFX_IMAGEHOST_H
#include <stdio.h> // for FILE
#include "CompositableHost.h" // for CompositableHost
#include "mozilla/Attributes.h" // for override
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for Point
+#include "mozilla/gfx/Polygon.h" // for Polygon
#include "mozilla/gfx/Rect.h" // for Rect
#include "mozilla/gfx/Types.h" // for SamplingFilter
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
#include "mozilla/layers/TextureHost.h" // for TextureHost, etc
#include "mozilla/mozalloc.h" // for operator delete
#include "nsCOMPtr.h" // for already_AddRefed
@@ -43,17 +44,18 @@ public:
virtual CompositableType GetType() override { return mTextureInfo.mCompositableType; }
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
- const nsIntRegion* aVisibleRegion = nullptr) override;
+ const nsIntRegion* aVisibleRegion = nullptr,
+ const Maybe<gfx::Polygon>& aGeometry = Nothing()) override;
virtual void UseTextureHost(const nsTArray<TimedTexture>& aTextures) override;
virtual void RemoveTextureHost(TextureHost* aTexture) override;
virtual void UseOverlaySource(OverlaySource aOverlay,
const gfx::IntRect& aPictureRect) override;
--- a/gfx/layers/composite/ImageLayerComposite.cpp
+++ b/gfx/layers/composite/ImageLayerComposite.cpp
@@ -85,17 +85,18 @@ ImageLayerComposite::SetLayerManager(Hos
LayerComposite::SetLayerManager(aManager);
mManager = aManager;
if (mImageHost) {
mImageHost->SetCompositor(mCompositor);
}
}
void
-ImageLayerComposite::RenderLayer(const IntRect& aClipRect)
+ImageLayerComposite::RenderLayer(const IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry)
{
if (!mImageHost || !mImageHost->IsAttached()) {
return;
}
#ifdef MOZ_DUMP_PAINTING
if (gfxEnv::DumpCompositorTextures()) {
RefPtr<gfx::DataSourceSurface> surf = mImageHost->GetAsSurface();
--- a/gfx/layers/composite/ImageLayerComposite.h
+++ b/gfx/layers/composite/ImageLayerComposite.h
@@ -40,17 +40,18 @@ public:
virtual void Disconnect() override;
virtual bool SetCompositableHost(CompositableHost* aHost) override;
virtual Layer* GetLayer() override;
virtual void SetLayerManager(HostLayerManager* aManager) override;
- virtual void RenderLayer(const gfx::IntRect& aClipRect) override;
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) override;
virtual void ComputeEffectiveTransforms(const mozilla::gfx::Matrix4x4& aTransformToSurface) override;
virtual void CleanupResources() override;
CompositableHost* GetCompositableHost() override;
virtual void GenEffectChain(EffectChain& aEffect) override;
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -568,17 +568,17 @@ LayerManagerComposite::DrawPaintTimes(Co
static uint16_t sFrameCount = 0;
void
LayerManagerComposite::RenderDebugOverlay(const IntRect& aBounds)
{
bool drawFps = gfxPrefs::LayersDrawFPS();
bool drawFrameCounter = gfxPrefs::DrawFrameCounter();
bool drawFrameColorBars = gfxPrefs::CompositorDrawColorBars();
-
+
TimeStamp now = TimeStamp::Now();
if (drawFps) {
if (!mFPS) {
mFPS = MakeUnique<FPSState>();
}
float alpha = 1;
@@ -921,17 +921,18 @@ LayerManagerComposite::Render(const nsIn
if (haveLayerEffects) {
previousTarget = PushGroupForLayerEffects();
} else {
mTwoPassTmpTarget = nullptr;
}
// Render our layers.
RootLayer()->Prepare(ViewAs<RenderTargetPixel>(clipRect, PixelCastJustification::RenderTargetIsParentLayerForRoot));
- RootLayer()->RenderLayer(clipRect.ToUnknownRect());
+ RootLayer()->RenderLayer(clipRect.ToUnknownRect(), Nothing());
+ RootLayer()->Cleanup();
if (!mRegionToClear.IsEmpty()) {
for (auto iter = mRegionToClear.RectIter(); !iter.Done(); iter.Next()) {
const IntRect& r = iter.Get();
mCompositor->ClearRect(Rect(r.x, r.y, r.width, r.height));
}
}
@@ -1128,17 +1129,17 @@ LayerManagerComposite::RenderToPresentat
// is cleared.
ScopedScissorRect scissorRect(egl, 0, 0, actualWidth, actualHeight);
egl->fClearColor(0.0, 0.0, 0.0, 0.0);
egl->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
const IntRect clipRect = IntRect::Truncate(0, 0, actualWidth, actualHeight);
RootLayer()->Prepare(RenderTargetIntRect::FromUnknownRect(clipRect));
- RootLayer()->RenderLayer(clipRect);
+ RootLayer()->RenderLayer(clipRect, Nothing());
mCompositor->EndFrame();
}
#endif
class TextLayerComposite : public TextLayer,
public LayerComposite
{
@@ -1165,17 +1166,18 @@ public:
virtual void SetLayerManager(HostLayerManager* aManager) override
{
LayerComposite::SetLayerManager(aManager);
mManager = aManager;
}
virtual void Destroy() override { mDestroyed = true; }
- virtual void RenderLayer(const gfx::IntRect& aClipRect) override {}
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) override {}
virtual void CleanupResources() override {};
virtual void GenEffectChain(EffectChain& aEffect) override {}
CompositableHost* GetCompositableHost() override { return nullptr; }
virtual HostLayer* AsHostLayer() override { return this; }
@@ -1208,17 +1210,18 @@ public:
virtual void SetLayerManager(HostLayerManager* aManager) override
{
LayerComposite::SetLayerManager(aManager);
mManager = aManager;
}
virtual void Destroy() override { mDestroyed = true; }
- virtual void RenderLayer(const gfx::IntRect& aClipRect) override {}
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) override {}
virtual void CleanupResources() override {};
virtual void GenEffectChain(EffectChain& aEffect) override {}
CompositableHost* GetCompositableHost() override { return nullptr; }
virtual HostLayer* AsHostLayer() override { return this; }
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -518,17 +518,17 @@ public:
// These getters can be used anytime.
float GetShadowOpacity() { return mShadowOpacity; }
const Maybe<ParentLayerIntRect>& GetShadowClipRect() { return mShadowClipRect; }
const LayerIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
const gfx::Matrix4x4& GetShadowBaseTransform() { return mShadowTransform; }
gfx::Matrix4x4 GetShadowTransform();
bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; }
bool GetShadowOpacitySetByAnimation() { return mShadowOpacitySetByAnimation; }
-
+
/**
* Return true if a checkerboarding background color needs to be drawn
* for this layer.
*/
virtual bool NeedToDrawCheckerboarding(gfx::Color* aOutCheckerboardingColor = nullptr) { return false; }
protected:
HostLayerManager* mCompositorManager;
@@ -572,27 +572,29 @@ public:
{
return nullptr;
}
/* Do NOT call this from the generic LayerComposite destructor. Only from the
* concrete class destructor
*/
virtual void Destroy();
+ virtual void Cleanup() {}
/**
* Perform a first pass over the layer tree to render all of the intermediate
* surfaces that we can. This allows us to avoid framebuffer switches in the
* middle of our render which is inefficient especially on mobile GPUs. This
* must be called before RenderLayer.
*/
virtual void Prepare(const RenderTargetIntRect& aClipRect) {}
// TODO: This should also take RenderTargetIntRect like Prepare.
- virtual void RenderLayer(const gfx::IntRect& aClipRect) = 0;
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) = 0;
virtual bool SetCompositableHost(CompositableHost*)
{
// We must handle this gracefully, see bug 967824
NS_WARNING("called SetCompositableHost for a layer type not accepting a compositable");
return false;
}
--- a/gfx/layers/composite/PaintedLayerComposite.cpp
+++ b/gfx/layers/composite/PaintedLayerComposite.cpp
@@ -6,16 +6,17 @@
#include "PaintedLayerComposite.h"
#include "CompositableHost.h" // for TiledLayerProperties, etc
#include "FrameMetrics.h" // for FrameMetrics
#include "Units.h" // for CSSRect, LayerPixel, etc
#include "gfxEnv.h" // for gfxEnv
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for Point
+#include "mozilla/gfx/Polygon.h" // for Polygon
#include "mozilla/gfx/Rect.h" // for RoundedToInt, Rect
#include "mozilla/gfx/Types.h" // for SamplingFilter::LINEAR
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/ContentHost.h" // for ContentHost
#include "mozilla/layers/Effects.h" // for EffectChain
#include "mozilla/mozalloc.h" // for operator delete
#include "nsAString.h"
#include "mozilla/RefPtr.h" // for nsRefPtr
@@ -93,17 +94,18 @@ PaintedLayerComposite::GetRenderState()
{
if (!mBuffer || !mBuffer->IsAttached() || mDestroyed) {
return LayerRenderState();
}
return mBuffer->GetRenderState();
}
void
-PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect)
+PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry)
{
if (!mBuffer || !mBuffer->IsAttached()) {
return;
}
PROFILER_LABEL("PaintedLayerComposite", "RenderLayer",
js::ProfileEntry::Category::GRAPHICS);
Compositor* compositor = mCompositeManager->GetCompositor();
@@ -118,27 +120,24 @@ PaintedLayerComposite::RenderLayer(const
if (gfxEnv::DumpCompositorTextures()) {
RefPtr<gfx::DataSourceSurface> surf = mBuffer->GetAsSurface();
if (surf) {
WriteSnapshotToDumpFile(this, surf);
}
}
#endif
-
RenderWithAllMasks(this, compositor, aClipRect,
- [&](EffectChain& effectChain, const gfx::IntRect& clipRect) {
+ [&](EffectChain& effectChain,
+ const gfx::IntRect& clipRect) {
mBuffer->SetPaintWillResample(MayResample());
- mBuffer->Composite(this, effectChain,
- GetEffectiveOpacity(),
- GetEffectiveTransform(),
- GetSamplingFilter(),
- clipRect,
- &visibleRegion);
+ mBuffer->Composite(this, effectChain, GetEffectiveOpacity(),
+ GetEffectiveTransform(), GetSamplingFilter(),
+ clipRect, &visibleRegion, aGeometry);
});
mBuffer->BumpFlashCounter();
compositor->MakeCurrent();
}
CompositableHost*
--- a/gfx/layers/composite/PaintedLayerComposite.h
+++ b/gfx/layers/composite/PaintedLayerComposite.h
@@ -46,17 +46,18 @@ public:
CompositableHost* GetCompositableHost() override;
virtual void Destroy() override;
virtual Layer* GetLayer() override;
virtual void SetLayerManager(HostLayerManager* aManager) override;
- virtual void RenderLayer(const gfx::IntRect& aClipRect) override;
+ virtual void RenderLayer(const gfx::IntRect& aClipRect,
+ const Maybe<gfx::Polygon>& aGeometry) override;
virtual void CleanupResources() override;
virtual void GenEffectChain(EffectChain& aEffect) override;
virtual bool SetCompositableHost(CompositableHost* aHost) override;
virtual HostLayer* AsHostLayer() override { return this; }
--- a/gfx/layers/composite/TiledContentHost.cpp
+++ b/gfx/layers/composite/TiledContentHost.cpp
@@ -389,17 +389,18 @@ TiledLayerBufferComposite::Clear()
void
TiledContentHost::Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
- const nsIntRegion* aVisibleRegion /* = nullptr */)
+ const nsIntRegion* aVisibleRegion /* = nullptr */,
+ const Maybe<gfx::Polygon>& aGeometry)
{
MOZ_ASSERT(mCompositor);
// Reduce the opacity of the low-precision buffer to make it a
// little more subtle and less jarring. In particular, text
// rendered at low-resolution and scaled tends to look pretty
// heavy and this helps mitigate that. When we reduce the opacity
// we also make sure to draw the background color behind the
// reduced-opacity tile so that content underneath doesn't show
@@ -434,33 +435,35 @@ TiledContentHost::Composite(LayerComposi
renderRegion = &tmpRegion;
}
#endif
// Render the low and high precision buffers.
RenderLayerBuffer(mLowPrecisionTiledBuffer,
lowPrecisionOpacityReduction < 1.0f ? &backgroundColor : nullptr,
aEffectChain, lowPrecisionOpacityReduction * aOpacity,
- aSamplingFilter, aClipRect, *renderRegion, aTransform);
+ aSamplingFilter, aClipRect, *renderRegion, aTransform, aGeometry);
+
RenderLayerBuffer(mTiledBuffer, nullptr, aEffectChain, aOpacity, aSamplingFilter,
- aClipRect, *renderRegion, aTransform);
+ aClipRect, *renderRegion, aTransform, aGeometry);
}
void
TiledContentHost::RenderTile(TileHost& aTile,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
const nsIntRegion& aScreenRegion,
const IntPoint& aTextureOffset,
const IntSize& aTextureBounds,
- const gfx::Rect& aVisibleRect)
+ const gfx::Rect& aVisibleRect,
+ const Maybe<gfx::Polygon>& aGeometry)
{
MOZ_ASSERT(!aTile.IsPlaceholderTile());
AutoLockTextureHost autoLock(aTile.mTextureHost);
AutoLockTextureHost autoLockOnWhite(aTile.mTextureHostOnWhite);
if (autoLock.Failed() ||
autoLockOnWhite.Failed()) {
NS_WARNING("Failed to lock tile");
@@ -493,35 +496,39 @@ TiledContentHost::RenderTile(TileHost& a
Rect graphicsRect(rect.x, rect.y, rect.width, rect.height);
Rect textureRect(rect.x - aTextureOffset.x, rect.y - aTextureOffset.y,
rect.width, rect.height);
effect->mTextureCoords = Rect(textureRect.x / aTextureBounds.width,
textureRect.y / aTextureBounds.height,
textureRect.width / aTextureBounds.width,
textureRect.height / aTextureBounds.height);
- mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, opacity, aTransform, aVisibleRect);
+
+ mCompositor->DrawGeometry(graphicsRect, aClipRect, aEffectChain, opacity,
+ aTransform, aVisibleRect, aGeometry);
}
+
DiagnosticFlags flags = DiagnosticFlags::CONTENT | DiagnosticFlags::TILE;
if (aTile.mTextureHostOnWhite) {
flags |= DiagnosticFlags::COMPONENT_ALPHA;
}
mCompositor->DrawDiagnostics(flags,
aScreenRegion, aClipRect, aTransform, mFlashCounter);
}
void
TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
const Color* aBackgroundColor,
EffectChain& aEffectChain,
float aOpacity,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
nsIntRegion aVisibleRegion,
- gfx::Matrix4x4 aTransform)
+ gfx::Matrix4x4 aTransform,
+ const Maybe<Polygon>& aGeometry)
{
if (!mCompositor) {
NS_WARNING("Can't render tiled content host - no compositor");
return;
}
float resolution = aLayerBuffer.GetResolution();
gfx::Size layerScale(1, 1);
@@ -567,17 +574,18 @@ TiledContentHost::RenderLayerBuffer(Tile
if (aBackgroundColor) {
nsIntRegion backgroundRegion = compositeRegion;
backgroundRegion.ScaleRoundOut(resolution, resolution);
EffectChain effect;
effect.mPrimaryEffect = new EffectSolidColor(*aBackgroundColor);
for (auto iter = backgroundRegion.RectIter(); !iter.Done(); iter.Next()) {
const IntRect& rect = iter.Get();
Rect graphicsRect(rect.x, rect.y, rect.width, rect.height);
- mCompositor->DrawQuad(graphicsRect, aClipRect, effect, 1.0, aTransform);
+ mCompositor->DrawGeometry(graphicsRect, aClipRect, effect,
+ 1.0, aTransform, aGeometry);
}
}
for (size_t i = 0; i < aLayerBuffer.GetTileCount(); ++i) {
TileHost& tile = aLayerBuffer.GetTile(i);
if (tile.IsPlaceholderTile()) {
continue;
}
@@ -594,17 +602,19 @@ TiledContentHost::RenderLayerBuffer(Tile
continue;
}
tileDrawRegion.ScaleRoundOut(resolution, resolution);
RenderTile(tile, aEffectChain, aOpacity,
aTransform, aSamplingFilter, aClipRect, tileDrawRegion,
tileOffset * resolution, aLayerBuffer.GetTileSize(),
gfx::Rect(visibleRect.x, visibleRect.y,
- visibleRect.width, visibleRect.height));
+ visibleRect.width, visibleRect.height),
+ aGeometry);
+
if (tile.mTextureHostOnWhite) {
componentAlphaDiagnostic = DiagnosticFlags::COMPONENT_ALPHA;
}
}
gfx::Rect rect(visibleRect.x, visibleRect.y,
visibleRect.width, visibleRect.height);
GetCompositor()->DrawDiagnostics(DiagnosticFlags::CONTENT | componentAlphaDiagnostic,
--- a/gfx/layers/composite/TiledContentHost.h
+++ b/gfx/layers/composite/TiledContentHost.h
@@ -231,17 +231,18 @@ public:
const SurfaceDescriptorTiles& aTiledDescriptor);
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
- const nsIntRegion* aVisibleRegion = nullptr) override;
+ const nsIntRegion* aVisibleRegion = nullptr,
+ const Maybe<gfx::Polygon>& aGeometry = Nothing()) override;
virtual CompositableType GetType() override { return CompositableType::CONTENT_TILED; }
virtual TiledContentHost* AsTiledContentHost() override { return this; }
virtual void Attach(Layer* aLayer,
Compositor* aCompositor,
AttachFlags aFlags = NO_FLAGS) override;
@@ -261,29 +262,31 @@ private:
void RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
const gfx::Color* aBackgroundColor,
EffectChain& aEffectChain,
float aOpacity,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
nsIntRegion aMaskRegion,
- gfx::Matrix4x4 aTransform);
+ gfx::Matrix4x4 aTransform,
+ const Maybe<gfx::Polygon>& aGeometry);
// Renders a single given tile.
void RenderTile(TileHost& aTile,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::SamplingFilter aSamplingFilter,
const gfx::IntRect& aClipRect,
const nsIntRegion& aScreenRegion,
const gfx::IntPoint& aTextureOffset,
const gfx::IntSize& aTextureBounds,
- const gfx::Rect& aVisibleRect);
+ const gfx::Rect& aVisibleRect,
+ const Maybe<gfx::Polygon>& aGeometry);
void EnsureTileStore() {}
TiledLayerBufferComposite mTiledBuffer;
TiledLayerBufferComposite mLowPrecisionTiledBuffer;
};
} // namespace layers
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -1814,10 +1814,16 @@ PerUnitTexturePoolOGL::DestroyTextures()
if (mGL && mGL->MakeCurrent()) {
if (mTextures.Length() > 0) {
mGL->fDeleteTextures(mTextures.Length(), &mTextures[0]);
}
}
mTextures.SetLength(0);
}
+bool
+CompositorOGL::SupportsLayerGeometry() const
+{
+ return gfxPrefs::OGLLayerGeometry();
+}
+
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -166,16 +166,18 @@ public:
virtual void DrawTriangle(const gfx::TexturedTriangle& aTriangle,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect) override;
+ virtual bool SupportsLayerGeometry() const override;
+
virtual void EndFrame() override;
virtual bool SupportsPartialTextureUpdate() override;
virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) override
{
if (!mGLContext)
return false;
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -522,16 +522,17 @@ private:
DECL_GFX_PREF(Once, "layers.tiles.adjust", LayersTilesAdjust, bool, true);
DECL_GFX_PREF(Once, "layers.tiles.edge-padding", TileEdgePaddingEnabled, bool, true);
DECL_GFX_PREF(Live, "layers.tiles.fade-in.enabled", LayerTileFadeInEnabled, bool, false);
DECL_GFX_PREF(Live, "layers.tiles.fade-in.duration-ms", LayerTileFadeInDuration, uint32_t, 250);
DECL_GFX_PREF(Live, "layers.transaction.warning-ms", LayerTransactionWarning, uint32_t, 200);
DECL_GFX_PREF(Once, "layers.uniformity-info", UniformityInfo, bool, false);
DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces", UseImageOffscreenSurfaces, bool, true);
DECL_GFX_PREF(Live, "layers.draw-mask-debug", DrawMaskLayer, bool, false);
+ DECL_GFX_PREF(Live, "layers.geometry.opengl.enabled", OGLLayerGeometry, bool, false);
DECL_GFX_PREF(Live, "layout.css.scroll-behavior.damping-ratio", ScrollBehaviorDampingRatio, float, 1.0f);
DECL_GFX_PREF(Live, "layout.css.scroll-behavior.enabled", ScrollBehaviorEnabled, bool, true);
DECL_GFX_PREF(Live, "layout.css.scroll-behavior.spring-constant", ScrollBehaviorSpringConstant, float, 250.0f);
DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-max-velocity", ScrollSnapPredictionMaxVelocity, int32_t, 2000);
DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-sensitivity", ScrollSnapPredictionSensitivity, float, 0.750f);
DECL_GFX_PREF(Live, "layout.css.scroll-snap.proximity-threshold", ScrollSnapProximityThreshold, int32_t, 200);
DECL_GFX_PREF(Live, "layout.css.touch_action.enabled", TouchActionEnabled, bool, false);