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

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

Issue 1796002: Changes the GLES2Implementation to use a RingBuffer... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 8 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') | gpu/command_buffer/client/ring_buffer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(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
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/ring_buffer.h ('k') | gpu/command_buffer/client/ring_buffer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698