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

Side by Side Diff: src/gpu/GrContext.cpp

Issue 622663002: GrContext::copyTexture->GrContext::copySurface. Add a flush writes pixel ops flag. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 6 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
« no previous file with comments | « samplecode/SampleApp.cpp ('k') | src/gpu/GrSurface.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "GrContext.h" 10 #include "GrContext.h"
(...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 return false; 1367 return false;
1368 } 1368 }
1369 } 1369 }
1370 1370
1371 if (!(kDontFlush_PixelOpsFlag & flags) && texture->surfacePriv().hasPendingI O()) { 1371 if (!(kDontFlush_PixelOpsFlag & flags) && texture->surfacePriv().hasPendingI O()) {
1372 this->flush(); 1372 this->flush();
1373 } 1373 }
1374 1374
1375 return fGpu->writeTexturePixels(texture, left, top, width, height, 1375 return fGpu->writeTexturePixels(texture, left, top, width, height,
1376 config, buffer, rowBytes); 1376 config, buffer, rowBytes);
1377
1378 // No need to check the kFlushWrites flag here since we issued the write dir ectly to fGpu.
1377 } 1379 }
1378 1380
1379 bool GrContext::readTexturePixels(GrTexture* texture, 1381 bool GrContext::readTexturePixels(GrTexture* texture,
1380 int left, int top, int width, int height, 1382 int left, int top, int width, int height,
1381 GrPixelConfig config, void* buffer, size_t row Bytes, 1383 GrPixelConfig config, void* buffer, size_t row Bytes,
1382 uint32_t flags) { 1384 uint32_t flags) {
1383 ASSERT_OWNED_RESOURCE(texture); 1385 ASSERT_OWNED_RESOURCE(texture);
1384 1386
1385 GrRenderTarget* target = texture->asRenderTarget(); 1387 GrRenderTarget* target = texture->asRenderTarget();
1386 if (target) { 1388 if (target) {
1387 return this->readRenderTargetPixels(target, 1389 return this->readRenderTargetPixels(target,
1388 left, top, width, height, 1390 left, top, width, height,
1389 config, buffer, rowBytes, 1391 config, buffer, rowBytes,
1390 flags); 1392 flags);
1391 } else { 1393 } else {
1392 // TODO: make this more efficient for cases where we're reading the enti re 1394 // TODO: make this more efficient for cases where we're reading the enti re
1393 // texture, i.e., use GetTexImage() instead 1395 // texture, i.e., use GetTexImage() instead
1394 1396
1395 // create scratch rendertarget and read from that 1397 // create scratch rendertarget and read from that
1396 GrAutoScratchTexture ast; 1398 GrAutoScratchTexture ast;
1397 GrTextureDesc desc; 1399 GrTextureDesc desc;
1398 desc.fFlags = kRenderTarget_GrTextureFlagBit; 1400 desc.fFlags = kRenderTarget_GrTextureFlagBit;
1399 desc.fWidth = width; 1401 desc.fWidth = width;
1400 desc.fHeight = height; 1402 desc.fHeight = height;
1401 desc.fConfig = config; 1403 desc.fConfig = config;
1402 desc.fOrigin = kTopLeft_GrSurfaceOrigin; 1404 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
1403 ast.set(this, desc, kExact_ScratchTexMatch); 1405 ast.set(this, desc, kExact_ScratchTexMatch);
1404 GrTexture* dst = ast.texture(); 1406 GrTexture* dst = ast.texture();
1405 if (dst && (target = dst->asRenderTarget())) { 1407 if (dst && (target = dst->asRenderTarget())) {
1406 this->copyTexture(texture, target, NULL); 1408 this->copySurface(target, texture, SkIRect::MakeXYWH(top, left, widt h, height),
1409 SkIPoint::Make(0,0));
1407 return this->readRenderTargetPixels(target, 1410 return this->readRenderTargetPixels(target,
1408 left, top, width, height, 1411 left, top, width, height,
1409 config, buffer, rowBytes, 1412 config, buffer, rowBytes,
1410 flags); 1413 flags);
1411 } 1414 }
1412 1415
1413 return false; 1416 return false;
1414 } 1417 }
1415 } 1418 }
1416 1419
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 ASSERT_OWNED_RESOURCE(renderTarget); 1587 ASSERT_OWNED_RESOURCE(renderTarget);
1585 AutoRestoreEffects are; 1588 AutoRestoreEffects are;
1586 AutoCheckFlush acf(this); 1589 AutoCheckFlush acf(this);
1587 GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf); 1590 GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf);
1588 if (NULL == target) { 1591 if (NULL == target) {
1589 return; 1592 return;
1590 } 1593 }
1591 target->discard(renderTarget); 1594 target->discard(renderTarget);
1592 } 1595 }
1593 1596
1594 void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) { 1597 void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe ct,
1598 const SkIPoint& dstPoint, uint32_t pixelOpsFlags) {
1595 if (NULL == src || NULL == dst) { 1599 if (NULL == src || NULL == dst) {
1596 return; 1600 return;
1597 } 1601 }
1598 ASSERT_OWNED_RESOURCE(src); 1602 ASSERT_OWNED_RESOURCE(src);
1599 ASSERT_OWNED_RESOURCE(dst); 1603 ASSERT_OWNED_RESOURCE(dst);
1600 1604
1601 SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); 1605 // Since we're going to the draw target and not GPU, no need to check kNoFlu sh
1602 if (topLeft) { 1606 // here.
1603 srcRect.offset(*topLeft);
1604 }
1605 SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height());
1606 if (!srcRect.intersect(srcBounds)) {
1607 return;
1608 }
1609 1607
1610 GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL); 1608 GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL);
1611 if (NULL == target) { 1609 if (NULL == target) {
1612 return; 1610 return;
1613 } 1611 }
1614 SkIPoint dstPoint;
1615 dstPoint.setZero();
1616 target->copySurface(dst, src, srcRect, dstPoint); 1612 target->copySurface(dst, src, srcRect, dstPoint);
1613
1614 if (kFlushWrites_PixelOp & pixelOpsFlags) {
1615 this->flush();
1616 }
1617 } 1617 }
1618 1618
1619 bool GrContext::writeRenderTargetPixels(GrRenderTarget* renderTarget, 1619 bool GrContext::writeRenderTargetPixels(GrRenderTarget* renderTarget,
1620 int left, int top, int width, int height , 1620 int left, int top, int width, int height ,
1621 GrPixelConfig srcConfig, 1621 GrPixelConfig srcConfig,
1622 const void* buffer, 1622 const void* buffer,
1623 size_t rowBytes, 1623 size_t rowBytes,
1624 uint32_t flags) { 1624 uint32_t pixelOpsFlags) {
1625 ASSERT_OWNED_RESOURCE(renderTarget); 1625 ASSERT_OWNED_RESOURCE(renderTarget);
1626 1626
1627 if (NULL == renderTarget) { 1627 if (NULL == renderTarget) {
1628 renderTarget = fRenderTarget.get(); 1628 renderTarget = fRenderTarget.get();
1629 if (NULL == renderTarget) { 1629 if (NULL == renderTarget) {
1630 return false; 1630 return false;
1631 } 1631 }
1632 } 1632 }
1633 1633
1634 // TODO: when underlying api has a direct way to do this we should use it (e .g. glDrawPixels on 1634 // TODO: when underlying api has a direct way to do this we should use it (e .g. glDrawPixels on
1635 // desktop GL). 1635 // desktop GL).
1636 1636
1637 // We will always call some form of writeTexturePixels and we will pass our flags on to it. 1637 // We will always call some form of writeTexturePixels and we will pass our flags on to it.
1638 // Thus, we don't perform a flush here since that call will do it (if the kN oFlush flag isn't 1638 // Thus, we don't perform a flush here since that call will do it (if the kN oFlush flag isn't
1639 // set.) 1639 // set.)
1640 1640
1641 // If the RT is also a texture and we don't have to premultiply then take th e texture path. 1641 // If the RT is also a texture and we don't have to premultiply then take th e texture path.
1642 // We expect to be at least as fast or faster since it doesn't use an interm ediate texture as 1642 // We expect to be at least as fast or faster since it doesn't use an interm ediate texture as
1643 // we do below. 1643 // we do below.
1644 1644
1645 #if !defined(SK_BUILD_FOR_MAC) 1645 #if !defined(SK_BUILD_FOR_MAC)
1646 // At least some drivers on the Mac get confused when glTexImage2D is called on a texture 1646 // At least some drivers on the Mac get confused when glTexImage2D is called on a texture
1647 // attached to an FBO. The FBO still sees the old image. TODO: determine wha t OS versions and/or 1647 // attached to an FBO. The FBO still sees the old image. TODO: determine wha t OS versions and/or
1648 // HW is affected. 1648 // HW is affected.
1649 if (renderTarget->asTexture() && !(kUnpremul_PixelOpsFlag & flags) && 1649 if (renderTarget->asTexture() && !(kUnpremul_PixelOpsFlag & pixelOpsFlags) & &
1650 fGpu->canWriteTexturePixels(renderTarget->asTexture(), srcConfig)) { 1650 fGpu->canWriteTexturePixels(renderTarget->asTexture(), srcConfig)) {
1651 return this->writeTexturePixels(renderTarget->asTexture(), 1651 return this->writeTexturePixels(renderTarget->asTexture(),
1652 left, top, width, height, 1652 left, top, width, height,
1653 srcConfig, buffer, rowBytes, flags); 1653 srcConfig, buffer, rowBytes, pixelOpsFla gs);
1654 } 1654 }
1655 #endif 1655 #endif
1656 1656
1657 // We ignore the preferred config unless it is a R/B swap of the src config. In that case 1657 // We ignore the preferred config unless it is a R/B swap of the src config. In that case
1658 // we will upload the original src data to a scratch texture but we will spo of it as the swapped 1658 // we will upload the original src data to a scratch texture but we will spo of it as the swapped
1659 // config. This scratch will then have R and B swapped. We correct for this by swapping again 1659 // config. This scratch will then have R and B swapped. We correct for this by swapping again
1660 // when drawing the scratch to the dst using a conversion effect. 1660 // when drawing the scratch to the dst using a conversion effect.
1661 bool swapRAndB = false; 1661 bool swapRAndB = false;
1662 GrPixelConfig writeConfig = srcConfig; 1662 GrPixelConfig writeConfig = srcConfig;
1663 if (GrPixelConfigSwapRAndB(srcConfig) == 1663 if (GrPixelConfigSwapRAndB(srcConfig) ==
(...skipping 12 matching lines...) Expand all
1676 return false; 1676 return false;
1677 } 1677 }
1678 1678
1679 SkAutoTUnref<const GrFragmentProcessor> fp; 1679 SkAutoTUnref<const GrFragmentProcessor> fp;
1680 SkMatrix textureMatrix; 1680 SkMatrix textureMatrix;
1681 textureMatrix.setIDiv(texture->width(), texture->height()); 1681 textureMatrix.setIDiv(texture->width(), texture->height());
1682 1682
1683 // allocate a tmp buffer and sw convert the pixels to premul 1683 // allocate a tmp buffer and sw convert the pixels to premul
1684 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); 1684 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
1685 1685
1686 if (kUnpremul_PixelOpsFlag & flags) { 1686 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
1687 if (!GrPixelConfigIs8888(srcConfig)) { 1687 if (!GrPixelConfigIs8888(srcConfig)) {
1688 return false; 1688 return false;
1689 } 1689 }
1690 fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); 1690 fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix));
1691 // handle the unpremul step on the CPU if we couldn't create an effect t o do it. 1691 // handle the unpremul step on the CPU if we couldn't create an effect t o do it.
1692 if (NULL == fp) { 1692 if (NULL == fp) {
1693 SkSrcPixelInfo srcPI; 1693 SkSrcPixelInfo srcPI;
1694 if (!GrPixelConfig2ColorType(srcConfig, &srcPI.fColorType)) { 1694 if (!GrPixelConfig2ColorType(srcConfig, &srcPI.fColorType)) {
1695 return false; 1695 return false;
1696 } 1696 }
(...skipping 20 matching lines...) Expand all
1717 if (NULL == fp) { 1717 if (NULL == fp) {
1718 fp.reset(GrConfigConversionEffect::Create(texture, 1718 fp.reset(GrConfigConversionEffect::Create(texture,
1719 swapRAndB, 1719 swapRAndB,
1720 GrConfigConversionEffect::kNon e_PMConversion, 1720 GrConfigConversionEffect::kNon e_PMConversion,
1721 textureMatrix)); 1721 textureMatrix));
1722 } 1722 }
1723 1723
1724 if (!this->writeTexturePixels(texture, 1724 if (!this->writeTexturePixels(texture,
1725 0, 0, width, height, 1725 0, 0, width, height,
1726 writeConfig, buffer, rowBytes, 1726 writeConfig, buffer, rowBytes,
1727 flags & ~kUnpremul_PixelOpsFlag)) { 1727 pixelOpsFlags & ~kUnpremul_PixelOpsFlag)) {
1728 return false; 1728 return false;
1729 } 1729 }
1730 1730
1731 SkMatrix matrix; 1731 SkMatrix matrix;
1732 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); 1732 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
1733 1733
1734
1734 // This function can be called in the midst of drawing another object (e.g., when uploading a 1735 // This function can be called in the midst of drawing another object (e.g., when uploading a
1735 // SW-rasterized clip while issuing a draw). So we push the current geometry state before 1736 // SW-rasterized clip while issuing a draw). So we push the current geometry state before
1736 // drawing a rect to the render target. 1737 // drawing a rect to the render target.
1737 GrDrawTarget* drawTarget = this->prepareToDraw(NULL, kYes_BufferedDraw, NULL , NULL); 1738 // The bracket ensures we pop the stack if we wind up flushing below.
1738 GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::kRese t_ASRInit, &matrix); 1739 {
1739 GrDrawState* drawState = drawTarget->drawState(); 1740 GrDrawTarget* drawTarget = this->prepareToDraw(NULL, kYes_BufferedDraw, NULL, NULL);
1740 drawState->addColorProcessor(fp); 1741 GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::k Reset_ASRInit,
1741 drawState->setRenderTarget(renderTarget); 1742 &matrix);
1742 drawState->disableState(GrDrawState::kClip_StateBit); 1743 GrDrawState* drawState = drawTarget->drawState();
1743 drawTarget->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScala r(height))); 1744 drawState->addColorProcessor(fp);
1745 drawState->setRenderTarget(renderTarget);
1746 drawState->disableState(GrDrawState::kClip_StateBit);
1747 drawTarget->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToS calar(height)));
1748 }
1749
1750 if (kFlushWrites_PixelOp & pixelOpsFlags) {
1751 this->flush();
1752 }
1753
1744 return true; 1754 return true;
1745 } 1755 }
1756
1757 void GrContext::flushSurfaceWrites(GrSurface* surface) {
1758 if (surface->surfacePriv().hasPendingWrite()) {
1759 this->flush();
1760 }
1761 }
1762
1746 //////////////////////////////////////////////////////////////////////////////// 1763 ////////////////////////////////////////////////////////////////////////////////
1747 1764
1748 GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, 1765 GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint,
1749 BufferedDraw buffered, 1766 BufferedDraw buffered,
1750 AutoRestoreEffects* are, 1767 AutoRestoreEffects* are,
1751 AutoCheckFlush* acf) { 1768 AutoCheckFlush* acf) {
1752 // All users of this draw state should be freeing up all effects when they'r e done. 1769 // All users of this draw state should be freeing up all effects when they'r e done.
1753 // Otherwise effects that own resources may keep those resources alive indef initely. 1770 // Otherwise effects that own resources may keep those resources alive indef initely.
1754 SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageSt ages() && 1771 SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageSt ages() &&
1755 !fDrawState->hasGeometryProcessor()); 1772 !fDrawState->hasGeometryProcessor());
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 fResourceCache->printStats(); 1971 fResourceCache->printStats();
1955 } 1972 }
1956 #endif 1973 #endif
1957 1974
1958 #if GR_GPU_STATS 1975 #if GR_GPU_STATS
1959 const GrContext::GPUStats* GrContext::gpuStats() const { 1976 const GrContext::GPUStats* GrContext::gpuStats() const {
1960 return fGpu->gpuStats(); 1977 return fGpu->gpuStats();
1961 } 1978 }
1962 #endif 1979 #endif
1963 1980
OLDNEW
« no previous file with comments | « samplecode/SampleApp.cpp ('k') | src/gpu/GrSurface.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698