Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

去除CacheManagingDrawTask清除弹幕缓存等待30毫秒 #396

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions DanmakuFlameMaster/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ apply plugin: 'com.android.library'
def SourcePath = 'src/main/'

android {
compileSdkVersion 25
buildToolsVersion "26.0.2"
compileSdkVersion 27
buildToolsVersion "27.0.3"

defaultConfig {
minSdkVersion 9
Expand All @@ -42,6 +42,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_7
}
}

dependencies {
implementation 'com.android.support:support-annotations:28.0.0'
}
if (rootProject.file('gradle/gradle-mvn-push.gradle').exists()) {
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
}
Expand Down
10 changes: 10 additions & 0 deletions DanmakuFlameMaster/src/main/assets/gl/glview.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
precision mediump float;
uniform sampler2D vTexture;
uniform float alpha;
varying vec2 aCoordinate;

void main()
{
gl_FragColor = texture2D(vTexture,aCoordinate);
gl_FragColor.a = gl_FragColor.a * alpha;
}
15 changes: 15 additions & 0 deletions DanmakuFlameMaster/src/main/assets/gl/glview.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
attribute vec4 vPosition;
attribute vec2 vCoordinate;
precision highp float;

uniform mat4 vProject;
uniform mat4 vView;
uniform mat4 vModel;

varying vec2 aCoordinate;

void main()
{
gl_Position=vProject*vView*vModel*vPosition;
aCoordinate=vCoordinate;
}
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public class CacheManager implements ICacheManager {

public HandlerThread mThread;

Danmakus mCaches = new Danmakus();
final Danmakus mCaches = new Danmakus();

DrawingCachePoolManager mCachePoolManager = new DrawingCachePoolManager();

Expand Down Expand Up @@ -241,12 +241,22 @@ public void addDanmaku(BaseDanmaku danmaku) {
}
}

@Override
public void buildDanmakuCache(final BaseDanmaku danmaku) {
if (danmaku == null) {
return;
}
CacheHandler handler = mHandler;
if (handler != null) {
//直接构建缓存
handler.addDanmakuAndBuildCache(danmaku, false);
}
}

public void invalidateDanmaku(BaseDanmaku danmaku, boolean remeasure) {
if (mHandler != null) {
mHandler.requestCancelCaching();
mHandler.obtainMessage(CacheHandler.REBUILD_CACHE, danmaku).sendToTarget();
mHandler.sendEmptyMessage(CacheHandler.DISABLE_CANCEL_FLAG);
requestBuild(0);
}
}

Expand All @@ -267,7 +277,6 @@ public void end() {
mDrawingNotify.notifyAll();
}
if (mHandler != null) {
mHandler.removeCallbacksAndMessages(null);
mHandler.pause();
mHandler = null;
}
Expand Down Expand Up @@ -381,12 +390,14 @@ private void clearCachePool() {

private boolean push(BaseDanmaku item, int itemSize, boolean forcePush) {
int size = itemSize; //sizeOf(item);
if (size > 0) {
clearTimeOutAndFilteredCaches(size, forcePush);
// may be a risk of OOM if (mRealSize + size) is still larger than mMaxSize
synchronized (this.mCaches) {
if (size > 0) {
clearTimeOutAndFilteredCaches(size, forcePush);
// may be a risk of OOM if (mRealSize + size) is still larger than mMaxSize
}
this.mCaches.addItem(item);
mRealSize += size;
}
this.mCaches.addItem(item);
mRealSize += size;
//Log.i("DFM CACHE", "realsize:"+mRealSize + ",size" + size);
return true;
}
Expand All @@ -403,16 +414,6 @@ public int accept(BaseDanmaku val) {
}
//else 回收尺寸过大的cache
}
if (!mEndFlag) {
synchronized (mDrawingNotify) {
try {
mDrawingNotify.wait(30);
} catch (InterruptedException e) {
e.printStackTrace();
return ACTION_BREAK;
}
}
}
entryRemoved(false, val, null);
return ACTION_REMOVE;
} else {
Expand Down Expand Up @@ -554,28 +555,30 @@ public void handleMessage(Message msg) {
break;
case ADD_DANMAKU:
BaseDanmaku item = (BaseDanmaku) msg.obj;
addDanmakuAndBuildCache(item);
addDanmakuAndBuildCache(item, false);
break;
case REBUILD_CACHE:
BaseDanmaku cacheitem = (BaseDanmaku) msg.obj;
if (cacheitem != null) {
IDrawingCache<?> cache = cacheitem.getDrawingCache();
boolean requestRemeasure = 0 != (cacheitem.requestFlags & BaseDanmaku.FLAG_REQUEST_REMEASURE);
if (!requestRemeasure && cache != null && cache.get() !=null && !cache.hasReferences()) {
cache = DanmakuUtils.buildDanmakuDrawingCache(cacheitem, mDisp, (DrawingCache) cacheitem.cache, mContext.cachingPolicy.bitsPerPixelOfCache);
cacheitem.cache = cache;
push(cacheitem, 0, true);
return;
}
if (cacheitem.isLive) {
clearCache(cacheitem);
createCache(cacheitem);
} else {
if (cache != null && cache.hasReferences()) {
cache.destroy();
synchronized (cacheitem) {
IDrawingCache<?> cache = cacheitem.getDrawingCache();
boolean requestRemeasure = 0 != (cacheitem.requestFlags & BaseDanmaku.FLAG_REQUEST_REMEASURE);
if (!requestRemeasure && cache != null && cache.get() != null && !cache.hasReferences()) {
cache = DanmakuUtils.buildDanmakuDrawingCache(cacheitem, mDisp, (DrawingCache) cacheitem.cache, mContext.cachingPolicy.bitsPerPixelOfCache);
cacheitem.cache = cache;
push(cacheitem, 0, true);
return;
}
if (cacheitem.isLive) {
clearCache(cacheitem);
createCache(cacheitem);
} else {
if (cache != null && cache.hasReferences()) {
cache.destroy();
}
entryRemoved(true, cacheitem, null);
addDanmakuAndBuildCache(cacheitem, true);
}
entryRemoved(true, cacheitem, null);
addDanmakuAndBuildCache(cacheitem);
}
}
break;
Expand Down Expand Up @@ -816,7 +819,12 @@ public int accept(BaseDanmaku item) {
}

// build cache
buildCache(item, false);
synchronized (item) {
cache = item.getDrawingCache();
if (cache == null || cache.get() == null) {
buildCache(item, false, false);
}
}
if (!repositioned) {
long consumingTime = SystemClock.uptimeMillis() - startTime;
if (consumingTime >= mContext.mDanmakuFactory.COMMON_DANMAKU_DURATION * mScreenSize) {
Expand All @@ -838,34 +846,36 @@ public int accept(BaseDanmaku item) {
}

public boolean createCache(BaseDanmaku item) {
// measure
if (!item.isMeasured()) {
item.measure(mDisp, true);
}
DrawingCache cache = null;
try {
cache = mCachePool.acquire();
cache = DanmakuUtils.buildDanmakuDrawingCache(item, mDisp, cache, mContext.cachingPolicy.bitsPerPixelOfCache);
item.cache = cache;
} catch (OutOfMemoryError e) {
//Log.e("cache", "break at error: oom");
if (cache != null) {
mCachePool.release(cache);
synchronized (item) {
// measure
if (!item.isMeasured()) {
item.measure(mDisp, true);
}
item.cache = null;
return false;
} catch (Exception e) {
DrawingCache cache = null;
try {
cache = mCachePool.acquire();
cache = DanmakuUtils.buildDanmakuDrawingCache(item, mDisp, cache, mContext.cachingPolicy.bitsPerPixelOfCache);
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);
if (cache != null) {
mCachePool.release(cache);
}
item.cache = null;
return false;
}
item.cache = null;
return false;
return true;
}
return true;
}

private byte buildCache(BaseDanmaku item, boolean forceInsert) {
private byte buildCache(BaseDanmaku item, boolean forceInsert, boolean rebuild) {

// measure
if (!item.isMeasured()) {
Expand Down Expand Up @@ -896,6 +906,7 @@ private byte buildCache(BaseDanmaku item, boolean forceInsert) {
danmaku.cache = null;
//Log.e("cache", danmaku.text + "DrawingCache hit!!:" + item.paintWidth + "," + danmaku.paintWidth);
cache = DanmakuUtils.buildDanmakuDrawingCache(item, mDisp, cache, mContext.cachingPolicy.bitsPerPixelOfCache); //redraw
delayDanmakuIfNeed(item, rebuild);
item.cache = cache;
mCacheManager.push(item, 0, forceInsert);
return RESULT_SUCCESS;
Expand All @@ -915,6 +926,7 @@ private byte buildCache(BaseDanmaku item, boolean forceInsert) {

cache = mCachePool.acquire();
cache = DanmakuUtils.buildDanmakuDrawingCache(item, mDisp, cache, mContext.cachingPolicy.bitsPerPixelOfCache);
delayDanmakuIfNeed(item, rebuild);
item.cache = cache;
boolean pushed = mCacheManager.push(item, sizeOf(item), forceInsert);
if (!pushed) {
Expand All @@ -934,7 +946,7 @@ private byte buildCache(BaseDanmaku item, boolean forceInsert) {
}
}

private final void addDanmakuAndBuildCache(BaseDanmaku danmaku) {
private final void addDanmakuAndBuildCache(BaseDanmaku danmaku, boolean rebuild) {
if (danmaku.isTimeOut() || (danmaku.getActualTime() > mCacheTimer.currMillisecond + mContext.mDanmakuFactory.MAX_DANMAKU_DURATION && !danmaku.isLive)) {
return;
}
Expand All @@ -943,7 +955,30 @@ private final void addDanmakuAndBuildCache(BaseDanmaku danmaku) {
}
IDrawingCache<?> cache = danmaku.getDrawingCache();
if (cache == null || cache.get() == null) {
buildCache(danmaku, true);
synchronized (danmaku) {
cache = danmaku.getDrawingCache();
if (cache == null || cache.get() == null) {
buildCache(danmaku, true, rebuild);
}
}
}
}

private void delayDanmakuIfNeed(BaseDanmaku item, boolean rebuild) {
if (!rebuild && !item.isOutside() && mContext.cachingPolicy.mAllowDelayInCacheModel) {
//该弹幕已经迟到了,将显示时间延后
/*该处必须比mTimer.currMillisecond小
* 原因参考DanmakuUtils#willHitInDuration方法判断两个弹幕碰撞
* 因为item.isOutside()此时等于false,大概率已经被layout了,并且在某一行的最后面
* 此时如果直接设置mTimer.currMillisecond,后面item.isOutside()会变成true,
* 碰撞结果变成false,后面很多弹幕被别添加到同一行,导致弹幕堆积在某一行,而下方
* 留下大量空白
* */
item.setTime(mTimer.currMillisecond - 1);
//重新计算位置
if (item.isShown()) {
item.layout(mContext.getDisplayer(), item.getLeft(), item.getTop());
}
}
}

Expand Down Expand Up @@ -991,7 +1026,7 @@ public int accept(BaseDanmaku oldValue) {
return IDanmakus.Consumer.ACTION_BREAK;
}
if (mRealSize + fexpectedFreeSize > mMaxSize) {
if (oldValue.isTimeOut() || oldValue.isFiltered()) {
if (oldValue.isTimeOut() || (oldValue.priority == 0 && oldValue.isFiltered())) {
entryRemoved(false, oldValue, null);
return IDanmakus.Consumer.ACTION_REMOVE;
} else if (forcePush) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
import master.flame.danmaku.danmaku.renderer.IRenderer.RenderingState;
import master.flame.danmaku.danmaku.util.SystemClock;
import master.flame.danmaku.gl.AndroidGLDisplayer;
import master.flame.danmaku.gl.GLDrawTask;
import tv.cjump.jni.DeviceUtils;

public class DrawHandler extends Handler {
Expand Down Expand Up @@ -625,7 +627,8 @@ private IDrawTask createDrawTask(boolean useDrwaingCache, DanmakuTimer timer,
displayMetrics.scaledDensity);
mDisp.resetSlopPixel(mContext.scaleTextSize);
mDisp.setHardwareAccelerated(isHardwareAccelerated);
IDrawTask task = useDrwaingCache ?
mContext.cachingPolicy.mCacheDrawEnabled = useDrwaingCache || mDisp instanceof AndroidGLDisplayer;
IDrawTask task = mDisp instanceof AndroidGLDisplayer ? new GLDrawTask(timer, mContext, taskListener) : useDrwaingCache ?
new CacheManagingDrawTask(timer, mContext, taskListener)
: new DrawTask(timer, mContext, taskListener);
task.setParser(mParser);
Expand Down
Loading