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
gpu / command_buffer / service / indexed_buffer_binding_host.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_INDEXED_BUFFER_BINDING_HOST_H_
#define GPU_COMMAND_BUFFER_SERVICE_INDEXED_BUFFER_BINDING_HOST_H_
#include <vector>
#include "base/memory/ref_counted.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/gpu_gles2_export.h"
namespace gpu {
namespace gles2 {
class Buffer;
// This is a base class for indexed buffer bindings tracking.
// TransformFeedback and Program should inherit from this base class,
// for tracking indexed TRANSFORM_FEEDBACK_BUFFER / UNIFORM_BUFFER bindings.
class GPU_GLES2_EXPORT IndexedBufferBindingHost
: public base::RefCounted<IndexedBufferBindingHost> {
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.
IndexedBufferBindingHost(uint32_t max_bindings,
GLenum target,
bool needs_emulation,
bool round_down_uniform_bind_buffer_range_size);
// The following two 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 DoBindBufferBase(GLuint index, Buffer* buffer);
void DoBindBufferRange(GLuint index,
Buffer* buffer,
GLintptr offset,
GLsizeiptr size);
// This is called on the active host when glBufferData is called and buffer
// size might change.
void OnBufferData(Buffer* buffer);
void RemoveBoundBuffer(GLenum target,
Buffer* buffer,
Buffer* target_generic_bound_buffer,
bool have_context);
void SetIsBound(bool bound);
Buffer* GetBufferBinding(GLuint index) const;
// Returns |size| set by glBindBufferRange; 0 if set by glBindBufferBase.
GLsizeiptr GetBufferSize(GLuint index) const;
// For glBindBufferBase, return the actual buffer size when this function is
// called, not when glBindBufferBase is called.
// For glBindBufferRange, return the |size| set by glBindBufferRange minus
// the range that's beyond the buffer.
GLsizeiptr GetEffectiveBufferSize(GLuint index) const;
GLintptr GetBufferStart(GLuint index) const;
// This is used only for UNIFORM_BUFFER bindings in context switching.
void RestoreBindings(IndexedBufferBindingHost* prev);
// Check if |buffer| is currently bound to one of the indexed binding point
// from 0 to |used_binding_count| - 1.
bool UsesBuffer(size_t used_binding_count, const Buffer* buffer) const;
protected:
friend class base::RefCounted<IndexedBufferBindingHost>;
virtual ~IndexedBufferBindingHost();
// Whether this object is currently bound into the context.
bool is_bound_;
// Whether or not to call Buffer::OnBind/OnUnbind whenever bindings change.
// This is only necessary for WebGL contexts to implement
// https://crbug.com/696345
bool do_buffer_refcounting_;
private:
enum class IndexedBufferBindingType {
kBindBufferBase,
kBindBufferRange,
kBindBufferNone
};
struct IndexedBufferBinding {
IndexedBufferBindingType type;
scoped_refptr<Buffer> buffer;
// The following fields are only used if |type| is kBindBufferRange.
GLintptr offset;
GLsizeiptr size;
// The full buffer size at the last successful glBindBufferRange call.
GLsizeiptr effective_full_buffer_size;
IndexedBufferBinding();
IndexedBufferBinding(const IndexedBufferBinding& other);
~IndexedBufferBinding();
bool operator==(const IndexedBufferBinding& other) const;
void SetBindBufferBase(Buffer* _buffer);
void SetBindBufferRange(
Buffer* _buffer, GLintptr _offset, GLsizeiptr _size);
void Reset();
};
// This is called when |needs_emulation_| is true, where the range
// (offset + size) can't go beyond the buffer's size.
static void DoAdjustedBindBufferRange(
GLenum target,
GLuint index,
GLuint service_id,
GLintptr offset,
GLsizeiptr size,
GLsizeiptr full_buffer_size,
bool round_down_uniform_bind_buffer_range_size);
void UpdateMaxNonNullBindingIndex(size_t changed_index);
std::vector<IndexedBufferBinding> buffer_bindings_;
bool needs_emulation_;
bool round_down_uniform_bind_buffer_range_size_;
// This is used for optimization purpose in context switching.
size_t max_non_null_binding_index_plus_one_;
// The GL binding point that this host manages
// (e.g. GL_TRANSFORM_FEEDBACK_BUFFER).
GLenum target_;
};
} // namespace gles2
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_INDEXED_BUFFER_BINDING_HOST_H_