4 * An object oriented GL/GLES Abstraction/Utility Layer
6 * Copyright (C) 2010 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
24 * Neil Roberts <neil@linux.intel.com>
25 * Johan Bilien <johan.bilien@nokia.com>
26 * Robert Bragg <robert@linux.intel.com>
33 #include "cogl-debug.h"
34 #include "cogl-internal.h"
35 #include "cogl-util.h"
36 #include "cogl-texture-pixmap-x11.h"
37 #include "cogl-texture-pixmap-x11-private.h"
38 #include "cogl-bitmap-private.h"
39 #include "cogl-texture-private.h"
40 #include "cogl-texture-driver.h"
41 #include "cogl-texture-2d-private.h"
42 #include "cogl-texture-rectangle-private.h"
43 #include "cogl-context-private.h"
44 #include "cogl-display-private.h"
45 #include "cogl-renderer-private.h"
46 #include "cogl-handle.h"
47 #include "cogl-winsys-private.h"
48 #include "cogl-pipeline-opengl-private.h"
49 #include "cogl-xlib.h"
52 #include <X11/Xutil.h>
56 #include <X11/extensions/XShm.h>
61 static void _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap);
63 COGL_TEXTURE_DEFINE (TexturePixmapX11, texture_pixmap_x11);
65 static const CoglTextureVtable cogl_texture_pixmap_x11_vtable;
68 cogl_texture_pixmap_x11_error_quark (void)
70 return g_quark_from_static_string ("cogl-texture-pixmap-error-quark");
74 cogl_damage_rectangle_union (CoglDamageRectangle *damage_rect,
80 /* If the damage region is empty then we'll just copy the new
82 if (damage_rect->x1 == damage_rect->x2 ||
83 damage_rect->y1 == damage_rect->y2)
87 damage_rect->x2 = x + width;
88 damage_rect->y2 = y + height;
92 if (damage_rect->x1 > x)
94 if (damage_rect->y1 > y)
96 if (damage_rect->x2 < x + width)
97 damage_rect->x2 = x + width;
98 if (damage_rect->y2 < y + height)
99 damage_rect->y2 = y + height;
104 cogl_damage_rectangle_is_whole (const CoglDamageRectangle *damage_rect,
108 return (damage_rect->x1 == 0 && damage_rect->y1 == 0
109 && damage_rect->x2 == width && damage_rect->y2 == height);
112 static const CoglWinsysVtable *
113 _cogl_texture_pixmap_x11_get_winsys (CoglTexturePixmapX11 *tex_pixmap)
115 /* FIXME: A CoglContext should be reachable from a CoglTexture
117 _COGL_GET_CONTEXT (ctx, NULL);
119 return ctx->display->renderer->winsys_vtable;
123 process_damage_event (CoglTexturePixmapX11 *tex_pixmap,
124 XDamageNotifyEvent *damage_event)
127 enum { DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode;
128 const CoglWinsysVtable *winsys;
130 _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
132 display = cogl_xlib_get_display ();
134 COGL_NOTE (TEXTURE_PIXMAP, "Damage event received for %p", tex_pixmap);
136 switch (tex_pixmap->damage_report_level)
138 case COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES:
139 /* For raw rectangles we don't need do look at the damage region
140 at all because the damage area is directly given in the event
141 struct and the reporting of events is not affected by
142 clearing the damage region */
143 handle_mode = DO_NOTHING;
146 case COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES:
147 case COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY:
148 /* For delta rectangles and non empty we'll query the damage
149 region for the bounding box */
150 handle_mode = NEED_BOUNDING_BOX;
153 case COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX:
154 /* For bounding box we need to clear the damage region but we
155 don't actually care what it was because the damage event
156 itself contains the bounding box of the region */
157 handle_mode = NEEDS_SUBTRACT;
161 g_assert_not_reached ();
164 /* If the damage already covers the whole rectangle then we don't
165 need to request the bounding box of the region because we're
166 going to update the whole texture anyway. */
167 if (cogl_damage_rectangle_is_whole (&tex_pixmap->damage_rect,
171 if (handle_mode != DO_NOTHING)
172 XDamageSubtract (display, tex_pixmap->damage, None, None);
174 else if (handle_mode == NEED_BOUNDING_BOX)
179 XRectangle *r_damage;
181 /* We need to extract the damage region so we can get the
184 parts = XFixesCreateRegion (display, 0, 0);
185 XDamageSubtract (display, tex_pixmap->damage, None, parts);
186 r_damage = XFixesFetchRegionAndBounds (display,
190 cogl_damage_rectangle_union (&tex_pixmap->damage_rect,
198 XFixesDestroyRegion (display, parts);
202 if (handle_mode == NEEDS_SUBTRACT)
203 /* We still need to subtract from the damage region but we
204 don't care what the region actually was */
205 XDamageSubtract (display, tex_pixmap->damage, None, None);
207 cogl_damage_rectangle_union (&tex_pixmap->damage_rect,
208 damage_event->area.x,
209 damage_event->area.y,
210 damage_event->area.width,
211 damage_event->area.height);
214 if (tex_pixmap->winsys)
216 /* If we're using the texture from pixmap extension then there's no
217 point in getting the region and we can just mark that the texture
219 winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
220 winsys->texture_pixmap_x11_damage_notify (tex_pixmap);
224 static CoglFilterReturn
225 _cogl_texture_pixmap_x11_filter (XEvent *event, void *data)
227 CoglTexturePixmapX11 *tex_pixmap = data;
230 _COGL_GET_CONTEXT (ctxt, COGL_FILTER_CONTINUE);
232 damage_base = _cogl_xlib_get_damage_base ();
233 if (event->type == damage_base + XDamageNotify)
235 XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) event;
237 if (damage_event->damage == tex_pixmap->damage)
238 process_damage_event (tex_pixmap, damage_event);
241 return COGL_FILTER_CONTINUE;
245 set_damage_object_internal (CoglContext *ctx,
246 CoglTexturePixmapX11 *tex_pixmap,
248 CoglTexturePixmapX11ReportLevel report_level)
250 if (tex_pixmap->damage)
252 cogl_xlib_renderer_remove_filter (ctx->display->renderer,
253 _cogl_texture_pixmap_x11_filter,
256 if (tex_pixmap->damage_owned)
258 XDamageDestroy (cogl_xlib_get_display (), tex_pixmap->damage);
259 tex_pixmap->damage_owned = FALSE;
263 tex_pixmap->damage = damage;
264 tex_pixmap->damage_report_level = report_level;
267 cogl_xlib_renderer_add_filter (ctx->display->renderer,
268 _cogl_texture_pixmap_x11_filter,
272 CoglTexturePixmapX11 *
273 cogl_texture_pixmap_x11_new (CoglContext *ctxt,
275 gboolean automatic_updates,
278 CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1);
279 Display *display = cogl_xlib_get_display ();
280 Window pixmap_root_window;
281 int pixmap_x, pixmap_y;
282 unsigned int pixmap_border_width;
283 CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
284 XWindowAttributes window_attributes;
286 const CoglWinsysVtable *winsys;
288 _cogl_texture_init (tex, &cogl_texture_pixmap_x11_vtable);
290 tex_pixmap->pixmap = pixmap;
291 tex_pixmap->image = NULL;
292 tex_pixmap->shm_info.shmid = -1;
293 tex_pixmap->tex = COGL_INVALID_HANDLE;
294 tex_pixmap->damage_owned = FALSE;
295 tex_pixmap->damage = 0;
297 if (!XGetGeometry (display, pixmap, &pixmap_root_window,
298 &pixmap_x, &pixmap_y,
299 &tex_pixmap->width, &tex_pixmap->height,
300 &pixmap_border_width, &tex_pixmap->depth))
304 COGL_TEXTURE_PIXMAP_X11_ERROR,
305 COGL_TEXTURE_PIXMAP_X11_ERROR_X11,
306 "Unable to query pixmap size");
310 /* We need a visual to use for shared memory images so we'll query
311 it from the pixmap's root window */
312 if (!XGetWindowAttributes (display, pixmap_root_window, &window_attributes))
316 COGL_TEXTURE_PIXMAP_X11_ERROR,
317 COGL_TEXTURE_PIXMAP_X11_ERROR_X11,
318 "Unable to query root window attributes");
321 tex_pixmap->visual = window_attributes.visual;
323 /* If automatic updates are requested and the Xlib connection
324 supports damage events then we'll register a damage object on the
326 damage_base = _cogl_xlib_get_damage_base ();
327 if (automatic_updates && damage_base >= 0)
329 Damage damage = XDamageCreate (display,
331 XDamageReportBoundingBox);
332 set_damage_object_internal (ctxt,
335 COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX);
336 tex_pixmap->damage_owned = TRUE;
339 /* Assume the entire pixmap is damaged to begin with */
340 tex_pixmap->damage_rect.x1 = 0;
341 tex_pixmap->damage_rect.x2 = tex_pixmap->width;
342 tex_pixmap->damage_rect.y1 = 0;
343 tex_pixmap->damage_rect.y2 = tex_pixmap->height;
345 winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
346 if (winsys->texture_pixmap_x11_create)
348 tex_pixmap->use_winsys_texture =
349 winsys->texture_pixmap_x11_create (tex_pixmap);
352 tex_pixmap->use_winsys_texture = FALSE;
354 if (!tex_pixmap->use_winsys_texture)
355 tex_pixmap->winsys = NULL;
357 return _cogl_texture_pixmap_x11_handle_new (tex_pixmap);
360 /* Tries to allocate enough shared mem to handle a full size
361 * update size of the X Pixmap. */
363 try_alloc_shm (CoglTexturePixmapX11 *tex_pixmap)
368 display = cogl_xlib_get_display ();
370 if (!XShmQueryExtension (display))
373 /* We are creating a dummy_image so we can have Xlib calculate
374 * image->bytes_per_line - including any magic padding it may
375 * want - for the largest possible ximage we might need to use
376 * when handling updates to the texture.
378 * Note: we pass a NULL shminfo here, but that has no bearing
379 * on the setup of the XImage, except that ximage->obdata will
383 XShmCreateImage (display,
392 goto failed_image_create;
394 tex_pixmap->shm_info.shmid = shmget (IPC_PRIVATE,
395 dummy_image->bytes_per_line
396 * dummy_image->height,
398 if (tex_pixmap->shm_info.shmid == -1)
401 tex_pixmap->shm_info.shmaddr = shmat (tex_pixmap->shm_info.shmid, 0, 0);
402 if (tex_pixmap->shm_info.shmaddr == (void *) -1)
405 tex_pixmap->shm_info.readOnly = False;
407 if (XShmAttach (display, &tex_pixmap->shm_info) == 0)
408 goto failed_xshmattach;
410 XDestroyImage (dummy_image);
415 g_warning ("XShmAttach failed");
416 shmdt (tex_pixmap->shm_info.shmaddr);
419 g_warning ("shmat failed");
420 shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0);
423 g_warning ("shmget failed");
424 XDestroyImage (dummy_image);
427 tex_pixmap->shm_info.shmid = -1;
431 cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap,
437 /* We'll queue the update for both the GLX texture and the regular
438 texture because we can't determine which will be needed until we
439 actually render something */
441 if (tex_pixmap->winsys)
443 const CoglWinsysVtable *winsys;
444 winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
445 winsys->texture_pixmap_x11_damage_notify (tex_pixmap);
448 cogl_damage_rectangle_union (&tex_pixmap->damage_rect,
449 x, y, width, height);
453 cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap)
455 return !!tex_pixmap->winsys;
459 cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *tex_pixmap,
461 CoglTexturePixmapX11ReportLevel
466 _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
468 damage_base = _cogl_xlib_get_damage_base ();
469 if (damage_base >= 0)
470 set_damage_object_internal (ctxt, tex_pixmap, damage, report_level);
474 _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
478 CoglPixelFormat image_format;
481 int x, y, width, height;
483 display = cogl_xlib_get_display ();
484 visual = tex_pixmap->visual;
486 /* If the damage region is empty then there's nothing to do */
487 if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1)
490 x = tex_pixmap->damage_rect.x1;
491 y = tex_pixmap->damage_rect.y1;
492 width = tex_pixmap->damage_rect.x2 - x;
493 height = tex_pixmap->damage_rect.y2 - y;
495 /* We lazily create the texture the first time it is needed in case
496 this texture can be entirely handled using the GLX texture
498 if (tex_pixmap->tex == COGL_INVALID_HANDLE)
500 CoglPixelFormat texture_format;
502 texture_format = (tex_pixmap->depth >= 32
503 ? COGL_PIXEL_FORMAT_RGBA_8888_PRE
504 : COGL_PIXEL_FORMAT_RGB_888);
506 tex_pixmap->tex = cogl_texture_new_with_size (tex_pixmap->width,
512 if (tex_pixmap->image == NULL)
514 /* If we also haven't got a shm segment then this must be the
515 first time we've tried to update, so lets try allocating shm
517 if (tex_pixmap->shm_info.shmid == -1)
518 try_alloc_shm (tex_pixmap);
520 if (tex_pixmap->shm_info.shmid == -1)
522 COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetImage", tex_pixmap);
524 /* We'll fallback to using a regular XImage. We'll download
525 the entire area instead of a sub region because presumably
526 if this is the first update then the entire pixmap is
527 needed anyway and it saves trying to manually allocate an
528 XImage at the right size */
529 tex_pixmap->image = XGetImage (display,
532 tex_pixmap->width, tex_pixmap->height,
534 image = tex_pixmap->image;
540 COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XShmGetImage",
543 /* Create a temporary image using the beginning of the
544 shared memory segment and the right size for the region
545 we want to update. We need to reallocate the XImage every
546 time because there is no XShmGetSubImage. */
547 image = XShmCreateImage (display,
552 &tex_pixmap->shm_info,
555 image->data = tex_pixmap->shm_info.shmaddr;
559 XShmGetImage (display, tex_pixmap->pixmap, image, x, y, AllPlanes);
564 COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetSubImage", tex_pixmap);
566 image = tex_pixmap->image;
570 XGetSubImage (display,
579 _cogl_util_pixel_format_from_masks (visual->red_mask,
583 image->bits_per_pixel,
584 image->byte_order == LSBFirst);
586 cogl_texture_set_region (tex_pixmap->tex,
592 image->bytes_per_line,
593 (const guint8 *) image->data);
595 /* If we have a shared memory segment then the XImage would be a
596 temporary one with no data allocated so we can just XFree it */
597 if (tex_pixmap->shm_info.shmid != -1)
600 memset (&tex_pixmap->damage_rect, 0, sizeof (CoglDamageRectangle));
604 _cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixmap,
607 if (tex_pixmap->use_winsys_texture != new_value)
609 /* Notify cogl-pipeline.c that the texture's underlying GL texture
610 * storage is changing so it knows it may need to bind a new texture
611 * if the CoglTexture is reused with the same texture unit. */
612 _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (tex_pixmap));
614 tex_pixmap->use_winsys_texture = new_value;
619 _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap,
620 gboolean needs_mipmap)
622 if (tex_pixmap->winsys)
624 const CoglWinsysVtable *winsys =
625 _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
627 if (winsys->texture_pixmap_x11_update (tex_pixmap, needs_mipmap))
629 _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE);
634 /* If it didn't work then fallback to using XGetImage. This may be
636 _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, FALSE);
638 _cogl_texture_pixmap_x11_update_image_texture (tex_pixmap);
642 _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
647 /* We try getting the texture twice, once without flushing the
648 updates and once with. If pre_paint has been called already then
649 we should have a good idea of which texture to use so we don't
650 want to mess with that by ensuring the updates. However, if we
651 couldn't find a texture then we'll just make a best guess by
652 flushing without expecting mipmap support and try again. This
653 would happen for example if an application calls
654 get_gl_texture before the first paint */
656 for (i = 0; i < 2; i++)
658 if (tex_pixmap->use_winsys_texture)
660 const CoglWinsysVtable *winsys =
661 _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
662 tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap);
665 tex = tex_pixmap->tex;
670 _cogl_texture_pixmap_x11_update (tex_pixmap, FALSE);
673 g_assert_not_reached ();
675 return COGL_INVALID_HANDLE;
679 _cogl_texture_pixmap_x11_set_region (CoglTexture *tex,
684 unsigned int dst_width,
685 unsigned int dst_height,
688 /* This doesn't make much sense for texture from pixmap so it's not
694 _cogl_texture_pixmap_x11_get_data (CoglTexture *tex,
695 CoglPixelFormat format,
696 unsigned int rowstride,
699 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
700 CoglHandle child_tex;
702 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
704 /* Forward on to the child texture */
705 return cogl_texture_get_data (child_tex, format, rowstride, data);
708 typedef struct _NormalizeCoordsWrapperData
712 CoglMetaTextureCallback callback;
714 } NormalizeCoordsWrapperData;
717 normalize_coords_wrapper_cb (CoglTexture *child_texture,
718 const float *child_texture_coords,
719 const float *meta_coords,
722 NormalizeCoordsWrapperData *data = user_data;
723 float normalized_coords[4];
725 normalized_coords[0] = meta_coords[0] / data->width;
726 normalized_coords[1] = meta_coords[1] / data->height;
727 normalized_coords[2] = meta_coords[2] / data->width;
728 normalized_coords[3] = meta_coords[3] / data->height;
730 data->callback (child_texture,
731 child_texture_coords, normalized_coords,
736 _cogl_texture_pixmap_x11_foreach_sub_texture_in_region
742 CoglMetaTextureCallback callback,
745 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
746 CoglHandle child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
748 /* Forward on to the child texture */
750 /* tfp textures may be implemented in terms of a
751 * CoglTextureRectangle texture which uses un-normalized texture
752 * coordinates but we want to consistently deal with normalized
753 * texture coordinates with CoglTexturePixmapX11... */
754 if (cogl_is_texture_rectangle (child_tex))
756 NormalizeCoordsWrapperData data;
757 int width = tex_pixmap->width;
758 int height = tex_pixmap->height;
760 virtual_tx_1 *= width;
761 virtual_ty_1 *= height;
762 virtual_tx_2 *= width;
763 virtual_ty_2 *= height;
766 data.height = height;
767 data.callback = callback;
768 data.user_data = user_data;
770 cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (child_tex),
775 COGL_PIPELINE_WRAP_MODE_REPEAT,
776 COGL_PIPELINE_WRAP_MODE_REPEAT,
777 normalize_coords_wrapper_cb,
781 cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (child_tex),
786 COGL_PIPELINE_WRAP_MODE_REPEAT,
787 COGL_PIPELINE_WRAP_MODE_REPEAT,
793 _cogl_texture_pixmap_x11_get_max_waste (CoglTexture *tex)
795 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
796 CoglHandle child_tex;
798 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
800 return cogl_texture_get_max_waste (child_tex);
804 _cogl_texture_pixmap_x11_is_sliced (CoglTexture *tex)
806 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
807 CoglHandle child_tex;
809 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
811 return cogl_texture_is_sliced (child_tex);
815 _cogl_texture_pixmap_x11_can_hardware_repeat (CoglTexture *tex)
817 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
818 CoglHandle child_tex;
820 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
822 return _cogl_texture_can_hardware_repeat (child_tex);
826 _cogl_texture_pixmap_x11_transform_coords_to_gl (CoglTexture *tex,
830 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
831 CoglHandle child_tex;
833 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
835 /* Forward on to the child texture */
836 _cogl_texture_transform_coords_to_gl (child_tex, s, t);
839 static CoglTransformResult
840 _cogl_texture_pixmap_x11_transform_quad_coords_to_gl (CoglTexture *tex,
843 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
844 CoglHandle child_tex;
846 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
848 /* Forward on to the child texture */
849 return _cogl_texture_transform_quad_coords_to_gl (child_tex, coords);
853 _cogl_texture_pixmap_x11_get_gl_texture (CoglTexture *tex,
854 GLuint *out_gl_handle,
855 GLenum *out_gl_target)
857 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
858 CoglHandle child_tex;
860 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
862 /* Forward on to the child texture */
863 return cogl_texture_get_gl_texture (child_tex,
869 _cogl_texture_pixmap_x11_set_filters (CoglTexture *tex,
873 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
874 CoglHandle child_tex;
876 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
878 /* Forward on to the child texture */
879 _cogl_texture_set_filters (child_tex, min_filter, mag_filter);
883 _cogl_texture_pixmap_x11_pre_paint (CoglTexture *tex,
884 CoglTexturePrePaintFlags flags)
886 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
887 CoglHandle child_tex;
889 _cogl_texture_pixmap_x11_update (tex_pixmap,
890 !!(flags & COGL_TEXTURE_NEEDS_MIPMAP));
892 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
894 _cogl_texture_pre_paint (child_tex, flags);
898 _cogl_texture_pixmap_x11_ensure_non_quad_rendering (CoglTexture *tex)
900 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
901 CoglHandle child_tex;
903 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
905 /* Forward on to the child texture */
906 _cogl_texture_ensure_non_quad_rendering (child_tex);
910 _cogl_texture_pixmap_x11_set_wrap_mode_parameters (CoglTexture *tex,
915 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
916 CoglHandle child_tex;
918 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
920 /* Forward on to the child texture */
921 _cogl_texture_set_wrap_mode_parameters (child_tex,
927 static CoglPixelFormat
928 _cogl_texture_pixmap_x11_get_format (CoglTexture *tex)
930 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
931 CoglHandle child_tex;
933 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
935 /* Forward on to the child texture */
936 return cogl_texture_get_format (child_tex);
940 _cogl_texture_pixmap_x11_get_gl_format (CoglTexture *tex)
942 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
943 CoglHandle child_tex;
945 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
947 return _cogl_texture_get_gl_format (child_tex);
951 _cogl_texture_pixmap_x11_get_width (CoglTexture *tex)
953 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
955 return tex_pixmap->width;
959 _cogl_texture_pixmap_x11_get_height (CoglTexture *tex)
961 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
963 return tex_pixmap->height;
966 static CoglTextureType
967 _cogl_texture_pixmap_x11_get_type (CoglTexture *tex)
969 CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex);
970 CoglTexture *child_tex;
972 child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap);
974 /* Forward on to the child texture */
975 return _cogl_texture_get_type (child_tex);
979 _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap)
981 _COGL_GET_CONTEXT (ctxt, NO_RETVAL);
983 set_damage_object_internal (ctxt, tex_pixmap, 0, 0);
985 if (tex_pixmap->image)
986 XDestroyImage (tex_pixmap->image);
988 if (tex_pixmap->shm_info.shmid != -1)
990 XShmDetach (cogl_xlib_get_display (), &tex_pixmap->shm_info);
991 shmdt (tex_pixmap->shm_info.shmaddr);
992 shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0);
996 cogl_handle_unref (tex_pixmap->tex);
998 if (tex_pixmap->winsys)
1000 const CoglWinsysVtable *winsys =
1001 _cogl_texture_pixmap_x11_get_winsys (tex_pixmap);
1002 winsys->texture_pixmap_x11_free (tex_pixmap);
1006 _cogl_texture_free (COGL_TEXTURE (tex_pixmap));
1009 static const CoglTextureVtable
1010 cogl_texture_pixmap_x11_vtable =
1012 _cogl_texture_pixmap_x11_set_region,
1013 _cogl_texture_pixmap_x11_get_data,
1014 _cogl_texture_pixmap_x11_foreach_sub_texture_in_region,
1015 _cogl_texture_pixmap_x11_get_max_waste,
1016 _cogl_texture_pixmap_x11_is_sliced,
1017 _cogl_texture_pixmap_x11_can_hardware_repeat,
1018 _cogl_texture_pixmap_x11_transform_coords_to_gl,
1019 _cogl_texture_pixmap_x11_transform_quad_coords_to_gl,
1020 _cogl_texture_pixmap_x11_get_gl_texture,
1021 _cogl_texture_pixmap_x11_set_filters,
1022 _cogl_texture_pixmap_x11_pre_paint,
1023 _cogl_texture_pixmap_x11_ensure_non_quad_rendering,
1024 _cogl_texture_pixmap_x11_set_wrap_mode_parameters,
1025 _cogl_texture_pixmap_x11_get_format,
1026 _cogl_texture_pixmap_x11_get_gl_format,
1027 _cogl_texture_pixmap_x11_get_width,
1028 _cogl_texture_pixmap_x11_get_height,
1029 _cogl_texture_pixmap_x11_get_type,
1030 NULL /* is_foreign */