BRL-CAD
fb_paged_io.c
Go to the documentation of this file.
1 /* F B _ P A G E D _ I O . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1986-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup fb */
21 /** @{ */
22 /** @file fb_paged_io.c
23  *
24  * Buffered frame buffer IO routines.
25  *
26  */
27 /** @} */
28 
29 #include "common.h"
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 
34 #include "bu/color.h"
35 #include "bu/log.h"
36 #include "fb_private.h"
37 #include "fb.h"
38 
39 
40 #define PAGE_BYTES (63*1024L) /* Max # of bytes/dma. */
41 #define PAGE_PIXELS (((PAGE_BYTES/sizeof(RGBpixel))/ifp->if_width) *ifp->if_width)
42 #define PAGE_SCANS (ifp->if_ppixels/ifp->if_width)
43 
44 #define Malloc_Bomb(_bytes_) \
45  fb_log("\"%s\"(%d) : allocation of %lu bytes failed.\n", \
46  __FILE__, __LINE__, _bytes_)
47 
48 
49 static int
50 _fb_pgout(register fb *ifp)
51 {
52  size_t scans, first_scan;
53 
54  /*fb_log("_fb_pgout(%d)\n", ifp->if_pno);*/
55 
56  if (ifp->if_pno < 0) /* Already paged out, return 1. */
57  return 1;
58 
59  first_scan = ifp->if_pno * PAGE_SCANS;
60  if (first_scan + PAGE_SCANS > (size_t)ifp->if_height)
61  scans = ifp->if_height - first_scan;
62  else
63  scans = PAGE_SCANS;
64 
65  return fb_write(ifp,
66  0,
67  first_scan,
68  ifp->if_pbase,
69  scans * ifp->if_width
70  );
71 }
72 
73 
74 static int
75 _fb_pgin(register fb *ifp, int pageno)
76 {
77  size_t scans, first_scan;
78 
79  /*fb_log("_fb_pgin(%d)\n", pageno);*/
80 
81  /* Set pixel pointer to beginning of page. */
82  ifp->if_pcurp = ifp->if_pbase;
83  ifp->if_pno = pageno;
84  ifp->if_pdirty = 0;
85 
86  first_scan = ifp->if_pno * PAGE_SCANS;
87  if (first_scan + PAGE_SCANS > (size_t)ifp->if_height)
88  scans = ifp->if_height - first_scan;
89  else
90  scans = PAGE_SCANS;
91 
92  return fb_read(ifp,
93  0,
94  first_scan,
95  ifp->if_pbase,
96  scans * ifp->if_width
97  );
98 }
99 
100 
101 static int
102 _fb_pgflush(register fb *ifp)
103 {
104  if (ifp->if_debug & FB_DEBUG_BIO) {
105  fb_log("_fb_pgflush(%p)\n", (void *)ifp);
106  }
107 
108  if (ifp->if_pdirty) {
109  if (_fb_pgout(ifp) <= -1)
110  return -1;
111  ifp->if_pdirty = 0;
112  }
113 
114  return 0;
115 }
116 
117 
118 /**
119  * This initialization routine must be called before any buffered I/O
120  * routines in this file are used.
121  */
122 int
123 fb_ioinit(register fb *ifp)
124 {
125  if (ifp->if_debug & FB_DEBUG_BIO) {
126  fb_log("fb_ioinit(%p)\n", (void *)ifp);
127  }
128 
129  ifp->if_pno = -1; /* Force _fb_pgin() initially. */
130  ifp->if_pixcur = 0L; /* Initialize pixel number. */
131  if (ifp->if_pbase == PIXEL_NULL) {
132  /* Only allocate buffer once. */
133  ifp->if_ppixels = PAGE_PIXELS; /* Pixels/page. */
134  if (ifp->if_ppixels > ifp->if_width * ifp->if_height)
135  ifp->if_ppixels = ifp->if_width * ifp->if_height;
136  if ((ifp->if_pbase = (unsigned char *)malloc(ifp->if_ppixels * sizeof(RGBpixel)))
137  == PIXEL_NULL) {
138  Malloc_Bomb(ifp->if_ppixels * sizeof(RGBpixel));
139  return -1;
140  }
141  }
142  ifp->if_pcurp = ifp->if_pbase; /* Initialize pointer. */
143  ifp->if_pendp = ifp->if_pbase+ifp->if_ppixels*sizeof(RGBpixel);
144  return 0;
145 }
146 
147 
148 int
149 fb_seek(register fb *ifp, int x, int y)
150 {
151  long pixelnum;
152  long pagepixel;
153 
154  if (ifp->if_debug & FB_DEBUG_BIO) {
155  fb_log("fb_seek(%p, %d, %d)\n",
156  (void *)ifp, x, y);
157  }
158 
159  if (x < 0 || y < 0 || x >= ifp->if_width || y >= ifp->if_height) {
160  fb_log("fb_seek: illegal address <%d, %d>.\n", x, y);
161  return -1;
162  }
163  pixelnum = ((long) y * (long) ifp->if_width) + x;
164  pagepixel = (long) ifp->if_pno * ifp->if_ppixels;
165  if (pixelnum < pagepixel || pixelnum >= (pagepixel + ifp->if_ppixels)) {
166  if (ifp->if_pdirty)
167  if (_fb_pgout(ifp) == - 1)
168  return -1;
169  if (_fb_pgin(ifp, (int) (pixelnum / (long) ifp->if_ppixels)) <= -1)
170  return -1;
171  }
172  ifp->if_pixcur = pixelnum;
173  /* Compute new pixel pointer into page. */
174  ifp->if_pcurp = ifp->if_pbase +
175  (ifp->if_pixcur % ifp->if_ppixels)*sizeof(RGBpixel);
176  return 0;
177 }
178 
179 
180 int
181 fb_tell(register fb *ifp, int *xp, int *yp)
182 {
183  *yp = (int) (ifp->if_pixcur / ifp->if_width);
184  *xp = (int) (ifp->if_pixcur % ifp->if_width);
185 
186  if (ifp->if_debug & FB_DEBUG_BIO) {
187  fb_log("fb_tell(%p, %p, %p) => (%4d, %4d)\n",
188  (void *)ifp, (void *)xp, (void *)yp, *xp, *yp);
189  }
190 
191  return 0;
192 }
193 
194 
195 int
196 fb_wpixel(register fb *ifp, unsigned char *pixelp)
197 {
198  if (ifp->if_pno == -1)
199  if (_fb_pgin(ifp, ifp->if_pixcur / ifp->if_ppixels) <= -1)
200  return -1;
201 
202  COPYRGB((ifp->if_pcurp), pixelp);
203  ifp->if_pcurp += sizeof(RGBpixel); /* position in page */
204  ifp->if_pixcur++; /* position in framebuffer */
205  ifp->if_pdirty = 1; /* page referenced (dirty) */
206  if (ifp->if_pcurp >= ifp->if_pendp) {
207  if (_fb_pgout(ifp) <= -1)
208  return -1;
209  ifp->if_pno = -1;
210  }
211  return 0;
212 }
213 
214 
215 int
216 fb_rpixel(register fb *ifp, unsigned char *pixelp)
217 {
218  if (ifp->if_pno == -1)
219  if (_fb_pgin(ifp, ifp->if_pixcur / ifp->if_ppixels) <= -1)
220  return -1;
221 
222  COPYRGB(pixelp, (ifp->if_pcurp));
223  ifp->if_pcurp += sizeof(RGBpixel); /* position in page */
224  ifp->if_pixcur++; /* position in framebuffer */
225  if (ifp->if_pcurp >= ifp->if_pendp) {
226  if (_fb_pgout(ifp) <= -1)
227  return -1;
228  ifp->if_pno = -1;
229  }
230 
231  return 0;
232 }
233 
234 
235 int
236 fb_flush(register fb *ifp)
237 {
238  _fb_pgflush(ifp);
239 
240  /* call device specific flush routine */
241  if ((*ifp->if_flush)(ifp) <= -1)
242  return -1;
243 
244  return 0;
245 }
246 
247 
248 /*
249  * Local Variables:
250  * mode: C
251  * tab-width: 8
252  * indent-tabs-mode: t
253  * c-file-style: "stroustrup"
254  * End:
255  * ex: shiftwidth=4 tabstop=8
256  */
unsigned char RGBpixel[3]
Definition: fb.h:73
void fb_log(const char *fmt,...) _BU_ATTR_PRINTF12
Definition: fb_log.c:42
#define PIXEL_NULL
Definition: fb.h:89
Header file for the BRL-CAD common definitions.
int fb_tell(register fb *ifp, int *xp, int *yp)
Definition: fb_paged_io.c:181
int fb_ioinit(register fb *ifp)
Definition: fb_paged_io.c:123
int fb_rpixel(register fb *ifp, unsigned char *pixelp)
Definition: fb_paged_io.c:216
#define COPYRGB(to, from)
Definition: fb.h:191
long if_ppixels
Sizeof page buffer (pixels).
Definition: fb_private.h:133
#define PAGE_PIXELS
Definition: fb_paged_io.c:41
if(share_geom)
Definition: nmg_mod.c:3829
int fb_flush(register fb *ifp)
Definition: fb_paged_io.c:236
int(* if_flush)(struct fb_internal *ifp)
flush output
Definition: fb_private.h:107
unsigned char * if_pendp
End of page buffer.
Definition: fb_private.h:129
#define PAGE_SCANS
Definition: fb_paged_io.c:42
#define Malloc_Bomb(_bytes_)
Definition: fb_paged_io.c:44
int fb_seek(register fb *ifp, int x, int y)
Definition: fb_paged_io.c:149
ssize_t fb_write(fb *ifp, int x, int y, const unsigned char *pp, size_t count)
Definition: fb_generic.c:276
int fb_wpixel(register fb *ifp, unsigned char *pixelp)
Definition: fb_paged_io.c:196
unsigned char * if_pcurp
Current pointer into page buffer.
Definition: fb_private.h:128
long if_pixcur
Current pixel number in framebuffer.
Definition: fb_private.h:132
int if_pno
Current "page" in memory.
Definition: fb_private.h:130
#define FB_DEBUG_BIO
Definition: fb.h:196
A frame-buffer IO structure.
Definition: fb_private.h:80
int if_width
current values
Definition: fb_private.h:115
int if_pdirty
Page modified flag.
Definition: fb_private.h:131
ssize_t fb_read(fb *ifp, int x, int y, unsigned char *pp, size_t count)
Definition: fb_generic.c:272
int if_debug
Buffered IO debug flag.
Definition: fb_private.h:134
unsigned char * if_pbase
Address of malloc()ed page buffer.
Definition: fb_private.h:127