Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/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
}
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
  { }
107
108
  int TileIndex(TileCoordIntPoint aCoord) const
109
  {
110
    return (aCoord.x - mFirst.x) * mSize.height + aCoord.y - mFirst.y;
111
  }
112
113
  TileCoordIntPoint TileCoord(size_t aIndex) const
114
  {
115
    return TileCoordIntPoint(
116
      mFirst.x + aIndex / mSize.height,
117
      mFirst.y + aIndex % mSize.height
118
    );
119
  }
120
121
  bool HasTile(TileCoordIntPoint aCoord) const
122
  {
123
    return aCoord.x >= mFirst.x && aCoord.x < mFirst.x + mSize.width &&
124
           aCoord.y >= mFirst.y && aCoord.y < mFirst.y + mSize.height;
125
  }
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
{
132
  return (i >= 0) ? (i % aTileLength)
133
                  : ((aTileLength - (-i % aTileLength)) %
134
                     aTileLength);
135
}
136
137
// Rounds the given coordinate down to the nearest tile boundary.
138
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
  {}
149
150
  ~TiledLayerBuffer() {}
151
152
  gfx::IntPoint GetTileOffset(TileCoordIntPoint aPosition) const
153
  {
154
    gfx::IntSize scaledTileSize = GetScaledTileSize();
155
    return gfx::IntPoint(aPosition.x * scaledTileSize.width,
156
                         aPosition.y * scaledTileSize.height) + mTileOrigin;
157
  }
158
159
  const TilesPlacement& GetPlacement() const { return mTiles; }
160
161
  const gfx::IntSize& GetTileSize() const { return mTileSize; }
162
163
  gfx::IntSize GetScaledTileSize() const { return gfx::IntSize::Round(gfx::Size(mTileSize) / mResolution); }
164
165
  unsigned int GetTileCount() const { return mRetainedTiles.Length(); }
166
167
  Tile& GetTile(size_t i) { return mRetainedTiles[i]; }
168
169
  const nsIntRegion& GetValidRegion() const { return mValidRegion; }
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
  float GetResolution() const { return mResolution; }
177
  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
{
207
  for (size_t i = 0; i < mRetainedTiles.Length(); ++i) {
208
    const TileCoordIntPoint tileCoord = mTiles.TileCoord(i);
209
    gfx::IntPoint tileOffset = GetTileOffset(tileCoord);
210
211
    aStream << "\n" << aPrefix << "Tile (x=" <<
212
      tileOffset.x << ", y=" << tileOffset.y << "): ";
213
    if (!mRetainedTiles[i].IsPlaceholderTile()) {
214
      mRetainedTiles[i].DumpTexture(aStream, aCompress);
215
    } else {
216
      aStream << "empty tile";
217
    }
218
  }
219
}
220
221
} // namespace layers
222
} // namespace mozilla
223
224
#endif // GFX_TILEDLAYERBUFFER_H