[haiku-commits] haiku: hrev53392 - src/kits/tracker

  • From: Ryan Leavengood <leavengood@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 20 Aug 2019 22:10:20 -0400 (EDT)

hrev53392 adds 1 changeset to branch 'master'
old head: 5eec8d3be6a386fb55f7a458f0f807d51829b05a
new head: d2a69b8bd92ae12fb9b8da5def538e07784746c5
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=d2a69b8bd92a+%5E5eec8d3be6a3

----------------------------------------------------------------------------

d2a69b8bd92a: Tracker: Improve pose loading speed, add comments
  
  If a new pose is going to be placed below the current view bounds, we
  definitely do not need to do any drawing. If it is above or inside the view
  bounds we do this special drawing method.
  
  Overall this method of doing updates is complicated and hard to adjust without
  introducing drawing artifacts. As noted in the TODO, this should be rethought
  from scratch.
  
  But for now in one case of over 8000 files in a single directory this improved
  the loading speed from about 8 or 9 seconds to 1. Queries results also load
  much faster. I am testing in a VM with a single CPU on a host with an SSD, so
  others may see better performance with more CPUs, or less with a spinning hard
  drive.
  
  But at least now the drawing won't be the bottleneck.
  
  Should finally fully fix #3011, or at least good enough for close.
  
  Change-Id: I3806ffa7674e404c9db24edb33d6ab4eb2d825f7
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/1726
  Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

                                  [ Ryan Leavengood <leavengood@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev53392
Commit:      d2a69b8bd92ae12fb9b8da5def538e07784746c5
URL:         https://git.haiku-os.org/haiku/commit/?id=d2a69b8bd92a
Author:      Ryan Leavengood <leavengood@xxxxxxxxx>
Date:        Tue Aug 20 22:02:04 2019 UTC

Ticket:      https://dev.haiku-os.org/ticket/3011

----------------------------------------------------------------------------

1 file changed, 76 insertions(+), 53 deletions(-)
src/kits/tracker/PoseView.cpp | 129 ++++++++++++++++++++++----------------

----------------------------------------------------------------------------

diff --git a/src/kits/tracker/PoseView.cpp b/src/kits/tracker/PoseView.cpp
index 4dd193e153..a832b72a08 100644
--- a/src/kits/tracker/PoseView.cpp
+++ b/src/kits/tracker/PoseView.cpp
@@ -1783,8 +1783,8 @@ BPoseView::AddPoseToList(PoseList* list, bool 
visibleList, bool insertionSort,
        bool addedItem = false;
        bool needToDraw = true;
 
-       if (insertionSort && list->CountItems() > 0) {
-               int32 orientation = BSearchList(list, pose, &poseIndex, 0);
+       if (insertionSort && poseIndex > 0) {
+               int32 orientation = BSearchList(list, pose, &poseIndex, 
poseIndex);
 
                if (orientation == kInsertAfter)
                        poseIndex++;
@@ -1794,50 +1794,72 @@ BPoseView::AddPoseToList(PoseList* list, bool 
visibleList, bool insertionSort,
                        poseBounds = CalcPoseRectList(pose, poseIndex);
                        havePoseBounds = true;
 
-                       BRect srcRect(Extent());
-                       srcRect.top = poseBounds.top;
-                       srcRect = srcRect & viewBounds;
-                       BRect destRect(srcRect);
-                       destRect.OffsetBy(0, fListElemHeight);
-
-                       // special case the addition of a pose that scrolls
-                       // the extent into the view for the first time:
-                       if (destRect.bottom > viewBounds.top
-                               && destRect.top > destRect.bottom) {
-                               // make destRect valid
-                               destRect.top = viewBounds.top;
-                       }
+                       // Simple optimization: if the new pose bounds is 
completely below
+                       // the current view bounds, we do not need to draw.
+                       if (poseBounds.top > viewBounds.bottom) {
+                               needToDraw = false;
+                       } else {
+                               // The new pose may need to be placed where 
another pose already
+                               // is. This code creates some rects where we 
either need to
+                               // slide some already drawn poses down, or at 
least update the
+                               // rect where the new pose is.
+                               BRect srcRect(Extent());
+                               srcRect.top = poseBounds.top;
+                               srcRect = srcRect & viewBounds;
+                               BRect destRect(srcRect);
+                               destRect.OffsetBy(0, fListElemHeight);
+
+                               // special case the addition of a pose that 
scrolls
+                               // the extent into the view for the first time:
+                               if (destRect.bottom > viewBounds.top
+                                       && destRect.top > destRect.bottom) {
+                                       // make destRect valid
+                                       destRect.top = viewBounds.top;
+                               }
 
-                       if (srcRect.Intersects(viewBounds)
-                               || destRect.Intersects(viewBounds)) {
-                               // The visual area is affected by the insertion.
-                               // If items have been added above the visual 
area,
-                               // delay the scrolling. srcRect.bottom holds the
-                               // current Extent(). So if the bottom is still 
above
-                               // the viewBounds top, it means the view is 
scrolled
-                               // to show the area below the items that have 
already
-                               // been added.
-                               if (srcRect.top == viewBounds.top
-                                       && srcRect.bottom >= viewBounds.top
-                                       && poseIndex != 0) {
-                                       // if new pose above current view 
bounds, cache up
-                                       // the draw and do it later
-                                       listViewScrollBy += fListElemHeight;
-                                       needToDraw = false;
-                               } else {
-                                       FinishPendingScroll(listViewScrollBy, 
viewBounds);
-                                       list->AddItem(pose, poseIndex);
-
-                                       fMimeTypeListIsDirty = true;
-                                       addedItem = true;
-                                       if (srcRect.IsValid()) {
-                                               CopyBits(srcRect, destRect);
-                                               srcRect.bottom = destRect.top;
-                                               SynchronousUpdate(srcRect);
+                               // TODO: As long as either srcRect or destRect 
are valid, this
+                               // will always be true because srcRect is built 
from viewBounds.
+                               // Many times they are not valid, but most of 
the time they are,
+                               // and in a folder with a lot of contents this 
causes a lot of
+                               // unnecessary drawing. Hence the optimization 
above. This all
+                               // just needs to be rethought completely. 
Similar code is in
+                               // BPoseView::InsertPoseAfter.
+                               if (srcRect.Intersects(viewBounds)
+                                       || destRect.Intersects(viewBounds)) {
+                                       // The visual area is affected by the 
insertion.
+                                       // If items have been added above the 
visual area,
+                                       // delay the scrolling. srcRect.bottom 
holds the
+                                       // current Extent(). So if the bottom 
is still above
+                                       // the viewBounds top, it means the 
view is scrolled
+                                       // to show the area below the items 
that have already
+                                       // been added.
+                                       if (srcRect.top == viewBounds.top
+                                               && srcRect.bottom >= 
viewBounds.top
+                                               && poseIndex != 0) {
+                                               // if new pose above current 
view bounds, cache up
+                                               // the draw and do it later
+                                               listViewScrollBy += 
fListElemHeight;
+                                               needToDraw = false;
                                        } else {
-                                               SynchronousUpdate(destRect);
+                                               
FinishPendingScroll(listViewScrollBy, viewBounds);
+                                               list->AddItem(pose, poseIndex);
+
+                                               fMimeTypeListIsDirty = true;
+                                               addedItem = true;
+                                               if (srcRect.IsValid()) {
+                                                       // Slide the already 
drawn bits down.
+                                                       CopyBits(srcRect, 
destRect);
+                                                       // Shrink the srcRect 
down to the just the part that
+                                                       // needs to be redrawn.
+                                                       srcRect.bottom = 
destRect.top;
+                                                       
SynchronousUpdate(srcRect);
+                                               } else {
+                                                       // This is probably the 
bottom of the view or just
+                                                       // got scrolled into 
view.
+                                                       
SynchronousUpdate(destRect);
+                                               }
+                                               needToDraw = false;
                                        }
-                                       needToDraw = false;
                                }
                        }
                }
@@ -9289,6 +9311,7 @@ PoseCompareAddWidget(const BPose* p1, const BPose* p2, 
BPoseView* view)
        }
 
        int32 result = 0;
+       // We perform a loop in case there is a secondary sort
        for (int32 count = 0; ; count++) {
                BTextWidget* widget1 = primary->WidgetFor(sort);
                if (widget1 == NULL)
@@ -9303,19 +9326,19 @@ PoseCompareAddWidget(const BPose* p1, const BPose* p2, 
BPoseView* view)
 
                result = widget1->Compare(*widget2, view);
 
-               if (count != 0)
+               // We either have a non-equal result, or are on the second 
iteration
+               // for secondary sort. Either way, return.
+               if (result != 0 || count != 0)
                        return result;
 
-               // do we need to sort by secondary attribute?
-               if (result == 0) {
-                       sort = view->SecondarySort();
-                       if (!sort)
-                               return result;
+               // Non-equal result, sort by secondary attribute
+               sort = view->SecondarySort();
+               if (!sort)
+                       return result;
 
-                       column = view->ColumnFor(sort);
-                       if (column == NULL)
-                               return result;
-               }
+               column = view->ColumnFor(sort);
+               if (column == NULL)
+                       return result;
        }
 
        return result;


Other related posts:

  • » [haiku-commits] haiku: hrev53392 - src/kits/tracker - Ryan Leavengood