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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 } | 114 } |
115 | 115 |
116 /////////////////////////////////////////////////////////////////////////////// | 116 /////////////////////////////////////////////////////////////////////////////// |
117 | 117 |
118 static bool gPrintStartupSpew; | 118 static bool gPrintStartupSpew; |
119 | 119 |
120 GrGLGpu::GrGLGpu(const GrGLContext& ctx, GrContext* context) | 120 GrGLGpu::GrGLGpu(const GrGLContext& ctx, GrContext* context) |
121 : GrGpu(context) | 121 : GrGpu(context) |
122 , fGLContext(ctx) { | 122 , fGLContext(ctx) { |
123 | 123 |
| 124 fTempSrcFBO.reset(SkNEW(GrGLFBO)); |
| 125 fTempDstFBO.reset(SkNEW(GrGLFBO)); |
| 126 fStencilClearFBO.reset(SkNEW(GrGLFBO)); |
| 127 |
124 SkASSERT(ctx.isInitialized()); | 128 SkASSERT(ctx.isInitialized()); |
125 fCaps.reset(SkRef(ctx.caps())); | 129 fCaps.reset(SkRef(ctx.caps())); |
126 | 130 |
127 fHWBoundTextureUniqueIDs.reset(this->glCaps().maxFragmentTextureUnits()); | 131 fHWBoundTextureUniqueIDs.reset(this->glCaps().maxFragmentTextureUnits()); |
128 | 132 |
129 GrGLClearErr(fGLContext.interface()); | 133 GrGLClearErr(fGLContext.interface()); |
130 if (gPrintStartupSpew) { | 134 if (gPrintStartupSpew) { |
131 const GrGLubyte* vendor; | 135 const GrGLubyte* vendor; |
132 const GrGLubyte* renderer; | 136 const GrGLubyte* renderer; |
133 const GrGLubyte* version; | 137 const GrGLubyte* version; |
(...skipping 10 matching lines...) Expand all Loading... |
144 SkDebugf("\n"); | 148 SkDebugf("\n"); |
145 SkDebugf("%s", this->glCaps().dump().c_str()); | 149 SkDebugf("%s", this->glCaps().dump().c_str()); |
146 } | 150 } |
147 | 151 |
148 fProgramCache = SkNEW_ARGS(ProgramCache, (this)); | 152 fProgramCache = SkNEW_ARGS(ProgramCache, (this)); |
149 | 153 |
150 SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVe
rtexAttribs); | 154 SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVe
rtexAttribs); |
151 | 155 |
152 fLastSuccessfulStencilFmtIdx = 0; | 156 fLastSuccessfulStencilFmtIdx = 0; |
153 fHWProgramID = 0; | 157 fHWProgramID = 0; |
154 fTempSrcFBOID = 0; | |
155 fTempDstFBOID = 0; | |
156 fStencilClearFBOID = 0; | |
157 | 158 |
158 if (this->glCaps().pathRenderingSupport()) { | 159 if (this->glCaps().pathRenderingSupport()) { |
159 fPathRendering.reset(new GrGLPathRendering(this)); | 160 fPathRendering.reset(new GrGLPathRendering(this)); |
160 } | 161 } |
161 } | 162 } |
162 | 163 |
163 GrGLGpu::~GrGLGpu() { | 164 GrGLGpu::~GrGLGpu() { |
164 if (0 != fHWProgramID) { | 165 if (0 != fHWProgramID) { |
165 // detach the current program so there is no confusion on OpenGL's part | 166 // detach the current program so there is no confusion on OpenGL's part |
166 // that we want it to be deleted | 167 // that we want it to be deleted |
167 SkASSERT(fHWProgramID == fCurrentProgram->programID()); | 168 SkASSERT(fHWProgramID == fCurrentProgram->programID()); |
168 GL_CALL(UseProgram(0)); | 169 GL_CALL(UseProgram(0)); |
169 } | 170 } |
170 | 171 |
171 if (0 != fTempSrcFBOID) { | 172 fTempSrcFBO->deleteIfValid(this); |
172 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); | 173 fTempDstFBO->deleteIfValid(this); |
173 } | 174 fStencilClearFBO->deleteIfValid(this); |
174 if (0 != fTempDstFBOID) { | |
175 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); | |
176 } | |
177 if (0 != fStencilClearFBOID) { | |
178 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); | |
179 } | |
180 | 175 |
181 delete fProgramCache; | 176 delete fProgramCache; |
182 } | 177 } |
183 | 178 |
184 void GrGLGpu::contextAbandoned() { | 179 void GrGLGpu::contextAbandoned() { |
185 INHERITED::contextAbandoned(); | 180 INHERITED::contextAbandoned(); |
186 fProgramCache->abandon(); | 181 fProgramCache->abandon(); |
187 fHWProgramID = 0; | 182 fHWProgramID = 0; |
188 fTempSrcFBOID = 0; | 183 fTempSrcFBO->abandon(this); |
189 fTempDstFBOID = 0; | 184 fTempDstFBO->abandon(this); |
190 fStencilClearFBOID = 0; | 185 fStencilClearFBO->abandon(this); |
191 if (this->glCaps().pathRenderingSupport()) { | 186 if (this->glCaps().pathRenderingSupport()) { |
192 this->glPathRendering()->abandonGpuResources(); | 187 this->glPathRendering()->abandonGpuResources(); |
193 } | 188 } |
194 } | 189 } |
195 | 190 |
196 /////////////////////////////////////////////////////////////////////////////// | 191 /////////////////////////////////////////////////////////////////////////////// |
197 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, | 192 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig, |
198 GrPixelConfig surfaceConfig) co
nst { | 193 GrPixelConfig surfaceConfig) co
nst { |
199 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig
) { | 194 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig
) { |
200 return kBGRA_8888_GrPixelConfig; | 195 return kBGRA_8888_GrPixelConfig; |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 fHWStencilSettings.invalidate(); | 319 fHWStencilSettings.invalidate(); |
325 fHWStencilTestEnabled = kUnknown_TriState; | 320 fHWStencilTestEnabled = kUnknown_TriState; |
326 } | 321 } |
327 | 322 |
328 // Vertex | 323 // Vertex |
329 if (resetBits & kVertex_GrGLBackendState) { | 324 if (resetBits & kVertex_GrGLBackendState) { |
330 fHWGeometryState.invalidate(); | 325 fHWGeometryState.invalidate(); |
331 } | 326 } |
332 | 327 |
333 if (resetBits & kRenderTarget_GrGLBackendState) { | 328 if (resetBits & kRenderTarget_GrGLBackendState) { |
334 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 329 for (size_t i = 0; i < SK_ARRAY_COUNT(fHWFBOBinding); ++i) { |
| 330 fHWFBOBinding[i].invalidate(); |
| 331 } |
335 } | 332 } |
336 | 333 |
337 if (resetBits & kPathRendering_GrGLBackendState) { | 334 if (resetBits & kPathRendering_GrGLBackendState) { |
338 if (this->caps()->pathRenderingSupport()) { | 335 if (this->caps()->pathRenderingSupport()) { |
339 this->glPathRendering()->resetContext(); | 336 this->glPathRendering()->resetContext(); |
340 } | 337 } |
341 } | 338 } |
342 | 339 |
343 // we assume these values | 340 // we assume these values |
344 if (resetBits & kPixelStore_GrGLBackendState) { | 341 if (resetBits & kPixelStore_GrGLBackendState) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 } | 422 } |
426 if (NULL == texture) { | 423 if (NULL == texture) { |
427 return NULL; | 424 return NULL; |
428 } | 425 } |
429 | 426 |
430 return texture; | 427 return texture; |
431 } | 428 } |
432 | 429 |
433 GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
sc& wrapDesc) { | 430 GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
sc& wrapDesc) { |
434 GrGLRenderTarget::IDDesc idDesc; | 431 GrGLRenderTarget::IDDesc idDesc; |
435 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); | 432 GrGLuint fboID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); |
| 433 idDesc.fRenderFBO.reset(SkNEW_ARGS(GrGLFBO, (fboID))); |
436 idDesc.fMSColorRenderbufferID = 0; | 434 idDesc.fMSColorRenderbufferID = 0; |
437 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; | |
438 idDesc.fLifeCycle = GrGpuResource::kWrapped_LifeCycle; | 435 idDesc.fLifeCycle = GrGpuResource::kWrapped_LifeCycle; |
439 | 436 |
440 GrSurfaceDesc desc; | 437 GrSurfaceDesc desc; |
441 desc.fConfig = wrapDesc.fConfig; | 438 desc.fConfig = wrapDesc.fConfig; |
442 desc.fFlags = kCheckAllocation_GrSurfaceFlag; | 439 desc.fFlags = kCheckAllocation_GrSurfaceFlag; |
443 desc.fWidth = wrapDesc.fWidth; | 440 desc.fWidth = wrapDesc.fWidth; |
444 desc.fHeight = wrapDesc.fHeight; | 441 desc.fHeight = wrapDesc.fHeight; |
445 desc.fSampleCnt = wrapDesc.fSampleCnt; | 442 desc.fSampleCnt = wrapDesc.fSampleCnt; |
446 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); | 443 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); |
447 | 444 |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 case GrGLCaps::kNone_MSFBOType: | 804 case GrGLCaps::kNone_MSFBOType: |
808 SkFAIL("Shouldn't be here if we don't support multisampled renderbuf
fers."); | 805 SkFAIL("Shouldn't be here if we don't support multisampled renderbuf
fers."); |
809 break; | 806 break; |
810 } | 807 } |
811 return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface()));; | 808 return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface()));; |
812 } | 809 } |
813 | 810 |
814 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, bool budgeted
, GrGLuint texID, | 811 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, bool budgeted
, GrGLuint texID, |
815 GrGLRenderTarget::IDDesc* idDesc) { | 812 GrGLRenderTarget::IDDesc* idDesc) { |
816 idDesc->fMSColorRenderbufferID = 0; | 813 idDesc->fMSColorRenderbufferID = 0; |
817 idDesc->fRTFBOID = 0; | |
818 idDesc->fTexFBOID = 0; | |
819 idDesc->fLifeCycle = budgeted ? GrGpuResource::kCached_LifeCycle : | 814 idDesc->fLifeCycle = budgeted ? GrGpuResource::kCached_LifeCycle : |
820 GrGpuResource::kUncached_LifeCycle; | 815 GrGpuResource::kUncached_LifeCycle; |
821 | 816 |
822 GrGLenum status; | 817 GrGLenum status; |
823 | 818 |
824 GrGLenum msColorFormat = 0; // suppress warning | 819 GrGLenum msColorFormat = 0; // suppress warning |
825 | 820 |
826 if (desc.fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBO
Type()) { | 821 if (desc.fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBO
Type()) { |
827 goto FAILED; | 822 goto FAILED; |
828 } | 823 } |
829 | 824 |
830 GL_CALL(GenFramebuffers(1, &idDesc->fTexFBOID)); | 825 idDesc->fTextureFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterface()))); |
831 if (!idDesc->fTexFBOID) { | 826 if (!idDesc->fTextureFBO->isValid()) { |
832 goto FAILED; | 827 goto FAILED; |
833 } | 828 } |
834 | 829 |
835 | |
836 // If we are using multisampling we will create two FBOS. We render to one a
nd then resolve to | 830 // 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 | 831 // 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 | 832 // extension the texture is multisampled when rendered to and then auto-reso
lves it when it is |
839 // rendered from. | 833 // rendered from. |
840 if (desc.fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) { | 834 if (desc.fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) { |
841 GL_CALL(GenFramebuffers(1, &idDesc->fRTFBOID)); | 835 idDesc->fRenderFBO.reset(SkNEW_ARGS(GrGLFBO, (this->glInterface()))); |
| 836 if (!idDesc->fRenderFBO->isValid()) { |
| 837 goto FAILED; |
| 838 } |
842 GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); | 839 GL_CALL(GenRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); |
843 if (!idDesc->fRTFBOID || | 840 if (!idDesc->fMSColorRenderbufferID || |
844 !idDesc->fMSColorRenderbufferID || | |
845 !this->configToGLFormats(desc.fConfig, | 841 !this->configToGLFormats(desc.fConfig, |
846 // ES2 and ES3 require sized internal forma
ts for rb storage. | 842 // ES2 and ES3 require sized internal forma
ts for rb storage. |
847 kGLES_GrGLStandard == this->glStandard(), | 843 kGLES_GrGLStandard == this->glStandard(), |
848 &msColorFormat, | 844 &msColorFormat, |
849 NULL, | 845 NULL, |
850 NULL)) { | 846 NULL)) { |
851 goto FAILED; | 847 goto FAILED; |
852 } | 848 } |
853 } else { | 849 } else { |
854 idDesc->fRTFBOID = idDesc->fTexFBOID; | 850 idDesc->fRenderFBO.reset(SkRef(idDesc->fTextureFBO.get())); |
855 } | 851 } |
856 | 852 |
857 // below here we may bind the FBO | 853 if (idDesc->fRenderFBO != idDesc->fTextureFBO) { |
858 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | |
859 if (idDesc->fRTFBOID != idDesc->fTexFBOID) { | |
860 SkASSERT(desc.fSampleCnt > 0); | 854 SkASSERT(desc.fSampleCnt > 0); |
861 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe
rID)); | 855 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe
rID)); |
862 if (!renderbuffer_storage_msaa(fGLContext, | 856 if (!renderbuffer_storage_msaa(fGLContext, |
863 desc.fSampleCnt, | 857 desc.fSampleCnt, |
864 msColorFormat, | 858 msColorFormat, |
865 desc.fWidth, desc.fHeight)) { | 859 desc.fWidth, desc.fHeight)) { |
866 goto FAILED; | 860 goto FAILED; |
867 } | 861 } |
868 fStats.incRenderTargetBinds(); | 862 this->bindFBO(kDraw_FBOBinding, idDesc->fRenderFBO); |
869 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); | |
870 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 863 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
871 GR_GL_COLOR_ATTACHMENT0, | 864 GR_GL_COLOR_ATTACHMENT0, |
872 GR_GL_RENDERBUFFER, | 865 GR_GL_RENDERBUFFER, |
873 idDesc->fMSColorRenderbufferID)); | 866 idDesc->fMSColorRenderbufferID)); |
874 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || | 867 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || |
875 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { | 868 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { |
876 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 869 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
877 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 870 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
878 goto FAILED; | 871 goto FAILED; |
879 } | 872 } |
880 fGLContext.caps()->markConfigAsValidColorAttachment(desc.fConfig); | 873 fGLContext.caps()->markConfigAsValidColorAttachment(desc.fConfig); |
881 } | 874 } |
882 } | 875 } |
883 fStats.incRenderTargetBinds(); | 876 this->bindFBO(kDraw_FBOBinding, idDesc->fTextureFBO); |
884 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID)); | |
885 | 877 |
886 if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) { | 878 if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) { |
887 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, | 879 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, |
888 GR_GL_COLOR_ATTACHMENT0, | 880 GR_GL_COLOR_ATTACHMENT0, |
889 GR_GL_TEXTURE_2D, | 881 GR_GL_TEXTURE_2D, |
890 texID, 0, desc.fSampleCnt)); | 882 texID, 0, desc.fSampleCnt)); |
891 } else { | 883 } else { |
892 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, | 884 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, |
893 GR_GL_COLOR_ATTACHMENT0, | 885 GR_GL_COLOR_ATTACHMENT0, |
894 GR_GL_TEXTURE_2D, | 886 GR_GL_TEXTURE_2D, |
895 texID, 0)); | 887 texID, 0)); |
896 } | 888 } |
897 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || | 889 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || |
898 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { | 890 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { |
899 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 891 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
900 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 892 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
901 goto FAILED; | 893 goto FAILED; |
902 } | 894 } |
903 fGLContext.caps()->markConfigAsValidColorAttachment(desc.fConfig); | 895 fGLContext.caps()->markConfigAsValidColorAttachment(desc.fConfig); |
904 } | 896 } |
905 | 897 |
906 return true; | 898 return true; |
907 | 899 |
908 FAILED: | 900 FAILED: |
909 if (idDesc->fMSColorRenderbufferID) { | 901 if (idDesc->fMSColorRenderbufferID) { |
910 GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); | 902 GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID)); |
911 } | 903 } |
912 if (idDesc->fRTFBOID != idDesc->fTexFBOID) { | 904 idDesc->fRenderFBO->deleteIfValid(this); |
913 GL_CALL(DeleteFramebuffers(1, &idDesc->fRTFBOID)); | 905 idDesc->fTextureFBO->deleteIfValid(this); |
914 } | |
915 if (idDesc->fTexFBOID) { | |
916 GL_CALL(DeleteFramebuffers(1, &idDesc->fTexFBOID)); | |
917 } | |
918 return false; | 906 return false; |
919 } | 907 } |
920 | 908 |
921 // good to set a break-point here to know when createTexture fails | 909 // good to set a break-point here to know when createTexture fails |
922 static GrTexture* return_null_texture() { | 910 static GrTexture* return_null_texture() { |
923 // SkDEBUGFAIL("null texture"); | 911 // SkDEBUGFAIL("null texture"); |
924 return NULL; | 912 return NULL; |
925 } | 913 } |
926 | 914 |
927 #if 0 && defined(SK_DEBUG) | 915 #if 0 && defined(SK_DEBUG) |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 get_stencil_rb_sizes(this->glInterface(), &format); | 1167 get_stencil_rb_sizes(this->glInterface(), &format); |
1180 SkAutoTUnref<GrGLStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, | 1168 SkAutoTUnref<GrGLStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, |
1181 (this, sbDesc, width, height,
samples, format))); | 1169 (this, sbDesc, width, height,
samples, format))); |
1182 if (this->attachStencilBufferToRenderTarget(sb, rt)) { | 1170 if (this->attachStencilBufferToRenderTarget(sb, rt)) { |
1183 fLastSuccessfulStencilFmtIdx = sIdx; | 1171 fLastSuccessfulStencilFmtIdx = sIdx; |
1184 rt->renderTargetPriv().didAttachStencilBuffer(sb); | 1172 rt->renderTargetPriv().didAttachStencilBuffer(sb); |
1185 | 1173 |
1186 // Clear the stencil buffer. We use a special purpose FBO for th
is so that the | 1174 // 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 | 1175 // entire stencil buffer is cleared, even if it is attached to a
n FBO with a |
1188 // smaller color target. | 1176 // smaller color target. |
1189 if (0 == fStencilClearFBOID) { | 1177 fStencilClearFBO->generateIfInvalid(this->glInterface()); |
1190 GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); | 1178 this->bindFBO(kDraw_FBOBinding, fStencilClearFBO); |
1191 } | |
1192 | |
1193 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBOID)); | |
1194 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | |
1195 fStats.incRenderTargetBinds(); | |
1196 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1179 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1197 GR_GL_STENCIL_ATTACHMENT, | 1180 GR_GL_STENCIL_ATTACHMENT, |
1198 GR_GL_RENDERBUFFER, sbDesc.fRend
erbufferID)); | 1181 GR_GL_RENDERBUFFER, sbDesc.fRend
erbufferID)); |
1199 if (sFmt.fPacked) { | 1182 if (sFmt.fPacked) { |
1200 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1183 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1201 GR_GL_DEPTH_ATTACHMENT, | 1184 GR_GL_DEPTH_ATTACHMENT, |
1202 GR_GL_RENDERBUFFER, sbDesc.f
RenderbufferID)); | 1185 GR_GL_RENDERBUFFER, sbDesc.f
RenderbufferID)); |
1203 } | 1186 } |
1204 | 1187 |
1205 GL_CALL(ClearStencil(0)); | 1188 GL_CALL(ClearStencil(0)); |
(...skipping 17 matching lines...) Expand all Loading... |
1223 // Set this to 0 since we handed the valid ID off to the failed sten
cil buffer resource. | 1206 // Set this to 0 since we handed the valid ID off to the failed sten
cil buffer resource. |
1224 sbDesc.fRenderbufferID = 0; | 1207 sbDesc.fRenderbufferID = 0; |
1225 } | 1208 } |
1226 } | 1209 } |
1227 GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); | 1210 GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); |
1228 return false; | 1211 return false; |
1229 } | 1212 } |
1230 | 1213 |
1231 bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { | 1214 bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { |
1232 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); | 1215 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); |
1233 | |
1234 GrGLuint fbo = glrt->renderFBOID(); | |
1235 | |
1236 if (NULL == sb) { | 1216 if (NULL == sb) { |
1237 if (rt->renderTargetPriv().getStencilBuffer()) { | 1217 if (rt->renderTargetPriv().getStencilBuffer()) { |
1238 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1218 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1239 GR_GL_STENCIL_ATTACHMENT, | 1219 GR_GL_STENCIL_ATTACHMENT, |
1240 GR_GL_RENDERBUFFER, 0)); | 1220 GR_GL_RENDERBUFFER, 0)); |
1241 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1221 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1242 GR_GL_DEPTH_ATTACHMENT, | 1222 GR_GL_DEPTH_ATTACHMENT, |
1243 GR_GL_RENDERBUFFER, 0)); | 1223 GR_GL_RENDERBUFFER, 0)); |
1244 #ifdef SK_DEBUG | 1224 #ifdef SK_DEBUG |
1245 GrGLenum status; | 1225 GrGLenum status; |
1246 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1226 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
1247 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); | 1227 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); |
1248 #endif | 1228 #endif |
1249 } | 1229 } |
1250 return true; | 1230 return true; |
1251 } else { | 1231 } else { |
1252 GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); | 1232 GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); |
1253 GrGLuint rb = glsb->renderbufferID(); | 1233 GrGLuint rb = glsb->renderbufferID(); |
1254 | 1234 |
1255 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 1235 this->bindFBO(kDraw_FBOBinding, glrt->renderFBO()); |
1256 fStats.incRenderTargetBinds(); | 1236 |
1257 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); | |
1258 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1237 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1259 GR_GL_STENCIL_ATTACHMENT, | 1238 GR_GL_STENCIL_ATTACHMENT, |
1260 GR_GL_RENDERBUFFER, rb)); | 1239 GR_GL_RENDERBUFFER, rb)); |
1261 if (glsb->format().fPacked) { | 1240 if (glsb->format().fPacked) { |
1262 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1241 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1263 GR_GL_DEPTH_ATTACHMENT, | 1242 GR_GL_DEPTH_ATTACHMENT, |
1264 GR_GL_RENDERBUFFER, rb)); | 1243 GR_GL_RENDERBUFFER, rb)); |
1265 } else { | 1244 } else { |
1266 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1245 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1267 GR_GL_DEPTH_ATTACHMENT, | 1246 GR_GL_DEPTH_ATTACHMENT, |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 | 1395 |
1417 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr
acker); | 1396 fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTr
acker); |
1418 | 1397 |
1419 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); | 1398 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); |
1420 this->flushStencil(pipeline.getStencil()); | 1399 this->flushStencil(pipeline.getStencil()); |
1421 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); | 1400 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); |
1422 this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), isLineDraw); | 1401 this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), isLineDraw); |
1423 | 1402 |
1424 // This must come after textures are flushed because a texture may need | 1403 // This must come after textures are flushed because a texture may need |
1425 // to be msaa-resolved (which will modify bound FBO state). | 1404 // to be msaa-resolved (which will modify bound FBO state). |
1426 this->flushRenderTarget(glRT, NULL); | 1405 this->prepareToDrawToRenderTarget(glRT, NULL); |
1427 | 1406 |
1428 return true; | 1407 return true; |
1429 } | 1408 } |
1430 | 1409 |
1431 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, | 1410 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, |
1432 const GrDrawTarget::DrawInfo& info, | 1411 const GrDrawTarget::DrawInfo& info, |
1433 size_t* indexOffsetInBytes) { | 1412 size_t* indexOffsetInBytes) { |
1434 GrGLVertexBuffer* vbuf; | 1413 GrGLVertexBuffer* vbuf; |
1435 vbuf = (GrGLVertexBuffer*) info.vertexBuffer(); | 1414 vbuf = (GrGLVertexBuffer*) info.vertexBuffer(); |
1436 | 1415 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 // flushScissor expects rect to be clipped to the target. | 1492 // flushScissor expects rect to be clipped to the target. |
1514 clippedRect = *rect; | 1493 clippedRect = *rect; |
1515 SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height()); | 1494 SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height()); |
1516 if (clippedRect.intersect(rtRect)) { | 1495 if (clippedRect.intersect(rtRect)) { |
1517 rect = &clippedRect; | 1496 rect = &clippedRect; |
1518 } else { | 1497 } else { |
1519 return; | 1498 return; |
1520 } | 1499 } |
1521 } | 1500 } |
1522 | 1501 |
1523 this->flushRenderTarget(glRT, rect); | 1502 this->prepareToDrawToRenderTarget(glRT, rect); |
1524 GrScissorState scissorState; | 1503 GrScissorState scissorState; |
1525 if (rect) { | 1504 if (rect) { |
1526 scissorState.set(*rect); | 1505 scissorState.set(*rect); |
1527 } | 1506 } |
1528 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); | 1507 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); |
1529 | 1508 |
1530 GrGLfloat r, g, b, a; | 1509 GrGLfloat r, g, b, a; |
1531 static const GrGLfloat scale255 = 1.f / 255.f; | 1510 static const GrGLfloat scale255 = 1.f / 255.f; |
1532 a = GrColorUnpackA(color) * scale255; | 1511 a = GrColorUnpackA(color) * scale255; |
1533 GrGLfloat scaleRGB = scale255; | 1512 GrGLfloat scaleRGB = scale255; |
1534 r = GrColorUnpackR(color) * scaleRGB; | 1513 r = GrColorUnpackR(color) * scaleRGB; |
1535 g = GrColorUnpackG(color) * scaleRGB; | 1514 g = GrColorUnpackG(color) * scaleRGB; |
1536 b = GrColorUnpackB(color) * scaleRGB; | 1515 b = GrColorUnpackB(color) * scaleRGB; |
1537 | 1516 |
1538 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); | 1517 GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE)); |
1539 fHWWriteToColor = kYes_TriState; | 1518 fHWWriteToColor = kYes_TriState; |
1540 GL_CALL(ClearColor(r, g, b, a)); | 1519 GL_CALL(ClearColor(r, g, b, a)); |
1541 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); | 1520 GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT)); |
1542 } | 1521 } |
1543 | 1522 |
1544 void GrGLGpu::discard(GrRenderTarget* renderTarget) { | 1523 void GrGLGpu::discard(GrRenderTarget* renderTarget) { |
1545 SkASSERT(renderTarget); | 1524 SkASSERT(renderTarget); |
1546 if (!this->caps()->discardRenderTargetSupport()) { | 1525 if (!this->caps()->discardRenderTargetSupport()) { |
1547 return; | 1526 return; |
1548 } | 1527 } |
1549 | 1528 |
1550 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); | 1529 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); |
1551 if (renderTarget->getUniqueID() != fHWBoundRenderTargetUniqueID) { | 1530 this->bindFBO(kDraw_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()) { | 1531 switch (this->glCaps().invalidateFBType()) { |
1557 case GrGLCaps::kNone_InvalidateFBType: | 1532 case GrGLCaps::kNone_InvalidateFBType: |
1558 SkFAIL("Should never get here."); | 1533 SkFAIL("Should never get here."); |
1559 break; | 1534 break; |
1560 case GrGLCaps::kInvalidate_InvalidateFBType: | 1535 case GrGLCaps::kInvalidate_InvalidateFBType: |
1561 if (0 == glRT->renderFBOID()) { | 1536 if (glRT->renderFBO()->isDefaultFramebuffer()) { |
1562 // When rendering to the default framebuffer the legal values f
or attachments | 1537 // 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 | 1538 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment |
1564 // types. | 1539 // types. |
1565 static const GrGLenum attachments[] = { GR_GL_COLOR }; | 1540 static const GrGLenum attachments[] = { GR_GL_COLOR }; |
1566 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(
attachments), | 1541 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(
attachments), |
1567 attachments)); | 1542 attachments)); |
1568 } else { | 1543 } else { |
1569 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; | 1544 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; |
1570 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(
attachments), | 1545 GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(
attachments), |
1571 attachments)); | 1546 attachments)); |
1572 } | 1547 } |
1573 break; | 1548 break; |
1574 case GrGLCaps::kDiscard_InvalidateFBType: { | 1549 case GrGLCaps::kDiscard_InvalidateFBType: { |
1575 if (0 == glRT->renderFBOID()) { | 1550 if (glRT->renderFBO()->isDefaultFramebuffer()) { |
1576 // When rendering to the default framebuffer the legal values f
or attachments | 1551 // 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 | 1552 // are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the vari
ous FBO attachment |
1578 // types. See glDiscardFramebuffer() spec. | 1553 // types. See glDiscardFramebuffer() spec. |
1579 static const GrGLenum attachments[] = { GR_GL_COLOR }; | 1554 static const GrGLenum attachments[] = { GR_GL_COLOR }; |
1580 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att
achments), | 1555 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att
achments), |
1581 attachments)); | 1556 attachments)); |
1582 } else { | 1557 } else { |
1583 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; | 1558 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0
}; |
1584 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att
achments), | 1559 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att
achments), |
1585 attachments)); | 1560 attachments)); |
1586 } | 1561 } |
1587 break; | 1562 break; |
1588 } | 1563 } |
1589 } | 1564 } |
1590 renderTarget->flagAsResolved(); | 1565 renderTarget->flagAsResolved(); |
1591 } | 1566 } |
1592 | 1567 |
1593 | 1568 |
1594 void GrGLGpu::clearStencil(GrRenderTarget* target) { | 1569 void GrGLGpu::clearStencil(GrRenderTarget* target) { |
1595 if (NULL == target) { | 1570 if (NULL == target) { |
1596 return; | 1571 return; |
1597 } | 1572 } |
1598 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); | 1573 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); |
1599 this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); | 1574 this->prepareToDrawToRenderTarget(glRT, &SkIRect::EmptyIRect()); |
1600 | 1575 |
1601 this->disableScissor(); | 1576 this->disableScissor(); |
1602 | 1577 |
1603 GL_CALL(StencilMask(0xffffffff)); | 1578 GL_CALL(StencilMask(0xffffffff)); |
1604 GL_CALL(ClearStencil(0)); | 1579 GL_CALL(ClearStencil(0)); |
1605 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1580 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
1606 fHWStencilSettings.invalidate(); | 1581 fHWStencilSettings.invalidate(); |
1607 } | 1582 } |
1608 | 1583 |
1609 void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo
ol insideClip) { | 1584 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. | 1600 // zero the client's clip bits. So we just clear the whole thing. |
1626 static const GrGLint clipStencilMask = ~0; | 1601 static const GrGLint clipStencilMask = ~0; |
1627 #endif | 1602 #endif |
1628 GrGLint value; | 1603 GrGLint value; |
1629 if (insideClip) { | 1604 if (insideClip) { |
1630 value = (1 << (stencilBitCount - 1)); | 1605 value = (1 << (stencilBitCount - 1)); |
1631 } else { | 1606 } else { |
1632 value = 0; | 1607 value = 0; |
1633 } | 1608 } |
1634 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); | 1609 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); |
1635 this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); | 1610 this->prepareToDrawToRenderTarget(glRT, &SkIRect::EmptyIRect()); |
1636 | 1611 |
1637 GrScissorState scissorState; | 1612 GrScissorState scissorState; |
1638 scissorState.set(rect); | 1613 scissorState.set(rect); |
1639 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); | 1614 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); |
1640 | 1615 |
1641 GL_CALL(StencilMask((uint32_t) clipStencilMask)); | 1616 GL_CALL(StencilMask((uint32_t) clipStencilMask)); |
1642 GL_CALL(ClearStencil(value)); | 1617 GL_CALL(ClearStencil(value)); |
1643 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1618 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
1644 fHWStencilSettings.invalidate(); | 1619 fHWStencilSettings.invalidate(); |
1645 } | 1620 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 size_t bpp = GrBytesPerPixel(config); | 1670 size_t bpp = GrBytesPerPixel(config); |
1696 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, | 1671 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, |
1697 &left, &top, &width, &height, | 1672 &left, &top, &width, &height, |
1698 const_cast<const void**>(&buffer), | 1673 const_cast<const void**>(&buffer), |
1699 &rowBytes)) { | 1674 &rowBytes)) { |
1700 return false; | 1675 return false; |
1701 } | 1676 } |
1702 | 1677 |
1703 // resolve the render target if necessary | 1678 // resolve the render target if necessary |
1704 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); | 1679 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); |
1705 switch (tgt->getResolveType()) { | 1680 if (tgt->getResolveType() == GrGLRenderTarget::kCantResolve_ResolveType) { |
1706 case GrGLRenderTarget::kCantResolve_ResolveType: | 1681 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 } | 1682 } |
| 1683 if (tgt->getResolveType() == GrGLRenderTarget::kCanResolve_ResolveType) { |
| 1684 this->onResolveRenderTarget(tgt); |
| 1685 } |
| 1686 this->bindFBO(kRead_FBOBinding, tgt->textureFBO()); |
1721 | 1687 |
1722 const GrGLIRect& glvp = tgt->getViewport(); | 1688 const GrGLIRect& glvp = tgt->getViewport(); |
1723 | 1689 |
1724 // the read rect is viewport-relative | 1690 // the read rect is viewport-relative |
1725 GrGLIRect readRect; | 1691 GrGLIRect readRect; |
1726 readRect.setRelativeTo(glvp, left, top, width, height, target->origin()); | 1692 readRect.setRelativeTo(glvp, left, top, width, height, target->origin()); |
1727 | 1693 |
1728 size_t tightRowBytes = bpp * width; | 1694 size_t tightRowBytes = bpp * width; |
1729 if (0 == rowBytes) { | 1695 if (0 == rowBytes) { |
1730 rowBytes = tightRowBytes; | 1696 rowBytes = tightRowBytes; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1796 if (!flipY) { | 1762 if (!flipY) { |
1797 dst += rowBytes; | 1763 dst += rowBytes; |
1798 } else { | 1764 } else { |
1799 dst -= rowBytes; | 1765 dst -= rowBytes; |
1800 } | 1766 } |
1801 } | 1767 } |
1802 } | 1768 } |
1803 return true; | 1769 return true; |
1804 } | 1770 } |
1805 | 1771 |
1806 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound)
{ | 1772 void GrGLGpu::willDeleteOrAbandonFramebuffer(GrGLFBO* fbo) { |
1807 | 1773 for (size_t i = 0; i < SK_ARRAY_COUNT(fHWFBOBinding); ++i) { |
1808 SkASSERT(target); | 1774 if (fHWFBOBinding[i].fGenID == fbo->genID()) { |
1809 | 1775 fHWFBOBinding[i].invalidate(); |
1810 uint32_t rtID = target->getUniqueID(); | |
1811 if (fHWBoundRenderTargetUniqueID != rtID) { | |
1812 fStats.incRenderTargetBinds(); | |
1813 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); | |
1814 #ifdef SK_DEBUG | |
1815 // don't do this check in Chromium -- this is causing | |
1816 // lots of repeated command buffer flushes when the compositor is | |
1817 // rendering with Ganesh, which is really slow; even too slow for | |
1818 // Debug mode. | |
1819 if (!this->glContext().isChromium()) { | |
1820 GrGLenum status; | |
1821 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | |
1822 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | |
1823 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x
\n", status); | |
1824 } | |
1825 } | |
1826 #endif | |
1827 fHWBoundRenderTargetUniqueID = rtID; | |
1828 const GrGLIRect& vp = target->getViewport(); | |
1829 if (fHWViewport != vp) { | |
1830 vp.pushToGLViewport(this->glInterface()); | |
1831 fHWViewport = vp; | |
1832 } | 1776 } |
1833 } | 1777 } |
| 1778 } |
| 1779 |
| 1780 static GrGLenum glenum_for_binding(GrGLGpu::FBOBinding binding, const GrGLCaps&
caps) { |
| 1781 // If the GL doesn't have render buffers then it also doesn't have separate
read/write FBOs |
| 1782 if (caps.usesMSAARenderBuffers()) { |
| 1783 return GR_GL_FRAMEBUFFER; |
| 1784 } else { |
| 1785 if (GrGLGpu::kDraw_FBOBinding == binding) { |
| 1786 return GR_GL_DRAW_FRAMEBUFFER; |
| 1787 } else { |
| 1788 SkASSERT(GrGLGpu::kRead_FBOBinding == binding); |
| 1789 return GR_GL_READ_FRAMEBUFFER; |
| 1790 } |
| 1791 } |
| 1792 } |
| 1793 |
| 1794 GrGLenum GrGLGpu::bindFBO(FBOBinding binding, const GrGLFBO* fbo) { |
| 1795 GrGLenum target = glenum_for_binding(binding, this->glCaps()); |
| 1796 HWFBOBinding* hwFBOState; |
| 1797 if (!this->glCaps().usesMSAARenderBuffers()) { |
| 1798 hwFBOState = &fHWFBOBinding[0]; |
| 1799 } else { |
| 1800 hwFBOState = &fHWFBOBinding[binding]; |
| 1801 } |
| 1802 |
| 1803 if (hwFBOState->fGenID != fbo->genID()) { |
| 1804 fStats.incRenderTargetBinds(); |
| 1805 GL_CALL(BindFramebuffer(target, fbo->fboID())); |
| 1806 hwFBOState->fGenID = fbo->genID(); |
| 1807 hwFBOState->fIsDefaultFBO = fbo->isDefaultFramebuffer(); |
| 1808 } |
| 1809 return target; |
| 1810 } |
| 1811 |
| 1812 void GrGLGpu::setViewport(const GrGLIRect& viewport) { |
| 1813 if (viewport != fHWViewport) { |
| 1814 viewport.pushToGLViewport(this->glInterface()); |
| 1815 fHWViewport = viewport; |
| 1816 } |
| 1817 } |
| 1818 |
| 1819 void GrGLGpu::prepareToDrawToRenderTarget(GrGLRenderTarget* target, const SkIRec
t* bound) { |
| 1820 SkASSERT(target); |
| 1821 this->bindFBO(kDraw_FBOBinding, target->renderFBO()); |
| 1822 |
| 1823 #ifdef SK_DEBUG |
| 1824 // don't do this check in Chromium -- this is causing |
| 1825 // lots of repeated command buffer flushes when the compositor is |
| 1826 // rendering with Ganesh, which is really slow; even too slow for |
| 1827 // Debug mode. |
| 1828 if (!this->glContext().isChromium()) { |
| 1829 GrGLenum status; |
| 1830 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 1831 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 1832 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x\n",
status); |
| 1833 } |
| 1834 } |
| 1835 #endif |
| 1836 this->setViewport(target->getViewport()); |
1834 if (NULL == bound || !bound->isEmpty()) { | 1837 if (NULL == bound || !bound->isEmpty()) { |
1835 target->flagAsNeedingResolve(bound); | 1838 target->flagAsNeedingResolve(bound); |
1836 } | 1839 } |
1837 | 1840 |
1838 GrTexture *texture = target->asTexture(); | 1841 GrTexture *texture = target->asTexture(); |
1839 if (texture) { | 1842 if (texture) { |
1840 texture->texturePriv().dirtyMipMaps(true); | 1843 texture->texturePriv().dirtyMipMaps(true); |
1841 } | 1844 } |
1842 } | 1845 } |
1843 | 1846 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1912 | 1915 |
1913 void GrGLGpu::onStencilPath(const GrPath* path, const StencilPathState& state) { | 1916 void GrGLGpu::onStencilPath(const GrPath* path, const StencilPathState& state) { |
1914 this->flushColorWrite(false); | 1917 this->flushColorWrite(false); |
1915 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); | 1918 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
1916 | 1919 |
1917 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(state.fRenderTarget); | 1920 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(state.fRenderTarget); |
1918 SkISize size = SkISize::Make(rt->width(), rt->height()); | 1921 SkISize size = SkISize::Make(rt->width(), rt->height()); |
1919 this->glPathRendering()->setProjectionMatrix(*state.fViewMatrix, size, rt->o
rigin()); | 1922 this->glPathRendering()->setProjectionMatrix(*state.fViewMatrix, size, rt->o
rigin()); |
1920 this->flushScissor(*state.fScissor, rt->getViewport(), rt->origin()); | 1923 this->flushScissor(*state.fScissor, rt->getViewport(), rt->origin()); |
1921 this->flushHWAAState(rt, state.fUseHWAA, false); | 1924 this->flushHWAAState(rt, state.fUseHWAA, false); |
1922 this->flushRenderTarget(rt, NULL); | 1925 this->prepareToDrawToRenderTarget(rt, NULL); |
1923 | 1926 |
1924 fPathRendering->stencilPath(path, *state.fStencil); | 1927 fPathRendering->stencilPath(path, *state.fStencil); |
1925 } | 1928 } |
1926 | 1929 |
1927 void GrGLGpu::onDrawPath(const DrawArgs& args, const GrPath* path, | 1930 void GrGLGpu::onDrawPath(const DrawArgs& args, const GrPath* path, |
1928 const GrStencilSettings& stencil) { | 1931 const GrStencilSettings& stencil) { |
1929 if (!this->flushGLState(args, false)) { | 1932 if (!this->flushGLState(args, false)) { |
1930 return; | 1933 return; |
1931 } | 1934 } |
1932 fPathRendering->drawPath(path, stencil); | 1935 fPathRendering->drawPath(path, stencil); |
(...skipping 12 matching lines...) Expand all Loading... |
1945 } | 1948 } |
1946 fPathRendering->drawPaths(pathRange, indices, indexType, transformValues, | 1949 fPathRendering->drawPaths(pathRange, indices, indexType, transformValues, |
1947 transformType, count, stencil); | 1950 transformType, count, stencil); |
1948 } | 1951 } |
1949 | 1952 |
1950 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { | 1953 void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { |
1951 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); | 1954 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); |
1952 if (rt->needsResolve()) { | 1955 if (rt->needsResolve()) { |
1953 // Some extensions automatically resolves the texture when it is read. | 1956 // Some extensions automatically resolves the texture when it is read. |
1954 if (this->glCaps().usesMSAARenderBuffers()) { | 1957 if (this->glCaps().usesMSAARenderBuffers()) { |
1955 SkASSERT(rt->textureFBOID() != rt->renderFBOID()); | 1958 SkASSERT(rt->textureFBO() != rt->renderFBO()); |
1956 fStats.incRenderTargetBinds(); | 1959 this->bindFBO(kRead_FBOBinding, rt->renderFBO()); |
1957 fStats.incRenderTargetBinds(); | 1960 this->bindFBO(kDraw_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(); | 1961 const GrGLIRect& vp = rt->getViewport(); |
1964 const SkIRect dirtyRect = rt->getResolveRect(); | 1962 const SkIRect dirtyRect = rt->getResolveRect(); |
1965 | 1963 |
1966 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { | 1964 if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { |
1967 // Apple's extension uses the scissor as the blit bounds. | 1965 // Apple's extension uses the scissor as the blit bounds. |
1968 GrScissorState scissorState; | 1966 GrScissorState scissorState; |
1969 scissorState.set(dirtyRect); | 1967 scissorState.set(dirtyRect); |
1970 this->flushScissor(scissorState, vp, rt->origin()); | 1968 this->flushScissor(scissorState, vp, rt->origin()); |
1971 GL_CALL(ResolveMultisampleFramebuffer()); | 1969 GL_CALL(ResolveMultisampleFramebuffer()); |
1972 } else { | 1970 } 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 | 2513 // 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 | 2514 // 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. | 2515 // many drivers would allow it to work, but ANGLE does not. |
2518 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF
ormat() && | 2516 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF
ormat() && |
2519 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig =
= src->config())) { | 2517 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig =
= src->config())) { |
2520 return false; | 2518 return false; |
2521 } | 2519 } |
2522 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as
RenderTarget()); | 2520 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) | 2521 // 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. | 2522 // then we don't want to copy to the texture but to the MSAA buffer. |
2525 if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) { | 2523 if (dstRT && dstRT->renderFBO() != dstRT->textureFBO()) { |
2526 return false; | 2524 return false; |
2527 } | 2525 } |
2528 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); | 2526 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 | 2527 // 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 | 2528 // renderbuffer) then it is an invalid operation to call CopyTexSubImage |
2531 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { | 2529 if (srcRT && srcRT->renderFBO() != srcRT->textureFBO()) { |
2532 return false; | 2530 return false; |
2533 } | 2531 } |
2534 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && | 2532 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && |
2535 dst->asTexture() && | 2533 dst->asTexture() && |
2536 dst->origin() == src->origin() && | 2534 dst->origin() == src->origin() && |
2537 !GrPixelConfigIsCompressed(src->config())) { | 2535 !GrPixelConfigIsCompressed(src->config())) { |
2538 return true; | 2536 return true; |
2539 } else { | 2537 } else { |
2540 return false; | 2538 return false; |
2541 } | 2539 } |
2542 } | 2540 } |
2543 | 2541 |
2544 } | 2542 } |
2545 | 2543 |
2546 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is | 2544 // 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. | 2545 // relative to is output. |
2548 GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLI
Rect* viewport, | 2546 GrGLGpu::FBOBinding GrGLGpu::bindSurfaceAsFBOForCopy(GrSurface* surface, FBOBind
ing binding, |
2549 TempFBOTarget tempFBOTarget) { | 2547 GrGLIRect* viewport) { |
2550 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); | 2548 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); |
2551 if (NULL == rt) { | 2549 if (NULL == rt) { |
2552 SkASSERT(surface->asTexture()); | 2550 SkASSERT(surface->asTexture()); |
2553 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); | 2551 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); |
2554 GrGLuint* tempFBOID; | 2552 GrGLFBO* tempFBO = kDraw_FBOBinding == binding ? fTempSrcFBO : fTempDstF
BO; |
2555 tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTem
pDstFBOID; | |
2556 | 2553 |
2557 if (0 == *tempFBOID) { | 2554 tempFBO->generateIfInvalid(this->glInterface()); |
2558 GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID)); | 2555 GrGLenum target = this->bindFBO(binding, tempFBO); |
2559 } | 2556 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(target, |
2560 | |
2561 fStats.incRenderTargetBinds(); | |
2562 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID)); | |
2563 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | |
2564 GR_GL_COLOR_ATTACHM
ENT0, | 2557 GR_GL_COLOR_ATTACHM
ENT0, |
2565 GR_GL_TEXTURE_2D, | 2558 GR_GL_TEXTURE_2D, |
2566 texID, | 2559 texID, |
2567 0)); | 2560 0)); |
2568 viewport->fLeft = 0; | 2561 viewport->fLeft = 0; |
2569 viewport->fBottom = 0; | 2562 viewport->fBottom = 0; |
2570 viewport->fWidth = surface->width(); | 2563 viewport->fWidth = surface->width(); |
2571 viewport->fHeight = surface->height(); | 2564 viewport->fHeight = surface->height(); |
2572 return *tempFBOID; | 2565 return binding; |
2573 } else { | 2566 } else { |
2574 GrGLuint tempFBOID = 0; | 2567 this->bindFBO(binding, rt->renderFBO()); |
2575 fStats.incRenderTargetBinds(); | |
2576 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO
ID())); | |
2577 *viewport = rt->getViewport(); | 2568 *viewport = rt->getViewport(); |
2578 return tempFBOID; | 2569 return kInvalidFBOBinding; |
2579 } | 2570 } |
2580 } | 2571 } |
2581 | 2572 |
2582 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { | 2573 void GrGLGpu::unbindSurfaceAsFBOForCopy(FBOBinding binding) { |
2583 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | 2574 if (kInvalidFBOBinding == binding) { |
| 2575 return; |
| 2576 } |
| 2577 GrGLFBO* tempFBO = kDraw_FBOBinding == binding ? fTempSrcFBO : fTempDstFBO; |
| 2578 GrGLenum target = this->bindFBO(binding, tempFBO); |
| 2579 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(target, |
2584 GR_GL_COLOR_ATTACHMENT0
, | 2580 GR_GL_COLOR_ATTACHMENT0
, |
2585 GR_GL_TEXTURE_2D, | 2581 GR_GL_TEXTURE_2D, |
2586 0, | 2582 0, |
2587 0)); | 2583 0)); |
2588 } | 2584 } |
2589 | 2585 |
2590 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ | 2586 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
{ |
2591 // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If
neither are | 2587 // 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- | 2588 // 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 | 2589 // 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; | 2600 desc->fConfig = kBGRA_8888_GrPixelConfig; |
2605 return true; | 2601 return true; |
2606 } | 2602 } |
2607 return false; | 2603 return false; |
2608 } else if (NULL == src->asRenderTarget()) { | 2604 } else if (NULL == src->asRenderTarget()) { |
2609 // CopyTexSubImage2D or fbo blit would require creating a temp fbo for t
he src. | 2605 // CopyTexSubImage2D or fbo blit would require creating a temp fbo for t
he src. |
2610 return false; | 2606 return false; |
2611 } | 2607 } |
2612 | 2608 |
2613 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); | 2609 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); |
2614 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { | 2610 if (srcRT && srcRT->renderFBO() != srcRT->textureFBO()) { |
2615 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up
for FBO blit or | 2611 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up
for FBO blit or |
2616 // fail. | 2612 // fail. |
2617 if (this->caps()->isConfigRenderable(src->config(), false)) { | 2613 if (this->caps()->isConfigRenderable(src->config(), false)) { |
2618 desc->fOrigin = kDefault_GrSurfaceOrigin; | 2614 desc->fOrigin = kDefault_GrSurfaceOrigin; |
2619 desc->fFlags = kRenderTarget_GrSurfaceFlag; | 2615 desc->fFlags = kRenderTarget_GrSurfaceFlag; |
2620 desc->fConfig = src->config(); | 2616 desc->fConfig = src->config(); |
2621 return true; | 2617 return true; |
2622 } | 2618 } |
2623 return false; | 2619 return false; |
2624 } | 2620 } |
2625 | 2621 |
2626 // We'll do a CopyTexSubImage. Make the dst a plain old texture. | 2622 // We'll do a CopyTexSubImage. Make the dst a plain old texture. |
2627 desc->fConfig = src->config(); | 2623 desc->fConfig = src->config(); |
2628 desc->fOrigin = src->origin(); | 2624 desc->fOrigin = src->origin(); |
2629 desc->fFlags = kNone_GrSurfaceFlags; | 2625 desc->fFlags = kNone_GrSurfaceFlags; |
2630 return true; | 2626 return true; |
2631 } | 2627 } |
2632 | 2628 |
2633 bool GrGLGpu::copySurface(GrSurface* dst, | 2629 bool GrGLGpu::copySurface(GrSurface* dst, |
2634 GrSurface* src, | 2630 GrSurface* src, |
2635 const SkIRect& srcRect, | 2631 const SkIRect& srcRect, |
2636 const SkIPoint& dstPoint) { | 2632 const SkIPoint& dstPoint) { |
2637 bool copied = false; | 2633 bool copied = false; |
2638 if (can_copy_texsubimage(dst, src, this)) { | 2634 if (can_copy_texsubimage(dst, src, this)) { |
2639 GrGLuint srcFBO; | |
2640 GrGLIRect srcVP; | 2635 GrGLIRect srcVP; |
2641 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_Tem
pFBOTarget); | 2636 FBOBinding srcFBOBinding = this->bindSurfaceAsFBOForCopy(src, kRead_FBOB
inding, &srcVP); |
2642 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); | 2637 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); |
2643 SkASSERT(dstTex); | 2638 SkASSERT(dstTex); |
2644 // We modified the bound FBO | |
2645 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | |
2646 GrGLIRect srcGLRect; | 2639 GrGLIRect srcGLRect; |
2647 srcGLRect.setRelativeTo(srcVP, | 2640 srcGLRect.setRelativeTo(srcVP, |
2648 srcRect.fLeft, | 2641 srcRect.fLeft, |
2649 srcRect.fTop, | 2642 srcRect.fTop, |
2650 srcRect.width(), | 2643 srcRect.width(), |
2651 srcRect.height(), | 2644 srcRect.height(), |
2652 src->origin()); | 2645 src->origin()); |
2653 | 2646 |
2654 this->setScratchTextureUnit(); | 2647 this->setScratchTextureUnit(); |
2655 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); | 2648 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); |
2656 GrGLint dstY; | 2649 GrGLint dstY; |
2657 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { | 2650 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { |
2658 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); | 2651 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); |
2659 } else { | 2652 } else { |
2660 dstY = dstPoint.fY; | 2653 dstY = dstPoint.fY; |
2661 } | 2654 } |
2662 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, | 2655 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, |
2663 dstPoint.fX, dstY, | 2656 dstPoint.fX, dstY, |
2664 srcGLRect.fLeft, srcGLRect.fBottom, | 2657 srcGLRect.fLeft, srcGLRect.fBottom, |
2665 srcGLRect.fWidth, srcGLRect.fHeight)); | 2658 srcGLRect.fWidth, srcGLRect.fHeight)); |
2666 copied = true; | 2659 copied = true; |
2667 if (srcFBO) { | 2660 this->unbindSurfaceAsFBOForCopy(srcFBOBinding); |
2668 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); | |
2669 } | |
2670 } else if (can_blit_framebuffer(dst, src, this)) { | 2661 } else if (can_blit_framebuffer(dst, src, this)) { |
2671 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | 2662 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, |
2672 srcRect.width(), srcRect.height()); | 2663 srcRect.width(), srcRect.height()); |
2673 bool selfOverlap = false; | 2664 bool selfOverlap = false; |
2674 if (dst == src) { | 2665 if (dst == src) { |
2675 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); | 2666 selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect); |
2676 } | 2667 } |
2677 | 2668 |
2678 if (!selfOverlap) { | 2669 if (!selfOverlap) { |
2679 GrGLuint dstFBO; | |
2680 GrGLuint srcFBO; | |
2681 GrGLIRect dstVP; | 2670 GrGLIRect dstVP; |
2682 GrGLIRect srcVP; | 2671 GrGLIRect srcVP; |
2683 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, | 2672 FBOBinding dstFBOBinding = this->bindSurfaceAsFBOForCopy(dst, kDraw_
FBOBinding, &dstVP); |
2684 kDst_TempFBOTarget); | 2673 FBOBinding srcFBOBinding = this->bindSurfaceAsFBOForCopy(src, kRead_
FBOBinding, &srcVP); |
2685 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, | 2674 |
2686 kSrc_TempFBOTarget); | |
2687 // We modified the bound FBO | |
2688 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | |
2689 GrGLIRect srcGLRect; | 2675 GrGLIRect srcGLRect; |
2690 GrGLIRect dstGLRect; | 2676 GrGLIRect dstGLRect; |
2691 srcGLRect.setRelativeTo(srcVP, | 2677 srcGLRect.setRelativeTo(srcVP, |
2692 srcRect.fLeft, | 2678 srcRect.fLeft, |
2693 srcRect.fTop, | 2679 srcRect.fTop, |
2694 srcRect.width(), | 2680 srcRect.width(), |
2695 srcRect.height(), | 2681 srcRect.height(), |
2696 src->origin()); | 2682 src->origin()); |
2697 dstGLRect.setRelativeTo(dstVP, | 2683 dstGLRect.setRelativeTo(dstVP, |
2698 dstRect.fLeft, | 2684 dstRect.fLeft, |
(...skipping 17 matching lines...) Expand all Loading... |
2716 } | 2702 } |
2717 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, | 2703 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, |
2718 srcY0, | 2704 srcY0, |
2719 srcGLRect.fLeft + srcGLRect.fWidth, | 2705 srcGLRect.fLeft + srcGLRect.fWidth, |
2720 srcY1, | 2706 srcY1, |
2721 dstGLRect.fLeft, | 2707 dstGLRect.fLeft, |
2722 dstGLRect.fBottom, | 2708 dstGLRect.fBottom, |
2723 dstGLRect.fLeft + dstGLRect.fWidth, | 2709 dstGLRect.fLeft + dstGLRect.fWidth, |
2724 dstGLRect.fBottom + dstGLRect.fHeight, | 2710 dstGLRect.fBottom + dstGLRect.fHeight, |
2725 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | 2711 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
2726 if (dstFBO) { | 2712 this->unbindSurfaceAsFBOForCopy(dstFBOBinding); |
2727 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER); | 2713 this->unbindSurfaceAsFBOForCopy(srcFBOBinding); |
2728 } | |
2729 if (srcFBO) { | |
2730 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER); | |
2731 } | |
2732 copied = true; | 2714 copied = true; |
2733 } | 2715 } |
2734 } | 2716 } |
2735 return copied; | 2717 return copied; |
2736 } | 2718 } |
2737 | 2719 |
2738 bool GrGLGpu::canCopySurface(const GrSurface* dst, | 2720 bool GrGLGpu::canCopySurface(const GrSurface* dst, |
2739 const GrSurface* src, | 2721 const GrSurface* src, |
2740 const SkIRect& srcRect, | 2722 const SkIRect& srcRect, |
2741 const SkIPoint& dstPoint) { | 2723 const SkIPoint& dstPoint) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2797 this->setVertexArrayID(gpu, 0); | 2779 this->setVertexArrayID(gpu, 0); |
2798 } | 2780 } |
2799 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2781 int attrCount = gpu->glCaps().maxVertexAttributes(); |
2800 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 2782 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
2801 fDefaultVertexArrayAttribState.resize(attrCount); | 2783 fDefaultVertexArrayAttribState.resize(attrCount); |
2802 } | 2784 } |
2803 attribState = &fDefaultVertexArrayAttribState; | 2785 attribState = &fDefaultVertexArrayAttribState; |
2804 } | 2786 } |
2805 return attribState; | 2787 return attribState; |
2806 } | 2788 } |
OLD | NEW |