Bug 1673387 - Don't use texture arrays for shared and standalone texture cache entries. r=gw
The patch ended up more complicated than I anticipated due to a lot of places in webrender assuming texture arrays unless specified otherwise. The patch also merges TextureTarget into ImageBufferKind, and removes the realloc code path ing the texture cache (which is supposed to be dead code since because of performance issues on windows+intel). Differential Revision: https://phabricator.services.mozilla.com/D95562
This commit is contained in:
@@ -707,9 +707,9 @@ void BufferTextureHost::PushResourceUpdates(
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
|
||||
auto imageType =
|
||||
UseExternalTextures() || gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Rect)
|
||||
auto imageType = UseExternalTextures() || gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureRect)
|
||||
: wr::ExternalImageType::Buffer();
|
||||
|
||||
if (GetFormat() != gfx::SurfaceFormat::YUV) {
|
||||
|
||||
@@ -1012,11 +1012,11 @@ void DXGITextureHostD3D11::PushResourceUpdates(
|
||||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
|
||||
wr::ImageDescriptor descriptor(mSize, GetFormat());
|
||||
auto imageType =
|
||||
gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Rect)
|
||||
auto imageType = gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureRect)
|
||||
: wr::ExternalImageType::TextureHandle(
|
||||
wr::TextureTarget::External);
|
||||
wr::ImageBufferKind::TextureExternal);
|
||||
(aResources.*method)(aImageKeys[0], descriptor, aExtID, imageType, 0);
|
||||
break;
|
||||
}
|
||||
@@ -1034,11 +1034,11 @@ void DXGITextureHostD3D11::PushResourceUpdates(
|
||||
mFormat == gfx::SurfaceFormat::NV12
|
||||
? gfx::SurfaceFormat::R8G8
|
||||
: gfx::SurfaceFormat::R16G16);
|
||||
auto imageType =
|
||||
gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Rect)
|
||||
auto imageType = gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureRect)
|
||||
: wr::ExternalImageType::TextureHandle(
|
||||
wr::TextureTarget::External);
|
||||
wr::ImageBufferKind::TextureExternal);
|
||||
(aResources.*method)(aImageKeys[0], descriptor0, aExtID, imageType, 0);
|
||||
(aResources.*method)(aImageKeys[1], descriptor1, aExtID, imageType, 1);
|
||||
break;
|
||||
@@ -1286,10 +1286,11 @@ void DXGIYCbCrTextureHostD3D11::PushResourceUpdates(
|
||||
auto method = aOp == TextureHost::ADD_IMAGE
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
auto imageType =
|
||||
gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Rect)
|
||||
: wr::ExternalImageType::TextureHandle(wr::TextureTarget::External);
|
||||
auto imageType = gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureRect)
|
||||
: wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureExternal);
|
||||
|
||||
// y
|
||||
wr::ImageDescriptor descriptor0(mSizeY, gfx::SurfaceFormat::A8);
|
||||
|
||||
@@ -135,7 +135,7 @@ void DMABUFTextureHostOGL::PushResourceUpdates(
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
auto imageType =
|
||||
wr::ExternalImageType::TextureHandle(wr::TextureTarget::Default);
|
||||
wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::Texture2D);
|
||||
|
||||
switch (mSurface->GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
|
||||
@@ -166,7 +166,7 @@ void MacIOSurfaceTextureHostOGL::PushResourceUpdates(
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
auto imageType =
|
||||
wr::ExternalImageType::TextureHandle(wr::TextureTarget::Rect);
|
||||
wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::TextureRect);
|
||||
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
|
||||
@@ -671,8 +671,8 @@ void SurfaceTextureHost::PushResourceUpdates(
|
||||
auto method = aOp == TextureHost::ADD_IMAGE
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
auto imageType =
|
||||
wr::ExternalImageType::TextureHandle(wr::TextureTarget::External);
|
||||
auto imageType = wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureExternal);
|
||||
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
@@ -969,8 +969,8 @@ void AndroidHardwareBufferTextureHost::PushResourceUpdates(
|
||||
auto method = aOp == TextureHost::ADD_IMAGE
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
auto imageType =
|
||||
wr::ExternalImageType::TextureHandle(wr::TextureTarget::External);
|
||||
auto imageType = wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureExternal);
|
||||
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
@@ -1181,8 +1181,8 @@ void EGLImageTextureHost::PushResourceUpdates(
|
||||
auto method = aOp == TextureHost::ADD_IMAGE
|
||||
? &wr::TransactionBuilder::AddExternalImage
|
||||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
auto imageType =
|
||||
wr::ExternalImageType::TextureHandle(wr::TextureTarget::External);
|
||||
auto imageType = wr::ExternalImageType::TextureHandle(
|
||||
wr::ImageBufferKind::TextureExternal);
|
||||
|
||||
gfx::SurfaceFormat format =
|
||||
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8;
|
||||
|
||||
@@ -709,7 +709,7 @@ bool WebRenderBridgeParent::AddSharedExternalImage(
|
||||
|
||||
auto imageType =
|
||||
mApi->GetBackendType() == WebRenderBackend::SOFTWARE
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Default)
|
||||
? wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::Texture2D)
|
||||
: wr::ExternalImageType::Buffer();
|
||||
wr::ImageDescriptor descriptor(dSurf->GetSize(), dSurf->Stride(),
|
||||
dSurf->GetFormat());
|
||||
@@ -823,7 +823,7 @@ bool WebRenderBridgeParent::UpdateSharedExternalImage(
|
||||
|
||||
auto imageType =
|
||||
mApi->GetBackendType() == WebRenderBackend::SOFTWARE
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Default)
|
||||
? wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::Texture2D)
|
||||
: wr::ExternalImageType::Buffer();
|
||||
wr::ImageDescriptor descriptor(dSurf->GetSize(), dSurf->Stride(),
|
||||
dSurf->GetFormat());
|
||||
|
||||
@@ -114,7 +114,7 @@ impl Example for App {
|
||||
id: ExternalImageId(0),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
@@ -126,7 +126,7 @@ impl Example for App {
|
||||
id: ExternalImageId(1),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
@@ -138,7 +138,7 @@ impl Example for App {
|
||||
id: ExternalImageId(2),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
@@ -150,7 +150,7 @@ impl Example for App {
|
||||
id: ExternalImageId(3),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
),
|
||||
}),
|
||||
None,
|
||||
|
||||
@@ -9,7 +9,6 @@ varying vec2 vClipMaskImageUv;
|
||||
|
||||
flat varying vec4 vClipMaskUvRect;
|
||||
flat varying vec4 vClipMaskUvInnerRect;
|
||||
flat varying float vLayer;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
@@ -52,7 +51,6 @@ void main(void) {
|
||||
cmi.shared.device_pixel_scale
|
||||
);
|
||||
vLocalPos = vi.local_pos;
|
||||
vLayer = res.layer;
|
||||
vClipMaskImageUv = (vi.local_pos.xy - cmi.tile_rect.p0 * vi.local_pos.w) / cmi.tile_rect.size;
|
||||
|
||||
vec2 texture_size = vec2(textureSize(sColor0, 0));
|
||||
@@ -79,7 +77,7 @@ void main(void) {
|
||||
vec2 source_uv = clamp(
|
||||
clamped_mask_uv / vLocalPos.w * vClipMaskUvRect.zw + vClipMaskUvRect.xy,
|
||||
vClipMaskUvInnerRect.xy, vClipMaskUvInnerRect.zw);
|
||||
float clip_alpha = texture(sColor0, vec3(source_uv, vLayer)).r; //careful: texture has type A8
|
||||
float clip_alpha = texture(sColor0, source_uv).r; //careful: texture has type A8
|
||||
oFragColor = vec4(alpha * clip_alpha, 1.0, 1.0, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,6 @@ flat varying vec4 v_uv_bounds;
|
||||
|
||||
// Interpolated UV coordinates to sample.
|
||||
varying vec2 v_uv;
|
||||
flat varying float v_layer;
|
||||
|
||||
|
||||
#ifdef WR_FEATURE_GLYPH_TRANSFORM
|
||||
@@ -256,7 +255,6 @@ void main() {
|
||||
vec2 st1 = res.uv_rect.zw / texture_size;
|
||||
|
||||
v_uv = mix(st0, st1, f);
|
||||
v_layer = res.layer;
|
||||
v_uv_bounds = (res.uv_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
|
||||
}
|
||||
|
||||
@@ -267,7 +265,7 @@ void main() {
|
||||
Fragment text_fs(void) {
|
||||
Fragment frag;
|
||||
|
||||
vec3 tc = vec3(clamp(v_uv, v_uv_bounds.xy, v_uv_bounds.zw), v_layer);
|
||||
vec2 tc = clamp(v_uv, v_uv_bounds.xy, v_uv_bounds.zw);
|
||||
vec4 mask = texture(sColor0, tc);
|
||||
mask.rgb = mask.rgb * v_mask_swizzle.x + mask.aaa * v_mask_swizzle.y;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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::{AlphaType, ClipMode, ExternalImageType, ImageRendering};
|
||||
use api::{AlphaType, ClipMode, ExternalImageType, ImageRendering, ImageBufferKind};
|
||||
use api::{FontInstanceFlags, YuvColorSpace, YuvFormat, ColorDepth, ColorRange, PremultipliedColorF};
|
||||
use api::units::*;
|
||||
use crate::clip::{ClipDataStore, ClipNodeFlags, ClipNodeRange, ClipItemKind, ClipStore};
|
||||
@@ -26,7 +26,7 @@ use crate::prim_store::image::ImageSource;
|
||||
use crate::render_target::RenderTargetContext;
|
||||
use crate::render_task_graph::{RenderTaskId, RenderTaskGraph};
|
||||
use crate::render_task::RenderTaskAddress;
|
||||
use crate::renderer::{BlendMode, ImageBufferKind, ShaderColorMode};
|
||||
use crate::renderer::{BlendMode, ShaderColorMode};
|
||||
use crate::renderer::{BLOCKS_PER_UV_RECT, MAX_VERTEX_TEXTURE_WIDTH};
|
||||
use crate::resource_cache::{CacheItem, GlyphFetchResult, ImageProperties, ImageRequest, ResourceCache};
|
||||
use crate::space::SpaceMapper;
|
||||
@@ -989,6 +989,9 @@ impl BatchBuilder {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: it would be less error-prone to get this info from the texture cache.
|
||||
let image_buffer_kind = ImageBufferKind::Texture2D;
|
||||
|
||||
let non_segmented_blend_mode = if !common_data.opacity.is_opaque ||
|
||||
prim_info.clip_task_index != ClipTaskIndex::INVALID ||
|
||||
transform_kind == TransformedRectKind::Complex
|
||||
@@ -1006,7 +1009,7 @@ impl BatchBuilder {
|
||||
};
|
||||
|
||||
let batch_params = BrushBatchParameters::instanced(
|
||||
BrushBatchKind::Image(ImageBufferKind::Texture2DArray),
|
||||
BrushBatchKind::Image(image_buffer_kind),
|
||||
ImageBrushData {
|
||||
color_mode: ShaderColorMode::Image,
|
||||
alpha_type: AlphaType::PremultipliedAlpha,
|
||||
@@ -3553,6 +3556,7 @@ pub fn get_buffer_kind(texture: TextureSource) -> ImageBufferKind {
|
||||
}
|
||||
}
|
||||
}
|
||||
TextureSource::TextureCache(..) => ImageBufferKind::Texture2D,
|
||||
_ => ImageBufferKind::Texture2DArray,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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::{ColorF, YuvColorSpace, YuvFormat, ImageRendering, ExternalImageId};
|
||||
use api::{ColorF, YuvColorSpace, YuvFormat, ImageRendering, ExternalImageId, ImageBufferKind};
|
||||
use api::units::*;
|
||||
use crate::batch::{resolve_image, get_buffer_kind};
|
||||
use euclid::Transform3D;
|
||||
@@ -11,7 +11,6 @@ use crate::gpu_types::{ZBufferId, ZBufferIdGenerator};
|
||||
use crate::internal_types::TextureSource;
|
||||
use crate::picture::{ImageDependency, ResolvedSurfaceTexture, TileCacheInstance, TileId, TileSurface};
|
||||
use crate::prim_store::DeferredResolve;
|
||||
use crate::renderer::ImageBufferKind;
|
||||
use crate::resource_cache::{ImageRequest, ResourceCache};
|
||||
use crate::util::Preallocator;
|
||||
use crate::tile_cache::PictureCacheDebugInfo;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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::{ColorU, ColorF, ImageFormat, TextureTarget};
|
||||
use api::{ColorU, ColorF, ImageFormat, ImageBufferKind};
|
||||
use api::units::*;
|
||||
use crate::debug_font_data;
|
||||
use crate::device::{Device, Program, Texture, TextureSlot, VertexDescriptor, ShaderError, VAO};
|
||||
@@ -140,7 +140,7 @@ impl DebugRenderer {
|
||||
let tri_vao = device.create_vao(&DESC_COLOR);
|
||||
|
||||
let font_texture = device.create_texture(
|
||||
TextureTarget::Array,
|
||||
ImageBufferKind::Texture2DArray,
|
||||
ImageFormat::R8,
|
||||
debug_font_data::BMP_WIDTH,
|
||||
debug_font_data::BMP_HEIGHT,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use super::super::shader_source::{OPTIMIZED_SHADERS, UNOPTIMIZED_SHADERS};
|
||||
use api::{ColorF, ImageDescriptor, ImageFormat};
|
||||
use api::{MixBlendMode, TextureTarget, VoidPtrToSizeFn};
|
||||
use api::{MixBlendMode, ImageBufferKind, VoidPtrToSizeFn};
|
||||
use api::units::*;
|
||||
use euclid::default::Transform3D;
|
||||
use gleam::gl;
|
||||
@@ -150,12 +150,12 @@ fn depth_target_size_in_bytes(dimensions: &DeviceIntSize) -> usize {
|
||||
(pixels as usize) * 4
|
||||
}
|
||||
|
||||
pub fn get_gl_target(target: TextureTarget) -> gl::GLuint {
|
||||
pub fn get_gl_target(target: ImageBufferKind) -> gl::GLuint {
|
||||
match target {
|
||||
TextureTarget::Default => gl::TEXTURE_2D,
|
||||
TextureTarget::Array => gl::TEXTURE_2D_ARRAY,
|
||||
TextureTarget::Rect => gl::TEXTURE_RECTANGLE,
|
||||
TextureTarget::External => gl::TEXTURE_EXTERNAL_OES,
|
||||
ImageBufferKind::Texture2D => gl::TEXTURE_2D,
|
||||
ImageBufferKind::Texture2DArray => gl::TEXTURE_2D_ARRAY,
|
||||
ImageBufferKind::TextureRect => gl::TEXTURE_RECTANGLE,
|
||||
ImageBufferKind::TextureExternal => gl::TEXTURE_EXTERNAL_OES,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ pub struct ExternalTexture {
|
||||
impl ExternalTexture {
|
||||
pub fn new(
|
||||
id: u32,
|
||||
target: TextureTarget,
|
||||
target: ImageBufferKind,
|
||||
swizzle: Swizzle,
|
||||
uv_rect: TexelRect,
|
||||
) -> Self {
|
||||
@@ -2215,7 +2215,7 @@ impl Device {
|
||||
|
||||
pub fn create_texture(
|
||||
&mut self,
|
||||
target: TextureTarget,
|
||||
target: ImageBufferKind,
|
||||
format: ImageFormat,
|
||||
mut width: i32,
|
||||
mut height: i32,
|
||||
@@ -3087,7 +3087,7 @@ impl Device {
|
||||
}
|
||||
|
||||
pub fn attach_read_texture_external(
|
||||
&mut self, texture_id: gl::GLuint, target: TextureTarget, layer_id: i32
|
||||
&mut self, texture_id: gl::GLuint, target: ImageBufferKind, layer_id: i32
|
||||
) {
|
||||
self.attach_read_texture_raw(texture_id, get_gl_target(target), layer_id)
|
||||
}
|
||||
|
||||
@@ -1153,7 +1153,7 @@ mod test_glyph_rasterizer {
|
||||
let mut glyph_rasterizer = GlyphRasterizer::new(workers).unwrap();
|
||||
let mut glyph_cache = GlyphCache::new();
|
||||
let mut gpu_cache = GpuCache::new_for_testing();
|
||||
let mut texture_cache = TextureCache::new_for_testing(2048, 1024, FORMAT);
|
||||
let mut texture_cache = TextureCache::new_for_testing(2048, FORMAT);
|
||||
let mut render_task_cache = RenderTaskCache::new();
|
||||
let mut render_task_tree = RenderTaskGraph::new(FrameId::INVALID, &RenderTaskGraphCounters::new());
|
||||
let mut font_file =
|
||||
@@ -1205,7 +1205,7 @@ mod test_glyph_rasterizer {
|
||||
|
||||
glyph_rasterizer.resolve_glyphs(
|
||||
&mut glyph_cache,
|
||||
&mut TextureCache::new_for_testing(4096, 1024, FORMAT),
|
||||
&mut TextureCache::new_for_testing(4096, FORMAT),
|
||||
&mut gpu_cache,
|
||||
&mut render_task_cache,
|
||||
&mut render_task_tree,
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* 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::{ColorF, DocumentId, ExternalImageData, ExternalImageId, PrimitiveFlags};
|
||||
use api::{ImageFormat, NotificationRequest, Shadow, FilterOp};
|
||||
use api::{ColorF, DocumentId, ExternalImageData, ExternalImageId, ExternalImageType, PrimitiveFlags};
|
||||
use api::{ImageFormat, NotificationRequest, Shadow, FilterOp, ImageBufferKind};
|
||||
use api::units::*;
|
||||
use api;
|
||||
use crate::render_api::DebugCommand;
|
||||
@@ -287,6 +287,31 @@ pub enum TextureSource {
|
||||
Dummy,
|
||||
}
|
||||
|
||||
impl TextureSource {
|
||||
pub fn image_buffer_kind(&self) -> ImageBufferKind {
|
||||
match *self {
|
||||
TextureSource::TextureCache(..) => ImageBufferKind::Texture2D,
|
||||
|
||||
TextureSource::External(external_image) => {
|
||||
match external_image.image_type {
|
||||
ExternalImageType::TextureHandle(kind) => kind,
|
||||
// Raw buffer external textures go to the texture cache.
|
||||
ExternalImageType::Buffer => ImageBufferKind::Texture2D,
|
||||
}
|
||||
},
|
||||
|
||||
// Render tasks use texture arrays for now.
|
||||
TextureSource::PrevPassAlpha
|
||||
| TextureSource::PrevPassColor
|
||||
| TextureSource::RenderTaskCache(..)
|
||||
| TextureSource::Dummy => ImageBufferKind::Texture2DArray,
|
||||
|
||||
|
||||
TextureSource::Invalid => ImageBufferKind::Texture2D,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@@ -323,6 +348,7 @@ pub struct TextureCacheAllocInfo {
|
||||
pub layer_count: i32,
|
||||
pub format: ImageFormat,
|
||||
pub filter: TextureFilter,
|
||||
pub target: ImageBufferKind,
|
||||
/// Indicates whether this corresponds to one of the shared texture caches.
|
||||
pub is_shared_cache: bool,
|
||||
/// If true, this texture requires a depth target.
|
||||
@@ -334,10 +360,6 @@ pub struct TextureCacheAllocInfo {
|
||||
pub enum TextureCacheAllocationKind {
|
||||
/// Performs an initial texture allocation.
|
||||
Alloc(TextureCacheAllocInfo),
|
||||
/// Reallocates the texture. The existing live texture with the same id
|
||||
/// will be deallocated and its contents blitted over. The new size must
|
||||
/// be greater than the old size.
|
||||
Realloc(TextureCacheAllocInfo),
|
||||
/// Reallocates the texture without preserving its contents.
|
||||
Reset(TextureCacheAllocInfo),
|
||||
/// Frees the texture and the corresponding cache ID.
|
||||
@@ -434,28 +456,6 @@ impl TextureUpdateList {
|
||||
});
|
||||
}
|
||||
|
||||
/// Pushes a reallocation operation onto the list, potentially coalescing
|
||||
/// with previous operations.
|
||||
pub fn push_realloc(&mut self, id: CacheTextureId, info: TextureCacheAllocInfo) {
|
||||
self.debug_assert_coalesced(id);
|
||||
|
||||
// Coallesce this realloc into a previous alloc or realloc, if available.
|
||||
if let Some(cur) = self.allocations.iter_mut().find(|x| x.id == id) {
|
||||
match cur.kind {
|
||||
TextureCacheAllocationKind::Alloc(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Realloc(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Reset(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Free => panic!("Reallocating freed texture"),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
self.allocations.push(TextureCacheAllocation {
|
||||
id,
|
||||
kind: TextureCacheAllocationKind::Realloc(info),
|
||||
});
|
||||
}
|
||||
|
||||
/// Pushes a reallocation operation onto the list, potentially coalescing
|
||||
/// with previous operations.
|
||||
pub fn push_reset(&mut self, id: CacheTextureId, info: TextureCacheAllocInfo) {
|
||||
@@ -470,10 +470,6 @@ impl TextureUpdateList {
|
||||
TextureCacheAllocationKind::Alloc(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Reset(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Free => panic!("Resetting freed texture"),
|
||||
TextureCacheAllocationKind::Realloc(_) => {
|
||||
// Reset takes precedence over realloc
|
||||
cur.kind = TextureCacheAllocationKind::Reset(info);
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -499,7 +495,6 @@ impl TextureUpdateList {
|
||||
match removed_kind {
|
||||
Some(TextureCacheAllocationKind::Alloc(..)) => { /* no-op! */ },
|
||||
Some(TextureCacheAllocationKind::Free) => panic!("Double free"),
|
||||
Some(TextureCacheAllocationKind::Realloc(..)) |
|
||||
Some(TextureCacheAllocationKind::Reset(..)) |
|
||||
None => {
|
||||
self.allocations.push(TextureCacheAllocation {
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
|
||||
use api::{BlobImageHandler, ColorF, ColorU, MixBlendMode};
|
||||
use api::{DocumentId, Epoch, ExternalImageHandler, ExternalImageId};
|
||||
use api::{ExternalImageSource, ExternalImageType, ExternalImageType::TextureHandle, FontRenderMode, ImageFormat};
|
||||
use api::{ExternalImageSource, ExternalImageType, FontRenderMode, ImageFormat};
|
||||
use api::{PipelineId, ImageRendering, Checkpoint, NotificationRequest};
|
||||
use api::{VoidPtrToSizeFn, PremultipliedColorF};
|
||||
use api::{RenderNotifier, TextureTarget, SharedFontInstanceMap};
|
||||
use api::{RenderNotifier, ImageBufferKind, SharedFontInstanceMap};
|
||||
#[cfg(feature = "replay")]
|
||||
use api::ExternalImage;
|
||||
use api::units::*;
|
||||
@@ -1096,28 +1096,6 @@ pub struct GraphicsApiInfo {
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum ImageBufferKind {
|
||||
Texture2D = 0,
|
||||
TextureRect = 1,
|
||||
TextureExternal = 2,
|
||||
Texture2DArray = 3,
|
||||
}
|
||||
|
||||
//TODO: those types are the same, so let's merge them
|
||||
impl From<TextureTarget> for ImageBufferKind {
|
||||
fn from(target: TextureTarget) -> Self {
|
||||
match target {
|
||||
TextureTarget::Default => ImageBufferKind::Texture2D,
|
||||
TextureTarget::Rect => ImageBufferKind::TextureRect,
|
||||
TextureTarget::Array => ImageBufferKind::Texture2DArray,
|
||||
TextureTarget::External => ImageBufferKind::TextureExternal,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GpuProfile {
|
||||
pub frame_id: GpuFrameId,
|
||||
@@ -1227,7 +1205,7 @@ impl TextureResolver {
|
||||
fn new(device: &mut Device) -> TextureResolver {
|
||||
let dummy_cache_texture = device
|
||||
.create_texture(
|
||||
TextureTarget::Array,
|
||||
ImageBufferKind::Texture2DArray,
|
||||
ImageFormat::RGBA8,
|
||||
1,
|
||||
1,
|
||||
@@ -1648,7 +1626,7 @@ impl GpuCacheTexture {
|
||||
_ => Some(RenderTargetInfo { has_depth: false }),
|
||||
};
|
||||
let mut texture = device.create_texture(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
ImageFormat::RGBAF32,
|
||||
new_size.width,
|
||||
new_size.height,
|
||||
@@ -1938,7 +1916,7 @@ impl<T> VertexDataTexture<T> {
|
||||
}
|
||||
|
||||
let texture = device.create_texture(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
self.format,
|
||||
MAX_VERTEX_TEXTURE_WIDTH as i32,
|
||||
// Ensure height is at least two to work around
|
||||
@@ -2453,7 +2431,6 @@ impl Renderer {
|
||||
return Err(RendererError::MaxTextureSize);
|
||||
}
|
||||
let max_texture_size = device.max_texture_size();
|
||||
let max_texture_layers = device.max_texture_layers();
|
||||
|
||||
device.begin_frame();
|
||||
|
||||
@@ -2531,7 +2508,7 @@ impl Renderer {
|
||||
];
|
||||
|
||||
let texture = device.create_texture(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
ImageFormat::R8,
|
||||
8,
|
||||
8,
|
||||
@@ -2770,7 +2747,6 @@ impl Renderer {
|
||||
|
||||
let texture_cache = TextureCache::new(
|
||||
max_texture_size,
|
||||
max_texture_layers,
|
||||
picture_tile_size,
|
||||
color_cache_formats,
|
||||
swizzle_settings,
|
||||
@@ -3981,20 +3957,18 @@ impl Renderer {
|
||||
for allocation in update_list.allocations {
|
||||
match allocation.kind {
|
||||
TextureCacheAllocationKind::Alloc(_) => add_event_marker(c_str!("TextureCacheAlloc")),
|
||||
TextureCacheAllocationKind::Realloc(_) => add_event_marker(c_str!("TextureCacheRealloc")),
|
||||
TextureCacheAllocationKind::Reset(_) => add_event_marker(c_str!("TextureCacheReset")),
|
||||
TextureCacheAllocationKind::Free => add_event_marker(c_str!("TextureCacheFree")),
|
||||
};
|
||||
let old = match allocation.kind {
|
||||
TextureCacheAllocationKind::Alloc(ref info) |
|
||||
TextureCacheAllocationKind::Realloc(ref info) |
|
||||
TextureCacheAllocationKind::Reset(ref info) => {
|
||||
// Create a new native texture, as requested by the texture cache.
|
||||
//
|
||||
// Ensure no PBO is bound when creating the texture storage,
|
||||
// or GL will attempt to read data from there.
|
||||
let mut texture = self.device.create_texture(
|
||||
TextureTarget::Array,
|
||||
info.target,
|
||||
info.format,
|
||||
info.width,
|
||||
info.height,
|
||||
@@ -4037,12 +4011,6 @@ impl Renderer {
|
||||
TextureCacheAllocationKind::Alloc(_) => {
|
||||
assert!(old.is_none(), "Renderer and backend disagree!");
|
||||
}
|
||||
TextureCacheAllocationKind::Realloc(_) => {
|
||||
self.device.blit_renderable_texture(
|
||||
self.texture_resolver.texture_cache_map.get_mut(&allocation.id).unwrap(),
|
||||
old.as_ref().unwrap(),
|
||||
);
|
||||
}
|
||||
TextureCacheAllocationKind::Reset(_) |
|
||||
TextureCacheAllocationKind::Free => {
|
||||
assert!(old.is_some(), "Renderer and backend disagree!");
|
||||
@@ -4162,7 +4130,7 @@ impl Renderer {
|
||||
allocator.extend(new_slice, BATCH_UPLOAD_TEXTURE_SIZE, rect.size);
|
||||
|
||||
let staging_texture = device.create_texture(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
texture.get_format(),
|
||||
BATCH_UPLOAD_TEXTURE_SIZE.width,
|
||||
BATCH_UPLOAD_TEXTURE_SIZE.height,
|
||||
@@ -4513,22 +4481,7 @@ impl Renderer {
|
||||
let _timer = self.gpu_profiler.start_timer(GPU_TAG_SCALE);
|
||||
|
||||
for (source, instances) in scalings {
|
||||
let target = match *source {
|
||||
TextureSource::External(external_image) => {
|
||||
match external_image.image_type {
|
||||
TextureHandle(texture_target) => {
|
||||
texture_target
|
||||
},
|
||||
_ => {
|
||||
TextureTarget::Array
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
TextureTarget::Array
|
||||
}
|
||||
};
|
||||
let buffer_kind = ImageBufferKind::from(target);
|
||||
let buffer_kind = source.image_buffer_kind();
|
||||
|
||||
self.shaders
|
||||
.borrow_mut()
|
||||
@@ -5124,7 +5077,7 @@ impl Renderer {
|
||||
tile.z_id,
|
||||
),
|
||||
BatchTextures::color(TextureSource::Dummy),
|
||||
(CompositeSurfaceFormat::Rgba, ImageBufferKind::Texture2DArray),
|
||||
(CompositeSurfaceFormat::Rgba, ImageBufferKind::Texture2D),
|
||||
)
|
||||
}
|
||||
CompositeTileSurface::Texture { surface: ResolvedSurfaceTexture::TextureCache { texture, layer } } => {
|
||||
@@ -6158,7 +6111,7 @@ impl Renderer {
|
||||
} else {
|
||||
self.profile.inc(profiler::CREATED_TARGETS);
|
||||
self.device.create_texture(
|
||||
TextureTarget::Array,
|
||||
ImageBufferKind::Texture2DArray,
|
||||
list.format,
|
||||
dimensions.width,
|
||||
dimensions.height,
|
||||
@@ -6802,7 +6755,7 @@ impl Renderer {
|
||||
|
||||
if self.zoom_debug_texture.is_none() {
|
||||
let texture = self.device.create_texture(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
ImageFormat::BGRA8,
|
||||
source_rect.size.width,
|
||||
source_rect.size.height,
|
||||
@@ -7639,7 +7592,7 @@ impl Renderer {
|
||||
|
||||
#[cfg(feature = "replay")]
|
||||
fn load_texture(
|
||||
target: TextureTarget,
|
||||
target: ImageBufferKind,
|
||||
plain: &PlainTexture,
|
||||
rt_info: Option<RenderTargetInfo>,
|
||||
root: &PathBuf,
|
||||
@@ -7902,7 +7855,7 @@ impl Renderer {
|
||||
for (id, texture) in renderer.textures {
|
||||
info!("\t{}", texture.data);
|
||||
let t = Self::load_texture(
|
||||
TextureTarget::Array,
|
||||
ImageBufferKind::Texture2DArray,
|
||||
&texture,
|
||||
Some(RenderTargetInfo { has_depth: texture.has_depth }),
|
||||
&root,
|
||||
@@ -7916,7 +7869,7 @@ impl Renderer {
|
||||
self.device.delete_texture(t);
|
||||
}
|
||||
let (t, gpu_cache_data) = Self::load_texture(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
&renderer.gpu_cache,
|
||||
Some(RenderTargetInfo { has_depth: false }),
|
||||
&root,
|
||||
|
||||
@@ -1808,7 +1808,6 @@ impl ResourceCache {
|
||||
self.current_frame_id = FrameId::INVALID;
|
||||
self.texture_cache = TextureCache::new(
|
||||
self.texture_cache.max_texture_size(),
|
||||
self.texture_cache.max_texture_layers(),
|
||||
self.texture_cache.default_picture_tile_size(),
|
||||
self.texture_cache.color_formats(),
|
||||
self.texture_cache.swizzle_settings(),
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use api::{ImageFormat, TextureTarget};
|
||||
use api::{ImageFormat, ImageBufferKind};
|
||||
use api::units::*;
|
||||
use gleam::gl::GlType;
|
||||
|
||||
@@ -248,7 +248,7 @@ impl AsyncScreenshotGrabber {
|
||||
// texture is the wrong size, then create a new one.
|
||||
if level == self.scaling_textures.len() || self.scaling_textures[level].get_dimensions() != texture_size {
|
||||
let texture = device.create_texture(
|
||||
TextureTarget::Default,
|
||||
ImageBufferKind::Texture2D,
|
||||
image_format,
|
||||
texture_size.width,
|
||||
texture_size.height,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* 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::ImageBufferKind;
|
||||
use crate::batch::{BatchKey, BatchKind, BrushBatchKind, BatchFeatures};
|
||||
use crate::composite::CompositeSurfaceFormat;
|
||||
use crate::device::{Device, Program, ShaderError};
|
||||
@@ -9,7 +10,7 @@ use euclid::default::Transform3D;
|
||||
use crate::glyph_rasterizer::GlyphFormat;
|
||||
use crate::renderer::{
|
||||
desc,
|
||||
BlendMode, DebugFlags, ImageBufferKind, RendererError, RendererOptions,
|
||||
BlendMode, DebugFlags, RendererError, RendererOptions,
|
||||
TextureSampler, VertexArrayKind, ShaderPrecacheFlags,
|
||||
};
|
||||
|
||||
@@ -21,18 +22,17 @@ use std::rc::Rc;
|
||||
|
||||
use webrender_build::shader::{ShaderFeatures, ShaderFeatureFlags, get_shader_features};
|
||||
|
||||
impl ImageBufferKind {
|
||||
pub(crate) fn get_feature_string(&self) -> &'static str {
|
||||
match *self {
|
||||
pub(crate) fn get_feature_string(kind: ImageBufferKind) -> &'static str {
|
||||
match kind {
|
||||
ImageBufferKind::Texture2D => "TEXTURE_2D",
|
||||
ImageBufferKind::Texture2DArray => "",
|
||||
ImageBufferKind::TextureRect => "TEXTURE_RECT",
|
||||
ImageBufferKind::TextureExternal => "TEXTURE_EXTERNAL",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn has_platform_support(&self, gl_type: &GlType) -> bool {
|
||||
match (*self, gl_type) {
|
||||
fn has_platform_support(kind: ImageBufferKind, gl_type: &GlType) -> bool {
|
||||
match (kind, gl_type) {
|
||||
(ImageBufferKind::Texture2D, _) => true,
|
||||
(ImageBufferKind::Texture2DArray, _) => true,
|
||||
(ImageBufferKind::TextureRect, &GlType::Gles) => false,
|
||||
@@ -40,7 +40,6 @@ impl ImageBufferKind {
|
||||
(ImageBufferKind::TextureExternal, &GlType::Gles) => true,
|
||||
(ImageBufferKind::TextureExternal, &GlType::Gl) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const IMAGE_BUFFER_KINDS: [ImageBufferKind; 4] = [
|
||||
@@ -447,6 +446,7 @@ impl TextShader {
|
||||
) -> Result<Self, ShaderError> {
|
||||
let mut simple_features = features.to_vec();
|
||||
simple_features.push("ALPHA_PASS");
|
||||
simple_features.push("TEXTURE_2D");
|
||||
|
||||
let simple = LazilyCompiledShader::new(
|
||||
ShaderKind::Text,
|
||||
@@ -460,6 +460,7 @@ impl TextShader {
|
||||
let mut glyph_transform_features = features.to_vec();
|
||||
glyph_transform_features.push("GLYPH_TRANSFORM");
|
||||
glyph_transform_features.push("ALPHA_PASS");
|
||||
glyph_transform_features.push("TEXTURE_2D");
|
||||
|
||||
let glyph_transform = LazilyCompiledShader::new(
|
||||
ShaderKind::Text,
|
||||
@@ -472,6 +473,7 @@ impl TextShader {
|
||||
|
||||
let mut debug_overdraw_features = features.to_vec();
|
||||
debug_overdraw_features.push("DEBUG_OVERDRAW");
|
||||
debug_overdraw_features.push("TEXTURE_2D");
|
||||
|
||||
let debug_overdraw = LazilyCompiledShader::new(
|
||||
ShaderKind::Text,
|
||||
@@ -776,7 +778,7 @@ impl Shaders {
|
||||
let cs_clip_box_shadow = LazilyCompiledShader::new(
|
||||
ShaderKind::ClipCache(VertexArrayKind::ClipBoxShadow),
|
||||
"cs_clip_box_shadow",
|
||||
&[],
|
||||
&["TEXTURE_2D"],
|
||||
device,
|
||||
options.precache_flags,
|
||||
&shader_list,
|
||||
@@ -785,7 +787,7 @@ impl Shaders {
|
||||
let cs_clip_image = LazilyCompiledShader::new(
|
||||
ShaderKind::ClipCache(VertexArrayKind::ClipImage),
|
||||
"cs_clip_image",
|
||||
&[],
|
||||
&["TEXTURE_2D"],
|
||||
device,
|
||||
options.precache_flags,
|
||||
&shader_list,
|
||||
@@ -824,8 +826,8 @@ impl Shaders {
|
||||
cs_scale.push(None);
|
||||
}
|
||||
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
||||
if image_buffer_kind.has_platform_support(&gl_type) {
|
||||
let feature_string = image_buffer_kind.get_feature_string();
|
||||
if has_platform_support(*image_buffer_kind, &gl_type) {
|
||||
let feature_string = get_feature_string(*image_buffer_kind);
|
||||
|
||||
let mut features = Vec::new();
|
||||
if feature_string != "" {
|
||||
@@ -904,11 +906,11 @@ impl Shaders {
|
||||
brush_fast_image.push(None);
|
||||
}
|
||||
for buffer_kind in 0 .. IMAGE_BUFFER_KINDS.len() {
|
||||
if !IMAGE_BUFFER_KINDS[buffer_kind].has_platform_support(&gl_type) {
|
||||
if !has_platform_support(IMAGE_BUFFER_KINDS[buffer_kind], &gl_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let feature_string = IMAGE_BUFFER_KINDS[buffer_kind].get_feature_string();
|
||||
let feature_string = get_feature_string(IMAGE_BUFFER_KINDS[buffer_kind]);
|
||||
if feature_string != "" {
|
||||
image_features.push(feature_string);
|
||||
}
|
||||
@@ -955,10 +957,10 @@ impl Shaders {
|
||||
composite_rgba.push(None);
|
||||
}
|
||||
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
|
||||
if image_buffer_kind.has_platform_support(&gl_type) {
|
||||
if has_platform_support(*image_buffer_kind, &gl_type) {
|
||||
yuv_features.push("YUV");
|
||||
|
||||
let feature_string = image_buffer_kind.get_feature_string();
|
||||
let feature_string = get_feature_string(*image_buffer_kind);
|
||||
if feature_string != "" {
|
||||
yuv_features.push(feature_string);
|
||||
rgba_features.push(feature_string);
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
* 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::{DirtyRect, ExternalImageType, ImageFormat};
|
||||
use api::{DirtyRect, ExternalImageType, ImageFormat, ImageBufferKind};
|
||||
use api::{DebugFlags, ImageDescriptor};
|
||||
use api::units::*;
|
||||
#[cfg(test)]
|
||||
use api::{DocumentId, IdNamespace};
|
||||
use euclid::point2;
|
||||
use crate::device::{TextureFilter, TextureFormatPair};
|
||||
use crate::freelist::{FreeListHandle, WeakFreeListHandle};
|
||||
use crate::gpu_cache::{GpuCache, GpuCacheHandle};
|
||||
@@ -38,7 +39,7 @@ pub enum TargetShader {
|
||||
Text,
|
||||
}
|
||||
|
||||
/// The size of each region/layer in shared cache texture arrays.
|
||||
/// The size of each region in shared cache texture arrays.
|
||||
pub const TEXTURE_REGION_DIMENSIONS: i32 = 512;
|
||||
|
||||
const PICTURE_TEXTURE_SLICE_COUNT: usize = 8;
|
||||
@@ -69,8 +70,8 @@ enum EntryDetails {
|
||||
Cache {
|
||||
/// Origin within the texture layer where this item exists.
|
||||
origin: DeviceIntPoint,
|
||||
/// The layer index of the texture array.
|
||||
layer_index: usize,
|
||||
/// The index of the allocator region.
|
||||
region_index: usize,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ impl EntryDetails {
|
||||
match *self {
|
||||
EntryDetails::Standalone { .. } => (0, DeviceIntPoint::zero()),
|
||||
EntryDetails::Picture { layer_index, .. } => (layer_index, DeviceIntPoint::zero()),
|
||||
EntryDetails::Cache { origin, layer_index, .. } => (layer_index, origin),
|
||||
EntryDetails::Cache { origin, .. } => (0, origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,11 +239,11 @@ impl EvictionNotice {
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
struct SharedTextures {
|
||||
array_color8_nearest: TextureArray,
|
||||
array_alpha8_linear: TextureArray,
|
||||
array_alpha16_linear: TextureArray,
|
||||
array_color8_linear: TextureArray,
|
||||
array_color8_glyphs: TextureArray,
|
||||
color8_nearest: TextureUnits,
|
||||
alpha8_linear: TextureUnits,
|
||||
alpha16_linear: TextureUnits,
|
||||
color8_linear: TextureUnits,
|
||||
color8_glyphs: TextureUnits,
|
||||
}
|
||||
|
||||
impl SharedTextures {
|
||||
@@ -252,34 +253,34 @@ impl SharedTextures {
|
||||
// Used primarily for cached shadow masks. There can be lots of
|
||||
// these on some pages like francine, but most pages don't use it
|
||||
// much.
|
||||
array_alpha8_linear: TextureArray::new(
|
||||
alpha8_linear: TextureUnits::new(
|
||||
TextureFormatPair::from(ImageFormat::R8),
|
||||
TextureFilter::Linear,
|
||||
8,
|
||||
2
|
||||
),
|
||||
// Used for experimental hdr yuv texture support, but not used in
|
||||
// production Firefox.
|
||||
array_alpha16_linear: TextureArray::new(
|
||||
alpha16_linear: TextureUnits::new(
|
||||
TextureFormatPair::from(ImageFormat::R16),
|
||||
TextureFilter::Linear,
|
||||
1,
|
||||
1
|
||||
),
|
||||
// The primary cache for images, etc.
|
||||
array_color8_linear: TextureArray::new(
|
||||
color8_linear: TextureUnits::new(
|
||||
color_formats.clone(),
|
||||
TextureFilter::Linear,
|
||||
16,
|
||||
4,
|
||||
),
|
||||
// The cache for glyphs (separate to help with batching).
|
||||
array_color8_glyphs: TextureArray::new(
|
||||
color8_glyphs: TextureUnits::new(
|
||||
color_formats.clone(),
|
||||
TextureFilter::Linear,
|
||||
16,
|
||||
4,
|
||||
),
|
||||
// Used for image-rendering: crisp. This is mostly favicons, which
|
||||
// are small. Some other images use it too, but those tend to be
|
||||
// larger than 512x512 and thus don't use the shared cache anyway.
|
||||
array_color8_nearest: TextureArray::new(
|
||||
color8_nearest: TextureUnits::new(
|
||||
color_formats,
|
||||
TextureFilter::Nearest,
|
||||
1,
|
||||
@@ -289,32 +290,32 @@ impl SharedTextures {
|
||||
|
||||
/// Clears each texture in the set, with the given set of pending updates.
|
||||
fn clear(&mut self, updates: &mut TextureUpdateList) {
|
||||
self.array_alpha8_linear.clear(updates);
|
||||
self.array_alpha16_linear.clear(updates);
|
||||
self.array_color8_linear.clear(updates);
|
||||
self.array_color8_nearest.clear(updates);
|
||||
self.array_color8_glyphs.clear(updates);
|
||||
self.alpha8_linear.clear(updates);
|
||||
self.alpha16_linear.clear(updates);
|
||||
self.color8_linear.clear(updates);
|
||||
self.color8_nearest.clear(updates);
|
||||
self.color8_glyphs.clear(updates);
|
||||
}
|
||||
|
||||
/// Returns a mutable borrow for the shared texture array matching the parameters.
|
||||
fn select(
|
||||
&mut self, external_format: ImageFormat, filter: TextureFilter, shader: TargetShader,
|
||||
) -> &mut TextureArray {
|
||||
) -> &mut TextureUnits {
|
||||
match external_format {
|
||||
ImageFormat::R8 => {
|
||||
assert_eq!(filter, TextureFilter::Linear);
|
||||
&mut self.array_alpha8_linear
|
||||
&mut self.alpha8_linear
|
||||
}
|
||||
ImageFormat::R16 => {
|
||||
assert_eq!(filter, TextureFilter::Linear);
|
||||
&mut self.array_alpha16_linear
|
||||
&mut self.alpha16_linear
|
||||
}
|
||||
ImageFormat::RGBA8 |
|
||||
ImageFormat::BGRA8 => {
|
||||
match (filter, shader) {
|
||||
(TextureFilter::Linear, TargetShader::Text) => &mut self.array_color8_glyphs,
|
||||
(TextureFilter::Linear, _) => &mut self.array_color8_linear,
|
||||
(TextureFilter::Nearest, _) => &mut self.array_color8_nearest,
|
||||
(TextureFilter::Linear, TargetShader::Text) => &mut self.color8_glyphs,
|
||||
(TextureFilter::Linear, _) => &mut self.color8_linear,
|
||||
(TextureFilter::Nearest, _) => &mut self.color8_nearest,
|
||||
_ => panic!("Unexpexcted filter {:?}", filter),
|
||||
}
|
||||
}
|
||||
@@ -452,9 +453,6 @@ pub struct TextureCache {
|
||||
/// Maximum texture size supported by hardware.
|
||||
max_texture_size: i32,
|
||||
|
||||
/// Maximum number of texture layers supported by hardware.
|
||||
max_texture_layers: usize,
|
||||
|
||||
/// Settings on using texture unit swizzling.
|
||||
swizzle: Option<SwizzleSettings>,
|
||||
|
||||
@@ -507,39 +505,10 @@ impl TextureCache {
|
||||
|
||||
pub fn new(
|
||||
max_texture_size: i32,
|
||||
mut max_texture_layers: usize,
|
||||
default_picture_tile_size: DeviceIntSize,
|
||||
color_formats: TextureFormatPair<ImageFormat>,
|
||||
swizzle: Option<SwizzleSettings>,
|
||||
) -> Self {
|
||||
// On MBP integrated Intel GPUs, texture arrays appear to be
|
||||
// implemented as a single texture of stacked layers, and that
|
||||
// texture appears to be subject to the texture size limit. As such,
|
||||
// allocating more than 32 512x512 regions results in a dimension
|
||||
// longer than 16k (the max texture size), causing incorrect behavior.
|
||||
//
|
||||
// So we clamp the number of layers on mac. This results in maximum
|
||||
// texture array size of 32MB, which isn't ideal but isn't terrible
|
||||
// either. OpenGL on mac is not long for this earth, so this may be
|
||||
// good enough until we have WebRender on gfx-rs (on Metal).
|
||||
//
|
||||
// On all platforms, we also clamp the number of textures per layer to 16
|
||||
// to avoid the cost of resizing large texture arrays (at the expense
|
||||
// of batching efficiency).
|
||||
//
|
||||
// Note that we could also define this more generally in terms of
|
||||
// |max_texture_size / TEXTURE_REGION_DIMENSION|, except:
|
||||
// * max_texture_size is actually clamped beyond the device limit
|
||||
// by Gecko to 8192, so we'd need to thread the raw device value
|
||||
// here, and:
|
||||
// * The bug we're working around is likely specific to a single
|
||||
// driver family, and those drivers are also likely to share
|
||||
// the same max texture size of 16k. If we do encounter a driver
|
||||
// with the same bug but a lower max texture size, we might need
|
||||
// to rethink our strategy anyway, since a limit below 32MB might
|
||||
// start to introduce performance issues.
|
||||
max_texture_layers = max_texture_layers.min(16);
|
||||
|
||||
let pending_updates = TextureUpdateList::new();
|
||||
|
||||
// Shared texture cache controls swizzling on a per-entry basis, assuming that
|
||||
@@ -557,7 +526,6 @@ impl TextureCache {
|
||||
default_picture_tile_size,
|
||||
),
|
||||
max_texture_size,
|
||||
max_texture_layers,
|
||||
swizzle,
|
||||
debug_flags: DebugFlags::empty(),
|
||||
next_id: next_texture_id,
|
||||
@@ -577,12 +545,10 @@ impl TextureCache {
|
||||
#[cfg(test)]
|
||||
pub fn new_for_testing(
|
||||
max_texture_size: i32,
|
||||
max_texture_layers: usize,
|
||||
image_format: ImageFormat,
|
||||
) -> Self {
|
||||
let mut cache = Self::new(
|
||||
max_texture_size,
|
||||
max_texture_layers,
|
||||
crate::picture::TILE_SIZE_DEFAULT,
|
||||
TextureFormatPair::from(image_format),
|
||||
None,
|
||||
@@ -648,33 +614,33 @@ impl TextureCache {
|
||||
// Release of empty shared textures is done at the end of the frame. That way, if the
|
||||
// eviction at the start of the frame frees up a texture, that is then subsequently
|
||||
// used during the frame, we avoid doing a free/alloc for it.
|
||||
self.shared_textures.array_alpha8_linear.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.array_alpha16_linear.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.array_color8_linear.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.array_color8_nearest.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.array_color8_glyphs.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.alpha8_linear.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.alpha16_linear.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.color8_linear.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.color8_nearest.release_empty_textures(&mut self.pending_updates);
|
||||
self.shared_textures.color8_glyphs.release_empty_textures(&mut self.pending_updates);
|
||||
|
||||
self.shared_textures.array_alpha8_linear.update_profile(
|
||||
self.shared_textures.alpha8_linear.update_profile(
|
||||
profiler::TEXTURE_CACHE_A8_REGIONS,
|
||||
profiler::TEXTURE_CACHE_A8_MEM,
|
||||
profile,
|
||||
);
|
||||
self.shared_textures.array_alpha16_linear.update_profile(
|
||||
self.shared_textures.alpha16_linear.update_profile(
|
||||
profiler::TEXTURE_CACHE_A16_REGIONS,
|
||||
profiler::TEXTURE_CACHE_A16_MEM,
|
||||
profile,
|
||||
);
|
||||
self.shared_textures.array_color8_linear.update_profile(
|
||||
self.shared_textures.color8_linear.update_profile(
|
||||
profiler::TEXTURE_CACHE_RGBA8_LINEAR_REGIONS,
|
||||
profiler::TEXTURE_CACHE_RGBA8_LINEAR_MEM,
|
||||
profile,
|
||||
);
|
||||
self.shared_textures.array_color8_nearest.update_profile(
|
||||
self.shared_textures.color8_nearest.update_profile(
|
||||
profiler::TEXTURE_CACHE_RGBA8_NEAREST_REGIONS,
|
||||
profiler::TEXTURE_CACHE_RGBA8_NEAREST_MEM,
|
||||
profile,
|
||||
);
|
||||
self.shared_textures.array_color8_glyphs.update_profile(
|
||||
self.shared_textures.color8_glyphs.update_profile(
|
||||
profiler::TEXTURE_CACHE_RGBA8_GLYPHS_REGIONS,
|
||||
profiler::TEXTURE_CACHE_RGBA8_GLYPHS_MEM,
|
||||
profile,
|
||||
@@ -719,14 +685,9 @@ impl TextureCache {
|
||||
self.max_texture_size
|
||||
}
|
||||
|
||||
#[cfg(feature = "replay")]
|
||||
pub fn max_texture_layers(&self) -> usize {
|
||||
self.max_texture_layers
|
||||
}
|
||||
|
||||
#[cfg(feature = "replay")]
|
||||
pub fn color_formats(&self) -> TextureFormatPair<ImageFormat> {
|
||||
self.shared_textures.array_color8_linear.formats.clone()
|
||||
self.shared_textures.color8_linear.formats.clone()
|
||||
}
|
||||
|
||||
#[cfg(feature = "replay")]
|
||||
@@ -810,13 +771,12 @@ impl TextureCache {
|
||||
// texture format (thus avoiding the conversion by the driver).
|
||||
// Otherwise, pass the external format to the driver.
|
||||
let use_upload_format = self.swizzle.is_none();
|
||||
let (layer_index, origin) = entry.details.describe();
|
||||
let (_, origin) = entry.details.describe();
|
||||
let op = TextureCacheUpdate::new_update(
|
||||
data,
|
||||
&descriptor,
|
||||
origin,
|
||||
entry.size,
|
||||
layer_index as i32,
|
||||
use_upload_format,
|
||||
&dirty_rect,
|
||||
);
|
||||
@@ -913,11 +873,11 @@ impl TextureCache {
|
||||
}
|
||||
|
||||
pub fn dump_color8_linear_as_svg(&self, output: &mut dyn std::io::Write) -> std::io::Result<()> {
|
||||
self.shared_textures.array_color8_linear.dump_as_svg(output)
|
||||
self.shared_textures.color8_linear.dump_as_svg(output)
|
||||
}
|
||||
|
||||
pub fn dump_glyphs_as_svg(&self, output: &mut dyn std::io::Write) -> std::io::Result<()> {
|
||||
self.shared_textures.array_color8_glyphs.dump_as_svg(output)
|
||||
self.shared_textures.color8_glyphs.dump_as_svg(output)
|
||||
}
|
||||
|
||||
/// Expire picture cache tiles that haven't been referenced in the last frame.
|
||||
@@ -1025,14 +985,14 @@ impl TextureCache {
|
||||
// This is a standalone texture allocation. Free it directly.
|
||||
self.pending_updates.push_free(entry.texture_id);
|
||||
}
|
||||
EntryDetails::Cache { origin, layer_index, .. } => {
|
||||
EntryDetails::Cache { origin, region_index, .. } => {
|
||||
// Free the block in the given region.
|
||||
let texture_array = self.shared_textures.select(entry.input_format, entry.filter, entry.shader);
|
||||
let unit = texture_array.units
|
||||
.iter_mut()
|
||||
.find(|unit| unit.texture_id == entry.texture_id)
|
||||
.expect("Unable to find the associated texture array unit");
|
||||
let region = &mut unit.regions[layer_index];
|
||||
let region = &mut unit.regions[region_index];
|
||||
|
||||
self.shared_bytes_allocated -= region.slab_size.size_in_bytes(texture_array.formats.internal);
|
||||
|
||||
@@ -1045,7 +1005,7 @@ impl TextureCache {
|
||||
origin,
|
||||
region.slab_size.width,
|
||||
region.slab_size.height,
|
||||
layer_index,
|
||||
0,
|
||||
);
|
||||
}
|
||||
region.free(origin, &mut unit.empty_regions);
|
||||
@@ -1073,12 +1033,12 @@ impl TextureCache {
|
||||
}
|
||||
};
|
||||
|
||||
let max_texture_layers = self.max_texture_layers;
|
||||
let slab_size = SlabSize::new(params.descriptor.size);
|
||||
|
||||
let mut info = TextureCacheAllocInfo {
|
||||
width: TEXTURE_REGION_DIMENSIONS,
|
||||
height: TEXTURE_REGION_DIMENSIONS,
|
||||
let info = TextureCacheAllocInfo {
|
||||
target: ImageBufferKind::Texture2D,
|
||||
width: texture_array.regions_per_row * TEXTURE_REGION_DIMENSIONS,
|
||||
height: texture_array.regions_per_row * TEXTURE_REGION_DIMENSIONS,
|
||||
format: texture_array.formats.internal,
|
||||
filter: texture_array.filter,
|
||||
layer_count: 1,
|
||||
@@ -1090,32 +1050,22 @@ impl TextureCache {
|
||||
.iter()
|
||||
.position(|unit| unit.can_alloc(slab_size))
|
||||
{
|
||||
index
|
||||
} else if let Some(index) = texture_array.units
|
||||
.iter()
|
||||
.position(|unit| unit.regions.len() < max_texture_layers)
|
||||
{
|
||||
let unit = &mut texture_array.units[index];
|
||||
|
||||
unit.push_regions(texture_array.layers_per_allocation);
|
||||
|
||||
info.layer_count = unit.regions.len() as i32;
|
||||
self.pending_updates.push_realloc(unit.texture_id, info);
|
||||
|
||||
index
|
||||
} else {
|
||||
let index = texture_array.units.len();
|
||||
texture_array.units.push(TextureArrayUnit {
|
||||
let regions_per_row = texture_array.regions_per_row;
|
||||
texture_array.units.push(TextureUnit {
|
||||
texture_id: self.next_id,
|
||||
regions_per_row,
|
||||
regions: Vec::new(),
|
||||
empty_regions: 0,
|
||||
});
|
||||
|
||||
let num_regions = texture_array.regions_per_texture();
|
||||
let unit = &mut texture_array.units[index];
|
||||
|
||||
unit.push_regions(texture_array.layers_per_allocation);
|
||||
unit.push_regions(num_regions);
|
||||
|
||||
info.layer_count = unit.regions.len() as i32;
|
||||
self.pending_updates.push_alloc(self.next_id, info);
|
||||
self.next_id.0 += 1;
|
||||
index
|
||||
@@ -1169,6 +1119,7 @@ impl TextureCache {
|
||||
|
||||
// Push a command to allocate device storage of the right size / format.
|
||||
let info = TextureCacheAllocInfo {
|
||||
target: ImageBufferKind::Texture2D,
|
||||
width: params.descriptor.size.width,
|
||||
height: params.descriptor.size.height,
|
||||
format: params.descriptor.format,
|
||||
@@ -1275,11 +1226,11 @@ impl TextureCache {
|
||||
}
|
||||
|
||||
pub fn shared_alpha_expected_format(&self) -> ImageFormat {
|
||||
self.shared_textures.array_alpha8_linear.formats.external
|
||||
self.shared_textures.alpha8_linear.formats.external
|
||||
}
|
||||
|
||||
pub fn shared_color_expected_format(&self) -> ImageFormat {
|
||||
self.shared_textures.array_color8_linear.formats.external
|
||||
self.shared_textures.color8_linear.formats.external
|
||||
}
|
||||
|
||||
|
||||
@@ -1351,23 +1302,23 @@ impl TextureLocation {
|
||||
}
|
||||
}
|
||||
|
||||
/// A region corresponds to a layer in a shared cache texture.
|
||||
///
|
||||
/// All allocations within a region are of the same size.
|
||||
/// A region is a rectangular part of a texture cache texture, split into fixed-size slabs.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
struct TextureRegion {
|
||||
layer_index: usize,
|
||||
index: usize,
|
||||
slab_size: SlabSize,
|
||||
offset: DeviceIntPoint,
|
||||
free_slots: Vec<TextureLocation>,
|
||||
total_slot_count: usize,
|
||||
}
|
||||
|
||||
impl TextureRegion {
|
||||
fn new(layer_index: usize) -> Self {
|
||||
fn new(index: usize, offset: DeviceIntPoint) -> Self {
|
||||
TextureRegion {
|
||||
layer_index,
|
||||
index,
|
||||
slab_size: SlabSize::invalid(),
|
||||
offset,
|
||||
free_slots: Vec::new(),
|
||||
total_slot_count: 0,
|
||||
}
|
||||
@@ -1411,17 +1362,17 @@ impl TextureRegion {
|
||||
debug_assert!(self.slab_size != SlabSize::invalid());
|
||||
|
||||
self.free_slots.pop().map(|location| {
|
||||
DeviceIntPoint::new(
|
||||
self.slab_size.width * location.0 as i32,
|
||||
self.slab_size.height * location.1 as i32,
|
||||
point2(
|
||||
self.offset.x + self.slab_size.width * location.0 as i32,
|
||||
self.offset.y + self.slab_size.height * location.1 as i32,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// Free a block in this region.
|
||||
fn free(&mut self, point: DeviceIntPoint, empty_regions: &mut usize) {
|
||||
let x = point.x / self.slab_size.width;
|
||||
let y = point.y / self.slab_size.height;
|
||||
let x = (point.x - self.offset.x) / self.slab_size.width;
|
||||
let y = (point.y - self.offset.y) / self.slab_size.height;
|
||||
self.free_slots.push(TextureLocation::new(x, y));
|
||||
|
||||
// If this region is completely unused, deinit it
|
||||
@@ -1433,25 +1384,35 @@ impl TextureRegion {
|
||||
}
|
||||
}
|
||||
|
||||
/// A 2D texture divided into regions.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
struct TextureArrayUnit {
|
||||
struct TextureUnit {
|
||||
texture_id: CacheTextureId,
|
||||
regions: Vec<TextureRegion>,
|
||||
empty_regions: usize,
|
||||
regions_per_row: i32,
|
||||
}
|
||||
|
||||
impl TextureArrayUnit {
|
||||
impl TextureUnit {
|
||||
/// Adds a new empty region to the array.
|
||||
fn push_regions(&mut self, count: i32) {
|
||||
assert!(self.empty_regions <= self.regions.len());
|
||||
for _ in 0..count {
|
||||
let index = self.regions.len();
|
||||
self.regions.push(TextureRegion::new(index));
|
||||
let offset = self.region_offset(index as i32);
|
||||
self.regions.push(TextureRegion::new(index, offset));
|
||||
self.empty_regions += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn region_offset(&self, index: i32) -> DeviceIntPoint {
|
||||
point2(
|
||||
(index % self.regions_per_row) * TEXTURE_REGION_DIMENSIONS,
|
||||
(index / self.regions_per_row) * TEXTURE_REGION_DIMENSIONS,
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns true if we can allocate the given entry.
|
||||
fn can_alloc(&self, slab_size: SlabSize) -> bool {
|
||||
self.empty_regions != 0 || self.regions.iter().any(|region| {
|
||||
@@ -1464,31 +1425,35 @@ impl TextureArrayUnit {
|
||||
}
|
||||
}
|
||||
|
||||
/// A texture array contains a number of textures, each with a number of
|
||||
/// layers, where each layer contains a region that can act as a slab allocator.
|
||||
/// A number of 2D textures (single layer), each with a number of
|
||||
/// regions that can act as a slab allocator.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
struct TextureArray {
|
||||
struct TextureUnits {
|
||||
filter: TextureFilter,
|
||||
formats: TextureFormatPair<ImageFormat>,
|
||||
units: SmallVec<[TextureArrayUnit; 1]>,
|
||||
layers_per_allocation: i32,
|
||||
units: SmallVec<[TextureUnit; 1]>,
|
||||
regions_per_row: i32,
|
||||
}
|
||||
|
||||
impl TextureArray {
|
||||
impl TextureUnits {
|
||||
fn new(
|
||||
formats: TextureFormatPair<ImageFormat>,
|
||||
filter: TextureFilter,
|
||||
layers_per_allocation: i32,
|
||||
regions_per_row: i32,
|
||||
) -> Self {
|
||||
TextureArray {
|
||||
TextureUnits {
|
||||
formats,
|
||||
filter,
|
||||
units: SmallVec::new(),
|
||||
layers_per_allocation,
|
||||
regions_per_row,
|
||||
}
|
||||
}
|
||||
|
||||
fn regions_per_texture(&self) -> i32 {
|
||||
self.regions_per_row * self.regions_per_row
|
||||
}
|
||||
|
||||
/// Returns the number of GPU bytes consumed by this texture array.
|
||||
fn size_in_bytes(&self) -> usize {
|
||||
let bpp = self.formats.internal.bytes_per_pixel() as usize;
|
||||
@@ -1553,7 +1518,7 @@ impl TextureArray {
|
||||
} else if region.slab_size == slab_size {
|
||||
if let Some(location) = region.alloc() {
|
||||
entry_details = Some(EntryDetails::Cache {
|
||||
layer_index: region.layer_index,
|
||||
region_index: region.index,
|
||||
origin: location,
|
||||
});
|
||||
break;
|
||||
@@ -1568,7 +1533,7 @@ impl TextureArray {
|
||||
let region = &mut unit.regions[empty_region_index.unwrap()];
|
||||
region.init(slab_size, &mut unit.empty_regions);
|
||||
EntryDetails::Cache {
|
||||
layer_index: region.layer_index,
|
||||
region_index: region.index,
|
||||
origin: region.alloc().unwrap(),
|
||||
}
|
||||
}
|
||||
@@ -1596,15 +1561,15 @@ impl TextureArray {
|
||||
use svg_fmt::*;
|
||||
|
||||
let num_arrays = self.units.len() as f32;
|
||||
let num_layers = self.layers_per_allocation as f32;
|
||||
let num_regions = self.regions_per_texture() as f32;
|
||||
|
||||
let text_spacing = 15.0;
|
||||
let array_spacing = 60.0;
|
||||
let layer_spacing = 10.0;
|
||||
let layer_size = 100.0;
|
||||
let unit_spacing = 10.0;
|
||||
let unit_size = 100.0;
|
||||
|
||||
let svg_w = array_spacing * 2.0 + num_layers * (layer_size + layer_spacing);
|
||||
let svg_h = layer_spacing * 2.0 + num_arrays * (text_spacing * 2.0 + array_spacing + layer_size);
|
||||
let svg_w = array_spacing * 2.0 + num_regions * (unit_size + unit_spacing);
|
||||
let svg_h = unit_spacing * 2.0 + num_arrays * (text_spacing * 2.0 + array_spacing + unit_size);
|
||||
|
||||
writeln!(output, "{}", BeginSvg { w: svg_w, h: svg_h })?;
|
||||
|
||||
@@ -1635,13 +1600,12 @@ impl TextureArray {
|
||||
|
||||
let y = y + text_spacing;
|
||||
|
||||
// Texture array layer.
|
||||
let layer_background = if region.is_empty() { rgb(30, 30, 30) } else { rgb(40, 40, 130) };
|
||||
writeln!(output, " {}", rectangle(x, y, layer_size, layer_size).inflate(1.0, 1.0).fill(rgb(10, 10, 10)))?;
|
||||
writeln!(output, " {}", rectangle(x, y, layer_size, layer_size).fill(layer_background))?;
|
||||
let texture_background = if region.is_empty() { rgb(30, 30, 30) } else { rgb(40, 40, 130) };
|
||||
writeln!(output, " {}", rectangle(x, y, unit_size, unit_size).inflate(1.0, 1.0).fill(rgb(10, 10, 10)))?;
|
||||
writeln!(output, " {}", rectangle(x, y, unit_size, unit_size).fill(texture_background))?;
|
||||
|
||||
let sw = (slab_size.width as f32 / 512.0) * layer_size;
|
||||
let sh = (slab_size.height as f32 / 512.0) * layer_size;
|
||||
let sw = (slab_size.width as f32 / 512.0) * unit_size;
|
||||
let sh = (slab_size.height as f32 / 512.0) * unit_size;
|
||||
|
||||
for slot in ®ion.free_slots {
|
||||
let sx = x + slot.0 as f32 * sw;
|
||||
@@ -1651,10 +1615,10 @@ impl TextureArray {
|
||||
writeln!(output, " {}", rectangle(sx, sy, sw, sh).inflate(-0.5, -0.5).fill(rgb(30, 30, 30)))?;
|
||||
}
|
||||
|
||||
x += layer_spacing + layer_size;
|
||||
x += unit_spacing + unit_size;
|
||||
}
|
||||
|
||||
y += array_spacing + layer_size;
|
||||
y += array_spacing + unit_size;
|
||||
x = array_spacing;
|
||||
}
|
||||
|
||||
@@ -1686,6 +1650,7 @@ struct WholeTextureArray {
|
||||
impl WholeTextureArray {
|
||||
fn to_info(&self) -> TextureCacheAllocInfo {
|
||||
TextureCacheAllocInfo {
|
||||
target: ImageBufferKind::Texture2DArray,
|
||||
width: self.size.width,
|
||||
height: self.size.height,
|
||||
format: self.format,
|
||||
@@ -1764,7 +1729,6 @@ impl TextureCacheUpdate {
|
||||
descriptor: &ImageDescriptor,
|
||||
origin: DeviceIntPoint,
|
||||
size: DeviceIntSize,
|
||||
layer_index: i32,
|
||||
use_upload_format: bool,
|
||||
dirty_rect: &ImageDirtyRect,
|
||||
) -> TextureCacheUpdate {
|
||||
@@ -1814,7 +1778,7 @@ impl TextureCacheUpdate {
|
||||
stride: Some(stride),
|
||||
offset,
|
||||
format_override,
|
||||
layer_index,
|
||||
layer_index: 0,
|
||||
}
|
||||
}
|
||||
DirtyRect::All => {
|
||||
@@ -1824,7 +1788,7 @@ impl TextureCacheUpdate {
|
||||
stride: descriptor.stride,
|
||||
offset: descriptor.offset,
|
||||
format_override,
|
||||
layer_index,
|
||||
layer_index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,26 +102,26 @@ pub trait ExternalImageHandler {
|
||||
|
||||
/// Specifies the type of texture target in driver terms.
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub enum TextureTarget {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
||||
pub enum ImageBufferKind {
|
||||
/// Standard texture. This maps to GL_TEXTURE_2D in OpenGL.
|
||||
Default = 0,
|
||||
/// Array texture. This maps to GL_TEXTURE_2D_ARRAY in OpenGL. See
|
||||
/// https://www.khronos.org/opengl/wiki/Array_Texture for background
|
||||
/// on Array textures.
|
||||
Array = 1,
|
||||
Texture2D = 0,
|
||||
/// Rectangle texture. This maps to GL_TEXTURE_RECTANGLE in OpenGL. This
|
||||
/// is similar to a standard texture, with a few subtle differences
|
||||
/// (no mipmaps, non-power-of-two dimensions, different coordinate space)
|
||||
/// that make it useful for representing the kinds of textures we use
|
||||
/// in WebRender. See https://www.khronos.org/opengl/wiki/Rectangle_Texture
|
||||
/// for background on Rectangle textures.
|
||||
Rect = 2,
|
||||
TextureRect = 1,
|
||||
/// External texture. This maps to GL_TEXTURE_EXTERNAL_OES in OpenGL, which
|
||||
/// is an extension. This is used for image formats that OpenGL doesn't
|
||||
/// understand, particularly YUV. See
|
||||
/// https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt
|
||||
External = 3,
|
||||
TextureExternal = 2,
|
||||
/// Array texture. This maps to GL_TEXTURE_2D_ARRAY in OpenGL. See
|
||||
/// https://www.khronos.org/opengl/wiki/Array_Texture for background
|
||||
/// on Array textures.
|
||||
Texture2DArray = 3,
|
||||
}
|
||||
|
||||
/// Storage format identifier for externally-managed images.
|
||||
@@ -129,7 +129,7 @@ pub enum TextureTarget {
|
||||
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ExternalImageType {
|
||||
/// The image is texture-backed.
|
||||
TextureHandle(TextureTarget),
|
||||
TextureHandle(ImageBufferKind),
|
||||
/// The image is heap-allocated by the embedding.
|
||||
Buffer,
|
||||
}
|
||||
|
||||
@@ -65,9 +65,8 @@ pub fn get_shader_features(flags: ShaderFeatureFlags) -> ShaderFeatures {
|
||||
|
||||
// Clip shaders
|
||||
shaders.insert("cs_clip_rectangle", vec![String::new(), "FAST_PATH".to_string()]);
|
||||
for name in &["cs_clip_image", "cs_clip_box_shadow"] {
|
||||
shaders.insert(name, vec![String::new()]);
|
||||
}
|
||||
shaders.insert("cs_clip_image", vec!["TEXTURE_2D".to_string()]);
|
||||
shaders.insert("cs_clip_box_shadow", vec!["TEXTURE_2D".to_string()]);
|
||||
|
||||
// Cache shaders
|
||||
shaders.insert("cs_blur", vec!["ALPHA_TARGET".to_string(), "COLOR_TARGET".to_string()]);
|
||||
@@ -186,7 +185,7 @@ pub fn get_shader_features(flags: ShaderFeatureFlags) -> ShaderFeatures {
|
||||
}
|
||||
let mut text_features: Vec<String> = Vec::new();
|
||||
for text_type in &text_types {
|
||||
let mut list = base_prim_features.clone();
|
||||
let mut list = base_prim_features.with("TEXTURE_2D");
|
||||
if !text_type.is_empty() {
|
||||
list.add(text_type);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ impl LocalExternalImageHandler {
|
||||
pub fn add_image(&mut self,
|
||||
device: &webrender::Device,
|
||||
desc: ImageDescriptor,
|
||||
target: TextureTarget,
|
||||
target: ImageBufferKind,
|
||||
image_data: ImageData,
|
||||
) -> ImageData {
|
||||
let (image_id, channel_idx) = match image_data {
|
||||
@@ -754,13 +754,13 @@ impl YamlFrameReader {
|
||||
// ensure it gets created as such
|
||||
let external_target = match item["external-target"].as_str() {
|
||||
Some(ref s) => match &s[..] {
|
||||
"2d" => TextureTarget::Default,
|
||||
"array" => TextureTarget::Array,
|
||||
"rect" => TextureTarget::Rect,
|
||||
"2d" => ImageBufferKind::Texture2D,
|
||||
"array" => ImageBufferKind::Texture2DArray,
|
||||
"rect" => ImageBufferKind::TextureRect,
|
||||
_ => panic!("Unsupported external texture target."),
|
||||
}
|
||||
None => {
|
||||
TextureTarget::Default
|
||||
ImageBufferKind::Texture2D
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user