public boolean createCache(BaseDanmaku item) { // measure if (!item.isMeasured()) { item.measure(mDisp); } DrawingCache cache = null; try { cache = mCachePool.acquire(); cache = DanmakuUtils.buildDanmakuDrawingCache(item, mDisp, cache); item.cache = cache; } catch (OutOfMemoryError e) { // Log.e("cache", "break at error: oom"); if (cache != null) { mCachePool.release(cache); } item.cache = null; return false; } catch (Exception e) { // Log.e("cache", "break at exception:" + e.getMessage()); if (cache != null) { mCachePool.release(cache); } item.cache = null; return false; } return true; }
private long clearCache(BaseDanmaku oldValue) { if (oldValue.cache.hasReferences()) { oldValue.cache.decreaseReference(); oldValue.cache = null; return 0; } long size = sizeOf(oldValue); oldValue.cache.destroy(); oldValue.cache = null; return size; }
private void releaseDanmakuCache(BaseDanmaku item, DrawingCache cache) { if (cache == null) { cache = (DrawingCache) item.cache; } item.cache = null; if (cache == null) { return; } cache.destroy(); mCachePool.release(cache); }
@Override protected void onDanmakuRemoved(BaseDanmaku danmaku) { super.onDanmakuRemoved(danmaku); if (danmaku.hasDrawingCache()) { if (danmaku.cache.hasReferences()) { danmaku.cache.decreaseReference(); } else { danmaku.cache.destroy(); } danmaku.cache = null; } }
private byte buildCache(BaseDanmaku item, boolean forceInsert) { // measure if (!item.isMeasured()) { item.measure(mDisp); } DrawingCache cache = null; try { // try to find reuseable cache BaseDanmaku danmaku = findReuseableCache(item, true, 20); if (danmaku != null) { cache = (DrawingCache) danmaku.cache; } if (cache != null) { cache.increaseReference(); item.cache = cache; // Log.w("cache", danmaku.text + "DrawingCache hit!!:" + item.paintWidth + "," + // danmaku.paintWidth); mCacheManager.push(item, 0, forceInsert); return RESULT_SUCCESS; } // try to find reuseable cache from timeout || no-refrerence caches danmaku = findReuseableCache(item, false, 50); if (danmaku != null) { cache = (DrawingCache) danmaku.cache; } if (cache != null) { danmaku.cache = null; // Log.e("cache", danmaku.text + "DrawingCache hit!!:" + item.paintWidth + "," + // danmaku.paintWidth); cache = DanmakuUtils.buildDanmakuDrawingCache(item, mDisp, cache); // redraw item.cache = cache; mCacheManager.push(item, 0, forceInsert); return RESULT_SUCCESS; } // guess cache size if (!forceInsert) { int cacheSize = DanmakuUtils.getCacheSize((int) item.paintWidth, (int) item.paintHeight); if (mRealSize + cacheSize > mMaxSize) { // Log.d("cache", "break at MaxSize:"+mMaxSize); return RESULT_FAILED; } } cache = mCachePool.acquire(); cache = DanmakuUtils.buildDanmakuDrawingCache(item, mDisp, cache); item.cache = cache; boolean pushed = mCacheManager.push(item, sizeOf(item), forceInsert); if (!pushed) { releaseDanmakuCache(item, cache); // Log.e("cache", "break at push failed:" + mMaxSize); } return pushed ? RESULT_SUCCESS : RESULT_FAILED; } catch (OutOfMemoryError e) { // Log.e("cache", "break at error: oom"); releaseDanmakuCache(item, cache); return RESULT_FAILED; } catch (Exception e) { // Log.e("cache", "break at exception:" + e.getMessage()); releaseDanmakuCache(item, cache); return RESULT_FAILED; } }
@Override public void handleMessage(Message msg) { int what = msg.what; switch (what) { case PREPARE: evictAllNotInScreen(); for (int i = 0; i < 300; i++) { mCachePool.release(new DrawingCache()); } case DISPATCH_ACTIONS: // Log.e(TAG,"dispatch_actions:"+mCacheTimer.currMillisecond+":"+mTimer.currMillisecond); long delayed = dispatchAction(); if (delayed <= 0) { delayed = mContext.mDanmakuFactory.MAX_DANMAKU_DURATION / 2; } sendEmptyMessageDelayed(DISPATCH_ACTIONS, delayed); break; case BUILD_CACHES: removeMessages(BUILD_CACHES); boolean repositioned = ((mTaskListener != null && mReadyState == false) || mSeekedFlag); prepareCaches(repositioned); if (repositioned) mSeekedFlag = false; if (mTaskListener != null && mReadyState == false) { mTaskListener.ready(); mReadyState = true; } // // Log.i(TAG,"BUILD_CACHES:"+mCacheTimer.currMillisecond+":"+mTimer.currMillisecond); break; case ADD_DANMAKKU: BaseDanmaku item = (BaseDanmaku) msg.obj; addDanmakuAndBuildCache(item); break; case REBUILD_CACHE: Pair<BaseDanmaku, Boolean> pair = (Pair<BaseDanmaku, Boolean>) msg.obj; if (pair != null) { BaseDanmaku cacheitem = pair.first; if (pair.second) { cacheitem.requestFlags |= BaseDanmaku.FLAG_REQUEST_REMEASURE; } cacheitem.requestFlags |= BaseDanmaku.FLAG_REQUEST_INVALIDATE; if (!pair.second && cacheitem.hasDrawingCache() && !cacheitem.cache.hasReferences()) { DrawingCache cache = DanmakuUtils.buildDanmakuDrawingCache( cacheitem, mDisp, (DrawingCache) cacheitem.cache); cacheitem.cache = cache; push(cacheitem, 0, true); return; } if (cacheitem.isLive) { clearCache(cacheitem); createCache(cacheitem); } else { entryRemoved(true, cacheitem, null); addDanmakuAndBuildCache(cacheitem); } } break; case CLEAR_TIMEOUT_CACHES: clearTimeOutCaches(); break; case SEEK: Long seekMills = (Long) msg.obj; if (seekMills != null) { mCacheTimer.update(seekMills.longValue()); mSeekedFlag = true; evictAllNotInScreen(); resume(); } break; case QUIT: removeCallbacksAndMessages(null); mPause = true; evictAll(); clearCachePool(); this.getLooper().quit(); break; case CLEAR_ALL_CACHES: evictAll(); mCacheTimer.update( mTimer.currMillisecond - mContext.mDanmakuFactory.MAX_DANMAKU_DURATION); mSeekedFlag = true; break; case CLEAR_OUTSIDE_CACHES: evictAllNotInScreen(true); mCacheTimer.update(mTimer.currMillisecond); break; case CLEAR_OUTSIDE_CACHES_AND_RESET: evictAllNotInScreen(true); mCacheTimer.update(mTimer.currMillisecond); requestClear(); break; } }