Author: boucman
Date: Mon Feb 28 21:37:38 2011
New Revision: 48683

URL: http://svn.gna.org/viewcvs/wesnoth?rev=48683&view=rev
Log:
Add parallel analysis of unit invalidation using OpenMP. This is ifdefed out by 
default, mail to wesnoth-dev to follow shortly

Modified:
    trunk/changelog
    trunk/src/display.cpp
    trunk/src/display.hpp
    trunk/src/game_display.cpp
    trunk/src/image.cpp
    trunk/src/unit.cpp
    trunk/src/unit_frame.cpp

Modified: trunk/changelog
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/changelog?rev=48683&r1=48682&r2=48683&view=diff
==============================================================================
--- trunk/changelog (original)
+++ trunk/changelog Mon Feb 28 21:37:38 2011
@@ -64,6 +64,7 @@
    * Fixed a replay OOS issue caused by ToD areas defined outside of events
      (bug #17783).
    * Changed: when loading a file fails to open try with a .gz file.
+   * Unit invalidation is processed in parallel using OpenMP
 
 Version 1.9.4:
  * AI:

Modified: trunk/src/display.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/display.cpp?rev=48683&r1=48682&r2=48683&view=diff
==============================================================================
--- trunk/src/display.cpp (original)
+++ trunk/src/display.cpp Mon Feb 28 21:37:38 2011
@@ -2416,6 +2416,9 @@
 {
        DBG_DP << "invalidate_all()\n";
        invalidateAll_ = true;
+#ifdef _OPENMP
+#pragma omp critical(invalidated_)
+#endif //_OPENMP
        invalidated_.clear();
        update_rect(map_area());
 }
@@ -2425,7 +2428,12 @@
        if(invalidateAll_)
                return false;
 
-       return invalidated_.insert(loc).second;
+       bool tmp;
+#ifdef _OPENMP
+#pragma omp critical(invalidated_)
+#endif //_OPENMP
+       tmp = invalidated_.insert(loc).second;
+       return tmp;
 }
 
 bool display::invalidate(const std::set<map_location>& locs)
@@ -2434,6 +2442,9 @@
                return false;
        bool ret = false;
        foreach (const map_location& loc, locs) {
+#ifdef _OPENMP
+#pragma omp critical(invalidated_)
+#endif //_OPENMP
                ret = invalidated_.insert(loc).second || ret;
        }
        return ret;
@@ -2447,19 +2458,26 @@
        if(locs.size()<=1)
                return false; // propagation never needed
 
-       // search the first hex invalidated (if any)
-       std::set<map_location>::const_iterator i = locs.begin();
-       for(; i != locs.end() && invalidated_.count(*i) == 0 ; ++i) {}
-
-       if (i == locs.end())
-               return false; // no invalidation, don't propagate
-
-       // propagate invalidation
-       // 'i' is already in, but I suspect that splitting the range is bad
-       // especially because locs are often adjacents
-       size_t previous_size = invalidated_.size();
-       invalidated_.insert(locs.begin(), locs.end());
-       return previous_size < invalidated_.size();
+       bool result = false;
+#ifdef _OPENMP
+#pragma omp critical(invalidated_)
+#endif //_OPENMP
+       {
+               // search the first hex invalidated (if any)
+               std::set<map_location>::const_iterator i = locs.begin();
+               for(; i != locs.end() && invalidated_.count(*i) == 0 ; ++i) {}
+
+               if (i != locs.end()) {
+
+                       // propagate invalidation
+                       // 'i' is already in, but I suspect that splitting the 
range is bad
+                       // especially because locs are often adjacents
+                       size_t previous_size = invalidated_.size();
+                       invalidated_.insert(locs.begin(), locs.end());
+                       result = previous_size < invalidated_.size();
+               }
+       }
+       return result;
 }
 
 bool display::invalidate_visible_locations_in_rect(const SDL_Rect& rect)

Modified: trunk/src/display.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/display.hpp?rev=48683&r1=48682&r2=48683&view=diff
==============================================================================
--- trunk/src/display.hpp (original)
+++ trunk/src/display.hpp Mon Feb 28 21:37:38 2011
@@ -296,14 +296,6 @@
         * defaults to no action, overridden by derived classes
         */
        virtual void invalidate_animations_location(const map_location& 
/*loc*/) {}
-
-       /**
-        * What hex are currently invalidated (read only)
-        * used for some fine grained invalidation algorithm which need 
recurstion
-        */
-       const std::set<map_location> & get_invalidated() const { return 
invalidated_; }
-
-
 
        const gamemap& get_map() const { return *map_; }
 

Modified: trunk/src/game_display.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_display.cpp?rev=48683&r1=48682&r2=48683&view=diff
==============================================================================
--- trunk/src/game_display.cpp (original)
+++ trunk/src/game_display.cpp Mon Feb 28 21:37:38 2011
@@ -905,16 +905,23 @@
        foreach(unit* temp_unit, temp_units_) {
                temp_unit->refresh();
        }
-       bool new_inval = true;
-       while(new_inval) {
+       std::vector<unit*> unit_list;
+       foreach (unit &u, units_) {
+               unit_list.push_back(&u);
+       }
+       foreach (unit *u, temp_units_) {
+               unit_list.push_back(u);
+       }
+       bool new_inval;
+       do {
                new_inval = false;
-               foreach (unit& u, units_) {
-                       new_inval |= u.invalidate(u.get_location());
-               }
-               foreach(unit* temp_unit, temp_units_) {
-                       new_inval |= 
temp_unit->invalidate(temp_unit->get_location());
-               }
-       }
+#ifdef _OPENMP
+#pragma omp parallel for reduction(|:new_inval) shared(unit_list) 
schedule(guided)
+#endif //_OPENMP
+               for(unsigned int i=0; i < unit_list.size(); i++) {
+                       new_inval |=  
unit_list[i]->invalidate(unit_list[i]->get_location());
+               }
+       }while(new_inval);
 }
 
 int& game_display::debug_highlight(const map_location& loc)

Modified: trunk/src/image.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/image.cpp?rev=48683&r1=48682&r2=48683&view=diff
==============================================================================
--- trunk/src/image.cpp (original)
+++ trunk/src/image.cpp Mon Feb 28 21:37:38 2011
@@ -146,19 +146,24 @@
 
 void flush_cache()
 {
-       images_.flush();
-       hexed_images_.flush();
-       tod_colored_images_.flush();
-       scaled_to_zoom_.flush();
-       scaled_to_hex_images_.flush();
-       brightened_images_.flush();
-       semi_brightened_images_.flush();
-       in_hex_info_.flush();
-       mini_terrain_cache.clear();
-       mini_fogged_terrain_cache.clear();
-       reversed_images_.clear();
-       image_existence_map.clear();
-       precached_dirs.clear();
+#ifdef _OPENMP
+#pragma omp critical(image_cache)
+#endif //_OPENMP
+       {
+               images_.flush();
+               hexed_images_.flush();
+               tod_colored_images_.flush();
+               scaled_to_zoom_.flush();
+               scaled_to_hex_images_.flush();
+               brightened_images_.flush();
+               semi_brightened_images_.flush();
+               in_hex_info_.flush();
+               mini_terrain_cache.clear();
+               mini_fogged_terrain_cache.clear();
+               reversed_images_.clear();
+               image_existence_map.clear();
+               precached_dirs.clear();
+       }
        /* We can't reset last_index_, since some locators are still alive
           when using :refresh. That would cause them to point to the wrong
           images. Not resetting the variable causes a memory leak, though. */
@@ -1080,8 +1085,20 @@
        }
 
        // return the image if already cached
-       if(i_locator.in_cache(*imap))
-               return i_locator.locate_in_cache(*imap);
+       bool tmp;
+#ifdef _OPENMP
+#pragma omp critical(image_cache)
+#endif //_OPENMP
+       tmp=i_locator.in_cache(*imap);
+
+       if(tmp) {
+               surface result;
+#ifdef _OPENMP
+#pragma omp critical(image_cache)
+#endif //_OPENMP
+               result = i_locator.locate_in_cache(*imap);
+               return result;
+       }
 
        // not cached, generate it
        switch(type) {
@@ -1115,6 +1132,9 @@
        if(res)
                res = create_optimized_surface(res);
 
+#ifdef _OPENMP
+#pragma omp critical(image_cache)
+#endif //_OPENMP
        i_locator.add_to_cache(*imap, res);
 
        return res;
@@ -1128,8 +1148,13 @@
 
 bool is_in_hex(const locator& i_locator)
 {
+       bool result;
+#ifdef _OPENMP
+#pragma omp critical(in_hex_info_)
+#endif //_OPENMP
+       {
        if(i_locator.in_cache(in_hex_info_)) {
-               return i_locator.locate_in_cache(in_hex_info_);
+               result= i_locator.locate_in_cache(in_hex_info_);
        } else {
                const surface image(get_image(i_locator, UNSCALED));
 
@@ -1140,8 +1165,10 @@
                //std::cout << "in_hex : " << i_locator.get_filename()
                //              << " " << (res ? "yes" : "no") << "\n";
 
-               return res;
-       }
+               result= res;
+       }
+       }
+       return result;
 }
 
 

Modified: trunk/src/unit.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/unit.cpp?rev=48683&r1=48682&r2=48683&view=diff
==============================================================================
--- trunk/src/unit.cpp (original)
+++ trunk/src/unit.cpp Mon Feb 28 21:37:38 2011
@@ -1996,7 +1996,7 @@
        // Very early calls, anim not initialized yet
        if(get_animation()) {
                frame_parameters params;
-               game_display * disp =  game_display::get_singleton();
+               const game_display * disp =  game_display::get_singleton();
                const gamemap & map = disp->get_map();
                const t_translation::t_terrain terrain = map.get_terrain(loc);
                const terrain_type& terrain_info = 
map.get_terrain_info(terrain);

Modified: trunk/src/unit_frame.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/unit_frame.cpp?rev=48683&r1=48682&r2=48683&view=diff
==============================================================================
--- trunk/src/unit_frame.cpp (original)
+++ trunk/src/unit_frame.cpp Mon Feb 28 21:37:38 2011
@@ -663,13 +663,24 @@
                        
result.insert(src.get_direction(map_location::SOUTH_WEST));
                }
        } else {
-               surface image;
-               if(!image_loc.is_void() && image_loc.get_filename() != "") { // 
invalid diag image, or not diagonal
-                       image=image::get_image(image_loc,
-                                       image::SCALED_TO_ZOOM
-                                       );
-               }
-               if (image != NULL) {
+               int w=0;
+               int h =0;
+#ifdef _OPENMP
+#pragma omp critical(frame_surface) // with the way surfaces work it's hard to 
lock the refcount within sdl_utils
+#endif //_OPENMP
+               {
+                       surface image;
+                       if(!image_loc.is_void() && image_loc.get_filename() != 
"") { // invalid diag image, or not diagonal
+                               image=image::get_image(image_loc,
+                                               image::SCALED_TO_ZOOM
+                                               );
+                       }
+                       if(image != NULL) {
+                               w = image->w;
+                               h = image->h;
+                       }
+               }
+               if (w != 0 || h != 0) {
                        const int x = static_cast<int>(tmp_offset * xdst + 
(1.0-tmp_offset) * xsrc);
                        const int y = static_cast<int>(tmp_offset * ydst + 
(1.0-tmp_offset) * ysrc);
 #ifdef LOW_MEM
@@ -680,8 +691,8 @@
                        bool facing_north = direction == 
map_location::NORTH_WEST || direction == map_location::NORTH || direction == 
map_location::NORTH_EAST;
                        if(!current_data.auto_vflip) facing_north = true;
                        if(!current_data.auto_hflip) facing_west = false;
-                       int my_x = x +current_data.x+d2- image->w/2;
-                       int my_y = y +current_data.y+d2- image->h/2;
+                       int my_x = x +current_data.x+d2- w/2;
+                       int my_y = y +current_data.y+d2- h/2;
                        if(facing_west) {
                                my_x += current_data.directional_x;
                        } else {
@@ -693,7 +704,7 @@
                                my_y -= current_data.directional_y;
                        }
 
-                       const SDL_Rect r = create_rect(my_x, my_y, image->w, 
image->h);
+                       const SDL_Rect r = create_rect(my_x, my_y, w, h);
                        // check if our underlying hexes are invalidated
                        // if we need to update ourselve because we changed, 
invalidate our hexes
                        // and return whether or not our hexs was invalidated


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to