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); } }
GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding) { Buffer *buffer = binding.get(); if (buffer) { if (binding.getSize() == 0) return static_cast<GLsizeiptr>(buffer->getSize()); angle::CheckedNumeric<GLintptr> offset = binding.getOffset(); angle::CheckedNumeric<GLsizeiptr> size = binding.getSize(); angle::CheckedNumeric<GLsizeiptr> bufferSize = buffer->getSize(); auto end = offset + size; auto clampedSize = size; auto difference = end - bufferSize; if (!difference.IsValid()) { return 0; } if (difference.ValueOrDie() > 0) { clampedSize = size - difference; } return clampedSize.ValueOrDefault(0); } else { return 0; } }