| 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 "GrGLGpu.h" | 9 #include "GrGLGpu.h" |
| 10 #include "GrGLStencilBuffer.h" | 10 #include "GrGLStencilBuffer.h" |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 SkDebugf("\n"); | 144 SkDebugf("\n"); |
| 145 SkDebugf("%s", this->glCaps().dump().c_str()); | 145 SkDebugf("%s", this->glCaps().dump().c_str()); |
| 146 } | 146 } |
| 147 | 147 |
| 148 fProgramCache = SkNEW_ARGS(ProgramCache, (this)); | 148 fProgramCache = SkNEW_ARGS(ProgramCache, (this)); |
| 149 | 149 |
| 150 SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVe
rtexAttribs); | 150 SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVe
rtexAttribs); |
| 151 | 151 |
| 152 fLastSuccessfulStencilFmtIdx = 0; | 152 fLastSuccessfulStencilFmtIdx = 0; |
| 153 fHWProgramID = 0; | 153 fHWProgramID = 0; |
| 154 fTempSrcFBOID = 0; |
| 155 fTempDstFBOID = 0; |
| 156 fStencilClearFBOID = 0; |
| 154 | 157 |
| 155 if (this->glCaps().pathRenderingSupport()) { | 158 if (this->glCaps().pathRenderingSupport()) { |
| 156 fPathRendering.reset(new GrGLPathRendering(this)); | 159 fPathRendering.reset(new GrGLPathRendering(this)); |
| 157 } | 160 } |
| 158 } | 161 } |
| 159 | 162 |
| 160 GrGLGpu::~GrGLGpu() { | 163 GrGLGpu::~GrGLGpu() { |
| 161 if (0 != fHWProgramID) { | 164 if (0 != fHWProgramID) { |
| 162 // detach the current program so there is no confusion on OpenGL's part | 165 // detach the current program so there is no confusion on OpenGL's part |
| 163 // that we want it to be deleted | 166 // that we want it to be deleted |
| 164 SkASSERT(fHWProgramID == fCurrentProgram->programID()); | 167 SkASSERT(fHWProgramID == fCurrentProgram->programID()); |
| 165 GL_CALL(UseProgram(0)); | 168 GL_CALL(UseProgram(0)); |
| 166 } | 169 } |
| 167 | 170 |
| 168 if (fTempSrcFBO) { | 171 if (0 != fTempSrcFBOID) { |
| 169 fTempSrcFBO->release(this->glInterface()); | 172 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); |
| 170 fTempSrcFBO.reset(NULL); | |
| 171 } | 173 } |
| 172 if (fTempDstFBO) { | 174 if (0 != fTempDstFBOID) { |
| 173 fTempDstFBO->release(this->glInterface()); | 175 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); |
| 174 fTempDstFBO.reset(NULL); | |
| 175 } | 176 } |
| 176 if (fStencilClearFBO) { | 177 if (0 != fStencilClearFBOID) { |
| 177 fStencilClearFBO->release(this->glInterface()); | 178 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); |
| 178 fStencilClearFBO.reset(NULL); | |
| 179 } | 179 } |
| 180 | 180 |
| 181 delete fProgramCache; | 181 delete fProgramCache; |
| 182 } | 182 } |
| 183 | 183 |
| 184 void GrGLGpu::contextAbandoned() { | 184 void GrGLGpu::contextAbandoned() { |
| 185 INHERITED::contextAbandoned(); | 185 INHERITED::contextAbandoned(); |
| 186 fProgramCache->abandon(); | 186 fProgramCache->abandon(); |
| 187 fHWProgramID = 0; | 187 fHWProgramID = 0; |
| 188 if (fTempSrcFBO) { | 188 fTempSrcFBOID = 0; |
| 189 fTempSrcFBO->abandon(); | 189 fTempDstFBOID = 0; |
| 190 fTempSrcFBO.reset(NULL); | 190 fStencilClearFBOID = 0; |
| 191 } | |
| 192 if (fTempDstFBO) { | |
| 193 fTempDstFBO->abandon(); | |
| 194 fTempDstFBO.reset(NULL); | |
| 195 } | |
| 196 if (fStencilClearFBO) { | |
| 197 fStencilClearFBO->abandon(); | |
| 198 fStencilClearFBO.reset(NULL); | |
| 199 } | |
| 200 | |
| 201 if (this->glCaps().pathRenderingSupport()) { | 191 if (this->glCaps().pathRenderingSupport()) { |
| 202 this->glPathRendering()->abandonGpuResources(); | 192 this->glPathRendering()->abandonGpuResources(); |
| 203 } | 193 } |
| 204 } | 194 } |
| 205 | 195 |
| 206 /////////////////////////////////////////////////////////////////////////////// | 196 /////////////////////////////////////////////////////////////////////////////// |
| 207 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, | 197 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, |
| 208 GrPixelConfig surfaceConfig) co
nst { | 198 GrPixelConfig surfaceConfig) co
nst { |
| 209 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig
) { | 199 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig
) { |
| 210 return kBGRA_8888_GrPixelConfig; | 200 return kBGRA_8888_GrPixelConfig; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 fHWStencilSettings.invalidate(); | 324 fHWStencilSettings.invalidate(); |
| 335 fHWStencilTestEnabled = kUnknown_TriState; | 325 fHWStencilTestEnabled = kUnknown_TriState; |
| 336 } | 326 } |
| 337 | 327 |
| 338 // Vertex | 328 // Vertex |
| 339 if (resetBits & kVertex_GrGLBackendState) { | 329 if (resetBits & kVertex_GrGLBackendState) { |
| 340 fHWGeometryState.invalidate(); | 330 fHWGeometryState.invalidate(); |
| 341 } | 331 } |
| 342 | 332 |
| 343 if (resetBits & kRenderTarget_GrGLBackendState) { | 333 if (resetBits & kRenderTarget_GrGLBackendState) { |
| 344 for (size_t i = 0; i < SK_ARRAY_COUNT(fHWFBOBinding); ++i) { | 334 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 345 fHWFBOBinding[i].invalidate(); | |
| 346 } | |
| 347 } | 335 } |
| 348 | 336 |
| 349 if (resetBits & kPathRendering_GrGLBackendState) { | 337 if (resetBits & kPathRendering_GrGLBackendState) { |
| 350 if (this->caps()->pathRenderingSupport()) { | 338 if (this->caps()->pathRenderingSupport()) { |
| 351 this->glPathRendering()->resetContext(); | 339 this->glPathRendering()->resetContext(); |
| 352 } | 340 } |
| 353 } | 341 } |
| 354 | 342 |
| 355 // we assume these values | 343 // we assume these values |
| 356 if (resetBits & kPixelStore_GrGLBackendState) { | 344 if (resetBits & kPixelStore_GrGLBackendState) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 } | 425 } |
| 438 if (NULL == texture) { | 426 if (NULL == texture) { |
| 439 return NULL; | 427 return NULL; |
| 440 } | 428 } |
| 441 | 429 |
| 442 return texture; | 430 return texture; |
| 443 } | 431 } |
| 444 | 432 |
| 445 GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
sc& wrapDesc) { | 433 GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
sc& wrapDesc) { |
| 446 GrGLRenderTarget::IDDesc idDesc; | 434 GrGLRenderTarget::IDDesc idDesc; |
| 447 GrGLuint fboID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); | 435 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); |
| 448 idDesc.fRenderFBO.reset(SkNEW_ARGS(GrGLFBO, (fboID))); | |
| 449 idDesc.fMSColorRenderbufferID = 0; | 436 idDesc.fMSColorRenderbufferID = 0; |
| 437 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; |
| 450 idDesc.fLifeCycle = GrGpuResource::kWrapped_LifeCycle; | 438 idDesc.fLifeCycle = GrGpuResource::kWrapped_LifeCycle; |
| 451 | 439 |
| 452 GrSurfaceDesc desc; | 440 GrSurfaceDesc desc; |
| 453 desc.fConfig = wrapDesc.fConfig; | 441 desc.fConfig = wrapDesc.fConfig; |
| 454 desc.fFlags = kCheckAllocation_GrSurfaceFlag; | 442 desc.fFlags = kCheckAllocation_GrSurfaceFlag; |
| 455 desc.fWidth = wrapDesc.fWidth; | 443 desc.fWidth = wrapDesc.fWidth; |
| 456 desc.fHeight = wrapDesc.fHeight; | 444 desc.fHeight = wrapDesc.fHeight; |
| 457 desc.fSampleCnt = wrapDesc.fSampleCnt; | 445 desc.fSampleCnt = wrapDesc.fSampleCnt; |
| 458 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); | 446 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); |
| 459 | 447 |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 case GrGLCaps::kNone_MSFBOType: | 807 case GrGLCaps::kNone_MSFBOType: |
| 820 SkFAIL("Shouldn't be here if we don't support multisampled renderbuf
fers."); | 808 SkFAIL("Shouldn't be here if we don't support multisampled renderbuf
fers."); |
| 821 break; | 809 break; |
| 822 } | 810 } |
| 823 return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface())); | 811 return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface())); |
| 824 } | 812 } |
| 825 | 813 |
| 826 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, bool budgeted
, GrGLuint texID, | 814 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, bool budgeted
, GrGLuint texID, |
| 827 GrGLRenderTarget::IDDesc* idDesc) { | 815 GrGLRenderTarget::IDDesc* idDesc) { |
| 828 idDesc->fMSColorRenderbufferID = 0; | 816 idDesc->fMSColorRenderbufferID = 0; |
| 817 idDesc->fRTFBOID = 0; |
| 818 idDesc->fTexFBOID = 0; |
| 829 idDesc->fLifeCycle = budgeted ? GrGpuResource::kCached_LifeCycle : | 819 idDesc->fLifeCycle = budgeted ? GrGpuResource::kCached_LifeCycle : |
| 830 GrGpuResource::kUncached_LifeCycle; | 820 GrGpuResource::kUncached_LifeCycle; |
| 831 | 821 |
| 832 GrGLenum status; | 822 GrGLenum status; |
| 833 | 823 |
| 834 GrGLenum msColorFormat = 0; // suppress warning | 824 GrGLenum msColorFormat = 0; // suppress warning |
| 835 GrGLenum fboTarget = 0; // suppress warning | |
| 836 | 825 |
| 837 if (desc.fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBO
Type()) { | 826 if (desc.fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBO
Type()) { |
| 838 goto FAILED; | 827 goto FAILED; |
| 839 } | 828 } |
| 840 | 829 |
| 841 idDesc->fTextureFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterface()))); | 830 GL_CALL(GenFramebuffers(1, &idDesc->fTexFBOID)); |
| 842 if (!idDesc->fTextureFBO->isValid()) { | 831 if (!idDesc->fTexFBOID) { |
| 843 goto FAILED; | 832 goto FAILED; |
| 844 } | 833 } |
| 845 | 834 |
| 835 |
| 846 // If we are using multisampling we will create two FBOS. We render to one a
nd then resolve to | 836 // If we are using multisampling we will create two FBOS. We render to one a
nd then resolve to |
| 847 // the texture bound to the other. The exception is the IMG multisample exte
nsion. With this | 837 // the texture bound to the other. The exception is the IMG multisample exte
nsion. With this |
| 848 // extension the texture is multisampled when rendered to and then auto-reso
lves it when it is | 838 // extension the texture is multisampled when rendered to and then auto-reso
lves it when it is |
| 849 // rendered from. | 839 // rendered from. |
| 850 if (desc.fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) { | 840 if (desc.fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) { |
| 851 idDesc->fRenderFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterface()))); | 841 GL_CALL(GenFramebuffers(1, &idDesc->fRTFBOID)); |
| 852 if (!idDesc->fRenderFBO->isValid()) { | |
| 853 goto FAILED; | |
| 854 } | |
| 855 GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); | 842 GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); |
| 856 if (!idDesc->fMSColorRenderbufferID || | 843 if (!idDesc->fRTFBOID || |
| 844 !idDesc->fMSColorRenderbufferID || |
| 857 !this->configToGLFormats(desc.fConfig, | 845 !this->configToGLFormats(desc.fConfig, |
| 858 // ES2 and ES3 require sized internal forma
ts for rb storage. | 846 // ES2 and ES3 require sized internal forma
ts for rb storage. |
| 859 kGLES_GrGLStandard == this->glStandard(), | 847 kGLES_GrGLStandard == this->glStandard(), |
| 860 &msColorFormat, | 848 &msColorFormat, |
| 861 NULL, | 849 NULL, |
| 862 NULL)) { | 850 NULL)) { |
| 863 goto FAILED; | 851 goto FAILED; |
| 864 } | 852 } |
| 865 } else { | 853 } else { |
| 866 idDesc->fRenderFBO.reset(SkRef(idDesc->fTextureFBO.get())); | 854 idDesc->fRTFBOID = idDesc->fTexFBOID; |
| 867 } | 855 } |
| 868 | 856 |
| 869 if (idDesc->fRenderFBO != idDesc->fTextureFBO) { | 857 // below here we may bind the FBO |
| 858 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 859 if (idDesc->fRTFBOID != idDesc->fTexFBOID) { |
| 870 SkASSERT(desc.fSampleCnt > 0); | 860 SkASSERT(desc.fSampleCnt > 0); |
| 871 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe
rID)); | 861 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe
rID)); |
| 872 if (!renderbuffer_storage_msaa(fGLContext, | 862 if (!renderbuffer_storage_msaa(fGLContext, |
| 873 desc.fSampleCnt, | 863 desc.fSampleCnt, |
| 874 msColorFormat, | 864 msColorFormat, |
| 875 desc.fWidth, desc.fHeight)) { | 865 desc.fWidth, desc.fHeight)) { |
| 876 goto FAILED; | 866 goto FAILED; |
| 877 } | 867 } |
| 878 fboTarget = this->bindFBO(kChangeAttachments_FBOBinding, idDesc->fRender
FBO); | 868 fStats.incRenderTargetBinds(); |
| 879 GL_CALL(FramebufferRenderbuffer(fboTarget, | 869 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); |
| 880 GR_GL_COLOR_ATTACHMENT0, | 870 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 881 GR_GL_RENDERBUFFER, | 871 GR_GL_COLOR_ATTACHMENT0, |
| 882 idDesc->fMSColorRenderbufferID)); | 872 GR_GL_RENDERBUFFER, |
| 873 idDesc->fMSColorRenderbufferID)); |
| 883 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || | 874 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || |
| 884 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { | 875 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { |
| 885 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 876 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 886 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 877 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 887 goto FAILED; | 878 goto FAILED; |
| 888 } | 879 } |
| 889 fGLContext.caps()->markConfigAsValidColorAttachment(desc.fConfig); | 880 fGLContext.caps()->markConfigAsValidColorAttachment(desc.fConfig); |
| 890 } | 881 } |
| 891 } | 882 } |
| 892 fboTarget = this->bindFBO(kChangeAttachments_FBOBinding, idDesc->fTextureFBO
); | 883 fStats.incRenderTargetBinds(); |
| 884 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID)); |
| 893 | 885 |
| 894 if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) { | 886 if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) { |
| 895 GL_CALL(FramebufferTexture2DMultisample(fboTarget, | 887 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, |
| 896 GR_GL_COLOR_ATTACHMENT0, | 888 GR_GL_COLOR_ATTACHMENT0, |
| 897 GR_GL_TEXTURE_2D, | 889 GR_GL_TEXTURE_2D, |
| 898 texID, 0, desc.fSampleCnt)); | 890 texID, 0, desc.fSampleCnt)); |
| 899 } else { | 891 } else { |
| 900 GL_CALL(FramebufferTexture2D(fboTarget, | 892 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, |
| 901 GR_GL_COLOR_ATTACHMENT0, | 893 GR_GL_COLOR_ATTACHMENT0, |
| 902 GR_GL_TEXTURE_2D, | 894 GR_GL_TEXTURE_2D, |
| 903 texID, 0)); | 895 texID, 0)); |
| 904 } | 896 } |
| 905 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || | 897 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || |
| 906 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { | 898 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { |
| 907 GL_CALL_RET(status, CheckFramebufferStatus(fboTarget)); | 899 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 908 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 900 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 909 goto FAILED; | 901 goto FAILED; |
| 910 } | 902 } |
| 911 fGLContext.caps()->markConfigAsValidColorAttachment(desc.fConfig); | 903 fGLContext.caps()->markConfigAsValidColorAttachment(desc.fConfig); |
| 912 } | 904 } |
| 913 | 905 |
| 914 return true; | 906 return true; |
| 915 | 907 |
| 916 FAILED: | 908 FAILED: |
| 917 if (idDesc->fMSColorRenderbufferID) { | 909 if (idDesc->fMSColorRenderbufferID) { |
| 918 GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); | 910 GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); |
| 919 } | 911 } |
| 920 if (idDesc->fRenderFBO) { | 912 if (idDesc->fRTFBOID != idDesc->fTexFBOID) { |
| 921 idDesc->fRenderFBO->release(this->glInterface()); | 913 GL_CALL(DeleteFramebuffers(1, &idDesc->fRTFBOID)); |
| 922 } | 914 } |
| 923 if (idDesc->fTextureFBO) { | 915 if (idDesc->fTexFBOID) { |
| 924 idDesc->fTextureFBO->release(this->glInterface()); | 916 GL_CALL(DeleteFramebuffers(1, &idDesc->fTexFBOID)); |
| 925 } | 917 } |
| 926 return false; | 918 return false; |
| 927 } | 919 } |
| 928 | 920 |
| 929 // good to set a break-point here to know when createTexture fails | 921 // good to set a break-point here to know when createTexture fails |
| 930 static GrTexture* return_null_texture() { | 922 static GrTexture* return_null_texture() { |
| 931 // SkDEBUGFAIL("null texture"); | 923 // SkDEBUGFAIL("null texture"); |
| 932 return NULL; | 924 return NULL; |
| 933 } | 925 } |
| 934 | 926 |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 get_stencil_rb_sizes(this->glInterface(), &format); | 1179 get_stencil_rb_sizes(this->glInterface(), &format); |
| 1188 SkAutoTUnref<GrGLStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, | 1180 SkAutoTUnref<GrGLStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, |
| 1189 (this, sbDesc, width, height,
samples, format))); | 1181 (this, sbDesc, width, height,
samples, format))); |
| 1190 if (this->attachStencilBufferToRenderTarget(sb, rt)) { | 1182 if (this->attachStencilBufferToRenderTarget(sb, rt)) { |
| 1191 fLastSuccessfulStencilFmtIdx = sIdx; | 1183 fLastSuccessfulStencilFmtIdx = sIdx; |
| 1192 rt->renderTargetPriv().didAttachStencilBuffer(sb); | 1184 rt->renderTargetPriv().didAttachStencilBuffer(sb); |
| 1193 | 1185 |
| 1194 // Clear the stencil buffer. We use a special purpose FBO for th
is so that the | 1186 // Clear the stencil buffer. We use a special purpose FBO for th
is so that the |
| 1195 // entire stencil buffer is cleared, even if it is attached to a
n FBO with a | 1187 // entire stencil buffer is cleared, even if it is attached to a
n FBO with a |
| 1196 // smaller color target. | 1188 // smaller color target. |
| 1197 if (!fStencilClearFBO) { | 1189 if (0 == fStencilClearFBOID) { |
| 1198 fStencilClearFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterfac
e()))); | 1190 GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); |
| 1199 } | 1191 } |
| 1200 SkASSERT(fStencilClearFBO->isValid()); | |
| 1201 GrGLenum fboTarget = this->bindFBO(kClear_FBOBinding, fStencilCl
earFBO); | |
| 1202 | 1192 |
| 1203 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1193 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBOID)); |
| 1194 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 1195 fStats.incRenderTargetBinds(); |
| 1196 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1204 GR_GL_STENCIL_ATTACHMENT, | 1197 GR_GL_STENCIL_ATTACHMENT, |
| 1205 GR_GL_RENDERBUFFER, sbDesc.fRend
erbufferID)); | 1198 GR_GL_RENDERBUFFER, sbDesc.fRend
erbufferID)); |
| 1206 if (sFmt.fPacked) { | 1199 if (sFmt.fPacked) { |
| 1207 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1200 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1208 GR_GL_DEPTH_ATTACHMENT, | 1201 GR_GL_DEPTH_ATTACHMENT, |
| 1209 GR_GL_RENDERBUFFER, sbDesc.f
RenderbufferID)); | 1202 GR_GL_RENDERBUFFER, sbDesc.f
RenderbufferID)); |
| 1210 } | 1203 } |
| 1211 | 1204 |
| 1212 GL_CALL(ClearStencil(0)); | 1205 GL_CALL(ClearStencil(0)); |
| 1213 // Many GL implementations seem to have trouble with clearing an
FBO with only | 1206 // Many GL implementations seem to have trouble with clearing an
FBO with only |
| 1214 // a stencil buffer. | 1207 // a stencil buffer. |
| 1215 GrGLuint tempRB; | 1208 GrGLuint tempRB; |
| 1216 GL_CALL(GenRenderbuffers(1, &tempRB)); | 1209 GL_CALL(GenRenderbuffers(1, &tempRB)); |
| 1217 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, tempRB)); | 1210 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, tempRB)); |
| 1218 | |
| 1219 if (samples > 0) { | 1211 if (samples > 0) { |
| 1220 renderbuffer_storage_msaa(fGLContext, samples, GR_GL_RGBA8,
width, height); | 1212 renderbuffer_storage_msaa(fGLContext, samples, GR_GL_RGBA8,
width, height); |
| 1221 } else { | 1213 } else { |
| 1222 GL_CALL(RenderbufferStorage(GR_GL_RENDERBUFFER, GR_GL_RGBA8,
width, height)); | 1214 GL_CALL(RenderbufferStorage(GR_GL_RENDERBUFFER, GR_GL_RGBA8,
width, height)); |
| 1223 } | 1215 } |
| 1224 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1216 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1225 GR_GL_COLOR_ATTACHMENT0, | 1217 GR_GL_COLOR_ATTACHMENT0, |
| 1226 GR_GL_RENDERBUFFER, tempRB)); | 1218 GR_GL_RENDERBUFFER, tempRB)); |
| 1227 | 1219 |
| 1228 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1220 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
| 1229 | 1221 |
| 1230 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1222 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1231 GR_GL_COLOR_ATTACHMENT0, | 1223 GR_GL_COLOR_ATTACHMENT0, |
| 1232 GR_GL_RENDERBUFFER, 0)); | 1224 GR_GL_RENDERBUFFER, 0)); |
| 1233 GL_CALL(DeleteRenderbuffers(1, &tempRB)); | 1225 GL_CALL(DeleteRenderbuffers(1, &tempRB)); |
| 1234 | 1226 |
| 1235 // Unbind the SB from the FBO so that we don't keep it alive. | 1227 // Unbind the SB from the FBO so that we don't keep it alive. |
| 1236 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1228 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1237 GR_GL_STENCIL_ATTACHMENT, | 1229 GR_GL_STENCIL_ATTACHMENT, |
| 1238 GR_GL_RENDERBUFFER, 0)); | 1230 GR_GL_RENDERBUFFER, 0)); |
| 1239 if (sFmt.fPacked) { | 1231 if (sFmt.fPacked) { |
| 1240 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1232 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1241 GR_GL_DEPTH_ATTACHMENT, | 1233 GR_GL_DEPTH_ATTACHMENT, |
| 1242 GR_GL_RENDERBUFFER, 0)); | 1234 GR_GL_RENDERBUFFER, 0)); |
| 1243 } | 1235 } |
| 1244 | 1236 |
| 1245 return true; | 1237 return true; |
| 1246 } | 1238 } |
| 1247 // Remove the scratch key from this resource so we don't grab it fro
m the cache ever | 1239 // Remove the scratch key from this resource so we don't grab it fro
m the cache ever |
| 1248 // again. | 1240 // again. |
| 1249 sb->resourcePriv().removeScratchKey(); | 1241 sb->resourcePriv().removeScratchKey(); |
| 1250 // Set this to 0 since we handed the valid ID off to the failed sten
cil buffer resource. | 1242 // Set this to 0 since we handed the valid ID off to the failed sten
cil buffer resource. |
| 1251 sbDesc.fRenderbufferID = 0; | 1243 sbDesc.fRenderbufferID = 0; |
| 1252 } | 1244 } |
| 1253 } | 1245 } |
| 1254 GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); | 1246 GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); |
| 1255 return false; | 1247 return false; |
| 1256 } | 1248 } |
| 1257 | 1249 |
| 1258 bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { | 1250 bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { |
| 1259 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); | 1251 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); |
| 1252 |
| 1253 GrGLuint fbo = glrt->renderFBOID(); |
| 1254 |
| 1260 if (NULL == sb) { | 1255 if (NULL == sb) { |
| 1261 if (rt->renderTargetPriv().getStencilBuffer()) { | 1256 if (rt->renderTargetPriv().getStencilBuffer()) { |
| 1262 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1257 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1263 GR_GL_STENCIL_ATTACHMENT, | 1258 GR_GL_STENCIL_ATTACHMENT, |
| 1264 GR_GL_RENDERBUFFER, 0)); | 1259 GR_GL_RENDERBUFFER, 0)); |
| 1265 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1260 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1266 GR_GL_DEPTH_ATTACHMENT, | 1261 GR_GL_DEPTH_ATTACHMENT, |
| 1267 GR_GL_RENDERBUFFER, 0)); | 1262 GR_GL_RENDERBUFFER, 0)); |
| 1268 #ifdef SK_DEBUG | 1263 #ifdef SK_DEBUG |
| 1269 GrGLenum status; | 1264 GrGLenum status; |
| 1270 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1265 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 1271 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); | 1266 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); |
| 1272 #endif | 1267 #endif |
| 1273 } | 1268 } |
| 1274 return true; | 1269 return true; |
| 1275 } else { | 1270 } else { |
| 1276 GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); | 1271 GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); |
| 1277 GrGLuint rb = glsb->renderbufferID(); | 1272 GrGLuint rb = glsb->renderbufferID(); |
| 1278 GrGLenum fboTarget = this->bindFBO(kChangeAttachments_FBOBinding, glrt->
renderFBO()); | |
| 1279 | 1273 |
| 1280 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1274 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 1275 fStats.incRenderTargetBinds(); |
| 1276 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); |
| 1277 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1281 GR_GL_STENCIL_ATTACHMENT, | 1278 GR_GL_STENCIL_ATTACHMENT, |
| 1282 GR_GL_RENDERBUFFER, rb)); | 1279 GR_GL_RENDERBUFFER, rb)); |
| 1283 if (glsb->format().fPacked) { | 1280 if (glsb->format().fPacked) { |
| 1284 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1281 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1285 GR_GL_DEPTH_ATTACHMENT, | 1282 GR_GL_DEPTH_ATTACHMENT, |
| 1286 GR_GL_RENDERBUFFER, rb)); | 1283 GR_GL_RENDERBUFFER, rb)); |
| 1287 } else { | 1284 } else { |
| 1288 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1285 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1289 GR_GL_DEPTH_ATTACHMENT, | 1286 GR_GL_DEPTH_ATTACHMENT, |
| 1290 GR_GL_RENDERBUFFER, 0)); | 1287 GR_GL_RENDERBUFFER, 0)); |
| 1291 } | 1288 } |
| 1292 | 1289 |
| 1293 GrGLenum status; | 1290 GrGLenum status; |
| 1294 if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
glsb->format())) { | 1291 if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
glsb->format())) { |
| 1295 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1292 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 1296 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 1293 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 1297 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1294 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1298 GR_GL_STENCIL_ATTACHMENT, | 1295 GR_GL_STENCIL_ATTACHMENT, |
| 1299 GR_GL_RENDERBUFFER, 0)); | 1296 GR_GL_RENDERBUFFER, 0)); |
| 1300 if (glsb->format().fPacked) { | 1297 if (glsb->format().fPacked) { |
| 1301 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1298 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1302 GR_GL_DEPTH_ATTACHMENT, | 1299 GR_GL_DEPTH_ATTACHMENT, |
| 1303 GR_GL_RENDERBUFFER, 0)); | 1300 GR_GL_RENDERBUFFER, 0)); |
| 1304 } | 1301 } |
| 1305 return false; | 1302 return false; |
| 1306 } else { | 1303 } else { |
| 1307 fGLContext.caps()->markColorConfigAndStencilFormatAsVerified( | 1304 fGLContext.caps()->markColorConfigAndStencilFormatAsVerified( |
| 1308 rt->config(), | 1305 rt->config(), |
| 1309 glsb->format()); | 1306 glsb->format()); |
| 1310 } | 1307 } |
| 1311 } | 1308 } |
| 1312 return true; | 1309 return true; |
| 1313 } | 1310 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1425 } | 1422 } |
| 1426 | 1423 |
| 1427 fCurrentProgram.get()->ref(); | 1424 fCurrentProgram.get()->ref(); |
| 1428 | 1425 |
| 1429 GrGLuint programID = fCurrentProgram->programID(); | 1426 GrGLuint programID = fCurrentProgram->programID(); |
| 1430 if (fHWProgramID != programID) { | 1427 if (fHWProgramID != programID) { |
| 1431 GL_CALL(UseProgram(programID)); | 1428 GL_CALL(UseProgram(programID)); |
| 1432 fHWProgramID = programID; | 1429 fHWProgramID = programID; |
| 1433 } | 1430 } |
| 1434 | 1431 |
| 1432 if (blendInfo.fWriteColor) { |
| 1433 this->flushBlend(blendInfo); |
| 1434 } |
| 1435 | 1435 |
| 1436 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr
acker); | 1436 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr
acker); |
| 1437 | 1437 |
| 1438 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); | 1438 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); |
| 1439 | |
| 1440 this->flushStencil(pipeline.getStencil()); | 1439 this->flushStencil(pipeline.getStencil()); |
| 1441 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); | 1440 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); |
| 1442 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); | 1441 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); |
| 1443 | 1442 |
| 1444 // This must come after textures are flushed because a texture may need | 1443 // This must come after textures are flushed because a texture may need |
| 1445 // to be msaa-resolved (which will modify bound FBO and scissor state). | 1444 // to be msaa-resolved (which will modify bound FBO state). |
| 1446 this->bindFBO(kDraw_FBOBinding, glRT->renderFBO()); | 1445 this->flushRenderTarget(glRT, NULL); |
| 1447 this->setViewport(glRT->getViewport()); | |
| 1448 if (blendInfo.fWriteColor) { | |
| 1449 this->flushBlend(blendInfo); | |
| 1450 this->markSurfaceContentsDirty(glRT, NULL); | |
| 1451 } | |
| 1452 | 1446 |
| 1453 return true; | 1447 return true; |
| 1454 } | 1448 } |
| 1455 | 1449 |
| 1456 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, | 1450 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, |
| 1457 const GrDrawTarget::DrawInfo& info, | 1451 const GrDrawTarget::DrawInfo& info, |
| 1458 size_t* indexOffsetInBytes) { | 1452 size_t* indexOffsetInBytes) { |
| 1459 GrGLVertexBuffer* vbuf; | 1453 GrGLVertexBuffer* vbuf; |
| 1460 vbuf = (GrGLVertexBuffer*) info.vertexBuffer(); | 1454 vbuf = (GrGLVertexBuffer*) info.vertexBuffer(); |
| 1461 | 1455 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 // flushScissor expects rect to be clipped to the target. | 1532 // flushScissor expects rect to be clipped to the target. |
| 1539 clippedRect = *rect; | 1533 clippedRect = *rect; |
| 1540 SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height()); | 1534 SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height()); |
| 1541 if (clippedRect.intersect(rtRect)) { | 1535 if (clippedRect.intersect(rtRect)) { |
| 1542 rect = &clippedRect; | 1536 rect = &clippedRect; |
| 1543 } else { | 1537 } else { |
| 1544 return; | 1538 return; |
| 1545 } | 1539 } |
| 1546 } | 1540 } |
| 1547 | 1541 |
| 1548 this->bindFBO(kClear_FBOBinding, glRT->renderFBO()); | 1542 this->flushRenderTarget(glRT, rect); |
| 1549 this->markSurfaceContentsDirty(glRT, rect); | |
| 1550 GrScissorState scissorState; | 1543 GrScissorState scissorState; |
| 1551 if (rect) { | 1544 if (rect) { |
| 1552 scissorState.set(*rect); | 1545 scissorState.set(*rect); |
| 1553 } | 1546 } |
| 1554 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); | 1547 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); |
| 1555 | 1548 |
| 1556 GrGLfloat r, g, b, a; | 1549 GrGLfloat r, g, b, a; |
| 1557 static const GrGLfloat scale255 = 1.f / 255.f; | 1550 static const GrGLfloat scale255 = 1.f / 255.f; |
| 1558 a = GrColorUnpackA(color) * scale255; | 1551 a = GrColorUnpackA(color) * scale255; |
| 1559 GrGLfloat scaleRGB = scale255; | 1552 GrGLfloat scaleRGB = scale255; |
| 1560 r = GrColorUnpackR(color) * scaleRGB; | 1553 r = GrColorUnpackR(color) * scaleRGB; |
| 1561 g = GrColorUnpackG(color) * scaleRGB; | 1554 g = GrColorUnpackG(color) * scaleRGB; |
| 1562 b = GrColorUnpackB(color) * scaleRGB; | 1555 b = GrColorUnpackB(color) * scaleRGB; |
| 1563 | 1556 |
| 1564 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); | 1557 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); |
| 1565 fHWWriteToColor = kYes_TriState; | 1558 fHWWriteToColor = kYes_TriState; |
| 1566 GL_CALL(ClearColor(r, g, b, a)); | 1559 GL_CALL(ClearColor(r, g, b, a)); |
| 1567 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); | 1560 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); |
| 1568 } | 1561 } |
| 1569 | 1562 |
| 1570 void GrGLGpu::discard(GrRenderTarget* renderTarget) { | 1563 void GrGLGpu::discard(GrRenderTarget* renderTarget) { |
| 1571 SkASSERT(renderTarget); | 1564 SkASSERT(renderTarget); |
| 1572 if (!this->caps()->discardRenderTargetSupport()) { | 1565 if (!this->caps()->discardRenderTargetSupport()) { |
| 1573 return; | 1566 return; |
| 1574 } | 1567 } |
| 1575 | 1568 |
| 1576 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); | 1569 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); |
| 1577 GrGLenum fboTarget = this->bindFBO(kDiscard_FBOBinding, glRT->renderFBO()); | 1570 if (renderTarget->getUniqueID() != fHWBoundRenderTargetUniqueID) { |
| 1571 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 1572 fStats.incRenderTargetBinds(); |
| 1573 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID())); |
| 1574 } |
| 1578 switch (this->glCaps().invalidateFBType()) { | 1575 switch (this->glCaps().invalidateFBType()) { |
| 1579 case GrGLCaps::kNone_InvalidateFBType: | 1576 case GrGLCaps::kNone_InvalidateFBType: |
| 1580 SkFAIL("Should never get here."); | 1577 SkFAIL("Should never get here."); |
| 1581 break; | 1578 break; |
| 1582 case GrGLCaps::kInvalidate_InvalidateFBType: | 1579 case GrGLCaps::kInvalidate_InvalidateFBType: |
| 1583 if (glRT->renderFBO()->isDefaultFramebuffer()) { | 1580 if (0 == glRT->renderFBOID()) { |
| 1584 // When rendering to the default framebuffer the legal values f
or attachments | 1581 // When rendering to the default framebuffer the legal values f
or attachments |
| 1585 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment | 1582 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment |
| 1586 // types. | 1583 // types. |
| 1587 static const GrGLenum attachments[] = { GR_GL_COLOR }; | 1584 static const GrGLenum attachments[] = { GR_GL_COLOR }; |
| 1588 GL_CALL(InvalidateFramebuffer(fboTarget, SK_ARRAY_COUNT(attachme
nts), | 1585 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(
attachments), |
| 1589 attachments)); | 1586 attachments)); |
| 1590 } else { | 1587 } else { |
| 1591 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; | 1588 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; |
| 1592 GL_CALL(InvalidateFramebuffer(fboTarget, SK_ARRAY_COUNT(attachme
nts), | 1589 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(
attachments), |
| 1593 attachments)); | 1590 attachments)); |
| 1594 } | 1591 } |
| 1595 break; | 1592 break; |
| 1596 case GrGLCaps::kDiscard_InvalidateFBType: { | 1593 case GrGLCaps::kDiscard_InvalidateFBType: { |
| 1597 if (glRT->renderFBO()->isDefaultFramebuffer()) { | 1594 if (0 == glRT->renderFBOID()) { |
| 1598 // When rendering to the default framebuffer the legal values f
or attachments | 1595 // When rendering to the default framebuffer the legal values f
or attachments |
| 1599 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment | 1596 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment |
| 1600 // types. See glDiscardFramebuffer() spec. | 1597 // types. See glDiscardFramebuffer() spec. |
| 1601 static const GrGLenum attachments[] = { GR_GL_COLOR }; | 1598 static const GrGLenum attachments[] = { GR_GL_COLOR }; |
| 1602 GL_CALL(DiscardFramebuffer(fboTarget, SK_ARRAY_COUNT(attachments
), | 1599 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att
achments), |
| 1603 attachments)); | 1600 attachments)); |
| 1604 } else { | 1601 } else { |
| 1605 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; | 1602 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; |
| 1606 GL_CALL(DiscardFramebuffer(fboTarget, SK_ARRAY_COUNT(attachments
), | 1603 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att
achments), |
| 1607 attachments)); | 1604 attachments)); |
| 1608 } | 1605 } |
| 1609 break; | 1606 break; |
| 1610 } | 1607 } |
| 1611 } | 1608 } |
| 1612 renderTarget->flagAsResolved(); | 1609 renderTarget->flagAsResolved(); |
| 1613 } | 1610 } |
| 1614 | 1611 |
| 1615 | 1612 |
| 1616 void GrGLGpu::clearStencil(GrRenderTarget* target) { | 1613 void GrGLGpu::clearStencil(GrRenderTarget* target) { |
| 1617 if (NULL == target) { | 1614 if (NULL == target) { |
| 1618 return; | 1615 return; |
| 1619 } | 1616 } |
| 1620 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); | 1617 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); |
| 1621 this->bindFBO(kClear_FBOBinding, glRT->renderFBO()); | 1618 this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); |
| 1622 | 1619 |
| 1623 this->disableScissor(); | 1620 this->disableScissor(); |
| 1624 | 1621 |
| 1625 GL_CALL(StencilMask(0xffffffff)); | 1622 GL_CALL(StencilMask(0xffffffff)); |
| 1626 GL_CALL(ClearStencil(0)); | 1623 GL_CALL(ClearStencil(0)); |
| 1627 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1624 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
| 1628 fHWStencilSettings.invalidate(); | 1625 fHWStencilSettings.invalidate(); |
| 1629 } | 1626 } |
| 1630 | 1627 |
| 1631 void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo
ol insideClip) { | 1628 void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo
ol insideClip) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1647 // zero the client's clip bits. So we just clear the whole thing. | 1644 // zero the client's clip bits. So we just clear the whole thing. |
| 1648 static const GrGLint clipStencilMask = ~0; | 1645 static const GrGLint clipStencilMask = ~0; |
| 1649 #endif | 1646 #endif |
| 1650 GrGLint value; | 1647 GrGLint value; |
| 1651 if (insideClip) { | 1648 if (insideClip) { |
| 1652 value = (1 << (stencilBitCount - 1)); | 1649 value = (1 << (stencilBitCount - 1)); |
| 1653 } else { | 1650 } else { |
| 1654 value = 0; | 1651 value = 0; |
| 1655 } | 1652 } |
| 1656 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); | 1653 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); |
| 1657 this->bindFBO(kClear_FBOBinding, glRT->renderFBO()); | 1654 this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); |
| 1658 | 1655 |
| 1659 GrScissorState scissorState; | 1656 GrScissorState scissorState; |
| 1660 scissorState.set(rect); | 1657 scissorState.set(rect); |
| 1661 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); | 1658 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); |
| 1662 | 1659 |
| 1663 GL_CALL(StencilMask((uint32_t) clipStencilMask)); | 1660 GL_CALL(StencilMask((uint32_t) clipStencilMask)); |
| 1664 GL_CALL(ClearStencil(value)); | 1661 GL_CALL(ClearStencil(value)); |
| 1665 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1662 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
| 1666 fHWStencilSettings.invalidate(); | 1663 fHWStencilSettings.invalidate(); |
| 1667 } | 1664 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 size_t bpp = GrBytesPerPixel(config); | 1714 size_t bpp = GrBytesPerPixel(config); |
| 1718 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, | 1715 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, |
| 1719 &left, &top, &width, &height, | 1716 &left, &top, &width, &height, |
| 1720 const_cast<const void**>(&buffer), | 1717 const_cast<const void**>(&buffer), |
| 1721 &rowBytes)) { | 1718 &rowBytes)) { |
| 1722 return false; | 1719 return false; |
| 1723 } | 1720 } |
| 1724 | 1721 |
| 1725 // resolve the render target if necessary | 1722 // resolve the render target if necessary |
| 1726 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); | 1723 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); |
| 1727 if (tgt->getResolveType() == GrGLRenderTarget::kCantResolve_ResolveType) { | 1724 switch (tgt->getResolveType()) { |
| 1728 return false; | 1725 case GrGLRenderTarget::kCantResolve_ResolveType: |
| 1726 return false; |
| 1727 case GrGLRenderTarget::kAutoResolves_ResolveType: |
| 1728 this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target), &SkI
Rect::EmptyIRect()); |
| 1729 break; |
| 1730 case GrGLRenderTarget::kCanResolve_ResolveType: |
| 1731 this->onResolveRenderTarget(tgt); |
| 1732 // we don't track the state of the READ FBO ID. |
| 1733 fStats.incRenderTargetBinds(); |
| 1734 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, |
| 1735 tgt->textureFBOID())); |
| 1736 break; |
| 1737 default: |
| 1738 SkFAIL("Unknown resolve type"); |
| 1729 } | 1739 } |
| 1730 if (tgt->getResolveType() == GrGLRenderTarget::kCanResolve_ResolveType) { | |
| 1731 this->onResolveRenderTarget(tgt); | |
| 1732 } | |
| 1733 this->bindFBO(kReadPixels_FBOBinding, tgt->textureFBO()); | |
| 1734 | 1740 |
| 1735 const GrGLIRect& glvp = tgt->getViewport(); | 1741 const GrGLIRect& glvp = tgt->getViewport(); |
| 1736 | 1742 |
| 1737 // the read rect is viewport-relative | 1743 // the read rect is viewport-relative |
| 1738 GrGLIRect readRect; | 1744 GrGLIRect readRect; |
| 1739 readRect.setRelativeTo(glvp, left, top, width, height, target->origin()); | 1745 readRect.setRelativeTo(glvp, left, top, width, height, target->origin()); |
| 1740 | 1746 |
| 1741 size_t tightRowBytes = bpp * width; | 1747 size_t tightRowBytes = bpp * width; |
| 1742 if (0 == rowBytes) { | 1748 if (0 == rowBytes) { |
| 1743 rowBytes = tightRowBytes; | 1749 rowBytes = tightRowBytes; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 char* bottom = top + (height - 1) * rowBytes; | 1794 char* bottom = top + (height - 1) * rowBytes; |
| 1789 for (int y = 0; y < halfY; y++) { | 1795 for (int y = 0; y < halfY; y++) { |
| 1790 memcpy(tmpRow, top, tightRowBytes); | 1796 memcpy(tmpRow, top, tightRowBytes); |
| 1791 memcpy(top, bottom, tightRowBytes); | 1797 memcpy(top, bottom, tightRowBytes); |
| 1792 memcpy(bottom, tmpRow, tightRowBytes); | 1798 memcpy(bottom, tmpRow, tightRowBytes); |
| 1793 top += rowBytes; | 1799 top += rowBytes; |
| 1794 bottom -= rowBytes; | 1800 bottom -= rowBytes; |
| 1795 } | 1801 } |
| 1796 } | 1802 } |
| 1797 } else { | 1803 } else { |
| 1798 SkASSERT(readDst != buffer); | 1804 SkASSERT(readDst != buffer); SkASSERT(rowBytes != tightRowBytes); |
| 1799 SkASSERT(rowBytes != tightRowBytes); | |
| 1800 // copy from readDst to buffer while flipping y | 1805 // copy from readDst to buffer while flipping y |
| 1801 // const int halfY = height >> 1; | 1806 // const int halfY = height >> 1; |
| 1802 const char* src = reinterpret_cast<const char*>(readDst); | 1807 const char* src = reinterpret_cast<const char*>(readDst); |
| 1803 char* dst = reinterpret_cast<char*>(buffer); | 1808 char* dst = reinterpret_cast<char*>(buffer); |
| 1804 if (flipY) { | 1809 if (flipY) { |
| 1805 dst += (height-1) * rowBytes; | 1810 dst += (height-1) * rowBytes; |
| 1806 } | 1811 } |
| 1807 for (int y = 0; y < height; y++) { | 1812 for (int y = 0; y < height; y++) { |
| 1808 memcpy(dst, src, tightRowBytes); | 1813 memcpy(dst, src, tightRowBytes); |
| 1809 src += readDstRowBytes; | 1814 src += readDstRowBytes; |
| 1810 if (!flipY) { | 1815 if (!flipY) { |
| 1811 dst += rowBytes; | 1816 dst += rowBytes; |
| 1812 } else { | 1817 } else { |
| 1813 dst -= rowBytes; | 1818 dst -= rowBytes; |
| 1814 } | 1819 } |
| 1815 } | 1820 } |
| 1816 } | 1821 } |
| 1817 return true; | 1822 return true; |
| 1818 } | 1823 } |
| 1819 | 1824 |
| 1820 GrGLenum GrGLGpu::bindFBO(FBOBinding binding, const GrGLFBO* fbo) { | 1825 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound)
{ |
| 1821 SkASSERT(fbo); | |
| 1822 SkASSERT(fbo->isValid()); | |
| 1823 | |
| 1824 enum { | |
| 1825 kDraw = 0, | |
| 1826 kRead = 1 | |
| 1827 }; | |
| 1828 | 1826 |
| 1829 bool useGLFramebuffer = !this->glCaps().usesMSAARenderBuffers() || | 1827 SkASSERT(target); |
| 1830 (this->glCaps().preferBindingToReadAndDrawFramebuffer() && | |
| 1831 kBlitSrc_FBOBinding != binding && kBlitDst_FBOBinding != binding); | |
| 1832 | 1828 |
| 1833 if (useGLFramebuffer) { | 1829 uint32_t rtID = target->getUniqueID(); |
| 1834 SkASSERT(kBlitSrc_FBOBinding != binding); | 1830 if (fHWBoundRenderTargetUniqueID != rtID) { |
| 1835 fStats.incRenderTargetBinds(); | 1831 fStats.incRenderTargetBinds(); |
| 1836 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo->fboID())); | 1832 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); |
| 1837 fHWFBOBinding[kDraw].fFBO.reset(SkRef(fbo)); | 1833 #ifdef SK_DEBUG |
| 1838 fHWFBOBinding[kRead].fFBO.reset(SkRef(fbo)); | 1834 // don't do this check in Chromium -- this is causing |
| 1839 return GR_GL_FRAMEBUFFER; | 1835 // lots of repeated command buffer flushes when the compositor is |
| 1836 // rendering with Ganesh, which is really slow; even too slow for |
| 1837 // Debug mode. |
| 1838 if (!this->glContext().isChromium()) { |
| 1839 GrGLenum status; |
| 1840 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 1841 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 1842 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x
\n", status); |
| 1843 } |
| 1844 } |
| 1845 #endif |
| 1846 fHWBoundRenderTargetUniqueID = rtID; |
| 1847 const GrGLIRect& vp = target->getViewport(); |
| 1848 if (fHWViewport != vp) { |
| 1849 vp.pushToGLViewport(this->glInterface()); |
| 1850 fHWViewport = vp; |
| 1851 } |
| 1840 } | 1852 } |
| 1841 GrGLenum target = 0; | 1853 if (NULL == bound || !bound->isEmpty()) { |
| 1842 HWFBOBinding* hwFBOBinding = NULL; | 1854 target->flagAsNeedingResolve(bound); |
| 1843 switch (binding) { | 1855 } |
| 1844 case kDraw_FBOBinding: | |
| 1845 case kClear_FBOBinding: | |
| 1846 case kDiscard_FBOBinding: | |
| 1847 case kChangeAttachments_FBOBinding: | |
| 1848 case kBlitDst_FBOBinding: | |
| 1849 target = GR_GL_DRAW_FRAMEBUFFER; | |
| 1850 hwFBOBinding = &fHWFBOBinding[kDraw]; | |
| 1851 break; | |
| 1852 | 1856 |
| 1853 case kReadPixels_FBOBinding: | 1857 GrTexture *texture = target->asTexture(); |
| 1854 case kBlitSrc_FBOBinding: | 1858 if (texture) { |
| 1855 case kCopyTexSrc_FBOBinding: | 1859 texture->texturePriv().dirtyMipMaps(true); |
| 1856 target = GR_GL_READ_FRAMEBUFFER; | |
| 1857 hwFBOBinding = &fHWFBOBinding[kRead]; | |
| 1858 break; | |
| 1859 } | |
| 1860 fStats.incRenderTargetBinds(); | |
| 1861 GL_CALL(BindFramebuffer(target, fbo->fboID())); | |
| 1862 hwFBOBinding->fFBO.reset(SkRef(fbo)); | |
| 1863 return target; | |
| 1864 } | |
| 1865 | |
| 1866 void GrGLGpu::setViewport(const GrGLIRect& viewport) { | |
| 1867 if (viewport != fHWViewport) { | |
| 1868 viewport.pushToGLViewport(this->glInterface()); | |
| 1869 fHWViewport = viewport; | |
| 1870 } | 1860 } |
| 1871 } | 1861 } |
| 1872 | 1862 |
| 1873 void GrGLGpu::markSurfaceContentsDirty(GrSurface* surface, const SkIRect* bounds
) { | |
| 1874 if (NULL == bounds || !bounds->isEmpty()) { | |
| 1875 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderT
arget()); | |
| 1876 if (rt) { | |
| 1877 rt->flagAsNeedingResolve(bounds); | |
| 1878 } | |
| 1879 GrGLTexture* texture = static_cast<GrGLTexture*>(surface->asTexture()); | |
| 1880 if (texture) { | |
| 1881 texture->texturePriv().dirtyMipMaps(true); | |
| 1882 } | |
| 1883 } | |
| 1884 } | |
| 1885 | |
| 1886 GrGLenum gPrimitiveType2GLMode[] = { | 1863 GrGLenum gPrimitiveType2GLMode[] = { |
| 1887 GR_GL_TRIANGLES, | 1864 GR_GL_TRIANGLES, |
| 1888 GR_GL_TRIANGLE_STRIP, | 1865 GR_GL_TRIANGLE_STRIP, |
| 1889 GR_GL_TRIANGLE_FAN, | 1866 GR_GL_TRIANGLE_FAN, |
| 1890 GR_GL_POINTS, | 1867 GR_GL_POINTS, |
| 1891 GR_GL_LINES, | 1868 GR_GL_LINES, |
| 1892 GR_GL_LINE_STRIP | 1869 GR_GL_LINE_STRIP |
| 1893 }; | 1870 }; |
| 1894 | 1871 |
| 1895 #define SWAP_PER_DRAW 0 | 1872 #define SWAP_PER_DRAW 0 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1954 | 1931 |
| 1955 void GrGLGpu::onStencilPath(const GrPath* path, const StencilPathState& state) { | 1932 void GrGLGpu::onStencilPath(const GrPath* path, const StencilPathState& state) { |
| 1956 this->flushColorWrite(false); | 1933 this->flushColorWrite(false); |
| 1957 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); | 1934 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
| 1958 | 1935 |
| 1959 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(state.fRenderTarget); | 1936 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(state.fRenderTarget); |
| 1960 SkISize size = SkISize::Make(rt->width(), rt->height()); | 1937 SkISize size = SkISize::Make(rt->width(), rt->height()); |
| 1961 this->glPathRendering()->setProjectionMatrix(*state.fViewMatrix, size, rt->o
rigin()); | 1938 this->glPathRendering()->setProjectionMatrix(*state.fViewMatrix, size, rt->o
rigin()); |
| 1962 this->flushScissor(*state.fScissor, rt->getViewport(), rt->origin()); | 1939 this->flushScissor(*state.fScissor, rt->getViewport(), rt->origin()); |
| 1963 this->flushHWAAState(rt, state.fUseHWAA); | 1940 this->flushHWAAState(rt, state.fUseHWAA); |
| 1964 this->bindFBO(kDraw_FBOBinding, rt->renderFBO()); | 1941 this->flushRenderTarget(rt, NULL); |
| 1965 this->setViewport(rt->getViewport()); | 1942 |
| 1966 fPathRendering->stencilPath(path, *state.fStencil); | 1943 fPathRendering->stencilPath(path, *state.fStencil); |
| 1967 } | 1944 } |
| 1968 | 1945 |
| 1969 void GrGLGpu::onDrawPath(const DrawArgs& args, const GrPath* path, | 1946 void GrGLGpu::onDrawPath(const DrawArgs& args, const GrPath* path, |
| 1970 const GrStencilSettings& stencil) { | 1947 const GrStencilSettings& stencil) { |
| 1971 if (!this->flushGLState(args)) { | 1948 if (!this->flushGLState(args)) { |
| 1972 return; | 1949 return; |
| 1973 } | 1950 } |
| 1974 fPathRendering->drawPath(path, stencil); | 1951 fPathRendering->drawPath(path, stencil); |
| 1975 } | 1952 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1987 } | 1964 } |
| 1988 fPathRendering->drawPaths(pathRange, indices, indexType, transformValues, | 1965 fPathRendering->drawPaths(pathRange, indices, indexType, transformValues, |
| 1989 transformType, count, stencil); | 1966 transformType, count, stencil); |
| 1990 } | 1967 } |
| 1991 | 1968 |
| 1992 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { | 1969 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { |
| 1993 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); | 1970 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); |
| 1994 if (rt->needsResolve()) { | 1971 if (rt->needsResolve()) { |
| 1995 // Some extensions automatically resolves the texture when it is read. | 1972 // Some extensions automatically resolves the texture when it is read. |
| 1996 if (this->glCaps().usesMSAARenderBuffers()) { | 1973 if (this->glCaps().usesMSAARenderBuffers()) { |
| 1997 SkASSERT(rt->textureFBO() != rt->renderFBO()); | 1974 SkASSERT(rt->textureFBOID() != rt->renderFBOID()); |
| 1998 this->bindFBO(kBlitSrc_FBOBinding, rt->renderFBO()); | 1975 fStats.incRenderTargetBinds(); |
| 1999 this->bindFBO(kBlitDst_FBOBinding, rt->textureFBO()); | 1976 fStats.incRenderTargetBinds(); |
| 1977 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID())); |
| 1978 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()))
; |
| 1979 // make sure we go through flushRenderTarget() since we've modified |
| 1980 // the bound DRAW FBO ID. |
| 1981 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 2000 const GrGLIRect& vp = rt->getViewport(); | 1982 const GrGLIRect& vp = rt->getViewport(); |
| 2001 const SkIRect dirtyRect = rt->getResolveRect(); | 1983 const SkIRect dirtyRect = rt->getResolveRect(); |
| 2002 | 1984 |
| 2003 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { | 1985 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { |
| 2004 // Apple's extension uses the scissor as the blit bounds. | 1986 // Apple's extension uses the scissor as the blit bounds. |
| 2005 GrScissorState scissorState; | 1987 GrScissorState scissorState; |
| 2006 scissorState.set(dirtyRect); | 1988 scissorState.set(dirtyRect); |
| 2007 this->flushScissor(scissorState, vp, rt->origin()); | 1989 this->flushScissor(scissorState, vp, rt->origin()); |
| 2008 GL_CALL(ResolveMultisampleFramebuffer()); | 1990 GL_CALL(ResolveMultisampleFramebuffer()); |
| 2009 } else { | 1991 } else { |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2543 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSub
Image | 2525 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSub
Image |
| 2544 // and BGRA isn't in the spec. There doesn't appear to be any extension that
adds it. Perhaps | 2526 // and BGRA isn't in the spec. There doesn't appear to be any extension that
adds it. Perhaps |
| 2545 // many drivers would allow it to work, but ANGLE does not. | 2527 // many drivers would allow it to work, but ANGLE does not. |
| 2546 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF
ormat() && | 2528 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF
ormat() && |
| 2547 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig =
= src->config())) { | 2529 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig =
= src->config())) { |
| 2548 return false; | 2530 return false; |
| 2549 } | 2531 } |
| 2550 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as
RenderTarget()); | 2532 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as
RenderTarget()); |
| 2551 // If dst is multisampled (and uses an extension where there is a separate M
SAA renderbuffer) | 2533 // If dst is multisampled (and uses an extension where there is a separate M
SAA renderbuffer) |
| 2552 // then we don't want to copy to the texture but to the MSAA buffer. | 2534 // then we don't want to copy to the texture but to the MSAA buffer. |
| 2553 if (dstRT && dstRT->renderFBO() != dstRT->textureFBO()) { | 2535 if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) { |
| 2554 return false; | 2536 return false; |
| 2555 } | 2537 } |
| 2556 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); | 2538 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); |
| 2557 // If the src is multisampled (and uses an extension where there is a separa
te MSAA | 2539 // If the src is multisampled (and uses an extension where there is a separa
te MSAA |
| 2558 // renderbuffer) then it is an invalid operation to call CopyTexSubImage | 2540 // renderbuffer) then it is an invalid operation to call CopyTexSubImage |
| 2559 if (srcRT && srcRT->renderFBO() != srcRT->textureFBO()) { | 2541 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { |
| 2560 return false; | 2542 return false; |
| 2561 } | 2543 } |
| 2562 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && | 2544 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && |
| 2563 dst->asTexture() && | 2545 dst->asTexture() && |
| 2564 dst->origin() == src->origin() && | 2546 dst->origin() == src->origin() && |
| 2565 !GrPixelConfigIsCompressed(src->config())) { | 2547 !GrPixelConfigIsCompressed(src->config())) { |
| 2566 return true; | 2548 return true; |
| 2567 } else { | 2549 } else { |
| 2568 return false; | 2550 return false; |
| 2569 } | 2551 } |
| 2570 } | 2552 } |
| 2571 | 2553 |
| 2572 } | 2554 } |
| 2573 | 2555 |
| 2574 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is | 2556 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is |
| 2575 // relative to is output. | 2557 // relative to is output. |
| 2576 GrGLGpu::FBOBinding GrGLGpu::bindSurfaceAsFBOForCopy(GrSurface* surface, FBOBind
ing binding, | 2558 GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLI
Rect* viewport, |
| 2577 GrGLIRect* viewport) { | 2559 TempFBOTarget tempFBOTarget) { |
| 2578 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); | 2560 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); |
| 2579 if (NULL == rt) { | 2561 if (NULL == rt) { |
| 2580 SkASSERT(surface->asTexture()); | 2562 SkASSERT(surface->asTexture()); |
| 2581 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); | 2563 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); |
| 2582 GrGLFBO* tempFBO; | 2564 GrGLuint* tempFBOID; |
| 2565 tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTem
pDstFBOID; |
| 2583 | 2566 |
| 2584 if (kBlitSrc_FBOBinding == binding || kCopyTexSrc_FBOBinding == binding)
{ | 2567 if (0 == *tempFBOID) { |
| 2585 if (!fTempSrcFBO) { | 2568 GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID)); |
| 2586 fTempSrcFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterface()))); | |
| 2587 SkASSERT(fTempSrcFBO->isValid()); | |
| 2588 } | |
| 2589 tempFBO = fTempSrcFBO; | |
| 2590 } else { | |
| 2591 SkASSERT(kBlitDst_FBOBinding == binding); | |
| 2592 if (!fTempDstFBO) { | |
| 2593 fTempDstFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterface()))); | |
| 2594 SkASSERT(fTempDstFBO->isValid()); | |
| 2595 } | |
| 2596 tempFBO = fTempDstFBO; | |
| 2597 } | 2569 } |
| 2598 | 2570 |
| 2599 GrGLenum target = this->bindFBO(binding, tempFBO); | 2571 fStats.incRenderTargetBinds(); |
| 2600 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(target, | 2572 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID)); |
| 2573 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
| 2601 GR_GL_COLOR_ATTACHM
ENT0, | 2574 GR_GL_COLOR_ATTACHM
ENT0, |
| 2602 GR_GL_TEXTURE_2D, | 2575 GR_GL_TEXTURE_2D, |
| 2603 texID, | 2576 texID, |
| 2604 0)); | 2577 0)); |
| 2605 viewport->fLeft = 0; | 2578 viewport->fLeft = 0; |
| 2606 viewport->fBottom = 0; | 2579 viewport->fBottom = 0; |
| 2607 viewport->fWidth = surface->width(); | 2580 viewport->fWidth = surface->width(); |
| 2608 viewport->fHeight = surface->height(); | 2581 viewport->fHeight = surface->height(); |
| 2609 return binding; | 2582 return *tempFBOID; |
| 2610 } else { | 2583 } else { |
| 2611 this->bindFBO(binding, rt->renderFBO()); | 2584 GrGLuint tempFBOID = 0; |
| 2585 fStats.incRenderTargetBinds(); |
| 2586 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO
ID())); |
| 2612 *viewport = rt->getViewport(); | 2587 *viewport = rt->getViewport(); |
| 2613 return kInvalidFBOBinding; | 2588 return tempFBOID; |
| 2614 } | 2589 } |
| 2615 } | 2590 } |
| 2616 | 2591 |
| 2617 void GrGLGpu::unbindSurfaceAsFBOForCopy(FBOBinding binding) { | 2592 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { |
| 2618 if (kInvalidFBOBinding == binding) { | 2593 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
| 2619 return; | |
| 2620 } | |
| 2621 GrGLFBO* tempFBO = kBlitDst_FBOBinding == binding ? fTempSrcFBO : fTempDstFB
O; | |
| 2622 GrGLenum target = this->bindFBO(binding, tempFBO); | |
| 2623 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(target, | |
| 2624 GR_GL_COLOR_ATTACHMENT0
, | 2594 GR_GL_COLOR_ATTACHMENT0
, |
| 2625 GR_GL_TEXTURE_2D, | 2595 GR_GL_TEXTURE_2D, |
| 2626 0, | 2596 0, |
| 2627 0)); | 2597 0)); |
| 2628 } | 2598 } |
| 2629 | 2599 |
| 2630 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ | 2600 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ |
| 2631 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If
neither are | 2601 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If
neither are |
| 2632 // possible and we return false to fallback to creating a render target dst
for render-to- | 2602 // possible and we return false to fallback to creating a render target dst
for render-to- |
| 2633 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger
ing temporary fbo | 2603 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger
ing temporary fbo |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2644 desc->fConfig = kBGRA_8888_GrPixelConfig; | 2614 desc->fConfig = kBGRA_8888_GrPixelConfig; |
| 2645 return true; | 2615 return true; |
| 2646 } | 2616 } |
| 2647 return false; | 2617 return false; |
| 2648 } else if (NULL == src->asRenderTarget()) { | 2618 } else if (NULL == src->asRenderTarget()) { |
| 2649 // CopyTexSubImage2D or fbo blit would require creating a temp fbo for t
he src. | 2619 // CopyTexSubImage2D or fbo blit would require creating a temp fbo for t
he src. |
| 2650 return false; | 2620 return false; |
| 2651 } | 2621 } |
| 2652 | 2622 |
| 2653 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); | 2623 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); |
| 2654 if (srcRT && srcRT->renderFBO() != srcRT->textureFBO()) { | 2624 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { |
| 2655 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up
for FBO blit or | 2625 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up
for FBO blit or |
| 2656 // fail. | 2626 // fail. |
| 2657 if (this->caps()->isConfigRenderable(src->config(), false)) { | 2627 if (this->caps()->isConfigRenderable(src->config(), false)) { |
| 2658 desc->fOrigin = kDefault_GrSurfaceOrigin; | 2628 desc->fOrigin = kDefault_GrSurfaceOrigin; |
| 2659 desc->fFlags = kRenderTarget_GrSurfaceFlag; | 2629 desc->fFlags = kRenderTarget_GrSurfaceFlag; |
| 2660 desc->fConfig = src->config(); | 2630 desc->fConfig = src->config(); |
| 2661 return true; | 2631 return true; |
| 2662 } | 2632 } |
| 2663 return false; | 2633 return false; |
| 2664 } | 2634 } |
| 2665 | 2635 |
| 2666 // We'll do a CopyTexSubImage. Make the dst a plain old texture. | 2636 // We'll do a CopyTexSubImage. Make the dst a plain old texture. |
| 2667 desc->fConfig = src->config(); | 2637 desc->fConfig = src->config(); |
| 2668 desc->fOrigin = src->origin(); | 2638 desc->fOrigin = src->origin(); |
| 2669 desc->fFlags = kNone_GrSurfaceFlags; | 2639 desc->fFlags = kNone_GrSurfaceFlags; |
| 2670 return true; | 2640 return true; |
| 2671 } | 2641 } |
| 2672 | 2642 |
| 2673 bool GrGLGpu::copySurface(GrSurface* dst, | 2643 bool GrGLGpu::copySurface(GrSurface* dst, |
| 2674 GrSurface* src, | 2644 GrSurface* src, |
| 2675 const SkIRect& srcRect, | 2645 const SkIRect& srcRect, |
| 2676 const SkIPoint& dstPoint) { | 2646 const SkIPoint& dstPoint) { |
| 2677 bool copied = false; | 2647 bool copied = false; |
| 2678 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | |
| 2679 srcRect.width(), srcRect.height()); | |
| 2680 if (can_copy_texsubimage(dst, src, this)) { | 2648 if (can_copy_texsubimage(dst, src, this)) { |
| 2649 GrGLuint srcFBO; |
| 2681 GrGLIRect srcVP; | 2650 GrGLIRect srcVP; |
| 2682 FBOBinding srcFBOBinding = this->bindSurfaceAsFBOForCopy(src, kCopyTexSr
c_FBOBinding, | 2651 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_Tem
pFBOTarget); |
| 2683 &srcVP); | |
| 2684 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); | 2652 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); |
| 2685 SkASSERT(dstTex); | 2653 SkASSERT(dstTex); |
| 2654 // We modified the bound FBO |
| 2655 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 2686 GrGLIRect srcGLRect; | 2656 GrGLIRect srcGLRect; |
| 2687 srcGLRect.setRelativeTo(srcVP, | 2657 srcGLRect.setRelativeTo(srcVP, |
| 2688 srcRect.fLeft, | 2658 srcRect.fLeft, |
| 2689 srcRect.fTop, | 2659 srcRect.fTop, |
| 2690 srcRect.width(), | 2660 srcRect.width(), |
| 2691 srcRect.height(), | 2661 srcRect.height(), |
| 2692 src->origin()); | 2662 src->origin()); |
| 2693 | 2663 |
| 2694 this->setScratchTextureUnit(); | 2664 this->setScratchTextureUnit(); |
| 2695 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); | 2665 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); |
| 2696 GrGLint dstY; | 2666 GrGLint dstY; |
| 2697 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { | 2667 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { |
| 2698 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); | 2668 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); |
| 2699 } else { | 2669 } else { |
| 2700 dstY = dstPoint.fY; | 2670 dstY = dstPoint.fY; |
| 2701 } | 2671 } |
| 2702 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, | 2672 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, |
| 2703 dstPoint.fX, dstY, | 2673 dstPoint.fX, dstY, |
| 2704 srcGLRect.fLeft, srcGLRect.fBottom, | 2674 srcGLRect.fLeft, srcGLRect.fBottom, |
| 2705 srcGLRect.fWidth, srcGLRect.fHeight)); | 2675 srcGLRect.fWidth, srcGLRect.fHeight)); |
| 2706 copied = true; | 2676 copied = true; |
| 2707 this->unbindSurfaceAsFBOForCopy(srcFBOBinding); | 2677 if (srcFBO) { |
| 2678 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); |
| 2679 } |
| 2708 } else if (can_blit_framebuffer(dst, src, this)) { | 2680 } else if (can_blit_framebuffer(dst, src, this)) { |
| 2681 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, |
| 2682 srcRect.width(), srcRect.height()); |
| 2709 bool selfOverlap = false; | 2683 bool selfOverlap = false; |
| 2710 if (dst == src) { | 2684 if (dst == src) { |
| 2711 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); | 2685 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); |
| 2712 } | 2686 } |
| 2713 | 2687 |
| 2714 if (!selfOverlap) { | 2688 if (!selfOverlap) { |
| 2689 GrGLuint dstFBO; |
| 2690 GrGLuint srcFBO; |
| 2715 GrGLIRect dstVP; | 2691 GrGLIRect dstVP; |
| 2716 GrGLIRect srcVP; | 2692 GrGLIRect srcVP; |
| 2717 FBOBinding dstFBOBinding = this->bindSurfaceAsFBOForCopy(dst, kBlitD
st_FBOBinding, | 2693 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, |
| 2718 &dstVP); | 2694 kDst_TempFBOTarget); |
| 2719 FBOBinding srcFBOBinding = this->bindSurfaceAsFBOForCopy(src, kBlitS
rc_FBOBinding, | 2695 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, |
| 2720 &srcVP); | 2696 kSrc_TempFBOTarget); |
| 2721 | 2697 // We modified the bound FBO |
| 2698 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 2722 GrGLIRect srcGLRect; | 2699 GrGLIRect srcGLRect; |
| 2723 GrGLIRect dstGLRect; | 2700 GrGLIRect dstGLRect; |
| 2724 srcGLRect.setRelativeTo(srcVP, | 2701 srcGLRect.setRelativeTo(srcVP, |
| 2725 srcRect.fLeft, | 2702 srcRect.fLeft, |
| 2726 srcRect.fTop, | 2703 srcRect.fTop, |
| 2727 srcRect.width(), | 2704 srcRect.width(), |
| 2728 srcRect.height(), | 2705 srcRect.height(), |
| 2729 src->origin()); | 2706 src->origin()); |
| 2730 dstGLRect.setRelativeTo(dstVP, | 2707 dstGLRect.setRelativeTo(dstVP, |
| 2731 dstRect.fLeft, | 2708 dstRect.fLeft, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2749 } | 2726 } |
| 2750 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, | 2727 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, |
| 2751 srcY0, | 2728 srcY0, |
| 2752 srcGLRect.fLeft + srcGLRect.fWidth, | 2729 srcGLRect.fLeft + srcGLRect.fWidth, |
| 2753 srcY1, | 2730 srcY1, |
| 2754 dstGLRect.fLeft, | 2731 dstGLRect.fLeft, |
| 2755 dstGLRect.fBottom, | 2732 dstGLRect.fBottom, |
| 2756 dstGLRect.fLeft + dstGLRect.fWidth, | 2733 dstGLRect.fLeft + dstGLRect.fWidth, |
| 2757 dstGLRect.fBottom + dstGLRect.fHeight, | 2734 dstGLRect.fBottom + dstGLRect.fHeight, |
| 2758 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | 2735 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
| 2759 this->unbindSurfaceAsFBOForCopy(dstFBOBinding); | 2736 if (dstFBO) { |
| 2760 this->unbindSurfaceAsFBOForCopy(srcFBOBinding); | 2737 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER); |
| 2738 } |
| 2739 if (srcFBO) { |
| 2740 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER); |
| 2741 } |
| 2761 copied = true; | 2742 copied = true; |
| 2762 } | 2743 } |
| 2763 } | 2744 } |
| 2764 if (copied) { | |
| 2765 this->markSurfaceContentsDirty(dst, &dstRect); | |
| 2766 } | |
| 2767 return copied; | 2745 return copied; |
| 2768 } | 2746 } |
| 2769 | 2747 |
| 2770 bool GrGLGpu::canCopySurface(const GrSurface* dst, | 2748 bool GrGLGpu::canCopySurface(const GrSurface* dst, |
| 2771 const GrSurface* src, | 2749 const GrSurface* src, |
| 2772 const SkIRect& srcRect, | 2750 const SkIRect& srcRect, |
| 2773 const SkIPoint& dstPoint) { | 2751 const SkIPoint& dstPoint) { |
| 2774 // This mirrors the logic in onCopySurface. | 2752 // This mirrors the logic in onCopySurface. |
| 2775 if (can_copy_texsubimage(dst, src, this)) { | 2753 if (can_copy_texsubimage(dst, src, this)) { |
| 2776 return true; | 2754 return true; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2837 this->setVertexArrayID(gpu, 0); | 2815 this->setVertexArrayID(gpu, 0); |
| 2838 } | 2816 } |
| 2839 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2817 int attrCount = gpu->glCaps().maxVertexAttributes(); |
| 2840 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 2818 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
| 2841 fDefaultVertexArrayAttribState.resize(attrCount); | 2819 fDefaultVertexArrayAttribState.resize(attrCount); |
| 2842 } | 2820 } |
| 2843 attribState = &fDefaultVertexArrayAttribState; | 2821 attribState = &fDefaultVertexArrayAttribState; |
| 2844 } | 2822 } |
| 2845 return attribState; | 2823 return attribState; |
| 2846 } | 2824 } |
| OLD | NEW |