~sethj/ubuntu/wily/unity/fix-for-1445595

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Copyright 2011 Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3, as published
 * by the  Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * version 3 along with this program.  If not, see
 * <http://www.gnu.org/licenses/>
 *
 * Authored by: Tim Penhey <tim.penhey@canonical.com>
 */

#include <gmock/gmock.h>

#include "TextureCache.h"

using namespace testing;
using namespace unity;

namespace
{
typedef nux::BaseTexture* (*TextureCallBack)(std::string const&, int, int);

TEST(TestTextureCache, TestInitiallyEmpty)
{
  TextureCache& cache = TextureCache::GetDefault();

  EXPECT_THAT(cache.Size(), Eq(0));
}

struct TextureCallbackValues
{
  std::string id;
  int width;
  int height;

  TextureCallbackValues() : width(0), height(0) {}
  nux::BaseTexture* callback(std::string const& i, int w, int h) {
    id = i;
    width = w;
    height = h;
    return nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
  }
};

TEST(TestTextureCache, TestCallsCreateTextureCallback)
{
  // Another lambda issue.  If the lambda takes a reference to any other
  // variables, it seems incapable of assigning the function to the
  // TextureCallback type.
  TextureCallbackValues values;

  TextureCache& cache = TextureCache::GetDefault();
  TextureCache::CreateTextureCallback callback(sigc::mem_fun(values, &TextureCallbackValues::callback));

  nux::ObjectPtr<nux::BaseTexture> texture = cache.FindTexture("foo", 5, 7, callback);

  EXPECT_THAT(cache.Size(), Eq(1));
  EXPECT_THAT(values.id, Eq("foo"));
  EXPECT_THAT(values.width, Eq(5));
  EXPECT_THAT(values.height, Eq(7));
  EXPECT_THAT(texture->GetReferenceCount(), Eq(1));
}

struct TextureCallbackCounter
{
  int count;

  TextureCallbackCounter() : count(0) {}
  nux::BaseTexture* callback(std::string const& i, int w, int h) {
    ++count;
    return nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
  }
};

TEST(TestTextureCache, TestCallbackOnlyCalledOnce)
{
  TextureCallbackCounter counter;
  TextureCache::CreateTextureCallback callback(sigc::mem_fun(counter, &TextureCallbackCounter::callback));

  TextureCache& cache = TextureCache::GetDefault();

  nux::ObjectPtr<nux::BaseTexture> t1 = cache.FindTexture("foo", 5, 7, callback);
  nux::ObjectPtr<nux::BaseTexture> t2 = cache.FindTexture("foo", 5, 7, callback);

  EXPECT_THAT(cache.Size(), Eq(1));
  EXPECT_THAT(counter.count, Eq(1));
  EXPECT_EQ(t1, t2);
}

TEST(TestTextureCache, TestCacheRemovesDeletedObject)
{
  // Note for others, if just using the lambda function, the return value is
  // lost in the type deduction that sigc uses.  So we have the typedef
  // (TextureCallback) at the top which includes the return value.  The lambda
  // constructor is fine to assign into this as it knows, and the explicit
  // return type is good for sigc.
  TextureCallBack callback =
    [](std::string const& i, int w, int h) -> nux::BaseTexture*
    {
      return nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
    };

  TextureCache& cache = TextureCache::GetDefault();

  nux::ObjectPtr<nux::BaseTexture> t1 = cache.FindTexture("foo", 5, 7, callback);

  // Now delete the only reference to the texture.
  t1 = nux::ObjectPtr<nux::BaseTexture>();

  EXPECT_THAT(cache.Size(), Eq(0));
}

TEST(TestTextureCache, Invalidate)
{
  TextureCallbackCounter counter;
  TextureCache::CreateTextureCallback callback(sigc::mem_fun(counter, &TextureCallbackCounter::callback));

  TextureCache& cache = TextureCache::GetDefault();
  nux::ObjectPtr<nux::BaseTexture> t1 = cache.FindTexture("foo", 5, 7, callback);
  cache.Invalidate("foo", 5, 7);
  ASSERT_EQ(0, cache.Size());

  nux::ObjectPtr<nux::BaseTexture> t2 = cache.FindTexture("foo", 5, 7, callback);
  EXPECT_NE(t1, t2);
  EXPECT_EQ(1, cache.Size());
  EXPECT_EQ(2, counter.count);
}

}