/src/mozilla-central/gfx/layers/TiledLayerBuffer.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
5 | | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef GFX_TILEDLAYERBUFFER_H |
8 | | #define GFX_TILEDLAYERBUFFER_H |
9 | | |
10 | | // Debug defines |
11 | | //#define GFX_TILEDLAYER_DEBUG_OVERLAY |
12 | | //#define GFX_TILEDLAYER_PREF_WARNINGS |
13 | | //#define GFX_TILEDLAYER_RETAINING_LOG |
14 | | |
15 | | #include <stdint.h> // for uint16_t, uint32_t |
16 | | #include <sys/types.h> // for int32_t |
17 | | #include "LayersLogging.h" // for print_stderr |
18 | | #include "mozilla/gfx/gfxVars.h" |
19 | | #include "mozilla/gfx/Logging.h" // for gfxCriticalError |
20 | | #include "mozilla/layers/LayersTypes.h" // for TextureDumpMode |
21 | | #include "nsDebug.h" // for NS_ASSERTION |
22 | | #include "nsPoint.h" // for nsIntPoint |
23 | | #include "nsRect.h" // for mozilla::gfx::IntRect |
24 | | #include "nsRegion.h" // for nsIntRegion |
25 | | #include "nsTArray.h" // for nsTArray |
26 | | |
27 | | namespace mozilla { |
28 | | |
29 | | struct TileCoordUnit {}; |
30 | | template<> struct IsPixel<TileCoordUnit> : mozilla::TrueType {}; |
31 | | |
32 | | namespace layers { |
33 | | |
34 | | // You can enable all the TILING_LOG print statements by |
35 | | // changing the 0 to a 1 in the following #define. |
36 | | #define ENABLE_TILING_LOG 0 |
37 | | |
38 | | #if ENABLE_TILING_LOG |
39 | | # define TILING_LOG(...) printf_stderr(__VA_ARGS__); |
40 | | #else |
41 | | # define TILING_LOG(...) |
42 | | #endif |
43 | | |
44 | | // Normal integer division truncates towards zero, |
45 | | // we instead want to floor to hangle negative numbers. |
46 | | static inline int floor_div(int a, int b) |
47 | 0 | { |
48 | 0 | int rem = a % b; |
49 | 0 | int div = a/b; |
50 | 0 | if (rem == 0) { |
51 | 0 | return div; |
52 | 0 | } else { |
53 | 0 | // If the signs are different substract 1. |
54 | 0 | int sub; |
55 | 0 | sub = a ^ b; |
56 | 0 | // The results of this shift is either 0 or -1. |
57 | 0 | sub >>= 8*sizeof(int)-1; |
58 | 0 | return div+sub; |
59 | 0 | } |
60 | 0 | } Unexecuted instantiation: Unified_cpp_gfx_layers10.cpp:mozilla::layers::floor_div(int, int) Unexecuted instantiation: Unified_cpp_gfx_layers5.cpp:mozilla::layers::floor_div(int, int) Unexecuted instantiation: Unified_cpp_gfx_layers6.cpp:mozilla::layers::floor_div(int, int) Unexecuted instantiation: Unified_cpp_gfx_layers7.cpp:mozilla::layers::floor_div(int, int) |
61 | | |
62 | | // Tiles are aligned to a grid with one of the grid points at (0,0) and other |
63 | | // grid points spaced evenly in the x- and y-directions by GetTileSize() |
64 | | // multiplied by mResolution. GetScaledTileSize() provides convenience for |
65 | | // accessing these values. |
66 | | // |
67 | | // This tile buffer stores a valid region, which defines the areas that have |
68 | | // up-to-date content. The contents of tiles within this region will be reused |
69 | | // from paint to paint. It also stores the region that was modified in the last |
70 | | // paint operation; this is useful when one tiled layer buffer shadows another |
71 | | // (as in an off-main-thread-compositing scenario), so that the shadow tiled |
72 | | // layer buffer can correctly reflect the updates of the master layer buffer. |
73 | | // |
74 | | // The associated Tile may be of any type as long as the derived class can |
75 | | // validate and return tiles of that type. Tiles will be frequently copied, so |
76 | | // the tile type should be a reference or some other type with an efficient |
77 | | // copy constructor. |
78 | | // |
79 | | // The contents of the tile buffer will be rendered at the resolution specified |
80 | | // in mResolution, which can be altered with SetResolution. The resolution |
81 | | // should always be a factor of the tile length, to avoid tiles covering |
82 | | // non-integer amounts of pixels. |
83 | | |
84 | | // Size and Point in number of tiles rather than in pixels |
85 | | typedef gfx::IntSizeTyped<TileCoordUnit> TileCoordIntSize; |
86 | | typedef gfx::IntPointTyped<TileCoordUnit> TileCoordIntPoint; |
87 | | |
88 | | /** |
89 | | * Stores the origin and size of a tile buffer and handles switching between |
90 | | * tile indices and tile coordinates. |
91 | | * |
92 | | * Tile coordinates in TileCoordIntPoint take the first tile offset into account which |
93 | | * means that two TilesPlacement of the same layer and resolution give tile |
94 | | * coordinates in the same coordinate space (useful when changing the offset and/or |
95 | | * size of a tile buffer). |
96 | | */ |
97 | | struct TilesPlacement |
98 | | { |
99 | | TileCoordIntPoint mFirst; |
100 | | TileCoordIntSize mSize; |
101 | | |
102 | | TilesPlacement(int aFirstX, int aFirstY, |
103 | | int aRetainedWidth, int aRetainedHeight) |
104 | | : mFirst(aFirstX, aFirstY) |
105 | | , mSize(aRetainedWidth, aRetainedHeight) |
106 | 0 | { } |
107 | | |
108 | | int TileIndex(TileCoordIntPoint aCoord) const |
109 | 0 | { |
110 | 0 | return (aCoord.x - mFirst.x) * mSize.height + aCoord.y - mFirst.y; |
111 | 0 | } |
112 | | |
113 | | TileCoordIntPoint TileCoord(size_t aIndex) const |
114 | 0 | { |
115 | 0 | return TileCoordIntPoint( |
116 | 0 | mFirst.x + aIndex / mSize.height, |
117 | 0 | mFirst.y + aIndex % mSize.height |
118 | 0 | ); |
119 | 0 | } |
120 | | |
121 | | bool HasTile(TileCoordIntPoint aCoord) const |
122 | 0 | { |
123 | 0 | return aCoord.x >= mFirst.x && aCoord.x < mFirst.x + mSize.width && |
124 | 0 | aCoord.y >= mFirst.y && aCoord.y < mFirst.y + mSize.height; |
125 | 0 | } |
126 | | }; |
127 | | |
128 | | |
129 | | // Given a position i, this function returns the position inside the current tile. |
130 | | inline int GetTileStart(int i, int aTileLength) |
131 | 0 | { |
132 | 0 | return (i >= 0) ? (i % aTileLength) |
133 | 0 | : ((aTileLength - (-i % aTileLength)) % |
134 | 0 | aTileLength); |
135 | 0 | } |
136 | | |
137 | | // Rounds the given coordinate down to the nearest tile boundary. |
138 | 0 | inline int RoundDownToTileEdge(int aX, int aTileLength) { return aX - GetTileStart(aX, aTileLength); } |
139 | | |
140 | | template<typename Derived, typename Tile> |
141 | | class TiledLayerBuffer |
142 | | { |
143 | | public: |
144 | | TiledLayerBuffer() |
145 | | : mTiles(0, 0, 0, 0) |
146 | | , mResolution(1) |
147 | | , mTileSize(mozilla::gfx::gfxVars::TileSize()) |
148 | 0 | {} Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::ClientMultiTiledLayerBuffer, mozilla::layers::TileClient>::TiledLayerBuffer() Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::TiledLayerBufferComposite, mozilla::layers::TileHost>::TiledLayerBuffer() |
149 | | |
150 | 0 | ~TiledLayerBuffer() {} Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::ClientMultiTiledLayerBuffer, mozilla::layers::TileClient>::~TiledLayerBuffer() Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::TiledLayerBufferComposite, mozilla::layers::TileHost>::~TiledLayerBuffer() |
151 | | |
152 | | gfx::IntPoint GetTileOffset(TileCoordIntPoint aPosition) const |
153 | 0 | { |
154 | 0 | gfx::IntSize scaledTileSize = GetScaledTileSize(); |
155 | 0 | return gfx::IntPoint(aPosition.x * scaledTileSize.width, |
156 | 0 | aPosition.y * scaledTileSize.height) + mTileOrigin; |
157 | 0 | } Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::TiledLayerBufferComposite, mozilla::layers::TileHost>::GetTileOffset(mozilla::gfx::IntPointTyped<mozilla::TileCoordUnit>) const Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::ClientMultiTiledLayerBuffer, mozilla::layers::TileClient>::GetTileOffset(mozilla::gfx::IntPointTyped<mozilla::TileCoordUnit>) const |
158 | | |
159 | 0 | const TilesPlacement& GetPlacement() const { return mTiles; } |
160 | | |
161 | 0 | const gfx::IntSize& GetTileSize() const { return mTileSize; } |
162 | | |
163 | 0 | gfx::IntSize GetScaledTileSize() const { return gfx::IntSize::Round(gfx::Size(mTileSize) / mResolution); } Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::TiledLayerBufferComposite, mozilla::layers::TileHost>::GetScaledTileSize() const Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::ClientMultiTiledLayerBuffer, mozilla::layers::TileClient>::GetScaledTileSize() const |
164 | | |
165 | 0 | unsigned int GetTileCount() const { return mRetainedTiles.Length(); } |
166 | | |
167 | 0 | Tile& GetTile(size_t i) { return mRetainedTiles[i]; } |
168 | | |
169 | 0 | const nsIntRegion& GetValidRegion() const { return mValidRegion; } Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::TiledLayerBufferComposite, mozilla::layers::TileHost>::GetValidRegion() const Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::ClientMultiTiledLayerBuffer, mozilla::layers::TileClient>::GetValidRegion() const |
170 | | |
171 | | // Get and set draw scaling. mResolution affects the resolution at which the |
172 | | // contents of the buffer are drawn. mResolution has no effect on the |
173 | | // coordinate space of the valid region, but does affect the size of an |
174 | | // individual tile's rect in relation to the valid region. |
175 | | // Setting the resolution will invalidate the buffer. |
176 | 0 | float GetResolution() const { return mResolution; } |
177 | 0 | bool IsLowPrecision() const { return mResolution < 1; } |
178 | | |
179 | | void Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml, |
180 | | TextureDumpMode aCompress); |
181 | | |
182 | | protected: |
183 | | |
184 | | nsIntRegion mValidRegion; |
185 | | |
186 | | /** |
187 | | * mRetainedTiles is a rectangular buffer of mTiles.mSize.width x mTiles.mSize.height |
188 | | * stored as column major with the same origin as mValidRegion.GetBounds(). |
189 | | * Any tile that does not intersect mValidRegion is a PlaceholderTile. |
190 | | * Only the region intersecting with mValidRegion should be read from a tile, |
191 | | * another other region is assumed to be uninitialized. The contents of the |
192 | | * tiles is scaled by mResolution. |
193 | | */ |
194 | | nsTArray<Tile> mRetainedTiles; |
195 | | TilesPlacement mTiles; |
196 | | float mResolution; |
197 | | gfx::IntSize mTileSize; |
198 | | gfx::IntPoint mTileOrigin; |
199 | | }; |
200 | | |
201 | | template<typename Derived, typename Tile> void |
202 | | TiledLayerBuffer<Derived, Tile>::Dump(std::stringstream& aStream, |
203 | | const char* aPrefix, |
204 | | bool aDumpHtml, |
205 | | TextureDumpMode aCompress) |
206 | 0 | { |
207 | 0 | for (size_t i = 0; i < mRetainedTiles.Length(); ++i) { |
208 | 0 | const TileCoordIntPoint tileCoord = mTiles.TileCoord(i); |
209 | 0 | gfx::IntPoint tileOffset = GetTileOffset(tileCoord); |
210 | 0 |
|
211 | 0 | aStream << "\n" << aPrefix << "Tile (x=" << |
212 | 0 | tileOffset.x << ", y=" << tileOffset.y << "): "; |
213 | 0 | if (!mRetainedTiles[i].IsPlaceholderTile()) { |
214 | 0 | mRetainedTiles[i].DumpTexture(aStream, aCompress); |
215 | 0 | } else { |
216 | 0 | aStream << "empty tile"; |
217 | 0 | } |
218 | 0 | } |
219 | 0 | } Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::ClientMultiTiledLayerBuffer, mozilla::layers::TileClient>::Dump(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, char const*, bool, mozilla::layers::TextureDumpMode) Unexecuted instantiation: mozilla::layers::TiledLayerBuffer<mozilla::layers::TiledLayerBufferComposite, mozilla::layers::TileHost>::Dump(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, char const*, bool, mozilla::layers::TextureDumpMode) |
220 | | |
221 | | } // namespace layers |
222 | | } // namespace mozilla |
223 | | |
224 | | #endif // GFX_TILEDLAYERBUFFER_H |