diff options
-rw-r--r-- | include/core/SkTypes.h | 51 | ||||
-rw-r--r-- | include/private/SkTemplates.h | 46 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 5 | ||||
-rw-r--r-- | src/gpu/batches/GrDrawPathBatch.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 5 |
5 files changed, 64 insertions, 49 deletions
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h index 0d31efc6cc..4592168bd4 100644 --- a/include/core/SkTypes.h +++ b/include/core/SkTypes.h @@ -606,17 +606,16 @@ private: #define SkAutoMalloc(...) SK_REQUIRE_LOCAL_VAR(SkAutoMalloc) /** - * Manage an allocated block of memory. If the requested size is <= kSize, then - * the allocation will come from the stack rather than the heap. This object - * is the sole manager of the lifetime of the block, so the caller must not - * call sk_free() or delete on the block. + * Manage an allocated block of memory. If the requested size is <= kSizeRequested (or slightly + * more), then the allocation will come from the stack rather than the heap. This object is the + * sole manager of the lifetime of the block, so the caller must not call sk_free() or delete on + * the block. */ -template <size_t kSize> class SkAutoSMalloc : SkNoncopyable { +template <size_t kSizeRequested> class SkAutoSMalloc : SkNoncopyable { public: /** - * Creates initially empty storage. get() returns a ptr, but it is to - * a zero-byte allocation. Must call reset(size) to return an allocated - * block. + * Creates initially empty storage. get() returns a ptr, but it is to a zero-byte allocation. + * Must call reset(size) to return an allocated block. */ SkAutoSMalloc() { fPtr = fStorage; @@ -624,9 +623,8 @@ public: } /** - * Allocate a block of the specified size. If size <= kSize, then the - * allocation will come from the stack, otherwise it will be dynamically - * allocated. + * Allocate a block of the specified size. If size <= kSizeRequested (or slightly more), then + * the allocation will come from the stack, otherwise it will be dynamically allocated. */ explicit SkAutoSMalloc(size_t size) { fPtr = fStorage; @@ -635,8 +633,8 @@ public: } /** - * Free the allocated block (if any). If the block was small enought to - * have been allocated on the stack (size <= kSize) then this does nothing. + * Free the allocated block (if any). If the block was small enough to have been allocated on + * the stack, then this does nothing. */ ~SkAutoSMalloc() { if (fPtr != (void*)fStorage) { @@ -645,18 +643,16 @@ public: } /** - * Return the allocated block. May return non-null even if the block is - * of zero size. Since this may be on the stack or dynamically allocated, - * the caller must not call sk_free() on it, but must rely on SkAutoSMalloc - * to manage it. + * Return the allocated block. May return non-null even if the block is of zero size. Since + * this may be on the stack or dynamically allocated, the caller must not call sk_free() on it, + * but must rely on SkAutoSMalloc to manage it. */ void* get() const { return fPtr; } /** - * Return a new block of the requested size, freeing (as necessary) any - * previously allocated block. As with the constructor, if size <= kSize - * then the return block may be allocated locally, rather than from the - * heap. + * Return a new block of the requested size, freeing (as necessary) any previously allocated + * block. As with the constructor, if size <= kSizeRequested (or slightly more) then the return + * block may be allocated locally, rather than from the heap. */ void* reset(size_t size, SkAutoMalloc::OnShrink shrink = SkAutoMalloc::kAlloc_OnShrink, @@ -686,9 +682,20 @@ public: } private: + // Align up to 32 bits. + static const size_t kSizeAlign4 = SkAlign4(kSizeRequested); +#if defined(GOOGLE3) + // Stack frame size is limited for GOOGLE3. 4k is less than the actual max, but some functions + // have multiple large stack allocations. + static const size_t kMaxBytes = 4 * 1024; + static const size_t kSize = kSizeRequested > kMaxBytes ? kMaxBytes : kSizeAlign4; +#else + static const size_t kSize = kSizeAlign4; +#endif + void* fPtr; size_t fSize; // can be larger than the requested size (see kReuse) - uint32_t fStorage[(kSize + 3) >> 2]; + uint32_t fStorage[kSize >> 2]; }; // Can't guard the constructor because it's a template class. diff --git a/include/private/SkTemplates.h b/include/private/SkTemplates.h index 496cf42733..e36910e814 100644 --- a/include/private/SkTemplates.h +++ b/include/private/SkTemplates.h @@ -164,9 +164,9 @@ private: SkDEBUGCODE(int fCount;) }; -/** Wraps SkAutoTArray, with room for up to N elements preallocated +/** Wraps SkAutoTArray, with room for kCountRequested elements preallocated. */ -template <int N, typename T> class SkAutoSTArray : SkNoncopyable { +template <int kCountRequested, typename T> class SkAutoSTArray : SkNoncopyable { public: /** Initialize with no objects */ SkAutoSTArray() { @@ -195,13 +195,13 @@ public: } if (fCount != count) { - if (fCount > N) { + if (fCount > kCount) { // 'fArray' was allocated last time so free it now SkASSERT((T*) fStorage != fArray); sk_free(fArray); } - if (count > N) { + if (count > kCount) { const uint64_t size64 = sk_64_mul(count, sizeof(T)); const size_t size = static_cast<size_t>(size64); if (size != size64) { @@ -240,10 +240,21 @@ public: } private: +#if defined(GOOGLE3) + // Stack frame size is limited for GOOGLE3. 4k is less than the actual max, but some functions + // have multiple large stack allocations. + static const int kMaxBytes = 4 * 1024; + static const int kCount = kCountRequested * sizeof(T) > kMaxBytes + ? kMaxBytes / sizeof(T) + : kCountRequested; +#else + static const int kCount = kCountRequested; +#endif + int fCount; T* fArray; // since we come right after fArray, fStorage should be properly aligned - char fStorage[N * sizeof(T)]; + char fStorage[kCount * sizeof(T)]; }; /** Manages an array of T elements, freeing the array in the destructor. @@ -317,12 +328,12 @@ private: T* fPtr; }; -template <size_t N, typename T> class SkAutoSTMalloc : SkNoncopyable { +template <size_t kCountRequested, typename T> class SkAutoSTMalloc : SkNoncopyable { public: SkAutoSTMalloc() : fPtr(fTStorage) {} SkAutoSTMalloc(size_t count) { - if (count > N) { + if (count > kCount) { fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP); } else { fPtr = fTStorage; @@ -340,7 +351,7 @@ public: if (fPtr != fTStorage) { sk_free(fPtr); } - if (count > N) { + if (count > kCount) { fPtr = (T*)sk_malloc_throw(count * sizeof(T)); } else { fPtr = fTStorage; @@ -368,10 +379,10 @@ public: // Reallocs the array, can be used to shrink the allocation. Makes no attempt to be intelligent void realloc(size_t count) { - if (count > N) { + if (count > kCount) { if (fPtr == fTStorage) { fPtr = (T*)sk_malloc_throw(count * sizeof(T)); - memcpy(fPtr, fTStorage, N * sizeof(T)); + memcpy(fPtr, fTStorage, kCount * sizeof(T)); } else { fPtr = (T*)sk_realloc_throw(fPtr, count * sizeof(T)); } @@ -381,9 +392,22 @@ public: } private: + // Since we use uint32_t storage, we might be able to get more elements for free. + static const size_t kCountWithPadding = SkAlign4(kCountRequested*sizeof(T)) / sizeof(T); +#if defined(GOOGLE3) + // Stack frame size is limited for GOOGLE3. 4k is less than the actual max, but some functions + // have multiple large stack allocations. + static const size_t kMaxBytes = 4 * 1024; + static const size_t kCount = kCountRequested * sizeof(T) > kMaxBytes + ? kMaxBytes / sizeof(T) + : kCountWithPadding; +#else + static const size_t kCount = kCountWithPadding; +#endif + T* fPtr; union { - uint32_t fStorage32[(N*sizeof(T) + 3) >> 2]; + uint32_t fStorage32[SkAlign4(kCount*sizeof(T)) >> 2]; T fTStorage[1]; // do NOT want to invoke T::T() }; }; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index e0ee801ecb..187a3ca37a 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -286,12 +286,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, } // temp buffer for doing sw premul conversion, if needed. -#if defined(GOOGLE3) - // Stack frame size is limited in GOOGLE3. - SkAutoSTMalloc<48 * 48, uint32_t> tmpPixels(0); -#else SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); -#endif if (tempTexture) { SkAutoTUnref<const GrFragmentProcessor> fp; SkMatrix textureMatrix; diff --git a/src/gpu/batches/GrDrawPathBatch.cpp b/src/gpu/batches/GrDrawPathBatch.cpp index ff62539932..a99f4ebf43 100644 --- a/src/gpu/batches/GrDrawPathBatch.cpp +++ b/src/gpu/batches/GrDrawPathBatch.cpp @@ -137,14 +137,8 @@ void GrDrawPathRangeBatch::onDraw(GrBatchFlushState* state) { instances.count()); } else { int floatsPerTransform = GrPathRendering::PathTransformSize(this->transformType()); -#if defined(GOOGLE3) - //Stack frame size is limited in GOOGLE3. - SkAutoSTMalloc<512, float> transformStorage(floatsPerTransform * fTotalPathCount); - SkAutoSTMalloc<256, uint16_t> indexStorage(fTotalPathCount); -#else SkAutoSTMalloc<4096, float> transformStorage(floatsPerTransform * fTotalPathCount); SkAutoSTMalloc<2048, uint16_t> indexStorage(fTotalPathCount); -#endif int idx = 0; for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) { const Draw& draw = *iter.get(); diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 3b7ccd3241..8a0d7282cc 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -857,12 +857,7 @@ bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, size_t trimRowBytes = width * bpp; // in case we need a temporary, trimmed copy of the src pixels -#if defined(GOOGLE3) - // Stack frame size is limited in GOOGLE3. - SkAutoSMalloc<64 * 128> tempStorage; -#else SkAutoSMalloc<128 * 128> tempStorage; -#endif // Internal format comes from the texture desc. GrGLenum internalFormat; |