2011-07-26 3 views
0

백그라운드 스레드에서 텍스처를로드하고 GLSurfaceView.queueEvent (...)를 통해 GL 스레드에 비트 맵을 보내 그래픽 카드에 업로드합니다. 각 이미지로드 후 가비지 수집을 방지하기 위해 gl을 열려면 텍스처를 보내기 위해 2 차원의 거듭 제곱을 가진 비트 맵 하나를 다시 사용하십시오.백그라운드 스레드에로드 된 android opengl 텍스처를 덮어 씁니다.

문제이며,이 비트 맵은 작업자 스레드와 GL 스레드가 서로 싸우면서 때때로 덮어 씁니다. 내가 이해하기 때문에 하나의 스레드 (작업자)에서 잠금을 획득하고 다른 스레드 (GL)에서 잠금을 해제하는 것은 불가능합니다. 그래서 난 (내 스레드가 HandlerThread이다)이 같은 솔루션과 함께 제공 :

public boolean handleMessage(Message msg) { 
    switch(msg.what) { 
     case MESSAGE_FROM_MAIN_THREAD: 
      m_Lock.lock(); 
      loadTextureFromAssets(msg.obj.toString(), msg.arg1); 
      break; 

     case MESSAGE_FROM_GL_THREAD: 
      m_Lock.unlock(); 
      break; 
    } 

    return true; 
} 

는 m_Lock이 ReentrantLock와입니다했다. 하지만 여전히 작동하지 않으며 때로는 텍스처가 반복됩니다 (또는 부분적으로 텍스처가 덮어 쓰여집니다). 잠금 해제가 LIFO 주문에있는 것 같습니다 ...

로드 된 텍스처마다 새로운 Bitmap을 만들고 GC를 발생시키는 것을 제외하면 어떤 아이디어입니까? ... 거의 모든 경우에 텍스처를로드하고 그 사이를 전환하기위한 두 개의 비트 맵을 사용하여 해결할 수 있지만 100 % 올바르지 않습니다. 적절한 스레드 동기화를 사용하여이 문제를 해결하고 싶습니다.

답변

2

그래서 하루가 지나면 나는 이것을 알아 냈습니다. 업로드 방법

public boolean handleMessage(Message msg) { 
    switch(msg.what) { 
     case MESSAGE_FROM_MAIN_THREAD: 
      try { 
       m_Semaphore.acquire(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      loadTextureFromAssets(msg.obj.toString(), msg.arg1); 

      break; 

     case MESSAGE_FROM_GL_THREAD: 
      // not needed for now 
      break; 

    } 

    return true; 
} 

INT를 :

// load the image from assests and then... 
m_GLSurface.queueEvent(new Runnable() { 
     public void run() { 
       gl.glBindTexture(GL10.GL_TEXTURE_2D, m_TexId); 

       gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); 
       gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); 
       gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 
       gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 

       if (gl instanceof GL11) { 
        // GL 1.1 has auto mip-map generation 
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_LINEAR); 
        gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE); 
       } 

       GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, m_TexBitmap, 0); 

       m_Semaphore.release(); 
      } 
    }); 

을 난 세마포어 초기 질감 업로드 1로 설정 LoadTextureFromAssets(...) 전에 획득 GL에 보낸 Runnable 말을 방출 사용 이것은 100 % 올바른 방법입니까?

+1

예외가 발생할 수 있고 사용자 세마포어가 공개되지 않을 수 있기 때문에 100 % 올바르지 않습니다. 따라서 최종 블록에서 호출해야합니다. –

+0

try {...} 코드가 잘못되었습니다. 세마포어를 다시 시도하거나 완전히 중단해야합니다. 하지만 지금은 실제 텍스처로드가 아닌 세마포어 획득 만 중단합니다. –

관련 문제