Index: src/gpu/gl/GrGLGpu.cpp |
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp |
index c07f704d21342df6ebb7723c0358dca14351c903..d1bb3a9ea298ba722796da750508feb1e3f6f5fd 100644 |
--- a/src/gpu/gl/GrGLGpu.cpp |
+++ b/src/gpu/gl/GrGLGpu.cpp |
@@ -157,6 +157,29 @@ bool GrGLGpu::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { |
GR_STATIC_ASSERT(kGrBlendCoeffCnt == SK_ARRAY_COUNT(gXfermodeCoeff2Blend)); |
} |
+// Sample locations that are colocated at pixel center. |
+static const GrGLfloat gCenteredSampleLocations[2*16] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, |
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, |
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, |
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; |
+ |
+// Default sample pattern. |
+static GrGLfloat defaultSampleLocations2x[] = { 0.75f, 0.75f, 0.25f, 0.25f }; |
+static GrGLfloat defaultSampleLocations4x[] = { 0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f }; |
+static GrGLfloat defaultSampleLocations8x[] = { 0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, |
+ 0.1875f, 0.8125f, 0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f }; |
+static GrGLfloat defaultSampleLocations16x[] = { 0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f, 0.75f, 0.4375f, |
+ 0.1875f, 0.375f, 0.625f, 0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f, |
+ 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f, |
+ 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f, |
+ 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f }; |
+// Lookup table for sample locations array for sample count 0..16. |
+static GrGLfloat* gDefaultSampleLocations[17] = { 0, |
+ 0, defaultSampleLocations2x, 0, defaultSampleLocations4x, |
+ 0, 0, 0, defaultSampleLocations8x, |
+ 0, 0, 0, 0, |
+ 0, 0, 0, defaultSampleLocations16x }; |
+ |
/////////////////////////////////////////////////////////////////////////////// |
// Used in the map of pixel configs to stencil format indices. This value is used to |
@@ -1477,7 +1500,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). |
@@ -1900,6 +1923,33 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, |
return true; |
} |
+void GrGLGpu::setCenteredSampleLocations(GrRenderTarget* rt, bool useCenteredSampleLocations) { |
+ GrGLRenderTarget* target = static_cast<GrGLRenderTarget*>(rt->asRenderTarget()); |
+ SkASSERT(0 != target->renderFBOID()); |
+ |
+ if (0 == rt->numRasterSamples() || |
+ useCenteredSampleLocations == rt->renderTargetPriv().usesCenteredSampleLocations()) { |
+ return; |
+ } |
+ |
+ if (!rt->renderTargetPriv().programmableSampleLocationsEnabled()) { |
+ GL_CALL(NamedFramebufferParameteri(target->renderFBOID(), |
+ GR_GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS, true)); |
+ rt->renderTargetPriv().setProgrammableSampleLocationsEnabled(true); |
+ } |
+ |
+ SkASSERT(rt->numRasterSamples() == 2 || |
+ rt->numRasterSamples() == 4 || |
+ rt->numRasterSamples() == 8 || |
+ rt->numRasterSamples() == 16); |
+ |
+ const GrGLfloat *sampleLocations = |
+ useCenteredSampleLocations ? gCenteredSampleLocations |
+ : gDefaultSampleLocations[rt->numRasterSamples()]; |
+ GL_CALL(NamedFramebufferSampleLocationsfv(target->renderFBOID(), 0, rt->numRasterSamples(), sampleLocations)); |
+ rt->renderTargetPriv().flagAsUsingCenteredSampleLocations(useCenteredSampleLocations); |
+} |
+ |
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound) { |
SkASSERT(target); |
@@ -2147,9 +2197,19 @@ 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 (rt->hasMixedSamples() && stencilEnabled && |
+ this->glCaps().glslCaps()->programmableSampleLocationsSupport()) { |
+ if (useHWAA) { |
+ setCenteredSampleLocations(rt, false); |
+ } else { |
+ setCenteredSampleLocations(rt, true); |
+ } |
+ useHWAA = true; |
+ } |
+ |
if (this->glCaps().multisampleDisableSupport()) { |
if (useHWAA) { |
if (kYes_TriState != fMSAAEnabled) { |
@@ -2932,7 +2992,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst, |
this->flushColorWrite(true); |
this->flushDither(false); |
this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
- this->flushHWAAState(dstRT, false); |
+ this->flushHWAAState(dstRT, false, false); |
this->disableScissor(); |
GrStencilSettings stencil; |
stencil.setDisabled(); |