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

Side by Side Diff: gpu/command_buffer/service/path_manager.cc

Issue 169403005: command_buffer: Implement path rendering functions for CHROMIUM_path_rendering (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@nv-pr-02-texgen
Patch Set: rebase and cleanup ids Created 6 years, 2 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
OLDNEW
(Empty)
1 // Copyright (c) 2014 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 #include "gpu/command_buffer/service/path_manager.h"
6 #include "base/logging.h"
7 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
8 #include "ui/gl/gl_bindings.h"
9
10 namespace {
11 void callDeletePaths(GLuint first_id, GLuint range) {
12 while (range > 0) {
13 GLsizei irange;
14 if (range > std::numeric_limits<GLsizei>::max()) {
15 irange = std::numeric_limits<GLsizei>::max();
16 } else {
17 irange = static_cast<GLsizei>(range);
18 }
19 glDeletePathsNV(first_id, irange);
20 range -= irange;
21 first_id += irange + 1;
22 }
23 }
24 } // anonymous namespace
25
26 namespace gpu {
27 namespace gles2 {
28
29 PathManager::PathManager() {
30 }
31
32 PathManager::~PathManager() {
33 DCHECK(path_map_.empty());
34 }
35
36 void PathManager::Destroy(bool have_context) {
37 if (have_context) {
38 for (PathRangeMap::const_iterator it = path_map_.begin();
39 it != path_map_.end();
40 ++it) {
41 callDeletePaths(FirstServiceId(it), RangeSize(it));
42 }
43 }
44 path_map_.clear();
45 }
46
47 void PathManager::CreatePathRange(GLuint first_client_id,
48 GLuint last_client_id,
49 GLuint first_service_id) {
50 DCHECK(!HasPathsInRange(first_client_id, last_client_id));
51 DCHECK(first_service_id > 0);
52 bool check_before = false;
53
54 PathRangeMap::iterator it = path_map_.lower_bound(first_client_id);
55 PathRangeMap::iterator next_range = it;
56 if (it != path_map_.begin()) {
57 --it;
58 check_before = true;
59 }
60 if (next_range != path_map_.end()) {
61 GLuint last_service_id =
62 first_service_id + last_client_id - first_client_id;
63 // FirstClientId(next_range) - 1 does not underflow because lower_bound
64 // returns > first_client_id.
65 // It does not return == first_client_id (== 0) because this would
66 // contradict
67 // !HasPathsInRange(first_client_id, last_client_id).
68 // FirstServiceId(next_range) - 1 does not underflow because
69 // first_service_id > 0.
70 if (FirstClientId(next_range) - 1 == last_client_id &&
71 FirstServiceId(next_range) - 1 == last_service_id) {
72 last_client_id = LastClientId(next_range);
73 path_map_.erase(next_range);
74 }
75 }
76
77 if (it != path_map_.end() && check_before) {
78 // The last first client id -1 does not underflow because then lower_bound
79 // would have found something, which contradicts
80 // !HasPathsInRange(first_client_id, last_client_id).
81 // first_service_id -1 does not underflow because first_service_id > 0.
82 if (LastClientId(it) == first_client_id - 1 &&
83 LastServiceId(it) == first_service_id - 1) {
84 LastClientId(it) = last_client_id;
85 return;
86 }
87 }
88
89 path_map_.insert(std::make_pair(
90 first_client_id, PathRangeDescription(last_client_id, first_service_id)));
91 }
92
93 bool PathManager::HasPathsInRange(GLuint first_client_id,
94 GLuint last_client_id) const {
95 PathRangeMap::const_iterator it = path_map_.lower_bound(first_client_id);
96 if (it != path_map_.end() && (FirstClientId(it) == first_client_id ||
97 FirstClientId(it) <= last_client_id)) {
98 return true;
99 }
100 if (it == path_map_.begin()) {
101 return false;
102 }
103 --it;
104 return LastClientId(it) >= first_client_id;
105 }
106
107 bool PathManager::GetPath(GLuint client_id, GLuint* service_id) const {
108 PathRangeMap::const_iterator it = path_map_.lower_bound(client_id);
109 if (it != path_map_.end() && FirstClientId(it) == client_id) {
110 *service_id = FirstServiceId(it);
111 return true;
112 }
113 if (it == path_map_.begin()) {
114 return false;
115 }
116 --it;
117 if (LastClientId(it) < client_id) {
118 return false;
119 }
120
121 *service_id = FirstServiceId(it) + client_id - FirstClientId(it);
122
123 return true;
124 }
125
126 void PathManager::RemovePaths(GLuint first_client_id, GLuint last_client_id) {
127 PathRangeMap::iterator it = path_map_.lower_bound(first_client_id);
128 if (it == path_map_.end() || FirstClientId(it) != first_client_id) {
129 if (it != path_map_.begin()) {
130 --it;
131 if (LastClientId(it) < first_client_id) {
132 ++it;
133 }
134 }
135 }
136
137 while (it != path_map_.end() && FirstClientId(it) <= last_client_id) {
138 GLuint delete_first_client_id =
139 std::max(first_client_id, FirstClientId(it));
140 GLuint delete_last_client_id = std::min(last_client_id, LastClientId(it));
141 GLuint delete_first_service_id =
142 FirstServiceId(it) + delete_first_client_id - FirstClientId(it);
143 GLuint delete_range = delete_last_client_id - delete_first_client_id + 1;
144
145 callDeletePaths(delete_first_service_id, delete_range);
146
147 PathRangeMap::iterator current = it;
148 ++it;
149
150 GLuint current_last_client_id = LastClientId(current);
151
152 if (FirstClientId(current) < delete_first_client_id) {
153 LastClientId(current) = delete_first_client_id - 1;
154 } else {
155 path_map_.erase(current);
156 }
157
158 if (current_last_client_id > delete_last_client_id) {
159 path_map_.insert(std::make_pair(
160 delete_last_client_id + 1,
161 PathRangeDescription(current_last_client_id,
162 delete_first_service_id + delete_range)));
163 DCHECK(delete_last_client_id == last_client_id);
164 // This is necessarily the last range to check. Return early due to
165 // consistency. Iterator increment would skip the inserted range. The
166 // algorithm would work ok, but it looks weird.
167 return;
168 }
169 }
170 }
171
172 } // namespace gles2
173 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698