| 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();
|
| }
|
|
|