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
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,10 @@ public void drawBlurRect(Canvas canvas, float y, Rect rectTmp, Paint blurScrimPa


iBlur3Capture = new ViewGroupPartRenderer(listView, contentView, listView::drawChild);
listView.setForceInternalRenderNodeBlurCapture(
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
LiteMode.isEnabled(LiteMode.FLAG_LIQUID_GLASS)
);
listView.addEdgeEffectListener(() -> listView.postOnAnimation(() -> {
checkUi_listClip();
blur3_InvalidateBlur();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3129,12 +3129,17 @@ public void removeEdgeEffectListener(EdgeEffectTrackerFactory.OnEdgeEffectListen
/* Blur3 */

private Matrix selfTransformationsMatrix;
private boolean forceInternalRenderNodeBlurCapture;

public void setForceInternalRenderNodeBlurCapture(boolean force) {
forceInternalRenderNodeBlurCapture = force;
}

@Override
public void capture(Canvas canvas, RectF position) {
final long drawingTime = SystemClock.uptimeMillis();

if (hasActiveEdgeEffects() && getOverScrollMode() != OVER_SCROLL_NEVER) {
if (forceInternalRenderNodeBlurCapture || hasActiveEdgeEffects() && getOverScrollMode() != OVER_SCROLL_NEVER) {
if (selfTransformationsMatrix == null) {
selfTransformationsMatrix = new Matrix();
}
Expand Down Expand Up @@ -3196,7 +3201,7 @@ public void captureCalculateHash(IBlur3Hash builder, RectF position) {
return;
}

if (hasActiveEdgeEffects() && getOverScrollMode() != OVER_SCROLL_NEVER) {
if (forceInternalRenderNodeBlurCapture || hasActiveEdgeEffects() && getOverScrollMode() != OVER_SCROLL_NEVER) {
builder.unsupported();
return;
}
Expand Down Expand Up @@ -3899,4 +3904,4 @@ private static float[] calculateGroup(List<Section> sections, int start, int end
return new float[]{drawFrom, drawTo, topRadius, bottomRadius, alpha};
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.telegram.ui.Components.blur3;

import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.RenderEffect;
import android.graphics.RenderNode;
import android.graphics.RuntimeShader;
import android.graphics.Shader;

import androidx.annotation.RequiresApi;

Expand All @@ -15,88 +17,114 @@ public class LiquidGlassEffect {

private final RenderNode node;
private final RuntimeShader shader;
private RenderEffect effect;

public LiquidGlassEffect(RenderNode node) {
this.node = node;
final String code = AndroidUtilities.readRes(R.raw.liquid_glass_shader);
shader = new RuntimeShader(code);
node.setRenderEffect(effect = RenderEffect.createRuntimeShaderEffect(shader, "img"));
}

private float resolutionX, resolutionY;
private float centerX, centerY;
private float sizeX, sizeY;
private float width;
private float height;
private float radiusLeftTop;
private float radiusRightTop;
private float radiusRightBottom;
private float radiusLeftBottom;
private float thickness;
private float intensity;
private float index;
private int foregroundColor;
private float refractionHeight;
private float refractionAmount;
private float depthEffect;
private float chromaticAberration;
private float blurRadius;
private float saturation;

public void update(
float left, float top, float right, float bottom,
float radiusLeftTop, float radiusRightTop, float radiusRightBottom, float radiusLeftBottom,
public LiquidGlassEffect(RenderNode node) {
this.node = node;
shader = new RuntimeShader(AndroidUtilities.readRes(R.raw.liquid_glass_shader));
}

float thickness,
float intensity,
float index,
int foregroundColor
public void update(
float width,
float height,
float radiusLeftTop,
float radiusRightTop,
float radiusRightBottom,
float radiusLeftBottom,
float refractionHeight,
float refractionAmount,
boolean depthEffect,
boolean chromaticAberration,
float blurRadius,
float saturation
) {
float resolutionX = node.getWidth();
float resolutionY = node.getHeight();
float centerX = (left + right) / 2;
float centerY = (top + bottom) / 2;
float width = right - left, height = bottom - top;
float sizeX = width / 2;
float sizeY = height / 2;
final float maxRadius = Math.min(width, height) * 0.5f;
radiusLeftTop = Math.min(radiusLeftTop, maxRadius);
radiusRightTop = Math.min(radiusRightTop, maxRadius);
radiusRightBottom = Math.min(radiusRightBottom, maxRadius);
radiusLeftBottom = Math.min(radiusLeftBottom, maxRadius);
refractionHeight = Math.max(refractionHeight, 0.001f);

if (radiusLeftTop + radiusLeftBottom > height) {
float a = radiusLeftTop / (radiusLeftTop + radiusLeftBottom);
radiusLeftTop = height * a;
radiusLeftBottom = height * (1.0f - a);
}
if (radiusRightTop + radiusRightBottom > height) {
float a = radiusRightTop / (radiusRightTop + radiusRightBottom);
radiusRightTop = height * a;
radiusRightBottom = height * (1.0f - a);
}
final float depth = depthEffect ? 1f : 0f;
final float dispersion = chromaticAberration ? 1f : 0f;

if (
Math.abs(this.resolutionX - resolutionX) > 0.1f ||
Math.abs(this.resolutionY - resolutionY) > 0.1f ||
Math.abs(this.centerX - centerX) > 0.1f ||
Math.abs(this.centerY - centerY) > 0.1f ||
Math.abs(this.sizeX - sizeX) > 0.1f ||
Math.abs(this.sizeY - sizeY) > 0.1f ||
Math.abs(this.radiusLeftTop - radiusLeftTop) > 0.1f ||
Math.abs(this.radiusRightTop - radiusRightTop) > 0.1f ||
Math.abs(this.radiusRightBottom - radiusRightBottom) > 0.1f ||
Math.abs(this.radiusLeftBottom - radiusLeftBottom) > 0.1f ||
Math.abs(this.thickness - thickness) > 0.1f ||
Math.abs(this.intensity - intensity) > 0.1f ||
Math.abs(this.index - index) > 0.1f ||
this.foregroundColor != foregroundColor
Math.abs(this.width - width) <= 0.1f &&
Math.abs(this.height - height) <= 0.1f &&
Math.abs(this.radiusLeftTop - radiusLeftTop) <= 0.1f &&
Math.abs(this.radiusRightTop - radiusRightTop) <= 0.1f &&
Math.abs(this.radiusRightBottom - radiusRightBottom) <= 0.1f &&
Math.abs(this.radiusLeftBottom - radiusLeftBottom) <= 0.1f &&
Math.abs(this.refractionHeight - refractionHeight) <= 0.1f &&
Math.abs(this.refractionAmount - refractionAmount) <= 0.1f &&
Math.abs(this.depthEffect - depth) <= 0.001f &&
Math.abs(this.chromaticAberration - dispersion) <= 0.001f &&
Math.abs(this.blurRadius - blurRadius) <= 0.1f &&
Math.abs(this.saturation - saturation) <= 0.001f
) {
this.foregroundColor = foregroundColor;
return;
}

final float a = Color.alpha(foregroundColor) / 255f;
final float r = Color.red(foregroundColor) / 255f * a;
final float g = Color.green(foregroundColor) / 255f * a;
final float b = Color.blue(foregroundColor) / 255f * a;
this.width = width;
this.height = height;
this.radiusLeftTop = radiusLeftTop;
this.radiusRightTop = radiusRightTop;
this.radiusRightBottom = radiusRightBottom;
this.radiusLeftBottom = radiusLeftBottom;
this.refractionHeight = refractionHeight;
this.refractionAmount = refractionAmount;
this.depthEffect = depth;
this.chromaticAberration = dispersion;
this.blurRadius = blurRadius;
this.saturation = saturation;

shader.setFloatUniform("resolution", this.resolutionX = resolutionX, this.resolutionY = resolutionY);
shader.setFloatUniform("center", this.centerX = centerX, this.centerY = centerY);
shader.setFloatUniform("size", this.sizeX = sizeX, this.sizeY = sizeY);
shader.setFloatUniform("radius", this.radiusRightBottom = radiusRightBottom, this.radiusRightTop = radiusRightTop, this.radiusLeftBottom = radiusLeftBottom, this.radiusLeftTop = radiusLeftTop);
shader.setFloatUniform("thickness", this.thickness = thickness);
shader.setFloatUniform("refract_intensity", this.intensity = intensity);
shader.setFloatUniform("refract_index", this.index = index);
shader.setFloatUniform("foreground_color_premultiplied", r, g, b, a);
node.setRenderEffect(effect = RenderEffect.createRuntimeShaderEffect(shader, "img"));
shader.setFloatUniform("size", width, height);
shader.setFloatUniform("offset", 0f, 0f);
shader.setFloatUniform(
"cornerRadii",
radiusLeftTop,
radiusRightTop,
radiusRightBottom,
radiusLeftBottom
);
shader.setFloatUniform("refractionHeight", refractionHeight);
shader.setFloatUniform("refractionAmount", -refractionAmount);
shader.setFloatUniform("depthEffect", depth);
shader.setFloatUniform("chromaticAberration", dispersion);

RenderEffect input = null;
if (Math.abs(saturation - 1f) > 0.001f) {
final float invSat = 1f - saturation;
final float r = 0.213f * invSat;
final float g = 0.715f * invSat;
final float b = 0.072f * invSat;
final ColorMatrix matrix = new ColorMatrix(new float[] {
r + saturation, g, b, 0f, 0f,
r, g + saturation, b, 0f, 0f,
r, g, b + saturation, 0f, 0f,
0f, 0f, 0f, 1f, 0f
});
input = RenderEffect.createColorFilterEffect(new ColorMatrixColorFilter(matrix));
}
if (blurRadius > 0f) {
input = input == null
? RenderEffect.createBlurEffect(blurRadius, blurRadius, Shader.TileMode.CLAMP)
: RenderEffect.createBlurEffect(blurRadius, blurRadius, input, Shader.TileMode.CLAMP);
}
}

final RenderEffect lens = RenderEffect.createRuntimeShaderEffect(shader, "content");
node.setRenderEffect(input == null ? lens : RenderEffect.createChainEffect(lens, input));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,55 @@ public void setIntensity(float intensity) {
onBoundPropsChanged();
}

public BlurredBackgroundDrawable setOpticalDisplacement(float amount) {
boundProps.opticalDisplacement = amount;
onBoundPropsChanged();
return this;
}

public BlurredBackgroundDrawable setDepthShadingEnabled(boolean enabled) {
boundProps.depthShadingEnabled = enabled;
onBoundPropsChanged();
return this;
}

public BlurredBackgroundDrawable setSpectralSeparationEnabled(boolean enabled) {
boundProps.spectralSeparationEnabled = enabled;
onBoundPropsChanged();
return this;
}

public BlurredBackgroundDrawable setSurfaceBlurRadius(float radius) {
boundProps.opticalBlurRadius = radius;
onBoundPropsChanged();
return this;
}

public BlurredBackgroundDrawable setBackdropSaturation(float saturation) {
boundProps.backdropSaturation = saturation;
onBoundPropsChanged();
return this;
}

public BlurredBackgroundDrawable setEdgeLightingStrength(float strength) {
boundProps.edgeLightingStrength = strength;
onBoundPropsChanged();
return this;
}

public BlurredBackgroundDrawable setSurfaceTintColor(int color) {
boundProps.surfaceTintColor = color;
onBoundPropsChanged();
return this;
}

public BlurredBackgroundDrawable setInsetShadow(float radius, float alpha) {
boundProps.insetShadowRadius = radius;
boundProps.insetShadowAlpha = alpha;
onBoundPropsChanged();
return this;
}

public Rect getPaddedBounds() {
return boundProps.boundsWithPadding;
}
Expand Down Expand Up @@ -222,7 +271,15 @@ protected static class Props {
public boolean hasPadding;
public int liquidThickness;
public float liquidIntensity = 0.75f;
public float liquidIndex = 1.5f;
public float opticalDisplacement = Float.NaN;
public float opticalBlurRadius;
public float backdropSaturation = 1.5f;
public float edgeLightingStrength = 1f;
public float insetShadowRadius;
public float insetShadowAlpha;
public int surfaceTintColor;
public boolean depthShadingEnabled;
public boolean spectralSeparationEnabled;

public float strokeWidthTop;
public float strokeWidthBottom;
Expand Down
Loading