| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 | 8 |
| 9 #include "GrGLGpu.h" | 9 #include "GrGLGpu.h" |
| 10 #include "GrGLGLSL.h" | 10 #include "GrGLGLSL.h" |
| 11 #include "GrGLStencilAttachment.h" | 11 #include "GrGLStencilAttachment.h" |
| 12 #include "GrGLTextureRenderTarget.h" | 12 #include "GrGLTextureRenderTarget.h" |
| 13 #include "GrGpuResourcePriv.h" | 13 #include "GrGpuResourcePriv.h" |
| 14 #include "GrPipeline.h" | 14 #include "GrPipeline.h" |
| 15 #include "GrRenderTargetPriv.h" | 15 #include "GrRenderTargetPriv.h" |
| 16 #include "GrSurfacePriv.h" | 16 #include "GrSurfacePriv.h" |
| 17 #include "GrTexturePriv.h" | 17 #include "GrTexturePriv.h" |
| 18 #include "GrTypes.h" | 18 #include "GrTypes.h" |
| 19 #include "GrVertices.h" | 19 #include "GrVertices.h" |
| 20 #include "builders/GrGLShaderStringBuilder.h" | 20 #include "builders/GrGLShaderStringBuilder.h" |
| 21 #include "glsl/GrGLSL.h" | 21 #include "glsl/GrGLSL.h" |
| 22 #include "glsl/GrGLSLCaps.h" | 22 #include "glsl/GrGLSLCaps.h" |
| 23 #include "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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 ¤tMipWidth, |
| 939 ¤tMipHeight, |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |