2017-10-28 02:10:06 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-04-17 02:22:59 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef GFX_TILEDLAYERBUFFER_H
|
|
|
|
#define GFX_TILEDLAYERBUFFER_H
|
|
|
|
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
// Debug defines
|
2012-04-17 02:22:59 +04:00
|
|
|
//#define GFX_TILEDLAYER_DEBUG_OVERLAY
|
|
|
|
//#define GFX_TILEDLAYER_PREF_WARNINGS
|
2015-03-23 20:01:02 +03:00
|
|
|
//#define GFX_TILEDLAYER_RETAINING_LOG
|
2012-04-17 02:22:59 +04:00
|
|
|
|
2013-08-12 03:17:23 +04:00
|
|
|
#include <stdint.h> // for uint16_t, uint32_t
|
|
|
|
#include <sys/types.h> // for int32_t
|
2015-03-23 20:01:02 +03:00
|
|
|
#include "LayersLogging.h" // for print_stderr
|
2016-08-04 21:33:43 +03:00
|
|
|
#include "mozilla/gfx/gfxVars.h"
|
2015-02-11 06:45:38 +03:00
|
|
|
#include "mozilla/gfx/Logging.h" // for gfxCriticalError
|
2015-09-29 01:51:37 +03:00
|
|
|
#include "mozilla/layers/LayersTypes.h" // for TextureDumpMode
|
2015-02-10 01:34:50 +03:00
|
|
|
#include "nsDebug.h" // for NS_ASSERTION
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "nsPoint.h" // for nsIntPoint
|
2015-05-07 12:07:53 +03:00
|
|
|
#include "nsRect.h" // for mozilla::gfx::IntRect
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "nsRegion.h" // for nsIntRegion
|
|
|
|
#include "nsTArray.h" // for nsTArray
|
2012-04-17 02:22:59 +04:00
|
|
|
|
|
|
|
namespace mozilla {
|
2015-06-10 18:56:34 +03:00
|
|
|
|
2018-04-20 00:03:24 +03:00
|
|
|
struct TileCoordUnit {};
|
|
|
|
template<> struct IsPixel<TileCoordUnit> : mozilla::TrueType {};
|
2015-06-10 18:56:34 +03:00
|
|
|
|
2012-04-17 02:22:59 +04:00
|
|
|
namespace layers {
|
|
|
|
|
2014-07-08 20:38:49 +04:00
|
|
|
// You can enable all the TILING_LOG print statements by
|
|
|
|
// changing the 0 to a 1 in the following #define.
|
|
|
|
#define ENABLE_TILING_LOG 0
|
|
|
|
|
|
|
|
#if ENABLE_TILING_LOG
|
2014-07-16 20:42:35 +04:00
|
|
|
# define TILING_LOG(...) printf_stderr(__VA_ARGS__);
|
2014-06-09 22:02:39 +04:00
|
|
|
#else
|
2014-07-16 20:42:35 +04:00
|
|
|
# define TILING_LOG(...)
|
2014-06-09 22:02:39 +04:00
|
|
|
#endif
|
|
|
|
|
2015-06-10 18:56:34 +03:00
|
|
|
// Normal integer division truncates towards zero,
|
|
|
|
// we instead want to floor to hangle negative numbers.
|
|
|
|
static inline int floor_div(int a, int b)
|
|
|
|
{
|
|
|
|
int rem = a % b;
|
|
|
|
int div = a/b;
|
|
|
|
if (rem == 0) {
|
|
|
|
return div;
|
|
|
|
} else {
|
|
|
|
// If the signs are different substract 1.
|
|
|
|
int sub;
|
|
|
|
sub = a ^ b;
|
|
|
|
// The results of this shift is either 0 or -1.
|
|
|
|
sub >>= 8*sizeof(int)-1;
|
|
|
|
return div+sub;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-23 18:49:52 +04:00
|
|
|
// Tiles are aligned to a grid with one of the grid points at (0,0) and other
|
2014-04-04 21:42:44 +04:00
|
|
|
// grid points spaced evenly in the x- and y-directions by GetTileSize()
|
|
|
|
// multiplied by mResolution. GetScaledTileSize() provides convenience for
|
2012-11-22 02:34:18 +04:00
|
|
|
// accessing these values.
|
2012-05-23 18:49:52 +04:00
|
|
|
//
|
2012-04-17 02:22:59 +04:00
|
|
|
// This tile buffer stores a valid region, which defines the areas that have
|
|
|
|
// up-to-date content. The contents of tiles within this region will be reused
|
|
|
|
// from paint to paint. It also stores the region that was modified in the last
|
|
|
|
// paint operation; this is useful when one tiled layer buffer shadows another
|
|
|
|
// (as in an off-main-thread-compositing scenario), so that the shadow tiled
|
|
|
|
// layer buffer can correctly reflect the updates of the master layer buffer.
|
|
|
|
//
|
|
|
|
// The associated Tile may be of any type as long as the derived class can
|
|
|
|
// validate and return tiles of that type. Tiles will be frequently copied, so
|
|
|
|
// the tile type should be a reference or some other type with an efficient
|
|
|
|
// copy constructor.
|
|
|
|
//
|
2012-11-22 02:34:18 +04:00
|
|
|
// The contents of the tile buffer will be rendered at the resolution specified
|
|
|
|
// in mResolution, which can be altered with SetResolution. The resolution
|
|
|
|
// should always be a factor of the tile length, to avoid tiles covering
|
|
|
|
// non-integer amounts of pixels.
|
2012-04-17 02:22:59 +04:00
|
|
|
|
2015-06-10 18:56:34 +03:00
|
|
|
// Size and Point in number of tiles rather than in pixels
|
2018-04-20 00:03:24 +03:00
|
|
|
typedef gfx::IntSizeTyped<TileCoordUnit> TileCoordIntSize;
|
|
|
|
typedef gfx::IntPointTyped<TileCoordUnit> TileCoordIntPoint;
|
2015-06-10 18:56:34 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Stores the origin and size of a tile buffer and handles switching between
|
2018-04-20 17:42:35 +03:00
|
|
|
* tile indices and tile coordinates.
|
2015-06-10 18:56:34 +03:00
|
|
|
*
|
2018-04-20 17:42:35 +03:00
|
|
|
* Tile coordinates in TileCoordIntPoint take the first tile offset into account which
|
2015-06-10 18:56:34 +03:00
|
|
|
* means that two TilesPlacement of the same layer and resolution give tile
|
2018-04-20 17:42:35 +03:00
|
|
|
* coordinates in the same coordinate space (useful when changing the offset and/or
|
2015-06-10 18:56:34 +03:00
|
|
|
* size of a tile buffer).
|
|
|
|
*/
|
2018-04-20 17:42:35 +03:00
|
|
|
struct TilesPlacement
|
|
|
|
{
|
2018-04-20 00:03:24 +03:00
|
|
|
TileCoordIntPoint mFirst;
|
|
|
|
TileCoordIntSize mSize;
|
2015-06-10 18:56:34 +03:00
|
|
|
|
|
|
|
TilesPlacement(int aFirstX, int aFirstY,
|
|
|
|
int aRetainedWidth, int aRetainedHeight)
|
|
|
|
: mFirst(aFirstX, aFirstY)
|
|
|
|
, mSize(aRetainedWidth, aRetainedHeight)
|
2018-04-20 17:42:35 +03:00
|
|
|
{ }
|
2015-06-10 18:56:34 +03:00
|
|
|
|
2018-04-20 17:42:35 +03:00
|
|
|
int TileIndex(TileCoordIntPoint aCoord) const
|
|
|
|
{
|
|
|
|
return (aCoord.x - mFirst.x) * mSize.height + aCoord.y - mFirst.y;
|
2015-06-10 18:56:34 +03:00
|
|
|
}
|
|
|
|
|
2018-04-20 17:42:35 +03:00
|
|
|
TileCoordIntPoint TileCoord(size_t aIndex) const
|
|
|
|
{
|
2018-04-20 00:03:24 +03:00
|
|
|
return TileCoordIntPoint(
|
2015-06-10 18:56:34 +03:00
|
|
|
mFirst.x + aIndex / mSize.height,
|
|
|
|
mFirst.y + aIndex % mSize.height
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-04-20 17:42:35 +03:00
|
|
|
bool HasTile(TileCoordIntPoint aCoord) const
|
|
|
|
{
|
|
|
|
return aCoord.x >= mFirst.x && aCoord.x < mFirst.x + mSize.width &&
|
|
|
|
aCoord.y >= mFirst.y && aCoord.y < mFirst.y + mSize.height;
|
2015-06-10 18:56:34 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-07-01 14:50:58 +03:00
|
|
|
|
|
|
|
// Given a position i, this function returns the position inside the current tile.
|
2018-04-20 17:42:35 +03:00
|
|
|
inline int GetTileStart(int i, int aTileLength)
|
|
|
|
{
|
2015-07-01 14:50:58 +03:00
|
|
|
return (i >= 0) ? (i % aTileLength)
|
|
|
|
: ((aTileLength - (-i % aTileLength)) %
|
|
|
|
aTileLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Rounds the given coordinate down to the nearest tile boundary.
|
|
|
|
inline int RoundDownToTileEdge(int aX, int aTileLength) { return aX - GetTileStart(aX, aTileLength); }
|
|
|
|
|
2012-04-17 02:22:59 +04:00
|
|
|
template<typename Derived, typename Tile>
|
|
|
|
class TiledLayerBuffer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
TiledLayerBuffer()
|
2015-06-10 18:56:34 +03:00
|
|
|
: mTiles(0, 0, 0, 0)
|
2012-11-22 02:34:18 +04:00
|
|
|
, mResolution(1)
|
2016-08-16 12:11:56 +03:00
|
|
|
, mTileSize(mozilla::gfx::gfxVars::TileSize())
|
2012-04-17 02:22:59 +04:00
|
|
|
{}
|
|
|
|
|
|
|
|
~TiledLayerBuffer() {}
|
|
|
|
|
2018-04-20 17:42:35 +03:00
|
|
|
gfx::IntPoint GetTileOffset(TileCoordIntPoint aPosition) const
|
|
|
|
{
|
2015-06-10 18:59:19 +03:00
|
|
|
gfx::IntSize scaledTileSize = GetScaledTileSize();
|
|
|
|
return gfx::IntPoint(aPosition.x * scaledTileSize.width,
|
2015-07-29 19:01:21 +03:00
|
|
|
aPosition.y * scaledTileSize.height) + mTileOrigin;
|
2015-06-10 18:59:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const TilesPlacement& GetPlacement() const { return mTiles; }
|
|
|
|
|
2014-04-04 21:42:44 +04:00
|
|
|
const gfx::IntSize& GetTileSize() const { return mTileSize; }
|
2013-07-31 21:26:44 +04:00
|
|
|
|
2016-07-26 17:48:34 +03:00
|
|
|
gfx::IntSize GetScaledTileSize() const { return gfx::IntSize::Round(gfx::Size(mTileSize) / mResolution); }
|
2012-04-17 02:22:59 +04:00
|
|
|
|
2012-04-25 06:48:33 +04:00
|
|
|
unsigned int GetTileCount() const { return mRetainedTiles.Length(); }
|
|
|
|
|
2015-07-01 14:50:58 +03:00
|
|
|
Tile& GetTile(size_t i) { return mRetainedTiles[i]; }
|
|
|
|
|
2012-04-17 02:22:59 +04:00
|
|
|
const nsIntRegion& GetValidRegion() const { return mValidRegion; }
|
|
|
|
|
2012-11-22 02:34:18 +04:00
|
|
|
// Get and set draw scaling. mResolution affects the resolution at which the
|
|
|
|
// contents of the buffer are drawn. mResolution has no effect on the
|
|
|
|
// coordinate space of the valid region, but does affect the size of an
|
|
|
|
// individual tile's rect in relation to the valid region.
|
|
|
|
// Setting the resolution will invalidate the buffer.
|
|
|
|
float GetResolution() const { return mResolution; }
|
2012-11-22 02:34:19 +04:00
|
|
|
bool IsLowPrecision() const { return mResolution < 1; }
|
2012-11-22 02:34:18 +04:00
|
|
|
|
2015-09-29 01:51:37 +03:00
|
|
|
void Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml,
|
|
|
|
TextureDumpMode aCompress);
|
2014-12-18 21:32:45 +03:00
|
|
|
|
2012-04-17 02:22:59 +04:00
|
|
|
protected:
|
|
|
|
|
|
|
|
nsIntRegion mValidRegion;
|
|
|
|
|
|
|
|
/**
|
2015-06-10 18:56:34 +03:00
|
|
|
* mRetainedTiles is a rectangular buffer of mTiles.mSize.width x mTiles.mSize.height
|
2012-04-17 02:22:59 +04:00
|
|
|
* stored as column major with the same origin as mValidRegion.GetBounds().
|
|
|
|
* Any tile that does not intersect mValidRegion is a PlaceholderTile.
|
|
|
|
* Only the region intersecting with mValidRegion should be read from a tile,
|
2012-11-22 02:34:18 +04:00
|
|
|
* another other region is assumed to be uninitialized. The contents of the
|
|
|
|
* tiles is scaled by mResolution.
|
2012-04-17 02:22:59 +04:00
|
|
|
*/
|
|
|
|
nsTArray<Tile> mRetainedTiles;
|
2015-06-10 18:56:34 +03:00
|
|
|
TilesPlacement mTiles;
|
2012-11-22 02:34:18 +04:00
|
|
|
float mResolution;
|
2014-04-04 21:42:44 +04:00
|
|
|
gfx::IntSize mTileSize;
|
2015-07-29 19:01:21 +03:00
|
|
|
gfx::IntPoint mTileOrigin;
|
2012-04-17 02:22:59 +04:00
|
|
|
};
|
|
|
|
|
2014-12-18 21:32:45 +03:00
|
|
|
template<typename Derived, typename Tile> void
|
|
|
|
TiledLayerBuffer<Derived, Tile>::Dump(std::stringstream& aStream,
|
|
|
|
const char* aPrefix,
|
2015-09-29 01:51:37 +03:00
|
|
|
bool aDumpHtml,
|
|
|
|
TextureDumpMode aCompress)
|
2014-12-18 21:32:45 +03:00
|
|
|
{
|
2015-07-01 14:50:58 +03:00
|
|
|
for (size_t i = 0; i < mRetainedTiles.Length(); ++i) {
|
2018-04-20 17:42:35 +03:00
|
|
|
const TileCoordIntPoint tileCoord = mTiles.TileCoord(i);
|
|
|
|
gfx::IntPoint tileOffset = GetTileOffset(tileCoord);
|
2015-07-01 14:50:58 +03:00
|
|
|
|
|
|
|
aStream << "\n" << aPrefix << "Tile (x=" <<
|
|
|
|
tileOffset.x << ", y=" << tileOffset.y << "): ";
|
|
|
|
if (!mRetainedTiles[i].IsPlaceholderTile()) {
|
2015-09-29 01:51:37 +03:00
|
|
|
mRetainedTiles[i].DumpTexture(aStream, aCompress);
|
2014-03-08 01:34:04 +04:00
|
|
|
} else {
|
2015-07-01 14:50:58 +03:00
|
|
|
aStream << "empty tile";
|
2012-04-17 02:22:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|
2012-04-17 02:22:59 +04:00
|
|
|
|
|
|
|
#endif // GFX_TILEDLAYERBUFFER_H
|