forked from mirrors/gecko-dev
Backed out 2 changesets (bug 1851777, bug 1851775) for causing multiple failures on CLOSED TREE
Backed out changeset dd328595264f (bug 1851777) Backed out changeset d14be9a2baa6 (bug 1851775)
This commit is contained in:
parent
8707af158b
commit
963c8ec383
1 changed files with 98 additions and 85 deletions
|
|
@ -214,13 +214,13 @@ bool nsWindow::OnPaint(uint32_t aNestingLevel) {
|
|||
}
|
||||
mLastPaintBounds = mBounds;
|
||||
|
||||
const bool isTransparent = mTransparencyMode == TransparencyMode::Transparent;
|
||||
// For layered translucent windows all drawing should go to memory DC and no
|
||||
// WM_PAINT messages are normally generated. To support asynchronous painting
|
||||
// we force generation of WM_PAINT messages by invalidating window areas with
|
||||
// RedrawWindow, InvalidateRect or InvalidateRgn function calls.
|
||||
const bool usingMemoryDC =
|
||||
renderer->GetBackendType() == LayersBackend::LAYERS_NONE && isTransparent;
|
||||
renderer->GetBackendType() == LayersBackend::LAYERS_NONE &&
|
||||
mTransparencyMode == TransparencyMode::Transparent;
|
||||
|
||||
HDC hDC = nullptr;
|
||||
if (usingMemoryDC) {
|
||||
|
|
@ -237,7 +237,7 @@ bool nsWindow::OnPaint(uint32_t aNestingLevel) {
|
|||
hDC = ::BeginPaint(mWnd, &ps);
|
||||
}
|
||||
|
||||
const bool forceRepaint = isTransparent;
|
||||
const bool forceRepaint = mTransparencyMode == TransparencyMode::Transparent;
|
||||
const LayoutDeviceIntRegion region = GetRegionToPaint(forceRepaint, ps, hDC);
|
||||
|
||||
if (knowsCompositor && layerManager) {
|
||||
|
|
@ -249,10 +249,15 @@ bool nsWindow::OnPaint(uint32_t aNestingLevel) {
|
|||
|
||||
RefPtr<nsWindow> strongThis(this);
|
||||
|
||||
if (nsIWidgetListener* listener = GetPaintListener()) {
|
||||
// Note that this might kill the listener.
|
||||
nsIWidgetListener* listener = GetPaintListener();
|
||||
if (listener) {
|
||||
listener->WillPaintWindow(this);
|
||||
}
|
||||
// Re-get the listener since the will paint notification may have killed it.
|
||||
listener = GetPaintListener();
|
||||
if (!listener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (knowsCompositor && layerManager && layerManager->NeedsComposite()) {
|
||||
layerManager->ScheduleComposite(wr::RenderReasons::WIDGET);
|
||||
|
|
@ -260,100 +265,108 @@ bool nsWindow::OnPaint(uint32_t aNestingLevel) {
|
|||
}
|
||||
|
||||
bool result = true;
|
||||
auto endPaint = MakeScopeExit([&] {
|
||||
if (!usingMemoryDC) {
|
||||
::EndPaint(mWnd, &ps);
|
||||
}
|
||||
mLastPaintEndTime = TimeStamp::Now();
|
||||
if (nsIWidgetListener* listener = GetPaintListener()) {
|
||||
listener->DidPaintWindow();
|
||||
}
|
||||
if (aNestingLevel == 0 && ::GetUpdateRect(mWnd, nullptr, false)) {
|
||||
OnPaint(1);
|
||||
}
|
||||
});
|
||||
if (!region.IsEmpty() && listener) {
|
||||
// Should probably pass in a real region here, using GetRandomRgn
|
||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/clipping_4q0e.asp
|
||||
|
||||
if (region.IsEmpty() || !GetWidgetListener()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Should probably pass in a real region here, using GetRandomRgn
|
||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/clipping_4q0e.asp
|
||||
#ifdef WIDGET_DEBUG_OUTPUT
|
||||
debug_DumpPaintEvent(stdout, this, region.ToUnknownRegion(), "noname",
|
||||
(int32_t)mWnd);
|
||||
debug_DumpPaintEvent(stdout, this, region.ToUnknownRegion(), "noname",
|
||||
(int32_t)mWnd);
|
||||
#endif // WIDGET_DEBUG_OUTPUT
|
||||
|
||||
switch (renderer->GetBackendType()) {
|
||||
case LayersBackend::LAYERS_NONE: {
|
||||
RefPtr<gfxASurface> targetSurface;
|
||||
switch (renderer->GetBackendType()) {
|
||||
case LayersBackend::LAYERS_NONE: {
|
||||
RefPtr<gfxASurface> targetSurface;
|
||||
|
||||
// don't support transparency for non-GDI rendering, for now
|
||||
if (isTransparent) {
|
||||
// This mutex needs to be held when EnsureTransparentSurface is
|
||||
// called.
|
||||
MutexAutoLock lock(mBasicLayersSurface->GetTransparentSurfaceLock());
|
||||
targetSurface = mBasicLayersSurface->EnsureTransparentSurface();
|
||||
}
|
||||
// don't support transparency for non-GDI rendering, for now
|
||||
if (TransparencyMode::Transparent == mTransparencyMode) {
|
||||
// This mutex needs to be held when EnsureTransparentSurface is
|
||||
// called.
|
||||
MutexAutoLock lock(mBasicLayersSurface->GetTransparentSurfaceLock());
|
||||
targetSurface = mBasicLayersSurface->EnsureTransparentSurface();
|
||||
}
|
||||
|
||||
RefPtr<gfxWindowsSurface> targetSurfaceWin;
|
||||
if (!targetSurface) {
|
||||
uint32_t flags =
|
||||
isTransparent ? gfxWindowsSurface::FLAG_IS_TRANSPARENT : 0;
|
||||
targetSurfaceWin = new gfxWindowsSurface(hDC, flags);
|
||||
targetSurface = targetSurfaceWin;
|
||||
}
|
||||
RefPtr<gfxWindowsSurface> targetSurfaceWin;
|
||||
if (!targetSurface) {
|
||||
uint32_t flags = (mTransparencyMode == TransparencyMode::Opaque)
|
||||
? 0
|
||||
: gfxWindowsSurface::FLAG_IS_TRANSPARENT;
|
||||
targetSurfaceWin = new gfxWindowsSurface(hDC, flags);
|
||||
targetSurface = targetSurfaceWin;
|
||||
}
|
||||
|
||||
RECT paintRect;
|
||||
::GetClientRect(mWnd, &paintRect);
|
||||
RefPtr<DrawTarget> dt = gfxPlatform::CreateDrawTargetForSurface(
|
||||
targetSurface, IntSize(paintRect.right - paintRect.left,
|
||||
paintRect.bottom - paintRect.top));
|
||||
if (!dt || !dt->IsValid()) {
|
||||
gfxWarning()
|
||||
<< "nsWindow::OnPaint failed in CreateDrawTargetForSurface";
|
||||
return false;
|
||||
}
|
||||
if (!targetSurface) {
|
||||
NS_ERROR("Invalid RenderMode!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't need to double buffer with anything but GDI
|
||||
const auto doubleBuffering =
|
||||
isTransparent ? BufferMode::BUFFER_NONE : BufferMode::BUFFERED;
|
||||
if (isTransparent) {
|
||||
// If we're rendering with translucency, we're going to be
|
||||
// rendering the whole window; make sure we clear it first
|
||||
dt->ClearRect(Rect(dt->GetRect()));
|
||||
}
|
||||
RECT paintRect;
|
||||
::GetClientRect(mWnd, &paintRect);
|
||||
RefPtr<DrawTarget> dt = gfxPlatform::CreateDrawTargetForSurface(
|
||||
targetSurface, IntSize(paintRect.right - paintRect.left,
|
||||
paintRect.bottom - paintRect.top));
|
||||
if (!dt || !dt->IsValid()) {
|
||||
gfxWarning()
|
||||
<< "nsWindow::OnPaint failed in CreateDrawTargetForSurface";
|
||||
return false;
|
||||
}
|
||||
|
||||
gfxContext thebesContext(dt);
|
||||
// don't need to double buffer with anything but GDI
|
||||
BufferMode doubleBuffering = mozilla::layers::BufferMode::BUFFER_NONE;
|
||||
switch (mTransparencyMode) {
|
||||
case TransparencyMode::Transparent:
|
||||
// If we're rendering with translucency, we're going to be
|
||||
// rendering the whole window; make sure we clear it first
|
||||
dt->ClearRect(
|
||||
Rect(0.f, 0.f, dt->GetSize().width, dt->GetSize().height));
|
||||
break;
|
||||
default:
|
||||
// If we're not doing translucency, then double buffer
|
||||
doubleBuffering = mozilla::layers::BufferMode::BUFFERED;
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
AutoLayerManagerSetup setupLayerManager(this, &thebesContext,
|
||||
doubleBuffering);
|
||||
if (nsIWidgetListener* listener = GetWidgetListener()) {
|
||||
gfxContext thebesContext(dt);
|
||||
|
||||
{
|
||||
AutoLayerManagerSetup setupLayerManager(this, &thebesContext,
|
||||
doubleBuffering);
|
||||
result = listener->PaintWindow(this, region);
|
||||
}
|
||||
}
|
||||
|
||||
if (isTransparent) {
|
||||
// Data from offscreen drawing surface was copied to memory bitmap of
|
||||
// transparent bitmap. Now it can be read from memory bitmap to apply
|
||||
// alpha channel and after that displayed on the screen.
|
||||
mBasicLayersSurface->RedrawTransparentWindow();
|
||||
}
|
||||
} break;
|
||||
case LayersBackend::LAYERS_WR: {
|
||||
if (nsIWidgetListener* listener = GetWidgetListener()) {
|
||||
if (TransparencyMode::Transparent == mTransparencyMode) {
|
||||
// Data from offscreen drawing surface was copied to memory bitmap of
|
||||
// transparent bitmap. Now it can be read from memory bitmap to apply
|
||||
// alpha channel and after that displayed on the screen.
|
||||
mBasicLayersSurface->RedrawTransparentWindow();
|
||||
}
|
||||
} break;
|
||||
case LayersBackend::LAYERS_WR: {
|
||||
result = listener->PaintWindow(this, region);
|
||||
}
|
||||
if (!gfxEnv::MOZ_DISABLE_FORCE_PRESENT()) {
|
||||
nsCOMPtr<nsIRunnable> event = NewRunnableMethod(
|
||||
"nsWindow::ForcePresent", this, &nsWindow::ForcePresent);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
NS_ERROR("Unknown layers backend used!");
|
||||
break;
|
||||
if (!gfxEnv::MOZ_DISABLE_FORCE_PRESENT()) {
|
||||
nsCOMPtr<nsIRunnable> event = NewRunnableMethod(
|
||||
"nsWindow::ForcePresent", this, &nsWindow::ForcePresent);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
NS_ERROR("Unknown layers backend used!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!usingMemoryDC) {
|
||||
::EndPaint(mWnd, &ps);
|
||||
}
|
||||
|
||||
mLastPaintEndTime = TimeStamp::Now();
|
||||
|
||||
// Re-get the listener since painting may have killed it.
|
||||
listener = GetPaintListener();
|
||||
if (listener) listener->DidPaintWindow();
|
||||
|
||||
if (aNestingLevel == 0 && ::GetUpdateRect(mWnd, nullptr, false)) {
|
||||
OnPaint(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
|||
Loading…
Reference in a new issue