Add support for GL_NV_framebuffer_multisample_coverage
Review URL: http://codereview.appspot.com/6005043
git-svn-id: http://skia.googlecode.com/svn/trunk@3651 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 5361967..c7e9380 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -9,6 +9,7 @@
#include "GrGLCaps.h"
#include "GrGLContextInfo.h"
+#include "SkTSearch.h"
GrGLCaps::GrGLCaps() {
this->reset();
@@ -19,6 +20,7 @@
fStencilFormats.reset();
fStencilVerifiedColorConfigs.reset();
fMSFBOType = kNone_MSFBOType;
+ fCoverageAAType = kNone_CoverageAAType;
fMaxFragmentUniformVectors = 0;
fRGBA8RenderbufferSupport = false;
fBGRAFormatSupport = false;
@@ -43,6 +45,8 @@
fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs;
fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors;
fMSFBOType = caps.fMSFBOType;
+ fCoverageAAType = caps.fCoverageAAType;
+ fMSAACoverageModes = caps.fMSAACoverageModes;
fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
fBGRAFormatSupport = caps.fBGRAFormatSupport;
fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat;
@@ -143,6 +147,22 @@
this->initStencilFormats(ctxInfo);
}
+namespace {
+int coverage_mode_compare(const GrGLCaps::MSAACoverageMode* left,
+ const GrGLCaps::MSAACoverageMode* right) {
+ if (left->fCoverageSampleCnt < right->fCoverageSampleCnt) {
+ return -1;
+ } else if (right->fCoverageSampleCnt < left->fCoverageSampleCnt) {
+ return 1;
+ } else if (left->fColorSampleCnt < right->fColorSampleCnt) {
+ return -1;
+ } else if (right->fColorSampleCnt < left->fColorSampleCnt) {
+ return 1;
+ }
+ return 0;
+}
+}
+
void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo) {
fMSFBOType = kNone_MSFBOType;
@@ -152,8 +172,8 @@
// and fbo_blit extensions.
fMSFBOType = kDesktopEXT_MSFBOType;
} else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
- fMSFBOType = kAppleES_MSFBOType;
- }
+ fMSFBOType = kAppleES_MSFBOType;
+ }
} else {
if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
@@ -162,6 +182,52 @@
ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
fMSFBOType = GrGLCaps::kDesktopEXT_MSFBOType;
}
+ // TODO: We could populate fMSAACoverageModes using GetInternalformativ
+ // on GL 4.2+. It's format-specific, though. See also
+ // http://code.google.com/p/skia/issues/detail?id=470 about using actual
+ // rather than requested sample counts in cache key.
+ if (ctxInfo.hasExtension("GL_NV_framebuffer_multisample_coverage")) {
+ fCoverageAAType = kNVDesktop_CoverageAAType;
+ GrGLint count;
+ GR_GL_GetIntegerv(ctxInfo.interface(),
+ GR_GL_MAX_MULTISAMPLE_COVERAGE_MODES,
+ &count);
+ fMSAACoverageModes.setCount(count);
+ GR_GL_GetIntegerv(ctxInfo.interface(),
+ GR_GL_MULTISAMPLE_COVERAGE_MODES,
+ (int*)&fMSAACoverageModes[0]);
+ // The NV driver seems to return the modes already sorted but the
+ // spec doesn't require this. So we sort.
+ SkQSortCompareProc compareProc =
+ reinterpret_cast<SkQSortCompareProc>(&coverage_mode_compare);
+ SkQSort(&fMSAACoverageModes[0],
+ count,
+ sizeof(MSAACoverageMode),
+ compareProc);
+ }
+ }
+}
+
+const GrGLCaps::MSAACoverageMode& GrGLCaps::getMSAACoverageMode(
+ int desiredSampleCount) const {
+ static const MSAACoverageMode kNoneMode = {0, 0};
+ if (0 == fMSAACoverageModes.count()) {
+ return kNoneMode;
+ } else {
+ GrAssert(kNone_CoverageAAType != fCoverageAAType);
+ int max = (fMSAACoverageModes.end() - 1)->fCoverageSampleCnt;
+ desiredSampleCount = GrMin(desiredSampleCount, max);
+ MSAACoverageMode desiredMode = {desiredSampleCount, 0};
+ int idx = SkTSearch<MSAACoverageMode>(&fMSAACoverageModes[0],
+ fMSAACoverageModes.count(),
+ desiredMode,
+ sizeof(MSAACoverageMode),
+ &coverage_mode_compare);
+ if (idx < 0) {
+ idx = ~idx;
+ }
+ GrAssert(idx >= 0 && idx < fMSAACoverageModes.count());
+ return fMSAACoverageModes[idx];
}
}