Clip mask manager sets stencil on draw type
BUG=skia: Committed: https://skia.googlesource.com/skia/+/7afb5aa201e4b59397cbd8480e121d7501a227e7 Review URL: https://codereview.chromium.org/676983003
This commit is contained in:
parent
f11c574882
commit
a58fe35fda
@ -17,12 +17,12 @@
|
||||
#include "GrRenderTarget.h"
|
||||
#include "GrStencilBuffer.h"
|
||||
#include "GrSWMaskHelper.h"
|
||||
#include "effects/GrTextureDomain.h"
|
||||
#include "effects/GrConvexPolyEffect.h"
|
||||
#include "effects/GrRRectEffect.h"
|
||||
#include "SkRasterClip.h"
|
||||
#include "SkStrokeRec.h"
|
||||
#include "SkTLazy.h"
|
||||
#include "effects/GrTextureDomain.h"
|
||||
#include "effects/GrConvexPolyEffect.h"
|
||||
#include "effects/GrRRectEffect.h"
|
||||
|
||||
#define GR_AA_CLIP 1
|
||||
|
||||
@ -212,6 +212,7 @@ bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele
|
||||
// scissor, or entirely software
|
||||
bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
|
||||
GrDrawState::AutoRestoreEffects* are,
|
||||
GrDrawState::AutoRestoreStencil* asr,
|
||||
const SkRect* devBounds) {
|
||||
fCurrClipMaskType = kNone_ClipMaskType;
|
||||
|
||||
@ -228,7 +229,6 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
|
||||
SkASSERT(rt);
|
||||
|
||||
bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWideOpen();
|
||||
|
||||
if (!ignoreClip) {
|
||||
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
|
||||
clipSpaceRTIBounds.offset(clipDataIn->fOrigin);
|
||||
@ -250,7 +250,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
|
||||
|
||||
if (ignoreClip) {
|
||||
fGpu->disableScissor();
|
||||
this->setGpuStencil();
|
||||
this->setDrawStateStencil(asr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -275,7 +275,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
|
||||
} else {
|
||||
fGpu->disableScissor();
|
||||
}
|
||||
this->setGpuStencil();
|
||||
this->setDrawStateStencil(asr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -307,7 +307,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
|
||||
are->set(fGpu->drawState());
|
||||
setup_drawstate_aaclip(fGpu, result, rtSpaceMaskBounds);
|
||||
fGpu->disableScissor();
|
||||
this->setGpuStencil();
|
||||
this->setDrawStateStencil(asr);
|
||||
return true;
|
||||
}
|
||||
// if alpha clip mask creation fails fall through to the non-AA code paths
|
||||
@ -335,7 +335,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
|
||||
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
|
||||
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
|
||||
fGpu->enableScissor(scissorSpaceIBounds);
|
||||
this->setGpuStencil();
|
||||
this->setDrawStateStencil(asr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -400,11 +400,11 @@ bool GrClipMaskManager::drawElement(GrTexture* target,
|
||||
// TODO: Do rects directly to the accumulator using a aa-rect GrProcessor that covers
|
||||
// the entire mask bounds and writes 0 outside the rect.
|
||||
if (element->isAA()) {
|
||||
getContext()->getAARectRenderer()->fillAARect(fGpu,
|
||||
fGpu,
|
||||
element->getRect(),
|
||||
SkMatrix::I(),
|
||||
element->getRect());
|
||||
this->getContext()->getAARectRenderer()->fillAARect(fGpu,
|
||||
fGpu,
|
||||
element->getRect(),
|
||||
SkMatrix::I(),
|
||||
element->getRect());
|
||||
} else {
|
||||
fGpu->drawSimpleRect(element->getRect());
|
||||
}
|
||||
@ -707,7 +707,6 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
|
||||
}
|
||||
|
||||
if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset)) {
|
||||
|
||||
stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset);
|
||||
|
||||
// Set the matrix so that rendered clip elements are transformed from clip to stencil space.
|
||||
@ -903,7 +902,7 @@ const GrStencilSettings& basic_apply_stencil_clip_settings() {
|
||||
}
|
||||
}
|
||||
|
||||
void GrClipMaskManager::setGpuStencil() {
|
||||
void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars) {
|
||||
// We make two copies of the StencilSettings here (except in the early
|
||||
// exit scenario. One copy from draw state to the stack var. Then another
|
||||
// from the stack var to the gpu. We could make this class hold a ptr to
|
||||
@ -933,7 +932,6 @@ void GrClipMaskManager::setGpuStencil() {
|
||||
if (GrClipMaskManager::kRespectClip_StencilClipMode == clipMode) {
|
||||
settings = basic_apply_stencil_clip_settings();
|
||||
} else {
|
||||
fGpu->disableStencil();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@ -942,8 +940,7 @@ void GrClipMaskManager::setGpuStencil() {
|
||||
|
||||
// TODO: dynamically attach a stencil buffer
|
||||
int stencilBits = 0;
|
||||
GrStencilBuffer* stencilBuffer =
|
||||
drawState.getRenderTarget()->getStencilBuffer();
|
||||
GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuffer();
|
||||
if (stencilBuffer) {
|
||||
stencilBits = stencilBuffer->bits();
|
||||
}
|
||||
@ -951,7 +948,8 @@ void GrClipMaskManager::setGpuStencil() {
|
||||
SkASSERT(fGpu->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
|
||||
SkASSERT(fGpu->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
|
||||
this->adjustStencilParams(&settings, clipMode, stencilBits);
|
||||
fGpu->setStencilSettings(settings);
|
||||
ars->set(fGpu->drawState());
|
||||
fGpu->drawState()->setStencil(settings);
|
||||
}
|
||||
|
||||
void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
|
||||
|
@ -50,7 +50,9 @@ public:
|
||||
* the manager when it must install additional effects to implement the
|
||||
* clip. devBounds is optional but can help optimize clipping.
|
||||
*/
|
||||
bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*,
|
||||
bool setupClipping(const GrClipData* clipDataIn,
|
||||
GrDrawState::AutoRestoreEffects*,
|
||||
GrDrawState::AutoRestoreStencil*,
|
||||
const SkRect* devBounds);
|
||||
|
||||
/**
|
||||
@ -173,7 +175,7 @@ private:
|
||||
* updates the GrGpu with stencil settings that account stencil-based
|
||||
* clipping.
|
||||
*/
|
||||
void setGpuStencil();
|
||||
void setDrawStateStencil(GrDrawState::AutoRestoreStencil* asr);
|
||||
|
||||
/**
|
||||
* Adjusts the stencil settings to account for interaction with stencil
|
||||
|
@ -346,6 +346,36 @@ public:
|
||||
int fCoverageEffectCnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* AutoRestoreStencil
|
||||
*
|
||||
* This simple struct saves and restores the stencil settings
|
||||
*/
|
||||
class AutoRestoreStencil : public ::SkNoncopyable {
|
||||
public:
|
||||
AutoRestoreStencil() : fDrawState(NULL) {}
|
||||
|
||||
AutoRestoreStencil(GrDrawState* ds) : fDrawState(NULL) { this->set(ds); }
|
||||
|
||||
~AutoRestoreStencil() { this->set(NULL); }
|
||||
|
||||
void set(GrDrawState* ds) {
|
||||
if (fDrawState) {
|
||||
fDrawState->setStencil(fStencilSettings);
|
||||
}
|
||||
fDrawState = ds;
|
||||
if (ds) {
|
||||
fStencilSettings = ds->getStencil();
|
||||
}
|
||||
}
|
||||
|
||||
bool isSet() const { return SkToBool(fDrawState); }
|
||||
|
||||
private:
|
||||
GrDrawState* fDrawState;
|
||||
GrStencilSettings fStencilSettings;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -298,10 +298,12 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrGpu::setupClipAndFlushState(DrawType type, const GrDeviceCoordTexture* dstCopy,
|
||||
bool GrGpu::setupClipAndFlushState(DrawType type,
|
||||
const GrDeviceCoordTexture* dstCopy,
|
||||
GrDrawState::AutoRestoreEffects* are,
|
||||
const SkRect* devBounds) {
|
||||
if (!fClipMaskManager.setupClipping(this->getClip(), are, devBounds)) {
|
||||
GrDrawState::AutoRestoreStencil asr;
|
||||
if (!fClipMaskManager.setupClipping(this->getClip(), are, &asr, devBounds)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -306,18 +306,6 @@ public:
|
||||
}
|
||||
void disableScissor() { fScissorState.fEnabled = false; }
|
||||
|
||||
/**
|
||||
* Like the scissor methods above this is called by setupClipping and
|
||||
* should be flushed by the GrGpu subclass in flushGraphicsState. These
|
||||
* stencil settings should be used in place of those on the GrDrawState.
|
||||
* They have been adjusted to account for any interactions between the
|
||||
* GrDrawState's stencil settings and stencil clipping.
|
||||
*/
|
||||
void setStencilSettings(const GrStencilSettings& settings) {
|
||||
fStencilSettings = settings;
|
||||
}
|
||||
void disableStencil() { fStencilSettings.setDisabled(); }
|
||||
|
||||
// GrGpu subclass sets clip bit in the stencil buffer. The subclass is
|
||||
// free to clear the remaining bits to zero if masked clears are more
|
||||
// expensive than clearing all bits.
|
||||
@ -369,7 +357,7 @@ protected:
|
||||
// prepares clip flushes gpu state before a draw
|
||||
bool setupClipAndFlushState(DrawType,
|
||||
const GrDeviceCoordTexture* dstCopy,
|
||||
GrDrawState::AutoRestoreEffects* are,
|
||||
GrDrawState::AutoRestoreEffects*,
|
||||
const SkRect* devBounds);
|
||||
|
||||
// Functions used to map clip-respecting stencil tests into normal
|
||||
@ -404,9 +392,6 @@ protected:
|
||||
SkIRect fRect;
|
||||
} fScissorState;
|
||||
|
||||
// The final stencil settings to use as determined by the clip manager.
|
||||
GrStencilSettings fStencilSettings;
|
||||
|
||||
// Helpers for setting up geometry state
|
||||
void finalizeReservedVertices();
|
||||
void finalizeReservedIndices();
|
||||
|
@ -1904,9 +1904,9 @@ void set_gl_stencil(const GrGLInterface* gl,
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::flushStencil(DrawType type) {
|
||||
if (kStencilPath_DrawType != type && fHWStencilSettings != fStencilSettings) {
|
||||
if (fStencilSettings.isDisabled()) {
|
||||
void GrGpuGL::flushStencil(const GrStencilSettings& stencilSettings, DrawType type) {
|
||||
if (kStencilPath_DrawType != type && fHWStencilSettings != stencilSettings) {
|
||||
if (stencilSettings.isDisabled()) {
|
||||
if (kNo_TriState != fHWStencilTestEnabled) {
|
||||
GL_CALL(Disable(GR_GL_STENCIL_TEST));
|
||||
fHWStencilTestEnabled = kNo_TriState;
|
||||
@ -1917,24 +1917,24 @@ void GrGpuGL::flushStencil(DrawType type) {
|
||||
fHWStencilTestEnabled = kYes_TriState;
|
||||
}
|
||||
}
|
||||
if (!fStencilSettings.isDisabled()) {
|
||||
if (!stencilSettings.isDisabled()) {
|
||||
if (this->caps()->twoSidedStencilSupport()) {
|
||||
set_gl_stencil(this->glInterface(),
|
||||
fStencilSettings,
|
||||
stencilSettings,
|
||||
GR_GL_FRONT,
|
||||
GrStencilSettings::kFront_Face);
|
||||
set_gl_stencil(this->glInterface(),
|
||||
fStencilSettings,
|
||||
stencilSettings,
|
||||
GR_GL_BACK,
|
||||
GrStencilSettings::kBack_Face);
|
||||
} else {
|
||||
set_gl_stencil(this->glInterface(),
|
||||
fStencilSettings,
|
||||
stencilSettings,
|
||||
GR_GL_FRONT_AND_BACK,
|
||||
GrStencilSettings::kFront_Face);
|
||||
}
|
||||
}
|
||||
fHWStencilSettings = fStencilSettings;
|
||||
fHWStencilSettings = stencilSettings;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +235,7 @@ private:
|
||||
// NULL means whole target. Can be an empty rect.
|
||||
void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
|
||||
|
||||
void flushStencil(DrawType);
|
||||
void flushStencil(const GrStencilSettings&, DrawType);
|
||||
void flushAAState(const GrOptDrawState&, DrawType);
|
||||
|
||||
bool configToGLFormats(GrPixelConfig config,
|
||||
|
@ -258,7 +258,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
|
||||
}
|
||||
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget());
|
||||
this->flushStencil(type);
|
||||
this->flushStencil(optState->getStencil(), type);
|
||||
this->flushScissor(glRT->getViewport(), glRT->origin());
|
||||
this->flushAAState(*optState.get(), type);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user