diff options
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrContext.cpp | 21 | ||||
-rw-r--r-- | src/gpu/SkGrTexturePixelRef.cpp | 49 |
2 files changed, 70 insertions, 0 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 70c9f6de2f..e4b1150824 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -1813,6 +1813,27 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, config, buffer, rowBytes, flipY); } +void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { + if (NULL == src || NULL == dst) { + return; + } + ASSERT_OWNED_RESOURCE(src); + + GrDrawTarget::AutoStateRestore asr(fGpu); + reset_target_state(fGpu); + fGpu->setRenderTarget(dst); + GrSamplerState sampler(GrSamplerState::kClamp_WrapMode, + GrSamplerState::kClamp_WrapMode, + GrSamplerState::kNearest_Filter); + GrMatrix sampleM; + sampleM.setIDiv(src->width(), src->height()); + sampler.setMatrix(sampleM); + fGpu->setTexture(0, src); + fGpu->setSamplerState(0, sampler); + SkRect rect = SkRect::MakeXYWH(0, 0, src->width(), src->height()); + fGpu->drawSimpleRect(rect, NULL, 1 << 0); +} + void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, int left, int top, int width, int height, diff --git a/src/gpu/SkGrTexturePixelRef.cpp b/src/gpu/SkGrTexturePixelRef.cpp index 8d0eb892c8..045ddab87d 100644 --- a/src/gpu/SkGrTexturePixelRef.cpp +++ b/src/gpu/SkGrTexturePixelRef.cpp @@ -9,7 +9,9 @@ #include "SkGrTexturePixelRef.h" +#include "GrContext.h" #include "GrTexture.h" +#include "SkGr.h" #include "SkRect.h" // since we call lockPixels recursively on fBitmap, we need a distinct mutex, @@ -46,6 +48,36 @@ bool SkROLockPixelsPixelRef::onLockPixelsAreWritable() const { /////////////////////////////////////////////////////////////////////////////// +static SkGrTexturePixelRef* copyToTexturePixelRef(GrTexture* texture, + SkBitmap::Config dstConfig) { + if (NULL == texture) { + return NULL; + } + GrContext* context = texture->getContext(); + if (NULL == context) { + return NULL; + } + GrTextureDesc desc; + + desc.fWidth = texture->width(); + desc.fHeight = texture->height(); + desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; + desc.fConfig = SkGr::BitmapConfig2PixelConfig(dstConfig, false); + desc.fAALevel = kNone_GrAALevel; + + GrTexture* dst = context->createUncachedTexture(desc, NULL, 0); + if (NULL == dst) { + return NULL; + } + + context->copyTexture(texture, dst->asRenderTarget()); + SkGrTexturePixelRef* pixelRef = new SkGrTexturePixelRef(dst); + GrSafeUnref(dst); + return pixelRef; +} + +/////////////////////////////////////////////////////////////////////////////// + SkGrTexturePixelRef::SkGrTexturePixelRef(GrTexture* tex) { fTexture = tex; GrSafeRef(tex); @@ -59,6 +91,10 @@ SkGpuTexture* SkGrTexturePixelRef::getTexture() { return (SkGpuTexture*)fTexture; } +SkPixelRef* SkGrTexturePixelRef::deepCopy(SkBitmap::Config dstConfig) { + return copyToTexturePixelRef(fTexture, dstConfig); +} + bool SkGrTexturePixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { if (NULL != fTexture && fTexture->isValid()) { int left, top, width, height; @@ -103,6 +139,19 @@ SkGpuTexture* SkGrRenderTargetPixelRef::getTexture() { return NULL; } +SkPixelRef* SkGrRenderTargetPixelRef::deepCopy(SkBitmap::Config dstConfig) { + if (NULL == fRenderTarget) { + return NULL; + } + // Note that when copying an SkGrRenderTargetPixelRef, we actually + // return an SkGrTexturePixelRef instead. This is because + // SkGrRenderTargetPixelRef is usually created in conjunction with + // GrTexture owned elsewhere (e.g., SkGpuDevice), and cannot live + // independently of that texture. SkGrTexturePixelRef, on the other + // hand, owns its own GrTexture, and is thus self-contained. + return copyToTexturePixelRef(fRenderTarget->asTexture(), dstConfig); +} + bool SkGrRenderTargetPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { if (NULL != fRenderTarget && fRenderTarget->isValid()) { int left, top, width, height; |