зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1372118 - Part1. Have a path to create WebRender commands without layers. r=jrmuizel, r=kats, r=mattwoodrow
MozReview-Commit-ID: 7iOW9rEtwur
This commit is contained in:
Родитель
178043d1da
Коммит
de600bafd7
|
@ -20,6 +20,7 @@
|
|||
#include "WebRenderPaintedLayerBlob.h"
|
||||
#include "WebRenderTextLayer.h"
|
||||
#include "WebRenderDisplayItemLayer.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -32,6 +33,7 @@ WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
|
|||
, mLatestTransactionId(0)
|
||||
, mNeedsComposite(false)
|
||||
, mIsFirstPaint(false)
|
||||
, mEndTransactionWithoutLayers(false)
|
||||
, mTarget(nullptr)
|
||||
, mPaintSequenceNumber(0)
|
||||
{
|
||||
|
@ -173,11 +175,81 @@ PopulateScrollData(WebRenderScrollData& aTarget, Layer* aLayer)
|
|||
return descendants + 1;
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
|
||||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
StackingContextHelper& aSc,
|
||||
wr::DisplayListBuilder& aBuilder)
|
||||
{
|
||||
nsDisplayList savedItems;
|
||||
nsDisplayItem* item;
|
||||
while ((item = aDisplayList->RemoveBottom()) != nullptr) {
|
||||
nsDisplayItem::Type itemType = item->GetType();
|
||||
|
||||
// If the item is a event regions item, but is empty (has no regions in it)
|
||||
// then we should just throw it out
|
||||
if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
|
||||
nsDisplayLayerEventRegions* eventRegions =
|
||||
static_cast<nsDisplayLayerEventRegions*>(item);
|
||||
if (eventRegions->IsEmpty()) {
|
||||
item->~nsDisplayItem();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Peek ahead to the next item and try merging with it or swapping with it
|
||||
// if necessary.
|
||||
nsDisplayItem* aboveItem;
|
||||
while ((aboveItem = aDisplayList->GetBottom()) != nullptr) {
|
||||
if (aboveItem->TryMerge(item)) {
|
||||
aDisplayList->RemoveBottom();
|
||||
item->~nsDisplayItem();
|
||||
item = aboveItem;
|
||||
itemType = item->GetType();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nsDisplayList* itemSameCoordinateSystemChildren
|
||||
= item->GetSameCoordinateSystemChildren();
|
||||
if (item->ShouldFlattenAway(aDisplayListBuilder)) {
|
||||
aDisplayList->AppendToBottom(itemSameCoordinateSystemChildren);
|
||||
item->~nsDisplayItem();
|
||||
continue;
|
||||
}
|
||||
|
||||
savedItems.AppendToTop(item);
|
||||
|
||||
if (!item->CreateWebRenderCommands(aBuilder, aSc, mParentCommands, this,
|
||||
aDisplayListBuilder)) {
|
||||
// TODO: fallback
|
||||
}
|
||||
}
|
||||
aDisplayList->AppendToTop(&savedItems);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
|
||||
nsDisplayListBuilder* aDisplayListBuilder)
|
||||
{
|
||||
MOZ_ASSERT(aDisplayList && aDisplayListBuilder);
|
||||
mEndTransactionWithoutLayers = true;
|
||||
DiscardImages();
|
||||
WrBridge()->RemoveExpiredFontKeys();
|
||||
EndTransactionInternal(nullptr,
|
||||
nullptr,
|
||||
EndTransactionFlags::END_DEFAULT,
|
||||
aDisplayList,
|
||||
aDisplayListBuilder);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags)
|
||||
{
|
||||
mEndTransactionWithoutLayers = false;
|
||||
DiscardImages();
|
||||
WrBridge()->RemoveExpiredFontKeys();
|
||||
EndTransactionInternal(aCallback, aCallbackData, aFlags);
|
||||
|
@ -186,7 +258,9 @@ WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
|||
bool
|
||||
WebRenderLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags)
|
||||
EndTransactionFlags aFlags,
|
||||
nsDisplayList* aDisplayList,
|
||||
nsDisplayListBuilder* aDisplayListBuilder)
|
||||
{
|
||||
AutoProfilerTracing tracing("Paint", "RenderLayers");
|
||||
mPaintedLayerCallback = aCallback;
|
||||
|
@ -205,12 +279,29 @@ WebRenderLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback
|
|||
return false;
|
||||
}
|
||||
DiscardCompositorAnimations();
|
||||
mRoot->StartPendingAnimations(mAnimationReadyTime);
|
||||
|
||||
StackingContextHelper sc;
|
||||
WrSize contentSize { (float)size.width, (float)size.height };
|
||||
wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize);
|
||||
WebRenderLayer::ToWebRenderLayer(mRoot)->RenderLayer(builder, sc);
|
||||
|
||||
if (mEndTransactionWithoutLayers) {
|
||||
// aDisplayList being null here means this is an empty transaction following a layers-free
|
||||
// transaction, so we reuse the previously built displaylist.
|
||||
if (aDisplayList && aDisplayListBuilder) {
|
||||
StackingContextHelper sc;
|
||||
mParentCommands.Clear();
|
||||
CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder, sc, builder);
|
||||
builder.Finalize(contentSize, mBuiltDisplayList);
|
||||
}
|
||||
|
||||
builder.PushBuiltDisplayList(mBuiltDisplayList);
|
||||
WrBridge()->AddWebRenderParentCommands(mParentCommands);
|
||||
} else {
|
||||
mRoot->StartPendingAnimations(mAnimationReadyTime);
|
||||
StackingContextHelper sc;
|
||||
|
||||
WebRenderLayer::ToWebRenderLayer(mRoot)->RenderLayer(builder, sc);
|
||||
}
|
||||
|
||||
mWidget->AddWindowOverlayWebRenderCommands(WrBridge(), builder);
|
||||
WrBridge()->ClearReadLocks();
|
||||
|
||||
|
|
|
@ -10,10 +10,13 @@
|
|||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/layers/APZTestData.h"
|
||||
#include "mozilla/layers/FocusTarget.h"
|
||||
#include "mozilla/layers/StackingContextHelper.h"
|
||||
#include "mozilla/layers/TransactionIdAllocator.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
|
||||
class nsIWidget;
|
||||
class nsDisplayList;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -22,6 +25,7 @@ class CompositorBridgeChild;
|
|||
class KnowsCompositor;
|
||||
class PCompositorBridgeChild;
|
||||
class WebRenderBridgeChild;
|
||||
class WebRenderParentCommand;
|
||||
|
||||
class WebRenderLayerManager final : public LayerManager
|
||||
{
|
||||
|
@ -48,6 +52,13 @@ public:
|
|||
virtual bool BeginTransactionWithTarget(gfxContext* aTarget) override;
|
||||
virtual bool BeginTransaction() override;
|
||||
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override;
|
||||
void CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
|
||||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
StackingContextHelper& aSc,
|
||||
wr::DisplayListBuilder& aBuilder);
|
||||
void EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
|
||||
nsDisplayListBuilder* aDisplayListBuilder);
|
||||
bool IsLayersFreeTransaction() { return mEndTransactionWithoutLayers; }
|
||||
virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags = END_DEFAULT) override;
|
||||
|
@ -152,8 +163,9 @@ private:
|
|||
|
||||
bool EndTransactionInternal(DrawPaintedLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags);
|
||||
|
||||
EndTransactionFlags aFlags,
|
||||
nsDisplayList* aDisplayList = nullptr,
|
||||
nsDisplayListBuilder* aDisplayListBuilder = nullptr);
|
||||
|
||||
private:
|
||||
nsIWidget* MOZ_NON_OWNING_REF mWidget;
|
||||
|
@ -174,6 +186,11 @@ private:
|
|||
|
||||
LayerRefArray mKeepAlive;
|
||||
|
||||
// These fields are used to save a copy of the display list for
|
||||
// empty transactions in layers-free mode.
|
||||
wr::BuiltDisplayList mBuiltDisplayList;
|
||||
nsTArray<WebRenderParentCommand> mParentCommands;
|
||||
|
||||
// Layers that have been mutated. If we have an empty transaction
|
||||
// then a display item layer will no longer be valid
|
||||
// if it was a mutated layers.
|
||||
|
@ -185,6 +202,7 @@ private:
|
|||
bool mNeedsComposite;
|
||||
bool mIsFirstPaint;
|
||||
FocusTarget mFocusTarget;
|
||||
bool mEndTransactionWithoutLayers;
|
||||
|
||||
// When we're doing a transaction in order to draw to a non-default
|
||||
// target, the layers transaction is only performed in order to send
|
||||
|
|
|
@ -473,6 +473,7 @@ private:
|
|||
DECL_GFX_PREF(Once, "gfx.vsync.compositor.unobserve-count", CompositorUnobserveCount, int32_t, 10);
|
||||
DECL_OVERRIDE_PREF(Live, "gfx.webrender.omta.enabled", WebRenderOMTAEnabled, gfxPrefs::OverrideBase_WebRender());
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.profiler.enabled", WebRenderProfilerEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.layers-free", WebRenderLayersFree, bool, false);
|
||||
DECL_GFX_PREF(Live, "gfx.webrendest.enabled", WebRendestEnabled, bool, false);
|
||||
// Use vsync events generated by hardware
|
||||
DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs", WorkAroundDriverBugs, bool, true);
|
||||
|
|
|
@ -2092,6 +2092,30 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
|
|||
nsIPresShell* presShell = presContext->PresShell();
|
||||
nsIDocument* document = presShell->GetDocument();
|
||||
|
||||
if (gfxPrefs::WebRenderLayersFree() &&
|
||||
layerManager->GetBackendType() == layers::LayersBackend::LAYERS_WR &&
|
||||
// We don't yet support many display items used in chrome, so
|
||||
// layers-free mode is only for content.
|
||||
!presContext->IsChrome()) {
|
||||
if (doBeginTransaction) {
|
||||
if (aCtx) {
|
||||
if (!layerManager->BeginTransactionWithTarget(aCtx)) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (!layerManager->BeginTransaction()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MaybeSetupTransactionIdAllocator(layerManager, presContext);
|
||||
bool temp = aBuilder->SetIsCompositingCheap(layerManager->IsCompositingCheap());
|
||||
static_cast<WebRenderLayerManager*>(layerManager.get())->EndTransactionWithoutLayer(this, aBuilder);
|
||||
aBuilder->SetIsCompositingCheap(temp);
|
||||
return layerManager.forget();
|
||||
}
|
||||
|
||||
NotifySubDocInvalidationFunc computeInvalidFunc =
|
||||
presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
|
||||
|
||||
|
|
|
@ -1955,10 +1955,16 @@ public:
|
|||
* The layer this item is in is passed in as rects must be relative
|
||||
* to their parent.
|
||||
*/
|
||||
virtual void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
virtual void CreateWebRenderCommand(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
const StackingContextHelper& aSc,
|
||||
nsTArray<WebRenderParentCommand>& aParentCommands,
|
||||
WebRenderDisplayItemLayer* aLayer) {}
|
||||
virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
const StackingContextHelper& aSc,
|
||||
nsTArray<WebRenderParentCommand>& aParentCommands,
|
||||
WebRenderDisplayItemLayer* aLayer) {}
|
||||
mozilla::layers::WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) { return false; }
|
||||
|
||||
/**
|
||||
* Builds a DisplayItemLayer and sets the display item to this.
|
||||
*/
|
||||
|
|
|
@ -4828,6 +4828,7 @@ pref("layers.force-active", false);
|
|||
pref("layers.gralloc.disable", false);
|
||||
|
||||
pref("webrender.highlight-painted-layers", false);
|
||||
pref("gfx.webrender.layers-free", false);
|
||||
|
||||
// Enable/Disable the geolocation API for content
|
||||
pref("geo.enabled", true);
|
||||
|
|
Загрузка…
Ссылка в новой задаче