source: mainline/uspace/lib/draw/surface.c@ b272c67a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b272c67a was ba733e83, checked in by Petr Koupy <petr.koupy@…>, 13 years ago

Improved safety of the optimized pixel transfers.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2011 Martin Decky
3 * Copyright (c) 2012 Petr Koupy
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup draw
31 * @{
32 */
33/**
34 * @file
35 */
36
37#include <malloc.h>
38#include <mem.h>
39#include <as.h>
40#include <assert.h>
41#include "surface.h"
42
43struct surface {
44 surface_flags_t flags;
45
46 surface_coord_t dirty_x_lo;
47 surface_coord_t dirty_x_hi;
48 surface_coord_t dirty_y_lo;
49 surface_coord_t dirty_y_hi;
50
51 pixelmap_t pixmap;
52};
53
54surface_t *surface_create(surface_coord_t width, surface_coord_t height,
55 pixel_t *pixbuf, surface_flags_t flags)
56{
57 surface_t *surface = (surface_t *) malloc(sizeof(surface_t));
58 if (!surface) {
59 return NULL;
60 }
61
62 size_t pixbuf_size = width * height * sizeof(pixel_t);
63
64 if (!pixbuf) {
65 if ((flags & SURFACE_FLAG_SHARED) == SURFACE_FLAG_SHARED) {
66 pixbuf = (pixel_t *) as_area_create(AS_AREA_ANY, pixbuf_size,
67 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
68 if (pixbuf == AS_MAP_FAILED) {
69 free(surface);
70 return NULL;
71 }
72 } else {
73 pixbuf = (pixel_t *) malloc(pixbuf_size);
74 if (pixbuf == NULL) {
75 free(surface);
76 return NULL;
77 }
78 }
79
80 memset(pixbuf, 0, pixbuf_size);
81 }
82
83 surface->flags = flags;
84 surface->pixmap.width = width;
85 surface->pixmap.height = height;
86 surface->pixmap.data = pixbuf;
87
88 surface_reset_damaged_region(surface);
89
90 return surface;
91}
92
93void surface_destroy(surface_t *surface)
94{
95 pixel_t *pixbuf = surface->pixmap.data;
96
97 if ((surface->flags & SURFACE_FLAG_SHARED) == SURFACE_FLAG_SHARED)
98 as_area_destroy((void *) pixbuf);
99 else
100 free(pixbuf);
101
102 free(surface);
103}
104
105bool surface_is_shared(surface_t *surface)
106{
107 return ((surface->flags & SURFACE_FLAG_SHARED) == SURFACE_FLAG_SHARED);
108}
109
110pixel_t *surface_direct_access(surface_t *surface)
111{
112 return surface->pixmap.data;
113}
114
115pixelmap_t *surface_pixmap_access(surface_t *surface)
116{
117 return &surface->pixmap;
118}
119
120void surface_get_resolution(surface_t *surface, surface_coord_t *width, surface_coord_t *height)
121{
122 assert(width);
123 assert(height);
124
125 *width = surface->pixmap.width;
126 *height = surface->pixmap.height;
127}
128
129void surface_get_damaged_region(surface_t *surface, surface_coord_t *x, surface_coord_t *y,
130 surface_coord_t *width, surface_coord_t *height)
131{
132 assert(x);
133 assert(y);
134 assert(width);
135 assert(height);
136
137 *x = surface->dirty_x_lo;
138 *y = surface->dirty_y_lo;
139 *width = surface->dirty_x_lo <= surface->dirty_x_hi ?
140 (surface->dirty_x_hi - surface->dirty_x_lo) + 1 : 0;
141 *height = surface->dirty_y_lo <= surface->dirty_y_hi ?
142 (surface->dirty_y_hi - surface->dirty_y_lo) + 1 : 0;
143}
144
145void surface_add_damaged_region(surface_t *surface, surface_coord_t x, surface_coord_t y,
146 surface_coord_t width, surface_coord_t height)
147{
148 surface->dirty_x_lo = surface->dirty_x_lo > x ? x : surface->dirty_x_lo;
149 surface->dirty_y_lo = surface->dirty_y_lo > y ? y : surface->dirty_y_lo;
150
151 surface_coord_t x_hi = x + width - 1;
152 surface_coord_t y_hi = y + height - 1;
153
154 surface->dirty_x_hi = surface->dirty_x_hi < x_hi ? x_hi : surface->dirty_x_hi;
155 surface->dirty_y_hi = surface->dirty_y_hi < y_hi ? y_hi : surface->dirty_y_hi;
156}
157
158void surface_reset_damaged_region(surface_t *surface)
159{
160 surface->dirty_x_lo = surface->pixmap.width - 1;
161 surface->dirty_x_hi = 0;
162 surface->dirty_y_lo = surface->pixmap.height - 1;
163 surface->dirty_y_hi = 0;
164}
165
166void surface_put_pixel(surface_t *surface, surface_coord_t x, surface_coord_t y, pixel_t pixel)
167{
168 surface->dirty_x_lo = surface->dirty_x_lo > x ? x : surface->dirty_x_lo;
169 surface->dirty_x_hi = surface->dirty_x_hi < x ? x : surface->dirty_x_hi;
170 surface->dirty_y_lo = surface->dirty_y_lo > y ? y : surface->dirty_y_lo;
171 surface->dirty_y_hi = surface->dirty_y_hi < y ? y : surface->dirty_y_hi;
172
173 pixelmap_put_pixel(&surface->pixmap, x, y, pixel);
174}
175
176pixel_t surface_get_pixel(surface_t *surface, surface_coord_t x, surface_coord_t y)
177{
178 return pixelmap_get_pixel(&surface->pixmap, x, y);
179}
180
181/** @}
182 */
Note: See TracBrowser for help on using the repository browser.