openMSX
GLHQLiteScaler.cc
Go to the documentation of this file.
1 #include "GLHQLiteScaler.hh"
2 #include "GLUtil.hh"
3 #include "HQCommon.hh"
4 #include "FrameSource.hh"
5 #include "FileContext.hh"
6 #include "File.hh"
7 #include "vla.hh"
8 #include <cstring>
9 #include <utility>
10 
11 using std::string;
12 
13 namespace openmsx {
14 
16  : GLScaler("hqlite")
17  , fallback(fallback_)
18 {
19  for (auto& p : program) {
20  p.activate();
21  glUniform1i(p.getUniformLocation("edgeTex"), 2);
22  glUniform1i(p.getUniformLocation("offsetTex"), 3);
23  }
24 
25  // GL_LUMINANCE_ALPHA is no longer supported in newer openGL versions
26  auto format = (OPENGL_VERSION >= OPENGL_3_3) ? GL_RG : GL_LUMINANCE_ALPHA;
27  edgeTexture.bind();
28  glTexImage2D(GL_TEXTURE_2D, // target
29  0, // level
30  format, // internal format
31  320, // width
32  240, // height
33  0, // border
34  format, // format
35  GL_UNSIGNED_BYTE, // type
36  nullptr); // data
37 #if OPENGL_VERSION >= OPENGL_3_3
38  GLint swizzleMask1[] = {GL_RED, GL_RED, GL_RED, GL_GREEN};
39  glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask1);
40 #endif
41  edgeBuffer.setImage(320, 240);
42 
43  auto context = systemFileContext();
44  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
45  string offsetName = "shaders/HQ_xLiteOffsets.dat";
46  for (int i = 0; i < 3; ++i) {
47  int n = i + 2;
48  offsetName[10] = char('0') + n;
49  File offsetFile(context.resolve(offsetName));
50  offsetTexture[i].bind();
51  glTexImage2D(GL_TEXTURE_2D, // target
52  0, // level
53  format, // internal format
54  n * 64, // width
55  n * 64, // height
56  0, // border
57  format, // format
58  GL_UNSIGNED_BYTE, // type
59  offsetFile.mmap().data());// data
60 #if OPENGL_VERSION >= OPENGL_3_3
61  GLint swizzleMask2[] = {GL_RED, GL_RED, GL_RED, GL_GREEN};
62  glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask2);
63 #endif
64  }
65  glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // restore to default
66 }
67 
69  gl::ColorTexture& src, gl::ColorTexture* superImpose,
70  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
71  unsigned dstStartY, unsigned dstEndY, unsigned dstWidth,
72  unsigned logSrcHeight)
73 {
74  unsigned factorX = dstWidth / srcWidth; // 1 - 4
75  unsigned factorY = (dstEndY - dstStartY) / (srcEndY - srcStartY);
76 
77  if ((srcWidth == 320) && (factorX > 1) && (factorX == factorY)) {
78  setup(superImpose != nullptr);
79  src.setInterpolation(true);
80  glActiveTexture(GL_TEXTURE3);
81  offsetTexture[factorX - 2].bind();
82  glActiveTexture(GL_TEXTURE2);
83  edgeTexture.bind();
84  glActiveTexture(GL_TEXTURE0);
85  execute(src, superImpose,
86  srcStartY, srcEndY, srcWidth,
87  dstStartY, dstEndY, dstWidth,
88  logSrcHeight);
89  src.setInterpolation(false);
90  } else {
91  fallback.scaleImage(src, superImpose,
92  srcStartY, srcEndY, srcWidth,
93  dstStartY, dstEndY, dstWidth,
94  logSrcHeight);
95  }
96 }
97 
98 using Pixel = uint32_t;
100  unsigned srcStartY, unsigned srcEndY, unsigned lineWidth,
101  FrameSource& paintFrame)
102 {
103  if ((lineWidth != 320) || (srcEndY > 240)) return;
104 
105  Endian::L32 tmpBuf2[320 / 2]; // 2 x uint16_t
106  #ifndef NDEBUG
107  // Avoid UMR. In optimized mode we don't care.
108  memset(tmpBuf2, 0, sizeof(tmpBuf2));
109  #endif
110 
111  VLA_SSE_ALIGNED(Pixel, buf1_, lineWidth); auto* buf1 = buf1_;
112  VLA_SSE_ALIGNED(Pixel, buf2_, lineWidth); auto* buf2 = buf2_;
113  const auto* curr = paintFrame.getLinePtr(srcStartY - 1, lineWidth, buf1);
114  const auto* next = paintFrame.getLinePtr(srcStartY + 0, lineWidth, buf2);
115  calcEdgesGL(curr, next, tmpBuf2, EdgeHQLite());
116 
117  edgeBuffer.bind();
118  if (auto* mapped = edgeBuffer.mapWrite()) {
119  for (unsigned y = srcStartY; y < srcEndY; ++y) {
120  curr = next;
121  std::swap(buf1, buf2);
122  next = paintFrame.getLinePtr(y + 1, lineWidth, buf2);
123  calcEdgesGL(curr, next, tmpBuf2, EdgeHQLite());
124  memcpy(mapped + 320 * y, tmpBuf2, 320 * sizeof(uint16_t));
125  }
126  edgeBuffer.unmap();
127 
128  auto format = (OPENGL_VERSION >= OPENGL_3_3) ? GL_RG : GL_LUMINANCE_ALPHA;
129  edgeTexture.bind();
130  glTexSubImage2D(GL_TEXTURE_2D, // target
131  0, // level
132  0, // offset x
133  srcStartY, // offset y
134  lineWidth, // width
135  srcEndY - srcStartY, // height
136  format, // format
137  GL_UNSIGNED_BYTE, // type
138  edgeBuffer.getOffset(0, srcStartY)); // data
139  }
140  edgeBuffer.unbind();
141 }
142 
143 } // namespace openmsx
openmsx::GLScaler::scaleImage
virtual void scaleImage(gl::ColorTexture &src, gl::ColorTexture *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, unsigned logSrcHeight)=0
Scales the image in the given area, which must consist of lines which are all equally wide.
openmsx::DiskImageUtils::format
void format(SectorAccessibleDisk &disk, bool dos1)
Format the given disk (= a single partition).
Definition: DiskImageUtils.cc:188
openmsx::calcEdgesGL
void calcEdgesGL(const uint32_t *curr, const uint32_t *next, Endian::L32 *edges2, EdgeOp edgeOp)
Definition: HQCommon.hh:105
openmsx::File::mmap
span< uint8_t > mmap()
Map file in memory.
Definition: File.cc:93
openmsx::GLScaler::program
gl::ShaderProgram program[2]
Definition: GLScaler.hh:78
gl::ColorTexture
Definition: GLUtil.hh:100
FrameSource.hh
gl::PixelBuffer::mapWrite
T * mapWrite()
Maps the contents of this buffer into memory.
Definition: GLUtil.hh:300
openmsx::GLHQLiteScaler::GLHQLiteScaler
GLHQLiteScaler(GLScaler &fallback)
Definition: GLHQLiteScaler.cc:15
openmsx::FrameSource::getLinePtr
const Pixel * getLinePtr(int line, unsigned width, Pixel *buf) const
Gets a pointer to the pixels of the given line number.
Definition: FrameSource.hh:90
gl::Texture::bind
void bind()
Makes this texture the active GL texture.
Definition: GLUtil.hh:82
openmsx::GLScaler::execute
void execute(gl::ColorTexture &src, gl::ColorTexture *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, unsigned logSrcHeight, bool textureFromZero=false)
Helper method to draw a rectangle with multiple texture coordinates.
Definition: GLScaler.cc:45
gl::PixelBuffer::setImage
void setImage(GLuint width, GLuint height)
Sets the image for this buffer.
Definition: GLUtil.hh:253
gl::PixelBuffer::unmap
void unmap() const
Unmaps the contents of this buffer.
Definition: GLUtil.hh:311
openmsx::GLScaler::setup
void setup(bool superImpose)
Definition: GLScaler.cc:39
vla.hh
openmsx::EdgeHQLite
Definition: HQCommon.hh:97
openmsx::Pixel
uint32_t Pixel
Definition: GLHQLiteScaler.cc:98
File.hh
openmsx::GLHQLiteScaler::uploadBlock
void uploadBlock(unsigned srcStartY, unsigned srcEndY, unsigned lineWidth, FrameSource &paintFrame) override
Definition: GLHQLiteScaler.cc:99
FileContext.hh
Endian::EndianT
Definition: endian.hh:71
openmsx::GLHQLiteScaler::scaleImage
void scaleImage(gl::ColorTexture &src, gl::ColorTexture *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, unsigned logSrcHeight) override
Scales the image in the given area, which must consist of lines which are all equally wide.
Definition: GLHQLiteScaler.cc:68
gl::PixelBuffer::unbind
void unbind() const
Unbind this buffer.
Definition: GLUtil.hh:279
gl::context
std::unique_ptr< Context > context
Definition: GLContext.cc:9
openmsx::File
Definition: File.hh:16
GLHQLiteScaler.hh
openmsx::FrameSource
Interface for getting lines from a video frame.
Definition: FrameSource.hh:14
openmsx::GLScaler
Abstract base class for OpenGL scalers.
Definition: GLScaler.hh:14
OPENGL_VERSION
#define OPENGL_VERSION
Definition: GLUtil.hh:26
gl::PixelBuffer::bind
void bind() const
Bind this PixelBuffer.
Definition: GLUtil.hh:271
GLUtil.hh
gl::PixelBuffer::getOffset
T * getOffset(GLuint x, GLuint y)
Gets a pointer relative to the start of this buffer.
Definition: GLUtil.hh:287
VLA_SSE_ALIGNED
#define VLA_SSE_ALIGNED(TYPE, NAME, LENGTH)
Definition: vla.hh:44
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
gl::Texture::setInterpolation
void setInterpolation(bool interpolation)
Enable/disable bilinear interpolation for this texture.
Definition: GLUtil.cc:49
OPENGL_3_3
#define OPENGL_3_3
Definition: GLUtil.hh:25
HQCommon.hh
openmsx::systemFileContext
FileContext systemFileContext()
Definition: FileContext.cc:152