Modernize PixelAttributes

Tests have shown that the vectors are as fast as the C-Arrays
This commit is contained in:
Unknown 2018-05-11 10:02:43 +02:00
parent d40bd789e8
commit 8e58e84218
2 changed files with 32 additions and 36 deletions

View File

@ -8,17 +8,11 @@
*/ */
#include "PixelAttributes.h" #include "PixelAttributes.h"
#include <cstring> // memcpy
using namespace std; using namespace std;
PixelAttribute::AlphaMixingMode PixelAttribute::m_mixMode = PixelAttribute::AlphaMixCumulative; PixelAttribute::AlphaMixingMode PixelAttribute::m_mixMode = PixelAttribute::AlphaMixCumulative;
PixelAttributes::~PixelAttributes()
{
freeAttributes();
}
void PixelAttributes::setParameters(int width, int lines, int nextY, int scale, bool defaultEmpty) void PixelAttributes::setParameters(int width, int lines, int nextY, int scale, bool defaultEmpty)
{ {
freeAttributes(); freeAttributes();
@ -34,22 +28,19 @@ void PixelAttributes::setParameters(int width, int lines, int nextY, int scale,
m_firstUnshadedY = 0; m_firstUnshadedY = 0;
m_scale = scale; m_scale = scale;
m_pixelAttributes = new PixelAttribute *[m_lineCount]; PixelAttribute pa;
if (!m_pixelAttributes) pa.m_a = 0;
throw std::runtime_error("Failed to allocate memory for PixelAttributes"); pa.nextEmpty = false;
for (int i = 0; i < m_lineCount; ++i) { m_pixelAttributes = vector<vector<PixelAttribute>>(m_lineCount, vector<PixelAttribute>(m_width, pa));
m_pixelAttributes[i] = new PixelAttribute[m_width];
if (!m_pixelAttributes[i]) if (defaultEmpty) {
throw std::runtime_error("Failed to allocate memory for PixelAttributes"); int emptyColumns = (16 / scale);
for (int i = 0; i < m_lineCount; i++) {
for (int j = 0; j < m_width; j += emptyColumns) {
m_pixelAttributes[i][j + 1].nextEmpty = true;
}
} }
for (int i=0; i<m_lineCount; i++)
for (int j=0; j<m_width; j++) {
m_pixelAttributes[i][j].m_a=0;
if (defaultEmpty)
m_pixelAttributes[i][j].nextEmpty = (j - 1) % (16 / scale) == 0;
else
m_pixelAttributes[i][j].nextEmpty = false;
} }
} }
@ -59,15 +50,13 @@ void PixelAttributes::scroll(int keepY)
if (scroll > 0) { if (scroll > 0) {
int i; int i;
for (i = m_previousLine; i + scroll <= m_lastLine; i++) { for (i = m_previousLine; i + scroll <= m_lastLine; i++) {
PixelAttribute *tmp; auto tmp = m_pixelAttributes[i];
tmp = m_pixelAttributes[i];
m_pixelAttributes[i] = m_pixelAttributes[i + scroll]; m_pixelAttributes[i] = m_pixelAttributes[i + scroll];
m_pixelAttributes[i + scroll] = tmp; m_pixelAttributes[i + scroll] = tmp;
} }
size_t lineLength = m_width * sizeof(PixelAttribute);
for (; i <= m_lastLine; ++i) { for (; i <= m_lastLine; ++i) {
memcpy(m_pixelAttributes[i], m_pixelAttributes[m_emptyLine], lineLength); m_pixelAttributes[i] = m_pixelAttributes[m_emptyLine];
} }
m_firstY += scroll; m_firstY += scroll;
@ -79,15 +68,7 @@ void PixelAttributes::scroll(int keepY)
void PixelAttributes::freeAttributes() void PixelAttributes::freeAttributes()
{ {
if (m_pixelAttributes) { m_pixelAttributes.clear();
for (int i = 0; i < m_lineCount; ++i) {
if (m_pixelAttributes[i] != nullptr) {
delete[] m_pixelAttributes[i];
}
}
delete[] m_pixelAttributes;
m_pixelAttributes = nullptr;
}
} }
@ -307,3 +288,15 @@ void PixelAttribute::mixUnder(const PixelAttribute &p)
#endif #endif
} }
bool PixelAttribute::operator==(const PixelAttribute & p)
{
return m_n == p.m_n &&
m_h == p.m_h &&
m_t == p.m_t &&
m_a == p.m_a &&
m_r == p.m_r &&
m_g == p.m_g &&
m_b == p.m_b &&
nextEmpty == p.nextEmpty;
}

View File

@ -15,6 +15,7 @@
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <stdexcept> #include <stdexcept>
#include <vector>
class PixelAttribute { class PixelAttribute {
public: public:
@ -50,6 +51,8 @@ public:
void normalize(double count = 0, Color defaultColor = Color(127, 127, 127)); void normalize(double count = 0, Color defaultColor = Color(127, 127, 127));
void add(const PixelAttribute &p); void add(const PixelAttribute &p);
void mixUnder(const PixelAttribute &p); void mixUnder(const PixelAttribute &p);
bool operator==(const PixelAttribute &p);
bool operator!=(const PixelAttribute &p) { return !(*this == p); };
private: private:
static AlphaMixingMode m_mixMode; static AlphaMixingMode m_mixMode;
double m_n{0}; double m_n{0};
@ -67,7 +70,7 @@ class PixelAttributes
{ {
public: public:
PixelAttributes() = default; PixelAttributes() = default;
virtual ~PixelAttributes(); ~PixelAttributes() = default;
void setParameters(int width, int lines, int nextY, int scale, bool defaultEmpty); void setParameters(int width, int lines, int nextY, int scale, bool defaultEmpty);
void scroll(int keepY); void scroll(int keepY);
PixelAttribute &attribute(int y, int x); PixelAttribute &attribute(int y, int x);
@ -86,7 +89,7 @@ private:
int m_lastLine{}; int m_lastLine{};
int m_emptyLine{}; int m_emptyLine{};
int m_lineCount{}; int m_lineCount{};
PixelAttribute **m_pixelAttributes{nullptr}; std::vector<std::vector<PixelAttribute>> m_pixelAttributes;
int m_width{}; int m_width{};
int m_firstY{}; int m_firstY{};
int m_nextY{}; int m_nextY{};