| Index: src/gpu/gl/GrGLNameAllocator.cpp
|
| diff --git a/src/gpu/gl/GrGLNameAllocator.cpp b/src/gpu/gl/GrGLNameAllocator.cpp
|
| deleted file mode 100644
|
| index 03123a6d86ea7e87e1afe345039412b79c1ff84b..0000000000000000000000000000000000000000
|
| --- a/src/gpu/gl/GrGLNameAllocator.cpp
|
| +++ /dev/null
|
| @@ -1,370 +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.
|
| - */
|
| -
|
| -#include "GrGLNameAllocator.h"
|
| -
|
| -/**
|
| - * This is the abstract base class for a nonempty AVL tree that tracks allocated
|
| - * names within the half-open range [fFirst, fEnd). The inner nodes can be
|
| - * sparse (meaning not every name within the range is necessarily allocated),
|
| - * but the bounds are tight, so fFirst *is* guaranteed to be allocated, and so
|
| - * is fEnd - 1.
|
| - */
|
| -class GrGLNameAllocator::SparseNameRange : public SkRefCnt {
|
| -public:
|
| - virtual ~SparseNameRange() {}
|
| -
|
| - /**
|
| - * Return the beginning of the range. first() is guaranteed to be allocated.
|
| - *
|
| - * @return The first name in the range.
|
| - */
|
| - GrGLuint first() const { return fFirst; }
|
| -
|
| - /**
|
| - * Return the end of the range. end() - 1 is guaranteed to be allocated.
|
| - *
|
| - * @return One plus the final name in the range.
|
| - */
|
| - GrGLuint end() const { return fEnd; }
|
| -
|
| - /**
|
| - * Return the height of the tree. This can only be nonzero at an inner node.
|
| - *
|
| - * @return 0 if the implementation is a leaf node,
|
| - * The nonzero height of the tree otherwise.
|
| - */
|
| - GrGLuint height() const { return fHeight; }
|
| -
|
| - /**
|
| - * Allocate a name from strictly inside this range. The call will fail if
|
| - * there is not a free name within.
|
| - *
|
| - * @param outName A pointer that receives the allocated name. outName will
|
| - * be set to zero if there were no free names within the
|
| - * range [fFirst, fEnd).
|
| - * @return The resulting SparseNameRange after the allocation. Note that
|
| - * this call is destructive, so the original SparseNameRange will no
|
| - * longer be valid afterward. The caller must always update its
|
| - * pointer with the new SparseNameRange.
|
| - */
|
| - virtual SparseNameRange* SK_WARN_UNUSED_RESULT internalAllocate(GrGLuint* outName) = 0;
|
| -
|
| - /**
|
| - * Remove the leftmost leaf node from this range (or the entire thing if it
|
| - * *is* a leaf node). This is an internal helper method that is used after
|
| - * an allocation if one contiguous range became adjacent to another. (The
|
| - * range gets removed so the one immediately before can be extended,
|
| - * collapsing the two into one.)
|
| - *
|
| - * @param removedCount A pointer that receives the size of the contiguous
|
| - range that was removed.
|
| - * @return The resulting SparseNameRange after the removal (or nullptr if it
|
| - * became empty). Note that this call is destructive, so the
|
| - * original SparseNameRange will no longer be valid afterward. The
|
| - * caller must always update its pointer with the new
|
| - * SparseNameRange.
|
| - */
|
| - virtual SparseNameRange* SK_WARN_UNUSED_RESULT removeLeftmostContiguousRange(GrGLuint* removedCount) = 0;
|
| -
|
| - /**
|
| - * Append adjacent allocated names to the end of this range. This operation
|
| - * does not affect the structure of the tree. The caller is responsible for
|
| - * ensuring the new names won't overlap sibling ranges, if any.
|
| - *
|
| - * @param count The number of adjacent names to append.
|
| - * @return The first name appended.
|
| - */
|
| - virtual GrGLuint appendNames(GrGLuint count) = 0;
|
| -
|
| - /**
|
| - * Prepend adjacent allocated names behind the beginning of this range. This
|
| - * operation does not affect the structure of the tree. The caller is
|
| - * responsible for ensuring the new names won't overlap sibling ranges, if
|
| - * any.
|
| - *
|
| - * @param count The number of adjacent names to prepend.
|
| - * @return The final name prepended (the one with the lowest value).
|
| - */
|
| - virtual GrGLuint prependNames(GrGLuint count) = 0;
|
| -
|
| - /**
|
| - * Free a name so it is no longer tracked as allocated. If the name is at
|
| - * the very beginning or very end of the range, the boundaries [fFirst, fEnd)
|
| - * will be tightened.
|
| - *
|
| - * @param name The name to free. Not-allocated names are silently ignored
|
| - * the same way they are in the OpenGL spec.
|
| - * @return The resulting SparseNameRange after the free (or nullptr if it
|
| - * became empty). Note that this call is destructive, so the
|
| - * original SparseNameRange will no longer be valid afterward. The
|
| - * caller must always update its pointer with the new
|
| - * SparseNameRange.
|
| - */
|
| - virtual SparseNameRange* SK_WARN_UNUSED_RESULT free(GrGLuint name) = 0;
|
| -
|
| -protected:
|
| - SparseNameRange* takeRef() {
|
| - this->ref();
|
| - return this;
|
| - }
|
| -
|
| - GrGLuint fFirst;
|
| - GrGLuint fEnd;
|
| - GrGLuint fHeight;
|
| -};
|
| -
|
| -/**
|
| - * This class is the SparseNameRange implementation for an inner node. It is an
|
| - * AVL tree with non-null, non-adjacent left and right children.
|
| - */
|
| -class GrGLNameAllocator::SparseNameTree : public SparseNameRange {
|
| -public:
|
| - SparseNameTree(SparseNameRange* left, SparseNameRange* right)
|
| - : fLeft(left),
|
| - fRight(right) {
|
| - SkASSERT(fLeft.get());
|
| - SkASSERT(fRight.get());
|
| - this->updateStats();
|
| - }
|
| -
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT internalAllocate(GrGLuint* outName) override {
|
| - // Try allocating the range inside fLeft's internal gaps.
|
| - fLeft.reset(fLeft->internalAllocate(outName));
|
| - if (0 != *outName) {
|
| - this->updateStats();
|
| - return this->rebalance();
|
| - }
|
| -
|
| - if (fLeft->end() + 1 == fRight->first()) {
|
| - // It closed the gap between fLeft and fRight; merge.
|
| - GrGLuint removedCount;
|
| - fRight.reset(fRight->removeLeftmostContiguousRange(&removedCount));
|
| - *outName = fLeft->appendNames(1 + removedCount);
|
| - if (nullptr == fRight.get()) {
|
| - return fLeft.detach();
|
| - }
|
| - this->updateStats();
|
| - return this->rebalance();
|
| - }
|
| -
|
| - // There is guaranteed to be a gap between fLeft and fRight, and the
|
| - // "size 1" case has already been covered.
|
| - SkASSERT(fLeft->end() + 1 < fRight->first());
|
| - *outName = fLeft->appendNames(1);
|
| - return this->takeRef();
|
| - }
|
| -
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT removeLeftmostContiguousRange(GrGLuint* removedCount) override {
|
| - fLeft.reset(fLeft->removeLeftmostContiguousRange(removedCount));
|
| - if (nullptr == fLeft) {
|
| - return fRight.detach();
|
| - }
|
| - this->updateStats();
|
| - return this->rebalance();
|
| - }
|
| -
|
| - GrGLuint appendNames(GrGLuint count) override {
|
| - SkASSERT(fEnd + count > fEnd); // Check for integer wrap.
|
| - GrGLuint name = fRight->appendNames(count);
|
| - SkASSERT(fRight->end() == fEnd + count);
|
| - this->updateStats();
|
| - return name;
|
| - }
|
| -
|
| - GrGLuint prependNames(GrGLuint count) override {
|
| - SkASSERT(fFirst > count); // We can't allocate at or below 0.
|
| - GrGLuint name = fLeft->prependNames(count);
|
| - SkASSERT(fLeft->first() == fFirst - count);
|
| - this->updateStats();
|
| - return name;
|
| - }
|
| -
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT free(GrGLuint name) override {
|
| - if (name < fLeft->end()) {
|
| - fLeft.reset(fLeft->free(name));
|
| - if (nullptr == fLeft) {
|
| - // fLeft became empty after the free.
|
| - return fRight.detach();
|
| - }
|
| - this->updateStats();
|
| - return this->rebalance();
|
| - } else {
|
| - fRight.reset(fRight->free(name));
|
| - if (nullptr == fRight) {
|
| - // fRight became empty after the free.
|
| - return fLeft.detach();
|
| - }
|
| - this->updateStats();
|
| - return this->rebalance();
|
| - }
|
| - }
|
| -
|
| -private:
|
| - typedef SkAutoTUnref<SparseNameRange> SparseNameTree::* ChildRange;
|
| -
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT rebalance() {
|
| - if (fLeft->height() > fRight->height() + 1) {
|
| - return this->rebalanceImpl<&SparseNameTree::fLeft, &SparseNameTree::fRight>();
|
| - }
|
| - if (fRight->height() > fLeft->height() + 1) {
|
| - return this->rebalanceImpl<&SparseNameTree::fRight, &SparseNameTree::fLeft>();
|
| - }
|
| - return this->takeRef();
|
| - }
|
| -
|
| - /**
|
| - * Rebalance the tree using rotations, as described in the AVL algorithm:
|
| - * http://en.wikipedia.org/wiki/AVL_tree#Insertion
|
| - */
|
| - template<ChildRange Tall, ChildRange Short>
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT rebalanceImpl() {
|
| - // We should be calling rebalance() enough that the tree never gets more
|
| - // than one rotation off balance.
|
| - SkASSERT(2 == (this->*Tall)->height() - (this->*Short)->height());
|
| -
|
| - // Ensure we are in the 'Left Left' or 'Right Right' case:
|
| - // http://en.wikipedia.org/wiki/AVL_tree#Insertion
|
| - SparseNameTree* tallChild = static_cast<SparseNameTree*>((this->*Tall).get());
|
| - if ((tallChild->*Tall)->height() < (tallChild->*Short)->height()) {
|
| - (this->*Tall).reset(tallChild->rotate<Short, Tall>());
|
| - }
|
| -
|
| - // Perform a rotation to balance the tree.
|
| - return this->rotate<Tall, Short>();
|
| - }
|
| -
|
| - /**
|
| - * Perform a node rotation, as described in the AVL algorithm:
|
| - * http://en.wikipedia.org/wiki/AVL_tree#Insertion
|
| - */
|
| - template<ChildRange Tall, ChildRange Short>
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT rotate() {
|
| - SparseNameTree* newRoot = static_cast<SparseNameTree*>((this->*Tall).detach());
|
| -
|
| - (this->*Tall).reset((newRoot->*Short).detach());
|
| - this->updateStats();
|
| -
|
| - (newRoot->*Short).reset(this->takeRef());
|
| - newRoot->updateStats();
|
| -
|
| - return newRoot;
|
| - }
|
| -
|
| - void updateStats() {
|
| - SkASSERT(fLeft->end() < fRight->first()); // There must be a gap between left and right.
|
| - fFirst = fLeft->first();
|
| - fEnd = fRight->end();
|
| - fHeight = 1 + SkMax32(fLeft->height(), fRight->height());
|
| - }
|
| -
|
| - SkAutoTUnref<SparseNameRange> fLeft;
|
| - SkAutoTUnref<SparseNameRange> fRight;
|
| -};
|
| -
|
| -/**
|
| - * This class is the SparseNameRange implementation for a leaf node. It just a
|
| - * contiguous range of allocated names.
|
| - */
|
| -class GrGLNameAllocator::ContiguousNameRange : public SparseNameRange {
|
| -public:
|
| - ContiguousNameRange(GrGLuint first, GrGLuint end) {
|
| - SkASSERT(first < end);
|
| - fFirst = first;
|
| - fEnd = end;
|
| - fHeight = 0;
|
| - }
|
| -
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT internalAllocate(GrGLuint* outName) override {
|
| - *outName = 0; // No internal gaps, we are contiguous.
|
| - return this->takeRef();
|
| - }
|
| -
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT removeLeftmostContiguousRange(GrGLuint* removedCount) override {
|
| - *removedCount = fEnd - fFirst;
|
| - return nullptr;
|
| - }
|
| -
|
| - GrGLuint appendNames(GrGLuint count) override {
|
| - SkASSERT(fEnd + count > fEnd); // Check for integer wrap.
|
| - GrGLuint name = fEnd;
|
| - fEnd += count;
|
| - return name;
|
| - }
|
| -
|
| - GrGLuint prependNames(GrGLuint count) override {
|
| - SkASSERT(fFirst > count); // We can't allocate at or below 0.
|
| - fFirst -= count;
|
| - return fFirst;
|
| - }
|
| -
|
| - SparseNameRange* SK_WARN_UNUSED_RESULT free(GrGLuint name) override {
|
| - if (name < fFirst || name >= fEnd) {
|
| - // Not-allocated names are silently ignored.
|
| - return this->takeRef();
|
| - }
|
| -
|
| - if (fFirst == name) {
|
| - ++fFirst;
|
| - return (fEnd == fFirst) ? nullptr : this->takeRef();
|
| - }
|
| -
|
| - if (fEnd == name + 1) {
|
| - --fEnd;
|
| - return this->takeRef();
|
| - }
|
| -
|
| - SparseNameRange* left = new ContiguousNameRange(fFirst, name);
|
| - SparseNameRange* right = this->takeRef();
|
| - fFirst = name + 1;
|
| - return new SparseNameTree(left, right);
|
| - }
|
| -};
|
| -
|
| -GrGLNameAllocator::GrGLNameAllocator(GrGLuint firstName, GrGLuint endName)
|
| - : fFirstName(firstName),
|
| - fEndName(endName) {
|
| - SkASSERT(firstName > 0);
|
| - SkASSERT(endName > firstName);
|
| -}
|
| -
|
| -GrGLNameAllocator::~GrGLNameAllocator() {
|
| -}
|
| -
|
| -GrGLuint GrGLNameAllocator::allocateName() {
|
| - if (nullptr == fAllocatedNames.get()) {
|
| - fAllocatedNames.reset(new ContiguousNameRange(fFirstName, fFirstName + 1));
|
| - return fFirstName;
|
| - }
|
| -
|
| - if (fAllocatedNames->first() > fFirstName) {
|
| - return fAllocatedNames->prependNames(1);
|
| - }
|
| -
|
| - GrGLuint name;
|
| - fAllocatedNames.reset(fAllocatedNames->internalAllocate(&name));
|
| - if (0 != name) {
|
| - return name;
|
| - }
|
| -
|
| - if (fAllocatedNames->end() < fEndName) {
|
| - return fAllocatedNames->appendNames(1);
|
| - }
|
| -
|
| - // Out of names.
|
| - return 0;
|
| -}
|
| -
|
| -void GrGLNameAllocator::free(GrGLuint name) {
|
| - if (!fAllocatedNames.get()) {
|
| - // Not-allocated names are silently ignored.
|
| - return;
|
| - }
|
| -
|
| - fAllocatedNames.reset(fAllocatedNames->free(name));
|
| -}
|
|
|