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

Side by Side Diff: src/gpu/gl/GrGLGpu.cpp

Issue 1249543003: Creating functions for uploading a mipmapped texture. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Fixing merge mistakes Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8
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
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
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 &currentMipWidth,
932 &currentMipHeight,
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« include/gpu/GrContext.h ('K') | « src/gpu/gl/GrGLGpu.h ('k') | src/image/SkImage_Gpu.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698