Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(567)

Side by Side Diff: src/gpu/gl/GrGLGpu.cpp

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

Powered by Google App Engine
This is Rietveld 408576698