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

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: Removing the concept of a dirty mipmap. It is expected that the texture upload provides the mipmaps. Created 5 years, 3 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
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 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 419
420 int maxSize = this->caps()->maxTextureSize(); 420 int maxSize = this->caps()->maxTextureSize();
421 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { 421 if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
422 return nullptr; 422 return nullptr;
423 } 423 }
424 424
425 GrGLTexture::IDDesc idDesc; 425 GrGLTexture::IDDesc idDesc;
426 GrSurfaceDesc surfDesc; 426 GrSurfaceDesc surfDesc;
427 427
428 idDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle); 428 idDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
429 429
430 switch (ownership) { 430 switch (ownership) {
431 case kAdopt_GrWrapOwnership: 431 case kAdopt_GrWrapOwnership:
432 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; 432 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
433 break; 433 break;
434 case kBorrow_GrWrapOwnership: 434 case kBorrow_GrWrapOwnership:
435 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; 435 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
436 break; 436 break;
437 } 437 }
438 438
439 // next line relies on GrBackendTextureDesc's flags matching GrTexture's 439 // next line relies on GrBackendTextureDesc's flags matching GrTexture's
440 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; 440 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags;
441 surfDesc.fWidth = desc.fWidth; 441 surfDesc.fWidth = desc.fWidth;
442 surfDesc.fHeight = desc.fHeight; 442 surfDesc.fHeight = desc.fHeight;
443 surfDesc.fConfig = desc.fConfig; 443 surfDesc.fConfig = desc.fConfig;
444 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() ); 444 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() );
445 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g); 445 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g);
446 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly 446 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly
447 // assuming the old behaviour, which is that backend textures are always 447 // assuming the old behaviour, which is that backend textures are always
(...skipping 29 matching lines...) Expand all
477 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); 477 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle);
478 idDesc.fMSColorRenderbufferID = 0; 478 idDesc.fMSColorRenderbufferID = 0;
479 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; 479 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
480 switch (ownership) { 480 switch (ownership) {
481 case kAdopt_GrWrapOwnership: 481 case kAdopt_GrWrapOwnership:
482 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; 482 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
483 break; 483 break;
484 case kBorrow_GrWrapOwnership: 484 case kBorrow_GrWrapOwnership:
485 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; 485 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
486 break; 486 break;
487 } 487 }
488 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; 488 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig;
489 489
490 GrSurfaceDesc desc; 490 GrSurfaceDesc desc;
491 desc.fConfig = wrapDesc.fConfig; 491 desc.fConfig = wrapDesc.fConfig;
492 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; 492 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag;
493 desc.fWidth = wrapDesc.fWidth; 493 desc.fWidth = wrapDesc.fWidth;
494 desc.fHeight = wrapDesc.fHeight; 494 desc.fHeight = wrapDesc.fHeight;
495 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); 495 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() );
496 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); 496 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true);
497 497
498 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits); 498 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits);
499 } 499 }
500 500
501 //////////////////////////////////////////////////////////////////////////////// 501 ////////////////////////////////////////////////////////////////////////////////
502 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 502 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
503 size_t rowBytes, GrPixelConfig srcConfig, 503 GrPixelConfig srcConfig,
504 DrawPreference* drawPreference, 504 DrawPreference* drawPreference,
505 WritePixelTempDrawInfo* tempDrawInfo) { 505 WritePixelTempDrawInfo* tempDrawInfo) {
506 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { 506 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) {
507 return false; 507 return false;
508 } 508 }
509 509
510 // This subclass only allows writes to textures. If the dst is not a texture we have to draw 510 // This subclass only allows writes to textures. If the dst is not a texture we have to draw
511 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. 511 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y.
512 if (!dstSurface->asTexture()) { 512 if (!dstSurface->asTexture()) {
513 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 513 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 if (!this->glCaps().unpackFlipYSupport() && 553 if (!this->glCaps().unpackFlipYSupport() &&
554 kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) { 554 kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) {
555 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 555 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
556 } 556 }
557 557
558 return true; 558 return true;
559 } 559 }
560 560
561 bool GrGLGpu::onWritePixels(GrSurface* surface, 561 bool GrGLGpu::onWritePixels(GrSurface* surface,
562 int left, int top, int width, int height, 562 int left, int top, int width, int height,
563 GrPixelConfig config, const void* buffer, 563 GrPixelConfig config,
564 size_t rowBytes) { 564 const SkTArray<SkMipMapLevel>& texels) {
565 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); 565 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
566 if (!glTex) { 566 if (!glTex) {
567 return false; 567 return false;
568 } 568 }
569 569
570 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels. 570 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels.
571 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 571 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
572 return false; 572 return false;
573 } 573 }
574 574
575 this->setScratchTextureUnit(); 575 this->setScratchTextureUnit();
576 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); 576 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID()));
577 577
578 bool success = false; 578 bool success = false;
579 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { 579 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
580 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() 580 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s()
581 SkASSERT(config == glTex->desc().fConfig); 581 SkASSERT(config == glTex->desc().fConfig);
582 success = this->uploadCompressedTexData(glTex->desc(), buffer, false, le ft, top, width, 582 success = this->uploadCompressedTexData(glTex->desc(), texels, false, le ft, top, width,
583 height); 583 height);
584 } else { 584 } else {
585 success = this->uploadTexData(glTex->desc(), false, left, top, width, he ight, config, 585 success = this->uploadTexData(glTex->desc(), false, left, top, width, he ight, config, texels);
586 buffer, rowBytes);
587 } 586 }
588 587
589 if (success) { 588 return success;
590 glTex->texturePriv().dirtyMipMaps(true);
591 return true;
592 }
593
594 return false;
595 } 589 }
596 590
597 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, 591 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
598 const GrGLInterface* interface) { 592 const GrGLInterface* interface) {
599 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { 593 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) {
600 return GR_GL_GET_ERROR(interface); 594 return GR_GL_GET_ERROR(interface);
601 } else { 595 } else {
602 return CHECK_ALLOC_ERROR(interface); 596 return CHECK_ALLOC_ERROR(interface);
603 } 597 }
604 } 598 }
605 599
606 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, 600 /**
607 bool isNewTexture, 601 * Determines if TexStorage can be used when creating a texture.
608 int left, int top, int width, int height, 602 *
609 GrPixelConfig dataConfig, 603 * @param caps The capabilities of the GL device.
610 const void* data, 604 * @param standard The GL standard in use.
611 size_t rowBytes) { 605 * @param desc The surface descriptor for the texture being created.
612 SkASSERT(data || isNewTexture); 606 */
613 607 static bool can_use_tex_storage(const GrGLCaps& caps, const GrGLStandard& standa rd,
614 // If we're uploading compressed data then we should be using uploadCompress edTexData 608 const GrSurfaceDesc& desc) {
615 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 609 bool useTexStorage = caps.texStorageSupport();
616 610 if (useTexStorage && kGL_GrGLStandard == standard) {
617 size_t bpp = GrBytesPerPixel(dataConfig);
618 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, & left, &top,
619 &width, &height, &data, &rowBytes )) {
620 return false;
621 }
622 size_t trimRowBytes = width * bpp;
623
624 // in case we need a temporary, trimmed copy of the src pixels
625 SkAutoSMalloc<128 * 128> tempStorage;
626
627 // We currently lazily create MIPMAPs when the we see a draw with
628 // GrTextureParams::kMipMap_FilterMode. Using texture storage requires that the
629 // MIP levels are all created when the texture is created. So for now we don 't use
630 // texture storage.
631 bool useTexStorage = false &&
632 isNewTexture &&
633 this->glCaps().texStorageSupport();
634
635 if (useTexStorage && kGL_GrGLStandard == this->glStandard()) {
636 // 565 is not a sized internal format on desktop GL. So on desktop with 611 // 565 is not a sized internal format on desktop GL. So on desktop with
637 // 565 we always use an unsized internal format to let the system pick 612 // 565 we always use an unsized internal format to let the system pick
638 // the best sized format to convert the 565 data to. Since TexStorage 613 // the best sized format to convert the 565 data to. Since TexStorage
639 // only allows sized internal formats we will instead use TexImage2D. 614 // only allows sized internal formats we will instead use TexImage2D.
640 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; 615 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig;
641 } 616 }
642 617
643 GrGLenum internalFormat = 0x0; // suppress warning 618 return useTexStorage;
644 GrGLenum externalFormat = 0x0; // suppress warning 619 }
645 GrGLenum externalType = 0x0; // suppress warning
646 620
621 /**
622 * Determines if sized internal formats are available for the texture being crea ted.
623 *
624 * @param useTexStorage The result of a call to can_use_tex_storage().
625 * @param caps The capabilities of the GL device.
626 * @param standard The GL standard in use.
627 * @param version The GL version in use.
628 * @param dataConfig The pixel configuration for the texture being created.
629 */
630 static bool can_use_sized_format(bool useTexStorage, const GrGLCaps& caps,
631 const GrGLStandard& standard, const GrGLVersion & version,
632 GrPixelConfig dataConfig) {
647 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized 633 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized
648 // format for glTexImage, unlike ES3 and desktop. 634 // format for glTexImage, unlike ES3 and desktop.
649 bool useSizedFormat = useTexStorage; 635 bool useSizedFormat = useTexStorage;
650 if (kGL_GrGLStandard == this->glStandard() || 636 if (kGL_GrGLStandard == standard ||
651 (this->glVersion() >= GR_GL_VER(3, 0) && 637 (version >= GR_GL_VER(3, 0) &&
652 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled 638 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled
653 (kBGRA_8888_GrPixelConfig != dataConfig || !this->glCaps().bgraIsIntern alFormat()))) { 639 (kBGRA_8888_GrPixelConfig != dataConfig || !caps.bgraIsInternalFormat() ))) {
654 useSizedFormat = true; 640 useSizedFormat = true;
655 } 641 }
656 642
657 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, 643 return useSizedFormat;
658 &externalFormat, &externalType)) { 644 }
659 return false;
660 }
661 645
662 /* 646 /**
663 * check whether to allocate a temporary buffer for flipping y or 647 * Prior to a texture being created, the image may need to be flipped vertically . This function
664 * because our srcData has extra bytes past each row. If so, we need 648 * prepares the texels for texture creation.
665 * to trim those off here, since GL ES may not let us specify 649 *
666 * GL_UNPACK_ROW_LENGTH. 650 * @param desc The surface descriptor for the texture being create d.
667 */ 651 * @param caps The capabilities of the GL device.
668 bool restoreGLRowLength = false; 652 * @param interface The GL interface in use.
669 bool swFlipY = false; 653 * @param swFlipY Should software be used when flipping a texture ver tically?
670 bool glFlipY = false; 654 * @param glFlipY Should GL be used when flipping a texture verticall y?
671 if (data) { 655 * @param width The width of the texture in texels.
672 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 656 * @param height The height of the texture in texels.
673 if (this->glCaps().unpackFlipYSupport()) { 657 * @param bpp The bits per pixel (or texel, really) of the textur e.
674 glFlipY = true; 658 * @param texels An array of mipmap levels which contain the texel d ata at that level.
675 } else { 659 * @param tempStorage In the case where the image needs to be flipped ver tically, it will
676 swFlipY = true; 660 * use tempStorage as a buffer.
677 } 661 * @param restoreGLRowLength After the texture is created, will the GL row lengt h unpacking need
662 * to be restored?
663 */
664 static void prepare_image_for_writing_to_texture(const GrSurfaceDesc& desc, cons t GrGLCaps& caps,
665 const GrGLInterface& interface, bool swFlipY,
666 bool glFlipY, int width, int he ight, int bpp,
667 SkTArray<SkMipMapLevel>& texels ,
668 SkAutoSMalloc<128 * 128>& tempS torage,
669 bool* restoreGLRowLength) {
670 int currentMipLevelWidth = width;
671 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) {
672 if (texels[currentMipLevel].fTexels == nullptr) {
673 continue;
678 } 674 }
679 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { 675
676 size_t trimRowBytes = currentMipLevelWidth * bpp;
677
678 /*
679 * check whether to allocate a temporary buffer for flipping y or
680 * because our srcData has extra bytes past each row. If so, we need
681 * to trim those off here, since GL ES may not let us specify
682 * GL_UNPACK_ROW_LENGTH.
683 */
684 *restoreGLRowLength = false;
685
686 auto rowBytes = texels[currentMipLevel].fRowBytes;
687 if (caps.unpackRowLengthSupport() && !swFlipY) {
680 // can't use this for flipping, only non-neg values allowed. :( 688 // can't use this for flipping, only non-neg values allowed. :(
681 if (rowBytes != trimRowBytes) { 689 if (rowBytes != trimRowBytes) {
682 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); 690 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
683 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); 691 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowL ength));
684 restoreGLRowLength = true; 692 *restoreGLRowLength = true;
685 } 693 }
686 } else { 694 } else {
687 if (trimRowBytes != rowBytes || swFlipY) { 695 if (trimRowBytes != rowBytes || swFlipY) {
688 // copy data into our new storage, skipping the trailing bytes 696 // copy data into our new storage, skipping the trailing bytes
689 size_t trimSize = height * trimRowBytes; 697 size_t trimSize = height * trimRowBytes;
690 const char* src = (const char*)data; 698 const char* src = (const char*)texels[currentMipLevel].fTexels;
691 if (swFlipY) { 699 if (swFlipY) {
692 src += (height - 1) * rowBytes; 700 src += (height - 1) * rowBytes;
693 } 701 }
694 char* dst = (char*)tempStorage.reset(trimSize); 702 char* dst = (char*)tempStorage.reset(trimSize);
695 for (int y = 0; y < height; y++) { 703 for (int y = 0; y < height; y++) {
696 memcpy(dst, src, trimRowBytes); 704 memcpy(dst, src, trimRowBytes);
697 if (swFlipY) { 705 if (swFlipY) {
698 src -= rowBytes; 706 src -= rowBytes;
699 } else { 707 } else {
700 src += rowBytes; 708 src += rowBytes;
701 } 709 }
702 dst += trimRowBytes; 710 dst += trimRowBytes;
703 } 711 }
704 // now point data to our copied version 712 // now point data to our copied version
705 data = tempStorage.get(); 713 texels[currentMipLevel] = SkMipMapLevel(tempStorage.get(), trimR owBytes);
706 } 714 }
707 } 715 }
708 if (glFlipY) { 716 if (glFlipY) {
709 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); 717 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)) ;
710 } 718 }
711 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 719 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT,
712 static_cast<GrGLint>(GrUnpackAlignment(dataConfig)))); 720 static_cast<GrGLint>(GrUnpackAlignmen t(desc.fConfig))));
713 } 721 currentMipLevelWidth /= 2;
722 }
723 }
724
725 /**
726 * Creates storage space for the texture and fills it with texels.
727 *
728 * @param desc The surface descriptor for the texture being created.
729 * @param interface The GL interface in use.
730 * @param useTexStorage The result of a call to can_use_tex_storage().
731 * @param internalFormat The data format used for the internal storage of the te xture.
732 * @param externalFormat The data format used for the external storage of the te xture.
733 * @param externalType The type of the data used for the external storage of t he texture.
734 * @param texels The texel data of the texture being created.
735 * @param succeeded Set to true if allocating and populating the texture co mpleted
736 * without error.
737 */
738 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc ,
739 const GrGLInterface& inte rface,
740 bool useTexStorage,
741 GrGLenum internalFormat,
742 GrGLenum externalFormat,
743 GrGLenum externalType,
744 const SkTArray<SkMipMapLe vel>& texels,
745 bool* succeeded) {
746 CLEAR_ERROR_BEFORE_ALLOC(&interface);
747 if (useTexStorage) {
748 // We never resize or change formats of textures.
749 GL_ALLOC_CALL(&interface,
750 TexStorage2D(GR_GL_TEXTURE_2D,
751 texels.count(),
752 internalFormat,
753 desc.fWidth, desc.fHeight));
754 } else {
755 int width = desc.fWidth;
756 int height = desc.fHeight;
757 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
758 auto currentMipData = texels[currentMipLevel].fTexels;
759 if (currentMipData == nullptr) {
760 continue;
761 }
762
763 GL_ALLOC_CALL(&interface,
764 TexImage2D(GR_GL_TEXTURE_2D,
765 currentMipLevel,
766 internalFormat,
767 width, height,
768 0, // border
769 externalFormat, externalType,
770 currentMipData));
771 width /= 2;
772 height /= 2;
773 }
774 }
775
776 GrGLenum error = check_alloc_error(desc, &interface);
777 if (error != GR_GL_NO_ERROR) {
778 *succeeded = false;
779 } else {
780 int width = desc.fWidth;
781 int height = desc.fHeight;
782 for (auto currentMipLevel = texels.count() - 1; currentMipLevel >= 0; cu rrentMipLevel--) {
783 auto currentMipData = texels[currentMipLevel].fTexels;
784 if (currentMipData == nullptr) {
785 continue;
786 }
787
788 GR_GL_CALL(&interface,
789 TexSubImage2D(GR_GL_TEXTURE_2D,
790 currentMipLevel,
791 0, // left
792 0, // top
793 width, height,
794 externalFormat, externalType,
795 currentMipData));
796 width /= 2;
797 height /= 2;
798 }
799 *succeeded = true;
800 }
801 }
802
803 /**
804 * Creates storage space for the texture and fills it with texels.
805 *
806 * @param desc The surface descriptor for the texture being created.
807 * @param interface The GL interface in use.
808 * @param useTexStorage The result of a call to can_use_tex_storage().
809 * @param internalFormat The data format used for the internal storage of the te xture.
810 * @param texels The texel data of the texture being created.
811 */
812 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc,
813 const GrGLInterface& interf ace,
814 bool useTexStorage, GrGLenu m internalFormat,
815 const SkTArray<SkMipMapLeve l>& texels) {
816 CLEAR_ERROR_BEFORE_ALLOC(&interface);
817 if (useTexStorage) {
818 // We never resize or change formats of textures.
819 GL_ALLOC_CALL(&interface,
820 TexStorage2D(GR_GL_TEXTURE_2D,
821 texels.count(),
822 internalFormat,
823 desc.fWidth, desc.fHeight));
824 } else {
825 int width = desc.fWidth;
826 int height = desc.fHeight;
827 for (auto currentMipLevel = texels.count() - 1; currentMipLevel >= 0; cu rrentMipLevel--) {
828 auto currentMipData = texels[currentMipLevel].fTexels;
829
830 if (currentMipData == nullptr) {
831 continue;
832 }
833
834 // Make sure that the width and height that we pass to OpenGL
835 // is a multiple of the block size.
836 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, he ight);
837
838 GL_ALLOC_CALL(&interface,
839 CompressedTexImage2D(GR_GL_TEXTURE_2D,
840 texels.count(),
841 internalFormat,
842 width, height,
843 0, // border
844 SkToInt(dataSize),
845 currentMipData));
846 width /= 2;
847 height /= 2;
848 }
849 }
850
851 GrGLenum error = check_alloc_error(desc, &interface);
852 if (error != GR_GL_NO_ERROR) {
853 return false;
854 }
855 return true;
856 }
857
858 /**
859 * After a texture is created, any state which was altered during its creation
860 * needs to be restored.
861 *
862 * @param interface The GL interface to use.
863 * @param caps The capabilities of the GL device.
864 * @param restoreGLRowLength Should the row length unpacking be restored?
865 * @param glFlipY Did GL flip the texture vertically?
866 */
867 static void restore_gl_state(const GrGLInterface& interface, const GrGLCaps& cap s,
bsalomon 2015/09/15 13:14:11 maybe give this a narrower name? e.g. restore_pixe
cblume 2015/09/16 18:40:46 Oh wow, that is a much better name. Done.
868 bool restoreGLRowLength, bool glFlipY) {
869 if (restoreGLRowLength) {
870 SkASSERT(caps.unpackRowLengthSupport());
871 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
872 }
873 if (glFlipY) {
874 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
875 }
876 }
877
878 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
879 bool isNewTexture,
880 int left, int top, int width, int height,
881 GrPixelConfig dataConfig,
882 const SkTArray<SkMipMapLevel>& texels) {
883 // If we're uploading compressed data then we should be using uploadCompress edTexData
884 SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
885
886 SkTArray<SkMipMapLevel> texelsCopy(texels);
887
888 for (auto currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; cu rrentMipLevel--) {
889 SkASSERT(texelsCopy[currentMipLevel].fTexels || isNewTexture);
890 }
891
892
893 auto interface = this->glInterface();
894 if (interface == nullptr) {
895 return false;
896 }
897 auto& caps = this->glCaps();
898 auto standard = this->glStandard();
899 auto version = this->glVersion();
900
901 size_t bpp = GrBytesPerPixel(dataConfig);
902 int mipWidth = desc.fWidth;
903 int mipHeight = desc.fHeight;
904 for (auto currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; cu rrentMipLevel--) {
905 if (texelsCopy[currentMipLevel].fTexels == nullptr) {
906 continue;
907 }
908
909 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp p, &left, &top,
910 &mipWidth, &mipHeight, &texelsCop y[currentMipLevel].fTexels, &texelsCopy[currentMipLevel].fRowBytes)) {
911 return false;
912 }
913 }
914
915 bool useTexStorage = can_use_tex_storage(caps, standard, desc);
916 bool useSizedFormat = can_use_sized_format(useTexStorage, caps, standard, ve rsion, dataConfig);
917
918 GrGLenum internalFormat = 0x0; // suppress warning
919 GrGLenum externalFormat = 0x0; // suppress warning
920 GrGLenum externalType = 0x0; // suppress warning
921
922 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat,
923 &externalFormat, &externalType)) {
924 return false;
925 }
926
927 bool swFlipY = false;
928 bool glFlipY = false;
929
930 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
931 if (caps.unpackFlipYSupport()) {
932 glFlipY = true;
933 } else {
934 swFlipY = true;
935 }
936 }
937
938 bool restoreGLRowLength = false;
939
940 // in case we need a temporary, trimmed copy of the src pixels
941 SkAutoSMalloc<128 * 128> tempStorage;
942 prepare_image_for_writing_to_texture(desc, caps, *interface, swFlipY, glFlip Y, width,
943 height, bpp, texelsCopy, tempStorage, & restoreGLRowLength);
714 bool succeeded = true; 944 bool succeeded = true;
715 if (isNewTexture && 945 if (isNewTexture &&
716 0 == left && 0 == top && 946 0 == left && 0 == top &&
717 desc.fWidth == width && desc.fHeight == height) { 947 desc.fWidth == width && desc.fHeight == height) {
718 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 948 allocate_and_populate_uncompressed_texture(desc, *interface, useTexStora ge, internalFormat,
719 if (useTexStorage) { 949 externalFormat, externalType, texelsCopy,
720 // We never resize or change formats of textures. 950 &succeeded);
721 GL_ALLOC_CALL(this->glInterface(),
722 TexStorage2D(GR_GL_TEXTURE_2D,
723 1, // levels
724 internalFormat,
725 desc.fWidth, desc.fHeight));
726 } else {
727 GL_ALLOC_CALL(this->glInterface(),
728 TexImage2D(GR_GL_TEXTURE_2D,
729 0, // level
730 internalFormat,
731 desc.fWidth, desc.fHeight,
732 0, // border
733 externalFormat, externalType,
734 data));
735 }
736 GrGLenum error = check_alloc_error(desc, this->glInterface());
737 if (error != GR_GL_NO_ERROR) {
738 succeeded = false;
739 } else {
740 // if we have data and we used TexStorage to create the texture, we
741 // now upload with TexSubImage.
742 if (data && useTexStorage) {
743 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
744 0, // level
745 left, top,
746 width, height,
747 externalFormat, externalType,
748 data));
749 }
750 }
751 } else { 951 } else {
752 if (swFlipY || glFlipY) { 952 if (swFlipY || glFlipY) {
753 top = desc.fHeight - (top + height); 953 top = desc.fHeight - (top + height);
754 } 954 }
755 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, 955 width = desc.fWidth;
756 0, // level 956 height = desc.fHeight;
757 left, top, 957 for (int currentMipLevel = 0; currentMipLevel < texelsCopy.count(); curr entMipLevel++) {
758 width, height, 958 if (texelsCopy[currentMipLevel].fTexels == nullptr) {
759 externalFormat, externalType, data)); 959 continue;
760 } 960 }
761 961
762 if (restoreGLRowLength) { 962 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
763 SkASSERT(this->glCaps().unpackRowLengthSupport()); 963 0, // level
764 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 964 left, top,
765 } 965 width, height,
766 if (glFlipY) { 966 externalFormat, externalType, texelsCopy[curre ntMipLevel].fTexels));
767 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 967 width /= 2;
768 } 968 height /= 2;
969 }
970 }
971
972 restore_gl_state(*interface, caps, restoreGLRowLength, glFlipY);
973
769 return succeeded; 974 return succeeded;
770 } 975 }
771 976
772 // TODO: This function is using a lot of wonky semantics like, if width == -1 977 // TODO: This function is using a lot of wonky semantics like, if width == -1
773 // then set width = desc.fWdith ... blah. A better way to do it might be to 978 // then set width = desc.fWdith ... blah. A better way to do it might be to
774 // create a CompressedTexData struct that takes a desc/ptr and figures out 979 // create a CompressedTexData struct that takes a desc/ptr and figures out
775 // the proper upload semantics. Then users can construct this function how they 980 // the proper upload semantics. Then users can construct this function how they
776 // see fit if they want to go against the "standard" way to do it. 981 // see fit if they want to go against the "standard" way to do it.
777 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, 982 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
778 const void* data, 983 const SkTArray<SkMipMapLevel>& texels,
779 bool isNewTexture, 984 bool isNewTexture,
780 int left, int top, int width, int height) { 985 int left, int top, int width, int height) {
781 SkASSERT(data || isNewTexture); 986 SkASSERT(isNewTexture);
782 987
783 // No support for software flip y, yet... 988 // No support for software flip y, yet...
784 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); 989 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
785 990
991 auto interface = this->glInterface();
992 if (interface == nullptr) {
993 return false;
994 }
995 auto& caps = this->glCaps();
996 auto standard = this->glStandard();
997
786 if (-1 == width) { 998 if (-1 == width) {
787 width = desc.fWidth; 999 width = desc.fWidth;
788 } 1000 }
789 #ifdef SK_DEBUG 1001 #ifdef SK_DEBUG
790 else { 1002 else {
791 SkASSERT(width <= desc.fWidth); 1003 SkASSERT(width <= desc.fWidth);
792 } 1004 }
793 #endif 1005 #endif
794 1006
795 if (-1 == height) { 1007 if (-1 == height) {
796 height = desc.fHeight; 1008 height = desc.fHeight;
797 } 1009 }
798 #ifdef SK_DEBUG 1010 #ifdef SK_DEBUG
799 else { 1011 else {
800 SkASSERT(height <= desc.fHeight); 1012 SkASSERT(height <= desc.fHeight);
801 } 1013 }
802 #endif 1014 #endif
803 1015
804 // Make sure that the width and height that we pass to OpenGL 1016 bool useTexStorage = can_use_tex_storage(caps, standard, desc);
805 // is a multiple of the block size.
806 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height);
807 1017
808 // We only need the internal format for compressed 2D textures. 1018 // We only need the internal format for compressed 2D textures.
809 GrGLenum internalFormat = 0; 1019 GrGLenum internalFormat = 0;
810 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, nullptr, nullptr)) { 1020 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, nullptr, nullptr)) {
811 return false; 1021 return false;
812 } 1022 }
813 1023
814 if (isNewTexture) { 1024 if (isNewTexture) {
815 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1025 return allocate_and_populate_compressed_texture(desc, *interface, useTex Storage,
816 GL_ALLOC_CALL(this->glInterface(), 1026 internalFormat, texels);
817 CompressedTexImage2D(GR_GL_TEXTURE_2D,
818 0, // level
819 internalFormat,
820 width, height,
821 0, // border
822 SkToInt(dataSize),
823 data));
824 GrGLenum error = check_alloc_error(desc, this->glInterface());
825 if (error != GR_GL_NO_ERROR) {
826 return false;
827 }
828 } else { 1027 } else {
829 // Paletted textures can't be updated. 1028 // Paletted textures can't be updated.
830 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { 1029 if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
831 return false; 1030 return false;
832 } 1031 }
833 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D, 1032 int currentMipWidth = width;
834 0, // level 1033 int currentMipHeight = height;
835 left, top, 1034 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
836 width, height, 1035 if (texels[currentMipLevel].fTexels == nullptr) {
837 internalFormat, 1036 continue;
838 SkToInt(dataSize), 1037 }
839 data)); 1038
1039 // Make sure that the width and height that we pass to OpenGL
1040 // is a multiple of the block size.
1041 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentMi pWidth, currentMipHeight);
1042 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D,
1043 0, // level
1044 left, top,
1045 currentMipWidth, currentMipHeight,
1046 internalFormat,
1047 dataSize,
1048 texels[currentMipLevel].fTexels));
1049 currentMipWidth /= 2;
1050 currentMipHeight /= 2;
1051 }
840 } 1052 }
841 1053
842 return true; 1054 return true;
843 } 1055 }
844 1056
845 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, 1057 static bool renderbuffer_storage_msaa(const GrGLContext& ctx,
846 int sampleCount, 1058 int sampleCount,
847 GrGLenum format, 1059 GrGLenum format,
848 int width, int height) { 1060 int width, int height) {
849 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); 1061 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe rID)); 1147 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe rID));
936 if (!renderbuffer_storage_msaa(*fGLContext, 1148 if (!renderbuffer_storage_msaa(*fGLContext,
937 desc.fSampleCnt, 1149 desc.fSampleCnt,
938 msColorFormat, 1150 msColorFormat,
939 desc.fWidth, desc.fHeight)) { 1151 desc.fWidth, desc.fHeight)) {
940 goto FAILED; 1152 goto FAILED;
941 } 1153 }
942 fStats.incRenderTargetBinds(); 1154 fStats.incRenderTargetBinds();
943 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); 1155 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID));
944 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, 1156 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
945 GR_GL_COLOR_ATTACHMENT0, 1157 GR_GL_COLOR_ATTACHMENT0,
946 GR_GL_RENDERBUFFER, 1158 GR_GL_RENDERBUFFER,
947 idDesc->fMSColorRenderbufferID)); 1159 idDesc->fMSColorRenderbufferID));
948 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || 1160 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) ||
949 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { 1161 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) {
950 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); 1162 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
951 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { 1163 if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
952 goto FAILED; 1164 goto FAILED;
953 } 1165 }
954 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); 1166 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig);
955 } 1167 }
956 } 1168 }
957 fStats.incRenderTargetBinds(); 1169 fStats.incRenderTargetBinds();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 // SkDEBUGFAIL("null texture"); 1209 // SkDEBUGFAIL("null texture");
998 return nullptr; 1210 return nullptr;
999 } 1211 }
1000 1212
1001 #if 0 && defined(SK_DEBUG) 1213 #if 0 && defined(SK_DEBUG)
1002 static size_t as_size_t(int x) { 1214 static size_t as_size_t(int x) {
1003 return x; 1215 return x;
1004 } 1216 }
1005 #endif 1217 #endif
1006 1218
1219 static GrGLTexture::IDDesc generate_and_bind_gl_texture(const GrGLInterface* int erface,
1220 GrGpuResource::LifeCycle lifeCycle) {
1221 GrGLTexture::IDDesc idDesc;
1222 GR_GL_CALL(interface, GenTextures(1, &idDesc.fTextureID));
1223 idDesc.fLifeCycle = lifeCycle;
1224 return idDesc;
1225 }
1226
1227 static GrGLTexture::TexParams set_initial_texture_params(const GrGLInterface* in terface) {
1228 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
1229 // drivers have a bug where an FBO won't be complete if it includes a
1230 // texture that is not mipmap complete (considering the filter in use).
1231 GrGLTexture::TexParams initialTexParams;
1232 // we only set a subset here so invalidate first
1233 initialTexParams.invalidate();
1234 initialTexParams.fMinFilter = GR_GL_NEAREST;
1235 initialTexParams.fMagFilter = GR_GL_NEAREST;
1236 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1237 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1238 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D,
1239 GR_GL_TEXTURE_MAG_FILTER,
1240 initialTexParams.fMagFilter));
1241 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D,
1242 GR_GL_TEXTURE_MIN_FILTER,
1243 initialTexParams.fMinFilter));
1244 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D,
1245 GR_GL_TEXTURE_WRAP_S,
1246 initialTexParams.fWrapS));
1247 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D,
1248 GR_GL_TEXTURE_WRAP_T,
1249 initialTexParams.fWrapT));
1250 return initialTexParams;
1251 }
1252
1007 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, 1253 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
1008 GrGpuResource::LifeCycle lifeCycle, 1254 GrGpuResource::LifeCycle lifeCycle,
1009 const void* srcData, size_t rowBytes) { 1255 const SkTArray<SkMipMapLevel>& texels) {
1010 // We fail if the MSAA was requested and is not available. 1256 // We fail if the MSAA was requested and is not available.
1011 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { 1257 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) {
1012 //SkDebugf("MSAA RT requested but not supported on this platform."); 1258 //SkDebugf("MSAA RT requested but not supported on this platform.");
1013 return return_null_texture(); 1259 return return_null_texture();
1014 } 1260 }
1015 1261
1016 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 1262 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
1017 1263
1018 GrGLTexture::IDDesc idDesc; 1264 auto idDesc = generate_and_bind_gl_texture(this->glInterface(), lifeCycle);
1019 GL_CALL(GenTextures(1, &idDesc.fTextureID));
1020 idDesc.fLifeCycle = lifeCycle;
1021
1022 if (!idDesc.fTextureID) { 1265 if (!idDesc.fTextureID) {
1023 return return_null_texture(); 1266 return return_null_texture();
1024 } 1267 }
1025 1268
1026 this->setScratchTextureUnit(); 1269 this->setScratchTextureUnit();
1027 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); 1270 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID));
1028 1271
1029 if (renderTarget && this->glCaps().textureUsageSupport()) { 1272 if (renderTarget && this->glCaps().textureUsageSupport()) {
1030 // provides a hint about how this texture will be used 1273 // provides a hint about how this texture will be used
1031 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 1274 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1032 GR_GL_TEXTURE_USAGE, 1275 GR_GL_TEXTURE_USAGE,
1033 GR_GL_FRAMEBUFFER_ATTACHMENT)); 1276 GR_GL_FRAMEBUFFER_ATTACHMENT));
1034 } 1277 }
1035 1278
1036 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1279 auto initialTexParams = set_initial_texture_params(this->glInterface());
1037 // drivers have a bug where an FBO won't be complete if it includes a 1280
1038 // texture that is not mipmap complete (considering the filter in use).
1039 GrGLTexture::TexParams initialTexParams;
1040 // we only set a subset here so invalidate first
1041 initialTexParams.invalidate();
1042 initialTexParams.fMinFilter = GR_GL_NEAREST;
1043 initialTexParams.fMagFilter = GR_GL_NEAREST;
1044 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1045 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1046 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1047 GR_GL_TEXTURE_MAG_FILTER,
1048 initialTexParams.fMagFilter));
1049 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1050 GR_GL_TEXTURE_MIN_FILTER,
1051 initialTexParams.fMinFilter));
1052 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1053 GR_GL_TEXTURE_WRAP_S,
1054 initialTexParams.fWrapS));
1055 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1056 GR_GL_TEXTURE_WRAP_T,
1057 initialTexParams.fWrapT));
1058 if (!this->uploadTexData(desc, true, 0, 0, 1281 if (!this->uploadTexData(desc, true, 0, 0,
1059 desc.fWidth, desc.fHeight, 1282 desc.fWidth, desc.fHeight,
1060 desc.fConfig, srcData, rowBytes)) { 1283 desc.fConfig, texels)) {
1061 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); 1284 GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
1062 return return_null_texture(); 1285 return return_null_texture();
1063 } 1286 }
1064 1287
1065 GrGLTexture* tex; 1288 GrGLTexture* tex;
1066 if (renderTarget) { 1289 if (renderTarget) {
1067 // unbind the texture from the texture unit before binding it to the fra me buffer 1290 // unbind the texture from the texture unit before binding it to the fra me buffer
1068 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); 1291 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0));
1069 GrGLRenderTarget::IDDesc rtIDDesc; 1292 GrGLRenderTarget::IDDesc rtIDDesc;
1070 1293
1071 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, &rtIDDesc)) { 1294 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, &rtIDDesc)) {
1072 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); 1295 GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
1073 return return_null_texture(); 1296 return return_null_texture();
1074 } 1297 }
1075 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); 1298 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc);
1076 } else { 1299 } else {
1077 tex = new GrGLTexture(this, desc, idDesc); 1300 tex = new GrGLTexture(this, desc, idDesc);
1078 } 1301 }
1079 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1302 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1080 #ifdef TRACE_TEXTURE_CREATION 1303 #ifdef TRACE_TEXTURE_CREATION
1081 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", 1304 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n",
1082 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1305 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
1083 #endif 1306 #endif
1084 return tex; 1307 return tex;
1085 } 1308 }
1086 1309
1087 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, 1310 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc,
1088 GrGpuResource::LifeCycle lifeCycle , 1311 GrGpuResource::LifeCycle lifeCycle ,
1089 const void* srcData) { 1312 const SkTArray<SkMipMapLevel>& tex els) {
1090 // Make sure that we're not flipping Y. 1313 // Make sure that we're not flipping Y.
1091 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 1314 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
1092 return return_null_texture(); 1315 return return_null_texture();
1093 } 1316 }
1094 1317
1095 GrGLTexture::IDDesc idDesc; 1318 auto idDesc = generate_and_bind_gl_texture(this->glInterface(), lifeCycle);
1096 GL_CALL(GenTextures(1, &idDesc.fTextureID));
1097 idDesc.fLifeCycle = lifeCycle;
1098
1099 if (!idDesc.fTextureID) { 1319 if (!idDesc.fTextureID) {
1100 return return_null_texture(); 1320 return return_null_texture();
1101 } 1321 }
1102 1322
1103 this->setScratchTextureUnit(); 1323 this->setScratchTextureUnit();
1104 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); 1324 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID));
1105 1325
1106 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1326 auto initialTexParams = set_initial_texture_params(this->glInterface());
1107 // drivers have a bug where an FBO won't be complete if it includes a
1108 // texture that is not mipmap complete (considering the filter in use).
1109 GrGLTexture::TexParams initialTexParams;
1110 // we only set a subset here so invalidate first
1111 initialTexParams.invalidate();
1112 initialTexParams.fMinFilter = GR_GL_NEAREST;
1113 initialTexParams.fMagFilter = GR_GL_NEAREST;
1114 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1115 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1116 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1117 GR_GL_TEXTURE_MAG_FILTER,
1118 initialTexParams.fMagFilter));
1119 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1120 GR_GL_TEXTURE_MIN_FILTER,
1121 initialTexParams.fMinFilter));
1122 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1123 GR_GL_TEXTURE_WRAP_S,
1124 initialTexParams.fWrapS));
1125 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1126 GR_GL_TEXTURE_WRAP_T,
1127 initialTexParams.fWrapT));
1128 1327
1129 if (!this->uploadCompressedTexData(desc, srcData)) { 1328 if (!this->uploadCompressedTexData(desc, texels)) {
1130 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); 1329 GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
1131 return return_null_texture(); 1330 return return_null_texture();
1132 } 1331 }
1133 1332
1134 GrGLTexture* tex; 1333 GrGLTexture* tex;
1135 tex = new GrGLTexture(this, desc, idDesc); 1334 tex = new GrGLTexture(this, desc, idDesc);
1136 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1335 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1137 #ifdef TRACE_TEXTURE_CREATION 1336 #ifdef TRACE_TEXTURE_CREATION
1138 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", 1337 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n",
1139 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1338 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 fHWSRGBFramebuffer = kYes_TriState; 2133 fHWSRGBFramebuffer = kYes_TriState;
1935 } else if (!enableSRGBWrite && kNo_TriState != fHWSRGBFramebuffer) { 2134 } else if (!enableSRGBWrite && kNo_TriState != fHWSRGBFramebuffer) {
1936 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); 2135 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB));
1937 fHWSRGBFramebuffer = kNo_TriState; 2136 fHWSRGBFramebuffer = kNo_TriState;
1938 } 2137 }
1939 } 2138 }
1940 } 2139 }
1941 if (nullptr == bound || !bound->isEmpty()) { 2140 if (nullptr == bound || !bound->isEmpty()) {
1942 target->flagAsNeedingResolve(bound); 2141 target->flagAsNeedingResolve(bound);
1943 } 2142 }
1944
1945 GrTexture *texture = target->asTexture();
1946 if (texture) {
1947 texture->texturePriv().dirtyMipMaps(true);
1948 }
1949 } 2143 }
1950 2144
1951 GrGLenum gPrimitiveType2GLMode[] = { 2145 GrGLenum gPrimitiveType2GLMode[] = {
1952 GR_GL_TRIANGLES, 2146 GR_GL_TRIANGLES,
1953 GR_GL_TRIANGLE_STRIP, 2147 GR_GL_TRIANGLE_STRIP,
1954 GR_GL_TRIANGLE_FAN, 2148 GR_GL_TRIANGLE_FAN,
1955 GR_GL_POINTS, 2149 GR_GL_POINTS,
1956 GR_GL_LINES, 2150 GR_GL_LINES,
1957 GR_GL_LINE_STRIP 2151 GR_GL_LINE_STRIP
1958 }; 2152 };
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
2280 GrTextureParams::FilterMode filterMode = params.filterMode(); 2474 GrTextureParams::FilterMode filterMode = params.filterMode();
2281 2475
2282 if (GrTextureParams::kMipMap_FilterMode == filterMode) { 2476 if (GrTextureParams::kMipMap_FilterMode == filterMode) {
2283 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) { 2477 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) {
2284 filterMode = GrTextureParams::kBilerp_FilterMode; 2478 filterMode = GrTextureParams::kBilerp_FilterMode;
2285 } 2479 }
2286 } 2480 }
2287 2481
2288 newTexParams.fMinFilter = glMinFilterModes[filterMode]; 2482 newTexParams.fMinFilter = glMinFilterModes[filterMode];
2289 newTexParams.fMagFilter = glMagFilterModes[filterMode]; 2483 newTexParams.fMagFilter = glMagFilterModes[filterMode];
2290
2291 if (GrTextureParams::kMipMap_FilterMode == filterMode &&
2292 texture->texturePriv().mipMapsAreDirty()) {
2293 GL_CALL(GenerateMipmap(GR_GL_TEXTURE_2D));
2294 texture->texturePriv().dirtyMipMaps(false);
2295 }
2296
2297 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); 2484 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX());
2298 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); 2485 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY());
2299 memcpy(newTexParams.fSwizzleRGBA, 2486 memcpy(newTexParams.fSwizzleRGBA,
2300 GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps ()), 2487 GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps ()),
2301 sizeof(newTexParams.fSwizzleRGBA)); 2488 sizeof(newTexParams.fSwizzleRGBA));
2302 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { 2489 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) {
2303 this->setTextureUnit(unitIdx); 2490 this->setTextureUnit(unitIdx);
2304 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, 2491 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2305 GR_GL_TEXTURE_MAG_FILTER, 2492 GR_GL_TEXTURE_MAG_FILTER,
2306 newTexParams.fMagFilter)); 2493 newTexParams.fMagFilter));
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 *internalFormat = GR_GL_ALPHA; 2745 *internalFormat = GR_GL_ALPHA;
2559 } 2746 }
2560 *externalFormat = GR_GL_ALPHA; 2747 *externalFormat = GR_GL_ALPHA;
2561 } 2748 }
2562 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { 2749 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) {
2563 *externalType = GR_GL_HALF_FLOAT; 2750 *externalType = GR_GL_HALF_FLOAT;
2564 } else { 2751 } else {
2565 *externalType = GR_GL_HALF_FLOAT_OES; 2752 *externalType = GR_GL_HALF_FLOAT_OES;
2566 } 2753 }
2567 break; 2754 break;
2568 2755
2569 case kRGBA_half_GrPixelConfig: 2756 case kRGBA_half_GrPixelConfig:
2570 *internalFormat = GR_GL_RGBA16F; 2757 *internalFormat = GR_GL_RGBA16F;
2571 *externalFormat = GR_GL_RGBA; 2758 *externalFormat = GR_GL_RGBA;
2572 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { 2759 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) {
2573 *externalType = GR_GL_HALF_FLOAT; 2760 *externalType = GR_GL_HALF_FLOAT;
2574 } else { 2761 } else {
2575 *externalType = GR_GL_HALF_FLOAT_OES; 2762 *externalType = GR_GL_HALF_FLOAT_OES;
2576 } 2763 }
2577 break; 2764 break;
2578 2765
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2753 } 2940 }
2754 2941
2755 bool GrGLGpu::onCopySurface(GrSurface* dst, 2942 bool GrGLGpu::onCopySurface(GrSurface* dst,
2756 GrSurface* src, 2943 GrSurface* src,
2757 const SkIRect& srcRect, 2944 const SkIRect& srcRect,
2758 const SkIPoint& dstPoint) { 2945 const SkIPoint& dstPoint) {
2759 if (src->asTexture() && dst->asRenderTarget()) { 2946 if (src->asTexture() && dst->asRenderTarget()) {
2760 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); 2947 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
2761 return true; 2948 return true;
2762 } 2949 }
2763 2950
2764 if (can_copy_texsubimage(dst, src, this)) { 2951 if (can_copy_texsubimage(dst, src, this)) {
2765 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); 2952 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
2766 return true; 2953 return true;
2767 } 2954 }
2768 2955
2769 if (can_blit_framebuffer(dst, src, this)) { 2956 if (can_blit_framebuffer(dst, src, this)) {
2770 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); 2957 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
2771 } 2958 }
2772 2959
2773 return false; 2960 return false;
2774 } 2961 }
2775 2962
2776 2963
2777 void GrGLGpu::createCopyProgram() { 2964 void GrGLGpu::createCopyProgram() {
2778 const char* version = GrGLGetGLSLVersionDecl(this->ctxInfo()); 2965 const char* version = GrGLGetGLSLVersionDecl(this->ctxInfo());
2779 2966
2780 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T ypeModifier); 2967 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T ypeModifier);
2781 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, 2968 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
2782 GrShaderVar::kUniform_TypeModifier); 2969 GrShaderVar::kUniform_TypeModifier);
2783 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform _TypeModifier); 2970 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform _TypeModifier);
2784 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo rm_TypeModifier); 2971 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo rm_TypeModifier);
2785 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying Out_TypeModifier); 2972 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying Out_TypeModifier);
2786 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier); 2973 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier);
2787 2974
2788 SkString vshaderTxt(version); 2975 SkString vshaderTxt(version);
2789 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt); 2976 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt);
2790 vshaderTxt.append(";"); 2977 vshaderTxt.append(";");
2791 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt); 2978 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt);
2792 vshaderTxt.append(";"); 2979 vshaderTxt.append(";");
2793 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt); 2980 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt);
2794 vshaderTxt.append(";"); 2981 vshaderTxt.append(";");
2795 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt); 2982 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt);
2796 vshaderTxt.append(";"); 2983 vshaderTxt.append(";");
2797 2984
2798 vshaderTxt.append( 2985 vshaderTxt.append(
2799 "// Copy Program VS\n" 2986 "// Copy Program VS\n"
2800 "void main() {" 2987 "void main() {"
2801 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" 2988 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
2802 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" 2989 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
2803 " gl_Position.zw = vec2(0, 1);" 2990 " gl_Position.zw = vec2(0, 1);"
2804 "}" 2991 "}"
2805 ); 2992 );
2806 2993
2807 SkString fshaderTxt(version); 2994 SkString fshaderTxt(version);
(...skipping 13 matching lines...) Expand all
2821 fsOutName = "gl_FragColor"; 3008 fsOutName = "gl_FragColor";
2822 } 3009 }
2823 fshaderTxt.appendf( 3010 fshaderTxt.appendf(
2824 "// Copy Program FS\n" 3011 "// Copy Program FS\n"
2825 "void main() {" 3012 "void main() {"
2826 " %s = %s(u_texture, v_texCoord);" 3013 " %s = %s(u_texture, v_texCoord);"
2827 "}", 3014 "}",
2828 fsOutName, 3015 fsOutName,
2829 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) 3016 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration())
2830 ); 3017 );
2831 3018
2832 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); 3019 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram());
2833 const char* str; 3020 const char* str;
2834 GrGLint length; 3021 GrGLint length;
2835 3022
2836 str = vshaderTxt.c_str(); 3023 str = vshaderTxt.c_str();
2837 length = SkToInt(vshaderTxt.size()); 3024 length = SkToInt(vshaderTxt.size());
2838 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram, 3025 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram,
2839 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats); 3026 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats);
2840 3027
2841 str = fshaderTxt.c_str(); 3028 str = fshaderTxt.c_str();
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
3160 this->setVertexArrayID(gpu, 0); 3347 this->setVertexArrayID(gpu, 0);
3161 } 3348 }
3162 int attrCount = gpu->glCaps().maxVertexAttributes(); 3349 int attrCount = gpu->glCaps().maxVertexAttributes();
3163 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3350 if (fDefaultVertexArrayAttribState.count() != attrCount) {
3164 fDefaultVertexArrayAttribState.resize(attrCount); 3351 fDefaultVertexArrayAttribState.resize(attrCount);
3165 } 3352 }
3166 attribState = &fDefaultVertexArrayAttribState; 3353 attribState = &fDefaultVertexArrayAttribState;
3167 } 3354 }
3168 return attribState; 3355 return attribState;
3169 } 3356 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698