[Drape] Remove GL ES2 Support #10256

Open
renderexpert wants to merge 8 commits from renderexpert/remove_gles2 into master
176 changed files with 4018 additions and 1850 deletions

View file

@ -61,6 +61,10 @@ jobs:
libgl1-mesa-dev \
libglvnd-dev \
libharfbuzz-dev \
libxrandr-dev \
libxinerama-dev \
libxcursor-dev \
libxi-dev \
qt6-base-dev \
libqt6svg6-dev \
qt6-positioning-dev \
@ -128,6 +132,10 @@ jobs:
libgl1-mesa-dev \
libglvnd-dev \
libharfbuzz-dev \
libxrandr-dev \
libxinerama-dev \
libxcursor-dev \
libxi-dev \
qt6-base-dev \
libqt6svg6-dev \
qt6-positioning-dev \

9
.gitmodules vendored
View file

@ -59,3 +59,12 @@
[submodule "3party/utfcpp"]
path = 3party/utfcpp
url = https://github.com/nemtrif/utfcpp.git
[submodule "3party/glfw"]
path = 3party/glfw
url = https://github.com/glfw/glfw.git
[submodule "3party/CMake-MetalShaderSupport"]
path = 3party/CMake-MetalShaderSupport
url = https://github.com/dpogue/CMake-MetalShaderSupport.git
[submodule "3party/imgui/imgui"]
path = 3party/imgui/imgui
url = https://github.com/ocornut/imgui

@ -0,0 +1 @@
Subproject commit 989857d2e5e54869c35ad06fb21a67d12a2dbc67

View file

@ -66,4 +66,19 @@ add_subdirectory(vulkan_wrapper)
if (PLATFORM_DESKTOP)
add_subdirectory(libtess2)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "")
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "")
set(GLFW_BUILD_TESTS OFF CACHE BOOL "")
set(GLFW_INSTALL OFF CACHE BOOL "")
set(GLFW_VULKAN_STATIC OFF CACHE BOOL "")
set(GLFW_BUILD_WAYLAND OFF CACHE BOOL "")
# Disable ARC for glfw and re-enable after it because it's globally set in the root CMakeLists.txt
set(CMAKE_OBJC_FLAGS "")
add_subdirectory(glfw)
set_target_properties(glfw PROPERTIES UNITY_BUILD OFF)
set_target_properties(glfw PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC NO)
set(CMAKE_OBJC_FLAGS -fobjc-arc)
add_subdirectory(imgui)
endif()

1
3party/glfw Submodule

@ -0,0 +1 @@
Subproject commit 21fea01161e0d6b70c0c5c1f52dc8e7a7df14a50

View file

@ -0,0 +1,16 @@
project(imgui)
set(SRC
imgui/imgui_draw.cpp
imgui/imgui_tables.cpp
imgui/imgui_widgets.cpp
imgui/imgui.cpp
imgui/backends/imgui_impl_glfw.cpp
)
add_library(${PROJECT_NAME} ${SRC})
target_include_directories(${PROJECT_NAME}
PRIVATE ${OMIM_ROOT}/3party/glfw/include
PUBLIC ${OMIM_ROOT}/3party/imgui/imgui
PUBLIC .
)

1
3party/imgui/imgui Submodule

@ -0,0 +1 @@
Subproject commit 6982ce43f5b143c5dce5fab0ce07dd4867b705ae

View file

@ -90,6 +90,19 @@ else()
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif()
if(${PLATFORM_MAC})
set(XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
# Metal language support
list(APPEND CMAKE_MODULE_PATH ${OMIM_ROOT}/3party/CMake-MetalShaderSupport/cmake)
include(CheckLanguage)
include(MetalShaderSupport)
check_language(Metal)
if(CMAKE_Metal_COMPILER)
enable_language(Metal)
endif()
endif()
# Sanitizer
if (PLATFORM_DESKTOP)
# https://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
@ -394,6 +407,7 @@ if (PLATFORM_DESKTOP)
add_subdirectory(qt)
omim_add_tool_subdirectory(skin_generator)
endif()
add_subdirectory(dev_sandbox)
endif()
omim_add_test_subdirectory(qt_tstfrm)

View file

@ -224,8 +224,7 @@ bool Framework::CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi
LOG(LWARNING, ("Invalid GL context."));
return false;
}
p.m_apiVersion = oglFactory->IsSupportedOpenGLES3() ? dp::ApiVersion::OpenGLES3 :
dp::ApiVersion::OpenGLES2;
p.m_apiVersion = dp::ApiVersion::OpenGLES3;
p.m_surfaceWidth = oglFactory->GetWidth();
p.m_surfaceHeight = oglFactory->GetHeight();

View file

@ -8,20 +8,16 @@
namespace android
{
static EGLint * getContextAttributesList(bool supportedES3)
static EGLint * getContextAttributesList()
{
static EGLint contextAttrList[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
static EGLint contextAttrListES3[] = {
EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE
};
return supportedES3 ? contextAttrListES3 : contextAttrList;
return contextAttrList;
}
AndroidOGLContext::AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLSurface surface,
AndroidOGLContext::AndroidOGLContext(EGLDisplay display, EGLSurface surface,
EGLConfig config, AndroidOGLContext * contextToShareWith)
: m_nativeContext(EGL_NO_CONTEXT)
, m_surface(surface)
@ -32,7 +28,7 @@ AndroidOGLContext::AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLS
ASSERT(m_display != EGL_NO_DISPLAY, ());
EGLContext sharedContext = (contextToShareWith == NULL) ? EGL_NO_CONTEXT : contextToShareWith->m_nativeContext;
m_nativeContext = eglCreateContext(m_display, config, sharedContext, getContextAttributesList(supportedES3));
m_nativeContext = eglCreateContext(m_display, config, sharedContext, getContextAttributesList());
CHECK(m_nativeContext != EGL_NO_CONTEXT, ());
}

View file

@ -10,7 +10,7 @@ namespace android
class AndroidOGLContext : public dp::OGLContext
{
public:
AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLSurface surface,
AndroidOGLContext(EGLDisplay display, EGLSurface surface,
EGLConfig config, AndroidOGLContext * contextToShareWith);
~AndroidOGLContext();

View file

@ -16,26 +16,13 @@
#define EGL_OPENGL_ES3_BIT 0x00000040
int constexpr kMinSdkVersionForES3 = 21;
namespace android
{
namespace
{
static EGLint * getConfigAttributesListRGB8(bool supportedES3)
static EGLint * getConfigAttributesListRGB8()
{
static EGLint attr_list[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_DEPTH_SIZE, 16,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
EGL_NONE
};
static EGLint attr_list_es3[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
@ -46,33 +33,16 @@ static EGLint * getConfigAttributesListRGB8(bool supportedES3)
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
EGL_NONE
};
return supportedES3 ? attr_list_es3 : attr_list;
return attr_list;
}
int const kMaxConfigCount = 40;
static EGLint * getConfigAttributesListR5G6B5()
{
// We do not support OpenGL ES3 for R5G6B5, because some Android devices
// are not able to create OpenGL context in such mode.
static EGLint attr_list[] = {
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_STENCIL_SIZE, 0,
EGL_DEPTH_SIZE, 16,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
EGL_NONE
};
return attr_list;
}
bool IsSupportedRGB8(EGLDisplay display, bool es3)
bool IsSupportedRGB8(EGLDisplay display)
{
EGLConfig configs[kMaxConfigCount];
int count = 0;
return eglChooseConfig(display, getConfigAttributesListRGB8(es3), configs,
return eglChooseConfig(display, getConfigAttributesListRGB8(), configs,
kMaxConfigCount, &count) == EGL_TRUE && count != 0;
}
@ -90,7 +60,6 @@ AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurfac
, m_surfaceWidth(0)
, m_surfaceHeight(0)
, m_windowSurfaceValid(false)
, m_supportedES3(false)
{
m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (m_display == EGL_NO_DISPLAY)
@ -106,10 +75,7 @@ AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurfac
return;
}
// Check ES3 availability.
bool const isES3Supported = IsSupportedRGB8(m_display, true /* es3 */) &&
android_get_device_api_level() >= kMinSdkVersionForES3;
m_supportedES3 = isES3Supported && gl3stubInit();
CHECK(gl3stubInit(), ("Could not initialize OpenGL ES3"));
SetSurface(env, jsurface);
@ -266,7 +232,7 @@ dp::GraphicsContext * AndroidOGLContextFactory::GetDrawContext()
ASSERT(m_windowSurface != EGL_NO_SURFACE, ());
if (m_drawContext == nullptr)
{
m_drawContext = new AndroidOGLContext(m_supportedES3, m_display, m_windowSurface,
m_drawContext = new AndroidOGLContext(m_display, m_windowSurface,
m_config, m_uploadContext);
}
return m_drawContext;
@ -278,7 +244,7 @@ dp::GraphicsContext * AndroidOGLContextFactory::GetResourcesUploadContext()
ASSERT(m_pixelbufferSurface != EGL_NO_SURFACE, ());
if (m_uploadContext == nullptr)
{
m_uploadContext = new AndroidOGLContext(m_supportedES3, m_display, m_pixelbufferSurface,
m_uploadContext = new AndroidOGLContext(m_display, m_pixelbufferSurface,
m_config, m_drawContext);
}
return m_uploadContext;
@ -322,17 +288,15 @@ bool AndroidOGLContextFactory::CreateWindowSurface()
{
EGLConfig configs[kMaxConfigCount];
int count = 0;
if (eglChooseConfig(m_display, getConfigAttributesListRGB8(m_supportedES3), configs,
kMaxConfigCount, &count) != EGL_TRUE)
if (eglChooseConfig(m_display, getConfigAttributesListRGB8(), configs,
kMaxConfigCount, &count) == EGL_TRUE)
{
ASSERT(!m_supportedES3, ());
VERIFY(eglChooseConfig(m_display, getConfigAttributesListR5G6B5(), configs,
kMaxConfigCount, &count) == EGL_TRUE, ());
LOG(LDEBUG, ("Backbuffer format: R5G6B5"));
CHECK(IsSupportedRGB8(m_display), ("RGB8 is not suported on this device"));
LOG(LDEBUG, ("Backbuffer format: RGB8"));
}
else
{
LOG(LDEBUG, ("Backbuffer format: RGB8"));
CHECK(false, ("OpenGL ES3 is not supported"));
}
ASSERT(count > 0, ("Didn't find any configs."));

View file

@ -33,8 +33,6 @@ public:
int GetHeight() const;
void UpdateSurfaceSize(int w, int h);
bool IsSupportedOpenGLES3() const { return m_supportedES3; }
private:
bool QuerySurfaceSize();
@ -56,7 +54,6 @@ private:
int m_surfaceHeight;
bool m_windowSurfaceValid;
bool m_supportedES3;
bool m_isInitialized = false;
size_t m_initializationCounter = 0;

View file

@ -155,6 +155,12 @@
<li><a href="https://chromium.googlesource.com/chromium/src/courgette/">Chromium's Courgette</a>;
<a href="#bsd3-license" class="license">BSD License</a></li>
<li><a href="https://github.com/dpogue/CMake-MetalShaderSupport">CMake Metal support files</a><br>
&copy; 2024 Darryl Pogue and Contributors;<a href="#cmake-support-license" class="license">License</a></li>
<li><a href="https://github.com/ocornut/imgui">Dear ImGui</a><br>
&copy; 2014-2025 Omar Cornut; <a href="#mit-license" class="license">MIT License</a></li>
<li><a href="https://libexpat.github.io">Expat</a><br>&copy; 1998&ndash;2000 Thai Open Source Software Center Ltd and Clark Cooper,
&copy; 2001&ndash;2019 Expat maintainers; <a href="#mit-license" class="license">MIT License</a></li>
@ -164,6 +170,9 @@
<li><a href="http://www.freetype.org">FreeType</a><br>
&copy; 2013 The FreeType Project; <a href="#freetype-license" class="license">FTL</a></li>
<li><a href="https://www.glfw.org/">GLFW</a><br>
&copy; 2002-2006 Marcus Geelnard;2006-2019 Camilla Löwy; <a href="#zlib-license" class="license">Zlib License</a></li>
<li><a href="http://www.g-truc.net/project-0016.html">GLM</a><br>
&copy; 2005&ndash;2014 G-Truc Creation; <a href="#mit-license" class="license">MIT License</a></li>
@ -1058,6 +1067,54 @@ of the copyright holder.</p>
</div>
<div class="section">
<h2 id="cmake-support-license">CMake Metal support files</h2>
<p>Copyright 2024 Darryl Pogue and Contributors</p>
<p>All rights reserved.</p>
<p>Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:</p>
<p>* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</p>
<p>* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.</p>
<p>* Neither the name of Kitware, Inc. nor the names of Contributors may be used to endorse or promote products derived from this software without specific prior written permission.</p>
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
<p>------------------------------------------------------------------------------</p>
<p>See version control history for details of individual contributions.</p>
<p>The above copyright and license notice applies to distributions of
CMake in source and binary form. Third-party software packages supplied
with CMake under compatible licenses provide their own copyright notices
documented in corresponding subdirectories or source files.</p>
<p>------------------------------------------------------------------------------</p>
<p>CMake was initially developed by Kitware with the following sponsorship:</p>
<p>* National Library of Medicine at the National Institutes of Health as part of the Insight Segmentation and Registration Toolkit (ITK).</p>
<p>* US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel Visualization Initiative.</p>
<p>* National Alliance for Medical Image Computing (NAMIC) is funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149.</p>
<p>* Kitware, Inc.</p>
</div>
<div class="section">
<h2 id="freetype-license">The FreeType Project License</h2>

File diff suppressed because one or more lines are too long

Binary file not shown.

144
dev_sandbox/CMakeLists.txt Normal file
View file

@ -0,0 +1,144 @@
project(dev_sandbox)
set(SRC
main.cpp
imgui_renderer.cpp
imgui_renderer.hpp
)
if (${PLATFORM_MAC})
append(SRC
main.mm
../iphone/Maps/Classes/MetalContextFactory.h
../iphone/Maps/Classes/MetalContextFactory.mm
)
file(GLOB_RECURSE SHADER_SOURCES_FILES ${OMIM_ROOT}/shaders/Metal/*.metal)
add_metal_shader_library(shaders_metal
${SHADER_SOURCES_FILES}
)
endif()
if (${PLATFORM_LINUX})
append(SRC
main_linux.cpp
)
endif()
omim_add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${SRC})
target_link_libraries(${PROJECT_NAME}
generator # For borders::LoadBorders
qt_common
map
gflags::gflags
glfw
imgui
)
# Installing Vulkan SDK is optional, however without it Vulkan dynamic libraries
# should be discovered via system paths and validation layers may not be available
find_package(Vulkan QUIET)
if (Vulkan_FOUND)
message(STATUS "Vulkan found")
target_link_libraries(${PROJECT_NAME} Vulkan::Vulkan)
endif()
if(PLATFORM_MAC)
target_embed_metal_shader_libraries(${PROJECT_NAME} shaders_metal)
endif()
target_compile_definitions(${PROJECT_NAME} PUBLIC GL_SILENCE_DEPRECATION)
if (PLATFORM_MAC)
set_target_properties(${PROJECT_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
endif()
if (PLATFORM_LINUX)
target_compile_definitions(${PROJECT_NAME} PRIVATE VK_USE_PLATFORM_XLIB_KHR)
endif()
target_include_directories(${PROJECT_NAME} PUBLIC ${OMIM_ROOT}/3party/glfw/include)
target_include_directories(${PROJECT_NAME} PUBLIC ${OMIM_ROOT}/3party/imgui)
set(BUNDLE_NAME "OMapsDevSandbox")
set(BUNDLE_DISPLAY_NAME "Organic Maps: Developer Sandbox")
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${BUNDLE_NAME})
set(BUNDLE_EXECUTABLE ${BUNDLE_NAME})
set(BUNDLE_FOLDER ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${BUNDLE_NAME}.app)
set(RESOURCES_FOLDER ${BUNDLE_FOLDER}/Contents/Resources)
set(DATA_DIR ${OMIM_ROOT}/data)
execute_process(
COMMAND mkdir -p ${RESOURCES_FOLDER}/shaders_compiler
)
function(copy_resources)
foreach(file ${ARGN})
execute_process(
COMMAND cp -r ${DATA_DIR}/${file} ${RESOURCES_FOLDER}
)
endforeach()
endfunction()
copy_resources(
countries-strings
resources-default
resources-mdpi_light
resources-hdpi_light
resources-xhdpi_light
resources-xxhdpi_light
resources-xxxhdpi_light
resources-6plus_light
categories.txt
categories_cuisines.txt
classificator.txt
colors.txt
countries.txt
drules_proto_default_light.bin
drules_proto_default_dark.bin
drules_proto_vehicle_light.bin
drules_proto_vehicle_dark.bin
editor.config
fonts_blacklist.txt
fonts_whitelist.txt
packed_polygons.bin
patterns.txt
transit_colors.txt
types.txt
unicode_blocks.txt
World.mwm
WorldCoasts.mwm
00_NotoNaskhArabic-Regular.ttf
00_NotoSansBengali-Regular.ttf
00_NotoSansHebrew-Regular.ttf
00_NotoSansMalayalam-Regular.ttf
00_NotoSansThai-Regular.ttf
00_NotoSerifDevanagari-Regular.ttf
01_dejavusans.ttf
02_droidsans-fallback.ttf
03_jomolhari-id-a3d.ttf
04_padauk.ttf
05_khmeros.ttf
06_code2000.ttf
07_roboto_medium.ttf
)
if (NOT PLATFORM_LINUX)
# On Linux, ICU data is loaded from the shared library.
copy_resources(icudt75l.dat)
endif()
if (PLATFORM_MAC)
execute_process(
COMMAND cp -r ${OMIM_ROOT}/tools/shaders_compiler/macos ${RESOURCES_FOLDER}/shaders_compiler
)
elseif (PLATFORM_LINUX)
execute_process(
COMMAND cp -r ${OMIM_ROOT}/tools/shaders_compiler/linux ${RESOURCES_FOLDER}/shaders_compiler
)
endif()

View file

@ -0,0 +1,257 @@
#include "imgui_renderer.hpp"
#include "base/logging.hpp"
#include "base/macros.hpp"
#include <drape_frontend/render_state_extension.hpp>
#include <shaders/program_manager.hpp>
#include <imgui/imgui.h>
#include <cstring>
#include <limits>
ImguiRenderer::ImguiRenderer()
: m_state(df::CreateRenderState(gpu::Program::ImGui, df::DepthLayer::GuiLayer))
{
m_state.SetDepthTestEnabled(false);
m_state.SetBlending(dp::Blending(true));
}
void ImguiRenderer::Render(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManager> textureManager,
ref_ptr<gpu::ProgramManager> programManager)
{
std::lock_guard<std::mutex> lock(m_bufferMutex);
size_t renderDataIndex = (m_updateIndex + 1) % m_uiDataBuffer.size();
UiDataBuffer & dataBuffer = m_uiDataBuffer[renderDataIndex];
auto gpuProgram = programManager->GetProgram(m_state.GetProgram<gpu::Program>());
bool needUpdate = true;
if (!m_mesh || dataBuffer.m_vertices.size() > m_vertexCount || dataBuffer.m_indices.size() > m_indexCount)
{
while (dataBuffer.m_vertices.size() > m_vertexCount)
m_vertexCount *= 2;
while (dataBuffer.m_indices.size() > m_indexCount)
m_indexCount *= 2;
m_indexCount = std::min(m_indexCount, static_cast<uint32_t>(std::numeric_limits<uint16_t>::max()));
dataBuffer.m_vertices.resize(m_vertexCount);
dataBuffer.m_indices.resize(m_indexCount);
m_mesh = make_unique_dp<dp::MeshObject>(context, dp::MeshObject::DrawPrimitive::Triangles, "imGui");
m_mesh->SetBuffer(0, std::move(dataBuffer.m_vertices));
m_mesh->SetAttribute("a_position", 0, 0 /* offset */, 2);
m_mesh->SetAttribute("a_texCoords", 0, 2 * sizeof(float) /* offset */, 2);
m_mesh->SetAttribute("a_color", 0, 4 * sizeof(float) /* offset */, 4);
m_mesh->SetIndexBuffer(std::move(dataBuffer.m_indices));
m_mesh->Build(context, gpuProgram);
dataBuffer.m_vertices.clear();
dataBuffer.m_indices.clear();
needUpdate = false;
}
if (!m_texture)
{
std::lock_guard<std::mutex> lock(m_textureMutex);
if (!m_textureData.empty())
{
m_texture = make_unique_dp<dp::StaticTexture>();
m_texture->Create(context,
dp::Texture::Params{
.m_width = m_textureWidth,
.m_height = m_textureHeight,
.m_format = dp::TextureFormat::RGBA8,
.m_allocator = textureManager->GetTextureAllocator(),
},
m_textureData.data());
m_textureData.clear();
m_state.SetColorTexture(make_ref(m_texture));
}
else
{
// Can't render without texture.
return;
}
}
if (dataBuffer.m_drawCalls.empty())
return;
if (needUpdate && !dataBuffer.m_vertices.empty() && !dataBuffer.m_indices.empty())
{
m_mesh->UpdateBuffer(context, 0, dataBuffer.m_vertices);
m_mesh->UpdateIndexBuffer(context, dataBuffer.m_indices);
dataBuffer.m_vertices.clear();
dataBuffer.m_indices.clear();
}
gpu::ImGuiProgramParams const params{.m_projection = m_projection};
context->PushDebugLabel("ImGui Rendering");
m_mesh->Render(context, gpuProgram, m_state, programManager->GetParamsSetter(), params,
[&, this]()
{
context->SetCullingEnabled(false);
for (auto const & drawCall : dataBuffer.m_drawCalls)
{
uint32_t y = drawCall.clipRect.y;
if (context->GetApiVersion() == dp::ApiVersion::OpenGLES3)
y = dataBuffer.m_height - y - drawCall.clipRect.w;
context->SetScissor(drawCall.clipRect.x, y, drawCall.clipRect.z, drawCall.clipRect.w);
m_mesh->DrawPrimitivesSubsetIndexed(context, drawCall.indexCount, drawCall.startIndex);
}
context->SetCullingEnabled(true);
context->SetScissor(0, 0, dataBuffer.m_width, dataBuffer.m_height);
});
context->PopDebugLabel();
}
void ImguiRenderer::Update(std::function<void()> const & uiCallback)
{
CHECK(uiCallback, ());
ImGuiIO & io = ImGui::GetIO();
if (!io.Fonts->IsBuilt())
io.Fonts->Build();
if (!m_texture)
UpdateTexture();
ImGui::NewFrame();
uiCallback();
ImGui::Render();
UpdateBuffers();
}
void ImguiRenderer::Reset()
{
{
std::lock_guard<std::mutex> lock(m_textureMutex);
m_texture.reset();
}
{
std::lock_guard<std::mutex> lock(m_bufferMutex);
m_mesh.reset();
}
}
void ImguiRenderer::UpdateTexture()
{
std::lock_guard<std::mutex> lock(m_textureMutex);
unsigned char * pixels;
int width, height;
ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
auto const sizeInBytes = width * height * sizeof(uint32_t);
m_textureData.resize(sizeInBytes);
memcpy(m_textureData.data(), pixels, sizeInBytes);
m_textureWidth = static_cast<uint32_t>(width);
m_textureHeight = static_cast<uint32_t>(height);
}
void ImguiRenderer::UpdateBuffers()
{
UiDataBuffer & dataBuffer = m_uiDataBuffer[m_updateIndex];
dataBuffer.m_drawCalls.clear();
ImDrawData * dd = ImGui::GetDrawData();
auto const fbWidth = static_cast<int>(dd->DisplaySize.x * dd->FramebufferScale.x);
auto const fbHeight = static_cast<int>(dd->DisplaySize.y * dd->FramebufferScale.y);
if (fbWidth <= 0 || fbHeight <= 0 || dd->CmdListsCount == 0 || dd->TotalIdxCount == 0 || dd->TotalVtxCount == 0)
return;
dataBuffer.m_width = static_cast<uint32_t>(fbWidth);
dataBuffer.m_height = static_cast<uint32_t>(fbHeight);
CHECK(dd->TotalVtxCount <= std::numeric_limits<uint16_t>::max(),
("UI is so complex and now requires 32-bit indices. You need to improve dp::MeshObject or simplify UI"));
CHECK((ImGui::GetIO().BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) == 0, ());
dataBuffer.m_vertices.resize(dd->TotalVtxCount);
dataBuffer.m_indices.resize(dd->TotalIdxCount);
int totalDrawCallsCount = 0;
for (int i = 0; i < dd->CmdListsCount; ++i)
totalDrawCallsCount += dd->CmdLists[i]->CmdBuffer.Size;
dataBuffer.m_drawCalls.reserve(totalDrawCallsCount);
ImVec2 const clipOff = dd->DisplayPos;
ImVec2 const clipScale = dd->FramebufferScale;
uint32_t vertexOffset = 0;
uint32_t indexOffset = 0;
for (int i = 0; i < dd->CmdListsCount; ++i)
{
ImDrawList const * cmdList = dd->CmdLists[i];
for (int j = 0; j < cmdList->VtxBuffer.Size; ++j)
{
dp::Color color(cmdList->VtxBuffer.Data[j].col);
dataBuffer.m_vertices[j + vertexOffset] = {
.position = {cmdList->VtxBuffer.Data[j].pos.x, cmdList->VtxBuffer.Data[j].pos.y},
.texCoords = {cmdList->VtxBuffer.Data[j].uv.x, cmdList->VtxBuffer.Data[j].uv.y},
.color = {color.GetAlphaF(), color.GetBlueF(), color.GetGreenF(),
color.GetRedF()} // Byte order is reversed in imGui
};
}
static_assert(sizeof(uint16_t) == sizeof(ImDrawIdx));
memcpy(dataBuffer.m_indices.data() + indexOffset, cmdList->IdxBuffer.Data,
cmdList->IdxBuffer.Size * sizeof(ImDrawIdx));
for (int j = 0; j < cmdList->IdxBuffer.Size; ++j)
{
uint32_t indexValue = dataBuffer.m_indices[j + indexOffset];
indexValue += vertexOffset;
CHECK(indexValue <= std::numeric_limits<uint16_t>::max(), ());
dataBuffer.m_indices[j + indexOffset] = static_cast<uint16_t>(indexValue);
}
for (int cmdIndex = 0; cmdIndex < cmdList->CmdBuffer.Size; ++cmdIndex)
{
const ImDrawCmd cmd = cmdList->CmdBuffer[cmdIndex];
ImVec2 clipMin((cmd.ClipRect.x - clipOff.x) * clipScale.x, (cmd.ClipRect.y - clipOff.y) * clipScale.y);
ImVec2 clipMax((cmd.ClipRect.z - clipOff.x) * clipScale.x, (cmd.ClipRect.w - clipOff.y) * clipScale.y);
if (clipMin.x < 0.0f)
clipMin.x = 0.0f;
if (clipMin.y < 0.0f)
clipMin.y = 0.0f;
if (clipMax.x > fbWidth)
clipMax.x = static_cast<float>(fbWidth);
if (clipMax.y > fbHeight)
clipMax.y = static_cast<float>(fbHeight);
if (clipMax.x <= clipMin.x || clipMax.y <= clipMin.y)
continue;
dataBuffer.m_drawCalls.emplace_back(DrawCall{
.indexCount = static_cast<uint32_t>(cmd.ElemCount),
.startIndex = static_cast<uint32_t>(indexOffset + cmd.IdxOffset),
.clipRect = {static_cast<uint32_t>(clipMin.x), static_cast<uint32_t>(clipMin.y),
static_cast<uint32_t>(clipMax.x - clipMin.x), static_cast<uint32_t>(clipMax.y - clipMin.y)}});
}
vertexOffset += static_cast<uint32_t>(cmdList->VtxBuffer.Size);
indexOffset += static_cast<uint32_t>(cmdList->IdxBuffer.Size);
}
CHECK(vertexOffset == dataBuffer.m_vertices.size(), ());
CHECK(indexOffset == dataBuffer.m_indices.size(), ());
{
std::lock_guard<std::mutex> lock(m_bufferMutex);
// Projection
float const left = dd->DisplayPos.x;
float const right = dd->DisplayPos.x + dd->DisplaySize.x;
float const top = dd->DisplayPos.y;
float const bottom = dd->DisplayPos.y + dd->DisplaySize.y;
m_projection[0][0] = 2.0f / (right - left);
m_projection[1][1] = 2.0f / (top - bottom);
m_projection[2][2] = -1.0f;
m_projection[3][3] = 1.0f;
m_projection[0][3] = -(right + left) / (right - left);
m_projection[1][3] = -(top + bottom) / (top - bottom);
// Swap buffers
m_updateIndex = (m_updateIndex + 1) % m_uiDataBuffer.size();
}
}

View file

@ -0,0 +1,72 @@
#pragma once
#include "drape/glsl_types.hpp"
#include "drape/graphics_context.hpp"
#include "drape/mesh_object.hpp"
#include "drape/pointers.hpp"
#include "drape/render_state.hpp"
#include "drape/static_texture.hpp"
#include "drape/texture_manager.hpp"
#include <array>
#include <cstdint>
#include <functional>
#include <mutex>
#include <vector>
class ImguiRenderer
{
public:
ImguiRenderer();
void Render(ref_ptr<dp::GraphicsContext> context,
ref_ptr<dp::TextureManager> textureManager,
ref_ptr<gpu::ProgramManager> programManager);
void Update(std::function<void()> const & uiCallback);
void Reset();
private:
void UpdateTexture();
void UpdateBuffers();
struct ImguiVertex
{
glsl::vec2 position;
glsl::vec2 texCoords;
glsl::vec4 color;
};
static_assert(sizeof(ImguiVertex) == 2 * sizeof(glsl::vec4));
struct DrawCall
{
uint32_t indexCount = 0;
uint32_t startIndex = 0;
glsl::uvec4 clipRect{};
};
drape_ptr<dp::MeshObject> m_mesh;
uint32_t m_vertexCount = 2000;
uint32_t m_indexCount = 3000;
drape_ptr<dp::StaticTexture> m_texture;
std::vector<unsigned char> m_textureData;
uint32_t m_textureWidth = 0;
uint32_t m_textureHeight = 0;
dp::RenderState m_state;
struct UiDataBuffer
{
std::vector<ImguiVertex> m_vertices;
std::vector<uint16_t> m_indices;
std::vector<DrawCall> m_drawCalls;
uint32_t m_width;
uint32_t m_height;
};
std::array<UiDataBuffer, 2> m_uiDataBuffer;
size_t m_updateIndex = 0;
glsl::mat4 m_projection;
std::mutex m_bufferMutex;
std::mutex m_textureMutex;
};

672
dev_sandbox/main.cpp Normal file
View file

@ -0,0 +1,672 @@
#include "dev_sandbox/imgui_renderer.hpp"
#include "map/framework.hpp"
#include "platform/platform.hpp"
#include "platform/settings.hpp"
#include "coding/reader.hpp"
#include "base/logging.hpp"
#include "base/macros.hpp"
#include "std/target_os.hpp"
#include <chrono>
#include <functional>
#include <mutex>
#include <optional>
#include <sstream>
#include <string>
#include <string_view>
#include <vector>
#include <gflags/gflags.h>
#if defined(OMIM_OS_WINDOWS)
#define GLFW_EXPOSE_NATIVE_WIN32
#elif defined(OMIM_OS_LINUX)
#define GLFW_EXPOSE_NATIVE_X11
#elif defined(OMIM_OS_MAC)
#define GLFW_EXPOSE_NATIVE_COCOA
#else
#error Unsupported plaform
#endif
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <imgui/backends/imgui_impl_glfw.h>
#include <imgui/imgui.h>
DEFINE_string(data_path, "", "Path to data directory.");
DEFINE_string(log_abort_level, base::ToString(base::GetDefaultLogAbortLevel()),
"Log messages severity that causes termination.");
DEFINE_string(resources_path, "", "Path to resources directory.");
DEFINE_string(lang, "", "Device language.");
#if defined(OMIM_OS_MAC) || defined(OMIM_OS_LINUX)
drape_ptr<dp::GraphicsContextFactory> CreateContextFactory(GLFWwindow * window, dp::ApiVersion api, m2::PointU size);
void PrepareDestroyContextFactory(ref_ptr<dp::GraphicsContextFactory> contextFactory);
void OnCreateDrapeEngine(GLFWwindow * window, dp::ApiVersion api, ref_ptr<dp::GraphicsContextFactory> contextFactory);
void UpdateContentScale(GLFWwindow * window, float scale);
void UpdateSize(ref_ptr<dp::GraphicsContextFactory> contextFactory, int w, int h);
#endif
#if defined(OMIM_OS_LINUX)
// Workaround for storage::Status compilation issue:
// /usr/include/X11/Xlib.h:83:16: note: expanded from macro 'Status'
#undef Status
#endif
namespace
{
bool ValidateLogAbortLevel(char const * flagname, std::string const & value)
{
if (auto level = base::FromString(value); !level)
{
std::cerr << "Invalid value for --" << flagname << ": " << value << ", must be one of: ";
auto const & names = base::GetLogLevelNames();
for (size_t i = 0; i < names.size(); ++i)
{
if (i != 0)
std::cerr << ", ";
std::cerr << names[i];
}
std::cerr << '\n';
return false;
}
return true;
}
bool const g_logAbortLevelDummy = gflags::RegisterFlagValidator(&FLAGS_log_abort_level, &ValidateLogAbortLevel);
void errorCallback(int error, char const * description) { LOG(LERROR, ("GLFW (", error, "):", description)); }
std::function<void(int w, int h)> onResize;
std::function<void(double x, double y, int button, int action, int mods)> onMouseButton;
std::function<void(double x, double y)> onMouseMove;
std::function<void(double x, double y, double xOffset, double yOffset)> onScroll;
std::function<void(int key, int scancode, int action, int mods)> onKeyboardButton;
std::function<void(float xscale, float yscale)> onContentScale;
df::Touch GetTouch(double x, double y)
{
return df::Touch{.m_location = m2::PointF(static_cast<float>(x), static_cast<float>(y)), .m_id = 0};
}
df::Touch GetSymmetricalTouch(Framework & framework, df::Touch const & touch)
{
m2::PointD const pixelCenter = framework.GetVisiblePixelCenter();
m2::PointD const symmetricalLocation = pixelCenter + pixelCenter - m2::PointD(touch.m_location);
df::Touch result;
result.m_id = touch.m_id + 1;
result.m_location = symmetricalLocation;
return result;
}
df::TouchEvent GetTouchEvent(Framework & framework, double x, double y, int mods, df::TouchEvent::ETouchType type)
{
df::TouchEvent event;
event.SetTouchType(type);
event.SetFirstTouch(GetTouch(x, y));
if (mods & GLFW_MOD_SUPER)
event.SetSecondTouch(GetSymmetricalTouch(framework, event.GetFirstTouch()));
return event;
}
void FormatMapSize(uint64_t sizeInBytes, std::string & units, size_t & sizeToDownload)
{
int const mbInBytes = 1024 * 1024;
int const kbInBytes = 1024;
if (sizeInBytes > mbInBytes)
{
sizeToDownload = (sizeInBytes + mbInBytes - 1) / mbInBytes;
units = "MB";
}
else if (sizeInBytes > kbInBytes)
{
sizeToDownload = (sizeInBytes + kbInBytes - 1) / kbInBytes;
units = "KB";
}
else
{
sizeToDownload = sizeInBytes;
units = "B";
}
}
std::string_view GetMyPoisitionText(location::EMyPositionMode mode)
{
switch(mode)
{
case location::EMyPositionMode::PendingPosition: return "Pending";
case location::EMyPositionMode::NotFollowNoPosition: return "No position";
case location::EMyPositionMode::NotFollow: return "Not follow";
case location::EMyPositionMode::Follow: return "Follow";
case location::EMyPositionMode::FollowAndRotate: return "Follow and Rotate";
}
return "";
}
dp::ApiVersion GetApiVersion(char const * apiLabel)
{
std::string_view v(apiLabel);
if (v == "Metal") return dp::ApiVersion::Metal;
if (v == "Vulkan") return dp::ApiVersion::Vulkan;
if (v == "OpenGL") return dp::ApiVersion::OpenGLES3;
return dp::ApiVersion::Invalid;
}
#if defined(OMIM_OS_LINUX)
class LinuxGuiThread : public base::TaskLoop
{
public:
PushResult Push(Task && task) override
{
std::lock_guard<std::mutex> lock(m_mutex);
m_tasks.emplace_back(std::move(task));
return {true, base::TaskLoop::kNoId};
}
PushResult Push(Task const & task) override
{
std::lock_guard<std::mutex> lock(m_mutex);
m_tasks.emplace_back(task);
return {true, base::TaskLoop::kNoId};
}
void ExecuteTasks()
{
std::lock_guard<std::mutex> lock(m_mutex);
for (auto & task : m_tasks)
task();
m_tasks.clear();
}
private:
std::vector<Task> m_tasks;
std::mutex m_mutex;
};
#endif
} // namespace
int main(int argc, char * argv[])
{
// Our double parsing code (base/string_utils.hpp) needs dots as a floating point delimiters, not commas.
// TODO: Refactor our doubles parsing code to use locale-independent delimiters.
// For example, https://github.com/google/double-conversion can be used.
// See http://dbaron.org/log/20121222-locale for more details.
(void)::setenv("LC_NUMERIC", "C", 1);
Platform & platform = GetPlatform();
LOG(LINFO, ("Organic Maps: Developer Sandbox", platform.Version(), "detected CPU cores:", platform.CpuCores()));
gflags::SetUsageMessage("Developer Sandbox.");
gflags::SetVersionString(platform.Version());
gflags::ParseCommandLineFlags(&argc, &argv, true);
if (!FLAGS_resources_path.empty())
platform.SetResourceDir(FLAGS_resources_path);
if (!FLAGS_data_path.empty())
platform.SetWritableDirForTests(FLAGS_data_path);
if (auto const logLevel = base::FromString(FLAGS_log_abort_level); logLevel)
base::g_LogAbortLevel = *logLevel;
else
LOG(LCRITICAL, ("Invalid log level:", FLAGS_log_abort_level));
#if defined(OMIM_OS_LINUX)
auto guiThread = std::make_unique<LinuxGuiThread>();
auto guiThreadPtr = guiThread.get();
platform.SetGuiThread(std::move(guiThread));
#endif
// Init GLFW.
glfwSetErrorCallback(errorCallback);
if (!glfwInit())
{
return -1;
}
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
#if defined(OMIM_OS_WINDOWS)
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
#endif
auto monitor = glfwGetPrimaryMonitor();
auto mode = glfwGetVideoMode(monitor);
GLFWwindow * window =
glfwCreateWindow(mode->width, mode->height, "Organic Maps: Developer Sandbox", nullptr, nullptr);
int fbWidth = 0, fbHeight = 0;
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
float xs = 1.0f, ys = 1.0f;
glfwGetWindowContentScale(window, &xs, &ys);
float visualScale = std::max(xs, ys);
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
ImGui::StyleColorsClassic();
glfwMaximizeWindow(window);
platform.SetupMeasurementSystem();
bool outvalue;
if (!settings::Get(settings::kDeveloperMode, outvalue))
settings::Set(settings::kDeveloperMode, true);
if (!FLAGS_lang.empty())
(void)::setenv("LANGUAGE", FLAGS_lang.c_str(), 1);
FrameworkParams frameworkParams;
Framework framework(frameworkParams);
ImguiRenderer imguiRenderer;
Framework::DrapeCreationParams drapeParams{
#if defined(OMIM_OS_MAC)
.m_apiVersion = dp::ApiVersion::Metal,
#else
.m_apiVersion = dp::ApiVersion::Vulkan,
#endif
.m_visualScale = visualScale,
.m_surfaceWidth = fbWidth,
.m_surfaceHeight = fbHeight,
.m_renderInjectionHandler = [&](ref_ptr<dp::GraphicsContext> context,
ref_ptr<dp::TextureManager> textureManager,
ref_ptr<gpu::ProgramManager> programManager,
bool shutdown)
{
if (shutdown)
imguiRenderer.Reset();
else
imguiRenderer.Render(context, textureManager, programManager);
}};
gui::Skin guiSkin(gui::ResolveGuiSkinFile("default"), visualScale);
guiSkin.Resize(fbWidth, fbHeight);
guiSkin.ForEach([&](gui::EWidget widget, gui::Position const & pos) { drapeParams.m_widgetsInitInfo[widget] = pos; });
drapeParams.m_widgetsInitInfo[gui::WIDGET_SCALE_FPS_LABEL] = gui::Position(dp::LeftTop);
drape_ptr<dp::GraphicsContextFactory> contextFactory;
auto CreateDrapeEngine = [&](dp::ApiVersion version)
{
drapeParams.m_apiVersion = version;
drapeParams.m_visualScale = visualScale;
drapeParams.m_surfaceWidth = fbWidth;
drapeParams.m_surfaceHeight = fbHeight;
contextFactory = CreateContextFactory(window, drapeParams.m_apiVersion,
m2::PointU(static_cast<uint32_t>(drapeParams.m_surfaceWidth),
static_cast<uint32_t>(drapeParams.m_surfaceHeight)));
auto params = drapeParams;
framework.CreateDrapeEngine(make_ref(contextFactory), std::move(params));
OnCreateDrapeEngine(window, version, make_ref(contextFactory));
framework.SetRenderingEnabled(nullptr);
};
CreateDrapeEngine(drapeParams.m_apiVersion);
auto DestroyDrapeEngine = [&]()
{
framework.SetRenderingDisabled(true);
framework.DestroyDrapeEngine();
PrepareDestroyContextFactory(make_ref(contextFactory));
contextFactory.reset();
};
// Process resizing.
onResize = [&](int w, int h)
{
fbWidth = w;
fbHeight = h;
if (fbWidth > 0 && fbHeight > 0)
{
UpdateSize(make_ref(contextFactory), fbWidth, fbHeight);
framework.OnSize(fbWidth, fbHeight);
guiSkin.Resize(w, h);
gui::TWidgetsLayoutInfo layout;
guiSkin.ForEach([&layout](gui::EWidget w, gui::Position const & pos) { layout[w] = pos.m_pixelPivot; });
framework.SetWidgetLayout(std::move(layout));
framework.MakeFrameActive();
}
};
glfwSetFramebufferSizeCallback(window, [](GLFWwindow * wnd, int w, int h) { onResize(w, h); });
// Process change content scale.
onContentScale = [&](float xscale, float yscale)
{
visualScale = std::max(xscale, yscale);
framework.UpdateVisualScale(visualScale);
int w = 0, h = 0;
glfwGetWindowSize(window, &w, &h);
#if defined(OMIM_OS_MAC)
w *= xscale;
h *= yscale;
#endif
if (w != fbWidth || h != fbHeight)
{
#if defined(OMIM_OS_MAC)
UpdateContentScale(window, xscale);
#endif
fbWidth = w;
fbHeight = h;
UpdateSize(make_ref(contextFactory), fbWidth, fbHeight);
framework.OnSize(fbWidth, fbHeight);
}
};
glfwSetWindowContentScaleCallback(window,
[](GLFWwindow *, float xscale, float yscale) { onContentScale(xscale, yscale); });
// Location handler
std::optional<ms::LatLon> lastLatLon;
bool bearingEnabled = false;
float bearing = 0.0f;
auto setUserLocation = [&]()
{
if (lastLatLon)
{
framework.OnLocationUpdate(
location::GpsInfo{.m_source = location::EUser,
.m_timestamp = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count()) /
1000,
.m_latitude = lastLatLon->m_lat,
.m_longitude = lastLatLon->m_lon,
.m_horizontalAccuracy = 10,
.m_bearing = bearingEnabled ? bearing : -1.0f});
if (bearingEnabled)
{
framework.OnCompassUpdate(location::CompassInfo{.m_bearing = base::DegToRad(bearing)});
}
}
};
// Download maps handler
std::string downloadButtonLabel;
std::string retryButtonLabel;
std::string downloadStatusLabel;
storage::CountryId lastCountry;
auto const onCountryChanged = [&](storage::CountryId const & countryId)
{
downloadButtonLabel.clear();
retryButtonLabel.clear();
downloadStatusLabel.clear();
lastCountry = countryId;
// Called by Framework in World zoom level.
if (countryId.empty())
return;
auto const & storage = framework.GetStorage();
auto status = storage.CountryStatusEx(countryId);
auto const & countryName = countryId;
if (status == storage::Status::NotDownloaded)
{
std::string units;
size_t sizeToDownload = 0;
FormatMapSize(storage.CountrySizeInBytes(countryId).second, units, sizeToDownload);
std::stringstream str;
str << "Download (" << countryName << ") " << sizeToDownload << units;
downloadButtonLabel = str.str();
}
else if (status == storage::Status::InQueue)
{
std::stringstream str;
str << countryName << " is waiting for downloading";
downloadStatusLabel = str.str();
}
else if (status != storage::Status::Downloading && status != storage::Status::OnDisk &&
status != storage::Status::OnDiskOutOfDate)
{
std::stringstream str;
str << "Retry to download " << countryName;
retryButtonLabel = str.str();
}
};
framework.SetCurrentCountryChangedListener(onCountryChanged);
framework.GetStorage().Subscribe(
[&](storage::CountryId const & countryId)
{
// Storage also calls notifications for parents, but we are interested in leafs only.
if (framework.GetStorage().IsLeaf(countryId))
onCountryChanged(countryId);
},
[&](storage::CountryId const & countryId, downloader::Progress const & progress)
{
std::stringstream str;
str << "Downloading (" << countryId << ") " << (progress.m_bytesDownloaded * 100 / progress.m_bytesTotal)
<< "%";
downloadStatusLabel = str.str();
framework.MakeFrameActive();
});
// Handle mouse buttons.
bool touchActive = false;
int touchMods = 0;
bool setUpLocationByLeftClick = false;
onMouseButton = [&](double x, double y, int button, int action, int mods)
{
#if defined(OMIM_OS_LINUX)
ImGui::GetIO().MousePos = ImVec2(x / visualScale, y / visualScale);
#endif
if (ImGui::GetIO().WantCaptureMouse)
{
framework.MakeFrameActive();
return;
}
#if defined(OMIM_OS_MAC)
x *= visualScale;
y *= visualScale;
#endif
lastLatLon = mercator::ToLatLon(framework.PtoG(m2::PointD(x, y)));
if (setUpLocationByLeftClick)
{
setUserLocation();
return;
}
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
{
framework.TouchEvent(GetTouchEvent(framework, x, y, mods, df::TouchEvent::TOUCH_DOWN));
touchActive = true;
touchMods = mods;
}
if (touchActive && action == GLFW_RELEASE)
{
framework.TouchEvent(GetTouchEvent(framework, x, y, 0, df::TouchEvent::TOUCH_UP));
touchActive = false;
touchMods = 0;
}
};
glfwSetMouseButtonCallback(window,
[](GLFWwindow * wnd, int button, int action, int mods)
{
double x, y;
glfwGetCursorPos(wnd, &x, &y);
onMouseButton(x, y, button, action, mods);
});
// Handle mouse moving.
onMouseMove = [&](double x, double y)
{
#if defined(OMIM_OS_LINUX)
ImGui::GetIO().MousePos = ImVec2(x / visualScale, y / visualScale);
#endif
if (ImGui::GetIO().WantCaptureMouse)
framework.MakeFrameActive();
if (touchActive)
{
#if defined(OMIM_OS_MAC)
x *= visualScale;
y *= visualScale;
#endif
framework.TouchEvent(
GetTouchEvent(framework, x, y, touchMods, df::TouchEvent::TOUCH_MOVE));
}
};
glfwSetCursorPosCallback(window, [](GLFWwindow *, double x, double y) { onMouseMove(x, y); });
// Handle scroll.
onScroll = [&](double x, double y, double xOffset, double yOffset)
{
#if defined(OMIM_OS_LINUX)
ImGui::GetIO().MousePos = ImVec2(x / visualScale, y / visualScale);
#endif
if (ImGui::GetIO().WantCaptureMouse)
{
framework.MakeFrameActive();
return;
}
#if defined(OMIM_OS_MAC)
x *= visualScale;
y *= visualScale;
#endif
constexpr double kSensitivity = 0.01;
double const factor = yOffset * kSensitivity;
framework.Scale(exp(factor), m2::PointD(x, y), false);
};
glfwSetScrollCallback(window,
[](GLFWwindow * wnd, double xoffset, double yoffset)
{
double x, y;
glfwGetCursorPos(wnd, &x, &y);
onScroll(x, y, xoffset, yoffset);
});
// Keys.
onKeyboardButton = [&](int key, int scancode, int action, int mods) {};
glfwSetKeyCallback(window, [](GLFWwindow *, int key, int scancode, int action, int mods)
{ onKeyboardButton(key, scancode, action, mods); });
// imGui UI
bool enableDebugRectRendering = false;
bool enableAA = false;
auto imGuiUI = [&]()
{
ImGui::SetNextWindowPos(ImVec2(5, 20), ImGuiCond_Appearing);
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
// Drape controls
char const * apiLabels[] = {
#if defined(OMIM_OS_MAC)
"Metal",
"Vulkan",
"OpenGL"
#elif defined(OMIM_OS_LINUX)
"Vulkan",
"OpenGL"
#endif
};
static int currentAPI = 0;
if (ImGui::Combo("API", &currentAPI, apiLabels, IM_ARRAYSIZE(apiLabels)))
{
auto const apiVersion = GetApiVersion(apiLabels[currentAPI]);
if (framework.GetDrapeEngine()->GetApiVersion() != apiVersion)
{
DestroyDrapeEngine();
CreateDrapeEngine(apiVersion);
}
}
if (ImGui::Checkbox("Debug rect rendering", &enableDebugRectRendering))
framework.EnableDebugRectRendering(enableDebugRectRendering);
if (ImGui::Checkbox("Antialiasing", &enableAA))
framework.GetDrapeEngine()->SetPosteffectEnabled(df::PostprocessRenderer::Antialiasing, enableAA);
ImGui::NewLine();
ImGui::Separator();
ImGui::NewLine();
// Map controls
if (ImGui::Button("Scale +"))
framework.Scale(Framework::SCALE_MAG, true);
ImGui::SameLine();
if (ImGui::Button("Scale -"))
framework.Scale(Framework::SCALE_MIN, true);
ImGui::Checkbox("Set up location by left click", &setUpLocationByLeftClick);
if (setUpLocationByLeftClick)
{
if (ImGui::Checkbox("Bearing", &bearingEnabled))
setUserLocation();
ImGui::SameLine();
if (ImGui::SliderFloat(" ", &bearing, 0.0f, 360.0f, "%.1f"))
setUserLocation();
}
ImGui::Text("My positon mode: %s", GetMyPoisitionText(framework.GetMyPositionMode()).data());
if (ImGui::Button("Next Position Mode"))
framework.SwitchMyPositionNextMode();
ImGui::NewLine();
ImGui::Separator();
ImGui::NewLine();
// No downloading on Linux at the moment, need to implement http_thread without Qt.
#if !defined(OMIM_OS_LINUX)
// Download controls
if (!downloadButtonLabel.empty())
{
if (ImGui::Button(downloadButtonLabel.c_str()))
framework.GetStorage().DownloadNode(lastCountry);
}
if (!retryButtonLabel.empty())
{
if (ImGui::Button(retryButtonLabel.c_str()))
framework.GetStorage().RetryDownloadNode(lastCountry);
}
if (!downloadStatusLabel.empty())
ImGui::Text("%s", downloadStatusLabel.c_str());
if (!downloadButtonLabel.empty() || !retryButtonLabel.empty() || !downloadStatusLabel.empty())
{
ImGui::NewLine();
ImGui::Separator();
ImGui::NewLine();
}
#endif
ImGui::End();
};
ImGui_ImplGlfw_InitForOther(window, true);
// Main loop.
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
#if defined(OMIM_OS_LINUX)
guiThreadPtr->ExecuteTasks();
#endif
// Render imGui UI
ImGui_ImplGlfw_NewFrame();
ImGuiIO& io = ImGui::GetIO();
#if defined(OMIM_OS_LINUX)
// Apply correct visual scale on Linux
// In glfw for Linux, window size and framebuffer size are the same,
// even if visual scale is not 1.0. It's different from behaviour on Mac.
io.DisplaySize = ImVec2(fbWidth / visualScale, fbHeight / visualScale);
io.DisplayFramebufferScale = ImVec2(visualScale, visualScale);
double mouseX, mouseY;
glfwGetCursorPos(window, &mouseX, &mouseY);
io.AddMousePosEvent((float)mouseX / visualScale, (float)mouseY / visualScale);
#endif
io.IniFilename = nullptr;
imguiRenderer.Update(imGuiUI);
std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 30));
}
framework.EnterBackground();
DestroyDrapeEngine();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

370
dev_sandbox/main.mm Normal file
View file

@ -0,0 +1,370 @@
#include "iphone/Maps/Classes/MetalContextFactory.h"
#include "drape/gl_functions.hpp"
#include "drape/oglcontext.hpp"
#include "drape/metal/metal_base_context.hpp"
#include "drape/vulkan/vulkan_context_factory.hpp"
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#if __APPLE__
#define GLFW_EXPOSE_NATIVE_COCOA
#else
#error Unsupported OS
#endif
#include <GLFW/glfw3native.h>
#import <AppKit/NSOpenGL.h>
#import <Cocoa/Cocoa.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#include <vulkan/vulkan_macos.h>
#include <atomic>
#include <memory>
class MacOSVulkanContextFactory : public dp::vulkan::VulkanContextFactory
{
public:
MacOSVulkanContextFactory()
: dp::vulkan::VulkanContextFactory(1, 33, false) {}
void SetSurface(CAMetalLayer *layer)
{
VkMacOSSurfaceCreateInfoMVK createInfo = {
.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK,
.flags = 0,
.pView = static_cast<const void *>(CFBridgingRetain(layer)),
};
VkResult statusCode;
CHECK(vkCreateMacOSSurfaceMVK, ());
statusCode = vkCreateMacOSSurfaceMVK(m_vulkanInstance, &createInfo, nullptr,
&m_surface);
if (statusCode != VK_SUCCESS)
{
LOG_ERROR_VK_CALL(vkCreateMacOSSurfaceMVK, statusCode);
return;
}
uint32_t const renderingQueueIndex = m_drawContext->GetRenderingQueueFamilyIndex();
VkBool32 supportsPresent;
statusCode = vkGetPhysicalDeviceSurfaceSupportKHR(m_gpu, renderingQueueIndex, m_surface, &supportsPresent);
if (statusCode != VK_SUCCESS)
{
LOG_ERROR_VK_CALL(vkGetPhysicalDeviceSurfaceSupportKHR, statusCode);
return;
}
CHECK_EQUAL(supportsPresent, VK_TRUE, ());
CHECK(QuerySurfaceSize(), ());
if (m_drawContext)
m_drawContext->SetSurface(m_surface, m_surfaceFormat, m_surfaceCapabilities);
}
void ResetSurface()
{
if (m_drawContext)
m_drawContext->ResetSurface(false);
vkDestroySurfaceKHR(m_vulkanInstance, m_surface, nullptr);
}
};
class MacGLContext : public dp::OGLContext
{
public:
MacGLContext(MacGLContext * contextToShareWith)
: m_viewSet(false)
{
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFAAccelerated,
NSOpenGLPFAOpenGLProfile,
NSOpenGLProfileVersion4_1Core,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize,
24,
NSOpenGLPFAAlphaSize,
8,
NSOpenGLPFADepthSize,
24,
NSOpenGLPFAStencilSize,
8,
0
};
m_pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
CHECK(m_pixelFormat, ("Pixel format is not found"));
m_context = [[NSOpenGLContext alloc] initWithFormat:m_pixelFormat
shareContext:(contextToShareWith ? contextToShareWith->m_context : nil)];
int interval = 1;
[m_context getValues:&interval forParameter:NSOpenGLContextParameterSwapInterval];
}
~MacGLContext()
{
@autoreleasepool {
[m_context clearDrawable];
m_pixelFormat = nil;
m_context = nil;
}
}
bool BeginRendering() override { return m_viewSet; }
void Present() override
{
if (m_viewSet)
{
std::lock_guard<std::mutex> lock(m_updateSizeMutex);
[m_context flushBuffer];
}
}
void MakeCurrent() override
{
[m_context makeCurrentContext];
}
void DoneCurrent() override
{
[NSOpenGLContext clearCurrentContext];
}
void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override
{
if (framebuffer)
framebuffer->Bind();
else
GLFunctions::glBindFramebuffer(0);
}
void SetView(NSView* view)
{
[m_context setView: view];
[m_context update];
m_viewSet = true;
}
void UpdateSize(int w, int h)
{
std::lock_guard<std::mutex> lock(m_updateSizeMutex);
[m_context update];
}
private:
NSOpenGLPixelFormat * m_pixelFormat = nil;
NSOpenGLContext* m_context = nil;
std::atomic<bool> m_viewSet;
std::mutex m_updateSizeMutex;
};
class MacGLContextFactory: public dp::GraphicsContextFactory
{
public:
dp::GraphicsContext * GetDrawContext() override
{
bool needNotify = false;
{
std::lock_guard<std::mutex> lock(m_contextAccess);
if (m_drawContext == nullptr)
{
m_drawContext = std::make_unique<MacGLContext>(m_uploadContext.get());
needNotify = true;
}
}
if (needNotify)
NotifyView();
std::lock_guard<std::mutex> lock(m_contextAccess);
return m_drawContext.get();
}
dp::GraphicsContext * GetResourcesUploadContext() override
{
std::lock_guard<std::mutex> lock(m_contextAccess);
if (m_uploadContext == nullptr)
m_uploadContext = std::make_unique<MacGLContext>(m_drawContext.get());
return m_uploadContext.get();
}
void WaitForInitialization(dp::GraphicsContext *) override
{
std::unique_lock<std::mutex> lock(m_initializationMutex);
if (m_isInitialized)
return;
m_initializationCounter++;
if (m_initializationCounter >= kGLThreadsCount)
{
m_isInitialized = true;
m_initializationCondition.notify_all();
}
else
{
m_initializationCondition.wait(lock, [this] { return m_isInitialized; });
}
}
bool IsDrawContextCreated() const override
{
std::lock_guard<std::mutex> lock(m_contextAccess);
return m_drawContext != nullptr;
}
bool IsUploadContextCreated() const override
{
std::lock_guard<std::mutex> lock(m_contextAccess);
return m_uploadContext != nullptr;
}
void SetView(NSView* view)
{
bool needWait;
{
std::lock_guard<std::mutex> lock(m_contextAccess);
needWait = (m_drawContext == nullptr);
}
if (needWait)
{
std::unique_lock<std::mutex> lock(m_viewSetMutex);
m_viewSetCondition.wait(lock, [this] { return m_viewSet; });
}
std::lock_guard<std::mutex> lock(m_contextAccess);
CHECK(m_drawContext, ());
m_drawContext->SetView(view);
}
void UpdateSize(int w, int h)
{
std::lock_guard<std::mutex> lock(m_contextAccess);
if (m_drawContext)
m_drawContext->UpdateSize(w, h);
}
private:
void NotifyView()
{
std::lock_guard<std::mutex> lock(m_viewSetMutex);
m_viewSet = true;
m_viewSetCondition.notify_all();
}
static size_t constexpr kGLThreadsCount = 2;
std::unique_ptr<MacGLContext> m_drawContext;
std::unique_ptr<MacGLContext> m_uploadContext;
mutable std::mutex m_contextAccess;
bool m_isInitialized = false;
size_t m_initializationCounter = 0;
std::condition_variable m_initializationCondition;
std::mutex m_initializationMutex;
bool m_viewSet = false;
std::condition_variable m_viewSetCondition;
std::mutex m_viewSetMutex;
};
drape_ptr<dp::GraphicsContextFactory> CreateContextFactory(GLFWwindow *window, dp::ApiVersion api, m2::PointU size)
{
if (api == dp::ApiVersion::Metal)
{
CAMetalLayer *layer = [CAMetalLayer layer];
layer.device = MTLCreateSystemDefaultDevice();
layer.opaque = YES;
layer.displaySyncEnabled = YES;
NSWindow *nswindow = glfwGetCocoaWindow(window);
NSScreen *screen = [NSScreen mainScreen];
CGFloat factor = [screen backingScaleFactor];
layer.contentsScale = factor;
nswindow.contentView.layer = layer;
nswindow.contentView.wantsLayer = YES;
return make_unique_dp<MetalContextFactory>(layer, size);
}
if (api == dp::ApiVersion::Vulkan)
{
CAMetalLayer *layer = [CAMetalLayer layer];
layer.device = MTLCreateSystemDefaultDevice();
layer.opaque = YES;
layer.displaySyncEnabled = YES;
NSWindow *nswindow = glfwGetCocoaWindow(window);
NSScreen *screen = [NSScreen mainScreen];
CGFloat factor = [screen backingScaleFactor];
layer.contentsScale = factor;
nswindow.contentView.layer = layer;
nswindow.contentView.wantsLayer = YES;
auto contextFactory = make_unique_dp<MacOSVulkanContextFactory>();
contextFactory->SetSurface(layer);
return contextFactory;
}
if (api == dp::ApiVersion::OpenGLES3)
{
NSWindow *nswindow = glfwGetCocoaWindow(window);
[nswindow.contentView setWantsBestResolutionOpenGLSurface:YES];
return make_unique_dp<MacGLContextFactory>();
}
ASSERT(false, ("API is not available yet"));
return nullptr;
}
void OnCreateDrapeEngine(GLFWwindow *window, dp::ApiVersion api,
ref_ptr<dp::GraphicsContextFactory> contextFactory)
{
if (api == dp::ApiVersion::OpenGLES3)
{
NSWindow *nswindow = glfwGetCocoaWindow(window);
ref_ptr<MacGLContextFactory> macosContextFactory = contextFactory;
macosContextFactory->SetView(nswindow.contentView);
}
}
void PrepareDestroyContextFactory(ref_ptr<dp::GraphicsContextFactory> contextFactory)
{
auto const api = contextFactory->GetDrawContext()->GetApiVersion();
if (api == dp::ApiVersion::Metal || api == dp::ApiVersion::OpenGLES3)
{
// Do nothing
}
else if (api == dp::ApiVersion::Vulkan)
{
ref_ptr<MacOSVulkanContextFactory> macosContextFactory = contextFactory;
macosContextFactory->ResetSurface();
}
else
{
ASSERT(false, ("API is not available yet"));
}
}
void UpdateContentScale(GLFWwindow *window, float scale)
{
NSWindow *nswindow = glfwGetCocoaWindow(window);
if (nswindow.contentView.layer)
nswindow.contentView.layer.contentsScale = scale;
}
void UpdateSize(ref_ptr<dp::GraphicsContextFactory> contextFactory, int w, int h)
{
if (!contextFactory || !contextFactory->GetDrawContext())
return;
auto const api = contextFactory->GetDrawContext()->GetApiVersion();
if (api == dp::ApiVersion::OpenGLES3)
{
ref_ptr<MacGLContextFactory> macosContextFactory = contextFactory;
macosContextFactory->UpdateSize(w, h);
}
}

411
dev_sandbox/main_linux.cpp Normal file
View file

@ -0,0 +1,411 @@
#include "std/target_os.hpp"
#if !defined(OMIM_OS_LINUX)
#error Unsupported OS
#endif
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#define GLFW_EXPOSE_NATIVE_X11
#include <GLFW/glfw3native.h>
#include <dlfcn.h>
#include <X11/X.h>
#include <vulkan_wrapper.h>
#include <vulkan/vulkan_xlib.h>
// Workaround for TestFunction::Always compilation issue:
// /usr/include/X11/X.h:441:33: note: expanded from macro 'Always'
#undef Always
// Workaround for storage::Status compilation issue:
// /usr/include/X11/Xlib.h:83:16: note: expanded from macro 'Status'
#undef Status
#include "drape/vulkan/vulkan_context_factory.hpp"
#include "drape/gl_functions.hpp"
#include "drape/gl_includes.hpp"
#include "drape/oglcontext.hpp"
#include <array>
#include <atomic>
#include <memory>
class LinuxVulkanContextFactory : public dp::vulkan::VulkanContextFactory
{
public:
LinuxVulkanContextFactory() : dp::vulkan::VulkanContextFactory(1, 33, false) {}
void SetSurface(Display * display, Window window)
{
VkXlibSurfaceCreateInfoKHR const createInfo = {
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
.pNext = nullptr,
.flags = 0,
.dpy = display,
.window = window,
};
VkResult statusCode;
CHECK(vkCreateXlibSurfaceKHR, ());
statusCode = vkCreateXlibSurfaceKHR(m_vulkanInstance, &createInfo, nullptr, &m_surface);
if (statusCode != VK_SUCCESS)
{
LOG_ERROR_VK_CALL(vkCreateXlibSurfaceKHR, statusCode);
return;
}
uint32_t const renderingQueueIndex = m_drawContext->GetRenderingQueueFamilyIndex();
VkBool32 supportsPresent;
statusCode = vkGetPhysicalDeviceSurfaceSupportKHR(m_gpu, renderingQueueIndex, m_surface, &supportsPresent);
if (statusCode != VK_SUCCESS)
{
LOG_ERROR_VK_CALL(vkGetPhysicalDeviceSurfaceSupportKHR, statusCode);
return;
}
CHECK_EQUAL(supportsPresent, VK_TRUE, ());
CHECK(QuerySurfaceSize(), ());
if (m_drawContext)
m_drawContext->SetSurface(m_surface, m_surfaceFormat, m_surfaceCapabilities);
}
void ResetSurface()
{
if (m_drawContext)
m_drawContext->ResetSurface(false);
vkDestroySurfaceKHR(m_vulkanInstance, m_surface, nullptr);
}
};
// Based on: https://github.com/glfw/glfw/blob/master/src/glx_context.c
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_PBUFFER_HEIGHT 0x8040
#define GLX_PBUFFER_WIDTH 0x8041
#define GLX_DOUBLEBUFFER 5
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_WINDOW_BIT 0x00000001
#define GLX_PBUFFER_BIT 0x00000004
#define GLX_RGBA_BIT 0x00000001
#define GLX_RED_SIZE 8
#define GLX_GREEN_SIZE 9
#define GLX_BLUE_SIZE 10
#define GLX_ALPHA_SIZE 11
#define GLX_DEPTH_SIZE 12
#define GLX_STENCIL_SIZE 13
typedef XID GLXDrawable;
typedef struct __GLXcontext * GLXContext;
typedef XID GLXPbuffer;
typedef struct __GLXFBConfig * GLXFBConfig;
typedef void (*__GLXextproc)(void);
typedef __GLXextproc (*PFNGLXGETPROCADDRESSPROC)(const GLubyte * procName);
typedef int (*PFNXFREE)(void *);
typedef GLXFBConfig * (*PFNGLXCHOOSEFBCONFIGPROC)(Display *, int, const int *, int *);
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARB)(Display *, GLXFBConfig, GLXContext, Bool, const int *);
typedef void (*PFNGLXDESTROYCONTEXT)(Display *, GLXContext);
typedef GLXPbuffer (*PFNGLXCREATEPBUFFERPROC)(Display *, GLXFBConfig, const int *);
typedef void (*PFNGLXDESTROYPBUFFER)(Display *, GLXPbuffer);
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display *, GLXDrawable, GLXContext);
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display *, GLXDrawable);
struct GLXFunctions
{
GLXFunctions()
{
std::array<char const *, 3> libs = {
"libGLX.so.0",
"libGL.so.1",
"libGL.so",
};
for (char const * lib : libs)
{
m_module = dlopen(lib, RTLD_LAZY | RTLD_LOCAL);
if (m_module)
{
break;
}
}
CHECK(m_module != nullptr, ("Failed to initialize GLX"));
XFree = loadFunction<PFNXFREE>("XFree");
glXGetProcAddress = loadFunction<PFNGLXGETPROCADDRESSPROC>("glXGetProcAddress");
glXGetProcAddressARB = loadFunction<PFNGLXGETPROCADDRESSPROC>("glXGetProcAddressARB");
glXChooseFBConfig = loadGlxFunction<PFNGLXCHOOSEFBCONFIGPROC>("glXChooseFBConfig");
glXCreateContextAttribsARB = loadGlxFunction<PFNGLXCREATECONTEXTATTRIBSARB>("glXCreateContextAttribsARB");
glXDestroyContext = loadGlxFunction<PFNGLXDESTROYCONTEXT>("glXDestroyContext");
glXCreatePbuffer = loadGlxFunction<PFNGLXCREATEPBUFFERPROC>("glXCreatePbuffer");
glXDestroyPbuffer = loadGlxFunction<PFNGLXDESTROYPBUFFER>("glXDestroyPbuffer");
glXMakeCurrent = loadGlxFunction<PFNGLXMAKECURRENTPROC>("glXMakeCurrent");
glXSwapBuffers = loadGlxFunction<PFNGLXSWAPBUFFERSPROC>("glXSwapBuffers");
}
~GLXFunctions()
{
if (m_module)
{
dlclose(m_module);
}
}
PFNXFREE XFree = nullptr;
PFNGLXGETPROCADDRESSPROC glXGetProcAddress = nullptr;
PFNGLXGETPROCADDRESSPROC glXGetProcAddressARB = nullptr;
PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = nullptr;
PFNGLXCREATECONTEXTATTRIBSARB glXCreateContextAttribsARB = nullptr;
PFNGLXDESTROYCONTEXT glXDestroyContext = nullptr;
PFNGLXCREATEPBUFFERPROC glXCreatePbuffer = nullptr;
PFNGLXDESTROYPBUFFER glXDestroyPbuffer = nullptr;
PFNGLXMAKECURRENTPROC glXMakeCurrent = nullptr;
PFNGLXSWAPBUFFERSPROC glXSwapBuffers = nullptr;
private:
template <typename T>
T loadFunction(char const * func)
{
auto f = reinterpret_cast<T>(dlsym(m_module, func));
ASSERT(f, ("Failed to initialize GLX:", func, "is not found"));
return f;
}
template <typename T>
T loadGlxFunction(char const * func)
{
if (auto f = reinterpret_cast<T>(glXGetProcAddress(reinterpret_cast<GLubyte const *>(func))))
return f;
if (auto f = reinterpret_cast<T>(glXGetProcAddressARB(reinterpret_cast<GLubyte const *>(func))))
return f;
return loadFunction<T>(func);
}
void * m_module = nullptr;
};
class LinuxGLContext : public dp::OGLContext
{
public:
LinuxGLContext(GLXFunctions const & glx, Display * display, Window window, LinuxGLContext * contextToShareWith,
bool usePixelBuffer)
: m_glx(glx), m_display(display), m_window(window)
{
static int visualAttribs[] = {
GLX_DOUBLEBUFFER, True,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, (usePixelBuffer ? GLX_PBUFFER_BIT : GLX_WINDOW_BIT),
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
None
};
int contextAttribs[] = {
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
None};
int fbcount = 0;
if (GLXFBConfig * config = m_glx.glXChooseFBConfig(display, DefaultScreen(display), visualAttribs, &fbcount))
{
m_context =
m_glx.glXCreateContextAttribsARB(display, config[0], contextToShareWith ? contextToShareWith->m_context : 0, True, contextAttribs);
CHECK(m_context != nullptr, ("Failed to create GLX context"));
if (usePixelBuffer)
{
int pbufferAttribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None};
m_pixelBufferHandle = m_glx.glXCreatePbuffer(display, config[0], pbufferAttribs);
CHECK(m_pixelBufferHandle != 0, ("Failed to create GLX pbuffer"));
}
m_glx.XFree(config);
}
}
~LinuxGLContext() override
{
if (m_pixelBufferHandle)
{
m_glx.glXDestroyPbuffer(m_display, m_pixelBufferHandle);
m_pixelBufferHandle = 0;
}
if (m_context)
{
m_glx.glXDestroyContext(m_display, m_context);
m_context = nullptr;
}
}
void Present() override
{
if (!m_pixelBufferHandle)
m_glx.glXSwapBuffers(m_display, m_window);
}
void MakeCurrent() override
{
if (!m_glx.glXMakeCurrent(m_display, m_pixelBufferHandle ? m_pixelBufferHandle : m_window, m_context))
LOG(LERROR, ("MakeCurrent(): glXMakeCurrent failed"));
}
void DoneCurrent() override
{
if (!m_glx.glXMakeCurrent(m_display, None, nullptr))
LOG(LERROR, ("DoneCurrent(): glXMakeCurrent failed"));
}
void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override
{
if (framebuffer)
framebuffer->Bind();
else
GLFunctions::glBindFramebuffer(0);
}
private:
GLXFunctions const & m_glx;
Display * m_display = nullptr;
Window m_window = 0;
GLXDrawable m_pixelBufferHandle = 0;
GLXContext m_context = nullptr;
};
class LinuxContextFactory : public dp::GraphicsContextFactory
{
public:
LinuxContextFactory(Display * display, Window window) : m_display(display), m_window(window) {}
dp::GraphicsContext * GetDrawContext() override
{
std::lock_guard<std::mutex> lock(m_contextAccess);
if (m_drawContext == nullptr)
m_drawContext = std::make_unique<LinuxGLContext>(m_glx, m_display, m_window, m_uploadContext.get(), false);
return m_drawContext.get();
}
dp::GraphicsContext * GetResourcesUploadContext() override
{
std::lock_guard<std::mutex> lock(m_contextAccess);
if (m_uploadContext == nullptr)
m_uploadContext = std::make_unique<LinuxGLContext>(m_glx, m_display, 0, m_drawContext.get(), true);
return m_uploadContext.get();
}
void WaitForInitialization(dp::GraphicsContext *) override
{
std::unique_lock<std::mutex> lock(m_initializationMutex);
if (m_isInitialized)
return;
m_initializationCounter++;
if (m_initializationCounter >= kGLThreadsCount)
{
m_isInitialized = true;
m_initializationCondition.notify_all();
}
else
{
m_initializationCondition.wait(lock, [this] { return m_isInitialized; });
}
}
bool IsDrawContextCreated() const override
{
std::lock_guard<std::mutex> lock(m_contextAccess);
return m_drawContext != nullptr;
}
bool IsUploadContextCreated() const override
{
std::lock_guard<std::mutex> lock(m_contextAccess);
return m_uploadContext != nullptr;
}
private:
static size_t constexpr kGLThreadsCount = 2;
GLXFunctions m_glx;
Display * m_display = nullptr;
Window m_window = 0;
std::unique_ptr<LinuxGLContext> m_drawContext;
std::unique_ptr<LinuxGLContext> m_uploadContext;
mutable std::mutex m_contextAccess;
bool m_isInitialized = false;
size_t m_initializationCounter = 0;
std::condition_variable m_initializationCondition;
std::mutex m_initializationMutex;
};
drape_ptr<dp::GraphicsContextFactory> CreateContextFactory(GLFWwindow * window, dp::ApiVersion api, m2::PointU size)
{
if (api == dp::ApiVersion::Vulkan)
{
auto contextFactory = make_unique_dp<LinuxVulkanContextFactory>();
contextFactory->SetSurface(glfwGetX11Display(), glfwGetX11Window(window));
return contextFactory;
}
if (api == dp::ApiVersion::OpenGLES3)
{
return make_unique_dp<LinuxContextFactory>(glfwGetX11Display(), glfwGetX11Window(window));
}
ASSERT(false, ("API is not available yet"));
return nullptr;
}
void OnCreateDrapeEngine(GLFWwindow * window, dp::ApiVersion api, ref_ptr<dp::GraphicsContextFactory> contextFactory)
{
// Do nothing
}
void PrepareDestroyContextFactory(ref_ptr<dp::GraphicsContextFactory> contextFactory)
{
auto const api = contextFactory->GetDrawContext()->GetApiVersion();
if (api == dp::ApiVersion::OpenGLES3)
{
// Do nothing
}
else if (api == dp::ApiVersion::Vulkan)
{
ref_ptr<LinuxVulkanContextFactory> linuxContextFactory = contextFactory;
linuxContextFactory->ResetSurface();
}
else
{
ASSERT(false, ("API is not available yet"));
}
}
void UpdateContentScale(GLFWwindow * window, float scale)
{
// Do nothing
}
void UpdateSize(ref_ptr<dp::GraphicsContextFactory> contextFactory, int w, int h)
{
// Do nothing
}

View file

@ -115,6 +115,10 @@ sudo apt update && sudo apt install -y \
libqt6positioning6-plugins \
libqt6positioning6 \
libsqlite3-dev \
libxrandr-dev \
libxinerama-dev \
libxcursor-dev \
libxi-dev \
zlib1g-dev
```

View file

@ -21,7 +21,7 @@ void DataBuffer::MoveToGPU(ref_ptr<GraphicsContext> context, GPUBuffer::Target t
uint32_t const currentSize = m_impl->GetCurrentSize();
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
if (currentSize != 0)
{

View file

@ -26,7 +26,6 @@ namespace dp
enum class ApiVersion
{
Invalid = -1,
OpenGLES2 = 0,
OpenGLES3,
Metal,
Vulkan
@ -101,7 +100,6 @@ inline std::string DebugPrint(dp::ApiVersion apiVersion)
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";
case dp::ApiVersion::Vulkan: return "Vulkan";
@ -121,9 +119,6 @@ inline dp::ApiVersion ApiVersionFromString(std::string const & str)
return dp::ApiVersion::Vulkan;
#endif
if (str == "OpenGLES2")
return dp::ApiVersion::OpenGLES2;
if (str == "OpenGLES3")
return dp::ApiVersion::OpenGLES3;

View file

@ -105,7 +105,7 @@ UNIT_TEST(UploadingGlyphs)
TestingGraphicsContext context;
Texture::Params p;
p.m_allocator = GetDefaultAllocator(make_ref(&context));
p.m_format = dp::TextureFormat::Alpha;
p.m_format = dp::TextureFormat::Red;
p.m_width = p.m_height = kTextureSize;
DummyTexture tex;

View file

@ -2,7 +2,7 @@
#include "drape/graphics_context.hpp"
// Testing context simulates OpenGLES2 API version.
// Testing context simulates OpenGLES3 API version.
class TestingGraphicsContext : public dp::GraphicsContext
{
public:
@ -38,5 +38,5 @@ public:
void SetCullingEnabled(bool enabled) override {}
private:
dp::ApiVersion m_apiVersion = dp::ApiVersion::OpenGLES2;
dp::ApiVersion m_apiVersion = dp::ApiVersion::OpenGLES3;
};

View file

@ -81,7 +81,7 @@ public:
FontTexture(m2::PointU const & size, ref_ptr<GlyphManager> glyphMng, ref_ptr<HWTextureAllocator> allocator)
: m_index(size, glyphMng)
{
DynamicTextureParams const params{size, TextureFormat::Alpha, TextureFilter::Linear, true /* m_usePixelBuffer */};
DynamicTextureParams const params{size, TextureFormat::Red, TextureFilter::Linear, true /* m_usePixelBuffer */};
Init(allocator, make_ref(&m_index), params);
}

View file

@ -134,7 +134,7 @@ void Framebuffer::SetSize(ref_ptr<dp::GraphicsContext> context, uint32_t width,
m_depthStencilRef->SetSize(context, m_width, m_height);
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
glConst depthAttachmentId = 0;
glConst stencilAttachmentId = 0;

View file

@ -7,67 +7,14 @@
namespace dp
{
void GLExtensionsList::Init(dp::ApiVersion apiVersion)
void GLExtensionsList::Init()
{
#if defined(OMIM_OS_MOBILE)
if (apiVersion == dp::ApiVersion::OpenGLES2)
{
#ifdef OMIM_OS_ANDROID
SetExtension(VertexArrayObject, false);
// On some Android devices glMapBufferRange/glMapBuffer works very slow.
// We have to substitute these functions to glBufferData/glBufferSubData.
SetExtension(MapBuffer, false);
SetExtension(MapBufferRange, false);
#else
CheckExtension(VertexArrayObject, "GL_OES_vertex_array_object");
CheckExtension(MapBuffer, "GL_OES_mapbuffer");
CheckExtension(MapBufferRange, "GL_EXT_map_buffer_range");
#endif
CheckExtension(UintIndices, "GL_OES_element_index_uint");
}
else
{
#ifdef OMIM_OS_ANDROID
SetExtension(MapBuffer, false);
SetExtension(MapBufferRange, false);
#else
SetExtension(MapBuffer, true);
SetExtension(MapBufferRange, true);
#endif
SetExtension(VertexArrayObject, true);
SetExtension(UintIndices, true);
}
#elif defined(OMIM_OS_LINUX)
SetExtension(MapBuffer, true);
SetExtension(UintIndices, true);
SetExtension(VertexArrayObject, true);
SetExtension(MapBufferRange, true);
#elif defined(OMIM_OS_WINDOWS)
SetExtension(MapBuffer, true);
SetExtension(UintIndices, true);
if (apiVersion == dp::ApiVersion::OpenGLES2)
{
SetExtension(VertexArrayObject, false);
SetExtension(MapBufferRange, false);
}
else
{
SetExtension(VertexArrayObject, true);
SetExtension(MapBufferRange, true);
}
// NOTE: MapBuffer/MapBufferRange are disabled by performance reasons according to
// https://github.com/organicmaps/organicmaps/commit/d72ab7c8cd8be0eb5a622d9d33ae943b391d5707
SetExtension(MapBuffer, false);
#else
SetExtension(MapBuffer, true);
SetExtension(UintIndices, true);
if (apiVersion == dp::ApiVersion::OpenGLES2)
{
CheckExtension(VertexArrayObject, "GL_APPLE_vertex_array_object");
SetExtension(MapBufferRange, false);
}
else
{
SetExtension(VertexArrayObject, true);
SetExtension(MapBufferRange, true);
}
#endif
}

View file

@ -14,14 +14,11 @@ class GLExtensionsList
public:
enum ExtensionName
{
VertexArrayObject,
MapBuffer,
UintIndices,
MapBufferRange
};
GLExtensionsList() = default;
void Init(dp::ApiVersion apiVersion);
void Init();
bool IsSupported(ExtensionName extName) const;
private:

View file

@ -239,81 +239,26 @@ void GLFunctions::Init(dp::ApiVersion apiVersion)
return;
CurrentApiVersion = apiVersion;
ExtensionsList.Init(apiVersion);
ExtensionsList.Init();
s_inited = true;
/// VAO
#if !defined(OMIM_OS_WINDOWS)
if (CurrentApiVersion == dp::ApiVersion::OpenGLES2)
{
#if defined(OMIM_OS_MAC)
glGenVertexArraysFn = &glGenVertexArraysAPPLE;
glBindVertexArrayFn = &glBindVertexArrayAPPLE;
glDeleteVertexArrayFn = &glDeleteVertexArraysAPPLE;
glMapBufferFn = &::glMapBuffer;
glUnmapBufferFn = &::glUnmapBuffer;
#elif defined(OMIM_OS_LINUX)
void *libhandle = dlopen("libGL.so.1", RTLD_LAZY);
if (!libhandle)
LOG(LCRITICAL, ("Failed to open libGL.so.1:", dlerror()));
glGenVertexArraysFn = (TglGenVertexArraysFn)dlsym(libhandle,"glGenVertexArraysOES");
glBindVertexArrayFn = (TglBindVertexArrayFn)dlsym(libhandle, "glBindVertexArrayOES");
glDeleteVertexArrayFn = (TglDeleteVertexArrayFn)dlsym(libhandle,"glDeleteVertexArraysOES");
glMapBufferFn = (TglMapBufferFn)dlsym(libhandle, "glMapBufferOES");
glUnmapBufferFn = (TglUnmapBufferFn)dlsym(libhandle, "glUnmapBufferOES");
glMapBufferRangeFn = (TglMapBufferRangeFn)dlsym(libhandle, "glMapBufferRangeEXT");
glFlushMappedBufferRangeFn =
(TglFlushMappedBufferRangeFn)dlsym(libhandle, "glFlushMappedBufferRangeEXT");
#elif defined(OMIM_OS_ANDROID)
glGenVertexArraysFn = (TglGenVertexArraysFn)eglGetProcAddress("glGenVertexArraysOES");
glBindVertexArrayFn = (TglBindVertexArrayFn)eglGetProcAddress("glBindVertexArrayOES");
glDeleteVertexArrayFn = (TglDeleteVertexArrayFn)eglGetProcAddress("glDeleteVertexArraysOES");
glMapBufferFn = &::glMapBufferOES;
glUnmapBufferFn = &::glUnmapBufferOES;
glMapBufferRangeFn = (TglMapBufferRangeFn)eglGetProcAddress("glMapBufferRangeEXT");
glFlushMappedBufferRangeFn =
(TglFlushMappedBufferRangeFn)eglGetProcAddress("glFlushMappedBufferRangeEXT");
#elif defined(OMIM_OS_MOBILE)
glGenVertexArraysFn = &glGenVertexArraysOES;
glBindVertexArrayFn = &glBindVertexArrayOES;
glDeleteVertexArrayFn = &glDeleteVertexArraysOES;
glMapBufferFn = &::glMapBufferOES;
glUnmapBufferFn = &::glUnmapBufferOES;
glMapBufferRangeFn = &::glMapBufferRangeEXT;
glFlushMappedBufferRangeFn = &::glFlushMappedBufferRangeEXT;
#endif // #if defined(OMIM_OS_MAC)
}
else if (CurrentApiVersion == dp::ApiVersion::OpenGLES3)
{
// OpenGL ES3 api is the same for all systems, except WINDOWS.
glGenVertexArraysFn = ::glGenVertexArrays;
glBindVertexArrayFn = ::glBindVertexArray;
glDeleteVertexArrayFn = ::glDeleteVertexArrays;
glUnmapBufferFn = ::glUnmapBuffer;
glMapBufferRangeFn = ::glMapBufferRange;
glFlushMappedBufferRangeFn = ::glFlushMappedBufferRange;
glGetStringiFn = ::glGetStringi;
}
else
{
CHECK(false, ("Unknown Graphics API"));
}
// OpenGL ES3 api is the same for all systems, except WINDOWS.
glGenVertexArraysFn = ::glGenVertexArrays;
glBindVertexArrayFn = ::glBindVertexArray;
glDeleteVertexArrayFn = ::glDeleteVertexArrays;
glUnmapBufferFn = ::glUnmapBuffer;
glMapBufferRangeFn = ::glMapBufferRange;
glFlushMappedBufferRangeFn = ::glFlushMappedBufferRange;
glGetStringiFn = ::glGetStringi;
#else // OMIM_OS_WINDOWS
if (ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject))
{
glGenVertexArraysFn = LOAD_GL_FUNC(TglGenVertexArraysFn, glGenVertexArrays);
glBindVertexArrayFn = LOAD_GL_FUNC(TglBindVertexArrayFn, glBindVertexArray);
glDeleteVertexArrayFn = LOAD_GL_FUNC(TglDeleteVertexArrayFn, glDeleteVertexArrays);
}
glMapBufferFn = LOAD_GL_FUNC(TglMapBufferFn, glMapBuffer);
glGenVertexArraysFn = LOAD_GL_FUNC(TglGenVertexArraysFn, glGenVertexArrays);
glBindVertexArrayFn = LOAD_GL_FUNC(TglBindVertexArrayFn, glBindVertexArray);
glDeleteVertexArrayFn = LOAD_GL_FUNC(TglDeleteVertexArrayFn, glDeleteVertexArrays);
glUnmapBufferFn = LOAD_GL_FUNC(TglUnmapBufferFn, glUnmapBuffer);
glMapBufferFn = LOAD_GL_FUNC(TglMapBufferFn, glMapBuffer);
glFlushMappedBufferRangeFn = LOAD_GL_FUNC(TglFlushMappedBufferRangeFn, glFlushMappedBufferRange);
glGetStringiFn = LOAD_GL_FUNC(TglGetStringiFn, glGetStringi);
#endif
glClearColorFn = LOAD_GL_FUNC(TglClearColorFn, glClearColor);
@ -393,115 +338,94 @@ 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)
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glGetStringiFn != nullptr, ());
GLint n = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
for (GLint i = 0; i < n; i++)
{
char const * extensions = reinterpret_cast<char const *>(::glGetString(GL_EXTENSIONS));
GLCHECKCALL();
if (extensions == nullptr)
return false;
char const * extName = name.c_str();
char const * ptr = nullptr;
while ((ptr = strstr(extensions, extName)) != nullptr)
{
char const * end = ptr + strlen(extName);
if (isspace(*end) || *end == '\0')
return true;
extensions = end;
}
}
else if (CurrentApiVersion == dp::ApiVersion::OpenGLES3)
{
ASSERT(glGetStringiFn != nullptr, ());
GLint n = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
for (GLint i = 0; i < n; i++)
{
std::string const extension =
std::string(reinterpret_cast<char const *>(glGetStringiFn(GL_EXTENSIONS, i)));
if (extension == name)
return true;
}
std::string const extension =
std::string(reinterpret_cast<char const *>(glGetStringiFn(GL_EXTENSIONS, i)));
if (extension == name)
return true;
}
return false;
}
void GLFunctions::glClearColor(float r, float g, float b, float a)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glClearColorFn != nullptr, ());
GLCHECK(glClearColorFn(r, g, b, a));
}
void GLFunctions::glClear(uint32_t clearBits)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glScissorFn != nullptr, ());
GLCHECK(glScissorFn(x, y, w, h));
}
void GLFunctions::glFlush()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glFlushFn != nullptr, ());
GLCHECK(glFlushFn());
}
void GLFunctions::glFinish()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glFinish());
}
void GLFunctions::glFrontFace(glConst mode)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glFrontFace(mode));
}
void GLFunctions::glCullFace(glConst face)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glCullFace(face));
}
void GLFunctions::glStencilOpSeparate(glConst face, glConst sfail, glConst dpfail, glConst dppass)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glStencilFuncSeparate(face, func, ref, mask));
}
void GLFunctions::glPixelStore(glConst name, uint32_t value)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glPixelStorei(name, value));
}
int32_t GLFunctions::glGetInteger(glConst pname)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLint value;
GLCHECK(::glGetIntegerv(pname, &value));
return (int32_t)value;
@ -509,7 +433,7 @@ int32_t GLFunctions::glGetInteger(glConst pname)
std::string GLFunctions::glGetString(glConst pname)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
char const * str = reinterpret_cast<char const *>(::glGetString(pname));
GLCHECKCALL();
if (str == nullptr)
@ -520,7 +444,7 @@ std::string GLFunctions::glGetString(glConst pname)
int32_t GLFunctions::glGetMaxLineWidth()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLint range[2];
GLCHECK(::glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range));
return std::max(range[0], range[1]);
@ -528,7 +452,7 @@ int32_t GLFunctions::glGetMaxLineWidth()
int32_t GLFunctions::glGetBufferParameter(glConst target, glConst name)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLint result;
ASSERT(glGetBufferParameterFn != nullptr, ());
GLCHECK(glGetBufferParameterFn(target, name, &result));
@ -537,19 +461,19 @@ int32_t GLFunctions::glGetBufferParameter(glConst target, glConst name)
void GLFunctions::glEnable(glConst mode)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glEnable(mode));
}
void GLFunctions::glDisable(glConst mode)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glDisable(mode));
}
void GLFunctions::glClearDepthValue(double depth)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
#if defined(OMIM_OS_IPHONE) || defined(OMIM_OS_ANDROID) || defined(OMIM_OS_LINUX)
GLCHECK(::glClearDepthf(static_cast<GLclampf>(depth)));
#else
@ -559,32 +483,32 @@ void GLFunctions::glClearDepthValue(double depth)
void GLFunctions::glDepthMask(bool needWriteToDepthBuffer)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glDepthMask(convert(needWriteToDepthBuffer)));
}
void GLFunctions::glDepthFunc(glConst depthFunc)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glDepthFunc(depthFunc));
}
void GLFunctions::glBlendEquation(glConst function)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glBlendEquationFn != nullptr, ());
GLCHECK(glBlendEquationFn(function));
}
void GLFunctions::glBlendFunc(glConst srcFactor, glConst dstFactor)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glBlendFunc(srcFactor, dstFactor));
}
bool GLFunctions::CanEnableDebugMessages()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
if (glDebugMessageCallbackFn == nullptr)
return false;
if (glDebugMessageControlFn == nullptr)
@ -596,7 +520,7 @@ bool GLFunctions::CanEnableDebugMessages()
void GLFunctions::glDebugMessageCallback(TglDebugProc messageCallback, void * userParam)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glDebugMessageCallbackFn != nullptr, ());
GLCHECK(glDebugMessageCallbackFn(reinterpret_cast<GLDEBUGPROC>(messageCallback), userParam));
}
@ -604,14 +528,14 @@ void GLFunctions::glDebugMessageCallback(TglDebugProc messageCallback, void * us
void GLFunctions::glDebugMessageControl(glConst source, glConst type, glConst severity,
int32_t count, uint32_t const * ids, uint8_t enabled)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glDebugMessageControlFn != nullptr, ());
GLCHECK(glDebugMessageControlFn(source, type, severity, count, ids, enabled));
}
uint32_t GLFunctions::glGenVertexArray()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glGenVertexArraysFn != nullptr, ());
GLuint result = std::numeric_limits<GLuint>::max();
GLCHECK(glGenVertexArraysFn(1, &result));
@ -620,21 +544,21 @@ uint32_t GLFunctions::glGenVertexArray()
void GLFunctions::glBindVertexArray(uint32_t vao)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glBindVertexArrayFn != nullptr, ());
GLCHECK(glBindVertexArrayFn(vao));
}
void GLFunctions::glDeleteVertexArray(uint32_t vao)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glDeleteVertexArrayFn != nullptr, ());
GLCHECK(glDeleteVertexArrayFn(1, &vao));
}
uint32_t GLFunctions::glGenBuffer()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glGenBuffersFn != nullptr, ());
GLuint result = std::numeric_limits<GLuint>::max();
GLCHECK(glGenBuffersFn(1, &result));
@ -643,7 +567,7 @@ uint32_t GLFunctions::glGenBuffer()
void GLFunctions::glBindBuffer(uint32_t vbo, uint32_t target)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glBindBufferFn != nullptr, ());
#ifdef DEBUG
std::lock_guard<std::mutex> guard(g_boundBuffersMutex);
@ -654,7 +578,7 @@ void GLFunctions::glBindBuffer(uint32_t vbo, uint32_t target)
void GLFunctions::glDeleteBuffer(uint32_t vbo)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glDeleteBuffersFn != nullptr, ());
#ifdef DEBUG
std::lock_guard<std::mutex> guard(g_boundBuffersMutex);
@ -666,21 +590,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glBufferSubDataFn != nullptr, ());
GLCHECK(glBufferSubDataFn(target, offset, size, data));
}
void * GLFunctions::glMapBuffer(glConst target, glConst access)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glMapBufferFn != nullptr, ());
void * result = glMapBufferFn(target, access);
GLCHECKCALL();
@ -689,7 +613,7 @@ void * GLFunctions::glMapBuffer(glConst target, glConst access)
void GLFunctions::glUnmapBuffer(glConst target)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUnmapBufferFn != nullptr, ());
VERIFY(glUnmapBufferFn(target) == GL_TRUE, ());
GLCHECKCALL();
@ -698,7 +622,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glMapBufferRangeFn != nullptr, ());
void * result = glMapBufferRangeFn(target, offset, length, access);
GLCHECKCALL();
@ -707,14 +631,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glFlushMappedBufferRangeFn != nullptr, ());
GLCHECK(glFlushMappedBufferRangeFn(target, offset, length));
}
uint32_t GLFunctions::glCreateShader(glConst type)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glCreateShaderFn != nullptr, ());
GLuint result = glCreateShaderFn(type);
GLCHECKCALL();
@ -723,7 +647,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glShaderSourceFn != nullptr, ());
std::string fullSrc;
@ -746,7 +670,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glCompileShaderFn != nullptr, ());
ASSERT(glGetShaderivFn != nullptr, ());
ASSERT(glGetShaderInfoLogFn != nullptr, ());
@ -766,14 +690,14 @@ bool GLFunctions::glCompileShader(uint32_t shaderID, std::string & errorLog)
void GLFunctions::glDeleteShader(uint32_t shaderID)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glDeleteShaderFn != nullptr, ());
GLCHECK(glDeleteBuffersFn(1, &shaderID));
}
uint32_t GLFunctions::glCreateProgram()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glCreateProgramFn != nullptr, ());
GLuint result = glCreateProgramFn();
GLCHECKCALL();
@ -782,21 +706,21 @@ uint32_t GLFunctions::glCreateProgram()
void GLFunctions::glAttachShader(uint32_t programID, uint32_t shaderID)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glAttachShaderFn != nullptr, ());
GLCHECK(glAttachShaderFn(programID, shaderID));
}
void GLFunctions::glDetachShader(uint32_t programID, uint32_t shaderID)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glDetachShaderFn != nullptr, ());
GLCHECK(glDetachShaderFn(programID, shaderID));
}
bool GLFunctions::glLinkProgram(uint32_t programID, std::string & errorLog)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glLinkProgramFn != nullptr, ());
ASSERT(glGetProgramivFn != nullptr, ());
ASSERT(glGetProgramInfoLogFn != nullptr, ());
@ -817,21 +741,21 @@ bool GLFunctions::glLinkProgram(uint32_t programID, std::string & errorLog)
void GLFunctions::glDeleteProgram(uint32_t programID)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glDeleteProgramFn != nullptr, ());
GLCHECK(glDeleteProgramFn(programID));
}
void GLFunctions::glUseProgram(uint32_t programID)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glGetAttribLocationFn != nullptr, ());
int result = glGetAttribLocationFn(programID, name.c_str());
GLCHECKCALL();
@ -841,14 +765,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glBindAttribLocationFn != nullptr, ());
GLCHECK(glBindAttribLocationFn(programID, index, name.c_str()));
}
void GLFunctions::glEnableVertexAttribute(int attributeLocation)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glEnableVertexAttributeFn != nullptr, ());
GLCHECK(glEnableVertexAttributeFn(attributeLocation));
}
@ -856,7 +780,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glVertexAttributePointerFn != nullptr, ());
GLCHECK(glVertexAttributePointerFn(attrLocation, count, type, convert(needNormalize), stride,
reinterpret_cast<void *>(offset)));
@ -865,7 +789,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glGetActiveUniformFn != nullptr, ());
GLchar buff[256];
GLCHECK(glGetActiveUniformFn(programID, uniformIndex, ARRAY_SIZE(buff), nullptr, uniformSize,
@ -875,17 +799,17 @@ 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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glGetUniformLocationFn != nullptr, ());
int result = glGetUniformLocationFn(programID, name.c_str());
GLCHECKCALL();
ASSERT(result != -1, ());
ASSERT(result != -1, (name));
return static_cast<int8_t>(result);
}
void GLFunctions::glUniformValuei(int8_t location, int32_t v)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform1iFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform1iFn(location, v));
@ -893,7 +817,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform2iFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform2iFn(location, v1, v2));
@ -901,7 +825,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform3iFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform3iFn(location, v1, v2, v3));
@ -909,7 +833,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform4iFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform4iFn(location, v1, v2, v3, v4));
@ -917,7 +841,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform1ivFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform1ivFn(location, size, v));
@ -925,7 +849,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform1fFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform1fFn(location, v));
@ -933,7 +857,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform2fFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform2fFn(location, v1, v2));
@ -941,7 +865,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform3fFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform3fFn(location, v1, v2, v3));
@ -949,7 +873,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform4fFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform4fFn(location, v1, v2, v3, v4));
@ -957,7 +881,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniform1fvFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniform1fvFn(location, size, v));
@ -965,7 +889,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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glUniformMatrix4fvFn != nullptr, ());
ASSERT(location != -1, ());
GLCHECK(glUniformMatrix4fvFn(location, 1, GL_FALSE, values));
@ -973,7 +897,7 @@ void GLFunctions::glUniformMatrix4x4Value(int8_t location, float const * values)
uint32_t GLFunctions::glGetCurrentProgram()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLint programIndex = 0;
GLCHECK(glGetIntegerv(GL_CURRENT_PROGRAM, &programIndex));
ASSERT_GREATER_OR_EQUAL(programIndex, 0, ());
@ -982,7 +906,7 @@ uint32_t GLFunctions::glGetCurrentProgram()
int32_t GLFunctions::glGetProgramiv(uint32_t program, glConst paramName)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glGetProgramivFn != nullptr, ());
GLint paramValue = 0;
GLCHECK(glGetProgramivFn(program, paramName, &paramValue));
@ -991,14 +915,14 @@ int32_t GLFunctions::glGetProgramiv(uint32_t program, glConst paramName)
void GLFunctions::glActiveTexture(glConst texBlock)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glActiveTextureFn != nullptr, ());
GLCHECK(glActiveTextureFn(texBlock));
}
uint32_t GLFunctions::glGenTexture()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLuint result = std::numeric_limits<GLuint>::max();
GLCHECK(::glGenTextures(1, &result));
return result;
@ -1006,20 +930,20 @@ uint32_t GLFunctions::glGenTexture()
void GLFunctions::glDeleteTexture(uint32_t id)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glDeleteTextures(1, &id));
}
void GLFunctions::glBindTexture(uint32_t textureID)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
// 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;
@ -1058,20 +982,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, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glDrawElements(primitive, indexCount,
sizeOfIndex == sizeof(uint32_t) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid *>(startIndex * sizeOfIndex)));
@ -1079,41 +1003,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, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glDrawArrays(mode, first, count));
}
void GLFunctions::glGenFramebuffer(uint32_t * fbo)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glGenFramebuffersFn != nullptr, ());
GLCHECK(glGenFramebuffersFn(1, fbo));
}
void GLFunctions::glDeleteFramebuffer(uint32_t * fbo)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glDeleteFramebuffersFn != nullptr, ());
GLCHECK(glDeleteFramebuffersFn(1, fbo));
}
void GLFunctions::glFramebufferTexture2D(glConst attachment, glConst texture)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
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_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glBindFramebufferFn != nullptr, ());
GLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER, fbo));
}
uint32_t GLFunctions::glCheckFramebufferStatus()
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
ASSERT(glCheckFramebufferStatusFn != nullptr, ());
uint32_t const result = glCheckFramebufferStatusFn(GL_FRAMEBUFFER);
GLCHECKCALL();
@ -1122,7 +1046,7 @@ uint32_t GLFunctions::glCheckFramebufferStatus()
void GLFunctions::glLineWidth(uint32_t value)
{
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLCHECK(::glLineWidth(static_cast<float>(value)));
}
@ -1143,7 +1067,7 @@ std::string GetGLError(GLenum error)
void CheckGLError(base::SrcPoint const & srcPoint)
{
ASSERT_NOT_EQUAL(GLFunctions::CurrentApiVersion, dp::ApiVersion::Invalid, ());
ASSERT_EQUAL(GLFunctions::CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
GLenum result = glGetError();
while (result != GL_NO_ERROR)
{

View file

@ -23,26 +23,14 @@ GLGpuProgram::GLGpuProgram(std::string const & programName,
if (!GLFunctions::glLinkProgram(m_programID, errorLog))
LOG(LERROR, ("Program ", programName, " link error = ", errorLog));
// On Tegra3 glGetActiveUniform isn't work if you detach shaders after linking.
LoadUniformLocations();
// On Tegra2 we cannot detach shaders at all.
// https://devtalk.nvidia.com/default/topic/528941/alpha-blending-not-working-on-t20-and-t30-under-ice-cream-sandwich/
if (!SupportManager::Instance().IsTegraDevice())
{
GLFunctions::glDetachShader(m_programID, m_vertexShader->GetID());
GLFunctions::glDetachShader(m_programID, m_fragmentShader->GetID());
}
GLFunctions::glDetachShader(m_programID, m_vertexShader->GetID());
GLFunctions::glDetachShader(m_programID, m_fragmentShader->GetID());
}
GLGpuProgram::~GLGpuProgram()
{
if (SupportManager::Instance().IsTegraDevice())
{
GLFunctions::glDetachShader(m_programID, m_vertexShader->GetID());
GLFunctions::glDetachShader(m_programID, m_fragmentShader->GetID());
}
GLFunctions::glDeleteProgram(m_programID);
}
@ -107,7 +95,7 @@ void GLGpuProgram::LoadUniformLocations()
std::string name;
GLFunctions::glGetActiveUniform(m_programID, static_cast<uint32_t>(i), &size, &info.m_type, name);
CHECK(kSupportedTypes.find(info.m_type) != kSupportedTypes.cend(),
("Used uniform has unsupported type. Program =", m_programName, "Type =", info.m_type));
("Used uniform has unsupported type. Program =", m_programName, "; Type =", info.m_type, "; Name =", name));
info.m_location = GLFunctions::glGetUniformLocation(m_programID, name);
m_uniforms[name] = std::move(info);

View file

@ -87,26 +87,17 @@ void * GPUBuffer::Map(uint32_t elementOffset, uint32_t elementCount)
m_isMapped = true;
#endif
if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES2)
if (!IsMapBufferSupported())
{
m_mappingOffset = elementOffset;
return IsMapBufferSupported() ? GLFunctions::glMapBuffer(glTarget(m_t)) : nullptr;
return nullptr;
}
else if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3)
{
if (!IsMapBufferSupported())
{
m_mappingOffset = elementOffset;
return nullptr;
}
m_mappingOffset = 0;
uint32_t const elementSize = GetElementSize();
uint32_t const byteOffset = elementOffset * elementSize;
uint32_t const byteCount = elementCount * elementSize;
return GLFunctions::glMapBufferRange(glTarget(m_t), byteOffset, byteCount,
gl_const::GLWriteBufferBit);
}
return nullptr;
m_mappingOffset = 0;
uint32_t const elementSize = GetElementSize();
uint32_t const byteOffset = elementOffset * elementSize;
uint32_t const byteCount = elementCount * elementSize;
return GLFunctions::glMapBufferRange(glTarget(m_t), byteOffset, byteCount,
gl_const::GLWriteBufferBit);
}
void GPUBuffer::UpdateData(void * gpuPtr, void const * data, uint32_t elementOffset,

View file

@ -36,7 +36,7 @@ void UnpackFormat(ref_ptr<dp::GraphicsContext> context, TextureFormat format,
glConst & layout, glConst & pixelType)
{
auto const apiVersion = context->GetApiVersion();
CHECK(apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3, ());
CHECK(apiVersion == dp::ApiVersion::OpenGLES3, ());
switch (format)
{
@ -45,21 +45,17 @@ void UnpackFormat(ref_ptr<dp::GraphicsContext> context, TextureFormat format,
pixelType = gl_const::GL8BitOnChannel;
return;
case TextureFormat::Alpha:
// On OpenGL ES3 GLAlpha is not supported, we use GLRed instead.
layout = apiVersion == dp::ApiVersion::OpenGLES2 ? gl_const::GLAlpha : gl_const::GLRed;
case TextureFormat::Red:
layout = gl_const::GLRed;
pixelType = gl_const::GL8BitOnChannel;
return;
case TextureFormat::RedGreen:
// On OpenGL ES2 2-channel textures are not supported.
layout = (apiVersion == dp::ApiVersion::OpenGLES2) ? gl_const::GLRGBA : gl_const::GLRedGreen;
layout = gl_const::GLRedGreen;
pixelType = gl_const::GL8BitOnChannel;
return;
case TextureFormat::DepthStencil:
// OpenGLES2 does not support texture-based depth-stencil.
CHECK(apiVersion != dp::ApiVersion::OpenGLES2, ());
layout = gl_const::GLDepthStencil;
pixelType = gl_const::GLUnsignedInt24_8Type;
return;

View file

@ -61,7 +61,7 @@ CVPixelBufferRef HWTextureAllocatorApple::CVCreatePixelBuffer(uint32_t width, ui
cvRetval = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA,
attrsRef, &result);
break;
case dp::TextureFormat::Alpha:
case dp::TextureFormat::Red:
cvRetval = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_OneComponent8,
attrsRef, &result);
break;

View file

@ -56,7 +56,7 @@ void const * IndexStorage::GetRawConst() const
bool IndexStorage::IsSupported32bit()
{
// We do not use 32-bit indices now to reduce size of index buffers.
static bool const supports32Bit = false;//GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::UintIndices);
static bool const supports32Bit = false;
return supports32Bit;
}

View file

@ -36,13 +36,8 @@ public:
{
UNUSED_VALUE(context);
bool const isVAOSupported =
GLFunctions::ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject);
if (isVAOSupported)
{
m_VAO = GLFunctions::glGenVertexArray();
GLFunctions::glBindVertexArray(m_VAO);
}
m_VAO = GLFunctions::glGenVertexArray();
GLFunctions::glBindVertexArray(m_VAO);
for (auto & buffer : m_mesh->m_buffers)
{
@ -64,23 +59,19 @@ public:
m_mesh->m_indices.data(), gl_const::GLStaticDraw);
}
if (isVAOSupported)
ref_ptr<dp::GLGpuProgram> p = program;
for (auto const & attribute : buffer->m_attributes)
{
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,
attribute.m_type, false, buffer->GetStrideInBytes(),
attribute.m_offset);
}
int8_t const attributePosition = p->GetAttributeLocation(attribute.m_attributeName);
ASSERT_NOT_EQUAL(attributePosition, -1, ());
GLFunctions::glEnableVertexAttribute(attributePosition);
GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount,
attribute.m_type, false, buffer->GetStrideInBytes(),
attribute.m_offset);
}
}
if (isVAOSupported)
GLFunctions::glBindVertexArray(0);
GLFunctions::glBindVertexArray(0);
GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
if (!m_mesh->m_indices.empty())
GLFunctions::glBindBuffer(0, gl_const::GLElementArrayBuffer);
@ -134,34 +125,12 @@ public:
void Bind(ref_ptr<dp::GpuProgram> program) override
{
if (GLFunctions::ExtensionsList.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);
if (m_indexBuffer != 0)
GLFunctions::glBindBuffer(m_indexBuffer, gl_const::GLElementArrayBuffer);
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,
attribute.m_type, false, buffer->GetStrideInBytes(),
attribute.m_offset);
}
}
GLFunctions::glBindVertexArray(m_VAO);
}
void Unbind() override
{
if (GLFunctions::ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject))
GLFunctions::glBindVertexArray(0);
GLFunctions::glBindVertexArray(0);
GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
if (m_indexBuffer != 0)
GLFunctions::glBindBuffer(0, gl_const::GLElementArrayBuffer);
@ -197,7 +166,7 @@ MeshObject::MeshObject(ref_ptr<dp::GraphicsContext> context, DrawPrimitive drawP
, m_debugName(debugName)
{
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
InitForOpenGL();
}

View file

@ -25,7 +25,7 @@ MTLPixelFormat UnpackFormat(TextureFormat format)
switch (format)
{
case TextureFormat::RGBA8: return MTLPixelFormatRGBA8Unorm;
case TextureFormat::Alpha: return MTLPixelFormatA8Unorm;
case TextureFormat::Red: return MTLPixelFormatA8Unorm; // TODO: change to R8, fix shaders
case TextureFormat::RedGreen: return MTLPixelFormatRG8Unorm;
case TextureFormat::DepthStencil: return MTLPixelFormatDepth32Float_Stencil8;
case TextureFormat::Depth: return MTLPixelFormatDepth32Float;

View file

@ -30,7 +30,7 @@ void AlphaBlendingState::Apply(ref_ptr<GraphicsContext> context)
{
// 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 (apiVersion == dp::ApiVersion::OpenGLES3)
{
GLFunctions::glBlendEquation(gl_const::GLAddBlend);
GLFunctions::glBlendFunc(gl_const::GLSrcAlpha, gl_const::GLOneMinusSrcAlpha);
@ -45,7 +45,7 @@ void Blending::Apply(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> progr
{
// 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 (apiVersion == dp::ApiVersion::OpenGLES3)
{
if (m_isEnabled)
GLFunctions::glEnable(gl_const::GLBlending);
@ -216,7 +216,7 @@ void TextureState::ApplyTextures(ref_ptr<GraphicsContext> context, RenderState c
{
m_usedSlots = 0;
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
ref_ptr<dp::GLGpuProgram> p = program;
for (auto const & texture : state.GetTextures())
@ -324,7 +324,7 @@ void ApplyState(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program, R
if (state.GetDrawAsLine())
{
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
ASSERT_GREATER_OR_EQUAL(state.GetLineWidth(), 0, ());
GLFunctions::glLineWidth(static_cast<uint32_t>(state.GetLineWidth()));

View file

@ -175,7 +175,7 @@ ref_ptr<Texture::ResourceInfo> StipplePenIndex::MapResource(StipplePenKey const
void StipplePenIndex::UploadResources(ref_ptr<dp::GraphicsContext> context, ref_ptr<Texture> texture)
{
ASSERT(texture->GetFormat() == dp::TextureFormat::Alpha, ());
ASSERT(texture->GetFormat() == dp::TextureFormat::Red, ());
TPendingNodes pendingNodes;
{
std::lock_guard<std::mutex> g(m_lock);

View file

@ -138,7 +138,7 @@ public:
StipplePenTexture(m2::PointU const & size, ref_ptr<HWTextureAllocator> allocator)
: m_index(size)
{
TBase::DynamicTextureParams params{size, TextureFormat::Alpha, TextureFilter::Nearest,
TBase::DynamicTextureParams params{size, TextureFormat::Red, TextureFilter::Nearest,
false /* m_usePixelBuffer */};
TBase::Init(allocator, make_ref(&m_index), params);
}

View file

@ -32,31 +32,8 @@ void SupportManager::Init(ref_ptr<GraphicsContext> context)
m_rendererVersion = context->GetRendererVersion();
LOG(LINFO, ("Renderer =", m_rendererName, "| Api =", context->GetApiVersion(), "| Version =", m_rendererVersion));
m_isSamsungGoogleNexus = (m_rendererName == "PowerVR SGX 540" &&
m_rendererVersion.find("GOOGLENEXUS.ED945322") != std::string::npos);
if (m_isSamsungGoogleNexus)
LOG(LINFO, ("Samsung Google Nexus detected."));
if (m_rendererName.find("Adreno") != std::string::npos)
{
std::array<std::string_view, 5> constexpr models = { "200", "203", "205", "220", "225" };
for (auto const & model : models)
{
if (m_rendererName.find(model) != std::string::npos)
{
LOG(LINFO, ("Adreno 200 device detected."));
m_isAdreno200 = true;
break;
}
}
}
m_isTegra = (m_rendererName.find("Tegra") != std::string::npos);
if (m_isTegra)
LOG(LINFO, ("NVidia Tegra device detected."));
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
m_maxLineWidth = static_cast<float>(std::max(1, GLFunctions::glGetMaxLineWidth()));
m_maxTextureSize = static_cast<uint32_t>(GLFunctions::glGetInteger(gl_const::GLMaxTextureSize));

View file

@ -26,9 +26,6 @@ public:
// reinitialization.
void Init(ref_ptr<GraphicsContext> context);
bool IsSamsungGoogleNexus() const { return m_isSamsungGoogleNexus; }
bool IsAdreno200Device() const { return m_isAdreno200; }
bool IsTegraDevice() const { return m_isTegra; }
bool IsAntialiasingEnabledByDefault() const { return m_isAntialiasingEnabledByDefault; }
float GetMaxLineWidth() const { return m_maxLineWidth; }
@ -50,9 +47,6 @@ private:
std::string m_rendererName;
std::string m_rendererVersion;
bool m_isSamsungGoogleNexus = false;
bool m_isAdreno200 = false;
bool m_isTegra = false;
bool m_isAntialiasingEnabledByDefault = false;
float m_maxLineWidth = 1;

View file

@ -183,7 +183,7 @@ bool TextureManager::UpdateDynamicTextures(ref_ptr<dp::GraphicsContext> context)
if (m_nothingToUpload.test_and_set())
{
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
// For some reasons OpenGL can not update textures immediately.
// Here we use some timeout to prevent rendering frozening.
@ -302,7 +302,7 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
m_maxTextureSize = std::min(kMaxTextureSize, dp::SupportManager::Instance().GetMaxTextureSize());
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
GLFunctions::glPixelStore(gl_const::GLUnpackAlignment, 1);
// Initialize symbols.
@ -323,16 +323,13 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
CreateArrowTexture(context, make_ref(m_textureAllocator), params.m_arrowTexturePath,
params.m_arrowTextureUseDefaultResourceFolder);
// SMAA is not supported on OpenGL ES2.
if (apiVersion != dp::ApiVersion::OpenGLES2)
{
m_smaaAreaTexture =
make_unique_dp<StaticTexture>(context, "smaa-area.png", StaticTexture::kDefaultResource,
dp::TextureFormat::RedGreen, make_ref(m_textureAllocator));
m_smaaSearchTexture =
make_unique_dp<StaticTexture>(context, "smaa-search.png", StaticTexture::kDefaultResource,
dp::TextureFormat::Alpha, make_ref(m_textureAllocator));
}
// SMAA.
m_smaaAreaTexture =
make_unique_dp<StaticTexture>(context, "smaa-area.png", StaticTexture::kDefaultResource,
dp::TextureFormat::RedGreen, make_ref(m_textureAllocator));
m_smaaSearchTexture =
make_unique_dp<StaticTexture>(context, "smaa-search.png", StaticTexture::kDefaultResource,
dp::TextureFormat::Red, make_ref(m_textureAllocator));
// Initialize patterns (reserved ./data/patterns.txt lines count).
std::set<PenPatternT> patterns;

View file

@ -9,7 +9,7 @@ namespace dp
enum class TextureFormat : uint8_t
{
RGBA8,
Alpha,
Red,
RedGreen,
DepthStencil,
Depth,
@ -21,7 +21,7 @@ inline std::string DebugPrint(TextureFormat tf)
switch (tf)
{
case TextureFormat::RGBA8: return "RGBA8";
case TextureFormat::Alpha: return "Alpha";
case TextureFormat::Red: return "Red";
case TextureFormat::RedGreen: return "RedGreen";
case TextureFormat::DepthStencil: return "DepthStencil";
case TextureFormat::Depth: return "Depth";
@ -50,7 +50,7 @@ inline uint8_t GetBytesPerPixel(TextureFormat format)
switch (format)
{
case TextureFormat::RGBA8: result = 4; break;
case TextureFormat::Alpha: result = 1; break;
case TextureFormat::Red: result = 1; break;
case TextureFormat::RedGreen: result = 2; break;
case TextureFormat::DepthStencil: result = 4; break;
case TextureFormat::Depth: result = 4; break;

View file

@ -56,9 +56,6 @@ public:
return false;
m_program = program;
// If OES_vertex_array_object not supported, than buffers will be bound on each render call.
if (!GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
return false;
if (m_VAO != 0)
GLFunctions::glDeleteVertexArray(m_VAO);
@ -68,19 +65,14 @@ public:
bool Bind() override
{
if (GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
{
ASSERT(m_VAO != 0, ("You need to call Build method before bind it and render."));
GLFunctions::glBindVertexArray(m_VAO);
return true;
}
return false;
ASSERT(m_VAO != 0, ("You need to call Build method before bind it and render."));
GLFunctions::glBindVertexArray(m_VAO);
return true;
}
void Unbind() override
{
if (GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
GLFunctions::glBindVertexArray(0);
GLFunctions::glBindVertexArray(0);
}
void BindBuffers(BuffersMap const & buffers) const override
@ -126,10 +118,6 @@ VertexArrayBuffer::VertexArrayBuffer(uint32_t indexBufferSize, uint32_t dataBuff
, m_batcherHash(batcherHash)
{
m_indexBuffer = make_unique_dp<IndexBuffer>(indexBufferSize);
// Adreno 200 GPUs aren't able to share OpenGL resources between 2 OGL-contexts correctly,
// so we have to create and destroy VBO on one context.
m_moveToGpuOnBuild = SupportManager::Instance().IsAdreno200Device();
}
VertexArrayBuffer::~VertexArrayBuffer()
@ -142,8 +130,7 @@ VertexArrayBuffer::~VertexArrayBuffer()
void VertexArrayBuffer::Preflush(ref_ptr<GraphicsContext> context)
{
if (!m_moveToGpuOnBuild)
PreflushImpl(context);
PreflushImpl(context);
}
void VertexArrayBuffer::PreflushImpl(ref_ptr<GraphicsContext> context)
@ -163,7 +150,7 @@ void VertexArrayBuffer::PreflushImpl(ref_ptr<GraphicsContext> context)
// Preflush can be called on BR, where impl is not initialized.
// For Metal rendering this code has no meaning.
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
GLFunctions::glBindBuffer(0, gl_const::GLElementArrayBuffer);
GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
@ -199,7 +186,7 @@ void VertexArrayBuffer::RenderRange(ref_ptr<GraphicsContext> context,
void VertexArrayBuffer::Build(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program)
{
if (m_moveToGpuOnBuild && !m_isPreflushed)
if (!m_isPreflushed)
PreflushImpl(context);
if (!HasBuffers())
@ -208,7 +195,7 @@ void VertexArrayBuffer::Build(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgr
if (!m_impl)
{
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
{
m_impl = make_unique_dp<GLVertexArrayBufferImpl>();
}

View file

@ -124,7 +124,6 @@ private:
drape_ptr<IndexBuffer> m_indexBuffer;
bool m_isPreflushed = false;
bool m_moveToGpuOnBuild = false;
bool m_isChanged = false;
BindingInfoArray m_bindingInfo;
uint8_t m_bindingInfoCount = 0;

View file

@ -158,7 +158,7 @@ VkFormat VulkanFormatUnpacker::Unpack(TextureFormat format)
switch (format)
{
case TextureFormat::RGBA8: return VK_FORMAT_R8G8B8A8_UNORM;
case TextureFormat::Alpha: return VK_FORMAT_R8_UNORM;
case TextureFormat::Red: return VK_FORMAT_R8_UNORM;
case TextureFormat::RedGreen: return VK_FORMAT_R8G8_UNORM;
#if defined(OMIM_OS_MAC)
case TextureFormat::DepthStencil: return VK_FORMAT_D32_SFLOAT_S8_UINT;

View file

@ -308,7 +308,7 @@ Arrow3d::Arrow3d(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManage
// Workaround for OpenGL: some devices require any texture to be set in the rendering pipeline.
auto const apiVersion = context->GetApiVersion();
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
if (apiVersion == dp::ApiVersion::OpenGLES3)
m_state.SetColorTexture(texMng->GetSymbolsTexture());
m_isValid = preloadedData.m_meshData.has_value();

View file

@ -1426,7 +1426,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram
RefreshBgColor();
uint32_t clearBits = dp::ClearBits::ColorBit | dp::ClearBits::DepthBit;
if (m_apiVersion == dp::ApiVersion::OpenGLES2 || m_apiVersion == dp::ApiVersion::OpenGLES3)
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
clearBits |= dp::ClearBits::StencilBit;
uint32_t storeBits = dp::ClearBits::ColorBit;
@ -1524,7 +1524,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram
if (IsValidCurrentZoom())
{
uint32_t clearBits = dp::ClearBits::DepthBit;
if (m_apiVersion == dp::ApiVersion::OpenGLES2 || m_apiVersion == dp::ApiVersion::OpenGLES3)
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
clearBits |= dp::ClearBits::StencilBit;
m_context->Clear(clearBits, dp::kClearBitsStoreAll);

View file

@ -369,7 +369,6 @@ void LayerCacher::CacheScaleFpsLabel(ref_ptr<dp::GraphicsContext> context, Posit
std::string apiLabel;
switch (apiVersion)
{
case dp::ApiVersion::OpenGLES2: apiLabel = "GL2"; break;
case dp::ApiVersion::OpenGLES3: apiLabel = "GL3"; break;
case dp::ApiVersion::Metal: apiLabel = "M"; break;
case dp::ApiVersion::Vulkan: apiLabel = "V"; break;

View file

@ -203,10 +203,6 @@ bool PostprocessRenderer::IsEnabled() const
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)
return;
auto const oldValue = m_effects;
auto const effectMask = static_cast<uint32_t>(effect);
m_effects = (m_effects & ~effectMask) | (enabled ? effectMask : 0);
@ -238,7 +234,7 @@ bool PostprocessRenderer::CanRenderAntialiasing() const
return false;
}
if (m_apiVersion == dp::ApiVersion::OpenGLES2 || m_apiVersion == dp::ApiVersion::OpenGLES3)
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
{
return m_staticTextures->m_smaaAreaTexture->GetID() != 0 &&
m_staticTextures->m_smaaSearchTexture->GetID() != 0;
@ -289,7 +285,7 @@ bool PostprocessRenderer::EndFrame(ref_ptr<dp::GraphicsContext> context,
ASSERT(m_staticTextures->m_smaaAreaTexture != nullptr, ());
ASSERT(m_staticTextures->m_smaaSearchTexture != nullptr, ());
if (m_apiVersion == dp::ApiVersion::OpenGLES2 || m_apiVersion == dp::ApiVersion::OpenGLES3)
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
{
ASSERT_GREATER(m_staticTextures->m_smaaAreaTexture->GetID(), 0, ());
ASSERT_GREATER(m_staticTextures->m_smaaSearchTexture->GetID(), 0, ());
@ -418,15 +414,12 @@ void PostprocessRenderer::UpdateFramebuffers(ref_ptr<dp::GraphicsContext> contex
ASSERT_NOT_EQUAL(height, 0, ());
CHECK_EQUAL(m_apiVersion, context->GetApiVersion(), ());
InitFramebuffer(context, m_mainFramebuffer, width, height, true /* depthEnabled */,
m_apiVersion != dp::ApiVersion::OpenGLES2 /* stencilEnabled */);
InitFramebuffer(context, m_mainFramebuffer, width, height, true /* depthEnabled */, true /* stencilEnabled */);
m_isMainFramebufferRendered = false;
m_isSmaaFramebufferRendered = false;
if (!m_isRouteFollowingActive && IsEffectEnabled(Effect::Antialiasing))
{
CHECK_NOT_EQUAL(m_apiVersion, dp::ApiVersion::OpenGLES2, ());
InitFramebuffer(context, m_edgesFramebuffer, dp::TextureFormat::RedGreen,
m_mainFramebuffer->GetDepthStencilRef(),
width, height);

View file

@ -81,7 +81,7 @@ double getExactDPI(double contentScaleFactor)
if (tempContext != nil)
apiVersion = dp::ApiVersion::OpenGLES3;
else
apiVersion = dp::ApiVersion::OpenGLES2;
CHECK(false, ("OpenGL ES3 is not supported"));
}
return apiVersion;

View file

@ -17,20 +17,14 @@ iosOGLContext::iosOGLContext(CAEAGLLayer * layer, dp::ApiVersion apiVersion,
, m_frameBufferId(0)
, m_presentAvailable(true)
{
EAGLRenderingAPI api;
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
api = kEAGLRenderingAPIOpenGLES3;
else
api = kEAGLRenderingAPIOpenGLES2;
if (contextToShareWith != NULL)
{
m_nativeContext = [[EAGLContext alloc] initWithAPI:api
m_nativeContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
sharegroup: contextToShareWith->m_nativeContext.sharegroup];
}
else
{
m_nativeContext = [[EAGLContext alloc] initWithAPI:api];
m_nativeContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
}
}

View file

@ -395,7 +395,7 @@ private:
public:
struct DrapeCreationParams
{
dp::ApiVersion m_apiVersion = dp::ApiVersion::OpenGLES2;
dp::ApiVersion m_apiVersion = dp::ApiVersion::OpenGLES3;
float m_visualScale = 1.0f;
int m_surfaceWidth = 0;
int m_surfaceHeight = 0;

View file

@ -107,7 +107,7 @@ void MapWidget::CreateEngine()
{
Framework::DrapeCreationParams p;
p.m_apiVersion = m_apiOpenGLES3 ? dp::ApiVersion::OpenGLES3 : dp::ApiVersion::OpenGLES2;
p.m_apiVersion = dp::ApiVersion::OpenGLES3;
p.m_surfaceWidth = m_screenshotMode ? width() : static_cast<int>(m_ratio * width());
p.m_surfaceHeight = m_screenshotMode ? height() : static_cast<int>(m_ratio * height());
@ -232,8 +232,6 @@ void MapWidget::Build()
{
std::string_view vertexSrc;
std::string_view fragmentSrc;
if (m_apiOpenGLES3)
{
#if defined(OMIM_OS_LINUX)
vertexSrc = ":common/shaders/gles_300.vsh.glsl";
fragmentSrc = ":common/shaders/gles_300.fsh.glsl";
@ -241,12 +239,6 @@ void MapWidget::Build()
vertexSrc = ":common/shaders/gl_150.vsh.glsl";
fragmentSrc = ":common/shaders/gl_150.fsh.glsl";
#endif
}
else
{
vertexSrc = ":common/shaders/gles_200.vsh.glsl";
fragmentSrc = ":common/shaders/gles_200.fsh.glsl";
}
m_program = std::make_unique<QOpenGLShaderProgram>(this);
m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, vertexSrc.data());
@ -348,8 +340,6 @@ void MapWidget::initializeGL()
if (!m_screenshotMode)
m_ratio = devicePixelRatio();
m_apiOpenGLES3 = true;
#if defined(OMIM_OS_LINUX)
{
QOpenGLFunctions * funcs = context()->functions();
@ -367,29 +357,14 @@ void MapWidget::initializeGL()
auto fmt = context()->format();
if (context()->format().version() < qMakePair(3, 0))
{
LOG(LINFO, ("OpenGL ES version is below 3.0, taking the OpenGL ES 2.0 path"));
m_apiOpenGLES3 = false;
constexpr const char* requiredExtensions[3] =
{ "GL_EXT_map_buffer_range", "GL_OES_mapbuffer", "GL_OES_vertex_array_object" };
for (auto & requiredExtension : requiredExtensions)
{
if (context()->hasExtension(QByteArray::fromStdString(requiredExtension)))
LOG(LDEBUG, ("Found OpenGL ES 2.0 extension: ", requiredExtension));
else
LOG(LCRITICAL, ("A required OpenGL ES 2.0 extension is missing:", requiredExtension));
}
fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
fmt.setVersion(2, 0);
CHECK(false, ("OpenGL ES2 is not supported"));
}
else
{
LOG(LINFO, ("OpenGL version is at least 3.0, enabling GLSL '#version 300 es'"));
m_apiOpenGLES3 = true;
fmt.setVersion(3, 0);
}
QSurfaceFormat::setDefaultFormat(fmt);
}
#endif

View file

@ -97,7 +97,6 @@ protected:
void wheelEvent(QWheelEvent * e) override;
Framework & m_framework;
bool m_apiOpenGLES3;
bool m_screenshotMode;
ScaleSlider * m_slider;
SliderState m_sliderState;

View file

@ -16,8 +16,6 @@
<file>spinner12.png</file>
<file>shaders/gl_150.fsh.glsl</file>
<file>shaders/gl_150.vsh.glsl</file>
<file>shaders/gles_200.fsh.glsl</file>
<file>shaders/gles_200.vsh.glsl</file>
<file>shaders/gles_300.fsh.glsl</file>
<file>shaders/gles_300.vsh.glsl</file>
</qresource>

View file

@ -1,15 +0,0 @@
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
uniform sampler2D u_sampler;
varying vec2 v_texCoord;
void main()
{
gl_FragColor = vec4(texture2D(u_sampler, v_texCoord).rgb, 1.0);
}

View file

@ -1,9 +0,0 @@
attribute vec4 a_position;
uniform vec2 u_samplerSize;
varying vec2 v_texCoord;
void main()
{
v_texCoord = vec2(a_position.z * u_samplerSize.x, a_position.w * u_samplerSize.y);
gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);
}

View file

@ -51,8 +51,7 @@ void RunTestLoop(char const * testName, testing::RenderFunction && fn, bool auto
app.exec();
}
void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES3,
testing::TestFunction const & fn)
void RunTestInOpenGLOffscreenEnvironment(char const * testName, testing::TestFunction const & fn)
{
std::vector<char> buf(strlen(testName) + 1);
strcpy(buf.data(), testName);
@ -71,16 +70,8 @@ void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES
fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
fmt.setSwapInterval(1);
fmt.setDepthBufferSize(16);
if (apiOpenGLES3)
{
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setVersion(3, 2);
}
else
{
fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
fmt.setVersion(2, 1);
}
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setVersion(3, 2);
auto surface = std::make_unique<QOffscreenSurface>();
surface->setFormat(fmt);
@ -92,7 +83,7 @@ void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES
context->makeCurrent(surface.get());
if (fn)
fn(apiOpenGLES3);
fn();
context->doneCurrent();
surface->destroy();

View file

@ -6,9 +6,9 @@ class QPaintDevice;
namespace testing
{
using RenderFunction = std::function<void (QPaintDevice *)>;
using TestFunction = std::function<void (bool apiOpenGLES3)>;
using TestFunction = std::function<void ()>;
} // namespace testing
extern void RunTestLoop(char const * testName, testing::RenderFunction && fn, bool autoExit = true);
extern void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES3, testing::TestFunction const & fn);
extern void RunTestInOpenGLOffscreenEnvironment(char const * testName, testing::TestFunction const & fn);

View file

@ -1,15 +1,26 @@
attribute vec3 a_position;
attribute vec2 a_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_colorTexCoords;
#ifdef ENABLE_VTF
uniform sampler2D u_colorTex;
varying LOW_P vec4 v_color;
layout (location = 0) out LOW_P vec4 v_color;
#else
varying vec2 v_colorTexCoords;
layout (location = 1) out vec2 v_colorTexCoords;
#endif
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
@ -17,7 +28,7 @@ void main()
vec4 pos = vec4(a_position, 1) * u_modelView * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
Review

Could you explain this change, please?

Previously, these parameters were automatically added by the reflection and now we need to add them manually. Why?

Could you explain this change, please? Previously, these parameters were automatically added by the reflection and now we need to add them manually. Why?
rokuz commented 2025-02-17 13:31:41 +00:00 (Migrated from github.com)
Review

I’m not sure I understood what reflection you meant. The reflection wasn’t changed as far as I see. This code is GLES3 shader syntax that can be directly consumed by Vulkan (or in GLES3 code with uniform buffers support).
I didn’t notice that any rendering logic was dramatically changed, it looks safe for me.
cc @renderexpert

I’m not sure I understood what reflection you meant. The reflection wasn’t changed as far as I see. This code is GLES3 shader syntax that can be directly consumed by Vulkan (or in GLES3 code with uniform buffers support). I didn’t notice that any rendering logic was dramatically changed, it looks safe for me. cc @renderexpert
renderexpert commented 2025-02-17 18:54:51 +00:00 (Migrated from github.com)
Review

@AndrewShkrob Nothing really changed in terms of reflection. You can find uniform in the old syntax that I removed above:

organicmaps/organicmaps#10256/files

So what I did here, I removed old syntax and used modern one for all shaders. It makes these shaders close to Metal ones, so it simplifies synchronous cross-language changes of shaders.

@AndrewShkrob Nothing really changed in terms of reflection. You can find uniform in the old syntax that I removed above: https://git.omaps.dev/organicmaps/organicmaps/pulls/10256/files#diff-4ad123dd71cdb25bc87eab7d6c71fb11dfb2a9a602afa5de2de9971c386e55d3L1-L7 So what I did here, I removed old syntax and used modern one for all shaders. It makes these shaders close to Metal ones, so it simplifies synchronous cross-language changes of shaders.
#ifdef ENABLE_VTF
v_color = texture2D(u_colorTex, a_colorTexCoords);
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoords = a_colorTexCoords;
#endif

View file

@ -1,34 +1,36 @@
attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec2 a_colorTexCoords;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 0) out vec2 v_colorTexCoords;
layout (location = 1) out float v_intensity;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
uniform float u_zScale;
varying vec2 v_colorTexCoords;
varying float v_intensity;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
const vec4 kNormalizedLightDir = vec4(0.3162, 0.0, 0.9486, 0.0);
void main()
{
vec4 pos = vec4(a_position, 1.0) * u_modelView;
vec4 normal = vec4(a_position + a_normal, 1.0) * u_modelView;
normal.xyw = (normal * u_projection).xyw;
normal.z = normal.z * u_zScale;
pos.xyw = (pos * u_projection).xyw;
pos.z = a_position.z * u_zScale;
vec4 normDir = normal - pos;
if (dot(normDir, normDir) != 0.0)
v_intensity = max(0.0, -dot(kNormalizedLightDir, normalize(normDir)));
else
v_intensity = 0.0;
gl_Position = u_pivotTransform * pos;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;

View file

@ -1,16 +1,26 @@
attribute vec3 a_position;
attribute vec2 a_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
uniform float u_zScale;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_colorTexCoords;
#ifdef ENABLE_VTF
uniform sampler2D u_colorTex;
varying LOW_P vec4 v_color;
layout (location = 0) out LOW_P vec4 v_color;
#else
varying vec2 v_colorTexCoords;
layout (location = 1) out vec2 v_colorTexCoords;
#endif
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
@ -23,9 +33,8 @@ void main()
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
#ifdef ENABLE_VTF
v_color = texture2D(u_colorTex, a_colorTexCoords);
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoords = a_colorTexCoords;
#endif

View file

@ -1,16 +1,19 @@
varying vec3 v_normal;
layout (location = 0) in vec3 v_normal;
#ifdef SAMSUNG_GOOGLE_NEXUS
uniform sampler2D u_colorTex;
#endif
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
const vec3 lightDir = vec3(0.316, 0.0, 0.948);
uniform vec4 u_color;
void main()
{
float phongDiffuse = max(0.0, -dot(lightDir, v_normal));
vec4 resColor = vec4((phongDiffuse * 0.5 + 0.5) * u_color.rgb, u_color.a);
gl_FragColor = samsungGoogleNexusWorkaround(resColor);
v_FragColor = vec4((phongDiffuse * 0.5 + 0.5) * u_color.rgb, u_color.a);
}

View file

@ -1,10 +1,15 @@
attribute vec3 a_pos;
attribute vec3 a_normal;
layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec3 a_normal;
uniform mat4 u_transform;
uniform mat4 u_normalTransform;
layout (location = 0) out vec3 v_normal;
varying vec3 v_normal;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{

View file

@ -1,13 +1,16 @@
varying float v_intensity;
layout (location = 0) in float v_intensity;
#ifdef SAMSUNG_GOOGLE_NEXUS
uniform sampler2D u_colorTex;
#endif
layout (location = 0) out vec4 v_FragColor;
uniform vec4 u_color;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{
vec4 resColor = vec4(u_color.rgb, u_color.a * smoothstep(0.7, 1.0, v_intensity));
gl_FragColor = samsungGoogleNexusWorkaround(resColor);
v_FragColor = vec4(u_color.rgb, u_color.a * smoothstep(0.7, 1.0, v_intensity));
}

View file

@ -1,13 +1,16 @@
varying float v_intensity;
layout (location = 0) in float v_intensity;
#ifdef SAMSUNG_GOOGLE_NEXUS
uniform sampler2D u_colorTex;
#endif
layout (location = 0) out vec4 v_FragColor;
uniform vec4 u_color;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{
vec4 resColor = vec4(u_color.rgb, u_color.a * v_intensity);
gl_FragColor = samsungGoogleNexusWorkaround(resColor);
v_FragColor = vec4(u_color.rgb, u_color.a * v_intensity);
}

View file

@ -1,9 +1,15 @@
attribute vec3 a_pos;
attribute vec2 a_texCoords;
layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec2 a_texCoords;
uniform mat4 u_transform;
layout (location = 0) out float v_intensity;
varying float v_intensity;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{

View file

@ -1,15 +1,23 @@
varying vec3 v_normal;
varying vec2 v_texCoords;
layout (location = 0) in vec3 v_normal;
layout (location = 1) in vec2 v_texCoords;
uniform sampler2D u_colorTex;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
layout (binding = 1) uniform sampler2D u_colorTex;
const vec3 lightDir = vec3(0.316, 0.0, 0.948);
uniform vec4 u_color;
void main()
{
float phongDiffuse = max(0.0, -dot(lightDir, v_normal));
vec4 color = texture2D(u_colorTex, v_texCoords) * u_color;
gl_FragColor = vec4((phongDiffuse * 0.5 + 0.5) * color.rgb, color.a);
vec4 color = texture(u_colorTex, v_texCoords) * u_color;
v_FragColor = vec4((phongDiffuse * 0.5 + 0.5) * color.rgb, color.a);
}

View file

@ -1,13 +1,17 @@
attribute vec3 a_pos;
attribute vec3 a_normal;
attribute vec2 a_texCoords;
layout (location = 0) in vec3 a_pos;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_texCoords;
uniform mat4 u_transform;
uniform mat4 u_normalTransform;
uniform vec2 u_texCoordFlipping;
layout (location = 0) out vec3 v_normal;
layout (location = 1) out vec2 v_texCoords;
varying vec3 v_normal;
varying vec2 v_texCoords;
layout (binding = 0) uniform UBO
{
mat4 u_transform;
mat4 u_normalTransform;
vec4 u_color;
vec2 u_texCoordFlipping;
};
void main()
{

View file

@ -1,12 +1,27 @@
uniform float u_opacity;
#ifdef ENABLE_VTF
varying LOW_P vec4 v_color;
layout (location = 0) in LOW_P vec4 v_color;
#else
uniform sampler2D u_colorTex;
varying vec2 v_colorTexCoords;
layout (location = 1) in vec2 v_colorTexCoords;
#endif
layout (location = 2) in vec3 v_radius;
varying vec3 v_radius;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
const float aaPixelsCount = 2.5;
@ -15,12 +30,11 @@ void main()
#ifdef ENABLE_VTF
LOW_P vec4 finalColor = v_color;
#else
LOW_P vec4 finalColor = texture2D(u_colorTex, v_colorTexCoords);
LOW_P vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
#endif
float smallRadius = v_radius.z - aaPixelsCount;
float stepValue = smoothstep(smallRadius * smallRadius, v_radius.z * v_radius.z,
v_radius.x * v_radius.x + v_radius.y * v_radius.y);
finalColor.a = finalColor.a * u_opacity * (1.0 - stepValue);
gl_FragColor = finalColor;
v_FragColor = finalColor;
}

View file

@ -1,19 +1,29 @@
attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec2 a_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
#ifdef ENABLE_VTF
uniform sampler2D u_colorTex;
varying LOW_P vec4 v_color;
layout (location = 0) out LOW_P vec4 v_color;
#else
varying vec2 v_colorTexCoords;
layout (location = 1) out vec2 v_colorTexCoords;
#endif
layout (location = 2) out vec3 v_radius;
varying vec3 v_radius;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
@ -21,7 +31,7 @@ void main()
vec4 pos = vec4(a_normal.xy, 0, 0) + p;
gl_Position = applyPivotTransform(pos * u_projection, u_pivotTransform, 0.0);
#ifdef ENABLE_VTF
v_color = texture2D(u_colorTex, a_colorTexCoords);
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoords = a_colorTexCoords;
#endif

View file

@ -1,11 +1,19 @@
#ifdef SAMSUNG_GOOGLE_NEXUS
uniform sampler2D u_colorTex;
#endif
layout (location = 0) in vec3 v_radius;
layout (location = 1) in vec4 v_color;
uniform float u_opacity;
layout (location = 0) out vec4 v_FragColor;
varying vec3 v_radius;
varying vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
const float kAntialiasingScalar = 0.9;
@ -13,10 +21,8 @@ void main()
{
float d = dot(v_radius.xy, v_radius.xy);
vec4 finalColor = v_color;
float aaRadius = v_radius.z * kAntialiasingScalar;
float stepValue = smoothstep(aaRadius * aaRadius, v_radius.z * v_radius.z, d);
finalColor.a = finalColor.a * u_opacity * (1.0 - stepValue);
gl_FragColor = samsungGoogleNexusWorkaround(finalColor);
v_FragColor = finalColor;
}

View file

@ -1,13 +1,21 @@
attribute vec3 a_normal;
attribute vec3 a_position;
attribute vec4 a_color;
layout (location = 0) in vec3 a_normal;
layout (location = 1) in vec3 a_position;
layout (location = 2) in vec4 a_color;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) out vec3 v_radius;
layout (location = 1) out vec4 v_color;
varying vec3 v_radius;
varying vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
@ -15,7 +23,6 @@ void main()
vec4 pos = vec4(a_position.xy, 0, 1) * u_modelView;
vec4 shiftedPos = vec4(radius.xy, 0, 0) + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
v_radius = radius;
v_color = a_color;
}

View file

@ -1,13 +1,25 @@
uniform float u_opacity;
varying vec4 v_normal;
layout (location = 0) in vec4 v_normal;
#ifdef ENABLE_VTF
varying LOW_P vec4 v_color;
layout (location = 1) in LOW_P vec4 v_color;
#else
uniform sampler2D u_colorTex;
varying vec2 v_colorTexCoords;
layout (location = 2) in vec2 v_colorTexCoords;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
const float aaPixelsCount = 2.5;
void main()
@ -15,18 +27,15 @@ void main()
#ifdef ENABLE_VTF
LOW_P vec4 color = v_color;
#else
LOW_P vec4 color = texture2D(u_colorTex, v_colorTexCoords);
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoords);
#endif
float r1 = (v_normal.z - aaPixelsCount) * (v_normal.z - aaPixelsCount);
float r2 = v_normal.x * v_normal.x + v_normal.y * v_normal.y;
float r3 = v_normal.z * v_normal.z;
float alpha = mix(step(r3, r2), smoothstep(r1, r3, r2), v_normal.w);
LOW_P vec4 finalColor = color;
finalColor.a = finalColor.a * u_opacity * (1.0 - alpha);
if (finalColor.a == 0.0)
discard;
gl_FragColor = finalColor;
v_FragColor = finalColor;
}

View file

@ -1,17 +1,28 @@
attribute vec3 a_position;
attribute vec4 a_normal;
attribute vec4 a_colorTexCoords;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec4 a_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
varying vec4 v_normal;
layout (location = 0) out vec4 v_normal;
#ifdef ENABLE_VTF
uniform sampler2D u_colorTex;
varying LOW_P vec4 v_color;
layout (location = 1) out LOW_P vec4 v_color;
#else
varying vec2 v_colorTexCoords;
layout (location = 2) out vec2 v_colorTexCoords;
#endif
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
@ -19,9 +30,8 @@ void main()
vec4 p = vec4(a_position, 1) * u_modelView;
vec4 pos = vec4(a_normal.xy + a_colorTexCoords.zw, 0, 0) + p;
gl_Position = applyPivotTransform(pos * u_projection, u_pivotTransform, 0.0);
#ifdef ENABLE_VTF
v_color = texture2D(u_colorTex, a_colorTexCoords.xy);
v_color = texture(u_colorTex, a_colorTexCoords.xy);
#else
v_colorTexCoords = a_colorTexCoords.xy;
#endif

View file

@ -1,17 +1,28 @@
attribute vec3 a_position;
attribute vec4 a_normal;
attribute vec4 a_colorTexCoords;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_normal;
layout (location = 2) in vec4 a_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
varying vec4 v_normal;
layout (location = 0) out vec4 v_normal;
#ifdef ENABLE_VTF
uniform sampler2D u_colorTex;
varying LOW_P vec4 v_color;
layout (location = 1) out LOW_P vec4 v_color;
#else
varying vec2 v_colorTexCoords;
layout (location = 2) out vec2 v_colorTexCoords;
#endif
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
@ -19,9 +30,8 @@ void main()
vec4 pivot = vec4(a_position.xyz, 1.0) * u_modelView;
vec4 offset = vec4(a_normal.xy + a_colorTexCoords.zw, 0.0, 0.0) * u_projection;
gl_Position = applyBillboardPivotTransform(pivot * u_projection, u_pivotTransform, 0.0, offset.xy);
#ifdef ENABLE_VTF
v_color = texture2D(u_colorTex, a_colorTexCoords.xy);
v_color = texture(u_colorTex, a_colorTexCoords.xy);
#else
v_colorTexCoords = a_colorTexCoords.xy;
#endif

View file

@ -1,28 +1,35 @@
varying vec2 v_colorTexCoord;
varying vec2 v_maskTexCoord;
//varying vec2 v_halfLength;
layout (location = 0) in vec2 v_colorTexCoord;
layout (location = 1) in vec2 v_maskTexCoord;
//layout (location = 2) in vec2 v_halfLength;
uniform sampler2D u_colorTex;
uniform sampler2D u_maskTex;
uniform float u_opacity;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
layout (binding = 2) uniform sampler2D u_maskTex;
//const float aaPixelsCount = 2.5;
void main()
{
vec4 color = texture2D(u_colorTex, v_colorTexCoord);
#ifdef GLES3
float mask = texture2D(u_maskTex, v_maskTexCoord).r;
#else
float mask = texture2D(u_maskTex, v_maskTexCoord).a;
#endif
vec4 color = texture(u_colorTex, v_colorTexCoord);
float mask = texture(u_maskTex, v_maskTexCoord).r;
color.a = color.a * mask * u_opacity;
// Disabled too agressive AA-like blurring of edges,
// see https://github.com/organicmaps/organicmaps/issues/6583.
//float currentW = abs(v_halfLength.x);
//float diff = v_halfLength.y - currentW;
//color.a *= mix(0.3, 1.0, clamp(diff / aaPixelsCount, 0.0, 1.0));
gl_FragColor = color;
v_FragColor = color;
}

View file

@ -1,15 +1,23 @@
attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec2 a_colorTexCoord;
attribute vec4 a_maskTexCoord;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_colorTexCoord;
layout (location = 3) in vec4 a_maskTexCoord;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) out vec2 v_colorTexCoord;
layout (location = 1) out vec2 v_maskTexCoord;
//layout (location = 2) out vec2 v_halfLength;
varying vec2 v_colorTexCoord;
varying vec2 v_maskTexCoord;
//varying vec2 v_halfLength;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
@ -21,12 +29,10 @@ void main()
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + normal,
u_modelView, halfWidth);
}
float uOffset = min(length(vec4(kShapeCoordScalar, 0, 0, 0) * u_modelView) * a_maskTexCoord.x, 1.0);
v_colorTexCoord = a_colorTexCoord;
v_maskTexCoord = vec2(a_maskTexCoord.y + uOffset * a_maskTexCoord.z, a_maskTexCoord.w);
//v_halfLength = vec2(sign(a_normal.z) * halfWidth, abs(a_normal.z));
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

View file

@ -1,10 +1,11 @@
uniform vec4 u_color;
layout (location = 0) out vec4 v_FragColor;
#ifdef SAMSUNG_GOOGLE_NEXUS
uniform sampler2D u_colorTex;
#endif
layout (binding = 0) uniform UBO
{
vec4 u_color;
};
void main()
{
gl_FragColor = samsungGoogleNexusWorkaround(u_color);
v_FragColor = u_color;
}

View file

@ -1,4 +1,4 @@
attribute vec2 a_position;
layout (location = 0) in vec2 a_position;
void main()
{

View file

@ -1,24 +1,35 @@
uniform float u_opacity;
#ifdef ENABLE_VTF
varying LOW_P vec4 v_color;
layout (location = 0) in LOW_P vec4 v_color;
#else
uniform sampler2D u_colorTex;
varying vec2 v_colorTexCoords;
layout (location = 1) in vec2 v_colorTexCoords;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
layout (location = 2) in vec2 v_maskTexCoords;
uniform sampler2D u_maskTex;
varying vec2 v_maskTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 2) uniform sampler2D u_maskTex;
void main()
{
#ifdef ENABLE_VTF
LOW_P vec4 color = v_color;
#else
LOW_P vec4 color = texture2D(u_colorTex, v_colorTexCoords);
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoords);
#endif
color *= texture2D(u_maskTex, v_maskTexCoords);
color *= texture(u_maskTex, v_maskTexCoords);
color.a *= u_opacity;
gl_FragColor = color;
v_FragColor = color;
}

View file

@ -1,25 +1,36 @@
attribute vec3 a_position;
attribute vec2 a_colorTexCoords;
attribute vec2 a_maskTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_colorTexCoords;
layout (location = 2) in vec2 a_maskTexCoords;
#ifdef ENABLE_VTF
uniform sampler2D u_colorTex;
varying LOW_P vec4 v_color;
layout (location = 0) out LOW_P vec4 v_color;
#else
varying vec2 v_colorTexCoords;
layout (location = 1) out vec2 v_colorTexCoords;
#endif
layout (location = 2) out vec2 v_maskTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
varying vec2 v_maskTexCoords;
void main()
{
vec4 pos = vec4(a_position, 1) * u_modelView * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
#ifdef ENABLE_VTF
v_color = texture2D(u_colorTex, a_colorTexCoords);
v_color = texture(u_colorTex, a_colorTexCoords);
#else
v_colorTexCoords = a_colorTexCoords;
#endif

12
shaders/GL/imgui.fsh.glsl Normal file
View file

@ -0,0 +1,12 @@
layout (location = 0) in vec2 v_texCoords;
layout (location = 1) in vec4 v_color;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
LOW_P vec4 color = texture(u_colorTex, v_texCoords);
v_FragColor = color * v_color;
}

22
shaders/GL/imgui.vsh.glsl Normal file
View file

@ -0,0 +1,22 @@
layout (location = 0) in vec2 a_position;
layout (location = 1) in vec2 a_texCoords;
layout (location = 2) in vec4 a_color;
layout (location = 0) out vec2 v_texCoords;
layout (location = 1) out vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_projection;
};
void main()
{
v_texCoords = a_texCoords;
v_color = a_color;
gl_Position = vec4(a_position, 0, 1) * u_projection;
#ifdef VULKAN
gl_Position.y = -gl_Position.y;
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
#endif
}

View file

@ -1,12 +1,24 @@
uniform float u_opacity;
#ifdef ENABLE_VTF
varying LOW_P vec4 v_color;
layout (location = 0) in LOW_P vec4 v_color;
#else
uniform sampler2D u_colorTex;
varying vec2 v_colorTexCoord;
layout (location = 1) in vec2 v_colorTexCoord;
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
//layout (location = 2) in vec2 v_halfLength;
//varying vec2 v_halfLength;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
//const float aaPixelsCount = 2.5;
@ -15,15 +27,13 @@ void main()
#ifdef ENABLE_VTF
LOW_P vec4 color = v_color;
#else
LOW_P vec4 color = texture2D(u_colorTex, v_colorTexCoord);
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoord);
#endif
color.a *= u_opacity;
// Disabled too agressive AA-like blurring of edges,
// see https://github.com/organicmaps/organicmaps/issues/6583.
//float currentW = abs(v_halfLength.x);
//float diff = v_halfLength.y - currentW;
//color.a *= mix(0.3, 1.0, clamp(diff / aaPixelsCount, 0.0, 1.0));
gl_FragColor = color;
v_FragColor = color;
}

View file

@ -1,19 +1,30 @@
attribute vec3 a_position;
attribute vec3 a_normal;
attribute vec2 a_colorTexCoord;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec3 a_normal;
layout (location = 2) in vec2 a_colorTexCoord;
#ifdef ENABLE_VTF
uniform sampler2D u_colorTex;
varying LOW_P vec4 v_color;
layout (location = 0) out LOW_P vec4 v_color;
#else
varying vec2 v_colorTexCoord;
layout (location = 1) out vec2 v_colorTexCoord;
#endif
//varying vec2 v_halfLength;
//layout (location = 2) out vec2 v_halfLength;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
#ifdef ENABLE_VTF
layout (binding = 1) uniform sampler2D u_colorTex;
#endif
void main()
{
@ -25,9 +36,8 @@ void main()
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + normal,
u_modelView, halfWidth);
}
#ifdef ENABLE_VTF
v_color = texture2D(u_colorTex, a_colorTexCoord);
v_color = texture(u_colorTex, a_colorTexCoord);
#else
v_colorTexCoord = a_colorTexCoord;
#endif

View file

@ -1,13 +1,26 @@
uniform sampler2D u_colorTex;
uniform sampler2D u_maskTex;
uniform float u_opacity;
layout (location = 0) in vec2 v_colorTexCoords;
layout (location = 1) in vec2 v_maskTexCoords;
varying vec2 v_colorTexCoords;
varying vec2 v_maskTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
layout (binding = 1) uniform sampler2D u_colorTex;
layout (binding = 2) uniform sampler2D u_maskTex;
void main()
{
vec4 finalColor = texture2D(u_colorTex, v_colorTexCoords) * texture2D(u_maskTex, v_maskTexCoords);
vec4 finalColor = texture(u_colorTex, v_colorTexCoords) * texture(u_maskTex, v_maskTexCoords);
finalColor.a *= u_opacity;
gl_FragColor = finalColor;
v_FragColor = finalColor;
}

View file

@ -1,14 +1,22 @@
attribute vec4 a_position;
attribute vec2 a_normal;
attribute vec2 a_colorTexCoords;
attribute vec2 a_maskTexCoords;
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 3) in vec2 a_maskTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) out vec2 v_colorTexCoords;
layout (location = 1) out vec2 v_maskTexCoords;
varying vec2 v_colorTexCoords;
varying vec2 v_maskTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{

View file

@ -1,15 +1,22 @@
attribute vec4 a_position;
attribute vec2 a_normal;
attribute vec2 a_colorTexCoords;
attribute vec2 a_maskTexCoords;
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
layout (location = 3) in vec2 a_maskTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
uniform float u_zScale;
layout (location = 0) out vec2 v_colorTexCoords;
layout (location = 1) out vec2 v_maskTexCoords;
varying vec2 v_colorTexCoords;
varying vec2 v_maskTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{

View file

@ -1,30 +1,33 @@
attribute vec2 a_normal;
attribute vec2 a_colorTexCoords;
layout (location = 0) in vec2 a_normal;
layout (location = 1) in vec2 a_colorTexCoords;
uniform vec3 u_position;
uniform float u_azimut;
layout (location = 0) out vec2 v_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
varying vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_position;
vec2 u_lineParams;
float u_accuracy;
float u_zScale;
float u_opacity;
float u_azimut;
};
void main()
{
float sinV = sin(u_azimut);
float cosV = cos(u_azimut);
mat4 rotation;
rotation[0] = vec4(cosV, sinV, 0.0, 0.0);
rotation[1] = vec4(-sinV, cosV, 0.0, 0.0);
rotation[2] = vec4(0.0, 0.0, 1.0, 0.0);
rotation[3] = vec4(0.0, 0.0, 0.0, 1.0);
vec4 pos = vec4(u_position, 1.0) * u_modelView;
vec4 pos = vec4(u_position.xyz, 1.0) * u_modelView;
vec4 normal = vec4(a_normal, 0, 0);
vec4 shiftedPos = normal * rotation + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -1,23 +1,29 @@
attribute vec4 a_position;
attribute vec2 a_normal;
attribute vec2 a_colorTexCoords;
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) out vec2 v_colorTexCoords;
varying vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec2 u_contrastGamma;
float u_opacity;
float u_zScale;
float u_interpolation;
float u_isOutlinePass;
};
void main()
{
vec4 pos = vec4(a_position.xyz, 1) * u_modelView;
float normalLen = length(a_normal);
vec4 n = vec4(a_position.xy + a_normal * kShapeCoordScalar, 0.0, 0.0) * u_modelView;
vec4 norm = vec4(0.0, 0.0, 0.0, 0.0);
if (dot(n, n) != 0.0)
norm = normalize(n) * normalLen;
vec4 shiftedPos = norm + pos;
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
v_colorTexCoords = a_colorTexCoords;

View file

@ -1,15 +1,20 @@
attribute vec2 a_normal;
attribute vec2 a_colorTexCoords;
layout (location = 0) in vec2 a_normal;
layout (location = 1) in vec2 a_colorTexCoords;
uniform vec3 u_position;
uniform float u_accuracy;
layout (location = 0) out vec2 v_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
uniform float u_zScale;
varying vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_position;
vec2 u_lineParams;
float u_accuracy;
float u_zScale;
float u_opacity;
float u_azimut;
};
void main()
{
@ -17,6 +22,5 @@ void main()
vec4 normal = vec4(a_normal * u_accuracy, 0.0, 0.0);
position = (position + normal) * u_projection;
gl_Position = applyPivotTransform(position, u_pivotTransform, u_position.z * u_zScale);
v_colorTexCoords = a_colorTexCoords;
}

View file

@ -1,25 +1,30 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented on OpenGL ES 2.0 without discarding
// fragments from depth buffer.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
varying vec3 v_length;
varying vec4 v_color;
layout (location = 0) in vec3 v_length;
layout (location = 1) in vec4 v_color;
#ifdef SAMSUNG_GOOGLE_NEXUS
uniform sampler2D u_colorTex;
#endif
layout (location = 0) out vec4 v_FragColor;
uniform vec4 u_color;
uniform vec4 u_outlineColor;
uniform vec4 u_routeParams;
uniform vec4 u_maskColor;
uniform vec2 u_fakeBorders;
uniform vec4 u_fakeColor;
uniform vec4 u_fakeOutlineColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
const float kAntialiasingThreshold = 0.92;
const float kOutlineThreshold1 = 0.81;
const float kOutlineThreshold2 = 0.71;
@ -27,18 +32,16 @@ void main()
{
if (v_length.x < v_length.z)
discard;
vec2 coefs = step(v_length.xx, u_fakeBorders);
coefs.y = 1.0 - coefs.y;
vec4 mainColor = mix(u_color, u_fakeColor, coefs.x);
mainColor = mix(mainColor, u_fakeColor, coefs.y);
vec4 mainOutlineColor = mix(u_outlineColor, u_fakeOutlineColor, coefs.x);
mainOutlineColor = mix(mainOutlineColor, u_fakeOutlineColor, coefs.y);
vec4 color = mix(mix(mainColor, vec4(v_color.rgb, 1.0), v_color.a), mainColor, step(u_routeParams.w, 0.0));
color = mix(color, mainOutlineColor, step(kOutlineThreshold1, abs(v_length.y)));
color = mix(color, mainOutlineColor, smoothstep(kOutlineThreshold2, kOutlineThreshold1, abs(v_length.y)));
color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_length.y)));
color = vec4(mix(color.rgb, u_maskColor.rgb, u_maskColor.a), color.a);
gl_FragColor = samsungGoogleNexusWorkaround(color);
v_FragColor = color;
}

View file

@ -1,16 +1,28 @@
attribute vec3 a_position;
attribute vec2 a_normal;
attribute vec3 a_length;
attribute vec4 a_color;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec3 a_length;
layout (location = 3) in vec4 a_color;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) out vec3 v_length;
layout (location = 1) out vec4 v_color;
uniform vec4 u_routeParams;
varying vec3 v_length;
varying vec4 v_color;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
void main()
{
@ -24,7 +36,6 @@ void main()
if (u_routeParams.y != 0.0)
len = vec2(a_length.x + a_length.y * u_routeParams.y, a_length.z);
}
v_length = vec3(len, u_routeParams.z);
v_color = a_color;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;

View file

@ -1,19 +1,36 @@
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
// Unfortunately some CG algorithms cannot be implemented on OpenGL ES 2.0 without discarding
// fragments from depth buffer.
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
uniform sampler2D u_colorTex;
uniform float u_opacity;
uniform vec4 u_maskColor;
layout (location = 0) in vec2 v_colorTexCoords;
varying vec2 v_colorTexCoords;
layout (location = 0) out vec4 v_FragColor;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
layout (binding = 1) uniform sampler2D u_colorTex;
void main()
{
vec4 finalColor = texture2D(u_colorTex, v_colorTexCoords);
vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
finalColor.a *= u_opacity;
if (finalColor.a < 0.01)
discard;
finalColor = vec4(mix(finalColor.rgb, u_maskColor.rgb, u_maskColor.a), finalColor.a);
gl_FragColor = finalColor;
v_FragColor = finalColor;
}

View file

@ -1,14 +1,26 @@
attribute vec4 a_position;
attribute vec2 a_normal;
attribute vec2 a_colorTexCoords;
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_normal;
layout (location = 2) in vec2 a_colorTexCoords;
uniform mat4 u_modelView;
uniform mat4 u_projection;
uniform mat4 u_pivotTransform;
layout (location = 0) out vec2 v_colorTexCoords;
uniform float u_arrowHalfWidth;
varying vec2 v_colorTexCoords;
layout (binding = 0) uniform UBO
{
mat4 u_modelView;
mat4 u_projection;
mat4 u_pivotTransform;
vec4 u_routeParams;
vec4 u_color;
vec4 u_maskColor;
vec4 u_outlineColor;
vec4 u_fakeColor;
vec4 u_fakeOutlineColor;
vec2 u_fakeBorders;
vec2 u_pattern;
vec2 u_angleCosSin;
float u_arrowHalfWidth;
float u_opacity;
};
void main()
{
@ -19,9 +31,7 @@ void main()
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
u_modelView, length(norm));
}
v_colorTexCoords = a_colorTexCoords;
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
}

Some files were not shown because too many files have changed in this diff Show more