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