1 //
2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "libANGLE/TransformFeedback.h"
8
9 #include "libANGLE/Buffer.h"
10 #include "libANGLE/Caps.h"
11 #include "libANGLE/ContextState.h"
12 #include "libANGLE/Program.h"
13 #include "libANGLE/renderer/GLImplFactory.h"
14 #include "libANGLE/renderer/TransformFeedbackImpl.h"
15
16 namespace gl
17 {
18
TransformFeedbackState(size_t maxIndexedBuffers)19 TransformFeedbackState::TransformFeedbackState(size_t maxIndexedBuffers)
20 : mLabel(),
21 mActive(false),
22 mPrimitiveMode(GL_NONE),
23 mPaused(false),
24 mProgram(nullptr),
25 mGenericBuffer(),
26 mIndexedBuffers(maxIndexedBuffers)
27 {
28 }
29
~TransformFeedbackState()30 TransformFeedbackState::~TransformFeedbackState()
31 {
32 }
33
getGenericBuffer() const34 const BindingPointer<Buffer> &TransformFeedbackState::getGenericBuffer() const
35 {
36 return mGenericBuffer;
37 }
38
getIndexedBuffer(size_t idx) const39 const OffsetBindingPointer<Buffer> &TransformFeedbackState::getIndexedBuffer(size_t idx) const
40 {
41 return mIndexedBuffers[idx];
42 }
43
getIndexedBuffers() const44 const std::vector<OffsetBindingPointer<Buffer>> &TransformFeedbackState::getIndexedBuffers() const
45 {
46 return mIndexedBuffers;
47 }
48
TransformFeedback(rx::GLImplFactory * implFactory,GLuint id,const Caps & caps)49 TransformFeedback::TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, const Caps &caps)
50 : RefCountObject(id),
51 mState(caps.maxTransformFeedbackSeparateAttributes),
52 mImplementation(implFactory->createTransformFeedback(mState))
53 {
54 ASSERT(mImplementation != nullptr);
55 }
56
onDestroy(const Context * context)57 Error TransformFeedback::onDestroy(const Context *context)
58 {
59 if (mState.mProgram)
60 {
61 mState.mProgram->release(context);
62 mState.mProgram = nullptr;
63 }
64
65 ASSERT(!mState.mProgram);
66 mState.mGenericBuffer.set(context, nullptr);
67 for (size_t i = 0; i < mState.mIndexedBuffers.size(); i++)
68 {
69 mState.mIndexedBuffers[i].set(context, nullptr);
70 }
71
72 return NoError();
73 }
74
~TransformFeedback()75 TransformFeedback::~TransformFeedback()
76 {
77 SafeDelete(mImplementation);
78 }
79
setLabel(const std::string & label)80 void TransformFeedback::setLabel(const std::string &label)
81 {
82 mState.mLabel = label;
83 }
84
getLabel() const85 const std::string &TransformFeedback::getLabel() const
86 {
87 return mState.mLabel;
88 }
89
begin(const Context * context,GLenum primitiveMode,Program * program)90 void TransformFeedback::begin(const Context *context, GLenum primitiveMode, Program *program)
91 {
92 mState.mActive = true;
93 mState.mPrimitiveMode = primitiveMode;
94 mState.mPaused = false;
95 mImplementation->begin(primitiveMode);
96 bindProgram(context, program);
97 }
98
end(const Context * context)99 void TransformFeedback::end(const Context *context)
100 {
101 mState.mActive = false;
102 mState.mPrimitiveMode = GL_NONE;
103 mState.mPaused = false;
104 mImplementation->end();
105 if (mState.mProgram)
106 {
107 mState.mProgram->release(context);
108 mState.mProgram = nullptr;
109 }
110 }
111
pause()112 void TransformFeedback::pause()
113 {
114 mState.mPaused = true;
115 mImplementation->pause();
116 }
117
resume()118 void TransformFeedback::resume()
119 {
120 mState.mPaused = false;
121 mImplementation->resume();
122 }
123
isActive() const124 bool TransformFeedback::isActive() const
125 {
126 return mState.mActive;
127 }
128
isPaused() const129 bool TransformFeedback::isPaused() const
130 {
131 return mState.mPaused;
132 }
133
getPrimitiveMode() const134 GLenum TransformFeedback::getPrimitiveMode() const
135 {
136 return mState.mPrimitiveMode;
137 }
138
bindProgram(const Context * context,Program * program)139 void TransformFeedback::bindProgram(const Context *context, Program *program)
140 {
141 if (mState.mProgram != program)
142 {
143 if (mState.mProgram != nullptr)
144 {
145 mState.mProgram->release(context);
146 }
147 mState.mProgram = program;
148 if (mState.mProgram != nullptr)
149 {
150 mState.mProgram->addRef();
151 }
152 }
153 }
154
hasBoundProgram(GLuint program) const155 bool TransformFeedback::hasBoundProgram(GLuint program) const
156 {
157 return mState.mProgram != nullptr && mState.mProgram->id() == program;
158 }
159
bindGenericBuffer(const Context * context,Buffer * buffer)160 void TransformFeedback::bindGenericBuffer(const Context *context, Buffer *buffer)
161 {
162 mState.mGenericBuffer.set(context, buffer);
163 mImplementation->bindGenericBuffer(mState.mGenericBuffer);
164 }
165
detachBuffer(const Context * context,GLuint bufferName)166 void TransformFeedback::detachBuffer(const Context *context, GLuint bufferName)
167 {
168 for (size_t index = 0; index < mState.mIndexedBuffers.size(); index++)
169 {
170 if (mState.mIndexedBuffers[index].id() == bufferName)
171 {
172 mState.mIndexedBuffers[index].set(context, nullptr);
173 mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]);
174 }
175 }
176
177 if (mState.mGenericBuffer.id() == bufferName)
178 {
179 mState.mGenericBuffer.set(context, nullptr);
180 mImplementation->bindGenericBuffer(mState.mGenericBuffer);
181 }
182 }
183
getGenericBuffer() const184 const BindingPointer<Buffer> &TransformFeedback::getGenericBuffer() const
185 {
186 return mState.mGenericBuffer;
187 }
188
bindIndexedBuffer(const Context * context,size_t index,Buffer * buffer,size_t offset,size_t size)189 void TransformFeedback::bindIndexedBuffer(const Context *context,
190 size_t index,
191 Buffer *buffer,
192 size_t offset,
193 size_t size)
194 {
195 ASSERT(index < mState.mIndexedBuffers.size());
196 mState.mIndexedBuffers[index].set(context, buffer, offset, size);
197 mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]);
198 }
199
getIndexedBuffer(size_t index) const200 const OffsetBindingPointer<Buffer> &TransformFeedback::getIndexedBuffer(size_t index) const
201 {
202 ASSERT(index < mState.mIndexedBuffers.size());
203 return mState.mIndexedBuffers[index];
204 }
205
getIndexedBufferCount() const206 size_t TransformFeedback::getIndexedBufferCount() const
207 {
208 return mState.mIndexedBuffers.size();
209 }
210
getImplementation()211 rx::TransformFeedbackImpl *TransformFeedback::getImplementation()
212 {
213 return mImplementation;
214 }
215
getImplementation() const216 const rx::TransformFeedbackImpl *TransformFeedback::getImplementation() const
217 {
218 return mImplementation;
219 }
220
221 }
222