main
buffer.c
1/* wld: buffer.c
2 *
3 * Copyright (c) 2013, 2014 Michael Forney
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#include "wld-private.h"
25
26void
27buffer_initialize(struct buffer *buffer,
28 const struct wld_buffer_impl *impl,
29 uint32_t width, uint32_t height,
30 uint32_t format, uint32_t pitch)
31{
32 *((const struct wld_buffer_impl **)&buffer->base.impl) = impl;
33 buffer->base.width = width;
34 buffer->base.height = height;
35 buffer->base.format = format;
36 buffer->base.pitch = pitch;
37 buffer->base.map = NULL;
38 buffer->ref = 1;
39 buffer->map_ref = 0;
40 buffer->exporters = NULL;
41 buffer->destructors = NULL;
42 pixman_region32_init_rect(&buffer->base.damage, 0, 0, width, height);
43}
44
45EXPORT
46bool
47wld_map(struct wld_buffer *base)
48{
49 struct buffer *buffer = (void *)base;
50
51 if (buffer->map_ref == 0 && !buffer->base.impl->map(buffer))
52 return false;
53
54 ++buffer->map_ref;
55 return true;
56}
57
58EXPORT
59bool
60wld_unmap(struct wld_buffer *base)
61{
62 struct buffer *buffer = (void *)base;
63
64 if (buffer->map_ref == 0 || (buffer->map_ref == 1 && !buffer->base.impl->unmap(buffer)))
65 return false;
66
67 --buffer->map_ref;
68 return true;
69}
70
71EXPORT
72bool
73wld_export(struct wld_buffer *base, uint32_t type, union wld_object *object)
74{
75 struct buffer *buffer = (void *)base;
76 struct wld_exporter *exporter;
77
78 for (exporter = buffer->exporters; exporter; exporter = exporter->next) {
79 if (exporter->export(exporter, &buffer->base, type, object))
80 return true;
81 }
82
83 return false;
84}
85
86EXPORT
87void
88wld_buffer_add_exporter(struct wld_buffer *base, struct wld_exporter *exporter)
89{
90 struct buffer *buffer = (void *)base;
91
92 exporter->next = buffer->exporters;
93 buffer->exporters = exporter;
94}
95
96EXPORT
97void
98wld_buffer_add_destructor(struct wld_buffer *base, struct wld_destructor *destructor)
99{
100 struct buffer *buffer = (void *)base;
101
102 destructor->next = buffer->destructors;
103 buffer->destructors = destructor;
104}
105
106EXPORT
107void
108wld_buffer_reference(struct wld_buffer *base)
109{
110 struct buffer *buffer = (void *)base;
111
112 ++buffer->ref;
113}
114
115EXPORT
116void
117wld_buffer_unreference(struct wld_buffer *base)
118{
119 struct buffer *buffer = (void *)base;
120 struct wld_destructor *destructor, *next;
121
122 if (--buffer->ref > 0)
123 return;
124
125 pixman_region32_fini(&buffer->base.damage);
126
127 for (destructor = buffer->destructors; destructor; destructor = next) {
128 next = destructor->next;
129 destructor->destroy(destructor);
130 }
131
132 if (buffer->map_ref > 0)
133 buffer->base.impl->unmap(buffer);
134
135 buffer->base.impl->destroy(buffer);
136}