| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 /* |  | 
| 2  * Copyright 2015 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 "GrTextureParamsAdjuster.h" |  | 
| 9 |  | 
| 10 #include "GrCaps.h" |  | 
| 11 #include "GrContext.h" |  | 
| 12 #include "GrDrawContext.h" |  | 
| 13 #include "GrGpu.h" |  | 
| 14 #include "GrTexture.h" |  | 
| 15 #include "GrTextureParams.h" |  | 
| 16 #include "GrTextureProvider.h" |  | 
| 17 #include "SkCanvas.h" |  | 
| 18 #include "SkGr.h" |  | 
| 19 #include "SkGrPriv.h" |  | 
| 20 |  | 
| 21 typedef GrTextureParamsAdjuster::CopyParams CopyParams; |  | 
| 22 |  | 
| 23 static GrTexture* copy_on_gpu(GrTexture* inputTexture, const CopyParams& copyPar
     ams) { |  | 
| 24     GrContext* context = inputTexture->getContext(); |  | 
| 25     SkASSERT(context); |  | 
| 26     const GrCaps* caps = context->caps(); |  | 
| 27 |  | 
| 28     // Either it's a cache miss or the original wasn't cached to begin with. |  | 
| 29     GrSurfaceDesc rtDesc = inputTexture->desc(); |  | 
| 30     rtDesc.fFlags =  rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; |  | 
| 31     rtDesc.fWidth  = copyParams.fWidth; |  | 
| 32     rtDesc.fHeight = copyParams.fHeight; |  | 
| 33     rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); |  | 
| 34 |  | 
| 35     // If the config isn't renderable try converting to either A8 or an 32 bit c
     onfig. Otherwise, |  | 
| 36     // fail. |  | 
| 37     if (!caps->isConfigRenderable(rtDesc.fConfig, false)) { |  | 
| 38         if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { |  | 
| 39             if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { |  | 
| 40                 rtDesc.fConfig = kAlpha_8_GrPixelConfig; |  | 
| 41             } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false))
      { |  | 
| 42                 rtDesc.fConfig = kSkia8888_GrPixelConfig; |  | 
| 43             } else { |  | 
| 44                 return nullptr; |  | 
| 45             } |  | 
| 46         } else if (kRGB_GrColorComponentFlags == |  | 
| 47                    (kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDe
     sc.fConfig))) { |  | 
| 48             if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { |  | 
| 49                 rtDesc.fConfig = kSkia8888_GrPixelConfig; |  | 
| 50             } else { |  | 
| 51                 return nullptr; |  | 
| 52             } |  | 
| 53         } else { |  | 
| 54             return nullptr; |  | 
| 55         } |  | 
| 56     } |  | 
| 57 |  | 
| 58     SkAutoTUnref<GrTexture> copy(context->textureProvider()->createTexture(rtDes
     c, true)); |  | 
| 59     if (!copy) { |  | 
| 60         return nullptr; |  | 
| 61     } |  | 
| 62 |  | 
| 63     GrPaint paint; |  | 
| 64 |  | 
| 65     // If filtering is not desired then we want to ensure all texels in the resa
     mpled image are |  | 
| 66     // copies of texels from the original. |  | 
| 67     GrTextureParams params(SkShader::kClamp_TileMode, copyParams.fFilter); |  | 
| 68     paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); |  | 
| 69 |  | 
| 70     SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD
     esc.fHeight)); |  | 
| 71     SkRect localRect = SkRect::MakeWH(1.f, 1.f); |  | 
| 72 |  | 
| 73     SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(copy->asRenderT
     arget())); |  | 
| 74     if (!drawContext) { |  | 
| 75         return nullptr; |  | 
| 76     } |  | 
| 77 |  | 
| 78     drawContext->drawNonAARectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), r
     ect, localRect); |  | 
| 79     return copy.detach(); |  | 
| 80 } |  | 
| 81 |  | 
| 82 static SkBitmap copy_on_cpu(const SkBitmap& bmp, const CopyParams& copyParams) { |  | 
| 83     SkBitmap stretched; |  | 
| 84     stretched.allocN32Pixels(copyParams.fWidth, copyParams.fHeight); |  | 
| 85     SkCanvas canvas(stretched); |  | 
| 86     SkPaint paint; |  | 
| 87     switch (copyParams.fFilter) { |  | 
| 88         case GrTextureParams::kNone_FilterMode: |  | 
| 89             paint.setFilterQuality(kNone_SkFilterQuality); |  | 
| 90             break; |  | 
| 91         case GrTextureParams::kBilerp_FilterMode: |  | 
| 92             paint.setFilterQuality(kLow_SkFilterQuality); |  | 
| 93             break; |  | 
| 94         case GrTextureParams::kMipMap_FilterMode: |  | 
| 95             paint.setFilterQuality(kMedium_SkFilterQuality); |  | 
| 96             break; |  | 
| 97     } |  | 
| 98     SkRect dstRect = SkRect::MakeWH(SkIntToScalar(copyParams.fWidth), |  | 
| 99                                     SkIntToScalar(copyParams.fHeight)); |  | 
| 100     canvas.drawBitmapRect(bmp, dstRect, &paint); |  | 
| 101     return stretched; |  | 
| 102 } |  | 
| 103 |  | 
| 104 GrTexture* GrTextureParamsAdjuster::refTextureForParams(GrContext* ctx, |  | 
| 105                                                         const GrTextureParams& p
     arams) { |  | 
| 106     CopyParams copyParams; |  | 
| 107     if (!ctx->getGpu()->makeCopyForTextureParams(this->width(), this->height(), 
     params, |  | 
| 108                                                  ©Params)) { |  | 
| 109         return this->refOriginalTexture(ctx); |  | 
| 110     } |  | 
| 111     GrUniqueKey copyKey; |  | 
| 112     this->makeCopyKey(copyParams, ©Key); |  | 
| 113     if (copyKey.isValid()) { |  | 
| 114         GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey
     (copyKey); |  | 
| 115         if (result) { |  | 
| 116             return result; |  | 
| 117         } |  | 
| 118     } |  | 
| 119 |  | 
| 120     GrTexture* result = this->generateTextureForParams(ctx, copyParams); |  | 
| 121     if (!result) { |  | 
| 122         return nullptr; |  | 
| 123     } |  | 
| 124 |  | 
| 125     if (copyKey.isValid()) { |  | 
| 126         ctx->textureProvider()->assignUniqueKeyToTexture(copyKey, result); |  | 
| 127         this->didCacheCopy(copyKey); |  | 
| 128     } |  | 
| 129     return result; |  | 
| 130 } |  | 
| 131 |  | 
| 132 GrTexture* GrTextureParamsAdjuster::generateTextureForParams(GrContext* ctx, |  | 
| 133                                                              const CopyParams& c
     opyParams) { |  | 
| 134     if (this->width() < ctx->caps()->minTextureSize() || |  | 
| 135         this->height() < ctx->caps()->minTextureSize()) |  | 
| 136     { |  | 
| 137         // we can't trust our ability to use HW to perform the stretch, so we re
     quest |  | 
| 138         // a raster instead, and perform the stretch on the CPU. |  | 
| 139         SkBitmap bitmap; |  | 
| 140         if (!this->getROBitmap(&bitmap)) { |  | 
| 141             return nullptr; |  | 
| 142         } |  | 
| 143         SkBitmap stretchedBmp = copy_on_cpu(bitmap, copyParams); |  | 
| 144         return GrUploadBitmapToTexture(ctx, stretchedBmp); |  | 
| 145     } else { |  | 
| 146         SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx)); |  | 
| 147         if (!original) { |  | 
| 148             return nullptr; |  | 
| 149         } |  | 
| 150         return copy_on_gpu(original, copyParams); |  | 
| 151     } |  | 
| 152 } |  | 
| OLD | NEW | 
|---|