diff options
-rw-r--r-- | src/core/SkCanvas.cpp | 8 | ||||
-rw-r--r-- | src/effects/SkMagnifierImageFilter.cpp | 46 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 34 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.h | 13 |
4 files changed, 67 insertions, 34 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 8426f090ec..5310c9f7d5 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -936,14 +936,6 @@ void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav } SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; -#if 1 - // this seems needed for current GMs, but makes us draw slower on the GPU - // Related to https://code.google.com/p/skia/issues/detail?id=3519 ? - // - if (paint && paint->getImageFilter()) { - usage = SkBaseDevice::kPossible_TileUsage; - } -#endif device = device->onCreateDevice(SkBaseDevice::CreateInfo(info, usage, geo), paint); if (NULL == device) { SkErrorInternals::SetError( kInternalError_SkError, diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp index 622713d796..d8e21cf29a 100644 --- a/src/effects/SkMagnifierImageFilter.cpp +++ b/src/effects/SkMagnifierImageFilter.cpp @@ -25,6 +25,7 @@ class GrMagnifierEffect : public GrSingleTextureEffect { public: static GrFragmentProcessor* Create(GrTexture* texture, + const SkRect& bounds, float xOffset, float yOffset, float xInvZoom, @@ -32,6 +33,7 @@ public: float xInvInset, float yInvInset) { return SkNEW_ARGS(GrMagnifierEffect, (texture, + bounds, xOffset, yOffset, xInvZoom, @@ -48,6 +50,7 @@ public: GrGLFragmentProcessor* createGLInstance() const override; + const SkRect& bounds() const { return fBounds; } float x_offset() const { return fXOffset; } float y_offset() const { return fYOffset; } float x_inv_zoom() const { return fXInvZoom; } @@ -57,6 +60,7 @@ public: private: GrMagnifierEffect(GrTexture* texture, + const SkRect& bounds, float xOffset, float yOffset, float xInvZoom, @@ -64,6 +68,7 @@ private: float xInvInset, float yInvInset) : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) + , fBounds(bounds) , fXOffset(xOffset) , fYOffset(yOffset) , fXInvZoom(xInvZoom) @@ -79,6 +84,7 @@ private: GR_DECLARE_FRAGMENT_PROCESSOR_TEST; + SkRect fBounds; float fXOffset; float fYOffset; float fXInvZoom; @@ -109,6 +115,7 @@ private: UniformHandle fOffsetVar; UniformHandle fInvZoomVar; UniformHandle fInvInsetVar; + UniformHandle fBoundsVar; typedef GrGLFragmentProcessor INHERITED; }; @@ -134,6 +141,10 @@ void GrGLMagnifierEffect::emitCode(GrGLFPBuilder* builder, GrGLProgramBuilder::kFragment_Visibility | GrGLProgramBuilder::kVertex_Visibility, kVec2f_GrSLType, kDefault_GrSLPrecision, "InvInset"); + fBoundsVar = builder->addUniform( + GrGLProgramBuilder::kFragment_Visibility | + GrGLProgramBuilder::kVertex_Visibility, + kVec4f_GrSLType, kDefault_GrSLPrecision, "Bounds"); GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); @@ -142,9 +153,9 @@ void GrGLMagnifierEffect::emitCode(GrGLFPBuilder* builder, builder->getUniformCStr(fOffsetVar), coords2D.c_str(), builder->getUniformCStr(fInvZoomVar)); - - fsBuilder->codeAppend("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n"); - + const char* bounds = builder->getUniformCStr(fBoundsVar); + fsBuilder->codeAppendf("\t\tvec2 delta = (coord - %s.xy) * %s.zw;\n", bounds, bounds); + fsBuilder->codeAppendf("\t\tdelta = min(delta, vec2(1.0, 1.0) - delta);\n"); fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n", builder->getUniformCStr(fInvInsetVar)); fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n"); @@ -175,6 +186,8 @@ void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman, pdman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset()); pdman.set2f(fInvZoomVar, zoom.x_inv_zoom(), zoom.y_inv_zoom()); pdman.set2f(fInvInsetVar, zoom.x_inv_inset(), zoom.y_inv_inset()); + pdman.set4f(fBoundsVar, zoom.bounds().x(), zoom.bounds().y(), + zoom.bounds().width(), zoom.bounds().height()); } ///////////////////////////////////////////////////////////////////// @@ -206,6 +219,7 @@ GrFragmentProcessor* GrMagnifierEffect::TestCreate(SkRandom* random, GrFragmentProcessor* effect = GrMagnifierEffect::Create( texture, + SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)), (float) width / texture->width(), (float) height / texture->height(), texture->width() / (float) x, @@ -220,7 +234,8 @@ GrFragmentProcessor* GrMagnifierEffect::TestCreate(SkRandom* random, bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& sBase) const { const GrMagnifierEffect& s = sBase.cast<GrMagnifierEffect>(); - return (this->fXOffset == s.fXOffset && + return (this->fBounds == s.fBounds && + this->fXOffset == s.fXOffset && this->fYOffset == s.fYOffset && this->fXInvZoom == s.fXInvZoom && this->fYInvZoom == s.fYInvZoom && @@ -258,18 +273,27 @@ SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar i #if SK_SUPPORT_GPU bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, GrTexture* texture, - const SkMatrix&, const SkIRect&) const { + const SkMatrix&, const SkIRect&bounds) const { if (fp) { - SkScalar yOffset = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? fSrcRect.y() : - (texture->height() - (fSrcRect.y() + fSrcRect.height())); + SkScalar yOffset = texture->origin() == kTopLeft_GrSurfaceOrigin ? fSrcRect.y() : + texture->height() - fSrcRect.height() * texture->height() / bounds.height() + - fSrcRect.y(); + int boundsY = (texture->origin() == kTopLeft_GrSurfaceOrigin) ? bounds.y() : + (texture->height() - bounds.height()); + SkRect effectBounds = SkRect::MakeXYWH( + SkIntToScalar(bounds.x()) / texture->width(), + SkIntToScalar(boundsY) / texture->height(), + SkIntToScalar(texture->width()) / bounds.width(), + SkIntToScalar(texture->height()) / bounds.height()); SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1; *fp = GrMagnifierEffect::Create(texture, + effectBounds, fSrcRect.x() / texture->width(), yOffset / texture->height(), - fSrcRect.width() / texture->width(), - fSrcRect.height() / texture->height(), - texture->width() * invInset, - texture->height() * invInset); + fSrcRect.width() / bounds.width(), + fSrcRect.height() / bounds.height(), + bounds.width() * invInset, + bounds.height() * invInset); } return true; } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 38a22e69f5..021cfba106 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -121,10 +121,15 @@ public: /////////////////////////////////////////////////////////////////////////////// SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) { + return SkGpuDevice::Create(rt, rt->width(), rt->height(), props, flags); +} + +SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, int width, int height, + const SkSurfaceProps* props, unsigned flags) { if (!rt || rt->wasDestroyed()) { return NULL; } - return SkNEW_ARGS(SkGpuDevice, (rt, props, flags)); + return SkNEW_ARGS(SkGpuDevice, (rt, width, height, props, flags)); } static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* props) { @@ -143,7 +148,8 @@ static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) { } } -SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) +SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height, + const SkSurfaceProps* props, unsigned flags) : INHERITED(surfaceprops_to_deviceprops(props)) , fSurfaceProps(copy_or_default_props(props)) { @@ -154,7 +160,7 @@ SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsign fRenderTarget = SkRef(rt); - SkImageInfo info = rt->surfacePriv().info(); + SkImageInfo info = rt->surfacePriv().info().makeWH(width, height); SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt)); fLegacyBitmap.setInfo(info); fLegacyBitmap.setPixelRef(pr)->unref(); @@ -211,7 +217,7 @@ SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgete return NULL; } - return SkNEW_ARGS(SkGpuDevice, (rt, props, flags)); + return SkNEW_ARGS(SkGpuDevice, (rt, info.width(), info.height(), props, flags)); } SkGpuDevice::~SkGpuDevice() { @@ -736,9 +742,9 @@ GrTexture* create_mask_GPU(GrContext* context, return mask; } -SkBitmap wrap_texture(GrTexture* texture) { +SkBitmap wrap_texture(GrTexture* texture, int width, int height) { SkBitmap result; - result.setInfo(texture->surfacePriv().info()); + result.setInfo(SkImageInfo::MakeN32Premul(width, height)); result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unref(); return result; } @@ -1474,6 +1480,7 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, } bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, + int width, int height, const SkImageFilter* filter, const SkImageFilter::Context& ctx, SkBitmap* result, SkIPoint* offset) { @@ -1484,7 +1491,8 @@ bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().pixelGeometry())); if (filter->canFilterImageGPU()) { - return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result, offset); + return filter->filterImageGPU(&proxy, wrap_texture(texture, width, height), + ctx, result, offset); } else { return false; } @@ -1523,7 +1531,7 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, // This cache is transient, and is freed (along with all its contained // textures) when it goes out of scope. SkImageFilter::Context ctx(matrix, clipBounds, cache); - if (this->filterTexture(fContext, texture, filter, ctx, &filteredBitmap, + if (this->filterTexture(fContext, texture, w, h, filter, ctx, &filteredBitmap, &offset)) { texture = (GrTexture*) filteredBitmap.getTexture(); w = filteredBitmap.width(); @@ -1637,8 +1645,8 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, // textures) when it goes out of scope. SkAutoTUnref<SkImageFilter::Cache> cache(getImageFilterCache()); SkImageFilter::Context ctx(matrix, clipBounds, cache); - if (this->filterTexture(fContext, devTex, filter, ctx, &filteredBitmap, - &offset)) { + if (this->filterTexture(fContext, devTex, device->width(), device->height(), + filter, ctx, &filteredBitmap, &offset)) { devTex = filteredBitmap.getTexture(); w = filteredBitmap.width(); h = filteredBitmap.height(); @@ -1691,7 +1699,8 @@ bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src, // must be pushed upstack. AutoBitmapTexture abt(fContext, src, NULL, &texture); - return this->filterTexture(fContext, texture, filter, ctx, result, offset); + return this->filterTexture(fContext, texture, src.width(), src.height(), + filter, ctx, result, offset); } /////////////////////////////////////////////////////////////////////////////// @@ -1901,7 +1910,8 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint if (texture) { SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry); - return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags); + return SkGpuDevice::Create( + texture->asRenderTarget(), cinfo.fInfo.width(), cinfo.fInfo.height(), &props, flags); } else { SkErrorInternals::SetError( kInternalError_SkError, "---- failed to create compatible device texture [%d %d]\n", diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index ad0c2d63f0..999a698ded 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -41,6 +41,13 @@ public: static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, unsigned flags = 0); /** + * Creates an SkGpuDevice from a GrRenderTarget whose texture width/height is + * different than its actual width/height (e.g., approx-match scratch texture). + */ + static SkGpuDevice* Create(GrRenderTarget* target, int width, int height, + const SkSurfaceProps*, unsigned flags = 0); + + /** * New device that will create an offscreen renderTarget based on the ImageInfo and * sampleCount. The Budgeted param controls whether the device's backing store counts against * the resource cache budget. On failure, returns NULL. @@ -67,7 +74,7 @@ public: GrRenderTarget* accessRenderTarget() override; SkImageInfo imageInfo() const override { - return fRenderTarget ? fRenderTarget->surfacePriv().info() : SkImageInfo::MakeUnknown(); + return fLegacyBitmap.info(); } const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; } @@ -121,7 +128,7 @@ public: const SkImageFilter::Context&, SkBitmap*, SkIPoint*) override; - bool filterTexture(GrContext*, GrTexture*, const SkImageFilter*, + bool filterTexture(GrContext*, GrTexture*, int width, int height, const SkImageFilter*, const SkImageFilter::Context&, SkBitmap* result, SkIPoint* offset); @@ -147,7 +154,7 @@ private: SkBitmap fLegacyBitmap; bool fNeedClear; - SkGpuDevice(GrRenderTarget*, const SkSurfaceProps*, unsigned flags); + SkGpuDevice(GrRenderTarget*, int width, int height, const SkSurfaceProps*, unsigned flags); SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override; |