Bug 1548484 - respect Cairo blit size limits when using BasicCompositor. r=mattwoodrow
authorLee Salzman <lsalzman@mozilla.com>
Fri, 10 May 2019 03:00:34 +0000
changeset 535225 1df96f5e640231e8ddbc8ed1dadaef69b55d4e62
parent 535224 919f1307f466e0d747bcc5cc40947ddfb0d7662e
child 535226 82c216e530eaaa56d5b59f95542f6835465241ff
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1548484
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1548484 - respect Cairo blit size limits when using BasicCompositor. r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D30571
gfx/2d/DrawTargetCairo.h
gfx/layers/basic/BasicCompositor.cpp
widget/gtk/nsWindow.cpp
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -169,17 +169,17 @@ class DrawTargetCairo final : public Dra
   // Call to set up aContext for drawing (with the current transform, etc).
   // Pass the path you're going to be using if you have one.
   // Implicitly calls WillChange(aPath).
   void PrepareForDrawing(cairo_t* aContext, const Path* aPath = nullptr);
 
   static cairo_surface_t* GetDummySurface();
 
   // Cairo hardcodes this as its maximum surface size.
-  static size_t GetMaxSurfaceSize() { return 32767; }
+  static size_t GetMaxSurfaceSize() { return 32766; }
 
  private:  // methods
   // Init cairo surface without doing a cairo_surface_reference() call.
   bool InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize,
                              SurfaceFormat* aFormat = nullptr);
   enum DrawPatternType { DRAW_FILL, DRAW_STROKE };
   void DrawPattern(const Pattern& aPattern, const StrokeOptions& aStrokeOptions,
                    const DrawOptions& aOptions, DrawPatternType aDrawType,
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -213,17 +213,24 @@ bool BasicAsyncReadbackBuffer::MapAndCop
 
 BasicCompositor::BasicCompositor(CompositorBridgeParent* aParent,
                                  widget::CompositorWidget* aWidget)
     : Compositor(aWidget, aParent),
       mIsPendingEndRemoteDrawing(false),
       mFullWindowRenderTarget(nullptr) {
   MOZ_COUNT_CTOR(BasicCompositor);
 
-  mMaxTextureSize = Factory::GetMaxSurfaceSize(gfxVars::ContentBackend());
+  // The widget backends may create intermediate Cairo surfaces to deal with
+  // various window buffers, regardless of actual content backend type, when
+  // using the basic compositor. Ensure that the buffers will be able to fit
+  // in or blit with a Cairo surface.
+  mMaxTextureSize =
+      std::min(Factory::GetMaxSurfaceSize(gfxVars::ContentBackend()),
+               Factory::GetMaxSurfaceSize(BackendType::CAIRO));
+
 }
 
 BasicCompositor::~BasicCompositor() { MOZ_COUNT_DTOR(BasicCompositor); }
 
 bool BasicCompositor::Initialize(nsCString* const out_failureReason) {
   return mWidget ? mWidget->InitCompositor(this) : false;
 };
 
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -112,16 +112,17 @@ using namespace mozilla::widget;
 #include "gfxUtils.h"
 #include "Layers.h"
 #include "GLContextProvider.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/HelpersCairo.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
+#include "mozilla/layers/KnowsCompositor.h"
 
 #ifdef MOZ_X11
 #  include "GLContextGLX.h"  // for GLContextGLX::FindVisual()
 #  include "GtkCompositorWidget.h"
 #  include "gfxXlibSurface.h"
 #  include "WindowSurfaceX11Image.h"
 #  include "WindowSurfaceX11SHM.h"
 #  include "WindowSurfaceXRender.h"
@@ -4231,23 +4232,28 @@ void nsWindow::SetHasMappedToplevel(bool
   }
 }
 
 LayoutDeviceIntSize nsWindow::GetSafeWindowSize(LayoutDeviceIntSize aSize) {
   // The X protocol uses CARD32 for window sizes, but the server (1.11.3)
   // reads it as CARD16.  Sizes of pixmaps, used for drawing, are (unsigned)
   // CARD16 in the protocol, but the server's ProcCreatePixmap returns
   // BadAlloc if dimensions cannot be represented by signed shorts.
+  // Because we are creating Cairo surfaces to represent window buffers,
+  // we also must ensure that the window can fit in a Cairo surface.
   LayoutDeviceIntSize result = aSize;
-  const int32_t kInt16Max = 32767;
-  if (result.width > kInt16Max) {
-    result.width = kInt16Max;
-  }
-  if (result.height > kInt16Max) {
-    result.height = kInt16Max;
+  int32_t maxSize = 32767;
+  if (mLayerManager && mLayerManager->AsKnowsCompositor()) {
+    maxSize = std::min(maxSize, mLayerManager->AsKnowsCompositor()->GetMaxTextureSize());
+  }
+  if (result.width > maxSize) {
+    result.width = maxSize;
+  }
+  if (result.height > maxSize) {
+    result.height = maxSize;
   }
   return result;
 }
 
 void nsWindow::EnsureGrabs(void) {
   if (mRetryPointerGrab) GrabPointer(sRetryGrabTime);
 }