Convert GrClip to an abstract base class
Converts GrClip to an abstract base class and adds a "GrFixedClip" implementation. GrFixedClip denotes a clip implemented with fixed- function hardware. GrFixedClip allows us to remove the stateful "fClipMode" member from GrClipMaskManager, and in the future will be able to nicely encapsulate window rectangles. After this change GrClipMaskManager is just a wrapper around GrDrawTarget. We may want to consider removing it altogether. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1971343002 Review-Url: https://codereview.chromium.org/1971343002
This commit is contained in:
parent
670f01f2fc
commit
846c051a48
@ -82,7 +82,7 @@ DEF_SIMPLE_GM_BG(texdata, canvas, 2 * S, 2 * S, SK_ColorBLACK) {
|
|||||||
SkAutoTUnref<GrTexture> au(texture);
|
SkAutoTUnref<GrTexture> au(texture);
|
||||||
|
|
||||||
// setup new clip
|
// setup new clip
|
||||||
GrClip clip(SkRect::MakeWH(2*S, 2*S));
|
GrFixedClip clip(SkIRect::MakeWH(2*S, 2*S));
|
||||||
|
|
||||||
GrPaint paint;
|
GrPaint paint;
|
||||||
paint.setPorterDuffXPFactory(SkXfermode::kSrcOver_Mode);
|
paint.setPorterDuffXPFactory(SkXfermode::kSrcOver_Mode);
|
||||||
|
@ -8,185 +8,125 @@
|
|||||||
#ifndef GrClip_DEFINED
|
#ifndef GrClip_DEFINED
|
||||||
#define GrClip_DEFINED
|
#define GrClip_DEFINED
|
||||||
|
|
||||||
|
#include "GrFragmentProcessor.h"
|
||||||
|
#include "GrTypesPriv.h"
|
||||||
#include "SkClipStack.h"
|
#include "SkClipStack.h"
|
||||||
|
|
||||||
struct SkIRect;
|
class GrClipMaskManager;
|
||||||
|
class GrPipelineBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GrClip encapsulates the information required to construct the clip
|
* Produced by GrClip. It provides a set of modifications to the drawing state that are used to
|
||||||
* masks. 'A GrClip is either wide open, just an IRect, just a Rect, or a full clipstack.
|
* create the final GrPipeline for a GrBatch.
|
||||||
* If the clip is a clipstack than the origin is used to translate the stack with
|
|
||||||
* respect to device coordinates. This allows us to use a clip stack that is
|
|
||||||
* specified for a root device with a layer device that is restricted to a subset
|
|
||||||
* of the original canvas. For other clip types the origin will always be (0,0).
|
|
||||||
*
|
|
||||||
* NOTE: GrClip *must* point to a const clipstack
|
|
||||||
*/
|
*/
|
||||||
class GrClip : SkNoncopyable {
|
class GrAppliedClip {
|
||||||
public:
|
public:
|
||||||
GrClip() : fClipType(kWideOpen_ClipType) {
|
GrAppliedClip() : fHasStencilClip(false) {}
|
||||||
fOrigin.setZero();
|
const GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP; }
|
||||||
}
|
const GrScissorState& scissorState() const { return fScissorState; }
|
||||||
|
bool hasStencilClip() const { return fHasStencilClip; }
|
||||||
GrClip(const SkIRect& rect) : fClipType(kIRect_ClipType) {
|
|
||||||
fOrigin.setZero();
|
|
||||||
fClip.fIRect = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
GrClip(const SkRect& rect) : fClipType(kIRect_ClipType) {
|
|
||||||
fOrigin.setZero();
|
|
||||||
fClip.fIRect.fLeft = SkScalarRoundToInt(rect.fLeft);
|
|
||||||
fClip.fIRect.fTop = SkScalarRoundToInt(rect.fTop);
|
|
||||||
fClip.fIRect.fRight = SkScalarRoundToInt(rect.fRight);
|
|
||||||
fClip.fIRect.fBottom = SkScalarRoundToInt(rect.fBottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
~GrClip() { this->reset(); }
|
|
||||||
|
|
||||||
const GrClip& operator=(const GrClip& other) {
|
|
||||||
this->reset();
|
|
||||||
fClipType = other.fClipType;
|
|
||||||
switch (other.fClipType) {
|
|
||||||
case kWideOpen_ClipType:
|
|
||||||
fOrigin.setZero();
|
|
||||||
break;
|
|
||||||
case kClipStack_ClipType:
|
|
||||||
fClip.fStack = SkRef(other.clipStack());
|
|
||||||
fOrigin = other.origin();
|
|
||||||
break;
|
|
||||||
case kIRect_ClipType:
|
|
||||||
fClip.fIRect = other.irect();
|
|
||||||
fOrigin.setZero();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const GrClip& other) const {
|
|
||||||
if (this->clipType() != other.clipType()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (fClipType) {
|
|
||||||
case kWideOpen_ClipType:
|
|
||||||
return true;
|
|
||||||
case kClipStack_ClipType:
|
|
||||||
if (this->origin() != other.origin()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->clipStack() && other.clipStack()) {
|
|
||||||
return *this->clipStack() == *other.clipStack();
|
|
||||||
} else {
|
|
||||||
return this->clipStack() == other.clipStack();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case kIRect_ClipType:
|
|
||||||
return this->irect() == other.irect();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SkFAIL("This should not occur\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const GrClip& other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
const SkClipStack* clipStack() const {
|
|
||||||
SkASSERT(kClipStack_ClipType == fClipType);
|
|
||||||
return fClip.fStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setClipStack(const SkClipStack* clipStack, const SkIPoint* origin = NULL) {
|
|
||||||
this->reset();
|
|
||||||
if (clipStack->isWideOpen()) {
|
|
||||||
fClipType = kWideOpen_ClipType;
|
|
||||||
fOrigin.setZero();
|
|
||||||
} else {
|
|
||||||
fClipType = kClipStack_ClipType;
|
|
||||||
fClip.fStack = SkRef(clipStack);
|
|
||||||
if (origin) {
|
|
||||||
fOrigin = *origin;
|
|
||||||
} else {
|
|
||||||
fOrigin.setZero();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setIRect(const SkIRect& irect) {
|
|
||||||
this->reset();
|
|
||||||
fClipType = kIRect_ClipType;
|
|
||||||
fOrigin.setZero();
|
|
||||||
fClip.fIRect = irect;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SkIRect& irect() const {
|
|
||||||
SkASSERT(kIRect_ClipType == fClipType);
|
|
||||||
return fClip.fIRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
if (kClipStack_ClipType == fClipType) {
|
|
||||||
fClip.fStack->unref();
|
|
||||||
fClip.fStack = NULL;
|
|
||||||
}
|
|
||||||
fClipType = kWideOpen_ClipType;
|
|
||||||
fOrigin.setZero();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We support this for all cliptypes to simplify the logic a bit in clip mask manager.
|
|
||||||
// non clipstack clip types MUST have a (0,0) origin
|
|
||||||
const SkIPoint& origin() const {
|
|
||||||
SkASSERT(fClipType == kClipStack_ClipType || (fOrigin.fX == 0 && fOrigin.fY == 0));
|
|
||||||
return fOrigin;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isWideOpen(const SkRect& rect) const {
|
|
||||||
return (kWideOpen_ClipType == fClipType) ||
|
|
||||||
(kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) ||
|
|
||||||
(kIRect_ClipType == fClipType && this->irect().contains(rect));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isWideOpen(const SkIRect& rect) const {
|
|
||||||
return (kWideOpen_ClipType == fClipType) ||
|
|
||||||
(kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) ||
|
|
||||||
(kIRect_ClipType == fClipType && this->irect().contains(rect));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isWideOpen() const {
|
|
||||||
return (kWideOpen_ClipType == fClipType) ||
|
|
||||||
(kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool quickContains(const SkRect& rect) const {
|
|
||||||
return (kWideOpen_ClipType == fClipType) ||
|
|
||||||
(kClipStack_ClipType == fClipType && this->clipStack()->quickContains(rect)) ||
|
|
||||||
(kIRect_ClipType == fClipType && this->irect().contains(rect));
|
|
||||||
}
|
|
||||||
|
|
||||||
void getConservativeBounds(int width, int height,
|
|
||||||
SkIRect* devResult,
|
|
||||||
bool* isIntersectionOfRects = NULL) const;
|
|
||||||
|
|
||||||
static const GrClip& WideOpen();
|
|
||||||
|
|
||||||
enum ClipType {
|
|
||||||
kClipStack_ClipType,
|
|
||||||
kWideOpen_ClipType,
|
|
||||||
kIRect_ClipType,
|
|
||||||
};
|
|
||||||
|
|
||||||
ClipType clipType() const { return fClipType; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union Clip {
|
SkAutoTUnref<const GrFragmentProcessor> fClipCoverageFP;
|
||||||
const SkClipStack* fStack;
|
GrScissorState fScissorState;
|
||||||
SkIRect fIRect;
|
bool fHasStencilClip;
|
||||||
} fClip;
|
|
||||||
|
|
||||||
SkIPoint fOrigin;
|
friend class GrFixedClip;
|
||||||
ClipType fClipType;
|
friend class GrClipMaskManager;
|
||||||
|
|
||||||
|
typedef SkNoncopyable INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GrClip is an abstract base class for applying a clip. It constructs a clip mask if necessary, and
|
||||||
|
* fills out a GrAppliedClip instructing the caller on how to set up the draw state.
|
||||||
|
*/
|
||||||
|
class GrClip {
|
||||||
|
public:
|
||||||
|
virtual bool quickContains(const SkRect&) const = 0;
|
||||||
|
virtual void getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||||
|
bool* isIntersectionOfRects = nullptr) const = 0;
|
||||||
|
virtual bool apply(GrClipMaskManager*, const GrPipelineBuilder&, const SkRect* devBounds,
|
||||||
|
GrAppliedClip*) const = 0;
|
||||||
|
|
||||||
|
virtual ~GrClip() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialized implementation for no clip.
|
||||||
|
*/
|
||||||
|
class GrNoClip final : public GrClip {
|
||||||
|
private:
|
||||||
|
bool quickContains(const SkRect&) const final { return true; }
|
||||||
|
void getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||||
|
bool* isIntersectionOfRects) const final;
|
||||||
|
bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
|
||||||
|
const SkRect*, GrAppliedClip*) const final { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GrFixedClip is a clip that can be represented by fixed-function hardware. It never modifies the
|
||||||
|
* stencil buffer itself, but can be configured to use whatever clip is already there.
|
||||||
|
*/
|
||||||
|
class GrFixedClip final : public GrClip {
|
||||||
|
public:
|
||||||
|
GrFixedClip() : fHasStencilClip(false) {}
|
||||||
|
GrFixedClip(const SkIRect& scissorRect) : fScissorState(scissorRect), fHasStencilClip(false) {}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
fScissorState.setDisabled();
|
||||||
|
fHasStencilClip = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(const SkIRect& scissorRect) {
|
||||||
|
fScissorState.set(scissorRect);
|
||||||
|
fHasStencilClip = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enableStencilClip(bool enable) { fHasStencilClip = enable; }
|
||||||
|
|
||||||
|
const GrScissorState& scissorState() const { return fScissorState; }
|
||||||
|
bool hasStencilClip() const { return fHasStencilClip; }
|
||||||
|
|
||||||
|
bool quickContains(const SkRect&) const final;
|
||||||
|
void getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||||
|
bool* isIntersectionOfRects) const final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
|
||||||
|
const SkRect* devBounds, GrAppliedClip* out) const final;
|
||||||
|
|
||||||
|
GrScissorState fScissorState;
|
||||||
|
bool fHasStencilClip;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GrClipStackClip can apply a generic SkClipStack to the draw state. It may generate clip masks or
|
||||||
|
* write to the stencil buffer during apply().
|
||||||
|
*/
|
||||||
|
class GrClipStackClip final : public GrClip {
|
||||||
|
public:
|
||||||
|
GrClipStackClip(const SkClipStack* stack = nullptr, const SkIPoint* origin = nullptr) {
|
||||||
|
this->reset(stack, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(const SkClipStack* stack = nullptr, const SkIPoint* origin = nullptr) {
|
||||||
|
fOrigin = origin ? *origin : SkIPoint::Make(0, 0);
|
||||||
|
fStack.reset(SkSafeRef(stack));
|
||||||
|
}
|
||||||
|
|
||||||
|
const SkIPoint& origin() const { return fOrigin; }
|
||||||
|
const SkClipStack* clipStack() const { return fStack; }
|
||||||
|
|
||||||
|
bool quickContains(const SkRect&) const final;
|
||||||
|
void getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||||
|
bool* isIntersectionOfRects) const final;
|
||||||
|
bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
|
||||||
|
const SkRect* devBounds, GrAppliedClip*) const final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SkIPoint fOrigin;
|
||||||
|
SkAutoTUnref<const SkClipStack> fStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -401,6 +401,8 @@ enum GrIOType {
|
|||||||
|
|
||||||
struct GrScissorState {
|
struct GrScissorState {
|
||||||
GrScissorState() : fEnabled(false) {}
|
GrScissorState() : fEnabled(false) {}
|
||||||
|
GrScissorState(const SkIRect& rect) : fEnabled(true), fRect(rect) {}
|
||||||
|
void setDisabled() { fEnabled = false; }
|
||||||
void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
|
void set(const SkIRect& rect) { fRect = rect; fEnabled = true; }
|
||||||
bool operator==(const GrScissorState& other) const {
|
bool operator==(const GrScissorState& other) const {
|
||||||
return fEnabled == other.fEnabled &&
|
return fEnabled == other.fEnabled &&
|
||||||
|
@ -287,13 +287,13 @@ sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkIRect dstIRect = SkIRect::MakeWH(bounds.width(), bounds.height());
|
||||||
SkRect srcRect = SkRect::Make(bounds);
|
SkRect srcRect = SkRect::Make(bounds);
|
||||||
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
|
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
|
||||||
GrClip clip(dstRect);
|
GrFixedClip clip(dstIRect);
|
||||||
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
|
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
|
||||||
|
|
||||||
return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()),
|
return SkSpecialImage::MakeFromGpu(dstIRect, kNeedNewImageUniqueID_SpecialImage,
|
||||||
kNeedNewImageUniqueID_SpecialImage,
|
|
||||||
drawContext->asTexture());
|
drawContext->asTexture());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -114,7 +114,7 @@ sk_sp<GrTexture> SkAlphaThresholdFilterImpl::createMaskTexture(GrContext* contex
|
|||||||
SkRegion::Iterator iter(fRegion);
|
SkRegion::Iterator iter(fRegion);
|
||||||
drawContext->clear(nullptr, 0x0, true);
|
drawContext->clear(nullptr, 0x0, true);
|
||||||
|
|
||||||
GrClip clip(SkRect::Make(SkIRect::MakeWH(bounds.width(), bounds.height())));
|
GrFixedClip clip(SkIRect::MakeWH(bounds.width(), bounds.height()));
|
||||||
while (!iter.done()) {
|
while (!iter.done()) {
|
||||||
SkRect rect = SkRect::Make(iter.rect());
|
SkRect rect = SkRect::Make(iter.rect());
|
||||||
drawContext->drawRect(clip, grPaint, inMatrix, rect);
|
drawContext->drawRect(clip, grPaint, inMatrix, rect);
|
||||||
|
@ -1278,7 +1278,7 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
|
|||||||
paint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
|
paint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), SkRect::Make(clipRect));
|
drawContext->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::Make(clipRect));
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = drawContext->asTexture().release();
|
*result = drawContext->asTexture().release();
|
||||||
|
@ -342,7 +342,7 @@ sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* sou
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(colorBounds));
|
drawContext->drawRect(GrNoClip(), paint, matrix, SkRect::Make(colorBounds));
|
||||||
|
|
||||||
offset->fX = bounds.left();
|
offset->fX = bounds.left();
|
||||||
offset->fY = bounds.top();
|
offset->fY = bounds.top();
|
||||||
|
@ -212,7 +212,7 @@ sk_sp<GrDrawContext> GaussianBlur(GrContext* context,
|
|||||||
scale_irect(&srcRect, scaleFactorX, scaleFactorY);
|
scale_irect(&srcRect, scaleFactorX, scaleFactorY);
|
||||||
|
|
||||||
// setup new clip
|
// setup new clip
|
||||||
GrClip clip(localDstBounds);
|
GrFixedClip clip(localDstBounds);
|
||||||
|
|
||||||
sk_sp<GrTexture> srcTexture(sk_ref_sp(origSrc));
|
sk_sp<GrTexture> srcTexture(sk_ref_sp(origSrc));
|
||||||
|
|
||||||
|
@ -415,11 +415,11 @@ sk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU(SkSpecialIma
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkRect dstRect = SkRect::MakeWH(SkIntToScalar(offsetBounds.width()),
|
SkIRect dstIRect = SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height());
|
||||||
SkIntToScalar(offsetBounds.height()));
|
SkRect dstRect = SkRect::Make(dstIRect);
|
||||||
|
|
||||||
// setup new clip
|
// setup new clip
|
||||||
GrClip clip(dstRect);
|
GrFixedClip clip(dstIRect);
|
||||||
|
|
||||||
const SkIRect inputBounds = SkIRect::MakeWH(input->width(), input->height());
|
const SkIRect inputBounds = SkIRect::MakeWH(input->width(), input->height());
|
||||||
SkRect topLeft = SkRect::MakeXYWH(0, 0, 1, 1);
|
SkRect topLeft = SkRect::MakeXYWH(0, 0, 1, 1);
|
||||||
|
@ -478,8 +478,7 @@ static sk_sp<SkSpecialImage> apply_morphology(GrContext* context,
|
|||||||
SkASSERT(srcTexture);
|
SkASSERT(srcTexture);
|
||||||
|
|
||||||
// setup new clip
|
// setup new clip
|
||||||
const GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()),
|
const GrFixedClip clip(SkIRect::MakeWH(srcTexture->width(), srcTexture->height()));
|
||||||
SkIntToScalar(srcTexture->height())));
|
|
||||||
|
|
||||||
const SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
|
const SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
|
||||||
SkIRect srcRect = rect;
|
SkIRect srcRect = rect;
|
||||||
|
@ -249,7 +249,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter::filterImageGPU(SkSpecialImage* sour
|
|||||||
|
|
||||||
SkMatrix matrix;
|
SkMatrix matrix;
|
||||||
matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
|
matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
|
||||||
drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds));
|
drawContext->drawRect(GrNoClip(), paint, matrix, SkRect::Make(bounds));
|
||||||
|
|
||||||
return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()),
|
return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()),
|
||||||
kNeedNewImageUniqueID_SpecialImage,
|
kNeedNewImageUniqueID_SpecialImage,
|
||||||
|
@ -125,8 +125,8 @@ static sk_sp<GrTexture> create_mask_GPU(GrContext* context,
|
|||||||
tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
|
tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
|
||||||
|
|
||||||
// setup new clip
|
// setup new clip
|
||||||
const SkRect clipRect = SkRect::MakeIWH(maskRect.width(), maskRect.height());
|
const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height());
|
||||||
GrClip clip(clipRect);
|
GrFixedClip clip(clipRect);
|
||||||
|
|
||||||
// Draw the mask into maskTexture with the path's integerized top-left at
|
// Draw the mask into maskTexture with the path's integerized top-left at
|
||||||
// the origin using tempPaint.
|
// the origin using tempPaint.
|
||||||
|
@ -7,47 +7,83 @@
|
|||||||
|
|
||||||
#include "GrClip.h"
|
#include "GrClip.h"
|
||||||
|
|
||||||
#include "GrSurface.h"
|
#include "GrClipMaskManager.h"
|
||||||
#include "SkRect.h"
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getConservativeBounds returns the conservative bounding box of the clip
|
|
||||||
* in device (as opposed to canvas) coordinates. If the bounding box is
|
|
||||||
* the result of purely intersections of rects (with an initial replace)
|
|
||||||
* isIntersectionOfRects will be set to true.
|
|
||||||
*/
|
|
||||||
void GrClip::getConservativeBounds(int width, int height, SkIRect* devResult,
|
|
||||||
bool* isIntersectionOfRects) const {
|
|
||||||
switch (fClipType) {
|
|
||||||
case kWideOpen_ClipType: {
|
|
||||||
devResult->setLTRB(0, 0, width, height);
|
|
||||||
if (isIntersectionOfRects) {
|
|
||||||
*isIntersectionOfRects = true;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case kIRect_ClipType: {
|
|
||||||
*devResult = this->irect();
|
|
||||||
if (isIntersectionOfRects) {
|
|
||||||
*isIntersectionOfRects = true;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case kClipStack_ClipType: {
|
|
||||||
SkRect devBounds;
|
|
||||||
this->clipStack()->getConservativeBounds(-this->origin().fX,
|
|
||||||
-this->origin().fY,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
&devBounds,
|
|
||||||
isIntersectionOfRects);
|
|
||||||
devBounds.roundOut(devResult);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
|
void GrNoClip::getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||||
|
bool* isIntersectionOfRects) const {
|
||||||
|
devResult->setXYWH(0, 0, width, height);
|
||||||
|
if (isIntersectionOfRects) {
|
||||||
|
*isIntersectionOfRects = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrClip& GrClip::WideOpen() {
|
bool GrFixedClip::quickContains(const SkRect& rect) const {
|
||||||
static const GrClip clip;
|
if (fHasStencilClip) {
|
||||||
return clip;
|
return false;
|
||||||
|
}
|
||||||
|
if (!fScissorState.enabled()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return fScissorState.rect().contains(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrFixedClip::getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||||
|
bool* isIntersectionOfRects) const {
|
||||||
|
devResult->setXYWH(0, 0, width, height);
|
||||||
|
if (fScissorState.enabled()) {
|
||||||
|
if (!devResult->intersect(fScissorState.rect())) {
|
||||||
|
devResult->setEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isIntersectionOfRects) {
|
||||||
|
*isIntersectionOfRects = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GrFixedClip::apply(GrClipMaskManager*, const GrPipelineBuilder& pipelineBuilder,
|
||||||
|
const SkRect* devBounds, GrAppliedClip* out) const {
|
||||||
|
if (fScissorState.enabled()) {
|
||||||
|
const GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
|
||||||
|
SkIRect tightScissor;
|
||||||
|
if (!tightScissor.intersect(fScissorState.rect(),
|
||||||
|
SkIRect::MakeWH(rt->width(), rt->height()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (devBounds && !devBounds->intersects(SkRect::Make(tightScissor))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out->fScissorState.set(tightScissor);
|
||||||
|
}
|
||||||
|
out->fHasStencilClip = fHasStencilClip;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GrClipStackClip::quickContains(const SkRect& rect) const {
|
||||||
|
if (!fStack) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return fStack->quickContains(rect.makeOffset(SkIntToScalar(fOrigin.x()),
|
||||||
|
SkIntToScalar(fOrigin.y())));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrClipStackClip::getConservativeBounds(int width, int height, SkIRect* devResult,
|
||||||
|
bool* isIntersectionOfRects) const {
|
||||||
|
if (!fStack) {
|
||||||
|
devResult->setXYWH(0, 0, width, height);
|
||||||
|
if (isIntersectionOfRects) {
|
||||||
|
*isIntersectionOfRects = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SkRect devBounds;
|
||||||
|
fStack->getConservativeBounds(-fOrigin.x(), -fOrigin.y(), width, height, &devBounds,
|
||||||
|
isIntersectionOfRects);
|
||||||
|
devBounds.roundOut(devResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GrClipStackClip::apply(GrClipMaskManager* clipMaskManager,
|
||||||
|
const GrPipelineBuilder& pipelineBuilder, const SkRect* devBounds,
|
||||||
|
GrAppliedClip* out) const {
|
||||||
|
// TODO: Collapse ClipMaskManager into this class.(?)
|
||||||
|
return clipMaskManager->setupClipping(pipelineBuilder, *this, devBounds, out);
|
||||||
}
|
}
|
||||||
|
@ -137,11 +137,6 @@ GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context,
|
|||||||
return pr;
|
return pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
|
|
||||||
: fDrawTarget(drawTarget)
|
|
||||||
, fClipMode(kIgnoreClip_StencilClipMode) {
|
|
||||||
}
|
|
||||||
|
|
||||||
GrContext* GrClipMaskManager::getContext() {
|
GrContext* GrClipMaskManager::getContext() {
|
||||||
return fDrawTarget->cmmAccess().context();
|
return fDrawTarget->cmmAccess().context();
|
||||||
}
|
}
|
||||||
@ -288,11 +283,11 @@ bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis
|
|||||||
// sort out what kind of clip mask needs to be created: alpha, stencil,
|
// sort out what kind of clip mask needs to be created: alpha, stencil,
|
||||||
// scissor, or entirely software
|
// scissor, or entirely software
|
||||||
bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
|
bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
|
||||||
const GrClip& clip,
|
const GrClipStackClip& clip,
|
||||||
const SkRect* devBounds,
|
const SkRect* devBounds,
|
||||||
GrAppliedClip* out) {
|
GrAppliedClip* out) {
|
||||||
if (kRespectClip_StencilClipMode == fClipMode) {
|
if (!clip.clipStack() || clip.clipStack()->isWideOpen()) {
|
||||||
fClipMode = kIgnoreClip_StencilClipMode;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrReducedClip::ElementList elements;
|
GrReducedClip::ElementList elements;
|
||||||
@ -306,58 +301,35 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
|
|||||||
SkASSERT(rt);
|
SkASSERT(rt);
|
||||||
|
|
||||||
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
|
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
|
||||||
if (clip.isWideOpen(clipSpaceRTIBounds)) {
|
clipSpaceRTIBounds.offset(clip.origin());
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The clip mask manager always draws with a single IRect so we special case that logic here
|
SkIRect clipSpaceReduceQueryBounds;
|
||||||
// Image filters just use a rect, so we also special case that logic
|
#define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0
|
||||||
switch (clip.clipType()) {
|
if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) {
|
||||||
case GrClip::kWideOpen_ClipType:
|
SkIRect devIBounds = devBounds->roundOut();
|
||||||
SkFAIL("Should have caught this with clip.isWideOpen()");
|
devIBounds.offset(clip.origin());
|
||||||
return true;
|
if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, devIBounds)) {
|
||||||
case GrClip::kIRect_ClipType: {
|
return false;
|
||||||
SkIRect scissor = clip.irect();
|
}
|
||||||
if (scissor.intersect(clipSpaceRTIBounds)) {
|
} else {
|
||||||
out->fScissorState.set(scissor);
|
clipSpaceReduceQueryBounds = clipSpaceRTIBounds;
|
||||||
out->fHasStencilClip = kIgnoreClip_StencilClipMode != fClipMode;
|
}
|
||||||
return true;
|
GrReducedClip::ReduceClipStack(*clip.clipStack(),
|
||||||
}
|
clipSpaceReduceQueryBounds,
|
||||||
|
&elements,
|
||||||
|
&genID,
|
||||||
|
&initialState,
|
||||||
|
&clipSpaceIBounds,
|
||||||
|
&requiresAA);
|
||||||
|
if (elements.isEmpty()) {
|
||||||
|
if (GrReducedClip::kAllIn_InitialState == initialState) {
|
||||||
|
if (clipSpaceIBounds == clipSpaceRTIBounds) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case GrClip::kClipStack_ClipType: {
|
|
||||||
clipSpaceRTIBounds.offset(clip.origin());
|
|
||||||
SkIRect clipSpaceReduceQueryBounds;
|
|
||||||
#define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0
|
|
||||||
if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) {
|
|
||||||
SkIRect devIBounds = devBounds->roundOut();
|
|
||||||
devIBounds.offset(clip.origin());
|
|
||||||
if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, devIBounds)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
clipSpaceReduceQueryBounds = clipSpaceRTIBounds;
|
|
||||||
}
|
|
||||||
GrReducedClip::ReduceClipStack(*clip.clipStack(),
|
|
||||||
clipSpaceReduceQueryBounds,
|
|
||||||
&elements,
|
|
||||||
&genID,
|
|
||||||
&initialState,
|
|
||||||
&clipSpaceIBounds,
|
|
||||||
&requiresAA);
|
|
||||||
if (elements.isEmpty()) {
|
|
||||||
if (GrReducedClip::kAllIn_InitialState == initialState) {
|
|
||||||
if (clipSpaceIBounds == clipSpaceRTIBounds) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkASSERT(kIgnoreClip_StencilClipMode == fClipMode); // TODO: Remove fClipMode.
|
|
||||||
|
|
||||||
// An element count of 4 was chosen because of the common pattern in Blink of:
|
// An element count of 4 was chosen because of the common pattern in Blink of:
|
||||||
// isect RR
|
// isect RR
|
||||||
@ -452,13 +424,12 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
|
|||||||
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
|
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
|
||||||
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
|
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
|
||||||
out->fScissorState.set(scissorSpaceIBounds);
|
out->fScissorState.set(scissorSpaceIBounds);
|
||||||
SkASSERT(kRespectClip_StencilClipMode == fClipMode); // TODO: Remove fClipMode.
|
|
||||||
out->fHasStencilClip = true;
|
out->fHasStencilClip = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool stencil_element(GrDrawContext* dc,
|
static bool stencil_element(GrDrawContext* dc,
|
||||||
const GrClip& clip,
|
const GrFixedClip& clip,
|
||||||
const GrUserStencilSettings* ss,
|
const GrUserStencilSettings* ss,
|
||||||
const SkMatrix& viewMatrix,
|
const SkMatrix& viewMatrix,
|
||||||
const SkClipStack::Element* element) {
|
const SkClipStack::Element* element) {
|
||||||
@ -603,7 +574,7 @@ GrTexture* GrClipMaskManager::CreateAlphaClipMask(GrContext* context,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GrClip clip(maskSpaceIBounds);
|
GrFixedClip clip(maskSpaceIBounds);
|
||||||
|
|
||||||
// draw directly into the result with the stencil set to make the pixels affected
|
// draw directly into the result with the stencil set to make the pixels affected
|
||||||
// by the clip shape be non-zero.
|
// by the clip shape be non-zero.
|
||||||
@ -645,7 +616,7 @@ GrTexture* GrClipMaskManager::CreateAlphaClipMask(GrContext* context,
|
|||||||
paint.setAntiAlias(element->isAA());
|
paint.setAntiAlias(element->isAA());
|
||||||
paint.setCoverageSetOpXPFactory(op, false);
|
paint.setCoverageSetOpXPFactory(op, false);
|
||||||
|
|
||||||
draw_element(dc.get(), GrClip::WideOpen(), paint, translate, element);
|
draw_element(dc.get(), GrNoClip(), paint, translate, element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -681,7 +652,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
|||||||
// We set the current clip to the bounds so that our recursive draws are scissored to them.
|
// We set the current clip to the bounds so that our recursive draws are scissored to them.
|
||||||
SkIRect stencilSpaceIBounds(clipSpaceIBounds);
|
SkIRect stencilSpaceIBounds(clipSpaceIBounds);
|
||||||
stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
|
stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
|
||||||
GrClip clip(stencilSpaceIBounds);
|
GrFixedClip clip(stencilSpaceIBounds);
|
||||||
|
|
||||||
fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
|
fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
|
||||||
GrReducedClip::kAllIn_InitialState == initialState, rt);
|
GrReducedClip::kAllIn_InitialState == initialState, rt);
|
||||||
@ -703,7 +674,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
|||||||
|
|
||||||
bool fillInverted = false;
|
bool fillInverted = false;
|
||||||
// enabled at bottom of loop
|
// enabled at bottom of loop
|
||||||
fClipMode = kIgnoreClip_StencilClipMode;
|
clip.enableStencilClip(false);
|
||||||
|
|
||||||
// This will be used to determine whether the clip shape can be rendered into the
|
// This will be used to determine whether the clip shape can be rendered into the
|
||||||
// stencil with arbitrary stencil settings.
|
// stencil with arbitrary stencil settings.
|
||||||
@ -801,7 +772,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
|||||||
|
|
||||||
// now we modify the clip bit by rendering either the clip
|
// now we modify the clip bit by rendering either the clip
|
||||||
// element directly or a bounding rect of the entire clip.
|
// element directly or a bounding rect of the entire clip.
|
||||||
fClipMode = kModifyClip_StencilClipMode;
|
clip.enableStencilClip(true);
|
||||||
for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
|
for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
|
||||||
pipelineBuilder.setUserStencil(*pass);
|
pipelineBuilder.setUserStencil(*pass);
|
||||||
|
|
||||||
@ -832,7 +803,6 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fClipMode = kRespectClip_StencilClipMode;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
#include "SkTLList.h"
|
#include "SkTLList.h"
|
||||||
#include "SkTypes.h"
|
#include "SkTypes.h"
|
||||||
|
|
||||||
class GrClip;
|
class GrAppliedClip;
|
||||||
|
class GrClipStackClip;
|
||||||
class GrDrawTarget;
|
class GrDrawTarget;
|
||||||
class GrPathRenderer;
|
class GrPathRenderer;
|
||||||
class GrPathRendererChain;
|
class GrPathRendererChain;
|
||||||
@ -25,28 +26,6 @@ class GrResourceProvider;
|
|||||||
class GrTexture;
|
class GrTexture;
|
||||||
class SkPath;
|
class SkPath;
|
||||||
|
|
||||||
/**
|
|
||||||
* Produced by GrClipMaskManager. It provides a set of modifications to the drawing state that
|
|
||||||
* are used to create the final GrPipeline for a GrBatch. This is a work in progress. It will
|
|
||||||
* eventually encapsulate all mechanisms for modifying the scissor, shaders, and stencil state
|
|
||||||
* to implement clipping.
|
|
||||||
*/
|
|
||||||
class GrAppliedClip : public SkNoncopyable {
|
|
||||||
public:
|
|
||||||
GrAppliedClip() : fHasStencilClip(false) {}
|
|
||||||
const GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP; }
|
|
||||||
const GrScissorState& scissorState() const { return fScissorState; }
|
|
||||||
bool hasStencilClip() const { return fHasStencilClip; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
SkAutoTUnref<const GrFragmentProcessor> fClipCoverageFP;
|
|
||||||
GrScissorState fScissorState;
|
|
||||||
bool fHasStencilClip;
|
|
||||||
friend class GrClipMaskManager;
|
|
||||||
|
|
||||||
typedef SkNoncopyable INHERITED;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The clip mask creator handles the generation of the clip mask. If anti
|
* The clip mask creator handles the generation of the clip mask. If anti
|
||||||
* aliasing is requested it will (in the future) generate a single channel
|
* aliasing is requested it will (in the future) generate a single channel
|
||||||
@ -57,7 +36,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
class GrClipMaskManager : SkNoncopyable {
|
class GrClipMaskManager : SkNoncopyable {
|
||||||
public:
|
public:
|
||||||
GrClipMaskManager(GrDrawTarget* owner);
|
GrClipMaskManager(GrDrawTarget* owner) : fDrawTarget(owner) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a clip mask if necessary as a stencil buffer or alpha texture
|
* Creates a clip mask if necessary as a stencil buffer or alpha texture
|
||||||
@ -65,7 +44,7 @@ public:
|
|||||||
* then the draw can be skipped. devBounds is optional but can help optimize
|
* then the draw can be skipped. devBounds is optional but can help optimize
|
||||||
* clipping.
|
* clipping.
|
||||||
*/
|
*/
|
||||||
bool setupClipping(const GrPipelineBuilder&, const GrClip&, const SkRect* devBounds,
|
bool setupClipping(const GrPipelineBuilder&, const GrClipStackClip&, const SkRect* devBounds,
|
||||||
GrAppliedClip*);
|
GrAppliedClip*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -85,20 +64,6 @@ private:
|
|||||||
const SkMatrix& viewMatrix,
|
const SkMatrix& viewMatrix,
|
||||||
const SkClipStack::Element* element);
|
const SkClipStack::Element* element);
|
||||||
|
|
||||||
/**
|
|
||||||
* Informs the helper function adjustStencilParams() about how the stencil
|
|
||||||
* buffer clip is being used.
|
|
||||||
*/
|
|
||||||
enum StencilClipMode {
|
|
||||||
// Draw to the clip bit of the stencil buffer
|
|
||||||
kModifyClip_StencilClipMode,
|
|
||||||
// Clip against the existing representation of the clip in the high bit
|
|
||||||
// of the stencil buffer.
|
|
||||||
kRespectClip_StencilClipMode,
|
|
||||||
// Neither writing to nor clipping against the clip bit.
|
|
||||||
kIgnoreClip_StencilClipMode,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Attempts to install a series of coverage effects to implement the clip. Return indicates
|
// Attempts to install a series of coverage effects to implement the clip. Return indicates
|
||||||
// whether the element list was successfully converted to processors. *fp may be nullptr even
|
// whether the element list was successfully converted to processors. *fp may be nullptr even
|
||||||
// when the function succeeds because all the elements were ignored. TODO: Make clip reduction
|
// when the function succeeds because all the elements were ignored. TODO: Make clip reduction
|
||||||
@ -146,7 +111,6 @@ private:
|
|||||||
static const int kMaxAnalyticElements = 4;
|
static const int kMaxAnalyticElements = 4;
|
||||||
|
|
||||||
GrDrawTarget* fDrawTarget; // This is our owning draw target.
|
GrDrawTarget* fDrawTarget; // This is our owning draw target.
|
||||||
StencilClipMode fClipMode;
|
|
||||||
|
|
||||||
typedef SkNoncopyable INHERITED;
|
typedef SkNoncopyable INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -373,7 +373,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
|
|||||||
paint.addColorFragmentProcessor(fp);
|
paint.addColorFragmentProcessor(fp);
|
||||||
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
||||||
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
|
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
|
||||||
drawContext->drawRect(GrClip::WideOpen(), paint, matrix, rect, nullptr);
|
drawContext->drawRect(GrNoClip(), paint, matrix, rect, nullptr);
|
||||||
|
|
||||||
if (kFlushWrites_PixelOp & pixelOpsFlags) {
|
if (kFlushWrites_PixelOp & pixelOpsFlags) {
|
||||||
this->flushSurfaceWrites(surface);
|
this->flushSurfaceWrites(surface);
|
||||||
@ -487,7 +487,7 @@ bool GrContext::readSurfacePixels(GrSurface* src,
|
|||||||
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
|
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
|
||||||
sk_sp<GrDrawContext> drawContext(
|
sk_sp<GrDrawContext> drawContext(
|
||||||
this->drawContext(sk_ref_sp(temp->asRenderTarget())));
|
this->drawContext(sk_ref_sp(temp->asRenderTarget())));
|
||||||
drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), rect, nullptr);
|
drawContext->drawRect(GrNoClip(), paint, SkMatrix::I(), rect, nullptr);
|
||||||
surfaceToRead.reset(SkRef(temp.get()));
|
surfaceToRead.reset(SkRef(temp.get()));
|
||||||
left = 0;
|
left = 0;
|
||||||
top = 0;
|
top = 0;
|
||||||
@ -559,7 +559,7 @@ bool GrContext::applyGamma(GrRenderTarget* dst, GrTexture* src, SkScalar gamma){
|
|||||||
|
|
||||||
SkRect rect;
|
SkRect rect;
|
||||||
src->getBoundsRect(&rect);
|
src->getBoundsRect(&rect);
|
||||||
drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), rect);
|
drawContext->drawRect(GrNoClip(), paint, SkMatrix::I(), rect);
|
||||||
|
|
||||||
this->flushSurfaceWrites(dst);
|
this->flushSurfaceWrites(dst);
|
||||||
return true;
|
return true;
|
||||||
|
@ -301,14 +301,8 @@ void GrDrawContext::drawRect(const GrClip& clip,
|
|||||||
if (width < 0) {
|
if (width < 0) {
|
||||||
SkRect rtRect;
|
SkRect rtRect;
|
||||||
fRenderTarget->getBoundsRect(&rtRect);
|
fRenderTarget->getBoundsRect(&rtRect);
|
||||||
SkRect clipSpaceRTRect = rtRect;
|
|
||||||
bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType();
|
|
||||||
if (checkClip) {
|
|
||||||
clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX),
|
|
||||||
SkIntToScalar(clip.origin().fY));
|
|
||||||
}
|
|
||||||
// Does the clip contain the entire RT?
|
// Does the clip contain the entire RT?
|
||||||
if (!checkClip || clip.quickContains(clipSpaceRTRect)) {
|
if (clip.quickContains(rtRect)) {
|
||||||
SkMatrix invM;
|
SkMatrix invM;
|
||||||
if (!viewMatrix.invert(&invM)) {
|
if (!viewMatrix.invert(&invM)) {
|
||||||
return;
|
return;
|
||||||
@ -374,7 +368,7 @@ void GrDrawContext::drawRect(const GrClip& clip,
|
|||||||
this->internalDrawPath(clip, paint, viewMatrix, path, *style);
|
this->internalDrawPath(clip, paint, viewMatrix, path, *style);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrDrawContextPriv::drawAndStencilRect(const GrClip& clip,
|
bool GrDrawContextPriv::drawAndStencilRect(const GrFixedClip& clip,
|
||||||
const GrUserStencilSettings* ss,
|
const GrUserStencilSettings* ss,
|
||||||
SkRegion::Op op,
|
SkRegion::Op op,
|
||||||
bool invert,
|
bool invert,
|
||||||
@ -839,7 +833,7 @@ void GrDrawContext::drawPath(const GrClip& clip,
|
|||||||
this->internalDrawPath(clip, paint, viewMatrix, path, style);
|
this->internalDrawPath(clip, paint, viewMatrix, path, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrDrawContextPriv::drawAndStencilPath(const GrClip& clip,
|
bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
|
||||||
const GrUserStencilSettings* ss,
|
const GrUserStencilSettings* ss,
|
||||||
SkRegion::Op op,
|
SkRegion::Op op,
|
||||||
bool invert,
|
bool invert,
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "GrDrawContext.h"
|
#include "GrDrawContext.h"
|
||||||
|
|
||||||
|
class GrFixedClip;
|
||||||
struct GrUserStencilSettings;
|
struct GrUserStencilSettings;
|
||||||
|
|
||||||
/** Class that adds methods to GrDrawContext that are only intended for use internal to Skia.
|
/** Class that adds methods to GrDrawContext that are only intended for use internal to Skia.
|
||||||
@ -17,7 +18,7 @@ struct GrUserStencilSettings;
|
|||||||
data members or virtual methods. */
|
data members or virtual methods. */
|
||||||
class GrDrawContextPriv {
|
class GrDrawContextPriv {
|
||||||
public:
|
public:
|
||||||
bool drawAndStencilRect(const GrClip&,
|
bool drawAndStencilRect(const GrFixedClip&,
|
||||||
const GrUserStencilSettings*,
|
const GrUserStencilSettings*,
|
||||||
SkRegion::Op op,
|
SkRegion::Op op,
|
||||||
bool invert,
|
bool invert,
|
||||||
@ -25,7 +26,7 @@ public:
|
|||||||
const SkMatrix& viewMatrix,
|
const SkMatrix& viewMatrix,
|
||||||
const SkRect&);
|
const SkRect&);
|
||||||
|
|
||||||
bool drawAndStencilPath(const GrClip&,
|
bool drawAndStencilPath(const GrFixedClip&,
|
||||||
const GrUserStencilSettings*,
|
const GrUserStencilSettings*,
|
||||||
SkRegion::Op op,
|
SkRegion::Op op,
|
||||||
bool invert,
|
bool invert,
|
||||||
|
@ -239,7 +239,7 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
|
|||||||
GrDrawBatch* batch) {
|
GrDrawBatch* batch) {
|
||||||
// Setup clip
|
// Setup clip
|
||||||
GrAppliedClip appliedClip;
|
GrAppliedClip appliedClip;
|
||||||
if (!fClipMaskManager->setupClipping(pipelineBuilder, clip, &batch->bounds(), &appliedClip)) {
|
if (!clip.apply(fClipMaskManager, pipelineBuilder, &batch->bounds(), &appliedClip)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,16 +317,14 @@ void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
|
|||||||
|
|
||||||
// Setup clip
|
// Setup clip
|
||||||
GrAppliedClip appliedClip;
|
GrAppliedClip appliedClip;
|
||||||
if (!fClipMaskManager->setupClipping(pipelineBuilder, clip, nullptr, &appliedClip)) {
|
if (!clip.apply(fClipMaskManager, pipelineBuilder, nullptr, &appliedClip)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: respect fClipBatchToBounds if we ever start computing bounds here.
|
// TODO: respect fClipBatchToBounds if we ever start computing bounds here.
|
||||||
|
|
||||||
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
|
// Coverage AA does not make sense when rendering to the stencil buffer. The caller should never
|
||||||
if (appliedClip.clipCoverageFragmentProcessor()) {
|
// attempt this in a situation that would require coverage AA.
|
||||||
arfps.set(&pipelineBuilder);
|
SkASSERT(!appliedClip.clipCoverageFragmentProcessor());
|
||||||
arfps.addCoverageFragmentProcessor(appliedClip.clipCoverageFragmentProcessor());
|
|
||||||
}
|
|
||||||
|
|
||||||
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
|
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
|
||||||
GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAttachment(rt);
|
GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAttachment(rt);
|
||||||
@ -378,7 +376,7 @@ void GrDrawTarget::clear(const SkIRect* rect,
|
|||||||
SkAutoTUnref<GrDrawBatch> batch(
|
SkAutoTUnref<GrDrawBatch> batch(
|
||||||
GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), scalarRect,
|
GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), scalarRect,
|
||||||
nullptr, nullptr));
|
nullptr, nullptr));
|
||||||
this->drawBatch(pipelineBuilder, GrClip::WideOpen(), batch);
|
this->drawBatch(pipelineBuilder, GrNoClip(), batch);
|
||||||
} else {
|
} else {
|
||||||
GrBatch* batch = new GrClearBatch(*rect, color, renderTarget);
|
GrBatch* batch = new GrClearBatch(*rect, color, renderTarget);
|
||||||
this->recordBatch(batch);
|
this->recordBatch(batch);
|
||||||
|
@ -119,7 +119,7 @@ static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkRect dstRect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
|
SkRect dstRect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
|
||||||
drawContext->fillRectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), dstRect, localRect);
|
drawContext->fillRectToRect(GrNoClip(), paint, SkMatrix::I(), dstRect, localRect);
|
||||||
return copy.release();
|
return copy.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ static bool convert_texture(GrTexture* src, GrDrawContext* dst, int dstW, int ds
|
|||||||
GrPaint paint;
|
GrPaint paint;
|
||||||
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
||||||
paint.addColorFragmentProcessor(fp);
|
paint.addColorFragmentProcessor(fp);
|
||||||
dst->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), SkRect::MakeIWH(dstW, dstH));
|
dst->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::MakeIWH(dstW, dstH));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx,
|
|||||||
const SkRect r = SkRect::MakeIWH(yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth,
|
const SkRect r = SkRect::MakeIWH(yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth,
|
||||||
yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
|
yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
|
||||||
|
|
||||||
drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), r);
|
drawContext->drawRect(GrNoClip(), paint, SkMatrix::I(), r);
|
||||||
|
|
||||||
return drawContext->asTexture();
|
return drawContext->asTexture();
|
||||||
}
|
}
|
||||||
|
@ -341,7 +341,7 @@ void SkGpuDevice::prepareDraw(const SkDraw& draw) {
|
|||||||
|
|
||||||
SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack);
|
SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack);
|
||||||
|
|
||||||
fClip.setClipStack(fClipStack, &this->getOrigin());
|
fClip.reset(fClipStack, &this->getOrigin());
|
||||||
}
|
}
|
||||||
|
|
||||||
GrRenderTarget* SkGpuDevice::accessRenderTarget() {
|
GrRenderTarget* SkGpuDevice::accessRenderTarget() {
|
||||||
|
@ -153,7 +153,7 @@ private:
|
|||||||
|
|
||||||
SkAutoTUnref<const SkClipStack> fClipStack;
|
SkAutoTUnref<const SkClipStack> fClipStack;
|
||||||
SkIPoint fClipOrigin;
|
SkIPoint fClipOrigin;
|
||||||
GrClip fClip;;
|
GrClipStackClip fClip;
|
||||||
// remove when our clients don't rely on accessBitmap()
|
// remove when our clients don't rely on accessBitmap()
|
||||||
SkBitmap fLegacyBitmap;
|
SkBitmap fLegacyBitmap;
|
||||||
bool fOpaque;
|
bool fOpaque;
|
||||||
|
@ -232,7 +232,7 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
readDrawContext->fillRectToRect(GrClip::WideOpen(),
|
readDrawContext->fillRectToRect(GrNoClip(),
|
||||||
paint1,
|
paint1,
|
||||||
SkMatrix::I(),
|
SkMatrix::I(),
|
||||||
kDstRect,
|
kDstRect,
|
||||||
@ -249,7 +249,7 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
|
|||||||
failed = true;
|
failed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tempDrawContext->fillRectToRect(GrClip::WideOpen(),
|
tempDrawContext->fillRectToRect(GrNoClip(),
|
||||||
paint2,
|
paint2,
|
||||||
SkMatrix::I(),
|
SkMatrix::I(),
|
||||||
kDstRect,
|
kDstRect,
|
||||||
@ -264,7 +264,7 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
readDrawContext->fillRectToRect(GrClip::WideOpen(),
|
readDrawContext->fillRectToRect(GrNoClip(),
|
||||||
paint3,
|
paint3,
|
||||||
SkMatrix::I(),
|
SkMatrix::I(),
|
||||||
kDstRect,
|
kDstRect,
|
||||||
|
@ -269,7 +269,7 @@ sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace
|
|||||||
|
|
||||||
const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
|
const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
|
||||||
|
|
||||||
drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), rect);
|
drawContext->drawRect(GrNoClip(), paint, SkMatrix::I(), rect);
|
||||||
ctx->flushSurfaceWrites(drawContext->accessRenderTarget());
|
ctx->flushSurfaceWrites(drawContext->accessRenderTarget());
|
||||||
return sk_make_sp<SkImage_Gpu>(width, height, kNeedNewImageUniqueID,
|
return sk_make_sp<SkImage_Gpu>(width, height, kNeedNewImageUniqueID,
|
||||||
kOpaque_SkAlphaType,
|
kOpaque_SkAlphaType,
|
||||||
|
@ -40,8 +40,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrClipBounds, reporter, ctxInfo) {
|
|||||||
REPORTER_ASSERT(reporter, isIntersectionOfRects);
|
REPORTER_ASSERT(reporter, isIntersectionOfRects);
|
||||||
|
|
||||||
// wrap the SkClipStack in a GrClip
|
// wrap the SkClipStack in a GrClip
|
||||||
GrClip clipData;
|
GrClipStackClip clipData(&stack);
|
||||||
clipData.setClipStack(&stack);
|
|
||||||
|
|
||||||
SkIRect devGrClipBound;
|
SkIRect devGrClipBound;
|
||||||
clipData.getConservativeBounds(kXSize, kYSize,
|
clipData.getConservativeBounds(kXSize, kYSize,
|
||||||
|
@ -239,11 +239,12 @@ static void test_path(GrDrawTarget* dt, GrRenderTarget* rt, GrResourceProvider*
|
|||||||
pipelineBuilder.setXPFactory(
|
pipelineBuilder.setXPFactory(
|
||||||
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
|
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
|
||||||
pipelineBuilder.setRenderTarget(rt);
|
pipelineBuilder.setRenderTarget(rt);
|
||||||
|
GrNoClip noClip;
|
||||||
GrStyle style(SkStrokeRec::kFill_InitStyle);
|
GrStyle style(SkStrokeRec::kFill_InitStyle);
|
||||||
GrPathRenderer::DrawPathArgs args;
|
GrPathRenderer::DrawPathArgs args;
|
||||||
args.fTarget = dt;
|
args.fTarget = dt;
|
||||||
args.fPipelineBuilder = &pipelineBuilder;
|
args.fPipelineBuilder = &pipelineBuilder;
|
||||||
args.fClip = &GrClip::WideOpen();
|
args.fClip = &noClip;
|
||||||
args.fResourceProvider = rp;
|
args.fResourceProvider = rp;
|
||||||
args.fColor = GrColor_WHITE;
|
args.fColor = GrColor_WHITE;
|
||||||
args.fViewMatrix = &SkMatrix::I();
|
args.fViewMatrix = &SkMatrix::I();
|
||||||
|
@ -168,8 +168,7 @@ void SkGpuDevice::drawTexture(GrTexture* tex, const SkRect& dst, const SkPaint&
|
|||||||
|
|
||||||
grPaint.addColorTextureProcessor(tex, textureMat);
|
grPaint.addColorTextureProcessor(tex, textureMat);
|
||||||
|
|
||||||
GrClip clip;
|
fDrawContext->drawRect(GrNoClip(), grPaint, mat, dst);
|
||||||
fDrawContext->drawRect(clip, grPaint, mat, dst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -260,8 +259,11 @@ void GrDrawContextPriv::testingOnly_drawBatch(const GrPipelineBuilder& pipelineB
|
|||||||
SkDEBUGCODE(fDrawContext->validate();)
|
SkDEBUGCODE(fDrawContext->validate();)
|
||||||
GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::testingOnly_drawBatch");
|
GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::testingOnly_drawBatch");
|
||||||
|
|
||||||
const GrClip& drawClip = clip ? *clip : GrClip::WideOpen();
|
if (clip) {
|
||||||
fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, drawClip, batch);
|
fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, *clip, batch);
|
||||||
|
} else {
|
||||||
|
fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, GrNoClip(), batch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ASSERT_SINGLE_OWNER
|
#undef ASSERT_SINGLE_OWNER
|
||||||
|
Loading…
Reference in New Issue
Block a user