diff options
-rw-r--r-- | include/gpu/GrCaps.h | 4 | ||||
-rw-r--r-- | src/gpu/GrCaps.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 13 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 44 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRendering.cpp | 2 |
6 files changed, 57 insertions, 14 deletions
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h index 05da8d7cad..944fb1481c 100644 --- a/include/gpu/GrCaps.h +++ b/include/gpu/GrCaps.h @@ -211,6 +211,9 @@ public: int maxColorSampleCount() const { return fMaxColorSampleCount; } // Will be 0 if MSAA is not supported int maxStencilSampleCount() const { return fMaxStencilSampleCount; } + // Will be 0 if raster multisample is not supported. Raster multisample is a special HW mode + // where the rasterizer runs with more samples than are in the target framebuffer. + int maxRasterSamples() const { return fMaxRasterSamples; } // We require the sample count to be less than maxColorSampleCount and maxStencilSampleCount. // If we are using mixed samples, we only care about stencil. int maxSampleCount() const { @@ -291,6 +294,7 @@ protected: int fMaxTileSize; int fMaxColorSampleCount; int fMaxStencilSampleCount; + int fMaxRasterSamples; private: virtual void onApplyOptionsOverrides(const GrContextOptions&) {}; diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp index f4c64c3333..46f49357c7 100644 --- a/src/gpu/GrCaps.cpp +++ b/src/gpu/GrCaps.cpp @@ -106,6 +106,7 @@ GrCaps::GrCaps(const GrContextOptions& options) { fMaxTextureSize = 1; fMaxColorSampleCount = 0; fMaxStencilSampleCount = 0; + fMaxRasterSamples = 0; fSuppressPrints = options.fSuppressPrints; fImmediateFlush = options.fImmediateMode; @@ -178,6 +179,7 @@ SkString GrCaps::dump() const { r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize); r.appendf("Max Color Sample Count : %d\n", fMaxColorSampleCount); r.appendf("Max Stencil Sample Count : %d\n", fMaxStencilSampleCount); + r.appendf("Max Raster Samples : %d\n", fMaxRasterSamples); static const char* kBlendEquationSupportNames[] = { "Basic", diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index d95e10ba64..1a87274b45 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -423,11 +423,18 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, // initFSAASupport() must have been called before this point if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) { - GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxColorSampleCount); + GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxStencilSampleCount); } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) { - GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxColorSampleCount); + GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxStencilSampleCount); } - fMaxStencilSampleCount = fMaxColorSampleCount; + // We only have a use for raster multisample if there is coverage modulation from mixed samples. + if (fUsesMixedSamples && ctxInfo.hasExtension("GL_EXT_raster_multisample")) { + GR_GL_GetIntegerv(gli, GR_GL_MAX_RASTER_SAMPLES, &fMaxRasterSamples); + // This is to guard against platforms that may not support as many samples for + // glRasterSamples as they do for framebuffers. + fMaxStencilSampleCount = SkTMin(fMaxStencilSampleCount, fMaxRasterSamples); + } + fMaxColorSampleCount = fMaxStencilSampleCount; if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() || kPowerVRRogue_GrGLRenderer == ctxInfo.renderer() || diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 317ddbb6ee..f916b4f436 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -442,11 +442,14 @@ void GrGLGpu::onResetContext(uint32_t resetBits) { if (resetBits & kMSAAEnable_GrGLBackendState) { fMSAAEnabled = kUnknown_TriState; - // In mixed samples mode coverage modulation allows the coverage to be converted to - // "opacity", which can then be blended into the color buffer to accomplish antialiasing. - // Enable coverage modulation suitable for premultiplied alpha colors. - // This state has no effect when not rendering to a mixed sampled target. if (this->caps()->usesMixedSamples()) { + if (0 != this->caps()->maxRasterSamples()) { + fHWRasterMultisampleEnabled = kUnknown_TriState; + fHWNumRasterSamples = 0; + } + + // The skia blend modes all use premultiplied alpha and therefore expect RGBA coverage + // modulation. This state has no effect when not rendering to a mixed sampled target. GL_CALL(CoverageModulation(GR_GL_RGBA)); } } @@ -1705,7 +1708,7 @@ 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). @@ -2377,7 +2380,7 @@ void GrGLGpu::performFlushWorkaround() { */ this->disableScissor(); // using PLS in the presence of MSAA results in GL_INVALID_OPERATION - this->flushHWAAState(nullptr, false); + this->flushHWAAState(nullptr, false, false); SkASSERT(!fHWPLSEnabled); SkASSERT(fMSAAEnabled != kYes_TriState); GL_CALL(Enable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE)); @@ -2709,7 +2712,7 @@ 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->glCaps().multisampleDisableSupport()) { @@ -2725,6 +2728,29 @@ void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA) { } } } + + if (0 != this->caps()->maxRasterSamples()) { + if (useHWAA && rt->hasMixedSamples() && !stencilEnabled) { + // Since stencil is disabled and we want more samples than are in the color buffer, we + // need to tell the rasterizer explicitly how many to run. + if (kYes_TriState != fHWRasterMultisampleEnabled) { + GL_CALL(Enable(GR_GL_RASTER_MULTISAMPLE)); + fHWRasterMultisampleEnabled = kYes_TriState; + } + if (rt->numStencilSamples() != fHWNumRasterSamples) { + SkASSERT(rt->numStencilSamples() <= this->caps()->maxRasterSamples()); + GL_CALL(RasterSamples(rt->numStencilSamples(), GR_GL_TRUE)); + fHWNumRasterSamples = rt->numStencilSamples(); + } + } else { + if (kNo_TriState != fHWRasterMultisampleEnabled) { + GL_CALL(Disable(GR_GL_RASTER_MULTISAMPLE)); + fHWRasterMultisampleEnabled = kNo_TriState; + } + } + } else { + SkASSERT(!useHWAA || !rt->hasMixedSamples() || stencilEnabled); + } } void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle& swizzle) { @@ -3466,7 +3492,7 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor this->flushBlend(blendInfo, GrSwizzle::RGBA()); this->flushColorWrite(true); this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); - this->flushHWAAState(glRT, false); + this->flushHWAAState(glRT, false, false); this->disableScissor(); GrStencilSettings stencil; stencil.setDisabled(); @@ -3544,7 +3570,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, this->flushBlend(blendInfo, GrSwizzle::RGBA()); this->flushColorWrite(true); this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); - this->flushHWAAState(dstRT, false); + this->flushHWAAState(dstRT, false, false); this->disableScissor(); GrStencilSettings stencil; stencil.setDisabled(); diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 62330480e6..ec93bbfe21 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -310,7 +310,7 @@ private: void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds); void flushStencil(const GrStencilSettings&); - void flushHWAAState(GrRenderTarget* rt, bool useHWAA); + void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled); // helper for onCreateTexture and writeTexturePixels enum UploadType { @@ -542,6 +542,10 @@ private: uint32_t fHWBoundRenderTargetUniqueID; TriState fHWSRGBFramebuffer; SkTArray<uint32_t, true> fHWBoundTextureUniqueIDs; + + // EXT_raster_multisample. + TriState fHWRasterMultisampleEnabled; + int fHWNumRasterSamples; ///@} /** IDs for copy surface program. */ diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp index 7fb85352fb..441967edc5 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -106,7 +106,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); |