aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkRect.h11
-rw-r--r--src/gpu/GrClipMaskManager.cpp76
-rw-r--r--src/gpu/GrClipMaskManager.h18
-rw-r--r--tests/ClipCacheTest.cpp14
4 files changed, 69 insertions, 50 deletions
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 702627775b..2fa3256e1c 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -144,7 +144,7 @@ struct SK_API SkIRect {
/** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
making the rectangle narrower. If dx is negative, then the sides are moved outwards,
- making the rectangle wider. The same hods true for dy and the top and bottom.
+ making the rectangle wider. The same holds true for dy and the top and bottom.
*/
void inset(int32_t dx, int32_t dy) {
fLeft += dx;
@@ -153,6 +153,13 @@ struct SK_API SkIRect {
fBottom -= dy;
}
+ /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
+ moved outwards, making the rectangle wider. If dx is negative, then the
+ sides are moved inwards, making the rectangle narrower. The same holds
+ true for dy and the top and bottom.
+ */
+ void outset(int32_t dx, int32_t dy) { this->inset(-dx, -dy); }
+
bool quickReject(int l, int t, int r, int b) const {
return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
}
@@ -481,7 +488,7 @@ struct SK_API SkRect {
/** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
moved outwards, making the rectangle wider. If dx is negative, then the
- sides are moved inwards, making the rectangle narrower. The same hods
+ sides are moved inwards, making the rectangle narrower. The same holds
true for dy and the top and bottom.
*/
void outset(SkScalar dx, SkScalar dy) { this->inset(-dx, -dy); }
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 43b27431ba..15aae1e2dc 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -32,7 +32,7 @@ namespace {
// sampler matrix this also alters the vertex layout
void setup_drawstate_aaclip(GrGpu* gpu,
GrTexture* result,
- const GrRect &bound) {
+ const GrIRect &bound) {
GrDrawState* drawState = gpu->drawState();
GrAssert(drawState);
@@ -40,7 +40,7 @@ void setup_drawstate_aaclip(GrGpu* gpu,
GrMatrix mat;
mat.setIDiv(result->width(), result->height());
- mat.preTranslate(-bound.fLeft, -bound.fTop);
+ mat.preTranslate(SkIntToScalar(-bound.fLeft), SkIntToScalar(-bound.fTop));
mat.preConcat(drawState->getViewMatrix());
drawState->sampler(maskStage)->reset(GrSamplerState::kClamp_WrapMode,
@@ -89,7 +89,7 @@ bool GrClipMaskManager::createClipMask(GrGpu* gpu,
// The clip geometry is complex enough that it will be more
// efficient to create it entirely in software
GrTexture* result = NULL;
- GrRect bound;
+ GrIRect bound;
if (this->createSoftwareClipMask(gpu, clipIn, &result, &bound)) {
fClipMaskInAlpha = true;
@@ -108,7 +108,7 @@ bool GrClipMaskManager::createClipMask(GrGpu* gpu,
// render target) we aren't going to use scissoring like the stencil
// path does (see scissorSettings below)
GrTexture* result = NULL;
- GrRect bound;
+ GrIRect bound;
if (this->createAlphaClipMask(gpu, clipIn, &result, &bound)) {
fClipMaskInAlpha = true;
@@ -165,12 +165,25 @@ bool GrClipMaskManager::createClipMask(GrGpu* gpu,
#endif
namespace {
+/**
+ * Does "container" contain "containee"? If either is empty then
+ * no containment is possible.
+ */
+bool contains(const SkRect& container, const SkIRect& containee) {
+ return !containee.isEmpty() && !container.isEmpty() &&
+ container.fLeft <= SkIntToScalar(containee.fLeft) &&
+ container.fTop <= SkIntToScalar(containee.fTop) &&
+ container.fRight >= SkIntToScalar(containee.fRight) &&
+ container.fBottom >= SkIntToScalar(containee.fBottom);
+}
+
+
////////////////////////////////////////////////////////////////////////////////
// determines how many elements at the head of the clip can be skipped and
// whether the initial clear should be to the inside- or outside-the-clip value,
// and what op should be used to draw the first element that isn't skipped.
int process_initial_clip_elements(const GrClip& clip,
- const GrRect& bounds,
+ const GrIRect& bounds,
bool* clearToInside,
SkRegion::Op* startOp) {
@@ -196,7 +209,7 @@ int process_initial_clip_elements(const GrClip& clip,
// if this element contains the entire bounds then we
// can skip it.
if (kRect_ClipType == clip.getElementType(curr)
- && clip.getRect(curr).contains(bounds)) {
+ && contains(clip.getRect(curr), bounds)) {
break;
}
// if everything is initially clearToInside then intersect is
@@ -378,7 +391,7 @@ void clear(GrGpu* gpu,
// get a texture to act as a temporary buffer for AA clip boolean operations
// TODO: given the expense of createTexture we may want to just cache this too
-void GrClipMaskManager::getTemp(const GrRect& bounds,
+void GrClipMaskManager::getTemp(const GrIRect& bounds,
GrAutoScratchTexture* temp) {
if (NULL != temp->texture()) {
// we've already allocated the temp texture
@@ -387,8 +400,8 @@ void GrClipMaskManager::getTemp(const GrRect& bounds,
const GrTextureDesc desc = {
kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit,
- SkScalarCeilToInt(bounds.width()),
- SkScalarCeilToInt(bounds.height()),
+ bounds.width(),
+ bounds.height(),
kAlpha_8_GrPixelConfig,
0 // samples
};
@@ -398,15 +411,15 @@ void GrClipMaskManager::getTemp(const GrRect& bounds,
void GrClipMaskManager::setupCache(const GrClip& clipIn,
- const GrRect& bounds) {
+ const GrIRect& bounds) {
// Since we are setting up the cache we know the last lookup was a miss
// Free up the currently cached mask so it can be reused
fAACache.reset();
const GrTextureDesc desc = {
kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit,
- SkScalarCeilToInt(bounds.width()),
- SkScalarCeilToInt(bounds.height()),
+ bounds.width(),
+ bounds.height(),
kAlpha_8_GrPixelConfig,
0 // samples
};
@@ -422,7 +435,7 @@ void GrClipMaskManager::setupCache(const GrClip& clipIn,
bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
const GrClip& clipIn,
GrTexture** result,
- GrRect *resultBounds) {
+ GrIRect *resultBounds) {
GrDrawState* origDrawState = gpu->drawState();
GrAssert(origDrawState->isClipState());
@@ -449,28 +462,26 @@ bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
bounds = rtRect;
}
- bounds.roundOut();
+ GrIRect intBounds;
+ bounds.roundOut(&intBounds);
// need to outset a pixel since the standard bounding box computation
// path doesn't leave any room for antialiasing (esp. w.r.t. rects)
- bounds.outset(SkIntToScalar(1), SkIntToScalar(1));
+ intBounds.outset(1, 1);
// TODO: make sure we don't outset if bounds are still 0,0 @ min
- GrAssert(SkScalarIsInt(bounds.width()));
- GrAssert(SkScalarIsInt(bounds.height()));
-
if (fAACache.canReuse(clipIn,
- SkScalarCeilToInt(bounds.width()),
- SkScalarCeilToInt(bounds.height()))) {
+ intBounds.width(),
+ intBounds.height())) {
*result = fAACache.getLastMask();
fAACache.getLastBound(resultBounds);
return true;
}
- this->setupCache(clipIn, bounds);
+ this->setupCache(clipIn, intBounds);
- *resultBounds = bounds;
+ *resultBounds = intBounds;
return false;
}
@@ -479,7 +490,7 @@ bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
const GrClip& clipIn,
GrTexture** result,
- GrRect *resultBounds) {
+ GrIRect *resultBounds) {
if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds)) {
return true;
@@ -504,7 +515,8 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
// offset the paths & rects that will be used to compute it
GrMatrix m;
- m.setTranslate(-resultBounds->fLeft, -resultBounds->fTop);
+ m.setTranslate(SkIntToScalar(-resultBounds->fLeft),
+ SkIntToScalar(-resultBounds->fTop));
drawState->setViewMatrix(m);
}
@@ -541,7 +553,7 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
// there is no point in intersecting a screen filling rectangle.
if (SkRegion::kIntersect_Op == op &&
kRect_ClipType == clipIn.getElementType(c) &&
- clipIn.getRect(c).contains(*resultBounds)) {
+ contains(clipIn.getRect(c), *resultBounds)) {
continue;
}
@@ -564,7 +576,8 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) {
GrMatrix m;
- m.setTranslate(resultBounds->fLeft, resultBounds->fTop);
+ m.setTranslate(SkIntToScalar(resultBounds->fLeft),
+ SkIntToScalar(resultBounds->fTop));
drawState->preConcatViewMatrix(m);
}
@@ -577,7 +590,8 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) {
GrMatrix m;
- m.setTranslate(-resultBounds->fLeft, -resultBounds->fTop);
+ m.setTranslate(SkIntToScalar(-resultBounds->fLeft),
+ SkIntToScalar(-resultBounds->fTop));
drawState->preConcatViewMatrix(m);
}
@@ -643,9 +657,7 @@ bool GrClipMaskManager::createStencilClipMask(GrGpu* gpu,
"Ganesh only handles 16b or smaller stencil buffers");
clipBit = (1 << (clipBit-1));
- GrRect rtRect;
- rtRect.setLTRB(0, 0,
- GrIntToScalar(rt->width()), GrIntToScalar(rt->height()));
+ GrIRect rtRect = GrIRect::MakeWH(rt->width(), rt->height());
bool clearToInside;
SkRegion::Op startOp = SkRegion::kReplace_Op; // suppress warning
@@ -681,7 +693,7 @@ bool GrClipMaskManager::createStencilClipMask(GrGpu* gpu,
// there is no point in intersecting a screen filling
// rectangle.
if (SkRegion::kIntersect_Op == op &&
- clipCopy.getRect(c).contains(rtRect)) {
+ contains(clipCopy.getRect(c), rtRect)) {
continue;
}
} else {
@@ -769,7 +781,7 @@ bool GrClipMaskManager::createStencilClipMask(GrGpu* gpu,
bool GrClipMaskManager::createSoftwareClipMask(GrGpu* gpu,
const GrClip& clipIn,
GrTexture** result,
- GrRect *resultBounds) {
+ GrIRect *resultBounds) {
if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds)) {
return true;
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index c87bb7c32a..02fc875f83 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -151,7 +151,7 @@ public:
void acquireMask(const GrClip& clip,
const GrTextureDesc& desc,
- const GrRect& bound) {
+ const GrIRect& bound) {
if (fStack.empty()) {
GrAssert(false);
@@ -195,7 +195,7 @@ public:
return back->fLastMask.texture()->height();
}
- void getLastBound(GrRect* bound) const {
+ void getLastBound(GrIRect* bound) const {
if (fStack.empty()) {
GrAssert(false);
@@ -237,7 +237,7 @@ private:
void acquireMask(GrContext* context,
const GrClip& clip,
const GrTextureDesc& desc,
- const GrRect& bound) {
+ const GrIRect& bound) {
fLastClip = clip;
@@ -263,7 +263,7 @@ private:
// fLastBound stores the bounding box of the clip mask in canvas
// space. The left and top fields are used to offset the uvs for
// geometry drawn with this mask (in setupDrawStateAAClip)
- GrRect fLastBound;
+ GrIRect fLastBound;
};
GrContext* fContext;
@@ -322,15 +322,15 @@ private:
bool createAlphaClipMask(GrGpu* gpu,
const GrClip& clipIn,
GrTexture** result,
- GrRect *resultBounds);
+ GrIRect *resultBounds);
bool createSoftwareClipMask(GrGpu* gpu,
const GrClip& clipIn,
GrTexture** result,
- GrRect *resultBounds);
+ GrIRect *resultBounds);
bool clipMaskPreamble(GrGpu* gpu,
const GrClip& clipIn,
GrTexture** result,
- GrRect *resultBounds);
+ GrIRect *resultBounds);
bool drawPath(GrGpu* gpu,
const SkPath& path,
@@ -346,10 +346,10 @@ private:
GrTexture* target,
GrTexture* texture);
- void getTemp(const GrRect& bounds, GrAutoScratchTexture* temp);
+ void getTemp(const GrIRect& bounds, GrAutoScratchTexture* temp);
void setupCache(const GrClip& clip,
- const GrRect& bounds);
+ const GrIRect& bounds);
// determines the path renderer used to draw a clip path element.
GrPathRenderer* getClipPathRenderer(GrGpu* gpu,
diff --git a/tests/ClipCacheTest.cpp b/tests/ClipCacheTest.cpp
index 1fc5d45b8f..a0888d85e4 100644
--- a/tests/ClipCacheTest.cpp
+++ b/tests/ClipCacheTest.cpp
@@ -42,14 +42,14 @@ static void check_state(skiatest::Reporter* reporter,
const GrClipMaskCache& cache,
const GrClip& clip,
GrTexture* mask,
- const GrRect& bound) {
+ const GrIRect& bound) {
GrClip cacheClip;
cache.getLastClip(&cacheClip);
REPORTER_ASSERT(reporter, clip == cacheClip);
REPORTER_ASSERT(reporter, mask == cache.getLastMask());
- GrRect cacheBound;
+ GrIRect cacheBound;
cache.getLastBound(&cacheBound);
REPORTER_ASSERT(reporter, bound == cacheBound);
}
@@ -66,18 +66,18 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
GrClip emptyClip;
emptyClip.setEmpty();
- GrRect emptyBound;
+ GrIRect emptyBound;
emptyBound.setEmpty();
// check initial state
check_state(reporter, cache, emptyClip, NULL, emptyBound);
// set the current state
- GrRect bound1;
+ GrIRect bound1;
bound1.set(0, 0, 100, 100);
GrClip clip1;
- clip1.setFromRect(bound1);
+ clip1.setFromIRect(bound1);
const GrTextureDesc desc = {
kRenderTarget_GrTextureFlagBit,
@@ -107,12 +107,12 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
// modify the new state
- GrRect bound2;
+ GrIRect bound2;
bound2.set(-10, -10, 10, 10);
GrClip clip2;
clip2.setEmpty();
- clip2.setFromRect(bound2);
+ clip2.setFromIRect(bound2);
cache.acquireMask(clip2, desc, bound2);