Bug 990608 - Make tile size configurable. r=tn,nical,bgirard

This commit is contained in:
Chris Lord 2014-04-04 18:42:44 +01:00
parent f54bf7467b
commit 4b3c68d60c
15 changed files with 123 additions and 106 deletions

View File

@ -406,7 +406,8 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
float aTopMargin, float aTopMargin,
float aRightMargin, float aRightMargin,
float aBottomMargin, float aBottomMargin,
uint32_t aAlignment, uint32_t aAlignmentX,
uint32_t aAlignmentY,
nsIDOMElement* aElement, nsIDOMElement* aElement,
uint32_t aPriority) uint32_t aPriority)
{ {
@ -447,7 +448,7 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
aLeftMargin); aLeftMargin);
content->SetProperty(nsGkAtoms::DisplayPortMargins, content->SetProperty(nsGkAtoms::DisplayPortMargins,
new DisplayPortMarginsPropertyData(displayportMargins, aAlignment, aPriority), new DisplayPortMarginsPropertyData(displayportMargins, aAlignmentX, aAlignmentY, aPriority),
nsINode::DeleteProperty<DisplayPortMarginsPropertyData>); nsINode::DeleteProperty<DisplayPortMarginsPropertyData>);
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame(); nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();

View File

@ -176,7 +176,8 @@ interface nsIDOMWindowUtils : nsISupports {
in float aTopMargin, in float aTopMargin,
in float aRightMargin, in float aRightMargin,
in float aBottomMargin, in float aBottomMargin,
in uint32_t aAlignment, in uint32_t aAlignmentX,
in uint32_t aAlignmentY,
in nsIDOMElement aElement, in nsIDOMElement aElement,
in uint32_t aPriority); in uint32_t aPriority);

View File

@ -75,10 +75,11 @@ GetBitsPerTexel(GLenum format, GLenum type)
/* static */ void /* static */ void
GfxTexturesReporter::UpdateAmount(MemoryUse action, GLenum format, GfxTexturesReporter::UpdateAmount(MemoryUse action, GLenum format,
GLenum type, uint16_t tileSize) GLenum type, int32_t tileWidth,
int32_t tileHeight)
{ {
int64_t bitsPerTexel = GetBitsPerTexel(format, type); int64_t bitsPerTexel = GetBitsPerTexel(format, type);
int64_t bytes = int64_t(tileSize) * int64_t(tileSize) * bitsPerTexel/8; int64_t bytes = int64_t(tileWidth) * int64_t(tileHeight) * bitsPerTexel/8;
if (action == MemoryFreed) { if (action == MemoryFreed) {
sAmount -= bytes; sAmount -= bytes;
} else { } else {

View File

@ -39,7 +39,7 @@ public:
// When memory is used/freed for tile textures, call this method to update // When memory is used/freed for tile textures, call this method to update
// the value reported by this memory reporter. // the value reported by this memory reporter.
static void UpdateAmount(MemoryUse action, GLenum format, GLenum type, static void UpdateAmount(MemoryUse action, GLenum format, GLenum type,
uint16_t tileSize); int32_t tileWidth, int32_t tileHeight);
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData) nsISupports* aData)

View File

@ -5,14 +5,13 @@
#ifndef GFX_TILEDLAYERBUFFER_H #ifndef GFX_TILEDLAYERBUFFER_H
#define GFX_TILEDLAYERBUFFER_H #define GFX_TILEDLAYERBUFFER_H
#define TILEDLAYERBUFFER_TILE_SIZE 256
// Debug defines // Debug defines
//#define GFX_TILEDLAYER_DEBUG_OVERLAY //#define GFX_TILEDLAYER_DEBUG_OVERLAY
//#define GFX_TILEDLAYER_PREF_WARNINGS //#define GFX_TILEDLAYER_PREF_WARNINGS
#include <stdint.h> // for uint16_t, uint32_t #include <stdint.h> // for uint16_t, uint32_t
#include <sys/types.h> // for int32_t #include <sys/types.h> // for int32_t
#include "gfxPrefs.h" // for gfxPrefs::LayersTileWidth/Height
#include "nsDebug.h" // for NS_ABORT_IF_FALSE #include "nsDebug.h" // for NS_ABORT_IF_FALSE
#include "nsPoint.h" // for nsIntPoint #include "nsPoint.h" // for nsIntPoint
#include "nsRect.h" // for nsIntRect #include "nsRect.h" // for nsIntRect
@ -32,8 +31,8 @@ namespace layers {
// template pattern. // template pattern.
// //
// Tiles are aligned to a grid with one of the grid points at (0,0) and other // Tiles are aligned to a grid with one of the grid points at (0,0) and other
// grid points spaced evenly in the x- and y-directions by GetTileLength() // grid points spaced evenly in the x- and y-directions by GetTileSize()
// multiplied by mResolution. GetScaledTileLength() provides convenience for // multiplied by mResolution. GetScaledTileSize() provides convenience for
// accessing these values. // accessing these values.
// //
// This tile buffer stores a valid region, which defines the areas that have // This tile buffer stores a valid region, which defines the areas that have
@ -85,22 +84,23 @@ public:
: mRetainedWidth(0) : mRetainedWidth(0)
, mRetainedHeight(0) , mRetainedHeight(0)
, mResolution(1) , mResolution(1)
, mTileSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight())
{} {}
~TiledLayerBuffer() {} ~TiledLayerBuffer() {}
// Given a tile origin aligned to a multiple of GetScaledTileLength, // Given a tile origin aligned to a multiple of GetScaledTileSize,
// return the tile that describes that region. // return the tile that describes that region.
// NOTE: To get the valid area of that tile you must intersect // NOTE: To get the valid area of that tile you must intersect
// (aTileOrigin.x, aTileOrigin.y, // (aTileOrigin.x, aTileOrigin.y,
// GetScaledTileLength(), GetScaledTileLength()) // GetScaledTileSize().width, GetScaledTileSize().height)
// and GetValidRegion() to get the area of the tile that is valid. // and GetValidRegion() to get the area of the tile that is valid.
Tile GetTile(const nsIntPoint& aTileOrigin) const; Tile GetTile(const nsIntPoint& aTileOrigin) const;
// Given a tile x, y relative to the top left of the layer, this function // Given a tile x, y relative to the top left of the layer, this function
// will return the tile for // will return the tile for
// (x*GetScaledTileLength(), y*GetScaledTileLength(), // (x*GetScaledTileSize().width, y*GetScaledTileSize().height,
// GetScaledTileLength(), GetScaledTileLength()) // GetScaledTileSize().width, GetScaledTileSize().height)
Tile GetTile(int x, int y) const; Tile GetTile(int x, int y) const;
// This operates the same as GetTile(aTileOrigin), but will also replace the // This operates the same as GetTile(aTileOrigin), but will also replace the
@ -113,12 +113,9 @@ public:
// on the removed tile. // on the removed tile.
bool RemoveTile(int x, int y, Tile& aRemovedTile); bool RemoveTile(int x, int y, Tile& aRemovedTile);
uint16_t GetTileLength() const { return TILEDLAYERBUFFER_TILE_SIZE; } const gfx::IntSize& GetTileSize() const { return mTileSize; }
#ifdef MOZ_WIDGET_ANDROID gfx::IntSize GetScaledTileSize() const { return RoundedToInt(gfx::Size(mTileSize) / mResolution); }
MOZ_NEVER_INLINE // bug 881018 causes wrong results when GetScaledTileLength is inlined
#endif
uint32_t GetScaledTileLength() const { return TILEDLAYERBUFFER_TILE_SIZE / mResolution; }
unsigned int GetTileCount() const { return mRetainedTiles.Length(); } unsigned int GetTileCount() const { return mRetainedTiles.Length(); }
@ -127,14 +124,14 @@ public:
void ClearPaintedRegion() { mPaintedRegion.SetEmpty(); } void ClearPaintedRegion() { mPaintedRegion.SetEmpty(); }
// Given a position i, this function returns the position inside the current tile. // Given a position i, this function returns the position inside the current tile.
int GetTileStart(int i) const { int GetTileStart(int i, int aTileLength) const {
return (i >= 0) ? (i % GetScaledTileLength()) return (i >= 0) ? (i % aTileLength)
: ((GetScaledTileLength() - (-i % GetScaledTileLength())) % : ((aTileLength - (-i % aTileLength)) %
GetScaledTileLength()); aTileLength);
} }
// Rounds the given coordinate down to the nearest tile boundary. // Rounds the given coordinate down to the nearest tile boundary.
int RoundDownToTileEdge(int aX) const { return aX - GetTileStart(aX); } int RoundDownToTileEdge(int aX, int aTileLength) const { return aX - GetTileStart(aX, aTileLength); }
// Get and set draw scaling. mResolution affects the resolution at which the // Get and set draw scaling. mResolution affects the resolution at which the
// contents of the buffer are drawn. mResolution has no effect on the // contents of the buffer are drawn. mResolution has no effect on the
@ -178,6 +175,7 @@ protected:
int mRetainedWidth; // in tiles int mRetainedWidth; // in tiles
int mRetainedHeight; // in tiles int mRetainedHeight; // in tiles
float mResolution; float mResolution;
gfx::IntSize mTileSize;
private: private:
const Derived& AsDerived() const { return *static_cast<const Derived*>(this); } const Derived& AsDerived() const { return *static_cast<const Derived*>(this); }
@ -244,10 +242,11 @@ TiledLayerBuffer<Derived, Tile>::GetTile(const nsIntPoint& aTileOrigin) const
// TODO Cache firstTileOriginX/firstTileOriginY // TODO Cache firstTileOriginX/firstTileOriginY
// Find the tile x/y of the first tile and the target tile relative to the (0, 0) // Find the tile x/y of the first tile and the target tile relative to the (0, 0)
// origin, the difference is the tile x/y relative to the start of the tile buffer. // origin, the difference is the tile x/y relative to the start of the tile buffer.
int firstTileX = floor_div(mValidRegion.GetBounds().x, GetScaledTileLength()); gfx::IntSize scaledTileSize = GetScaledTileSize();
int firstTileY = floor_div(mValidRegion.GetBounds().y, GetScaledTileLength()); int firstTileX = floor_div(mValidRegion.GetBounds().x, scaledTileSize.width);
return GetTile(floor_div(aTileOrigin.x, GetScaledTileLength()) - firstTileX, int firstTileY = floor_div(mValidRegion.GetBounds().y, scaledTileSize.height);
floor_div(aTileOrigin.y, GetScaledTileLength()) - firstTileY); return GetTile(floor_div(aTileOrigin.x, scaledTileSize.width) - firstTileX,
floor_div(aTileOrigin.y, scaledTileSize.height) - firstTileY);
} }
template<typename Derived, typename Tile> Tile template<typename Derived, typename Tile> Tile
@ -261,10 +260,11 @@ template<typename Derived, typename Tile> bool
TiledLayerBuffer<Derived, Tile>::RemoveTile(const nsIntPoint& aTileOrigin, TiledLayerBuffer<Derived, Tile>::RemoveTile(const nsIntPoint& aTileOrigin,
Tile& aRemovedTile) Tile& aRemovedTile)
{ {
int firstTileX = floor_div(mValidRegion.GetBounds().x, GetScaledTileLength()); gfx::IntSize scaledTileSize = GetScaledTileSize();
int firstTileY = floor_div(mValidRegion.GetBounds().y, GetScaledTileLength()); int firstTileX = floor_div(mValidRegion.GetBounds().x, scaledTileSize.width);
return RemoveTile(floor_div(aTileOrigin.x, GetScaledTileLength()) - firstTileX, int firstTileY = floor_div(mValidRegion.GetBounds().y, scaledTileSize.height);
floor_div(aTileOrigin.y, GetScaledTileLength()) - firstTileY, return RemoveTile(floor_div(aTileOrigin.x, scaledTileSize.width) - firstTileX,
floor_div(aTileOrigin.y, scaledTileSize.height) - firstTileY,
aRemovedTile); aRemovedTile);
} }
@ -285,14 +285,16 @@ template<typename Derived, typename Tile> void
TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion, TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
const nsIntRegion& aPaintRegion) const nsIntRegion& aPaintRegion)
{ {
gfx::IntSize scaledTileSize = GetScaledTileSize();
nsTArray<Tile> newRetainedTiles; nsTArray<Tile> newRetainedTiles;
nsTArray<Tile>& oldRetainedTiles = mRetainedTiles; nsTArray<Tile>& oldRetainedTiles = mRetainedTiles;
const nsIntRect oldBound = mValidRegion.GetBounds(); const nsIntRect oldBound = mValidRegion.GetBounds();
const nsIntRect newBound = aNewValidRegion.GetBounds(); const nsIntRect newBound = aNewValidRegion.GetBounds();
const nsIntPoint oldBufferOrigin(RoundDownToTileEdge(oldBound.x), const nsIntPoint oldBufferOrigin(RoundDownToTileEdge(oldBound.x, scaledTileSize.width),
RoundDownToTileEdge(oldBound.y)); RoundDownToTileEdge(oldBound.y, scaledTileSize.height));
const nsIntPoint newBufferOrigin(RoundDownToTileEdge(newBound.x), const nsIntPoint newBufferOrigin(RoundDownToTileEdge(newBound.x, scaledTileSize.width),
RoundDownToTileEdge(newBound.y)); RoundDownToTileEdge(newBound.y, scaledTileSize.height));
const nsIntRegion& oldValidRegion = mValidRegion; const nsIntRegion& oldValidRegion = mValidRegion;
const nsIntRegion& newValidRegion = aNewValidRegion; const nsIntRegion& newValidRegion = aNewValidRegion;
const int oldRetainedHeight = mRetainedHeight; const int oldRetainedHeight = mRetainedHeight;
@ -309,14 +311,14 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
for (int32_t x = newBound.x; x < newBound.XMost(); tileX++) { for (int32_t x = newBound.x; x < newBound.XMost(); tileX++) {
// Compute tileRect(x,y,width,height) in layer space coordinate // Compute tileRect(x,y,width,height) in layer space coordinate
// giving us the rect of the tile that hits the newBounds. // giving us the rect of the tile that hits the newBounds.
int width = GetScaledTileLength() - GetTileStart(x); int width = scaledTileSize.width - GetTileStart(x, scaledTileSize.width);
if (x + width > newBound.XMost()) { if (x + width > newBound.XMost()) {
width = newBound.x + newBound.width - x; width = newBound.x + newBound.width - x;
} }
tileY = 0; tileY = 0;
for (int32_t y = newBound.y; y < newBound.YMost(); tileY++) { for (int32_t y = newBound.y; y < newBound.YMost(); tileY++) {
int height = GetScaledTileLength() - GetTileStart(y); int height = scaledTileSize.height - GetTileStart(y, scaledTileSize.height);
if (y + height > newBound.y + newBound.height) { if (y + height > newBound.y + newBound.height) {
height = newBound.y + newBound.height - y; height = newBound.y + newBound.height - y;
} }
@ -326,8 +328,8 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
// This old tiles contains some valid area so move it to the new tile // This old tiles contains some valid area so move it to the new tile
// buffer. Replace the tile in the old buffer with a placeholder // buffer. Replace the tile in the old buffer with a placeholder
// to leave the old buffer index unaffected. // to leave the old buffer index unaffected.
int tileX = floor_div(x - oldBufferOrigin.x, GetScaledTileLength()); int tileX = floor_div(x - oldBufferOrigin.x, scaledTileSize.width);
int tileY = floor_div(y - oldBufferOrigin.y, GetScaledTileLength()); int tileY = floor_div(y - oldBufferOrigin.y, scaledTileSize.height);
int index = tileX * oldRetainedHeight + tileY; int index = tileX * oldRetainedHeight + tileY;
// The tile may have been removed, skip over it in this case. // The tile may have been removed, skip over it in this case.
@ -409,15 +411,15 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
for (int x = newBound.x; x < newBound.x + newBound.width; tileX++) { for (int x = newBound.x; x < newBound.x + newBound.width; tileX++) {
// Compute tileRect(x,y,width,height) in layer space coordinate // Compute tileRect(x,y,width,height) in layer space coordinate
// giving us the rect of the tile that hits the newBounds. // giving us the rect of the tile that hits the newBounds.
int tileStartX = RoundDownToTileEdge(x); int tileStartX = RoundDownToTileEdge(x, scaledTileSize.width);
int width = GetScaledTileLength() - GetTileStart(x); int width = scaledTileSize.width - GetTileStart(x, scaledTileSize.width);
if (x + width > newBound.XMost()) if (x + width > newBound.XMost())
width = newBound.XMost() - x; width = newBound.XMost() - x;
tileY = 0; tileY = 0;
for (int y = newBound.y; y < newBound.y + newBound.height; tileY++) { for (int y = newBound.y; y < newBound.y + newBound.height; tileY++) {
int tileStartY = RoundDownToTileEdge(y); int tileStartY = RoundDownToTileEdge(y, scaledTileSize.height);
int height = GetScaledTileLength() - GetTileStart(y); int height = scaledTileSize.height - GetTileStart(y, scaledTileSize.height);
if (y + height > newBound.YMost()) { if (y + height > newBound.YMost()) {
height = newBound.YMost() - y; height = newBound.YMost() - y;
} }
@ -432,8 +434,8 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
// because we can reuse all of the content from the // because we can reuse all of the content from the
// previous buffer. // previous buffer.
#ifdef DEBUG #ifdef DEBUG
int currTileX = floor_div(x - newBufferOrigin.x, GetScaledTileLength()); int currTileX = floor_div(x - newBufferOrigin.x, scaledTileSize.width);
int currTileY = floor_div(y - newBufferOrigin.y, GetScaledTileLength()); int currTileY = floor_div(y - newBufferOrigin.y, scaledTileSize.height);
int index = currTileX * mRetainedHeight + currTileY; int index = currTileX * mRetainedHeight + currTileY;
NS_ABORT_IF_FALSE(!newValidRegion.Intersects(tileRect) || NS_ABORT_IF_FALSE(!newValidRegion.Intersects(tileRect) ||
!IsPlaceholder(newRetainedTiles. !IsPlaceholder(newRetainedTiles.
@ -444,8 +446,8 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
continue; continue;
} }
int tileX = floor_div(x - newBufferOrigin.x, GetScaledTileLength()); int tileX = floor_div(x - newBufferOrigin.x, scaledTileSize.width);
int tileY = floor_div(y - newBufferOrigin.y, GetScaledTileLength()); int tileY = floor_div(y - newBufferOrigin.y, scaledTileSize.height);
int index = tileX * mRetainedHeight + tileY; int index = tileX * mRetainedHeight + tileY;
NS_ABORT_IF_FALSE(index >= 0 && NS_ABORT_IF_FALSE(index >= 0 &&
static_cast<unsigned>(index) < newRetainedTiles.Length(), static_cast<unsigned>(index) < newRetainedTiles.Length(),

View File

@ -7,6 +7,7 @@
#include "CompositorChild.h" // for CompositorChild #include "CompositorChild.h" // for CompositorChild
#include "GeckoProfiler.h" // for PROFILER_LABEL #include "GeckoProfiler.h" // for PROFILER_LABEL
#include "gfxASurface.h" // for gfxASurface, etc #include "gfxASurface.h" // for gfxASurface, etc
#include "gfxPrefs.h" // for gfxPrefs::LayersTileWidth/Height
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Hal.h" #include "mozilla/Hal.h"
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation #include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
@ -456,8 +457,8 @@ ClientLayerManager::GetTexturePool(SurfaceFormat aFormat)
} }
mTexturePools.AppendElement( mTexturePools.AppendElement(
new TextureClientPool(aFormat, IntSize(TILEDLAYERBUFFER_TILE_SIZE, new TextureClientPool(aFormat, IntSize(gfxPrefs::LayersTileWidth(),
TILEDLAYERBUFFER_TILE_SIZE), gfxPrefs::LayersTileHeight()),
mForwarder)); mForwarder));
return mTexturePools.LastElement(); return mTexturePools.LastElement();
@ -470,8 +471,8 @@ ClientLayerManager::GetSimpleTileTexturePool(SurfaceFormat aFormat)
mSimpleTilePools.EnsureLengthAtLeast(index+1); mSimpleTilePools.EnsureLengthAtLeast(index+1);
if (mSimpleTilePools[index].get() == nullptr) { if (mSimpleTilePools[index].get() == nullptr) {
mSimpleTilePools[index] = new SimpleTextureClientPool(aFormat, IntSize(TILEDLAYERBUFFER_TILE_SIZE, mSimpleTilePools[index] = new SimpleTextureClientPool(aFormat, IntSize(gfxPrefs::LayersTileWidth(),
TILEDLAYERBUFFER_TILE_SIZE), gfxPrefs::LayersTileHeight()),
mForwarder); mForwarder);
} }

View File

@ -14,6 +14,7 @@
#include "CompositorChild.h" // for CompositorChild #include "CompositorChild.h" // for CompositorChild
#include "gfxContext.h" // for gfxContext, etc #include "gfxContext.h" // for gfxContext, etc
#include "gfxPlatform.h" // for gfxPlatform #include "gfxPlatform.h" // for gfxPlatform
#include "gfxPrefs.h" // for gfxPrefs::LayersTileWidth/Height
#include "gfxRect.h" // for gfxRect #include "gfxRect.h" // for gfxRect
#include "mozilla/Attributes.h" // for MOZ_THIS_IN_INITIALIZER_LIST #include "mozilla/Attributes.h" // for MOZ_THIS_IN_INITIALIZER_LIST
#include "mozilla/MathAlgorithms.h" // for Abs #include "mozilla/MathAlgorithms.h" // for Abs
@ -74,7 +75,7 @@ SimpleTiledLayerBuffer::ValidateTile(SimpleTiledLayerTile aTile,
const nsIntRegion& aDirtyRegion) const nsIntRegion& aDirtyRegion)
{ {
PROFILER_LABEL("SimpleTiledLayerBuffer", "ValidateTile"); PROFILER_LABEL("SimpleTiledLayerBuffer", "ValidateTile");
static gfx::IntSize kTileSize(TILEDLAYERBUFFER_TILE_SIZE, TILEDLAYERBUFFER_TILE_SIZE); static gfx::IntSize kTileSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight());
gfx::SurfaceFormat tileFormat = gfxPlatform::GetPlatform()->Optimal2DFormatForContent(GetContentType()); gfx::SurfaceFormat tileFormat = gfxPlatform::GetPlatform()->Optimal2DFormatForContent(GetContentType());
@ -129,7 +130,7 @@ SimpleTiledLayerBuffer::ValidateTile(SimpleTiledLayerTile aTile,
tileFormat); tileFormat);
if (fullPaint) { if (fullPaint) {
drawBounds = nsIntRect(aTileOrigin.x, aTileOrigin.y, GetScaledTileLength(), GetScaledTileLength()); drawBounds = nsIntRect(aTileOrigin.x, aTileOrigin.y, GetScaledTileSize().width, GetScaledTileSize().height);
drawRegion = nsIntRegion(drawBounds); drawRegion = nsIntRegion(drawBounds);
} else { } else {
drawBounds = aDirtyRegion.GetBounds(); drawBounds = aDirtyRegion.GetBounds();
@ -149,7 +150,7 @@ SimpleTiledLayerBuffer::ValidateTile(SimpleTiledLayerTile aTile,
drawTarget = textureClient->AsTextureClientDrawTarget()->GetAsDrawTarget(); drawTarget = textureClient->AsTextureClientDrawTarget()->GetAsDrawTarget();
fullPaint = true; fullPaint = true;
drawBounds = nsIntRect(aTileOrigin.x, aTileOrigin.y, GetScaledTileLength(), GetScaledTileLength()); drawBounds = nsIntRect(aTileOrigin.x, aTileOrigin.y, GetScaledTileSize().width, GetScaledTileSize().height);
drawRegion = nsIntRegion(drawBounds); drawRegion = nsIntRegion(drawBounds);
if (GetContentType() == gfxContentType::COLOR_ALPHA) if (GetContentType() == gfxContentType::COLOR_ALPHA)

View File

@ -29,7 +29,7 @@
// This is the minimum area that we deem reasonable to copy from the front buffer to the // This is the minimum area that we deem reasonable to copy from the front buffer to the
// back buffer on tile updates. If the valid region is smaller than this, we just // back buffer on tile updates. If the valid region is smaller than this, we just
// redraw it and save on the copy (and requisite surface-locking involved). // redraw it and save on the copy (and requisite surface-locking involved).
#define MINIMUM_TILE_COPY_AREA ((TILEDLAYERBUFFER_TILE_SIZE * TILEDLAYERBUFFER_TILE_SIZE)/16) #define MINIMUM_TILE_COPY_AREA (1.f/16.f)
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
#include "cairo.h" #include "cairo.h"
@ -423,7 +423,8 @@ TileClient::ValidateBackBufferFromFront(const nsIntRegion& aDirtyRegion,
bool aCanRerasterizeValidRegion) bool aCanRerasterizeValidRegion)
{ {
if (mBackBuffer && mFrontBuffer) { if (mBackBuffer && mFrontBuffer) {
const nsIntRect tileRect = nsIntRect(0, 0, TILEDLAYERBUFFER_TILE_SIZE, TILEDLAYERBUFFER_TILE_SIZE); gfx::IntSize tileSize = mFrontBuffer->GetSize();
const nsIntRect tileRect = nsIntRect(0, 0, tileSize.width, tileSize.height);
if (aDirtyRegion.Contains(tileRect)) { if (aDirtyRegion.Contains(tileRect)) {
// The dirty region means that we no longer need the front buffer, so // The dirty region means that we no longer need the front buffer, so
@ -437,7 +438,7 @@ TileClient::ValidateBackBufferFromFront(const nsIntRegion& aDirtyRegion,
if (regionToCopy.IsEmpty() || if (regionToCopy.IsEmpty() ||
(aCanRerasterizeValidRegion && (aCanRerasterizeValidRegion &&
regionToCopy.Area() < MINIMUM_TILE_COPY_AREA)) { regionToCopy.Area() < tileSize.width * tileSize.height * MINIMUM_TILE_COPY_AREA)) {
// Just redraw it all. // Just redraw it all.
return; return;
} }
@ -526,7 +527,7 @@ TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion, TextureClientPool *aP
MOZ_ASSERT(mBackLock->IsValid()); MOZ_ASSERT(mBackLock->IsValid());
*aCreatedTextureClient = true; *aCreatedTextureClient = true;
mInvalidBack = nsIntRect(0, 0, TILEDLAYERBUFFER_TILE_SIZE, TILEDLAYERBUFFER_TILE_SIZE); mInvalidBack = nsIntRect(0, 0, mBackBuffer->GetSize().width, mBackBuffer->GetSize().height);
} }
ValidateBackBufferFromFront(aDirtyRegion, aCanRerasterizeValidRegion); ValidateBackBufferFromFront(aDirtyRegion, aCanRerasterizeValidRegion);
@ -782,13 +783,13 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
} }
// The new buffer is now validated, remove the dirty region from it. // The new buffer is now validated, remove the dirty region from it.
aTile.mInvalidBack.Sub(nsIntRect(0, 0, TILEDLAYERBUFFER_TILE_SIZE, TILEDLAYERBUFFER_TILE_SIZE), aTile.mInvalidBack.Sub(nsIntRect(0, 0, GetTileSize().width, GetTileSize().height),
offsetScaledDirtyRegion); offsetScaledDirtyRegion);
} else { } else {
// Area of the full tile... // Area of the full tile...
nsIntRegion tileRegion = nsIntRegion tileRegion =
nsIntRect(aTileOrigin.x, aTileOrigin.y, nsIntRect(aTileOrigin.x, aTileOrigin.y,
GetScaledTileLength(), GetScaledTileLength()); GetScaledTileSize().width, GetScaledTileSize().height);
// Intersect this area with the portion that's dirty. // Intersect this area with the portion that's dirty.
tileRegion = tileRegion.Intersect(aDirtyRegion); tileRegion = tileRegion.Intersect(aDirtyRegion);
@ -997,25 +998,25 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval
nsIntRect paintBounds = aRegionToPaint.GetBounds(); nsIntRect paintBounds = aRegionToPaint.GetBounds();
int startX, incX, startY, incY; int startX, incX, startY, incY;
int tileLength = GetScaledTileLength(); gfx::IntSize scaledTileSize = GetScaledTileSize();
if (aPaintData->mScrollOffset.x >= aPaintData->mLastScrollOffset.x) { if (aPaintData->mScrollOffset.x >= aPaintData->mLastScrollOffset.x) {
startX = RoundDownToTileEdge(paintBounds.x); startX = RoundDownToTileEdge(paintBounds.x, scaledTileSize.width);
incX = tileLength; incX = scaledTileSize.width;
} else { } else {
startX = RoundDownToTileEdge(paintBounds.XMost() - 1); startX = RoundDownToTileEdge(paintBounds.XMost() - 1, scaledTileSize.width);
incX = -tileLength; incX = -scaledTileSize.width;
} }
if (aPaintData->mScrollOffset.y >= aPaintData->mLastScrollOffset.y) { if (aPaintData->mScrollOffset.y >= aPaintData->mLastScrollOffset.y) {
startY = RoundDownToTileEdge(paintBounds.y); startY = RoundDownToTileEdge(paintBounds.y, scaledTileSize.height);
incY = tileLength; incY = scaledTileSize.height;
} else { } else {
startY = RoundDownToTileEdge(paintBounds.YMost() - 1); startY = RoundDownToTileEdge(paintBounds.YMost() - 1, scaledTileSize.height);
incY = -tileLength; incY = -scaledTileSize.height;
} }
// Find a tile to draw. // Find a tile to draw.
nsIntRect tileBounds(startX, startY, tileLength, tileLength); nsIntRect tileBounds(startX, startY, scaledTileSize.width, scaledTileSize.height);
int32_t scrollDiffX = aPaintData->mScrollOffset.x - aPaintData->mLastScrollOffset.x; int32_t scrollDiffX = aPaintData->mScrollOffset.x - aPaintData->mLastScrollOffset.x;
int32_t scrollDiffY = aPaintData->mScrollOffset.y - aPaintData->mLastScrollOffset.y; int32_t scrollDiffY = aPaintData->mScrollOffset.y - aPaintData->mLastScrollOffset.y;
// This loop will always terminate, as there is at least one tile area // This loop will always terminate, as there is at least one tile area

View File

@ -429,24 +429,25 @@ TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
uint32_t rowCount = 0; uint32_t rowCount = 0;
uint32_t tileX = 0; uint32_t tileX = 0;
nsIntRect visibleRect = aVisibleRegion.GetBounds(); nsIntRect visibleRect = aVisibleRegion.GetBounds();
gfx::IntSize scaledTileSize = aLayerBuffer.GetScaledTileSize();
for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) {
rowCount++; rowCount++;
int32_t tileStartX = aLayerBuffer.GetTileStart(x); int32_t tileStartX = aLayerBuffer.GetTileStart(x, scaledTileSize.width);
int32_t w = aLayerBuffer.GetScaledTileLength() - tileStartX; int32_t w = scaledTileSize.width - tileStartX;
if (x + w > visibleRect.x + visibleRect.width) { if (x + w > visibleRect.x + visibleRect.width) {
w = visibleRect.x + visibleRect.width - x; w = visibleRect.x + visibleRect.width - x;
} }
int tileY = 0; int tileY = 0;
for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) {
int32_t tileStartY = aLayerBuffer.GetTileStart(y); int32_t tileStartY = aLayerBuffer.GetTileStart(y, scaledTileSize.height);
int32_t h = aLayerBuffer.GetScaledTileLength() - tileStartY; int32_t h = scaledTileSize.height - tileStartY;
if (y + h > visibleRect.y + visibleRect.height) { if (y + h > visibleRect.y + visibleRect.height) {
h = visibleRect.y + visibleRect.height - y; h = visibleRect.y + visibleRect.height - y;
} }
TileHost tileTexture = aLayerBuffer. TileHost tileTexture = aLayerBuffer.
GetTile(nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x), GetTile(nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width),
aLayerBuffer.RoundDownToTileEdge(y))); aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height)));
if (tileTexture != aLayerBuffer.GetPlaceholderTile()) { if (tileTexture != aLayerBuffer.GetPlaceholderTile()) {
nsIntRegion tileDrawRegion; nsIntRegion tileDrawRegion;
tileDrawRegion.And(nsIntRect(x, y, w, h), aLayerBuffer.GetValidRegion()); tileDrawRegion.And(nsIntRect(x, y, w, h), aLayerBuffer.GetValidRegion());
@ -457,9 +458,9 @@ TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
tileDrawRegion.ScaleRoundOut(resolution, resolution); tileDrawRegion.ScaleRoundOut(resolution, resolution);
nsIntPoint tileOffset((x - tileStartX) * resolution, nsIntPoint tileOffset((x - tileStartX) * resolution,
(y - tileStartY) * resolution); (y - tileStartY) * resolution);
uint32_t tileSize = aLayerBuffer.GetTileLength(); gfx::IntSize tileSize = aLayerBuffer.GetTileSize();
RenderTile(tileTexture, aEffectChain, aOpacity, aTransform, aFilter, aClipRect, tileDrawRegion, RenderTile(tileTexture, aEffectChain, aOpacity, aTransform, aFilter, aClipRect, tileDrawRegion,
tileOffset, nsIntSize(tileSize, tileSize)); tileOffset, nsIntSize(tileSize.width, tileSize.height));
} }
} }
tileY++; tileY++;

View File

@ -13,7 +13,6 @@
#include "SharedSurfaceGL.h" // for SharedSurface_GLTexture, etc #include "SharedSurfaceGL.h" // for SharedSurface_GLTexture, etc
#include "SurfaceStream.h" // for SurfaceStream #include "SurfaceStream.h" // for SurfaceStream
#include "SurfaceTypes.h" // for SharedSurfaceType, etc #include "SurfaceTypes.h" // for SharedSurfaceType, etc
#include "TiledLayerBuffer.h" // for TILEDLAYERBUFFER_TILE_SIZE
#include "gfx2DGlue.h" // for ContentForFormat, etc #include "gfx2DGlue.h" // for ContentForFormat, etc
#include "gfxImageSurface.h" // for gfxImageSurface #include "gfxImageSurface.h" // for gfxImageSurface
#include "gfxReusableSurfaceWrapper.h" // for gfxReusableSurfaceWrapper #include "gfxReusableSurfaceWrapper.h" // for gfxReusableSurfaceWrapper

View File

@ -61,8 +61,8 @@ TEST(TiledLayerBuffer, TileConstructor) {
TEST(TiledLayerBuffer, TileStart) { TEST(TiledLayerBuffer, TileStart) {
TestTiledLayerBuffer buffer; TestTiledLayerBuffer buffer;
ASSERT_EQ(buffer.RoundDownToTileEdge(10), 0); ASSERT_EQ(buffer.RoundDownToTileEdge(10, 256), 0);
ASSERT_EQ(buffer.RoundDownToTileEdge(-10), -256); ASSERT_EQ(buffer.RoundDownToTileEdge(-10, 256), -256);
} }
TEST(TiledLayerBuffer, EmptyUpdate) { TEST(TiledLayerBuffer, EmptyUpdate) {

View File

@ -179,6 +179,11 @@ private:
DECL_GFX_PREF(Once, "layers.enable-tiles", LayersTilesEnabled, bool, false); DECL_GFX_PREF(Once, "layers.enable-tiles", LayersTilesEnabled, bool, false);
DECL_GFX_PREF(Once, "layers.simple-tiles", LayersUseSimpleTiles, bool, false); DECL_GFX_PREF(Once, "layers.simple-tiles", LayersUseSimpleTiles, bool, false);
DECL_GFX_PREF(Once, "layers.force-per-tile-drawing", PerTileDrawing, bool, false); DECL_GFX_PREF(Once, "layers.force-per-tile-drawing", PerTileDrawing, bool, false);
// We allow for configurable and rectangular tile size to avoid wasting memory on devices whose
// screen size does not align nicely to the default tile size. Although layers can be any size,
// they are often the same size as the screen, especially for width.
DECL_GFX_PREF(Once, "layers.tile-width", LayersTileWidth, int32_t, 256);
DECL_GFX_PREF(Once, "layers.tile-height", LayersTileHeight, int32_t, 256);
DECL_GFX_PREF(Once, "layers.overzealous-gralloc-unlocking", OverzealousGrallocUnlocking, bool, false); DECL_GFX_PREF(Once, "layers.overzealous-gralloc-unlocking", OverzealousGrallocUnlocking, bool, false);
DECL_GFX_PREF(Once, "layers.force-shmem-tiles", ForceShmemTiles, bool, false); DECL_GFX_PREF(Once, "layers.force-shmem-tiles", ForceShmemTiles, bool, false);
DECL_GFX_PREF(Live, "layers.frame-counter", DrawFrameCounter, bool, false); DECL_GFX_PREF(Live, "layers.frame-counter", DrawFrameCounter, bool, false);

View File

@ -725,7 +725,7 @@ nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
nsIScrollableFrame* scrollableFrame = frame->GetScrollTargetFrame(); nsIScrollableFrame* scrollableFrame = frame->GetScrollTargetFrame();
nsPoint scrollPos( nsPoint scrollPos(
scrollableFrame ? scrollableFrame->GetScrollPosition() : nsPoint(0,0)); scrollableFrame ? scrollableFrame->GetScrollPosition() : nsPoint(0,0));
if (marginsData->mAlignment > 0) { if (marginsData->mAlignmentX > 0 || marginsData->mAlignmentY > 0) {
LayerPoint scrollPosLayer( LayerPoint scrollPosLayer(
res.width * NSAppUnitsToFloatPixels(scrollPos.x, auPerDevPixel), res.width * NSAppUnitsToFloatPixels(scrollPos.x, auPerDevPixel),
res.height * NSAppUnitsToFloatPixels(scrollPos.y, auPerDevPixel)); res.height * NSAppUnitsToFloatPixels(scrollPos.y, auPerDevPixel));
@ -738,13 +738,13 @@ nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
rect.Inflate(1); rect.Inflate(1);
float left = float left =
marginsData->mAlignment * floor(rect.x / marginsData->mAlignment); marginsData->mAlignmentX * floor(rect.x / marginsData->mAlignmentX);
float top = float top =
marginsData->mAlignment * floor(rect.y / marginsData->mAlignment); marginsData->mAlignmentY * floor(rect.y / marginsData->mAlignmentY);
float right = float right =
marginsData->mAlignment * ceil(rect.XMost() / marginsData->mAlignment); marginsData->mAlignmentX * ceil(rect.XMost() / marginsData->mAlignmentX);
float bottom = float bottom =
marginsData->mAlignment * ceil(rect.YMost() / marginsData->mAlignment); marginsData->mAlignmentY * ceil(rect.YMost() / marginsData->mAlignmentY);
rect = LayerRect(left, top, right - left, bottom - top); rect = LayerRect(left, top, right - left, bottom - top);
rect -= scrollPosLayer; rect -= scrollPosLayer;
} }

View File

@ -87,13 +87,16 @@ struct DisplayPortPropertyData {
struct DisplayPortMarginsPropertyData { struct DisplayPortMarginsPropertyData {
DisplayPortMarginsPropertyData(const LayerMargin& aMargins, DisplayPortMarginsPropertyData(const LayerMargin& aMargins,
uint32_t aAlignment, uint32_t aPriority) uint32_t aAlignmentX, uint32_t aAlignmentY,
uint32_t aPriority)
: mMargins(aMargins) : mMargins(aMargins)
, mAlignment(aAlignment) , mAlignmentX(aAlignmentX)
, mAlignmentY(aAlignmentY)
, mPriority(aPriority) , mPriority(aPriority)
{} {}
LayerMargin mMargins; LayerMargin mMargins;
uint32_t mAlignment; uint32_t mAlignmentX;
uint32_t mAlignmentY;
uint32_t mPriority; uint32_t mPriority;
}; };

View File

@ -4,13 +4,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "APZCCallbackHelper.h" #include "APZCCallbackHelper.h"
#include "gfxPrefs.h" // For gfxPrefs::LayersTilesEnabled #include "gfxPrefs.h" // For gfxPrefs::LayersTilesEnabled, LayersTileWidth/Height
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "nsIScrollableFrame.h" #include "nsIScrollableFrame.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "TiledLayerBuffer.h" // For TILEDLAYERBUFFER_TILE_SIZE
namespace mozilla { namespace mozilla {
namespace widget { namespace widget {
@ -46,14 +45,12 @@ static CSSRect ExpandDisplayPortToTileBoundaries(
displayPortInLayerSpace.Inflate(1); displayPortInLayerSpace.Inflate(1);
// Now nudge the rectangle to the nearest equal or larger tile boundary. // Now nudge the rectangle to the nearest equal or larger tile boundary.
gfxFloat left = TILEDLAYERBUFFER_TILE_SIZE int32_t tileWidth = gfxPrefs::LayersTileWidth();
* floor(displayPortInLayerSpace.x / TILEDLAYERBUFFER_TILE_SIZE); int32_t tileHeight = gfxPrefs::LayersTileHeight();
gfxFloat top = TILEDLAYERBUFFER_TILE_SIZE gfxFloat left = tileWidth * floor(displayPortInLayerSpace.x / tileWidth);
* floor(displayPortInLayerSpace.y / TILEDLAYERBUFFER_TILE_SIZE); gfxFloat right = tileWidth * ceil(displayPortInLayerSpace.XMost() / tileWidth);
gfxFloat right = TILEDLAYERBUFFER_TILE_SIZE gfxFloat top = tileHeight * floor(displayPortInLayerSpace.y / tileHeight);
* ceil(displayPortInLayerSpace.XMost() / TILEDLAYERBUFFER_TILE_SIZE); gfxFloat bottom = tileHeight * ceil(displayPortInLayerSpace.YMost() / tileHeight);
gfxFloat bottom = TILEDLAYERBUFFER_TILE_SIZE
* ceil(displayPortInLayerSpace.YMost() / TILEDLAYERBUFFER_TILE_SIZE);
displayPortInLayerSpace = LayerRect(left, top, right - left, bottom - top); displayPortInLayerSpace = LayerRect(left, top, right - left, bottom - top);
CSSRect displayPort = displayPortInLayerSpace / aLayerPixelsPerCSSPixel; CSSRect displayPort = displayPortInLayerSpace / aLayerPixelsPerCSSPixel;
@ -231,14 +228,16 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
aMetrics.mDisplayPort.height, aMetrics.mDisplayPort.height,
element, 0); element, 0);
} else { } else {
uint32_t alignment = gfxPrefs::LayersTilesEnabled() gfx::IntSize alignment = gfxPrefs::LayersTilesEnabled()
? TILEDLAYERBUFFER_TILE_SIZE : 1; ? gfx::IntSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight()) :
gfx::IntSize(1, 1);
LayerMargin margins = aMetrics.GetDisplayPortMargins(); LayerMargin margins = aMetrics.GetDisplayPortMargins();
aUtils->SetDisplayPortMarginsForElement(margins.left, aUtils->SetDisplayPortMarginsForElement(margins.left,
margins.top, margins.top,
margins.right, margins.right,
margins.bottom, margins.bottom,
alignment, alignment.width,
alignment.height,
element, 0); element, 0);
CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent(); CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent();
nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(), nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(),
@ -284,14 +283,16 @@ APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent,
aMetrics.mDisplayPort.height, aMetrics.mDisplayPort.height,
element, 0); element, 0);
} else { } else {
uint32_t alignment = gfxPrefs::LayersTilesEnabled() gfx::IntSize alignment = gfxPrefs::LayersTilesEnabled()
? TILEDLAYERBUFFER_TILE_SIZE : 1; ? gfx::IntSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight()) :
gfx::IntSize(1, 1);
LayerMargin margins = aMetrics.GetDisplayPortMargins(); LayerMargin margins = aMetrics.GetDisplayPortMargins();
utils->SetDisplayPortMarginsForElement(margins.left, utils->SetDisplayPortMarginsForElement(margins.left,
margins.top, margins.top,
margins.right, margins.right,
margins.bottom, margins.bottom,
alignment, alignment.width,
alignment.height,
element, 0); element, 0);
CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent(); CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent();
nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(), nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(),