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
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