Fix alignment issues with stack allocated memory allocated as bytes but used to hold...
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 20 Apr 2011 15:47:04 +0000 (15:47 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 20 Apr 2011 15:47:04 +0000 (15:47 +0000)
Review URL: http://codereview.appspot.com/4435060/

git-svn-id: http://skia.googlecode.com/svn/trunk@1162 2bbb7eff-a529-9590-31e7-b0007b416f81

gpu/include/GrAllocator.h
gpu/include/GrClip.h
gpu/include/GrInOrderDrawBuffer.h
gpu/include/GrTArray.h
gpu/include/GrTemplates.h [new file with mode: 0644]
gpu/include/GrTypes.h
gpu/src/GrClip.cpp
gpu/src/GrInOrderDrawBuffer.cpp

index da02ba4..28a18bf 100755 (executable)
@@ -135,12 +135,12 @@ private:
     static const uint32_t NUM_INIT_BLOCK_PTRS = 8;
     
     GrTArray<void*> fBlocks;
-    size_t          fBlockSize;    
-    char            fBlockInitialStorage[NUM_INIT_BLOCK_PTRS*sizeof(void*)];    
+    size_t          fBlockSize;
+    char            fBlockInitialStorage[NUM_INIT_BLOCK_PTRS*sizeof(void*)];
     size_t          fItemSize;
     uint32_t        fItemsPerBlock;
     bool            fOwnFirstBlock;
-    uint32_t        fCount;    
+    uint32_t        fCount;
 };
 
 template <typename T>
@@ -150,7 +150,7 @@ private:
     
 public:
     virtual ~GrTAllocator() {};
-    
+
     /**
      * Create an allocator
      *
@@ -159,9 +159,18 @@ public:
      *                          Must be at least size(T)*itemsPerBlock sized.
      *                          Caller is responsible for freeing this memory.
      */
-    GrTAllocator(uint32_t itemsPerBlock, void* initialBlock) :
-        fAllocator(sizeof(T), itemsPerBlock, initialBlock)
-    {}
+    GrTAllocator(uint32_t itemsPerBlock, void* initialBlock)
+        : fAllocator(sizeof(T), itemsPerBlock, initialBlock) {}
+
+    /**
+     * Create an allocator using a GrAlignedTAlloc as the initial block.
+     *
+     * @param   initialBlock    specifies the storage for the initial block
+     *                          and the size of subsequent blocks.
+     */
+    template <int N>
+    GrTAllocator(GrAlignedSTStorage<N,T>* initialBlock)
+        : fAllocator(sizeof(T), N, initialBlock->get()) {}
     
     /**
      * Adds an item and returns it.
index 54082b7..717dfe6 100644 (file)
@@ -22,6 +22,7 @@
 #include "GrRect.h"
 #include "GrPath.h"
 #include "GrTArray.h"
+#include "GrTemplates.h"
 
 
 class GrClip {
@@ -140,7 +141,7 @@ private:
     enum {
         kPreAllocElements = 4,
     };
-    uint8_t             fListMemory[sizeof(Element) * kPreAllocElements];
+    GrAlignedSTStorage<kPreAllocElements, Element>  fListStorage;
     GrTArray<Element>   fList;
 };
 #endif
index 9d3f91a..c80afd9 100644 (file)
@@ -158,18 +158,17 @@ private:
     size_t                          fReservedIndexBytes;
     size_t                          fUsedReservedVertexBytes;
     size_t                          fUsedReservedIndexBytes;
+    
+    enum {
+        kDrawPreallocCnt   = 8,
+        kStatePreallocCnt  = 8,
+        kClipPreallocCnt   = 8,
+    };
+
+    GrAlignedSTStorage<kDrawPreallocCnt, Draw>              fDrawStorage;
+    GrAlignedSTStorage<kStatePreallocCnt, SavedDrawState>   fStateStorage;
+    GrAlignedSTStorage<kClipPreallocCnt, GrClip>            fClipStorage;
 
-    static const uint32_t           STATES_BLOCK_SIZE = 8;
-    static const uint32_t           DRAWS_BLOCK_SIZE  = 8;
-    static const uint32_t           CLIPS_BLOCK_SIZE  = 8;
-    static const uint32_t           VERTEX_BLOCK_SIZE = 1 << 12;
-    static const uint32_t           INDEX_BLOCK_SIZE  = 1 << 10;
-    int8_t                          fDrawsStorage[sizeof(Draw) *
-                                                  DRAWS_BLOCK_SIZE];
-    int8_t                          fStatesStorage[sizeof(SavedDrawState) *
-                                                   STATES_BLOCK_SIZE];
-    int8_t                          fClipsStorage[sizeof(GrClip) *
-                                                  CLIPS_BLOCK_SIZE];
     typedef GrDrawTarget INHERITED;
 };
 
index 6ef1a13..821424b 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <new>
 #include "GrTypes.h"
+#include "GrTemplates.h"
 
 // DATA_TYPE indicates that T has a trivial cons, destructor
 // and can be shallow-copied
@@ -43,6 +44,16 @@ public:
         fPreAllocMemArray = NULL;
     }
 
+    template <int N>
+    GrTArray(GrAlignedSTStorage<N,T>* storage) {
+        GrAssert(N > 0);
+        fCount              = 0;
+        fReserveCount       = N;
+        fAllocCount         = N;
+        fMemArray           = storage->get();
+        fPreAllocMemArray   = storage->get();
+    }
+
     GrTArray(void* preAllocStorage, int preAllocCount) {
         GrAssert(preAllocCount >= 0);
         // we allow NULL,0 args and revert to the default cons. behavior
@@ -64,6 +75,7 @@ public:
         fAllocCount         = GrMax(fReserveCount, fCount);
         fMemArray           = GrMalloc(sizeof(T) * fAllocCount);
         fPreAllocMemArray   = NULL;
+
         if (DATA_TYPE) {
             memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
         } else {
diff --git a/gpu/include/GrTemplates.h b/gpu/include/GrTemplates.h
new file mode 100644 (file)
index 0000000..18f68ba
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#ifndef GrTemplates_DEFINED
+#define GrTemplates_DEFINED
+
+#include "GrNoncopyable.h"
+
+/**
+ *  Use to cast a ptr to a different type, and maintain strict-aliasing
+ */
+template <typename Dst, typename Src> Dst GrTCast(Src src) {
+    union {
+        Src src;
+        Dst dst;
+    } data;
+    data.src = src;
+    return data.dst;
+}
+
+/**
+ * Reserves memory that is aligned on double and pointer boundaries.
+ * Hopefully this is sufficient for all practical purposes.
+ */
+template <size_t N> class GrAlignedSStorage : GrNoncopyable {
+public:
+    void* get() { return fData; }
+private:
+    union {
+        void*   fPtr;
+        double  fDouble;
+        char    fData[N];
+    };
+};
+
+/**
+ * Reserves memory that is aligned on double and pointer boundaries.
+ * Hopefully this is sufficient for all practical purposes. Otherwise,
+ * we have to do some arcane trickery to determine alignment of non-POD
+ * types. Lifetime of the memory is the lifetime of the object.
+ */
+template <int N, typename T> class GrAlignedSTStorage : GrNoncopyable {
+public:
+    /**
+     * Returns void* because this object does not initialize the
+     * memory. Use placement new for types that require a cons.
+     */
+    void* get() { return fStorage.get(); }
+private:
+    GrAlignedSStorage<sizeof(T)*N> fStorage;
+};
+
+/**
+ * saves value of T* in and restores in destructor
+ * e.g.:
+ * {
+ *      GrAutoTPtrValueRestore<int*> autoCountRestore;
+ *      if (useExtra) {
+ *          autoCountRestore.save(&fCount);
+ *          fCount += fExtraCount;
+ *      }
+ *      ...
+ * }  // fCount is restored
+ */
+template <typename T> class GrAutoTPtrValueRestore : public GrNoncopyable {
+public:
+    GrAutoTPtrValueRestore() : fPtr(NULL), fVal() {}
+    
+    GrAutoTPtrValueRestore(T* ptr) {
+        fPtr = ptr;
+        if (NULL != ptr) {
+            fVal = *ptr;
+        }
+    }
+    
+    ~GrAutoTPtrValueRestore() {
+        if (NULL != fPtr) {
+            *fPtr = fVal;
+        }
+    }
+    
+    // restores previously saved value (if any) and saves value for passed T*
+    void save(T* ptr) {
+        if (NULL != fPtr) {
+            *fPtr = fVal;
+        }
+        fPtr = ptr;
+        fVal = *ptr;
+    }
+private:
+    T* fPtr;
+    T  fVal;
+};
+
+#endif
\ No newline at end of file
index 9d1c5e3..f5bd036 100644 (file)
@@ -138,63 +138,6 @@ static inline int16_t GrToS16(intptr_t x) {
 
 #endif
 
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- *  Use to cast a ptr to a different type, and maintain strict-aliasing
- */
-template <typename Dst, typename Src> Dst GrTCast(Src src) {
-    union {
-        Src src;
-        Dst dst;
-    } data;
-    data.src = src;
-    return data.dst;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-// saves value of T* in and restores in destructor
-// e.g.:
-// {
-//      GrAutoTPtrValueRestore<int*> autoCountRestore;
-//      if (useExtra) {
-//          autoCountRestore.save(&fCount);
-//          fCount += fExtraCount;
-//      }
-//      ...
-//  }  // fCount is restored
-//
-template <typename T>
-class GrAutoTPtrValueRestore {
-public:
-    GrAutoTPtrValueRestore() : fPtr(NULL), fVal() {}
-    
-    GrAutoTPtrValueRestore(T* ptr) {
-        fPtr = ptr;
-        if (NULL != ptr) {
-            fVal = *ptr;
-        }
-    }
-    
-    ~GrAutoTPtrValueRestore() {
-        if (NULL != fPtr) {
-            *fPtr = fVal;
-        }
-    }
-    
-    // restores previously saved value (if any) and saves value for passed T*
-    void save(T* ptr) {
-        if (NULL != fPtr) {
-            *fPtr = fVal;
-        }
-        fPtr = ptr;
-        fVal = *ptr;
-    }
-private:
-    T* fPtr;
-    T  fVal;
-};
 
 ///////////////////////////////////////////////////////////////////////////////
 
index e8da3d1..425ad27 100644 (file)
 #include "GrClip.h"
 
 GrClip::GrClip()
-    : fList(fListMemory, kPreAllocElements) {
+    : fList(&fListStorage) {
     fConservativeBounds.setEmpty();
     fConservativeBoundsValid = true;
 }
 
 GrClip::GrClip(const GrClip& src)
-    : fList(fListMemory, kPreAllocElements) {
+    : fList(&fListStorage) {
     *this = src;
 }
 
 GrClip::GrClip(const GrIRect& rect)
-    : fList(fListMemory, kPreAllocElements) {
+    : fList(&fListStorage) {
     this->setFromIRect(rect);
 }
 
 GrClip::GrClip(const GrRect& rect)
-    : fList(fListMemory, kPreAllocElements) {
+    : fList(&fListStorage) {
     this->setFromRect(rect);
 }
 
 GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
                const GrRect* bounds)
-    : fList(fListMemory, kPreAllocElements) {
+    : fList(&fListStorage) {
     this->setFromIterator(iter, tx, ty, bounds);
 }
 
index be4db99..eebae00 100644 (file)
@@ -24,9 +24,9 @@
 
 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
                                          GrIndexBufferAllocPool* indexPool) :
-        fDraws(DRAWS_BLOCK_SIZE, fDrawsStorage),
-        fStates(STATES_BLOCK_SIZE, fStatesStorage),
-        fClips(CLIPS_BLOCK_SIZE, fClipsStorage),
+        fDraws(&fDrawStorage),
+        fStates(&fStateStorage),
+        fClips(&fClipStorage),
         fClipSet(true),
 
         fLastRectVertexLayout(0),