虽然没有在Android OpenGL绘图快速的屏幕闪烁 [英] Fast Screen Flicker while NOT drawing on Android OpenGL

查看:2115
本文介绍了虽然没有在Android OpenGL绘图快速的屏幕闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想节省电池续航时间。我的应用程序只需要有时绘制。 所以,我在OnDraw的方法添加这个code到我的渲染:

I wanted to save battery life time. My app only needs to be drawn sometimes. So I added this code to my Renderer in the onDraw method:

boolean dirty = true;

public void onDrawFrame(GL10 arg0) {
    if (!dirty) return;
    dirty = false;

    ..... draw images ....
}

所以,我的应用程序时,我希望它只是被画。但是,什么情况是,如果我不利用每一帧我的应用程序就闪烁非常快。它看起来像它会被绘制每2帧左右,在所有的只是一个黑色的屏幕将绘制其它帧。

So my app only gets drawn when I want it. But what happens is that if I dont draw my app on every frame it flickers really fast. It looks like it will be drawn every 2. frame or so and in all the other frames only a black screen will be drawn.

我知道我可以设置渲染模式为 RENDERMODE_WHEN_DIRTY 。但我不希望创建另一个线程来检查其肮脏与否。

I know that i could set the render mode to RENDERMODE_WHEN_DIRTY. But I dont want to create another thread to check if its dirty or not.

我的问题是,为什么它闪烁?我不调用任何方法或GLES20要求我做我的前检查:如果(!脏)回报; 和我深信布尔脏并没有改变,并且总是假的,除了第一帧。

My question is why does it flicker? i dont call any methods or GLES20 calls before i do my check: if (!dirty) return; and i am sure that the boolean dirty doesnt change and is always false except for the first frame.

编辑:

我改变了我的code到这一点:

I changed my code to this:

int dirty = 0;

public void onDrawFrame(GL10 arg0) {
    if (dirty > 1) return;
    dirty++;

    ..... draw images ....
}

这将停止闪烁!看起来你有,所以你不要有这种奇怪的屏幕闪烁绘制至少有2个次。反正我现在会尝试使用更清洁的方式,并创建一个线程调用 requestRender()时,我想画的东西,把我的渲染模式为 RENDERMODE_WHEN_DIRTY

This stops the flickering! Looks like you have to draw atleast 2 times so you dont have this wierd screen flickering. Anyways I will now try to use the more clean way and create a thread that calls requestRender() when i want to draw something and set my render mode to RENDERMODE_WHEN_DIRTY

推荐答案

onDrawFrame()被调用时,为时已晚,以决定你不想画一帧。不管你在那方法来绘制将是presented。如果你不画任何东西,无论发生是在渲染目标将是presented。有没有保证关于那是什么。它可能是一个较旧的帧,或随机垃圾

When onDrawFrame() is called, it's too late to decide that you don't want to draw a frame. Whatever you draw in that method will be presented. If you don't draw anything, whatever happened to be in the render target will be presented. There's no guarantee about what that is. It could be an older frame, or random garbage.

解决方法,你发现渲染帧至少两次可能对当前系统的,但我不会在它的工作无处不在计数。它也将浪费电池电量。当你跳过实际的渲染,框架将仍然是presented。

The workaround you found of rendering the frame at least twice may work for your current system, but I wouldn't count on it working everywhere. It will also waste battery power. While you skip the actual rendering, the frames will still be presented.

最好的办法是真的,你使用 RENDERMODE_WHEN_DIRTY ,并触发更新,当你真正需要它们。我不知道你为什么会需要一个额外的线程。在你的程序逻辑某些时候,你会改变的数据/状态,需要重绘。您可以直接调用 requestRender()当这种情况发生,而不是设置一个标志,该标志必须由另一个线程进行检查。

The best solution is really that you use RENDERMODE_WHEN_DIRTY, and trigger updates when you actually need them. I'm not sure why you would need an extra thread for that. At some point in your program logic, you will change data/state that requires a redraw. You can directly call requestRender() when that happens, instead of setting a flag that has to be checked by another thread.

另一种选择是,你拨打:

Another option is that you call:

eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);

在设置背景/面。这就要求缓冲区的内容是在 eglSwapBuffers preserved()。它配备了一个大的警告,虽然:这是不支持的所有设备。您可以测试它是否支持:

while setting up the context/surface. This requests that the buffer content is preserved after eglSwapBuffers(). It comes with a big caveat, though: This is not supported on all devices. You can test if it's supported with:

EGLint surfType = 0;
eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfType);
if (surfType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) {
    // supported!
}

您也可以请求该功能选择配置的一部分。它被传递到属性的一部分 eglChooseConfig(),地址:

You can also request this functionality as part of choosing the config. As part of the attributes passed to eglChooseConfig(), add:

...
EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT,
...

但同样,这是不支持在所有设备上。所以这是唯一的一个真正的选择,如果你针对特定设备的,或者有一个备用的功能,如果它不支持。

But again, this is not supported on all devices. So it's only really an option if you're targeting specific devices, or have a functional fallback if it's not supported.

这篇关于虽然没有在Android OpenGL绘图快速的屏幕闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆