Bug 1258481 - Add a RegionBuilder for accumulating rects. r=jrmuizel

MozReview-Commit-ID: 6AO9q6Ru833

--HG--
extra : rebase_source : 64da769ea9d1f61a5ff191e39c3a8638ffc8cfe0
This commit is contained in:
Benoit Girard 2016-03-21 16:22:37 -04:00
parent be0fcafff8
commit 5ff652a2ac
4 changed files with 69 additions and 0 deletions

32
gfx/src/RegionBuilder.h Normal file
View File

@ -0,0 +1,32 @@
/* 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 RegionBuilder_h__
#define RegionBuilder_h__
#include <nsTArray.h>
template <typename RegionType>
class RegionBuilder
{
public:
typedef typename RegionType::RectType RectType;
RegionBuilder()
{}
void Or(const RectType& aRect) {
pixman_box32_t box = { aRect.x, aRect.y, aRect.XMost(), aRect.YMost() };
mRects.AppendElement(box);
}
RegionType ToRegion() const {
return RegionType(mRects);
}
private:
nsTArray<pixman_box32_t> mRects;
};
#endif // RegionBuilder_h__

View File

@ -37,6 +37,7 @@ EXPORTS += [
'nsSize.h',
'nsThemeConstants.h',
'nsTransform2D.h',
'RegionBuilder.h',
]
EXPORTS.mozilla += [

View File

@ -19,6 +19,7 @@
#include "nsMargin.h" // for nsIntMargin
#include "nsRegionFwd.h" // for nsIntRegion
#include "nsStringGlue.h" // for nsCString
#include "nsTArray.h" // for nsTArray, nsTArray_Impl
#include "xpcom-config.h" // for CPP_THROW_NEW
#include "mozilla/Move.h" // for mozilla::Move
#include "mozilla/gfx/MatrixFwd.h" // for mozilla::gfx::Matrix4x4
@ -49,12 +50,20 @@ enum class VisitSide {
class nsRegion
{
public:
typedef nsRect RectType;
typedef nsPoint PointType;
typedef nsMargin MarginType;
nsRegion () { pixman_region32_init(&mImpl); }
MOZ_IMPLICIT nsRegion (const nsRect& aRect) { pixman_region32_init_rect(&mImpl,
aRect.x,
aRect.y,
aRect.width,
aRect.height); }
explicit nsRegion (const nsTArray<pixman_box32_t>& aRects)
{
pixman_region32_init_rects(&mImpl, aRects.Elements(), aRects.Length());
}
nsRegion (const nsRegion& aRegion) { pixman_region32_init(&mImpl); pixman_region32_copy(&mImpl,aRegion.Impl()); }
nsRegion (nsRegion&& aRegion) { mImpl = aRegion.mImpl; pixman_region32_init(&aRegion.mImpl); }
nsRegion& operator = (nsRegion&& aRegion) {
@ -471,6 +480,7 @@ public:
BaseIntRegion () {}
MOZ_IMPLICIT BaseIntRegion (const Rect& aRect) : mImpl (ToRect(aRect)) {}
explicit BaseIntRegion (const nsTArray<pixman_box32_t>& aRects) : mImpl (aRects) {}
BaseIntRegion (const BaseIntRegion& aRegion) : mImpl (aRegion.mImpl) {}
BaseIntRegion (BaseIntRegion&& aRegion) : mImpl (mozilla::Move(aRegion.mImpl)) {}
Derived& operator = (const Rect& aRect) { mImpl = ToRect (aRect); return This(); }
@ -814,10 +824,15 @@ class IntRegionTyped :
static_assert(IsPixel<units>::value, "'units' must be a coordinate system tag");
public:
typedef IntRectTyped<units> RectType;
typedef IntPointTyped<units> PointType;
typedef IntMarginTyped<units> MarginType;
// Forward constructors.
IntRegionTyped() {}
MOZ_IMPLICIT IntRegionTyped(const IntRectTyped<units>& aRect) : Super(aRect) {}
IntRegionTyped(const IntRegionTyped& aRegion) : Super(aRegion) {}
IntRegionTyped(const nsTArray<pixman_box32_t>& aRects) : Super(aRects) {}
IntRegionTyped(IntRegionTyped&& aRegion) : Super(mozilla::Move(aRegion)) {}
// Assignment operators need to be forwarded as well, otherwise the compiler

View File

@ -9,6 +9,7 @@
#include "gtest/MozGTestBench.h"
#include "nsRect.h"
#include "nsRegion.h"
#include "RegionBuilder.h"
using namespace std;
@ -583,3 +584,23 @@ MOZ_GTEST_BENCH(GfxBench, RegionAnd, []{
}
});
void TestExec() {
const int size = 5000;
RegionBuilder<nsRegion> r;
for (int i = 0; i < size; i++) {
r.Or(nsRect(i, i, i + 10, i + 10));
}
r.ToRegion();
RegionBuilder<nsIntRegion> rInt;
for (int i = 0; i < size; i++) {
rInt.Or(nsIntRect(i, i, i + 10, i + 10));
}
rInt.ToRegion();
}
MOZ_GTEST_BENCH(GfxBench, RegionBuilderOr, []{
TestExec();
});