Skip to content

Commit

Permalink
Implement Android surface pre-rotation for Vulkan (#2955)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrian-cojocaru authored Nov 20, 2024
1 parent 5642b1f commit d282b3b
Show file tree
Hide file tree
Showing 24 changed files with 195 additions and 55 deletions.
3 changes: 3 additions & 0 deletions include/mbgl/shaders/layer_ubo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ static_assert(sizeof(GlobalPaintParamsUBO) == 3 * 16);

enum {
idGlobalPaintParamsUBO,
#if MLN_RENDER_BACKEND_VULKAN
PlatformParamsUBO,
#endif
globalUBOCount
};

Expand Down
4 changes: 2 additions & 2 deletions include/mbgl/shaders/vulkan/background.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ layout(set = DRAWABLE_UBO_SET_INDEX, binding = 0) uniform BackgroundDrawableUBO
void main() {
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
}
)";

Expand Down Expand Up @@ -101,7 +101,7 @@ void main() {
in_position);
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
}
)";

Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/shaders/vulkan/circle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void main() {
gl_Position.xy += scaled_extrude * (radius + stroke_width) * factor;
}
gl_Position.y *= -1.0;
applySurfaceTransform();
// This is a minimum blur distance that serves as a faux-antialiasing for
// the circle. since blur is a ratio of the circle's size and the intent is
Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/shaders/vulkan/clipping_mask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace mbgl {
namespace shaders {

struct ClipUBO {
matf4 matrix;
mat4 matrix;
std::uint32_t stencil_ref;
};

Expand Down
4 changes: 2 additions & 2 deletions include/mbgl/shaders/vulkan/collision.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void main() {
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.xy += (in_extrude + in_shift) * drawable.extrude_scale * gl_Position.w * collision_perspective_ratio;
gl_Position.y *= -1.0;
applySurfaceTransform();
frag_placed = in_placed.x;
frag_notUsed = in_placed.y;
Expand Down Expand Up @@ -128,7 +128,7 @@ void main() {
float padding_factor = 1.2; // Pad the vertices slightly to make room for anti-alias blur
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.xy += in_extrude * drawable.extrude_scale * padding_factor * gl_Position.w * collision_perspective_ratio;
gl_Position.y *= -1.0;
applySurfaceTransform();
frag_placed = in_placed.x;
frag_notUsed = in_placed.y;
Expand Down
18 changes: 16 additions & 2 deletions include/mbgl/shaders/vulkan/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ layout(set = GLOBAL_SET_INDEX, binding = 0) uniform GlobalPaintParamsUBO {
float pad1;
} global;
#ifdef USE_SURFACE_TRANSFORM
layout(set = GLOBAL_SET_INDEX, binding = 1) uniform PlatformParamsUBO {
mat2 rotation;
} platform;
#endif
void applySurfaceTransform() {
#ifdef USE_SURFACE_TRANSFORM
gl_Position.xy = platform.rotation * gl_Position.xy;
#endif
gl_Position.y *= -1.0;
}
)";

static constexpr auto fragment = R"(
Expand Down Expand Up @@ -130,7 +144,7 @@ layout(set = DRAWABLE_UBO_SET_INDEX, binding = 0) uniform CommonUBO {
void main() {
gl_Position = ubo.matrix * vec4(in_position, 0, 1);
gl_Position.y *= -1.0;
applySurfaceTransform();
}
)";

Expand Down Expand Up @@ -170,7 +184,7 @@ layout(location = 0) out vec2 frag_uv;
void main() {
gl_Position = ubo.matrix * vec4(in_position, 0, 1);
gl_Position.y *= -1.0;
applySurfaceTransform();
frag_uv = in_texcoord;
}
Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/shaders/vulkan/debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ layout(location = 0) out vec2 frag_uv;
void main() {
gl_Position = debug.matrix * vec4(in_position * debug.overlay_scale, 0, 1);
gl_Position.y *= -1.0;
applySurfaceTransform();
// This vertex shader expects a EXTENT x EXTENT quad,
// The UV co-ordinates for the overlay texture can be calculated using that knowledge
Expand Down
20 changes: 9 additions & 11 deletions include/mbgl/shaders/vulkan/fill.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void main() {
#endif
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
}
)";

Expand Down Expand Up @@ -150,7 +150,7 @@ void main() {
#endif
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
frag_position = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * global.world_size;
}
Expand Down Expand Up @@ -309,7 +309,7 @@ void main() {
frag_pos_b = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, toScale * display_size_b, tileZoomRatio, in_position),
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
}
)";

Expand Down Expand Up @@ -502,14 +502,12 @@ void main() {
const vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
const vec2 position2 = in_position.xy;
vec4 position = drawable.matrix * vec4(in_position, 0.0, 1.0);
position.y *= -1.0;
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
applySurfaceTransform();
frag_pos_a = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, fromScale * display_size_a, tileZoomRatio, position2),
frag_pos_b = get_pattern_pos(drawable.pixel_coord_upper, drawable.pixel_coord_lower, toScale * display_size_b, tileZoomRatio, position2),
frag_pos = (position.xy / position.w + 1.0) / 2.0 * global.world_size;
gl_Position = position;
frag_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * global.world_size;
}
)";

Expand Down Expand Up @@ -655,7 +653,7 @@ void main() {
vec4 projected_extrude = drawable.matrix * vec4(dist / drawable.ratio, 0.0, 0.0);
gl_Position = drawable.matrix * vec4(pos, 0.0, 1.0) + projected_extrude;
gl_Position.y *= -1.0;
applySurfaceTransform();
// calculate how much the perspective view squishes or stretches the extrude
float extrude_length_without_perspective = length(dist);
Expand Down Expand Up @@ -788,7 +786,7 @@ void main() {
const float z = t != 0.0 ? height : base;
gl_Position = drawable.matrix * vec4(in_position, z, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
#if defined(OVERDRAW_INSPECTOR)
frag_color = vec4(1.0);
Expand Down Expand Up @@ -944,7 +942,7 @@ void main() {
const float z = t != 0.0 ? height : base;
gl_Position = drawable.matrix * vec4(in_position, z, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
#if defined(OVERDRAW_INSPECTOR)
frag_color = vec4(1.0);
Expand Down
4 changes: 2 additions & 2 deletions include/mbgl/shaders/vulkan/heatmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void main() {
// multiply a_pos by 0.5, since we had it * 2 in order to sneak
// in extrusion data
gl_Position = drawable.matrix * vec4(floor(in_position * 0.5) + scaled_extrude, 0, 1);
gl_Position.y *= -1.0;
applySurfaceTransform();
frag_weight = weight;
frag_extrude = extrude;
Expand Down Expand Up @@ -162,7 +162,7 @@ layout(location = 0) out vec2 frag_position;
void main() {
gl_Position = props.matrix * vec4(in_position * global.world_size, 0, 1);
gl_Position.y *= -1.0;
applySurfaceTransform();
frag_position = in_position;
}
Expand Down
4 changes: 2 additions & 2 deletions include/mbgl/shaders/vulkan/hillshade.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ layout(location = 0) out vec2 frag_position;
void main() {
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
const vec2 epsilon = vec2(1.0) / drawable.dimension;
const float scale = (drawable.dimension.x - 2.0) / drawable.dimension.x;
Expand Down Expand Up @@ -149,7 +149,7 @@ layout(location = 0) out vec2 frag_position;
void main() {
gl_Position = drawable.matrix * vec4(in_position, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
frag_position = vec2(in_texture_position) / 8192.0;
frag_position.y = 1.0 - frag_position.y; // TODO check this. prepare should ignore the flip
Expand Down
8 changes: 4 additions & 4 deletions include/mbgl/shaders/vulkan/line.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void main() {
vec4 projected_extrude = drawable.matrix * vec4(dist / drawable.ratio, 0.0, 0.0);
gl_Position = drawable.matrix * vec4(pos + offset2 / drawable.ratio, 0.0, 1.0) + projected_extrude;
gl_Position.y *= -1.0;
applySurfaceTransform();
// calculate how much the perspective view squishes or stretches the extrude
float extrude_length_without_perspective = length(dist);
Expand Down Expand Up @@ -376,7 +376,7 @@ void main() {
vec4 projected_extrude = drawable.matrix * vec4(dist / drawable.ratio, 0.0, 0.0);
gl_Position = drawable.matrix * vec4(pos + offset2 / drawable.ratio, 0.0, 1.0) + projected_extrude;
gl_Position.y *= -1.0;
applySurfaceTransform();
// calculate how much the perspective view squishes or stretches the extrude
float extrude_length_without_perspective = length(dist);
Expand Down Expand Up @@ -626,7 +626,7 @@ void main() {
vec4 projected_extrude = drawable.matrix * vec4(dist / drawable.ratio, 0.0, 0.0);
gl_Position = drawable.matrix * vec4(pos + offset2 / drawable.ratio, 0.0, 1.0) + projected_extrude;
gl_Position.y *= -1.0;
applySurfaceTransform();
// calculate how much the perspective view squishes or stretches the extrude
float extrude_length_without_perspective = length(dist);
Expand Down Expand Up @@ -941,7 +941,7 @@ void main() {
vec4 projected_extrude = drawable.matrix * vec4(dist / drawable.ratio, 0.0, 0.0);
gl_Position = drawable.matrix * vec4(pos + offset2 / drawable.ratio, 0.0, 1.0) + projected_extrude;
gl_Position.y *= -1.0;
applySurfaceTransform();
// calculate how much the perspective view squishes or stretches the extrude
float extrude_length_without_perspective = length(dist);
Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/shaders/vulkan/raster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ layout(location = 1) out vec2 frag_position1;
void main() {
gl_Position = drawable.matrix * vec4(in_position, 0, 1);
gl_Position.y *= -1.0;
applySurfaceTransform();
// We are using Int16 for texture position coordinates to give us enough precision for
// fractional coordinates. We use 8192 to scale the texture coordinates in the buffer
Expand Down
10 changes: 5 additions & 5 deletions include/mbgl/shaders/vulkan/symbol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void main() {
const vec2 pos0 = projected_pos.xy / projected_pos.w;
const vec2 posOffset = a_offset * max(a_minFontScale, fontScale) / 32.0 + a_pxoffset / 16.0;
gl_Position = drawable.coord_matrix * vec4(pos0 + rotation_matrix * posOffset, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
const vec2 raw_fade_opacity = unpack_opacity(in_fade_opacity);
const float fade_change = raw_fade_opacity[1] > 0.5 ? global.symbol_fade_change : -global.symbol_fade_change;
Expand Down Expand Up @@ -339,8 +339,8 @@ void main() {
const vec2 pos_rot = a_offset / 32.0 * fontScale + a_pxoffset;
const vec2 pos0 = projected_pos.xy / projected_pos.w + rotation_matrix * pos_rot;
gl_Position = drawable.coord_matrix * vec4(pos0, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
const vec2 raw_fade_opacity = unpack_opacity(in_fade_opacity);
const float fade_change = raw_fade_opacity[1] > 0.5 ? global.symbol_fade_change : -global.symbol_fade_change;
Expand Down Expand Up @@ -640,7 +640,7 @@ void main() {
const vec2 pos_rot = a_offset / 32.0 * fontScale;
const vec2 pos0 = projected_pos.xy / projected_pos.w + rotation_matrix * pos_rot;
gl_Position = drawable.coord_matrix * vec4(pos0, 0.0, 1.0);
gl_Position.y *= -1.0;
applySurfaceTransform();
const vec2 raw_fade_opacity = unpack_opacity(in_fade_opacity);
const float fade_change = raw_fade_opacity[1] > 0.5 ? global.symbol_fade_change : -global.symbol_fade_change;
Expand Down Expand Up @@ -862,7 +862,7 @@ void main() {
}
gl_Position = position;
gl_Position.y *= -1.0;
applySurfaceTransform();
frag_tex = in_tex;
}
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/vulkan/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class Context final : public gfx::Context {
uint8_t frameResourceIndex = 0;
std::vector<FrameResources> frameResources;
bool surfaceUpdateRequested{false};
int32_t currentFrameCount{0};

struct {
gfx::ShaderProgramBasePtr shader;
Expand Down
22 changes: 22 additions & 0 deletions include/mbgl/vulkan/renderable_resource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,22 @@ class SurfaceRenderableResource : public RenderableResource {
void setAcquiredImageIndex(uint32_t index) { acquiredImageIndex = index; };
const vk::Image getAcquiredImage() const;

bool hasSurfaceTransformSupport() const;
bool didSurfaceTransformUpdate() const;

// rotation needed to align framebuffer contents with device surface
float getRotation();

void setSurfaceTransformPollingInterval(int32_t value) { surfaceTransformPollingInterval = value; }
int32_t getSurfaceTransformPollingInterval() const { return surfaceTransformPollingInterval; }

void init(uint32_t w, uint32_t h);
void recreateSwapchain();

protected:
vk::UniqueSurfaceKHR surface;
vk::UniqueSwapchainKHR swapchain;
vk::SurfaceCapabilitiesKHR capabilities;

uint32_t acquiredImageIndex{0};

Expand All @@ -77,6 +87,18 @@ class SurfaceRenderableResource : public RenderableResource {

UniqueImageAllocation depthAllocation;
vk::Format depthFormat{vk::Format::eUndefined};

int32_t surfaceTransformPollingInterval{-1};
};

class Renderable : public gfx::Renderable {
protected:
Renderable(const Size size_, std::unique_ptr<gfx::RenderableResource> resource_)
: gfx::Renderable(size_, std::move(resource_)) {}
virtual ~Renderable() override = default;

public:
void setSize(const Size& size_) { size = size_; }
};

} // namespace vulkan
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ class AndroidVulkanRenderableResource final : public mbgl::vulkan::SurfaceRender
auto& backendImpl = static_cast<AndroidVulkanRendererBackend&>(backend);
const vk::AndroidSurfaceCreateInfoKHR createInfo({}, backendImpl.getWindow());
surface = backendImpl.getInstance()->createAndroidSurfaceKHRUnique(createInfo);

const int apiLevel = android_get_device_api_level();
if (apiLevel < __ANDROID_API_Q__) {
setSurfaceTransformPollingInterval(30);
}
}

void bind() override {}
Expand All @@ -42,7 +47,7 @@ class AndroidVulkanRenderableResource final : public mbgl::vulkan::SurfaceRender

AndroidVulkanRendererBackend::AndroidVulkanRendererBackend(ANativeWindow* window_)
: vulkan::RendererBackend(gfx::ContextMode::Unique),
mbgl::gfx::Renderable({64, 64}, std::make_unique<AndroidVulkanRenderableResource>(*this)),
vulkan::Renderable({64, 64}, std::make_unique<AndroidVulkanRenderableResource>(*this)),
window(window_) {
init();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <mbgl/gfx/renderable.hpp>
#include <mbgl/vulkan/renderable_resource.hpp>
#include <mbgl/vulkan/renderer_backend.hpp>
#include "android_renderer_backend.hpp"
#include <android/native_window.h>
Expand All @@ -10,7 +10,7 @@ namespace android {

class AndroidVulkanRendererBackend : public AndroidRendererBackend,
public vulkan::RendererBackend,
public mbgl::gfx::Renderable {
public vulkan::Renderable {
public:
AndroidVulkanRendererBackend(ANativeWindow*);
~AndroidVulkanRendererBackend() override;
Expand Down
2 changes: 1 addition & 1 deletion platform/glfw/glfw_vulkan_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class GLFWVulkanRenderableResource final : public mbgl::vulkan::SurfaceRenderabl

GLFWVulkanBackend::GLFWVulkanBackend(GLFWwindow* window_, const bool)
: mbgl::vulkan::RendererBackend(mbgl::gfx::ContextMode::Unique),
mbgl::gfx::Renderable(
mbgl::vulkan::Renderable(
[window_] {
int fbWidth;
int fbHeight;
Expand Down
Loading

0 comments on commit d282b3b

Please sign in to comment.