Bug 1059033 - Part 3: Avoid save/restoring for tiles that are entirely clipped out. r=Bas

This commit is contained in:
Matt Woodrow 2014-09-01 15:22:49 +12:00
parent 0d56aae4ca
commit d5c33cbff9
2 changed files with 99 additions and 24 deletions

View File

@ -48,7 +48,7 @@ DrawTargetTiled::Init(const TileSet& aTiles)
class SnapshotTiled : public SourceSurface class SnapshotTiled : public SourceSurface
{ {
public: public:
SnapshotTiled(const vector<Tile>& aTiles, const IntRect& aRect) SnapshotTiled(const vector<TileInternal>& aTiles, const IntRect& aRect)
: mRect(aRect) : mRect(aRect)
{ {
for (size_t i = 0; i < aTiles.size(); i++) { for (size_t i = 0; i < aTiles.size(); i++) {
@ -97,14 +97,14 @@ DrawTargetTiled::Snapshot()
return new SnapshotTiled(mTiles, mRect); return new SnapshotTiled(mTiles, mRect);
} }
// Skip the mClippedOut check since this is only used for Flush() which
// should happen even if we're clipped.
#define TILED_COMMAND(command) \ #define TILED_COMMAND(command) \
void \ void \
DrawTargetTiled::command() \ DrawTargetTiled::command() \
{ \ { \
for (size_t i = 0; i < mTiles.size(); i++) { \ for (size_t i = 0; i < mTiles.size(); i++) { \
\ mTiles[i].mDrawTarget->command(); \
\
mTiles[i].mDrawTarget->command(); \
} \ } \
} }
#define TILED_COMMAND1(command, type1) \ #define TILED_COMMAND1(command, type1) \
@ -112,9 +112,8 @@ DrawTargetTiled::Snapshot()
DrawTargetTiled::command(type1 arg1) \ DrawTargetTiled::command(type1 arg1) \
{ \ { \
for (size_t i = 0; i < mTiles.size(); i++) { \ for (size_t i = 0; i < mTiles.size(); i++) { \
\ if (!mTiles[i].mClippedOut) \
\ mTiles[i].mDrawTarget->command(arg1); \
mTiles[i].mDrawTarget->command(arg1); \
} \ } \
} }
#define TILED_COMMAND3(command, type1, type2, type3) \ #define TILED_COMMAND3(command, type1, type2, type3) \
@ -122,9 +121,8 @@ DrawTargetTiled::Snapshot()
DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3) \ DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3) \
{ \ { \
for (size_t i = 0; i < mTiles.size(); i++) { \ for (size_t i = 0; i < mTiles.size(); i++) { \
\ if (!mTiles[i].mClippedOut) \
\ mTiles[i].mDrawTarget->command(arg1, arg2, arg3); \
mTiles[i].mDrawTarget->command(arg1, arg2, arg3); \
} \ } \
} }
#define TILED_COMMAND4(command, type1, type2, type3, type4) \ #define TILED_COMMAND4(command, type1, type2, type3, type4) \
@ -132,9 +130,8 @@ DrawTargetTiled::Snapshot()
DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
{ \ { \
for (size_t i = 0; i < mTiles.size(); i++) { \ for (size_t i = 0; i < mTiles.size(); i++) { \
\ if (!mTiles[i].mClippedOut) \
\ mTiles[i].mDrawTarget->command(arg1, arg2, arg3, arg4); \
mTiles[i].mDrawTarget->command(arg1, arg2, arg3, arg4); \
} \ } \
} }
#define TILED_COMMAND5(command, type1, type2, type3, type4, type5) \ #define TILED_COMMAND5(command, type1, type2, type3, type4, type5) \
@ -142,9 +139,8 @@ DrawTargetTiled::Snapshot()
DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
{ \ { \
for (size_t i = 0; i < mTiles.size(); i++) { \ for (size_t i = 0; i < mTiles.size(); i++) { \
\ if (!mTiles[i].mClippedOut) \
\ mTiles[i].mDrawTarget->command(arg1, arg2, arg3, arg4, arg5); \
mTiles[i].mDrawTarget->command(arg1, arg2, arg3, arg4, arg5); \
} \ } \
} }
@ -156,9 +152,69 @@ TILED_COMMAND4(StrokeRect, const Rect&, const Pattern&, const StrokeOptions&, co
TILED_COMMAND5(StrokeLine, const Point&, const Point&, const Pattern&, const StrokeOptions&, const DrawOptions&) TILED_COMMAND5(StrokeLine, const Point&, const Point&, const Pattern&, const StrokeOptions&, const DrawOptions&)
TILED_COMMAND5(FillGlyphs, ScaledFont*, const GlyphBuffer&, const Pattern&, const DrawOptions&, const GlyphRenderingOptions*) TILED_COMMAND5(FillGlyphs, ScaledFont*, const GlyphBuffer&, const Pattern&, const DrawOptions&, const GlyphRenderingOptions*)
TILED_COMMAND3(Mask, const Pattern&, const Pattern&, const DrawOptions&) TILED_COMMAND3(Mask, const Pattern&, const Pattern&, const DrawOptions&)
TILED_COMMAND1(PushClip, const Path*)
TILED_COMMAND1(PushClipRect, const Rect&) void
TILED_COMMAND(PopClip) DrawTargetTiled::PushClip(const Path* aPath)
{
mClippedOutTilesStack.push_back(std::vector<uint32_t>());
std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
Rect deviceRect = aPath->GetBounds(mTransform);
for (size_t i = 0; i < mTiles.size(); i++) {
if (!mTiles[i].mClippedOut) {
if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
mTiles[i].mTileOrigin.y,
mTiles[i].mDrawTarget->GetSize().width,
mTiles[i].mDrawTarget->GetSize().height))) {
mTiles[i].mDrawTarget->PushClip(aPath);
} else {
mTiles[i].mClippedOut = true;
clippedTiles.push_back(i);
}
}
}
}
void
DrawTargetTiled::PushClipRect(const Rect& aRect)
{
mClippedOutTilesStack.push_back(std::vector<uint32_t>());
std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
Rect deviceRect = mTransform.TransformBounds(aRect);
for (size_t i = 0; i < mTiles.size(); i++) {
if (!mTiles[i].mClippedOut) {
if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
mTiles[i].mTileOrigin.y,
mTiles[i].mDrawTarget->GetSize().width,
mTiles[i].mDrawTarget->GetSize().height))) {
mTiles[i].mDrawTarget->PushClipRect(aRect);
} else {
mTiles[i].mClippedOut = true;
clippedTiles.push_back(i);
}
}
}
}
void
DrawTargetTiled::PopClip()
{
for (size_t i = 0; i < mTiles.size(); i++) {
if (!mTiles[i].mClippedOut) {
mTiles[i].mDrawTarget->PopClip();
}
}
std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
for (size_t i = 0; i < clippedTiles.size(); i++) {
mTiles[clippedTiles[i]].mClippedOut = false;
}
mClippedOutTilesStack.pop_back();
}
void void
DrawTargetTiled::CopySurface(SourceSurface *aSurface, DrawTargetTiled::CopySurface(SourceSurface *aSurface,
@ -197,7 +253,8 @@ DrawTargetTiled::DrawSurface(SourceSurface* aSurface, const Rect& aDest, const R
{ {
Rect deviceRect = mTransform.TransformBounds(aDest); Rect deviceRect = mTransform.TransformBounds(aDest);
for (size_t i = 0; i < mTiles.size(); i++) { for (size_t i = 0; i < mTiles.size(); i++) {
if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x, if (!mTiles[i].mClippedOut &&
deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
mTiles[i].mTileOrigin.y, mTiles[i].mTileOrigin.y,
mTiles[i].mDrawTarget->GetSize().width, mTiles[i].mDrawTarget->GetSize().width,
mTiles[i].mDrawTarget->GetSize().height))) { mTiles[i].mDrawTarget->GetSize().height))) {
@ -211,7 +268,8 @@ DrawTargetTiled::FillRect(const Rect& aRect, const Pattern& aPattern, const Draw
{ {
Rect deviceRect = mTransform.TransformBounds(aRect); Rect deviceRect = mTransform.TransformBounds(aRect);
for (size_t i = 0; i < mTiles.size(); i++) { for (size_t i = 0; i < mTiles.size(); i++) {
if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x, if (!mTiles[i].mClippedOut &&
deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
mTiles[i].mTileOrigin.y, mTiles[i].mTileOrigin.y,
mTiles[i].mDrawTarget->GetSize().width, mTiles[i].mDrawTarget->GetSize().width,
mTiles[i].mDrawTarget->GetSize().height))) { mTiles[i].mDrawTarget->GetSize().height))) {
@ -255,7 +313,8 @@ DrawTargetTiled::Stroke(const Path* aPath, const Pattern& aPattern, const Stroke
aPath->GetBounds(mTransform), aPath->GetBounds(mTransform),
mTransform); mTransform);
for (size_t i = 0; i < mTiles.size(); i++) { for (size_t i = 0; i < mTiles.size(); i++) {
if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x, if (!mTiles[i].mClippedOut &&
deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
mTiles[i].mTileOrigin.y, mTiles[i].mTileOrigin.y,
mTiles[i].mDrawTarget->GetSize().width, mTiles[i].mDrawTarget->GetSize().width,
mTiles[i].mDrawTarget->GetSize().height))) { mTiles[i].mDrawTarget->GetSize().height))) {
@ -269,7 +328,8 @@ DrawTargetTiled::Fill(const Path* aPath, const Pattern& aPattern, const DrawOpti
{ {
Rect deviceRect = aPath->GetBounds(mTransform); Rect deviceRect = aPath->GetBounds(mTransform);
for (size_t i = 0; i < mTiles.size(); i++) { for (size_t i = 0; i < mTiles.size(); i++) {
if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x, if (!mTiles[i].mClippedOut &&
deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
mTiles[i].mTileOrigin.y, mTiles[i].mTileOrigin.y,
mTiles[i].mDrawTarget->GetSize().width, mTiles[i].mDrawTarget->GetSize().width,
mTiles[i].mDrawTarget->GetSize().height))) { mTiles[i].mDrawTarget->GetSize().height))) {

View File

@ -14,6 +14,20 @@
namespace mozilla { namespace mozilla {
namespace gfx { namespace gfx {
struct TileInternal : public Tile {
TileInternal()
: mClippedOut(false)
{}
TileInternal(const Tile& aOther)
: Tile(aOther)
, mClippedOut(false)
{}
bool mClippedOut;
};
class DrawTargetTiled : public DrawTarget class DrawTargetTiled : public DrawTarget
{ {
public: public:
@ -130,7 +144,8 @@ public:
} }
private: private:
std::vector<Tile> mTiles; std::vector<TileInternal> mTiles;
std::vector<std::vector<uint32_t> > mClippedOutTilesStack;
IntRect mRect; IntRect mRect;
}; };