Bug 884226 - Add 'willReadFrequently' getContext() option for 2D canvas r=ehsan,gwright
authorJames Willcox <snorp@snorp.net>
Fri, 20 Dec 2013 15:50:48 -0600
changeset 171857 48f72b0961062df314af1a1365db7f95330e64fe
parent 171856 0cc9c500afd979eade0c8e426a7c02f22bb7f15f
child 171858 e1d87f9680a028506b3a483166d5f3d59da1d658
push id5166
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:47:54 +0000
treeherdermozilla-aurora@977eb2548b2d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, gwright
bugs884226
milestone29.0a1
Bug 884226 - Add 'willReadFrequently' getContext() option for 2D canvas r=ehsan,gwright
content/canvas/src/CanvasRenderingContext2D.cpp
content/canvas/src/CanvasRenderingContext2D.h
dom/webidl/CanvasRenderingContext2D.webidl
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -1050,16 +1050,36 @@ CanvasRenderingContext2D::Render(gfxCont
       MOZ_ASSERT(gis, "If non-premult alpha, must be able to get image surface!");
 
       gfxUtils::UnpremultiplyImageSurface(gis);
   }
 
   return rv;
 }
 
+NS_IMETHODIMP
+CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions)
+{
+  if (aOptions.isNullOrUndefined()) {
+    return NS_OK;
+  }
+
+  ContextAttributes2D attributes;
+  NS_ENSURE_TRUE(attributes.Init(aCx, aOptions), NS_ERROR_UNEXPECTED);
+
+#ifdef USE_SKIA_GPU
+  if (Preferences::GetBool("gfx.canvas.willReadFrequently.enable", false)) {
+    // Use software when there is going to be a lot of readback
+    mForceSoftware = attributes.mWillReadFrequently;
+  }
+#endif
+
+  return NS_OK;
+}
+
 void
 CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer,
                                          int32_t* aFormat)
 {
   *aImageBuffer = nullptr;
   *aFormat = 0;
 
   EnsureTarget();
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -408,16 +408,17 @@ public:
                                                CanvasLayer *aOldLayer,
                                                LayerManager *aManager) MOZ_OVERRIDE;
   virtual bool ShouldForceInactiveLayer(LayerManager *aManager) MOZ_OVERRIDE;
   void MarkContextClean() MOZ_OVERRIDE;
   NS_IMETHOD SetIsIPC(bool isIPC) MOZ_OVERRIDE;
   // this rect is in canvas device space
   void Redraw(const mozilla::gfx::Rect &r);
   NS_IMETHOD Redraw(const gfxRect &r) MOZ_OVERRIDE { Redraw(ToRect(r)); return NS_OK; }
+  NS_IMETHOD SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions) MOZ_OVERRIDE;
 
   // this rect is in mTarget's current user space
   void RedrawUser(const gfxRect &r);
 
   // nsISupports interface + CC
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(CanvasRenderingContext2D)
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -10,16 +10,21 @@
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 interface HitRegionOptions;
 
 enum CanvasWindingRule { "nonzero", "evenodd" };
 
+dictionary ContextAttributes2D {
+  // whether or not we're planning to do a lot of readback operations
+  boolean willReadFrequently = false;
+};
+
 interface CanvasRenderingContext2D {
 
   // back-reference to the canvas.  Might be null if we're not
   // associated with a canvas.
   readonly attribute HTMLCanvasElement? canvas;
 
   // state
   void save(); // push state on state stack