Revert of Fix mixed samples stencil clip (patchset #5 id:80001 of https://codereview.chromium.org/1431593006/ )
Reason for revert: Co-centered sample locations are not needed to do stencil clip with mixed samples. Original issue's description: > Fix mixed samples stencil clip > > Fixes rendering bugs and nondeterminism in gm. > > Before, mixed samples stencil clip would try to infer whether the draw > wanted co-centered sample locations from within GrGLGpu, which caused > various errors. This change reworks it so the draw itself can request > the co-centered sample locations when it knows it will need them. > > Also reduces framebuffer binds by moving the code that enables > GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS into flushRenderTarget. > > Committed: https://skia.googlesource.com/skia/+/14184d5567b58085b6d8a6375796d405056f7f73 TBR=bsalomon@google.com NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Review URL: https://codereview.chromium.org/1407063011
This commit is contained in:
parent
091f60c2a0
commit
d472792a72
@ -62,6 +62,7 @@ public:
|
||||
bool pathRenderingSupport() const { return fPathRenderingSupport; }
|
||||
bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
|
||||
bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
|
||||
bool programmableSampleLocationsSupport() const { return fProgrammableSampleLocationsSupport; }
|
||||
|
||||
/**
|
||||
* Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
|
||||
@ -91,6 +92,7 @@ protected:
|
||||
bool fPathRenderingSupport : 1;
|
||||
bool fDstReadInShaderSupport : 1;
|
||||
bool fDualSourceBlendingSupport : 1;
|
||||
bool fProgrammableSampleLocationsSupport : 1;
|
||||
|
||||
bool fShaderPrecisionVaries;
|
||||
PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
|
||||
@ -126,8 +128,6 @@ public:
|
||||
bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
|
||||
bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
|
||||
bool textureBarrierSupport() const { return fTextureBarrierSupport; }
|
||||
bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
|
||||
bool programmableSampleLocationsSupport() const { return fProgrammableSampleLocationsSupport; }
|
||||
bool mixedSamplesSupport() const { return fMixedSamplesSupport; }
|
||||
|
||||
bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; }
|
||||
@ -246,8 +246,6 @@ protected:
|
||||
bool fCompressedTexSubImageSupport : 1;
|
||||
bool fOversizedStencilSupport : 1;
|
||||
bool fTextureBarrierSupport : 1;
|
||||
bool fMultisampleDisableSupport : 1;
|
||||
bool fProgrammableSampleLocationsSupport : 1;
|
||||
bool fMixedSamplesSupport : 1;
|
||||
bool fSupportsInstancedDraws : 1;
|
||||
bool fFullClearIsFree : 1;
|
||||
|
@ -15,6 +15,7 @@ GrShaderCaps::GrShaderCaps() {
|
||||
fPathRenderingSupport = false;
|
||||
fDstReadInShaderSupport = false;
|
||||
fDualSourceBlendingSupport = false;
|
||||
fProgrammableSampleLocationsSupport = false;
|
||||
fShaderPrecisionVaries = false;
|
||||
}
|
||||
|
||||
@ -50,6 +51,7 @@ SkString GrShaderCaps::dump() const {
|
||||
r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]);
|
||||
r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
|
||||
r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]);
|
||||
r.appendf("Programmable Sample Locations Support : %s\n", gNY[fProgrammableSampleLocationsSupport]);
|
||||
|
||||
r.appendf("Shader Float Precisions (varies: %s) :\n", gNY[fShaderPrecisionVaries]);
|
||||
|
||||
@ -90,8 +92,6 @@ GrCaps::GrCaps(const GrContextOptions& options) {
|
||||
fCompressedTexSubImageSupport = false;
|
||||
fOversizedStencilSupport = false;
|
||||
fTextureBarrierSupport = false;
|
||||
fMultisampleDisableSupport = false;
|
||||
fProgrammableSampleLocationsSupport = false;
|
||||
fMixedSamplesSupport = false;
|
||||
fSupportsInstancedDraws = false;
|
||||
fFullClearIsFree = false;
|
||||
@ -164,9 +164,6 @@ SkString GrCaps::dump() const {
|
||||
r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]);
|
||||
r.appendf("Oversized Stencil Support : %s\n", gNY[fOversizedStencilSupport]);
|
||||
r.appendf("Texture Barrier Support : %s\n", gNY[fTextureBarrierSupport]);
|
||||
r.appendf("Multisample Disable Support : %s\n", gNY[fMultisampleDisableSupport]);
|
||||
r.appendf("Programmable Sample Locations Support : %s\n",
|
||||
gNY[fProgrammableSampleLocationsSupport]);
|
||||
r.appendf("Mixed Samples Support : %s\n", gNY[fMixedSamplesSupport]);
|
||||
r.appendf("Supports instanced draws : %s\n", gNY[fSupportsInstancedDraws]);
|
||||
r.appendf("Full screen clear is free : %s\n", gNY[fFullClearIsFree]);
|
||||
|
@ -368,22 +368,8 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
SkASSERT(!pipelineBuilder.isHWAntialias() || rt->isStencilBufferMultisampled());
|
||||
|
||||
bool hasHWAntialias = pipelineBuilder.isHWAntialias();
|
||||
|
||||
if (rt->isStencilBufferMultisampled() && !hasHWAntialias) {
|
||||
if (!this->caps()->multisampleDisableSupport()) {
|
||||
hasHWAntialias = true; // This will be on regardless, it's impossible to turn it off.
|
||||
} else if (this->caps()->programmableSampleLocationsSupport()) {
|
||||
// Enable HW antialias, but leave the draw non-antialiased by co-centering the samples.
|
||||
out->fIsCoCenteredMultisampledDraw = true;
|
||||
hasHWAntialias = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have HW antialias, or don't need AA, we can do everything in the stencil buffer.
|
||||
if (!hasHWAntialias && requiresAA) {
|
||||
// If MSAA is enabled we can do everything in the stencil buffer.
|
||||
if (0 == rt->numStencilSamples() && requiresAA) {
|
||||
SkAutoTUnref<GrTexture> result;
|
||||
|
||||
// The top-left of the mask corresponds to the top-left corner of the bounds.
|
||||
|
@ -33,23 +33,13 @@ class SkPath;
|
||||
*/
|
||||
class GrAppliedClip : public SkNoncopyable {
|
||||
public:
|
||||
GrAppliedClip() : fIsCoCenteredMultisampledDraw(false) {}
|
||||
|
||||
GrAppliedClip() {}
|
||||
const GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP; }
|
||||
const GrScissorState& scissorState() const { return fScissorState; }
|
||||
|
||||
/**
|
||||
* This is used to perform a multisampled clip test when the draw requires MSAA to be disabled.
|
||||
* It will allow the stencil test to run multisampled by turning on hardware MSAA, but co-locate
|
||||
* the draw's samples at pixel center so it will still feel like MSAA is disabled.
|
||||
*/
|
||||
bool isCoCenteredMultisampledDraw() const { return fIsCoCenteredMultisampledDraw; }
|
||||
|
||||
private:
|
||||
SkAutoTUnref<const GrFragmentProcessor> fClipCoverageFP;
|
||||
GrScissorState fScissorState;
|
||||
bool fIsCoCenteredMultisampledDraw;
|
||||
|
||||
friend class GrClipMaskManager;
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
|
@ -219,9 +219,14 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBat
|
||||
if (!fClipMaskManager->setupClipping(pipelineBuilder, &ars, &batch->bounds(), &clip)) {
|
||||
return;
|
||||
}
|
||||
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
|
||||
if (clip.clipCoverageFragmentProcessor()) {
|
||||
arfps.set(&pipelineBuilder);
|
||||
arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor());
|
||||
}
|
||||
|
||||
GrPipeline::CreateArgs args;
|
||||
if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip, batch)) {
|
||||
if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState(), batch)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -344,6 +349,12 @@ void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder,
|
||||
return;
|
||||
}
|
||||
|
||||
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
|
||||
if (clip.clipCoverageFragmentProcessor()) {
|
||||
arfps.set(&pipelineBuilder);
|
||||
arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor());
|
||||
}
|
||||
|
||||
// Ensure the render target has a stencil buffer and get the stencil settings.
|
||||
GrStencilSettings stencilSettings;
|
||||
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
|
||||
@ -352,7 +363,7 @@ void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder,
|
||||
batch->setStencilSettings(stencilSettings);
|
||||
|
||||
GrPipeline::CreateArgs args;
|
||||
if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip, batch)) {
|
||||
if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState(), batch)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -528,19 +539,14 @@ void GrDrawTarget::recordBatch(GrBatch* batch) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
|
||||
const GrAppliedClip* clip, GrDrawBatch* batch) {
|
||||
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
|
||||
if (clip->clipCoverageFragmentProcessor()) {
|
||||
arfps.set(pipelineBuilder);
|
||||
arfps.addCoverageFragmentProcessor(clip->clipCoverageFragmentProcessor());
|
||||
}
|
||||
|
||||
const GrScissorState* scissor,
|
||||
GrDrawBatch* batch) {
|
||||
GrPipeline::CreateArgs args;
|
||||
args.fPipelineBuilder = pipelineBuilder;
|
||||
args.fCaps = this->caps();
|
||||
args.fScissor = scissor;
|
||||
args.fColorPOI = pipelineBuilder->colorProcInfo(batch);
|
||||
args.fCoveragePOI = pipelineBuilder->coverageProcInfo(batch);
|
||||
args.fClip = clip;
|
||||
if (!this->setupDstReadIfNecessary(*pipelineBuilder, args.fColorPOI,
|
||||
args.fCoveragePOI, &args.fDstTexture,
|
||||
batch->bounds())) {
|
||||
|
@ -277,7 +277,9 @@ private:
|
||||
};
|
||||
|
||||
void recordBatch(GrBatch*);
|
||||
bool installPipelineInDrawBatch(const GrPipelineBuilder*, const GrAppliedClip*, GrDrawBatch*);
|
||||
bool installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
|
||||
const GrScissorState* scissor,
|
||||
GrDrawBatch* batch);
|
||||
|
||||
// Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
|
||||
// but couldn't be made. Otherwise, returns true. This method needs to be protected because it
|
||||
|
@ -59,15 +59,12 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
|
||||
pipeline->fRenderTarget.reset(builder.fRenderTarget.get());
|
||||
SkASSERT(pipeline->fRenderTarget);
|
||||
pipeline->fScissorState = args.fClip->scissorState();
|
||||
pipeline->fScissorState = *args.fScissor;
|
||||
pipeline->fStencilSettings = builder.getStencil();
|
||||
pipeline->fDrawFace = builder.getDrawFace();
|
||||
|
||||
pipeline->fFlags = 0;
|
||||
if (args.fClip->isCoCenteredMultisampledDraw()) {
|
||||
SkASSERT(args.fCaps->programmableSampleLocationsSupport() && !builder.isHWAntialias());
|
||||
pipeline->fFlags |= (kHWAA_Flag | kCoCenteredSamples_Flag);
|
||||
} else if (builder.isHWAntialias()) {
|
||||
if (builder.isHWAntialias()) {
|
||||
pipeline->fFlags |= kHWAA_Flag;
|
||||
}
|
||||
if (builder.snapVerticesToPixelCenters()) {
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "SkMatrix.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class GrAppliedClip;
|
||||
class GrBatch;
|
||||
class GrDeviceCoordTexture;
|
||||
class GrPipelineBuilder;
|
||||
@ -39,7 +38,7 @@ public:
|
||||
const GrCaps* fCaps;
|
||||
GrProcOptInfo fColorPOI;
|
||||
GrProcOptInfo fCoveragePOI;
|
||||
const GrAppliedClip* fClip;
|
||||
const GrScissorState* fScissor;
|
||||
GrXferProcessor::DstTexture fDstTexture;
|
||||
};
|
||||
|
||||
@ -126,7 +125,6 @@ public:
|
||||
|
||||
bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAA_Flag); }
|
||||
bool snapVerticesToPixelCenters() const { return SkToBool(fFlags & kSnapVertices_Flag); }
|
||||
bool hasCoCenteredSamples() const { return SkToBool(fFlags & kCoCenteredSamples_Flag); }
|
||||
|
||||
GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
|
||||
return fXferProcessor->xferBarrierType(fRenderTarget.get(), caps);
|
||||
@ -168,7 +166,6 @@ private:
|
||||
enum Flags {
|
||||
kHWAA_Flag = 0x1,
|
||||
kSnapVertices_Flag = 0x2,
|
||||
kCoCenteredSamples_Flag = 0x4
|
||||
};
|
||||
|
||||
typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
|
||||
|
@ -43,6 +43,7 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
|
||||
fDirectStateAccessSupport = false;
|
||||
fDebugSupport = false;
|
||||
fES2CompatibilitySupport = false;
|
||||
fMultisampleDisableSupport = false;
|
||||
fUseNonVBOVertexAndIndexDynamicData = false;
|
||||
fIsCoreProfile = false;
|
||||
fBindFragDataLocationSupport = false;
|
||||
@ -251,17 +252,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
||||
fMultisampleDisableSupport = ctxInfo.hasExtension("GL_EXT_multisample_compatibility");
|
||||
}
|
||||
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
fProgrammableSampleLocationsSupport =
|
||||
ctxInfo.version() >= GR_GL_VER(4, 3) &&
|
||||
(ctxInfo.hasExtension("GL_ARB_sample_locations") ||
|
||||
ctxInfo.hasExtension("GL_NV_sample_locations"));
|
||||
} else {
|
||||
fProgrammableSampleLocationsSupport =
|
||||
ctxInfo.version() >= GR_GL_VER(3, 1) &&
|
||||
ctxInfo.hasExtension("GL_NV_sample_locations");
|
||||
}
|
||||
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
if (version >= GR_GL_VER(3, 0)) {
|
||||
fBindFragDataLocationSupport = true;
|
||||
@ -320,6 +310,17 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
||||
ctxInfo.hasExtension("GL_OES_standard_derivatives");
|
||||
}
|
||||
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
glslCaps->fProgrammableSampleLocationsSupport =
|
||||
ctxInfo.version() >= GR_GL_VER(4, 3) &&
|
||||
(ctxInfo.hasExtension("GL_ARB_sample_locations") ||
|
||||
ctxInfo.hasExtension("GL_NV_sample_locations"));
|
||||
} else {
|
||||
glslCaps->fProgrammableSampleLocationsSupport =
|
||||
ctxInfo.version() >= GR_GL_VER(3, 1) &&
|
||||
ctxInfo.hasExtension("GL_NV_sample_locations");
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* GrCaps fields
|
||||
**************************************************************************/
|
||||
@ -1182,6 +1183,7 @@ SkString GrGLCaps::dump() const {
|
||||
r.appendf("Instanced drawing support: %s\n", (fInstancedDrawingSupport ? "YES": "NO"));
|
||||
r.appendf("Direct state access support: %s\n", (fDirectStateAccessSupport ? "YES": "NO"));
|
||||
r.appendf("Debug support: %s\n", (fDebugSupport ? "YES": "NO"));
|
||||
r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
|
||||
r.appendf("Use non-VBO for dynamic data: %s\n",
|
||||
(fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
|
||||
r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
|
||||
|
@ -213,6 +213,11 @@ public:
|
||||
/// Is there support for ES2 compatability?
|
||||
bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; }
|
||||
|
||||
/// Can we call glDisable(GL_MULTISAMPLE)?
|
||||
bool multisampleDisableSupport() const {
|
||||
return fMultisampleDisableSupport;
|
||||
}
|
||||
|
||||
/// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
|
||||
bool useNonVBOVertexAndIndexDynamicData() const {
|
||||
return fUseNonVBOVertexAndIndexDynamicData;
|
||||
@ -351,6 +356,7 @@ private:
|
||||
bool fDirectStateAccessSupport : 1;
|
||||
bool fDebugSupport : 1;
|
||||
bool fES2CompatibilitySupport : 1;
|
||||
bool fMultisampleDisableSupport : 1;
|
||||
bool fUseNonVBOVertexAndIndexDynamicData : 1;
|
||||
bool fIsCoreProfile : 1;
|
||||
bool fBindFragDataLocationSupport : 1;
|
||||
|
@ -1500,11 +1500,11 @@ bool GrGLGpu::flushGLState(const DrawArgs& args) {
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
|
||||
this->flushStencil(pipeline.getStencil());
|
||||
this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin());
|
||||
this->flushHWAAState(glRT, pipeline.isHWAntialiasState());
|
||||
this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStencil().isDisabled());
|
||||
|
||||
// This must come after textures are flushed because a texture may need
|
||||
// to be msaa-resolved (which will modify bound FBO state).
|
||||
this->flushRenderTarget(glRT, nullptr, pipeline.hasCoCenteredSamples());
|
||||
this->flushRenderTarget(glRT, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2034,10 +2034,33 @@ bool GrGLGpu::onReadPixels(GrSurface* surface,
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound,
|
||||
bool coCenterSamples) {
|
||||
void GrGLGpu::setColocatedSampleLocations(GrRenderTarget* rt, bool useColocatedSampleLocations) {
|
||||
GrGLRenderTarget* target = static_cast<GrGLRenderTarget*>(rt->asRenderTarget());
|
||||
SkASSERT(0 != target->renderFBOID());
|
||||
|
||||
if (!rt->isStencilBufferMultisampled() ||
|
||||
useColocatedSampleLocations == target->usesColocatedSampleLocations()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (kGL_GrGLStandard == this->glStandard() && this->glVersion() >= GR_GL_VER(4,5)) {
|
||||
GL_CALL(NamedFramebufferParameteri(target->renderFBOID(),
|
||||
GR_GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS,
|
||||
useColocatedSampleLocations));
|
||||
} else {
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
|
||||
GL_CALL(FramebufferParameteri(GR_GL_FRAMEBUFFER,
|
||||
GR_GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS,
|
||||
useColocatedSampleLocations));
|
||||
fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
|
||||
}
|
||||
|
||||
target->flagAsUsingColocatedSampleLocations(useColocatedSampleLocations);
|
||||
}
|
||||
|
||||
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound) {
|
||||
|
||||
SkASSERT(target);
|
||||
SkASSERT(!coCenterSamples || this->caps()->programmableSampleLocationsSupport());
|
||||
|
||||
uint32_t rtID = target->getUniqueID();
|
||||
if (fHWBoundRenderTargetUniqueID != rtID) {
|
||||
@ -2081,19 +2104,6 @@ void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound,
|
||||
if (texture) {
|
||||
texture->texturePriv().dirtyMipMaps(true);
|
||||
}
|
||||
|
||||
if (this->caps()->programmableSampleLocationsSupport()) {
|
||||
ResetTimestamp timestamp;
|
||||
bool hasCoCenteredSamples = target->getCachedCoCenteredSamplesState(×tamp);
|
||||
if (timestamp < this->getResetTimestamp() || hasCoCenteredSamples != coCenterSamples) {
|
||||
// The default state for programmable sample locations is already at pixel center, so we
|
||||
// don't assign them. This assumes the client does not modify them outside of Skia.
|
||||
GL_CALL(FramebufferParameteri(GR_GL_FRAMEBUFFER,
|
||||
GR_GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS,
|
||||
coCenterSamples));
|
||||
target->setCachedCoCenteredSamplesState(coCenterSamples, this->getResetTimestamp());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GrGLenum gPrimitiveType2GLMode[] = {
|
||||
@ -2295,10 +2305,20 @@ void GrGLGpu::flushStencil(const GrStencilSettings& stencilSettings) {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA) {
|
||||
void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled) {
|
||||
SkASSERT(!useHWAA || rt->isStencilBufferMultisampled());
|
||||
|
||||
if (this->caps()->multisampleDisableSupport()) {
|
||||
if (rt->hasMixedSamples() && stencilEnabled &&
|
||||
this->glCaps().glslCaps()->programmableSampleLocationsSupport()) {
|
||||
if (useHWAA) {
|
||||
this->setColocatedSampleLocations(rt, false);
|
||||
} else {
|
||||
this->setColocatedSampleLocations(rt, true);
|
||||
}
|
||||
useHWAA = true;
|
||||
}
|
||||
|
||||
if (this->glCaps().multisampleDisableSupport()) {
|
||||
if (useHWAA) {
|
||||
if (kYes_TriState != fMSAAEnabled) {
|
||||
GL_CALL(Enable(GR_GL_MULTISAMPLE));
|
||||
@ -3099,7 +3119,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
|
||||
this->flushBlend(blendInfo);
|
||||
this->flushColorWrite(true);
|
||||
this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
|
||||
this->flushHWAAState(dstRT, false);
|
||||
this->flushHWAAState(dstRT, false, false);
|
||||
this->disableScissor();
|
||||
GrStencilSettings stencil;
|
||||
stencil.setDisabled();
|
||||
|
@ -269,12 +269,16 @@ private:
|
||||
// ensures that such operations don't negatively interact with tracking bound textures.
|
||||
void setScratchTextureUnit();
|
||||
|
||||
// colocates all samples at pixel center for render target, if MSAA.
|
||||
// allows drawing coverage based AA shapes in MSAA mode.
|
||||
void setColocatedSampleLocations(GrRenderTarget* rt, bool useColocatedSampleLocations);
|
||||
|
||||
// bounds is region that may be modified and therefore has to be resolved.
|
||||
// nullptr means whole target. Can be an empty rect.
|
||||
void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds, bool coCenterSamples = false);
|
||||
void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds);
|
||||
|
||||
void flushStencil(const GrStencilSettings&);
|
||||
void flushHWAAState(GrRenderTarget* rt, bool useHWAA);
|
||||
void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled);
|
||||
|
||||
bool configToGLFormats(GrPixelConfig config,
|
||||
bool getSizedInternal,
|
||||
|
@ -100,7 +100,7 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
|
||||
SkISize size = SkISize::Make(rt->width(), rt->height());
|
||||
this->setProjectionMatrix(*args.fViewMatrix, size, rt->origin());
|
||||
gpu->flushScissor(*args.fScissor, rt->getViewport(), rt->origin());
|
||||
gpu->flushHWAAState(rt, args.fUseHWAA);
|
||||
gpu->flushHWAAState(rt, args.fUseHWAA, true);
|
||||
gpu->flushRenderTarget(rt, nullptr);
|
||||
|
||||
const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
|
||||
|
@ -34,11 +34,10 @@ GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, cons
|
||||
}
|
||||
|
||||
void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
|
||||
fRTFBOID = idDesc.fRTFBOID;
|
||||
fTexFBOID = idDesc.fTexFBOID;
|
||||
fMSColorRenderbufferID = idDesc.fMSColorRenderbufferID;
|
||||
fRTLifecycle = idDesc.fLifeCycle;
|
||||
fHasCoCenteredSamplesTimestamp = GrGpu::kExpiredTimestamp;
|
||||
fRTFBOID = idDesc.fRTFBOID;
|
||||
fTexFBOID = idDesc.fTexFBOID;
|
||||
fMSColorRenderbufferID = idDesc.fMSColorRenderbufferID;
|
||||
fRTLifecycle = idDesc.fLifeCycle;
|
||||
|
||||
fViewport.fLeft = 0;
|
||||
fViewport.fBottom = 0;
|
||||
|
@ -9,7 +9,6 @@
|
||||
#ifndef GrGLRenderTarget_DEFINED
|
||||
#define GrGLRenderTarget_DEFINED
|
||||
|
||||
#include "GrGpu.h"
|
||||
#include "GrGLIRect.h"
|
||||
#include "GrRenderTarget.h"
|
||||
#include "SkScalar.h"
|
||||
@ -71,14 +70,19 @@ public:
|
||||
// components seperately.
|
||||
void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
|
||||
|
||||
bool getCachedCoCenteredSamplesState(GrGpu::ResetTimestamp* stamp) const {
|
||||
*stamp = fHasCoCenteredSamplesTimestamp;
|
||||
return fHasCoCenteredSamples;
|
||||
/**
|
||||
* @return true if sample locations colocated at pixel center have been set for this
|
||||
* render target. Requires support for NV_sample_locations.
|
||||
*/
|
||||
bool usesColocatedSampleLocations() const {
|
||||
return fUsesColocatedSampleLocations;
|
||||
}
|
||||
|
||||
void setCachedCoCenteredSamplesState(bool hasCoCenteredSamples, GrGpu::ResetTimestamp stamp) {
|
||||
fHasCoCenteredSamples = hasCoCenteredSamples;
|
||||
fHasCoCenteredSamplesTimestamp = stamp;
|
||||
/**
|
||||
* Flag render target as using or not using sample locations colocated at pixel center.
|
||||
*/
|
||||
void flagAsUsingColocatedSampleLocations(bool useColocatedSampleLocations) {
|
||||
fUsesColocatedSampleLocations = useColocatedSampleLocations;
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -110,24 +114,26 @@ private:
|
||||
// The number total number of samples, including both MSAA and resolve texture samples.
|
||||
int totalSamples() const;
|
||||
|
||||
GrGLuint fRTFBOID;
|
||||
GrGLuint fTexFBOID;
|
||||
GrGLuint fMSColorRenderbufferID;
|
||||
bool fHasCoCenteredSamples;
|
||||
GrGpu::ResetTimestamp fHasCoCenteredSamplesTimestamp;
|
||||
GrGLuint fRTFBOID;
|
||||
GrGLuint fTexFBOID;
|
||||
GrGLuint fMSColorRenderbufferID;
|
||||
|
||||
// We track this separately from GrGpuResource because this may be both a texture and a render
|
||||
// target, and the texture may be wrapped while the render target is not.
|
||||
LifeCycle fRTLifecycle;
|
||||
LifeCycle fRTLifecycle;
|
||||
|
||||
// when we switch to this render target we want to set the viewport to
|
||||
// only render to content area (as opposed to the whole allocation) and
|
||||
// we want the rendering to be at top left (GL has origin in bottom left)
|
||||
GrGLIRect fViewport;
|
||||
GrGLIRect fViewport;
|
||||
|
||||
// onGpuMemorySize() needs to know the VRAM footprint of the FBO(s). However, abandon and
|
||||
// release zero out the IDs and the cache needs to know the size even after those actions.
|
||||
size_t fGpuMemorySize;
|
||||
size_t fGpuMemorySize;
|
||||
|
||||
// True if sample locations colocated at pixel center are currently in use, false if default
|
||||
// sample locations are currently in use.
|
||||
bool fUsesColocatedSampleLocations;
|
||||
|
||||
typedef GrRenderTarget INHERITED;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user