29
* LCM() and scanLineWidth() are:
31
* Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
33
* Permission to use, copy, modify, distribute, and sell this software and its
34
* documentation for any purpose is hereby granted without fee, provided that
35
* the above copyright notice appear in all copies and that both that copyright
36
* notice and this permission notice appear in supporting documentation, and
37
* that the name of Marc Aurele La France not be used in advertising or
38
* publicity pertaining to distribution of the software without specific,
39
* written prior permission. Marc Aurele La France makes no representations
40
* about the suitability of this software for any purpose. It is provided
41
* "as-is" without express or implied warranty.
43
* MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
44
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
45
* EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
46
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
47
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
48
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
49
* PERFORMANCE OF THIS SOFTWARE.
51
* Copyright 1990,91,92,93 by Thomas Roell, Germany.
52
* Copyright 1991,92,93 by SGCS (Snitily Graphics Consulting Services), USA.
54
* Permission to use, copy, modify, distribute, and sell this software
55
* and its documentation for any purpose is hereby granted without fee,
56
* provided that the above copyright notice appear in all copies and
57
* that both that copyright notice and this permission notice appear
58
* in supporting documentation, and that the name of Thomas Roell nor
59
* SGCS be used in advertising or publicity pertaining to distribution
60
* of the software without specific, written prior permission.
61
* Thomas Roell nor SGCS makes no representations about the suitability
62
* of this software for any purpose. It is provided "as is" without
63
* express or implied warranty.
65
* THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
66
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
67
* FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS BE LIABLE FOR ANY
68
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
69
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
70
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
71
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
75
* Authors: Dirk Hohndel <hohndel@XFree86.Org>
30
76
* David Dawes <dawes@XFree86.Org>
31
77
* Marc La France <tsi@XFree86.Org>
1174
/* Least common multiple */
1176
LCM(unsigned int x, unsigned int y)
1178
unsigned int m = x, n = y, o;
1190
* Given various screen attributes, determine the minimum scanline width such
1191
* that each scanline is server and DDX padded and any pixels with imbedded
1192
* bank boundaries are off-screen. This function returns -1 if such a width
1197
unsigned int xsize, /* pixels */
1198
unsigned int ysize, /* pixels */
1199
unsigned int width, /* pixels */
1200
unsigned long BankSize, /* char's */
1201
PixmapFormatRec *pBankFormat,
1202
unsigned int nWidthUnit /* bits */
1205
unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
1206
unsigned long minBitsPerScanline, maxBitsPerScanline;
1210
if (!nWidthUnit || !pBankFormat)
1213
nBitsPerBank = BankSize * 8;
1214
if (nBitsPerBank % pBankFormat->scanlinePad)
1219
nBitsPerScanlinePadUnit = LCM(pBankFormat->scanlinePad, nWidthUnit);
1221
(((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
1222
nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
1223
width = nBitsPerScanline / pBankFormat->bitsPerPixel;
1225
if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
1229
* Scanlines will be server-pad aligned at this point. They will also be
1230
* a multiple of nWidthUnit bits long. Ensure that pixels with imbedded
1231
* bank boundaries are off-screen.
1233
* It seems reasonable to limit total frame buffer size to 1/16 of the
1234
* theoretical maximum address space size. On a machine with 32-bit
1235
* addresses (to 8-bit quantities) this turns out to be 256MB. Not only
1236
* does this provide a simple limiting condition for the loops below, but
1237
* it also prevents unsigned long wraparounds.
1242
minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
1243
if (minBitsPerScanline > nBitsPerBank)
1249
maxBitsPerScanline =
1250
(((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1);
1251
while (nBitsPerScanline <= maxBitsPerScanline)
1253
unsigned long BankBase, BankUnit;
1255
BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
1257
if (!(BankUnit % nBitsPerScanline))
1260
for (BankBase = BankUnit; ; BankBase += nBitsPerBank)
1264
y = BankBase / nBitsPerScanline;
1268
x = BankBase % nBitsPerScanline;
1269
if (!(x % pBankFormat->bitsPerPixel))
1272
if (x < minBitsPerScanline)
1275
* Skip ahead certain widths by dividing the excess scanline
1278
y *= nBitsPerScanlinePadUnit;
1280
((x + y - 1) / y) * nBitsPerScanlinePadUnit;
1281
width = nBitsPerScanline / pBankFormat->bitsPerPixel;
1285
if (BankBase != BankUnit)
1288
if (!(nBitsPerScanline % x))
1291
BankBase = ((nBitsPerScanline - minBitsPerScanline) /
1292
(nBitsPerScanline - x)) * BankUnit;
1130
1300
* xf86ValidateModes
1363
1533
for (i = 0; linePitches[i] != 0; i++) {
1364
1534
if ((linePitches[i] >= virtualX) &&
1365
1535
(linePitches[i] ==
1366
miScanLineWidth(virtualX, virtualY, linePitches[i],
1367
apertureSize, BankFormat, pitchInc))) {
1536
scanLineWidth(virtualX, virtualY, linePitches[i],
1537
apertureSize, BankFormat, pitchInc))) {
1368
1538
linePitch = linePitches[i];
1373
linePitch = miScanLineWidth(virtualX, virtualY, minPitch,
1374
apertureSize, BankFormat, pitchInc);
1543
linePitch = scanLineWidth(virtualX, virtualY, minPitch,
1544
apertureSize, BankFormat, pitchInc);
1377
1547
if ((linePitch < minPitch) || (linePitch > maxPitch)) {
1396
1566
/* XXX this doesn't take m{in,ax}Pitch into account; oh well */
1397
1567
inferred_virtual = inferVirtualSize(scrp, availModes, &virtX, &virtY);
1398
1568
if (inferred_virtual)
1399
linePitch = miScanLineWidth(virtX, virtY, minPitch, apertureSize,
1400
BankFormat, pitchInc);
1569
linePitch = scanLineWidth(virtX, virtY, minPitch, apertureSize,
1570
BankFormat, pitchInc);
1403
1573
/* Print clock ranges and scaled clocks */
1609
1779
if ((linePitches[i] >= newVirtX) &&
1610
1780
(linePitches[i] >= linePitch) &&
1611
1781
(linePitches[i] ==
1612
miScanLineWidth(newVirtX, newVirtY, linePitches[i],
1613
apertureSize, BankFormat, pitchInc))) {
1782
scanLineWidth(newVirtX, newVirtY, linePitches[i],
1783
apertureSize, BankFormat, pitchInc))) {
1614
1784
newLinePitch = linePitches[i];
1619
1789
if (linePitch < minPitch)
1620
1790
linePitch = minPitch;
1621
newLinePitch = miScanLineWidth(newVirtX, newVirtY, linePitch,
1622
apertureSize, BankFormat,
1791
newLinePitch = scanLineWidth(newVirtX, newVirtY, linePitch,
1792
apertureSize, BankFormat,
1625
1795
if ((newLinePitch < minPitch) || (newLinePitch > maxPitch)) {
1626
1796
p->status = MODE_BAD_WIDTH;