Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2010 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkGr.h"
      9 
     10 #include "GrXferProcessor.h"
     11 #include "SkColorFilter.h"
     12 #include "SkConfig8888.h"
     13 #include "SkData.h"
     14 #include "SkErrorInternals.h"
     15 #include "SkGrPixelRef.h"
     16 #include "SkMessageBus.h"
     17 #include "SkPixelRef.h"
     18 #include "SkResourceCache.h"
     19 #include "SkTextureCompressor.h"
     20 #include "SkYUVPlanesCache.h"
     21 #include "effects/GrDitherEffect.h"
     22 #include "effects/GrPorterDuffXferProcessor.h"
     23 #include "effects/GrYUVtoRGBEffect.h"
     24 
     25 #ifndef SK_IGNORE_ETC1_SUPPORT
     26 #  include "ktx.h"
     27 #  include "etc1.h"
     28 #endif
     29 
     30 /*  Fill out buffer with the compressed format Ganesh expects from a colortable
     31  based bitmap. [palette (colortable) + indices].
     32 
     33  At the moment Ganesh only supports 8bit version. If Ganesh allowed we others
     34  we could detect that the colortable.count is <= 16, and then repack the
     35  indices as nibbles to save RAM, but it would take more time (i.e. a lot
     36  slower than memcpy), so skipping that for now.
     37 
     38  Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
     39  as the colortable.count says it is.
     40  */
     41 static void build_index8_data(void* buffer, const SkBitmap& bitmap) {
     42     SkASSERT(kIndex_8_SkColorType == bitmap.colorType());
     43 
     44     SkAutoLockPixels alp(bitmap);
     45     if (!bitmap.readyToDraw()) {
     46         SkDEBUGFAIL("bitmap not ready to draw!");
     47         return;
     48     }
     49 
     50     SkColorTable* ctable = bitmap.getColorTable();
     51     char* dst = (char*)buffer;
     52 
     53     const int count = ctable->count();
     54 
     55     SkDstPixelInfo dstPI;
     56     dstPI.fColorType = kRGBA_8888_SkColorType;
     57     dstPI.fAlphaType = kPremul_SkAlphaType;
     58     dstPI.fPixels = buffer;
     59     dstPI.fRowBytes = count * sizeof(SkPMColor);
     60 
     61     SkSrcPixelInfo srcPI;
     62     srcPI.fColorType = kN32_SkColorType;
     63     srcPI.fAlphaType = kPremul_SkAlphaType;
     64     srcPI.fPixels = ctable->readColors();
     65     srcPI.fRowBytes = count * sizeof(SkPMColor);
     66 
     67     srcPI.convertPixelsTo(&dstPI, count, 1);
     68 
     69     // always skip a full 256 number of entries, even if we memcpy'd fewer
     70     dst += 256 * sizeof(GrColor);
     71 
     72     if ((unsigned)bitmap.width() == bitmap.rowBytes()) {
     73         memcpy(dst, bitmap.getPixels(), bitmap.getSize());
     74     } else {
     75         // need to trim off the extra bytes per row
     76         size_t width = bitmap.width();
     77         size_t rowBytes = bitmap.rowBytes();
     78         const char* src = (const char*)bitmap.getPixels();
     79         for (int y = 0; y < bitmap.height(); y++) {
     80             memcpy(dst, src, width);
     81             src += rowBytes;
     82             dst += width;
     83         }
     84     }
     85 }
     86 
     87 ////////////////////////////////////////////////////////////////////////////////
     88 
     89 enum Stretch {
     90     kNo_Stretch,
     91     kBilerp_Stretch,
     92     kNearest_Stretch
     93 };
     94 
     95 static Stretch get_stretch_type(const GrContext* ctx, int width, int height,
     96                                 const GrTextureParams* params) {
     97     if (params && params->isTiled()) {
     98         if (!ctx->npotTextureTileSupport() && (!SkIsPow2(width) || !SkIsPow2(height))) {
     99             switch(params->filterMode()) {
    100                 case GrTextureParams::kNone_FilterMode:
    101                     return kNearest_Stretch;
    102                 case GrTextureParams::kBilerp_FilterMode:
    103                 case GrTextureParams::kMipMap_FilterMode:
    104                     return kBilerp_Stretch;
    105             }
    106         }
    107     }
    108     return kNo_Stretch;
    109 }
    110 
    111 static bool make_stretched_key(const GrUniqueKey& origKey, Stretch stretch,
    112                                GrUniqueKey* stretchedKey) {
    113     if (origKey.isValid() && kNo_Stretch != stretch) {
    114         static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
    115         GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 1);
    116         builder[0] = stretch;
    117         builder.finish();
    118         return true;
    119     }
    120     SkASSERT(!stretchedKey->isValid());
    121     return false;
    122 }
    123 
    124 static void make_unstretched_key(const SkBitmap& bitmap, GrUniqueKey* key) {
    125     // Our id includes the offset, width, and height so that bitmaps created by extractSubset()
    126     // are unique.
    127     uint32_t genID = bitmap.getGenerationID();
    128     SkIPoint origin = bitmap.pixelRefOrigin();
    129     uint32_t width = SkToU16(bitmap.width());
    130     uint32_t height = SkToU16(bitmap.height());
    131 
    132     static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
    133     GrUniqueKey::Builder builder(key, kDomain, 4);
    134     builder[0] = genID;
    135     builder[1] = origin.fX;
    136     builder[2] = origin.fY;
    137     builder[3] = width | (height << 16);
    138 }
    139 
    140 static void make_bitmap_keys(const SkBitmap& bitmap,
    141                              Stretch stretch,
    142                              GrUniqueKey* key,
    143                              GrUniqueKey* stretchedKey) {
    144     make_unstretched_key(bitmap, key);
    145     if (kNo_Stretch != stretch) {
    146         make_stretched_key(*key, stretch, stretchedKey);
    147     }
    148 }
    149 
    150 static void generate_bitmap_texture_desc(const SkBitmap& bitmap, GrSurfaceDesc* desc) {
    151     desc->fFlags = kNone_GrSurfaceFlags;
    152     desc->fWidth = bitmap.width();
    153     desc->fHeight = bitmap.height();
    154     desc->fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
    155     desc->fSampleCnt = 0;
    156 }
    157 
    158 namespace {
    159 
    160 // When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key.
    161 class BitmapInvalidator : public SkPixelRef::GenIDChangeListener {
    162 public:
    163     explicit BitmapInvalidator(const GrUniqueKey& key) : fMsg(key) {}
    164 private:
    165     GrUniqueKeyInvalidatedMessage fMsg;
    166 
    167     void onChange() override {
    168         SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg);
    169     }
    170 };
    171 
    172 }  // namespace
    173 
    174 
    175 static GrTexture* create_texture_for_bmp(GrContext* ctx,
    176                                          const GrUniqueKey& optionalKey,
    177                                          GrSurfaceDesc desc,
    178                                          SkPixelRef* pixelRefForInvalidationNotification,
    179                                          const void* pixels,
    180                                          size_t rowBytes) {
    181     GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels, rowBytes);
    182     if (result && optionalKey.isValid()) {
    183         BitmapInvalidator* listener = SkNEW_ARGS(BitmapInvalidator, (optionalKey));
    184         pixelRefForInvalidationNotification->addGenIDChangeListener(listener);
    185         ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result);
    186     }
    187     return result;
    188 }
    189 
    190 // creates a new texture that is the input texture scaled up to the next power of two in
    191 // width or height. If optionalKey is valid it will be set on the new texture. stretch
    192 // controls whether the scaling is done using nearest or bilerp filtering.
    193 GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch,
    194                                        SkPixelRef* pixelRef,
    195                                        const GrUniqueKey& optionalKey) {
    196     SkASSERT(kNo_Stretch != stretch);
    197 
    198     GrContext* context = inputTexture->getContext();
    199     SkASSERT(context);
    200 
    201     // Either it's a cache miss or the original wasn't cached to begin with.
    202     GrSurfaceDesc rtDesc = inputTexture->desc();
    203     rtDesc.fFlags =  rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
    204     rtDesc.fWidth  = GrNextPow2(rtDesc.fWidth);
    205     rtDesc.fHeight = GrNextPow2(rtDesc.fHeight);
    206     rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
    207 
    208     // If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise,
    209     // fail.
    210     if (!context->isConfigRenderable(rtDesc.fConfig, false)) {
    211         if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) {
    212             if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
    213                 rtDesc.fConfig = kAlpha_8_GrPixelConfig;
    214             } else if (context->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
    215                 rtDesc.fConfig = kSkia8888_GrPixelConfig;
    216             } else {
    217                 return NULL;
    218             }
    219         } else if (kRGB_GrColorComponentFlags ==
    220                    (kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDesc.fConfig))) {
    221             if (context->isConfigRenderable(kSkia8888_GrPixelConfig, false)) {
    222                 rtDesc.fConfig = kSkia8888_GrPixelConfig;
    223             } else {
    224                 return NULL;
    225             }
    226         } else {
    227             return NULL;
    228         }
    229     }
    230 
    231     GrTexture* stretched = create_texture_for_bmp(context, optionalKey, rtDesc, pixelRef, NULL, 0);
    232 
    233     if (!stretched) {
    234         return NULL;
    235     }
    236     GrPaint paint;
    237 
    238     // If filtering is not desired then we want to ensure all texels in the resampled image are
    239     // copies of texels from the original.
    240     GrTextureParams params(SkShader::kClamp_TileMode,
    241                            kBilerp_Stretch == stretch ? GrTextureParams::kBilerp_FilterMode :
    242                                                         GrTextureParams::kNone_FilterMode);
    243     paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
    244 
    245     SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
    246     SkRect localRect = SkRect::MakeWH(1.f, 1.f);
    247 
    248     context->drawNonAARectToRect(stretched->asRenderTarget(), GrClip::WideOpen(), paint,
    249                                  SkMatrix::I(), rect, localRect);
    250 
    251     return stretched;
    252 }
    253 
    254 #ifndef SK_IGNORE_ETC1_SUPPORT
    255 static GrTexture *load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalKey,
    256                                     const SkBitmap &bm, GrSurfaceDesc desc) {
    257     SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData());
    258 
    259     // Is this even encoded data?
    260     if (NULL == data) {
    261         return NULL;
    262     }
    263 
    264     // Is this a valid PKM encoded data?
    265     const uint8_t *bytes = data->bytes();
    266     if (etc1_pkm_is_valid(bytes)) {
    267         uint32_t encodedWidth = etc1_pkm_get_width(bytes);
    268         uint32_t encodedHeight = etc1_pkm_get_height(bytes);
    269 
    270         // Does the data match the dimensions of the bitmap? If not,
    271         // then we don't know how to scale the image to match it...
    272         if (encodedWidth != static_cast<uint32_t>(bm.width()) ||
    273             encodedHeight != static_cast<uint32_t>(bm.height())) {
    274             return NULL;
    275         }
    276 
    277         // Everything seems good... skip ahead to the data.
    278         bytes += ETC_PKM_HEADER_SIZE;
    279         desc.fConfig = kETC1_GrPixelConfig;
    280     } else if (SkKTXFile::is_ktx(bytes)) {
    281         SkKTXFile ktx(data);
    282 
    283         // Is it actually an ETC1 texture?
    284         if (!ktx.isCompressedFormat(SkTextureCompressor::kETC1_Format)) {
    285             return NULL;
    286         }
    287 
    288         // Does the data match the dimensions of the bitmap? If not,
    289         // then we don't know how to scale the image to match it...
    290         if (ktx.width() != bm.width() || ktx.height() != bm.height()) {
    291             return NULL;
    292         }
    293 
    294         bytes = ktx.pixelData();
    295         desc.fConfig = kETC1_GrPixelConfig;
    296     } else {
    297         return NULL;
    298     }
    299 
    300     return create_texture_for_bmp(ctx, optionalKey, desc, bm.pixelRef(), bytes, 0);
    301 }
    302 #endif   // SK_IGNORE_ETC1_SUPPORT
    303 
    304 static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKey,
    305                                    const SkBitmap& bm, const GrSurfaceDesc& desc) {
    306     // Subsets are not supported, the whole pixelRef is loaded when using YUV decoding
    307     SkPixelRef* pixelRef = bm.pixelRef();
    308     if ((NULL == pixelRef) ||
    309         (pixelRef->info().width()  != bm.info().width()) ||
    310         (pixelRef->info().height() != bm.info().height())) {
    311         return NULL;
    312     }
    313 
    314     const bool useCache = optionalKey.isValid();
    315     SkYUVPlanesCache::Info yuvInfo;
    316     SkAutoTUnref<SkCachedData> cachedData;
    317     SkAutoMalloc storage;
    318     if (useCache) {
    319         cachedData.reset(SkYUVPlanesCache::FindAndRef(pixelRef->getGenerationID(), &yuvInfo));
    320     }
    321 
    322     void* planes[3];
    323     if (cachedData.get()) {
    324         planes[0] = (void*)cachedData->data();
    325         planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0];
    326         planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1];
    327     } else {
    328         // Fetch yuv plane sizes for memory allocation. Here, width and height can be
    329         // rounded up to JPEG block size and be larger than the image's width and height.
    330         if (!pixelRef->getYUV8Planes(yuvInfo.fSize, NULL, NULL, NULL)) {
    331             return NULL;
    332         }
    333 
    334         // Allocate the memory for YUV
    335         size_t totalSize(0);
    336         for (int i = 0; i < 3; ++i) {
    337             yuvInfo.fRowBytes[i] = yuvInfo.fSize[i].fWidth;
    338             yuvInfo.fSizeInMemory[i] = yuvInfo.fRowBytes[i] * yuvInfo.fSize[i].fHeight;
    339             totalSize += yuvInfo.fSizeInMemory[i];
    340         }
    341         if (useCache) {
    342             cachedData.reset(SkResourceCache::NewCachedData(totalSize));
    343             planes[0] = cachedData->writable_data();
    344         } else {
    345             storage.reset(totalSize);
    346             planes[0] = storage.get();
    347         }
    348         planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0];
    349         planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1];
    350 
    351         // Get the YUV planes and update plane sizes to actual image size
    352         if (!pixelRef->getYUV8Planes(yuvInfo.fSize, planes, yuvInfo.fRowBytes,
    353                                      &yuvInfo.fColorSpace)) {
    354             return NULL;
    355         }
    356 
    357         if (useCache) {
    358             // Decoding is done, cache the resulting YUV planes
    359             SkYUVPlanesCache::Add(pixelRef->getGenerationID(), cachedData, &yuvInfo);
    360         }
    361     }
    362 
    363     GrSurfaceDesc yuvDesc;
    364     yuvDesc.fConfig = kAlpha_8_GrPixelConfig;
    365     SkAutoTUnref<GrTexture> yuvTextures[3];
    366     for (int i = 0; i < 3; ++i) {
    367         yuvDesc.fWidth  = yuvInfo.fSize[i].fWidth;
    368         yuvDesc.fHeight = yuvInfo.fSize[i].fHeight;
    369         bool needsExactTexture =
    370             (yuvDesc.fWidth  != yuvInfo.fSize[0].fWidth) ||
    371             (yuvDesc.fHeight != yuvInfo.fSize[0].fHeight);
    372         yuvTextures[i].reset(ctx->textureProvider()->refScratchTexture(yuvDesc,
    373             needsExactTexture ? GrTextureProvider::kExact_ScratchTexMatch :
    374                                 GrTextureProvider::kApprox_ScratchTexMatch));
    375         if (!yuvTextures[i] ||
    376             !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight,
    377                                          yuvDesc.fConfig, planes[i], yuvInfo.fRowBytes[i])) {
    378             return NULL;
    379         }
    380     }
    381 
    382     GrSurfaceDesc rtDesc = desc;
    383     rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
    384 
    385     GrTexture* result = create_texture_for_bmp(ctx, optionalKey, rtDesc, pixelRef, NULL, 0);
    386     if (!result) {
    387         return NULL;
    388     }
    389 
    390     GrRenderTarget* renderTarget = result->asRenderTarget();
    391     SkASSERT(renderTarget);
    392 
    393     SkAutoTUnref<GrFragmentProcessor>
    394         yuvToRgbProcessor(GrYUVtoRGBEffect::Create(yuvTextures[0], yuvTextures[1], yuvTextures[2],
    395                                                    yuvInfo.fSize, yuvInfo.fColorSpace));
    396     GrPaint paint;
    397     paint.addColorProcessor(yuvToRgbProcessor);
    398     SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth),
    399                               SkIntToScalar(yuvInfo.fSize[0].fHeight));
    400 
    401     ctx->drawRect(renderTarget, GrClip::WideOpen(), paint, SkMatrix::I(), r);
    402 
    403     return result;
    404 }
    405 
    406 static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx,
    407                                                     const SkBitmap& origBitmap,
    408                                                     const GrUniqueKey& optionalKey) {
    409     SkBitmap tmpBitmap;
    410 
    411     const SkBitmap* bitmap = &origBitmap;
    412 
    413     GrSurfaceDesc desc;
    414     generate_bitmap_texture_desc(*bitmap, &desc);
    415 
    416     if (kIndex_8_SkColorType == bitmap->colorType()) {
    417         if (ctx->isConfigTexturable(kIndex_8_GrPixelConfig)) {
    418             size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig,
    419                                                           bitmap->width(), bitmap->height());
    420             SkAutoMalloc storage(imageSize);
    421             build_index8_data(storage.get(), origBitmap);
    422 
    423             // our compressed data will be trimmed, so pass width() for its
    424             // "rowBytes", since they are the same now.
    425             return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(),
    426                                           storage.get(), bitmap->width());
    427         } else {
    428             origBitmap.copyTo(&tmpBitmap, kN32_SkColorType);
    429             // now bitmap points to our temp, which has been promoted to 32bits
    430             bitmap = &tmpBitmap;
    431             desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info());
    432         }
    433     }
    434 
    435     // Is this an ETC1 encoded texture?
    436 #ifndef SK_IGNORE_ETC1_SUPPORT
    437     // Make sure that the underlying device supports ETC1 textures before we go ahead
    438     // and check the data.
    439     else if (ctx->isConfigTexturable(kETC1_GrPixelConfig)
    440             // If the bitmap had compressed data and was then uncompressed, it'll still return
    441             // compressed data on 'refEncodedData' and upload it. Probably not good, since if
    442             // the bitmap has available pixels, then they might not be what the decompressed
    443             // data is.
    444             && !(bitmap->readyToDraw())) {
    445         GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc);
    446         if (texture) {
    447             return texture;
    448         }
    449     }
    450 #endif   // SK_IGNORE_ETC1_SUPPORT
    451 
    452     GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc);
    453     if (texture) {
    454         return texture;
    455     }
    456 
    457     SkAutoLockPixels alp(*bitmap);
    458     if (!bitmap->readyToDraw()) {
    459         return NULL;
    460     }
    461 
    462     return create_texture_for_bmp(ctx, optionalKey, desc, origBitmap.pixelRef(),
    463                                   bitmap->getPixels(), bitmap->rowBytes());
    464 }
    465 
    466 static GrTexture* create_bitmap_texture(GrContext* ctx,
    467                                         const SkBitmap& bmp,
    468                                         Stretch stretch,
    469                                         const GrUniqueKey& unstretchedKey,
    470                                         const GrUniqueKey& stretchedKey) {
    471     if (kNo_Stretch != stretch) {
    472         SkAutoTUnref<GrTexture> unstretched;
    473         // Check if we have the unstretched version in the cache, if not create it.
    474         if (unstretchedKey.isValid()) {
    475             unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueKey(unstretchedKey));
    476         }
    477         if (!unstretched) {
    478             unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey));
    479             if (!unstretched) {
    480                 return NULL;
    481             }
    482         }
    483         GrTexture* stretched = stretch_texture_to_next_pot(unstretched, stretch, bmp.pixelRef(),
    484                                                            stretchedKey);
    485         return stretched;
    486     }
    487 
    488     return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey);
    489 
    490 }
    491 
    492 bool GrIsBitmapInCache(const GrContext* ctx,
    493                        const SkBitmap& bitmap,
    494                        const GrTextureParams* params) {
    495     Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), params);
    496 
    497     // Handle the case where the bitmap is explicitly texture backed.
    498     GrTexture* texture = bitmap.getTexture();
    499     if (texture) {
    500         if (kNo_Stretch == stretch) {
    501             return true;
    502         }
    503         // No keys for volatile bitmaps.
    504         if (bitmap.isVolatile()) {
    505             return false;
    506         }
    507         const GrUniqueKey& key = texture->getUniqueKey();
    508         if (!key.isValid()) {
    509             return false;
    510         }
    511         GrUniqueKey stretchedKey;
    512         make_stretched_key(key, stretch, &stretchedKey);
    513         return ctx->textureProvider()->existsTextureWithUniqueKey(stretchedKey);
    514     }
    515 
    516     // We don't cache volatile bitmaps
    517     if (bitmap.isVolatile()) {
    518         return false;
    519     }
    520 
    521     GrUniqueKey key, stretchedKey;
    522     make_bitmap_keys(bitmap, stretch, &key, &stretchedKey);
    523     return ctx->textureProvider()->existsTextureWithUniqueKey(
    524         (kNo_Stretch == stretch) ? key : stretchedKey);
    525 }
    526 
    527 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
    528                                     const SkBitmap& bitmap,
    529                                     const GrTextureParams* params) {
    530 
    531     Stretch stretch = get_stretch_type(ctx, bitmap.width(), bitmap.height(), params);
    532 
    533     GrTexture* result = bitmap.getTexture();
    534     if (result) {
    535         if (kNo_Stretch == stretch) {
    536             return SkRef(result);
    537         }
    538         GrUniqueKey stretchedKey;
    539         // Don't create a key for the resized version if the bmp is volatile.
    540         if (!bitmap.isVolatile()) {
    541             const GrUniqueKey& key = result->getUniqueKey();
    542             if (key.isValid()) {
    543                 make_stretched_key(key, stretch, &stretchedKey);
    544                 GrTexture* stretched =
    545                     ctx->textureProvider()->findAndRefTextureByUniqueKey(stretchedKey);
    546                 if (stretched) {
    547                     return stretched;
    548                 }
    549             }
    550         }
    551         return stretch_texture_to_next_pot(result, stretch, bitmap.pixelRef(), stretchedKey);
    552     }
    553 
    554     GrUniqueKey key, resizedKey;
    555 
    556     if (!bitmap.isVolatile()) {
    557         // If the bitmap isn't changing try to find a cached copy first.
    558         make_bitmap_keys(bitmap, stretch, &key, &resizedKey);
    559 
    560         result = ctx->textureProvider()->findAndRefTextureByUniqueKey(
    561             resizedKey.isValid() ? resizedKey : key);
    562         if (result) {
    563             return result;
    564         }
    565     }
    566 
    567     result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey);
    568     if (result) {
    569         return result;
    570     }
    571 
    572     SkErrorInternals::SetError( kInternalError_SkError,
    573                                 "---- failed to create texture for cache [%d %d]\n",
    574                                 bitmap.width(), bitmap.height());
    575 
    576     return NULL;
    577 }
    578 ///////////////////////////////////////////////////////////////////////////////
    579 
    580 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
    581 // alpha info, that will be considered.
    582 GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt) {
    583     switch (ct) {
    584         case kUnknown_SkColorType:
    585             return kUnknown_GrPixelConfig;
    586         case kAlpha_8_SkColorType:
    587             return kAlpha_8_GrPixelConfig;
    588         case kRGB_565_SkColorType:
    589             return kRGB_565_GrPixelConfig;
    590         case kARGB_4444_SkColorType:
    591             return kRGBA_4444_GrPixelConfig;
    592         case kRGBA_8888_SkColorType:
    593 //            if (kSRGB_SkColorProfileType == pt) {
    594 //                return kSRGBA_8888_GrPixelConfig;
    595 //            }
    596             return kRGBA_8888_GrPixelConfig;
    597         case kBGRA_8888_SkColorType:
    598             return kBGRA_8888_GrPixelConfig;
    599         case kIndex_8_SkColorType:
    600             return kIndex_8_GrPixelConfig;
    601         case kGray_8_SkColorType:
    602             return kAlpha_8_GrPixelConfig; // TODO: gray8 support on gpu
    603     }
    604     SkASSERT(0);    // shouldn't get here
    605     return kUnknown_GrPixelConfig;
    606 }
    607 
    608 bool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
    609                                        SkColorProfileType* ptOut) {
    610     SkColorType ct;
    611     SkColorProfileType pt = kLinear_SkColorProfileType;
    612     switch (config) {
    613         case kAlpha_8_GrPixelConfig:
    614             ct = kAlpha_8_SkColorType;
    615             break;
    616         case kIndex_8_GrPixelConfig:
    617             ct = kIndex_8_SkColorType;
    618             break;
    619         case kRGB_565_GrPixelConfig:
    620             ct = kRGB_565_SkColorType;
    621             break;
    622         case kRGBA_4444_GrPixelConfig:
    623             ct = kARGB_4444_SkColorType;
    624             break;
    625         case kRGBA_8888_GrPixelConfig:
    626             ct = kRGBA_8888_SkColorType;
    627             break;
    628         case kBGRA_8888_GrPixelConfig:
    629             ct = kBGRA_8888_SkColorType;
    630             break;
    631         case kSRGBA_8888_GrPixelConfig:
    632             ct = kRGBA_8888_SkColorType;
    633             pt = kSRGB_SkColorProfileType;
    634             break;
    635         default:
    636             return false;
    637     }
    638     if (ctOut) {
    639         *ctOut = ct;
    640     }
    641     if (ptOut) {
    642         *ptOut = pt;
    643     }
    644     return true;
    645 }
    646 
    647 ///////////////////////////////////////////////////////////////////////////////
    648 
    649 bool SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget* rt, const SkPaint& skPaint,
    650                              GrColor paintColor, bool constantColor, GrPaint* grPaint) {
    651 
    652     grPaint->setDither(skPaint.isDither());
    653     grPaint->setAntiAlias(skPaint.isAntiAlias());
    654 
    655     SkXfermode* mode = skPaint.getXfermode();
    656     GrXPFactory* xpFactory = NULL;
    657     if (!SkXfermode::AsXPFactory(mode, &xpFactory)) {
    658         // Fall back to src-over
    659         // return false here?
    660         xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode);
    661     }
    662     SkASSERT(xpFactory);
    663     grPaint->setXPFactory(xpFactory)->unref();
    664 
    665     //set the color of the paint to the one of the parameter
    666     grPaint->setColor(paintColor);
    667 
    668     SkColorFilter* colorFilter = skPaint.getColorFilter();
    669     if (colorFilter) {
    670         // if the source color is a constant then apply the filter here once rather than per pixel
    671         // in a shader.
    672         if (constantColor) {
    673             SkColor filtered = colorFilter->filterColor(skPaint.getColor());
    674             grPaint->setColor(SkColor2GrColor(filtered));
    675         } else {
    676             SkTDArray<GrFragmentProcessor*> array;
    677             // return false if failed?
    678             if (colorFilter->asFragmentProcessors(context, &array)) {
    679                 for (int i = 0; i < array.count(); ++i) {
    680                     grPaint->addColorProcessor(array[i]);
    681                     array[i]->unref();
    682                 }
    683             }
    684         }
    685     }
    686 
    687 #ifndef SK_IGNORE_GPU_DITHER
    688     // If the dither flag is set, then we need to see if the underlying context
    689     // supports it. If not, then install a dither effect.
    690     if (skPaint.isDither() && grPaint->numColorStages() > 0) {
    691         // What are we rendering into?
    692         SkASSERT(rt);
    693 
    694         // Suspect the dithering flag has no effect on these configs, otherwise
    695         // fall back on setting the appropriate state.
    696         if (GrPixelConfigIs8888(rt->config()) ||
    697             GrPixelConfigIs8888(rt->config())) {
    698             // The dither flag is set and the target is likely
    699             // not going to be dithered by the GPU.
    700             SkAutoTUnref<GrFragmentProcessor> fp(GrDitherEffect::Create());
    701             if (fp.get()) {
    702                 grPaint->addColorProcessor(fp);
    703                 grPaint->setDither(false);
    704             }
    705         }
    706     }
    707 #endif
    708     return true;
    709 }
    710 
    711 bool SkPaint2GrPaint(GrContext* context, GrRenderTarget* rt, const SkPaint& skPaint,
    712                      const SkMatrix& viewM, bool constantColor, GrPaint* grPaint) {
    713     SkShader* shader = skPaint.getShader();
    714     if (NULL == shader) {
    715         return SkPaint2GrPaintNoShader(context, rt, skPaint, SkColor2GrColor(skPaint.getColor()),
    716                                        constantColor, grPaint);
    717     }
    718 
    719     GrColor paintColor = SkColor2GrColor(skPaint.getColor());
    720 
    721     // Start a new block here in order to preserve our context state after calling
    722     // asFragmentProcessor(). Since these calls get passed back to the client, we don't really
    723     // want them messing around with the context.
    724     {
    725         // Allow the shader to modify paintColor and also create an effect to be installed as
    726         // the first color effect on the GrPaint.
    727         GrFragmentProcessor* fp = NULL;
    728         if (!shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintColor, &fp)) {
    729             return false;
    730         }
    731         if (fp) {
    732             grPaint->addColorProcessor(fp)->unref();
    733             constantColor = false;
    734         }
    735     }
    736 
    737     // The grcolor is automatically set when calling asFragmentProcessor.
    738     // If the shader can be seen as an effect it returns true and adds its effect to the grpaint.
    739     return SkPaint2GrPaintNoShader(context, rt, skPaint, paintColor, constantColor, grPaint);
    740 }
    741 
    742 SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) {
    743 #ifdef SK_DEBUG
    744     const GrSurfaceDesc& desc = tex->desc();
    745     SkASSERT(w <= desc.fWidth);
    746     SkASSERT(h <= desc.fHeight);
    747 #endif
    748     const GrPixelConfig config = tex->config();
    749     SkColorType ct;
    750     SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
    751     if (!GrPixelConfig2ColorAndProfileType(config, &ct, NULL)) {
    752         ct = kUnknown_SkColorType;
    753     }
    754     return SkImageInfo::Make(w, h, ct, at);
    755 }
    756 
    757 
    758 void GrWrapTextureInBitmap(GrTexture* src, int w, int h, bool isOpaque, SkBitmap* dst) {
    759     const SkImageInfo info = GrMakeInfoFromTexture(src, w, h, isOpaque);
    760     dst->setInfo(info);
    761     dst->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, src)))->unref();
    762 }
    763