Home | History | Annotate | Download | only in gpu
      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