diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp index 77c58117863e..0d585b41e452 100644 --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -651,6 +651,49 @@ public: BorderWidths mWidths; }; +struct TextLayerProperties : public LayerPropertiesBase +{ + explicit TextLayerProperties(TextLayer *aLayer) + : LayerPropertiesBase(aLayer) + , mBounds(aLayer->GetBounds()) + , mGlyphs(aLayer->GetGlyphs()) + , mFont(aLayer->GetScaledFont()) + { } + +protected: + TextLayerProperties(const TextLayerProperties& a) = delete; + TextLayerProperties& operator=(const TextLayerProperties& a) = delete; + +public: + bool ComputeChangeInternal(const char* aPrefix, + nsIntRegion& aOutRegion, + NotifySubDocInvalidationFunc aCallback) override + { + TextLayer* text = static_cast(mLayer.get()); + + if (!text->GetLocalVisibleRegion().ToUnknownRegion().IsEqual(mVisibleRegion)) { + IntRect result = NewTransformedBoundsForLeaf(); + result = result.Union(OldTransformedBoundsForLeaf()); + aOutRegion = result; + return true; + } + + if (!mBounds.IsEqualEdges(text->GetBounds()) || + mGlyphs != text->GetGlyphs() || + mFont != text->GetScaledFont()) { + LTI_DUMP(NewTransformedBoundsForLeaf(), "bounds"); + aOutRegion = NewTransformedBoundsForLeaf(); + return true; + } + + return true; + } + + gfx::IntRect mBounds; + nsTArray mGlyphs; + gfx::ScaledFont* mFont; +}; + static ImageHost* GetImageHost(Layer* aLayer) { HostLayer* compositor = aLayer->AsHostLayer(); @@ -787,6 +830,8 @@ CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask /* = false */) return MakeUnique(static_cast(aRoot)); case Layer::TYPE_BORDER: return MakeUnique(static_cast(aRoot)); + case Layer::TYPE_TEXT: + return MakeUnique(static_cast(aRoot)); case Layer::TYPE_DISPLAYITEM: case Layer::TYPE_READBACK: case Layer::TYPE_SHADOW: diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 0ed9020c4b05..773736c1743d 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -2119,6 +2119,23 @@ ColorLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) layer->set_color(mColor.ToABGR()); } +void +TextLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + Layer::PrintInfo(aStream, aPrefix); + AppendToString(aStream, mBounds, " [bounds=", "]"); +} + +void +TextLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) +{ + Layer::DumpPacket(aPacket, aParent); + // Get this layer data + using namespace layerscope; + LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1); + layer->set_type(LayersPacket::Layer::TextLayer); +} + void BorderLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix) { @@ -2468,5 +2485,20 @@ ToOutsideIntRect(const gfxRect &aRect) return IntRect::RoundOut(aRect.x, aRect.y, aRect.Width(), aRect.Height()); } +TextLayer::TextLayer(LayerManager* aManager, void* aImplData) + : Layer(aManager, aImplData) +{} + +TextLayer::~TextLayer() +{} + +void +TextLayer::SetGlyphs(nsTArray&& aGlyphs) +{ + MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Glyphs", this)); + mGlyphs = Move(aGlyphs); + Mutated(); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 08d03d2cc086..075fb791b0e1 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -92,6 +92,7 @@ class DisplayItemLayer; class ColorLayer; class CompositorAnimations; class CompositorBridgeChild; +class TextLayer; class CanvasLayer; class BorderLayer; class ReadbackLayer; @@ -433,6 +434,11 @@ public: * Create a ColorLayer for this manager's layer tree. */ virtual already_AddRefed CreateColorLayer() = 0; + /** + * CONSTRUCTION PHASE ONLY + * Create a TextLayer for this manager's layer tree. + */ + virtual already_AddRefed CreateTextLayer() = 0; /** * CONSTRUCTION PHASE ONLY * Create a BorderLayer for this manager's layer tree. @@ -824,6 +830,7 @@ public: TYPE_CONTAINER, TYPE_DISPLAYITEM, TYPE_IMAGE, + TYPE_TEXT, TYPE_BORDER, TYPE_READBACK, TYPE_REF, @@ -1556,6 +1563,12 @@ public: */ virtual ColorLayer* AsColorLayer() { return nullptr; } + /** + * Dynamic cast to a TextLayer. Returns null if this is not a + * TextLayer. + */ + virtual TextLayer* AsTextLayer() { return nullptr; } + /** * Dynamic cast to a Border. Returns null if this is not a * ColorLayer. @@ -2510,6 +2523,63 @@ protected: gfx::Color mColor; }; +/** + * A Layer which renders Glyphs. + */ +class TextLayer : public Layer { +public: + virtual TextLayer* AsTextLayer() override { return this; } + + /** + * CONSTRUCTION PHASE ONLY + */ + void SetBounds(const gfx::IntRect& aBounds) + { + if (!mBounds.IsEqualEdges(aBounds)) { + mBounds = aBounds; + Mutated(); + } + } + + const gfx::IntRect& GetBounds() + { + return mBounds; + } + + void SetScaledFont(gfx::ScaledFont* aScaledFont) { + if (aScaledFont != mFont) { + mFont = aScaledFont; + Mutated(); + } + } + + const nsTArray& GetGlyphs() { return mGlyphs; } + + gfx::ScaledFont* GetScaledFont() { return mFont; } + + MOZ_LAYER_DECL_NAME("TextLayer", TYPE_TEXT) + + virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override + { + gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; + mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr); + ComputeEffectiveTransformForMaskLayers(aTransformToSurface); + } + + virtual void SetGlyphs(nsTArray&& aGlyphs); +protected: + TextLayer(LayerManager* aManager, void* aImplData); + ~TextLayer(); + + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override; + + virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override; + + gfx::IntRect mBounds; + nsTArray mGlyphs; + RefPtr mFont; +}; + /** * A Layer which renders a rounded rect. */ diff --git a/gfx/layers/basic/BasicLayers.h b/gfx/layers/basic/BasicLayers.h index 4c2aaef71629..e8f30ba9c064 100644 --- a/gfx/layers/basic/BasicLayers.h +++ b/gfx/layers/basic/BasicLayers.h @@ -117,6 +117,7 @@ public: virtual already_AddRefed CreateImageLayer() override; virtual already_AddRefed CreateCanvasLayer() override; virtual already_AddRefed CreateColorLayer() override; + virtual already_AddRefed CreateTextLayer() override; virtual already_AddRefed CreateBorderLayer() override; virtual already_AddRefed CreateReadbackLayer() override; virtual already_AddRefed CreateDisplayItemLayer() override; diff --git a/gfx/layers/basic/BasicTextLayer.cpp b/gfx/layers/basic/BasicTextLayer.cpp new file mode 100644 index 000000000000..c0c1c4745281 --- /dev/null +++ b/gfx/layers/basic/BasicTextLayer.cpp @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "BasicLayersImpl.h" // for FillRectWithMask, etc +#include "Layers.h" // for ColorLayer, etc +#include "BasicImplData.h" // for BasicImplData +#include "BasicLayers.h" // for BasicLayerManager +#include "gfxContext.h" // for gfxContext, etc +#include "gfxRect.h" // for gfxRect +#include "gfx2DGlue.h" +#include "mozilla/mozalloc.h" // for operator new +#include "nsCOMPtr.h" // for already_AddRefed +#include "nsDebug.h" // for NS_ASSERTION +#include "nsISupportsImpl.h" // for Layer::AddRef, etc +#include "nsRect.h" // for mozilla::gfx::IntRect +#include "nsRegion.h" // for nsIntRegion +#include "mozilla/gfx/PathHelpers.h" +#include "mozilla/layers/LayersMessages.h" // for GlyphArray + +using namespace mozilla::gfx; + +namespace mozilla { +namespace layers { + +class BasicTextLayer : public TextLayer, public BasicImplData { +public: + explicit BasicTextLayer(BasicLayerManager* aLayerManager) : + TextLayer(aLayerManager, static_cast(this)) + { + MOZ_COUNT_CTOR(BasicTextLayer); + } + +protected: + virtual ~BasicTextLayer() + { + MOZ_COUNT_DTOR(BasicTextLayer); + } + +public: + virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override + { + NS_ASSERTION(BasicManager()->InConstruction(), + "Can only set properties in construction phase"); + TextLayer::SetVisibleRegion(aRegion); + } + + virtual void Paint(DrawTarget* aDT, + const gfx::Point& aDeviceOffset, + Layer* aMaskLayer) override + { + if (IsHidden() || !mFont) { + return; + } + + Rect snapped(mBounds.x, mBounds.y, mBounds.Width(), mBounds.Height()); + MaybeSnapToDevicePixels(snapped, *aDT, true); + + // We don't currently support subpixel-AA in TextLayers since we + // don't check if there's an opaque background color behind them. + // We should fix this before using them in production. + aDT->SetPermitSubpixelAA(false); + + for (GlyphArray& g : mGlyphs) { + GlyphBuffer buffer = { g.glyphs().Elements(), (uint32_t)g.glyphs().Length() }; + aDT->FillGlyphs(mFont, buffer, ColorPattern(g.color().value())); + } + } + +protected: + BasicLayerManager* BasicManager() + { + return static_cast(mManager); + } +}; + +already_AddRefed +BasicLayerManager::CreateTextLayer() +{ + NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); + RefPtr layer = new BasicTextLayer(this); + return layer.forget(); +} + +} // namespace layers +} // namespace mozilla diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index 64c9fa22da6b..f6facf44e076 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -106,6 +106,7 @@ public: virtual already_AddRefed CreateCanvasLayer() override; virtual already_AddRefed CreateReadbackLayer() override; virtual already_AddRefed CreateColorLayer() override; + virtual already_AddRefed CreateTextLayer() override; virtual already_AddRefed CreateBorderLayer() override; virtual already_AddRefed CreateRefLayer() override; diff --git a/gfx/layers/client/ClientTextLayer.cpp b/gfx/layers/client/ClientTextLayer.cpp new file mode 100644 index 000000000000..923211c84c4d --- /dev/null +++ b/gfx/layers/client/ClientTextLayer.cpp @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "ClientLayerManager.h" // for ClientLayerManager, etc +#include "Layers.h" // for ColorLayer, etc +#include "mozilla/layers/LayersMessages.h" // for ColorLayerAttributes, etc +#include "mozilla/mozalloc.h" // for operator new +#include "nsCOMPtr.h" // for already_AddRefed +#include "nsDebug.h" // for NS_ASSERTION +#include "nsISupportsImpl.h" // for Layer::AddRef, etc +#include "nsRegion.h" // for nsIntRegion + +namespace mozilla { +namespace layers { + +using namespace mozilla::gfx; + +class ClientTextLayer : public TextLayer, + public ClientLayer { +public: + explicit ClientTextLayer(ClientLayerManager* aLayerManager) : + TextLayer(aLayerManager, static_cast(this)), + mSwapped(false) + { + MOZ_COUNT_CTOR(ClientTextLayer); + } + +protected: + virtual ~ClientTextLayer() + { + MOZ_COUNT_DTOR(ClientTextLayer); + } + +public: + virtual void SetVisibleRegion(const LayerIntRegion& aRegion) + { + NS_ASSERTION(ClientManager()->InConstruction(), + "Can only set properties in construction phase"); + TextLayer::SetVisibleRegion(aRegion); + } + + virtual void RenderLayer() + { + RenderMaskLayers(this); + } + + virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) + { + NS_ASSERTION(!mSwapped, "Trying to access glyph array after it's been swapped!"); + aAttrs = TextLayerAttributes(GetBounds(), nsTArray(), uintptr_t(mFont.get())); + aAttrs.get_TextLayerAttributes().glyphs().SwapElements(mGlyphs); + mSwapped = true; + } + + virtual void SetGlyphs(nsTArray&& aGlyphs) + { + TextLayer::SetGlyphs(Move(aGlyphs)); + mSwapped = false; + } + + virtual Layer* AsLayer() { return this; } + virtual ShadowableLayer* AsShadowableLayer() { return this; } + +protected: + ClientLayerManager* ClientManager() + { + return static_cast(mManager); + } + + bool mSwapped; +}; + +already_AddRefed +ClientLayerManager::CreateTextLayer() +{ + NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); + RefPtr layer = + new ClientTextLayer(this); + CREATE_SHADOW(Text); + return layer.forget(); +} + +} // namespace layers +} // namespace mozilla diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 7ea9197767d4..740dd2a5476e 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -1236,6 +1236,50 @@ LayerManagerComposite::HandlePixelsTarget() } #endif +class TextLayerComposite : public TextLayer, + public LayerComposite +{ +public: + explicit TextLayerComposite(LayerManagerComposite *aManager) + : TextLayer(aManager, nullptr) + , LayerComposite(aManager) + { + MOZ_COUNT_CTOR(TextLayerComposite); + mImplData = static_cast(this); + } + +protected: + ~TextLayerComposite() + { + MOZ_COUNT_DTOR(TextLayerComposite); + Destroy(); + } + +public: + // LayerComposite Implementation + virtual Layer* GetLayer() override { return this; } + + virtual void SetLayerManager(HostLayerManager* aManager) override + { + LayerComposite::SetLayerManager(aManager); + mManager = aManager; + } + + virtual void Destroy() override { mDestroyed = true; } + + virtual void RenderLayer(const gfx::IntRect& aClipRect, + const Maybe& aGeometry) override {} + virtual void CleanupResources() override {}; + + virtual void GenEffectChain(EffectChain& aEffect) override {} + + CompositableHost* GetCompositableHost() override { return nullptr; } + + virtual HostLayer* AsHostLayer() override { return this; } + + virtual const char* Name() const override { return "TextLayerComposite"; } +}; + class BorderLayerComposite : public BorderLayer, public LayerComposite { @@ -1340,6 +1384,16 @@ LayerManagerComposite::CreateRefLayer() return RefPtr(new RefLayerComposite(this)).forget(); } +already_AddRefed +LayerManagerComposite::CreateTextLayer() +{ + if (LayerManagerComposite::mDestroyed) { + NS_WARNING("Call on destroyed layer manager"); + return nullptr; + } + return RefPtr(new TextLayerComposite(this)).forget(); +} + already_AddRefed LayerManagerComposite::CreateBorderLayer() { diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 7ad5f653f4ee..82e7e9f95b06 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -308,6 +308,7 @@ public: virtual already_AddRefed CreateContainerLayer() override; virtual already_AddRefed CreateImageLayer() override; virtual already_AddRefed CreateColorLayer() override; + virtual already_AddRefed CreateTextLayer() override; virtual already_AddRefed CreateBorderLayer() override; virtual already_AddRefed CreateCanvasLayer() override; virtual already_AddRefed CreateRefLayer() override; diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 94a181915cec..35f82219e404 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -246,6 +246,17 @@ LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo) UpdateHitTestingTree(layer, "CreateColorLayer"); break; } + case Edit::TOpCreateTextLayer: { + MOZ_LAYERS_LOG(("[ParentSide] CreateTextLayer")); + + RefPtr layer = mLayerManager->CreateTextLayer(); + if (!BindLayer(layer, edit.get_OpCreateTextLayer())) { + return IPC_FAIL_NO_REASON(this); + } + + UpdateHitTestingTree(layer, "CreateTextLayer"); + break; + } case Edit::TOpCreateBorderLayer: { MOZ_LAYERS_LOG(("[ParentSide] CreateBorderLayer")); @@ -611,6 +622,19 @@ LayerTransactionParent::SetLayerAttributes(const OpSetLayerAttributes& aOp) colorLayer->SetBounds(specific.get_ColorLayerAttributes().bounds()); break; } + case Specific::TTextLayerAttributes: { + MOZ_LAYERS_LOG(("[ParentSide] text layer")); + + TextLayer* textLayer = layer->AsTextLayer(); + if (!textLayer) { + return false; + } + const auto& tla = specific.get_TextLayerAttributes(); + textLayer->SetBounds(tla.bounds()); + textLayer->SetGlyphs(Move(const_cast&>(tla.glyphs()))); + textLayer->SetScaledFont(reinterpret_cast(tla.scaledFont())); + break; + } case Specific::TBorderLayerAttributes: { MOZ_LAYERS_LOG(("[ParentSide] border layer")); diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 74dc33e33106..dd5a895509a3 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -71,6 +71,7 @@ struct OpCreatePaintedLayer { LayerHandle layer; }; struct OpCreateContainerLayer { LayerHandle layer; }; struct OpCreateImageLayer { LayerHandle layer; }; struct OpCreateColorLayer { LayerHandle layer; }; +struct OpCreateTextLayer { LayerHandle layer; }; struct OpCreateBorderLayer { LayerHandle layer; }; struct OpCreateCanvasLayer { LayerHandle layer; }; struct OpCreateRefLayer { LayerHandle layer; }; @@ -294,6 +295,9 @@ struct GlyphArray Glyph[] glyphs; }; +// XXX - Bas - Hack warning! This is using a raw pointer to a ScaledFont* +// and won't work with e10s. +struct TextLayerAttributes { IntRect bounds; GlyphArray[] glyphs; uintptr_t scaledFont; }; struct ColorLayerAttributes { LayerColor color; IntRect bounds; }; struct CanvasLayerAttributes { SamplingFilter samplingFilter; IntRect bounds; }; struct RefLayerAttributes { @@ -314,6 +318,7 @@ union SpecificLayerAttributes { ContainerLayerAttributes; ColorLayerAttributes; CanvasLayerAttributes; + TextLayerAttributes; RefLayerAttributes; ImageLayerAttributes; BorderLayerAttributes; @@ -492,6 +497,7 @@ union Edit { OpCreateContainerLayer; OpCreateImageLayer; OpCreateColorLayer; + OpCreateTextLayer; OpCreateBorderLayer; OpCreateCanvasLayer; OpCreateRefLayer; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 05b6e82a8ef8..d0c00fdde266 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -339,6 +339,11 @@ ShadowLayerForwarder::CreatedColorLayer(ShadowableLayer* aColor) CreatedLayer(mTxn, aColor); } void +ShadowLayerForwarder::CreatedTextLayer(ShadowableLayer* aColor) +{ + CreatedLayer(mTxn, aColor); +} +void ShadowLayerForwarder::CreatedBorderLayer(ShadowableLayer* aBorder) { CreatedLayer(mTxn, aBorder); diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index 41c49005020a..6c893cec5cb2 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -177,6 +177,7 @@ public: void CreatedColorLayer(ShadowableLayer* aColor); void CreatedCanvasLayer(ShadowableLayer* aCanvas); void CreatedRefLayer(ShadowableLayer* aRef); + void CreatedTextLayer(ShadowableLayer* aRef); void CreatedBorderLayer(ShadowableLayer* aRef); /** diff --git a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp index f5dec2dcf0ac..5edeeab3faa0 100644 --- a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp +++ b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp @@ -164,6 +164,13 @@ LayerManagerMLGPU::CreateBorderLayer() return nullptr; } +already_AddRefed +LayerManagerMLGPU::CreateTextLayer() +{ + MOZ_ASSERT_UNREACHABLE("Not yet implemented"); + return nullptr; +} + already_AddRefed LayerManagerMLGPU::CreateCanvasLayer() { diff --git a/gfx/layers/mlgpu/LayerManagerMLGPU.h b/gfx/layers/mlgpu/LayerManagerMLGPU.h index 85bc693eae5a..8751a2fc7a8a 100644 --- a/gfx/layers/mlgpu/LayerManagerMLGPU.h +++ b/gfx/layers/mlgpu/LayerManagerMLGPU.h @@ -44,6 +44,7 @@ public: already_AddRefed CreateContainerLayer() override; already_AddRefed CreateImageLayer() override; already_AddRefed CreateColorLayer() override; + already_AddRefed CreateTextLayer() override; already_AddRefed CreateCanvasLayer() override; already_AddRefed CreateRefLayer() override; already_AddRefed CreateBorderLayer() override; diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 942cdd6713f5..f84461d94c9e 100755 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -342,6 +342,7 @@ UNIFIED_SOURCES += [ 'basic/BasicLayerManager.cpp', 'basic/BasicLayersImpl.cpp', 'basic/BasicPaintedLayer.cpp', + 'basic/BasicTextLayer.cpp', 'basic/TextureHostBasic.cpp', 'BSPTree.cpp', 'BufferTexture.cpp', @@ -356,6 +357,7 @@ UNIFIED_SOURCES += [ 'client/ClientImageLayer.cpp', 'client/ClientLayerManager.cpp', 'client/ClientPaintedLayer.cpp', + 'client/ClientTextLayer.cpp', 'client/ClientTiledPaintedLayer.cpp', 'client/CompositableClient.cpp', 'client/ContentClient.cpp', diff --git a/gfx/layers/protobuf/LayerScopePacket.pb.cc b/gfx/layers/protobuf/LayerScopePacket.pb.cc index 823e8cf279ac..993b68992d88 100644 --- a/gfx/layers/protobuf/LayerScopePacket.pb.cc +++ b/gfx/layers/protobuf/LayerScopePacket.pb.cc @@ -302,6 +302,7 @@ const LayersPacket_Layer_LayerType LayersPacket_Layer::PaintedLayer; const LayersPacket_Layer_LayerType LayersPacket_Layer::CanvasLayer; const LayersPacket_Layer_LayerType LayersPacket_Layer::ImageLayer; const LayersPacket_Layer_LayerType LayersPacket_Layer::ColorLayer; +const LayersPacket_Layer_LayerType LayersPacket_Layer::TextLayer; const LayersPacket_Layer_LayerType LayersPacket_Layer::RefLayer; const LayersPacket_Layer_LayerType LayersPacket_Layer::ReadbackLayer; const LayersPacket_Layer_LayerType LayersPacket_Layer::DisplayItemLayer; diff --git a/gfx/layers/protobuf/LayerScopePacket.pb.h b/gfx/layers/protobuf/LayerScopePacket.pb.h index d9c05c52b0dd..5c25095eee67 100644 --- a/gfx/layers/protobuf/LayerScopePacket.pb.h +++ b/gfx/layers/protobuf/LayerScopePacket.pb.h @@ -131,6 +131,7 @@ enum LayersPacket_Layer_LayerType { LayersPacket_Layer_LayerType_CanvasLayer = 4, LayersPacket_Layer_LayerType_ImageLayer = 5, LayersPacket_Layer_LayerType_ColorLayer = 6, + LayersPacket_Layer_LayerType_TextLayer = 7, LayersPacket_Layer_LayerType_RefLayer = 8, LayersPacket_Layer_LayerType_ReadbackLayer = 9, LayersPacket_Layer_LayerType_DisplayItemLayer = 10 @@ -1951,6 +1952,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite /* @@protoc_in LayersPacket_Layer_LayerType_ImageLayer; static const LayerType ColorLayer = LayersPacket_Layer_LayerType_ColorLayer; + static const LayerType TextLayer = + LayersPacket_Layer_LayerType_TextLayer; static const LayerType RefLayer = LayersPacket_Layer_LayerType_RefLayer; static const LayerType ReadbackLayer = diff --git a/gfx/layers/protobuf/LayerScopePacket.proto b/gfx/layers/protobuf/LayerScopePacket.proto index a871aa85948d..c72f0e82a65c 100644 --- a/gfx/layers/protobuf/LayerScopePacket.proto +++ b/gfx/layers/protobuf/LayerScopePacket.proto @@ -79,6 +79,7 @@ message LayersPacket { CanvasLayer = 4; ImageLayer = 5; ColorLayer = 6; + TextLayer = 7; RefLayer = 8; ReadbackLayer = 9; DisplayItemLayer = 10; diff --git a/gfx/layers/wr/WebRenderLayerManager.h b/gfx/layers/wr/WebRenderLayerManager.h index bc5f47e95b59..1b2aba15a911 100644 --- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -84,6 +84,7 @@ public: already_AddRefed CreateContainerLayer() override { return nullptr; } already_AddRefed CreateImageLayer() override { return nullptr; } already_AddRefed CreateColorLayer() override { return nullptr; } + already_AddRefed CreateTextLayer() override { return nullptr; } already_AddRefed CreateBorderLayer() override { return nullptr; } already_AddRefed CreateCanvasLayer() override { return nullptr; } diff --git a/gfx/tests/gtest/TestLayers.cpp b/gfx/tests/gtest/TestLayers.cpp index c055cc0a3e5a..e56be233586b 100644 --- a/gfx/tests/gtest/TestLayers.cpp +++ b/gfx/tests/gtest/TestLayers.cpp @@ -76,6 +76,9 @@ public: virtual already_AddRefed CreateColorLayer() { MOZ_CRASH("Not implemented."); } + virtual already_AddRefed CreateTextLayer() { + MOZ_CRASH("Not implemented."); + } virtual already_AddRefed CreateBorderLayer() { MOZ_CRASH("Not implemented."); } diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 66d9664e6755..0f11db282ecc 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -548,6 +548,7 @@ private: DECL_OVERRIDE_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, gfxPrefs::OverrideBase_WebRender()); DECL_GFX_PREF(Live, "layers.advanced.solid-color", LayersAllowSolidColorLayers, bool, false); DECL_GFX_PREF(Live, "layers.advanced.table", LayersAllowTable, bool, false); + DECL_OVERRIDE_PREF(Live, "layers.advanced.text-layers", LayersAllowTextLayers, gfxPrefs::OverrideBase_WebRender()); DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled", LayersAMDSwitchableGfxEnabled, bool, false); DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled", AsyncPanZoomEnabledDoNotUseDirectly, bool, true); DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false); diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index bb9a0512bdf4..4ce7f884bb18 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -298,6 +298,10 @@ nsDisplayTextOverflowMarker::CreateWebRenderCommands(mozilla::wr::DisplayListBui layers::WebRenderLayerManager* aManager, nsDisplayListBuilder* aDisplayListBuilder) { + if (!gfxPrefs::LayersAllowTextLayers()) { + return false; + } + bool snap; nsRect bounds = GetBounds(aDisplayListBuilder, &snap); if (bounds.IsEmpty()) { diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 77f6fb5a97c5..063486b50f23 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -5123,6 +5123,10 @@ nsDisplayText::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder WebRenderLayerManager* aManager, nsDisplayListBuilder* aDisplayListBuilder) { + if (!gfxPrefs::LayersAllowTextLayers()) { + return false; + } + if (mBounds.IsEmpty()) { return true; } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 559ccb91db49..40d08cb9da04 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5829,6 +5829,7 @@ pref("layers.advanced.image-layers", 2); pref("layers.advanced.outline-layers", 2); pref("layers.advanced.solid-color", false); pref("layers.advanced.table", false); +pref("layers.advanced.text-layers", 2); // Enable lowercased response header name pref("dom.xhr.lowercase_header.enabled", false);