aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/GrCaps.h4
-rw-r--r--src/gpu/GrCaps.cpp2
-rw-r--r--src/gpu/gl/GrGLCaps.cpp13
-rw-r--r--src/gpu/gl/GrGLGpu.cpp44
-rw-r--r--src/gpu/gl/GrGLGpu.h6
-rw-r--r--src/gpu/gl/GrGLPathRendering.cpp2
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);