Home | History | Annotate | Download | only in trees
      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 
     17 namespace cc {
     18 
     19 QuadCuller::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 
     34 SharedQuadState* 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 
     43 static 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 
     80 bool 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 has_occlusion_from_outside_target_surface;
     88   bool impl_draw_transform_is_unknown = false;
     89 
     90   if (for_surface_) {
     91     culled_rect = occlusion_tracker_.UnoccludedContributingSurfaceContentRect(
     92         layer_,
     93         false,
     94         draw_quad->rect,
     95         &has_occlusion_from_outside_target_surface);
     96   } else {
     97     culled_rect = occlusion_tracker_.UnoccludedContentRect(
     98         layer_->render_target(),
     99         draw_quad->rect,
    100         draw_quad->quadTransform(),
    101         impl_draw_transform_is_unknown,
    102         draw_quad->isClipped(),
    103         draw_quad->clipRect(),
    104         &has_occlusion_from_outside_target_surface);
    105   }
    106 
    107   append_quads_data->had_occlusion_from_outside_target_surface |=
    108       has_occlusion_from_outside_target_surface;
    109 
    110   return AppendQuadInternal(draw_quad.Pass(),
    111                             culled_rect,
    112                             quad_list_,
    113                             occlusion_tracker_,
    114                             layer_,
    115                             show_culling_with_debug_border_quads_);
    116 }
    117 
    118 }  // namespace cc
    119