зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1722258 - Add FallbackRenderer to replace BasicLayerManager usage. r=miko
Differential Revision: https://phabricator.services.mozilla.com/D120921
This commit is contained in:
Родитель
7cd494afba
Коммит
0c782c8447
|
@ -6441,8 +6441,14 @@ void PresShell::Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
|
|||
bgcolor = NS_ComposeColors(bgcolor, mCanvasBackgroundColor);
|
||||
|
||||
if (!layerManager) {
|
||||
// TODO: Once we support WindowRenderers that aren't a LayerManager,
|
||||
// then we need to handle this single color case for them.
|
||||
FallbackRenderer* fallback = renderer->AsFallback();
|
||||
MOZ_ASSERT(fallback);
|
||||
|
||||
if (aFlags & PaintFlags::PaintComposite) {
|
||||
nsIntRect bounds = presContext->GetVisibleArea().ToOutsidePixels(
|
||||
presContext->AppUnitsPerDevPixel());
|
||||
fallback->EndTransactionWithColor(bounds, ToDeviceColor(bgcolor));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,4 +167,44 @@ void WindowRenderer::UpdatePartialPrerenderedAnimations(
|
|||
}
|
||||
}
|
||||
|
||||
void FallbackRenderer::SetTarget(gfxContext* aTarget,
|
||||
layers::BufferMode aDoubleBuffering) {
|
||||
mTarget = aTarget;
|
||||
mBufferMode = aDoubleBuffering;
|
||||
}
|
||||
|
||||
bool FallbackRenderer::BeginTransaction(const nsCString& aURL) {
|
||||
if (!mTarget) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FallbackRenderer::EndTransactionWithColor(const nsIntRect& aRect,
|
||||
const gfx::DeviceColor& aColor) {
|
||||
mTarget->GetDrawTarget()->FillRect(Rect(aRect), ColorPattern(aColor));
|
||||
}
|
||||
|
||||
void FallbackRenderer::EndTransactionWithList(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList,
|
||||
int32_t aAppUnitsPerDevPixel,
|
||||
EndTransactionFlags aFlags) {
|
||||
if (aFlags & EndTransactionFlags::END_NO_COMPOSITE) {
|
||||
return;
|
||||
}
|
||||
|
||||
DrawTarget* dt = mTarget->GetDrawTarget();
|
||||
|
||||
if (mBufferMode == BufferMode::BUFFERED) {
|
||||
dt->PushLayer(true, 1.0, nullptr, Matrix());
|
||||
}
|
||||
|
||||
aList->Paint(aBuilder, mTarget, aAppUnitsPerDevPixel);
|
||||
|
||||
if (mBufferMode == BufferMode::BUFFERED) {
|
||||
dt->PopLayer();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -24,6 +24,9 @@ class ClientLayerManager;
|
|||
class FrameUniformityData;
|
||||
class PersistentBufferProvider;
|
||||
} // namespace layers
|
||||
class FallbackRenderer;
|
||||
class nsDisplayListBuilder;
|
||||
class nsDisplayList;
|
||||
|
||||
class FrameRecorder {
|
||||
public:
|
||||
|
@ -100,6 +103,7 @@ class WindowRenderer : public FrameRecorder {
|
|||
// Cast to implementation types.
|
||||
virtual layers::LayerManager* AsLayerManager() { return nullptr; }
|
||||
virtual layers::WebRenderLayerManager* AsWebRender() { return nullptr; }
|
||||
virtual FallbackRenderer* AsFallback() { return nullptr; }
|
||||
|
||||
// Required functionality
|
||||
|
||||
|
@ -231,6 +235,49 @@ class WindowRenderer : public FrameRecorder {
|
|||
TimeStamp mAnimationReadyTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* FallbackRenderer is non-retained renderer that acts as a direct wrapper
|
||||
* around calling Paint on the provided DisplayList. This is used for cases
|
||||
* where initializing WebRender is too costly, and we don't need
|
||||
* retaining/invalidation (like small popup windows).
|
||||
*
|
||||
* It doesn't support any sort of EmptyTransaction, and only draws during
|
||||
* EndTransaction if a composite is requested (no END_NO_COMPOSITE flag
|
||||
* provided)
|
||||
*/
|
||||
class FallbackRenderer : public WindowRenderer {
|
||||
public:
|
||||
FallbackRenderer* AsFallback() override { return this; }
|
||||
|
||||
void SetTarget(gfxContext* aContext, layers::BufferMode aDoubleBuffering);
|
||||
|
||||
bool BeginTransaction(const nsCString& aURL = nsCString()) override;
|
||||
|
||||
bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
layers::LayersBackend GetBackendType() override {
|
||||
return layers::LayersBackend::LAYERS_NONE;
|
||||
}
|
||||
|
||||
virtual void GetBackendName(nsAString& name) override {
|
||||
name.AssignLiteral("Fallback");
|
||||
}
|
||||
|
||||
bool IsCompositingCheap() override { return false; }
|
||||
|
||||
void EndTransactionWithColor(const nsIntRect& aRect,
|
||||
const gfx::DeviceColor& aColor);
|
||||
void EndTransactionWithList(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList,
|
||||
int32_t aAppUnitsPerDevPixel,
|
||||
EndTransactionFlags aFlags);
|
||||
|
||||
RefPtr<gfxContext> mTarget;
|
||||
layers::BufferMode mBufferMode;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* MOZILLA_PAINTING_WINDOWRENDERER_H */
|
||||
|
|
|
@ -2477,13 +2477,20 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(
|
|||
if (aFlags & PAINT_USE_WIDGET_LAYERS) {
|
||||
renderer = aBuilder->GetWidgetWindowRenderer(&view);
|
||||
if (renderer) {
|
||||
layerManager = renderer->AsLayerManager();
|
||||
if (layerManager) {
|
||||
layerManager->SetContainsSVG(false);
|
||||
}
|
||||
// The fallback renderer doesn't retain any content, so it's
|
||||
// not meaningful to use it when drawing to an external context.
|
||||
if (aCtx && renderer->AsFallback()) {
|
||||
MOZ_ASSERT(!(aFlags & PAINT_EXISTING_TRANSACTION));
|
||||
renderer = nullptr;
|
||||
} else {
|
||||
layerManager = renderer->AsLayerManager();
|
||||
if (layerManager) {
|
||||
layerManager->SetContainsSVG(false);
|
||||
}
|
||||
|
||||
doBeginTransaction = !(aFlags & PAINT_EXISTING_TRANSACTION);
|
||||
widgetTransaction = true;
|
||||
doBeginTransaction = !(aFlags & PAINT_EXISTING_TRANSACTION);
|
||||
widgetTransaction = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2618,21 +2625,26 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(
|
|||
}
|
||||
|
||||
if (!sent) {
|
||||
const auto start = TimeStamp::Now();
|
||||
if (renderer->AsFallback()) {
|
||||
renderer->AsFallback()->EndTransactionWithList(
|
||||
aBuilder, this, presContext->AppUnitsPerDevPixel(), flags);
|
||||
} else {
|
||||
const auto start = TimeStamp::Now();
|
||||
|
||||
FrameLayerBuilder* layerBuilder =
|
||||
BuildLayers(aBuilder, layerManager, aFlags, widgetTransaction);
|
||||
FrameLayerBuilder* layerBuilder =
|
||||
BuildLayers(aBuilder, layerManager, aFlags, widgetTransaction);
|
||||
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::PAINT_BUILD_LAYERS_TIME, start);
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::PAINT_BUILD_LAYERS_TIME, start);
|
||||
|
||||
if (!layerBuilder) {
|
||||
layerManager->SetUserData(&gLayerManagerLayerBuilder, nullptr);
|
||||
return nullptr;
|
||||
if (!layerBuilder) {
|
||||
layerManager->SetUserData(&gLayerManagerLayerBuilder, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
|
||||
aBuilder, flags);
|
||||
layerBuilder->DidEndTransaction();
|
||||
}
|
||||
|
||||
layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, aBuilder,
|
||||
flags);
|
||||
layerBuilder->DidEndTransaction();
|
||||
}
|
||||
|
||||
if (widgetTransaction ||
|
||||
|
|
|
@ -4782,6 +4782,11 @@
|
|||
value: true
|
||||
mirror: always
|
||||
|
||||
- name: gfx.basic_layer_manager.force_enabled
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# Whether to enable LayerScope tool and default listening port.
|
||||
- name: gfx.layerscope.enabled
|
||||
type: RelaxedAtomicBool
|
||||
|
|
|
@ -1179,6 +1179,13 @@ bool nsWebBrowser::PaintWindow(nsIWidget* aWidget,
|
|||
LayoutDeviceIntRegion aRegion) {
|
||||
WindowRenderer* renderer = aWidget->GetWindowRenderer();
|
||||
NS_ASSERTION(renderer, "Must be in paint event");
|
||||
if (FallbackRenderer* fallback = renderer->AsFallback()) {
|
||||
if (fallback->BeginTransaction()) {
|
||||
fallback->EndTransactionWithColor(aRegion.GetBounds().ToUnknownRect(),
|
||||
ToDeviceColor(mBackgroundColor));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
LayerManager* layerManager = renderer->AsLayerManager();
|
||||
NS_ASSERTION(layerManager, "Must be in paint event");
|
||||
|
||||
|
|
|
@ -592,7 +592,12 @@ WindowRenderer* PuppetWidget::GetWindowRenderer() {
|
|||
// On the parent process there is no CompositorBridgeChild which confuses
|
||||
// some layers code, so we use basic layers instead. Note that we create
|
||||
// a non-retaining layer manager since we don't care about performance.
|
||||
mWindowRenderer = new BasicLayerManager(BasicLayerManager::BLM_OFFSCREEN);
|
||||
if (StaticPrefs::gfx_basic_layer_manager_force_enabled()) {
|
||||
mWindowRenderer =
|
||||
new BasicLayerManager(BasicLayerManager::BLM_OFFSCREEN);
|
||||
} else {
|
||||
mWindowRenderer = new FallbackRenderer;
|
||||
}
|
||||
return mWindowRenderer;
|
||||
}
|
||||
|
||||
|
|
|
@ -1348,7 +1348,8 @@ bool nsChildView::PaintWindowInDrawTarget(gfx::DrawTarget* aDT,
|
|||
targetContext->Clip();
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(mView);
|
||||
if (GetWindowRenderer()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
|
||||
if (GetWindowRenderer()->GetBackendType() == LayersBackend::LAYERS_NONE ||
|
||||
GetWindowRenderer()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
|
||||
nsBaseWidget::AutoLayerManagerSetup setupLayerManager(this, targetContext,
|
||||
BufferMode::BUFFER_NONE);
|
||||
return PaintWindow(aRegion);
|
||||
|
@ -1399,7 +1400,8 @@ void nsChildView::PaintWindowInContentLayer() {
|
|||
void nsChildView::HandleMainThreadCATransaction() {
|
||||
WillPaintWindow();
|
||||
|
||||
if (GetWindowRenderer()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
|
||||
if (GetWindowRenderer()->GetBackendType() == LayersBackend::LAYERS_NONE ||
|
||||
GetWindowRenderer()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
|
||||
// We're in BasicLayers mode, i.e. main thread software compositing.
|
||||
// Composite the window into our layer's surface.
|
||||
PaintWindowInContentLayer();
|
||||
|
|
|
@ -884,6 +884,11 @@ nsBaseWidget::AutoLayerManagerSetup::AutoLayerManagerSetup(
|
|||
nsBaseWidget* aWidget, gfxContext* aTarget, BufferMode aDoubleBuffering)
|
||||
: mWidget(aWidget) {
|
||||
WindowRenderer* renderer = mWidget->GetWindowRenderer();
|
||||
if (renderer->AsFallback()) {
|
||||
mRenderer = renderer->AsFallback();
|
||||
mRenderer->SetTarget(aTarget, aDoubleBuffering);
|
||||
return;
|
||||
}
|
||||
LayerManager* lm = renderer ? renderer->AsLayerManager() : nullptr;
|
||||
NS_ASSERTION(
|
||||
!lm || lm->GetBackendType() == LayersBackend::LAYERS_BASIC,
|
||||
|
@ -904,6 +909,9 @@ nsBaseWidget::AutoLayerManagerSetup::~AutoLayerManagerSetup() {
|
|||
mLayerManager->SetDefaultTargetConfiguration(
|
||||
mozilla::layers::BufferMode::BUFFER_NONE, ROTATION_0);
|
||||
}
|
||||
if (mRenderer) {
|
||||
mRenderer->SetTarget(nullptr, mozilla::layers::BufferMode::BUFFER_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
bool nsBaseWidget::IsSmallPopup() const {
|
||||
|
@ -1525,7 +1533,11 @@ WindowRenderer* nsBaseWidget::GetWindowRenderer() {
|
|||
}
|
||||
|
||||
WindowRenderer* nsBaseWidget::CreateBasicLayerManager() {
|
||||
return new BasicLayerManager(this);
|
||||
if (StaticPrefs::gfx_basic_layer_manager_force_enabled()) {
|
||||
return new BasicLayerManager(this);
|
||||
} else {
|
||||
return new FallbackRenderer;
|
||||
}
|
||||
}
|
||||
|
||||
CompositorBridgeChild* nsBaseWidget::GetRemoteRenderer() {
|
||||
|
|
|
@ -403,6 +403,7 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
|
|||
private:
|
||||
nsBaseWidget* mWidget;
|
||||
RefPtr<BasicLayerManager> mLayerManager;
|
||||
mozilla::FallbackRenderer* mRenderer = nullptr;
|
||||
};
|
||||
friend class AutoLayerManagerSetup;
|
||||
|
||||
|
|
|
@ -270,6 +270,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) {
|
|||
#endif // WIDGET_DEBUG_OUTPUT
|
||||
|
||||
switch (renderer->GetBackendType()) {
|
||||
case LayersBackend::LAYERS_NONE:
|
||||
case LayersBackend::LAYERS_BASIC: {
|
||||
RefPtr<gfxASurface> targetSurface;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче