commit f61ad4e
Michael Forney
·
2014-01-01 06:53:22 +0000 UTC
parent 6fb42cc
Add context abstraction
16 files changed,
+346,
-275
M
Makefile
+1,
-1
1@@ -15,7 +15,7 @@ CLEAN_FILES := $(TARGETS)
2
3 WLD_REQUIRES = fontconfig pixman-1
4 WLD_REQUIRES_PRIVATE = freetype2
5-WLD_SOURCES = drawable.c color.c font.c
6+WLD_SOURCES = context.c drawable.c color.c font.c
7 WLD_HEADERS = wld.h
8
9 ifeq ($(ENABLE_DEBUG),1)
+55,
-0
1@@ -0,0 +1,55 @@
2+/* wld: context.c
3+ *
4+ * Copyright (c) 2013 Michael Forney
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#include "wld-private.h"
26+
27+void context_initialize(struct wld_context * context,
28+ const struct wld_context_impl * impl)
29+{
30+ *((const struct wld_context_impl **) &context->impl) = impl;
31+}
32+
33+EXPORT
34+struct wld_drawable * wld_create_drawable(struct wld_context * context,
35+ uint32_t width, uint32_t height,
36+ uint32_t format)
37+{
38+ return context->impl->create_drawable(context, width, height, format);
39+}
40+
41+EXPORT
42+struct wld_drawable * wld_import(struct wld_context * context,
43+ uint32_t type, union wld_object object,
44+ uint32_t width, uint32_t height,
45+ uint32_t format, uint32_t pitch)
46+{
47+ return context->impl->import(context, type, object,
48+ width, height, format, pitch);
49+}
50+
51+EXPORT
52+void wld_destroy_context(struct wld_context * context)
53+{
54+ context->impl->destroy(context);
55+}
56+
+3,
-28
1@@ -26,30 +26,13 @@
2
3 #include "wld-private.h"
4
5-typedef bool (* drm_device_supported_func_t)(uint32_t vendor_id,
6- uint32_t device_id);
7-typedef void * (* drm_create_context_func_t)(int drm_fd);
8-typedef void (* drm_destroy_context_func_t)(void * context);
9-typedef struct wld_drawable * (* drm_create_drawable_func_t)
10- (void * context, uint32_t width, uint32_t height, uint32_t format);
11-typedef struct wld_drawable * (* drm_import_func_t)
12- (void * context, uint32_t width, uint32_t height, uint32_t format,
13- int prime_fd, unsigned long pitch);
14-typedef struct wld_drawable * (* drm_import_gem_func_t)
15- (void * context, uint32_t width, uint32_t height, uint32_t format,
16- uint32_t gem_name, unsigned long pitch);
17-
18 typedef int (* drm_export_func_t)(struct wld_drawable * drawable);
19 typedef uint32_t (* drm_get_handle_func_t)(struct wld_drawable * drawable);
20
21 struct wld_drm_interface
22 {
23- drm_device_supported_func_t device_supported;
24- drm_create_context_func_t create_context;
25- drm_destroy_context_func_t destroy_context;
26- drm_create_drawable_func_t create_drawable;
27- drm_import_func_t import;
28- drm_import_gem_func_t import_gem;
29+ bool (* device_supported)(uint32_t vendor_id, uint32_t device_id);
30+ struct wld_context * (* create_context)(int drm_fd);
31 };
32
33 struct drm_draw_interface
34@@ -59,19 +42,11 @@ struct drm_draw_interface
35 drm_get_handle_func_t get_handle;
36 };
37
38-struct wld_drm_context
39-{
40- const struct wld_drm_interface * interface;
41- void * context;
42-};
43-
44 #if WITH_DRM_INTEL
45 extern const struct wld_drm_interface intel_drm;
46 #endif
47 extern const struct wld_drm_interface dumb_drm;
48-
49-bool drm_initialize_context(struct wld_drm_context * context, int fd);
50-void drm_finalize_context(struct wld_drm_context * context);
51+extern const struct wld_context_impl * dumb_context_impl;
52
53 #endif
54
M
drm.c
+7,
-66
1@@ -68,80 +68,21 @@ static const struct wld_drm_interface * find_drm_interface(int fd)
2 return NULL;
3 }
4
5-bool drm_initialize_context(struct wld_drm_context * drm, int fd)
6-{
7- if (!(drm->interface = find_drm_interface(fd)))
8- return false;
9-
10- if (!(drm->context = drm->interface->create_context(fd)))
11- return false;
12-
13- return true;
14-}
15-
16-void drm_finalize_context(struct wld_drm_context * drm)
17-{
18- drm->interface->destroy_context(drm->context);
19-}
20-
21-EXPORT
22-struct wld_drm_context * wld_drm_create_context(int fd)
23-{
24- struct wld_drm_context * drm;
25-
26- if (!(drm = malloc(sizeof *drm)))
27- goto error0;
28-
29- if (!drm_initialize_context(drm, fd))
30- goto error1;
31-
32- return drm;
33-
34- error1:
35- free(drm);
36- error0:
37- return NULL;
38-}
39-
40-EXPORT
41-void wld_drm_destroy_context(struct wld_drm_context * drm)
42-{
43- drm_finalize_context(drm);
44- free(drm);
45-}
46-
47 EXPORT
48-bool wld_drm_is_dumb(struct wld_drm_context * drm)
49+struct wld_context * wld_drm_create_context(int fd)
50 {
51- return drm->interface == &dumb_drm;
52-}
53+ const struct wld_drm_interface * interface;
54
55-EXPORT
56-struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * drm,
57- uint32_t width, uint32_t height,
58- uint32_t format)
59-{
60- return drm->interface->create_drawable(drm->context, width, height, format);
61-}
62+ if (!(interface = find_drm_interface(fd)))
63+ return NULL;
64
65-EXPORT
66-struct wld_drawable * wld_drm_import(struct wld_drm_context * drm,
67- uint32_t width, uint32_t height,
68- uint32_t format,
69- int prime_fd, unsigned long pitch)
70-{
71- return drm->interface->import(drm->context, width, height, format,
72- prime_fd, pitch);
73+ return interface->create_context(fd);
74 }
75
76 EXPORT
77-struct wld_drawable * wld_drm_import_gem(struct wld_drm_context * drm,
78- uint32_t width, uint32_t height,
79- uint32_t format,
80- uint32_t gem_name, unsigned long pitch)
81+bool wld_drm_is_dumb(struct wld_context * context)
82 {
83- return drm->interface->import_gem(drm->context, width, height, format,
84- gem_name, pitch);
85+ return context->impl == dumb_context_impl;
86 }
87
88 EXPORT
M
drm.h
+8,
-36
1@@ -27,46 +27,18 @@
2 #include <stdbool.h>
3 #include <stdint.h>
4
5-struct wld_drm_context;
6-struct wld_drawable;
7+enum wld_drm_object_type
8+{
9+ WLD_DRM_OBJECT_PRIME_FD = 0x00010000,
10+ WLD_DRM_OBJECT_GEM_NAME = 0x00010001
11+};
12
13 /**
14- * Create a new DRM context from an opened DRM device file descriptor.
15+ * Create a new WLD context from an opened DRM device file descriptor.
16 */
17-struct wld_drm_context * wld_drm_create_context(int fd);
18+struct wld_context * wld_drm_create_context(int fd);
19
20-/**
21- * Destroy a DRM context.
22- */
23-void wld_drm_destroy_context(struct wld_drm_context * drm);
24-
25-bool wld_drm_is_dumb(struct wld_drm_context * drm);
26-
27-/**
28- * Create a new DRM drawable.
29- */
30-struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * drm,
31- uint32_t width, uint32_t height,
32- uint32_t format);
33-
34-/**
35- * Create a new DRM drawable by importing a PRIME file descriptor.
36- */
37-struct wld_drawable * wld_drm_import(struct wld_drm_context * context,
38- uint32_t width, uint32_t height,
39- uint32_t format,
40- int prime_fd, unsigned long pitch);
41-
42-/**
43- * Create a new DRM drawable by importing a GEM name.
44- *
45- * This is provided for compatibility with clients that don't support PRIME.
46- * You should use wld_drm_import_drawable and PRIME if possible.
47- */
48-struct wld_drawable * wld_drm_import_gem(struct wld_drm_context * context,
49- uint32_t width, uint32_t height,
50- uint32_t format, uint32_t gem_name,
51- unsigned long pitch);
52+bool wld_drm_is_dumb(struct wld_context * context);
53
54 /**
55 * Export a DRM drawable to a PRIME file descriptor.
M
dumb.c
+31,
-33
1@@ -24,6 +24,7 @@
2 #include "pixman.h"
3 #include "pixman-private.h"
4 #include "drm-private.h"
5+#include "drm.h"
6
7 #include <fcntl.h>
8 #include <sys/mman.h>
9@@ -33,7 +34,8 @@
10
11 struct dumb_context
12 {
13- struct wld_pixman_context * pixman;
14+ struct wld_context base;
15+ struct wld_context * pixman;
16 int fd;
17 };
18
19@@ -45,7 +47,11 @@ struct dumb_drawable
20 };
21
22 #define DRM_DRIVER_NAME dumb
23+#include "interface/context.h"
24 #include "interface/drm.h"
25+IMPL(dumb, context)
26+
27+const struct wld_context_impl * dumb_context_impl = &context_impl;
28
29 /* DRM drawable */
30 static int drawable_export(struct wld_drawable * drawable);
31@@ -62,7 +68,7 @@ bool drm_device_supported(uint32_t vendor_id, uint32_t device_id)
32 return true;
33 }
34
35-void * drm_create_context(int drm_fd)
36+struct wld_context * drm_create_context(int drm_fd)
37 {
38 struct dumb_context * context;
39
40@@ -72,6 +78,7 @@ void * drm_create_context(int drm_fd)
41 if (!(context->pixman = wld_pixman_create_context()))
42 goto error1;
43
44+ context_initialize(&context->base, &context_impl);
45 context->fd = drm_fd;
46
47 if (!draw_initialized)
48@@ -80,7 +87,7 @@ void * drm_create_context(int drm_fd)
49 draw_initialized = true;
50 }
51
52- return context;
53+ return &context->base;
54
55 error1:
56 free(context);
57@@ -88,14 +95,6 @@ void * drm_create_context(int drm_fd)
58 return NULL;
59 }
60
61-void drm_destroy_context(void * base)
62-{
63- struct dumb_context * context = base;
64-
65- wld_pixman_destroy_context(context->pixman);
66- free(context);
67-}
68-
69 static struct wld_drawable * new_drawable(struct dumb_context * context,
70 uint32_t width, uint32_t height,
71 uint32_t format, uint32_t handle,
72@@ -141,11 +140,11 @@ static struct wld_drawable * new_drawable(struct dumb_context * context,
73 return NULL;
74 }
75
76-struct wld_drawable * drm_create_drawable(void * base,
77- uint32_t width, uint32_t height,
78- uint32_t format)
79+struct wld_drawable * context_create_drawable(struct wld_context * base,
80+ uint32_t width, uint32_t height,
81+ uint32_t format)
82 {
83- struct dumb_context * context = base;
84+ struct dumb_context * context = dumb_context(base);
85 struct wld_drawable * drawable;
86 struct drm_mode_create_dumb create_dumb_arg = {
87 .height = height, .width = width,
88@@ -178,33 +177,32 @@ struct wld_drawable * drm_create_drawable(void * base,
89 return NULL;
90 }
91
92-struct wld_drawable * drm_import(void * base, uint32_t width, uint32_t height,
93- uint32_t format, int prime_fd,
94- unsigned long pitch)
95+struct wld_drawable * context_import(struct wld_context * base,
96+ uint32_t type, union wld_object object,
97+ uint32_t width, uint32_t height,
98+ uint32_t format, uint32_t pitch)
99 {
100- struct dumb_context * context = base;
101- int ret;
102+ struct dumb_context * context = dumb_context(base);
103 uint32_t handle;
104
105- ret = drmPrimeFDToHandle(context->fd, prime_fd, &handle);
106-
107- if (ret != 0)
108- goto error0;
109+ switch (type)
110+ {
111+ case WLD_DRM_OBJECT_PRIME_FD:
112+ if (drmPrimeFDToHandle(context->fd, object.i, &handle) != 0)
113+ return NULL;
114+ break;
115+ default: return NULL;
116+ }
117
118 return new_drawable(context, width, height, format, handle, pitch);
119-
120- error0:
121- return NULL;
122 }
123
124-struct wld_drawable * drm_import_gem(void * context,
125- uint32_t width, uint32_t height,
126- uint32_t format,
127- uint32_t gem_name, unsigned long pitch)
128+void context_destroy(struct wld_context * base)
129 {
130- DEBUG("dumb: import_gem is not supported\n");
131+ struct dumb_context * context = dumb_context(base);
132
133- return NULL;
134+ wld_destroy_context(context->pixman);
135+ free(context);
136 }
137
138 static int drawable_export(struct wld_drawable * drawable)
M
intel.c
+48,
-38
1@@ -22,6 +22,7 @@
2 */
3
4 #include "drm-private.h"
5+#include "drm.h"
6 #include "wld-private.h"
7
8 #include <unistd.h>
9@@ -31,6 +32,7 @@
10
11 struct intel_context
12 {
13+ struct wld_context base;
14 drm_intel_bufmgr * bufmgr;
15 struct intel_batch * batch;
16 };
17@@ -44,16 +46,18 @@ struct intel_drawable
18 pixman_image_t * virtual;
19 };
20
21+#include "interface/context.h"
22 #define DRM_DRIVER_NAME intel
23 #include "interface/drm.h"
24 #include "interface/drm_drawable.h"
25+IMPL(intel, context)
26
27 bool drm_device_supported(uint32_t vendor_id, uint32_t device_id)
28 {
29 return vendor_id == 0x8086;
30 }
31
32-void * drm_create_context(int drm_fd)
33+struct wld_context * drm_create_context(int drm_fd)
34 {
35 struct intel_context * context;
36
37@@ -62,6 +66,7 @@ void * drm_create_context(int drm_fd)
38 if (!context)
39 goto error0;
40
41+ context_initialize(&context->base, &context_impl);
42 context->bufmgr = drm_intel_bufmgr_gem_init(drm_fd, INTEL_BATCH_SIZE);
43
44 if (!context->bufmgr)
45@@ -72,7 +77,7 @@ void * drm_create_context(int drm_fd)
46 if (!context->batch)
47 goto error2;
48
49- return context;
50+ return &context->base;
51
52 error2:
53 drm_intel_bufmgr_destroy(context->bufmgr);
54@@ -82,15 +87,6 @@ void * drm_create_context(int drm_fd)
55 return NULL;
56 }
57
58-void drm_destroy_context(void * base)
59-{
60- struct intel_context * context = base;
61-
62- intel_batch_destroy(context->batch);
63- drm_intel_bufmgr_destroy(context->bufmgr);
64- free(context);
65-}
66-
67 static struct intel_drawable * new_drawable(struct intel_context * context,
68 uint32_t width, uint32_t height,
69 uint32_t format)
70@@ -110,11 +106,11 @@ static struct intel_drawable * new_drawable(struct intel_context * context,
71 return intel;
72 }
73
74-struct wld_drawable * drm_create_drawable(void * base,
75- uint32_t width, uint32_t height,
76- uint32_t format)
77+struct wld_drawable * context_create_drawable(struct wld_context * base,
78+ uint32_t width, uint32_t height,
79+ uint32_t format)
80 {
81- struct intel_context * context = base;
82+ struct intel_context * context = intel_context(base);
83 struct intel_drawable * intel;
84 uint32_t tiling_mode = width >= 128 ? I915_TILING_X : I915_TILING_NONE;
85
86@@ -128,41 +124,55 @@ struct wld_drawable * drm_create_drawable(void * base,
87 return &intel->base;
88 }
89
90-struct wld_drawable * drm_import(void * base,
91- uint32_t width, uint32_t height,
92- uint32_t format,
93- int prime_fd, unsigned long pitch)
94+struct wld_drawable * context_import(struct wld_context * base,
95+ uint32_t type, union wld_object object,
96+ uint32_t width, uint32_t height,
97+ uint32_t format, uint32_t pitch)
98 {
99- struct intel_context * context = base;
100+ struct intel_context * context = intel_context(base);
101 struct intel_drawable * intel;
102- uint32_t size = width * height * 4;
103+ drm_intel_bo * bo;
104+
105+ switch (type)
106+ {
107+ case WLD_DRM_OBJECT_PRIME_FD:
108+ {
109+ uint32_t size = width * height * format_bytes_per_pixel(format);
110+ bo = drm_intel_bo_gem_create_from_prime(context->bufmgr,
111+ object.i, size);
112+ break;
113+ }
114+ case WLD_DRM_OBJECT_GEM_NAME:
115+ bo = drm_intel_bo_gem_create_from_name(context->bufmgr, "buffer",
116+ object.u32);
117+ break;
118+ default: bo = NULL;
119+ };
120+
121+ if (!bo)
122+ goto error0;
123
124 if (!(intel = new_drawable(context, width, height, format)))
125- return NULL;
126+ goto error1;
127
128- intel->bo = drm_intel_bo_gem_create_from_prime(context->bufmgr,
129- prime_fd, size);
130+ intel->bo = bo;
131 intel->base.pitch = pitch;
132
133 return &intel->base;
134+
135+ error1:
136+ drm_intel_bo_unreference(bo);
137+ error0:
138+ return NULL;
139 }
140
141-struct wld_drawable * drm_import_gem(void * base,
142- uint32_t width, uint32_t height,
143- uint32_t format,
144- uint32_t gem_name, unsigned long pitch)
145+void context_destroy(struct wld_context * base)
146 {
147- struct intel_context * context = base;
148- struct intel_drawable * intel;
149+ struct intel_context * context = intel_context(base);
150
151- if (!(intel = new_drawable(context, width, height, format)))
152- return NULL;
153-
154- intel->bo = drm_intel_bo_gem_create_from_name(context->bufmgr, "drawable",
155- gem_name);
156- intel->base.pitch = pitch;
157-
158- return &intel->base;
159+ intel_batch_destroy(context->batch);
160+ drm_intel_bufmgr_destroy(context->bufmgr);
161+ free(context);
162 }
163
164 void drawable_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
+37,
-0
1@@ -0,0 +1,37 @@
2+/* wld: interface/context.h
3+ *
4+ * Copyright (c) 2013 Michael Forney
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+static struct wld_drawable * context_create_drawable
26+ (struct wld_context * context,
27+ uint32_t width, uint32_t height, uint32_t format);
28+static struct wld_drawable * context_import
29+ (struct wld_context * context, uint32_t type, union wld_object object,
30+ uint32_t width, uint32_t height, uint32_t format, uint32_t pitch);
31+static void context_destroy(struct wld_context * context);
32+
33+static const struct wld_context_impl context_impl = {
34+ .create_drawable = &context_create_drawable,
35+ .import = &context_import,
36+ .destroy = &context_destroy
37+};
38+
+1,
-16
1@@ -27,28 +27,13 @@
2
3 /* DRM implementation */
4 static bool drm_device_supported(uint32_t vendor_id, uint32_t device_id);
5-static void * drm_create_context(int drm_fd);
6-static void drm_destroy_context(void * context);
7-static struct wld_drawable * drm_create_drawable
8- (void * context, uint32_t width, uint32_t height, uint32_t format);
9-static struct wld_drawable * drm_import(void * context,
10- uint32_t width, uint32_t height,
11- uint32_t format, int prime_fd,
12- unsigned long pitch);
13-static struct wld_drawable * drm_import_gem(void * context,
14- uint32_t width, uint32_t height,
15- uint32_t format, uint32_t gem_name,
16- unsigned long pitch);
17+static struct wld_context * drm_create_context(int drm_fd);
18
19 #define EXPAND(f, x) f(x)
20 #define VAR(name) name ## _drm
21 const struct wld_drm_interface EXPAND(VAR, DRM_DRIVER_NAME) = {
22 .device_supported = &drm_device_supported,
23 .create_context = &drm_create_context,
24- .destroy_context = &drm_destroy_context,
25- .create_drawable = &drm_create_drawable,
26- .import = &drm_import,
27- .import_gem = &drm_import_gem,
28 };
29 #undef VAR
30 #undef EXPAND
+3,
-3
1@@ -26,19 +26,19 @@
2
3 #include "wld.h"
4
5-struct wld_pixman_context;
6+struct wld_context;
7
8 struct pixman_drawable
9 {
10 struct wld_drawable base;
11 pixman_image_t * image;
12- struct wld_pixman_context * context;
13+ struct pixman_context * context;
14 };
15
16 extern const struct wld_draw_interface * const pixman_draw;
17
18 bool pixman_initialize_drawable
19- (struct wld_pixman_context * context, struct pixman_drawable * drawable,
20+ (struct wld_context * context, struct pixman_drawable * drawable,
21 uint32_t width, uint32_t height,
22 void * data, uint32_t pitch, uint32_t format);
23
M
pixman.c
+79,
-25
1@@ -32,20 +32,22 @@
2 .blue = ((c >> 0) & 0xff) * 0x101, \
3 }
4
5-struct wld_pixman_context
6+struct pixman_context
7 {
8+ struct wld_context base;
9 pixman_glyph_cache_t * glyph_cache;
10 };
11
12+#include "interface/context.h"
13 #define DRAWABLE_IMPLEMENTS_REGION
14 #include "interface/drawable.h"
15
16 const struct wld_draw_interface * const pixman_draw = &draw_interface;
17
18 EXPORT
19-struct wld_pixman_context * wld_pixman_create_context()
20+struct wld_context * wld_pixman_create_context()
21 {
22- struct wld_pixman_context * context;
23+ struct pixman_context * context;
24
25 if (!(context = malloc(sizeof *context)))
26 goto error0;
27@@ -53,7 +55,7 @@ struct wld_pixman_context * wld_pixman_create_context()
28 if (!(context->glyph_cache = pixman_glyph_cache_create()))
29 goto error1;
30
31- return context;
32+ return &context->base;
33
34 error1:
35 free(context);
36@@ -61,15 +63,8 @@ struct wld_pixman_context * wld_pixman_create_context()
37 return NULL;
38 }
39
40-EXPORT
41-void wld_pixman_destroy_context(struct wld_pixman_context * context)
42-{
43- pixman_glyph_cache_destroy(context->glyph_cache);
44- free(context);
45-}
46-
47 bool pixman_initialize_drawable
48- (struct wld_pixman_context * context, struct pixman_drawable * drawable,
49+ (struct wld_context * context, struct pixman_drawable * drawable,
50 uint32_t width, uint32_t height,
51 void * data, uint32_t pitch, uint32_t format)
52 {
53@@ -79,7 +74,7 @@ bool pixman_initialize_drawable
54 drawable->base.format = format;
55 drawable->base.pitch = pitch;
56
57- drawable->context = context;
58+ drawable->context = (void *) context;
59 drawable->image = pixman_image_create_bits(format_wld_to_pixman(format),
60 width, height,
61 (uint32_t *) data, pitch);
62@@ -87,30 +82,89 @@ bool pixman_initialize_drawable
63 return drawable->image != NULL;
64 }
65
66-EXPORT
67-struct wld_drawable * wld_pixman_create_drawable
68- (struct wld_pixman_context * context, uint32_t width, uint32_t height,
69- void * data, uint32_t pitch, uint32_t format)
70+struct wld_drawable * new_drawable(struct pixman_context * context,
71+ pixman_image_t * image)
72+{
73+ struct pixman_drawable * drawable;
74+
75+ if (!(drawable = malloc(sizeof *drawable)))
76+ return NULL;
77+
78+ drawable->base.interface = &draw_interface;
79+ drawable->base.width = pixman_image_get_width(image);
80+ drawable->base.height = pixman_image_get_height(image);
81+ drawable->base.format = format_pixman_to_wld
82+ (pixman_image_get_format(image));
83+ drawable->base.pitch = pixman_image_get_stride(image);
84+ drawable->context = context;
85+ drawable->image = image;
86+
87+ return &drawable->base;
88+}
89+
90+struct wld_drawable * context_create_drawable(struct wld_context * base,
91+ uint32_t width, uint32_t height,
92+ uint32_t format)
93 {
94- struct pixman_drawable * pixman;
95+ struct pixman_context * context = (void *) base;
96+ struct wld_drawable * drawable;
97+ pixman_image_t * image;
98
99- pixman = malloc(sizeof *pixman);
100+ image = pixman_image_create_bits(format_wld_to_pixman(format),
101+ width, height, NULL, 0);
102
103- if (!pixman)
104+ if (!image)
105 goto error0;
106
107- if (!pixman_initialize_drawable(context, pixman, width, height,
108- data, pitch, format))
109- {
110+ if (!(drawable = new_drawable(context, image)))
111 goto error1;
112+
113+ return drawable;
114+
115+ error1:
116+ pixman_image_unref(image);
117+ error0:
118+ return NULL;
119+}
120+
121+struct wld_drawable * context_import
122+ (struct wld_context * base, uint32_t type, union wld_object object,
123+ uint32_t width, uint32_t height, uint32_t format, uint32_t pitch)
124+{
125+ struct pixman_context * context = (void *) base;
126+ struct wld_drawable * drawable;
127+ pixman_image_t * image;
128+
129+ switch (type)
130+ {
131+ case WLD_OBJECT_DATA:
132+ image = pixman_image_create_bits(format_wld_to_pixman(format),
133+ width, height, object.ptr, pitch);
134+ break;
135+ default: image = NULL;
136 }
137
138- return &pixman->base;
139+ if (!image)
140+ goto error0;
141+
142+ if (!(drawable = new_drawable(context, image)))
143+ goto error1;
144+
145+ return drawable;
146
147 error1:
148- free(pixman);
149+ pixman_image_unref(image);
150 error0:
151 return NULL;
152+
153+}
154+
155+void context_destroy(struct wld_context * base)
156+{
157+ struct pixman_context * context = (void *) base;
158+
159+ pixman_glyph_cache_destroy(context->glyph_cache);
160+ free(context);
161 }
162
163 void drawable_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
M
pixman.h
+2,
-17
1@@ -26,28 +26,13 @@
2
3 #include <stdint.h>
4
5-struct wld_pixman_context;
6-struct wld_drawable;
7+struct wld_context;
8
9 /**
10 * Create a new drawing context which uses Pixman to do software rendering on
11 * buffers in memory.
12 */
13-struct wld_pixman_context * wld_pixman_create_context();
14-
15-/**
16- * Destroy a Pixman context.
17- */
18-void wld_pixman_destroy_context(struct wld_pixman_context * context);
19-
20-/**
21- * Create a new Pixman drawable with the specified dimensions.
22- *
23- * If data is NULL, new backing memory will be allocated.
24- */
25-struct wld_drawable * wld_pixman_create_drawable
26- (struct wld_pixman_context * context, uint32_t width, uint32_t height,
27- void * data, uint32_t pitch, uint32_t format);
28+struct wld_context * wld_pixman_create_context();
29
30 #endif
31
+7,
-8
1@@ -39,8 +39,7 @@
2
3 struct wld_wayland_drm_context
4 {
5- struct wld_drm_context context;
6-
7+ struct wld_context * driver_context;
8 struct wl_drm * wl;
9 struct wl_registry * registry;
10 struct wl_array formats;
11@@ -141,7 +140,7 @@ struct wld_wayland_drm_context * wld_wayland_drm_create_context
12 goto error4;
13 }
14
15- if (!drm_initialize_context(&drm->context, drm->fd))
16+ if (!(drm->driver_context = wld_drm_create_context(drm->fd)))
17 {
18 DEBUG("Couldn't initialize context for DRM device\n");
19 goto error4;
20@@ -165,7 +164,7 @@ struct wld_wayland_drm_context * wld_wayland_drm_create_context
21 EXPORT
22 void wld_wayland_drm_destroy_context(struct wld_wayland_drm_context * drm)
23 {
24- drm_finalize_context(&drm->context);
25+ wld_destroy_context(&drm->driver_context);
26 close(drm->fd);
27 wl_drm_destroy(drm->wl);
28 wl_registry_destroy(drm->registry);
29@@ -205,17 +204,17 @@ struct wld_drawable * wld_wayland_drm_create_drawable
30 if (buffer && !wld_wayland_drm_has_format(drm, format))
31 return NULL;
32
33- drawable = wld_drm_create_drawable(&drm->context, width, height, format);
34+ drawable = wld_create_drawable(drm->driver_context, width, height, format);
35
36 if (!drawable)
37 return NULL;
38
39 if (buffer)
40 {
41- int prime_fd;
42+ union wld_object object;
43
44- prime_fd = wld_drm_export(drawable);
45- *buffer = wl_drm_create_prime_buffer(drm->wl, prime_fd,
46+ wld_export(drawable, WLD_DRM_OBJECT_PRIME_FD, &object);
47+ *buffer = wl_drm_create_prime_buffer(drm->wl, object.i,
48 width, height, format,
49 0, drawable->pitch, 0, 0, 0, 0);
50 close(prime_fd);
+6,
-4
1@@ -42,7 +42,7 @@ struct wld_shm_context
2 struct wl_shm * wl;
3 struct wl_array formats;
4
5- struct wld_pixman_context * pixman_context;
6+ struct wld_context * pixman_context;
7 };
8
9 static void registry_global(void * data, struct wl_registry * registry,
10@@ -137,7 +137,7 @@ struct wld_shm_context * wld_shm_create_context(struct wl_display * display,
11 EXPORT
12 void wld_shm_destroy_context(struct wld_shm_context * shm)
13 {
14- wld_pixman_destroy_context(shm->pixman_context);
15+ wld_destroy_context(shm->pixman_context);
16 wl_shm_destroy(shm->wl);
17 wl_registry_destroy(shm->registry);
18 wl_array_release(&shm->formats);
19@@ -173,6 +173,7 @@ struct wld_drawable * wld_shm_create_drawable(struct wld_shm_context * shm,
20 struct wl_shm_pool * pool;
21 struct wld_drawable * drawable;
22 uint32_t shm_format = wayland_format(format);
23+ union wld_object object;
24
25 fd = mkostemp(name, O_CLOEXEC);
26
27@@ -189,8 +190,9 @@ struct wld_drawable * wld_shm_create_drawable(struct wld_shm_context * shm,
28 if (data == MAP_FAILED)
29 goto error1;
30
31- drawable = wld_pixman_create_drawable(shm->pixman_context, width, height,
32- data, pitch, format);
33+ object.ptr = data;
34+ drawable = wld_import(shm->pixman_context, WLD_OBJECT_DATA, object,
35+ width, height, format, pitch);
36
37 pool = wl_shm_create_pool(shm->wl, fd, size);
38 *buffer = wl_shm_pool_create_buffer(pool, 0, width, height, pitch,
+28,
-0
1@@ -83,6 +83,18 @@ struct font
2 struct glyph ** glyphs;
3 };
4
5+struct wld_context_impl
6+{
7+ struct wld_drawable * (* create_drawable)(struct wld_context * context,
8+ uint32_t width, uint32_t height,
9+ uint32_t format);
10+ struct wld_drawable * (* import)(struct wld_context * context,
11+ uint32_t type, union wld_object object,
12+ uint32_t width, uint32_t height,
13+ uint32_t format, uint32_t pitch);
14+ void (* destroy)(struct wld_context * context);
15+};
16+
17 struct wld_draw_interface
18 {
19 void (* fill_rectangle)(struct wld_drawable * drawable, uint32_t color,
20@@ -140,6 +152,19 @@ static inline pixman_format_code_t format_wld_to_pixman(uint32_t format)
21 }
22 }
23
24+static inline uint32_t format_pixman_to_wld(pixman_format_code_t format)
25+{
26+ switch (format)
27+ {
28+ case PIXMAN_a8r8g8b8:
29+ return WLD_FORMAT_ARGB8888;
30+ case PIXMAN_x8r8g8b8:
31+ return WLD_FORMAT_XRGB8888;
32+ default:
33+ return 0;
34+ }
35+}
36+
37 /**
38 * This default fill_region method is implemented in terms of fill_rectangle.
39 */
40@@ -153,5 +178,8 @@ void default_copy_region(struct wld_drawable * src, struct wld_drawable * dst,
41 pixman_region32_t * region,
42 int32_t dst_x, int32_t dst_y);
43
44+void context_initialize(struct wld_context * context,
45+ const struct wld_context_impl * impl);
46+
47 #endif
48
M
wld.h
+30,
-0
1@@ -47,6 +47,36 @@ enum wld_format
2
3 bool wld_lookup_named_color(const char * name, uint32_t * color);
4
5+/**** WLD Context ****/
6+
7+enum wld_object_type
8+{
9+ WLD_OBJECT_DATA = 0x0
10+};
11+
12+union wld_object
13+{
14+ void * ptr;
15+ uint32_t u32;
16+ int i;
17+};
18+
19+struct wld_context
20+{
21+ const struct wld_context_impl * const impl;
22+};
23+
24+struct wld_drawable * wld_create_drawable(struct wld_context * context,
25+ uint32_t width, uint32_t height,
26+ uint32_t format);
27+
28+struct wld_drawable * wld_import(struct wld_context * context, uint32_t type,
29+ union wld_object object,
30+ uint32_t width, uint32_t height,
31+ uint32_t format, uint32_t pitch);
32+
33+void wld_destroy_context(struct wld_context * context);
34+
35 /**** Font Handling ****/
36
37 struct wld_extents