Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6865 serge 1
#include 
2
#include 
3
#include "pxdraw.h"
4
#include "internal.h"
5
 
6
ctx_t* create_context(int x, int y, int width, int height)
7
{
8
	ctx_t *ctx;
9
 
10
	ctx = malloc(sizeof(ctx_t));
11
	if (ctx == NULL)
12
        goto err_0;
13
 
14
    ctx->pitch = ALIGN(width * sizeof(color_t), 16);
15
    ctx->size = ALIGN(ctx->pitch * height, 4096);
16
 
17
    ctx->buffer = user_alloc(ctx->size+4096);
18
    if (ctx->buffer == NULL)
19
        goto err_1;
20
 
21
	ctx->x = x;
22
	ctx->y = y;
23
	ctx->width = width;
24
	ctx->height = height;
25
 
26
	ctx->rc.l = 0;
27
	ctx->rc.t = 0;
28
	ctx->rc.r = width;
29
	ctx->rc.b = height;
30
 
31
	ctx->rcu.l = 0;
32
	ctx->rcu.t = 0;
33
	ctx->rcu.r = ctx->width;
34
	ctx->rcu.b = ctx->height;
35
    ctx->dirty = 1;
36
 
37
    __builtin_cpu_init ();
38
    if (__builtin_cpu_supports ("sse2"))
39
        ctx->px_rect_simd = px_rect_xmm;
40
    else if (__builtin_cpu_supports ("mmx"))
41
        ctx->px_rect_simd = px_rect_mmx;
42
    else
43
        ctx->px_rect_simd = px_rect_alu;
44
 
45
    if (__builtin_cpu_supports ("sse2"))
46
		ctx->px_glyph = px_glyph_sse;
47
	else
48
        ctx->px_glyph = px_glyph_alu;
49
 
50
	return ctx;
51
 
52
err_1:
53
    free(ctx);
54
err_0:
55
    return NULL;
56
};
57
 
58
int resize_context(ctx_t *ctx, int width, int height)
59
{
60
    int size;
61
    int pitch;
62
 
63
    pitch = ALIGN(width * sizeof(color_t), 16);
64
    size = ALIGN(pitch * height, 4096);
65
 
66
    if (size > ctx->size)
67
    {
68
        ctx->buffer = user_realloc(ctx->buffer, size);    /* grow buffer */
69
        if (ctx->buffer == NULL)
70
            return -1;
71
 
72
        ctx->size = size;
73
    }
74
    else if (size < ctx->size)
75
        user_unmap(ctx->buffer, size, ctx->size - size); /* unmap unused pages */
76
 
77
    ctx->width  = width;
78
    ctx->height = height;
79
    ctx->pitch  = pitch;
80
 
81
    ctx->rc.l   = 0;
82
    ctx->rc.t   = 0;
83
    ctx->rc.r   = width;
84
    ctx->rc.b   = height;
85
 
86
    ctx->rcu.l  = ctx->rcu.t = 0;
87
    ctx->rcu.r  = ctx->rcu.b = 0;
88
 
89
    return 0;
90
};
91
 
92
void clear_context(ctx_t *ctx, color_t color)
93
{
94
	size_t size;
95
 
96
	size = ctx->pitch * ctx->height;
97
 
98
	if (size >= 1024)
99
		ctx->px_rect_simd(ctx->buffer, ctx->pitch, ctx->width, ctx->height, color);
100
	else
101
		px_rect_alu(ctx->buffer, ctx->pitch, ctx->width, ctx->height, color);
102
 
103
	ctx->rcu.l = 0;
104
	ctx->rcu.t = 0;
105
	ctx->rcu.r = ctx->width;
106
	ctx->rcu.b = ctx->height;
107
    ctx->dirty = 1;
108
};
109
 
110
void show_context(ctx_t *ctx)
111
{
112
    struct blit_call bc;
113
    int ret;
114
 
115
    bc.dstx   = ctx->x;
116
    bc.dsty   = ctx->y;
117
    bc.w      = ctx->width;
118
    bc.h      = ctx->height;
119
    bc.srcx   = 0;
120
    bc.srcy   = 0;
121
    bc.srcw   = ctx->width;
122
    bc.srch   = ctx->height;
123
    bc.stride = ctx->pitch;
124
    bc.bitmap = ctx->buffer;
125
 
126
    __asm__ __volatile__(
127
    "int $0x40":"=a"(ret):"a"(73), "b"(0x00),
128
    "c"(&bc):"memory");
129
 
130
    ctx->dirty = 0;
131
};
132
 
133
void scroll_context(ctx_t *ctx, int dst_y, int  src_y, int rows)
134
{
135
    char *dst;
136
    char *src;
137
 
138
    dst = ctx->buffer + dst_y * ctx->pitch;
139
    src = ctx->buffer + src_y * ctx->pitch;
140
 
141
    __builtin_memmove(dst, src, rows * ctx->pitch);
142
    ctx->dirty = 1;
143
}
144
 
145
static int clip_rect(const rect_t *clip, rect_t *rc)
146
{
147
	if (rc->l > rc->r)
148
		return 1;
149
	if (rc->t > rc->b)
150
		return 1;
151
 
152
	if (rc->l < clip->l)
153
		rc->l = clip->l;
154
	else if (rc->l >= clip->r)
155
		return 1;
156
 
157
	if (rc->t < clip->t)
158
		rc->t = clip->t;
159
	else if (rc->t >= clip->b)
160
		return 1;
161
 
162
	if (rc->r < clip->l)
163
		return 1;
164
	else if (rc->r > clip->r)
165
		rc->r = clip->r;
166
 
167
	if (rc->b < clip->t)
168
		return 1;
169
	else if (rc->b > clip->b)
170
		rc->b = clip->b;
171
 
172
	if ((rc->l == rc->r) ||
173
		(rc->t == rc->b))
174
		return 1;
175
	return 0;
176
}
177
 
178
int px_hline(ctx_t*ctx, int x, int y, int width, color_t color)
179
{
180
    char *dst_addr;
181
 
182
    int xr = x + width;
183
 
184
    if(y < ctx->rc.t)
185
        return 0;
186
    else if(y >= ctx->rc.b)
187
        return 0;
188
 
189
    if(x < ctx->rc.l)
190
        x = ctx->rc.l;
191
    else if(x >= ctx->rc.r)
192
        return 0;
193
 
194
    if(xr <= ctx->rc.l)
195
        return 0;
196
    else if(xr > ctx->rc.r)
197
        xr = ctx->rc.r;
198
 
199
    dst_addr = ctx->buffer;
200
    dst_addr+= ctx->pitch * y + x * sizeof(color_t);
201
 
202
    __asm__ __volatile__
203
    (" cld; rep stosl\n\t"
204
      :: "D" (dst_addr),"c" (xr-x), "a" (color)
205
      : "flags");
206
};
207
 
208
void px_vline(ctx_t*ctx, int x, int y, int height, color_t color)
209
{
210
    char *dst_addr;
211
 
212
    int yb = y + height;
213
 
214
    if(x < ctx->rc.l)
215
        return;
216
    else if(x >= ctx->rc.r)
217
        return;
218
 
219
    if(y < ctx->rc.t)
220
        y = ctx->rc.t;
221
    else if(y >= ctx->rc.b)
222
        return;
223
 
224
    if(yb <= ctx->rc.t)
225
        return;
226
    else if(yb > ctx->rc.b)
227
        yb = ctx->rc.b;
228
 
229
    dst_addr = ctx->buffer;
230
    dst_addr+= ctx->pitch * y + x * sizeof(color_t);
231
 
232
    while(y < yb)
233
    {
234
        color_t *t = (color_t*)dst_addr;
235
        *t = color;
236
        y++;
237
        dst_addr+= ctx->pitch;
238
    };
239
};
240
 
241
static int do_fill_rect(ctx_t *ctx, rect_t *rc, color_t color)
242
{
243
	if (!clip_rect(&ctx->rc, rc))
244
	{
245
		int w, h;
246
		char *dst_addr;
247
 
248
		w = rc->r - rc->l;
249
		h = rc->b - rc->t;
250
 
251
		dst_addr = ctx->buffer;
252
		dst_addr += ctx->pitch * rc->t + rc->l * sizeof(color_t);
253
		if (w * h >= 256)
254
			ctx->px_rect_simd(dst_addr, ctx->pitch, w, h, color);
255
		else
256
			px_rect_alu(dst_addr, ctx->pitch, w, h, color);
257
		return 1;
258
	};
259
	return 0;
260
};
261
 
262
void px_fill_rect(ctx_t *ctx, const rect_t *src, color_t color)
263
{
264
	rect_t rc = *src;
265
	int update;
266
 
267
	update = do_fill_rect(ctx, &rc, color);
268
 
269
	if(update)
270
	{
271
		if (rc.l < ctx->rcu.l)
272
			ctx->rcu.l = rc.l;
273
		if (rc.t < ctx->rcu.t)
274
			ctx->rcu.t = rc.t;
275
		if (rc.r > ctx->rcu.r)
276
			ctx->rcu.r = rc.r;
277
		if (rc.b > ctx->rcu.b)
278
			ctx->rcu.b = rc.b;
279
        ctx->dirty = 1;
280
	};
281
}
282
 
283
void px_fill_region(ctx_t *ctx, const rgn_t *rgn, color_t color)
284
{
285
	int update = 0;
286
 
287
	for (int i = 0; i < rgn->num_rects; i++)
288
	{
289
		rect_t rc = rgn->rects[i];
290
		update |= do_fill_rect(ctx, &rc, color);
291
	}
292
 
293
	if (update)
294
	{
295
		if (rgn->extents.l < ctx->rcu.l)
296
			ctx->rcu.l = rgn->extents.l;
297
		if (rgn->extents.t < ctx->rcu.t)
298
			ctx->rcu.t = rgn->extents.t;
299
		if (rgn->extents.r > ctx->rcu.r)
300
			ctx->rcu.r = rgn->extents.r;
301
		if (rgn->extents.b > ctx->rcu.b)
302
			ctx->rcu.b = rgn->extents.b;
303
        ctx->dirty = 1;
304
	};
305
}
306
 
307
void px_draw_glyph(ctx_t *ctx, const void *buffer, int pitch, const rect_t *rc, color_t color)
308
{
309
	rect_t rc_dst = *rc;
310
	int srcx, srcy;
311
 
312
	if (!clip_rect(&ctx->rc, &rc_dst))
313
	{
314
		int width;
315
		int height;
316
		unsigned char *dst = ctx->buffer;
317
		const unsigned char *src = buffer;
318
 
319
		width = rc_dst.r - rc_dst.l;
320
		height = rc_dst.b - rc_dst.t;
321
 
322
		srcx = rc_dst.l - rc->l;
323
		srcy = rc_dst.t - rc->t;
324
		dst += ctx->pitch * rc_dst.t + rc_dst.l * sizeof(color_t);
325
		src += pitch * srcy + srcx;
326
    	ctx->px_glyph(dst, ctx->pitch, src, pitch, width, height, color);
327
 
328
		if (rc_dst.l < ctx->rcu.l)
329
			ctx->rcu.l = rc_dst.l;
330
		if (rc_dst.t < ctx->rcu.t)
331
			ctx->rcu.t = rc_dst.t;
332
		if (rc_dst.r > ctx->rcu.r)
333
			ctx->rcu.r = rc_dst.r;
334
		if (rc_dst.b > ctx->rcu.b)
335
			ctx->rcu.b = rc_dst.b;
336
 
337
        ctx->dirty = 1;
338
	};
339
};