Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / cc / resources / picture_pile.cc
index 3037521..46f589e 100644 (file)
@@ -226,34 +226,151 @@ bool PicturePile::UpdateAndExpandInvalidation(
     gfx::Rect old_tiling_rect_over_tiles =
         tiling_.ExpandRectToTileBounds(gfx::Rect(old_tiling_size));
     if (min_toss_x < tiling_.num_tiles_x()) {
-      int unrecorded_left = std::max(tiling_.TilePositionX(min_toss_x),
-                                     interest_rect_over_tiles.right());
+      // The bounds which we want to invalidate are the tiles along the old
+      // edge of the pile. We'll call this bounding box the OLD EDGE RECT.
+      //
+      // In the picture below, the old edge rect would be the bounding box
+      // of tiles {h,i,j}. |min_toss_x| would be equal to the horizontal index
+      // of the same tiles.
+      //
+      //  old pile edge-v  new pile edge-v
+      // ---------------+ - - - - - - - -+
+      // mmppssvvyybbeeh|h               .
+      // mmppssvvyybbeeh|h               .
+      // nnqqttwwzzccffi|i               .
+      // nnqqttwwzzccffi|i               .
+      // oorruuxxaaddggj|j               .
+      // oorruuxxaaddggj|j               .
+      // ---------------+ - - - - - - - -+ <- old pile edge
+      //                                 .
+      //  - - - - - - - - - - - - - - - -+ <- new pile edge
+      //
+      // If you were to slide a vertical beam from the left edge of the
+      // old edge rect toward the right, it would either hit the right edge
+      // of the old edge rect, or the interest rect (expanded to the bounds
+      // of the tiles it touches). The same is true for a beam parallel to
+      // any of the four edges, sliding accross the old edge rect. We use
+      // the union of these four rectangles generated by these beams to
+      // determine which part of the old edge rect is outside of the expanded
+      // interest rect.
+      //
+      // Case 1: Intersect rect is outside the old edge rect. It can be
+      // either on the left or the right. The |left_rect| and |right_rect|,
+      // cover this case, one will be empty and one will cover the full
+      // old edge rect. In the picture below, |left_rect| would cover the
+      // old edge rect, and |right_rect| would be empty.
+      // +----------------------+ |^^^^^^^^^^^^^^^|
+      // |===>   OLD EDGE RECT  | |               |
+      // |===>                  | | INTEREST RECT |
+      // |===>                  | |               |
+      // |===>                  | |               |
+      // +----------------------+ |vvvvvvvvvvvvvvv|
+      //
+      // Case 2: Interest rect is inside the old edge rect. It will always
+      // fill the entire old edge rect horizontally since the old edge rect
+      // is a single tile wide, and the interest rect has been expanded to the
+      // bounds of the tiles it touches. In this case the |left_rect| and
+      // |right_rect| will be empty, but the case is handled by the |top_rect|
+      // and |bottom_rect|. In the picture below, neither the |top_rect| nor
+      // |bottom_rect| would empty, they would each cover the area of the old
+      // edge rect outside the expanded interest rect.
+      // +-----------------+
+      // |:::::::::::::::::|
+      // |:::::::::::::::::|
+      // |vvvvvvvvvvvvvvvvv|
+      // |                 |
+      // +-----------------+
+      // | INTEREST RECT   |
+      // |                 |
+      // +-----------------+
+      // |                 |
+      // | OLD EDGE RECT   |
+      // +-----------------+
+      //
+      // Lastly, we need to consider tiles inside the expanded interest rect.
+      // For those tiles, we want to invalidate exactly the newly exposed
+      // pixels. In the picture below the tiles in the old edge rect have been
+      // resized and the area covered by periods must be invalidated. The
+      // |exposed_rect| will cover exactly that area.
+      //           v-old pile edge
+      // +---------+-------+
+      // |         ........|
+      // |         ........|
+      // |  OLD EDGE.RECT..|
+      // |         ........|
+      // |         ........|
+      // |         ........|
+      // |         ........|
+      // |         ........|
+      // |         ........|
+      // +---------+-------+
+
+      int left = tiling_.TilePositionX(min_toss_x);
+      int right = left + tiling_.TileSizeX(min_toss_x);
+      int top = old_tiling_rect_over_tiles.y();
+      int bottom = old_tiling_rect_over_tiles.bottom();
+
+      int left_until = std::min(interest_rect_over_tiles.x(), right);
+      int right_until = std::max(interest_rect_over_tiles.right(), left);
+      int top_until = std::min(interest_rect_over_tiles.y(), bottom);
+      int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
+
       int exposed_left = old_tiling_size.width();
-      int left = std::min(unrecorded_left, exposed_left);
-      int tile_right =
-          tiling_.TilePositionX(min_toss_x) + tiling_.TileSizeX(min_toss_x);
-      int exposed_right = tiling_size().width();
-      int right = std::min(tile_right, exposed_right);
-      gfx::Rect right_side(left,
-                           old_tiling_rect_over_tiles.y(),
-                           right - left,
-                           old_tiling_rect_over_tiles.height());
-      resize_invalidation.Union(right_side);
+      int exposed_left_until = tiling_size().width();
+      int exposed_top = top;
+      int exposed_bottom = tiling_size().height();
+      DCHECK_GE(exposed_left, left);
+
+      gfx::Rect left_rect(left, top, left_until - left, bottom - top);
+      gfx::Rect right_rect(right_until, top, right - right_until, bottom - top);
+      gfx::Rect top_rect(left, top, right - left, top_until - top);
+      gfx::Rect bottom_rect(
+          left, bottom_until, right - left, bottom - bottom_until);
+      gfx::Rect exposed_rect(exposed_left,
+                             exposed_top,
+                             exposed_left_until - exposed_left,
+                             exposed_bottom - exposed_top);
+      resize_invalidation.Union(left_rect);
+      resize_invalidation.Union(right_rect);
+      resize_invalidation.Union(top_rect);
+      resize_invalidation.Union(bottom_rect);
+      resize_invalidation.Union(exposed_rect);
     }
     if (min_toss_y < tiling_.num_tiles_y()) {
-      int unrecorded_top = std::max(tiling_.TilePositionY(min_toss_y),
-                                    interest_rect_over_tiles.bottom());
+      // The same thing occurs here as in the case above, but the invalidation
+      // rect is the bounding box around the bottom row of tiles in the old
+      // pile. This would be tiles {o,r,u,x,a,d,g,j} in the above picture.
+
+      int top = tiling_.TilePositionY(min_toss_y);
+      int bottom = top + tiling_.TileSizeY(min_toss_y);
+      int left = old_tiling_rect_over_tiles.x();
+      int right = old_tiling_rect_over_tiles.right();
+
+      int top_until = std::min(interest_rect_over_tiles.y(), bottom);
+      int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
+      int left_until = std::min(interest_rect_over_tiles.x(), right);
+      int right_until = std::max(interest_rect_over_tiles.right(), left);
+
       int exposed_top = old_tiling_size.height();
-      int top = std::min(unrecorded_top, exposed_top);
-      int tile_bottom =
-          tiling_.TilePositionY(min_toss_y) + tiling_.TileSizeY(min_toss_y);
-      int exposed_bottom = tiling_size().height();
-      int bottom = std::min(tile_bottom, exposed_bottom);
-      gfx::Rect bottom_side(old_tiling_rect_over_tiles.x(),
-                            top,
-                            old_tiling_rect_over_tiles.width(),
-                            bottom - top);
-      resize_invalidation.Union(bottom_side);
+      int exposed_top_until = tiling_size().height();
+      int exposed_left = left;
+      int exposed_right = tiling_size().width();
+      DCHECK_GE(exposed_top, top);
+
+      gfx::Rect left_rect(left, top, left_until - left, bottom - top);
+      gfx::Rect right_rect(right_until, top, right - right_until, bottom - top);
+      gfx::Rect top_rect(left, top, right - left, top_until - top);
+      gfx::Rect bottom_rect(
+          left, bottom_until, right - left, bottom - bottom_until);
+      gfx::Rect exposed_rect(exposed_left,
+                             exposed_top,
+                             exposed_right - exposed_left,
+                             exposed_top_until - exposed_top);
+      resize_invalidation.Union(left_rect);
+      resize_invalidation.Union(right_rect);
+      resize_invalidation.Union(top_rect);
+      resize_invalidation.Union(bottom_rect);
+      resize_invalidation.Union(exposed_rect);
     }
   }