| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrTextureParamsAdjuster.h" | 8 #include "GrTextureParamsAdjuster.h" |
| 9 | 9 |
| 10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
| 11 #include "GrContext.h" | 11 #include "GrContext.h" |
| 12 #include "GrDrawContext.h" | 12 #include "GrDrawContext.h" |
| 13 #include "GrGpu.h" | 13 #include "GrGpu.h" |
| 14 #include "GrGpuResourcePriv.h" |
| 15 #include "GrResourceKey.h" |
| 14 #include "GrTexture.h" | 16 #include "GrTexture.h" |
| 15 #include "GrTextureParams.h" | 17 #include "GrTextureParams.h" |
| 16 #include "GrTextureProvider.h" | 18 #include "GrTextureProvider.h" |
| 17 #include "SkCanvas.h" | 19 #include "SkCanvas.h" |
| 18 #include "SkGr.h" | 20 #include "SkGr.h" |
| 19 #include "SkGrPriv.h" | 21 #include "SkGrPriv.h" |
| 22 #include "effects/GrTextureDomain.h" |
| 20 | 23 |
| 21 typedef GrTextureParamsAdjuster::CopyParams CopyParams; | 24 typedef GrTextureProducer::CopyParams CopyParams; |
| 22 | 25 |
| 23 static GrTexture* copy_on_gpu(GrTexture* inputTexture, const CopyParams& copyPar
ams) { | 26 ////////////////////////////////////////////////////////////////////////////// |
| 27 |
| 28 static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset, |
| 29 const CopyParams& copyParams) { |
| 30 SkASSERT(!subset || !subset->isEmpty()); |
| 24 GrContext* context = inputTexture->getContext(); | 31 GrContext* context = inputTexture->getContext(); |
| 25 SkASSERT(context); | 32 SkASSERT(context); |
| 26 const GrCaps* caps = context->caps(); | 33 const GrCaps* caps = context->caps(); |
| 27 | 34 |
| 28 // Either it's a cache miss or the original wasn't cached to begin with. | 35 // Either it's a cache miss or the original wasn't cached to begin with. |
| 29 GrSurfaceDesc rtDesc = inputTexture->desc(); | 36 GrSurfaceDesc rtDesc = inputTexture->desc(); |
| 30 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; | 37 rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag; |
| 31 rtDesc.fWidth = copyParams.fWidth; | 38 rtDesc.fWidth = copyParams.fWidth; |
| 32 rtDesc.fHeight = copyParams.fHeight; | 39 rtDesc.fHeight = copyParams.fHeight; |
| 33 rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); | 40 rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); |
| 34 | 41 |
| 35 // If the config isn't renderable try converting to either A8 or an 32 bit c
onfig. Otherwise, | 42 // If the config isn't renderable try converting to either A8 or an 32 bit c
onfig. Otherwise, |
| 36 // fail. | 43 // fail. |
| 37 if (!caps->isConfigRenderable(rtDesc.fConfig, false)) { | 44 if (!caps->isConfigRenderable(rtDesc.fConfig, false)) { |
| 38 if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { | 45 if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { |
| 39 if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { | 46 if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { |
| 40 rtDesc.fConfig = kAlpha_8_GrPixelConfig; | 47 rtDesc.fConfig = kAlpha_8_GrPixelConfig; |
| 41 } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false))
{ | 48 } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false))
{ |
| (...skipping 11 matching lines...) Expand all Loading... |
| 53 } else { | 60 } else { |
| 54 return nullptr; | 61 return nullptr; |
| 55 } | 62 } |
| 56 } | 63 } |
| 57 | 64 |
| 58 SkAutoTUnref<GrTexture> copy(context->textureProvider()->createTexture(rtDes
c, true)); | 65 SkAutoTUnref<GrTexture> copy(context->textureProvider()->createTexture(rtDes
c, true)); |
| 59 if (!copy) { | 66 if (!copy) { |
| 60 return nullptr; | 67 return nullptr; |
| 61 } | 68 } |
| 62 | 69 |
| 70 // TODO: If no scaling is being performed then use copySurface. |
| 71 |
| 63 GrPaint paint; | 72 GrPaint paint; |
| 64 | 73 |
| 65 // If filtering is not desired then we want to ensure all texels in the resa
mpled image are | 74 SkScalar sx; |
| 66 // copies of texels from the original. | 75 SkScalar sy; |
| 67 GrTextureParams params(SkShader::kClamp_TileMode, copyParams.fFilter); | 76 if (subset) { |
| 68 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); | 77 sx = 1.f / inputTexture->width(); |
| 78 sy = 1.f / inputTexture->height(); |
| 79 } |
| 69 | 80 |
| 70 SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtD
esc.fHeight)); | 81 if (copyParams.fFilter != GrTextureParams::kNone_FilterMode && subset && |
| 71 SkRect localRect = SkRect::MakeWH(1.f, 1.f); | 82 (subset->width() != copyParams.fWidth || subset->height() != copyParams.
fHeight)) { |
| 83 SkRect domain; |
| 84 domain.fLeft = (subset->fLeft + 0.5f) * sx; |
| 85 domain.fTop = (subset->fTop + 0.5f)* sy; |
| 86 domain.fRight = (subset->fRight - 0.5f) * sx; |
| 87 domain.fBottom = (subset->fBottom - 0.5f) * sy; |
| 88 // This would cause us to read values from outside the subset. Surely, t
he caller knows |
| 89 // better! |
| 90 SkASSERT(copyParams.fFilter != GrTextureParams::kMipMap_FilterMode); |
| 91 paint.addColorFragmentProcessor( |
| 92 GrTextureDomainEffect::Create(inputTexture, SkMatrix::I(), domain, |
| 93 GrTextureDomain::kClamp_Mode, |
| 94 copyParams.fFilter))->unref(); |
| 95 } else { |
| 96 GrTextureParams params(SkShader::kClamp_TileMode, copyParams.fFilter); |
| 97 paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); |
| 98 } |
| 99 |
| 100 SkRect localRect; |
| 101 if (subset) { |
| 102 localRect = SkRect::Make(*subset); |
| 103 localRect.fLeft *= sx; |
| 104 localRect.fTop *= sy; |
| 105 localRect.fRight *= sx; |
| 106 localRect.fBottom *= sy; |
| 107 } else { |
| 108 localRect = SkRect::MakeWH(1.f, 1.f); |
| 109 } |
| 72 | 110 |
| 73 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(copy->asRenderT
arget())); | 111 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(copy->asRenderT
arget())); |
| 74 if (!drawContext) { | 112 if (!drawContext) { |
| 75 return nullptr; | 113 return nullptr; |
| 76 } | 114 } |
| 77 | 115 |
| 78 drawContext->drawNonAARectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), r
ect, localRect); | 116 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(
rtDesc.fHeight)); |
| 117 drawContext->drawNonAARectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), d
stRect, localRect); |
| 79 return copy.detach(); | 118 return copy.detach(); |
| 80 } | 119 } |
| 81 | 120 |
| 82 GrTexture* GrTextureParamsAdjuster::refTextureForParams(GrContext* ctx, | 121 GrTextureAdjuster::GrTextureAdjuster(GrTexture* original, const SkIRect& subset) |
| 83 const GrTextureParams& p
arams) { | 122 : fOriginal(original) { |
| 123 if (subset.fLeft > 0 || subset.fTop > 0 || |
| 124 subset.fRight < original->width() || subset.fBottom < original->height()
) { |
| 125 fSubset.set(subset); |
| 126 } |
| 127 } |
| 128 |
| 129 GrTexture* GrTextureAdjuster::refTextureSafeForParams(const GrTextureParams& par
ams, |
| 130 SkIPoint* outOffset) { |
| 131 GrTexture* texture = this->originalTexture(); |
| 132 GrContext* context = texture->getContext(); |
| 133 CopyParams copyParams; |
| 134 const SkIRect* subset = this->subset(); |
| 135 |
| 136 if (!context->getGpu()->makeCopyForTextureParams(texture->width(), texture->
height(), params, |
| 137 ©Params)) { |
| 138 if (outOffset) { |
| 139 if (subset) { |
| 140 outOffset->set(subset->fLeft, subset->fRight); |
| 141 } else { |
| 142 outOffset->set(0, 0); |
| 143 } |
| 144 } |
| 145 return SkRef(texture); |
| 146 } |
| 147 GrUniqueKey key; |
| 148 this->makeCopyKey(copyParams, &key); |
| 149 if (key.isValid()) { |
| 150 GrTexture* result = context->textureProvider()->findAndRefTextureByUniqu
eKey(key); |
| 151 if (result) { |
| 152 return result; |
| 153 } |
| 154 } |
| 155 GrTexture* result = copy_on_gpu(texture, subset, copyParams); |
| 156 if (result) { |
| 157 if (key.isValid()) { |
| 158 result->resourcePriv().setUniqueKey(key); |
| 159 this->didCacheCopy(key); |
| 160 } |
| 161 if (outOffset) { |
| 162 outOffset->set(0, 0); |
| 163 } |
| 164 } |
| 165 return result; |
| 166 } |
| 167 |
| 168 ////////////////////////////////////////////////////////////////////////////// |
| 169 |
| 170 GrTexture* GrTextureMaker::refTextureForParams(GrContext* ctx, const GrTexturePa
rams& params) { |
| 84 CopyParams copyParams; | 171 CopyParams copyParams; |
| 85 if (!ctx->getGpu()->makeCopyForTextureParams(this->width(), this->height(),
params, | 172 if (!ctx->getGpu()->makeCopyForTextureParams(this->width(), this->height(),
params, |
| 86 ©Params)) { | 173 ©Params)) { |
| 87 return this->refOriginalTexture(ctx); | 174 return this->refOriginalTexture(ctx); |
| 88 } | 175 } |
| 89 GrUniqueKey copyKey; | 176 GrUniqueKey copyKey; |
| 90 this->makeCopyKey(copyParams, ©Key); | 177 this->makeCopyKey(copyParams, ©Key); |
| 91 if (copyKey.isValid()) { | 178 if (copyKey.isValid()) { |
| 92 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey
(copyKey); | 179 GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey
(copyKey); |
| 93 if (result) { | 180 if (result) { |
| 94 return result; | 181 return result; |
| 95 } | 182 } |
| 96 } | 183 } |
| 97 | 184 |
| 98 GrTexture* result = this->generateTextureForParams(ctx, copyParams); | 185 GrTexture* result = this->generateTextureForParams(ctx, copyParams); |
| 99 if (!result) { | 186 if (!result) { |
| 100 return nullptr; | 187 return nullptr; |
| 101 } | 188 } |
| 102 | 189 |
| 103 if (copyKey.isValid()) { | 190 if (copyKey.isValid()) { |
| 104 ctx->textureProvider()->assignUniqueKeyToTexture(copyKey, result); | 191 ctx->textureProvider()->assignUniqueKeyToTexture(copyKey, result); |
| 105 this->didCacheCopy(copyKey); | 192 this->didCacheCopy(copyKey); |
| 106 } | 193 } |
| 107 return result; | 194 return result; |
| 108 } | 195 } |
| 109 | 196 |
| 110 GrTexture* GrTextureParamsAdjuster::generateTextureForParams(GrContext* ctx, | 197 GrTexture* GrTextureMaker::generateTextureForParams(GrContext* ctx, const CopyPa
rams& copyParams) { |
| 111 const CopyParams& c
opyParams) { | |
| 112 SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx)); | 198 SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx)); |
| 113 if (!original) { | 199 if (!original) { |
| 114 return nullptr; | 200 return nullptr; |
| 115 } | 201 } |
| 116 return copy_on_gpu(original, copyParams); | 202 return copy_on_gpu(original, nullptr, copyParams); |
| 117 } | 203 } |
| OLD | NEW |