一、初始化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頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...