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

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: Fixing bad rebase. Created 5 years, 1 month 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)
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 // We only support GL_TEXTURE_2D at the moment. 431 // We only support GL_TEXTURE_2D at the moment.
431 idDesc.fTarget = GR_GL_TEXTURE_2D; 432 idDesc.fTarget = GR_GL_TEXTURE_2D;
432 433
433 switch (ownership) { 434 switch (ownership) {
434 case kAdopt_GrWrapOwnership: 435 case kAdopt_GrWrapOwnership:
435 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; 436 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
436 break; 437 break;
437 case kBorrow_GrWrapOwnership: 438 case kBorrow_GrWrapOwnership:
438 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; 439 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
439 break; 440 break;
440 } 441 }
441 442
442 // next line relies on GrBackendTextureDesc's flags matching GrTexture's 443 // next line relies on GrBackendTextureDesc's flags matching GrTexture's
443 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; 444 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags;
444 surfDesc.fWidth = desc.fWidth; 445 surfDesc.fWidth = desc.fWidth;
445 surfDesc.fHeight = desc.fHeight; 446 surfDesc.fHeight = desc.fHeight;
446 surfDesc.fConfig = desc.fConfig; 447 surfDesc.fConfig = desc.fConfig;
447 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() ); 448 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() );
448 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g); 449 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g);
449 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly 450 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly
450 // assuming the old behaviour, which is that backend textures are always 451 // assuming the old behaviour, which is that backend textures are always
(...skipping 29 matching lines...) Expand all
480 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); 481 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle);
481 idDesc.fMSColorRenderbufferID = 0; 482 idDesc.fMSColorRenderbufferID = 0;
482 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; 483 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
483 switch (ownership) { 484 switch (ownership) {
484 case kAdopt_GrWrapOwnership: 485 case kAdopt_GrWrapOwnership:
485 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; 486 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
486 break; 487 break;
487 case kBorrow_GrWrapOwnership: 488 case kBorrow_GrWrapOwnership:
488 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; 489 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
489 break; 490 break;
490 } 491 }
491 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; 492 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig;
492 493
493 GrSurfaceDesc desc; 494 GrSurfaceDesc desc;
494 desc.fConfig = wrapDesc.fConfig; 495 desc.fConfig = wrapDesc.fConfig;
495 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; 496 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag;
496 desc.fWidth = wrapDesc.fWidth; 497 desc.fWidth = wrapDesc.fWidth;
497 desc.fHeight = wrapDesc.fHeight; 498 desc.fHeight = wrapDesc.fHeight;
498 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); 499 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() );
499 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); 500 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true);
500 501
501 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits); 502 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits);
502 } 503 }
503 504
504 //////////////////////////////////////////////////////////////////////////////// 505 ////////////////////////////////////////////////////////////////////////////////
505 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 506 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
506 size_t rowBytes, GrPixelConfig srcConfig, 507 GrPixelConfig srcConfig,
507 DrawPreference* drawPreference, 508 DrawPreference* drawPreference,
508 WritePixelTempDrawInfo* tempDrawInfo) { 509 WritePixelTempDrawInfo* tempDrawInfo) {
509 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { 510 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) {
510 return false; 511 return false;
511 } 512 }
512 513
513 // This subclass only allows writes to textures. If the dst is not a texture we have to draw 514 // This subclass only allows writes to textures. If the dst is not a texture we have to draw
514 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. 515 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y.
515 if (!dstSurface->asTexture()) { 516 if (!dstSurface->asTexture()) {
516 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 517 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 if (!this->glCaps().unpackFlipYSupport() && 557 if (!this->glCaps().unpackFlipYSupport() &&
557 kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) { 558 kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) {
558 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 559 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
559 } 560 }
560 561
561 return true; 562 return true;
562 } 563 }
563 564
564 bool GrGLGpu::onWritePixels(GrSurface* surface, 565 bool GrGLGpu::onWritePixels(GrSurface* surface,
565 int left, int top, int width, int height, 566 int left, int top, int width, int height,
566 GrPixelConfig config, const void* buffer, 567 GrPixelConfig config,
567 size_t rowBytes) { 568 const SkTArray<SkMipMapLevel>& texels) {
568 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); 569 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
569 if (!glTex) { 570 if (!glTex) {
570 return false; 571 return false;
571 } 572 }
572 573
573 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels. 574 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels.
574 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 575 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
575 return false; 576 return false;
576 } 577 }
577 578
578 this->setScratchTextureUnit(); 579 this->setScratchTextureUnit();
579 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); 580 GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
580 581
581 bool success = false; 582 bool success = false;
582 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { 583 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
583 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() 584 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s()
584 SkASSERT(config == glTex->desc().fConfig); 585 SkASSERT(config == glTex->desc().fConfig);
585 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), buffer, false, left, 586 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(), texels, false,
586 top, width, height); 587 left, top, width, height);
587 } else { 588 } else {
588 success = this->uploadTexData(glTex->desc(), glTex->target(), false, lef t, top, width, 589 success = this->uploadTexData(glTex->desc(), glTex->target(), false, lef t, top, width,
589 height, config, buffer, rowBytes); 590 height, config, texels);
590 } 591 }
591 592
592 if (success) { 593 return success;
593 glTex->texturePriv().dirtyMipMaps(true);
594 return true;
595 }
596
597 return false;
598 } 594 }
599 595
600 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, 596 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
601 const GrGLInterface* interface) { 597 const GrGLInterface* interface) {
602 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { 598 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) {
603 return GR_GL_GET_ERROR(interface); 599 return GR_GL_GET_ERROR(interface);
604 } else { 600 } else {
605 return CHECK_ALLOC_ERROR(interface); 601 return CHECK_ALLOC_ERROR(interface);
606 } 602 }
607 } 603 }
608 604
609 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, 605 /**
610 GrGLenum target, 606 * Determines if TexStorage can be used when creating a texture.
611 bool isNewTexture, 607 *
612 int left, int top, int width, int height, 608 * @param caps The capabilities of the GL device.
613 GrPixelConfig dataConfig, 609 * @param standard The GL standard in use.
614 const void* data, 610 * @param desc The surface descriptor for the texture being created.
615 size_t rowBytes) { 611 */
616 SkASSERT(data || isNewTexture); 612 static bool can_use_tex_storage(const GrGLCaps& caps, const GrGLStandard& standa rd,
617 613 const GrSurfaceDesc& desc) {
618 // If we're uploading compressed data then we should be using uploadCompress edTexData 614 bool useTexStorage = caps.texStorageSupport();
619 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); 615 if (useTexStorage && kGL_GrGLStandard == standard) {
620
621 size_t bpp = GrBytesPerPixel(dataConfig);
622 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, & left, &top,
623 &width, &height, &data, &rowBytes )) {
624 return false;
625 }
626 size_t trimRowBytes = width * bpp;
627
628 // in case we need a temporary, trimmed copy of the src pixels
629 #if defined(GOOGLE3)
630 // Stack frame size is limited in GOOGLE3.
631 SkAutoSMalloc<64 * 128> tempStorage;
632 #else
633 SkAutoSMalloc<128 * 128> tempStorage;
634 #endif
635
636 // We currently lazily create MIPMAPs when the we see a draw with
637 // GrTextureParams::kMipMap_FilterMode. Using texture storage requires that the
638 // MIP levels are all created when the texture is created. So for now we don 't use
639 // texture storage.
640 bool useTexStorage = false &&
641 isNewTexture &&
642 this->glCaps().texStorageSupport();
643
644 if (useTexStorage && kGL_GrGLStandard == this->glStandard()) {
645 // 565 is not a sized internal format on desktop GL. So on desktop with 616 // 565 is not a sized internal format on desktop GL. So on desktop with
646 // 565 we always use an unsized internal format to let the system pick 617 // 565 we always use an unsized internal format to let the system pick
647 // the best sized format to convert the 565 data to. Since TexStorage 618 // the best sized format to convert the 565 data to. Since TexStorage
648 // only allows sized internal formats we will instead use TexImage2D. 619 // only allows sized internal formats we will instead use TexImage2D.
649 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; 620 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig;
650 } 621 }
651 622
652 GrGLenum internalFormat = 0x0; // suppress warning 623 return useTexStorage;
653 GrGLenum externalFormat = 0x0; // suppress warning 624 }
654 GrGLenum externalType = 0x0; // suppress warning
655 625
626 /**
627 * Determines if sized internal formats are available for the texture being crea ted.
628 *
629 * @param useTexStorage The result of a call to can_use_tex_storage().
630 * @param caps The capabilities of the GL device.
631 * @param standard The GL standard in use.
632 * @param version The GL version in use.
633 * @param dataConfig The pixel configuration for the texture being created.
634 */
635 static bool can_use_sized_format(bool useTexStorage, const GrGLCaps& caps,
636 const GrGLStandard& standard, const GrGLVersion & version,
637 GrPixelConfig dataConfig) {
656 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized 638 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized
657 // format for glTexImage, unlike ES3 and desktop. 639 // format for glTexImage, unlike ES3 and desktop.
658 bool useSizedFormat = useTexStorage; 640 bool useSizedFormat = useTexStorage;
659 if (kGL_GrGLStandard == this->glStandard() || 641 if (kGL_GrGLStandard == standard ||
660 (this->glVersion() >= GR_GL_VER(3, 0) && 642 (version >= GR_GL_VER(3, 0) &&
661 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled 643 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled
662 (kBGRA_8888_GrPixelConfig != dataConfig || !this->glCaps().bgraIsIntern alFormat()))) { 644 (kBGRA_8888_GrPixelConfig != dataConfig || !caps.bgraIsInternalFormat() ))) {
663 useSizedFormat = true; 645 useSizedFormat = true;
664 } 646 }
665 647
666 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, 648 return useSizedFormat;
667 &externalFormat, &externalType)) { 649 }
668 return false;
669 }
670 650
671 /* 651 /**
672 * check whether to allocate a temporary buffer for flipping y or 652 * Prior to a texture being created, the image may need to be flipped vertically . This function
673 * because our srcData has extra bytes past each row. If so, we need 653 * prepares the texels for texture creation.
674 * to trim those off here, since GL ES may not let us specify 654 *
675 * GL_UNPACK_ROW_LENGTH. 655 * @param desc The surface descriptor for the texture being create d.
676 */ 656 * @param caps The capabilities of the GL device.
677 bool restoreGLRowLength = false; 657 * @param interface The GL interface in use.
678 bool swFlipY = false; 658 * @param swFlipY Should software be used when flipping a texture ver tically?
679 bool glFlipY = false; 659 * @param glFlipY Should GL be used when flipping a texture verticall y?
680 if (data) { 660 * @param width The width of the texture in texels.
681 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 661 * @param height The height of the texture in texels.
682 if (this->glCaps().unpackFlipYSupport()) { 662 * @param bpp The bits per pixel (or texel, really) of the textur e.
683 glFlipY = true; 663 * @param texels An array of mipmap levels which contain the texel d ata at that level.
684 } else { 664 * @param tempStorage In the case where the image needs to be flipped ver tically, it will
685 swFlipY = true; 665 * use tempStorage as a buffer.
686 } 666 * @param restoreGLRowLength After the texture is created, will the GL row lengt h unpacking need
667 * to be restored?
668 */
669 static void prepare_image_for_writing_to_texture(const GrSurfaceDesc& desc, cons t GrGLCaps& caps,
670 const GrGLInterface& interface, bool swFlipY,
671 bool glFlipY, int bpp,
672 SkTArray<SkMipMapLevel>& texels ,
673 #if defined(GOOGLE3)
674 // Stack frame size is limited in GOOGLE3.
675 SkAutoSMalloc<64 * 128>& tempSt orage,
676 #else
677 SkAutoSMalloc<128 * 128>& tempS torage,
678 #endif
679 bool* restoreGLRowLength) {
680 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) {
681 if (texels[currentMipLevel].fTexels == nullptr) {
682 continue;
687 } 683 }
688 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { 684
685 const size_t trimRowBytes = texels[currentMipLevel].fWidth * bpp;
686
687 /*
688 * check whether to allocate a temporary buffer for flipping y or
689 * because our srcData has extra bytes past each row. If so, we need
690 * to trim those off here, since GL ES may not let us specify
691 * GL_UNPACK_ROW_LENGTH.
692 */
693 *restoreGLRowLength = false;
694
695 const size_t rowBytes = texels[currentMipLevel].fRowBytes;
696 if (caps.unpackRowLengthSupport() && !swFlipY) {
689 // can't use this for flipping, only non-neg values allowed. :( 697 // can't use this for flipping, only non-neg values allowed. :(
690 if (rowBytes != trimRowBytes) { 698 if (rowBytes != trimRowBytes) {
691 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); 699 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
692 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); 700 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowL ength));
693 restoreGLRowLength = true; 701 *restoreGLRowLength = true;
694 } 702 }
695 } else { 703 } else {
696 if (trimRowBytes != rowBytes || swFlipY) { 704 if (trimRowBytes != rowBytes || swFlipY) {
705 const uint32_t height = texels[currentMipLevel].fHeight;
697 // copy data into our new storage, skipping the trailing bytes 706 // copy data into our new storage, skipping the trailing bytes
698 size_t trimSize = height * trimRowBytes; 707 const size_t trimSize = height * trimRowBytes;
699 const char* src = (const char*)data; 708 const char* src = (const char*)texels[currentMipLevel].fTexels;
700 if (swFlipY) { 709 if (swFlipY && height >= 1) {
701 src += (height - 1) * rowBytes; 710 src += (height - 1) * rowBytes;
702 } 711 }
703 char* dst = (char*)tempStorage.reset(trimSize); 712 char* dst = (char*)tempStorage.reset(trimSize);
704 for (int y = 0; y < height; y++) { 713 for (uint32_t y = 0; y < height; y++) {
705 memcpy(dst, src, trimRowBytes); 714 memcpy(dst, src, trimRowBytes);
706 if (swFlipY) { 715 if (swFlipY) {
707 src -= rowBytes; 716 src -= rowBytes;
708 } else { 717 } else {
709 src += rowBytes; 718 src += rowBytes;
710 } 719 }
711 dst += trimRowBytes; 720 dst += trimRowBytes;
712 } 721 }
713 // now point data to our copied version 722 // now point data to our copied version
714 data = tempStorage.get(); 723 texels[currentMipLevel] = SkMipMapLevel(tempStorage.get(), trimR owBytes,
724 texels[currentMipLevel]. fWidth,
725 texels[currentMipLevel]. fHeight);
715 } 726 }
716 } 727 }
717 if (glFlipY) { 728 if (glFlipY) {
718 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); 729 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)) ;
719 } 730 }
720 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 731 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT,
721 static_cast<GrGLint>(GrUnpackAlignment(dataConfig)))); 732 static_cast<GrGLint>(GrUnpackAlignmen t(desc.fConfig))));
722 } 733 }
734 }
735
736 /**
737 * Creates storage space for the texture and fills it with texels.
738 *
739 * @param desc The surface descriptor for the texture being created.
740 * @param interface The GL interface in use.
741 * @param useTexStorage The result of a call to can_use_tex_storage().
742 * @param internalFormat The data format used for the internal storage of the te xture.
743 * @param externalFormat The data format used for the external storage of the te xture.
744 * @param externalType The type of the data used for the external storage of t he texture.
745 * @param texels The texel data of the texture being created.
746 * @param succeeded Set to true if allocating and populating the texture co mpleted
747 * without error.
748 */
749 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc ,
750 const GrGLInterface& inte rface,
751 GrGLenum target,
752 bool useTexStorage,
753 GrGLenum internalFormat,
754 GrGLenum externalFormat,
755 GrGLenum externalType,
756 const SkTArray<SkMipMapLe vel>& texels,
757 bool* succeeded) {
758 CLEAR_ERROR_BEFORE_ALLOC(&interface);
759 if (useTexStorage) {
760 // We never resize or change formats of textures.
761 GL_ALLOC_CALL(&interface,
762 TexStorage2D(target,
763 texels.count(),
764 internalFormat,
765 desc.fWidth, desc.fHeight));
766
767 GrGLenum error = check_alloc_error(desc, &interface);
768 if (error != GR_GL_NO_ERROR) {
769 *succeeded = false;
770 } else {
771 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr entMipLevel++) {
772 const void* currentMipData = texels[currentMipLevel].fTexels;
773 if (currentMipData == nullptr) {
774 continue;
775 }
776
777 GR_GL_CALL(&interface,
778 TexSubImage2D(target,
779 currentMipLevel,
780 0, // left
781 0, // top
782 texels[currentMipLevel].fWidth,
783 texels[currentMipLevel].fHeight,
784 externalFormat, externalType,
785 currentMipData));
786 }
787 *succeeded = true;
788 }
789 } else {
790 *succeeded = true;
791 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
792 GL_ALLOC_CALL(&interface,
793 TexImage2D(target,
794 currentMipLevel,
795 internalFormat,
796 texels[currentMipLevel].fWidth,
797 texels[currentMipLevel].fHeight,
798 0, // border
799 externalFormat, externalType,
800 texels[currentMipLevel].fTexels));
801 GrGLenum error = check_alloc_error(desc, &interface);
802 if (error != GR_GL_NO_ERROR) {
803 *succeeded = false;
804 break;
805 }
806 }
807 }
808 }
809
810 /**
811 * Creates storage space for the texture and fills it with texels.
812 *
813 * @param desc The surface descriptor for the texture being created.
814 * @param interface The GL interface in use.
815 * @param useTexStorage The result of a call to can_use_tex_storage().
816 * @param internalFormat The data format used for the internal storage of the te xture.
817 * @param texels The texel data of the texture being created.
818 */
819 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc,
820 const GrGLInterface& interf ace,
821 GrGLenum target,
822 bool useTexStorage, GrGLenu m internalFormat,
823 const SkTArray<SkMipMapLeve l>& texels) {
824 CLEAR_ERROR_BEFORE_ALLOC(&interface);
825 if (useTexStorage) {
826 // We never resize or change formats of textures.
827 GL_ALLOC_CALL(&interface,
828 TexStorage2D(target,
829 texels.count(),
830 internalFormat,
831 desc.fWidth, desc.fHeight));
832 GrGLenum error = check_alloc_error(desc, &interface);
833 if (error != GR_GL_NO_ERROR) {
834 return false;
835 } else {
836 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr entMipLevel++) {
837 const void* currentMipData = texels[currentMipLevel].fTexels;
838 if (currentMipData == nullptr) {
839 continue;
840 }
841
842 const uint32_t width = texels[currentMipLevel].fWidth;
843 const uint32_t height = texels[currentMipLevel].fHeight;
844
845 // Make sure that the width and height that we pass to OpenGL
846 // is a multiple of the block size.
847 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width , height);
848 GR_GL_CALL(&interface, CompressedTexSubImage2D(target,
849 currentMipLevel,
850 0, // left
851 0, // top
852 width, height,
853 internalFormat, S kToInt(dataSize),
854 currentMipData));
855 }
856 }
857 } else {
858 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
859 const uint32_t width = texels[currentMipLevel].fWidth;
860 const uint32_t height = texels[currentMipLevel].fHeight;
861
862 // Make sure that the width and height that we pass to OpenGL
863 // is a multiple of the block size.
864 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, he ight);
865
866 GL_ALLOC_CALL(&interface,
867 CompressedTexImage2D(target,
868 texels.count(),
869 internalFormat,
870 width, height,
871 0, // border
872 SkToInt(dataSize),
873 texels[currentMipLevel].fTexels)) ;
874
875 GrGLenum error = check_alloc_error(desc, &interface);
876 if (error != GR_GL_NO_ERROR) {
877 return false;
878 }
879 }
880 }
881 return true;
882 }
883
884 /**
885 * After a texture is created, any state which was altered during its creation
886 * needs to be restored.
887 *
888 * @param interface The GL interface to use.
889 * @param caps The capabilities of the GL device.
890 * @param restoreGLRowLength Should the row length unpacking be restored?
891 * @param glFlipY Did GL flip the texture vertically?
892 */
893 static void restore_pixelstore_state(const GrGLInterface& interface, const GrGLC aps& caps,
894 bool restoreGLRowLength, bool glFlipY) {
895 if (restoreGLRowLength) {
896 SkASSERT(caps.unpackRowLengthSupport());
897 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
898 }
899 if (glFlipY) {
900 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
901 }
902 }
903
904 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc,
905 GrGLenum target,
906 bool isNewTexture,
907 int left, int top, int width, int height,
908 GrPixelConfig dataConfig,
909 const SkTArray<SkMipMapLevel>& texels) {
910 // If we're uploading compressed data then we should be using uploadCompress edTexData
911 SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
912
913 SkTArray<SkMipMapLevel> texelsCopy(texels);
914
915 for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; cur rentMipLevel--) {
916 //SkASSERT(texelsCopy[currentMipLevel].fTexels || isNewTexture);
917 }
918
919
920 const GrGLInterface* interface = this->glInterface();
921 const GrGLCaps& caps = this->glCaps();
922 GrGLStandard standard = this->glStandard();
923 GrGLVersion version = this->glVersion();
924
925 size_t bpp = GrBytesPerPixel(dataConfig);
926 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) {
927 if (texelsCopy[currentMipLevel].fTexels == nullptr) {
928 continue;
929 }
930
931 if (texelsCopy[currentMipLevel].fHeight > SK_MaxS32
932 || texelsCopy[currentMipLevel].fWidth > SK_MaxS32) {
933 return false;
934 }
935 int currentMipHeight = texelsCopy[currentMipLevel].fHeight;
936 int currentMipWidth = texelsCopy[currentMipLevel].fWidth;
937 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp p, &left, &top,
938 &currentMipWidth,
939 &currentMipHeight,
940 &texelsCopy[currentMipLevel].fTex els,
941 &texelsCopy[currentMipLevel].fRow Bytes)) {
942 return false;
943 }
944 if (currentMipWidth < 0 || currentMipHeight < 0) {
945 return false;
946 }
947 texelsCopy[currentMipLevel].fWidth = currentMipWidth;
948 texelsCopy[currentMipLevel].fHeight = currentMipHeight;
949 }
950
951 bool useTexStorage = can_use_tex_storage(caps, standard, desc);
952 bool useSizedFormat = can_use_sized_format(useTexStorage, caps, standard, ve rsion, dataConfig);
953
954 GrGLenum internalFormat = 0x0; // suppress warning
955 GrGLenum externalFormat = 0x0; // suppress warning
956 GrGLenum externalType = 0x0; // suppress warning
957
958 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat,
959 &externalFormat, &externalType)) {
960 return false;
961 }
962
963 bool swFlipY = false;
964 bool glFlipY = false;
965
966 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
967 if (caps.unpackFlipYSupport()) {
968 glFlipY = true;
969 } else {
970 swFlipY = true;
971 }
972 }
973
974 bool restoreGLRowLength = false;
975
976 // in case we need a temporary, trimmed copy of the src pixels
977 #if defined(GOOGLE3)
978 // Stack frame size is limited in GOOGLE3.
979 SkAutoSMalloc<64 * 128> tempStorage;
980 #else
981 SkAutoSMalloc<128 * 128> tempStorage;
982 #endif
983
984 prepare_image_for_writing_to_texture(desc, caps, *interface, swFlipY, glFlip Y, bpp, texelsCopy,
985 tempStorage, &restoreGLRowLength);
723 bool succeeded = true; 986 bool succeeded = true;
724 if (isNewTexture && 987 if (isNewTexture &&
725 0 == left && 0 == top && 988 0 == left && 0 == top &&
726 desc.fWidth == width && desc.fHeight == height) { 989 desc.fWidth == width && desc.fHeight == height) {
727 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 990 allocate_and_populate_uncompressed_texture(desc, *interface, useTexStora ge, internalFormat,
728 if (useTexStorage) { 991 externalFormat, externalType, target,
729 // We never resize or change formats of textures. 992 texelsCopy, &succeeded);
730 GL_ALLOC_CALL(this->glInterface(),
731 TexStorage2D(target,
732 1, // levels
733 internalFormat,
734 desc.fWidth, desc.fHeight));
735 } else {
736 GL_ALLOC_CALL(this->glInterface(),
737 TexImage2D(target,
738 0, // level
739 internalFormat,
740 desc.fWidth, desc.fHeight,
741 0, // border
742 externalFormat, externalType,
743 data));
744 }
745 GrGLenum error = check_alloc_error(desc, this->glInterface());
746 if (error != GR_GL_NO_ERROR) {
747 succeeded = false;
748 } else {
749 // if we have data and we used TexStorage to create the texture, we
750 // now upload with TexSubImage.
751 if (data && useTexStorage) {
752 GL_CALL(TexSubImage2D(target,
753 0, // level
754 left, top,
755 width, height,
756 externalFormat, externalType,
757 data));
758 }
759 }
760 } else { 993 } else {
761 if (swFlipY || glFlipY) { 994 if (swFlipY || glFlipY) {
762 top = desc.fHeight - (top + height); 995 top = desc.fHeight - (top + height);
763 } 996 }
764 GL_CALL(TexSubImage2D(target, 997 for (int currentMipLevel = 0; currentMipLevel < texelsCopy.count(); curr entMipLevel++) {
765 0, // level 998 if (texelsCopy[currentMipLevel].fTexels == nullptr) {
766 left, top, 999 continue;
767 width, height, 1000 }
768 externalFormat, externalType, data)); 1001
769 } 1002 GL_CALL(TexSubImage2D(target,
770 1003 currentMipLevel,
771 if (restoreGLRowLength) { 1004 left, top,
772 SkASSERT(this->glCaps().unpackRowLengthSupport()); 1005 texelsCopy[currentMipLevel].fWidth,
773 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); 1006 texelsCopy[currentMipLevel].fHeight,
774 } 1007 externalFormat, externalType,
775 if (glFlipY) { 1008 texelsCopy[currentMipLevel].fTexels));
776 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); 1009 }
777 } 1010 }
1011
1012 restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY);
1013
778 return succeeded; 1014 return succeeded;
779 } 1015 }
780 1016
781 // TODO: This function is using a lot of wonky semantics like, if width == -1 1017 // TODO: This function is using a lot of wonky semantics like, if width == -1
782 // then set width = desc.fWdith ... blah. A better way to do it might be to 1018 // then set width = desc.fWdith ... blah. A better way to do it might be to
783 // create a CompressedTexData struct that takes a desc/ptr and figures out 1019 // create a CompressedTexData struct that takes a desc/ptr and figures out
784 // the proper upload semantics. Then users can construct this function how they 1020 // the proper upload semantics. Then users can construct this function how they
785 // see fit if they want to go against the "standard" way to do it. 1021 // see fit if they want to go against the "standard" way to do it.
786 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, 1022 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc,
787 GrGLenum target, 1023 GrGLenum target,
788 const void* data, 1024 const SkTArray<SkMipMapLevel>& texels,
789 bool isNewTexture, 1025 bool isNewTexture,
790 int left, int top, int width, int height) { 1026 int left, int top, int width, int height) {
791 SkASSERT(data || isNewTexture); 1027 SkASSERT(isNewTexture);
792 1028
793 // No support for software flip y, yet... 1029 // No support for software flip y, yet...
794 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); 1030 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
795 1031
1032 const GrGLInterface* interface = this->glInterface();
1033 const GrGLCaps& caps = this->glCaps();
1034 GrGLStandard standard = this->glStandard();
1035
796 if (-1 == width) { 1036 if (-1 == width) {
797 width = desc.fWidth; 1037 width = desc.fWidth;
798 } 1038 }
799 #ifdef SK_DEBUG 1039 #ifdef SK_DEBUG
800 else { 1040 else {
801 SkASSERT(width <= desc.fWidth); 1041 SkASSERT(width <= desc.fWidth);
802 } 1042 }
803 #endif 1043 #endif
804 1044
805 if (-1 == height) { 1045 if (-1 == height) {
806 height = desc.fHeight; 1046 height = desc.fHeight;
807 } 1047 }
808 #ifdef SK_DEBUG 1048 #ifdef SK_DEBUG
809 else { 1049 else {
810 SkASSERT(height <= desc.fHeight); 1050 SkASSERT(height <= desc.fHeight);
811 } 1051 }
812 #endif 1052 #endif
813 1053
814 // Make sure that the width and height that we pass to OpenGL 1054 bool useTexStorage = can_use_tex_storage(caps, standard, desc);
815 // is a multiple of the block size.
816 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height);
817 1055
818 // We only need the internal format for compressed 2D textures. 1056 // We only need the internal format for compressed 2D textures.
819 GrGLenum internalFormat = 0; 1057 GrGLenum internalFormat = 0;
820 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, nullptr, nullptr)) { 1058 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, nullptr, nullptr)) {
821 return false; 1059 return false;
822 } 1060 }
823 1061
824 if (isNewTexture) { 1062 if (isNewTexture) {
825 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1063 return allocate_and_populate_compressed_texture(desc, *interface, target , useTexStorage,
826 GL_ALLOC_CALL(this->glInterface(), 1064 internalFormat, texels);
827 CompressedTexImage2D(target,
828 0, // level
829 internalFormat,
830 width, height,
831 0, // border
832 SkToInt(dataSize),
833 data));
834 GrGLenum error = check_alloc_error(desc, this->glInterface());
835 if (error != GR_GL_NO_ERROR) {
836 return false;
837 }
838 } else { 1065 } else {
839 // Paletted textures can't be updated. 1066 // Paletted textures can't be updated.
840 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { 1067 if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
841 return false; 1068 return false;
842 } 1069 }
843 GL_CALL(CompressedTexSubImage2D(target, 1070 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
844 0, // level 1071 if (texels[currentMipLevel].fTexels == nullptr) {
845 left, top, 1072 continue;
846 width, height, 1073 }
847 internalFormat, 1074
848 SkToInt(dataSize), 1075 // Make sure that the width and height that we pass to OpenGL
849 data)); 1076 // is a multiple of the block size.
1077 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig,
1078 texels[currentMipLevel] .fWidth,
1079 texels[currentMipLevel] .fHeight);
1080 GL_CALL(CompressedTexSubImage2D(target,
1081 currentMipLevel,
1082 left, top,
1083 texels[currentMipLevel].fWidth,
1084 texels[currentMipLevel].fHeight,
1085 internalFormat,
1086 dataSize,
1087 texels[currentMipLevel].fTexels));
1088 }
850 } 1089 }
851 1090
852 return true; 1091 return true;
853 } 1092 }
854 1093
855 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, 1094 static bool renderbuffer_storage_msaa(const GrGLContext& ctx,
856 int sampleCount, 1095 int sampleCount,
857 GrGLenum format, 1096 GrGLenum format,
858 int width, int height) { 1097 int width, int height) {
859 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); 1098 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface());
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 // SkDEBUGFAIL("null texture"); 1247 // SkDEBUGFAIL("null texture");
1009 return nullptr; 1248 return nullptr;
1010 } 1249 }
1011 1250
1012 #if 0 && defined(SK_DEBUG) 1251 #if 0 && defined(SK_DEBUG)
1013 static size_t as_size_t(int x) { 1252 static size_t as_size_t(int x) {
1014 return x; 1253 return x;
1015 } 1254 }
1016 #endif 1255 #endif
1017 1256
1257 static GrGLTexture::IDDesc generate_and_bind_gl_texture(const GrGLInterface* int erface,
1258 GrGpuResource::LifeCycle lifeCycle) {
1259 GrGLTexture::IDDesc idDesc;
1260 GR_GL_CALL(interface, GenTextures(1, &idDesc.fTextureID));
1261 idDesc.fLifeCycle = lifeCycle;
1262 // We only support GL_TEXTURE_2D at the moment.
1263 idDesc.fTarget = GR_GL_TEXTURE_2D;
1264 return idDesc;
1265 }
1266
1267 static GrGLTexture::TexParams set_initial_texture_params(const GrGLInterface* in terface,
1268 GrGLTexture::IDDesc idD esc) {
1269 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
1270 // drivers have a bug where an FBO won't be complete if it includes a
1271 // texture that is not mipmap complete (considering the filter in use).
1272 GrGLTexture::TexParams initialTexParams;
1273 // we only set a subset here so invalidate first
1274 initialTexParams.invalidate();
1275 initialTexParams.fMinFilter = GR_GL_NEAREST;
1276 initialTexParams.fMagFilter = GR_GL_NEAREST;
1277 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1278 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1279 GR_GL_CALL(interface, TexParameteri(idDesc.fTarget,
1280 GR_GL_TEXTURE_MAG_FILTER,
1281 initialTexParams.fMagFilter));
1282 GR_GL_CALL(interface, TexParameteri(idDesc.fTarget,
1283 GR_GL_TEXTURE_MIN_FILTER,
1284 initialTexParams.fMinFilter));
1285 GR_GL_CALL(interface, TexParameteri(idDesc.fTarget,
1286 GR_GL_TEXTURE_WRAP_S,
1287 initialTexParams.fWrapS));
1288 GR_GL_CALL(interface, TexParameteri(idDesc.fTarget,
1289 GR_GL_TEXTURE_WRAP_T,
1290 initialTexParams.fWrapT));
1291 return initialTexParams;
1292 }
1293
1018 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, 1294 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
1019 GrGpuResource::LifeCycle lifeCycle, 1295 GrGpuResource::LifeCycle lifeCycle,
1020 const void* srcData, size_t rowBytes) { 1296 const SkTArray<SkMipMapLevel>& texels) {
1021 // We fail if the MSAA was requested and is not available. 1297 // We fail if the MSAA was requested and is not available.
1022 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { 1298 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) {
1023 //SkDebugf("MSAA RT requested but not supported on this platform."); 1299 //SkDebugf("MSAA RT requested but not supported on this platform.");
1024 return return_null_texture(); 1300 return return_null_texture();
1025 } 1301 }
1026 1302
1027 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 1303 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
1028 1304
1029 GrGLTexture::IDDesc idDesc; 1305 GrGLTexture::IDDesc idDesc = generate_and_bind_gl_texture(this->glInterface( ), lifeCycle);
1030 GL_CALL(GenTextures(1, &idDesc.fTextureID));
1031 idDesc.fLifeCycle = lifeCycle;
1032 // We only support GL_TEXTURE_2D at the moment.
1033 idDesc.fTarget = GR_GL_TEXTURE_2D;
1034
1035 if (!idDesc.fTextureID) { 1306 if (!idDesc.fTextureID) {
1036 return return_null_texture(); 1307 return return_null_texture();
1037 } 1308 }
1038 1309
1039 this->setScratchTextureUnit(); 1310 this->setScratchTextureUnit();
1040 GL_CALL(BindTexture(idDesc.fTarget, idDesc.fTextureID)); 1311 GL_CALL(BindTexture(idDesc.fTarget, idDesc.fTextureID));
1041 1312
1042 if (renderTarget && this->glCaps().textureUsageSupport()) { 1313 if (renderTarget && this->glCaps().textureUsageSupport()) {
1043 // provides a hint about how this texture will be used 1314 // provides a hint about how this texture will be used
1044 GL_CALL(TexParameteri(idDesc.fTarget, 1315 GL_CALL(TexParameteri(idDesc.fTarget,
1045 GR_GL_TEXTURE_USAGE, 1316 GR_GL_TEXTURE_USAGE,
1046 GR_GL_FRAMEBUFFER_ATTACHMENT)); 1317 GR_GL_FRAMEBUFFER_ATTACHMENT));
1047 } 1318 }
1048 1319
1049 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1320 GrGLTexture::TexParams initialTexParams = set_initial_texture_params(this->g lInterface(),
1050 // drivers have a bug where an FBO won't be complete if it includes a 1321 idDesc) ;
1051 // texture that is not mipmap complete (considering the filter in use). 1322
1052 GrGLTexture::TexParams initialTexParams; 1323 if (!this->uploadTexData(desc, GR_GL_TEXTURE_2D, true, 0, 0,
1053 // we only set a subset here so invalidate first
1054 initialTexParams.invalidate();
1055 initialTexParams.fMinFilter = GR_GL_NEAREST;
1056 initialTexParams.fMagFilter = GR_GL_NEAREST;
1057 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1058 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1059 GL_CALL(TexParameteri(idDesc.fTarget,
1060 GR_GL_TEXTURE_MAG_FILTER,
1061 initialTexParams.fMagFilter));
1062 GL_CALL(TexParameteri(idDesc.fTarget,
1063 GR_GL_TEXTURE_MIN_FILTER,
1064 initialTexParams.fMinFilter));
1065 GL_CALL(TexParameteri(idDesc.fTarget,
1066 GR_GL_TEXTURE_WRAP_S,
1067 initialTexParams.fWrapS));
1068 GL_CALL(TexParameteri(idDesc.fTarget,
1069 GR_GL_TEXTURE_WRAP_T,
1070 initialTexParams.fWrapT));
1071 if (!this->uploadTexData(desc, idDesc.fTarget, true, 0, 0,
1072 desc.fWidth, desc.fHeight, 1324 desc.fWidth, desc.fHeight,
1073 desc.fConfig, srcData, rowBytes)) { 1325 desc.fConfig, texels)) {
1074 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); 1326 GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
1075 return return_null_texture(); 1327 return return_null_texture();
1076 } 1328 }
1077 1329
1078 GrGLTexture* tex; 1330 GrGLTexture* tex;
1079 if (renderTarget) { 1331 if (renderTarget) {
1080 // unbind the texture from the texture unit before binding it to the fra me buffer 1332 // unbind the texture from the texture unit before binding it to the fra me buffer
1081 GL_CALL(BindTexture(idDesc.fTarget, 0)); 1333 GL_CALL(BindTexture(idDesc.fTarget, 0));
1082 GrGLRenderTarget::IDDesc rtIDDesc; 1334 GrGLRenderTarget::IDDesc rtIDDesc;
1083 1335
1084 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, idDesc.fTarget, 1336 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, idDesc.fTarget,
1085 &rtIDDesc)) { 1337 &rtIDDesc)) {
1086 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); 1338 GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
1087 return return_null_texture(); 1339 return return_null_texture();
1088 } 1340 }
1089 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); 1341 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc);
1090 } else { 1342 } else {
1091 tex = new GrGLTexture(this, desc, idDesc); 1343 tex = new GrGLTexture(this, desc, idDesc);
1092 } 1344 }
1093 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1345 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1094 #ifdef TRACE_TEXTURE_CREATION 1346 #ifdef TRACE_TEXTURE_CREATION
1095 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", 1347 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n",
1096 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1348 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
1097 #endif 1349 #endif
1098 return tex; 1350 return tex;
1099 } 1351 }
1100 1352
1101 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, 1353 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc,
1102 GrGpuResource::LifeCycle lifeCycle , 1354 GrGpuResource::LifeCycle lifeCycle ,
1103 const void* srcData) { 1355 const SkTArray<SkMipMapLevel>& tex els) {
1104 // Make sure that we're not flipping Y. 1356 // Make sure that we're not flipping Y.
1105 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { 1357 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
1106 return return_null_texture(); 1358 return return_null_texture();
1107 } 1359 }
1108 1360
1109 GrGLTexture::IDDesc idDesc; 1361 GrGLTexture::IDDesc idDesc = generate_and_bind_gl_texture(this->glInterface( ), lifeCycle);
1110 GL_CALL(GenTextures(1, &idDesc.fTextureID));
1111 idDesc.fLifeCycle = lifeCycle;
1112 // We only support GL_TEXTURE_2D at the moment.
1113 idDesc.fTarget = GR_GL_TEXTURE_2D;
1114
1115 if (!idDesc.fTextureID) { 1362 if (!idDesc.fTextureID) {
1116 return return_null_texture(); 1363 return return_null_texture();
1117 } 1364 }
1118 1365
1119 this->setScratchTextureUnit(); 1366 this->setScratchTextureUnit();
1120 GL_CALL(BindTexture(idDesc.fTarget, idDesc.fTextureID)); 1367 GL_CALL(BindTexture(idDesc.fTarget, idDesc.fTextureID));
1121 1368
1122 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some 1369 GrGLTexture::TexParams initialTexParams = set_initial_texture_params(this->g lInterface(),
1123 // drivers have a bug where an FBO won't be complete if it includes a 1370 idDesc) ;
1124 // texture that is not mipmap complete (considering the filter in use).
1125 GrGLTexture::TexParams initialTexParams;
1126 // we only set a subset here so invalidate first
1127 initialTexParams.invalidate();
1128 initialTexParams.fMinFilter = GR_GL_NEAREST;
1129 initialTexParams.fMagFilter = GR_GL_NEAREST;
1130 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1131 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1132 GL_CALL(TexParameteri(idDesc.fTarget,
1133 GR_GL_TEXTURE_MAG_FILTER,
1134 initialTexParams.fMagFilter));
1135 GL_CALL(TexParameteri(idDesc.fTarget,
1136 GR_GL_TEXTURE_MIN_FILTER,
1137 initialTexParams.fMinFilter));
1138 GL_CALL(TexParameteri(idDesc.fTarget,
1139 GR_GL_TEXTURE_WRAP_S,
1140 initialTexParams.fWrapS));
1141 GL_CALL(TexParameteri(idDesc.fTarget,
1142 GR_GL_TEXTURE_WRAP_T,
1143 initialTexParams.fWrapT));
1144 1371
1145 if (!this->uploadCompressedTexData(desc, idDesc.fTarget, srcData)) { 1372 if (!this->uploadCompressedTexData(desc, idDesc.fTarget, texels)) {
1146 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); 1373 GL_CALL(DeleteTextures(1, &idDesc.fTextureID));
1147 return return_null_texture(); 1374 return return_null_texture();
1148 } 1375 }
1149 1376
1150 GrGLTexture* tex; 1377 GrGLTexture* tex;
1151 tex = new GrGLTexture(this, desc, idDesc); 1378 tex = new GrGLTexture(this, desc, idDesc);
1152 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); 1379 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1153 #ifdef TRACE_TEXTURE_CREATION 1380 #ifdef TRACE_TEXTURE_CREATION
1154 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", 1381 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n",
1155 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); 1382 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
(...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after
2703 *internalFormat = GR_GL_ALPHA; 2930 *internalFormat = GR_GL_ALPHA;
2704 } 2931 }
2705 *externalFormat = GR_GL_ALPHA; 2932 *externalFormat = GR_GL_ALPHA;
2706 } 2933 }
2707 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { 2934 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) {
2708 *externalType = GR_GL_HALF_FLOAT; 2935 *externalType = GR_GL_HALF_FLOAT;
2709 } else { 2936 } else {
2710 *externalType = GR_GL_HALF_FLOAT_OES; 2937 *externalType = GR_GL_HALF_FLOAT_OES;
2711 } 2938 }
2712 break; 2939 break;
2713 2940
2714 case kRGBA_half_GrPixelConfig: 2941 case kRGBA_half_GrPixelConfig:
2715 *internalFormat = GR_GL_RGBA16F; 2942 *internalFormat = GR_GL_RGBA16F;
2716 *externalFormat = GR_GL_RGBA; 2943 *externalFormat = GR_GL_RGBA;
2717 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { 2944 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) {
2718 *externalType = GR_GL_HALF_FLOAT; 2945 *externalType = GR_GL_HALF_FLOAT;
2719 } else { 2946 } else {
2720 *externalType = GR_GL_HALF_FLOAT_OES; 2947 *externalType = GR_GL_HALF_FLOAT_OES;
2721 } 2948 }
2722 break; 2949 break;
2723 2950
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2829 viewport->fWidth = surface->width(); 3056 viewport->fWidth = surface->width();
2830 viewport->fHeight = surface->height(); 3057 viewport->fHeight = surface->height();
2831 } else { 3058 } else {
2832 fStats.incRenderTargetBinds(); 3059 fStats.incRenderTargetBinds();
2833 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO ID())); 3060 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO ID()));
2834 *viewport = rt->getViewport(); 3061 *viewport = rt->getViewport();
2835 } 3062 }
2836 } 3063 }
2837 3064
2838 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) { 3065 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) {
2839 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ ets to 3066 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ ets to
2840 if (!surface->asRenderTarget()) { 3067 if (!surface->asRenderTarget()) {
2841 SkASSERT(surface->asTexture()); 3068 SkASSERT(surface->asTexture());
2842 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture()) ->target(); 3069 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture()) ->target();
2843 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, 3070 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
2844 GR_GL_COLOR_ATTACHM ENT0, 3071 GR_GL_COLOR_ATTACHM ENT0,
2845 textureTarget, 3072 textureTarget,
2846 0, 3073 0,
2847 0)); 3074 0));
2848 } 3075 }
2849 } 3076 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2901 } 3128 }
2902 3129
2903 bool GrGLGpu::onCopySurface(GrSurface* dst, 3130 bool GrGLGpu::onCopySurface(GrSurface* dst,
2904 GrSurface* src, 3131 GrSurface* src,
2905 const SkIRect& srcRect, 3132 const SkIRect& srcRect,
2906 const SkIPoint& dstPoint) { 3133 const SkIPoint& dstPoint) {
2907 if (src->asTexture() && dst->asRenderTarget()) { 3134 if (src->asTexture() && dst->asRenderTarget()) {
2908 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); 3135 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
2909 return true; 3136 return true;
2910 } 3137 }
2911 3138
2912 if (can_copy_texsubimage(dst, src, this)) { 3139 if (can_copy_texsubimage(dst, src, this)) {
2913 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); 3140 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
2914 return true; 3141 return true;
2915 } 3142 }
2916 3143
2917 if (can_blit_framebuffer(dst, src, this)) { 3144 if (can_blit_framebuffer(dst, src, this)) {
2918 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); 3145 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
2919 } 3146 }
2920 3147
2921 return false; 3148 return false;
2922 } 3149 }
2923 3150
2924 3151
2925 void GrGLGpu::createCopyProgram() { 3152 void GrGLGpu::createCopyProgram() {
2926 const char* version = this->glCaps().glslCaps()->versionDeclString(); 3153 const char* version = this->glCaps().glslCaps()->versionDeclString();
2927 3154
2928 GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute _TypeModifier); 3155 GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute _TypeModifier);
2929 GrGLSLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, 3156 GrGLSLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
2930 GrShaderVar::kUniform_TypeModifier); 3157 GrShaderVar::kUniform_TypeModifier);
2931 GrGLSLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUnifo rm_TypeModifier); 3158 GrGLSLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUnifo rm_TypeModifier);
2932 GrGLSLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUni form_TypeModifier); 3159 GrGLSLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUni form_TypeModifier);
2933 GrGLSLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVaryi ngOut_TypeModifier); 3160 GrGLSLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVaryi ngOut_TypeModifier);
2934 GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut _TypeModifier); 3161 GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut _TypeModifier);
2935 3162
2936 SkString vshaderTxt(version); 3163 SkString vshaderTxt(version);
2937 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3164 aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2938 vshaderTxt.append(";"); 3165 vshaderTxt.append(";");
2939 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3166 uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2940 vshaderTxt.append(";"); 3167 vshaderTxt.append(";");
2941 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3168 uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2942 vshaderTxt.append(";"); 3169 vshaderTxt.append(";");
2943 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt); 3170 vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
2944 vshaderTxt.append(";"); 3171 vshaderTxt.append(";");
2945 3172
2946 vshaderTxt.append( 3173 vshaderTxt.append(
2947 "// Copy Program VS\n" 3174 "// Copy Program VS\n"
2948 "void main() {" 3175 "void main() {"
2949 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" 3176 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
2950 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" 3177 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
2951 " gl_Position.zw = vec2(0, 1);" 3178 " gl_Position.zw = vec2(0, 1);"
2952 "}" 3179 "}"
2953 ); 3180 );
2954 3181
2955 SkString fshaderTxt(version); 3182 SkString fshaderTxt(version);
(...skipping 14 matching lines...) Expand all
2970 fsOutName = "gl_FragColor"; 3197 fsOutName = "gl_FragColor";
2971 } 3198 }
2972 fshaderTxt.appendf( 3199 fshaderTxt.appendf(
2973 "// Copy Program FS\n" 3200 "// Copy Program FS\n"
2974 "void main() {" 3201 "void main() {"
2975 " %s = %s(u_texture, v_texCoord);" 3202 " %s = %s(u_texture, v_texCoord);"
2976 "}", 3203 "}",
2977 fsOutName, 3204 fsOutName,
2978 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) 3205 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration())
2979 ); 3206 );
2980 3207
2981 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); 3208 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram());
2982 const char* str; 3209 const char* str;
2983 GrGLint length; 3210 GrGLint length;
2984 3211
2985 str = vshaderTxt.c_str(); 3212 str = vshaderTxt.c_str();
2986 length = SkToInt(vshaderTxt.size()); 3213 length = SkToInt(vshaderTxt.size());
2987 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram, 3214 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram,
2988 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats); 3215 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats);
2989 3216
2990 str = fshaderTxt.c_str(); 3217 str = fshaderTxt.c_str();
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
3297 this->setVertexArrayID(gpu, 0); 3524 this->setVertexArrayID(gpu, 0);
3298 } 3525 }
3299 int attrCount = gpu->glCaps().maxVertexAttributes(); 3526 int attrCount = gpu->glCaps().maxVertexAttributes();
3300 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3527 if (fDefaultVertexArrayAttribState.count() != attrCount) {
3301 fDefaultVertexArrayAttribState.resize(attrCount); 3528 fDefaultVertexArrayAttribState.resize(attrCount);
3302 } 3529 }
3303 attribState = &fDefaultVertexArrayAttribState; 3530 attribState = &fDefaultVertexArrayAttribState;
3304 } 3531 }
3305 return attribState; 3532 return attribState;
3306 } 3533 }
OLDNEW
« src/gpu/SkGr.cpp ('K') | « src/gpu/gl/GrGLGpu.h ('k') | src/image/SkImage_Gpu.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698