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

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

Issue 1249543003: Creating functions for uploading a mipmapped texture. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: No longer exposing SkMipMap and SkCachedData. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/gpu/SkGr.cpp ('K') | « src/gpu/gl/GrGLGpu.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 8
9 #include "GrGLGpu.h" 9 #include "GrGLGpu.h"
10 #include "GrGLGLSL.h" 10 #include "GrGLGLSL.h"
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« src/gpu/SkGr.cpp ('K') | « src/gpu/gl/GrGLGpu.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698