Minor fix.
[xy_vsfilter.git] / src / subtitles / cache_manager.cpp
blob1e64799a5cec7f1c5c200f4293be249453114116
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 += style.charSet;
133 m_hash_value += (m_hash_value<<5);
134 m_hash_value += CStringElementTraits<CString>::Hash(style.fontName);
135 m_hash_value += (m_hash_value<<5);
136 m_hash_value += style.fontSize;
137 m_hash_value += (m_hash_value<<5);
138 m_hash_value += style.fontSpacing;
139 m_hash_value += (m_hash_value<<5);
140 m_hash_value += style.fontWeight;
141 m_hash_value += (m_hash_value<<5);
142 m_hash_value += style.fItalic;
143 m_hash_value += (m_hash_value<<5);
144 m_hash_value += style.fUnderline;
145 m_hash_value += (m_hash_value<<5);
146 m_hash_value += style.fStrikeOut;
147 return m_hash_value;
151 //////////////////////////////////////////////////////////////////////////////////////////////
153 // ScanLineData2CacheKey
155 bool ScanLineData2CacheKey::operator==( const ScanLineData2CacheKey& key ) const
157 AddFuncCalls(ScanLineData2CacheKey_EQUAL);
158 return
159 this->m_style.get().borderStyle == key.m_style.get().borderStyle
160 && fabs(this->m_style.get().outlineWidthX - key.m_style.get().outlineWidthX) < 0.000001
161 && fabs(this->m_style.get().outlineWidthY - key.m_style.get().outlineWidthY) < 0.000001
162 && fabs(this->m_style.get().fontScaleX - key.m_style.get().fontScaleX) < 0.000001
163 && fabs(this->m_style.get().fontScaleY - key.m_style.get().fontScaleY) < 0.000001
164 && fabs(this->m_style.get().fontAngleX - key.m_style.get().fontAngleX) < 0.000001
165 && fabs(this->m_style.get().fontAngleY - key.m_style.get().fontAngleY) < 0.000001
166 && fabs(this->m_style.get().fontAngleZ - key.m_style.get().fontAngleZ) < 0.000001
167 && fabs(this->m_style.get().fontShiftX - key.m_style.get().fontShiftX) < 0.000001
168 && fabs(this->m_style.get().fontShiftY - key.m_style.get().fontShiftY) < 0.000001
169 && (m_org.x==key.m_org.x) && (m_org.y==key.m_org.y)
170 && PathDataCacheKey::operator==(key); //NOTE: static_cast will call copy constructer to construct a tmp obj
173 ULONG ScanLineData2CacheKey::UpdateHashValue()
175 const STSStyle& style = m_style.get();
176 m_hash_value = __super::UpdateHashValue();
177 m_hash_value += (m_hash_value<<5);
178 m_hash_value += m_org.x;
179 m_hash_value += (m_hash_value<<5);
180 m_hash_value += m_org.y;
181 m_hash_value += (m_hash_value<<5);
182 m_hash_value += style.borderStyle;
183 m_hash_value += (m_hash_value<<5);
184 m_hash_value += ((int)style.outlineWidthX<<16) + (int)style.outlineWidthY;
185 m_hash_value += (m_hash_value<<5);
186 m_hash_value += ((int)style.fontScaleX<<16) + (int)style.fontScaleY;
187 m_hash_value += (m_hash_value<<5);
188 m_hash_value += ((int)style.fontAngleX<<20) + ((int)style.fontAngleY<<10) + ((int)style.fontAngleZ);
189 m_hash_value += (m_hash_value<<5);
190 m_hash_value += ((int)style.fontShiftX<<16) + (int)style.fontShiftY;
192 return m_hash_value;
195 //////////////////////////////////////////////////////////////////////////////////////////////
197 // OverlayNoBlurKey
199 bool OverlayNoBlurKey::operator==( const OverlayNoBlurKey& key ) const
201 AddFuncCalls(OverlayNoBlurKey_EQUAL);
202 //static_cast will call copy constructer to construct a tmp obj
203 //return (static_cast<ScanLineDataCacheKey>(*this)==static_cast<ScanLineDataCacheKey>(key))
204 // && (m_p.x==key.m_p.x) && (m_p.y==key.m_p.y);
205 return (m_p.x==key.m_p.x) && (m_p.y==key.m_p.y) && ScanLineData2CacheKey::operator==(key);
208 ULONG OverlayNoBlurKey::UpdateHashValue()
210 m_hash_value = __super::UpdateHashValue();
211 m_hash_value += (m_hash_value<<5);
212 m_hash_value += m_p.x;
213 m_hash_value += (m_hash_value<<5);
214 m_hash_value += m_p.y;
215 return m_hash_value;
219 //////////////////////////////////////////////////////////////////////////////////////////////
221 // OverlayKey
223 bool OverlayKey::operator==( const OverlayKey& key ) const
225 AddFuncCalls(OverlayKey_EQUAL);
226 return fabs(this->m_style.get().fGaussianBlur - key.m_style.get().fGaussianBlur) < 0.000001
227 && fabs(this->m_style.get().fBlur - key.m_style.get().fBlur) < 0.000001
228 && OverlayNoBlurKey::operator==(key);
229 //static_cast will call copy constructer to construct a tmp obj
230 //return ((CWordCacheKey)(*this)==(CWordCacheKey)key) && (m_p.x==key.m_p.x) && (m_p.y==key.m_p.y)
231 // && (m_org.x==key.m_org.x) && (m_org.y==key.m_org.y);
234 ULONG OverlayKey::UpdateHashValue()
236 m_hash_value = __super::UpdateHashValue();
237 m_hash_value += (m_hash_value<<5);
238 m_hash_value += *(UINT*)(&m_style.get().fBlur);
239 m_hash_value += (m_hash_value<<5);
240 m_hash_value += hash_value(m_style.get().fGaussianBlur);
241 return m_hash_value;
245 //////////////////////////////////////////////////////////////////////////////////////////////
247 // ScanLineDataCacheKey
249 bool ScanLineDataCacheKey::operator==( const ScanLineDataCacheKey& key ) const
251 AddFuncCalls(ScanLineDataCacheKey_EQUAL);
252 return (m_path_data && key.m_path_data) ? *m_path_data==*key.m_path_data : m_path_data==key.m_path_data;
255 ULONG ScanLineDataCacheKey::UpdateHashValue()
257 m_hash_value = PathDataTraits::Hash(*m_path_data);
258 return m_hash_value;
261 //////////////////////////////////////////////////////////////////////////////////////////////
263 // OverlayNoOffsetKey
265 bool OverlayNoOffsetKey::operator==( const OverlayNoOffsetKey& key ) const
267 AddFuncCalls(OverlayNoOffsetKey_EQUAL);
268 return (this==&key) || ( this->m_border == key.m_border && this->m_rasterize_sub == key.m_rasterize_sub &&
269 ScanLineDataCacheKey::operator==(key) );
272 ULONG OverlayNoOffsetKey::UpdateHashValue()
274 m_hash_value = __super::UpdateHashValue();
275 m_hash_value += (m_hash_value<<5);
276 m_hash_value += m_border;
277 m_hash_value += (m_hash_value<<5);
278 m_hash_value += m_rasterize_sub;
279 return m_hash_value;
283 //////////////////////////////////////////////////////////////////////////////////////////////
285 // ClipperAlphaMaskCacheKey
287 bool ClipperAlphaMaskCacheKey::operator==( const ClipperAlphaMaskCacheKey& key ) const
289 AddFuncCalls(ClipperAlphaMaskCacheKey_EQUAL);
290 bool result = false;
291 if (m_clipper==key.m_clipper)
293 result = true;
295 else if ( m_clipper!=NULL && key.m_clipper!=NULL )
297 const CClipper& lhs = *m_clipper;
298 const CClipper& rhs = *key.m_clipper;
299 result = (lhs.m_polygon->m_str.GetId() == rhs.m_polygon->m_str.GetId()
300 && fabs(lhs.m_polygon->m_scalex - rhs.m_polygon->m_scalex) < 0.000001
301 && fabs(lhs.m_polygon->m_scaley - rhs.m_polygon->m_scaley) < 0.000001
302 && lhs.m_size == rhs.m_size
303 && lhs.m_inverse == rhs.m_inverse
304 && lhs.m_effectType == rhs.m_effectType
305 && lhs.m_effect == rhs.m_effect);//fix me: unsafe code
307 return result;
310 ULONG ClipperAlphaMaskCacheKey::UpdateHashValue()
312 if(m_clipper)
313 m_hash_value = ClipperTraits::Hash(*m_clipper);
314 else
315 m_hash_value = 0;
316 return m_hash_value;
319 //////////////////////////////////////////////////////////////////////////////////////////////
321 // DrawItemHashKey
323 ULONG DrawItemHashKey::UpdateHashValue()
325 m_hash_value = m_overlay_key->GetHashValue();
326 m_hash_value += (m_hash_value<<5);
327 m_hash_value += m_clipper_key.GetHashValue();
328 m_hash_value += (m_hash_value<<5);
329 m_hash_value += hash_value(m_clip_rect);
330 m_hash_value += (m_hash_value<<5);
331 m_hash_value += m_fBorder;
332 m_hash_value += (m_hash_value<<5);
333 m_hash_value += m_fBody;
334 m_hash_value += (m_hash_value<<5);
335 m_hash_value += (m_xsub<<16) + m_ysub;
336 m_hash_value += (m_hash_value<<5);
337 m_hash_value += m_switchpts[0];//fix me: other m_switchpts elements?
338 return m_hash_value;
341 DrawItemHashKey::DrawItemHashKey( const DrawItem& draw_item)
342 : m_overlay_key( draw_item.overlay_paint_machine->GetHashKey() )
343 , m_clipper_key( draw_item.clipper->GetHashKey() )
344 , m_clip_rect(draw_item.clip_rect)
345 , m_xsub(draw_item.xsub)
346 , m_ysub(draw_item.ysub)
347 , m_fBody(draw_item.fBody)
348 , m_fBorder(draw_item.fBorder)
350 for(int i=0;i<countof(m_switchpts);i++)
351 m_switchpts[i] = draw_item.switchpts[i];
354 bool DrawItemHashKey::operator==( const DrawItemHashKey& key ) const
356 AddFuncCalls(DrawItemHashKey_EQUAL);
357 return (this==&key) || (
358 (m_clip_rect == key.m_clip_rect)==TRUE &&
359 m_xsub == key.m_xsub &&
360 m_ysub == key.m_ysub &&
361 m_fBody == key.m_fBody &&
362 m_fBorder == key.m_fBorder &&
363 !memcmp(m_switchpts, key.m_switchpts, sizeof(m_switchpts)) &&
364 *m_overlay_key==*key.m_overlay_key &&
365 m_clipper_key==key.m_clipper_key);
368 //////////////////////////////////////////////////////////////////////////////////////////////
370 // GroupedDrawItemsHashKey
372 ULONG GroupedDrawItemsHashKey::UpdateHashValue()
374 m_hash_value = hash_value(m_clip_rect);
375 ASSERT(m_key);
376 for( unsigned i=0;i<m_key->GetCount();i++)
378 m_hash_value += (m_hash_value<<5);
379 m_hash_value += m_key->GetAt(i)->GetHashValue();
381 return m_hash_value;
384 bool GroupedDrawItemsHashKey::operator==( const GroupedDrawItemsHashKey& key ) const
386 AddFuncCalls(GroupedDrawItemsHashKey_EQUAL);
387 if (this==&key)
389 return true;
391 else if ( m_key->GetCount()!=key.m_key->GetCount() || m_clip_rect!=key.m_clip_rect)
393 return false;
395 else
397 for( unsigned i=0;i<m_key->GetCount();i++)
399 if( !(*m_key->GetAt(i) == *key.m_key->GetAt(i)) )
400 return false;
402 return true;
404 return true;
408 //////////////////////////////////////////////////////////////////////////////////////////////
410 // CacheManager
412 struct Caches
414 public:
415 Caches()
417 s_bitmap_cache = NULL;
418 s_clipper_alpha_mask_cache = NULL;
420 s_text_info_cache = NULL;
421 s_path_data_mru_cache = NULL;
422 s_scan_line_data_2_mru_cache = NULL;
423 s_overlay_no_blur_mru_cache = NULL;
424 s_overlay_mru_cache = NULL;
426 s_scan_line_data_mru_cache = NULL;
427 s_overlay_no_offset_mru_cache = NULL;
429 s_subpixel_variance_cache = NULL;
430 s_ass_tag_list_cache = NULL;
432 ~Caches()
434 delete s_bitmap_cache;
435 delete s_clipper_alpha_mask_cache;
437 delete s_text_info_cache;
438 delete s_path_data_mru_cache;
439 delete s_scan_line_data_2_mru_cache;
440 delete s_overlay_no_blur_mru_cache;
441 delete s_overlay_mru_cache;
443 delete s_scan_line_data_mru_cache;
444 delete s_overlay_no_offset_mru_cache;
446 delete s_subpixel_variance_cache;
447 delete s_ass_tag_list_cache;
449 public:
450 BitmapMruCache* s_bitmap_cache;
451 ClipperAlphaMaskMruCache* s_clipper_alpha_mask_cache;
453 TextInfoMruCache* s_text_info_cache;
454 AssTagListMruCache* s_ass_tag_list_cache;
456 ScanLineDataMruCache* s_scan_line_data_mru_cache;
457 OverlayNoOffsetMruCache* s_overlay_no_offset_mru_cache;
459 OverlayMruCache* s_subpixel_variance_cache;
460 OverlayMruCache* s_overlay_mru_cache;
461 OverlayNoBlurMruCache* s_overlay_no_blur_mru_cache;
462 PathDataMruCache* s_path_data_mru_cache;
463 ScanLineData2MruCache* s_scan_line_data_2_mru_cache;
466 static Caches s_caches;
468 OverlayMruCache* CacheManager::GetOverlayMruCache()
470 if(s_caches.s_overlay_mru_cache==NULL)
472 s_caches.s_overlay_mru_cache = new OverlayMruCache(OVERLAY_CACHE_ITEM_NUM);
474 return s_caches.s_overlay_mru_cache;
477 PathDataMruCache* CacheManager::GetPathDataMruCache()
479 if (s_caches.s_path_data_mru_cache==NULL)
481 s_caches.s_path_data_mru_cache = new PathDataMruCache(PATH_CACHE_ITEM_NUM);
483 return s_caches.s_path_data_mru_cache;
486 OverlayNoBlurMruCache* CacheManager::GetOverlayNoBlurMruCache()
488 if(s_caches.s_overlay_no_blur_mru_cache==NULL)
490 s_caches.s_overlay_no_blur_mru_cache = new OverlayNoBlurMruCache(OVERLAY_NO_BLUR_CACHE_ITEM_NUM);
492 return s_caches.s_overlay_no_blur_mru_cache;
495 ScanLineData2MruCache* CacheManager::GetScanLineData2MruCache()
497 if(s_caches.s_scan_line_data_2_mru_cache==NULL)
499 s_caches.s_scan_line_data_2_mru_cache = new ScanLineData2MruCache(SCAN_LINE_DATA_CACHE_ITEM_NUM);
501 return s_caches.s_scan_line_data_2_mru_cache;
504 OverlayMruCache* CacheManager::GetSubpixelVarianceCache()
506 if(s_caches.s_subpixel_variance_cache==NULL)
508 s_caches.s_subpixel_variance_cache = new OverlayMruCache(SUBPIXEL_VARIANCE_CACHE_ITEM_NUM);
510 return s_caches.s_subpixel_variance_cache;
513 ScanLineDataMruCache* CacheManager::GetScanLineDataMruCache()
515 if(s_caches.s_scan_line_data_mru_cache==NULL)
517 s_caches.s_scan_line_data_mru_cache = new ScanLineDataMruCache(SCAN_LINE_DATA_CACHE_ITEM_NUM);
519 return s_caches.s_scan_line_data_mru_cache;
522 OverlayNoOffsetMruCache* CacheManager::GetOverlayNoOffsetMruCache()
524 if(s_caches.s_overlay_no_offset_mru_cache==NULL)
526 s_caches.s_overlay_no_offset_mru_cache = new OverlayNoOffsetMruCache(OVERLAY_NO_BLUR_CACHE_ITEM_NUM);
528 return s_caches.s_overlay_no_offset_mru_cache;
531 AssTagListMruCache* CacheManager::GetAssTagListMruCache()
533 if(s_caches.s_ass_tag_list_cache==NULL)
535 s_caches.s_ass_tag_list_cache = new AssTagListMruCache(ASS_TAG_LIST_CACHE_ITEM_NUM);
537 return s_caches.s_ass_tag_list_cache;
540 TextInfoMruCache* CacheManager::GetTextInfoCache()
542 if(s_caches.s_text_info_cache==NULL)
544 s_caches.s_text_info_cache = new TextInfoMruCache(TEXT_INFO_CACHE_ITEM_NUM);
546 return s_caches.s_text_info_cache;
549 ClipperAlphaMaskMruCache* CacheManager::GetClipperAlphaMaskMruCache()
551 if(s_caches.s_clipper_alpha_mask_cache==NULL)
553 s_caches.s_clipper_alpha_mask_cache = new ClipperAlphaMaskMruCache(CLIPPER_MRU_CACHE_ITEM_NUM);
555 return s_caches.s_clipper_alpha_mask_cache;
558 BitmapMruCache* CacheManager::GetBitmapMruCache()
560 if (s_caches.s_bitmap_cache==NULL)
562 s_caches.s_bitmap_cache = new BitmapMruCache(BITMAP_MRU_CACHE_ITEM_NUM);
564 return s_caches.s_bitmap_cache;