1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
gpu / command_buffer / service / transform_feedback_manager.h [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GPU_COMMAND_BUFFER_SERVICE_TRANSFORM_FEEDBACK_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_TRANSFORM_FEEDBACK_MANAGER_H_
#include <unordered_map>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/indexed_buffer_binding_host.h"
#include "gpu/gpu_gles2_export.h"
namespace gpu {
namespace gles2 {
class Buffer;
class TransformFeedbackManager;
// Info about TransformFeedbacks currently in the system.
class GPU_GLES2_EXPORT TransformFeedback : public IndexedBufferBindingHost {
public:
TransformFeedback(TransformFeedbackManager* manager,
GLuint client_id,
GLuint service_id);
// All the following functions do state update and call the underlying GL
// function. All validations have been done already and the GL function is
// guaranteed to succeed.
void DoBindTransformFeedback(GLenum target,
TransformFeedback* last_bound_transform_feedback,
Buffer* bound_transform_feedback_buffer);
void DoBeginTransformFeedback(GLenum primitive_mode);
void DoEndTransformFeedback();
void DoPauseTransformFeedback();
void DoResumeTransformFeedback();
GLuint client_id() const {
return client_id_;
}
GLuint service_id() const {
return service_id_;
}
bool has_been_bound() const {
return has_been_bound_;
}
bool active() const {
return active_;
}
bool paused() const {
return paused_;
}
GLenum primitive_mode() const {
return primitive_mode_;
}
// Calculates the number of vertices that this draw call will write to the
// transform feedback buffer, plus the number of vertices that were previously
// written since the last call to BeginTransformFeedback (because vertices are
// written starting just after the last vertex written by the previous draw),
// plus |pending_vertices_drawn|. The pending vertices are used to iteratively
// validate and accumulate the number of vertices drawn for multiple draws.
// This is used to calculate whether there is enough space in the transform
// feedback buffers. Returns false on integer overflow.
bool GetVerticesNeededForDraw(GLenum mode,
GLsizei count,
GLsizei primcount,
GLsizei pending_vertices_drawn,
GLsizei* vertices_out) const;
// This must be called every time a transform feedback draw happens to keep
// track of how many vertices have been written to the transform feedback
// buffers.
void OnVerticesDrawn(GLsizei vertices_drawn);
private:
~TransformFeedback() override;
// The manager that owns this Buffer.
raw_ptr<TransformFeedbackManager> manager_;
GLuint client_id_;
GLuint service_id_;
bool has_been_bound_;
bool active_;
bool paused_;
GLenum primitive_mode_;
GLsizei vertices_drawn_;
};
// This class keeps tracks of the transform feedbacks and their states.
class GPU_GLES2_EXPORT TransformFeedbackManager {
public:
// In theory |needs_emulation| needs to be true on Desktop GL 4.1 or lower.
// However, we set it to true everywhere, not to trust drivers to handle
// out-of-bounds buffer accesses.
TransformFeedbackManager(GLuint max_transform_feedback_separate_attribs,
bool needs_emulation);
TransformFeedbackManager(const TransformFeedbackManager&) = delete;
TransformFeedbackManager& operator=(const TransformFeedbackManager&) = delete;
~TransformFeedbackManager();
void MarkContextLost() {
lost_context_ = true;
}
// Must call before destruction.
void Destroy();
// Creates a TransformFeedback from the given client/service IDs and
// insert it into the list.
TransformFeedback* CreateTransformFeedback(
GLuint client_id, GLuint service_id);
TransformFeedback* GetTransformFeedback(GLuint client_id);
// Removes a TransformFeedback info for the given client ID.
void RemoveTransformFeedback(GLuint client_id);
GLuint max_transform_feedback_separate_attribs() const {
return max_transform_feedback_separate_attribs_;
}
bool needs_emulation() const {
return needs_emulation_;
}
bool lost_context() const {
return lost_context_;
}
private:
// Info for each transform feedback in the system.
std::unordered_map<GLuint, scoped_refptr<TransformFeedback>>
transform_feedbacks_;
GLuint max_transform_feedback_separate_attribs_;
bool needs_emulation_;
bool lost_context_;
};
} // namespace gles2
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_TRANSFORM_FEEDBACK_MANAGER_H_