summaryrefslogtreecommitdiffstats
path: root/chromium/cc/trees/quad_culler.cc
blob: 2fc8aaa6caa8fe8bcace7ccf3502e30b7a68ebe3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/trees/quad_culler.h"

#include "cc/debug/debug_colors.h"
#include "cc/debug/overdraw_metrics.h"
#include "cc/layers/append_quads_data.h"
#include "cc/layers/layer_impl.h"
#include "cc/quads/debug_border_draw_quad.h"
#include "cc/quads/render_pass.h"
#include "cc/trees/occlusion_tracker.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/transform.h"

namespace cc {

QuadCuller::QuadCuller(QuadList* quad_list,
                       SharedQuadStateList* shared_quad_state_list,
                       const LayerImpl* layer,
                       const OcclusionTrackerImpl& occlusion_tracker,
                       bool show_culling_with_debug_border_quads,
                       bool for_surface)
    : quad_list_(quad_list),
      shared_quad_state_list_(shared_quad_state_list),
      layer_(layer),
      occlusion_tracker_(occlusion_tracker),
      current_shared_quad_state_(NULL),
      show_culling_with_debug_border_quads_(
          show_culling_with_debug_border_quads),
      for_surface_(for_surface) {}

SharedQuadState* QuadCuller::UseSharedQuadState(
    scoped_ptr<SharedQuadState> shared_quad_state) {
  // TODO(danakj): If all quads are culled for the shared_quad_state, we can
  // drop it from the list.
  current_shared_quad_state_ = shared_quad_state.get();
  shared_quad_state_list_->push_back(shared_quad_state.Pass());
  return current_shared_quad_state_;
}

static inline bool AppendQuadInternal(
    scoped_ptr<DrawQuad> draw_quad,
    gfx::Rect culled_rect,
    QuadList* quad_list,
    const OcclusionTrackerImpl& occlusion_tracker,
    const LayerImpl* layer,
    bool create_debug_border_quads) {
  bool keep_quad = !culled_rect.IsEmpty();
  if (keep_quad)
    draw_quad->visible_rect = culled_rect;

  occlusion_tracker.overdraw_metrics()->DidCullForDrawing(
      draw_quad->quadTransform(), draw_quad->rect, culled_rect);
  gfx::Rect opaque_draw_rect =
      draw_quad->opacity() == 1.0f ? draw_quad->opaque_rect : gfx::Rect();
  occlusion_tracker.overdraw_metrics()->
      DidDraw(draw_quad->quadTransform(), culled_rect, opaque_draw_rect);

  if (keep_quad) {
    if (create_debug_border_quads && !draw_quad->IsDebugQuad() &&
        draw_quad->visible_rect != draw_quad->rect) {
      SkColor color = DebugColors::CulledTileBorderColor();
      float width = DebugColors::CulledTileBorderWidth(
          layer ? layer->layer_tree_impl() : NULL);
      scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
          DebugBorderDrawQuad::Create();
      debug_border_quad->SetNew(
          draw_quad->shared_quad_state, draw_quad->visible_rect, color, width);
      quad_list->push_back(debug_border_quad.PassAs<DrawQuad>());
    }

    // Pass the quad after we're done using it.
    quad_list->push_back(draw_quad.Pass());
  }
  return keep_quad;
}

bool QuadCuller::Append(scoped_ptr<DrawQuad> draw_quad,
                        AppendQuadsData* append_quads_data) {
  DCHECK(draw_quad->shared_quad_state == current_shared_quad_state_);
  DCHECK(!shared_quad_state_list_->empty());
  DCHECK(shared_quad_state_list_->back() == current_shared_quad_state_);

  gfx::Rect culled_rect;
  bool impl_draw_transform_is_unknown = false;

  if (for_surface_) {
    culled_rect = occlusion_tracker_.UnoccludedContributingSurfaceContentRect(
        layer_, false, draw_quad->visible_rect);
  } else {
    culled_rect = occlusion_tracker_.UnoccludedContentRect(
        layer_->render_target(),
        draw_quad->visible_rect,
        draw_quad->quadTransform(),
        impl_draw_transform_is_unknown);
  }

  return AppendQuadInternal(draw_quad.Pass(),
                            culled_rect,
                            quad_list_,
                            occlusion_tracker_,
                            layer_,
                            show_culling_with_debug_border_quads_);
}

}  // namespace cc