Chromium Code Reviews| Index: src/gpu/gl/GrGpuGL.cpp |
| =================================================================== |
| --- src/gpu/gl/GrGpuGL.cpp (revision 8223) |
| +++ 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,46 @@ |
| } |
| 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(); |
|
robertphillips
2013/03/19 15:35:35
can this be "const GrIRect&"?
bsalomon
2013/03/19 19:06:42
No, it's x/y/width/height bottom-left origin.
|
| + 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 == |
|
robertphillips
2013/03/19 15:35:35
move up a line?
bsalomon
2013/03/19 19:06:42
Done.
|
| + 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(); |
| } |