| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
|  | 2 // Use of this source code is governed by a BSD-style license that can be | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 // This file contains the implementation of the RingBuffer class. | 
|  | 6 | 
|  | 7 #include "../client/ring_buffer.h" | 
|  | 8 #include <algorithm> | 
|  | 9 #include "../client/cmd_buffer_helper.h" | 
|  | 10 | 
|  | 11 namespace gpu { | 
|  | 12 | 
|  | 13 RingBuffer::RingBuffer( | 
|  | 14     Offset base_offset, unsigned int size, CommandBufferHelper* helper) | 
|  | 15     : helper_(helper), | 
|  | 16       base_offset_(base_offset), | 
|  | 17       size_(size), | 
|  | 18       free_offset_(0), | 
|  | 19       in_use_offset_(0) { | 
|  | 20 } | 
|  | 21 | 
|  | 22 RingBuffer::~RingBuffer() { | 
|  | 23   // Free blocks pending tokens. | 
|  | 24   while (!blocks_.empty()) { | 
|  | 25     FreeOldestBlock(); | 
|  | 26   } | 
|  | 27 } | 
|  | 28 | 
|  | 29 void RingBuffer::FreeOldestBlock() { | 
|  | 30   DCHECK(!blocks_.empty()) << "no free blocks"; | 
|  | 31   Block& block = blocks_.front(); | 
|  | 32   DCHECK(block.valid) << "attempt to allocate more than maximum memory"; | 
|  | 33   helper_->WaitForToken(block.token); | 
|  | 34   in_use_offset_ += block.size; | 
|  | 35   if (in_use_offset_ == size_) { | 
|  | 36     in_use_offset_ = 0; | 
|  | 37   } | 
|  | 38   // If they match then the entire buffer is free. | 
|  | 39   if (in_use_offset_ == free_offset_) { | 
|  | 40     in_use_offset_ = 0; | 
|  | 41     free_offset_ = 0; | 
|  | 42   } | 
|  | 43   blocks_.pop_back(); | 
|  | 44 } | 
|  | 45 | 
|  | 46 RingBuffer::Offset RingBuffer::Alloc(unsigned int size) { | 
|  | 47   DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory"; | 
|  | 48   // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to | 
|  | 49   // return different pointers every time. | 
|  | 50   if (size == 0) size = 1; | 
|  | 51 | 
|  | 52   // Wait until there is enough room. | 
|  | 53   while (size > GetLargestFreeSizeNoWaiting()) { | 
|  | 54     FreeOldestBlock(); | 
|  | 55   } | 
|  | 56 | 
|  | 57   Offset offset = free_offset_; | 
|  | 58   blocks_.push_back(Block(offset, size)); | 
|  | 59   free_offset_ += size; | 
|  | 60   if (free_offset_ == size_) { | 
|  | 61     free_offset_ = 0; | 
|  | 62   } | 
|  | 63   return offset + base_offset_; | 
|  | 64 } | 
|  | 65 | 
|  | 66 void RingBuffer::FreePendingToken(RingBuffer::Offset offset, | 
|  | 67                                   unsigned int token) { | 
|  | 68   offset -= base_offset_; | 
|  | 69   DCHECK(!blocks_.empty()) << "no allocations to free"; | 
|  | 70   for (Container::reverse_iterator it = blocks_.rbegin(); | 
|  | 71         it != blocks_.rend(); | 
|  | 72         ++it) { | 
|  | 73     Block& block = *it; | 
|  | 74     if (block.offset == offset) { | 
|  | 75       DCHECK(!block.valid) << "block that corresponds to offset already freed"; | 
|  | 76       block.token = token; | 
|  | 77       block.valid = true; | 
|  | 78       return; | 
|  | 79     } | 
|  | 80   } | 
|  | 81   NOTREACHED() << "attempt to free non-existant block"; | 
|  | 82 } | 
|  | 83 | 
|  | 84 unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() { | 
|  | 85   if (free_offset_ == in_use_offset_) { | 
|  | 86     if (blocks_.empty()) { | 
|  | 87       // The entire buffer is free. | 
|  | 88       DCHECK_EQ(free_offset_, 0u); | 
|  | 89       return size_; | 
|  | 90     } else { | 
|  | 91       // The entire buffer is in use. | 
|  | 92       return 0; | 
|  | 93     } | 
|  | 94   } else if (free_offset_ > in_use_offset_) { | 
|  | 95     // It's free from free_offset_ to size_ | 
|  | 96     return size_ - free_offset_; | 
|  | 97   } else { | 
|  | 98     // It's free from free_offset_ -> in_use_offset_; | 
|  | 99     return in_use_offset_ - free_offset_; | 
|  | 100   } | 
|  | 101 } | 
|  | 102 | 
|  | 103 }  // namespace gpu | 
| OLD | NEW | 
|---|