| Index: src/gpu/GrTRecorder.h
|
| diff --git a/src/gpu/GrTRecorder.h b/src/gpu/GrTRecorder.h
|
| deleted file mode 100644
|
| index c8f7644f4f10bb4a1fc617b80f18cd91f78c387a..0000000000000000000000000000000000000000
|
| --- 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
|
|
|