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 } |
2580 } | 2743 } |
2581 | 2744 |
| 2745 newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); |
| 2746 |
2582 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); | 2747 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); |
2583 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); | 2748 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); |
2584 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz
leRGBA); | 2749 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz
leRGBA); |
2585 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { | 2750 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { |
2586 this->setTextureUnit(unitIdx); | 2751 this->setTextureUnit(unitIdx); |
2587 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa
gFilter)); | 2752 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa
gFilter)); |
2588 } | 2753 } |
2589 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { | 2754 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { |
2590 this->setTextureUnit(unitIdx); | 2755 this->setTextureUnit(unitIdx); |
2591 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newTexParams.fMi
nFilter)); | 2756 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newTexParams.fMi
nFilter)); |
2592 } | 2757 } |
| 2758 if (setAll || newTexParams.fMaxMipMapLevel != oldTexParams.fMaxMipMapLevel)
{ |
| 2759 if (newTexParams.fMaxMipMapLevel != 0) { |
| 2760 this->setTextureUnit(unitIdx); |
| 2761 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_LOD, 0)); |
| 2762 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL, 0)); |
| 2763 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LOD, |
| 2764 static_cast<float>(newTexParams.fMaxMipMapLeve
l))); |
| 2765 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL, |
| 2766 newTexParams.fMaxMipMapLevel)); |
| 2767 } |
| 2768 } |
2593 if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) { | 2769 if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) { |
2594 this->setTextureUnit(unitIdx); | 2770 this->setTextureUnit(unitIdx); |
2595 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newTexParams.fWrapS)
); | 2771 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newTexParams.fWrapS)
); |
2596 } | 2772 } |
2597 if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) { | 2773 if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) { |
2598 this->setTextureUnit(unitIdx); | 2774 this->setTextureUnit(unitIdx); |
2599 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT)
); | 2775 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT)
); |
2600 } | 2776 } |
2601 if (this->glCaps().textureSwizzleSupport() && | 2777 if (this->glCaps().textureSwizzleSupport() && |
2602 (setAll || memcmp(newTexParams.fSwizzleRGBA, | 2778 (setAll || memcmp(newTexParams.fSwizzleRGBA, |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2775 viewport->fWidth = surface->width(); | 2951 viewport->fWidth = surface->width(); |
2776 viewport->fHeight = surface->height(); | 2952 viewport->fHeight = surface->height(); |
2777 } else { | 2953 } else { |
2778 fStats.incRenderTargetBinds(); | 2954 fStats.incRenderTargetBinds(); |
2779 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO
ID())); | 2955 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO
ID())); |
2780 *viewport = rt->getViewport(); | 2956 *viewport = rt->getViewport(); |
2781 } | 2957 } |
2782 } | 2958 } |
2783 | 2959 |
2784 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) { | 2960 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) { |
2785 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ
ets to | 2961 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ
ets to |
2786 if (!surface->asRenderTarget()) { | 2962 if (!surface->asRenderTarget()) { |
2787 SkASSERT(surface->asTexture()); | 2963 SkASSERT(surface->asTexture()); |
2788 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())
->target(); | 2964 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())
->target(); |
2789 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | 2965 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
2790 GR_GL_COLOR_ATTACHM
ENT0, | 2966 GR_GL_COLOR_ATTACHM
ENT0, |
2791 textureTarget, | 2967 textureTarget, |
2792 0, | 2968 0, |
2793 0)); | 2969 0)); |
2794 } | 2970 } |
2795 } | 2971 } |
(...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 | 3035 // None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDr
aw handle the |
2860 // swizzle. | 3036 // swizzle. |
2861 if (this->glCaps().glslCaps()->configOutputSwizzle(src->config()) != | 3037 if (this->glCaps().glslCaps()->configOutputSwizzle(src->config()) != |
2862 this->glCaps().glslCaps()->configOutputSwizzle(dst->config())) { | 3038 this->glCaps().glslCaps()->configOutputSwizzle(dst->config())) { |
2863 return false; | 3039 return false; |
2864 } | 3040 } |
2865 if (src->asTexture() && dst->asRenderTarget()) { | 3041 if (src->asTexture() && dst->asRenderTarget()) { |
2866 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | 3042 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); |
2867 return true; | 3043 return true; |
2868 } | 3044 } |
2869 | 3045 |
2870 if (can_copy_texsubimage(dst, src, this)) { | 3046 if (can_copy_texsubimage(dst, src, this)) { |
2871 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); | 3047 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); |
2872 return true; | 3048 return true; |
2873 } | 3049 } |
2874 | 3050 |
2875 if (can_blit_framebuffer(dst, src, this)) { | 3051 if (can_blit_framebuffer(dst, src, this)) { |
2876 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); | 3052 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); |
2877 } | 3053 } |
2878 | 3054 |
2879 return false; | 3055 return false; |
(...skipping 30 matching lines...) Expand all Loading... |
2910 | 3086 |
2911 SkString vshaderTxt(version); | 3087 SkString vshaderTxt(version); |
2912 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); | 3088 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
2913 vshaderTxt.append(";"); | 3089 vshaderTxt.append(";"); |
2914 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); | 3090 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
2915 vshaderTxt.append(";"); | 3091 vshaderTxt.append(";"); |
2916 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); | 3092 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
2917 vshaderTxt.append(";"); | 3093 vshaderTxt.append(";"); |
2918 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); | 3094 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); |
2919 vshaderTxt.append(";"); | 3095 vshaderTxt.append(";"); |
2920 | 3096 |
2921 vshaderTxt.append( | 3097 vshaderTxt.append( |
2922 "// Copy Program VS\n" | 3098 "// Copy Program VS\n" |
2923 "void main() {" | 3099 "void main() {" |
2924 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.z
w;" | 3100 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.z
w;" |
2925 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" | 3101 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" |
2926 " gl_Position.zw = vec2(0, 1);" | 3102 " gl_Position.zw = vec2(0, 1);" |
2927 "}" | 3103 "}" |
2928 ); | 3104 ); |
2929 | 3105 |
2930 SkString fshaderTxt(version); | 3106 SkString fshaderTxt(version); |
(...skipping 18 matching lines...) Expand all Loading... |
2949 fsOutName = "gl_FragColor"; | 3125 fsOutName = "gl_FragColor"; |
2950 } | 3126 } |
2951 fshaderTxt.appendf( | 3127 fshaderTxt.appendf( |
2952 "// Copy Program FS\n" | 3128 "// Copy Program FS\n" |
2953 "void main() {" | 3129 "void main() {" |
2954 " %s = %s(u_texture, v_texCoord);" | 3130 " %s = %s(u_texture, v_texCoord);" |
2955 "}", | 3131 "}", |
2956 fsOutName, | 3132 fsOutName, |
2957 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[i], this-
>glslGeneration()) | 3133 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[i], this-
>glslGeneration()) |
2958 ); | 3134 ); |
2959 | 3135 |
2960 GL_CALL_RET(fCopyPrograms[i].fProgram, CreateProgram()); | 3136 GL_CALL_RET(fCopyPrograms[i].fProgram, CreateProgram()); |
2961 const char* str; | 3137 const char* str; |
2962 GrGLint length; | 3138 GrGLint length; |
2963 | 3139 |
2964 str = vshaderTxt.c_str(); | 3140 str = vshaderTxt.c_str(); |
2965 length = SkToInt(vshaderTxt.size()); | 3141 length = SkToInt(vshaderTxt.size()); |
2966 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms
[i].fProgram, | 3142 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms
[i].fProgram, |
2967 GR_GL_VERTEX_SHADER, &str,
&length, 1, | 3143 GR_GL_VERTEX_SHADER, &str,
&length, 1, |
2968 &fStats); | 3144 &fStats); |
2969 | 3145 |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3484 this->setVertexArrayID(gpu, 0); | 3660 this->setVertexArrayID(gpu, 0); |
3485 } | 3661 } |
3486 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3662 int attrCount = gpu->glCaps().maxVertexAttributes(); |
3487 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 3663 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
3488 fDefaultVertexArrayAttribState.resize(attrCount); | 3664 fDefaultVertexArrayAttribState.resize(attrCount); |
3489 } | 3665 } |
3490 attribState = &fDefaultVertexArrayAttribState; | 3666 attribState = &fDefaultVertexArrayAttribState; |
3491 } | 3667 } |
3492 return attribState; | 3668 return attribState; |
3493 } | 3669 } |
OLD | NEW |