@@ -11,32 +11,34 @@ const char frame_vertex_shader[] =
1111#else
1212 " #version 300 es\n "
1313#endif
14- " in vec4 aPosition;\n "
15- " in vec4 aTexCoord;\n "
14+ " layout(location = 0) in vec4 aPosition;\n "
15+ " layout(location = 1) in vec2 aTexCoord;\n "
1616 " uniform mat4 uTransform;\n "
17- " out vec4 vTexCoord;\n "
17+ " out vec2 vTexCoord;\n "
1818 " void main() {\n "
1919 " gl_Position = uTransform * aPosition;\n "
2020 " vTexCoord = aTexCoord;\n "
2121 " }\n " ;
2222
23- const char frame_fragment_shader[] =
24- #ifdef NANOVG_GL3_IMPLEMENTATION
25- " #version 150 core\n "
26- #else
27- " #version 300 es\n "
28- #endif
29- " precision mediump float;\n "
30- " uniform sampler2D uTexture;\n "
31- " in vec4 vTexCoord;\n "
32- " out vec4 colorOut;\n "
33- " void main() {\n "
34- " colorOut = texture(uTexture, vTexCoord.xy);\n "
35- #ifdef QCOM
36- " vec3 dz = vec3(0.0627f, 0.0627f, 0.0627f);\n "
37- " colorOut.rgb = ((vec3(1.0f, 1.0f, 1.0f) - dz) * colorOut.rgb / vec3(1.0f, 1.0f, 1.0f)) + dz;\n "
38- #endif
39- " }\n " ;
23+ const char yuv_fragment_shader[] = R"(
24+ #version 300 es
25+ precision highp float;
26+ in vec2 vTexCoord;
27+ out vec4 fragColor;
28+ uniform lowp sampler2D texture_y;
29+ uniform lowp sampler2D texture_u;
30+ uniform lowp sampler2D texture_v;
31+ void main() {
32+ float y = texture2D(texture_y, vTexCoord).r;
33+ float u = texture2D(texture_u, vTexCoord).r - 0.5;
34+ float v = texture2D(texture_v, vTexCoord).r - 0.5;
35+ float r = y + 1.402 * v;
36+ float g = y - 0.344 * u - 0.714 * v;
37+ float b = y + 1.772 * u;
38+ fragColor = vec4(r, g, b, 1.0);
39+ }
40+ )" ;
41+
4042
4143const mat4 device_transform = {{
4244 1.0 , 0.0 , 0.0 , 0.0 ,
@@ -107,6 +109,7 @@ CameraViewWidget::~CameraViewWidget() {
107109 glDeleteVertexArrays (1 , &frame_vao);
108110 glDeleteBuffers (1 , &frame_vbo);
109111 glDeleteBuffers (1 , &frame_ibo);
112+ glDeleteBuffers (3 , textures);
110113 }
111114 doneCurrent ();
112115}
@@ -117,14 +120,14 @@ void CameraViewWidget::initializeGL() {
117120 program = new QOpenGLShaderProgram (context ());
118121 bool ret = program->addShaderFromSourceCode (QOpenGLShader::Vertex, frame_vertex_shader);
119122 assert (ret);
120- ret = program->addShaderFromSourceCode (QOpenGLShader::Fragment, frame_fragment_shader );
123+ ret = program->addShaderFromSourceCode (QOpenGLShader::Fragment, yuv_fragment_shader );
121124 assert (ret);
122125
123126 program->link ();
124127 GLint frame_pos_loc = program->attributeLocation (" aPosition" );
125128 GLint frame_texcoord_loc = program->attributeLocation (" aTexCoord" );
126129
127- auto [x1, x2, y1, y2] = stream_type == VISION_STREAM_RGB_FRONT ? std::tuple (0 .f , 1 .f , 1 .f , 0 .f ) : std::tuple (1 .f , 0 .f , 1 .f , 0 .f );
130+ auto [x1, x2, y1, y2] = stream_type == VISION_STREAM_YUV_FRONT ? std::tuple (0 .f , 1 .f , 1 .f , 0 .f ) : std::tuple (1 .f , 0 .f , 1 .f , 0 .f );
128131 const uint8_t frame_indicies[] = {0 , 1 , 2 , 0 , 2 , 3 };
129132 const float frame_coords[4 ][4 ] = {
130133 {-1.0 , -1.0 , x2, y1}, // bl
@@ -139,8 +142,7 @@ void CameraViewWidget::initializeGL() {
139142 glBindBuffer (GL_ARRAY_BUFFER, frame_vbo);
140143 glBufferData (GL_ARRAY_BUFFER, sizeof (frame_coords), frame_coords, GL_STATIC_DRAW);
141144 glEnableVertexAttribArray (frame_pos_loc);
142- glVertexAttribPointer (frame_pos_loc, 2 , GL_FLOAT, GL_FALSE,
143- sizeof (frame_coords[0 ]), (const void *)0 );
145+ glVertexAttribPointer (frame_pos_loc, 2 , GL_FLOAT, GL_FALSE, sizeof (frame_coords[0 ]), (const void *)0 );
144146 glEnableVertexAttribArray (frame_texcoord_loc);
145147 glVertexAttribPointer (frame_texcoord_loc, 2 , GL_FLOAT, GL_FALSE,
146148 sizeof (frame_coords[0 ]), (const void *)(sizeof (float ) * 2 ));
@@ -149,6 +151,11 @@ void CameraViewWidget::initializeGL() {
149151 glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (frame_indicies), frame_indicies, GL_STATIC_DRAW);
150152 glBindBuffer (GL_ARRAY_BUFFER, 0 );
151153 glBindVertexArray (0 );
154+
155+ glUseProgram (program->programId ());
156+ glUniform1i (program->uniformLocation (" texture_y" ), 0 );
157+ glUniform1i (program->uniformLocation (" texture_u" ), 1 );
158+ glUniform1i (program->uniformLocation (" texture_v" ), 2 );
152159}
153160
154161void CameraViewWidget::showEvent (QShowEvent *event) {
@@ -172,12 +179,12 @@ void CameraViewWidget::hideEvent(QHideEvent *event) {
172179
173180void CameraViewWidget::updateFrameMat (int w, int h) {
174181 if (zoomed_view) {
175- if (stream_type == VISION_STREAM_RGB_FRONT ) {
182+ if (stream_type == VISION_STREAM_YUV_FRONT ) {
176183 frame_mat = matmul (device_transform, get_driver_view_transform ());
177184 } else {
178- auto intrinsic_matrix = stream_type == VISION_STREAM_RGB_WIDE ? ecam_intrinsic_matrix : fcam_intrinsic_matrix;
185+ auto intrinsic_matrix = stream_type == VISION_STREAM_YUV_WIDE ? ecam_intrinsic_matrix : fcam_intrinsic_matrix;
179186 float zoom = ZOOM / intrinsic_matrix.v [0 ];
180- if (stream_type == VISION_STREAM_RGB_WIDE ) {
187+ if (stream_type == VISION_STREAM_YUV_WIDE ) {
181188 zoom *= 0.5 ;
182189 }
183190 float zx = zoom * 2 * intrinsic_matrix.v [2 ] / width ();
@@ -205,18 +212,22 @@ void CameraViewWidget::paintGL() {
205212 glClear (GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
206213 return ;
207214 }
208- std::unique_lock lk (texture_lock);
209215
210216 glViewport (0 , 0 , width (), height ());
211-
212217 glBindVertexArray (frame_vao);
213- glActiveTexture (GL_TEXTURE0);
214- glBindTexture (GL_TEXTURE_2D, texture[latest_frame->idx ]->frame_tex );
215218
216219 glUseProgram (program->programId ());
217- glUniform1i (program->uniformLocation (" uTexture" ), 0 );
218- glUniformMatrix4fv (program->uniformLocation (" uTransform" ), 1 , GL_TRUE, frame_mat.v );
220+ uint8_t *address[3 ] = {latest_frame->y , latest_frame->u , latest_frame->v };
221+ for (int i = 0 ; i < 3 ; ++i) {
222+ glActiveTexture (GL_TEXTURE0 + i);
223+ glBindTexture (GL_TEXTURE_2D, textures[i]);
224+ int width = i == 0 ? stream_width : stream_width / 2 ;
225+ int height = i == 0 ? stream_height : stream_height / 2 ;
226+ glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, address[i]);
227+ assert (glGetError () == GL_NO_ERROR);
228+ }
219229
230+ glUniformMatrix4fv (program->uniformLocation (" uTransform" ), 1 , GL_TRUE, frame_mat.v );
220231 assert (glGetError () == GL_NO_ERROR);
221232 glEnableVertexAttribArray (0 );
222233 glDrawElements (GL_TRIANGLES, 6 , GL_UNSIGNED_BYTE, (const void *)0 );
@@ -226,22 +237,24 @@ void CameraViewWidget::paintGL() {
226237
227238void CameraViewWidget::vipcConnected (VisionIpcClient *vipc_client) {
228239 makeCurrent ();
229- for (int i = 0 ; i < vipc_client->num_buffers ; i++) {
230- texture[i].reset (new EGLImageTexture (&vipc_client->buffers [i]));
231-
232- glBindTexture (GL_TEXTURE_2D, texture[i]->frame_tex );
233- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
234- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
235-
236- // BGR
237- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
238- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
239- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
240- assert (glGetError () == GL_NO_ERROR);
241- }
242240 latest_frame = nullptr ;
243241 stream_width = vipc_client->buffers [0 ].width ;
244242 stream_height = vipc_client->buffers [0 ].height ;
243+
244+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1 );
245+ glGenTextures (3 , textures);
246+ for (int i = 0 ; i < 3 ; ++i) {
247+ glBindTexture (GL_TEXTURE_2D, textures[i]);
248+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
249+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
250+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
251+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
252+ int width = i == 0 ? stream_width : stream_width / 2 ;
253+ int height = i == 0 ? stream_height : stream_height / 2 ;
254+ glTexImage2D (GL_TEXTURE_2D, 0 , GL_LUMINANCE, width, height, 0 , GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr );
255+ assert (glGetError () == GL_NO_ERROR);
256+ }
257+
245258 updateFrameMat (width (), height ());
246259}
247260
@@ -254,25 +267,6 @@ void CameraViewWidget::vipcThread() {
254267 VisionStreamType cur_stream_type = stream_type;
255268 std::unique_ptr<VisionIpcClient> vipc_client;
256269
257- std::unique_ptr<QOpenGLContext> ctx;
258- std::unique_ptr<QOffscreenSurface> surface;
259- std::unique_ptr<QOpenGLBuffer> gl_buffer;
260-
261- if (!Hardware::EON ()) {
262- ctx = std::make_unique<QOpenGLContext>();
263- ctx->setFormat (context ()->format ());
264- ctx->setShareContext (context ());
265- ctx->create ();
266- assert (ctx->isValid ());
267-
268- surface = std::make_unique<QOffscreenSurface>();
269- surface->setFormat (ctx->format ());
270- surface->create ();
271- ctx->makeCurrent (surface.get ());
272- assert (QOpenGLContext::currentContext () == ctx.get ());
273- initializeOpenGLFunctions ();
274- }
275-
276270 while (!QThread::currentThread ()->isInterruptionRequested ()) {
277271 if (!vipc_client || cur_stream_type != stream_type) {
278272 cur_stream_type = stream_type;
@@ -285,37 +279,14 @@ void CameraViewWidget::vipcThread() {
285279 continue ;
286280 }
287281
288- if (!Hardware::EON ()) {
289- gl_buffer.reset (new QOpenGLBuffer (QOpenGLBuffer::PixelUnpackBuffer));
290- gl_buffer->create ();
291- gl_buffer->bind ();
292- gl_buffer->setUsagePattern (QOpenGLBuffer::StreamDraw);
293- gl_buffer->allocate (vipc_client->buffers [0 ].len );
294- }
282+
295283
296284 emit vipcThreadConnected (vipc_client.get ());
297285 }
298286
299287 if (VisionBuf *buf = vipc_client->recv (nullptr , 1000 )) {
300- if (!Hardware::EON ()) {
301- std::unique_lock lk (texture_lock);
302-
303- void *texture_buffer = gl_buffer->map (QOpenGLBuffer::WriteOnly);
304- memcpy (texture_buffer, buf->addr , buf->len );
305- gl_buffer->unmap ();
306-
307- // copy pixels from PBO to texture object
308- glBindTexture (GL_TEXTURE_2D, texture[buf->idx ]->frame_tex );
309- glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , buf->width , buf->height , GL_RGB, GL_UNSIGNED_BYTE, 0 );
310- glBindTexture (GL_TEXTURE_2D, 0 );
311- assert (glGetError () == GL_NO_ERROR);
312-
313- emit vipcThreadFrameReceived (buf);
314-
315- glFlush ();
316- } else {
317- emit vipcThreadFrameReceived (buf);
318- }
319- }
288+ emit vipcThreadFrameReceived (buf);
289+ }
290+
320291 }
321292}
0 commit comments