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

Divide foreground tasks and all-time tasks #4206

Merged
merged 6 commits into from Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -434,7 +434,7 @@ public void run() {
Native functions invoked by UI.
**************************************************************************************/
private void onKeyboardInput(String text) {
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
CocosEditBoxActivity.onKeyboardInputNative(text);
Expand All @@ -443,7 +443,7 @@ public void run() {
}

private void onKeyboardComplete(String text) {
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
CocosEditBoxActivity.onKeyboardCompleteNative(text);
Expand All @@ -452,7 +452,7 @@ public void run() {
}

private void onKeyboardConfirm(String text) {
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
CocosEditBoxActivity.onKeyboardConfirmNative(text);
Expand Down
47 changes: 32 additions & 15 deletions cocos/platform/android/java/src/com/cocos/lib/CocosHelper.java
Expand Up @@ -58,8 +58,11 @@ of this software and associated documentation files (the "Software"), to deal
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Queue;
import java.util.concurrent.locks.ReentrantLock;


public class CocosHelper {
Expand All @@ -86,9 +89,26 @@ public class CocosHelper {
// The OBB file
private static ZipResourceFile sOBBFile = null;

private static Object sTaskMtx = new Object();
private static List<Runnable> sTaskOnGameThread = Collections.synchronizedList(new ArrayList<>());
static class LockedTaskQ {
private final Object readMtx = new Object();
private Queue<Runnable> sTaskQ = new LinkedList<>();
public synchronized void addTask(Runnable runnable) {
sTaskQ.add(runnable);
}
public void runTasks(){
Queue<Runnable> tmp;
synchronized (readMtx) {
tmp = sTaskQ;
sTaskQ = new LinkedList<>();
}
for(Runnable runnable : tmp){
runnable.run();
}
}
}

private static LockedTaskQ sTaskQOnGameThread = new LockedTaskQ();
private static LockedTaskQ sForegroundTaskQOnGameThread = new LockedTaskQ();
/**
* Battery receiver to getting battery level.
*/
Expand Down Expand Up @@ -120,23 +140,20 @@ static void unregisterBatteryLevelReceiver(Context context) {
context.unregisterReceiver(sBatteryReceiver);
}

//Run on game thread forever, no matter foreground or background
public static void runOnGameThread(final Runnable runnable) {
synchronized (sTaskMtx) {
sTaskOnGameThread.add(runnable);
}
sTaskQOnGameThread.addTask(runnable);
}

static void flushTasksOnGameThread() {
List<Runnable> tmp = sTaskOnGameThread;
synchronized (sTaskMtx) {
sTaskOnGameThread = Collections.synchronizedList(new ArrayList<>());
}
while (tmp.size() > 0) {
Runnable r = tmp.remove(0);
if (r != null) {
r.run();
}
}
sTaskQOnGameThread.runTasks();
}
public static void runOnGameThreadAtForeground(final Runnable runnable) {
sForegroundTaskQOnGameThread.addTask(runnable);
}

static void flushTasksOnGameThreadAtForeground() {
sForegroundTaskQOnGameThread.runTasks();
}

public static int getNetworkType() {
Expand Down
Expand Up @@ -50,7 +50,7 @@ public boolean onKeyDown(final int keyCode, final KeyEvent event) {
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_DPAD_CENTER:
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
handleKeyDown(keyCode);
Expand All @@ -73,7 +73,7 @@ public boolean onKeyUp(final int keyCode, KeyEvent event) {
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_DPAD_CENTER:
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
handleKeyUp(keyCode);
Expand Down
Expand Up @@ -49,7 +49,7 @@ public void onOrientationChanged(int orientation) {
int curOrientation = CocosHelper.getDeviceRotation();
if (curOrientation != mCurrentOrientation) {
mCurrentOrientation = CocosHelper.getDeviceRotation();
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
nativeOnOrientationChanged(mCurrentOrientation);
Expand Down
Expand Up @@ -41,7 +41,7 @@ public CocosSurfaceView(Context context) {
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
nativeOnSizeChanged(w, h);
Expand Down
Expand Up @@ -60,7 +60,7 @@ boolean onTouchEvent(MotionEvent pMotionEvent) {
final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);
final float xPointerDown = pMotionEvent.getX(indexPointerDown);
final float yPointerDown = pMotionEvent.getY(indexPointerDown);
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
handleActionDown(idPointerDown, xPointerDown, yPointerDown);
Expand All @@ -79,7 +79,7 @@ public void run() {
final float xDown = xs[0];
final float yDown = ys[0];

CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
handleActionDown(idDown, xDown, yDown);
Expand All @@ -89,7 +89,7 @@ public void run() {
break;

case MotionEvent.ACTION_MOVE:
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
handleActionMove(ids, xs, ys);
Expand All @@ -103,7 +103,7 @@ public void run() {
final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);
final float xPointerUp = pMotionEvent.getX(indexPointUp);
final float yPointerUp = pMotionEvent.getY(indexPointUp);
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
handleActionUp(idPointerUp, xPointerUp, yPointerUp);
Expand All @@ -117,7 +117,7 @@ public void run() {
final int idUp = pMotionEvent.getPointerId(0);
final float xUp = xs[0];
final float yUp = ys[0];
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
handleActionUp(idUp, xUp, yUp);
Expand All @@ -127,7 +127,7 @@ public void run() {
break;

case MotionEvent.ACTION_CANCEL:
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
handleActionCancel(ids, xs, ys);
Expand Down
Expand Up @@ -170,7 +170,7 @@ public void handleMessage(Message msg) {

@Override
public void onVideoEvent(int tag,int event) {
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
nativeExecuteVideoCallback(tag, event);
Expand Down Expand Up @@ -282,7 +282,7 @@ private void onBackKeyEvent() {
CocosVideoView videoView = sVideoViews.get(key);
if (videoView != null) {
videoView.setFullScreenEnabled(false);
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
nativeExecuteVideoCallback(key, KeyEventBack);
Expand Down
Expand Up @@ -109,7 +109,7 @@ public boolean shouldOverrideUrlLoading(WebView view, final String urlString) {
try {
URI uri = URI.create(urlString);
if (uri != null && uri.getScheme().equals(mJSScheme)) {
CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
CocosWebViewHelper._onJsCallback(mViewTag, urlString);
Expand Down Expand Up @@ -141,7 +141,7 @@ public void run() {
public void onPageFinished(WebView view, final String url) {
super.onPageFinished(view, url);

CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
CocosWebViewHelper._didFinishLoading(mViewTag, url);
Expand All @@ -153,7 +153,7 @@ public void run() {
public void onReceivedError(WebView view, int errorCode, String description, final String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);

CocosHelper.runOnGameThread(new Runnable() {
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
@Override
public void run() {
CocosWebViewHelper._didFailLoading(mViewTag, failingUrl);
Expand Down
3 changes: 3 additions & 0 deletions cocos/platform/android/jni/JniCocosActivity.cpp
Expand Up @@ -169,6 +169,9 @@ void glThreadEntry() {
"flushTasksOnGameThread");
}
if (game && cc::cocosApp.animating) {

cc::JniHelper::callStaticVoidMethod("com.cocos.lib.CocosHelper",
"flushTasksOnGameThreadAtForeground");
game->tick();
}
if (cc::cocosApp.destroyRequested) break;
Expand Down
45 changes: 36 additions & 9 deletions cocos/platform/ohos/jni/JniCocosAbility.cpp
Expand Up @@ -88,6 +88,28 @@ int readCommand(CommandMsg *msg) {
return read(pipeRead, msg, sizeof(*msg));
}

int readCommandWithTimeout(CommandMsg *msg, int delayMS) {
if (delayMS > 0) {
static fd_set fdSet;
static timeval timeout;

timeout = {delayMS / 1000, (delayMS % 1000) * 1000};
FD_ZERO(&fdSet);
FD_SET(pipeRead, &fdSet);

auto ret = select(pipeRead + 1, &fdSet, nullptr, nullptr, &timeout);
if (ret < 0) {
LOGV("failed to run select(..): %s\n", strerror(errno));
return ret;
}

if (ret == 0) {
return 0;
}
}
return read(pipeRead, msg, sizeof(*msg));
}

void handlePauseResume(int8_t cmd) {
LOGV("activityState=%d", cmd);
cc::cocosApp.activityState = cmd;
Expand Down Expand Up @@ -139,27 +161,32 @@ void glThreadEntry() {
cc::cocosApp.glThreadPromise.set_value();
cc::cocosApp.running = true;

int cmd = 0;
CommandMsg msg;
bool runInLowRate = false;
while (true) {
if (readCommand(&msg) > 0) {
cmd = msg.cmd;
preExecCmd(cmd);
cc::View::engineHandleCmd(cmd);
postExecCmd(cmd);
runInLowRate = !cc::cocosApp.animating || ABILITY_CMD_PAUSE == cc::cocosApp.activityState;
if (readCommandWithTimeout(&msg, runInLowRate ? 50 : 0) > 0) {
// if(readCommand(0&msg)>0){
preExecCmd(msg.cmd);
cc::View::engineHandleCmd(msg.cmd);
postExecCmd(msg.cmd);
if (msg.callback) {
msg.callback();
}
}
// if (!cc::cocosApp.animating || ABILITY_CMD_PAUSE == cc::cocosApp.activityState) {
// std::this_thread::yield();
// }

if (!cc::cocosApp.animating || ABILITY_CMD_PAUSE == cc::cocosApp.activityState) {
std::this_thread::yield();
if (game) {
cc::JniHelper::callStaticVoidMethod("com.cocos.lib.CocosHelper",
"flushTasksOnGameThread");
}

if (game && cc::cocosApp.animating) {
// Handle java events send by UI thread. Input events are handled here too.
cc::JniHelper::callStaticVoidMethod("com.cocos.lib.CocosHelper",
"flushTasksOnGameThread");
"flushTasksOnGameThreadAtForeground");
game->tick();
}

Expand Down
Expand Up @@ -152,7 +152,7 @@ protected void initView() {
mSurfaceProvider.setTouchEventListener(this);
mSurfaceProvider.setLayoutRefreshedListener(component -> {
// dispatch resize event
CocosHelper.runOnGameThread(()->{
CocosHelper.runOnGameThreadAtForeground(()->{
onOrientationChangedNative(getDisplayOrientation(), component.getWidth(), component.getHeight());
});
});
Expand Down
Expand Up @@ -397,19 +397,19 @@ private static void hideNative() {
Native functions invoked by UI.
**************************************************************************************/
private void onKeyboardInput(String text) {
CocosHelper.runOnGameThread(() ->
CocosHelper.runOnGameThreadAtForeground(() ->
CocosEditBoxAbility.onKeyboardInputNative(text)
);
}

private void onKeyboardComplete(String text) {
CocosHelper.runOnGameThread(() ->
CocosHelper.runOnGameThreadAtForeground(() ->
CocosEditBoxAbility.onKeyboardCompleteNative(text)
);
}

private void onKeyboardConfirm(String text) {
CocosHelper.runOnGameThread(() ->
CocosHelper.runOnGameThreadAtForeground(() ->
CocosEditBoxAbility.onKeyboardConfirmNative(text)
);
}
Expand Down