Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial support for WebGL compressed textures #23226

Merged
merged 1 commit into from May 21, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -1168,6 +1168,43 @@ impl WebGLImpl {
&pixels,
);
},
WebGLCommand::CompressedTexImage2D {
target,
level,
internal_format,
size,
ref data,
} => {
ctx.gl().compressed_tex_image_2d(
target,
level as i32,
internal_format,
size.width as i32,
size.height as i32,
0,
&*data,
);
},
WebGLCommand::CompressedTexSubImage2D {
target,
level,
xoffset,
yoffset,
size,
format,
ref data,
} => {
ctx.gl().compressed_tex_sub_image_2d(
target,
level as i32,
xoffset as i32,
yoffset as i32,
size.width as i32,
size.height as i32,
format,
&*data,
);
},
WebGLCommand::DrawingBufferWidth(ref sender) => sender
.send(ctx.borrow_draw_buffer().unwrap().size().width)
.unwrap(),
@@ -331,6 +331,22 @@ pub enum WebGLCommand {
pixel_format: Option<PixelFormat>,
data: TruncatedDebug<IpcSharedMemory>,
},
CompressedTexImage2D {
target: u32,
level: u32,
internal_format: u32,
size: Size2D<u32>,
data: TruncatedDebug<IpcSharedMemory>,
},
CompressedTexSubImage2D {
target: u32,
level: i32,
xoffset: i32,
yoffset: i32,
size: Size2D<u32>,
format: u32,
data: TruncatedDebug<IpcSharedMemory>,
},
DrawingBufferWidth(WebGLSender<i32>),
DrawingBufferHeight(WebGLSender<i32>),
Finish(WebGLSender<()>),
@@ -736,6 +752,25 @@ macro_rules! gl_enums {
}
}

// FIXME: These should come from gleam
mod gl_ext_constants {
use gleam::gl::types::GLenum;

pub const COMPRESSED_RGB_S3TC_DXT1_EXT: GLenum = 0x83F0;
pub const COMPRESSED_RGBA_S3TC_DXT1_EXT: GLenum = 0x83F1;
pub const COMPRESSED_RGBA_S3TC_DXT3_EXT: GLenum = 0x83F2;
pub const COMPRESSED_RGBA_S3TC_DXT5_EXT: GLenum = 0x83F3;
pub const COMPRESSED_RGB_ETC1_WEBGL: GLenum = 0x8D64;

pub static COMPRESSIONS: &'static [GLenum] = &[
COMPRESSED_RGB_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT1_EXT,
COMPRESSED_RGBA_S3TC_DXT3_EXT,
COMPRESSED_RGBA_S3TC_DXT5_EXT,
COMPRESSED_RGB_ETC1_WEBGL,
];
}

gl_enums! {
pub enum TexFormat {
DepthComponent = gl::DEPTH_COMPONENT,
@@ -744,6 +779,11 @@ gl_enums! {
RGBA = gl::RGBA,
Luminance = gl::LUMINANCE,
LuminanceAlpha = gl::LUMINANCE_ALPHA,
CompressedRgbS3tcDxt1 = gl_ext_constants::COMPRESSED_RGB_S3TC_DXT1_EXT,
CompressedRgbaS3tcDxt1 = gl_ext_constants::COMPRESSED_RGBA_S3TC_DXT1_EXT,
CompressedRgbaS3tcDxt3 = gl_ext_constants::COMPRESSED_RGBA_S3TC_DXT3_EXT,
CompressedRgbaS3tcDxt5 = gl_ext_constants::COMPRESSED_RGBA_S3TC_DXT5_EXT,
CompressedRgbEtc1 = gl_ext_constants::COMPRESSED_RGB_ETC1_WEBGL,
}

pub enum TexDataType {
@@ -767,8 +807,14 @@ impl TexFormat {
TexFormat::LuminanceAlpha => 2,
TexFormat::RGB => 3,
TexFormat::RGBA => 4,
_ => 1,
}
}

/// Returns whether this format is a known texture compression format.
pub fn is_compressed(&self) -> bool {
gl_ext_constants::COMPRESSIONS.contains(&self.as_gl_constant())
}
}

impl TexDataType {
@@ -18,3 +18,5 @@ pub mod oestexturehalffloat;
pub mod oestexturehalffloatlinear;
pub mod oesvertexarrayobject;
pub mod webglcolorbufferfloat;
pub mod webglcompressedtextureetc1;
pub mod webglcompressedtextures3tc;
@@ -0,0 +1,58 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use super::{WebGLExtension, WebGLExtensionSpec, WebGLExtensions};
use crate::dom::bindings::codegen::Bindings::WEBGLCompressedTextureETC1Binding;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::webgltexture::{TexCompression, TexCompressionValidation};
use canvas_traits::webgl::{TexFormat, WebGLVersion};
use dom_struct::dom_struct;

#[dom_struct]
pub struct WEBGLCompressedTextureETC1 {
reflector_: Reflector,
}

impl WEBGLCompressedTextureETC1 {
fn new_inherited() -> WEBGLCompressedTextureETC1 {
Self {
reflector_: Reflector::new(),
}
}
}

impl WebGLExtension for WEBGLCompressedTextureETC1 {
type Extension = WEBGLCompressedTextureETC1;
fn new(ctx: &WebGLRenderingContext) -> DomRoot<WEBGLCompressedTextureETC1> {
reflect_dom_object(
Box::new(WEBGLCompressedTextureETC1::new_inherited()),
&*ctx.global(),
WEBGLCompressedTextureETC1Binding::Wrap,
)
}

fn spec() -> WebGLExtensionSpec {
WebGLExtensionSpec::Specific(WebGLVersion::WebGL1)
}

fn is_supported(ext: &WebGLExtensions) -> bool {
ext.supports_gl_extension("GL_OES_compressed_ETC1_RGB8_texture")
}

fn enable(ext: &WebGLExtensions) {
ext.add_tex_compression_formats(&[TexCompression {
format: TexFormat::CompressedRgbEtc1,
bytes_per_block: 8,
block_width: 4,
block_height: 4,
validation: TexCompressionValidation::None,
}]);
}

fn name() -> &'static str {
"WEBGL_compressed_texture_etc1"
}
}
@@ -0,0 +1,86 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use super::{WebGLExtension, WebGLExtensionSpec, WebGLExtensions};
use crate::dom::bindings::codegen::Bindings::WEBGLCompressedTextureS3TCBinding;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::webgltexture::{TexCompression, TexCompressionValidation};
use canvas_traits::webgl::{TexFormat, WebGLVersion};
use dom_struct::dom_struct;

#[dom_struct]
pub struct WEBGLCompressedTextureS3TC {
reflector_: Reflector,
}

impl WEBGLCompressedTextureS3TC {
fn new_inherited() -> WEBGLCompressedTextureS3TC {
Self {
reflector_: Reflector::new(),
}
}
}

impl WebGLExtension for WEBGLCompressedTextureS3TC {
type Extension = WEBGLCompressedTextureS3TC;
fn new(ctx: &WebGLRenderingContext) -> DomRoot<WEBGLCompressedTextureS3TC> {
reflect_dom_object(
Box::new(WEBGLCompressedTextureS3TC::new_inherited()),
&*ctx.global(),
WEBGLCompressedTextureS3TCBinding::Wrap,
)
}

fn spec() -> WebGLExtensionSpec {
WebGLExtensionSpec::Specific(WebGLVersion::WebGL1)
}

fn is_supported(ext: &WebGLExtensions) -> bool {
ext.supports_gl_extension("GL_EXT_texture_compression_s3tc") ||
ext.supports_all_gl_extension(&[
"GL_EXT_texture_compression_dxt1",
"GL_ANGLE_texture_compression_dxt3",
"GL_ANGLE_texture_compression_dxt5",
])
}

fn enable(ext: &WebGLExtensions) {
ext.add_tex_compression_formats(&[
TexCompression {
format: TexFormat::CompressedRgbS3tcDxt1,
bytes_per_block: 8,
block_width: 4,
block_height: 4,
validation: TexCompressionValidation::S3TC,
},
TexCompression {
format: TexFormat::CompressedRgbaS3tcDxt1,
bytes_per_block: 8,
block_width: 4,
block_height: 4,
validation: TexCompressionValidation::S3TC,
},
TexCompression {
format: TexFormat::CompressedRgbaS3tcDxt3,
bytes_per_block: 16,
block_width: 4,
block_height: 4,
validation: TexCompressionValidation::S3TC,
},
TexCompression {
format: TexFormat::CompressedRgbaS3tcDxt5,
bytes_per_block: 16,
block_width: 4,
block_height: 4,
validation: TexCompressionValidation::S3TC,
},
]);
}

fn name() -> &'static str {
"WEBGL_compressed_texture_s3tc"
}
}
@@ -17,6 +17,7 @@ use crate::dom::oestexturefloat::OESTextureFloat;
use crate::dom::oestexturehalffloat::OESTextureHalfFloat;
use crate::dom::webglcolorbufferfloat::WEBGLColorBufferFloat;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::webgltexture::TexCompression;
use canvas_traits::webgl::WebGLVersion;
use fnv::{FnvHashMap, FnvHashSet};
use gleam::gl::{self, GLenum};
@@ -82,6 +83,8 @@ struct WebGLExtensionFeatures {
element_index_uint_enabled: bool,
/// WebGL EXT_blend_minmax extension.
blend_minmax_enabled: bool,
/// WebGL supported texture compression formats enabled by extensions.
tex_compression_formats: FnvHashMap<GLenum, TexCompression>,
}

impl WebGLExtensionFeatures {
@@ -131,6 +134,7 @@ impl WebGLExtensionFeatures {
disabled_get_vertex_attrib_names,
element_index_uint_enabled,
blend_minmax_enabled,
tex_compression_formats: Default::default(),
}
}
}
@@ -225,6 +229,13 @@ impl WebGLExtensions {
.any(|name| features.gl_extensions.contains(*name))
}

pub fn supports_all_gl_extension(&self, names: &[&str]) -> bool {
let features = self.features.borrow();
names
.iter()
.all(|name| features.gl_extensions.contains(*name))
}

pub fn enable_tex_type(&self, data_type: GLenum) {
self.features
.borrow_mut()
@@ -335,6 +346,35 @@ impl WebGLExtensions {
.contains(&name)
}

pub fn add_tex_compression_formats(&self, formats: &[TexCompression]) {
let formats: FnvHashMap<GLenum, TexCompression> = formats
.iter()
.map(|&compression| (compression.format.as_gl_constant(), compression))
.collect();

self.features
.borrow_mut()
.tex_compression_formats
.extend(formats.iter());
}

pub fn get_tex_compression_format(&self, format_id: GLenum) -> Option<TexCompression> {
self.features
.borrow()
.tex_compression_formats
.get(&format_id)
.cloned()
}

pub fn get_tex_compression_ids(&self) -> Vec<GLenum> {
self.features
.borrow()
.tex_compression_formats
.keys()
.map(|&k| k)
.collect()
}

fn register_all_extensions(&self) {
self.register::<ext::angleinstancedarrays::ANGLEInstancedArrays>();
self.register::<ext::extblendminmax::EXTBlendMinmax>();
@@ -349,6 +389,8 @@ impl WebGLExtensions {
self.register::<ext::oestexturehalffloatlinear::OESTextureHalfFloatLinear>();
self.register::<ext::oesvertexarrayobject::OESVertexArrayObject>();
self.register::<ext::webglcolorbufferfloat::WEBGLColorBufferFloat>();
self.register::<ext::webglcompressedtextureetc1::WEBGLCompressedTextureETC1>();
self.register::<ext::webglcompressedtextures3tc::WEBGLCompressedTextureS3TC>();
}

pub fn enable_element_index_uint(&self) {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.