| 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 "GrGLStencilAttachment.h" |
| 11 #include "GrGLTextureRenderTarget.h" | 11 #include "GrGLTextureRenderTarget.h" |
| 12 #include "GrGpuResourcePriv.h" | 12 #include "GrGpuResourcePriv.h" |
| 13 #include "GrPipeline.h" | 13 #include "GrPipeline.h" |
| 14 #include "GrRenderTargetPriv.h" | 14 #include "GrRenderTargetPriv.h" |
| 15 #include "GrSurfacePriv.h" | 15 #include "GrSurfacePriv.h" |
| 16 #include "GrTemplates.h" | 16 #include "GrTemplates.h" |
| 17 #include "GrTexturePriv.h" | 17 #include "GrTexturePriv.h" |
| 18 #include "GrTypes.h" | 18 #include "GrTypes.h" |
| 19 #include "SkStrokeRec.h" | 19 #include "SkStrokeRec.h" |
| 20 #include "SkTemplates.h" | 20 #include "SkTemplates.h" |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 GrSurfaceDesc desc; | 440 GrSurfaceDesc desc; |
| 441 desc.fConfig = wrapDesc.fConfig; | 441 desc.fConfig = wrapDesc.fConfig; |
| 442 desc.fFlags = kCheckAllocation_GrSurfaceFlag; | 442 desc.fFlags = kCheckAllocation_GrSurfaceFlag; |
| 443 desc.fWidth = wrapDesc.fWidth; | 443 desc.fWidth = wrapDesc.fWidth; |
| 444 desc.fHeight = wrapDesc.fHeight; | 444 desc.fHeight = wrapDesc.fHeight; |
| 445 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()
); | 445 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()
); |
| 446 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); | 446 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); |
| 447 | 447 |
| 448 GrRenderTarget* tgt = SkNEW_ARGS(GrGLRenderTarget, (this, desc, idDesc)); | 448 GrRenderTarget* tgt = SkNEW_ARGS(GrGLRenderTarget, (this, desc, idDesc)); |
| 449 if (wrapDesc.fStencilBits) { | 449 if (wrapDesc.fStencilBits) { |
| 450 GrGLStencilBuffer::IDDesc sbDesc; | 450 GrGLStencilAttachment::IDDesc sbDesc; |
| 451 GrGLStencilBuffer::Format format; | 451 GrGLStencilAttachment::Format format; |
| 452 format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat; | 452 format.fInternalFormat = GrGLStencilAttachment::kUnknownInternalFormat; |
| 453 format.fPacked = false; | 453 format.fPacked = false; |
| 454 format.fStencilBits = wrapDesc.fStencilBits; | 454 format.fStencilBits = wrapDesc.fStencilBits; |
| 455 format.fTotalBits = wrapDesc.fStencilBits; | 455 format.fTotalBits = wrapDesc.fStencilBits; |
| 456 GrGLStencilBuffer* sb = SkNEW_ARGS(GrGLStencilBuffer, | 456 GrGLStencilAttachment* sb = SkNEW_ARGS(GrGLStencilAttachment, |
| 457 (this, | 457 (this, |
| 458 sbDesc, | 458 sbDesc, |
| 459 desc.fWidth, | 459 desc.fWidth, |
| 460 desc.fHeight, | 460 desc.fHeight, |
| 461 desc.fSampleCnt, | 461 desc.fSampleCnt, |
| 462 format)); | 462 format)); |
| 463 tgt->renderTargetPriv().didAttachStencilBuffer(sb); | 463 tgt->renderTargetPriv().didAttachStencilAttachment(sb); |
| 464 sb->unref(); | 464 sb->unref(); |
| 465 } | 465 } |
| 466 return tgt; | 466 return tgt; |
| 467 } | 467 } |
| 468 | 468 |
| 469 //////////////////////////////////////////////////////////////////////////////// | 469 //////////////////////////////////////////////////////////////////////////////// |
| 470 | 470 |
| 471 bool GrGLGpu::onWriteTexturePixels(GrTexture* texture, | 471 bool GrGLGpu::onWriteTexturePixels(GrTexture* texture, |
| 472 int left, int top, int width, int height, | 472 int left, int top, int width, int height, |
| 473 GrPixelConfig config, const void* buffer, | 473 GrPixelConfig config, const void* buffer, |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1101 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
| 1102 #ifdef TRACE_TEXTURE_CREATION | 1102 #ifdef TRACE_TEXTURE_CREATION |
| 1103 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", | 1103 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", |
| 1104 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1104 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
| 1105 #endif | 1105 #endif |
| 1106 return tex; | 1106 return tex; |
| 1107 } | 1107 } |
| 1108 | 1108 |
| 1109 namespace { | 1109 namespace { |
| 1110 | 1110 |
| 1111 const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount; | 1111 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; |
| 1112 | 1112 |
| 1113 void inline get_stencil_rb_sizes(const GrGLInterface* gl, | 1113 void inline get_stencil_rb_sizes(const GrGLInterface* gl, |
| 1114 GrGLStencilBuffer::Format* format) { | 1114 GrGLStencilAttachment::Format* format) { |
| 1115 | 1115 |
| 1116 // we shouldn't ever know one size and not the other | 1116 // we shouldn't ever know one size and not the other |
| 1117 SkASSERT((kUnknownBitCount == format->fStencilBits) == | 1117 SkASSERT((kUnknownBitCount == format->fStencilBits) == |
| 1118 (kUnknownBitCount == format->fTotalBits)); | 1118 (kUnknownBitCount == format->fTotalBits)); |
| 1119 if (kUnknownBitCount == format->fStencilBits) { | 1119 if (kUnknownBitCount == format->fStencilBits) { |
| 1120 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, | 1120 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, |
| 1121 GR_GL_RENDERBUFFER_STENCIL_SIZE, | 1121 GR_GL_RENDERBUFFER_STENCIL_SIZE, |
| 1122 (GrGLint*)&format->fStencilBits); | 1122 (GrGLint*)&format->fStencilBits); |
| 1123 if (format->fPacked) { | 1123 if (format->fPacked) { |
| 1124 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, | 1124 GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER, |
| 1125 GR_GL_RENDERBUFFER_DEPTH_SIZE, | 1125 GR_GL_RENDERBUFFER_DEPTH_SIZE, |
| 1126 (GrGLint*)&format->fTotalBits); | 1126 (GrGLint*)&format->fTotalBits); |
| 1127 format->fTotalBits += format->fStencilBits; | 1127 format->fTotalBits += format->fStencilBits; |
| 1128 } else { | 1128 } else { |
| 1129 format->fTotalBits = format->fStencilBits; | 1129 format->fTotalBits = format->fStencilBits; |
| 1130 } | 1130 } |
| 1131 } | 1131 } |
| 1132 } | 1132 } |
| 1133 } | 1133 } |
| 1134 | 1134 |
| 1135 bool GrGLGpu::createStencilBufferForRenderTarget(GrRenderTarget* rt, int width,
int height) { | 1135 bool GrGLGpu::createStencilAttachmentForRenderTarget(GrRenderTarget* rt, int wid
th, int height) { |
| 1136 // All internally created RTs are also textures. We don't create | 1136 // All internally created RTs are also textures. We don't create |
| 1137 // SBs for a client's standalone RT (that is a RT that isn't also a texture)
. | 1137 // SBs for a client's standalone RT (that is a RT that isn't also a texture)
. |
| 1138 SkASSERT(rt->asTexture()); | 1138 SkASSERT(rt->asTexture()); |
| 1139 SkASSERT(width >= rt->width()); | 1139 SkASSERT(width >= rt->width()); |
| 1140 SkASSERT(height >= rt->height()); | 1140 SkASSERT(height >= rt->height()); |
| 1141 | 1141 |
| 1142 int samples = rt->numSamples(); | 1142 int samples = rt->numSamples(); |
| 1143 GrGLStencilBuffer::IDDesc sbDesc; | 1143 GrGLStencilAttachment::IDDesc sbDesc; |
| 1144 | 1144 |
| 1145 int stencilFmtCnt = this->glCaps().stencilFormats().count(); | 1145 int stencilFmtCnt = this->glCaps().stencilFormats().count(); |
| 1146 for (int i = 0; i < stencilFmtCnt; ++i) { | 1146 for (int i = 0; i < stencilFmtCnt; ++i) { |
| 1147 if (!sbDesc.fRenderbufferID) { | 1147 if (!sbDesc.fRenderbufferID) { |
| 1148 GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID)); | 1148 GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID)); |
| 1149 } | 1149 } |
| 1150 if (!sbDesc.fRenderbufferID) { | 1150 if (!sbDesc.fRenderbufferID) { |
| 1151 return false; | 1151 return false; |
| 1152 } | 1152 } |
| 1153 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); | 1153 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1165 samples, | 1165 samples, |
| 1166 sFmt.fInternalFormat, | 1166 sFmt.fInternalFormat, |
| 1167 width, height); | 1167 width, height); |
| 1168 } else { | 1168 } else { |
| 1169 GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERB
UFFER, | 1169 GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERB
UFFER, |
| 1170 sFmt.fInterna
lFormat, | 1170 sFmt.fInterna
lFormat, |
| 1171 width, height
)); | 1171 width, height
)); |
| 1172 created = (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glI
nterface())); | 1172 created = (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glI
nterface())); |
| 1173 } | 1173 } |
| 1174 if (created) { | 1174 if (created) { |
| 1175 fStats.incStencilBufferCreates(); | 1175 fStats.incStencilAttachmentCreates(); |
| 1176 // After sized formats we attempt an unsized format and take | 1176 // After sized formats we attempt an unsized format and take |
| 1177 // whatever sizes GL gives us. In that case we query for the size. | 1177 // whatever sizes GL gives us. In that case we query for the size. |
| 1178 GrGLStencilBuffer::Format format = sFmt; | 1178 GrGLStencilAttachment::Format format = sFmt; |
| 1179 get_stencil_rb_sizes(this->glInterface(), &format); | 1179 get_stencil_rb_sizes(this->glInterface(), &format); |
| 1180 SkAutoTUnref<GrGLStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer, | 1180 SkAutoTUnref<GrGLStencilAttachment> sb(SkNEW_ARGS(GrGLStencilAttachm
ent, |
| 1181 (this, sbDesc, width, height,
samples, format))); | 1181 (this, sbDesc, width, height,
samples, format))); |
| 1182 if (this->attachStencilBufferToRenderTarget(sb, rt)) { | 1182 if (this->attachStencilAttachmentToRenderTarget(sb, rt)) { |
| 1183 fLastSuccessfulStencilFmtIdx = sIdx; | 1183 fLastSuccessfulStencilFmtIdx = sIdx; |
| 1184 rt->renderTargetPriv().didAttachStencilBuffer(sb); | 1184 rt->renderTargetPriv().didAttachStencilAttachment(sb); |
| 1185 // This work around is currently breaking on windows 7 hd2000 bot when we bind a
color buffer | 1185 // This work around is currently breaking on windows 7 hd2000 bot when we bind a
color buffer |
| 1186 #if 0 | 1186 #if 0 |
| 1187 // Clear the stencil buffer. We use a special purpose FBO for th
is so that the | 1187 // Clear the stencil buffer. We use a special purpose FBO for th
is so that the |
| 1188 // entire stencil buffer is cleared, even if it is attached to a
n FBO with a | 1188 // entire stencil buffer is cleared, even if it is attached to a
n FBO with a |
| 1189 // smaller color target. | 1189 // smaller color target. |
| 1190 if (0 == fStencilClearFBOID) { | 1190 if (0 == fStencilClearFBOID) { |
| 1191 GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); | 1191 GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); |
| 1192 } | 1192 } |
| 1193 | 1193 |
| 1194 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBOID)); | 1194 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBOID)); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 // again. | 1241 // again. |
| 1242 sb->resourcePriv().removeScratchKey(); | 1242 sb->resourcePriv().removeScratchKey(); |
| 1243 // Set this to 0 since we handed the valid ID off to the failed sten
cil buffer resource. | 1243 // Set this to 0 since we handed the valid ID off to the failed sten
cil buffer resource. |
| 1244 sbDesc.fRenderbufferID = 0; | 1244 sbDesc.fRenderbufferID = 0; |
| 1245 } | 1245 } |
| 1246 } | 1246 } |
| 1247 GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); | 1247 GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); |
| 1248 return false; | 1248 return false; |
| 1249 } | 1249 } |
| 1250 | 1250 |
| 1251 bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { | 1251 bool GrGLGpu::attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb, GrR
enderTarget* rt) { |
| 1252 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); | 1252 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); |
| 1253 | 1253 |
| 1254 GrGLuint fbo = glrt->renderFBOID(); | 1254 GrGLuint fbo = glrt->renderFBOID(); |
| 1255 | 1255 |
| 1256 if (NULL == sb) { | 1256 if (NULL == sb) { |
| 1257 if (rt->renderTargetPriv().getStencilBuffer()) { | 1257 if (rt->renderTargetPriv().getStencilAttachment()) { |
| 1258 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1258 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1259 GR_GL_STENCIL_ATTACHMENT, | 1259 GR_GL_STENCIL_ATTACHMENT, |
| 1260 GR_GL_RENDERBUFFER, 0)); | 1260 GR_GL_RENDERBUFFER, 0)); |
| 1261 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1261 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1262 GR_GL_DEPTH_ATTACHMENT, | 1262 GR_GL_DEPTH_ATTACHMENT, |
| 1263 GR_GL_RENDERBUFFER, 0)); | 1263 GR_GL_RENDERBUFFER, 0)); |
| 1264 #ifdef SK_DEBUG | 1264 #ifdef SK_DEBUG |
| 1265 GrGLenum status; | 1265 GrGLenum status; |
| 1266 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1266 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 1267 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); | 1267 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); |
| 1268 #endif | 1268 #endif |
| 1269 } | 1269 } |
| 1270 return true; | 1270 return true; |
| 1271 } else { | 1271 } else { |
| 1272 GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); | 1272 GrGLStencilAttachment* glsb = static_cast<GrGLStencilAttachment*>(sb); |
| 1273 GrGLuint rb = glsb->renderbufferID(); | 1273 GrGLuint rb = glsb->renderbufferID(); |
| 1274 | 1274 |
| 1275 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 1275 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 1276 fStats.incRenderTargetBinds(); | 1276 fStats.incRenderTargetBinds(); |
| 1277 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); | 1277 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); |
| 1278 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1278 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 1279 GR_GL_STENCIL_ATTACHMENT, | 1279 GR_GL_STENCIL_ATTACHMENT, |
| 1280 GR_GL_RENDERBUFFER, rb)); | 1280 GR_GL_RENDERBUFFER, rb)); |
| 1281 if (glsb->format().fPacked) { | 1281 if (glsb->format().fPacked) { |
| 1282 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1282 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1622 | 1622 |
| 1623 GL_CALL(StencilMask(0xffffffff)); | 1623 GL_CALL(StencilMask(0xffffffff)); |
| 1624 GL_CALL(ClearStencil(0)); | 1624 GL_CALL(ClearStencil(0)); |
| 1625 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1625 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
| 1626 fHWStencilSettings.invalidate(); | 1626 fHWStencilSettings.invalidate(); |
| 1627 } | 1627 } |
| 1628 | 1628 |
| 1629 void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo
ol insideClip) { | 1629 void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bo
ol insideClip) { |
| 1630 SkASSERT(target); | 1630 SkASSERT(target); |
| 1631 | 1631 |
| 1632 GrStencilBuffer* sb = target->renderTargetPriv().getStencilBuffer(); | 1632 GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment(); |
| 1633 // this should only be called internally when we know we have a | 1633 // this should only be called internally when we know we have a |
| 1634 // stencil buffer. | 1634 // stencil buffer. |
| 1635 SkASSERT(sb); | 1635 SkASSERT(sb); |
| 1636 GrGLint stencilBitCount = sb->bits(); | 1636 GrGLint stencilBitCount = sb->bits(); |
| 1637 #if 0 | 1637 #if 0 |
| 1638 SkASSERT(stencilBitCount > 0); | 1638 SkASSERT(stencilBitCount > 0); |
| 1639 GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); | 1639 GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); |
| 1640 #else | 1640 #else |
| 1641 // we could just clear the clip bit but when we go through | 1641 // we could just clear the clip bit but when we go through |
| 1642 // ANGLE a partial stencil mask will cause clears to be | 1642 // ANGLE a partial stencil mask will cause clears to be |
| (...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2816 this->setVertexArrayID(gpu, 0); | 2816 this->setVertexArrayID(gpu, 0); |
| 2817 } | 2817 } |
| 2818 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2818 int attrCount = gpu->glCaps().maxVertexAttributes(); |
| 2819 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 2819 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
| 2820 fDefaultVertexArrayAttribState.resize(attrCount); | 2820 fDefaultVertexArrayAttribState.resize(attrCount); |
| 2821 } | 2821 } |
| 2822 attribState = &fDefaultVertexArrayAttribState; | 2822 attribState = &fDefaultVertexArrayAttribState; |
| 2823 } | 2823 } |
| 2824 return attribState; | 2824 return attribState; |
| 2825 } | 2825 } |
| OLD | NEW |