Backed out 3 changesets (bug 1656533, bug 1575765) for WebRender bustages. CLOSED TREE

Backed out changeset 84c31fd9ff82 (bug 1575765)
Backed out changeset 48c1532d1d9d (bug 1575765)
Backed out changeset ed9075d9319b (bug 1656533)
This commit is contained in:
Razvan Maries 2020-10-02 12:51:55 +03:00
Родитель e0889bffdf
Коммит 63b41aa30f
16 изменённых файлов: 35 добавлений и 307 удалений

Просмотреть файл

@ -98,8 +98,7 @@ class GLContextEGL final : public GLContext {
EGLSurface GetEGLSurface() const { return mSurface; }
bool HasExtBufferAge() const;
bool HasKhrPartialUpdate() const;
bool HasBufferAge() const;
EGLint GetBufferAge() const;
bool BindTex2DOffscreen(GLContext* aOffscreen);

Просмотреть файл

@ -599,19 +599,15 @@ void GLContextEGL::GetWSIInfo(nsCString* const out) const {
// for the lifetime of this context.
void GLContextEGL::HoldSurface(gfxASurface* aSurf) { mThebesSurface = aSurf; }
bool GLContextEGL::HasExtBufferAge() const {
bool GLContextEGL::HasBufferAge() const {
return mEgl->IsExtensionSupported(EGLExtension::EXT_buffer_age);
}
bool GLContextEGL::HasKhrPartialUpdate() const {
return mEgl->IsExtensionSupported(EGLExtension::KHR_partial_update);
}
EGLint GLContextEGL::GetBufferAge() const {
EGLSurface surface =
mSurfaceOverride != EGL_NO_SURFACE ? mSurfaceOverride : mSurface;
if (surface && (HasExtBufferAge() || HasKhrPartialUpdate())) {
if (surface && HasBufferAge()) {
EGLint result;
mEgl->fQuerySurface(surface, LOCAL_EGL_BUFFER_AGE_EXT, &result);
return result;

Просмотреть файл

@ -76,8 +76,7 @@ static const char* sEGLExtensionNames[] = {
"EGL_MOZ_create_context_provoking_vertex_dont_care",
"EGL_EXT_swap_buffers_with_damage",
"EGL_KHR_swap_buffers_with_damage",
"EGL_EXT_buffer_age",
"EGL_KHR_partial_update"};
"EGL_EXT_buffer_age"};
PRLibrary* LoadApitraceLibrary() {
const char* path = nullptr;
@ -600,12 +599,6 @@ bool GLLibraryEGL::Init(nsACString* const out_failureId) {
END_OF_SYMBOLS};
(void)fnLoadSymbols(symbols);
}
{
const SymLoadStruct symbols[] = {
{(PRFuncPtr*)&mSymbols.fSetDamageRegion, {{"eglSetDamageRegionKHR"}}},
END_OF_SYMBOLS};
(void)fnLoadSymbols(symbols);
}
return true;
}

Просмотреть файл

@ -104,7 +104,6 @@ enum class EGLExtension {
EXT_swap_buffers_with_damage,
KHR_swap_buffers_with_damage,
EXT_buffer_age,
KHR_partial_update,
Max
};
@ -447,12 +446,6 @@ class GLLibraryEGL final {
WRAP(fSwapBuffersWithDamage(dpy, surface, rects, n_rects));
}
// EGL_KHR_partial_update
EGLBoolean fSetDamageRegion(EGLDisplay dpy, EGLSurface surface,
const EGLint* rects, EGLint n_rects) {
WRAP(fSetDamageRegion(dpy, surface, rects, n_rects));
}
#undef WRAP
#undef PROFILE_CALL
#undef BEFORE_CALL
@ -578,10 +571,6 @@ class GLLibraryEGL final {
EGLSurface surface,
const EGLint* rects,
EGLint n_rects);
// EGL_KHR_partial_update
EGLBoolean(GLAPIENTRY* fSetDamageRegion)(EGLDisplay dpy, EGLSurface surface,
const EGLint* rects,
EGLint n_rects);
EGLClientBuffer(GLAPIENTRY* fGetNativeClientBufferANDROID)(
const struct AHardwareBuffer* buffer);
} mSymbols = {};
@ -835,13 +824,6 @@ class EglDisplay final {
IsExtensionSupported(EGLExtension::KHR_swap_buffers_with_damage));
return mLib->fSwapBuffersWithDamage(mDisplay, surface, rects, n_rects);
}
// EGL_KHR_partial_update
EGLBoolean fSetDamageRegion(EGLSurface surface, const EGLint* rects,
EGLint n_rects) {
MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_partial_update));
return mLib->fSetDamageRegion(mDisplay, surface, rects, n_rects);
}
};
} /* namespace gl */

Просмотреть файл

@ -125,18 +125,6 @@ void wr_compositor_unmap_tile(void* aCompositor) {
compositor->UnmapTile();
}
size_t wr_partial_present_compositor_get_buffer_age(const void* aCompositor) {
const RenderCompositor* compositor =
static_cast<const RenderCompositor*>(aCompositor);
return compositor->GetBufferAge();
}
void wr_partial_present_compositor_set_buffer_damage_region(
void* aCompositor, const wr::DeviceIntRect* aRects, size_t aNumRects) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->SetBufferDamageRegion(aRects, aNumRects);
}
/* static */
UniquePtr<RenderCompositor> RenderCompositor::Create(
RefPtr<widget::CompositorWidget>&& aWidget, nsACString& aError) {

Просмотреть файл

@ -126,17 +126,6 @@ class RenderCompositor {
virtual bool RequestFullRender() { return false; }
virtual uint32_t GetMaxPartialPresentRects() { return 0; }
virtual bool ShouldDrawPreviousPartialPresentRegions() { return false; }
// Returns the age of the current backbuffer., This should be used, if
// ShouldDrawPreviousPartialPresentRegions() returns true, to determine the
// region which must be rendered in addition to the current frame's dirty
// rect.
virtual size_t GetBufferAge() const { return 0; }
// Allows webrender to specify the total region that will be rendered to this
// frame, ie the frame's dirty region and some previous frames' dirty regions,
// if applicable (calculated using the buffer age). Must be called before
// anything has been rendered to the main framebuffer.
virtual void SetBufferDamageRegion(const wr::DeviceIntRect* aRects,
size_t aNumRects) {}
// Whether the surface origin is top-left.
virtual bool SurfaceOriginIsTopLeft() { return false; }

Просмотреть файл

@ -238,54 +238,14 @@ bool RenderCompositorEGL::UsePartialPresent() {
return gfx::gfxVars::WebRenderMaxPartialPresentRects() > 0;
}
bool RenderCompositorEGL::RequestFullRender() { return mBufferAge == 0; }
bool RenderCompositorEGL::RequestFullRender() { return mBufferAge != 2; }
uint32_t RenderCompositorEGL::GetMaxPartialPresentRects() {
return gfx::gfxVars::WebRenderMaxPartialPresentRects();
}
bool RenderCompositorEGL::ShouldDrawPreviousPartialPresentRegions() {
return true;
}
size_t RenderCompositorEGL::GetBufferAge() const { return mBufferAge; }
void RenderCompositorEGL::SetBufferDamageRegion(const wr::DeviceIntRect* aRects,
size_t aNumRects) {
const auto& gle = gl::GLContextEGL::Cast(gl());
const auto& egl = gle->mEgl;
if (gle->HasKhrPartialUpdate()) {
std::vector<EGLint> rects;
rects.reserve(4 * aNumRects);
const auto bufferSize = GetBufferSize();
for (size_t i = 0; i < aNumRects; i++) {
const auto left =
std::max(0, std::min(bufferSize.width, aRects[i].origin.x));
const auto top =
std::max(0, std::min(bufferSize.height, aRects[i].origin.y));
const auto right =
std::min(bufferSize.width,
std::max(0, aRects[i].origin.x + aRects[i].size.width));
const auto bottom =
std::min(bufferSize.height,
std::max(0, aRects[i].origin.y + aRects[i].size.height));
const auto width = right - left;
const auto height = bottom - top;
rects.push_back(left);
rects.push_back(bufferSize.height - bottom);
rects.push_back(width);
rects.push_back(height);
}
const auto ret =
egl->fSetDamageRegion(mEGLSurface, rects.data(), rects.size() / 4);
if (ret == LOCAL_EGL_FALSE) {
const auto err = egl->mLib->fGetError();
gfxCriticalError() << "Error in eglSetDamageRegion: " << gfx::hexa(err);
}
}
return gl::GLContextEGL::Cast(gl())->HasBufferAge();
}
} // namespace mozilla::wr

Просмотреть файл

@ -42,9 +42,6 @@ class RenderCompositorEGL : public RenderCompositor {
bool RequestFullRender() override;
uint32_t GetMaxPartialPresentRects() override;
bool ShouldDrawPreviousPartialPresentRegions() override;
size_t GetBufferAge() const override;
void SetBufferDamageRegion(const wr::DeviceIntRect* aRects,
size_t aNumRects) override;
ipc::FileDescriptor GetAndResetReleaseFence() override;

Просмотреть файл

@ -113,7 +113,7 @@ uint32_t RenderCompositorOGL::GetMaxPartialPresentRects() {
}
bool RenderCompositorOGL::RequestFullRender() {
return mIsEGL && (mBufferAge == 0);
return mIsEGL && (mBufferAge != 2);
}
bool RenderCompositorOGL::UsePartialPresent() {
@ -121,14 +121,7 @@ bool RenderCompositorOGL::UsePartialPresent() {
}
bool RenderCompositorOGL::ShouldDrawPreviousPartialPresentRegions() {
return true;
}
size_t RenderCompositorOGL::GetBufferAge() const {
if (mIsEGL) {
return mBufferAge;
}
return 0;
return mIsEGL && gl::GLContextEGL::Cast(gl())->HasBufferAge();
}
} // namespace wr

Просмотреть файл

@ -39,7 +39,6 @@ class RenderCompositorOGL : public RenderCompositor {
bool RequestFullRender() override;
uint32_t GetMaxPartialPresentRects() override;
bool ShouldDrawPreviousPartialPresentRegions() override;
size_t GetBufferAge() const override;
protected:
RefPtr<gl::GLContext> mGL;

Просмотреть файл

@ -139,7 +139,6 @@ class NewRenderer : public RendererEvent {
compositor->ShouldUseNativeCompositor() ? compositor.get()
: nullptr,
compositor->GetMaxUpdateRects(),
compositor->UsePartialPresent() ? compositor.get() : nullptr,
compositor->GetMaxPartialPresentRects(),
compositor->ShouldDrawPreviousPartialPresentRegions(), mDocHandle,
&wrRenderer, mMaxTextureSize, &errorMessage,

Просмотреть файл

@ -36,9 +36,9 @@ use tracy_rs::register_thread_with_profiler;
use webrender::{
api::units::*, api::*, render_api::*, set_profiler_hooks, AsyncPropertySampler, AsyncScreenshotHandle, Compositor,
CompositorCapabilities, CompositorConfig, CompositorSurfaceTransform, DebugFlags, Device, FastHashMap,
NativeSurfaceId, NativeSurfaceInfo, NativeTileId, PartialPresentCompositor, PipelineInfo, ProfilerHooks,
RecordedFrameHandle, Renderer, RendererOptions, RendererStats, SceneBuilderHooks, ShaderPrecacheFlags, Shaders,
ThreadListener, UploadMethod, WrShaders, ONE_TIME_USAGE_HINT,
NativeSurfaceId, NativeSurfaceInfo, NativeTileId, PipelineInfo, ProfilerHooks, RecordedFrameHandle, Renderer,
RendererOptions, RendererStats, SceneBuilderHooks, ShaderPrecacheFlags, Shaders, ThreadListener, UploadMethod,
WrShaders, ONE_TIME_USAGE_HINT,
};
use wr_malloc_size_of::MallocSizeOfOps;
@ -1240,13 +1240,6 @@ extern "C" {
stride: &mut i32,
);
fn wr_compositor_unmap_tile(compositor: *mut c_void);
fn wr_partial_present_compositor_get_buffer_age(compositor: *const c_void) -> usize;
fn wr_partial_present_compositor_set_buffer_damage_region(
compositor: *mut c_void,
rects: *const DeviceIntRect,
n_rects: usize,
);
}
pub struct WrCompositor(*mut c_void);
@ -1361,20 +1354,6 @@ impl Compositor for WrCompositor {
}
}
pub struct WrPartialPresentCompositor(*mut c_void);
impl PartialPresentCompositor for WrPartialPresentCompositor {
fn get_buffer_age(&self) -> usize {
unsafe { wr_partial_present_compositor_get_buffer_age(self.0) }
}
fn set_buffer_damage_region(&mut self, rects: &[DeviceIntRect]) {
unsafe {
wr_partial_present_compositor_set_buffer_damage_region(self.0, rects.as_ptr(), rects.len());
}
}
}
/// Information about the underlying data buffer of a mapped tile.
#[repr(C)]
#[derive(Copy, Clone)]
@ -1451,7 +1430,6 @@ pub extern "C" fn wr_window_new(
document_id: u32,
compositor: *mut c_void,
max_update_rects: usize,
partial_present_compositor: *mut c_void,
max_partial_present_rects: usize,
draw_previous_partial_present_regions: bool,
out_handle: &mut *mut DocumentHandle,
@ -1542,11 +1520,6 @@ pub extern "C" fn wr_window_new(
CompositorConfig::Draw {
max_partial_present_rects,
draw_previous_partial_present_regions,
partial_present: if partial_present_compositor != ptr::null_mut() {
Some(Box::new(WrPartialPresentCompositor(partial_present_compositor)))
} else {
None
},
}
};

Просмотреть файл

@ -200,13 +200,10 @@ pub enum CompositorConfig {
/// then the operating system supports a form of 'partial present' where
/// only dirty regions of the framebuffer need to be updated.
max_partial_present_rects: usize,
/// If this is true, WR must draw the previous frames' dirty regions when
/// If this is true, WR would draw the previous frame's dirty region when
/// doing a partial present. This is used for EGL which requires the front
/// buffer to always be fully consistent.
draw_previous_partial_present_regions: bool,
/// A client provided interface to a compositor handling partial present.
/// Required if webrender must query the backbuffer's age.
partial_present: Option<Box<dyn PartialPresentCompositor>>,
},
/// Use a native OS compositor to draw tiles. This requires clients to implement
/// the Compositor trait, but can be significantly more power efficient on operating
@ -232,18 +229,6 @@ impl CompositorConfig {
}
}
}
pub fn partial_present(&mut self) -> Option<&mut Box<dyn PartialPresentCompositor>> {
match self {
CompositorConfig::Native { .. } => {
None
}
CompositorConfig::Draw { ref mut partial_present, .. } => {
partial_present.as_mut()
}
}
}
}
impl Default for CompositorConfig {
@ -252,7 +237,6 @@ impl Default for CompositorConfig {
CompositorConfig::Draw {
max_partial_present_rects: 0,
draw_previous_partial_present_regions: false,
partial_present: None,
}
}
}
@ -1015,21 +999,6 @@ pub trait Compositor {
fn get_capabilities(&self) -> CompositorCapabilities;
}
/// Defines an interface to a non-native (application-level) Compositor which handles
/// partial present. This is required if webrender must query the backbuffer's age.
/// TODO: Use the Compositor trait for native and non-native compositors, and integrate
/// this functionality there.
pub trait PartialPresentCompositor {
/// Returns the age of the current backbuffer. This should be used, if
/// draw_previous_partial_present_regions is true, to determine the
/// region which must be rendered in addition to the current frame's dirty rect.
fn get_buffer_age(&self) -> usize;
/// Allows webrender to specify the total region that will be rendered to this frame,
/// ie the frame's dirty region and some previous frames' dirty regions, if applicable
/// (calculated using the buffer age). Must be called before anything has been rendered
/// to the main framebuffer.
fn set_buffer_damage_region(&mut self, rects: &[DeviceIntRect]);
}
/// Information about an opaque surface used to occlude tiles.
#[cfg_attr(feature = "capture", derive(Serialize))]

Просмотреть файл

@ -209,8 +209,8 @@ pub extern crate api;
extern crate webrender_build;
#[doc(hidden)]
pub use crate::composite::{CompositorConfig, Compositor, CompositorCapabilities, CompositorSurfaceTransform};
pub use crate::composite::{NativeSurfaceId, NativeTileId, NativeSurfaceInfo, PartialPresentCompositor};
pub use crate::composite::{CompositorConfig, Compositor, CompositorCapabilities};
pub use crate::composite::{NativeSurfaceId, NativeTileId, NativeSurfaceInfo, CompositorSurfaceTransform};
pub use crate::device::{UploadMethod, VertexUsageHint, get_gl_target, get_unoptimized_shader_source};
pub use crate::device::{ProgramBinary, ProgramCache, ProgramCacheObserver, FormatDesc};
pub use crate::device::Device;

Просмотреть файл

@ -2172,61 +2172,6 @@ impl VertexDataTextures {
}
}
/// Tracks buffer damage rects over a series of frames.
#[derive(Debug)]
struct BufferDamageTracker {
damage_rects: [DeviceRect; 2],
current_offset: usize,
}
impl Default for BufferDamageTracker {
fn default() -> Self {
Self {
damage_rects: [DeviceRect::default(); 2],
current_offset: 0,
}
}
}
impl BufferDamageTracker {
/// Sets the damage rect for the current frame. Should only be called *after*
/// get_damage_rect() has been called to get the current backbuffer's damage rect.
fn push_dirty_rect(&mut self, rect: &DeviceRect) {
self.damage_rects[self.current_offset] = rect.clone();
self.current_offset = match self.current_offset {
0 => self.damage_rects.len() - 1,
n => n - 1,
}
}
/// Gets the damage rect for the current backbuffer, given the backbuffer's age.
/// (The number of frames since it was previously the backbuffer.)
/// Returns an empty rect if the buffer is valid, and None if the entire buffer is invalid.
fn get_damage_rect(&self, buffer_age: usize) -> Option<DeviceRect> {
match buffer_age {
// 0 means this is a new buffer, so is completely invalid.
0 => None,
// 1 means this backbuffer was also the previous frame's backbuffer
// (so must have been copied to the frontbuffer). It is therefore entirely valid.
1 => Some(DeviceRect::zero()),
// We must calculate the union of the damage rects since this buffer was previously
// the backbuffer.
n if n <= self.damage_rects.len() + 1 => {
Some(
self.damage_rects.iter()
.cycle()
.skip(self.current_offset + 1)
.take(n - 1)
.fold(DeviceRect::zero(), |acc, r| acc.union(r))
)
}
// The backbuffer is older than the number of frames for which we track,
// so we treat it as entirely invalid.
_ => None,
}
}
}
/// The renderer is responsible for submitting to the GPU the work prepared by the
/// RenderBackend.
///
@ -2353,10 +2298,10 @@ pub struct Renderer {
/// State related to the debug / profiling overlays
debug_overlay_state: DebugOverlayState,
/// Tracks the dirty rectangles from previous frames. Used on platforms
/// that require keeping the front buffer fully correct when doing
/// The dirty rectangle from the previous frame, used on platforms that
/// require keeping the front buffer fully correct when doing
/// partial present (e.g. unix desktop with EGL_EXT_buffer_age).
buffer_damage_tracker: BufferDamageTracker,
prev_dirty_rect: DeviceRect,
max_primitive_instance_count: usize,
}
@ -2647,7 +2592,7 @@ impl Renderer {
};
let compositor_kind = match options.compositor_config {
CompositorConfig::Draw { max_partial_present_rects, draw_previous_partial_present_regions, .. } => {
CompositorConfig::Draw { max_partial_present_rects, draw_previous_partial_present_regions } => {
CompositorKind::Draw { max_partial_present_rects, draw_previous_partial_present_regions }
}
CompositorConfig::Native { ref compositor, max_update_rects, .. } => {
@ -2931,7 +2876,7 @@ impl Renderer {
current_compositor_kind: compositor_kind,
allocated_native_surfaces: FastHashSet::default(),
debug_overlay_state: DebugOverlayState::new(),
buffer_damage_tracker: BufferDamageTracker::default(),
prev_dirty_rect: DeviceRect::zero(),
max_primitive_instance_count:
RendererOptions::MAX_INSTANCE_BUFFER_SIZE / mem::size_of::<PrimitiveInstanceData>(),
};
@ -5222,19 +5167,9 @@ impl Renderer {
let mut partial_present_mode = None;
if max_partial_present_rects > 0 {
let prev_frames_damage_rect = if let Some(partial_present) = self.compositor_config.partial_present() {
self.buffer_damage_tracker
.get_damage_rect(partial_present.get_buffer_age())
.or_else(|| Some(DeviceRect::from_size(draw_target.dimensions().to_f32())))
} else {
None
};
let can_use_partial_present =
composite_state.dirty_rects_are_valid &&
!self.force_redraw &&
!(prev_frames_damage_rect.is_none() && draw_previous_partial_present_regions) &&
!self.debug_overlay_state.is_enabled;
let can_use_partial_present = composite_state.dirty_rects_are_valid &&
!self.force_redraw &&
!self.debug_overlay_state.is_enabled;
if can_use_partial_present {
let mut combined_dirty_rect = DeviceRect::zero();
@ -5242,40 +5177,29 @@ impl Renderer {
// Work out how many dirty rects WR produced, and if that's more than
// what the device supports.
for tile in composite_state.opaque_tiles.iter().chain(composite_state.alpha_tiles.iter()) {
let tile_dirty_rect = tile.dirty_rect.translate(tile.rect.origin.to_vector());
combined_dirty_rect = combined_dirty_rect.union(&tile_dirty_rect);
let dirty_rect = tile.dirty_rect.translate(tile.rect.origin.to_vector());
combined_dirty_rect = combined_dirty_rect.union(&dirty_rect);
}
let combined_dirty_rect = combined_dirty_rect.round();
let combined_dirty_rect_i32 = combined_dirty_rect.to_i32();
// Return this frame's dirty region. If nothing has changed, don't return any dirty
// rects at all (the client can use this as a signal to skip present completely).
// If nothing has changed, don't return any dirty rects at all (the client
// can use this as a signal to skip present completely).
if !combined_dirty_rect.is_empty() {
results.dirty_rects.push(combined_dirty_rect_i32);
}
// Track this frame's dirty region, for calculating subsequent frames' damage.
if draw_previous_partial_present_regions {
self.buffer_damage_tracker.push_dirty_rect(&combined_dirty_rect);
}
// If the implementation requires manually keeping the buffer consistent,
// then we must combine this frame's dirty region with that of previous frames
// to determine the total_dirty_rect. The is used to determine what region we
// render to, and is what we send to the compositor as the buffer damage region
// (eg for KHR_partial_update).
let total_dirty_rect = if draw_previous_partial_present_regions {
combined_dirty_rect.union(&prev_frames_damage_rect.unwrap())
} else {
combined_dirty_rect
};
// combine the previous frame's damage for tile clipping.
// (Not for the returned region though, that should be from this frame only)
partial_present_mode = Some(PartialPresentMode::Single {
dirty_rect: total_dirty_rect,
dirty_rect: if draw_previous_partial_present_regions {
combined_dirty_rect.union(&self.prev_dirty_rect)
} else { combined_dirty_rect },
});
if let Some(partial_present) = self.compositor_config.partial_present() {
partial_present.set_buffer_damage_region(&[total_dirty_rect.to_i32()]);
if draw_previous_partial_present_regions {
self.prev_dirty_rect = combined_dirty_rect;
}
} else {
// If we don't have a valid partial present scenario, return a single
@ -5287,7 +5211,7 @@ impl Renderer {
results.dirty_rects.push(fb_rect);
if draw_previous_partial_present_regions {
self.buffer_damage_tracker.push_dirty_rect(&fb_rect.to_f32());
self.prev_dirty_rect = fb_rect.to_f32();
}
}
@ -7939,36 +7863,3 @@ impl CompositeState {
compositor.start_compositing();
}
}
mod tests {
#[test]
fn test_buffer_damage_tracker() {
use super::BufferDamageTracker;
use api::units::{DevicePoint, DeviceRect, DeviceSize};
let mut tracker = BufferDamageTracker::default();
assert_eq!(tracker.get_damage_rect(0), None);
assert_eq!(tracker.get_damage_rect(1), Some(DeviceRect::zero()));
assert_eq!(tracker.get_damage_rect(2), Some(DeviceRect::zero()));
assert_eq!(tracker.get_damage_rect(3), Some(DeviceRect::zero()));
assert_eq!(tracker.get_damage_rect(4), None);
let damage1 = DeviceRect::new(DevicePoint::new(10, 10), DeviceSize::new(10, 10));
let damage2 = DeviceRect::new(DevicePoint::new(20, 20), DeviceSize::new(10, 10));
let combined = damage1.union(&damage2);
tracker.push_dirty_rect(&damage1);
assert_eq!(tracker.get_damage_rect(0), None);
assert_eq!(tracker.get_damage_rect(1), Some(DeviceRect::zero()));
assert_eq!(tracker.get_damage_rect(2), Some(damage1));
assert_eq!(tracker.get_damage_rect(3), Some(damage1));
assert_eq!(tracker.get_damage_rect(4), None);
tracker.push_dirty_rect(&damage2);
assert_eq!(tracker.get_damage_rect(0), None);
assert_eq!(tracker.get_damage_rect(1), Some(DeviceRect::zero()));
assert_eq!(tracker.get_damage_rect(2), Some(damage2));
assert_eq!(tracker.get_damage_rect(3), Some(combined));
assert_eq!(tracker.get_damage_rect(4), None);
}
}

Просмотреть файл

@ -4510,7 +4510,7 @@
- name: gfx.webrender.max-partial-present-rects
type: uint32_t
#if defined(XP_WIN) || defined(MOZ_WIDGET_ANDROID)
#if defined(XP_WIN)
value: 1
#else
value: 0