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 "GrGLGLSL.h" | 10 #include "GrGLGLSL.h" |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 this->setScratchTextureUnit(); | 642 this->setScratchTextureUnit(); |
643 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); | 643 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); |
644 | 644 |
645 bool success = false; | 645 bool success = false; |
646 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { | 646 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { |
647 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel
s() | 647 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel
s() |
648 SkASSERT(config == glTex->desc().fConfig); | 648 SkASSERT(config == glTex->desc().fConfig); |
649 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(),
buffer, | 649 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(),
buffer, |
650 kWrite_UploadType, left, top, wi
dth, height); | 650 kWrite_UploadType, left, top, wi
dth, height); |
651 } else { | 651 } else { |
652 success = this->uploadTexData( | 652 success = this->uploadTexData(glTex->desc(), glTex->target(), kWrite_Upl
oadType, |
653 glTex->desc(), | 653 left, top, width, height, config, buffer,
rowBytes); |
654 reinterpret_cast<GrGLTextureInfo*>(glTex->getTextureHandle()), | |
655 kWrite_UploadType, left, top, width, height, config, buffer, | |
656 rowBytes); | |
657 } | 654 } |
658 | 655 |
659 if (success) { | 656 if (success) { |
660 glTex->texturePriv().dirtyMipMaps(true); | 657 glTex->texturePriv().dirtyMipMaps(true); |
661 return true; | 658 return true; |
662 } | 659 } |
663 | 660 |
664 return false; | 661 return false; |
665 } | 662 } |
666 | 663 |
(...skipping 16 matching lines...) Expand all Loading... |
683 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); | 680 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); |
684 | 681 |
685 SkASSERT(!buffer->isMapped()); | 682 SkASSERT(!buffer->isMapped()); |
686 GrGLTransferBuffer* glBuffer = reinterpret_cast<GrGLTransferBuffer*>(buffer)
; | 683 GrGLTransferBuffer* glBuffer = reinterpret_cast<GrGLTransferBuffer*>(buffer)
; |
687 // bind the transfer buffer | 684 // bind the transfer buffer |
688 SkASSERT(GR_GL_PIXEL_UNPACK_BUFFER == glBuffer->bufferType() || | 685 SkASSERT(GR_GL_PIXEL_UNPACK_BUFFER == glBuffer->bufferType() || |
689 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == glBuffer->bufferType
()); | 686 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == glBuffer->bufferType
()); |
690 GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID())); | 687 GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID())); |
691 | 688 |
692 bool success = false; | 689 bool success = false; |
693 success = this->uploadTexData( | 690 success = this->uploadTexData(glTex->desc(), glTex->target(), kTransfer_Uplo
adType, |
694 glTex->desc(), | 691 left, top, width, height, config, buffer, rowB
ytes); |
695 reinterpret_cast<GrGLTextureInfo*>(glTex->getTextureHandle()), | |
696 kTransfer_UploadType, left, top, width, height, config, buffer, | |
697 rowBytes); | |
698 | 692 |
699 if (success) { | 693 if (success) { |
700 glTex->texturePriv().dirtyMipMaps(true); | 694 glTex->texturePriv().dirtyMipMaps(true); |
701 return true; | 695 return true; |
702 } | 696 } |
703 | 697 |
704 return false; | 698 return false; |
705 } | 699 } |
706 | 700 |
707 // For GL_[UN]PACK_ALIGNMENT. | 701 // For GL_[UN]PACK_ALIGNMENT. |
(...skipping 20 matching lines...) Expand all Loading... |
728 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, | 722 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, |
729 const GrGLInterface* interface) { | 723 const GrGLInterface* interface) { |
730 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { | 724 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { |
731 return GR_GL_GET_ERROR(interface); | 725 return GR_GL_GET_ERROR(interface); |
732 } else { | 726 } else { |
733 return CHECK_ALLOC_ERROR(interface); | 727 return CHECK_ALLOC_ERROR(interface); |
734 } | 728 } |
735 } | 729 } |
736 | 730 |
737 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | 731 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, |
738 GrGLTextureInfo* info, | 732 GrGLenum target, |
739 UploadType uploadType, | 733 UploadType uploadType, |
740 int left, int top, int width, int height, | 734 int left, int top, int width, int height, |
741 GrPixelConfig dataConfig, | 735 GrPixelConfig dataConfig, |
742 const void* dataOrOffset, | 736 const void* dataOrOffset, |
743 size_t rowBytes) { | 737 size_t rowBytes) { |
744 SkASSERT(dataOrOffset || kNewTexture_UploadType == uploadType || | 738 SkASSERT(dataOrOffset || kNewTexture_UploadType == uploadType || |
745 kTransfer_UploadType == uploadType); | 739 kTransfer_UploadType == uploadType); |
746 | 740 |
747 // If we're uploading compressed data then we should be using uploadCompress
edTexData | 741 // If we're uploading compressed data then we should be using uploadCompress
edTexData |
748 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | 742 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); | 819 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); |
826 } | 820 } |
827 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(dataConfig)
)); | 821 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(dataConfig)
)); |
828 } | 822 } |
829 bool succeeded = true; | 823 bool succeeded = true; |
830 if (kNewTexture_UploadType == uploadType) { | 824 if (kNewTexture_UploadType == uploadType) { |
831 if (dataOrOffset && | 825 if (dataOrOffset && |
832 !(0 == left && 0 == top && desc.fWidth == width && desc.fHeight == h
eight)) { | 826 !(0 == left && 0 == top && desc.fWidth == width && desc.fHeight == h
eight)) { |
833 succeeded = false; | 827 succeeded = false; |
834 } else { | 828 } else { |
835 if (desc.fTextureStorageAllocator.fAllocateTextureStorage) { | 829 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); |
836 if (dataOrOffset) { | 830 GL_ALLOC_CALL(this->glInterface(), TexImage2D(target, 0, internalFor
mat, desc.fWidth, |
837 GL_CALL(TexSubImage2D(info->fTarget, | 831 desc.fHeight, 0, exter
nalFormat, |
838 0, // level | 832 externalType, dataOrOf
fset)); |
839 left, top, | 833 GrGLenum error = check_alloc_error(desc, this->glInterface()); |
840 width, height, | 834 if (error != GR_GL_NO_ERROR) { |
841 externalFormat, externalType, dataOrOf
fset)); | 835 succeeded = false; |
842 } | 836 } |
843 } else {
| |
844 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
| |
845 GL_ALLOC_CALL(this->glInterface(), TexImage2D(
| |
846 info->fTarget, 0, internalFormat, desc.fWidth, desc.fHeight,
0, externalFormat, | |
847 externalType, dataOrOffset));
| |
848 GrGLenum error = check_alloc_error(desc, this->glInterface()); | |
849 if (error != GR_GL_NO_ERROR) {
| |
850 succeeded = false;
| |
851 } | |
852 } | |
853 } | 837 } |
854 } else { | 838 } else { |
855 if (swFlipY || glFlipY) { | 839 if (swFlipY || glFlipY) { |
856 top = desc.fHeight - (top + height); | 840 top = desc.fHeight - (top + height); |
857 } | 841 } |
858 GL_CALL(TexSubImage2D(info->fTarget, | 842 GL_CALL(TexSubImage2D(target, |
859 0, // level | 843 0, // level |
860 left, top, | 844 left, top, |
861 width, height, | 845 width, height, |
862 externalFormat, externalType, dataOrOffset)); | 846 externalFormat, externalType, dataOrOffset)); |
863 } | 847 } |
864 | 848 |
865 if (restoreGLRowLength) { | 849 if (restoreGLRowLength) { |
866 SkASSERT(this->glCaps().unpackRowLengthSupport()); | 850 SkASSERT(this->glCaps().unpackRowLengthSupport()); |
867 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | 851 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); |
868 } | 852 } |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 const void* srcData, size_t rowBytes) { | 1095 const void* srcData, size_t rowBytes) { |
1112 // We fail if the MSAA was requested and is not available. | 1096 // We fail if the MSAA was requested and is not available. |
1113 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC
nt) { | 1097 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC
nt) { |
1114 //SkDebugf("MSAA RT requested but not supported on this platform."); | 1098 //SkDebugf("MSAA RT requested but not supported on this platform."); |
1115 return return_null_texture(); | 1099 return return_null_texture(); |
1116 } | 1100 } |
1117 | 1101 |
1118 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); | 1102 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); |
1119 | 1103 |
1120 GrGLTexture::IDDesc idDesc; | 1104 GrGLTexture::IDDesc idDesc; |
| 1105 idDesc.fInfo.fID = 0; |
| 1106 GL_CALL(GenTextures(1, &idDesc.fInfo.fID)); |
1121 idDesc.fLifeCycle = lifeCycle; | 1107 idDesc.fLifeCycle = lifeCycle; |
1122 GrGLTexture::TexParams initialTexParams; | 1108 // We only support GL_TEXTURE_2D at the moment. |
1123 if (!this->createTextureImpl(desc, &idDesc.fInfo, renderTarget, srcData, | 1109 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D; |
1124 &initialTexParams, rowBytes)) { | 1110 |
| 1111 if (!idDesc.fInfo.fID) { |
1125 return return_null_texture(); | 1112 return return_null_texture(); |
1126 } | 1113 } |
1127 | 1114 |
| 1115 this->setScratchTextureUnit(); |
| 1116 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); |
| 1117 |
| 1118 if (renderTarget && this->glCaps().textureUsageSupport()) { |
| 1119 // provides a hint about how this texture will be used |
| 1120 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| 1121 GR_GL_TEXTURE_USAGE, |
| 1122 GR_GL_FRAMEBUFFER_ATTACHMENT)); |
| 1123 } |
| 1124 |
| 1125 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some |
| 1126 // drivers have a bug where an FBO won't be complete if it includes a |
| 1127 // texture that is not mipmap complete (considering the filter in use). |
| 1128 GrGLTexture::TexParams initialTexParams; |
| 1129 // we only set a subset here so invalidate first |
| 1130 initialTexParams.invalidate(); |
| 1131 initialTexParams.fMinFilter = GR_GL_NEAREST; |
| 1132 initialTexParams.fMagFilter = GR_GL_NEAREST; |
| 1133 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; |
| 1134 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; |
| 1135 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| 1136 GR_GL_TEXTURE_MAG_FILTER, |
| 1137 initialTexParams.fMagFilter)); |
| 1138 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| 1139 GR_GL_TEXTURE_MIN_FILTER, |
| 1140 initialTexParams.fMinFilter)); |
| 1141 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| 1142 GR_GL_TEXTURE_WRAP_S, |
| 1143 initialTexParams.fWrapS)); |
| 1144 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| 1145 GR_GL_TEXTURE_WRAP_T, |
| 1146 initialTexParams.fWrapT)); |
| 1147 if (!this->uploadTexData(desc, idDesc.fInfo.fTarget, kNewTexture_UploadType,
0, 0, |
| 1148 desc.fWidth, desc.fHeight, |
| 1149 desc.fConfig, srcData, rowBytes)) { |
| 1150 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); |
| 1151 return return_null_texture(); |
| 1152 } |
| 1153 |
1128 GrGLTexture* tex; | 1154 GrGLTexture* tex; |
1129 if (renderTarget) { | 1155 if (renderTarget) { |
1130 // unbind the texture from the texture unit before binding it to the fra
me buffer | 1156 // unbind the texture from the texture unit before binding it to the fra
me buffer |
1131 GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0)); | 1157 GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0)); |
1132 GrGLRenderTarget::IDDesc rtIDDesc; | 1158 GrGLRenderTarget::IDDesc rtIDDesc; |
1133 | 1159 |
1134 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fInfo, &rtI
DDesc)) { | 1160 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fInfo, &rtI
DDesc)) { |
1135 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); | 1161 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); |
1136 return return_null_texture(); | 1162 return return_null_texture(); |
1137 } | 1163 } |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 GL_CALL(DeleteRenderbuffers(1, &sbRBID)); | 1363 GL_CALL(DeleteRenderbuffers(1, &sbRBID)); |
1338 } | 1364 } |
1339 GL_CALL(DeleteTextures(1, &colorID)); | 1365 GL_CALL(DeleteTextures(1, &colorID)); |
1340 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); | 1366 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); |
1341 GL_CALL(DeleteFramebuffers(1, &fb)); | 1367 GL_CALL(DeleteFramebuffers(1, &fb)); |
1342 fGLContext->caps()->setStencilFormatIndexForConfig(config, firstWorkingS
tencilFormatIndex); | 1368 fGLContext->caps()->setStencilFormatIndexForConfig(config, firstWorkingS
tencilFormatIndex); |
1343 } | 1369 } |
1344 return this->glCaps().getStencilFormatIndexForConfig(config); | 1370 return this->glCaps().getStencilFormatIndexForConfig(config); |
1345 } | 1371 } |
1346 | 1372 |
1347 bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info
, | |
1348 bool renderTarget, const void* srcData, | |
1349 GrGLTexture::TexParams* initialTexParams, size_t
rowBytes) { | |
1350 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | |
1351 // drivers have a bug where an FBO won't be complete if it includes a | |
1352 // texture that is not mipmap complete (considering the filter in use). | |
1353 | |
1354 // we only set a subset here so invalidate first | |
1355 initialTexParams->invalidate(); | |
1356 initialTexParams->fMinFilter = GR_GL_NEAREST; | |
1357 initialTexParams->fMagFilter = GR_GL_NEAREST; | |
1358 initialTexParams->fWrapS = GR_GL_CLAMP_TO_EDGE; | |
1359 initialTexParams->fWrapT = GR_GL_CLAMP_TO_EDGE; | |
1360 | |
1361 if (desc.fTextureStorageAllocator.fAllocateTextureStorage) { | |
1362 return this->createTextureExternalAllocatorImpl(desc, info, srcData, row
Bytes); | |
1363 } | |
1364 | |
1365 info->fID = 0; | |
1366 info->fTarget = GR_GL_TEXTURE_2D; | |
1367 GL_CALL(GenTextures(1, &(info->fID))); | |
1368 | |
1369 if (!info->fID) { | |
1370 return false; | |
1371 } | |
1372 | |
1373 this->setScratchTextureUnit(); | |
1374 GL_CALL(BindTexture(info->fTarget, info->fID)); | |
1375 | |
1376 if (renderTarget && this->glCaps().textureUsageSupport()) { | |
1377 // provides a hint about how this texture will be used | |
1378 GL_CALL(TexParameteri(info->fTarget, | |
1379 GR_GL_TEXTURE_USAGE, | |
1380 GR_GL_FRAMEBUFFER_ATTACHMENT)); | |
1381 } | |
1382 | |
1383 GL_CALL(TexParameteri(info->fTarget, | |
1384 GR_GL_TEXTURE_MAG_FILTER, | |
1385 initialTexParams->fMagFilter)); | |
1386 GL_CALL(TexParameteri(info->fTarget, | |
1387 GR_GL_TEXTURE_MIN_FILTER, | |
1388 initialTexParams->fMinFilter)); | |
1389 GL_CALL(TexParameteri(info->fTarget, | |
1390 GR_GL_TEXTURE_WRAP_S, | |
1391 initialTexParams->fWrapS)); | |
1392 GL_CALL(TexParameteri(info->fTarget, | |
1393 GR_GL_TEXTURE_WRAP_T, | |
1394 initialTexParams->fWrapT)); | |
1395 if (!this->uploadTexData(desc, info, kNewTexture_UploadType, 0, 0, | |
1396 desc.fWidth, desc.fHeight, | |
1397 desc.fConfig, srcData, rowBytes)) { | |
1398 GL_CALL(DeleteTextures(1, &(info->fID))); | |
1399 return false; | |
1400 } | |
1401 return true; | |
1402 } | |
1403 | |
1404 bool GrGLGpu::createTextureExternalAllocatorImpl( | |
1405 const GrSurfaceDesc& desc, GrGLTextureInfo* info, const void* srcData, s
ize_t rowBytes) { | |
1406 switch (desc.fTextureStorageAllocator.fAllocateTextureStorage( | |
1407 desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBacke
ndObject>(info), | |
1408 desc.fWidth, desc.fHeight, desc.fConfig, srcData, desc.fOrig
in)) { | |
1409 case GrTextureStorageAllocator::Result::kSucceededAndUploaded: | |
1410 return true; | |
1411 case GrTextureStorageAllocator::Result::kFailed: | |
1412 return false; | |
1413 case GrTextureStorageAllocator::Result::kSucceededWithoutUpload: | |
1414 break; | |
1415 } | |
1416 | |
1417 if (!this->uploadTexData(desc, info, kNewTexture_UploadType, 0, 0, | |
1418 desc.fWidth, desc.fHeight, | |
1419 desc.fConfig, srcData, rowBytes)) { | |
1420 desc.fTextureStorageAllocator.fDeallocateTextureStorage( | |
1421 desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBackendOb
ject>(info)); | |
1422 return false; | |
1423 } | |
1424 return true; | |
1425 } | |
1426 | |
1427 GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRen
derTarget* rt, | 1373 GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRen
derTarget* rt, |
1428 int width, | 1374 int width, |
1429 int height)
{ | 1375 int height)
{ |
1430 // All internally created RTs are also textures. We don't create | 1376 // All internally created RTs are also textures. We don't create |
1431 // SBs for a client's standalone RT (that is a RT that isn't also a texture)
. | 1377 // SBs for a client's standalone RT (that is a RT that isn't also a texture)
. |
1432 SkASSERT(rt->asTexture()); | 1378 SkASSERT(rt->asTexture()); |
1433 SkASSERT(width >= rt->width()); | 1379 SkASSERT(width >= rt->width()); |
1434 SkASSERT(height >= rt->height()); | 1380 SkASSERT(height >= rt->height()); |
1435 | 1381 |
1436 int samples = rt->numStencilSamples(); | 1382 int samples = rt->numStencilSamples(); |
(...skipping 2173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3610 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || | 3556 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
3611 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 3557 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
3612 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 3558 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
3613 copyParams->fWidth = texture->width(); | 3559 copyParams->fWidth = texture->width(); |
3614 copyParams->fHeight = texture->height(); | 3560 copyParams->fHeight = texture->height(); |
3615 return true; | 3561 return true; |
3616 } | 3562 } |
3617 } | 3563 } |
3618 return false; | 3564 return false; |
3619 } | 3565 } |
OLD | NEW |