Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified app/src/legacy/jniLibs/arm64-v8a/libvulkan_renderer.so
Binary file not shown.
19 changes: 16 additions & 3 deletions app/src/main/cpp/winlator/VulkanRendererContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,9 @@ void VulkanRendererContext::recordCmdBuf(VkCommandBuffer cb, uint32_t imgIdx,
pc.gamma = activeGamma;
pc.outW = std::max(1.0f, (float)d.w * sx / cw * (float)swapchainExt.width);
pc.outH = std::max(1.0f, (float)d.h * sy / ch * (float)swapchainExt.height);
pc.barrelStrength = activeBarrelStrength;
pc.barrelHeight = activeBarrelHeight;
pc.barrelCylindricalRatio = activeBarrelCylindricalRatio;
vk_.CmdPushConstants(cb, pipeLayout, VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(pc), &pc);
vk_.CmdDraw(cb, 4, 1, 0, 0);
}
Expand All @@ -797,6 +800,9 @@ void VulkanRendererContext::recordCmdBuf(VkCommandBuffer cb, uint32_t imgIdx,
cpc.gamma = 1.0f;
cpc.outW = (float)std::max(1, (int)curW);
cpc.outH = (float)std::max(1, (int)curH);
cpc.barrelStrength = 0.0f;
cpc.barrelHeight = 0.176327f;
cpc.barrelCylindricalRatio = 0.5f;
vk_.CmdPushConstants(cb, pipeLayout, VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(cpc), &cpc);
vk_.CmdDraw(cb, 4, 1, 0, 0);
}
Expand Down Expand Up @@ -1245,15 +1251,22 @@ void VulkanRendererContext::setSwapRB(bool enabled) {

}

void VulkanRendererContext::setEffect(int effectId, float sharpness, int effectMask, float brightness, float contrast, float gamma) {
void VulkanRendererContext::setEffect(int effectId, float sharpness, int effectMask,
float brightness, float contrast, float gamma,
float barrelStrength, float barrelHeight,
float barrelCylindricalRatio) {
activeEffectId = effectId;
activeSharpness = std::max(0.0f, std::min(1.0f, sharpness));
activeEffectMask = effectMask;
activeBrightness = std::max(-1.0f, std::min(1.0f, brightness));
activeContrast = std::max(-1.0f, std::min(1.0f, contrast));
activeGamma = std::max(0.1f, std::min(4.0f, gamma));
RLOG("setEffect: id=%d sharpness=%.3f mask=%d brightness=%.3f contrast=%.3f gamma=%.3f",
activeEffectId, activeSharpness, activeEffectMask, activeBrightness, activeContrast, activeGamma);
activeBarrelStrength = std::max(0.0f, std::min(1.0f, barrelStrength));
Comment thread
feilen marked this conversation as resolved.
activeBarrelHeight = std::max(0.05f, barrelHeight);
activeBarrelCylindricalRatio = std::max(0.5f, std::min(1.5f, barrelCylindricalRatio));
RLOG("setEffect: id=%d sharpness=%.3f mask=%d brightness=%.3f contrast=%.3f gamma=%.3f barrelStrength=%.3f barrelHeight=%.4f barrelCylindricalRatio=%.3f",
activeEffectId, activeSharpness, activeEffectMask, activeBrightness, activeContrast, activeGamma,
activeBarrelStrength, activeBarrelHeight, activeBarrelCylindricalRatio);
needsRender.store(true);
dirtyCV.notify_one();
}
Expand Down
11 changes: 10 additions & 1 deletion app/src/main/cpp/winlator/VulkanRendererContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ struct WindowPushConstants {
float gamma;
float outW; // on-screen quad width in pixels (for FSR/EASU upscale ratio)
float outH; // on-screen quad height in pixels
float barrelStrength;
float barrelHeight;
float barrelCylindricalRatio;
};

class VulkanRendererContext {
Expand Down Expand Up @@ -175,7 +178,10 @@ class VulkanRendererContext {

void setFilterMode(int mode);
void setSwapRB(bool enabled);
void setEffect(int effectId, float sharpness, int effectMask, float brightness, float contrast, float gamma);
void setEffect(int effectId, float sharpness, int effectMask, float brightness, float contrast, float gamma,
float barrelStrength = 0.0f,
float barrelHeight = 0.176327f,
float barrelCylindricalRatio = 0.5f);
void setPresentMode(VkPresentModeKHR mode);
std::vector<int> getSupportedPresentModes() const;

Expand Down Expand Up @@ -218,6 +224,9 @@ class VulkanRendererContext {
float activeBrightness = 0.0f;
float activeContrast = 0.0f;
float activeGamma = 1.0f;
float activeBarrelStrength = 0.0f;
float activeBarrelHeight = 0.176327f;
float activeBarrelCylindricalRatio = 0.5f;
float maxAnisotropy = 1.0f;
bool cubicSupported = false;
VkPhysicalDeviceMemoryProperties memProperties{};
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/cpp/winlator/vulkan_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,19 @@ Java_com_winlator_renderer_VulkanRenderer_nativeSetPresentMode(JNIEnv*, jobject,
extern "C" JNIEXPORT void JNICALL
Java_com_winlator_renderer_VulkanRenderer_nativeSetEffect(
JNIEnv*, jobject, jlong handle, jint effectId, jfloat sharpness,
jint effectMask, jfloat brightness, jfloat contrast, jfloat gamma) {
jint effectMask, jfloat brightness, jfloat contrast, jfloat gamma,
jfloat barrelStrength, jfloat barrelHeight, jfloat barrelCylindricalRatio) {
auto* r = reinterpret_cast<VulkanRendererContext*>(handle);
if (r) r->setEffect(
(int)effectId,
(float)sharpness,
(int)effectMask,
(float)brightness,
(float)contrast,
(float)gamma
(float)gamma,
(float)barrelStrength,
(float)barrelHeight,
(float)barrelCylindricalRatio
);
}

Expand Down
16 changes: 15 additions & 1 deletion app/src/main/cpp/winlator/window.frag
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,23 @@ layout(push_constant) uniform PC {
float gamma;
float outW;
float outH;
float barrelStrength;
float barrelHeight;
float barrelCylindricalRatio;
} pc;

layout(location = 0) in vec2 fragTexCoord;
layout(location = 0) in vec2 fragTexCoord;
layout(location = 1) in vec3 vUVBarrel;
layout(location = 2) in vec2 vUVDotBarrel;

layout(location = 0) out vec4 outColor;

const int EFFECT_MASK_TOON = 1;
const int EFFECT_MASK_FXAA = 2;
const int EFFECT_MASK_VIVID = 4;
const int EFFECT_MASK_CRT = 8;
const int EFFECT_MASK_NTSC = 16;
const int EFFECT_MASK_BARREL_DISTORTION = 32;

bool hasEffect(int mask) {
return (pc.effectMask & mask) != 0;
Expand Down Expand Up @@ -264,6 +271,8 @@ vec3 applyNTSC(vec2 uv, vec3 color) {
return clamp(mix(color, shifted + vec3(bleed), 0.65), 0.0, 1.0);
}



void main() {
vec2 uv = fragTexCoord;
vec4 src = texture(texSampler, uv);
Expand All @@ -284,7 +293,12 @@ void main() {
if (hasEffect(EFFECT_MASK_VIVID)) rgb = applyVivid(rgb);
if (hasEffect(EFFECT_MASK_CRT)) rgb = applyCRTOverlay(uv, rgb);
if (hasEffect(EFFECT_MASK_NTSC)) rgb = applyNTSC(uv, rgb);
if (hasEffect(EFFECT_MASK_BARREL_DISTORTION)) {
vec3 puv = dot(vUVDotBarrel, vUVDotBarrel) * vec3(-0.5, -0.5, -1.0) + vUVBarrel;
rgb = texture(texSampler, puv.xy / puv.z).rgb;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Barrel distortion overwrites the brightness/contrast/gamma adjustments applied just above it. The barrel branch re-samples from the raw texture (texSampler), discarding the color adjustments that were already applied to rgb on line 297. Users who enable barrel zoom will lose their brightness, contrast, and gamma settings entirely.

Suggestion: re-apply applyColorAdjustments(rgb) after the barrel sample, or move the barrel distortion before the color-adjustment step.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/cpp/winlator/window.frag, line 298:

<comment>Barrel distortion overwrites the brightness/contrast/gamma adjustments applied just above it. The barrel branch re-samples from the raw texture (`texSampler`), discarding the color adjustments that were already applied to `rgb` on line 297. Users who enable barrel zoom will lose their brightness, contrast, and gamma settings entirely.

Suggestion: re-apply `applyColorAdjustments(rgb)` after the barrel sample, or move the barrel distortion before the color-adjustment step.</comment>

<file context>
@@ -284,7 +293,12 @@ void main() {
         if (hasEffect(EFFECT_MASK_NTSC))  rgb = applyNTSC(uv, rgb);
+        if (hasEffect(EFFECT_MASK_BARREL_DISTORTION)) {
+            vec3 puv = dot(vUVDotBarrel, vUVDotBarrel) * vec3(-0.5, -0.5, -1.0) + vUVBarrel;
+            rgb = texture(texSampler, puv.xy / puv.z).rgb;
+        }
     }
</file context>

}
}


outColor = vec4(rgb, pc.useTexAlpha != 0 ? src.a : 1.0);
}
30 changes: 30 additions & 0 deletions app/src/main/cpp/winlator/window.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,25 @@ layout(push_constant) uniform PC {
float ndcY0;
float ndcX1;
float ndcY1;
int useTexAlpha;
int effectId;
float sharpness;
float resW;
float resH;
int effectMask;
float brightness;
float contrast;
float gamma;
float outW;
float outH;
float barrelStrength;
float barrelHeight;
float barrelCylindricalRatio;
} pc;

layout(location = 0) out vec2 fragTexCoord;
layout(location = 1) out vec3 vUVBarrel;
layout(location = 2) out vec2 vUVDotBarrel;

void main() {
int xi = (gl_VertexIndex >> 1) & 1;
Expand All @@ -16,4 +32,18 @@ void main() {
float y = yi == 1 ? pc.ndcY1 : pc.ndcY0;
gl_Position = vec4(x, y, 0.0, 1.0);
fragTexCoord = vec2(float(xi), float(yi));

float scaledHeight = pc.barrelStrength * pc.barrelHeight;
float aspectRatio = max(pc.resW / max(pc.resH, 1e-6), 1e-6);
float cylAspectRatio = aspectRatio * pc.barrelCylindricalRatio;
float aspectDiagSq = aspectRatio * aspectRatio + 1.0;
float diagSq = scaledHeight * scaledHeight * aspectDiagSq;
vec2 signedUV = fragTexCoord * 2.0 - 1.0;

float z = 0.5 * sqrt(diagSq + 1.0) + 0.5;
float ny = (z - 1.0) / (cylAspectRatio * cylAspectRatio + 1.0);

vUVDotBarrel = sqrt(max(ny, 0.0)) * vec2(cylAspectRatio, 1.0) * signedUV;
vUVBarrel = vec3(0.5, 0.5, 1.0) * z + vec3(-0.5, -0.5, 0.0);
vUVBarrel.xy += fragTexCoord;
}
Loading