dab1425dea
### 🐛 Bug Fixes - Fix random crashes when switching video sources in settings management - Enhanced VodConfig.setHome() null pointer exception handling - Improved Fragment lifecycle checks to prevent crashes - Optimized HistoryDialog source switching safety - Enhanced thread safety for concurrent loading ### ⚡ Performance Improvements - Added automatic cache cleaning functionality - Improved memory usage optimization - Enhanced network request stability ### 🆕 New Features - Added comprehensive error handling mechanisms - Enhanced crash protection functionality - Improved Fragment state validation ### 📱 Build Improvements - Updated README with professional documentation - Enhanced build configuration for ARM64-V8A and ARM V7A - Improved APK packaging and signing process
98 lines
4.7 KiB
GLSL
98 lines
4.7 KiB
GLSL
#version 100
|
|
// Copyright 2022 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// ES2 fragment shader that samples from a (non-external) texture with
|
|
// uTexSampler, copying from this texture to the current output while
|
|
// applying a 3D color lookup table to change the pixel colors.
|
|
|
|
precision highp float;
|
|
uniform sampler2D uTexSampler;
|
|
// The uColorLut texture is a N x N^2 2D texture where each z-plane of the 3D
|
|
// LUT is vertically stacked on top of each other. The red channel of the input
|
|
// color (z-axis in LUT[R][G][B] = LUT[z][y][x]) points to the plane to sample
|
|
// from. For more information check the
|
|
// androidx/media3/effect/SingleColorLut.java class, especially the function
|
|
// #transformCubeIntoBitmap with a provided example.
|
|
uniform sampler2D uColorLut;
|
|
uniform float uColorLutLength;
|
|
varying vec2 vTexSamplingCoord;
|
|
|
|
// Applies the color lookup using uLut based on the input colors.
|
|
vec3 applyLookup(vec3 color) {
|
|
// Reminder: Inside OpenGL vector.xyz is the same as vector.rgb.
|
|
// Here we use mentions of x and y coordinates to references to
|
|
// the position to sample from inside the 2D LUT plane and
|
|
// rgb to create the 3D coordinates based on the input colors.
|
|
|
|
// To sample from the 3D LUT we interpolate bilinearly twice in the 2D LUT
|
|
// to replicate the trilinear interpolation in a 3D LUT. Thus we sample
|
|
// from the plane of position redCoordLow and on the plane above.
|
|
// redCoordLow points to the lower plane to sample from.
|
|
float redCoord = color.r * (uColorLutLength - 1.0);
|
|
// Clamping to uColorLutLength - 2 is only needed if redCoord points to the
|
|
// most upper plane. In this case there would not be any plane above
|
|
// available to sample from.
|
|
float redCoordLow = clamp(floor(redCoord), 0.0, uColorLutLength - 2.0);
|
|
|
|
// lowerY is indexed in two steps. First redCoordLow defines the plane to
|
|
// sample from. Next the green color component is added to index the row in
|
|
// the found plane. As described in the NVIDIA blog article about LUTs
|
|
// https://developer.nvidia.com/gpugems/gpugems2/part-iii-high-quality-rendering/chapter-24-using-lookup-tables-accelerate-color
|
|
// (Section 24.2), we sample from color * scale + offset, where offset is
|
|
// defined by 1 / (2 * uColorLutLength) and the scale is defined by
|
|
// (uColorLutLength - 1.0) / uColorLutLength.
|
|
|
|
// The following derives the equation of lowerY. For this let
|
|
// N = uColorLutLenght. The general formula to sample at row y
|
|
// is defined as y = N * r + g.
|
|
// Using the offset and scale as described in NVIDIA's blog article we get:
|
|
// y = offset + (N * r + g) * scale
|
|
// y = 1 / (2 * N) + (N * r + g) * (N - 1) / N
|
|
// y = 1 / (2 * N) + N * r * (N - 1) / N + g * (N - 1) / N
|
|
// We have defined redCoord as r * (N - 1) if we excluded the clamping for
|
|
// now, giving us:
|
|
// y = 1 / (2 * N) + N * redCoord / N + g * (N - 1) / N
|
|
// This simplifies to:
|
|
// y = 0.5 / N + (N * redCoord + g * (N - 1)) / N
|
|
// y = (0.5 + N * redCoord + g * (N - 1)) / N
|
|
// This formula now assumes a coordinate system in the range of [0, N] but
|
|
// OpenGL uses a [0, 1] unit coordinate system internally. Thus dividing
|
|
// by N gives us the final formula for y:
|
|
// y = ((0.5 + N * redCoord + g * (N - 1)) / N) / N
|
|
// y = (0.5 + redCoord * N + g * (N - 1)) / (N * N)
|
|
float lowerY = (0.5 + redCoordLow * uColorLutLength +
|
|
color.g * (uColorLutLength - 1.0)) /
|
|
(uColorLutLength * uColorLutLength);
|
|
// The upperY is the same position moved up by one LUT plane.
|
|
float upperY = lowerY + 1.0 / uColorLutLength;
|
|
|
|
// The x position is the blue color channel (x-axis in LUT[R][G][B]).
|
|
float x = (0.5 + color.b * (uColorLutLength - 1.0)) / uColorLutLength;
|
|
|
|
vec3 lowerRgb = texture2D(uColorLut, vec2(x, lowerY)).rgb;
|
|
vec3 upperRgb = texture2D(uColorLut, vec2(x, upperY)).rgb;
|
|
|
|
// Linearly interpolate between lowerRgb and upperRgb based on the
|
|
// distance of the actual in the plane and the lower sampling position.
|
|
return mix(lowerRgb, upperRgb, redCoord - redCoordLow);
|
|
}
|
|
|
|
void main() {
|
|
vec4 inputColor = texture2D(uTexSampler, vTexSamplingCoord);
|
|
|
|
gl_FragColor.rgb = applyLookup(inputColor.rgb);
|
|
gl_FragColor.a = inputColor.a;
|
|
}
|