| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "SkBitmapCache.h" | 8 #include "SkBitmapCache.h" |
| 9 #include "SkImage_Gpu.h" | 9 #include "SkImage_Gpu.h" |
| 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 "GrTextureParamsAdjuster.h" | 13 #include "GrTextureParamsAdjuster.h" |
| 14 #include "effects/GrYUVtoRGBEffect.h" | 14 #include "effects/GrYUVtoRGBEffect.h" |
| 15 #include "SkCanvas.h" | 15 #include "SkCanvas.h" |
| 16 #include "SkGpuDevice.h" | 16 #include "SkGpuDevice.h" |
| 17 #include "SkGr.h" | 17 #include "SkGr.h" |
| 18 #include "SkPixelRef.h" | 18 #include "SkPixelRef.h" |
| 19 | 19 |
| 20 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText
ure* tex, | 20 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText
ure* tex, |
| 21 SkSurface::Budgeted budgeted) | 21 SkSurface::Budgeted budgeted) |
| 22 : INHERITED(w, h, uniqueID) | 22 : INHERITED(w, h, uniqueID) |
| 23 , fTexture(SkRef(tex)) | 23 , fTexture(SkRef(tex)) |
| 24 , fAlphaType(at) | 24 , fAlphaType(at) |
| 25 , fBudgeted(budgeted) | 25 , fBudgeted(budgeted) |
| 26 , fAddedRasterVersionToCache(false) | 26 , fAddedRasterVersionToCache(false) |
| 27 {} | 27 { |
| 28 // At the moment, we can't handle general transformations on textures (e.g.
tiling, |
| 29 // mip/filtering) unless they are exactly sized to match the "logical" size
(image size). |
| 30 // Hence these asserts. |
| 31 SkASSERT(tex->width() == w); |
| 32 SkASSERT(tex->height() == h); |
| 33 } |
| 28 | 34 |
| 29 SkImage_Gpu::~SkImage_Gpu() { | 35 SkImage_Gpu::~SkImage_Gpu() { |
| 30 if (fAddedRasterVersionToCache.load()) { | 36 if (fAddedRasterVersionToCache.load()) { |
| 31 SkNotifyBitmapGenIDIsStale(this->uniqueID()); | 37 SkNotifyBitmapGenIDIsStale(this->uniqueID()); |
| 32 } | 38 } |
| 33 } | 39 } |
| 34 | 40 |
| 35 extern void SkTextureImageApplyBudgetedDecision(SkImage* image) { | 41 extern void SkTextureImageApplyBudgetedDecision(SkImage* image) { |
| 36 if (as_IB(image)->getTexture()) { | 42 if (as_IB(image)->getTexture()) { |
| 37 ((SkImage_Gpu*)image)->applyBudgetDecision(); | 43 ((SkImage_Gpu*)image)->applyBudgetDecision(); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 return new SkImage_Gpu(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, fAl
phaType, subTx, | 186 return new SkImage_Gpu(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, fAl
phaType, subTx, |
| 181 fBudgeted); | 187 fBudgeted); |
| 182 } | 188 } |
| 183 | 189 |
| 184 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 190 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 185 | 191 |
| 186 #include "SkGrPixelRef.h" | 192 #include "SkGrPixelRef.h" |
| 187 #include "SkImageFilter.h" | 193 #include "SkImageFilter.h" |
| 188 | 194 |
| 189 class SkGpuImageFilterProxy : public SkImageFilter::Proxy { | 195 class SkGpuImageFilterProxy : public SkImageFilter::Proxy { |
| 190 GrContext* fCtx; | |
| 191 | |
| 192 public: | 196 public: |
| 193 SkGpuImageFilterProxy(GrContext* ctx) : fCtx(ctx) {} | 197 SkGpuImageFilterProxy(GrContext* ctx, bool requireExactTexSize) |
| 198 : INHERITED(requireExactTexSize), fCtx(ctx) |
| 199 {} |
| 194 | 200 |
| 195 SkBaseDevice* createDevice(int width, int height) override { | 201 SkBaseDevice* createDevice(int width, int height) override { |
| 196 GrSurfaceDesc desc; | 202 GrSurfaceDesc desc; |
| 197 desc.fConfig = kSkia8888_GrPixelConfig; | 203 desc.fConfig = kSkia8888_GrPixelConfig; |
| 198 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 204 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 199 desc.fWidth = width; | 205 desc.fWidth = width; |
| 200 desc.fHeight = height; | 206 desc.fHeight = height; |
| 201 desc.fSampleCnt = 0; | 207 desc.fSampleCnt = 0; |
| 202 | 208 |
| 203 SkAutoTUnref<GrTexture> texture(fCtx->textureProvider()->createTexture(d
esc, true)); | 209 SkAutoTUnref<GrTexture> texture(fCtx->textureProvider()->createTexture(d
esc, true)); |
| 204 | 210 |
| 205 if (texture) { | 211 if (texture) { |
| 206 SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | 212 SkSurfaceProps props(0, kUnknown_SkPixelGeometry); |
| 207 return SkGpuDevice::Create(texture->asRenderTarget(), width, height,
&props, | 213 return SkGpuDevice::Create(texture->asRenderTarget(), width, height,
&props, |
| 208 SkGpuDevice::kClear_InitContents); | 214 SkGpuDevice::kClear_InitContents); |
| 209 } else { | 215 } else { |
| 210 return nullptr; | 216 return nullptr; |
| 211 } | 217 } |
| 212 } | 218 } |
| 213 | 219 |
| 214 bool filterImage(const SkImageFilter* filter, const SkBitmap& src, | 220 bool filterImage(const SkImageFilter* filter, const SkBitmap& src, |
| 215 const SkImageFilter::Context& ctx, SkBitmap* dst, SkIPoint*
offset) override { | 221 const SkImageFilter::Context& ctx, SkBitmap* dst, SkIPoint*
offset) override { |
| 216 return filter->canFilterImageGPU() && | 222 return filter->canFilterImageGPU() && |
| 217 filter->filterImageGPU(this, src, ctx, dst, offset); | 223 filter->filterImageGPU(this, src, ctx, dst, offset); |
| 218 } | 224 } |
| 225 |
| 226 private: |
| 227 GrContext* fCtx; |
| 228 |
| 229 typedef Proxy INHERITED; |
| 219 }; | 230 }; |
| 220 | 231 |
| 221 static SkIRect compute_fast_ibounds(SkImageFilter* filter, const SkIRect& srcBou
nds) { | 232 static SkIRect compute_fast_ibounds(SkImageFilter* filter, const SkIRect& srcBou
nds) { |
| 222 SkRect fastBounds; | 233 SkRect fastBounds; |
| 223 fastBounds.set(srcBounds); | 234 fastBounds.set(srcBounds); |
| 224 filter->computeFastBounds(fastBounds, &fastBounds); | 235 filter->computeFastBounds(fastBounds, &fastBounds); |
| 225 return fastBounds.roundOut(); | 236 return fastBounds.roundOut(); |
| 226 } | 237 } |
| 227 | 238 |
| 228 SkImage* SkImage_Gpu::onApplyFilter(SkImageFilter* filter, SkIPoint* offsetResul
t, | 239 SkImage* SkImage_Gpu::onApplyFilter(SkImageFilter* filter, SkIPoint* offsetResul
t, |
| 229 bool forceResultToOriginalSize) const { | 240 bool forceResultToOriginalSize) const { |
| 230 const SkIRect srcBounds = SkIRect::MakeWH(this->width(), this->height()); | 241 const SkIRect srcBounds = SkIRect::MakeWH(this->width(), this->height()); |
| 231 | 242 |
| 232 if (forceResultToOriginalSize) { | 243 if (forceResultToOriginalSize) { |
| 233 SkBitmap src; | 244 SkBitmap src; |
| 234 GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isO
paque(), &src); | 245 GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isO
paque(), &src); |
| 235 | 246 |
| 236 const SkIRect clipBounds = srcBounds; | 247 // Since we want to return an image that wraps the filter's texture, and
our clients |
| 237 SkGpuImageFilterProxy proxy(fTexture->getContext()); | 248 // assume (at the moment) that the image can be scaled/tiled etc., we mu
st have an exact |
| 249 // sized texture (matching the image's logical size). Hence we pass true
to the Proxy's |
| 250 // constructor. |
| 251 const bool kRequireExactTexSize = true; |
| 252 SkGpuImageFilterProxy proxy(fTexture->getContext(), kRequireExactTexSize
); |
| 238 SkAutoTUnref<SkImageFilter::Cache> cache(SkGpuDevice::NewImageFilterCach
e()); | 253 SkAutoTUnref<SkImageFilter::Cache> cache(SkGpuDevice::NewImageFilterCach
e()); |
| 239 SkImageFilter::Context ctx(SkMatrix::I(), clipBounds, cache); | 254 SkImageFilter::Context ctx(SkMatrix::I(), srcBounds, cache); |
| 240 | 255 |
| 241 SkBitmap dst; | 256 SkBitmap dst; |
| 242 if (!filter->filterImage(&proxy, src, ctx, &dst, offsetResult)) { | 257 if (!filter->filterImage(&proxy, src, ctx, &dst, offsetResult)) { |
| 243 return nullptr; | 258 return nullptr; |
| 244 } | 259 } |
| 245 return new SkImage_Gpu(dst.width(), dst.height(), kNeedNewImageUniqueID,
dst.alphaType(), | 260 return new SkImage_Gpu(dst.width(), dst.height(), kNeedNewImageUniqueID,
dst.alphaType(), |
| 246 dst.getTexture(), SkSurface::kNo_Budgeted); | 261 dst.getTexture(), SkSurface::kNo_Budgeted); |
| 247 } | 262 } |
| 248 | 263 |
| 249 const SkIRect dstR = compute_fast_ibounds(filter, srcBounds); | 264 const SkIRect dstR = compute_fast_ibounds(filter, srcBounds); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 if (!dst) { | 417 if (!dst) { |
| 403 return nullptr; | 418 return nullptr; |
| 404 } | 419 } |
| 405 | 420 |
| 406 const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight); | 421 const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight); |
| 407 const SkIPoint dstP = SkIPoint::Make(0, 0); | 422 const SkIPoint dstP = SkIPoint::Make(0, 0); |
| 408 ctx->copySurface(dst, src, srcR, dstP, GrContext::kFlushWrites_PixelOp); | 423 ctx->copySurface(dst, src, srcR, dstP, GrContext::kFlushWrites_PixelOp); |
| 409 return dst; | 424 return dst; |
| 410 } | 425 } |
| 411 | 426 |
| OLD | NEW |