// // 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 &binding) { } void TransformFeedbackGL::bindIndexedBuffer(size_t index, const OffsetBindingPointer &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(binding.get()); if (binding.getSize() != 0) { mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast(index), bufferGL->getBufferID(), binding.getOffset(), binding.getSize()); } else { mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast(index), bufferGL->getBufferID()); } } else { mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast(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(); } } } }