Rev 4485 | Rev 4498 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4464 | Serge | 1 | #include |
2 | #include |
||
3 | #include |
||
4 | #include |
||
5 | |||
6 | #define EGL_EGLEXT_PROTOTYPES |
||
4472 | Serge | 7 | #define GL_GLEXT_PROTOTYPES |
8 | |||
4464 | Serge | 9 | #include "EGL/egl.h" |
10 | #include "EGL/eglext.h" |
||
11 | #include "GL/gl.h" |
||
12 | #include "gbm.h" |
||
4472 | Serge | 13 | #include |
4464 | Serge | 14 | #include |
15 | #include |
||
16 | |||
4473 | Serge | 17 | EGLImageKHR px_create_image(EGLDisplay display, EGLContext context, |
18 | int width, int height, int stride, int name); |
||
4485 | Serge | 19 | GLuint create_framebuffer(int width, int height, GLuint *tex); |
20 | GLint create_shader(GLenum type, const char *source); |
||
4472 | Serge | 21 | |
4464 | Serge | 22 | int main() |
23 | { |
||
24 | struct gbm_device *gbm; |
||
25 | struct gbm_surface *gs; |
||
26 | |||
27 | EGLDisplay dpy; |
||
28 | EGLint major, minor; |
||
29 | |||
30 | EGLContext context; |
||
31 | EGLSurface surface; |
||
4495 | Serge | 32 | EGLImageKHR front,fb_image; |
4464 | Serge | 33 | EGLConfig config; |
34 | |||
35 | EGLint config_attribs[32]; |
||
36 | EGLint num_configs, i; |
||
4495 | Serge | 37 | GLuint texture, buffer; |
4485 | Serge | 38 | GLuint f_tex; |
4464 | Serge | 39 | |
40 | int fd; |
||
41 | |||
42 | fd = get_service("DISPLAY"); |
||
43 | gbm = gbm_create_device(fd); |
||
44 | if( gbm == NULL){ |
||
45 | printf("failed to initialize GBM device"); |
||
46 | return 1; |
||
47 | }; |
||
48 | |||
4472 | Serge | 49 | init_pixlib(HW_BIT_BLIT); |
50 | |||
4464 | Serge | 51 | dpy = eglGetDisplay((EGLNativeDisplayType)gbm); |
52 | |||
53 | if (!eglInitialize(dpy, &major, &minor)) |
||
54 | printf("failed to initialize EGL display"); |
||
55 | |||
56 | printf("EGL_VERSION = %s\n", eglQueryString(dpy, EGL_VERSION)); |
||
57 | printf("EGL_VENDOR = %s\n", eglQueryString(dpy, EGL_VENDOR)); |
||
58 | printf("EGL_EXTENSIONS = %s\n", eglQueryString(dpy, EGL_EXTENSIONS)); |
||
59 | printf("EGL_CLIENT_APIS = %s\n",eglQueryString(dpy, EGL_CLIENT_APIS)); |
||
60 | |||
61 | i = 0; |
||
62 | config_attribs[i++] = EGL_RED_SIZE; |
||
63 | config_attribs[i++] = 1; |
||
64 | config_attribs[i++] = EGL_GREEN_SIZE; |
||
65 | config_attribs[i++] = 1; |
||
66 | config_attribs[i++] = EGL_BLUE_SIZE; |
||
67 | config_attribs[i++] = 1; |
||
68 | config_attribs[i++] = EGL_DEPTH_SIZE; |
||
69 | config_attribs[i++] = 1; |
||
70 | |||
71 | config_attribs[i++] = EGL_SURFACE_TYPE; |
||
72 | config_attribs[i++] = EGL_WINDOW_BIT; |
||
73 | |||
74 | config_attribs[i++] = EGL_RENDERABLE_TYPE; |
||
75 | config_attribs[i++] = EGL_OPENGL_BIT; |
||
76 | config_attribs[i] = EGL_NONE; |
||
77 | |||
78 | if (!eglChooseConfig(dpy,config_attribs, &config, 1, &num_configs) || !num_configs) |
||
79 | printf("failed to choose a config"); |
||
80 | |||
81 | eglBindAPI(EGL_OPENGL_API); |
||
82 | context = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL); |
||
83 | if (!context) |
||
84 | printf("failed to create context"); |
||
85 | |||
4495 | Serge | 86 | gs = gbm_surface_create(gbm, 400, 300, GBM_BO_FORMAT_ARGB8888, GBM_BO_USE_RENDERING); |
4464 | Serge | 87 | |
88 | |||
89 | BeginDraw(); |
||
90 | DrawWindow(20, 20, 400+9, 300+24, "gl-render", 0x000000, 0x74); |
||
91 | EndDraw(); |
||
92 | |||
4472 | Serge | 93 | sna_create_mask(); |
94 | |||
4495 | Serge | 95 | surface = eglCreateWindowSurface(dpy,config, (EGLNativeWindowType)gs, NULL); |
96 | if (surface == EGL_NO_SURFACE) |
||
97 | printf("failed to create surface"); |
||
4464 | Serge | 98 | |
4495 | Serge | 99 | if (!eglMakeCurrent(dpy, surface, surface, context)) |
4464 | Serge | 100 | printf("failed to make window current"); |
101 | |||
4472 | Serge | 102 | |
4495 | Serge | 103 | front = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_BACK); |
104 | glGenTextures(1, &f_tex); |
||
105 | glBindTexture(GL_TEXTURE_2D, f_tex); |
||
106 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); |
||
107 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); |
||
108 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,front); |
||
109 | glBindTexture(GL_TEXTURE_2D, 0); |
||
110 | |||
4485 | Serge | 111 | glMatrixMode(GL_PROJECTION); |
112 | glLoadIdentity(); |
||
113 | glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); |
||
114 | glMatrixMode(GL_MODELVIEW); |
||
115 | glLoadIdentity(); |
||
116 | |||
117 | glViewport(0, 0, 400, 300); |
||
118 | |||
119 | glClearColor( 0, 0, 0, 1); |
||
120 | |||
121 | glClear(GL_COLOR_BUFFER_BIT); |
||
122 | |||
123 | glBegin(GL_QUADS); |
||
124 | glColor3f(1,0,0); |
||
125 | glVertex3f( 0.9, -0.9, -30.0); |
||
126 | glColor3f(1,1,0); |
||
127 | glVertex3f( 0.9, 0.9, -30.0); |
||
128 | |||
129 | glColor3f(1,1,1); |
||
130 | glVertex3f( 0.1, 0.9, -30.0); |
||
131 | glColor3f(1,0,1); |
||
132 | glVertex3f( 0.1, -0.9, -30.0); |
||
133 | glEnd(); |
||
134 | |||
135 | glFlush(); |
||
136 | |||
137 | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
||
138 | |||
4472 | Serge | 139 | if(fd) |
140 | { |
||
141 | int ret; |
||
4473 | Serge | 142 | GLenum status; |
4472 | Serge | 143 | struct drm_i915_fb_info fb; |
144 | |||
145 | memset(&fb, 0, sizeof(fb)); |
||
146 | ret = drmIoctl(fd, SRV_FBINFO, &fb); |
||
147 | if( ret != 0 ) |
||
148 | printf("failed to get framebuffer info\n"); |
||
149 | |||
4473 | Serge | 150 | fb_image = px_create_image(dpy,context,fb.width,fb.height, |
151 | fb.pitch,fb.name); |
||
4472 | Serge | 152 | |
4473 | Serge | 153 | printf("fb_image %p\n", fb_image); |
154 | |||
155 | glGenTextures(1, &texture); |
||
156 | glBindTexture(GL_TEXTURE_2D, texture); |
||
4472 | Serge | 157 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); |
158 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); |
||
159 | |||
160 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,fb_image); |
||
161 | glBindTexture(GL_TEXTURE_2D, 0); |
||
162 | |||
4473 | Serge | 163 | glGenFramebuffers(1, &buffer); |
164 | glBindFramebuffer(GL_FRAMEBUFFER, buffer); |
||
165 | glFramebufferTexture2D(GL_FRAMEBUFFER, |
||
166 | GL_COLOR_ATTACHMENT0, |
||
167 | GL_TEXTURE_2D, texture,0); |
||
168 | status = glCheckFramebufferStatus(GL_FRAMEBUFFER); |
||
169 | if (status != GL_FRAMEBUFFER_COMPLETE) |
||
170 | { |
||
171 | const char *str; |
||
172 | switch (status) |
||
173 | { |
||
174 | case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: |
||
175 | str = "incomplete attachment"; |
||
176 | break; |
||
177 | case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: |
||
178 | str = "incomplete/missing attachment"; |
||
179 | break; |
||
180 | case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: |
||
181 | str = "incomplete draw buffer"; |
||
182 | break; |
||
183 | case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: |
||
184 | str = "incomplete read buffer"; |
||
185 | break; |
||
186 | case GL_FRAMEBUFFER_UNSUPPORTED: |
||
187 | str = "unsupported"; |
||
188 | break; |
||
189 | case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: |
||
190 | str = "incomplete multiple"; |
||
191 | break; |
||
192 | default: |
||
193 | str = "unknown error"; |
||
194 | break; |
||
195 | } |
||
196 | |||
197 | printf("destination is framebuffer incomplete: %s [%#x]\n", |
||
198 | str, status); |
||
199 | } |
||
4472 | Serge | 200 | } |
201 | |||
4485 | Serge | 202 | glViewport(0, 0, 1024, 768); |
203 | glMatrixMode(GL_PROJECTION); |
||
204 | glLoadIdentity(); |
||
205 | glMatrixMode(GL_MODELVIEW); |
||
206 | glLoadIdentity(); |
||
4464 | Serge | 207 | |
208 | |||
4485 | Serge | 209 | const char *vs_src = |
210 | "attribute vec4 v_position;\n" |
||
211 | "attribute vec4 v_texcoord0;\n" |
||
212 | "varying vec2 source_texture;\n" |
||
213 | "void main()\n" |
||
214 | "{\n" |
||
215 | " gl_Position = v_position;\n" |
||
216 | " source_texture = v_texcoord0.xy;\n" |
||
217 | "}\n"; |
||
4464 | Serge | 218 | |
4485 | Serge | 219 | const char *fs_src = |
220 | // "precision mediump float;\n" |
||
221 | "varying vec2 source_texture;\n" |
||
222 | "uniform sampler2D sampler;\n" |
||
223 | "void main()\n" |
||
224 | "{\n" |
||
225 | " vec3 cg = texture2D(sampler, source_texture).rgb;\n" |
||
226 | " gl_FragColor = vec4(cg.r,cg.g,cg.b,1.0);\n" |
||
227 | "}\n"; |
||
4464 | Serge | 228 | |
4485 | Serge | 229 | GLuint blit_prog; |
230 | GLint vs_shader, fs_shader; |
||
4464 | Serge | 231 | |
4472 | Serge | 232 | asm volatile ("int3"); |
233 | |||
4485 | Serge | 234 | blit_prog = glCreateProgram(); |
235 | vs_shader = create_shader(GL_VERTEX_SHADER,vs_src); |
||
236 | fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_src); |
||
237 | glAttachShader(blit_prog, vs_shader); |
||
238 | glAttachShader(blit_prog, fs_shader); |
||
239 | glBindAttribLocation(blit_prog, 0, "v_position"); |
||
240 | glBindAttribLocation(blit_prog, 1, "v_texcoord0"); |
||
4464 | Serge | 241 | |
4485 | Serge | 242 | GLint ok; |
4464 | Serge | 243 | |
4485 | Serge | 244 | glLinkProgram(blit_prog); |
245 | glGetProgramiv(blit_prog, GL_LINK_STATUS, &ok); |
||
246 | if (!ok) { |
||
247 | GLchar *info; |
||
248 | GLint size; |
||
4464 | Serge | 249 | |
4485 | Serge | 250 | glGetProgramiv(blit_prog, GL_INFO_LOG_LENGTH, &size); |
251 | info = malloc(size); |
||
4464 | Serge | 252 | |
4485 | Serge | 253 | glGetProgramInfoLog(blit_prog, size, NULL, info); |
254 | printf("Failed to link: %s\n", info); |
||
255 | printf("GLSL link failure\n"); |
||
256 | } |
||
4464 | Serge | 257 | |
4485 | Serge | 258 | GLint sampler; |
259 | float vertices[8], texcoords[8]; |
||
260 | GLfloat dst_xscale, dst_yscale; //, src_xscale, src_yscale; |
||
261 | int l, t, r, b, stride; |
||
4464 | Serge | 262 | |
4485 | Serge | 263 | sampler = glGetUniformLocation(blit_prog,"sampler"); |
264 | glUseProgram(blit_prog); |
||
265 | glUniform1i(sampler, 0); |
||
4464 | Serge | 266 | |
4485 | Serge | 267 | glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),vertices); |
268 | glEnableVertexAttribArray(0); |
||
269 | |||
270 | glActiveTexture(GL_TEXTURE0); |
||
271 | glBindTexture(GL_TEXTURE_2D, f_tex); |
||
272 | glTexParameteri(GL_TEXTURE_2D, |
||
273 | GL_TEXTURE_MIN_FILTER, |
||
274 | GL_NEAREST); |
||
275 | glTexParameteri(GL_TEXTURE_2D, |
||
276 | GL_TEXTURE_MAG_FILTER, |
||
277 | GL_NEAREST); |
||
278 | |||
279 | glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),texcoords); |
||
280 | glEnableVertexAttribArray(1); |
||
281 | |||
282 | dst_xscale = 1.0/1024; |
||
283 | dst_yscale = 1.0/768; |
||
284 | // src_xscale = 1.0/400; |
||
285 | // src_yscale = 1.0/300; |
||
286 | |||
287 | stride = 2; |
||
288 | |||
289 | l = 20; |
||
290 | t = 20; |
||
291 | r = l+400; |
||
292 | b = t+300; |
||
293 | |||
294 | float t0, t1, t2, t5; |
||
295 | |||
296 | vertices[0] = t0 = 2*l*dst_xscale - 1.0; |
||
297 | vertices[1 * 2] = t2 = 2*r*dst_xscale - 1.0; |
||
298 | |||
299 | vertices[2 * 2] = t2; |
||
300 | vertices[3 * 2] = t0; |
||
301 | |||
302 | vertices[1] = t1 = 2*t*dst_yscale - 1.0; |
||
303 | vertices[2*2+1] = t5 = 2*b*dst_yscale - 1.0; |
||
304 | vertices[1*2+1] = t1; |
||
305 | vertices[3*2+1] = t5; |
||
306 | |||
307 | texcoords[0] = 0.0; |
||
308 | texcoords[1] = 0.0; |
||
309 | texcoords[1*2] = 1.0; |
||
310 | texcoords[1*2+1]= 0.0; |
||
311 | texcoords[2*2] = 1.0; |
||
312 | texcoords[2*2+1]= 1.0; |
||
313 | texcoords[3*2] = 0.0; |
||
314 | texcoords[3*2+1]= 1.0; |
||
315 | |||
316 | glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
||
317 | |||
318 | glDisableVertexAttribArray(0); |
||
319 | glDisableVertexAttribArray(1); |
||
320 | glDisable(GL_TEXTURE_2D); |
||
321 | glUseProgram(0); |
||
322 | |||
4464 | Serge | 323 | glFinish(); |
324 | eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
||
4473 | Serge | 325 | // eglDestroySurface(dpy, surface); |
326 | // gbm_surface_destroy(gs); |
||
4464 | Serge | 327 | eglDestroyContext(dpy, context); |
328 | eglTerminate(dpy); |
||
329 | |||
330 | while(1) |
||
331 | { |
||
332 | delay(1); |
||
333 | } |
||
4472 | Serge | 334 | |
4464 | Serge | 335 | return 0; |
336 | } |
||
4472 | Serge | 337 | |
338 | int drmIoctl(int fd, unsigned long request, void *arg) |
||
339 | { |
||
340 | ioctl_t io; |
||
341 | |||
342 | io.handle = fd; |
||
343 | io.io_code = request; |
||
344 | io.input = arg; |
||
345 | io.inp_size = 64; |
||
346 | io.output = NULL; |
||
347 | io.out_size = 0; |
||
348 | |||
349 | return call_service(&io); |
||
350 | } |
||
351 | |||
4473 | Serge | 352 | EGLImageKHR px_create_image(EGLDisplay display, EGLContext context, |
353 | int width, int height, int stride, int name) |
||
4472 | Serge | 354 | { |
355 | EGLImageKHR image; |
||
356 | EGLint attribs[] = { |
||
357 | EGL_WIDTH, 0, |
||
358 | EGL_HEIGHT, 0, |
||
359 | EGL_DRM_BUFFER_STRIDE_MESA, 0, |
||
360 | EGL_DRM_BUFFER_FORMAT_MESA, |
||
361 | EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, |
||
362 | EGL_DRM_BUFFER_USE_MESA, |
||
363 | EGL_DRM_BUFFER_USE_SHARE_MESA | |
||
364 | EGL_DRM_BUFFER_USE_SCANOUT_MESA, |
||
365 | EGL_NONE |
||
366 | }; |
||
367 | attribs[1] = width; |
||
368 | attribs[3] = height; |
||
4485 | Serge | 369 | attribs[5] = stride/4; |
4473 | Serge | 370 | |
371 | printf("%s w:%d :%d pitch:%d handle %d\n", __FUNCTION__, |
||
372 | width, height, stride, name); |
||
373 | |||
4472 | Serge | 374 | image = eglCreateImageKHR(display, context, EGL_DRM_BUFFER_MESA, |
375 | (void *) (uintptr_t)name, attribs); |
||
376 | |||
377 | return image; |
||
378 | } |
||
4485 | Serge | 379 | |
380 | GLint create_shader(GLenum type, const char *source) |
||
381 | { |
||
382 | GLint ok; |
||
383 | GLint prog; |
||
384 | |||
385 | prog = glCreateShader(type); |
||
386 | glShaderSource(prog, 1, (const GLchar **) &source, NULL); |
||
387 | glCompileShader(prog); |
||
388 | glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); |
||
389 | if (!ok) { |
||
390 | GLchar *info; |
||
391 | GLint size; |
||
392 | |||
393 | glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); |
||
394 | info = malloc(size); |
||
395 | |||
396 | glGetShaderInfoLog(prog, size, NULL, info); |
||
397 | printf("Failed to compile %s: %s\n", |
||
398 | type == GL_FRAGMENT_SHADER ? "FS" : "VS",info); |
||
399 | printf("Program source:\n%s", source); |
||
400 | printf("GLSL compile failure\n"); |
||
401 | } |
||
402 | |||
403 | return prog; |
||
404 | } |
||
405 | |||
406 | GLuint create_framebuffer(int width, int height, GLuint *tex) |
||
407 | { |
||
408 | GLuint buffer; |
||
409 | |||
410 | glGenTextures(1, tex); |
||
411 | glBindTexture(GL_TEXTURE_2D, *tex); |
||
412 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); |
||
413 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); |
||
414 | |||
415 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, |
||
416 | GL_UNSIGNED_BYTE, NULL); |
||
417 | glBindTexture(GL_TEXTURE_2D, 0); |
||
418 | |||
419 | glGenFramebuffers(1, &buffer); |
||
420 | glBindFramebuffer(GL_FRAMEBUFFER, buffer); |
||
421 | glFramebufferTexture2D(GL_FRAMEBUFFER, |
||
422 | GL_COLOR_ATTACHMENT0, |
||
423 | GL_TEXTURE_2D, *tex,0); |
||
424 | return buffer; |
||
425 | } |