diff --git a/glamor/glamor.c b/glamor/glamor.c index 29f827cc4..9b9d82304 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -210,8 +210,10 @@ glamor_block_handler(ScreenPtr screen) glamor_get_screen_private(screen); glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; + glamor_priv->tick++; dispatch->glFlush(); dispatch->glFinish(); + glamor_fbo_expire(glamor_priv); } static void @@ -381,6 +383,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) ps->DestroyPicture = glamor_destroy_picture; glamor_init_composite_shaders(screen); #endif + glamor_init_pixmap_fbo(screen); glamor_init_solid_shader(screen); glamor_init_tile_shader(screen); glamor_init_putimage_shaders(screen); @@ -392,6 +395,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) #else glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP; #endif + glamor_priv->flags = flags; return TRUE; @@ -402,26 +406,54 @@ glamor_init(ScreenPtr screen, unsigned int flags) return FALSE; } +static void +glamor_release_screen_priv(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv; + + glamor_priv = glamor_get_screen_private(screen); +#ifdef RENDER + glamor_fini_composite_shaders(screen); +#endif + glamor_fini_pixmap_fbo(screen); + glamor_fini_solid_shader(screen); + glamor_fini_tile_shader(screen); + glamor_fini_putimage_shaders(screen); + glamor_fini_finish_access_shaders(screen); + glamor_pixmap_fini(screen); + free(glamor_priv); + + dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, + NULL); +} + Bool glamor_close_screen(int idx, ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); + glamor_screen_private *glamor_priv; + int flags; + + glamor_priv = glamor_get_screen_private(screen); + flags = glamor_priv->flags; #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif glamor_glyphs_fini(screen); - screen->CloseScreen = glamor_priv->saved_procs.close_screen; - screen->CreateGC = glamor_priv->saved_procs.create_gc; - screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap; - screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap; - screen->GetSpans = glamor_priv->saved_procs.get_spans; - screen->ChangeWindowAttributes = - glamor_priv->saved_procs.change_window_attributes; - screen->CopyWindow = glamor_priv->saved_procs.copy_window; - screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region; + if (flags & GLAMOR_USE_SCREEN) { + + screen->CloseScreen = glamor_priv->saved_procs.close_screen; + screen->CreateGC = glamor_priv->saved_procs.create_gc; + screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap; + screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap; + screen->GetSpans = glamor_priv->saved_procs.get_spans; + screen->ChangeWindowAttributes = + glamor_priv->saved_procs.change_window_attributes; + screen->CopyWindow = glamor_priv->saved_procs.copy_window; + screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region; + } #ifdef RENDER - if (ps) { + if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) { + ps->Composite = glamor_priv->saved_procs.composite; ps->Trapezoids = glamor_priv->saved_procs.trapezoids; ps->Glyphs = glamor_priv->saved_procs.glyphs; @@ -429,13 +461,15 @@ glamor_close_screen(int idx, ScreenPtr screen) ps->CreatePicture = glamor_priv->saved_procs.create_picture; } #endif - if (glamor_priv->vb) - free(glamor_priv->vb); - free(glamor_priv); - return screen->CloseScreen(idx, screen); + glamor_release_screen_priv(screen); + if (flags & GLAMOR_USE_SCREEN) + return screen->CloseScreen(idx, screen); + else + return TRUE; } + void glamor_fini(ScreenPtr screen) { diff --git a/glamor/glamor.h b/glamor/glamor.h index 51061f31d..fe1570022 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -42,7 +42,7 @@ #endif /* GLAMOR_H */ /* @GLAMOR_INVERTED_Y_AXIS: - * set 1 means the GL env's origin (0,0) is at top-left. + * set 1 means the GL env's origin (0,0) is at top-left. * EGL/DRM platform is an example need to set this bit. * glx platform's origin is at bottom-left thus need to * clear this bit.*/ @@ -54,7 +54,7 @@ * create/destroy pixmap and handle the gc ops. need to * set this bit. Standalone glamor DDX driver need to set * this bit. - * Otherwise, need to clear this bit, as the intel video + * Otherwise, need to clear this bit, as the intel video * driver with glamor enabled. * */ #define GLAMOR_USE_SCREEN 2 @@ -97,12 +97,24 @@ typedef enum glamor_pixmap_type { * * This function initializes necessary internal data structure * for glamor. And before calling into this function, the OpenGL - * environment should be ready. Should be called before any real - * glamor rendering or texture allocation functions. + * environment should be ready. Should be called before any real + * glamor rendering or texture allocation functions. */ extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT void glamor_fini(ScreenPtr screen); +/* This function is used to free the glamor private screen's + * resources. If the DDX driver is not set GLAMOR_USE_SCREEN, + * then, DDX need to call this function at proper stage, if + * it is the xorg DDX driver,then it should be called at free + * screen stage not the close screen stage. The reason is after + * call to this function, the xorg DDX may need to destroy the + * screen pixmap which must be a glamor pixmap and requires + * the internal data structure still exist at that time. + * Otherwise, the glamor internal structure will not be freed.*/ +extern _X_EXPORT Bool glamor_close_screen(int idx, ScreenPtr screen); + + /* Let glamor to know the screen's fbo. The low level * driver should already assign a tex * to this pixmap through the set_pixmap_texture. */ @@ -133,7 +145,7 @@ extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, * @scrn: Current screen info pointer. * @fd: Current drm fd. * - * This function creates and intialize EGL contexts. + * This function creates and intialize EGL contexts. * Should be called from DDX's preInit function. * Return TRUE if success, otherwise return FALSE. * */ @@ -165,7 +177,7 @@ extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen, /* * @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from * a BO handle. - * + * * @pixmap: The pixmap need to be processed. * @handle: The BO's handle attached to this pixmap at DDX layer. * @stride: Stride in bytes for this pixmap. @@ -188,24 +200,24 @@ extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags); extern _X_EXPORT int glamor_create_gc(GCPtr gc); extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable); -/* Glamor rendering/drawing functions with XXX_nf. +/* Glamor rendering/drawing functions with XXX_nf. * nf means no fallback within glamor internal if possible. If glamor * fail to accelerate the operation, glamor will return a false, and the * caller need to implement fallback method. Return a true means the * rendering request get done successfully. */ extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable, GCPtr gc, - int n, DDXPointPtr points, + int n, DDXPointPtr points, int *widths, int sorted); extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable, - GCPtr gc, - int nrect, + GCPtr gc, + int nrect, xRectangle * prect); -extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable, +extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int left_pad, + int w, int h, int left_pad, int image_format, char *bits); extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src, @@ -216,7 +228,7 @@ extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src, int dx, int dy, Bool reverse, - Bool upsidedown, Pixel bitplane, + Bool upsidedown, Pixel bitplane, void *closure); extern _X_EXPORT Bool glamor_composite_nf(CARD8 op, @@ -227,12 +239,12 @@ extern _X_EXPORT Bool glamor_composite_nf(CARD8 op, INT16 y_source, INT16 x_mask, INT16 y_mask, - INT16 x_dest, INT16 y_dest, + INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height); extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op, PicturePtr src, PicturePtr dst, - PictFormatPtr mask_format, + PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps); @@ -241,14 +253,14 @@ extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, - INT16 y_src, int nlist, + INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr * glyphs); extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, - INT16 xSrc, INT16 ySrc, + INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris); @@ -270,7 +282,7 @@ extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, i unsigned int format, unsigned long planeMask, char *d); extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture, - INT16 x_off, + INT16 x_off, INT16 y_off, int ntrap, xTrap * traps); extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index f6f9e832c..395e91276 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -114,9 +114,8 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) void glamor_init_finish_access_shaders(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; const char *vs_source = "attribute vec4 v_position;\n" "attribute vec4 v_texcoord0;\n" @@ -174,25 +173,23 @@ glamor_init_finish_access_shaders(ScreenPtr screen) GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; GLint sampler_uniform_location; + glamor_priv = glamor_get_screen_private(screen); + dispatch = &glamor_priv->dispatch; glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram(); glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram(); - vs_prog = - glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source); - fs_prog = - glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, fs_source); dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); - avs_prog = - glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, + avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source); - set_alpha_prog = - glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, + set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, set_alpha_source); dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); @@ -254,6 +251,20 @@ glamor_init_finish_access_shaders(ScreenPtr screen) } +void +glamor_fini_finish_access_shaders(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = &glamor_priv->dispatch; + dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]); + dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]); +} + + + void glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode) { diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 1b57b46a8..3d581d2eb 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -77,7 +77,6 @@ glamor_identify(int flags) struct glamor_egl_screen_private { EGLDisplay display; EGLContext context; - EGLImageKHR root; EGLint major, minor; CreateScreenResourcesProcPtr CreateScreenResources; @@ -250,10 +249,6 @@ glamor_egl_close_screen(ScreenPtr screen) glamor_egl_get_screen_private(scrn); glamor_fini(screen); - eglDestroyImageKHR(glamor_egl->display, glamor_egl->root); - - glamor_egl->root = EGL_NO_IMAGE_KHR; - return TRUE; } @@ -402,6 +397,8 @@ glamor_egl_free_screen(int scrnIndex, int flags) } free(glamor_egl); } + + glamor_close_screen(scrn->scrnIndex, scrn->pScreen); } Bool diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index 068d877d7..97ba33c1c 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -6,6 +6,132 @@ #include "glamor_priv.h" +#define GLAMOR_CACHE_EXPIRE_MAX 1000 + +#define GLAMOR_CACHE_DEFAULT 0 +#define GLAMOR_CACHE_EXACT_SIZE 1 + +/* Loop from the tail to the head. */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = __container_of((head)->prev, pos, member); \ + &pos->member != (head); \ + pos = __container_of(pos->member.prev, pos, member)) + + +#define list_for_each_entry_safe_reverse(pos, tmp, head, member) \ + for (pos = __container_of((head)->prev, pos, member), \ + tmp = __container_of(pos->member.prev, pos, member); \ + &pos->member != (head); \ + pos = tmp, tmp = __container_of(pos->member.prev, tmp, member)) + +#ifdef __i386__ +static inline unsigned long __fls(unsigned long x) +{ + asm("bsr %1,%0" + : "=r" (x) + : "rm" (x)); + return x; +} +#else +static inline unsigned long __fls(unsigned long x) +{ + int n; + + if (x == 0) return(0); + n = 0; + if (x <= 0x0000FFFF) {n = n +16; x = x <<16;} + if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;} + if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;} + if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;} + if (x <= 0x7FFFFFFF) {n = n + 1;} + return 31 - n; +} +#endif + +inline static int cache_wbucket(int size) +{ + int order = __fls(size / 256); + if (order >= CACHE_BUCKET_WCOUNT) + order = CACHE_BUCKET_WCOUNT - 1; + return order; +} + +inline static int cache_hbucket(int size) +{ + int order = __fls(size / 256); + if (order >= CACHE_BUCKET_HCOUNT) + order = CACHE_BUCKET_HCOUNT - 1; + return order; +} + +inline static int cache_format(GLenum format) +{ + switch (format) { +#if 0 + case GL_ALPHA: + return 1; +#endif + case GL_RGBA: + default: + return 0; + } +} + +glamor_pixmap_fbo * +glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv, + int w, int h, GLenum format, int flag) +{ + struct list *cache; + glamor_pixmap_fbo *fbo_entry; + int size; + + cache = &glamor_priv->fbo_cache[cache_format(format)] + [cache_wbucket(w)] + [cache_hbucket(h)]; + if (flag != GLAMOR_CACHE_EXACT_SIZE) { + list_for_each_entry(fbo_entry, cache, list) { + if (fbo_entry->width == w && fbo_entry->height == h) { + + DEBUGF("Request w %d h %d \n", w, h); + DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n", + fbo_entry, fbo_entry->width, fbo_entry->height, + fbo_entry->fb, fbo_entry->tex); + list_del(&fbo_entry->list); + return fbo_entry; + } + } + } + else { + list_for_each_entry(fbo_entry, cache, list) { + if (fbo_entry->width == w && fbo_entry->height == h) { + + DEBUGF("Request w %d h %d \n", w, h); + DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n", + fbo_entry, fbo_entry->width, fbo_entry->height, + fbo_entry->fb, fbo_entry->tex); + list_del(&fbo_entry->list); + return fbo_entry; + } + } + } + + return NULL; +} + +void +glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo) +{ + struct list *cache; + + cache = &fbo->glamor_priv->fbo_cache[cache_format(fbo->format)] + [cache_wbucket(fbo->width)] + [cache_hbucket(fbo->height)]; + DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache, + fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex); + list_add(&fbo->list, cache); + fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX; +} + glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, int w, int h, int depth, GLint tex, int flag) @@ -18,6 +144,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, if (fbo == NULL) return NULL; + list_init(&fbo->list); gl_iformat_for_depth(depth, &format); fbo->tex = tex; @@ -31,13 +158,11 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, return fbo; } -/* Make sure already detached from any pixmap. */ -void -glamor_destroy_fbo(glamor_pixmap_fbo *fbo) +static void +glamor_purge_fbo(glamor_pixmap_fbo *fbo) { glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch; - - DEBUGF("Destroy fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb); + DEBUGF("Purge fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb); if (fbo->fb) dispatch->glDeleteFramebuffers(1, &fbo->fb); if (fbo->tex) @@ -48,6 +173,79 @@ glamor_destroy_fbo(glamor_pixmap_fbo *fbo) free(fbo); } +void +glamor_fbo_expire(glamor_screen_private *glamor_priv) +{ + struct list *cache; + glamor_pixmap_fbo *fbo_entry, *tmp; + int i,j,k; + int empty_cache = TRUE; + + for(i = 0; i < CACHE_FORMAT_COUNT; i++) + for(j = 0; j < CACHE_BUCKET_WCOUNT; j++) + for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) { + cache = &glamor_priv->fbo_cache[i][j][k]; + list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) { + if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) { + empty_cache = FALSE; + break; + } + list_del(&fbo_entry->list); + DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry, + fbo_entry->expire, glamor_priv->tick); + glamor_purge_fbo(fbo_entry); + } + } + +} + +void +glamor_init_pixmap_fbo(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv; + int i,j,k; + + glamor_priv = glamor_get_screen_private(screen); + for(i = 0; i < CACHE_FORMAT_COUNT; i++) + for(j = 0; j < CACHE_BUCKET_WCOUNT; j++) + for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) + { + list_init(&glamor_priv->fbo_cache[i][j][k]); + } +} + +void +glamor_fini_pixmap_fbo(ScreenPtr screen) +{ + struct list *cache; + glamor_screen_private *glamor_priv; + glamor_pixmap_fbo *fbo_entry, *tmp; + int i,j,k; + + glamor_priv = glamor_get_screen_private(screen); + for(i = 0; i < CACHE_FORMAT_COUNT; i++) + for(j = 0; j < CACHE_BUCKET_WCOUNT; j++) + for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) + { + cache = &glamor_priv->fbo_cache[i][j][k]; + list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) { + list_del(&fbo_entry->list); + glamor_purge_fbo(fbo_entry); + } + + } +} + +void +glamor_destroy_fbo(glamor_pixmap_fbo *fbo) +{ + glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch; + + list_del(&fbo->list); + glamor_pixmap_fbo_cache_put(fbo); + +} + glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv, int w, int h, int depth, int flag) @@ -56,8 +254,19 @@ glamor_create_fbo(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo; GLenum format; GLint tex; + int cache_flag; + + if (flag == GLAMOR_CREATE_PIXMAP_FIXUP) + cache_flag = GLAMOR_CACHE_EXACT_SIZE; + else + cache_flag = 0; gl_iformat_for_depth(depth, &format); + fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, + format, GLAMOR_CACHE_EXACT_SIZE); + if (fbo) + return fbo; + dispatch = &glamor_priv->dispatch; dispatch->glGenTextures(1, &tex); dispatch->glBindTexture(GL_TEXTURE_2D, tex); @@ -69,8 +278,8 @@ glamor_create_fbo(glamor_screen_private *glamor_priv, GL_UNSIGNED_BYTE, NULL); fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag); - DEBUGF("Creat fbo %p tex %d width %d height %d \n", fbo, tex, w, h); + DEBUGF("Creat new fbo %p tex %d width %d height %d \n", fbo, tex, w, h); return fbo; } diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index da8097a10..df97ad018 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -101,9 +101,8 @@ glamor_fill(DrawablePtr drawable, void glamor_init_solid_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; const char *solid_vs = "attribute vec4 v_position;" "void main()\n" "{\n" " gl_Position = v_position;\n" @@ -113,12 +112,12 @@ glamor_init_solid_shader(ScreenPtr screen) "void main()\n" "{\n" " gl_FragColor = color;\n" "}\n"; GLint fs_prog, vs_prog; + glamor_priv = glamor_get_screen_private(screen); + dispatch = &glamor_priv->dispatch; glamor_priv->solid_prog = dispatch->glCreateProgram(); - vs_prog = - glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs); - fs_prog = - glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - solid_fs); + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, + solid_fs); dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog); dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog); @@ -131,6 +130,17 @@ glamor_init_solid_shader(ScreenPtr screen) "color"); } +void +glamor_fini_solid_shader(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = &glamor_priv->dispatch; + dispatch->glDeleteProgram(glamor_priv->solid_prog); +} + Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, unsigned char alu, unsigned long planemask, diff --git a/glamor/glamor_gl_dispatch.c b/glamor/glamor_gl_dispatch.c index f8516b4d9..493c96707 100644 --- a/glamor/glamor_gl_dispatch.c +++ b/glamor/glamor_gl_dispatch.c @@ -61,6 +61,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch, INIT_FUNC(dispatch, glUniform4f, get_proc_address); INIT_FUNC(dispatch, glUniform4fv, get_proc_address); INIT_FUNC(dispatch, glCreateProgram, get_proc_address); + INIT_FUNC(dispatch, glDeleteProgram, get_proc_address); INIT_FUNC(dispatch, glCreateShader, get_proc_address); INIT_FUNC(dispatch, glCompileShader, get_proc_address); INIT_FUNC(dispatch, glAttachShader, get_proc_address); diff --git a/glamor/glamor_gl_dispatch.h b/glamor/glamor_gl_dispatch.h index a8a699b5c..024de265a 100644 --- a/glamor/glamor_gl_dispatch.h +++ b/glamor/glamor_gl_dispatch.h @@ -97,6 +97,7 @@ typedef struct glamor_gl_dispatch { void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat * value); GLuint(*glCreateProgram) (void); + GLuint(*glDeleteProgram) (GLuint); GLuint(*glCreateShader) (GLenum type); void (*glCompileShader) (GLuint shader); void (*glAttachShader) (GLuint program, GLuint shader); diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 7c76496c8..f001962e7 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -63,11 +63,17 @@ glamor_pixmap_validate_function_t pixmap_validate_funcs[] = { void glamor_pixmap_init(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); + glamor_screen_private *glamor_priv; + + glamor_priv = glamor_get_screen_private(screen); glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs; } +void +glamor_pixmap_fini(ScreenPtr screen) +{ +} + void glamor_validate_pixmap(PixmapPtr pixmap) { diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index b4c3b74af..31f9c93ca 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -159,18 +159,24 @@ struct glamor_saved_procs { UnrealizeGlyphProcPtr unrealize_glyph; }; -#define CACHE_FORMAT_COUNT 2 -#define CACHE_BUCKET_WCOUNT 16 -#define CACHE_BUCKET_HCOUNT 16 +#define CACHE_FORMAT_COUNT 1 +#define CACHE_BUCKET_WCOUNT 4 +#define CACHE_BUCKET_HCOUNT 4 + +#define GLAMOR_TICK_AFTER(t0, t1) \ + (((int)(t1) - (int)(t0)) < 0) typedef struct glamor_screen_private { struct glamor_gl_dispatch dispatch; int yInverted; + unsigned int tick; enum glamor_gl_flavor gl_flavor; int has_pack_invert; int has_fbo_blit; int max_fbo_size; + struct list fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT]; + /* glamor_solid */ GLint solid_prog; GLint solid_color_uniform_location; @@ -207,6 +213,7 @@ typedef struct glamor_screen_private { char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1]; int delayed_fallback_pending; glamor_pixmap_validate_function_t *pixmap_validate_funcs; + int flags; } glamor_screen_private; typedef enum glamor_access { @@ -246,6 +253,8 @@ typedef union _glamor_pending_op { **/ typedef struct glamor_pixmap_fbo { + struct list list; + unsigned int expire; unsigned char pbo_valid; GLuint tex; GLuint fb; @@ -321,8 +330,6 @@ extern int glamor_debug_level; /* glamor.c */ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable); -Bool glamor_close_screen(int idx, ScreenPtr screen); - PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage); @@ -336,15 +343,15 @@ glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv, int w, int h, int depth, int flag); void glamor_destroy_fbo(glamor_pixmap_fbo *fbo); +void glamor_init_pixmap_fbo(ScreenPtr screen); +void glamor_fini_pixmap_fbo(ScreenPtr screen); Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap); +void glamor_fbo_expire(glamor_screen_private *glamor_priv); +void glamor_init_pixmap_fbo(ScreenPtr screen); +void glamor_fini_pixmap_fbo(ScreenPtr screen); Bool glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv); -#define GLAMOR_CACHE_GET_DEFAULT 0 -#define GLAMOR_CACHE_GET_EAXCT_SIZE 1 -#define GLAMOR_CACHE_GET_UPLOAD 2 - - /* glamor_copyarea.c */ RegionPtr glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, @@ -366,6 +373,7 @@ void glamor_finish_access_window(WindowPtr window); Bool glamor_prepare_access_gc(GCPtr gc); void glamor_finish_access_gc(GCPtr gc); void glamor_init_finish_access_shaders(ScreenPtr screen); +void glamor_fini_finish_access_shaders(ScreenPtr screen); const Bool glamor_get_drawable_location(const DrawablePtr drawable); void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int *x, int *y); @@ -427,6 +435,7 @@ void glamor_fill_spans(DrawablePtr drawable, int n, DDXPointPtr points, int *widths, int sorted); void glamor_init_solid_shader(ScreenPtr screen); +void glamor_fini_solid_shader(ScreenPtr screen); /* glamor_getspans.c */ void @@ -468,6 +477,7 @@ void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits); void glamor_init_putimage_shaders(ScreenPtr screen); +void glamor_fini_putimage_shaders(ScreenPtr screen); /* glamor_render.c */ void glamor_composite(CARD8 op, @@ -484,6 +494,7 @@ void glamor_trapezoids(CARD8 op, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps); void glamor_init_composite_shaders(ScreenPtr screen); +void glamor_fini_composite_shaders(ScreenPtr screen); void glamor_composite_glyph_rects(CARD8 op, PicturePtr src, PicturePtr mask, PicturePtr dst, int nrect, @@ -501,6 +512,7 @@ Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, unsigned char alu, unsigned long planemask, int tile_x, int tile_y); void glamor_init_tile_shader(ScreenPtr screen); +void glamor_fini_tile_shader(ScreenPtr screen); /* glamor_triangles.c */ void @@ -514,6 +526,7 @@ glamor_triangles(CARD8 op, /* glamor_pixmap.c */ void glamor_pixmap_init(ScreenPtr screen); +void glamor_pixmap_fini(ScreenPtr screen); /** * Download a pixmap's texture to cpu memory. If success, * One copy of current pixmap's texture will be put into diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index f285d957c..26d5cf766 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -239,6 +239,11 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, } #endif +void +glamor_fini_putimage_shaders(ScreenPtr screen) +{ +} + static Bool _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 99b60c660..19ed22e55 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -309,11 +309,12 @@ glamor_init_eb(unsigned short *eb, int vert_cnt) void glamor_init_composite_shaders(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; unsigned short *eb; + glamor_priv = glamor_get_screen_private(screen); + dispatch = &glamor_priv->dispatch; dispatch->glGenBuffers(1, &glamor_priv->vbo); dispatch->glGenBuffers(1, &glamor_priv->ebo); dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); @@ -326,6 +327,34 @@ glamor_init_composite_shaders(ScreenPtr screen) dispatch->glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); } + + +void +glamor_fini_composite_shaders(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + glamor_composite_shader *shader; + int i,j,k; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = &glamor_priv->dispatch; + dispatch->glDeleteBuffers(1, &glamor_priv->vbo); + dispatch->glDeleteBuffers(1, &glamor_priv->ebo); + + + for(i = 0; i < SHADER_SOURCE_COUNT; i++) + for(j = 0; j < SHADER_MASK_COUNT; j++) + for(k = 0; k < SHADER_IN_COUNT; k++) + { + shader = &glamor_priv->composite_shader[i][j][k]; + if (shader->prog) + dispatch->glDeleteProgram(shader->prog); + } + +} + + static Bool glamor_set_composite_op(ScreenPtr screen, CARD8 op, PicturePtr dest, PicturePtr mask) diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 9dadf5e47..7e0e6acb3 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -39,9 +39,8 @@ void glamor_init_tile_shader(ScreenPtr screen) { - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; const char *tile_vs = "attribute vec4 v_position;\n" "attribute vec4 v_texcoord0;\n" @@ -60,12 +59,12 @@ glamor_init_tile_shader(ScreenPtr screen) GLint fs_prog, vs_prog; GLint sampler_uniform_location; + glamor_priv = glamor_get_screen_private(screen); + dispatch = &glamor_priv->dispatch; glamor_priv->tile_prog = dispatch->glCreateProgram(); - vs_prog = - glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs); - fs_prog = - glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, - tile_fs); + vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs); + fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, + tile_fs); dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog); dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog); @@ -84,6 +83,17 @@ glamor_init_tile_shader(ScreenPtr screen) dispatch->glUseProgram(0); } +void +glamor_fini_tile_shader(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv; + glamor_gl_dispatch *dispatch; + + glamor_priv = glamor_get_screen_private(screen); + dispatch = &glamor_priv->dispatch; + dispatch->glDeleteProgram(glamor_priv->tile_prog); +} + Bool glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int x, int y, int width, int height,