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 GL_CALL(RenderbufferStorage(GR_GL_RENDERBUFFER, GR_GL_RGBA8, wid
th, height)); | 1211 GL_CALL(RenderbufferStorage(GR_GL_RENDERBUFFER, GR_GL_RGBA8, wid
th, height)); |
1219 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1212 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1220 GR_GL_COLOR_ATTACHMENT0, | 1213 GR_GL_COLOR_ATTACHMENT0, |
1221 GR_GL_RENDERBUFFER, tempRB)); | 1214 GR_GL_RENDERBUFFER, tempRB)); |
1222 | 1215 |
1223 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1216 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
1224 | 1217 |
1225 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1218 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1226 GR_GL_COLOR_ATTACHMENT0, | 1219 GR_GL_COLOR_ATTACHMENT0, |
1227 GR_GL_RENDERBUFFER, 0)); | 1220 GR_GL_RENDERBUFFER, 0)); |
1228 GL_CALL(DeleteRenderbuffers(1, &tempRB)); | 1221 GL_CALL(DeleteRenderbuffers(1, &tempRB)); |
1229 | 1222 |
1230 // Unbind the SB from the FBO so that we don't keep it alive. | 1223 // Unbind the SB from the FBO so that we don't keep it alive. |
1231 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1224 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1232 GR_GL_STENCIL_ATTACHMENT, | 1225 GR_GL_STENCIL_ATTACHMENT, |
1233 GR_GL_RENDERBUFFER, 0)); | 1226 GR_GL_RENDERBUFFER, 0)); |
1234 if (sFmt.fPacked) { | 1227 if (sFmt.fPacked) { |
1235 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1228 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1236 GR_GL_DEPTH_ATTACHMENT, | 1229 GR_GL_DEPTH_ATTACHMENT, |
1237 GR_GL_RENDERBUFFER, 0)); | 1230 GR_GL_RENDERBUFFER, 0)); |
1238 } | 1231 } |
1239 | 1232 |
1240 return true; | 1233 return true; |
1241 } | 1234 } |
1242 // Remove the scratch key from this resource so we don't grab it fro
m the cache ever | 1235 // Remove the scratch key from this resource so we don't grab it fro
m the cache ever |
1243 // again. | 1236 // again. |
1244 sb->resourcePriv().removeScratchKey(); | 1237 sb->resourcePriv().removeScratchKey(); |
1245 // Set this to 0 since we handed the valid ID off to the failed sten
cil buffer resource. | 1238 // Set this to 0 since we handed the valid ID off to the failed sten
cil buffer resource. |
1246 sbDesc.fRenderbufferID = 0; | 1239 sbDesc.fRenderbufferID = 0; |
1247 } | 1240 } |
1248 } | 1241 } |
1249 GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); | 1242 GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); |
1250 return false; | 1243 return false; |
1251 } | 1244 } |
1252 | 1245 |
1253 bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { | 1246 bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { |
1254 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); | 1247 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); |
| 1248 |
| 1249 GrGLuint fbo = glrt->renderFBOID(); |
| 1250 |
1255 if (NULL == sb) { | 1251 if (NULL == sb) { |
1256 if (rt->renderTargetPriv().getStencilBuffer()) { | 1252 if (rt->renderTargetPriv().getStencilBuffer()) { |
1257 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1253 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1258 GR_GL_STENCIL_ATTACHMENT, | 1254 GR_GL_STENCIL_ATTACHMENT, |
1259 GR_GL_RENDERBUFFER, 0)); | 1255 GR_GL_RENDERBUFFER, 0)); |
1260 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1256 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1261 GR_GL_DEPTH_ATTACHMENT, | 1257 GR_GL_DEPTH_ATTACHMENT, |
1262 GR_GL_RENDERBUFFER, 0)); | 1258 GR_GL_RENDERBUFFER, 0)); |
1263 #ifdef SK_DEBUG | 1259 #ifdef SK_DEBUG |
1264 GrGLenum status; | 1260 GrGLenum status; |
1265 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1261 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
1266 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); | 1262 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); |
1267 #endif | 1263 #endif |
1268 } | 1264 } |
1269 return true; | 1265 return true; |
1270 } else { | 1266 } else { |
1271 GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); | 1267 GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); |
1272 GrGLuint rb = glsb->renderbufferID(); | 1268 GrGLuint rb = glsb->renderbufferID(); |
1273 GrGLenum fboTarget = this->bindFBO(kChangeAttachments_FBOBinding, glrt->
renderFBO()); | |
1274 | 1269 |
1275 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1270 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 1271 fStats.incRenderTargetBinds(); |
| 1272 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); |
| 1273 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1276 GR_GL_STENCIL_ATTACHMENT, | 1274 GR_GL_STENCIL_ATTACHMENT, |
1277 GR_GL_RENDERBUFFER, rb)); | 1275 GR_GL_RENDERBUFFER, rb)); |
1278 if (glsb->format().fPacked) { | 1276 if (glsb->format().fPacked) { |
1279 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1277 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1280 GR_GL_DEPTH_ATTACHMENT, | 1278 GR_GL_DEPTH_ATTACHMENT, |
1281 GR_GL_RENDERBUFFER, rb)); | 1279 GR_GL_RENDERBUFFER, rb)); |
1282 } else { | 1280 } else { |
1283 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1281 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1284 GR_GL_DEPTH_ATTACHMENT, | 1282 GR_GL_DEPTH_ATTACHMENT, |
1285 GR_GL_RENDERBUFFER, 0)); | 1283 GR_GL_RENDERBUFFER, 0)); |
1286 } | 1284 } |
1287 | 1285 |
1288 GrGLenum status; | 1286 GrGLenum status; |
1289 if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
glsb->format())) { | 1287 if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
glsb->format())) { |
1290 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1288 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
1291 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 1289 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
1292 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1290 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1293 GR_GL_STENCIL_ATTACHMENT, | 1291 GR_GL_STENCIL_ATTACHMENT, |
1294 GR_GL_RENDERBUFFER, 0)); | 1292 GR_GL_RENDERBUFFER, 0)); |
1295 if (glsb->format().fPacked) { | 1293 if (glsb->format().fPacked) { |
1296 GL_CALL(FramebufferRenderbuffer(fboTarget, | 1294 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1297 GR_GL_DEPTH_ATTACHMENT, | 1295 GR_GL_DEPTH_ATTACHMENT, |
1298 GR_GL_RENDERBUFFER, 0)); | 1296 GR_GL_RENDERBUFFER, 0)); |
1299 } | 1297 } |
1300 return false; | 1298 return false; |
1301 } else { | 1299 } else { |
1302 fGLContext.caps()->markColorConfigAndStencilFormatAsVerified( | 1300 fGLContext.caps()->markColorConfigAndStencilFormatAsVerified( |
1303 rt->config(), | 1301 rt->config(), |
1304 glsb->format()); | 1302 glsb->format()); |
1305 } | 1303 } |
1306 } | 1304 } |
1307 return true; | 1305 return true; |
1308 } | 1306 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 } | 1418 } |
1421 | 1419 |
1422 fCurrentProgram.get()->ref(); | 1420 fCurrentProgram.get()->ref(); |
1423 | 1421 |
1424 GrGLuint programID = fCurrentProgram->programID(); | 1422 GrGLuint programID = fCurrentProgram->programID(); |
1425 if (fHWProgramID != programID) { | 1423 if (fHWProgramID != programID) { |
1426 GL_CALL(UseProgram(programID)); | 1424 GL_CALL(UseProgram(programID)); |
1427 fHWProgramID = programID; | 1425 fHWProgramID = programID; |
1428 } | 1426 } |
1429 | 1427 |
| 1428 if (blendInfo.fWriteColor) { |
| 1429 this->flushBlend(blendInfo); |
| 1430 } |
1430 | 1431 |
1431 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr
acker); | 1432 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr
acker); |
1432 | 1433 |
1433 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); | 1434 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); |
1434 | |
1435 this->flushStencil(pipeline.getStencil()); | 1435 this->flushStencil(pipeline.getStencil()); |
1436 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); | 1436 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); |
1437 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); | 1437 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); |
1438 | 1438 |
1439 // This must come after textures are flushed because a texture may need | 1439 // This must come after textures are flushed because a texture may need |
1440 // to be msaa-resolved (which will modify bound FBO and scissor state). | 1440 // to be msaa-resolved (which will modify bound FBO state). |
1441 this->bindFBO(kDraw_FBOBinding, glRT->renderFBO()); | 1441 this->flushRenderTarget(glRT, NULL); |
1442 this->setViewport(glRT->getViewport()); | |
1443 if (blendInfo.fWriteColor) { | |
1444 this->flushBlend(blendInfo); | |
1445 this->markSurfaceContentsDirty(glRT, NULL); | |
1446 } | |
1447 | 1442 |
1448 return true; | 1443 return true; |
1449 } | 1444 } |
1450 | 1445 |
1451 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, | 1446 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, |
1452 const GrDrawTarget::DrawInfo& info, | 1447 const GrDrawTarget::DrawInfo& info, |
1453 size_t* indexOffsetInBytes) { | 1448 size_t* indexOffsetInBytes) { |
1454 GrGLVertexBuffer* vbuf; | 1449 GrGLVertexBuffer* vbuf; |
1455 vbuf = (GrGLVertexBuffer*) info.vertexBuffer(); | 1450 vbuf = (GrGLVertexBuffer*) info.vertexBuffer(); |
1456 | 1451 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1533 // flushScissor expects rect to be clipped to the target. | 1528 // flushScissor expects rect to be clipped to the target. |
1534 clippedRect = *rect; | 1529 clippedRect = *rect; |
1535 SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height()); | 1530 SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height()); |
1536 if (clippedRect.intersect(rtRect)) { | 1531 if (clippedRect.intersect(rtRect)) { |
1537 rect = &clippedRect; | 1532 rect = &clippedRect; |
1538 } else { | 1533 } else { |
1539 return; | 1534 return; |
1540 } | 1535 } |
1541 } | 1536 } |
1542 | 1537 |
1543 this->bindFBO(kClear_FBOBinding, glRT->renderFBO()); | 1538 this->flushRenderTarget(glRT, rect); |
1544 this->markSurfaceContentsDirty(glRT, rect); | |
1545 GrScissorState scissorState; | 1539 GrScissorState scissorState; |
1546 if (rect) { | 1540 if (rect) { |
1547 scissorState.set(*rect); | 1541 scissorState.set(*rect); |
1548 } | 1542 } |
1549 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); | 1543 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); |
1550 | 1544 |
1551 GrGLfloat r, g, b, a; | 1545 GrGLfloat r, g, b, a; |
1552 static const GrGLfloat scale255 = 1.f / 255.f; | 1546 static const GrGLfloat scale255 = 1.f / 255.f; |
1553 a = GrColorUnpackA(color) * scale255; | 1547 a = GrColorUnpackA(color) * scale255; |
1554 GrGLfloat scaleRGB = scale255; | 1548 GrGLfloat scaleRGB = scale255; |
1555 r = GrColorUnpackR(color) * scaleRGB; | 1549 r = GrColorUnpackR(color) * scaleRGB; |
1556 g = GrColorUnpackG(color) * scaleRGB; | 1550 g = GrColorUnpackG(color) * scaleRGB; |
1557 b = GrColorUnpackB(color) * scaleRGB; | 1551 b = GrColorUnpackB(color) * scaleRGB; |
1558 | 1552 |
1559 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); | 1553 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); |
1560 fHWWriteToColor = kYes_TriState; | 1554 fHWWriteToColor = kYes_TriState; |
1561 GL_CALL(ClearColor(r, g, b, a)); | 1555 GL_CALL(ClearColor(r, g, b, a)); |
1562 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); | 1556 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); |
1563 } | 1557 } |
1564 | 1558 |
1565 void GrGLGpu::discard(GrRenderTarget* renderTarget) { | 1559 void GrGLGpu::discard(GrRenderTarget* renderTarget) { |
1566 SkASSERT(renderTarget); | 1560 SkASSERT(renderTarget); |
1567 if (!this->caps()->discardRenderTargetSupport()) { | 1561 if (!this->caps()->discardRenderTargetSupport()) { |
1568 return; | 1562 return; |
1569 } | 1563 } |
1570 | 1564 |
1571 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); | 1565 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); |
1572 GrGLenum fboTarget = this->bindFBO(kDiscard_FBOBinding, glRT->renderFBO()); | 1566 if (renderTarget->getUniqueID() != fHWBoundRenderTargetUniqueID) { |
| 1567 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 1568 fStats.incRenderTargetBinds(); |
| 1569 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID())); |
| 1570 } |
1573 switch (this->glCaps().invalidateFBType()) { | 1571 switch (this->glCaps().invalidateFBType()) { |
1574 case GrGLCaps::kNone_InvalidateFBType: | 1572 case GrGLCaps::kNone_InvalidateFBType: |
1575 SkFAIL("Should never get here."); | 1573 SkFAIL("Should never get here."); |
1576 break; | 1574 break; |
1577 case GrGLCaps::kInvalidate_InvalidateFBType: | 1575 case GrGLCaps::kInvalidate_InvalidateFBType: |
1578 if (glRT->renderFBO()->isDefaultFramebuffer()) { | 1576 if (0 == glRT->renderFBOID()) { |
1579 // When rendering to the default framebuffer the legal values f
or attachments | 1577 // When rendering to the default framebuffer the legal values f
or attachments |
1580 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment | 1578 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment |
1581 // types. | 1579 // types. |
1582 static const GrGLenum attachments[] = { GR_GL_COLOR }; | 1580 static const GrGLenum attachments[] = { GR_GL_COLOR }; |
1583 GL_CALL(InvalidateFramebuffer(fboTarget, SK_ARRAY_COUNT(attachme
nts), | 1581 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(
attachments), |
1584 attachments)); | 1582 attachments)); |
1585 } else { | 1583 } else { |
1586 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; | 1584 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; |
1587 GL_CALL(InvalidateFramebuffer(fboTarget, SK_ARRAY_COUNT(attachme
nts), | 1585 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(
attachments), |
1588 attachments)); | 1586 attachments)); |
1589 } | 1587 } |
1590 break; | 1588 break; |
1591 case GrGLCaps::kDiscard_InvalidateFBType: { | 1589 case GrGLCaps::kDiscard_InvalidateFBType: { |
1592 if (glRT->renderFBO()->isDefaultFramebuffer()) { | 1590 if (0 == glRT->renderFBOID()) { |
1593 // When rendering to the default framebuffer the legal values f
or attachments | 1591 // When rendering to the default framebuffer the legal values f
or attachments |
1594 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment | 1592 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment |
1595 // types. See glDiscardFramebuffer() spec. | 1593 // types. See glDiscardFramebuffer() spec. |
1596 static const GrGLenum attachments[] = { GR_GL_COLOR }; | 1594 static const GrGLenum attachments[] = { GR_GL_COLOR }; |
1597 GL_CALL(DiscardFramebuffer(fboTarget, SK_ARRAY_COUNT(attachments
), | 1595 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att
achments), |
1598 attachments)); | 1596 attachments)); |
1599 } else { | 1597 } else { |
1600 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; | 1598 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; |
1601 GL_CALL(DiscardFramebuffer(fboTarget, SK_ARRAY_COUNT(attachments
), | 1599 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att
achments), |
1602 attachments)); | 1600 attachments)); |
1603 } | 1601 } |
1604 break; | 1602 break; |
1605 } | 1603 } |
1606 } | 1604 } |
1607 renderTarget->flagAsResolved(); | 1605 renderTarget->flagAsResolved(); |
1608 } | 1606 } |
1609 | 1607 |
1610 | 1608 |
1611 void GrGLGpu::clearStencil(GrRenderTarget* target) { | 1609 void GrGLGpu::clearStencil(GrRenderTarget* target) { |
1612 if (NULL == target) { | 1610 if (NULL == target) { |
1613 return; | 1611 return; |
1614 } | 1612 } |
1615 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); | 1613 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); |
1616 this->bindFBO(kClear_FBOBinding, glRT->renderFBO()); | 1614 this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); |
1617 | 1615 |
1618 this->disableScissor(); | 1616 this->disableScissor(); |
1619 | 1617 |
1620 GL_CALL(StencilMask(0xffffffff)); | 1618 GL_CALL(StencilMask(0xffffffff)); |
1621 GL_CALL(ClearStencil(0)); | 1619 GL_CALL(ClearStencil(0)); |
1622 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1620 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
1623 fHWStencilSettings.invalidate(); | 1621 fHWStencilSettings.invalidate(); |
1624 } | 1622 } |
1625 | 1623 |
1626 void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo
ol insideClip) { | 1624 void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo
ol insideClip) { |
(...skipping 15 matching lines...) Expand all Loading... |
1642 // zero the client's clip bits. So we just clear the whole thing. | 1640 // zero the client's clip bits. So we just clear the whole thing. |
1643 static const GrGLint clipStencilMask = ~0; | 1641 static const GrGLint clipStencilMask = ~0; |
1644 #endif | 1642 #endif |
1645 GrGLint value; | 1643 GrGLint value; |
1646 if (insideClip) { | 1644 if (insideClip) { |
1647 value = (1 << (stencilBitCount - 1)); | 1645 value = (1 << (stencilBitCount - 1)); |
1648 } else { | 1646 } else { |
1649 value = 0; | 1647 value = 0; |
1650 } | 1648 } |
1651 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); | 1649 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); |
1652 this->bindFBO(kClear_FBOBinding, glRT->renderFBO()); | 1650 this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); |
1653 | 1651 |
1654 GrScissorState scissorState; | 1652 GrScissorState scissorState; |
1655 scissorState.set(rect); | 1653 scissorState.set(rect); |
1656 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); | 1654 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); |
1657 | 1655 |
1658 GL_CALL(StencilMask((uint32_t) clipStencilMask)); | 1656 GL_CALL(StencilMask((uint32_t) clipStencilMask)); |
1659 GL_CALL(ClearStencil(value)); | 1657 GL_CALL(ClearStencil(value)); |
1660 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1658 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
1661 fHWStencilSettings.invalidate(); | 1659 fHWStencilSettings.invalidate(); |
1662 } | 1660 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1712 size_t bpp = GrBytesPerPixel(config); | 1710 size_t bpp = GrBytesPerPixel(config); |
1713 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, | 1711 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, |
1714 &left, &top, &width, &height, | 1712 &left, &top, &width, &height, |
1715 const_cast<const void**>(&buffer), | 1713 const_cast<const void**>(&buffer), |
1716 &rowBytes)) { | 1714 &rowBytes)) { |
1717 return false; | 1715 return false; |
1718 } | 1716 } |
1719 | 1717 |
1720 // resolve the render target if necessary | 1718 // resolve the render target if necessary |
1721 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); | 1719 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); |
1722 if (tgt->getResolveType() == GrGLRenderTarget::kCantResolve_ResolveType) { | 1720 switch (tgt->getResolveType()) { |
1723 return false; | 1721 case GrGLRenderTarget::kCantResolve_ResolveType: |
| 1722 return false; |
| 1723 case GrGLRenderTarget::kAutoResolves_ResolveType: |
| 1724 this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target), &SkI
Rect::EmptyIRect()); |
| 1725 break; |
| 1726 case GrGLRenderTarget::kCanResolve_ResolveType: |
| 1727 this->onResolveRenderTarget(tgt); |
| 1728 // we don't track the state of the READ FBO ID. |
| 1729 fStats.incRenderTargetBinds(); |
| 1730 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, |
| 1731 tgt->textureFBOID())); |
| 1732 break; |
| 1733 default: |
| 1734 SkFAIL("Unknown resolve type"); |
1724 } | 1735 } |
1725 if (tgt->getResolveType() == GrGLRenderTarget::kCanResolve_ResolveType) { | |
1726 this->onResolveRenderTarget(tgt); | |
1727 } | |
1728 this->bindFBO(kReadPixels_FBOBinding, tgt->textureFBO()); | |
1729 | 1736 |
1730 const GrGLIRect& glvp = tgt->getViewport(); | 1737 const GrGLIRect& glvp = tgt->getViewport(); |
1731 | 1738 |
1732 // the read rect is viewport-relative | 1739 // the read rect is viewport-relative |
1733 GrGLIRect readRect; | 1740 GrGLIRect readRect; |
1734 readRect.setRelativeTo(glvp, left, top, width, height, target->origin()); | 1741 readRect.setRelativeTo(glvp, left, top, width, height, target->origin()); |
1735 | 1742 |
1736 size_t tightRowBytes = bpp * width; | 1743 size_t tightRowBytes = bpp * width; |
1737 if (0 == rowBytes) { | 1744 if (0 == rowBytes) { |
1738 rowBytes = tightRowBytes; | 1745 rowBytes = tightRowBytes; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1783 char* bottom = top + (height - 1) * rowBytes; | 1790 char* bottom = top + (height - 1) * rowBytes; |
1784 for (int y = 0; y < halfY; y++) { | 1791 for (int y = 0; y < halfY; y++) { |
1785 memcpy(tmpRow, top, tightRowBytes); | 1792 memcpy(tmpRow, top, tightRowBytes); |
1786 memcpy(top, bottom, tightRowBytes); | 1793 memcpy(top, bottom, tightRowBytes); |
1787 memcpy(bottom, tmpRow, tightRowBytes); | 1794 memcpy(bottom, tmpRow, tightRowBytes); |
1788 top += rowBytes; | 1795 top += rowBytes; |
1789 bottom -= rowBytes; | 1796 bottom -= rowBytes; |
1790 } | 1797 } |
1791 } | 1798 } |
1792 } else { | 1799 } else { |
1793 SkASSERT(readDst != buffer); | 1800 SkASSERT(readDst != buffer); SkASSERT(rowBytes != tightRowBytes); |
1794 SkASSERT(rowBytes != tightRowBytes); | |
1795 // copy from readDst to buffer while flipping y | 1801 // copy from readDst to buffer while flipping y |
1796 // const int halfY = height >> 1; | 1802 // const int halfY = height >> 1; |
1797 const char* src = reinterpret_cast<const char*>(readDst); | 1803 const char* src = reinterpret_cast<const char*>(readDst); |
1798 char* dst = reinterpret_cast<char*>(buffer); | 1804 char* dst = reinterpret_cast<char*>(buffer); |
1799 if (flipY) { | 1805 if (flipY) { |
1800 dst += (height-1) * rowBytes; | 1806 dst += (height-1) * rowBytes; |
1801 } | 1807 } |
1802 for (int y = 0; y < height; y++) { | 1808 for (int y = 0; y < height; y++) { |
1803 memcpy(dst, src, tightRowBytes); | 1809 memcpy(dst, src, tightRowBytes); |
1804 src += readDstRowBytes; | 1810 src += readDstRowBytes; |
1805 if (!flipY) { | 1811 if (!flipY) { |
1806 dst += rowBytes; | 1812 dst += rowBytes; |
1807 } else { | 1813 } else { |
1808 dst -= rowBytes; | 1814 dst -= rowBytes; |
1809 } | 1815 } |
1810 } | 1816 } |
1811 } | 1817 } |
1812 return true; | 1818 return true; |
1813 } | 1819 } |
1814 | 1820 |
1815 GrGLenum GrGLGpu::bindFBO(FBOBinding binding, const GrGLFBO* fbo) { | 1821 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound)
{ |
1816 SkASSERT(fbo); | |
1817 SkASSERT(fbo->isValid()); | |
1818 | |
1819 enum { | |
1820 kDraw = 0, | |
1821 kRead = 1 | |
1822 }; | |
1823 | 1822 |
1824 bool useGLFramebuffer = !this->glCaps().usesMSAARenderBuffers() || | 1823 SkASSERT(target); |
1825 (this->glCaps().preferBindingToReadAndDrawFramebuffer() && | |
1826 kBlitSrc_FBOBinding != binding && kBlitDst_FBOBinding != binding); | |
1827 | 1824 |
1828 if (useGLFramebuffer) { | 1825 uint32_t rtID = target->getUniqueID(); |
1829 SkASSERT(kBlitSrc_FBOBinding != binding); | 1826 if (fHWBoundRenderTargetUniqueID != rtID) { |
1830 fStats.incRenderTargetBinds(); | 1827 fStats.incRenderTargetBinds(); |
1831 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo->fboID())); | 1828 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); |
1832 fHWFBOBinding[kDraw].fFBO.reset(SkRef(fbo)); | 1829 #ifdef SK_DEBUG |
1833 fHWFBOBinding[kRead].fFBO.reset(SkRef(fbo)); | 1830 // don't do this check in Chromium -- this is causing |
1834 return GR_GL_FRAMEBUFFER; | 1831 // lots of repeated command buffer flushes when the compositor is |
| 1832 // rendering with Ganesh, which is really slow; even too slow for |
| 1833 // Debug mode. |
| 1834 if (!this->glContext().isChromium()) { |
| 1835 GrGLenum status; |
| 1836 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 1837 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 1838 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x
\n", status); |
| 1839 } |
| 1840 } |
| 1841 #endif |
| 1842 fHWBoundRenderTargetUniqueID = rtID; |
| 1843 const GrGLIRect& vp = target->getViewport(); |
| 1844 if (fHWViewport != vp) { |
| 1845 vp.pushToGLViewport(this->glInterface()); |
| 1846 fHWViewport = vp; |
| 1847 } |
1835 } | 1848 } |
1836 GrGLenum target = 0; | 1849 if (NULL == bound || !bound->isEmpty()) { |
1837 HWFBOBinding* hwFBOBinding = NULL; | 1850 target->flagAsNeedingResolve(bound); |
1838 switch (binding) { | 1851 } |
1839 case kDraw_FBOBinding: | |
1840 case kClear_FBOBinding: | |
1841 case kDiscard_FBOBinding: | |
1842 case kChangeAttachments_FBOBinding: | |
1843 case kBlitDst_FBOBinding: | |
1844 target = GR_GL_DRAW_FRAMEBUFFER; | |
1845 hwFBOBinding = &fHWFBOBinding[kDraw]; | |
1846 break; | |
1847 | 1852 |
1848 case kReadPixels_FBOBinding: | 1853 GrTexture *texture = target->asTexture(); |
1849 case kBlitSrc_FBOBinding: | 1854 if (texture) { |
1850 target = GR_GL_READ_FRAMEBUFFER; | 1855 texture->texturePriv().dirtyMipMaps(true); |
1851 hwFBOBinding = &fHWFBOBinding[kRead]; | |
1852 break; | |
1853 } | |
1854 fStats.incRenderTargetBinds(); | |
1855 GL_CALL(BindFramebuffer(target, fbo->fboID())); | |
1856 hwFBOBinding->fFBO.reset(SkRef(fbo)); | |
1857 return target; | |
1858 } | |
1859 | |
1860 void GrGLGpu::setViewport(const GrGLIRect& viewport) { | |
1861 if (viewport != fHWViewport) { | |
1862 viewport.pushToGLViewport(this->glInterface()); | |
1863 fHWViewport = viewport; | |
1864 } | 1856 } |
1865 } | 1857 } |
1866 | 1858 |
1867 void GrGLGpu::markSurfaceContentsDirty(GrSurface* surface, const SkIRect* bounds
) { | |
1868 if (NULL == bounds || !bounds->isEmpty()) { | |
1869 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderT
arget()); | |
1870 if (rt) { | |
1871 rt->flagAsNeedingResolve(bounds); | |
1872 } | |
1873 GrGLTexture* texture = static_cast<GrGLTexture*>(surface->asTexture()); | |
1874 if (texture) { | |
1875 texture->texturePriv().dirtyMipMaps(true); | |
1876 } | |
1877 } | |
1878 } | |
1879 | |
1880 GrGLenum gPrimitiveType2GLMode[] = { | 1859 GrGLenum gPrimitiveType2GLMode[] = { |
1881 GR_GL_TRIANGLES, | 1860 GR_GL_TRIANGLES, |
1882 GR_GL_TRIANGLE_STRIP, | 1861 GR_GL_TRIANGLE_STRIP, |
1883 GR_GL_TRIANGLE_FAN, | 1862 GR_GL_TRIANGLE_FAN, |
1884 GR_GL_POINTS, | 1863 GR_GL_POINTS, |
1885 GR_GL_LINES, | 1864 GR_GL_LINES, |
1886 GR_GL_LINE_STRIP | 1865 GR_GL_LINE_STRIP |
1887 }; | 1866 }; |
1888 | 1867 |
1889 #define SWAP_PER_DRAW 0 | 1868 #define SWAP_PER_DRAW 0 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1948 | 1927 |
1949 void GrGLGpu::onStencilPath(const GrPath* path, const StencilPathState& state) { | 1928 void GrGLGpu::onStencilPath(const GrPath* path, const StencilPathState& state) { |
1950 this->flushColorWrite(false); | 1929 this->flushColorWrite(false); |
1951 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); | 1930 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
1952 | 1931 |
1953 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(state.fRenderTarget); | 1932 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(state.fRenderTarget); |
1954 SkISize size = SkISize::Make(rt->width(), rt->height()); | 1933 SkISize size = SkISize::Make(rt->width(), rt->height()); |
1955 this->glPathRendering()->setProjectionMatrix(*state.fViewMatrix, size, rt->o
rigin()); | 1934 this->glPathRendering()->setProjectionMatrix(*state.fViewMatrix, size, rt->o
rigin()); |
1956 this->flushScissor(*state.fScissor, rt->getViewport(), rt->origin()); | 1935 this->flushScissor(*state.fScissor, rt->getViewport(), rt->origin()); |
1957 this->flushHWAAState(rt, state.fUseHWAA); | 1936 this->flushHWAAState(rt, state.fUseHWAA); |
1958 this->bindFBO(kDraw_FBOBinding, rt->renderFBO()); | 1937 this->flushRenderTarget(rt, NULL); |
1959 this->setViewport(rt->getViewport()); | 1938 |
1960 fPathRendering->stencilPath(path, *state.fStencil); | 1939 fPathRendering->stencilPath(path, *state.fStencil); |
1961 } | 1940 } |
1962 | 1941 |
1963 void GrGLGpu::onDrawPath(const DrawArgs& args, const GrPath* path, | 1942 void GrGLGpu::onDrawPath(const DrawArgs& args, const GrPath* path, |
1964 const GrStencilSettings& stencil) { | 1943 const GrStencilSettings& stencil) { |
1965 if (!this->flushGLState(args)) { | 1944 if (!this->flushGLState(args)) { |
1966 return; | 1945 return; |
1967 } | 1946 } |
1968 fPathRendering->drawPath(path, stencil); | 1947 fPathRendering->drawPath(path, stencil); |
1969 } | 1948 } |
(...skipping 11 matching lines...) Expand all Loading... |
1981 } | 1960 } |
1982 fPathRendering->drawPaths(pathRange, indices, indexType, transformValues, | 1961 fPathRendering->drawPaths(pathRange, indices, indexType, transformValues, |
1983 transformType, count, stencil); | 1962 transformType, count, stencil); |
1984 } | 1963 } |
1985 | 1964 |
1986 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { | 1965 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { |
1987 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); | 1966 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); |
1988 if (rt->needsResolve()) { | 1967 if (rt->needsResolve()) { |
1989 // Some extensions automatically resolves the texture when it is read. | 1968 // Some extensions automatically resolves the texture when it is read. |
1990 if (this->glCaps().usesMSAARenderBuffers()) { | 1969 if (this->glCaps().usesMSAARenderBuffers()) { |
1991 SkASSERT(rt->textureFBO() != rt->renderFBO()); | 1970 SkASSERT(rt->textureFBOID() != rt->renderFBOID()); |
1992 this->bindFBO(kBlitSrc_FBOBinding, rt->renderFBO()); | 1971 fStats.incRenderTargetBinds(); |
1993 this->bindFBO(kBlitDst_FBOBinding, rt->textureFBO()); | 1972 fStats.incRenderTargetBinds(); |
| 1973 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID())); |
| 1974 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()))
; |
| 1975 // make sure we go through flushRenderTarget() since we've modified |
| 1976 // the bound DRAW FBO ID. |
| 1977 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
1994 const GrGLIRect& vp = rt->getViewport(); | 1978 const GrGLIRect& vp = rt->getViewport(); |
1995 const SkIRect dirtyRect = rt->getResolveRect(); | 1979 const SkIRect dirtyRect = rt->getResolveRect(); |
1996 | 1980 |
1997 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { | 1981 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { |
1998 // Apple's extension uses the scissor as the blit bounds. | 1982 // Apple's extension uses the scissor as the blit bounds. |
1999 GrScissorState scissorState; | 1983 GrScissorState scissorState; |
2000 scissorState.set(dirtyRect); | 1984 scissorState.set(dirtyRect); |
2001 this->flushScissor(scissorState, vp, rt->origin()); | 1985 this->flushScissor(scissorState, vp, rt->origin()); |
2002 GL_CALL(ResolveMultisampleFramebuffer()); | 1986 GL_CALL(ResolveMultisampleFramebuffer()); |
2003 } else { | 1987 } else { |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2537 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSub
Image | 2521 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSub
Image |
2538 // and BGRA isn't in the spec. There doesn't appear to be any extension that
adds it. Perhaps | 2522 // and BGRA isn't in the spec. There doesn't appear to be any extension that
adds it. Perhaps |
2539 // many drivers would allow it to work, but ANGLE does not. | 2523 // many drivers would allow it to work, but ANGLE does not. |
2540 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF
ormat() && | 2524 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF
ormat() && |
2541 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig =
= src->config())) { | 2525 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig =
= src->config())) { |
2542 return false; | 2526 return false; |
2543 } | 2527 } |
2544 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as
RenderTarget()); | 2528 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as
RenderTarget()); |
2545 // If dst is multisampled (and uses an extension where there is a separate M
SAA renderbuffer) | 2529 // If dst is multisampled (and uses an extension where there is a separate M
SAA renderbuffer) |
2546 // then we don't want to copy to the texture but to the MSAA buffer. | 2530 // then we don't want to copy to the texture but to the MSAA buffer. |
2547 if (dstRT && dstRT->renderFBO() != dstRT->textureFBO()) { | 2531 if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) { |
2548 return false; | 2532 return false; |
2549 } | 2533 } |
2550 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); | 2534 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); |
2551 // If the src is multisampled (and uses an extension where there is a separa
te MSAA | 2535 // If the src is multisampled (and uses an extension where there is a separa
te MSAA |
2552 // renderbuffer) then it is an invalid operation to call CopyTexSubImage | 2536 // renderbuffer) then it is an invalid operation to call CopyTexSubImage |
2553 if (srcRT && srcRT->renderFBO() != srcRT->textureFBO()) { | 2537 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { |
2554 return false; | 2538 return false; |
2555 } | 2539 } |
2556 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && | 2540 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && |
2557 dst->asTexture() && | 2541 dst->asTexture() && |
2558 dst->origin() == src->origin() && | 2542 dst->origin() == src->origin() && |
2559 !GrPixelConfigIsCompressed(src->config())) { | 2543 !GrPixelConfigIsCompressed(src->config())) { |
2560 return true; | 2544 return true; |
2561 } else { | 2545 } else { |
2562 return false; | 2546 return false; |
2563 } | 2547 } |
2564 } | 2548 } |
2565 | 2549 |
2566 } | 2550 } |
2567 | 2551 |
2568 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is | 2552 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is |
2569 // relative to is output. | 2553 // relative to is output. |
2570 GrGLGpu::FBOBinding GrGLGpu::bindSurfaceAsFBOForCopy(GrSurface* surface, FBOBind
ing binding, | 2554 GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLI
Rect* viewport, |
2571 GrGLIRect* viewport) { | 2555 TempFBOTarget tempFBOTarget) { |
2572 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); | 2556 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); |
2573 if (NULL == rt) { | 2557 if (NULL == rt) { |
2574 SkASSERT(surface->asTexture()); | 2558 SkASSERT(surface->asTexture()); |
2575 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); | 2559 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); |
2576 GrGLFBO* tempFBO; | 2560 GrGLuint* tempFBOID; |
| 2561 tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTem
pDstFBOID; |
2577 | 2562 |
2578 if (kBlitSrc_FBOBinding == binding) { | 2563 if (0 == *tempFBOID) { |
2579 if (!fTempSrcFBO) { | 2564 GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID)); |
2580 fTempSrcFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterface()))); | |
2581 SkASSERT(fTempSrcFBO->isValid()); | |
2582 } | |
2583 tempFBO = fTempSrcFBO; | |
2584 } else { | |
2585 SkASSERT(kBlitDst_FBOBinding == binding); | |
2586 if (!fTempDstFBO) { | |
2587 fTempDstFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterface()))); | |
2588 SkASSERT(fTempDstFBO->isValid()); | |
2589 } | |
2590 tempFBO = fTempDstFBO; | |
2591 } | 2565 } |
2592 | 2566 |
2593 GrGLenum target = this->bindFBO(binding, tempFBO); | 2567 fStats.incRenderTargetBinds(); |
2594 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(target, | 2568 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID)); |
| 2569 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
2595 GR_GL_COLOR_ATTACHM
ENT0, | 2570 GR_GL_COLOR_ATTACHM
ENT0, |
2596 GR_GL_TEXTURE_2D, | 2571 GR_GL_TEXTURE_2D, |
2597 texID, | 2572 texID, |
2598 0)); | 2573 0)); |
2599 viewport->fLeft = 0; | 2574 viewport->fLeft = 0; |
2600 viewport->fBottom = 0; | 2575 viewport->fBottom = 0; |
2601 viewport->fWidth = surface->width(); | 2576 viewport->fWidth = surface->width(); |
2602 viewport->fHeight = surface->height(); | 2577 viewport->fHeight = surface->height(); |
2603 return binding; | 2578 return *tempFBOID; |
2604 } else { | 2579 } else { |
2605 this->bindFBO(binding, rt->renderFBO()); | 2580 GrGLuint tempFBOID = 0; |
| 2581 fStats.incRenderTargetBinds(); |
| 2582 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO
ID())); |
2606 *viewport = rt->getViewport(); | 2583 *viewport = rt->getViewport(); |
2607 return kInvalidFBOBinding; | 2584 return tempFBOID; |
2608 } | 2585 } |
2609 } | 2586 } |
2610 | 2587 |
2611 void GrGLGpu::unbindSurfaceAsFBOForCopy(FBOBinding binding) { | 2588 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { |
2612 if (kInvalidFBOBinding == binding) { | 2589 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
2613 return; | |
2614 } | |
2615 GrGLFBO* tempFBO = kBlitDst_FBOBinding == binding ? fTempSrcFBO : fTempDstFB
O; | |
2616 GrGLenum target = this->bindFBO(binding, tempFBO); | |
2617 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(target, | |
2618 GR_GL_COLOR_ATTACHMENT0
, | 2590 GR_GL_COLOR_ATTACHMENT0
, |
2619 GR_GL_TEXTURE_2D, | 2591 GR_GL_TEXTURE_2D, |
2620 0, | 2592 0, |
2621 0)); | 2593 0)); |
2622 } | 2594 } |
2623 | 2595 |
2624 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ | 2596 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ |
2625 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If
neither are | 2597 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If
neither are |
2626 // possible and we return false to fallback to creating a render target dst
for render-to- | 2598 // possible and we return false to fallback to creating a render target dst
for render-to- |
2627 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger
ing temporary fbo | 2599 // texture. This code prefers CopyTexSubImage to fbo blit and avoids trigger
ing temporary fbo |
(...skipping 10 matching lines...) Expand all Loading... |
2638 desc->fConfig = kBGRA_8888_GrPixelConfig; | 2610 desc->fConfig = kBGRA_8888_GrPixelConfig; |
2639 return true; | 2611 return true; |
2640 } | 2612 } |
2641 return false; | 2613 return false; |
2642 } else if (NULL == src->asRenderTarget()) { | 2614 } else if (NULL == src->asRenderTarget()) { |
2643 // CopyTexSubImage2D or fbo blit would require creating a temp fbo for t
he src. | 2615 // CopyTexSubImage2D or fbo blit would require creating a temp fbo for t
he src. |
2644 return false; | 2616 return false; |
2645 } | 2617 } |
2646 | 2618 |
2647 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); | 2619 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); |
2648 if (srcRT && srcRT->renderFBO() != srcRT->textureFBO()) { | 2620 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { |
2649 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up
for FBO blit or | 2621 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up
for FBO blit or |
2650 // fail. | 2622 // fail. |
2651 if (this->caps()->isConfigRenderable(src->config(), false)) { | 2623 if (this->caps()->isConfigRenderable(src->config(), false)) { |
2652 desc->fOrigin = kDefault_GrSurfaceOrigin; | 2624 desc->fOrigin = kDefault_GrSurfaceOrigin; |
2653 desc->fFlags = kRenderTarget_GrSurfaceFlag; | 2625 desc->fFlags = kRenderTarget_GrSurfaceFlag; |
2654 desc->fConfig = src->config(); | 2626 desc->fConfig = src->config(); |
2655 return true; | 2627 return true; |
2656 } | 2628 } |
2657 return false; | 2629 return false; |
2658 } | 2630 } |
2659 | 2631 |
2660 // We'll do a CopyTexSubImage. Make the dst a plain old texture. | 2632 // We'll do a CopyTexSubImage. Make the dst a plain old texture. |
2661 desc->fConfig = src->config(); | 2633 desc->fConfig = src->config(); |
2662 desc->fOrigin = src->origin(); | 2634 desc->fOrigin = src->origin(); |
2663 desc->fFlags = kNone_GrSurfaceFlags; | 2635 desc->fFlags = kNone_GrSurfaceFlags; |
2664 return true; | 2636 return true; |
2665 } | 2637 } |
2666 | 2638 |
2667 bool GrGLGpu::copySurface(GrSurface* dst, | 2639 bool GrGLGpu::copySurface(GrSurface* dst, |
2668 GrSurface* src, | 2640 GrSurface* src, |
2669 const SkIRect& srcRect, | 2641 const SkIRect& srcRect, |
2670 const SkIPoint& dstPoint) { | 2642 const SkIPoint& dstPoint) { |
2671 bool copied = false; | 2643 bool copied = false; |
2672 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | |
2673 srcRect.width(), srcRect.height()); | |
2674 if (can_copy_texsubimage(dst, src, this)) { | 2644 if (can_copy_texsubimage(dst, src, this)) { |
| 2645 GrGLuint srcFBO; |
2675 GrGLIRect srcVP; | 2646 GrGLIRect srcVP; |
2676 FBOBinding srcFBOBinding = this->bindSurfaceAsFBOForCopy(src, kBlitSrc_F
BOBinding, &srcVP); | 2647 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_Tem
pFBOTarget); |
2677 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); | 2648 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); |
2678 SkASSERT(dstTex); | 2649 SkASSERT(dstTex); |
| 2650 // We modified the bound FBO |
| 2651 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
2679 GrGLIRect srcGLRect; | 2652 GrGLIRect srcGLRect; |
2680 srcGLRect.setRelativeTo(srcVP, | 2653 srcGLRect.setRelativeTo(srcVP, |
2681 srcRect.fLeft, | 2654 srcRect.fLeft, |
2682 srcRect.fTop, | 2655 srcRect.fTop, |
2683 srcRect.width(), | 2656 srcRect.width(), |
2684 srcRect.height(), | 2657 srcRect.height(), |
2685 src->origin()); | 2658 src->origin()); |
2686 | 2659 |
2687 this->setScratchTextureUnit(); | 2660 this->setScratchTextureUnit(); |
2688 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); | 2661 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); |
2689 GrGLint dstY; | 2662 GrGLint dstY; |
2690 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { | 2663 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { |
2691 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); | 2664 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); |
2692 } else { | 2665 } else { |
2693 dstY = dstPoint.fY; | 2666 dstY = dstPoint.fY; |
2694 } | 2667 } |
2695 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, | 2668 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, |
2696 dstPoint.fX, dstY, | 2669 dstPoint.fX, dstY, |
2697 srcGLRect.fLeft, srcGLRect.fBottom, | 2670 srcGLRect.fLeft, srcGLRect.fBottom, |
2698 srcGLRect.fWidth, srcGLRect.fHeight)); | 2671 srcGLRect.fWidth, srcGLRect.fHeight)); |
2699 copied = true; | 2672 copied = true; |
2700 this->unbindSurfaceAsFBOForCopy(srcFBOBinding); | 2673 if (srcFBO) { |
| 2674 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); |
| 2675 } |
2701 } else if (can_blit_framebuffer(dst, src, this)) { | 2676 } else if (can_blit_framebuffer(dst, src, this)) { |
| 2677 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, |
| 2678 srcRect.width(), srcRect.height()); |
2702 bool selfOverlap = false; | 2679 bool selfOverlap = false; |
2703 if (dst == src) { | 2680 if (dst == src) { |
2704 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); | 2681 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); |
2705 } | 2682 } |
2706 | 2683 |
2707 if (!selfOverlap) { | 2684 if (!selfOverlap) { |
| 2685 GrGLuint dstFBO; |
| 2686 GrGLuint srcFBO; |
2708 GrGLIRect dstVP; | 2687 GrGLIRect dstVP; |
2709 GrGLIRect srcVP; | 2688 GrGLIRect srcVP; |
2710 FBOBinding dstFBOBinding = this->bindSurfaceAsFBOForCopy(dst, kBlitD
st_FBOBinding, | 2689 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, |
2711 &dstVP); | 2690 kDst_TempFBOTarget); |
2712 FBOBinding srcFBOBinding = this->bindSurfaceAsFBOForCopy(src, kBlitS
rc_FBOBinding, | 2691 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, |
2713 &srcVP); | 2692 kSrc_TempFBOTarget); |
2714 | 2693 // We modified the bound FBO |
| 2694 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
2715 GrGLIRect srcGLRect; | 2695 GrGLIRect srcGLRect; |
2716 GrGLIRect dstGLRect; | 2696 GrGLIRect dstGLRect; |
2717 srcGLRect.setRelativeTo(srcVP, | 2697 srcGLRect.setRelativeTo(srcVP, |
2718 srcRect.fLeft, | 2698 srcRect.fLeft, |
2719 srcRect.fTop, | 2699 srcRect.fTop, |
2720 srcRect.width(), | 2700 srcRect.width(), |
2721 srcRect.height(), | 2701 srcRect.height(), |
2722 src->origin()); | 2702 src->origin()); |
2723 dstGLRect.setRelativeTo(dstVP, | 2703 dstGLRect.setRelativeTo(dstVP, |
2724 dstRect.fLeft, | 2704 dstRect.fLeft, |
(...skipping 17 matching lines...) Expand all Loading... |
2742 } | 2722 } |
2743 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, | 2723 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, |
2744 srcY0, | 2724 srcY0, |
2745 srcGLRect.fLeft + srcGLRect.fWidth, | 2725 srcGLRect.fLeft + srcGLRect.fWidth, |
2746 srcY1, | 2726 srcY1, |
2747 dstGLRect.fLeft, | 2727 dstGLRect.fLeft, |
2748 dstGLRect.fBottom, | 2728 dstGLRect.fBottom, |
2749 dstGLRect.fLeft + dstGLRect.fWidth, | 2729 dstGLRect.fLeft + dstGLRect.fWidth, |
2750 dstGLRect.fBottom + dstGLRect.fHeight, | 2730 dstGLRect.fBottom + dstGLRect.fHeight, |
2751 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | 2731 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
2752 this->unbindSurfaceAsFBOForCopy(dstFBOBinding); | 2732 if (dstFBO) { |
2753 this->unbindSurfaceAsFBOForCopy(srcFBOBinding); | 2733 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER); |
| 2734 } |
| 2735 if (srcFBO) { |
| 2736 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER); |
| 2737 } |
2754 copied = true; | 2738 copied = true; |
2755 } | 2739 } |
2756 } | 2740 } |
2757 if (copied) { | |
2758 this->markSurfaceContentsDirty(dst, &dstRect); | |
2759 } | |
2760 return copied; | 2741 return copied; |
2761 } | 2742 } |
2762 | 2743 |
2763 bool GrGLGpu::canCopySurface(const GrSurface* dst, | 2744 bool GrGLGpu::canCopySurface(const GrSurface* dst, |
2764 const GrSurface* src, | 2745 const GrSurface* src, |
2765 const SkIRect& srcRect, | 2746 const SkIRect& srcRect, |
2766 const SkIPoint& dstPoint) { | 2747 const SkIPoint& dstPoint) { |
2767 // This mirrors the logic in onCopySurface. | 2748 // This mirrors the logic in onCopySurface. |
2768 if (can_copy_texsubimage(dst, src, this)) { | 2749 if (can_copy_texsubimage(dst, src, this)) { |
2769 return true; | 2750 return true; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2830 this->setVertexArrayID(gpu, 0); | 2811 this->setVertexArrayID(gpu, 0); |
2831 } | 2812 } |
2832 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2813 int attrCount = gpu->glCaps().maxVertexAttributes(); |
2833 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 2814 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
2834 fDefaultVertexArrayAttribState.resize(attrCount); | 2815 fDefaultVertexArrayAttribState.resize(attrCount); |
2835 } | 2816 } |
2836 attribState = &fDefaultVertexArrayAttribState; | 2817 attribState = &fDefaultVertexArrayAttribState; |
2837 } | 2818 } |
2838 return attribState; | 2819 return attribState; |
2839 } | 2820 } |
OLD | NEW |