1 2/* 3 * Copyright 2010 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11#include "SkGrTexturePixelRef.h" 12#include "GrContext.h" 13#include "GrTexture.h" 14#include "SkGr.h" 15#include "SkRect.h" 16 17// since we call lockPixels recursively on fBitmap, we need a distinct mutex, 18// to avoid deadlock with the default one provided by SkPixelRef. 19SK_DECLARE_STATIC_MUTEX(gROLockPixelsPixelRefMutex); 20 21SkROLockPixelsPixelRef::SkROLockPixelsPixelRef() : INHERITED(&gROLockPixelsPixelRefMutex) { 22} 23 24SkROLockPixelsPixelRef::~SkROLockPixelsPixelRef() { 25} 26 27void* SkROLockPixelsPixelRef::onLockPixels(SkColorTable** ctable) { 28 if (ctable) { 29 *ctable = NULL; 30 } 31 fBitmap.reset(); 32// SkDebugf("---------- calling readpixels in support of lockpixels\n"); 33 if (!this->onReadPixels(&fBitmap, NULL)) { 34 SkDebugf("SkROLockPixelsPixelRef::onLockPixels failed!\n"); 35 return NULL; 36 } 37 fBitmap.lockPixels(); 38 return fBitmap.getPixels(); 39} 40 41void SkROLockPixelsPixelRef::onUnlockPixels() { 42 fBitmap.unlockPixels(); 43} 44 45bool SkROLockPixelsPixelRef::onLockPixelsAreWritable() const { 46 return false; 47} 48 49/////////////////////////////////////////////////////////////////////////////// 50 51static SkGrTexturePixelRef* copyToTexturePixelRef(GrTexture* texture, 52 SkBitmap::Config dstConfig) { 53 if (NULL == texture) { 54 return NULL; 55 } 56 GrContext* context = texture->getContext(); 57 if (NULL == context) { 58 return NULL; 59 } 60 GrTextureDesc desc; 61 62 desc.fWidth = texture->width(); 63 desc.fHeight = texture->height(); 64 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 65 desc.fConfig = SkGr::BitmapConfig2PixelConfig(dstConfig, false); 66 desc.fSampleCnt = 0; 67 68 GrTexture* dst = context->createUncachedTexture(desc, NULL, 0); 69 if (NULL == dst) { 70 return NULL; 71 } 72 73 context->copyTexture(texture, dst->asRenderTarget()); 74 SkGrTexturePixelRef* pixelRef = new SkGrTexturePixelRef(dst); 75 GrSafeUnref(dst); 76 return pixelRef; 77} 78 79/////////////////////////////////////////////////////////////////////////////// 80 81SkGrTexturePixelRef::SkGrTexturePixelRef(GrTexture* tex) { 82 fTexture = tex; 83 GrSafeRef(tex); 84} 85 86SkGrTexturePixelRef::~SkGrTexturePixelRef() { 87 GrSafeUnref(fTexture); 88} 89 90SkGpuTexture* SkGrTexturePixelRef::getTexture() { 91 return (SkGpuTexture*)fTexture; 92} 93 94SkPixelRef* SkGrTexturePixelRef::deepCopy(SkBitmap::Config dstConfig) { 95 return copyToTexturePixelRef(fTexture, dstConfig); 96} 97 98bool SkGrTexturePixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { 99 if (NULL != fTexture && fTexture->isValid()) { 100 int left, top, width, height; 101 if (NULL != subset) { 102 left = subset->fLeft; 103 width = subset->width(); 104 top = subset->fTop; 105 height = subset->height(); 106 } else { 107 left = 0; 108 width = fTexture->width(); 109 top = 0; 110 height = fTexture->height(); 111 } 112 dst->setConfig(SkBitmap::kARGB_8888_Config, width, height); 113 dst->allocPixels(); 114 SkAutoLockPixels al(*dst); 115 void* buffer = dst->getPixels(); 116 return fTexture->readPixels(left, top, width, height, 117 kSkia8888_PM_GrPixelConfig, 118 buffer, dst->rowBytes()); 119 } else { 120 return false; 121 } 122} 123 124/////////////////////////////////////////////////////////////////////////////// 125 126SkGrRenderTargetPixelRef::SkGrRenderTargetPixelRef(GrRenderTarget* rt) { 127 fRenderTarget = rt; 128 GrSafeRef(fRenderTarget); 129} 130 131SkGrRenderTargetPixelRef::~SkGrRenderTargetPixelRef() { 132 GrSafeUnref(fRenderTarget); 133} 134 135SkGpuTexture* SkGrRenderTargetPixelRef::getTexture() { 136 if (NULL != fRenderTarget) { 137 return (SkGpuTexture*) fRenderTarget->asTexture(); 138 } 139 return NULL; 140} 141 142SkPixelRef* SkGrRenderTargetPixelRef::deepCopy(SkBitmap::Config dstConfig) { 143 if (NULL == fRenderTarget) { 144 return NULL; 145 } 146 // Note that when copying an SkGrRenderTargetPixelRef, we actually 147 // return an SkGrTexturePixelRef instead. This is because 148 // SkGrRenderTargetPixelRef is usually created in conjunction with 149 // GrTexture owned elsewhere (e.g., SkGpuDevice), and cannot live 150 // independently of that texture. SkGrTexturePixelRef, on the other 151 // hand, owns its own GrTexture, and is thus self-contained. 152 return copyToTexturePixelRef(fRenderTarget->asTexture(), dstConfig); 153} 154 155bool SkGrRenderTargetPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { 156 if (NULL != fRenderTarget && fRenderTarget->isValid()) { 157 int left, top, width, height; 158 if (NULL != subset) { 159 left = subset->fLeft; 160 width = subset->width(); 161 top = subset->fTop; 162 height = subset->height(); 163 } else { 164 left = 0; 165 width = fRenderTarget->width(); 166 top = 0; 167 height = fRenderTarget->height(); 168 } 169 dst->setConfig(SkBitmap::kARGB_8888_Config, width, height); 170 dst->allocPixels(); 171 SkAutoLockPixels al(*dst); 172 void* buffer = dst->getPixels(); 173 return fRenderTarget->readPixels(left, top, width, height, 174 kSkia8888_PM_GrPixelConfig, 175 buffer, dst->rowBytes()); 176 } else { 177 return false; 178 } 179} 180 181