Почему openGL блокирует пользовательский интерфейс? - PullRequest
0 голосов
/ 12 февраля 2019

Обновление # 1 Я реализовал очередь PBO, которые я перебираю, чтобы попытаться помочь уменьшить задержку пользовательского интерфейса.По сути, я привязываюсь к PBO, вызываю glReadPixels, настраиваю объект забора и жду, пока этот объект будет сигнализирован.

Все время я загружаю больше пикселей в другие PBO через glReadPixels,Как только объект синхронизации становится сигнальным, я пытаюсь glMapBufferRange на сигнализированном PBO.Однако это все еще блокирует пользовательский интерфейс.

Есть ли способ заставить эти вызовы выполняться на отдельном рендерере?


Я пишу приложение для отключения экранных данныхтелефона и превратить серию изображений в видео.Моя проблема в том, что независимо от того, что я делаю, вызовы openGL блокируют поток пользовательского интерфейса.

Ниже я разместил код, который я использую для чтения пикселей с экрана, а затем отобразил их обратно вByteBuffer, которым я могу манипулировать позже.

Мое приложение использует GLSurface, в который я ставлю события в очередь, однако очередь событий на этот переданный GLSurface блокирует пользовательский интерфейс.

Я попытался создать новое представление GLSurface со следующим:GLSurfaceView mGLSurfaceView = new GLSurfaceView(mContext); Однако все события, вызываемые через queueevent, никогда не обрабатываются.Почему это?

private void screenScrape() {

    sync = 0;

    //read pixels from frame buffer into PBO (GL_PIXEL_PACK_BUFFER)
    mGLSurfaceView.queueEvent(new Runnable() {
        @Override
        public void run() {

            //generate and bind buffer ID
            GLES30.glGenBuffers(1, pboIds);
            checkGlError("Gen Buffers");

            GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, pboIds.get(0));
            checkGlError("Bind Buffers");

            //creates and initializes data store for PBO.  Any pre-existing data store is deleted
            GLES30.glBufferData(GLES30.GL_PIXEL_PACK_BUFFER, (mWidth * mHeight * 4), null, GLES30.GL_STATIC_READ);
            checkGlError("Buffer Data");

            glReadPixelsPBO(0, 0, mWidth, mHeight, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, 0);
            checkGlError("Read Pixels");
            long afterTime = System.currentTimeMillis() - startTime;

            sync = GLES30.glFenceSync(GLES30.GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        }
    });

    //map PBO data into client address space
    mGLSurfaceView.queueEvent(new Runnable() {
        @Override
        public void run() {

            int result = GLES30.glClientWaitSync(sync, GLES30.GL_SYNC_FLUSH_COMMANDS_BIT, 15000000);
            Log.d(TAG, "GL Client Wait Sync Result = " + result);

            //read pixels from PBO into a byte buffer for processing.  Unmap buffer for use in next pass
            mapBuffer = ((ByteBuffer) GLES30.glMapBufferRange(GLES30.GL_PIXEL_PACK_BUFFER, 0, 4 * mWidth * mHeight, GLES30.GL_MAP_READ_BIT)).order(ByteOrder.nativeOrder());
            checkGlError("Map Buffer");

            GLES30.glUnmapBuffer(GLES30.GL_PIXEL_PACK_BUFFER);
            checkGlError("Unmap Buffer");



            flipBuffer(mapBuffer);
            mapBuffer.clear();
        }
    });
}

1 Ответ

0 голосов
/ 12 февраля 2019

Возможно, вас смущает то, что glReadPixels PBO предназначен для асинхронного вызова, но во всех этих случаях он фактически блокирует поток рендеринга на длительное время.Вот почему у вас есть эти проблемы.

В любом случае, вместо glReadPixelsPBO -> glReadPixelsFBO

...