diff options
author | 2013-03-19 19:06:09 +0000 | |
---|---|---|
committer | 2013-03-19 19:06:09 +0000 | |
commit | f3a60c09b975f50bbd14215df10effffd2fd46e8 (patch) | |
tree | cbe688acf9cdecd769c92a7f3fbe860eb399711b /src/gpu | |
parent | 4c75f241cb75f202cfa51569ba8dc4749a28a9f7 (diff) |
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
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLDefines.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLInterface.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 131 | ||||
-rw-r--r-- | src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp | 4 |
6 files changed, 88 insertions, 63 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 04c2c3c720..a115b5d12e 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -251,6 +251,8 @@ void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterfa fMSFBOType = kDesktopEXT_MSFBOType; } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) { fMSFBOType = kAppleES_MSFBOType; + } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) { + fMSFBOType = kImaginationES_MSFBOType; } } else { if ((ctxInfo.version() >= GR_GL_VER(3,0)) || @@ -420,11 +422,13 @@ void GrGLCaps::print() const { GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType); GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType); GR_STATIC_ASSERT(3 == kAppleES_MSFBOType); + GR_STATIC_ASSERT(4 == kImaginationES_MSFBOType); static const char* gMSFBOExtStr[] = { "None", "ARB", "EXT", "Apple", + "IMG", }; GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]); GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors); diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index 2ecfb85840..83f4650c97 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -62,6 +62,10 @@ public: * GL_APPLE_framebuffer_multisample ES extension */ kAppleES_MSFBOType, + /** + * GL_IMG_multisampled_render_to_texture + */ + kImaginationES_MSFBOType, }; enum CoverageAAType { diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h index e0e8398795..2ab9570818 100644 --- a/src/gpu/gl/GrGLDefines.h +++ b/src/gpu/gl/GrGLDefines.h @@ -658,6 +658,8 @@ #define GR_GL_DEPTH24_STENCIL8 0x88F0 #define GR_GL_MAX_SAMPLES 0x8D57 +// GL_IMG_multisampled_render_to_texture uses a different value for GL_MAX_SAMPLES +#define GR_GL_MAX_SAMPLES_IMG 0x9135 #define GR_GL_RENDERBUFFER_WIDTH 0x8D42 #define GR_GL_RENDERBUFFER_HEIGHT 0x8D43 diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp index 0119a1e760..0c6bd8604d 100644 --- a/src/gpu/gl/GrGLInterface.cpp +++ b/src/gpu/gl/GrGLInterface.cpp @@ -323,6 +323,12 @@ bool GrGLInterface::validate(GrGLBinding binding) const { return false; } } + if (extensions.has("GL_IMG_multisampled_render_to_texture")) { + if (NULL == fRenderbufferStorageMultisample || + NULL == fFramebufferTexture2DMultisample) { + return false; + } + } } // On ES buffer mapping is an extension. On Desktop diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 8882934459..e202a14e40 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -285,11 +285,12 @@ void GrGpuGL::initCaps() { 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 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height, } - // 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 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height, 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 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt, 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 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, 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 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, } 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::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) { } 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()); - - 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()); + // 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 = 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(); } diff --git a/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp b/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp index 6fa9053cb8..6f81cab41c 100644 --- a/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp +++ b/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp @@ -124,6 +124,10 @@ const GrGLInterface* GrGLCreateNativeInterface() { interface->fDeleteRenderbuffers = glDeleteRenderbuffers; interface->fFramebufferRenderbuffer = glFramebufferRenderbuffer; interface->fFramebufferTexture2D = glFramebufferTexture2D; +#if GL_IMG_multisampled_render_to_texture + interface->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG; + interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleIMG; +#endif interface->fGenFramebuffers = glGenFramebuffers; interface->fGenRenderbuffers = glGenRenderbuffers; interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv; |