[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/dlist.cpp server/dlist.h...
From: |
Zou Lunkai |
Subject: |
[Gnash-commit] gnash ChangeLog server/dlist.cpp server/dlist.h... |
Date: |
Mon, 03 Dec 2007 07:06:15 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Zou Lunkai <zoulunkai> 07/12/03 07:06:15
Modified files:
. : ChangeLog
server : dlist.cpp dlist.h sprite_instance.cpp
sprite_instance.h
testsuite/misc-ming.all: loop_test-Runner.cpp loop_test10.c
Log message:
* server/dlist.{h, cpp}: add mergeDisplayList() for timeline control
attempt5.
* server/sprite_instance.{h,cpp): restoreDisplayList(), use the new
mergeDisplayList() interface; cleanups for executing a PlaceObject2
tag.
* testsuite/misc-ming.all/loop_test10.c: xchecks to checks.
* testsuite/misc-ming.all/loop_test-Runner.cpp: allow a invalidated
bound
detection regression, one check to xcheck. This regression is caused
by
always invalidating a looping back character, could be fixed in later
optimization step.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5059&r2=1.5060
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.cpp?cvsroot=gnash&r1=1.104&r2=1.105
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.h?cvsroot=gnash&r1=1.57&r2=1.58
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.401&r2=1.402
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.h?cvsroot=gnash&r1=1.151&r2=1.152
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/loop_test-Runner.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/loop_test10.c?cvsroot=gnash&r1=1.2&r2=1.3
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5059
retrieving revision 1.5060
diff -u -b -r1.5059 -r1.5060
--- ChangeLog 3 Dec 2007 05:29:33 -0000 1.5059
+++ ChangeLog 3 Dec 2007 07:06:14 -0000 1.5060
@@ -1,3 +1,13 @@
+2007-12-03 Zou Lunkai <address@hidden>
+ * server/dlist.{h, cpp}: add mergeDisplayList() for timeline control
attempt5.
+ * server/sprite_instance.{h,cpp): restoreDisplayList(), use the new
+ mergeDisplayList() interface; cleanups for executing a PlaceObject2
tag.
+ * testsuite/misc-ming.all/loop_test10.c: xchecks to checks.
+ * testsuite/misc-ming.all/loop_test-Runner.cpp: allow a invalidated
bound
+ detection regression, one check to xcheck. This regression is caused
by
+ always invalidating a looping back character, could be fixed in later
+ optimization step.
+
2007-12-02 Bastiaan Jacques <address@hidden>
* backend/render_handler{.h,_ogl.cpp,_agg.cpp,_cairo.cpp},
Index: server/dlist.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/dlist.cpp,v
retrieving revision 1.104
retrieving revision 1.105
diff -u -b -r1.104 -r1.105
--- server/dlist.cpp 27 Nov 2007 11:28:50 -0000 1.104
+++ server/dlist.cpp 3 Dec 2007 07:06:14 -0000 1.105
@@ -744,6 +744,34 @@
}
+
+void
+DisplayList::destroy()
+{
+ //GNASH_REPORT_FUNCTION;
+
+ testInvariant();
+
+ // Should we start looking from beginNonRemoved ?
+ // If I try, I get a failure in swfdec/gotoframe.swf
+ for (iterator it = _charsByDepth.begin(), itEnd = _charsByDepth.end(); it !=
itEnd; )
+ {
+ // make a copy
+ DisplayItem di = *it;
+
+ // skip if already unloaded
+ if ( di->isDestroyed() )
+ {
+ ++it;
+ continue;
+ }
+
+ di->destroy();
+ it = _charsByDepth.erase(it);
+ }
+ testInvariant();
+}
+
// Display the referenced characters. Lower depths
// are obscured by higher depths.
void
@@ -1003,6 +1031,156 @@
_charsByDepth.sort(DisplayItemDepthLess());
}
+void
+DisplayList::mergeDisplayList(DisplayList & newList)
+{
+ testInvariant();
+
+ iterator itOld = beginNonRemoved(_charsByDepth);
+ iterator itNew = beginNonRemoved(newList._charsByDepth);
+
+ iterator itOldEnd = staticZoneEnd(_charsByDepth);
+ iterator itNewEnd = staticZoneEnd(newList._charsByDepth);
+
+ while( itOld != itOldEnd )
+ {
+ iterator itOldBack = itOld;
+
+ boost::intrusive_ptr<character> chOld = itOldBack->get();
+ int depthOld = chOld->get_depth();
+
+ while( itNew != itNewEnd )
+ {
+ iterator itNewBack = itNew;
+
+ boost::intrusive_ptr<character> chNew =
itNewBack->get();
+ int depthNew = chNew->get_depth();
+
+ // unload the old character if it is not in the new list
+ if( depthOld < depthNew )
+ {
+ itOld++;
+
+ _charsByDepth.erase(itOldBack);
+
+ if ( chOld->unload() )
+ {
+ reinsertRemovedCharacter(chOld);
+ }
+ else
+ {
+ chOld->destroy();
+ }
+
+ break;
+ }
+ // if depth is occupied in both lists
+ else if( depthOld == depthNew )
+ {
+ itOld++;
+ itNew++;
+
+ bool is_ratio_compatible = ( (
chOld->get_ratio() == chNew->get_ratio() )
+ || ( chOld->get_ratio()==0 &&
chNew->get_ratio()==character::noRatioValue )
+ || (
chOld->get_ratio()==character::noRatioValue && chNew->get_ratio()==0 ) );
+
+ if( !is_ratio_compatible || chOld->isDynamic()
|| !chOld->isActionScriptReferenceable() )
+ {
+ // replace the old character with the
character in the new depth
+ _charsByDepth.insert(itOldBack,
*itNewBack);
+ _charsByDepth.erase(itOldBack);
+
+ // unload the old character
+ if ( chOld->unload() )
+ {
+ reinsertRemovedCharacter(chOld);
+ }
+ else
+ {
+ chOld->destroy();
+ }
+ }
+ else
+ {
+ newList._charsByDepth.erase(itNewBack);
+
+ // replace the transformation matrix if
the old character accepts transform
+ if( chOld->get_accept_anim_moves() )
+ {
+
chOld->set_matrix(chNew->get_matrix());
+
chOld->set_cxform(chNew->get_cxform());
+
+ // TODO: update the name if
needed
+
//chOld->set_name(chNew->get_name().c_str());
+ }
+ chNew->unload();
+ chNew->destroy();
+ }
+
+ break;
+ }
+ // add the new character if it is not in the old list
+ else
+ {
+ itNew++;
+
+ _charsByDepth.insert(itOldBack, *itNewBack );
+ }
+ }// end of while
+
+ if( itNew == itNewEnd )
+ {
+ break;
+ }
+ }// end of while
+
+ // unload remaining characters in old list
+ while( itOld != itOldEnd )
+ {
+ boost::intrusive_ptr<character> chOld = itOld->get();
+
+ itOld = _charsByDepth.erase(itOld);
+
+ if ( chOld->unload() )
+ {
+ reinsertRemovedCharacter(chOld);
+ }
+ else
+ {
+ chOld->destroy();
+ }
+ }
+
+ // add remaining characters in new list to the old list
+ if( itNew != itNewEnd )
+ {
+ _charsByDepth.insert(itOld, itNew, itNewEnd);
+ }
+
+ // Copy all unloaded characters from the new display list to the old
display list,
+ // and clear the new display list
+ for (itNew = newList._charsByDepth.begin(); itNew != itNewEnd; ++itNew)
+ {
+ boost::intrusive_ptr<character> chNew = itNew->get();
+ int depthNew = chNew->get_depth();
+
+ if( chNew->isUnloaded() )
+ {
+ iterator it = find_if(_charsByDepth.begin(),
_charsByDepth.end(),
+ DepthGreaterOrEqual(depthNew));
+
+ _charsByDepth.insert(it, *itNew);
+ }
+ }
+
+ // clear the new display list after merge
+ newList._charsByDepth.clear();
+
+ testInvariant();
+}
+
+
+
std::ostream& operator<< (std::ostream& os, const DisplayList& dl)
{
os << "By depth: ";
@@ -1025,14 +1203,13 @@
DisplayList::reinsertRemovedCharacter(boost::intrusive_ptr<character> ch)
{
assert(ch->isUnloaded());
+ testInvariant();
// TODO: have this done by character::unload() instead ?
int oldDepth = ch->get_depth();
int newDepth = character::removedDepthOffset - oldDepth;
ch->set_depth(newDepth);
- testInvariant();
-
// TODO: optimize this by searching from the end(lowest depth).
container_type::iterator it = find_if(
_charsByDepth.begin(), _charsByDepth.end(),
@@ -1059,6 +1236,20 @@
DepthGreaterOrEqual(character::removedDepthOffset -
character::staticDepthOffset));
}
+/*private static*/
+DisplayList::iterator
+DisplayList::staticZoneEnd(container_type& c)
+{
+ return std::find_if(c.begin(), c.end(), DepthGreaterOrEqual(0));
+}
+
+/*private static*/
+DisplayList::const_iterator
+DisplayList::staticZoneEnd(const container_type& c)
+{
+ return std::find_if(c.begin(), c.end(), DepthGreaterOrEqual(0));
+}
+
void
DisplayList::removeUnloaded()
{
Index: server/dlist.h
===================================================================
RCS file: /sources/gnash/gnash/server/dlist.h,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -b -r1.57 -r1.58
--- server/dlist.h 1 Dec 2007 00:14:59 -0000 1.57
+++ server/dlist.h 3 Dec 2007 07:06:15 -0000 1.58
@@ -215,6 +215,8 @@
///
bool unload();
+ void destroy();
+
/// Add all characters in the list, maintaining depth-order
//
/// @param chars
@@ -382,6 +384,10 @@
///
void sort ();
+ /// \brief
+ /// merge the given display list
+ void mergeDisplayList(DisplayList& newList);
+
bool operator==(const DisplayList& other) const { return _charsByDepth
== other._charsByDepth; }
bool operator!=(const DisplayList& other) const { return _charsByDepth
!= other._charsByDepth; }
@@ -397,9 +403,16 @@
/// Return an iterator to the first element of the container NOT in the
"removed" depth zone
static iterator beginNonRemoved(container_type& c);
- /// Return an iterator to the first element of the container NOT in the
"removed" depth zone
+ /// Return an constant iterator to the first element of the container
NOT in the "removed" depth zone
static const_iterator beginNonRemoved(const container_type& c);
+ /// Return an iterator succeeding the last element in the static zone
+ static iterator staticZoneEnd(container_type& c);
+
+ /// Return an constant iterator succeeding the last element in the
static zone
+ static const_iterator staticZoneEnd(const container_type& c);
+
+
/// Re-insert a removed-from-stage character after appropriately
/// shifting its depth based on the character::removedDepthOffset
/// value.
Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.401
retrieving revision 1.402
diff -u -b -r1.401 -r1.402
--- server/sprite_instance.cpp 30 Nov 2007 11:26:05 -0000 1.401
+++ server/sprite_instance.cpp 3 Dec 2007 07:06:15 -0000 1.402
@@ -2546,43 +2546,26 @@
// for jump-forwards would do
assert(tgtFrame <= m_current_frame);
- is_jumping_back = true; //remember we are jumping back
-
- // 1. Find all "timeline depth" for the target frame, querying the
- // Timeline object in the sprite/movie definition (see
implementation details)
- // 2. Remove step
- // 2.1 Remove all current dynamic instances found in static depth
zone
- // 2.2 Remove all current timeline instances at a depth NOT in the
set found in step 1
- // 2.3 Remove all non-script-referencable instances, suboptimal!
-
- // NOTE: reset() will call our set_invalidated() before making any
change
- m_display_list.reset(*m_def, tgtFrame, *this);
+ // Just invalidate this character before jumping back.
+ // Should be optimized, but the invalidating model is not clear enough,
+ // and there are some old questions spreading the source files.
+ set_invalidated();
- // 3. Execute all displaylist tags from first to target frame, with
- // target frame tag execution including ACTION tags
+ is_jumping_back = true; //remember we are jumping back
for (size_t f = 0; f<tgtFrame; ++f)
{
- //
- // Set m_current_frame so it is correct (0-based) during
- // execute_frame_tags and thus timeline objects placement
- // (need to correctly set TimelineInfo record).
- //
m_current_frame = f;
execute_frame_tags(f, TAG_DLIST);
}
- // call_frame (setting _callignFrameActions) should never trigger
::advance,
- // at most it shoudl trigger goto_frame which would temporarly set
_callingFrameAction to false
- // ::advance and ::goto_frame are supposedly the only callers to
restoreDisplayList
- //
- assert(!_callingFrameActions);
-
- // Finally, execute target frame tags, both ACTION and DLIST
+ // Execute both action tags and DLIST tags of the target frame
m_current_frame = tgtFrame;
execute_frame_tags(tgtFrame, TAG_DLIST|TAG_ACTION);
is_jumping_back = false; // finished jumping back
+
+ m_display_list.mergeDisplayList(m_tmp_display_list);
}
// 0-based frame number !
@@ -2637,14 +2620,6 @@
getTargetPath().c_str(), target_frame_number, m_current_frame);
#endif
- // TODO: the assertion fails against all.swf with NEW_TIMELINE_DESIGN
- // (swf from http://www.ferryhalim.com/orisinal/)
- //assert(! isUnloaded() );
- if ( isUnloaded() )
- {
- log_error("Sprite %s unloaded on gotoFrame call... let Gnash
developers know please", getTarget().c_str());
- }
-
// goto_frame stops by default.
// ActionGotoFrame tells the movieClip to go to the target frame
// and stop at that frame.
@@ -2723,16 +2698,6 @@
restoreDisplayList(target_frame_number);
assert(m_current_frame == target_frame_number);
_callingFrameActions = callingFrameActionsBackup;
-
- // <UdoG> current design is sub-optimal because it causes unnecessary
- // redraw. Consider a static graphic that stays at it's position all
- // the time. When looping betwen two frames
- // gotoAndPlay(_currentframe-1);
- // then restoreDisplayList() will remove that character and
- // execute_frame_tags() will insert it again. So the next
- // set_invalidated() call (which currently *is* correct) will cause
- // redraw of the whole sprite even if it doesn't change visually
- // at all.
}
else
// Go forward to a later frame
@@ -2749,9 +2714,6 @@
}
assert(m_current_frame == target_frame_number);
-#if defined(GNASH_DEBUG_TIMELINE)
- cout << "At end of DisplayList reconstruction, m_current_frame is " <<
m_current_frame << endl;
-#endif
// Now execute target frame tags (queuing actions)
// NOTE: just in case we're being called by code in a called frame
@@ -2860,31 +2822,16 @@
return NULL;
}
- character* existing_char = m_display_list.get_character_at_depth(depth);
+ DisplayList& dlist = const_cast<DisplayList &>( getDisplayList() );
+ character* existing_char = dlist.get_character_at_depth(depth);
- boost::intrusive_ptr<character> ch;
-
- bool is_ratio_compatible=true;
if(existing_char)
{
- is_ratio_compatible= (ratio == existing_char->get_ratio())
- || (ratio==character::noRatioValue && existing_char->get_ratio()==0)
- || (ratio==0 && existing_char->get_ratio()==character::noRatioValue);
- }
-
- // Place a new character if:
- // (1)target depth is empty
- // (2)target depth is not empty but the character has a different ratio
- // in jump-back-mode.
- if(!existing_char || (is_jumping_back && !is_ratio_compatible))
- {
- // TODO: Optimize this.
- // Create_character_instance() is too expensive for some characters.
- // All I need to do here might be just syntetize a new instance name,
- // the real character is not needed.
- // To decide whether a new instance name is needed for static
characters,
- // a single character_id should be enough.
- ch = cdef->create_character_instance(this, character_id);
+ return NULL;
+ }
+ else
+ {
+ boost::intrusive_ptr<character> ch =
cdef->create_character_instance(this, character_id);
ch->setTimelineInfo(depth, m_current_frame, false);
if(name)
@@ -2904,7 +2851,7 @@
ch->add_event_handler(ev->event(), ev->action());
}
- m_display_list.place_character(
+ dlist.place_character(
ch.get(),
depth,
color_transform,
@@ -2914,20 +2861,6 @@
return ch.get();
}
-
- // move the existing charater if has same ratio in jump-back-mode
- if(existing_char && is_jumping_back && is_ratio_compatible)
- {
- // remove the created character from the key listener list,
- // it might be there(eg. button_character).
- // TODO: optimize this. This is not necessary if we don't create
- // instances blindly above.
- if ( ch ) _vm.getRoot().remove_key_listener(ch.get());
-
- move_display_object(depth, &color_transform, &mat, ratio, clip_depth);
- }
-
- return NULL;
}
void
@@ -2951,7 +2884,9 @@
}
assert(cdef);
- character* existing_char = m_display_list.get_character_at_depth(depth);
+ DisplayList& dlist = const_cast<DisplayList &>( getDisplayList() );
+ character* existing_char = dlist.get_character_at_depth(depth);
+
if (existing_char)
{
// if the existing character is not a shape, move it instead of replace
@@ -2967,10 +2902,13 @@
ch->setTimelineInfo(depth, m_current_frame, true);
replace_display_object(
- ch.get(), name, depth,
+ ch.get(),
+ name,
+ depth,
color_transform,
mat,
- ratio, clip_depth);
+ ratio,
+ clip_depth);
}
}
else // non-existing character
@@ -2997,7 +2935,9 @@
ch->set_name(name);
}
- m_display_list.replace_character(
+ DisplayList& dlist = const_cast<DisplayList &>( getDisplayList() );
+
+ dlist.replace_character(
ch,
depth,
color_transform,
@@ -3952,6 +3892,8 @@
void
sprite_instance::destroy()
{
+ m_display_list.destroy();
+
/// We don't need these anymore
clearProperties();
Index: server/sprite_instance.h
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.h,v
retrieving revision 1.151
retrieving revision 1.152
diff -u -b -r1.151 -r1.152
--- server/sprite_instance.h 23 Nov 2007 12:21:26 -0000 1.151
+++ server/sprite_instance.h 3 Dec 2007 07:06:15 -0000 1.152
@@ -454,7 +454,8 @@
int ratio,
int clip_depth)
{
- m_display_list.move_display_object(depth, color_xform, mat, ratio,
clip_depth);
+ DisplayList& dlist = const_cast<DisplayList &>(
getDisplayList() );
+ dlist.move_display_object(depth, color_xform, mat, ratio,
clip_depth);
}
@@ -505,7 +506,8 @@
void remove_display_object(int depth, int /* id */)
{
set_invalidated();
- m_display_list.remove_display_object(depth);
+ DisplayList& dlist = const_cast<DisplayList &>(
getDisplayList() );
+ dlist.remove_display_object(depth);
}
@@ -674,7 +676,11 @@
const DisplayList& getDisplayList() const {
+ if(! is_jumping_back) {
return m_display_list;
+ } else {
+ return m_tmp_display_list;
+ }
}
/// Return the next highest available depth
@@ -929,6 +935,9 @@
/// Current Display List contents.
DisplayList m_display_list;
+ /// temporary display list used for timeline construction during jump
back
+ DisplayList m_tmp_display_list;
+
/// The canvas for dynamic drawing
//
/// WARNING: since DynamicShape is a character_def, which is
Index: testsuite/misc-ming.all/loop_test-Runner.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/loop_test-Runner.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- testsuite/misc-ming.all/loop_test-Runner.cpp 1 Dec 2007 00:15:02
-0000 1.11
+++ testsuite/misc-ming.all/loop_test-Runner.cpp 3 Dec 2007 07:06:15
-0000 1.12
@@ -125,7 +125,7 @@
// visually, it seems so, but loop-back is too complex
// to be sure (ie: xtrace window text might be reset or
something)
// I checked that it's not resetDisplayList
invalidating it...
- check( tester.getInvalidatedRanges().isNull() );
+ xcheck( tester.getInvalidatedRanges().isNull() );
}
else // we did nothing here...
{
Index: testsuite/misc-ming.all/loop_test10.c
===================================================================
RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/loop_test10.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- testsuite/misc-ming.all/loop_test10.c 23 Nov 2007 02:39:07 -0000
1.2
+++ testsuite/misc-ming.all/loop_test10.c 3 Dec 2007 07:06:15 -0000
1.3
@@ -174,12 +174,11 @@
check_equals(mo, "mc1Initialized", "2");
check_equals(mo, "mc2Initialized", "2");
- xcheck_equals(mo, "mc3Initialized", "1");
+ check_equals(mo, "mc3Initialized", "1");
check_equals(mo, "mc1Unloaded", "2");
check_equals(mo, "mc2Unloaded", "2");
- xcheck_equals(mo, "mc3Unloaded", "0");
+ check_equals(mo, "mc3Unloaded", "0");
- // Don't bother to fix this order untill timeline control is fixed.
xcheck_equals(mo, "asOrder", "'0+1+2+3+4+5+1+2+3+5+'");
add_actions(mo, "totals(); stop();");
SWFMovie_nextFrame(mo); // frame 7
- [Gnash-commit] gnash ChangeLog server/dlist.cpp server/dlist.h...,
Zou Lunkai <=