Subversion Repositories Kolibri OS

Rev

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