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
diff options
context:
space:
mode:
authorr.kuznetsov <r.kuznetsov@corp.mail.ru>2018-09-05 15:20:10 +0300
committerAleksey Belousov <beloal@users.noreply.github.com>2018-09-25 12:33:08 +0300
commitd1074729e0d0c63ab887efb866903bc99181f919 (patch)
treef1d70b92271c7c09eae2293a2b233572730be13c
parenta81f1fc4d1f698a0f0aaaa1e7a29f41516b05d11 (diff)
[drape][metal] Fixed unit tests, refactored a bit CurrentApiVersion.
-rw-r--r--drape/drape_tests/CMakeLists.txt1
-rw-r--r--drape/drape_tests/font_texture_tests.cpp8
-rw-r--r--drape/drape_tests/gl_functions.cpp3
-rw-r--r--drape/drape_tests/static_texture_tests.cpp6
-rw-r--r--drape/drape_tests/testing_graphics_context.hpp29
-rw-r--r--drape/drape_tests/texture_of_colors_tests.cpp18
-rw-r--r--drape/dynamic_texture.hpp6
-rw-r--r--drape/font_texture.hpp4
-rw-r--r--drape/gl_extensions_list.cpp9
-rw-r--r--drape/gl_extensions_list.hpp6
-rw-r--r--drape/gl_functions.cpp6
-rw-r--r--drape/gl_functions.hpp2
-rw-r--r--drape/gl_gpu_program.cpp4
-rw-r--r--drape/gpu_buffer.cpp2
-rw-r--r--drape/hw_texture.cpp42
-rw-r--r--drape/hw_texture.hpp9
-rw-r--r--drape/hw_texture_ios.mm2
-rw-r--r--drape/index_storage.cpp2
-rw-r--r--drape/mesh_object.cpp12
-rw-r--r--drape/metal/metal_base_context.hpp3
-rw-r--r--drape/metal/metal_base_context.mm7
-rw-r--r--drape/metal/metal_gpu_program.hpp36
-rw-r--r--drape/metal/metal_states.hpp20
-rw-r--r--drape/metal/metal_states.mm145
-rw-r--r--drape/metal/metal_texture.mm2
-rw-r--r--drape/metal/render_state_metal.mm8
-rw-r--r--drape/render_state.cpp13
-rw-r--r--drape/static_texture.cpp12
-rw-r--r--drape/stipple_pen_resource.hpp2
-rw-r--r--drape/symbols_texture.cpp8
-rw-r--r--drape/texture.cpp2
-rw-r--r--drape/vertex_array_buffer.cpp6
-rw-r--r--drape_frontend/arrow3d.cpp1
-rw-r--r--drape_frontend/debug_rect_renderer.cpp10
-rw-r--r--drape_frontend/postprocess_renderer.cpp8
-rw-r--r--drape_frontend/screen_quad_renderer.cpp4
-rw-r--r--shaders/Metal/debug_rect.metal7
-rw-r--r--shaders/Metal/screen_quad.metal8
-rw-r--r--shaders/metal_program_pool.hpp1
-rw-r--r--shaders/metal_program_pool.mm71
40 files changed, 391 insertions, 154 deletions
diff --git a/drape/drape_tests/CMakeLists.txt b/drape/drape_tests/CMakeLists.txt
index 81ded8bc74..b8ae948a17 100644
--- a/drape/drape_tests/CMakeLists.txt
+++ b/drape/drape_tests/CMakeLists.txt
@@ -34,6 +34,7 @@ set(
static_texture_tests.cpp
stipple_pen_tests.cpp
texture_of_colors_tests.cpp
+ testing_graphics_context.hpp
testingmain.cpp
uniform_value_tests.cpp
)
diff --git a/drape/drape_tests/font_texture_tests.cpp b/drape/drape_tests/font_texture_tests.cpp
index ecb1fe186d..8326b3b35a 100644
--- a/drape/drape_tests/font_texture_tests.cpp
+++ b/drape/drape_tests/font_texture_tests.cpp
@@ -1,6 +1,7 @@
#include "drape/drape_tests/dummy_texture.hpp"
#include "drape/drape_tests/gl_mock_functions.hpp"
#include "drape/drape_tests/img.hpp"
+#include "drape/drape_tests/testing_graphics_context.hpp"
#include "platform/platform.hpp"
#include "qt_tstfrm/test_main_loop.hpp"
@@ -30,7 +31,7 @@ namespace
class UploadedRender
{
public:
- UploadedRender(QPoint const & pen) : m_pen(pen) {}
+ explicit UploadedRender(QPoint const & pen) : m_pen(pen) {}
void glMemoryToQImage(int x, int y, int w, int h, glConst f, glConst t, void const * memory)
{
@@ -101,13 +102,14 @@ UNIT_TEST(UploadingGlyphs)
while (index.GetPendingNodesCount() < count)
;
+ TestingGraphicsContext context;
Texture::Params p;
- p.m_allocator = GetDefaultAllocator(nullptr /* context */);
+ p.m_allocator = GetDefaultAllocator(make_ref(&context));
p.m_format = dp::TextureFormat::Alpha;
p.m_width = p.m_height = 128;
DummyTexture tex;
- tex.Create(nullptr /* context */, p);
+ tex.Create(make_ref(&context), p);
EXPECTGL(glTexSubImage2D(_, _, _, _, _, _, _))
.WillRepeatedly(Invoke(&r, &UploadedRender::glMemoryToQImage));
index.UploadResources(make_ref(&tex));
diff --git a/drape/drape_tests/gl_functions.cpp b/drape/drape_tests/gl_functions.cpp
index 74e734b4b7..396d239c98 100644
--- a/drape/drape_tests/gl_functions.cpp
+++ b/drape/drape_tests/gl_functions.cpp
@@ -7,7 +7,8 @@
using namespace emul;
-dp::ApiVersion GLFunctions::CurrentApiVersion = dp::ApiVersion::OpenGLES2;
+dp::ApiVersion GLFunctions::CurrentApiVersion = dp::ApiVersion::Invalid;
+dp::GLExtensionsList GLFunctions::ExtensionsList;
#define MOCK_CALL(f) GLMockFunctions::Instance().f;
diff --git a/drape/drape_tests/static_texture_tests.cpp b/drape/drape_tests/static_texture_tests.cpp
index b6c2a83558..0366a0cb1b 100644
--- a/drape/drape_tests/static_texture_tests.cpp
+++ b/drape/drape_tests/static_texture_tests.cpp
@@ -3,6 +3,7 @@
#include "indexer/map_style.hpp"
#include "indexer/map_style_reader.hpp"
+#include "drape/drape_tests/testing_graphics_context.hpp"
#include "drape/static_texture.hpp"
#include <string>
@@ -15,16 +16,17 @@ UNIT_TEST(CheckTrafficArrowTextures)
MapStyle::MapStyleVehicleClear,
MapStyle::MapStyleVehicleDark};
+ TestingGraphicsContext context;
for (auto const & style : styles)
{
GetStyleReader().SetCurrentStyle(style);
for (size_t i = 0; i < skinPaths.size(); ++i)
{
- dp::StaticTexture texture(nullptr /* context */, "traffic-arrow", skinPaths[i],
+ dp::StaticTexture texture(make_ref(&context), "traffic-arrow", skinPaths[i],
dp::TextureFormat::RGBA8, nullptr);
TEST(texture.IsLoadingCorrect(), ());
- dp::StaticTexture texture2(nullptr /* context */, "area-hatching", skinPaths[i],
+ dp::StaticTexture texture2(make_ref(&context), "area-hatching", skinPaths[i],
dp::TextureFormat::RGBA8, nullptr);
TEST(texture2.IsLoadingCorrect(), ());
}
diff --git a/drape/drape_tests/testing_graphics_context.hpp b/drape/drape_tests/testing_graphics_context.hpp
new file mode 100644
index 0000000000..b65fdfe6f3
--- /dev/null
+++ b/drape/drape_tests/testing_graphics_context.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "drape/graphics_context.hpp"
+
+// Testing context simulates OpenGLES2 API version.
+class TestingGraphicsContext : public dp::GraphicsContext
+{
+public:
+ void Present() override {}
+ void MakeCurrent() override {}
+ void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override {}
+ void ApplyFramebuffer(std::string const & framebufferLabel) override {}
+
+ void Init(dp::ApiVersion apiVersion) override {}
+ dp::ApiVersion GetApiVersion() const override { return dp::ApiVersion::OpenGLES2; }
+ std::string GetRendererName() const override { return {}; }
+ std::string GetRendererVersion() const override { return {}; }
+
+ void SetClearColor(dp::Color const & color) override {}
+ void Clear(uint32_t clearBits) override {}
+ void Flush() override {}
+ void SetViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override {}
+ void SetDepthTestEnabled(bool enabled) override {}
+ void SetDepthTestFunction(dp::TestFunction depthFunction) override {}
+ void SetStencilTestEnabled(bool enabled) override {}
+ void SetStencilFunction(dp::StencilFace face, dp::TestFunction stencilFunction) override {}
+ void SetStencilActions(dp::StencilFace face, dp::StencilAction stencilFailAction,
+ dp::StencilAction depthFailAction, dp::StencilAction passAction) override {}
+};
diff --git a/drape/drape_tests/texture_of_colors_tests.cpp b/drape/drape_tests/texture_of_colors_tests.cpp
index 201c01d721..40667db35d 100644
--- a/drape/drape_tests/texture_of_colors_tests.cpp
+++ b/drape/drape_tests/texture_of_colors_tests.cpp
@@ -1,7 +1,8 @@
#include "testing/testing.hpp"
-#include "drape/drape_tests/memory_comparer.hpp"
#include "drape/drape_tests/dummy_texture.hpp"
+#include "drape/drape_tests/memory_comparer.hpp"
+#include "drape/drape_tests/testing_graphics_context.hpp"
#include "drape/gl_constants.hpp"
#include "drape/texture_of_colors.hpp"
@@ -93,14 +94,15 @@ UNIT_TEST(ColorPalleteUploadingSingleRow)
int const height = 16;
InitOpenGLTextures(width, height);
+ TestingGraphicsContext context;
Texture::Params p;
- p.m_allocator = GetDefaultAllocator(nullptr /* context */);
+ p.m_allocator = GetDefaultAllocator(make_ref(&context));
p.m_format = dp::TextureFormat::RGBA8;
p.m_width = width;
p.m_height = height;
DummyTexture texture;
- texture.Create(nullptr /* context */, p);
+ texture.Create(make_ref(&context), p);
DummyColorPallete cp(m2::PointU(width, height));
cp.UploadResources(make_ref(&texture));
@@ -191,14 +193,15 @@ UNIT_TEST(ColorPalleteUploadingPartialyRow)
int const height = 8;
InitOpenGLTextures(width, height);
+ TestingGraphicsContext context;
Texture::Params p;
- p.m_allocator = GetDefaultAllocator(nullptr /* context */);
+ p.m_allocator = GetDefaultAllocator(make_ref(&context));
p.m_format = dp::TextureFormat::RGBA8;
p.m_width = width;
p.m_height = height;
DummyTexture texture;
- texture.Create(nullptr /* context */, p);
+ texture.Create(make_ref(&context), p);
DummyColorPallete cp(m2::PointU(width, height));
@@ -279,14 +282,15 @@ UNIT_TEST(ColorPalleteUploadingMultiplyRow)
int const height = 8;
InitOpenGLTextures(width, height);
+ TestingGraphicsContext context;
Texture::Params p;
- p.m_allocator = GetDefaultAllocator(nullptr /* context */);
+ p.m_allocator = GetDefaultAllocator(make_ref(&context));
p.m_format = dp::TextureFormat::RGBA8;
p.m_width = width;
p.m_height = height;
DummyTexture texture;
- texture.Create(nullptr /* context */, p);
+ texture.Create(make_ref(&context), p);
DummyColorPallete cp(m2::PointU(width, height));
cp.SetIsDebug(true);
diff --git a/drape/dynamic_texture.hpp b/drape/dynamic_texture.hpp
index 0ff603a76d..3ae46646d2 100644
--- a/drape/dynamic_texture.hpp
+++ b/drape/dynamic_texture.hpp
@@ -29,14 +29,14 @@ public:
void Create(ref_ptr<dp::GraphicsContext> context, Params const & params) override
{
ASSERT(Base::IsPowerOfTwo(params.m_width, params.m_height), (params.m_width, params.m_height));
- Base::Create(std::move(context), params);
+ Base::Create(context, params);
}
void Create(ref_ptr<dp::GraphicsContext> context, Params const & params,
ref_ptr<void> data) override
{
ASSERT(Base::IsPowerOfTwo(params.m_width, params.m_height), (params.m_width, params.m_height));
- Base::Create(std::move(context), params, data);
+ Base::Create(context, params, data);
}
void UpdateState(ref_ptr<dp::GraphicsContext> context) override
@@ -46,7 +46,7 @@ public:
{
std::vector<uint8_t> initData(m_params.m_width * m_params.m_height *
GetBytesPerPixel(m_params.m_format), 0);
- Create(std::move(context), m_params, initData.data());
+ Create(context, m_params, initData.data());
m_isInitialized = true;
}
diff --git a/drape/font_texture.hpp b/drape/font_texture.hpp
index e7fd2bf0c5..e5aac49c89 100644
--- a/drape/font_texture.hpp
+++ b/drape/font_texture.hpp
@@ -117,11 +117,11 @@ class FontTexture : public DynamicTexture<GlyphIndex, GlyphKey, Texture::Resourc
public:
FontTexture(m2::PointU const & size, ref_ptr<GlyphManager> glyphMng,
ref_ptr<GlyphGenerator> glyphGenerator, ref_ptr<HWTextureAllocator> allocator)
- : m_index(size, std::move(glyphMng), std::move(glyphGenerator))
+ : m_index(size, glyphMng, glyphGenerator)
{
TBase::DynamicTextureParams params{size, TextureFormat::Alpha,
TextureFilter::Linear, true /* m_usePixelBuffer */};
- TBase::Init(std::move(allocator), make_ref(&m_index), params);
+ TBase::Init(allocator, make_ref(&m_index), params);
}
~FontTexture() override { TBase::Reset(); }
diff --git a/drape/gl_extensions_list.cpp b/drape/gl_extensions_list.cpp
index 29c6de1988..f6313379bc 100644
--- a/drape/gl_extensions_list.cpp
+++ b/drape/gl_extensions_list.cpp
@@ -7,7 +7,7 @@
namespace dp
{
-GLExtensionsList::GLExtensionsList(dp::ApiVersion apiVersion)
+void GLExtensionsList::Init(dp::ApiVersion apiVersion)
{
#if defined(OMIM_OS_MOBILE)
if (apiVersion == dp::ApiVersion::OpenGLES2)
@@ -66,13 +66,6 @@ GLExtensionsList::GLExtensionsList(dp::ApiVersion apiVersion)
#endif
}
-// static
-GLExtensionsList & GLExtensionsList::Instance()
-{
- static GLExtensionsList extList(GLFunctions::CurrentApiVersion);
- return extList;
-}
-
bool GLExtensionsList::IsSupported(ExtensionName extName) const
{
auto const it = m_supportedMap.find(extName);
diff --git a/drape/gl_extensions_list.hpp b/drape/gl_extensions_list.hpp
index 5f2f18370f..c5fb4dfc1b 100644
--- a/drape/gl_extensions_list.hpp
+++ b/drape/gl_extensions_list.hpp
@@ -20,12 +20,12 @@ public:
MapBufferRange
};
- static GLExtensionsList & Instance();
-
+ GLExtensionsList() = default;
+ void Init(dp::ApiVersion apiVersion);
bool IsSupported(ExtensionName extName) const;
private:
- GLExtensionsList(dp::ApiVersion apiVersion);
+
void CheckExtension(ExtensionName enumName, std::string const & extName);
void SetExtension(ExtensionName enumName, bool isSupported);
diff --git a/drape/gl_functions.cpp b/drape/gl_functions.cpp
index 77df358c75..ddde95461c 100644
--- a/drape/gl_functions.cpp
+++ b/drape/gl_functions.cpp
@@ -23,6 +23,9 @@
// static
dp::ApiVersion GLFunctions::CurrentApiVersion = dp::ApiVersion::Invalid;
+// static
+dp::GLExtensionsList GLFunctions::ExtensionsList;
+
namespace
{
#ifdef DEBUG
@@ -222,6 +225,7 @@ void GLFunctions::Init(dp::ApiVersion apiVersion)
return;
CurrentApiVersion = apiVersion;
+ ExtensionsList.Init(apiVersion);
s_inited = true;
/// VAO
@@ -306,7 +310,7 @@ void GLFunctions::Init(dp::ApiVersion apiVersion)
ASSERT(false, ("Unknown Graphics API"));
}
#elif defined(OMIM_OS_WINDOWS)
- if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject))
+ if (ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject))
{
glGenVertexArraysFn = LOAD_GL_FUNC(TglGenVertexArraysFn, glGenVertexArrays);
glBindVertexArrayFn = LOAD_GL_FUNC(TglBindVertexArrayFn, glBindVertexArray);
diff --git a/drape/gl_functions.hpp b/drape/gl_functions.hpp
index 79c769c55b..b3b2d6068d 100644
--- a/drape/gl_functions.hpp
+++ b/drape/gl_functions.hpp
@@ -2,6 +2,7 @@
#include "drape/drape_global.hpp"
#include "drape/gl_constants.hpp"
+#include "drape/gl_extensions_list.hpp"
#include "base/src_point.hpp"
@@ -12,6 +13,7 @@ class GLFunctions
{
public:
static dp::ApiVersion CurrentApiVersion;
+ static dp::GLExtensionsList ExtensionsList;
static void Init(dp::ApiVersion apiVersion);
diff --git a/drape/gl_gpu_program.cpp b/drape/gl_gpu_program.cpp
index 9aeeb7fbfa..3a3bfedbcf 100644
--- a/drape/gl_gpu_program.cpp
+++ b/drape/gl_gpu_program.cpp
@@ -12,8 +12,8 @@ namespace dp
GLGpuProgram::GLGpuProgram(std::string const & programName,
ref_ptr<Shader> vertexShader, ref_ptr<Shader> fragmentShader)
: GpuProgram(programName)
- , m_vertexShader(std::move(vertexShader))
- , m_fragmentShader(std::move(fragmentShader))
+ , m_vertexShader(vertexShader)
+ , m_fragmentShader(fragmentShader)
{
m_programID = GLFunctions::glCreateProgram();
GLFunctions::glAttachShader(m_programID, m_vertexShader->GetID());
diff --git a/drape/gpu_buffer.cpp b/drape/gpu_buffer.cpp
index f85bf6b62d..7c80e85887 100644
--- a/drape/gpu_buffer.cpp
+++ b/drape/gpu_buffer.cpp
@@ -15,7 +15,7 @@ namespace
bool IsMapBufferSupported()
{
static bool const isSupported =
- GLExtensionsList::Instance().IsSupported(GLExtensionsList::MapBuffer);
+ GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::MapBuffer);
return isSupported;
}
diff --git a/drape/hw_texture.cpp b/drape/hw_texture.cpp
index e7295a74be..a14a5a47d9 100644
--- a/drape/hw_texture.cpp
+++ b/drape/hw_texture.cpp
@@ -18,9 +18,11 @@ extern ref_ptr<dp::HWTextureAllocator> GetDefaultMetalAllocator();
namespace dp
{
-void UnpackFormat(TextureFormat format, glConst & layout, glConst & pixelType)
+void UnpackFormat(ref_ptr<dp::GraphicsContext> context, TextureFormat format,
+ glConst & layout, glConst & pixelType)
{
- auto const apiVersion = GLFunctions::CurrentApiVersion;
+ CHECK(context != nullptr, ());
+ auto const apiVersion = context->GetApiVersion();
CHECK(apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3, ());
switch (format)
@@ -58,14 +60,11 @@ void UnpackFormat(TextureFormat format, glConst & layout, glConst & pixelType)
CHECK(false, ());
return;
}
- ASSERT(false, ());
+ CHECK_SWITCH();
}
glConst DecodeTextureFilter(TextureFilter filter)
{
- auto const apiVersion = GLFunctions::CurrentApiVersion;
- CHECK(apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3, ());
-
switch (filter)
{
case TextureFilter::Linear: return gl_const::GLLinear;
@@ -76,9 +75,6 @@ glConst DecodeTextureFilter(TextureFilter filter)
glConst DecodeTextureWrapping(TextureWrapping wrapping)
{
- auto const apiVersion = GLFunctions::CurrentApiVersion;
- CHECK(apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3, ());
-
switch (wrapping)
{
case TextureWrapping::ClampToEdge: return gl_const::GLClampToEdge;
@@ -97,7 +93,7 @@ HWTexture::~HWTexture()
void HWTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params)
{
- Create(std::move(context), params, nullptr);
+ Create(context, params, nullptr);
}
void HWTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params,
@@ -168,17 +164,16 @@ OpenGLHWTexture::~OpenGLHWTexture()
void OpenGLHWTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params,
ref_ptr<void> data)
{
- Base::Create(std::move(context), params, data);
+ Base::Create(context, params, data);
m_textureID = GLFunctions::glGenTexture();
Bind();
- glConst layout;
- glConst pixelType;
- UnpackFormat(m_params.m_format, layout, pixelType);
+ UnpackFormat(context, m_params.m_format, m_unpackedLayout, m_unpackedPixelType);
auto const f = DecodeTextureFilter(m_params.m_filter);
- GLFunctions::glTexImage2D(m_params.m_width, m_params.m_height, layout, pixelType, data.get());
+ GLFunctions::glTexImage2D(m_params.m_width, m_params.m_height,
+ m_unpackedLayout, m_unpackedPixelType, data.get());
GLFunctions::glTexParameter(gl_const::GLMinFilter, f);
GLFunctions::glTexParameter(gl_const::GLMagFilter, f);
GLFunctions::glTexParameter(gl_const::GLWrapS, DecodeTextureWrapping(m_params.m_wrapSMode));
@@ -201,22 +196,18 @@ void OpenGLHWTexture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_
ref_ptr<void> data)
{
ASSERT(Validate(), ());
- glConst layout;
- glConst pixelType;
- UnpackFormat(m_params.m_format, layout, pixelType);
-
uint32_t const mappingSize = height * width * m_pixelBufferElementSize;
if (m_pixelBufferID != 0 && m_pixelBufferSize != 0 && m_pixelBufferSize >= mappingSize)
{
ASSERT_GREATER(m_pixelBufferElementSize, 0, ());
GLFunctions::glBindBuffer(m_pixelBufferID, gl_const::GLPixelBufferWrite);
GLFunctions::glBufferSubData(gl_const::GLPixelBufferWrite, mappingSize, data.get(), 0);
- GLFunctions::glTexSubImage2D(x, y, width, height, layout, pixelType, nullptr);
+ GLFunctions::glTexSubImage2D(x, y, width, height, m_unpackedLayout, m_unpackedPixelType, nullptr);
GLFunctions::glBindBuffer(0, gl_const::GLPixelBufferWrite);
}
else
{
- GLFunctions::glTexSubImage2D(x, y, width, height, layout, pixelType, data.get());
+ GLFunctions::glTexSubImage2D(x, y, width, height, m_unpackedLayout, m_unpackedPixelType, data.get());
}
}
@@ -257,10 +248,7 @@ void OpenGLHWTextureAllocator::Flush()
drape_ptr<HWTextureAllocator> CreateAllocator(ref_ptr<dp::GraphicsContext> context)
{
- // Context can be nullptr in unit tests.
- if (!context)
- return make_unique_dp<OpenGLHWTextureAllocator>();
-
+ CHECK(context != nullptr, ());
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::Metal)
{
@@ -283,8 +271,8 @@ drape_ptr<HWTextureAllocator> CreateAllocator(ref_ptr<dp::GraphicsContext> conte
ref_ptr<HWTextureAllocator> GetDefaultAllocator(ref_ptr<dp::GraphicsContext> context)
{
- // Context can be nullptr in unit tests.
- if (context && context->GetApiVersion() == dp::ApiVersion::Metal)
+ CHECK(context != nullptr, ());
+ if (context->GetApiVersion() == dp::ApiVersion::Metal)
{
#if defined(OMIM_OS_IPHONE)
return GetDefaultMetalAllocator();
diff --git a/drape/hw_texture.hpp b/drape/hw_texture.hpp
index c7ccb2303b..f780550897 100644
--- a/drape/hw_texture.hpp
+++ b/drape/hw_texture.hpp
@@ -50,6 +50,8 @@ public:
uint32_t GetHeight() const;
float GetS(uint32_t x) const;
float GetT(uint32_t y) const;
+
+ Params const & GetParams() const { return m_params; }
uint32_t GetID() const;
@@ -83,6 +85,10 @@ public:
void Bind() const override;
void SetFilter(TextureFilter filter) override;
bool Validate() const override;
+
+private:
+ glConst m_unpackedLayout = 0;
+ glConst m_unpackedPixelType = 0;
};
class OpenGLHWTextureAllocator : public HWTextureAllocator
@@ -95,7 +101,8 @@ public:
ref_ptr<HWTextureAllocator> GetDefaultAllocator(ref_ptr<dp::GraphicsContext> context);
drape_ptr<HWTextureAllocator> CreateAllocator(ref_ptr<dp::GraphicsContext> context);
-void UnpackFormat(TextureFormat format, glConst & layout, glConst & pixelType);
+void UnpackFormat(ref_ptr<dp::GraphicsContext> context, TextureFormat format,
+ glConst & layout, glConst & pixelType);
glConst DecodeTextureFilter(TextureFilter filter);
glConst DecodeTextureWrapping(TextureWrapping wrapping);
} // namespace dp
diff --git a/drape/hw_texture_ios.mm b/drape/hw_texture_ios.mm
index 914cc31348..17a9526f80 100644
--- a/drape/hw_texture_ios.mm
+++ b/drape/hw_texture_ios.mm
@@ -151,7 +151,7 @@ void HWTextureApple::Create(ref_ptr<dp::GraphicsContext> context, Params const &
m_directBuffer = m_allocator->CVCreatePixelBuffer(m_params.m_width, m_params.m_height, params.m_format);
glConst layout, pixelType;
- UnpackFormat(params.m_format, layout, pixelType);
+ UnpackFormat(context, params.m_format, layout, pixelType);
m_texture = m_allocator->CVCreateTexture(m_directBuffer, params.m_width, params.m_height,
layout, pixelType);
diff --git a/drape/index_storage.cpp b/drape/index_storage.cpp
index 2bc08259de..52322a4a98 100644
--- a/drape/index_storage.cpp
+++ b/drape/index_storage.cpp
@@ -57,7 +57,7 @@ void const * IndexStorage::GetRawConst() const
bool IndexStorage::IsSupported32bit()
{
// We do not use 32-bit indices now to reduce size of index buffers.
- static bool const supports32Bit = false;//GLExtensionsList::Instance().IsSupported(GLExtensionsList::UintIndices);
+ static bool const supports32Bit = false;//GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::UintIndices);
return supports32Bit;
}
diff --git a/drape/mesh_object.cpp b/drape/mesh_object.cpp
index 0ce9c267fe..edd92a7266 100644
--- a/drape/mesh_object.cpp
+++ b/drape/mesh_object.cpp
@@ -28,7 +28,7 @@ class GLMeshObjectImpl : public MeshObjectImpl
{
public:
explicit GLMeshObjectImpl(ref_ptr<dp::MeshObject> mesh)
- : m_mesh(std::move(mesh))
+ : m_mesh(mesh)
{}
void Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program) override
@@ -36,7 +36,7 @@ public:
UNUSED_VALUE(context);
bool const isVAOSupported =
- dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject);
+ GLFunctions::ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject);
if (isVAOSupported)
{
m_VAO = GLFunctions::glGenVertexArray();
@@ -104,7 +104,7 @@ public:
void Bind(ref_ptr<dp::GpuProgram> program) override
{
- if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject))
+ if (GLFunctions::ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject))
{
GLFunctions::glBindVertexArray(m_VAO);
return;
@@ -128,7 +128,7 @@ public:
void Unbind(ref_ptr<dp::GpuProgram> program) override
{
- if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject))
+ if (GLFunctions::ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject))
GLFunctions::glBindVertexArray(0);
GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
}
@@ -220,7 +220,7 @@ void MeshObject::Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProg
Reset();
CHECK(m_impl != nullptr, ());
- m_impl->Build(std::move(context), std::move(program));
+ m_impl->Build(context, program);
m_initialized = true;
}
@@ -253,7 +253,7 @@ void MeshObject::DrawPrimitives(ref_ptr<dp::GraphicsContext> context)
static_cast<uint32_t>(buffer.m_data.size() * sizeof(buffer.m_data[0]) / buffer.m_stride);
CHECK(m_impl != nullptr, ());
- m_impl->DrawPrimitives(std::move(context), verticesCount);
+ m_impl->DrawPrimitives(context, verticesCount);
}
void MeshObject::Unbind(ref_ptr<dp::GpuProgram> program)
diff --git a/drape/metal/metal_base_context.hpp b/drape/metal/metal_base_context.hpp
index ebb7f31650..f5bd6c5642 100644
--- a/drape/metal/metal_base_context.hpp
+++ b/drape/metal/metal_base_context.hpp
@@ -5,6 +5,7 @@
#include "drape/gpu_program.hpp"
#include "drape/metal/metal_states.hpp"
#include "drape/pointers.hpp"
+#include "drape/texture_types.hpp"
#include <cstdint>
@@ -42,6 +43,8 @@ public:
id<MTLRenderCommandEncoder> GetCommandEncoder() const;
id<MTLDepthStencilState> GetDepthStencilState();
id<MTLRenderPipelineState> GetPipelineState(ref_ptr<GpuProgram> program, bool blendingEnabled);
+ id<MTLSamplerState> GetSamplerState(TextureFilter filter, TextureWrapping wrapSMode,
+ TextureWrapping wrapTMode);
protected:
void SetFrameDrawable(id<CAMetalDrawable> drawable);
diff --git a/drape/metal/metal_base_context.mm b/drape/metal/metal_base_context.mm
index 4fffba9ccd..4895084c44 100644
--- a/drape/metal/metal_base_context.mm
+++ b/drape/metal/metal_base_context.mm
@@ -237,6 +237,13 @@ id<MTLRenderPipelineState> MetalBaseContext::GetPipelineState(ref_ptr<GpuProgram
MetalStates::PipelineKey const key(program, colorTexture.pixelFormat, depthStencilFormat, blendingEnabled);
return m_metalStates.GetPipelineState(m_device, key);
}
+
+id<MTLSamplerState> MetalBaseContext::GetSamplerState(TextureFilter filter, TextureWrapping wrapSMode,
+ TextureWrapping wrapTMode)
+{
+ MetalStates::SamplerKey const key(filter, wrapSMode, wrapTMode);
+ return m_metalStates.GetSamplerState(m_device, key);
+}
void MetalBaseContext::Present()
{
diff --git a/drape/metal/metal_gpu_program.hpp b/drape/metal/metal_gpu_program.hpp
index ba2f950795..5329d316ba 100644
--- a/drape/metal/metal_gpu_program.hpp
+++ b/drape/metal/metal_gpu_program.hpp
@@ -3,7 +3,10 @@
#include "drape/gpu_program.hpp"
+#include <cstdint>
+#include <map>
#include <string>
+#include <utility>
namespace dp
{
@@ -12,11 +15,24 @@ namespace metal
class MetalGpuProgram : public GpuProgram
{
public:
- MetalGpuProgram(std::string const & programName, id<MTLFunction> vertexShader,
- id<MTLFunction> fragmentShader)
+ static int8_t constexpr kInvalidBindingIndex = -1;
+ struct TextureBindingInfo
+ {
+ int8_t m_textureBindingIndex = kInvalidBindingIndex;
+ int8_t m_samplerBindingIndex = kInvalidBindingIndex;
+ };
+ using TexturesBindingInfo = std::map<std::string, TextureBindingInfo>;
+
+ MetalGpuProgram(std::string const & programName,
+ id<MTLFunction> vertexShader, id<MTLFunction> fragmentShader,
+ int8_t vsUniformsBindingIndex, int8_t fsUniformsBindingIndex,
+ TexturesBindingInfo && textureBindingInfo)
: GpuProgram(programName)
, m_vertexShader(vertexShader)
, m_fragmentShader(fragmentShader)
+ , m_vsUniformsBindingIndex(vsUniformsBindingIndex)
+ , m_fsUniformsBindingIndex(fsUniformsBindingIndex)
+ , m_textureBindingInfo(std::move(textureBindingInfo))
{}
void Bind() override {}
@@ -24,10 +40,26 @@ public:
id<MTLFunction> GetVertexShader() const { return m_vertexShader; }
id<MTLFunction> GetFragmentShader() const { return m_fragmentShader; }
+
+ int8_t GetVertexShaderUniformsBindingIndex() const { return m_vsUniformsBindingIndex; }
+ int8_t GetFragmentShaderUniformsBindingIndex() const { return m_fsUniformsBindingIndex; }
+
+ // Now textures can be bound only in fragment shaders.
+ TextureBindingInfo const & GetTextureBindingInfo(std::string const & textureName) const
+ {
+ static TextureBindingInfo kEmptyBinding;
+ auto const it = m_textureBindingInfo.find(textureName);
+ if (it == m_textureBindingInfo.cend())
+ return kEmptyBinding;
+ return it->second;
+ }
private:
id<MTLFunction> m_vertexShader;
id<MTLFunction> m_fragmentShader;
+ int8_t const m_vsUniformsBindingIndex;
+ int8_t const m_fsUniformsBindingIndex;
+ TexturesBindingInfo const m_textureBindingInfo;
};
} // namespace metal
} // namespace dp
diff --git a/drape/metal/metal_states.hpp b/drape/metal/metal_states.hpp
index 89b16a38a4..0613572cd7 100644
--- a/drape/metal/metal_states.hpp
+++ b/drape/metal/metal_states.hpp
@@ -4,6 +4,7 @@
#include "drape/graphics_context.hpp"
#include "drape/metal/metal_gpu_program.hpp"
#include "drape/pointers.hpp"
+#include "drape/texture_types.hpp"
#include <cstdint>
#include <map>
@@ -30,10 +31,6 @@ public:
bool m_stencilEnabled = false;
TestFunction m_depthFunction = TestFunction::Always;
uint64_t m_stencil = 0;
-
- private:
- void SetStencilByte(uint8_t value, uint8_t byteNumber);
- uint8_t GetStencilByte(uint8_t byteNumber) const;
};
struct PipelineKey
@@ -51,8 +48,20 @@ public:
bool m_blendingEnabled = false;
};
+ struct SamplerKey
+ {
+ SamplerKey() = default;
+ SamplerKey(TextureFilter filter, TextureWrapping wrapSMode, TextureWrapping wrapTMode);
+ void Set(TextureFilter filter, TextureWrapping wrapSMode, TextureWrapping wrapTMode);
+ bool operator<(SamplerKey const & rhs) const;
+ MTLSamplerDescriptor * BuildDescriptor() const;
+
+ uint32_t m_sampler = 0;
+ };
+
id<MTLDepthStencilState> GetDepthStencilState(id<MTLDevice> device, DepthStencilKey const & key);
id<MTLRenderPipelineState> GetPipelineState(id<MTLDevice> device, PipelineKey const & key);
+ id<MTLSamplerState> GetSamplerState(id<MTLDevice> device, SamplerKey const & key);
private:
using DepthStencilCache = std::map<DepthStencilKey, id<MTLDepthStencilState>>;
@@ -60,6 +69,9 @@ private:
using PipelineCache = std::map<PipelineKey, id<MTLRenderPipelineState>>;
PipelineCache m_pipelineCache;
+
+ using SamplerCache = std::map<SamplerKey, id<MTLSamplerState>>;
+ SamplerCache m_samplerCache;
};
} // namespace metal
} // namespace dp
diff --git a/drape/metal/metal_states.mm b/drape/metal/metal_states.mm
index 8410647bba..37bc5ab702 100644
--- a/drape/metal/metal_states.mm
+++ b/drape/metal/metal_states.mm
@@ -13,8 +13,7 @@ namespace metal
{
namespace
{
-// Bytes 7-4: [back function][back stencil fail action][back depth fail action][back pass action]
-// Bytes 3-0: [front function][front stencil fail action][front depth fail action][front pass action]
+// Stencil package.
uint8_t constexpr kStencilBackFunctionByte = 7;
uint8_t constexpr kStencilBackFailActionByte = 6;
uint8_t constexpr kStencilBackDepthFailActionByte = 5;
@@ -23,6 +22,26 @@ uint8_t constexpr kStencilFrontFunctionByte = 3;
uint8_t constexpr kStencilFrontFailActionByte = 2;
uint8_t constexpr kStencilFrontDepthFailActionByte = 1;
uint8_t constexpr kStencilFrontPassActionByte = 0;
+
+// Stencil package.
+uint8_t constexpr kWrapSModeByte = 3;
+uint8_t constexpr kWrapTModeByte = 2;
+uint8_t constexpr kMagFilterByte = 1;
+uint8_t constexpr kMinFilterByte = 0;
+
+template<typename T>
+void SetStateByte(T & state, uint8_t value, uint8_t byteNumber)
+{
+ auto const shift = byteNumber * 8;
+ auto const mask = ~(static_cast<T>(0xFF) << shift);
+ state = (state & mask) | (static_cast<T>(value) << shift);
+}
+
+template<typename T>
+uint8_t GetStateByte(T & state, uint8_t byteNumber)
+{
+ return static_cast<uint8_t>((state >> byteNumber * 8) & 0xFF);
+}
MTLCompareFunction DecodeTestFunction(uint8_t testFunctionByte)
{
@@ -56,6 +75,26 @@ MTLStencilOperation DecodeStencilAction(uint8_t stencilActionByte)
ASSERT(false, ());
}
+MTLSamplerMinMagFilter DecodeTextureFilter(uint8_t textureFilterByte)
+{
+ switch (static_cast<TextureFilter>(textureFilterByte))
+ {
+ case TextureFilter::Nearest: return MTLSamplerMinMagFilterNearest;
+ case TextureFilter::Linear: return MTLSamplerMinMagFilterLinear;
+ }
+ ASSERT(false, ());
+}
+
+MTLSamplerAddressMode DecodeTextureWrapping(uint8_t textureWrappingByte)
+{
+ switch (static_cast<TextureWrapping>(textureWrappingByte))
+ {
+ case TextureWrapping::ClampToEdge: return MTLSamplerAddressModeClampToEdge;
+ case TextureWrapping::Repeat: return MTLSamplerAddressModeRepeat;
+ }
+ ASSERT(false, ());
+}
+
bool IsStencilFormat(MTLPixelFormat format)
{
return format == MTLPixelFormatDepth32Float_Stencil8 ||
@@ -82,7 +121,7 @@ id<MTLRenderPipelineState> MetalStates::GetPipelineState(id<MTLDevice> device, P
if (it != m_pipelineCache.end())
return it->second;
- NSError * error = NULL;
+ NSError * error = nil;
id<MTLRenderPipelineState> pipelineState = [device newRenderPipelineStateWithDescriptor:key.BuildDescriptor()
error:&error];
if (pipelineState == nil || error != nil)
@@ -94,6 +133,18 @@ id<MTLRenderPipelineState> MetalStates::GetPipelineState(id<MTLDevice> device, P
return pipelineState;
}
+id<MTLSamplerState> MetalStates::GetSamplerState(id<MTLDevice> device, SamplerKey const & key)
+{
+ auto const it = m_samplerCache.find(key);
+ if (it != m_samplerCache.end())
+ return it->second;
+
+ id<MTLSamplerState> samplerState = [device newSamplerStateWithDescriptor:key.BuildDescriptor()];
+ CHECK(samplerState != nil, ());
+ m_samplerCache.insert(std::make_pair(key, samplerState));
+ return samplerState;
+}
+
void MetalStates::DepthStencilKey::SetDepthTestEnabled(bool enabled)
{
m_depthEnabled = enabled;
@@ -108,32 +159,20 @@ void MetalStates::DepthStencilKey::SetStencilTestEnabled(bool enabled)
{
m_stencilEnabled = enabled;
}
-
-void MetalStates::DepthStencilKey::SetStencilByte(uint8_t value, uint8_t byteNumber)
-{
- auto const shift = byteNumber * 8;
- uint64_t const mask = ~(static_cast<uint64_t>(0xFF) << shift);
- m_stencil = (m_stencil & mask) | (static_cast<uint64_t>(value) << shift);
-}
-
-uint8_t MetalStates::DepthStencilKey::GetStencilByte(uint8_t byteNumber) const
-{
- return static_cast<uint8_t>((m_stencil >> byteNumber * 8) & 0xFF);
-}
void MetalStates::DepthStencilKey::SetStencilFunction(StencilFace face, TestFunction stencilFunction)
{
switch (face)
{
case StencilFace::Front:
- SetStencilByte(static_cast<uint8_t>(stencilFunction), kStencilFrontFunctionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(stencilFunction), kStencilFrontFunctionByte);
break;
case StencilFace::Back:
- SetStencilByte(static_cast<uint8_t>(stencilFunction), kStencilBackFunctionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(stencilFunction), kStencilBackFunctionByte);
break;
case StencilFace::FrontAndBack:
- SetStencilByte(static_cast<uint8_t>(stencilFunction), kStencilFrontFunctionByte);
- SetStencilByte(static_cast<uint8_t>(stencilFunction), kStencilBackFunctionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(stencilFunction), kStencilFrontFunctionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(stencilFunction), kStencilBackFunctionByte);
break;
}
}
@@ -144,22 +183,22 @@ void MetalStates::DepthStencilKey::SetStencilActions(StencilFace face, StencilAc
switch (face)
{
case StencilFace::Front:
- SetStencilByte(static_cast<uint8_t>(stencilFailAction), kStencilFrontFailActionByte);
- SetStencilByte(static_cast<uint8_t>(depthFailAction), kStencilFrontDepthFailActionByte);
- SetStencilByte(static_cast<uint8_t>(passAction), kStencilFrontPassActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(stencilFailAction), kStencilFrontFailActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(depthFailAction), kStencilFrontDepthFailActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(passAction), kStencilFrontPassActionByte);
break;
case StencilFace::Back:
- SetStencilByte(static_cast<uint8_t>(stencilFailAction), kStencilBackFailActionByte);
- SetStencilByte(static_cast<uint8_t>(depthFailAction), kStencilBackDepthFailActionByte);
- SetStencilByte(static_cast<uint8_t>(passAction), kStencilBackPassActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(stencilFailAction), kStencilBackFailActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(depthFailAction), kStencilBackDepthFailActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(passAction), kStencilBackPassActionByte);
break;
case StencilFace::FrontAndBack:
- SetStencilByte(static_cast<uint8_t>(stencilFailAction), kStencilFrontFailActionByte);
- SetStencilByte(static_cast<uint8_t>(depthFailAction), kStencilFrontDepthFailActionByte);
- SetStencilByte(static_cast<uint8_t>(passAction), kStencilFrontPassActionByte);
- SetStencilByte(static_cast<uint8_t>(stencilFailAction), kStencilBackFailActionByte);
- SetStencilByte(static_cast<uint8_t>(depthFailAction), kStencilBackDepthFailActionByte);
- SetStencilByte(static_cast<uint8_t>(passAction), kStencilBackPassActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(stencilFailAction), kStencilFrontFailActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(depthFailAction), kStencilFrontDepthFailActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(passAction), kStencilFrontPassActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(stencilFailAction), kStencilBackFailActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(depthFailAction), kStencilBackDepthFailActionByte);
+ SetStateByte(m_stencil, static_cast<uint8_t>(passAction), kStencilBackPassActionByte);
break;
}
}
@@ -194,17 +233,17 @@ MTLDepthStencilDescriptor * MetalStates::DepthStencilKey::BuildDescriptor() cons
if (m_stencilEnabled)
{
MTLStencilDescriptor * frontDesc = [[MTLStencilDescriptor alloc] init];
- frontDesc.stencilCompareFunction = DecodeTestFunction(GetStencilByte(kStencilFrontFunctionByte));
- frontDesc.stencilFailureOperation = DecodeStencilAction(GetStencilByte(kStencilFrontFailActionByte));
- frontDesc.depthFailureOperation = DecodeStencilAction(GetStencilByte(kStencilFrontDepthFailActionByte));
- frontDesc.depthStencilPassOperation = DecodeStencilAction(GetStencilByte(kStencilFrontPassActionByte));
+ frontDesc.stencilCompareFunction = DecodeTestFunction(GetStateByte(m_stencil, kStencilFrontFunctionByte));
+ frontDesc.stencilFailureOperation = DecodeStencilAction(GetStateByte(m_stencil, kStencilFrontFailActionByte));
+ frontDesc.depthFailureOperation = DecodeStencilAction(GetStateByte(m_stencil, kStencilFrontDepthFailActionByte));
+ frontDesc.depthStencilPassOperation = DecodeStencilAction(GetStateByte(m_stencil, kStencilFrontPassActionByte));
desc.frontFaceStencil = frontDesc;
MTLStencilDescriptor * backDesc = [[MTLStencilDescriptor alloc] init];
- backDesc.stencilCompareFunction = DecodeTestFunction(GetStencilByte(kStencilBackFunctionByte));
- backDesc.stencilFailureOperation = DecodeStencilAction(GetStencilByte(kStencilBackFailActionByte));
- backDesc.depthFailureOperation = DecodeStencilAction(GetStencilByte(kStencilBackDepthFailActionByte));
- backDesc.depthStencilPassOperation = DecodeStencilAction(GetStencilByte(kStencilBackPassActionByte));
+ backDesc.stencilCompareFunction = DecodeTestFunction(GetStateByte(m_stencil, kStencilBackFunctionByte));
+ backDesc.stencilFailureOperation = DecodeStencilAction(GetStateByte(m_stencil, kStencilBackFailActionByte));
+ backDesc.depthFailureOperation = DecodeStencilAction(GetStateByte(m_stencil, kStencilBackDepthFailActionByte));
+ backDesc.depthStencilPassOperation = DecodeStencilAction(GetStateByte(m_stencil, kStencilBackPassActionByte));
desc.backFaceStencil = backDesc;
}
else
@@ -260,5 +299,33 @@ MTLRenderPipelineDescriptor * MetalStates::PipelineKey::BuildDescriptor() const
colorAttachment.destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
return desc;
}
+
+MetalStates::SamplerKey::SamplerKey(TextureFilter filter, TextureWrapping wrapSMode, TextureWrapping wrapTMode)
+{
+ Set(filter, wrapSMode, wrapTMode);
+}
+
+void MetalStates::SamplerKey::Set(TextureFilter filter, TextureWrapping wrapSMode, TextureWrapping wrapTMode)
+{
+ SetStateByte(m_sampler, static_cast<uint8_t>(filter), kMinFilterByte);
+ SetStateByte(m_sampler, static_cast<uint8_t>(filter), kMagFilterByte);
+ SetStateByte(m_sampler, static_cast<uint8_t>(wrapSMode), kWrapSModeByte);
+ SetStateByte(m_sampler, static_cast<uint8_t>(wrapTMode), kWrapTModeByte);
+}
+
+bool MetalStates::SamplerKey::operator<(SamplerKey const & rhs) const
+{
+ return m_sampler < rhs.m_sampler;
+}
+
+MTLSamplerDescriptor * MetalStates::SamplerKey::BuildDescriptor() const
+{
+ MTLSamplerDescriptor * desc = [[MTLSamplerDescriptor alloc] init];
+ desc.minFilter = DecodeTextureFilter(GetStateByte(m_sampler, kMinFilterByte));
+ desc.magFilter = DecodeTextureFilter(GetStateByte(m_sampler, kMagFilterByte));
+ desc.sAddressMode = DecodeTextureWrapping(GetStateByte(m_sampler, kWrapSModeByte));
+ desc.tAddressMode = DecodeTextureWrapping(GetStateByte(m_sampler, kWrapTModeByte));
+ return desc;
+}
} // namespace metal
} // namespace dp
diff --git a/drape/metal/metal_texture.mm b/drape/metal/metal_texture.mm
index 96a4d04872..7f63646af6 100644
--- a/drape/metal/metal_texture.mm
+++ b/drape/metal/metal_texture.mm
@@ -86,7 +86,7 @@ void MetalTexture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t h
void MetalTexture::SetFilter(TextureFilter filter)
{
- //TODO(@rokuz,@darina)
+ m_params.m_filter = filter;
}
bool MetalTexture::Validate() const
diff --git a/drape/metal/render_state_metal.mm b/drape/metal/render_state_metal.mm
index ea2c058f89..1498a09591 100644
--- a/drape/metal/render_state_metal.mm
+++ b/drape/metal/render_state_metal.mm
@@ -3,6 +3,7 @@
#include "drape/metal/metal_base_context.hpp"
#include "drape/metal/metal_gpu_program.hpp"
#include "drape/pointers.hpp"
+#include "drape/render_state.hpp"
#include "base/assert.hpp"
@@ -24,4 +25,11 @@ void ApplyPipelineStateForMetal(ref_ptr<GraphicsContext> context, ref_ptr<GpuPro
id<MTLRenderPipelineState> state = metalContext->GetPipelineState(std::move(program), blendingEnabled);
[metalContext->GetCommandEncoder() setRenderPipelineState:state];
}
+
+void ApplyTexturesForMetal(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program,
+ RenderState const & state)
+{
+ ref_ptr<dp::metal::MetalBaseContext> metalContext = context;
+ //TODO(@rokuz,@darina)
+}
} // namespace dp
diff --git a/drape/render_state.cpp b/drape/render_state.cpp
index 0da8a47e3c..a9b409080c 100644
--- a/drape/render_state.cpp
+++ b/drape/render_state.cpp
@@ -16,6 +16,8 @@ std::string const kMaskTextureName = "u_maskTex";
extern void ApplyDepthStencilStateForMetal(ref_ptr<GraphicsContext> context);
extern void ApplyPipelineStateForMetal(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program,
bool blendingEnabled);
+extern void ApplyTexturesForMetal(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program,
+ RenderState const & state);
#endif
// static
@@ -213,7 +215,16 @@ void TextureState::ApplyTextures(ref_ptr<GraphicsContext> context, RenderState c
}
}
}
- //TODO(@rokuz,@darina): Metal?
+ else if (apiVersion == dp::ApiVersion::Metal)
+ {
+#if defined(OMIM_OS_IPHONE)
+ ApplyTexturesForMetal(context, program, state);
+#endif
+ }
+ else
+ {
+ CHECK(false, ("Unsupported API version."));
+ }
}
uint8_t TextureState::GetLastUsedSlots()
diff --git a/drape/static_texture.cpp b/drape/static_texture.cpp
index 4318ab2df2..28735d75b9 100644
--- a/drape/static_texture.cpp
+++ b/drape/static_texture.cpp
@@ -98,7 +98,7 @@ StaticTexture::StaticTexture(ref_ptr<dp::GraphicsContext> context,
, m_format(format)
, m_info(make_unique_dp<StaticResourceInfo>())
{
- m_isLoadingCorrect = Load(std::move(context), allocator);
+ m_isLoadingCorrect = Load(context, allocator);
}
bool StaticTexture::Load(ref_ptr<dp::GraphicsContext> context, ref_ptr<HWTextureAllocator> allocator)
@@ -114,13 +114,13 @@ bool StaticTexture::Load(ref_ptr<dp::GraphicsContext> context, ref_ptr<HWTexture
p.m_wrapSMode = TextureWrapping::Repeat;
p.m_wrapTMode = TextureWrapping::Repeat;
- Create(std::move(context), p, make_ref(data));
+ Create(context, p, make_ref(data));
};
auto failureHandler = [this, context](std::string const & reason)
{
LOG(LERROR, (reason));
- Fail(std::move(context));
+ Fail(context);
};
uint8_t const bytesPerPixel = GetBytesPerPixel(m_format);
@@ -132,7 +132,7 @@ void StaticTexture::Invalidate(ref_ptr<dp::GraphicsContext> context,
ref_ptr<HWTextureAllocator> allocator)
{
Destroy();
- m_isLoadingCorrect = Load(std::move(context), std::move(allocator));
+ m_isLoadingCorrect = Load(context, allocator);
}
ref_ptr<Texture::ResourceInfo> StaticTexture::FindResource(Texture::Key const & key,
@@ -148,7 +148,7 @@ void StaticTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const &
{
ASSERT(Base::IsPowerOfTwo(params.m_width, params.m_height), (params.m_width, params.m_height));
- Base::Create(std::move(context), params);
+ Base::Create(context, params);
}
void StaticTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params,
@@ -156,7 +156,7 @@ void StaticTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const &
{
ASSERT(Base::IsPowerOfTwo(params.m_width, params.m_height), (params.m_width, params.m_height));
- Base::Create(std::move(context), params, data);
+ Base::Create(context, params, data);
}
void StaticTexture::Fail(ref_ptr<dp::GraphicsContext> context)
diff --git a/drape/stipple_pen_resource.hpp b/drape/stipple_pen_resource.hpp
index 18f9f294c1..31ef3c846f 100644
--- a/drape/stipple_pen_resource.hpp
+++ b/drape/stipple_pen_resource.hpp
@@ -129,7 +129,7 @@ public:
{
TBase::DynamicTextureParams params{size, TextureFormat::Alpha, TextureFilter::Nearest,
false /* m_usePixelBuffer */};
- TBase::Init(std::move(allocator), make_ref(&m_index), params);
+ TBase::Init(allocator, make_ref(&m_index), params);
}
~StipplePenTexture() override { TBase::Reset(); }
diff --git a/drape/symbols_texture.cpp b/drape/symbols_texture.cpp
index bb0adc6f22..ce9bc4ea77 100644
--- a/drape/symbols_texture.cpp
+++ b/drape/symbols_texture.cpp
@@ -203,7 +203,7 @@ SymbolsTexture::SymbolsTexture(ref_ptr<dp::GraphicsContext> context, std::string
std::string const & textureName, ref_ptr<HWTextureAllocator> allocator)
: m_name(textureName)
{
- Load(std::move(context), skinPathName, std::move(allocator));
+ Load(context, skinPathName, allocator);
}
void SymbolsTexture::Load(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName,
@@ -222,13 +222,13 @@ void SymbolsTexture::Load(ref_ptr<dp::GraphicsContext> context, std::string cons
p.m_width = width;
p.m_height = height;
- Create(std::move(context), p, make_ref(data));
+ Create(context, p, make_ref(data));
};
auto failureHandler = [this, context](std::string const & reason)
{
LOG(LERROR, (reason));
- Fail(std::move(context));
+ Fail(context);
};
LoadSymbols(skinPathName, m_name, true /* convertToUV */, definitionInserter,
@@ -241,7 +241,7 @@ void SymbolsTexture::Invalidate(ref_ptr<dp::GraphicsContext> context, std::strin
Destroy();
m_definition.clear();
- Load(std::move(context), skinPathName, std::move(allocator));
+ Load(context, skinPathName, allocator);
}
ref_ptr<Texture::ResourceInfo> SymbolsTexture::FindResource(Texture::Key const & key, bool & newResource)
diff --git a/drape/texture.cpp b/drape/texture.cpp
index 514de5d9ad..948b55f1ac 100644
--- a/drape/texture.cpp
+++ b/drape/texture.cpp
@@ -104,7 +104,7 @@ bool Texture::AllocateTexture(ref_ptr<dp::GraphicsContext> context,
{
if (allocator != nullptr)
{
- m_hwTexture = allocator->CreateTexture(std::move(context));
+ m_hwTexture = allocator->CreateTexture(context);
return true;
}
return false;
diff --git a/drape/vertex_array_buffer.cpp b/drape/vertex_array_buffer.cpp
index a1c26b0818..1ddf72a5c8 100644
--- a/drape/vertex_array_buffer.cpp
+++ b/drape/vertex_array_buffer.cpp
@@ -122,7 +122,7 @@ void VertexArrayBuffer::Build(ref_ptr<GpuProgram> program)
m_program = program;
// If OES_vertex_array_object not supported, than buffers will be bound on each render call.
- if (!GLExtensionsList::Instance().IsSupported(GLExtensionsList::VertexArrayObject))
+ if (!GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
return;
if (m_staticBuffers.empty())
@@ -301,7 +301,7 @@ void VertexArrayBuffer::ApplyMutation(ref_ptr<IndexBufferMutator> indexMutator,
bool VertexArrayBuffer::Bind() const
{
- if (GLExtensionsList::Instance().IsSupported(GLExtensionsList::VertexArrayObject))
+ if (GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
{
ASSERT(m_VAO != 0, ("You need to call Build method before bind it and render"));
GLFunctions::glBindVertexArray(m_VAO);
@@ -312,7 +312,7 @@ bool VertexArrayBuffer::Bind() const
void VertexArrayBuffer::Unbind() const
{
- if (GLExtensionsList::Instance().IsSupported(GLExtensionsList::VertexArrayObject))
+ if (GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
GLFunctions::glBindVertexArray(0);
}
diff --git a/drape_frontend/arrow3d.cpp b/drape_frontend/arrow3d.cpp
index 12fde6461e..82e3c9d9e0 100644
--- a/drape_frontend/arrow3d.cpp
+++ b/drape_frontend/arrow3d.cpp
@@ -126,7 +126,6 @@ void Arrow3d::RenderArrow(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::Pro
params.m_color = glsl::ToVec4(color);
auto gpuProgram = mng->GetProgram(program);
-
mesh.Render(context, gpuProgram, m_state, mng->GetParamsSetter(), params);
}
diff --git a/drape_frontend/debug_rect_renderer.cpp b/drape_frontend/debug_rect_renderer.cpp
index a269cd358a..2eb9bd1420 100644
--- a/drape_frontend/debug_rect_renderer.cpp
+++ b/drape_frontend/debug_rect_renderer.cpp
@@ -19,9 +19,9 @@ void PixelPointToScreenSpace(ScreenBase const & screen, m2::PointF const & pt, s
DebugRectRenderer::DebugRectRenderer(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program,
ref_ptr<gpu::ProgramParamsSetter> paramsSetter)
- : Base(std::move(context), DrawPrimitive::LineStrip)
- , m_program(std::move(program))
- , m_paramsSetter(std::move(paramsSetter))
+ : Base(context, DrawPrimitive::LineStrip)
+ , m_program(program)
+ , m_paramsSetter(paramsSetter)
, m_state(CreateRenderState(gpu::Program::DebugRect, DepthLayer::OverlayLayer))
{
m_state.SetDepthTestEnabled(false);
@@ -53,7 +53,7 @@ void DebugRectRenderer::SetArrow(ref_ptr<dp::GraphicsContext> context, m2::Point
PixelPointToScreenSpace(screen, arrowEnd - dir * 20 - side * 10, vertices);
if (!Base::IsInitialized())
- Base::Build(std::move(context), m_program);
+ Base::Build(context, m_program);
Base::UpdateBuffer(0 /* bufferInd */, std::move(vertices));
}
@@ -68,7 +68,7 @@ void DebugRectRenderer::SetRect(ref_ptr<dp::GraphicsContext> context, m2::RectF
PixelPointToScreenSpace(screen, rect.LeftBottom(), vertices);
if (!Base::IsInitialized())
- Base::Build(std::move(context), m_program);
+ Base::Build(context, m_program);
Base::UpdateBuffer(0 /* bufferInd */, std::move(vertices));
}
diff --git a/drape_frontend/postprocess_renderer.cpp b/drape_frontend/postprocess_renderer.cpp
index c7722cf474..19998b17aa 100644
--- a/drape_frontend/postprocess_renderer.cpp
+++ b/drape_frontend/postprocess_renderer.cpp
@@ -121,7 +121,7 @@ void InitFramebuffer(ref_ptr<dp::GraphicsContext> context,
framebuffer = make_unique_dp<dp::Framebuffer>(dp::TextureFormat::RGBA8, depthEnabled,
stencilEnabled);
}
- framebuffer->SetSize(std::move(context), width, height);
+ framebuffer->SetSize(context, width, height);
}
void InitFramebuffer(ref_ptr<dp::GraphicsContext> context,
@@ -133,7 +133,7 @@ void InitFramebuffer(ref_ptr<dp::GraphicsContext> context,
if (framebuffer == nullptr)
framebuffer = make_unique_dp<dp::Framebuffer>(colorFormat);
framebuffer->SetDepthStencilRef(std::move(depthStencilRef));
- framebuffer->SetSize(std::move(context), width, height);
+ framebuffer->SetSize(context, width, height);
}
bool IsSupported(drape_ptr<dp::Framebuffer> const & framebuffer)
@@ -174,7 +174,7 @@ void PostprocessRenderer::Resize(ref_ptr<dp::GraphicsContext> context, uint32_t
m_width = width;
m_height = height;
- UpdateFramebuffers(std::move(context), m_width, m_height);
+ UpdateFramebuffers(context, m_width, m_height);
}
void PostprocessRenderer::SetStaticTextures(drape_ptr<PostprocessStaticTextures> && textures)
@@ -426,7 +426,7 @@ void PostprocessRenderer::OnChangedRouteFollowingMode(ref_ptr<dp::GraphicsContex
m_isRouteFollowingActive = isRouteFollowingActive;
if (m_width != 0 && m_height != 0)
- UpdateFramebuffers(std::move(context), m_width, m_height);
+ UpdateFramebuffers(context, m_width, m_height);
}
StencilWriterGuard::StencilWriterGuard(ref_ptr<PostprocessRenderer> renderer,
diff --git a/drape_frontend/screen_quad_renderer.cpp b/drape_frontend/screen_quad_renderer.cpp
index f071e5e592..e41f7edd04 100644
--- a/drape_frontend/screen_quad_renderer.cpp
+++ b/drape_frontend/screen_quad_renderer.cpp
@@ -39,7 +39,7 @@ private:
} // namespace
ScreenQuadRenderer::ScreenQuadRenderer(ref_ptr<dp::GraphicsContext> context)
- : Base(std::move(context), DrawPrimitive::TriangleStrip)
+ : Base(context, DrawPrimitive::TriangleStrip)
{
Rebuild();
}
@@ -64,7 +64,7 @@ void ScreenQuadRenderer::RenderTexture(ref_ptr<dp::GraphicsContext> context,
params.SetParams(mng, std::move(texture), opacity);
auto program = mng->GetProgram(params.GetRenderState().GetProgram<gpu::Program>());
- Base::Render(std::move(context), program, params.GetRenderState(), mng->GetParamsSetter(),
+ Base::Render(context, program, params.GetRenderState(), mng->GetParamsSetter(),
params.GetProgramParams());
}
diff --git a/shaders/Metal/debug_rect.metal b/shaders/Metal/debug_rect.metal
index b795740622..d6e3a1eb99 100644
--- a/shaders/Metal/debug_rect.metal
+++ b/shaders/Metal/debug_rect.metal
@@ -4,7 +4,7 @@ using namespace metal;
typedef struct
{
- float2 a_position [[attribute(0)]];
+ packed_float2 a_position;
} Vertex_T;
typedef struct
@@ -17,10 +17,11 @@ typedef struct
float4 u_color;
} Uniforms_T;
-vertex Fragment_T vsDebugRect(const Vertex_T in [[stage_in]])
+vertex Fragment_T vsDebugRect(device const Vertex_T * vertices [[buffer(0)]],
+ uint vid [[vertex_id]])
{
Fragment_T out;
- out.position = float4(in.a_position, 0.0, 1.0);
+ out.position = float4(vertices[vid].a_position, 0.0, 1.0);
return out;
}
diff --git a/shaders/Metal/screen_quad.metal b/shaders/Metal/screen_quad.metal
index c864387d6b..55c4475fa9 100644
--- a/shaders/Metal/screen_quad.metal
+++ b/shaders/Metal/screen_quad.metal
@@ -4,8 +4,8 @@ using namespace metal;
typedef struct
{
- float2 a_position [[attribute(0)]];
- float2 a_texCoords [[attribute(1)]];
+ packed_float2 a_position;
+ packed_float2 a_texCoords;
} Vertex_T;
typedef struct
@@ -19,8 +19,10 @@ typedef struct
float u_opacity;
} Uniforms_T;
-vertex Fragment_T vsScreenQuad(const Vertex_T in [[stage_in]])
+vertex Fragment_T vsScreenQuad(device const Vertex_T * vertices [[buffer(0)]],
+ uint vid [[vertex_id]])
{
+ Vertex_T const in = vertices[vid];
Fragment_T out;
out.position = float4(in.a_position, 0.0, 1.0);
out.texCoords = in.a_texCoords;
diff --git a/shaders/metal_program_pool.hpp b/shaders/metal_program_pool.hpp
index 1c8ed6130d..3c3dfcd899 100644
--- a/shaders/metal_program_pool.hpp
+++ b/shaders/metal_program_pool.hpp
@@ -22,6 +22,7 @@ public:
private:
id<MTLFunction> GetFunction(std::string const & name);
+ id<MTLDevice> m_device;
id<MTLLibrary> m_library;
std::map<std::string, id<MTLFunction>> m_functions;
};
diff --git a/shaders/metal_program_pool.mm b/shaders/metal_program_pool.mm
index bb1011e5a1..23f3cd712d 100644
--- a/shaders/metal_program_pool.mm
+++ b/shaders/metal_program_pool.mm
@@ -17,7 +17,7 @@ struct ProgramInfo
{
std::string m_vertexShaderName;
std::string m_fragmentShaderName;
- ProgramInfo(std::string && vertexShaderName, std::string fragmentShaderName)
+ ProgramInfo(std::string && vertexShaderName, std::string && fragmentShaderName)
: m_vertexShaderName(std::move(vertexShaderName))
, m_fragmentShaderName(std::move(fragmentShaderName))
{}
@@ -77,12 +77,13 @@ std::array<ProgramInfo, static_cast<size_t>(Program::ProgramsCount)> const kMeta
} // namespace
MetalProgramPool::MetalProgramPool(id<MTLDevice> device)
+ : m_device(device)
{
ProgramParams::Init();
NSString * libPath = [[NSBundle mainBundle] pathForResource:@"shaders_metal" ofType:@"metallib"];
- NSError * error;
- m_library = [device newLibraryWithFile:libPath error:&error];
+ NSError * error = nil;
+ m_library = [m_device newLibraryWithFile:libPath error:&error];
if (error)
{
NSLog(@"%@", error);
@@ -102,9 +103,69 @@ drape_ptr<dp::GpuProgram> MetalProgramPool::Get(Program program)
CHECK(!info.m_vertexShaderName.empty(), ());
CHECK(!info.m_fragmentShaderName.empty(), ());
+ id<MTLFunction> vertexShader = GetFunction(info.m_vertexShaderName);
+ id<MTLFunction> fragmentShader = GetFunction(info.m_fragmentShaderName);
+
+ MTLRenderPipelineDescriptor * desc = [[MTLRenderPipelineDescriptor alloc] init];
+ desc.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm;
+ desc.vertexFunction = vertexShader;
+ desc.fragmentFunction = fragmentShader;
+ NSError * error = nil;
+ MTLRenderPipelineReflection * reflectionObj = nil;
+ MTLPipelineOption option = MTLPipelineOptionBufferTypeInfo | MTLPipelineOptionArgumentInfo;
+ id <MTLRenderPipelineState> pso = [m_device newRenderPipelineStateWithDescriptor:desc
+ options:option
+ reflection:&reflectionObj
+ error:&error];
+ if (error != nil || pso == nil)
+ {
+ NSLog(@"%@", error);
+ CHECK(false, ("Failed to create reflection pipeline state."));
+ }
+
+ // Uniforms buffer must have the name "uniforms".
+ NSString * kUniformsName = @"uniforms";
+
+ int8_t vsUniformsBindingIndex = dp::metal::MetalGpuProgram::kInvalidBindingIndex;
+ for (MTLArgument * arg in reflectionObj.vertexArguments)
+ {
+ if ([arg.name compare:kUniformsName] == NSOrderedSame && arg.active && arg.type == MTLArgumentTypeBuffer)
+ {
+ vsUniformsBindingIndex = static_cast<int8_t>(arg.index);
+ break;
+ }
+ }
+
+ int8_t fsUniformsBindingIndex = dp::metal::MetalGpuProgram::kInvalidBindingIndex;
+ dp::metal::MetalGpuProgram::TexturesBindingInfo textureBindingInfo;
+ for (MTLArgument * arg in reflectionObj.fragmentArguments)
+ {
+ if ([arg.name compare:kUniformsName] == NSOrderedSame && arg.active && arg.type == MTLArgumentTypeBuffer)
+ {
+ fsUniformsBindingIndex = static_cast<int8_t>(arg.index);
+ }
+ else if (arg.type == MTLArgumentTypeTexture)
+ {
+ std::string const name([arg.name UTF8String]);
+ textureBindingInfo[name].m_textureBindingIndex = static_cast<int8_t>(arg.index);
+ }
+ else if (arg.type == MTLArgumentTypeSampler)
+ {
+ std::string const name([arg.name UTF8String]);
+ // Sampler name must be constructed as concatenation of texture name and kSamplerSuffix.
+ static std::string const kSamplerSuffix = "Sampler";
+ auto const pos = name.find(kSamplerSuffix);
+ if (pos == std::string::npos)
+ continue;
+ std::string const textureName = name.substr(0, pos);
+ textureBindingInfo[textureName].m_samplerBindingIndex = static_cast<int8_t>(arg.index);
+ }
+ }
+
auto const name = DebugPrint(program);
- return make_unique_dp<dp::metal::MetalGpuProgram>(name, GetFunction(info.m_vertexShaderName),
- GetFunction(info.m_fragmentShaderName));
+ return make_unique_dp<dp::metal::MetalGpuProgram>(name, vertexShader, fragmentShader,
+ vsUniformsBindingIndex, fsUniformsBindingIndex,
+ std::move(textureBindingInfo));
}
id<MTLFunction> MetalProgramPool::GetFunction(std::string const & name)