Merge with MPC-HC 6d1472b2f18266d92e5bc068667de348c0cd3b3b.
[xy_vsfilter.git] / src / subtitles / cache_manager.cpp
blob91587e5c2e6c657da47ba59eb852224fc1ff151a
1 /************************************************************************/
2 /* author: xy */
3 /* date: 20110926 */
4 /************************************************************************/
5 #include "StdAfx.h"
6 #include "cache_manager.h"
7 #include "draw_item.h"
8 #include "xy_overlay_paint_machine.h"
9 #include "xy_clipper_paint_machine.h"
11 enum { TextInfoCacheKey_EQUAL, ScanLineData2CacheKey_EQUAL,
12 OverlayNoBlurKey_EQUAL, OverlayKey_EQUAL,
13 ScanLineDataCacheKey_EQUAL, OverlayNoOffsetKey_EQUAL,
14 ClipperAlphaMaskCacheKey_EQUAL, DrawItemHashKey_EQUAL, GroupedDrawItemsHashKey_EQUAL,
15 EQUALITY_TEST_FUNC_NUM
18 #ifdef DEBUG
20 int g_func_calls_num[EQUALITY_TEST_FUNC_NUM] = {0};
22 inline void AddFuncCalls(int func)
24 g_func_calls_num[func]++;
26 #else
27 inline void AddFuncCalls(int func)
29 func;
31 #endif
33 ULONG PathDataTraits::Hash( const PathData& key )
35 ULONG hash = 515;
36 hash += (hash<<5);
37 hash += key.mPathPoints;
38 for (int i=0;i<key.mPathPoints;i++)
40 hash += (hash<<5);
41 hash += key.mpPathTypes[i];
43 for (int i=0;i<key.mPathPoints;i++)
45 hash += (hash<<5);
46 hash += key.mpPathPoints[i].x;
47 hash += (hash<<5);
48 hash += key.mpPathPoints[i].y;
50 return hash;
53 ULONG ClipperTraits::Hash( const CClipper& key )
55 ULONG hash = key.m_polygon->m_str.GetId();
56 hash += (hash<<5);
57 hash += key.m_inverse;
58 hash += (hash<<5);
59 hash += key.m_effectType;
60 hash += (hash<<5);
61 hash += key.m_size.cx;
62 hash += (hash<<5);
63 hash += key.m_size.cy;
64 hash += (hash<<5);
65 hash += hash_value(key.m_polygon->m_scalex);
66 hash += (hash<<5);
67 hash += hash_value(key.m_polygon->m_scaley);
69 for (int i=0;i<sizeof(key.m_effect.param)/sizeof(key.m_effect.param[0]);i++)
71 hash += (hash<<5);
72 hash += key.m_effect.param[i];
74 for (int i=0;i<sizeof(key.m_effect.t)/sizeof(key.m_effect.t[0]);i++)
76 hash += (hash<<5);
77 hash += key.m_effect.t[i];
79 return hash;
82 //////////////////////////////////////////////////////////////////////////////////////////////
84 // TextInfoCacheKey
86 bool TextInfoCacheKey::operator==( const TextInfoCacheKey& key ) const
88 AddFuncCalls(TextInfoCacheKey_EQUAL);
89 return m_str_id == key.m_str_id
90 && ( m_style==key.m_style ||
91 (static_cast<const STSStyleBase&>(m_style).operator==(key.m_style)
92 && m_style.get().fontScaleX == key.m_style.get().fontScaleX
93 && m_style.get().fontScaleY == key.m_style.get().fontScaleY
94 && m_style.get().fontSpacing == key.m_style.get().fontSpacing) );
97 ULONG TextInfoCacheKey::UpdateHashValue()
99 m_hash_value = m_str_id;
100 m_hash_value += (m_hash_value<<5);
101 m_hash_value += hash_value( static_cast<const STSStyleBase&>(m_style.get()) );
102 m_hash_value += (m_hash_value<<5);
103 m_hash_value += hash_value( m_style.get().fontScaleX );
104 m_hash_value += (m_hash_value<<5);
105 m_hash_value += hash_value( m_style.get().fontScaleY );
106 m_hash_value += (m_hash_value<<5);
107 m_hash_value += hash_value( m_style.get().fontSpacing );
108 return m_hash_value;
111 //////////////////////////////////////////////////////////////////////////////////////////////
113 // PathDataCacheKey
115 bool PathDataCacheKey::CompareSTSStyle( const STSStyle& lhs, const STSStyle& rhs )
117 return lhs.charSet==rhs.charSet &&
118 lhs.fontName==rhs.fontName &&
119 lhs.fontSize==rhs.fontSize &&
120 lhs.fontSpacing==rhs.fontSpacing &&
121 lhs.fontWeight==rhs.fontWeight &&
122 lhs.fItalic==rhs.fItalic &&
123 lhs.fUnderline==rhs.fUnderline &&
124 lhs.fStrikeOut==rhs.fStrikeOut;
127 ULONG PathDataCacheKey::UpdateHashValue()
129 const STSStyle& style = m_style.get();
130 m_hash_value = m_str_id;
131 m_hash_value += (m_hash_value<<5);
132 m_hash_value += hash_value(m_scalex);
133 m_hash_value += (m_hash_value<<5);
134 m_hash_value += hash_value(m_scaley);
135 m_hash_value += (m_hash_value<<5);
136 m_hash_value += style.charSet;
137 m_hash_value += (m_hash_value<<5);
138 m_hash_value += CStringElementTraits<CString>::Hash(style.fontName);
139 m_hash_value += (m_hash_value<<5);
140 m_hash_value += style.fontSize;
141 m_hash_value += (m_hash_value<<5);
142 m_hash_value += style.fontSpacing;
143 m_hash_value += (m_hash_value<<5);
144 m_hash_value += style.fontWeight;
145 m_hash_value += (m_hash_value<<5);
146 m_hash_value += style.fItalic;
147 m_hash_value += (m_hash_value<<5);
148 m_hash_value += style.fUnderline;
149 m_hash_value += (m_hash_value<<5);
150 m_hash_value += style.fStrikeOut;
151 return m_hash_value;
155 //////////////////////////////////////////////////////////////////////////////////////////////
157 // ScanLineData2CacheKey
159 bool ScanLineData2CacheKey::operator==( const ScanLineData2CacheKey& key ) const
161 AddFuncCalls(ScanLineData2CacheKey_EQUAL);
162 return
163 this->m_style.get().borderStyle == key.m_style.get().borderStyle
164 && fabs(this->m_style.get().outlineWidthX - key.m_style.get().outlineWidthX) < 0.000001
165 && fabs(this->m_style.get().outlineWidthY - key.m_style.get().outlineWidthY) < 0.000001
166 && fabs(this->m_style.get().fontScaleX - key.m_style.get().fontScaleX) < 0.000001
167 && fabs(this->m_style.get().fontScaleY - key.m_style.get().fontScaleY) < 0.000001
168 && fabs(this->m_style.get().fontAngleX - key.m_style.get().fontAngleX) < 0.000001
169 && fabs(this->m_style.get().fontAngleY - key.m_style.get().fontAngleY) < 0.000001
170 && fabs(this->m_style.get().fontAngleZ - key.m_style.get().fontAngleZ) < 0.000001
171 && fabs(this->m_style.get().fontShiftX - key.m_style.get().fontShiftX) < 0.000001
172 && fabs(this->m_style.get().fontShiftY - key.m_style.get().fontShiftY) < 0.000001
173 && (m_org.x==key.m_org.x) && (m_org.y==key.m_org.y)
174 && PathDataCacheKey::operator==(key); //NOTE: static_cast will call copy constructer to construct a tmp obj
177 ULONG ScanLineData2CacheKey::UpdateHashValue()
179 const STSStyle& style = m_style.get();
180 m_hash_value = __super::UpdateHashValue();
181 m_hash_value += (m_hash_value<<5);
182 m_hash_value += m_org.x;
183 m_hash_value += (m_hash_value<<5);
184 m_hash_value += m_org.y;
185 m_hash_value += (m_hash_value<<5);
186 m_hash_value += style.borderStyle;
187 m_hash_value += (m_hash_value<<5);
188 m_hash_value += ((int)style.outlineWidthX<<16) + (int)style.outlineWidthY;
189 m_hash_value += (m_hash_value<<5);
190 m_hash_value += ((int)style.fontScaleX<<16) + (int)style.fontScaleY;
191 m_hash_value += (m_hash_value<<5);
192 m_hash_value += ((int)style.fontAngleX<<20) + ((int)style.fontAngleY<<10) + ((int)style.fontAngleZ);
193 m_hash_value += (m_hash_value<<5);
194 m_hash_value += ((int)style.fontShiftX<<16) + (int)style.fontShiftY;
196 return m_hash_value;
199 //////////////////////////////////////////////////////////////////////////////////////////////
201 // OverlayNoBlurKey
203 bool OverlayNoBlurKey::operator==( const OverlayNoBlurKey& key ) const
205 AddFuncCalls(OverlayNoBlurKey_EQUAL);
206 //static_cast will call copy constructer to construct a tmp obj
207 //return (static_cast<ScanLineDataCacheKey>(*this)==static_cast<ScanLineDataCacheKey>(key))
208 // && (m_p.x==key.m_p.x) && (m_p.y==key.m_p.y);
209 return (m_p.x==key.m_p.x) && (m_p.y==key.m_p.y) && ScanLineData2CacheKey::operator==(key);
212 ULONG OverlayNoBlurKey::UpdateHashValue()
214 m_hash_value = __super::UpdateHashValue();
215 m_hash_value += (m_hash_value<<5);
216 m_hash_value += m_p.x;
217 m_hash_value += (m_hash_value<<5);
218 m_hash_value += m_p.y;
219 return m_hash_value;
223 //////////////////////////////////////////////////////////////////////////////////////////////
225 // OverlayKey
227 bool OverlayKey::operator==( const OverlayKey& key ) const
229 AddFuncCalls(OverlayKey_EQUAL);
230 return fabs(this->m_style.get().fGaussianBlur - key.m_style.get().fGaussianBlur) < 0.000001
231 && fabs(this->m_style.get().fBlur - key.m_style.get().fBlur) < 0.000001
232 && OverlayNoBlurKey::operator==(key);
233 //static_cast will call copy constructer to construct a tmp obj
234 //return ((CWordCacheKey)(*this)==(CWordCacheKey)key) && (m_p.x==key.m_p.x) && (m_p.y==key.m_p.y)
235 // && (m_org.x==key.m_org.x) && (m_org.y==key.m_org.y);
238 ULONG OverlayKey::UpdateHashValue()
240 m_hash_value = __super::UpdateHashValue();
241 m_hash_value += (m_hash_value<<5);
242 m_hash_value += *(UINT*)(&m_style.get().fBlur);
243 m_hash_value += (m_hash_value<<5);
244 m_hash_value += hash_value(m_style.get().fGaussianBlur);
245 return m_hash_value;
249 //////////////////////////////////////////////////////////////////////////////////////////////
251 // ScanLineDataCacheKey
253 bool ScanLineDataCacheKey::operator==( const ScanLineDataCacheKey& key ) const
255 AddFuncCalls(ScanLineDataCacheKey_EQUAL);
256 return (m_path_data && key.m_path_data) ? *m_path_data==*key.m_path_data : m_path_data==key.m_path_data;
259 ULONG ScanLineDataCacheKey::UpdateHashValue()
261 m_hash_value = PathDataTraits::Hash(*m_path_data);
262 return m_hash_value;
265 //////////////////////////////////////////////////////////////////////////////////////////////
267 // OverlayNoOffsetKey
269 bool OverlayNoOffsetKey::operator==( const OverlayNoOffsetKey& key ) const
271 AddFuncCalls(OverlayNoOffsetKey_EQUAL);
272 return (this==&key) || ( this->m_border == key.m_border && this->m_rasterize_sub == key.m_rasterize_sub &&
273 ScanLineDataCacheKey::operator==(key) );
276 ULONG OverlayNoOffsetKey::UpdateHashValue()
278 m_hash_value = __super::UpdateHashValue();
279 m_hash_value += (m_hash_value<<5);
280 m_hash_value += m_border;
281 m_hash_value += (m_hash_value<<5);
282 m_hash_value += m_rasterize_sub;
283 return m_hash_value;
287 //////////////////////////////////////////////////////////////////////////////////////////////
289 // ClipperAlphaMaskCacheKey
291 bool ClipperAlphaMaskCacheKey::operator==( const ClipperAlphaMaskCacheKey& key ) const
293 AddFuncCalls(ClipperAlphaMaskCacheKey_EQUAL);
294 bool result = false;
295 if (m_clipper==key.m_clipper)
297 result = true;
299 else if ( m_clipper!=NULL && key.m_clipper!=NULL )
301 const CClipper& lhs = *m_clipper;
302 const CClipper& rhs = *key.m_clipper;
303 result = (lhs.m_polygon->m_str.GetId() == rhs.m_polygon->m_str.GetId()
304 && fabs(lhs.m_polygon->m_scalex - rhs.m_polygon->m_scalex) < 0.000001
305 && fabs(lhs.m_polygon->m_scaley - rhs.m_polygon->m_scaley) < 0.000001
306 && lhs.m_size == rhs.m_size
307 && lhs.m_inverse == rhs.m_inverse
308 && lhs.m_effectType == rhs.m_effectType
309 && lhs.m_effect == rhs.m_effect);//fix me: unsafe code
311 return result;
314 ULONG ClipperAlphaMaskCacheKey::UpdateHashValue()
316 if(m_clipper)
317 m_hash_value = ClipperTraits::Hash(*m_clipper);
318 else
319 m_hash_value = 0;
320 return m_hash_value;
323 //////////////////////////////////////////////////////////////////////////////////////////////
325 // DrawItemHashKey
327 ULONG DrawItemHashKey::UpdateHashValue()
329 m_hash_value = m_overlay_key->GetHashValue();
330 m_hash_value += (m_hash_value<<5);
331 m_hash_value += m_clipper_key.GetHashValue();
332 m_hash_value += (m_hash_value<<5);
333 m_hash_value += hash_value(m_clip_rect);
334 m_hash_value += (m_hash_value<<5);
335 m_hash_value += m_fBorder;
336 m_hash_value += (m_hash_value<<5);
337 m_hash_value += m_fBody;
338 m_hash_value += (m_hash_value<<5);
339 m_hash_value += (m_xsub<<16) + m_ysub;
340 m_hash_value += (m_hash_value<<5);
341 m_hash_value += m_switchpts[0];//fix me: other m_switchpts elements?
342 return m_hash_value;
345 DrawItemHashKey::DrawItemHashKey( const DrawItem& draw_item)
346 : m_overlay_key( draw_item.overlay_paint_machine->GetHashKey() )
347 , m_clipper_key( draw_item.clipper->GetHashKey() )
348 , m_clip_rect(draw_item.clip_rect)
349 , m_xsub(draw_item.xsub)
350 , m_ysub(draw_item.ysub)
351 , m_fBody(draw_item.fBody)
352 , m_fBorder(draw_item.fBorder)
354 for(int i=0;i<countof(m_switchpts);i++)
355 m_switchpts[i] = draw_item.switchpts[i];
358 bool DrawItemHashKey::operator==( const DrawItemHashKey& key ) const
360 AddFuncCalls(DrawItemHashKey_EQUAL);
361 return (this==&key) || (
362 (m_clip_rect == key.m_clip_rect)==TRUE &&
363 m_xsub == key.m_xsub &&
364 m_ysub == key.m_ysub &&
365 m_fBody == key.m_fBody &&
366 m_fBorder == key.m_fBorder &&
367 !memcmp(m_switchpts, key.m_switchpts, sizeof(m_switchpts)) &&
368 *m_overlay_key==*key.m_overlay_key &&
369 m_clipper_key==key.m_clipper_key);
372 //////////////////////////////////////////////////////////////////////////////////////////////
374 // GroupedDrawItemsHashKey
376 ULONG GroupedDrawItemsHashKey::UpdateHashValue()
378 m_hash_value = hash_value(m_clip_rect);
379 ASSERT(m_key);
380 for( unsigned i=0;i<m_key->GetCount();i++)
382 m_hash_value += (m_hash_value<<5);
383 m_hash_value += m_key->GetAt(i)->GetHashValue();
385 return m_hash_value;
388 bool GroupedDrawItemsHashKey::operator==( const GroupedDrawItemsHashKey& key ) const
390 AddFuncCalls(GroupedDrawItemsHashKey_EQUAL);
391 if (this==&key)
393 return true;
395 else if ( m_key->GetCount()!=key.m_key->GetCount() || m_clip_rect!=key.m_clip_rect)
397 return false;
399 else
401 for( unsigned i=0;i<m_key->GetCount();i++)
403 if( !(*m_key->GetAt(i) == *key.m_key->GetAt(i)) )
404 return false;
406 return true;
408 return true;
412 //////////////////////////////////////////////////////////////////////////////////////////////
414 // CacheManager
416 struct Caches
418 public:
419 Caches()
421 s_bitmap_cache = NULL;
422 s_clipper_alpha_mask_cache = NULL;
424 s_text_info_cache = NULL;
425 s_path_data_mru_cache = NULL;
426 s_scan_line_data_2_mru_cache = NULL;
427 s_overlay_no_blur_mru_cache = NULL;
428 s_overlay_mru_cache = NULL;
430 s_scan_line_data_mru_cache = NULL;
431 s_overlay_no_offset_mru_cache = NULL;
433 s_subpixel_variance_cache = NULL;
434 s_ass_tag_list_cache = NULL;
436 ~Caches()
438 delete s_bitmap_cache;
439 delete s_clipper_alpha_mask_cache;
441 delete s_text_info_cache;
442 delete s_path_data_mru_cache;
443 delete s_scan_line_data_2_mru_cache;
444 delete s_overlay_no_blur_mru_cache;
445 delete s_overlay_mru_cache;
447 delete s_scan_line_data_mru_cache;
448 delete s_overlay_no_offset_mru_cache;
450 delete s_subpixel_variance_cache;
451 delete s_ass_tag_list_cache;
453 public:
454 BitmapMruCache* s_bitmap_cache;
455 ClipperAlphaMaskMruCache* s_clipper_alpha_mask_cache;
457 TextInfoMruCache* s_text_info_cache;
458 AssTagListMruCache* s_ass_tag_list_cache;
460 ScanLineDataMruCache* s_scan_line_data_mru_cache;
461 OverlayNoOffsetMruCache* s_overlay_no_offset_mru_cache;
463 OverlayMruCache* s_subpixel_variance_cache;
464 OverlayMruCache* s_overlay_mru_cache;
465 OverlayNoBlurMruCache* s_overlay_no_blur_mru_cache;
466 PathDataMruCache* s_path_data_mru_cache;
467 ScanLineData2MruCache* s_scan_line_data_2_mru_cache;
470 static Caches s_caches;
472 OverlayMruCache* CacheManager::GetOverlayMruCache()
474 if(s_caches.s_overlay_mru_cache==NULL)
476 s_caches.s_overlay_mru_cache = new OverlayMruCache(OVERLAY_CACHE_ITEM_NUM);
478 return s_caches.s_overlay_mru_cache;
481 PathDataMruCache* CacheManager::GetPathDataMruCache()
483 if (s_caches.s_path_data_mru_cache==NULL)
485 s_caches.s_path_data_mru_cache = new PathDataMruCache(PATH_CACHE_ITEM_NUM);
487 return s_caches.s_path_data_mru_cache;
490 OverlayNoBlurMruCache* CacheManager::GetOverlayNoBlurMruCache()
492 if(s_caches.s_overlay_no_blur_mru_cache==NULL)
494 s_caches.s_overlay_no_blur_mru_cache = new OverlayNoBlurMruCache(OVERLAY_NO_BLUR_CACHE_ITEM_NUM);
496 return s_caches.s_overlay_no_blur_mru_cache;
499 ScanLineData2MruCache* CacheManager::GetScanLineData2MruCache()
501 if(s_caches.s_scan_line_data_2_mru_cache==NULL)
503 s_caches.s_scan_line_data_2_mru_cache = new ScanLineData2MruCache(SCAN_LINE_DATA_CACHE_ITEM_NUM);
505 return s_caches.s_scan_line_data_2_mru_cache;
508 OverlayMruCache* CacheManager::GetSubpixelVarianceCache()
510 if(s_caches.s_subpixel_variance_cache==NULL)
512 s_caches.s_subpixel_variance_cache = new OverlayMruCache(SUBPIXEL_VARIANCE_CACHE_ITEM_NUM);
514 return s_caches.s_subpixel_variance_cache;
517 ScanLineDataMruCache* CacheManager::GetScanLineDataMruCache()
519 if(s_caches.s_scan_line_data_mru_cache==NULL)
521 s_caches.s_scan_line_data_mru_cache = new ScanLineDataMruCache(SCAN_LINE_DATA_CACHE_ITEM_NUM);
523 return s_caches.s_scan_line_data_mru_cache;
526 OverlayNoOffsetMruCache* CacheManager::GetOverlayNoOffsetMruCache()
528 if(s_caches.s_overlay_no_offset_mru_cache==NULL)
530 s_caches.s_overlay_no_offset_mru_cache = new OverlayNoOffsetMruCache(OVERLAY_NO_BLUR_CACHE_ITEM_NUM);
532 return s_caches.s_overlay_no_offset_mru_cache;
535 AssTagListMruCache* CacheManager::GetAssTagListMruCache()
537 if(s_caches.s_ass_tag_list_cache==NULL)
539 s_caches.s_ass_tag_list_cache = new AssTagListMruCache(ASS_TAG_LIST_CACHE_ITEM_NUM);
541 return s_caches.s_ass_tag_list_cache;
544 TextInfoMruCache* CacheManager::GetTextInfoCache()
546 if(s_caches.s_text_info_cache==NULL)
548 s_caches.s_text_info_cache = new TextInfoMruCache(TEXT_INFO_CACHE_ITEM_NUM);
550 return s_caches.s_text_info_cache;
553 ClipperAlphaMaskMruCache* CacheManager::GetClipperAlphaMaskMruCache()
555 if(s_caches.s_clipper_alpha_mask_cache==NULL)
557 s_caches.s_clipper_alpha_mask_cache = new ClipperAlphaMaskMruCache(CLIPPER_MRU_CACHE_ITEM_NUM);
559 return s_caches.s_clipper_alpha_mask_cache;
562 BitmapMruCache* CacheManager::GetBitmapMruCache()
564 if (s_caches.s_bitmap_cache==NULL)
566 s_caches.s_bitmap_cache = new BitmapMruCache(BITMAP_MRU_CACHE_ITEM_NUM);
568 return s_caches.s_bitmap_cache;