Edit

kc3-lang/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp

Branch :

  • Show log

    Commit

  • Author : Geoff Lang
    Date : 2016-07-15 13:01:24
    Hash : 73bd218e
    Message : Support virtualized contexts and transform feedback in Renderer11. Track buffer offets in the transform feedback object and dirty them when a buffer is bound. This fixes problems when a buffer is rebound at the same offset and maintains tracking between context switches. BUG=angleproject:1447 BUG=angleproject:1298 Change-Id: I2f890e3ad5edacab47f624a95a502615c86cc0c8 Reviewed-on: https://chromium-review.googlesource.com/360910 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>

  • src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
  • //
    // 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();
            }
        }
    }
    
    }