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

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

Issue 1249543003: Creating functions for uploading a mipmapped texture. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Moving glTexStorage over to a separate CL. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 8
9 #include "GrGLGpu.h" 9 #include "GrGLGpu.h"
10 #include "GrGLGLSL.h" 10 #include "GrGLGLSL.h"
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 "SkStrokeRec.h" 23 #include "SkStrokeRec.h"
24 #include "SkTemplates.h" 24 #include "SkTemplates.h"
25 #include "SkTypes.h"
25 26
26 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) 27 #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) 28 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
28 29
29 #define SKIP_CACHE_CHECK true 30 #define SKIP_CACHE_CHECK true
30 31
31 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR 32 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
32 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) 33 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface)
33 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) 34 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call)
34 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) 35 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface)
35 #else 36 #else
36 #define CLEAR_ERROR_BEFORE_ALLOC(iface) 37 #define CLEAR_ERROR_BEFORE_ALLOC(iface)
37 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call) 38 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call)
38 #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR 39 #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR
39 #endif 40 #endif
40 41
42 #if defined(GOOGLE3)
43 // Stack frame size is limited in GOOGLE3.
44 typedef SkAutoSMalloc<64 * 128> SkAutoSMallocTexels;
45 #else
46 typedef SkAutoSMalloc<128 * 128> SkAutoSMallocTexels;
47 #endif
41 48
42 /////////////////////////////////////////////////////////////////////////////// 49 ///////////////////////////////////////////////////////////////////////////////
43 50
44 51
45 static const GrGLenum gXfermodeEquation2Blend[] = { 52 static const GrGLenum gXfermodeEquation2Blend[] = {
46 // Basic OpenGL blend equations. 53 // Basic OpenGL blend equations.
47 GR_GL_FUNC_ADD, 54 GR_GL_FUNC_ADD,
48 GR_GL_FUNC_SUBTRACT, 55 GR_GL_FUNC_SUBTRACT,
49 GR_GL_FUNC_REVERSE_SUBTRACT, 56 GR_GL_FUNC_REVERSE_SUBTRACT,
50 57
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 return nullptr; 465 return nullptr;
459 } 466 }
460 467
461 switch (ownership) { 468 switch (ownership) {
462 case kAdopt_GrWrapOwnership: 469 case kAdopt_GrWrapOwnership:
463 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; 470 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
464 break; 471 break;
465 case kBorrow_GrWrapOwnership: 472 case kBorrow_GrWrapOwnership:
466 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; 473 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
467 break; 474 break;
468 } 475 }
469 476
470 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; 477 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags;
471 surfDesc.fWidth = desc.fWidth; 478 surfDesc.fWidth = desc.fWidth;
472 surfDesc.fHeight = desc.fHeight; 479 surfDesc.fHeight = desc.fHeight;
473 surfDesc.fConfig = desc.fConfig; 480 surfDesc.fConfig = desc.fConfig;
474 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() ); 481 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() );
475 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly 482 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly
476 // assuming the old behaviour, which is that backend textures are always 483 // assuming the old behaviour, which is that backend textures are always
477 // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to: 484 // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to:
478 // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget); 485 // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
(...skipping 27 matching lines...) Expand all
506 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); 513 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle);
507 idDesc.fMSColorRenderbufferID = 0; 514 idDesc.fMSColorRenderbufferID = 0;
508 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; 515 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
509 switch (ownership) { 516 switch (ownership) {
510 case kAdopt_GrWrapOwnership: 517 case kAdopt_GrWrapOwnership:
511 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; 518 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
512 break; 519 break;
513 case kBorrow_GrWrapOwnership: 520 case kBorrow_GrWrapOwnership:
514 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; 521 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
515 break; 522 break;
516 } 523 }
517 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; 524 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig;
518 525
519 GrSurfaceDesc desc; 526 GrSurfaceDesc desc;
520 desc.fConfig = wrapDesc.fConfig; 527 desc.fConfig = wrapDesc.fConfig;
521 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; 528 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag;
522 desc.fWidth = wrapDesc.fWidth; 529 desc.fWidth = wrapDesc.fWidth;
523 desc.fHeight = wrapDesc.fHeight; 530 desc.fHeight = wrapDesc.fHeight;
524 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); 531 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() );
525 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); 532 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true);
526 533
527 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits); 534 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits);
528 } 535 }
529 536
530 //////////////////////////////////////////////////////////////////////////////// 537 ////////////////////////////////////////////////////////////////////////////////
531 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 538 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
532 size_t rowBytes, GrPixelConfig srcConfig, 539 GrPixelConfig srcConfig,
533 DrawPreference* drawPreference, 540 DrawPreference* drawPreference,
534 WritePixelTempDrawInfo* tempDrawInfo) { 541 WritePixelTempDrawInfo* tempDrawInfo) {
535 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { 542 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) {
536 return false; 543 return false;
537 } 544 }
538 545
539 // This subclass only allows writes to textures. If the dst is not a texture we have to draw 546 // This subclass only allows writes to textures. If the dst is not a texture we have to draw
540 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. 547 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y.
541 if (!dstSurface->asTexture()) { 548 if (!dstSurface->asTexture()) {
542 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 549 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 // Write or transfer of pixels is only implemented for TEXTURE_2D textures 614 // Write or transfer of pixels is only implemented for TEXTURE_2D textures
608 if (GR_GL_TEXTURE_2D != glTex->target()) { 615 if (GR_GL_TEXTURE_2D != glTex->target()) {
609 return false; 616 return false;
610 } 617 }
611 618
612 return true; 619 return true;
613 } 620 }
614 621
615 bool GrGLGpu::onWritePixels(GrSurface* surface, 622 bool GrGLGpu::onWritePixels(GrSurface* surface,
616 int left, int top, int width, int height, 623 int left, int top, int width, int height,
617 GrPixelConfig config, const void* buffer, 624 GrPixelConfig config,
618 size_t rowBytes) { 625 const SkTArray<SkMipMapLevel>& texels) {
619 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); 626 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
620 627
621 if (!check_write_and_transfer_input(glTex, surface, config)) { 628 if (!check_write_and_transfer_input(glTex, surface, config)) {
622 return false; 629 return false;
623 } 630 }
624 631
625 this->setScratchTextureUnit(); 632 this->setScratchTextureUnit();
626 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); 633 GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
627 634
628 bool success = false; 635 bool success = false;
629 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { 636 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
630 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() 637 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s()
631 SkASSERT(config == glTex->desc().fConfig); 638 SkASSERT(config == glTex->desc().fConfig);
632 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), buffer, 639 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), texels, false,
633 kWrite_UploadType, left, top, wi dth, height); 640 kWrite_UploadType, left, top, wi dth, height);
634 } else { 641 } else {
635 success = this->uploadTexData(glTex->desc(), glTex->target(), kWrite_Upl oadType, 642 success = this->uploadTexData(glTex->desc(), glTex->target(), kWrite_Upl oadType,
636 left, top, width, height, config, buffer, rowBytes); 643 left, top, width, height, config, texels);
637 } 644 }
638 645
639 if (success) { 646 return success;
640 glTex->texturePriv().dirtyMipMaps(true);
641 return true;
642 }
643
644 return false;
645 } 647 }
646 648
647 bool GrGLGpu::onTransferPixels(GrSurface* surface, 649 bool GrGLGpu::onTransferPixels(GrSurface* surface,
648 int left, int top, int width, int height, 650 int left, int top, int width, int height,
649 GrPixelConfig config, GrTransferBuffer* buffer, 651 GrPixelConfig config, GrTransferBuffer* buffer,
650 size_t offset, size_t rowBytes) { 652 size_t offset, size_t rowBytes) {
651 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); 653 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
652 654
653 if (!check_write_and_transfer_input(glTex, surface, config)) { 655 if (!check_write_and_transfer_input(glTex, surface, config)) {
654 return false; 656 return false;
655 } 657 }
656 658
657 // For the moment, can't transfer compressed data 659 // For the moment, can't transfer compressed data
658 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { 660 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
659 return false; 661 return false;
660 } 662 }
661 663
662 this->setScratchTextureUnit(); 664 this->setScratchTextureUnit();
663 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); 665 GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
664 666
665 SkASSERT(!buffer->isMapped()); 667 SkASSERT(!buffer->isMapped());
666 GrGLTransferBuffer* glBuffer = reinterpret_cast<GrGLTransferBuffer*>(buffer) ; 668 GrGLTransferBuffer* glBuffer = reinterpret_cast<GrGLTransferBuffer*>(buffer) ;
667 // bind the transfer buffer 669 // bind the transfer buffer
668 SkASSERT(GR_GL_PIXEL_UNPACK_BUFFER == glBuffer->bufferType() || 670 SkASSERT(GR_GL_PIXEL_UNPACK_BUFFER == glBuffer->bufferType() ||
669 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == glBuffer->bufferType ()); 671 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == glBuffer->bufferType ());
670 GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID())); 672 GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID()));
671 673
672 bool success = false; 674 bool success = false;
675 SkMipMapLevel mipLevel(buffer, rowBytes, width, height);
676 const int mipLevelCount = 1;
677 SkTArray<SkMipMapLevel> texels(mipLevelCount);
678 texels.push_back(mipLevel);
673 success = this->uploadTexData(glTex->desc(), glTex->target(), kTransfer_Uplo adType, 679 success = this->uploadTexData(glTex->desc(), glTex->target(), kTransfer_Uplo adType,
674 left, top, width, height, config, buffer, rowB ytes); 680 left, top, width, height, config, texels);
675 681
676 if (success) { 682 if (success) {
677 glTex->texturePriv().dirtyMipMaps(true); 683 glTex->texturePriv().dirtyMipMaps(true);
678 return true; 684 return true;
679 } 685 }
680 686
681 return false; 687 return false;
682 } 688 }
683 689
684 // For GL_[UN]PACK_ALIGNMENT. 690 // For GL_[UN]PACK_ALIGNMENT.
(...skipping 19 matching lines...) Expand all
704 710
705 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, 711 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
706 const GrGLInterface* interface) { 712 const GrGLInterface* interface) {
707 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { 713 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) {
708 return GR_GL_GET_ERROR(interface); 714 return GR_GL_GET_ERROR(interface);
709 } else { 715 } else {
710 return CHECK_ALLOC_ERROR(interface); 716 return CHECK_ALLOC_ERROR(interface);
711 } 717 }
712 } 718 }
713 719
720 /**
721 * Creates storage space for the texture and fills it with texels.
722 *
723 * @param desc The surface descriptor for the texture being created.
724 * @param interface The GL interface in use.
725 * @param useTexStorage The result of a call to can_use_tex_storage().
726 * @param internalFormat The data format used for the internal storage of the te xture.
727 * @param externalFormat The data format used for the external storage of the te xture.
728 * @param externalType The type of the data used for the external storage of t he texture.
729 * @param texels The texel data of the texture being created.
730 * @param succeeded Set to true if allocating and populating the texture co mpleted
731 * without error.
732 */
733 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc ,
734 const GrGLInterface& inte rface,
735 GrGLenum target,
736 GrGLenum internalFormat,
737 GrGLenum externalFormat,
738 GrGLenum externalType,
739 const SkTArray<SkMipMapLe vel>& texels,
740 bool* succeeded) {
741 CLEAR_ERROR_BEFORE_ALLOC(&interface);
742 *succeeded = true;
743 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) {
744 const void* currentMipData = texels[currentMipLevel].fTexelsOrOffset;
745 // Even if curremtMipData is nullptr, continue to call TexImage2D.
746 // This will allocate texture memory which we can later populate.
747 GL_ALLOC_CALL(&interface,
748 TexImage2D(target,
749 currentMipLevel,
750 internalFormat,
751 texels[currentMipLevel].fWidth,
752 texels[currentMipLevel].fHeight,
753 0, // border
754 externalFormat, externalType,
755 currentMipData));
756 GrGLenum error = check_alloc_error(desc, &interface);
757 if (error != GR_GL_NO_ERROR) {
758 *succeeded = false;
759 break;
760 }
761 }
762
763 if (*succeeded == true) {
764 GR_GL_CALL(&interface,
765 TexParameteri(target, GR_GL_TEXTURE_MIN_LOD, 0));
766 GR_GL_CALL(&interface,
767 TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL, 0));
768 if (texels.count() > 1) {
769 // If we have mipmaps, we can go ahead and limit the max mipmap leve l.
770 // Otherwise, mipmaps may be generated later and we do not want to
771 // limit.
772 GR_GL_CALL(&interface,
bsalomon 2016/01/11 17:16:38 In GrGLGpu::bindTexture we respecify the other tex
Chris Blume 2016/01/12 12:49:33 That makes a lot of sense. I began adding the max
773 TexParameteri(target, GR_GL_TEXTURE_MAX_LOD, static_cast< float>(texels.count() - 1)));
774 GR_GL_CALL(&interface,
775 TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL, texels.cou nt() - 1));
776 }
777 }
778 }
779
780 /**
781 * Creates storage space for the texture and fills it with texels.
782 *
783 * @param desc The surface descriptor for the texture being created.
784 * @param interface The GL interface in use.
785 * @param useTexStorage The result of a call to can_use_tex_storage().
786 * @param internalFormat The data format used for the internal storage of the te xture.
787 * @param texels The texel data of the texture being created.
788 */
789 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc,
790 const GrGLInterface& interf ace,
791 GrGLenum target, GrGLenum i nternalFormat,
792 const SkTArray<SkMipMapLeve l>& texels) {
793 CLEAR_ERROR_BEFORE_ALLOC(&interface);
794 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) {
795 int width = texels[currentMipLevel].fWidth;
796 int height = texels[currentMipLevel].fHeight;
797
798 // Make sure that the width and height that we pass to OpenGL
799 // is a multiple of the block size.
800 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height );
801
802 GL_ALLOC_CALL(&interface,
803 CompressedTexImage2D(target,
804 currentMipLevel,
805 internalFormat,
806 width,
807 height,
808 0, // border
809 SkToInt(dataSize),
810 texels[currentMipLevel].fTexelsOrOffs et));
811
812 GrGLenum error = check_alloc_error(desc, &interface);
813 if (error != GR_GL_NO_ERROR) {
814 return false;
815 }
816 }
817
818 GR_GL_CALL(&interface,
819 TexParameteri(target, GR_GL_TEXTURE_MIN_LOD, 0));
820 GR_GL_CALL(&interface,
821 TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL, 0));
822 if (texels.count() > 1) {
823 // If we have mipmaps, we can go ahead and limit the max mipmap level.
824 // Otherwise, mipmaps may be generated later and we do not want to
825 // limit.
826 GR_GL_CALL(&interface,
827 TexParameteri(target, GR_GL_TEXTURE_MAX_LOD, static_cast<floa t>(texels.count() - 1)));
828
829 GR_GL_CALL(&interface,
830 TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL, texels.count() - 1));
831 }
832
833 return true;
834 }
835
836 /**
837 * After a texture is created, any state which was altered during its creation
838 * needs to be restored.
839 *
840 * @param interface The GL interface to use.
841 * @param caps The capabilities of the GL device.
842 * @param restoreGLRowLength Should the row length unpacking be restored?
843 * @param glFlipY Did GL flip the texture vertically?
844 */
845 static void restore_pixelstore_state(const GrGLInterface& interface, const GrGLC aps& caps,
846 bool restoreGLRowLength, bool glFlipY) {
847 if (restoreGLRowLength) {
848 SkASSERT(caps.unpackRowLengthSupport());
849 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
850 }
851 if (glFlipY) {
852 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
853 }
854 }
855
714 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, 856 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
715 GrGLenum target, 857 GrGLenum target,
716 UploadType uploadType, 858 UploadType uploadType,
717 int left, int top, int width, int height, 859 int left, int top, int width, int height,
718 GrPixelConfig dataConfig, 860 GrPixelConfig dataConfig,
719 const void* dataOrOffset, 861 const SkTArray<SkMipMapLevel>& texels) {
720 size_t rowBytes) {
721 SkASSERT(dataOrOffset || kNewTexture_UploadType == uploadType ||
722 kTransfer_UploadType == uploadType);
723
724 // If we're uploading compressed data then we should be using uploadCompress edTexData 862 // If we're uploading compressed data then we should be using uploadCompress edTexData
725 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 863 SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
726 864
727 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); 865 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig));
728 866
867 // texels is const.
868 // But we may need to flip the texture vertically to prepare it.
869 // Rather than flip in place and alter the incoming data,
870 // we allocate a new buffer to flip into.
871 // This means we need to make a non-const shallow copy of texels.
872 SkTArray<SkMipMapLevel> texelsShallowCopy(texels);
873
874 for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0;
875 currentMipLevel--) {
876 SkASSERT(texelsShallowCopy[currentMipLevel].fTexelsOrOffset
877 || kNewTexture_UploadType == uploadType || kTransfer_UploadType == uploadType);
878 }
879
880
881 const GrGLInterface* interface = this->glInterface();
882 const GrGLCaps& caps = this->glCaps();
883
729 size_t bpp = GrBytesPerPixel(dataConfig); 884 size_t bpp = GrBytesPerPixel(dataConfig);
730 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, & left, &top, 885 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c urrentMipLevel++) {
731 &width, &height, &dataOrOffset, & rowBytes)) { 886 if (texelsShallowCopy[currentMipLevel].fTexelsOrOffset == nullptr) {
732 return false; 887 continue;
733 } 888 }
734 size_t trimRowBytes = width * bpp; 889
735 890 if (texelsShallowCopy[currentMipLevel].fHeight > SK_MaxS32
736 // in case we need a temporary, trimmed copy of the src pixels 891 || texelsShallowCopy[currentMipLevel].fWidth > SK_MaxS32) {
bsalomon 2016/01/11 17:16:38 style nit, || on previous line
Chris Blume 2016/01/12 12:49:34 Done.
737 #if defined(GOOGLE3) 892 return false;
738 // Stack frame size is limited in GOOGLE3. 893 }
739 SkAutoSMalloc<64 * 128> tempStorage; 894 int currentMipHeight = texelsShallowCopy[currentMipLevel].fHeight;
740 #else 895 int currentMipWidth = texelsShallowCopy[currentMipLevel].fWidth;
741 SkAutoSMalloc<128 * 128> tempStorage; 896 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp p, &left, &top,
742 #endif 897 &currentMipWidth,
898 &currentMipHeight,
899 &texelsShallowCopy[currentMipLeve l].fTexelsOrOffset,
900 &texelsShallowCopy[currentMipLeve l].fRowBytes)) {
901 return false;
902 }
903 if (currentMipWidth < 0 || currentMipHeight < 0) {
904 return false;
905 }
906 texelsShallowCopy[currentMipLevel].fWidth = currentMipWidth;
907 texelsShallowCopy[currentMipLevel].fHeight = currentMipHeight;
908 }
743 909
744 // Internal format comes from the texture desc. 910 // Internal format comes from the texture desc.
745 GrGLenum internalFormat = 911 GrGLenum internalFormat = caps.configGLFormats(desc.fConfig).fInternalFormat TexImage;
746 this->glCaps().configGLFormats(desc.fConfig).fInternalFormatTexImage;
747 912
748 // External format and type come from the upload data. 913 // External format and type come from the upload data.
749 GrGLenum externalFormat = 914 GrGLenum externalFormat = caps.configGLFormats(dataConfig).fExternalFormatFo rTexImage;
750 this->glCaps().configGLFormats(dataConfig).fExternalFormatForTexImage; 915 GrGLenum externalType = caps.configGLFormats(dataConfig).fExternalType;
751 GrGLenum externalType = this->glCaps().configGLFormats(dataConfig).fExternal Type; 916
752
753 /*
754 * Check whether to allocate a temporary buffer for flipping y or
755 * because our srcData has extra bytes past each row. If so, we need
756 * to trim those off here, since GL ES may not let us specify
757 * GL_UNPACK_ROW_LENGTH.
758 */
759 bool restoreGLRowLength = false;
760 bool swFlipY = false; 917 bool swFlipY = false;
761 bool glFlipY = false; 918 bool glFlipY = false;
762 if (dataOrOffset) { 919
763 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 920 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
764 if (this->glCaps().unpackFlipYSupport()) { 921 if (caps.unpackFlipYSupport()) {
765 glFlipY = true; 922 glFlipY = true;
766 } else { 923 } else {
767 swFlipY = true; 924 swFlipY = true;
768 } 925 }
769 } 926 }
770 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { 927
928 bool restoreGLRowLength = false;
929
930 // in case we need a temporary, trimmed copy of the src pixels
931 SkAutoSMallocTexels tempStorage;
932
933 // find the combined size of all the mip levels and the relative offset of
934 // each into the collective buffer
935 size_t combined_buffer_size = 0;
936 SkTArray<size_t> individual_mip_offsets(texelsShallowCopy.count());
937 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c urrentMipLevel++) {
938 const size_t trimmedSize = texels[currentMipLevel].fWidth * bpp *
939 texelsShallowCopy[currentMipLevel].fHeight;
940 individual_mip_offsets.push_back(combined_buffer_size);
941 combined_buffer_size += trimmedSize;
942 }
943 char* buffer = (char*)tempStorage.reset(combined_buffer_size);
944
945 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c urrentMipLevel++) {
946 if (texelsShallowCopy[currentMipLevel].fTexelsOrOffset == nullptr) {
947 continue;
948 }
949
950 const size_t trimRowBytes = texelsShallowCopy[currentMipLevel].fWidth * bpp;
951
952 /*
953 * check whether to allocate a temporary buffer for flipping y or
954 * because our srcData has extra bytes past each row. If so, we need
955 * to trim those off here, since GL ES may not let us specify
956 * GL_UNPACK_ROW_LENGTH.
957 */
958 restoreGLRowLength = false;
959
960 const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes;
961 if (caps.unpackRowLengthSupport() && !swFlipY) {
771 // can't use this for flipping, only non-neg values allowed. :( 962 // can't use this for flipping, only non-neg values allowed. :(
772 if (rowBytes != trimRowBytes) { 963 if (rowBytes != trimRowBytes) {
773 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); 964 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
774 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); 965 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLe ngth));
775 restoreGLRowLength = true; 966 restoreGLRowLength = true;
776 } 967 }
777 } else if (kTransfer_UploadType != uploadType) { 968 } else if (kTransfer_UploadType != uploadType) {
778 if (trimRowBytes != rowBytes || swFlipY) { 969 if (trimRowBytes != rowBytes || swFlipY) {
970 const int height = texelsShallowCopy[currentMipLevel].fHeight;
779 // copy data into our new storage, skipping the trailing bytes 971 // copy data into our new storage, skipping the trailing bytes
780 size_t trimSize = height * trimRowBytes; 972 const char* src = (const char*)texelsShallowCopy[currentMipLevel ].fTexelsOrOffset;
781 const char* src = (const char*)dataOrOffset; 973 if (swFlipY && height >= 1) {
782 if (swFlipY) {
783 src += (height - 1) * rowBytes; 974 src += (height - 1) * rowBytes;
784 } 975 }
785 char* dst = (char*)tempStorage.reset(trimSize); 976 char* dst = buffer + individual_mip_offsets[currentMipLevel];
786 for (int y = 0; y < height; y++) { 977 for (int y = 0; y < height; y++) {
787 memcpy(dst, src, trimRowBytes); 978 memcpy(dst, src, trimRowBytes);
788 if (swFlipY) { 979 if (swFlipY) {
789 src -= rowBytes; 980 src -= rowBytes;
790 } else { 981 } else {
791 src += rowBytes; 982 src += rowBytes;
792 } 983 }
793 dst += trimRowBytes; 984 dst += trimRowBytes;
794 } 985 }
795 // now point data to our copied version 986 // now point data to our copied version
796 dataOrOffset = tempStorage.get(); 987 texelsShallowCopy[currentMipLevel] =
988 SkMipMapLevel(buffer + individual_mip_offsets[currentMipLeve l],
989 trimRowBytes,
990 texelsShallowCopy[currentMipLevel].fWidth,
991 texelsShallowCopy[currentMipLevel].fHeight);
797 } 992 }
798 } else { 993 } else {
799 return false; 994 return false;
800 } 995 }
801 if (glFlipY) { 996 if (glFlipY) {
802 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); 997 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
803 } 998 }
804 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(dataConfig) )); 999 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT,
1000 config_alignment(desc.fConfig)));
805 } 1001 }
1002
806 bool succeeded = true; 1003 bool succeeded = true;
807 if (kNewTexture_UploadType == uploadType) { 1004 if (kNewTexture_UploadType == uploadType &&
808 if (dataOrOffset && 1005 0 == left && 0 == top &&
809 !(0 == left && 0 == top && desc.fWidth == width && desc.fHeight == h eight)) { 1006 desc.fWidth == width && desc.fHeight == height) {
810 succeeded = false; 1007 allocate_and_populate_uncompressed_texture(desc, *interface, target, int ernalFormat,
811 } else { 1008 externalFormat, externalType, texelsShallowCopy,
812 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1009 &succeeded);
813 GL_ALLOC_CALL(this->glInterface(), TexImage2D(target, 0, internalFor mat, desc.fWidth,
814 desc.fHeight, 0, exte rnalFormat,
815 externalType, dataOrOf fset));
816 GrGLenum error = check_alloc_error(desc, this->glInterface());
817 if (error != GR_GL_NO_ERROR) {
818 succeeded = false;
819 }
820 }
821 } else { 1010 } else {
822 if (swFlipY || glFlipY) { 1011 if (swFlipY || glFlipY) {
823 top = desc.fHeight - (top + height); 1012 top = desc.fHeight - (top + height);
824 } 1013 }
825 GL_CALL(TexSubImage2D(target, 1014 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count( );
826 0, // level 1015 currentMipLevel++) {
827 left, top, 1016 if (texelsShallowCopy[currentMipLevel].fTexelsOrOffset == nullptr) {
828 width, height, 1017 continue;
829 externalFormat, externalType, dataOrOffset)); 1018 }
1019
1020 GL_CALL(TexSubImage2D(target,
1021 currentMipLevel,
1022 left, top,
1023 texelsShallowCopy[currentMipLevel].fWidth,
1024 texelsShallowCopy[currentMipLevel].fHeight,
1025 externalFormat, externalType,
1026 texelsShallowCopy[currentMipLevel].fTexelsOrOf fset));
1027 }
830 } 1028 }
831 1029
832 if (restoreGLRowLength) { 1030 restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY);
833 SkASSERT(this->glCaps().unpackRowLengthSupport()); 1031
834 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
835 }
836 if (glFlipY) {
837 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
838 }
839 return succeeded; 1032 return succeeded;
840 } 1033 }
841 1034
842 // TODO: This function is using a lot of wonky semantics like, if width == -1 1035 // TODO: This function is using a lot of wonky semantics like, if width == -1
843 // then set width = desc.fWdith ... blah. A better way to do it might be to 1036 // then set width = desc.fWdith ... blah. A better way to do it might be to
844 // create a CompressedTexData struct that takes a desc/ptr and figures out 1037 // create a CompressedTexData struct that takes a desc/ptr and figures out
845 // the proper upload semantics. Then users can construct this function how they 1038 // the proper upload semantics. Then users can construct this function how they
846 // see fit if they want to go against the "standard" way to do it. 1039 // see fit if they want to go against the "standard" way to do it.
847 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, 1040 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
848 GrGLenum target, 1041 GrGLenum target,
849 const void* data, 1042 const SkTArray<SkMipMapLevel>& texels,
1043 bool isNewTexture,
850 UploadType uploadType, 1044 UploadType uploadType,
851 int left, int top, int width, int height) { 1045 int left, int top, int width, int height) {
852 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); 1046 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig));
853 SkASSERT(kTransfer_UploadType != uploadType && 1047 SkASSERT(kTransfer_UploadType != uploadType &&
854 (data || kNewTexture_UploadType != uploadType)); 1048 (texels[0].fTexelsOrOffset || kNewTexture_UploadType != uploadType) );
855 1049
856 // No support for software flip y, yet... 1050 // No support for software flip y, yet...
857 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); 1051 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
858 1052
1053 const GrGLInterface* interface = this->glInterface();
1054 const GrGLCaps& caps = this->glCaps();
1055
859 if (-1 == width) { 1056 if (-1 == width) {
860 width = desc.fWidth; 1057 width = desc.fWidth;
861 } 1058 }
862 #ifdef SK_DEBUG 1059 #ifdef SK_DEBUG
863 else { 1060 else {
864 SkASSERT(width <= desc.fWidth); 1061 SkASSERT(width <= desc.fWidth);
865 } 1062 }
866 #endif 1063 #endif
867 1064
868 if (-1 == height) { 1065 if (-1 == height) {
869 height = desc.fHeight; 1066 height = desc.fHeight;
870 } 1067 }
871 #ifdef SK_DEBUG 1068 #ifdef SK_DEBUG
872 else { 1069 else {
873 SkASSERT(height <= desc.fHeight); 1070 SkASSERT(height <= desc.fHeight);
874 } 1071 }
875 #endif 1072 #endif
876 1073
877 // Make sure that the width and height that we pass to OpenGL
878 // is a multiple of the block size.
879 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height);
880
881 // We only need the internal format for compressed 2D textures. There is on 1074 // We only need the internal format for compressed 2D textures. There is on
882 // sized vs base internal format distinction for compressed textures. 1075 // sized vs base internal format distinction for compressed textures.
883 GrGLenum internalFormat =this->glCaps().configGLFormats(desc.fConfig).fSized InternalFormat; 1076 GrGLenum internalFormat = caps.configGLFormats(desc.fConfig).fInternalFormat TexImage;
884 1077
885 if (kNewTexture_UploadType == uploadType) { 1078 if (kNewTexture_UploadType == uploadType) {
886 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1079 return allocate_and_populate_compressed_texture(desc, *interface, target , internalFormat,
887 GL_ALLOC_CALL(this->glInterface(), 1080 texels);
888 CompressedTexImage2D(target,
889 0, // level
890 internalFormat,
891 width, height,
892 0, // border
893 SkToInt(dataSize),
894 data));
895 GrGLenum error = check_alloc_error(desc, this->glInterface());
896 if (error != GR_GL_NO_ERROR) {
897 return false;
898 }
899 } else { 1081 } else {
900 // Paletted textures can't be updated. 1082 // Paletted textures can't be updated.
901 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { 1083 if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
902 return false; 1084 return false;
903 } 1085 }
904 GL_CALL(CompressedTexSubImage2D(target, 1086 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
905 0, // level 1087 if (texels[currentMipLevel].fTexelsOrOffset == nullptr) {
906 left, top, 1088 continue;
907 width, height, 1089 }
908 internalFormat, 1090
909 SkToInt(dataSize), 1091 // Make sure that the width and height that we pass to OpenGL
910 data)); 1092 // is a multiple of the block size.
1093 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig,
1094 texels[currentMipLevel] .fWidth,
1095 texels[currentMipLevel] .fHeight);
1096 GL_CALL(CompressedTexSubImage2D(target,
1097 currentMipLevel,
1098 left, top,
1099 texels[currentMipLevel].fWidth,
1100 texels[currentMipLevel].fHeight,
1101 internalFormat,
1102 dataSize,
1103 texels[currentMipLevel].fTexelsOrOff set));
1104 }
911 } 1105 }
912 1106
913 return true; 1107 return true;
914 } 1108 }
915 1109
916 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, 1110 static bool renderbuffer_storage_msaa(const GrGLContext& ctx,
917 int sampleCount, 1111 int sampleCount,
918 GrGLenum format, 1112 GrGLenum format,
919 int width, int height) { 1113 int width, int height) {
920 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); 1114 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface());
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 // SkDEBUGFAIL("null texture"); 1261 // SkDEBUGFAIL("null texture");
1068 return nullptr; 1262 return nullptr;
1069 } 1263 }
1070 1264
1071 #if 0 && defined(SK_DEBUG) 1265 #if 0 && defined(SK_DEBUG)
1072 static size_t as_size_t(int x) { 1266 static size_t as_size_t(int x) {
1073 return x; 1267 return x;
1074 } 1268 }
1075 #endif 1269 #endif
1076 1270
1271 static GrGLTexture::IDDesc generate_gl_texture(const GrGLInterface* interface,
1272 GrGpuResource::LifeCycle lifeCycl e) {
1273 GrGLTexture::IDDesc idDesc;
1274 idDesc.fInfo.fID = 0;
1275 GR_GL_CALL(interface, GenTextures(1, &idDesc.fInfo.fID));
1276 idDesc.fLifeCycle = lifeCycle;
1277 // We only support GL_TEXTURE_2D at the moment.
1278 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D;
1279 return idDesc;
1280 }
1281
1282 static GrGLTexture::TexParams set_initial_texture_params(const GrGLInterface* in terface,
1283 GrGLTexture::IDDesc idD esc) {
1284 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
1285 // drivers have a bug where an FBO won't be complete if it includes a
1286 // texture that is not mipmap complete (considering the filter in use).
1287 GrGLTexture::TexParams initialTexParams;
1288 // we only set a subset here so invalidate first
1289 initialTexParams.invalidate();
1290 initialTexParams.fMinFilter = GR_GL_NEAREST;
1291 initialTexParams.fMagFilter = GR_GL_NEAREST;
1292 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1293 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1294 GR_GL_CALL(interface, TexParameteri(idDesc.fInfo.fTarget,
1295 GR_GL_TEXTURE_MAG_FILTER,
1296 initialTexParams.fMagFilter));
1297 GR_GL_CALL(interface, TexParameteri(idDesc.fInfo.fTarget,
1298 GR_GL_TEXTURE_MIN_FILTER,
1299 initialTexParams.fMinFilter));
1300 GR_GL_CALL(interface, TexParameteri(idDesc.fInfo.fTarget,
1301 GR_GL_TEXTURE_WRAP_S,
1302 initialTexParams.fWrapS));
1303 GR_GL_CALL(interface, TexParameteri(idDesc.fInfo.fTarget,
1304 GR_GL_TEXTURE_WRAP_T,
1305 initialTexParams.fWrapT));
1306 return initialTexParams;
1307 }
1308
1077 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, 1309 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
1078 GrGpuResource::LifeCycle lifeCycle, 1310 GrGpuResource::LifeCycle lifeCycle,
1079 const void* srcData, size_t rowBytes) { 1311 const SkTArray<SkMipMapLevel>& texels) {
1080 // We fail if the MSAA was requested and is not available. 1312 // We fail if the MSAA was requested and is not available.
1081 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { 1313 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) {
1082 //SkDebugf("MSAA RT requested but not supported on this platform."); 1314 //SkDebugf("MSAA RT requested but not supported on this platform.");
1083 return return_null_texture(); 1315 return return_null_texture();
1084 } 1316 }
1085 1317
1086 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 1318 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
1087 1319
1088 GrGLTexture::IDDesc idDesc; 1320 GrGLTexture::IDDesc idDesc = generate_gl_texture(this->glInterface(), lifeCy cle);
1089 idDesc.fInfo.fID = 0;
1090 GL_CALL(GenTextures(1, &idDesc.fInfo.fID));
1091 idDesc.fLifeCycle = lifeCycle;
1092 // We only support GL_TEXTURE_2D at the moment.
1093 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D;
1094
1095 if (!idDesc.fInfo.fID) { 1321 if (!idDesc.fInfo.fID) {
1096 return return_null_texture(); 1322 return return_null_texture();
1097 } 1323 }
1098 1324
1099 this->setScratchTextureUnit(); 1325 this->setScratchTextureUnit();
1100 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); 1326 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID));
1101 1327
1102 if (renderTarget && this->glCaps().textureUsageSupport()) { 1328 if (renderTarget && this->glCaps().textureUsageSupport()) {
1103 // provides a hint about how this texture will be used 1329 // provides a hint about how this texture will be used
1104 GL_CALL(TexParameteri(idDesc.fInfo.fTarget, 1330 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1105 GR_GL_TEXTURE_USAGE, 1331 GR_GL_TEXTURE_USAGE,
1106 GR_GL_FRAMEBUFFER_ATTACHMENT)); 1332 GR_GL_FRAMEBUFFER_ATTACHMENT));
1107 } 1333 }
1108 1334
1109 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1335 GrGLTexture::TexParams initialTexParams = set_initial_texture_params(this->g lInterface(),
1110 // drivers have a bug where an FBO won't be complete if it includes a 1336 idDesc) ;
1111 // texture that is not mipmap complete (considering the filter in use). 1337
1112 GrGLTexture::TexParams initialTexParams;
1113 // we only set a subset here so invalidate first
1114 initialTexParams.invalidate();
1115 initialTexParams.fMinFilter = GR_GL_NEAREST;
1116 initialTexParams.fMagFilter = GR_GL_NEAREST;
1117 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1118 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1119 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1120 GR_GL_TEXTURE_MAG_FILTER,
1121 initialTexParams.fMagFilter));
1122 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1123 GR_GL_TEXTURE_MIN_FILTER,
1124 initialTexParams.fMinFilter));
1125 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1126 GR_GL_TEXTURE_WRAP_S,
1127 initialTexParams.fWrapS));
1128 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1129 GR_GL_TEXTURE_WRAP_T,
1130 initialTexParams.fWrapT));
1131 if (!this->uploadTexData(desc, idDesc.fInfo.fTarget, kNewTexture_UploadType, 0, 0, 1338 if (!this->uploadTexData(desc, idDesc.fInfo.fTarget, kNewTexture_UploadType, 0, 0,
1132 desc.fWidth, desc.fHeight, 1339 desc.fWidth, desc.fHeight,
1133 desc.fConfig, srcData, rowBytes)) { 1340 desc.fConfig, texels)) {
1134 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); 1341 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID));
1135 return return_null_texture(); 1342 return return_null_texture();
1136 } 1343 }
1137 1344
1138 GrGLTexture* tex; 1345 GrGLTexture* tex;
1139 if (renderTarget) { 1346 if (renderTarget) {
1140 // unbind the texture from the texture unit before binding it to the fra me buffer 1347 // unbind the texture from the texture unit before binding it to the fra me buffer
1141 GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0)); 1348 GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0));
1142 GrGLRenderTarget::IDDesc rtIDDesc; 1349 GrGLRenderTarget::IDDesc rtIDDesc;
1143 1350
1144 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fInfo, &rtI DDesc)) { 1351 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fInfo, &rtI DDesc)) {
1145 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); 1352 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID));
1146 return return_null_texture(); 1353 return return_null_texture();
1147 } 1354 }
1148 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); 1355 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc);
1149 } else { 1356 } else {
1150 tex = new GrGLTexture(this, desc, idDesc); 1357 bool wasMipMapDataProvided = false;
1358 if (texels.count() > 1) {
1359 wasMipMapDataProvided = true;
1360 }
1361 tex = new GrGLTexture(this, desc, idDesc, wasMipMapDataProvided);
1151 } 1362 }
1152 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1363 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1153 #ifdef TRACE_TEXTURE_CREATION 1364 #ifdef TRACE_TEXTURE_CREATION
1154 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", 1365 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n",
1155 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1366 glTexDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig);
1156 #endif 1367 #endif
1157 return tex; 1368 return tex;
1158 } 1369 }
1159 1370
1160 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, 1371 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc,
1161 GrGpuResource::LifeCycle lifeCycle , 1372 GrGpuResource::LifeCycle lifeCycle ,
1162 const void* srcData) { 1373 const SkTArray<SkMipMapLevel>& tex els) {
1163 // Make sure that we're not flipping Y. 1374 // Make sure that we're not flipping Y.
1164 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 1375 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
1165 return return_null_texture(); 1376 return return_null_texture();
1166 } 1377 }
1167 1378
1168 GrGLTexture::IDDesc idDesc; 1379 GrGLTexture::IDDesc idDesc = generate_gl_texture(this->glInterface(), lifeCy cle);
1169 idDesc.fInfo.fID = 0;
1170 GL_CALL(GenTextures(1, &idDesc.fInfo.fID));
1171 idDesc.fLifeCycle = lifeCycle;
1172 // We only support GL_TEXTURE_2D at the moment.
1173 idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D;
1174
1175 if (!idDesc.fInfo.fID) { 1380 if (!idDesc.fInfo.fID) {
1176 return return_null_texture(); 1381 return return_null_texture();
1177 } 1382 }
1178 1383
1179 this->setScratchTextureUnit(); 1384 this->setScratchTextureUnit();
1180 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID)); 1385 GL_CALL(BindTexture(idDesc.fInfo.fTarget, idDesc.fInfo.fID));
1181 1386
1182 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1387 GrGLTexture::TexParams initialTexParams = set_initial_texture_params(this->g lInterface(),
1183 // drivers have a bug where an FBO won't be complete if it includes a 1388 idDesc) ;
1184 // texture that is not mipmap complete (considering the filter in use).
1185 GrGLTexture::TexParams initialTexParams;
1186 // we only set a subset here so invalidate first
1187 initialTexParams.invalidate();
1188 initialTexParams.fMinFilter = GR_GL_NEAREST;
1189 initialTexParams.fMagFilter = GR_GL_NEAREST;
1190 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1191 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1192 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1193 GR_GL_TEXTURE_MAG_FILTER,
1194 initialTexParams.fMagFilter));
1195 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1196 GR_GL_TEXTURE_MIN_FILTER,
1197 initialTexParams.fMinFilter));
1198 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1199 GR_GL_TEXTURE_WRAP_S,
1200 initialTexParams.fWrapS));
1201 GL_CALL(TexParameteri(idDesc.fInfo.fTarget,
1202 GR_GL_TEXTURE_WRAP_T,
1203 initialTexParams.fWrapT));
1204 1389
1205 if (!this->uploadCompressedTexData(desc, idDesc.fInfo.fTarget, srcData)) { 1390 if (!this->uploadCompressedTexData(desc, idDesc.fInfo.fTarget, texels)) {
1206 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID)); 1391 GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID));
1207 return return_null_texture(); 1392 return return_null_texture();
1208 } 1393 }
1209 1394
1210 GrGLTexture* tex; 1395 GrGLTexture* tex;
1211 tex = new GrGLTexture(this, desc, idDesc); 1396 tex = new GrGLTexture(this, desc, idDesc);
1212 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1397 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1213 #ifdef TRACE_TEXTURE_CREATION 1398 #ifdef TRACE_TEXTURE_CREATION
1214 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", 1399 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n",
1215 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1400 glTexDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig);
1216 #endif 1401 #endif
1217 return tex; 1402 return tex;
1218 } 1403 }
1219 1404
1220 namespace { 1405 namespace {
1221 1406
1222 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; 1407 const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount;
1223 1408
1224 void inline get_stencil_rb_sizes(const GrGLInterface* gl, 1409 void inline get_stencil_rb_sizes(const GrGLInterface* gl,
1225 GrGLStencilAttachment::Format* format) { 1410 GrGLStencilAttachment::Format* format) {
(...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after
2752 viewport->fWidth = surface->width(); 2937 viewport->fWidth = surface->width();
2753 viewport->fHeight = surface->height(); 2938 viewport->fHeight = surface->height();
2754 } else { 2939 } else {
2755 fStats.incRenderTargetBinds(); 2940 fStats.incRenderTargetBinds();
2756 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO ID())); 2941 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO ID()));
2757 *viewport = rt->getViewport(); 2942 *viewport = rt->getViewport();
2758 } 2943 }
2759 } 2944 }
2760 2945
2761 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) { 2946 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) {
2762 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ ets to 2947 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ ets to
2763 if (!surface->asRenderTarget()) { 2948 if (!surface->asRenderTarget()) {
2764 SkASSERT(surface->asTexture()); 2949 SkASSERT(surface->asTexture());
2765 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture()) ->target(); 2950 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture()) ->target();
2766 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, 2951 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
2767 GR_GL_COLOR_ATTACHM ENT0, 2952 GR_GL_COLOR_ATTACHM ENT0,
2768 textureTarget, 2953 textureTarget,
2769 0, 2954 0,
2770 0)); 2955 0));
2771 } 2956 }
2772 } 2957 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2830 } 3015 }
2831 3016
2832 bool GrGLGpu::onCopySurface(GrSurface* dst, 3017 bool GrGLGpu::onCopySurface(GrSurface* dst,
2833 GrSurface* src, 3018 GrSurface* src,
2834 const SkIRect& srcRect, 3019 const SkIRect& srcRect,
2835 const SkIPoint& dstPoint) { 3020 const SkIPoint& dstPoint) {
2836 if (src->asTexture() && dst->asRenderTarget()) { 3021 if (src->asTexture() && dst->asRenderTarget()) {
2837 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); 3022 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
2838 return true; 3023 return true;
2839 } 3024 }
2840 3025
2841 if (can_copy_texsubimage(dst, src, this)) { 3026 if (can_copy_texsubimage(dst, src, this)) {
2842 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); 3027 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
2843 return true; 3028 return true;
2844 } 3029 }
2845 3030
2846 if (can_blit_framebuffer(dst, src, this)) { 3031 if (can_blit_framebuffer(dst, src, this)) {
2847 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); 3032 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
2848 } 3033 }
2849 3034
2850 return false; 3035 return false;
(...skipping 22 matching lines...) Expand all
2873 3058
2874 SkString vshaderTxt(version); 3059 SkString vshaderTxt(version);
2875 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3060 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2876 vshaderTxt.append(";"); 3061 vshaderTxt.append(";");
2877 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3062 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2878 vshaderTxt.append(";"); 3063 vshaderTxt.append(";");
2879 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3064 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2880 vshaderTxt.append(";"); 3065 vshaderTxt.append(";");
2881 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3066 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2882 vshaderTxt.append(";"); 3067 vshaderTxt.append(";");
2883 3068
2884 vshaderTxt.append( 3069 vshaderTxt.append(
2885 "// Copy Program VS\n" 3070 "// Copy Program VS\n"
2886 "void main() {" 3071 "void main() {"
2887 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.z w;" 3072 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.z w;"
2888 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" 3073 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
2889 " gl_Position.zw = vec2(0, 1);" 3074 " gl_Position.zw = vec2(0, 1);"
2890 "}" 3075 "}"
2891 ); 3076 );
2892 3077
2893 SkString fshaderTxt(version); 3078 SkString fshaderTxt(version);
(...skipping 18 matching lines...) Expand all
2912 fsOutName = "gl_FragColor"; 3097 fsOutName = "gl_FragColor";
2913 } 3098 }
2914 fshaderTxt.appendf( 3099 fshaderTxt.appendf(
2915 "// Copy Program FS\n" 3100 "// Copy Program FS\n"
2916 "void main() {" 3101 "void main() {"
2917 " %s = %s(u_texture, v_texCoord);" 3102 " %s = %s(u_texture, v_texCoord);"
2918 "}", 3103 "}",
2919 fsOutName, 3104 fsOutName,
2920 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) 3105 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration())
2921 ); 3106 );
2922 3107
2923 GL_CALL_RET(fCopyPrograms[i].fProgram, CreateProgram()); 3108 GL_CALL_RET(fCopyPrograms[i].fProgram, CreateProgram());
2924 const char* str; 3109 const char* str;
2925 GrGLint length; 3110 GrGLint length;
2926 3111
2927 str = vshaderTxt.c_str(); 3112 str = vshaderTxt.c_str();
2928 length = SkToInt(vshaderTxt.size()); 3113 length = SkToInt(vshaderTxt.size());
2929 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms [i].fProgram, 3114 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms [i].fProgram,
2930 GR_GL_VERTEX_SHADER, &str, &length, 1, 3115 GR_GL_VERTEX_SHADER, &str, &length, 1,
2931 &fStats); 3116 &fStats);
2932 3117
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
3427 this->setVertexArrayID(gpu, 0); 3612 this->setVertexArrayID(gpu, 0);
3428 } 3613 }
3429 int attrCount = gpu->glCaps().maxVertexAttributes(); 3614 int attrCount = gpu->glCaps().maxVertexAttributes();
3430 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3615 if (fDefaultVertexArrayAttribState.count() != attrCount) {
3431 fDefaultVertexArrayAttribState.resize(attrCount); 3616 fDefaultVertexArrayAttribState.resize(attrCount);
3432 } 3617 }
3433 attribState = &fDefaultVertexArrayAttribState; 3618 attribState = &fDefaultVertexArrayAttribState;
3434 } 3619 }
3435 return attribState; 3620 return attribState;
3436 } 3621 }
OLDNEW
« src/gpu/SkGr.cpp ('K') | « src/gpu/gl/GrGLGpu.h ('k') | src/gpu/gl/GrGLTexture.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698