Index: src/gpu/gl/GrGpuGL.cpp |
=================================================================== |
--- src/gpu/gl/GrGpuGL.cpp (revision 8240) |
+++ src/gpu/gl/GrGpuGL.cpp (working copy) |
@@ -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(); |
} |