openMSX
RawFrame.cc
Go to the documentation of this file.
1 #include "RawFrame.hh"
2 #include "MemoryOps.hh"
3 #include "MSXException.hh"
4 #include "openmsx.hh"
5 #include <SDL.h>
6 
7 #if PLATFORM_GP2X
8 #include "GP2XMMUHack.hh"
9 #endif
10 
11 namespace openmsx {
12 
14  const SDL_PixelFormat& format, unsigned maxWidth_, unsigned height)
15  : FrameSource(format)
16  , lineWidths(height)
17  , maxWidth(maxWidth_)
18 {
19  setHeight(height);
20  unsigned bytesPerPixel = format.BytesPerPixel;
21 
22  if (PLATFORM_GP2X) {
23  surface.reset(SDL_CreateRGBSurface(
24  SDL_HWSURFACE, maxWidth, height, format.BitsPerPixel,
25  format.Rmask, format.Gmask, format.Bmask, format.Amask));
26  if (!surface.get()) {
27  throw FatalError("Couldn't allocate surface.");
28  }
29  // To keep code more uniform with non-GP2X case, we copy these
30  // two variables. This is OK if the variables inside surface
31  // don't change. AFAIK SDL doesn't explictly document this, but
32  // I don't see why they would change.
33  // Note: for a double buffered display surface, the pixels
34  // variable DOES change.
35  data = static_cast<char*>(surface->pixels);
36  pitch = surface->pitch;
37  } else {
38  // Allocate memory, make sure each line begins at a 64 byte
39  // boundary:
40  // - SSE instruction need 16 byte aligned data
41  // - cache line size on athlon and P4 CPUs is 64 bytes
42  pitch = ((bytesPerPixel * maxWidth) + 63) & ~63;
43  data = reinterpret_cast<char*>(
44  MemoryOps::mallocAligned(64, pitch * height));
45  }
46  maxWidth = pitch / bytesPerPixel; // adjust maxWidth
47  locked = false;
48 
49  // Start with a black frame.
51  for (unsigned line = 0; line < height; line++) {
52  if (bytesPerPixel == 2) {
53  setBlank(line, static_cast<word>(0));
54  } else {
55  setBlank(line, static_cast<unsigned>(0));
56  }
57  }
58 
59 #if PLATFORM_GP2X
61 #endif
62 }
63 
65 {
66  if (PLATFORM_GP2X) {
67  // surface is freed automatically
68  } else {
70  }
71 }
72 
73 unsigned RawFrame::getLineWidth(unsigned line) const
74 {
75  assert(line < getHeight());
76  return lineWidths[line];
77 }
78 
79 const void* RawFrame::getLineInfo(unsigned line, unsigned& width) const
80 {
81  if (PLATFORM_GP2X) {
82  if (!isLocked()) const_cast<RawFrame*>(this)->lock();
83  }
84  assert(line < getHeight());
85  width = lineWidths[line];
86  return data + line * pitch;
87 }
88 
89 unsigned RawFrame::getRowLength() const
90 {
91  return maxWidth; // in pixels (not in bytes)
92 }
93 
95 {
96  return true;
97 }
98 
100 {
101  if (isLocked()) return;
102  locked = true;
103  if (SDL_MUSTLOCK(surface.get())) SDL_LockSurface(surface.get());
104  // Note: we ignore the return value from SDL_LockSurface()
105 }
106 
108 {
109  if (!isLocked()) return;
110  locked = false;
111  if (SDL_MUSTLOCK(surface.get())) SDL_UnlockSurface(surface.get());
112 }
113 
114 } // namespace openmsx