fShaderDerivativeSupport = ctxInfo.hasExtension("GL_OES_standard_derivatives");
}
- if (GrGLCaps::kImaginationES_MSFBOType == fMSFBOType) {
+ if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxSampleCount);
} else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxSampleCount);
if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
// chrome's extension is equivalent to the EXT msaa
// and fbo_blit extensions.
- fMSFBOType = kDesktopEXT_MSFBOType;
+ fMSFBOType = kDesktop_EXT_MSFBOType;
} else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
- fMSFBOType = kAppleES_MSFBOType;
+ fMSFBOType = kES_Apple_MSFBOType;
+ } else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
+ fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
} else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
- fMSFBOType = kImaginationES_MSFBOType;
+ fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
}
} else {
if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
- fMSFBOType = GrGLCaps::kDesktopARB_MSFBOType;
+ fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
} else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
- fMSFBOType = GrGLCaps::kDesktopEXT_MSFBOType;
+ fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
}
// TODO: We could populate fMSAACoverageModes using GetInternalformativ
// on GL 4.2+. It's format-specific, though. See also
}
GR_STATIC_ASSERT(0 == kNone_MSFBOType);
- GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType);
- GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType);
- GR_STATIC_ASSERT(3 == kAppleES_MSFBOType);
- GR_STATIC_ASSERT(4 == kImaginationES_MSFBOType);
+ GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
+ GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
+ GR_STATIC_ASSERT(3 == kES_Apple_MSFBOType);
+ GR_STATIC_ASSERT(4 == kES_IMG_MsToTexture_MSFBOType);
+ GR_STATIC_ASSERT(5 == kES_EXT_MsToTexture_MSFBOType);
static const char* gMSFBOExtStr[] = {
"None",
"ARB",
"EXT",
"Apple",
- "IMG",
+ "IMG MS To Texture",
+ "EXT MS To Texture",
};
GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
/**
* GL3.0-style MSAA FBO (GL_ARB_framebuffer_object)
*/
- kDesktopARB_MSFBOType,
+ kDesktop_ARB_MSFBOType,
/**
* earlier GL_EXT_framebuffer* extensions
*/
- kDesktopEXT_MSFBOType,
+ kDesktop_EXT_MSFBOType,
/**
* GL_APPLE_framebuffer_multisample ES extension
*/
- kAppleES_MSFBOType,
+ kES_Apple_MSFBOType,
/**
- * GL_IMG_multisampled_render_to_texture
+ * GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers.
+ * Instead the texture is multisampled when bound to the FBO and then resolved automatically
+ * when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call
+ * GR_GL_MAX_SAMPLES_IMG).
*/
- kImaginationES_MSFBOType,
+ kES_IMG_MsToTexture_MSFBOType,
+ /**
+ * GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard
+ * GL_MAX_SAMPLES value.
+ */
+ kES_EXT_MsToTexture_MSFBOType,
};
enum CoverageAAType {
MSFBOType msFBOType() const { return fMSFBOType; }
/**
+ * Does the supported MSAA FBO extension have MSAA renderbuffers?
+ */
+ bool usesMSAARenderBuffers() const {
+ return kNone_MSFBOType != fMSFBOType &&
+ kES_IMG_MsToTexture_MSFBOType != fMSFBOType &&
+ kES_EXT_MsToTexture_MSFBOType != fMSFBOType;
+ }
+
+ /**
+ * Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and
+ * then implicitly resolved when read.
+ */
+ bool usesImplicitMSAAResolve() const {
+ return kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
+ kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
+ }
+
+ /**
* Reports the type of coverage sample AA support.
*/
CoverageAAType coverageAAType() const { return fCoverageAAType; }
return false;
}
}
- if (extensions.has("GL_IMG_multisampled_render_to_texture")) {
+ if (extensions.has("GL_IMG_multisampled_render_to_texture") ||
+ extensions.has("GL_EXT_multisampled_render_to_texture")) {
if (NULL == fRenderbufferStorageMultisample ||
NULL == fFramebufferTexture2DMultisample) {
return false;
GrGLenum msColorFormat = 0; // suppress warning
+ if (desc->fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
+ goto FAILED;
+ }
+
GL_CALL(GenFramebuffers(1, &desc->fTexFBOID));
if (!desc->fTexFBOID) {
goto FAILED;
// the texture bound to the other. The exception is the IMG multisample extension. With this
// extension the texture is multisampled when rendered to and then auto-resolves it when it is
// rendered from.
- if (desc->fSampleCnt > 0 && GrGLCaps::kImaginationES_MSFBOType != this->glCaps().msFBOType()) {
- if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
- goto FAILED;
- }
+ if (desc->fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) {
GL_CALL(GenFramebuffers(1, &desc->fRTFBOID));
GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID));
if (!desc->fRTFBOID ||
!this->configToGLFormats(desc->fConfig,
// GLES requires sized internal formats
kES2_GrGLBinding == this->glBinding(),
- &msColorFormat, NULL, NULL)) {
+ &msColorFormat,
+ NULL,
+ NULL)) {
goto FAILED;
}
} else {
}
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
- if (GrGLCaps::kImaginationES_MSFBOType == this->glCaps().msFBOType() && desc->fSampleCnt > 0) {
+ if (this->glCaps().usesImplicitMSAAResolve() && desc->fSampleCnt > 0) {
GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
GR_GL_COLOR_ATTACHMENT0,
GR_GL_TEXTURE_2D,
void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
if (rt->needsResolve()) {
- // The IMG extension automatically resolves the texture when it is read.
- if (GrGLCaps::kImaginationES_MSFBOType != this->glCaps().msFBOType()) {
- GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType());
+ // Some extensions automatically resolves the texture when it is read.
+ if (this->glCaps().usesMSAARenderBuffers()) {
GrAssert(rt->textureFBOID() != rt->renderFBOID());
GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
dirtyRect.width(), dirtyRect.height(), target->origin());
GrAutoTRestore<ScissorState> asr;
- if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
+ if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
// Apple's extension uses the scissor as the blit bounds.
asr.reset(&fScissorState);
fScissorState.fEnabled = true;
this->flushScissor();
GL_CALL(ResolveMultisampleFramebuffer());
} else {
- if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) {
+ if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) {
// this respects the scissor during the blit, so disable it.
- GrAssert(GrGLCaps::kDesktopEXT_MSFBOType == this->glCaps().msFBOType());
asr.reset(&fScissorState);
fScissorState.fEnabled = false;
this->flushScissor();
const GrSurface* src,
const GrGpuGL* gpu,
bool* wouldNeedTempFBO = NULL) {
- if (gpu->isConfigRenderable(dst->config()) && gpu->isConfigRenderable(src->config()) &&
- (GrGLCaps::kDesktopEXT_MSFBOType == gpu->glCaps().msFBOType() ||
- GrGLCaps::kDesktopARB_MSFBOType == gpu->glCaps().msFBOType())) {
+ if (gpu->isConfigRenderable(dst->config()) &&
+ gpu->isConfigRenderable(src->config()) &&
+ gpu->glCaps().usesMSAARenderBuffers()) {
if (NULL != wouldNeedTempFBO) {
*wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->asRenderTarget();
}
dst->origin());
GrAutoTRestore<ScissorState> asr;
- if (GrGLCaps::kDesktopEXT_MSFBOType == this->glCaps().msFBOType()) {
+ if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) {
// The EXT version applies the scissor during the blit, so disable it.
asr.reset(&fScissorState);
fScissorState.fEnabled = false;
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "gl/GrGLExtensions.h"
#include "gl/GrGLInterface.h"
#ifndef GL_GLEXT_PROTOTYPES
const GrGLInterface* GrGLCreateNativeInterface() {
static SkAutoTUnref<GrGLInterface> glInterface;
if (!glInterface.get()) {
+ GrGLExtensions extensions;
+ if (!extensions.init(kES2_GrGLBinding, glGetString, NULL, glGetIntegerv)) {
+ return NULL;
+ }
GrGLInterface* interface = new GrGLInterface;
glInterface.reset(interface);
interface->fBindingsExported = kES2_GrGLBinding;
interface->fDeleteRenderbuffers = glDeleteRenderbuffers;
interface->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
interface->fFramebufferTexture2D = glFramebufferTexture2D;
+ if (extensions.has("GL_EXT_multisampled_render_to_texture")) {
+#if GL_EXT_multisampled_render_to_texture
+ interface->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleEXT;
+ interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
+#else
+ interface->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleEXT");
+ interface->fRenderbufferStorageMultisample = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleEXT");
+#endif
+ } else if (extensions.has("GL_IMG_multisampled_render_to_texture")) {
#if GL_IMG_multisampled_render_to_texture
- interface->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG;
- interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleIMG;
+ interface->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG;
+ interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleIMG;
+#else
+ interface->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleIMG");
+ interface->fRenderbufferStorageMultisample = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleIMG");
#endif
+ }
interface->fGenFramebuffers = glGenFramebuffers;
interface->fGenRenderbuffers = glGenRenderbuffers;
interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;