Revert 6351 due to bugs.
git-svn-id: http://skia.googlecode.com/svn/trunk@6377 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
453995e01d
commit
2e0c79fb63
@ -138,10 +138,6 @@ public:
|
||||
* Gets the bounds of the clip element, either the rect or path bounds.
|
||||
*/
|
||||
const SkRect& getBounds() const;
|
||||
/**
|
||||
* Returns true if the clip element is a path that is inverse filled
|
||||
*/
|
||||
bool isInverseFilled() const;
|
||||
|
||||
const SkRect* fRect; // if non-null, this is a rect clip
|
||||
const SkPath* fPath; // if non-null, this is a path clip
|
||||
@ -177,12 +173,6 @@ public:
|
||||
*/
|
||||
const Clip* skipToTopmost(SkRegion::Op op);
|
||||
|
||||
/**
|
||||
* Moves forward to the next clip element that uses op. If no clip with that op is found,
|
||||
* returns NULL.
|
||||
*/
|
||||
const Clip* skipToNext(SkRegion::Op op);
|
||||
|
||||
/**
|
||||
* Restarts the iterator on a clip stack.
|
||||
*/
|
||||
|
@ -735,10 +735,6 @@ const SkRect& SkClipStack::Iter::Clip::getBounds() const {
|
||||
}
|
||||
}
|
||||
|
||||
bool SkClipStack::Iter::Clip::isInverseFilled() const {
|
||||
return NULL != fPath && fPath->isInverseFillType();
|
||||
}
|
||||
|
||||
SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc)
|
||||
: fStack(&stack) {
|
||||
this->reset(stack, startLoc);
|
||||
@ -823,18 +819,6 @@ const SkClipStack::Iter::Clip* SkClipStack::Iter::skipToTopmost(SkRegion::Op op)
|
||||
return this->next();
|
||||
}
|
||||
|
||||
const SkClipStack::Iter::Clip* SkClipStack::Iter::skipToNext(SkRegion::Op op) {
|
||||
const SkClipStack::Rec* rec;
|
||||
do {
|
||||
rec = (const SkClipStack::Rec*)fIter.next();
|
||||
if (NULL == rec) {
|
||||
return NULL;
|
||||
}
|
||||
} while (rec->fOp != op);
|
||||
this->updateClip(rec);
|
||||
return &fClip;
|
||||
}
|
||||
|
||||
const SkClipStack::Iter::Clip* SkClipStack::Iter::nextCombined() {
|
||||
const Clip* clip;
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
GR_DEFINE_RESOURCE_CACHE_DOMAIN(GrClipMaskManager, GetAlphaMaskDomain)
|
||||
|
||||
#define GR_AA_CLIP 1
|
||||
#define GR_SW_CLIP 1
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
namespace {
|
||||
@ -157,7 +158,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if GR_AA_CLIP
|
||||
#if GR_SW_CLIP
|
||||
bool requiresAA = requires_AA(*clipDataIn->fClipStack);
|
||||
|
||||
// If MSAA is enabled we can do everything in the stencil buffer.
|
||||
@ -181,7 +182,9 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
|
||||
// if SW clip mask creation fails fall through to the other
|
||||
// two possible methods (bottoming out at stencil clipping)
|
||||
}
|
||||
#endif // GR_SW_CLIP
|
||||
|
||||
#if GR_AA_CLIP
|
||||
// If MSAA is enabled use the (faster) stencil path for AA clipping
|
||||
// otherwise the alpha clip mask is our only option
|
||||
if (0 == rt->numSamples() && requiresAA) {
|
||||
@ -343,7 +346,7 @@ const SkClipStack::Iter::Clip* process_initial_clip_elements(
|
||||
break;
|
||||
case SkRegion::kReverseDifference_Op:
|
||||
// if all pixels are clearToInside then reverse difference
|
||||
// produces empty set. Otherwise it is same as replace
|
||||
// produces empty set. Otherise it is same as replace
|
||||
if (*clearToInside) {
|
||||
*clearToInside = false;
|
||||
} else {
|
||||
@ -398,8 +401,48 @@ void setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool draw_path_in_software(GrContext* context,
|
||||
GrGpu* gpu,
|
||||
const SkPath& path,
|
||||
GrPathFill fill,
|
||||
bool doAA,
|
||||
const GrIRect& resultBounds) {
|
||||
|
||||
SkAutoTUnref<GrTexture> texture(
|
||||
GrSWMaskHelper::DrawPathMaskToTexture(context, path,
|
||||
resultBounds, fill,
|
||||
doAA, NULL));
|
||||
if (NULL == texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The ClipMaskManager accumulates the clip mask in the UL corner
|
||||
GrIRect rect = GrIRect::MakeWH(resultBounds.width(), resultBounds.height());
|
||||
|
||||
GrSWMaskHelper::DrawToTargetWithPathMask(texture, gpu, rect);
|
||||
|
||||
GrAssert(!GrIsFillInverted(fill));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool draw_path(GrContext* context,
|
||||
GrGpu* gpu,
|
||||
const SkPath& path,
|
||||
GrPathFill fill,
|
||||
bool doAA,
|
||||
const GrIRect& resultBounds) {
|
||||
|
||||
GrPathRenderer* pr = context->getPathRenderer(path, fill, gpu, doAA, false);
|
||||
if (NULL == pr) {
|
||||
return draw_path_in_software(context, gpu, path, fill, doAA, resultBounds);
|
||||
}
|
||||
|
||||
pr->drawPath(path, fill, gpu, doAA);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 'rect' enters in device coordinates and leaves in canvas coordinates
|
||||
void device_to_canvas(SkRect* rect, const SkIPoint& origin) {
|
||||
@ -416,19 +459,12 @@ void device_to_canvas(SkRect* rect, const SkIPoint& origin) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool GrClipMaskManager::drawClipShape(GrTexture* target,
|
||||
const SkClipStack::Iter::Clip* clip,
|
||||
const SkIRect& clipRect) {
|
||||
const GrIRect& resultBounds) {
|
||||
GrDrawState* drawState = fGpu->drawState();
|
||||
GrAssert(NULL != drawState);
|
||||
|
||||
drawState->setRenderTarget(target->asRenderTarget());
|
||||
|
||||
GrDrawTarget::AutoClipRestore acr(fGpu);
|
||||
SkClipStack rectStack(clipRect);
|
||||
GrClipData cd;
|
||||
cd.fClipStack = &rectStack;
|
||||
cd.fOrigin.setZero();
|
||||
fGpu->setClip(&cd);
|
||||
|
||||
if (NULL != clip->fRect) {
|
||||
if (clip->fDoAA) {
|
||||
getContext()->getAARectRenderer()->fillAARect(fGpu, fGpu,
|
||||
@ -438,18 +474,11 @@ bool GrClipMaskManager::drawClipShape(GrTexture* target,
|
||||
fGpu->drawSimpleRect(*clip->fRect, NULL);
|
||||
}
|
||||
} else if (NULL != clip->fPath) {
|
||||
|
||||
GrPathRenderer* pr = this->getContext()->getPathRenderer(*clip->fPath,
|
||||
get_path_fill(*clip->fPath),
|
||||
fGpu,
|
||||
clip->fDoAA,
|
||||
false);
|
||||
if (NULL == pr) {
|
||||
GrAssert(false); // We should have done the whole clip-stack in SW.
|
||||
return false;
|
||||
}
|
||||
|
||||
pr->drawPath(*clip->fPath, get_path_fill(*clip->fPath), fGpu, clip->fDoAA);
|
||||
return draw_path(this->getContext(), fGpu,
|
||||
*clip->fPath,
|
||||
get_path_fill(*clip->fPath),
|
||||
clip->fDoAA,
|
||||
resultBounds);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -535,7 +564,7 @@ bool GrClipMaskManager::clipMaskPreamble(const GrClipData& clipDataIn,
|
||||
clipDataIn.getConservativeBounds(rt, devResultBounds);
|
||||
|
||||
// need to outset a pixel since the standard bounding box computation
|
||||
// path doesn't leave any room for anti-aliasing (esp. w.r.t. rects)
|
||||
// path doesn't leave any room for antialiasing (esp. w.r.t. rects)
|
||||
devResultBounds->outset(1, 1);
|
||||
|
||||
// TODO: make sure we don't outset if bounds are still 0,0 @ min
|
||||
@ -550,30 +579,6 @@ bool GrClipMaskManager::clipMaskPreamble(const GrClipData& clipDataIn,
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Does a look-ahead to check whether we can bound earlier mask generation by forthcoming
|
||||
// intersections.
|
||||
void get_current_mask_bounds(const SkIRect& maskResultBounds,
|
||||
const SkClipStack::Iter& curr,
|
||||
const SkVector& clipToMaskOffset,
|
||||
SkRect* currMaskBounds) {
|
||||
SkClipStack::Iter isectIter(curr);
|
||||
const SkClipStack::Iter::Clip* clip = isectIter.skipToNext(SkRegion::kIntersect_Op);
|
||||
if (NULL != clip) {
|
||||
*currMaskBounds = clip->getBounds();
|
||||
while (NULL != (clip = isectIter.next()) &&
|
||||
SkRegion::kIntersect_Op == clip->fOp &&
|
||||
!clip->isInverseFilled()) {
|
||||
currMaskBounds->intersect(clip->getBounds());
|
||||
}
|
||||
currMaskBounds->offset(clipToMaskOffset);
|
||||
currMaskBounds->intersect(SkRect::MakeFromIRect(maskResultBounds));
|
||||
} else {
|
||||
*currMaskBounds = SkRect::MakeFromIRect(maskResultBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Create a 8-bit clip mask in alpha
|
||||
bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
|
||||
@ -616,9 +621,8 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
|
||||
bool clearToInside;
|
||||
SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
|
||||
|
||||
SkClipStack::Iter iter(*clipDataIn.fClipStack, SkClipStack::Iter::kBottom_IterStart);
|
||||
iter.skipToTopmost(SkRegion::kReplace_Op);
|
||||
|
||||
SkClipStack::Iter iter(*clipDataIn.fClipStack,
|
||||
SkClipStack::Iter::kBottom_IterStart);
|
||||
const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
|
||||
*devResultBounds,
|
||||
&clearToInside,
|
||||
@ -629,26 +633,10 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
|
||||
fGpu->clear(&maskResultBounds,
|
||||
clearToInside ? 0xffffffff : 0x00000000,
|
||||
accum->asRenderTarget());
|
||||
GR_DEBUGCODE(bool accumClearedToZero = !clearToInside;)
|
||||
|
||||
bool accumClearedToZero = !clearToInside;
|
||||
|
||||
GrAutoScratchTexture temp;
|
||||
bool first = true;
|
||||
|
||||
// We bound mask-generation to both the known bounds of the final result as well as the bounds
|
||||
// of the next run of intersections. This limits the amount of clearing and merging we have
|
||||
// to do and can also allow us to skip intersect-rects entirely.
|
||||
SkRect currMaskBounds;
|
||||
SkIRect currMaskIBounds;
|
||||
get_current_mask_bounds(maskResultBounds, iter, clipToMaskOffset, &currMaskBounds);
|
||||
// currMaskBounds is used to reduce the number of pixels touched. It also allows us to skip
|
||||
// non-AA intersect rects since we've clipped earlier elements to those rects already.
|
||||
// We round out here which is consistent with how non-AA rects are handled.
|
||||
currMaskBounds.roundOut(&currMaskIBounds);
|
||||
|
||||
// used to know when we're through with a run of intersect ops.
|
||||
SkRegion::Op prevOp = SkRegion::kReplace_Op;
|
||||
|
||||
// walk through each clip element and perform its set op
|
||||
for ( ; NULL != clip; clip = iter.nextCombined()) {
|
||||
|
||||
@ -658,33 +646,18 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
|
||||
op = firstOp;
|
||||
}
|
||||
|
||||
if (op == SkRegion::kIntersect_Op) {
|
||||
// When we encounter an intersect we may have already fully accounted for it by applying
|
||||
// currMaskBounds to the accumulated mask.
|
||||
if (NULL != clip->fRect &&
|
||||
(!clip->fDoAA || clip->fRect->contains(currMaskBounds))) {
|
||||
prevOp = SkRegion::kIntersect_Op;
|
||||
continue;
|
||||
}
|
||||
} else if (prevOp == SkRegion::kIntersect_Op) {
|
||||
// We've finished a run of intersects, update currMaskBounds based on the next run.
|
||||
get_current_mask_bounds(maskResultBounds, iter, clipToMaskOffset, &currMaskBounds);
|
||||
currMaskBounds.roundOut(&currMaskIBounds);
|
||||
}
|
||||
|
||||
prevOp = op;
|
||||
|
||||
if (SkRegion::kReplace_Op == op) {
|
||||
// The accumulator should already be cleared. There can only be one replace since we
|
||||
// skip to the last one. Moreover, process_initial_clip_elements will have set
|
||||
// clearToInside to false before the initial clear.
|
||||
GrAssert(accumClearedToZero);
|
||||
// clear the accumulator and draw the new object directly into it
|
||||
if (!accumClearedToZero) {
|
||||
fGpu->clear(&maskResultBounds, 0x00000000, accum->asRenderTarget());
|
||||
}
|
||||
|
||||
setup_boolean_blendcoeffs(drawState, op);
|
||||
this->drawClipShape(accum, clip, currMaskIBounds);
|
||||
this->drawClipShape(accum, clip, *devResultBounds);
|
||||
|
||||
} else if (SkRegion::kReverseDifference_Op == op ||
|
||||
SkRegion::kIntersect_Op == op) {
|
||||
// There is no point in intersecting a screen filling rectangle.
|
||||
// there is no point in intersecting a screen filling rectangle.
|
||||
if (SkRegion::kIntersect_Op == op && NULL != clip->fRect &&
|
||||
contains(*clip->fRect, *devResultBounds, clipDataIn.fOrigin)) {
|
||||
continue;
|
||||
@ -696,32 +669,31 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is the bounds of the clip element in the space of the alpha-mask. The temporary
|
||||
// this is the bounds of the clip element in the space of the alpha-mask. The temporary
|
||||
// mask buffer can be substantially larger than the actually clip stack element. We
|
||||
// touch the minimum number of pixels necessary and use decal mode to combine it with
|
||||
// the accumulator.
|
||||
// the accumulator
|
||||
GrRect elementMaskBounds = clip->getBounds();
|
||||
elementMaskBounds.offset(clipToMaskOffset);
|
||||
elementMaskBounds.intersect(currMaskBounds);
|
||||
GrIRect elementMaskIBounds;
|
||||
elementMaskBounds.roundOut(&elementMaskIBounds);
|
||||
|
||||
// Clear the temp target & draw into it
|
||||
// clear the temp target & draw into it
|
||||
fGpu->clear(&elementMaskIBounds, 0x00000000, temp.texture()->asRenderTarget());
|
||||
|
||||
setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op);
|
||||
this->drawClipShape(temp.texture(), clip, currMaskIBounds);
|
||||
this->drawClipShape(temp.texture(), clip, elementMaskIBounds);
|
||||
|
||||
// Now draw into the accumulator using the real operation and the temp buffer as a
|
||||
// texture
|
||||
// Now draw into the accumulator using the real operation
|
||||
// and the temp buffer as a texture
|
||||
this->mergeMask(accum, temp.texture(), op, maskResultBounds, elementMaskIBounds);
|
||||
} else {
|
||||
// all the remaining ops can just be directly draw into
|
||||
// the accumulation buffer
|
||||
setup_boolean_blendcoeffs(drawState, op);
|
||||
this->drawClipShape(accum, clip, currMaskIBounds);
|
||||
this->drawClipShape(accum, clip, *devResultBounds);
|
||||
}
|
||||
GR_DEBUGCODE(accumClearedToZero = false;)
|
||||
accumClearedToZero = false;
|
||||
}
|
||||
|
||||
*result = accum;
|
||||
|
@ -126,7 +126,7 @@ private:
|
||||
|
||||
bool drawClipShape(GrTexture* target,
|
||||
const SkClipStack::Iter::Clip* clip,
|
||||
const SkIRect& clipRect);
|
||||
const GrIRect& resultBounds);
|
||||
|
||||
void mergeMask(GrTexture* dstMask,
|
||||
GrTexture* srcMask,
|
||||
|
Loading…
Reference in New Issue
Block a user