OLD | NEW |
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 #include "GrContext.h" | 9 #include "GrContext.h" |
10 | 10 |
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 swapRAndB = true; | 1421 swapRAndB = true; |
1422 } | 1422 } |
1423 | 1423 |
1424 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); | 1424 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); |
1425 | 1425 |
1426 if (unpremul && !GrPixelConfigIs8888(dstConfig)) { | 1426 if (unpremul && !GrPixelConfigIs8888(dstConfig)) { |
1427 // The unpremul flag is only allowed for these two configs. | 1427 // The unpremul flag is only allowed for these two configs. |
1428 return false; | 1428 return false; |
1429 } | 1429 } |
1430 | 1430 |
| 1431 SkAutoTUnref<GrTexture> tempTexture; |
| 1432 |
1431 // If the src is a texture and we would have to do conversions after read pi
xels, we instead | 1433 // If the src is a texture and we would have to do conversions after read pi
xels, we instead |
1432 // do the conversions by drawing the src to a scratch texture. If we handle
any of the | 1434 // do the conversions by drawing the src to a scratch texture. If we handle
any of the |
1433 // conversions in the draw we set the corresponding bool to false so that we
don't reapply it | 1435 // conversions in the draw we set the corresponding bool to false so that we
don't reapply it |
1434 // on the read back pixels. | 1436 // on the read back pixels. |
1435 GrTexture* src = target->asTexture(); | 1437 GrTexture* src = target->asTexture(); |
1436 if (src && (swapRAndB || unpremul || flipY)) { | 1438 if (src && (swapRAndB || unpremul || flipY)) { |
1437 // Make the scratch a render so we can read its pixels. | 1439 // Make the scratch a render so we can read its pixels. |
1438 GrSurfaceDesc desc; | 1440 GrSurfaceDesc desc; |
1439 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 1441 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
1440 desc.fWidth = width; | 1442 desc.fWidth = width; |
1441 desc.fHeight = height; | 1443 desc.fHeight = height; |
1442 desc.fConfig = readConfig; | 1444 desc.fConfig = readConfig; |
1443 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 1445 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
1444 | 1446 |
1445 // When a full read back is faster than a partial we could always make t
he scratch exactly | 1447 // When a full read back is faster than a partial we could always make t
he scratch exactly |
1446 // match the passed rect. However, if we see many different size rectang
les we will trash | 1448 // match the passed rect. However, if we see many different size rectang
les we will trash |
1447 // our texture cache and pay the cost of creating and destroying many te
xtures. So, we only | 1449 // our texture cache and pay the cost of creating and destroying many te
xtures. So, we only |
1448 // request an exact match when the caller is reading an entire RT. | 1450 // request an exact match when the caller is reading an entire RT. |
1449 ScratchTexMatch match = kApprox_ScratchTexMatch; | 1451 ScratchTexMatch match = kApprox_ScratchTexMatch; |
1450 if (0 == left && | 1452 if (0 == left && |
1451 0 == top && | 1453 0 == top && |
1452 target->width() == width && | 1454 target->width() == width && |
1453 target->height() == height && | 1455 target->height() == height && |
1454 fGpu->fullReadPixelsIsFasterThanPartial()) { | 1456 fGpu->fullReadPixelsIsFasterThanPartial()) { |
1455 match = kExact_ScratchTexMatch; | 1457 match = kExact_ScratchTexMatch; |
1456 } | 1458 } |
1457 SkAutoTUnref<GrTexture> texture(this->refScratchTexture(desc, match)); | 1459 tempTexture.reset(this->refScratchTexture(desc, match)); |
1458 if (texture) { | 1460 if (tempTexture) { |
1459 // compute a matrix to perform the draw | 1461 // compute a matrix to perform the draw |
1460 SkMatrix textureMatrix; | 1462 SkMatrix textureMatrix; |
1461 textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); | 1463 textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); |
1462 textureMatrix.postIDiv(src->width(), src->height()); | 1464 textureMatrix.postIDiv(src->width(), src->height()); |
1463 | 1465 |
1464 SkAutoTUnref<const GrFragmentProcessor> fp; | 1466 SkAutoTUnref<const GrFragmentProcessor> fp; |
1465 if (unpremul) { | 1467 if (unpremul) { |
1466 fp.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix
)); | 1468 fp.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix
)); |
1467 if (fp) { | 1469 if (fp) { |
1468 unpremul = false; // we no longer need to do this on CPU aft
er the read back. | 1470 unpremul = false; // we no longer need to do this on CPU aft
er the read back. |
(...skipping 12 matching lines...) Expand all Loading... |
1481 // We protect the existing geometry here since it may not be | 1483 // We protect the existing geometry here since it may not be |
1482 // clear to the caller that a draw operation (i.e., drawSimpleRe
ct) | 1484 // clear to the caller that a draw operation (i.e., drawSimpleRe
ct) |
1483 // can be invoked in this method | 1485 // can be invoked in this method |
1484 { | 1486 { |
1485 GrDrawTarget::AutoGeometryAndStatePush agasp(fDrawBuffer, | 1487 GrDrawTarget::AutoGeometryAndStatePush agasp(fDrawBuffer, |
1486 GrDrawTarget::k
Reset_ASRInit); | 1488 GrDrawTarget::k
Reset_ASRInit); |
1487 GrDrawState* drawState = fDrawBuffer->drawState(); | 1489 GrDrawState* drawState = fDrawBuffer->drawState(); |
1488 SkASSERT(fp); | 1490 SkASSERT(fp); |
1489 drawState->addColorProcessor(fp); | 1491 drawState->addColorProcessor(fp); |
1490 | 1492 |
1491 drawState->setRenderTarget(texture->asRenderTarget()); | 1493 drawState->setRenderTarget(tempTexture->asRenderTarget()); |
1492 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToSc
alar(height)); | 1494 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToSc
alar(height)); |
1493 fDrawBuffer->drawSimpleRect(rect); | 1495 fDrawBuffer->drawSimpleRect(rect); |
1494 // we want to read back from the scratch's origin | 1496 // we want to read back from the scratch's origin |
1495 left = 0; | 1497 left = 0; |
1496 top = 0; | 1498 top = 0; |
1497 target = texture->asRenderTarget(); | 1499 target = tempTexture->asRenderTarget(); |
1498 } | 1500 } |
1499 this->flushSurfaceWrites(target); | 1501 this->flushSurfaceWrites(target); |
1500 } | 1502 } |
1501 } | 1503 } |
1502 } | 1504 } |
1503 | 1505 |
1504 if (!fGpu->readPixels(target, | 1506 if (!fGpu->readPixels(target, |
1505 left, top, width, height, | 1507 left, top, width, height, |
1506 readConfig, buffer, rowBytes)) { | 1508 readConfig, buffer, rowBytes)) { |
1507 return false; | 1509 return false; |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 fResourceCache->printStats(); | 1779 fResourceCache->printStats(); |
1778 } | 1780 } |
1779 #endif | 1781 #endif |
1780 | 1782 |
1781 #if GR_GPU_STATS | 1783 #if GR_GPU_STATS |
1782 const GrContext::GPUStats* GrContext::gpuStats() const { | 1784 const GrContext::GPUStats* GrContext::gpuStats() const { |
1783 return fGpu->gpuStats(); | 1785 return fGpu->gpuStats(); |
1784 } | 1786 } |
1785 #endif | 1787 #endif |
1786 | 1788 |
OLD | NEW |