Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/drape
diff options
context:
space:
mode:
Diffstat (limited to 'drape')
-rw-r--r--drape/CMakeLists.txt4
-rw-r--r--drape/data_buffer.cpp28
-rw-r--r--drape/data_buffer.hpp17
-rw-r--r--drape/data_buffer_impl.hpp103
-rw-r--r--drape/drape_common.pri4
-rw-r--r--drape/drape_global.hpp9
-rw-r--r--drape/drape_tests/font_texture_tests.cpp109
-rw-r--r--drape/drape_tests/glfunctions.cpp4
-rw-r--r--drape/drape_tests/memory_comparer.hpp35
-rw-r--r--drape/framebuffer.cpp105
-rw-r--r--drape/framebuffer.hpp37
-rw-r--r--drape/glIncludes.hpp7
-rw-r--r--drape/glconstants.cpp9
-rw-r--r--drape/glconstants.hpp1
-rw-r--r--drape/glextensions_list.cpp158
-rw-r--r--drape/glextensions_list.hpp28
-rw-r--r--drape/glfunctions.cpp693
-rw-r--r--drape/glfunctions.hpp72
-rw-r--r--drape/gpu_buffer.cpp81
-rw-r--r--drape/gpu_buffer.hpp14
-rw-r--r--drape/gpu_program_manager.cpp3
-rw-r--r--drape/hw_texture.cpp56
-rw-r--r--drape/hw_texture_ios.mm1
-rw-r--r--drape/support_manager.cpp2
-rw-r--r--drape/texture.cpp35
-rw-r--r--drape/texture.hpp10
-rw-r--r--drape/vertex_array_buffer.cpp135
-rw-r--r--drape/vertex_array_buffer.hpp46
-rw-r--r--drape/viewport.cpp25
-rw-r--r--drape/viewport.hpp31
30 files changed, 945 insertions, 917 deletions
diff --git a/drape/CMakeLists.txt b/drape/CMakeLists.txt
index bfff605500..4355682b36 100644
--- a/drape/CMakeLists.txt
+++ b/drape/CMakeLists.txt
@@ -42,6 +42,8 @@ set(
${DRAPE_ROOT}/dynamic_texture.hpp
${DRAPE_ROOT}/font_texture.cpp
${DRAPE_ROOT}/font_texture.hpp
+ ${DRAPE_ROOT}/framebuffer.cpp
+ ${DRAPE_ROOT}/framebuffer.hpp
${DRAPE_ROOT}/glconstants.cpp
${DRAPE_ROOT}/glconstants.hpp
${DRAPE_ROOT}/glextensions_list.cpp
@@ -111,6 +113,8 @@ set(
${DRAPE_ROOT}/utils/vertex_decl.hpp
${DRAPE_ROOT}/vertex_array_buffer.cpp
${DRAPE_ROOT}/vertex_array_buffer.hpp
+ ${DRAPE_ROOT}/viewport.cpp
+ ${DRAPE_ROOT}/viewport.hpp
${DRAPE_ROOT}/visual_scale.hpp
)
diff --git a/drape/data_buffer.cpp b/drape/data_buffer.cpp
index fccc4fa7f9..672741fa9d 100644
--- a/drape/data_buffer.cpp
+++ b/drape/data_buffer.cpp
@@ -3,7 +3,6 @@
namespace dp
{
-
DataBuffer::DataBuffer(uint8_t elementSize, uint32_t capacity)
: m_impl(make_unique_dp<CpuBufferImpl>(elementSize, capacity))
{
@@ -17,30 +16,31 @@ ref_ptr<DataBufferBase> DataBuffer::GetBuffer() const
void DataBuffer::MoveToGPU(GPUBuffer::Target target)
{
- // if currentSize is 0 buffer hasn't been filled on preparation stage, let it be filled further
+ // If currentSize is 0 buffer hasn't been filled on preparation stage, let it be filled further.
uint32_t const currentSize = m_impl->GetCurrentSize();
if (currentSize != 0)
- m_impl = make_unique_dp<GpuBufferImpl>(target, m_impl->Data(),m_impl->GetElementSize(), currentSize);
+ {
+ m_impl = make_unique_dp<GpuBufferImpl>(target, m_impl->Data(), m_impl->GetElementSize(),
+ currentSize);
+ }
else
- m_impl = make_unique_dp<GpuBufferImpl>(target, nullptr, m_impl->GetElementSize(), m_impl->GetAvailableSize());
+ {
+ m_impl = make_unique_dp<GpuBufferImpl>(target, nullptr, m_impl->GetElementSize(),
+ m_impl->GetAvailableSize());
+ }
}
-
-DataBufferMapper::DataBufferMapper(ref_ptr<DataBuffer> buffer)
+DataBufferMapper::DataBufferMapper(ref_ptr<DataBuffer> buffer, uint32_t elementOffset,
+ uint32_t elementCount)
: m_buffer(buffer)
{
m_buffer->GetBuffer()->Bind();
- m_ptr = m_buffer->GetBuffer()->Map();
-}
-
-DataBufferMapper::~DataBufferMapper()
-{
- m_buffer->GetBuffer()->Unmap();
+ m_ptr = m_buffer->GetBuffer()->Map(elementOffset, elementCount);
}
+DataBufferMapper::~DataBufferMapper() { m_buffer->GetBuffer()->Unmap(); }
void DataBufferMapper::UpdateData(void const * data, uint32_t elementOffset, uint32_t elementCount)
{
m_buffer->GetBuffer()->UpdateData(m_ptr, data, elementOffset, elementCount);
}
-
-}
+} // namespace dp
diff --git a/drape/data_buffer.hpp b/drape/data_buffer.hpp
index 0c82228449..15871a0326 100644
--- a/drape/data_buffer.hpp
+++ b/drape/data_buffer.hpp
@@ -1,16 +1,14 @@
#pragma once
-#include "drape/pointers.hpp"
#include "drape/gpu_buffer.hpp"
+#include "drape/pointers.hpp"
namespace dp
{
-
class DataBufferBase
{
public:
virtual ~DataBufferBase() {}
-
virtual uint32_t GetCapacity() const = 0;
virtual uint32_t GetCurrentSize() const = 0;
virtual uint32_t GetAvailableSize() const = 0;
@@ -19,14 +17,14 @@ public:
virtual void const * Data() const = 0;
virtual void UploadData(void const * data, uint32_t elementCount) = 0;
- virtual void UpdateData(void * destPtr, void const * srcPtr, uint32_t elementOffset, uint32_t elementCount) = 0;
+ virtual void UpdateData(void * destPtr, void const * srcPtr, uint32_t elementOffset,
+ uint32_t elementCount) = 0;
virtual void Bind() = 0;
- virtual void * Map() = 0;
+ virtual void * Map(uint32_t elementOffset, uint32_t elementCount) = 0;
virtual void Unmap() = 0;
};
-
class DataBuffer
{
public:
@@ -39,11 +37,10 @@ private:
drape_ptr<DataBufferBase> m_impl;
};
-
class DataBufferMapper
{
public:
- DataBufferMapper(ref_ptr<DataBuffer> buffer);
+ DataBufferMapper(ref_ptr<DataBuffer> buffer, uint32_t elementOffset, uint32_t elementCount);
~DataBufferMapper();
void UpdateData(void const * data, uint32_t elementOffset, uint32_t elementCount);
@@ -52,6 +49,4 @@ private:
ref_ptr<DataBuffer> m_buffer;
void * m_ptr;
};
-
-} // namespace dp
-
+} // namespace dp
diff --git a/drape/data_buffer_impl.hpp b/drape/data_buffer_impl.hpp
index 562e9a0913..1d46204a55 100644
--- a/drape/data_buffer_impl.hpp
+++ b/drape/data_buffer_impl.hpp
@@ -1,65 +1,40 @@
#pragma once
-#include "data_buffer.hpp"
-#include "cpu_buffer.hpp"
-#include "gpu_buffer.hpp"
+#include "drape/cpu_buffer.hpp"
+#include "drape/data_buffer.hpp"
+#include "drape/gpu_buffer.hpp"
+
#include "std/utility.hpp"
namespace dp
{
-
-/// generic implementation of data buffer
+// Generic implementation of data buffer.
template <typename TBuffer>
class DataBufferImpl : public DataBufferBase
{
public:
- template<typename... Args> DataBufferImpl(Args&&... params)
- : m_buffer(make_unique_dp<TBuffer>(forward<Args>(params)...))
- {
- }
-
- uint32_t GetCapacity() const override
- {
- return m_buffer->GetCapacity();
- }
-
- uint32_t GetCurrentSize() const override
- {
- return m_buffer->GetCurrentSize();
- }
-
- uint32_t GetAvailableSize() const override
- {
- return m_buffer->GetAvailableSize();
- }
-
- uint8_t GetElementSize() const override
- {
- return m_buffer->GetElementSize();
- }
-
- void Seek(uint32_t elementNumber) override
- {
- m_buffer->Seek(elementNumber);
- }
+ template <typename... Args>
+ DataBufferImpl(Args &&... params) : m_buffer(make_unique_dp<TBuffer>(forward<Args>(params)...))
+ {}
+ uint32_t GetCapacity() const override { return m_buffer->GetCapacity(); }
+ uint32_t GetCurrentSize() const override { return m_buffer->GetCurrentSize(); }
+ uint32_t GetAvailableSize() const override { return m_buffer->GetAvailableSize(); }
+ uint8_t GetElementSize() const override { return m_buffer->GetElementSize(); }
+ void Seek(uint32_t elementNumber) override { m_buffer->Seek(elementNumber); }
protected:
drape_ptr<TBuffer> m_buffer;
};
-/// CPU implementation of data buffer
+// CPU implementation of data buffer.
class CpuBufferImpl : public DataBufferImpl<CPUBuffer>
{
public:
- template<typename... Args> CpuBufferImpl(Args&&... params)
- : DataBufferImpl(forward<Args>(params)...)
+ template <typename... Args>
+ CpuBufferImpl(Args &&... params) : DataBufferImpl(forward<Args>(params)...)
{}
- void const * Data() const override
- {
- return m_buffer->Data();
- }
-
+ void const * Data() const override { return m_buffer->Data(); }
void UploadData(void const * data, uint32_t elementCount) override
{
m_buffer->UploadData(data, elementCount);
@@ -67,34 +42,28 @@ public:
m_buffer->Seek(newOffset);
}
- void UpdateData(void * destPtr, void const * srcPtr, uint32_t elementOffset, uint32_t elementCount) override
+ void UpdateData(void * destPtr, void const * srcPtr, uint32_t elementOffset,
+ uint32_t elementCount) override
{
ASSERT(false, ("Data updating is unavailable for CPU buffer"));
}
- void Bind() override
- {
- ASSERT(false, ("Binding is unavailable for CPU buffer"));
- }
-
- void * Map() override
+ void Bind() override { ASSERT(false, ("Binding is unavailable for CPU buffer")); }
+ void * Map(uint32_t elementOffset, uint32_t elementCount) override
{
ASSERT(false, ("Mapping is unavailable for CPU buffer"));
return nullptr;
}
- void Unmap() override
- {
- ASSERT(false, ("Unmapping is unavailable for CPU buffer"));
- }
+ void Unmap() override { ASSERT(false, ("Unmapping is unavailable for CPU buffer")); }
};
-/// GPU implementation of data buffer
+// GPU implementation of data buffer.
class GpuBufferImpl : public DataBufferImpl<GPUBuffer>
{
public:
- template<typename... Args> GpuBufferImpl(Args&&... params)
- : DataBufferImpl(forward<Args>(params)...)
+ template <typename... Args>
+ GpuBufferImpl(Args &&... params) : DataBufferImpl(forward<Args>(params)...)
{}
void const * Data() const override
@@ -108,25 +77,17 @@ public:
m_buffer->UploadData(data, elementCount);
}
- void UpdateData(void * destPtr, void const * srcPtr, uint32_t elementOffset, uint32_t elementCount) override
+ void UpdateData(void * destPtr, void const * srcPtr, uint32_t elementOffset,
+ uint32_t elementCount) override
{
m_buffer->UpdateData(destPtr, srcPtr, elementOffset, elementCount);
}
- void Bind() override
- {
- m_buffer->Bind();
- }
-
- void * Map() override
+ void Bind() override { m_buffer->Bind(); }
+ void * Map(uint32_t elementOffset, uint32_t elementCount) override
{
- return m_buffer->Map();
- }
-
- void Unmap() override
- {
- return m_buffer->Unmap();
+ return m_buffer->Map(elementOffset, elementCount);
}
+ void Unmap() override { return m_buffer->Unmap(); }
};
-
-} // namespace dp
+} // namespace dp
diff --git a/drape/drape_common.pri b/drape/drape_common.pri
index fa68b27b05..2511103f47 100644
--- a/drape/drape_common.pri
+++ b/drape/drape_common.pri
@@ -13,6 +13,7 @@ SOURCES += \
$$DRAPE_DIR/data_buffer.cpp \
$$DRAPE_DIR/debug_rect_renderer.cpp \
$$DRAPE_DIR/font_texture.cpp \
+ $$DRAPE_DIR/framebuffer.cpp \
$$DRAPE_DIR/glconstants.cpp \
$$DRAPE_DIR/glextensions_list.cpp \
$$DRAPE_DIR/glstate.cpp \
@@ -44,6 +45,7 @@ SOURCES += \
$$DRAPE_DIR/utils/projection.cpp \
$$DRAPE_DIR/utils/vertex_decl.cpp \
$$DRAPE_DIR/vertex_array_buffer.cpp \
+ $$DRAPE_DIR/viewport.cpp \
HEADERS += \
$$DRAPE_DIR/attribute_buffer_mutator.hpp \
@@ -63,6 +65,7 @@ HEADERS += \
$$DRAPE_DIR/drape_global.hpp \
$$DRAPE_DIR/dynamic_texture.hpp \
$$DRAPE_DIR/font_texture.hpp \
+ $$DRAPE_DIR/framebuffer.hpp \
$$DRAPE_DIR/glconstants.hpp \
$$DRAPE_DIR/glextensions_list.hpp \
$$DRAPE_DIR/glfunctions.hpp \
@@ -101,6 +104,7 @@ HEADERS += \
$$DRAPE_DIR/utils/projection.hpp \
$$DRAPE_DIR/utils/vertex_decl.hpp \
$$DRAPE_DIR/vertex_array_buffer.hpp \
+ $$DRAPE_DIR/viewport.hpp \
$$DRAPE_DIR/visual_scale.hpp \
iphone*{
diff --git a/drape/drape_global.hpp b/drape/drape_global.hpp
index d445f72633..d3933057d0 100644
--- a/drape/drape_global.hpp
+++ b/drape/drape_global.hpp
@@ -72,4 +72,13 @@ struct FontDecl
float m_size = 0;
bool m_isSdf = true;
};
+
+inline std::string DebugPrint(dp::ApiVersion apiVersion)
+{
+ if (apiVersion == dp::OpenGLES2)
+ return "OpenGLES2";
+ else if (apiVersion == dp::OpenGLES3)
+ return "OpenGLES3";
+ return "Unknown";
+}
} // namespace dp
diff --git a/drape/drape_tests/font_texture_tests.cpp b/drape/drape_tests/font_texture_tests.cpp
index b6b7882fd2..f4eab31fd1 100644
--- a/drape/drape_tests/font_texture_tests.cpp
+++ b/drape/drape_tests/font_texture_tests.cpp
@@ -1,6 +1,6 @@
-#include "testing/testing.hpp"
-#include "drape/drape_tests/img.hpp"
#include "drape/drape_tests/dummy_texture.hpp"
+#include "drape/drape_tests/img.hpp"
+#include "testing/testing.hpp"
#include "drape/font_texture.hpp"
#include "drape/glyph_manager.hpp"
@@ -10,8 +10,8 @@
#include "std/bind.hpp"
-#include <QtGui/QPainter>
#include <QtCore/QPoint>
+#include <QtGui/QPainter>
#include "drape/drape_tests/glmock_functions.hpp"
@@ -26,59 +26,52 @@ using namespace dp;
namespace
{
- class UploadedRender
+class UploadedRender
+{
+public:
+ UploadedRender(QPoint const & pen) : m_pen(pen) {}
+ void glMemoryToQImage(int x, int y, int w, int h, glConst f, glConst t, void const * memory)
+ {
+ TEST(f == gl_const::GLAlpha || f == gl_const::GLAlpha8 || f == gl_const::GLRed, ());
+ TEST(t == gl_const::GLUnsignedByteType, ());
+
+ uint8_t const * image = reinterpret_cast<uint8_t const *>(memory);
+
+ QPoint p(m_pen);
+ p.rx() += x;
+ m_images.push_back(qMakePair(p, CreateImage(w, h, image)));
+ m_pen.ry() += h;
+ }
+
+ void Render(QPaintDevice * device)
{
- public:
- UploadedRender(QPoint const & pen)
- : m_pen(pen)
- {
- }
-
- void glMemoryToQImage(int x, int y, int w, int h, glConst f, glConst t, void const * memory)
- {
- TEST(f == gl_const::GLAlpha || f == gl_const::GLAlpha8, ());
- TEST(t == gl_const::GLUnsignedByteType, ());
-
- uint8_t const * image = reinterpret_cast<uint8_t const *>(memory);
-
- QPoint p(m_pen);
- p.rx() += x;
- m_images.push_back(qMakePair(p, CreateImage(w, h, image)));
- m_pen.ry() += h;
- }
-
- void Render(QPaintDevice * device)
- {
- QPainter p(device);
- for (auto d : m_images)
- p.drawImage(d.first, d.second);
- }
-
- private:
- QPoint m_pen;
- QVector<QPair<QPoint, QImage> > m_images;
- };
-
- class DummyGlyphIndex : public GlyphIndex
+ QPainter p(device);
+ for (auto d : m_images)
+ p.drawImage(d.first, d.second);
+ }
+
+private:
+ QPoint m_pen;
+ QVector<QPair<QPoint, QImage>> m_images;
+};
+
+class DummyGlyphIndex : public GlyphIndex
+{
+ typedef GlyphIndex TBase;
+
+public:
+ DummyGlyphIndex(m2::PointU size, ref_ptr<GlyphManager> mng) : TBase(size, mng) {}
+ ref_ptr<Texture::ResourceInfo> MapResource(GlyphKey const & key)
{
- typedef GlyphIndex TBase;
- public:
- DummyGlyphIndex(m2::PointU size, ref_ptr<GlyphManager> mng)
- : TBase(size, mng)
- {
- }
-
- ref_ptr<Texture::ResourceInfo> MapResource(GlyphKey const & key)
- {
- bool dummy = false;
- return TBase::MapResource(key, dummy);
- }
- };
-}
+ bool dummy = false;
+ return TBase::MapResource(key, dummy);
+ }
+};
+} // namespace
UNIT_TEST(UploadingGlyphs)
{
- // This unit test creates window so can't be run in GUI-less Linux machine.
+// This unit test creates window so can't be run in GUI-less Linux machine.
#ifndef OMIM_OS_LINUX
EXPECTGL(glHasExtension(_)).Times(AnyNumber());
EXPECTGL(glBindTexture(_)).Times(AnyNumber());
@@ -96,11 +89,12 @@ UNIT_TEST(UploadingGlyphs)
GlyphManager mng(args);
DummyGlyphIndex index(m2::PointU(128, 128), make_ref(&mng));
- size_t count = 1; // invalid symbol glyph has mapped internally.
+ size_t count = 1; // invalid symbol glyph has mapped internally.
count += (index.MapResource(GlyphKey(0x58, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
count += (index.MapResource(GlyphKey(0x59, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
count += (index.MapResource(GlyphKey(0x61, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
- while (index.GetPendingNodesCount() < count);
+ while (index.GetPendingNodesCount() < count)
+ ;
Texture::Params p;
p.m_allocator = GetDefaultAllocator();
@@ -109,7 +103,8 @@ UNIT_TEST(UploadingGlyphs)
DummyTexture tex;
tex.Create(p);
- EXPECTGL(glTexSubImage2D(_, _, _, _, _, _, _)).WillRepeatedly(Invoke(&r, &UploadedRender::glMemoryToQImage));
+ EXPECTGL(glTexSubImage2D(_, _, _, _, _, _, _))
+ .WillRepeatedly(Invoke(&r, &UploadedRender::glMemoryToQImage));
index.UploadResources(make_ref(&tex));
count = 0;
@@ -119,9 +114,11 @@ UNIT_TEST(UploadingGlyphs)
count += (index.MapResource(GlyphKey(0x65, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
count += (index.MapResource(GlyphKey(0x400, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
count += (index.MapResource(GlyphKey(0x401, GlyphManager::kDynamicGlyphSize)) != nullptr) ? 1 : 0;
- while (index.GetPendingNodesCount() < count);
+ while (index.GetPendingNodesCount() < count)
+ ;
- EXPECTGL(glTexSubImage2D(_, _, _, _, _, _, _)).WillRepeatedly(Invoke(&r, &UploadedRender::glMemoryToQImage));
+ EXPECTGL(glTexSubImage2D(_, _, _, _, _, _, _))
+ .WillRepeatedly(Invoke(&r, &UploadedRender::glMemoryToQImage));
index.UploadResources(make_ref(&tex));
RunTestLoop("UploadingGlyphs", bind(&UploadedRender::Render, &r, _1));
diff --git a/drape/drape_tests/glfunctions.cpp b/drape/drape_tests/glfunctions.cpp
index ad78bd869b..7cc5909d3b 100644
--- a/drape/drape_tests/glfunctions.cpp
+++ b/drape/drape_tests/glfunctions.cpp
@@ -7,6 +7,8 @@
using namespace emul;
+dp::ApiVersion GLFunctions::CurrentApiVersion = dp::ApiVersion::OpenGLES2;
+
#define MOCK_CALL(f) GLMockFunctions::Instance().f;
void GLFunctions::glFlush()
@@ -270,6 +272,8 @@ void GLFunctions::glUniformValueiv(int8_t location, int32_t * v, uint32_t size)
void * GLFunctions::glMapBuffer(glConst, glConst) { return 0; }
+void * GLFunctions::glMapBufferRange(glConst, uint32_t, uint32_t, glConst) { return 0; }
+
void GLFunctions::glUnmapBuffer(glConst target) {}
void GLFunctions::glDrawElements(glConst primitive, uint32_t sizeOfIndex,
diff --git a/drape/drape_tests/memory_comparer.hpp b/drape/drape_tests/memory_comparer.hpp
index d7cdd0e003..eb6a3fbdeb 100644
--- a/drape/drape_tests/memory_comparer.hpp
+++ b/drape/drape_tests/memory_comparer.hpp
@@ -1,46 +1,36 @@
#pragma once
-#include "testing/testing.hpp"
-#include "drape/glconstants.hpp"
#include "base/logging.hpp"
+#include "drape/glconstants.hpp"
+#include "testing/testing.hpp"
-#include "std/cstring.hpp"
+#include <cstring>
namespace dp
{
-
struct MemoryComparer
{
void * m_mem;
int m_size;
- MemoryComparer(void * memory, int size)
- : m_mem(memory)
- , m_size(size)
- {
- }
-
+ MemoryComparer(void * memory, int size) : m_mem(memory), m_size(size) {}
void cmpSubBuffer(glConst /*type*/, uint32_t size, void const * data, uint32_t /*offset*/) const
{
TEST_EQUAL(size, m_size, ());
TEST_EQUAL(memcmp(m_mem, data, size), 0, ());
}
- void cmpSubImage(uint32_t /*x*/, uint32_t /*y*/, uint32_t width, uint32_t height,
- glConst layout, glConst pixelFormat, void const * data) const
+ void cmpSubImage(uint32_t /*x*/, uint32_t /*y*/, uint32_t width, uint32_t height, glConst layout,
+ glConst pixelFormat, void const * data) const
{
uint32_t channelCount = 0;
- if (layout == gl_const::GLRGBA ||
- layout == gl_const::GLRGBA8 ||
- layout == gl_const::GLRGBA4)
+ if (layout == gl_const::GLRGBA || layout == gl_const::GLRGBA8 || layout == gl_const::GLRGBA4)
channelCount = 4;
else if (layout == gl_const::GLRGB)
channelCount = 3;
- else if (layout == gl_const::GLAlpha ||
- layout == gl_const::GLAlpha8 ||
- layout == gl_const::GLLuminance ||
- layout == gl_const::GLLuminance8 ||
- layout == gl_const::GLAlphaLuminance)
+ else if (layout == gl_const::GLAlpha || layout == gl_const::GLAlpha8 ||
+ layout == gl_const::GLLuminance || layout == gl_const::GLLuminance8 ||
+ layout == gl_const::GLAlphaLuminance || layout == gl_const::GLRed)
{
channelCount = 1;
}
@@ -55,9 +45,6 @@ struct MemoryComparer
for (int i = 0; i < m_size; ++i)
TEST_EQUAL(member[i], input[i], (i));
-
- //TEST_EQUAL(memcmp(m_mem, data, m_size), 0, ());
}
};
-
-}
+} // namespace dp
diff --git a/drape/framebuffer.cpp b/drape/framebuffer.cpp
new file mode 100644
index 0000000000..73d79173f5
--- /dev/null
+++ b/drape/framebuffer.cpp
@@ -0,0 +1,105 @@
+#include "drape/framebuffer.hpp"
+
+#include "drape/glfunctions.hpp"
+#include "drape/oglcontext.hpp"
+
+#include "base/assert.hpp"
+#include "base/logging.hpp"
+#include "base/string_utils.hpp"
+
+namespace dp
+{
+Framebuffer::~Framebuffer() { Destroy(); }
+void Framebuffer::Destroy()
+{
+ if (m_colorTextureId != 0)
+ {
+ GLFunctions::glDeleteTexture(m_colorTextureId);
+ m_colorTextureId = 0;
+ }
+
+ if (m_depthTextureId != 0)
+ {
+ GLFunctions::glDeleteTexture(m_depthTextureId);
+ m_depthTextureId = 0;
+ }
+
+ if (m_framebufferId != 0)
+ {
+ GLFunctions::glDeleteFramebuffer(&m_framebufferId);
+ m_framebufferId = 0;
+ }
+}
+
+void Framebuffer::SetDefaultContext(dp::OGLContext * context) { m_defaultContext = context; }
+void Framebuffer::SetSize(uint32_t width, uint32_t height)
+{
+ ASSERT(m_defaultContext, ());
+
+ if (!m_isSupported)
+ return;
+
+ if (m_width == width && m_height == height)
+ return;
+
+ m_height = height;
+ m_width = width;
+
+ Destroy();
+
+ m_colorTextureId = GLFunctions::glGenTexture();
+ GLFunctions::glBindTexture(m_colorTextureId);
+ GLFunctions::glTexImage2D(m_width, m_height, gl_const::GLRGBA, gl_const::GLUnsignedByteType,
+ nullptr);
+ GLFunctions::glTexParameter(gl_const::GLMagFilter, gl_const::GLLinear);
+ GLFunctions::glTexParameter(gl_const::GLMinFilter, gl_const::GLLinear);
+ GLFunctions::glTexParameter(gl_const::GLWrapT, gl_const::GLClampToEdge);
+ GLFunctions::glTexParameter(gl_const::GLWrapS, gl_const::GLClampToEdge);
+
+ m_depthTextureId = GLFunctions::glGenTexture();
+ GLFunctions::glBindTexture(m_depthTextureId);
+ GLFunctions::glTexImage2D(m_width, m_height, gl_const::GLDepthComponent,
+ gl_const::GLUnsignedIntType, nullptr);
+ if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3)
+ {
+ GLFunctions::glTexParameter(gl_const::GLMagFilter, gl_const::GLNearest);
+ GLFunctions::glTexParameter(gl_const::GLMinFilter, gl_const::GLNearest);
+ GLFunctions::glTexParameter(gl_const::GLWrapT, gl_const::GLClampToEdge);
+ GLFunctions::glTexParameter(gl_const::GLWrapS, gl_const::GLClampToEdge);
+ }
+
+ GLFunctions::glBindTexture(0);
+
+ GLFunctions::glGenFramebuffer(&m_framebufferId);
+ GLFunctions::glBindFramebuffer(m_framebufferId);
+
+ GLFunctions::glFramebufferTexture2D(gl_const::GLColorAttachment, m_colorTextureId);
+ GLFunctions::glFramebufferTexture2D(gl_const::GLDepthAttachment, m_depthTextureId);
+ GLFunctions::glFramebufferTexture2D(gl_const::GLStencilAttachment, 0);
+
+ uint32_t const status = GLFunctions::glCheckFramebufferStatus();
+ if (status != gl_const::GLFramebufferComplete)
+ {
+ m_isSupported = false;
+ Destroy();
+ LOG(LWARNING, ("Framebuffer is unsupported. Framebuffer status =", status));
+ }
+
+ m_defaultContext->setDefaultFramebuffer();
+}
+
+void Framebuffer::Enable()
+{
+ ASSERT(m_isSupported, ());
+ GLFunctions::glBindFramebuffer(m_framebufferId);
+}
+
+void Framebuffer::Disable()
+{
+ ASSERT(m_defaultContext, ());
+ ASSERT(m_isSupported, ());
+ m_defaultContext->setDefaultFramebuffer();
+}
+
+uint32_t Framebuffer::GetTextureId() const { return m_colorTextureId; }
+} // namespace dp
diff --git a/drape/framebuffer.hpp b/drape/framebuffer.hpp
new file mode 100644
index 0000000000..39de064799
--- /dev/null
+++ b/drape/framebuffer.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <cstdint>
+
+namespace dp
+{
+class OGLContext;
+
+class Framebuffer
+{
+public:
+ Framebuffer() = default;
+ ~Framebuffer();
+
+ void SetDefaultContext(dp::OGLContext * context);
+ void SetSize(uint32_t width, uint32_t height);
+
+ void Enable();
+ void Disable();
+
+ uint32_t GetTextureId() const;
+ bool IsSupported() const { return m_isSupported; }
+private:
+ void Destroy();
+
+ uint32_t m_width = 0;
+ uint32_t m_height = 0;
+
+ uint32_t m_colorTextureId = 0;
+ uint32_t m_depthTextureId = 0;
+ uint32_t m_framebufferId = 0;
+
+ dp::OGLContext * m_defaultContext = 0;
+
+ bool m_isSupported = true;
+};
+} // namespace dp
diff --git a/drape/glIncludes.hpp b/drape/glIncludes.hpp
index 5f87f1670e..b47df3e85a 100644
--- a/drape/glIncludes.hpp
+++ b/drape/glIncludes.hpp
@@ -3,9 +3,8 @@
#include "std/target_os.hpp"
#if defined(OMIM_OS_IPHONE)
- #define USE_OPENGLES20_IF_AVAILABLE 1
- #include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
+ #include <OpenGLES/ES3/gl.h>
#elif defined(OMIM_OS_MAC)
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
@@ -15,10 +14,10 @@
#include <GL/gl.h>
#include "3party/GL/glext.h"
#elif defined(OMIM_OS_ANDROID)
- #include <EGL/egl.h>
- #include <GLES2/gl2.h>
#define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2ext.h>
+ #include "android/jni/com/mapswithme/opengl/gl3stub.h"
+ #include <EGL/egl.h>
#else
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
diff --git a/drape/glconstants.cpp b/drape/glconstants.cpp
index e934c7be71..0c3c0f5724 100644
--- a/drape/glconstants.cpp
+++ b/drape/glconstants.cpp
@@ -25,6 +25,14 @@
#define GL_LUMINANCE8_ALPHA4_OES 0x8043
#endif
+#if !defined(GL_LUMINANCE)
+ #define GL_LUMINANCE 0x1909
+#endif
+
+#if !defined(GL_LUMINANCE_ALPHA)
+ #define GL_LUMINANCE_ALPHA 0x190A
+#endif
+
#if defined(GL_WRITE_ONLY)
#define WRITE_ONLY_DEF GL_WRITE_ONLY
#elif defined(GL_WRITE_ONLY_OES)
@@ -125,6 +133,7 @@ const glConst GLAlpha8 = GL_ALPHA8_OES;
const glConst GLLuminance8 = GL_LUMINANCE8_OES;
const glConst GLAlphaLuminance8 = GL_LUMINANCE8_ALPHA8_OES;
const glConst GLAlphaLuminance4 = GL_LUMINANCE8_ALPHA4_OES;
+const glConst GLRed = GL_RED;
const glConst GL8BitOnChannel = GL_UNSIGNED_BYTE;
const glConst GL4BitOnChannel = GL_UNSIGNED_SHORT_4_4_4_4;
diff --git a/drape/glconstants.hpp b/drape/glconstants.hpp
index 1dccc60bb8..c67c181fa9 100644
--- a/drape/glconstants.hpp
+++ b/drape/glconstants.hpp
@@ -62,6 +62,7 @@ extern const glConst GLAlpha8;
extern const glConst GLLuminance8;
extern const glConst GLAlphaLuminance8;
extern const glConst GLAlphaLuminance4;
+extern const glConst GLRed;
/// Pixel type for texture upload
extern const glConst GL8BitOnChannel;
diff --git a/drape/glextensions_list.cpp b/drape/glextensions_list.cpp
index b9647ebefd..69647f4fa5 100644
--- a/drape/glextensions_list.cpp
+++ b/drape/glextensions_list.cpp
@@ -3,121 +3,87 @@
#include "base/assert.hpp"
-#include "std/string.hpp"
+#include "std/target_os.hpp"
namespace dp
{
-
-#ifdef DEBUG
- #include "std/map.hpp"
-
- class GLExtensionsList::Impl
+GLExtensionsList::GLExtensionsList(dp::ApiVersion apiVersion)
+{
+#if defined(OMIM_OS_MOBILE)
+ CheckExtension(TextureNPOT, "GL_OES_texture_npot");
+ if (apiVersion == dp::ApiVersion::OpenGLES2)
{
- public:
- void CheckExtension(GLExtensionsList::ExtensionName const & enumName, const string & extName)
- {
#ifdef OMIM_OS_ANDROID
- if (enumName == GLExtensionsList::VertexArrayObject)
- m_supportedMap[enumName] = false;
- else
-#endif
- m_supportedMap[enumName] = GLFunctions::glHasExtension(extName);
- }
-
- void SetExtension(GLExtensionsList::ExtensionName const & enumName, bool isSupported)
- {
- m_supportedMap[enumName] = isSupported;
- }
-
- bool IsSupported(GLExtensionsList::ExtensionName const & enumName) const
- {
- map<GLExtensionsList::ExtensionName, bool>::const_iterator it = m_supportedMap.find(enumName);
- if (it != m_supportedMap.end())
- return it->second;
-
- ASSERT(false, ("Not all used extensions is checked"));
- return false;
- }
-
- private:
- map<GLExtensionsList::ExtensionName, bool> m_supportedMap;
- };
+ SetExtension(VertexArrayObject, false);
#else
- #include "std/set.hpp"
-
- class GLExtensionsList::Impl
- {
- public:
- void CheckExtension(GLExtensionsList::ExtensionName const & enumName, const string & extName)
- {
-#ifdef OMIM_OS_ANDROID
- if (enumName == GLExtensionsList::VertexArrayObject)
- return;
-#endif
- if (GLFunctions::glHasExtension(extName))
- m_supported.insert(enumName);
- }
-
- void SetExtension(GLExtensionsList::ExtensionName const & enumName, bool isSupported)
- {
- if (isSupported)
- m_supported.insert(enumName);
- }
-
- bool IsSupported(GLExtensionsList::ExtensionName const & enumName) const
- {
- if (m_supported.find(enumName) != m_supported.end())
- return true;
-
- return false;
- }
-
- private:
- set<GLExtensionsList::ExtensionName> m_supported;
- };
+ CheckExtension(VertexArrayObject, "GL_OES_vertex_array_object");
#endif
-
-GLExtensionsList::GLExtensionsList()
- : m_impl(new Impl())
-{
-#if defined(OMIM_OS_MOBILE)
- m_impl->CheckExtension(VertexArrayObject, "GL_OES_vertex_array_object");
- m_impl->CheckExtension(RequiredInternalFormat, "GL_OES_required_internalformat");
- m_impl->CheckExtension(TextureNPOT, "GL_OES_texture_npot");
- m_impl->CheckExtension(MapBuffer, "GL_OES_mapbuffer");
- m_impl->CheckExtension(UintIndices, "GL_OES_element_index_uint");
- m_impl->CheckExtension(MapBufferRange, "GL_EXT_map_buffer_range");
+ CheckExtension(MapBuffer, "GL_OES_mapbuffer");
+ CheckExtension(UintIndices, "GL_OES_element_index_uint");
+ CheckExtension(MapBufferRange, "GL_EXT_map_buffer_range");
+ }
+ else
+ {
+ SetExtension(VertexArrayObject, true);
+ SetExtension(MapBuffer, true);
+ SetExtension(MapBufferRange, true);
+ SetExtension(UintIndices, true);
+ }
#elif defined(OMIM_OS_WINDOWS)
m_impl->CheckExtension(TextureNPOT, "GL_ARB_texture_non_power_of_two");
- m_impl->SetExtension(VertexArrayObject, false);
- m_impl->SetExtension(RequiredInternalFormat, false);
- m_impl->SetExtension(MapBuffer, true);
- m_impl->SetExtension(MapBufferRange, false);
- m_impl->SetExtension(UintIndices, true);
+ SetExtension(MapBuffer, true);
+ SetExtension(UintIndices, true);
+ if (apiVersion == dp::ApiVersion::OpenGLES2)
+ {
+ SetExtension(VertexArrayObject, false);
+ SetExtension(MapBufferRange, false);
+ }
+ else
+ {
+ SetExtension(VertexArrayObject, true);
+ SetExtension(MapBufferRange, true);
+ }
#else
- m_impl->CheckExtension(VertexArrayObject, "GL_APPLE_vertex_array_object");
- m_impl->CheckExtension(TextureNPOT, "GL_ARB_texture_non_power_of_two");
- m_impl->SetExtension(RequiredInternalFormat, false);
- m_impl->SetExtension(MapBuffer, true);
- m_impl->SetExtension(MapBufferRange, false);
- m_impl->SetExtension(UintIndices, true);
+ CheckExtension(TextureNPOT, "GL_ARB_texture_non_power_of_two");
+ SetExtension(MapBuffer, true);
+ SetExtension(UintIndices, true);
+ if (apiVersion == dp::ApiVersion::OpenGLES2)
+ {
+ CheckExtension(VertexArrayObject, "GL_APPLE_vertex_array_object");
+ SetExtension(MapBufferRange, false);
+ }
+ else
+ {
+ SetExtension(VertexArrayObject, true);
+ SetExtension(MapBufferRange, true);
+ }
#endif
}
-GLExtensionsList::~GLExtensionsList()
+// static
+GLExtensionsList & GLExtensionsList::Instance()
{
- delete m_impl;
+ static GLExtensionsList extList(GLFunctions::CurrentApiVersion);
+ return extList;
}
-GLExtensionsList & GLExtensionsList::Instance()
+bool GLExtensionsList::IsSupported(ExtensionName extName) const
{
- static GLExtensionsList extList;
- return extList;
+ auto const it = m_supportedMap.find(extName);
+ if (it != m_supportedMap.end())
+ return it->second;
+
+ ASSERT(false, ("Not all used extensions are checked"));
+ return false;
}
-bool GLExtensionsList::IsSupported(ExtensionName const & extName) const
+void GLExtensionsList::CheckExtension(ExtensionName enumName, std::string const & extName)
{
- return m_impl->IsSupported(extName);
+ m_supportedMap[enumName] = GLFunctions::glHasExtension(extName);
}
-} // namespace dp
+void GLExtensionsList::SetExtension(ExtensionName enumName, bool isSupported)
+{
+ m_supportedMap[enumName] = isSupported;
+}
+} // namespace dp
diff --git a/drape/glextensions_list.hpp b/drape/glextensions_list.hpp
index d5ffc143ed..507c10ec52 100644
--- a/drape/glextensions_list.hpp
+++ b/drape/glextensions_list.hpp
@@ -1,33 +1,37 @@
#pragma once
-#include "std/noncopyable.hpp"
+#include "drape/drape_global.hpp"
+
+#include "base/macros.hpp"
+
+#include <map>
+#include <string>
namespace dp
{
-
-class GLExtensionsList : private noncopyable
+class GLExtensionsList
{
public:
enum ExtensionName
{
VertexArrayObject,
TextureNPOT,
- RequiredInternalFormat,
MapBuffer,
UintIndices,
MapBufferRange
};
static GLExtensionsList & Instance();
- bool IsSupported(ExtensionName const & extName) const;
-private:
- GLExtensionsList();
- ~GLExtensionsList();
+ bool IsSupported(ExtensionName extName) const;
private:
- class Impl;
- Impl * m_impl;
-};
+ GLExtensionsList(dp::ApiVersion apiVersion);
+ void CheckExtension(ExtensionName enumName, std::string const & extName);
+ void SetExtension(ExtensionName enumName, bool isSupported);
+
+ std::map<ExtensionName, bool> m_supportedMap;
-} // namespace dp
+ DISALLOW_COPY_AND_MOVE(GLExtensionsList);
+};
+} // namespace dp
diff --git a/drape/glfunctions.cpp b/drape/glfunctions.cpp
index 15887ac76b..0a272d6056 100644
--- a/drape/glfunctions.cpp
+++ b/drape/glfunctions.cpp
@@ -8,13 +8,10 @@
#include "base/mutex.hpp"
#include "base/string_utils.hpp"
-#ifdef DEBUG
-#include "base/thread.hpp"
-#endif
-
-#include "std/algorithm.hpp"
-#include "std/map.hpp"
-#include "std/utility.hpp"
+#include <algorithm>
+#include <map>
+#include <mutex>
+#include <utility>
#if defined(OMIM_OS_WINDOWS)
#define DP_APIENTRY __stdcall
@@ -22,87 +19,103 @@
#define DP_APIENTRY
#endif
+// static
+dp::ApiVersion GLFunctions::CurrentApiVersion = dp::ApiVersion::OpenGLES2;
+
namespace
{
#ifdef DEBUG
- typedef pair<threads::ThreadID, glConst> TKey;
- typedef pair<TKey, uint32_t> TNode;
- typedef map<TKey, uint32_t> TBoundMap;
- TBoundMap g_boundBuffers;
- threads::Mutex g_mutex;
+using NodeKey = std::pair<std::thread::id, glConst>;
+using Node = std::pair<NodeKey, uint32_t>;
+using BoundMap = std::map<NodeKey, uint32_t>;
+BoundMap g_boundBuffers;
+std::mutex g_boundBuffersMutex;
#endif
-inline GLboolean convert(bool v)
-{
- return (v == true) ? GL_TRUE : GL_FALSE;
-}
-
-typedef void (DP_APIENTRY *TglClearColorFn)(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
-typedef void (DP_APIENTRY *TglClearFn)(GLbitfield mask);
-typedef void (DP_APIENTRY *TglViewportFn)(GLint x, GLint y, GLsizei w, GLsizei h);
-typedef void (DP_APIENTRY *TglScissorFn)(GLint x, GLint y, GLsizei w, GLsizei h);
-typedef void (DP_APIENTRY *TglFlushFn)();
-
-typedef void (DP_APIENTRY *TglActiveTextureFn)(GLenum texture);
-typedef void (DP_APIENTRY *TglBlendEquationFn)(GLenum mode);
-
-typedef void (DP_APIENTRY *TglGenVertexArraysFn)(GLsizei n, GLuint * ids);
-typedef void (DP_APIENTRY *TglBindVertexArrayFn)(GLuint id);
-typedef void (DP_APIENTRY *TglDeleteVertexArrayFn)(GLsizei n, GLuint const * ids);
-
-typedef void (DP_APIENTRY *TglGetBufferParameterFn)(GLenum target, GLenum value, GLint * data);
-typedef void (DP_APIENTRY *TglGenBuffersFn)(GLsizei n, GLuint * buffers);
-typedef void (DP_APIENTRY *TglBindBufferFn)(GLenum target, GLuint buffer);
-typedef void (DP_APIENTRY *TglDeleteBuffersFn)(GLsizei n, GLuint const * buffers);
-typedef void (DP_APIENTRY *TglBufferDataFn)(GLenum target, GLsizeiptr size, GLvoid const * data, GLenum usage);
-typedef void (DP_APIENTRY *TglBufferSubDataFn)(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid const * data);
-typedef void * (DP_APIENTRY *TglMapBufferFn)(GLenum target, GLenum access);
-typedef GLboolean(DP_APIENTRY *TglUnmapBufferFn)(GLenum target);
-typedef void * (DP_APIENTRY *TglMapBufferRangeFn)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
-typedef void (DP_APIENTRY *TglFlushMappedBufferRangeFn)(GLenum target, GLintptr offset, GLsizeiptr length);
-
-typedef GLuint(DP_APIENTRY *TglCreateShaderFn)(GLenum type);
-typedef void (DP_APIENTRY *TglShaderSourceFn)(GLuint shaderID, GLsizei count, GLchar const ** string, GLint const * length);
-typedef void (DP_APIENTRY *TglCompileShaderFn)(GLuint shaderID);
-typedef void (DP_APIENTRY *TglDeleteShaderFn)(GLuint shaderID);
-typedef void (DP_APIENTRY *TglGetShaderivFn)(GLuint shaderID, GLenum name, GLint * p);
-typedef void (DP_APIENTRY *TglGetShaderInfoLogFn)(GLuint shaderID, GLsizei maxLength, GLsizei * length, GLchar * infoLog);
-
-typedef GLuint(DP_APIENTRY *TglCreateProgramFn)();
-typedef void (DP_APIENTRY *TglAttachShaderFn)(GLuint programID, GLuint shaderID);
-typedef void (DP_APIENTRY *TglDetachShaderFn)(GLuint programID, GLuint shaderID);
-typedef void (DP_APIENTRY *TglLinkProgramFn)(GLuint programID);
-typedef void (DP_APIENTRY *TglDeleteProgramFn)(GLuint programID);
-typedef void (DP_APIENTRY *TglGetProgramivFn)(GLuint programID, GLenum name, GLint * p);
-typedef void (DP_APIENTRY *TglGetProgramInfoLogFn)(GLuint programID, GLsizei maxLength, GLsizei * length, GLchar * infoLog);
-
-typedef void (DP_APIENTRY *TglUseProgramFn)(GLuint programID);
-typedef GLint (DP_APIENTRY *TglGetAttribLocationFn)(GLuint program, GLchar const * name);
-typedef void (DP_APIENTRY *TglBindAttribLocationFn)(GLuint program, GLuint index, GLchar const * name);
-
-typedef void (DP_APIENTRY *TglEnableVertexAttributeFn)(GLuint location);
-typedef void (DP_APIENTRY *TglVertexAttributePointerFn)(GLuint index, GLint count, GLenum type, GLboolean normalize,
- GLsizei stride, GLvoid const * p);
-typedef GLint(DP_APIENTRY *TglGetUniformLocationFn)(GLuint programID, GLchar const * name);
-typedef void (DP_APIENTRY *TglGetActiveUniformFn)(GLuint programID, GLuint uniformIndex, GLsizei bufSize, GLsizei * length,
- GLint * size, GLenum * type, GLchar * name);
-typedef void (DP_APIENTRY *TglUniform1iFn)(GLint location, GLint value);
-typedef void (DP_APIENTRY *TglUniform2iFn)(GLint location, GLint v1, GLint v2);
-typedef void (DP_APIENTRY *TglUniform3iFn)(GLint location, GLint v1, GLint v2, GLint v3);
-typedef void (DP_APIENTRY *TglUniform4iFn)(GLint location, GLint v1, GLint v2, GLint v3, GLint v4);
-typedef void (DP_APIENTRY *TglUniform1ivFn)(GLint location, GLsizei count, GLint const * value);
-typedef void (DP_APIENTRY *TglUniform1fFn)(GLint location, GLfloat value);
-typedef void (DP_APIENTRY *TglUniform2fFn)(GLint location, GLfloat v1, GLfloat v2);
-typedef void (DP_APIENTRY *TglUniform3fFn)(GLint location, GLfloat v1, GLfloat v2, GLfloat v3);
-typedef void (DP_APIENTRY *TglUniform4fFn)(GLint location, GLfloat v1, GLfloat v2, GLfloat v3, GLfloat v4);
-typedef void (DP_APIENTRY *TglUniform1fvFn)(GLint location, GLsizei count, GLfloat const * value);
-typedef void (DP_APIENTRY *TglUniformMatrix4fvFn)(GLint location, GLsizei count, GLboolean transpose, GLfloat const * value);
-
-typedef void (DP_APIENTRY *TglGenFramebuffersFn)(GLsizei n, GLuint * framebuffers);
-typedef void (DP_APIENTRY *TglDeleteFramebuffersFn)(GLsizei n, GLuint const * framebuffers);
-typedef void (DP_APIENTRY *TglBindFramebufferFn)(GLenum target, GLuint id);
-typedef void (DP_APIENTRY *TglFramebufferTexture2DFn)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-typedef GLenum(DP_APIENTRY *TglCheckFramebufferStatusFn)(GLenum target);
+inline GLboolean convert(bool v) { return static_cast<GLboolean>(v ? GL_TRUE : GL_FALSE); }
+
+typedef void(DP_APIENTRY * TglClearColorFn)(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+typedef void(DP_APIENTRY * TglClearFn)(GLbitfield mask);
+typedef void(DP_APIENTRY * TglViewportFn)(GLint x, GLint y, GLsizei w, GLsizei h);
+typedef void(DP_APIENTRY * TglScissorFn)(GLint x, GLint y, GLsizei w, GLsizei h);
+typedef void(DP_APIENTRY * TglFlushFn)();
+
+typedef void(DP_APIENTRY * TglActiveTextureFn)(GLenum texture);
+typedef void(DP_APIENTRY * TglBlendEquationFn)(GLenum mode);
+
+typedef void(DP_APIENTRY * TglGenVertexArraysFn)(GLsizei n, GLuint * ids);
+typedef void(DP_APIENTRY * TglBindVertexArrayFn)(GLuint id);
+typedef void(DP_APIENTRY * TglDeleteVertexArrayFn)(GLsizei n, GLuint const * ids);
+
+typedef void(DP_APIENTRY * TglGetBufferParameterFn)(GLenum target, GLenum value, GLint * data);
+typedef void(DP_APIENTRY * TglGenBuffersFn)(GLsizei n, GLuint * buffers);
+typedef void(DP_APIENTRY * TglBindBufferFn)(GLenum target, GLuint buffer);
+typedef void(DP_APIENTRY * TglDeleteBuffersFn)(GLsizei n, GLuint const * buffers);
+typedef void(DP_APIENTRY * TglBufferDataFn)(GLenum target, GLsizeiptr size, GLvoid const * data,
+ GLenum usage);
+typedef void(DP_APIENTRY * TglBufferSubDataFn)(GLenum target, GLintptr offset, GLsizeiptr size,
+ GLvoid const * data);
+typedef void *(DP_APIENTRY * TglMapBufferFn)(GLenum target, GLenum access);
+typedef GLboolean(DP_APIENTRY * TglUnmapBufferFn)(GLenum target);
+typedef void *(DP_APIENTRY * TglMapBufferRangeFn)(GLenum target, GLintptr offset, GLsizeiptr length,
+ GLbitfield access);
+typedef void(DP_APIENTRY * TglFlushMappedBufferRangeFn)(GLenum target, GLintptr offset,
+ GLsizeiptr length);
+
+typedef GLuint(DP_APIENTRY * TglCreateShaderFn)(GLenum type);
+typedef void(DP_APIENTRY * TglShaderSourceFn)(GLuint shaderID, GLsizei count,
+ GLchar const ** string, GLint const * length);
+typedef void(DP_APIENTRY * TglCompileShaderFn)(GLuint shaderID);
+typedef void(DP_APIENTRY * TglDeleteShaderFn)(GLuint shaderID);
+typedef void(DP_APIENTRY * TglGetShaderivFn)(GLuint shaderID, GLenum name, GLint * p);
+typedef void(DP_APIENTRY * TglGetShaderInfoLogFn)(GLuint shaderID, GLsizei maxLength,
+ GLsizei * length, GLchar * infoLog);
+
+typedef GLuint(DP_APIENTRY * TglCreateProgramFn)();
+typedef void(DP_APIENTRY * TglAttachShaderFn)(GLuint programID, GLuint shaderID);
+typedef void(DP_APIENTRY * TglDetachShaderFn)(GLuint programID, GLuint shaderID);
+typedef void(DP_APIENTRY * TglLinkProgramFn)(GLuint programID);
+typedef void(DP_APIENTRY * TglDeleteProgramFn)(GLuint programID);
+typedef void(DP_APIENTRY * TglGetProgramivFn)(GLuint programID, GLenum name, GLint * p);
+typedef void(DP_APIENTRY * TglGetProgramInfoLogFn)(GLuint programID, GLsizei maxLength,
+ GLsizei * length, GLchar * infoLog);
+
+typedef void(DP_APIENTRY * TglUseProgramFn)(GLuint programID);
+typedef GLint(DP_APIENTRY * TglGetAttribLocationFn)(GLuint program, GLchar const * name);
+typedef void(DP_APIENTRY * TglBindAttribLocationFn)(GLuint program, GLuint index,
+ GLchar const * name);
+
+typedef void(DP_APIENTRY * TglEnableVertexAttributeFn)(GLuint location);
+typedef void(DP_APIENTRY * TglVertexAttributePointerFn)(GLuint index, GLint count, GLenum type,
+ GLboolean normalize, GLsizei stride,
+ GLvoid const * p);
+typedef GLint(DP_APIENTRY * TglGetUniformLocationFn)(GLuint programID, GLchar const * name);
+typedef void(DP_APIENTRY * TglGetActiveUniformFn)(GLuint programID, GLuint uniformIndex,
+ GLsizei bufSize, GLsizei * length, GLint * size,
+ GLenum * type, GLchar * name);
+typedef void(DP_APIENTRY * TglUniform1iFn)(GLint location, GLint value);
+typedef void(DP_APIENTRY * TglUniform2iFn)(GLint location, GLint v1, GLint v2);
+typedef void(DP_APIENTRY * TglUniform3iFn)(GLint location, GLint v1, GLint v2, GLint v3);
+typedef void(DP_APIENTRY * TglUniform4iFn)(GLint location, GLint v1, GLint v2, GLint v3, GLint v4);
+typedef void(DP_APIENTRY * TglUniform1ivFn)(GLint location, GLsizei count, GLint const * value);
+typedef void(DP_APIENTRY * TglUniform1fFn)(GLint location, GLfloat value);
+typedef void(DP_APIENTRY * TglUniform2fFn)(GLint location, GLfloat v1, GLfloat v2);
+typedef void(DP_APIENTRY * TglUniform3fFn)(GLint location, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void(DP_APIENTRY * TglUniform4fFn)(GLint location, GLfloat v1, GLfloat v2, GLfloat v3,
+ GLfloat v4);
+typedef void(DP_APIENTRY * TglUniform1fvFn)(GLint location, GLsizei count, GLfloat const * value);
+typedef void(DP_APIENTRY * TglUniformMatrix4fvFn)(GLint location, GLsizei count,
+ GLboolean transpose, GLfloat const * value);
+
+typedef void(DP_APIENTRY * TglGenFramebuffersFn)(GLsizei n, GLuint * framebuffers);
+typedef void(DP_APIENTRY * TglDeleteFramebuffersFn)(GLsizei n, GLuint const * framebuffers);
+typedef void(DP_APIENTRY * TglBindFramebufferFn)(GLenum target, GLuint id);
+typedef void(DP_APIENTRY * TglFramebufferTexture2DFn)(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level);
+typedef GLenum(DP_APIENTRY * TglCheckFramebufferStatusFn)(GLenum target);
+
+typedef GLubyte const * (DP_APIENTRY * TglGetStringiFn) (GLenum name, GLuint index);
TglClearColorFn glClearColorFn = nullptr;
TglClearFn glClearFn = nullptr;
@@ -173,184 +186,19 @@ TglBindFramebufferFn glBindFramebufferFn = nullptr;
TglFramebufferTexture2DFn glFramebufferTexture2DFn = nullptr;
TglCheckFramebufferStatusFn glCheckFramebufferStatusFn = nullptr;
-int const GLCompileStatus = GL_COMPILE_STATUS;
-int const GLLinkStatus = GL_LINK_STATUS;
-
-threads::Mutex s_mutex;
-bool s_inited = false;
-
-class GLFunctionsCache
-{
-public:
- GLFunctionsCache() = default;
-
- void SetThread(thread::id const & threadId)
- {
- m_threadId = threadId;
-
- m_glBindTextureCache = CachedParam<uint32_t>();
- m_glActiveTextureCache = CachedParam<glConst>();
- m_glUseProgramCache = CachedParam<uint32_t>();
- m_glLineWidthCache = CachedParam<uint32_t>();
- m_glStateCache.clear();
- m_uniformsCache.clear();
- }
-
- void glBindTexture(uint32_t textureID)
- {
- if (!IsCachedThread() || m_glBindTextureCache.Assign(textureID))
- GLCHECK(::glBindTexture(GL_TEXTURE_2D, textureID));
- }
-
- void glActiveTexture(glConst texBlock)
- {
- if (!IsCachedThread() || m_glActiveTextureCache.Assign(texBlock))
- {
- ASSERT(glActiveTextureFn != nullptr, ());
- GLCHECK(glActiveTextureFn(texBlock));
- }
- }
+TglGetStringiFn glGetStringiFn = nullptr;
- void glUseProgram(uint32_t programID)
- {
- if (!IsCachedThread() || m_glUseProgramCache.Assign(programID))
- {
- ASSERT(glUseProgramFn != nullptr, ());
- GLCHECK(glUseProgramFn(programID));
- }
- }
-
- void glEnable(glConst mode)
- {
- if (!IsCachedThread() || m_glStateCache[mode].Assign(true))
- GLCHECK(::glEnable(mode));
- }
-
- void glDisable(glConst mode)
- {
- if (!IsCachedThread() || m_glStateCache[mode].Assign(false))
- GLCHECK(::glDisable(mode));
- }
-
- void glUniformValuei(int8_t location, int32_t v)
- {
- if (!IsCachedThread() || GetCacheForCurrentProgram().Assign(location, v))
- {
- ASSERT(glUniform1iFn != nullptr, ());
- ASSERT(location != -1, ());
- GLCHECK(glUniform1iFn(location, v));
- }
- }
-
- void glUniformValuef(int8_t location, float v)
- {
- if (!IsCachedThread() || GetCacheForCurrentProgram().Assign(location, v))
- {
- ASSERT(glUniform1fFn != nullptr, ());
- ASSERT(location != -1, ());
- GLCHECK(glUniform1fFn(location, v));
- }
- }
-
- void glLineWidth(uint32_t value)
- {
- if (!IsCachedThread() || m_glLineWidthCache.Assign(value))
- {
- GLCHECK(::glLineWidth(static_cast<float>(value)));
- }
- }
-
-private:
-
- template<typename TValue>
- struct CachedParam
- {
- TValue m_value;
- bool m_inited;
-
- CachedParam()
- : m_value(TValue())
- , m_inited(false)
- {
- }
-
- explicit CachedParam(TValue const & value)
- : m_value(value)
- , m_inited(true)
- {
- }
-
- bool Assign(TValue const & newValue)
- {
- if (m_inited && newValue == m_value)
- return false;
-
- m_value = newValue;
- m_inited = true;
- return true;
- }
-
- bool operator!=(TValue const & value) const
- {
- return m_value != value;
- }
-
- CachedParam & operator=(TValue const & param)
- {
- m_value = param;
- m_inited = true;
- return *this;
- }
- };
-
- template<typename TValue> using UniformCache = map<int8_t, CachedParam<TValue>>;
- using StateParams = map<glConst, CachedParam<bool>>;
-
- struct UniformsCache
- {
- UniformCache<int32_t> m_glUniform1iCache;
- UniformCache<float> m_glUniform1fCache;
-
- bool Assign(int8_t location, int32_t value) { return Assign(location, value, m_glUniform1iCache); }
- bool Assign(int8_t location, float value) { return Assign(location, value, m_glUniform1fCache); }
-
- template<typename TValue>
- bool Assign(int8_t location, TValue const & value, UniformCache<TValue> & cache)
- {
- return cache[location].Assign(value);
- }
- };
-
- GLFunctionsCache::UniformsCache & GetCacheForCurrentProgram()
- {
- ASSERT(m_glUseProgramCache.m_inited, ());
- return m_uniformsCache[m_glUseProgramCache.m_value];
- }
-
- bool IsCachedThread() const
- {
- return this_thread::get_id() == m_threadId;
- }
-
- CachedParam<uint32_t> m_glBindTextureCache;
- CachedParam<glConst> m_glActiveTextureCache;
- CachedParam<uint32_t> m_glUseProgramCache;
- StateParams m_glStateCache;
- CachedParam<uint32_t> m_glLineWidthCache;
-
- map<uint32_t, UniformsCache> m_uniformsCache;
-
- thread::id m_threadId;
-};
-
-GLFunctionsCache s_cache;
+#if !defined(GL_NUM_EXTENSIONS)
+ #define GL_NUM_EXTENSIONS 0x821D
+#endif
-} // namespace
+std::mutex s_mutex;
+bool s_inited = false;
+} // namespace
#ifdef OMIM_OS_WINDOWS
-
template <typename TFunc>
-TFunc LoadExtension(string const & ext)
+TFunc LoadExtension(std::string const & ext)
{
TFunc func = reinterpret_cast<TFunc>(wglGetProcAddress(ext.c_str()));
if (func == nullptr)
@@ -361,21 +209,21 @@ TFunc LoadExtension(string const & ext)
return func;
}
-
- #define LOAD_GL_FUNC(type, func) LoadExtension<type>(#func);
+#define LOAD_GL_FUNC(type, func) LoadExtension<type>(#func);
#else
- #define LOAD_GL_FUNC(type, func) &::func
+#define LOAD_GL_FUNC(type, func) static_cast<type>(&::func)
#endif
-
-void GLFunctions::Init()
+void GLFunctions::Init(dp::ApiVersion apiVersion)
{
- threads::MutexGuard g(s_mutex);
+ std::lock_guard<std::mutex> lock(s_mutex);
if (s_inited)
return;
+ CurrentApiVersion = apiVersion;
s_inited = true;
- /// VAO
+
+/// VAO
#if defined(OMIM_OS_MAC)
glGenVertexArraysFn = &glGenVertexArraysAPPLE;
glBindVertexArrayFn = &glBindVertexArrayAPPLE;
@@ -386,24 +234,59 @@ void GLFunctions::Init()
glGenVertexArraysFn = &::glGenVertexArrays;
glBindVertexArrayFn = &::glBindVertexArray;
glDeleteVertexArrayFn = &::glDeleteVertexArrays;
- glMapBufferFn = &::glMapBuffer; // I don't know correct name for linux!
- glUnmapBufferFn = &::glUnmapBuffer; // I don't know correct name for linux!
+ glMapBufferFn = &::glMapBuffer;
+ glUnmapBufferFn = &::glUnmapBuffer;
#elif defined(OMIM_OS_ANDROID)
- glGenVertexArraysFn = (TglGenVertexArraysFn)eglGetProcAddress("glGenVertexArraysOES");
- glBindVertexArrayFn = (TglBindVertexArrayFn)eglGetProcAddress("glBindVertexArrayOES");
- glDeleteVertexArrayFn = (TglDeleteVertexArrayFn)eglGetProcAddress("glDeleteVertexArraysOES");
- glMapBufferFn = &::glMapBufferOES;
- glUnmapBufferFn = &::glUnmapBufferOES;
- glMapBufferRangeFn = (TglMapBufferRangeFn)eglGetProcAddress("glMapBufferRangeEXT");
- glFlushMappedBufferRangeFn = (TglFlushMappedBufferRangeFn)eglGetProcAddress("glFlushMappedBufferRangeEXT");
+ if (CurrentApiVersion == dp::ApiVersion::OpenGLES2)
+ {
+ glGenVertexArraysFn = (TglGenVertexArraysFn)eglGetProcAddress("glGenVertexArraysOES");
+ glBindVertexArrayFn = (TglBindVertexArrayFn)eglGetProcAddress("glBindVertexArrayOES");
+ glDeleteVertexArrayFn = (TglDeleteVertexArrayFn)eglGetProcAddress("glDeleteVertexArraysOES");
+ glMapBufferFn = &::glMapBufferOES;
+ glUnmapBufferFn = &::glUnmapBufferOES;
+ glMapBufferRangeFn = (TglMapBufferRangeFn)eglGetProcAddress("glMapBufferRangeEXT");
+ glFlushMappedBufferRangeFn =
+ (TglFlushMappedBufferRangeFn)eglGetProcAddress("glFlushMappedBufferRangeEXT");
+ }
+ else if (CurrentApiVersion == dp::ApiVersion::OpenGLES3)
+ {
+ glGenVertexArraysFn = ::glGenVertexArrays;
+ glBindVertexArrayFn = ::glBindVertexArray;
+ glDeleteVertexArrayFn = ::glDeleteVertexArrays;
+ glUnmapBufferFn = ::glUnmapBuffer;
+ glMapBufferRangeFn = ::glMapBufferRange;
+ glFlushMappedBufferRangeFn = ::glFlushMappedBufferRange;
+ glGetStringiFn = ::glGetStringi;
+ }
+ else
+ {
+ ASSERT(false, ("Unknown Graphics API"));
+ }
#elif defined(OMIM_OS_MOBILE)
- glGenVertexArraysFn = &glGenVertexArraysOES;
- glBindVertexArrayFn = &glBindVertexArrayOES;
- glDeleteVertexArrayFn = &glDeleteVertexArraysOES;
- glMapBufferFn = &::glMapBufferOES;
- glUnmapBufferFn = &::glUnmapBufferOES;
- glMapBufferRangeFn = &::glMapBufferRangeEXT;
- glFlushMappedBufferRangeFn = &::glFlushMappedBufferRangeEXT;
+ if (CurrentApiVersion == dp::ApiVersion::OpenGLES2)
+ {
+ glGenVertexArraysFn = &glGenVertexArraysOES;
+ glBindVertexArrayFn = &glBindVertexArrayOES;
+ glDeleteVertexArrayFn = &glDeleteVertexArraysOES;
+ glMapBufferFn = &::glMapBufferOES;
+ glUnmapBufferFn = &::glUnmapBufferOES;
+ glMapBufferRangeFn = &::glMapBufferRangeEXT;
+ glFlushMappedBufferRangeFn = &::glFlushMappedBufferRangeEXT;
+ }
+ else if (CurrentApiVersion == dp::ApiVersion::OpenGLES3)
+ {
+ glGenVertexArraysFn = &::glGenVertexArrays;
+ glBindVertexArrayFn = &::glBindVertexArray;
+ glDeleteVertexArrayFn = &::glDeleteVertexArrays;
+ glUnmapBufferFn = &::glUnmapBuffer;
+ glMapBufferRangeFn = &::glMapBufferRange;
+ glFlushMappedBufferRangeFn = &::glFlushMappedBufferRange;
+ glGetStringiFn = &::glGetStringi;
+ }
+ else
+ {
+ ASSERT(false, ("Unknown Graphics API"));
+ }
#elif defined(OMIM_OS_WINDOWS)
if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject))
{
@@ -411,16 +294,15 @@ void GLFunctions::Init()
glBindVertexArrayFn = LOAD_GL_FUNC(TglBindVertexArrayFn, glBindVertexArray);
glDeleteVertexArrayFn = LOAD_GL_FUNC(TglDeleteVertexArrayFn, glDeleteVertexArrays);
}
-
glMapBufferFn = LOAD_GL_FUNC(TglMapBufferFn, glMapBuffer);
glUnmapBufferFn = LOAD_GL_FUNC(TglUnmapBufferFn, glUnmapBuffer);
#endif
- glClearColorFn = &::glClearColor;
- glClearFn = &::glClear;
- glViewportFn = &::glViewport;
- glScissorFn = &::glScissor;
- glFlushFn = &::glFlush;
+ glClearColorFn = LOAD_GL_FUNC(TglClearColorFn, glClearColor);
+ glClearFn = LOAD_GL_FUNC(TglClearFn, glClear);
+ glViewportFn = LOAD_GL_FUNC(TglViewportFn, glViewport);
+ glScissorFn = LOAD_GL_FUNC(TglScissorFn, glScissor);
+ glFlushFn = LOAD_GL_FUNC(TglFlushFn, glFlush);
glActiveTextureFn = LOAD_GL_FUNC(TglActiveTextureFn, glActiveTexture);
glBlendEquationFn = LOAD_GL_FUNC(TglBlendEquationFn, glBlendEquation);
@@ -438,7 +320,8 @@ void GLFunctions::Init()
#ifdef OMIM_OS_WINDOWS
glShaderSourceFn = LOAD_GL_FUNC(TglShaderSourceFn, glShaderSource);
#else
- typedef void (DP_APIENTRY *glShaderSource_Type)(GLuint shaderID, GLsizei count, GLchar const ** string, GLint const * length);
+ typedef void(DP_APIENTRY * glShaderSource_Type)(GLuint shaderID, GLsizei count,
+ GLchar const ** string, GLint const * length);
glShaderSourceFn = reinterpret_cast<glShaderSource_Type>(&::glShaderSource);
#endif
glCompileShaderFn = LOAD_GL_FUNC(TglCompileShaderFn, glCompileShader);
@@ -485,29 +368,39 @@ void GLFunctions::Init()
glCheckFramebufferStatusFn = LOAD_GL_FUNC(TglCheckFramebufferStatusFn, glCheckFramebufferStatus);
}
-void GLFunctions::AttachCache(thread::id const & threadId)
-{
- s_cache.SetThread(threadId);
-}
-
-bool GLFunctions::glHasExtension(string const & name)
+bool GLFunctions::glHasExtension(std::string const & name)
{
- char const * extensions = reinterpret_cast<char const * >(::glGetString(GL_EXTENSIONS));
- GLCHECKCALL();
- if (extensions == nullptr)
- return false;
-
- char const * extName = name.c_str();
- char const * ptr = nullptr;
- while ((ptr = strstr(extensions, extName)) != nullptr)
+ if (CurrentApiVersion == dp::ApiVersion::OpenGLES2)
{
- char const * end = ptr + strlen(extName);
- if (isspace(*end) || *end == '\0')
+ char const * extensions = reinterpret_cast<char const *>(::glGetString(GL_EXTENSIONS));
+ GLCHECKCALL();
+ if (extensions == nullptr)
+ return false;
+
+ char const * extName = name.c_str();
+ char const * ptr = nullptr;
+ while ((ptr = strstr(extensions, extName)) != nullptr)
+ {
+ char const * end = ptr + strlen(extName);
+ if (isspace(*end) || *end == '\0')
return true;
- extensions = end;
+ extensions = end;
+ }
+ }
+ else if (CurrentApiVersion == dp::ApiVersion::OpenGLES3)
+ {
+ ASSERT(glGetStringiFn != nullptr, ());
+ GLint n = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &n);
+ for (GLint i = 0; i < n; i++)
+ {
+ std::string const extension =
+ std::string(reinterpret_cast<char const *>(glGetStringiFn(GL_EXTENSIONS, i)));
+ if (extension == name)
+ return true;
+ }
}
-
return false;
}
@@ -547,21 +440,9 @@ void GLFunctions::glFlush()
GLCHECK(glFlushFn());
}
-void GLFunctions::glFinish()
-{
- GLCHECK(::glFinish());
-}
-
-void GLFunctions::glFrontFace(glConst mode)
-{
- GLCHECK(::glFrontFace(mode));
-}
-
-void GLFunctions::glCullFace(glConst face)
-{
- GLCHECK(::glCullFace(face));
-}
-
+void GLFunctions::glFinish() { GLCHECK(::glFinish()); }
+void GLFunctions::glFrontFace(glConst mode) { GLCHECK(::glFrontFace(mode)); }
+void GLFunctions::glCullFace(glConst face) { GLCHECK(::glCullFace(face)); }
void GLFunctions::glPixelStore(glConst name, uint32_t value)
{
GLCHECK(::glPixelStorei(name, value));
@@ -574,21 +455,21 @@ int32_t GLFunctions::glGetInteger(glConst pname)
return (int32_t)value;
}
-string GLFunctions::glGetString(glConst pname)
+std::string GLFunctions::glGetString(glConst pname)
{
- char const * str = reinterpret_cast<char const * >(::glGetString(pname));
+ char const * str = reinterpret_cast<char const *>(::glGetString(pname));
GLCHECKCALL();
if (str == nullptr)
return "";
- return string(str);
+ return std::string(str);
}
int32_t GLFunctions::glGetMaxLineWidth()
{
GLint range[2];
GLCHECK(::glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range));
- return max(range[0], range[1]);
+ return std::max(range[0], range[1]);
}
int32_t GLFunctions::glGetBufferParameter(glConst target, glConst name)
@@ -601,12 +482,12 @@ int32_t GLFunctions::glGetBufferParameter(glConst target, glConst name)
void GLFunctions::glEnable(glConst mode)
{
- s_cache.glEnable(mode);
+ GLCHECK(::glEnable(mode));
}
void GLFunctions::glDisable(glConst mode)
{
- s_cache.glDisable(mode);
+ GLCHECK(::glDisable(mode));
}
void GLFunctions::glClearDepthValue(double depth)
@@ -623,11 +504,7 @@ void GLFunctions::glDepthMask(bool needWriteToDepthBuffer)
GLCHECK(::glDepthMask(convert(needWriteToDepthBuffer)));
}
-void GLFunctions::glDepthFunc(glConst depthFunc)
-{
- GLCHECK(::glDepthFunc(depthFunc));
-}
-
+void GLFunctions::glDepthFunc(glConst depthFunc) { GLCHECK(::glDepthFunc(depthFunc)); }
void GLFunctions::glBlendEquation(glConst function)
{
ASSERT(glBlendEquationFn != nullptr, ());
@@ -671,8 +548,8 @@ void GLFunctions::glBindBuffer(uint32_t vbo, uint32_t target)
{
ASSERT(glBindBufferFn != nullptr, ());
#ifdef DEBUG
- threads::MutexGuard guard(g_mutex);
- g_boundBuffers[make_pair(threads::GetCurrentThreadID(), target)] = vbo;
+ std::lock_guard<std::mutex> guard(g_boundBuffersMutex);
+ g_boundBuffers[std::make_pair(std::this_thread::get_id(), target)] = vbo;
#endif
GLCHECK(glBindBufferFn(target, vbo));
}
@@ -681,11 +558,9 @@ void GLFunctions::glDeleteBuffer(uint32_t vbo)
{
ASSERT(glDeleteBuffersFn != nullptr, ());
#ifdef DEBUG
- threads::MutexGuard guard(g_mutex);
- for (TNode const & n : g_boundBuffers)
- {
+ std::lock_guard<std::mutex> guard(g_boundBuffersMutex);
+ for (auto const & n : g_boundBuffers)
ASSERT(n.second != vbo, ());
- }
#endif
GLCHECK(glDeleteBuffersFn(1, &vbo));
}
@@ -717,7 +592,8 @@ void GLFunctions::glUnmapBuffer(glConst target)
GLCHECKCALL();
}
-void * GLFunctions::glMapBufferRange(glConst target, uint32_t offset, uint32_t length, glConst access)
+void * GLFunctions::glMapBufferRange(glConst target, uint32_t offset, uint32_t length,
+ glConst access)
{
ASSERT(glMapBufferRangeFn != nullptr, ());
void * result = glMapBufferRangeFn(target, offset, length, access);
@@ -739,24 +615,29 @@ uint32_t GLFunctions::glCreateShader(glConst type)
return result;
}
-void GLFunctions::glShaderSource(uint32_t shaderID, string const & src, string const & defines)
+void GLFunctions::glShaderSource(uint32_t shaderID, std::string const & src, std::string const & defines)
{
ASSERT(glShaderSourceFn != nullptr, ());
- GLchar const * source[2] =
+
+ std::string fullSrc;
+ if (src.find("#version") != std::string::npos)
{
- defines.c_str(),
- src.c_str()
- };
-
- GLint lengths[2] =
+ auto pos = src.find('\n');
+ ASSERT_NOT_EQUAL(pos, std::string::npos, ());
+ fullSrc = src;
+ fullSrc.insert(pos + 1, defines);
+ }
+ else
{
- static_cast<GLint>(defines.size()),
- static_cast<GLint>(src.size())
- };
- GLCHECK(glShaderSourceFn(shaderID, 2, source, lengths));
+ fullSrc = defines + src;
+ }
+
+ GLchar const * source[1] = {fullSrc.c_str()};
+ GLint lengths[1] = {static_cast<GLint>(fullSrc.size())};
+ GLCHECK(glShaderSourceFn(shaderID, 1, source, lengths));
}
-bool GLFunctions::glCompileShader(uint32_t shaderID, string &errorLog)
+bool GLFunctions::glCompileShader(uint32_t shaderID, std::string & errorLog)
{
ASSERT(glCompileShaderFn != nullptr, ());
ASSERT(glGetShaderivFn != nullptr, ());
@@ -764,14 +645,14 @@ bool GLFunctions::glCompileShader(uint32_t shaderID, string &errorLog)
GLCHECK(glCompileShaderFn(shaderID));
GLint result = GL_FALSE;
- GLCHECK(glGetShaderivFn(shaderID, GLCompileStatus, &result));
+ GLCHECK(glGetShaderivFn(shaderID, GL_COMPILE_STATUS, &result));
if (result == GL_TRUE)
return true;
GLchar buf[1024];
GLint length = 0;
GLCHECK(glGetShaderInfoLogFn(shaderID, 1024, &length, buf));
- errorLog = string(buf, length);
+ errorLog = std::string(buf, static_cast<size_t>(length));
return false;
}
@@ -801,7 +682,7 @@ void GLFunctions::glDetachShader(uint32_t programID, uint32_t shaderID)
GLCHECK(glDetachShaderFn(programID, shaderID));
}
-bool GLFunctions::glLinkProgram(uint32_t programID, string & errorLog)
+bool GLFunctions::glLinkProgram(uint32_t programID, std::string & errorLog)
{
ASSERT(glLinkProgramFn != nullptr, ());
ASSERT(glGetProgramivFn != nullptr, ());
@@ -809,7 +690,7 @@ bool GLFunctions::glLinkProgram(uint32_t programID, string & errorLog)
GLCHECK(glLinkProgramFn(programID));
GLint result = GL_FALSE;
- GLCHECK(glGetProgramivFn(programID, GLLinkStatus, &result));
+ GLCHECK(glGetProgramivFn(programID, GL_LINK_STATUS, &result));
if (result == GL_TRUE)
return true;
@@ -817,7 +698,7 @@ bool GLFunctions::glLinkProgram(uint32_t programID, string & errorLog)
GLchar buf[1024];
GLint length = 0;
GLCHECK(glGetProgramInfoLogFn(programID, 1024, &length, buf));
- errorLog = string(buf, length);
+ errorLog = std::string(buf, static_cast<size_t>(length));
return false;
}
@@ -829,19 +710,20 @@ void GLFunctions::glDeleteProgram(uint32_t programID)
void GLFunctions::glUseProgram(uint32_t programID)
{
- s_cache.glUseProgram(programID);
+ ASSERT(glUseProgramFn != nullptr, ());
+ GLCHECK(glUseProgramFn(programID));
}
-int8_t GLFunctions::glGetAttribLocation(uint32_t programID, string const & name)
+int8_t GLFunctions::glGetAttribLocation(uint32_t programID, std::string const & name)
{
ASSERT(glGetAttribLocationFn != nullptr, ());
int result = glGetAttribLocationFn(programID, name.c_str());
GLCHECKCALL();
ASSERT(result != -1, ());
- return result;
+ return static_cast<int8_t>(result);
}
-void GLFunctions::glBindAttribLocation(uint32_t programID, uint8_t index, string const & name)
+void GLFunctions::glBindAttribLocation(uint32_t programID, uint8_t index, std::string const & name)
{
ASSERT(glBindAttribLocationFn != nullptr, ());
GLCHECK(glBindAttribLocationFn(programID, index, name.c_str()));
@@ -853,43 +735,38 @@ void GLFunctions::glEnableVertexAttribute(int attributeLocation)
GLCHECK(glEnableVertexAttributeFn(attributeLocation));
}
-void GLFunctions::glVertexAttributePointer(int attrLocation,
- uint32_t count,
- glConst type,
- bool needNormalize,
- uint32_t stride,
- uint32_t offset)
+void GLFunctions::glVertexAttributePointer(int attrLocation, uint32_t count, glConst type,
+ bool needNormalize, uint32_t stride, uint32_t offset)
{
ASSERT(glVertexAttributePointerFn != nullptr, ());
- GLCHECK(glVertexAttributePointerFn(attrLocation,
- count,
- type,
- convert(needNormalize),
- stride,
+ GLCHECK(glVertexAttributePointerFn(attrLocation, count, type, convert(needNormalize), stride,
reinterpret_cast<void *>(offset)));
}
void GLFunctions::glGetActiveUniform(uint32_t programID, uint32_t uniformIndex,
- int32_t * uniformSize, glConst * type, string & name)
+ int32_t * uniformSize, glConst * type, std::string & name)
{
ASSERT(glGetActiveUniformFn != nullptr, ());
GLchar buff[256];
- GLCHECK(glGetActiveUniformFn(programID, uniformIndex, ARRAY_SIZE(buff), nullptr, uniformSize, type, buff));
+ GLCHECK(glGetActiveUniformFn(programID, uniformIndex, ARRAY_SIZE(buff), nullptr, uniformSize,
+ type, buff));
name = buff;
}
-int8_t GLFunctions::glGetUniformLocation(uint32_t programID, string const & name)
+int8_t GLFunctions::glGetUniformLocation(uint32_t programID, std::string const & name)
{
ASSERT(glGetUniformLocationFn != nullptr, ());
int result = glGetUniformLocationFn(programID, name.c_str());
GLCHECKCALL();
ASSERT(result != -1, ());
- return result;
+ return static_cast<int8_t>(result);
}
void GLFunctions::glUniformValuei(int8_t location, int32_t v)
{
- s_cache.glUniformValuei(location, v);
+ ASSERT(glUniform1iFn != nullptr, ());
+ ASSERT(location != -1, ());
+ GLCHECK(glUniform1iFn(location, v));
}
void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2)
@@ -922,7 +799,9 @@ void GLFunctions::glUniformValueiv(int8_t location, int32_t * v, uint32_t size)
void GLFunctions::glUniformValuef(int8_t location, float v)
{
- s_cache.glUniformValuef(location, v);
+ ASSERT(glUniform1fFn != nullptr, ());
+ ASSERT(location != -1, ());
+ GLCHECK(glUniform1fFn(location, v));
}
void GLFunctions::glUniformValuef(int8_t location, float v1, float v2)
@@ -953,7 +832,7 @@ void GLFunctions::glUniformValuefv(int8_t location, float * v, uint32_t size)
GLCHECK(glUniform1fvFn(location, size, v));
}
-void GLFunctions::glUniformMatrix4x4Value(int8_t location, float const * values)
+void GLFunctions::glUniformMatrix4x4Value(int8_t location, float const * values)
{
ASSERT(glUniformMatrix4fvFn != nullptr, ());
ASSERT(location != -1, ());
@@ -964,7 +843,8 @@ uint32_t GLFunctions::glGetCurrentProgram()
{
GLint programIndex = 0;
GLCHECK(glGetIntegerv(GL_CURRENT_PROGRAM, &programIndex));
- return programIndex;
+ ASSERT_GREATER_OR_EQUAL(programIndex, 0, ());
+ return static_cast<uint32_t>(programIndex);
}
int32_t GLFunctions::glGetProgramiv(uint32_t program, glConst paramName)
@@ -977,7 +857,8 @@ int32_t GLFunctions::glGetProgramiv(uint32_t program, glConst paramName)
void GLFunctions::glActiveTexture(glConst texBlock)
{
- s_cache.glActiveTexture(texBlock);
+ ASSERT(glActiveTextureFn != nullptr, ());
+ GLCHECK(glActiveTextureFn(texBlock));
}
uint32_t GLFunctions::glGenTexture()
@@ -994,15 +875,39 @@ void GLFunctions::glDeleteTexture(uint32_t id)
void GLFunctions::glBindTexture(uint32_t textureID)
{
- s_cache.glBindTexture(textureID);
+ GLCHECK(::glBindTexture(GL_TEXTURE_2D, textureID));
}
-void GLFunctions::glTexImage2D(int width, int height, glConst layout, glConst pixelType, void const * data)
+void GLFunctions::glTexImage2D(int width, int height, glConst layout, glConst pixelType,
+ void const * data)
{
- GLCHECK(::glTexImage2D(GL_TEXTURE_2D, 0, layout, width, height, 0, layout, pixelType, data));
+ // In OpenGL ES3:
+ // - we can't create unsized GL_RED texture, so we use GL_R8;
+ // - we can't create unsized GL_DEPTH_COMPONENT texture, so we use GL_DEPTH_COMPONENT16
+ // or GL_DEPTH_COMPONENT24 or GL_DEPTH_COMPONENT32F.
+ glConst internalFormat = layout;
+ if (CurrentApiVersion == dp::ApiVersion::OpenGLES3)
+ {
+ if (layout == gl_const::GLRed)
+ {
+ internalFormat = GL_R8;
+ }
+ else if (layout == gl_const::GLDepthComponent)
+ {
+ internalFormat = GL_DEPTH_COMPONENT16;
+ if (pixelType == gl_const::GLUnsignedIntType)
+ internalFormat = GL_DEPTH_COMPONENT24;
+ else if (pixelType == gl_const::GLFloatType)
+ internalFormat = GL_DEPTH_COMPONENT32F;
+ }
+ }
+
+ GLCHECK(
+ ::glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, layout, pixelType, data));
}
-void GLFunctions::glTexSubImage2D(int x, int y, int width, int height, glConst layout, glConst pixelType, void const * data)
+void GLFunctions::glTexSubImage2D(int x, int y, int width, int height, glConst layout,
+ glConst pixelType, void const * data)
{
GLCHECK(::glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, layout, pixelType, data));
}
@@ -1012,9 +917,11 @@ void GLFunctions::glTexParameter(glConst param, glConst value)
GLCHECK(::glTexParameteri(GL_TEXTURE_2D, param, value));
}
-void GLFunctions::glDrawElements(glConst primitive, uint32_t sizeOfIndex, uint32_t indexCount, uint32_t startIndex)
+void GLFunctions::glDrawElements(glConst primitive, uint32_t sizeOfIndex, uint32_t indexCount,
+ uint32_t startIndex)
{
- GLCHECK(::glDrawElements(primitive, indexCount, sizeOfIndex == sizeof(uint32_t) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
+ GLCHECK(::glDrawElements(primitive, indexCount,
+ sizeOfIndex == sizeof(uint32_t) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid *>(startIndex * sizeOfIndex)));
}
@@ -1057,25 +964,23 @@ uint32_t GLFunctions::glCheckFramebufferStatus()
void GLFunctions::glLineWidth(uint32_t value)
{
- s_cache.glLineWidth(value);
+ GLCHECK(::glLineWidth(static_cast<float>(value)));
}
namespace
{
-
-string GetGLError(GLenum error)
+std::string GetGLError(GLenum error)
{
switch (error)
{
- case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
- case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
- case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
- case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
- default: return strings::to_string(error);
+ case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
+ case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
+ case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
+ case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
+ default: return strings::to_string(error);
}
}
-
-} // namespace
+} // namespace
void CheckGLError(my::SrcPoint const & srcPoint)
{
diff --git a/drape/glfunctions.hpp b/drape/glfunctions.hpp
index dab34efe89..4c3e87c4d5 100644
--- a/drape/glfunctions.hpp
+++ b/drape/glfunctions.hpp
@@ -1,25 +1,23 @@
#pragma once
+#include "drape/drape_global.hpp"
#include "drape/glconstants.hpp"
#include "base/src_point.hpp"
-#include "std/string.hpp"
-#include "std/thread.hpp"
+#include <string>
+#include <thread>
class GLFunctions
{
friend class GLFunctionsCache;
public:
- static void Init();
+ static dp::ApiVersion CurrentApiVersion;
- /// Attaches cache of gl-functions to specified thread. The only cache
- /// is available, so invoking of this method on other thread leads to
- /// disabling of current cache and enabling another
- static void AttachCache(thread::id const & threadId);
+ static void Init(dp::ApiVersion apiVersion);
- static bool glHasExtension(string const & name);
+ static bool glHasExtension(std::string const & name);
static void glClearColor(float r, float g, float b, float a);
static void glClear();
static void glClearDepth();
@@ -38,7 +36,7 @@ public:
/// name = { gl_const::GLBufferSize, gl_const::GLBufferUsage }
static int32_t glGetBufferParameter(glConst target, glConst name);
- static string glGetString(glConst pname);
+ static std::string glGetString(glConst pname);
static int32_t glGetMaxLineWidth();
@@ -74,41 +72,40 @@ public:
/// Shaders support
static uint32_t glCreateShader(glConst type);
- static void glShaderSource(uint32_t shaderID, string const & src, string const & defines);
- static bool glCompileShader(uint32_t shaderID, string & errorLog);
+ static void glShaderSource(uint32_t shaderID, std::string const & src,
+ std::string const & defines);
+ static bool glCompileShader(uint32_t shaderID, std::string & errorLog);
static void glDeleteShader(uint32_t shaderID);
static uint32_t glCreateProgram();
static void glAttachShader(uint32_t programID, uint32_t shaderID);
static void glDetachShader(uint32_t programID, uint32_t shaderID);
- static bool glLinkProgram(uint32_t programID, string & errorLog);
+ static bool glLinkProgram(uint32_t programID, std::string & errorLog);
static void glDeleteProgram(uint32_t programID);
static void glUseProgram(uint32_t programID);
- static int8_t glGetAttribLocation(uint32_t programID, string const & name);
- static void glBindAttribLocation(uint32_t programID, uint8_t index, string const & name);
+ static int8_t glGetAttribLocation(uint32_t programID, std::string const & name);
+ static void glBindAttribLocation(uint32_t programID, uint8_t index, std::string const & name);
/// enable vertex attribute binding. To get attributeLocation need to call glGetAttributeLocation
static void glEnableVertexAttribute(int32_t attributeLocation);
/// Configure vertex attribute binding.
/// attrLocation - attribute location in shader program
/// count - specify number of components with "type" for generic attribute
- /// needNormalize - if "true" then OGL will map integer value on [-1 : 1] for signed of on [0 : 1] for unsigned
+ /// needNormalize - if "true" then OGL will map integer value on [-1 : 1] for signed of on [0 : 1]
+ /// for unsigned
/// if "false" it will direct convert to float type
/// if "type" == GLFloat this parameter have no sense
/// stride - how much bytes need to seek from current attribute value to get the second value
- /// offset - how much bytes need to seek from begin of currenct buffer to get first attribute value
- static void glVertexAttributePointer(int32_t attrLocation,
- uint32_t count,
- glConst type,
- bool needNormalize,
- uint32_t stride,
- uint32_t offset);
-
- static void glGetActiveUniform(uint32_t programID, uint32_t uniformIndex,
- int32_t * uniformSize, glConst * type, string & name);
-
- static int8_t glGetUniformLocation(uint32_t programID, string const & name);
+ /// offset - how much bytes need to seek from begin of currenct buffer to get first attribute
+ /// value
+ static void glVertexAttributePointer(int32_t attrLocation, uint32_t count, glConst type,
+ bool needNormalize, uint32_t stride, uint32_t offset);
+
+ static void glGetActiveUniform(uint32_t programID, uint32_t uniformIndex, int32_t * uniformSize,
+ glConst * type, std::string & name);
+
+ static int8_t glGetUniformLocation(uint32_t programID, std::string const & name);
static void glUniformValuei(int8_t location, int32_t v);
static void glUniformValuei(int8_t location, int32_t v1, int32_t v2);
static void glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32_t v3);
@@ -121,7 +118,7 @@ public:
static void glUniformValuef(int8_t location, float v1, float v2, float v3, float v4);
static void glUniformValuefv(int8_t location, float * v, uint32_t size);
- static void glUniformMatrix4x4Value(int8_t location, float const *values);
+ static void glUniformMatrix4x4Value(int8_t location, float const * values);
static uint32_t glGetCurrentProgram();
@@ -132,12 +129,15 @@ public:
static uint32_t glGenTexture();
static void glDeleteTexture(uint32_t id);
static void glBindTexture(uint32_t textureID);
- static void glTexImage2D(int width, int height, glConst layout, glConst pixelType, void const * data);
- static void glTexSubImage2D(int x, int y, int width, int height, glConst layout, glConst pixelType, void const * data);
+ static void glTexImage2D(int width, int height, glConst layout, glConst pixelType,
+ void const * data);
+ static void glTexSubImage2D(int x, int y, int width, int height, glConst layout,
+ glConst pixelType, void const * data);
static void glTexParameter(glConst param, glConst value);
// Draw support
- static void glDrawElements(glConst primitive, uint32_t sizeOfIndex, uint32_t indexCount, uint32_t startIndex = 0);
+ static void glDrawElements(glConst primitive, uint32_t sizeOfIndex, uint32_t indexCount,
+ uint32_t startIndex = 0);
static void glDrawArrays(glConst mode, int32_t first, uint32_t count);
// FBO support
@@ -148,12 +148,12 @@ public:
static uint32_t glCheckFramebufferStatus();
};
-void CheckGLError(my::SrcPoint const &src);
+void CheckGLError(my::SrcPoint const & src);
#ifdef DEBUG
- #define GLCHECK(x) do { (x); CheckGLError(SRC()); } while (false)
- #define GLCHECKCALL() do { CheckGLError(SRC()); } while (false)
+#define GLCHECK(x) do { (x); CheckGLError(SRC()); } while (false)
+#define GLCHECKCALL() do { CheckGLError(SRC()); } while (false)
#else
- #define GLCHECK(x) (x)
- #define GLCHECKCALL()
+#define GLCHECK(x) (x)
+#define GLCHECKCALL()
#endif
diff --git a/drape/gpu_buffer.cpp b/drape/gpu_buffer.cpp
index 5d91dc06f2..12afc9109c 100644
--- a/drape/gpu_buffer.cpp
+++ b/drape/gpu_buffer.cpp
@@ -1,24 +1,23 @@
#include "drape/gpu_buffer.hpp"
-#include "drape/glfunctions.hpp"
#include "drape/glextensions_list.hpp"
+#include "drape/glfunctions.hpp"
#include "drape/utils/gpu_mem_tracker.hpp"
#include "base/assert.hpp"
-#include "std/cstring.hpp"
+#include <cstring>
//#define CHECK_VBO_BOUNDS
namespace dp
{
-
namespace
{
- bool IsMapBufferSupported()
- {
- static bool const isSupported = GLExtensionsList::Instance().IsSupported(GLExtensionsList::MapBuffer);
- return isSupported;
- }
+bool IsMapBufferSupported()
+{
+ static bool const isSupported =
+ GLExtensionsList::Instance().IsSupported(GLExtensionsList::MapBuffer);
+ return isSupported;
}
glConst glTarget(GPUBuffer::Target t)
@@ -28,10 +27,12 @@ glConst glTarget(GPUBuffer::Target t)
return gl_const::GLElementArrayBuffer;
}
+} // namespace
GPUBuffer::GPUBuffer(Target t, void const * data, uint8_t elementSize, uint32_t capacity)
: TBase(elementSize, capacity)
, m_t(t)
+ , m_mappingOffset(0)
#ifdef DEBUG
, m_isMapped(false)
#endif
@@ -51,20 +52,22 @@ GPUBuffer::~GPUBuffer()
void GPUBuffer::UploadData(void const * data, uint32_t elementCount)
{
- ASSERT(m_isMapped == false, ());
+ ASSERT(!m_isMapped, ());
uint32_t currentSize = GetCurrentSize();
uint8_t elementSize = GetElementSize();
- ASSERT(GetCapacity() >= elementCount + currentSize, ("Not enough memory to upload ", elementCount, " elements"));
+ ASSERT(GetCapacity() >= elementCount + currentSize,
+ ("Not enough memory to upload ", elementCount, " elements"));
Bind();
#if defined(CHECK_VBO_BOUNDS)
int32_t size = GLFunctions::glGetBufferParameter(glTarget(m_t), gl_const::GLBufferSize);
ASSERT_EQUAL(GetCapacity() * elementSize, size, ());
- ASSERT_LESS_OR_EQUAL((elementCount + currentSize) * elementSize, size,());
+ ASSERT_LESS_OR_EQUAL((elementCount + currentSize) * elementSize, size, ());
#endif
- GLFunctions::glBufferSubData(glTarget(m_t), elementCount * elementSize, data, currentSize * elementSize);
+ GLFunctions::glBufferSubData(glTarget(m_t), elementCount * elementSize, data,
+ currentSize * elementSize);
TBase::UploadData(elementCount);
#if defined(TRACK_GPU_MEM)
@@ -72,46 +75,55 @@ void GPUBuffer::UploadData(void const * data, uint32_t elementCount)
#endif
}
-void GPUBuffer::Bind()
-{
- GLFunctions::glBindBuffer(m_bufferID, glTarget(m_t));
-}
-
-void * GPUBuffer::Map()
+void GPUBuffer::Bind() { GLFunctions::glBindBuffer(m_bufferID, glTarget(m_t)); }
+void * GPUBuffer::Map(uint32_t elementOffset, uint32_t elementCount)
{
#ifdef DEBUG
- ASSERT(m_isMapped == false, ());
+ ASSERT(!m_isMapped, ());
m_isMapped = true;
#endif
- if (IsMapBufferSupported())
- return GLFunctions::glMapBuffer(glTarget(m_t));
-
- return NULL;
+ if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES2)
+ {
+ m_mappingOffset = elementOffset;
+ return IsMapBufferSupported() ? GLFunctions::glMapBuffer(glTarget(m_t)) : nullptr;
+ }
+ else if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3)
+ {
+ ASSERT(IsMapBufferSupported(), ());
+ m_mappingOffset = 0;
+ uint32_t const elementSize = GetElementSize();
+ uint32_t const byteOffset = elementOffset * elementSize;
+ uint32_t const byteCount = elementCount * elementSize;
+ return GLFunctions::glMapBufferRange(glTarget(m_t), byteOffset, byteCount,
+ gl_const::GLWriteBufferBit);
+ }
+ return nullptr;
}
-void GPUBuffer::UpdateData(void * gpuPtr, void const * data, uint32_t elementOffset, uint32_t elementCount)
+void GPUBuffer::UpdateData(void * gpuPtr, void const * data, uint32_t elementOffset,
+ uint32_t elementCount)
{
uint32_t const elementSize = GetElementSize();
- uint32_t const byteOffset = elementOffset * elementSize;
+ uint32_t const byteOffset = (elementOffset + m_mappingOffset) * elementSize;
uint32_t const byteCount = elementCount * elementSize;
uint32_t const byteCapacity = GetCapacity() * elementSize;
- ASSERT(m_isMapped == true, ());
+ ASSERT(m_isMapped, ());
#if defined(CHECK_VBO_BOUNDS)
int32_t size = GLFunctions::glGetBufferParameter(glTarget(m_t), gl_const::GLBufferSize);
ASSERT_EQUAL(size, byteCapacity, ());
- ASSERT_LESS(byteOffset + byteCount, size, ());
+ ASSERT_LESS_OR_EQUAL(byteOffset + byteCount, size, ());
#endif
if (IsMapBufferSupported())
{
- ASSERT(gpuPtr != NULL, ());
+ ASSERT(gpuPtr != nullptr, ());
memcpy((uint8_t *)gpuPtr + byteOffset, data, byteCount);
}
else
{
- ASSERT(gpuPtr == NULL, ());
+ ASSERT(gpuPtr == nullptr, ());
if (byteOffset == 0 && byteCount == byteCapacity)
GLFunctions::glBufferData(glTarget(m_t), byteCount, data, gl_const::GLStaticDraw);
else
@@ -122,9 +134,10 @@ void GPUBuffer::UpdateData(void * gpuPtr, void const * data, uint32_t elementOff
void GPUBuffer::Unmap()
{
#ifdef DEBUG
- ASSERT(m_isMapped == true, ());
+ ASSERT(m_isMapped, ());
m_isMapped = false;
#endif
+ m_mappingOffset = 0;
if (IsMapBufferSupported())
GLFunctions::glUnmapBuffer(glTarget(m_t));
}
@@ -133,9 +146,10 @@ void GPUBuffer::Resize(void const * data, uint32_t elementCount)
{
TBase::Resize(elementCount);
Bind();
- GLFunctions::glBufferData(glTarget(m_t), GetCapacity() * GetElementSize(), data, gl_const::GLDynamicDraw);
+ GLFunctions::glBufferData(glTarget(m_t), GetCapacity() * GetElementSize(), data,
+ gl_const::GLDynamicDraw);
- // if we have set up data already (in glBufferData), we have to call SetDataSize
+ // If we have set up data already (in glBufferData), we have to call SetDataSize.
if (data != nullptr)
SetDataSize(elementCount);
@@ -147,5 +161,4 @@ void GPUBuffer::Resize(void const * data, uint32_t elementCount)
dp::GPUMemTracker::Inst().SetUsed("VBO", m_bufferID, GetCurrentSize() * GetElementSize());
#endif
}
-
-} // namespace dp
+} // namespace dp
diff --git a/drape/gpu_buffer.hpp b/drape/gpu_buffer.hpp
index ec65cd47d7..b04ef21ff8 100644
--- a/drape/gpu_buffer.hpp
+++ b/drape/gpu_buffer.hpp
@@ -1,14 +1,14 @@
#pragma once
-#include "drape/pointers.hpp"
#include "drape/buffer_base.hpp"
+#include "drape/pointers.hpp"
namespace dp
{
-
class GPUBuffer : public BufferBase
{
- typedef BufferBase TBase;
+ using TBase = BufferBase;
+
public:
enum Target
{
@@ -23,22 +23,22 @@ public:
void UploadData(void const * data, uint32_t elementCount);
void Bind();
- void * Map();
+ void * Map(uint32_t elementOffset, uint32_t elementCount);
void UpdateData(void * gpuPtr, void const * data, uint32_t elementOffset, uint32_t elementCount);
void Unmap();
protected:
- /// discard old data
+ // Discard old data.
void Resize(void const * data, uint32_t elementCount);
private:
friend class GPUBufferMapper;
Target m_t;
uint32_t m_bufferID;
+ uint32_t m_mappingOffset;
#ifdef DEBUG
bool m_isMapped;
#endif
};
-
-} // namespace dp
+} // namespace dp
diff --git a/drape/gpu_program_manager.cpp b/drape/gpu_program_manager.cpp
index 5b9df04b81..6ddb7e193c 100644
--- a/drape/gpu_program_manager.cpp
+++ b/drape/gpu_program_manager.cpp
@@ -30,6 +30,9 @@ void GpuProgramManager::Init(drape_ptr<gpu::GpuProgramGetter> && programGetter)
if (SupportManager::Instance().IsSamsungGoogleNexus())
m_globalDefines.append("#define SAMSUNG_GOOGLE_NEXUS\n");
+
+ if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3)
+ m_globalDefines.append("#define GLES3\n");
}
ref_ptr<GpuProgram> GpuProgramManager::GetProgram(int index)
diff --git a/drape/hw_texture.cpp b/drape/hw_texture.cpp
index 547a82c6c0..06a6c580b7 100644
--- a/drape/hw_texture.cpp
+++ b/drape/hw_texture.cpp
@@ -1,7 +1,7 @@
#include "hw_texture.hpp"
-#include "glfunctions.hpp"
#include "glextensions_list.hpp"
+#include "glfunctions.hpp"
#include "platform/platform.hpp"
@@ -15,21 +15,12 @@
namespace dp
{
-
HWTexture::HWTexture()
- : m_width(0)
- , m_height(0)
- , m_format(UNSPECIFIED)
- , m_textureID(-1)
- , m_filter(gl_const::GLLinear)
-{
-}
-
-void HWTexture::Create(Params const & params)
+ : m_width(0), m_height(0), m_format(UNSPECIFIED), m_textureID(-1), m_filter(gl_const::GLLinear)
{
- Create(params, nullptr);
}
+void HWTexture::Create(Params const & params) { Create(params, nullptr); }
void HWTexture::Create(Params const & params, ref_ptr<void> /*data*/)
{
m_width = params.m_width;
@@ -47,7 +38,7 @@ void HWTexture::Create(Params const & params, ref_ptr<void> /*data*/)
if (pixelType == gl_const::GL4BitOnChannel)
channelBitSize = 4;
- if (layout == gl_const::GLAlpha)
+ if (layout == gl_const::GLAlpha || layout == gl_const::GLRed)
channelCount = 1;
uint32_t bitCount = channelBitSize * channelCount * m_width * m_height;
@@ -57,11 +48,7 @@ void HWTexture::Create(Params const & params, ref_ptr<void> /*data*/)
#endif
}
-TextureFormat HWTexture::GetFormat() const
-{
- return m_format;
-}
-
+TextureFormat HWTexture::GetFormat() const { return m_format; }
uint32_t HWTexture::GetWidth() const
{
ASSERT_ID;
@@ -95,19 +82,20 @@ void HWTexture::UnpackFormat(TextureFormat format, glConst & layout, glConst & p
pixelType = gl_const::GL8BitOnChannel;
break;
case ALPHA:
- layout = gl_const::GLAlpha;
+ // On OpenGL ES3 GLAlpha is not supported, we use GLRed instead.
+ layout = GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES2 ? gl_const::GLAlpha
+ : gl_const::GLRed;
pixelType = gl_const::GL8BitOnChannel;
break;
- default:
- ASSERT(false, ());
- break;
+ default: ASSERT(false, ()); break;
}
}
void HWTexture::Bind() const
{
ASSERT_ID;
- GLFunctions::glBindTexture(GetID());
+ if (m_textureID != -1)
+ GLFunctions::glBindTexture(static_cast<uint32_t>(GetID()));
}
void HWTexture::SetFilter(glConst filter)
@@ -120,15 +108,11 @@ void HWTexture::SetFilter(glConst filter)
}
}
-int32_t HWTexture::GetID() const
-{
- return m_textureID;
-}
-
+int32_t HWTexture::GetID() const { return m_textureID; }
OpenGLHWTexture::~OpenGLHWTexture()
{
if (m_textureID != -1)
- GLFunctions::glDeleteTexture(m_textureID);
+ GLFunctions::glDeleteTexture(static_cast<uint32_t>(m_textureID));
}
void OpenGLHWTexture::Create(Params const & params, ref_ptr<void> data)
@@ -158,7 +142,8 @@ void OpenGLHWTexture::Create(Params const & params, ref_ptr<void> data)
GLFunctions::glBindTexture(0);
}
-void OpenGLHWTexture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data)
+void OpenGLHWTexture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height,
+ ref_ptr<void> data)
{
ASSERT_ID;
glConst layout;
@@ -175,9 +160,11 @@ drape_ptr<HWTexture> OpenGLHWTextureAllocator::CreateTexture()
drape_ptr<HWTextureAllocator> CreateAllocator()
{
- if (!Platform::IsCustomTextureAllocatorSupported())
- return make_unique_dp<OpenGLHWTextureAllocator>();;
-
+ if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3 ||
+ !Platform::IsCustomTextureAllocatorSupported())
+ {
+ return make_unique_dp<OpenGLHWTextureAllocator>();
+ }
#if defined(OMIM_OS_IPHONE) && !defined(OMIM_OS_IPHONE_SIMULATOR)
return make_unique_dp<HWTextureAllocatorApple>();
#else
@@ -190,5 +177,4 @@ ref_ptr<HWTextureAllocator> GetDefaultAllocator()
static OpenGLHWTextureAllocator s_allocator;
return make_ref<HWTextureAllocator>(&s_allocator);
}
-
-}
+} // namespace dp
diff --git a/drape/hw_texture_ios.mm b/drape/hw_texture_ios.mm
index 538d24af05..87951b8a7a 100644
--- a/drape/hw_texture_ios.mm
+++ b/drape/hw_texture_ios.mm
@@ -3,6 +3,7 @@
#include "base/logging.hpp"
#include "drape/glfunctions.hpp"
+#include "drape/glIncludes.hpp"
#import <QuartzCore/CAEAGLLayer.h>
diff --git a/drape/support_manager.cpp b/drape/support_manager.cpp
index 10a0ecccc8..6a68449086 100644
--- a/drape/support_manager.cpp
+++ b/drape/support_manager.cpp
@@ -15,7 +15,7 @@ void SupportManager::Init()
{
string const renderer = GLFunctions::glGetString(gl_const::GLRenderer);
string const version = GLFunctions::glGetString(gl_const::GLVersion);
- LOG(LINFO, ("Renderer =", renderer, "Version =", version));
+ LOG(LINFO, ("Renderer =", renderer, "Api =", GLFunctions::CurrentApiVersion, "Driver version =", version));
// On Android the engine may be recreated. Here we guarantee that GPU info is sent once per session.
static bool gpuInfoSent = false;
diff --git a/drape/texture.cpp b/drape/texture.cpp
index c198dc2722..e764f5e17b 100644
--- a/drape/texture.cpp
+++ b/drape/texture.cpp
@@ -1,7 +1,7 @@
#include "drape/texture.hpp"
-#include "drape/glfunctions.hpp"
#include "drape/glextensions_list.hpp"
+#include "drape/glfunctions.hpp"
#include "drape/utils/gpu_mem_tracker.hpp"
#include "base/math.hpp"
@@ -10,25 +10,13 @@
namespace dp
{
+Texture::ResourceInfo::ResourceInfo(m2::RectF const & texRect) : m_texRect(texRect) {}
-Texture::ResourceInfo::ResourceInfo(m2::RectF const & texRect)
- : m_texRect(texRect) {}
+m2::RectF const & Texture::ResourceInfo::GetTexRect() const { return m_texRect; }
-m2::RectF const & Texture::ResourceInfo::GetTexRect() const
-{
- return m_texRect;
-}
+Texture::Texture() {}
-//////////////////////////////////////////////////////////////////
-
-Texture::Texture()
-{
-}
-
-Texture::~Texture()
-{
- Destroy();
-}
+Texture::~Texture() { Destroy(); }
void Texture::Create(Params const & params)
{
@@ -42,7 +30,8 @@ void Texture::Create(Params const & params, ref_ptr<void> data)
m_hwTexture->Create(params, data);
}
-void Texture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data)
+void Texture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height,
+ ref_ptr<void> data)
{
ASSERT(m_hwTexture != nullptr, ());
m_hwTexture->UploadData(x, y, width, height, data);
@@ -98,13 +87,10 @@ void Texture::SetFilter(glConst filter)
uint32_t Texture::GetMaxTextureSize()
{
- return GLFunctions::glGetInteger(gl_const::GLMaxTextureSize);
+ return static_cast<uint32_t>(GLFunctions::glGetInteger(gl_const::GLMaxTextureSize));
}
-void Texture::Destroy()
-{
- m_hwTexture.reset();
-}
+void Texture::Destroy() { m_hwTexture.reset(); }
bool Texture::AllocateTexture(ref_ptr<HWTextureAllocator> allocator)
{
@@ -116,5 +102,4 @@ bool Texture::AllocateTexture(ref_ptr<HWTextureAllocator> allocator)
return false;
}
-
-} // namespace dp
+} // namespace dp
diff --git a/drape/texture.hpp b/drape/texture.hpp
index 12237e9622..b795855793 100644
--- a/drape/texture.hpp
+++ b/drape/texture.hpp
@@ -1,9 +1,9 @@
#pragma once
-#include "drape/pointers.hpp"
-#include "drape/glconstants.hpp"
#include "drape/drape_global.hpp"
+#include "drape/glconstants.hpp"
#include "drape/hw_texture.hpp"
+#include "drape/pointers.hpp"
#include "geometry/rect2d.hpp"
@@ -12,7 +12,6 @@
namespace dp
{
-
class Texture
{
public:
@@ -37,7 +36,6 @@ public:
public:
ResourceInfo(m2::RectF const & texRect);
virtual ~ResourceInfo() {}
-
virtual ResourceType GetType() const = 0;
m2::RectF const & GetTexRect() const;
@@ -52,7 +50,6 @@ public:
virtual void UpdateState() {}
virtual bool HasAsyncRoutines() const { return false; }
virtual bool HasEnoughSpace(uint32_t /*newKeysCount*/) const { return true; }
-
using Params = HWTexture::Params;
void Create(Params const & params);
@@ -81,5 +78,4 @@ protected:
private:
drape_ptr<HWTexture> m_hwTexture;
};
-
-} // namespace dp
+} // namespace dp
diff --git a/drape/vertex_array_buffer.cpp b/drape/vertex_array_buffer.cpp
index b812881732..9da306ec15 100644
--- a/drape/vertex_array_buffer.cpp
+++ b/drape/vertex_array_buffer.cpp
@@ -1,14 +1,35 @@
#include "drape/vertex_array_buffer.hpp"
-#include "drape/glfunctions.hpp"
+
#include "drape/glextensions_list.hpp"
+#include "drape/glfunctions.hpp"
#include "drape/index_storage.hpp"
#include "drape/support_manager.hpp"
-#include "base/stl_add.hpp"
#include "base/assert.hpp"
+#include "base/logging.hpp"
namespace dp
{
+namespace
+{
+std::pair<uint32_t, uint32_t> CalculateMappingPart(std::vector<dp::MutateNode> const & nodes)
+{
+ uint32_t minOffset = std::numeric_limits<uint32_t>::max();
+ uint32_t maxOffset = std::numeric_limits<uint32_t>::min();
+ for (size_t i = 0; i < nodes.size(); ++i)
+ {
+ MutateNode const & node = nodes[i];
+ ASSERT_GREATER(node.m_region.m_count, 0, ());
+ if (node.m_region.m_offset < minOffset)
+ minOffset = node.m_region.m_offset;
+ uint32_t const endOffset = node.m_region.m_offset + node.m_region.m_count;
+ if (endOffset > maxOffset)
+ maxOffset = endOffset;
+ }
+ ASSERT_LESS(minOffset, maxOffset, ());
+ return std::make_pair(minOffset, maxOffset - minOffset);
+};
+} // namespace
VertexArrayBuffer::VertexArrayBuffer(uint32_t indexBufferSize, uint32_t dataBufferSize)
: m_VAO(0)
@@ -33,10 +54,10 @@ VertexArrayBuffer::~VertexArrayBuffer()
if (m_VAO != 0)
{
- /// Build called only when VertexArrayBuffer fulled and transfer to FrontendRenderer
- /// but if user move screen before all geometry readed from MWM we delete VertexArrayBuffer on BackendRenderer
- /// in this case m_VAO will be equal a 0
- /// also m_VAO == 0 will be on device that not support OES_vertex_array_object extension
+ // Build is called only when VertexArrayBuffer is full and transferred to FrontendRenderer.
+ // If user move screen before all geometry read from MWM we delete VertexArrayBuffer on
+ // BackendRenderer. In this case m_VAO will be equal 0 also m_VAO == 0 is on devices
+ // that do not support OES_vertex_array_object extension.
GLFunctions::glDeleteVertexArray(m_VAO);
}
}
@@ -52,10 +73,10 @@ void VertexArrayBuffer::PreflushImpl()
ASSERT(!m_isPreflushed, ());
// Buffers are ready, so moving them from CPU to GPU.
- for(auto & buffer : m_staticBuffers)
+ for (auto & buffer : m_staticBuffers)
buffer.second->MoveToGPU(GPUBuffer::ElementBuffer);
- for(auto & buffer : m_dynamicBuffers)
+ for (auto & buffer : m_dynamicBuffers)
buffer.second->MoveToGPU(GPUBuffer::ElementBuffer);
ASSERT(m_indexBuffer != nullptr, ());
@@ -77,16 +98,16 @@ void VertexArrayBuffer::RenderRange(bool drawAsLine, IndicesRange const & range)
if (!(m_staticBuffers.empty() && m_dynamicBuffers.empty()) && GetIndexCount() > 0)
{
ASSERT(m_program != nullptr, ("Somebody not call Build. It's very bad. Very very bad"));
- /// if OES_vertex_array_object is supported than all bindings already saved in VAO
- /// and we need only bind VAO.
+ // If OES_vertex_array_object is supported than all bindings have already saved in VAO
+ // and we need only bind VAO.
if (!Bind())
BindStaticBuffers();
BindDynamicBuffers();
GetIndexBuffer()->Bind();
GLFunctions::glDrawElements(drawAsLine ? gl_const::GLLines : gl_const::GLTriangles,
- dp::IndexStorage::SizeOfIndex(),
- range.m_idxCount, range.m_idxStart);
+ dp::IndexStorage::SizeOfIndex(), range.m_idxCount,
+ range.m_idxStart);
Unbind();
}
@@ -98,10 +119,10 @@ void VertexArrayBuffer::Build(ref_ptr<GpuProgram> program)
PreflushImpl();
if (m_VAO != 0 && m_program == program)
- return;
+ return;
m_program = program;
- /// if OES_vertex_array_object not supported, than buffers will be bind on each Render call
+ // If OES_vertex_array_object not supported, than buffers will be bound on each render call.
if (!GLExtensionsList::Instance().IsSupported(GLExtensionsList::VertexArrayObject))
return;
@@ -116,7 +137,8 @@ void VertexArrayBuffer::Build(ref_ptr<GpuProgram> program)
Unbind();
}
-void VertexArrayBuffer::UploadData(BindingInfo const & bindingInfo, void const * data, uint32_t count)
+void VertexArrayBuffer::UploadData(BindingInfo const & bindingInfo, void const * data,
+ uint32_t count)
{
ref_ptr<DataBuffer> buffer;
if (!bindingInfo.IsDynamic())
@@ -144,35 +166,38 @@ ref_ptr<DataBuffer> VertexArrayBuffer::GetOrCreateStaticBuffer(BindingInfo const
return GetOrCreateBuffer(bindingInfo, false);
}
-ref_ptr<DataBuffer> VertexArrayBuffer::GetBuffer(BindingInfo const & bindingInfo, bool isDynamic) const
+ref_ptr<DataBuffer> VertexArrayBuffer::GetBuffer(BindingInfo const & bindingInfo,
+ bool isDynamic) const
{
- TBuffersMap const * buffers = nullptr;
+ BuffersMap const * buffers = nullptr;
if (isDynamic)
buffers = &m_dynamicBuffers;
else
buffers = &m_staticBuffers;
- TBuffersMap::const_iterator it = buffers->find(bindingInfo);
+ auto it = buffers->find(bindingInfo);
if (it == buffers->end())
return nullptr;
return make_ref(it->second);
}
-ref_ptr<DataBuffer> VertexArrayBuffer::GetOrCreateBuffer(BindingInfo const & bindingInfo, bool isDynamic)
+ref_ptr<DataBuffer> VertexArrayBuffer::GetOrCreateBuffer(BindingInfo const & bindingInfo,
+ bool isDynamic)
{
- TBuffersMap * buffers = nullptr;
+ BuffersMap * buffers = nullptr;
if (isDynamic)
buffers = &m_dynamicBuffers;
else
buffers = &m_staticBuffers;
- TBuffersMap::iterator it = buffers->find(bindingInfo);
+ auto it = buffers->find(bindingInfo);
if (it == buffers->end())
{
- drape_ptr<DataBuffer> dataBuffer = make_unique_dp<DataBuffer>(bindingInfo.GetElementSize(), m_dataBufferSize);
+ drape_ptr<DataBuffer> dataBuffer =
+ make_unique_dp<DataBuffer>(bindingInfo.GetElementSize(), m_dataBufferSize);
ref_ptr<DataBuffer> result = make_ref(dataBuffer);
- (*buffers).insert(make_pair(bindingInfo, move(dataBuffer)));
+ (*buffers).insert(std::make_pair(bindingInfo, move(dataBuffer)));
return result;
}
@@ -190,8 +215,8 @@ uint32_t VertexArrayBuffer::GetAvailableVertexCount() const
return m_dataBufferSize;
#ifdef DEBUG
- TBuffersMap::const_iterator it = m_staticBuffers.begin();
- uint32_t prev = it->second->GetBuffer()->GetAvailableSize();
+ auto it = m_staticBuffers.begin();
+ uint32_t const prev = it->second->GetBuffer()->GetAvailableSize();
for (; it != m_staticBuffers.end(); ++it)
ASSERT_EQUAL(prev, it->second->GetBuffer()->GetAvailableSize(), ());
#endif
@@ -205,8 +230,8 @@ uint32_t VertexArrayBuffer::GetStartIndexValue() const
return 0;
#ifdef DEBUG
- TBuffersMap::const_iterator it = m_staticBuffers.begin();
- uint32_t prev = it->second->GetBuffer()->GetCurrentSize();
+ auto it = m_staticBuffers.begin();
+ uint32_t const prev = it->second->GetBuffer()->GetCurrentSize();
for (; it != m_staticBuffers.end(); ++it)
ASSERT(prev == it->second->GetBuffer()->GetCurrentSize(), ());
#endif
@@ -219,11 +244,7 @@ uint32_t VertexArrayBuffer::GetDynamicBufferOffset(BindingInfo const & bindingIn
return GetOrCreateDynamicBuffer(bindingInfo)->GetBuffer()->GetCurrentSize();
}
-uint32_t VertexArrayBuffer::GetIndexCount() const
-{
- return GetIndexBuffer()->GetCurrentSize();
-}
-
+uint32_t VertexArrayBuffer::GetIndexCount() const { return GetIndexBuffer()->GetCurrentSize(); }
void VertexArrayBuffer::UploadIndexes(void const * data, uint32_t count)
{
ASSERT_LESS_OR_EQUAL(count, GetIndexBuffer()->GetAvailableSize(), ());
@@ -233,8 +254,8 @@ void VertexArrayBuffer::UploadIndexes(void const * data, uint32_t count)
void VertexArrayBuffer::ApplyMutation(ref_ptr<IndexBufferMutator> indexMutator,
ref_ptr<AttributeBufferMutator> attrMutator)
{
- /// We need to bind current VAO before calling glBindBuffer if OES_vertex_array_object is supported.
- /// Otherwise we risk affecting a previously binded VAO.
+ // We need to bind current VAO before calling glBindBuffer if OES_vertex_array_object is
+ // supported. Otherwise we risk affecting a previously bound VAO.
Bind();
if (indexMutator != nullptr)
@@ -254,21 +275,24 @@ void VertexArrayBuffer::ApplyMutation(ref_ptr<IndexBufferMutator> indexMutator,
return;
}
- typedef AttributeBufferMutator::TMutateData TMutateData;
- typedef AttributeBufferMutator::TMutateNodes TMutateNodes;
- TMutateData const & data = attrMutator->GetMutateData();
- for (TMutateData::const_iterator it = data.begin(); it != data.end(); ++it)
+ auto const & data = attrMutator->GetMutateData();
+ for (auto it = data.begin(); it != data.end(); ++it)
{
+ auto const & nodes = it->second;
+ if (nodes.empty())
+ continue;
+
+ auto const offsets = CalculateMappingPart(nodes);
+
ref_ptr<DataBuffer> buffer = GetDynamicBuffer(it->first);
ASSERT(buffer != nullptr, ());
- DataBufferMapper mapper(buffer);
- TMutateNodes const & nodes = it->second;
-
+ DataBufferMapper mapper(buffer, offsets.first, offsets.second);
for (size_t i = 0; i < nodes.size(); ++i)
{
MutateNode const & node = nodes[i];
ASSERT_GREATER(node.m_region.m_count, 0, ());
- mapper.UpdateData(node.m_data.get(), node.m_region.m_offset, node.m_region.m_count);
+ mapper.UpdateData(node.m_data.get(), node.m_region.m_offset - offsets.first,
+ node.m_region.m_count);
}
}
@@ -292,20 +316,11 @@ void VertexArrayBuffer::Unbind() const
GLFunctions::glBindVertexArray(0);
}
-void VertexArrayBuffer::BindStaticBuffers() const
-{
- BindBuffers(m_staticBuffers);
-}
-
-void VertexArrayBuffer::BindDynamicBuffers() const
+void VertexArrayBuffer::BindStaticBuffers() const { BindBuffers(m_staticBuffers); }
+void VertexArrayBuffer::BindDynamicBuffers() const { BindBuffers(m_dynamicBuffers); }
+void VertexArrayBuffer::BindBuffers(BuffersMap const & buffers) const
{
- BindBuffers(m_dynamicBuffers);
-}
-
-void VertexArrayBuffer::BindBuffers(TBuffersMap const & buffers) const
-{
- TBuffersMap::const_iterator it = buffers.begin();
- for (; it != buffers.end(); ++it)
+ for (auto it = buffers.begin(); it != buffers.end(); ++it)
{
BindingInfo const & binding = it->first;
ref_ptr<DataBuffer> buffer = make_ref(it->second);
@@ -317,11 +332,8 @@ void VertexArrayBuffer::BindBuffers(TBuffersMap const & buffers) const
int8_t attributeLocation = m_program->GetAttributeLocation(decl.m_attributeName);
assert(attributeLocation != -1);
GLFunctions::glEnableVertexAttribute(attributeLocation);
- GLFunctions::glVertexAttributePointer(attributeLocation,
- decl.m_componentCount,
- decl.m_componentType,
- false,
- decl.m_stride,
+ GLFunctions::glVertexAttributePointer(attributeLocation, decl.m_componentCount,
+ decl.m_componentType, false, decl.m_stride,
decl.m_offset);
}
}
@@ -332,5 +344,4 @@ ref_ptr<DataBufferBase> VertexArrayBuffer::GetIndexBuffer() const
ASSERT(m_indexBuffer != nullptr, ());
return m_indexBuffer->GetBuffer();
}
-
-} // namespace dp
+} // namespace dp
diff --git a/drape/vertex_array_buffer.hpp b/drape/vertex_array_buffer.hpp
index baab293954..49fc1c67e2 100644
--- a/drape/vertex_array_buffer.hpp
+++ b/drape/vertex_array_buffer.hpp
@@ -1,14 +1,14 @@
#pragma once
-#include "drape/index_buffer_mutator.hpp"
#include "drape/attribute_buffer_mutator.hpp"
-#include "drape/pointers.hpp"
-#include "drape/index_buffer.hpp"
-#include "drape/data_buffer.hpp"
#include "drape/binding_info.hpp"
+#include "drape/data_buffer.hpp"
#include "drape/gpu_program.hpp"
+#include "drape/index_buffer.hpp"
+#include "drape/index_buffer_mutator.hpp"
+#include "drape/pointers.hpp"
-#include "std/map.hpp"
+#include <map>
namespace df
{
@@ -17,42 +17,34 @@ class BatchMergeHelper;
namespace dp
{
-
struct IndicesRange
{
uint32_t m_idxStart;
uint32_t m_idxCount;
- IndicesRange()
- : m_idxStart(0), m_idxCount(0)
- {}
-
- IndicesRange(uint32_t idxStart, uint32_t idxCount)
- : m_idxStart(idxStart), m_idxCount(idxCount)
- {}
-
+ IndicesRange() : m_idxStart(0), m_idxCount(0) {}
+ IndicesRange(uint32_t idxStart, uint32_t idxCount) : m_idxStart(idxStart), m_idxCount(idxCount) {}
bool IsValid() const { return m_idxCount != 0; }
};
class VertexArrayBuffer
{
- typedef map<BindingInfo, drape_ptr<DataBuffer> > TBuffersMap;
+ using BuffersMap = std::map<BindingInfo, drape_ptr<DataBuffer>>;
friend class df::BatchMergeHelper;
+
public:
VertexArrayBuffer(uint32_t indexBufferSize, uint32_t dataBufferSize);
~VertexArrayBuffer();
- /// This method must be call on reading thread, before VAO will be transfer on render thread
+ // This method must be call on reading thread, before VAO will be transfered on render thread.
void Preflush();
- ///{@
- /// On devices where implemented OES_vertex_array_object extensions we use it for build VertexArrayBuffer
- /// OES_vertex_array_object create OpenGL resource that belong only one GL context (which was created by)
- /// by this reason Build/Bind and Render must be called only on Frontendrendere thread
+ // OES_vertex_array_object create OpenGL resource that belong only one GL context (which was
+ // created by). By this reason Build/Bind and Render must be called only on FrontendRenderer
+ // thread.
void Render(bool drawAsLine);
void RenderRange(bool drawAsLine, IndicesRange const & range);
void Build(ref_ptr<GpuProgram> program);
- ///@}
uint32_t GetAvailableVertexCount() const;
uint32_t GetAvailableIndexCount() const;
@@ -68,7 +60,6 @@ public:
void ResetChangingTracking() { m_isChanged = false; }
bool IsChanged() const { return m_isChanged; }
-
private:
ref_ptr<DataBuffer> GetOrCreateStaticBuffer(BindingInfo const & bindingInfo);
ref_ptr<DataBuffer> GetOrCreateDynamicBuffer(BindingInfo const & bindingInfo);
@@ -80,17 +71,17 @@ private:
void Unbind() const;
void BindStaticBuffers() const;
void BindDynamicBuffers() const;
- void BindBuffers(TBuffersMap const & buffers) const;
+ void BindBuffers(BuffersMap const & buffers) const;
ref_ptr<DataBufferBase> GetIndexBuffer() const;
void PreflushImpl();
private:
- /// m_VAO - VertexArrayObject name/identificator
+ // m_VAO - VertexArrayObject name/identifier.
int m_VAO;
- TBuffersMap m_staticBuffers;
- TBuffersMap m_dynamicBuffers;
+ BuffersMap m_staticBuffers;
+ BuffersMap m_dynamicBuffers;
drape_ptr<IndexBuffer> m_indexBuffer;
uint32_t m_dataBufferSize;
@@ -101,5 +92,4 @@ private:
bool m_moveToGpuOnBuild;
bool m_isChanged;
};
-
-} // namespace dp
+} // namespace dp
diff --git a/drape/viewport.cpp b/drape/viewport.cpp
new file mode 100644
index 0000000000..f36b1b6cc1
--- /dev/null
+++ b/drape/viewport.cpp
@@ -0,0 +1,25 @@
+#include "drape/viewport.hpp"
+#include "drape/glfunctions.hpp"
+
+namespace dp
+{
+Viewport::Viewport(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h) : m_zero(x0, y0), m_size(w, h)
+{
+}
+
+void Viewport::SetViewport(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h)
+{
+ m_zero = m2::PointU(x0, y0);
+ m_size = m2::PointU(w, h);
+}
+
+uint32_t Viewport::GetX0() const { return m_zero.x; }
+uint32_t Viewport::GetY0() const { return m_zero.y; }
+uint32_t Viewport::GetWidth() const { return m_size.x; }
+uint32_t Viewport::GetHeight() const { return m_size.y; }
+void Viewport::Apply() const
+{
+ GLCHECK(GLFunctions::glViewport(GetX0(), GetY0(), GetWidth(), GetHeight()));
+ GLCHECK(GLFunctions::glScissor(GetX0(), GetY0(), GetWidth(), GetHeight()));
+}
+} // namespace dp
diff --git a/drape/viewport.hpp b/drape/viewport.hpp
new file mode 100644
index 0000000000..65dcffffa3
--- /dev/null
+++ b/drape/viewport.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "geometry/point2d.hpp"
+
+namespace dp
+{
+// Pixel ratio independent viewport implementation.
+// pixelRatio is ratio between physical pixels and device-independent pixels for the window.
+class Viewport
+{
+public:
+ // x0, y0, w, h is device-independent pixels
+ Viewport(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h);
+
+ // On iOS we must multiply this on scaleFactor.
+ // On Android we get true size from surface.
+ void SetViewport(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h);
+
+ uint32_t GetX0() const;
+ uint32_t GetY0() const;
+ uint32_t GetWidth() const;
+ uint32_t GetHeight() const;
+
+ // Apply viewport to graphics pipeline with convert start point and size to physical pixels.
+ void Apply() const;
+
+private:
+ m2::PointU m_zero;
+ m2::PointU m_size;
+};
+} // namespace dp