зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1514738 - Update webrender to commit deaeaba5fd955f7a22b97b257d268a78ab744d4b (WR PR #3414). r=kats
https://github.com/servo/webrender/pull/3414 Differential Revision: https://phabricator.services.mozilla.com/D14737 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
c26f41601c
Коммит
a2c52a5f76
|
@ -1 +1 @@
|
|||
7f2d2ea79e65d49f0da2030e6033761c38c1e296
|
||||
deaeaba5fd955f7a22b97b257d268a78ab744d4b
|
||||
|
|
|
@ -10,36 +10,26 @@
|
|||
// for the various YUV modes. To save on the number of shaders we
|
||||
// need to compile, it might be worth just doing this as an
|
||||
// uber-shader instead.
|
||||
// TODO(gw): Regardless of the above, we should remove the separate shader
|
||||
// compilations for the different color space matrix below. That
|
||||
// can be provided by a branch in the VS and pushed through the
|
||||
// interpolators, or even as a uniform that breaks batches, rather
|
||||
// that needing to compile to / select a different shader when
|
||||
// there is a different color space.
|
||||
|
||||
#define YUV_COLOR_SPACE_REC601 0
|
||||
#define YUV_COLOR_SPACE_REC709 1
|
||||
|
||||
#define YUV_FORMAT_NV12 0
|
||||
#define YUV_FORMAT_PLANAR 1
|
||||
#define YUV_FORMAT_INTERLEAVED 2
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
varying vec2 vLocalPos;
|
||||
#endif
|
||||
|
||||
#if defined (WR_FEATURE_YUV_PLANAR)
|
||||
varying vec3 vUv_Y;
|
||||
flat varying vec4 vUvBounds_Y;
|
||||
varying vec3 vUv_Y;
|
||||
flat varying vec4 vUvBounds_Y;
|
||||
|
||||
varying vec3 vUv_U;
|
||||
flat varying vec4 vUvBounds_U;
|
||||
varying vec3 vUv_U;
|
||||
flat varying vec4 vUvBounds_U;
|
||||
|
||||
varying vec3 vUv_V;
|
||||
flat varying vec4 vUvBounds_V;
|
||||
#elif defined (WR_FEATURE_YUV_NV12)
|
||||
varying vec3 vUv_Y;
|
||||
flat varying vec4 vUvBounds_Y;
|
||||
|
||||
varying vec3 vUv_UV;
|
||||
flat varying vec4 vUvBounds_UV;
|
||||
#elif defined (WR_FEATURE_YUV_INTERLEAVED)
|
||||
varying vec3 vUv_YUV;
|
||||
flat varying vec4 vUvBounds_YUV;
|
||||
#endif
|
||||
varying vec3 vUv_V;
|
||||
flat varying vec4 vUvBounds_V;
|
||||
|
||||
#ifdef WR_FEATURE_TEXTURE_RECT
|
||||
#define TEX_SIZE(sampler) vec2(1.0)
|
||||
|
@ -48,8 +38,40 @@ varying vec2 vLocalPos;
|
|||
#endif
|
||||
|
||||
flat varying float vCoefficient;
|
||||
flat varying mat3 vYuvColorMatrix;
|
||||
flat varying int vFormat;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
// The constants added to the Y, U and V components are applied in the fragment shader.
|
||||
|
||||
// From Rec601:
|
||||
// [R] [1.1643835616438356, 0.0, 1.5960267857142858 ] [Y - 16]
|
||||
// [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708 ] x [U - 128]
|
||||
// [B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [V - 128]
|
||||
//
|
||||
// For the range [0,1] instead of [0,255].
|
||||
//
|
||||
// The matrix is stored in column-major.
|
||||
const mat3 YuvColorMatrixRec601 = mat3(
|
||||
1.16438, 1.16438, 1.16438,
|
||||
0.0, -0.39176, 2.01723,
|
||||
1.59603, -0.81297, 0.0
|
||||
);
|
||||
|
||||
// From Rec709:
|
||||
// [R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [Y - 16]
|
||||
// [G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444 ] x [U - 128]
|
||||
// [B] [1.1643835616438356, 2.1124017857142854, 0.0 ] [V - 128]
|
||||
//
|
||||
// For the range [0,1] instead of [0,255]:
|
||||
//
|
||||
// The matrix is stored in column-major.
|
||||
const mat3 YuvColorMatrixRec709 = mat3(
|
||||
1.16438, 1.16438, 1.16438,
|
||||
0.0 , -0.21325, 2.11240,
|
||||
1.79274, -0.53291, 0.0
|
||||
);
|
||||
|
||||
void write_uv_rect(
|
||||
int resource_id,
|
||||
vec2 f,
|
||||
|
@ -74,11 +96,13 @@ void write_uv_rect(
|
|||
|
||||
struct YuvPrimitive {
|
||||
float coefficient;
|
||||
int color_space;
|
||||
int yuv_format;
|
||||
};
|
||||
|
||||
YuvPrimitive fetch_yuv_primitive(int address) {
|
||||
vec4 data = fetch_from_gpu_cache_1(address);
|
||||
return YuvPrimitive(data.x);
|
||||
return YuvPrimitive(data.x, int(data.y), int(data.z));
|
||||
}
|
||||
|
||||
void brush_vs(
|
||||
|
@ -97,88 +121,60 @@ void brush_vs(
|
|||
YuvPrimitive prim = fetch_yuv_primitive(prim_address);
|
||||
vCoefficient = prim.coefficient;
|
||||
|
||||
if (prim.color_space == YUV_COLOR_SPACE_REC601) {
|
||||
vYuvColorMatrix = YuvColorMatrixRec601;
|
||||
} else {
|
||||
vYuvColorMatrix = YuvColorMatrixRec709;
|
||||
}
|
||||
vFormat = prim.yuv_format;
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
vLocalPos = vi.local_pos;
|
||||
#endif
|
||||
|
||||
#if defined (WR_FEATURE_YUV_PLANAR)
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
|
||||
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_U, vUvBounds_U);
|
||||
write_uv_rect(user_data.z, f, TEX_SIZE(sColor2), vUv_V, vUvBounds_V);
|
||||
#elif defined (WR_FEATURE_YUV_NV12)
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
|
||||
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_UV, vUvBounds_UV);
|
||||
#elif defined (WR_FEATURE_YUV_INTERLEAVED)
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_YUV, vUvBounds_YUV);
|
||||
#endif //WR_FEATURE_YUV_*
|
||||
if (vFormat == YUV_FORMAT_PLANAR) {
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
|
||||
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_U, vUvBounds_U);
|
||||
write_uv_rect(user_data.z, f, TEX_SIZE(sColor2), vUv_V, vUvBounds_V);
|
||||
} else if (vFormat == YUV_FORMAT_NV12) {
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
|
||||
write_uv_rect(user_data.y, f, TEX_SIZE(sColor1), vUv_U, vUvBounds_U);
|
||||
} else if (vFormat == YUV_FORMAT_INTERLEAVED) {
|
||||
write_uv_rect(user_data.x, f, TEX_SIZE(sColor0), vUv_Y, vUvBounds_Y);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
|
||||
#if !defined(WR_FEATURE_YUV_REC601) && !defined(WR_FEATURE_YUV_REC709)
|
||||
#define WR_FEATURE_YUV_REC601
|
||||
#endif
|
||||
|
||||
// The constants added to the Y, U and V components are applied in the fragment shader.
|
||||
#if defined(WR_FEATURE_YUV_REC601)
|
||||
// From Rec601:
|
||||
// [R] [1.1643835616438356, 0.0, 1.5960267857142858 ] [Y - 16]
|
||||
// [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708 ] x [U - 128]
|
||||
// [B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [V - 128]
|
||||
//
|
||||
// For the range [0,1] instead of [0,255].
|
||||
//
|
||||
// The matrix is stored in column-major.
|
||||
const mat3 YuvColorMatrix = mat3(
|
||||
1.16438, 1.16438, 1.16438,
|
||||
0.0, -0.39176, 2.01723,
|
||||
1.59603, -0.81297, 0.0
|
||||
);
|
||||
#elif defined(WR_FEATURE_YUV_REC709)
|
||||
// From Rec709:
|
||||
// [R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [Y - 16]
|
||||
// [G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444 ] x [U - 128]
|
||||
// [B] [1.1643835616438356, 2.1124017857142854, 0.0 ] [V - 128]
|
||||
//
|
||||
// For the range [0,1] instead of [0,255]:
|
||||
//
|
||||
// The matrix is stored in column-major.
|
||||
const mat3 YuvColorMatrix = mat3(
|
||||
1.16438, 1.16438, 1.16438,
|
||||
0.0 , -0.21325, 2.11240,
|
||||
1.79274, -0.53291, 0.0
|
||||
);
|
||||
#endif
|
||||
|
||||
Fragment brush_fs() {
|
||||
vec3 yuv_value;
|
||||
|
||||
#if defined (WR_FEATURE_YUV_PLANAR)
|
||||
// The yuv_planar format should have this third texture coordinate.
|
||||
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
|
||||
vec2 uv_u = clamp(vUv_U.xy, vUvBounds_U.xy, vUvBounds_U.zw);
|
||||
vec2 uv_v = clamp(vUv_V.xy, vUvBounds_V.xy, vUvBounds_V.zw);
|
||||
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
|
||||
yuv_value.y = TEX_SAMPLE(sColor1, vec3(uv_u, vUv_U.z)).r;
|
||||
yuv_value.z = TEX_SAMPLE(sColor2, vec3(uv_v, vUv_V.z)).r;
|
||||
#elif defined (WR_FEATURE_YUV_NV12)
|
||||
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
|
||||
vec2 uv_uv = clamp(vUv_UV.xy, vUvBounds_UV.xy, vUvBounds_UV.zw);
|
||||
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
|
||||
yuv_value.yz = TEX_SAMPLE(sColor1, vec3(uv_uv, vUv_UV.z)).rg;
|
||||
#elif defined (WR_FEATURE_YUV_INTERLEAVED)
|
||||
// "The Y, Cb and Cr color channels within the 422 data are mapped into
|
||||
// the existing green, blue and red color channels."
|
||||
// https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
|
||||
vec2 uv_y = clamp(vUv_YUV.xy, vUvBounds_YUV.xy, vUvBounds_YUV.zw);
|
||||
yuv_value = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_YUV.z)).gbr;
|
||||
#else
|
||||
yuv_value = vec3(0.0);
|
||||
#endif
|
||||
if (vFormat == YUV_FORMAT_PLANAR) {
|
||||
// The yuv_planar format should have this third texture coordinate.
|
||||
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
|
||||
vec2 uv_u = clamp(vUv_U.xy, vUvBounds_U.xy, vUvBounds_U.zw);
|
||||
vec2 uv_v = clamp(vUv_V.xy, vUvBounds_V.xy, vUvBounds_V.zw);
|
||||
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
|
||||
yuv_value.y = TEX_SAMPLE(sColor1, vec3(uv_u, vUv_U.z)).r;
|
||||
yuv_value.z = TEX_SAMPLE(sColor2, vec3(uv_v, vUv_V.z)).r;
|
||||
} else if (vFormat == YUV_FORMAT_NV12) {
|
||||
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
|
||||
vec2 uv_uv = clamp(vUv_U.xy, vUvBounds_U.xy, vUvBounds_U.zw);
|
||||
yuv_value.x = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).r;
|
||||
yuv_value.yz = TEX_SAMPLE(sColor1, vec3(uv_uv, vUv_U.z)).rg;
|
||||
} else if (vFormat == YUV_FORMAT_INTERLEAVED) {
|
||||
// "The Y, Cb and Cr color channels within the 422 data are mapped into
|
||||
// the existing green, blue and red color channels."
|
||||
// https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
|
||||
vec2 uv_y = clamp(vUv_Y.xy, vUvBounds_Y.xy, vUvBounds_Y.zw);
|
||||
yuv_value = TEX_SAMPLE(sColor0, vec3(uv_y, vUv_Y.z)).gbr;
|
||||
} else {
|
||||
yuv_value = vec3(0.0);
|
||||
}
|
||||
|
||||
// See the YuvColorMatrix definition for an explanation of where the constants come from.
|
||||
vec3 rgb = YuvColorMatrix * (yuv_value * vCoefficient - vec3(0.06275, 0.50196, 0.50196));
|
||||
vec3 rgb = vYuvColorMatrix * (yuv_value * vCoefficient - vec3(0.06275, 0.50196, 0.50196));
|
||||
vec4 color = vec4(rgb, 1.0);
|
||||
|
||||
#ifdef WR_FEATURE_ALPHA_PASS
|
||||
|
|
|
@ -962,11 +962,11 @@ impl PrimitiveTemplateKind {
|
|||
}
|
||||
}
|
||||
}
|
||||
PrimitiveTemplateKind::YuvImage { color_depth, .. } => {
|
||||
PrimitiveTemplateKind::YuvImage { color_depth, format, color_space, .. } => {
|
||||
request.push([
|
||||
color_depth.rescaling_factor(),
|
||||
0.0,
|
||||
0.0,
|
||||
pack_as_float(color_space as u32),
|
||||
pack_as_float(format as u32),
|
||||
0.0
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{
|
||||
YUV_COLOR_SPACES, YUV_FORMATS,
|
||||
YuvColorSpace, YuvFormat,
|
||||
};
|
||||
use batch::{BatchKey, BatchKind, BrushBatchKind};
|
||||
use device::{Device, Program, ShaderError};
|
||||
use euclid::{Transform3D};
|
||||
|
@ -635,7 +631,7 @@ impl Shaders {
|
|||
|
||||
// All yuv_image configuration.
|
||||
let mut yuv_features = Vec::new();
|
||||
let yuv_shader_num = IMAGE_BUFFER_KINDS.len() * YUV_FORMATS.len() * YUV_COLOR_SPACES.len();
|
||||
let yuv_shader_num = IMAGE_BUFFER_KINDS.len();
|
||||
let mut brush_yuv_image = Vec::new();
|
||||
// PrimitiveShader is not clonable. Use push() to initialize the vec.
|
||||
for _ in 0 .. yuv_shader_num {
|
||||
|
@ -643,37 +639,23 @@ impl Shaders {
|
|||
}
|
||||
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
||||
if image_buffer_kind.has_platform_support(&gl_type) {
|
||||
for format_kind in &YUV_FORMATS {
|
||||
for color_space_kind in &YUV_COLOR_SPACES {
|
||||
let feature_string = image_buffer_kind.get_feature_string();
|
||||
if feature_string != "" {
|
||||
yuv_features.push(feature_string);
|
||||
}
|
||||
let feature_string = format_kind.get_feature_string();
|
||||
if feature_string != "" {
|
||||
yuv_features.push(feature_string);
|
||||
}
|
||||
let feature_string = color_space_kind.get_feature_string();
|
||||
if feature_string != "" {
|
||||
yuv_features.push(feature_string);
|
||||
}
|
||||
|
||||
let shader = BrushShader::new(
|
||||
"brush_yuv_image",
|
||||
device,
|
||||
&yuv_features,
|
||||
options.precache_flags,
|
||||
false,
|
||||
)?;
|
||||
let index = Self::get_yuv_shader_index(
|
||||
*image_buffer_kind,
|
||||
*format_kind,
|
||||
*color_space_kind,
|
||||
);
|
||||
brush_yuv_image[index] = Some(shader);
|
||||
yuv_features.clear();
|
||||
}
|
||||
let feature_string = image_buffer_kind.get_feature_string();
|
||||
if feature_string != "" {
|
||||
yuv_features.push(feature_string);
|
||||
}
|
||||
|
||||
let shader = BrushShader::new(
|
||||
"brush_yuv_image",
|
||||
device,
|
||||
&yuv_features,
|
||||
options.precache_flags,
|
||||
false,
|
||||
)?;
|
||||
let index = Self::get_yuv_shader_index(
|
||||
*image_buffer_kind,
|
||||
);
|
||||
brush_yuv_image[index] = Some(shader);
|
||||
yuv_features.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -733,13 +715,8 @@ impl Shaders {
|
|||
})
|
||||
}
|
||||
|
||||
fn get_yuv_shader_index(
|
||||
buffer_kind: ImageBufferKind,
|
||||
format: YuvFormat,
|
||||
color_space: YuvColorSpace,
|
||||
) -> usize {
|
||||
((buffer_kind as usize) * YUV_FORMATS.len() + (format as usize)) * YUV_COLOR_SPACES.len() +
|
||||
(color_space as usize)
|
||||
fn get_yuv_shader_index(buffer_kind: ImageBufferKind) -> usize {
|
||||
(buffer_kind as usize)
|
||||
}
|
||||
|
||||
pub fn get(&mut self, key: &BatchKey, debug_flags: DebugFlags) -> &mut LazilyCompiledShader {
|
||||
|
@ -769,9 +746,9 @@ impl Shaders {
|
|||
BrushBatchKind::LinearGradient => {
|
||||
&mut self.brush_linear_gradient
|
||||
}
|
||||
BrushBatchKind::YuvImage(image_buffer_kind, format, _color_depth, color_space) => {
|
||||
BrushBatchKind::YuvImage(image_buffer_kind, ..) => {
|
||||
let shader_index =
|
||||
Self::get_yuv_shader_index(image_buffer_kind, format, color_space);
|
||||
Self::get_yuv_shader_index(image_buffer_kind);
|
||||
self.brush_yuv_image[shader_index]
|
||||
.as_mut()
|
||||
.expect("Unsupported YUV shader kind")
|
||||
|
|
|
@ -689,16 +689,6 @@ pub enum YuvColorSpace {
|
|||
Rec601 = 0,
|
||||
Rec709 = 1,
|
||||
}
|
||||
pub const YUV_COLOR_SPACES: [YuvColorSpace; 2] = [YuvColorSpace::Rec601, YuvColorSpace::Rec709];
|
||||
|
||||
impl YuvColorSpace {
|
||||
pub fn get_feature_string(&self) -> &'static str {
|
||||
match *self {
|
||||
YuvColorSpace::Rec601 => "YUV_REC601",
|
||||
YuvColorSpace::Rec709 => "YUV_REC709",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub enum YuvData {
|
||||
|
@ -723,11 +713,6 @@ pub enum YuvFormat {
|
|||
PlanarYCbCr = 1,
|
||||
InterleavedYCbCr = 2,
|
||||
}
|
||||
pub const YUV_FORMATS: [YuvFormat; 3] = [
|
||||
YuvFormat::NV12,
|
||||
YuvFormat::PlanarYCbCr,
|
||||
YuvFormat::InterleavedYCbCr,
|
||||
];
|
||||
|
||||
impl YuvFormat {
|
||||
pub fn get_plane_num(&self) -> usize {
|
||||
|
@ -737,14 +722,6 @@ impl YuvFormat {
|
|||
YuvFormat::InterleavedYCbCr => 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_feature_string(&self) -> &'static str {
|
||||
match *self {
|
||||
YuvFormat::NV12 => "YUV_NV12",
|
||||
YuvFormat::PlanarYCbCr => "YUV_PLANAR",
|
||||
YuvFormat::InterleavedYCbCr => "YUV_INTERLEAVED",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
Загрузка…
Ссылка в новой задаче