Bug 1368846 - Display the window buttons when webrender is used. r?mattwoodrow, r?kats
MozReview-Commit-ID: Ki4ONGxtzyO
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -91,16 +91,21 @@ public:
uint32_t GetNextResourceId() { return ++mResourceId; }
uint32_t GetNamespace() { return mIdNamespace; }
void SetNamespace(uint32_t aIdNamespace)
{
mIdNamespace = aIdNamespace;
}
+ WrImageKey GetNextImageKey()
+ {
+ return WrImageKey{ GetNamespace(), GetNextResourceId() };
+ }
+
void PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<GlyphArray>& aGlyphs,
gfx::ScaledFont* aFont, const StackingContextHelper& aSc,
const LayerRect& aBounds, const LayerRect& aClip);
wr::FontKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
void RemoveExpiredFontKeys();
void ClearReadLocks();
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -69,16 +69,18 @@ WebRenderLayerManager::Initialize(PCompo
void
WebRenderLayerManager::Destroy()
{
if (IsDestroyed()) {
return;
}
+ mWidget->CleanupWebRenderWindowOverlay(WrBridge());
+
LayerManager::Destroy();
DiscardImages();
DiscardCompositorAnimations();
WrBridge()->Destroy();
if (mTransactionIdAllocator) {
// Make sure to notify the refresh driver just in case it's waiting on a
// pending transaction. Do this at the top of the event loop so we don't
@@ -198,16 +200,17 @@ WebRenderLayerManager::EndTransactionInt
}
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);
+ mWidget->AddWindowOverlayWebRenderCommands(WrBridge(), builder);
WrBridge()->ClearReadLocks();
// We can't finish this transaction so return. This usually
// happens in an empty transaction where we can't repaint a painted layer.
// In this case, leave the transaction open and let a full transaction happen.
if (mTransactionIncomplete) {
DiscardLocalImages();
WrBridge()->ProcessWebRenderParentCommands();
--- a/gfx/webrender_bindings/RendererOGL.cpp
+++ b/gfx/webrender_bindings/RendererOGL.cpp
@@ -116,24 +116,21 @@ RendererOGL::Render()
//#elif defined(MOZ_WIDGET_ANDROID)
// widgetContext.mCompositor = mCompositor;
#endif
if (!mWidget->PreRender(&widgetContext)) {
return false;
}
// XXX set clear color if MOZ_WIDGET_ANDROID is defined.
- // XXX pass the actual render bounds instead of an empty rect.
- mWidget->DrawWindowUnderlay(&widgetContext, LayoutDeviceIntRect());
auto size = mWidget->GetClientSize();
wr_renderer_render(mWrRenderer, size.width, size.height);
mGL->SwapBuffers();
- mWidget->DrawWindowOverlay(&widgetContext, LayoutDeviceIntRect());
mWidget->PostRender(&widgetContext);
// TODO: Flush pending actions such as texture deletions/unlocks and
// textureHosts recycling.
return true;
}
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -19,16 +19,17 @@
#include "TextInputHandler.h"
#include "nsCocoaUtils.h"
#include "gfxQuartzSurface.h"
#include "GLContextTypes.h"
#include "mozilla/Mutex.h"
#include "nsRegion.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/UniquePtr.h"
+#include "mozilla/webrender/WebRenderTypes.h"
#include "nsString.h"
#include "nsIDragService.h"
#include "ViewRegion.h"
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
#import <AppKit/NSOpenGL.h>
@@ -446,16 +447,22 @@ public:
#ifdef ACCESSIBILITY
already_AddRefed<mozilla::a11y::Accessible> GetDocumentAccessible();
#endif
virtual void CreateCompositor() override;
virtual void PrepareWindowEffects() override;
virtual void CleanupWindowEffects() override;
+
+ virtual void AddWindowOverlayWebRenderCommands(mozilla::layers::WebRenderBridgeChild* aWrBridge,
+ mozilla::wr::DisplayListBuilder& aBuilder) override;
+
+ virtual void CleanupWebRenderWindowOverlay(mozilla::layers::WebRenderBridgeChild* aWrBridge) override;
+
virtual bool PreRender(mozilla::widget::WidgetRenderingContext* aContext) override;
virtual void PostRender(mozilla::widget::WidgetRenderingContext* aContext) override;
virtual void DrawWindowOverlay(mozilla::widget::WidgetRenderingContext* aManager,
LayoutDeviceIntRect aRect) override;
virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) override;
virtual void UpdateWindowDraggingRegion(const LayoutDeviceIntRegion& aRegion) override;
@@ -621,16 +628,19 @@ protected:
CGContextRef mTitlebarCGContext;
// Compositor thread only
mozilla::UniquePtr<mozilla::widget::RectTextureImage> mResizerImage;
mozilla::UniquePtr<mozilla::widget::RectTextureImage> mCornerMaskImage;
mozilla::UniquePtr<mozilla::widget::RectTextureImage> mTitlebarImage;
mozilla::UniquePtr<mozilla::widget::RectTextureImage> mBasicCompositorImage;
+ // Main thread + webrender only
+ mozilla::Maybe<mozilla::wr::ImageKey> mTitlebarImageKey;
+
// The area of mTitlebarCGContext that has changed and needs to be
// uploaded to to mTitlebarImage. Main thread only.
nsIntRegion mDirtyTitlebarRegion;
mozilla::ViewRegion mNonDraggableRegion;
// Cached value of [mView backingScaleFactor], to avoid sending two obj-c
// messages (respondsToSelector, backingScaleFactor) every time we need to
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -63,16 +63,18 @@
#include "HeapCopyOfStackArray.h"
#include "mozilla/layers/IAPZCTreeManager.h"
#include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layers/GLManager.h"
#include "mozilla/layers/CompositorOGL.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/BasicCompositor.h"
#include "mozilla/layers/InputAPZContext.h"
+#include "mozilla/layers/WebRenderBridgeChild.h"
+#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/widget/CompositorWidget.h"
#include "gfxUtils.h"
#include "gfxPrefs.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/BorrowedContext.h"
#include "mozilla/gfx/MacIOSurface.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
@@ -2069,16 +2071,62 @@ nsChildView::PrepareWindowEffects()
void
nsChildView::CleanupWindowEffects()
{
mResizerImage = nullptr;
mCornerMaskImage = nullptr;
mTitlebarImage = nullptr;
}
+void
+nsChildView::AddWindowOverlayWebRenderCommands(layers::WebRenderBridgeChild* aWrBridge,
+ wr::DisplayListBuilder& aBuilder)
+{
+ PrepareWindowEffects();
+
+ LayoutDeviceIntRegion updatedTitlebarRegion;
+ updatedTitlebarRegion.And(mUpdatedTitlebarRegion, mTitlebarRect);
+ mUpdatedTitlebarRegion.SetEmpty();
+
+ if (mTitlebarCGContext) {
+ gfx::IntSize size(CGBitmapContextGetWidth(mTitlebarCGContext),
+ CGBitmapContextGetHeight(mTitlebarCGContext));
+ size_t stride = CGBitmapContextGetBytesPerRow(mTitlebarCGContext);
+ size_t titlebarCGContextDataLength = stride * size.height;
+ gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8;
+ wr::ByteBuffer buffer(
+ titlebarCGContextDataLength,
+ static_cast<uint8_t *>(CGBitmapContextGetData(mTitlebarCGContext)));
+
+ if (!mTitlebarImageKey) {
+ mTitlebarImageKey = Some(aWrBridge->GetNextImageKey());
+ aWrBridge->SendAddImage(*mTitlebarImageKey, size, stride, format, buffer);
+ updatedTitlebarRegion.SetEmpty();
+ }
+
+ if (!updatedTitlebarRegion.IsEmpty()) {
+ aWrBridge->SendUpdateImage(*mTitlebarImageKey, size, format, buffer);
+ }
+
+ WrRect rect = wr::ToWrRect(mTitlebarRect);
+ WrClipRegionToken clip = aBuilder.PushClipRegion(rect, nullptr);
+ aBuilder.PushImage(WrRect{ 0, 0, float(size.width), float(size.height) },
+ clip, wr::ImageRendering::Auto, *mTitlebarImageKey);
+ }
+}
+
+void
+nsChildView::CleanupWebRenderWindowOverlay(layers::WebRenderBridgeChild* aWrBridge)
+{
+ if (mTitlebarImageKey) {
+ aWrBridge->SendDeleteImage(*mTitlebarImageKey);
+ mTitlebarImageKey = Nothing();
+ }
+}
+
bool
nsChildView::PreRender(WidgetRenderingContext* aContext)
{
UniquePtr<GLManager> manager(GLManager::CreateGLManager(aContext->mLayerManager));
gl::GLContext* gl = manager ? manager->gl() : aContext->mGL;
if (!gl) {
return true;
}
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -56,28 +56,32 @@ class PluginWidgetChild;
} // namespace plugins
namespace layers {
class AsyncDragMetrics;
class Compositor;
class CompositorBridgeChild;
class LayerManager;
class LayerManagerComposite;
class PLayerTransactionChild;
+class WebRenderBridgeChild;
struct ScrollableLayerGuid;
} // namespace layers
namespace gfx {
class DrawTarget;
class SourceSurface;
} // namespace gfx
namespace widget {
class TextEventDispatcher;
class TextEventDispatcherListener;
class CompositorWidget;
class CompositorWidgetInitData;
} // namespace widget
+namespace wr {
+class DisplayListBuilder;
+} // namespace wr
} // namespace mozilla
/**
* Callback function that processes events.
*
* The argument is actually a subtype (subclass) of WidgetEvent which carries
* platform specific information about the event. Platform specific code
* knows how to deal with it.
@@ -1270,16 +1274,28 @@ class nsIWidget : public nsISupports
* Called before each layer manager transaction to allow any preparation
* for DrawWindowUnderlay/Overlay that needs to be on the main thread.
*
* Always called on the main thread.
*/
virtual void PrepareWindowEffects() = 0;
/**
+ * Called on the main thread at the end of WebRender display list building.
+ */
+ virtual void AddWindowOverlayWebRenderCommands(mozilla::layers::WebRenderBridgeChild* aWrBridge,
+ mozilla::wr::DisplayListBuilder& aBuilder) {}
+
+ /**
+ * Called on the main thread when WebRender resources used for
+ * AddWindowOverlayWebRenderCommands need to be destroyed.
+ */
+ virtual void CleanupWebRenderWindowOverlay(mozilla::layers::WebRenderBridgeChild* aWrBridge) {}
+
+ /**
* Called when Gecko knows which themed widgets exist in this window.
* The passed array contains an entry for every themed widget of the right
* type (currently only NS_THEME_TOOLBAR) within the window, except for
* themed widgets which are transformed or have effects applied to them
* (e.g. CSS opacity or filters).
* This could sometimes be called during display list construction
* outside of painting.
* If called during painting, it will be called before we actually