Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/drape
diff options
context:
space:
mode:
authorExMix <rahuba.youri@mapswithme.com>2014-12-02 09:54:53 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:34:19 +0300
commitc97f5468dbfcea3d39369b434aa936295e460fb9 (patch)
tree236dcb89ec969c0f3e7a7a8cb305bd83001ea425 /drape
parentc76dcd04a4a7550d1b155e90067b27d63049baf3 (diff)
[drape] map on texture 4 pixel of color
Diffstat (limited to 'drape')
-rw-r--r--drape/color.cpp73
-rw-r--r--drape/color.hpp30
-rw-r--r--drape/drape_tests/memory_comparer.hpp58
-rw-r--r--drape/drape_tests/texture_of_colors_tests.cpp276
-rw-r--r--drape/glfunctions.cpp3
-rw-r--r--drape/glstate.cpp31
-rw-r--r--drape/glstate.hpp6
-rw-r--r--drape/texture_of_colors.cpp150
-rw-r--r--drape/texture_of_colors.hpp29
9 files changed, 395 insertions, 261 deletions
diff --git a/drape/color.cpp b/drape/color.cpp
index ad60134abf..b4269ec7e6 100644
--- a/drape/color.cpp
+++ b/drape/color.cpp
@@ -10,40 +10,36 @@ static const uint8_t MaxChannelValue = 255;
} // namespace
+#define EXTRACT_BYTE(x, n) (((x) >> 8 * (n)) & 0xFF);
+
Color::Color()
- : m_red(0)
- , m_green(0)
- , m_blue(0)
- , m_alfa(MaxChannelValue)
+ : m_rgba(MaxChannelValue)
{
}
Color::Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alfa)
- : m_red(red)
- , m_green(green)
- , m_blue(blue)
- , m_alfa(alfa)
{
+ m_rgba = red << 24 | green << 16 | blue << 8 | alfa;
+}
+
+uint8_t Color::GetRed() const
+{
+ return EXTRACT_BYTE(m_rgba, 3);
+}
+
+uint8_t Color::GetGreen() const
+{
+ return EXTRACT_BYTE(m_rgba, 2);
}
-bool Color::operator< (Color const & other) const
+uint8_t Color::GetBlue() const
{
- if (other.m_red != m_red)
- return m_red < other.m_red;
- if (other.m_green != m_green)
- return m_green < other.m_green;
- if (other.m_blue != m_blue)
- return m_blue < other.m_blue;
-
- return m_alfa < other.m_alfa;
+ return EXTRACT_BYTE(m_rgba, 1);
}
-bool Color::operator== (Color const & other) const
+uint8_t Color::GetAlfa() const
{
- return m_red == other.m_red &&
- m_green == other.m_green &&
- m_blue == other.m_blue &&
- m_alfa == other.m_alfa;
+ return EXTRACT_BYTE(m_rgba, 0);
}
uint8_t ExtractRed(uint32_t argb)
@@ -82,37 +78,4 @@ Color Extract(uint32_t xrgb, uint8_t a)
a);
}
-void Convert(Color const & c, float & r, float & g, float & b, float & a)
-{
- r = c.m_red / (float)MaxChannelValue;
- g = c.m_green / (float)MaxChannelValue;
- b = c.m_blue / (float)MaxChannelValue;
- a = c.m_alfa / (float)MaxChannelValue;
-}
-
-ColorF::ColorF(Color const & clr)
-{
- Convert(clr, m_r, m_g, m_b, m_a);
-}
-
-bool ColorF::operator< (ColorF const & other) const
-{
- if (other.m_r != m_r)
- return m_r < other.m_r;
- if (other.m_g != m_g)
- return m_g < other.m_g;
- if (other.m_b != m_b)
- return m_b < other.m_b;
-
- return m_a < other.m_a;
-}
-
-bool ColorF::operator== (ColorF const & other) const
-{
- return m_r == other.m_r &&
- m_g == other.m_g &&
- m_b == other.m_b &&
- m_a == other.m_a;
-}
-
} // namespace dp
diff --git a/drape/color.hpp b/drape/color.hpp
index 20c575bbd6..44a0e4c743 100644
--- a/drape/color.hpp
+++ b/drape/color.hpp
@@ -10,34 +10,19 @@ struct Color
Color();
Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alfa);
- bool operator < (Color const & other) const;
- bool operator == (Color const & other) const;
+ uint8_t GetRed() const;
+ uint8_t GetGreen() const;
+ uint8_t GetBlue() const;
+ uint8_t GetAlfa() const;
- uint8_t m_red;
- uint8_t m_green;
- uint8_t m_blue;
- uint8_t m_alfa;
-
- int GetColorInInt() const { return (m_alfa << 24) | (m_blue << 16) | (m_green << 8) | m_red; }
+ bool operator< (Color const & other) const { return m_rgba < other.m_rgba; }
static Color Black() { return Color(0, 0, 0, 255); }
static Color White() { return Color(255, 255, 255, 255); }
static Color Red() { return Color(255, 0, 0, 255); }
-};
-
-struct ColorF
-{
- ColorF() {}
- ColorF(Color const & clr);
- ColorF(float r, float g, float b, float a) : m_r (r), m_g (g), m_b (b), m_a (a) {}
-
- bool operator < (ColorF const & other) const;
- bool operator == (ColorF const & other) const;
- float m_r;
- float m_g;
- float m_b;
- float m_a;
+private:
+ uint32_t m_rgba;
};
inline uint8_t ExtractRed(uint32_t argb);
@@ -46,6 +31,5 @@ inline uint8_t ExtractBlue(uint32_t argb);
inline uint8_t ExtractAlfa(uint32_t argb);
Color Extract(uint32_t argb);
Color Extract(uint32_t xrgb, uint8_t a);
-void Convert(Color const & c, float & r, float & g, float & b, float & a);
}
diff --git a/drape/drape_tests/memory_comparer.hpp b/drape/drape_tests/memory_comparer.hpp
index 0ef2e7fc4e..bf3a475775 100644
--- a/drape/drape_tests/memory_comparer.hpp
+++ b/drape/drape_tests/memory_comparer.hpp
@@ -8,28 +8,52 @@
namespace dp
{
- struct MemoryComparer
+
+struct MemoryComparer
+{
+ void * m_mem;
+ int m_size;
+
+ MemoryComparer(void * memory, int size)
+ : m_mem(memory)
+ , m_size(size)
{
- void * m_mem;
- int m_size;
+ }
- MemoryComparer(void * memory, int size)
- : m_mem(memory)
- , m_size(size)
- {
- }
+ void cmpSubBuffer(glConst /*type*/, uint32_t size, void const * data, uint32_t /*offset*/) const
+ {
+ TEST_EQUAL(size, m_size, ());
+ TEST_EQUAL(memcmp(m_mem, data, size), 0, ());
+ }
- void cmpSubBuffer(glConst /*type*/, uint32_t size, void const * data, uint32_t /*offset*/) const
+ void cmpSubImage(uint32_t /*x*/, uint32_t /*y*/, uint32_t width, uint32_t height,
+ glConst layout, glConst pixelFormat, void const * data) const
+ {
+ uint32_t channelCount = 0;
+ if (layout == gl_const::GLRGBA)
+ channelCount = 4;
+ else if (layout == gl_const::GLRGB)
+ channelCount = 3;
+ else if (layout == gl_const::GLAlpha ||
+ layout == gl_const::GLLuminance ||
+ layout == gl_const::GLAlphaLuminance)
{
- TEST_EQUAL(size, m_size, ());
- TEST_EQUAL(memcmp(m_mem, data, size), 0, ());
+ channelCount = 1;
}
+ else
+ ASSERT(false, ());
- void cmpSubImage(uint32_t /*x*/, uint32_t /*y*/, uint32_t /*width*/, uint32_t /*height*/,
- glConst /*layout*/, glConst /*pixelFormat*/, void const * data) const
- {
- TEST_EQUAL(memcmp(m_mem, data, m_size), 0, ());
- }
- };
+ ASSERT(gl_const::GL8BitOnChannel == pixelFormat, ());
+
+ TEST_EQUAL(m_size, width * height * channelCount, ());
+ uint8_t * member = (uint8_t *)m_mem;
+ uint8_t * input = (uint8_t *)data;
+
+ for (int i = 0; i < m_size; ++i)
+ TEST_EQUAL(member[i], input[i], (i));
+
+ //TEST_EQUAL(memcmp(m_mem, data, m_size), 0, ());
+ }
+};
}
diff --git a/drape/drape_tests/texture_of_colors_tests.cpp b/drape/drape_tests/texture_of_colors_tests.cpp
index 5d815cbe2b..2dbe599b62 100644
--- a/drape/drape_tests/texture_of_colors_tests.cpp
+++ b/drape/drape_tests/texture_of_colors_tests.cpp
@@ -55,30 +55,27 @@ UNIT_TEST(ColorPalleteMappingTests)
{
ColorPalette cp(m2::PointU(32, 16));
- dp::ColorKey key(0);
- key.SetColor(0);
- ColorResourceInfo const * info1 = cp.MapResource(key);
- key.SetColor(1);
- ColorResourceInfo const * info2 = cp.MapResource(key);
- key.SetColor(0);
- ColorResourceInfo const * info3 = cp.MapResource(key);
+ ColorResourceInfo const * info1 = cp.MapResource(dp::Color(0, 0, 0, 0));
+ ColorResourceInfo const * info2 = cp.MapResource(dp::Color(1, 1, 1, 1));
+ ColorResourceInfo const * info3 = cp.MapResource(dp::Color(0, 0, 0, 0));
TEST_NOT_EQUAL(info1, info2, ());
TEST_EQUAL(info1, info3, ());
+ TestRects(info1->GetTexRect(), m2::RectF(1.0f / 32.0f, 1.0f / 16,
+ 1.0f / 32.0f, 1.0f / 16));
+ TestRects(info2->GetTexRect(), m2::RectF(3.0f / 32.0f, 1.0f / 16,
+ 3.0f / 32.0f, 1.0f / 16));
+ TestRects(info3->GetTexRect(), m2::RectF(1.0f / 32.0f, 1.0f / 16,
+ 1.0f / 32.0f, 1.0f / 16));
for (int i = 2; i < 100; ++i)
- {
- key.SetColor(i);
- cp.MapResource(key);
- }
+ cp.MapResource(dp::Color(i, i, i, i));
- key.SetColor(54);
- ColorResourceInfo const * info4 = cp.MapResource(key);
- ColorResourceInfo const info5(m2::RectF(22.5f / 32.0f, 1.5f / 16.0f, 22.5f / 32.0f, 1.5f / 16.0f));
- TestRects(info4->GetTexRect(), info5.GetTexRect());
+ TestRects(cp.MapResource(dp::Color(54, 54, 54, 54))->GetTexRect(), m2::RectF(13.0f / 32.0f, 7.0f / 16.0f,
+ 13.0f / 32.0f, 7.0f / 16.0f));
}
-UNIT_TEST(ColorPalleteUploadingTests1)
+UNIT_TEST(ColorPalleteUploadingSingleRow)
{
int const width = 32;
int const height = 16;
@@ -89,102 +86,209 @@ UNIT_TEST(ColorPalleteUploadingTests1)
ColorPalette cp(m2::PointU(width, height));
cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
- dp::ColorKey key(0);
- key.SetColor(0);
- cp.MapResource(key);
- key.SetColor(1);
- cp.MapResource(key);
- key.SetColor(2);
- cp.MapResource(key);
- key.SetColor(3);
- cp.MapResource(key);
- key.SetColor(4);
- cp.MapResource(key);
-
- int ar1[5] = {0, 1, 2, 3, 4};
- int ar2[27];
- int ar3[64];
- int ar4[4];
-
- MemoryComparer cmp1(ar1, sizeof(int) * 5);
- EXPECTGL(glTexSubImage2D(0, 0, 5, 1, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
- .WillOnce(Invoke(&cmp1, &MemoryComparer::cmpSubImage));
-
- cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
-
- for (int i = 5; i < 32; ++i)
{
- key.SetColor(i);
- cp.MapResource(key);
- ar2[i - 5] = i;
+ cp.MapResource(dp::Color(0xFF, 0, 0, 0));
+ cp.MapResource(dp::Color(0, 0xFF, 0, 0));
+ cp.MapResource(dp::Color(0, 0, 0xFF, 0));
+ cp.MapResource(dp::Color(0, 0, 0, 0xFF));
+ cp.MapResource(dp::Color(0xAA, 0xBB, 0xCC, 0xDD));
+
+ uint8_t memoryEtalon[] =
+ {
+ // 1 pixel 2 pixel 3 pixel 4 pixel
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD,
+ // second row
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD
+ };
+
+ MemoryComparer cmp(memoryEtalon, ARRAY_SIZE(memoryEtalon));
+ EXPECTGL(glTexSubImage2D(0, 0, 10, 2, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
+ .WillOnce(Invoke(&cmp, &MemoryComparer::cmpSubImage));
+
+ cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
}
- for (int i = 32; i < 96; ++i)
{
- key.SetColor(i);
- cp.MapResource(key);
- ar3[i - 32] = i;
+ cp.MapResource(dp::Color(0xFF, 0xAA, 0, 0));
+ cp.MapResource(dp::Color(0xAA, 0xFF, 0, 0));
+ cp.MapResource(dp::Color(0xAA, 0, 0xFF, 0));
+ cp.MapResource(dp::Color(0xAA, 0, 0, 0xFF));
+ cp.MapResource(dp::Color(0x00, 0xBB, 0xCC, 0xDD));
+
+ uint8_t memoryEtalon[] =
+ {
+ // 1 pixel 2 pixel 3 pixel 4 pixel
+ 0xFF, 0xAA, 0x00, 0x00, 0xFF, 0xAA, 0x00, 0x00, 0xAA, 0xFF, 0x00, 0x00, 0xAA, 0xFF, 0x00, 0x00,
+ 0xAA, 0x00, 0xFF, 0x00, 0xAA, 0x00, 0xFF, 0x00, 0xAA, 0x00, 0x00, 0xFF, 0xAA, 0x00, 0x00, 0xFF,
+ 0x00, 0xBB, 0xCC, 0xDD, 0x00, 0xBB, 0xCC, 0xDD,
+ // second row
+ 0xFF, 0xAA, 0x00, 0x00, 0xFF, 0xAA, 0x00, 0x00, 0xAA, 0xFF, 0x00, 0x00, 0xAA, 0xFF, 0x00, 0x00,
+ 0xAA, 0x00, 0xFF, 0x00, 0xAA, 0x00, 0xFF, 0x00, 0xAA, 0x00, 0x00, 0xFF, 0xAA, 0x00, 0x00, 0xFF,
+ 0x00, 0xBB, 0xCC, 0xDD, 0x00, 0xBB, 0xCC, 0xDD,
+ };
+
+ MemoryComparer cmp(memoryEtalon, ARRAY_SIZE(memoryEtalon));
+ EXPECTGL(glTexSubImage2D(10, 0, 10, 2, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
+ .WillOnce(Invoke(&cmp, &MemoryComparer::cmpSubImage));
+
+ cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
}
- for (int i = 96; i < 100; ++i)
- {
- key.SetColor(i);
- cp.MapResource(key);
- ar4[i - 96] = i;
- }
+ EXPECTGL(glDeleteTexture(1));
+}
- InSequence seq1;
- MemoryComparer cmp2(ar2, sizeof(int) * 27);
- EXPECTGL(glTexSubImage2D(5, 0, 27, 1, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
- .WillOnce(Invoke(&cmp2, &MemoryComparer::cmpSubImage));
+UNIT_TEST(ColorPalleteUploadingPartialyRow)
+{
+ int const width = 16;
+ int const height = 16;
+ InitOpenGLTextures(width, height);
+
+ SimpleTexture texture;
+ dp::ColorKey key(dp::Color(0, 0, 0, 0));
+ texture.Create(width, height, dp::RGBA8);
+ ColorPalette cp(m2::PointU(width, height));
- MemoryComparer cmp3(ar3, sizeof(int) * 64);
- EXPECTGL(glTexSubImage2D(0, 1, 32, 2, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
- .WillOnce(Invoke(&cmp3, &MemoryComparer::cmpSubImage));
+ {
+ cp.MapResource(dp::Color(0xFF, 0, 0, 0));
+ cp.MapResource(dp::Color(0xFF, 0xFF, 0, 0));
+ cp.MapResource(dp::Color(0xFF, 0xFF, 0xFF, 0));
+ cp.MapResource(dp::Color(0xFF, 0xFF, 0xFF, 0xFF));
+ cp.MapResource(dp::Color(0, 0, 0, 0xFF));
+ cp.MapResource(dp::Color(0, 0, 0xFF, 0xFF));
+
+ uint8_t memoryEtalon[] =
+ {
+ // 1 pixel 2 pixel 3 pixel 4 pixel
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
+ // second row
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF
+ };
+
+ MemoryComparer cmp(memoryEtalon, ARRAY_SIZE(memoryEtalon));
+ EXPECTGL(glTexSubImage2D(0, 0, 12, 2, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
+ .WillOnce(Invoke(&cmp, &MemoryComparer::cmpSubImage));
+
+ cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
+ }
- MemoryComparer cmp4(ar4, sizeof(int) * 4);
- EXPECTGL(glTexSubImage2D(0, 3, 4, 1, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
- .WillOnce(Invoke(&cmp4, &MemoryComparer::cmpSubImage));
+ {
+ cp.MapResource(dp::Color(0xAA, 0, 0, 0));
+ cp.MapResource(dp::Color(0xAA, 0xAA, 0, 0));
+ cp.MapResource(dp::Color(0xAA, 0xAA, 0xAA, 0));
+ cp.MapResource(dp::Color(0xAA, 0xAA, 0xAA, 0xAA));
+
+ uint8_t memoryEtalon1[] =
+ {
+ // 1 pixel 2 pixel 3 pixel 4 pixel
+ 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00,
+ // second row
+ 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00,
+ };
+
+ uint8_t memoryEtalon2[] =
+ {
+ // 1 pixel 2 pixel 3 pixel 4 pixel
+ 0xAA, 0xAA, 0xAA, 0x00, 0xAA, 0xAA, 0xAA, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ // second row
+ 0xAA, 0xAA, 0xAA, 0x00, 0xAA, 0xAA, 0xAA, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
+ };
+
+ MemoryComparer cmp1(memoryEtalon1, ARRAY_SIZE(memoryEtalon1));
+ EXPECTGL(glTexSubImage2D(12, 0, 4, 2, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
+ .WillOnce(Invoke(&cmp1, &MemoryComparer::cmpSubImage));
+
+ MemoryComparer cmp2(memoryEtalon2, ARRAY_SIZE(memoryEtalon2));
+ EXPECTGL(glTexSubImage2D(0, 2, 4, 2, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
+ .WillOnce(Invoke(&cmp2, &MemoryComparer::cmpSubImage));
+
+ cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
+ }
- cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
EXPECTGL(glDeleteTexture(1));
}
-UNIT_TEST(ColorPalleteUploadingTests2)
+UNIT_TEST(ColorPalleteUploadingMultipyRow)
{
- int const width = 32;
+ int const width = 8;
int const height = 16;
InitOpenGLTextures(width, height);
SimpleTexture texture;
- dp::ColorKey key(0);
+ dp::ColorKey key(dp::Color(0, 0, 0, 0));
texture.Create(width, height, dp::RGBA8);
ColorPalette cp(m2::PointU(width, height));
+ cp.SetIsDebug(true);
- int ar1[32];
- int ar2[1];
-
- for (int i = 0; i < 32; ++i)
{
- key.SetColor(i);
- cp.MapResource(key);
- ar1[i] = i;
- }
+ cp.MapResource(dp::Color(0xFF, 0, 0, 0));
+ cp.MapResource(dp::Color(0xAA, 0, 0, 0));
- MemoryComparer cmp1(ar1, sizeof(int) * 32);
- EXPECTGL(glTexSubImage2D(0, 0, 32, 1, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
- .WillOnce(Invoke(&cmp1, &MemoryComparer::cmpSubImage));
- cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
+ uint8_t memoryEtalon[] =
+ {
+ // 1 pixel 2 pixel 3 pixel 4 pixel
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00
+ };
- key.SetColor(32);
- cp.MapResource(key);
- ar2[0] = 32;
+ MemoryComparer cmp(memoryEtalon, ARRAY_SIZE(memoryEtalon));
+ EXPECTGL(glTexSubImage2D(0, 0, 4, 2, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
+ .WillOnce(Invoke(&cmp, &MemoryComparer::cmpSubImage));
- MemoryComparer cmp2(ar2, sizeof(int) * 1);
- EXPECTGL(glTexSubImage2D(0, 1, 1, 1, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
- .WillOnce(Invoke(&cmp2, &MemoryComparer::cmpSubImage));
- cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
+ cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
+ }
+
+ {
+ cp.MapResource(dp::Color(0xCC, 0, 0, 0));
+ cp.MapResource(dp::Color(0xFF, 0xFF, 0, 0));
+ cp.MapResource(dp::Color(0xFF, 0xFF, 0xFF, 0));
+ cp.MapResource(dp::Color(0xFF, 0xFF, 0xFF, 0xFF));
+ cp.MapResource(dp::Color(0, 0, 0, 0xFF));
+ cp.MapResource(dp::Color(0, 0, 0xFF, 0xFF));
+ cp.MapResource(dp::Color(0, 0, 0xAA, 0xAA));
+
+ uint8_t memoryEtalon1[] =
+ {
+ // 1 pixel 2 pixel 3 pixel 4 pixel
+ 0xCC, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+ 0xCC, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+ };
+
+ uint8_t memoryEtalon2[] =
+ {
+ // 1 pixel 2 pixel 3 pixel 4 pixel
+ 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ // 5 pixel 6 pixel 7 pixel 8 pixel
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
+ // second row
+ 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
+ // next row
+ 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // next row
+ 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+
+ MemoryComparer cmp1(memoryEtalon1, ARRAY_SIZE(memoryEtalon1));
+ EXPECTGL(glTexSubImage2D(4, 0, 4, 2, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
+ .WillOnce(Invoke(&cmp1, &MemoryComparer::cmpSubImage));
+
+ MemoryComparer cmp2(memoryEtalon2, ARRAY_SIZE(memoryEtalon2));
+ EXPECTGL(glTexSubImage2D(0, 2, 8, 4, gl_const::GLRGBA, gl_const::GL8BitOnChannel, _))
+ .WillOnce(Invoke(&cmp2, &MemoryComparer::cmpSubImage));
+
+ cp.UploadResources(MakeStackRefPointer<Texture>(&texture));
+ }
EXPECTGL(glDeleteTexture(1));
}
diff --git a/drape/glfunctions.cpp b/drape/glfunctions.cpp
index 01d01a8daa..6468306871 100644
--- a/drape/glfunctions.cpp
+++ b/drape/glfunctions.cpp
@@ -184,9 +184,6 @@ void GLFunctions::Init()
glUniform1fvFn = &::glUniform1fv;
glUniformMatrix4fvFn = &glUniformMatrix4fv;
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
}
bool GLFunctions::glHasExtension(string const & name)
diff --git a/drape/glstate.cpp b/drape/glstate.cpp
index be5715b1d8..e09385f398 100644
--- a/drape/glstate.cpp
+++ b/drape/glstate.cpp
@@ -4,8 +4,7 @@
#include "../base/buffer_vector.hpp"
#include "../std/bind.hpp"
-#define COLOR_BIT 0x1
-#define TEXTURE_BIT 0x2
+#define TEXTURE_BIT 0x1
namespace dp
{
@@ -54,7 +53,6 @@ GLState::GLState(uint32_t gpuProgramIndex, DepthLayer depthLayer)
: m_gpuProgramIndex(gpuProgramIndex)
, m_depthLayer(depthLayer)
, m_textureSet(-1)
- , m_color(0, 0, 0, 0)
, m_mask(0)
{
}
@@ -70,17 +68,6 @@ bool GLState::HasTextureSet() const
return (m_mask & TEXTURE_BIT) != 0;
}
-void GLState::SetColor(Color const & c)
-{
- m_mask |= COLOR_BIT;
- m_color = c;
-}
-
-bool GLState::HasColor() const
-{
- return (m_mask & COLOR_BIT) != 0;
-}
-
void GLState::SetBlending(Blending const & blending)
{
m_blending = blending;
@@ -96,10 +83,7 @@ bool GLState::operator<(GLState const & other) const
if (m_gpuProgramIndex != other.m_gpuProgramIndex)
return m_gpuProgramIndex < other.m_gpuProgramIndex;
- if (m_textureSet != other.m_textureSet)
- return m_textureSet < other.m_textureSet;
-
- return m_color < other.m_color;
+ return m_textureSet < other.m_textureSet;
}
bool GLState::operator==(GLState const & other) const
@@ -108,8 +92,7 @@ bool GLState::operator==(GLState const & other) const
m_depthLayer == other.m_depthLayer &&
m_gpuProgramIndex == other.m_gpuProgramIndex &&
m_textureSet == other.m_textureSet &&
- m_blending == other.m_blending &&
- m_color == other.m_color;
+ m_blending == other.m_blending;
}
namespace
@@ -128,14 +111,6 @@ void ApplyUniforms(UniformValuesStorage const & uniforms, RefPointer<GpuProgram>
void ApplyState(GLState state, RefPointer<GpuProgram> program,
RefPointer<TextureSetController> textures)
{
- if (state.HasColor())
- {
- int8_t location = program->GetUniformLocation("u_color");
- float c[4];
- Convert(state.GetColor(), c[0], c[1], c[2], c[3]);
- GLFunctions::glUniformValuef(location, c[0], c[1], c[2], c[3]);
- }
-
if (state.HasTextureSet())
{
uint32_t textureSet = state.GetTextureSet();
diff --git a/drape/glstate.hpp b/drape/glstate.hpp
index 65bb0b8e39..0225c377de 100644
--- a/drape/glstate.hpp
+++ b/drape/glstate.hpp
@@ -42,10 +42,6 @@ public:
int32_t GetTextureSet() const { return m_textureSet; }
bool HasTextureSet() const;
- void SetColor(Color const & c);
- Color const & GetColor() const { return m_color; }
- bool HasColor() const;
-
void SetBlending(Blending const & blending);
Blending const & GetBlending() const { return m_blending; }
@@ -59,8 +55,6 @@ private:
DepthLayer m_depthLayer;
int32_t m_textureSet;
Blending m_blending;
- Color m_color;
-
uint32_t m_mask;
};
diff --git a/drape/texture_of_colors.cpp b/drape/texture_of_colors.cpp
index ead21d2931..b837db0d28 100644
--- a/drape/texture_of_colors.cpp
+++ b/drape/texture_of_colors.cpp
@@ -1,14 +1,20 @@
#include "texture_of_colors.hpp"
+#include "../base/shared_buffer_manager.hpp"
#include "../base/stl_add.hpp"
namespace dp
{
+namespace
+{
+ int const RESOURCE_SIZE = 2;
+ int const BYTES_PER_PIXEL = 4;
+}
+
ColorPalette::ColorPalette(m2::PointU const & canvasSize)
- : m_textureSize(canvasSize),
- m_curY(0),
- m_curX(0)
+ : m_textureSize(canvasSize)
+ , m_cursor(m2::PointU::Zero())
{}
ColorPalette::~ColorPalette()
@@ -16,20 +22,33 @@ ColorPalette::~ColorPalette()
DeleteRange(m_palette, MasterPointerDeleter());
}
-ColorResourceInfo const * ColorPalette::MapResource(const ColorKey &key)
+ColorResourceInfo const * ColorPalette::MapResource(ColorKey const & key)
{
- uint32_t color = key.GetColor();
- TPalette::iterator itm = m_palette.find(color);
+ TPalette::iterator itm = m_palette.find(key.m_color);
if (itm == m_palette.end())
{
- m_pendingNodes.push_back(color);
- int const size = m_palette.size();
+ PendingColor pendingColor;
+ pendingColor.m_color = key.m_color;
+ pendingColor.m_rect = m2::RectU(m_cursor.x, m_cursor.y,
+ m_cursor.x + RESOURCE_SIZE, m_cursor.y + RESOURCE_SIZE);
+ m_pendingNodes.push_back(pendingColor);
+
+ m_cursor.x += RESOURCE_SIZE;
+ if (m_cursor.x >= m_textureSize.x)
+ {
+ m_cursor.y += RESOURCE_SIZE;
+ m_cursor.x = 0;
+
+ ASSERT(m_cursor.y < m_textureSize.y, ());
+ }
+
float const sizeX = static_cast<float>(m_textureSize.x);
float const sizeY = static_cast<float>(m_textureSize.y);
- float const x = (size % m_textureSize.x + 0.5f) / sizeX;
- float const y = (size / m_textureSize.x + 0.5f) / sizeY;
- TResourcePtr m_ptr(new ColorResourceInfo(m2::RectF(x, y, x, y)));
- itm = m_palette.insert(make_pair(color, m_ptr)).first;
+ m2::PointF const resCenter = m2::RectF(pendingColor.m_rect).Center();
+ float const x = resCenter.x / sizeX;
+ float const y = resCenter.y / sizeY;
+ TResourcePtr resourcePtr(new ColorResourceInfo(m2::RectF(x, y, x, y)));
+ itm = m_palette.insert(make_pair(key.m_color, resourcePtr)).first;
}
return itm->second.GetRaw();
}
@@ -39,36 +58,99 @@ void ColorPalette::UploadResources(RefPointer<Texture> texture)
ASSERT(texture->GetFormat() == dp::RGBA8, ());
if (m_pendingNodes.empty())
return;
- uint32_t const nodeCnt = m_pendingNodes.size();
- uint32_t const offset = m_textureSize.x - m_curX;
- if (offset >= nodeCnt)
+
+ buffer_vector<size_t, 3> ranges;
+ ranges.push_back(0);
+
+ uint32_t minX = m_pendingNodes[0].m_rect.minX();
+ for (size_t i = 0; i < m_pendingNodes.size(); ++i)
{
- texture->UploadData(m_curX, m_curY, nodeCnt, 1, dp::RGBA8, MakeStackRefPointer<void>(&m_pendingNodes[0]));
- m_curX += nodeCnt;
- if (offset == nodeCnt)
+ m2::RectU const & currentRect = m_pendingNodes[i].m_rect;
+ if (minX > currentRect.minX())
{
- m_curX = 0;
- m_curY++;
+ ranges.push_back(i);
+ minX = currentRect.minX();
}
}
- else
+
+ ranges.push_back(m_pendingNodes.size());
+
+ for (size_t i = 1; i < ranges.size(); ++i)
{
- texture->UploadData(m_curX, m_curY, offset, 1, dp::RGBA8, MakeStackRefPointer<void>(&m_pendingNodes[0]));
- m_curY++;
- m_curX = 0;
- uint32_t const remnant = nodeCnt - offset;
- uint32_t const ySteps = remnant / m_textureSize.x;
- uint32_t const xSteps = remnant % m_textureSize.x;
- if (ySteps)
- texture->UploadData(0, m_curY, m_textureSize.x, ySteps, dp::RGBA8, MakeStackRefPointer<void>(&m_pendingNodes[offset]));
- m_curY += ySteps;
- if (!xSteps)
- return;
- texture->UploadData(m_curX, m_curY, xSteps, 1, dp::RGBA8, MakeStackRefPointer<void>(&m_pendingNodes[offset + ySteps * m_textureSize.x]));
- m_curX += xSteps;
+ size_t startRange = ranges[i - 1];
+ size_t endRange = ranges[i];
+
+ m2::RectU const & startRect = m_pendingNodes[startRange].m_rect;
+ m2::RectU const & endRect = m_pendingNodes[endRange - 1].m_rect;
+
+ m2::RectU uploadRect;
+ if (startRect.minY() == endRect.minY() &&
+ startRect.maxY() == endRect.maxY())
+ {
+ uploadRect = m2::RectU(startRect.minX(), startRect.minY(), endRect.maxX(), endRect.maxY());
+ }
+ else
+ {
+ ASSERT(startRect.minX() == 0, ());
+ uploadRect = m2::RectU(0, startRect.minY(), m_textureSize.x, endRect.maxY());
+ }
+
+ size_t pixelStride = uploadRect.SizeX();
+ size_t byteCount = BYTES_PER_PIXEL * uploadRect.SizeX() * uploadRect.SizeY();
+ size_t bufferSize = my::NextPowOf2(byteCount);
+
+ SharedBufferManager::shared_buffer_ptr_t buffer = SharedBufferManager::instance().reserveSharedBuffer(bufferSize);
+ uint8_t * pointer = SharedBufferManager::GetRawPointer(buffer);
+ if (m_isDebug)
+ memset(pointer, 0, bufferSize);
+ uint32_t currentY = startRect.minY();
+ for (size_t j = startRange; j < endRange; ++j)
+ {
+ ASSERT(pointer < SharedBufferManager::GetRawPointer(buffer) + byteCount, ());
+ PendingColor const & c = m_pendingNodes[j];
+ if (c.m_rect.minY() > currentY)
+ {
+ pointer += BYTES_PER_PIXEL * pixelStride;
+ currentY = c.m_rect.minY();
+ }
+
+ uint32_t byteStride = pixelStride * BYTES_PER_PIXEL;
+ uint8_t red = c.m_color.GetRed();
+ uint8_t green = c.m_color.GetGreen();
+ uint8_t blue = c.m_color.GetBlue();
+ uint8_t alfa = c.m_color.GetAlfa();
+
+ pointer[0] = pointer[4] = red;
+ pointer[1] = pointer[5] = green;
+ pointer[2] = pointer[6] = blue;
+ pointer[3] = pointer[7] = alfa;
+ pointer[byteStride + 0] = pointer[byteStride + 4] = red;
+ pointer[byteStride + 1] = pointer[byteStride + 5] = green;
+ pointer[byteStride + 2] = pointer[byteStride + 6] = blue;
+ pointer[byteStride + 3] = pointer[byteStride + 7] = alfa;
+
+ pointer += 2 * BYTES_PER_PIXEL;
+ ASSERT(pointer <= SharedBufferManager::GetRawPointer(buffer) + byteCount, ());
+ }
+
+ pointer = SharedBufferManager::GetRawPointer(buffer);
+ texture->UploadData(uploadRect.minX(), uploadRect.minY(), uploadRect.SizeX(), uploadRect.SizeY(),
+ dp::RGBA8, dp::MakeStackRefPointer<void>(pointer));
}
m_pendingNodes.clear();
}
+void ColorPalette::MoveCursor()
+{
+ m_cursor.x += RESOURCE_SIZE;
+ if (m_cursor.x >= m_textureSize.x)
+ {
+ m_cursor.y += RESOURCE_SIZE;
+ m_cursor.x = 0;
+ }
+
+ ASSERT(m_cursor.y + RESOURCE_SIZE <= m_textureSize.y, ());
+}
+
}
diff --git a/drape/texture_of_colors.hpp b/drape/texture_of_colors.hpp
index 95b10ce106..5100239d1e 100644
--- a/drape/texture_of_colors.hpp
+++ b/drape/texture_of_colors.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "texture.hpp"
+#include "color.hpp"
#include "../base/buffer_vector.hpp"
@@ -10,12 +11,10 @@ namespace dp
class ColorKey : public Texture::Key
{
public:
- ColorKey(uint32_t color) : Texture::Key(), m_color(color) {}
+ ColorKey(Color color) : Texture::Key(), m_color(color) {}
virtual Texture::ResourceType GetType() const { return Texture::Color; }
- uint32_t GetColor() const { return m_color; }
- void SetColor(uint32_t color) { m_color = color; }
-private:
- uint32_t m_color;
+
+ Color m_color;
};
class ColorResourceInfo : public Texture::ResourceInfo
@@ -32,15 +31,27 @@ public:
~ColorPalette();
ColorResourceInfo const * MapResource(ColorKey const & key);
void UploadResources(RefPointer<Texture> texture);
+
+ void SetIsDebug(bool isDebug) { m_isDebug = isDebug; }
+
+private:
+ void MoveCursor();
+
private:
typedef MasterPointer<ColorResourceInfo> TResourcePtr;
- typedef map<uint32_t, TResourcePtr> TPalette;
+ typedef map<Color, TResourcePtr> TPalette;
+
+ struct PendingColor
+ {
+ m2::RectU m_rect;
+ Color m_color;
+ };
TPalette m_palette;
- vector<uint32_t> m_pendingNodes;
+ buffer_vector<PendingColor, 16> m_pendingNodes;
m2::PointU m_textureSize;
- uint32_t m_curY;
- uint32_t m_curX;
+ m2::PointU m_cursor;
+ bool m_isDebug = false;
};
}