commit e2b75f7
Michael Forney
·
2014-01-14 08:40:02 +0000 UTC
parent bbb03ae
pixman: Allow read/write to arbitrary buffers using drawable_map The first time pixman sees an unknown drawable, it maps it and then adds a pixman image exporter to the drawable.
M
pixman.c
+88,
-13
1@@ -39,12 +39,20 @@ struct pixman_renderer
2 pixman_glyph_cache_t * glyph_cache;
3 };
4
5+struct pixman_exporter
6+{
7+ struct wld_exporter base;
8+ pixman_image_t * image;
9+};
10+
11 #include "interface/context.h"
12 #define RENDERER_IMPLEMENTS_REGION
13 #include "interface/renderer.h"
14 #include "interface/drawable.h"
15+#include "interface/exporter.h"
16 IMPL(pixman, renderer)
17 IMPL(pixman, drawable)
18+IMPL(pixman, exporter)
19
20 static struct wld_context context = { .impl = &context_impl };
21 const struct wld_drawable_impl * const pixman_drawable_impl = &drawable_impl;
22@@ -168,11 +176,56 @@ void context_destroy(struct wld_context * context)
23
24 uint32_t renderer_capabilities(struct wld_renderer * renderer,
25 struct wld_drawable * drawable)
26+{
27+ /* The pixman renderer can read and write to any drawable using it's map
28+ * implementation. */
29+ return WLD_CAPABILITY_READ | WLD_CAPABILITY_WRITE;
30+}
31+
32+static void destroy_image(pixman_image_t * image, void * data)
33+{
34+ struct wld_drawable * drawable = data;
35+
36+ wld_unmap(drawable);
37+}
38+
39+static pixman_image_t * pixman_image(struct wld_drawable * drawable)
40 {
41 if (drawable->impl == &drawable_impl)
42- return WLD_CAPABILITY_READ | WLD_CAPABILITY_WRITE;
43+ return pixman_image_ref(pixman_drawable(drawable)->image);
44+
45+ union wld_object object;
46+
47+ if (wld_export(drawable, WLD_PIXMAN_OBJECT_IMAGE, &object))
48+ return object.ptr;
49+
50+ struct pixman_exporter * exporter;
51+ pixman_image_t * image;
52+
53+ if (!wld_map(drawable))
54+ goto error0;
55+
56+ image = pixman_image_create_bits(format_wld_to_pixman(drawable->format),
57+ drawable->width, drawable->height,
58+ drawable->map.data, drawable->pitch);
59+ pixman_image_set_destroy_function(image, &destroy_image, drawable);
60+
61+ if (!image)
62+ goto error1;
63+
64+ if (!(exporter = malloc(sizeof *exporter)))
65+ return NULL;
66+
67+ exporter_initialize(&exporter->base, &exporter_impl);
68+ exporter->image = image;
69+ drawable_add_exporter(drawable, &exporter->base);
70+
71+ return pixman_image_ref(image);
72
73- return 0;
74+ error1:
75+ wld_unmap(drawable);
76+ error0:
77+ return NULL;
78 }
79
80 bool renderer_set_target(struct wld_renderer * base,
81@@ -180,11 +233,13 @@ bool renderer_set_target(struct wld_renderer * base,
82 {
83 struct pixman_renderer * renderer = pixman_renderer(base);
84
85- if (drawable && drawable->impl != &drawable_impl)
86- return false;
87+ if (renderer->target)
88+ pixman_image_unref(renderer->target);
89
90- renderer->target = drawable ? pixman_drawable(drawable)->image : NULL;
91+ if (drawable)
92+ return (renderer->target = pixman_image(drawable));
93
94+ renderer->target = NULL;
95 return true;
96 }
97
98@@ -220,12 +275,10 @@ void renderer_copy_rectangle(struct wld_renderer * base,
99 uint32_t width, uint32_t height)
100 {
101 struct pixman_renderer * renderer = pixman_renderer(base);
102- pixman_image_t * dst = renderer->target, * src;
103+ pixman_image_t * src = pixman_image(drawable), * dst = renderer->target;
104
105- if (drawable->impl != &drawable_impl)
106- return;
107+ if (!src) return;
108
109- src = pixman_drawable(drawable)->image;
110 pixman_image_composite32(PIXMAN_OP_SRC, src, NULL, dst,
111 src_x, src_y, 0, 0, dst_x, dst_y, width, height);
112 }
113@@ -236,12 +289,10 @@ void renderer_copy_region(struct wld_renderer * base,
114 pixman_region32_t * region)
115 {
116 struct pixman_renderer * renderer = pixman_renderer(base);
117- pixman_image_t * dst = renderer->target, * src;
118+ pixman_image_t * src = pixman_image(drawable), * dst = renderer->target;
119
120- if (drawable->impl != &drawable_impl)
121- return;
122+ if (!src) return;
123
124- src = pixman_drawable(drawable)->image;
125 pixman_image_set_clip_region32(src, region);
126 pixman_image_composite32(PIXMAN_OP_SRC, src, NULL, dst,
127 region->extents.x1, region->extents.y1, 0, 0,
128@@ -383,3 +434,27 @@ void drawable_destroy(struct wld_drawable * drawable)
129 free(pixman);
130 }
131
132+/**** Exporter ****/
133+bool exporter_export(struct wld_exporter * base, struct wld_drawable * drawable,
134+ uint32_t type, union wld_object * object)
135+{
136+ struct pixman_exporter * exporter = pixman_exporter(base);
137+
138+ switch (type)
139+ {
140+ case WLD_PIXMAN_OBJECT_IMAGE:
141+ object->ptr = pixman_image_ref(exporter->image);
142+ return true;
143+ default:
144+ return false;
145+ }
146+}
147+
148+void exporter_destroy(struct wld_exporter * base)
149+{
150+ struct pixman_exporter * exporter = pixman_exporter(base);
151+
152+ pixman_image_unref(exporter->image);
153+ free(exporter);
154+}
155+
M
pixman.h
+5,
-0
1@@ -26,6 +26,11 @@
2
3 #include <stdint.h>
4
5+enum wld_pixman_object_type
6+{
7+ WLD_PIXMAN_OBJECT_IMAGE = 0x00030000
8+};
9+
10 extern struct wld_context * wld_pixman_context;
11
12 static inline struct wld_context * wld_pixman_create_context()