Rev 5371 | Rev 6115 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5371 | serge | 1 | #include |
2 | #include |
||
3 | #include |
||
4 | #include |
||
5 | #include |
||
6 | #include "pixlib3.h" |
||
7 | #include "pixdriver.h" |
||
8 | #include "pxgl.h" |
||
9 | |||
10 | #define WIN_STATE_MINIMIZED 0x02 |
||
11 | #define WIN_STATE_ROLLED 0x04 |
||
12 | |||
13 | static int drm_ioctl(int fd, unsigned long request, void *arg) |
||
14 | { |
||
15 | ioctl_t io; |
||
16 | |||
17 | io.handle = fd; |
||
18 | io.io_code = request; |
||
19 | io.input = arg; |
||
20 | io.inp_size = 64; |
||
21 | io.output = NULL; |
||
22 | io.out_size = 0; |
||
23 | |||
24 | return call_service(&io); |
||
25 | } |
||
26 | |||
27 | static EGLImageKHR px_create_image(struct render *px,void *name,GLuint tex, EGLint *attribs) |
||
28 | { |
||
29 | EGLImageKHR image; |
||
30 | |||
31 | image = eglCreateImageKHR(px->dpy, px->context, |
||
32 | EGL_DRM_BUFFER_MESA, name, attribs); |
||
33 | if(image == NULL) |
||
34 | goto err_0; |
||
35 | |||
36 | glBindTexture(GL_TEXTURE_2D, tex); |
||
37 | if(glGetError() != GL_NO_ERROR) |
||
38 | goto err_1; |
||
39 | |||
40 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); |
||
41 | if(glGetError() != GL_NO_ERROR) |
||
42 | goto err_1; |
||
43 | |||
5602 | serge | 44 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); |
45 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); |
||
5371 | serge | 46 | |
47 | return image; |
||
48 | |||
49 | err_1: |
||
50 | eglDestroyImageKHR(px->dpy, image); |
||
51 | err_0: |
||
52 | return NULL; |
||
53 | }; |
||
54 | |||
55 | static int update_fb(struct render *px, int name, int pitch) |
||
56 | { |
||
57 | GLenum status; |
||
58 | EGLImageKHR screen; |
||
59 | |||
60 | EGLint attribs[] = { |
||
61 | EGL_WIDTH, px->scr_width, |
||
62 | EGL_HEIGHT, px->scr_height, |
||
63 | EGL_DRM_BUFFER_STRIDE_MESA, pitch/4, |
||
64 | EGL_DRM_BUFFER_FORMAT_MESA, |
||
65 | EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, |
||
66 | EGL_DRM_BUFFER_USE_MESA, |
||
67 | EGL_DRM_BUFFER_USE_SHARE_MESA | |
||
68 | EGL_DRM_BUFFER_USE_SCANOUT_MESA, |
||
69 | EGL_NONE |
||
70 | }; |
||
71 | char *errmsg; |
||
72 | |||
73 | px->screen = px_create_image(px,(void*)name, px->texture[TEX_SCREEN], attribs); |
||
74 | errmsg = "failed to create new screen image\n"; |
||
75 | if(px->screen == EGL_NO_IMAGE_KHR) |
||
76 | goto err_0; |
||
77 | |||
78 | px->screen = screen; |
||
79 | |||
80 | glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0, |
||
81 | GL_TEXTURE_2D, px->texture[TEX_SCREEN],0); |
||
82 | |||
83 | status = glCheckFramebufferStatus(GL_FRAMEBUFFER); |
||
84 | if (status != GL_FRAMEBUFFER_COMPLETE) |
||
85 | { |
||
86 | const char *str; |
||
87 | switch (status) |
||
88 | { |
||
89 | case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: |
||
90 | str = "incomplete attachment"; |
||
91 | break; |
||
92 | case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: |
||
93 | str = "incomplete/missing attachment"; |
||
94 | break; |
||
95 | case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: |
||
96 | str = "incomplete draw buffer"; |
||
97 | break; |
||
98 | case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: |
||
99 | str = "incomplete read buffer"; |
||
100 | break; |
||
101 | case GL_FRAMEBUFFER_UNSUPPORTED: |
||
102 | str = "unsupported"; |
||
103 | break; |
||
104 | case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: |
||
105 | str = "incomplete multiple"; |
||
106 | break; |
||
107 | default: |
||
108 | str = "unknown error"; |
||
109 | break; |
||
110 | } |
||
111 | DBG("destination framebuffer incomplete: %s [%#x]\n", str, status); |
||
112 | |||
113 | return -1; |
||
114 | }; |
||
115 | |||
116 | DBG("framebuffer changed successfull\n"); |
||
117 | |||
118 | glViewport(0, 0, px->scr_width, px->scr_height); |
||
119 | |||
120 | return 0; |
||
121 | |||
122 | err_0: |
||
123 | DBG("%s %s\n", __FUNCTION__, errmsg); |
||
124 | |||
125 | return -1; |
||
126 | }; |
||
127 | |||
128 | static GLint create_shader(GLenum type, const char *source) |
||
129 | { |
||
130 | GLint ok; |
||
131 | GLint shader; |
||
132 | |||
133 | shader = glCreateShader(type); |
||
134 | if(shader == 0) |
||
135 | goto err; |
||
136 | |||
137 | glShaderSource(shader, 1, (const GLchar **) &source, NULL); |
||
138 | glCompileShader(shader); |
||
139 | glGetShaderiv(shader, GL_COMPILE_STATUS, &ok); |
||
140 | if (!ok) { |
||
141 | GLchar *info; |
||
142 | GLint size; |
||
143 | |||
144 | glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size); |
||
145 | info = malloc(size); |
||
146 | |||
147 | glGetShaderInfoLog(shader, size, NULL, info); |
||
148 | DBG("Failed to compile %s: %s\n", |
||
149 | type == GL_FRAGMENT_SHADER ? "FS" : "VS",info); |
||
150 | DBG("Program source:\n%s", source); |
||
151 | DBG("GLSL compile failure\n"); |
||
152 | free(info); |
||
153 | glDeleteShader(shader); |
||
154 | shader = 0; |
||
155 | }; |
||
156 | |||
157 | DBG("create shader %d\n", shader); |
||
158 | err: |
||
159 | return shader; |
||
160 | } |
||
161 | |||
162 | |||
163 | static void *px_create_obj(struct render *px, size_t size, |
||
164 | GLuint *handle, GLuint *name) |
||
165 | { |
||
166 | struct drm_i915_gem_create create; |
||
167 | struct drm_i915_gem_mmap mmap_arg; |
||
168 | struct drm_gem_close close; |
||
169 | struct drm_gem_flink flink; |
||
170 | |||
171 | create.size = size; |
||
172 | create.handle = 0; |
||
173 | |||
174 | if(drm_ioctl(px->fd, DRM_IOCTL_I915_GEM_CREATE, &create)) |
||
175 | goto err_0; |
||
176 | |||
177 | *handle = create.handle; |
||
178 | flink.handle = create.handle; |
||
179 | if (drm_ioctl(px->fd, DRM_IOCTL_GEM_FLINK, &flink)) |
||
180 | goto err_1; |
||
181 | |||
182 | *name = flink.name; |
||
183 | |||
184 | mmap_arg.handle = *handle; |
||
185 | mmap_arg.offset = 0; |
||
186 | mmap_arg.size = size; |
||
187 | if (drm_ioctl(px->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) |
||
188 | { |
||
189 | DBG("%s: failed to mmap bitmap handle=%d, %d bytes, into CPU domain\n", |
||
190 | __FUNCTION__, *handle, size); |
||
191 | goto err_1; |
||
192 | }; |
||
193 | |||
194 | return (void*)(uintptr_t)mmap_arg.addr_ptr; |
||
195 | |||
196 | err_1: |
||
197 | close.handle = *handle; |
||
198 | drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close); |
||
199 | err_0: |
||
200 | return NULL; |
||
201 | }; |
||
202 | |||
203 | |||
204 | static int px_create_bitmap(struct render *px, struct bitmap *bitmap, |
||
205 | size_t size, EGLint format) |
||
206 | { |
||
207 | struct drm_gem_close close; |
||
208 | EGLint attribs[] = { |
||
209 | EGL_WIDTH, bitmap->width, |
||
210 | EGL_HEIGHT, bitmap->height, |
||
211 | EGL_DRM_BUFFER_STRIDE_MESA, 0, |
||
212 | EGL_DRM_BUFFER_FORMAT_MESA, |
||
213 | format, |
||
214 | EGL_DRM_BUFFER_USE_MESA, |
||
215 | EGL_DRM_BUFFER_USE_SHARE_MESA, |
||
216 | EGL_NONE |
||
217 | }; |
||
218 | |||
219 | bitmap->buffer = px_create_obj(px, size, &bitmap->handle, &bitmap->name); |
||
220 | if(bitmap->buffer == NULL) |
||
221 | goto err_0; |
||
222 | |||
223 | switch(format) |
||
224 | { |
||
225 | case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: |
||
226 | attribs[5] = bitmap->pitch/4; |
||
227 | break; |
||
228 | case EGL_DRM_BUFFER_FORMAT_R8_MESA: |
||
229 | attribs[5] = bitmap->pitch; |
||
230 | break; |
||
231 | default: |
||
232 | DBG("%s invalid format %x\n", |
||
233 | __FUNCTION__, format); |
||
234 | goto err_1; |
||
235 | } |
||
236 | |||
237 | bitmap->image = px_create_image(px,(void*)bitmap->name, |
||
238 | bitmap->tex, attribs); |
||
239 | if(bitmap->image == NULL) |
||
240 | goto err_1; |
||
241 | |||
242 | DBG("create bitmap:%p %dx%d pitch:%d\n" |
||
243 | "KHRimage:%p gl_tex:%d handle:%d name:%d\n" |
||
244 | "mapped at %x\n", |
||
245 | bitmap, bitmap->width, bitmap->height, bitmap->pitch, |
||
246 | bitmap->image, bitmap->tex, bitmap->handle, bitmap->name, |
||
247 | bitmap->buffer); |
||
248 | |||
249 | return 0; |
||
250 | |||
251 | err_1: |
||
252 | user_free(bitmap->buffer); |
||
253 | close.handle = bitmap->handle; |
||
254 | drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close); |
||
255 | err_0: |
||
256 | return -1; |
||
257 | } |
||
258 | |||
259 | |||
260 | static int create_mask(struct render *px) |
||
261 | { |
||
262 | struct drm_i915_mask_update update; |
||
263 | int pitch; |
||
264 | |||
265 | pitch = (px->width+15) & ~15; |
||
266 | |||
267 | px->mask.width = px->width; |
||
268 | px->mask.height = px->height; |
||
269 | px->mask.pitch = pitch; |
||
270 | px->mask.tex = px->texture[TEX_MASK]; |
||
271 | px->mask_size = pitch * px->height; |
||
272 | |||
273 | if(px_create_bitmap(px, &px->mask, px->mask_size, |
||
274 | EGL_DRM_BUFFER_FORMAT_R8_MESA) == 0) |
||
275 | { |
||
276 | update.handle = px->mask.handle; |
||
277 | update.dx = px->dx; |
||
278 | update.dy = px->dy; |
||
279 | update.width = px->width; |
||
280 | update.height = px->height; |
||
281 | update.bo_pitch = (px->width+15) & ~15; |
||
282 | update.bo_map = (int)px->mask.buffer; |
||
283 | update.forced = 1; |
||
284 | drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update); |
||
285 | return 0; |
||
286 | }; |
||
287 | return -1; |
||
288 | }; |
||
289 | |||
290 | |||
291 | static int update_mask(struct render *px) |
||
292 | { |
||
293 | struct drm_gem_close close; |
||
294 | EGLint attribs[] = { |
||
295 | EGL_WIDTH, 0, |
||
296 | EGL_HEIGHT, 0, |
||
297 | EGL_DRM_BUFFER_STRIDE_MESA, 0, |
||
298 | EGL_DRM_BUFFER_FORMAT_MESA, |
||
299 | EGL_DRM_BUFFER_FORMAT_R8_MESA, |
||
300 | EGL_DRM_BUFFER_USE_MESA, |
||
301 | EGL_DRM_BUFFER_USE_SHARE_MESA, |
||
302 | EGL_NONE |
||
303 | }; |
||
304 | unsigned int size, pitch; |
||
305 | |||
306 | eglDestroyImageKHR(px->dpy, px->mask.image); |
||
307 | |||
308 | pitch = (px->width+15) & ~15; |
||
309 | size = pitch*px->height; |
||
310 | |||
311 | if(size > px->mask_size) |
||
312 | { |
||
313 | user_free(px->mask.buffer); |
||
314 | close.handle = px->mask.handle; |
||
315 | drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close); |
||
316 | |||
317 | px->mask_size = size; |
||
318 | |||
319 | px->mask.buffer = px_create_obj(px, px->mask_size, |
||
320 | &px->mask.handle, &px->mask.name); |
||
321 | if(px->mask.buffer == 0) |
||
322 | goto err_0; |
||
323 | }; |
||
324 | |||
325 | attribs[1] = px->width; |
||
326 | attribs[3] = px->height; |
||
327 | attribs[5] = pitch; |
||
328 | |||
329 | px->mask.image = px_create_image(px,(void*)px->mask.name, |
||
330 | px->mask.tex, attribs); |
||
331 | if(px->mask.image == NULL) |
||
332 | goto err_1; |
||
333 | |||
334 | DBG("create mask w:%d h:%d pitch:%d\n" |
||
335 | "KHRimage:%p gl_tex:%d handle:%d name:%d\n" |
||
336 | "mapped at %x\n", |
||
337 | px->width, px->height, |
||
338 | pitch, px->mask.image, px->texture[TEX_MASK], |
||
339 | px->mask.handle, px->mask.name, px->mask.buffer); |
||
340 | |||
341 | return 0; |
||
342 | |||
343 | err_1: |
||
344 | user_free(px->mask.buffer); |
||
345 | close.handle = px->mask.handle; |
||
346 | drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close); |
||
347 | err_0: |
||
348 | return -1; |
||
349 | }; |
||
350 | |||
351 | static struct render* create_render(EGLDisplay dpy, EGLContext context, int dx, int dy, int w, int h) |
||
352 | { |
||
353 | const char *vs_src = |
||
354 | "attribute vec4 v_position;\n" |
||
355 | "attribute vec4 v_texcoord0;\n" |
||
356 | "varying vec2 source_texture;\n" |
||
357 | "void main()\n" |
||
358 | "{\n" |
||
359 | " gl_Position = v_position;\n" |
||
360 | " source_texture = v_texcoord0.xy;\n" |
||
361 | "}\n"; |
||
362 | |||
363 | const char *fs_i965 = |
||
364 | "varying vec2 source_texture;\n" |
||
365 | "uniform sampler2D sampler_src;\n" |
||
366 | "uniform sampler2D sampler_mask;\n" |
||
367 | "void main()\n" |
||
368 | "{\n" |
||
369 | " float ca = texture2D(sampler_mask, source_texture).r;\n" |
||
370 | " gl_FragColor = vec4(texture2D(sampler_src, source_texture).rgb, ca);\n" |
||
371 | "}\n"; |
||
372 | |||
373 | struct drm_i915_fb_info fb; |
||
374 | struct render *px; |
||
375 | GLint vs_shader, fs_shader; |
||
376 | int ret; |
||
377 | |||
378 | px = (struct render*)malloc(sizeof(struct render)); |
||
379 | if(px == NULL) |
||
380 | goto err_0; |
||
381 | |||
382 | px->fd = get_service("DISPLAY"); |
||
383 | |||
384 | __builtin_memset(&fb, 0, sizeof(fb)); |
||
385 | if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb)) |
||
386 | { DBG("failed to get framebuffer info\n"); |
||
387 | goto err_1; |
||
388 | }; |
||
389 | |||
390 | px->dpy = dpy; |
||
391 | px->context = context; |
||
392 | px->dx = dx; |
||
393 | px->dy = dy; |
||
394 | px->width = w; |
||
395 | px->height = h; |
||
396 | px->scr_width = fb.width; |
||
397 | px->scr_height = fb.height; |
||
398 | |||
399 | glGenTextures(2, px->texture); |
||
400 | if(glGetError() != GL_NO_ERROR) |
||
401 | goto err_1; |
||
402 | |||
403 | glGenFramebuffers(1, &px->framebuffer); |
||
404 | if(glGetError() != GL_NO_ERROR) |
||
405 | goto err_2; |
||
406 | |||
407 | glBindFramebuffer(GL_FRAMEBUFFER, px->framebuffer); |
||
408 | if(glGetError() != GL_NO_ERROR) |
||
409 | goto err_3; |
||
410 | |||
411 | if(update_fb(px, fb.name, fb.pitch)) |
||
412 | goto err_4; |
||
413 | |||
414 | glMatrixMode(GL_PROJECTION); |
||
415 | glLoadIdentity(); |
||
416 | glMatrixMode(GL_MODELVIEW); |
||
417 | glLoadIdentity(); |
||
418 | |||
419 | if(create_mask(px)) |
||
420 | goto err_4; |
||
421 | |||
422 | px->blit_prog = glCreateProgram(); |
||
423 | if(px->blit_prog == 0) |
||
424 | goto err_4; |
||
425 | |||
426 | vs_shader = create_shader(GL_VERTEX_SHADER, vs_src); |
||
427 | if(vs_shader == 0) |
||
428 | goto err_4; |
||
429 | |||
430 | fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_i965); |
||
431 | if(fs_shader == 0) |
||
432 | goto err_4; |
||
433 | |||
434 | glAttachShader(px->blit_prog, vs_shader); |
||
435 | glAttachShader(px->blit_prog, fs_shader); |
||
436 | glBindAttribLocation(px->blit_prog, 0, "v_position"); |
||
437 | glBindAttribLocation(px->blit_prog, 1, "v_texcoord0"); |
||
438 | |||
439 | glLinkProgram(px->blit_prog); |
||
440 | glGetProgramiv(px->blit_prog, GL_LINK_STATUS, &ret); |
||
441 | if (!ret) |
||
442 | { |
||
443 | GLchar *info; |
||
444 | GLint size; |
||
445 | |||
446 | glGetProgramiv(px->blit_prog, GL_INFO_LOG_LENGTH, &size); |
||
447 | info = malloc(size); |
||
448 | |||
449 | glGetProgramInfoLog(px->blit_prog, size, NULL, info); |
||
450 | DBG("Failed to link: %s\n", info); |
||
451 | DBG("GLSL link failure\n"); |
||
452 | free(info); |
||
453 | goto err_4; |
||
454 | } |
||
455 | |||
456 | px->sampler = glGetUniformLocation(px->blit_prog,"sampler_src"); |
||
457 | px->sm_mask = glGetUniformLocation(px->blit_prog,"sampler_mask"); |
||
458 | |||
459 | glUseProgram(px->blit_prog); |
||
460 | glUniform1i(px->sampler, 0); |
||
461 | glUniform1i(px->sm_mask, 1); |
||
462 | |||
463 | glEnableClientState(GL_VERTEX_ARRAY); |
||
464 | |||
465 | glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->vertices); |
||
466 | glEnableVertexAttribArray(0); |
||
467 | |||
468 | glVertexAttribPointer(1, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->tc_src); |
||
469 | glEnableVertexAttribArray(1); |
||
470 | |||
471 | glEnable(GL_BLEND); |
||
472 | glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); |
||
473 | |||
474 | px->tc_src[0] = 0.0; |
||
475 | px->tc_src[1] = 0.0; |
||
476 | px->tc_src[1*2] = 1.0; |
||
477 | px->tc_src[1*2+1]= 0.0; |
||
478 | px->tc_src[2*2] = 1.0; |
||
479 | px->tc_src[2*2+1]= 1.0; |
||
480 | px->tc_src[3*2] = 0.0; |
||
481 | px->tc_src[3*2+1]= 1.0; |
||
482 | |||
483 | DBG("create render framebuffer:%p %dx%d pitch:%d name %d\n", |
||
484 | px->screen,fb.width, fb.height, fb.pitch, fb.name); |
||
485 | |||
486 | return px; |
||
487 | |||
488 | err_4: |
||
489 | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
||
490 | err_3: |
||
491 | glDeleteFramebuffers(1, &px->framebuffer); |
||
492 | err_2: |
||
493 | glDeleteTextures(2, px->texture); |
||
494 | err_1: |
||
495 | free(px); |
||
496 | err_0: |
||
497 | return NULL; |
||
498 | }; |
||
499 | |||
500 | static struct render *px; |
||
501 | |||
502 | static bitmap_t *hw_create_bitmap(uint32_t width, uint32_t height) |
||
503 | { |
||
504 | struct bitmap *bitmap; |
||
505 | |||
506 | bitmap = malloc(sizeof(struct bitmap)); |
||
507 | if(bitmap == NULL) |
||
508 | return NULL; |
||
509 | |||
510 | glGenTextures(1, &bitmap->tex); |
||
511 | if(glGetError() != GL_NO_ERROR) |
||
512 | goto err_0; |
||
513 | |||
514 | bitmap->width = width; |
||
515 | bitmap->height = height; |
||
516 | bitmap->pitch = (width*4 + 15) & ~15; |
||
517 | |||
518 | if(px_create_bitmap(px, bitmap, bitmap->pitch * bitmap->height, |
||
519 | EGL_DRM_BUFFER_FORMAT_ARGB32_MESA) == 0) |
||
520 | { |
||
521 | return bitmap; |
||
522 | }; |
||
523 | |||
524 | glDeleteTextures(1, &bitmap->tex); |
||
525 | err_0: |
||
526 | free(bitmap); |
||
527 | return NULL; |
||
528 | }; |
||
529 | |||
530 | static int hw_destroy_bitmap(bitmap_t * bitmap) |
||
531 | { |
||
532 | struct drm_gem_close close; |
||
533 | |||
534 | glDeleteTextures(1, &bitmap->tex); |
||
535 | eglDestroyImageKHR(px->dpy, bitmap->image); |
||
536 | user_free(bitmap->buffer); |
||
537 | close.handle = bitmap->handle; |
||
538 | drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close); |
||
539 | free(bitmap); |
||
540 | }; |
||
541 | |||
542 | static void *hw_lock_bitmap(bitmap_t *bitmap, uint32_t *pitch) |
||
543 | { |
||
544 | *pitch = bitmap->pitch; |
||
545 | |||
546 | return bitmap->buffer; |
||
547 | }; |
||
548 | |||
549 | static int hw_resize_bitmap(bitmap_t * bitmap, uint32_t width, uint32_t height) |
||
550 | { |
||
551 | return 0; |
||
552 | } |
||
553 | |||
554 | char proc_info[1024]; |
||
555 | |||
556 | static int hw_blit(bitmap_t *bitmap, int dst_x, int dst_y, |
||
557 | uint32_t w, uint32_t h, int src_x, int src_y) |
||
558 | { |
||
559 | struct drm_i915_mask_update update; |
||
560 | struct drm_i915_fb_info fb; |
||
561 | |||
562 | uint32_t winx, winy, winw, winh; |
||
563 | uint8_t state; |
||
564 | float xscale, yscale; |
||
565 | int r, b; |
||
566 | float *vertices = px->vertices; |
||
567 | |||
568 | get_proc_info(proc_info); |
||
569 | |||
570 | state = *(uint8_t*)(proc_info+70); |
||
571 | if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED)) |
||
572 | return; |
||
573 | |||
574 | winx = *(uint32_t*)(proc_info+34); |
||
575 | winy = *(uint32_t*)(proc_info+38); |
||
576 | winw = *(uint32_t*)(proc_info+42)+1; |
||
577 | winh = *(uint32_t*)(proc_info+46)+1; |
||
578 | |||
579 | __builtin_memset(&fb, 0, sizeof(fb)); |
||
580 | if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb)) |
||
581 | { |
||
582 | DBG("failed to get framebuffer info\n"); |
||
583 | return; |
||
584 | }; |
||
585 | |||
586 | if( fb.width != px->scr_width || |
||
587 | fb.height != px->scr_height ) |
||
588 | { |
||
589 | px->scr_width = fb.width; |
||
590 | px->scr_height = fb.height; |
||
591 | |||
592 | eglDestroyImageKHR(px->dpy, px->screen); |
||
593 | |||
594 | if(update_fb(px, fb.name, fb.pitch)) |
||
595 | return; |
||
596 | }; |
||
597 | |||
598 | update.handle = px->mask.handle; |
||
599 | update.dx = px->dx; |
||
600 | update.dy = px->dy; |
||
601 | update.width = px->width; |
||
602 | update.height = px->height; |
||
603 | update.bo_pitch = (px->width+15) & ~15; |
||
604 | update.bo_map = (int)px->mask.buffer; |
||
605 | |||
606 | if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update)) |
||
607 | { |
||
608 | return; |
||
609 | } |
||
610 | |||
611 | xscale = 1.0/px->scr_width; |
||
612 | yscale = 1.0/px->scr_height; |
||
613 | |||
614 | r = winx + px->dx + px->width; |
||
615 | b = winy + px->dy + px->height; |
||
616 | |||
617 | float t0, t1, t2, t5; |
||
618 | |||
619 | // render->tc_src[1*2] = 1.0; |
||
620 | // render->tc_src[2*2] = 1.0; |
||
621 | // render->tc_src[2*2+1]= 1.0; |
||
622 | // render->tc_src[3*2+1]= 1.0; |
||
623 | |||
624 | vertices[0] = t0 = 2*(winx+px->dx)*xscale - 1.0; |
||
625 | vertices[1 * 2] = t2 = 2*r*xscale - 1.0; |
||
626 | |||
627 | vertices[2 * 2] = t2; |
||
628 | vertices[3 * 2] = t0; |
||
629 | |||
630 | vertices[1] = t1 = 2*(winy+px->dy)*yscale - 1.0; |
||
631 | vertices[2*2+1] = t5 = 2*b*yscale - 1.0; |
||
632 | vertices[1*2+1] = t1; |
||
633 | vertices[3*2+1] = t5; |
||
634 | |||
635 | glActiveTexture(GL_TEXTURE0); |
||
636 | glBindTexture(GL_TEXTURE_2D, bitmap->tex); |
||
637 | |||
638 | glActiveTexture(GL_TEXTURE1); |
||
639 | glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]); |
||
640 | |||
641 | glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
||
642 | |||
643 | glFlush(); |
||
644 | |||
645 | return; |
||
646 | }; |
||
647 | |||
648 | static int hw_create_client(int x, int y, uint32_t width, uint32_t height) |
||
649 | { |
||
650 | px = create_render(eglGetCurrentDisplay(), eglGetCurrentContext(), x, y, width, height); |
||
651 | |||
652 | return !px; |
||
653 | }; |
||
654 | |||
655 | static int hw_resize_client(int x, int y, uint32_t width, uint32_t height) |
||
656 | { |
||
657 | if( x != px->dx || |
||
658 | y != px->dy || |
||
659 | width != px->width || |
||
660 | height != px->height ) |
||
661 | { |
||
662 | struct drm_i915_mask_update update; |
||
663 | |||
664 | px->dx = x; |
||
665 | px->dy = y; |
||
666 | px->width = width; |
||
667 | px->height = height; |
||
668 | update_mask(px); |
||
669 | |||
670 | update.handle = px->mask.handle; |
||
671 | update.dx = px->dx; |
||
672 | update.dy = px->dy; |
||
673 | update.width = px->width; |
||
674 | update.height = px->height; |
||
675 | update.bo_pitch = (px->width+15) & ~15; |
||
676 | update.bo_map = (int)px->mask.buffer; |
||
677 | update.forced = 1; |
||
678 | |||
679 | drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update); |
||
680 | }; |
||
681 | |||
682 | return 0; |
||
683 | }; |
||
684 | |||
685 | static void hw_fini(void) |
||
686 | { |
||
687 | struct drm_gem_close close; |
||
688 | |||
689 | DBG("%s\n", __FUNCTION__); |
||
690 | |||
691 | eglDestroyImageKHR(px->dpy, px->mask.image); |
||
692 | user_free(px->mask.buffer); |
||
693 | close.handle = px->mask.handle; |
||
694 | drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close); |
||
695 | |||
696 | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
||
697 | glDeleteFramebuffers(1, &px->framebuffer); |
||
698 | eglDestroyImageKHR(px->dpy, px->screen); |
||
699 | glDeleteTextures(2, px->texture); |
||
700 | egl_destroy(px->dpy, px->context); |
||
701 | free(px); |
||
702 | }; |
||
703 | |||
704 | static struct pix_driver gl_driver = |
||
705 | { |
||
706 | HW_TEX_BLIT, |
||
707 | hw_create_bitmap, |
||
708 | hw_destroy_bitmap, |
||
709 | hw_lock_bitmap, |
||
710 | hw_resize_bitmap, |
||
711 | hw_blit, |
||
712 | hw_create_client, |
||
713 | hw_resize_client, |
||
714 | hw_fini |
||
715 | }; |
||
716 | |||
717 | struct pix_driver *DrvInit(uint32_t service) |
||
718 | { |
||
719 | EGLDisplay dpy; |
||
720 | EGLConfig config; |
||
721 | EGLContext context; |
||
722 | int ret; |
||
723 | |||
724 | ret = egl_initialize(&dpy, &config, &context); |
||
725 | if( ret ) |
||
726 | return NULL; |
||
727 | |||
728 | return &gl_driver; |
||
729 | |||
730 | err_0: |
||
731 | egl_destroy(dpy, context); |
||
732 | return NULL; |
||
733 | } |
||
734 |