// allocate an uninitialized buffer of the specified size // and copy the initialization range into the start of the buffer buffer(std::size_t const size, span<char const> initialize) : buffer(size) { TORRENT_ASSERT(initialize.size() <= size); if (!initialize.empty()) { std::memcpy(m_begin, initialize.data(), (std::min)(initialize.size(), size)); } }
void GLVertexBuffer::upload(span<const byte> a_data) { assert(GLStateBuffer::isBegun()); assert(m_initialized); if (!a_data.empty()) { glBindBuffer(GLenum(m_bufferType), m_id); glBufferData(GLenum(m_bufferType), a_data.length_bytes(), a_data.data(), GLenum(m_drawUsage)); } }
// this has to be thread safe and atomic. i.e. on posix systems it has to be // turned into a series of pread() calls std::int64_t file::readv(std::int64_t file_offset, span<iovec_t const> bufs , error_code& ec, open_mode_t flags) { if (m_file_handle == INVALID_HANDLE_VALUE) { #ifdef TORRENT_WINDOWS ec = error_code(ERROR_INVALID_HANDLE, system_category()); #else ec = error_code(boost::system::errc::bad_file_descriptor, generic_category()); #endif return -1; } TORRENT_ASSERT((m_open_mode & open_mode::rw_mask) == open_mode::read_only || (m_open_mode & open_mode::rw_mask) == open_mode::read_write); TORRENT_ASSERT(!bufs.empty()); TORRENT_ASSERT(is_open()); #if TORRENT_USE_PREADV TORRENT_UNUSED(flags); std::int64_t ret = iov(&::preadv, native_handle(), file_offset, bufs, ec); #else // there's no point in coalescing single buffer writes if (bufs.size() == 1) { flags &= ~open_mode::coalesce_buffers; } iovec_t tmp; span<iovec_t const> tmp_bufs = bufs; if (flags & open_mode::coalesce_buffers) { if (!coalesce_read_buffers(tmp_bufs, tmp)) // ok, that failed, don't coalesce this read flags &= ~open_mode::coalesce_buffers; } #if TORRENT_USE_PREAD std::int64_t ret = iov(&::pread, native_handle(), file_offset, tmp_bufs, ec); #else std::int64_t ret = iov(&::read, native_handle(), file_offset, tmp_bufs, ec); #endif if (flags & open_mode::coalesce_buffers) coalesce_read_buffers_end(bufs , tmp.data(), !ec); #endif return ret; }
void GLVertexBuffer::setVertexAttributes(span<const VertexAttribute> a_attributes) { assert(GLStateBuffer::isBegun()); assert(m_initialized); assert(!a_attributes.empty()); uint64 offset = 0; uint stride = 0; if (a_attributes.size() == 1) stride = 0; else { for (uint i = 0; i < a_attributes.size(); ++i) { const VertexAttribute& attribute = a_attributes[i]; stride += attribute.numElements * (attribute.format == VertexAttribute::EFormat::UNSIGNED_BYTE ? 1 : 4); } } for (uint i = 0; i < a_attributes.size(); ++i) { const VertexAttribute& attribute = a_attributes[i]; const bool isFloatType = (attribute.format == VertexAttribute::EFormat::FLOAT) || attribute.normalize; const uint dataSize = ((attribute.format == VertexAttribute::EFormat::UNSIGNED_BYTE) ? 1 : 4) * attribute.numElements; glBindBuffer(GLenum(m_bufferType), m_id); if (isFloatType) glVertexAttribPointer(attribute.attributeIndex, attribute.numElements, GLenum(attribute.format), attribute.normalize, stride, rcast<GLvoid*>(offset)); else glVertexAttribIPointer(attribute.attributeIndex, attribute.numElements, GLenum(attribute.format), stride, rcast<GLvoid*>(offset)); glEnableVertexAttribArray(attribute.attributeIndex); offset += dataSize; } }
// This has to be thread safe, i.e. atomic. // that means, on posix this has to be turned into a series of // pwrite() calls std::int64_t file::writev(std::int64_t file_offset, span<iovec_t const> bufs , error_code& ec, open_mode_t flags) { if (m_file_handle == INVALID_HANDLE_VALUE) { #ifdef TORRENT_WINDOWS ec = error_code(ERROR_INVALID_HANDLE, system_category()); #else ec = error_code(boost::system::errc::bad_file_descriptor, generic_category()); #endif return -1; } TORRENT_ASSERT((m_open_mode & open_mode::rw_mask) == open_mode::write_only || (m_open_mode & open_mode::rw_mask) == open_mode::read_write); TORRENT_ASSERT(!bufs.empty()); TORRENT_ASSERT(is_open()); ec.clear(); #if TORRENT_USE_PREADV TORRENT_UNUSED(flags); std::int64_t ret = iov(&::pwritev, native_handle(), file_offset, bufs, ec); #else // there's no point in coalescing single buffer writes if (bufs.size() == 1) { flags &= ~open_mode::coalesce_buffers; } iovec_t tmp; if (flags & open_mode::coalesce_buffers) { if (!coalesce_write_buffers(bufs, tmp)) // ok, that failed, don't coalesce writes flags &= ~open_mode::coalesce_buffers; } #if TORRENT_USE_PREAD std::int64_t ret = iov(&::pwrite, native_handle(), file_offset, bufs, ec); #else std::int64_t ret = iov(&::write, native_handle(), file_offset, bufs, ec); #endif if (flags & open_mode::coalesce_buffers) delete[] tmp.data(); #endif #if TORRENT_USE_FDATASYNC \ && !defined F_NOCACHE && \ !defined DIRECTIO_ON if (m_open_mode & open_mode::no_cache) { if (::fdatasync(native_handle()) != 0 && errno != EINVAL && errno != ENOSYS) { ec.assign(errno, system_category()); } } #endif return ret; }