Bug 1624264 - Use different texture cache sizes for popup windows. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D99771
This commit is contained in:
Nicolas Silva 2020-12-18 09:27:19 +00:00
parent 8f053bc4d0
commit 316d3394f3
17 changed files with 103 additions and 30 deletions

View File

@ -165,6 +165,11 @@ struct LayersObserverEpoch {
class CompositionOpportunityType {};
typedef BaseTransactionId<CompositionOpportunityType> CompositionOpportunityId;
/// We make different decisions about resource allocation sizes in WebRender
/// depending on whether we are going to render web pages or simpler
/// content in the window.
enum class WindowKind : int8_t { MAIN = 0, SECONDARY, LAST };
enum class LayersBackend : int8_t {
LAYERS_NONE = 0,
LAYERS_BASIC,

View File

@ -1093,7 +1093,8 @@ bool CompositorBridgeChild::DeallocPAPZCTreeManagerChild(
void CompositorBridgeChild::WillEndTransaction() { ResetShmemCounter(); }
PWebRenderBridgeChild* CompositorBridgeChild::AllocPWebRenderBridgeChild(
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize&) {
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize&,
const WindowKind&) {
WebRenderBridgeChild* child = new WebRenderBridgeChild(aPipelineId);
child->AddIPDLReference();
return child;

View File

@ -228,7 +228,8 @@ class CompositorBridgeChild final : public PCompositorBridgeChild,
void WillEndTransaction();
PWebRenderBridgeChild* AllocPWebRenderBridgeChild(
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize&);
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize&,
const WindowKind&);
bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor);
webgpu::PWebGPUChild* AllocPWebGPUChild();

View File

@ -1864,7 +1864,8 @@ mozilla::ipc::IPCResult CompositorBridgeParent::RecvAdoptChild(
}
PWebRenderBridgeParent* CompositorBridgeParent::AllocPWebRenderBridgeParent(
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize) {
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize,
const WindowKind& aWindowKind) {
MOZ_ASSERT(wr::AsLayersId(aPipelineId) == mRootLayerTreeID);
MOZ_ASSERT(!mWrBridge);
MOZ_ASSERT(!mCompositor);
@ -1896,8 +1897,8 @@ PWebRenderBridgeParent* CompositorBridgeParent::AllocPWebRenderBridgeParent(
}
nsCString error("FEATURE_FAILTURE_WEBRENDER_INITIALIZE_UNSPECIFIED");
RefPtr<wr::WebRenderAPI> api =
wr::WebRenderAPI::Create(this, std::move(widget), windowId, aSize, error);
RefPtr<wr::WebRenderAPI> api = wr::WebRenderAPI::Create(
this, std::move(widget), windowId, aSize, aWindowKind, error);
if (!api) {
mWrBridge =
WebRenderBridgeParent::CreateDestroyed(aPipelineId, std::move(error));

View File

@ -242,7 +242,8 @@ class CompositorBridgeParentBase : public PCompositorBridgeParent,
virtual bool DeallocPTextureParent(PTextureParent* aActor) = 0;
virtual PWebRenderBridgeParent* AllocPWebRenderBridgeParent(
const PipelineId& pipelineId, const LayoutDeviceIntSize& aSize) = 0;
const PipelineId& pipelineId, const LayoutDeviceIntSize& aSize,
const WindowKind& aWindowKind) = 0;
virtual bool DeallocPWebRenderBridgeParent(
PWebRenderBridgeParent* aActor) = 0;
@ -665,8 +666,8 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
}
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(
const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize& aSize) override;
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize,
const WindowKind& aWindowKind) override;
bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;
RefPtr<WebRenderBridgeParent> GetWebRenderBridgeParent() const;
Maybe<TimeStamp> GetTestingTimeStamp() const;

View File

@ -201,7 +201,8 @@ bool ContentCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor) {
PWebRenderBridgeParent*
ContentCompositorBridgeParent::AllocPWebRenderBridgeParent(
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize) {
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize,
const WindowKind& aWindowKind) {
LayersId layersId = wr::AsLayersId(aPipelineId);
// Check to see if this child process has access to this layer tree.
if (!LayerTreeOwnerTracker::Get()->IsMapped(layersId, OtherPid())) {

View File

@ -202,8 +202,8 @@ class ContentCompositorBridgeParent final : public CompositorBridgeParentBase {
const nsTArray<CompositionPayload>& aPayload) override;
PWebRenderBridgeParent* AllocPWebRenderBridgeParent(
const wr::PipelineId& aPipelineId,
const LayoutDeviceIntSize& aSize) override;
const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize,
const WindowKind& aWindowKind) override;
bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;
webgpu::PWebGPUParent* AllocPWebGPUParent() override;

View File

@ -94,6 +94,12 @@ template <>
struct ParamTraits<mozilla::layers::LayersObserverEpoch>
: public PlainOldDataSerializer<mozilla::layers::LayersObserverEpoch> {};
template <>
struct ParamTraits<mozilla::layers::WindowKind>
: public ContiguousEnumSerializer<mozilla::layers::WindowKind,
mozilla::layers::WindowKind::MAIN,
mozilla::layers::WindowKind::LAST> {};
template <>
struct ParamTraits<mozilla::layers::LayersBackend>
: public ContiguousEnumSerializer<

View File

@ -30,6 +30,7 @@ using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/Comp
using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
using mozilla::layers::ScrollableLayerGuid::ViewID from "mozilla/layers/ScrollableLayerGuid.h";
using mozilla::layers::MaybeZoomConstraints from "mozilla/layers/ZoomConstraints.h";
using mozilla::layers::WindowKind from "mozilla/layers/LayersTypes.h";
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
using mozilla::CrossProcessMutexHandle from "mozilla/ipc/CrossProcessMutex.h";
using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
@ -273,7 +274,7 @@ parent:
sync SyncWithCompositor();
// The pipelineId is the same as the layersId
async PWebRenderBridge(PipelineId pipelineId, LayoutDeviceIntSize aSize);
async PWebRenderBridge(PipelineId pipelineId, LayoutDeviceIntSize aSize, WindowKind aKind);
sync CheckContentOnlyTDR(uint32_t sequenceNum)
returns (bool isContentOnlyTDR);

View File

@ -68,9 +68,16 @@ bool WebRenderLayerManager::Initialize(
// succeeded, or if this is the first attempt.
static bool hasInitialized = false;
WindowKind windowKind;
if (mWidget->WindowType() == eWindowType_toplevel) {
windowKind = WindowKind::MAIN;
} else {
windowKind = WindowKind::SECONDARY;
}
LayoutDeviceIntSize size = mWidget->GetClientSize();
PWebRenderBridgeChild* bridge =
aCBChild->SendPWebRenderBridgeConstructor(aLayersId, size);
aCBChild->SendPWebRenderBridgeConstructor(aLayersId, size, windowKind);
if (!bridge) {
// This should only fail if we attempt to access a layer we don't have
// permission for, or more likely, the GPU process crashed again during

View File

@ -65,7 +65,8 @@ class NewRenderer : public RendererEvent {
bool* aUseTripleBuffering, bool* aSupportsExternalBufferTextures,
RefPtr<widget::CompositorWidget>&& aWidget,
layers::SynchronousTask* aTask, LayoutDeviceIntSize aSize,
layers::SyncHandle* aHandle, nsACString* aError)
layers::WindowKind aWindowKind, layers::SyncHandle* aHandle,
nsACString* aError)
: mDocHandle(aDocHandle),
mBackend(aBackend),
mCompositor(aCompositor),
@ -78,6 +79,7 @@ class NewRenderer : public RendererEvent {
mCompositorWidget(std::move(aWidget)),
mTask(aTask),
mSize(aSize),
mWindowKind(aWindowKind),
mSyncHandle(aHandle),
mError(aError) {
MOZ_COUNT_CTOR(NewRenderer);
@ -126,8 +128,8 @@ class NewRenderer : public RendererEvent {
if (!wr_window_new(
aWindowId, mSize.width, mSize.height,
supportLowPriorityTransactions, supportLowPriorityThreadpool,
gfx::gfxVars::UseGLSwizzle(),
mWindowKind == WindowKind::MAIN, supportLowPriorityTransactions,
supportLowPriorityThreadpool, gfx::gfxVars::UseGLSwizzle(),
gfx::gfxVars::UseWebRenderScissoredCacheClears(),
#ifdef NIGHTLY_BUILD
StaticPrefs::gfx_webrender_start_debug_server(),
@ -194,6 +196,7 @@ class NewRenderer : public RendererEvent {
RefPtr<widget::CompositorWidget> mCompositorWidget;
layers::SynchronousTask* mTask;
LayoutDeviceIntSize mSize;
layers::WindowKind mWindowKind;
layers::SyncHandle* mSyncHandle;
nsACString* mError;
};
@ -344,7 +347,8 @@ void TransactionWrapper::UpdateIsTransformAsyncZooming(uint64_t aAnimationId,
already_AddRefed<WebRenderAPI> WebRenderAPI::Create(
layers::CompositorBridgeParent* aBridge,
RefPtr<widget::CompositorWidget>&& aWidget, const wr::WrWindowId& aWindowId,
LayoutDeviceIntSize aSize, nsACString& aError) {
LayoutDeviceIntSize aSize, layers::WindowKind aWindowKind,
nsACString& aError) {
MOZ_ASSERT(aBridge);
MOZ_ASSERT(aWidget);
static_assert(
@ -368,7 +372,7 @@ already_AddRefed<WebRenderAPI> WebRenderAPI::Create(
auto event = MakeUnique<NewRenderer>(
&docHandle, aBridge, &backend, &compositor, &maxTextureSize, &useANGLE,
&useDComp, &useTripleBuffering, &supportsExternalBufferTextures,
std::move(aWidget), &task, aSize, &syncHandle, &aError);
std::move(aWidget), &task, aSize, aWindowKind, &syncHandle, &aError);
RenderThread::Get()->RunEvent(aWindowId, std::move(event));
task.Wait();

View File

@ -235,7 +235,7 @@ class WebRenderAPI final {
layers::CompositorBridgeParent* aBridge,
RefPtr<widget::CompositorWidget>&& aWidget,
const wr::WrWindowId& aWindowId, LayoutDeviceIntSize aSize,
nsACString& aError);
layers::WindowKind aWindowKind, nsACString& aError);
already_AddRefed<WebRenderAPI> Clone();

View File

@ -38,7 +38,7 @@ use webrender::{
CompositorCapabilities, CompositorConfig, CompositorSurfaceTransform, DebugFlags, Device, NativeSurfaceId,
NativeSurfaceInfo, NativeTileId, PartialPresentCompositor, PipelineInfo, ProfilerHooks, RecordedFrameHandle,
Renderer, RendererOptions, RendererStats, SceneBuilderHooks, ShaderPrecacheFlags, Shaders, ThreadListener,
UploadMethod, WrShaders, ONE_TIME_USAGE_HINT,
UploadMethod, WrShaders, ONE_TIME_USAGE_HINT, TextureCacheConfig,
};
use wr_malloc_size_of::MallocSizeOfOps;
@ -1456,6 +1456,7 @@ pub extern "C" fn wr_window_new(
window_id: WrWindowId,
window_width: i32,
window_height: i32,
is_main_window: bool,
support_low_priority_transactions: bool,
support_low_priority_threadpool: bool,
allow_texture_swizzling: bool,
@ -1580,6 +1581,18 @@ pub extern "C" fn wr_window_new(
None
};
let texture_cache_config = if is_main_window {
TextureCacheConfig::DEFAULT
} else {
TextureCacheConfig {
color8_linear_texture_size: 512,
color8_nearest_texture_size: 512,
color8_glyph_texture_size: 512,
alpha8_texture_size: 512,
alpha16_texture_size: 512,
}
};
let opts = RendererOptions {
enable_aa: true,
force_subpixel_aa: false,
@ -1625,6 +1638,7 @@ pub extern "C" fn wr_window_new(
enable_gpu_markers,
panic_on_gl_error,
picture_tile_size,
texture_cache_config,
..Default::default()
};

View File

@ -229,6 +229,7 @@ pub use crate::hit_test::SharedHitTester;
pub use crate::internal_types::FastHashMap;
pub use crate::screen_capture::{AsyncScreenshotHandle, RecordedFrameHandle};
pub use crate::shade::{Shaders, WrShaders};
pub use crate::texture_cache::TextureCacheConfig;
pub use api as webrender_api;
pub use webrender_build::shader::ProgramSourceDigest;
pub use crate::picture::{TileDescriptor, TileId, InvalidationReason};

View File

@ -93,7 +93,7 @@ use crate::scene_builder_thread::{SceneBuilderThread, SceneBuilderThreadChannels
use crate::screen_capture::AsyncScreenshotGrabber;
use crate::shade::{Shaders, WrShaders};
use crate::guillotine_allocator::{GuillotineAllocator, FreeRectSlice};
use crate::texture_cache::TextureCache;
use crate::texture_cache::{TextureCache, TextureCacheConfig};
use crate::render_target::{AlphaRenderTarget, ColorRenderTarget, PictureCacheTarget};
use crate::render_target::{RenderTarget, TextureCacheRenderTarget};
use crate::render_target::{RenderTargetKind, BlitJob, BlitJobSource};
@ -2511,6 +2511,7 @@ impl Renderer {
.as_ref()
.map(|handler| handler.create_similar());
let texture_cache_config = options.texture_cache_config.clone();
let mut picture_tile_size = options.picture_tile_size.unwrap_or(picture::TILE_SIZE_DEFAULT);
// Clamp the picture tile size to reasonable values.
picture_tile_size.width = picture_tile_size.width.max(128).min(4096);
@ -2531,6 +2532,7 @@ impl Renderer {
picture_tile_size,
color_cache_formats,
swizzle_settings,
&texture_cache_config,
);
let glyph_cache = GlyphCache::new();
@ -6939,6 +6941,7 @@ pub struct RendererOptions {
/// performance impact, so only use when debugging specific problems!
pub panic_on_gl_error: bool,
pub picture_tile_size: Option<DeviceIntSize>,
pub texture_cache_config: TextureCacheConfig,
}
impl RendererOptions {
@ -7007,6 +7010,7 @@ impl Default for RendererOptions {
enable_gpu_markers: true,
panic_on_gl_error: false,
picture_tile_size: None,
texture_cache_config: TextureCacheConfig::DEFAULT,
}
}
}

View File

@ -1941,6 +1941,7 @@ impl ResourceCache {
config: &CaptureConfig,
) -> Vec<PlainExternalImage> {
use std::{fs, path::Path};
use crate::texture_cache::TextureCacheConfig;
info!("loading resource cache");
//TODO: instead of filling the local path to Arc<data> map as we process
@ -1967,6 +1968,7 @@ impl ResourceCache {
self.texture_cache.default_picture_tile_size(),
self.texture_cache.color_formats(),
self.texture_cache.swizzle_settings(),
&TextureCacheConfig::DEFAULT,
);
}
}

View File

@ -27,6 +27,7 @@ use std::mem;
use std::rc::Rc;
use euclid::size2;
/// Information about which shader will use the entry.
///
/// For batching purposes, it's beneficial to group some items in their
@ -244,7 +245,7 @@ struct SharedTextures {
impl SharedTextures {
/// Mints a new set of shared textures.
fn new(color_formats: TextureFormatPair<ImageFormat>) -> Self {
fn new(color_formats: TextureFormatPair<ImageFormat>, config: &TextureCacheConfig) -> Self {
Self {
// Used primarily for cached shadow masks. There can be lots of
// these on some pages like francine, but most pages don't use it
@ -255,7 +256,7 @@ impl SharedTextures {
// whether it would actually lead to a lot of batch breaks in
// practice.
alpha8_linear: AllocatorList::new(
1024,
config.alpha8_texture_size,
ShelfAllocatorOptions {
num_columns: 1,
alignment: size2(8, 8),
@ -269,7 +270,7 @@ impl SharedTextures {
// Used for experimental hdr yuv texture support, but not used in
// production Firefox.
alpha16_linear: AllocatorList::new(
TEXTURE_REGION_DIMENSIONS,
config.alpha16_texture_size,
SlabAllocatorParameters {
region_size: TEXTURE_REGION_DIMENSIONS,
},
@ -280,9 +281,9 @@ impl SharedTextures {
),
// The primary cache for images, etc.
color8_linear: AllocatorList::new(
2048,
config.color8_linear_texture_size,
ShelfAllocatorOptions {
num_columns: 2,
num_columns: if config.color8_linear_texture_size >= 1024 { 2 } else { 1 },
alignment: size2(16, 16),
.. ShelfAllocatorOptions::default()
},
@ -293,9 +294,9 @@ impl SharedTextures {
),
// The cache for glyphs (separate to help with batching).
color8_glyphs: AllocatorList::new(
2048,
config.color8_glyph_texture_size,
ShelfAllocatorOptions {
num_columns: 2,
num_columns: if config.color8_glyph_texture_size >= 1024 { 2 } else { 1 },
alignment: size2(4, 8),
.. ShelfAllocatorOptions::default()
},
@ -308,7 +309,7 @@ impl SharedTextures {
// 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.
color8_nearest: AllocatorList::new(
512,
config.color8_nearest_texture_size,
ShelfAllocatorOptions::default(),
TextureParameters {
formats: color_formats,
@ -458,6 +459,28 @@ struct CacheAllocParams {
shader: TargetShader,
}
/// Startup parameters for the texture cache.
///
/// Texture sizes must be at least 512.
#[derive(Clone)]
pub struct TextureCacheConfig {
pub color8_linear_texture_size: i32,
pub color8_nearest_texture_size: i32,
pub color8_glyph_texture_size: i32,
pub alpha8_texture_size: i32,
pub alpha16_texture_size: i32,
}
impl TextureCacheConfig {
pub const DEFAULT: Self = TextureCacheConfig {
color8_linear_texture_size: 2048,
color8_nearest_texture_size: 512,
color8_glyph_texture_size: 2048,
alpha8_texture_size: 1024,
alpha16_texture_size: 512,
};
}
/// General-purpose manager for images in GPU memory. This includes images,
/// rasterized glyphs, rasterized blobs, cached render tasks, etc.
///
@ -542,6 +565,7 @@ impl TextureCache {
default_picture_tile_size: DeviceIntSize,
color_formats: TextureFormatPair<ImageFormat>,
swizzle: Option<SwizzleSettings>,
config: &TextureCacheConfig,
) -> Self {
let pending_updates = TextureUpdateList::new();
@ -555,7 +579,7 @@ impl TextureCache {
let next_texture_id = CacheTextureId(1);
TextureCache {
shared_textures: SharedTextures::new(color_formats),
shared_textures: SharedTextures::new(color_formats, config),
picture_textures: PictureTextures::new(
default_picture_tile_size,
),