OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "GrGpuGL.h" | 9 #include "GrGpuGL.h" |
10 #include "GrGLStencilBuffer.h" | 10 #include "GrGLStencilBuffer.h" |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 } | 535 } |
536 | 536 |
537 } | 537 } |
538 | 538 |
539 bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc, | 539 bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc, |
540 bool isNewTexture, | 540 bool isNewTexture, |
541 int left, int top, int width, int height, | 541 int left, int top, int width, int height, |
542 GrPixelConfig dataConfig, | 542 GrPixelConfig dataConfig, |
543 const void* data, | 543 const void* data, |
544 size_t rowBytes) { | 544 size_t rowBytes) { |
545 SkASSERT(NULL != data || isNewTexture); | 545 SkASSERT(data || isNewTexture); |
546 | 546 |
547 // If we're uploading compressed data then we should be using uploadCompress
edTexData | 547 // If we're uploading compressed data then we should be using uploadCompress
edTexData |
548 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); | 548 SkASSERT(!GrPixelConfigIsCompressed(dataConfig)); |
549 | 549 |
550 size_t bpp = GrBytesPerPixel(dataConfig); | 550 size_t bpp = GrBytesPerPixel(dataConfig); |
551 if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top, | 551 if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top, |
552 &width, &height, &data, &rowBytes)) { | 552 &width, &height, &data, &rowBytes)) { |
553 return false; | 553 return false; |
554 } | 554 } |
555 size_t trimRowBytes = width * bpp; | 555 size_t trimRowBytes = width * bpp; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 | 595 |
596 /* | 596 /* |
597 * check whether to allocate a temporary buffer for flipping y or | 597 * check whether to allocate a temporary buffer for flipping y or |
598 * because our srcData has extra bytes past each row. If so, we need | 598 * because our srcData has extra bytes past each row. If so, we need |
599 * to trim those off here, since GL ES may not let us specify | 599 * to trim those off here, since GL ES may not let us specify |
600 * GL_UNPACK_ROW_LENGTH. | 600 * GL_UNPACK_ROW_LENGTH. |
601 */ | 601 */ |
602 bool restoreGLRowLength = false; | 602 bool restoreGLRowLength = false; |
603 bool swFlipY = false; | 603 bool swFlipY = false; |
604 bool glFlipY = false; | 604 bool glFlipY = false; |
605 if (NULL != data) { | 605 if (data) { |
606 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { | 606 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
607 if (this->glCaps().unpackFlipYSupport()) { | 607 if (this->glCaps().unpackFlipYSupport()) { |
608 glFlipY = true; | 608 glFlipY = true; |
609 } else { | 609 } else { |
610 swFlipY = true; | 610 swFlipY = true; |
611 } | 611 } |
612 } | 612 } |
613 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { | 613 if (this->glCaps().unpackRowLengthSupport() && !swFlipY) { |
614 // can't use this for flipping, only non-neg values allowed. :( | 614 // can't use this for flipping, only non-neg values allowed. :( |
615 if (rowBytes != trimRowBytes) { | 615 if (rowBytes != trimRowBytes) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 0, // border | 666 0, // border |
667 externalFormat, externalType, | 667 externalFormat, externalType, |
668 data)); | 668 data)); |
669 } | 669 } |
670 GrGLenum error = check_alloc_error(desc, this->glInterface()); | 670 GrGLenum error = check_alloc_error(desc, this->glInterface()); |
671 if (error != GR_GL_NO_ERROR) { | 671 if (error != GR_GL_NO_ERROR) { |
672 succeeded = false; | 672 succeeded = false; |
673 } else { | 673 } else { |
674 // if we have data and we used TexStorage to create the texture, we | 674 // if we have data and we used TexStorage to create the texture, we |
675 // now upload with TexSubImage. | 675 // now upload with TexSubImage. |
676 if (NULL != data && useTexStorage) { | 676 if (data && useTexStorage) { |
677 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, | 677 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D, |
678 0, // level | 678 0, // level |
679 left, top, | 679 left, top, |
680 width, height, | 680 width, height, |
681 externalFormat, externalType, | 681 externalFormat, externalType, |
682 data)); | 682 data)); |
683 } | 683 } |
684 } | 684 } |
685 } else { | 685 } else { |
686 if (swFlipY || glFlipY) { | 686 if (swFlipY || glFlipY) { |
(...skipping 18 matching lines...) Expand all Loading... |
705 | 705 |
706 // TODO: This function is using a lot of wonky semantics like, if width == -1 | 706 // TODO: This function is using a lot of wonky semantics like, if width == -1 |
707 // then set width = desc.fWdith ... blah. A better way to do it might be to | 707 // then set width = desc.fWdith ... blah. A better way to do it might be to |
708 // create a CompressedTexData struct that takes a desc/ptr and figures out | 708 // create a CompressedTexData struct that takes a desc/ptr and figures out |
709 // the proper upload semantics. Then users can construct this function how they | 709 // the proper upload semantics. Then users can construct this function how they |
710 // see fit if they want to go against the "standard" way to do it. | 710 // see fit if they want to go against the "standard" way to do it. |
711 bool GrGpuGL::uploadCompressedTexData(const GrGLTexture::Desc& desc, | 711 bool GrGpuGL::uploadCompressedTexData(const GrGLTexture::Desc& desc, |
712 const void* data, | 712 const void* data, |
713 bool isNewTexture, | 713 bool isNewTexture, |
714 int left, int top, int width, int height)
{ | 714 int left, int top, int width, int height)
{ |
715 SkASSERT(NULL != data || isNewTexture); | 715 SkASSERT(data || isNewTexture); |
716 | 716 |
717 // No support for software flip y, yet... | 717 // No support for software flip y, yet... |
718 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); | 718 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); |
719 | 719 |
720 if (-1 == width) { | 720 if (-1 == width) { |
721 width = desc.fWidth; | 721 width = desc.fWidth; |
722 } | 722 } |
723 #ifdef SK_DEBUG | 723 #ifdef SK_DEBUG |
724 else { | 724 else { |
725 SkASSERT(width <= desc.fWidth); | 725 SkASSERT(width <= desc.fWidth); |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 GL_CALL(DeleteRenderbuffers(1, &sbID)); | 1218 GL_CALL(DeleteRenderbuffers(1, &sbID)); |
1219 return false; | 1219 return false; |
1220 } | 1220 } |
1221 | 1221 |
1222 bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { | 1222 bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
get* rt) { |
1223 GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt; | 1223 GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt; |
1224 | 1224 |
1225 GrGLuint fbo = glrt->renderFBOID(); | 1225 GrGLuint fbo = glrt->renderFBOID(); |
1226 | 1226 |
1227 if (NULL == sb) { | 1227 if (NULL == sb) { |
1228 if (NULL != rt->getStencilBuffer()) { | 1228 if (rt->getStencilBuffer()) { |
1229 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1229 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1230 GR_GL_STENCIL_ATTACHMENT, | 1230 GR_GL_STENCIL_ATTACHMENT, |
1231 GR_GL_RENDERBUFFER, 0)); | 1231 GR_GL_RENDERBUFFER, 0)); |
1232 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, | 1232 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, |
1233 GR_GL_DEPTH_ATTACHMENT, | 1233 GR_GL_DEPTH_ATTACHMENT, |
1234 GR_GL_RENDERBUFFER, 0)); | 1234 GR_GL_RENDERBUFFER, 0)); |
1235 #ifdef SK_DEBUG | 1235 #ifdef SK_DEBUG |
1236 GrGLenum status; | 1236 GrGLenum status; |
1237 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1237 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
1238 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); | 1238 SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 if (kNo_TriState != fHWScissorSettings.fEnabled) { | 1375 if (kNo_TriState != fHWScissorSettings.fEnabled) { |
1376 GL_CALL(Disable(GR_GL_SCISSOR_TEST)); | 1376 GL_CALL(Disable(GR_GL_SCISSOR_TEST)); |
1377 fHWScissorSettings.fEnabled = kNo_TriState; | 1377 fHWScissorSettings.fEnabled = kNo_TriState; |
1378 return; | 1378 return; |
1379 } | 1379 } |
1380 } | 1380 } |
1381 | 1381 |
1382 void GrGpuGL::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color
, | 1382 void GrGpuGL::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color
, |
1383 bool canIgnoreRect) { | 1383 bool canIgnoreRect) { |
1384 // parent class should never let us get here with no RT | 1384 // parent class should never let us get here with no RT |
1385 SkASSERT(NULL != target); | 1385 SkASSERT(target); |
1386 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); | 1386 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); |
1387 | 1387 |
1388 if (canIgnoreRect && this->glCaps().fullClearIsFree()) { | 1388 if (canIgnoreRect && this->glCaps().fullClearIsFree()) { |
1389 rect = NULL; | 1389 rect = NULL; |
1390 } | 1390 } |
1391 | 1391 |
1392 SkIRect clippedRect; | 1392 SkIRect clippedRect; |
1393 if (NULL != rect) { | 1393 if (rect) { |
1394 // flushScissor expects rect to be clipped to the target. | 1394 // flushScissor expects rect to be clipped to the target. |
1395 clippedRect = *rect; | 1395 clippedRect = *rect; |
1396 SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height()); | 1396 SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height()); |
1397 if (clippedRect.intersect(rtRect)) { | 1397 if (clippedRect.intersect(rtRect)) { |
1398 rect = &clippedRect; | 1398 rect = &clippedRect; |
1399 } else { | 1399 } else { |
1400 return; | 1400 return; |
1401 } | 1401 } |
1402 } | 1402 } |
1403 | 1403 |
1404 this->flushRenderTarget(glRT, rect); | 1404 this->flushRenderTarget(glRT, rect); |
1405 GrAutoTRestore<ScissorState> asr(&fScissorState); | 1405 GrAutoTRestore<ScissorState> asr(&fScissorState); |
1406 fScissorState.fEnabled = (NULL != rect); | 1406 fScissorState.fEnabled = SkToBool(rect); |
1407 if (fScissorState.fEnabled) { | 1407 if (fScissorState.fEnabled) { |
1408 fScissorState.fRect = *rect; | 1408 fScissorState.fRect = *rect; |
1409 } | 1409 } |
1410 this->flushScissor(glRT->getViewport(), glRT->origin()); | 1410 this->flushScissor(glRT->getViewport(), glRT->origin()); |
1411 | 1411 |
1412 GrGLfloat r, g, b, a; | 1412 GrGLfloat r, g, b, a; |
1413 static const GrGLfloat scale255 = 1.f / 255.f; | 1413 static const GrGLfloat scale255 = 1.f / 255.f; |
1414 a = GrColorUnpackA(color) * scale255; | 1414 a = GrColorUnpackA(color) * scale255; |
1415 GrGLfloat scaleRGB = scale255; | 1415 GrGLfloat scaleRGB = scale255; |
1416 r = GrColorUnpackR(color) * scaleRGB; | 1416 r = GrColorUnpackR(color) * scaleRGB; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1488 fScissorState.fEnabled = false; | 1488 fScissorState.fEnabled = false; |
1489 this->flushScissor(glRT->getViewport(), glRT->origin()); | 1489 this->flushScissor(glRT->getViewport(), glRT->origin()); |
1490 | 1490 |
1491 GL_CALL(StencilMask(0xffffffff)); | 1491 GL_CALL(StencilMask(0xffffffff)); |
1492 GL_CALL(ClearStencil(0)); | 1492 GL_CALL(ClearStencil(0)); |
1493 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); | 1493 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); |
1494 fHWStencilSettings.invalidate(); | 1494 fHWStencilSettings.invalidate(); |
1495 } | 1495 } |
1496 | 1496 |
1497 void GrGpuGL::clearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool
insideClip) { | 1497 void GrGpuGL::clearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool
insideClip) { |
1498 SkASSERT(NULL != target); | 1498 SkASSERT(target); |
1499 | 1499 |
1500 // this should only be called internally when we know we have a | 1500 // this should only be called internally when we know we have a |
1501 // stencil buffer. | 1501 // stencil buffer. |
1502 SkASSERT(NULL != target->getStencilBuffer()); | 1502 SkASSERT(target->getStencilBuffer()); |
1503 GrGLint stencilBitCount = target->getStencilBuffer()->bits(); | 1503 GrGLint stencilBitCount = target->getStencilBuffer()->bits(); |
1504 #if 0 | 1504 #if 0 |
1505 SkASSERT(stencilBitCount > 0); | 1505 SkASSERT(stencilBitCount > 0); |
1506 GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); | 1506 GrGLint clipStencilMask = (1 << (stencilBitCount - 1)); |
1507 #else | 1507 #else |
1508 // we could just clear the clip bit but when we go through | 1508 // we could just clear the clip bit but when we go through |
1509 // ANGLE a partial stencil mask will cause clears to be | 1509 // ANGLE a partial stencil mask will cause clears to be |
1510 // turned into draws. Our contract on GrDrawTarget says that | 1510 // turned into draws. Our contract on GrDrawTarget says that |
1511 // changing the clip between stencil passes may or may not | 1511 // changing the clip between stencil passes may or may not |
1512 // zero the client's clip bits. So we just clear the whole thing. | 1512 // zero the client's clip bits. So we just clear the whole thing. |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1686 } else { | 1686 } else { |
1687 dst -= rowBytes; | 1687 dst -= rowBytes; |
1688 } | 1688 } |
1689 } | 1689 } |
1690 } | 1690 } |
1691 return true; | 1691 return true; |
1692 } | 1692 } |
1693 | 1693 |
1694 void GrGpuGL::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound)
{ | 1694 void GrGpuGL::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound)
{ |
1695 | 1695 |
1696 SkASSERT(NULL != target); | 1696 SkASSERT(target); |
1697 | 1697 |
1698 uint32_t rtID = target->getUniqueID(); | 1698 uint32_t rtID = target->getUniqueID(); |
1699 if (fHWBoundRenderTargetUniqueID != rtID) { | 1699 if (fHWBoundRenderTargetUniqueID != rtID) { |
1700 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); | 1700 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID())); |
1701 #ifdef SK_DEBUG | 1701 #ifdef SK_DEBUG |
1702 // don't do this check in Chromium -- this is causing | 1702 // don't do this check in Chromium -- this is causing |
1703 // lots of repeated command buffer flushes when the compositor is | 1703 // lots of repeated command buffer flushes when the compositor is |
1704 // rendering with Ganesh, which is really slow; even too slow for | 1704 // rendering with Ganesh, which is really slow; even too slow for |
1705 // Debug mode. | 1705 // Debug mode. |
1706 if (!this->glContext().isChromium()) { | 1706 if (!this->glContext().isChromium()) { |
1707 GrGLenum status; | 1707 GrGLenum status; |
1708 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | 1708 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
1709 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 1709 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
1710 GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x
\n", status); | 1710 GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x
\n", status); |
1711 } | 1711 } |
1712 } | 1712 } |
1713 #endif | 1713 #endif |
1714 fHWBoundRenderTargetUniqueID = rtID; | 1714 fHWBoundRenderTargetUniqueID = rtID; |
1715 const GrGLIRect& vp = target->getViewport(); | 1715 const GrGLIRect& vp = target->getViewport(); |
1716 if (fHWViewport != vp) { | 1716 if (fHWViewport != vp) { |
1717 vp.pushToGLViewport(this->glInterface()); | 1717 vp.pushToGLViewport(this->glInterface()); |
1718 fHWViewport = vp; | 1718 fHWViewport = vp; |
1719 } | 1719 } |
1720 } | 1720 } |
1721 if (NULL == bound || !bound->isEmpty()) { | 1721 if (NULL == bound || !bound->isEmpty()) { |
1722 target->flagAsNeedingResolve(bound); | 1722 target->flagAsNeedingResolve(bound); |
1723 } | 1723 } |
1724 | 1724 |
1725 GrTexture *texture = target->asTexture(); | 1725 GrTexture *texture = target->asTexture(); |
1726 if (NULL != texture) { | 1726 if (texture) { |
1727 texture->impl()->dirtyMipMaps(true); | 1727 texture->impl()->dirtyMipMaps(true); |
1728 } | 1728 } |
1729 } | 1729 } |
1730 | 1730 |
1731 GrGLenum gPrimitiveType2GLMode[] = { | 1731 GrGLenum gPrimitiveType2GLMode[] = { |
1732 GR_GL_TRIANGLES, | 1732 GR_GL_TRIANGLES, |
1733 GR_GL_TRIANGLE_STRIP, | 1733 GR_GL_TRIANGLE_STRIP, |
1734 GR_GL_TRIANGLE_FAN, | 1734 GR_GL_TRIANGLE_FAN, |
1735 GR_GL_POINTS, | 1735 GR_GL_POINTS, |
1736 GR_GL_LINES, | 1736 GR_GL_LINES, |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1999 GR_GL_MIRRORED_REPEAT | 1999 GR_GL_MIRRORED_REPEAT |
2000 }; | 2000 }; |
2001 GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes)); | 2001 GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes)); |
2002 GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode); | 2002 GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode); |
2003 GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode); | 2003 GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode); |
2004 GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode); | 2004 GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode); |
2005 return gWrapModes[tm]; | 2005 return gWrapModes[tm]; |
2006 } | 2006 } |
2007 | 2007 |
2008 void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
e* texture) { | 2008 void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
e* texture) { |
2009 SkASSERT(NULL != texture); | 2009 SkASSERT(texture); |
2010 | 2010 |
2011 // If we created a rt/tex and rendered to it without using a texture and now
we're texturing | 2011 // If we created a rt/tex and rendered to it without using a texture and now
we're texturing |
2012 // from the rt it will still be the last bound texture, but it needs resolvi
ng. So keep this | 2012 // from the rt it will still be the last bound texture, but it needs resolvi
ng. So keep this |
2013 // out of the "last != next" check. | 2013 // out of the "last != next" check. |
2014 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderT
arget()); | 2014 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderT
arget()); |
2015 if (NULL != texRT) { | 2015 if (texRT) { |
2016 this->onResolveRenderTarget(texRT); | 2016 this->onResolveRenderTarget(texRT); |
2017 } | 2017 } |
2018 | 2018 |
2019 uint32_t textureID = texture->getUniqueID(); | 2019 uint32_t textureID = texture->getUniqueID(); |
2020 if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) { | 2020 if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) { |
2021 this->setTextureUnit(unitIdx); | 2021 this->setTextureUnit(unitIdx); |
2022 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID())); | 2022 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID())); |
2023 fHWBoundTextureUniqueIDs[unitIdx] = textureID; | 2023 fHWBoundTextureUniqueIDs[unitIdx] = textureID; |
2024 } | 2024 } |
2025 | 2025 |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2311 bool* wouldNeedTempFBO = NULL) { | 2311 bool* wouldNeedTempFBO = NULL) { |
2312 if (gpu->glCaps().isConfigRenderable(dst->config(), dst->desc().fSampleCnt >
0) && | 2312 if (gpu->glCaps().isConfigRenderable(dst->config(), dst->desc().fSampleCnt >
0) && |
2313 gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && | 2313 gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && |
2314 gpu->glCaps().usesMSAARenderBuffers()) { | 2314 gpu->glCaps().usesMSAARenderBuffers()) { |
2315 // ES3 doesn't allow framebuffer blits when the src has MSAA and the con
figs don't match | 2315 // ES3 doesn't allow framebuffer blits when the src has MSAA and the con
figs don't match |
2316 // or the rects are not the same (not just the same size but have the sa
me edges). | 2316 // or the rects are not the same (not just the same size but have the sa
me edges). |
2317 if (GrGLCaps::kES_3_0_MSFBOType == gpu->glCaps().msFBOType() && | 2317 if (GrGLCaps::kES_3_0_MSFBOType == gpu->glCaps().msFBOType() && |
2318 (src->desc().fSampleCnt > 0 || src->config() != dst->config())) { | 2318 (src->desc().fSampleCnt > 0 || src->config() != dst->config())) { |
2319 return false; | 2319 return false; |
2320 } | 2320 } |
2321 if (NULL != wouldNeedTempFBO) { | 2321 if (wouldNeedTempFBO) { |
2322 *wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->as
RenderTarget(); | 2322 *wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->as
RenderTarget(); |
2323 } | 2323 } |
2324 return true; | 2324 return true; |
2325 } else { | 2325 } else { |
2326 return false; | 2326 return false; |
2327 } | 2327 } |
2328 } | 2328 } |
2329 | 2329 |
2330 inline bool can_copy_texsubimage(const GrSurface* dst, | 2330 inline bool can_copy_texsubimage(const GrSurface* dst, |
2331 const GrSurface* src, | 2331 const GrSurface* src, |
2332 const GrGpuGL* gpu, | 2332 const GrGpuGL* gpu, |
2333 bool* wouldNeedTempFBO = NULL) { | 2333 bool* wouldNeedTempFBO = NULL) { |
2334 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSub
Image | 2334 // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSub
Image |
2335 // and BGRA isn't in the spec. There doesn't appear to be any extension that
adds it. Perhaps | 2335 // and BGRA isn't in the spec. There doesn't appear to be any extension that
adds it. Perhaps |
2336 // many drivers would allow it to work, but ANGLE does not. | 2336 // many drivers would allow it to work, but ANGLE does not. |
2337 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF
ormat() && | 2337 if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalF
ormat() && |
2338 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig =
= src->config())) { | 2338 (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig =
= src->config())) { |
2339 return false; | 2339 return false; |
2340 } | 2340 } |
2341 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as
RenderTarget()); | 2341 const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->as
RenderTarget()); |
2342 // If dst is multisampled (and uses an extension where there is a separate M
SAA renderbuffer) | 2342 // If dst is multisampled (and uses an extension where there is a separate M
SAA renderbuffer) |
2343 // then we don't want to copy to the texture but to the MSAA buffer. | 2343 // then we don't want to copy to the texture but to the MSAA buffer. |
2344 if (NULL != dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) { | 2344 if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) { |
2345 return false; | 2345 return false; |
2346 } | 2346 } |
2347 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); | 2347 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); |
2348 // If the src is multisampled (and uses an extension where there is a separa
te MSAA | 2348 // If the src is multisampled (and uses an extension where there is a separa
te MSAA |
2349 // renderbuffer) then it is an invalid operation to call CopyTexSubImage | 2349 // renderbuffer) then it is an invalid operation to call CopyTexSubImage |
2350 if (NULL != srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { | 2350 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { |
2351 return false; | 2351 return false; |
2352 } | 2352 } |
2353 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && | 2353 if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt >
0) && |
2354 NULL != dst->asTexture() && | 2354 dst->asTexture() && |
2355 dst->origin() == src->origin() && | 2355 dst->origin() == src->origin() && |
2356 !GrPixelConfigIsCompressed(src->config())) { | 2356 !GrPixelConfigIsCompressed(src->config())) { |
2357 if (NULL != wouldNeedTempFBO) { | 2357 if (wouldNeedTempFBO) { |
2358 *wouldNeedTempFBO = NULL == src->asRenderTarget(); | 2358 *wouldNeedTempFBO = NULL == src->asRenderTarget(); |
2359 } | 2359 } |
2360 return true; | 2360 return true; |
2361 } else { | 2361 } else { |
2362 return false; | 2362 return false; |
2363 } | 2363 } |
2364 } | 2364 } |
2365 | 2365 |
2366 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is | 2366 // If a temporary FBO was created, its non-zero ID is returned. The viewport tha
t the copy rect is |
2367 // relative to is output. | 2367 // relative to is output. |
2368 inline GrGLuint bind_surface_as_fbo(const GrGLInterface* gl, | 2368 inline GrGLuint bind_surface_as_fbo(const GrGLInterface* gl, |
2369 GrSurface* surface, | 2369 GrSurface* surface, |
2370 GrGLenum fboTarget, | 2370 GrGLenum fboTarget, |
2371 GrGLIRect* viewport) { | 2371 GrGLIRect* viewport) { |
2372 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); | 2372 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarge
t()); |
2373 GrGLuint tempFBOID; | 2373 GrGLuint tempFBOID; |
2374 if (NULL == rt) { | 2374 if (NULL == rt) { |
2375 SkASSERT(NULL != surface->asTexture()); | 2375 SkASSERT(surface->asTexture()); |
2376 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); | 2376 GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textur
eID(); |
2377 GR_GL_CALL(gl, GenFramebuffers(1, &tempFBOID)); | 2377 GR_GL_CALL(gl, GenFramebuffers(1, &tempFBOID)); |
2378 GR_GL_CALL(gl, BindFramebuffer(fboTarget, tempFBOID)); | 2378 GR_GL_CALL(gl, BindFramebuffer(fboTarget, tempFBOID)); |
2379 GR_GL_CALL(gl, FramebufferTexture2D(fboTarget, | 2379 GR_GL_CALL(gl, FramebufferTexture2D(fboTarget, |
2380 GR_GL_COLOR_ATTACHMENT0, | 2380 GR_GL_COLOR_ATTACHMENT0, |
2381 GR_GL_TEXTURE_2D, | 2381 GR_GL_TEXTURE_2D, |
2382 texID, | 2382 texID, |
2383 0)); | 2383 0)); |
2384 viewport->fLeft = 0; | 2384 viewport->fLeft = 0; |
2385 viewport->fBottom = 0; | 2385 viewport->fBottom = 0; |
(...skipping 18 matching lines...) Expand all Loading... |
2404 INHERITED::initCopySurfaceDstDesc(src, desc); | 2404 INHERITED::initCopySurfaceDstDesc(src, desc); |
2405 return; | 2405 return; |
2406 } else if (NULL == src->asRenderTarget()) { | 2406 } else if (NULL == src->asRenderTarget()) { |
2407 // We don't want to have to create an FBO just to use glCopyTexSubImage2
D. Let the base | 2407 // We don't want to have to create an FBO just to use glCopyTexSubImage2
D. Let the base |
2408 // class handle it by rendering. | 2408 // class handle it by rendering. |
2409 INHERITED::initCopySurfaceDstDesc(src, desc); | 2409 INHERITED::initCopySurfaceDstDesc(src, desc); |
2410 return; | 2410 return; |
2411 } | 2411 } |
2412 | 2412 |
2413 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); | 2413 const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->as
RenderTarget()); |
2414 if (NULL != srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { | 2414 if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { |
2415 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. | 2415 // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. |
2416 INHERITED::initCopySurfaceDstDesc(src, desc); | 2416 INHERITED::initCopySurfaceDstDesc(src, desc); |
2417 } else { | 2417 } else { |
2418 desc->fConfig = src->config(); | 2418 desc->fConfig = src->config(); |
2419 desc->fOrigin = src->origin(); | 2419 desc->fOrigin = src->origin(); |
2420 desc->fFlags = kNone_GrTextureFlags; | 2420 desc->fFlags = kNone_GrTextureFlags; |
2421 } | 2421 } |
2422 } | 2422 } |
2423 | 2423 |
2424 bool GrGpuGL::onCopySurface(GrSurface* dst, | 2424 bool GrGpuGL::onCopySurface(GrSurface* dst, |
2425 GrSurface* src, | 2425 GrSurface* src, |
2426 const SkIRect& srcRect, | 2426 const SkIRect& srcRect, |
2427 const SkIPoint& dstPoint) { | 2427 const SkIPoint& dstPoint) { |
2428 bool inheritedCouldCopy = INHERITED::onCanCopySurface(dst, src, srcRect, dst
Point); | 2428 bool inheritedCouldCopy = INHERITED::onCanCopySurface(dst, src, srcRect, dst
Point); |
2429 bool copied = false; | 2429 bool copied = false; |
2430 bool wouldNeedTempFBO = false; | 2430 bool wouldNeedTempFBO = false; |
2431 if (can_copy_texsubimage(dst, src, this, &wouldNeedTempFBO) && | 2431 if (can_copy_texsubimage(dst, src, this, &wouldNeedTempFBO) && |
2432 (!wouldNeedTempFBO || !inheritedCouldCopy)) { | 2432 (!wouldNeedTempFBO || !inheritedCouldCopy)) { |
2433 GrGLuint srcFBO; | 2433 GrGLuint srcFBO; |
2434 GrGLIRect srcVP; | 2434 GrGLIRect srcVP; |
2435 srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_FRAMEBUFFER
, &srcVP); | 2435 srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_FRAMEBUFFER
, &srcVP); |
2436 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); | 2436 GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); |
2437 SkASSERT(NULL != dstTex); | 2437 SkASSERT(dstTex); |
2438 // We modified the bound FBO | 2438 // We modified the bound FBO |
2439 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | 2439 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
2440 GrGLIRect srcGLRect; | 2440 GrGLIRect srcGLRect; |
2441 srcGLRect.setRelativeTo(srcVP, | 2441 srcGLRect.setRelativeTo(srcVP, |
2442 srcRect.fLeft, | 2442 srcRect.fLeft, |
2443 srcRect.fTop, | 2443 srcRect.fTop, |
2444 srcRect.width(), | 2444 srcRect.width(), |
2445 srcRect.height(), | 2445 srcRect.height(), |
2446 src->origin()); | 2446 src->origin()); |
2447 | 2447 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2570 if (this->caps()->gpuTracingSupport()) { | 2570 if (this->caps()->gpuTracingSupport()) { |
2571 GL_CALL(PopGroupMarker()); | 2571 GL_CALL(PopGroupMarker()); |
2572 } | 2572 } |
2573 } | 2573 } |
2574 /////////////////////////////////////////////////////////////////////////////// | 2574 /////////////////////////////////////////////////////////////////////////////// |
2575 | 2575 |
2576 GrGLAttribArrayState* GrGpuGL::HWGeometryState::bindArrayAndBuffersToDraw( | 2576 GrGLAttribArrayState* GrGpuGL::HWGeometryState::bindArrayAndBuffersToDraw( |
2577 GrGpuGL* gpu, | 2577 GrGpuGL* gpu, |
2578 const GrGLVertexBuffer* vbuffer, | 2578 const GrGLVertexBuffer* vbuffer, |
2579 const GrGLIndexBuffer* ibuffer)
{ | 2579 const GrGLIndexBuffer* ibuffer)
{ |
2580 SkASSERT(NULL != vbuffer); | 2580 SkASSERT(vbuffer); |
2581 GrGLAttribArrayState* attribState; | 2581 GrGLAttribArrayState* attribState; |
2582 | 2582 |
2583 // We use a vertex array if we're on a core profile and the verts are in a V
BO. | 2583 // We use a vertex array if we're on a core profile and the verts are in a V
BO. |
2584 if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) { | 2584 if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) { |
2585 if (NULL == fVBOVertexArray || fVBOVertexArray->wasDestroyed()) { | 2585 if (NULL == fVBOVertexArray || fVBOVertexArray->wasDestroyed()) { |
2586 SkSafeUnref(fVBOVertexArray); | 2586 SkSafeUnref(fVBOVertexArray); |
2587 GrGLuint arrayID; | 2587 GrGLuint arrayID; |
2588 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); | 2588 GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID)); |
2589 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2589 int attrCount = gpu->glCaps().maxVertexAttributes(); |
2590 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (gpu, arrayID, attrCou
nt)); | 2590 fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (gpu, arrayID, attrCou
nt)); |
2591 } | 2591 } |
2592 attribState = fVBOVertexArray->bindWithIndexBuffer(ibuffer); | 2592 attribState = fVBOVertexArray->bindWithIndexBuffer(ibuffer); |
2593 } else { | 2593 } else { |
2594 if (NULL != ibuffer) { | 2594 if (ibuffer) { |
2595 this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID())
; | 2595 this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID())
; |
2596 } else { | 2596 } else { |
2597 this->setVertexArrayID(gpu, 0); | 2597 this->setVertexArrayID(gpu, 0); |
2598 } | 2598 } |
2599 int attrCount = gpu->glCaps().maxVertexAttributes(); | 2599 int attrCount = gpu->glCaps().maxVertexAttributes(); |
2600 if (fDefaultVertexArrayAttribState.count() != attrCount) { | 2600 if (fDefaultVertexArrayAttribState.count() != attrCount) { |
2601 fDefaultVertexArrayAttribState.resize(attrCount); | 2601 fDefaultVertexArrayAttribState.resize(attrCount); |
2602 } | 2602 } |
2603 attribState = &fDefaultVertexArrayAttribState; | 2603 attribState = &fDefaultVertexArrayAttribState; |
2604 } | 2604 } |
2605 return attribState; | 2605 return attribState; |
2606 } | 2606 } |
OLD | NEW |