diff --git a/base/math.hpp b/base/math.hpp index 0fd40a2c25..f1eed73e8b 100644 --- a/base/math.hpp +++ b/base/math.hpp @@ -127,4 +127,16 @@ template inline T PrevModN(T x, T n) return x == 0 ? n - 1 : x - 1; } +inline uint32_t NextPowOf2(uint32_t v) +{ + v = v - 1; + v |= (v >> 1); + v |= (v >> 2); + v |= (v >> 4); + v |= (v >> 8); + v |= (v >> 16); + + return v + 1; +} + } diff --git a/graphics/opengl/geometry_renderer.cpp b/graphics/opengl/geometry_renderer.cpp index 89d202670b..8a40318220 100644 --- a/graphics/opengl/geometry_renderer.cpp +++ b/graphics/opengl/geometry_renderer.cpp @@ -11,25 +11,11 @@ #include "../../base/logging.hpp" #include "../../base/shared_buffer_manager.hpp" +#include "../../base/math.hpp" #include "../../std/bind.hpp" namespace graphics { - namespace - { - unsigned NextPowerOf2(unsigned n) - { - n = n - 1; - n |= (n >> 1); - n |= (n >> 2); - n |= (n >> 4); - n |= (n >> 8); - n |= (n >> 16); - - return n + 1; - } - } - namespace gl { typedef Texture TDynamicTexture; @@ -117,9 +103,9 @@ namespace graphics currentRect.setMinX(currentRect.minX() - maxRect.minX()); currentRect.setMaxX(currentRect.maxX() - maxRect.minX()); - size_t renderBufferSize = NextPowerOf2(currentRect.SizeX() * - currentRect.SizeY() * - sizeof(TDynamicTexture::pixel_t)); + size_t renderBufferSize = my::NextPowOf2(currentRect.SizeX() * + currentRect.SizeY() * + sizeof(TDynamicTexture::pixel_t)); SharedBufferManager::shared_buffer_ptr_t buffer = SharedBufferManager::instance().reserveSharedBuffer(renderBufferSize); TDynamicTexture::view_t bufferView = gil::interleaved_view(currentRect.SizeX(), currentRect.SizeY(), diff --git a/graphics/resource_manager.cpp b/graphics/resource_manager.cpp index d6175b6be3..eda4e847be 100644 --- a/graphics/resource_manager.cpp +++ b/graphics/resource_manager.cpp @@ -287,6 +287,11 @@ namespace LOG(LINFO, ("using ReadPixels instead of glFinish to synchronize")); } + bool ResourceManager::Params::canUseNPOTextures() + { + return graphics::gl::HasExtension("GL_OES_texture_npot"); + } + void ResourceManager::loadSkinInfoAndTexture(string const & skinFileName, EDensity density) { try diff --git a/graphics/resource_manager.hpp b/graphics/resource_manager.hpp index 75eda9b086..9c31489c7b 100644 --- a/graphics/resource_manager.hpp +++ b/graphics/resource_manager.hpp @@ -210,6 +210,7 @@ namespace graphics int memoryUsage() const; int fixedMemoryUsage() const; void initScaleWeights(); + bool canUseNPOTextures(); }; private: diff --git a/map/render_policy.cpp b/map/render_policy.cpp index 7bed3f8ab1..ea64fd3fab 100644 --- a/map/render_policy.cpp +++ b/map/render_policy.cpp @@ -281,6 +281,30 @@ Drawer * RenderPolicy::CreateDrawer(bool isDefaultFB, return new Drawer(dp); } +size_t RenderPolicy::GetLargeTextureSize(bool useNpot) +{ + UNUSED_VALUE(useNpot); + return 512; +} + +size_t RenderPolicy::GetMediumTextureSize(bool useNpot) +{ + uint32_t size = 256 * VisualScale(); + if (useNpot) + return size; + + return my::NextPowOf2(size); +} + +size_t RenderPolicy::GetSmallTextureSize(bool useNpot) +{ + uint32_t size = 128 * VisualScale(); + if (useNpot) + return size; + + return my::NextPowOf2(size); +} + graphics::ResourceManager::StoragePoolParams RenderPolicy::GetStorageParam(size_t vertexCount, size_t indexCount, size_t batchSize, @@ -298,6 +322,7 @@ graphics::ResourceManager::TexturePoolParams RenderPolicy::GetTextureParam(size_ graphics::DataFormat format, graphics::ETextureType type) { + LOG(LDEBUG, ("Texture creating size = ", size)); return graphics::ResourceManager::TexturePoolParams(size, size, initCount, format, type, false); } diff --git a/map/render_policy.hpp b/map/render_policy.hpp index 1f7d29814d..1872cb2cd6 100644 --- a/map/render_policy.hpp +++ b/map/render_policy.hpp @@ -175,6 +175,11 @@ protected: shared_ptr context, graphics::EStorageType storageType, graphics::ETextureType textureType); + + size_t GetLargeTextureSize(bool useNpot); + size_t GetMediumTextureSize(bool useNpot); + size_t GetSmallTextureSize(bool useNpot); + graphics::ResourceManager::StoragePoolParams GetStorageParam(size_t vertexCount, size_t indexCount, size_t batchSize, diff --git a/map/simple_render_policy.cpp b/map/simple_render_policy.cpp index dc47633033..df2240ed8b 100644 --- a/map/simple_render_policy.cpp +++ b/map/simple_render_policy.cpp @@ -20,11 +20,11 @@ SimpleRenderPolicy::SimpleRenderPolicy(Params const & p) graphics::ResourceManager::Params rmp = p.m_rmParams; rmp.checkDeviceCaps(); - double k = VisualScale(); + bool useNpot = rmp.canUseNPOTextures(); - rmp.m_textureParams[ELargeTexture] = GetTextureParam(512, 10, rmp.m_texFormat, ELargeTexture); - rmp.m_textureParams[EMediumTexture] = GetTextureParam(256 * k, 5, rmp.m_texFormat, EMediumTexture); - rmp.m_textureParams[ESmallTexture] = GetTextureParam(128 * k, 4, rmp.m_texFormat, ESmallTexture); + rmp.m_textureParams[ELargeTexture] = GetTextureParam(GetLargeTextureSize(useNpot), 10, rmp.m_texFormat, ELargeTexture); + rmp.m_textureParams[EMediumTexture] = GetTextureParam(GetMediumTextureSize(useNpot), 5, rmp.m_texFormat, EMediumTexture); + rmp.m_textureParams[ESmallTexture] = GetTextureParam(GetSmallTextureSize(useNpot), 4, rmp.m_texFormat, ESmallTexture); rmp.m_storageParams[ELargeStorage] = GetStorageParam(50000, 100000, 15, ELargeStorage); rmp.m_storageParams[EMediumStorage] = GetStorageParam(5000, 10000, 100, EMediumStorage); diff --git a/map/tiling_render_policy_mt.cpp b/map/tiling_render_policy_mt.cpp index 5e54275fd8..f6a0b89a3a 100644 --- a/map/tiling_render_policy_mt.cpp +++ b/map/tiling_render_policy_mt.cpp @@ -18,12 +18,12 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(Params const & p) graphics::ResourceManager::Params rmp = p.m_rmParams; rmp.checkDeviceCaps(); - int k = int(ceil(VisualScale())); + bool useNpot = rmp.canUseNPOTextures(); - rmp.m_textureParams[ELargeTexture] = GetTextureParam(512, 1, rmp.m_texFormat, ELargeTexture); - rmp.m_textureParams[EMediumTexture] = GetTextureParam(256 * k, 1, rmp.m_texFormat, EMediumTexture); + rmp.m_textureParams[ELargeTexture] = GetTextureParam(GetLargeTextureSize(useNpot), 1, rmp.m_texFormat, ELargeTexture); + rmp.m_textureParams[EMediumTexture] = GetTextureParam(GetMediumTextureSize(useNpot), 1, rmp.m_texFormat, EMediumTexture); rmp.m_textureParams[ERenderTargetTexture] = GetTextureParam(TileSize(), 1, rmp.m_texRtFormat, ERenderTargetTexture); - rmp.m_textureParams[ESmallTexture] = GetTextureParam(128 * k, 4, rmp.m_texFormat, ESmallTexture); + rmp.m_textureParams[ESmallTexture] = GetTextureParam(GetSmallTextureSize(useNpot), 4, rmp.m_texFormat, ESmallTexture); rmp.m_storageParams[ELargeStorage] = GetStorageParam(50000, 100000, 5, ELargeStorage); rmp.m_storageParams[EMediumStorage] = GetStorageParam(6000, 9000, 1, EMediumStorage); diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp index a88a5f7542..293d8f4703 100644 --- a/map/tiling_render_policy_st.cpp +++ b/map/tiling_render_policy_st.cpp @@ -21,13 +21,12 @@ TilingRenderPolicyST::TilingRenderPolicyST(Params const & p) ResourceManager::Params rmp = p.m_rmParams; rmp.checkDeviceCaps(); + bool useNpot = rmp.canUseNPOTextures(); - int k = int(ceil(VisualScale())); - - rmp.m_textureParams[ELargeTexture] = GetTextureParam(512, 1, rmp.m_texFormat, ELargeTexture); - rmp.m_textureParams[EMediumTexture] = GetTextureParam(256 * k, 10, rmp.m_texFormat, EMediumTexture); + rmp.m_textureParams[ELargeTexture] = GetTextureParam(GetLargeTextureSize(useNpot), 1, rmp.m_texFormat, ELargeTexture); + rmp.m_textureParams[EMediumTexture] = GetTextureParam(GetMediumTextureSize(useNpot), 10, rmp.m_texFormat, EMediumTexture); rmp.m_textureParams[ERenderTargetTexture] = GetTextureParam(TileSize(), 1, rmp.m_texRtFormat, ERenderTargetTexture); - rmp.m_textureParams[ESmallTexture] = GetTextureParam(128 * k, 2, rmp.m_texFormat, ESmallTexture); + rmp.m_textureParams[ESmallTexture] = GetTextureParam(GetSmallTextureSize(useNpot), 2, rmp.m_texFormat, ESmallTexture); rmp.m_storageParams[ELargeStorage] = GetStorageParam(6000, 9000, 10, ELargeStorage); rmp.m_storageParams[EMediumStorage] = GetStorageParam(6000, 9000, 1, EMediumStorage);