Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 | 8 |
| 9 #include "GrGLGpu.h" | 9 #include "GrGLGpu.h" |
| 10 #include "GrGLGLSL.h" | 10 #include "GrGLGLSL.h" |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 | 419 |
| 420 int maxSize = this->caps()->maxTextureSize(); | 420 int maxSize = this->caps()->maxTextureSize(); |
| 421 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { | 421 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { |
| 422 return nullptr; | 422 return nullptr; |
| 423 } | 423 } |
| 424 | 424 |
| 425 GrGLTexture::IDDesc idDesc; | 425 GrGLTexture::IDDesc idDesc; |
| 426 GrSurfaceDesc surfDesc; | 426 GrSurfaceDesc surfDesc; |
| 427 | 427 |
| 428 idDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle); | 428 idDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle); |
| 429 | 429 |
| 430 switch (ownership) { | 430 switch (ownership) { |
| 431 case kAdopt_GrWrapOwnership: | 431 case kAdopt_GrWrapOwnership: |
| 432 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; | 432 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; |
| 433 break; | 433 break; |
| 434 case kBorrow_GrWrapOwnership: | 434 case kBorrow_GrWrapOwnership: |
| 435 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; | 435 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; |
| 436 break; | 436 break; |
| 437 } | 437 } |
| 438 | 438 |
| 439 // next line relies on GrBackendTextureDesc's flags matching GrTexture's | 439 // next line relies on GrBackendTextureDesc's flags matching GrTexture's |
| 440 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; | 440 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; |
| 441 surfDesc.fWidth = desc.fWidth; | 441 surfDesc.fWidth = desc.fWidth; |
| 442 surfDesc.fHeight = desc.fHeight; | 442 surfDesc.fHeight = desc.fHeight; |
| 443 surfDesc.fConfig = desc.fConfig; | 443 surfDesc.fConfig = desc.fConfig; |
| 444 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() ); | 444 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount() ); |
| 445 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g); | 445 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla g); |
| 446 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly | 446 // FIXME: this should be calling resolve_origin(), but Chrome code is curre ntly |
| 447 // assuming the old behaviour, which is that backend textures are always | 447 // assuming the old behaviour, which is that backend textures are always |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 477 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); | 477 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); |
| 478 idDesc.fMSColorRenderbufferID = 0; | 478 idDesc.fMSColorRenderbufferID = 0; |
| 479 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; | 479 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; |
| 480 switch (ownership) { | 480 switch (ownership) { |
| 481 case kAdopt_GrWrapOwnership: | 481 case kAdopt_GrWrapOwnership: |
| 482 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; | 482 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; |
| 483 break; | 483 break; |
| 484 case kBorrow_GrWrapOwnership: | 484 case kBorrow_GrWrapOwnership: |
| 485 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; | 485 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; |
| 486 break; | 486 break; |
| 487 } | 487 } |
| 488 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; | 488 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; |
| 489 | 489 |
| 490 GrSurfaceDesc desc; | 490 GrSurfaceDesc desc; |
| 491 desc.fConfig = wrapDesc.fConfig; | 491 desc.fConfig = wrapDesc.fConfig; |
| 492 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; | 492 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; |
| 493 desc.fWidth = wrapDesc.fWidth; | 493 desc.fWidth = wrapDesc.fWidth; |
| 494 desc.fHeight = wrapDesc.fHeight; | 494 desc.fHeight = wrapDesc.fHeight; |
| 495 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); | 495 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount() ); |
| 496 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); | 496 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); |
| 497 | 497 |
| 498 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits); | 498 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil Bits); |
| 499 } | 499 } |
| 500 | 500 |
| 501 //////////////////////////////////////////////////////////////////////////////// | 501 //////////////////////////////////////////////////////////////////////////////// |
| 502 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, | 502 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, |
| 503 size_t rowBytes, GrPixelConfig srcConfig, | 503 GrPixelConfig srcConfig, |
| 504 DrawPreference* drawPreference, | 504 DrawPreference* drawPreference, |
| 505 WritePixelTempDrawInfo* tempDrawInfo) { | 505 WritePixelTempDrawInfo* tempDrawInfo) { |
| 506 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { | 506 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { |
| 507 return false; | 507 return false; |
| 508 } | 508 } |
| 509 | 509 |
| 510 // This subclass only allows writes to textures. If the dst is not a texture we have to draw | 510 // This subclass only allows writes to textures. If the dst is not a texture we have to draw |
| 511 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. | 511 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. |
| 512 if (!dstSurface->asTexture()) { | 512 if (!dstSurface->asTexture()) { |
| 513 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); | 513 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 if (!this->glCaps().unpackFlipYSupport() && | 553 if (!this->glCaps().unpackFlipYSupport() && |
| 554 kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) { | 554 kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) { |
| 555 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); | 555 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); |
| 556 } | 556 } |
| 557 | 557 |
| 558 return true; | 558 return true; |
| 559 } | 559 } |
| 560 | 560 |
| 561 bool GrGLGpu::onWritePixels(GrSurface* surface, | 561 bool GrGLGpu::onWritePixels(GrSurface* surface, |
| 562 int left, int top, int width, int height, | 562 int left, int top, int width, int height, |
| 563 GrPixelConfig config, const void* buffer, | 563 GrPixelConfig config, |
| 564 size_t rowBytes) { | 564 const SkTArray<SkMipMapLevel>& texels) { |
| 565 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); | 565 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); |
| 566 if (!glTex) { | 566 if (!glTex) { |
| 567 return false; | 567 return false; |
| 568 } | 568 } |
| 569 | 569 |
| 570 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels. | 570 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels. |
| 571 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { | 571 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { |
| 572 return false; | 572 return false; |
| 573 } | 573 } |
| 574 | 574 |
| 575 this->setScratchTextureUnit(); | 575 this->setScratchTextureUnit(); |
| 576 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); | 576 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); |
| 577 | 577 |
| 578 bool success = false; | 578 bool success = false; |
| 579 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { | 579 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { |
| 580 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() | 580 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() |
| 581 SkASSERT(config == glTex->desc().fConfig); | 581 SkASSERT(config == glTex->desc().fConfig); |
| 582 success = this->uploadCompressedTexData(glTex->desc(), buffer, false, le ft, top, width, | 582 success = this->uploadCompressedTexData(glTex->desc(), texels, false, le ft, top, width, |
| 583 height); | 583 height); |
| 584 } else { | 584 } else { |
| 585 success = this->uploadTexData(glTex->desc(), false, left, top, width, he ight, config, | 585 success = this->uploadTexData(glTex->desc(), false, left, top, width, he ight, config, texels); |
| 586 buffer, rowBytes); | |
| 587 } | 586 } |
| 588 | 587 |
| 589 if (success) { | 588 return success; |
| 590 glTex->texturePriv().dirtyMipMaps(true); | |
| 591 return true; | |
| 592 } | |
| 593 | |
| 594 return false; | |
| 595 } | 589 } |
| 596 | 590 |
| 597 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, | 591 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, |
| 598 const GrGLInterface* interface) { | 592 const GrGLInterface* interface) { |
| 599 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { | 593 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { |
| 600 return GR_GL_GET_ERROR(interface); | 594 return GR_GL_GET_ERROR(interface); |
| 601 } else { | 595 } else { |
| 602 return CHECK_ALLOC_ERROR(interface); | 596 return CHECK_ALLOC_ERROR(interface); |
| 603 } | 597 } |
| 604 } | 598 } |
| 605 | 599 |
| 606 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | 600 /** |
| 607 bool isNewTexture, | 601 * Determines if TexStorage can be used when creating a texture. |
| 608 int left, int top, int width, int height, | 602 * |
| 609 GrPixelConfig dataConfig, | 603 * @param caps The capabilities of the GL device. |
| 610 const void* data, | 604 * @param standard The GL standard in use. |
| 611 size_t rowBytes) { | 605 * @param desc The surface descriptor for the texture being created. |
| 612 SkASSERT(data || isNewTexture); | 606 */ |
| 613 | 607 static bool can_use_tex_storage(const GrGLCaps& caps, const GrGLStandard& standa rd, |
| 614 // If we're uploading compressed data then we should be using uploadCompress edTexData | 608 const GrSurfaceDesc& desc) { |
| 615 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | 609 bool useTexStorage = caps.texStorageSupport(); |
| 616 | 610 if (useTexStorage && kGL_GrGLStandard == standard) { |
| 617 size_t bpp = GrBytesPerPixel(dataConfig); | |
| 618 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, & left, &top, | |
| 619 &width, &height, &data, &rowBytes )) { | |
| 620 return false; | |
| 621 } | |
| 622 size_t trimRowBytes = width * bpp; | |
| 623 | |
| 624 // in case we need a temporary, trimmed copy of the src pixels | |
| 625 SkAutoSMalloc<128 * 128> tempStorage; | |
| 626 | |
| 627 // We currently lazily create MIPMAPs when the we see a draw with | |
| 628 // GrTextureParams::kMipMap_FilterMode. Using texture storage requires that the | |
| 629 // MIP levels are all created when the texture is created. So for now we don 't use | |
| 630 // texture storage. | |
| 631 bool useTexStorage = false && | |
| 632 isNewTexture && | |
| 633 this->glCaps().texStorageSupport(); | |
| 634 | |
| 635 if (useTexStorage && kGL_GrGLStandard == this->glStandard()) { | |
| 636 // 565 is not a sized internal format on desktop GL. So on desktop with | 611 // 565 is not a sized internal format on desktop GL. So on desktop with |
| 637 // 565 we always use an unsized internal format to let the system pick | 612 // 565 we always use an unsized internal format to let the system pick |
| 638 // the best sized format to convert the 565 data to. Since TexStorage | 613 // the best sized format to convert the 565 data to. Since TexStorage |
| 639 // only allows sized internal formats we will instead use TexImage2D. | 614 // only allows sized internal formats we will instead use TexImage2D. |
| 640 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; | 615 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; |
| 641 } | 616 } |
| 642 | 617 |
| 643 GrGLenum internalFormat = 0x0; // suppress warning | 618 return useTexStorage; |
| 644 GrGLenum externalFormat = 0x0; // suppress warning | 619 } |
| 645 GrGLenum externalType = 0x0; // suppress warning | |
| 646 | 620 |
| 621 /** | |
| 622 * Determines if sized internal formats are available for the texture being crea ted. | |
| 623 * | |
| 624 * @param useTexStorage The result of a call to can_use_tex_storage(). | |
| 625 * @param caps The capabilities of the GL device. | |
| 626 * @param standard The GL standard in use. | |
| 627 * @param version The GL version in use. | |
| 628 * @param dataConfig The pixel configuration for the texture being created. | |
| 629 */ | |
| 630 static bool can_use_sized_format(bool useTexStorage, const GrGLCaps& caps, | |
| 631 const GrGLStandard& standard, const GrGLVersion & version, | |
| 632 GrPixelConfig dataConfig) { | |
| 647 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized | 633 // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized |
| 648 // format for glTexImage, unlike ES3 and desktop. | 634 // format for glTexImage, unlike ES3 and desktop. |
| 649 bool useSizedFormat = useTexStorage; | 635 bool useSizedFormat = useTexStorage; |
| 650 if (kGL_GrGLStandard == this->glStandard() || | 636 if (kGL_GrGLStandard == standard || |
| 651 (this->glVersion() >= GR_GL_VER(3, 0) && | 637 (version >= GR_GL_VER(3, 0) && |
| 652 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled | 638 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B GRA8888" enabled |
| 653 (kBGRA_8888_GrPixelConfig != dataConfig || !this->glCaps().bgraIsIntern alFormat()))) { | 639 (kBGRA_8888_GrPixelConfig != dataConfig || !caps.bgraIsInternalFormat() ))) { |
| 654 useSizedFormat = true; | 640 useSizedFormat = true; |
| 655 } | 641 } |
| 656 | 642 |
| 657 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, | 643 return useSizedFormat; |
| 658 &externalFormat, &externalType)) { | 644 } |
| 659 return false; | |
| 660 } | |
| 661 | 645 |
| 662 /* | 646 /** |
| 663 * check whether to allocate a temporary buffer for flipping y or | 647 * Prior to a texture being created, the image may need to be flipped vertically . This function |
| 664 * because our srcData has extra bytes past each row. If so, we need | 648 * prepares the texels for texture creation. |
| 665 * to trim those off here, since GL ES may not let us specify | 649 * |
| 666 * GL_UNPACK_ROW_LENGTH. | 650 * @param desc The surface descriptor for the texture being create d. |
| 667 */ | 651 * @param caps The capabilities of the GL device. |
| 668 bool restoreGLRowLength = false; | 652 * @param interface The GL interface in use. |
| 669 bool swFlipY = false; | 653 * @param swFlipY Should software be used when flipping a texture ver tically? |
| 670 bool glFlipY = false; | 654 * @param glFlipY Should GL be used when flipping a texture verticall y? |
| 671 if (data) { | 655 * @param width The width of the texture in texels. |
| 672 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 656 * @param height The height of the texture in texels. |
| 673 if (this->glCaps().unpackFlipYSupport()) { | 657 * @param bpp The bits per pixel (or texel, really) of the textur e. |
| 674 glFlipY = true; | 658 * @param texels An array of mipmap levels which contain the texel d ata at that level. |
| 675 } else { | 659 * @param tempStorage In the case where the image needs to be flipped ver tically, it will |
| 676 swFlipY = true; | 660 * use tempStorage as a buffer. |
| 677 } | 661 * @param restoreGLRowLength After the texture is created, will the GL row lengt h unpacking need |
| 662 * to be restored? | |
| 663 */ | |
| 664 static void prepare_image_for_writing_to_texture(const GrSurfaceDesc& desc, cons t GrGLCaps& caps, | |
| 665 const GrGLInterface& interface, bool swFlipY, | |
| 666 bool glFlipY, int width, int he ight, int bpp, | |
| 667 SkTArray<SkMipMapLevel>& texels , | |
| 668 SkAutoSMalloc<128 * 128>& tempS torage, | |
| 669 bool* restoreGLRowLength) { | |
| 670 int currentMipLevelWidth = width; | |
| 671 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) { | |
| 672 if (texels[currentMipLevel].fTexels == nullptr) { | |
| 673 continue; | |
| 678 } | 674 } |
| 679 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { | 675 |
| 676 size_t trimRowBytes = currentMipLevelWidth * bpp; | |
| 677 | |
| 678 /* | |
| 679 * check whether to allocate a temporary buffer for flipping y or | |
| 680 * because our srcData has extra bytes past each row. If so, we need | |
| 681 * to trim those off here, since GL ES may not let us specify | |
| 682 * GL_UNPACK_ROW_LENGTH. | |
| 683 */ | |
| 684 *restoreGLRowLength = false; | |
| 685 | |
| 686 auto rowBytes = texels[currentMipLevel].fRowBytes; | |
| 687 if (caps.unpackRowLengthSupport() && !swFlipY) { | |
| 680 // can't use this for flipping, only non-neg values allowed. :( | 688 // can't use this for flipping, only non-neg values allowed. :( |
| 681 if (rowBytes != trimRowBytes) { | 689 if (rowBytes != trimRowBytes) { |
| 682 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); | 690 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); |
| 683 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); | 691 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowL ength)); |
| 684 restoreGLRowLength = true; | 692 *restoreGLRowLength = true; |
| 685 } | 693 } |
| 686 } else { | 694 } else { |
| 687 if (trimRowBytes != rowBytes || swFlipY) { | 695 if (trimRowBytes != rowBytes || swFlipY) { |
| 688 // copy data into our new storage, skipping the trailing bytes | 696 // copy data into our new storage, skipping the trailing bytes |
| 689 size_t trimSize = height * trimRowBytes; | 697 size_t trimSize = height * trimRowBytes; |
| 690 const char* src = (const char*)data; | 698 const char* src = (const char*)texels[currentMipLevel].fTexels; |
| 691 if (swFlipY) { | 699 if (swFlipY) { |
| 692 src += (height - 1) * rowBytes; | 700 src += (height - 1) * rowBytes; |
| 693 } | 701 } |
| 694 char* dst = (char*)tempStorage.reset(trimSize); | 702 char* dst = (char*)tempStorage.reset(trimSize); |
| 695 for (int y = 0; y < height; y++) { | 703 for (int y = 0; y < height; y++) { |
| 696 memcpy(dst, src, trimRowBytes); | 704 memcpy(dst, src, trimRowBytes); |
| 697 if (swFlipY) { | 705 if (swFlipY) { |
| 698 src -= rowBytes; | 706 src -= rowBytes; |
| 699 } else { | 707 } else { |
| 700 src += rowBytes; | 708 src += rowBytes; |
| 701 } | 709 } |
| 702 dst += trimRowBytes; | 710 dst += trimRowBytes; |
| 703 } | 711 } |
| 704 // now point data to our copied version | 712 // now point data to our copied version |
| 705 data = tempStorage.get(); | 713 texels[currentMipLevel] = SkMipMapLevel(tempStorage.get(), trimR owBytes); |
| 706 } | 714 } |
| 707 } | 715 } |
| 708 if (glFlipY) { | 716 if (glFlipY) { |
| 709 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); | 717 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)) ; |
| 710 } | 718 } |
| 711 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, | 719 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, |
| 712 static_cast<GrGLint>(GrUnpackAlignment(dataConfig)))); | 720 static_cast<GrGLint>(GrUnpackAlignmen t(desc.fConfig)))); |
| 713 } | 721 currentMipLevelWidth /= 2; |
| 722 } | |
| 723 } | |
| 724 | |
| 725 /** | |
| 726 * Creates storage space for the texture and fills it with texels. | |
| 727 * | |
| 728 * @param desc The surface descriptor for the texture being created. | |
| 729 * @param interface The GL interface in use. | |
| 730 * @param useTexStorage The result of a call to can_use_tex_storage(). | |
| 731 * @param internalFormat The data format used for the internal storage of the te xture. | |
| 732 * @param externalFormat The data format used for the external storage of the te xture. | |
| 733 * @param externalType The type of the data used for the external storage of t he texture. | |
| 734 * @param texels The texel data of the texture being created. | |
| 735 * @param succeeded Set to true if allocating and populating the texture co mpleted | |
| 736 * without error. | |
| 737 */ | |
| 738 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc , | |
| 739 const GrGLInterface& inte rface, | |
| 740 bool useTexStorage, | |
| 741 GrGLenum internalFormat, | |
| 742 GrGLenum externalFormat, | |
| 743 GrGLenum externalType, | |
| 744 const SkTArray<SkMipMapLe vel>& texels, | |
| 745 bool* succeeded) { | |
| 746 CLEAR_ERROR_BEFORE_ALLOC(&interface); | |
| 747 if (useTexStorage) { | |
| 748 // We never resize or change formats of textures. | |
| 749 GL_ALLOC_CALL(&interface, | |
| 750 TexStorage2D(GR_GL_TEXTURE_2D, | |
| 751 texels.count(), | |
| 752 internalFormat, | |
| 753 desc.fWidth, desc.fHeight)); | |
| 754 } else { | |
| 755 int width = desc.fWidth; | |
| 756 int height = desc.fHeight; | |
| 757 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) { | |
| 758 auto currentMipData = texels[currentMipLevel].fTexels; | |
| 759 if (currentMipData == nullptr) { | |
| 760 continue; | |
| 761 } | |
| 762 | |
| 763 GL_ALLOC_CALL(&interface, | |
| 764 TexImage2D(GR_GL_TEXTURE_2D, | |
| 765 currentMipLevel, | |
| 766 internalFormat, | |
| 767 width, height, | |
| 768 0, // border | |
| 769 externalFormat, externalType, | |
| 770 currentMipData)); | |
| 771 width /= 2; | |
| 772 height /= 2; | |
| 773 } | |
| 774 } | |
| 775 | |
| 776 GrGLenum error = check_alloc_error(desc, &interface); | |
| 777 if (error != GR_GL_NO_ERROR) { | |
| 778 *succeeded = false; | |
| 779 } else { | |
| 780 int width = desc.fWidth; | |
| 781 int height = desc.fHeight; | |
| 782 for (auto currentMipLevel = texels.count() - 1; currentMipLevel >= 0; cu rrentMipLevel--) { | |
| 783 auto currentMipData = texels[currentMipLevel].fTexels; | |
| 784 if (currentMipData == nullptr) { | |
| 785 continue; | |
| 786 } | |
| 787 | |
| 788 GR_GL_CALL(&interface, | |
| 789 TexSubImage2D(GR_GL_TEXTURE_2D, | |
| 790 currentMipLevel, | |
| 791 0, // left | |
| 792 0, // top | |
| 793 width, height, | |
| 794 externalFormat, externalType, | |
| 795 currentMipData)); | |
| 796 width /= 2; | |
| 797 height /= 2; | |
| 798 } | |
| 799 *succeeded = true; | |
| 800 } | |
| 801 } | |
| 802 | |
| 803 /** | |
| 804 * Creates storage space for the texture and fills it with texels. | |
| 805 * | |
| 806 * @param desc The surface descriptor for the texture being created. | |
| 807 * @param interface The GL interface in use. | |
| 808 * @param useTexStorage The result of a call to can_use_tex_storage(). | |
| 809 * @param internalFormat The data format used for the internal storage of the te xture. | |
| 810 * @param texels The texel data of the texture being created. | |
| 811 */ | |
| 812 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc, | |
| 813 const GrGLInterface& interf ace, | |
| 814 bool useTexStorage, GrGLenu m internalFormat, | |
| 815 const SkTArray<SkMipMapLeve l>& texels) { | |
| 816 CLEAR_ERROR_BEFORE_ALLOC(&interface); | |
| 817 if (useTexStorage) { | |
| 818 // We never resize or change formats of textures. | |
| 819 GL_ALLOC_CALL(&interface, | |
| 820 TexStorage2D(GR_GL_TEXTURE_2D, | |
| 821 texels.count(), | |
| 822 internalFormat, | |
| 823 desc.fWidth, desc.fHeight)); | |
| 824 } else { | |
| 825 int width = desc.fWidth; | |
| 826 int height = desc.fHeight; | |
| 827 for (auto currentMipLevel = texels.count() - 1; currentMipLevel >= 0; cu rrentMipLevel--) { | |
| 828 auto currentMipData = texels[currentMipLevel].fTexels; | |
| 829 | |
| 830 if (currentMipData == nullptr) { | |
| 831 continue; | |
| 832 } | |
| 833 | |
| 834 // Make sure that the width and height that we pass to OpenGL | |
| 835 // is a multiple of the block size. | |
| 836 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, he ight); | |
| 837 | |
| 838 GL_ALLOC_CALL(&interface, | |
| 839 CompressedTexImage2D(GR_GL_TEXTURE_2D, | |
| 840 texels.count(), | |
| 841 internalFormat, | |
| 842 width, height, | |
| 843 0, // border | |
| 844 SkToInt(dataSize), | |
| 845 currentMipData)); | |
| 846 width /= 2; | |
| 847 height /= 2; | |
| 848 } | |
| 849 } | |
| 850 | |
| 851 GrGLenum error = check_alloc_error(desc, &interface); | |
| 852 if (error != GR_GL_NO_ERROR) { | |
| 853 return false; | |
| 854 } | |
| 855 return true; | |
| 856 } | |
| 857 | |
| 858 /** | |
| 859 * After a texture is created, any state which was altered during its creation | |
| 860 * needs to be restored. | |
| 861 * | |
| 862 * @param interface The GL interface to use. | |
| 863 * @param caps The capabilities of the GL device. | |
| 864 * @param restoreGLRowLength Should the row length unpacking be restored? | |
| 865 * @param glFlipY Did GL flip the texture vertically? | |
| 866 */ | |
| 867 static void restore_gl_state(const GrGLInterface& interface, const GrGLCaps& cap s, | |
|
bsalomon
2015/09/15 13:14:11
maybe give this a narrower name? e.g. restore_pixe
cblume
2015/09/16 18:40:46
Oh wow, that is a much better name. Done.
| |
| 868 bool restoreGLRowLength, bool glFlipY) { | |
| 869 if (restoreGLRowLength) { | |
| 870 SkASSERT(caps.unpackRowLengthSupport()); | |
| 871 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | |
| 872 } | |
| 873 if (glFlipY) { | |
| 874 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | |
| 875 } | |
| 876 } | |
| 877 | |
| 878 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | |
| 879 bool isNewTexture, | |
| 880 int left, int top, int width, int height, | |
| 881 GrPixelConfig dataConfig, | |
| 882 const SkTArray<SkMipMapLevel>& texels) { | |
| 883 // If we're uploading compressed data then we should be using uploadCompress edTexData | |
| 884 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | |
| 885 | |
| 886 SkTArray<SkMipMapLevel> texelsCopy(texels); | |
| 887 | |
| 888 for (auto currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; cu rrentMipLevel--) { | |
| 889 SkASSERT(texelsCopy[currentMipLevel].fTexels || isNewTexture); | |
| 890 } | |
| 891 | |
| 892 | |
| 893 auto interface = this->glInterface(); | |
| 894 if (interface == nullptr) { | |
| 895 return false; | |
| 896 } | |
| 897 auto& caps = this->glCaps(); | |
| 898 auto standard = this->glStandard(); | |
| 899 auto version = this->glVersion(); | |
| 900 | |
| 901 size_t bpp = GrBytesPerPixel(dataConfig); | |
| 902 int mipWidth = desc.fWidth; | |
| 903 int mipHeight = desc.fHeight; | |
| 904 for (auto currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; cu rrentMipLevel--) { | |
| 905 if (texelsCopy[currentMipLevel].fTexels == nullptr) { | |
| 906 continue; | |
| 907 } | |
| 908 | |
| 909 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp p, &left, &top, | |
| 910 &mipWidth, &mipHeight, &texelsCop y[currentMipLevel].fTexels, &texelsCopy[currentMipLevel].fRowBytes)) { | |
| 911 return false; | |
| 912 } | |
| 913 } | |
| 914 | |
| 915 bool useTexStorage = can_use_tex_storage(caps, standard, desc); | |
| 916 bool useSizedFormat = can_use_sized_format(useTexStorage, caps, standard, ve rsion, dataConfig); | |
| 917 | |
| 918 GrGLenum internalFormat = 0x0; // suppress warning | |
| 919 GrGLenum externalFormat = 0x0; // suppress warning | |
| 920 GrGLenum externalType = 0x0; // suppress warning | |
| 921 | |
| 922 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, | |
| 923 &externalFormat, &externalType)) { | |
| 924 return false; | |
| 925 } | |
| 926 | |
| 927 bool swFlipY = false; | |
| 928 bool glFlipY = false; | |
| 929 | |
| 930 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | |
| 931 if (caps.unpackFlipYSupport()) { | |
| 932 glFlipY = true; | |
| 933 } else { | |
| 934 swFlipY = true; | |
| 935 } | |
| 936 } | |
| 937 | |
| 938 bool restoreGLRowLength = false; | |
| 939 | |
| 940 // in case we need a temporary, trimmed copy of the src pixels | |
| 941 SkAutoSMalloc<128 * 128> tempStorage; | |
| 942 prepare_image_for_writing_to_texture(desc, caps, *interface, swFlipY, glFlip Y, width, | |
| 943 height, bpp, texelsCopy, tempStorage, & restoreGLRowLength); | |
| 714 bool succeeded = true; | 944 bool succeeded = true; |
| 715 if (isNewTexture && | 945 if (isNewTexture && |
| 716 0 == left && 0 == top && | 946 0 == left && 0 == top && |
| 717 desc.fWidth == width && desc.fHeight == height) { | 947 desc.fWidth == width && desc.fHeight == height) { |
| 718 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 948 allocate_and_populate_uncompressed_texture(desc, *interface, useTexStora ge, internalFormat, |
| 719 if (useTexStorage) { | 949 externalFormat, externalType, texelsCopy, |
| 720 // We never resize or change formats of textures. | 950 &succeeded); |
| 721 GL_ALLOC_CALL(this->glInterface(), | |
| 722 TexStorage2D(GR_GL_TEXTURE_2D, | |
| 723 1, // levels | |
| 724 internalFormat, | |
| 725 desc.fWidth, desc.fHeight)); | |
| 726 } else { | |
| 727 GL_ALLOC_CALL(this->glInterface(), | |
| 728 TexImage2D(GR_GL_TEXTURE_2D, | |
| 729 0, // level | |
| 730 internalFormat, | |
| 731 desc.fWidth, desc.fHeight, | |
| 732 0, // border | |
| 733 externalFormat, externalType, | |
| 734 data)); | |
| 735 } | |
| 736 GrGLenum error = check_alloc_error(desc, this->glInterface()); | |
| 737 if (error != GR_GL_NO_ERROR) { | |
| 738 succeeded = false; | |
| 739 } else { | |
| 740 // if we have data and we used TexStorage to create the texture, we | |
| 741 // now upload with TexSubImage. | |
| 742 if (data && useTexStorage) { | |
| 743 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, | |
| 744 0, // level | |
| 745 left, top, | |
| 746 width, height, | |
| 747 externalFormat, externalType, | |
| 748 data)); | |
| 749 } | |
| 750 } | |
| 751 } else { | 951 } else { |
| 752 if (swFlipY || glFlipY) { | 952 if (swFlipY || glFlipY) { |
| 753 top = desc.fHeight - (top + height); | 953 top = desc.fHeight - (top + height); |
| 754 } | 954 } |
| 755 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, | 955 width = desc.fWidth; |
| 756 0, // level | 956 height = desc.fHeight; |
| 757 left, top, | 957 for (int currentMipLevel = 0; currentMipLevel < texelsCopy.count(); curr entMipLevel++) { |
| 758 width, height, | 958 if (texelsCopy[currentMipLevel].fTexels == nullptr) { |
| 759 externalFormat, externalType, data)); | 959 continue; |
| 760 } | 960 } |
| 761 | 961 |
| 762 if (restoreGLRowLength) { | 962 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, |
| 763 SkASSERT(this->glCaps().unpackRowLengthSupport()); | 963 0, // level |
| 764 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | 964 left, top, |
| 765 } | 965 width, height, |
| 766 if (glFlipY) { | 966 externalFormat, externalType, texelsCopy[curre ntMipLevel].fTexels)); |
| 767 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | 967 width /= 2; |
| 768 } | 968 height /= 2; |
| 969 } | |
| 970 } | |
| 971 | |
| 972 restore_gl_state(*interface, caps, restoreGLRowLength, glFlipY); | |
| 973 | |
| 769 return succeeded; | 974 return succeeded; |
| 770 } | 975 } |
| 771 | 976 |
| 772 // TODO: This function is using a lot of wonky semantics like, if width == -1 | 977 // TODO: This function is using a lot of wonky semantics like, if width == -1 |
| 773 // then set width = desc.fWdith ... blah. A better way to do it might be to | 978 // then set width = desc.fWdith ... blah. A better way to do it might be to |
| 774 // create a CompressedTexData struct that takes a desc/ptr and figures out | 979 // create a CompressedTexData struct that takes a desc/ptr and figures out |
| 775 // the proper upload semantics. Then users can construct this function how they | 980 // the proper upload semantics. Then users can construct this function how they |
| 776 // see fit if they want to go against the "standard" way to do it. | 981 // see fit if they want to go against the "standard" way to do it. |
| 777 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, | 982 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, |
| 778 const void* data, | 983 const SkTArray<SkMipMapLevel>& texels, |
| 779 bool isNewTexture, | 984 bool isNewTexture, |
| 780 int left, int top, int width, int height) { | 985 int left, int top, int width, int height) { |
| 781 SkASSERT(data || isNewTexture); | 986 SkASSERT(isNewTexture); |
| 782 | 987 |
| 783 // No support for software flip y, yet... | 988 // No support for software flip y, yet... |
| 784 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); | 989 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); |
| 785 | 990 |
| 991 auto interface = this->glInterface(); | |
| 992 if (interface == nullptr) { | |
| 993 return false; | |
| 994 } | |
| 995 auto& caps = this->glCaps(); | |
| 996 auto standard = this->glStandard(); | |
| 997 | |
| 786 if (-1 == width) { | 998 if (-1 == width) { |
| 787 width = desc.fWidth; | 999 width = desc.fWidth; |
| 788 } | 1000 } |
| 789 #ifdef SK_DEBUG | 1001 #ifdef SK_DEBUG |
| 790 else { | 1002 else { |
| 791 SkASSERT(width <= desc.fWidth); | 1003 SkASSERT(width <= desc.fWidth); |
| 792 } | 1004 } |
| 793 #endif | 1005 #endif |
| 794 | 1006 |
| 795 if (-1 == height) { | 1007 if (-1 == height) { |
| 796 height = desc.fHeight; | 1008 height = desc.fHeight; |
| 797 } | 1009 } |
| 798 #ifdef SK_DEBUG | 1010 #ifdef SK_DEBUG |
| 799 else { | 1011 else { |
| 800 SkASSERT(height <= desc.fHeight); | 1012 SkASSERT(height <= desc.fHeight); |
| 801 } | 1013 } |
| 802 #endif | 1014 #endif |
| 803 | 1015 |
| 804 // Make sure that the width and height that we pass to OpenGL | 1016 bool useTexStorage = can_use_tex_storage(caps, standard, desc); |
| 805 // is a multiple of the block size. | |
| 806 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height); | |
| 807 | 1017 |
| 808 // We only need the internal format for compressed 2D textures. | 1018 // We only need the internal format for compressed 2D textures. |
| 809 GrGLenum internalFormat = 0; | 1019 GrGLenum internalFormat = 0; |
| 810 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, nullptr, nullptr)) { | 1020 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, nullptr, nullptr)) { |
| 811 return false; | 1021 return false; |
| 812 } | 1022 } |
| 813 | 1023 |
| 814 if (isNewTexture) { | 1024 if (isNewTexture) { |
| 815 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 1025 return allocate_and_populate_compressed_texture(desc, *interface, useTex Storage, |
| 816 GL_ALLOC_CALL(this->glInterface(), | 1026 internalFormat, texels); |
| 817 CompressedTexImage2D(GR_GL_TEXTURE_2D, | |
| 818 0, // level | |
| 819 internalFormat, | |
| 820 width, height, | |
| 821 0, // border | |
| 822 SkToInt(dataSize), | |
| 823 data)); | |
| 824 GrGLenum error = check_alloc_error(desc, this->glInterface()); | |
| 825 if (error != GR_GL_NO_ERROR) { | |
| 826 return false; | |
| 827 } | |
| 828 } else { | 1027 } else { |
| 829 // Paletted textures can't be updated. | 1028 // Paletted textures can't be updated. |
| 830 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { | 1029 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { |
| 831 return false; | 1030 return false; |
| 832 } | 1031 } |
| 833 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D, | 1032 int currentMipWidth = width; |
| 834 0, // level | 1033 int currentMipHeight = height; |
| 835 left, top, | 1034 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) { |
| 836 width, height, | 1035 if (texels[currentMipLevel].fTexels == nullptr) { |
| 837 internalFormat, | 1036 continue; |
| 838 SkToInt(dataSize), | 1037 } |
| 839 data)); | 1038 |
| 1039 // Make sure that the width and height that we pass to OpenGL | |
| 1040 // is a multiple of the block size. | |
| 1041 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentMi pWidth, currentMipHeight); | |
| 1042 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D, | |
| 1043 0, // level | |
| 1044 left, top, | |
| 1045 currentMipWidth, currentMipHeight, | |
| 1046 internalFormat, | |
| 1047 dataSize, | |
| 1048 texels[currentMipLevel].fTexels)); | |
| 1049 currentMipWidth /= 2; | |
| 1050 currentMipHeight /= 2; | |
| 1051 } | |
| 840 } | 1052 } |
| 841 | 1053 |
| 842 return true; | 1054 return true; |
| 843 } | 1055 } |
| 844 | 1056 |
| 845 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, | 1057 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, |
| 846 int sampleCount, | 1058 int sampleCount, |
| 847 GrGLenum format, | 1059 GrGLenum format, |
| 848 int width, int height) { | 1060 int width, int height) { |
| 849 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); | 1061 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 935 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe rID)); | 1147 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe rID)); |
| 936 if (!renderbuffer_storage_msaa(*fGLContext, | 1148 if (!renderbuffer_storage_msaa(*fGLContext, |
| 937 desc.fSampleCnt, | 1149 desc.fSampleCnt, |
| 938 msColorFormat, | 1150 msColorFormat, |
| 939 desc.fWidth, desc.fHeight)) { | 1151 desc.fWidth, desc.fHeight)) { |
| 940 goto FAILED; | 1152 goto FAILED; |
| 941 } | 1153 } |
| 942 fStats.incRenderTargetBinds(); | 1154 fStats.incRenderTargetBinds(); |
| 943 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); | 1155 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); |
| 944 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1156 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 945 GR_GL_COLOR_ATTACHMENT0, | 1157 GR_GL_COLOR_ATTACHMENT0, |
| 946 GR_GL_RENDERBUFFER, | 1158 GR_GL_RENDERBUFFER, |
| 947 idDesc->fMSColorRenderbufferID)); | 1159 idDesc->fMSColorRenderbufferID)); |
| 948 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || | 1160 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || |
| 949 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { | 1161 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { |
| 950 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1162 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 951 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 1163 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 952 goto FAILED; | 1164 goto FAILED; |
| 953 } | 1165 } |
| 954 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); | 1166 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); |
| 955 } | 1167 } |
| 956 } | 1168 } |
| 957 fStats.incRenderTargetBinds(); | 1169 fStats.incRenderTargetBinds(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 997 // SkDEBUGFAIL("null texture"); | 1209 // SkDEBUGFAIL("null texture"); |
| 998 return nullptr; | 1210 return nullptr; |
| 999 } | 1211 } |
| 1000 | 1212 |
| 1001 #if 0 && defined(SK_DEBUG) | 1213 #if 0 && defined(SK_DEBUG) |
| 1002 static size_t as_size_t(int x) { | 1214 static size_t as_size_t(int x) { |
| 1003 return x; | 1215 return x; |
| 1004 } | 1216 } |
| 1005 #endif | 1217 #endif |
| 1006 | 1218 |
| 1219 static GrGLTexture::IDDesc generate_and_bind_gl_texture(const GrGLInterface* int erface, | |
| 1220 GrGpuResource::LifeCycle lifeCycle) { | |
| 1221 GrGLTexture::IDDesc idDesc; | |
| 1222 GR_GL_CALL(interface, GenTextures(1, &idDesc.fTextureID)); | |
| 1223 idDesc.fLifeCycle = lifeCycle; | |
| 1224 return idDesc; | |
| 1225 } | |
| 1226 | |
| 1227 static GrGLTexture::TexParams set_initial_texture_params(const GrGLInterface* in terface) { | |
| 1228 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | |
| 1229 // drivers have a bug where an FBO won't be complete if it includes a | |
| 1230 // texture that is not mipmap complete (considering the filter in use). | |
| 1231 GrGLTexture::TexParams initialTexParams; | |
| 1232 // we only set a subset here so invalidate first | |
| 1233 initialTexParams.invalidate(); | |
| 1234 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
| 1235 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
| 1236 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
| 1237 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
| 1238 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
| 1239 GR_GL_TEXTURE_MAG_FILTER, | |
| 1240 initialTexParams.fMagFilter)); | |
| 1241 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
| 1242 GR_GL_TEXTURE_MIN_FILTER, | |
| 1243 initialTexParams.fMinFilter)); | |
| 1244 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
| 1245 GR_GL_TEXTURE_WRAP_S, | |
| 1246 initialTexParams.fWrapS)); | |
| 1247 GR_GL_CALL(interface, TexParameteri(GR_GL_TEXTURE_2D, | |
| 1248 GR_GL_TEXTURE_WRAP_T, | |
| 1249 initialTexParams.fWrapT)); | |
| 1250 return initialTexParams; | |
| 1251 } | |
| 1252 | |
| 1007 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, | 1253 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, |
| 1008 GrGpuResource::LifeCycle lifeCycle, | 1254 GrGpuResource::LifeCycle lifeCycle, |
| 1009 const void* srcData, size_t rowBytes) { | 1255 const SkTArray<SkMipMapLevel>& texels) { |
| 1010 // We fail if the MSAA was requested and is not available. | 1256 // We fail if the MSAA was requested and is not available. |
| 1011 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { | 1257 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC nt) { |
| 1012 //SkDebugf("MSAA RT requested but not supported on this platform."); | 1258 //SkDebugf("MSAA RT requested but not supported on this platform."); |
| 1013 return return_null_texture(); | 1259 return return_null_texture(); |
| 1014 } | 1260 } |
| 1015 | 1261 |
| 1016 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); | 1262 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); |
| 1017 | 1263 |
| 1018 GrGLTexture::IDDesc idDesc; | 1264 auto idDesc = generate_and_bind_gl_texture(this->glInterface(), lifeCycle); |
| 1019 GL_CALL(GenTextures(1, &idDesc.fTextureID)); | |
| 1020 idDesc.fLifeCycle = lifeCycle; | |
| 1021 | |
| 1022 if (!idDesc.fTextureID) { | 1265 if (!idDesc.fTextureID) { |
| 1023 return return_null_texture(); | 1266 return return_null_texture(); |
| 1024 } | 1267 } |
| 1025 | 1268 |
| 1026 this->setScratchTextureUnit(); | 1269 this->setScratchTextureUnit(); |
| 1027 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | 1270 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); |
| 1028 | 1271 |
| 1029 if (renderTarget && this->glCaps().textureUsageSupport()) { | 1272 if (renderTarget && this->glCaps().textureUsageSupport()) { |
| 1030 // provides a hint about how this texture will be used | 1273 // provides a hint about how this texture will be used |
| 1031 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 1274 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, |
| 1032 GR_GL_TEXTURE_USAGE, | 1275 GR_GL_TEXTURE_USAGE, |
| 1033 GR_GL_FRAMEBUFFER_ATTACHMENT)); | 1276 GR_GL_FRAMEBUFFER_ATTACHMENT)); |
| 1034 } | 1277 } |
| 1035 | 1278 |
| 1036 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1279 auto initialTexParams = set_initial_texture_params(this->glInterface()); |
| 1037 // drivers have a bug where an FBO won't be complete if it includes a | 1280 |
| 1038 // texture that is not mipmap complete (considering the filter in use). | |
| 1039 GrGLTexture::TexParams initialTexParams; | |
| 1040 // we only set a subset here so invalidate first | |
| 1041 initialTexParams.invalidate(); | |
| 1042 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
| 1043 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
| 1044 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
| 1045 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
| 1046 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
| 1047 GR_GL_TEXTURE_MAG_FILTER, | |
| 1048 initialTexParams.fMagFilter)); | |
| 1049 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
| 1050 GR_GL_TEXTURE_MIN_FILTER, | |
| 1051 initialTexParams.fMinFilter)); | |
| 1052 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
| 1053 GR_GL_TEXTURE_WRAP_S, | |
| 1054 initialTexParams.fWrapS)); | |
| 1055 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
| 1056 GR_GL_TEXTURE_WRAP_T, | |
| 1057 initialTexParams.fWrapT)); | |
| 1058 if (!this->uploadTexData(desc, true, 0, 0, | 1281 if (!this->uploadTexData(desc, true, 0, 0, |
| 1059 desc.fWidth, desc.fHeight, | 1282 desc.fWidth, desc.fHeight, |
| 1060 desc.fConfig, srcData, rowBytes)) { | 1283 desc.fConfig, texels)) { |
| 1061 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1284 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
| 1062 return return_null_texture(); | 1285 return return_null_texture(); |
| 1063 } | 1286 } |
| 1064 | 1287 |
| 1065 GrGLTexture* tex; | 1288 GrGLTexture* tex; |
| 1066 if (renderTarget) { | 1289 if (renderTarget) { |
| 1067 // unbind the texture from the texture unit before binding it to the fra me buffer | 1290 // unbind the texture from the texture unit before binding it to the fra me buffer |
| 1068 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); | 1291 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); |
| 1069 GrGLRenderTarget::IDDesc rtIDDesc; | 1292 GrGLRenderTarget::IDDesc rtIDDesc; |
| 1070 | 1293 |
| 1071 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, &rtIDDesc)) { | 1294 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID, &rtIDDesc)) { |
| 1072 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1295 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
| 1073 return return_null_texture(); | 1296 return return_null_texture(); |
| 1074 } | 1297 } |
| 1075 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); | 1298 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); |
| 1076 } else { | 1299 } else { |
| 1077 tex = new GrGLTexture(this, desc, idDesc); | 1300 tex = new GrGLTexture(this, desc, idDesc); |
| 1078 } | 1301 } |
| 1079 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1302 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
| 1080 #ifdef TRACE_TEXTURE_CREATION | 1303 #ifdef TRACE_TEXTURE_CREATION |
| 1081 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", | 1304 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", |
| 1082 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1305 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
| 1083 #endif | 1306 #endif |
| 1084 return tex; | 1307 return tex; |
| 1085 } | 1308 } |
| 1086 | 1309 |
| 1087 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, | 1310 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, |
| 1088 GrGpuResource::LifeCycle lifeCycle , | 1311 GrGpuResource::LifeCycle lifeCycle , |
| 1089 const void* srcData) { | 1312 const SkTArray<SkMipMapLevel>& tex els) { |
| 1090 // Make sure that we're not flipping Y. | 1313 // Make sure that we're not flipping Y. |
| 1091 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 1314 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
| 1092 return return_null_texture(); | 1315 return return_null_texture(); |
| 1093 } | 1316 } |
| 1094 | 1317 |
| 1095 GrGLTexture::IDDesc idDesc; | 1318 auto idDesc = generate_and_bind_gl_texture(this->glInterface(), lifeCycle); |
| 1096 GL_CALL(GenTextures(1, &idDesc.fTextureID)); | |
| 1097 idDesc.fLifeCycle = lifeCycle; | |
| 1098 | |
| 1099 if (!idDesc.fTextureID) { | 1319 if (!idDesc.fTextureID) { |
| 1100 return return_null_texture(); | 1320 return return_null_texture(); |
| 1101 } | 1321 } |
| 1102 | 1322 |
| 1103 this->setScratchTextureUnit(); | 1323 this->setScratchTextureUnit(); |
| 1104 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | 1324 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); |
| 1105 | 1325 |
| 1106 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1326 auto initialTexParams = set_initial_texture_params(this->glInterface()); |
| 1107 // drivers have a bug where an FBO won't be complete if it includes a | |
| 1108 // texture that is not mipmap complete (considering the filter in use). | |
| 1109 GrGLTexture::TexParams initialTexParams; | |
| 1110 // we only set a subset here so invalidate first | |
| 1111 initialTexParams.invalidate(); | |
| 1112 initialTexParams.fMinFilter = GR_GL_NEAREST; | |
| 1113 initialTexParams.fMagFilter = GR_GL_NEAREST; | |
| 1114 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; | |
| 1115 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; | |
| 1116 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
| 1117 GR_GL_TEXTURE_MAG_FILTER, | |
| 1118 initialTexParams.fMagFilter)); | |
| 1119 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
| 1120 GR_GL_TEXTURE_MIN_FILTER, | |
| 1121 initialTexParams.fMinFilter)); | |
| 1122 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
| 1123 GR_GL_TEXTURE_WRAP_S, | |
| 1124 initialTexParams.fWrapS)); | |
| 1125 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | |
| 1126 GR_GL_TEXTURE_WRAP_T, | |
| 1127 initialTexParams.fWrapT)); | |
| 1128 | 1327 |
| 1129 if (!this->uploadCompressedTexData(desc, srcData)) { | 1328 if (!this->uploadCompressedTexData(desc, texels)) { |
| 1130 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1329 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
| 1131 return return_null_texture(); | 1330 return return_null_texture(); |
| 1132 } | 1331 } |
| 1133 | 1332 |
| 1134 GrGLTexture* tex; | 1333 GrGLTexture* tex; |
| 1135 tex = new GrGLTexture(this, desc, idDesc); | 1334 tex = new GrGLTexture(this, desc, idDesc); |
| 1136 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1335 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
| 1137 #ifdef TRACE_TEXTURE_CREATION | 1336 #ifdef TRACE_TEXTURE_CREATION |
| 1138 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", | 1337 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", |
| 1139 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1338 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1934 fHWSRGBFramebuffer = kYes_TriState; | 2133 fHWSRGBFramebuffer = kYes_TriState; |
| 1935 } else if (!enableSRGBWrite && kNo_TriState != fHWSRGBFramebuffer) { | 2134 } else if (!enableSRGBWrite && kNo_TriState != fHWSRGBFramebuffer) { |
| 1936 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); | 2135 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); |
| 1937 fHWSRGBFramebuffer = kNo_TriState; | 2136 fHWSRGBFramebuffer = kNo_TriState; |
| 1938 } | 2137 } |
| 1939 } | 2138 } |
| 1940 } | 2139 } |
| 1941 if (nullptr == bound || !bound->isEmpty()) { | 2140 if (nullptr == bound || !bound->isEmpty()) { |
| 1942 target->flagAsNeedingResolve(bound); | 2141 target->flagAsNeedingResolve(bound); |
| 1943 } | 2142 } |
| 1944 | |
| 1945 GrTexture *texture = target->asTexture(); | |
| 1946 if (texture) { | |
| 1947 texture->texturePriv().dirtyMipMaps(true); | |
| 1948 } | |
| 1949 } | 2143 } |
| 1950 | 2144 |
| 1951 GrGLenum gPrimitiveType2GLMode[] = { | 2145 GrGLenum gPrimitiveType2GLMode[] = { |
| 1952 GR_GL_TRIANGLES, | 2146 GR_GL_TRIANGLES, |
| 1953 GR_GL_TRIANGLE_STRIP, | 2147 GR_GL_TRIANGLE_STRIP, |
| 1954 GR_GL_TRIANGLE_FAN, | 2148 GR_GL_TRIANGLE_FAN, |
| 1955 GR_GL_POINTS, | 2149 GR_GL_POINTS, |
| 1956 GR_GL_LINES, | 2150 GR_GL_LINES, |
| 1957 GR_GL_LINE_STRIP | 2151 GR_GL_LINE_STRIP |
| 1958 }; | 2152 }; |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2280 GrTextureParams::FilterMode filterMode = params.filterMode(); | 2474 GrTextureParams::FilterMode filterMode = params.filterMode(); |
| 2281 | 2475 |
| 2282 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | 2476 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
| 2283 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) { | 2477 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) { |
| 2284 filterMode = GrTextureParams::kBilerp_FilterMode; | 2478 filterMode = GrTextureParams::kBilerp_FilterMode; |
| 2285 } | 2479 } |
| 2286 } | 2480 } |
| 2287 | 2481 |
| 2288 newTexParams.fMinFilter = glMinFilterModes[filterMode]; | 2482 newTexParams.fMinFilter = glMinFilterModes[filterMode]; |
| 2289 newTexParams.fMagFilter = glMagFilterModes[filterMode]; | 2483 newTexParams.fMagFilter = glMagFilterModes[filterMode]; |
| 2290 | |
| 2291 if (GrTextureParams::kMipMap_FilterMode == filterMode && | |
| 2292 texture->texturePriv().mipMapsAreDirty()) { | |
| 2293 GL_CALL(GenerateMipmap(GR_GL_TEXTURE_2D)); | |
| 2294 texture->texturePriv().dirtyMipMaps(false); | |
| 2295 } | |
| 2296 | |
| 2297 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); | 2484 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); |
| 2298 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); | 2485 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); |
| 2299 memcpy(newTexParams.fSwizzleRGBA, | 2486 memcpy(newTexParams.fSwizzleRGBA, |
| 2300 GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps ()), | 2487 GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps ()), |
| 2301 sizeof(newTexParams.fSwizzleRGBA)); | 2488 sizeof(newTexParams.fSwizzleRGBA)); |
| 2302 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { | 2489 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { |
| 2303 this->setTextureUnit(unitIdx); | 2490 this->setTextureUnit(unitIdx); |
| 2304 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 2491 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, |
| 2305 GR_GL_TEXTURE_MAG_FILTER, | 2492 GR_GL_TEXTURE_MAG_FILTER, |
| 2306 newTexParams.fMagFilter)); | 2493 newTexParams.fMagFilter)); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2558 *internalFormat = GR_GL_ALPHA; | 2745 *internalFormat = GR_GL_ALPHA; |
| 2559 } | 2746 } |
| 2560 *externalFormat = GR_GL_ALPHA; | 2747 *externalFormat = GR_GL_ALPHA; |
| 2561 } | 2748 } |
| 2562 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { | 2749 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { |
| 2563 *externalType = GR_GL_HALF_FLOAT; | 2750 *externalType = GR_GL_HALF_FLOAT; |
| 2564 } else { | 2751 } else { |
| 2565 *externalType = GR_GL_HALF_FLOAT_OES; | 2752 *externalType = GR_GL_HALF_FLOAT_OES; |
| 2566 } | 2753 } |
| 2567 break; | 2754 break; |
| 2568 | 2755 |
| 2569 case kRGBA_half_GrPixelConfig: | 2756 case kRGBA_half_GrPixelConfig: |
| 2570 *internalFormat = GR_GL_RGBA16F; | 2757 *internalFormat = GR_GL_RGBA16F; |
| 2571 *externalFormat = GR_GL_RGBA; | 2758 *externalFormat = GR_GL_RGBA; |
| 2572 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { | 2759 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G R_GL_VER(3, 0)) { |
| 2573 *externalType = GR_GL_HALF_FLOAT; | 2760 *externalType = GR_GL_HALF_FLOAT; |
| 2574 } else { | 2761 } else { |
| 2575 *externalType = GR_GL_HALF_FLOAT_OES; | 2762 *externalType = GR_GL_HALF_FLOAT_OES; |
| 2576 } | 2763 } |
| 2577 break; | 2764 break; |
| 2578 | 2765 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2753 } | 2940 } |
| 2754 | 2941 |
| 2755 bool GrGLGpu::onCopySurface(GrSurface* dst, | 2942 bool GrGLGpu::onCopySurface(GrSurface* dst, |
| 2756 GrSurface* src, | 2943 GrSurface* src, |
| 2757 const SkIRect& srcRect, | 2944 const SkIRect& srcRect, |
| 2758 const SkIPoint& dstPoint) { | 2945 const SkIPoint& dstPoint) { |
| 2759 if (src->asTexture() && dst->asRenderTarget()) { | 2946 if (src->asTexture() && dst->asRenderTarget()) { |
| 2760 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | 2947 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); |
| 2761 return true; | 2948 return true; |
| 2762 } | 2949 } |
| 2763 | 2950 |
| 2764 if (can_copy_texsubimage(dst, src, this)) { | 2951 if (can_copy_texsubimage(dst, src, this)) { |
| 2765 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); | 2952 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); |
| 2766 return true; | 2953 return true; |
| 2767 } | 2954 } |
| 2768 | 2955 |
| 2769 if (can_blit_framebuffer(dst, src, this)) { | 2956 if (can_blit_framebuffer(dst, src, this)) { |
| 2770 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); | 2957 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); |
| 2771 } | 2958 } |
| 2772 | 2959 |
| 2773 return false; | 2960 return false; |
| 2774 } | 2961 } |
| 2775 | 2962 |
| 2776 | 2963 |
| 2777 void GrGLGpu::createCopyProgram() { | 2964 void GrGLGpu::createCopyProgram() { |
| 2778 const char* version = GrGLGetGLSLVersionDecl(this->ctxInfo()); | 2965 const char* version = GrGLGetGLSLVersionDecl(this->ctxInfo()); |
| 2779 | 2966 |
| 2780 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T ypeModifier); | 2967 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T ypeModifier); |
| 2781 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, | 2968 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, |
| 2782 GrShaderVar::kUniform_TypeModifier); | 2969 GrShaderVar::kUniform_TypeModifier); |
| 2783 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform _TypeModifier); | 2970 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform _TypeModifier); |
| 2784 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo rm_TypeModifier); | 2971 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo rm_TypeModifier); |
| 2785 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying Out_TypeModifier); | 2972 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying Out_TypeModifier); |
| 2786 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier); | 2973 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier); |
| 2787 | 2974 |
| 2788 SkString vshaderTxt(version); | 2975 SkString vshaderTxt(version); |
| 2789 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt); | 2976 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2790 vshaderTxt.append(";"); | 2977 vshaderTxt.append(";"); |
| 2791 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt); | 2978 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2792 vshaderTxt.append(";"); | 2979 vshaderTxt.append(";"); |
| 2793 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt); | 2980 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2794 vshaderTxt.append(";"); | 2981 vshaderTxt.append(";"); |
| 2795 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt); | 2982 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2796 vshaderTxt.append(";"); | 2983 vshaderTxt.append(";"); |
| 2797 | 2984 |
| 2798 vshaderTxt.append( | 2985 vshaderTxt.append( |
| 2799 "// Copy Program VS\n" | 2986 "// Copy Program VS\n" |
| 2800 "void main() {" | 2987 "void main() {" |
| 2801 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" | 2988 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" |
| 2802 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" | 2989 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" |
| 2803 " gl_Position.zw = vec2(0, 1);" | 2990 " gl_Position.zw = vec2(0, 1);" |
| 2804 "}" | 2991 "}" |
| 2805 ); | 2992 ); |
| 2806 | 2993 |
| 2807 SkString fshaderTxt(version); | 2994 SkString fshaderTxt(version); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2821 fsOutName = "gl_FragColor"; | 3008 fsOutName = "gl_FragColor"; |
| 2822 } | 3009 } |
| 2823 fshaderTxt.appendf( | 3010 fshaderTxt.appendf( |
| 2824 "// Copy Program FS\n" | 3011 "// Copy Program FS\n" |
| 2825 "void main() {" | 3012 "void main() {" |
| 2826 " %s = %s(u_texture, v_texCoord);" | 3013 " %s = %s(u_texture, v_texCoord);" |
| 2827 "}", | 3014 "}", |
| 2828 fsOutName, | 3015 fsOutName, |
| 2829 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) | 3016 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) |
| 2830 ); | 3017 ); |
| 2831 | 3018 |
| 2832 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); | 3019 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); |
| 2833 const char* str; | 3020 const char* str; |
| 2834 GrGLint length; | 3021 GrGLint length; |
| 2835 | 3022 |
| 2836 str = vshaderTxt.c_str(); | 3023 str = vshaderTxt.c_str(); |
| 2837 length = SkToInt(vshaderTxt.size()); | 3024 length = SkToInt(vshaderTxt.size()); |
| 2838 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram, | 3025 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro gram, |
| 2839 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats); | 3026 GR_GL_VERTEX_SHADER, &str, &le ngth, 1, &fStats); |
| 2840 | 3027 |
| 2841 str = fshaderTxt.c_str(); | 3028 str = fshaderTxt.c_str(); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3160 this->setVertexArrayID(gpu, 0); | 3347 this->setVertexArrayID(gpu, 0); |
| 3161 } | 3348 } |
| 3162 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3349 int attrCount = gpu->glCaps().maxVertexAttributes(); |
| 3163 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 3350 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
| 3164 fDefaultVertexArrayAttribState.resize(attrCount); | 3351 fDefaultVertexArrayAttribState.resize(attrCount); |
| 3165 } | 3352 } |
| 3166 attribState = &fDefaultVertexArrayAttribState; | 3353 attribState = &fDefaultVertexArrayAttribState; |
| 3167 } | 3354 } |
| 3168 return attribState; | 3355 return attribState; |
| 3169 } | 3356 } |
| OLD | NEW |