Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
本机Android多线程奇数出现_Android_C++_Multithreading_Opengl Es - Fatal编程技术网

本机Android多线程奇数出现

本机Android多线程奇数出现,android,c++,multithreading,opengl-es,Android,C++,Multithreading,Opengl Es,我一直在本地Android/NDK级别上开发这个游戏。首先,我只有一个纹理,但当我的纹理达到5时,我的fps从60左右慢慢减少到20左右(伴有口吃) 目前我在一个线程上执行我的所有操作。在引入另一个使用posix线程和start_例程(无限循环且没有实现)的线程时,我的fps似乎毫无理由地达到了40左右 这里的另一点是,引入该线程后,FPS稳定在42-43。但如果没有线程,就会出现口吃(每秒18-28帧),导致动画抖动。 我的疑问是: 为什么会发生上述情况(与线程相关) 此外,我使用1纹理时的唯

我一直在本地Android/NDK级别上开发这个游戏。首先,我只有一个纹理,但当我的纹理达到5时,我的fps从60左右慢慢减少到20左右(伴有口吃)

目前我在一个线程上执行我的所有操作。在引入另一个使用posix线程和start_例程(无限循环且没有实现)的线程时,我的fps似乎毫无理由地达到了40左右

这里的另一点是,引入该线程后,FPS稳定在42-43。但如果没有线程,就会出现口吃(每秒18-28帧),导致动画抖动。 我的疑问是:

  • 为什么会发生上述情况(与线程相关)
  • 此外,我使用1纹理时的唯一区别是,碎片着色器中的计算现在更加复杂。这是否意味着GPU过载,因此glSwapBuffers需要更多的时间
  • 假设glSwapBuffers确实需要时间,这是否意味着我的游戏逻辑总是领先于我的渲染器
  • 如何准确地向渲染线程提供渲染帧所需的信息?和中一样,我是否让渲染线程在由游戏逻辑线程提供的队列上等待?(与守则有关)
  • 代码:

    void * start_render (void * param)
    {
    
        while (1) {
    
        }
    
        return NULL;
    }
    
    void android_main(struct android_app* state) {
    
    
        // Creation of this thread, increased my FPS to around 40 even though start_render wasnt doing     anything
    
        pthread_t renderthread;
        pthread_create(&renderthread,NULL,start_render,NULL);
    
    
        struct engine engine;
    
        memset(&engine, 0, sizeof(engine));
        state->userData = &engine;
        state->onAppCmd = engine_handle_cmd;
        state->onInputEvent = engine_handle_input;
    
    
        engine.assetManager = state->activity->assetManager;
    
        engine.app = state;
        engine.texsize = 4;
    
    
        if (state->savedState != NULL) {
            // We are starting with a previous saved state; restore from it.
            engine.state = *(struct saved_state*)state->savedState;
        }
    
        // loop waiting for stuff to do.
    
        while (1) {
            // Read all pending events.
            int ident;
            int events;
            struct android_poll_source* source;
    
            // If not animating, we will block forever waiting for events.
            // If animating, we loop until all events are read, then continue
            // to draw the next frame of animation.
            while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events,
                    (void**)&source)) >= 0) {
    
                // Process this event.
                if (source != NULL) {
                    source->process(state, source);
                }
    
    
                // Check if we are exiting.
                if (state->destroyRequested != 0) {
                    engine_term_display(&engine);
                    return;
                }
            }
    
            if (engine.animating) {
    
    
    
                    for (int i = 0; i < 4;i++)
                    {
                        float cur = engine.mytextures[i].currentposition;
    
                        if (cur < 1.0)
                            engine.mytextures[i].currentposition = cur + engine.mytextures[i].relativespeed;
                        else
                            engine.mytextures[i].currentposition = cur - 1.0;
                    }
    
                // How do i enable the render thread (created above) to call the below function?
                on_draw_frame(&engine);
    
    
    
    
            }
        }
    }
    
    void on_draw_frame(engine * engine) {
    
        glUseProgram(program);
    
        engine->texsize = 4;
    
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, engine->mytextures[0].textureid);
    
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, engine->mytextures[1].textureid);
    
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_2D, engine->mytextures[2].textureid);
    
        glActiveTexture(GL_TEXTURE3);
        glBindTexture(GL_TEXTURE_2D, engine->mytextures[3].textureid);
    
        glUniform1i(u_texture_unit_location1,0);
        glUniform1i(u_texture_unit_location2,1);
        glUniform1i(u_texture_unit_location3,2);
        glUniform1i(u_texture_unit_location4,3);
    
    
        glUniform1f(timeCoord1,engine->mytextures[0].currentposition);
        glUniform1f(timeCoord2,engine->mytextures[1].currentposition);
        glUniform1f(timeCoord3,engine->mytextures[2].currentposition);
        glUniform1f(timeCoord4,engine->mytextures[3].currentposition);
    
    
    
        glUniform1i(texSize,engine->texsize);
    
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
    
        glVertexAttribPointer(a_position_location, 2, GL_FLOAT, GL_FALSE,
            4 * sizeof(GL_FLOAT), BUFFER_OFFSET(0));
        glVertexAttribPointer(a_texture_coordinates_location, 2, GL_FLOAT, GL_FALSE,
            4 * sizeof(GL_FLOAT), BUFFER_OFFSET(2 * sizeof(GL_FLOAT)));
        glEnableVertexAttribArray(a_position_location);
        glEnableVertexAttribArray(a_texture_coordinates_location);
    
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    
        eglSwapBuffers(engine->display, engine->surface);
    
    
        // FPS calculation
        if (fps == 0)
            clock_gettime(CLOCK_MONOTONIC, &starttime);
        else
            clock_gettime (CLOCK_MONOTONIC,&stoptime);
    
        if (stoptime.tv_sec - starttime.tv_sec == 1) {
    
            __android_log_print(ANDROID_LOG_VERBOSE, "GAME", "FPS %d",fps);
            fps = 0;
    
        } else
            fps++;
    
    }
    
    void*start\u渲染(void*param)
    {
    而(1){
    }
    返回NULL;
    }
    无效android_main(结构android_应用程序*状态){
    //创建这个线程,将我的FPS增加到40左右,即使start_render没有做任何事情
    pthread_t renderthread;
    pthread_create(&renderthread,NULL,start_render,NULL);
    结构引擎;
    memset(&engine,0,sizeof(engine));
    状态->用户数据=&引擎;
    state->onAppCmd=engine\u handle\u cmd;
    状态->onInputEvent=引擎\处理\输入;
    engine.assetManager=状态->活动->assetManager;
    engine.app=状态;
    engine.texsize=4;
    如果(状态->保存状态!=NULL){
    //我们从以前保存的状态开始;从中恢复。
    engine.state=*(struct saved_state*)state->savedState;
    }
    //循环等待要做的事情。
    而(1){
    //读取所有挂起的事件。
    内部识别;
    国际赛事;
    struct android_poll_source*source;
    //如果不设置动画,我们将永远阻止等待事件。
    //如果设置动画,我们将循环直到读取所有事件,然后继续
    //绘制动画的下一帧。
    while((ident=ALooper_pollAll)(engine.animating?0:-1,NULL,&事件,
    (void**)和source))>=0){
    //处理此事件。
    如果(源!=NULL){
    来源->过程(状态,来源);
    }
    //检查我们是否正在离开。
    如果(状态->请求销毁!=0){
    引擎\术语\显示(&engine);
    回来
    }
    }
    if(引擎动画){
    对于(int i=0;i<4;i++)
    {
    float cur=engine.mytextures[i].currentposition;
    如果(电流<1.0)
    engine.mytextures[i]。currentposition=cur+engine.mytextures[i]。relativespeed;
    其他的
    engine.mytextures[i].currentposition=cur-1.0;
    }
    //如何使渲染线程(在上面创建)调用下面的函数?
    在绘图框(发动机)上;
    }
    }
    }
    绘图框上的空白(发动机*发动机){
    glUseProgram(程序);
    引擎->texsize=4;
    玻璃纹理(GL_纹理0);
    glBindTexture(GL_TEXTURE_2D,引擎->mytextures[0].textureid);
    玻璃结构(GL_纹理1);
    glBindTexture(GL_TEXTURE_2D,引擎->mytextures[1].textureid);
    玻璃结构(GL_纹理2);
    glBindTexture(GL_TEXTURE_2D,引擎->mytextures[2].textureid);
    玻璃纹理(GL_纹理3);
    glBindTexture(GL_TEXTURE_2D,引擎->mytextures[3].textureid);
    glUniform1i(u_纹理单位位置1,0);
    glUniform1i(u_纹理单位位置2,1);
    glUniform1i(u_纹理单位位置3,2);
    glUniform1i(u_纹理单位位置4,3);
    glUniform1f(时间坐标1,引擎->mytextures[0].currentposition);
    glUniform1f(timeCoord2,引擎->mytextures[1].currentposition);
    glUniform1f(timeCoord3,引擎->mytextures[2].currentposition);
    glUniform1f(timeCoord4,引擎->mytextures[3].currentposition);
    glUniform1i(texSize,引擎->texSize);
    glBindBuffer(GL_数组_BUFFER,BUFFER);
    GLVertexAttribute指针(a位置,2,GL浮动,GL假,
    4*sizeof(总账浮点数),缓冲区偏移量(0);
    GLVertexAttributePointer(纹理坐标位置,2,GL浮动,GL假,
    4*sizeof(GL_FLOAT),缓冲区偏移量(2*sizeof(GL_FLOAT));
    GlenableVertexAttributeArray(位置);
    GlenableVertexAttributeArray(纹理坐标位置);
    gldrawArray(GL_三角带,0,4);
    glBindBuffer(GL_数组_BUFFER,0);
    EGLSWAPBuffer(发动机->显示器,发动机->表面);
    //FPS计算
    如果(fps==0)
    时钟获取时间(时钟单调和开始时间);
    其他的
    时钟获取时间(时钟单调和停止时间);
    if(stoptime.tv_sec-starttime.tv_sec==1){
    __安卓日志打印(安卓日志详细,“游戏”,“FPS%d”,FPS);
    fps=0;
    }否则
    fps++;
    }
    

    如果您需要有关代码的更多信息,请告诉我。

    我不能完全确定,但这看起来很像电源管理对设备的不良影响

    您描述的症状可能是由关注CPU使用情况的电源管理策略引起的。有了这样的策略,如果CPU使用率非常低(因为大部分GPU有限),整个系统就会进入低功耗状态,并有效地降低GPU的速度,即使GPU已满载

    在这种情况下,当您通过启动另一个占用CPU时间的线程来增加额外的CPU负载时,您会