| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 | 8 |
| 9 #include "GrGpuGL.h" | 9 #include "GrGpuGL.h" |
| 10 #include "GrGLStencilBuffer.h" | 10 #include "GrGLStencilBuffer.h" |
| (...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 GrGLRenderTarget::Desc* desc) { | 774 GrGLRenderTarget::Desc* desc) { |
| 775 desc->fMSColorRenderbufferID = 0; | 775 desc->fMSColorRenderbufferID = 0; |
| 776 desc->fRTFBOID = 0; | 776 desc->fRTFBOID = 0; |
| 777 desc->fTexFBOID = 0; | 777 desc->fTexFBOID = 0; |
| 778 desc->fIsWrapped = false; | 778 desc->fIsWrapped = false; |
| 779 | 779 |
| 780 GrGLenum status; | 780 GrGLenum status; |
| 781 | 781 |
| 782 GrGLenum msColorFormat = 0; // suppress warning | 782 GrGLenum msColorFormat = 0; // suppress warning |
| 783 | 783 |
| 784 if (desc->fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFB
OType()) { |
| 785 goto FAILED; |
| 786 } |
| 787 |
| 784 GL_CALL(GenFramebuffers(1, &desc->fTexFBOID)); | 788 GL_CALL(GenFramebuffers(1, &desc->fTexFBOID)); |
| 785 if (!desc->fTexFBOID) { | 789 if (!desc->fTexFBOID) { |
| 786 goto FAILED; | 790 goto FAILED; |
| 787 } | 791 } |
| 788 | 792 |
| 789 | 793 |
| 790 // If we are using multisampling we will create two FBOS. We render to one a
nd then resolve to | 794 // If we are using multisampling we will create two FBOS. We render to one a
nd then resolve to |
| 791 // the texture bound to the other. The exception is the IMG multisample exte
nsion. With this | 795 // the texture bound to the other. The exception is the IMG multisample exte
nsion. With this |
| 792 // extension the texture is multisampled when rendered to and then auto-reso
lves it when it is | 796 // extension the texture is multisampled when rendered to and then auto-reso
lves it when it is |
| 793 // rendered from. | 797 // rendered from. |
| 794 if (desc->fSampleCnt > 0 && GrGLCaps::kImaginationES_MSFBOType != this->glCa
ps().msFBOType()) { | 798 if (desc->fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) { |
| 795 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) { | |
| 796 goto FAILED; | |
| 797 } | |
| 798 GL_CALL(GenFramebuffers(1, &desc->fRTFBOID)); | 799 GL_CALL(GenFramebuffers(1, &desc->fRTFBOID)); |
| 799 GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID)); | 800 GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID)); |
| 800 if (!desc->fRTFBOID || | 801 if (!desc->fRTFBOID || |
| 801 !desc->fMSColorRenderbufferID || | 802 !desc->fMSColorRenderbufferID || |
| 802 !this->configToGLFormats(desc->fConfig, | 803 !this->configToGLFormats(desc->fConfig, |
| 803 // GLES requires sized internal formats | 804 // GLES requires sized internal formats |
| 804 kES2_GrGLBinding == this->glBinding(), | 805 kES2_GrGLBinding == this->glBinding(), |
| 805 &msColorFormat, NULL, NULL)) { | 806 &msColorFormat, |
| 807 NULL, |
| 808 NULL)) { |
| 806 goto FAILED; | 809 goto FAILED; |
| 807 } | 810 } |
| 808 } else { | 811 } else { |
| 809 desc->fRTFBOID = desc->fTexFBOID; | 812 desc->fRTFBOID = desc->fTexFBOID; |
| 810 } | 813 } |
| 811 | 814 |
| 812 // below here we may bind the FBO | 815 // below here we may bind the FBO |
| 813 fHWBoundRenderTarget = NULL; | 816 fHWBoundRenderTarget = NULL; |
| 814 if (desc->fRTFBOID != desc->fTexFBOID) { | 817 if (desc->fRTFBOID != desc->fTexFBOID) { |
| 815 GrAssert(desc->fSampleCnt > 0); | 818 GrAssert(desc->fSampleCnt > 0); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 829 if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) { | 832 if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) { |
| 830 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 833 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 831 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 834 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 832 goto FAILED; | 835 goto FAILED; |
| 833 } | 836 } |
| 834 fGLContext.info().caps()->markConfigAsValidColorAttachment(desc->fCo
nfig); | 837 fGLContext.info().caps()->markConfigAsValidColorAttachment(desc->fCo
nfig); |
| 835 } | 838 } |
| 836 } | 839 } |
| 837 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID)); | 840 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID)); |
| 838 | 841 |
| 839 if (GrGLCaps::kImaginationES_MSFBOType == this->glCaps().msFBOType() && desc
->fSampleCnt > 0) { | 842 if (this->glCaps().usesImplicitMSAAResolve() && desc->fSampleCnt > 0) { |
| 840 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, | 843 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, |
| 841 GR_GL_COLOR_ATTACHMENT0, | 844 GR_GL_COLOR_ATTACHMENT0, |
| 842 GR_GL_TEXTURE_2D, | 845 GR_GL_TEXTURE_2D, |
| 843 texID, 0, desc->fSampleCnt)); | 846 texID, 0, desc->fSampleCnt)); |
| 844 } else { | 847 } else { |
| 845 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, | 848 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, |
| 846 GR_GL_COLOR_ATTACHMENT0, | 849 GR_GL_COLOR_ATTACHMENT0, |
| 847 GR_GL_TEXTURE_2D, | 850 GR_GL_TEXTURE_2D, |
| 848 texID, 0)); | 851 texID, 0)); |
| 849 } | 852 } |
| (...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1674 GrCrash("Unexpected path fill."); | 1677 GrCrash("Unexpected path fill."); |
| 1675 return; // suppress unused var warning. | 1678 return; // suppress unused var warning. |
| 1676 } | 1679 } |
| 1677 GrGLint writeMask = fStencilSettings.writeMask(GrStencilSettings::kFront_Fac
e); | 1680 GrGLint writeMask = fStencilSettings.writeMask(GrStencilSettings::kFront_Fac
e); |
| 1678 GL_CALL(StencilFillPath(id, fillMode, writeMask)); | 1681 GL_CALL(StencilFillPath(id, fillMode, writeMask)); |
| 1679 } | 1682 } |
| 1680 | 1683 |
| 1681 void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) { | 1684 void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) { |
| 1682 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); | 1685 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); |
| 1683 if (rt->needsResolve()) { | 1686 if (rt->needsResolve()) { |
| 1684 // The IMG extension automatically resolves the texture when it is read. | 1687 // Some extensions automatically resolves the texture when it is read. |
| 1685 if (GrGLCaps::kImaginationES_MSFBOType != this->glCaps().msFBOType()) { | 1688 if (this->glCaps().usesMSAARenderBuffers()) { |
| 1686 GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType()); | |
| 1687 GrAssert(rt->textureFBOID() != rt->renderFBOID()); | 1689 GrAssert(rt->textureFBOID() != rt->renderFBOID()); |
| 1688 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID())); | 1690 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID())); |
| 1689 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()))
; | 1691 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()))
; |
| 1690 // make sure we go through flushRenderTarget() since we've modified | 1692 // make sure we go through flushRenderTarget() since we've modified |
| 1691 // the bound DRAW FBO ID. | 1693 // the bound DRAW FBO ID. |
| 1692 fHWBoundRenderTarget = NULL; | 1694 fHWBoundRenderTarget = NULL; |
| 1693 const GrGLIRect& vp = rt->getViewport(); | 1695 const GrGLIRect& vp = rt->getViewport(); |
| 1694 const GrIRect dirtyRect = rt->getResolveRect(); | 1696 const GrIRect dirtyRect = rt->getResolveRect(); |
| 1695 GrGLIRect r; | 1697 GrGLIRect r; |
| 1696 r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop, | 1698 r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop, |
| 1697 dirtyRect.width(), dirtyRect.height(), target->origi
n()); | 1699 dirtyRect.width(), dirtyRect.height(), target->origi
n()); |
| 1698 | 1700 |
| 1699 GrAutoTRestore<ScissorState> asr; | 1701 GrAutoTRestore<ScissorState> asr; |
| 1700 if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) { | 1702 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { |
| 1701 // Apple's extension uses the scissor as the blit bounds. | 1703 // Apple's extension uses the scissor as the blit bounds. |
| 1702 asr.reset(&fScissorState); | 1704 asr.reset(&fScissorState); |
| 1703 fScissorState.fEnabled = true; | 1705 fScissorState.fEnabled = true; |
| 1704 fScissorState.fRect = dirtyRect; | 1706 fScissorState.fRect = dirtyRect; |
| 1705 this->flushScissor(); | 1707 this->flushScissor(); |
| 1706 GL_CALL(ResolveMultisampleFramebuffer()); | 1708 GL_CALL(ResolveMultisampleFramebuffer()); |
| 1707 } else { | 1709 } else { |
| 1708 if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType(
)) { | 1710 if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType
()) { |
| 1709 // this respects the scissor during the blit, so disable it. | 1711 // this respects the scissor during the blit, so disable it. |
| 1710 GrAssert(GrGLCaps::kDesktopEXT_MSFBOType == this->glCaps().m
sFBOType()); | |
| 1711 asr.reset(&fScissorState); | 1712 asr.reset(&fScissorState); |
| 1712 fScissorState.fEnabled = false; | 1713 fScissorState.fEnabled = false; |
| 1713 this->flushScissor(); | 1714 this->flushScissor(); |
| 1714 } | 1715 } |
| 1715 int right = r.fLeft + r.fWidth; | 1716 int right = r.fLeft + r.fWidth; |
| 1716 int top = r.fBottom + r.fHeight; | 1717 int top = r.fBottom + r.fHeight; |
| 1717 GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top, | 1718 GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top, |
| 1718 r.fLeft, r.fBottom, right, top, | 1719 r.fLeft, r.fBottom, right, top, |
| 1719 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | 1720 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
| 1720 } | 1721 } |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 fHWActiveTextureUnitIdx = SPARE_TEX_UNIT; | 2227 fHWActiveTextureUnitIdx = SPARE_TEX_UNIT; |
| 2227 } | 2228 } |
| 2228 } | 2229 } |
| 2229 | 2230 |
| 2230 namespace { | 2231 namespace { |
| 2231 // Determines whether glBlitFramebuffer could be used between src and dst. | 2232 // Determines whether glBlitFramebuffer could be used between src and dst. |
| 2232 inline bool can_blit_framebuffer(const GrSurface* dst, | 2233 inline bool can_blit_framebuffer(const GrSurface* dst, |
| 2233 const GrSurface* src, | 2234 const GrSurface* src, |
| 2234 const GrGpuGL* gpu, | 2235 const GrGpuGL* gpu, |
| 2235 bool* wouldNeedTempFBO = NULL) { | 2236 bool* wouldNeedTempFBO = NULL) { |
| 2236 if (gpu->isConfigRenderable(dst->config()) && gpu->isConfigRenderable(src->c
onfig()) && | 2237 if (gpu->isConfigRenderable(dst->config()) && |
| 2237 (GrGLCaps::kDesktopEXT_MSFBOType == gpu->glCaps().msFBOType() || | 2238 gpu->isConfigRenderable(src->config()) && |
| 2238 GrGLCaps::kDesktopARB_MSFBOType == gpu->glCaps().msFBOType())) { | 2239 gpu->glCaps().usesMSAARenderBuffers()) { |
| 2239 if (NULL != wouldNeedTempFBO) { | 2240 if (NULL != wouldNeedTempFBO) { |
| 2240 *wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->as
RenderTarget(); | 2241 *wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->as
RenderTarget(); |
| 2241 } | 2242 } |
| 2242 return true; | 2243 return true; |
| 2243 } else { | 2244 } else { |
| 2244 return false; | 2245 return false; |
| 2245 } | 2246 } |
| 2246 } | 2247 } |
| 2247 | 2248 |
| 2248 inline bool can_copy_texsubimage(const GrSurface* dst, | 2249 inline bool can_copy_texsubimage(const GrSurface* dst, |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2404 srcRect.height(), | 2405 srcRect.height(), |
| 2405 src->origin()); | 2406 src->origin()); |
| 2406 dstGLRect.setRelativeTo(dstVP, | 2407 dstGLRect.setRelativeTo(dstVP, |
| 2407 dstRect.fLeft, | 2408 dstRect.fLeft, |
| 2408 dstRect.fTop, | 2409 dstRect.fTop, |
| 2409 dstRect.width(), | 2410 dstRect.width(), |
| 2410 dstRect.height(), | 2411 dstRect.height(), |
| 2411 dst->origin()); | 2412 dst->origin()); |
| 2412 | 2413 |
| 2413 GrAutoTRestore<ScissorState> asr; | 2414 GrAutoTRestore<ScissorState> asr; |
| 2414 if (GrGLCaps::kDesktopEXT_MSFBOType == this->glCaps().msFBOType()) { | 2415 if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType())
{ |
| 2415 // The EXT version applies the scissor during the blit, so disab
le it. | 2416 // The EXT version applies the scissor during the blit, so disab
le it. |
| 2416 asr.reset(&fScissorState); | 2417 asr.reset(&fScissorState); |
| 2417 fScissorState.fEnabled = false; | 2418 fScissorState.fEnabled = false; |
| 2418 this->flushScissor(); | 2419 this->flushScissor(); |
| 2419 } | 2420 } |
| 2420 GrGLint srcY0; | 2421 GrGLint srcY0; |
| 2421 GrGLint srcY1; | 2422 GrGLint srcY1; |
| 2422 // Does the blit need to y-mirror or not? | 2423 // Does the blit need to y-mirror or not? |
| 2423 if (src->origin() == dst->origin()) { | 2424 if (src->origin() == dst->origin()) { |
| 2424 srcY0 = srcGLRect.fBottom; | 2425 srcY0 = srcGLRect.fBottom; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2501 this->setVertexArrayID(gpu, 0); | 2502 this->setVertexArrayID(gpu, 0); |
| 2502 } | 2503 } |
| 2503 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2504 int attrCount = gpu->glCaps().maxVertexAttributes(); |
| 2504 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 2505 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
| 2505 fDefaultVertexArrayAttribState.resize(attrCount); | 2506 fDefaultVertexArrayAttribState.resize(attrCount); |
| 2506 } | 2507 } |
| 2507 attribState = &fDefaultVertexArrayAttribState; | 2508 attribState = &fDefaultVertexArrayAttribState; |
| 2508 } | 2509 } |
| 2509 return attribState; | 2510 return attribState; |
| 2510 } | 2511 } |
| OLD | NEW |