Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions data/gala.gresource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
<file alias="buttons/resize.svg" compressed="true" preprocess="xml-stripblanks">resize.svg</file>
</gresource>
<gresource prefix="/io/elementary/desktop/gala">
<file compressed="true">shaders/colorblindness-correction.vert</file>
<file compressed="true">shaders/monochrome.vert</file>
<file compressed="true">shaders/rounded-corners.vert</file>
<file compressed="true">shaders/colorblindness-correction.frag</file>
<file compressed="true">shaders/monochrome.frag</file>
<file compressed="true">shaders/rounded-corners.frag</file>
</gresource>
<gresource prefix="/io/elementary/desktop/gala-daemon">
<file compressed="true">gala-daemon.css</file>
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,27 @@
// based on shader from mutter

uniform sampler2D tex;
uniform float clip_radius;
uniform int clip_radius;
uniform vec2 actor_size;
uniform vec2 offset;
uniform vec2 full_texture_size;

float rounded_rect_coverage (vec2 p) {
float center_left = clip_radius + 1.5;
float center_right = actor_size.x - clip_radius - 0.55;
float center_x;
float center_left = clip_radius;
float center_right = actor_size.x - clip_radius;

float center_x;
if (p.x < center_left)
center_x = center_left;
else if (p.x >= center_right)
center_x = center_right;
else
return 1.0;

float center_top = clip_radius + 1.5;
float center_bottom = actor_size.y - clip_radius - 0.55;
float center_y;
float center_top = clip_radius;
float center_bottom = actor_size.y - clip_radius;

float center_y;
if (p.y < center_top)
center_y = center_top;
else if (p.y > center_bottom)
Expand All @@ -42,18 +44,26 @@ float rounded_rect_coverage (vec2 p) {

// Fully inside the circle
float inner_radius = clip_radius - 0.5;
if (dist_squared <= (inner_radius * inner_radius))
if (dist_squared < (inner_radius * inner_radius))
return 1.0;

// Only pixels on the edge of the curve need expensive antialiasing
return smoothstep (outer_radius, inner_radius, sqrt (dist_squared));
}

void main () {
vec4 sample = texture2D (tex, cogl_tex_coord0_in.xy);
vec2 texture_coord = cogl_tex_coord0_in.xy * full_texture_size;
if (texture_coord.x < offset.x || texture_coord.x > offset.x + actor_size.x ||
texture_coord.y < offset.y || texture_coord.y > offset.y + actor_size.y
) {
cogl_color_out = vec4 (0, 0, 0, 0);
return;
}

vec2 texture_coord = cogl_tex_coord0_in.xy * actor_size;
float res = rounded_rect_coverage (texture_coord);
texture_coord.x -= offset.x;
texture_coord.y -= offset.y;

vec4 sample = texture2D (tex, cogl_tex_coord0_in.xy);
float res = rounded_rect_coverage (texture_coord);
cogl_color_out = sample * cogl_color_in * res;
}
81 changes: 72 additions & 9 deletions lib/RoundedCornersEffect.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
*/

public class Gala.RoundedCornersEffect : Clutter.ShaderEffect {
private const int CLIP_RADIUS_OFFSET = 3;

public float clip_radius {
private int _clip_radius;
public int clip_radius {
get {
return _clip_radius;
}
construct set {
set_uniform_value ("clip_radius", value + CLIP_RADIUS_OFFSET);
_clip_radius = value;

if (actor != null) {
update_clip_radius ();
}
}
}

Expand All @@ -21,12 +27,13 @@ public class Gala.RoundedCornersEffect : Clutter.ShaderEffect {
_monitor_scale = value;

if (actor != null) {
update_clip_radius ();
update_actor_size ();
}
}
}

public RoundedCornersEffect (float clip_radius, float monitor_scale) {
public RoundedCornersEffect (int clip_radius, float monitor_scale) {
Object (
#if HAS_MUTTER48
shader_type: Cogl.ShaderType.FRAGMENT,
Expand All @@ -40,10 +47,10 @@ public class Gala.RoundedCornersEffect : Clutter.ShaderEffect {

construct {
try {
var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/rounded-corners.vert", GLib.ResourceLookupFlags.NONE);
var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/rounded-corners.frag", NONE);
set_shader_source ((string) bytes.get_data ());
} catch (Error e) {
critical ("Unable to load rounded-corners.vert: %s", e.message);
critical ("Unable to load rounded-corners.frag: %s", e.message);
}
}

Expand All @@ -59,18 +66,74 @@ public class Gala.RoundedCornersEffect : Clutter.ShaderEffect {
actor.notify["width"].connect (update_actor_size);
actor.notify["height"].connect (update_actor_size);

update_clip_radius ();
update_actor_size ();
}
}

private void update_clip_radius () requires (actor != null) {
var resource_scale = actor.get_resource_scale ();
set_uniform_value ("clip_radius", Utils.scale_to_int (clip_radius, monitor_scale / resource_scale));
Copy link
Member

Choose a reason for hiding this comment

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

Why do we divide by the resource scale here?

}

private void update_actor_size () requires (actor != null) {
var resource_scale = actor.get_resource_scale ();
var actor_box = actor.get_allocation_box ();
actor_box.scale (1.0f / resource_scale);
Clutter.ActorBox.clamp_to_pixel (ref actor_box);

float[] actor_size = {
actor.width * monitor_scale,
actor.height * monitor_scale
Math.ceilf (actor_box.get_width ()),
Math.ceilf (actor_box.get_height ())
};

var actor_size_value = GLib.Value (typeof (Clutter.ShaderFloat));
Clutter.Value.set_shader_float (actor_size_value, actor_size);
set_uniform_value ("actor_size", actor_size_value);

var effect_box = actor_box.copy ();
clutter_actor_box_enlarge_for_effects (ref effect_box);

float[] full_texture_size = {
Math.ceilf (effect_box.get_width ()),
Math.ceilf (effect_box.get_height ())
};

var full_texture_size_value = GLib.Value (typeof (Clutter.ShaderFloat));
Clutter.Value.set_shader_float (full_texture_size_value, full_texture_size);
set_uniform_value ("full_texture_size", full_texture_size_value);

float[] offset = {
Math.ceilf ((actor_box.x1 - effect_box.x1)),
Math.ceilf ((actor_box.y1 - effect_box.y1))
};

var offset_value = GLib.Value (typeof (Clutter.ShaderFloat));
Clutter.Value.set_shader_float (offset_value, offset);
set_uniform_value ("offset", offset_value);
}

/**
* This is the same as mutter's private _clutter_actor_box_enlarge_for_effects function
* Mutter basically enlarges the texture a bit to "determine a stable quantized size in pixels
* that doesn't vary due to the original box's sub-pixel position."
*
* We need to account for this in our shader code so this function is reimplemented here.
*/
private void clutter_actor_box_enlarge_for_effects (ref Clutter.ActorBox box) {
if (box.get_area () == 0.0) {
return;
}

var width = box.x2 - box.x1;
var height = box.y2 - box.y1;
width = Math.nearbyintf (width);
height = Math.nearbyintf (height);

box.x2 = Math.ceilf (box.x2 + 0.75f);
box.y2 = Math.ceilf (box.y2 + 0.75f);

box.x1 = box.x2 - width - 3;
box.y1 = box.y2 - height - 3;
}
}
4 changes: 2 additions & 2 deletions src/ColorFilters/ColorblindnessCorrectionEffect.vala
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ public class Gala.ColorblindnessCorrectionEffect : Clutter.ShaderEffect {
);

try {
var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/colorblindness-correction.vert", GLib.ResourceLookupFlags.NONE);
var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/colorblindness-correction.frag", GLib.ResourceLookupFlags.NONE);
set_shader_source ((string) bytes.get_data ());
} catch (Error e) {
critical ("Unable to load colorblindness-correction.vert: %s", e.message);
critical ("Unable to load colorblindness-correction.frag: %s", e.message);
}

pause_for_screenshot = false;
Expand Down
4 changes: 2 additions & 2 deletions src/ColorFilters/MonochromeEffect.vala
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public class Gala.MonochromeEffect : Clutter.ShaderEffect {
);

try {
var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/monochrome.vert", GLib.ResourceLookupFlags.NONE);
var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/monochrome.frag", GLib.ResourceLookupFlags.NONE);
set_shader_source ((string) bytes.get_data ());
} catch (Error e) {
critical ("Unable to load monochrome.vert: %s", e.message);
critical ("Unable to load monochrome.frag: %s", e.message);
}

pause_for_screenshot = false;
Expand Down