openMSX
Multiply32.cc
Go to the documentation of this file.
1 #include "Multiply32.hh"
2 #include "PixelOperations.hh"
3 #include "build-info.hh"
4 #include <cstring>
5 
6 namespace openmsx {
7 
8 // class Multiply32<uint32_t>
9 
11 {
12  // nothing
13 }
14 
15 
16 // class Multiply32<uint16_t>
17 
18 // gcc can optimize these rotate functions to just one instruction.
19 // We don't really need a rotate, but we do need a shift over a positive or
20 // negative (not known at compile time) distance, rotate handles this just fine.
21 // Note that 0 <= n < 32; on x86 this doesn't matter but on PPC it does.
22 static inline uint32_t rotLeft(uint32_t a, unsigned n)
23 {
24  return (a << n) | (a >> (32 - n));
25 }
26 
28 {
29  Rmask1 = pixelOps.getRmask();
30  Gmask1 = pixelOps.getGmask();
31  Bmask1 = pixelOps.getBmask();
32 
33  Rshift1 = ((2 + pixelOps.getRloss()) - pixelOps.getRshift()) & 31;
34  Gshift1 = ((2 + pixelOps.getGloss()) - pixelOps.getGshift()) & 31;
35  Bshift1 = ((2 + pixelOps.getBloss()) - pixelOps.getBshift()) & 31;
36 
37  Rmask2 = ((1 << (2 + pixelOps.getRloss())) - 1) <<
38  (10 + pixelOps.getRshift() - 2 * (2 + pixelOps.getRloss()));
39  Gmask2 = ((1 << (2 + pixelOps.getGloss())) - 1) <<
40  (10 + pixelOps.getGshift() - 2 * (2 + pixelOps.getGloss()));
41  Bmask2 = ((1 << (2 + pixelOps.getBloss())) - 1) <<
42  (10 + pixelOps.getBshift() - 2 * (2 + pixelOps.getBloss()));
43 
44  Rshift2 = (2 * (2 + pixelOps.getRloss()) - pixelOps.getRshift() - 10) & 31;
45  Gshift2 = (2 * (2 + pixelOps.getGloss()) - pixelOps.getGshift() - 10) & 31;
46  Bshift2 = (2 * (2 + pixelOps.getBloss()) - pixelOps.getBshift() - 10) & 31;
47 
48  Rshift3 = (Rshift1 + 0) & 31;
49  Gshift3 = (Gshift1 + 10) & 31;
50  Bshift3 = (Bshift1 + 20) & 31;
51 
52  factor = 0;
53  memset(tab, 0, sizeof(tab));
54 }
55 
57 {
58  if (factor == f) {
59  return;
60  }
61  factor = f;
62 
63  for (unsigned p = 0; p < 0x10000; ++p) {
64  uint32_t r = rotLeft((p & Rmask1), Rshift1) |
65  rotLeft((p & Rmask2), Rshift2);
66  uint32_t g = rotLeft((p & Gmask1), Gshift1) |
67  rotLeft((p & Gmask2), Gshift2);
68  uint32_t b = rotLeft((p & Bmask1), Bshift1) |
69  rotLeft((p & Bmask2), Bshift2);
70  tab[p] = (((r * factor) >> 8) << 0) |
71  (((g * factor) >> 8) << 10) |
72  (((b * factor) >> 8) << 20);
73  }
74 }
75 
76 
77 // Force template instantiation
78 #ifndef _MSC_VER
79 #if HAVE_16BPP
80 template class Multiply32<uint16_t>;
81 #endif
82 #if HAVE_32BPP
83 template class Multiply32<uint32_t>;
84 #endif
85 #else
86 // In VC++ we hit this problem again (see also V9990BitmapConverter)
87 // http://msdn.microsoft.com/en-us/library/9045w50z.aspx
88 // But luckily we don't get link errors without this in VC++.
89 #endif
90 
91 } // namespace openmsx
Helper class to perform 'pixel x scalar' calculations.
Definition: Multiply32.hh:14