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 |