Bug 1167235 - Part 1: Add code exposing a PersistentBufferProvider. r=nical
authorBas Schouten <bschouten@mozilla.com>
Fri, 19 Jun 2015 01:07:21 +0200
changeset 249684 54ad73e3a027524c74c2deff9bda18b65a9a536b
parent 249683 d1d45ce7cbf53564f5549cf8cf8ce0eca2976cfd
child 249685 a8cc59610b7f0ba610a0bea9401c960afa0f1db1
push id28936
push userryanvm@gmail.com
push dateFri, 19 Jun 2015 20:34:42 +0000
treeherderautoland@c319f262ce3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1167235
milestone41.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 1167235 - Part 1: Add code exposing a PersistentBufferProvider. r=nical
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/PersistentBufferProvider.cpp
gfx/layers/PersistentBufferProvider.h
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/moz.build
gfx/thebes/gfxPlatform.h
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/BaseSize.h"       // for BaseSize
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
 #include "mozilla/layers/Compositor.h"  // for Compositor
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayerManagerComposite.h"  // for LayerComposite
 #include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
 #include "mozilla/layers/LayersMessages.h"  // for TransformFunction, etc
+#include "mozilla/layers/PersistentBufferProvider.h"
 #include "nsAString.h"
 #include "nsCSSValue.h"                 // for nsCSSValue::Array, etc
 #include "nsPrintfCString.h"            // for nsPrintfCString
 #include "nsStyleStruct.h"              // for nsTimingFunction, etc
 #include "protobuf/LayerScopePacket.pb.h"
 
 uint8_t gLayerManagerLayerBuilder;
 
@@ -154,16 +155,37 @@ LayerManager::CreateOptimalMaskDrawTarge
 TemporaryRef<DrawTarget>
 LayerManager::CreateDrawTarget(const IntSize &aSize,
                                SurfaceFormat aFormat)
 {
   return gfxPlatform::GetPlatform()->
     CreateOffscreenCanvasDrawTarget(aSize, aFormat);
 }
 
+TemporaryRef<PersistentBufferProvider>
+LayerManager::CreatePersistentBufferProvider(const mozilla::gfx::IntSize &aSize,
+                                             mozilla::gfx::SurfaceFormat aFormat)
+{
+  RefPtr<PersistentBufferProviderBasic> bufferProvider =
+    new PersistentBufferProviderBasic(this, aSize, aFormat,
+                                      gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
+
+  if (!bufferProvider->IsValid()) {
+    bufferProvider =
+      new PersistentBufferProviderBasic(this, aSize, aFormat,
+                                        gfxPlatform::GetPlatform()->GetFallbackCanvasBackend());
+  }
+
+  if (!bufferProvider->IsValid()) {
+    return nullptr;
+  }
+
+  return bufferProvider.forget();
+}
+
 #ifdef DEBUG
 void
 LayerManager::Mutated(Layer* aLayer)
 {
 }
 #endif  // DEBUG
 
 already_AddRefed<ImageContainer>
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -88,16 +88,17 @@ class ReadbackProcessor;
 class RefLayer;
 class LayerComposite;
 class ShadowableLayer;
 class ShadowLayerForwarder;
 class LayerManagerComposite;
 class SpecificLayerAttributes;
 class Compositor;
 class FrameUniformityData;
+class PersistentBufferProvider;
 
 namespace layerscope {
 class LayersPacket;
 }
 
 #define MOZ_LAYER_DECL_NAME(n, e)                              \
   virtual const char* Name() const override { return n; }  \
   virtual LayerType GetType() const override { return e; }
@@ -476,16 +477,24 @@ public:
   /**
    * Creates a DrawTarget for use with canvas which is optimized for
    * inter-operating with this layermanager.
    */
   virtual TemporaryRef<mozilla::gfx::DrawTarget>
     CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
                      mozilla::gfx::SurfaceFormat aFormat);
 
+  /**
+   * Creates a PersistentBufferProvider for use with canvas which is optimized for
+   * inter-operating with this layermanager.
+   */
+  virtual TemporaryRef<PersistentBufferProvider>
+    CreatePersistentBufferProvider(const mozilla::gfx::IntSize &aSize,
+                                   mozilla::gfx::SurfaceFormat aFormat);
+
   virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) { return true; }
 
   /**
    * returns the maximum texture size on this layer backend, or INT32_MAX
    * if there is no maximum
    */
   virtual int32_t GetMaxTextureSize() const = 0;
 
new file mode 100644
--- /dev/null
+++ b/gfx/layers/PersistentBufferProvider.cpp
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "PersistentBufferProvider.h"
+
+#include "Layers.h"
+#include "mozilla/gfx/Logging.h"
+#include "pratom.h"
+#include "gfxPlatform.h"
+
+namespace mozilla {
+
+using namespace gfx;
+
+namespace layers {
+
+PersistentBufferProviderBasic::PersistentBufferProviderBasic(LayerManager* aManager, gfx::IntSize aSize,
+                                                             gfx::SurfaceFormat aFormat, gfx::BackendType aBackend)
+{
+  mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(aBackend, aSize, aFormat);
+}
+
+}
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/layers/PersistentBufferProvider.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_GFX_PersistentBUFFERPROVIDER_H
+#define MOZILLA_GFX_PersistentBUFFERPROVIDER_H
+
+#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
+#include "mozilla/RefPtr.h"             // for RefPtr, TemporaryRef, etc
+#include "mozilla/layers/LayersTypes.h"
+#include "mozilla/layers/CompositableForwarder.h"
+#include "mozilla/gfx/Types.h"
+
+namespace mozilla {
+namespace layers {
+
+class CopyableCanvasLayer;
+
+/**
+ * A PersistentBufferProvider is for users which require the temporary use of
+ * a DrawTarget to draw into. When they're done drawing they return the
+ * DrawTarget, when they later need to continue drawing they get a DrawTarget
+ * from the provider again, the provider will guarantee the contents of the
+ * previously returned DrawTarget is persisted into the one newly returned.
+ */
+class PersistentBufferProvider : public RefCounted<PersistentBufferProvider>
+{
+public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProvider)
+
+  virtual ~PersistentBufferProvider() { }
+
+  virtual LayersBackend GetType() { return LayersBackend::LAYERS_NONE; }
+
+  /**
+   * Get a DrawTarget from the PersistentBufferProvider.
+   *
+   * \param aPersistedRect This indicates the area of the DrawTarget that needs
+   *                       to have remained the same since the call to
+   *                       ReturnAndUseDT.
+   */
+  virtual gfx::DrawTarget* GetDT(const gfx::IntRect& aPersistedRect) = 0;
+  /**
+   * Return a DrawTarget to the PersistentBufferProvider and indicate the
+   * contents of this DrawTarget is to be considered current by the
+   * BufferProvider
+   */
+  virtual bool ReturnAndUseDT(gfx::DrawTarget* aDT) = 0;
+
+protected:
+  friend class CopyableCanvasLayer;
+
+  virtual TemporaryRef<gfx::SourceSurface> GetSnapshot() = 0;
+};
+
+class PersistentBufferProviderBasic : public PersistentBufferProvider
+{
+public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic)
+
+  PersistentBufferProviderBasic(LayerManager* aManager, gfx::IntSize aSize,
+                                gfx::SurfaceFormat aFormat, gfx::BackendType aBackend);
+
+  bool IsValid() { return !!mDrawTarget; }
+  virtual LayersBackend GetType() { return LayersBackend::LAYERS_BASIC; }
+  gfx::DrawTarget* GetDT(const gfx::IntRect& aPersistedRect) { return mDrawTarget; }
+  bool ReturnAndUseDT(gfx::DrawTarget* aDT) { MOZ_ASSERT(mDrawTarget == aDT); return true; }
+  virtual TemporaryRef<gfx::SourceSurface> GetSnapshot() { return mDrawTarget->Snapshot(); }
+private:
+  RefPtr<gfx::DrawTarget> mDrawTarget;
+};
+
+}
+}
+#endif
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -16,16 +16,17 @@
 #include "mozilla/layers/ContentClient.h"
 #include "mozilla/layers/FrameUniformityData.h"
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/PLayerChild.h"  // for PLayerChild
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/TextureClientPool.h" // for TextureClientPool
+#include "mozilla/layers/PersistentBufferProvider.h"
 #include "ClientReadbackLayer.h"        // for ClientReadbackLayer
 #include "nsAString.h"
 #include "nsIWidgetListener.h"
 #include "nsTArray.h"                   // for AutoInfallibleTArray
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
 #include "TiledLayerBuffer.h"
 #include "mozilla/dom/WindowBinding.h"  // for Overfill Callback
 #include "FrameLayerBuilder.h"          // for FrameLayerbuilder
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -160,16 +160,17 @@ EXPORTS.mozilla.layers += [
     'opengl/CompositingRenderTargetOGL.h',
     'opengl/CompositorOGL.h',
     'opengl/GrallocTextureClient.h',
     'opengl/GrallocTextureHost.h',
     'opengl/MacIOSurfaceTextureClientOGL.h',
     'opengl/MacIOSurfaceTextureHostOGL.h',
     'opengl/TextureClientOGL.h',
     'opengl/TextureHostOGL.h',
+    'PersistentBufferProvider.h',
     'RenderTrace.h',
     'TransactionIdAllocator.h',
     'YCbCrImageDataSerializer.h',
 ]
 
 if CONFIG['MOZ_X11']:
     EXPORTS.mozilla.layers += [
         'basic/TextureClientX11.h',
@@ -329,16 +330,17 @@ UNIFIED_SOURCES += [
     'YCbCrImageDataSerializer.cpp',
 ]
 
 SOURCES += [
     'basic/BasicImageLayer.cpp',
     'ImageContainer.cpp',
     'Layers.cpp',
     'LayerTreeInvalidation.cpp',
+    'PersistentBufferProvider.cpp',
 ]
 
 # Disable RTTI in google protocol buffer
 DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = True
 
 # Workaround compiler bug (Bug 795594)
 if CONFIG['_MSC_VER'] and CONFIG['CPU_ARCH'] == 'x86_64':
     for src in [
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -303,17 +303,19 @@ public:
 
     mozilla::gfx::BackendType GetContentBackend() {
       return mContentBackend;
     }
 
     mozilla::gfx::BackendType GetPreferredCanvasBackend() {
       return mPreferredCanvasBackend;
     }
-
+    mozilla::gfx::BackendType GetFallbackCanvasBackend() {
+      return mFallbackCanvasBackend;
+    }
     /*
      * Font bits
      */
 
     virtual void SetupClusterBoundaries(gfxTextRun *aTextRun, const char16_t *aString);
 
     /**
      * Fill aListOfFonts with the results of querying the list of font names
@@ -633,38 +635,39 @@ public:
     virtual bool SupportsApzWheelInput() const {
       return false;
     }
     virtual bool SupportsApzTouchInput() const {
       return false;
     }
 
     virtual void FlushContentDrawing() {}
+
+    /**
+     * Helper method, creates a draw target for a specific Azure backend.
+     * Used by CreateOffscreenDrawTarget.
+     */
+    mozilla::TemporaryRef<DrawTarget>
+      CreateDrawTargetForBackend(mozilla::gfx::BackendType aBackend,
+                                 const mozilla::gfx::IntSize& aSize,
+                                 mozilla::gfx::SurfaceFormat aFormat);
+
 protected:
     gfxPlatform();
     virtual ~gfxPlatform();
 
     void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], uint32_t &aLen,
                             eFontPrefLang aCharLang, eFontPrefLang aPageLang);
 
     /**
      * Initialized hardware vsync based on each platform.
      */
     virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource();
 
     /**
-     * Helper method, creates a draw target for a specific Azure backend.
-     * Used by CreateOffscreenDrawTarget.
-     */
-    mozilla::TemporaryRef<DrawTarget>
-      CreateDrawTargetForBackend(mozilla::gfx::BackendType aBackend,
-                                 const mozilla::gfx::IntSize& aSize,
-                                 mozilla::gfx::SurfaceFormat aFormat);
-
-    /**
      * Initialise the preferred and fallback canvas backends
      * aBackendBitmask specifies the backends which are acceptable to the caller.
      * The backend used is determined by aBackendBitmask and the order specified
      * by the gfx.canvas.azure.backends pref.
      */
     void InitBackendPrefs(uint32_t aCanvasBitmask, mozilla::gfx::BackendType aCanvasDefault,
                           uint32_t aContentBitmask, mozilla::gfx::BackendType aContentDefault);