mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
Bug 1926862 - Add transparency support to RenderCompositorANGLE. r=gfx-reviewers,nical
Bring back some of the code from https://hg.mozilla.org/mozilla-central/rev/5942e11048ea to achieve this. Partial present seems to work fine, so we can just keep it working. Differential Revision: https://phabricator.services.mozilla.com/D226886
This commit is contained in:
parent
db0d30dc7c
commit
7e6a74492c
@ -226,6 +226,7 @@ bool RenderCompositorANGLE::CreateSwapChain(nsACString& aError) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool alpha = ShouldUseAlpha();
|
||||
if (!mSwapChain && dxgiFactory2) {
|
||||
RefPtr<IDXGISwapChain1> swapChain1;
|
||||
bool useTripleBuffering = false;
|
||||
@ -237,7 +238,6 @@ bool RenderCompositorANGLE::CreateSwapChain(nsACString& aError) {
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
|
||||
bool useFlipSequential = gfx::gfxVars::UseWebRenderFlipSequentialWin();
|
||||
if (useFlipSequential && !mWidget->AsWindows()->GetCompositorHwnd()) {
|
||||
useFlipSequential = false;
|
||||
@ -258,6 +258,8 @@ bool RenderCompositorANGLE::CreateSwapChain(nsACString& aError) {
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
|
||||
desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
}
|
||||
desc.AlphaMode =
|
||||
alpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE;
|
||||
desc.Flags = 0;
|
||||
|
||||
hr = dxgiFactory2->CreateSwapChainForHwnd(
|
||||
@ -268,6 +270,7 @@ bool RenderCompositorANGLE::CreateSwapChain(nsACString& aError) {
|
||||
mSwapChain = swapChain1;
|
||||
mSwapChain1 = swapChain1;
|
||||
mUseTripleBuffering = useTripleBuffering;
|
||||
mSwapChainUsingAlpha = alpha;
|
||||
} else if (useFlipSequential) {
|
||||
gfxCriticalNoteOnce << "FLIP_SEQUENTIAL is not supported. Fallback";
|
||||
}
|
||||
@ -307,7 +310,7 @@ bool RenderCompositorANGLE::CreateSwapChain(nsACString& aError) {
|
||||
hr = mSwapChain->QueryInterface(
|
||||
(IDXGISwapChain1**)getter_AddRefs(swapChain1));
|
||||
if (SUCCEEDED(hr)) {
|
||||
mSwapChain1 = swapChain1;
|
||||
mSwapChain1 = std::move(swapChain1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,7 +344,7 @@ void RenderCompositorANGLE::CreateSwapChainForDCompIfPossible(
|
||||
|
||||
// When compositor is enabled, CompositionSurface is used for rendering.
|
||||
// It does not support triple buffering.
|
||||
bool useTripleBuffering =
|
||||
const bool useTripleBuffering =
|
||||
gfx::gfxVars::UseWebRenderTripleBufferingWin() && !UseCompositor();
|
||||
RefPtr<IDXGISwapChain1> swapChain1 =
|
||||
CreateSwapChainForDComp(useTripleBuffering);
|
||||
@ -396,7 +399,10 @@ RefPtr<IDXGISwapChain1> RenderCompositorANGLE::CreateSwapChainForDComp(
|
||||
// DXGI_SCALING_NONE caused swap chain creation failure.
|
||||
desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||
const bool alpha = ShouldUseAlpha();
|
||||
// See if we need to use transparency.
|
||||
desc.AlphaMode =
|
||||
alpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE;
|
||||
desc.Flags = 0;
|
||||
|
||||
hr = dxgiFactory2->CreateSwapChainForComposition(mDevice, &desc, nullptr,
|
||||
@ -404,17 +410,30 @@ RefPtr<IDXGISwapChain1> RenderCompositorANGLE::CreateSwapChainForDComp(
|
||||
if (SUCCEEDED(hr) && swapChain1) {
|
||||
DXGI_RGBA color = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
swapChain1->SetBackgroundColor(&color);
|
||||
mSwapChainUsingAlpha = alpha;
|
||||
return swapChain1;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool RenderCompositorANGLE::ShouldUseAlpha() const {
|
||||
return mWidget->AsWindows()->TransparencyModeIs(
|
||||
widget::TransparencyMode::Transparent);
|
||||
}
|
||||
|
||||
bool RenderCompositorANGLE::BeginFrame() {
|
||||
mWidget->AsWindows()->UpdateCompositorWndSizeIfNecessary();
|
||||
|
||||
if (!UseCompositor() && !ResizeBufferIfNeeded()) {
|
||||
return false;
|
||||
if (!UseCompositor()) {
|
||||
if (!mSwapChainUsingAlpha && ShouldUseAlpha()) {
|
||||
if (!RecreateNonNativeCompositorSwapChain()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!ResizeBufferIfNeeded()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MakeCurrent()) {
|
||||
@ -788,15 +807,9 @@ gfx::DeviceResetReason RenderCompositorANGLE::IsContextLost(bool aForce) {
|
||||
return layers::DXGIErrorToDeviceResetReason(reason);
|
||||
}
|
||||
|
||||
bool RenderCompositorANGLE::UseCompositor() {
|
||||
if (!mUseNativeCompositor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mDCLayerTree || !gfx::gfxVars::UseWebRenderCompositor()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
bool RenderCompositorANGLE::UseCompositor() const {
|
||||
return mUseNativeCompositor && mDCLayerTree &&
|
||||
gfx::gfxVars::UseWebRenderCompositor();
|
||||
}
|
||||
|
||||
bool RenderCompositorANGLE::SupportAsyncScreenshot() {
|
||||
@ -887,21 +900,30 @@ void RenderCompositorANGLE::EnableNativeCompositor(bool aEnable) {
|
||||
mUseNativeCompositor = false;
|
||||
mDCLayerTree->DisableNativeCompositor();
|
||||
|
||||
if (!RecreateNonNativeCompositorSwapChain()) {
|
||||
gfxCriticalNote << "Failed to re-create SwapChain";
|
||||
RenderThread::Get()->HandleWebRenderError(WebRenderError::NEW_SURFACE);
|
||||
return;
|
||||
}
|
||||
|
||||
mDisablingNativeCompositor = true;
|
||||
}
|
||||
|
||||
bool RenderCompositorANGLE::RecreateNonNativeCompositorSwapChain() {
|
||||
DestroyEGLSurface();
|
||||
mBufferSize.reset();
|
||||
|
||||
RefPtr<IDXGISwapChain1> swapChain1 =
|
||||
CreateSwapChainForDComp(mUseTripleBuffering);
|
||||
if (swapChain1) {
|
||||
mSwapChain = swapChain1;
|
||||
mDCLayerTree->SetDefaultSwapChain(swapChain1);
|
||||
ResizeBufferIfNeeded();
|
||||
} else {
|
||||
gfxCriticalNote << "Failed to re-create SwapChain";
|
||||
RenderThread::Get()->HandleWebRenderError(WebRenderError::NEW_SURFACE);
|
||||
return;
|
||||
if (!swapChain1) {
|
||||
return false;
|
||||
}
|
||||
mDisablingNativeCompositor = true;
|
||||
mSwapChain = swapChain1;
|
||||
mSwapChain1 = swapChain1;
|
||||
if (mDCLayerTree) {
|
||||
mDCLayerTree->SetDefaultSwapChain(swapChain1);
|
||||
}
|
||||
return ResizeBufferIfNeeded();
|
||||
}
|
||||
|
||||
void RenderCompositorANGLE::InitializeUsePartialPresent() {
|
||||
|
@ -30,7 +30,7 @@ namespace wr {
|
||||
|
||||
class DCLayerTree;
|
||||
|
||||
class RenderCompositorANGLE : public RenderCompositor {
|
||||
class RenderCompositorANGLE final : public RenderCompositor {
|
||||
public:
|
||||
static UniquePtr<RenderCompositor> Create(
|
||||
const RefPtr<widget::CompositorWidget>& aWidget, nsACString& aError);
|
||||
@ -110,7 +110,8 @@ class RenderCompositorANGLE : public RenderCompositor {
|
||||
bool* aNeedsYFlip) override;
|
||||
|
||||
protected:
|
||||
bool UseCompositor();
|
||||
bool UseCompositor() const;
|
||||
bool RecreateNonNativeCompositorSwapChain();
|
||||
void InitializeUsePartialPresent();
|
||||
void InsertGraphicsCommandsFinishedWaitQuery(
|
||||
RenderedFrameId aRenderedFrameId);
|
||||
@ -125,6 +126,7 @@ class RenderCompositorANGLE : public RenderCompositor {
|
||||
RefPtr<ID3D11Query> GetD3D11Query();
|
||||
void ReleaseNativeCompositorResources();
|
||||
HWND GetCompositorHwnd();
|
||||
bool ShouldUseAlpha() const;
|
||||
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
|
||||
@ -152,6 +154,8 @@ class RenderCompositorANGLE : public RenderCompositor {
|
||||
// Used to know a timing of disabling native compositor.
|
||||
bool mDisablingNativeCompositor = false;
|
||||
bool mFirstPresent = true;
|
||||
// Wether we're currently using alpha.
|
||||
bool mSwapChainUsingAlpha = false;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
|
@ -66,6 +66,10 @@ void CompositorWidgetChild::NotifyVisibilityUpdated(bool aIsFullyOccluded) {
|
||||
Unused << SendNotifyVisibilityUpdated(aIsFullyOccluded);
|
||||
};
|
||||
|
||||
void CompositorWidgetChild::UpdateTransparency(TransparencyMode aMode) {
|
||||
Unused << SendUpdateTransparency(aMode);
|
||||
}
|
||||
|
||||
void CompositorWidgetChild::ClearTransparentWindow() {
|
||||
Unused << SendClearTransparentWindow();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class CompositorWidgetChild final : public PCompositorWidgetChild,
|
||||
bool OnWindowResize(const LayoutDeviceIntSize& aSize) override;
|
||||
void NotifyVisibilityUpdated(bool aIsFullyOccluded) override;
|
||||
|
||||
void UpdateTransparency(TransparencyMode) override {}
|
||||
void UpdateTransparency(TransparencyMode) override;
|
||||
void ClearTransparentWindow() override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvObserveVsync() override;
|
||||
|
@ -138,6 +138,12 @@ bool CompositorWidgetParent::GetWindowIsFullyOccluded() const {
|
||||
return mIsFullyOccluded;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CompositorWidgetParent::RecvUpdateTransparency(
|
||||
const TransparencyMode& aMode) {
|
||||
SetTransparencyMode(aMode);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CompositorWidgetParent::RecvClearTransparentWindow() {
|
||||
gfx::CriticalSectionAutoEnter lock(&mPresentLock);
|
||||
|
||||
|
@ -53,6 +53,8 @@ class CompositorWidgetParent final : public PCompositorWidgetParent,
|
||||
mozilla::ipc::IPCResult RecvLeavePresentLock() override;
|
||||
mozilla::ipc::IPCResult RecvNotifyVisibilityUpdated(
|
||||
const bool& aIsFullyOccluded) override;
|
||||
mozilla::ipc::IPCResult RecvUpdateTransparency(
|
||||
const TransparencyMode& aTransparencyMode) override;
|
||||
mozilla::ipc::IPCResult RecvClearTransparentWindow() override;
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
@ -73,9 +75,6 @@ class CompositorWidgetParent final : public PCompositorWidgetParent,
|
||||
|
||||
gfx::CriticalSection mPresentLock;
|
||||
|
||||
// Transparency handling.
|
||||
mozilla::Atomic<uint32_t, MemoryOrdering::Relaxed> mTransparencyMode;
|
||||
|
||||
// Visibility handling.
|
||||
mozilla::Atomic<nsSizeMode, MemoryOrdering::Relaxed> mSizeMode;
|
||||
mozilla::Atomic<bool, MemoryOrdering::Relaxed> mIsFullyOccluded;
|
||||
|
@ -51,7 +51,6 @@ InProcessWinCompositorWidget::InProcessWinCompositorWidget(
|
||||
mWindow(aWindow),
|
||||
mWnd(reinterpret_cast<HWND>(aInitData.hWnd())),
|
||||
mTransparentSurfaceLock("mTransparentSurfaceLock"),
|
||||
mTransparencyMode(uint32_t(aInitData.transparencyMode())),
|
||||
mMemoryDC(nullptr),
|
||||
mCompositeDC(nullptr),
|
||||
mLockedBackBufferData(nullptr) {
|
||||
@ -265,7 +264,7 @@ void InProcessWinCompositorWidget::UpdateTransparency(TransparencyMode aMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTransparencyMode = uint32_t(aMode);
|
||||
SetTransparencyMode(aMode);
|
||||
mTransparentSurface = nullptr;
|
||||
mMemoryDC = nullptr;
|
||||
|
||||
|
@ -83,11 +83,6 @@ class InProcessWinCompositorWidget final
|
||||
|
||||
// Transparency handling.
|
||||
mozilla::Mutex mTransparentSurfaceLock MOZ_UNANNOTATED;
|
||||
mozilla::Atomic<uint32_t, MemoryOrdering::Relaxed> mTransparencyMode;
|
||||
|
||||
bool TransparencyModeIs(TransparencyMode aMode) const {
|
||||
return TransparencyMode(uint32_t(mTransparencyMode)) == aMode;
|
||||
}
|
||||
|
||||
// Visibility handling.
|
||||
mozilla::Atomic<bool, MemoryOrdering::Relaxed> mIsFullyOccluded;
|
||||
|
@ -34,6 +34,7 @@ parent:
|
||||
sync EnterPresentLock();
|
||||
sync LeavePresentLock();
|
||||
async NotifyVisibilityUpdated(bool aIsFullyOccluded);
|
||||
async UpdateTransparency(TransparencyMode aMode);
|
||||
sync ClearTransparentWindow();
|
||||
async __delete__();
|
||||
|
||||
|
@ -32,6 +32,7 @@ WinCompositorWidget::WinCompositorWidget(
|
||||
mSetParentCompleted(false),
|
||||
mWidgetKey(aInitData.widgetKey()),
|
||||
mWnd(reinterpret_cast<HWND>(aInitData.hWnd())),
|
||||
mTransparencyMode(uint32_t(aInitData.transparencyMode())),
|
||||
mCompositorWnds(nullptr, nullptr) {
|
||||
MOZ_ASSERT(mWnd && ::IsWindow(mWnd));
|
||||
}
|
||||
|
@ -80,13 +80,21 @@ class WinCompositorWidget : public CompositorWidget {
|
||||
const HWND aParentWnd) = 0;
|
||||
virtual void SetRootLayerTreeID(const layers::LayersId& aRootLayerTreeId) = 0;
|
||||
|
||||
bool TransparencyModeIs(TransparencyMode aMode) const {
|
||||
return TransparencyMode(uint32_t(mTransparencyMode)) == aMode;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool mSetParentCompleted;
|
||||
void SetTransparencyMode(TransparencyMode aMode) {
|
||||
mTransparencyMode = uint32_t(aMode);
|
||||
}
|
||||
|
||||
bool mSetParentCompleted = false;
|
||||
|
||||
private:
|
||||
uintptr_t mWidgetKey;
|
||||
HWND mWnd;
|
||||
|
||||
mozilla::Atomic<uint32_t, MemoryOrdering::Relaxed> mTransparencyMode;
|
||||
WinCompositorWnds mCompositorWnds;
|
||||
LayoutDeviceIntSize mLastCompositorWndSize;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user