Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1892 Rev 3959
Line 38... Line 38...
38
 */
38
 */
Line 39... Line 39...
39
 
39
 
Line 40... Line 40...
40
#include "cairoint.h"
40
#include "cairoint.h"
-
 
41
 
41
 
42
#include "cairo-error-private.h"
Line 42... Line 43...
42
#include "cairo-error-private.h"
43
#include "cairo-image-surface-private.h"
43
#include "cairo-surface-snapshot-private.h"
44
#include "cairo-surface-snapshot-inline.h"
44
 
45
 
45
static cairo_status_t
46
static cairo_status_t
46
_cairo_surface_snapshot_finish (void *abstract_surface)
47
_cairo_surface_snapshot_finish (void *abstract_surface)
Line -... Line 48...
-
 
48
{
-
 
49
    cairo_surface_snapshot_t *surface = abstract_surface;
47
{
50
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
48
    cairo_surface_snapshot_t *surface = abstract_surface;
51
 
49
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
52
    TRACE ((stderr, "%s\n", __FUNCTION__));
Line 50... Line 53...
50
 
53
 
51
    if (surface->clone != NULL) {
54
    if (surface->clone != NULL) {
Line -... Line 55...
-
 
55
	cairo_surface_finish (surface->clone);
-
 
56
	status = surface->clone->status;
52
	cairo_surface_finish (surface->clone);
57
 
53
	status = surface->clone->status;
58
	cairo_surface_destroy (surface->clone);
Line 54... Line 59...
54
 
59
    }
-
 
60
 
-
 
61
    CAIRO_MUTEX_FINI (surface->mutex);
-
 
62
 
-
 
63
    return status;
-
 
64
}
-
 
65
 
-
 
66
static cairo_status_t
-
 
67
_cairo_surface_snapshot_flush (void *abstract_surface, unsigned flags)
-
 
68
{
-
 
69
    cairo_surface_snapshot_t *surface = abstract_surface;
-
 
70
    cairo_surface_t *target;
-
 
71
    cairo_status_t status;
-
 
72
 
-
 
73
    target = _cairo_surface_snapshot_get_target (&surface->base);
-
 
74
    status = _cairo_surface_flush (target, flags);
-
 
75
    cairo_surface_destroy (target);
-
 
76
 
-
 
77
    return status;
-
 
78
}
-
 
79
 
-
 
80
static cairo_surface_t *
-
 
81
_cairo_surface_snapshot_source (void                    *abstract_surface,
-
 
82
				cairo_rectangle_int_t *extents)
-
 
83
{
-
 
84
    cairo_surface_snapshot_t *surface = abstract_surface;
-
 
85
    return _cairo_surface_get_source (surface->target, extents); /* XXX racy */
-
 
86
}
55
	cairo_surface_destroy (surface->clone);
87
 
56
    }
88
struct snapshot_extra {
57
 
89
    cairo_surface_t *target;
58
    return status;
90
    void *extra;
59
}
91
};
-
 
92
 
-
 
93
static cairo_status_t
-
 
94
_cairo_surface_snapshot_acquire_source_image (void                    *abstract_surface,
-
 
95
					      cairo_image_surface_t  **image_out,
-
 
96
					      void                   **extra_out)
-
 
97
{
Line -... Line 98...
-
 
98
    cairo_surface_snapshot_t *surface = abstract_surface;
60
 
99
    struct snapshot_extra *extra;
-
 
100
    cairo_status_t status;
-
 
101
 
-
 
102
    extra = malloc (sizeof (*extra));
-
 
103
    if (unlikely (extra == NULL))
-
 
104
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
105
 
-
 
106
    extra->target = _cairo_surface_snapshot_get_target (&surface->base);
61
static cairo_status_t
107
    status =  _cairo_surface_acquire_source_image (extra->target, image_out, &extra->extra);
Line 62... Line 108...
62
_cairo_surface_snapshot_acquire_source_image (void                    *abstract_surface,
108
    if (unlikely (status)) {
63
					      cairo_image_surface_t  **image_out,
109
	cairo_surface_destroy (extra->target);
64
					      void                   **extra_out)
110
	free (extra);
65
{
111
    }
66
    cairo_surface_snapshot_t *surface = abstract_surface;
112
 
67
 
113
    *extra_out = extra;
Line 68... Line 114...
68
    return _cairo_surface_acquire_source_image (surface->target, image_out, extra_out);
114
    return status;
-
 
115
}
-
 
116
 
69
}
117
static void
Line 70... Line 118...
70
 
118
_cairo_surface_snapshot_release_source_image (void                   *abstract_surface,
71
static void
119
					      cairo_image_surface_t  *image,
72
_cairo_surface_snapshot_release_source_image (void                   *abstract_surface,
120
					      void                   *_extra)
73
					      cairo_image_surface_t  *image,
121
{
74
					      void                   *extra)
122
    struct snapshot_extra *extra = _extra;
-
 
123
 
-
 
124
    _cairo_surface_release_source_image (extra->target, image, extra->extra);
-
 
125
    cairo_surface_destroy (extra->target);
-
 
126
    free (extra);
-
 
127
}
-
 
128
 
Line 75... Line 129...
75
{
129
static cairo_bool_t
76
    cairo_surface_snapshot_t *surface = abstract_surface;
130
_cairo_surface_snapshot_get_extents (void                  *abstract_surface,
Line 77... Line 131...
77
 
131
				     cairo_rectangle_int_t *extents)
78
    _cairo_surface_release_source_image (surface->target, image, extra);
132
{
-
 
133
    cairo_surface_snapshot_t *surface = abstract_surface;
-
 
134
    cairo_surface_t *target;
Line 79... Line 135...
79
}
135
    cairo_bool_t bounded;
80
 
136
 
-
 
137
    target = _cairo_surface_snapshot_get_target (&surface->base);
-
 
138
    bounded = _cairo_surface_get_extents (target, extents);
Line -... Line 139...
-
 
139
    cairo_surface_destroy (target);
81
static cairo_bool_t
140
 
82
_cairo_surface_snapshot_get_extents (void                  *abstract_surface,
141
    return bounded;
83
				     cairo_rectangle_int_t *extents)
-
 
84
{
-
 
85
    cairo_surface_snapshot_t *surface = abstract_surface;
142
}
86
 
-
 
87
    return _cairo_surface_get_extents (surface->target, extents);
-
 
88
}
-
 
89
 
-
 
-
 
143
 
90
static const cairo_surface_backend_t _cairo_surface_snapshot_backend = {
144
static const cairo_surface_backend_t _cairo_surface_snapshot_backend = {
91
    CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT,
145
    CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT,
-
 
146
    _cairo_surface_snapshot_finish,
92
 
147
    NULL,
-
 
148
 
-
 
149
    NULL, /* create similar */
-
 
150
    NULL, /* create similar image  */
93
    NULL, /* create similar */
151
    NULL, /* map to image */
Line 94... Line 152...
94
    _cairo_surface_snapshot_finish,
152
    NULL, /* unmap image  */
95
 
153
 
96
    _cairo_surface_snapshot_acquire_source_image,
154
    _cairo_surface_snapshot_source,
97
    _cairo_surface_snapshot_release_source_image,
155
    _cairo_surface_snapshot_acquire_source_image,
98
    NULL, NULL, /* acquire, release dest */
156
    _cairo_surface_snapshot_release_source_image,
99
    NULL, /* clone similar */
157
    NULL, /* snapshot */
100
    NULL, /* composite */
158
 
101
    NULL, /* fill rectangles */
159
    NULL, /* copy_page */
Line -... Line 160...
-
 
160
    NULL, /* show_page */
-
 
161
 
-
 
162
    _cairo_surface_snapshot_get_extents,
102
    NULL, /* composite trapezoids */
163
    NULL, /* get-font-options */
103
    NULL, /* create span renderer */
164
 
104
    NULL, /* check span renderer */
165
    _cairo_surface_snapshot_flush,
105
    NULL, /* copy_page */
166
};
106
    NULL, /* show_page */
167
 
Line -... Line 168...
-
 
168
static void
-
 
169
_cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface)
-
 
170
{
-
 
171
    cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface;
-
 
172
    cairo_image_surface_t *image;
-
 
173
    cairo_surface_t *clone;
-
 
174
    void *extra;
-
 
175
    cairo_status_t status;
-
 
176
 
-
 
177
    TRACE ((stderr, "%s: target=%d\n",
-
 
178
	    __FUNCTION__, snapshot->target->unique_id));
-
 
179
 
-
 
180
    /* We need to make an image copy of the original surface since the
-
 
181
     * snapshot may exceed the lifetime of the original device, i.e.
107
    _cairo_surface_snapshot_get_extents,
182
     * when we later need to use the snapshot the data may have already
108
};
183
     * been lost.
109
 
184
     */
110
static void
185
 
111
_cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface)
186
    CAIRO_MUTEX_LOCK (snapshot->mutex);
112
{
-
 
113
    cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface;
-
 
114
    cairo_image_surface_t *image;
-
 
115
    cairo_image_surface_t *clone;
-
 
116
    void *extra;
-
 
117
    cairo_status_t status;
-
 
118
 
-
 
119
    /* We need to make an image copy of the original surface since the
-
 
120
     * snapshot may exceed the lifetime of the original device, i.e.
-
 
121
     * when we later need to use the snapshot the data may have already
-
 
122
     * been lost.
-
 
123
     */
-
 
124
 
-
 
125
    status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra);
-
 
126
    if (unlikely (status)) {
-
 
127
	snapshot->target = _cairo_surface_create_in_error (status);
-
 
128
	status = _cairo_surface_set_error (surface, status);
-
 
129
	return;
-
 
130
    }
-
 
131
 
-
 
132
    clone = (cairo_image_surface_t *)
-
 
133
	_cairo_image_surface_create_with_pixman_format (NULL,
-
 
134
							image->pixman_format,
-
 
135
							image->width,
-
 
136
							image->height,
-
 
137
							0);
187
 
138
    if (likely (clone->base.status == CAIRO_STATUS_SUCCESS)) {
-
 
-
 
188
    if (snapshot->target->backend->snapshot != NULL) {
139
	if (clone->stride == image->stride) {
189
	clone = snapshot->target->backend->snapshot (snapshot->target);
-
 
190
	if (clone != NULL) {
-
 
191
	    assert (clone->status || ! _cairo_surface_is_snapshot (clone));
-
 
192
	    goto done;
140
	    memcpy (clone->data, image->data, image->stride * image->height);
193
	}
141
	} else {
194
    }
-
 
195
 
-
 
196
    /* XXX copy to a similar surface, leave acquisition till later?
142
	    pixman_image_composite32 (PIXMAN_OP_SRC,
197
     * We should probably leave such decisions to the backend in case we
Line 143... Line 198...
143
				      image->pixman_image, NULL, clone->pixman_image,
198
     * rely upon devices/connections like Xlib.
144
				      0, 0,
199
    */
145
				      0, 0,
200
    status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra);
146
				      0, 0,
201
    if (unlikely (status)) {
147
				      image->width, image->height);
202
	snapshot->target = _cairo_surface_create_in_error (status);
148
	}
203
	status = _cairo_surface_set_error (surface, status);
149
	clone->base.is_clear = FALSE;
204
	goto unlock;
Line 182... Line 237...
182
_cairo_surface_snapshot (cairo_surface_t *surface)
237
_cairo_surface_snapshot (cairo_surface_t *surface)
183
{
238
{
184
    cairo_surface_snapshot_t *snapshot;
239
    cairo_surface_snapshot_t *snapshot;
185
    cairo_status_t status;
240
    cairo_status_t status;
Line -... Line 241...
-
 
241
 
-
 
242
    TRACE ((stderr, "%s: target=%d\n", __FUNCTION__, surface->unique_id));
186
 
243
 
187
    if (unlikely (surface->status))
244
    if (unlikely (surface->status))
Line 188... Line 245...
188
	return _cairo_surface_create_in_error (surface->status);
245
	return _cairo_surface_create_in_error (surface->status);
189
 
246
 
Line 190... Line 247...
190
    if (surface->finished)
247
    if (unlikely (surface->finished))
191
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
248
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
Line 192... Line -...
192
 
-
 
193
    if (surface->snapshot_of != NULL)
-
 
194
	return cairo_surface_reference (surface);
-
 
195
 
249
 
196
    if (surface->backend->snapshot != NULL) {
-
 
197
	cairo_surface_t *snap;
250
    if (surface->snapshot_of != NULL)
198
 
-
 
199
	snap = _cairo_surface_has_snapshot (surface, surface->backend);
-
 
200
	if (snap != NULL)
-
 
201
	    return cairo_surface_reference (snap);
-
 
202
 
-
 
203
	snap = surface->backend->snapshot (surface);
-
 
204
	if (snap != NULL) {
-
 
205
	    if (unlikely (snap->status))
-
 
206
		return snap;
-
 
207
 
-
 
208
	    status = _cairo_surface_copy_mime_data (snap, surface);
-
 
209
	    if (unlikely (status)) {
-
 
210
		cairo_surface_destroy (snap);
-
 
211
		return _cairo_surface_create_in_error (status);
-
 
212
	    }
-
 
213
 
-
 
214
	    snap->device_transform = surface->device_transform;
-
 
215
	    snap->device_transform_inverse = surface->device_transform_inverse;
-
 
216
 
-
 
217
	    _cairo_surface_attach_snapshot (surface, snap, NULL);
-
 
Line 218... Line 251...
218
 
251
	return cairo_surface_reference (surface);
219
	    return snap;
252
 
220
	}
253
    if (_cairo_surface_is_snapshot (surface))
221
    }
254
	return cairo_surface_reference (surface);
Line 233... Line 266...
233
			 &_cairo_surface_snapshot_backend,
266
			 &_cairo_surface_snapshot_backend,
234
			 NULL, /* device */
267
			 NULL, /* device */
235
			 surface->content);
268
			 surface->content);
236
    snapshot->base.type = surface->type;
269
    snapshot->base.type = surface->type;
Line -... Line 270...
-
 
270
 
237
 
271
    CAIRO_MUTEX_INIT (snapshot->mutex);
238
    snapshot->target = surface;
272
    snapshot->target = surface;
Line 239... Line 273...
239
    snapshot->clone = NULL;
273
    snapshot->clone = NULL;
240
 
274