12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/quad_culler.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/debug/debug_colors.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/debug/overdraw_metrics.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/append_quads_data.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer_impl.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/debug_border_draw_quad.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/quads/render_pass.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/occlusion_tracker.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuadCuller::QuadCuller(QuadList* quad_list,
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       SharedQuadStateList* shared_quad_state_list,
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const LayerImpl* layer,
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const OcclusionTrackerImpl& occlusion_tracker,
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       bool show_culling_with_debug_border_quads,
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       bool for_surface)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : quad_list_(quad_list),
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shared_quad_state_list_(shared_quad_state_list),
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_(layer),
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occlusion_tracker_(occlusion_tracker),
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      current_shared_quad_state_(NULL),
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      show_culling_with_debug_border_quads_(
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          show_culling_with_debug_border_quads),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for_surface_(for_surface) {}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SharedQuadState* QuadCuller::UseSharedQuadState(
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<SharedQuadState> shared_quad_state) {
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // TODO(danakj): If all quads are culled for the shared_quad_state, we can
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // drop it from the list.
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_shared_quad_state_ = shared_quad_state.get();
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shared_quad_state_list_->push_back(shared_quad_state.Pass());
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return current_shared_quad_state_;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline bool AppendQuadInternal(
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<DrawQuad> draw_quad,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect culled_rect,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuadList* quad_list,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const OcclusionTrackerImpl& occlusion_tracker,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const LayerImpl* layer,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool create_debug_border_quads) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool keep_quad = !culled_rect.IsEmpty();
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (keep_quad)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_quad->visible_rect = culled_rect;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_tracker.overdraw_metrics()->DidCullForDrawing(
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_quad->quadTransform(), draw_quad->rect, culled_rect);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_draw_rect =
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_quad->opacity() == 1.0f ? draw_quad->opaque_rect : gfx::Rect();
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_tracker.overdraw_metrics()->
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DidDraw(draw_quad->quadTransform(), culled_rect, opaque_draw_rect);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (keep_quad) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (create_debug_border_quads && !draw_quad->IsDebugQuad() &&
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        draw_quad->visible_rect != draw_quad->rect) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkColor color = DebugColors::CulledTileBorderColor();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      float width = DebugColors::CulledTileBorderWidth(
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          layer ? layer->layer_tree_impl() : NULL);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          DebugBorderDrawQuad::Create();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      debug_border_quad->SetNew(
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          draw_quad->shared_quad_state, draw_quad->visible_rect, color, width);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      quad_list->push_back(debug_border_quad.PassAs<DrawQuad>());
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pass the quad after we're done using it.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    quad_list->push_back(draw_quad.Pass());
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return keep_quad;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuadCuller::Append(scoped_ptr<DrawQuad> draw_quad,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        AppendQuadsData* append_quads_data) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(draw_quad->shared_quad_state == current_shared_quad_state_);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!shared_quad_state_list_->empty());
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(shared_quad_state_list_->back() == current_shared_quad_state_);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect culled_rect;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_occlusion_from_outside_target_surface;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool impl_draw_transform_is_unknown = false;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (for_surface_) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    culled_rect = occlusion_tracker_.UnoccludedContributingSurfaceContentRect(
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        false,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        draw_quad->rect,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &has_occlusion_from_outside_target_surface);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    culled_rect = occlusion_tracker_.UnoccludedContentRect(
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_->render_target(),
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        draw_quad->rect,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        draw_quad->quadTransform(),
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        impl_draw_transform_is_unknown,
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        draw_quad->isClipped(),
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        draw_quad->clipRect(),
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &has_occlusion_from_outside_target_surface);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  append_quads_data->had_occlusion_from_outside_target_surface |=
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      has_occlusion_from_outside_target_surface;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AppendQuadInternal(draw_quad.Pass(),
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            culled_rect,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            quad_list_,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            occlusion_tracker_,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            layer_,
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            show_culling_with_debug_border_quads_);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
119