Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(432)

Side by Side Diff: third_party/libva/test/egl/va_egl_x11.c

Issue 10375035: Add libva to chromium third_party. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <X11/Xlib.h>
6 #include <X11/Xutil.h>
7 #include <X11/keysym.h>
8 #include <GLES/gl.h>
9 #include <GLES/glext.h>
10 #include <EGL/egl.h>
11 #include <EGL/eglext.h>
12 #include <va/va_x11.h>
13 #include <va/va_egl.h>
14
15 struct va_egl_context
16 {
17 Display *x11_dpy;
18 Window win;
19
20 EGLDisplay egl_dpy;
21 EGLContext egl_ctx;
22 EGLSurface egl_surf;
23 unsigned int egl_target;
24 EGLClientBuffer egl_buffer;
25 EGLImageKHR egl_image;
26 PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
27 PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_hkr;
28 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glegl_image_target_texture2d_oes;
29
30 VADisplay va_dpy;
31 VASurfaceID va_surface;
32 VASurfaceEGL va_egl_surface;
33
34 int x, y;
35 unsigned int width, height;
36 GLuint texture;
37 GLfloat ar;
38 unsigned int box_width;
39 unsigned char ydata;
40 };
41
42 static void
43 va_egl_fini_egl(struct va_egl_context *ctx)
44 {
45 eglMakeCurrent(ctx->egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ;
46 eglTerminate(ctx->egl_dpy);
47 }
48
49 static int
50 va_egl_init_egl(struct va_egl_context *ctx)
51 {
52 EGLint egl_major, egl_minor;
53 const char *s;
54
55 ctx->egl_dpy = eglGetDisplay(ctx->x11_dpy);
56
57 if (!ctx->egl_dpy) {
58 printf("Error: eglGetDisplay() failed\n");
59 return -1;
60 }
61
62 if (!eglInitialize(ctx->egl_dpy, &egl_major, &egl_minor)) {
63 printf("Error: eglInitialize() failed\n");
64 return -1;
65 }
66
67 s = eglQueryString(ctx->egl_dpy, EGL_VERSION);
68 printf("EGL_VERSION = %s\n", s);
69
70 return 0;
71 }
72
73 static int
74 yuvgen_planar(int width, int height,
75 unsigned char *Y_start, int Y_pitch,
76 unsigned char *U_start, int U_pitch,
77 unsigned char *V_start, int V_pitch,
78 int UV_interleave, int box_width, unsigned char ydata)
79 {
80 int row;
81
82 /* copy Y plane */
83 for (row = 0; row < height; row++) {
84 unsigned char *Y_row = Y_start + row * Y_pitch;
85 int jj, xpos, ypos;
86
87 ypos = (row / box_width) & 0x1;
88
89 for (jj = 0; jj < width; jj++) {
90 xpos = ((jj) / box_width) & 0x1;
91
92 if ((xpos == 0) && (ypos == 0))
93 Y_row[jj] = ydata;
94 if ((xpos == 1) && (ypos == 1))
95 Y_row[jj] = ydata;
96
97 if ((xpos == 1) && (ypos == 0))
98 Y_row[jj] = 0xff - ydata;
99 if ((xpos == 0) && (ypos == 1))
100 Y_row[jj] = 0xff - ydata;
101 }
102 }
103
104 /* copy UV data */
105 for( row = 0; row < height/2; row++) {
106 unsigned short value = 0x80;
107
108 if (UV_interleave) {
109 unsigned short *UV_row = (unsigned short *)(U_start + row * U_pitch) ;
110
111 memset(UV_row, value, width);
112 } else {
113 unsigned char *U_row = U_start + row * U_pitch;
114 unsigned char *V_row = V_start + row * V_pitch;
115
116 memset(U_row, value, width / 2);
117 memset(V_row, value, width / 2);
118 }
119 }
120
121 return 0;
122 }
123
124 static int
125 va_egl_upload_surface(struct va_egl_context *ctx)
126 {
127 VAImage surface_image;
128 void *surface_p = NULL, *U_start, *V_start;
129
130 vaDeriveImage(ctx->va_dpy, ctx->va_surface, &surface_image);
131
132 vaMapBuffer(ctx->va_dpy, surface_image.buf, &surface_p);
133
134 U_start = (char *)surface_p + surface_image.offsets[1];
135 V_start = (char *)surface_p + surface_image.offsets[2];
136
137 /* assume surface is planar format */
138 yuvgen_planar(surface_image.width, surface_image.height,
139 (unsigned char *)surface_p, surface_image.pitches[0],
140 (unsigned char *)U_start, surface_image.pitches[1],
141 (unsigned char *)V_start, surface_image.pitches[2],
142 (surface_image.format.fourcc==VA_FOURCC_NV12),
143 ctx->box_width, ctx->ydata);
144
145 vaUnmapBuffer(ctx->va_dpy,surface_image.buf);
146
147 vaDestroyImage(ctx->va_dpy,surface_image.image_id);
148
149 return 0;
150 }
151
152 static void
153 va_egl_fini_va(struct va_egl_context *ctx)
154 {
155 vaDestroySurfaces(ctx->va_dpy, &ctx->va_surface, 1);
156 vaTerminate(ctx->va_dpy);
157 }
158
159 static int
160 va_egl_init_va(struct va_egl_context *ctx)
161 {
162 VAStatus va_status;
163 int major_ver, minor_ver;
164
165 ctx->va_dpy = vaGetDisplayEGL(ctx->x11_dpy, ctx->egl_dpy);
166
167 if (!ctx->va_dpy) {
168 printf("Error: vaGetDisplayEGL() failed\n");
169 return -1;
170 }
171
172 va_status = vaInitialize(ctx->va_dpy, &major_ver, &minor_ver);
173
174 if (va_status != VA_STATUS_SUCCESS) {
175 printf("Error: vaInitialize() failed\n");
176 return -1;
177 }
178
179 va_status = vaCreateSurfaces(ctx->va_dpy,
180 ctx->width, ctx->height,
181 VA_RT_FORMAT_YUV420,
182 1, &ctx->va_surface);
183
184 if (va_status != VA_STATUS_SUCCESS) {
185 printf("Error: vaCreateSurfaces() failed\n");
186 return -1;
187 }
188
189 va_egl_upload_surface(ctx);
190
191 return 0;
192 }
193
194 static void
195 va_egl_make_window(struct va_egl_context *ctx, const char *title)
196 {
197 int scrnum;
198 XSetWindowAttributes attr;
199 unsigned long mask;
200 Window root;
201 XVisualInfo *visInfo, visTemplate;
202 int num_visuals;
203 EGLConfig config;
204 EGLint num_configs, vid;
205 const EGLint attribs[] = {
206 EGL_RED_SIZE, 8,
207 EGL_GREEN_SIZE, 8,
208 EGL_BLUE_SIZE, 8,
209 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
210 EGL_NONE
211 };
212
213 scrnum = DefaultScreen(ctx->x11_dpy);
214 root = RootWindow(ctx->x11_dpy, scrnum);
215
216 if (!eglChooseConfig(ctx->egl_dpy, attribs, &config, 1, &num_configs) ||
217 !num_configs) {
218 printf("Error: couldn't get an EGL visual config\n");
219
220 return;
221 }
222
223 if (!eglGetConfigAttrib(ctx->egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
224 printf("Error: eglGetConfigAttrib() failed\n");
225
226 return;
227 }
228
229 /* The X window visual must match the EGL config */
230 visTemplate.visualid = vid;
231 visInfo = XGetVisualInfo(ctx->x11_dpy, VisualIDMask, &visTemplate, &num_visu als);
232
233 if (!visInfo) {
234 printf("Error: couldn't get X visual\n");
235
236 return;
237 }
238
239 /* window attributes */
240 attr.background_pixel = 0;
241 attr.border_pixel = 0;
242 attr.colormap = XCreateColormap(ctx->x11_dpy, root, visInfo->visual, AllocNo ne);
243 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
244 attr.override_redirect = 0;
245 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRe direct;
246
247 ctx->win = XCreateWindow(ctx->x11_dpy,
248 root,
249 ctx->x, ctx->y,
250 ctx->width, ctx->height,
251 0, visInfo->depth, InputOutput,
252 visInfo->visual, mask, &attr);
253
254 /* set hints and properties */
255 {
256 XSizeHints sizehints;
257 sizehints.x = ctx->x;
258 sizehints.y = ctx->y;
259 sizehints.width = ctx->width;
260 sizehints.height = ctx->height;
261 sizehints.flags = USSize | USPosition;
262 XSetNormalHints(ctx->x11_dpy, ctx->win, &sizehints);
263 XSetStandardProperties(ctx->x11_dpy, ctx->win, title, title,
264 None, (char **)NULL, 0, &sizehints);
265 }
266
267 eglBindAPI(EGL_OPENGL_ES_API);
268
269 ctx->egl_ctx = eglCreateContext(ctx->egl_dpy, config, EGL_NO_CONTEXT, NULL);
270
271 if (!ctx->egl_ctx) {
272 printf("Error: eglCreateContext() failed\n");
273
274 return;
275 }
276
277 ctx->egl_surf = eglCreateWindowSurface(ctx->egl_dpy, config, ctx->win, NULL) ;
278 eglMakeCurrent(ctx->egl_dpy, ctx->egl_surf, ctx->egl_surf, ctx->egl_ctx);
279 XFree(visInfo);
280 }
281
282 static int
283 va_egl_init_extension(struct va_egl_context *ctx)
284 {
285 const char *exts;
286
287 exts = eglQueryString(ctx->egl_dpy, EGL_EXTENSIONS);
288 ctx->egl_create_image_khr =
289 (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
290 ctx->egl_destroy_image_hkr =
291 (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
292
293 if (!exts ||
294 !strstr(exts, "EGL_KHR_image_base") ||
295 !ctx->egl_create_image_khr ||
296 !ctx->egl_destroy_image_hkr) {
297 printf("EGL does not support EGL_KHR_image_base\n");
298 return -1;
299 }
300
301 exts = (const char *)glGetString(GL_EXTENSIONS);
302 ctx->glegl_image_target_texture2d_oes =
303 (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetT exture2DOES");
304
305 if (!exts ||
306 !strstr(exts, "GL_OES_EGL_image") ||
307 !ctx->glegl_image_target_texture2d_oes) {
308 printf("OpenGL ES does not support GL_OES_EGL_image\n");
309 return -1;
310 }
311
312 return 0;
313 }
314
315 static void
316 va_egl_fini_gles(struct va_egl_context *ctx)
317 {
318 glDeleteTextures(1, &ctx->texture);
319 }
320
321 static int
322 va_egl_init_gles(struct va_egl_context *ctx)
323 {
324 glClearColor(0.0, 0.0, 0.0, 0.0);
325 glColor4f(1.0, 1.0, 1.0, 1.0);
326
327 glDisable(GL_BLEND);
328 glDisable(GL_DEPTH_TEST);
329
330 glGenTextures(1, &ctx->texture);
331 glBindTexture(GL_TEXTURE_2D, ctx->texture);
332 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
333 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
334 glEnable(GL_TEXTURE_2D);
335
336 return 0;
337 }
338
339 static void
340 va_egl_fini_va_egl(struct va_egl_context *ctx)
341 {
342 if (ctx->egl_image)
343 ctx->egl_destroy_image_hkr(ctx->egl_dpy, ctx->egl_image);
344
345 vaDeassociateSurfaceEGL(ctx->va_dpy, ctx->va_egl_surface);
346 vaDestroySurfaceEGL(ctx->va_dpy, ctx->va_egl_surface);
347 }
348
349 static int
350 va_egl_init_va_egl(struct va_egl_context *ctx)
351 {
352 VAStatus va_status;
353 int num_max_targets = 0, num_targets = 0;
354 int num_max_attributes = 0, num_attribs = 0;
355 unsigned int *target_list = NULL;
356 EGLint *img_attribs = NULL;
357
358 num_targets = num_max_targets = vaMaxNumSurfaceTargetsEGL(ctx->va_dpy);
359
360 if (num_max_targets < 1) {
361 printf("Error: vaMaxNumSurfaceTargetsEGL() returns %d\n", num_max_target s);
362 return -1;
363 }
364
365 num_attribs = num_max_attributes = vaMaxNumSurfaceAttributesEGL(ctx->va_dpy) ;
366
367 if (num_max_attributes < 1) {
368 printf("Error: vaMaxNumSurfaceAttributesEGL() returns %d\n", num_max_att ributes);
369 return -1;
370 }
371
372 target_list = malloc(num_max_targets * sizeof(unsigned int));
373 va_status = vaQuerySurfaceTargetsEGL(ctx->va_dpy,
374 target_list,
375 &num_targets);
376
377 if (va_status != VA_STATUS_SUCCESS || num_targets < 1) {
378 printf("Error: vaQuerySurfaceTargetsEGL() failed\n");
379 return -1;
380 }
381
382 va_status = vaCreateSurfaceEGL(ctx->va_dpy,
383 target_list[0],
384 ctx->width, ctx->height,
385 &ctx->va_egl_surface);
386
387 if (va_status != VA_STATUS_SUCCESS) {
388 printf("Error: vaCreateSurfaceEGL() failed\n");
389 return -1;
390 }
391
392 va_status = vaAssociateSurfaceEGL(ctx->va_dpy,
393 ctx->va_egl_surface,
394 ctx->va_surface,
395 0);
396
397 if (va_status != VA_STATUS_SUCCESS) {
398 printf("Error: vaAssociateSurfaceEGL() failed\n");
399 return -1;
400 }
401
402 img_attribs = malloc(2 * num_max_attributes * sizeof(EGLint));
403 va_status = vaGetSurfaceInfoEGL(ctx->va_dpy,
404 ctx->va_egl_surface,
405 &ctx->egl_target,
406 &ctx->egl_buffer,
407 img_attribs,
408 &num_attribs);
409
410 if (va_status != VA_STATUS_SUCCESS) {
411 printf("Error: vaGetSurfaceInfoEGL() failed\n");
412 return -1;
413 }
414
415 ctx->egl_image = ctx->egl_create_image_khr(ctx->egl_dpy,
416 EGL_NO_CONTEXT,
417 ctx->egl_target,
418 ctx->egl_buffer,
419 img_attribs);
420
421 vaSyncSurfaceEGL(ctx->va_dpy, ctx->va_egl_surface);
422 ctx->glegl_image_target_texture2d_oes(GL_TEXTURE_2D,
423 (GLeglImageOES)ctx->egl_image);
424
425 return 0;
426 }
427
428 static void
429 va_egl_fini(struct va_egl_context *ctx)
430 {
431 va_egl_fini_gles(ctx);
432 va_egl_fini_va(ctx);
433 va_egl_fini_egl(ctx);
434 va_egl_fini_gles(ctx);
435 va_egl_fini_va_egl(ctx);
436
437 // XDestroyWindow(ctx->x11_dpy, ctx->win);
438 XCloseDisplay(ctx->x11_dpy);
439 }
440
441 static int
442 va_egl_init(struct va_egl_context *ctx, int argc, char **argv)
443 {
444 memset(ctx, 0, sizeof(*ctx));
445 ctx->x11_dpy = XOpenDisplay(NULL);
446 ctx->width = 320;
447 ctx->height = 320;
448 ctx->ar = 1.0;
449 ctx->box_width = 16;
450 ctx->ydata = 0xff;
451
452 if (!ctx->x11_dpy) {
453 printf("Error: couldn't open display %s\n", getenv("DISPLAY"));
454 return -1;
455 }
456
457 if (va_egl_init_egl(ctx) != 0)
458 return -1;
459
460 if (va_egl_init_va(ctx) != 0)
461 return -1;
462
463 va_egl_make_window(ctx, "VA/EGL");
464 va_egl_init_extension(ctx);
465 va_egl_init_gles(ctx);
466 va_egl_init_va_egl(ctx);
467
468 return 0;
469 }
470
471 static void
472 va_egl_reshape(struct va_egl_context *ctx, int width, int height)
473 {
474 GLfloat ar = (GLfloat) width / (GLfloat) height;
475
476 ctx->width = width;
477 ctx->height = height;
478 ctx->ar = ar;
479
480 glViewport(0, 0, (GLint) width, (GLint) height);
481
482 glMatrixMode(GL_PROJECTION);
483 glLoadIdentity();
484 glOrthof(-ar, ar, -ar, ar, -1.0, 1.0);
485 glMatrixMode(GL_MODELVIEW);
486 glLoadIdentity();
487 }
488
489 static void
490 va_egl_draw(struct va_egl_context *ctx)
491 {
492 const GLfloat verts[][3] = {
493 { -ctx->ar, -ctx->ar, 0 },
494 { ctx->ar, -ctx->ar, 0 },
495 { ctx->ar, ctx->ar, 0 },
496 { -ctx->ar, ctx->ar, 0 }
497 };
498 const GLfloat texs[][2] = {
499 { 0, 0 },
500 { 1, 0 },
501 { 1, 1 },
502 { 0, 1 }
503 };
504
505 glClear(GL_COLOR_BUFFER_BIT);
506
507 glVertexPointer(3, GL_FLOAT, 0, verts);
508 glTexCoordPointer(2, GL_FLOAT, 0, texs);
509
510 glEnableClientState(GL_VERTEX_ARRAY);
511 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
512
513 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
514
515 glDisableClientState(GL_VERTEX_ARRAY);
516 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
517 }
518
519 static void
520 va_egl_event_loop(struct va_egl_context *ctx)
521 {
522 while (1) {
523 int redraw = 0;
524
525 if (XPending(ctx->x11_dpy) > 0) {
526 XEvent event;
527 XNextEvent(ctx->x11_dpy, &event);
528
529 switch (event.type) {
530 case Expose:
531 redraw = 1;
532 break;
533
534 case ConfigureNotify:
535 va_egl_reshape(ctx, event.xconfigure.width, event.xconfigure.hei ght);
536 redraw = 1;
537 break;
538
539 case KeyPress:
540 {
541 char buffer[10];
542 int code;
543 code = XLookupKeysym(&event.xkey, 0);
544
545 if (code == XK_y) {
546 ctx->ydata += 0x10;
547 va_egl_upload_surface(ctx);
548 vaSyncSurfaceEGL(ctx->va_dpy, ctx->va_egl_surface);
549 ctx->glegl_image_target_texture2d_oes(GL_TEXTURE_2D,
550 (GLeglImageOES)ctx->eg l_image);
551 redraw = 1;
552 } else {
553 XLookupString(&event.xkey, buffer, sizeof(buffer),
554 NULL, NULL);
555
556 if (buffer[0] == 27) {
557 /* escape */
558 return;
559 }
560 }
561 }
562
563 break;
564
565 default:
566 ; /*no-op*/
567 }
568 }
569
570 if (redraw) {
571 va_egl_draw(ctx);
572 eglSwapBuffers(ctx->egl_dpy, ctx->egl_surf);
573 }
574 }
575 }
576
577 static void
578 va_egl_run(struct va_egl_context *ctx)
579 {
580 XMapWindow(ctx->x11_dpy, ctx->win);
581 va_egl_reshape(ctx, ctx->width, ctx->height);
582 va_egl_event_loop(ctx);
583 }
584
585 int
586 main(int argc, char *argv[])
587 {
588 struct va_egl_context ctx;
589
590 printf("Usage: press 'y' to change Y plane \n\n");
591
592 if (va_egl_init(&ctx, argc, argv) == 0) {
593 va_egl_run(&ctx);
594 va_egl_fini(&ctx);
595 }
596
597 return 0;
598 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698