gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/dlist.cpp


From: Udo Giacomozzi
Subject: [Gnash-commit] gnash ChangeLog server/dlist.cpp
Date: Wed, 24 Oct 2007 12:20:05 +0000

CVSROOT:        /cvsroot/gnash
Module name:    gnash
Changes by:     Udo Giacomozzi <udog>   07/10/24 12:20:05

Modified files:
        .              : ChangeLog 
        server         : dlist.cpp 

Log message:
        server/dlist.cpp: optimize add_invalidated_bounds() for masks (don't 
invalidate outside of masks)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4682&r2=1.4683
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.cpp?cvsroot=gnash&r1=1.96&r2=1.97

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/gnash/gnash/ChangeLog,v
retrieving revision 1.4682
retrieving revision 1.4683
diff -u -b -r1.4682 -r1.4683
--- ChangeLog   24 Oct 2007 12:15:55 -0000      1.4682
+++ ChangeLog   24 Oct 2007 12:20:04 -0000      1.4683
@@ -2,6 +2,8 @@
 
        * libgeometry/snappingrange.h: add routines for calculating
          intersections between SnappingRanges    
+       * server/dlist.cpp: optimize add_invalidated_bounds() for
+    masks (don't invalidate outside of masks)  
 
 2007-10-24 Sandro Santilli <address@hidden>
 

Index: server/dlist.cpp
===================================================================
RCS file: /cvsroot/gnash/gnash/server/dlist.cpp,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -b -r1.96 -r1.97
--- server/dlist.cpp    17 Oct 2007 11:14:17 -0000      1.96
+++ server/dlist.cpp    24 Oct 2007 12:20:05 -0000      1.97
@@ -846,19 +846,131 @@
 void 
 DisplayList::add_invalidated_bounds(InvalidatedRanges& ranges, bool force)
 {
-    
        testInvariant();
 
+  /*
+  This function generally has nothing else to do than calling the 
+  add_invalidated_bounds() function of all items in the display list.
+  However, special optimization is included for masks, which makes it 
+  look a bit more complicated. We want to avoid that a masked character
+  invalidates an area where the character is invisible because of it's
+  mask (which is quite common). For example, think of a large bitmap that
+  covers the entire stage and is masked by a very small circle in the
+  middle of the stage (ie. it's only visible there). Changes in the 
+  bitmap sprite would invalidate the whole stage even if only the small 
+  masked portion in the middle really needs to be drawn again.
+  
+  So, like display(), we keep a stack of masks. Instead of drawing the
+  mask we keep a separate list of InvalidatedRanges for the masks which
+  later are intersected with the masked characters' InvalidatedRanges.
+  
+  The code is much based on the display() function, so some references
+  in comments have been added for convenience.
+  
+  For a simpler implementation (that doesn't care about masks, but 
+  still produces correct results) see CVS revision 1.96    
+  */
+  
+  std::stack<int> clipDepthStack; // same method used in display()
+  std::stack<InvalidatedRanges> rangesStack;
+  bool drawing_mask = false;
+
        iterator it = beginNonRemoved(_charsByDepth);
        for( iterator endIt = _charsByDepth.end(); it != endIt; ++it)
        {
                DisplayItem& dobj = *it;
+    
 #ifndef GNASH_USE_GC
                assert(dobj->get_ref_count() > 0);
 #endif // ndef GNASH_USE_GC
+
+
+    int depth = dobj->get_depth();    
+    // Discard useless masks
+    while (!clipDepthStack.empty() && (depth > clipDepthStack.top())) 
+    {
+      clipDepthStack.pop();
+
+      // also add mask to ranges because mask itself may have changed
+//      ranges.add(rangesStack.top());
+
+      rangesStack.pop();  // disable_mask() equivalent
+      
+    }
+    
+    int clipDepth = dobj->get_clip_depth();
+    // Push a new mask to the masks stack
+    if (clipDepth != character::noClipDepthValue) 
+    {
+      clipDepthStack.push(clipDepth);
+      
+      drawing_mask = true; // begin_submit_mask equivalent
+      
+      if (rangesStack.empty())    
+      {
+        InvalidatedRanges item;
+        rangesStack.push(item);
+      } else {
+        rangesStack.push(rangesStack.top()); // copy the top mask              
            
+      }
+    }
+    
+    // ==> display() equivalent
+    
+    if (drawing_mask) {
+    
+      // --> The child is part of a mask, so add ranges to our 
+      // mask ranges stack
+      
+      assert(!rangesStack.empty());
+      dobj->add_invalidated_bounds(rangesStack.top(), true);          
+      
+      // need to call add_invalidated_bounds again because the previous
+      // call needs force==true. Changes to the mask itself may also require
+      // re-rendering of the mask area, so we have to add the mask itself
+      // to the global ranges, but this time with normal "force" value...
+      // As long the mask has not been invalidated and force==false this
+      // call won't modify the "ranges" list.
                dobj->add_invalidated_bounds(ranges, force);
+      
+    } else {
+      
+      if (rangesStack.empty()) {
+      
+        // --> normal case for unmasked characters
+        dobj->add_invalidated_bounds(ranges, force);
+        
+      } else {
+      
+        // --> character is masked, so intersect with "mask"
+        
+        // first get the ranges of the child in a separate list
+        InvalidatedRanges childRanges;
+        childRanges.inheritConfig(ranges);
+        
+        dobj->add_invalidated_bounds(childRanges, force);
+        
+        // then intersect ranges with topmost "mask"
+        childRanges.intersect(rangesStack.top());
+        
+        // add result to the global ranges
+        ranges.add(childRanges);
+      
        }
        
+    } // not drawing mask 
+    
+    // <== end of display() equivalent
+    
+    
+    // Mask "drawing" has finished
+    if (dobj->isMask())
+    {
+      drawing_mask = false; // end_submit_mask equivalent
+    }
+  }
+  
+  
 }
 
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]