00001 /* 00002 $Id: surface_manager.cpp,v 1.1 2001/03/06 15:09:22 mbn Exp $ 00003 00004 ------------------------------------------------------------------------ 00005 ClanLib, the platform independent game SDK. 00006 00007 This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE 00008 version 2. See COPYING for details. 00009 00010 For a total list of contributers see CREDITS. 00011 00012 ------------------------------------------------------------------------ 00013 00014 File purpose: 00015 Surface manager 00016 00017 */ 00018 00019 #include "Core/precomp.h" 00020 /* 00021 #include "API/Core/SurfaceProviders/surface_manager.h" 00022 00023 CL_SurfaceManager_Card::CL_SurfaceManager_Card(CL_DisplayCard *_card) 00024 { 00025 card = _card == NULL ? CL_Display::get_current_card() : _card; 00026 } 00027 00028 int CL_SurfaceManager_Card::compare_surfaces(const void *s1, const void *s2) 00029 { 00030 int p1 = (*((CL_SurfaceManager_Priority **) s1))->get_priority(); 00031 int p2 = (*((CL_SurfaceManager_Priority **) s2))->get_priority(); 00032 00033 if (p1 < p2) return 1; 00034 else if (p1 > p2) return -1; 00035 else return 0; 00036 } 00037 00038 void CL_SurfaceManager_Card::add_surface(CL_SurfaceManager_Priority *surf_prio) 00039 { 00040 priority_list.push_back(surf_prio); 00041 } 00042 00043 void CL_SurfaceManager_Card::remove_surface(CL_SurfaceManager_Priority *surf_prio) 00044 { 00045 priority_list.remove(surf_prio); 00046 } 00047 00048 void CL_SurfaceManager_Card::optimize_video() 00049 { 00050 CL_SurfaceManager_Priority **surfaces = new CL_SurfaceManager_Priority *[priority_list.size()]; 00051 int pos = 0; 00052 00053 { 00054 for ( 00055 std::list<CL_SurfaceManager_Priority*>::iterator it = priority_list.begin(); 00056 it != priority_list.end(); 00057 it++) 00058 { 00059 surfaces[pos++] = *it; 00060 } 00061 } 00062 00063 qsort(surfaces, pos, sizeof(CL_SurfaceManager_Priority*), compare_surfaces); 00064 00065 for ( 00066 std::list<CL_SurfaceManager_Priority*>::iterator it = priority_list.begin(); 00067 it != priority_list.end(); 00068 it++) 00069 { 00070 (*it)->reset_priority(); 00071 } 00072 00073 int i; 00074 for (i=0;i<pos;i++) 00075 { 00076 CL_Surface *surf = surfaces[i]->get_surface(); 00077 if (!surf->is_loaded()) 00078 { 00079 surf->get_provider()->lock(); 00080 if (!surf->convert_video() && !surf->convert_system()) 00081 { 00082 cout << "Dammit - we're in a lot of trouble (surface could not be loaded into memory (video or system))" << endl; 00083 } 00084 surf->get_provider()->unlock(); 00085 } 00086 else surf->convert_video(); 00087 } 00088 00089 bool still_video = true; 00090 int memory_limit_pos = 0; 00091 int memory_needed = 0; 00092 for (i=0; i<pos; i++) 00093 { 00094 CL_Surface *cur_surface = surfaces[i]->get_surface(); 00095 00096 bool video = cur_surface->is_video(); 00097 if (!video && still_video) 00098 { 00099 // no need for speculations if memory is plentiful 00100 if (cur_surface->convert_video()) continue; 00101 00102 memory_needed = cur_surface->get_provider()->get_width()* 00103 cur_surface->get_provider()->get_height()* 00104 cur_surface->get_provider()->get_no_sprs(); 00105 00106 int memory_attainable = 0; 00107 for (int o=i+1;o<pos;o++) 00108 { 00109 CL_Surface *check_surf = surfaces[o]->get_surface(); 00110 if (check_surf->is_video()) 00111 { 00112 CL_SurfaceProvider *prov = check_surf->get_provider(); 00113 memory_attainable += prov->get_width()* 00114 prov->get_height()* 00115 prov->get_no_sprs(); 00116 } 00117 } 00118 if (memory_needed <= memory_attainable) 00119 { 00120 still_video = false; 00121 memory_limit_pos = i; 00122 } 00123 } 00124 else if (video && !still_video) 00125 { 00126 cur_surface->convert_system(card); 00127 memory_needed -= cur_surface->get_provider()->get_width()* 00128 cur_surface->get_provider()->get_height()* 00129 cur_surface->get_provider()->get_no_sprs(); 00130 00131 if (memory_needed < 0) 00132 { 00133 if (!surfaces[memory_limit_pos]->get_surface()->convert_video()) 00134 { 00135 // cout << "Mal-aligned memory... retrying" << endl; 00136 continue; 00137 } 00138 00139 while (memory_limit_pos < i) 00140 { 00141 memory_limit_pos++; 00142 CL_SurfaceProvider *prov = surfaces[memory_limit_pos]->get_surface()->get_provider(); 00143 00144 int new_mem_needed = memory_needed + prov->get_width()* 00145 prov->get_height()* 00146 prov->get_no_sprs(); 00147 int memory_attainable = 0; 00148 for (int o=i+1;o<pos;o++) 00149 { 00150 if (surfaces[o]->get_surface()->is_video()) 00151 { 00152 CL_SurfaceProvider *prov = surfaces[o]->get_surface()->get_provider(); 00153 memory_attainable += prov->get_width()* 00154 prov->get_height()* 00155 prov->get_no_sprs(); 00156 } 00157 } 00158 00159 if (new_mem_needed < memory_attainable) 00160 { 00161 memory_needed += prov->get_width()* 00162 prov->get_height()* 00163 prov->get_no_sprs(); 00164 break; 00165 } 00166 } 00167 } 00168 } 00169 } 00170 00171 for (i=0;i<pos;i++) 00172 { 00173 CL_Surface *surf = surfaces[i]->get_surface(); 00174 if (!surf->is_loaded()) 00175 { 00176 surf->get_provider()->lock(); 00177 if (!surf->convert_video() && !surf->convert_system()) 00178 { 00179 cout << "Dammit - we're in a lot of trouble (surface could not be loaded into memory (video or system))" << endl; 00180 } 00181 surf->get_provider()->unlock(); 00182 } 00183 else surf->convert_video(); 00184 } 00185 00186 delete[] surfaces; 00187 } 00188 */
1.2.6 written by Dimitri van Heesch,
© 1997-2001