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 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
466 | 466 |
467 int maxSize = this->caps()->maxTextureSize(); | 467 int maxSize = this->caps()->maxTextureSize(); |
468 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { | 468 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { |
469 return NULL; | 469 return NULL; |
470 } | 470 } |
471 | 471 |
472 GrGLTexture::IDDesc idDesc; | 472 GrGLTexture::IDDesc idDesc; |
473 GrSurfaceDesc surfDesc; | 473 GrSurfaceDesc surfDesc; |
474 | 474 |
475 idDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle); | 475 idDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle); |
476 | 476 |
477 switch (ownership) { | 477 switch (ownership) { |
478 case kAdopt_GrWrapOwnership: | 478 case kAdopt_GrWrapOwnership: |
479 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; | 479 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; |
480 break; | 480 break; |
481 case kBorrow_GrWrapOwnership: | 481 case kBorrow_GrWrapOwnership: |
482 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; | 482 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; |
483 break; | 483 break; |
484 } | 484 } |
485 | 485 |
486 // next line relies on GrBackendTextureDesc's flags matching GrTexture's | 486 // next line relies on GrBackendTextureDesc's flags matching GrTexture's |
487 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; | 487 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; |
488 surfDesc.fWidth = desc.fWidth; | 488 surfDesc.fWidth = desc.fWidth; |
489 surfDesc.fHeight = desc.fHeight; | 489 surfDesc.fHeight = desc.fHeight; |
490 surfDesc.fConfig = desc.fConfig; | 490 surfDesc.fConfig = desc.fConfig; |
491 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() ); | 491 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() ); |
492 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g); | 492 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g); |
493 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly | 493 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly |
494 // assuming the old behaviour, which is that backend textures are always | 494 // assuming the old behaviour, which is that backend textures are always |
(...skipping 29 matching lines...) Expand all Loading... | |
524 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); | 524 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); |
525 idDesc.fMSColorRenderbufferID = 0; | 525 idDesc.fMSColorRenderbufferID = 0; |
526 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; | 526 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; |
527 switch (ownership) { | 527 switch (ownership) { |
528 case kAdopt_GrWrapOwnership: | 528 case kAdopt_GrWrapOwnership: |
529 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; | 529 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; |
530 break; | 530 break; |
531 case kBorrow_GrWrapOwnership: | 531 case kBorrow_GrWrapOwnership: |
532 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; | 532 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; |
533 break; | 533 break; |
534 } | 534 } |
535 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; | 535 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; |
536 | 536 |
537 GrSurfaceDesc desc; | 537 GrSurfaceDesc desc; |
538 desc.fConfig = wrapDesc.fConfig; | 538 desc.fConfig = wrapDesc.fConfig; |
539 desc.fFlags = kCheckAllocation_GrSurfaceFlag; | 539 desc.fFlags = kCheckAllocation_GrSurfaceFlag; |
540 desc.fWidth = wrapDesc.fWidth; | 540 desc.fWidth = wrapDesc.fWidth; |
541 desc.fHeight = wrapDesc.fHeight; | 541 desc.fHeight = wrapDesc.fHeight; |
542 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); | 542 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); |
543 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); | 543 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); |
544 | 544 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
624 | 624 |
625 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, | 625 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, |
626 const GrGLInterface* interface) { | 626 const GrGLInterface* interface) { |
627 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { | 627 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { |
628 return GR_GL_GET_ERROR(interface); | 628 return GR_GL_GET_ERROR(interface); |
629 } else { | 629 } else { |
630 return CHECK_ALLOC_ERROR(interface); | 630 return CHECK_ALLOC_ERROR(interface); |
631 } | 631 } |
632 } | 632 } |
633 | 633 |
634 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | 634 static bool can_use_tex_storage(const GrGLCaps& caps, const GrGLStandard& standa rd, |
635 bool isNewTexture, | 635 const GrSurfaceDesc& desc) { |
636 int left, int top, int width, int height, | 636 bool useTexStorage = caps.texStorageSupport(); |
637 GrPixelConfig dataConfig, | 637 if (useTexStorage && kGL_GrGLStandard == standard) { |
638 const void* data, | |
639 size_t rowBytes) { | |
640 SkASSERT(data || isNewTexture); | |
641 | |
642 // If we're uploading compressed data then we should be using uploadCompress edTexData | |
643 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | |
644 | |
645 size_t bpp = GrBytesPerPixel(dataConfig); | |
646 if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top, | |
647 &width, &height, &data, &rowBytes)) { | |
648 return false; | |
649 } | |
650 size_t trimRowBytes = width * bpp; | |
651 | |
652 // in case we need a temporary, trimmed copy of the src pixels | |
653 SkAutoSMalloc<128 * 128> tempStorage; | |
654 | |
655 // We currently lazily create MIPMAPs when the we see a draw with | |
656 // GrTextureParams::kMipMap_FilterMode. Using texture storage requires that the | |
657 // MIP levels are all created when the texture is created. So for now we don 't use | |
658 // texture storage. | |
659 bool useTexStorage = false && | |
660 isNewTexture && | |
661 this->glCaps().texStorageSupport(); | |
662 | |
663 if (useTexStorage && kGL_GrGLStandard == this->glStandard()) { | |
664 // 565 is not a sized internal format on desktop GL. So on desktop with | 638 // 565 is not a sized internal format on desktop GL. So on desktop with |
665 // 565 we always use an unsized internal format to let the system pick | 639 // 565 we always use an unsized internal format to let the system pick |
666 // the best sized format to convert the 565 data to. Since TexStorage | 640 // the best sized format to convert the 565 data to. Since TexStorage |
667 // only allows sized internal formats we will instead use TexImage2D. | 641 // only allows sized internal formats we will instead use TexImage2D. |
668 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; | 642 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; |
669 } | 643 } |
670 | 644 |
671 GrGLenum internalFormat = 0x0; // suppress warning | 645 return useTexStorage; |
672 GrGLenum externalFormat = 0x0; // suppress warning | 646 } |
673 GrGLenum externalType = 0x0; // suppress warning | 647 |
674 | 648 static bool can_use_sized_format(bool useTexStorage, const GrGLCaps& caps, |
649 const GrGLStandard& standard, const GrGLVersion & version, | |
650 GrPixelConfig dataConfig) { | |
675 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized | 651 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized |
676 // format for glTexImage, unlike ES3 and desktop. | 652 // format for glTexImage, unlike ES3 and desktop. |
677 bool useSizedFormat = useTexStorage; | 653 bool useSizedFormat = useTexStorage; |
678 if (kGL_GrGLStandard == this->glStandard() || | 654 if (kGL_GrGLStandard == standard || |
679 (this->glVersion() >= GR_GL_VER(3, 0) && | 655 (version >= GR_GL_VER(3, 0) && |
680 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled | 656 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled |
681 (kBGRA_8888_GrPixelConfig != dataConfig || !this->glCaps().bgraIsIntern alFormat()))) { | 657 (kBGRA_8888_GrPixelConfig != dataConfig || !caps.bgraIsInternalFormat() ))) { |
682 useSizedFormat = true; | 658 useSizedFormat = true; |
683 } | 659 } |
684 | 660 |
685 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, | 661 return useSizedFormat; |
686 &externalFormat, &externalType)) { | 662 } |
687 return false; | 663 |
688 } | 664 static void prepare_image_for_writing_to_texture(const GrSurfaceDesc& desc, cons t GrGLCaps& caps, |
665 bool swFlipY, bool glFlipY, int width, int height, | |
666 int bpp, size_t rowBytes, const void*& data, | |
667 SkAutoSMalloc<128 * 128>& tempS torage, | |
668 const GrGLInterface* interface, | |
669 bool& restoreGLRowLength) { | |
670 if (NULL == interface) { | |
671 return; | |
672 } | |
673 | |
674 size_t trimRowBytes = width * bpp; | |
689 | 675 |
690 /* | 676 /* |
691 * check whether to allocate a temporary buffer for flipping y or | 677 * check whether to allocate a temporary buffer for flipping y or |
692 * because our srcData has extra bytes past each row. If so, we need | 678 * because our srcData has extra bytes past each row. If so, we need |
693 * to trim those off here, since GL ES may not let us specify | 679 * to trim those off here, since GL ES may not let us specify |
694 * GL_UNPACK_ROW_LENGTH. | 680 * GL_UNPACK_ROW_LENGTH. |
695 */ | 681 */ |
696 bool restoreGLRowLength = false; | 682 restoreGLRowLength = false; |
683 | |
684 if (caps.unpackRowLengthSupport() && !swFlipY) { | |
685 // can't use this for flipping, only non-neg values allowed. :( | |
686 if (rowBytes != trimRowBytes) { | |
687 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); | |
688 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength )); | |
689 restoreGLRowLength = true; | |
690 } | |
691 } else { | |
692 if (trimRowBytes != rowBytes || swFlipY) { | |
693 // copy data into our new storage, skipping the trailing bytes | |
694 size_t trimSize = height * trimRowBytes; | |
695 const char* src = (const char*)data; | |
696 if (swFlipY) { | |
697 src += (height - 1) * rowBytes; | |
698 } | |
699 char* dst = (char*)tempStorage.reset(trimSize); | |
700 for (int y = 0; y < height; y++) { | |
701 memcpy(dst, src, trimRowBytes); | |
702 if (swFlipY) { | |
703 src -= rowBytes; | |
704 } else { | |
705 src += rowBytes; | |
706 } | |
707 dst += trimRowBytes; | |
708 } | |
709 // now point data to our copied version | |
710 data = tempStorage.get(); | |
711 } | |
712 } | |
713 if (glFlipY) { | |
714 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); | |
715 } | |
716 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, | |
717 static_cast<GrGLint>(GrUnpackAlignment(des c.fConfig)))); | |
718 } | |
719 | |
720 static void allocate_and_populate_uncompressed_texture(const GrGLInterface* inte rface, | |
721 bool useTexStorage, | |
722 GrGLenum internalFormat, | |
723 GrGLenum externalFormat, | |
724 GrGLenum externalType, | |
725 const GrSurfaceDesc& desc , | |
726 SkTArray<const void*>& da ta, | |
727 bool& succeeded) { | |
728 CLEAR_ERROR_BEFORE_ALLOC(interface); | |
729 if (useTexStorage) { | |
730 // We never resize or change formats of textures. | |
731 GL_ALLOC_CALL(interface, | |
732 TexStorage2D(GR_GL_TEXTURE_2D, | |
733 data.count(), | |
734 internalFormat, | |
735 desc.fWidth, desc.fHeight)); | |
736 } else { | |
737 int width = desc.fWidth; | |
738 int height = desc.fHeight; | |
739 for (int currentMipLevel = 0; currentMipLevel < data.count(); currentMip Level++) { | |
740 GL_ALLOC_CALL(interface, | |
741 TexImage2D(GR_GL_TEXTURE_2D, | |
742 currentMipLevel, | |
743 internalFormat, | |
744 width, height, | |
745 0, // border | |
746 externalFormat, externalType, | |
747 data[currentMipLevel])); | |
748 width /= 2; | |
749 height /= 2; | |
750 } | |
751 } | |
752 | |
753 GrGLenum error = check_alloc_error(desc, interface); | |
754 if (error != GR_GL_NO_ERROR) { | |
755 succeeded = false; | |
756 } else { | |
757 int width = desc.fWidth; | |
758 int height = desc.fHeight; | |
759 for (int currentMipLevel = data.count(); currentMipLevel != 0; currentMi pLevel--) { | |
760 auto currentMipData = data[currentMipLevel]; | |
761 GR_GL_CALL(interface, | |
762 TexSubImage2D(GR_GL_TEXTURE_2D, | |
763 currentMipLevel, | |
764 0, // left | |
765 0, // top | |
766 width, height, | |
767 externalFormat, externalType, | |
768 currentMipData)); | |
769 width /= 2; | |
770 height /= 2; | |
771 } | |
772 } | |
773 } | |
774 | |
775 static bool allocate_and_populate_compressed_texture(const GrGLInterface* interf ace, | |
776 bool useTexStorage, GrGLenu m internalFormat, | |
777 const GrSurfaceDesc& desc, | |
778 SkTArray<const void*>& data , | |
779 size_t dataSize) { | |
780 CLEAR_ERROR_BEFORE_ALLOC(interface); | |
781 if (useTexStorage) { | |
782 // We never resize or change formats of textures. | |
783 GL_ALLOC_CALL(interface, | |
784 TexStorage2D(GR_GL_TEXTURE_2D, | |
785 data.count(), | |
786 internalFormat, | |
787 desc.fWidth, desc.fHeight)); | |
788 } else { | |
789 int width = desc.fWidth; | |
790 int height = desc.fHeight; | |
791 for (int currentMipLevel = 0; currentMipLevel < data.count(); currentMip Level++) { | |
792 GL_ALLOC_CALL(interface, | |
793 CompressedTexImage2D(GR_GL_TEXTURE_2D, | |
794 data.count(), | |
795 internalFormat, | |
796 width, height, | |
797 0, // border | |
798 SkToInt(dataSize), | |
cblume
2015/07/23 18:18:59
I think this may be a bug. Each mip level probably
cblume
2015/08/14 21:56:55
Done.
| |
799 data[currentMipLevel])); | |
800 width /= 2; | |
801 height /= 2; | |
802 } | |
803 } | |
804 | |
805 GrGLenum error = check_alloc_error(desc, interface); | |
806 if (error != GR_GL_NO_ERROR) { | |
807 return false; | |
808 } | |
809 return true; | |
810 } | |
811 | |
812 static void restore_gl_state(bool restoreGLRowLength, const GrGLInterface* inter face, | |
813 const GrGLCaps& caps, bool glFlipY) { | |
814 if (restoreGLRowLength) { | |
815 SkASSERT(caps.unpackRowLengthSupport()); | |
816 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | |
817 } | |
818 if (glFlipY) { | |
819 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | |
820 } | |
821 } | |
822 | |
823 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | |
824 bool isNewTexture, | |
825 int left, int top, int width, int height, | |
826 GrPixelConfig dataConfig, | |
827 const void* data, | |
828 size_t rowBytes) { | |
829 SkASSERT(data || isNewTexture); | |
830 | |
831 // If we're uploading compressed data then we should be using uploadCompress edTexData | |
832 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | |
833 | |
834 size_t bpp = GrBytesPerPixel(dataConfig); | |
835 if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top, | |
836 &width, &height, &data, &rowBytes)) { | |
837 return false; | |
838 } | |
839 | |
840 bool useTexStorage = can_use_tex_storage(this->glCaps(), this->glStandard(), | |
841 desc); | |
842 bool useSizedFormat = can_use_sized_format(useTexStorage, this->glCaps(), th is->glStandard(), | |
843 this->glVersion(), dataConfig); | |
844 | |
845 GrGLenum internalFormat = 0x0; // suppress warning | |
846 GrGLenum externalFormat = 0x0; // suppress warning | |
847 GrGLenum externalType = 0x0; // suppress warning | |
848 | |
849 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, | |
850 &externalFormat, &externalType)) { | |
851 return false; | |
852 } | |
853 | |
697 bool swFlipY = false; | 854 bool swFlipY = false; |
698 bool glFlipY = false; | 855 bool glFlipY = false; |
856 | |
857 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | |
858 if (glCaps().unpackFlipYSupport()) { | |
859 glFlipY = true; | |
860 } else { | |
861 swFlipY = true; | |
862 } | |
863 } | |
864 | |
865 bool restoreGLRowLength = false; | |
866 | |
867 // in case we need a temporary, trimmed copy of the src pixels | |
868 SkAutoSMalloc<128 * 128> tempStorage; | |
699 if (data) { | 869 if (data) { |
700 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 870 prepare_image_for_writing_to_texture(desc, this->glCaps(), swFlipY, glFl ipY, width, height, |
701 if (this->glCaps().unpackFlipYSupport()) { | 871 bpp, rowBytes, data, tempStorage, t his->glInterface(), |
702 glFlipY = true; | 872 restoreGLRowLength); |
703 } else { | |
704 swFlipY = true; | |
705 } | |
706 } | |
707 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { | |
708 // can't use this for flipping, only non-neg values allowed. :( | |
709 if (rowBytes != trimRowBytes) { | |
710 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); | |
711 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); | |
712 restoreGLRowLength = true; | |
713 } | |
714 } else { | |
715 if (trimRowBytes != rowBytes || swFlipY) { | |
716 // copy data into our new storage, skipping the trailing bytes | |
717 size_t trimSize = height * trimRowBytes; | |
718 const char* src = (const char*)data; | |
719 if (swFlipY) { | |
720 src += (height - 1) * rowBytes; | |
721 } | |
722 char* dst = (char*)tempStorage.reset(trimSize); | |
723 for (int y = 0; y < height; y++) { | |
724 memcpy(dst, src, trimRowBytes); | |
725 if (swFlipY) { | |
726 src -= rowBytes; | |
727 } else { | |
728 src += rowBytes; | |
729 } | |
730 dst += trimRowBytes; | |
731 } | |
732 // now point data to our copied version | |
733 data = tempStorage.get(); | |
734 } | |
735 } | |
736 if (glFlipY) { | |
737 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); | |
738 } | |
739 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, | |
740 static_cast<GrGLint>(GrUnpackAlignment(dataConfig)))); | |
741 } | 873 } |
742 bool succeeded = true; | 874 bool succeeded = true; |
743 if (isNewTexture && | 875 if (isNewTexture && |
744 0 == left && 0 == top && | 876 0 == left && 0 == top && |
745 desc.fWidth == width && desc.fHeight == height) { | 877 desc.fWidth == width && desc.fHeight == height) { |
746 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 878 const int mipLevelCount = 1; |
747 if (useTexStorage) { | 879 SkTArray<const void*> mipLevels(mipLevelCount); |
748 // We never resize or change formats of textures. | 880 mipLevels[0] = data; |
749 GL_ALLOC_CALL(this->glInterface(), | 881 allocate_and_populate_uncompressed_texture(this->glInterface(), useTexSt orage, |
750 TexStorage2D(GR_GL_TEXTURE_2D, | 882 internalFormat, externalForma t, externalType, |
751 1, // levels | 883 desc, mipLevels, succeeded); |
752 internalFormat, | |
753 desc.fWidth, desc.fHeight)); | |
754 } else { | |
755 GL_ALLOC_CALL(this->glInterface(), | |
756 TexImage2D(GR_GL_TEXTURE_2D, | |
757 0, // level | |
758 internalFormat, | |
759 desc.fWidth, desc.fHeight, | |
760 0, // border | |
761 externalFormat, externalType, | |
762 data)); | |
763 } | |
764 GrGLenum error = check_alloc_error(desc, this->glInterface()); | |
765 if (error != GR_GL_NO_ERROR) { | |
766 succeeded = false; | |
767 } else { | |
768 // if we have data and we used TexStorage to create the texture, we | |
769 // now upload with TexSubImage. | |
770 if (data && useTexStorage) { | |
771 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, | |
772 0, // level | |
773 left, top, | |
774 width, height, | |
775 externalFormat, externalType, | |
776 data)); | |
777 } | |
778 } | |
779 } else { | 884 } else { |
780 if (swFlipY || glFlipY) { | 885 if (swFlipY || glFlipY) { |
781 top = desc.fHeight - (top + height); | 886 top = desc.fHeight - (top + height); |
782 } | 887 } |
783 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, | 888 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, |
784 0, // level | 889 0, // level |
785 left, top, | 890 left, top, |
786 width, height, | 891 width, height, |
787 externalFormat, externalType, data)); | 892 externalFormat, externalType, data)); |
788 } | 893 } |
789 | 894 |
790 if (restoreGLRowLength) { | 895 restore_gl_state(restoreGLRowLength, this->glInterface(), this->glCaps(), gl FlipY); |
791 SkASSERT(this->glCaps().unpackRowLengthSupport()); | 896 |
792 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | |
793 } | |
794 if (glFlipY) { | |
795 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | |
796 } | |
797 return succeeded; | 897 return succeeded; |
798 } | 898 } |
799 | 899 |
800 // TODO: This function is using a lot of wonky semantics like, if width == -1 | 900 // TODO: This function is using a lot of wonky semantics like, if width == -1 |
801 // then set width = desc.fWdith ... blah. A better way to do it might be to | 901 // then set width = desc.fWdith ... blah. A better way to do it might be to |
802 // create a CompressedTexData struct that takes a desc/ptr and figures out | 902 // create a CompressedTexData struct that takes a desc/ptr and figures out |
803 // the proper upload semantics. Then users can construct this function how they | 903 // the proper upload semantics. Then users can construct this function how they |
804 // see fit if they want to go against the "standard" way to do it. | 904 // see fit if they want to go against the "standard" way to do it. |
805 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, | 905 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, |
806 const void* data, | 906 const void* data, |
(...skipping 15 matching lines...) Expand all Loading... | |
822 | 922 |
823 if (-1 == height) { | 923 if (-1 == height) { |
824 height = desc.fHeight; | 924 height = desc.fHeight; |
825 } | 925 } |
826 #ifdef SK_DEBUG | 926 #ifdef SK_DEBUG |
827 else { | 927 else { |
828 SkASSERT(height <= desc.fHeight); | 928 SkASSERT(height <= desc.fHeight); |
829 } | 929 } |
830 #endif | 930 #endif |
831 | 931 |
932 bool useTexStorage = can_use_tex_storage(this->glCaps(), this->glStandard(), | |
933 desc); | |
934 | |
832 // Make sure that the width and height that we pass to OpenGL | 935 // Make sure that the width and height that we pass to OpenGL |
833 // is a multiple of the block size. | 936 // is a multiple of the block size. |
834 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height); | 937 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height); |
835 | 938 |
836 // We only need the internal format for compressed 2D textures. | 939 // We only need the internal format for compressed 2D textures. |
837 GrGLenum internalFormat = 0; | 940 GrGLenum internalFormat = 0; |
838 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NUL L)) { | 941 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NUL L)) { |
839 return false; | 942 return false; |
840 } | 943 } |
841 | 944 |
842 if (isNewTexture) { | 945 if (isNewTexture) { |
843 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 946 const int mipLevelCount = 1; |
844 GL_ALLOC_CALL(this->glInterface(), | 947 SkTArray<const void*> mipLevels(mipLevelCount); |
845 CompressedTexImage2D(GR_GL_TEXTURE_2D, | 948 mipLevels[0] = data; |
846 0, // level | 949 return allocate_and_populate_compressed_texture(this->glInterface(), use TexStorage, |
847 internalFormat, | 950 internalFormat, desc, mi pLevels, dataSize); |
848 width, height, | |
849 0, // border | |
850 SkToInt(dataSize), | |
851 data)); | |
852 GrGLenum error = check_alloc_error(desc, this->glInterface()); | |
853 if (error != GR_GL_NO_ERROR) { | |
854 return false; | |
855 } | |
856 } else { | 951 } else { |
857 // Paletted textures can't be updated. | 952 // Paletted textures can't be updated. |
858 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { | 953 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { |
859 return false; | 954 return false; |
860 } | 955 } |
861 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D, | 956 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D, |
862 0, // level | 957 0, // level |
863 left, top, | 958 left, top, |
864 width, height, | 959 width, height, |
865 internalFormat, | 960 internalFormat, |
866 SkToInt(dataSize), | 961 SkToInt(dataSize), |
867 data)); | 962 data)); |
868 } | 963 } |
869 | 964 |
870 return true; | 965 return true; |
871 } | 966 } |
872 | 967 |
968 bool GrGLGpu::uploadMipmappedTexData(const GrSurfaceDesc& desc, | |
969 const SkMipMap& data) { | |
970 // If we're uploading compressed data then we should be using uploadCompress edMipmappedTexData | |
971 SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig)); | |
972 | |
973 size_t bpp = GrBytesPerPixel(desc.fConfig); | |
974 | |
975 bool useTexStorage = can_use_tex_storage(this->glCaps(), this->glStandard(), | |
976 desc); | |
977 bool useSizedFormat = can_use_sized_format(useTexStorage, this->glCaps(), th is->glStandard(), | |
978 this->glVersion(), desc.fConfig); | |
979 | |
980 GrGLenum internalFormat = 0x0; // suppress warning | |
981 GrGLenum externalFormat = 0x0; // suppress warning | |
982 GrGLenum externalType = 0x0; // suppress warning | |
983 | |
984 if (!this->configToGLFormats(desc.fConfig, useSizedFormat, &internalFormat, | |
985 &externalFormat, &externalType)) { | |
986 return false; | |
987 } | |
988 | |
989 bool swFlipY = false; | |
990 bool glFlipY = false; | |
991 | |
992 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | |
993 if (glCaps().unpackFlipYSupport()) { | |
994 glFlipY = true; | |
995 } else { | |
996 swFlipY = true; | |
997 } | |
998 } | |
999 | |
1000 bool restoreGLRowLength = false; | |
1001 | |
1002 // in case we need a temporary, trimmed copy of the src pixels | |
1003 SkAutoSMalloc<128 * 128> tempStorage; | |
1004 | |
1005 bool succeeded = true; | |
1006 auto mipLevelCount = data.getLevelsCount(); | |
1007 SkTArray<const void*> mipLevels(mipLevelCount); | |
1008 for (int currentMipLevel = mipLevelCount; currentMipLevel != 0; currentMipLe vel--) { | |
1009 SkMipMap::Level currentMipData; | |
1010 if (data.getLevel(currentMipLevel, ¤tMipData)) { | |
1011 mipLevels[currentMipLevel] = currentMipData.fPixels; | |
1012 | |
1013 prepare_image_for_writing_to_texture(desc, this->glCaps(), swFlipY, glFlipY, | |
1014 currentMipData.fWidth, currentM ipData.fHeight, | |
1015 bpp, currentMipData.fRowBytes, | |
1016 mipLevels[currentMipLevel], tem pStorage, | |
1017 this->glInterface(), restoreGLR owLength); | |
1018 } | |
1019 } | |
1020 allocate_and_populate_uncompressed_texture(this->glInterface(), useTexStorag e, internalFormat, | |
1021 externalFormat, externalType, des c, mipLevels, | |
1022 succeeded); | |
1023 | |
1024 restore_gl_state(restoreGLRowLength, this->glInterface(), this->glCaps(), gl FlipY); | |
1025 | |
1026 return succeeded; | |
1027 } | |
1028 | |
1029 bool GrGLGpu::uploadCompressedMipmappedTexData(const GrSurfaceDesc& desc, | |
1030 const SkMipMap& data) { | |
1031 // No support for software flip y, yet... | |
1032 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); | |
1033 | |
1034 // Make sure that the width and height that we pass to OpenGL | |
1035 // is a multiple of the block size. | |
1036 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, desc.fWidth, desc .fHeight); | |
1037 | |
1038 bool useTexStorage = can_use_tex_storage(this->glCaps(), this->glStandard(), | |
1039 desc); | |
1040 bool useSizedFormat = can_use_sized_format(useTexStorage, this->glCaps(), th is->glStandard(), | |
1041 this->glVersion(), desc.fConfig); | |
1042 | |
1043 // We only need the internal format for compressed 2D textures. | |
1044 GrGLenum internalFormat = 0; | |
1045 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NUL L)) { | |
1046 return false; | |
1047 } | |
1048 | |
1049 auto mipLevelCount = data.getLevelsCount(); | |
1050 SkTArray<const void*> mipLevels(mipLevelCount); | |
1051 for (int currentLevelIndex = mipLevelCount; currentLevelIndex != 0; currentL evelIndex--) { | |
1052 SkMipMap::Level currentLevel; | |
1053 if (data.getLevel(currentLevelIndex, ¤tLevel)) { | |
1054 mipLevels[currentLevelIndex] = currentLevel.fPixels; | |
1055 } | |
1056 } | |
1057 return allocate_and_populate_compressed_texture(this->glInterface(), useTexS torage, | |
1058 internalFormat, desc, mipLev els, dataSize); | |
1059 } | |
1060 | |
873 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, | 1061 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, |
874 int sampleCount, | 1062 int sampleCount, |
875 GrGLenum format, | 1063 GrGLenum format, |
876 int width, int height) { | 1064 int width, int height) { |
877 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); | 1065 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); |
878 SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType()); | 1066 SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType()); |
879 switch (ctx.caps()->msFBOType()) { | 1067 switch (ctx.caps()->msFBOType()) { |
880 case GrGLCaps::kDesktop_ARB_MSFBOType: | 1068 case GrGLCaps::kDesktop_ARB_MSFBOType: |
881 case GrGLCaps::kDesktop_EXT_MSFBOType: | 1069 case GrGLCaps::kDesktop_EXT_MSFBOType: |
882 case GrGLCaps::kMixedSamples_MSFBOType: | 1070 case GrGLCaps::kMixedSamples_MSFBOType: |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1025 // SkDEBUGFAIL("null texture"); | 1213 // SkDEBUGFAIL("null texture"); |
1026 return NULL; | 1214 return NULL; |
1027 } | 1215 } |
1028 | 1216 |
1029 #if 0 && defined(SK_DEBUG) | 1217 #if 0 && defined(SK_DEBUG) |
1030 static size_t as_size_t(int x) { | 1218 static size_t as_size_t(int x) { |
1031 return x; | 1219 return x; |
1032 } | 1220 } |
1033 #endif | 1221 #endif |
1034 | 1222 |
1223 static GrGLTexture::IDDesc generate_and_bind_gl_texture(const GrGLInterface* int erface, | |
1224 GrGpuResource::LifeCycle lifeCycle) { | |
1225 GrGLTexture::IDDesc idDesc; | |
1226 GR_GL_CALL(interface, GenTextures(1, &idDesc.fTextureID)); | |
1227 idDesc.fLifeCycle = lifeCycle; | |
1228 return idDesc; | |
1229 } | |
1230 | |
1231 static GrGLTexture::TexParams set_initial_texture_params(const GrGLInterface* in terface) { | |
1232 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | |
1233 // drivers have a bug where an FBO won't be complete if it includes a | |
1234 // texture that is not mipmap complete (considering the filter in use). | |
1235 GrGLTexture::TexParams initialTexParams; | |
1236 // we only set a subset here so invalidate first | |
1237 initialTexParams.invalidate(); | |
1238 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
1239 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
1240 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
1241 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
1242 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
1243 GR_GL_TEXTURE_MAG_FILTER, | |
1244 initialTexParams.fMagFilter)); | |
1245 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
1246 GR_GL_TEXTURE_MIN_FILTER, | |
1247 initialTexParams.fMinFilter)); | |
1248 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
1249 GR_GL_TEXTURE_WRAP_S, | |
1250 initialTexParams.fWrapS)); | |
1251 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
1252 GR_GL_TEXTURE_WRAP_T, | |
1253 initialTexParams.fWrapT)); | |
1254 return initialTexParams; | |
1255 } | |
1256 | |
1035 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, | 1257 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, |
1036 GrGpuResource::LifeCycle lifeCycle, | 1258 GrGpuResource::LifeCycle lifeCycle, |
1037 const void* srcData, size_t rowBytes) { | 1259 const void* srcData, size_t rowBytes) { |
1038 // We fail if the MSAA was requested and is not available. | 1260 // We fail if the MSAA was requested and is not available. |
1039 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { | 1261 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { |
1040 //SkDebugf("MSAA RT requested but not supported on this platform."); | 1262 //SkDebugf("MSAA RT requested but not supported on this platform."); |
1041 return return_null_texture(); | 1263 return return_null_texture(); |
1042 } | 1264 } |
1043 | 1265 |
1044 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); | 1266 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); |
1045 | 1267 |
1046 GrGLTexture::IDDesc idDesc; | 1268 auto idDesc = generate_and_bind_gl_texture(this->glInterface(), lifeCycle); |
1047 GL_CALL(GenTextures(1, &idDesc.fTextureID)); | |
1048 idDesc.fLifeCycle = lifeCycle; | |
1049 | |
1050 if (!idDesc.fTextureID) { | 1269 if (!idDesc.fTextureID) { |
1051 return return_null_texture(); | 1270 return return_null_texture(); |
1052 } | 1271 } |
1053 | 1272 |
1054 this->setScratchTextureUnit(); | 1273 this->setScratchTextureUnit(); |
1055 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | 1274 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); |
1056 | 1275 |
1057 if (renderTarget && this->glCaps().textureUsageSupport()) { | 1276 if (renderTarget && this->glCaps().textureUsageSupport()) { |
1058 // provides a hint about how this texture will be used | 1277 // provides a hint about how this texture will be used |
1059 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 1278 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, |
1060 GR_GL_TEXTURE_USAGE, | 1279 GR_GL_TEXTURE_USAGE, |
1061 GR_GL_FRAMEBUFFER_ATTACHMENT)); | 1280 GR_GL_FRAMEBUFFER_ATTACHMENT)); |
1062 } | 1281 } |
1063 | 1282 |
1064 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1283 auto initialTexParams = set_initial_texture_params(this->glInterface()); |
1065 // drivers have a bug where an FBO won't be complete if it includes a | 1284 |
1066 // texture that is not mipmap complete (considering the filter in use). | |
1067 GrGLTexture::TexParams initialTexParams; | |
1068 // we only set a subset here so invalidate first | |
1069 initialTexParams.invalidate(); | |
1070 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
1071 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
1072 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
1073 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
1074 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1075 GR_GL_TEXTURE_MAG_FILTER, | |
1076 initialTexParams.fMagFilter)); | |
1077 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1078 GR_GL_TEXTURE_MIN_FILTER, | |
1079 initialTexParams.fMinFilter)); | |
1080 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1081 GR_GL_TEXTURE_WRAP_S, | |
1082 initialTexParams.fWrapS)); | |
1083 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1084 GR_GL_TEXTURE_WRAP_T, | |
1085 initialTexParams.fWrapT)); | |
1086 if (!this->uploadTexData(desc, true, 0, 0, | 1285 if (!this->uploadTexData(desc, true, 0, 0, |
1087 desc.fWidth, desc.fHeight, | 1286 desc.fWidth, desc.fHeight, |
1088 desc.fConfig, srcData, rowBytes)) { | 1287 desc.fConfig, srcData, rowBytes)) { |
1089 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1288 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
1090 return return_null_texture(); | 1289 return return_null_texture(); |
1091 } | 1290 } |
1092 | 1291 |
1093 GrGLTexture* tex; | 1292 GrGLTexture* tex; |
1094 if (renderTarget) { | 1293 if (renderTarget) { |
1095 // unbind the texture from the texture unit before binding it to the fra me buffer | 1294 // unbind the texture from the texture unit before binding it to the fra me buffer |
(...skipping 17 matching lines...) Expand all Loading... | |
1113 } | 1312 } |
1114 | 1313 |
1115 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, | 1314 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, |
1116 GrGpuResource::LifeCycle lifeCycle , | 1315 GrGpuResource::LifeCycle lifeCycle , |
1117 const void* srcData) { | 1316 const void* srcData) { |
1118 // Make sure that we're not flipping Y. | 1317 // Make sure that we're not flipping Y. |
1119 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 1318 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
1120 return return_null_texture(); | 1319 return return_null_texture(); |
1121 } | 1320 } |
1122 | 1321 |
1123 GrGLTexture::IDDesc idDesc; | 1322 auto idDesc = generate_and_bind_gl_texture(this->glInterface(), lifeCycle); |
1124 GL_CALL(GenTextures(1, &idDesc.fTextureID)); | |
1125 idDesc.fLifeCycle = lifeCycle; | |
1126 | |
1127 if (!idDesc.fTextureID) { | 1323 if (!idDesc.fTextureID) { |
1128 return return_null_texture(); | 1324 return return_null_texture(); |
1129 } | 1325 } |
1130 | 1326 |
1131 this->setScratchTextureUnit(); | 1327 this->setScratchTextureUnit(); |
1132 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | 1328 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); |
1133 | 1329 |
1134 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1330 auto initialTexParams = set_initial_texture_params(this->glInterface()); |
1135 // drivers have a bug where an FBO won't be complete if it includes a | |
1136 // texture that is not mipmap complete (considering the filter in use). | |
1137 GrGLTexture::TexParams initialTexParams; | |
1138 // we only set a subset here so invalidate first | |
1139 initialTexParams.invalidate(); | |
1140 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
1141 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
1142 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
1143 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
1144 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1145 GR_GL_TEXTURE_MAG_FILTER, | |
1146 initialTexParams.fMagFilter)); | |
1147 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1148 GR_GL_TEXTURE_MIN_FILTER, | |
1149 initialTexParams.fMinFilter)); | |
1150 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1151 GR_GL_TEXTURE_WRAP_S, | |
1152 initialTexParams.fWrapS)); | |
1153 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1154 GR_GL_TEXTURE_WRAP_T, | |
1155 initialTexParams.fWrapT)); | |
1156 | 1331 |
1157 if (!this->uploadCompressedTexData(desc, srcData)) { | 1332 if (!this->uploadCompressedTexData(desc, srcData)) { |
1158 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1333 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
1159 return return_null_texture(); | 1334 return return_null_texture(); |
1160 } | 1335 } |
1161 | 1336 |
1162 GrGLTexture* tex; | 1337 GrGLTexture* tex; |
1163 tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); | 1338 tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); |
1164 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1339 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
1165 #ifdef TRACE_TEXTURE_CREATION | 1340 #ifdef TRACE_TEXTURE_CREATION |
1166 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", | 1341 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", |
1167 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1342 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
1168 #endif | 1343 #endif |
1169 return tex; | 1344 return tex; |
1170 } | 1345 } |
1171 | 1346 |
1347 GrTexture* GrGLGpu::onCreateMipmappedTexture(const GrSurfaceDesc& desc, | |
1348 GrGpuResource::LifeCycle lifeCycle, | |
1349 const SkMipMap& srcData) | |
1350 { | |
1351 // We fail if the MSAA was requested and is not available. | |
1352 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { | |
1353 //SkDebugf("MSAA RT requested but not supported on this platform."); | |
1354 return return_null_texture(); | |
1355 } | |
1356 | |
1357 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); | |
1358 | |
1359 auto idDesc = generate_and_bind_gl_texture(this->glInterface(), lifeCycle); | |
1360 if (!idDesc.fTextureID) { | |
1361 return return_null_texture(); | |
1362 } | |
1363 | |
1364 if (renderTarget && this->glCaps().textureUsageSupport()) { | |
1365 // provides a hint about how this texture will be used | |
1366 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
1367 GR_GL_TEXTURE_USAGE, | |
1368 GR_GL_FRAMEBUFFER_ATTACHMENT)); | |
1369 } | |
1370 | |
1371 auto initialTexParams = set_initial_texture_params(this->glInterface()); | |
1372 | |
1373 if (!this->uploadMipmappedTexData(desc, srcData)) { | |
1374 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | |
1375 return return_null_texture(); | |
1376 } | |
1377 | |
1378 GrGLTexture* tex; | |
1379 if (renderTarget) { | |
1380 // unbind the texture from the texture unit before binding it to the fra me buffer | |
1381 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); | |
1382 GrGLRenderTarget::IDDesc rtIDDesc; | |
1383 | |
1384 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, &rtIDDesc)) { | |
1385 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | |
1386 return return_null_texture(); | |
1387 } | |
1388 tex = SkNEW_ARGS(GrGLTextureRenderTarget, (this, desc, idDesc, rtIDDesc) ); | |
1389 } else { | |
1390 tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); | |
1391 } | |
1392 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | |
1393 #ifdef TRACE_TEXTURE_CREATION | |
1394 SkDebugf("--- new mipmapped texture [%d] size=(%d %d) config=%d\n", | |
1395 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | |
1396 #endif | |
1397 return tex; | |
1398 } | |
1399 | |
1400 GrTexture* GrGLGpu::onCreateCompressedMipmappedTexture(const GrSurfaceDesc& desc , | |
1401 GrGpuResource::LifeCycle lifeCycle, | |
1402 const SkMipMap& srcData) | |
1403 { | |
1404 // Make sure that we're not flipping Y. | |
1405 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | |
1406 return return_null_texture(); | |
1407 } | |
1408 | |
1409 auto idDesc = generate_and_bind_gl_texture(this->glInterface(), lifeCycle); | |
1410 if (!idDesc.fTextureID) { | |
1411 return return_null_texture(); | |
1412 } | |
1413 | |
1414 this->setScratchTextureUnit(); | |
1415 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | |
1416 | |
1417 auto initialTexParams = set_initial_texture_params(this->glInterface()); | |
1418 | |
1419 if (!this->uploadCompressedMipmappedTexData(desc, srcData)) { | |
1420 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | |
1421 return return_null_texture(); | |
1422 } | |
1423 | |
1424 GrGLTexture* tex; | |
1425 tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); | |
1426 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | |
1427 #ifdef TRACE_TEXTURE_CREATION | |
1428 SkDebugf("--- new compressed mipmapped texture [%d] size=(%d %d) config=%d\n ", | |
1429 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | |
1430 #endif | |
1431 return tex; | |
1432 } | |
1433 | |
1172 namespace { | 1434 namespace { |
1173 | 1435 |
1174 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; | 1436 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; |
1175 | 1437 |
1176 void inline get_stencil_rb_sizes(const GrGLInterface* gl, | 1438 void inline get_stencil_rb_sizes(const GrGLInterface* gl, |
1177 GrGLStencilAttachment::Format* format) { | 1439 GrGLStencilAttachment::Format* format) { |
1178 | 1440 |
1179 // we shouldn't ever know one size and not the other | 1441 // we shouldn't ever know one size and not the other |
1180 SkASSERT((kUnknownBitCount == format->fStencilBits) == | 1442 SkASSERT((kUnknownBitCount == format->fStencilBits) == |
1181 (kUnknownBitCount == format->fTotalBits)); | 1443 (kUnknownBitCount == format->fTotalBits)); |
(...skipping 1974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3156 this->setVertexArrayID(gpu, 0); | 3418 this->setVertexArrayID(gpu, 0); |
3157 } | 3419 } |
3158 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3420 int attrCount = gpu->glCaps().maxVertexAttributes(); |
3159 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 3421 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
3160 fDefaultVertexArrayAttribState.resize(attrCount); | 3422 fDefaultVertexArrayAttribState.resize(attrCount); |
3161 } | 3423 } |
3162 attribState = &fDefaultVertexArrayAttribState; | 3424 attribState = &fDefaultVertexArrayAttribState; |
3163 } | 3425 } |
3164 return attribState; | 3426 return attribState; |
3165 } | 3427 } |
OLD | NEW |