Bug 717921. Add UserData to DrawTarget. r=bas
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Fri, 13 Jan 2012 09:47:58 -0500
changeset 85920 d3b761d31434ee736a92969360df0d4a5df9fe5e
parent 85919 f9f62e9293d842233143e9578eaab4b11bd0e161
child 85921 044c107a719f16795f2eeb0fb2605530b6839963
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs717921
milestone12.0a1
Bug 717921. Add UserData to DrawTarget. r=bas * * * Bug 717921. Fix bustage about moz_xrealloc.
gfx/2d/2D.h
gfx/2d/Makefile.in
gfx/2d/UserData.h
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -36,17 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _MOZILLA_GFX_2D_H
 #define _MOZILLA_GFX_2D_H
 
 #include "Point.h"
 #include "Rect.h"
 #include "Matrix.h"
-
+#include "UserData.h"
 // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
 // outparams using the &-operator. But it will have to do as there's no easy
 // solution.
 #include "mozilla/RefPtr.h"
 
 struct _cairo_surface;
 typedef _cairo_surface cairo_surface_t;
 
@@ -739,17 +739,24 @@ public:
 
   SurfaceFormat GetFormat() { return mFormat; }
 
   /* Tries to get a native surface for a DrawTarget, this may fail if the
    * draw target cannot convert to this surface type.
    */
   virtual void *GetNativeSurface(NativeSurfaceType aType) { return NULL; }
 
+  void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
+    mUserData.Add(key, userData, destroy);
+  }
+  void *GetUserData(UserDataKey *key) {
+    return mUserData.Get(key);
+  }
 protected:
+  UserData mUserData;
   Matrix mTransform;
   bool mTransformDirty : 1;
 
   SurfaceFormat mFormat;
 };
 
 class Factory
 {
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -57,16 +57,17 @@ EXPORTS_mozilla/gfx	= \
         BaseRect.h \
         BaseSize.h \
         Blur.h \
         PathHelpers.h \
         Point.h \
         Matrix.h \
         Rect.h \
         Types.h \
+        UserData.h \
 	$(NULL)
 
 CPPSRCS	= \
 	Factory.cpp \
         Matrix.cpp \
         DrawTargetCairo.cpp \
         ScaledFontCairo.cpp \
         SourceSurfaceCairo.cpp \
new file mode 100644
--- /dev/null
+++ b/gfx/2d/UserData.h
@@ -0,0 +1,108 @@
+/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (Sub) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jeff Muizelaar <jmuizelaar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include <stdlib.h>
+#include "mozilla/mozalloc.h"
+
+namespace mozilla {
+namespace gfx {
+
+struct UserDataKey {
+  int unused;
+};
+
+/* this class is basically a clone of the user data concept from cairo */
+class UserData
+{
+  typedef void (*destroyFunc)(void *data);
+public:
+  UserData() : count(0), entries(NULL) {}
+
+  /* Attaches untyped userData associated with key. destroy is called on destruction */
+  void Add(UserDataKey *key, void *userData, destroyFunc destroy)
+  {
+    // We could keep entries in a std::vector instead of managing it by hand
+    // but that would propagate an stl dependency out which we'd rather not
+    // do (see bug 666609). Plus, the entries array is expect to stay small
+    // so doing a realloc everytime we add a new entry shouldn't be too costly
+    entries = static_cast<Entry*>(moz_xrealloc(entries, sizeof(Entry)*(count+1)));
+
+    entries[count].key      = key;
+    entries[count].userData = userData;
+    entries[count].destroy  = destroy;
+
+    count++;
+  }
+
+  //XXX: we probably want to add a way to remove Keys
+
+  /* Retrives the userData for the associated key */
+  void *Get(UserDataKey *key)
+  {
+    for (int i=0; i<count; i++) {
+      if (key == entries[i].key) {
+        return entries[i].userData;
+      }
+    }
+    return NULL;
+  }
+
+  ~UserData()
+  {
+    for (int i=0; i<count; i++) {
+      entries[i].destroy(entries[i].userData);
+    }
+    free(entries);
+  }
+
+private:
+  struct Entry {
+    const UserDataKey *key;
+    void *userData;
+    destroyFunc destroy;
+  };
+
+  int count;
+  Entry *entries;
+
+};
+
+}
+}
+
+