Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Side by Side Diff: gpu/command_buffer/client/ring_buffer.cc

Issue 6901138: Allow gpu ringbuffer to wrap around. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gpu/command_buffer/client/ring_buffer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file contains the implementation of the RingBuffer class. 5 // This file contains the implementation of the RingBuffer class.
6 6
7 #include "../client/ring_buffer.h" 7 #include "../client/ring_buffer.h"
8 #include <algorithm> 8 #include <algorithm>
9 #include "../client/cmd_buffer_helper.h" 9 #include "../client/cmd_buffer_helper.h"
10 10
(...skipping 11 matching lines...) Expand all
22 RingBuffer::~RingBuffer() { 22 RingBuffer::~RingBuffer() {
23 // Free blocks pending tokens. 23 // Free blocks pending tokens.
24 while (!blocks_.empty()) { 24 while (!blocks_.empty()) {
25 FreeOldestBlock(); 25 FreeOldestBlock();
26 } 26 }
27 } 27 }
28 28
29 void RingBuffer::FreeOldestBlock() { 29 void RingBuffer::FreeOldestBlock() {
30 GPU_DCHECK(!blocks_.empty()) << "no free blocks"; 30 GPU_DCHECK(!blocks_.empty()) << "no free blocks";
31 Block& block = blocks_.front(); 31 Block& block = blocks_.front();
32 GPU_DCHECK(block.valid) << "attempt to allocate more than maximum memory"; 32 GPU_DCHECK(block.state != IN_USE)
33 helper_->WaitForToken(block.token); 33 << "attempt to allocate more than maximum memory";
34 if (block.state == FREE_PENDING_TOKEN) {
35 helper_->WaitForToken(block.token);
36 }
34 in_use_offset_ += block.size; 37 in_use_offset_ += block.size;
35 if (in_use_offset_ == size_) { 38 if (in_use_offset_ == size_) {
36 in_use_offset_ = 0; 39 in_use_offset_ = 0;
37 } 40 }
38 // If they match then the entire buffer is free. 41 // If they match then the entire buffer is free.
39 if (in_use_offset_ == free_offset_) { 42 if (in_use_offset_ == free_offset_) {
40 in_use_offset_ = 0; 43 in_use_offset_ = 0;
41 free_offset_ = 0; 44 free_offset_ = 0;
42 } 45 }
43 blocks_.pop_front(); 46 blocks_.pop_front();
44 } 47 }
45 48
46 RingBuffer::Offset RingBuffer::Alloc(unsigned int size) { 49 RingBuffer::Offset RingBuffer::Alloc(unsigned int size) {
47 GPU_DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory"; 50 GPU_DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory";
48 GPU_DCHECK(blocks_.empty() || blocks_.back().valid) 51 GPU_DCHECK(blocks_.empty() || blocks_.back().state != IN_USE)
49 << "Attempt to alloc another block before freeing the previous."; 52 << "Attempt to alloc another block before freeing the previous.";
50 // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to 53 // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to
51 // return different pointers every time. 54 // return different pointers every time.
52 if (size == 0) size = 1; 55 if (size == 0) size = 1;
53 56
54 // Wait until there is enough room. 57 // Wait until there is enough room.
55 while (size > GetLargestFreeSizeNoWaiting()) { 58 while (size > GetLargestFreeSizeNoWaiting()) {
56 FreeOldestBlock(); 59 FreeOldestBlock();
57 } 60 }
58 61
62 if (size + free_offset_ > size_) {
63 //Add padding to fill space before wrapping around
piman 2011/05/03 16:30:20 1 space after //
64 blocks_.push_back(Block(free_offset_, size_ - free_offset_, PADDING));
65 free_offset_ = 0;
66 }
67
59 Offset offset = free_offset_; 68 Offset offset = free_offset_;
60 blocks_.push_back(Block(offset, size)); 69 blocks_.push_back(Block(offset, size, IN_USE));
61 free_offset_ += size; 70 free_offset_ += size;
62 if (free_offset_ == size_) { 71 if (free_offset_ == size_) {
63 free_offset_ = 0; 72 free_offset_ = 0;
64 } 73 }
65 return offset + base_offset_; 74 return offset + base_offset_;
66 } 75 }
67 76
68 void RingBuffer::FreePendingToken(RingBuffer::Offset offset, 77 void RingBuffer::FreePendingToken(RingBuffer::Offset offset,
69 unsigned int token) { 78 unsigned int token) {
70 offset -= base_offset_; 79 offset -= base_offset_;
71 GPU_DCHECK(!blocks_.empty()) << "no allocations to free"; 80 GPU_DCHECK(!blocks_.empty()) << "no allocations to free";
72 for (Container::reverse_iterator it = blocks_.rbegin(); 81 for (Container::reverse_iterator it = blocks_.rbegin();
73 it != blocks_.rend(); 82 it != blocks_.rend();
74 ++it) { 83 ++it) {
75 Block& block = *it; 84 Block& block = *it;
76 if (block.offset == offset) { 85 if (block.offset == offset) {
77 GPU_DCHECK(!block.valid) 86 GPU_DCHECK(block.state == IN_USE)
78 << "block that corresponds to offset already freed"; 87 << "block that corresponds to offset already freed";
79 block.token = token; 88 block.token = token;
80 block.valid = true; 89 block.state = FREE_PENDING_TOKEN;
81 return; 90 return;
82 } 91 }
83 } 92 }
84 GPU_NOTREACHED() << "attempt to free non-existant block"; 93 GPU_NOTREACHED() << "attempt to free non-existant block";
85 } 94 }
86 95
87 unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() { 96 unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() {
88 // TODO(gman): Should check what the current token is and free up to that 97 // TODO(gman): Should check what the current token is and free up to that
89 // point. 98 // point.
90 if (free_offset_ == in_use_offset_) { 99 if (free_offset_ == in_use_offset_) {
91 if (blocks_.empty()) { 100 if (blocks_.empty()) {
92 // The entire buffer is free. 101 // The entire buffer is free.
93 GPU_DCHECK_EQ(free_offset_, 0u); 102 GPU_DCHECK_EQ(free_offset_, 0u);
94 return size_; 103 return size_;
95 } else { 104 } else {
96 // The entire buffer is in use. 105 // The entire buffer is in use.
97 return 0; 106 return 0;
98 } 107 }
99 } else if (free_offset_ > in_use_offset_) { 108 } else if (free_offset_ > in_use_offset_) {
100 // It's free from free_offset_ to size_ 109 // It's free from free_offset_ to size_ and from 0 to in_use_offset_
101 return size_ - free_offset_; 110 return std::max(size_ - free_offset_, in_use_offset_);
102 } else { 111 } else {
103 // It's free from free_offset_ -> in_use_offset_; 112 // It's free from free_offset_ -> in_use_offset_;
104 return in_use_offset_ - free_offset_; 113 return in_use_offset_ - free_offset_;
105 } 114 }
106 } 115 }
107 116
108 } // namespace gpu 117 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/ring_buffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698