Add support for IMG's MSAA extension.
Review URL: https://codereview.chromium.org/12875005
git-svn-id: http://skia.googlecode.com/svn/trunk@8241 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 8882934..e202a14 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -285,11 +285,12 @@
caps->fGeometryShaderSupport = this->glVersion() >= GR_GL_VER(3,2) &&
this->glslGeneration() >= k150_GrGLSLGeneration;
} else {
- caps->fShaderDerivativeSupport =
- this->hasExtension("GL_OES_standard_derivatives");
+ caps->fShaderDerivativeSupport = this->hasExtension("GL_OES_standard_derivatives");
}
- if (GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType()) {
+ if (GrGLCaps::kImaginationES_MSFBOType == this->glCaps().msFBOType()) {
+ GR_GL_GetIntegerv(this->glInterface(), GR_GL_MAX_SAMPLES_IMG, &caps->fMaxSampleCount);
+ } else if (GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType()) {
GR_GL_GetIntegerv(this->glInterface(), GR_GL_MAX_SAMPLES, &caps->fMaxSampleCount);
}
}
@@ -879,9 +880,11 @@
}
- // If we are using multisampling we will create two FBOS. We render
- // to one and then resolve to the texture bound to the other.
- if (desc->fSampleCnt > 0) {
+ // If we are using multisampling we will create two FBOS. We render to one and then resolve to
+ // 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;
}
@@ -921,16 +924,22 @@
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
goto FAILED;
}
- fGLContext.info().caps().markConfigAsValidColorAttachment(
- desc->fConfig);
+ fGLContext.info().caps().markConfigAsValidColorAttachment(desc->fConfig);
}
}
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
- GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
- GR_GL_COLOR_ATTACHMENT0,
- GR_GL_TEXTURE_2D,
- texID, 0));
+ if (GrGLCaps::kImaginationES_MSFBOType == this->glCaps().msFBOType() && desc->fSampleCnt > 0) {
+ GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
+ GR_GL_COLOR_ATTACHMENT0,
+ GR_GL_TEXTURE_2D,
+ texID, 0, desc->fSampleCnt));
+ } else {
+ GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
+ GR_GL_COLOR_ATTACHMENT0,
+ GR_GL_TEXTURE_2D,
+ texID, 0));
+ }
if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
@@ -1172,8 +1181,7 @@
return false;
}
-bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
- GrRenderTarget* rt) {
+bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTarget* rt) {
GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt;
GrGLuint fbo = glrt->renderFBOID();
@@ -1181,11 +1189,11 @@
if (NULL == sb) {
if (NULL != rt->getStencilBuffer()) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_STENCIL_ATTACHMENT,
- GR_GL_RENDERBUFFER, 0));
+ GR_GL_STENCIL_ATTACHMENT,
+ GR_GL_RENDERBUFFER, 0));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_DEPTH_ATTACHMENT,
- GR_GL_RENDERBUFFER, 0));
+ GR_GL_DEPTH_ATTACHMENT,
+ GR_GL_RENDERBUFFER, 0));
#if GR_DEBUG
GrGLenum status;
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
@@ -1194,27 +1202,26 @@
}
return true;
} else {
- GrGLStencilBuffer* glsb = (GrGLStencilBuffer*) sb;
+ GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb);
GrGLuint rb = glsb->renderbufferID();
fHWBoundRenderTarget = NULL;
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_STENCIL_ATTACHMENT,
- GR_GL_RENDERBUFFER, rb));
+ GR_GL_STENCIL_ATTACHMENT,
+ GR_GL_RENDERBUFFER, rb));
if (glsb->format().fPacked) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_DEPTH_ATTACHMENT,
- GR_GL_RENDERBUFFER, rb));
+ GR_GL_DEPTH_ATTACHMENT,
+ GR_GL_RENDERBUFFER, rb));
} else {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_DEPTH_ATTACHMENT,
- GR_GL_RENDERBUFFER, 0));
+ GR_GL_DEPTH_ATTACHMENT,
+ GR_GL_RENDERBUFFER, 0));
}
GrGLenum status;
- if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
- glsb->format())) {
+ if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(), glsb->format())) {
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
@@ -1767,47 +1774,45 @@
}
void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
-
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
-
if (rt->needsResolve()) {
- GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType());
- GrAssert(rt->textureFBOID() != rt->renderFBOID());
- GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
- rt->renderFBOID()));
- GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER,
- rt->textureFBOID()));
- // make sure we go through flushRenderTarget() since we've modified
- // the bound DRAW FBO ID.
- fHWBoundRenderTarget = NULL;
- const GrGLIRect& vp = rt->getViewport();
- const GrIRect dirtyRect = rt->getResolveRect();
- GrGLIRect r;
- r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
- dirtyRect.width(), dirtyRect.height(), target->origin());
+ // 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());
+ GrAssert(rt->textureFBOID() != rt->renderFBOID());
+ GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
+ GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
+ // make sure we go through flushRenderTarget() since we've modified
+ // the bound DRAW FBO ID.
+ fHWBoundRenderTarget = NULL;
+ const GrGLIRect& vp = rt->getViewport();
+ const GrIRect dirtyRect = rt->getResolveRect();
+ GrGLIRect r;
+ r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
+ dirtyRect.width(), dirtyRect.height(), target->origin());
- GrAutoTRestore<ScissorState> asr;
- if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
- // Apple's extension uses the scissor as the blit bounds.
- asr.reset(&fScissorState);
- fScissorState.fEnabled = true;
- fScissorState.fRect = dirtyRect;
- this->flushScissor();
- GL_CALL(ResolveMultisampleFramebuffer());
- } else {
- if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) {
- // this respects the scissor during the blit, so disable it.
- GrAssert(GrGLCaps::kDesktopEXT_MSFBOType ==
- this->glCaps().msFBOType());
+ GrAutoTRestore<ScissorState> asr;
+ if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
+ // Apple's extension uses the scissor as the blit bounds.
asr.reset(&fScissorState);
- fScissorState.fEnabled = false;
+ fScissorState.fEnabled = true;
+ fScissorState.fRect = dirtyRect;
this->flushScissor();
+ GL_CALL(ResolveMultisampleFramebuffer());
+ } else {
+ if (GrGLCaps::kDesktopARB_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();
+ }
+ int right = r.fLeft + r.fWidth;
+ int top = r.fBottom + r.fHeight;
+ GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
+ r.fLeft, r.fBottom, right, top,
+ GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
}
- int right = r.fLeft + r.fWidth;
- int top = r.fBottom + r.fHeight;
- GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
- r.fLeft, r.fBottom, right, top,
- GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
}
rt->flagAsResolved();
}