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