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 15 matching lines...) Expand all Loading... | |
560 tgt->renderTargetPriv().didAttachStencilAttachment(sb); | 560 tgt->renderTargetPriv().didAttachStencilAttachment(sb); |
561 sb->unref(); | 561 sb->unref(); |
562 } | 562 } |
563 return tgt; | 563 return tgt; |
564 } | 564 } |
565 | 565 |
566 //////////////////////////////////////////////////////////////////////////////// | 566 //////////////////////////////////////////////////////////////////////////////// |
567 | 567 |
568 bool GrGLGpu::onWriteTexturePixels(GrTexture* texture, | 568 bool GrGLGpu::onWriteTexturePixels(GrTexture* texture, |
569 int left, int top, int width, int height, | 569 int left, int top, int width, int height, |
570 GrPixelConfig config, const void* buffer, | 570 GrPixelConfig config, SkTArray<SkMipMapLevel> & texels) { |
571 size_t rowBytes) { | 571 if (texels.count() == 0) { |
572 if (NULL == buffer) { | |
573 return false; | 572 return false; |
574 } | 573 } |
575 GrGLTexture* glTex = static_cast<GrGLTexture*>(texture); | 574 GrGLTexture* glTex = static_cast<GrGLTexture*>(texture); |
576 | 575 |
577 this->setScratchTextureUnit(); | 576 this->setScratchTextureUnit(); |
578 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); | 577 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); |
579 | 578 |
580 bool success = false; | 579 bool success = false; |
581 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { | 580 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { |
582 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() | 581 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() |
583 SkASSERT(config == glTex->desc().fConfig); | 582 SkASSERT(config == glTex->desc().fConfig); |
584 success = this->uploadCompressedTexData(glTex->desc(), buffer, false, le ft, top, width, | 583 success = this->uploadCompressedTexData(glTex->desc(), texels, false, le ft, top, width, |
585 height); | 584 height); |
586 } else { | 585 } else { |
587 success = this->uploadTexData(glTex->desc(), false, left, top, width, he ight, config, | 586 success = this->uploadTexData(glTex->desc(), false, left, top, width, he ight, config, |
588 buffer, rowBytes); | 587 texels); |
589 } | 588 } |
590 | 589 |
591 if (success) { | 590 if (success) { |
592 texture->texturePriv().dirtyMipMaps(true); | 591 texture->texturePriv().dirtyMipMaps(true); |
593 return true; | 592 return true; |
594 } | 593 } |
595 | 594 |
596 return false; | 595 return false; |
597 } | 596 } |
598 | 597 |
(...skipping 25 matching lines...) Expand all Loading... | |
624 | 623 |
625 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, | 624 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, |
626 const GrGLInterface* interface) { | 625 const GrGLInterface* interface) { |
627 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { | 626 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { |
628 return GR_GL_GET_ERROR(interface); | 627 return GR_GL_GET_ERROR(interface); |
629 } else { | 628 } else { |
630 return CHECK_ALLOC_ERROR(interface); | 629 return CHECK_ALLOC_ERROR(interface); |
631 } | 630 } |
632 } | 631 } |
633 | 632 |
634 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | 633 /** |
635 bool isNewTexture, | 634 * Determines if TexStorage can be used when creating a texture. |
636 int left, int top, int width, int height, | 635 * |
637 GrPixelConfig dataConfig, | 636 * @param caps The capabilities of the GL device. |
638 const void* data, | 637 * @param standard The GL standard in use. |
639 size_t rowBytes) { | 638 * @param desc The surface descriptor for the texture being created. |
640 SkASSERT(data || isNewTexture); | 639 */ |
641 | 640 static bool can_use_tex_storage(const GrGLCaps& caps, const GrGLStandard& standa rd, |
642 // If we're uploading compressed data then we should be using uploadCompress edTexData | 641 const GrSurfaceDesc& desc) { |
643 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | 642 bool useTexStorage = caps.texStorageSupport(); |
644 | 643 if (useTexStorage && kGL_GrGLStandard == standard) { |
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 | 644 // 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 | 645 // 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 | 646 // the best sized format to convert the 565 data to. Since TexStorage |
667 // only allows sized internal formats we will instead use TexImage2D. | 647 // only allows sized internal formats we will instead use TexImage2D. |
668 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; | 648 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; |
669 } | 649 } |
670 | 650 |
671 GrGLenum internalFormat = 0x0; // suppress warning | 651 return useTexStorage; |
672 GrGLenum externalFormat = 0x0; // suppress warning | 652 } |
673 GrGLenum externalType = 0x0; // suppress warning | |
674 | 653 |
654 /** | |
655 * Determines if sized internal formats are available for the texture being crea ted. | |
656 * | |
657 * @param useTexStorage The result of a call to can_use_tex_storage(). | |
658 * @param caps The capabilities of the GL device. | |
659 * @param standard The GL standard in use. | |
660 * @param version The GL version in use. | |
661 * @param dataConfig The pixel configuration for the texture being created. | |
662 */ | |
663 static bool can_use_sized_format(bool useTexStorage, const GrGLCaps& caps, | |
664 const GrGLStandard& standard, const GrGLVersion & version, | |
665 GrPixelConfig dataConfig) { | |
675 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized | 666 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized |
676 // format for glTexImage, unlike ES3 and desktop. | 667 // format for glTexImage, unlike ES3 and desktop. |
677 bool useSizedFormat = useTexStorage; | 668 bool useSizedFormat = useTexStorage; |
678 if (kGL_GrGLStandard == this->glStandard() || | 669 if (kGL_GrGLStandard == standard || |
679 (this->glVersion() >= GR_GL_VER(3, 0) && | 670 (version >= GR_GL_VER(3, 0) && |
680 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled | 671 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled |
681 (kBGRA_8888_GrPixelConfig != dataConfig || !this->glCaps().bgraIsIntern alFormat()))) { | 672 (kBGRA_8888_GrPixelConfig != dataConfig || !caps.bgraIsInternalFormat() ))) { |
682 useSizedFormat = true; | 673 useSizedFormat = true; |
683 } | 674 } |
684 | 675 |
685 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, | 676 return useSizedFormat; |
686 &externalFormat, &externalType)) { | 677 } |
687 return false; | |
688 } | |
689 | 678 |
690 /* | 679 /** |
691 * check whether to allocate a temporary buffer for flipping y or | 680 * Prior to a texture being created, the image may need to be flipped vertically . This function |
692 * because our srcData has extra bytes past each row. If so, we need | 681 * prepares the texels for texture creation. |
693 * to trim those off here, since GL ES may not let us specify | 682 * |
694 * GL_UNPACK_ROW_LENGTH. | 683 * @param desc The surface descriptor for the texture being create d. |
695 */ | 684 * @param caps The capabilities of the GL device. |
696 bool restoreGLRowLength = false; | 685 * @param interface The GL interface in use. |
697 bool swFlipY = false; | 686 * @param swFlipY Should software be used when flipping a texture ver tically? |
698 bool glFlipY = false; | 687 * @param glFlipY Should GL be used when flipping a texture verticall y? |
699 if (data) { | 688 * @param width The width of the texture in texels. |
700 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 689 * @param height The height of the texture in texels. |
701 if (this->glCaps().unpackFlipYSupport()) { | 690 * @param bpp The bits per pixel (or texel, really) of the textur e. |
702 glFlipY = true; | 691 * @param rowBytes The number of bytes between consecutive rows. Zero means rows are |
703 } else { | 692 * tightly packed. |
704 swFlipY = true; | 693 * @param data The texel data of the texture being created. |
705 } | 694 * @param tempStorage In the case where the image needs to be flipped ver tically, it will use |
706 } | 695 * tempStorage as a buffer. |
707 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { | 696 * @param restoreGLRowLength After the texture is created, will the GL row lengt h unpacking need to |
697 * be restored? | |
698 */ | |
699 static void prepare_image_for_writing_to_texture(const GrSurfaceDesc& desc, cons t GrGLCaps& caps, | |
700 const GrGLInterface& interface, bool swFlipY, | |
701 bool glFlipY, int width, int he ight, int bpp, | |
702 SkTArray<SkMipMapLevel>& texels , | |
703 SkAutoSMalloc<128 * 128>& tempS torage, | |
704 bool* restoreGLRowLength) { | |
705 int currentMipLevelWidth = width; | |
706 for(int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLev el++) { | |
707 size_t trimRowBytes = currentMipLevelWidth * bpp; | |
708 | |
709 /* | |
710 * check whether to allocate a temporary buffer for flipping y or | |
711 * because our srcData has extra bytes past each row. If so, we need | |
712 * to trim those off here, since GL ES may not let us specify | |
713 * GL_UNPACK_ROW_LENGTH. | |
714 */ | |
715 *restoreGLRowLength = false; | |
716 | |
717 auto rowBytes = texels[currentMipLevel].fRowBytes; | |
718 if (caps.unpackRowLengthSupport() && !swFlipY) { | |
708 // can't use this for flipping, only non-neg values allowed. :( | 719 // can't use this for flipping, only non-neg values allowed. :( |
709 if (rowBytes != trimRowBytes) { | 720 if (rowBytes != trimRowBytes) { |
710 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); | 721 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); |
711 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); | 722 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowL ength)); |
712 restoreGLRowLength = true; | 723 *restoreGLRowLength = true; |
713 } | 724 } |
714 } else { | 725 } else { |
715 if (trimRowBytes != rowBytes || swFlipY) { | 726 if (trimRowBytes != rowBytes || swFlipY) { |
716 // copy data into our new storage, skipping the trailing bytes | 727 // copy data into our new storage, skipping the trailing bytes |
717 size_t trimSize = height * trimRowBytes; | 728 size_t trimSize = height * trimRowBytes; |
718 const char* src = (const char*)data; | 729 const char* src = (const char*)texels[currentMipLevel].fTexels; |
719 if (swFlipY) { | 730 if (swFlipY) { |
720 src += (height - 1) * rowBytes; | 731 src += (height - 1) * rowBytes; |
721 } | 732 } |
722 char* dst = (char*)tempStorage.reset(trimSize); | 733 char* dst = (char*)tempStorage.reset(trimSize); |
723 for (int y = 0; y < height; y++) { | 734 for (int y = 0; y < height; y++) { |
724 memcpy(dst, src, trimRowBytes); | 735 memcpy(dst, src, trimRowBytes); |
725 if (swFlipY) { | 736 if (swFlipY) { |
726 src -= rowBytes; | 737 src -= rowBytes; |
727 } else { | 738 } else { |
728 src += rowBytes; | 739 src += rowBytes; |
729 } | 740 } |
730 dst += trimRowBytes; | 741 dst += trimRowBytes; |
731 } | 742 } |
732 // now point data to our copied version | 743 // now point data to our copied version |
733 data = tempStorage.get(); | 744 texels[currentMipLevel] = SkMipMapLevel(tempStorage.get(), trimR owBytes); |
734 } | 745 } |
735 } | 746 } |
736 if (glFlipY) { | 747 if (glFlipY) { |
737 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); | 748 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)) ; |
738 } | 749 } |
739 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, | 750 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, |
740 static_cast<GrGLint>(GrUnpackAlignment(dataConfig)))); | 751 static_cast<GrGLint>(GrUnpackAlignmen t(desc.fConfig)))); |
741 } | 752 currentMipLevelWidth /= 2; |
753 } | |
754 } | |
755 | |
756 /** | |
757 * Creates storage space for the texture and fills it with texels. | |
758 * | |
759 * @param desc The surface descriptor for the texture being created. | |
760 * @param interface The GL interface in use. | |
761 * @param useTexStorage The result of a call to can_use_tex_storage(). | |
762 * @param internalFormat The data format used for the internal storage of the te xture. | |
763 * @param externalFormat The data format used for the external storage of the te xture. | |
764 * @param externalType The type of the data used for the external storage of t he texture. | |
765 * @param texels The texel data of the texture being created. | |
766 * @param succeeded Set to true if allocating and populating the texture co mpleted | |
767 * without error. | |
768 */ | |
769 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc , | |
770 const GrGLInterface& inte rface, | |
771 bool useTexStorage, | |
772 GrGLenum internalFormat, | |
773 GrGLenum externalFormat, | |
774 GrGLenum externalType, | |
775 const SkTArray<SkMipMapLe vel>& texels, | |
776 bool* succeeded) { | |
777 CLEAR_ERROR_BEFORE_ALLOC(&interface); | |
778 if (useTexStorage) { | |
779 // We never resize or change formats of textures. | |
780 GL_ALLOC_CALL(&interface, | |
781 TexStorage2D(GR_GL_TEXTURE_2D, | |
782 texels.count(), | |
783 internalFormat, | |
784 desc.fWidth, desc.fHeight)); | |
785 } else { | |
786 int width = desc.fWidth; | |
787 int height = desc.fHeight; | |
788 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) { | |
789 auto currentMipData = texels[currentMipLevel].fTexels; | |
790 GL_ALLOC_CALL(&interface, | |
791 TexImage2D(GR_GL_TEXTURE_2D, | |
792 currentMipLevel, | |
793 internalFormat, | |
794 width, height, | |
795 0, // border | |
796 externalFormat, externalType, | |
797 currentMipData)); | |
798 width /= 2; | |
799 height /= 2; | |
800 } | |
801 } | |
802 | |
803 GrGLenum error = check_alloc_error(desc, &interface); | |
804 if (error != GR_GL_NO_ERROR) { | |
805 *succeeded = false; | |
806 } else { | |
807 int width = desc.fWidth; | |
808 int height = desc.fHeight; | |
809 for (int currentMipLevel = texels.count(); currentMipLevel != 0; current MipLevel--) { | |
810 auto currentMipData = texels[currentMipLevel].fTexels; | |
811 GR_GL_CALL(&interface, | |
812 TexSubImage2D(GR_GL_TEXTURE_2D, | |
813 currentMipLevel, | |
814 0, // left | |
815 0, // top | |
816 width, height, | |
817 externalFormat, externalType, | |
818 currentMipData)); | |
819 width /= 2; | |
820 height /= 2; | |
821 } | |
822 *succeeded = true; | |
823 } | |
824 } | |
825 | |
826 /** | |
827 * Creates storage space for the texture and fills it with texels. | |
828 * | |
829 * @param desc The surface descriptor for the texture being created. | |
830 * @param interface The GL interface in use. | |
831 * @param useTexStorage The result of a call to can_use_tex_storage(). | |
832 * @param internalFormat The data format used for the internal storage of the te xture. | |
833 * @param data The texel data of the texture being created. | |
834 */ | |
835 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc, | |
836 const GrGLInterface& interf ace, | |
837 bool useTexStorage, GrGLenu m internalFormat, | |
838 const SkTArray<SkMipMapLeve l>& texels) { | |
839 CLEAR_ERROR_BEFORE_ALLOC(&interface); | |
840 if (useTexStorage) { | |
841 // We never resize or change formats of textures. | |
842 GL_ALLOC_CALL(&interface, | |
843 TexStorage2D(GR_GL_TEXTURE_2D, | |
844 texels.count(), | |
845 internalFormat, | |
846 desc.fWidth, desc.fHeight)); | |
847 } else { | |
848 int width = desc.fWidth; | |
849 int height = desc.fHeight; | |
850 for (int currentMipLevel = texels.count(); currentMipLevel != 0; current MipLevel--) { | |
851 auto currentMipData = texels[currentMipLevel].fTexels; | |
852 | |
853 // Make sure that the width and height that we pass to OpenGL | |
854 // is a multiple of the block size. | |
855 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, he ight); | |
856 | |
857 GR_GL_CALL(&interface, | |
858 CompressedTexImage2D(GR_GL_TEXTURE_2D, | |
859 texels.count(), | |
860 internalFormat, | |
861 width, height, | |
862 0, // border | |
863 SkToInt(dataSize), | |
864 currentMipData)); | |
865 width /= 2; | |
866 height /= 2; | |
867 } | |
868 } | |
869 | |
870 GrGLenum error = check_alloc_error(desc, &interface); | |
871 if (error != GR_GL_NO_ERROR) { | |
872 return false; | |
873 } | |
874 return true; | |
875 } | |
876 | |
877 /** | |
878 * After a texture is created, any state which was altered during its creation | |
879 * needs to be restored. | |
880 * | |
881 * @param interface The GL interface to use. | |
882 * @param caps The capabilities of the GL device. | |
883 * @param restoreGLRowLength Should the row length unpacking be restored? | |
884 * @param glFlipY Did GL flip the texture vertically? | |
885 */ | |
886 static void restore_gl_state(const GrGLInterface& interface, const GrGLCaps& cap s, | |
887 bool restoreGLRowLength, bool glFlipY) { | |
888 if (restoreGLRowLength) { | |
889 SkASSERT(caps.unpackRowLengthSupport()); | |
890 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | |
891 } | |
892 if (glFlipY) { | |
893 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | |
894 } | |
895 } | |
896 | |
897 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | |
898 bool isNewTexture, | |
899 int left, int top, int width, int height, | |
900 GrPixelConfig dataConfig, | |
901 SkTArray<SkMipMapLevel>& texels) { | |
902 SkASSERT(isNewTexture); | |
903 | |
904 // If we're uploading compressed data then we should be using uploadCompress edTexData | |
905 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | |
906 | |
907 auto interface = this->glInterface(); | |
908 if (interface == nullptr) { | |
909 return false; | |
910 } | |
911 auto& caps = this->glCaps(); | |
912 auto standard = this->glStandard(); | |
913 auto version = this->glVersion(); | |
914 | |
915 size_t bpp = GrBytesPerPixel(dataConfig); | |
916 int mipWidth = desc.fWidth; | |
917 int mipHeight = desc.fHeight; | |
918 for (int currentMipLevel = texels.count(); currentMipLevel != 0; currentMipL evel--) { | |
919 if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top , | |
920 &mipWidth, &mipHeight, &texels[currentMipLe vel].fTexels, | |
921 &texels[currentMipLevel].fRowBytes)) { | |
922 return false; | |
923 } | |
924 } | |
925 | |
926 bool useTexStorage = can_use_tex_storage(caps, standard, desc); | |
927 bool useSizedFormat = can_use_sized_format(useTexStorage, caps, standard, ve rsion, dataConfig); | |
928 | |
929 GrGLenum internalFormat = 0x0; // suppress warning | |
930 GrGLenum externalFormat = 0x0; // suppress warning | |
931 GrGLenum externalType = 0x0; // suppress warning | |
932 | |
933 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, | |
934 &externalFormat, &externalType)) { | |
935 return false; | |
936 } | |
937 | |
938 bool swFlipY = false; | |
939 bool glFlipY = false; | |
940 | |
941 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | |
942 if (caps.unpackFlipYSupport()) { | |
943 glFlipY = true; | |
944 } else { | |
945 swFlipY = true; | |
946 } | |
947 } | |
948 | |
949 bool restoreGLRowLength = false; | |
950 | |
951 // in case we need a temporary, trimmed copy of the src pixels | |
952 SkAutoSMalloc<128 * 128> tempStorage; | |
953 prepare_image_for_writing_to_texture(desc, caps, *interface, swFlipY, glFlip Y, width, | |
954 height, bpp, texels, tempStorage, &rest oreGLRowLength); | |
742 bool succeeded = true; | 955 bool succeeded = true; |
743 if (isNewTexture && | 956 if (isNewTexture && |
744 0 == left && 0 == top && | 957 0 == left && 0 == top && |
745 desc.fWidth == width && desc.fHeight == height) { | 958 desc.fWidth == width && desc.fHeight == height) { |
746 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 959 allocate_and_populate_uncompressed_texture(desc, *interface, useTexStora ge, internalFormat, |
747 if (useTexStorage) { | 960 externalFormat, externalType, texels, |
748 // We never resize or change formats of textures. | 961 &succeeded); |
749 GL_ALLOC_CALL(this->glInterface(), | |
750 TexStorage2D(GR_GL_TEXTURE_2D, | |
751 1, // levels | |
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 { | 962 } else { |
780 if (swFlipY || glFlipY) { | 963 if (swFlipY || glFlipY) { |
781 top = desc.fHeight - (top + height); | 964 top = desc.fHeight - (top + height); |
782 } | 965 } |
783 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, | 966 width = desc.fWidth; |
784 0, // level | 967 height = desc.fHeight; |
785 left, top, | 968 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) { |
786 width, height, | 969 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, |
787 externalFormat, externalType, data)); | 970 0, // level |
788 } | 971 left, top, |
789 | 972 width, height, |
790 if (restoreGLRowLength) { | 973 externalFormat, externalType, texels[currentMi pLevel].fTexels)); |
791 SkASSERT(this->glCaps().unpackRowLengthSupport()); | 974 width /= 2; |
792 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | 975 height /= 2; |
793 } | 976 } |
794 if (glFlipY) { | 977 } |
795 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | 978 |
796 } | 979 restore_gl_state(*interface, caps, restoreGLRowLength, glFlipY); |
980 | |
797 return succeeded; | 981 return succeeded; |
798 } | 982 } |
799 | 983 |
800 // TODO: This function is using a lot of wonky semantics like, if width == -1 | 984 // 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 | 985 // 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 | 986 // 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 | 987 // 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. | 988 // see fit if they want to go against the "standard" way to do it. |
805 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, | 989 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, |
806 const void* data, | 990 const SkTArray<SkMipMapLevel>& texels, |
807 bool isNewTexture, | 991 bool isNewTexture, |
808 int left, int top, int width, int height) { | 992 int left, int top, int width, int height) { |
809 SkASSERT(data || isNewTexture); | 993 SkASSERT(isNewTexture); |
810 | 994 |
811 // No support for software flip y, yet... | 995 // No support for software flip y, yet... |
812 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); | 996 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); |
813 | 997 |
998 auto interface = this->glInterface(); | |
999 if (interface == nullptr) { | |
1000 return false; | |
1001 } | |
1002 auto& caps = this->glCaps(); | |
1003 auto standard = this->glStandard(); | |
1004 | |
814 if (-1 == width) { | 1005 if (-1 == width) { |
815 width = desc.fWidth; | 1006 width = desc.fWidth; |
816 } | 1007 } |
817 #ifdef SK_DEBUG | 1008 #ifdef SK_DEBUG |
818 else { | 1009 else { |
819 SkASSERT(width <= desc.fWidth); | 1010 SkASSERT(width <= desc.fWidth); |
820 } | 1011 } |
821 #endif | 1012 #endif |
822 | 1013 |
823 if (-1 == height) { | 1014 if (-1 == height) { |
824 height = desc.fHeight; | 1015 height = desc.fHeight; |
825 } | 1016 } |
826 #ifdef SK_DEBUG | 1017 #ifdef SK_DEBUG |
827 else { | 1018 else { |
828 SkASSERT(height <= desc.fHeight); | 1019 SkASSERT(height <= desc.fHeight); |
829 } | 1020 } |
830 #endif | 1021 #endif |
831 | 1022 |
832 // Make sure that the width and height that we pass to OpenGL | 1023 bool useTexStorage = can_use_tex_storage(caps, standard, desc); |
833 // is a multiple of the block size. | |
834 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height); | |
835 | 1024 |
836 // We only need the internal format for compressed 2D textures. | 1025 // We only need the internal format for compressed 2D textures. |
837 GrGLenum internalFormat = 0; | 1026 GrGLenum internalFormat = 0; |
838 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NUL L)) { | 1027 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NUL L)) { |
839 return false; | 1028 return false; |
840 } | 1029 } |
841 | 1030 |
842 if (isNewTexture) { | 1031 if (isNewTexture) { |
843 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 1032 return allocate_and_populate_compressed_texture(desc, *interface, useTex Storage, |
844 GL_ALLOC_CALL(this->glInterface(), | 1033 internalFormat, texels); |
845 CompressedTexImage2D(GR_GL_TEXTURE_2D, | |
846 0, // level | |
847 internalFormat, | |
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 { | 1034 } else { |
857 // Paletted textures can't be updated. | 1035 // Paletted textures can't be updated. |
858 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { | 1036 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { |
859 return false; | 1037 return false; |
860 } | 1038 } |
861 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D, | 1039 int currentMipWidth = width; |
862 0, // level | 1040 int currentMipHeight = height; |
863 left, top, | 1041 for(int currentMipLevel = 0; currentMipLevel < texels.count(); currentMi pLevel++) { |
864 width, height, | 1042 // Make sure that the width and height that we pass to OpenGL |
865 internalFormat, | 1043 // is a multiple of the block size. |
866 SkToInt(dataSize), | 1044 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentMi pWidth, currentMipHeight); |
867 data)); | 1045 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D, |
1046 currentMipLevel, | |
1047 left, top, | |
1048 currentMipWidth, currentMipHeight, | |
1049 internalFormat, | |
1050 dataSize, | |
1051 texels[currentMipLevel].fTexels)); | |
1052 currentMipWidth /= 2; | |
1053 currentMipHeight /= 2; | |
1054 } | |
868 } | 1055 } |
869 | 1056 |
870 return true; | 1057 return true; |
871 } | 1058 } |
872 | 1059 |
873 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, | 1060 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, |
874 int sampleCount, | 1061 int sampleCount, |
875 GrGLenum format, | 1062 GrGLenum format, |
876 int width, int height) { | 1063 int width, int height) { |
877 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); | 1064 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
963 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe rID)); | 1150 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe rID)); |
964 if (!renderbuffer_storage_msaa(*fGLContext, | 1151 if (!renderbuffer_storage_msaa(*fGLContext, |
965 desc.fSampleCnt, | 1152 desc.fSampleCnt, |
966 msColorFormat, | 1153 msColorFormat, |
967 desc.fWidth, desc.fHeight)) { | 1154 desc.fWidth, desc.fHeight)) { |
968 goto FAILED; | 1155 goto FAILED; |
969 } | 1156 } |
970 fStats.incRenderTargetBinds(); | 1157 fStats.incRenderTargetBinds(); |
971 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); | 1158 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); |
972 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1159 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
973 GR_GL_COLOR_ATTACHMENT0, | 1160 GR_GL_COLOR_ATTACHMENT0, |
974 GR_GL_RENDERBUFFER, | 1161 GR_GL_RENDERBUFFER, |
975 idDesc->fMSColorRenderbufferID)); | 1162 idDesc->fMSColorRenderbufferID)); |
976 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || | 1163 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || |
977 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { | 1164 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { |
978 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1165 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
979 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 1166 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
980 goto FAILED; | 1167 goto FAILED; |
981 } | 1168 } |
982 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); | 1169 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); |
983 } | 1170 } |
984 } | 1171 } |
985 fStats.incRenderTargetBinds(); | 1172 fStats.incRenderTargetBinds(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1025 // SkDEBUGFAIL("null texture"); | 1212 // SkDEBUGFAIL("null texture"); |
1026 return NULL; | 1213 return NULL; |
1027 } | 1214 } |
1028 | 1215 |
1029 #if 0 && defined(SK_DEBUG) | 1216 #if 0 && defined(SK_DEBUG) |
1030 static size_t as_size_t(int x) { | 1217 static size_t as_size_t(int x) { |
1031 return x; | 1218 return x; |
1032 } | 1219 } |
1033 #endif | 1220 #endif |
1034 | 1221 |
1222 static GrGLTexture::IDDesc generate_and_bind_gl_texture(const GrGLInterface* int erface, | |
1223 GrGpuResource::LifeCycle lifeCycle) { | |
1224 GrGLTexture::IDDesc idDesc; | |
1225 GR_GL_CALL(interface, GenTextures(1, &idDesc.fTextureID)); | |
1226 idDesc.fLifeCycle = lifeCycle; | |
1227 return idDesc; | |
1228 } | |
1229 | |
1230 static GrGLTexture::TexParams set_initial_texture_params(const GrGLInterface* in terface) { | |
1231 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | |
1232 // drivers have a bug where an FBO won't be complete if it includes a | |
1233 // texture that is not mipmap complete (considering the filter in use). | |
1234 GrGLTexture::TexParams initialTexParams; | |
1235 // we only set a subset here so invalidate first | |
1236 initialTexParams.invalidate(); | |
1237 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
1238 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
1239 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
1240 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
1241 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
1242 GR_GL_TEXTURE_MAG_FILTER, | |
1243 initialTexParams.fMagFilter)); | |
1244 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
1245 GR_GL_TEXTURE_MIN_FILTER, | |
1246 initialTexParams.fMinFilter)); | |
1247 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
1248 GR_GL_TEXTURE_WRAP_S, | |
1249 initialTexParams.fWrapS)); | |
1250 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
1251 GR_GL_TEXTURE_WRAP_T, | |
1252 initialTexParams.fWrapT)); | |
1253 return initialTexParams; | |
1254 } | |
1255 | |
1035 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, | 1256 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, |
1036 GrGpuResource::LifeCycle lifeCycle, | 1257 GrGpuResource::LifeCycle lifeCycle, |
1037 const void* srcData, size_t rowBytes) { | 1258 SkTArray<SkMipMapLevel>& texels) { |
1038 // We fail if the MSAA was requested and is not available. | 1259 // We fail if the MSAA was requested and is not available. |
1039 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { | 1260 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { |
1040 //SkDebugf("MSAA RT requested but not supported on this platform."); | 1261 //SkDebugf("MSAA RT requested but not supported on this platform."); |
1041 return return_null_texture(); | 1262 return return_null_texture(); |
1042 } | 1263 } |
1043 | 1264 |
1044 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); | 1265 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); |
1045 | 1266 |
1046 GrGLTexture::IDDesc idDesc; | 1267 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) { | 1268 if (!idDesc.fTextureID) { |
1051 return return_null_texture(); | 1269 return return_null_texture(); |
1052 } | 1270 } |
1053 | 1271 |
1054 this->setScratchTextureUnit(); | 1272 this->setScratchTextureUnit(); |
1055 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | 1273 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); |
1056 | 1274 |
1057 if (renderTarget && this->glCaps().textureUsageSupport()) { | 1275 if (renderTarget && this->glCaps().textureUsageSupport()) { |
1058 // provides a hint about how this texture will be used | 1276 // provides a hint about how this texture will be used |
1059 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 1277 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, |
1060 GR_GL_TEXTURE_USAGE, | 1278 GR_GL_TEXTURE_USAGE, |
1061 GR_GL_FRAMEBUFFER_ATTACHMENT)); | 1279 GR_GL_FRAMEBUFFER_ATTACHMENT)); |
1062 } | 1280 } |
1063 | 1281 |
1064 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1282 auto initialTexParams = set_initial_texture_params(this->glInterface()); |
1065 // drivers have a bug where an FBO won't be complete if it includes a | 1283 |
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, | 1284 if (!this->uploadTexData(desc, true, 0, 0, |
1087 desc.fWidth, desc.fHeight, | 1285 desc.fWidth, desc.fHeight, |
1088 desc.fConfig, srcData, rowBytes)) { | 1286 desc.fConfig, texels)) { |
1089 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1287 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
1090 return return_null_texture(); | 1288 return return_null_texture(); |
1091 } | 1289 } |
1092 | 1290 |
1093 GrGLTexture* tex; | 1291 GrGLTexture* tex; |
1094 if (renderTarget) { | 1292 if (renderTarget) { |
1095 // unbind the texture from the texture unit before binding it to the fra me buffer | 1293 // unbind the texture from the texture unit before binding it to the fra me buffer |
1096 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); | 1294 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); |
1097 GrGLRenderTarget::IDDesc rtIDDesc; | 1295 GrGLRenderTarget::IDDesc rtIDDesc; |
1098 | 1296 |
1099 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, &rtIDDesc)) { | 1297 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, &rtIDDesc)) { |
1100 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1298 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
1101 return return_null_texture(); | 1299 return return_null_texture(); |
1102 } | 1300 } |
1103 tex = SkNEW_ARGS(GrGLTextureRenderTarget, (this, desc, idDesc, rtIDDesc) ); | 1301 tex = SkNEW_ARGS(GrGLTextureRenderTarget, (this, desc, idDesc, rtIDDesc) ); |
1104 } else { | 1302 } else { |
1105 tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); | 1303 tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); |
1106 } | 1304 } |
1107 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1305 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
1108 #ifdef TRACE_TEXTURE_CREATION | 1306 #ifdef TRACE_TEXTURE_CREATION |
1109 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", | 1307 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", |
1110 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1308 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
1111 #endif | 1309 #endif |
1112 return tex; | 1310 return tex; |
1113 } | 1311 } |
1114 | 1312 |
1115 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, | 1313 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, |
1116 GrGpuResource::LifeCycle lifeCycle , | 1314 GrGpuResource::LifeCycle lifeCycle , |
1117 const void* srcData) { | 1315 SkTArray<SkMipMapLevel>& texels) { |
1118 // Make sure that we're not flipping Y. | 1316 // Make sure that we're not flipping Y. |
1119 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 1317 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
1120 return return_null_texture(); | 1318 return return_null_texture(); |
1121 } | 1319 } |
1122 | 1320 |
1123 GrGLTexture::IDDesc idDesc; | 1321 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) { | 1322 if (!idDesc.fTextureID) { |
1128 return return_null_texture(); | 1323 return return_null_texture(); |
1129 } | 1324 } |
1130 | 1325 |
1131 this->setScratchTextureUnit(); | 1326 this->setScratchTextureUnit(); |
1132 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | 1327 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); |
1133 | 1328 |
1134 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1329 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 | 1330 |
1157 if (!this->uploadCompressedTexData(desc, srcData)) { | 1331 if (!this->uploadCompressedTexData(desc, texels)) { |
1158 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1332 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
1159 return return_null_texture(); | 1333 return return_null_texture(); |
1160 } | 1334 } |
1161 | 1335 |
1162 GrGLTexture* tex; | 1336 GrGLTexture* tex; |
1163 tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); | 1337 tex = SkNEW_ARGS(GrGLTexture, (this, desc, idDesc)); |
1164 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1338 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
1165 #ifdef TRACE_TEXTURE_CREATION | 1339 #ifdef TRACE_TEXTURE_CREATION |
1166 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", | 1340 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", |
1167 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1341 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1234 width, height )); | 1408 width, height )); |
1235 created = (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glI nterface())); | 1409 created = (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glI nterface())); |
1236 } | 1410 } |
1237 if (created) { | 1411 if (created) { |
1238 fStats.incStencilAttachmentCreates(); | 1412 fStats.incStencilAttachmentCreates(); |
1239 // After sized formats we attempt an unsized format and take | 1413 // After sized formats we attempt an unsized format and take |
1240 // whatever sizes GL gives us. In that case we query for the size. | 1414 // whatever sizes GL gives us. In that case we query for the size. |
1241 GrGLStencilAttachment::Format format = sFmt; | 1415 GrGLStencilAttachment::Format format = sFmt; |
1242 get_stencil_rb_sizes(this->glInterface(), &format); | 1416 get_stencil_rb_sizes(this->glInterface(), &format); |
1243 SkAutoTUnref<GrGLStencilAttachment> sb(SkNEW_ARGS(GrGLStencilAttachm ent, | 1417 SkAutoTUnref<GrGLStencilAttachment> sb(SkNEW_ARGS(GrGLStencilAttachm ent, |
1244 (this, sbDesc, width, height, samples, format))); | 1418 (this, sbDesc, wid th, height, samples, format))); |
bsalomon
2015/08/26 18:30:11
nit wrap at 100 col
cblume
2015/08/26 18:58:00
Done.
| |
1245 if (this->attachStencilAttachmentToRenderTarget(sb, rt)) { | 1419 if (this->attachStencilAttachmentToRenderTarget(sb, rt)) { |
1246 fLastSuccessfulStencilFmtIdx = sIdx; | 1420 fLastSuccessfulStencilFmtIdx = sIdx; |
1247 rt->renderTargetPriv().didAttachStencilAttachment(sb); | 1421 rt->renderTargetPriv().didAttachStencilAttachment(sb); |
1248 // This work around is currently breaking on windows 7 hd2000 bot when we bind a color buffer | 1422 // This work around is currently breaking on windows 7 hd2000 bot when we bind a color buffer |
1249 #if 0 | 1423 #if 0 |
1250 // Clear the stencil buffer. We use a special purpose FBO for th is so that the | 1424 // Clear the stencil buffer. We use a special purpose FBO for th is so that the |
1251 // entire stencil buffer is cleared, even if it is attached to a n FBO with a | 1425 // entire stencil buffer is cleared, even if it is attached to a n FBO with a |
1252 // smaller color target. | 1426 // smaller color target. |
1253 if (0 == fStencilClearFBOID) { | 1427 if (0 == fStencilClearFBOID) { |
1254 GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); | 1428 GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1349 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1523 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1350 GR_GL_DEPTH_ATTACHMENT, | 1524 GR_GL_DEPTH_ATTACHMENT, |
1351 GR_GL_RENDERBUFFER, 0)); | 1525 GR_GL_RENDERBUFFER, 0)); |
1352 } | 1526 } |
1353 | 1527 |
1354 GrGLenum status; | 1528 GrGLenum status; |
1355 if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(), glsb->format())) { | 1529 if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(), glsb->format())) { |
1356 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1530 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
1357 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 1531 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
1358 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1532 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1359 GR_GL_STENCIL_ATTACHMENT, | 1533 GR_GL_STENCIL_ATTACHMENT, |
1360 GR_GL_RENDERBUFFER, 0)); | 1534 GR_GL_RENDERBUFFER, 0)); |
1361 if (glsb->format().fPacked) { | 1535 if (glsb->format().fPacked) { |
1362 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1536 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1363 GR_GL_DEPTH_ATTACHMENT, | 1537 GR_GL_DEPTH_ATTACHMENT, |
1364 GR_GL_RENDERBUFFER, 0)); | 1538 GR_GL_RENDERBUFFER, 0)); |
1365 } | 1539 } |
1366 return false; | 1540 return false; |
1367 } else { | 1541 } else { |
1368 fGLContext->caps()->markColorConfigAndStencilFormatAsVerified( | 1542 fGLContext->caps()->markColorConfigAndStencilFormatAsVerified( |
1369 rt->config(), | 1543 rt->config(), |
1370 glsb->format()); | 1544 glsb->format()); |
1371 } | 1545 } |
1372 } | 1546 } |
1373 return true; | 1547 return true; |
1374 } | 1548 } |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2426 case kSRGBA_8888_GrPixelConfig: | 2600 case kSRGBA_8888_GrPixelConfig: |
2427 *internalFormat = GR_GL_SRGB_ALPHA; | 2601 *internalFormat = GR_GL_SRGB_ALPHA; |
2428 *externalFormat = GR_GL_SRGB_ALPHA; | 2602 *externalFormat = GR_GL_SRGB_ALPHA; |
2429 if (getSizedInternalFormat || kGL_GrGLStandard == this->glStandard() ) { | 2603 if (getSizedInternalFormat || kGL_GrGLStandard == this->glStandard() ) { |
2430 // desktop or ES 3.0 | 2604 // desktop or ES 3.0 |
2431 SkASSERT(this->glVersion() >= GR_GL_VER(3, 0)); | 2605 SkASSERT(this->glVersion() >= GR_GL_VER(3, 0)); |
2432 *internalFormat = GR_GL_SRGB8_ALPHA8; | 2606 *internalFormat = GR_GL_SRGB8_ALPHA8; |
2433 *externalFormat = GR_GL_RGBA; | 2607 *externalFormat = GR_GL_RGBA; |
2434 } else { | 2608 } else { |
2435 // ES 2.0 with EXT_sRGB | 2609 // ES 2.0 with EXT_sRGB |
2436 SkASSERT(kGL_GrGLStandard != this->glStandard() && | 2610 SkASSERT(kGL_GrGLStandard != this->glStandard() && |
2437 this->glVersion() < GR_GL_VER(3, 0)); | 2611 this->glVersion() < GR_GL_VER(3, 0)); |
2438 *internalFormat = GR_GL_SRGB_ALPHA; | 2612 *internalFormat = GR_GL_SRGB_ALPHA; |
2439 *externalFormat = GR_GL_SRGB_ALPHA; | 2613 *externalFormat = GR_GL_SRGB_ALPHA; |
2440 } | 2614 } |
2441 *externalType = GR_GL_UNSIGNED_BYTE; | 2615 *externalType = GR_GL_UNSIGNED_BYTE; |
2442 break; | 2616 break; |
2443 case kRGB_565_GrPixelConfig: | 2617 case kRGB_565_GrPixelConfig: |
2444 *internalFormat = GR_GL_RGB; | 2618 *internalFormat = GR_GL_RGB; |
2445 *externalFormat = GR_GL_RGB; | 2619 *externalFormat = GR_GL_RGB; |
2446 if (getSizedInternalFormat) { | 2620 if (getSizedInternalFormat) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2534 *internalFormat = GR_GL_ALPHA; | 2708 *internalFormat = GR_GL_ALPHA; |
2535 } | 2709 } |
2536 *externalFormat = GR_GL_ALPHA; | 2710 *externalFormat = GR_GL_ALPHA; |
2537 } | 2711 } |
2538 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { | 2712 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { |
2539 *externalType = GR_GL_HALF_FLOAT; | 2713 *externalType = GR_GL_HALF_FLOAT; |
2540 } else { | 2714 } else { |
2541 *externalType = GR_GL_HALF_FLOAT_OES; | 2715 *externalType = GR_GL_HALF_FLOAT_OES; |
2542 } | 2716 } |
2543 break; | 2717 break; |
2544 | 2718 |
2545 case kRGBA_half_GrPixelConfig: | 2719 case kRGBA_half_GrPixelConfig: |
2546 *internalFormat = GR_GL_RGBA16F; | 2720 *internalFormat = GR_GL_RGBA16F; |
2547 *externalFormat = GR_GL_RGBA; | 2721 *externalFormat = GR_GL_RGBA; |
2548 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { | 2722 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { |
2549 *externalType = GR_GL_HALF_FLOAT; | 2723 *externalType = GR_GL_HALF_FLOAT; |
2550 } else { | 2724 } else { |
2551 *externalType = GR_GL_HALF_FLOAT_OES; | 2725 *externalType = GR_GL_HALF_FLOAT_OES; |
2552 } | 2726 } |
2553 break; | 2727 break; |
2554 | 2728 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2729 } | 2903 } |
2730 | 2904 |
2731 bool GrGLGpu::copySurface(GrSurface* dst, | 2905 bool GrGLGpu::copySurface(GrSurface* dst, |
2732 GrSurface* src, | 2906 GrSurface* src, |
2733 const SkIRect& srcRect, | 2907 const SkIRect& srcRect, |
2734 const SkIPoint& dstPoint) { | 2908 const SkIPoint& dstPoint) { |
2735 if (src->asTexture() && dst->asRenderTarget()) { | 2909 if (src->asTexture() && dst->asRenderTarget()) { |
2736 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | 2910 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); |
2737 return true; | 2911 return true; |
2738 } | 2912 } |
2739 | 2913 |
2740 if (can_copy_texsubimage(dst, src, this)) { | 2914 if (can_copy_texsubimage(dst, src, this)) { |
2741 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); | 2915 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); |
2742 return true; | 2916 return true; |
2743 } | 2917 } |
2744 | 2918 |
2745 if (can_blit_framebuffer(dst, src, this)) { | 2919 if (can_blit_framebuffer(dst, src, this)) { |
2746 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); | 2920 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); |
2747 } | 2921 } |
2748 | 2922 |
2749 return false; | 2923 return false; |
2750 } | 2924 } |
2751 | 2925 |
2752 | 2926 |
2753 void GrGLGpu::createCopyProgram() { | 2927 void GrGLGpu::createCopyProgram() { |
2754 const char* version = GrGLGetGLSLVersionDecl(this->ctxInfo()); | 2928 const char* version = GrGLGetGLSLVersionDecl(this->ctxInfo()); |
2755 | 2929 |
2756 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T ypeModifier); | 2930 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T ypeModifier); |
2757 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, | 2931 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, |
2758 GrShaderVar::kUniform_TypeModifier); | 2932 GrShaderVar::kUniform_TypeModifier); |
2759 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform _TypeModifier); | 2933 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform _TypeModifier); |
2760 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo rm_TypeModifier); | 2934 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo rm_TypeModifier); |
2761 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying Out_TypeModifier); | 2935 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying Out_TypeModifier); |
2762 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier); | 2936 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier); |
2763 | 2937 |
2764 SkString vshaderTxt(version); | 2938 SkString vshaderTxt(version); |
2765 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt); | 2939 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt); |
2766 vshaderTxt.append(";"); | 2940 vshaderTxt.append(";"); |
2767 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt); | 2941 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt); |
2768 vshaderTxt.append(";"); | 2942 vshaderTxt.append(";"); |
2769 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt); | 2943 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt); |
2770 vshaderTxt.append(";"); | 2944 vshaderTxt.append(";"); |
2771 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt); | 2945 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt); |
2772 vshaderTxt.append(";"); | 2946 vshaderTxt.append(";"); |
2773 | 2947 |
2774 vshaderTxt.append( | 2948 vshaderTxt.append( |
2775 "// Copy Program VS\n" | 2949 "// Copy Program VS\n" |
2776 "void main() {" | 2950 "void main() {" |
2777 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" | 2951 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" |
2778 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" | 2952 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" |
2779 " gl_Position.zw = vec2(0, 1);" | 2953 " gl_Position.zw = vec2(0, 1);" |
2780 "}" | 2954 "}" |
2781 ); | 2955 ); |
2782 | 2956 |
2783 SkString fshaderTxt(version); | 2957 SkString fshaderTxt(version); |
(...skipping 13 matching lines...) Expand all Loading... | |
2797 fsOutName = "gl_FragColor"; | 2971 fsOutName = "gl_FragColor"; |
2798 } | 2972 } |
2799 fshaderTxt.appendf( | 2973 fshaderTxt.appendf( |
2800 "// Copy Program FS\n" | 2974 "// Copy Program FS\n" |
2801 "void main() {" | 2975 "void main() {" |
2802 " %s = %s(u_texture, v_texCoord);" | 2976 " %s = %s(u_texture, v_texCoord);" |
2803 "}", | 2977 "}", |
2804 fsOutName, | 2978 fsOutName, |
2805 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) | 2979 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) |
2806 ); | 2980 ); |
2807 | 2981 |
2808 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); | 2982 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); |
2809 const char* str; | 2983 const char* str; |
2810 GrGLint length; | 2984 GrGLint length; |
2811 | 2985 |
2812 str = vshaderTxt.c_str(); | 2986 str = vshaderTxt.c_str(); |
2813 length = SkToInt(vshaderTxt.size()); | 2987 length = SkToInt(vshaderTxt.size()); |
2814 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram, | 2988 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram, |
2815 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats); | 2989 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats); |
2816 | 2990 |
2817 str = fshaderTxt.c_str(); | 2991 str = fshaderTxt.c_str(); |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3156 this->setVertexArrayID(gpu, 0); | 3330 this->setVertexArrayID(gpu, 0); |
3157 } | 3331 } |
3158 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3332 int attrCount = gpu->glCaps().maxVertexAttributes(); |
3159 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 3333 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
3160 fDefaultVertexArrayAttribState.resize(attrCount); | 3334 fDefaultVertexArrayAttribState.resize(attrCount); |
3161 } | 3335 } |
3162 attribState = &fDefaultVertexArrayAttribState; | 3336 attribState = &fDefaultVertexArrayAttribState; |
3163 } | 3337 } |
3164 return attribState; | 3338 return attribState; |
3165 } | 3339 } |
OLD | NEW |