Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / cc / layers / tiled_layer.cc
index a650672..1f30b45 100644 (file)
 #include "base/auto_reset.h"
 #include "base/basictypes.h"
 #include "build/build_config.h"
-#include "cc/debug/overdraw_metrics.h"
+#include "cc/base/simple_enclosed_region.h"
 #include "cc/layers/layer_impl.h"
 #include "cc/layers/tiled_layer_impl.h"
 #include "cc/resources/layer_updater.h"
 #include "cc/resources/prioritized_resource.h"
 #include "cc/resources/priority_calculator.h"
 #include "cc/trees/layer_tree_host.h"
+#include "cc/trees/occlusion_tracker.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "ui/gfx/rect_conversions.h"
 
@@ -142,39 +143,38 @@ void TiledLayer::UpdateTileSizeAndTilingOption() {
 }
 
 void TiledLayer::UpdateBounds() {
-  gfx::Size old_bounds = tiler_->bounds();
-  gfx::Size new_bounds = content_bounds();
-  if (old_bounds == new_bounds)
+  gfx::Size old_tiling_size = tiler_->tiling_size();
+  gfx::Size new_tiling_size = content_bounds();
+  if (old_tiling_size == new_tiling_size)
     return;
-  tiler_->SetBounds(new_bounds);
+  tiler_->SetTilingSize(new_tiling_size);
 
   // Invalidate any areas that the new bounds exposes.
-  Region old_region = gfx::Rect(old_bounds);
-  Region new_region = gfx::Rect(new_bounds);
-  new_region.Subtract(old_region);
-  for (Region::Iterator new_rects(new_region);
-       new_rects.has_rect();
+  Region new_region =
+      SubtractRegions(gfx::Rect(new_tiling_size), gfx::Rect(old_tiling_size));
+  for (Region::Iterator new_rects(new_region); new_rects.has_rect();
        new_rects.next())
     InvalidateContentRect(new_rects.rect());
+  UpdateDrawsContent(HasDrawableContent());
 }
 
-void TiledLayer::SetTileSize(gfx::Size size) { tiler_->SetTileSize(size); }
+void TiledLayer::SetTileSize(const gfx::Size& size) {
+  tiler_->SetTileSize(size);
+  UpdateDrawsContent(HasDrawableContent());
+}
 
 void TiledLayer::SetBorderTexelOption(
     LayerTilingData::BorderTexelOption border_texel_option) {
   tiler_->SetBorderTexelOption(border_texel_option);
+  UpdateDrawsContent(HasDrawableContent());
 }
 
-bool TiledLayer::DrawsContent() const {
-  if (!ContentsScalingLayer::DrawsContent())
-    return false;
-
+bool TiledLayer::HasDrawableContent() const {
   bool has_more_than_one_tile =
-      tiler_->num_tiles_x() > 1 || tiler_->num_tiles_y() > 1;
-  if (tiling_option_ == NEVER_TILE && has_more_than_one_tile)
-    return false;
+      (tiler_->num_tiles_x() > 1) || (tiler_->num_tiles_y() > 1);
 
-  return true;
+  return !(tiling_option_ == NEVER_TILE && has_more_than_one_tile) &&
+         ContentsScalingLayer::HasDrawableContent();
 }
 
 void TiledLayer::ReduceMemoryUsage() {
@@ -221,7 +221,6 @@ void TiledLayer::PushPropertiesTo(LayerImpl* layer) {
         i,
         j,
         tile->managed_resource()->resource_id(),
-        tile->opaque_rect(),
         tile->managed_resource()->contents_swizzled());
   }
   for (std::vector<UpdatableTile*>::const_iterator iter = invalid_tiles.begin();
@@ -294,7 +293,7 @@ void TiledLayer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) {
   ContentsScalingLayer::SetNeedsDisplayRect(dirty_rect);
 }
 
-void TiledLayer::InvalidateContentRect(gfx::Rect content_rect) {
+void TiledLayer::InvalidateContentRect(const gfx::Rect& content_rect) {
   UpdateBounds();
   if (tiler_->is_empty() || content_rect.IsEmpty() || skips_draw_)
     return;
@@ -324,7 +323,7 @@ bool TiledLayer::UpdateTiles(int left,
                              int right,
                              int bottom,
                              ResourceUpdateQueue* queue,
-                             const OcclusionTracker* occlusion,
+                             const OcclusionTracker<Layer>* occlusion,
                              bool* updated) {
   CreateUpdaterIfNeeded();
 
@@ -334,18 +333,17 @@ bool TiledLayer::UpdateTiles(int left,
     return false;
   }
 
-  gfx::Rect paint_rect =
-      MarkTilesForUpdate(left, top, right, bottom, ignore_occlusions);
-
-  if (occlusion)
-    occlusion->overdraw_metrics()->DidPaint(paint_rect);
+  gfx::Rect update_rect;
+  gfx::Rect paint_rect;
+  MarkTilesForUpdate(
+    &update_rect, &paint_rect, left, top, right, bottom, ignore_occlusions);
 
   if (paint_rect.IsEmpty())
     return true;
 
   *updated = true;
   UpdateTileTextures(
-      paint_rect, left, top, right, bottom, queue, occlusion);
+      update_rect, paint_rect, left, top, right, bottom, queue, occlusion);
   return true;
 }
 
@@ -354,13 +352,7 @@ void TiledLayer::MarkOcclusionsAndRequestTextures(
     int top,
     int right,
     int bottom,
-    const OcclusionTracker* occlusion) {
-  // There is some difficult dependancies between occlusions, recording
-  // occlusion metrics and requesting memory so those are encapsulated in this
-  // function: - We only want to call RequestLate on unoccluded textures (to
-  // preserve memory for other layers when near OOM).  - We only want to record
-  // occlusion metrics if all memory requests succeed.
-
+    const OcclusionTracker<Layer>* occlusion) {
   int occluded_tile_count = 0;
   bool succeeded = true;
   for (int j = top; j <= bottom; ++j) {
@@ -375,10 +367,9 @@ void TiledLayer::MarkOcclusionsAndRequestTextures(
       DCHECK(!tile->occluded);
       gfx::Rect visible_tile_rect = gfx::IntersectRects(
           tiler_->tile_bounds(i, j), visible_content_rect());
-      if (occlusion && occlusion->Occluded(render_target(),
-                                           visible_tile_rect,
-                                           draw_transform(),
-                                           draw_transform_is_animating())) {
+      if (!draw_transform_is_animating() && occlusion &&
+          occlusion->GetCurrentOcclusionForLayer(draw_transform())
+              .IsOccluded(visible_tile_rect)) {
         tile->occluded = true;
         occluded_tile_count++;
       } else {
@@ -386,11 +377,6 @@ void TiledLayer::MarkOcclusionsAndRequestTextures(
       }
     }
   }
-
-  if (!succeeded)
-    return;
-  if (occlusion)
-    occlusion->overdraw_metrics()->DidCullTilesForUpload(occluded_tile_count);
 }
 
 bool TiledLayer::HaveTexturesForTiles(int left,
@@ -422,12 +408,13 @@ bool TiledLayer::HaveTexturesForTiles(int left,
   return true;
 }
 
-gfx::Rect TiledLayer::MarkTilesForUpdate(int left,
-                                         int top,
-                                         int right,
-                                         int bottom,
-                                         bool ignore_occlusions) {
-  gfx::Rect paint_rect;
+void TiledLayer::MarkTilesForUpdate(gfx::Rect* update_rect,
+                                    gfx::Rect* paint_rect,
+                                    int left,
+                                    int top,
+                                    int right,
+                                    int bottom,
+                                    bool ignore_occlusions) {
   for (int j = top; j <= bottom; ++j) {
     for (int i = left; i <= right; ++i) {
       UpdatableTile* tile = TileAt(i, j);
@@ -437,6 +424,10 @@ gfx::Rect TiledLayer::MarkTilesForUpdate(int left,
         continue;
       if (tile->occluded && !ignore_occlusions)
         continue;
+
+      // Prepare update rect from original dirty rects.
+      update_rect->Union(tile->dirty_rect);
+
       // TODO(reveman): Decide if partial update should be allowed based on cost
       // of update. https://bugs.webkit.org/show_bug.cgi?id=77376
       if (tile->is_dirty() &&
@@ -455,29 +446,25 @@ gfx::Rect TiledLayer::MarkTilesForUpdate(int left,
         }
       }
 
-      paint_rect.Union(tile->dirty_rect);
+      paint_rect->Union(tile->dirty_rect);
       tile->MarkForUpdate();
     }
   }
-  return paint_rect;
 }
 
-void TiledLayer::UpdateTileTextures(gfx::Rect paint_rect,
+void TiledLayer::UpdateTileTextures(const gfx::Rect& update_rect,
+                                    const gfx::Rect& paint_rect,
                                     int left,
                                     int top,
                                     int right,
                                     int bottom,
                                     ResourceUpdateQueue* queue,
-                                    const OcclusionTracker* occlusion) {
+                                    const OcclusionTracker<Layer>* occlusion) {
   // The update_rect should be in layer space. So we have to convert the
   // paint_rect from content space to layer space.
-  float width_scale =
-      paint_properties().bounds.width() /
-      static_cast<float>(content_bounds().width());
-  float height_scale =
-      paint_properties().bounds.height() /
-      static_cast<float>(content_bounds().height());
-  update_rect_ = gfx::ScaleRect(paint_rect, width_scale, height_scale);
+  float width_scale = 1 / draw_properties().contents_scale_x;
+  float height_scale = 1 / draw_properties().contents_scale_y;
+  update_rect_ = gfx::ScaleRect(update_rect, width_scale, height_scale);
 
   // Calling PrepareToUpdate() calls into WebKit to paint, which may have the
   // side effect of disabling compositing, which causes our reference to the
@@ -485,12 +472,11 @@ void TiledLayer::UpdateTileTextures(gfx::Rect paint_rect,
   // the SkCanvas until the paint finishes, so we grab a local reference here to
   // hold the updater alive until the paint completes.
   scoped_refptr<LayerUpdater> protector(Updater());
-  gfx::Rect painted_opaque_rect;
-  Updater()->PrepareToUpdate(paint_rect,
+  Updater()->PrepareToUpdate(content_bounds(),
+                             paint_rect,
                              tiler_->tile_size(),
                              1.f / width_scale,
-                             1.f / height_scale,
-                             &painted_opaque_rect);
+                             1.f / height_scale);
 
   for (int j = top; j <= bottom; ++j) {
     for (int i = left; i <= right; ++i) {
@@ -508,27 +494,6 @@ void TiledLayer::UpdateTileTextures(gfx::Rect paint_rect,
       if (dirty_rect.IsEmpty())
         continue;
 
-      // Save what was painted opaque in the tile. Keep the old area if the
-      // paint didn't touch it, and didn't paint some other part of the tile
-      // opaque.
-      gfx::Rect tile_painted_rect = gfx::IntersectRects(tile_rect, paint_rect);
-      gfx::Rect tile_painted_opaque_rect =
-          gfx::IntersectRects(tile_rect, painted_opaque_rect);
-      if (!tile_painted_rect.IsEmpty()) {
-        gfx::Rect paint_inside_tile_opaque_rect =
-            gfx::IntersectRects(tile->opaque_rect(), tile_painted_rect);
-        bool paint_inside_tile_opaque_rect_is_non_opaque =
-            !paint_inside_tile_opaque_rect.IsEmpty() &&
-            !tile_painted_opaque_rect.Contains(paint_inside_tile_opaque_rect);
-        bool opaque_paint_not_inside_tile_opaque_rect =
-            !tile_painted_opaque_rect.IsEmpty() &&
-            !tile->opaque_rect().Contains(tile_painted_opaque_rect);
-
-        if (paint_inside_tile_opaque_rect_is_non_opaque ||
-            opaque_paint_not_inside_tile_opaque_rect)
-          tile->set_opaque_rect(tile_painted_opaque_rect);
-      }
-
       // source_rect starts as a full-sized tile with border texels included.
       gfx::Rect source_rect = tiler_->TileRect(tile);
       source_rect.Intersect(dirty_rect);
@@ -557,10 +522,6 @@ void TiledLayer::UpdateTileTextures(gfx::Rect paint_rect,
 
       tile->updater_resource()->Update(
           queue, source_rect, dest_offset, tile->partial_update);
-      if (occlusion) {
-        occlusion->overdraw_metrics()->
-            DidUpload(gfx::Transform(), source_rect, tile->opaque_rect());
-      }
     }
   }
 }
@@ -586,8 +547,8 @@ namespace {
 // TODO(epenner): Remove this and make this based on distance once distance can
 // be calculated for offscreen layers. For now, prioritize all small animated
 // layers after 512 pixels of pre-painting.
-void SetPriorityForTexture(gfx::Rect visible_rect,
-                           gfx::Rect tile_rect,
+void SetPriorityForTexture(const gfx::Rect& visible_rect,
+                           const gfx::Rect& tile_rect,
                            bool draws_to_root,
                            bool is_small_animated_layer,
                            PrioritizedResource* texture) {
@@ -652,12 +613,10 @@ void TiledLayer::SetTexturePriorities(const PriorityCalculator& priority_calc) {
   }
 }
 
-Region TiledLayer::VisibleContentOpaqueRegion() const {
+SimpleEnclosedRegion TiledLayer::VisibleContentOpaqueRegion() const {
   if (skips_draw_)
-    return Region();
-  if (contents_opaque())
-    return visible_content_rect();
-  return tiler_->OpaqueRegionInContentRect(visible_content_rect());
+    return SimpleEnclosedRegion();
+  return Layer::VisibleContentOpaqueRegion();
 }
 
 void TiledLayer::ResetUpdateState() {
@@ -677,7 +636,7 @@ void TiledLayer::ResetUpdateState() {
 }
 
 namespace {
-gfx::Rect ExpandRectByDelta(gfx::Rect rect, gfx::Vector2d delta) {
+gfx::Rect ExpandRectByDelta(const gfx::Rect& rect, const gfx::Vector2d& delta) {
   int width = rect.width() + std::abs(delta.x());
   int height = rect.height() + std::abs(delta.y());
   int x = rect.x() + ((delta.x() < 0) ? delta.x() : 0);
@@ -723,7 +682,7 @@ void TiledLayer::UpdateScrollPrediction() {
 }
 
 bool TiledLayer::Update(ResourceUpdateQueue* queue,
-                        const OcclusionTracker* occlusion) {
+                        const OcclusionTracker<Layer>* occlusion) {
   DCHECK(!skips_draw_ && !failed_update_);  // Did ResetUpdateState get skipped?
 
   // Tiled layer always causes commits to wait for activation, as it does