Skip to content

Commit

Permalink
Fixed staging buffers in WebGL (fix #412)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Oct 3, 2023
1 parent a346b2a commit e230e55
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Common/interface/StringTools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ inline size_t CountFloatNumberChars(const char* Str)
/// For each chunk, calls the Handler.
///
/// \note This function is used to split long messages on Android to avoid
/// trunction in logcat.
/// truncation in logcat.
template <typename IterType, typename HandlerType>
void SplitLongString(IterType Start, IterType End, size_t MaxChunkLen, size_t NewLineSearchLen, HandlerType&& Handler)
{
Expand Down
7 changes: 7 additions & 0 deletions Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

#pragma once

#include <vector>

#include "EngineGLImplTraits.hpp"
#include "BufferBase.hpp"
#include "BufferViewGLImpl.hpp" // Required by BufferBase
Expand Down Expand Up @@ -92,6 +94,11 @@ class BufferGLImpl final : public BufferBase<EngineGLImplTraits>, public AsyncWr
GLObjectWrappers::GLBufferObj m_GlBuffer;
const Uint32 m_BindTarget;
const GLenum m_GLUsageHint;

#if PLATFORM_EMSCRIPTEN
// Used for devices that don't support glMapBufferRange (currently, Emscripten)
std::vector<Uint8> m_MappedData;
#endif
};

void BufferGLImpl::BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLState)
Expand Down
3 changes: 2 additions & 1 deletion Graphics/GraphicsEngineOpenGL/include/pch.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Diligent Graphics LLC
* Copyright 2019-2023 Diligent Graphics LLC
* Copyright 2015-2019 Egor Yusov
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -111,6 +111,7 @@

#elif PLATFORM_EMSCRIPTEN

# include <webgl/webgl2.h>
# include <GLES3/gl32.h>
# include "GLStubsEmscripten.h"

Expand Down
22 changes: 21 additions & 1 deletion Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Diligent Graphics LLC
* Copyright 2019-2023 Diligent Graphics LLC
* Copyright 2015-2019 Egor Yusov
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -277,6 +277,18 @@ void BufferGLImpl::MapRange(GLContextState& CtxState, MAP_TYPE MapType, Uint32 M
constexpr bool ResetVAO = true;
CtxState.BindBuffer(m_BindTarget, m_GlBuffer, ResetVAO);

#if PLATFORM_EMSCRIPTEN
// Emscripten does not support mapping buffers for reading
if (MapType == MAP_READ)
{
m_MappedData.resize(static_cast<size_t>(Length));
glGetBufferSubData(m_BindTarget, StaticCast<GLintptr>(Offset), StaticCast<GLsizeiptr>(Length), m_MappedData.data());
CHECK_GL_ERROR("glGetBufferSubData() failed");
pMappedData = m_MappedData.data();
return;
}
#endif

// !!!WARNING!!! GL_MAP_UNSYNCHRONIZED_BIT is not the same thing as MAP_FLAG_DO_NOT_WAIT.
// If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize operations
// on the buffer. This does not mean that map will fail if the buffer still in use. It is thus
Expand Down Expand Up @@ -328,6 +340,14 @@ void BufferGLImpl::MapRange(GLContextState& CtxState, MAP_TYPE MapType, Uint32 M

void BufferGLImpl::Unmap(GLContextState& CtxState)
{
#if PLATFORM_EMSCRIPTEN
if (!m_MappedData.empty())
{
m_MappedData.clear();
return;
}
#endif

constexpr bool ResetVAO = true;
CtxState.BindBuffer(m_BindTarget, m_GlBuffer, ResetVAO);
auto Result = glUnmapBuffer(m_BindTarget);
Expand Down

0 comments on commit e230e55

Please sign in to comment.