| 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 |