Jni呼叫PBO提高讀取速度

2021-08-17 04:35:01 字數 3189 閱讀 1154

一、初始化pbo環境

#include #include "gl3stub.h"
注意:
1、 這個標頭檔案裡面只包含了gles3.0獨有的api,所以你如果還用到了gles2.0的api,你需要包含gl2.h,這樣呼叫才不會報錯
2、 在包含gl3stub標頭檔案後還不能使用3.0特性,如果你認真看gl3stub檔案內容你會發現需要手動呼叫gl3stubinit();這個函式後才能真正開始呼叫
因為pbo是3.0才有的特性,所以在上面初始化環境後就可以使用pbo了,首先建立兩個pbo用於交替使用,至於為什麼建立兩個後面會逐步介紹:
void initpbo() 

logd("pbo id :%d,%d", mpboids[0], mpboids[1]);

//繫結到第乙個pbo

glbindbuffer(gl_pixel_pack_buffer, mpboids[0]);

//設定記憶體大小

glbufferdata(gl_pixel_pack_buffer, mpbosize, null, gl_static_read);

//繫結到第而箇pbo

glbindbuffer(gl_pixel_pack_buffer, mpboids[1]);

//設定記憶體大小

glbufferdata(gl_pixel_pack_buffer, mpbosize, null, gl_static_read);

//解除繫結pbo

glbindbuffer(gl_pixel_pack_buffer, 0);

}bool setupegl(int width, int height, int texturesize) ;

const eglint pbuf_attribs = ;

const eglint meglcontextattribs = ;

if ((megldisplay = eglgetdisplay(egl_default_display)) == egl_no_display) else

}if (!eglchooseconfig(megldisplay, attribs, &config, 1, &numconfigs))

if (!(meglcontext = eglcreatecontext(megldisplay, config, 0, meglcontextattribs)))

if (!(meglsu***ce = eglcreatepbuffersu***ce(megldisplay, config, pbuf_attribs)))

logd("about to make current. display %p su***ce %p meglcontext %p", megldisplay, meglsu***ce,

meglcontext);

if (!eglmakecurrent(megldisplay, meglsu***ce, meglsu***ce, meglcontext))

if (result)

return result;

}uint8_t *readdatafromgpu(int width, int height)

glbindbuffer(gl_pixel_pack_buffer, mpboids[mpboindex]);

glreadpixels(0, 0, width, height, gl_rgba, gl_unsigned_byte, 0);

if (!minitrecord)

glbindbuffer(gl_pixel_pack_buffer, mpboids[mpbonewindex]);

//glmapbufferrange會等待dma傳輸完成,所以需要交替使用pbo,這邊獲取的是上一幀的內容

uint8_t *bytebuffer = (uint8_t *) glmapbufferrange(gl_pixel_pack_buffer, 0,

mpbosize,

gl_map_read_bit);

if (bytebuffer == null)

glunmapbuffer(gl_pixel_pack_buffer);

unbindpixelbuffer();

return bytebuffer;

} else

}

這邊就有幾點需要說明一下了,

1、 首先是為什麼使用2個pbo,
a)   可以看到第一次呼叫這個函式只呼叫了glreadpixels,然後就返回了,這樣做的目的是通知gpu把資料拷貝到第乙個pbo裡面,而這個拷貝過程是非同步的,所以glreadpixels會立即返回,
b)   第二次呼叫這個函式時之前要gpu拷貝的資料拷貝完了,這時候再讓gpu繼續拷貝資料到第二個pbo中,然後去處理第乙個pbo中已經拷貝完的資料,這樣的話每次就不用等待gpu慢慢拷貝資料,於是時間上面就縮短了將近一半。
c)   然後為什麼是2個不是3個或4個呢,因為你每次處理乙個pbo的時間小於等待gpu拷貝乙個pbo時間的時候就不會出現處理來不及的情況,這樣也就不需要其他pbo存放gpu資料了。
2、 如果是yuv資料的話,glreadpixels大小就得改了,如下:
a)   glreadpixels(0, 0, width, height, gl_rgba, gl_unsigned_byte, 0);
b)   因為你的渲染指令碼已經將yuv轉成rgba了,所以讀出來的大小就要按rgba的大小,而不是yuv原先的大小
3、 glmapbufferrange的作用就是將pbo的位址對映到cpu來,所以這個位址是可以直接使用的,不用再呼叫memcpy來拷貝一遍,不然反而失去了pbo的優勢
4、 glreadpixels傳入的陣列必須是malloc或者new建立的,不能是直接宣告大小的,比如uint8_t data[size]這種是會出現fault addr錯誤,new 或者malloc才不會報錯

androidstudio呼叫jni實現日誌列印

在對jni進行日誌列印只需要在build.gradle檔案的defaultconfig裡面新增ndk 然後在編寫的c或者c 檔案中新增 include define log tag test define logi android log print android log info,log tag...

androidstudio呼叫jni實現日誌列印

1.在對jni進行日誌列印只需要在build.gradle檔案的defaultconfig裡面新增ndk 2.然後在編寫的c或者c 檔案中新增 include define log tag test define logi android log print android log info,log...

JNI與底層呼叫 2

本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...