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. 19 SK_DECLARE_STATIC_MUTEX(gROLockPixelsPixelRefMutex); 20 21 SkROLockPixelsPixelRef::SkROLockPixelsPixelRef() : INHERITED(&gROLockPixelsPixelRefMutex) { 22 } 23 24 SkROLockPixelsPixelRef::~SkROLockPixelsPixelRef() { 25 } 26 27 void* 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 41 void SkROLockPixelsPixelRef::onUnlockPixels() { 42 fBitmap.unlockPixels(); 43 } 44 45 bool SkROLockPixelsPixelRef::onLockPixelsAreWritable() const { 46 return false; 47 } 48 49 /////////////////////////////////////////////////////////////////////////////// 50 51 static 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 81 SkGrTexturePixelRef::SkGrTexturePixelRef(GrTexture* tex) { 82 fTexture = tex; 83 GrSafeRef(tex); 84 } 85 86 SkGrTexturePixelRef::~SkGrTexturePixelRef() { 87 GrSafeUnref(fTexture); 88 } 89 90 SkGpuTexture* SkGrTexturePixelRef::getTexture() { 91 return (SkGpuTexture*)fTexture; 92 } 93 94 SkPixelRef* SkGrTexturePixelRef::deepCopy(SkBitmap::Config dstConfig) { 95 return copyToTexturePixelRef(fTexture, dstConfig); 96 } 97 98 bool 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 126 SkGrRenderTargetPixelRef::SkGrRenderTargetPixelRef(GrRenderTarget* rt) { 127 fRenderTarget = rt; 128 GrSafeRef(fRenderTarget); 129 } 130 131 SkGrRenderTargetPixelRef::~SkGrRenderTargetPixelRef() { 132 GrSafeUnref(fRenderTarget); 133 } 134 135 SkGpuTexture* SkGrRenderTargetPixelRef::getTexture() { 136 if (NULL != fRenderTarget) { 137 return (SkGpuTexture*) fRenderTarget->asTexture(); 138 } 139 return NULL; 140 } 141 142 SkPixelRef* 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 155 bool 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