Beginning to refactor nvpr code
BUG=skia: Review URL: https://codereview.chromium.org/687563008
This commit is contained in:
parent
2faa228435
commit
92e496f96a
@ -47,3 +47,16 @@ dropshadowimagefilter
|
||||
# senorblanco https://codereview.chromium.org/637283009/
|
||||
# quality improvements to imagemagnifier GM
|
||||
imagemagnifier
|
||||
|
||||
#joshualitt rebase tonight
|
||||
rrect_clip_bw
|
||||
multipicturedraw_rrectclip_tiled
|
||||
multipicturedraw_rrectclip_simple
|
||||
filltypespersp
|
||||
convex_poly_clip
|
||||
complexclip2_path_bw
|
||||
complexclip2_rrect_bw
|
||||
complexclip_bw_layer
|
||||
complexclip_bw
|
||||
circular-clips
|
||||
|
||||
|
@ -527,28 +527,20 @@ void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
|
||||
}
|
||||
}
|
||||
|
||||
void GrDrawTarget::stencilPath(const GrPath* path, SkPath::FillType fill) {
|
||||
void GrDrawTarget::stencilPath(const GrPath* path, GrPathRendering::FillType fill) {
|
||||
// TODO: extract portions of checkDraw that are relevant to path stenciling.
|
||||
SkASSERT(path);
|
||||
SkASSERT(this->caps()->pathRenderingSupport());
|
||||
SkASSERT(!SkPath::IsInverseFillType(fill));
|
||||
this->onStencilPath(path, fill);
|
||||
}
|
||||
|
||||
void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) {
|
||||
void GrDrawTarget::drawPath(const GrPath* path, GrPathRendering::FillType fill) {
|
||||
// TODO: extract portions of checkDraw that are relevant to path rendering.
|
||||
SkASSERT(path);
|
||||
SkASSERT(this->caps()->pathRenderingSupport());
|
||||
const GrDrawState* drawState = &getDrawState();
|
||||
|
||||
SkRect devBounds;
|
||||
if (SkPath::IsInverseFillType(fill)) {
|
||||
devBounds = SkRect::MakeWH(SkIntToScalar(drawState->getRenderTarget()->width()),
|
||||
SkIntToScalar(drawState->getRenderTarget()->height()));
|
||||
} else {
|
||||
devBounds = path->getBounds();
|
||||
}
|
||||
SkMatrix viewM = drawState->getViewMatrix();
|
||||
SkRect devBounds = path->getBounds();
|
||||
SkMatrix viewM = this->drawState()->getViewMatrix();
|
||||
viewM.mapRect(&devBounds);
|
||||
|
||||
GrDeviceCoordTexture dstCopy;
|
||||
@ -562,7 +554,7 @@ void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) {
|
||||
void GrDrawTarget::drawPaths(const GrPathRange* pathRange,
|
||||
const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType transformsType,
|
||||
SkPath::FillType fill) {
|
||||
GrPathRendering::FillType fill) {
|
||||
SkASSERT(this->caps()->pathRenderingSupport());
|
||||
SkASSERT(pathRange);
|
||||
SkASSERT(indices);
|
||||
@ -724,43 +716,6 @@ void GrDrawTarget::onDrawRect(const SkRect& rect,
|
||||
void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
|
||||
}
|
||||
|
||||
static const GrStencilSettings& winding_path_stencil_settings() {
|
||||
GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
|
||||
kIncClamp_StencilOp,
|
||||
kIncClamp_StencilOp,
|
||||
kAlwaysIfInClip_StencilFunc,
|
||||
0xFFFF, 0xFFFF, 0xFFFF);
|
||||
return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
|
||||
}
|
||||
|
||||
static const GrStencilSettings& even_odd_path_stencil_settings() {
|
||||
GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
|
||||
kInvert_StencilOp,
|
||||
kInvert_StencilOp,
|
||||
kAlwaysIfInClip_StencilFunc,
|
||||
0xFFFF, 0xFFFF, 0xFFFF);
|
||||
return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
|
||||
}
|
||||
|
||||
void GrDrawTarget::getPathStencilSettingsForFillType(SkPath::FillType fill,
|
||||
GrStencilSettings* outStencilSettings) {
|
||||
|
||||
switch (fill) {
|
||||
default:
|
||||
SkFAIL("Unexpected path fill.");
|
||||
/* fallthrough */;
|
||||
case SkPath::kWinding_FillType:
|
||||
case SkPath::kInverseWinding_FillType:
|
||||
*outStencilSettings = winding_path_stencil_settings();
|
||||
break;
|
||||
case SkPath::kEvenOdd_FillType:
|
||||
case SkPath::kInverseEvenOdd_FillType:
|
||||
*outStencilSettings = even_odd_path_stencil_settings();
|
||||
break;
|
||||
}
|
||||
this->getClipMaskManager()->adjustPathStencilParams(outStencilSettings);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrDrawTarget::AutoStateRestore::AutoStateRestore() {
|
||||
|
@ -315,15 +315,16 @@ public:
|
||||
/**
|
||||
* Draws path into the stencil buffer. The fill must be either even/odd or
|
||||
* winding (not inverse or hairline). It will respect the HW antialias flag
|
||||
* on the draw state (if possible in the 3D API).
|
||||
* on the draw state (if possible in the 3D API). Note, we will never have an inverse fill
|
||||
* with stencil path
|
||||
*/
|
||||
void stencilPath(const GrPath*, SkPath::FillType fill);
|
||||
void stencilPath(const GrPath*, GrPathRendering::FillType fill);
|
||||
|
||||
/**
|
||||
* Draws a path. Fill must not be a hairline. It will respect the HW
|
||||
* antialias flag on the draw state (if possible in the 3D API).
|
||||
*/
|
||||
void drawPath(const GrPath*, SkPath::FillType fill);
|
||||
void drawPath(const GrPath*, GrPathRendering::FillType fill);
|
||||
|
||||
/**
|
||||
* Draws many paths. It will respect the HW
|
||||
@ -340,7 +341,7 @@ public:
|
||||
void drawPaths(const GrPathRange* pathRange,
|
||||
const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType transformsType,
|
||||
SkPath::FillType fill);
|
||||
GrPathRendering::FillType fill);
|
||||
|
||||
/**
|
||||
* Helper function for drawing rects. It performs a geometry src push and pop
|
||||
@ -490,7 +491,7 @@ public:
|
||||
/**
|
||||
* For subclass internal use to invoke a call to onDrawPath().
|
||||
*/
|
||||
void executeDrawPath(const GrPath* path, SkPath::FillType fill,
|
||||
void executeDrawPath(const GrPath* path, GrPathRendering::FillType fill,
|
||||
const GrDeviceCoordTexture* dstCopy) {
|
||||
this->onDrawPath(path, fill, dstCopy);
|
||||
}
|
||||
@ -501,13 +502,11 @@ public:
|
||||
void executeDrawPaths(const GrPathRange* pathRange,
|
||||
const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType transformsType,
|
||||
SkPath::FillType fill,
|
||||
GrPathRendering::FillType fill,
|
||||
const GrDeviceCoordTexture* dstCopy) {
|
||||
this->onDrawPaths(pathRange, indices, count, transforms, transformsType, fill, dstCopy);
|
||||
}
|
||||
|
||||
void getPathStencilSettingsForFillType(SkPath::FillType, GrStencilSettings*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@ -898,13 +897,13 @@ private:
|
||||
const SkRect* localRect,
|
||||
const SkMatrix* localMatrix);
|
||||
|
||||
virtual void onStencilPath(const GrPath*, SkPath::FillType) = 0;
|
||||
virtual void onDrawPath(const GrPath*, SkPath::FillType,
|
||||
virtual void onStencilPath(const GrPath*, GrPathRendering::FillType) = 0;
|
||||
virtual void onDrawPath(const GrPath*, GrPathRendering::FillType,
|
||||
const GrDeviceCoordTexture* dstCopy) = 0;
|
||||
virtual void onDrawPaths(const GrPathRange*,
|
||||
const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType,
|
||||
SkPath::FillType, const GrDeviceCoordTexture*) = 0;
|
||||
GrPathRendering::FillType, const GrDeviceCoordTexture*) = 0;
|
||||
|
||||
virtual void didAddGpuTraceMarker() = 0;
|
||||
virtual void didRemoveGpuTraceMarker() = 0;
|
||||
|
@ -275,13 +275,13 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
|
||||
bool GrGpu::setupClipAndFlushState(DrawType type,
|
||||
const GrDeviceCoordTexture* dstCopy,
|
||||
const SkRect* devBounds,
|
||||
GrDrawState::AutoRestoreEffects* are) {
|
||||
GrDrawState::AutoRestoreEffects* are,
|
||||
GrDrawState::AutoRestoreStencil* ars) {
|
||||
GrClipMaskManager::ScissorState scissorState;
|
||||
GrDrawState::AutoRestoreStencil ars;
|
||||
if (!fClipMaskManager.setupClipping(this->getClip(),
|
||||
devBounds,
|
||||
are,
|
||||
&ars,
|
||||
ars,
|
||||
&scissorState)) {
|
||||
return false;
|
||||
}
|
||||
@ -325,56 +325,109 @@ void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) {
|
||||
void GrGpu::onDraw(const DrawInfo& info) {
|
||||
this->handleDirtyContext();
|
||||
GrDrawState::AutoRestoreEffects are;
|
||||
GrDrawState::AutoRestoreStencil ars;
|
||||
if (!this->setupClipAndFlushState(PrimTypeToDrawType(info.primitiveType()),
|
||||
info.getDstCopy(),
|
||||
info.getDevBounds(),
|
||||
&are)) {
|
||||
&are,
|
||||
&ars)) {
|
||||
return;
|
||||
}
|
||||
this->onGpuDraw(info);
|
||||
}
|
||||
|
||||
void GrGpu::onStencilPath(const GrPath* path, SkPath::FillType fill) {
|
||||
|
||||
// TODO hack
|
||||
static const GrStencilSettings& winding_path_stencil_settings() {
|
||||
GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
|
||||
kIncClamp_StencilOp,
|
||||
kIncClamp_StencilOp,
|
||||
kAlwaysIfInClip_StencilFunc,
|
||||
0xFFFF, 0xFFFF, 0xFFFF);
|
||||
return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
|
||||
}
|
||||
|
||||
static const GrStencilSettings& even_odd_path_stencil_settings() {
|
||||
GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
|
||||
kInvert_StencilOp,
|
||||
kInvert_StencilOp,
|
||||
kAlwaysIfInClip_StencilFunc,
|
||||
0xFFFF, 0xFFFF, 0xFFFF);
|
||||
return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
|
||||
}
|
||||
|
||||
static void get_path_stencil_settings_for_filltype(GrPathRendering::FillType fill,
|
||||
GrStencilSettings* outStencilSettings) {
|
||||
|
||||
switch (fill) {
|
||||
default:
|
||||
SkFAIL("Unexpected path fill.");
|
||||
case GrPathRendering::kWinding_FillType:
|
||||
*outStencilSettings = winding_path_stencil_settings();
|
||||
break;
|
||||
case GrPathRendering::kEvenOdd_FillType:
|
||||
*outStencilSettings = even_odd_path_stencil_settings();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpu::onStencilPath(const GrPath* path, GrPathRendering::FillType fill) {
|
||||
this->handleDirtyContext();
|
||||
|
||||
GrDrawState::AutoRestoreEffects are;
|
||||
if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, NULL, &are)) {
|
||||
GrDrawState::AutoRestoreStencil ars;
|
||||
if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, NULL, &are, &ars)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->pathRendering()->stencilPath(path, fill);
|
||||
GrStencilSettings stencilSettings;
|
||||
get_path_stencil_settings_for_filltype(fill, &stencilSettings);
|
||||
fClipMaskManager.adjustPathStencilParams(&stencilSettings);
|
||||
|
||||
this->pathRendering()->stencilPath(path, stencilSettings);
|
||||
}
|
||||
|
||||
|
||||
void GrGpu::onDrawPath(const GrPath* path, SkPath::FillType fill,
|
||||
void GrGpu::onDrawPath(const GrPath* path, GrPathRendering::FillType fill,
|
||||
const GrDeviceCoordTexture* dstCopy) {
|
||||
this->handleDirtyContext();
|
||||
|
||||
drawState()->setDefaultVertexAttribs();
|
||||
|
||||
GrDrawState::AutoRestoreEffects are;
|
||||
if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, NULL, &are)) {
|
||||
GrDrawState::AutoRestoreStencil ars;
|
||||
if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, NULL, &are, &ars)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->pathRendering()->drawPath(path, fill);
|
||||
GrStencilSettings stencilSettings;
|
||||
get_path_stencil_settings_for_filltype(fill, &stencilSettings);
|
||||
fClipMaskManager.adjustPathStencilParams(&stencilSettings);
|
||||
|
||||
this->pathRendering()->drawPath(path, stencilSettings);
|
||||
}
|
||||
|
||||
void GrGpu::onDrawPaths(const GrPathRange* pathRange,
|
||||
const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType transformsType,
|
||||
SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) {
|
||||
GrPathRendering::FillType fill, const GrDeviceCoordTexture* dstCopy) {
|
||||
this->handleDirtyContext();
|
||||
|
||||
drawState()->setDefaultVertexAttribs();
|
||||
|
||||
GrDrawState::AutoRestoreEffects are;
|
||||
if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, NULL, &are)) {
|
||||
GrDrawState::AutoRestoreStencil ars;
|
||||
if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, NULL, &are, &ars)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrStencilSettings stencilSettings;
|
||||
get_path_stencil_settings_for_filltype(fill, &stencilSettings);
|
||||
fClipMaskManager.adjustPathStencilParams(&stencilSettings);
|
||||
|
||||
pathRange->willDrawPaths(indices, count);
|
||||
this->pathRendering()->drawPaths(pathRange, indices, count, transforms, transformsType, fill);
|
||||
this->pathRendering()->drawPaths(pathRange, indices, count, transforms, transformsType,
|
||||
stencilSettings);
|
||||
}
|
||||
|
||||
void GrGpu::finalizeReservedVertices() {
|
||||
|
@ -335,7 +335,8 @@ protected:
|
||||
bool setupClipAndFlushState(DrawType,
|
||||
const GrDeviceCoordTexture* dstCopy,
|
||||
const SkRect* devBounds,
|
||||
GrDrawState::AutoRestoreEffects*);
|
||||
GrDrawState::AutoRestoreEffects*,
|
||||
GrDrawState::AutoRestoreStencil*);
|
||||
|
||||
// Functions used to map clip-respecting stencil tests into normal
|
||||
// stencil funcs supported by GPUs.
|
||||
@ -452,13 +453,13 @@ private:
|
||||
|
||||
// GrDrawTarget overrides
|
||||
virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
|
||||
virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
|
||||
virtual void onDrawPath(const GrPath*, SkPath::FillType,
|
||||
virtual void onStencilPath(const GrPath*, GrPathRendering::FillType) SK_OVERRIDE;
|
||||
virtual void onDrawPath(const GrPath*, GrPathRendering::FillType,
|
||||
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
|
||||
virtual void onDrawPaths(const GrPathRange*,
|
||||
const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType,
|
||||
SkPath::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
|
||||
GrPathRendering::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
|
||||
|
||||
// readies the pools to provide vertex/index data.
|
||||
void prepareVertexPool();
|
||||
|
@ -361,7 +361,7 @@ void GrInOrderDrawBuffer::onDraw(const DrawInfo& info) {
|
||||
}
|
||||
}
|
||||
|
||||
void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fill) {
|
||||
void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathRendering::FillType fill) {
|
||||
this->recordClipIfNecessary();
|
||||
// Only compare the subset of GrDrawState relevant to path stenciling?
|
||||
this->recordStateIfNecessary();
|
||||
@ -371,7 +371,8 @@ void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil
|
||||
}
|
||||
|
||||
void GrInOrderDrawBuffer::onDrawPath(const GrPath* path,
|
||||
SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) {
|
||||
GrPathRendering::FillType fill,
|
||||
const GrDeviceCoordTexture* dstCopy) {
|
||||
this->recordClipIfNecessary();
|
||||
// TODO: Only compare the subset of GrDrawState relevant to path covering?
|
||||
this->recordStateIfNecessary();
|
||||
@ -386,7 +387,8 @@ void GrInOrderDrawBuffer::onDrawPath(const GrPath* path,
|
||||
void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange,
|
||||
const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType transformsType,
|
||||
SkPath::FillType fill, const GrDeviceCoordTexture* dstCopy) {
|
||||
GrPathRendering::FillType fill,
|
||||
const GrDeviceCoordTexture* dstCopy) {
|
||||
SkASSERT(pathRange);
|
||||
SkASSERT(indices);
|
||||
SkASSERT(transforms);
|
||||
|
@ -139,7 +139,7 @@ private:
|
||||
|
||||
virtual void execute(GrClipTarget*);
|
||||
|
||||
SkPath::FillType fFill;
|
||||
GrPathRendering::FillType fFill;
|
||||
|
||||
private:
|
||||
GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
|
||||
@ -152,8 +152,8 @@ private:
|
||||
|
||||
virtual void execute(GrClipTarget*);
|
||||
|
||||
SkPath::FillType fFill;
|
||||
GrDeviceCoordTexture fDstCopy;
|
||||
GrPathRendering::FillType fFill;
|
||||
GrDeviceCoordTexture fDstCopy;
|
||||
|
||||
private:
|
||||
GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
|
||||
@ -168,10 +168,10 @@ private:
|
||||
|
||||
virtual void execute(GrClipTarget*);
|
||||
|
||||
size_t fCount;
|
||||
PathTransformType fTransformsType;
|
||||
SkPath::FillType fFill;
|
||||
GrDeviceCoordTexture fDstCopy;
|
||||
size_t fCount;
|
||||
PathTransformType fTransformsType;
|
||||
GrPathRendering::FillType fFill;
|
||||
GrDeviceCoordTexture fDstCopy;
|
||||
|
||||
private:
|
||||
GrPendingIOResource<const GrPathRange, kRead_GrIOType> fPathRange;
|
||||
@ -257,13 +257,13 @@ private:
|
||||
const SkRect* localRect,
|
||||
const SkMatrix* localMatrix) SK_OVERRIDE;
|
||||
|
||||
virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
|
||||
virtual void onDrawPath(const GrPath*, SkPath::FillType,
|
||||
virtual void onStencilPath(const GrPath*, GrPathRendering::FillType) SK_OVERRIDE;
|
||||
virtual void onDrawPath(const GrPath*, GrPathRendering::FillType,
|
||||
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
|
||||
virtual void onDrawPaths(const GrPathRange*,
|
||||
const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType,
|
||||
SkPath::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
|
||||
GrPathRendering::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
|
||||
|
||||
virtual bool onReserveVertexSpace(size_t vertexSize,
|
||||
int vertexCount,
|
||||
|
@ -16,6 +16,7 @@ class SkDescriptor;
|
||||
class SkTypeface;
|
||||
class GrPath;
|
||||
class GrGpu;
|
||||
class GrStencilSettings;
|
||||
|
||||
/**
|
||||
* Abstract class wrapping HW path rendering API.
|
||||
@ -33,6 +34,18 @@ class GrPathRendering {
|
||||
public:
|
||||
virtual ~GrPathRendering() { }
|
||||
|
||||
// No native support for inverse at this time
|
||||
enum FillType {
|
||||
/** Specifies that "inside" is computed by a non-zero sum of signed
|
||||
edge crossings
|
||||
*/
|
||||
kWinding_FillType,
|
||||
/** Specifies that "inside" is computed by an odd number of edge
|
||||
crossings
|
||||
*/
|
||||
kEvenOdd_FillType,
|
||||
};
|
||||
|
||||
enum PathTransformType {
|
||||
kNone_PathTransformType, //!< []
|
||||
kTranslateX_PathTransformType, //!< [kMTransX]
|
||||
@ -111,10 +124,11 @@ public:
|
||||
*/
|
||||
virtual GrPathRange* createGlyphs(const SkTypeface*, const SkDescriptor*, const SkStrokeRec&) = 0;
|
||||
|
||||
virtual void stencilPath(const GrPath*, SkPath::FillType) = 0;
|
||||
virtual void drawPath(const GrPath*, SkPath::FillType) = 0;
|
||||
virtual void stencilPath(const GrPath*, const GrStencilSettings&) = 0;
|
||||
virtual void drawPath(const GrPath*, const GrStencilSettings&) = 0;
|
||||
virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType, SkPath::FillType) = 0;
|
||||
const float transforms[], PathTransformType,
|
||||
const GrStencilSettings&) = 0;
|
||||
protected:
|
||||
GrPathRendering() { }
|
||||
|
||||
|
@ -14,6 +14,22 @@
|
||||
#include "GrPath.h"
|
||||
#include "SkStrokeRec.h"
|
||||
|
||||
/*
|
||||
* For now paths only natively support winding and even odd fill types
|
||||
*/
|
||||
static GrPathRendering::FillType convert_skpath_filltype(SkPath::FillType fill) {
|
||||
switch (fill) {
|
||||
default:
|
||||
SkFAIL("Incomplete Switch\n");
|
||||
case SkPath::kWinding_FillType:
|
||||
case SkPath::kInverseWinding_FillType:
|
||||
return GrPathRendering::kWinding_FillType;
|
||||
case SkPath::kEvenOdd_FillType:
|
||||
case SkPath::kInverseEvenOdd_FillType:
|
||||
return GrPathRendering::kEvenOdd_FillType;
|
||||
}
|
||||
}
|
||||
|
||||
GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) {
|
||||
SkASSERT(context);
|
||||
SkASSERT(context->getGpu());
|
||||
@ -44,10 +60,10 @@ bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path,
|
||||
target->getDrawState().getStencil().isDisabled();
|
||||
}
|
||||
|
||||
GrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport(
|
||||
const SkPath&,
|
||||
const SkStrokeRec& ,
|
||||
const GrDrawTarget*) const {
|
||||
GrPathRenderer::StencilSupport
|
||||
GrStencilAndCoverPathRenderer::onGetStencilSupport(const SkPath&,
|
||||
const SkStrokeRec& ,
|
||||
const GrDrawTarget*) const {
|
||||
return GrPathRenderer::kStencilOnly_StencilSupport;
|
||||
}
|
||||
|
||||
@ -67,7 +83,7 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path,
|
||||
GrDrawTarget* target) {
|
||||
SkASSERT(!path.isInverseFillType());
|
||||
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
|
||||
target->stencilPath(p, path.getFillType());
|
||||
target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
|
||||
}
|
||||
|
||||
bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
|
||||
@ -94,7 +110,27 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
|
||||
0x0000,
|
||||
0xffff);
|
||||
|
||||
*drawState->stencil() = kInvertedStencilPass;
|
||||
drawState->setStencil(kInvertedStencilPass);
|
||||
|
||||
// fake inverse with a stencil and cover
|
||||
target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
|
||||
|
||||
GrDrawState::AutoViewMatrixRestore avmr;
|
||||
SkRect bounds = SkRect::MakeLTRB(0, 0,
|
||||
SkIntToScalar(drawState->getRenderTarget()->width()),
|
||||
SkIntToScalar(drawState->getRenderTarget()->height()));
|
||||
SkMatrix vmi;
|
||||
// mapRect through persp matrix may not be correct
|
||||
if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
|
||||
vmi.mapRect(&bounds);
|
||||
// theoretically could set bloat = 0, instead leave it because of matrix inversion
|
||||
// precision.
|
||||
SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
|
||||
bounds.outset(bloat, bloat);
|
||||
} else {
|
||||
avmr.setIdentity(drawState);
|
||||
}
|
||||
target->drawSimpleRect(bounds);
|
||||
} else {
|
||||
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
|
||||
kZero_StencilOp,
|
||||
@ -104,11 +140,10 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
|
||||
0x0000,
|
||||
0xffff);
|
||||
|
||||
*drawState->stencil() = kStencilPass;
|
||||
drawState->setStencil(kStencilPass);
|
||||
target->drawPath(p, convert_skpath_filltype(path.getFillType()));
|
||||
}
|
||||
|
||||
target->drawPath(p, path.getFillType());
|
||||
|
||||
target->drawState()->stencil()->setDisabled();
|
||||
return true;
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ void GrStencilAndCoverTextContext::flush() {
|
||||
}
|
||||
|
||||
fDrawTarget->drawPaths(fGlyphs, fIndexBuffer, fPendingGlyphCount,
|
||||
fTransformBuffer, fTransformType, SkPath::kWinding_FillType);
|
||||
fTransformBuffer, fTransformType, GrPathRendering::kWinding_FillType);
|
||||
|
||||
fPendingGlyphCount = 0;
|
||||
}
|
||||
|
@ -152,147 +152,88 @@ GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface,
|
||||
return SkNEW_ARGS(GrGLPathRange, (fGpu, basePathID, numPaths, gpuMemorySize, stroke));
|
||||
}
|
||||
|
||||
void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) {
|
||||
void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings& stencilSettings) {
|
||||
GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
|
||||
SkASSERT(fGpu->drawState()->getRenderTarget());
|
||||
SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
|
||||
|
||||
this->flushPathStencilSettings(fill);
|
||||
SkASSERT(!fHWPathStencilSettings.isTwoSided());
|
||||
|
||||
GrGLenum fillMode =
|
||||
gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
|
||||
GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
|
||||
GL_CALL(StencilFillPath(id, fillMode, writeMask));
|
||||
}
|
||||
|
||||
void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) {
|
||||
GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
|
||||
SkASSERT(fGpu->drawState()->getRenderTarget());
|
||||
SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
|
||||
|
||||
this->flushPathStencilSettings(fill);
|
||||
this->flushPathStencilSettings(stencilSettings);
|
||||
SkASSERT(!fHWPathStencilSettings.isTwoSided());
|
||||
|
||||
const SkStrokeRec& stroke = path->getStroke();
|
||||
|
||||
SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill);
|
||||
GrGLenum fillMode =
|
||||
gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
|
||||
GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
|
||||
|
||||
if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
|
||||
GL_CALL(StencilFillPath(id, fillMode, writeMask));
|
||||
}
|
||||
if (stroke.needToApply()) {
|
||||
GL_CALL(StencilStrokePath(id, 0xffff, writeMask));
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLPathRendering::drawPath(const GrPath* path, const GrStencilSettings& stencilSettings) {
|
||||
GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
|
||||
SkASSERT(fGpu->drawState()->getRenderTarget());
|
||||
SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
|
||||
|
||||
this->flushPathStencilSettings(stencilSettings);
|
||||
SkASSERT(!fHWPathStencilSettings.isTwoSided());
|
||||
|
||||
const SkStrokeRec& stroke = path->getStroke();
|
||||
|
||||
GrGLenum fillMode =
|
||||
gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
|
||||
GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
|
||||
|
||||
if (nonInvertedFill == fill) {
|
||||
if (stroke.needToApply()) {
|
||||
if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
|
||||
GL_CALL(StencilFillPath(id, fillMode, writeMask));
|
||||
}
|
||||
this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX);
|
||||
} else {
|
||||
this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX);
|
||||
}
|
||||
} else {
|
||||
if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
|
||||
if (stroke.needToApply()) {
|
||||
if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
|
||||
GL_CALL(StencilFillPath(id, fillMode, writeMask));
|
||||
}
|
||||
if (stroke.needToApply()) {
|
||||
GL_CALL(StencilStrokePath(id, 0xffff, writeMask));
|
||||
}
|
||||
|
||||
GrDrawState* drawState = fGpu->drawState();
|
||||
GrDrawState::AutoViewMatrixRestore avmr;
|
||||
SkRect bounds = SkRect::MakeLTRB(0, 0,
|
||||
SkIntToScalar(drawState->getRenderTarget()->width()),
|
||||
SkIntToScalar(drawState->getRenderTarget()->height()));
|
||||
SkMatrix vmi;
|
||||
// mapRect through persp matrix may not be correct
|
||||
if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
|
||||
vmi.mapRect(&bounds);
|
||||
// theoretically could set bloat = 0, instead leave it because of matrix inversion
|
||||
// precision.
|
||||
SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
|
||||
bounds.outset(bloat, bloat);
|
||||
} else {
|
||||
avmr.setIdentity(drawState);
|
||||
}
|
||||
|
||||
fGpu->drawSimpleRect(bounds);
|
||||
this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX);
|
||||
} else {
|
||||
this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType transformsType,
|
||||
SkPath::FillType fill) {
|
||||
const GrStencilSettings& stencilSettings) {
|
||||
SkASSERT(fGpu->caps()->pathRenderingSupport());
|
||||
SkASSERT(fGpu->drawState()->getRenderTarget());
|
||||
SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
|
||||
|
||||
GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();
|
||||
|
||||
this->flushPathStencilSettings(fill);
|
||||
this->flushPathStencilSettings(stencilSettings);
|
||||
SkASSERT(!fHWPathStencilSettings.isTwoSided());
|
||||
|
||||
const SkStrokeRec& stroke = pathRange->getStroke();
|
||||
|
||||
SkPath::FillType nonInvertedFill =
|
||||
SkPath::ConvertToNonInverseFillType(fill);
|
||||
|
||||
GrGLenum fillMode =
|
||||
gr_stencil_op_to_gl_path_rendering_fill_mode(
|
||||
fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
|
||||
GrGLint writeMask =
|
||||
fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
|
||||
|
||||
if (nonInvertedFill == fill) {
|
||||
if (stroke.needToApply()) {
|
||||
if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
|
||||
GL_CALL(StencilFillPathInstanced(
|
||||
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
|
||||
writeMask, gXformType2GLType[transformsType],
|
||||
transforms));
|
||||
}
|
||||
this->stencilThenCoverStrokePathInstanced(
|
||||
count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask,
|
||||
GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
|
||||
gXformType2GLType[transformsType], transforms);
|
||||
} else {
|
||||
this->stencilThenCoverFillPathInstanced(
|
||||
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask,
|
||||
GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
|
||||
gXformType2GLType[transformsType], transforms);
|
||||
}
|
||||
} else {
|
||||
if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
|
||||
if (stroke.needToApply()) {
|
||||
if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
|
||||
GL_CALL(StencilFillPathInstanced(
|
||||
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
|
||||
writeMask, gXformType2GLType[transformsType],
|
||||
transforms));
|
||||
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
|
||||
writeMask, gXformType2GLType[transformsType],
|
||||
transforms));
|
||||
}
|
||||
if (stroke.needToApply()) {
|
||||
GL_CALL(StencilStrokePathInstanced(
|
||||
count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff,
|
||||
writeMask, gXformType2GLType[transformsType],
|
||||
transforms));
|
||||
}
|
||||
|
||||
GrDrawState* drawState = fGpu->drawState();
|
||||
GrDrawState::AutoViewMatrixRestore avmr;
|
||||
SkRect bounds = SkRect::MakeLTRB(0, 0,
|
||||
SkIntToScalar(drawState->getRenderTarget()->width()),
|
||||
SkIntToScalar(drawState->getRenderTarget()->height()));
|
||||
SkMatrix vmi;
|
||||
// mapRect through persp matrix may not be correct
|
||||
if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
|
||||
vmi.mapRect(&bounds);
|
||||
// theoretically could set bloat = 0, instead leave it because of matrix inversion
|
||||
// precision.
|
||||
SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
|
||||
bounds.outset(bloat, bloat);
|
||||
} else {
|
||||
avmr.setIdentity(drawState);
|
||||
}
|
||||
|
||||
fGpu->drawSimpleRect(bounds);
|
||||
this->stencilThenCoverStrokePathInstanced(
|
||||
count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask,
|
||||
GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
|
||||
gXformType2GLType[transformsType], transforms);
|
||||
} else {
|
||||
this->stencilThenCoverFillPathInstanced(
|
||||
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask,
|
||||
GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
|
||||
gXformType2GLType[transformsType], transforms);
|
||||
}
|
||||
}
|
||||
|
||||
@ -466,18 +407,16 @@ void GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) {
|
||||
fPathNameAllocator->free(path);
|
||||
}
|
||||
|
||||
void GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) {
|
||||
GrStencilSettings pathStencilSettings;
|
||||
fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings);
|
||||
if (fHWPathStencilSettings != pathStencilSettings) {
|
||||
void GrGLPathRendering::flushPathStencilSettings(const GrStencilSettings& stencilSettings) {
|
||||
if (fHWPathStencilSettings != stencilSettings) {
|
||||
// Just the func, ref, and mask is set here. The op and write mask are params to the call
|
||||
// that draws the path to the SB (glStencilFillPath)
|
||||
GrGLenum func =
|
||||
GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront_Face));
|
||||
GL_CALL(PathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSettings::kFront_Face),
|
||||
pathStencilSettings.funcMask(GrStencilSettings::kFront_Face)));
|
||||
GrToGLStencilFunc(stencilSettings.func(GrStencilSettings::kFront_Face));
|
||||
GL_CALL(PathStencilFunc(func, stencilSettings.funcRef(GrStencilSettings::kFront_Face),
|
||||
stencilSettings.funcMask(GrStencilSettings::kFront_Face)));
|
||||
|
||||
fHWPathStencilSettings = pathStencilSettings;
|
||||
fHWPathStencilSettings = stencilSettings;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,11 @@ public:
|
||||
virtual GrPathRange* createGlyphs(const SkTypeface*,
|
||||
const SkDescriptor*,
|
||||
const SkStrokeRec&) SK_OVERRIDE;
|
||||
virtual void stencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
|
||||
virtual void drawPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
|
||||
virtual void stencilPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE;
|
||||
virtual void drawPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE;
|
||||
virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count,
|
||||
const float transforms[], PathTransformType,
|
||||
SkPath::FillType) SK_OVERRIDE;
|
||||
const GrStencilSettings&) SK_OVERRIDE;
|
||||
|
||||
/* Called when the 3D context state is unknown. */
|
||||
void resetContext();
|
||||
@ -107,7 +107,7 @@ private:
|
||||
};
|
||||
const Caps& caps() const { return fCaps; }
|
||||
|
||||
void flushPathStencilSettings(SkPath::FillType fill);
|
||||
void flushPathStencilSettings(const GrStencilSettings&);
|
||||
|
||||
// NV_path_rendering v1.2
|
||||
void stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
|
||||
|
@ -1871,6 +1871,7 @@ void set_gl_stencil(const GrGLInterface* gl,
|
||||
}
|
||||
|
||||
void GrGpuGL::flushStencil(const GrStencilSettings& stencilSettings, DrawType type) {
|
||||
// TODO figure out why we need to flush stencil settings on path draws at all
|
||||
if (kStencilPath_DrawType != type && fHWStencilSettings != stencilSettings) {
|
||||
if (stencilSettings.isDisabled()) {
|
||||
if (kNo_TriState != fHWStencilTestEnabled) {
|
||||
@ -1917,10 +1918,7 @@ void GrGpuGL::flushAAState(const GrOptDrawState& optState, DrawType type) {
|
||||
const GrRenderTarget* rt = optState.getRenderTarget();
|
||||
if (kGL_GrGLStandard == this->glStandard()) {
|
||||
if (RT_HAS_MSAA) {
|
||||
// FIXME: GL_NV_pr doesn't seem to like MSAA disabled. The paths
|
||||
// convex hulls of each segment appear to get filled.
|
||||
bool enableMSAA = kStencilPath_DrawType == type ||
|
||||
optState.isHWAntialiasState();
|
||||
bool enableMSAA = optState.isHWAntialiasState();
|
||||
if (enableMSAA) {
|
||||
if (kYes_TriState != fMSAAEnabled) {
|
||||
GL_CALL(Enable(GR_GL_MULTISAMPLE));
|
||||
|
Loading…
Reference in New Issue
Block a user