| 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 | |
| 9 #include "GrGLGpu.h" | 8 #include "GrGLGpu.h" |
| 10 #include "GrGLGLSL.h" | 9 #include "GrGLGLSL.h" |
| 11 #include "GrGLStencilAttachment.h" | 10 #include "GrGLStencilAttachment.h" |
| 12 #include "GrGLTextureRenderTarget.h" | 11 #include "GrGLTextureRenderTarget.h" |
| 13 #include "GrGpuResourcePriv.h" | 12 #include "GrGpuResourcePriv.h" |
| 14 #include "GrPipeline.h" | 13 #include "GrPipeline.h" |
| 15 #include "GrRenderTargetPriv.h" | 14 #include "GrRenderTargetPriv.h" |
| 16 #include "GrSurfacePriv.h" | 15 #include "GrSurfacePriv.h" |
| 17 #include "GrTexturePriv.h" | 16 #include "GrTexturePriv.h" |
| 18 #include "GrTypes.h" | 17 #include "GrTypes.h" |
| 19 #include "GrVertices.h" | 18 #include "GrVertices.h" |
| 20 #include "builders/GrGLShaderStringBuilder.h" | 19 #include "builders/GrGLShaderStringBuilder.h" |
| 21 #include "glsl/GrGLSLCaps.h" | 20 #include "glsl/GrGLSLCaps.h" |
| 22 #include "SkStrokeRec.h" | 21 #include "SkStrokeRec.h" |
| 23 #include "SkTemplates.h" | 22 #include "SkTemplates.h" |
| 23 #include "SkTypes.h" |
| 24 | 24 |
| 25 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) | 25 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) |
| 26 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) | 26 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) |
| 27 | 27 |
| 28 #define SKIP_CACHE_CHECK true | 28 #define SKIP_CACHE_CHECK true |
| 29 | 29 |
| 30 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR | 30 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR |
| 31 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) | 31 #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface) |
| 32 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) | 32 #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call) |
| 33 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) | 33 #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface) |
| (...skipping 385 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 // We only support GL_TEXTURE_2D at the moment. |
| 430 idDesc.fTarget = GR_GL_TEXTURE_2D; |
| 431 |
| 430 switch (ownership) { | 432 switch (ownership) { |
| 431 case kAdopt_GrWrapOwnership: | 433 case kAdopt_GrWrapOwnership: |
| 432 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; | 434 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; |
| 433 break; | 435 break; |
| 434 case kBorrow_GrWrapOwnership: | 436 case kBorrow_GrWrapOwnership: |
| 435 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; | 437 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; |
| 436 break; | 438 break; |
| 437 } | 439 } |
| 438 | 440 |
| 439 // next line relies on GrBackendTextureDesc's flags matching GrTexture's | 441 // next line relies on GrBackendTextureDesc's flags matching GrTexture's |
| 440 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; | 442 surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags; |
| 441 surfDesc.fWidth = desc.fWidth; | 443 surfDesc.fWidth = desc.fWidth; |
| 442 surfDesc.fHeight = desc.fHeight; | 444 surfDesc.fHeight = desc.fHeight; |
| 443 surfDesc.fConfig = desc.fConfig; | 445 surfDesc.fConfig = desc.fConfig; |
| 444 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()
); | 446 surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount()
); |
| 445 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla
g); | 447 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFla
g); |
| 446 // FIXME: this should be calling resolve_origin(), but Chrome code is curre
ntly | 448 // 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 | 449 // assuming the old behaviour, which is that backend textures are always |
| 448 // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to: | 450 // BottomLeft, even for non-RT's. Once Chrome is fixed, change this to: |
| 449 // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget); | 451 // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget); |
| 450 if (kDefault_GrSurfaceOrigin == desc.fOrigin) { | 452 if (kDefault_GrSurfaceOrigin == desc.fOrigin) { |
| 451 surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; | 453 surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; |
| 452 } else { | 454 } else { |
| 453 surfDesc.fOrigin = desc.fOrigin; | 455 surfDesc.fOrigin = desc.fOrigin; |
| 454 } | 456 } |
| 455 | 457 |
| 456 GrGLTexture* texture = nullptr; | 458 GrGLTexture* texture = nullptr; |
| 457 if (renderTarget) { | 459 if (renderTarget) { |
| 458 GrGLRenderTarget::IDDesc rtIDDesc; | 460 GrGLRenderTarget::IDDesc rtIDDesc; |
| 459 if (!this->createRenderTargetObjects(surfDesc, GrGpuResource::kUncached_
LifeCycle, | 461 if (!this->createRenderTargetObjects(surfDesc, GrGpuResource::kUncached_
LifeCycle, |
| 460 idDesc.fTextureID, &rtIDDesc)) { | 462 idDesc.fTextureID, idDesc.fTarget,
&rtIDDesc)) { |
| 461 return nullptr; | 463 return nullptr; |
| 462 } | 464 } |
| 463 texture = new GrGLTextureRenderTarget(this, surfDesc, idDesc, rtIDDesc); | 465 texture = new GrGLTextureRenderTarget(this, surfDesc, idDesc, rtIDDesc); |
| 464 } else { | 466 } else { |
| 465 texture = new GrGLTexture(this, surfDesc, idDesc); | 467 texture = new GrGLTexture(this, surfDesc, idDesc); |
| 466 } | 468 } |
| 467 if (nullptr == texture) { | 469 if (nullptr == texture) { |
| 468 return nullptr; | 470 return nullptr; |
| 469 } | 471 } |
| 470 | 472 |
| 471 return texture; | 473 return texture; |
| 472 } | 474 } |
| 473 | 475 |
| 474 GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
sc& wrapDesc, | 476 GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
sc& wrapDesc, |
| 475 GrWrapOwnership ownership) { | 477 GrWrapOwnership ownership) { |
| 476 GrGLRenderTarget::IDDesc idDesc; | 478 GrGLRenderTarget::IDDesc idDesc; |
| 477 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); | 479 idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle); |
| 478 idDesc.fMSColorRenderbufferID = 0; | 480 idDesc.fMSColorRenderbufferID = 0; |
| 479 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; | 481 idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; |
| 480 switch (ownership) { | 482 switch (ownership) { |
| 481 case kAdopt_GrWrapOwnership: | 483 case kAdopt_GrWrapOwnership: |
| 482 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; | 484 idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle; |
| 483 break; | 485 break; |
| 484 case kBorrow_GrWrapOwnership: | 486 case kBorrow_GrWrapOwnership: |
| 485 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; | 487 idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle; |
| 486 break; | 488 break; |
| 487 } | 489 } |
| 488 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; | 490 idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; |
| 489 | 491 |
| 490 GrSurfaceDesc desc; | 492 GrSurfaceDesc desc; |
| 491 desc.fConfig = wrapDesc.fConfig; | 493 desc.fConfig = wrapDesc.fConfig; |
| 492 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; | 494 desc.fFlags = kCheckAllocation_GrSurfaceFlag | kRenderTarget_GrSurfaceFlag; |
| 493 desc.fWidth = wrapDesc.fWidth; | 495 desc.fWidth = wrapDesc.fWidth; |
| 494 desc.fHeight = wrapDesc.fHeight; | 496 desc.fHeight = wrapDesc.fHeight; |
| 495 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()
); | 497 desc.fSampleCnt = SkTMin(wrapDesc.fSampleCnt, this->caps()->maxSampleCount()
); |
| 496 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); | 498 desc.fOrigin = resolve_origin(wrapDesc.fOrigin, true); |
| 497 | 499 |
| 498 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil
Bits); | 500 return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencil
Bits); |
| 499 } | 501 } |
| 500 | 502 |
| 501 //////////////////////////////////////////////////////////////////////////////// | 503 //////////////////////////////////////////////////////////////////////////////// |
| 502 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, | 504 bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, |
| 503 size_t rowBytes, GrPixelConfig srcConfig, | 505 GrPixelConfig srcConfig, |
| 504 DrawPreference* drawPreference, | 506 DrawPreference* drawPreference, |
| 505 WritePixelTempDrawInfo* tempDrawInfo) { | 507 WritePixelTempDrawInfo* tempDrawInfo) { |
| 506 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf
ace->config())) { | 508 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf
ace->config())) { |
| 507 return false; | 509 return false; |
| 508 } | 510 } |
| 509 | 511 |
| 510 // This subclass only allows writes to textures. If the dst is not a texture
we have to draw | 512 // 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. | 513 // into it. We could use glDrawPixels on GLs that have it, but we don't toda
y. |
| 512 if (!dstSurface->asTexture()) { | 514 if (!dstSurface->asTexture()) { |
| 513 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); | 515 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 if (!this->glCaps().unpackFlipYSupport() && | 555 if (!this->glCaps().unpackFlipYSupport() && |
| 554 kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) { | 556 kBottomLeft_GrSurfaceOrigin == dstSurface->origin()) { |
| 555 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); | 557 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); |
| 556 } | 558 } |
| 557 | 559 |
| 558 return true; | 560 return true; |
| 559 } | 561 } |
| 560 | 562 |
| 561 bool GrGLGpu::onWritePixels(GrSurface* surface, | 563 bool GrGLGpu::onWritePixels(GrSurface* surface, |
| 562 int left, int top, int width, int height, | 564 int left, int top, int width, int height, |
| 563 GrPixelConfig config, const void* buffer, | 565 GrPixelConfig config, |
| 564 size_t rowBytes) { | 566 const SkTArray<SkMipMapLevel>& texels) { |
| 565 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); | 567 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); |
| 566 if (!glTex) { | 568 if (!glTex) { |
| 567 return false; | 569 return false; |
| 568 } | 570 } |
| 569 | 571 |
| 570 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi
xels. | 572 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi
xels. |
| 571 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { | 573 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { |
| 572 return false; | 574 return false; |
| 573 } | 575 } |
| 574 | 576 |
| 575 this->setScratchTextureUnit(); | 577 this->setScratchTextureUnit(); |
| 576 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); | 578 GL_CALL(BindTexture(glTex->target(), glTex->textureID())); |
| 577 | 579 |
| 578 bool success = false; | 580 bool success = false; |
| 579 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { | 581 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { |
| 580 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel
s() | 582 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel
s() |
| 581 SkASSERT(config == glTex->desc().fConfig); | 583 SkASSERT(config == glTex->desc().fConfig); |
| 582 success = this->uploadCompressedTexData(glTex->desc(), buffer, false, le
ft, top, width, | 584 success = this->uploadCompressedTexData(glTex->desc(), glTex->target(),
texels, false, |
| 583 height); | 585 left, top, width, height); |
| 584 } else { | 586 } else { |
| 585 success = this->uploadTexData(glTex->desc(), false, left, top, width, he
ight, config, | 587 success = this->uploadTexData(glTex->desc(), glTex->target(), false, lef
t, top, width, |
| 586 buffer, rowBytes); | 588 height, config, texels); |
| 587 } | 589 } |
| 588 | 590 |
| 589 if (success) { | 591 return success; |
| 590 glTex->texturePriv().dirtyMipMaps(true); | |
| 591 return true; | |
| 592 } | |
| 593 | |
| 594 return false; | |
| 595 } | 592 } |
| 596 | 593 |
| 597 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, | 594 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, |
| 598 const GrGLInterface* interface) { | 595 const GrGLInterface* interface) { |
| 599 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { | 596 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { |
| 600 return GR_GL_GET_ERROR(interface); | 597 return GR_GL_GET_ERROR(interface); |
| 601 } else { | 598 } else { |
| 602 return CHECK_ALLOC_ERROR(interface); | 599 return CHECK_ALLOC_ERROR(interface); |
| 603 } | 600 } |
| 604 } | 601 } |
| 605 | 602 |
| 606 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, | 603 /** |
| 607 bool isNewTexture, | 604 * Determines if TexStorage can be used when creating a texture. |
| 608 int left, int top, int width, int height, | 605 * |
| 609 GrPixelConfig dataConfig, | 606 * @param caps The capabilities of the GL device. |
| 610 const void* data, | 607 * @param standard The GL standard in use. |
| 611 size_t rowBytes) { | 608 * @param desc The surface descriptor for the texture being created. |
| 612 SkASSERT(data || isNewTexture); | 609 */ |
| 613 | 610 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 | 611 const GrSurfaceDesc& desc) { |
| 615 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | 612 bool useTexStorage = caps.texStorageSupport(); |
| 616 | 613 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 | 614 // 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 | 615 // 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 | 616 // the best sized format to convert the 565 data to. Since TexStorage |
| 639 // only allows sized internal formats we will instead use TexImage2D. | 617 // only allows sized internal formats we will instead use TexImage2D. |
| 640 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; | 618 useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig; |
| 641 } | 619 } |
| 642 | 620 |
| 643 GrGLenum internalFormat = 0x0; // suppress warning | 621 return useTexStorage; |
| 644 GrGLenum externalFormat = 0x0; // suppress warning | 622 } |
| 645 GrGLenum externalType = 0x0; // suppress warning | |
| 646 | 623 |
| 624 /** |
| 625 * Determines if sized internal formats are available for the texture being crea
ted. |
| 626 * |
| 627 * @param useTexStorage The result of a call to can_use_tex_storage(). |
| 628 * @param caps The capabilities of the GL device. |
| 629 * @param standard The GL standard in use. |
| 630 * @param version The GL version in use. |
| 631 * @param dataConfig The pixel configuration for the texture being created. |
| 632 */ |
| 633 static bool can_use_sized_format(bool useTexStorage, const GrGLCaps& caps, |
| 634 const GrGLStandard& standard, const GrGLVersion
& version, |
| 635 GrPixelConfig dataConfig) { |
| 647 // glTexStorage requires sized internal formats on both desktop and ES. ES2
requires an unsized | 636 // glTexStorage requires sized internal formats on both desktop and ES. ES2
requires an unsized |
| 648 // format for glTexImage, unlike ES3 and desktop. | 637 // format for glTexImage, unlike ES3 and desktop. |
| 649 bool useSizedFormat = useTexStorage; | 638 bool useSizedFormat = useTexStorage; |
| 650 if (kGL_GrGLStandard == this->glStandard() || | 639 if (kGL_GrGLStandard == standard || |
| 651 (this->glVersion() >= GR_GL_VER(3, 0) && | 640 (version >= GR_GL_VER(3, 0) && |
| 652 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B
GRA8888" enabled | 641 // ES3 only works with sized BGRA8 format if "GL_APPLE_texture_format_B
GRA8888" enabled |
| 653 (kBGRA_8888_GrPixelConfig != dataConfig || !this->glCaps().bgraIsIntern
alFormat()))) { | 642 (kBGRA_8888_GrPixelConfig != dataConfig || !caps.bgraIsInternalFormat()
))) { |
| 654 useSizedFormat = true; | 643 useSizedFormat = true; |
| 655 } | 644 } |
| 656 | 645 |
| 657 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, | 646 return useSizedFormat; |
| 658 &externalFormat, &externalType)) { | 647 } |
| 659 return false; | |
| 660 } | |
| 661 | 648 |
| 662 /* | 649 /** |
| 663 * check whether to allocate a temporary buffer for flipping y or | 650 * 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 | 651 * prepares the texels for texture creation. |
| 665 * to trim those off here, since GL ES may not let us specify | 652 * |
| 666 * GL_UNPACK_ROW_LENGTH. | 653 * @param desc The surface descriptor for the texture being create
d. |
| 667 */ | 654 * @param caps The capabilities of the GL device. |
| 668 bool restoreGLRowLength = false; | 655 * @param interface The GL interface in use. |
| 669 bool swFlipY = false; | 656 * @param swFlipY Should software be used when flipping a texture ver
tically? |
| 670 bool glFlipY = false; | 657 * @param glFlipY Should GL be used when flipping a texture verticall
y? |
| 671 if (data) { | 658 * @param width The width of the texture in texels. |
| 672 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 659 * @param height The height of the texture in texels. |
| 673 if (this->glCaps().unpackFlipYSupport()) { | 660 * @param bpp The bits per pixel (or texel, really) of the textur
e. |
| 674 glFlipY = true; | 661 * @param texels An array of mipmap levels which contain the texel d
ata at that level. |
| 675 } else { | 662 * @param tempStorage In the case where the image needs to be flipped ver
tically, it will |
| 676 swFlipY = true; | 663 * use tempStorage as a buffer. |
| 677 } | 664 * @param restoreGLRowLength After the texture is created, will the GL row lengt
h unpacking need |
| 665 * to be restored? |
| 666 */ |
| 667 static void prepare_image_for_writing_to_texture(const GrSurfaceDesc& desc, cons
t GrGLCaps& caps, |
| 668 const GrGLInterface& interface,
bool swFlipY, |
| 669 bool glFlipY, int bpp, |
| 670 SkTArray<SkMipMapLevel>& texels
, |
| 671 SkAutoSMalloc<128 * 128>& tempS
torage, |
| 672 bool* restoreGLRowLength) { |
| 673 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe
vel++) { |
| 674 if (texels[currentMipLevel].fTexels == nullptr) { |
| 675 continue; |
| 678 } | 676 } |
| 679 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { | 677 |
| 678 const size_t trimRowBytes = texels[currentMipLevel].fWidth * bpp; |
| 679 |
| 680 /* |
| 681 * check whether to allocate a temporary buffer for flipping y or |
| 682 * because our srcData has extra bytes past each row. If so, we need |
| 683 * to trim those off here, since GL ES may not let us specify |
| 684 * GL_UNPACK_ROW_LENGTH. |
| 685 */ |
| 686 *restoreGLRowLength = false; |
| 687 |
| 688 const size_t rowBytes = texels[currentMipLevel].fRowBytes; |
| 689 if (caps.unpackRowLengthSupport() && !swFlipY) { |
| 680 // can't use this for flipping, only non-neg values allowed. :( | 690 // can't use this for flipping, only non-neg values allowed. :( |
| 681 if (rowBytes != trimRowBytes) { | 691 if (rowBytes != trimRowBytes) { |
| 682 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); | 692 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp); |
| 683 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength)); | 693 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowL
ength)); |
| 684 restoreGLRowLength = true; | 694 *restoreGLRowLength = true; |
| 685 } | 695 } |
| 686 } else { | 696 } else { |
| 687 if (trimRowBytes != rowBytes || swFlipY) { | 697 if (trimRowBytes != rowBytes || swFlipY) { |
| 698 const uint32_t height = texels[currentMipLevel].fHeight; |
| 688 // copy data into our new storage, skipping the trailing bytes | 699 // copy data into our new storage, skipping the trailing bytes |
| 689 size_t trimSize = height * trimRowBytes; | 700 const size_t trimSize = height * trimRowBytes; |
| 690 const char* src = (const char*)data; | 701 const char* src = (const char*)texels[currentMipLevel].fTexels; |
| 691 if (swFlipY) { | 702 if (swFlipY && height >= 1) { |
| 692 src += (height - 1) * rowBytes; | 703 src += (height - 1) * rowBytes; |
| 693 } | 704 } |
| 694 char* dst = (char*)tempStorage.reset(trimSize); | 705 char* dst = (char*)tempStorage.reset(trimSize); |
| 695 for (int y = 0; y < height; y++) { | 706 for (uint32_t y = 0; y < height; y++) { |
| 696 memcpy(dst, src, trimRowBytes); | 707 memcpy(dst, src, trimRowBytes); |
| 697 if (swFlipY) { | 708 if (swFlipY) { |
| 698 src -= rowBytes; | 709 src -= rowBytes; |
| 699 } else { | 710 } else { |
| 700 src += rowBytes; | 711 src += rowBytes; |
| 701 } | 712 } |
| 702 dst += trimRowBytes; | 713 dst += trimRowBytes; |
| 703 } | 714 } |
| 704 // now point data to our copied version | 715 // now point data to our copied version |
| 705 data = tempStorage.get(); | 716 texels[currentMipLevel] = SkMipMapLevel(tempStorage.get(), trimR
owBytes, |
| 717 texels[currentMipLevel].
fWidth, |
| 718 texels[currentMipLevel].
fHeight); |
| 706 } | 719 } |
| 707 } | 720 } |
| 708 if (glFlipY) { | 721 if (glFlipY) { |
| 709 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); | 722 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE))
; |
| 710 } | 723 } |
| 711 GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, | 724 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, |
| 712 static_cast<GrGLint>(GrUnpackAlignment(dataConfig)))); | 725 static_cast<GrGLint>(GrUnpackAlignmen
t(desc.fConfig)))); |
| 713 } | 726 } |
| 727 } |
| 728 |
| 729 /** |
| 730 * Creates storage space for the texture and fills it with texels. |
| 731 * |
| 732 * @param desc The surface descriptor for the texture being created. |
| 733 * @param interface The GL interface in use. |
| 734 * @param useTexStorage The result of a call to can_use_tex_storage(). |
| 735 * @param internalFormat The data format used for the internal storage of the te
xture. |
| 736 * @param externalFormat The data format used for the external storage of the te
xture. |
| 737 * @param externalType The type of the data used for the external storage of t
he texture. |
| 738 * @param texels The texel data of the texture being created. |
| 739 * @param succeeded Set to true if allocating and populating the texture co
mpleted |
| 740 * without error. |
| 741 */ |
| 742 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc
, |
| 743 const GrGLInterface& inte
rface, |
| 744 GrGLenum target, |
| 745 bool useTexStorage, |
| 746 GrGLenum internalFormat, |
| 747 GrGLenum externalFormat, |
| 748 GrGLenum externalType, |
| 749 const SkTArray<SkMipMapLe
vel>& texels, |
| 750 bool* succeeded) { |
| 751 CLEAR_ERROR_BEFORE_ALLOC(&interface); |
| 752 if (useTexStorage) { |
| 753 // We never resize or change formats of textures. |
| 754 GL_ALLOC_CALL(&interface, |
| 755 TexStorage2D(target, |
| 756 texels.count(), |
| 757 internalFormat, |
| 758 desc.fWidth, desc.fHeight)); |
| 759 |
| 760 GrGLenum error = check_alloc_error(desc, &interface); |
| 761 if (error != GR_GL_NO_ERROR) { |
| 762 *succeeded = false; |
| 763 } else { |
| 764 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr
entMipLevel++) { |
| 765 const void* currentMipData = texels[currentMipLevel].fTexels; |
| 766 if (currentMipData == nullptr) { |
| 767 continue; |
| 768 } |
| 769 |
| 770 GR_GL_CALL(&interface, |
| 771 TexSubImage2D(GR_GL_TEXTURE_2D, |
| 772 currentMipLevel, |
| 773 0, // left |
| 774 0, // top |
| 775 texels[currentMipLevel].fWidth, |
| 776 texels[currentMipLevel].fHeight, |
| 777 externalFormat, externalType, |
| 778 currentMipData)); |
| 779 } |
| 780 *succeeded = true; |
| 781 } |
| 782 } else { |
| 783 *succeeded = true; |
| 784 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { |
| 785 GL_ALLOC_CALL(&interface, |
| 786 TexImage2D(target, |
| 787 currentMipLevel, |
| 788 internalFormat, |
| 789 texels[currentMipLevel].fWidth, |
| 790 texels[currentMipLevel].fHeight, |
| 791 0, // border |
| 792 externalFormat, externalType, |
| 793 texels[currentMipLevel].fTexels)); |
| 794 GrGLenum error = check_alloc_error(desc, &interface); |
| 795 if (error != GR_GL_NO_ERROR) { |
| 796 *succeeded = false; |
| 797 break; |
| 798 } |
| 799 } |
| 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 GrGLenum target, |
| 815 bool useTexStorage, GrGLenu
m internalFormat, |
| 816 const SkTArray<SkMipMapLeve
l>& texels) { |
| 817 CLEAR_ERROR_BEFORE_ALLOC(&interface); |
| 818 if (useTexStorage) { |
| 819 // We never resize or change formats of textures. |
| 820 GL_ALLOC_CALL(&interface, |
| 821 TexStorage2D(target, |
| 822 texels.count(), |
| 823 internalFormat, |
| 824 desc.fWidth, desc.fHeight)); |
| 825 GrGLenum error = check_alloc_error(desc, &interface); |
| 826 if (error != GR_GL_NO_ERROR) { |
| 827 return false; |
| 828 } else { |
| 829 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr
entMipLevel++) { |
| 830 const void* currentMipData = texels[currentMipLevel].fTexels; |
| 831 if (currentMipData == nullptr) { |
| 832 continue; |
| 833 } |
| 834 |
| 835 const uint32_t width = texels[currentMipLevel].fWidth; |
| 836 const uint32_t height = texels[currentMipLevel].fHeight; |
| 837 |
| 838 // Make sure that the width and height that we pass to OpenGL |
| 839 // is a multiple of the block size. |
| 840 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width
, height); |
| 841 GR_GL_CALL(&interface, CompressedTexSubImage2D(GR_GL_TEXTURE_2D, |
| 842 currentMipLevel, |
| 843 0, // left |
| 844 0, // top |
| 845 width, height, |
| 846 internalFormat, S
kToInt(dataSize), |
| 847 currentMipData)); |
| 848 } |
| 849 } |
| 850 } else { |
| 851 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { |
| 852 const uint32_t width = texels[currentMipLevel].fWidth; |
| 853 const uint32_t height = texels[currentMipLevel].fHeight; |
| 854 |
| 855 // Make sure that the width and height that we pass to OpenGL |
| 856 // is a multiple of the block size. |
| 857 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, width, he
ight); |
| 858 |
| 859 GL_ALLOC_CALL(&interface, |
| 860 CompressedTexImage2D(target, |
| 861 texels.count(), |
| 862 internalFormat, |
| 863 width, height, |
| 864 0, // border |
| 865 SkToInt(dataSize), |
| 866 texels[currentMipLevel].fTexels))
; |
| 867 |
| 868 GrGLenum error = check_alloc_error(desc, &interface); |
| 869 if (error != GR_GL_NO_ERROR) { |
| 870 return false; |
| 871 } |
| 872 } |
| 873 } |
| 874 return true; |
| 875 } |
| 876 |
| 877 /** |
| 878 * After a texture is created, any state which was altered during its creation |
| 879 * needs to be restored. |
| 880 * |
| 881 * @param interface The GL interface to use. |
| 882 * @param caps The capabilities of the GL device. |
| 883 * @param restoreGLRowLength Should the row length unpacking be restored? |
| 884 * @param glFlipY Did GL flip the texture vertically? |
| 885 */ |
| 886 static void restore_pixelstore_state(const GrGLInterface& interface, const GrGLC
aps& caps, |
| 887 bool restoreGLRowLength, bool glFlipY) { |
| 888 if (restoreGLRowLength) { |
| 889 SkASSERT(caps.unpackRowLengthSupport()); |
| 890 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); |
| 891 } |
| 892 if (glFlipY) { |
| 893 GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); |
| 894 } |
| 895 } |
| 896 |
| 897 bool GrGLGpu::uploadTexData(const GrSurfaceDesc& desc, |
| 898 GrGLenum target, |
| 899 bool isNewTexture, |
| 900 int left, int top, int width, int height, |
| 901 GrPixelConfig dataConfig, |
| 902 const SkTArray<SkMipMapLevel>& texels) { |
| 903 // If we're uploading compressed data then we should be using uploadCompress
edTexData |
| 904 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); |
| 905 |
| 906 SkTArray<SkMipMapLevel> texelsCopy(texels); |
| 907 |
| 908 for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; cur
rentMipLevel--) { |
| 909 //SkASSERT(texelsCopy[currentMipLevel].fTexels || isNewTexture); |
| 910 } |
| 911 |
| 912 |
| 913 const GrGLInterface* interface = this->glInterface(); |
| 914 const GrGLCaps& caps = this->glCaps(); |
| 915 GrGLStandard standard = this->glStandard(); |
| 916 GrGLVersion version = this->glVersion(); |
| 917 |
| 918 size_t bpp = GrBytesPerPixel(dataConfig); |
| 919 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe
vel++) { |
| 920 if (texelsCopy[currentMipLevel].fTexels == nullptr) { |
| 921 continue; |
| 922 } |
| 923 |
| 924 if (texelsCopy[currentMipLevel].fHeight > SK_MaxS32 |
| 925 || texelsCopy[currentMipLevel].fWidth > SK_MaxS32) { |
| 926 return false; |
| 927 } |
| 928 int currentMipHeight = texelsCopy[currentMipLevel].fHeight; |
| 929 int currentMipWidth = texelsCopy[currentMipLevel].fWidth; |
| 930 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp
p, &left, &top, |
| 931 ¤tMipWidth, |
| 932 ¤tMipHeight, |
| 933 &texelsCopy[currentMipLevel].fTex
els, |
| 934 &texelsCopy[currentMipLevel].fRow
Bytes)) { |
| 935 return false; |
| 936 } |
| 937 if (currentMipWidth < 0 || currentMipHeight < 0) { |
| 938 return false; |
| 939 } |
| 940 texelsCopy[currentMipLevel].fWidth = currentMipWidth; |
| 941 texelsCopy[currentMipLevel].fHeight = currentMipHeight; |
| 942 } |
| 943 |
| 944 bool useTexStorage = can_use_tex_storage(caps, standard, desc); |
| 945 bool useSizedFormat = can_use_sized_format(useTexStorage, caps, standard, ve
rsion, dataConfig); |
| 946 |
| 947 GrGLenum internalFormat = 0x0; // suppress warning |
| 948 GrGLenum externalFormat = 0x0; // suppress warning |
| 949 GrGLenum externalType = 0x0; // suppress warning |
| 950 |
| 951 if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat, |
| 952 &externalFormat, &externalType)) { |
| 953 return false; |
| 954 } |
| 955 |
| 956 bool swFlipY = false; |
| 957 bool glFlipY = false; |
| 958 |
| 959 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
| 960 if (caps.unpackFlipYSupport()) { |
| 961 glFlipY = true; |
| 962 } else { |
| 963 swFlipY = true; |
| 964 } |
| 965 } |
| 966 |
| 967 bool restoreGLRowLength = false; |
| 968 |
| 969 // in case we need a temporary, trimmed copy of the src pixels |
| 970 SkAutoSMalloc<128 * 128> tempStorage; |
| 971 prepare_image_for_writing_to_texture(desc, caps, *interface, swFlipY, glFlip
Y, bpp, texelsCopy, |
| 972 tempStorage, &restoreGLRowLength); |
| 714 bool succeeded = true; | 973 bool succeeded = true; |
| 715 if (isNewTexture && | 974 if (isNewTexture && |
| 716 0 == left && 0 == top && | 975 0 == left && 0 == top && |
| 717 desc.fWidth == width && desc.fHeight == height) { | 976 desc.fWidth == width && desc.fHeight == height) { |
| 718 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 977 allocate_and_populate_uncompressed_texture(desc, *interface, useTexStora
ge, internalFormat, |
| 719 if (useTexStorage) { | 978 externalFormat, externalType,
target, |
| 720 // We never resize or change formats of textures. | 979 texelsCopy, &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 { | 980 } else { |
| 752 if (swFlipY || glFlipY) { | 981 if (swFlipY || glFlipY) { |
| 753 top = desc.fHeight - (top + height); | 982 top = desc.fHeight - (top + height); |
| 754 } | 983 } |
| 755 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, | 984 for (int currentMipLevel = 0; currentMipLevel < texelsCopy.count(); curr
entMipLevel++) { |
| 756 0, // level | 985 if (texelsCopy[currentMipLevel].fTexels == nullptr) { |
| 757 left, top, | 986 continue; |
| 758 width, height, | 987 } |
| 759 externalFormat, externalType, data)); | 988 |
| 760 } | 989 GL_CALL(TexSubImage2D(target, |
| 761 | 990 currentMipLevel, |
| 762 if (restoreGLRowLength) { | 991 left, top, |
| 763 SkASSERT(this->glCaps().unpackRowLengthSupport()); | 992 texelsCopy[currentMipLevel].fWidth, |
| 764 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0)); | 993 texelsCopy[currentMipLevel].fHeight, |
| 765 } | 994 externalFormat, externalType, |
| 766 if (glFlipY) { | 995 texelsCopy[currentMipLevel].fTexels)); |
| 767 GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE)); | 996 } |
| 768 } | 997 } |
| 998 |
| 999 restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY); |
| 1000 |
| 769 return succeeded; | 1001 return succeeded; |
| 770 } | 1002 } |
| 771 | 1003 |
| 772 // TODO: This function is using a lot of wonky semantics like, if width == -1 | 1004 // 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 | 1005 // 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 | 1006 // 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 | 1007 // 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. | 1008 // see fit if they want to go against the "standard" way to do it. |
| 777 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, | 1009 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, |
| 778 const void* data, | 1010 GrGLenum target, |
| 1011 const SkTArray<SkMipMapLevel>& texels, |
| 779 bool isNewTexture, | 1012 bool isNewTexture, |
| 780 int left, int top, int width, int height)
{ | 1013 int left, int top, int width, int height)
{ |
| 781 SkASSERT(data || isNewTexture); | 1014 SkASSERT(isNewTexture); |
| 782 | 1015 |
| 783 // No support for software flip y, yet... | 1016 // No support for software flip y, yet... |
| 784 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); | 1017 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); |
| 785 | 1018 |
| 1019 const GrGLInterface* interface = this->glInterface(); |
| 1020 const GrGLCaps& caps = this->glCaps(); |
| 1021 GrGLStandard standard = this->glStandard(); |
| 1022 |
| 786 if (-1 == width) { | 1023 if (-1 == width) { |
| 787 width = desc.fWidth; | 1024 width = desc.fWidth; |
| 788 } | 1025 } |
| 789 #ifdef SK_DEBUG | 1026 #ifdef SK_DEBUG |
| 790 else { | 1027 else { |
| 791 SkASSERT(width <= desc.fWidth); | 1028 SkASSERT(width <= desc.fWidth); |
| 792 } | 1029 } |
| 793 #endif | 1030 #endif |
| 794 | 1031 |
| 795 if (-1 == height) { | 1032 if (-1 == height) { |
| 796 height = desc.fHeight; | 1033 height = desc.fHeight; |
| 797 } | 1034 } |
| 798 #ifdef SK_DEBUG | 1035 #ifdef SK_DEBUG |
| 799 else { | 1036 else { |
| 800 SkASSERT(height <= desc.fHeight); | 1037 SkASSERT(height <= desc.fHeight); |
| 801 } | 1038 } |
| 802 #endif | 1039 #endif |
| 803 | 1040 |
| 804 // Make sure that the width and height that we pass to OpenGL | 1041 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 | 1042 |
| 808 // We only need the internal format for compressed 2D textures. | 1043 // We only need the internal format for compressed 2D textures. |
| 809 GrGLenum internalFormat = 0; | 1044 GrGLenum internalFormat = 0; |
| 810 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, nullptr,
nullptr)) { | 1045 if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, nullptr,
nullptr)) { |
| 811 return false; | 1046 return false; |
| 812 } | 1047 } |
| 813 | 1048 |
| 814 if (isNewTexture) { | 1049 if (isNewTexture) { |
| 815 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); | 1050 return allocate_and_populate_compressed_texture(desc, *interface, target
, useTexStorage, |
| 816 GL_ALLOC_CALL(this->glInterface(), | 1051 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 { | 1052 } else { |
| 829 // Paletted textures can't be updated. | 1053 // Paletted textures can't be updated. |
| 830 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { | 1054 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { |
| 831 return false; | 1055 return false; |
| 832 } | 1056 } |
| 833 GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D, | 1057 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { |
| 834 0, // level | 1058 if (texels[currentMipLevel].fTexels == nullptr) { |
| 835 left, top, | 1059 continue; |
| 836 width, height, | 1060 } |
| 837 internalFormat, | 1061 |
| 838 SkToInt(dataSize), | 1062 // Make sure that the width and height that we pass to OpenGL |
| 839 data)); | 1063 // is a multiple of the block size. |
| 1064 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, |
| 1065 texels[currentMipLevel]
.fWidth, |
| 1066 texels[currentMipLevel]
.fHeight); |
| 1067 GL_CALL(CompressedTexSubImage2D(target, |
| 1068 currentMipLevel, |
| 1069 left, top, |
| 1070 texels[currentMipLevel].fWidth, |
| 1071 texels[currentMipLevel].fHeight, |
| 1072 internalFormat, |
| 1073 dataSize, |
| 1074 texels[currentMipLevel].fTexels)); |
| 1075 } |
| 840 } | 1076 } |
| 841 | 1077 |
| 842 return true; | 1078 return true; |
| 843 } | 1079 } |
| 844 | 1080 |
| 845 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, | 1081 static bool renderbuffer_storage_msaa(const GrGLContext& ctx, |
| 846 int sampleCount, | 1082 int sampleCount, |
| 847 GrGLenum format, | 1083 GrGLenum format, |
| 848 int width, int height) { | 1084 int width, int height) { |
| 849 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); | 1085 CLEAR_ERROR_BEFORE_ALLOC(ctx.interface()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 877 case GrGLCaps::kNone_MSFBOType: | 1113 case GrGLCaps::kNone_MSFBOType: |
| 878 SkFAIL("Shouldn't be here if we don't support multisampled renderbuf
fers."); | 1114 SkFAIL("Shouldn't be here if we don't support multisampled renderbuf
fers."); |
| 879 break; | 1115 break; |
| 880 } | 1116 } |
| 881 return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface())); | 1117 return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface())); |
| 882 } | 1118 } |
| 883 | 1119 |
| 884 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, | 1120 bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, |
| 885 GrGpuResource::LifeCycle lifeCycle, | 1121 GrGpuResource::LifeCycle lifeCycle, |
| 886 GrGLuint texID, | 1122 GrGLuint texID, |
| 1123 GrGLenum textureTarget, |
| 887 GrGLRenderTarget::IDDesc* idDesc) { | 1124 GrGLRenderTarget::IDDesc* idDesc) { |
| 888 idDesc->fMSColorRenderbufferID = 0; | 1125 idDesc->fMSColorRenderbufferID = 0; |
| 889 idDesc->fRTFBOID = 0; | 1126 idDesc->fRTFBOID = 0; |
| 890 idDesc->fTexFBOID = 0; | 1127 idDesc->fTexFBOID = 0; |
| 891 idDesc->fLifeCycle = lifeCycle; | 1128 idDesc->fLifeCycle = lifeCycle; |
| 892 idDesc->fSampleConfig = (GrGLCaps::kMixedSamples_MSFBOType == this->glCaps()
.msFBOType() && | 1129 idDesc->fSampleConfig = (GrGLCaps::kMixedSamples_MSFBOType == this->glCaps()
.msFBOType() && |
| 893 desc.fSampleCnt > 0) ? GrRenderTarget::kStencil_Samp
leConfig : | 1130 desc.fSampleCnt > 0) ? GrRenderTarget::kStencil_Samp
leConfig : |
| 894 GrRenderTarget::kUnified_Samp
leConfig; | 1131 GrRenderTarget::kUnified_Samp
leConfig; |
| 895 | 1132 |
| 896 GrGLenum status; | 1133 GrGLenum status; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe
rID)); | 1172 GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, idDesc->fMSColorRenderbuffe
rID)); |
| 936 if (!renderbuffer_storage_msaa(*fGLContext, | 1173 if (!renderbuffer_storage_msaa(*fGLContext, |
| 937 desc.fSampleCnt, | 1174 desc.fSampleCnt, |
| 938 msColorFormat, | 1175 msColorFormat, |
| 939 desc.fWidth, desc.fHeight)) { | 1176 desc.fWidth, desc.fHeight)) { |
| 940 goto FAILED; | 1177 goto FAILED; |
| 941 } | 1178 } |
| 942 fStats.incRenderTargetBinds(); | 1179 fStats.incRenderTargetBinds(); |
| 943 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); | 1180 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID)); |
| 944 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1181 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
| 945 GR_GL_COLOR_ATTACHMENT0, | 1182 GR_GL_COLOR_ATTACHMENT0, |
| 946 GR_GL_RENDERBUFFER, | 1183 GR_GL_RENDERBUFFER, |
| 947 idDesc->fMSColorRenderbufferID)); | 1184 idDesc->fMSColorRenderbufferID)); |
| 948 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || | 1185 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || |
| 949 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { | 1186 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { |
| 950 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1187 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 951 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 1188 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 952 goto FAILED; | 1189 goto FAILED; |
| 953 } | 1190 } |
| 954 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); | 1191 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); |
| 955 } | 1192 } |
| 956 } | 1193 } |
| 957 fStats.incRenderTargetBinds(); | 1194 fStats.incRenderTargetBinds(); |
| 958 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID)); | 1195 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID)); |
| 959 | 1196 |
| 960 if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) { | 1197 if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 0) { |
| 961 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, | 1198 GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER, |
| 962 GR_GL_COLOR_ATTACHMENT0, | 1199 GR_GL_COLOR_ATTACHMENT0, |
| 963 GR_GL_TEXTURE_2D, | 1200 textureTarget, |
| 964 texID, 0, desc.fSampleCnt)); | 1201 texID, 0, desc.fSampleCnt)); |
| 965 } else { | 1202 } else { |
| 966 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, | 1203 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, |
| 967 GR_GL_COLOR_ATTACHMENT0, | 1204 GR_GL_COLOR_ATTACHMENT0, |
| 968 GR_GL_TEXTURE_2D, | 1205 textureTarget, |
| 969 texID, 0)); | 1206 texID, 0)); |
| 970 } | 1207 } |
| 971 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || | 1208 if ((desc.fFlags & kCheckAllocation_GrSurfaceFlag) || |
| 972 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { | 1209 !this->glCaps().isConfigVerifiedColorAttachment(desc.fConfig)) { |
| 973 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1210 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 974 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 1211 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 975 goto FAILED; | 1212 goto FAILED; |
| 976 } | 1213 } |
| 977 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); | 1214 fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig); |
| 978 } | 1215 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 997 // SkDEBUGFAIL("null texture"); | 1234 // SkDEBUGFAIL("null texture"); |
| 998 return nullptr; | 1235 return nullptr; |
| 999 } | 1236 } |
| 1000 | 1237 |
| 1001 #if 0 && defined(SK_DEBUG) | 1238 #if 0 && defined(SK_DEBUG) |
| 1002 static size_t as_size_t(int x) { | 1239 static size_t as_size_t(int x) { |
| 1003 return x; | 1240 return x; |
| 1004 } | 1241 } |
| 1005 #endif | 1242 #endif |
| 1006 | 1243 |
| 1244 static GrGLTexture::IDDesc generate_and_bind_gl_texture(const GrGLInterface* int
erface, |
| 1245 GrGpuResource::LifeCycle
lifeCycle) { |
| 1246 GrGLTexture::IDDesc idDesc; |
| 1247 GR_GL_CALL(interface, GenTextures(1, &idDesc.fTextureID)); |
| 1248 idDesc.fLifeCycle = lifeCycle; |
| 1249 // We only support GL_TEXTURE_2D at the moment. |
| 1250 idDesc.fTarget = GR_GL_TEXTURE_2D; |
| 1251 return idDesc; |
| 1252 } |
| 1253 |
| 1254 static GrGLTexture::TexParams set_initial_texture_params(const GrGLInterface* in
terface, |
| 1255 GrGLTexture::IDDesc idD
esc) { |
| 1256 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some |
| 1257 // drivers have a bug where an FBO won't be complete if it includes a |
| 1258 // texture that is not mipmap complete (considering the filter in use). |
| 1259 GrGLTexture::TexParams initialTexParams; |
| 1260 // we only set a subset here so invalidate first |
| 1261 initialTexParams.invalidate(); |
| 1262 initialTexParams.fMinFilter = GR_GL_NEAREST; |
| 1263 initialTexParams.fMagFilter = GR_GL_NEAREST; |
| 1264 initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE; |
| 1265 initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE; |
| 1266 GR_GL_CALL(interface, TexParameteri(idDesc.fTarget, |
| 1267 GR_GL_TEXTURE_MAG_FILTER, |
| 1268 initialTexParams.fMagFilter)); |
| 1269 GR_GL_CALL(interface, TexParameteri(idDesc.fTarget, |
| 1270 GR_GL_TEXTURE_MIN_FILTER, |
| 1271 initialTexParams.fMinFilter)); |
| 1272 GR_GL_CALL(interface, TexParameteri(idDesc.fTarget, |
| 1273 GR_GL_TEXTURE_WRAP_S, |
| 1274 initialTexParams.fWrapS)); |
| 1275 GR_GL_CALL(interface, TexParameteri(idDesc.fTarget, |
| 1276 GR_GL_TEXTURE_WRAP_T, |
| 1277 initialTexParams.fWrapT)); |
| 1278 return initialTexParams; |
| 1279 } |
| 1280 |
| 1007 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, | 1281 GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc, |
| 1008 GrGpuResource::LifeCycle lifeCycle, | 1282 GrGpuResource::LifeCycle lifeCycle, |
| 1009 const void* srcData, size_t rowBytes) { | 1283 const SkTArray<SkMipMapLevel>& texels) { |
| 1010 // We fail if the MSAA was requested and is not available. | 1284 // We fail if the MSAA was requested and is not available. |
| 1011 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC
nt) { | 1285 if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleC
nt) { |
| 1012 //SkDebugf("MSAA RT requested but not supported on this platform."); | 1286 //SkDebugf("MSAA RT requested but not supported on this platform."); |
| 1013 return return_null_texture(); | 1287 return return_null_texture(); |
| 1014 } | 1288 } |
| 1015 | 1289 |
| 1016 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); | 1290 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); |
| 1017 | 1291 |
| 1018 GrGLTexture::IDDesc idDesc; | 1292 GrGLTexture::IDDesc 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) { | 1293 if (!idDesc.fTextureID) { |
| 1023 return return_null_texture(); | 1294 return return_null_texture(); |
| 1024 } | 1295 } |
| 1025 | 1296 |
| 1026 this->setScratchTextureUnit(); | 1297 this->setScratchTextureUnit(); |
| 1027 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | 1298 GL_CALL(BindTexture(idDesc.fTarget, idDesc.fTextureID)); |
| 1028 | 1299 |
| 1029 if (renderTarget && this->glCaps().textureUsageSupport()) { | 1300 if (renderTarget && this->glCaps().textureUsageSupport()) { |
| 1030 // provides a hint about how this texture will be used | 1301 // provides a hint about how this texture will be used |
| 1031 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 1302 GL_CALL(TexParameteri(idDesc.fTarget, |
| 1032 GR_GL_TEXTURE_USAGE, | 1303 GR_GL_TEXTURE_USAGE, |
| 1033 GR_GL_FRAMEBUFFER_ATTACHMENT)); | 1304 GR_GL_FRAMEBUFFER_ATTACHMENT)); |
| 1034 } | 1305 } |
| 1035 | 1306 |
| 1036 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1307 GrGLTexture::TexParams initialTexParams = set_initial_texture_params(this->g
lInterface(), |
| 1037 // drivers have a bug where an FBO won't be complete if it includes a | 1308 idDesc)
; |
| 1038 // texture that is not mipmap complete (considering the filter in use). | 1309 |
| 1039 GrGLTexture::TexParams initialTexParams; | 1310 if (!this->uploadTexData(desc, GR_GL_TEXTURE_2D, true, 0, 0, |
| 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, | |
| 1059 desc.fWidth, desc.fHeight, | 1311 desc.fWidth, desc.fHeight, |
| 1060 desc.fConfig, srcData, rowBytes)) { | 1312 desc.fConfig, texels)) { |
| 1061 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1313 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
| 1062 return return_null_texture(); | 1314 return return_null_texture(); |
| 1063 } | 1315 } |
| 1064 | 1316 |
| 1065 GrGLTexture* tex; | 1317 GrGLTexture* tex; |
| 1066 if (renderTarget) { | 1318 if (renderTarget) { |
| 1067 // unbind the texture from the texture unit before binding it to the fra
me buffer | 1319 // unbind the texture from the texture unit before binding it to the fra
me buffer |
| 1068 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); | 1320 GL_CALL(BindTexture(idDesc.fTarget, 0)); |
| 1069 GrGLRenderTarget::IDDesc rtIDDesc; | 1321 GrGLRenderTarget::IDDesc rtIDDesc; |
| 1070 | 1322 |
| 1071 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID,
&rtIDDesc)) { | 1323 if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fTextureID,
idDesc.fTarget, |
| 1324 &rtIDDesc)) { |
| 1072 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1325 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
| 1073 return return_null_texture(); | 1326 return return_null_texture(); |
| 1074 } | 1327 } |
| 1075 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); | 1328 tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc); |
| 1076 } else { | 1329 } else { |
| 1077 tex = new GrGLTexture(this, desc, idDesc); | 1330 tex = new GrGLTexture(this, desc, idDesc); |
| 1078 } | 1331 } |
| 1079 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1332 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
| 1080 #ifdef TRACE_TEXTURE_CREATION | 1333 #ifdef TRACE_TEXTURE_CREATION |
| 1081 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", | 1334 SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n", |
| 1082 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1335 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
| 1083 #endif | 1336 #endif |
| 1084 return tex; | 1337 return tex; |
| 1085 } | 1338 } |
| 1086 | 1339 |
| 1087 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, | 1340 GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc, |
| 1088 GrGpuResource::LifeCycle lifeCycle
, | 1341 GrGpuResource::LifeCycle lifeCycle
, |
| 1089 const void* srcData) { | 1342 const SkTArray<SkMipMapLevel>& tex
els) { |
| 1090 // Make sure that we're not flipping Y. | 1343 // Make sure that we're not flipping Y. |
| 1091 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 1344 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
| 1092 return return_null_texture(); | 1345 return return_null_texture(); |
| 1093 } | 1346 } |
| 1094 | 1347 |
| 1095 GrGLTexture::IDDesc idDesc; | 1348 GrGLTexture::IDDesc 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) { | 1349 if (!idDesc.fTextureID) { |
| 1100 return return_null_texture(); | 1350 return return_null_texture(); |
| 1101 } | 1351 } |
| 1102 | 1352 |
| 1103 this->setScratchTextureUnit(); | 1353 this->setScratchTextureUnit(); |
| 1104 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, idDesc.fTextureID)); | 1354 GL_CALL(BindTexture(idDesc.fTarget, idDesc.fTextureID)); |
| 1105 | 1355 |
| 1106 // Some drivers like to know filter/wrap before seeing glTexImage2D. Some | 1356 GrGLTexture::TexParams initialTexParams = set_initial_texture_params(this->g
lInterface(), |
| 1107 // drivers have a bug where an FBO won't be complete if it includes a | 1357 idDesc)
; |
| 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 | 1358 |
| 1129 if (!this->uploadCompressedTexData(desc, srcData)) { | 1359 if (!this->uploadCompressedTexData(desc, GR_GL_TEXTURE_2D, texels)) { |
| 1130 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); | 1360 GL_CALL(DeleteTextures(1, &idDesc.fTextureID)); |
| 1131 return return_null_texture(); | 1361 return return_null_texture(); |
| 1132 } | 1362 } |
| 1133 | 1363 |
| 1134 GrGLTexture* tex; | 1364 GrGLTexture* tex; |
| 1135 tex = new GrGLTexture(this, desc, idDesc); | 1365 tex = new GrGLTexture(this, desc, idDesc); |
| 1136 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); | 1366 tex->setCachedTexParams(initialTexParams, this->getResetTimestamp()); |
| 1137 #ifdef TRACE_TEXTURE_CREATION | 1367 #ifdef TRACE_TEXTURE_CREATION |
| 1138 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", | 1368 SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n", |
| 1139 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); | 1369 glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig); |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1469 | 1699 |
| 1470 int numTextureAccesses = textureAccesses.count(); | 1700 int numTextureAccesses = textureAccesses.count(); |
| 1471 for (int i = 0; i < numTextureAccesses; i++) { | 1701 for (int i = 0; i < numTextureAccesses; i++) { |
| 1472 this->bindTexture(i, textureAccesses[i]->getParams(), | 1702 this->bindTexture(i, textureAccesses[i]->getParams(), |
| 1473 static_cast<GrGLTexture*>(textureAccesses[i]->getTextu
re())); | 1703 static_cast<GrGLTexture*>(textureAccesses[i]->getTextu
re())); |
| 1474 } | 1704 } |
| 1475 | 1705 |
| 1476 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); | 1706 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); |
| 1477 this->flushStencil(pipeline.getStencil()); | 1707 this->flushStencil(pipeline.getStencil()); |
| 1478 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); | 1708 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); |
| 1479 this->flushHWAAState(glRT, pipeline.isHWAntialiasState()); | 1709 this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStenc
il().isDisabled()); |
| 1480 | 1710 |
| 1481 // This must come after textures are flushed because a texture may need | 1711 // This must come after textures are flushed because a texture may need |
| 1482 // to be msaa-resolved (which will modify bound FBO state). | 1712 // to be msaa-resolved (which will modify bound FBO state). |
| 1483 this->flushRenderTarget(glRT, nullptr); | 1713 this->flushRenderTarget(glRT, nullptr); |
| 1484 | 1714 |
| 1485 return true; | 1715 return true; |
| 1486 } | 1716 } |
| 1487 | 1717 |
| 1488 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, | 1718 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, |
| 1489 const GrNonInstancedVertices& vertices, | 1719 const GrNonInstancedVertices& vertices, |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1892 if (!flipY) { | 2122 if (!flipY) { |
| 1893 dst += rowBytes; | 2123 dst += rowBytes; |
| 1894 } else { | 2124 } else { |
| 1895 dst -= rowBytes; | 2125 dst -= rowBytes; |
| 1896 } | 2126 } |
| 1897 } | 2127 } |
| 1898 } | 2128 } |
| 1899 return true; | 2129 return true; |
| 1900 } | 2130 } |
| 1901 | 2131 |
| 2132 void GrGLGpu::setColocatedSampleLocations(GrRenderTarget* rt, bool useColocatedS
ampleLocations) { |
| 2133 GrGLRenderTarget* target = static_cast<GrGLRenderTarget*>(rt->asRenderTarget
()); |
| 2134 SkASSERT(0 != target->renderFBOID()); |
| 2135 |
| 2136 if (!rt->isStencilBufferMultisampled() || |
| 2137 useColocatedSampleLocations == target->usesColocatedSampleLocations()) { |
| 2138 return; |
| 2139 } |
| 2140 |
| 2141 GL_CALL(NamedFramebufferParameteri(target->renderFBOID(), |
| 2142 GR_GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOC
ATIONS, |
| 2143 useColocatedSampleLocations)); |
| 2144 |
| 2145 target->flagAsUsingColocatedSampleLocations(useColocatedSampleLocations); |
| 2146 } |
| 2147 |
| 1902 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound)
{ | 2148 void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound)
{ |
| 1903 | 2149 |
| 1904 SkASSERT(target); | 2150 SkASSERT(target); |
| 1905 | 2151 |
| 1906 uint32_t rtID = target->getUniqueID(); | 2152 uint32_t rtID = target->getUniqueID(); |
| 1907 if (fHWBoundRenderTargetUniqueID != rtID) { | 2153 if (fHWBoundRenderTargetUniqueID != rtID) { |
| 1908 fStats.incRenderTargetBinds(); | 2154 fStats.incRenderTargetBinds(); |
| 1909 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); | 2155 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); |
| 1910 #ifdef SK_DEBUG | 2156 #ifdef SK_DEBUG |
| 1911 // don't do this check in Chromium -- this is causing | 2157 // don't do this check in Chromium -- this is causing |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2139 set_gl_stencil(this->glInterface(), | 2385 set_gl_stencil(this->glInterface(), |
| 2140 stencilSettings, | 2386 stencilSettings, |
| 2141 GR_GL_FRONT_AND_BACK, | 2387 GR_GL_FRONT_AND_BACK, |
| 2142 GrStencilSettings::kFront_Face); | 2388 GrStencilSettings::kFront_Face); |
| 2143 } | 2389 } |
| 2144 } | 2390 } |
| 2145 fHWStencilSettings = stencilSettings; | 2391 fHWStencilSettings = stencilSettings; |
| 2146 } | 2392 } |
| 2147 } | 2393 } |
| 2148 | 2394 |
| 2149 void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA) { | 2395 void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabl
ed) { |
| 2150 SkASSERT(!useHWAA || rt->isStencilBufferMultisampled()); | 2396 SkASSERT(!useHWAA || rt->isStencilBufferMultisampled()); |
| 2151 | 2397 |
| 2398 if (rt->hasMixedSamples() && stencilEnabled && |
| 2399 this->glCaps().glslCaps()->programmableSampleLocationsSupport()) { |
| 2400 if (useHWAA) { |
| 2401 this->setColocatedSampleLocations(rt, false); |
| 2402 } else { |
| 2403 this->setColocatedSampleLocations(rt, true); |
| 2404 } |
| 2405 useHWAA = true; |
| 2406 } |
| 2407 |
| 2152 if (this->glCaps().multisampleDisableSupport()) { | 2408 if (this->glCaps().multisampleDisableSupport()) { |
| 2153 if (useHWAA) { | 2409 if (useHWAA) { |
| 2154 if (kYes_TriState != fMSAAEnabled) { | 2410 if (kYes_TriState != fMSAAEnabled) { |
| 2155 GL_CALL(Enable(GR_GL_MULTISAMPLE)); | 2411 GL_CALL(Enable(GR_GL_MULTISAMPLE)); |
| 2156 fMSAAEnabled = kYes_TriState; | 2412 fMSAAEnabled = kYes_TriState; |
| 2157 } | 2413 } |
| 2158 } else { | 2414 } else { |
| 2159 if (kNo_TriState != fMSAAEnabled) { | 2415 if (kNo_TriState != fMSAAEnabled) { |
| 2160 GL_CALL(Disable(GR_GL_MULTISAMPLE)); | 2416 GL_CALL(Disable(GR_GL_MULTISAMPLE)); |
| 2161 fMSAAEnabled = kNo_TriState; | 2417 fMSAAEnabled = kNo_TriState; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2239 GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes)); | 2495 GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes)); |
| 2240 GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode); | 2496 GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode); |
| 2241 GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode); | 2497 GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode); |
| 2242 GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode); | 2498 GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode); |
| 2243 return gWrapModes[tm]; | 2499 return gWrapModes[tm]; |
| 2244 } | 2500 } |
| 2245 | 2501 |
| 2246 void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
e* texture) { | 2502 void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
e* texture) { |
| 2247 SkASSERT(texture); | 2503 SkASSERT(texture); |
| 2248 | 2504 |
| 2505 #ifdef SK_DEBUG |
| 2506 if (!this->caps()->npotTextureTileSupport()) { |
| 2507 const bool tileX = SkShader::kClamp_TileMode != params.getTileModeX(); |
| 2508 const bool tileY = SkShader::kClamp_TileMode != params.getTileModeY(); |
| 2509 if (tileX || tileY) { |
| 2510 const int w = texture->width(); |
| 2511 const int h = texture->height(); |
| 2512 SkASSERT(SkIsPow2(w) && SkIsPow2(h)); |
| 2513 } |
| 2514 } |
| 2515 #endif |
| 2516 |
| 2249 // If we created a rt/tex and rendered to it without using a texture and now
we're texturing | 2517 // If we created a rt/tex and rendered to it without using a texture and now
we're texturing |
| 2250 // from the rt it will still be the last bound texture, but it needs resolvi
ng. So keep this | 2518 // from the rt it will still be the last bound texture, but it needs resolvi
ng. So keep this |
| 2251 // out of the "last != next" check. | 2519 // out of the "last != next" check. |
| 2252 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTa
rget()); | 2520 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTa
rget()); |
| 2253 if (texRT) { | 2521 if (texRT) { |
| 2254 this->onResolveRenderTarget(texRT); | 2522 this->onResolveRenderTarget(texRT); |
| 2255 } | 2523 } |
| 2256 | 2524 |
| 2257 uint32_t textureID = texture->getUniqueID(); | 2525 uint32_t textureID = texture->getUniqueID(); |
| 2526 GrGLenum target = texture->target(); |
| 2258 if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) { | 2527 if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) { |
| 2259 this->setTextureUnit(unitIdx); | 2528 this->setTextureUnit(unitIdx); |
| 2260 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID())); | 2529 GL_CALL(BindTexture(target, texture->textureID())); |
| 2261 fHWBoundTextureUniqueIDs[unitIdx] = textureID; | 2530 fHWBoundTextureUniqueIDs[unitIdx] = textureID; |
| 2262 } | 2531 } |
| 2263 | 2532 |
| 2264 ResetTimestamp timestamp; | 2533 ResetTimestamp timestamp; |
| 2265 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&ti
mestamp); | 2534 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&ti
mestamp); |
| 2266 bool setAll = timestamp < this->getResetTimestamp(); | 2535 bool setAll = timestamp < this->getResetTimestamp(); |
| 2267 GrGLTexture::TexParams newTexParams; | 2536 GrGLTexture::TexParams newTexParams; |
| 2268 | 2537 |
| 2269 static GrGLenum glMinFilterModes[] = { | 2538 static GrGLenum glMinFilterModes[] = { |
| 2270 GR_GL_NEAREST, | 2539 GR_GL_NEAREST, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2282 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture-
>config())) { | 2551 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture-
>config())) { |
| 2283 filterMode = GrTextureParams::kBilerp_FilterMode; | 2552 filterMode = GrTextureParams::kBilerp_FilterMode; |
| 2284 } | 2553 } |
| 2285 } | 2554 } |
| 2286 | 2555 |
| 2287 newTexParams.fMinFilter = glMinFilterModes[filterMode]; | 2556 newTexParams.fMinFilter = glMinFilterModes[filterMode]; |
| 2288 newTexParams.fMagFilter = glMagFilterModes[filterMode]; | 2557 newTexParams.fMagFilter = glMagFilterModes[filterMode]; |
| 2289 | 2558 |
| 2290 if (GrTextureParams::kMipMap_FilterMode == filterMode && | 2559 if (GrTextureParams::kMipMap_FilterMode == filterMode && |
| 2291 texture->texturePriv().mipMapsAreDirty()) { | 2560 texture->texturePriv().mipMapsAreDirty()) { |
| 2292 GL_CALL(GenerateMipmap(GR_GL_TEXTURE_2D)); | 2561 GL_CALL(GenerateMipmap(target)); |
| 2293 texture->texturePriv().dirtyMipMaps(false); | 2562 texture->texturePriv().dirtyMipMaps(false); |
| 2294 } | 2563 } |
| 2295 | 2564 |
| 2296 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); | 2565 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); |
| 2297 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); | 2566 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); |
| 2298 memcpy(newTexParams.fSwizzleRGBA, | 2567 memcpy(newTexParams.fSwizzleRGBA, |
| 2299 GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps
()), | 2568 GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps
()), |
| 2300 sizeof(newTexParams.fSwizzleRGBA)); | 2569 sizeof(newTexParams.fSwizzleRGBA)); |
| 2301 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { | 2570 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { |
| 2302 this->setTextureUnit(unitIdx); | 2571 this->setTextureUnit(unitIdx); |
| 2303 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 2572 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa
gFilter)); |
| 2304 GR_GL_TEXTURE_MAG_FILTER, | |
| 2305 newTexParams.fMagFilter)); | |
| 2306 } | 2573 } |
| 2307 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { | 2574 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { |
| 2308 this->setTextureUnit(unitIdx); | 2575 this->setTextureUnit(unitIdx); |
| 2309 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 2576 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newTexParams.fMi
nFilter)); |
| 2310 GR_GL_TEXTURE_MIN_FILTER, | |
| 2311 newTexParams.fMinFilter)); | |
| 2312 } | 2577 } |
| 2313 if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) { | 2578 if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) { |
| 2314 this->setTextureUnit(unitIdx); | 2579 this->setTextureUnit(unitIdx); |
| 2315 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 2580 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newTexParams.fWrapS)
); |
| 2316 GR_GL_TEXTURE_WRAP_S, | |
| 2317 newTexParams.fWrapS)); | |
| 2318 } | 2581 } |
| 2319 if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) { | 2582 if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) { |
| 2320 this->setTextureUnit(unitIdx); | 2583 this->setTextureUnit(unitIdx); |
| 2321 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, | 2584 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT)
); |
| 2322 GR_GL_TEXTURE_WRAP_T, | |
| 2323 newTexParams.fWrapT)); | |
| 2324 } | 2585 } |
| 2325 if (this->glCaps().textureSwizzleSupport() && | 2586 if (this->glCaps().textureSwizzleSupport() && |
| 2326 (setAll || memcmp(newTexParams.fSwizzleRGBA, | 2587 (setAll || memcmp(newTexParams.fSwizzleRGBA, |
| 2327 oldTexParams.fSwizzleRGBA, | 2588 oldTexParams.fSwizzleRGBA, |
| 2328 sizeof(newTexParams.fSwizzleRGBA)))) { | 2589 sizeof(newTexParams.fSwizzleRGBA)))) { |
| 2329 this->setTextureUnit(unitIdx); | 2590 this->setTextureUnit(unitIdx); |
| 2330 if (this->glStandard() == kGLES_GrGLStandard) { | 2591 if (this->glStandard() == kGLES_GrGLStandard) { |
| 2331 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. | 2592 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. |
| 2332 const GrGLenum* swizzle = newTexParams.fSwizzleRGBA; | 2593 const GrGLenum* swizzle = newTexParams.fSwizzleRGBA; |
| 2333 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_R, swi
zzle[0])); | 2594 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); |
| 2334 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_G, swi
zzle[1])); | 2595 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); |
| 2335 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_B, swi
zzle[2])); | 2596 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); |
| 2336 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_A, swi
zzle[3])); | 2597 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); |
| 2337 } else { | 2598 } else { |
| 2338 GR_STATIC_ASSERT(sizeof(newTexParams.fSwizzleRGBA[0]) == sizeof(GrGL
int)); | 2599 GR_STATIC_ASSERT(sizeof(newTexParams.fSwizzleRGBA[0]) == sizeof(GrGL
int)); |
| 2339 const GrGLint* swizzle = reinterpret_cast<const GrGLint*>(newTexPara
ms.fSwizzleRGBA); | 2600 const GrGLint* swizzle = reinterpret_cast<const GrGLint*>(newTexPara
ms.fSwizzleRGBA); |
| 2340 GL_CALL(TexParameteriv(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_RGBA,
swizzle)); | 2601 GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle))
; |
| 2341 } | 2602 } |
| 2342 } | 2603 } |
| 2343 texture->setCachedTexParams(newTexParams, this->getResetTimestamp()); | 2604 texture->setCachedTexParams(newTexParams, this->getResetTimestamp()); |
| 2344 } | 2605 } |
| 2345 | 2606 |
| 2346 void GrGLGpu::flushColorWrite(bool writeColor) { | 2607 void GrGLGpu::flushColorWrite(bool writeColor) { |
| 2347 if (!writeColor) { | 2608 if (!writeColor) { |
| 2348 if (kNo_TriState != fHWWriteToColor) { | 2609 if (kNo_TriState != fHWWriteToColor) { |
| 2349 GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE, | 2610 GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE, |
| 2350 GR_GL_FALSE, GR_GL_FALSE)); | 2611 GR_GL_FALSE, GR_GL_FALSE)); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2543 *internalFormat = GR_GL_ALPHA; | 2804 *internalFormat = GR_GL_ALPHA; |
| 2544 } | 2805 } |
| 2545 *externalFormat = GR_GL_ALPHA; | 2806 *externalFormat = GR_GL_ALPHA; |
| 2546 } | 2807 } |
| 2547 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G
R_GL_VER(3, 0)) { | 2808 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G
R_GL_VER(3, 0)) { |
| 2548 *externalType = GR_GL_HALF_FLOAT; | 2809 *externalType = GR_GL_HALF_FLOAT; |
| 2549 } else { | 2810 } else { |
| 2550 *externalType = GR_GL_HALF_FLOAT_OES; | 2811 *externalType = GR_GL_HALF_FLOAT_OES; |
| 2551 } | 2812 } |
| 2552 break; | 2813 break; |
| 2553 | 2814 |
| 2554 case kRGBA_half_GrPixelConfig: | 2815 case kRGBA_half_GrPixelConfig: |
| 2555 *internalFormat = GR_GL_RGBA16F; | 2816 *internalFormat = GR_GL_RGBA16F; |
| 2556 *externalFormat = GR_GL_RGBA; | 2817 *externalFormat = GR_GL_RGBA; |
| 2557 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G
R_GL_VER(3, 0)) { | 2818 if (kGL_GrGLStandard == this->glStandard() || this->glVersion() >= G
R_GL_VER(3, 0)) { |
| 2558 *externalType = GR_GL_HALF_FLOAT; | 2819 *externalType = GR_GL_HALF_FLOAT; |
| 2559 } else { | 2820 } else { |
| 2560 *externalType = GR_GL_HALF_FLOAT_OES; | 2821 *externalType = GR_GL_HALF_FLOAT_OES; |
| 2561 } | 2822 } |
| 2562 break; | 2823 break; |
| 2563 | 2824 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2636 return true; | 2897 return true; |
| 2637 } else { | 2898 } else { |
| 2638 return false; | 2899 return false; |
| 2639 } | 2900 } |
| 2640 } | 2901 } |
| 2641 | 2902 |
| 2642 } | 2903 } |
| 2643 | 2904 |
| 2644 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is | 2905 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is |
| 2645 // relative to is output. | 2906 // relative to is output. |
| 2646 GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLI
Rect* viewport, | 2907 void GrGLGpu::bindSurfaceFBOForCopy(GrSurface* surface, GrGLenum fboTarget, GrGL
IRect* viewport, |
| 2647 TempFBOTarget tempFBOTarget) { | 2908 TempFBOTarget tempFBOTarget) { |
| 2648 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); | 2909 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); |
| 2649 if (nullptr == rt) { | 2910 if (nullptr == rt) { |
| 2650 SkASSERT(surface->asTexture()); | 2911 SkASSERT(surface->asTexture()); |
| 2651 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); | 2912 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); |
| 2913 GrGLenum target = static_cast<GrGLTexture*>(surface->asTexture())->targe
t(); |
| 2652 GrGLuint* tempFBOID; | 2914 GrGLuint* tempFBOID; |
| 2653 tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTem
pDstFBOID; | 2915 tempFBOID = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBOID : &fTem
pDstFBOID; |
| 2654 | 2916 |
| 2655 if (0 == *tempFBOID) { | 2917 if (0 == *tempFBOID) { |
| 2656 GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID)); | 2918 GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID)); |
| 2657 } | 2919 } |
| 2658 | 2920 |
| 2659 fStats.incRenderTargetBinds(); | 2921 fStats.incRenderTargetBinds(); |
| 2660 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID)); | 2922 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID)); |
| 2661 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | 2923 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
| 2662 GR_GL_COLOR_ATTACHM
ENT0, | 2924 GR_GL_COLOR_ATTACHM
ENT0, |
| 2663 GR_GL_TEXTURE_2D, | 2925 target, |
| 2664 texID, | 2926 texID, |
| 2665 0)); | 2927 0)); |
| 2666 viewport->fLeft = 0; | 2928 viewport->fLeft = 0; |
| 2667 viewport->fBottom = 0; | 2929 viewport->fBottom = 0; |
| 2668 viewport->fWidth = surface->width(); | 2930 viewport->fWidth = surface->width(); |
| 2669 viewport->fHeight = surface->height(); | 2931 viewport->fHeight = surface->height(); |
| 2670 return *tempFBOID; | |
| 2671 } else { | 2932 } else { |
| 2672 GrGLuint tempFBOID = 0; | |
| 2673 fStats.incRenderTargetBinds(); | 2933 fStats.incRenderTargetBinds(); |
| 2674 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO
ID())); | 2934 GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBO
ID())); |
| 2675 *viewport = rt->getViewport(); | 2935 *viewport = rt->getViewport(); |
| 2676 return tempFBOID; | |
| 2677 } | 2936 } |
| 2678 } | 2937 } |
| 2679 | 2938 |
| 2680 void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) { | 2939 void GrGLGpu::unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface) { |
| 2681 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, | 2940 // bindSurfaceFBOForCopy temporarily binds textures that are not render targ
ets to |
| 2682 GR_GL_COLOR_ATTACHMENT0
, | 2941 if (!surface->asRenderTarget()) { |
| 2683 GR_GL_TEXTURE_2D, | 2942 SkASSERT(surface->asTexture()); |
| 2684 0, | 2943 GrGLenum textureTarget = static_cast<GrGLTexture*>(surface->asTexture())
->target(); |
| 2685 0)); | 2944 GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget, |
| 2945 GR_GL_COLOR_ATTACHM
ENT0, |
| 2946 textureTarget, |
| 2947 0, |
| 2948 0)); |
| 2949 } |
| 2686 } | 2950 } |
| 2687 | 2951 |
| 2688 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
const { | 2952 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
const { |
| 2689 // If the src is a texture, we can implement the blit as a draw assuming the
config is | 2953 // If the src is a texture, we can implement the blit as a draw assuming the
config is |
| 2690 // renderable. | 2954 // renderable. |
| 2691 if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), fals
e)) { | 2955 if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), fals
e)) { |
| 2692 desc->fOrigin = kDefault_GrSurfaceOrigin; | 2956 desc->fOrigin = kDefault_GrSurfaceOrigin; |
| 2693 desc->fFlags = kRenderTarget_GrSurfaceFlag; | 2957 desc->fFlags = kRenderTarget_GrSurfaceFlag; |
| 2694 desc->fConfig = src->config(); | 2958 desc->fConfig = src->config(); |
| 2695 return true; | 2959 return true; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2738 } | 3002 } |
| 2739 | 3003 |
| 2740 bool GrGLGpu::onCopySurface(GrSurface* dst, | 3004 bool GrGLGpu::onCopySurface(GrSurface* dst, |
| 2741 GrSurface* src, | 3005 GrSurface* src, |
| 2742 const SkIRect& srcRect, | 3006 const SkIRect& srcRect, |
| 2743 const SkIPoint& dstPoint) { | 3007 const SkIPoint& dstPoint) { |
| 2744 if (src->asTexture() && dst->asRenderTarget()) { | 3008 if (src->asTexture() && dst->asRenderTarget()) { |
| 2745 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); | 3009 this->copySurfaceAsDraw(dst, src, srcRect, dstPoint); |
| 2746 return true; | 3010 return true; |
| 2747 } | 3011 } |
| 2748 | 3012 |
| 2749 if (can_copy_texsubimage(dst, src, this)) { | 3013 if (can_copy_texsubimage(dst, src, this)) { |
| 2750 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); | 3014 this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint); |
| 2751 return true; | 3015 return true; |
| 2752 } | 3016 } |
| 2753 | 3017 |
| 2754 if (can_blit_framebuffer(dst, src, this)) { | 3018 if (can_blit_framebuffer(dst, src, this)) { |
| 2755 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); | 3019 return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint); |
| 2756 } | 3020 } |
| 2757 | 3021 |
| 2758 return false; | 3022 return false; |
| 2759 } | 3023 } |
| 2760 | 3024 |
| 2761 | 3025 |
| 2762 void GrGLGpu::createCopyProgram() { | 3026 void GrGLGpu::createCopyProgram() { |
| 2763 const char* version = GrGLGetGLSLVersionDecl(this->ctxInfo()); | 3027 const char* version = GrGLGetGLSLVersionDecl(this->ctxInfo()); |
| 2764 | 3028 |
| 2765 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T
ypeModifier); | 3029 GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_T
ypeModifier); |
| 2766 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, | 3030 GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, |
| 2767 GrShaderVar::kUniform_TypeModifier); | 3031 GrShaderVar::kUniform_TypeModifier); |
| 2768 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform
_TypeModifier); | 3032 GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform
_TypeModifier); |
| 2769 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo
rm_TypeModifier); | 3033 GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUnifo
rm_TypeModifier); |
| 2770 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying
Out_TypeModifier); | 3034 GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVarying
Out_TypeModifier); |
| 2771 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T
ypeModifier); | 3035 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T
ypeModifier); |
| 2772 | 3036 |
| 2773 SkString vshaderTxt(version); | 3037 SkString vshaderTxt(version); |
| 2774 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt); | 3038 aVertex.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2775 vshaderTxt.append(";"); | 3039 vshaderTxt.append(";"); |
| 2776 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt); | 3040 uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2777 vshaderTxt.append(";"); | 3041 vshaderTxt.append(";"); |
| 2778 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt); | 3042 uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2779 vshaderTxt.append(";"); | 3043 vshaderTxt.append(";"); |
| 2780 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt); | 3044 vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt); |
| 2781 vshaderTxt.append(";"); | 3045 vshaderTxt.append(";"); |
| 2782 | 3046 |
| 2783 vshaderTxt.append( | 3047 vshaderTxt.append( |
| 2784 "// Copy Program VS\n" | 3048 "// Copy Program VS\n" |
| 2785 "void main() {" | 3049 "void main() {" |
| 2786 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" | 3050 " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;" |
| 2787 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" | 3051 " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;" |
| 2788 " gl_Position.zw = vec2(0, 1);" | 3052 " gl_Position.zw = vec2(0, 1);" |
| 2789 "}" | 3053 "}" |
| 2790 ); | 3054 ); |
| 2791 | 3055 |
| 2792 SkString fshaderTxt(version); | 3056 SkString fshaderTxt(version); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2806 fsOutName = "gl_FragColor"; | 3070 fsOutName = "gl_FragColor"; |
| 2807 } | 3071 } |
| 2808 fshaderTxt.appendf( | 3072 fshaderTxt.appendf( |
| 2809 "// Copy Program FS\n" | 3073 "// Copy Program FS\n" |
| 2810 "void main() {" | 3074 "void main() {" |
| 2811 " %s = %s(u_texture, v_texCoord);" | 3075 " %s = %s(u_texture, v_texCoord);" |
| 2812 "}", | 3076 "}", |
| 2813 fsOutName, | 3077 fsOutName, |
| 2814 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) | 3078 GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration()) |
| 2815 ); | 3079 ); |
| 2816 | 3080 |
| 2817 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); | 3081 GL_CALL_RET(fCopyProgram.fProgram, CreateProgram()); |
| 2818 const char* str; | 3082 const char* str; |
| 2819 GrGLint length; | 3083 GrGLint length; |
| 2820 | 3084 |
| 2821 str = vshaderTxt.c_str(); | 3085 str = vshaderTxt.c_str(); |
| 2822 length = SkToInt(vshaderTxt.size()); | 3086 length = SkToInt(vshaderTxt.size()); |
| 2823 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro
gram, | 3087 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyProgram.fPro
gram, |
| 2824 GR_GL_VERTEX_SHADER, &str, &le
ngth, 1, &fStats); | 3088 GR_GL_VERTEX_SHADER, &str, &le
ngth, 1, &fStats); |
| 2825 | 3089 |
| 2826 str = fshaderTxt.c_str(); | 3090 str = fshaderTxt.c_str(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2909 | 3173 |
| 2910 GL_CALL(Uniform4f(fCopyProgram.fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0,
dy0)); | 3174 GL_CALL(Uniform4f(fCopyProgram.fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0,
dy0)); |
| 2911 GL_CALL(Uniform4f(fCopyProgram.fTexCoordXformUniform, sx1 - sx0, sy1 - sy0,
sx0, sy0)); | 3175 GL_CALL(Uniform4f(fCopyProgram.fTexCoordXformUniform, sx1 - sx0, sy1 - sy0,
sx0, sy0)); |
| 2912 GL_CALL(Uniform1i(fCopyProgram.fTextureUniform, 0)); | 3176 GL_CALL(Uniform1i(fCopyProgram.fTextureUniform, 0)); |
| 2913 | 3177 |
| 2914 GrXferProcessor::BlendInfo blendInfo; | 3178 GrXferProcessor::BlendInfo blendInfo; |
| 2915 blendInfo.reset(); | 3179 blendInfo.reset(); |
| 2916 this->flushBlend(blendInfo); | 3180 this->flushBlend(blendInfo); |
| 2917 this->flushColorWrite(true); | 3181 this->flushColorWrite(true); |
| 2918 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); | 3182 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
| 2919 this->flushHWAAState(dstRT, false); | 3183 this->flushHWAAState(dstRT, false, false); |
| 2920 this->disableScissor(); | 3184 this->disableScissor(); |
| 2921 GrStencilSettings stencil; | 3185 GrStencilSettings stencil; |
| 2922 stencil.setDisabled(); | 3186 stencil.setDisabled(); |
| 2923 this->flushStencil(stencil); | 3187 this->flushStencil(stencil); |
| 2924 | 3188 |
| 2925 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); | 3189 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); |
| 2926 } | 3190 } |
| 2927 | 3191 |
| 2928 void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, | 3192 void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, |
| 2929 GrSurface* src, | 3193 GrSurface* src, |
| 2930 const SkIRect& srcRect, | 3194 const SkIRect& srcRect, |
| 2931 const SkIPoint& dstPoint) { | 3195 const SkIPoint& dstPoint) { |
| 2932 SkASSERT(can_copy_texsubimage(dst, src, this)); | 3196 SkASSERT(can_copy_texsubimage(dst, src, this)); |
| 2933 GrGLuint srcFBO; | |
| 2934 GrGLIRect srcVP; | 3197 GrGLIRect srcVP; |
| 2935 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBO
Target); | 3198 this->bindSurfaceFBOForCopy(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarg
et); |
| 2936 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); | 3199 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); |
| 2937 SkASSERT(dstTex); | 3200 SkASSERT(dstTex); |
| 2938 // We modified the bound FBO | 3201 // We modified the bound FBO |
| 2939 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 3202 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 2940 GrGLIRect srcGLRect; | 3203 GrGLIRect srcGLRect; |
| 2941 srcGLRect.setRelativeTo(srcVP, | 3204 srcGLRect.setRelativeTo(srcVP, |
| 2942 srcRect.fLeft, | 3205 srcRect.fLeft, |
| 2943 srcRect.fTop, | 3206 srcRect.fTop, |
| 2944 srcRect.width(), | 3207 srcRect.width(), |
| 2945 srcRect.height(), | 3208 srcRect.height(), |
| 2946 src->origin()); | 3209 src->origin()); |
| 2947 | 3210 |
| 2948 this->setScratchTextureUnit(); | 3211 this->setScratchTextureUnit(); |
| 2949 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); | 3212 GL_CALL(BindTexture(dstTex->target(), dstTex->textureID())); |
| 2950 GrGLint dstY; | 3213 GrGLint dstY; |
| 2951 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { | 3214 if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { |
| 2952 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); | 3215 dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight); |
| 2953 } else { | 3216 } else { |
| 2954 dstY = dstPoint.fY; | 3217 dstY = dstPoint.fY; |
| 2955 } | 3218 } |
| 2956 GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0, | 3219 GL_CALL(CopyTexSubImage2D(dstTex->target(), 0, |
| 2957 dstPoint.fX, dstY, | 3220 dstPoint.fX, dstY, |
| 2958 srcGLRect.fLeft, srcGLRect.fBottom, | 3221 srcGLRect.fLeft, srcGLRect.fBottom, |
| 2959 srcGLRect.fWidth, srcGLRect.fHeight)); | 3222 srcGLRect.fWidth, srcGLRect.fHeight)); |
| 2960 if (srcFBO) { | 3223 this->unbindTextureFBOForCopy(GR_GL_FRAMEBUFFER, src); |
| 2961 this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER); | |
| 2962 } | |
| 2963 } | 3224 } |
| 2964 | 3225 |
| 2965 bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, | 3226 bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, |
| 2966 GrSurface* src, | 3227 GrSurface* src, |
| 2967 const SkIRect& srcRect, | 3228 const SkIRect& srcRect, |
| 2968 const SkIPoint& dstPoint) { | 3229 const SkIPoint& dstPoint) { |
| 2969 SkASSERT(can_blit_framebuffer(dst, src, this)); | 3230 SkASSERT(can_blit_framebuffer(dst, src, this)); |
| 2970 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, | 3231 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, |
| 2971 srcRect.width(), srcRect.height()); | 3232 srcRect.width(), srcRect.height()); |
| 2972 if (dst == src) { | 3233 if (dst == src) { |
| 2973 if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { | 3234 if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) { |
| 2974 return false; | 3235 return false; |
| 2975 } | 3236 } |
| 2976 } | 3237 } |
| 2977 | 3238 |
| 2978 GrGLuint dstFBO; | |
| 2979 GrGLuint srcFBO; | |
| 2980 GrGLIRect dstVP; | 3239 GrGLIRect dstVP; |
| 2981 GrGLIRect srcVP; | 3240 GrGLIRect srcVP; |
| 2982 dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, | 3241 this->bindSurfaceFBOForCopy(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, kDst_TempFB
OTarget); |
| 2983 kDst_TempFBOTarget); | 3242 this->bindSurfaceFBOForCopy(src, GR_GL_READ_FRAMEBUFFER, &srcVP, kSrc_TempFB
OTarget); |
| 2984 srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP, | |
| 2985 kSrc_TempFBOTarget); | |
| 2986 // We modified the bound FBO | 3243 // We modified the bound FBO |
| 2987 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 3244 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 2988 GrGLIRect srcGLRect; | 3245 GrGLIRect srcGLRect; |
| 2989 GrGLIRect dstGLRect; | 3246 GrGLIRect dstGLRect; |
| 2990 srcGLRect.setRelativeTo(srcVP, | 3247 srcGLRect.setRelativeTo(srcVP, |
| 2991 srcRect.fLeft, | 3248 srcRect.fLeft, |
| 2992 srcRect.fTop, | 3249 srcRect.fTop, |
| 2993 srcRect.width(), | 3250 srcRect.width(), |
| 2994 srcRect.height(), | 3251 srcRect.height(), |
| 2995 src->origin()); | 3252 src->origin()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3015 } | 3272 } |
| 3016 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, | 3273 GL_CALL(BlitFramebuffer(srcGLRect.fLeft, |
| 3017 srcY0, | 3274 srcY0, |
| 3018 srcGLRect.fLeft + srcGLRect.fWidth, | 3275 srcGLRect.fLeft + srcGLRect.fWidth, |
| 3019 srcY1, | 3276 srcY1, |
| 3020 dstGLRect.fLeft, | 3277 dstGLRect.fLeft, |
| 3021 dstGLRect.fBottom, | 3278 dstGLRect.fBottom, |
| 3022 dstGLRect.fLeft + dstGLRect.fWidth, | 3279 dstGLRect.fLeft + dstGLRect.fWidth, |
| 3023 dstGLRect.fBottom + dstGLRect.fHeight, | 3280 dstGLRect.fBottom + dstGLRect.fHeight, |
| 3024 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | 3281 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
| 3025 if (dstFBO) { | 3282 this->unbindTextureFBOForCopy(GR_GL_DRAW_FRAMEBUFFER, dst); |
| 3026 this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER); | 3283 this->unbindTextureFBOForCopy(GR_GL_READ_FRAMEBUFFER, src); |
| 3027 } | |
| 3028 if (srcFBO) { | |
| 3029 this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER); | |
| 3030 } | |
| 3031 return true; | 3284 return true; |
| 3032 } | 3285 } |
| 3033 | 3286 |
| 3034 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { | 3287 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { |
| 3035 SkASSERT(type); | 3288 SkASSERT(type); |
| 3036 switch (type) { | 3289 switch (type) { |
| 3037 case kTexture_GrXferBarrierType: { | 3290 case kTexture_GrXferBarrierType: { |
| 3038 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); | 3291 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(rt); |
| 3039 if (glrt->textureFBOID() != glrt->renderFBOID()) { | 3292 if (glrt->textureFBOID() != glrt->renderFBOID()) { |
| 3040 // The render target uses separate storage so no need for glText
ureBarrier. | 3293 // The render target uses separate storage so no need for glText
ureBarrier. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3144 this->setVertexArrayID(gpu, 0); | 3397 this->setVertexArrayID(gpu, 0); |
| 3145 } | 3398 } |
| 3146 int attrCount = gpu->glCaps().maxVertexAttributes(); | 3399 int attrCount = gpu->glCaps().maxVertexAttributes(); |
| 3147 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 3400 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
| 3148 fDefaultVertexArrayAttribState.resize(attrCount); | 3401 fDefaultVertexArrayAttribState.resize(attrCount); |
| 3149 } | 3402 } |
| 3150 attribState = &fDefaultVertexArrayAttribState; | 3403 attribState = &fDefaultVertexArrayAttribState; |
| 3151 } | 3404 } |
| 3152 return attribState; | 3405 return attribState; |
| 3153 } | 3406 } |
| OLD | NEW |