Skip to content

Commit

Permalink
cc: Change damage tracking from floats to integers.
Browse files Browse the repository at this point in the history
Damage rects can become huge when layers clip the viewport, and in some
cases become so large that we reach inaccurate floating point
representation of the whole-number portion, which we fail to handle
correctly when doing gfx::ToEnclosingRect.

Int/float conversions are also slow, and the GL_SCISSOR wants integers
eventually anyway, so keeping track of partial-pixel damage is not
buying us much here. So convert the DamageTracker to use integer rects.

Also change cc::RenderSurfaceImpl to export a damage_rect that is
contained inside the output_rect for the RenderPass, and add DCHECKs
to cc::RenderPass to ensure we don't send pointlessly large damage_rects
to the cc::Renderer.

Tests:
DamageTrackerTest.HugeDamageRect

R=enne@chromium.org, piman@chromium.org
BUG=355514

Review URL: https://codereview.chromium.org/226183007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262160 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
danakj@chromium.org committed Apr 7, 2014
1 parent 2056c3b commit b4ead7b
Show file tree
Hide file tree
Showing 20 changed files with 374 additions and 342 deletions.
101 changes: 54 additions & 47 deletions cc/debug/debug_rect_history.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "cc/trees/damage_tracker.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_common.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace cc {

Expand Down Expand Up @@ -80,12 +81,12 @@ void DebugRectHistory::SavePaintRects(LayerImpl* layer) {
static_cast<float>(layer->bounds().width());
float height_scale = layer->content_bounds().height() /
static_cast<float>(layer->bounds().height());
gfx::RectF update_content_rect =
gfx::ScaleRect(layer->update_rect(), width_scale, height_scale);
gfx::Rect update_content_rect = gfx::ScaleToEnclosingRect(
gfx::ToEnclosingRect(layer->update_rect()), width_scale, height_scale);
debug_rects_.push_back(
DebugRect(PAINT_RECT_TYPE,
MathUtil::MapClippedRect(layer->screen_space_transform(),
update_content_rect)));
MathUtil::MapEnclosingClippedRect(
layer->screen_space_transform(), update_content_rect)));
}

for (unsigned i = 0; i < layer->children().size(); ++i)
Expand Down Expand Up @@ -115,13 +116,14 @@ void DebugRectHistory::SavePropertyChangedRects(
if (layer == hud_layer)
continue;

if (layer->LayerPropertyChanged()) {
debug_rects_.push_back(
DebugRect(PROPERTY_CHANGED_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
layer->screen_space_transform(),
gfx::Rect(layer->content_bounds()))));
}
if (!layer->LayerPropertyChanged())
continue;

debug_rects_.push_back(
DebugRect(PROPERTY_CHANGED_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
layer->screen_space_transform(),
gfx::Rect(layer->content_bounds()))));
}
}
}
Expand All @@ -137,7 +139,7 @@ void DebugRectHistory::SaveSurfaceDamageRects(

debug_rects_.push_back(DebugRect(
SURFACE_DAMAGE_RECT_TYPE,
MathUtil::MapClippedRect(
MathUtil::MapEnclosingClippedRect(
render_surface->screen_space_transform(),
render_surface->damage_tracker()->current_damage_rect())));
}
Expand All @@ -152,15 +154,16 @@ void DebugRectHistory::SaveScreenSpaceRects(
RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
DCHECK(render_surface);

debug_rects_.push_back(DebugRect(
SCREEN_SPACE_RECT_TYPE,
MathUtil::MapClippedRect(render_surface->screen_space_transform(),
render_surface->content_rect())));
debug_rects_.push_back(
DebugRect(SCREEN_SPACE_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
render_surface->screen_space_transform(),
render_surface->content_rect())));

if (render_surface_layer->replica_layer()) {
debug_rects_.push_back(
DebugRect(REPLICA_SCREEN_SPACE_RECT_TYPE,
MathUtil::MapClippedRect(
MathUtil::MapEnclosingClippedRect(
render_surface->replica_screen_space_transform(),
render_surface->content_rect())));
}
Expand Down Expand Up @@ -192,13 +195,12 @@ void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) {
for (Region::Iterator iter(layer->touch_event_handler_region());
iter.has_rect();
iter.next()) {
gfx::RectF touch_rect = gfx::ScaleRect(iter.rect(),
layer->contents_scale_x(),
layer->contents_scale_y());
debug_rects_.push_back(DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE,
MathUtil::MapClippedRect(
layer->screen_space_transform(),
touch_rect)));
gfx::Rect touch_rect = gfx::ScaleToEnclosingRect(
iter.rect(), layer->contents_scale_x(), layer->contents_scale_y());
debug_rects_.push_back(
DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
layer->screen_space_transform(), touch_rect)));
}
}

Expand All @@ -213,12 +215,14 @@ void DebugRectHistory::SaveWheelEventHandlerRectsCallback(LayerImpl* layer) {
if (!layer->have_wheel_event_handlers())
return;

gfx::RectF wheel_rect = gfx::RectF(layer->content_bounds());
wheel_rect.Scale(layer->contents_scale_x(), layer->contents_scale_y());
debug_rects_.push_back(DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE,
MathUtil::MapClippedRect(
layer->screen_space_transform(),
wheel_rect)));
gfx::Rect wheel_rect =
gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()),
layer->contents_scale_x(),
layer->contents_scale_y());
debug_rects_.push_back(
DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
layer->screen_space_transform(), wheel_rect)));
}

void DebugRectHistory::SaveScrollEventHandlerRects(LayerImpl* layer) {
Expand All @@ -232,11 +236,14 @@ void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) {
if (!layer->have_scroll_event_handlers())
return;

gfx::RectF scroll_rect = gfx::RectF(layer->content_bounds());
scroll_rect.Scale(layer->contents_scale_x(), layer->contents_scale_y());
debug_rects_.push_back(DebugRect(
SCROLL_EVENT_HANDLER_RECT_TYPE,
MathUtil::MapClippedRect(layer->screen_space_transform(), scroll_rect)));
gfx::Rect scroll_rect =
gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()),
layer->contents_scale_x(),
layer->contents_scale_y());
debug_rects_.push_back(
DebugRect(SCROLL_EVENT_HANDLER_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
layer->screen_space_transform(), scroll_rect)));
}

void DebugRectHistory::SaveNonFastScrollableRects(LayerImpl* layer) {
Expand All @@ -250,13 +257,12 @@ void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
for (Region::Iterator iter(layer->non_fast_scrollable_region());
iter.has_rect();
iter.next()) {
gfx::RectF scroll_rect = gfx::ScaleRect(iter.rect(),
layer->contents_scale_x(),
layer->contents_scale_y());
debug_rects_.push_back(DebugRect(NON_FAST_SCROLLABLE_RECT_TYPE,
MathUtil::MapClippedRect(
layer->screen_space_transform(),
scroll_rect)));
gfx::Rect scroll_rect = gfx::ScaleToEnclosingRect(
iter.rect(), layer->contents_scale_x(), layer->contents_scale_y());
debug_rects_.push_back(
DebugRect(NON_FAST_SCROLLABLE_RECT_TYPE,
MathUtil::MapEnclosingClippedRect(
layer->screen_space_transform(), scroll_rect)));
}
}

Expand All @@ -276,11 +282,12 @@ void DebugRectHistory::SaveLayerAnimationBoundsRects(
if (!LayerUtils::GetAnimationBounds(**it, &inflated_bounds))
continue;

debug_rects_.push_back(DebugRect(ANIMATION_BOUNDS_RECT_TYPE,
gfx::RectF(inflated_bounds.x(),
inflated_bounds.y(),
inflated_bounds.width(),
inflated_bounds.height())));
debug_rects_.push_back(
DebugRect(ANIMATION_BOUNDS_RECT_TYPE,
gfx::ToEnclosingRect(gfx::RectF(inflated_bounds.x(),
inflated_bounds.y(),
inflated_bounds.width(),
inflated_bounds.height()))));
}
}

Expand Down
5 changes: 2 additions & 3 deletions cc/debug/debug_rect_history.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "base/memory/scoped_ptr.h"
#include "cc/layers/layer_lists.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/rect_f.h"

namespace cc {

Expand Down Expand Up @@ -58,11 +57,11 @@ enum DebugRectType {
};

struct DebugRect {
DebugRect(DebugRectType new_type, const gfx::RectF& new_rect)
DebugRect(DebugRectType new_type, const gfx::Rect& new_rect)
: type(new_type), rect(new_rect) {}

DebugRectType type;
gfx::RectF rect;
gfx::Rect rect;
};

// This class maintains a history of rects of various types that can be used
Expand Down
18 changes: 12 additions & 6 deletions cc/layers/heads_up_display_layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -599,25 +599,31 @@ void HeadsUpDisplayLayerImpl::DrawDebugRect(
SkColor fill_color,
float stroke_width,
const std::string& label_text) const {
gfx::RectF debug_layer_rect = gfx::ScaleRect(
gfx::Rect debug_layer_rect = gfx::ScaleToEnclosingRect(
rect.rect, 1.0 / contents_scale_x(), 1.0 / contents_scale_y());
SkRect sk_rect = RectFToSkRect(debug_layer_rect);
SkIRect sk_rect = RectToSkIRect(debug_layer_rect);
paint.setColor(fill_color);
paint.setStyle(SkPaint::kFill_Style);
canvas->drawRect(sk_rect, paint);
canvas->drawIRect(sk_rect, paint);

paint.setColor(stroke_color);
paint.setStyle(SkPaint::kStroke_Style);
paint.setStrokeWidth(SkFloatToScalar(stroke_width));
canvas->drawRect(sk_rect, paint);
canvas->drawIRect(sk_rect, paint);

if (label_text.length()) {
const int kFontHeight = 12;
const int kPadding = 3;

// The debug_layer_rect may be huge, and converting to a floating point may
// be lossy, so intersect with the HUD layer bounds first to prevent that.
gfx::Rect clip_rect = debug_layer_rect;
clip_rect.Intersect(gfx::Rect(content_bounds()));
SkRect sk_clip_rect = RectToSkRect(clip_rect);

canvas->save();
canvas->clipRect(sk_rect);
canvas->translate(sk_rect.x(), sk_rect.y());
canvas->clipRect(sk_clip_rect);
canvas->translate(sk_clip_rect.x(), sk_clip_rect.y());

SkPaint label_paint = CreatePaint();
label_paint.setTextSize(kFontHeight);
Expand Down
3 changes: 2 additions & 1 deletion cc/layers/render_surface_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ void RenderSurfaceImpl::AppendRenderPasses(RenderPassSink* pass_sink) {
scoped_ptr<RenderPass> pass = RenderPass::Create(layer_list_.size());
pass->SetNew(RenderPassId(),
content_rect_,
damage_tracker_->current_damage_rect(),
gfx::IntersectRects(content_rect_,
damage_tracker_->current_damage_rect()),
screen_space_transform_);
pass_sink->AppendRenderPass(pass.Pass());
}
Expand Down
22 changes: 11 additions & 11 deletions cc/output/direct_renderer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ void DirectRenderer::InitializeViewport(DrawingFrame* frame,
}

gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace(
const gfx::RectF& draw_rect) const {
gfx::Rect window_rect = gfx::ToEnclosingRect(draw_rect);
const gfx::Rect& draw_rect) const {
gfx::Rect window_rect = draw_rect;
window_rect -= current_draw_rect_.OffsetFromOrigin();
window_rect += current_viewport_rect_.OffsetFromOrigin();
if (FlippedFramebuffer())
Expand Down Expand Up @@ -254,9 +254,9 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
render_passes_in_draw_order->clear();
}

gfx::RectF DirectRenderer::ComputeScissorRectForRenderPass(
gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass(
const DrawingFrame* frame) {
gfx::RectF render_pass_scissor = frame->current_render_pass->output_rect;
gfx::Rect render_pass_scissor = frame->current_render_pass->output_rect;

if (frame->root_damage_rect == frame->root_render_pass->output_rect ||
!frame->current_render_pass->copy_requests.empty())
Expand All @@ -266,9 +266,9 @@ gfx::RectF DirectRenderer::ComputeScissorRectForRenderPass(
if (frame->current_render_pass->transform_to_root_target.GetInverse(
&inverse_transform)) {
// Only intersect inverse-projected damage if the transform is invertible.
gfx::RectF damage_rect_in_render_pass_space =
MathUtil::ProjectClippedRect(inverse_transform,
frame->root_damage_rect);
gfx::Rect damage_rect_in_render_pass_space =
MathUtil::ProjectEnclosingClippedRect(inverse_transform,
frame->root_damage_rect);
render_pass_scissor.Intersect(damage_rect_in_render_pass_space);
}

Expand Down Expand Up @@ -308,9 +308,9 @@ void DirectRenderer::SetScissorStateForQuad(const DrawingFrame* frame,
void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor(
const DrawingFrame* frame,
const DrawQuad& quad,
const gfx::RectF& render_pass_scissor,
const gfx::Rect& render_pass_scissor,
bool* should_skip_quad) {
gfx::RectF quad_scissor_rect = render_pass_scissor;
gfx::Rect quad_scissor_rect = render_pass_scissor;

if (quad.isClipped())
quad_scissor_rect.Intersect(quad.clipRect());
Expand All @@ -326,7 +326,7 @@ void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor(

void DirectRenderer::SetScissorTestRectInDrawSpace(
const DrawingFrame* frame,
const gfx::RectF& draw_space_rect) {
const gfx::Rect& draw_space_rect) {
gfx::Rect window_space_rect = MoveFromDrawToWindowSpace(draw_space_rect);
if (NeedDeviceClip(frame))
window_space_rect.Intersect(DeviceClipRectInWindowSpace(frame));
Expand All @@ -342,7 +342,7 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
return;

bool using_scissor_as_optimization = Capabilities().using_partial_swap;
gfx::RectF render_pass_scissor;
gfx::Rect render_pass_scissor;
bool draw_rect_covers_full_surface = true;
if (frame->current_render_pass == frame->root_render_pass &&
!frame->device_viewport_rect.Contains(
Expand Down
10 changes: 5 additions & 5 deletions cc/output/direct_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class CC_EXPORT DirectRenderer : public Renderer {
const RenderPass* current_render_pass;
const ScopedResource* current_texture;

gfx::RectF root_damage_rect;
gfx::Rect root_damage_rect;
gfx::Rect device_viewport_rect;
gfx::Rect device_clip_rect;

Expand Down Expand Up @@ -78,19 +78,19 @@ class CC_EXPORT DirectRenderer : public Renderer {
const gfx::Rect& draw_rect,
const gfx::Rect& viewport_rect,
const gfx::Size& surface_size);
gfx::Rect MoveFromDrawToWindowSpace(const gfx::RectF& draw_rect) const;
gfx::Rect MoveFromDrawToWindowSpace(const gfx::Rect& draw_rect) const;

bool NeedDeviceClip(const DrawingFrame* frame) const;
gfx::Rect DeviceClipRectInWindowSpace(const DrawingFrame* frame) const;
static gfx::RectF ComputeScissorRectForRenderPass(const DrawingFrame* frame);
static gfx::Rect ComputeScissorRectForRenderPass(const DrawingFrame* frame);
void SetScissorStateForQuad(const DrawingFrame* frame, const DrawQuad& quad);
void SetScissorStateForQuadWithRenderPassScissor(
const DrawingFrame* frame,
const DrawQuad& quad,
const gfx::RectF& render_pass_scissor,
const gfx::Rect& render_pass_scissor,
bool* should_skip_quad);
void SetScissorTestRectInDrawSpace(const DrawingFrame* frame,
const gfx::RectF& draw_space_rect);
const gfx::Rect& draw_space_rect);

static gfx::Size RenderPassTextureSize(const RenderPass* render_pass);

Expand Down
12 changes: 6 additions & 6 deletions cc/output/gl_renderer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
viewport_rect,
gfx::Transform());
AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
root_pass->damage_rect = gfx::RectF(2.f, 2.f, 3.f, 3.f);
root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);

renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
renderer.DrawFrame(&render_passes_in_draw_order_,
Expand All @@ -1136,7 +1136,7 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
viewport_rect,
gfx::Transform());
AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
root_pass->damage_rect = root_pass->output_rect;

renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
renderer.DrawFrame(&render_passes_in_draw_order_,
Expand All @@ -1157,7 +1157,7 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
viewport_rect,
gfx::Transform());
AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
root_pass->damage_rect = root_pass->output_rect;
root_pass->has_transparent_background = false;

renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
Expand All @@ -1180,7 +1180,7 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
viewport_rect,
gfx::Transform());
AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
root_pass->damage_rect = root_pass->output_rect;

renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
renderer.DrawFrame(&render_passes_in_draw_order_,
Expand All @@ -1201,7 +1201,7 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
viewport_rect,
gfx::Transform());
AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
root_pass->damage_rect = root_pass->output_rect;

renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
renderer.DrawFrame(&render_passes_in_draw_order_,
Expand All @@ -1223,7 +1223,7 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
viewport_rect,
gfx::Transform());
AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
root_pass->damage_rect = root_pass->output_rect;

renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
renderer.DrawFrame(&render_passes_in_draw_order_,
Expand Down
Loading

0 comments on commit b4ead7b

Please sign in to comment.