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" |
| 11 #include "GrGLStencilAttachment.h" | 11 #include "GrGLStencilAttachment.h" |
| 12 #include "GrGLTextureRenderTarget.h" | 12 #include "GrGLTextureRenderTarget.h" |
| 13 #include "GrGpuResourcePriv.h" | 13 #include "GrGpuResourcePriv.h" |
| 14 #include "GrPipeline.h" | 14 #include "GrPipeline.h" |
| 15 #include "GrRenderTargetPriv.h" | 15 #include "GrRenderTargetPriv.h" |
| 16 #include "GrSurfacePriv.h" | 16 #include "GrSurfacePriv.h" |
| 17 #include "GrTexturePriv.h" | 17 #include "GrTexturePriv.h" |
| 18 #include "GrTypes.h" | 18 #include "GrTypes.h" |
| 19 #include "GrVertices.h" | 19 #include "GrVertices.h" |
| 20 #include "builders/GrGLShaderStringBuilder.h" | 20 #include "builders/GrGLShaderStringBuilder.h" |
| 21 #include "glsl/GrGLSL.h" | 21 #include "glsl/GrGLSL.h" |
| 22 #include "glsl/GrGLSLCaps.h" | 22 #include "glsl/GrGLSLCaps.h" |
| 23 #include "SkMipMapLevel.h" | |
| 23 #include "SkStrokeRec.h" | 24 #include "SkStrokeRec.h" |
| 24 #include "SkTemplates.h" | 25 #include "SkTemplates.h" |
| 26 #include "SkTypes.h" | |
| 25 | 27 |
| 26 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) | 28 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) |
| 27 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) | 29 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) |
| 28 | 30 |
| 29 #define SKIP_CACHE_CHECK true | 31 #define SKIP_CACHE_CHECK true |
| 30 | 32 |
| 31 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR | 33 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR |
| 32 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) | 34 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) |
| 33 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) | 35 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) |
| 34 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) | 36 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) |
| 35 #else | 37 #else |
| 36 #define CLEAR_ERROR_BEFORE_ALLOC(iface) | 38 #define CLEAR_ERROR_BEFORE_ALLOC(iface) |
| 37 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call) | 39 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call) |
| 38 #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR | 40 #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR |
| 39 #endif | 41 #endif |
| 40 | 42 |
| 43 #if defined(GOOGLE3) | |
| 44 // Stack frame size is limited in GOOGLE3. | |
| 45 typedef SkAutoSMalloc<64 * 128> SkAutoSMallocTexels; | |
| 46 #else | |
| 47 typedef SkAutoSMalloc<128 * 128> SkAutoSMallocTexels; | |
| 48 #endif | |
| 41 | 49 |
| 42 /////////////////////////////////////////////////////////////////////////////// | 50 /////////////////////////////////////////////////////////////////////////////// |
| 43 | 51 |
| 44 | 52 |
| 45 static const GrGLenum gXfermodeEquation2Blend[] = { | 53 static const GrGLenum gXfermodeEquation2Blend[] = { |
| 46 // Basic OpenGL blend equations. | 54 // Basic OpenGL blend equations. |
| 47 GR_GL_FUNC_ADD, | 55 GR_GL_FUNC_ADD, |
| 48 GR_GL_FUNC_SUBTRACT, | 56 GR_GL_FUNC_SUBTRACT, |
| 49 GR_GL_FUNC_REVERSE_SUBTRACT, | 57 GR_GL_FUNC_REVERSE_SUBTRACT, |
| 50 | 58 |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); | 526 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); |
| 519 idDesc.fMSColorRenderbufferID = 0; | 527 idDesc.fMSColorRenderbufferID = 0; |
| 520 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; | 528 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; |
| 521 switch (ownership) { | 529 switch (ownership) { |
| 522 case kAdopt_GrWrapOwnership: | 530 case kAdopt_GrWrapOwnership: |
| 523 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; | 531 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; |
| 524 break; | 532 break; |
| 525 case kBorrow_GrWrapOwnership: | 533 case kBorrow_GrWrapOwnership: |
| 526 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; | 534 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; |
| 527 break; | 535 break; |
| 528 } | 536 } |
| 529 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; | 537 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; |
| 530 | 538 |
| 531 GrSurfaceDesc desc; | 539 GrSurfaceDesc desc; |
| 532 desc.fConfig = wrapDesc.fConfig; | 540 desc.fConfig = wrapDesc.fConfig; |
| 533 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; | 541 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; |
| 534 desc.fWidth = wrapDesc.fWidth; | 542 desc.fWidth = wrapDesc.fWidth; |
| 535 desc.fHeight = wrapDesc.fHeight; | 543 desc.fHeight = wrapDesc.fHeight; |
| 536 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); | 544 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); |
| 537 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); | 545 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); |
| 538 | 546 |
| 539 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits); | 547 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits); |
| 540 } | 548 } |
| 541 | 549 |
| 542 //////////////////////////////////////////////////////////////////////////////// | 550 //////////////////////////////////////////////////////////////////////////////// |
| 543 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, | 551 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, |
| 544 size_t rowBytes, GrPixelConfig srcConfig, | 552 GrPixelConfig srcConfig, |
| 545 DrawPreference* drawPreference, | 553 DrawPreference* drawPreference, |
| 546 WritePixelTempDrawInfo* tempDrawInfo) { | 554 WritePixelTempDrawInfo* tempDrawInfo) { |
| 547 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { | 555 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { |
| 548 return false; | 556 return false; |
| 549 } | 557 } |
| 550 | 558 |
| 551 // This subclass only allows writes to textures. If the dst is not a texture we have to draw | 559 // This subclass only allows writes to textures. If the dst is not a texture we have to draw |
| 552 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. | 560 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. |
| 553 if (!dstSurface->asTexture()) { | 561 if (!dstSurface->asTexture()) { |
| 554 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); | 562 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 619 // Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textu res | 627 // Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textu res |
| 620 if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) { | 628 if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) { |
| 621 return false; | 629 return false; |
| 622 } | 630 } |
| 623 | 631 |
| 624 return true; | 632 return true; |
| 625 } | 633 } |
| 626 | 634 |
| 627 bool GrGLGpu::onWritePixels(GrSurface* surface, | 635 bool GrGLGpu::onWritePixels(GrSurface* surface, |
| 628 int left, int top, int width, int height, | 636 int left, int top, int width, int height, |
| 629 GrPixelConfig config, const void* buffer, | 637 GrPixelConfig config, |
| 630 size_t rowBytes) { | 638 const SkTArray<SkMipMapLevel>& texels) { |
| 631 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); | 639 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); |
| 632 | 640 |
| 633 if (!check_write_and_transfer_input(glTex, surface, config)) { | 641 if (!check_write_and_transfer_input(glTex, surface, config)) { |
| 634 return false; | 642 return false; |
| 635 } | 643 } |
| 636 | 644 |
| 637 this->setScratchTextureUnit(); | 645 this->setScratchTextureUnit(); |
| 638 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); | 646 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); |
| 639 | 647 |
| 640 bool success = false; | 648 bool success = false; |
| 641 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { | 649 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { |
| 642 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() | 650 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() |
| 643 SkASSERT(config == glTex->desc().fConfig); | 651 SkASSERT(config == glTex->desc().fConfig); |
| 644 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), buffer, | 652 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), texels, |
| 645 kWrite_UploadType, left, top, wi dth, height); | 653 kWrite_UploadType, left, top, wi dth, height); |
| 646 } else { | 654 } else { |
| 647 success = this->uploadTexData(glTex->desc(), glTex->target(), kWrite_Upl oadType, | 655 success = this->uploadTexData(glTex->desc(), glTex->target(), kWrite_Upl oadType, |
| 648 left, top, width, height, config, buffer, rowBytes); | 656 left, top, width, height, config, texels); |
| 649 } | 657 } |
| 650 | 658 |
| 651 if (success) { | 659 return success; |
| 652 glTex->texturePriv().dirtyMipMaps(true); | |
| 653 return true; | |
| 654 } | |
| 655 | |
| 656 return false; | |
| 657 } | 660 } |
| 658 | 661 |
| 659 bool GrGLGpu::onTransferPixels(GrSurface* surface, | 662 bool GrGLGpu::onTransferPixels(GrSurface* surface, |
| 660 int left, int top, int width, int height, | 663 int left, int top, int width, int height, |
| 661 GrPixelConfig config, GrTransferBuffer* buffer, | 664 GrPixelConfig config, GrTransferBuffer* buffer, |
| 662 size_t offset, size_t rowBytes) { | 665 size_t offset, size_t rowBytes) { |
| 663 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); | 666 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); |
| 664 | 667 |
| 665 if (!check_write_and_transfer_input(glTex, surface, config)) { | 668 if (!check_write_and_transfer_input(glTex, surface, config)) { |
| 666 return false; | 669 return false; |
| 667 } | 670 } |
| 668 | 671 |
| 669 // For the moment, can't transfer compressed data | 672 // For the moment, can't transfer compressed data |
| 670 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { | 673 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { |
| 671 return false; | 674 return false; |
| 672 } | 675 } |
| 673 | 676 |
| 674 this->setScratchTextureUnit(); | 677 this->setScratchTextureUnit(); |
| 675 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); | 678 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); |
| 676 | 679 |
| 677 SkASSERT(!buffer->isMapped()); | 680 SkASSERT(!buffer->isMapped()); |
| 678 GrGLTransferBuffer* glBuffer = reinterpret_cast<GrGLTransferBuffer*>(buffer) ; | 681 GrGLTransferBuffer* glBuffer = reinterpret_cast<GrGLTransferBuffer*>(buffer) ; |
| 679 // bind the transfer buffer | 682 // bind the transfer buffer |
| 680 SkASSERT(GR_GL_PIXEL_UNPACK_BUFFER == glBuffer->bufferType() || | 683 SkASSERT(GR_GL_PIXEL_UNPACK_BUFFER == glBuffer->bufferType() || |
| 681 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == glBuffer->bufferType ()); | 684 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == glBuffer->bufferType ()); |
| 682 GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID())); | 685 GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID())); |
| 683 | 686 |
| 684 bool success = false; | 687 bool success = false; |
| 688 SkMipMapLevel mipLevel(buffer, rowBytes, width, height); | |
| 689 SkSTArray<1, SkMipMapLevel> texels; | |
| 690 texels.push_back(mipLevel); | |
| 685 success = this->uploadTexData(glTex->desc(), glTex->target(), kTransfer_Uplo adType, | 691 success = this->uploadTexData(glTex->desc(), glTex->target(), kTransfer_Uplo adType, |
| 686 left, top, width, height, config, buffer, rowB ytes); | 692 left, top, width, height, config, texels); |
| 687 | 693 |
| 688 if (success) { | 694 if (success) { |
| 689 glTex->texturePriv().dirtyMipMaps(true); | 695 glTex->texturePriv().dirtyMipMaps(true); |
| 690 return true; | 696 return true; |
| 691 } | 697 } |
| 692 | 698 |
| 693 return false; | 699 return false; |
| 694 } | 700 } |
| 695 | 701 |
| 696 // For GL_[UN]PACK_ALIGNMENT. | 702 // For GL_[UN]PACK_ALIGNMENT. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 716 | 722 |
| 717 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, | 723 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, |
| 718 const GrGLInterface* interface) { | 724 const GrGLInterface* interface) { |
| 719 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { | 725 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { |
| 720 return GR_GL_GET_ERROR(interface); | 726 return GR_GL_GET_ERROR(interface); |
| 721 } else { | 727 } else { |
| 722 return CHECK_ALLOC_ERROR(interface); | 728 return CHECK_ALLOC_ERROR(interface); |
| 723 } | 729 } |
| 724 } | 730 } |
| 725 | 731 |
| 732 /** | |
| 733 * Creates storage space for the texture and fills it with texels. | |
| 734 * | |
| 735 * @param desc The surface descriptor for the texture being created. | |
| 736 * @param interface The GL interface in use. | |
| 737 * @param useTexStorage The result of a call to can_use_tex_storage(). | |
| 738 * @param internalFormat The data format used for the internal storage of the te xture. | |
| 739 * @param externalFormat The data format used for the external storage of the te xture. | |
| 740 * @param externalType The type of the data used for the external storage of t he texture. | |
| 741 * @param texels The texel data of the texture being created. | |
| 742 * @param succeeded Set to true if allocating and populating the texture co mpleted | |
| 743 * without error. | |
| 744 */ | |
| 745 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc , | |
| 746 const GrGLInterface& inte rface, | |
| 747 GrGLenum target, | |
| 748 GrGLenum internalFormat, | |
| 749 GrGLenum externalFormat, | |
| 750 GrGLenum externalType, | |
| 751 const SkTArray<SkMipMapLe vel>& texels, | |
| 752 bool* succeeded) { | |
| 753 CLEAR_ERROR_BEFORE_ALLOC(&interface); | |
| 754 *succeeded = true; | |
| 755 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) { | |
| 756 const void* currentMipData = texels[currentMipLevel].fTexelsOrOffset; | |
| 757 // Even if curremtMipData is nullptr, continue to call TexImage2D. | |
| 758 // This will allocate texture memory which we can later populate. | |
| 759 GL_ALLOC_CALL(&interface, | |
| 760 TexImage2D(target, | |
| 761 currentMipLevel, | |
| 762 internalFormat, | |
| 763 texels[currentMipLevel].fWidth, | |
| 764 texels[currentMipLevel].fHeight, | |
| 765 0, // border | |
| 766 externalFormat, externalType, | |
| 767 currentMipData)); | |
| 768 GrGLenum error = check_alloc_error(desc, &interface); | |
| 769 if (error != GR_GL_NO_ERROR) { | |
| 770 *succeeded = false; | |
| 771 break; | |
| 772 } | |
| 773 } | |
| 774 } | |
| 775 | |
| 776 /** | |
| 777 * Creates storage space for the texture and fills it with texels. | |
| 778 * | |
| 779 * @param desc The surface descriptor for the texture being created. | |
| 780 * @param interface The GL interface in use. | |
| 781 * @param useTexStorage The result of a call to can_use_tex_storage(). | |
| 782 * @param internalFormat The data format used for the internal storage of the te xture. | |
| 783 * @param texels The texel data of the texture being created. | |
| 784 */ | |
| 785 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc, | |
| 786 const GrGLInterface& interf ace, | |
| 787 GrGLenum target, GrGLenum i nternalFormat, | |
| 788 const SkTArray<SkMipMapLeve l>& texels) { | |
| 789 CLEAR_ERROR_BEFORE_ALLOC(&interface); | |
| 790 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) { | |
| 791 int width = texels[currentMipLevel].fWidth; | |
| 792 int height = texels[currentMipLevel].fHeight; | |
| 793 | |
| 794 // Make sure that the width and height that we pass to OpenGL | |
| 795 // is a multiple of the block size. | |
| 796 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height ); | |
| 797 | |
| 798 GL_ALLOC_CALL(&interface, | |
| 799 CompressedTexImage2D(target, | |
| 800 currentMipLevel, | |
| 801 internalFormat, | |
| 802 width, | |
| 803 height, | |
| 804 0, // border | |
| 805 SkToInt(dataSize), | |
| 806 texels[currentMipLevel].fTexelsOrOffs et)); | |
| 807 | |
| 808 GrGLenum error = check_alloc_error(desc, &interface); | |
| 809 if (error != GR_GL_NO_ERROR) { | |
| 810 return false; | |
| 811 } | |
| 812 } | |
| 813 | |
| 814 return true; | |
| 815 } | |
| 816 | |
| 817 /** | |
| 818 * After a texture is created, any state which was altered during its creation | |
| 819 * needs to be restored. | |
| 820 * | |
| 821 * @param interface The GL interface to use. | |
| 822 * @param caps The capabilities of the GL device. | |
| 823 * @param restoreGLRowLength Should the row length unpacking be restored? | |
| 824 * @param glFlipY Did GL flip the texture vertically? | |
| 825 */ | |
| 826 static void restore_pixelstore_state(const GrGLInterface& interface, const GrGLC aps& caps, | |
| 827 bool restoreGLRowLength, bool glFlipY) { | |
| 828 if (restoreGLRowLength) { | |
| 829 SkASSERT(caps.unpackRowLengthSupport()); | |
| 830 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | |
| 831 } | |
| 832 if (glFlipY) { | |
| 833 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | |
| 834 } | |
| 835 } | |
| 836 | |
| 726 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | 837 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, |
| 727 GrGLenum target, | 838 GrGLenum target, |
| 728 UploadType uploadType, | 839 UploadType uploadType, |
| 729 int left, int top, int width, int height, | 840 int left, int top, int width, int height, |
| 730 GrPixelConfig dataConfig, | 841 GrPixelConfig dataConfig, |
| 731 const void* dataOrOffset, | 842 const SkTArray<SkMipMapLevel>& texels) { |
| 732 size_t rowBytes) { | |
| 733 SkASSERT(dataOrOffset || kNewTexture_UploadType == uploadType || | |
| 734 kTransfer_UploadType == uploadType); | |
| 735 | |
| 736 // If we're uploading compressed data then we should be using uploadCompress edTexData | 843 // If we're uploading compressed data then we should be using uploadCompress edTexData |
| 737 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | 844 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); |
| 738 | 845 |
| 739 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); | 846 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); |
| 740 | 847 |
| 848 // texels is const. | |
| 849 // But we may need to flip the texture vertically to prepare it. | |
| 850 // Rather than flip in place and alter the incoming data, | |
| 851 // we allocate a new buffer to flip into. | |
| 852 // This means we need to make a non-const shallow copy of texels. | |
| 853 SkTArray<SkMipMapLevel> texelsShallowCopy(texels); | |
| 854 | |
| 855 for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0; | |
| 856 currentMipLevel--) { | |
| 857 SkASSERT(texelsShallowCopy[currentMipLevel].fTexelsOrOffset || | |
| 858 kNewTexture_UploadType == uploadType || kTransfer_UploadType == uploadType); | |
| 859 } | |
| 860 | |
| 861 | |
| 862 const GrGLInterface* interface = this->glInterface(); | |
| 863 const GrGLCaps& caps = this->glCaps(); | |
| 864 | |
| 741 size_t bpp = GrBytesPerPixel(dataConfig); | 865 size_t bpp = GrBytesPerPixel(dataConfig); |
| 742 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, & left, &top, | 866 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c urrentMipLevel++) { |
| 743 &width, &height, &dataOrOffset, & rowBytes)) { | 867 if (texelsShallowCopy[currentMipLevel].fTexelsOrOffset == nullptr) { |
| 744 return false; | 868 continue; |
| 869 } | |
| 870 | |
| 871 if (texelsShallowCopy[currentMipLevel].fHeight > SK_MaxS32 || | |
| 872 texelsShallowCopy[currentMipLevel].fWidth > SK_MaxS32) { | |
| 873 return false; | |
| 874 } | |
| 875 int currentMipHeight = texelsShallowCopy[currentMipLevel].fHeight; | |
| 876 int currentMipWidth = texelsShallowCopy[currentMipLevel].fWidth; | |
| 877 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp p, &left, &top, | |
| 878 ¤tMipWidth, | |
| 879 ¤tMipHeight, | |
| 880 &texelsShallowCopy[currentMipLeve l].fTexelsOrOffset, | |
| 881 &texelsShallowCopy[currentMipLeve l].fRowBytes)) { | |
| 882 return false; | |
| 883 } | |
| 884 if (currentMipWidth < 0 || currentMipHeight < 0) { | |
| 885 return false; | |
| 886 } | |
| 887 texelsShallowCopy[currentMipLevel].fWidth = currentMipWidth; | |
| 888 texelsShallowCopy[currentMipLevel].fHeight = currentMipHeight; | |
| 745 } | 889 } |
| 746 size_t trimRowBytes = width * bpp; | |
| 747 | |
| 748 // in case we need a temporary, trimmed copy of the src pixels | |
| 749 #if defined(GOOGLE3) | |
| 750 // Stack frame size is limited in GOOGLE3. | |
| 751 SkAutoSMalloc<64 * 128> tempStorage; | |
| 752 #else | |
| 753 SkAutoSMalloc<128 * 128> tempStorage; | |
| 754 #endif | |
| 755 | 890 |
| 756 // Internal format comes from the texture desc. | 891 // Internal format comes from the texture desc. |
| 757 GrGLenum internalFormat; | 892 GrGLenum internalFormat; |
| 758 // External format and type come from the upload data. | 893 // External format and type come from the upload data. |
| 759 GrGLenum externalFormat; | 894 GrGLenum externalFormat; |
| 760 GrGLenum externalType; | 895 GrGLenum externalType; |
| 761 if (!this->glCaps().getTexImageFormats(desc.fConfig, dataConfig, &internalFo rmat, | 896 if (!this->glCaps().getTexImageFormats(desc.fConfig, dataConfig, &internalFo rmat, |
| 762 &externalFormat, &externalType)) { | 897 &externalFormat, &externalType)) { |
| 763 return false; | 898 return false; |
| 764 } | 899 } |
| 765 /* | 900 /* |
| 766 * Check whether to allocate a temporary buffer for flipping y or | 901 * Check whether to allocate a temporary buffer for flipping y or |
| 767 * because our srcData has extra bytes past each row. If so, we need | 902 * because our srcData has extra bytes past each row. If so, we need |
| 768 * to trim those off here, since GL ES may not let us specify | 903 * to trim those off here, since GL ES may not let us specify |
| 769 * GL_UNPACK_ROW_LENGTH. | 904 * GL_UNPACK_ROW_LENGTH. |
| 770 */ | 905 */ |
| 771 bool restoreGLRowLength = false; | 906 bool restoreGLRowLength = false; |
| 772 bool swFlipY = false; | 907 bool swFlipY = false; |
| 773 bool glFlipY = false; | 908 bool glFlipY = false; |
| 774 if (dataOrOffset) { | 909 |
| 775 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 910 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
| 776 if (this->glCaps().unpackFlipYSupport()) { | 911 if (caps.unpackFlipYSupport()) { |
| 777 glFlipY = true; | 912 glFlipY = true; |
| 778 } else { | 913 } else { |
| 779 swFlipY = true; | 914 swFlipY = true; |
| 780 } | |
| 781 } | 915 } |
| 782 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { | 916 } |
| 917 | |
| 918 // in case we need a temporary, trimmed copy of the src pixels | |
| 919 SkAutoSMallocTexels tempStorage; | |
| 920 | |
| 921 // find the combined size of all the mip levels and the relative offset of | |
| 922 // each into the collective buffer | |
| 923 size_t combined_buffer_size = 0; | |
| 924 SkTArray<size_t> individual_mip_offsets(texelsShallowCopy.count()); | |
| 925 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c urrentMipLevel++) { | |
| 926 const size_t trimmedSize = texels[currentMipLevel].fWidth * bpp * | |
| 927 texelsShallowCopy[currentMipLevel].fHeight; | |
| 928 individual_mip_offsets.push_back(combined_buffer_size); | |
| 929 combined_buffer_size += trimmedSize; | |
| 930 } | |
| 931 char* buffer = (char*)tempStorage.reset(combined_buffer_size); | |
| 932 | |
| 933 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c urrentMipLevel++) { | |
| 934 if (texelsShallowCopy[currentMipLevel].fTexelsOrOffset == nullptr) { | |
| 935 continue; | |
| 936 } | |
| 937 | |
| 938 const size_t trimRowBytes = texelsShallowCopy[currentMipLevel].fWidth * bpp; | |
| 939 | |
| 940 /* | |
| 941 * check whether to allocate a temporary buffer for flipping y or | |
| 942 * because our srcData has extra bytes past each row. If so, we need | |
| 943 * to trim those off here, since GL ES may not let us specify | |
| 944 * GL_UNPACK_ROW_LENGTH. | |
| 945 */ | |
| 946 restoreGLRowLength = false; | |
| 947 | |
| 948 const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes; | |
| 949 if (caps.unpackRowLengthSupport() && !swFlipY) { | |
| 783 // can't use this for flipping, only non-neg values allowed. :( | 950 // can't use this for flipping, only non-neg values allowed. :( |
| 784 if (rowBytes != trimRowBytes) { | 951 if (rowBytes != trimRowBytes) { |
| 785 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); | 952 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); |
| 786 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); | 953 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLe ngth)); |
| 787 restoreGLRowLength = true; | 954 restoreGLRowLength = true; |
| 788 } | 955 } |
| 789 } else if (kTransfer_UploadType != uploadType) { | 956 } else if (kTransfer_UploadType != uploadType) { |
| 790 if (trimRowBytes != rowBytes || swFlipY) { | 957 if (trimRowBytes != rowBytes || swFlipY) { |
| 958 const int height = texelsShallowCopy[currentMipLevel].fHeight; | |
| 791 // copy data into our new storage, skipping the trailing bytes | 959 // copy data into our new storage, skipping the trailing bytes |
| 792 size_t trimSize = height * trimRowBytes; | 960 const char* src = (const char*)texelsShallowCopy[currentMipLevel ].fTexelsOrOffset; |
| 793 const char* src = (const char*)dataOrOffset; | 961 if (swFlipY && height >= 1) { |
| 794 if (swFlipY) { | |
| 795 src += (height - 1) * rowBytes; | 962 src += (height - 1) * rowBytes; |
| 796 } | 963 } |
| 797 char* dst = (char*)tempStorage.reset(trimSize); | 964 char* dst = buffer + individual_mip_offsets[currentMipLevel]; |
| 798 for (int y = 0; y < height; y++) { | 965 for (int y = 0; y < height; y++) { |
| 799 memcpy(dst, src, trimRowBytes); | 966 memcpy(dst, src, trimRowBytes); |
| 800 if (swFlipY) { | 967 if (swFlipY) { |
| 801 src -= rowBytes; | 968 src -= rowBytes; |
| 802 } else { | 969 } else { |
| 803 src += rowBytes; | 970 src += rowBytes; |
| 804 } | 971 } |
| 805 dst += trimRowBytes; | 972 dst += trimRowBytes; |
| 806 } | 973 } |
| 807 // now point data to our copied version | 974 // now point data to our copied version |
| 808 dataOrOffset = tempStorage.get(); | 975 texelsShallowCopy[currentMipLevel] = |
| 976 SkMipMapLevel(buffer + individual_mip_offsets[currentMipLeve l], | |
| 977 trimRowBytes, | |
| 978 texelsShallowCopy[currentMipLevel].fWidth, | |
| 979 texelsShallowCopy[currentMipLevel].fHeight); | |
| 809 } | 980 } |
| 810 } else { | 981 } else { |
| 811 return false; | 982 return false; |
| 812 } | 983 } |
| 813 if (glFlipY) { | 984 if (glFlipY) { |
| 814 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); | 985 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); |
| 815 } | 986 } |
| 816 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(dataConfig) )); | 987 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, |
| 988 config_alignment(desc.fConfig))); | |
| 817 } | 989 } |
| 990 | |
| 818 bool succeeded = true; | 991 bool succeeded = true; |
| 819 if (kNewTexture_UploadType == uploadType) { | 992 if (kNewTexture_UploadType == uploadType && |
| 820 if (dataOrOffset && | 993 0 == left && 0 == top && |
| 821 !(0 == left && 0 == top && desc.fWidth == width && desc.fHeight == h eight)) { | 994 desc.fWidth == width && desc.fHeight == height) { |
| 822 succeeded = false; | 995 allocate_and_populate_uncompressed_texture(desc, *interface, target, int ernalFormat, |
| 823 } else { | 996 externalFormat, externalType, texelsShallowCopy, |
| 824 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 997 &succeeded); |
| 825 GL_ALLOC_CALL(this->glInterface(), TexImage2D(target, 0, internalFor mat, desc.fWidth, | |
| 826 desc.fHeight, 0, exter nalFormat, | |
| 827 externalType, dataOrOf fset)); | |
| 828 GrGLenum error = check_alloc_error(desc, this->glInterface()); | |
| 829 if (error != GR_GL_NO_ERROR) { | |
| 830 succeeded = false; | |
| 831 } | |
| 832 } | |
| 833 } else { | 998 } else { |
| 834 if (swFlipY || glFlipY) { | 999 if (swFlipY || glFlipY) { |
| 835 top = desc.fHeight - (top + height); | 1000 top = desc.fHeight - (top + height); |
| 836 } | 1001 } |
| 837 GL_CALL(TexSubImage2D(target, | 1002 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count( ); |
| 838 0, // level | 1003 currentMipLevel++) { |
| 839 left, top, | 1004 if (texelsShallowCopy[currentMipLevel].fTexelsOrOffset == nullptr) { |
| 840 width, height, | 1005 continue; |
| 841 externalFormat, externalType, dataOrOffset)); | 1006 } |
| 1007 | |
| 1008 GL_CALL(TexSubImage2D(target, | |
| 1009 currentMipLevel, | |
| 1010 left, top, | |
| 1011 texelsShallowCopy[currentMipLevel].fWidth, | |
| 1012 texelsShallowCopy[currentMipLevel].fHeight, | |
| 1013 externalFormat, externalType, | |
| 1014 texelsShallowCopy[currentMipLevel].fTexelsOrOf fset)); | |
| 1015 } | |
| 842 } | 1016 } |
| 843 | 1017 |
| 844 if (restoreGLRowLength) { | 1018 restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY); |
| 845 SkASSERT(this->glCaps().unpackRowLengthSupport()); | 1019 |
| 846 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | |
| 847 } | |
| 848 if (glFlipY) { | |
| 849 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | |
| 850 } | |
| 851 return succeeded; | 1020 return succeeded; |
| 852 } | 1021 } |
| 853 | 1022 |
| 854 // TODO: This function is using a lot of wonky semantics like, if width == -1 | 1023 // TODO: This function is using a lot of wonky semantics like, if width == -1 |
| 855 // then set width = desc.fWdith ... blah. A better way to do it might be to | 1024 // then set width = desc.fWdith ... blah. A better way to do it might be to |
| 856 // create a CompressedTexData struct that takes a desc/ptr and figures out | 1025 // create a CompressedTexData struct that takes a desc/ptr and figures out |
| 857 // the proper upload semantics. Then users can construct this function how they | 1026 // the proper upload semantics. Then users can construct this function how they |
| 858 // see fit if they want to go against the "standard" way to do it. | 1027 // see fit if they want to go against the "standard" way to do it. |
| 859 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, | 1028 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, |
| 860 GrGLenum target, | 1029 GrGLenum target, |
| 861 const void* data, | 1030 const SkTArray<SkMipMapLevel>& texels, |
| 862 UploadType uploadType, | 1031 UploadType uploadType, |
| 863 int left, int top, int width, int height) { | 1032 int left, int top, int width, int height) { |
| 864 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); | 1033 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); |
| 865 SkASSERT(kTransfer_UploadType != uploadType && | 1034 SkASSERT(kTransfer_UploadType != uploadType && |
| 866 (data || kNewTexture_UploadType != uploadType)); | 1035 (texels[0].fTexelsOrOffset || kNewTexture_UploadType != uploadType) ); |
| 867 | 1036 |
| 868 // No support for software flip y, yet... | 1037 // No support for software flip y, yet... |
| 869 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); | 1038 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); |
| 870 | 1039 |
| 1040 const GrGLInterface* interface = this->glInterface(); | |
| 1041 const GrGLCaps& caps = this->glCaps(); | |
| 1042 | |
| 871 if (-1 == width) { | 1043 if (-1 == width) { |
| 872 width = desc.fWidth; | 1044 width = desc.fWidth; |
| 873 } | 1045 } |
| 874 #ifdef SK_DEBUG | 1046 #ifdef SK_DEBUG |
| 875 else { | 1047 else { |
| 876 SkASSERT(width <= desc.fWidth); | 1048 SkASSERT(width <= desc.fWidth); |
| 877 } | 1049 } |
| 878 #endif | 1050 #endif |
| 879 | 1051 |
| 880 if (-1 == height) { | 1052 if (-1 == height) { |
| 881 height = desc.fHeight; | 1053 height = desc.fHeight; |
| 882 } | 1054 } |
| 883 #ifdef SK_DEBUG | 1055 #ifdef SK_DEBUG |
| 884 else { | 1056 else { |
| 885 SkASSERT(height <= desc.fHeight); | 1057 SkASSERT(height <= desc.fHeight); |
| 886 } | 1058 } |
| 887 #endif | 1059 #endif |
| 888 | 1060 |
| 889 // Make sure that the width and height that we pass to OpenGL | |
| 890 // is a multiple of the block size. | |
| 891 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height); | |
| 892 | |
| 893 // We only need the internal format for compressed 2D textures. | 1061 // We only need the internal format for compressed 2D textures. |
| 894 GrGLenum internalFormat; | 1062 GrGLenum internalFormat; |
| 895 if (!this->glCaps().getCompressedTexImageFormats(desc.fConfig, &internalForm at)) { | 1063 if (!caps.getCompressedTexImageFormats(desc.fConfig, &internalFormat)) { |
| 896 return false; | 1064 return false; |
| 897 } | 1065 } |
| 898 | 1066 |
| 899 if (kNewTexture_UploadType == uploadType) { | 1067 if (kNewTexture_UploadType == uploadType) { |
| 900 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 1068 return allocate_and_populate_compressed_texture(desc, *interface, target , internalFormat, |
| 901 GL_ALLOC_CALL(this->glInterface(), | 1069 texels); |
| 902 CompressedTexImage2D(target, | |
| 903 0, // level | |
| 904 internalFormat, | |
| 905 width, height, | |
| 906 0, // border | |
| 907 SkToInt(dataSize), | |
| 908 data)); | |
| 909 GrGLenum error = check_alloc_error(desc, this->glInterface()); | |
| 910 if (error != GR_GL_NO_ERROR) { | |
| 911 return false; | |
| 912 } | |
| 913 } else { | 1070 } else { |
| 914 // Paletted textures can't be updated. | 1071 // Paletted textures can't be updated. |
| 915 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { | 1072 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { |
| 916 return false; | 1073 return false; |
| 917 } | 1074 } |
| 918 GL_CALL(CompressedTexSubImage2D(target, | 1075 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) { |
| 919 0, // level | 1076 if (texels[currentMipLevel].fTexelsOrOffset == nullptr) { |
| 920 left, top, | 1077 continue; |
| 921 width, height, | 1078 } |
| 922 internalFormat, | 1079 |
| 923 SkToInt(dataSize), | 1080 // Make sure that the width and height that we pass to OpenGL |
| 924 data)); | 1081 // is a multiple of the block size. |
| 1082 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, | |
| 1083 texels[currentMipLevel] .fWidth, | |
| 1084 texels[currentMipLevel] .fHeight); | |
| 1085 GL_CALL(CompressedTexSubImage2D(target, | |
| 1086 currentMipLevel, | |
| 1087 left, top, | |
| 1088 texels[currentMipLevel].fWidth, | |
| 1089 texels[currentMipLevel].fHeight, | |
| 1090 internalFormat, | |
| 1091 dataSize, | |
| 1092 texels[currentMipLevel].fTexelsOrOff set)); | |
| 1093 } | |
| 925 } | 1094 } |
| 926 | 1095 |
| 927 return true; | 1096 return true; |
| 928 } | 1097 } |
| 929 | 1098 |
| 930 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, | 1099 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, |
| 931 int sampleCount, | 1100 int sampleCount, |
| 932 GrGLenum format, | 1101 GrGLenum format, |
| 933 int width, int height) { | 1102 int width, int height) { |
| 934 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); | 1103 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1078 // SkDEBUGFAIL("null texture"); | 1247 // SkDEBUGFAIL("null texture"); |
| 1079 return nullptr; | 1248 return nullptr; |
| 1080 } | 1249 } |
| 1081 | 1250 |
| 1082 #if 0 && defined(SK_DEBUG) | 1251 #if 0 && defined(SK_DEBUG) |
| 1083 static size_t as_size_t(int x) { | 1252 static size_t as_size_t(int x) { |
| 1084 return x; | 1253 return x; |
| 1085 } | 1254 } |
| 1086 #endif | 1255 #endif |
| 1087 | 1256 |
| 1257 static GrGLTexture::IDDesc generate_gl_texture(const GrGLInterface* interface, | |
| 1258 GrGpuResource::LifeCycle lifeCycl e) { | |
| 1259 GrGLTexture::IDDesc idDesc; | |
| 1260 idDesc.fInfo.fID = 0; | |
| 1261 GR_GL_CALL(interface, GenTextures(1, &idDesc.fInfo.fID)); | |
| 1262 idDesc.fLifeCycle = lifeCycle; | |
| 1263 // We only support GL_TEXTURE_2D at the moment. | |
| 1264 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D; | |
| 1265 return idDesc; | |
| 1266 } | |
| 1267 | |
| 1268 static GrGLTexture::TexParams set_initial_texture_params(const GrGLInterface* in terface, | |
| 1269 GrGLTexture::IDDesc idD esc) { | |
| 1270 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | |
| 1271 // drivers have a bug where an FBO won't be complete if it includes a | |
| 1272 // texture that is not mipmap complete (considering the filter in use). | |
| 1273 GrGLTexture::TexParams initialTexParams; | |
| 1274 // we only set a subset here so invalidate first | |
| 1275 initialTexParams.invalidate(); | |
| 1276 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
| 1277 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
| 1278 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
| 1279 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
| 1280 GR_GL_CALL(interface, TexParameteri(idDesc.fInfo.fTarget, | |
| 1281 GR_GL_TEXTURE_MAG_FILTER, | |
| 1282 initialTexParams.fMagFilter)); | |
| 1283 GR_GL_CALL(interface, TexParameteri(idDesc.fInfo.fTarget, | |
| 1284 GR_GL_TEXTURE_MIN_FILTER, | |
| 1285 initialTexParams.fMinFilter)); | |
| 1286 GR_GL_CALL(interface, TexParameteri(idDesc.fInfo.fTarget, | |
| 1287 GR_GL_TEXTURE_WRAP_S, | |
| 1288 initialTexParams.fWrapS)); | |
| 1289 GR_GL_CALL(interface, TexParameteri(idDesc.fInfo.fTarget, | |
| 1290 GR_GL_TEXTURE_WRAP_T, | |
| 1291 initialTexParams.fWrapT)); | |
| 1292 return initialTexParams; | |
| 1293 } | |
| 1294 | |
| 1088 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, | 1295 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, |
| 1089 GrGpuResource::LifeCycle lifeCycle, | 1296 GrGpuResource::LifeCycle lifeCycle, |
| 1090 const void* srcData, size_t rowBytes) { | 1297 const SkTArray<SkMipMapLevel>& texels) { |
| 1091 // We fail if the MSAA was requested and is not available. | 1298 // We fail if the MSAA was requested and is not available. |
| 1092 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { | 1299 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { |
| 1093 //SkDebugf("MSAA RT requested but not supported on this platform."); | 1300 //SkDebugf("MSAA RT requested but not supported on this platform."); |
| 1094 return return_null_texture(); | 1301 return return_null_texture(); |
| 1095 } | 1302 } |
| 1096 | 1303 |
| 1097 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); | 1304 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); |
| 1098 | 1305 |
| 1099 GrGLTexture::IDDesc idDesc; | 1306 GrGLTexture::IDDesc idDesc = generate_gl_texture(this->glInterface(), lifeCy cle); |
| 1100 idDesc.fInfo.fID = 0; | |
| 1101 GL_CALL(GenTextures(1, &idDesc.fInfo.fID)); | |
| 1102 idDesc.fLifeCycle = lifeCycle; | |
| 1103 // We only support GL_TEXTURE_2D at the moment. | |
| 1104 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D; | |
| 1105 | |
| 1106 if (!idDesc.fInfo.fID) { | 1307 if (!idDesc.fInfo.fID) { |
| 1107 return return_null_texture(); | 1308 return return_null_texture(); |
| 1108 } | 1309 } |
| 1109 | 1310 |
| 1110 this->setScratchTextureUnit(); | 1311 this->setScratchTextureUnit(); |
| 1111 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); | 1312 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); |
| 1112 | 1313 |
| 1113 if (renderTarget && this->glCaps().textureUsageSupport()) { | 1314 if (renderTarget && this->glCaps().textureUsageSupport()) { |
| 1114 // provides a hint about how this texture will be used | 1315 // provides a hint about how this texture will be used |
| 1115 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | 1316 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, |
| 1116 GR_GL_TEXTURE_USAGE, | 1317 GR_GL_TEXTURE_USAGE, |
| 1117 GR_GL_FRAMEBUFFER_ATTACHMENT)); | 1318 GR_GL_FRAMEBUFFER_ATTACHMENT)); |
| 1118 } | 1319 } |
| 1119 | 1320 |
| 1120 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1321 GrGLTexture::TexParams initialTexParams = set_initial_texture_params(this->g lInterface(), |
| 1121 // drivers have a bug where an FBO won't be complete if it includes a | 1322 idDesc) ; |
| 1122 // texture that is not mipmap complete (considering the filter in use). | 1323 |
| 1123 GrGLTexture::TexParams initialTexParams; | |
| 1124 // we only set a subset here so invalidate first | |
| 1125 initialTexParams.invalidate(); | |
| 1126 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
| 1127 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
| 1128 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
| 1129 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
| 1130 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | |
| 1131 GR_GL_TEXTURE_MAG_FILTER, | |
| 1132 initialTexParams.fMagFilter)); | |
| 1133 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | |
| 1134 GR_GL_TEXTURE_MIN_FILTER, | |
| 1135 initialTexParams.fMinFilter)); | |
| 1136 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | |
| 1137 GR_GL_TEXTURE_WRAP_S, | |
| 1138 initialTexParams.fWrapS)); | |
| 1139 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | |
| 1140 GR_GL_TEXTURE_WRAP_T, | |
| 1141 initialTexParams.fWrapT)); | |
| 1142 if (!this->uploadTexData(desc, idDesc.fInfo.fTarget, kNewTexture_UploadType, 0, 0, | 1324 if (!this->uploadTexData(desc, idDesc.fInfo.fTarget, kNewTexture_UploadType, 0, 0, |
| 1143 desc.fWidth, desc.fHeight, | 1325 desc.fWidth, desc.fHeight, |
| 1144 desc.fConfig, srcData, rowBytes)) { | 1326 desc.fConfig, texels)) { |
| 1145 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); | 1327 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); |
| 1146 return return_null_texture(); | 1328 return return_null_texture(); |
| 1147 } | 1329 } |
| 1148 | 1330 |
| 1149 GrGLTexture* tex; | 1331 GrGLTexture* tex; |
| 1150 if (renderTarget) { | 1332 if (renderTarget) { |
| 1151 // unbind the texture from the texture unit before binding it to the fra me buffer | 1333 // unbind the texture from the texture unit before binding it to the fra me buffer |
| 1152 GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0)); | 1334 GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0)); |
| 1153 GrGLRenderTarget::IDDesc rtIDDesc; | 1335 GrGLRenderTarget::IDDesc rtIDDesc; |
| 1154 | 1336 |
| 1155 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fInfo, &rtI DDesc)) { | 1337 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fInfo, &rtI DDesc)) { |
| 1156 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); | 1338 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); |
| 1157 return return_null_texture(); | 1339 return return_null_texture(); |
| 1158 } | 1340 } |
| 1159 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); | 1341 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); |
| 1160 } else { | 1342 } else { |
| 1161 tex = new GrGLTexture(this, desc, idDesc); | 1343 bool wasMipMapDataProvided = false; |
| 1344 if (texels.count() > 1) { | |
| 1345 wasMipMapDataProvided = true; | |
| 1346 } | |
| 1347 tex = new GrGLTexture(this, desc, idDesc, wasMipMapDataProvided); | |
| 1162 } | 1348 } |
| 1163 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1349 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
| 1164 #ifdef TRACE_TEXTURE_CREATION | 1350 #ifdef TRACE_TEXTURE_CREATION |
| 1165 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", | 1351 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", |
| 1166 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1352 glTexDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig); |
| 1167 #endif | 1353 #endif |
| 1168 return tex; | 1354 return tex; |
| 1169 } | 1355 } |
| 1170 | 1356 |
| 1171 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, | 1357 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, |
| 1172 GrGpuResource::LifeCycle lifeCycle , | 1358 GrGpuResource::LifeCycle lifeCycle , |
| 1173 const void* srcData) { | 1359 const SkTArray<SkMipMapLevel>& tex els) { |
| 1174 // Make sure that we're not flipping Y. | 1360 // Make sure that we're not flipping Y. |
| 1175 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 1361 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
| 1176 return return_null_texture(); | 1362 return return_null_texture(); |
| 1177 } | 1363 } |
| 1178 | 1364 |
| 1179 GrGLTexture::IDDesc idDesc; | 1365 GrGLTexture::IDDesc idDesc = generate_gl_texture(this->glInterface(), lifeCy cle); |
| 1180 idDesc.fInfo.fID = 0; | |
| 1181 GL_CALL(GenTextures(1, &idDesc.fInfo.fID)); | |
| 1182 idDesc.fLifeCycle = lifeCycle; | |
| 1183 // We only support GL_TEXTURE_2D at the moment. | |
| 1184 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D; | |
| 1185 | |
| 1186 if (!idDesc.fInfo.fID) { | 1366 if (!idDesc.fInfo.fID) { |
| 1187 return return_null_texture(); | 1367 return return_null_texture(); |
| 1188 } | 1368 } |
| 1189 | 1369 |
| 1190 this->setScratchTextureUnit(); | 1370 this->setScratchTextureUnit(); |
| 1191 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); | 1371 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); |
| 1192 | 1372 |
| 1193 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1373 GrGLTexture::TexParams initialTexParams = set_initial_texture_params(this->g lInterface(), |
| 1194 // drivers have a bug where an FBO won't be complete if it includes a | 1374 idDesc) ; |
| 1195 // texture that is not mipmap complete (considering the filter in use). | |
| 1196 GrGLTexture::TexParams initialTexParams; | |
| 1197 // we only set a subset here so invalidate first | |
| 1198 initialTexParams.invalidate(); | |
| 1199 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
| 1200 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
| 1201 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
| 1202 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
| 1203 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | |
| 1204 GR_GL_TEXTURE_MAG_FILTER, | |
| 1205 initialTexParams.fMagFilter)); | |
| 1206 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | |
| 1207 GR_GL_TEXTURE_MIN_FILTER, | |
| 1208 initialTexParams.fMinFilter)); | |
| 1209 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | |
| 1210 GR_GL_TEXTURE_WRAP_S, | |
| 1211 initialTexParams.fWrapS)); | |
| 1212 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, | |
| 1213 GR_GL_TEXTURE_WRAP_T, | |
| 1214 initialTexParams.fWrapT)); | |
| 1215 | 1375 |
| 1216 if (!this->uploadCompressedTexData(desc, idDesc.fInfo.fTarget, srcData)) { | 1376 if (!this->uploadCompressedTexData(desc, idDesc.fInfo.fTarget, texels)) { |
| 1217 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); | 1377 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); |
| 1218 return return_null_texture(); | 1378 return return_null_texture(); |
| 1219 } | 1379 } |
| 1220 | 1380 |
| 1221 GrGLTexture* tex; | 1381 GrGLTexture* tex; |
| 1222 tex = new GrGLTexture(this, desc, idDesc); | 1382 tex = new GrGLTexture(this, desc, idDesc); |
| 1223 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1383 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
| 1224 #ifdef TRACE_TEXTURE_CREATION | 1384 #ifdef TRACE_TEXTURE_CREATION |
| 1225 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", | 1385 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", |
| 1226 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1386 glTexDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig); |
| 1227 #endif | 1387 #endif |
| 1228 return tex; | 1388 return tex; |
| 1229 } | 1389 } |
| 1230 | 1390 |
| 1231 namespace { | 1391 namespace { |
| 1232 | 1392 |
| 1233 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; | 1393 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; |
| 1234 | 1394 |
| 1235 void inline get_stencil_rb_sizes(const GrGLInterface* gl, | 1395 void inline get_stencil_rb_sizes(const GrGLInterface* gl, |
| 1236 GrGLStencilAttachment::Format* format) { | 1396 GrGLStencilAttachment::Format* format) { |
| (...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2566 | 2726 |
| 2567 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | 2727 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
| 2568 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) { | 2728 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) { |
| 2569 filterMode = GrTextureParams::kBilerp_FilterMode; | 2729 filterMode = GrTextureParams::kBilerp_FilterMode; |
| 2570 } | 2730 } |
| 2571 } | 2731 } |
| 2572 | 2732 |
| 2573 newTexParams.fMinFilter = glMinFilterModes[filterMode]; | 2733 newTexParams.fMinFilter = glMinFilterModes[filterMode]; |
| 2574 newTexParams.fMagFilter = glMagFilterModes[filterMode]; | 2734 newTexParams.fMagFilter = glMagFilterModes[filterMode]; |
| 2575 | 2735 |
| 2576 if (GrTextureParams::kMipMap_FilterMode == filterMode && | 2736 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
| 2577 texture->texturePriv().mipMapsAreDirty()) { | 2737 if (texture->texturePriv().mipMapsAreDirty()) { |
| 2578 GL_CALL(GenerateMipmap(target)); | 2738 GL_CALL(GenerateMipmap(target)); |
| 2579 texture->texturePriv().dirtyMipMaps(false); | 2739 texture->texturePriv().dirtyMipMaps(false); |
| 2740 texture->texturePriv().setMaxMipMapLevel(SkMipMapLevelCount(texture- >width(), | |
| 2741 texture- >height())); | |
| 2742 } | |
| 2743 if (texture->texturePriv().hasMipMaps()) { | |
| 2744 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_LOD, 0)); | |
|
bsalomon
2016/01/20 14:21:44
Should we be setting this on every draw? Maybe sto
cblume
2016/01/21 23:08:50
I have updated this to now only call when the max
| |
| 2745 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL, 0)); | |
| 2746 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LOD, | |
| 2747 static_cast<float>(texture->texturePriv().maxM ipMapLevel()))); | |
| 2748 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL, | |
| 2749 texture->texturePriv().maxMipMapLevel())); | |
| 2750 } | |
| 2580 } | 2751 } |
| 2581 | 2752 |
| 2582 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); | 2753 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); |
| 2583 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); | 2754 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); |
| 2584 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz leRGBA); | 2755 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz leRGBA); |
| 2585 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { | 2756 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { |
| 2586 this->setTextureUnit(unitIdx); | 2757 this->setTextureUnit(unitIdx); |
| 2587 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa gFilter)); | 2758 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa gFilter)); |
| 2588 } | 2759 } |
| 2589 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { | 2760 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2775 viewport->fWidth = surface->width(); | 2946 viewport->fWidth = surface->width(); |
| 2776 viewport->fHeight = surface->height(); | 2947 viewport->fHeight = surface->height(); |
| 2777 } else { | 2948 } else { |
| 2778 fStats.incRenderTargetBinds(); | 2949 fStats.incRenderTargetBinds(); |
| 2779 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO ID())); | 2950 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO ID())); |
| 2780 *viewport = rt->getViewport(); | 2951 *viewport = rt->getViewport(); |
| 2781 } | 2952 } |
| 2782 } | 2953 } |
| 2783 | 2954 |
| 2784 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) { | 2955 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) { |
| 2785 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ ets to | 2956 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ ets to |
| 2786 if (!surface->asRenderTarget()) { | 2957 if (!surface->asRenderTarget()) { |
| 2787 SkASSERT(surface->asTexture()); | 2958 SkASSERT(surface->asTexture()); |
| 2788 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture()) ->target(); | 2959 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture()) ->target(); |
| 2789 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | 2960 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
| 2790 GR_GL_COLOR_ATTACHM ENT0, | 2961 GR_GL_COLOR_ATTACHM ENT0, |
| 2791 textureTarget, | 2962 textureTarget, |
| 2792 0, | 2963 0, |
| 2793 0)); | 2964 0)); |
| 2794 } | 2965 } |
| 2795 } | 2966 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2859 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDr aw handle the | 3030 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDr aw handle the |
| 2860 // swizzle. | 3031 // swizzle. |
| 2861 if (this->glCaps().glslCaps()->configOutputSwizzle(src->config()) != | 3032 if (this->glCaps().glslCaps()->configOutputSwizzle(src->config()) != |
| 2862 this->glCaps().glslCaps()->configOutputSwizzle(dst->config())) { | 3033 this->glCaps().glslCaps()->configOutputSwizzle(dst->config())) { |
| 2863 return false; | 3034 return false; |
| 2864 } | 3035 } |
| 2865 if (src->asTexture() && dst->asRenderTarget()) { | 3036 if (src->asTexture() && dst->asRenderTarget()) { |
| 2866 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | 3037 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); |
| 2867 return true; | 3038 return true; |
| 2868 } | 3039 } |
| 2869 | 3040 |
| 2870 if (can_copy_texsubimage(dst, src, this)) { | 3041 if (can_copy_texsubimage(dst, src, this)) { |
| 2871 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); | 3042 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); |
| 2872 return true; | 3043 return true; |
| 2873 } | 3044 } |
| 2874 | 3045 |
| 2875 if (can_blit_framebuffer(dst, src, this)) { | 3046 if (can_blit_framebuffer(dst, src, this)) { |
| 2876 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); | 3047 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); |
| 2877 } | 3048 } |
| 2878 | 3049 |
| 2879 return false; | 3050 return false; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2910 | 3081 |
| 2911 SkString vshaderTxt(version); | 3082 SkString vshaderTxt(version); |
| 2912 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); | 3083 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
| 2913 vshaderTxt.append(";"); | 3084 vshaderTxt.append(";"); |
| 2914 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); | 3085 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
| 2915 vshaderTxt.append(";"); | 3086 vshaderTxt.append(";"); |
| 2916 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); | 3087 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
| 2917 vshaderTxt.append(";"); | 3088 vshaderTxt.append(";"); |
| 2918 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); | 3089 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
| 2919 vshaderTxt.append(";"); | 3090 vshaderTxt.append(";"); |
| 2920 | 3091 |
| 2921 vshaderTxt.append( | 3092 vshaderTxt.append( |
| 2922 "// Copy Program VS\n" | 3093 "// Copy Program VS\n" |
| 2923 "void main() {" | 3094 "void main() {" |
| 2924 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.z w;" | 3095 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.z w;" |
| 2925 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" | 3096 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" |
| 2926 " gl_Position.zw = vec2(0, 1);" | 3097 " gl_Position.zw = vec2(0, 1);" |
| 2927 "}" | 3098 "}" |
| 2928 ); | 3099 ); |
| 2929 | 3100 |
| 2930 SkString fshaderTxt(version); | 3101 SkString fshaderTxt(version); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 2949 fsOutName = "gl_FragColor"; | 3120 fsOutName = "gl_FragColor"; |
| 2950 } | 3121 } |
| 2951 fshaderTxt.appendf( | 3122 fshaderTxt.appendf( |
| 2952 "// Copy Program FS\n" | 3123 "// Copy Program FS\n" |
| 2953 "void main() {" | 3124 "void main() {" |
| 2954 " %s = %s(u_texture, v_texCoord);" | 3125 " %s = %s(u_texture, v_texCoord);" |
| 2955 "}", | 3126 "}", |
| 2956 fsOutName, | 3127 fsOutName, |
| 2957 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[i], this- >glslGeneration()) | 3128 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[i], this- >glslGeneration()) |
| 2958 ); | 3129 ); |
| 2959 | 3130 |
| 2960 GL_CALL_RET(fCopyPrograms[i].fProgram, CreateProgram()); | 3131 GL_CALL_RET(fCopyPrograms[i].fProgram, CreateProgram()); |
| 2961 const char* str; | 3132 const char* str; |
| 2962 GrGLint length; | 3133 GrGLint length; |
| 2963 | 3134 |
| 2964 str = vshaderTxt.c_str(); | 3135 str = vshaderTxt.c_str(); |
| 2965 length = SkToInt(vshaderTxt.size()); | 3136 length = SkToInt(vshaderTxt.size()); |
| 2966 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms [i].fProgram, | 3137 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms [i].fProgram, |
| 2967 GR_GL_VERTEX_SHADER, &str, &length, 1, | 3138 GR_GL_VERTEX_SHADER, &str, &length, 1, |
| 2968 &fStats); | 3139 &fStats); |
| 2969 | 3140 |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3484 this->setVertexArrayID(gpu, 0); | 3655 this->setVertexArrayID(gpu, 0); |
| 3485 } | 3656 } |
| 3486 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3657 int attrCount = gpu->glCaps().maxVertexAttributes(); |
| 3487 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 3658 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
| 3488 fDefaultVertexArrayAttribState.resize(attrCount); | 3659 fDefaultVertexArrayAttribState.resize(attrCount); |
| 3489 } | 3660 } |
| 3490 attribState = &fDefaultVertexArrayAttribState; | 3661 attribState = &fDefaultVertexArrayAttribState; |
| 3491 } | 3662 } |
| 3492 return attribState; | 3663 return attribState; |
| 3493 } | 3664 } |
| OLD | NEW |