Я довольно рано пытаюсь выполнить некоторые задачи манипулирования изображениями на безголовом встроенном устройстве, работающем с графическим процессором Mali 400. Это поддерживает OpenGL ES 2.0 через официальный драйвер, и, возможно, в основном полное полное OpenGL 2.1 через неофициальный драйвер Lima.
) Текстура, запустите программу шейдера, которая превращается в другую текстуру, а затем прочитайте ее для использования с Glreadpixels . Я могу опубликовать более полный код, если он поможет кому-либо, но сейчас я показываю только соответствующие части установки, чтобы избежать беспорядка (я думаю, все довольно стандартные): < /p>
// Setup code:
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, &major, &minor);
const EGLint configAttributes[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_NONE
};
eglChooseConfig(display, configAttributes, &config, 1, &numConfigs)
const EGLint pbufferAttributes[] = {
EGL_WIDTH, 1920,
EGL_HEIGHT, 1200,
EGL_NONE
};
surface = eglCreatePbufferSurface(display, config, pbufferAttributes);
const EGLint contextAttributes[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
eglMakeCurrent(display, surface, surface, context);
... Setup shaders, VBOs, etc ...
// Texture used to load image
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
unsigned char* data = (unsigned char*)malloc(1920 * 1200 * sizeof(unsigned char));
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1920, 1200, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); // Bind to dummy data at first, check if we can remove this
glBindBuffer(GL_ARRAY_BUFFER, VBOVertices);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// Texture used to render into
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1200, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
< /code>
// LATER: In main loop
auto start = std::chrono::steady_clock::now(); // Start timer for image loading
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1920, 1200, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image.img); // Load current image into texture from before
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0);
auto text_loaded = std::chrono::steady_clock::now(); // Texture is loaded, end timer for image loading
glUseProgram(shaderProgram);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glFinish();
auto gl_finished = std::chrono::steady_clock::now(); // All rendering should be done when glFinish returns?
glReadPixels(0, 0, 1920, 1200, GL_RGBA, GL_UNSIGNED_BYTE, preprocessed_img_buf);
auto end = std::chrono::steady_clock::now(); // End timer for readout
// This is needed to get back into MONO8 format
for (int i = 0; i < 1920 * 1200; i++){
processed_img_buf[i] = preprocessed_img_buf[i * 4];
}
// Print frame times
auto text_loaded_time = std::chrono::duration_cast(text_loaded - start).count();
auto frame_render_time = std::chrono::duration_cast(gl_finished - text_loaded).count();
auto frame_readout_time = std::chrono::duration_cast(end - gl_finished).count();
< /code>
Попытка получить свободный эталон с приведенным выше кодом, я вижу время, когда я едва могу поверить: < /p>
Image loading time: 7148 us
Render time: 85720 us
Readout time: 158734 us
Total frame time: 251602 us
Image loading time: 4797 us
Render time: 85841 us
Readout time: 152563 us
Total frame time: 243201 us
Image loading time: 6018 us
Render time: 85757 us
Readout time: 158420 us
Total frame time: 250195 us
Я вступал в это ожидание Glreadpixels будет медленным, но не вдвое больше времени рендеринга/медленнее, чем 10 кадров в секунду (при условии, что я справляюсь довольно в здравом уме). Это заставляет меня думать, что я делаю что -то другое не так, однако все, что я пытался, кажется, так или иначе не поддержано:
Пробовал использовать надлежащую gl_luminance текстуру, в которую можно было разобраться, но я получал ошибки, кажется, что у моего egl нет конфигурации только с одним каналом 8bpp, что я не могу высказывать, как, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это так, я не могу решать, что это так, как это, так, как я не могу решать, что я не могу решать, что я не могу решать. /> Пробовал использование Gl_luminance формат на glreadpixels , только чтобы обнаружить, что она не поддерживается с этой функцией из документов, только GL_RGB , GL_RGBA , GL_ALPHA Говорят, что я не нуждаюсь в чтении. Избыточные данные и вызов glreadpixels с Gl_alpha , но, несмотря на документы, меня встретили недействительную ошибку OP (возможно, я неправильно настроил что -то еще раньше, чтобы это произошло?) make them unsuitable for this (mostly format/use case/lack of support)
Looked into EGL images, but am horribly confused by them and don't want to break the part of my code that seems to be working how I expect, and from what I can tell they are more for inputs anyway, so my thought process is I would rather attack the part taking more than half the time
So my title Вопрос: Есть ли способ, которым я могу сделать это более оптимально в случае описания? Я пришел к этому думать, что это было выполнено, и теперь я сомневаюсь, что этот графический процессор может быть полезен для меня без серьезных инвестиций. Это случай или я в нескольких перечислениях от более разумного времени кадров? экран. Возможно ли это, и поможет ли это, или я переоценил силу Мали 400, и это никогда не было предназначено для управления 1920x1200? /> [*] Будет ли полезным с открытым исходным кодом. Я сделал очень мало на пути к развитию водителя, и ни один из графических процессоров, поэтому я не совсем уверен, насколько это амбициозно, хотя я чувствую, что, честно говоря, будет более комфортно, чем пытаться сделать то, что, по моему мнению, было бы простой задачей в GLES.
Я довольно рано пытаюсь выполнить некоторые задачи манипулирования изображениями на безголовом встроенном устройстве, работающем с графическим процессором Mali 400. Это поддерживает OpenGL ES 2.0 через официальный драйвер, и, возможно, в основном полное полное OpenGL 2.1 через неофициальный драйвер Lima.[code]MONO8[/code]/[code]LUMINANCE[/code]) Текстура, запустите программу шейдера, которая превращается в другую текстуру, а затем прочитайте ее для использования с Glreadpixels . Я могу опубликовать более полный код, если он поможет кому-либо, но сейчас я показываю только соответствующие части установки, чтобы избежать беспорядка (я думаю, все довольно стандартные): < /p> [code]// Setup code: display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, &major, &minor); const EGLint configAttributes[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE }; eglChooseConfig(display, configAttributes, &config, 1, &numConfigs) const EGLint pbufferAttributes[] = { EGL_WIDTH, 1920, EGL_HEIGHT, 1200, EGL_NONE }; surface = eglCreatePbufferSurface(display, config, pbufferAttributes); const EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); eglMakeCurrent(display, surface, surface, context);
... Setup shaders, VBOs, etc ...
// Texture used to load image glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); unsigned char* data = (unsigned char*)malloc(1920 * 1200 * sizeof(unsigned char)); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1920, 1200, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); // Bind to dummy data at first, check if we can remove this glBindBuffer(GL_ARRAY_BUFFER, VBOVertices); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1);
// Texture used to render into GLuint framebuffer; glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1200, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID); < /code> // LATER: In main loop auto start = std::chrono::steady_clock::now(); // Start timer for image loading glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1920, 1200, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image.img); // Load current image into texture from before glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID); glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0); auto text_loaded = std::chrono::steady_clock::now(); // Texture is loaded, end timer for image loading glUseProgram(shaderProgram); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glFinish(); auto gl_finished = std::chrono::steady_clock::now(); // All rendering should be done when glFinish returns? glReadPixels(0, 0, 1920, 1200, GL_RGBA, GL_UNSIGNED_BYTE, preprocessed_img_buf); auto end = std::chrono::steady_clock::now(); // End timer for readout // This is needed to get back into MONO8 format for (int i = 0; i < 1920 * 1200; i++){ processed_img_buf[i] = preprocessed_img_buf[i * 4]; } // Print frame times auto text_loaded_time = std::chrono::duration_cast(text_loaded - start).count(); auto frame_render_time = std::chrono::duration_cast(gl_finished - text_loaded).count(); auto frame_readout_time = std::chrono::duration_cast(end - gl_finished).count(); < /code> Попытка получить свободный эталон с приведенным выше кодом, я вижу время, когда я едва могу поверить: < /p> Image loading time: 7148 us Render time: 85720 us Readout time: 158734 us Total frame time: 251602 us
Image loading time: 4797 us Render time: 85841 us Readout time: 152563 us Total frame time: 243201 us
Image loading time: 6018 us Render time: 85757 us Readout time: 158420 us Total frame time: 250195 us [/code] Я вступал в это ожидание Glreadpixels будет медленным, но не вдвое больше времени рендеринга/медленнее, чем 10 кадров в секунду (при условии, что я справляюсь довольно в здравом уме). Это заставляет меня думать, что я делаю что -то другое не так, однако все, что я пытался, кажется, так или иначе не поддержано: [list] [*] Пробовал использовать надлежащую gl_luminance текстуру, в которую можно было разобраться, но я получал ошибки, кажется, что у моего egl нет конфигурации только с одним каналом 8bpp, что я не могу высказывать, как, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это, так, как, так, как это, так, как это, так, как это, так, как это, так, как это, так, как это так, я не могу решать, что это так, как это, так, как я не могу решать, что я не могу решать, что я не могу решать. /> Пробовал использование Gl_luminance формат на glreadpixels , только чтобы обнаружить, что она не поддерживается с этой функцией из документов, только GL_RGB , GL_RGBA , GL_ALPHA Говорят, что я не нуждаюсь в чтении. Избыточные данные и вызов glreadpixels с Gl_alpha , но, несмотря на документы, меня встретили недействительную ошибку OP (возможно, я неправильно настроил что -то еще раньше, чтобы это произошло?) make them unsuitable for this (mostly format/use case/lack of support) [*]Looked into EGL images, but am horribly confused by them and don't want to break the part of my code that seems to be working how I expect, and from what I can tell they are more for inputs anyway, so my thought process is I would rather attack the part taking more than half the time [/list] So my title Вопрос: Есть ли способ, которым я могу сделать это более оптимально в случае описания? Я пришел к этому думать, что это было выполнено, и теперь я сомневаюсь, что этот графический процессор может быть полезен для меня без серьезных инвестиций. Это случай или я в нескольких перечислениях от более разумного времени кадров? экран. Возможно ли это, и поможет ли это, или я переоценил силу Мали 400, и это никогда не было предназначено для управления 1920x1200? /> [*] Будет ли полезным с открытым исходным кодом. Я сделал очень мало на пути к развитию водителя, и ни один из графических процессоров, поэтому я не совсем уверен, насколько это амбициозно, хотя я чувствую, что, честно говоря, будет более комфортно, чем пытаться сделать то, что, по моему мнению, было бы простой задачей в GLES.