[Top][All Lists]
[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
+ }
+ }
+
+
}
- [Gnash-commit] gnash ChangeLog server/dlist.cpp,
Udo Giacomozzi <=