diff options
author | mtklein <mtklein@google.com> | 2014-10-13 14:00:42 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-13 14:00:42 -0700 |
commit | 07894c4d7dbd539583d7f51f05616e295eef2578 (patch) | |
tree | 7d6cd877bbcdaab334460ce784a5612abe5a5e09 /src/gpu/GrTRecorder.h | |
parent | be23418776414ccc6d534ba4dcbe1361b94f4356 (diff) |
Revert of Create a single command buffer for GrInOrderDrawBuffer (patchset #14 id:1050001 of https://codereview.chromium.org/628453002/)
Reason for revert:
New test failing on Android: http://build.chromium.org/p/client.skia.android/builders/Test-Android-Nexus7-Tegra3-Arm7-Release/builds/89/steps/dm/logs/stdio
Original issue's description:
> Adds a GrTBaseList class that GrInOrderDrawBuffer uses to allocate
> all its commands interleaved in contiguous memory. GrTBaseList also
> supports extra data associated with objects, so we can store arrays
> inline without having to call malloc().
>
> Committed: https://skia.googlesource.com/skia/+/47c844aaba81e5a29c773b660e1d6062c766d253
TBR=bsalomon@google.com,reed@google.com,cdalton@nvidia.com
NOTREECHECKS=true
NOTRY=true
Review URL: https://codereview.chromium.org/652843002
Diffstat (limited to 'src/gpu/GrTRecorder.h')
-rw-r--r-- | src/gpu/GrTRecorder.h | 251 |
1 files changed, 0 insertions, 251 deletions
diff --git a/src/gpu/GrTRecorder.h b/src/gpu/GrTRecorder.h deleted file mode 100644 index c8f7644f4f..0000000000 --- a/src/gpu/GrTRecorder.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrTRecorder_DEFINED -#define GrTRecorder_DEFINED - -#include "SkTemplates.h" -#include "SkTypes.h" - -template<typename TBase, typename TAlign> class GrTRecorder; -template<typename TItem> struct GrTRecorderAllocWrapper; - -/** - * Records a list of items with a common base type, optional associated data, and - * permanent memory addresses. - * - * This class preallocates its own chunks of memory for hosting objects, so new items can - * be created without excessive calls to malloc(). - * - * To create a new item and append it to the back of the list, use the following macros: - * - * GrNEW_APPEND_TO_RECORDER(recorder, SubclassName, (args)) - * GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, SubclassName, (args), sizeOfData) - * - * Upon reset or delete, the items are destructed in the same order they were received, - * not reverse (stack) order. - * - * @param TBase Common base type of items in the list. If TBase is not a class with a - * virtual destructor, the client is responsible for invoking any necessary - * destructors. - * - * For now, any subclass used in the list must have the same start address - * as TBase (or in other words, the types must be convertible via - * reinterpret_cast<>). Classes with multiple inheritance (or any subclass - * on an obscure compiler) may not be compatible. This is runtime asserted - * in debug builds. - * - * @param TAlign A type whose size is the desired memory alignment for object allocations. - * This should be the largest known alignment requirement for all objects - * that may be stored in the list. - */ -template<typename TBase, typename TAlign> class GrTRecorder : SkNoncopyable { -public: - class Iter; - - /** - * Create a recorder. - * - * @param initialSizeInBytes The amount of memory reserved by the recorder initially, - and after calls to reset(). - */ - GrTRecorder(int initialSizeInBytes) - : fHeadBlock(MemBlock::Alloc(LengthOf(initialSizeInBytes))), - fTailBlock(fHeadBlock), - fLastItem(NULL) {} - - ~GrTRecorder() { - this->reset(); - sk_free(fHeadBlock); - } - - bool empty() { return !fLastItem; } - - TBase& back() { - SkASSERT(!this->empty()); - return *fLastItem; - } - - /** - * Destruct all items in the list and reset to empty. - */ - void reset(); - - /** - * Retrieve the extra data associated with an item that was allocated using - * GrNEW_APPEND_WITH_DATA_TO_RECORDER(). - * - * @param item The item whose data to retrieve. The pointer must be of the same type - * that was allocated initally; it can't be a pointer to a base class. - * - * @return The item's associated data. - */ - template<typename TItem> static const void* GetDataForItem(const TItem* item) { - const TAlign* ptr = reinterpret_cast<const TAlign*>(item); - return &ptr[length_of<TItem>::kValue]; - } - template<typename TItem> static void* GetDataForItem(TItem* item) { - TAlign* ptr = reinterpret_cast<TAlign*>(item); - return &ptr[length_of<TItem>::kValue]; - } - -private: - template<typename TItem> struct length_of { - enum { kValue = (sizeof(TItem) + sizeof(TAlign) - 1) / sizeof(TAlign) }; - }; - static int LengthOf(int bytes) { return (bytes + sizeof(TAlign) - 1) / sizeof(TAlign); } - - struct Header { - int fTotalLength; - }; - template<typename TItem> TItem* alloc_back(int dataLength); - - struct MemBlock { - static MemBlock* Alloc(int length) { - void* ptr = sk_malloc_throw(sizeof(TAlign) * (length_of<MemBlock>::kValue + length)); - return SkNEW_PLACEMENT_ARGS(ptr, MemBlock, (length)); - } - TAlign& operator [](int i) { - return reinterpret_cast<TAlign*>(this)[length_of<MemBlock>::kValue + i]; - } - ~MemBlock() { sk_free(fNext); } - - const int fLength; - int fBack; - MemBlock* fNext; - - private: - MemBlock(int length) : fLength(length), fBack(0), fNext(NULL) {} - }; - MemBlock* const fHeadBlock; - MemBlock* fTailBlock; - - TBase* fLastItem; - - template<typename TItem> friend struct GrTRecorderAllocWrapper; - - template <typename UBase, typename UAlign, typename UAlloc> - friend void* operator new(size_t, GrTRecorder<UBase, UAlign>&, - const GrTRecorderAllocWrapper<UAlloc>&); - - friend class Iter; -}; - -//////////////////////////////////////////////////////////////////////////////// - -template<typename TBase, typename TAlign> -template<typename TItem> -TItem* GrTRecorder<TBase, TAlign>::alloc_back(int dataLength) { - const int totalLength = length_of<Header>::kValue + length_of<TItem>::kValue + dataLength; - - if (fTailBlock->fBack + totalLength > fTailBlock->fLength) { - SkASSERT(!fTailBlock->fNext); - fTailBlock->fNext = MemBlock::Alloc(SkTMax(2 * fTailBlock->fLength, totalLength)); - fTailBlock = fTailBlock->fNext; - } - - Header* header = reinterpret_cast<Header*>(&(*fTailBlock)[fTailBlock->fBack]); - TItem* rawPtr = reinterpret_cast<TItem*>( - &(*fTailBlock)[fTailBlock->fBack + length_of<Header>::kValue]); - - header->fTotalLength = totalLength; - fLastItem = rawPtr; - fTailBlock->fBack += totalLength; - - // FIXME: We currently require that the base and subclass share the same start address. - // This is not required by the C++ spec, and is likely to not be true in the case of - // multiple inheritance or a base class that doesn't have virtual methods (when the - // subclass does). It would be ideal to find a more robust solution that comes at no - // extra cost to performance or code generality. - SkDEBUGCODE(void* baseAddr = fLastItem; - void* subclassAddr = rawPtr); - SkASSERT(baseAddr == subclassAddr); - - return rawPtr; -} - -template<typename TBase, typename TAlign> -class GrTRecorder<TBase, TAlign>::Iter { -public: - Iter(GrTRecorder& recorder) : fBlock(recorder.fHeadBlock), fPosition(0), fItem(NULL) {} - - bool next() { - if (fPosition >= fBlock->fBack) { - SkASSERT(fPosition == fBlock->fBack); - if (!fBlock->fNext) { - return false; - } - SkASSERT(0 != fBlock->fNext->fBack); - fBlock = fBlock->fNext; - fPosition = 0; - } - - Header* header = reinterpret_cast<Header*>(&(*fBlock)[fPosition]); - fItem = reinterpret_cast<TBase*>(&(*fBlock)[fPosition + length_of<Header>::kValue]); - fPosition += header->fTotalLength; - return true; - } - - TBase* get() const { - SkASSERT(fItem); - return fItem; - } - - TBase* operator->() const { return this->get(); } - -private: - MemBlock* fBlock; - int fPosition; - TBase* fItem; -}; - -template<typename TBase, typename TAlign> -void GrTRecorder<TBase, TAlign>::reset() { - Iter iter(*this); - while (iter.next()) { - iter->~TBase(); - } - fHeadBlock->fBack = 0; - sk_free(fHeadBlock->fNext); - fHeadBlock->fNext = NULL; - fTailBlock = fHeadBlock; - fLastItem = NULL; -} - -//////////////////////////////////////////////////////////////////////////////// - -template<typename TItem> struct GrTRecorderAllocWrapper { - GrTRecorderAllocWrapper() : fDataLength(0) {} - - template <typename TBase, typename TAlign> - GrTRecorderAllocWrapper(const GrTRecorder<TBase, TAlign>&, int sizeOfData) - : fDataLength(GrTRecorder<TBase, TAlign>::LengthOf(sizeOfData)) {} - - const int fDataLength; -}; - -template <typename TBase, typename TAlign, typename TItem> -void* operator new(size_t size, GrTRecorder<TBase, TAlign>& recorder, - const GrTRecorderAllocWrapper<TItem>& wrapper) { - SkASSERT(size == sizeof(TItem)); - return recorder.template alloc_back<TItem>(wrapper.fDataLength); -} - -template <typename TBase, typename TAlign, typename TItem> -void operator delete(void*, GrTRecorder<TBase, TAlign>&, const GrTRecorderAllocWrapper<TItem>&) { - // We only provide an operator delete to work around compiler warnings that can come - // up for an unmatched operator new when compiling with exceptions. - SK_CRASH(); -} - -#define GrNEW_APPEND_TO_RECORDER(recorder, type_name, args) \ - (new (recorder, GrTRecorderAllocWrapper<type_name>()) type_name args) - -#define GrNEW_APPEND_WITH_DATA_TO_RECORDER(recorder, type_name, args, size_of_data) \ - (new (recorder, GrTRecorderAllocWrapper<type_name>(recorder, size_of_data)) type_name args) - -#endif |