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
|
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// TransformFeedbackGL.cpp: Implements the class methods for TransformFeedbackGL.
#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
#include "common/debug.h"
#include "libANGLE/ContextState.h"
#include "libANGLE/renderer/gl/BufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
namespace rx
{
TransformFeedbackGL::TransformFeedbackGL(const gl::TransformFeedbackState &state,
const FunctionsGL *functions,
StateManagerGL *stateManager)
: TransformFeedbackImpl(state),
mFunctions(functions),
mStateManager(stateManager),
mTransformFeedbackID(0),
mIsActive(false),
mIsPaused(false)
{
mFunctions->genTransformFeedbacks(1, &mTransformFeedbackID);
}
TransformFeedbackGL::~TransformFeedbackGL()
{
mStateManager->deleteTransformFeedback(mTransformFeedbackID);
mTransformFeedbackID = 0;
}
void TransformFeedbackGL::begin(GLenum primitiveMode)
{
// Do not begin directly, StateManagerGL will handle beginning and resuming transform feedback.
}
void TransformFeedbackGL::end()
{
syncActiveState(false, GL_NONE);
}
void TransformFeedbackGL::pause()
{
syncPausedState(true);
}
void TransformFeedbackGL::resume()
{
// Do not resume directly, StateManagerGL will handle beginning and resuming transform feedback.
}
void TransformFeedbackGL::bindGenericBuffer(const BindingPointer<gl::Buffer> &binding)
{
}
void TransformFeedbackGL::bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding)
{
// Directly bind buffer (not through the StateManager methods) because the buffer bindings are
// tracked per transform feedback object
mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
if (binding.get() != nullptr)
{
const BufferGL *bufferGL = GetImplAs<BufferGL>(binding.get());
if (binding.getSize() != 0)
{
mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
bufferGL->getBufferID(), binding.getOffset(),
binding.getSize());
}
else
{
mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
bufferGL->getBufferID());
}
}
else
{
mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), 0);
}
}
GLuint TransformFeedbackGL::getTransformFeedbackID() const
{
return mTransformFeedbackID;
}
void TransformFeedbackGL::syncActiveState(bool active, GLenum primitiveMode) const
{
if (mIsActive != active)
{
mIsActive = active;
mIsPaused = false;
mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
if (mIsActive)
{
mFunctions->beginTransformFeedback(primitiveMode);
}
else
{
mFunctions->endTransformFeedback();
}
}
}
void TransformFeedbackGL::syncPausedState(bool paused) const
{
if (mIsActive && mIsPaused != paused)
{
mIsPaused = paused;
mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
if (mIsPaused)
{
mFunctions->pauseTransformFeedback();
}
else
{
mFunctions->resumeTransformFeedback();
}
}
}
}
|