1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/trees/quad_culler.h"
6
7#include "cc/debug/debug_colors.h"
8#include "cc/debug/overdraw_metrics.h"
9#include "cc/layers/append_quads_data.h"
10#include "cc/layers/layer_impl.h"
11#include "cc/quads/debug_border_draw_quad.h"
12#include "cc/quads/render_pass.h"
13#include "cc/trees/occlusion_tracker.h"
14#include "third_party/skia/include/core/SkColor.h"
15#include "ui/gfx/transform.h"
16
17namespace cc {
18
19QuadCuller::QuadCuller(QuadList* quad_list,
20                       SharedQuadStateList* shared_quad_state_list,
21                       const LayerImpl* layer,
22                       const OcclusionTrackerImpl& occlusion_tracker,
23                       bool show_culling_with_debug_border_quads,
24                       bool for_surface)
25    : quad_list_(quad_list),
26      shared_quad_state_list_(shared_quad_state_list),
27      layer_(layer),
28      occlusion_tracker_(occlusion_tracker),
29      current_shared_quad_state_(NULL),
30      show_culling_with_debug_border_quads_(
31          show_culling_with_debug_border_quads),
32      for_surface_(for_surface) {}
33
34SharedQuadState* QuadCuller::UseSharedQuadState(
35    scoped_ptr<SharedQuadState> shared_quad_state) {
36  // TODO(danakj): If all quads are culled for the shared_quad_state, we can
37  // drop it from the list.
38  current_shared_quad_state_ = shared_quad_state.get();
39  shared_quad_state_list_->push_back(shared_quad_state.Pass());
40  return current_shared_quad_state_;
41}
42
43static inline bool AppendQuadInternal(
44    scoped_ptr<DrawQuad> draw_quad,
45    gfx::Rect culled_rect,
46    QuadList* quad_list,
47    const OcclusionTrackerImpl& occlusion_tracker,
48    const LayerImpl* layer,
49    bool create_debug_border_quads) {
50  bool keep_quad = !culled_rect.IsEmpty();
51  if (keep_quad)
52    draw_quad->visible_rect = culled_rect;
53
54  occlusion_tracker.overdraw_metrics()->DidCullForDrawing(
55      draw_quad->quadTransform(), draw_quad->rect, culled_rect);
56  gfx::Rect opaque_draw_rect =
57      draw_quad->opacity() == 1.0f ? draw_quad->opaque_rect : gfx::Rect();
58  occlusion_tracker.overdraw_metrics()->
59      DidDraw(draw_quad->quadTransform(), culled_rect, opaque_draw_rect);
60
61  if (keep_quad) {
62    if (create_debug_border_quads && !draw_quad->IsDebugQuad() &&
63        draw_quad->visible_rect != draw_quad->rect) {
64      SkColor color = DebugColors::CulledTileBorderColor();
65      float width = DebugColors::CulledTileBorderWidth(
66          layer ? layer->layer_tree_impl() : NULL);
67      scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
68          DebugBorderDrawQuad::Create();
69      debug_border_quad->SetNew(
70          draw_quad->shared_quad_state, draw_quad->visible_rect, color, width);
71      quad_list->push_back(debug_border_quad.PassAs<DrawQuad>());
72    }
73
74    // Pass the quad after we're done using it.
75    quad_list->push_back(draw_quad.Pass());
76  }
77  return keep_quad;
78}
79
80bool QuadCuller::Append(scoped_ptr<DrawQuad> draw_quad,
81                        AppendQuadsData* append_quads_data) {
82  DCHECK(draw_quad->shared_quad_state == current_shared_quad_state_);
83  DCHECK(!shared_quad_state_list_->empty());
84  DCHECK(shared_quad_state_list_->back() == current_shared_quad_state_);
85
86  gfx::Rect culled_rect;
87  bool impl_draw_transform_is_unknown = false;
88
89  if (for_surface_) {
90    culled_rect = occlusion_tracker_.UnoccludedContributingSurfaceContentRect(
91        layer_, false, draw_quad->visible_rect);
92  } else {
93    culled_rect = occlusion_tracker_.UnoccludedContentRect(
94        layer_->render_target(),
95        draw_quad->visible_rect,
96        draw_quad->quadTransform(),
97        impl_draw_transform_is_unknown);
98  }
99
100  return AppendQuadInternal(draw_quad.Pass(),
101                            culled_rect,
102                            quad_list_,
103                            occlusion_tracker_,
104                            layer_,
105                            show_culling_with_debug_border_quads_);
106}
107
108}  // namespace cc
109