diff options
138 files changed, 3080 insertions, 1236 deletions
diff --git a/android/jni/com/mapswithme/opengl/android_gl_utils.hpp b/android/jni/com/mapswithme/opengl/android_gl_utils.hpp index 1e06facd18..d8c08f9721 100644 --- a/android/jni/com/mapswithme/opengl/android_gl_utils.hpp +++ b/android/jni/com/mapswithme/opengl/android_gl_utils.hpp @@ -1,15 +1,14 @@ #pragma once -#include "drape/glIncludes.hpp" +#include "drape/gl_includes.hpp" namespace base { class SrcPoint; -} +} // namespace base namespace android { - class ConfigComparator { public: @@ -24,7 +23,6 @@ private: }; void CheckEGL(base::SrcPoint const & src); - } // namespace android #define CHECK_EGL(x) do { (x); android::CheckEGL(SRC());} while(false); diff --git a/android/jni/com/mapswithme/opengl/androidoglcontext.cpp b/android/jni/com/mapswithme/opengl/androidoglcontext.cpp index 46ad1af2d5..0c73761217 100644 --- a/android/jni/com/mapswithme/opengl/androidoglcontext.cpp +++ b/android/jni/com/mapswithme/opengl/androidoglcontext.cpp @@ -43,9 +43,12 @@ AndroidOGLContext::~AndroidOGLContext() CHECK_EGL_CALL(); } -void AndroidOGLContext::SetDefaultFramebuffer() +void AndroidOGLContext::SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) { - glBindFramebuffer(GL_FRAMEBUFFER, 0); + if (framebuffer) + framebuffer->Bind(); + else + glBindFramebuffer(GL_FRAMEBUFFER, 0); } void AndroidOGLContext::MakeCurrent() diff --git a/android/jni/com/mapswithme/opengl/androidoglcontext.hpp b/android/jni/com/mapswithme/opengl/androidoglcontext.hpp index 358c559a46..385d801548 100644 --- a/android/jni/com/mapswithme/opengl/androidoglcontext.hpp +++ b/android/jni/com/mapswithme/opengl/androidoglcontext.hpp @@ -1,6 +1,6 @@ #pragma once -#include "drape/glIncludes.hpp" +#include "drape/gl_includes.hpp" #include "drape/oglcontext.hpp" #include <atomic> @@ -17,7 +17,7 @@ public: void MakeCurrent() override; void DoneCurrent() override; void Present() override; - void SetDefaultFramebuffer() override; + void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override; void SetRenderingEnabled(bool enabled) override; void SetPresentAvailable(bool available) override; bool Validate() override; diff --git a/drape/CMakeLists.txt b/drape/CMakeLists.txt index 4ecf970658..aa5652e00d 100644 --- a/drape/CMakeLists.txt +++ b/drape/CMakeLists.txt @@ -44,12 +44,14 @@ set( ${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 - ${DRAPE_ROOT}/glextensions_list.hpp - ${DRAPE_ROOT}/glfunctions.hpp - ${DRAPE_ROOT}/glIncludes.hpp + ${DRAPE_ROOT}/gl_constants.cpp + ${DRAPE_ROOT}/gl_constants.hpp + ${DRAPE_ROOT}/gl_gpu_program.cpp + ${DRAPE_ROOT}/gl_gpu_program.hpp + ${DRAPE_ROOT}/gl_extensions_list.cpp + ${DRAPE_ROOT}/gl_extensions_list.hpp + ${DRAPE_ROOT}/gl_functions.hpp + ${DRAPE_ROOT}/gl_includes.hpp ${DRAPE_ROOT}/glsl_func.hpp ${DRAPE_ROOT}/glsl_types.hpp ${DRAPE_ROOT}/glyph_generator.cpp @@ -58,7 +60,6 @@ set( ${DRAPE_ROOT}/glyph_manager.hpp ${DRAPE_ROOT}/gpu_buffer.cpp ${DRAPE_ROOT}/gpu_buffer.hpp - ${DRAPE_ROOT}/gpu_program.cpp ${DRAPE_ROOT}/gpu_program.hpp ${DRAPE_ROOT}/graphics_context.hpp ${DRAPE_ROOT}/graphics_context_factory.cpp @@ -122,15 +123,24 @@ set( set( SRC - glfunctions.cpp + gl_functions.cpp ) if (PLATFORM_IPHONE) - append( - SRC - hw_texture_ios.hpp - hw_texture_ios.mm - ) +append( + SRC + hw_texture_ios.hpp + hw_texture_ios.mm + metal/metal_base_context.hpp + metal/metal_base_context.mm + metal/metal_gpu_program.hpp + metal/metal_mesh_object_impl.mm + metal/metal_states.hpp + metal/metal_states.mm + metal/metal_texture.hpp + metal/metal_texture.mm + metal/render_state_metal.mm +) endif() omim_add_library(${PROJECT_NAME} ${DRAPE_COMMON_SRC} ${SRC}) diff --git a/drape/attribute_buffer_mutator.cpp b/drape/attribute_buffer_mutator.cpp index f112652542..21fd5d6731 100644 --- a/drape/attribute_buffer_mutator.cpp +++ b/drape/attribute_buffer_mutator.cpp @@ -2,7 +2,6 @@ namespace dp { - AttributeBufferMutator::~AttributeBufferMutator() { SharedBufferManager & mng = SharedBufferManager::instance(); @@ -23,5 +22,4 @@ void * AttributeBufferMutator::AllocateMutationBuffer(uint32_t byteCount) m_array.push_back(make_pair(SharedBufferManager::instance().reserveSharedBuffer(byteCount), byteCount)); return &((*m_array.back().first)[0]); } - -} // namespace dp +} // namespace dp diff --git a/drape/attribute_buffer_mutator.hpp b/drape/attribute_buffer_mutator.hpp index 330ec616a4..7155b931e9 100644 --- a/drape/attribute_buffer_mutator.hpp +++ b/drape/attribute_buffer_mutator.hpp @@ -12,7 +12,6 @@ namespace dp { - struct MutateRegion { MutateRegion() : m_offset(0), m_count(0) {} @@ -30,10 +29,10 @@ struct MutateNode class AttributeBufferMutator { - typedef std::pair<SharedBufferManager::shared_buffer_ptr_t, size_t> TBufferNode; - typedef std::vector<TBufferNode> TBufferArray; - typedef std::vector<MutateNode> TMutateNodes; - typedef std::map<BindingInfo, TMutateNodes> TMutateData; + using TBufferNode = std::pair<SharedBufferManager::shared_buffer_ptr_t, size_t>; + using TBufferArray = std::vector<TBufferNode>; + using TMutateNodes = std::vector<MutateNode>; + using TMutateData = std::map<BindingInfo, TMutateNodes>; public: ~AttributeBufferMutator(); @@ -44,9 +43,7 @@ private: friend class VertexArrayBuffer; TMutateData const & GetMutateData() const { return m_data; } -private: TMutateData m_data; TBufferArray m_array; }; - -} // namespace dp +} // namespace dp diff --git a/drape/batcher.cpp b/drape/batcher.cpp index cb9e0c5949..88f70985ed 100644 --- a/drape/batcher.cpp +++ b/drape/batcher.cpp @@ -1,18 +1,14 @@ #include "drape/batcher.hpp" #include "drape/batcher_helpers.hpp" #include "drape/cpu_buffer.hpp" -#include "drape/glextensions_list.hpp" #include "drape/index_storage.hpp" #include "drape/vertex_array_buffer.hpp" #include "base/assert.hpp" #include "base/stl_helpers.hpp" -#include "std/bind.hpp" - namespace dp { - class Batcher::CallbacksWrapper : public BatchCallbacks { public: @@ -20,13 +16,12 @@ public: : m_state(state) , m_overlay(overlay) , m_batcher(batcher) - { - } + {} void SetVAO(ref_ptr<VertexArrayBuffer> buffer) { - // invocation with non-null VAO will cause to invalid range of indices. - // It means that VAO has been changed during batching + // Invocation with non-null VAO will cause to invalid range of indices. + // It means that VAO has been changed during batching. if (m_buffer != nullptr) m_vaoChanged = true; @@ -299,5 +294,4 @@ SessionGuard::~SessionGuard() { m_batcher.EndSession(); } - -} // namespace dp +} // namespace dp diff --git a/drape/batcher.hpp b/drape/batcher.hpp index 3f4ecf714b..63141840c4 100644 --- a/drape/batcher.hpp +++ b/drape/batcher.hpp @@ -9,8 +9,8 @@ #include "base/macros.hpp" -#include "std/map.hpp" -#include "std/function.hpp" +#include <functional> +#include <map> namespace dp { @@ -53,7 +53,7 @@ public: IndicesRange InsertLineRaw(RenderState const & state, ref_ptr<AttributeProvider> params, vector<int> const & indices, drape_ptr<OverlayHandle> && handle); - typedef function<void (RenderState const &, drape_ptr<RenderBucket> &&)> TFlushFn; + using TFlushFn = std::function<void (RenderState const &, drape_ptr<RenderBucket> &&)>; void StartSession(TFlushFn const & flusher); void EndSession(); void ResetSession(); @@ -75,7 +75,7 @@ private: TFlushFn m_flushInterface; - using TBuckets = map<RenderState, drape_ptr<RenderBucket>>; + using TBuckets = std::map<RenderState, drape_ptr<RenderBucket>>; TBuckets m_buckets; uint32_t m_indexBufferSize; diff --git a/drape/batcher_helpers.cpp b/drape/batcher_helpers.cpp index a7653b7a8c..ecb4a5a82d 100644 --- a/drape/batcher_helpers.cpp +++ b/drape/batcher_helpers.cpp @@ -2,7 +2,7 @@ #include "drape/attribute_provider.hpp" #include "drape/cpu_buffer.hpp" #include "drape/index_storage.hpp" -#include "drape/glextensions_list.hpp" +#include "drape/gl_extensions_list.hpp" #include "base/assert.hpp" #include "base/math.hpp" diff --git a/drape/binding_info.cpp b/drape/binding_info.cpp index a1be34d59f..da80934324 100644 --- a/drape/binding_info.cpp +++ b/drape/binding_info.cpp @@ -1,14 +1,12 @@ #include "drape/binding_info.hpp" +#include "drape/gl_includes.hpp" #include "base/assert.hpp" namespace dp { - namespace { - -#include "drape/glIncludes.hpp" uint16_t sizeOfType(glConst type) { if (type == gl_const::GLByteType || type == gl_const::GLUnsignedByteType) @@ -23,16 +21,15 @@ uint16_t sizeOfType(glConst type) ASSERT(false, ()); return 0; } - -} // namespace +} // namespace bool BindingDecl::operator!=(BindingDecl const & other) const { return m_attributeName != other.m_attributeName || - m_componentCount != other.m_componentCount || - m_componentType != other.m_componentType || - m_stride != other.m_stride || - m_offset != other.m_offset; + m_componentCount != other.m_componentCount || + m_componentType != other.m_componentType || + m_stride != other.m_stride || + m_offset != other.m_offset; } bool BindingDecl::operator<(BindingDecl const & other) const @@ -50,8 +47,7 @@ bool BindingDecl::operator<(BindingDecl const & other) const BindingInfo::BindingInfo() : m_info(0) -{ -} +{} BindingInfo::BindingInfo(uint8_t count, uint8_t id) : m_info(((uint16_t)count << 8) | id) @@ -59,10 +55,6 @@ BindingInfo::BindingInfo(uint8_t count, uint8_t id) m_bindings.reset(new BindingDecl[count]); } -BindingInfo::~BindingInfo() -{ -} - uint8_t BindingInfo::GetCount() const { return (m_info & 0xFF00) >> 8; @@ -118,8 +110,6 @@ bool BindingInfo::operator<(BindingInfo const & other) const if (thisDecl != otherDecl) return thisDecl < otherDecl; } - return false; } - -} // namespace dp +} // namespace dp diff --git a/drape/binding_info.hpp b/drape/binding_info.hpp index 5b9bbe49ee..3994bac2b5 100644 --- a/drape/binding_info.hpp +++ b/drape/binding_info.hpp @@ -1,33 +1,33 @@ #pragma once -#include "drape/glconstants.hpp" +#include "drape/gl_constants.hpp" #include "drape/glsl_func.hpp" #include "drape/glsl_types.hpp" -#include "std/string.hpp" -#include "std/shared_array.hpp" +#include <boost/shared_array.hpp> + +#include <string> namespace dp { - struct BindingDecl { - string m_attributeName; + string m_attributeName; uint8_t m_componentCount; glConst m_componentType; uint8_t m_stride; uint8_t m_offset; - bool operator != (BindingDecl const & other) const; - bool operator < (BindingDecl const & other) const; + bool operator!=(BindingDecl const & other) const; + bool operator<(BindingDecl const & other) const; }; class BindingInfo { public: BindingInfo(); - BindingInfo(uint8_t count, uint8_t id = 0); - ~BindingInfo(); + explicit BindingInfo(uint8_t count, uint8_t id = 0); + ~BindingInfo() = default; uint8_t GetCount() const; uint8_t GetID() const; @@ -36,17 +36,17 @@ public: uint16_t GetElementSize() const; bool IsDynamic() const; - bool operator< (BindingInfo const & other) const; + bool operator<(BindingInfo const & other) const; protected: - shared_array<BindingDecl> m_bindings; + boost::shared_array<BindingDecl> m_bindings; uint16_t m_info; }; template <typename TFieldType, typename TVertexType> uint8_t FillDecl(size_t index, string const & attrName, dp::BindingInfo & info, uint8_t offset) { - dp::BindingDecl & decl = info.GetBindingDecl(index); + dp::BindingDecl & decl = info.GetBindingDecl(static_cast<uint16_t>(index)); decl.m_attributeName = attrName; decl.m_componentCount = glsl::GetComponentCount<TFieldType>(); decl.m_componentType = gl_const::GLFloatType; @@ -60,12 +60,9 @@ template <typename TVertex> class BindingFiller { public: - BindingFiller(uint8_t count, uint8_t id = 0) - : m_info(count, id) - { - } + explicit BindingFiller(uint8_t count, uint8_t id = 0) : m_info(count, id) {} - template<typename TFieldType> + template <typename TFieldType> void FillDecl(string const & attrName) { m_offset += dp::FillDecl<TFieldType, TVertex>(m_index, attrName, m_info, m_offset); @@ -78,5 +75,4 @@ private: size_t m_index = 0; uint8_t m_offset = 0; }; - -} // namespace dp +} // namespace dp diff --git a/drape/drape_global.hpp b/drape/drape_global.hpp index b79005d104..2a90388711 100644 --- a/drape/drape_global.hpp +++ b/drape/drape_global.hpp @@ -10,8 +10,9 @@ namespace dp { -enum ApiVersion +enum class ApiVersion { + Invalid = -1, OpenGLES2 = 0, OpenGLES3, Metal @@ -73,12 +74,22 @@ struct TitleDecl bool m_secondaryOptional = false; }; +class BaseFramebuffer +{ +public: + virtual ~BaseFramebuffer() = default; + virtual void Bind() = 0; +}; + inline std::string DebugPrint(dp::ApiVersion apiVersion) { - if (apiVersion == dp::OpenGLES2) - return "OpenGLES2"; - else if (apiVersion == dp::OpenGLES3) - return "OpenGLES3"; + switch (apiVersion) + { + case dp::ApiVersion::Invalid: return "Invalid"; + case dp::ApiVersion::OpenGLES2: return "OpenGLES2"; + case dp::ApiVersion::OpenGLES3: return "OpenGLES3"; + case dp::ApiVersion::Metal: return "Metal"; + } return "Unknown"; } } // namespace dp diff --git a/drape/drape_tests/CMakeLists.txt b/drape/drape_tests/CMakeLists.txt index b89241f6db..81ded8bc74 100644 --- a/drape/drape_tests/CMakeLists.txt +++ b/drape/drape_tests/CMakeLists.txt @@ -21,9 +21,9 @@ set( dummy_texture.hpp failure_reporter.cpp font_texture_tests.cpp - glfunctions.cpp - glmock_functions.cpp - glmock_functions.hpp + gl_functions.cpp + gl_mock_functions.cpp + gl_mock_functions.hpp glyph_mng_tests.cpp glyph_packer_test.cpp img.cpp diff --git a/drape/drape_tests/batcher_tests.cpp b/drape/drape_tests/batcher_tests.cpp index f4c04bb6e9..614b99e101 100644 --- a/drape/drape_tests/batcher_tests.cpp +++ b/drape/drape_tests/batcher_tests.cpp @@ -1,9 +1,9 @@ #include "testing/testing.hpp" #include "drape/batcher.hpp" -#include "drape/drape_tests/glmock_functions.hpp" +#include "drape/drape_tests/gl_mock_functions.hpp" #include "drape/drape_tests/memory_comparer.hpp" -#include "drape/glconstants.hpp" +#include "drape/gl_constants.hpp" #include "drape/index_storage.hpp" #include "drape/vertex_array_buffer.hpp" diff --git a/drape/drape_tests/buffer_tests.cpp b/drape/drape_tests/buffer_tests.cpp index d68bd36076..b006403faf 100644 --- a/drape/drape_tests/buffer_tests.cpp +++ b/drape/drape_tests/buffer_tests.cpp @@ -1,6 +1,6 @@ #include "testing/testing.hpp" -#include "drape/drape_tests/glmock_functions.hpp" +#include "drape/drape_tests/gl_mock_functions.hpp" #include "drape/data_buffer.hpp" #include "drape/gpu_buffer.hpp" diff --git a/drape/drape_tests/font_texture_tests.cpp b/drape/drape_tests/font_texture_tests.cpp index 9f18c2ca0f..ecb1fe186d 100644 --- a/drape/drape_tests/font_texture_tests.cpp +++ b/drape/drape_tests/font_texture_tests.cpp @@ -1,5 +1,5 @@ #include "drape/drape_tests/dummy_texture.hpp" -#include "drape/drape_tests/glmock_functions.hpp" +#include "drape/drape_tests/gl_mock_functions.hpp" #include "drape/drape_tests/img.hpp" #include "platform/platform.hpp" @@ -102,12 +102,12 @@ UNIT_TEST(UploadingGlyphs) ; Texture::Params p; - p.m_allocator = GetDefaultAllocator(); + p.m_allocator = GetDefaultAllocator(nullptr /* context */); p.m_format = dp::TextureFormat::Alpha; p.m_width = p.m_height = 128; DummyTexture tex; - tex.Create(p); + tex.Create(nullptr /* context */, p); EXPECTGL(glTexSubImage2D(_, _, _, _, _, _, _)) .WillRepeatedly(Invoke(&r, &UploadedRender::glMemoryToQImage)); index.UploadResources(make_ref(&tex)); diff --git a/drape/drape_tests/glfunctions.cpp b/drape/drape_tests/gl_functions.cpp index 249e9deae6..74e734b4b7 100644 --- a/drape/drape_tests/glfunctions.cpp +++ b/drape/drape_tests/gl_functions.cpp @@ -1,5 +1,5 @@ -#include "drape/glfunctions.hpp" -#include "drape/drape_tests/glmock_functions.hpp" +#include "drape/gl_functions.hpp" +#include "drape/drape_tests/gl_mock_functions.hpp" #include "base/assert.hpp" @@ -118,7 +118,7 @@ int8_t GLFunctions::glGetAttribLocation(uint32_t programID, string const & name) void GLFunctions::glBindAttribLocation(uint32_t programID, uint8_t index, string const & name) {} -/// enable vertex attribute binding. To get attributeLocation need to call glGetAttributeLocation +// Enable vertex attribute binding. To get attributeLocation need to call glGetAttributeLocation. void GLFunctions::glEnableVertexAttribute(int32_t attributeLocation) { MOCK_CALL(glEnableVertexAttribute(attributeLocation)); diff --git a/drape/drape_tests/glmock_functions.cpp b/drape/drape_tests/gl_mock_functions.cpp index 0d7ff6e746..893a5065b8 100644 --- a/drape/drape_tests/glmock_functions.cpp +++ b/drape/drape_tests/gl_mock_functions.cpp @@ -1,8 +1,7 @@ -#include "drape/drape_tests/glmock_functions.hpp" +#include "drape/drape_tests/gl_mock_functions.hpp" namespace emul { - void GLMockFunctions::Init(int * argc, char **argv) { ::testing::InitGoogleMock(argc, argv); @@ -26,5 +25,4 @@ void GLMockFunctions::ValidateAndClear() } GLMockFunctions * GLMockFunctions::m_mock; - -} // namespace emul +} // namespace emul diff --git a/drape/drape_tests/glmock_functions.hpp b/drape/drape_tests/gl_mock_functions.hpp index 2f5b99f33c..06d01704e3 100644 --- a/drape/drape_tests/glmock_functions.hpp +++ b/drape/drape_tests/gl_mock_functions.hpp @@ -1,14 +1,12 @@ #pragma once #include "drape/drape_global.hpp" -#include "drape/glconstants.hpp" -#include "std/string.hpp" +#include "drape/gl_constants.hpp" #include <gmock/gmock.h> namespace emul { - class GLMockFunctions { public: @@ -110,7 +108,6 @@ public: private: static GLMockFunctions * m_mock; }; - -} // namespace emul +} // namespace emul #define EXPECTGL(x) EXPECT_CALL(emul::GLMockFunctions::Instance(), x) diff --git a/drape/drape_tests/memory_comparer.hpp b/drape/drape_tests/memory_comparer.hpp index fcc97c19a6..a6c3feaaf5 100644 --- a/drape/drape_tests/memory_comparer.hpp +++ b/drape/drape_tests/memory_comparer.hpp @@ -1,7 +1,7 @@ #pragma once #include "base/logging.hpp" -#include "drape/glconstants.hpp" +#include "drape/gl_constants.hpp" #include "testing/testing.hpp" #include <cstring> diff --git a/drape/drape_tests/static_texture_tests.cpp b/drape/drape_tests/static_texture_tests.cpp index 9022c00ad3..b6c2a83558 100644 --- a/drape/drape_tests/static_texture_tests.cpp +++ b/drape/drape_tests/static_texture_tests.cpp @@ -20,10 +20,12 @@ UNIT_TEST(CheckTrafficArrowTextures) GetStyleReader().SetCurrentStyle(style); for (size_t i = 0; i < skinPaths.size(); ++i) { - dp::StaticTexture texture("traffic-arrow", skinPaths[i], dp::TextureFormat::RGBA8, nullptr); + dp::StaticTexture texture(nullptr /* context */, "traffic-arrow", skinPaths[i], + dp::TextureFormat::RGBA8, nullptr); TEST(texture.IsLoadingCorrect(), ()); - dp::StaticTexture texture2("area-hatching", skinPaths[i], dp::TextureFormat::RGBA8, nullptr); + dp::StaticTexture texture2(nullptr /* context */, "area-hatching", skinPaths[i], + dp::TextureFormat::RGBA8, nullptr); TEST(texture2.IsLoadingCorrect(), ()); } } diff --git a/drape/drape_tests/testingmain.cpp b/drape/drape_tests/testingmain.cpp index a76d7c86c3..4cde0e6c90 100644 --- a/drape/drape_tests/testingmain.cpp +++ b/drape/drape_tests/testingmain.cpp @@ -11,8 +11,7 @@ #include "std/target_os.hpp" #include "std/bind.hpp" -#include "drape/drape_tests/glmock_functions.hpp" - +#include "drape/drape_tests/gl_mock_functions.hpp" #ifdef OMIM_UNIT_TEST_WITH_QT_EVENT_LOOP #include <Qt> diff --git a/drape/drape_tests/texture_of_colors_tests.cpp b/drape/drape_tests/texture_of_colors_tests.cpp index 7d631771af..201c01d721 100644 --- a/drape/drape_tests/texture_of_colors_tests.cpp +++ b/drape/drape_tests/texture_of_colors_tests.cpp @@ -3,11 +3,11 @@ #include "drape/drape_tests/memory_comparer.hpp" #include "drape/drape_tests/dummy_texture.hpp" -#include "drape/glconstants.hpp" +#include "drape/gl_constants.hpp" #include "drape/texture_of_colors.hpp" #include "drape/texture.hpp" -#include "drape/drape_tests/glmock_functions.hpp" +#include "drape/drape_tests/gl_mock_functions.hpp" #include <gmock/gmock.h> @@ -94,13 +94,13 @@ UNIT_TEST(ColorPalleteUploadingSingleRow) InitOpenGLTextures(width, height); Texture::Params p; - p.m_allocator = GetDefaultAllocator(); + p.m_allocator = GetDefaultAllocator(nullptr /* context */); p.m_format = dp::TextureFormat::RGBA8; p.m_width = width; p.m_height = height; DummyTexture texture; - texture.Create(p); + texture.Create(nullptr /* context */, p); DummyColorPallete cp(m2::PointU(width, height)); cp.UploadResources(make_ref(&texture)); @@ -192,13 +192,13 @@ UNIT_TEST(ColorPalleteUploadingPartialyRow) InitOpenGLTextures(width, height); Texture::Params p; - p.m_allocator = GetDefaultAllocator(); + p.m_allocator = GetDefaultAllocator(nullptr /* context */); p.m_format = dp::TextureFormat::RGBA8; p.m_width = width; p.m_height = height; DummyTexture texture; - texture.Create(p); + texture.Create(nullptr /* context */, p); DummyColorPallete cp(m2::PointU(width, height)); @@ -280,13 +280,13 @@ UNIT_TEST(ColorPalleteUploadingMultiplyRow) InitOpenGLTextures(width, height); Texture::Params p; - p.m_allocator = GetDefaultAllocator(); + p.m_allocator = GetDefaultAllocator(nullptr /* context */); p.m_format = dp::TextureFormat::RGBA8; p.m_width = width; p.m_height = height; DummyTexture texture; - texture.Create(p); + texture.Create(nullptr /* context */, p); DummyColorPallete cp(m2::PointU(width, height)); cp.SetIsDebug(true); diff --git a/drape/drape_tests/uniform_value_tests.cpp b/drape/drape_tests/uniform_value_tests.cpp index 1db347d1f4..b7876ab1cc 100644 --- a/drape/drape_tests/uniform_value_tests.cpp +++ b/drape/drape_tests/uniform_value_tests.cpp @@ -1,10 +1,10 @@ #include "testing/testing.hpp" #include "drape/drape_global.hpp" -#include "drape/gpu_program.hpp" +#include "drape/gl_gpu_program.hpp" #include "drape/uniform_value.hpp" -#include "drape/drape_tests/glmock_functions.hpp" +#include "drape/drape_tests/gl_mock_functions.hpp" #include <cstring> #include <string> @@ -151,7 +151,7 @@ UNIT_TEST(UniformValueTest) drape_ptr<Shader> fs = make_unique_dp<Shader>("", "void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); }", "", Shader::Type::FragmentShader); - drape_ptr<GpuProgram> program = make_unique_dp<GpuProgram>("", make_ref(vs), make_ref(fs)); + drape_ptr<GLGpuProgram> program = make_unique_dp<GLGpuProgram>("", make_ref(vs), make_ref(fs)); program->Bind(); @@ -172,4 +172,10 @@ UNIT_TEST(UniformValueTest) UniformValue::ApplyRaw(positionLoc, glsl::vec4(1.0f, 2.0f, 3.0f, 4.0f)); UniformValue::ApplyRaw(modelViewLoc, glsl::make_mat4(matrix)); + + program->Unbind(); + + program.reset(); + vs.reset(); + fs.reset(); } diff --git a/drape/dynamic_texture.hpp b/drape/dynamic_texture.hpp index 877c40c168..0ff603a76d 100644 --- a/drape/dynamic_texture.hpp +++ b/drape/dynamic_texture.hpp @@ -26,26 +26,27 @@ public: return m_indexer->MapResource(static_cast<TResourceKey const &>(key), newResource); } - void Create(Params const & params) override + 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(params); + Base::Create(std::move(context), params); } - void Create(Params const & params, ref_ptr<void> data) override + 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(params, data); + Base::Create(std::move(context), params, data); } - void UpdateState() override + void UpdateState(ref_ptr<dp::GraphicsContext> context) override { // Create texture before first uploading. if (!m_isInitialized) { std::vector<uint8_t> initData(m_params.m_width * m_params.m_height * GetBytesPerPixel(m_params.m_format), 0); - Create(m_params, initData.data()); + Create(std::move(context), m_params, initData.data()); m_isInitialized = true; } @@ -101,16 +102,16 @@ protected: : m_isInitialized(false) {} - struct TextureParams + struct DynamicTextureParams { m2::PointU m_size; - dp::TextureFormat m_format; - TextureFilter m_filter; - bool m_usePixelBuffer; + dp::TextureFormat m_format = dp::TextureFormat::Unspecified; + TextureFilter m_filter = dp::TextureFilter::Nearest; + bool m_usePixelBuffer = false; }; void Init(ref_ptr<HWTextureAllocator> allocator, ref_ptr<TIndexer> indexer, - TextureParams const & params) + DynamicTextureParams const & params) { m_indexer = indexer; m_params.m_allocator = allocator; @@ -119,6 +120,7 @@ protected: m_params.m_format = params.m_format; m_params.m_filter = params.m_filter; m_params.m_usePixelBuffer = params.m_usePixelBuffer; + m_params.m_isMutable = true; } void Reset() diff --git a/drape/font_texture.hpp b/drape/font_texture.hpp index f3aea98e09..e7fd2bf0c5 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, glyphMng, glyphGenerator) + : m_index(size, std::move(glyphMng), std::move(glyphGenerator)) { - TBase::TextureParams params{size, TextureFormat::Alpha, - TextureFilter::Linear, true /* m_usePixelBuffer */}; - TBase::Init(allocator, make_ref(&m_index), params); + TBase::DynamicTextureParams params{size, TextureFormat::Alpha, + TextureFilter::Linear, true /* m_usePixelBuffer */}; + TBase::Init(std::move(allocator), make_ref(&m_index), params); } ~FontTexture() override { TBase::Reset(); } diff --git a/drape/framebuffer.cpp b/drape/framebuffer.cpp index 72fed7f05d..2ff239b14f 100644 --- a/drape/framebuffer.cpp +++ b/drape/framebuffer.cpp @@ -1,5 +1,5 @@ #include "drape/framebuffer.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include "drape/texture.hpp" #include "base/assert.hpp" @@ -11,32 +11,15 @@ namespace dp Framebuffer::DepthStencil::DepthStencil(bool depthEnabled, bool stencilEnabled) : m_depthEnabled(depthEnabled) , m_stencilEnabled(stencilEnabled) -{ - if (m_depthEnabled && m_stencilEnabled) - { - // OpenGLES2 does not support texture-based depth-stencil. - CHECK(GLFunctions::CurrentApiVersion != dp::ApiVersion::OpenGLES2, ()); - - m_layout = gl_const::GLDepthStencil; - m_pixelType = gl_const::GLUnsignedInt24_8Type; - } - else if (m_depthEnabled) - { - m_layout = gl_const::GLDepthComponent; - m_pixelType = gl_const::GLUnsignedIntType; - } - else - { - CHECK(false, ("Unsupported depth-stencil combination.")); - } -} +{} Framebuffer::DepthStencil::~DepthStencil() { Destroy(); } -void Framebuffer::DepthStencil::SetSize(uint32_t width, uint32_t height) +void Framebuffer::DepthStencil::SetSize(ref_ptr<dp::GraphicsContext> context, + uint32_t width, uint32_t height) { Destroy(); @@ -47,10 +30,13 @@ void Framebuffer::DepthStencil::SetSize(uint32_t width, uint32_t height) params.m_format = TextureFormat::DepthStencil; else if (m_depthEnabled) params.m_format = TextureFormat::Depth; - params.m_allocator = GetDefaultAllocator(); + else + CHECK(false, ("Unsupported depth-stencil combination.")); + params.m_allocator = GetDefaultAllocator(context); + params.m_isRenderTarget = true; m_texture = make_unique_dp<FramebufferTexture>(); - m_texture->Create(params); + m_texture->Create(context, params); } void Framebuffer::DepthStencil::Destroy() @@ -70,6 +56,11 @@ uint32_t Framebuffer::DepthStencil::GetStencilAttachmentId() const return m_stencilEnabled ? m_texture->GetID() : 0; } +ref_ptr<FramebufferTexture> Framebuffer::DepthStencil::GetTexture() const +{ + return make_ref(m_texture); +} + Framebuffer::Framebuffer() : m_colorFormat(TextureFormat::RGBA8) { @@ -113,7 +104,7 @@ void Framebuffer::SetFramebufferFallback(FramebufferFallback && fallback) m_framebufferFallback = std::move(fallback); } -void Framebuffer::SetSize(uint32_t width, uint32_t height) +void Framebuffer::SetSize(ref_ptr<dp::GraphicsContext> context, uint32_t width, uint32_t height) { if (!m_isSupported) return; @@ -130,50 +121,56 @@ void Framebuffer::SetSize(uint32_t width, uint32_t height) params.m_width = width; params.m_height = height; params.m_format = m_colorFormat; - params.m_allocator = GetDefaultAllocator(); + params.m_allocator = GetDefaultAllocator(context); + params.m_isRenderTarget = true; m_colorTexture = make_unique_dp<FramebufferTexture>(); - m_colorTexture->Create(params); - - glConst depthAttachmentId = 0; - glConst stencilAttachmentId = 0; - if (m_depthStencilRef != nullptr) - { - if (m_depthStencilRef == m_depthStencil.get()) - m_depthStencilRef->SetSize(m_width, m_height); - depthAttachmentId = m_depthStencilRef->GetDepthAttachmentId(); - stencilAttachmentId = m_depthStencilRef->GetStencilAttachmentId(); - } + m_colorTexture->Create(context, params); - GLFunctions::glGenFramebuffer(&m_framebufferId); - GLFunctions::glBindFramebuffer(m_framebufferId); + if (m_depthStencilRef != nullptr && m_depthStencilRef == m_depthStencil.get()) + m_depthStencilRef->SetSize(context, m_width, m_height); - GLFunctions::glFramebufferTexture2D(gl_const::GLColorAttachment, m_colorTexture->GetID()); - if (depthAttachmentId != stencilAttachmentId) + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) { - GLFunctions::glFramebufferTexture2D(gl_const::GLDepthAttachment, depthAttachmentId); - GLFunctions::glFramebufferTexture2D(gl_const::GLStencilAttachment, stencilAttachmentId); + glConst depthAttachmentId = 0; + glConst stencilAttachmentId = 0; + if (m_depthStencilRef != nullptr) + { + depthAttachmentId = m_depthStencilRef->GetDepthAttachmentId(); + stencilAttachmentId = m_depthStencilRef->GetStencilAttachmentId(); + } + + GLFunctions::glGenFramebuffer(&m_framebufferId); + GLFunctions::glBindFramebuffer(m_framebufferId); + + GLFunctions::glFramebufferTexture2D(gl_const::GLColorAttachment, m_colorTexture->GetID()); + if (depthAttachmentId != stencilAttachmentId) + { + GLFunctions::glFramebufferTexture2D(gl_const::GLDepthAttachment, depthAttachmentId); + GLFunctions::glFramebufferTexture2D(gl_const::GLStencilAttachment, stencilAttachmentId); + } + else + { + GLFunctions::glFramebufferTexture2D(gl_const::GLDepthStencilAttachment, depthAttachmentId); + } + + uint32_t const status = GLFunctions::glCheckFramebufferStatus(); + if (status != gl_const::GLFramebufferComplete) + { + m_isSupported = false; + Destroy(); + LOG(LWARNING, ("Framebuffer is unsupported. Framebuffer status =", status)); + } + + if (m_framebufferFallback != nullptr) + m_framebufferFallback(); } - else - { - GLFunctions::glFramebufferTexture2D(gl_const::GLDepthStencilAttachment, depthAttachmentId); - } - - uint32_t const status = GLFunctions::glCheckFramebufferStatus(); - if (status != gl_const::GLFramebufferComplete) - { - m_isSupported = false; - Destroy(); - LOG(LWARNING, ("Framebuffer is unsupported. Framebuffer status =", status)); - } - - if (m_framebufferFallback != nullptr) - m_framebufferFallback(); } void Framebuffer::SetDepthStencilRef(ref_ptr<DepthStencil> depthStencilRef) { - m_depthStencilRef = depthStencilRef; + m_depthStencilRef = std::move(depthStencilRef); } void Framebuffer::ApplyOwnDepthStencil() @@ -181,13 +178,14 @@ void Framebuffer::ApplyOwnDepthStencil() m_depthStencilRef = make_ref(m_depthStencil); } -void Framebuffer::Enable() +void Framebuffer::Bind() { ASSERT(m_isSupported, ()); + ASSERT_NOT_EQUAL(m_framebufferId, 0, ()); GLFunctions::glBindFramebuffer(m_framebufferId); } -void Framebuffer::Disable() +void Framebuffer::ApplyFallback() { ASSERT(m_isSupported, ()); if (m_framebufferFallback != nullptr) diff --git a/drape/framebuffer.hpp b/drape/framebuffer.hpp index c2c15ff4a7..05729641ec 100644 --- a/drape/framebuffer.hpp +++ b/drape/framebuffer.hpp @@ -1,5 +1,7 @@ #pragma once +#include "drape/drape_global.hpp" +#include "drape/graphics_context.hpp" #include "drape/pointers.hpp" #include "drape/texture.hpp" @@ -8,7 +10,7 @@ namespace dp { -class FramebufferTexture: public Texture +class FramebufferTexture : public Texture { public: ref_ptr<ResourceInfo> FindResource(Key const & key, bool & newResource) override { return nullptr; } @@ -16,7 +18,7 @@ public: using FramebufferFallback = std::function<bool()>; -class Framebuffer +class Framebuffer : public BaseFramebuffer { public: class DepthStencil @@ -24,35 +26,35 @@ public: public: DepthStencil(bool depthEnabled, bool stencilEnabled); ~DepthStencil(); - void SetSize(uint32_t width, uint32_t height); + void SetSize(ref_ptr<dp::GraphicsContext> context, uint32_t width, uint32_t height); void Destroy(); uint32_t GetDepthAttachmentId() const; uint32_t GetStencilAttachmentId() const; + ref_ptr<FramebufferTexture> GetTexture() const; private: bool const m_depthEnabled = false; bool const m_stencilEnabled = false; - uint32_t m_layout = 0; - uint32_t m_pixelType = 0; drape_ptr<FramebufferTexture> m_texture; }; Framebuffer(); explicit Framebuffer(TextureFormat colorFormat); Framebuffer(TextureFormat colorFormat, bool depthEnabled, bool stencilEnabled); - ~Framebuffer(); + ~Framebuffer() override; void SetFramebufferFallback(FramebufferFallback && fallback); - void SetSize(uint32_t width, uint32_t height); + void SetSize(ref_ptr<dp::GraphicsContext> context, uint32_t width, uint32_t height); void SetDepthStencilRef(ref_ptr<DepthStencil> depthStencilRef); void ApplyOwnDepthStencil(); - void Enable(); - void Disable(); + void Bind() override; + void ApplyFallback(); ref_ptr<Texture> GetTexture() const; ref_ptr<DepthStencil> GetDepthStencilRef() const; bool IsSupported() const { return m_isSupported; } + private: void Destroy(); diff --git a/drape/glconstants.cpp b/drape/gl_constants.cpp index 6a06dab62b..8176605246 100644 --- a/drape/glconstants.cpp +++ b/drape/gl_constants.cpp @@ -1,5 +1,5 @@ -#include "drape/glconstants.hpp" -#include "drape/glIncludes.hpp" +#include "drape/gl_constants.hpp" +#include "drape/gl_includes.hpp" #if !defined(GL_RGBA8_OES) #define GL_RGBA8_OES 0x8058 diff --git a/drape/glconstants.hpp b/drape/gl_constants.hpp index 9517174334..9517174334 100644 --- a/drape/glconstants.hpp +++ b/drape/gl_constants.hpp diff --git a/drape/glextensions_list.cpp b/drape/gl_extensions_list.cpp index 30cafee26a..29c6de1988 100644 --- a/drape/glextensions_list.cpp +++ b/drape/gl_extensions_list.cpp @@ -1,5 +1,5 @@ -#include "drape/glextensions_list.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_extensions_list.hpp" +#include "drape/gl_functions.hpp" #include "base/assert.hpp" diff --git a/drape/glextensions_list.hpp b/drape/gl_extensions_list.hpp index 5f2f18370f..5f2f18370f 100644 --- a/drape/glextensions_list.hpp +++ b/drape/gl_extensions_list.hpp diff --git a/drape/glfunctions.cpp b/drape/gl_functions.cpp index 14d22f136b..77df358c75 100644 --- a/drape/glfunctions.cpp +++ b/drape/gl_functions.cpp @@ -1,6 +1,6 @@ -#include "drape/glfunctions.hpp" -#include "drape/glIncludes.hpp" -#include "drape/glextensions_list.hpp" +#include "drape/gl_functions.hpp" +#include "drape/gl_includes.hpp" +#include "drape/gl_extensions_list.hpp" #include "base/assert.hpp" #include "base/logging.hpp" @@ -21,7 +21,7 @@ #endif // static -dp::ApiVersion GLFunctions::CurrentApiVersion = dp::ApiVersion::OpenGLES2; +dp::ApiVersion GLFunctions::CurrentApiVersion = dp::ApiVersion::Invalid; namespace { @@ -388,6 +388,7 @@ void GLFunctions::Init(dp::ApiVersion apiVersion) bool GLFunctions::glHasExtension(std::string const & name) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); if (CurrentApiVersion == dp::ApiVersion::OpenGLES2) { char const * extensions = reinterpret_cast<char const *>(::glGetString(GL_EXTENSIONS)); @@ -424,57 +425,78 @@ bool GLFunctions::glHasExtension(std::string const & name) void GLFunctions::glClearColor(float r, float g, float b, float a) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glClearColorFn != nullptr, ()); GLCHECK(glClearColorFn(r, g, b, a)); } void GLFunctions::glClear(uint32_t clearBits) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glClearFn != nullptr, ()); GLCHECK(glClearFn(clearBits)); } void GLFunctions::glViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glViewportFn != nullptr, ()); GLCHECK(glViewportFn(x, y, w, h)); } void GLFunctions::glScissor(uint32_t x, uint32_t y, uint32_t w, uint32_t h) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glScissorFn != nullptr, ()); GLCHECK(glScissorFn(x, y, w, h)); } void GLFunctions::glFlush() { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glFlushFn != nullptr, ()); GLCHECK(glFlushFn()); } -void GLFunctions::glFinish() { GLCHECK(::glFinish()); } +void GLFunctions::glFinish() +{ + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); + GLCHECK(::glFinish()); +} -void GLFunctions::glFrontFace(glConst mode) { GLCHECK(::glFrontFace(mode)); } +void GLFunctions::glFrontFace(glConst mode) +{ + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); + GLCHECK(::glFrontFace(mode)); +} -void GLFunctions::glCullFace(glConst face) { GLCHECK(::glCullFace(face)); } +void GLFunctions::glCullFace(glConst face) +{ + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); + GLCHECK(::glCullFace(face)); +} void GLFunctions::glStencilOpSeparate(glConst face, glConst sfail, glConst dpfail, glConst dppass) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glStencilOpSeparate(face, sfail, dpfail, dppass)); } void GLFunctions::glStencilFuncSeparate(glConst face, glConst func, int ref, uint32_t mask) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glStencilFuncSeparate(face, func, ref, mask)); } void GLFunctions::glPixelStore(glConst name, uint32_t value) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glPixelStorei(name, value)); } int32_t GLFunctions::glGetInteger(glConst pname) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLint value; GLCHECK(::glGetIntegerv(pname, &value)); return (int32_t)value; @@ -482,6 +504,7 @@ int32_t GLFunctions::glGetInteger(glConst pname) std::string GLFunctions::glGetString(glConst pname) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); char const * str = reinterpret_cast<char const *>(::glGetString(pname)); GLCHECKCALL(); if (str == nullptr) @@ -492,6 +515,7 @@ std::string GLFunctions::glGetString(glConst pname) int32_t GLFunctions::glGetMaxLineWidth() { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLint range[2]; GLCHECK(::glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range)); return std::max(range[0], range[1]); @@ -499,6 +523,7 @@ int32_t GLFunctions::glGetMaxLineWidth() int32_t GLFunctions::glGetBufferParameter(glConst target, glConst name) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLint result; ASSERT(glGetBufferParameterFn != nullptr, ()); GLCHECK(glGetBufferParameterFn(target, name, &result)); @@ -507,16 +532,19 @@ int32_t GLFunctions::glGetBufferParameter(glConst target, glConst name) void GLFunctions::glEnable(glConst mode) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glEnable(mode)); } void GLFunctions::glDisable(glConst mode) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glDisable(mode)); } void GLFunctions::glClearDepthValue(double depth) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); #if defined(OMIM_OS_IPHONE) || defined(OMIM_OS_ANDROID) GLCHECK(::glClearDepthf(static_cast<GLclampf>(depth))); #else @@ -526,23 +554,32 @@ void GLFunctions::glClearDepthValue(double depth) void GLFunctions::glDepthMask(bool needWriteToDepthBuffer) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glDepthMask(convert(needWriteToDepthBuffer))); } -void GLFunctions::glDepthFunc(glConst depthFunc) { GLCHECK(::glDepthFunc(depthFunc)); } +void GLFunctions::glDepthFunc(glConst depthFunc) +{ + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); + GLCHECK(::glDepthFunc(depthFunc)); +} + void GLFunctions::glBlendEquation(glConst function) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glBlendEquationFn != nullptr, ()); GLCHECK(glBlendEquationFn(function)); } void GLFunctions::glBlendFunc(glConst srcFactor, glConst dstFactor) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glBlendFunc(srcFactor, dstFactor)); } uint32_t GLFunctions::glGenVertexArray() { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glGenVertexArraysFn != nullptr, ()); GLuint result = std::numeric_limits<GLuint>::max(); GLCHECK(glGenVertexArraysFn(1, &result)); @@ -551,18 +588,21 @@ uint32_t GLFunctions::glGenVertexArray() void GLFunctions::glBindVertexArray(uint32_t vao) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glBindVertexArrayFn != nullptr, ()); GLCHECK(glBindVertexArrayFn(vao)); } void GLFunctions::glDeleteVertexArray(uint32_t vao) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glDeleteVertexArrayFn != nullptr, ()); GLCHECK(glDeleteVertexArrayFn(1, &vao)); } uint32_t GLFunctions::glGenBuffer() { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glGenBuffersFn != nullptr, ()); GLuint result = std::numeric_limits<GLuint>::max(); GLCHECK(glGenBuffersFn(1, &result)); @@ -571,6 +611,7 @@ uint32_t GLFunctions::glGenBuffer() void GLFunctions::glBindBuffer(uint32_t vbo, uint32_t target) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glBindBufferFn != nullptr, ()); #ifdef DEBUG std::lock_guard<std::mutex> guard(g_boundBuffersMutex); @@ -581,6 +622,7 @@ void GLFunctions::glBindBuffer(uint32_t vbo, uint32_t target) void GLFunctions::glDeleteBuffer(uint32_t vbo) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glDeleteBuffersFn != nullptr, ()); #ifdef DEBUG std::lock_guard<std::mutex> guard(g_boundBuffersMutex); @@ -592,18 +634,21 @@ void GLFunctions::glDeleteBuffer(uint32_t vbo) void GLFunctions::glBufferData(glConst target, uint32_t size, void const * data, glConst usage) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glBufferDataFn != nullptr, ()); GLCHECK(glBufferDataFn(target, size, data, usage)); } void GLFunctions::glBufferSubData(glConst target, uint32_t size, void const * data, uint32_t offset) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glBufferSubDataFn != nullptr, ()); GLCHECK(glBufferSubDataFn(target, offset, size, data)); } void * GLFunctions::glMapBuffer(glConst target, glConst access) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glMapBufferFn != nullptr, ()); void * result = glMapBufferFn(target, access); GLCHECKCALL(); @@ -612,6 +657,7 @@ void * GLFunctions::glMapBuffer(glConst target, glConst access) void GLFunctions::glUnmapBuffer(glConst target) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUnmapBufferFn != nullptr, ()); VERIFY(glUnmapBufferFn(target) == GL_TRUE, ()); GLCHECKCALL(); @@ -620,6 +666,7 @@ void GLFunctions::glUnmapBuffer(glConst target) void * GLFunctions::glMapBufferRange(glConst target, uint32_t offset, uint32_t length, glConst access) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glMapBufferRangeFn != nullptr, ()); void * result = glMapBufferRangeFn(target, offset, length, access); GLCHECKCALL(); @@ -628,12 +675,14 @@ void * GLFunctions::glMapBufferRange(glConst target, uint32_t offset, uint32_t l void GLFunctions::glFlushMappedBufferRange(glConst target, uint32_t offset, uint32_t length) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glFlushMappedBufferRangeFn != nullptr, ()); GLCHECK(glFlushMappedBufferRangeFn(target, offset, length)); } uint32_t GLFunctions::glCreateShader(glConst type) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glCreateShaderFn != nullptr, ()); GLuint result = glCreateShaderFn(type); GLCHECKCALL(); @@ -642,6 +691,7 @@ uint32_t GLFunctions::glCreateShader(glConst type) void GLFunctions::glShaderSource(uint32_t shaderID, std::string const & src, std::string const & defines) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glShaderSourceFn != nullptr, ()); std::string fullSrc; @@ -664,6 +714,7 @@ void GLFunctions::glShaderSource(uint32_t shaderID, std::string const & src, std bool GLFunctions::glCompileShader(uint32_t shaderID, std::string & errorLog) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glCompileShaderFn != nullptr, ()); ASSERT(glGetShaderivFn != nullptr, ()); ASSERT(glGetShaderInfoLogFn != nullptr, ()); @@ -683,12 +734,14 @@ bool GLFunctions::glCompileShader(uint32_t shaderID, std::string & errorLog) void GLFunctions::glDeleteShader(uint32_t shaderID) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glDeleteShaderFn != nullptr, ()); GLCHECK(glDeleteBuffersFn(1, &shaderID)); } uint32_t GLFunctions::glCreateProgram() { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glCreateProgramFn != nullptr, ()); GLuint result = glCreateProgramFn(); GLCHECKCALL(); @@ -697,18 +750,21 @@ uint32_t GLFunctions::glCreateProgram() void GLFunctions::glAttachShader(uint32_t programID, uint32_t shaderID) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glAttachShaderFn != nullptr, ()); GLCHECK(glAttachShaderFn(programID, shaderID)); } void GLFunctions::glDetachShader(uint32_t programID, uint32_t shaderID) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glDetachShaderFn != nullptr, ()); GLCHECK(glDetachShaderFn(programID, shaderID)); } bool GLFunctions::glLinkProgram(uint32_t programID, std::string & errorLog) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glLinkProgramFn != nullptr, ()); ASSERT(glGetProgramivFn != nullptr, ()); ASSERT(glGetProgramInfoLogFn != nullptr, ()); @@ -729,18 +785,21 @@ bool GLFunctions::glLinkProgram(uint32_t programID, std::string & errorLog) void GLFunctions::glDeleteProgram(uint32_t programID) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glDeleteProgramFn != nullptr, ()); GLCHECK(glDeleteProgramFn(programID)); } void GLFunctions::glUseProgram(uint32_t programID) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUseProgramFn != nullptr, ()); GLCHECK(glUseProgramFn(programID)); } int8_t GLFunctions::glGetAttribLocation(uint32_t programID, std::string const & name) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glGetAttribLocationFn != nullptr, ()); int result = glGetAttribLocationFn(programID, name.c_str()); GLCHECKCALL(); @@ -750,12 +809,14 @@ int8_t GLFunctions::glGetAttribLocation(uint32_t programID, std::string const & void GLFunctions::glBindAttribLocation(uint32_t programID, uint8_t index, std::string const & name) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glBindAttribLocationFn != nullptr, ()); GLCHECK(glBindAttribLocationFn(programID, index, name.c_str())); } void GLFunctions::glEnableVertexAttribute(int attributeLocation) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glEnableVertexAttributeFn != nullptr, ()); GLCHECK(glEnableVertexAttributeFn(attributeLocation)); } @@ -763,6 +824,7 @@ void GLFunctions::glEnableVertexAttribute(int attributeLocation) void GLFunctions::glVertexAttributePointer(int attrLocation, uint32_t count, glConst type, bool needNormalize, uint32_t stride, uint32_t offset) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glVertexAttributePointerFn != nullptr, ()); GLCHECK(glVertexAttributePointerFn(attrLocation, count, type, convert(needNormalize), stride, reinterpret_cast<void *>(offset))); @@ -771,6 +833,7 @@ void GLFunctions::glVertexAttributePointer(int attrLocation, uint32_t count, glC void GLFunctions::glGetActiveUniform(uint32_t programID, uint32_t uniformIndex, int32_t * uniformSize, glConst * type, std::string & name) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glGetActiveUniformFn != nullptr, ()); GLchar buff[256]; GLCHECK(glGetActiveUniformFn(programID, uniformIndex, ARRAY_SIZE(buff), nullptr, uniformSize, @@ -780,6 +843,7 @@ void GLFunctions::glGetActiveUniform(uint32_t programID, uint32_t uniformIndex, int8_t GLFunctions::glGetUniformLocation(uint32_t programID, std::string const & name) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glGetUniformLocationFn != nullptr, ()); int result = glGetUniformLocationFn(programID, name.c_str()); GLCHECKCALL(); @@ -789,6 +853,7 @@ int8_t GLFunctions::glGetUniformLocation(uint32_t programID, std::string const & void GLFunctions::glUniformValuei(int8_t location, int32_t v) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform1iFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform1iFn(location, v)); @@ -796,6 +861,7 @@ void GLFunctions::glUniformValuei(int8_t location, int32_t v) void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform2iFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform2iFn(location, v1, v2)); @@ -803,6 +869,7 @@ void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2) void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32_t v3) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform3iFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform3iFn(location, v1, v2, v3)); @@ -810,6 +877,7 @@ void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32 void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32_t v3, int32_t v4) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform4iFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform4iFn(location, v1, v2, v3, v4)); @@ -817,6 +885,7 @@ void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32 void GLFunctions::glUniformValueiv(int8_t location, int32_t * v, uint32_t size) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform1ivFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform1ivFn(location, size, v)); @@ -824,6 +893,7 @@ void GLFunctions::glUniformValueiv(int8_t location, int32_t * v, uint32_t size) void GLFunctions::glUniformValuef(int8_t location, float v) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform1fFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform1fFn(location, v)); @@ -831,6 +901,7 @@ void GLFunctions::glUniformValuef(int8_t location, float v) void GLFunctions::glUniformValuef(int8_t location, float v1, float v2) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform2fFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform2fFn(location, v1, v2)); @@ -838,6 +909,7 @@ void GLFunctions::glUniformValuef(int8_t location, float v1, float v2) void GLFunctions::glUniformValuef(int8_t location, float v1, float v2, float v3) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform3fFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform3fFn(location, v1, v2, v3)); @@ -845,6 +917,7 @@ void GLFunctions::glUniformValuef(int8_t location, float v1, float v2, float v3) void GLFunctions::glUniformValuef(int8_t location, float v1, float v2, float v3, float v4) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform4fFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform4fFn(location, v1, v2, v3, v4)); @@ -852,6 +925,7 @@ void GLFunctions::glUniformValuef(int8_t location, float v1, float v2, float v3, void GLFunctions::glUniformValuefv(int8_t location, float * v, uint32_t size) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniform1fvFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniform1fvFn(location, size, v)); @@ -859,6 +933,7 @@ void GLFunctions::glUniformValuefv(int8_t location, float * v, uint32_t size) void GLFunctions::glUniformMatrix4x4Value(int8_t location, float const * values) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glUniformMatrix4fvFn != nullptr, ()); ASSERT(location != -1, ()); GLCHECK(glUniformMatrix4fvFn(location, 1, GL_FALSE, values)); @@ -866,6 +941,7 @@ void GLFunctions::glUniformMatrix4x4Value(int8_t location, float const * values) uint32_t GLFunctions::glGetCurrentProgram() { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLint programIndex = 0; GLCHECK(glGetIntegerv(GL_CURRENT_PROGRAM, &programIndex)); ASSERT_GREATER_OR_EQUAL(programIndex, 0, ()); @@ -874,6 +950,7 @@ uint32_t GLFunctions::glGetCurrentProgram() int32_t GLFunctions::glGetProgramiv(uint32_t program, glConst paramName) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glGetProgramivFn != nullptr, ()); GLint paramValue = 0; GLCHECK(glGetProgramivFn(program, paramName, ¶mValue)); @@ -882,12 +959,14 @@ int32_t GLFunctions::glGetProgramiv(uint32_t program, glConst paramName) void GLFunctions::glActiveTexture(glConst texBlock) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glActiveTextureFn != nullptr, ()); GLCHECK(glActiveTextureFn(texBlock)); } uint32_t GLFunctions::glGenTexture() { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLuint result = std::numeric_limits<GLuint>::max(); GLCHECK(::glGenTextures(1, &result)); return result; @@ -895,17 +974,20 @@ uint32_t GLFunctions::glGenTexture() void GLFunctions::glDeleteTexture(uint32_t id) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glDeleteTextures(1, &id)); } void GLFunctions::glBindTexture(uint32_t textureID) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glBindTexture(GL_TEXTURE_2D, textureID)); } void GLFunctions::glTexImage2D(int width, int height, glConst layout, glConst pixelType, void const * data) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); // In OpenGL ES3: // - we can't create unsized GL_RED texture, so we use GL_R8; // - we can't create unsized GL_RG texture, so we use GL_RG8; @@ -944,17 +1026,20 @@ void GLFunctions::glTexImage2D(int width, int height, glConst layout, glConst pi void GLFunctions::glTexSubImage2D(int x, int y, int width, int height, glConst layout, glConst pixelType, void const * data) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, layout, pixelType, data)); } void GLFunctions::glTexParameter(glConst param, glConst value) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glTexParameteri(GL_TEXTURE_2D, param, value)); } void GLFunctions::glDrawElements(glConst primitive, uint32_t sizeOfIndex, uint32_t indexCount, uint32_t startIndex) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glDrawElements(primitive, indexCount, sizeOfIndex == sizeof(uint32_t) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, reinterpret_cast<GLvoid *>(startIndex * sizeOfIndex))); @@ -962,35 +1047,41 @@ void GLFunctions::glDrawElements(glConst primitive, uint32_t sizeOfIndex, uint32 void GLFunctions::glDrawArrays(glConst mode, int32_t first, uint32_t count) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glDrawArrays(mode, first, count)); } void GLFunctions::glGenFramebuffer(uint32_t * fbo) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glGenFramebuffersFn != nullptr, ()); GLCHECK(glGenFramebuffersFn(1, fbo)); } void GLFunctions::glDeleteFramebuffer(uint32_t * fbo) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glDeleteFramebuffersFn != nullptr, ()); GLCHECK(glDeleteFramebuffersFn(1, fbo)); } void GLFunctions::glFramebufferTexture2D(glConst attachment, glConst texture) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glFramebufferTexture2DFn != nullptr, ()); GLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture, 0)); } void GLFunctions::glBindFramebuffer(uint32_t fbo) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glBindFramebufferFn != nullptr, ()); GLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER, fbo)); } uint32_t GLFunctions::glCheckFramebufferStatus() { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); ASSERT(glCheckFramebufferStatusFn != nullptr, ()); uint32_t const result = glCheckFramebufferStatusFn(GL_FRAMEBUFFER); GLCHECKCALL(); @@ -999,6 +1090,7 @@ uint32_t GLFunctions::glCheckFramebufferStatus() void GLFunctions::glLineWidth(uint32_t value) { + ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLCHECK(::glLineWidth(static_cast<float>(value))); } @@ -1019,6 +1111,7 @@ std::string GetGLError(GLenum error) void CheckGLError(base::SrcPoint const & srcPoint) { + ASSERT_NOT_EQUAL(GLFunctions::CurrentApiVersion, dp::ApiVersion::Invalid, ()); GLenum result = glGetError(); while (result != GL_NO_ERROR) { diff --git a/drape/glfunctions.hpp b/drape/gl_functions.hpp index 3df71f5a75..79c769c55b 100644 --- a/drape/glfunctions.hpp +++ b/drape/gl_functions.hpp @@ -1,7 +1,7 @@ #pragma once #include "drape/drape_global.hpp" -#include "drape/glconstants.hpp" +#include "drape/gl_constants.hpp" #include "base/src_point.hpp" @@ -10,8 +10,6 @@ class GLFunctions { - friend class GLFunctionsCache; - public: static dp::ApiVersion CurrentApiVersion; diff --git a/drape/gpu_program.cpp b/drape/gl_gpu_program.cpp index 2ce44807d7..9aeeb7fbfa 100644 --- a/drape/gpu_program.cpp +++ b/drape/gl_gpu_program.cpp @@ -1,5 +1,5 @@ -#include "drape/gpu_program.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_gpu_program.hpp" +#include "drape/gl_functions.hpp" #include "drape/render_state.hpp" #include "drape/support_manager.hpp" @@ -9,11 +9,11 @@ namespace dp { -GpuProgram::GpuProgram(std::string const & programName, - ref_ptr<Shader> vertexShader, ref_ptr<Shader> fragmentShader) - : m_programName(programName) - , m_vertexShader(vertexShader) - , m_fragmentShader(fragmentShader) +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_programID = GLFunctions::glCreateProgram(); GLFunctions::glAttachShader(m_programID, m_vertexShader->GetID()); @@ -35,10 +35,8 @@ GpuProgram::GpuProgram(std::string const & programName, } } -GpuProgram::~GpuProgram() +GLGpuProgram::~GLGpuProgram() { - Unbind(); - if (SupportManager::Instance().IsTegraDevice()) { GLFunctions::glDetachShader(m_programID, m_vertexShader->GetID()); @@ -48,7 +46,7 @@ GpuProgram::~GpuProgram() GLFunctions::glDeleteProgram(m_programID); } -void GpuProgram::Bind() +void GLGpuProgram::Bind() { // Deactivate all unused textures. uint8_t const usedSlots = TextureState::GetLastUsedSlots(); @@ -61,17 +59,17 @@ void GpuProgram::Bind() GLFunctions::glUseProgram(m_programID); } -void GpuProgram::Unbind() +void GLGpuProgram::Unbind() { GLFunctions::glUseProgram(0); } -int8_t GpuProgram::GetAttributeLocation(std::string const & attributeName) const +int8_t GLGpuProgram::GetAttributeLocation(std::string const & attributeName) const { return GLFunctions::glGetAttribLocation(m_programID, attributeName); } -int8_t GpuProgram::GetUniformLocation(std::string const & uniformName) const +int8_t GLGpuProgram::GetUniformLocation(std::string const & uniformName) const { auto const it = m_uniforms.find(uniformName); if (it == m_uniforms.end()) @@ -80,7 +78,7 @@ int8_t GpuProgram::GetUniformLocation(std::string const & uniformName) const return it->second.m_location; } -glConst GpuProgram::GetUniformType(std::string const & uniformName) const +glConst GLGpuProgram::GetUniformType(std::string const & uniformName) const { auto const it = m_uniforms.find(uniformName); if (it == m_uniforms.end()) @@ -89,12 +87,12 @@ glConst GpuProgram::GetUniformType(std::string const & uniformName) const return it->second.m_type; } -GpuProgram::UniformsInfo const & GpuProgram::GetUniformsInfo() const +GLGpuProgram::UniformsInfo const & GLGpuProgram::GetUniformsInfo() const { return m_uniforms; } -void GpuProgram::LoadUniformLocations() +void GLGpuProgram::LoadUniformLocations() { static std::set<glConst> const kSupportedTypes = { gl_const::GLFloatType, gl_const::GLFloatVec2, gl_const::GLFloatVec3, gl_const::GLFloatVec4, @@ -118,7 +116,7 @@ void GpuProgram::LoadUniformLocations() m_textureSlotsCount = static_cast<uint8_t>(m_uniforms.size() - m_numericUniformsCount); } -uint32_t GpuProgram::CalculateNumericUniformsCount() const +uint32_t GLGpuProgram::CalculateNumericUniformsCount() const { uint32_t counter = 0; for (auto const & u : m_uniforms) diff --git a/drape/gl_gpu_program.hpp b/drape/gl_gpu_program.hpp new file mode 100644 index 0000000000..d446a3fb13 --- /dev/null +++ b/drape/gl_gpu_program.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "drape/gl_constants.hpp" +#include "drape/gpu_program.hpp" +#include "drape/pointers.hpp" +#include "drape/shader.hpp" + +#include <map> +#include <string> +#include <vector> + +namespace dp +{ +class GLGpuProgram : public GpuProgram +{ +public: + GLGpuProgram(std::string const & programName, + ref_ptr<Shader> vertexShader, ref_ptr<Shader> fragmentShader); + ~GLGpuProgram() override; + + void Bind() override; + void Unbind() override; + + int8_t GetAttributeLocation(std::string const & attributeName) const; + int8_t GetUniformLocation(std::string const & uniformName) const; + glConst GetUniformType(std::string const & uniformName) const; + + struct UniformInfo + { + int8_t m_location = -1; + glConst m_type = gl_const::GLFloatType; + }; + + using UniformsInfo = std::map<std::string, UniformInfo>; + UniformsInfo const & GetUniformsInfo() const; + uint32_t GetNumericUniformsCount() const { return m_numericUniformsCount; } + +private: + void LoadUniformLocations(); + uint32_t CalculateNumericUniformsCount() const; + + uint32_t m_programID; + + ref_ptr<Shader> m_vertexShader; + ref_ptr<Shader> m_fragmentShader; + + UniformsInfo m_uniforms; + uint8_t m_textureSlotsCount = 0; + uint32_t m_numericUniformsCount = 0; +}; +} // namespace dp diff --git a/drape/glIncludes.hpp b/drape/gl_includes.hpp index f407dacf4e..f407dacf4e 100644 --- a/drape/glIncludes.hpp +++ b/drape/gl_includes.hpp diff --git a/drape/gpu_buffer.cpp b/drape/gpu_buffer.cpp index 7b2f3556f3..f85bf6b62d 100644 --- a/drape/gpu_buffer.cpp +++ b/drape/gpu_buffer.cpp @@ -1,7 +1,7 @@ #include "drape/gpu_buffer.hpp" #include "drape/drape_diagnostics.hpp" -#include "drape/glextensions_list.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_extensions_list.hpp" +#include "drape/gl_functions.hpp" #include "drape/utils/gpu_mem_tracker.hpp" #include "base/assert.hpp" diff --git a/drape/gpu_program.hpp b/drape/gpu_program.hpp index 5ae0186568..475957549e 100644 --- a/drape/gpu_program.hpp +++ b/drape/gpu_program.hpp @@ -1,54 +1,24 @@ #pragma once -#include "drape/glconstants.hpp" -#include "drape/pointers.hpp" -#include "drape/shader.hpp" - -#include <map> #include <string> -#include <vector> namespace dp { class GpuProgram { public: - GpuProgram(std::string const & programName, - ref_ptr<Shader> vertexShader, ref_ptr<Shader> fragmentShader); - ~GpuProgram(); - - std::string const & GetName() const { return m_programName; } - - void Bind(); - void Unbind(); - - int8_t GetAttributeLocation(std::string const & attributeName) const; - int8_t GetUniformLocation(std::string const & uniformName) const; - glConst GetUniformType(std::string const & uniformName) const; + explicit GpuProgram(std::string const & programName) + : m_programName(programName) + {} - struct UniformInfo - { - int8_t m_location = -1; - glConst m_type = gl_const::GLFloatType; - }; + virtual ~GpuProgram() = default; - using UniformsInfo = std::map<std::string, UniformInfo>; - UniformsInfo const & GetUniformsInfo() const; - uint32_t GetNumericUniformsCount() const { return m_numericUniformsCount; } + std::string const & GetName() const { return m_programName; } -private: - void LoadUniformLocations(); - uint32_t CalculateNumericUniformsCount() const; + virtual void Bind() = 0; + virtual void Unbind() = 0; +protected: std::string const m_programName; - - uint32_t m_programID; - - ref_ptr<Shader> m_vertexShader; - ref_ptr<Shader> m_fragmentShader; - - UniformsInfo m_uniforms; - uint8_t m_textureSlotsCount = 0; - uint32_t m_numericUniformsCount = 0; }; } // namespace dp diff --git a/drape/graphics_context.hpp b/drape/graphics_context.hpp index a8412afe89..c87d9261b5 100644 --- a/drape/graphics_context.hpp +++ b/drape/graphics_context.hpp @@ -1,6 +1,9 @@ #pragma once #include "drape/drape_global.hpp" +#include "drape/pointers.hpp" + +#include <string> namespace dp { @@ -13,7 +16,7 @@ enum ClearBits: uint32_t enum class TestFunction : uint8_t { - Never, + Never = 0, Less, Equal, LessOrEqual, @@ -25,14 +28,14 @@ enum class TestFunction : uint8_t enum class StencilFace : uint8_t { - Front, + Front = 0, Back, FrontAndBack }; enum class StencilAction : uint8_t { - Keep, + Keep = 0, Zero, Replace, Increment, @@ -49,24 +52,29 @@ public: virtual void Present() = 0; virtual void MakeCurrent() = 0; virtual void DoneCurrent() {} - virtual void SetDefaultFramebuffer() = 0; + // The value 'nullptr' means default(system) framebuffer. + virtual void SetFramebuffer(ref_ptr<BaseFramebuffer> framebuffer) = 0; + virtual void ApplyFramebuffer(std::string const & framebufferLabel) = 0; // w, h - pixel size of render target (logical size * visual scale). - virtual void Resize(int /*w*/, int /*h*/) {} - virtual void SetRenderingEnabled(bool /*enabled*/) {} - virtual void SetPresentAvailable(bool /*available*/) {} + virtual void Resize(int /* w */, int /* h */) {} + virtual void SetRenderingEnabled(bool /* enabled */) {} + virtual void SetPresentAvailable(bool /* available */) {} virtual bool Validate() { return true; } virtual void Init(ApiVersion apiVersion) = 0; + virtual ApiVersion GetApiVersion() const = 0; + virtual std::string GetRendererName() const = 0; + virtual std::string GetRendererVersion() const = 0; + virtual void SetClearColor(Color const & color) = 0; virtual void Clear(uint32_t clearBits) = 0; virtual void Flush() = 0; + virtual void SetViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) = 0; virtual void SetDepthTestEnabled(bool enabled) = 0; virtual void SetDepthTestFunction(TestFunction depthFunction) = 0; virtual void SetStencilTestEnabled(bool enabled) = 0; virtual void SetStencilFunction(StencilFace face, TestFunction stencilFunction) = 0; - virtual void SetStencilActions(StencilFace face, StencilAction stencilFailAction, StencilAction depthFailAction, - StencilAction passAction) = 0; - - + virtual void SetStencilActions(StencilFace face, StencilAction stencilFailAction, + StencilAction depthFailAction, StencilAction passAction) = 0; }; } // namespace dp diff --git a/drape/graphics_context_factory.cpp b/drape/graphics_context_factory.cpp index d2d8b50d09..d3bc5728bc 100644 --- a/drape/graphics_context_factory.cpp +++ b/drape/graphics_context_factory.cpp @@ -26,7 +26,7 @@ GraphicsContext * ThreadSafeFactory::GetResourcesUploadContext() GraphicsContext * ThreadSafeFactory::CreateContext(TCreateCtxFn const & createFn, TIsSeparateCreatedFn const checkFn) { - threads::ConditionGuard g(m_contidion); + threads::ConditionGuard g(m_condition); GraphicsContext * ctx = createFn(); if (m_enableSharing) { diff --git a/drape/graphics_context_factory.hpp b/drape/graphics_context_factory.hpp index 8a057a9f22..423beff117 100644 --- a/drape/graphics_context_factory.hpp +++ b/drape/graphics_context_factory.hpp @@ -12,7 +12,7 @@ namespace dp class GraphicsContextFactory { public: - virtual ~GraphicsContextFactory() {} + virtual ~GraphicsContextFactory() = default; virtual GraphicsContext * GetDrawContext() = 0; virtual GraphicsContext * GetResourcesUploadContext() = 0; virtual bool IsDrawContextCreated() const { return false; } @@ -46,7 +46,7 @@ protected: private: GraphicsContextFactory * m_factory; - threads::Condition m_contidion; + threads::Condition m_condition; bool m_enableSharing; }; } // namespace dp diff --git a/drape/hw_texture.cpp b/drape/hw_texture.cpp index 7e168258e4..e7295a74be 100644 --- a/drape/hw_texture.cpp +++ b/drape/hw_texture.cpp @@ -1,7 +1,7 @@ #include "drape/hw_texture.hpp" -#include "drape/glextensions_list.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_extensions_list.hpp" +#include "drape/gl_functions.hpp" #include "drape/utils/gpu_mem_tracker.hpp" #include "platform/platform.hpp" @@ -11,14 +11,18 @@ #if defined(OMIM_OS_IPHONE) #include "drape/hw_texture_ios.hpp" -#endif -#define ASSERT_ID ASSERT(GetID() != 0, ()) +extern drape_ptr<dp::HWTextureAllocator> CreateMetalAllocator(); +extern ref_ptr<dp::HWTextureAllocator> GetDefaultMetalAllocator(); +#endif namespace dp { void UnpackFormat(TextureFormat format, glConst & layout, glConst & pixelType) { + auto const apiVersion = GLFunctions::CurrentApiVersion; + CHECK(apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3, ()); + switch (format) { case TextureFormat::RGBA8: @@ -28,21 +32,19 @@ void UnpackFormat(TextureFormat format, glConst & layout, glConst & pixelType) case TextureFormat::Alpha: // On OpenGL ES3 GLAlpha is not supported, we use GLRed instead. - layout = GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES2 ? gl_const::GLAlpha - : gl_const::GLRed; + layout = apiVersion == dp::ApiVersion::OpenGLES2 ? gl_const::GLAlpha : gl_const::GLRed; pixelType = gl_const::GL8BitOnChannel; return; case TextureFormat::RedGreen: // On OpenGL ES2 2-channel textures are not supported. - layout = GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES2 ? gl_const::GLRGBA - : gl_const::GLRedGreen; + layout = (apiVersion == dp::ApiVersion::OpenGLES2) ? gl_const::GLRGBA : gl_const::GLRedGreen; pixelType = gl_const::GL8BitOnChannel; return; case TextureFormat::DepthStencil: // OpenGLES2 does not support texture-based depth-stencil. - CHECK(GLFunctions::CurrentApiVersion != dp::ApiVersion::OpenGLES2, ()); + CHECK(apiVersion != dp::ApiVersion::OpenGLES2, ()); layout = gl_const::GLDepthStencil; pixelType = gl_const::GLUnsignedInt24_8Type; return; @@ -61,6 +63,9 @@ void UnpackFormat(TextureFormat format, glConst & layout, glConst & pixelType) 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; @@ -71,6 +76,9 @@ 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; @@ -87,26 +95,29 @@ HWTexture::~HWTexture() #endif } -void HWTexture::Create(Params const & params) { Create(params, nullptr); } +void HWTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params) +{ + Create(std::move(context), params, nullptr); +} -void HWTexture::Create(Params const & params, ref_ptr<void> /* data */) +void HWTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params, + ref_ptr<void> /* data */) { - m_width = params.m_width; - m_height = params.m_height; - m_format = params.m_format; - m_filter = params.m_filter; + m_params = params; - uint32_t const bytesPerPixel = GetBytesPerPixel(m_format); - if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3 && params.m_usePixelBuffer && + // OpenGL ES 2.0 does not support PBO, Metal has no necessity in it. + uint32_t const bytesPerPixel = GetBytesPerPixel(m_params.m_format); + if (context && context->GetApiVersion() == dp::ApiVersion::OpenGLES3 && params.m_usePixelBuffer && bytesPerPixel > 0) { float const kPboPercent = 0.1f; m_pixelBufferElementSize = bytesPerPixel; - m_pixelBufferSize = static_cast<uint32_t>(kPboPercent * m_width * m_height * bytesPerPixel); + m_pixelBufferSize = + static_cast<uint32_t>(kPboPercent * m_params.m_width * m_params.m_height * bytesPerPixel); } #if defined(TRACK_GPU_MEM) - uint32_t const memSize = (CHAR_BIT * bytesPerPixel * m_width * m_height) >> 3; + uint32_t const memSize = (CHAR_BIT * bytesPerPixel * m_params.m_width * m_params.m_height) >> 3; dp::GPUMemTracker::Inst().AddAllocated("Texture", m_textureID, memSize); dp::GPUMemTracker::Inst().SetUsed("Texture", m_textureID, memSize); if (params.m_usePixelBuffer) @@ -117,48 +128,30 @@ void HWTexture::Create(Params const & params, ref_ptr<void> /* data */) #endif } -TextureFormat HWTexture::GetFormat() const { return m_format; } +TextureFormat HWTexture::GetFormat() const { return m_params.m_format; } uint32_t HWTexture::GetWidth() const { - ASSERT_ID; - return m_width; + ASSERT(Validate(), ()); + return m_params.m_width; } uint32_t HWTexture::GetHeight() const { - ASSERT_ID; - return m_height; + ASSERT(Validate(), ()); + return m_params.m_height; } float HWTexture::GetS(uint32_t x) const { - ASSERT_ID; - return x / static_cast<float>(m_width); + ASSERT(Validate(), ()); + return x / static_cast<float>(m_params.m_width); } float HWTexture::GetT(uint32_t y) const { - ASSERT_ID; - return y / static_cast<float>(m_height); -} - -void HWTexture::Bind() const -{ - ASSERT_ID; - if (m_textureID != 0) - GLFunctions::glBindTexture(GetID()); -} - -void HWTexture::SetFilter(TextureFilter filter) -{ - if (m_filter != filter) - { - m_filter = filter; - auto const f = DecodeTextureFilter(m_filter); - GLFunctions::glTexParameter(gl_const::GLMinFilter, f); - GLFunctions::glTexParameter(gl_const::GLMagFilter, f); - } + ASSERT(Validate(), ()); + return y / static_cast<float>(m_params.m_height); } uint32_t HWTexture::GetID() const { return m_textureID; } @@ -172,23 +165,24 @@ OpenGLHWTexture::~OpenGLHWTexture() GLFunctions::glDeleteBuffer(m_pixelBufferID); } -void OpenGLHWTexture::Create(Params const & params, ref_ptr<void> data) +void OpenGLHWTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params, + ref_ptr<void> data) { - Base::Create(params, data); + Base::Create(std::move(context), params, data); m_textureID = GLFunctions::glGenTexture(); Bind(); glConst layout; glConst pixelType; - UnpackFormat(m_format, layout, pixelType); + UnpackFormat(m_params.m_format, layout, pixelType); - auto const f = DecodeTextureFilter(m_filter); - GLFunctions::glTexImage2D(m_width, m_height, layout, pixelType, data.get()); + auto const f = DecodeTextureFilter(m_params.m_filter); + GLFunctions::glTexImage2D(m_params.m_width, m_params.m_height, layout, pixelType, data.get()); GLFunctions::glTexParameter(gl_const::GLMinFilter, f); GLFunctions::glTexParameter(gl_const::GLMagFilter, f); - GLFunctions::glTexParameter(gl_const::GLWrapS, DecodeTextureWrapping(params.m_wrapSMode)); - GLFunctions::glTexParameter(gl_const::GLWrapT, DecodeTextureWrapping(params.m_wrapTMode)); + GLFunctions::glTexParameter(gl_const::GLWrapS, DecodeTextureWrapping(m_params.m_wrapSMode)); + GLFunctions::glTexParameter(gl_const::GLWrapT, DecodeTextureWrapping(m_params.m_wrapTMode)); if (m_pixelBufferSize > 0) { @@ -206,10 +200,10 @@ void OpenGLHWTexture::Create(Params const & params, 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; + ASSERT(Validate(), ()); glConst layout; glConst pixelType; - UnpackFormat(m_format, layout, 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) @@ -226,8 +220,33 @@ void OpenGLHWTexture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_ } } -drape_ptr<HWTexture> OpenGLHWTextureAllocator::CreateTexture() +void OpenGLHWTexture::Bind() const +{ + ASSERT(Validate(), ()); + if (m_textureID != 0) + GLFunctions::glBindTexture(GetID()); +} + +void OpenGLHWTexture::SetFilter(TextureFilter filter) { + ASSERT(Validate(), ()); + if (m_params.m_filter != filter) + { + m_params.m_filter = filter; + auto const f = DecodeTextureFilter(m_params.m_filter); + GLFunctions::glTexParameter(gl_const::GLMinFilter, f); + GLFunctions::glTexParameter(gl_const::GLMagFilter, f); + } +} + +bool OpenGLHWTexture::Validate() const +{ + return GetID() != 0; +} + +drape_ptr<HWTexture> OpenGLHWTextureAllocator::CreateTexture(ref_ptr<dp::GraphicsContext> context) +{ + UNUSED_VALUE(context); return make_unique_dp<OpenGLHWTexture>(); } @@ -236,12 +255,25 @@ void OpenGLHWTextureAllocator::Flush() GLFunctions::glFlush(); } -drape_ptr<HWTextureAllocator> CreateAllocator() +drape_ptr<HWTextureAllocator> CreateAllocator(ref_ptr<dp::GraphicsContext> context) { - if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3) - { + // Context can be nullptr in unit tests. + if (!context) return make_unique_dp<OpenGLHWTextureAllocator>(); + + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::Metal) + { +#if defined(OMIM_OS_IPHONE) + return CreateMetalAllocator(); +#endif + CHECK(false, ("Metal rendering is supported now only on iOS.")); + return nullptr; } + + if (apiVersion == dp::ApiVersion::OpenGLES3) + return make_unique_dp<OpenGLHWTextureAllocator>(); + #if defined(OMIM_OS_IPHONE) && !defined(OMIM_OS_IPHONE_SIMULATOR) return make_unique_dp<HWTextureAllocatorApple>(); #else @@ -249,8 +281,18 @@ drape_ptr<HWTextureAllocator> CreateAllocator() #endif } -ref_ptr<HWTextureAllocator> GetDefaultAllocator() +ref_ptr<HWTextureAllocator> GetDefaultAllocator(ref_ptr<dp::GraphicsContext> context) { + // Context can be nullptr in unit tests. + if (context && context->GetApiVersion() == dp::ApiVersion::Metal) + { +#if defined(OMIM_OS_IPHONE) + return GetDefaultMetalAllocator(); +#endif + CHECK(false, ("Metal rendering is supported now only on iOS.")); + return nullptr; + } + static OpenGLHWTextureAllocator s_allocator; return make_ref<HWTextureAllocator>(&s_allocator); } diff --git a/drape/hw_texture.hpp b/drape/hw_texture.hpp index 0226e3b7d5..c7ccb2303b 100644 --- a/drape/hw_texture.hpp +++ b/drape/hw_texture.hpp @@ -1,6 +1,7 @@ #pragma once -#include "drape/glconstants.hpp" +#include "drape/gl_constants.hpp" +#include "drape/graphics_context.hpp" #include "drape/pointers.hpp" #include "drape/texture_types.hpp" @@ -24,19 +25,25 @@ public: TextureWrapping m_wrapTMode = TextureWrapping::ClampToEdge; TextureFormat m_format = TextureFormat::Unspecified; bool m_usePixelBuffer = false; + bool m_isRenderTarget = false; + bool m_isMutable = false; ref_ptr<HWTextureAllocator> m_allocator; }; - void Create(Params const & params); - virtual void Create(Params const & params, ref_ptr<void> data) = 0; + void Create(ref_ptr<dp::GraphicsContext> context, Params const & params); + + virtual void Create(ref_ptr<dp::GraphicsContext> context, Params const & params, + ref_ptr<void> data) = 0; virtual void UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data) = 0; - void Bind() const; + virtual void Bind() const = 0; + + // For OpenGL the texture must be bound before calling this method. + virtual void SetFilter(TextureFilter filter) = 0; - // Texture must be bound before calling this method. - void SetFilter(TextureFilter filter); + virtual bool Validate() const = 0; TextureFormat GetFormat() const; uint32_t GetWidth() const; @@ -47,11 +54,8 @@ public: uint32_t GetID() const; protected: - uint32_t m_width = 0; - uint32_t m_height = 0; - TextureFormat m_format = TextureFormat::Unspecified; + Params m_params; uint32_t m_textureID = 0; - TextureFilter m_filter = TextureFilter::Linear; uint32_t m_pixelBufferID = 0; uint32_t m_pixelBufferSize = 0; uint32_t m_pixelBufferElementSize = 0; @@ -62,7 +66,7 @@ class HWTextureAllocator public: virtual ~HWTextureAllocator() = default; - virtual drape_ptr<HWTexture> CreateTexture() = 0; + virtual drape_ptr<HWTexture> CreateTexture(ref_ptr<dp::GraphicsContext> context) = 0; virtual void Flush() = 0; }; @@ -72,20 +76,24 @@ class OpenGLHWTexture : public HWTexture public: ~OpenGLHWTexture() override; - void Create(Params const & params, ref_ptr<void> data) override; + void Create(ref_ptr<dp::GraphicsContext> context, Params const & params, + ref_ptr<void> data) override; void UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data) override; + void Bind() const override; + void SetFilter(TextureFilter filter) override; + bool Validate() const override; }; class OpenGLHWTextureAllocator : public HWTextureAllocator { public: - drape_ptr<HWTexture> CreateTexture() override; + drape_ptr<HWTexture> CreateTexture(ref_ptr<dp::GraphicsContext> context) override; void Flush() override; }; -ref_ptr<HWTextureAllocator> GetDefaultAllocator(); -drape_ptr<HWTextureAllocator> CreateAllocator(); +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); glConst DecodeTextureFilter(TextureFilter filter); diff --git a/drape/hw_texture_ios.hpp b/drape/hw_texture_ios.hpp index fc714d3c67..2825d8599e 100644 --- a/drape/hw_texture_ios.hpp +++ b/drape/hw_texture_ios.hpp @@ -1,6 +1,6 @@ #pragma once -#include "drape/glconstants.hpp" +#include "drape/gl_constants.hpp" #include "drape/hw_texture.hpp" #ifndef OMIM_OS_IPHONE @@ -28,7 +28,7 @@ public: void RiseFlushFlag(); - drape_ptr<HWTexture> CreateTexture() override; + drape_ptr<HWTexture> CreateTexture(ref_ptr<dp::GraphicsContext> context) override; void Flush() override; private: @@ -41,12 +41,15 @@ class HWTextureApple : public HWTexture using TBase = HWTexture; public: - HWTextureApple(ref_ptr<HWTextureAllocatorApple> allocator); + explicit HWTextureApple(ref_ptr<HWTextureAllocatorApple> allocator); ~HWTextureApple(); - void Create(Params const & params, ref_ptr<void> data); - void UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data); - + void Create(ref_ptr<dp::GraphicsContext> context, Params const & params, ref_ptr<void> data) override; + void UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data) override; + void Bind() const override; + void SetFilter(TextureFilter filter) override; + bool Validate() const override; + private: void Lock(); void Unlock(); diff --git a/drape/hw_texture_ios.mm b/drape/hw_texture_ios.mm index 9f7a9f3cc1..914cc31348 100644 --- a/drape/hw_texture_ios.mm +++ b/drape/hw_texture_ios.mm @@ -1,6 +1,6 @@ #include "drape/hw_texture_ios.hpp" -#include "drape/glfunctions.hpp" -#include "drape/glIncludes.hpp" +#include "drape/gl_functions.hpp" +#include "drape/gl_includes.hpp" #include "base/logging.hpp" @@ -111,8 +111,9 @@ void HWTextureAllocatorApple::RiseFlushFlag() m_needFlush = true; } -drape_ptr<HWTexture> HWTextureAllocatorApple::CreateTexture() +drape_ptr<HWTexture> HWTextureAllocatorApple::CreateTexture(ref_ptr<dp::GraphicsContext> context) { + UNUSED_VALUE(context); return make_unique_dp<HWTextureApple>(make_ref<HWTextureAllocatorApple>(this)); } @@ -142,12 +143,12 @@ HWTextureApple::~HWTextureApple() } } -void HWTextureApple::Create(Params const & params, ref_ptr<void> data) +void HWTextureApple::Create(ref_ptr<dp::GraphicsContext> context, Params const & params, ref_ptr<void> data) { - TBase::Create(params, data); + TBase::Create(context, params, data); - m_allocator = params.m_allocator.downcast<HWTextureAllocatorApple>(); - m_directBuffer = m_allocator->CVCreatePixelBuffer(params.m_width, params.m_height, params.m_format); + m_allocator = m_params.m_allocator.downcast<HWTextureAllocatorApple>(); + 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); @@ -156,17 +157,17 @@ void HWTextureApple::Create(Params const & params, ref_ptr<void> data) m_textureID = CVOpenGLESTextureGetName(m_texture); GLFunctions::glBindTexture(m_textureID); - auto const f = DecodeTextureFilter(params.m_filter); + auto const f = DecodeTextureFilter(m_params.m_filter); GLFunctions::glTexParameter(gl_const::GLMinFilter, f); GLFunctions::glTexParameter(gl_const::GLMagFilter, f); - GLFunctions::glTexParameter(gl_const::GLWrapS, DecodeTextureWrapping(params.m_wrapSMode)); - GLFunctions::glTexParameter(gl_const::GLWrapT, DecodeTextureWrapping(params.m_wrapTMode)); + GLFunctions::glTexParameter(gl_const::GLWrapS, DecodeTextureWrapping(m_params.m_wrapSMode)); + GLFunctions::glTexParameter(gl_const::GLWrapT, DecodeTextureWrapping(m_params.m_wrapTMode)); if (data == nullptr) return; Lock(); - memcpy(m_directPointer, data.get(), m_width * m_height * GetBytesPerPixel(m_format)); + memcpy(m_directPointer, data.get(), m_params.m_width * m_params.m_height * GetBytesPerPixel(m_params.m_format)); Unlock(); } @@ -177,7 +178,8 @@ void HWTextureApple::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t if (bytesPerPixel == 1) { gray8c_view_t srcView = interleaved_view(width, height, (gray8c_pixel_t *)data.get(), width); - gray8_view_t dstView = interleaved_view(m_width, m_height, (gray8_pixel_t *)m_directPointer, m_width); + gray8_view_t dstView = interleaved_view(m_params.m_width, m_params.m_height, + (gray8_pixel_t *)m_directPointer, m_params.m_width); gray8_view_t subDstView = subimage_view(dstView, x, y, width, height); copy_pixels(srcView, subDstView); } @@ -186,22 +188,47 @@ void HWTextureApple::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t rgba8c_view_t srcView = interleaved_view(width, height, (rgba8c_pixel_t *)data.get(), width * bytesPerPixel); - rgba8_view_t dstView = interleaved_view(m_width, m_height, + rgba8_view_t dstView = interleaved_view(m_params.m_width, m_params.m_height, (rgba8_pixel_t *)m_directPointer, - m_width * bytesPerPixel); + m_params.m_width * bytesPerPixel); rgba8_view_t subDstView = subimage_view(dstView, x, y, width, height); copy_pixels(srcView, subDstView); } Unlock(); } +void HWTextureApple::Bind() const +{ + ASSERT(Validate(), ()); + if (m_textureID != 0) + GLFunctions::glBindTexture(GetID()); +} + +void HWTextureApple::SetFilter(TextureFilter filter) +{ + ASSERT(Validate(), ()); + if (m_params.m_filter != filter) + { + m_params.m_filter = filter; + auto const f = DecodeTextureFilter(m_params.m_filter); + GLFunctions::glTexParameter(gl_const::GLMinFilter, f); + GLFunctions::glTexParameter(gl_const::GLMagFilter, f); + } +} + +bool HWTextureApple::Validate() const +{ + return GetID() != 0; +} + void HWTextureApple::Lock() { ASSERT(m_directPointer == nullptr, ()); CHECK_EQUAL(CVPixelBufferLockBaseAddress(m_directBuffer, 0), kCVReturnSuccess, ()); - ASSERT_EQUAL(CVPixelBufferGetBytesPerRow(m_directBuffer), m_width * GetBytesPerPixel(m_format), ()); + ASSERT_EQUAL(CVPixelBufferGetBytesPerRow(m_directBuffer), + m_params.m_width * GetBytesPerPixel(m_params.m_format), ()); m_directPointer = CVPixelBufferGetBaseAddress(m_directBuffer); } diff --git a/drape/index_buffer_mutator.cpp b/drape/index_buffer_mutator.cpp index 4a0da796ad..cc9e8e0ccb 100644 --- a/drape/index_buffer_mutator.cpp +++ b/drape/index_buffer_mutator.cpp @@ -1,14 +1,12 @@ #include "drape/index_buffer_mutator.hpp" #include "drape/vertex_array_buffer.hpp" -#include "std/cstring.hpp" // for memcpy -#include "std/algorithm.hpp" // for max +#include <algorithm> +#include <cstring> namespace dp { - IndexBufferMutator::IndexBufferMutator(uint32_t baseSize) - : m_activeSize(0) { m_buffer.Resize(baseSize); } @@ -17,7 +15,7 @@ void IndexBufferMutator::AppendIndexes(void const * indexes, uint32_t count) { uint32_t dstActiveSize = m_activeSize + count; if (dstActiveSize > m_buffer.Size()) - m_buffer.Resize(max(m_buffer.Size() * 2, dstActiveSize)); + m_buffer.Resize(std::max(m_buffer.Size() * 2, dstActiveSize)); memcpy(m_buffer.GetRaw(m_activeSize), indexes, count * IndexStorage::SizeOfIndex()); m_activeSize = dstActiveSize; @@ -37,5 +35,4 @@ uint32_t IndexBufferMutator::GetCapacity() const { return m_buffer.Size(); } - -} // namespace dp +} // namespace dp diff --git a/drape/index_buffer_mutator.hpp b/drape/index_buffer_mutator.hpp index 9a63a44f45..160791baf0 100644 --- a/drape/index_buffer_mutator.hpp +++ b/drape/index_buffer_mutator.hpp @@ -3,17 +3,16 @@ #include "drape/index_storage.hpp" #include "drape/pointers.hpp" -#include "std/cstdint.hpp" +#include <cstdint> namespace dp { - class VertexArrayBuffer; class IndexBufferMutator { public: - IndexBufferMutator(uint32_t baseSize); + explicit IndexBufferMutator(uint32_t baseSize); void AppendIndexes(void const * indexes, uint32_t count); @@ -26,7 +25,6 @@ private: private: IndexStorage m_buffer; - uint32_t m_activeSize; + uint32_t m_activeSize = 0; }; - -} // namespace dp +} // namespace dp diff --git a/drape/index_storage.cpp b/drape/index_storage.cpp index 6a217ff7b4..2bc08259de 100644 --- a/drape/index_storage.cpp +++ b/drape/index_storage.cpp @@ -1,5 +1,5 @@ #include "drape/index_storage.hpp" -#include "drape/glextensions_list.hpp" +#include "drape/gl_extensions_list.hpp" #include "std/utility.hpp" diff --git a/drape/mesh_object.cpp b/drape/mesh_object.cpp index 236b5cae6f..0ce9c267fe 100644 --- a/drape/mesh_object.cpp +++ b/drape/mesh_object.cpp @@ -1,8 +1,9 @@ #include "drape/mesh_object.hpp" -#include "drape/glconstants.hpp" -#include "drape/glextensions_list.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_constants.hpp" +#include "drape/gl_gpu_program.hpp" +#include "drape/gl_extensions_list.hpp" +#include "drape/gl_functions.hpp" #include "drape/glsl_func.hpp" #include "drape/glsl_types.hpp" #include "drape/gpu_program.hpp" @@ -23,15 +24,154 @@ glConst GetGLDrawPrimitive(dp::MeshObject::DrawPrimitive drawPrimitive) namespace dp { -MeshObject::MeshObject(DrawPrimitive drawPrimitive) +class GLMeshObjectImpl : public MeshObjectImpl +{ +public: + explicit GLMeshObjectImpl(ref_ptr<dp::MeshObject> mesh) + : m_mesh(std::move(mesh)) + {} + + void Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program) override + { + UNUSED_VALUE(context); + + bool const isVAOSupported = + dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject); + if (isVAOSupported) + { + m_VAO = GLFunctions::glGenVertexArray(); + GLFunctions::glBindVertexArray(m_VAO); + } + + for (auto & buffer : m_mesh->m_buffers) + { + buffer.m_bufferId = GLFunctions::glGenBuffer(); + GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); + + if (!buffer.m_data.empty()) + { + GLFunctions::glBufferData(gl_const::GLArrayBuffer, + static_cast<uint32_t>(buffer.m_data.size()) * sizeof(buffer.m_data[0]), + buffer.m_data.data(), gl_const::GLStaticDraw); + } + + if (isVAOSupported) + { + ref_ptr<dp::GLGpuProgram> p = program; + for (auto const & attribute : buffer.m_attributes) + { + int8_t const attributePosition = p->GetAttributeLocation(attribute.m_attributeName); + ASSERT_NOT_EQUAL(attributePosition, -1, ()); + GLFunctions::glEnableVertexAttribute(attributePosition); + GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount, + gl_const::GLFloatType, false, + buffer.m_stride, attribute.m_offset); + } + } + } + + if (isVAOSupported) + GLFunctions::glBindVertexArray(0); + GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); + } + + void Reset() override + { + for (auto & buffer : m_mesh->m_buffers) + { + if (buffer.m_bufferId != 0) + { + GLFunctions::glDeleteBuffer(buffer.m_bufferId); + buffer.m_bufferId = 0; + } + } + + if (m_VAO != 0) + GLFunctions::glDeleteVertexArray(m_VAO); + + m_VAO = 0; + } + + void UpdateBuffer(uint32_t bufferInd) override + { + auto & buffer = m_mesh->m_buffers[bufferInd]; + GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); + GLFunctions::glBufferData(gl_const::GLArrayBuffer, + static_cast<uint32_t>(buffer.m_data.size()) * sizeof(buffer.m_data[0]), + buffer.m_data.data(), gl_const::GLStaticDraw); + GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); + } + + void Bind(ref_ptr<dp::GpuProgram> program) override + { + if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) + { + GLFunctions::glBindVertexArray(m_VAO); + return; + } + + ref_ptr<dp::GLGpuProgram> p = program; + for (auto const & buffer : m_mesh->m_buffers) + { + GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); + for (auto const & attribute : buffer.m_attributes) + { + int8_t const attributePosition = p->GetAttributeLocation(attribute.m_attributeName); + ASSERT_NOT_EQUAL(attributePosition, -1, ()); + GLFunctions::glEnableVertexAttribute(attributePosition); + GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount, + gl_const::GLFloatType, false, + buffer.m_stride, attribute.m_offset); + } + } + } + + void Unbind(ref_ptr<dp::GpuProgram> program) override + { + if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) + GLFunctions::glBindVertexArray(0); + GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); + } + + void DrawPrimitives(ref_ptr<dp::GraphicsContext> context, uint32_t verticesCount) override + { + UNUSED_VALUE(context); + + GLFunctions::glDrawArrays(GetGLDrawPrimitive(m_mesh->m_drawPrimitive), 0, verticesCount); + } + +private: + ref_ptr<dp::MeshObject> m_mesh; + uint32_t m_VAO = 0; +}; + +MeshObject::MeshObject(ref_ptr<dp::GraphicsContext> context, DrawPrimitive drawPrimitive) : m_drawPrimitive(drawPrimitive) -{} +{ + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) + { + InitForOpenGL(); + } + else if (apiVersion == dp::ApiVersion::Metal) + { +#if defined(OMIM_OS_IPHONE) + InitForMetal(); +#endif + } + CHECK(m_impl != nullptr, ()); +} MeshObject::~MeshObject() { Reset(); } +void MeshObject::InitForOpenGL() +{ + m_impl = make_unique_dp<GLMeshObjectImpl>(make_ref(this)); +} + void MeshObject::SetBuffer(uint32_t bufferInd, std::vector<float> && vertices, uint32_t stride) { CHECK_LESS_OR_EQUAL(bufferInd, GetNextBufferIndex(), ()); @@ -55,19 +195,9 @@ void MeshObject::SetAttribute(std::string const & attributeName, uint32_t buffer void MeshObject::Reset() { - for (auto & buffer : m_buffers) - { - if (buffer.m_bufferId != 0) - { - GLFunctions::glDeleteBuffer(buffer.m_bufferId); - buffer.m_bufferId = 0; - } - } + CHECK(m_impl != nullptr, ()); + m_impl->Reset(); - if (m_VAO != 0) - GLFunctions::glDeleteVertexArray(m_VAO); - - m_VAO = 0; m_initialized = false; } @@ -80,109 +210,63 @@ void MeshObject::UpdateBuffer(uint32_t bufferInd, std::vector<float> && vertices auto & buffer = m_buffers[bufferInd]; buffer.m_data = std::move(vertices); - GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); - GLFunctions::glBufferData(gl_const::GLArrayBuffer, - static_cast<uint32_t>(buffer.m_data.size()) * sizeof(buffer.m_data[0]), - buffer.m_data.data(), gl_const::GLStaticDraw); - GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); + + CHECK(m_impl != nullptr, ()); + m_impl->UpdateBuffer(bufferInd); } -void MeshObject::Build(ref_ptr<dp::GpuProgram> program) +void MeshObject::Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program) { Reset(); - bool const isVAOSupported = dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject); - if (isVAOSupported) - { - m_VAO = GLFunctions::glGenVertexArray(); - GLFunctions::glBindVertexArray(m_VAO); - } - - for (auto & buffer : m_buffers) - { - buffer.m_bufferId = GLFunctions::glGenBuffer(); - GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); - - if (!buffer.m_data.empty()) - { - GLFunctions::glBufferData(gl_const::GLArrayBuffer, - static_cast<uint32_t>(buffer.m_data.size()) * sizeof(buffer.m_data[0]), - buffer.m_data.data(), gl_const::GLStaticDraw); - } - - if (isVAOSupported) - { - for (auto const & attribute : buffer.m_attributes) - { - int8_t const attributePosition = program->GetAttributeLocation(attribute.m_attributeName); - ASSERT_NOT_EQUAL(attributePosition, -1, ()); - GLFunctions::glEnableVertexAttribute(attributePosition); - GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount, - gl_const::GLFloatType, false, - buffer.m_stride, attribute.m_offset); - } - } - } - - if (isVAOSupported) - GLFunctions::glBindVertexArray(0); - GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); + CHECK(m_impl != nullptr, ()); + m_impl->Build(std::move(context), std::move(program)); m_initialized = true; } -void MeshObject::Bind(ref_ptr<dp::GpuProgram> program) +void MeshObject::Bind(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program) { program->Bind(); if (!m_initialized) - Build(program); + Build(context, program); - if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) - { - GLFunctions::glBindVertexArray(m_VAO); - } - else - { - for (auto const & buffer : m_buffers) - { - GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); - for (auto const & attribute : buffer.m_attributes) - { - int8_t const attributePosition = program->GetAttributeLocation(attribute.m_attributeName); - ASSERT_NOT_EQUAL(attributePosition, -1, ()); - GLFunctions::glEnableVertexAttribute(attributePosition); - GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount, - gl_const::GLFloatType, false, - buffer.m_stride, attribute.m_offset); - } - } - } + CHECK(m_impl != nullptr, ()); + m_impl->Bind(program); } -void MeshObject::DrawPrimitives() +void MeshObject::DrawPrimitives(ref_ptr<dp::GraphicsContext> context) { if (m_buffers.empty()) return; auto const & buffer = m_buffers[0]; - auto const verticesCount = static_cast<uint32_t>(buffer.m_data.size() * sizeof(buffer.m_data[0]) / buffer.m_stride); +#ifdef DEBUG + for (size_t i = 1; i < m_buffers.size(); i++) + { + ASSERT_EQUAL(m_buffers[i].m_data.size() / m_buffers[i].m_stride, + buffer.m_data.size() / buffer.m_stride, ()); + } +#endif + auto const verticesCount = + static_cast<uint32_t>(buffer.m_data.size() * sizeof(buffer.m_data[0]) / buffer.m_stride); - GLFunctions::glDrawArrays(GetGLDrawPrimitive(m_drawPrimitive), 0, verticesCount); + CHECK(m_impl != nullptr, ()); + m_impl->DrawPrimitives(std::move(context), verticesCount); } void MeshObject::Unbind(ref_ptr<dp::GpuProgram> program) { program->Unbind(); - if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) - GLFunctions::glBindVertexArray(0); - GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); + CHECK(m_impl != nullptr, ()); + m_impl->Unbind(program); } // static std::vector<float> MeshObject::GenerateNormalsForTriangles(std::vector<float> const & vertices, - size_t componentsCount) + size_t componentsCount) { auto const trianglesCount = vertices.size() / (3 * componentsCount); std::vector<float> normals; diff --git a/drape/mesh_object.hpp b/drape/mesh_object.hpp index 5d3c14bf5d..d8660ed81f 100644 --- a/drape/mesh_object.hpp +++ b/drape/mesh_object.hpp @@ -1,5 +1,6 @@ #pragma once +#include "drape/graphics_context.hpp" #include "drape/render_state.hpp" #include "drape/pointers.hpp" @@ -11,9 +12,20 @@ namespace dp { class GpuProgram; class GraphicsContext; +class MeshObjectImpl; +namespace metal +{ +class MetalMeshObjectImpl; +} // namespace metal +// This class implement simple mesh object which does not use an index buffer. +// Use this class only for simple geometry. class MeshObject { + friend class MeshObjectImpl; + friend class GLMeshObjectImpl; + friend class metal::MetalMeshObjectImpl; + public: enum class DrawPrimitive: uint8_t { @@ -22,7 +34,7 @@ public: LineStrip }; - MeshObject(DrawPrimitive drawPrimitive); + MeshObject(ref_ptr<dp::GraphicsContext> context, DrawPrimitive drawPrimitive); virtual ~MeshObject(); void SetBuffer(uint32_t bufferInd, std::vector<float> && vertices, uint32_t stride); @@ -30,16 +42,17 @@ public: void UpdateBuffer(uint32_t bufferInd, std::vector<float> && vertices); - template<typename TParamsSetter, typename TParams> - void Render(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program, dp::RenderState const & state, - ref_ptr<TParamsSetter> paramsSetter, TParams const & params) + template <typename TParamsSetter, typename TParams> + void Render(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program, + dp::RenderState const & state, ref_ptr<TParamsSetter> paramsSetter, + TParams const & params) { - Bind(program); + Bind(context, program); ApplyState(context, program, state); paramsSetter->Apply(program, params); - DrawPrimitives(); + DrawPrimitives(context); Unbind(program); }; @@ -47,7 +60,7 @@ public: uint32_t GetNextBufferIndex() const { return static_cast<uint32_t>(m_buffers.size()); } bool IsInitialized() const { return m_initialized; } - void Build(ref_ptr<dp::GpuProgram> program); + void Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program); void Reset(); static std::vector<float> GenerateNormalsForTriangles(std::vector<float> const & vertices, size_t componentsCount); @@ -84,14 +97,30 @@ private: std::vector<AttributeMapping> m_attributes; }; - void Bind(ref_ptr<dp::GpuProgram> program); + void InitForOpenGL(); + // Definition of this method is in separate .mm-file. + void InitForMetal(); + + void Bind(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program); void Unbind(ref_ptr<dp::GpuProgram> program); - void DrawPrimitives(); + void DrawPrimitives(ref_ptr<dp::GraphicsContext> context); std::vector<VertexBuffer> m_buffers; DrawPrimitive m_drawPrimitive = DrawPrimitive::Triangles; - uint32_t m_VAO = 0; + drape_ptr<MeshObjectImpl> m_impl; bool m_initialized = false; }; + +class MeshObjectImpl +{ +public: + virtual ~MeshObjectImpl() = default; + virtual void Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program) = 0; + virtual void Reset() = 0; + virtual void UpdateBuffer(uint32_t bufferInd) = 0; + virtual void Bind(ref_ptr<dp::GpuProgram> program) = 0; + virtual void Unbind(ref_ptr<dp::GpuProgram> program) = 0; + virtual void DrawPrimitives(ref_ptr<dp::GraphicsContext> context, uint32_t verticesCount) = 0; +}; } // namespace dp diff --git a/drape/metal/metal_base_context.hpp b/drape/metal/metal_base_context.hpp new file mode 100644 index 0000000000..ebb7f31650 --- /dev/null +++ b/drape/metal/metal_base_context.hpp @@ -0,0 +1,65 @@ +#pragma once +#import <MetalKit/MetalKit.h> + +#include "drape/graphics_context.hpp" +#include "drape/gpu_program.hpp" +#include "drape/metal/metal_states.hpp" +#include "drape/pointers.hpp" + +#include <cstdint> + +namespace dp +{ +namespace metal +{ +class MetalBaseContext : public dp::GraphicsContext +{ +public: + MetalBaseContext(id<MTLDevice> device, id<MTLTexture> depthStencilTexture); + + void Present() override; + void MakeCurrent() override {} + void DoneCurrent() override {} + void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override; + void ApplyFramebuffer(std::string const & framebufferLabel) override; + void Init(ApiVersion apiVersion) override; + ApiVersion GetApiVersion() const override; + std::string GetRendererName() const override; + std::string GetRendererVersion() const override; + + void SetClearColor(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(TestFunction depthFunction) override; + void SetStencilTestEnabled(bool enabled) override; + void SetStencilFunction(StencilFace face, TestFunction stencilFunction) override; + void SetStencilActions(StencilFace face, StencilAction stencilFailAction, + StencilAction depthFailAction, StencilAction passAction) override; + + id<MTLDevice> GetMetalDevice() const; + id<MTLRenderCommandEncoder> GetCommandEncoder() const; + id<MTLDepthStencilState> GetDepthStencilState(); + id<MTLRenderPipelineState> GetPipelineState(ref_ptr<GpuProgram> program, bool blendingEnabled); + +protected: + void SetFrameDrawable(id<CAMetalDrawable> drawable); + bool HasFrameDrawable() const; + void FinishCurrentEncoding(); + + id<MTLDevice> m_device; + id<MTLTexture> m_depthStencilTexture; + MTLRenderPassDescriptor * m_renderPassDescriptor; + id<MTLCommandQueue> m_commandQueue; + ref_ptr<dp::BaseFramebuffer> m_currentFramebuffer; + MetalStates::DepthStencilKey m_currentDepthStencilKey; + MetalStates m_metalStates; + + // These objects are recreated each frame. They MUST NOT be stored anywhere. + id<CAMetalDrawable> m_frameDrawable; + id<MTLCommandBuffer> m_frameCommandBuffer; + id<MTLRenderCommandEncoder> m_currentCommandEncoder; +}; +} // namespace metal +} // namespace dp diff --git a/drape/metal/metal_base_context.mm b/drape/metal/metal_base_context.mm new file mode 100644 index 0000000000..4fffba9ccd --- /dev/null +++ b/drape/metal/metal_base_context.mm @@ -0,0 +1,272 @@ +#include "drape/metal/metal_base_context.hpp" +#include "drape/metal/metal_gpu_program.hpp" +#include "drape/metal/metal_texture.hpp" + +#include "drape/framebuffer.hpp" + +#include "base/assert.hpp" + +#include <algorithm> +#include <string> +#include <vector> +#include <utility> + +namespace dp +{ +namespace metal +{ +MetalBaseContext::MetalBaseContext(id<MTLDevice> device, id<MTLTexture> depthStencilTexture) + : m_device(device) + , m_depthStencilTexture(depthStencilTexture) +{ + m_renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; + m_renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; + m_renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + m_renderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear; + m_renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionStore; + m_renderPassDescriptor.depthAttachment.clearDepth = 1.0; + m_renderPassDescriptor.stencilAttachment.loadAction = MTLLoadActionClear; + m_renderPassDescriptor.stencilAttachment.storeAction = MTLStoreActionStore; + m_renderPassDescriptor.stencilAttachment.clearStencil = 0; +} + +void MetalBaseContext::Init(dp::ApiVersion apiVersion) +{ + CHECK(apiVersion == dp::ApiVersion::Metal, ()); + m_commandQueue = [m_device newCommandQueue]; +} + +ApiVersion MetalBaseContext::GetApiVersion() const +{ + return dp::ApiVersion::Metal; +} + +std::string MetalBaseContext::GetRendererName() const +{ + return std::string([m_device.name UTF8String]); +} + +std::string MetalBaseContext::GetRendererVersion() const +{ + static std::vector<std::pair<MTLFeatureSet, std::string>> features; + if (features.empty()) + { + features.reserve(12); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily1_v1, "iOS_GPUFamily1_v1"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily2_v1, "iOS_GPUFamily2_v1"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily1_v2, "iOS_GPUFamily1_v2"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily2_v2, "iOS_GPUFamily2_v2"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily3_v1, "iOS_GPUFamily3_v1"); + if (@available(iOS 10.0, *)) + { + features.emplace_back(MTLFeatureSet_iOS_GPUFamily1_v3, "iOS_GPUFamily1_v3"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily2_v3, "iOS_GPUFamily2_v3"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily3_v2, "iOS_GPUFamily3_v2"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily4_v1, "iOS_GPUFamily4_v1"); + } + if (@available(iOS 11.0, *)) + { + features.emplace_back(MTLFeatureSet_iOS_GPUFamily1_v4, "iOS_GPUFamily1_v4"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily2_v4, "iOS_GPUFamily2_v4"); + features.emplace_back(MTLFeatureSet_iOS_GPUFamily3_v3, "iOS_GPUFamily3_v3"); + } + std::sort(features.begin(), features.end(), [](auto const & s1, auto const & s2) + { + return s1.first > s2.first; + }); + } + + for (auto featureSet : features) + { + if ([m_device supportsFeatureSet:featureSet.first]) + return featureSet.second; + } + return "Unknown"; +} + +void MetalBaseContext::SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) +{ + FinishCurrentEncoding(); + m_currentFramebuffer = framebuffer; +} + +void MetalBaseContext::ApplyFramebuffer(std::string const & framebufferLabel) +{ + // Initialize frame command buffer if there is no one. + if (!m_frameCommandBuffer) + { + m_frameCommandBuffer = [m_commandQueue commandBuffer]; + m_frameCommandBuffer.label = @"Frame command buffer"; + } + + if (!m_currentFramebuffer) + { + // Use default(system) framebuffer and depth-stencil. + m_renderPassDescriptor.colorAttachments[0].texture = m_frameDrawable.texture; + m_renderPassDescriptor.depthAttachment.texture = m_depthStencilTexture; + m_renderPassDescriptor.stencilAttachment.texture = nil; + } + else + { + ref_ptr<Framebuffer> framebuffer = m_currentFramebuffer; + + ASSERT(dynamic_cast<MetalTexture *>(framebuffer->GetTexture()->GetHardwareTexture().get()) != nullptr, ()); + ref_ptr<MetalTexture> colorAttachment = framebuffer->GetTexture()->GetHardwareTexture(); + m_renderPassDescriptor.colorAttachments[0].texture = colorAttachment->GetTexture(); + + auto const depthStencilRef = framebuffer->GetDepthStencilRef(); + if (depthStencilRef != nullptr) + { + ASSERT(dynamic_cast<MetalTexture *>(depthStencilRef->GetTexture()->GetHardwareTexture().get()) != nullptr, ()); + ref_ptr<MetalTexture> depthStencilAttachment = depthStencilRef->GetTexture()->GetHardwareTexture(); + m_renderPassDescriptor.depthAttachment.texture = depthStencilAttachment->GetTexture(); + m_renderPassDescriptor.stencilAttachment.texture = depthStencilAttachment->GetTexture(); + } + else + { + m_renderPassDescriptor.depthAttachment.texture = nil; + m_renderPassDescriptor.stencilAttachment.texture = nil; + } + } + + CHECK(m_currentCommandEncoder == nil, ("Current command encoder was not finished.")); + m_currentCommandEncoder = [m_frameCommandBuffer renderCommandEncoderWithDescriptor:m_renderPassDescriptor]; + [m_currentCommandEncoder pushDebugGroup:@(framebufferLabel.c_str())]; + + // Default rendering options. + [m_currentCommandEncoder setFrontFacingWinding:MTLWindingClockwise]; + [m_currentCommandEncoder setCullMode:MTLCullModeBack]; + [m_currentCommandEncoder setStencilReferenceValue:1]; +} + +void MetalBaseContext::SetClearColor(dp::Color const & color) +{ + m_renderPassDescriptor.colorAttachments[0].clearColor = + MTLClearColorMake(color.GetRedF(), color.GetGreenF(), color.GetBlueF(), color.GetAlphaF()); +} + +void MetalBaseContext::Clear(uint32_t clearBits) +{ + if (m_currentCommandEncoder != nil) + { + // Encoder has already been created. Here we has to draw fullscreen quad for clearing. + // TODO(@rokuz,@darina) + } + else + { + if (clearBits & ClearBits::ColorBit) + m_renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; + else + m_renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad; + + if (clearBits & ClearBits::DepthBit) + m_renderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear; + else + m_renderPassDescriptor.depthAttachment.loadAction = MTLLoadActionLoad; + + if (clearBits & ClearBits::StencilBit) + m_renderPassDescriptor.stencilAttachment.loadAction = MTLLoadActionClear; + else + m_renderPassDescriptor.stencilAttachment.loadAction = MTLLoadActionLoad; + } +} + +void MetalBaseContext::SetViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) +{ + id<MTLRenderCommandEncoder> encoder = GetCommandEncoder(); + [encoder setViewport:(MTLViewport){ static_cast<double>(x), static_cast<double>(y), + static_cast<double>(w), static_cast<double>(h), + -1.0, 1.0 }]; + [encoder setScissorRect:(MTLScissorRect){ x, y, w, h }]; +} + +void MetalBaseContext::SetDepthTestEnabled(bool enabled) +{ + m_currentDepthStencilKey.m_depthEnabled = enabled; +} + +void MetalBaseContext::SetDepthTestFunction(dp::TestFunction depthFunction) +{ + m_currentDepthStencilKey.m_depthFunction = depthFunction; +} + +void MetalBaseContext::SetStencilTestEnabled(bool enabled) +{ + m_currentDepthStencilKey.m_stencilEnabled = enabled; +} + +void MetalBaseContext::SetStencilFunction(dp::StencilFace face, dp::TestFunction stencilFunction) +{ + m_currentDepthStencilKey.SetStencilFunction(face, stencilFunction); +} + +void MetalBaseContext::SetStencilActions(dp::StencilFace face, + dp::StencilAction stencilFailAction, + dp::StencilAction depthFailAction, + dp::StencilAction passAction) +{ + m_currentDepthStencilKey.SetStencilActions(face, stencilFailAction, depthFailAction, passAction); +} + +id<MTLDevice> MetalBaseContext::GetMetalDevice() const +{ + return m_device; +} + +id<MTLRenderCommandEncoder> MetalBaseContext::GetCommandEncoder() const +{ + CHECK(m_currentCommandEncoder != nil, ("Probably encoding commands were called before ApplyFramebuffer.")); + return m_currentCommandEncoder; +} + +id<MTLDepthStencilState> MetalBaseContext::GetDepthStencilState() +{ + return m_metalStates.GetDepthStencilState(m_device, m_currentDepthStencilKey); +} + +id<MTLRenderPipelineState> MetalBaseContext::GetPipelineState(ref_ptr<GpuProgram> program, bool blendingEnabled) +{ + CHECK(m_currentCommandEncoder != nil, ("Probably encoding commands were called before ApplyFramebuffer.")); + + id<MTLTexture> colorTexture = m_renderPassDescriptor.colorAttachments[0].texture; + CHECK(colorTexture != nil, ()); + + id<MTLTexture> depthTexture = m_renderPassDescriptor.depthAttachment.texture; + MTLPixelFormat depthStencilFormat = (depthTexture != nil) ? depthTexture.pixelFormat : MTLPixelFormatInvalid; + + MetalStates::PipelineKey const key(program, colorTexture.pixelFormat, depthStencilFormat, blendingEnabled); + return m_metalStates.GetPipelineState(m_device, key); +} + +void MetalBaseContext::Present() +{ + FinishCurrentEncoding(); + if (m_frameDrawable) + { + [m_frameCommandBuffer presentDrawable:m_frameDrawable]; + [m_frameCommandBuffer commit]; + } + m_frameDrawable = nil; + [m_frameCommandBuffer waitUntilCompleted]; + m_frameCommandBuffer = nil; +} + +void MetalBaseContext::SetFrameDrawable(id<CAMetalDrawable> drawable) +{ + CHECK(drawable != nil, ()); + m_frameDrawable = drawable; +} + +bool MetalBaseContext::HasFrameDrawable() const +{ + return m_frameDrawable != nil; +} + +void MetalBaseContext::FinishCurrentEncoding() +{ + [m_currentCommandEncoder popDebugGroup]; + [m_currentCommandEncoder endEncoding]; + m_currentCommandEncoder = nil; +} +} // namespace metal +} // namespace dp diff --git a/drape/metal/metal_gpu_program.hpp b/drape/metal/metal_gpu_program.hpp new file mode 100644 index 0000000000..ba2f950795 --- /dev/null +++ b/drape/metal/metal_gpu_program.hpp @@ -0,0 +1,33 @@ +#pragma once +#import <MetalKit/MetalKit.h> + +#include "drape/gpu_program.hpp" + +#include <string> + +namespace dp +{ +namespace metal +{ +class MetalGpuProgram : public GpuProgram +{ +public: + MetalGpuProgram(std::string const & programName, id<MTLFunction> vertexShader, + id<MTLFunction> fragmentShader) + : GpuProgram(programName) + , m_vertexShader(vertexShader) + , m_fragmentShader(fragmentShader) + {} + + void Bind() override {} + void Unbind() override {} + + id<MTLFunction> GetVertexShader() const { return m_vertexShader; } + id<MTLFunction> GetFragmentShader() const { return m_fragmentShader; } + +private: + id<MTLFunction> m_vertexShader; + id<MTLFunction> m_fragmentShader; +}; +} // namespace metal +} // namespace dp diff --git a/drape/metal/metal_mesh_object_impl.mm b/drape/metal/metal_mesh_object_impl.mm new file mode 100644 index 0000000000..0a42af2e9a --- /dev/null +++ b/drape/metal/metal_mesh_object_impl.mm @@ -0,0 +1,103 @@ +#import <MetalKit/MetalKit.h> + +#include "drape/metal/metal_base_context.hpp" +#include "drape/mesh_object.hpp" +#include "drape/pointers.hpp" + +#include "base/assert.hpp" + +#include <cstdint> +#include <cstring> +#include <sstream> + +namespace dp +{ +namespace metal +{ +namespace +{ +MTLPrimitiveType GetPrimitiveType(MeshObject::DrawPrimitive primitive) +{ + switch (primitive) + { + case MeshObject::DrawPrimitive::Triangles: return MTLPrimitiveTypeTriangle; + case MeshObject::DrawPrimitive::TriangleStrip: return MTLPrimitiveTypeTriangleStrip; + case MeshObject::DrawPrimitive::LineStrip: return MTLPrimitiveTypeLineStrip; + } + CHECK(false, ("Unsupported type")); +} +} // namespace + +class MetalMeshObjectImpl : public MeshObjectImpl +{ +public: + MetalMeshObjectImpl(ref_ptr<dp::MeshObject> mesh) + : m_mesh(std::move(mesh)) + {} + + void Build(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program) override + { + ref_ptr<dp::metal::MetalBaseContext> metalContext = context; + id<MTLDevice> device = metalContext->GetMetalDevice(); + + m_geometryBuffers.resize(m_mesh->m_buffers.size()); + for (size_t i = 0; i < m_mesh->m_buffers.size(); i++) + { + if (m_mesh->m_buffers[i].m_data.empty()) + continue; + + auto const sizeInBytes = m_mesh->m_buffers[i].m_data.size() * sizeof(m_mesh->m_buffers[i].m_data[0]); + m_geometryBuffers[i] = [device newBufferWithBytes:m_mesh->m_buffers[i].m_data.data() + length:sizeInBytes + options:MTLResourceCPUCacheModeWriteCombined]; + std::ostringstream ss; + for (size_t j = 0; j < m_mesh->m_buffers[i].m_attributes.size(); j++) + { + ss << m_mesh->m_buffers[i].m_attributes[j].m_attributeName; + if (j + 1 < m_mesh->m_buffers[i].m_attributes.size()) + ss << "+"; + } + m_geometryBuffers[i].label = @(ss.str().c_str()); + } + } + + void Reset() override + { + m_geometryBuffers.clear(); + } + + void UpdateBuffer(uint32_t bufferInd) override + { + CHECK_LESS(bufferInd, static_cast<uint32_t>(m_geometryBuffers.size()), ()); + + auto & buffer = m_mesh->m_buffers[bufferInd]; + CHECK(!buffer.m_data.empty(), ()); + + uint8_t * bufferPointer = (uint8_t *)[m_geometryBuffers[bufferInd] contents]; + auto const sizeInBytes = buffer.m_data.size() * sizeof(buffer.m_data[0]); + memcpy(bufferPointer, buffer.m_data.data(), sizeInBytes); + } + + void Bind(ref_ptr<dp::GpuProgram> program) override {} + + void Unbind(ref_ptr<dp::GpuProgram> program) override {} + + void DrawPrimitives(ref_ptr<dp::GraphicsContext> context, uint32_t verticesCount) override + { + ref_ptr<dp::metal::MetalBaseContext> metalContext = context; + [metalContext->GetCommandEncoder() drawPrimitives:GetPrimitiveType(m_mesh->m_drawPrimitive) + vertexStart:0 + vertexCount:verticesCount]; + } + +private: + ref_ptr<dp::MeshObject> m_mesh; + std::vector<id<MTLBuffer>> m_geometryBuffers; +}; +} // namespace metal + +void MeshObject::InitForMetal() +{ + m_impl = make_unique_dp<metal::MetalMeshObjectImpl>(make_ref(this)); +} +} // namespace dp diff --git a/drape/metal/metal_states.hpp b/drape/metal/metal_states.hpp new file mode 100644 index 0000000000..89b16a38a4 --- /dev/null +++ b/drape/metal/metal_states.hpp @@ -0,0 +1,65 @@ +#pragma once +#import <MetalKit/MetalKit.h> + +#include "drape/graphics_context.hpp" +#include "drape/metal/metal_gpu_program.hpp" +#include "drape/pointers.hpp" + +#include <cstdint> +#include <map> + +namespace dp +{ +namespace metal +{ +class MetalStates +{ +public: + struct DepthStencilKey + { + void SetDepthTestEnabled(bool enabled); + void SetDepthTestFunction(TestFunction depthFunction); + void SetStencilTestEnabled(bool enabled); + void SetStencilFunction(StencilFace face, TestFunction stencilFunction); + void SetStencilActions(StencilFace face, StencilAction stencilFailAction, + StencilAction depthFailAction, StencilAction passAction); + bool operator<(DepthStencilKey const & rhs) const; + MTLDepthStencilDescriptor * BuildDescriptor() const; + + bool m_depthEnabled = false; + 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 + { + PipelineKey() = default; + PipelineKey(ref_ptr<GpuProgram> program, MTLPixelFormat colorFormat, + MTLPixelFormat depthStencilFormat, bool blendingEnabled); + + bool operator<(PipelineKey const & rhs) const; + MTLRenderPipelineDescriptor * BuildDescriptor() const; + + ref_ptr<GpuProgram> m_program; + MTLPixelFormat m_colorFormat = MTLPixelFormatInvalid; + MTLPixelFormat m_depthStencilFormat = MTLPixelFormatInvalid; + bool m_blendingEnabled = false; + }; + + id<MTLDepthStencilState> GetDepthStencilState(id<MTLDevice> device, DepthStencilKey const & key); + id<MTLRenderPipelineState> GetPipelineState(id<MTLDevice> device, PipelineKey const & key); + +private: + using DepthStencilCache = std::map<DepthStencilKey, id<MTLDepthStencilState>>; + DepthStencilCache m_depthStencilCache; + + using PipelineCache = std::map<PipelineKey, id<MTLRenderPipelineState>>; + PipelineCache m_pipelineCache; +}; +} // namespace metal +} // namespace dp diff --git a/drape/metal/metal_states.mm b/drape/metal/metal_states.mm new file mode 100644 index 0000000000..8410647bba --- /dev/null +++ b/drape/metal/metal_states.mm @@ -0,0 +1,264 @@ +#include "drape/metal/metal_states.hpp" + +#include "base/assert.hpp" + +#include <algorithm> +#include <string> +#include <vector> +#include <utility> + +namespace dp +{ +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] +uint8_t constexpr kStencilBackFunctionByte = 7; +uint8_t constexpr kStencilBackFailActionByte = 6; +uint8_t constexpr kStencilBackDepthFailActionByte = 5; +uint8_t constexpr kStencilBackPassActionByte = 4; +uint8_t constexpr kStencilFrontFunctionByte = 3; +uint8_t constexpr kStencilFrontFailActionByte = 2; +uint8_t constexpr kStencilFrontDepthFailActionByte = 1; +uint8_t constexpr kStencilFrontPassActionByte = 0; + +MTLCompareFunction DecodeTestFunction(uint8_t testFunctionByte) +{ + switch (static_cast<TestFunction>(testFunctionByte)) + { + case TestFunction::Never: return MTLCompareFunctionNever; + case TestFunction::Less: return MTLCompareFunctionLess; + case TestFunction::Equal: return MTLCompareFunctionEqual; + case TestFunction::LessOrEqual: return MTLCompareFunctionLessEqual; + case TestFunction::Greater: return MTLCompareFunctionGreater; + case TestFunction::NotEqual: return MTLCompareFunctionNotEqual; + case TestFunction::GreaterOrEqual: return MTLCompareFunctionGreaterEqual; + case TestFunction::Always: return MTLCompareFunctionAlways; + } + ASSERT(false, ()); +} + +MTLStencilOperation DecodeStencilAction(uint8_t stencilActionByte) +{ + switch (static_cast<StencilAction>(stencilActionByte)) + { + case StencilAction::Keep: return MTLStencilOperationKeep; + case StencilAction::Zero: return MTLStencilOperationZero; + case StencilAction::Replace: return MTLStencilOperationReplace; + case StencilAction::Increment: return MTLStencilOperationIncrementClamp; + case StencilAction::IncrementWrap: return MTLStencilOperationIncrementWrap; + case StencilAction::Decrement: return MTLStencilOperationDecrementClamp; + case StencilAction::DecrementWrap: return MTLStencilOperationDecrementWrap; + case StencilAction::Invert: return MTLStencilOperationInvert; + } + ASSERT(false, ()); +} + +bool IsStencilFormat(MTLPixelFormat format) +{ + return format == MTLPixelFormatDepth32Float_Stencil8 || + format == MTLPixelFormatStencil8 || + format == MTLPixelFormatX32_Stencil8; +} +} // namespace + +id<MTLDepthStencilState> MetalStates::GetDepthStencilState(id<MTLDevice> device, DepthStencilKey const & key) +{ + auto const it = m_depthStencilCache.find(key); + if (it != m_depthStencilCache.end()) + return it->second; + + id<MTLDepthStencilState> depthState = [device newDepthStencilStateWithDescriptor:key.BuildDescriptor()]; + CHECK(depthState != nil, ()); + m_depthStencilCache.insert(std::make_pair(key, depthState)); + return depthState; +} + +id<MTLRenderPipelineState> MetalStates::GetPipelineState(id<MTLDevice> device, PipelineKey const & key) +{ + auto const it = m_pipelineCache.find(key); + if (it != m_pipelineCache.end()) + return it->second; + + NSError * error = NULL; + id<MTLRenderPipelineState> pipelineState = [device newRenderPipelineStateWithDescriptor:key.BuildDescriptor() + error:&error]; + if (pipelineState == nil || error != nil) + { + NSLog(@"%@", error); + CHECK(false, ("Failed to create pipeline state.")); + } + m_pipelineCache.insert(std::make_pair(key, pipelineState)); + return pipelineState; +} + +void MetalStates::DepthStencilKey::SetDepthTestEnabled(bool enabled) +{ + m_depthEnabled = enabled; +} + +void MetalStates::DepthStencilKey::SetDepthTestFunction(TestFunction depthFunction) +{ + m_depthFunction = depthFunction; +} + +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); + break; + case StencilFace::Back: + SetStencilByte(static_cast<uint8_t>(stencilFunction), kStencilBackFunctionByte); + break; + case StencilFace::FrontAndBack: + SetStencilByte(static_cast<uint8_t>(stencilFunction), kStencilFrontFunctionByte); + SetStencilByte(static_cast<uint8_t>(stencilFunction), kStencilBackFunctionByte); + break; + } +} + +void MetalStates::DepthStencilKey::SetStencilActions(StencilFace face, StencilAction stencilFailAction, + StencilAction depthFailAction, StencilAction passAction) +{ + 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); + 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); + 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); + break; + } +} + +bool MetalStates::DepthStencilKey::operator<(DepthStencilKey const & rhs) const +{ + if (m_depthEnabled != rhs.m_depthEnabled) + return m_depthEnabled < rhs.m_depthEnabled; + + if (m_stencilEnabled != rhs.m_stencilEnabled) + return m_stencilEnabled < rhs.m_stencilEnabled; + + if (m_depthFunction != rhs.m_depthFunction) + return m_depthFunction < rhs.m_depthFunction; + + return m_stencil < rhs.m_stencil; +} + +MTLDepthStencilDescriptor * MetalStates::DepthStencilKey::BuildDescriptor() const +{ + MTLDepthStencilDescriptor * desc = [[MTLDepthStencilDescriptor alloc] init]; + if (m_depthEnabled) + { + desc.depthWriteEnabled = YES; + desc.depthCompareFunction = DecodeTestFunction(static_cast<uint8_t>(m_depthFunction)); + } + else + { + desc.depthWriteEnabled = NO; + desc.depthCompareFunction = MTLCompareFunctionAlways; + } + 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)); + 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)); + desc.backFaceStencil = backDesc; + } + else + { + desc.frontFaceStencil = nil; + desc.backFaceStencil = nil; + } + return desc; +} + +MetalStates::PipelineKey::PipelineKey(ref_ptr<GpuProgram> program, MTLPixelFormat colorFormat, + MTLPixelFormat depthStencilFormat, bool blendingEnabled) + : m_program(std::move(program)) + , m_colorFormat(colorFormat) + , m_depthStencilFormat(depthStencilFormat) + , m_blendingEnabled(blendingEnabled) +{} + +bool MetalStates::PipelineKey::operator<(PipelineKey const & rhs) const +{ + if (m_program != rhs.m_program) + return m_program < rhs.m_program; + + if (m_colorFormat != rhs.m_colorFormat) + return m_colorFormat < rhs.m_colorFormat; + + if (m_depthStencilFormat != rhs.m_depthStencilFormat) + return m_depthStencilFormat < rhs.m_depthStencilFormat; + + return m_blendingEnabled < rhs.m_blendingEnabled; +} + +MTLRenderPipelineDescriptor * MetalStates::PipelineKey::BuildDescriptor() const +{ + MTLRenderPipelineDescriptor * desc = [[MTLRenderPipelineDescriptor alloc] init]; + desc.rasterSampleCount = 1; + ref_ptr<MetalGpuProgram> metalProgram = m_program; + desc.vertexFunction = metalProgram->GetVertexShader(); + desc.fragmentFunction = metalProgram->GetFragmentShader(); + MTLRenderPipelineColorAttachmentDescriptor * colorAttachment = desc.colorAttachments[0]; + colorAttachment.pixelFormat = m_colorFormat; + desc.depthAttachmentPixelFormat = m_depthStencilFormat; + if (IsStencilFormat(m_depthStencilFormat)) + desc.stencilAttachmentPixelFormat = m_depthStencilFormat; + else + desc.stencilAttachmentPixelFormat = MTLPixelFormatInvalid; + colorAttachment.blendingEnabled = m_blendingEnabled ? YES : NO; + colorAttachment.rgbBlendOperation = MTLBlendOperationAdd; + colorAttachment.alphaBlendOperation = MTLBlendOperationAdd; + colorAttachment.sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; + colorAttachment.sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha; + colorAttachment.destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + colorAttachment.destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + return desc; +} +} // namespace metal +} // namespace dp diff --git a/drape/metal/metal_texture.hpp b/drape/metal/metal_texture.hpp new file mode 100644 index 0000000000..d2771f2334 --- /dev/null +++ b/drape/metal/metal_texture.hpp @@ -0,0 +1,38 @@ +#pragma once +#import <MetalKit/MetalKit.h> + +#include "drape/hw_texture.hpp" +#include "drape/pointers.hpp" + +namespace dp +{ +namespace metal +{ +class MetalTextureAllocator : public HWTextureAllocator +{ +public: + drape_ptr<HWTexture> CreateTexture(ref_ptr<dp::GraphicsContext> context) override; + void Flush() override {} +}; + +class MetalTexture : public HWTexture +{ + using Base = HWTexture; +public: + explicit MetalTexture(ref_ptr<MetalTextureAllocator> allocator); + + void Create(ref_ptr<dp::GraphicsContext> context, Params const & params, ref_ptr<void> data) override; + void UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data) override; + void Bind() const override {} + void SetFilter(TextureFilter filter) override; + bool Validate() const override; + + id<MTLTexture> GetTexture() const { return m_texture; } + +private: + ref_ptr<MetalTextureAllocator> m_allocator; + id<MTLTexture> m_texture; + bool m_isMutable = false; +}; +} // namespace metal +} // namespace dp diff --git a/drape/metal/metal_texture.mm b/drape/metal/metal_texture.mm new file mode 100644 index 0000000000..96a4d04872 --- /dev/null +++ b/drape/metal/metal_texture.mm @@ -0,0 +1,97 @@ +#include "drape/metal/metal_texture.hpp" +#include "drape/metal/metal_base_context.hpp" + +#include "base/logging.hpp" + +drape_ptr<dp::HWTextureAllocator> CreateMetalAllocator() +{ + return make_unique_dp<dp::metal::MetalTextureAllocator>(); +} + +ref_ptr<dp::HWTextureAllocator> GetDefaultMetalAllocator() +{ + static dp::metal::MetalTextureAllocator allocator; + return make_ref<dp::HWTextureAllocator>(&allocator); +} + +namespace dp +{ +namespace metal +{ +namespace +{ +MTLPixelFormat UnpackFormat(TextureFormat format) +{ + switch (format) + { + case TextureFormat::RGBA8: return MTLPixelFormatRGBA8Unorm; + case TextureFormat::Alpha: return MTLPixelFormatA8Unorm; + case TextureFormat::RedGreen: return MTLPixelFormatRG8Unorm; + case TextureFormat::DepthStencil: return MTLPixelFormatDepth32Float_Stencil8; + case TextureFormat::Depth: return MTLPixelFormatDepth32Float; + case TextureFormat::Unspecified: + CHECK(false, ()); + return MTLPixelFormatInvalid; + } + CHECK(false, ()); +} +} // namespace + +drape_ptr<HWTexture> MetalTextureAllocator::CreateTexture(ref_ptr<dp::GraphicsContext> context) +{ + return make_unique_dp<MetalTexture>(make_ref<MetalTextureAllocator>(this)); +} + +MetalTexture::MetalTexture(ref_ptr<MetalTextureAllocator> allocator) + : m_allocator(allocator) +{} + +void MetalTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params, ref_ptr<void> data) +{ + Base::Create(context, params, data); + ref_ptr<MetalBaseContext> metalContext = context; + id<MTLDevice> metalDevice = metalContext->GetMetalDevice(); + + MTLTextureDescriptor * texDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:UnpackFormat(params.m_format) + width:params.m_width + height:params.m_height + mipmapped:NO]; + texDesc.usage = MTLTextureUsageShaderRead; + m_isMutable = params.m_isMutable; + if (params.m_isRenderTarget) + { + texDesc.usage |= MTLTextureUsageRenderTarget; + texDesc.storageMode = MTLStorageModePrivate; + m_texture = [metalDevice newTextureWithDescriptor:texDesc]; + CHECK(m_texture != nil, ()); + } + else + { + texDesc.storageMode = MTLStorageModeShared; + m_texture = [metalDevice newTextureWithDescriptor:texDesc]; + CHECK(m_texture != nil, ()); + MTLRegion region = MTLRegionMake2D(0, 0, m_params.m_width, m_params.m_height); + auto const rowBytes = m_params.m_width * GetBytesPerPixel(m_params.m_format); + [m_texture replaceRegion:region mipmapLevel:0 withBytes:data.get() bytesPerRow:rowBytes]; + } +} + +void MetalTexture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data) +{ + CHECK(m_isMutable, ("Upload data is avaivable only for mutable textures.")); + MTLRegion region = MTLRegionMake2D(x, y, width, height); + auto const rowBytes = width * GetBytesPerPixel(m_params.m_format); + [m_texture replaceRegion:region mipmapLevel:0 withBytes:data.get() bytesPerRow:rowBytes]; +} + +void MetalTexture::SetFilter(TextureFilter filter) +{ + //TODO(@rokuz,@darina) +} + +bool MetalTexture::Validate() const +{ + return m_texture != nil; +} +} // namespace metal +} // namespace dp diff --git a/drape/metal/render_state_metal.mm b/drape/metal/render_state_metal.mm new file mode 100644 index 0000000000..ea2c058f89 --- /dev/null +++ b/drape/metal/render_state_metal.mm @@ -0,0 +1,27 @@ +#import <MetalKit/MetalKit.h> + +#include "drape/metal/metal_base_context.hpp" +#include "drape/metal/metal_gpu_program.hpp" +#include "drape/pointers.hpp" + +#include "base/assert.hpp" + +#include <utility> + +namespace dp +{ +void ApplyDepthStencilStateForMetal(ref_ptr<GraphicsContext> context) +{ + ref_ptr<dp::metal::MetalBaseContext> metalContext = context; + id<MTLDepthStencilState> state = metalContext->GetDepthStencilState(); + [metalContext->GetCommandEncoder() setDepthStencilState:state]; +} + +void ApplyPipelineStateForMetal(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program, + bool blendingEnabled) +{ + ref_ptr<dp::metal::MetalBaseContext> metalContext = context; + id<MTLRenderPipelineState> state = metalContext->GetPipelineState(std::move(program), blendingEnabled); + [metalContext->GetCommandEncoder() setRenderPipelineState:state]; +} +} // namespace dp diff --git a/drape/oglcontext.cpp b/drape/oglcontext.cpp index 62794bb176..d9d8644b1c 100644 --- a/drape/oglcontext.cpp +++ b/drape/oglcontext.cpp @@ -1,5 +1,7 @@ #include "drape/oglcontext.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" + +#include "base/macros.hpp" namespace dp { @@ -65,6 +67,21 @@ void OGLContext::Init(ApiVersion apiVersion) GLFunctions::glEnable(gl_const::GLScissorTest); } +ApiVersion OGLContext::GetApiVersion() const +{ + return GLFunctions::CurrentApiVersion; +} + +std::string OGLContext::GetRendererName() const +{ + return GLFunctions::glGetString(gl_const::GLRenderer); +} + +std::string OGLContext::GetRendererVersion() const +{ + return GLFunctions::glGetString(gl_const::GLVersion); +} + void OGLContext::SetClearColor(dp::Color const & color) { GLFunctions::glClearColor(color.GetRedF(), color.GetGreenF(), color.GetBlueF(), color.GetAlphaF()); @@ -88,6 +105,12 @@ void OGLContext::Flush() GLFunctions::glFlush(); } +void OGLContext::SetViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) +{ + GLCHECK(GLFunctions::glViewport(x, y, w, h)); + GLCHECK(GLFunctions::glScissor(x, y, w, h)); +} + void OGLContext::SetDepthTestEnabled(bool enabled) { if (enabled) diff --git a/drape/oglcontext.hpp b/drape/oglcontext.hpp index 129e76c09b..2692e662a8 100644 --- a/drape/oglcontext.hpp +++ b/drape/oglcontext.hpp @@ -4,13 +4,19 @@ namespace dp { -class OGLContext: public GraphicsContext +class OGLContext : public GraphicsContext { public: void Init(ApiVersion apiVersion) override; + ApiVersion GetApiVersion() const override; + std::string GetRendererName() const override; + std::string GetRendererVersion() const override; + void ApplyFramebuffer(std::string const & framebufferLabel) override {} + 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(TestFunction depthFunction) override; void SetStencilTestEnabled(bool enabled) override; diff --git a/drape/pointers.hpp b/drape/pointers.hpp index ccddb3e7a6..22ef786f9c 100644 --- a/drape/pointers.hpp +++ b/drape/pointers.hpp @@ -72,35 +72,47 @@ template<typename T> class ref_ptr { public: - ref_ptr() - : m_ptr(nullptr), m_isOwnerUnique(false) - {} + ref_ptr() noexcept + : m_ptr(nullptr) + { +#if defined(TRACK_POINTERS) + m_isOwnerUnique = false; +#endif + } - ref_ptr(T * ptr, bool isOwnerUnique = false) - : m_ptr(ptr), m_isOwnerUnique(isOwnerUnique) +#if defined(TRACK_POINTERS) + ref_ptr(T * ptr, bool isOwnerUnique = false) noexcept +#else + ref_ptr(T * ptr) noexcept +#endif + : m_ptr(ptr) { #if defined(TRACK_POINTERS) + m_isOwnerUnique = isOwnerUnique; if (m_isOwnerUnique) DpPointerTracker::Instance().RefPtr(m_ptr); #endif } - ref_ptr(ref_ptr const & rhs) - : m_ptr(rhs.m_ptr), m_isOwnerUnique(rhs.m_isOwnerUnique) + ref_ptr(ref_ptr const & rhs) noexcept + : m_ptr(rhs.m_ptr) { #if defined(TRACK_POINTERS) + m_isOwnerUnique = rhs.m_isOwnerUnique; if (m_isOwnerUnique) DpPointerTracker::Instance().RefPtr(m_ptr); #endif } - ref_ptr(ref_ptr && rhs) + ref_ptr(ref_ptr && rhs) noexcept { m_ptr = rhs.m_ptr; rhs.m_ptr = nullptr; +#if defined(TRACK_POINTERS) m_isOwnerUnique = rhs.m_isOwnerUnique; rhs.m_isOwnerUnique = false; +#endif } ~ref_ptr() @@ -120,17 +132,26 @@ public: static_assert(std::is_base_of<TResult, T>::value || std::is_base_of<T, TResult>::value || std::is_void<T>::value || std::is_void<TResult>::value, ""); +#if defined(TRACK_POINTERS) return ref_ptr<TResult>(static_cast<TResult *>(m_ptr), m_isOwnerUnique); +#else + return ref_ptr<TResult>(static_cast<TResult *>(m_ptr)); +#endif } template<typename TResult> ref_ptr<TResult> downcast() const { ASSERT(dynamic_cast<TResult *>(m_ptr) != nullptr, ()); + +#if defined(TRACK_POINTERS) return ref_ptr<TResult>(static_cast<TResult *>(m_ptr), m_isOwnerUnique); +#else + return ref_ptr<TResult>(static_cast<TResult *>(m_ptr)); +#endif } - operator bool() const { return m_ptr != nullptr; } + explicit operator bool() const { return m_ptr != nullptr; } bool operator==(ref_ptr const & rhs) const { return m_ptr == rhs.m_ptr; } @@ -148,7 +169,7 @@ public: return *m_ptr; } - ref_ptr & operator=(ref_ptr const & rhs) + ref_ptr & operator=(ref_ptr const & rhs) noexcept { if (this == &rhs) return *this; @@ -159,9 +180,9 @@ public: #endif m_ptr = rhs.m_ptr; - m_isOwnerUnique = rhs.m_isOwnerUnique; #if defined(TRACK_POINTERS) + m_isOwnerUnique = rhs.m_isOwnerUnique; if (m_isOwnerUnique) DpPointerTracker::Instance().RefPtr(m_ptr); #endif @@ -169,7 +190,7 @@ public: return *this; } - ref_ptr & operator=(ref_ptr && rhs) + ref_ptr & operator=(ref_ptr && rhs) noexcept { if (this == &rhs) return *this; @@ -182,8 +203,10 @@ public: m_ptr = rhs.m_ptr; rhs.m_ptr = nullptr; +#if defined(TRACK_POINTERS) m_isOwnerUnique = rhs.m_isOwnerUnique; rhs.m_isOwnerUnique = false; +#endif return *this; } @@ -192,7 +215,9 @@ public: private: T* m_ptr; +#if defined(TRACK_POINTERS) bool m_isOwnerUnique; +#endif template <typename TResult> friend inline std::string DebugPrint(ref_ptr<TResult> const & v); @@ -207,11 +232,19 @@ inline std::string DebugPrint(ref_ptr<T> const & v) template <typename T> ref_ptr<T> make_ref(drape_ptr<T> const & drapePtr) { - return ref_ptr<T>(drapePtr.get(), true); +#if defined(TRACK_POINTERS) + return ref_ptr<T>(drapePtr.get(), true /* isOwnerUnique */); +#else + return ref_ptr<T>(drapePtr.get()); +#endif } template <typename T> ref_ptr<T> make_ref(T* ptr) { - return ref_ptr<T>(ptr, false); +#if defined(TRACK_POINTERS) + return ref_ptr<T>(ptr, false /* isOwnerUnique */); +#else + return ref_ptr<T>(ptr); +#endif } diff --git a/drape/render_bucket.cpp b/drape/render_bucket.cpp index 7f6beb22be..f06a195049 100644 --- a/drape/render_bucket.cpp +++ b/drape/render_bucket.cpp @@ -7,19 +7,14 @@ #include "drape/vertex_array_buffer.hpp" #include "base/stl_helpers.hpp" -#include "std/bind.hpp" namespace dp { - RenderBucket::RenderBucket(drape_ptr<VertexArrayBuffer> && buffer) - : m_buffer(move(buffer)) -{ -} + : m_buffer(std::move(buffer)) +{} -RenderBucket::~RenderBucket() -{ -} +RenderBucket::~RenderBucket() {} ref_ptr<VertexArrayBuffer> RenderBucket::GetBuffer() { @@ -28,7 +23,7 @@ ref_ptr<VertexArrayBuffer> RenderBucket::GetBuffer() drape_ptr<VertexArrayBuffer> && RenderBucket::MoveBuffer() { - return move(m_buffer); + return std::move(m_buffer); } size_t RenderBucket::GetOverlayHandlesCount() const @@ -144,7 +139,7 @@ void RenderBucket::RenderDebug(ref_ptr<GraphicsContext> context, ScreenBase cons if (!screen.PixelRect().IsIntersect(handle->GetPixelRect(screen, false))) continue; - OverlayHandle::Rects const & rects = handle->GetExtendedPixelShape(screen); + auto const & rects = handle->GetExtendedPixelShape(screen); for (auto const & rect : rects) { if (screen.isPerspective() && !screen.PixelRectIn3d().IsIntersect(m2::RectD(rect))) @@ -158,5 +153,4 @@ void RenderBucket::RenderDebug(ref_ptr<GraphicsContext> context, ScreenBase cons } } } - -} // namespace dp +} // namespace dp diff --git a/drape/render_bucket.hpp b/drape/render_bucket.hpp index 0ef6ce50e6..678b1d6d35 100644 --- a/drape/render_bucket.hpp +++ b/drape/render_bucket.hpp @@ -2,31 +2,23 @@ #include "drape/pointers.hpp" -#include "std/function.hpp" -#include "std/limits.hpp" -#include "std/vector.hpp" +#include <limits> +#include <vector> class ScreenBase; -namespace df -{ -class BatchMergeHelper; -} - namespace dp { - -class GraphicsContext; class DebugRenderer; +class GraphicsContext; class OverlayHandle; class OverlayTree; class VertexArrayBuffer; class RenderBucket { - friend class df::BatchMergeHelper; public: - RenderBucket(drape_ptr<VertexArrayBuffer> && buffer); + explicit RenderBucket(drape_ptr<VertexArrayBuffer> && buffer); ~RenderBucket(); ref_ptr<VertexArrayBuffer> GetBuffer(); @@ -62,11 +54,9 @@ public: private: void BeforeUpdate(); -private: - int m_featuresMinZoom = numeric_limits<int>::max(); + int m_featuresMinZoom = std::numeric_limits<int>::max(); - vector<drape_ptr<OverlayHandle> > m_overlay; + std::vector<drape_ptr<OverlayHandle>> m_overlay; drape_ptr<VertexArrayBuffer> m_buffer; }; - -} // namespace dp +} // namespace dp diff --git a/drape/render_state.cpp b/drape/render_state.cpp index 1d317f9c6c..0da8a47e3c 100644 --- a/drape/render_state.cpp +++ b/drape/render_state.cpp @@ -1,5 +1,6 @@ #include "drape/render_state.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" +#include "drape/gl_gpu_program.hpp" #include "base/buffer_vector.hpp" @@ -11,23 +12,43 @@ std::string const kColorTextureName = "u_colorTex"; std::string const kMaskTextureName = "u_maskTex"; } // namespace +#if defined(OMIM_OS_IPHONE) +extern void ApplyDepthStencilStateForMetal(ref_ptr<GraphicsContext> context); +extern void ApplyPipelineStateForMetal(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program, + bool blendingEnabled); +#endif + // static -void AlphaBlendingState::Apply() +void AlphaBlendingState::Apply(ref_ptr<GraphicsContext> context) { - GLFunctions::glBlendEquation(gl_const::GLAddBlend); - GLFunctions::glBlendFunc(gl_const::GLSrcAlpha, gl_const::GLOneMinusSrcAlpha); + // For Metal Rendering these settings must be set in the pipeline state. + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) + { + GLFunctions::glBlendEquation(gl_const::GLAddBlend); + GLFunctions::glBlendFunc(gl_const::GLSrcAlpha, gl_const::GLOneMinusSrcAlpha); + } } Blending::Blending(bool isEnabled) : m_isEnabled(isEnabled) {} -void Blending::Apply() const +void Blending::Apply(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program) const { - if (m_isEnabled) - GLFunctions::glEnable(gl_const::GLBlending); + // For Metal Rendering these settings must be set in the pipeline state. + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) + { + if (m_isEnabled) + GLFunctions::glEnable(gl_const::GLBlending); + else + GLFunctions::glDisable(gl_const::GLBlending); + } else - GLFunctions::glDisable(gl_const::GLBlending); + { + CHECK(false, ("Unsupported API version.")); + } } bool Blending::operator<(Blending const & other) const { return m_isEnabled < other.m_isEnabled; } @@ -36,7 +57,7 @@ bool Blending::operator==(Blending const & other) const { return m_isEnabled == void RenderState::SetColorTexture(ref_ptr<Texture> tex) { - m_textures[kColorTextureName] = tex; + m_textures[kColorTextureName] = std::move(tex); } ref_ptr<Texture> RenderState::GetColorTexture() const @@ -49,7 +70,7 @@ ref_ptr<Texture> RenderState::GetColorTexture() const void RenderState::SetMaskTexture(ref_ptr<Texture> tex) { - m_textures[kMaskTextureName] = tex; + m_textures[kMaskTextureName] = std::move(tex); } ref_ptr<Texture> RenderState::GetMaskTexture() const @@ -62,7 +83,7 @@ ref_ptr<Texture> RenderState::GetMaskTexture() const void RenderState::SetTexture(std::string const & name, ref_ptr<Texture> tex) { - m_textures[name] = tex; + m_textures[name] = std::move(tex); } ref_ptr<Texture> RenderState::GetTexture(std::string const & name) const @@ -170,23 +191,29 @@ bool RenderState::operator!=(RenderState const & other) const uint8_t TextureState::m_usedSlots = 0; -void TextureState::ApplyTextures(RenderState const & state, ref_ptr<GpuProgram> program) +void TextureState::ApplyTextures(ref_ptr<GraphicsContext> context, RenderState const & state, + ref_ptr<GpuProgram> program) { m_usedSlots = 0; - - for (auto const & texture : state.GetTextures()) + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) { - auto const tex = texture.second; - int8_t texLoc = -1; - if (tex != nullptr && (texLoc = program->GetUniformLocation(texture.first)) >= 0) + ref_ptr<dp::GLGpuProgram> p = program; + for (auto const & texture : state.GetTextures()) { - GLFunctions::glActiveTexture(gl_const::GLTexture0 + m_usedSlots); - tex->Bind(); - GLFunctions::glUniformValuei(texLoc, m_usedSlots); - tex->SetFilter(state.GetTextureFilter()); - m_usedSlots++; + auto const tex = texture.second; + int8_t texLoc = -1; + if (tex != nullptr && (texLoc = p->GetUniformLocation(texture.first)) >= 0) + { + GLFunctions::glActiveTexture(gl_const::GLTexture0 + m_usedSlots); + tex->Bind(); + GLFunctions::glUniformValuei(texLoc, m_usedSlots); + tex->SetFilter(state.GetTextureFilter()); + m_usedSlots++; + } } } + //TODO(@rokuz,@darina): Metal? } uint8_t TextureState::GetLastUsedSlots() @@ -194,20 +221,42 @@ uint8_t TextureState::GetLastUsedSlots() return m_usedSlots; } -void ApplyBlending(RenderState const & state) -{ - state.GetBlending().Apply(); -} - void ApplyState(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program, RenderState const & state) { - TextureState::ApplyTextures(state, program); - ApplyBlending(state); + auto const apiVersion = context->GetApiVersion(); + + TextureState::ApplyTextures(context, state, program); + + // Apply blending state. + if (apiVersion == dp::ApiVersion::Metal) + { + // For Metal rendering blending state is a part of the pipeline state. +#if defined(OMIM_OS_IPHONE) + ApplyPipelineStateForMetal(context, program, state.GetBlending().m_isEnabled); +#endif + } + else + { + state.GetBlending().Apply(context, program); + } + + // Apply depth state. context->SetDepthTestEnabled(state.GetDepthTestEnabled()); if (state.GetDepthTestEnabled()) context->SetDepthTestFunction(state.GetDepthFunction()); + if (apiVersion == dp::ApiVersion::Metal) + { + // For Metal rendering we have to apply depth-stencil state after SetX functions calls. +#if defined(OMIM_OS_IPHONE) + ApplyDepthStencilStateForMetal(context); +#endif + } - ASSERT_GREATER_OR_EQUAL(state.GetLineWidth(), 0, ()); - GLFunctions::glLineWidth(static_cast<uint32_t>(state.GetLineWidth())); + // Metal does not support line width. + if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) + { + ASSERT_GREATER_OR_EQUAL(state.GetLineWidth(), 0, ()); + GLFunctions::glLineWidth(static_cast<uint32_t>(state.GetLineWidth())); + } } } // namespace dp diff --git a/drape/render_state.hpp b/drape/render_state.hpp index 485ea1fb81..122a760466 100644 --- a/drape/render_state.hpp +++ b/drape/render_state.hpp @@ -14,14 +14,14 @@ namespace dp { struct AlphaBlendingState { - static void Apply(); + static void Apply(ref_ptr<GraphicsContext> context); }; struct Blending { explicit Blending(bool isEnabled = true); - void Apply() const; + void Apply(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program) const; bool operator<(Blending const & other) const; bool operator==(Blending const & other) const; @@ -116,7 +116,8 @@ private: class TextureState { public: - static void ApplyTextures(RenderState const & state, ref_ptr<GpuProgram> program); + static void ApplyTextures(ref_ptr<GraphicsContext> context, RenderState const & state, + ref_ptr<GpuProgram> program); static uint8_t GetLastUsedSlots(); private: @@ -124,5 +125,4 @@ private: }; void ApplyState(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program, RenderState const & state); -void ApplyBlending(RenderState const & state); } // namespace dp diff --git a/drape/shader.cpp b/drape/shader.cpp index 54149ce8af..259ccc278c 100644 --- a/drape/shader.cpp +++ b/drape/shader.cpp @@ -1,5 +1,5 @@ #include "drape/shader.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include "base/assert.hpp" diff --git a/drape/static_texture.cpp b/drape/static_texture.cpp index e51609ee12..4318ab2df2 100644 --- a/drape/static_texture.cpp +++ b/drape/static_texture.cpp @@ -90,20 +90,21 @@ public: }; } // namespace -StaticTexture::StaticTexture(std::string const & textureName, std::string const & skinPathName, +StaticTexture::StaticTexture(ref_ptr<dp::GraphicsContext> context, + std::string const & textureName, std::string const & skinPathName, dp::TextureFormat format, ref_ptr<HWTextureAllocator> allocator) : m_textureName(textureName) , m_skinPathName(skinPathName) , m_format(format) , m_info(make_unique_dp<StaticResourceInfo>()) { - m_isLoadingCorrect = Load(allocator); + m_isLoadingCorrect = Load(std::move(context), allocator); } -bool StaticTexture::Load(ref_ptr<HWTextureAllocator> allocator) +bool StaticTexture::Load(ref_ptr<dp::GraphicsContext> context, ref_ptr<HWTextureAllocator> allocator) { - auto completionHandler = [this, &allocator](unsigned char * data, uint32_t width, - uint32_t height) + auto completionHandler = [this, &allocator, context](unsigned char * data, uint32_t width, + uint32_t height) { Texture::Params p; p.m_allocator = allocator; @@ -113,13 +114,13 @@ bool StaticTexture::Load(ref_ptr<HWTextureAllocator> allocator) p.m_wrapSMode = TextureWrapping::Repeat; p.m_wrapTMode = TextureWrapping::Repeat; - Create(p, make_ref(data)); + Create(std::move(context), p, make_ref(data)); }; - auto failureHandler = [this](std::string const & reason) + auto failureHandler = [this, context](std::string const & reason) { LOG(LERROR, (reason)); - Fail(); + Fail(std::move(context)); }; uint8_t const bytesPerPixel = GetBytesPerPixel(m_format); @@ -127,10 +128,11 @@ bool StaticTexture::Load(ref_ptr<HWTextureAllocator> allocator) completionHandler, failureHandler); } -void StaticTexture::Invalidate(ref_ptr<HWTextureAllocator> allocator) +void StaticTexture::Invalidate(ref_ptr<dp::GraphicsContext> context, + ref_ptr<HWTextureAllocator> allocator) { Destroy(); - m_isLoadingCorrect = Load(allocator); + m_isLoadingCorrect = Load(std::move(context), std::move(allocator)); } ref_ptr<Texture::ResourceInfo> StaticTexture::FindResource(Texture::Key const & key, @@ -142,28 +144,29 @@ ref_ptr<Texture::ResourceInfo> StaticTexture::FindResource(Texture::Key const & return make_ref(m_info); } -void StaticTexture::Create(Params const & params) +void StaticTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params) { ASSERT(Base::IsPowerOfTwo(params.m_width, params.m_height), (params.m_width, params.m_height)); - Base::Create(params); + Base::Create(std::move(context), params); } -void StaticTexture::Create(Params const & params, ref_ptr<void> data) +void StaticTexture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params, + ref_ptr<void> data) { ASSERT(Base::IsPowerOfTwo(params.m_width, params.m_height), (params.m_width, params.m_height)); - Base::Create(params, data); + Base::Create(std::move(context), params, data); } -void StaticTexture::Fail() +void StaticTexture::Fail(ref_ptr<dp::GraphicsContext> context) { int32_t alphaTexture = 0; Texture::Params p; - p.m_allocator = GetDefaultAllocator(); + p.m_allocator = GetDefaultAllocator(context); p.m_format = dp::TextureFormat::RGBA8; p.m_width = 1; p.m_height = 1; - Create(p, make_ref(&alphaTexture)); + Create(context, p, make_ref(&alphaTexture)); } } // namespace dp diff --git a/drape/static_texture.hpp b/drape/static_texture.hpp index 8175a4d2fc..f2ccbe4797 100644 --- a/drape/static_texture.hpp +++ b/drape/static_texture.hpp @@ -18,19 +18,21 @@ public: static std::string const kDefaultResource; - StaticTexture(std::string const & textureName, std::string const & skinPathName, + StaticTexture(ref_ptr<dp::GraphicsContext> context, + std::string const & textureName, std::string const & skinPathName, dp::TextureFormat format, ref_ptr<HWTextureAllocator> allocator); ref_ptr<ResourceInfo> FindResource(Key const & key, bool & newResource) override; - void Create(Params const & params) override; - void Create(Params const & params, ref_ptr<void> data) override; + void Create(ref_ptr<dp::GraphicsContext> context, Params const & params) override; + void Create(ref_ptr<dp::GraphicsContext> context, Params const & params, + ref_ptr<void> data) override; - void Invalidate(ref_ptr<HWTextureAllocator> allocator); + void Invalidate(ref_ptr<dp::GraphicsContext> context, ref_ptr<HWTextureAllocator> allocator); bool IsLoadingCorrect() const { return m_isLoadingCorrect; } private: - void Fail(); - bool Load(ref_ptr<HWTextureAllocator> allocator); + void Fail(ref_ptr<dp::GraphicsContext> context); + bool Load(ref_ptr<dp::GraphicsContext> context, ref_ptr<HWTextureAllocator> allocator); std::string const m_textureName; std::string const m_skinPathName; diff --git a/drape/stipple_pen_resource.hpp b/drape/stipple_pen_resource.hpp index 57143e1ed4..18f9f294c1 100644 --- a/drape/stipple_pen_resource.hpp +++ b/drape/stipple_pen_resource.hpp @@ -98,7 +98,8 @@ class StipplePenIndex { public: StipplePenIndex(m2::PointU const & canvasSize) : m_packer(canvasSize) {} - ref_ptr<Texture::ResourceInfo> ReserveResource(bool predefined, StipplePenKey const & key, bool & newResource); + ref_ptr<Texture::ResourceInfo> ReserveResource(bool predefined, StipplePenKey const & key, + bool & newResource); ref_ptr<Texture::ResourceInfo> MapResource(StipplePenKey const & key, bool & newResource); void UploadResources(ref_ptr<Texture> texture); @@ -118,15 +119,17 @@ private: std::string DebugPrint(StipplePenHandle const & key); -class StipplePenTexture : public DynamicTexture<StipplePenIndex, StipplePenKey, Texture::ResourceType::StipplePen> +class StipplePenTexture : public DynamicTexture<StipplePenIndex, StipplePenKey, + Texture::ResourceType::StipplePen> { - typedef DynamicTexture<StipplePenIndex, StipplePenKey, Texture::ResourceType::StipplePen> TBase; + using TBase = DynamicTexture<StipplePenIndex, StipplePenKey, Texture::ResourceType::StipplePen>; public: StipplePenTexture(m2::PointU const & size, ref_ptr<HWTextureAllocator> allocator) : m_index(size) { - TBase::TextureParams params{size, TextureFormat::Alpha, TextureFilter::Nearest, false /* m_usePixelBuffer */}; - TBase::Init(allocator, make_ref(&m_index), params); + TBase::DynamicTextureParams params{size, TextureFormat::Alpha, TextureFilter::Nearest, + false /* m_usePixelBuffer */}; + TBase::Init(std::move(allocator), make_ref(&m_index), params); } ~StipplePenTexture() override { TBase::Reset(); } diff --git a/drape/support_manager.cpp b/drape/support_manager.cpp index 2f55082caf..939cc3797f 100644 --- a/drape/support_manager.cpp +++ b/drape/support_manager.cpp @@ -1,5 +1,5 @@ #include "drape/support_manager.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include "platform/settings.hpp" @@ -15,11 +15,11 @@ namespace dp { char const * kSupportedAntialiasing = "Antialiasing"; -void SupportManager::Init() +void SupportManager::Init(ref_ptr<GraphicsContext> context) { - std::string const renderer = GLFunctions::glGetString(gl_const::GLRenderer); - std::string const version = GLFunctions::glGetString(gl_const::GLVersion); - LOG(LINFO, ("Renderer =", renderer, "Api =", GLFunctions::CurrentApiVersion, "Driver version =", version)); + std::string const renderer = context->GetRendererName(); + std::string const version = context->GetRendererVersion(); + LOG(LINFO, ("Renderer =", renderer, "| Api =", context->GetApiVersion(), "| Version =", version)); // On Android the engine may be recreated. Here we guarantee that GPU info is sent once per session. static bool gpuInfoSent = false; @@ -51,8 +51,12 @@ void SupportManager::Init() if (m_isTegra) LOG(LINFO, ("NVidia Tegra device detected.")); - m_maxLineWidth = std::max(1, GLFunctions::glGetMaxLineWidth()); - LOG(LINFO, ("Max line width =", m_maxLineWidth)); + // Metal does not support thick lines. + if (context->GetApiVersion() != dp::ApiVersion::Metal) + { + m_maxLineWidth = std::max(1, GLFunctions::glGetMaxLineWidth()); + LOG(LINFO, ("Max line width =", m_maxLineWidth)); + } // Set up default antialiasing value. // Turn off AA for a while by energy-saving issues. diff --git a/drape/support_manager.hpp b/drape/support_manager.hpp index e7a9df6aa9..71b933a458 100644 --- a/drape/support_manager.hpp +++ b/drape/support_manager.hpp @@ -1,5 +1,8 @@ #pragma once +#include "drape/graphics_context.hpp" +#include "drape/pointers.hpp" + #include "base/macros.hpp" namespace dp @@ -12,8 +15,8 @@ public: // This singleton must be available only from rendering threads. static SupportManager & Instance(); - // Initialization must be called only when OpenGL context is created. - void Init(); + // Initialization must be called only when graphics context is created. + void Init(ref_ptr<GraphicsContext> context); bool IsSamsungGoogleNexus() const { return m_isSamsungGoogleNexus; } bool IsAdreno200Device() const { return m_isAdreno200; } diff --git a/drape/symbols_texture.cpp b/drape/symbols_texture.cpp index 439d51e32d..bb0adc6f22 100644 --- a/drape/symbols_texture.cpp +++ b/drape/symbols_texture.cpp @@ -14,13 +14,16 @@ #include "3party/glm/glm/gtx/bit.hpp" #endif +#include <functional> +#include <utility> + namespace dp { namespace { -using TDefinitionInserter = function<void(string const &, m2::RectF const &)>; -using TSymbolsLoadingCompletion = function<void(unsigned char *, uint32_t, uint32_t)>; -using TSymbolsLoadingFailure = function<void(string const &)>; +using TDefinitionInserter = std::function<void(std::string const &, m2::RectF const &)>; +using TSymbolsLoadingCompletion = std::function<void(unsigned char *, uint32_t, uint32_t)>; +using TSymbolsLoadingFailure = std::function<void(std::string const &)>; class DefinitionLoader { @@ -32,9 +35,9 @@ public: , m_height(0) {} - bool Push(string const & /*element*/) { return true; } + bool Push(std::string const & /*element*/) { return true; } - void Pop(string const & element) + void Pop(std::string const & element) { if (element == "symbol") { @@ -48,7 +51,7 @@ public: } } - void AddAttr(string const & attribute, string const & value) + void AddAttr(std::string const & attribute, std::string const & value) { if (attribute == "name") m_name = value; @@ -93,7 +96,7 @@ public: } } - void CharData(string const &) {} + void CharData(std::string const &) {} uint32_t GetWidth() const { return m_width; } uint32_t GetHeight() const { return m_height; } @@ -105,7 +108,7 @@ private: uint32_t m_width; uint32_t m_height; - string m_name; + std::string m_name; m2::RectF m_rect; }; @@ -126,8 +129,9 @@ void LoadSymbols(std::string const & skinPathName, std::string const & textureNa DefinitionLoader loader(definitionInserter, convertToUV); { - ReaderPtr<Reader> reader = GetStyleReader().GetResourceReader(textureName + ".sdf", skinPathName); - ReaderSource<ReaderPtr<Reader> > source(reader); + ReaderPtr<Reader> reader = + GetStyleReader().GetResourceReader(textureName + ".sdf", skinPathName); + ReaderSource<ReaderPtr<Reader>> source(reader); if (!ParseXML(source, loader)) { failureHandler("Error parsing skin"); @@ -139,7 +143,8 @@ void LoadSymbols(std::string const & skinPathName, std::string const & textureNa } { - ReaderPtr<Reader> reader = GetStyleReader().GetResourceReader(textureName + ".png", skinPathName); + ReaderPtr<Reader> reader = + GetStyleReader().GetResourceReader(textureName + ".png", skinPathName); size_t const size = static_cast<size_t>(reader.Size()); rawData.resize(size); reader.Read(0, &rawData[0], size); @@ -152,7 +157,8 @@ void LoadSymbols(std::string const & skinPathName, std::string const & textureNa } int w, h, bpp; - unsigned char * data = stbi_load_from_memory(&rawData[0], static_cast<int>(rawData.size()), &w, &h, &bpp, 0); + unsigned char * data = + stbi_load_from_memory(&rawData[0], static_cast<int>(rawData.size()), &w, &h, &bpp, 0); ASSERT_EQUAL(bpp, 4, ("Incorrect symbols texture format")); ASSERT(glm::isPowerOfTwo(w), (w)); ASSERT(glm::isPowerOfTwo(h), (h)); @@ -170,7 +176,7 @@ void LoadSymbols(std::string const & skinPathName, std::string const & textureNa } } // namespace -SymbolsTexture::SymbolKey::SymbolKey(string const & symbolName) +SymbolsTexture::SymbolKey::SymbolKey(std::string const & symbolName) : m_symbolName(symbolName) {} @@ -179,7 +185,7 @@ Texture::ResourceType SymbolsTexture::SymbolKey::GetType() const return Texture::ResourceType::Symbol; } -string const & SymbolsTexture::SymbolKey::GetSymbolName() const +std::string const & SymbolsTexture::SymbolKey::GetSymbolName() const { return m_symbolName; } @@ -193,21 +199,22 @@ Texture::ResourceType SymbolsTexture::SymbolInfo::GetType() const return Texture::ResourceType::Symbol; } -SymbolsTexture::SymbolsTexture(std::string const & skinPathName, std::string const & textureName, - ref_ptr<HWTextureAllocator> allocator) +SymbolsTexture::SymbolsTexture(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName, + std::string const & textureName, ref_ptr<HWTextureAllocator> allocator) : m_name(textureName) { - Load(skinPathName, allocator); + Load(std::move(context), skinPathName, std::move(allocator)); } -void SymbolsTexture::Load(std::string const & skinPathName, ref_ptr<HWTextureAllocator> allocator) +void SymbolsTexture::Load(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName, + ref_ptr<HWTextureAllocator> allocator) { - auto definitionInserter = [this](string const & name, m2::RectF const & rect) + auto definitionInserter = [this](std::string const & name, m2::RectF const & rect) { m_definition.insert(std::make_pair(name, SymbolsTexture::SymbolInfo(rect))); }; - auto completionHandler = [this, &allocator](unsigned char * data, uint32_t width, uint32_t height) + auto completionHandler = [this, &allocator, context](unsigned char * data, uint32_t width, uint32_t height) { Texture::Params p; p.m_allocator = allocator; @@ -215,25 +222,26 @@ void SymbolsTexture::Load(std::string const & skinPathName, ref_ptr<HWTextureAll p.m_width = width; p.m_height = height; - Create(p, make_ref(data)); + Create(std::move(context), p, make_ref(data)); }; - auto failureHandler = [this](string const & reason) + auto failureHandler = [this, context](std::string const & reason) { LOG(LERROR, (reason)); - Fail(); + Fail(std::move(context)); }; LoadSymbols(skinPathName, m_name, true /* convertToUV */, definitionInserter, completionHandler, failureHandler); } -void SymbolsTexture::Invalidate(string const & skinPathName, ref_ptr<HWTextureAllocator> allocator) +void SymbolsTexture::Invalidate(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName, + ref_ptr<HWTextureAllocator> allocator) { Destroy(); m_definition.clear(); - Load(skinPathName, allocator); + Load(std::move(context), skinPathName, std::move(allocator)); } ref_ptr<Texture::ResourceInfo> SymbolsTexture::FindResource(Texture::Key const & key, bool & newResource) @@ -242,24 +250,24 @@ ref_ptr<Texture::ResourceInfo> SymbolsTexture::FindResource(Texture::Key const & if (key.GetType() != Texture::ResourceType::Symbol) return nullptr; - string const & symbolName = static_cast<SymbolKey const &>(key).GetSymbolName(); + std::string const & symbolName = static_cast<SymbolKey const &>(key).GetSymbolName(); auto it = m_definition.find(symbolName); ASSERT(it != m_definition.end(), (symbolName)); return make_ref(&it->second); } -void SymbolsTexture::Fail() +void SymbolsTexture::Fail(ref_ptr<dp::GraphicsContext> context) { m_definition.clear(); - int32_t alfaTexture = 0; + int32_t alphaTexture = 0; Texture::Params p; - p.m_allocator = GetDefaultAllocator(); + p.m_allocator = GetDefaultAllocator(context); p.m_format = dp::TextureFormat::RGBA8; p.m_width = 1; p.m_height = 1; - Create(p, make_ref(&alfaTexture)); + Create(context, p, make_ref(&alphaTexture)); } bool SymbolsTexture::IsSymbolContained(std::string const & symbolName) const @@ -269,10 +277,10 @@ bool SymbolsTexture::IsSymbolContained(std::string const & symbolName) const bool SymbolsTexture::DecodeToMemory(std::string const & skinPathName, std::string const & textureName, vector<uint8_t> & symbolsSkin, - std::map<string, m2::RectU> & symbolsIndex, + std::map<std::string, m2::RectU> & symbolsIndex, uint32_t & skinWidth, uint32_t & skinHeight) { - auto definitionInserter = [&symbolsIndex](string const & name, m2::RectF const & rect) + auto definitionInserter = [&symbolsIndex](std::string const & name, m2::RectF const & rect) { symbolsIndex.insert(make_pair(name, m2::RectU(rect))); }; @@ -289,7 +297,7 @@ bool SymbolsTexture::DecodeToMemory(std::string const & skinPathName, std::strin result = true; }; - auto failureHandler = [&result](string const & reason) + auto failureHandler = [&result](std::string const & reason) { LOG(LERROR, (reason)); result = false; diff --git a/drape/symbols_texture.hpp b/drape/symbols_texture.hpp index 9d022d4d37..c18d488b81 100644 --- a/drape/symbols_texture.hpp +++ b/drape/symbols_texture.hpp @@ -2,54 +2,54 @@ #include "drape/texture.hpp" -#include "std/string.hpp" -#include "std/map.hpp" -#include "std/vector.hpp" +#include <map> +#include <string> +#include <vector> namespace dp { - class SymbolsTexture : public Texture { public: class SymbolKey : public Key { public: - SymbolKey(string const & symbolName); - virtual ResourceType GetType() const; - string const & GetSymbolName() const; + explicit SymbolKey(string const & symbolName); + ResourceType GetType() const override; + std::string const & GetSymbolName() const; private: - string m_symbolName; + std::string m_symbolName; }; class SymbolInfo : public ResourceInfo { public: - SymbolInfo(m2::RectF const & texRect); - virtual ResourceType GetType() const; + explicit SymbolInfo(m2::RectF const & texRect); + ResourceType GetType() const override; }; - SymbolsTexture(std::string const & skinPathName, std::string const & textureName, - ref_ptr<HWTextureAllocator> allocator); + SymbolsTexture(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName, + std::string const & textureName, ref_ptr<HWTextureAllocator> allocator); ref_ptr<ResourceInfo> FindResource(Key const & key, bool & newResource) override; - void Invalidate(string const & skinPathName, ref_ptr<HWTextureAllocator> allocator); + void Invalidate(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName, + ref_ptr<HWTextureAllocator> allocator); bool IsSymbolContained(std::string const & symbolName) const; static bool DecodeToMemory(std::string const & skinPathName, std::string const & textureName, - vector<uint8_t> & symbolsSkin, - std::map<string, m2::RectU> & symbolsIndex, + std::vector<uint8_t> & symbolsSkin, + std::map<std::string, m2::RectU> & symbolsIndex, uint32_t & skinWidth, uint32_t & skinHeight); private: - void Fail(); - void Load(std::string const & skinPathName, ref_ptr<HWTextureAllocator> allocator); + void Fail(ref_ptr<dp::GraphicsContext> context); + void Load(ref_ptr<dp::GraphicsContext> context, std::string const & skinPathName, + ref_ptr<HWTextureAllocator> allocator); - using TSymDefinition = map<std::string, SymbolInfo>; + using TSymDefinition = std::map<std::string, SymbolInfo>; std::string m_name; mutable TSymDefinition m_definition; }; - -} // namespace dp +} // namespace dp diff --git a/drape/texture.cpp b/drape/texture.cpp index 3eb0156175..514de5d9ad 100644 --- a/drape/texture.cpp +++ b/drape/texture.cpp @@ -1,7 +1,7 @@ #include "drape/texture.hpp" -#include "drape/glextensions_list.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_extensions_list.hpp" +#include "drape/gl_functions.hpp" #include "drape/glsl_func.hpp" #include "drape/utils/gpu_mem_tracker.hpp" @@ -15,20 +15,19 @@ Texture::ResourceInfo::ResourceInfo(m2::RectF const & texRect) : m_texRect(texRe m2::RectF const & Texture::ResourceInfo::GetTexRect() const { return m_texRect; } -Texture::Texture() {} - Texture::~Texture() { Destroy(); } -void Texture::Create(Params const & params) +void Texture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params) { - if (AllocateTexture(params.m_allocator)) - m_hwTexture->Create(params); + if (AllocateTexture(context, params.m_allocator)) + m_hwTexture->Create(context, params); } -void Texture::Create(Params const & params, ref_ptr<void> data) +void Texture::Create(ref_ptr<dp::GraphicsContext> context, Params const & params, + ref_ptr<void> data) { - if (AllocateTexture(params.m_allocator)) - m_hwTexture->Create(params, data); + if (AllocateTexture(context, params.m_allocator)) + m_hwTexture->Create(context, params, data); } void Texture::UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, @@ -100,14 +99,19 @@ bool Texture::IsPowerOfTwo(uint32_t width, uint32_t height) void Texture::Destroy() { m_hwTexture.reset(); } -bool Texture::AllocateTexture(ref_ptr<HWTextureAllocator> allocator) +bool Texture::AllocateTexture(ref_ptr<dp::GraphicsContext> context, + ref_ptr<HWTextureAllocator> allocator) { if (allocator != nullptr) { - m_hwTexture = allocator->CreateTexture(); + m_hwTexture = allocator->CreateTexture(std::move(context)); return true; } - return false; } + +ref_ptr<HWTexture> Texture::GetHardwareTexture() const +{ + return make_ref(m_hwTexture); +} } // namespace dp diff --git a/drape/texture.hpp b/drape/texture.hpp index 8dff145036..ed6b58b594 100644 --- a/drape/texture.hpp +++ b/drape/texture.hpp @@ -1,5 +1,6 @@ #pragma once +#include "drape/graphics_context.hpp" #include "drape/hw_texture.hpp" #include "drape/pointers.hpp" #include "drape/texture_types.hpp" @@ -44,11 +45,11 @@ public: m2::RectF m_texRect; }; - Texture(); + Texture() = default; virtual ~Texture(); virtual ref_ptr<ResourceInfo> FindResource(Key const & key, bool & newResource) = 0; - virtual void UpdateState() {} + virtual void UpdateState(ref_ptr<dp::GraphicsContext> context) {} virtual bool HasEnoughSpace(uint32_t /* newKeysCount */) const { return true; } using Params = HWTexture::Params; @@ -64,16 +65,21 @@ public: // Texture must be bound before calling this method. virtual void SetFilter(TextureFilter filter); - virtual void Create(Params const & params); - virtual void Create(Params const & params, ref_ptr<void> data); - void UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, ref_ptr<void> data); + virtual void Create(ref_ptr<dp::GraphicsContext> context, Params const & params); + virtual void Create(ref_ptr<dp::GraphicsContext> context, Params const & params, + ref_ptr<void> data); + void UploadData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, + ref_ptr<void> data); + + ref_ptr<HWTexture> GetHardwareTexture() const; static uint32_t GetMaxTextureSize(); static bool IsPowerOfTwo(uint32_t width, uint32_t height); protected: void Destroy(); - bool AllocateTexture(ref_ptr<HWTextureAllocator> allocator); + bool AllocateTexture(ref_ptr<dp::GraphicsContext> context, + ref_ptr<HWTextureAllocator> allocator); drape_ptr<HWTexture> m_hwTexture; diff --git a/drape/texture_manager.cpp b/drape/texture_manager.cpp index 71cf970617..e8f1f68934 100644 --- a/drape/texture_manager.cpp +++ b/drape/texture_manager.cpp @@ -4,7 +4,7 @@ #include "drape/static_texture.hpp" #include "drape/stipple_pen_resource.hpp" #include "drape/texture_of_colors.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include "drape/utils/glyph_usage_tracker.hpp" #include "platform/platform.hpp" @@ -255,32 +255,42 @@ void TextureManager::Release() m_nothingToUpload.test_and_set(); } -bool TextureManager::UpdateDynamicTextures() +bool TextureManager::UpdateDynamicTextures(ref_ptr<dp::GraphicsContext> context) { - // For some reasons OpenGL can not update textures immediately. - // Here we use some timeout to allow to do it. - double const kUploadTimeoutInSeconds = 2.0; - if (!HasAsyncRoutines() && m_nothingToUpload.test_and_set()) - return m_uploadTimer.ElapsedSeconds() < kUploadTimeoutInSeconds; + { + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) + { + // For some reasons OpenGL can not update textures immediately. + // Here we use some timeout to prevent rendering frozening. + double const kUploadTimeoutInSeconds = 2.0; + return m_uploadTimer.ElapsedSeconds() < kUploadTimeoutInSeconds; + } + + if (apiVersion == dp::ApiVersion::Metal) + return false; + + CHECK(false, ("Unsupported API version.")); + } m_uploadTimer.Reset(); - m_colorTexture->UpdateState(); - m_stipplePenTexture->UpdateState(); + m_colorTexture->UpdateState(context); + m_stipplePenTexture->UpdateState(context); - UpdateGlyphTextures(); + UpdateGlyphTextures(context); m_textureAllocator->Flush(); return true; } -void TextureManager::UpdateGlyphTextures() +void TextureManager::UpdateGlyphTextures(ref_ptr<dp::GraphicsContext> context) { std::lock_guard<std::mutex> lock(m_glyphTexturesMutex); for (auto & texture : m_glyphTextures) - texture->UpdateState(); + texture->UpdateState(context); } bool TextureManager::HasAsyncRoutines() const @@ -461,34 +471,42 @@ size_t TextureManager::FindHybridGlyphsGroup(TMultilineText const & text, int fi return FindHybridGlyphsGroup(combinedString, fixedHeight); } -void TextureManager::Init(Params const & params) +void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & params) { m_resPostfix = params.m_resPostfix; - m_textureAllocator = CreateAllocator(); - - m_maxTextureSize = std::min(kMaxTextureSize, - static_cast<uint32_t>(GLFunctions::glGetInteger(gl_const::GLMaxTextureSize))); + m_textureAllocator = CreateAllocator(context); - GLFunctions::glPixelStore(gl_const::GLUnpackAlignment, 1); + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) + { + m_maxTextureSize = std::min(kMaxTextureSize, + static_cast<uint32_t>(GLFunctions::glGetInteger(gl_const::GLMaxTextureSize))); + GLFunctions::glPixelStore(gl_const::GLUnpackAlignment, 1); + } + else + { + m_maxTextureSize = kMaxTextureSize; + } // Initialize symbols. for (size_t i = 0; i < ARRAY_SIZE(kSymbolTextures); ++i) { - m_symbolTextures.push_back(make_unique_dp<SymbolsTexture>(m_resPostfix, kSymbolTextures[i], + m_symbolTextures.push_back(make_unique_dp<SymbolsTexture>(context, m_resPostfix, kSymbolTextures[i], make_ref(m_textureAllocator))); } // Initialize static textures. - m_trafficArrowTexture = make_unique_dp<StaticTexture>("traffic-arrow", m_resPostfix, + m_trafficArrowTexture = make_unique_dp<StaticTexture>(context, "traffic-arrow", m_resPostfix, dp::TextureFormat::RGBA8, make_ref(m_textureAllocator)); - m_hatchingTexture = make_unique_dp<StaticTexture>("area-hatching", m_resPostfix, + m_hatchingTexture = make_unique_dp<StaticTexture>(context, "area-hatching", m_resPostfix, dp::TextureFormat::RGBA8, make_ref(m_textureAllocator)); - if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3) + // SMAA is not supported on OpenGL ES2. + if (apiVersion != dp::ApiVersion::OpenGLES2) { - m_smaaAreaTexture = make_unique_dp<StaticTexture>("smaa-area", StaticTexture::kDefaultResource, + m_smaaAreaTexture = make_unique_dp<StaticTexture>(context, "smaa-area", StaticTexture::kDefaultResource, dp::TextureFormat::RedGreen, make_ref(m_textureAllocator)); - m_smaaSearchTexture = make_unique_dp<StaticTexture>("smaa-search", StaticTexture::kDefaultResource, + m_smaaSearchTexture = make_unique_dp<StaticTexture>(context, "smaa-search", StaticTexture::kDefaultResource, dp::TextureFormat::Alpha, make_ref(m_textureAllocator)); } @@ -554,7 +572,7 @@ void TextureManager::Init(Params const & params) m_nothingToUpload.clear(); } -void TextureManager::OnSwitchMapStyle() +void TextureManager::OnSwitchMapStyle(ref_ptr<dp::GraphicsContext> context) { // Here we need invalidate only textures which can be changed in map style switch. for (size_t i = 0; i < m_symbolTextures.size(); ++i) @@ -562,7 +580,7 @@ void TextureManager::OnSwitchMapStyle() ASSERT(m_symbolTextures[i] != nullptr, ()); ASSERT(dynamic_cast<SymbolsTexture *>(m_symbolTextures[i].get()) != nullptr, ()); ref_ptr<SymbolsTexture> symbolsTexture = make_ref(m_symbolTextures[i]); - symbolsTexture->Invalidate(m_resPostfix, make_ref(m_textureAllocator)); + symbolsTexture->Invalidate(context, m_resPostfix, make_ref(m_textureAllocator)); } // Uncomment if static textures can be changed. @@ -573,7 +591,7 @@ void TextureManager::OnSwitchMapStyle() // ASSERT(staticTextures[i] != nullptr, ()); // ASSERT(dynamic_cast<StaticTexture *>(staticTextures[i].get()) != nullptr, ()); // ref_ptr<StaticTexture> t = staticTextures[i]; - // t->Invalidate(make_ref(m_textureAllocator)); + // t->Invalidate(context, make_ref(m_textureAllocator)); //} } diff --git a/drape/texture_manager.hpp b/drape/texture_manager.hpp index 07b637bfe1..d4ebe155f7 100644 --- a/drape/texture_manager.hpp +++ b/drape/texture_manager.hpp @@ -83,8 +83,8 @@ public: explicit TextureManager(ref_ptr<GlyphGenerator> glyphGenerator); void Release(); - void Init(Params const & params); - void OnSwitchMapStyle(); + void Init(ref_ptr<dp::GraphicsContext> context, Params const & params); + void OnSwitchMapStyle(ref_ptr<dp::GraphicsContext> context); void GetSymbolRegion(std::string const & symbolName, SymbolRegion & region); bool HasSymbolRegion(std::string const & symbolName) const; @@ -106,7 +106,8 @@ public: // and use this texture to render on another thread. By this we move UpdateDynamicTextures call // into render thread. If you implement some kind of dynamic texture, you must synchronize UploadData // and index creation operations. - bool UpdateDynamicTextures(); + // The result of the method shows if there are some changes in texture manager. + bool UpdateDynamicTextures(ref_ptr<dp::GraphicsContext> context); ref_ptr<Texture> GetSymbolsTexture() const; ref_ptr<Texture> GetTrafficArrowTexture() const; @@ -227,7 +228,7 @@ private: uint32_t GetAbsentGlyphsCount(ref_ptr<Texture> texture, TMultilineText const & text, int fixedHeight) const; - void UpdateGlyphTextures(); + void UpdateGlyphTextures(ref_ptr<dp::GraphicsContext> context); bool HasAsyncRoutines() const; static constexpr size_t GetInvalidGlyphGroup(); diff --git a/drape/texture_of_colors.hpp b/drape/texture_of_colors.hpp index c204882d89..01c4b8f4ec 100644 --- a/drape/texture_of_colors.hpp +++ b/drape/texture_of_colors.hpp @@ -39,7 +39,7 @@ public: void SetIsDebug(bool isDebug) { m_isDebug = isDebug; } private: - typedef std::map<Color, ColorResourceInfo> TPalette; + using TPalette = std::map<Color, ColorResourceInfo>; struct PendingColor { @@ -59,18 +59,19 @@ private: class ColorTexture : public DynamicTexture<ColorPalette, ColorKey, Texture::ResourceType::Color> { - typedef DynamicTexture<ColorPalette, ColorKey, Texture::ResourceType::Color> TBase; + using TBase = DynamicTexture<ColorPalette, ColorKey, Texture::ResourceType::Color>; public: ColorTexture(m2::PointU const & size, ref_ptr<HWTextureAllocator> allocator) : m_palette(size) { - TBase::TextureParams params{size, TextureFormat::RGBA8, TextureFilter::Nearest, false /* m_usePixelBuffer */}; + TBase::DynamicTextureParams params{size, TextureFormat::RGBA8, TextureFilter::Nearest, + false /* m_usePixelBuffer */}; TBase::Init(allocator, make_ref(&m_palette), params); } void ReserveColor(dp::Color const & color); - ~ColorTexture() { TBase::Reset(); } + ~ColorTexture() override { TBase::Reset(); } static int GetColorSizeInPixels(); diff --git a/drape/uniform_value.cpp b/drape/uniform_value.cpp index c2896d0e32..5f35aeb0d2 100644 --- a/drape/uniform_value.cpp +++ b/drape/uniform_value.cpp @@ -1,5 +1,5 @@ #include "drape/uniform_value.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" namespace dp { diff --git a/drape/vertex_array_buffer.cpp b/drape/vertex_array_buffer.cpp index aeea0b67f8..a1c26b0818 100644 --- a/drape/vertex_array_buffer.cpp +++ b/drape/vertex_array_buffer.cpp @@ -1,7 +1,7 @@ #include "drape/vertex_array_buffer.hpp" -#include "drape/glextensions_list.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_extensions_list.hpp" +#include "drape/gl_functions.hpp" #include "drape/index_storage.hpp" #include "drape/support_manager.hpp" @@ -34,7 +34,6 @@ std::pair<uint32_t, uint32_t> CalculateMappingPart(std::vector<dp::MutateNode> c VertexArrayBuffer::VertexArrayBuffer(uint32_t indexBufferSize, uint32_t dataBufferSize) : m_VAO(0) , m_dataBufferSize(dataBufferSize) - , m_program() , m_isPreflushed(false) , m_moveToGpuOnBuild(false) , m_isChanged(false) @@ -97,7 +96,7 @@ 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")); + ASSERT(m_program != nullptr, ("Build must be called before RenderRange")); // If OES_vertex_array_object is supported than all bindings have already saved in VAO // and we need only bind VAO. if (!Bind()) @@ -118,7 +117,7 @@ void VertexArrayBuffer::Build(ref_ptr<GpuProgram> program) if (m_moveToGpuOnBuild && !m_isPreflushed) PreflushImpl(); - if (m_VAO != 0 && m_program == program) + if (m_VAO != 0 && m_program.get() == program.get()) return; m_program = program; diff --git a/drape/vertex_array_buffer.hpp b/drape/vertex_array_buffer.hpp index 49fc1c67e2..e5057e90af 100644 --- a/drape/vertex_array_buffer.hpp +++ b/drape/vertex_array_buffer.hpp @@ -3,18 +3,13 @@ #include "drape/attribute_buffer_mutator.hpp" #include "drape/binding_info.hpp" #include "drape/data_buffer.hpp" -#include "drape/gpu_program.hpp" +#include "drape/gl_gpu_program.hpp" #include "drape/index_buffer.hpp" #include "drape/index_buffer_mutator.hpp" #include "drape/pointers.hpp" #include <map> -namespace df -{ -class BatchMergeHelper; -} - namespace dp { struct IndicesRange @@ -30,13 +25,11 @@ struct IndicesRange class VertexArrayBuffer { 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 transfered on render thread. + // This method must be called on a reading thread, before VAO will be transferred to the render thread. void Preflush(); // OES_vertex_array_object create OpenGL resource that belong only one GL context (which was @@ -60,6 +53,7 @@ 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); @@ -77,8 +71,6 @@ private: void PreflushImpl(); -private: - // m_VAO - VertexArrayObject name/identifier. int m_VAO; BuffersMap m_staticBuffers; BuffersMap m_dynamicBuffers; @@ -86,7 +78,7 @@ private: drape_ptr<IndexBuffer> m_indexBuffer; uint32_t m_dataBufferSize; - ref_ptr<GpuProgram> m_program; + ref_ptr<GLGpuProgram> m_program; bool m_isPreflushed; bool m_moveToGpuOnBuild; diff --git a/drape/viewport.cpp b/drape/viewport.cpp index f36b1b6cc1..489fc5201f 100644 --- a/drape/viewport.cpp +++ b/drape/viewport.cpp @@ -1,11 +1,12 @@ #include "drape/viewport.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.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) -{ -} +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) { @@ -14,12 +15,15 @@ void Viewport::SetViewport(uint32_t x0, uint32_t y0, uint32_t w, uint32_t 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 + +void Viewport::Apply(ref_ptr<dp::GraphicsContext> context) const { - GLCHECK(GLFunctions::glViewport(GetX0(), GetY0(), GetWidth(), GetHeight())); - GLCHECK(GLFunctions::glScissor(GetX0(), GetY0(), GetWidth(), GetHeight())); + context->SetViewport(GetX0(), GetY0(), GetWidth(), GetHeight()); } } // namespace dp diff --git a/drape/viewport.hpp b/drape/viewport.hpp index 65dcffffa3..2db5820740 100644 --- a/drape/viewport.hpp +++ b/drape/viewport.hpp @@ -1,5 +1,7 @@ #pragma once +#include "drape/graphics_context.hpp" + #include "geometry/point2d.hpp" namespace dp @@ -22,7 +24,7 @@ public: uint32_t GetHeight() const; // Apply viewport to graphics pipeline with convert start point and size to physical pixels. - void Apply() const; + void Apply(ref_ptr<dp::GraphicsContext> context) const; private: m2::PointU m_zero; diff --git a/drape_frontend/animation/linear_animation.hpp b/drape_frontend/animation/linear_animation.hpp index df3f9def49..2f65480a38 100644 --- a/drape_frontend/animation/linear_animation.hpp +++ b/drape_frontend/animation/linear_animation.hpp @@ -5,7 +5,6 @@ namespace df { - class MapLinearAnimation : public Animation { public: @@ -14,7 +13,7 @@ public: double startScale, double endScale, ScreenBase const & convertor); MapLinearAnimation(); - void Init(const ScreenBase &screen, const TPropertyCache &properties) override; + void Init(ScreenBase const & screen, TPropertyCache const & properties) override; void SetMove(m2::PointD const & startPos, m2::PointD const & endPos, ScreenBase const & convertor); void SetMove(m2::PointD const & startPos, m2::PointD const & endPos, m2::RectD const & viewportRect, double scale); @@ -60,5 +59,4 @@ private: TObjectProperties m_properties; TAnimObjects m_objects; }; - -} // namespace df +} // namespace df diff --git a/drape_frontend/arrow3d.cpp b/drape_frontend/arrow3d.cpp index a33eb37c63..12fde6461e 100644 --- a/drape_frontend/arrow3d.cpp +++ b/drape_frontend/arrow3d.cpp @@ -29,9 +29,9 @@ df::ColorConstant const kArrow3DObsoleteColor = "Arrow3DObsolete"; df::ColorConstant const kArrow3DColor = "Arrow3D"; df::ColorConstant const kArrow3DOutlineColor = "Arrow3DOutline"; -Arrow3d::Arrow3d() - : m_arrowMesh(dp::MeshObject::DrawPrimitive::Triangles) - , m_shadowMesh(dp::MeshObject::DrawPrimitive::Triangles) +Arrow3d::Arrow3d(ref_ptr<dp::GraphicsContext> context) + : m_arrowMesh(context, dp::MeshObject::DrawPrimitive::Triangles) + , m_shadowMesh(context, dp::MeshObject::DrawPrimitive::Triangles) , m_state(CreateRenderState(gpu::Program::Arrow3d, DepthLayer::OverlayLayer)) { m_state.SetDepthTestEnabled(false); @@ -126,6 +126,7 @@ 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/arrow3d.hpp b/drape_frontend/arrow3d.hpp index 476f32f514..97b5e2f619 100644 --- a/drape_frontend/arrow3d.hpp +++ b/drape_frontend/arrow3d.hpp @@ -28,7 +28,7 @@ class Arrow3d { using Base = dp::MeshObject; public: - Arrow3d(); + explicit Arrow3d(ref_ptr<dp::GraphicsContext> context); void SetPosition(m2::PointD const & position); void SetAzimuth(double azimuth); diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index ea53a92aab..2d1eac7cf2 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -347,7 +347,7 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message) case Message::Type::SwitchMapStyle: { - m_texMng->OnSwitchMapStyle(); + m_texMng->OnSwitchMapStyle(make_ref(m_contextFactory->GetResourcesUploadContext())); RecacheMapShapes(); RecacheGui(m_lastWidgetsInfo, false /* needResetOldGui */); #ifdef RENDER_DEBUG_INFO_LABELS @@ -606,10 +606,6 @@ void BackendRenderer::OnContextCreate() context->MakeCurrent(); context->Init(m_apiVersion); - // TODO: Temporary code. - if (m_apiVersion == dp::ApiVersion::Metal) - return; - m_readManager->Start(); InitGLDependentResource(); } @@ -669,7 +665,7 @@ void BackendRenderer::InitGLDependentResource() params.m_glyphMngParams.m_baseGlyphHeight = VisualParams::Instance().GetGlyphBaseSize(); GetPlatform().GetFontNames(params.m_glyphMngParams.m_fonts); - m_texMng->Init(params); + m_texMng->Init(make_ref(m_contextFactory->GetResourcesUploadContext()), params); // Send some textures to frontend renderer. drape_ptr<PostprocessStaticTextures> textures = make_unique_dp<PostprocessStaticTextures>(); diff --git a/drape_frontend/debug_rect_renderer.cpp b/drape_frontend/debug_rect_renderer.cpp index 0602e30ff0..a269cd358a 100644 --- a/drape_frontend/debug_rect_renderer.cpp +++ b/drape_frontend/debug_rect_renderer.cpp @@ -17,16 +17,17 @@ void PixelPointToScreenSpace(ScreenBase const & screen, m2::PointF const & pt, s } } // namespace -DebugRectRenderer::DebugRectRenderer(ref_ptr<dp::GpuProgram> program, ref_ptr<gpu::ProgramParamsSetter> paramsSetter) - : Base(DrawPrimitive::LineStrip) - , m_program(program) - , m_paramsSetter(paramsSetter) +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)) , m_state(CreateRenderState(gpu::Program::DebugRect, DepthLayer::OverlayLayer)) { m_state.SetDepthTestEnabled(false); Base::SetBuffer(0 /* bufferInd */, {} /* vertices */, static_cast<uint32_t>(sizeof(float) * 2)); - Base::SetAttribute("a_position", 0 /* bufferInd */, 0.0f /* offset */, 2 /* componentsCount */); + Base::SetAttribute("a_position", 0 /* bufferInd */, 0 /* offset */, 2 /* componentsCount */); } bool DebugRectRenderer::IsEnabled() const @@ -39,8 +40,8 @@ void DebugRectRenderer::SetEnabled(bool enabled) m_isEnabled = enabled; } -void DebugRectRenderer::SetArrow(m2::PointF const & arrowStart, m2::PointF const & arrowEnd, - ScreenBase const & screen) +void DebugRectRenderer::SetArrow(ref_ptr<dp::GraphicsContext> context, m2::PointF const & arrowStart, + m2::PointF const & arrowEnd, ScreenBase const & screen) { std::vector<float> vertices; m2::PointF const dir = (arrowEnd - arrowStart).Normalize(); @@ -52,11 +53,12 @@ void DebugRectRenderer::SetArrow(m2::PointF const & arrowStart, m2::PointF const PixelPointToScreenSpace(screen, arrowEnd - dir * 20 - side * 10, vertices); if (!Base::IsInitialized()) - Base::Build(m_program); + Base::Build(std::move(context), m_program); Base::UpdateBuffer(0 /* bufferInd */, std::move(vertices)); } -void DebugRectRenderer::SetRect(m2::RectF const & rect, ScreenBase const & screen) +void DebugRectRenderer::SetRect(ref_ptr<dp::GraphicsContext> context, m2::RectF const & rect, + ScreenBase const & screen) { std::vector<float> vertices; PixelPointToScreenSpace(screen, rect.LeftBottom(), vertices); @@ -66,7 +68,7 @@ void DebugRectRenderer::SetRect(m2::RectF const & rect, ScreenBase const & scree PixelPointToScreenSpace(screen, rect.LeftBottom(), vertices); if (!Base::IsInitialized()) - Base::Build(m_program); + Base::Build(std::move(context), m_program); Base::UpdateBuffer(0 /* bufferInd */, std::move(vertices)); } @@ -76,7 +78,7 @@ void DebugRectRenderer::DrawRect(ref_ptr<dp::GraphicsContext> context, ScreenBas if (!m_isEnabled) return; - SetRect(rect, screen); + SetRect(context, rect, screen); gpu::DebugRectProgramParams params; params.m_color = glsl::ToVec4(color); @@ -93,7 +95,7 @@ void DebugRectRenderer::DrawArrow(ref_ptr<dp::GraphicsContext> context, ScreenBa if (data.m_arrowStart.EqualDxDy(data.m_arrowEnd, 1e-5f)) return; - SetArrow(data.m_arrowStart, data.m_arrowEnd, screen); + SetArrow(context, data.m_arrowStart, data.m_arrowEnd, screen); gpu::DebugRectProgramParams params; params.m_color = glsl::ToVec4(data.m_arrowColor); diff --git a/drape_frontend/debug_rect_renderer.hpp b/drape_frontend/debug_rect_renderer.hpp index 39eb57fc30..f9edee902d 100644 --- a/drape_frontend/debug_rect_renderer.hpp +++ b/drape_frontend/debug_rect_renderer.hpp @@ -16,7 +16,8 @@ class DebugRectRenderer: public dp::MeshObject, public dp::DebugRenderer { using Base = dp::MeshObject; public: - DebugRectRenderer(ref_ptr<dp::GpuProgram> program, ref_ptr<gpu::ProgramParamsSetter> paramsSetter); + DebugRectRenderer(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program, + ref_ptr<gpu::ProgramParamsSetter> paramsSetter); void SetEnabled(bool enabled); @@ -27,8 +28,10 @@ public: dp::OverlayTree::DisplacementData const & data) override; private: - void SetArrow(m2::PointF const & arrowStart, m2::PointF const & arrowEnd, ScreenBase const & screen); - void SetRect(m2::RectF const & rect, ScreenBase const & screen); + void SetArrow(ref_ptr<dp::GraphicsContext> context, m2::PointF const & arrowStart, + m2::PointF const & arrowEnd, ScreenBase const & screen); + void SetRect(ref_ptr<dp::GraphicsContext> context, m2::RectF const & rect, + ScreenBase const & screen); ref_ptr<dp::GpuProgram> m_program; ref_ptr<gpu::ProgramParamsSetter> m_paramsSetter; diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 13e3fa885b..14cf948eb4 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -128,6 +128,7 @@ FrontendRenderer::FrontendRenderer(Params && params) , m_forceUpdateScene(false) , m_forceUpdateUserMarks(false) , m_postprocessRenderer(new PostprocessRenderer()) + , m_enabledOnStartEffects(params.m_enabledEffects) #ifdef SCENARIO_ENABLE , m_scenarioManager(new ScenarioManager(this)) #endif @@ -159,11 +160,6 @@ FrontendRenderer::FrontendRenderer(Params && params) m_myPositionController = make_unique_dp<MyPositionController>( std::move(params.m_myPositionParams), make_ref(m_notifier)); -#ifndef OMIM_OS_IPHONE_SIMULATOR - for (auto const & effect : params.m_enabledEffects) - m_postprocessRenderer->SetEffectEnabled(effect, true /* enabled */); -#endif - StartThread(); } @@ -212,10 +208,6 @@ void FrontendRenderer::UpdateCanBeDeletedStatus() void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) { - // TODO: Temporary code. - if (m_apiVersion == dp::ApiVersion::Metal) - return; - switch (message->GetType()) { case Message::Type::FlushTile: @@ -351,7 +343,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) case Message::Type::MapShapes: { ref_ptr<MapShapesMessage> msg = message; - m_myPositionController->SetRenderShape(msg->AcceptShape()); + m_myPositionController->SetRenderShape(make_ref(m_contextFactory->GetDrawContext()), + m_texMng, msg->AcceptShape()); m_selectionShape = msg->AcceptSelection(); if (m_selectObjectMessage != nullptr) { @@ -502,7 +495,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) m_routeRenderer->Clear(); ++m_lastRecacheRouteId; m_myPositionController->DeactivateRouting(); - m_postprocessRenderer->OnChangedRouteFollowingMode(false /* active */); + m_postprocessRenderer->OnChangedRouteFollowingMode(make_ref(m_contextFactory->GetDrawContext()), + false /* active */); if (m_enablePerspectiveInNavigation) DisablePerspective(); } @@ -534,7 +528,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) case Message::Type::DeactivateRouteFollowing: { m_myPositionController->DeactivateRouting(); - m_postprocessRenderer->OnChangedRouteFollowingMode(false /* active */); + m_postprocessRenderer->OnChangedRouteFollowingMode(make_ref(m_contextFactory->GetDrawContext()), + false /* active */); if (m_enablePerspectiveInNavigation) DisablePerspective(); break; @@ -587,7 +582,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) } // Must be recreated on map style changing. - m_transitBackground.reset(new ScreenQuadRenderer()); + m_transitBackground = + make_unique_dp<ScreenQuadRenderer>(make_ref(m_contextFactory->GetDrawContext())); // Invalidate read manager. { @@ -752,7 +748,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) ref_ptr<EnableTransitSchemeMessage > msg = message; m_transitSchemeEnabled = msg->IsEnabled(); #ifndef OMIM_OS_IPHONE_SIMULATOR - m_postprocessRenderer->SetEffectEnabled(PostprocessRenderer::Effect::Antialiasing, + m_postprocessRenderer->SetEffectEnabled(make_ref(m_contextFactory->GetDrawContext()), + PostprocessRenderer::Effect::Antialiasing, msg->IsEnabled() ? true : m_isAntialiasingEnabled); #endif if (!msg->IsEnabled()) @@ -862,7 +859,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) if (msg->GetEffect() == PostprocessRenderer::Effect::Antialiasing) m_isAntialiasingEnabled = msg->IsEnabled(); #ifndef OMIM_OS_IPHONE_SIMULATOR - m_postprocessRenderer->SetEffectEnabled(msg->GetEffect(), msg->IsEnabled()); + m_postprocessRenderer->SetEffectEnabled(make_ref(m_contextFactory->GetDrawContext()), + msg->GetEffect(), msg->IsEnabled()); #endif break; } @@ -961,7 +959,8 @@ void FrontendRenderer::FollowRoute(int preferredZoomLevel, int preferredZoomLeve AddUserEvent(make_unique_dp<SetAutoPerspectiveEvent>(true /* isAutoPerspective */)); m_routeRenderer->SetFollowingEnabled(true); - m_postprocessRenderer->OnChangedRouteFollowingMode(true /* active */); + m_postprocessRenderer->OnChangedRouteFollowingMode(make_ref(m_contextFactory->GetDrawContext()), + true /* active */); } bool FrontendRenderer::CheckRouteRecaching(ref_ptr<BaseSubrouteData> subrouteData) @@ -1033,9 +1032,10 @@ void FrontendRenderer::OnResize(ScreenBase const & screen) if (viewportChanged || m_needRestoreSize) { - m_contextFactory->GetDrawContext()->Resize(sx, sy); - m_buildingsFramebuffer->SetSize(sx, sy); - m_postprocessRenderer->Resize(sx, sy); + auto context = make_ref(m_contextFactory->GetDrawContext()); + context->Resize(sx, sy); + m_buildingsFramebuffer->SetSize(context, sx, sy); + m_postprocessRenderer->Resize(context, sx, sy); m_needRestoreSize = false; } @@ -1214,9 +1214,6 @@ void FrontendRenderer::EndUpdateOverlayTree() void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFrame) { - // TODO: Temporary code. - if (m_apiVersion == dp::ApiVersion::Metal) - return; #if defined(DRAPE_MEASURER) && (defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM)) DrapeMeasurer::Instance().BeforeRenderFrame(); #endif @@ -1225,9 +1222,10 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram if (m_postprocessRenderer->BeginFrame(context, activeFrame)) { - m_viewport.Apply(); RefreshBgColor(); context->Clear(dp::ClearBits::ColorBit | dp::ClearBits::DepthBit | dp::ClearBits::StencilBit); + context->ApplyFramebuffer("Static frame"); + m_viewport.Apply(context); Render2dLayer(modelView); RenderUserMarksLayer(modelView, DepthLayer::UserLineLayer); @@ -1300,7 +1298,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram m_debugRectRenderer->DrawArrow(context, modelView, arrow); } - if (!m_postprocessRenderer->EndFrame(context, make_ref(m_gpuProgramManager))) + if (!m_postprocessRenderer->EndFrame(context, make_ref(m_gpuProgramManager), m_viewport)) return; m_myPositionController->Render(context, make_ref(m_gpuProgramManager), modelView, m_currentZoomLevel, @@ -1338,9 +1336,11 @@ void FrontendRenderer::Render3dLayer(ScreenBase const & modelView, bool useFrame if (useFramebuffer) { ASSERT(m_buildingsFramebuffer->IsSupported(), ()); - m_buildingsFramebuffer->Enable(); + context->SetFramebuffer(make_ref(m_buildingsFramebuffer)); context->SetClearColor(dp::Color::Transparent()); context->Clear(dp::ClearBits::ColorBit | dp::ClearBits::DepthBit); + context->ApplyFramebuffer("Buildings"); + m_viewport.Apply(context); } else { @@ -1353,7 +1353,7 @@ void FrontendRenderer::Render3dLayer(ScreenBase const & modelView, bool useFrame if (useFramebuffer) { - m_buildingsFramebuffer->Disable(); + m_buildingsFramebuffer->ApplyFallback(); m_screenQuadRenderer->RenderTexture(context, make_ref(m_gpuProgramManager), m_buildingsFramebuffer->GetTexture(), kOpacity); @@ -1474,12 +1474,12 @@ void FrontendRenderer::RenderEmptyFrame() if (!context->Validate()) return; - context->SetDefaultFramebuffer(); - + context->SetFramebuffer(nullptr /* default */); auto const c = dp::Extract(drule::rules().GetBgColor(1 /* scale */), 255); context->SetClearColor(c); - m_viewport.Apply(); context->Clear(dp::ClearBits::ColorBit); + context->ApplyFramebuffer("Empty frame"); + m_viewport.Apply(context); context->Present(); } @@ -1897,47 +1897,49 @@ void FrontendRenderer::OnContextCreate() // Render empty frame here to avoid black initialization screen. RenderEmptyFrame(); - // TODO: Temporary code. - if (m_apiVersion == dp::ApiVersion::Metal) - return; - - dp::SupportManager::Instance().Init(); + dp::SupportManager::Instance().Init(context); m_gpuProgramManager = make_unique_dp<gpu::ProgramManager>(); - m_gpuProgramManager->Init(m_apiVersion); + m_gpuProgramManager->Init(context); - dp::AlphaBlendingState::Apply(); + dp::AlphaBlendingState::Apply(context); - m_debugRectRenderer = make_unique<DebugRectRenderer>(m_gpuProgramManager->GetProgram(gpu::Program::DebugRect), - m_gpuProgramManager->GetParamsSetter()); + m_debugRectRenderer = make_unique<DebugRectRenderer>( + context, m_gpuProgramManager->GetProgram(gpu::Program::DebugRect), + m_gpuProgramManager->GetParamsSetter()); m_debugRectRenderer->SetEnabled(m_isDebugRectRenderingEnabled); m_overlayTree->SetDebugRectRenderer(make_ref(m_debugRectRenderer)); // Resources recovering. - m_screenQuadRenderer = make_unique_dp<ScreenQuadRenderer>(); + m_screenQuadRenderer = make_unique_dp<ScreenQuadRenderer>(context); - m_postprocessRenderer->Init(m_apiVersion, [context]() + m_postprocessRenderer->Init(context, [context]() { if (!context->Validate()) return false; - context->SetDefaultFramebuffer(); + context->SetFramebuffer(nullptr /* default */); return true; }); + #ifndef OMIM_OS_IPHONE_SIMULATOR + for (auto const & effect : m_enabledOnStartEffects) + m_postprocessRenderer->SetEffectEnabled(context, effect, true /* enabled */); + m_enabledOnStartEffects.clear(); + if (dp::SupportManager::Instance().IsAntialiasingEnabledByDefault()) - m_postprocessRenderer->SetEffectEnabled(PostprocessRenderer::Antialiasing, true); + m_postprocessRenderer->SetEffectEnabled(context, PostprocessRenderer::Antialiasing, true); #endif m_buildingsFramebuffer = make_unique_dp<dp::Framebuffer>(dp::TextureFormat::RGBA8, true /* depthEnabled */, false /* stencilEnabled */); - m_buildingsFramebuffer->SetFramebufferFallback([this]() + m_buildingsFramebuffer->SetFramebufferFallback([this, context]() { - return m_postprocessRenderer->OnFramebufferFallback(); + return m_postprocessRenderer->OnFramebufferFallback(context); }); - m_transitBackground = make_unique_dp<ScreenQuadRenderer>(); + m_transitBackground = make_unique_dp<ScreenQuadRenderer>(context); } FrontendRenderer::Routine::Routine(FrontendRenderer & renderer) : m_renderer(renderer) {} @@ -1996,7 +1998,7 @@ void FrontendRenderer::Routine::Do() if (isActiveFrame) m_renderer.PrepareScene(modelView); - isActiveFrame |= m_renderer.m_texMng->UpdateDynamicTextures(); + isActiveFrame |= m_renderer.m_texMng->UpdateDynamicTextures(context); isActiveFrame |= m_renderer.m_userEventStream.IsWaitingForActionCompletion(); isActiveFrame |= InterpolationHolder::Instance().IsActive(); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 4a19358193..a4b63d34bb 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -333,6 +333,7 @@ private: bool m_isAntialiasingEnabled = false; drape_ptr<PostprocessRenderer> m_postprocessRenderer; + std::vector<PostprocessRenderer::Effect> m_enabledOnStartEffects; bool m_isDebugRectRenderingEnabled = false; drape_ptr<DebugRectRenderer> m_debugRectRenderer; diff --git a/drape_frontend/my_position.cpp b/drape_frontend/my_position.cpp index 0a2dffe46f..85df3b8550 100644 --- a/drape_frontend/my_position.cpp +++ b/drape_frontend/my_position.cpp @@ -66,6 +66,12 @@ MyPosition::MyPosition(ref_ptr<dp::TextureManager> mng) CachePointPosition(mng); } +void MyPosition::InitArrow(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManager> mng) +{ + m_arrow3d = make_unique_dp<Arrow3d>(context); + m_arrow3d->SetTexture(mng); +} + void MyPosition::SetPosition(m2::PointF const & pt) { m_position = pt; @@ -94,7 +100,8 @@ void MyPosition::SetRoutingMode(bool routingMode) void MyPosition::SetPositionObsolete(bool obsolete) { m_obsoletePosition = obsolete; - m_arrow3d.SetPositionObsolete(obsolete); + CHECK(m_arrow3d != nullptr, ()); + m_arrow3d->SetPositionObsolete(obsolete); } void MyPosition::RenderAccuracy(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng, @@ -122,9 +129,10 @@ void MyPosition::RenderMyPosition(ref_ptr<dp::GraphicsContext> context, ref_ptr< { if (m_showAzimuth) { - m_arrow3d.SetPosition(m2::PointD(m_position)); - m_arrow3d.SetAzimuth(m_azimuth); - m_arrow3d.Render(context, mng, screen, m_isRoutingMode); + CHECK(m_arrow3d != nullptr, ()); + m_arrow3d->SetPosition(m2::PointD(m_position)); + m_arrow3d->SetAzimuth(m_azimuth); + m_arrow3d->Render(context, mng, screen, m_isRoutingMode); } else { @@ -215,8 +223,6 @@ void MyPosition::CachePointPosition(ref_ptr<dp::TextureManager> mng) dp::TextureManager::SymbolRegion pointSymbol; mng->GetSymbolRegion("current-position", pointSymbol); - m_arrow3d.SetTexture(mng); - auto state = CreateRenderState(gpu::Program::MyPosition, DepthLayer::OverlayLayer); state.SetDepthTestEnabled(false); state.SetColorTexture(pointSymbol.GetTexture()); diff --git a/drape_frontend/my_position.hpp b/drape_frontend/my_position.hpp index f1ed728d6e..9adf7c06f3 100644 --- a/drape_frontend/my_position.hpp +++ b/drape_frontend/my_position.hpp @@ -23,7 +23,9 @@ class MyPosition public: explicit MyPosition(ref_ptr<dp::TextureManager> mng); - // pt - mercator point + void InitArrow(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManager> mng); + + // pt - mercator point. void SetPosition(m2::PointF const & pt); void SetAzimuth(float azimut); void SetIsValidAzimuth(bool isValid); @@ -68,6 +70,6 @@ private: std::vector<TPart> m_parts; std::vector<RenderNode> m_nodes; - Arrow3d m_arrow3d; + drape_ptr<Arrow3d> m_arrow3d; }; } // namespace df diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 27cac70d95..6428d18979 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -328,9 +328,12 @@ void MyPositionController::CorrectGlobalScalePoint(m2::PointD & pt) const pt = m_position; } -void MyPositionController::SetRenderShape(drape_ptr<MyPosition> && shape) +void MyPositionController::SetRenderShape(ref_ptr<dp::GraphicsContext> context, + ref_ptr<dp::TextureManager> texMng, + drape_ptr<MyPosition> && shape) { m_shape = std::move(shape); + m_shape->InitArrow(context, texMng); } void MyPositionController::ResetRenderShape() diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 238a5b2d3c..43b522e34c 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -100,7 +100,8 @@ public: void CorrectScalePoint(m2::PointD & pt1, m2::PointD & pt2) const; void CorrectGlobalScalePoint(m2::PointD & pt) const; - void SetRenderShape(drape_ptr<MyPosition> && shape); + void SetRenderShape(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManager> texMng, + drape_ptr<MyPosition> && shape); void ResetRenderShape(); void ActivateRouting(int zoomLevel, bool enableAutoZoom); diff --git a/drape_frontend/postprocess_renderer.cpp b/drape_frontend/postprocess_renderer.cpp index 7b0e8a033c..c7722cf474 100644 --- a/drape_frontend/postprocess_renderer.cpp +++ b/drape_frontend/postprocess_renderer.cpp @@ -111,22 +111,29 @@ private: gpu::ScreenQuadProgramParams m_params; }; -void InitFramebuffer(drape_ptr<dp::Framebuffer> & framebuffer, uint32_t width, uint32_t height, +void InitFramebuffer(ref_ptr<dp::GraphicsContext> context, + drape_ptr<dp::Framebuffer> & framebuffer, + uint32_t width, uint32_t height, bool depthEnabled, bool stencilEnabled) { if (framebuffer == nullptr) - framebuffer = make_unique_dp<dp::Framebuffer>(dp::TextureFormat::RGBA8, depthEnabled, stencilEnabled); - framebuffer->SetSize(width, height); + { + framebuffer = make_unique_dp<dp::Framebuffer>(dp::TextureFormat::RGBA8, depthEnabled, + stencilEnabled); + } + framebuffer->SetSize(std::move(context), width, height); } -void InitFramebuffer(drape_ptr<dp::Framebuffer> & framebuffer, dp::TextureFormat colorFormat, +void InitFramebuffer(ref_ptr<dp::GraphicsContext> context, + drape_ptr<dp::Framebuffer> & framebuffer, + dp::TextureFormat colorFormat, ref_ptr<dp::Framebuffer::DepthStencil> depthStencilRef, uint32_t width, uint32_t height) { if (framebuffer == nullptr) framebuffer = make_unique_dp<dp::Framebuffer>(colorFormat); - framebuffer->SetDepthStencilRef(depthStencilRef); - framebuffer->SetSize(width, height); + framebuffer->SetDepthStencilRef(std::move(depthStencilRef)); + framebuffer->SetSize(std::move(context), width, height); } bool IsSupported(drape_ptr<dp::Framebuffer> const & framebuffer) @@ -140,10 +147,10 @@ PostprocessRenderer::~PostprocessRenderer() ClearGLDependentResources(); } -void PostprocessRenderer::Init(dp::ApiVersion apiVersion, dp::FramebufferFallback && fallback) +void PostprocessRenderer::Init(ref_ptr<dp::GraphicsContext> context, dp::FramebufferFallback && fallback) { - m_apiVersion = apiVersion; - m_screenQuadRenderer = make_unique_dp<ScreenQuadRenderer>(); + m_apiVersion = context->GetApiVersion(); + m_screenQuadRenderer = make_unique_dp<ScreenQuadRenderer>(context); m_framebufferFallback = std::move(fallback); ASSERT(m_framebufferFallback != nullptr, ()); } @@ -162,12 +169,12 @@ void PostprocessRenderer::ClearGLDependentResources() m_isSmaaFramebufferRendered = false; } -void PostprocessRenderer::Resize(uint32_t width, uint32_t height) +void PostprocessRenderer::Resize(ref_ptr<dp::GraphicsContext> context, uint32_t width, uint32_t height) { m_width = width; m_height = height; - UpdateFramebuffers(m_width, m_height); + UpdateFramebuffers(std::move(context), m_width, m_height); } void PostprocessRenderer::SetStaticTextures(drape_ptr<PostprocessStaticTextures> && textures) @@ -184,10 +191,11 @@ bool PostprocessRenderer::IsEnabled() const return IsSupported(m_mainFramebuffer); } -void PostprocessRenderer::SetEffectEnabled(Effect effect, bool enabled) +void PostprocessRenderer::SetEffectEnabled(ref_ptr<dp::GraphicsContext> context, + Effect effect, bool enabled) { // Do not support AA for OpenGLES 2.0. - if (m_apiVersion == dp::ApiVersion::OpenGLES2 && effect == Effect::Antialiasing) + if (context->GetApiVersion() == dp::ApiVersion::OpenGLES2 && effect == Effect::Antialiasing) return; auto const oldValue = m_effects; @@ -195,7 +203,7 @@ void PostprocessRenderer::SetEffectEnabled(Effect effect, bool enabled) m_effects = (m_effects & ~effectMask) | (enabled ? effectMask : 0); if (m_width != 0 && m_height != 0 && oldValue != m_effects) - UpdateFramebuffers(m_width, m_height); + UpdateFramebuffers(context, m_width, m_height); } bool PostprocessRenderer::IsEffectEnabled(Effect effect) const @@ -233,7 +241,7 @@ bool PostprocessRenderer::BeginFrame(ref_ptr<dp::GraphicsContext> context, bool m_frameStarted = activeFrame || !m_isMainFramebufferRendered; if (m_frameStarted) - m_mainFramebuffer->Enable(); + context->SetFramebuffer(make_ref(m_mainFramebuffer)); if (m_frameStarted && CanRenderAntialiasing()) context->SetStencilTestEnabled(false); @@ -242,7 +250,9 @@ bool PostprocessRenderer::BeginFrame(ref_ptr<dp::GraphicsContext> context, bool return m_frameStarted; } -bool PostprocessRenderer::EndFrame(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> gpuProgramManager) +bool PostprocessRenderer::EndFrame(ref_ptr<dp::GraphicsContext> context, + ref_ptr<gpu::ProgramManager> gpuProgramManager, + dp::Viewport const & viewport) { if (!IsEnabled()) return true; @@ -261,13 +271,13 @@ bool PostprocessRenderer::EndFrame(ref_ptr<dp::GraphicsContext> context, ref_ptr // Render edges to texture. { - m_edgesFramebuffer->Enable(); - + context->SetFramebuffer(make_ref(m_edgesFramebuffer)); context->Clear(dp::ClearBits::ColorBit); - context->SetStencilFunction(dp::StencilFace::FrontAndBack, dp::TestFunction::NotEqual); context->SetStencilActions(dp::StencilFace::FrontAndBack, dp::StencilAction::Zero, dp::StencilAction::Zero, dp::StencilAction::Replace); + context->ApplyFramebuffer("SMAA edges"); + viewport.Apply(context); EdgesRenderParams params; params.SetParams(m_mainFramebuffer->GetTexture(), m_width, m_height); @@ -279,13 +289,13 @@ bool PostprocessRenderer::EndFrame(ref_ptr<dp::GraphicsContext> context, ref_ptr // Render blending weight to texture. { - m_blendingWeightFramebuffer->Enable(); - + context->SetFramebuffer(make_ref(m_blendingWeightFramebuffer)); context->Clear(dp::ClearBits::ColorBit); - context->SetStencilFunction(dp::StencilFace::FrontAndBack, dp::TestFunction::Equal); context->SetStencilActions(dp::StencilFace::FrontAndBack, dp::StencilAction::Keep, dp::StencilAction::Keep, dp::StencilAction::Keep); + context->ApplyFramebuffer("SMAA blending"); + viewport.Apply(context); BlendingWeightRenderParams params; params.SetParams(m_edgesFramebuffer->GetTexture(), @@ -301,9 +311,10 @@ bool PostprocessRenderer::EndFrame(ref_ptr<dp::GraphicsContext> context, ref_ptr // SMAA final pass. context->SetStencilTestEnabled(false); { - m_smaaFramebuffer->Enable(); - + context->SetFramebuffer(make_ref(m_smaaFramebuffer)); context->Clear(dp::ClearBits::ColorBit); + context->ApplyFramebuffer("SMAA final"); + viewport.Apply(context); SMAAFinalRenderParams params; params.SetParams(m_mainFramebuffer->GetTexture(), @@ -328,6 +339,10 @@ bool PostprocessRenderer::EndFrame(ref_ptr<dp::GraphicsContext> context, ref_ptr bool m_wasRendered = false; if (m_framebufferFallback()) { + context->Clear(dp::ClearBits::ColorBit); + context->ApplyFramebuffer("Dynamic frame"); + viewport.Apply(context); + DefaultScreenQuadRenderParams params; params.SetParams(finalFramebuffer->GetTexture()); @@ -358,28 +373,29 @@ void PostprocessRenderer::DisableWritingToStencil(ref_ptr<dp::GraphicsContext> c context->SetStencilTestEnabled(false); } -void PostprocessRenderer::UpdateFramebuffers(uint32_t width, uint32_t height) +void PostprocessRenderer::UpdateFramebuffers(ref_ptr<dp::GraphicsContext> context, + uint32_t width, uint32_t height) { ASSERT_NOT_EQUAL(width, 0, ()); ASSERT_NOT_EQUAL(height, 0, ()); - InitFramebuffer(m_mainFramebuffer, width, height, - true /* depthEnabled */, - m_apiVersion != dp::ApiVersion::OpenGLES2 /* stencilEnabled */); + auto const apiVersion = context->GetApiVersion(); + InitFramebuffer(context, m_mainFramebuffer, width, height, true /* depthEnabled */, + apiVersion != dp::ApiVersion::OpenGLES2 /* stencilEnabled */); m_isMainFramebufferRendered = false; m_isSmaaFramebufferRendered = false; if (!m_isRouteFollowingActive && IsEffectEnabled(Effect::Antialiasing)) { - CHECK(m_apiVersion != dp::ApiVersion::OpenGLES2, ()); + CHECK_NOT_EQUAL(apiVersion, dp::ApiVersion::OpenGLES2, ()); - InitFramebuffer(m_edgesFramebuffer, dp::TextureFormat::RedGreen, + InitFramebuffer(context, m_edgesFramebuffer, dp::TextureFormat::RedGreen, m_mainFramebuffer->GetDepthStencilRef(), width, height); - InitFramebuffer(m_blendingWeightFramebuffer, dp::TextureFormat::RGBA8, + InitFramebuffer(context, m_blendingWeightFramebuffer, dp::TextureFormat::RGBA8, m_mainFramebuffer->GetDepthStencilRef(), width, height); - InitFramebuffer(m_smaaFramebuffer, dp::TextureFormat::RGBA8, + InitFramebuffer(context, m_smaaFramebuffer, dp::TextureFormat::RGBA8, m_mainFramebuffer->GetDepthStencilRef(), width, height); } @@ -391,30 +407,32 @@ void PostprocessRenderer::UpdateFramebuffers(uint32_t width, uint32_t height) } } -bool PostprocessRenderer::OnFramebufferFallback() +bool PostprocessRenderer::OnFramebufferFallback(ref_ptr<dp::GraphicsContext> context) { if (m_frameStarted) { - m_mainFramebuffer->Enable(); + context->SetFramebuffer(make_ref(m_mainFramebuffer)); return true; } return m_framebufferFallback(); } -void PostprocessRenderer::OnChangedRouteFollowingMode(bool isRouteFollowingActive) +void PostprocessRenderer::OnChangedRouteFollowingMode(ref_ptr<dp::GraphicsContext> context, + bool isRouteFollowingActive) { if (m_isRouteFollowingActive == isRouteFollowingActive) return; m_isRouteFollowingActive = isRouteFollowingActive; if (m_width != 0 && m_height != 0) - UpdateFramebuffers(m_width, m_height); + UpdateFramebuffers(std::move(context), m_width, m_height); } -StencilWriterGuard::StencilWriterGuard(ref_ptr<PostprocessRenderer> renderer, ref_ptr<dp::GraphicsContext> context) - : m_renderer(renderer) - , m_context(context) +StencilWriterGuard::StencilWriterGuard(ref_ptr<PostprocessRenderer> renderer, + ref_ptr<dp::GraphicsContext> context) + : m_renderer(std::move(renderer)) + , m_context(std::move(context)) { ASSERT(m_renderer != nullptr, ()); m_renderer->EnableWritingToStencil(m_context); diff --git a/drape_frontend/postprocess_renderer.hpp b/drape_frontend/postprocess_renderer.hpp index adb2ce447e..db8cdaf0e8 100644 --- a/drape_frontend/postprocess_renderer.hpp +++ b/drape_frontend/postprocess_renderer.hpp @@ -6,6 +6,7 @@ #include "drape/framebuffer.hpp" #include "drape/pointers.hpp" #include "drape/render_state.hpp" +#include "drape/viewport.hpp" #include <cstdint> @@ -41,26 +42,27 @@ public: PostprocessRenderer() = default; ~PostprocessRenderer(); - void Init(dp::ApiVersion apiVersion, dp::FramebufferFallback && fallback); + void Init(ref_ptr<dp::GraphicsContext> context, dp::FramebufferFallback && fallback); void ClearGLDependentResources(); - void Resize(uint32_t width, uint32_t height); + void Resize(ref_ptr<dp::GraphicsContext> context, uint32_t width, uint32_t height); void SetStaticTextures(drape_ptr<PostprocessStaticTextures> && textures); bool IsEnabled() const; - void SetEffectEnabled(Effect effect, bool enabled); + void SetEffectEnabled(ref_ptr<dp::GraphicsContext> context, Effect effect, bool enabled); bool IsEffectEnabled(Effect effect) const; - bool OnFramebufferFallback(); - void OnChangedRouteFollowingMode(bool isRouteFollowingActive); + bool OnFramebufferFallback(ref_ptr<dp::GraphicsContext> context); + void OnChangedRouteFollowingMode(ref_ptr<dp::GraphicsContext> context, bool isRouteFollowingActive); bool BeginFrame(ref_ptr<dp::GraphicsContext> context, bool activeFrame); - bool EndFrame(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> gpuProgramManager); + bool EndFrame(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> gpuProgramManager, + dp::Viewport const & viewport); void EnableWritingToStencil(ref_ptr<dp::GraphicsContext> context) const; void DisableWritingToStencil(ref_ptr<dp::GraphicsContext> context) const; private: - void UpdateFramebuffers(uint32_t width, uint32_t height); + void UpdateFramebuffers(ref_ptr<dp::GraphicsContext> context, uint32_t width, uint32_t height); bool CanRenderAntialiasing() const; dp::ApiVersion m_apiVersion; diff --git a/drape_frontend/render_group.hpp b/drape_frontend/render_group.hpp index be14aa9d26..2001b9c656 100755 --- a/drape_frontend/render_group.hpp +++ b/drape_frontend/render_group.hpp @@ -51,7 +51,6 @@ private: class RenderGroup : public BaseRenderGroup { using TBase = BaseRenderGroup; - friend class BatchMergeHelper; public: RenderGroup(dp::RenderState const & state, TileKey const & tileKey); ~RenderGroup() override; @@ -97,10 +96,8 @@ public: class UserMarkRenderGroup : public RenderGroup { using TBase = RenderGroup; - public: UserMarkRenderGroup(dp::RenderState const & state, TileKey const & tileKey); - ~UserMarkRenderGroup() override {} void UpdateAnimation() override; diff --git a/drape_frontend/screen_quad_renderer.cpp b/drape_frontend/screen_quad_renderer.cpp index 0ef2dd4ded..f071e5e592 100644 --- a/drape_frontend/screen_quad_renderer.cpp +++ b/drape_frontend/screen_quad_renderer.cpp @@ -24,7 +24,8 @@ public: void SetParams(ref_ptr<gpu::ProgramManager> gpuProgramManager, ref_ptr<dp::Texture> texture, float opacity) { - m_state.SetTexture("u_colorTex", texture); + UNUSED_VALUE(gpuProgramManager); + m_state.SetTexture("u_colorTex", std::move(texture)); m_params.m_opacity = opacity; } @@ -37,8 +38,8 @@ private: }; } // namespace -ScreenQuadRenderer::ScreenQuadRenderer() - : Base(DrawPrimitive::TriangleStrip) +ScreenQuadRenderer::ScreenQuadRenderer(ref_ptr<dp::GraphicsContext> context) + : Base(std::move(context), DrawPrimitive::TriangleStrip) { Rebuild(); } @@ -55,14 +56,16 @@ void ScreenQuadRenderer::Rebuild() SetAttribute("a_tcoord", bufferIndex, sizeof(float) * 2 /* offset */, 2 /* componentsCount */); } -void ScreenQuadRenderer::RenderTexture(ref_ptr<dp::GraphicsContext> context, ref_ptr<gpu::ProgramManager> mng, +void ScreenQuadRenderer::RenderTexture(ref_ptr<dp::GraphicsContext> context, + ref_ptr<gpu::ProgramManager> mng, ref_ptr<dp::Texture> texture, float opacity) { TextureRenderParams params; - params.SetParams(mng, texture, opacity); + params.SetParams(mng, std::move(texture), opacity); auto program = mng->GetProgram(params.GetRenderState().GetProgram<gpu::Program>()); - Base::Render(context, program, params.GetRenderState(), mng->GetParamsSetter(), params.GetProgramParams()); + Base::Render(std::move(context), program, params.GetRenderState(), mng->GetParamsSetter(), + params.GetProgramParams()); } void ScreenQuadRenderer::SetTextureRect(m2::RectF const & rect) diff --git a/drape_frontend/screen_quad_renderer.hpp b/drape_frontend/screen_quad_renderer.hpp index 06c2b60583..f5fef58ecb 100644 --- a/drape_frontend/screen_quad_renderer.hpp +++ b/drape_frontend/screen_quad_renderer.hpp @@ -11,11 +11,11 @@ class ProgramManager; namespace df { -class ScreenQuadRenderer: public dp::MeshObject +class ScreenQuadRenderer : public dp::MeshObject { using Base = dp::MeshObject; public: - ScreenQuadRenderer(); + explicit ScreenQuadRenderer(ref_ptr<dp::GraphicsContext> context); void SetTextureRect(m2::RectF const & rect); m2::RectF const & GetTextureRect() const { return m_textureRect; } diff --git a/iphone/Maps/Classes/EAGLView.h b/iphone/Maps/Classes/EAGLView.h index f788eeeda2..40f278c663 100644 --- a/iphone/Maps/Classes/EAGLView.h +++ b/iphone/Maps/Classes/EAGLView.h @@ -18,7 +18,8 @@ namespace dp drape_ptr<dp::GraphicsContextFactory> m_factory; // Do not call onSize from layoutSubViews when real size wasn't changed. // It's possible when we add/remove subviews (bookmark balloons) and it hangs the map without this check - CGRect lastViewSize; + CGRect m_lastViewSize; + bool m_presentAvailable; } @property(nonatomic) MWMMapWidgets * widgetsManager; @@ -28,10 +29,10 @@ namespace dp @property(nonatomic) BOOL isLaunchByDeepLink; @property(nonatomic, readonly) m2::PointU pixelSize; +- (void)createDrapeEngine; - (void)deallocateNative; +- (void)setPresentAvailable:(BOOL)available; - (CGPoint)viewPoint2GlobalPoint:(CGPoint)pt; - (CGPoint)globalPoint2ViewPoint:(CGPoint)pt; -- (void)initialize; -- (void)setPresentAvailable:(BOOL)available; @end diff --git a/iphone/Maps/Classes/EAGLView.mm b/iphone/Maps/Classes/EAGLView.mm index bf0e82f1f6..e183908b82 100644 --- a/iphone/Maps/Classes/EAGLView.mm +++ b/iphone/Maps/Classes/EAGLView.mm @@ -11,6 +11,7 @@ #include "drape/visual_scale.hpp" +#include "base/assert.hpp" #include "base/logging.hpp" @implementation EAGLView @@ -62,42 +63,54 @@ double getExactDPI(double contentScaleFactor) EAGLContext * tempContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; if (tempContext != nil) - { - tempContext = nil; return dp::ApiVersion::OpenGLES3; - } return dp::ApiVersion::OpenGLES2;; } - (void)initialize { - lastViewSize = CGRectZero; + m_presentAvailable = false; + m_lastViewSize = CGRectZero; m_apiVersion = [self getSupportedApiVersion]; - if (m_apiVersion == dp::ApiVersion::Metal) - { - m_factory = make_unique_dp<MetalContextFactory>(self.metalView); - } - else + // Correct retina display support in renderbuffer. + self.contentScaleFactor = [[UIScreen mainScreen] nativeScale]; + + if (m_apiVersion != dp::ApiVersion::Metal) { // Setup Layer Properties CAEAGLLayer * eaglLayer = (CAEAGLLayer *)self.layer; - eaglLayer.opaque = YES; eaglLayer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking : @NO, kEAGLDrawablePropertyColorFormat : kEAGLColorFormatRGBA8}; + } +} - // Correct retina display support in opengl renderbuffer - self.contentScaleFactor = [[UIScreen mainScreen] nativeScale]; - - m_factory = make_unique_dp<dp::ThreadSafeFactory>(new iosOGLContextFactory(eaglLayer, m_apiVersion)); +- (void)createDrapeEngine +{ + if (m_apiVersion == dp::ApiVersion::Metal) + { + CHECK(self.metalView != nil, ()); + CHECK_EQUAL(self.bounds.size.width, self.metalView.bounds.size.width, ()); + CHECK_EQUAL(self.bounds.size.height, self.metalView.bounds.size.height, ()); + m_factory = make_unique_dp<MetalContextFactory>(self.metalView); + } + else + { + CAEAGLLayer * eaglLayer = (CAEAGLLayer *)self.layer; + m_factory = make_unique_dp<dp::ThreadSafeFactory>( + new iosOGLContextFactory(eaglLayer, m_apiVersion, m_presentAvailable)); } + + m2::PointU const s = [self pixelSize]; + [self createDrapeEngineWithWidth:s.x height:s.y]; } - (void)createDrapeEngineWithWidth:(int)width height:(int)height { - LOG(LINFO, ("EAGLView createDrapeEngine Started")); + LOG(LINFO, ("CreateDrapeEngine Started", width, height)); + CHECK(m_factory != nullptr, ()); Framework::DrapeCreationParams p; p.m_apiVersion = m_apiVersion; @@ -110,7 +123,8 @@ double getExactDPI(double contentScaleFactor) [self.widgetsManager setupWidgets:p]; GetFramework().CreateDrapeEngine(make_ref(m_factory), move(p)); - LOG(LINFO, ("EAGLView createDrapeEngine Ended")); + self->_drapeEngineCreated = YES; + LOG(LINFO, ("CreateDrapeEngine Finished")); } - (void)addSubview:(UIView *)view @@ -126,16 +140,6 @@ double getExactDPI(double contentScaleFactor) } } -- (void)applyOnSize:(int)width withHeight:(int)height -{ - dispatch_async(dispatch_get_main_queue(), ^ - { - GetFramework().OnSize(width, height); - [self.widgetsManager resize:CGSizeMake(width, height)]; - self->_drapeEngineCreated = YES; - }); -} - - (m2::PointU)pixelSize { CGSize const s = self.bounds.size; @@ -144,24 +148,14 @@ double getExactDPI(double contentScaleFactor) return m2::PointU(w, h); } -- (void)onSize:(int)width withHeight:(int)height -{ - int w = width * self.contentScaleFactor; - int h = height * self.contentScaleFactor; - - if (GetFramework().GetDrapeEngine() == nullptr) - [self createDrapeEngineWithWidth:w height:h]; - - [self applyOnSize:w withHeight:h]; -} - - (void)layoutSubviews { - if (!CGRectEqualToRect(lastViewSize, self.frame)) + if (!CGRectEqualToRect(m_lastViewSize, self.frame)) { - lastViewSize = self.frame; - CGSize const s = self.bounds.size; - [self onSize:s.width withHeight:s.height]; + m_lastViewSize = self.frame; + m2::PointU const s = [self pixelSize]; + GetFramework().OnSize(s.x, s.y); + [self.widgetsManager resize:CGSizeMake(s.x, s.y)]; } [super layoutSubviews]; } @@ -188,7 +182,9 @@ double getExactDPI(double contentScaleFactor) - (void)setPresentAvailable:(BOOL)available { - m_factory->SetPresentAvailable(available); + m_presentAvailable = available; + if (m_factory != nullptr) + m_factory->SetPresentAvailable(m_presentAvailable); } - (MWMMapWidgets *)widgetsManager diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index cf7f1e6df6..f657c340d4 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -248,6 +248,7 @@ BOOL gIsFirstMyPositionMode = YES; - (void)viewDidLoad { [super viewDidLoad]; + self.view.clipsToBounds = YES; [self processMyPositionStateModeEvent:MWMMyPositionModePendingPosition]; [MWMKeyboard addObserver:self]; @@ -270,6 +271,12 @@ BOOL gIsFirstMyPositionMode = YES; [self.controlsManager showTutorialIfNeeded]; } +- (void)viewDidLayoutSubviews +{ + [super viewDidLayoutSubviews]; + [(EAGLView *)self.view createDrapeEngine]; +} + - (void)mwm_refreshUI { [MapsAppDelegate customizeAppearance]; diff --git a/iphone/Maps/Classes/MetalContext.h b/iphone/Maps/Classes/MetalContext.h deleted file mode 100644 index 6b585a1d0c..0000000000 --- a/iphone/Maps/Classes/MetalContext.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "drape/graphics_context.hpp" - -#import "MetalView.h" - -class MetalContext: public dp::GraphicsContext -{ -public: - MetalContext(MetalView * view); - ~MetalContext() override; - - void Present() override; - void MakeCurrent() override; - void DoneCurrent() override; - void SetDefaultFramebuffer() override; - void Resize(int w, int h) override; - void SetRenderingEnabled(bool enabled) override; - void SetPresentAvailable(bool available) override; - bool Validate() override; - - void Init(dp::ApiVersion apiVersion) override; - void SetClearColor(dp::Color const & color) override; - void Clear(uint32_t clearBits) override; - void Flush() 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; - -private: - MetalView * m_view; - id<MTLDevice> m_device; - id<MTLCommandQueue> m_commandQueue; -}; diff --git a/iphone/Maps/Classes/MetalContext.mm b/iphone/Maps/Classes/MetalContext.mm deleted file mode 100644 index dc07fc3f69..0000000000 --- a/iphone/Maps/Classes/MetalContext.mm +++ /dev/null @@ -1,116 +0,0 @@ -#import "MetalContext.h" - -MetalContext::MetalContext(MetalView * view) -{ - m_device = view.device; - m_commandQueue = [m_device newCommandQueue]; -} - -MetalContext::~MetalContext() -{ - -} - -void MetalContext::MakeCurrent() -{ - -} - -void MetalContext::DoneCurrent() -{ - -} - -void MetalContext::Present() -{ - id<MTLCommandBuffer> commandBuffer = [m_commandQueue commandBuffer]; - commandBuffer.label = @"MyCommand"; - - MTLRenderPassDescriptor *renderPassDescriptor = m_view.currentRenderPassDescriptor; - - if(renderPassDescriptor != nil) - { - id<MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; - - renderEncoder.label = @"MyRenderEncoder"; - - [renderEncoder endEncoding]; - - [commandBuffer presentDrawable:m_view.currentDrawable]; - } - [commandBuffer commit]; -} - -void MetalContext::SetDefaultFramebuffer() -{ - -} - -void MetalContext::Resize(int w, int h) -{ - -} - -void MetalContext::SetRenderingEnabled(bool enabled) -{ - -} - -void MetalContext::SetPresentAvailable(bool available) -{ - -} - -bool MetalContext::Validate() -{ - return true; -} - - -void MetalContext::Init(dp::ApiVersion apiVersion) -{ - -} - -void MetalContext::SetClearColor(dp::Color const & color) -{ - m_view.clearColor = MTLClearColorMake(color.GetRedF(), color.GetGreen(), - color.GetBlueF(), color.GetAlphaF()); -} - -void MetalContext::Clear(uint32_t clearBits) -{ -} - -void MetalContext::Flush() -{ - -} - -void MetalContext::SetDepthTestEnabled(bool enabled) -{ - -} - -void MetalContext::SetDepthTestFunction(dp::TestFunction depthFunction) -{ - -} - -void MetalContext::SetStencilTestEnabled(bool enabled) -{ - -} - -void MetalContext::SetStencilFunction(dp::StencilFace face, dp::TestFunction stencilFunction) -{ - -} - -void MetalContext::SetStencilActions(dp::StencilFace face, - dp::StencilAction stencilFailAction, - dp::StencilAction depthFailAction, - dp::StencilAction passAction) -{ - -} diff --git a/iphone/Maps/Classes/MetalContextFactory.h b/iphone/Maps/Classes/MetalContextFactory.h index eb506b7e4f..981a8c32bc 100644 --- a/iphone/Maps/Classes/MetalContextFactory.h +++ b/iphone/Maps/Classes/MetalContextFactory.h @@ -1,24 +1,22 @@ #pragma once +#import "MetalView.h" #include "drape/graphics_context_factory.hpp" +#include "drape/metal/metal_base_context.hpp" #include "drape/pointers.hpp" -#import "MetalContext.h" -#import "MetalView.h" - class MetalContextFactory: public dp::GraphicsContextFactory { public: - MetalContextFactory(MetalView * view); - ~MetalContextFactory() override; + explicit MetalContextFactory(MetalView * metalView); dp::GraphicsContext * GetDrawContext() override; dp::GraphicsContext * GetResourcesUploadContext() override; - bool IsDrawContextCreated() const override; - bool IsUploadContextCreated() const override; - void WaitForInitialization(dp::GraphicsContext * context) override; + bool IsDrawContextCreated() const override { return true; } + bool IsUploadContextCreated() const override { return true; } + void WaitForInitialization(dp::GraphicsContext * context) override {} void SetPresentAvailable(bool available) override; private: - MetalView * m_view; - drape_ptr<MetalContext> m_context; + drape_ptr<dp::metal::MetalBaseContext> m_drawContext; + drape_ptr<dp::metal::MetalBaseContext> m_uploadContext; }; diff --git a/iphone/Maps/Classes/MetalContextFactory.mm b/iphone/Maps/Classes/MetalContextFactory.mm index 745af2e4cb..160de400d8 100644 --- a/iphone/Maps/Classes/MetalContextFactory.mm +++ b/iphone/Maps/Classes/MetalContextFactory.mm @@ -1,39 +1,77 @@ #import "MetalContextFactory.h" -MetalContextFactory::MetalContextFactory(MetalView * view): m_view(view) -{} +#include "base/assert.hpp" -MetalContextFactory::~MetalContextFactory() -{} - -dp::GraphicsContext * MetalContextFactory::GetDrawContext() +namespace { - if (m_context == nullptr) - m_context = make_unique_dp<MetalContext>(m_view); - return m_context.get(); -} +class DrawMetalContext : public dp::metal::MetalBaseContext +{ +public: + DrawMetalContext(CAMetalLayer * metalLayer, id<MTLTexture> depthStencilTexture) + : dp::metal::MetalBaseContext(metalLayer.device, depthStencilTexture) + , m_metalLayer(metalLayer) + {} + + bool Validate() override + { + if (HasFrameDrawable()) + return true; + + id<CAMetalDrawable> drawable = [m_metalLayer nextDrawable]; + SetFrameDrawable(drawable); + return drawable != nil; + } + +private: + CAMetalLayer * m_metalLayer; +}; + +class UploadMetalContext : public dp::metal::MetalBaseContext +{ +public: + explicit UploadMetalContext(id<MTLDevice> device) + : dp::metal::MetalBaseContext(device, nil) + {} + + void Present() override {} + void MakeCurrent() override {} + void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override {} + void Init(dp::ApiVersion apiVersion) override + { + CHECK_EQUAL(apiVersion, dp::ApiVersion::Metal, ()); + } + bool Validate() override { return true; } + + void SetClearColor(dp::Color const & color) override {} + void Clear(uint32_t clearBits) override {} + void Flush() 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 {} +}; +} // namespace -dp::GraphicsContext * MetalContextFactory::GetResourcesUploadContext() +MetalContextFactory::MetalContextFactory(MetalView * metalView) { - if (m_context == nullptr) - m_context = make_unique_dp<MetalContext>(m_view); - return m_context.get(); + CAMetalLayer * metalLayer = (CAMetalLayer *)metalView.layer; + m_drawContext = make_unique_dp<DrawMetalContext>(metalLayer, metalView.depthStencilTexture); + m_uploadContext = make_unique_dp<UploadMetalContext>(m_drawContext->GetMetalDevice()); } -bool MetalContextFactory::IsDrawContextCreated() const +dp::GraphicsContext * MetalContextFactory::GetDrawContext() { - return m_context != nullptr; + return m_drawContext.get(); } -bool MetalContextFactory::IsUploadContextCreated() const +dp::GraphicsContext * MetalContextFactory::GetResourcesUploadContext() { - return m_context != nullptr; + return m_uploadContext.get(); } -void MetalContextFactory::WaitForInitialization(dp::GraphicsContext * context) -{} - void MetalContextFactory::SetPresentAvailable(bool available) { - m_context->SetPresentAvailable(available); + m_drawContext->SetPresentAvailable(available); } diff --git a/iphone/Maps/Classes/MetalView.h b/iphone/Maps/Classes/MetalView.h index 030c5be46b..499f5fa31b 100644 --- a/iphone/Maps/Classes/MetalView.h +++ b/iphone/Maps/Classes/MetalView.h @@ -3,6 +3,5 @@ @interface MetalView : MTKView - (void)initialize; -- (void)setPresentAvailable:(BOOL)available; @end diff --git a/iphone/Maps/Classes/Widgets/MWMMapWidgets.mm b/iphone/Maps/Classes/Widgets/MWMMapWidgets.mm index f4f0235743..bed8d9950c 100644 --- a/iphone/Maps/Classes/Widgets/MWMMapWidgets.mm +++ b/iphone/Maps/Classes/Widgets/MWMMapWidgets.mm @@ -31,7 +31,8 @@ - (void)resize:(CGSize)size { - m_skin->Resize(size.width, size.height); + if (m_skin != nullptr) + m_skin->Resize(size.width, size.height); dispatch_async(dispatch_get_main_queue(), ^{ [self updateAvailableArea:self.availableArea]; }); diff --git a/iphone/Maps/Classes/iosOGLContext.h b/iphone/Maps/Classes/iosOGLContext.h index c7e2abed29..553d946abc 100644 --- a/iphone/Maps/Classes/iosOGLContext.h +++ b/iphone/Maps/Classes/iosOGLContext.h @@ -2,7 +2,7 @@ #include "drape/drape_global.hpp" #include "drape/oglcontext.hpp" -#include "drape/glIncludes.hpp" +#include "drape/gl_includes.hpp" #import <QuartzCore/CAEAGLLayer.h> @@ -17,7 +17,7 @@ public: void MakeCurrent() override; void Present() override; - void SetDefaultFramebuffer() override; + void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override; void Resize(int w, int h) override; void SetPresentAvailable(bool available) override; diff --git a/iphone/Maps/Classes/iosOGLContext.mm b/iphone/Maps/Classes/iosOGLContext.mm index a048e03c6d..ec18d14c81 100644 --- a/iphone/Maps/Classes/iosOGLContext.mm +++ b/iphone/Maps/Classes/iosOGLContext.mm @@ -1,8 +1,9 @@ #import "iosOGLContext.h" -#import "base/assert.hpp" -#import "base/logging.cpp" -#import "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" + +#include "base/assert.hpp" +#include "base/logging.cpp" iosOGLContext::iosOGLContext(CAEAGLLayer * layer, dp::ApiVersion apiVersion, iosOGLContext * contextToShareWith, bool needBuffers) @@ -73,10 +74,17 @@ void iosOGLContext::Present() GLCHECK(glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards + 1)); } -void iosOGLContext::SetDefaultFramebuffer() +void iosOGLContext::SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) { - ASSERT(m_frameBufferId, ()); - glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId); + if (framebuffer) + { + framebuffer->Bind(); + } + else + { + ASSERT(m_frameBufferId, ()); + glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId); + } } void iosOGLContext::Resize(int w, int h) diff --git a/iphone/Maps/Classes/iosOGLContextFactory.h b/iphone/Maps/Classes/iosOGLContextFactory.h index 6beebe7617..5f9870ef60 100644 --- a/iphone/Maps/Classes/iosOGLContextFactory.h +++ b/iphone/Maps/Classes/iosOGLContextFactory.h @@ -11,7 +11,7 @@ class iosOGLContextFactory: public dp::GraphicsContextFactory { public: - iosOGLContextFactory(CAEAGLLayer * layer, dp::ApiVersion apiVersion); + iosOGLContextFactory(CAEAGLLayer * layer, dp::ApiVersion apiVersion, bool presentAvailable); ~iosOGLContextFactory(); dp::GraphicsContext * GetDrawContext() override; diff --git a/iphone/Maps/Classes/iosOGLContextFactory.mm b/iphone/Maps/Classes/iosOGLContextFactory.mm index a15099f1ef..911abe0928 100644 --- a/iphone/Maps/Classes/iosOGLContextFactory.mm +++ b/iphone/Maps/Classes/iosOGLContextFactory.mm @@ -2,14 +2,15 @@ size_t constexpr kGLThreadsCount = 2; -iosOGLContextFactory::iosOGLContextFactory(CAEAGLLayer * layer, dp::ApiVersion apiVersion) +iosOGLContextFactory::iosOGLContextFactory(CAEAGLLayer * layer, dp::ApiVersion apiVersion, + bool presentAvailable) : m_layer(layer) , m_apiVersion(apiVersion) , m_drawContext(nullptr) , m_uploadContext(nullptr) , m_isInitialized(false) , m_initializationCounter(0) - , m_presentAvailable(false) + , m_presentAvailable(presentAvailable) {} iosOGLContextFactory::~iosOGLContextFactory() @@ -21,14 +22,14 @@ iosOGLContextFactory::~iosOGLContextFactory() dp::GraphicsContext * iosOGLContextFactory::GetDrawContext() { if (m_drawContext == nullptr) - m_drawContext = new iosOGLContext(m_layer, m_apiVersion, m_uploadContext, true); + m_drawContext = new iosOGLContext(m_layer, m_apiVersion, m_uploadContext, true /* needBuffers */); return m_drawContext; } dp::GraphicsContext * iosOGLContextFactory::GetResourcesUploadContext() { if (m_uploadContext == nullptr) - m_uploadContext = new iosOGLContext(m_layer, m_apiVersion, m_drawContext, false); + m_uploadContext = new iosOGLContext(m_layer, m_apiVersion, m_drawContext, false /* needBuffers */); return m_uploadContext; } diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index cbcddfc196..ef563197ee 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -339,9 +339,11 @@ 4501B1952077C35A001B9173 /* resources-xxxhdpi_dark in Resources */ = {isa = PBXBuildFile; fileRef = 4501B1932077C35A001B9173 /* resources-xxxhdpi_dark */; }; 4554B6EC1E55F0EF0084017F /* drules_proto_vehicle_clear.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4554B6E81E55F02B0084017F /* drules_proto_vehicle_clear.bin */; }; 4554B6EE1E55F0F30084017F /* drules_proto_vehicle_dark.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4554B6E91E55F02B0084017F /* drules_proto_vehicle_dark.bin */; }; + 4560F585213D53C100CC736C /* shaders_metal.metallib in Resources */ = {isa = PBXBuildFile; fileRef = 4598438921394D7700F8CAB2 /* shaders_metal.metallib */; }; 4563158920E264C20076E9DB /* libshaders.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4563158820E264C20076E9DB /* libshaders.a */; }; 4586D0C41F48121A00DF9CE5 /* libbsdiff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4586D0C31F48121A00DF9CE5 /* libbsdiff.a */; }; 4586D0E71F4813AB00DF9CE5 /* libmwm_diff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4586D0E61F4813AB00DF9CE5 /* libmwm_diff.a */; }; + 4598438621394CFD00F8CAB2 /* MetalPerformanceShaders.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4598438521394CFD00F8CAB2 /* MetalPerformanceShaders.framework */; }; 45A37B9E20B33F5E005FBDBB /* FBAudienceNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45A37B9D20B33F5D005FBDBB /* FBAudienceNetwork.framework */; }; 45CBCCBA20590AAB006B55C2 /* libkml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45CBCCBB20590AAB006B55C2 /* libkml.a */; }; 45FFD65D1E965EBE00DB854E /* liblocal_ads.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 45FFD65C1E965EBE00DB854E /* liblocal_ads.a */; }; @@ -507,7 +509,6 @@ BB8123CC212C25FA00ADE512 /* MetalView.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB8123CB212C25FA00ADE512 /* MetalView.mm */; }; BB8123CF212C264700ADE512 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BB8123CD212C264700ADE512 /* Metal.framework */; }; BB8123D0212C264700ADE512 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BB8123CE212C264700ADE512 /* MetalKit.framework */; }; - BB8123D3212C754C00ADE512 /* MetalContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB8123D2212C754C00ADE512 /* MetalContext.mm */; }; BB8123D62130427E00ADE512 /* MetalContextFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = BB8123D52130427E00ADE512 /* MetalContextFactory.mm */; }; EBDA7B7820B370B40054165B /* GoogleMobileAds.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EBDA7B7320B3576D0054165B /* GoogleMobileAds.framework */; }; F5BD255A0838E70EC012748E /* DiscoverySearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5BD2ED6E94925472A9901B4 /* DiscoverySearchCell.swift */; }; @@ -1315,6 +1316,8 @@ 458287C21AD3BE2000BA8940 /* DownloadIndicatorProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadIndicatorProtocol.h; sourceTree = "<group>"; }; 4586D0C31F48121A00DF9CE5 /* libbsdiff.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbsdiff.a; path = ../../xcode/bsdiff/build/Debug/libbsdiff.a; sourceTree = "<group>"; }; 4586D0E61F4813AB00DF9CE5 /* libmwm_diff.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmwm_diff.a; path = ../../xcode/mwm_diff/build/Debug/libmwm_diff.a; sourceTree = "<group>"; }; + 4598438521394CFD00F8CAB2 /* MetalPerformanceShaders.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalPerformanceShaders.framework; path = System/Library/Frameworks/MetalPerformanceShaders.framework; sourceTree = SDKROOT; }; + 4598438921394D7700F8CAB2 /* shaders_metal.metallib */ = {isa = PBXFileReference; explicitFileType = "archive.metal-library"; path = shaders_metal.metallib; sourceTree = BUILT_PRODUCTS_DIR; }; 45A37B9D20B33F5D005FBDBB /* FBAudienceNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FBAudienceNetwork.framework; path = MoPubSDK/AdNetworkSupport/FacebookAudienceNetwork/SDK/FBAudienceNetwork.framework; sourceTree = "<group>"; }; 45CBCCBB20590AAB006B55C2 /* libkml.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libkml.a; sourceTree = BUILT_PRODUCTS_DIR; }; 45FFD65C1E965EBE00DB854E /* liblocal_ads.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblocal_ads.a; path = "/Users/r.kuznetsov/Dev/Projects/omim/xcode/local_ads/../../../omim-build/xcode/Debug/liblocal_ads.a"; sourceTree = "<absolute>"; }; @@ -1462,8 +1465,6 @@ BB8123CB212C25FA00ADE512 /* MetalView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MetalView.mm; sourceTree = "<group>"; }; BB8123CD212C264700ADE512 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; BB8123CE212C264700ADE512 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; }; - BB8123D1212C754C00ADE512 /* MetalContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MetalContext.h; sourceTree = "<group>"; }; - BB8123D2212C754C00ADE512 /* MetalContext.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MetalContext.mm; sourceTree = "<group>"; }; BB8123D42130427E00ADE512 /* MetalContextFactory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MetalContextFactory.h; sourceTree = "<group>"; }; BB8123D52130427E00ADE512 /* MetalContextFactory.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MetalContextFactory.mm; sourceTree = "<group>"; }; EBDA7B7320B3576D0054165B /* GoogleMobileAds.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleMobileAds.framework; path = MoPubSDK/AdNetworkSupport/AdMob/SDK/GoogleMobileAds.framework; sourceTree = "<group>"; }; @@ -1875,6 +1876,7 @@ buildActionMask = 2147483647; files = ( 3D1958EB213804B6009A83EC /* libmetrics.a in Frameworks */, + 4598438621394CFD00F8CAB2 /* MetalPerformanceShaders.framework in Frameworks */, BB8123CF212C264700ADE512 /* Metal.framework in Frameworks */, BB8123D0212C264700ADE512 /* MetalKit.framework in Frameworks */, 47800D2520C05E3200072F42 /* libFlurry_8.6.1.a in Frameworks */, @@ -1971,8 +1973,6 @@ 3404757C1E081B3300C92850 /* iosOGLContextFactory.mm */, F6DF5F321CD1136800A87154 /* LocaleTranslator.h */, F6381BF41CD12045004CA943 /* LocaleTranslator.mm */, - BB8123D1212C754C00ADE512 /* MetalContext.h */, - BB8123D2212C754C00ADE512 /* MetalContext.mm */, BB8123D42130427E00ADE512 /* MetalContextFactory.h */, BB8123D52130427E00ADE512 /* MetalContextFactory.mm */, BB8123CA212C25FA00ADE512 /* MetalView.h */, @@ -2051,6 +2051,7 @@ isa = PBXGroup; children = ( 3D1958EA213804B6009A83EC /* libmetrics.a */, + 4598438521394CFD00F8CAB2 /* MetalPerformanceShaders.framework */, BB8123CD212C264700ADE512 /* Metal.framework */, BB8123CE212C264700ADE512 /* MetalKit.framework */, 4563158820E264C20076E9DB /* libshaders.a */, @@ -2096,6 +2097,7 @@ 34201E0B1DC0E33100D24118 /* libtracking.a */, 3446C6761DDCA9A200146687 /* libtraffic.a */, 3462FD8A1DC1DF3A00906FD7 /* SDK */, + 4598438921394D7700F8CAB2 /* shaders_metal.metallib */, ); name = Frameworks; sourceTree = "<group>"; @@ -4323,6 +4325,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4560F585213D53C100CC736C /* shaders_metal.metallib in Resources */, F642D1231F0F9D1D005E3C25 /* ugc_types.csv in Resources */, 34E50DFB1F6FCC96008EED49 /* UGCReviewCell.xib in Resources */, 34EE25A21EFA68BC00F870AB /* PPViatorCarouselCell.xib in Resources */, @@ -4979,7 +4982,6 @@ 34AB661D1FC5AA330078E451 /* MWMTaxiPreviewDataSource.mm in Sources */, F69CE8D61E5C49B4002B5881 /* PPHotelCarouselCell.swift in Sources */, F6FEA82E1C58F108007223CC /* MWMButton.mm in Sources */, - BB8123D3212C754C00ADE512 /* MetalContext.mm in Sources */, 3445324E1F714FD70059FBCC /* UGCAddReviewController.swift in Sources */, 34EE259E1EFA682D00F870AB /* PPViatorCarouselCell.swift in Sources */, 34B924431DC8A29C0008D971 /* MWMMailViewController.mm in Sources */, diff --git a/iphone/Maps/UI/Storyboard/Main.storyboard b/iphone/Maps/UI/Storyboard/Main.storyboard index 455a74ffe4..0b96c351a7 100644 --- a/iphone/Maps/UI/Storyboard/Main.storyboard +++ b/iphone/Maps/UI/Storyboard/Main.storyboard @@ -21,10 +21,10 @@ <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> - <mtkView contentMode="scaleToFill" colorPixelFormat="BGRA8Unorm" depthStencilPixelFormat="Depth32Float" translatesAutoresizingMaskIntoConstraints="NO" id="MSN-qF-aIb" customClass="MetalView"> + <mtkView contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" colorPixelFormat="BGRA8Unorm" depthStencilPixelFormat="Depth32Float" translatesAutoresizingMaskIntoConstraints="NO" id="MSN-qF-aIb" customClass="MetalView"> <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <color key="clearColor" name="systemGreenColor" catalog="System" colorSpace="catalog"/> + <color key="clearColor" red="0.99999600649999998" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> </mtkView> <view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="65S-M4-TnM" customClass="NavigationInfoArea" customModule="maps_me" customModuleProvider="target"> <rect key="frame" x="0.0" y="20" width="320" height="548"/> diff --git a/map/framework.cpp b/map/framework.cpp index d61a388ee7..50b6bd4058 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -408,7 +408,7 @@ Framework::Framework(FrameworkParams const & params) df::LoadTransitColors(); m_connectToGpsTrack = GpsTracker::Instance().IsEnabled(); - + // Init strings bundle. // @TODO. There are hardcoded strings below which are defined in strings.txt as well. // It's better to use strings from strings.txt instead of hardcoding them here. diff --git a/qt/qt_common/qtoglcontext.cpp b/qt/qt_common/qtoglcontext.cpp index d9db07aef0..d7be83fb61 100644 --- a/qt/qt_common/qtoglcontext.cpp +++ b/qt/qt_common/qtoglcontext.cpp @@ -5,7 +5,7 @@ #include "base/macros.hpp" #include "base/math.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include <memory> @@ -13,7 +13,6 @@ namespace qt { namespace common { -// QtRenderOGLContext ------------------------------------------------------------------------------ QtRenderOGLContext::QtRenderOGLContext(QOpenGLContext * rootContext, QOffscreenSurface * surface) : m_surface(surface) , m_ctx(std::make_unique<QOpenGLContext>()) @@ -46,12 +45,12 @@ void QtRenderOGLContext::DoneCurrent() m_ctx->doneCurrent(); } -void QtRenderOGLContext::SetDefaultFramebuffer() +void QtRenderOGLContext::SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) { - if (m_backFrame == nullptr) - return; - - m_backFrame->bind(); + if (framebuffer) + framebuffer->Bind(); + else if (m_backFrame != nullptr) + m_backFrame->bind(); } void QtRenderOGLContext::Resize(int w, int h) @@ -90,7 +89,6 @@ void QtRenderOGLContext::UnlockFrame() m_lock.unlock(); } -// QtUploadOGLContext ------------------------------------------------------------------------------ QtUploadOGLContext::QtUploadOGLContext(QOpenGLContext * rootContext, QOffscreenSurface * surface) : m_surface(surface), m_ctx(std::make_unique<QOpenGLContext>()) { @@ -112,12 +110,12 @@ void QtUploadOGLContext::DoneCurrent() void QtUploadOGLContext::Present() { - ASSERT(false, ()); + CHECK(false, ()); } -void QtUploadOGLContext::SetDefaultFramebuffer() +void QtUploadOGLContext::SetFramebuffer(ref_ptr<dp::BaseFramebuffer>) { - ASSERT(false, ()); + CHECK(false, ()); } } // namespace common } // namespace qt diff --git a/qt/qt_common/qtoglcontext.hpp b/qt/qt_common/qtoglcontext.hpp index 679fad5313..50f149f60a 100644 --- a/qt/qt_common/qtoglcontext.hpp +++ b/qt/qt_common/qtoglcontext.hpp @@ -18,11 +18,10 @@ class QtRenderOGLContext : public dp::OGLContext public: QtRenderOGLContext(QOpenGLContext * rootContext, QOffscreenSurface * surface); - // dp::OGLContext overrides: void Present() override; void MakeCurrent() override; void DoneCurrent() override; - void SetDefaultFramebuffer() override; + void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override; void Resize(int w, int h) override; void LockFrame(); @@ -47,11 +46,10 @@ class QtUploadOGLContext: public dp::OGLContext public: QtUploadOGLContext(QOpenGLContext * rootContext, QOffscreenSurface * surface); - // dp::OGLContext overrides: void Present() override; void MakeCurrent() override; void DoneCurrent() override; - void SetDefaultFramebuffer() override; + void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override; private: QOffscreenSurface * m_surface = nullptr; // non-owning ptr diff --git a/shaders/CMakeLists.txt b/shaders/CMakeLists.txt index 2c65193980..355651adb9 100644 --- a/shaders/CMakeLists.txt +++ b/shaders/CMakeLists.txt @@ -31,6 +31,18 @@ set( programs.hpp ) +if (PLATFORM_IPHONE) +append( + SRC + metal_program_params.hpp + metal_program_params.mm + metal_program_pool.hpp + metal_program_pool.mm + metal/debug_rect.metal + program_manager_metal.mm +) +endif() + add_library(${PROJECT_NAME} ${SRC}) set( diff --git a/shaders/Metal/debug_rect.metal b/shaders/Metal/debug_rect.metal new file mode 100644 index 0000000000..b795740622 --- /dev/null +++ b/shaders/Metal/debug_rect.metal @@ -0,0 +1,31 @@ +#include <metal_stdlib> +#include <simd/simd.h> +using namespace metal; + +typedef struct +{ + float2 a_position [[attribute(0)]]; +} Vertex_T; + +typedef struct +{ + float4 position [[position]]; +} Fragment_T; + +typedef struct +{ + float4 u_color; +} Uniforms_T; + +vertex Fragment_T vsDebugRect(const Vertex_T in [[stage_in]]) +{ + Fragment_T out; + out.position = float4(in.a_position, 0.0, 1.0); + return out; +} + +fragment float4 fsDebugRect(const Fragment_T in [[stage_in]], + constant Uniforms_T & uniforms [[buffer(0)]]) +{ + return uniforms.u_color; +} diff --git a/shaders/Metal/screen_quad.metal b/shaders/Metal/screen_quad.metal new file mode 100644 index 0000000000..c864387d6b --- /dev/null +++ b/shaders/Metal/screen_quad.metal @@ -0,0 +1,38 @@ +#include <metal_stdlib> +#include <simd/simd.h> +using namespace metal; + +typedef struct +{ + float2 a_position [[attribute(0)]]; + float2 a_texCoords [[attribute(1)]]; +} Vertex_T; + +typedef struct +{ + float4 position [[position]]; + float2 texCoords; +} Fragment_T; + +typedef struct +{ + float u_opacity; +} Uniforms_T; + +vertex Fragment_T vsScreenQuad(const Vertex_T in [[stage_in]]) +{ + Fragment_T out; + out.position = float4(in.a_position, 0.0, 1.0); + out.texCoords = in.a_texCoords; + return out; +} + +fragment float4 fsScreenQuad(const Fragment_T in [[stage_in]], + constant Uniforms_T & uniforms [[buffer(0)]], + texture2d<float> u_colorTex [[texture(0)]], + sampler u_colorTexSampler [[sampler(0)]]) +{ + float4 color = u_colorTex.sample(u_colorTexSampler, in.texCoords); + color.a *= uniforms.u_opacity; + return color; +} diff --git a/shaders/gl_program_params.cpp b/shaders/gl_program_params.cpp index 08bc3db140..a8109bdfc9 100644 --- a/shaders/gl_program_params.cpp +++ b/shaders/gl_program_params.cpp @@ -1,5 +1,6 @@ #include "shaders/gl_program_params.hpp" +#include "drape/gl_gpu_program.hpp" #include "drape/uniform_value.hpp" #include "base/assert.hpp" @@ -13,7 +14,7 @@ namespace struct UniformsGuard { template <typename ParamsType> - UniformsGuard(ref_ptr<dp::GpuProgram> program, ParamsType const &) + UniformsGuard(ref_ptr<dp::GLGpuProgram> program, ParamsType const &) : m_program(program) , m_paramsName(ParamsType::GetName()) { @@ -27,7 +28,7 @@ struct UniformsGuard CHECK_EQUAL(m_counter, uniformsCount, ("Not all numeric uniforms are set up", m_program->GetName(), m_paramsName)); } - ref_ptr<dp::GpuProgram> m_program; + ref_ptr<dp::GLGpuProgram> m_program; std::string const m_paramsName; uint32_t m_counter = 0; }; @@ -63,7 +64,7 @@ public: private: template<typename ParamType> - static bool Apply(ref_ptr<dp::GpuProgram> program, std::string const & name, ParamType const & p) + static bool Apply(ref_ptr<dp::GLGpuProgram> program, std::string const & name, ParamType const & p) { auto const location = program->GetUniformLocation(name); if (location < 0) diff --git a/shaders/gl_program_pool.cpp b/shaders/gl_program_pool.cpp index 7b985c81a9..80ac3cbbab 100644 --- a/shaders/gl_program_pool.cpp +++ b/shaders/gl_program_pool.cpp @@ -2,6 +2,9 @@ #include "shaders/program_params.hpp" #include "shaders/gl_shaders.hpp" +#include "drape/gl_gpu_program.hpp" +#include "drape/gl_functions.hpp" + namespace gpu { GLProgramPool::GLProgramPool(dp::ApiVersion apiVersion) @@ -21,6 +24,7 @@ GLProgramPool::GLProgramPool(dp::ApiVersion apiVersion) GLProgramPool::~GLProgramPool() { + GLFunctions::glUseProgram(0); ProgramParams::Destroy(); } @@ -33,7 +37,7 @@ drape_ptr<dp::GpuProgram> GLProgramPool::Get(Program program) dp::Shader::Type::FragmentShader); auto const name = DebugPrint(program); - return make_unique_dp<dp::GpuProgram>(name, vertexShader, fragmentShader); + return make_unique_dp<dp::GLGpuProgram>(name, vertexShader, fragmentShader); } void GLProgramPool::SetDefines(std::string const & defines) diff --git a/shaders/metal_program_params.hpp b/shaders/metal_program_params.hpp new file mode 100644 index 0000000000..f051ead1b3 --- /dev/null +++ b/shaders/metal_program_params.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "shaders/program_params.hpp" + +#include <cstdint> + +namespace gpu +{ +namespace metal +{ +class MetalProgramParamsSetter : public ProgramParamsSetter +{ +public: + void Apply(ref_ptr<dp::GpuProgram> program, MapProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, RouteProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, TrafficProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, TransitProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, GuiProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, ShapesProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, Arrow3dProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, DebugRectProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, ScreenQuadProgramParams const & params) override; + void Apply(ref_ptr<dp::GpuProgram> program, SMAAProgramParams const & params) override; +}; +} // namespace metal +} // namespace gpu diff --git a/shaders/metal_program_params.mm b/shaders/metal_program_params.mm new file mode 100644 index 0000000000..c39b8b7247 --- /dev/null +++ b/shaders/metal_program_params.mm @@ -0,0 +1,47 @@ +#include "shaders/metal_program_params.hpp" + +namespace gpu +{ +namespace metal +{ +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, MapProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, RouteProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, TrafficProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, TransitProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, GuiProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, ShapesProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, Arrow3dProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, DebugRectProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, ScreenQuadProgramParams const & params) +{ +} + +void MetalProgramParamsSetter::Apply(ref_ptr<dp::GpuProgram> program, SMAAProgramParams const & params) +{ +} +} // namespace metal +} // namespace gpu diff --git a/shaders/metal_program_pool.hpp b/shaders/metal_program_pool.hpp new file mode 100644 index 0000000000..1c8ed6130d --- /dev/null +++ b/shaders/metal_program_pool.hpp @@ -0,0 +1,29 @@ +#pragma once +#import <MetalKit/MetalKit.h> + +#include "shaders/program_pool.hpp" + +#include "drape/pointers.hpp" + +#include <map> +#include <string> + +namespace gpu +{ +namespace metal +{ +class MetalProgramPool : public ProgramPool +{ +public: + explicit MetalProgramPool(id<MTLDevice> device); + ~MetalProgramPool() override; + + drape_ptr<dp::GpuProgram> Get(Program program) override; + +private: + id<MTLFunction> GetFunction(std::string const & name); + id<MTLLibrary> m_library; + std::map<std::string, id<MTLFunction>> m_functions; +}; +} // namespace metal +} // namespace gpu diff --git a/shaders/metal_program_pool.mm b/shaders/metal_program_pool.mm new file mode 100644 index 0000000000..bb1011e5a1 --- /dev/null +++ b/shaders/metal_program_pool.mm @@ -0,0 +1,124 @@ +#include "shaders/metal_program_pool.hpp" +#include "shaders/program_params.hpp" + +#include "drape/metal/metal_gpu_program.hpp" + +#include "base/assert.hpp" + +#include <utility> + +namespace gpu +{ +namespace metal +{ +namespace +{ +struct ProgramInfo +{ + std::string m_vertexShaderName; + std::string m_fragmentShaderName; + ProgramInfo(std::string && vertexShaderName, std::string fragmentShaderName) + : m_vertexShaderName(std::move(vertexShaderName)) + , m_fragmentShaderName(std::move(fragmentShaderName)) + {} +}; + +std::array<ProgramInfo, static_cast<size_t>(Program::ProgramsCount)> const kMetalProgramsInfo = {{ + ProgramInfo("", ""), // ColoredSymbol + ProgramInfo("", ""), // Texturing + ProgramInfo("", ""), // MaskedTexturing + ProgramInfo("", ""), // Bookmark + ProgramInfo("", ""), // BookmarkAnim + ProgramInfo("", ""), // TextOutlined + ProgramInfo("", ""), // Text + ProgramInfo("", ""), // TextFixed + ProgramInfo("", ""), // TextOutlinedGui + ProgramInfo("", ""), // Area + ProgramInfo("", ""), // AreaOutline + ProgramInfo("", ""), // Area3d + ProgramInfo("", ""), // Area3dOutline + ProgramInfo("", ""), // Line + ProgramInfo("", ""), // CapJoin + ProgramInfo("", ""), // TransitCircle + ProgramInfo("", ""), // DashedLine + ProgramInfo("", ""), // PathSymbol + ProgramInfo("", ""), // HatchingArea + ProgramInfo("", ""), // TexturingGui + ProgramInfo("", ""), // Ruler + ProgramInfo("", ""), // Accuracy + ProgramInfo("", ""), // MyPosition + ProgramInfo("", ""), // Transit + ProgramInfo("", ""), // TransitMarker + ProgramInfo("", ""), // Route + ProgramInfo("", ""), // RouteDash + ProgramInfo("", ""), // RouteArrow + ProgramInfo("", ""), // RouteMarker + ProgramInfo("", ""), // CirclePoint + ProgramInfo("vsDebugRect", "fsDebugRect"), // DebugRect + ProgramInfo("vsScreenQuad", "fsScreenQuad"), // ScreenQuad + ProgramInfo("", ""), // Arrow3d + ProgramInfo("", ""), // Arrow3dShadow + ProgramInfo("", ""), // Arrow3dOutline + ProgramInfo("", ""), // ColoredSymbolBillboard + ProgramInfo("", ""), // TexturingBillboard + ProgramInfo("", ""), // MaskedTexturingBillboard + ProgramInfo("", ""), // BookmarkBillboard + ProgramInfo("", ""), // BookmarkAnimBillboard + ProgramInfo("", ""), // TextOutlinedBillboard + ProgramInfo("", ""), // TextBillboard + ProgramInfo("", ""), // TextFixedBillboard + ProgramInfo("", ""), // Traffic + ProgramInfo("", ""), // TrafficLine + ProgramInfo("", ""), // TrafficCircle + ProgramInfo("", ""), // SmaaEdges + ProgramInfo("", ""), // SmaaBlendingWeight + ProgramInfo("", ""), // SmaaFinal +}}; +} // namespace + +MetalProgramPool::MetalProgramPool(id<MTLDevice> device) +{ + ProgramParams::Init(); + + NSString * libPath = [[NSBundle mainBundle] pathForResource:@"shaders_metal" ofType:@"metallib"]; + NSError * error; + m_library = [device newLibraryWithFile:libPath error:&error]; + if (error) + { + NSLog(@"%@", error); + CHECK(false, ("Shaders library creation error.")); + } + m_library.label = @"Shaders library"; +} + +MetalProgramPool::~MetalProgramPool() +{ + ProgramParams::Destroy(); +} + +drape_ptr<dp::GpuProgram> MetalProgramPool::Get(Program program) +{ + auto const & info = kMetalProgramsInfo[static_cast<size_t>(program)]; + CHECK(!info.m_vertexShaderName.empty(), ()); + CHECK(!info.m_fragmentShaderName.empty(), ()); + + auto const name = DebugPrint(program); + return make_unique_dp<dp::metal::MetalGpuProgram>(name, GetFunction(info.m_vertexShaderName), + GetFunction(info.m_fragmentShaderName)); +} + +id<MTLFunction> MetalProgramPool::GetFunction(std::string const & name) +{ + auto const it = m_functions.find(name); + if (it == m_functions.end()) + { + id<MTLFunction> f = [m_library newFunctionWithName:@(name.c_str())]; + CHECK(f != nil, ()); + f.label = [@"Function " stringByAppendingString:@(name.c_str())]; + m_functions.insert(std::make_pair(name, f)); + return f; + } + return it->second; +} +} // namespace metal +} // namespace gpu diff --git a/shaders/program_manager.cpp b/shaders/program_manager.cpp index b0f83289fc..faaaa86ef1 100644 --- a/shaders/program_manager.cpp +++ b/shaders/program_manager.cpp @@ -1,7 +1,7 @@ #include "shaders/program_manager.hpp" #include "shaders/gl_program_pool.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include "drape/support_manager.hpp" #include "base/logging.hpp" @@ -13,39 +13,52 @@ namespace gpu { -void ProgramManager::Init(dp::ApiVersion apiVersion) +void ProgramManager::Init(ref_ptr<dp::GraphicsContext> context) { + auto const apiVersion = context->GetApiVersion(); if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3) { - std::string globalDefines; - - // This feature is not supported on some Android devices (especially on Android 4.x version). - // Since we can't predict on which devices it'll work fine, we have to turn off for all devices. -#if !defined(OMIM_OS_ANDROID) - if (GLFunctions::glGetInteger(gl_const::GLMaxVertexTextures) > 0) - { - LOG(LINFO, ("VTF enabled")); - globalDefines.append("#define ENABLE_VTF\n"); // VTF == Vertex Texture Fetch - } + InitForOpenGL(context); + } + else if (apiVersion == dp::ApiVersion::Metal) + { +#if defined(OMIM_OS_IPHONE) + InitForMetal(context); #endif - - if (dp::SupportManager::Instance().IsSamsungGoogleNexus()) - globalDefines.append("#define SAMSUNG_GOOGLE_NEXUS\n"); - - if (apiVersion == dp::ApiVersion::OpenGLES3) - globalDefines.append("#define GLES3\n"); - - m_pool = make_unique_dp<GLProgramPool>(apiVersion); - ref_ptr<GLProgramPool> pool = make_ref(m_pool); - pool->SetDefines(globalDefines); - - m_paramsSetter = make_unique_dp<GLProgramParamsSetter>(); } else { - CHECK(false, ("Unsupported API version")); + CHECK(false, ("Unsupported API version.")); } } + +void ProgramManager::InitForOpenGL(ref_ptr<dp::GraphicsContext> context) +{ + std::string globalDefines; + + // This feature is not supported on some Android devices (especially on Android 4.x version). + // Since we can't predict on which devices it'll work fine, we have to turn off for all devices. +#if !defined(OMIM_OS_ANDROID) + if (GLFunctions::glGetInteger(gl_const::GLMaxVertexTextures) > 0) + { + LOG(LINFO, ("VTF enabled")); + globalDefines.append("#define ENABLE_VTF\n"); // VTF == Vertex Texture Fetch + } +#endif + + if (dp::SupportManager::Instance().IsSamsungGoogleNexus()) + globalDefines.append("#define SAMSUNG_GOOGLE_NEXUS\n"); + + auto const apiVersion = context->GetApiVersion(); + if (apiVersion == dp::ApiVersion::OpenGLES3) + globalDefines.append("#define GLES3\n"); + + m_pool = make_unique_dp<GLProgramPool>(apiVersion); + ref_ptr<GLProgramPool> pool = make_ref(m_pool); + pool->SetDefines(globalDefines); + + m_paramsSetter = make_unique_dp<GLProgramParamsSetter>(); +} ref_ptr<dp::GpuProgram> ProgramManager::GetProgram(Program program) { diff --git a/shaders/program_manager.hpp b/shaders/program_manager.hpp index e3209e6b44..f4b988496d 100644 --- a/shaders/program_manager.hpp +++ b/shaders/program_manager.hpp @@ -4,6 +4,7 @@ #include "shaders/program_params.hpp" #include "drape/drape_global.hpp" +#include "drape/graphics_context.hpp" #include "drape/gpu_program.hpp" #include "drape/pointers.hpp" @@ -19,12 +20,16 @@ class ProgramManager public: ProgramManager() = default; - void Init(dp::ApiVersion apiVersion); + void Init(ref_ptr<dp::GraphicsContext> context); ref_ptr<dp::GpuProgram> GetProgram(Program program); ref_ptr<ProgramParamsSetter> GetParamsSetter() const; private: + void InitForOpenGL(ref_ptr<dp::GraphicsContext> context); + // Definition of this method is in separate .mm-file. + void InitForMetal(ref_ptr<dp::GraphicsContext> context); + using Programs = std::array<drape_ptr<dp::GpuProgram>, static_cast<size_t>(Program::ProgramsCount)>; Programs m_programs; diff --git a/shaders/program_manager_metal.mm b/shaders/program_manager_metal.mm new file mode 100644 index 0000000000..43c3235d8c --- /dev/null +++ b/shaders/program_manager_metal.mm @@ -0,0 +1,16 @@ +#include "shaders/program_manager.hpp" +#include "shaders/metal_program_params.hpp" +#include "shaders/metal_program_pool.hpp" + +#include "drape/metal/metal_base_context.hpp" + +namespace gpu +{ +void ProgramManager::InitForMetal(ref_ptr<dp::GraphicsContext> context) +{ + ASSERT(dynamic_cast<dp::metal::MetalBaseContext *>(context.get()) != nullptr, ()); + ref_ptr<dp::metal::MetalBaseContext> metalContext = context; + m_pool = make_unique_dp<metal::MetalProgramPool>(metalContext->GetMetalDevice()); + m_paramsSetter = make_unique_dp<metal::MetalProgramParamsSetter>(); +} +} // namespace gpu diff --git a/shaders/shaders_tests/gl_program_params_tests.cpp b/shaders/shaders_tests/gl_program_params_tests.cpp index 25dd8e6006..ec5c1d9257 100644 --- a/shaders/shaders_tests/gl_program_params_tests.cpp +++ b/shaders/shaders_tests/gl_program_params_tests.cpp @@ -5,7 +5,7 @@ #include "shaders/gl_program_pool.hpp" #include "drape/drape_global.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include <functional> diff --git a/shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp b/shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp index b33cbba939..67c84e9fbc 100644 --- a/shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp +++ b/shaders/shaders_tests/gl_shaders_desktop_compile_tests.cpp @@ -4,7 +4,7 @@ #include "shaders/gl_program_pool.hpp" #include "drape/drape_global.hpp" -#include "drape/glfunctions.hpp" +#include "drape/gl_functions.hpp" #include <functional> diff --git a/xcode/common.xcconfig b/xcode/common.xcconfig index 8cb6e987fb..2cb68b3ff9 100644 --- a/xcode/common.xcconfig +++ b/xcode/common.xcconfig @@ -64,7 +64,7 @@ CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer COMPILER_INDEX_STORE_ENABLE = YES -DEBUG_INFORMATION_FORMAT = dwarf +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym ENABLE_BITCODE = YES ENABLE_STRICT_OBJC_MSGSEND = YES GCC_NO_COMMON_BLOCKS = YES diff --git a/xcode/drape/drape.xcodeproj/project.pbxproj b/xcode/drape/drape.xcodeproj/project.pbxproj index e8c2461cf5..2718cd4451 100644 --- a/xcode/drape/drape.xcodeproj/project.pbxproj +++ b/xcode/drape/drape.xcodeproj/project.pbxproj @@ -16,9 +16,27 @@ 4513BF0E1EC2F0760066565C /* viewport.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4513BF0A1EC2F0760066565C /* viewport.hpp */; }; 45201E951CE605B1008A4842 /* constants.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45201E941CE605B1008A4842 /* constants.hpp */; }; 45447109211462A300D28C28 /* texture_types.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45447108211462A300D28C28 /* texture_types.hpp */; }; + 4560F591213EC93400CC736C /* render_state_metal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4560F590213EC93300CC736C /* render_state_metal.mm */; }; + 4560F59E213F986E00CC736C /* metal_states.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4560F59C213F986D00CC736C /* metal_states.hpp */; }; + 4560F59F213F986E00CC736C /* metal_states.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4560F59D213F986D00CC736C /* metal_states.mm */; }; + 45789ED72133DFC2009955CC /* metal_base_context.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45789ED52133DFC2009955CC /* metal_base_context.mm */; }; + 45789EDA2133E14F009955CC /* metal_base_context.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45789ED92133E14F009955CC /* metal_base_context.hpp */; }; + 45789EF2213557F7009955CC /* gl_constants.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45789EE9213557F4009955CC /* gl_constants.hpp */; }; + 45789EF3213557F7009955CC /* gl_extensions_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45789EEA213557F5009955CC /* gl_extensions_list.cpp */; }; + 45789EF4213557F7009955CC /* gl_functions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45789EEB213557F5009955CC /* gl_functions.cpp */; }; + 45789EF5213557F7009955CC /* gl_gpu_program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45789EEC213557F5009955CC /* gl_gpu_program.cpp */; }; + 45789EF6213557F7009955CC /* gl_includes.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45789EED213557F5009955CC /* gl_includes.hpp */; }; + 45789EF7213557F7009955CC /* gl_gpu_program.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45789EEE213557F6009955CC /* gl_gpu_program.hpp */; }; + 45789EF8213557F7009955CC /* gl_constants.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45789EEF213557F6009955CC /* gl_constants.cpp */; }; + 45789EF9213557F7009955CC /* gl_functions.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45789EF0213557F6009955CC /* gl_functions.hpp */; }; + 45789EFA213557F7009955CC /* gl_extensions_list.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45789EF1213557F7009955CC /* gl_extensions_list.hpp */; }; 457B536620358F7E00E4E752 /* drape_routine.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 457B536320358F7D00E4E752 /* drape_routine.hpp */; }; 457B536720358F7E00E4E752 /* glyph_generator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 457B536420358F7D00E4E752 /* glyph_generator.cpp */; }; 457B536820358F7E00E4E752 /* glyph_generator.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 457B536520358F7E00E4E752 /* glyph_generator.hpp */; }; + 4598437321357DC500F8CAB2 /* metal_gpu_program.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4598437121357DC500F8CAB2 /* metal_gpu_program.hpp */; }; + 459843792136AC2600F8CAB2 /* metal_mesh_object_impl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 459843772136AC2600F8CAB2 /* metal_mesh_object_impl.mm */; }; + 4598438F2139967F00F8CAB2 /* metal_texture.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4598438D2139967F00F8CAB2 /* metal_texture.mm */; }; + 459843902139967F00F8CAB2 /* metal_texture.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 4598438E2139967F00F8CAB2 /* metal_texture.hpp */; }; 45D7ADE22113535600160DE3 /* render_state.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 45D7ADE02113535500160DE3 /* render_state.hpp */; }; 45D7ADE32113535600160DE3 /* render_state.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45D7ADE12113535600160DE3 /* render_state.cpp */; }; 670947231BDF9A4F005014C0 /* data_buffer_impl.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 670947151BDF9A4F005014C0 /* data_buffer_impl.hpp */; }; @@ -54,18 +72,10 @@ 6729A5761A69213A007D5872 /* dynamic_texture.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A5121A69213A007D5872 /* dynamic_texture.hpp */; }; 6729A5771A69213A007D5872 /* font_texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6729A5131A69213A007D5872 /* font_texture.cpp */; }; 6729A5781A69213A007D5872 /* font_texture.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A5141A69213A007D5872 /* font_texture.hpp */; }; - 6729A5791A69213A007D5872 /* glconstants.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6729A5151A69213A007D5872 /* glconstants.cpp */; }; - 6729A57A1A69213A007D5872 /* glconstants.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A5161A69213A007D5872 /* glconstants.hpp */; }; - 6729A57B1A69213A007D5872 /* glextensions_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6729A5171A69213A007D5872 /* glextensions_list.cpp */; }; - 6729A57C1A69213A007D5872 /* glextensions_list.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A5181A69213A007D5872 /* glextensions_list.hpp */; }; - 6729A57D1A69213A007D5872 /* glfunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6729A5191A69213A007D5872 /* glfunctions.cpp */; }; - 6729A57E1A69213A007D5872 /* glfunctions.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A51A1A69213A007D5872 /* glfunctions.hpp */; }; - 6729A57F1A69213A007D5872 /* glIncludes.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A51B1A69213A007D5872 /* glIncludes.hpp */; }; 6729A5801A69213A007D5872 /* glsl_func.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A51C1A69213A007D5872 /* glsl_func.hpp */; }; 6729A5811A69213A007D5872 /* glsl_types.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A51D1A69213A007D5872 /* glsl_types.hpp */; }; 6729A5861A69213A007D5872 /* gpu_buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6729A5221A69213A007D5872 /* gpu_buffer.cpp */; }; 6729A5871A69213A007D5872 /* gpu_buffer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A5231A69213A007D5872 /* gpu_buffer.hpp */; }; - 6729A58A1A69213A007D5872 /* gpu_program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6729A5261A69213A007D5872 /* gpu_program.cpp */; }; 6729A58B1A69213A007D5872 /* gpu_program.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A5271A69213A007D5872 /* gpu_program.hpp */; }; 6729A58C1A69213A007D5872 /* index_buffer_mutator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6729A5281A69213A007D5872 /* index_buffer_mutator.cpp */; }; 6729A58D1A69213A007D5872 /* index_buffer_mutator.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6729A5291A69213A007D5872 /* index_buffer_mutator.hpp */; }; @@ -125,9 +135,27 @@ 4513BF0A1EC2F0760066565C /* viewport.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = viewport.hpp; sourceTree = "<group>"; }; 45201E941CE605B1008A4842 /* constants.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = constants.hpp; sourceTree = "<group>"; }; 45447108211462A300D28C28 /* texture_types.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = texture_types.hpp; sourceTree = "<group>"; }; + 4560F590213EC93300CC736C /* render_state_metal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = render_state_metal.mm; sourceTree = "<group>"; }; + 4560F59C213F986D00CC736C /* metal_states.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = metal_states.hpp; sourceTree = "<group>"; }; + 4560F59D213F986D00CC736C /* metal_states.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = metal_states.mm; sourceTree = "<group>"; }; + 45789ED52133DFC2009955CC /* metal_base_context.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = metal_base_context.mm; sourceTree = "<group>"; }; + 45789ED92133E14F009955CC /* metal_base_context.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = metal_base_context.hpp; sourceTree = "<group>"; }; + 45789EE9213557F4009955CC /* gl_constants.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gl_constants.hpp; sourceTree = "<group>"; }; + 45789EEA213557F5009955CC /* gl_extensions_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gl_extensions_list.cpp; sourceTree = "<group>"; }; + 45789EEB213557F5009955CC /* gl_functions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gl_functions.cpp; sourceTree = "<group>"; }; + 45789EEC213557F5009955CC /* gl_gpu_program.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gl_gpu_program.cpp; sourceTree = "<group>"; }; + 45789EED213557F5009955CC /* gl_includes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gl_includes.hpp; sourceTree = "<group>"; }; + 45789EEE213557F6009955CC /* gl_gpu_program.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gl_gpu_program.hpp; sourceTree = "<group>"; }; + 45789EEF213557F6009955CC /* gl_constants.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gl_constants.cpp; sourceTree = "<group>"; }; + 45789EF0213557F6009955CC /* gl_functions.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gl_functions.hpp; sourceTree = "<group>"; }; + 45789EF1213557F7009955CC /* gl_extensions_list.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gl_extensions_list.hpp; sourceTree = "<group>"; }; 457B536320358F7D00E4E752 /* drape_routine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = drape_routine.hpp; sourceTree = "<group>"; }; 457B536420358F7D00E4E752 /* glyph_generator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glyph_generator.cpp; sourceTree = "<group>"; }; 457B536520358F7E00E4E752 /* glyph_generator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = glyph_generator.hpp; sourceTree = "<group>"; }; + 4598437121357DC500F8CAB2 /* metal_gpu_program.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = metal_gpu_program.hpp; sourceTree = "<group>"; }; + 459843772136AC2600F8CAB2 /* metal_mesh_object_impl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = metal_mesh_object_impl.mm; sourceTree = "<group>"; }; + 4598438D2139967F00F8CAB2 /* metal_texture.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = metal_texture.mm; sourceTree = "<group>"; }; + 4598438E2139967F00F8CAB2 /* metal_texture.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = metal_texture.hpp; sourceTree = "<group>"; }; 45D7ADE02113535500160DE3 /* render_state.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = render_state.hpp; sourceTree = "<group>"; }; 45D7ADE12113535600160DE3 /* render_state.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render_state.cpp; sourceTree = "<group>"; }; 670947151BDF9A4F005014C0 /* data_buffer_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = data_buffer_impl.hpp; sourceTree = "<group>"; }; @@ -164,18 +192,10 @@ 6729A5121A69213A007D5872 /* dynamic_texture.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = dynamic_texture.hpp; sourceTree = "<group>"; }; 6729A5131A69213A007D5872 /* font_texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font_texture.cpp; sourceTree = "<group>"; }; 6729A5141A69213A007D5872 /* font_texture.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = font_texture.hpp; sourceTree = "<group>"; }; - 6729A5151A69213A007D5872 /* glconstants.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glconstants.cpp; sourceTree = "<group>"; }; - 6729A5161A69213A007D5872 /* glconstants.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = glconstants.hpp; sourceTree = "<group>"; }; - 6729A5171A69213A007D5872 /* glextensions_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glextensions_list.cpp; sourceTree = "<group>"; }; - 6729A5181A69213A007D5872 /* glextensions_list.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = glextensions_list.hpp; sourceTree = "<group>"; }; - 6729A5191A69213A007D5872 /* glfunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glfunctions.cpp; sourceTree = "<group>"; }; - 6729A51A1A69213A007D5872 /* glfunctions.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = glfunctions.hpp; sourceTree = "<group>"; }; - 6729A51B1A69213A007D5872 /* glIncludes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = glIncludes.hpp; sourceTree = "<group>"; }; 6729A51C1A69213A007D5872 /* glsl_func.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = glsl_func.hpp; sourceTree = "<group>"; }; 6729A51D1A69213A007D5872 /* glsl_types.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = glsl_types.hpp; sourceTree = "<group>"; }; 6729A5221A69213A007D5872 /* gpu_buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gpu_buffer.cpp; sourceTree = "<group>"; }; 6729A5231A69213A007D5872 /* gpu_buffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gpu_buffer.hpp; sourceTree = "<group>"; }; - 6729A5261A69213A007D5872 /* gpu_program.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gpu_program.cpp; sourceTree = "<group>"; }; 6729A5271A69213A007D5872 /* gpu_program.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gpu_program.hpp; sourceTree = "<group>"; }; 6729A5281A69213A007D5872 /* index_buffer_mutator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = index_buffer_mutator.cpp; sourceTree = "<group>"; }; 6729A5291A69213A007D5872 /* index_buffer_mutator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = index_buffer_mutator.hpp; sourceTree = "<group>"; }; @@ -234,6 +254,22 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 45789ED42133DF91009955CC /* metal */ = { + isa = PBXGroup; + children = ( + 45789ED92133E14F009955CC /* metal_base_context.hpp */, + 45789ED52133DFC2009955CC /* metal_base_context.mm */, + 4598437121357DC500F8CAB2 /* metal_gpu_program.hpp */, + 459843772136AC2600F8CAB2 /* metal_mesh_object_impl.mm */, + 4560F59C213F986D00CC736C /* metal_states.hpp */, + 4560F59D213F986D00CC736C /* metal_states.mm */, + 4598438E2139967F00F8CAB2 /* metal_texture.hpp */, + 4598438D2139967F00F8CAB2 /* metal_texture.mm */, + 4560F590213EC93300CC736C /* render_state_metal.mm */, + ); + path = metal; + sourceTree = "<group>"; + }; 6729A4E81A691F6A007D5872 = { isa = PBXGroup; children = ( @@ -286,13 +322,15 @@ 6729A5141A69213A007D5872 /* font_texture.hpp */, 4513BF071EC2F0760066565C /* framebuffer.cpp */, 4513BF081EC2F0760066565C /* framebuffer.hpp */, - 6729A5151A69213A007D5872 /* glconstants.cpp */, - 6729A5161A69213A007D5872 /* glconstants.hpp */, - 6729A5171A69213A007D5872 /* glextensions_list.cpp */, - 6729A5181A69213A007D5872 /* glextensions_list.hpp */, - 6729A5191A69213A007D5872 /* glfunctions.cpp */, - 6729A51A1A69213A007D5872 /* glfunctions.hpp */, - 6729A51B1A69213A007D5872 /* glIncludes.hpp */, + 45789EEF213557F6009955CC /* gl_constants.cpp */, + 45789EE9213557F4009955CC /* gl_constants.hpp */, + 45789EEA213557F5009955CC /* gl_extensions_list.cpp */, + 45789EF1213557F7009955CC /* gl_extensions_list.hpp */, + 45789EEB213557F5009955CC /* gl_functions.cpp */, + 45789EF0213557F6009955CC /* gl_functions.hpp */, + 45789EEC213557F5009955CC /* gl_gpu_program.cpp */, + 45789EEE213557F6009955CC /* gl_gpu_program.hpp */, + 45789EED213557F5009955CC /* gl_includes.hpp */, 6729A51C1A69213A007D5872 /* glsl_func.hpp */, 6729A51D1A69213A007D5872 /* glsl_types.hpp */, 457B536420358F7D00E4E752 /* glyph_generator.cpp */, @@ -301,7 +339,6 @@ 6709471A1BDF9A4F005014C0 /* glyph_manager.hpp */, 6729A5221A69213A007D5872 /* gpu_buffer.cpp */, 6729A5231A69213A007D5872 /* gpu_buffer.hpp */, - 6729A5261A69213A007D5872 /* gpu_program.cpp */, 6729A5271A69213A007D5872 /* gpu_program.hpp */, BBB72E992111CE9100249D4F /* graphics_context_factory.cpp */, BBB72E982111CE9100249D4F /* graphics_context_factory.hpp */, @@ -318,6 +355,7 @@ 670947201BDF9A4F005014C0 /* index_storage.hpp */, BBB72E9D2118A45700249D4F /* mesh_object.cpp */, BBB72E9E2118A45800249D4F /* mesh_object.hpp */, + 45789ED42133DF91009955CC /* metal */, 6729A52C1A69213A007D5872 /* object_pool.hpp */, BBB72E8F2110AF0F00249D4F /* oglcontext.cpp */, 6729A52D1A69213A007D5872 /* oglcontext.hpp */, @@ -379,17 +417,19 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 459843902139967F00F8CAB2 /* metal_texture.hpp in Headers */, 6729A5A31A69213A007D5872 /* stipple_pen_resource.hpp in Headers */, 6729A5661A69213A007D5872 /* attribute_provider.hpp in Headers */, - 6729A57C1A69213A007D5872 /* glextensions_list.hpp in Headers */, 6729A58D1A69213A007D5872 /* index_buffer_mutator.hpp in Headers */, 6729A5781A69213A007D5872 /* font_texture.hpp in Headers */, 670947231BDF9A4F005014C0 /* data_buffer_impl.hpp in Headers */, 6729A59B1A69213A007D5872 /* render_bucket.hpp in Headers */, + 45789EFA213557F7009955CC /* gl_extensions_list.hpp in Headers */, 6729A56C1A69213A007D5872 /* binding_info.hpp in Headers */, 3492DA0B1CA2D91C00C1F3B3 /* visual_scale.hpp in Headers */, 6729A5971A69213A007D5872 /* overlay_tree.hpp in Headers */, 6729A5751A69213A007D5872 /* drape_global.hpp in Headers */, + 4560F59E213F986E00CC736C /* metal_states.hpp in Headers */, 6729A5701A69213A007D5872 /* color.hpp in Headers */, 6729A5801A69213A007D5872 /* glsl_func.hpp in Headers */, 6729A5761A69213A007D5872 /* dynamic_texture.hpp in Headers */, @@ -400,7 +440,10 @@ 45447109211462A300D28C28 /* texture_types.hpp in Headers */, BBB72EA02118A45800249D4F /* mesh_object.hpp in Headers */, 675D219A1BFB876E00717E4F /* projection.hpp in Headers */, + 45789EF6213557F7009955CC /* gl_includes.hpp in Headers */, + 45789EF9213557F7009955CC /* gl_functions.hpp in Headers */, 670947291BDF9A4F005014C0 /* hw_texture_ios.hpp in Headers */, + 4598437321357DC500F8CAB2 /* metal_gpu_program.hpp in Headers */, 670947281BDF9A4F005014C0 /* glyph_manager.hpp in Headers */, 6729A5991A69213A007D5872 /* pointers.hpp in Headers */, 6729A5A51A69213A007D5872 /* symbols_texture.hpp in Headers */, @@ -408,12 +451,12 @@ BBB72E9A2111CE9100249D4F /* graphics_context.hpp in Headers */, 6729A5741A69213A007D5872 /* data_buffer.hpp in Headers */, 6729A58B1A69213A007D5872 /* gpu_program.hpp in Headers */, + 45789EDA2133E14F009955CC /* metal_base_context.hpp in Headers */, 6743D3451C3533AE0095054B /* support_manager.hpp in Headers */, 6729A5B31A69213A007D5872 /* vertex_decl.hpp in Headers */, 6729A5721A69213A007D5872 /* cpu_buffer.hpp in Headers */, 6729A5AD1A69213A007D5872 /* uniform_value.hpp in Headers */, 6729A5951A69213A007D5872 /* overlay_handle.hpp in Headers */, - 6729A57E1A69213A007D5872 /* glfunctions.hpp in Headers */, 45201E951CE605B1008A4842 /* constants.hpp in Headers */, 6709472E1BDF9A4F005014C0 /* index_storage.hpp in Headers */, 6729A5B51A69213A007D5872 /* vertex_array_buffer.hpp in Headers */, @@ -426,16 +469,16 @@ 4513BF0C1EC2F0760066565C /* framebuffer.hpp in Headers */, 6729A5641A69213A007D5872 /* attribute_buffer_mutator.hpp in Headers */, 6729A5811A69213A007D5872 /* glsl_types.hpp in Headers */, - 6729A57A1A69213A007D5872 /* glconstants.hpp in Headers */, 6709472C1BDF9A4F005014C0 /* hw_texture.hpp in Headers */, 6729A5911A69213A007D5872 /* oglcontext.hpp in Headers */, 457B536620358F7E00E4E752 /* drape_routine.hpp in Headers */, + 45789EF2213557F7009955CC /* gl_constants.hpp in Headers */, 6729A5AB1A69213A007D5872 /* texture.hpp in Headers */, - 6729A57F1A69213A007D5872 /* glIncludes.hpp in Headers */, 4513BF0E1EC2F0760066565C /* viewport.hpp in Headers */, 6729A5A91A69213A007D5872 /* texture_of_colors.hpp in Headers */, 6729A5871A69213A007D5872 /* gpu_buffer.hpp in Headers */, BB035F6C1E3A2A5C00519962 /* drape_diagnostics.hpp in Headers */, + 45789EF7213557F7009955CC /* gl_gpu_program.hpp in Headers */, 6729A56E1A69213A007D5872 /* buffer_base.hpp in Headers */, 6729A58F1A69213A007D5872 /* index_buffer.hpp in Headers */, ); @@ -501,15 +544,17 @@ 6729A5631A69213A007D5872 /* attribute_buffer_mutator.cpp in Sources */, 6729A56B1A69213A007D5872 /* binding_info.cpp in Sources */, BBB72E9F2118A45800249D4F /* mesh_object.cpp in Sources */, - 6729A5791A69213A007D5872 /* glconstants.cpp in Sources */, + 45789EF5213557F7009955CC /* gl_gpu_program.cpp in Sources */, + 45789EF3213557F7009955CC /* gl_extensions_list.cpp in Sources */, 6729A5941A69213A007D5872 /* overlay_handle.cpp in Sources */, 6709472D1BDF9A4F005014C0 /* index_storage.cpp in Sources */, 6729A5861A69213A007D5872 /* gpu_buffer.cpp in Sources */, + 45789EF8213557F7009955CC /* gl_constants.cpp in Sources */, 6729A59A1A69213A007D5872 /* render_bucket.cpp in Sources */, - 6729A58A1A69213A007D5872 /* gpu_program.cpp in Sources */, + 4560F59F213F986E00CC736C /* metal_states.mm in Sources */, 6709472A1BDF9A4F005014C0 /* hw_texture_ios.mm in Sources */, + 459843792136AC2600F8CAB2 /* metal_mesh_object_impl.mm in Sources */, 4513BF0D1EC2F0760066565C /* viewport.cpp in Sources */, - 6729A57B1A69213A007D5872 /* glextensions_list.cpp in Sources */, 34C624C91DABDB2000510300 /* static_texture.cpp in Sources */, 4513BF0B1EC2F0760066565C /* framebuffer.cpp in Sources */, 6729A5981A69213A007D5872 /* pointers.cpp in Sources */, @@ -523,13 +568,16 @@ 6729A5691A69213A007D5872 /* batcher.cpp in Sources */, 670947251BDF9A4F005014C0 /* bidi.cpp in Sources */, 6729A58C1A69213A007D5872 /* index_buffer_mutator.cpp in Sources */, + 4598438F2139967F00F8CAB2 /* metal_texture.mm in Sources */, BBB72E902110AF0F00249D4F /* oglcontext.cpp in Sources */, - 6729A57D1A69213A007D5872 /* glfunctions.cpp in Sources */, + 45789EF4213557F7009955CC /* gl_functions.cpp in Sources */, + 45789ED72133DFC2009955CC /* metal_base_context.mm in Sources */, 6729A5731A69213A007D5872 /* data_buffer.cpp in Sources */, 6709472B1BDF9A4F005014C0 /* hw_texture.cpp in Sources */, 6729A5AA1A69213A007D5872 /* texture.cpp in Sources */, BBB72E9C2111CE9100249D4F /* graphics_context_factory.cpp in Sources */, 6729A5771A69213A007D5872 /* font_texture.cpp in Sources */, + 4560F591213EC93400CC736C /* render_state_metal.mm in Sources */, 45D7ADE32113535600160DE3 /* render_state.cpp in Sources */, 6729A58E1A69213A007D5872 /* index_buffer.cpp in Sources */, 6729A5A61A69213A007D5872 /* texture_manager.cpp in Sources */, @@ -550,7 +598,7 @@ /* Begin XCBuildConfiguration section */ 6729A4FA1A691F6A007D5872 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 34AF87CA1DBE4F4900E5E7DC /* common-release.xcconfig */; + baseConfigurationReference = 34AF87C91DBE4F4900E5E7DC /* common-debug.xcconfig */; buildSettings = { ENABLE_TESTABILITY = YES; GCC_OPTIMIZATION_LEVEL = 2; diff --git a/xcode/drape_frontend/drape_frontend.xcodeproj/project.pbxproj b/xcode/drape_frontend/drape_frontend.xcodeproj/project.pbxproj index e56311ac57..36ef0dcba8 100644 --- a/xcode/drape_frontend/drape_frontend.xcodeproj/project.pbxproj +++ b/xcode/drape_frontend/drape_frontend.xcodeproj/project.pbxproj @@ -952,7 +952,7 @@ /* Begin XCBuildConfiguration section */ 6709473C1BDF9B82005014C0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 34AF87CC1DBE508400E5E7DC /* common-release.xcconfig */; + baseConfigurationReference = 34AF87CB1DBE508400E5E7DC /* common-debug.xcconfig */; buildSettings = { ENABLE_TESTABILITY = YES; GCC_OPTIMIZATION_LEVEL = 2; diff --git a/xcode/shaders/shaders.xcodeproj/project.pbxproj b/xcode/shaders/shaders.xcodeproj/project.pbxproj index 9f7e0b9b25..4cf17bed44 100644 --- a/xcode/shaders/shaders.xcodeproj/project.pbxproj +++ b/xcode/shaders/shaders.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 4560F58A213D57D600CC736C /* debug_rect.metal in Sources */ = {isa = PBXBuildFile; fileRef = 45789EDC21342BDE009955CC /* debug_rect.metal */; }; + 4560F58B213D57D600CC736C /* screen_quad.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4560F582213D44CE00CC736C /* screen_quad.metal */; }; 4561ADF520E378CB0096BC12 /* program_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4561ADF320E378CB0096BC12 /* program_manager.cpp */; }; 4561ADF920E37A6F0096BC12 /* shaders_compiler in Resources */ = {isa = PBXBuildFile; fileRef = 4561ADF820E37A6F0096BC12 /* shaders_compiler */; }; 4566608A20E256240085E8C1 /* program_params.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4566608020E256230085E8C1 /* program_params.cpp */; }; @@ -28,8 +30,21 @@ 4566610520E25EF70085E8C1 /* libplatform.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4566610420E25EF70085E8C1 /* libplatform.a */; }; 4566610720E25F560085E8C1 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4566610620E25F560085E8C1 /* libz.tbd */; }; 4566610A20E25F790085E8C1 /* test_main_loop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4566610920E25F790085E8C1 /* test_main_loop.cpp */; }; + 45789EE021343F70009955CC /* metal_program_pool.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45789EDE21343F70009955CC /* metal_program_pool.mm */; }; + 45789EE421353CA3009955CC /* program_manager_metal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45789EE321353CA3009955CC /* program_manager_metal.mm */; }; + 45789EE72135464D009955CC /* metal_program_params.mm in Sources */ = {isa = PBXBuildFile; fileRef = 45789EE62135464D009955CC /* metal_program_params.mm */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 4560F58C213D57F900CC736C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4566606620E254060085E8C1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4598437B21394BE000F8CAB2; + remoteInfo = shaders_metal; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 4566606C20E254060085E8C1 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -43,6 +58,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 4560F582213D44CE00CC736C /* screen_quad.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = screen_quad.metal; sourceTree = "<group>"; }; 4561ADF320E378CB0096BC12 /* program_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = program_manager.cpp; sourceTree = "<group>"; }; 4561ADF420E378CB0096BC12 /* program_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = program_manager.hpp; sourceTree = "<group>"; }; 4561ADF820E37A6F0096BC12 /* shaders_compiler */ = {isa = PBXFileReference; lastKnownFileType = folder; name = shaders_compiler; path = ../../tools/shaders_compiler; sourceTree = "<group>"; }; @@ -146,6 +162,13 @@ 4566610620E25F560085E8C1 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 4566610820E25F790085E8C1 /* test_main_loop.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = test_main_loop.hpp; path = ../../qt_tstfrm/test_main_loop.hpp; sourceTree = "<group>"; }; 4566610920E25F790085E8C1 /* test_main_loop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test_main_loop.cpp; path = ../../qt_tstfrm/test_main_loop.cpp; sourceTree = "<group>"; }; + 45789EDC21342BDE009955CC /* debug_rect.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = debug_rect.metal; sourceTree = "<group>"; }; + 45789EDE21343F70009955CC /* metal_program_pool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = metal_program_pool.mm; sourceTree = "<group>"; }; + 45789EDF21343F70009955CC /* metal_program_pool.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = metal_program_pool.hpp; sourceTree = "<group>"; }; + 45789EE321353CA3009955CC /* program_manager_metal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = program_manager_metal.mm; sourceTree = "<group>"; }; + 45789EE52135464D009955CC /* metal_program_params.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = metal_program_params.hpp; sourceTree = "<group>"; }; + 45789EE62135464D009955CC /* metal_program_params.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = metal_program_params.mm; sourceTree = "<group>"; }; + 4598437C21394BE000F8CAB2 /* shaders_metal.metallib */ = {isa = PBXFileReference; explicitFileType = "archive.metal-library"; includeInIndex = 0; path = shaders_metal.metallib; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -194,6 +217,7 @@ children = ( 4566606E20E254060085E8C1 /* libshaders.a */, 456660DA20E25A380085E8C1 /* shaders_tests.app */, + 4598437C21394BE000F8CAB2 /* shaders_metal.metallib */, ); name = Products; sourceTree = "<group>"; @@ -209,6 +233,12 @@ 4566608520E256230085E8C1 /* gl_program_pool.hpp */, 4566608220E256230085E8C1 /* gl_shaders.cpp */, 4566608820E256230085E8C1 /* gl_shaders.hpp */, + 45789EDB21342AC4009955CC /* Metal */, + 45789EE52135464D009955CC /* metal_program_params.hpp */, + 45789EE62135464D009955CC /* metal_program_params.mm */, + 45789EDF21343F70009955CC /* metal_program_pool.hpp */, + 45789EDE21343F70009955CC /* metal_program_pool.mm */, + 45789EE321353CA3009955CC /* program_manager_metal.mm */, 4561ADF320E378CB0096BC12 /* program_manager.cpp */, 4561ADF420E378CB0096BC12 /* program_manager.hpp */, 4566608020E256230085E8C1 /* program_params.cpp */, @@ -335,6 +365,15 @@ name = Resources; sourceTree = "<group>"; }; + 45789EDB21342AC4009955CC /* Metal */ = { + isa = PBXGroup; + children = ( + 45789EDC21342BDE009955CC /* debug_rect.metal */, + 4560F582213D44CE00CC736C /* screen_quad.metal */, + ); + path = Metal; + sourceTree = "<group>"; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -350,6 +389,7 @@ buildRules = ( ); dependencies = ( + 4560F58D213D57F900CC736C /* PBXTargetDependency */, ); name = shaders; productName = shaders; @@ -373,6 +413,21 @@ productReference = 456660DA20E25A380085E8C1 /* shaders_tests.app */; productType = "com.apple.product-type.application"; }; + 4598437B21394BE000F8CAB2 /* shaders_metal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4598438321394BE000F8CAB2 /* Build configuration list for PBXNativeTarget "shaders_metal" */; + buildPhases = ( + 4598437A21394BE000F8CAB2 /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = shaders_metal; + productName = shaders_metal; + productReference = 4598437C21394BE000F8CAB2 /* shaders_metal.metallib */; + productType = "com.apple.product-type.metal-library"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -388,6 +443,9 @@ 456660D920E25A380085E8C1 = { CreatedOnToolsVersion = 9.4; }; + 4598437B21394BE000F8CAB2 = { + CreatedOnToolsVersion = 9.4.1; + }; }; }; buildConfigurationList = 4566606920E254060085E8C1 /* Build configuration list for PBXProject "shaders" */; @@ -405,6 +463,7 @@ targets = ( 4566606D20E254060085E8C1 /* shaders */, 456660D920E25A380085E8C1 /* shaders_tests */, + 4598437B21394BE000F8CAB2 /* shaders_metal */, ); }; /* End PBXProject section */ @@ -441,8 +500,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 45789EE72135464D009955CC /* metal_program_params.mm in Sources */, 4566608A20E256240085E8C1 /* program_params.cpp in Sources */, + 45789EE021343F70009955CC /* metal_program_pool.mm in Sources */, 4566608B20E256240085E8C1 /* gl_shaders.cpp in Sources */, + 45789EE421353CA3009955CC /* program_manager_metal.mm in Sources */, 4561ADF520E378CB0096BC12 /* program_manager.cpp in Sources */, 4566608C20E256240085E8C1 /* gl_program_params.cpp in Sources */, 4566608D20E256240085E8C1 /* gl_program_pool.cpp in Sources */, @@ -461,8 +523,25 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4598437A21394BE000F8CAB2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4560F58A213D57D600CC736C /* debug_rect.metal in Sources */, + 4560F58B213D57D600CC736C /* screen_quad.metal in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 4560F58D213D57F900CC736C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4598437B21394BE000F8CAB2 /* shaders_metal */; + targetProxy = 4560F58C213D57F900CC736C /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ 4566607520E254060085E8C1 /* Debug */ = { isa = XCBuildConfiguration; @@ -566,6 +645,24 @@ }; name = "Production Full"; }; + 4598438021394BE000F8CAB2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 4598438121394BE000F8CAB2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + 4598438221394BE000F8CAB2 /* Production Full */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = "Production Full"; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -599,6 +696,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4598438321394BE000F8CAB2 /* Build configuration list for PBXNativeTarget "shaders_metal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4598438021394BE000F8CAB2 /* Debug */, + 4598438121394BE000F8CAB2 /* Release */, + 4598438221394BE000F8CAB2 /* Production Full */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 4566606620E254060085E8C1 /* Project object */; |